History

Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus

Pull MIPS updates from Ralf Baechle: "This is the main pull request for 4.3 for MIPS. Here's the summary: Three fixes that didn't make 4.2-stable: - a -Os build might compile the kernel using the MIPS16 instruction set but the R2 optimized inline functions in <uapi/asm/swab.h> are implemented using 32-bit wide instructions which is invalid. - a build error in pgtable-bits.h for a particular kernel configuration. - accessing registers of the CM GCR might have been compiled to use 64 bit accesses but these registers are onl 32 bit wide. And also a few new bits: - move the ATH79 GPIO driver to drivers/gpio - the definition of IRQCHIP_DECLARE has moved to linux/irqchip.h, change ATH79 accordingly. - fix definition of pgprot_writecombine - add an implementation of dma_map_ops.mmap - fix alignment of quiet build output for vmlinuz link - BCM47xx: Use kmemdup rather than duplicating its implementation - Netlogic: Fix 0x0x prefixes of constants. - merge Bjorn Helgaas' series to remove most of the weak keywords from function declarations. - CP0 and CP1 registers are best considered treated as unsigned values to avoid large values from becoming negative values. - improve support for the MIPS GIC timer. - enable common clock framework for Malta and SEAD3. - a number of improvments and fixes to dump_tlb(). - document the MIPS TLB dump functionality in Magic SysRq. - Cavium Octeon CN68XX improvments. - NetLogic improvments. - irq: Use access helper irq_data_get_affinity_mask. - handle MSA unaligned accesses. - a number of R6-related math-emu fixes. - support for I6400. - improvments to MSA support. - add uprobes support. - move from deprecated __initcall to arch_initcall. - remove finish_arch_switch(). - IRQ cleanups by Thomas Gleixner. - migrate to new 'set-state' interface. - random small cleanups" * 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (148 commits) MIPS: UAPI: Fix unrecognized opcode WSBH/DSBH/DSHD when using MIPS16. MIPS: Fix alignment of quiet build output for vmlinuz link MIPS: math-emu: Remove unused handle_dsemul function declaration MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction MIPS: math-emu: Add support for the MIPS R6 MIN{, A} FPU instruction MIPS: math-emu: Add support for the MIPS R6 CLASS FPU instruction MIPS: math-emu: Add support for the MIPS R6 RINT FPU instruction MIPS: math-emu: Add support for the MIPS R6 MSUBF FPU instruction MIPS: math-emu: Add support for the MIPS R6 MADDF FPU instruction MIPS: math-emu: Add support for the MIPS R6 SELNEZ FPU instruction MIPS: math-emu: Add support for the MIPS R6 SELEQZ FPU instruction MIPS: math-emu: Add support for the CMP.condn.fmt R6 instruction MIPS: inst.h: Add new MIPS R6 FPU opcodes MIPS: Octeon: Fix management port MII address on Kontron S1901 MIPS: BCM47xx: Use kmemdup rather than duplicating its implementation STAGING: Octeon: Use common helpers for determining interface and port MIPS: Octeon: Support interfaces 4 and 5 MIPS: Octeon: Set up 1:1 mapping between CN68XX PKO queues and ports MIPS: Octeon: Initialize CN68XX PKO STAGING: Octeon: Support CN68XX style WQE ...

Linus Torvalds committed 11 years ago

Commit 807249d2 parents ff474e8 2db9704195 files · +6347 −2101Browse files

Unified · Split

195 files
  1. Documentation/devicetree/bindings/timer/img,pistachio-gptimer.txt +28 −0
  2. Documentation/features/debug/uprobes/arch-support.txt +1 −1
  3. Documentation/sysrq.txt +1 −0
  4. arch/mips/Kconfig +17 −8
  5. arch/mips/Kconfig.debug +0 −9
  6. arch/mips/alchemy/Kconfig +0 −7
  7. arch/mips/alchemy/board-gpr.c +1 −0
  8. arch/mips/alchemy/board-mtx1.c +1 −0
  9. arch/mips/alchemy/common/Makefile +1 −6
  10. arch/mips/alchemy/common/irq.c +2 −2
  11. arch/mips/alchemy/common/time.c +0 −6
  12. arch/mips/alchemy/devboards/bcsr.c +4 −2
  13. arch/mips/alchemy/devboards/db1000.c +1 −0
  14. arch/mips/alchemy/devboards/db1300.c +1 −0
  15. arch/mips/alchemy/devboards/db1550.c +1 −0
  16. arch/mips/alchemy/devboards/pm.c +1 −1
  17. arch/mips/ar7/gpio.c +4 −1
  18. arch/mips/ar7/platform.c +0 −1
  19. arch/mips/ar7/setup.c +0 −1
  20. arch/mips/ath79/Makefile +1 −1
  21. arch/mips/ath79/common.h +0 −3
  22. arch/mips/ath79/irq.c +2 −16
  23. arch/mips/bcm47xx/buttons.c +1 −2
  24. arch/mips/bcm63xx/irq.c +3 −3
  25. arch/mips/boot/compressed/Makefile +1 −1
  26. arch/mips/boot/dts/netlogic/xlp_evp.dts +12 −0
  27. arch/mips/boot/dts/netlogic/xlp_fvp.dts +12 −0
  28. arch/mips/boot/dts/netlogic/xlp_gvp.dts +11 −0
  29. arch/mips/boot/dts/netlogic/xlp_rvp.dts +11 −0
  30. arch/mips/boot/dts/netlogic/xlp_svp.dts +12 −0
  31. arch/mips/cavium-octeon/executive/cvmx-helper-board.c +6 −0
  32. arch/mips/cavium-octeon/executive/cvmx-helper-util.c +16 −4
  33. arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c +13 −1
  34. arch/mips/cavium-octeon/executive/cvmx-helper.c +17 −0
  35. arch/mips/cavium-octeon/executive/cvmx-pko.c +144 −5
  36. arch/mips/cavium-octeon/octeon-irq.c +19 −17
  37. arch/mips/include/asm/Kbuild +0 −1
  38. arch/mips/include/asm/abi.h +4 −0
  39. arch/mips/include/asm/asmmacro.h +114 −0
  40. arch/mips/include/asm/cdmm.h +2 −2
  41. arch/mips/include/asm/cevt-r4k.h +0 −1
  42. arch/mips/include/asm/cpu-features.h +4 −0
  43. arch/mips/include/asm/cpu-type.h +4 −0
  44. arch/mips/include/asm/cpu.h +3 −0
  45. arch/mips/include/asm/debug.h +0 −48
  46. arch/mips/include/asm/elf.h +3 −1
  47. arch/mips/include/asm/fpu.h +13 −8
  48. arch/mips/include/asm/gpio.h +0 −6
  49. arch/mips/include/asm/irq.h +1 −1
  50. arch/mips/include/asm/kdebug.h +3 −1
  51. arch/mips/include/asm/linkage.h +0 −1
  52. arch/mips/include/asm/maar.h +1 −1
  53. arch/mips/include/asm/mach-ar7/ar7.h +4 −0
  54. arch/mips/include/asm/mach-ar7/gpio.h +0 −41
  55. arch/mips/include/asm/mach-ath25/gpio.h +0 −16
  56. arch/mips/include/asm/mach-ath79/gpio.h +0 −26
  57. arch/mips/include/asm/mach-au1x00/gpio-au1000.h +11 −137
  58. arch/mips/include/asm/mach-au1x00/gpio.h +0 −86
  59. arch/mips/include/asm/mach-bcm47xx/gpio.h +0 −17
  60. arch/mips/include/asm/mach-bcm63xx/gpio.h +0 −15
  61. arch/mips/include/asm/mach-cavium-octeon/gpio.h +0 −21
  62. arch/mips/include/asm/mach-generic/gpio.h +0 −21
  63. arch/mips/include/asm/mach-jz4740/gpio.h +0 −2
  64. arch/mips/include/asm/mach-lantiq/gpio.h +0 −13
  65. arch/mips/include/asm/mach-loongson64/gpio.h +0 −36
  66. arch/mips/include/asm/mach-pistachio/gpio.h +0 −21
  67. arch/mips/include/asm/mach-rc32434/gpio.h +0 −12
  68. arch/mips/include/asm/mips-cm.h +85 −4
  69. arch/mips/include/asm/mips-cpc.h +0 −10
  70. arch/mips/include/asm/mipsregs.h +32 −28
  71. arch/mips/include/asm/msa.h +80 −0
  72. arch/mips/include/asm/octeon/cvmx-bootinfo.h +2 −0
  73. arch/mips/include/asm/octeon/cvmx-pip.h +1 −1
  74. arch/mips/include/asm/octeon/cvmx-pko.h +3 −0
  75. arch/mips/include/asm/octeon/cvmx-pow-defs.h +29 −0
  76. arch/mips/include/asm/octeon/cvmx-pow.h +5 −4
  77. arch/mips/include/asm/octeon/cvmx-wqe.h +249 −59
  78. arch/mips/include/asm/pgtable-bits.h +10 −15
  79. arch/mips/include/asm/pgtable.h +2 −0
  80. arch/mips/include/asm/processor.h +2 −0
  81. arch/mips/include/asm/ptrace.h +80 −0
  82. arch/mips/include/asm/signal.h +3 −0
  83. arch/mips/include/asm/spinlock.h +5 −0
  84. arch/mips/include/asm/switch_to.h +4 −17
  85. arch/mips/include/asm/thread_info.h +4 −1
  86. arch/mips/include/asm/time.h +1 −1
  87. arch/mips/include/asm/tlbdebug.h +1 −0
  88. arch/mips/include/asm/uprobes.h +58 −0
  89. arch/mips/include/asm/vpe.h +1 −1
  90. arch/mips/include/uapi/asm/break.h +2 −0
  91. arch/mips/include/uapi/asm/hwcap.h +8 −0
  92. arch/mips/include/uapi/asm/inst.h +37 −3
  93. arch/mips/include/uapi/asm/sigcontext.h +12 −0
  94. arch/mips/include/uapi/asm/swab.h +9 −3
  95. arch/mips/include/uapi/asm/ucontext.h +65 −0
  96. arch/mips/jazz/irq.c +0 −7
  97. arch/mips/jz4740/gpio.c +10 −14
  98. arch/mips/jz4740/time.c +27 −19
  99. arch/mips/kernel/Makefile +1 −0
  100. arch/mips/kernel/asm-offsets.c +1 −11
  101. arch/mips/kernel/cevt-bcm1480.c +22 −22
  102. arch/mips/kernel/cevt-ds1287.c +22 −15
  103. arch/mips/kernel/cevt-gt641xx.c +39 −18
  104. arch/mips/kernel/cevt-r4k.c +7 −11
  105. arch/mips/kernel/cevt-sb1250.c +23 −22
  106. arch/mips/kernel/cevt-txx9.c +51 −30
  107. arch/mips/kernel/cps-vec.S +2 −2
  108. arch/mips/kernel/cpu-probe.c +46 −10
  109. arch/mips/kernel/idle.c +1 −0
  110. arch/mips/kernel/mips-cm.c +256 −1
  111. arch/mips/kernel/mips-cpc.c +9 −2
  112. arch/mips/kernel/perf_event_mipsxx.c +6 −0
  113. arch/mips/kernel/pm-cps.c +2 −0
  114. arch/mips/kernel/ptrace.c +88 −0
  115. arch/mips/kernel/r4k_fpu.S +259 −177
  116. arch/mips/kernel/r4k_switch.S +1 −40
  117. arch/mips/kernel/signal-common.h +9 −0
  118. arch/mips/kernel/signal.c +340 −93
  119. arch/mips/kernel/signal32.c +11 −196
  120. arch/mips/kernel/signal_n32.c +5 −1
  121. arch/mips/kernel/spram.c +1 −0
  122. arch/mips/kernel/sysrq.c +1 −13
  123. arch/mips/kernel/traps.c +29 −28
  124. arch/mips/kernel/unaligned.c +73 −1
  125. arch/mips/kernel/uprobes.c +341 −0
  126. arch/mips/kernel/vpe.c +6 −1
  127. arch/mips/lasat/sysctl.c +1 −1
  128. arch/mips/lib/dump_tlb.c +36 −9
  129. arch/mips/lib/r3k_dump_tlb.c +11 −0
  130. arch/mips/loongson32/common/time.c +34 −23
  131. arch/mips/loongson64/common/cs5536/cs5536_mfgpt.c +21 −25
  132. arch/mips/loongson64/loongson-3/hpet.c +71 −46
  133. arch/mips/math-emu/Makefile +2 −2
  134. arch/mips/math-emu/cp1emu.c +387 −13
  135. arch/mips/math-emu/dp_2008class.c +55 −0
  136. arch/mips/math-emu/dp_fmax.c +213 −0
  137. arch/mips/math-emu/dp_fmin.c +213 −0
  138. arch/mips/math-emu/dp_maddf.c +265 −0
  139. arch/mips/math-emu/dp_msubf.c +269 −0
  140. arch/mips/math-emu/dsemul.c +0 −1
  141. arch/mips/math-emu/ieee754.h +19 −0
  142. arch/mips/math-emu/ieee754int.h +4 −4
  143. arch/mips/math-emu/me-debugfs.c +1 −1
  144. arch/mips/math-emu/sp_2008class.c +55 −0
  145. arch/mips/math-emu/sp_fmax.c +213 −0
  146. arch/mips/math-emu/sp_fmin.c +213 −0
  147. arch/mips/math-emu/sp_maddf.c +255 −0
  148. arch/mips/math-emu/sp_msubf.c +258 −0
  149. arch/mips/mm/c-r4k.c +1 −0
  150. arch/mips/mm/dma-default.c +35 −0
  151. arch/mips/mm/fault.c +4 −4
  152. arch/mips/mm/init.c +34 −2
  153. arch/mips/mm/sc-mips.c +42 −0
  154. arch/mips/mm/tlb-r3k.c +1 −1
  155. arch/mips/mti-malta/malta-init.c +7 −0
  156. arch/mips/mti-malta/malta-int.c +1 −111
  157. arch/mips/mti-malta/malta-memory.c +0 −25
  158. arch/mips/netlogic/common/irq.c +6 −6
  159. arch/mips/netlogic/common/smp.c +4 −2
  160. arch/mips/netlogic/xlp/ahci-init-xlp2.c +1 −1
  161. arch/mips/netlogic/xlp/nlm_hal.c +2 −0
  162. arch/mips/oprofile/common.c +1 −0
  163. arch/mips/oprofile/op_model_mipsxx.c +4 −0
  164. arch/mips/pci/msi-xlp.c +10 −10
  165. arch/mips/pci/ops-emma2rh.c +2 −4
  166. arch/mips/pci/pci-ar71xx.c +2 −2
  167. arch/mips/pci/pci-ar724x.c +2 −2
  168. arch/mips/pci/pci-lantiq.c +0 −1
  169. arch/mips/pci/pci-rt3883.c +3 −4
  170. arch/mips/pistachio/Kconfig +13 −0
  171. arch/mips/pmcs-msp71xx/msp_irq_cic.c +2 −1
  172. arch/mips/ralink/cevt-rt3352.c +30 −29
  173. arch/mips/rb532/devices.c +1 −0
  174. arch/mips/rb532/gpio.c +6 −0
  175. arch/mips/sgi-ip27/ip27-timer.c +0 −7
  176. arch/mips/sibyte/common/bus_watcher.c +1 −1
  177. arch/mips/sni/time.c +19 −30
  178. arch/mips/txx9/generic/setup.c +0 −16
  179. drivers/ata/pata_rb532_cf.c +1 −2
  180. drivers/bus/mips_cdmm.c +13 −1
  181. drivers/clocksource/Kconfig +4 −0
  182. drivers/clocksource/Makefile +1 −0
  183. drivers/clocksource/mips-gic-timer.c +56 −9
  184. drivers/clocksource/time-pistachio.c +217 −0
  185. drivers/gpio/Makefile +1 −0
  186. drivers/gpio/gpio-ath79.c +0 −75
  187. drivers/input/misc/rb532_button.c +1 −0
  188. drivers/irqchip/irq-mips-gic.c +94 −48
  189. drivers/net/ethernet/ti/cpmac.c +2 −0
  190. drivers/staging/octeon/ethernet-rx.c +92 −41
  191. drivers/staging/octeon/ethernet-tx.c +10 −9
  192. drivers/staging/octeon/ethernet-util.h +11 −11
  193. drivers/staging/octeon/ethernet.c +5 −2
  194. drivers/tty/mips_ejtag_fdc.c +6 −3
  195. include/linux/irqchip/mips-gic.h +12 −2
Documentation/devicetree/bindings/timer/img,pistachio-gptimer.txt+28−0
@@ -0,0 +1,28 @@
1+* Pistachio general-purpose timer based clocksource
2+
3+Required properties:
4+ - compatible: "img,pistachio-gptimer".
5+ - reg: Address range of the timer registers.
6+ - interrupts: An interrupt for each of the four timers
7+ - clocks: Should contain a clock specifier for each entry in clock-names
8+ - clock-names: Should contain the following entries:
9+ "sys", interface clock
10+ "slow", slow counter clock
11+ "fast", fast counter clock
12+ - img,cr-periph: Must contain a phandle to the peripheral control
13+ syscon node.
14+
15+Example:
16+ timer: timer@18102000 {
17+ compatible = "img,pistachio-gptimer";
18+ reg = <0x18102000 0x100>;
19+ interrupts = <GIC_SHARED 60 IRQ_TYPE_LEVEL_HIGH>,
20+ <GIC_SHARED 61 IRQ_TYPE_LEVEL_HIGH>,
21+ <GIC_SHARED 62 IRQ_TYPE_LEVEL_HIGH>,
22+ <GIC_SHARED 63 IRQ_TYPE_LEVEL_HIGH>;
23+ clocks = <&clk_periph PERIPH_CLK_COUNTER_FAST>,
24+ <&clk_periph PERIPH_CLK_COUNTER_SLOW>,
25+ <&cr_periph SYS_CLK_TIMER>;
26+ clock-names = "fast", "slow", "sys";
27+ img,cr-periph = <&cr_periph>;
28+ };
Documentation/features/debug/uprobes/arch-support.txt+1−1
@@ -22,7 +22,7 @@ · 21 unmodified lines
2222 | m68k: | TODO |
2323 | metag: | TODO |
2424 | microblaze: | TODO |
25− | mips: | TODO |
25+ | mips: | ok |
2626 | mn10300: | TODO |
2727 | nios2: | TODO |
2828 | openrisc: | TODO |
Documentation/sysrq.txt+1−0
@@ -119,6 +119,7 @@ On all - write a character to /proc/sysrq-trigger. e.g.: · 118 unmodified lines
119119
120120 'x' - Used by xmon interface on ppc/powerpc platforms.
121121 Show global PMU Registers on sparc64.
122+ Dump all TLB entries on MIPS.
122123
123124 'y' - Show global CPU Registers [SPARC-64 specific]
124125
arch/mips/Kconfig+17−8
@@ -1,8 +1,10 @@
11 config MIPS
22 bool
33 default y
4+ select ARCH_SUPPORTS_UPROBES
45 select ARCH_MIGHT_HAVE_PC_PARPORT
56 select ARCH_MIGHT_HAVE_PC_SERIO
7+ select ARCH_USE_CMPXCHG_LOCKREF if 64BIT
68 select HAVE_CONTEXT_TRACKING
79 select HAVE_GENERIC_DMA_COHERENT
810 select HAVE_IDE
@@ -13,7 +15,6 @@ config MIPS · 4 unmodified lines
1315 select HAVE_ARCH_SECCOMP_FILTER
1416 select HAVE_ARCH_TRACEHOOK
1517 select HAVE_BPF_JIT if !CPU_MICROMIPS
16− select ARCH_HAVE_CUSTOM_GPIO_H
1718 select HAVE_FUNCTION_TRACER
1819 select HAVE_DYNAMIC_FTRACE
1920 select HAVE_FTRACE_MCOUNT_RECORD
@@ -409,6 +410,7 @@ config MIPS_MALTA · 389 unmodified lines
409410 select CEVT_R4K
410411 select CSRC_R4K
411412 select CLKSRC_MIPS_GIC
413+ select COMMON_CLK
412414 select DMA_MAYBE_COHERENT
413415 select GENERIC_ISA_DMA
414416 select HAVE_PCSPKR_PLATFORM
@@ -459,6 +461,7 @@ config MIPS_SEAD3 · 44 unmodified lines
459461 select CEVT_R4K
460462 select CSRC_R4K
461463 select CLKSRC_MIPS_GIC
464+ select COMMON_CLK
462465 select CPU_MIPSR2_IRQ_VI
463466 select CPU_MIPSR2_IRQ_EI
464467 select DMA_NONCOHERENT
@@ -899,6 +902,7 @@ config NLM_XLP_BOARD · 434 unmodified lines
899902 select SYS_SUPPORTS_32BIT_KERNEL
900903 select SYS_SUPPORTS_64BIT_KERNEL
901904 select ARCH_PHYS_ADDR_T_64BIT
905+ select ARCH_REQUIRE_GPIOLIB
902906 select SYS_SUPPORTS_BIG_ENDIAN
903907 select SYS_SUPPORTS_LITTLE_ENDIAN
904908 select SYS_SUPPORTS_HIGHMEM
@@ -948,6 +952,7 @@ source "arch/mips/jazz/Kconfig" · 43 unmodified lines
948952 source "arch/mips/jz4740/Kconfig"
949953 source "arch/mips/lantiq/Kconfig"
950954 source "arch/mips/lasat/Kconfig"
955+source "arch/mips/pistachio/Kconfig"
951956 source "arch/mips/pmcs-msp71xx/Kconfig"
952957 source "arch/mips/ralink/Kconfig"
953958 source "arch/mips/sgi-ip27/Kconfig"
@@ -1041,6 +1046,9 @@ config FW_CFE · 87 unmodified lines
10411046 config ARCH_DMA_ADDR_T_64BIT
10421047 def_bool (HIGHMEM && ARCH_PHYS_ADDR_T_64BIT) || 64BIT
10431048
1049+config ARCH_SUPPORTS_UPROBES
1050+ bool
1051+
10441052 config DMA_MAYBE_COHERENT
10451053 select DMA_NONCOHERENT
10461054 bool
@@ -1364,7 +1372,7 @@ config CPU_MIPS32_R2 · 317 unmodified lines
13641372 otherwise CPU_MIPS32_R1 is a safe bet for any MIPS32 system.
13651373
13661374 config CPU_MIPS32_R6
1367− bool "MIPS32 Release 6 (EXPERIMENTAL)"
1375+ bool "MIPS32 Release 6"
13681376 depends on SYS_HAS_CPU_MIPS32_R6
13691377 select CPU_HAS_PREFETCH
13701378 select CPU_SUPPORTS_32BIT_KERNEL
@@ -1415,7 +1423,7 @@ config CPU_MIPS64_R2 · 44 unmodified lines
14151423 otherwise CPU_MIPS64_R1 is a safe bet for any MIPS64 system.
14161424
14171425 config CPU_MIPS64_R6
1418− bool "MIPS64 Release 6 (EXPERIMENTAL)"
1426+ bool "MIPS64 Release 6"
14191427 depends on SYS_HAS_CPU_MIPS64_R6
14201428 select CPU_HAS_PREFETCH
14211429 select CPU_SUPPORTS_32BIT_KERNEL
@@ -1965,6 +1973,7 @@ config 32BIT · 543 unmodified lines
19651973 select TRAD_SIGNALS
19661974 help
19671975 Select this option if you want to build a 32-bit kernel.
1976+
19681977 config 64BIT
19691978 bool "64-bit kernel"
19701979 depends on CPU_SUPPORTS_64BIT_KERNEL && SYS_SUPPORTS_64BIT_KERNEL
@@ -2110,7 +2119,7 @@ config CPU_R4K_CACHE_TLB · 139 unmodified lines
21102119
21112120 config MIPS_MT_SMP
21122121 bool "MIPS MT SMP support (1 TC on each available VPE)"
2113− depends on SYS_SUPPORTS_MULTITHREADING
2122+ depends on SYS_SUPPORTS_MULTITHREADING && !CPU_MIPSR6
21142123 select CPU_MIPSR2_IRQ_VI
21152124 select CPU_MIPSR2_IRQ_EI
21162125 select SYNC_R4K
@@ -2211,7 +2220,7 @@ config MIPS_VPE_APSP_API_MT · 94 unmodified lines
22112220
22122221 config MIPS_CMP
22132222 bool "MIPS CMP framework support (DEPRECATED)"
2214− depends on SYS_SUPPORTS_MIPS_CMP
2223+ depends on SYS_SUPPORTS_MIPS_CMP && !CPU_MIPSR6
22152224 select MIPS_GIC_IPI
22162225 select SMP
22172226 select SYNC_R4K
@@ -2228,7 +2237,7 @@ config MIPS_CMP · 10 unmodified lines
22282237
22292238 config MIPS_CPS
22302239 bool "MIPS Coherent Processing System support"
2231− depends on SYS_SUPPORTS_MIPS_CPS
2240+ depends on SYS_SUPPORTS_MIPS_CPS && !CPU_MIPSR6
22322241 select MIPS_CM
22332242 select MIPS_CPC
22342243 select MIPS_CPS_PM if HOTPLUG_CPU
@@ -2303,7 +2312,7 @@ config CPU_MICROMIPS · 68 unmodified lines
23032312 endchoice
23042313
23052314 config CPU_HAS_MSA
2306− bool "Support for the MIPS SIMD Architecture (EXPERIMENTAL)"
2315+ bool "Support for the MIPS SIMD Architecture"
23072316 depends on CPU_SUPPORTS_MSA
23082317 depends on 64BIT || MIPS_O32_FP64_SUPPORT
23092318 help
@@ -2643,7 +2652,7 @@ config SECCOMP · 333 unmodified lines
26432652 If unsure, say Y. Only embedded should say N here.
26442653
26452654 config MIPS_O32_FP64_SUPPORT
2646− bool "Support for O32 binaries using 64-bit FP (EXPERIMENTAL)"
2655+ bool "Support for O32 binaries using 64-bit FP"
26472656 depends on 32BIT || MIPS32_O32
26482657 help
26492658 When this is enabled, the kernel will support use of 64-bit floating
arch/mips/Kconfig.debug+0−9
@@ -87,15 +87,6 @@ config SB1XXX_CORELIS · 86 unmodified lines
8787 Select compile flags that produce code that can be processed by the
8888 Corelis mksym utility and UDB Emulator.
8989
90−config RUNTIME_DEBUG
91− bool "Enable run-time debugging"
92− depends on DEBUG_KERNEL
93− help
94− If you say Y here, some debugging macros will do run-time checking.
95− If you say N here, those macros will mostly turn to no-ops. See
96− arch/mips/include/asm/debug.h for debugging macros.
97− If unsure, say N.
98−
9990 config DEBUG_ZBOOT
10091 bool "Enable compressed kernel support debugging"
10192 depends on DEBUG_KERNEL && SYS_SUPPORTS_ZBOOT
arch/mips/alchemy/Kconfig+0−7
@@ -6,13 +6,6 @@ config ALCHEMY_GPIOINT_AU1000 · 5 unmodified lines
66 config ALCHEMY_GPIOINT_AU1300
77 bool
88
9−# select this in your board config if you don't want to use the gpio
10−# namespace as documented in the manuals. In this case however you need
11−# to create the necessary gpio_* functions in your board code/headers!
12−# see arch/mips/include/asm/mach-au1x00/gpio.h for more information.
13−config ALCHEMY_GPIO_INDIRECT
14− def_bool n
15−
169 choice
1710 prompt "Machine type"
1811 depends on MIPS_ALCHEMY
arch/mips/alchemy/board-gpr.c+1−0
@@ -34,6 +34,7 @@ · 33 unmodified lines
3434 #include <asm/idle.h>
3535 #include <asm/reboot.h>
3636 #include <asm/mach-au1x00/au1000.h>
37+#include <asm/mach-au1x00/gpio-au1000.h>
3738 #include <prom.h>
3839
3940 const char *get_system_type(void)
arch/mips/alchemy/board-mtx1.c+1−0
@@ -32,6 +32,7 @@ · 31 unmodified lines
3232 #include <asm/bootinfo.h>
3333 #include <asm/reboot.h>
3434 #include <asm/mach-au1x00/au1000.h>
35+#include <asm/mach-au1x00/gpio-au1000.h>
3536 #include <asm/mach-au1x00/au1xxx_eth.h>
3637 #include <prom.h>
3738
arch/mips/alchemy/common/Makefile+1−6
@@ -5,10 +5,5 @@ · 4 unmodified lines
55 # Makefile for the Alchemy Au1xx0 CPUs, generic files.
66 #
77
8−obj-y += prom.o time.o clock.o platform.o power.o \
8+obj-y += prom.o time.o clock.o platform.o power.o gpiolib.o \
99 setup.o sleeper.o dma.o dbdma.o vss.o irq.o usb.o
10−
11−# optional gpiolib support
12−ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),)
13− obj-$(CONFIG_GPIOLIB) += gpiolib.o
14−endif
arch/mips/alchemy/common/irq.c+2−2
@@ -491,7 +491,7 @@ static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type) · 490 unmodified lines
491491 default:
492492 ret = -EINVAL;
493493 }
494− __irq_set_chip_handler_name_locked(d->irq, chip, handler, name);
494+ irq_set_chip_handler_name_locked(d, chip, handler, name);
495495
496496 wmb();
497497
@@ -703,7 +703,7 @@ static int au1300_gpic_settype(struct irq_data *d, unsigned int type) · 205 unmodified lines
703703 return -EINVAL;
704704 }
705705
706− __irq_set_chip_handler_name_locked(d->irq, &au1300_gpic, hdl, name);
706+ irq_set_chip_handler_name_locked(d, &au1300_gpic, hdl, name);
707707
708708 au1300_gpic_chgcfg(d->irq - ALCHEMY_GPIC_INT_BASE, GPIC_CFG_IC_MASK, s);
709709
arch/mips/alchemy/common/time.c+0−6
@@ -69,11 +69,6 @@ static int au1x_rtcmatch2_set_next_event(unsigned long delta, · 68 unmodified lines
6969 return 0;
7070 }
7171
72−static void au1x_rtcmatch2_set_mode(enum clock_event_mode mode,
73− struct clock_event_device *cd)
74−{
75−}
76−
7772 static irqreturn_t au1x_rtcmatch2_irq(int irq, void *dev_id)
7873 {
7974 struct clock_event_device *cd = dev_id;
@@ -86,7 +81,6 @@ static struct clock_event_device au1x_rtcmatch2_clockdev = { · 6 unmodified lines
8681 .features = CLOCK_EVT_FEAT_ONESHOT,
8782 .rating = 1500,
8883 .set_next_event = au1x_rtcmatch2_set_next_event,
89− .set_mode = au1x_rtcmatch2_set_mode,
9084 .cpumask = cpu_all_mask,
9185 };
9286
arch/mips/alchemy/devboards/bcsr.c+4−2
@@ -8,6 +8,7 @@ · 7 unmodified lines
88 */
99
1010 #include <linux/interrupt.h>
11+#include <linux/irqchip/chained_irq.h>
1112 #include <linux/module.h>
1213 #include <linux/spinlock.h>
1314 #include <linux/irq.h>
@@ -88,10 +89,11 @@ EXPORT_SYMBOL_GPL(bcsr_mod); · 74 unmodified lines
8889 static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d)
8990 {
9091 unsigned short bisr = __raw_readw(bcsr_virt + BCSR_REG_INTSTAT);
92+ struct irq_chip *chip = irq_desc_get_chip(d);
9193
92− disable_irq_nosync(irq);
94+ chained_irq_enter(chip, d);
9395 generic_handle_irq(bcsr_csc_base + __ffs(bisr));
94− enable_irq(irq);
96+ chained_irq_exit(chip, d);
9597 }
9698
9799 static void bcsr_irq_mask(struct irq_data *d)
arch/mips/alchemy/devboards/db1000.c+1−0
@@ -33,6 +33,7 @@ · 32 unmodified lines
3333 #include <linux/spi/spi_gpio.h>
3434 #include <linux/spi/ads7846.h>
3535 #include <asm/mach-au1x00/au1000.h>
36+#include <asm/mach-au1x00/gpio-au1000.h>
3637 #include <asm/mach-au1x00/au1000_dma.h>
3738 #include <asm/mach-au1x00/au1100_mmc.h>
3839 #include <asm/mach-db1x00/bcsr.h>
arch/mips/alchemy/devboards/db1300.c+1−0
@@ -24,6 +24,7 @@ · 23 unmodified lines
2424 #include <linux/wm97xx.h>
2525
2626 #include <asm/mach-au1x00/au1000.h>
27+#include <asm/mach-au1x00/gpio-au1300.h>
2728 #include <asm/mach-au1x00/au1100_mmc.h>
2829 #include <asm/mach-au1x00/au1200fb.h>
2930 #include <asm/mach-au1x00/au1xxx_dbdma.h>
arch/mips/alchemy/devboards/db1550.c+1−0
@@ -20,6 +20,7 @@ · 19 unmodified lines
2020 #include <linux/spi/flash.h>
2121 #include <asm/bootinfo.h>
2222 #include <asm/mach-au1x00/au1000.h>
23+#include <asm/mach-au1x00/gpio-au1000.h>
2324 #include <asm/mach-au1x00/au1xxx_eth.h>
2425 #include <asm/mach-au1x00/au1xxx_dbdma.h>
2526 #include <asm/mach-au1x00/au1xxx_psc.h>
arch/mips/alchemy/devboards/pm.c+1−1
@@ -9,7 +9,7 @@ · 8 unmodified lines
99 #include <linux/suspend.h>
1010 #include <linux/sysfs.h>
1111 #include <asm/mach-au1x00/au1000.h>
12−#include <asm/mach-au1x00/gpio.h>
12+#include <asm/mach-au1x00/gpio-au1000.h>
1313 #include <asm/mach-db1x00/bcsr.h>
1414
1515 /*
arch/mips/ar7/gpio.c+4−1
@@ -21,7 +21,10 @@ · 20 unmodified lines
2121 #include <linux/module.h>
2222 #include <linux/gpio.h>
2323
24−#include <asm/mach-ar7/gpio.h>
24+#include <asm/mach-ar7/ar7.h>
25+
26+#define AR7_GPIO_MAX 32
27+#define TITAN_GPIO_MAX 51
2528
2629 struct ar7_gpio_chip {
2730 void __iomem *regs;
arch/mips/ar7/platform.c+0−1
@@ -39,7 +39,6 @@ · 38 unmodified lines
3939
4040 #include <asm/addrspace.h>
4141 #include <asm/mach-ar7/ar7.h>
42−#include <asm/mach-ar7/gpio.h>
4342 #include <asm/mach-ar7/prom.h>
4443
4544 /*****************************************************************************
arch/mips/ar7/setup.c+0−1
@@ -23,7 +23,6 @@ · 22 unmodified lines
2323 #include <asm/reboot.h>
2424 #include <asm/mach-ar7/ar7.h>
2525 #include <asm/mach-ar7/prom.h>
26−#include <asm/mach-ar7/gpio.h>
2726
2827 static void ar7_machine_restart(char *command)
2928 {
arch/mips/ath79/Makefile+1−1
@@ -8,7 +8,7 @@ · 7 unmodified lines
88 # under the terms of the GNU General Public License version 2 as published
99 # by the Free Software Foundation.
1010
11−obj-y := prom.o setup.o irq.o common.o clock.o gpio.o
11+obj-y := prom.o setup.o irq.o common.o clock.o
1212
1313 obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
1414 obj-$(CONFIG_PCI) += pci.o
arch/mips/ath79/common.h+0−3
@@ -25,9 +25,6 @@ unsigned long ath79_get_sys_clk_rate(const char *id); · 24 unmodified lines
2525 void ath79_ddr_ctrl_init(void);
2626 void ath79_ddr_wb_flush(unsigned int reg);
2727
28−void ath79_gpio_function_enable(u32 mask);
29−void ath79_gpio_function_disable(u32 mask);
30−void ath79_gpio_function_setup(u32 set, u32 clear);
3128 void ath79_gpio_init(void);
3229
3330 #endif /* __ATH79_COMMON_H */
arch/mips/ath79/irq.c+2−16
@@ -123,8 +123,6 @@ static void ar934x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc) · 122 unmodified lines
123123 {
124124 u32 status;
125125
126− disable_irq_nosync(irq);
127−
128126 status = ath79_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS);
129127
130128 if (status & AR934X_PCIE_WMAC_INT_PCIE_ALL) {
@@ -136,8 +134,6 @@ static void ar934x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc) · 5 unmodified lines
136134 } else {
137135 spurious_interrupt();
138136 }
139−
140− enable_irq(irq);
141137 }
142138
143139 static void ar934x_ip2_irq_init(void)
@@ -156,14 +152,12 @@ static void qca955x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc) · 12 unmodified lines
156152 {
157153 u32 status;
158154
159− disable_irq_nosync(irq);
160−
161155 status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS);
162156 status &= QCA955X_EXT_INT_PCIE_RC1_ALL | QCA955X_EXT_INT_WMAC_ALL;
163157
164158 if (status == 0) {
165159 spurious_interrupt();
166− goto enable;
160+ return;
167161 }
168162
169163 if (status & QCA955X_EXT_INT_PCIE_RC1_ALL) {
@@ -175,17 +169,12 @@ static void qca955x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc) · 5 unmodified lines
175169 /* TODO: flush DDR? */
176170 generic_handle_irq(ATH79_IP2_IRQ(1));
177171 }
178−
179−enable:
180− enable_irq(irq);
181172 }
182173
183174 static void qca955x_ip3_irq_dispatch(unsigned int irq, struct irq_desc *desc)
184175 {
185176 u32 status;
186177
187− disable_irq_nosync(irq);
188−
189178 status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS);
190179 status &= QCA955X_EXT_INT_PCIE_RC2_ALL |
191180 QCA955X_EXT_INT_USB1 |
@@ -193,7 +182,7 @@ static void qca955x_ip3_irq_dispatch(unsigned int irq, struct irq_desc *desc) · 1 unmodified line
193182
194183 if (status == 0) {
195184 spurious_interrupt();
196− goto enable;
185+ return;
197186 }
198187
199188 if (status & QCA955X_EXT_INT_USB1) {
@@ -210,9 +199,6 @@ static void qca955x_ip3_irq_dispatch(unsigned int irq, struct irq_desc *desc) · 10 unmodified lines
210199 /* TODO: flush DDR? */
211200 generic_handle_irq(ATH79_IP3_IRQ(2));
212201 }
213−
214−enable:
215− enable_irq(irq);
216202 }
217203
218204 static void qca955x_irq_init(void)
arch/mips/bcm47xx/buttons.c+1−2
@@ -396,10 +396,9 @@ static int __init bcm47xx_buttons_copy(const struct gpio_keys_button *buttons, · 395 unmodified lines
396396 {
397397 size_t size = nbuttons * sizeof(*buttons);
398398
399− bcm47xx_button_pdata.buttons = kmalloc(size, GFP_KERNEL);
399+ bcm47xx_button_pdata.buttons = kmemdup(buttons, size, GFP_KERNEL);
400400 if (!bcm47xx_button_pdata.buttons)
401401 return -ENOMEM;
402− memcpy(bcm47xx_button_pdata.buttons, buttons, size);
403402 bcm47xx_button_pdata.nbuttons = nbuttons;
404403
405404 return 0;
arch/mips/bcm63xx/irq.c+3−3
@@ -60,7 +60,7 @@ static inline int enable_irq_for_cpu(int cpu, struct irq_data *d, · 59 unmodified lines
6060 if (m)
6161 enable &= cpumask_test_cpu(cpu, m);
6262 else if (irqd_affinity_was_set(d))
63− enable &= cpumask_test_cpu(cpu, d->affinity);
63+ enable &= cpumask_test_cpu(cpu, irq_data_get_affinity_mask(d));
6464 #endif
6565 return enable;
6666 }
@@ -365,9 +365,9 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d, · 298 unmodified lines
365365
366366 irqd_set_trigger_type(d, flow_type);
367367 if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
368− __irq_set_handler_locked(d->irq, handle_level_irq);
368+ irq_set_handler_locked(d, handle_level_irq);
369369 else
370− __irq_set_handler_locked(d->irq, handle_edge_irq);
370+ irq_set_handler_locked(d, handle_edge_irq);
371371
372372 return IRQ_SET_MASK_OK_NOCOPY;
373373 }
arch/mips/boot/compressed/Makefile+1−1
@@ -78,7 +78,7 @@ endif · 77 unmodified lines
7878
7979 vmlinuzobjs-y += $(obj)/piggy.o
8080
81−quiet_cmd_zld = LD $@
81+quiet_cmd_zld = LD $@
8282 cmd_zld = $(LD) $(LDFLAGS) -Ttext $(VMLINUZ_LOAD_ADDRESS) -T $< $(vmlinuzobjs-y) -o $@
8383 quiet_cmd_strip = STRIP $@
8484 cmd_strip = $(STRIP) -s $@
arch/mips/boot/dts/netlogic/xlp_evp.dts+12−0
@@ -110,6 +110,18 @@ · 109 unmodified lines
110110 read-only;
111111 };
112112 };
113+
114+ gpio: xlp_gpio@34100 {
115+ compatible = "netlogic,xlp832-gpio";
116+ reg = <0 0x34100 0x1000>;
117+ #gpio-cells = <2>;
118+ gpio-controller;
119+
120+ #interrupt-cells = <2>;
121+ interrupt-parent = <&pic>;
122+ interrupts = <39>;
123+ interrupt-controller;
124+ };
113125 };
114126
115127 chosen {
arch/mips/boot/dts/netlogic/xlp_fvp.dts+12−0
@@ -110,6 +110,18 @@ · 109 unmodified lines
110110 read-only;
111111 };
112112 };
113+
114+ gpio: xlp_gpio@34100 {
115+ compatible = "netlogic,xlp208-gpio";
116+ reg = <0 0x34100 0x1000>;
117+ #gpio-cells = <2>;
118+ gpio-controller;
119+
120+ #interrupt-cells = <2>;
121+ interrupt-parent = <&pic>;
122+ interrupts = <39>;
123+ interrupt-controller;
124+ };
113125 };
114126
115127 chosen {
arch/mips/boot/dts/netlogic/xlp_gvp.dts+11−0
@@ -69,6 +69,17 @@ · 68 unmodified lines
6969 };
7070 };
7171
72+ gpio: xlp_gpio@114100 {
73+ compatible = "netlogic,xlp980-gpio";
74+ reg = <0 0x114100 0x1000>;
75+ #gpio-cells = <2>;
76+ gpio-controller;
77+
78+ #interrupt-cells = <2>;
79+ interrupt-parent = <&pic>;
80+ interrupts = <39>;
81+ interrupt-controller;
82+ };
7283 };
7384
7485 chosen {
arch/mips/boot/dts/netlogic/xlp_rvp.dts+11−0
@@ -69,6 +69,17 @@ · 68 unmodified lines
6969 };
7070 };
7171
72+ gpio: xlp_gpio@114100 {
73+ compatible = "netlogic,xlp532-gpio";
74+ reg = <0 0x114100 0x1000>;
75+ #gpio-cells = <2>;
76+ gpio-controller;
77+
78+ #interrupt-cells = <2>;
79+ interrupt-parent = <&pic>;
80+ interrupts = <39>;
81+ interrupt-controller;
82+ };
7283 };
7384
7485 chosen {
arch/mips/boot/dts/netlogic/xlp_svp.dts+12−0
@@ -110,6 +110,18 @@ · 109 unmodified lines
110110 read-only;
111111 };
112112 };
113+
114+ gpio: xlp_gpio@34100 {
115+ compatible = "netlogic,xlp316-gpio";
116+ reg = <0 0x34100 0x1000>;
117+ #gpio-cells = <2>;
118+ gpio-controller;
119+
120+ #interrupt-cells = <2>;
121+ interrupt-parent = <&pic>;
122+ interrupts = <39>;
123+ interrupt-controller;
124+ };
113125 };
114126
115127 chosen {
arch/mips/cavium-octeon/executive/cvmx-helper-board.c+6−0
@@ -195,6 +195,12 @@ int cvmx_helper_board_get_mii_address(int ipd_port) · 194 unmodified lines
195195 return 8;
196196 else
197197 return -1;
198+ case CVMX_BOARD_TYPE_KONTRON_S1901:
199+ if (ipd_port == CVMX_HELPER_BOARD_MGMT_IPD_PORT)
200+ return 1;
201+ else
202+ return -1;
203+
198204 }
199205
200206 /* Some unknown board. Somebody forgot to update this function... */
arch/mips/cavium-octeon/executive/cvmx-helper-util.c+16−4
@@ -95,9 +95,9 @@ int cvmx_helper_dump_packet(cvmx_wqe_t *work) · 94 unmodified lines
9595 uint8_t *data_address;
9696 uint8_t *end_of_data;
9797
98− cvmx_dprintf("Packet Length: %u\n", work->len);
99− cvmx_dprintf(" Input Port: %u\n", work->ipprt);
100− cvmx_dprintf(" QoS: %u\n", work->qos);
98+ cvmx_dprintf("Packet Length: %u\n", work->word1.len);
99+ cvmx_dprintf(" Input Port: %u\n", cvmx_wqe_get_port(work));
100+ cvmx_dprintf(" QoS: %u\n", cvmx_wqe_get_qos(work));
101101 cvmx_dprintf(" Buffers: %u\n", work->word2.s.bufs);
102102
103103 if (work->word2.s.bufs == 0) {
@@ -127,7 +127,7 @@ int cvmx_helper_dump_packet(cvmx_wqe_t *work) · 23 unmodified lines
127127 }
128128 } else
129129 buffer_ptr = work->packet_ptr;
130− remaining_bytes = work->len;
130+ remaining_bytes = work->word1.len;
131131
132132 while (remaining_bytes) {
133133 start_of_buffer =
@@ -382,6 +382,10 @@ int cvmx_helper_get_ipd_port(int interface, int port) · 248 unmodified lines
382382 return port + 32;
383383 case 3:
384384 return port + 36;
385+ case 4:
386+ return port + 40;
387+ case 5:
388+ return port + 44;
385389 }
386390 return -1;
387391 }
@@ -404,6 +408,10 @@ int cvmx_helper_get_interface_num(int ipd_port) · 16 unmodified lines
404408 return 2;
405409 else if (ipd_port < 40)
406410 return 3;
411+ else if (ipd_port < 44)
412+ return 4;
413+ else if (ipd_port < 48)
414+ return 5;
407415 else
408416 cvmx_dprintf("cvmx_helper_get_interface_num: Illegal IPD "
409417 "port number\n");
@@ -428,6 +436,10 @@ int cvmx_helper_get_interface_index_num(int ipd_port) · 18 unmodified lines
428436 return ipd_port & 3;
429437 else if (ipd_port < 40)
430438 return ipd_port & 3;
439+ else if (ipd_port < 44)
440+ return ipd_port & 3;
441+ else if (ipd_port < 48)
442+ return ipd_port & 3;
431443 else
432444 cvmx_dprintf("cvmx_helper_get_interface_index_num: "
433445 "Illegal IPD port number\n");
arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c+13−1
@@ -124,6 +124,13 @@ int __cvmx_helper_xaui_enable(int interface) · 123 unmodified lines
124124 union cvmx_gmxx_tx_int_en gmx_tx_int_en;
125125 union cvmx_pcsxx_int_en_reg pcsx_int_en_reg;
126126
127+ /* Setup PKND */
128+ if (octeon_has_feature(OCTEON_FEATURE_PKND)) {
129+ gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(0, interface));
130+ gmx_cfg.s.pknd = cvmx_helper_get_ipd_port(interface, 0);
131+ cvmx_write_csr(CVMX_GMXX_PRTX_CFG(0, interface), gmx_cfg.u64);
132+ }
133+
127134 /* (1) Interface has already been enabled. */
128135
129136 /* (2) Disable GMX. */
@@ -151,7 +158,12 @@ int __cvmx_helper_xaui_enable(int interface) · 21 unmodified lines
151158 /* (4)c Aply reset sequence */
152159 xauiCtl.u64 = cvmx_read_csr(CVMX_PCSXX_CONTROL1_REG(interface));
153160 xauiCtl.s.lo_pwr = 0;
154− xauiCtl.s.reset = 1;
161+
162+ /* Issuing a reset here seems to hang some CN68XX chips. */
163+ if (!OCTEON_IS_MODEL(OCTEON_CN68XX_PASS1_X) &&
164+ !OCTEON_IS_MODEL(OCTEON_CN68XX_PASS2_X))
165+ xauiCtl.s.reset = 1;
166+
155167 cvmx_write_csr(CVMX_PCSXX_CONTROL1_REG(interface), xauiCtl.u64);
156168
157169 /* Wait for PCS to come out of reset */
arch/mips/cavium-octeon/executive/cvmx-helper.c+17−0
@@ -83,6 +83,8 @@ static cvmx_helper_link_info_t · 82 unmodified lines
8383 */
8484 int cvmx_helper_get_number_of_interfaces(void)
8585 {
86+ if (OCTEON_IS_MODEL(OCTEON_CN68XX))
87+ return 9;
8688 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
8789 return 4;
8890 else
@@ -656,6 +658,21 @@ static int __cvmx_helper_global_setup_pko(void) · 567 unmodified lines
656658 fau_to.s.tout_val = 0xfff;
657659 fau_to.s.tout_enb = 0;
658660 cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_to.u64);
661+
662+ if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
663+ union cvmx_pko_reg_min_pkt min_pkt;
664+
665+ min_pkt.u64 = 0;
666+ min_pkt.s.size1 = 59;
667+ min_pkt.s.size2 = 59;
668+ min_pkt.s.size3 = 59;
669+ min_pkt.s.size4 = 59;
670+ min_pkt.s.size5 = 59;
671+ min_pkt.s.size6 = 59;
672+ min_pkt.s.size7 = 59;
673+ cvmx_write_csr(CVMX_PKO_REG_MIN_PKT, min_pkt.u64);
674+ }
675+
659676 return 0;
660677 }
661678
arch/mips/cavium-octeon/executive/cvmx-pko.c+144−5
@@ -39,6 +39,143 @@ · 38 unmodified lines
3939 * Internal state of packet output
4040 */
4141
42+static int __cvmx_pko_int(int interface, int index)
43+{
44+ switch (interface) {
45+ case 0:
46+ return index;
47+ case 1:
48+ return 4;
49+ case 2:
50+ return index + 0x08;
51+ case 3:
52+ return index + 0x0c;
53+ case 4:
54+ return index + 0x10;
55+ case 5:
56+ return 0x1c;
57+ case 6:
58+ return 0x1d;
59+ case 7:
60+ return 0x1e;
61+ case 8:
62+ return 0x1f;
63+ default:
64+ return -1;
65+ }
66+}
67+
68+static void __cvmx_pko_iport_config(int pko_port)
69+{
70+ int queue;
71+ const int num_queues = 1;
72+ const int base_queue = pko_port;
73+ const int static_priority_end = 1;
74+ const int static_priority_base = 1;
75+
76+ for (queue = 0; queue < num_queues; queue++) {
77+ union cvmx_pko_mem_iqueue_ptrs config;
78+ cvmx_cmd_queue_result_t cmd_res;
79+ uint64_t *buf_ptr;
80+
81+ config.u64 = 0;
82+ config.s.index = queue;
83+ config.s.qid = base_queue + queue;
84+ config.s.ipid = pko_port;
85+ config.s.tail = (queue == (num_queues - 1));
86+ config.s.s_tail = (queue == static_priority_end);
87+ config.s.static_p = (static_priority_base >= 0);
88+ config.s.static_q = (queue <= static_priority_end);
89+ config.s.qos_mask = 0xff;
90+
91+ cmd_res = cvmx_cmd_queue_initialize(
92+ CVMX_CMD_QUEUE_PKO(base_queue + queue),
93+ CVMX_PKO_MAX_QUEUE_DEPTH,
94+ CVMX_FPA_OUTPUT_BUFFER_POOL,
95+ (CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE -
96+ CVMX_PKO_COMMAND_BUFFER_SIZE_ADJUST * 8));
97+
98+ WARN(cmd_res,
99+ "%s: cmd_res=%d pko_port=%d base_queue=%d num_queues=%d queue=%d\n",
100+ __func__, (int)cmd_res, pko_port, base_queue,
101+ num_queues, queue);
102+
103+ buf_ptr = (uint64_t *)cvmx_cmd_queue_buffer(
104+ CVMX_CMD_QUEUE_PKO(base_queue + queue));
105+ config.s.buf_ptr = cvmx_ptr_to_phys(buf_ptr) >> 7;
106+ CVMX_SYNCWS;
107+ cvmx_write_csr(CVMX_PKO_MEM_IQUEUE_PTRS, config.u64);
108+ }
109+}
110+
111+static void __cvmx_pko_queue_alloc_o68(void)
112+{
113+ int port;
114+
115+ for (port = 0; port < 48; port++)
116+ __cvmx_pko_iport_config(port);
117+}
118+
119+static void __cvmx_pko_port_map_o68(void)
120+{
121+ int port;
122+ int interface, index;
123+ cvmx_helper_interface_mode_t mode;
124+ union cvmx_pko_mem_iport_ptrs config;
125+
126+ /*
127+ * Initialize every iport with the invalid eid.
128+ */
129+ config.u64 = 0;
130+ config.s.eid = 31; /* Invalid */
131+ for (port = 0; port < 128; port++) {
132+ config.s.ipid = port;
133+ cvmx_write_csr(CVMX_PKO_MEM_IPORT_PTRS, config.u64);
134+ }
135+
136+ /*
137+ * Set up PKO_MEM_IPORT_PTRS
138+ */
139+ for (port = 0; port < 48; port++) {
140+ interface = cvmx_helper_get_interface_num(port);
141+ index = cvmx_helper_get_interface_index_num(port);
142+ mode = cvmx_helper_interface_get_mode(interface);
143+ if (mode == CVMX_HELPER_INTERFACE_MODE_DISABLED)
144+ continue;
145+
146+ config.s.ipid = port;
147+ config.s.qos_mask = 0xff;
148+ config.s.crc = 1;
149+ config.s.min_pkt = 1;
150+ config.s.intr = __cvmx_pko_int(interface, index);
151+ config.s.eid = config.s.intr;
152+ config.s.pipe = (mode == CVMX_HELPER_INTERFACE_MODE_LOOP) ?
153+ index : port;
154+ cvmx_write_csr(CVMX_PKO_MEM_IPORT_PTRS, config.u64);
155+ }
156+}
157+
158+static void __cvmx_pko_chip_init(void)
159+{
160+ int i;
161+
162+ if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
163+ __cvmx_pko_port_map_o68();
164+ __cvmx_pko_queue_alloc_o68();
165+ return;
166+ }
167+
168+ /*
169+ * Initialize queues
170+ */
171+ for (i = 0; i < CVMX_PKO_MAX_OUTPUT_QUEUES; i++) {
172+ const uint64_t priority = 8;
173+
174+ cvmx_pko_config_port(CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID, i, 1,
175+ &priority);
176+ }
177+}
178+
42179 /**
43180 * Call before any other calls to initialize the packet
44181 * output system. This does chip global config, and should only be
@@ -47,8 +184,6 @@ · 2 unmodified lines
47184
48185 void cvmx_pko_initialize_global(void)
49186 {
50− int i;
51− uint64_t priority = 8;
52187 union cvmx_pko_reg_cmd_buf config;
53188
54189 /*
@@ -62,9 +197,10 @@ void cvmx_pko_initialize_global(void) · 7 unmodified lines
62197
63198 cvmx_write_csr(CVMX_PKO_REG_CMD_BUF, config.u64);
64199
65− for (i = 0; i < CVMX_PKO_MAX_OUTPUT_QUEUES; i++)
66− cvmx_pko_config_port(CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID, i, 1,
67− &priority);
200+ /*
201+ * Chip-specific setup.
202+ */
203+ __cvmx_pko_chip_init();
68204
69205 /*
70206 * If we aren't using all of the queues optimize PKO's
@@ -212,6 +348,9 @@ cvmx_pko_status_t cvmx_pko_config_port(uint64_t port, uint64_t base_queue, · 141 unmodified lines
212348 int static_priority_base = -1;
213349 int static_priority_end = -1;
214350
351+ if (OCTEON_IS_MODEL(OCTEON_CN68XX))
352+ return CVMX_PKO_SUCCESS;
353+
215354 if ((port >= CVMX_PKO_NUM_OUTPUT_PORTS)
216355 && (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID)) {
217356 cvmx_dprintf("ERROR: cvmx_pko_config_port: Invalid port %llu\n",
arch/mips/cavium-octeon/octeon-irq.c+19−17
@@ -225,13 +225,14 @@ static int next_cpu_for_irq(struct irq_data *data) · 224 unmodified lines
225225
226226 #ifdef CONFIG_SMP
227227 int cpu;
228− int weight = cpumask_weight(data->affinity);
228+ struct cpumask *mask = irq_data_get_affinity_mask(data);
229+ int weight = cpumask_weight(mask);
229230 struct octeon_ciu_chip_data *cd = irq_data_get_irq_chip_data(data);
230231
231232 if (weight > 1) {
232233 cpu = cd->current_cpu;
233234 for (;;) {
234− cpu = cpumask_next(cpu, data->affinity);
235+ cpu = cpumask_next(cpu, mask);
235236 if (cpu >= nr_cpu_ids) {
236237 cpu = -1;
237238 continue;
@@ -240,7 +241,7 @@ static int next_cpu_for_irq(struct irq_data *data) · 2 unmodified lines
240241 }
241242 }
242243 } else if (weight == 1) {
243− cpu = cpumask_first(data->affinity);
244+ cpu = cpumask_first(mask);
244245 } else {
245246 cpu = smp_processor_id();
246247 }
@@ -662,6 +663,11 @@ static int octeon_irq_ciu_gpio_set_type(struct irq_data *data, unsigned int t) · 415 unmodified lines
662663 irqd_set_trigger_type(data, t);
663664 octeon_irq_gpio_setup(data);
664665
666+ if (irqd_get_trigger_type(data) & IRQ_TYPE_EDGE_BOTH)
667+ irq_set_handler_locked(data, handle_edge_irq);
668+ else
669+ irq_set_handler_locked(data, handle_level_irq);
670+
665671 return IRQ_SET_MASK_OK;
666672 }
667673
@@ -696,32 +702,23 @@ static void octeon_irq_ciu_gpio_ack(struct irq_data *data) · 28 unmodified lines
696702 cvmx_write_csr(CVMX_GPIO_INT_CLR, mask);
697703 }
698704
699−static void octeon_irq_handle_trigger(unsigned int irq, struct irq_desc *desc)
700−{
701− struct irq_data *data = irq_desc_get_irq_data(desc);
702−
703− if (irqd_get_trigger_type(data) & IRQ_TYPE_EDGE_BOTH)
704− handle_edge_irq(irq, desc);
705− else
706− handle_level_irq(irq, desc);
707−}
708−
709705 #ifdef CONFIG_SMP
710706
711707 static void octeon_irq_cpu_offline_ciu(struct irq_data *data)
712708 {
713709 int cpu = smp_processor_id();
714710 cpumask_t new_affinity;
711+ struct cpumask *mask = irq_data_get_affinity_mask(data);
715712
716− if (!cpumask_test_cpu(cpu, data->affinity))
713+ if (!cpumask_test_cpu(cpu, mask))
717714 return;
718715
719− if (cpumask_weight(data->affinity) > 1) {
716+ if (cpumask_weight(mask) > 1) {
720717 /*
721718 * It has multi CPU affinity, just remove this CPU
722719 * from the affinity set.
723720 */
724− cpumask_copy(&new_affinity, data->affinity);
721+ cpumask_copy(&new_affinity, mask);
725722 cpumask_clear_cpu(cpu, &new_affinity);
726723 } else {
727724 /* Otherwise, put it on lowest numbered online CPU. */
@@ -1227,8 +1224,13 @@ static int octeon_irq_gpio_map(struct irq_domain *d, · 499 unmodified lines
12271224 octeon_irq_ciu_to_irq[line][bit] != 0)
12281225 return -EINVAL;
12291226
1227+ /*
1228+ * Default to handle_level_irq. If the DT contains a different
1229+ * trigger type, it will call the irq_set_type callback and
1230+ * the handler gets updated.
1231+ */
12301232 r = octeon_irq_set_ciu_mapping(virq, line, bit, hw,
1231− octeon_irq_gpio_chip, octeon_irq_handle_trigger);
1233+ octeon_irq_gpio_chip, handle_level_irq);
12321234 return r;
12331235 }
12341236
arch/mips/include/asm/Kbuild+0−1
@@ -16,6 +16,5 @@ generic-y += sections.h · 15 unmodified lines
1616 generic-y += segment.h
1717 generic-y += serial.h
1818 generic-y += trace_clock.h
19−generic-y += ucontext.h
2019 generic-y += user.h
2120 generic-y += xor.h
arch/mips/include/asm/abi.h+4−0
@@ -20,6 +20,10 @@ struct mips_abi { · 19 unmodified lines
2020 struct pt_regs *regs, sigset_t *set);
2121 const unsigned long rt_signal_return_offset;
2222 const unsigned long restart;
23+
24+ unsigned off_sc_fpregs;
25+ unsigned off_sc_fpc_csr;
26+ unsigned off_sc_used_math;
2327 };
2428
2529 #endif /* _ASM_ABI_H */
arch/mips/include/asm/asmmacro.h+114−0
@@ -232,6 +232,30 @@ · 231 unmodified lines
232232 .set pop
233233 .endm
234234
235+ .macro ld_b wd, off, base
236+ .set push
237+ .set mips32r2
238+ .set msa
239+ ld.b $w\wd, \off(\base)
240+ .set pop
241+ .endm
242+
243+ .macro ld_h wd, off, base
244+ .set push
245+ .set mips32r2
246+ .set msa
247+ ld.h $w\wd, \off(\base)
248+ .set pop
249+ .endm
250+
251+ .macro ld_w wd, off, base
252+ .set push
253+ .set mips32r2
254+ .set msa
255+ ld.w $w\wd, \off(\base)
256+ .set pop
257+ .endm
258+
235259 .macro ld_d wd, off, base
236260 .set push
237261 .set mips32r2
@@ -241,6 +265,30 @@ · 3 unmodified lines
241265 .set pop
242266 .endm
243267
268+ .macro st_b wd, off, base
269+ .set push
270+ .set mips32r2
271+ .set msa
272+ st.b $w\wd, \off(\base)
273+ .set pop
274+ .endm
275+
276+ .macro st_h wd, off, base
277+ .set push
278+ .set mips32r2
279+ .set msa
280+ st.h $w\wd, \off(\base)
281+ .set pop
282+ .endm
283+
284+ .macro st_w wd, off, base
285+ .set push
286+ .set mips32r2
287+ .set msa
288+ st.w $w\wd, \off(\base)
289+ .set pop
290+ .endm
291+
244292 .macro st_d wd, off, base
245293 .set push
246294 .set mips32r2
@@ -290,7 +338,13 @@ · 43 unmodified lines
290338 #ifdef CONFIG_CPU_MICROMIPS
291339 #define CFC_MSA_INSN 0x587e0056
292340 #define CTC_MSA_INSN 0x583e0816
341+#define LDB_MSA_INSN 0x58000807
342+#define LDH_MSA_INSN 0x58000817
343+#define LDW_MSA_INSN 0x58000827
293344 #define LDD_MSA_INSN 0x58000837
345+#define STB_MSA_INSN 0x5800080f
346+#define STH_MSA_INSN 0x5800081f
347+#define STW_MSA_INSN 0x5800082f
294348 #define STD_MSA_INSN 0x5800083f
295349 #define COPY_UW_MSA_INSN 0x58f00056
296350 #define COPY_UD_MSA_INSN 0x58f80056
@@ -299,7 +353,13 @@ · 2 unmodified lines
299353 #else
300354 #define CFC_MSA_INSN 0x787e0059
301355 #define CTC_MSA_INSN 0x783e0819
356+#define LDB_MSA_INSN 0x78000820
357+#define LDH_MSA_INSN 0x78000821
358+#define LDW_MSA_INSN 0x78000822
302359 #define LDD_MSA_INSN 0x78000823
360+#define STB_MSA_INSN 0x78000824
361+#define STH_MSA_INSN 0x78000825
362+#define STW_MSA_INSN 0x78000826
303363 #define STD_MSA_INSN 0x78000827
304364 #define COPY_UW_MSA_INSN 0x78f00059
305365 #define COPY_UD_MSA_INSN 0x78f80059
@@ -329,6 +389,33 @@ · 23 unmodified lines
329389 .set pop
330390 .endm
331391
392+ .macro ld_b wd, off, base
393+ .set push
394+ .set noat
395+ SET_HARDFLOAT
396+ addu $1, \base, \off
397+ .word LDB_MSA_INSN | (\wd << 6)
398+ .set pop
399+ .endm
400+
401+ .macro ld_h wd, off, base
402+ .set push
403+ .set noat
404+ SET_HARDFLOAT
405+ addu $1, \base, \off
406+ .word LDH_MSA_INSN | (\wd << 6)
407+ .set pop
408+ .endm
409+
410+ .macro ld_w wd, off, base
411+ .set push
412+ .set noat
413+ SET_HARDFLOAT
414+ addu $1, \base, \off
415+ .word LDW_MSA_INSN | (\wd << 6)
416+ .set pop
417+ .endm
418+
332419 .macro ld_d wd, off, base
333420 .set push
334421 .set noat
@@ -338,6 +425,33 @@ · 3 unmodified lines
338425 .set pop
339426 .endm
340427
428+ .macro st_b wd, off, base
429+ .set push
430+ .set noat
431+ SET_HARDFLOAT
432+ addu $1, \base, \off
433+ .word STB_MSA_INSN | (\wd << 6)
434+ .set pop
435+ .endm
436+
437+ .macro st_h wd, off, base
438+ .set push
439+ .set noat
440+ SET_HARDFLOAT
441+ addu $1, \base, \off
442+ .word STH_MSA_INSN | (\wd << 6)
443+ .set pop
444+ .endm
445+
446+ .macro st_w wd, off, base
447+ .set push
448+ .set noat
449+ SET_HARDFLOAT
450+ addu $1, \base, \off
451+ .word STW_MSA_INSN | (\wd << 6)
452+ .set pop
453+ .endm
454+
341455 .macro st_d wd, off, base
342456 .set push
343457 .set noat
arch/mips/include/asm/cdmm.h+2−2
@@ -53,7 +53,7 @@ struct mips_cdmm_driver { · 52 unmodified lines
5353 * mips_cdmm_phys_base() - Choose a physical base address for CDMM region.
5454 *
5555 * Picking a suitable physical address at which to map the CDMM region is
56− * platform specific, so this weak function can be defined by platform code to
56+ * platform specific, so this function can be defined by platform code to
5757 * pick a suitable value if none is configured by the bootloader.
5858 *
5959 * This address must be 32kB aligned, and the region occupies a maximum of 32kB
@@ -61,7 +61,7 @@ struct mips_cdmm_driver { · 1 unmodified line
6161 *
6262 * Returns: Physical base address for CDMM region, or 0 on failure.
6363 */
64−phys_addr_t __weak mips_cdmm_phys_base(void);
64+phys_addr_t mips_cdmm_phys_base(void);
6565
6666 extern struct bus_type mips_cdmm_bustype;
6767 void __iomem *mips_cdmm_early_probe(unsigned int dev_type);
arch/mips/include/asm/cevt-r4k.h+0−1
@@ -21,7 +21,6 @@ DECLARE_PER_CPU(struct clock_event_device, mips_clockevent_device); · 20 unmodified lines
2121
2222 void mips_event_handler(struct clock_event_device *dev);
2323 int c0_compare_int_usable(void);
24−void mips_set_clock_mode(enum clock_event_mode, struct clock_event_device *);
2524 irqreturn_t c0_compare_interrupt(int, void *);
2625
2726 extern struct irqaction c0_compare_irqaction;
arch/mips/include/asm/cpu-features.h+4−0
@@ -411,4 +411,8 @@ · 410 unmodified lines
411411 # define cpu_has_cdmm (cpu_data[0].options & MIPS_CPU_CDMM)
412412 #endif
413413
414+#ifndef cpu_has_small_pages
415+# define cpu_has_small_pages (cpu_data[0].options & MIPS_CPU_SP)
416+#endif
417+
414418 #endif /* __ASM_CPU_FEATURES_H */
arch/mips/include/asm/cpu-type.h+4−0
@@ -77,6 +77,10 @@ static inline int __pure __get_cpu_type(const int cpu_type) · 76 unmodified lines
7777 */
7878 #endif
7979
80+#ifdef CONFIG_SYS_HAS_CPU_MIPS64_R6
81+ case CPU_I6400:
82+#endif
83+
8084 #ifdef CONFIG_SYS_HAS_CPU_R3000
8185 case CPU_R2000:
8286 case CPU_R3000:
arch/mips/include/asm/cpu.h+3−0
@@ -120,6 +120,7 @@ · 119 unmodified lines
120120 #define PRID_IMP_PROAPTIV_MP 0xa300
121121 #define PRID_IMP_M5150 0xa700
122122 #define PRID_IMP_P5600 0xa800
123+#define PRID_IMP_I6400 0xa900
123124
124125 /*
125126 * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE
@@ -307,6 +308,7 @@ enum cpu_type_enum { · 181 unmodified lines
307308 CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350,
308309 CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_LOONGSON1, CPU_M14KC,
309310 CPU_M14KEC, CPU_INTERAPTIV, CPU_P5600, CPU_PROAPTIV, CPU_1074K, CPU_M5150,
311+ CPU_I6400,
310312
311313 /*
312314 * MIPS64 class processors
@@ -382,6 +384,7 @@ enum cpu_type_enum { · 69 unmodified lines
382384 #define MIPS_CPU_XPA 0x2000000000ull /* CPU supports Extended Physical Addressing */
383385 #define MIPS_CPU_CDMM 0x4000000000ull /* CPU has Common Device Memory Map */
384386 #define MIPS_CPU_BP_GHIST 0x8000000000ull /* R12K+ Branch Prediction Global History */
387+#define MIPS_CPU_SP 0x10000000000ull /* Small (1KB) page support */
385388
386389 /*
387390 * CPU ASE encodings
arch/mips/include/asm/debug.h+0−48
@@ -1,48 +0,0 @@
1−/*
2− * Debug macros for run-time debugging.
3− * Turned on/off with CONFIG_RUNTIME_DEBUG option.
4− *
5− * Copyright (C) 2001 MontaVista Software Inc.
6− * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
7− *
8− * This program is free software; you can redistribute it and/or modify it
9− * under the terms of the GNU General Public License as published by the
10− * Free Software Foundation; either version 2 of the License, or (at your
11− * option) any later version.
12− *
13− */
14−
15−#ifndef _ASM_DEBUG_H
16−#define _ASM_DEBUG_H
17−
18−
19−/*
20− * run-time macros for catching spurious errors. Eable CONFIG_RUNTIME_DEBUG in
21− * kernel hacking config menu to use them.
22− *
23− * Use them as run-time debugging aid. NEVER USE THEM AS ERROR HANDLING CODE!!!
24− */
25−
26−#ifdef CONFIG_RUNTIME_DEBUG
27−
28−#include <linux/kernel.h>
29−
30−#define db_assert(x) if (!(x)) { \
31− panic("assertion failed at %s:%d: %s", __FILE__, __LINE__, #x); }
32−#define db_warn(x) if (!(x)) { \
33− printk(KERN_WARNING "warning at %s:%d: %s", __FILE__, __LINE__, #x); }
34−#define db_verify(x, y) db_assert(x y)
35−#define db_verify_warn(x, y) db_warn(x y)
36−#define db_run(x) do { x; } while (0)
37−
38−#else
39−
40−#define db_assert(x)
41−#define db_warn(x)
42−#define db_verify(x, y) x
43−#define db_verify_warn(x, y) x
44−#define db_run(x)
45−
46−#endif
47−
48−#endif /* _ASM_DEBUG_H */
arch/mips/include/asm/elf.h+3−1
@@ -382,7 +382,9 @@ do { \ · 381 unmodified lines
382382 instruction set this cpu supports. This could be done in userspace,
383383 but it's not easy, and we've already done it here. */
384384
385−#define ELF_HWCAP (0)
385+#define ELF_HWCAP (elf_hwcap)
386+extern unsigned int elf_hwcap;
387+#include <asm/hwcap.h>
386388
387389 /*
388390 * This yields a string that ld.so will use to load implementation
arch/mips/include/asm/fpu.h+13−8
@@ -164,25 +164,30 @@ static inline int own_fpu(int restore) · 163 unmodified lines
164164 return ret;
165165 }
166166
167−static inline void lose_fpu(int save)
167+static inline void lose_fpu_inatomic(int save, struct task_struct *tsk)
168168 {
169− preempt_disable();
170169 if (is_msa_enabled()) {
171170 if (save) {
172− save_msa(current);
173− current->thread.fpu.fcr31 =
171+ save_msa(tsk);
172+ tsk->thread.fpu.fcr31 =
174173 read_32bit_cp1_register(CP1_STATUS);
175174 }
176175 disable_msa();
177− clear_thread_flag(TIF_USEDMSA);
176+ clear_tsk_thread_flag(tsk, TIF_USEDMSA);
178177 __disable_fpu();
179178 } else if (is_fpu_owner()) {
180179 if (save)
181− _save_fp(current);
180+ _save_fp(tsk);
182181 __disable_fpu();
183182 }
184− KSTK_STATUS(current) &= ~ST0_CU1;
185− clear_thread_flag(TIF_USEDFPU);
183+ KSTK_STATUS(tsk) &= ~ST0_CU1;
184+ clear_tsk_thread_flag(tsk, TIF_USEDFPU);
185+}
186+
187+static inline void lose_fpu(int save)
188+{
189+ preempt_disable();
190+ lose_fpu_inatomic(save, current);
186191 preempt_enable();
187192 }
188193
arch/mips/include/asm/gpio.h+0−6
@@ -1,6 +0,0 @@
1−#ifndef __ASM_MIPS_GPIO_H
2−#define __ASM_MIPS_GPIO_H
3−
4−#include <gpio.h>
5−
6−#endif /* __ASM_MIPS_GPIO_H */
arch/mips/include/asm/irq.h+1−1
@@ -49,7 +49,7 @@ extern int cp0_compare_irq_shift; · 48 unmodified lines
4949 extern int cp0_perfcount_irq;
5050 extern int cp0_fdc_irq;
5151
52−extern int __weak get_c0_fdc_int(void);
52+extern int get_c0_fdc_int(void);
5353
5454 void arch_trigger_all_cpu_backtrace(bool);
5555 #define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace
arch/mips/include/asm/kdebug.h+3−1
@@ -11,7 +11,9 @@ enum die_val { · 10 unmodified lines
1111 DIE_PAGE_FAULT,
1212 DIE_BREAK,
1313 DIE_SSTEPBP,
14− DIE_MSAFP
14+ DIE_MSAFP,
15+ DIE_UPROBE,
16+ DIE_UPROBE_XOL,
1517 };
1618
1719 #endif /* _ASM_MIPS_KDEBUG_H */
arch/mips/include/asm/linkage.h+0−1
@@ -5,7 +5,6 @@ · 4 unmodified lines
55 #include <asm/asm.h>
66 #endif
77
8−#define __weak __attribute__((weak))
98 #define cond_syscall(x) asm(".weak\t" #x "\n" #x "\t=\tsys_ni_syscall")
109 #define SYSCALL_ALIAS(alias, name) \
1110 asm ( #alias " = " #name "\n\t.globl " #alias)
arch/mips/include/asm/maar.h+1−1
@@ -26,7 +26,7 @@ · 25 unmodified lines
2626 *
2727 * Return: The number of MAAR pairs configured.
2828 */
29−unsigned __weak platform_maar_init(unsigned num_pairs);
29+unsigned platform_maar_init(unsigned num_pairs);
3030
3131 /**
3232 * write_maar_pair() - write to a pair of MAARs
arch/mips/include/asm/mach-ar7/ar7.h+4−0
@@ -203,4 +203,8 @@ static inline void ar7_device_off(u32 bit) · 202 unmodified lines
203203 int __init ar7_gpio_init(void);
204204 void __init ar7_init_clocks(void);
205205
206+/* Board specific GPIO functions */
207+int ar7_gpio_enable(unsigned gpio);
208+int ar7_gpio_disable(unsigned gpio);
209+
206210 #endif /* __AR7_H__ */
arch/mips/include/asm/mach-ar7/gpio.h+0−41
@@ -1,41 +0,0 @@
1−/*
2− * Copyright (C) 2007-2009 Florian Fainelli <florian@openwrt.org>
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; either version 2 of the License, or
7− * (at your option) any later version.
8− *
9− * This program is distributed in the hope that it will be useful,
10− * but WITHOUT ANY WARRANTY; without even the implied warranty of
11− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12− * GNU General Public License for more details.
13− *
14− * You should have received a copy of the GNU General Public License
15− * along with this program; if not, write to the Free Software
16− * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17− */
18−
19−#ifndef __AR7_GPIO_H__
20−#define __AR7_GPIO_H__
21−
22−#include <asm/mach-ar7/ar7.h>
23−
24−#define AR7_GPIO_MAX 32
25−#define TITAN_GPIO_MAX 51
26−#define NR_BUILTIN_GPIO TITAN_GPIO_MAX
27−
28−#define gpio_to_irq(gpio) -1
29−
30−#define gpio_get_value __gpio_get_value
31−#define gpio_set_value __gpio_set_value
32−
33−#define gpio_cansleep __gpio_cansleep
34−
35−/* Board specific GPIO functions */
36−int ar7_gpio_enable(unsigned gpio);
37−int ar7_gpio_disable(unsigned gpio);
38−
39−#include <asm-generic/gpio.h>
40−
41−#endif
arch/mips/include/asm/mach-ath25/gpio.h+0−16
@@ -1,16 +0,0 @@
1−#ifndef __ASM_MACH_ATH25_GPIO_H
2−#define __ASM_MACH_ATH25_GPIO_H
3−
4−#include <asm-generic/gpio.h>
5−
6−#define gpio_get_value __gpio_get_value
7−#define gpio_set_value __gpio_set_value
8−#define gpio_cansleep __gpio_cansleep
9−#define gpio_to_irq __gpio_to_irq
10−
11−static inline int irq_to_gpio(unsigned irq)
12−{
13− return -EINVAL;
14−}
15−
16−#endif /* __ASM_MACH_ATH25_GPIO_H */
arch/mips/include/asm/mach-ath79/gpio.h+0−26
@@ -1,26 +0,0 @@
1−/*
2− * Atheros AR71XX/AR724X/AR913X GPIO API definitions
3− *
4− * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
5− * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
6− *
7− * This program is free software; you can redistribute it and/or modify it
8− * under the terms of the GNU General Public License version 2 as published
9− * by the Free Software Foundation.
10− *
11− */
12−
13−#ifndef __ASM_MACH_ATH79_GPIO_H
14−#define __ASM_MACH_ATH79_GPIO_H
15−
16−#define ARCH_NR_GPIOS 64
17−#include <asm-generic/gpio.h>
18−
19−int gpio_to_irq(unsigned gpio);
20−int irq_to_gpio(unsigned irq);
21−int gpio_get_value(unsigned gpio);
22−void gpio_set_value(unsigned gpio, int value);
23−
24−#define gpio_cansleep __gpio_cansleep
25−
26−#endif /* __ASM_MACH_ATH79_GPIO_H */
arch/mips/include/asm/mach-au1x00/gpio-au1000.h+11−137
@@ -266,6 +266,17 @@ static inline int alchemy_gpio1_to_irq(int gpio) · 265 unmodified lines
266266 return -ENXIO;
267267 }
268268
269+/* On Au1000, Au1500 and Au1100 GPIOs won't work as inputs before
270+ * SYS_PININPUTEN is written to at least once. On Au1550/Au1200/Au1300 this
271+ * register enables use of GPIOs as wake source.
272+ */
273+static inline void alchemy_gpio1_input_enable(void)
274+{
275+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
276+ __raw_writel(0, base + 0x110); /* the write op is key */
277+ wmb();
278+}
279+
269280 /*
270281 * GPIO2 block macros for common linux GPIO functions. The 'gpio'
271282 * parameter must be in range of ALCHEMY_GPIO2_BASE..ALCHEMY_GPIO2_MAX.
@@ -518,141 +529,4 @@ static inline int alchemy_irq_to_gpio(int irq) · 246 unmodified lines
518529 return -ENXIO;
519530 }
520531
521−/**********************************************************************/
522−
523−/* Linux gpio framework integration.
524− *
525− * 4 use cases of Au1000-Au1200 GPIOS:
526− *(1) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=y:
527− * Board must register gpiochips.
528− *(2) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=n:
529− * 2 (1 for Au1000) gpio_chips are registered.
530− *
531− *(3) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=y:
532− * the boards' gpio.h must provide the linux gpio wrapper functions,
533− *
534− *(4) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=n:
535− * inlinable gpio functions are provided which enable access to the
536− * Au1000 gpios only by using the numbers straight out of the data-
537− * sheets.
538−
539− * Cases 1 and 3 are intended for boards which want to provide their own
540− * GPIO namespace and -operations (i.e. for example you have 8 GPIOs
541− * which are in part provided by spare Au1000 GPIO pins and in part by
542− * an external FPGA but you still want them to be accssible in linux
543− * as gpio0-7. The board can of course use the alchemy_gpioX_* functions
544− * as required).
545− */
546−
547−#ifndef CONFIG_GPIOLIB
548−
549−#ifdef CONFIG_ALCHEMY_GPIOINT_AU1000
550−
551−#ifndef CONFIG_ALCHEMY_GPIO_INDIRECT /* case (4) */
552−
553−static inline int gpio_direction_input(int gpio)
554−{
555− return alchemy_gpio_direction_input(gpio);
556−}
557−
558−static inline int gpio_direction_output(int gpio, int v)
559−{
560− return alchemy_gpio_direction_output(gpio, v);
561−}
562−
563−static inline int gpio_get_value(int gpio)
564−{
565− return alchemy_gpio_get_value(gpio);
566−}
567−
568−static inline void gpio_set_value(int gpio, int v)
569−{
570− alchemy_gpio_set_value(gpio, v);
571−}
572−
573−static inline int gpio_get_value_cansleep(unsigned gpio)
574−{
575− return gpio_get_value(gpio);
576−}
577−
578−static inline void gpio_set_value_cansleep(unsigned gpio, int value)
579−{
580− gpio_set_value(gpio, value);
581−}
582−
583−static inline int gpio_is_valid(int gpio)
584−{
585− return alchemy_gpio_is_valid(gpio);
586−}
587−
588−static inline int gpio_cansleep(int gpio)
589−{
590− return alchemy_gpio_cansleep(gpio);
591−}
592−
593−static inline int gpio_to_irq(int gpio)
594−{
595− return alchemy_gpio_to_irq(gpio);
596−}
597−
598−static inline int irq_to_gpio(int irq)
599−{
600− return alchemy_irq_to_gpio(irq);
601−}
602−
603−static inline int gpio_request(unsigned gpio, const char *label)
604−{
605− return 0;
606−}
607−
608−static inline int gpio_request_one(unsigned gpio,
609− unsigned long flags, const char *label)
610−{
611− return 0;
612−}
613−
614−static inline int gpio_request_array(struct gpio *array, size_t num)
615−{
616− return 0;
617−}
618−
619−static inline void gpio_free(unsigned gpio)
620−{
621−}
622−
623−static inline void gpio_free_array(struct gpio *array, size_t num)
624−{
625−}
626−
627−static inline int gpio_set_debounce(unsigned gpio, unsigned debounce)
628−{
629− return -ENOSYS;
630−}
631−
632−static inline int gpio_export(unsigned gpio, bool direction_may_change)
633−{
634− return -ENOSYS;
635−}
636−
637−static inline int gpio_export_link(struct device *dev, const char *name,
638− unsigned gpio)
639−{
640− return -ENOSYS;
641−}
642−
643−static inline int gpio_sysfs_set_active_low(unsigned gpio, int value)
644−{
645− return -ENOSYS;
646−}
647−
648−static inline void gpio_unexport(unsigned gpio)
649−{
650−}
651−
652−#endif /* !CONFIG_ALCHEMY_GPIO_INDIRECT */
653−
654−#endif /* CONFIG_ALCHEMY_GPIOINT_AU1000 */
655−
656−#endif /* !CONFIG_GPIOLIB */
657−
658532 #endif /* _ALCHEMY_GPIO_AU1000_H_ */
arch/mips/include/asm/mach-au1x00/gpio.h+0−86
@@ -1,86 +0,0 @@
1−/*
2− * Alchemy GPIO support.
3− *
4− * With CONFIG_GPIOLIB=y different types of on-chip GPIO can be supported within
5− * the same kernel image.
6− * With CONFIG_GPIOLIB=n, your board must select ALCHEMY_GPIOINT_AU1XXX for the
7− * appropriate CPU type (AU1000 currently).
8− */
9−
10−#ifndef _ALCHEMY_GPIO_H_
11−#define _ALCHEMY_GPIO_H_
12−
13−#include <asm/mach-au1x00/au1000.h>
14−#include <asm/mach-au1x00/gpio-au1000.h>
15−#include <asm/mach-au1x00/gpio-au1300.h>
16−
17−/* On Au1000, Au1500 and Au1100 GPIOs won't work as inputs before
18− * SYS_PININPUTEN is written to at least once. On Au1550/Au1200/Au1300 this
19− * register enables use of GPIOs as wake source.
20− */
21−static inline void alchemy_gpio1_input_enable(void)
22−{
23− void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
24− __raw_writel(0, base + 0x110); /* the write op is key */
25− wmb();
26−}
27−
28−
29−/* Linux gpio framework integration.
30−*
31−* 4 use cases of Alchemy GPIOS:
32−*(1) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=y:
33−* Board must register gpiochips.
34−*(2) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=n:
35−* A gpiochip for the 75 GPIOs is registered.
36−*
37−*(3) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=y:
38−* the boards' gpio.h must provide the linux gpio wrapper functions,
39−*
40−*(4) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=n:
41−* inlinable gpio functions are provided which enable access to the
42−* Au1300 gpios only by using the numbers straight out of the data-
43−* sheets.
44−
45−* Cases 1 and 3 are intended for boards which want to provide their own
46−* GPIO namespace and -operations (i.e. for example you have 8 GPIOs
47−* which are in part provided by spare Au1300 GPIO pins and in part by
48−* an external FPGA but you still want them to be accssible in linux
49−* as gpio0-7. The board can of course use the alchemy_gpioX_* functions
50−* as required).
51−*/
52−
53−#ifdef CONFIG_GPIOLIB
54−
55−/* wraps the cpu-dependent irq_to_gpio functions */
56−/* FIXME: gpiolib needs an irq_to_gpio hook */
57−static inline int __au_irq_to_gpio(unsigned int irq)
58−{
59− switch (alchemy_get_cputype()) {
60− case ALCHEMY_CPU_AU1000...ALCHEMY_CPU_AU1200:
61− return alchemy_irq_to_gpio(irq);
62− case ALCHEMY_CPU_AU1300:
63− return au1300_irq_to_gpio(irq);
64− }
65− return -EINVAL;
66−}
67−
68−
69−/* using gpiolib to provide up to 2 gpio_chips for on-chip gpios */
70−#ifndef CONFIG_ALCHEMY_GPIO_INDIRECT /* case (2) */
71−
72−/* get everything through gpiolib */
73−#define gpio_to_irq __gpio_to_irq
74−#define gpio_get_value __gpio_get_value
75−#define gpio_set_value __gpio_set_value
76−#define gpio_cansleep __gpio_cansleep
77−#define irq_to_gpio __au_irq_to_gpio
78−
79−#include <asm-generic/gpio.h>
80−
81−#endif /* !CONFIG_ALCHEMY_GPIO_INDIRECT */
82−
83−
84−#endif /* CONFIG_GPIOLIB */
85−
86−#endif /* _ALCHEMY_GPIO_H_ */
arch/mips/include/asm/mach-bcm47xx/gpio.h+0−17
@@ -1,17 +0,0 @@
1−#ifndef __ASM_MIPS_MACH_BCM47XX_GPIO_H
2−#define __ASM_MIPS_MACH_BCM47XX_GPIO_H
3−
4−#include <asm-generic/gpio.h>
5−
6−#define gpio_get_value __gpio_get_value
7−#define gpio_set_value __gpio_set_value
8−
9−#define gpio_cansleep __gpio_cansleep
10−#define gpio_to_irq __gpio_to_irq
11−
12−static inline int irq_to_gpio(unsigned int irq)
13−{
14− return -EINVAL;
15−}
16−
17−#endif
arch/mips/include/asm/mach-bcm63xx/gpio.h+0−15
@@ -1,15 +0,0 @@
1−#ifndef __ASM_MIPS_MACH_BCM63XX_GPIO_H
2−#define __ASM_MIPS_MACH_BCM63XX_GPIO_H
3−
4−#include <bcm63xx_gpio.h>
5−
6−#define gpio_to_irq(gpio) -1
7−
8−#define gpio_get_value __gpio_get_value
9−#define gpio_set_value __gpio_set_value
10−
11−#define gpio_cansleep __gpio_cansleep
12−
13−#include <asm-generic/gpio.h>
14−
15−#endif /* __ASM_MIPS_MACH_BCM63XX_GPIO_H */
arch/mips/include/asm/mach-cavium-octeon/gpio.h+0−21
@@ -1,21 +0,0 @@
1−#ifndef __ASM_MACH_CAVIUM_OCTEON_GPIO_H
2−#define __ASM_MACH_CAVIUM_OCTEON_GPIO_H
3−
4−#ifdef CONFIG_GPIOLIB
5−#define gpio_get_value __gpio_get_value
6−#define gpio_set_value __gpio_set_value
7−#define gpio_cansleep __gpio_cansleep
8−#else
9−int gpio_request(unsigned gpio, const char *label);
10−void gpio_free(unsigned gpio);
11−int gpio_direction_input(unsigned gpio);
12−int gpio_direction_output(unsigned gpio, int value);
13−int gpio_get_value(unsigned gpio);
14−void gpio_set_value(unsigned gpio, int value);
15−#endif
16−
17−#include <asm-generic/gpio.h>
18−
19−#define gpio_to_irq __gpio_to_irq
20−
21−#endif /* __ASM_MACH_GENERIC_GPIO_H */
arch/mips/include/asm/mach-generic/gpio.h+0−21
@@ -1,21 +0,0 @@
1−#ifndef __ASM_MACH_GENERIC_GPIO_H
2−#define __ASM_MACH_GENERIC_GPIO_H
3−
4−#ifdef CONFIG_GPIOLIB
5−#define gpio_get_value __gpio_get_value
6−#define gpio_set_value __gpio_set_value
7−#define gpio_cansleep __gpio_cansleep
8−#else
9−int gpio_request(unsigned gpio, const char *label);
10−void gpio_free(unsigned gpio);
11−int gpio_direction_input(unsigned gpio);
12−int gpio_direction_output(unsigned gpio, int value);
13−int gpio_get_value(unsigned gpio);
14−void gpio_set_value(unsigned gpio, int value);
15−#endif
16−int gpio_to_irq(unsigned gpio);
17−int irq_to_gpio(unsigned irq);
18−
19−#include <asm-generic/gpio.h> /* cansleep wrappers */
20−
21−#endif /* __ASM_MACH_GENERIC_GPIO_H */
arch/mips/include/asm/mach-jz4740/gpio.h+0−2
@@ -73,8 +73,6 @@ int jz_gpio_port_direction_output(int port, uint32_t mask); · 72 unmodified lines
7373 void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask);
7474 uint32_t jz_gpio_port_get_value(int port, uint32_t mask);
7575
76−#include <asm/mach-generic/gpio.h>
77−
7876 #define JZ_GPIO_PORTA(x) ((x) + 32 * 0)
7977 #define JZ_GPIO_PORTB(x) ((x) + 32 * 1)
8078 #define JZ_GPIO_PORTC(x) ((x) + 32 * 2)
arch/mips/include/asm/mach-lantiq/gpio.h+0−13
@@ -1,13 +0,0 @@
1−#ifndef __ASM_MIPS_MACH_LANTIQ_GPIO_H
2−#define __ASM_MIPS_MACH_LANTIQ_GPIO_H
3−
4−#define gpio_to_irq __gpio_to_irq
5−
6−#define gpio_get_value __gpio_get_value
7−#define gpio_set_value __gpio_set_value
8−
9−#define gpio_cansleep __gpio_cansleep
10−
11−#include <asm-generic/gpio.h>
12−
13−#endif
arch/mips/include/asm/mach-loongson64/gpio.h+0−36
@@ -1,36 +0,0 @@
1−/*
2− * Loongson GPIO Support
3− *
4− * Copyright (c) 2008 Richard Liu, STMicroelectronics <richard.liu@st.com>
5− * Copyright (c) 2008-2010 Arnaud Patard <apatard@mandriva.com>
6− * Copyright (c) 2014 Huacai Chen <chenhc@lemote.com>
7− *
8− * This program is free software; you can redistribute it and/or modify
9− * it under the terms of the GNU General Public License as published by
10− * the Free Software Foundation; either version 2 of the License, or
11− * (at your option) any later version.
12− */
13−
14−#ifndef __LOONGSON_GPIO_H
15−#define __LOONGSON_GPIO_H
16−
17−#include <asm-generic/gpio.h>
18−
19−#define gpio_get_value __gpio_get_value
20−#define gpio_set_value __gpio_set_value
21−#define gpio_cansleep __gpio_cansleep
22−
23−/* The chip can do interrupt
24− * but it has not been tested and doc not clear
25− */
26−static inline int gpio_to_irq(int gpio)
27−{
28− return -EINVAL;
29−}
30−
31−static inline int irq_to_gpio(int gpio)
32−{
33− return -EINVAL;
34−}
35−
36−#endif /* __LOONGSON_GPIO_H */
arch/mips/include/asm/mach-pistachio/gpio.h+0−21
@@ -1,21 +0,0 @@
1−/*
2− * Pistachio IRQ setup
3− *
4− * Copyright (C) 2014 Google, Inc.
5− *
6− * This program is free software; you can redistribute it and/or modify it
7− * under the terms and conditions of the GNU General Public License,
8− * version 2, as published by the Free Software Foundation.
9− */
10−
11−#ifndef __ASM_MACH_PISTACHIO_GPIO_H
12−#define __ASM_MACH_PISTACHIO_GPIO_H
13−
14−#include <asm-generic/gpio.h>
15−
16−#define gpio_get_value __gpio_get_value
17−#define gpio_set_value __gpio_set_value
18−#define gpio_cansleep __gpio_cansleep
19−#define gpio_to_irq __gpio_to_irq
20−
21−#endif /* __ASM_MACH_PISTACHIO_GPIO_H */
arch/mips/include/asm/mach-rc32434/gpio.h+0−12
@@ -13,18 +13,6 @@ · 12 unmodified lines
1313 #ifndef _RC32434_GPIO_H_
1414 #define _RC32434_GPIO_H_
1515
16−#include <linux/types.h>
17−#include <asm-generic/gpio.h>
18−
19−#define NR_BUILTIN_GPIO 32
20−
21−#define gpio_get_value __gpio_get_value
22−#define gpio_set_value __gpio_set_value
23−#define gpio_cansleep __gpio_cansleep
24−
25−#define gpio_to_irq(gpio) (8 + 4 * 32 + gpio)
26−#define irq_to_gpio(irq) (irq - (8 + 4 * 32))
27−
2816 struct rb532_gpio_reg {
2917 u32 gpiofunc; /* GPIO Function Register
3018 * gpiofunc[x]==0 bit = gpio
arch/mips/include/asm/mips-cm.h+85−4
@@ -33,6 +33,29 @@ extern void __iomem *mips_cm_l2sync_base; · 32 unmodified lines
3333 */
3434 extern phys_addr_t __mips_cm_phys_base(void);
3535
36+/*
37+ * mips_cm_is64 - determine CM register width
38+ *
39+ * The CM register width is processor and CM specific. A 64-bit processor
40+ * usually has a 64-bit CM and a 32-bit one has a 32-bit CM but a 64-bit
41+ * processor could come with a 32-bit CM. Moreover, accesses on 64-bit CMs
42+ * can be done either using regular 64-bit load/store instructions, or 32-bit
43+ * load/store instruction on 32-bit register pairs. We opt for using 64-bit
44+ * accesses on 64-bit CMs and kernels and 32-bit in any other case.
45+ *
46+ * It's set to 0 for 32-bit accesses and 1 for 64-bit accesses.
47+ */
48+extern int mips_cm_is64;
49+
50+/**
51+ * mips_cm_error_report - Report CM cache errors
52+ */
53+#ifdef CONFIG_MIPS_CM
54+extern void mips_cm_error_report(void);
55+#else
56+static inline void mips_cm_error_report(void) {}
57+#endif
58+
3659 /**
3760 * mips_cm_probe - probe for a Coherence Manager
3861 *
@@ -90,20 +113,46 @@ static inline bool mips_cm_has_l2sync(void) · 51 unmodified lines
90113
91114 /* Macros to ease the creation of register access functions */
92115 #define BUILD_CM_R_(name, off) \
93−static inline u32 __iomem *addr_gcr_##name(void) \
116+static inline unsigned long __iomem *addr_gcr_##name(void) \
94117 { \
95− return (u32 __iomem *)(mips_cm_base + (off)); \
118+ return (unsigned long __iomem *)(mips_cm_base + (off)); \
96119 } \
97120 \
98−static inline u32 read_gcr_##name(void) \
121+static inline u32 read32_gcr_##name(void) \
99122 { \
100123 return __raw_readl(addr_gcr_##name()); \
124+} \
125+ \
126+static inline u64 read64_gcr_##name(void) \
127+{ \
128+ return __raw_readq(addr_gcr_##name()); \
129+} \
130+ \
131+static inline unsigned long read_gcr_##name(void) \
132+{ \
133+ if (mips_cm_is64) \
134+ return read64_gcr_##name(); \
135+ else \
136+ return read32_gcr_##name(); \
101137 }
102138
103139 #define BUILD_CM__W(name, off) \
104−static inline void write_gcr_##name(u32 value) \
140+static inline void write32_gcr_##name(u32 value) \
105141 { \
106142 __raw_writel(value, addr_gcr_##name()); \
143+} \
144+ \
145+static inline void write64_gcr_##name(u64 value) \
146+{ \
147+ __raw_writeq(value, addr_gcr_##name()); \
148+} \
149+ \
150+static inline void write_gcr_##name(unsigned long value) \
151+{ \
152+ if (mips_cm_is64) \
153+ write64_gcr_##name(value); \
154+ else \
155+ write32_gcr_##name(value); \
107156 }
108157
109158 #define BUILD_CM_RW(name, off) \
@@ -144,6 +193,7 @@ BUILD_CM_RW(reg3_base, MIPS_CM_GCB_OFS + 0xc0) · 34 unmodified lines
144193 BUILD_CM_RW(reg3_mask, MIPS_CM_GCB_OFS + 0xc8)
145194 BUILD_CM_R_(gic_status, MIPS_CM_GCB_OFS + 0xd0)
146195 BUILD_CM_R_(cpc_status, MIPS_CM_GCB_OFS + 0xf0)
196+BUILD_CM_RW(l2_config, MIPS_CM_GCB_OFS + 0x130)
147197
148198 /* Core Local & Core Other register accessor functions */
149199 BUILD_CM_Cx_RW(reset_release, 0x00)
@@ -189,6 +239,13 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80) · 39 unmodified lines
189239 #define CM_GCR_REV_MINOR_SHF 0
190240 #define CM_GCR_REV_MINOR_MSK (_ULCAST_(0xff) << 0)
191241
242+#define CM_ENCODE_REV(major, minor) \
243+ (((major) << CM_GCR_REV_MAJOR_SHF) | \
244+ ((minor) << CM_GCR_REV_MINOR_SHF))
245+
246+#define CM_REV_CM2 CM_ENCODE_REV(6, 0)
247+#define CM_REV_CM3 CM_ENCODE_REV(8, 0)
248+
192249 /* GCR_ERROR_CAUSE register fields */
193250 #define CM_GCR_ERROR_CAUSE_ERRTYPE_SHF 27
194251 #define CM_GCR_ERROR_CAUSE_ERRTYPE_MSK (_ULCAST_(0x1f) << 27)
@@ -249,6 +306,16 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80) · 54 unmodified lines
249306 #define CM_GCR_CPC_STATUS_EX_SHF 0
250307 #define CM_GCR_CPC_STATUS_EX_MSK (_ULCAST_(0x1) << 0)
251308
309+/* GCR_L2_CONFIG register fields */
310+#define CM_GCR_L2_CONFIG_BYPASS_SHF 20
311+#define CM_GCR_L2_CONFIG_BYPASS_MSK (_ULCAST_(0x1) << 20)
312+#define CM_GCR_L2_CONFIG_SET_SIZE_SHF 12
313+#define CM_GCR_L2_CONFIG_SET_SIZE_MSK (_ULCAST_(0xf) << 12)
314+#define CM_GCR_L2_CONFIG_LINE_SIZE_SHF 8
315+#define CM_GCR_L2_CONFIG_LINE_SIZE_MSK (_ULCAST_(0xf) << 8)
316+#define CM_GCR_L2_CONFIG_ASSOC_SHF 0
317+#define CM_GCR_L2_CONFIG_ASSOC_MSK (_ULCAST_(0xff) << 0)
318+
252319 /* GCR_Cx_COHERENCE register fields */
253320 #define CM_GCR_Cx_COHERENCE_COHDOMAINEN_SHF 0
254321 #define CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK (_ULCAST_(0xff) << 0)
@@ -324,4 +391,18 @@ static inline int mips_cm_l2sync(void) · 69 unmodified lines
324391 return 0;
325392 }
326393
394+/**
395+ * mips_cm_revision() - return CM revision
396+ *
397+ * Return: The revision of the CM, from GCR_REV, or 0 if no CM is present. The
398+ * return value should be checked against the CM_REV_* macros.
399+ */
400+static inline int mips_cm_revision(void)
401+{
402+ if (!mips_cm_present())
403+ return 0;
404+
405+ return read_gcr_rev();
406+}
407+
327408 #endif /* __MIPS_ASM_MIPS_CM_H__ */
arch/mips/include/asm/mips-cpc.h+0−10
@@ -27,16 +27,6 @@ extern void __iomem *mips_cpc_base; · 26 unmodified lines
2727 */
2828 extern phys_addr_t mips_cpc_default_phys_base(void);
2929
30−/**
31− * mips_cpc_phys_base - retrieve the physical base address of the CPC
32− *
33− * This function returns the physical base address of the Cluster Power
34− * Controller memory mapped registers, or 0 if no Cluster Power Controller
35− * is present. It may be overriden by individual platforms which determine
36− * this address in a different way.
37− */
38−extern phys_addr_t __weak mips_cpc_phys_base(void);
39−
4030 /**
4131 * mips_cpc_probe - probe for a Cluster Power Controller
4232 *
arch/mips/include/asm/mipsregs.h+32−28
@@ -112,6 +112,30 @@ · 111 unmodified lines
112112 #define CP0_TX39_CACHE $7
113113
114114
115+/* Generic EntryLo bit definitions */
116+#define ENTRYLO_G (_ULCAST_(1) << 0)
117+#define ENTRYLO_V (_ULCAST_(1) << 1)
118+#define ENTRYLO_D (_ULCAST_(1) << 2)
119+#define ENTRYLO_C_SHIFT 3
120+#define ENTRYLO_C (_ULCAST_(7) << ENTRYLO_C_SHIFT)
121+
122+/* R3000 EntryLo bit definitions */
123+#define R3K_ENTRYLO_G (_ULCAST_(1) << 8)
124+#define R3K_ENTRYLO_V (_ULCAST_(1) << 9)
125+#define R3K_ENTRYLO_D (_ULCAST_(1) << 10)
126+#define R3K_ENTRYLO_N (_ULCAST_(1) << 11)
127+
128+/* MIPS32/64 EntryLo bit definitions */
129+#ifdef CONFIG_64BIT
130+/* as read by dmfc0 */
131+#define MIPS_ENTRYLO_XI (_ULCAST_(1) << 62)
132+#define MIPS_ENTRYLO_RI (_ULCAST_(1) << 63)
133+#else
134+/* as read by mfc0 */
135+#define MIPS_ENTRYLO_XI (_ULCAST_(1) << 30)
136+#define MIPS_ENTRYLO_RI (_ULCAST_(1) << 31)
137+#endif
138+
115139 /*
116140 * Values for PageMask register
117141 */
@@ -203,6 +227,9 @@ · 85 unmodified lines
203227 #define PG_ESP (_ULCAST_(1) << 28)
204228 #define PG_IEC (_ULCAST_(1) << 27)
205229
230+/* MIPS32/64 EntryHI bit definitions */
231+#define MIPS_ENTRYHI_EHINV (_ULCAST_(1) << 10)
232+
206233 /*
207234 * R4x00 interrupt enable / cause bits
208235 */
@@ -579,6 +606,8 @@ · 370 unmodified lines
579606
580607 #define MIPS_CONF7_IAR (_ULCAST_(1) << 10)
581608 #define MIPS_CONF7_AR (_ULCAST_(1) << 16)
609+/* FTLB probability bits for R6 */
610+#define MIPS_CONF7_FTLBP_SHIFT (18)
582611
583612 /* MAAR bit definitions */
584613 #define MIPS_MAAR_ADDR ((BIT_ULL(BITS_PER_LONG - 12) - 1) << 12)
@@ -586,31 +615,6 @@ · 1 unmodified line
586615 #define MIPS_MAAR_S (_ULCAST_(1) << 1)
587616 #define MIPS_MAAR_V (_ULCAST_(1) << 0)
588617
589−/* EntryHI bit definition */
590−#define MIPS_ENTRYHI_EHINV (_ULCAST_(1) << 10)
591−
592−/* R3000 EntryLo bit definitions */
593−#define R3K_ENTRYLO_G (_ULCAST_(1) << 8)
594−#define R3K_ENTRYLO_V (_ULCAST_(1) << 9)
595−#define R3K_ENTRYLO_D (_ULCAST_(1) << 10)
596−#define R3K_ENTRYLO_N (_ULCAST_(1) << 11)
597−
598−/* R4000 compatible EntryLo bit definitions */
599−#define MIPS_ENTRYLO_G (_ULCAST_(1) << 0)
600−#define MIPS_ENTRYLO_V (_ULCAST_(1) << 1)
601−#define MIPS_ENTRYLO_D (_ULCAST_(1) << 2)
602−#define MIPS_ENTRYLO_C_SHIFT 3
603−#define MIPS_ENTRYLO_C (_ULCAST_(7) << MIPS_ENTRYLO_C_SHIFT)
604−#ifdef CONFIG_64BIT
605−/* as read by dmfc0 */
606−#define MIPS_ENTRYLO_XI (_ULCAST_(1) << 62)
607−#define MIPS_ENTRYLO_RI (_ULCAST_(1) << 63)
608−#else
609−/* as read by mfc0 */
610−#define MIPS_ENTRYLO_XI (_ULCAST_(1) << 30)
611−#define MIPS_ENTRYLO_RI (_ULCAST_(1) << 31)
612−#endif
613−
614618 /* CMGCRBase bit definitions */
615619 #define MIPS_CMGCRB_BASE 11
616620 #define MIPS_CMGCRF_BASE (~_ULCAST_((1 << MIPS_CMGCRB_BASE) - 1))
@@ -932,7 +936,7 @@ do { \ · 315 unmodified lines
932936 */
933937
934938 #define __read_32bit_c0_register(source, sel) \
935−({ int __res; \
939+({ unsigned int __res; \
936940 if (sel == 0) \
937941 __asm__ __volatile__( \
938942 "mfc0\t%0, " #source "\n\t" \
@@ -1014,7 +1018,7 @@ do { \ · 75 unmodified lines
10141018 * On RM7000/RM9000 these are uses to access cop0 set 1 registers
10151019 */
10161020 #define __read_32bit_c0_ctrl_register(source) \
1017−({ int __res; \
1021+({ unsigned int __res; \
10181022 __asm__ __volatile__( \
10191023 "cfc0\t%0, " #source "\n\t" \
10201024 : "=r" (__res)); \
@@ -1471,7 +1475,7 @@ do { \ · 450 unmodified lines
14711475 */
14721476 #define _read_32bit_cp1_register(source, gas_hardfloat) \
14731477 ({ \
1474− int __res; \
1478+ unsigned int __res; \
14751479 \
14761480 __asm__ __volatile__( \
14771481 " .set push \n" \
arch/mips/include/asm/msa.h+80−0
@@ -14,10 +14,90 @@ · 13 unmodified lines
1414
1515 #ifndef __ASSEMBLY__
1616
17+#include <asm/inst.h>
18+
1719 extern void _save_msa(struct task_struct *);
1820 extern void _restore_msa(struct task_struct *);
1921 extern void _init_msa_upper(void);
2022
23+extern void read_msa_wr_b(unsigned idx, union fpureg *to);
24+extern void read_msa_wr_h(unsigned idx, union fpureg *to);
25+extern void read_msa_wr_w(unsigned idx, union fpureg *to);
26+extern void read_msa_wr_d(unsigned idx, union fpureg *to);
27+
28+/**
29+ * read_msa_wr() - Read a single MSA vector register
30+ * @idx: The index of the vector register to read
31+ * @to: The FPU register union to store the registers value in
32+ * @fmt: The format of the data in the vector register
33+ *
34+ * Read the value of MSA vector register idx into the FPU register
35+ * union to, using the format fmt.
36+ */
37+static inline void read_msa_wr(unsigned idx, union fpureg *to,
38+ enum msa_2b_fmt fmt)
39+{
40+ switch (fmt) {
41+ case msa_fmt_b:
42+ read_msa_wr_b(idx, to);
43+ break;
44+
45+ case msa_fmt_h:
46+ read_msa_wr_h(idx, to);
47+ break;
48+
49+ case msa_fmt_w:
50+ read_msa_wr_w(idx, to);
51+ break;
52+
53+ case msa_fmt_d:
54+ read_msa_wr_d(idx, to);
55+ break;
56+
57+ default:
58+ BUG();
59+ }
60+}
61+
62+extern void write_msa_wr_b(unsigned idx, union fpureg *from);
63+extern void write_msa_wr_h(unsigned idx, union fpureg *from);
64+extern void write_msa_wr_w(unsigned idx, union fpureg *from);
65+extern void write_msa_wr_d(unsigned idx, union fpureg *from);
66+
67+/**
68+ * write_msa_wr() - Write a single MSA vector register
69+ * @idx: The index of the vector register to write
70+ * @from: The FPU register union to take the registers value from
71+ * @fmt: The format of the data in the vector register
72+ *
73+ * Write the value from the FPU register union from into MSA vector
74+ * register idx, using the format fmt.
75+ */
76+static inline void write_msa_wr(unsigned idx, union fpureg *from,
77+ enum msa_2b_fmt fmt)
78+{
79+ switch (fmt) {
80+ case msa_fmt_b:
81+ write_msa_wr_b(idx, from);
82+ break;
83+
84+ case msa_fmt_h:
85+ write_msa_wr_h(idx, from);
86+ break;
87+
88+ case msa_fmt_w:
89+ write_msa_wr_w(idx, from);
90+ break;
91+
92+ case msa_fmt_d:
93+ write_msa_wr_d(idx, from);
94+ break;
95+
96+ default:
97+ BUG();
98+ }
99+}
100+
21101 static inline void enable_msa(void)
22102 {
23103 if (cpu_has_msa) {
arch/mips/include/asm/octeon/cvmx-bootinfo.h+2−0
@@ -284,6 +284,7 @@ enum cvmx_board_types_enum { · 283 unmodified lines
284284 CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001,
285285 CVMX_BOARD_TYPE_UBNT_E100 = 20002,
286286 CVMX_BOARD_TYPE_CUST_DSR1000N = 20006,
287+ CVMX_BOARD_TYPE_KONTRON_S1901 = 21901,
287288 CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000,
288289
289290 /* The remaining range is reserved for future use. */
@@ -384,6 +385,7 @@ static inline const char *cvmx_board_type_to_string(enum · 94 unmodified lines
384385 ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MIN)
385386 ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E100)
386387 ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DSR1000N)
388+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_KONTRON_S1901)
387389 ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX)
388390 }
389391 return "Unsupported Board";
arch/mips/include/asm/octeon/cvmx-pip.h+1−1
@@ -37,7 +37,7 @@ · 36 unmodified lines
3737 #include <asm/octeon/cvmx-fpa.h>
3838 #include <asm/octeon/cvmx-pip-defs.h>
3939
40−#define CVMX_PIP_NUM_INPUT_PORTS 40
40+#define CVMX_PIP_NUM_INPUT_PORTS 48
4141 #define CVMX_PIP_NUM_WATCHERS 4
4242
4343 /*
arch/mips/include/asm/octeon/cvmx-pko.h+3−0
@@ -542,6 +542,9 @@ static inline int cvmx_pko_get_base_queue_per_core(int port, int core) · 541 unmodified lines
542542 */
543543 static inline int cvmx_pko_get_base_queue(int port)
544544 {
545+ if (OCTEON_IS_MODEL(OCTEON_CN68XX))
546+ return port;
547+
545548 return cvmx_pko_get_base_queue_per_core(port, 0);
546549 }
547550
arch/mips/include/asm/octeon/cvmx-pow-defs.h+29−0
@@ -52,6 +52,12 @@ · 51 unmodified lines
5252 #define CVMX_POW_WQ_INT_THRX(offset) (CVMX_ADD_IO_SEG(0x0001670000000080ull) + ((offset) & 15) * 8)
5353 #define CVMX_POW_WS_PCX(offset) (CVMX_ADD_IO_SEG(0x0001670000000280ull) + ((offset) & 15) * 8)
5454
55+#define CVMX_SSO_WQ_INT (CVMX_ADD_IO_SEG(0x0001670000001000ull))
56+#define CVMX_SSO_WQ_IQ_DIS (CVMX_ADD_IO_SEG(0x0001670000001010ull))
57+#define CVMX_SSO_WQ_INT_PC (CVMX_ADD_IO_SEG(0x0001670000001020ull))
58+#define CVMX_SSO_PPX_GRP_MSK(offset) (CVMX_ADD_IO_SEG(0x0001670000006000ull) + ((offset) & 31) * 8)
59+#define CVMX_SSO_WQ_INT_THRX(offset) (CVMX_ADD_IO_SEG(0x0001670000007000ull) + ((offset) & 63) * 8)
60+
5561 union cvmx_pow_bist_stat {
5662 uint64_t u64;
5763 struct cvmx_pow_bist_stat_s {
@@ -1286,4 +1292,27 @@ union cvmx_pow_ws_pcx { · 1228 unmodified lines
12861292 struct cvmx_pow_ws_pcx_s cnf71xx;
12871293 };
12881294
1295+union cvmx_sso_wq_int_thrx {
1296+ uint64_t u64;
1297+ struct {
1298+#ifdef __BIG_ENDIAN_BITFIELD
1299+ uint64_t reserved_33_63:31;
1300+ uint64_t tc_en:1;
1301+ uint64_t tc_thr:4;
1302+ uint64_t reserved_26_27:2;
1303+ uint64_t ds_thr:12;
1304+ uint64_t reserved_12_13:2;
1305+ uint64_t iq_thr:12;
1306+#else
1307+ uint64_t iq_thr:12;
1308+ uint64_t reserved_12_13:2;
1309+ uint64_t ds_thr:12;
1310+ uint64_t reserved_26_27:2;
1311+ uint64_t tc_thr:4;
1312+ uint64_t tc_en:1;
1313+ uint64_t reserved_33_63:31;
1314+#endif
1315+ } s;
1316+};
1317+
12891318 #endif
arch/mips/include/asm/octeon/cvmx-pow.h+5−4
@@ -1810,10 +1810,11 @@ static inline void cvmx_pow_work_submit(cvmx_wqe_t *wqp, uint32_t tag, · 1809 unmodified lines
18101810 cvmx_addr_t ptr;
18111811 cvmx_pow_tag_req_t tag_req;
18121812
1813− wqp->qos = qos;
1814− wqp->tag = tag;
1815− wqp->tag_type = tag_type;
1816− wqp->grp = grp;
1813+ wqp->word1.tag = tag;
1814+ wqp->word1.tag_type = tag_type;
1815+
1816+ cvmx_wqe_set_qos(wqp, qos);
1817+ cvmx_wqe_set_grp(wqp, grp);
18171818
18181819 tag_req.u64 = 0;
18191820 tag_req.s.op = CVMX_POW_TAG_OP_ADDWQ;
arch/mips/include/asm/octeon/cvmx-wqe.h+249−59
@@ -193,6 +193,53 @@ typedef union { · 192 unmodified lines
193193 uint64_t bufs:8;
194194 #endif
195195 } s;
196+ struct {
197+#ifdef __BIG_ENDIAN_BITFIELD
198+ uint64_t bufs:8;
199+ uint64_t ip_offset:8;
200+ uint64_t vlan_valid:1;
201+ uint64_t vlan_stacked:1;
202+ uint64_t unassigned:1;
203+ uint64_t vlan_cfi:1;
204+ uint64_t vlan_id:12;
205+ uint64_t port:12; /* MAC/PIP port number. */
206+ uint64_t dec_ipcomp:1;
207+ uint64_t tcp_or_udp:1;
208+ uint64_t dec_ipsec:1;
209+ uint64_t is_v6:1;
210+ uint64_t software:1;
211+ uint64_t L4_error:1;
212+ uint64_t is_frag:1;
213+ uint64_t IP_exc:1;
214+ uint64_t is_bcast:1;
215+ uint64_t is_mcast:1;
216+ uint64_t not_IP:1;
217+ uint64_t rcv_error:1;
218+ uint64_t err_code:8;
219+#else
220+ uint64_t err_code:8;
221+ uint64_t rcv_error:1;
222+ uint64_t not_IP:1;
223+ uint64_t is_mcast:1;
224+ uint64_t is_bcast:1;
225+ uint64_t IP_exc:1;
226+ uint64_t is_frag:1;
227+ uint64_t L4_error:1;
228+ uint64_t software:1;
229+ uint64_t is_v6:1;
230+ uint64_t dec_ipsec:1;
231+ uint64_t tcp_or_udp:1;
232+ uint64_t dec_ipcomp:1;
233+ uint64_t port:12;
234+ uint64_t vlan_id:12;
235+ uint64_t vlan_cfi:1;
236+ uint64_t unassigned:1;
237+ uint64_t vlan_stacked:1;
238+ uint64_t vlan_valid:1;
239+ uint64_t ip_offset:8;
240+ uint64_t bufs:8;
241+#endif
242+ } s_cn68xx;
196243
197244 /* use this to get at the 16 vlan bits */
198245 struct {
@@ -355,6 +402,146 @@ typedef union { · 156 unmodified lines
355402
356403 } cvmx_pip_wqe_word2;
357404
405+union cvmx_pip_wqe_word0 {
406+ struct {
407+#ifdef __BIG_ENDIAN_BITFIELD
408+ /**
409+ * raw chksum result generated by the HW
410+ */
411+ uint16_t hw_chksum;
412+ /**
413+ * Field unused by hardware - available for software
414+ */
415+ uint8_t unused;
416+ /**
417+ * Next pointer used by hardware for list maintenance.
418+ * May be written/read by HW before the work queue
419+ * entry is scheduled to a PP (Only 36 bits used in
420+ * Octeon 1)
421+ */
422+ uint64_t next_ptr:40;
423+#else
424+ uint64_t next_ptr:40;
425+ uint8_t unused;
426+ uint16_t hw_chksum;
427+#endif
428+ } cn38xx;
429+ struct {
430+#ifdef __BIG_ENDIAN_BITFIELD
431+ uint64_t l4ptr:8; /* 56..63 */
432+ uint64_t unused0:8; /* 48..55 */
433+ uint64_t l3ptr:8; /* 40..47 */
434+ uint64_t l2ptr:8; /* 32..39 */
435+ uint64_t unused1:18; /* 14..31 */
436+ uint64_t bpid:6; /* 8..13 */
437+ uint64_t unused2:2; /* 6..7 */
438+ uint64_t pknd:6; /* 0..5 */
439+#else
440+ uint64_t pknd:6; /* 0..5 */
441+ uint64_t unused2:2; /* 6..7 */
442+ uint64_t bpid:6; /* 8..13 */
443+ uint64_t unused1:18; /* 14..31 */
444+ uint64_t l2ptr:8; /* 32..39 */
445+ uint64_t l3ptr:8; /* 40..47 */
446+ uint64_t unused0:8; /* 48..55 */
447+ uint64_t l4ptr:8; /* 56..63 */
448+#endif
449+ } cn68xx;
450+};
451+
452+union cvmx_wqe_word0 {
453+ uint64_t u64;
454+ union cvmx_pip_wqe_word0 pip;
455+};
456+
457+union cvmx_wqe_word1 {
458+ uint64_t u64;
459+ struct {
460+#ifdef __BIG_ENDIAN_BITFIELD
461+ uint64_t len:16;
462+ uint64_t varies:14;
463+ /**
464+ * the type of the tag (ORDERED, ATOMIC, NULL)
465+ */
466+ uint64_t tag_type:2;
467+ uint64_t tag:32;
468+#else
469+ uint64_t tag:32;
470+ uint64_t tag_type:2;
471+ uint64_t varies:14;
472+ uint64_t len:16;
473+#endif
474+ };
475+ struct {
476+#ifdef __BIG_ENDIAN_BITFIELD
477+ uint64_t len:16;
478+ uint64_t zero_0:1;
479+ /**
480+ * HW sets this to what it thought the priority of
481+ * the input packet was
482+ */
483+ uint64_t qos:3;
484+
485+ uint64_t zero_1:1;
486+ /**
487+ * the group that the work queue entry will be scheduled to
488+ */
489+ uint64_t grp:6;
490+ uint64_t zero_2:3;
491+ uint64_t tag_type:2;
492+ uint64_t tag:32;
493+#else
494+ uint64_t tag:32;
495+ uint64_t tag_type:2;
496+ uint64_t zero_2:3;
497+ uint64_t grp:6;
498+ uint64_t zero_1:1;
499+ uint64_t qos:3;
500+ uint64_t zero_0:1;
501+ uint64_t len:16;
502+#endif
503+ } cn68xx;
504+ struct {
505+#ifdef __BIG_ENDIAN_BITFIELD
506+ /**
507+ * HW sets to the total number of bytes in the packet
508+ */
509+ uint64_t len:16;
510+ /**
511+ * HW sets this to input physical port
512+ */
513+ uint64_t ipprt:6;
514+
515+ /**
516+ * HW sets this to what it thought the priority of
517+ * the input packet was
518+ */
519+ uint64_t qos:3;
520+
521+ /**
522+ * the group that the work queue entry will be scheduled to
523+ */
524+ uint64_t grp:4;
525+ /**
526+ * the type of the tag (ORDERED, ATOMIC, NULL)
527+ */
528+ uint64_t tag_type:3;
529+ /**
530+ * the synchronization/ordering tag
531+ */
532+ uint64_t tag:32;
533+#else
534+ uint64_t tag:32;
535+ uint64_t tag_type:2;
536+ uint64_t zero_2:1;
537+ uint64_t grp:4;
538+ uint64_t qos:3;
539+ uint64_t ipprt:6;
540+ uint64_t len:16;
541+#endif
542+ } cn38xx;
543+};
544+
358545 /**
359546 * Work queue entry format
360547 *
@@ -366,70 +553,13 @@ typedef struct { · 5 unmodified lines
366553 * WORD 0
367554 * HW WRITE: the following 64 bits are filled by HW when a packet arrives
368555 */
369−
370−#ifdef __BIG_ENDIAN_BITFIELD
371− /**
372− * raw chksum result generated by the HW
373− */
374− uint16_t hw_chksum;
375− /**
376− * Field unused by hardware - available for software
377− */
378− uint8_t unused;
379− /**
380− * Next pointer used by hardware for list maintenance.
381− * May be written/read by HW before the work queue
382− * entry is scheduled to a PP
383− * (Only 36 bits used in Octeon 1)
384− */
385− uint64_t next_ptr:40;
386−#else
387− uint64_t next_ptr:40;
388− uint8_t unused;
389− uint16_t hw_chksum;
390−#endif
556+ union cvmx_wqe_word0 word0;
391557
392558 /*****************************************************************
393559 * WORD 1
394560 * HW WRITE: the following 64 bits are filled by HW when a packet arrives
395561 */
396−
397−#ifdef __BIG_ENDIAN_BITFIELD
398− /**
399− * HW sets to the total number of bytes in the packet
400− */
401− uint64_t len:16;
402− /**
403− * HW sets this to input physical port
404− */
405− uint64_t ipprt:6;
406−
407− /**
408− * HW sets this to what it thought the priority of the input packet was
409− */
410− uint64_t qos:3;
411−
412− /**
413− * the group that the work queue entry will be scheduled to
414− */
415− uint64_t grp:4;
416− /**
417− * the type of the tag (ORDERED, ATOMIC, NULL)
418− */
419− uint64_t tag_type:3;
420− /**
421− * the synchronization/ordering tag
422− */
423− uint64_t tag:32;
424−#else
425− uint64_t tag:32;
426− uint64_t tag_type:2;
427− uint64_t zero_2:1;
428− uint64_t grp:4;
429− uint64_t qos:3;
430− uint64_t ipprt:6;
431− uint64_t len:16;
432−#endif
562+ union cvmx_wqe_word1 word1;
433563
434564 /**
435565 * WORD 2 HW WRITE: the following 64-bits are filled in by
@@ -465,4 +595,64 @@ typedef struct { · 29 unmodified lines
465595
466596 } CVMX_CACHE_LINE_ALIGNED cvmx_wqe_t;
467597
598+static inline int cvmx_wqe_get_port(cvmx_wqe_t *work)
599+{
600+ int port;
601+
602+ if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
603+ port = work->word2.s_cn68xx.port;
604+ else
605+ port = work->word1.cn38xx.ipprt;
606+
607+ return port;
608+}
609+
610+static inline void cvmx_wqe_set_port(cvmx_wqe_t *work, int port)
611+{
612+ if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
613+ work->word2.s_cn68xx.port = port;
614+ else
615+ work->word1.cn38xx.ipprt = port;
616+}
617+
618+static inline int cvmx_wqe_get_grp(cvmx_wqe_t *work)
619+{
620+ int grp;
621+
622+ if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
623+ grp = work->word1.cn68xx.grp;
624+ else
625+ grp = work->word1.cn38xx.grp;
626+
627+ return grp;
628+}
629+
630+static inline void cvmx_wqe_set_grp(cvmx_wqe_t *work, int grp)
631+{
632+ if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
633+ work->word1.cn68xx.grp = grp;
634+ else
635+ work->word1.cn38xx.grp = grp;
636+}
637+
638+static inline int cvmx_wqe_get_qos(cvmx_wqe_t *work)
639+{
640+ int qos;
641+
642+ if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
643+ qos = work->word1.cn68xx.qos;
644+ else
645+ qos = work->word1.cn38xx.qos;
646+
647+ return qos;
648+}
649+
650+static inline void cvmx_wqe_set_qos(cvmx_wqe_t *work, int qos)
651+{
652+ if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE))
653+ work->word1.cn68xx.qos = qos;
654+ else
655+ work->word1.cn38xx.qos = qos;
656+}
657+
468658 #endif /* __CVMX_WQE_H__ */
arch/mips/include/asm/pgtable-bits.h+10−15
@@ -133,20 +133,13 @@ · 132 unmodified lines
133133 #define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT)
134134 #define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT + 1)
135135 #define _PAGE_SPLITTING (1 << _PAGE_SPLITTING_SHIFT)
136−
137−/* Only R2 or newer cores have the XI bit */
138−#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
139−#define _PAGE_NO_EXEC_SHIFT (_PAGE_SPLITTING_SHIFT + 1)
140−#else
141−#define _PAGE_GLOBAL_SHIFT (_PAGE_SPLITTING_SHIFT + 1)
142−#define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT)
143−#endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
144−
145136 #endif /* CONFIG_64BIT && CONFIG_MIPS_HUGE_TLB_SUPPORT */
146137
147138 #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
148139 /* XI - page cannot be executed */
149−#ifndef _PAGE_NO_EXEC_SHIFT
140+#ifdef _PAGE_SPLITTING_SHIFT
141+#define _PAGE_NO_EXEC_SHIFT (_PAGE_SPLITTING_SHIFT + 1)
142+#else
150143 #define _PAGE_NO_EXEC_SHIFT (_PAGE_MODIFIED_SHIFT + 1)
151144 #endif
152145 #define _PAGE_NO_EXEC (cpu_has_rixi ? (1 << _PAGE_NO_EXEC_SHIFT) : 0)
@@ -156,14 +149,16 @@ · 3 unmodified lines
156149 #define _PAGE_READ (cpu_has_rixi ? 0 : (1 << _PAGE_READ_SHIFT))
157150 #define _PAGE_NO_READ_SHIFT _PAGE_READ_SHIFT
158151 #define _PAGE_NO_READ (cpu_has_rixi ? (1 << _PAGE_READ_SHIFT) : 0)
152+#endif /* defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) */
159153
154+#if defined(_PAGE_NO_READ_SHIFT)
160155 #define _PAGE_GLOBAL_SHIFT (_PAGE_NO_READ_SHIFT + 1)
161−#define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT)
162−
163−#else /* !CONFIG_CPU_MIPSR2 && !CONFIG_CPU_MIPSR6 */
156+#elif defined(_PAGE_SPLITTING_SHIFT)
157+#define _PAGE_GLOBAL_SHIFT (_PAGE_SPLITTING_SHIFT + 1)
158+#else
164159 #define _PAGE_GLOBAL_SHIFT (_PAGE_MODIFIED_SHIFT + 1)
160+#endif
165161 #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT)
166−#endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
167162
168163 #define _PAGE_VALID_SHIFT (_PAGE_GLOBAL_SHIFT + 1)
169164 #define _PAGE_VALID (1 << _PAGE_VALID_SHIFT)
@@ -249,7 +244,7 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val) · 79 unmodified lines
249244 #define _CACHE_CACHABLE_NONCOHERENT (3<<_CACHE_SHIFT) /* LOONGSON */
250245 #define _CACHE_CACHABLE_COHERENT (3<<_CACHE_SHIFT) /* LOONGSON-3 */
251246
252−#elif defined(CONFIG_MACH_JZ4740)
247+#elif defined(CONFIG_MACH_INGENIC)
253248
254249 /* Ingenic uses the WA bit to achieve write-combine memory writes */
255250 #define _CACHE_UNCACHED_ACCELERATED (1<<_CACHE_SHIFT)
arch/mips/include/asm/pgtable.h+2−0
@@ -393,6 +393,8 @@ static inline pgprot_t pgprot_noncached(pgprot_t _prot) · 392 unmodified lines
393393 return __pgprot(prot);
394394 }
395395
396+#define pgprot_writecombine pgprot_writecombine
397+
396398 static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
397399 {
398400 unsigned long prot = pgprot_val(_prot);
arch/mips/include/asm/processor.h+2−0
@@ -275,6 +275,7 @@ struct thread_struct { · 274 unmodified lines
275275 unsigned long cp0_badvaddr; /* Last user fault */
276276 unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */
277277 unsigned long error_code;
278+ unsigned long trap_nr;
278279 #ifdef CONFIG_CPU_CAVIUM_OCTEON
279280 struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128)));
280281 struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128)));
@@ -341,6 +342,7 @@ struct thread_struct { · 60 unmodified lines
341342 .cp0_badvaddr = 0, \
342343 .cp0_baduaddr = 0, \
343344 .error_code = 0, \
345+ .trap_nr = 0, \
344346 /* \
345347 * Platform specific cop2 registers(null if no COP2) \
346348 */ \
arch/mips/include/asm/ptrace.h+80−0
@@ -14,11 +14,16 @@ · 13 unmodified lines
1414 #include <linux/linkage.h>
1515 #include <linux/types.h>
1616 #include <asm/isadep.h>
17+#include <asm/page.h>
18+#include <asm/thread_info.h>
1719 #include <uapi/asm/ptrace.h>
1820
1921 /*
2022 * This struct defines the way the registers are stored on the stack during a
2123 * system call/exception. As usual the registers k0/k1 aren't being saved.
24+ *
25+ * If you add a register here, also add it to regoffset_table[] in
26+ * arch/mips/kernel/ptrace.c.
2227 */
2328 struct pt_regs {
2429 #ifdef CONFIG_32BIT
@@ -43,8 +48,83 @@ struct pt_regs { · 18 unmodified lines
4348 unsigned long long mpl[6]; /* MTM{0-5} */
4449 unsigned long long mtp[6]; /* MTP{0-5} */
4550 #endif
51+ unsigned long __last[0];
4652 } __aligned(8);
4753
54+static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
55+{
56+ return regs->regs[31];
57+}
58+
59+/*
60+ * Don't use asm-generic/ptrace.h it defines FP accessors that don't make
61+ * sense on MIPS. We rather want an error if they get invoked.
62+ */
63+
64+static inline void instruction_pointer_set(struct pt_regs *regs,
65+ unsigned long val)
66+{
67+ regs->cp0_epc = val;
68+}
69+
70+/* Query offset/name of register from its name/offset */
71+extern int regs_query_register_offset(const char *name);
72+#define MAX_REG_OFFSET (offsetof(struct pt_regs, __last))
73+
74+/**
75+ * regs_get_register() - get register value from its offset
76+ * @regs: pt_regs from which register value is gotten.
77+ * @offset: offset number of the register.
78+ *
79+ * regs_get_register returns the value of a register. The @offset is the
80+ * offset of the register in struct pt_regs address which specified by @regs.
81+ * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
82+ */
83+static inline unsigned long regs_get_register(struct pt_regs *regs,
84+ unsigned int offset)
85+{
86+ if (unlikely(offset > MAX_REG_OFFSET))
87+ return 0;
88+
89+ return *(unsigned long *)((unsigned long)regs + offset);
90+}
91+
92+/**
93+ * regs_within_kernel_stack() - check the address in the stack
94+ * @regs: pt_regs which contains kernel stack pointer.
95+ * @addr: address which is checked.
96+ *
97+ * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
98+ * If @addr is within the kernel stack, it returns true. If not, returns false.
99+ */
100+static inline int regs_within_kernel_stack(struct pt_regs *regs,
101+ unsigned long addr)
102+{
103+ return ((addr & ~(THREAD_SIZE - 1)) ==
104+ (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
105+}
106+
107+/**
108+ * regs_get_kernel_stack_nth() - get Nth entry of the stack
109+ * @regs: pt_regs which contains kernel stack pointer.
110+ * @n: stack entry number.
111+ *
112+ * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
113+ * is specified by @regs. If the @n th entry is NOT in the kernel stack,
114+ * this returns 0.
115+ */
116+static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
117+ unsigned int n)
118+{
119+ unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
120+
121+ addr += n;
122+ if (regs_within_kernel_stack(regs, (unsigned long)addr))
123+ return *addr;
124+ else
125+ return 0;
126+}
127+
48128 struct task_struct;
49129
50130 extern int ptrace_getregs(struct task_struct *child,
arch/mips/include/asm/signal.h+3−0
@@ -23,4 +23,7 @@ · 22 unmodified lines
2323
2424 #define __ARCH_HAS_IRIX_SIGACTION
2525
26+extern int protected_save_fp_context(void __user *sc);
27+extern int protected_restore_fp_context(void __user *sc);
28+
2629 #endif /* _ASM_SIGNAL_H */
arch/mips/include/asm/spinlock.h+5−0
@@ -42,6 +42,11 @@ static inline int arch_spin_is_locked(arch_spinlock_t *lock) · 41 unmodified lines
4242 return ((counters >> 16) ^ counters) & 0xffff;
4343 }
4444
45+static inline int arch_spin_value_unlocked(arch_spinlock_t lock)
46+{
47+ return lock.h.serving_now == lock.h.ticket;
48+}
49+
4550 #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
4651 #define arch_spin_unlock_wait(x) \
4752 while (arch_spin_is_locked(x)) { cpu_relax(); }
arch/mips/include/asm/switch_to.h+4−17
@@ -16,29 +16,21 @@ · 15 unmodified lines
1616 #include <asm/watch.h>
1717 #include <asm/dsp.h>
1818 #include <asm/cop2.h>
19−#include <asm/msa.h>
19+#include <asm/fpu.h>
2020
2121 struct task_struct;
2222
23−enum {
24− FP_SAVE_NONE = 0,
25− FP_SAVE_VECTOR = -1,
26− FP_SAVE_SCALAR = 1,
27−};
28−
2923 /**
3024 * resume - resume execution of a task
3125 * @prev: The task previously executed.
3226 * @next: The task to begin executing.
3327 * @next_ti: task_thread_info(next).
34− * @fp_save: Which, if any, FP context to save for prev.
3528 *
3629 * This function is used whilst scheduling to save the context of prev & load
3730 * the context of next. Returns prev.
3831 */
3932 extern asmlinkage struct task_struct *resume(struct task_struct *prev,
40− struct task_struct *next, struct thread_info *next_ti,
41− s32 fp_save);
33+ struct task_struct *next, struct thread_info *next_ti);
4234
4335 extern unsigned int ll_bit;
4436 extern struct task_struct *ll_task;
@@ -91,8 +83,8 @@ do { if (cpu_has_rw_llb) { \ · 46 unmodified lines
9183 */
9284 #define switch_to(prev, next, last) \
9385 do { \
94− s32 __fpsave = FP_SAVE_NONE; \
9586 __mips_mt_fpaff_switch_to(prev); \
87+ lose_fpu_inatomic(1, prev); \
9688 if (cpu_has_dsp) { \
9789 __save_dsp(prev); \
9890 __restore_dsp(next); \
@@ -111,15 +103,10 @@ do { \ · 12 unmodified lines
111103 clear_c0_status(ST0_CU2); \
112104 } \
113105 __clear_software_ll_bit(); \
114− if (test_and_clear_tsk_thread_flag(prev, TIF_USEDFPU)) \
115− __fpsave = FP_SAVE_SCALAR; \
116− if (test_and_clear_tsk_thread_flag(prev, TIF_USEDMSA)) \
117− __fpsave = FP_SAVE_VECTOR; \
118106 if (cpu_has_userlocal) \
119107 write_c0_userlocal(task_thread_info(next)->tp_value); \
120108 __restore_watch(); \
121− disable_msa(); \
122− (last) = resume(prev, next, task_thread_info(next), __fpsave); \
109+ (last) = resume(prev, next, task_thread_info(next)); \
123110 } while (0)
124111
125112 #endif /* _ASM_SWITCH_TO_H */
arch/mips/include/asm/thread_info.h+4−1
@@ -99,6 +99,7 @@ static inline struct thread_info *current_thread_info(void) · 98 unmodified lines
9999 #define TIF_SYSCALL_AUDIT 3 /* syscall auditing active */
100100 #define TIF_SECCOMP 4 /* secure computing */
101101 #define TIF_NOTIFY_RESUME 5 /* callback before returning to user */
102+#define TIF_UPROBE 6 /* breakpointed or singlestepping */
102103 #define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */
103104 #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
104105 #define TIF_MEMDIE 18 /* is terminating due to OOM killer */
@@ -122,6 +123,7 @@ static inline struct thread_info *current_thread_info(void) · 17 unmodified lines
122123 #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
123124 #define _TIF_SECCOMP (1<<TIF_SECCOMP)
124125 #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
126+#define _TIF_UPROBE (1<<TIF_UPROBE)
125127 #define _TIF_USEDFPU (1<<TIF_USEDFPU)
126128 #define _TIF_NOHZ (1<<TIF_NOHZ)
127129 #define _TIF_FIXADE (1<<TIF_FIXADE)
@@ -146,7 +148,8 @@ static inline struct thread_info *current_thread_info(void) · 18 unmodified lines
146148
147149 /* work to do on interrupt/exception return */
148150 #define _TIF_WORK_MASK \
149− (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME)
151+ (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME | \
152+ _TIF_UPROBE)
150153 /* work to do on any return to u-space */
151154 #define _TIF_ALLWORK_MASK (_TIF_NOHZ | _TIF_WORK_MASK | \
152155 _TIF_WORK_SYSCALL_EXIT | \
arch/mips/include/asm/time.h+1−1
@@ -51,7 +51,7 @@ extern int __weak get_c0_perfcount_int(void); · 50 unmodified lines
5151 /*
5252 * Initialize the calling CPU's compare interrupt as clockevent device
5353 */
54−extern unsigned int __weak get_c0_compare_int(void);
54+extern unsigned int get_c0_compare_int(void);
5555 extern int r4k_clockevent_init(void);
5656
5757 static inline int mips_clockevent_init(void)
arch/mips/include/asm/tlbdebug.h+1−0
@@ -11,6 +11,7 @@ · 10 unmodified lines
1111 /*
1212 * TLB debugging functions:
1313 */
14+extern void dump_tlb_regs(void);
1415 extern void dump_tlb_all(void);
1516
1617 #endif /* __ASM_TLBDEBUG_H */
arch/mips/include/asm/uprobes.h+58−0
@@ -0,0 +1,58 @@
1+/*
2+ * This file is subject to the terms and conditions of the GNU General Public
3+ * License. See the file "COPYING" in the main directory of this archive
4+ * for more details.
5+ */
6+#ifndef __ASM_UPROBES_H
7+#define __ASM_UPROBES_H
8+
9+#include <linux/notifier.h>
10+#include <linux/types.h>
11+
12+#include <asm/break.h>
13+#include <asm/inst.h>
14+
15+/*
16+ * We want this to be defined as union mips_instruction but that makes the
17+ * generic code blow up.
18+ */
19+typedef u32 uprobe_opcode_t;
20+
21+/*
22+ * Classic MIPS (note this implementation doesn't consider microMIPS yet)
23+ * instructions are always 4 bytes but in order to deal with branches and
24+ * their delay slots, we treat instructions as having 8 bytes maximum.
25+ */
26+#define MAX_UINSN_BYTES 8
27+#define UPROBE_XOL_SLOT_BYTES 128 /* Max. cache line size */
28+
29+#define UPROBE_BRK_UPROBE 0x000d000d /* break 13 */
30+#define UPROBE_BRK_UPROBE_XOL 0x000e000d /* break 14 */
31+
32+#define UPROBE_SWBP_INSN UPROBE_BRK_UPROBE
33+#define UPROBE_SWBP_INSN_SIZE 4
34+
35+struct arch_uprobe {
36+ unsigned long resume_epc;
37+ u32 insn[2];
38+ u32 ixol[2];
39+ union mips_instruction orig_inst[MAX_UINSN_BYTES / 4];
40+};
41+
42+struct arch_uprobe_task {
43+ unsigned long saved_trap_nr;
44+};
45+
46+extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup,
47+ struct mm_struct *mm, unsigned long addr);
48+extern int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs);
49+extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs);
50+extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk);
51+extern int arch_uprobe_exception_notify(struct notifier_block *self,
52+ unsigned long val, void *data);
53+extern void arch_uprobe_abort_xol(struct arch_uprobe *aup,
54+ struct pt_regs *regs);
55+extern unsigned long arch_uretprobe_hijack_return_addr(
56+ unsigned long trampoline_vaddr, struct pt_regs *regs);
57+
58+#endif /* __ASM_UPROBES_H */
arch/mips/include/asm/vpe.h+1−1
@@ -122,7 +122,7 @@ void release_vpe(struct vpe *v); · 121 unmodified lines
122122 void *alloc_progmem(unsigned long len);
123123 void release_progmem(void *ptr);
124124
125−int __weak vpe_run(struct vpe *v);
125+int vpe_run(struct vpe *v);
126126 void cleanup_tc(struct tc *tc);
127127
128128 int __init vpe_module_init(void);
arch/mips/include/uapi/asm/break.h+2−0
@@ -21,6 +21,8 @@ · 20 unmodified lines
2121 #define BRK_DIVZERO 7 /* Divide by zero check */
2222 #define BRK_RANGE 8 /* Range error check */
2323 #define BRK_BUG 12 /* Used by BUG() */
24+#define BRK_UPROBE 13 /* See <asm/uprobes.h> */
25+#define BRK_UPROBE_XOL 14 /* See <asm/uprobes.h> */
2426 #define BRK_MEMU 514 /* Used by FPU emulator */
2527 #define BRK_KPROBE_BP 515 /* Kprobe break */
2628 #define BRK_KPROBE_SSTEPBP 516 /* Kprobe single step software implementation */
arch/mips/include/uapi/asm/hwcap.h+8−0
@@ -0,0 +1,8 @@
1+#ifndef _UAPI_ASM_HWCAP_H
2+#define _UAPI_ASM_HWCAP_H
3+
4+/* HWCAP flags */
5+#define HWCAP_MIPS_R6 (1 << 0)
6+#define HWCAP_MIPS_MSA (1 << 1)
7+
8+#endif /* _UAPI_ASM_HWCAP_H */
arch/mips/include/uapi/asm/inst.h+37−3
@@ -26,7 +26,7 @@ enum major_op { · 25 unmodified lines
2626 cop0_op, cop1_op, cop2_op, cop1x_op,
2727 beql_op, bnel_op, blezl_op, bgtzl_op,
2828 daddi_op, cbcond1_op = daddi_op, daddiu_op, ldl_op, ldr_op,
29− spec2_op, jalx_op, mdmx_op, spec3_op,
29+ spec2_op, jalx_op, mdmx_op, msa_op = mdmx_op, spec3_op,
3030 lb_op, lh_op, lwl_op, lw_op,
3131 lbu_op, lhu_op, lwr_op, lwu_op,
3232 sb_op, sh_op, swl_op, sw_op,
@@ -167,8 +167,13 @@ enum cop1_sdw_func { · 134 unmodified lines
167167 fround_op = 0x0c, ftrunc_op = 0x0d,
168168 fceil_op = 0x0e, ffloor_op = 0x0f,
169169 fmovc_op = 0x11, fmovz_op = 0x12,
170− fmovn_op = 0x13, frecip_op = 0x15,
171− frsqrt_op = 0x16, fcvts_op = 0x20,
170+ fmovn_op = 0x13, fseleqz_op = 0x14,
171+ frecip_op = 0x15, frsqrt_op = 0x16,
172+ fselnez_op = 0x17, fmaddf_op = 0x18,
173+ fmsubf_op = 0x19, frint_op = 0x1a,
174+ fclass_op = 0x1b, fmin_op = 0x1c,
175+ fmina_op = 0x1d, fmax_op = 0x1e,
176+ fmaxa_op = 0x1f, fcvts_op = 0x20,
172177 fcvtd_op = 0x21, fcvte_op = 0x22,
173178 fcvtw_op = 0x24, fcvtl_op = 0x25,
174179 fcmp_op = 0x30
@@ -220,6 +225,24 @@ enum bshfl_func { · 45 unmodified lines
220225 seh_op = 0x18,
221226 };
222227
228+/*
229+ * func field for MSA MI10 format.
230+ */
231+enum msa_mi10_func {
232+ msa_ld_op = 8,
233+ msa_st_op = 9,
234+};
235+
236+/*
237+ * MSA 2 bit format fields.
238+ */
239+enum msa_2b_fmt {
240+ msa_fmt_b = 0,
241+ msa_fmt_h = 1,
242+ msa_fmt_w = 2,
243+ msa_fmt_d = 3,
244+};
245+
223246 /*
224247 * (microMIPS) Major opcodes.
225248 */
@@ -611,6 +634,16 @@ struct v_format { /* MDMX vector format */ · 385 unmodified lines
611634 ;)))))))
612635 };
613636
637+struct msa_mi10_format { /* MSA MI10 */
638+ __BITFIELD_FIELD(unsigned int opcode : 6,
639+ __BITFIELD_FIELD(signed int s10 : 10,
640+ __BITFIELD_FIELD(unsigned int rs : 5,
641+ __BITFIELD_FIELD(unsigned int wd : 5,
642+ __BITFIELD_FIELD(unsigned int func : 4,
643+ __BITFIELD_FIELD(unsigned int df : 2,
644+ ;))))))
645+};
646+
614647 struct spec3_format { /* SPEC3 */
615648 __BITFIELD_FIELD(unsigned int opcode:6,
616649 __BITFIELD_FIELD(unsigned int rs:5,
@@ -888,6 +921,7 @@ union mips_instruction { · 271 unmodified lines
888921 struct p_format p_format;
889922 struct f_format f_format;
890923 struct ma_format ma_format;
924+ struct msa_mi10_format msa_mi10_format;
891925 struct b_format b_format;
892926 struct ps_format ps_format;
893927 struct v_format v_format;
arch/mips/include/uapi/asm/sigcontext.h+12−0
@@ -12,6 +12,18 @@ · 11 unmodified lines
1212 #include <linux/types.h>
1313 #include <asm/sgidefs.h>
1414
15+/* scalar FP context was used */
16+#define USED_FP (1 << 0)
17+
18+/* the value of Status.FR when context was saved */
19+#define USED_FR1 (1 << 1)
20+
21+/* FR=1, but with odd singles in bits 63:32 of preceding even double */
22+#define USED_HYBRID_FPRS (1 << 2)
23+
24+/* extended context was used, see struct extcontext for details */
25+#define USED_EXTCONTEXT (1 << 3)
26+
1527 #if _MIPS_SIM == _MIPS_SIM_ABI32
1628
1729 /*
arch/mips/include/uapi/asm/swab.h+9−3
@@ -16,11 +16,13 @@ · 15 unmodified lines
1616 #if (defined(__mips_isa_rev) && (__mips_isa_rev >= 2)) || \
1717 defined(_MIPS_ARCH_LOONGSON3A)
1818
19−static inline __attribute_const__ __u16 __arch_swab16(__u16 x)
19+static inline __attribute__((nomips16)) __attribute_const__
20+ __u16 __arch_swab16(__u16 x)
2021 {
2122 __asm__(
2223 " .set push \n"
2324 " .set arch=mips32r2 \n"
25+ " .set nomips16 \n"
2426 " wsbh %0, %1 \n"
2527 " .set pop \n"
2628 : "=r" (x)
@@ -30,11 +32,13 @@ static inline __attribute_const__ __u16 __arch_swab16(__u16 x) · 3 unmodified lines
3032 }
3133 #define __arch_swab16 __arch_swab16
3234
33−static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
35+static inline __attribute__((nomips16)) __attribute_const__
36+ __u32 __arch_swab32(__u32 x)
3437 {
3538 __asm__(
3639 " .set push \n"
3740 " .set arch=mips32r2 \n"
41+ " .set nomips16 \n"
3842 " wsbh %0, %1 \n"
3943 " rotr %0, %0, 16 \n"
4044 " .set pop \n"
@@ -50,11 +54,13 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x) · 9 unmodified lines
5054 * 64-bit kernel on r2 CPUs.
5155 */
5256 #ifdef __mips64
53−static inline __attribute_const__ __u64 __arch_swab64(__u64 x)
57+static inline __attribute__((nomips16)) __attribute_const__
58+ __u64 __arch_swab64(__u64 x)
5459 {
5560 __asm__(
5661 " .set push \n"
5762 " .set arch=mips64r2 \n"
63+ " .set nomips16 \n"
5864 " dsbh %0, %1 \n"
5965 " dshd %0, %0 \n"
6066 " .set pop \n"
arch/mips/include/uapi/asm/ucontext.h+65−0
@@ -0,0 +1,65 @@
1+#ifndef __MIPS_UAPI_ASM_UCONTEXT_H
2+#define __MIPS_UAPI_ASM_UCONTEXT_H
3+
4+/**
5+ * struct extcontext - extended context header structure
6+ * @magic: magic value identifying the type of extended context
7+ * @size: the size in bytes of the enclosing structure
8+ *
9+ * Extended context structures provide context which does not fit within struct
10+ * sigcontext. They are placed sequentially in memory at the end of struct
11+ * ucontext and struct sigframe, with each extended context structure beginning
12+ * with a header defined by this struct. The type of context represented is
13+ * indicated by the magic field. Userland may check each extended context
14+ * structure against magic values that it recognises. The size field allows any
15+ * unrecognised context to be skipped, allowing for future expansion. The end
16+ * of the extended context data is indicated by the magic value
17+ * END_EXTCONTEXT_MAGIC.
18+ */
19+struct extcontext {
20+ unsigned int magic;
21+ unsigned int size;
22+};
23+
24+/**
25+ * struct msa_extcontext - MSA extended context structure
26+ * @ext: the extended context header, with magic == MSA_EXTCONTEXT_MAGIC
27+ * @wr: the most significant 64 bits of each MSA vector register
28+ * @csr: the value of the MSA control & status register
29+ *
30+ * If MSA context is live for a task at the time a signal is delivered to it,
31+ * this structure will hold the MSA context of the task as it was prior to the
32+ * signal delivery.
33+ */
34+struct msa_extcontext {
35+ struct extcontext ext;
36+#define MSA_EXTCONTEXT_MAGIC 0x784d5341 /* xMSA */
37+
38+ unsigned long long wr[32];
39+ unsigned int csr;
40+};
41+
42+#define END_EXTCONTEXT_MAGIC 0x78454e44 /* xEND */
43+
44+/**
45+ * struct ucontext - user context structure
46+ * @uc_flags:
47+ * @uc_link:
48+ * @uc_stack:
49+ * @uc_mcontext: holds basic processor state
50+ * @uc_sigmask:
51+ * @uc_extcontext: holds extended processor state
52+ */
53+struct ucontext {
54+ /* Historic fields matching asm-generic */
55+ unsigned long uc_flags;
56+ struct ucontext *uc_link;
57+ stack_t uc_stack;
58+ struct sigcontext uc_mcontext;
59+ sigset_t uc_sigmask;
60+
61+ /* Extended context structures may follow ucontext */
62+ unsigned long long uc_extcontext[0];
63+};
64+
65+#endif /* __MIPS_UAPI_ASM_UCONTEXT_H */
arch/mips/jazz/irq.c+0−7
@@ -110,18 +110,11 @@ asmlinkage void plat_irq_dispatch(void) · 109 unmodified lines
110110 }
111111 }
112112
113−static void r4030_set_mode(enum clock_event_mode mode,
114− struct clock_event_device *evt)
115−{
116− /* Nothing to do ... */
117−}
118−
119113 struct clock_event_device r4030_clockevent = {
120114 .name = "r4030",
121115 .features = CLOCK_EVT_FEAT_PERIODIC,
122116 .rating = 300,
123117 .irq = JAZZ_TIMER_IRQ,
124− .set_mode = r4030_set_mode,
125118 };
126119
127120 static irqreturn_t r4030_timer_interrupt(int irq, void *dev_id)
arch/mips/jz4740/gpio.c+10−14
@@ -231,6 +231,13 @@ static int jz_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) · 230 unmodified lines
231231 return 0;
232232 }
233233
234+static int jz_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
235+{
236+ struct jz_gpio_chip *jz_gpio = gpio_chip_to_jz_gpio_chip(chip);
237+
238+ return jz_gpio->irq_base + gpio;
239+}
240+
234241 int jz_gpio_port_direction_input(int port, uint32_t mask)
235242 {
236243 writel(mask, GPIO_TO_REG(port, JZ_REG_GPIO_DIRECTION_CLEAR));
@@ -262,18 +269,6 @@ uint32_t jz_gpio_port_get_value(int port, uint32_t mask) · 25 unmodified lines
262269 }
263270 EXPORT_SYMBOL(jz_gpio_port_get_value);
264271
265−int gpio_to_irq(unsigned gpio)
266−{
267− return JZ4740_IRQ_GPIO(0) + gpio;
268−}
269−EXPORT_SYMBOL_GPL(gpio_to_irq);
270−
271−int irq_to_gpio(unsigned irq)
272−{
273− return irq - JZ4740_IRQ_GPIO(0);
274−}
275−EXPORT_SYMBOL_GPL(irq_to_gpio);
276−
277272 #define IRQ_TO_BIT(irq) BIT(irq_to_gpio(irq) & 0x1f)
278273
279274 static void jz_gpio_check_trigger_both(struct jz_gpio_chip *chip, unsigned int irq)
@@ -403,6 +398,7 @@ static int jz_gpio_irq_set_wake(struct irq_data *data, unsigned int on) · 123 unmodified lines
403398 .get = jz_gpio_get_value, \
404399 .direction_output = jz_gpio_direction_output, \
405400 .direction_input = jz_gpio_direction_input, \
401+ .to_irq = jz_gpio_to_irq, \
406402 .base = JZ4740_GPIO_BASE_ ## _bank, \
407403 .ngpio = JZ4740_GPIO_NUM_ ## _bank, \
408404 }, \
@@ -423,8 +419,8 @@ static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id) · 14 unmodified lines
423419 chip->base = ioremap(JZ4740_GPIO_BASE_ADDR + (id * 0x100), 0x100);
424420
425421 chip->irq = JZ4740_IRQ_INTC_GPIO(id);
426− irq_set_handler_data(chip->irq, chip);
427− irq_set_chained_handler(chip->irq, jz_gpio_irq_demux_handler);
422+ irq_set_chained_handler_and_data(chip->irq,
423+ jz_gpio_irq_demux_handler, chip);
428424
429425 gc = irq_alloc_generic_chip(chip->gpio_chip.label, 1, chip->irq_base,
430426 chip->base, handle_level_irq);
arch/mips/jz4740/time.c+27−19
@@ -58,7 +58,7 @@ static irqreturn_t jz4740_clockevent_irq(int irq, void *devid) · 57 unmodified lines
5858
5959 jz4740_timer_ack_full(TIMER_CLOCKEVENT);
6060
61− if (cd->mode != CLOCK_EVT_MODE_PERIODIC)
61+ if (!clockevent_state_periodic(cd))
6262 jz4740_timer_disable(TIMER_CLOCKEVENT);
6363
6464 cd->event_handler(cd);
@@ -66,24 +66,29 @@ static irqreturn_t jz4740_clockevent_irq(int irq, void *devid) · 1 unmodified line
6666 return IRQ_HANDLED;
6767 }
6868
69−static void jz4740_clockevent_set_mode(enum clock_event_mode mode,
70− struct clock_event_device *cd)
69+static int jz4740_clockevent_set_periodic(struct clock_event_device *evt)
7170 {
72− switch (mode) {
73− case CLOCK_EVT_MODE_PERIODIC:
74− jz4740_timer_set_count(TIMER_CLOCKEVENT, 0);
75− jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick);
76− case CLOCK_EVT_MODE_RESUME:
77− jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT);
78− jz4740_timer_enable(TIMER_CLOCKEVENT);
79− break;
80− case CLOCK_EVT_MODE_ONESHOT:
81− case CLOCK_EVT_MODE_SHUTDOWN:
82− jz4740_timer_disable(TIMER_CLOCKEVENT);
83− break;
84− default:
85− break;
86− }
71+ jz4740_timer_set_count(TIMER_CLOCKEVENT, 0);
72+ jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick);
73+ jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT);
74+ jz4740_timer_enable(TIMER_CLOCKEVENT);
75+
76+ return 0;
77+}
78+
79+static int jz4740_clockevent_resume(struct clock_event_device *evt)
80+{
81+ jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT);
82+ jz4740_timer_enable(TIMER_CLOCKEVENT);
83+
84+ return 0;
85+}
86+
87+static int jz4740_clockevent_shutdown(struct clock_event_device *evt)
88+{
89+ jz4740_timer_disable(TIMER_CLOCKEVENT);
90+
91+ return 0;
8792 }
8893
8994 static int jz4740_clockevent_set_next(unsigned long evt,
@@ -100,7 +105,10 @@ static struct clock_event_device jz4740_clockevent = { · 10 unmodified lines
100105 .name = "jz4740-timer",
101106 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
102107 .set_next_event = jz4740_clockevent_set_next,
103− .set_mode = jz4740_clockevent_set_mode,
108+ .set_state_shutdown = jz4740_clockevent_shutdown,
109+ .set_state_periodic = jz4740_clockevent_set_periodic,
110+ .set_state_oneshot = jz4740_clockevent_shutdown,
111+ .tick_resume = jz4740_clockevent_resume,
104112 .rating = 200,
105113 #ifdef CONFIG_MACH_JZ4740
106114 .irq = JZ4740_IRQ_TCU0,
arch/mips/kernel/Makefile+1−0
@@ -99,6 +99,7 @@ obj-$(CONFIG_PERF_EVENTS) += perf_event.o · 98 unmodified lines
9999 obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_mipsxx.o
100100
101101 obj-$(CONFIG_JUMP_LABEL) += jump_label.o
102+obj-$(CONFIG_UPROBES) += uprobes.o
102103
103104 obj-$(CONFIG_MIPS_CM) += mips-cm.o
104105 obj-$(CONFIG_MIPS_CPC) += mips-cpc.o
arch/mips/kernel/asm-offsets.c+1−11
@@ -128,6 +128,7 @@ void output_thread_defines(void) · 127 unmodified lines
128128 thread.cp0_baduaddr);
129129 OFFSET(THREAD_ECODE, task_struct, \
130130 thread.error_code);
131+ OFFSET(THREAD_TRAPNO, task_struct, thread.trap_nr);
131132 BLANK();
132133 }
133134
@@ -245,17 +246,6 @@ void output_sc_defines(void) · 111 unmodified lines
245246 }
246247 #endif
247248
248−#ifdef CONFIG_MIPS32_COMPAT
249−void output_sc32_defines(void)
250−{
251− COMMENT("Linux 32-bit sigcontext offsets.");
252− OFFSET(SC32_FPREGS, sigcontext32, sc_fpregs);
253− OFFSET(SC32_FPC_CSR, sigcontext32, sc_fpc_csr);
254− OFFSET(SC32_FPC_EIR, sigcontext32, sc_fpc_eir);
255− BLANK();
256−}
257−#endif
258−
259249 void output_signal_defined(void)
260250 {
261251 COMMENT("Linux signal numbers.");
arch/mips/kernel/cevt-bcm1480.c+22−22
@@ -40,8 +40,8 @@ · 39 unmodified lines
4040 * The general purpose timer ticks at 1MHz independent if
4141 * the rest of the system
4242 */
43−static void sibyte_set_mode(enum clock_event_mode mode,
44− struct clock_event_device *evt)
43+
44+static int sibyte_set_periodic(struct clock_event_device *evt)
4545 {
4646 unsigned int cpu = smp_processor_id();
4747 void __iomem *cfg, *init;
@@ -49,24 +49,22 @@ static void sibyte_set_mode(enum clock_event_mode mode, · 1 unmodified line
4949 cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
5050 init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
5151
52− switch (mode) {
53− case CLOCK_EVT_MODE_PERIODIC:
54− __raw_writeq(0, cfg);
55− __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, init);
56− __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
57− cfg);
58− break;
59−
60− case CLOCK_EVT_MODE_ONESHOT:
61− /* Stop the timer until we actually program a shot */
62− case CLOCK_EVT_MODE_SHUTDOWN:
63− __raw_writeq(0, cfg);
64− break;
65−
66− case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */
67− case CLOCK_EVT_MODE_RESUME:
68− ;
69− }
52+ __raw_writeq(0, cfg);
53+ __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, init);
54+ __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, cfg);
55+ return 0;
56+}
57+
58+static int sibyte_shutdown(struct clock_event_device *evt)
59+{
60+ unsigned int cpu = smp_processor_id();
61+ void __iomem *cfg;
62+
63+ cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
64+
65+ /* Stop the timer until we actually program a shot */
66+ __raw_writeq(0, cfg);
67+ return 0;
7068 }
7169
7270 static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd)
@@ -91,7 +89,7 @@ static irqreturn_t sibyte_counter_handler(int irq, void *dev_id) · 18 unmodified lines
9189 void __iomem *cfg;
9290 unsigned long tmode;
9391
94− if (cd->mode == CLOCK_EVT_MODE_PERIODIC)
92+ if (clockevent_state_periodic(cd))
9593 tmode = M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS;
9694 else
9795 tmode = 0;
@@ -130,7 +128,9 @@ void sb1480_clockevent_init(void) · 32 unmodified lines
130128 cd->irq = irq;
131129 cd->cpumask = cpumask_of(cpu);
132130 cd->set_next_event = sibyte_next_event;
133− cd->set_mode = sibyte_set_mode;
131+ cd->set_state_shutdown = sibyte_shutdown;
132+ cd->set_state_periodic = sibyte_set_periodic;
133+ cd->set_state_oneshot = sibyte_shutdown;
134134 clockevents_register_device(cd);
135135
136136 bcm1480_mask_irq(cpu, irq);
arch/mips/kernel/cevt-ds1287.c+22−15
@@ -59,27 +59,32 @@ static int ds1287_set_next_event(unsigned long delta, · 58 unmodified lines
5959 return -EINVAL;
6060 }
6161
62−static void ds1287_set_mode(enum clock_event_mode mode,
63− struct clock_event_device *evt)
62+static int ds1287_shutdown(struct clock_event_device *evt)
6463 {
6564 u8 val;
6665
6766 spin_lock(&rtc_lock);
6867
6968 val = CMOS_READ(RTC_REG_B);
69+ val &= ~RTC_PIE;
70+ CMOS_WRITE(val, RTC_REG_B);
7071
71− switch (mode) {
72− case CLOCK_EVT_MODE_PERIODIC:
73− val |= RTC_PIE;
74− break;
75− default:
76− val &= ~RTC_PIE;
77− break;
78− }
72+ spin_unlock(&rtc_lock);
73+ return 0;
74+}
7975
76+static int ds1287_set_periodic(struct clock_event_device *evt)
77+{
78+ u8 val;
79+
80+ spin_lock(&rtc_lock);
81+
82+ val = CMOS_READ(RTC_REG_B);
83+ val |= RTC_PIE;
8084 CMOS_WRITE(val, RTC_REG_B);
8185
8286 spin_unlock(&rtc_lock);
87+ return 0;
8388 }
8489
8590 static void ds1287_event_handler(struct clock_event_device *dev)
@@ -87,11 +92,13 @@ static void ds1287_event_handler(struct clock_event_device *dev) · 1 unmodified line
8792 }
8893
8994 static struct clock_event_device ds1287_clockevent = {
90− .name = "ds1287",
91− .features = CLOCK_EVT_FEAT_PERIODIC,
92− .set_next_event = ds1287_set_next_event,
93− .set_mode = ds1287_set_mode,
94− .event_handler = ds1287_event_handler,
95+ .name = "ds1287",
96+ .features = CLOCK_EVT_FEAT_PERIODIC,
97+ .set_next_event = ds1287_set_next_event,
98+ .set_state_shutdown = ds1287_shutdown,
99+ .set_state_periodic = ds1287_set_periodic,
100+ .tick_resume = ds1287_shutdown,
101+ .event_handler = ds1287_event_handler,
95102 };
96103
97104 static irqreturn_t ds1287_interrupt(int irq, void *dev_id)
arch/mips/kernel/cevt-gt641xx.c+39−18
@@ -64,8 +64,7 @@ static int gt641xx_timer0_set_next_event(unsigned long delta, · 63 unmodified lines
6464 return 0;
6565 }
6666
67−static void gt641xx_timer0_set_mode(enum clock_event_mode mode,
68− struct clock_event_device *evt)
67+static int gt641xx_timer0_shutdown(struct clock_event_device *evt)
6968 {
7069 u32 ctrl;
7170
@@ -73,21 +72,39 @@ static void gt641xx_timer0_set_mode(enum clock_event_mode mode, · 1 unmodified line
7372
7473 ctrl = GT_READ(GT_TC_CONTROL_OFS);
7574 ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
75+ GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
76+
77+ raw_spin_unlock(&gt641xx_timer_lock);
78+ return 0;
79+}
80+
81+static int gt641xx_timer0_set_oneshot(struct clock_event_device *evt)
82+{
83+ u32 ctrl;
84+
85+ raw_spin_lock(&gt641xx_timer_lock);
86+
87+ ctrl = GT_READ(GT_TC_CONTROL_OFS);
88+ ctrl &= ~GT_TC_CONTROL_SELTC0_MSK;
89+ ctrl |= GT_TC_CONTROL_ENTC0_MSK;
90+ GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
91+
92+ raw_spin_unlock(&gt641xx_timer_lock);
93+ return 0;
94+}
7695
77− switch (mode) {
78− case CLOCK_EVT_MODE_PERIODIC:
79− ctrl |= GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK;
80− break;
81− case CLOCK_EVT_MODE_ONESHOT:
82− ctrl |= GT_TC_CONTROL_ENTC0_MSK;
83− break;
84− default:
85− break;
86− }
96+static int gt641xx_timer0_set_periodic(struct clock_event_device *evt)
97+{
98+ u32 ctrl;
99+
100+ raw_spin_lock(&gt641xx_timer_lock);
87101
102+ ctrl = GT_READ(GT_TC_CONTROL_OFS);
103+ ctrl |= GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK;
88104 GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
89105
90106 raw_spin_unlock(&gt641xx_timer_lock);
107+ return 0;
91108 }
92109
93110 static void gt641xx_timer0_event_handler(struct clock_event_device *dev)
@@ -95,12 +112,16 @@ static void gt641xx_timer0_event_handler(struct clock_event_device *dev) · 1 unmodified line
95112 }
96113
97114 static struct clock_event_device gt641xx_timer0_clockevent = {
98− .name = "gt641xx-timer0",
99− .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
100− .irq = GT641XX_TIMER0_IRQ,
101− .set_next_event = gt641xx_timer0_set_next_event,
102− .set_mode = gt641xx_timer0_set_mode,
103− .event_handler = gt641xx_timer0_event_handler,
115+ .name = "gt641xx-timer0",
116+ .features = CLOCK_EVT_FEAT_PERIODIC |
117+ CLOCK_EVT_FEAT_ONESHOT,
118+ .irq = GT641XX_TIMER0_IRQ,
119+ .set_next_event = gt641xx_timer0_set_next_event,
120+ .set_state_shutdown = gt641xx_timer0_shutdown,
121+ .set_state_periodic = gt641xx_timer0_set_periodic,
122+ .set_state_oneshot = gt641xx_timer0_set_oneshot,
123+ .tick_resume = gt641xx_timer0_shutdown,
124+ .event_handler = gt641xx_timer0_event_handler,
104125 };
105126
106127 static irqreturn_t gt641xx_timer0_interrupt(int irq, void *dev_id)
arch/mips/kernel/cevt-r4k.c+7−11
@@ -28,12 +28,6 @@ static int mips_next_event(unsigned long delta, · 27 unmodified lines
2828 return res;
2929 }
3030
31−void mips_set_clock_mode(enum clock_event_mode mode,
32− struct clock_event_device *evt)
33−{
34− /* Nothing to do ... */
35−}
36−
3731 DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device);
3832 int cp0_timer_irq_installed;
3933
@@ -174,6 +168,11 @@ int c0_compare_int_usable(void) · 134 unmodified lines
174168 return 1;
175169 }
176170
171+unsigned int __weak get_c0_compare_int(void)
172+{
173+ return MIPS_CPU_IRQ_BASE + cp0_compare_irq;
174+}
175+
177176 int r4k_clockevent_init(void)
178177 {
179178 unsigned int cpu = smp_processor_id();
@@ -189,11 +188,9 @@ int r4k_clockevent_init(void) · 9 unmodified lines
189188 /*
190189 * With vectored interrupts things are getting platform specific.
191190 * get_c0_compare_int is a hook to allow a platform to return the
192− * interrupt number of it's liking.
191+ * interrupt number of its liking.
193192 */
194− irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
195− if (get_c0_compare_int)
196− irq = get_c0_compare_int();
193+ irq = get_c0_compare_int();
197194
198195 cd = &per_cpu(mips_clockevent_device, cpu);
199196
@@ -212,7 +209,6 @@ int r4k_clockevent_init(void) · 12 unmodified lines
212209 cd->irq = irq;
213210 cd->cpumask = cpumask_of(cpu);
214211 cd->set_next_event = mips_next_event;
215− cd->set_mode = mips_set_clock_mode;
216212 cd->event_handler = mips_event_handler;
217213
218214 clockevents_register_device(cd);
arch/mips/kernel/cevt-sb1250.c+23−22
@@ -38,8 +38,20 @@ · 37 unmodified lines
3838 * The general purpose timer ticks at 1MHz independent if
3939 * the rest of the system
4040 */
41−static void sibyte_set_mode(enum clock_event_mode mode,
42− struct clock_event_device *evt)
41+
42+static int sibyte_shutdown(struct clock_event_device *evt)
43+{
44+ void __iomem *cfg;
45+
46+ cfg = IOADDR(A_SCD_TIMER_REGISTER(smp_processor_id(), R_SCD_TIMER_CFG));
47+
48+ /* Stop the timer until we actually program a shot */
49+ __raw_writeq(0, cfg);
50+
51+ return 0;
52+}
53+
54+static int sibyte_set_periodic(struct clock_event_device *evt)
4355 {
4456 unsigned int cpu = smp_processor_id();
4557 void __iomem *cfg, *init;
@@ -47,24 +59,11 @@ static void sibyte_set_mode(enum clock_event_mode mode, · 1 unmodified line
4759 cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
4860 init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
4961
50− switch (mode) {
51− case CLOCK_EVT_MODE_PERIODIC:
52− __raw_writeq(0, cfg);
53− __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, init);
54− __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
55− cfg);
56− break;
57−
58− case CLOCK_EVT_MODE_ONESHOT:
59− /* Stop the timer until we actually program a shot */
60− case CLOCK_EVT_MODE_SHUTDOWN:
61− __raw_writeq(0, cfg);
62− break;
63−
64− case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */
65− case CLOCK_EVT_MODE_RESUME:
66− ;
67− }
62+ __raw_writeq(0, cfg);
63+ __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, init);
64+ __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, cfg);
65+
66+ return 0;
6867 }
6968
7069 static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd)
@@ -89,7 +88,7 @@ static irqreturn_t sibyte_counter_handler(int irq, void *dev_id) · 18 unmodified lines
8988 void __iomem *cfg;
9089 unsigned long tmode;
9190
92− if (cd->mode == CLOCK_EVT_MODE_PERIODIC)
91+ if (clockevent_state_periodic(cd))
9392 tmode = M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS;
9493 else
9594 tmode = 0;
@@ -129,7 +128,9 @@ void sb1250_clockevent_init(void) · 33 unmodified lines
129128 cd->irq = irq;
130129 cd->cpumask = cpumask_of(cpu);
131130 cd->set_next_event = sibyte_next_event;
132− cd->set_mode = sibyte_set_mode;
131+ cd->set_state_shutdown = sibyte_shutdown;
132+ cd->set_state_periodic = sibyte_set_periodic;
133+ cd->set_state_oneshot = sibyte_shutdown;
133134 clockevents_register_device(cd);
134135
135136 sb1250_mask_irq(cpu, irq);
arch/mips/kernel/cevt-txx9.c+51−30
@@ -85,36 +85,54 @@ static void txx9tmr_stop_and_clear(struct txx9_tmr_reg __iomem *tmrptr) · 84 unmodified lines
8585 __raw_writel(0, &tmrptr->tisr);
8686 }
8787
88−static void txx9tmr_set_mode(enum clock_event_mode mode,
89− struct clock_event_device *evt)
88+static int txx9tmr_set_state_periodic(struct clock_event_device *evt)
9089 {
9190 struct txx9_clock_event_device *txx9_cd =
9291 container_of(evt, struct txx9_clock_event_device, cd);
9392 struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
9493
9594 txx9tmr_stop_and_clear(tmrptr);
96− switch (mode) {
97− case CLOCK_EVT_MODE_PERIODIC:
98− __raw_writel(TXx9_TMITMR_TIIE | TXx9_TMITMR_TZCE,
99− &tmrptr->itmr);
100− /* start timer */
101− __raw_writel(((u64)(NSEC_PER_SEC / HZ) * evt->mult) >>
102− evt->shift,
103− &tmrptr->cpra);
104− __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
105− break;
106− case CLOCK_EVT_MODE_SHUTDOWN:
107− case CLOCK_EVT_MODE_UNUSED:
108− __raw_writel(0, &tmrptr->itmr);
109− break;
110− case CLOCK_EVT_MODE_ONESHOT:
111− __raw_writel(TXx9_TMITMR_TIIE, &tmrptr->itmr);
112− break;
113− case CLOCK_EVT_MODE_RESUME:
114− __raw_writel(TIMER_CCD, &tmrptr->ccdr);
115− __raw_writel(0, &tmrptr->itmr);
116− break;
117− }
95+
96+ __raw_writel(TXx9_TMITMR_TIIE | TXx9_TMITMR_TZCE, &tmrptr->itmr);
97+ /* start timer */
98+ __raw_writel(((u64)(NSEC_PER_SEC / HZ) * evt->mult) >> evt->shift,
99+ &tmrptr->cpra);
100+ __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
101+ return 0;
102+}
103+
104+static int txx9tmr_set_state_oneshot(struct clock_event_device *evt)
105+{
106+ struct txx9_clock_event_device *txx9_cd =
107+ container_of(evt, struct txx9_clock_event_device, cd);
108+ struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
109+
110+ txx9tmr_stop_and_clear(tmrptr);
111+ __raw_writel(TXx9_TMITMR_TIIE, &tmrptr->itmr);
112+ return 0;
113+}
114+
115+static int txx9tmr_set_state_shutdown(struct clock_event_device *evt)
116+{
117+ struct txx9_clock_event_device *txx9_cd =
118+ container_of(evt, struct txx9_clock_event_device, cd);
119+ struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
120+
121+ txx9tmr_stop_and_clear(tmrptr);
122+ __raw_writel(0, &tmrptr->itmr);
123+ return 0;
124+}
125+
126+static int txx9tmr_tick_resume(struct clock_event_device *evt)
127+{
128+ struct txx9_clock_event_device *txx9_cd =
129+ container_of(evt, struct txx9_clock_event_device, cd);
130+ struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
131+
132+ txx9tmr_stop_and_clear(tmrptr);
133+ __raw_writel(TIMER_CCD, &tmrptr->ccdr);
134+ __raw_writel(0, &tmrptr->itmr);
135+ return 0;
118136 }
119137
120138 static int txx9tmr_set_next_event(unsigned long delta,
@@ -133,12 +151,15 @@ static int txx9tmr_set_next_event(unsigned long delta, · 12 unmodified lines
133151
134152 static struct txx9_clock_event_device txx9_clock_event_device = {
135153 .cd = {
136− .name = "TXx9",
137− .features = CLOCK_EVT_FEAT_PERIODIC |
138− CLOCK_EVT_FEAT_ONESHOT,
139− .rating = 200,
140− .set_mode = txx9tmr_set_mode,
141− .set_next_event = txx9tmr_set_next_event,
154+ .name = "TXx9",
155+ .features = CLOCK_EVT_FEAT_PERIODIC |
156+ CLOCK_EVT_FEAT_ONESHOT,
157+ .rating = 200,
158+ .set_state_shutdown = txx9tmr_set_state_shutdown,
159+ .set_state_periodic = txx9tmr_set_state_periodic,
160+ .set_state_oneshot = txx9tmr_set_state_oneshot,
161+ .tick_resume = txx9tmr_tick_resume,
162+ .set_next_event = txx9tmr_set_next_event,
142163 },
143164 };
144165
arch/mips/kernel/cps-vec.S+2−2
@@ -152,7 +152,7 @@ dcache_done: · 151 unmodified lines
152152
153153 /* Enter the coherent domain */
154154 li t0, 0xff
155− PTR_S t0, GCR_CL_COHERENCE_OFS(v1)
155+ sw t0, GCR_CL_COHERENCE_OFS(v1)
156156 ehb
157157
158158 /* Jump to kseg0 */
@@ -302,7 +302,7 @@ LEAF(mips_cps_boot_vpes) · 143 unmodified lines
302302 PTR_L t0, 0(t0)
303303
304304 /* Calculate a pointer to this cores struct core_boot_config */
305− PTR_L t0, GCR_CL_ID_OFS(t0)
305+ lw t0, GCR_CL_ID_OFS(t0)
306306 li t1, COREBOOTCFG_SIZE
307307 mul t0, t0, t1
308308 PTR_LA t1, mips_cps_core_bootcfg
arch/mips/kernel/cpu-probe.c+46−10
@@ -32,6 +32,9 @@ · 31 unmodified lines
3232 #include <asm/spram.h>
3333 #include <asm/uaccess.h>
3434
35+/* Hardware capabilities */
36+unsigned int elf_hwcap __read_mostly;
37+
3538 /*
3639 * Get the FPU Implementation/Revision.
3740 */
@@ -188,7 +191,7 @@ __setup("nohtw", htw_disable); · 150 unmodified lines
188191 static int mips_ftlb_disabled;
189192 static int mips_has_ftlb_configured;
190193
191−static void set_ftlb_enable(struct cpuinfo_mips *c, int enable);
194+static int set_ftlb_enable(struct cpuinfo_mips *c, int enable);
192195
193196 static int __init ftlb_disable(char *s)
194197 {
@@ -202,7 +205,10 @@ static int __init ftlb_disable(char *s) · 7 unmodified lines
202205 return 1;
203206
204207 /* Disable it in the boot cpu */
205− set_ftlb_enable(&cpu_data[0], 0);
208+ if (set_ftlb_enable(&cpu_data[0], 0)) {
209+ pr_warn("Can't turn FTLB off\n");
210+ return 1;
211+ }
206212
207213 back_to_back_c0_hazard();
208214
@@ -364,30 +370,41 @@ static unsigned int calculate_ftlb_probability(struct cpuinfo_mips *c) · 155 unmodified lines
364370 return 3;
365371 }
366372
367−static void set_ftlb_enable(struct cpuinfo_mips *c, int enable)
373+static int set_ftlb_enable(struct cpuinfo_mips *c, int enable)
368374 {
369− unsigned int config6;
375+ unsigned int config;
370376
371377 /* It's implementation dependent how the FTLB can be enabled */
372378 switch (c->cputype) {
373379 case CPU_PROAPTIV:
374380 case CPU_P5600:
375381 /* proAptiv & related cores use Config6 to enable the FTLB */
376− config6 = read_c0_config6();
382+ config = read_c0_config6();
377383 /* Clear the old probability value */
378− config6 &= ~(3 << MIPS_CONF6_FTLBP_SHIFT);
384+ config &= ~(3 << MIPS_CONF6_FTLBP_SHIFT);
379385 if (enable)
380386 /* Enable FTLB */
381− write_c0_config6(config6 |
387+ write_c0_config6(config |
382388 (calculate_ftlb_probability(c)
383389 << MIPS_CONF6_FTLBP_SHIFT)
384390 | MIPS_CONF6_FTLBEN);
385391 else
386392 /* Disable FTLB */
387− write_c0_config6(config6 & ~MIPS_CONF6_FTLBEN);
388− back_to_back_c0_hazard();
393+ write_c0_config6(config & ~MIPS_CONF6_FTLBEN);
389394 break;
395+ case CPU_I6400:
396+ /* I6400 & related cores use Config7 to configure FTLB */
397+ config = read_c0_config7();
398+ /* Clear the old probability value */
399+ config &= ~(3 << MIPS_CONF7_FTLBP_SHIFT);
400+ write_c0_config7(config | (calculate_ftlb_probability(c)
401+ << MIPS_CONF7_FTLBP_SHIFT));
402+ break;
403+ default:
404+ return 1;
390405 }
406+
407+ return 0;
391408 }
392409
393410 static inline unsigned int decode_config0(struct cpuinfo_mips *c)
@@ -524,6 +541,8 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c) · 130 unmodified lines
524541 }
525542 if (config3 & MIPS_CONF3_CDMM)
526543 c->options |= MIPS_CPU_CDMM;
544+ if (config3 & MIPS_CONF3_SP)
545+ c->options |= MIPS_CPU_SP;
527546
528547 return config3 & MIPS_CONF_M;
529548 }
@@ -540,7 +559,16 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c) · 10 unmodified lines
540559 if (cpu_has_tlb) {
541560 if (((config4 & MIPS_CONF4_IE) >> 29) == 2)
542561 c->options |= MIPS_CPU_TLBINV;
543− mmuextdef = config4 & MIPS_CONF4_MMUEXTDEF;
562+ /*
563+ * This is a bit ugly. R6 has dropped that field from
564+ * config4 and the only valid configuration is VTLB+FTLB so
565+ * set a good value for mmuextdef for that case.
566+ */
567+ if (cpu_has_mips_r6)
568+ mmuextdef = MIPS_CONF4_MMUEXTDEF_VTLBSIZEEXT;
569+ else
570+ mmuextdef = config4 & MIPS_CONF4_MMUEXTDEF;
571+
544572 switch (mmuextdef) {
545573 case MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT:
546574 c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
@@ -1121,6 +1149,10 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) · 574 unmodified lines
11211149 c->cputype = CPU_P5600;
11221150 __cpu_name[cpu] = "MIPS P5600";
11231151 break;
1152+ case PRID_IMP_I6400:
1153+ c->cputype = CPU_I6400;
1154+ __cpu_name[cpu] = "MIPS I6400";
1155+ break;
11241156 case PRID_IMP_M5150:
11251157 c->cputype = CPU_M5150;
11261158 __cpu_name[cpu] = "MIPS M5150";
@@ -1492,10 +1524,14 @@ void cpu_probe(void) · 365 unmodified lines
14921524 else
14931525 c->srsets = 1;
14941526
1527+ if (cpu_has_mips_r6)
1528+ elf_hwcap |= HWCAP_MIPS_R6;
1529+
14951530 if (cpu_has_msa) {
14961531 c->msa_id = cpu_get_msa_id();
14971532 WARN(c->msa_id & MSA_IR_WRPF,
14981533 "Vector register partitioning unimplemented!");
1534+ elf_hwcap |= HWCAP_MIPS_MSA;
14991535 }
15001536
15011537 cpu_probe_vmbits(c);
arch/mips/kernel/idle.c+1−0
@@ -196,6 +196,7 @@ void __init check_wait(void) · 195 unmodified lines
196196 case CPU_INTERAPTIV:
197197 case CPU_M5150:
198198 case CPU_QEMU_GENERIC:
199+ case CPU_I6400:
199200 cpu_wait = r4k_wait;
200201 if (read_c0_config7() & MIPS_CONF7_WII)
201202 cpu_wait = r4k_wait_irqoff;
arch/mips/kernel/mips-cm.c+256−1
@@ -15,11 +15,131 @@ · 14 unmodified lines
1515
1616 void __iomem *mips_cm_base;
1717 void __iomem *mips_cm_l2sync_base;
18+int mips_cm_is64;
19+
20+static char *cm2_tr[8] = {
21+ "mem", "gcr", "gic", "mmio",
22+ "0x04", "cpc", "0x06", "0x07"
23+};
24+
25+/* CM3 Tag ECC transation type */
26+static char *cm3_tr[16] = {
27+ [0x0] = "ReqNoData",
28+ [0x1] = "0x1",
29+ [0x2] = "ReqWData",
30+ [0x3] = "0x3",
31+ [0x4] = "IReqNoResp",
32+ [0x5] = "IReqWResp",
33+ [0x6] = "IReqNoRespDat",
34+ [0x7] = "IReqWRespDat",
35+ [0x8] = "RespNoData",
36+ [0x9] = "RespDataFol",
37+ [0xa] = "RespWData",
38+ [0xb] = "RespDataOnly",
39+ [0xc] = "IRespNoData",
40+ [0xd] = "IRespDataFol",
41+ [0xe] = "IRespWData",
42+ [0xf] = "IRespDataOnly"
43+};
44+
45+static char *cm2_cmd[32] = {
46+ [0x00] = "0x00",
47+ [0x01] = "Legacy Write",
48+ [0x02] = "Legacy Read",
49+ [0x03] = "0x03",
50+ [0x04] = "0x04",
51+ [0x05] = "0x05",
52+ [0x06] = "0x06",
53+ [0x07] = "0x07",
54+ [0x08] = "Coherent Read Own",
55+ [0x09] = "Coherent Read Share",
56+ [0x0a] = "Coherent Read Discard",
57+ [0x0b] = "Coherent Ready Share Always",
58+ [0x0c] = "Coherent Upgrade",
59+ [0x0d] = "Coherent Writeback",
60+ [0x0e] = "0x0e",
61+ [0x0f] = "0x0f",
62+ [0x10] = "Coherent Copyback",
63+ [0x11] = "Coherent Copyback Invalidate",
64+ [0x12] = "Coherent Invalidate",
65+ [0x13] = "Coherent Write Invalidate",
66+ [0x14] = "Coherent Completion Sync",
67+ [0x15] = "0x15",
68+ [0x16] = "0x16",
69+ [0x17] = "0x17",
70+ [0x18] = "0x18",
71+ [0x19] = "0x19",
72+ [0x1a] = "0x1a",
73+ [0x1b] = "0x1b",
74+ [0x1c] = "0x1c",
75+ [0x1d] = "0x1d",
76+ [0x1e] = "0x1e",
77+ [0x1f] = "0x1f"
78+};
79+
80+/* CM3 Tag ECC command type */
81+static char *cm3_cmd[16] = {
82+ [0x0] = "Legacy Read",
83+ [0x1] = "Legacy Write",
84+ [0x2] = "Coherent Read Own",
85+ [0x3] = "Coherent Read Share",
86+ [0x4] = "Coherent Read Discard",
87+ [0x5] = "Coherent Evicted",
88+ [0x6] = "Coherent Upgrade",
89+ [0x7] = "Coherent Upgrade for Store Conditional",
90+ [0x8] = "Coherent Writeback",
91+ [0x9] = "Coherent Write Invalidate",
92+ [0xa] = "0xa",
93+ [0xb] = "0xb",
94+ [0xc] = "0xc",
95+ [0xd] = "0xd",
96+ [0xe] = "0xe",
97+ [0xf] = "0xf"
98+};
99+
100+/* CM3 Tag ECC command group */
101+static char *cm3_cmd_group[8] = {
102+ [0x0] = "Normal",
103+ [0x1] = "Registers",
104+ [0x2] = "TLB",
105+ [0x3] = "0x3",
106+ [0x4] = "L1I",
107+ [0x5] = "L1D",
108+ [0x6] = "L3",
109+ [0x7] = "L2"
110+};
111+
112+static char *cm2_core[8] = {
113+ "Invalid/OK", "Invalid/Data",
114+ "Shared/OK", "Shared/Data",
115+ "Modified/OK", "Modified/Data",
116+ "Exclusive/OK", "Exclusive/Data"
117+};
118+
119+static char *cm2_causes[32] = {
120+ "None", "GC_WR_ERR", "GC_RD_ERR", "COH_WR_ERR",
121+ "COH_RD_ERR", "MMIO_WR_ERR", "MMIO_RD_ERR", "0x07",
122+ "0x08", "0x09", "0x0a", "0x0b",
123+ "0x0c", "0x0d", "0x0e", "0x0f",
124+ "0x10", "0x11", "0x12", "0x13",
125+ "0x14", "0x15", "0x16", "INTVN_WR_ERR",
126+ "INTVN_RD_ERR", "0x19", "0x1a", "0x1b",
127+ "0x1c", "0x1d", "0x1e", "0x1f"
128+};
129+
130+static char *cm3_causes[32] = {
131+ "0x0", "MP_CORRECTABLE_ECC_ERR", "MP_REQUEST_DECODE_ERR",
132+ "MP_UNCORRECTABLE_ECC_ERR", "MP_PARITY_ERR", "MP_COHERENCE_ERR",
133+ "CMBIU_REQUEST_DECODE_ERR", "CMBIU_PARITY_ERR", "CMBIU_AXI_RESP_ERR",
134+ "0x9", "RBI_BUS_ERR", "0xb", "0xc", "0xd", "0xe", "0xf", "0x10",
135+ "0x11", "0x12", "0x13", "0x14", "0x15", "0x16", "0x17", "0x18",
136+ "0x19", "0x1a", "0x1b", "0x1c", "0x1d", "0x1e", "0x1f"
137+};
18138
19139 phys_addr_t __mips_cm_phys_base(void)
20140 {
21141 u32 config3 = read_c0_config3();
22− u32 cmgcr;
142+ unsigned long cmgcr;
23143
24144 /* Check the CMGCRBase register is implemented */
25145 if (!(config3 & MIPS_CONF3_CMGCR))
@@ -81,6 +201,13 @@ int mips_cm_probe(void) · 55 unmodified lines
81201 phys_addr_t addr;
82202 u32 base_reg;
83203
204+ /*
205+ * No need to probe again if we have already been
206+ * here before.
207+ */
208+ if (mips_cm_base)
209+ return 0;
210+
84211 addr = mips_cm_phys_base();
85212 BUG_ON((addr & CM_GCR_BASE_GCRBASE_MSK) != addr);
86213 if (!addr)
@@ -117,5 +244,133 @@ int mips_cm_probe(void) · 30 unmodified lines
117244 /* probe for an L2-only sync region */
118245 mips_cm_probe_l2sync();
119246
247+ /* determine register width for this CM */
248+ mips_cm_is64 = config_enabled(CONFIG_64BIT) && (mips_cm_revision() >= CM_REV_CM3);
249+
120250 return 0;
121251 }
252+
253+void mips_cm_error_report(void)
254+{
255+ unsigned long revision = mips_cm_revision();
256+ /*
257+ * CM3 has a 64-bit Error cause register with 0:57 containing the error
258+ * info and 63:58 the error type. For old CMs, everything is contained
259+ * in a single 32-bit register (0:26 and 31:27 respectively). Even
260+ * though the cm_error is u64, we will simply ignore the upper word
261+ * for CM2.
262+ */
263+ u64 cm_error = read_gcr_error_cause();
264+ int cm_error_cause_sft = CM_GCR_ERROR_CAUSE_ERRTYPE_SHF +
265+ ((revision >= CM_REV_CM3) ? 31 : 0);
266+ unsigned long cm_addr = read_gcr_error_addr();
267+ unsigned long cm_other = read_gcr_error_mult();
268+ int ocause, cause;
269+ char buf[256];
270+
271+ if (!mips_cm_present())
272+ return;
273+
274+ cause = cm_error >> cm_error_cause_sft;
275+
276+ if (!cause)
277+ /* All good */
278+ return;
279+
280+ ocause = cm_other >> CM_GCR_ERROR_MULT_ERR2ND_SHF;
281+ if (revision < CM_REV_CM3) { /* CM2 */
282+ if (cause < 16) {
283+ unsigned long cca_bits = (cm_error >> 15) & 7;
284+ unsigned long tr_bits = (cm_error >> 12) & 7;
285+ unsigned long cmd_bits = (cm_error >> 7) & 0x1f;
286+ unsigned long stag_bits = (cm_error >> 3) & 15;
287+ unsigned long sport_bits = (cm_error >> 0) & 7;
288+
289+ snprintf(buf, sizeof(buf),
290+ "CCA=%lu TR=%s MCmd=%s STag=%lu "
291+ "SPort=%lu\n", cca_bits, cm2_tr[tr_bits],
292+ cm2_cmd[cmd_bits], stag_bits, sport_bits);
293+ } else {
294+ /* glob state & sresp together */
295+ unsigned long c3_bits = (cm_error >> 18) & 7;
296+ unsigned long c2_bits = (cm_error >> 15) & 7;
297+ unsigned long c1_bits = (cm_error >> 12) & 7;
298+ unsigned long c0_bits = (cm_error >> 9) & 7;
299+ unsigned long sc_bit = (cm_error >> 8) & 1;
300+ unsigned long cmd_bits = (cm_error >> 3) & 0x1f;
301+ unsigned long sport_bits = (cm_error >> 0) & 7;
302+
303+ snprintf(buf, sizeof(buf),
304+ "C3=%s C2=%s C1=%s C0=%s SC=%s "
305+ "MCmd=%s SPort=%lu\n",
306+ cm2_core[c3_bits], cm2_core[c2_bits],
307+ cm2_core[c1_bits], cm2_core[c0_bits],
308+ sc_bit ? "True" : "False",
309+ cm2_cmd[cmd_bits], sport_bits);
310+ }
311+ pr_err("CM_ERROR=%08llx %s <%s>\n", cm_error,
312+ cm2_causes[cause], buf);
313+ pr_err("CM_ADDR =%08lx\n", cm_addr);
314+ pr_err("CM_OTHER=%08lx %s\n", cm_other, cm2_causes[ocause]);
315+ } else { /* CM3 */
316+ /* Used by cause == {1,2,3} */
317+ unsigned long core_id_bits = (cm_error >> 22) & 0xf;
318+ unsigned long vp_id_bits = (cm_error >> 18) & 0xf;
319+ unsigned long cmd_bits = (cm_error >> 14) & 0xf;
320+ unsigned long cmd_group_bits = (cm_error >> 11) & 0xf;
321+ unsigned long cm3_cca_bits = (cm_error >> 8) & 7;
322+ unsigned long mcp_bits = (cm_error >> 5) & 0xf;
323+ unsigned long cm3_tr_bits = (cm_error >> 1) & 0xf;
324+ unsigned long sched_bit = cm_error & 0x1;
325+
326+ if (cause == 1 || cause == 3) { /* Tag ECC */
327+ unsigned long tag_ecc = (cm_error >> 57) & 0x1;
328+ unsigned long tag_way_bits = (cm_error >> 29) & 0xffff;
329+ unsigned long dword_bits = (cm_error >> 49) & 0xff;
330+ unsigned long data_way_bits = (cm_error >> 45) & 0xf;
331+ unsigned long data_sets_bits = (cm_error >> 29) & 0xfff;
332+ unsigned long bank_bit = (cm_error >> 28) & 0x1;
333+ snprintf(buf, sizeof(buf),
334+ "%s ECC Error: Way=%lu (DWORD=%lu, Sets=%lu)"
335+ "Bank=%lu CoreID=%lu VPID=%lu Command=%s"
336+ "Command Group=%s CCA=%lu MCP=%d"
337+ "Transaction type=%s Scheduler=%lu\n",
338+ tag_ecc ? "TAG" : "DATA",
339+ tag_ecc ? (unsigned long)ffs(tag_way_bits) - 1 :
340+ data_way_bits, bank_bit, dword_bits,
341+ data_sets_bits,
342+ core_id_bits, vp_id_bits,
343+ cm3_cmd[cmd_bits],
344+ cm3_cmd_group[cmd_group_bits],
345+ cm3_cca_bits, 1 << mcp_bits,
346+ cm3_tr[cm3_tr_bits], sched_bit);
347+ } else if (cause == 2) {
348+ unsigned long data_error_type = (cm_error >> 41) & 0xfff;
349+ unsigned long data_decode_cmd = (cm_error >> 37) & 0xf;
350+ unsigned long data_decode_group = (cm_error >> 34) & 0x7;
351+ unsigned long data_decode_destination_id = (cm_error >> 28) & 0x3f;
352+
353+ snprintf(buf, sizeof(buf),
354+ "Decode Request Error: Type=%lu, Command=%lu"
355+ "Command Group=%lu Destination ID=%lu"
356+ "CoreID=%lu VPID=%lu Command=%s"
357+ "Command Group=%s CCA=%lu MCP=%d"
358+ "Transaction type=%s Scheduler=%lu\n",
359+ data_error_type, data_decode_cmd,
360+ data_decode_group, data_decode_destination_id,
361+ core_id_bits, vp_id_bits,
362+ cm3_cmd[cmd_bits],
363+ cm3_cmd_group[cmd_group_bits],
364+ cm3_cca_bits, 1 << mcp_bits,
365+ cm3_tr[cm3_tr_bits], sched_bit);
366+ }
367+
368+ pr_err("CM_ERROR=%llx %s <%s>\n", cm_error,
369+ cm3_causes[cause], buf);
370+ pr_err("CM_ADDR =%lx\n", cm_addr);
371+ pr_err("CM_OTHER=%lx %s\n", cm_other, cm3_causes[ocause]);
372+ }
373+
374+ /* reprime cause register */
375+ write_gcr_error_cause(0);
376+}
arch/mips/kernel/mips-cpc.c+9−2
@@ -21,9 +21,16 @@ static DEFINE_PER_CPU_ALIGNED(spinlock_t, cpc_core_lock); · 20 unmodified lines
2121
2222 static DEFINE_PER_CPU_ALIGNED(unsigned long, cpc_core_lock_flags);
2323
24−phys_addr_t __weak mips_cpc_phys_base(void)
24+/**
25+ * mips_cpc_phys_base - retrieve the physical base address of the CPC
26+ *
27+ * This function returns the physical base address of the Cluster Power
28+ * Controller memory mapped registers, or 0 if no Cluster Power Controller
29+ * is present.
30+ */
31+static phys_addr_t mips_cpc_phys_base(void)
2532 {
26− u32 cpc_base;
33+ unsigned long cpc_base;
2734
2835 if (!mips_cm_present())
2936 return 0;
arch/mips/kernel/perf_event_mipsxx.c+6−0
@@ -1556,6 +1556,7 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config) · 1555 unmodified lines
15561556 #endif
15571557 break;
15581558 case CPU_P5600:
1559+ case CPU_I6400:
15591560 /* 8-bit event numbers */
15601561 raw_id = config & 0x1ff;
15611562 base_id = raw_id & 0xff;
@@ -1717,6 +1718,11 @@ init_hw_perf_events(void) · 155 unmodified lines
17171718 mipspmu.general_event_map = &mipsxxcore_event_map2;
17181719 mipspmu.cache_event_map = &mipsxxcore_cache_map2;
17191720 break;
1721+ case CPU_I6400:
1722+ mipspmu.name = "mips/I6400";
1723+ mipspmu.general_event_map = &mipsxxcore_event_map2;
1724+ mipspmu.cache_event_map = &mipsxxcore_cache_map2;
1725+ break;
17201726 case CPU_1004K:
17211727 mipspmu.name = "mips/1004K";
17221728 mipspmu.general_event_map = &mipsxxcore_event_map;
arch/mips/kernel/pm-cps.c+2−0
@@ -267,6 +267,7 @@ static int __init cps_gen_flush_fsb(u32 **pp, struct uasm_label **pl, · 266 unmodified lines
267267
268268 /* CPUs which do not require the workaround */
269269 case CPU_P5600:
270+ case CPU_I6400:
270271 return 0;
271272
272273 default:
@@ -671,6 +672,7 @@ static int __init cps_pm_init(void) · 398 unmodified lines
671672 case CPU_PROAPTIV:
672673 case CPU_M5150:
673674 case CPU_P5600:
675+ case CPU_I6400:
674676 stype_intervention = 0x2;
675677 stype_memory = 0x3;
676678 stype_ordering = 0x10;
arch/mips/kernel/ptrace.c+88−0
@@ -25,6 +25,7 @@ · 24 unmodified lines
2525 #include <linux/regset.h>
2626 #include <linux/smp.h>
2727 #include <linux/security.h>
28+#include <linux/stddef.h>
2829 #include <linux/tracehook.h>
2930 #include <linux/audit.h>
3031 #include <linux/seccomp.h>
@@ -490,6 +491,93 @@ enum mips_regset { · 459 unmodified lines
490491 REGSET_FPR,
491492 };
492493
494+struct pt_regs_offset {
495+ const char *name;
496+ int offset;
497+};
498+
499+#define REG_OFFSET_NAME(reg, r) { \
500+ .name = #reg, \
501+ .offset = offsetof(struct pt_regs, r) \
502+}
503+
504+#define REG_OFFSET_END { \
505+ .name = NULL, \
506+ .offset = 0 \
507+}
508+
509+static const struct pt_regs_offset regoffset_table[] = {
510+ REG_OFFSET_NAME(r0, regs[0]),
511+ REG_OFFSET_NAME(r1, regs[1]),
512+ REG_OFFSET_NAME(r2, regs[2]),
513+ REG_OFFSET_NAME(r3, regs[3]),
514+ REG_OFFSET_NAME(r4, regs[4]),
515+ REG_OFFSET_NAME(r5, regs[5]),
516+ REG_OFFSET_NAME(r6, regs[6]),
517+ REG_OFFSET_NAME(r7, regs[7]),
518+ REG_OFFSET_NAME(r8, regs[8]),
519+ REG_OFFSET_NAME(r9, regs[9]),
520+ REG_OFFSET_NAME(r10, regs[10]),
521+ REG_OFFSET_NAME(r11, regs[11]),
522+ REG_OFFSET_NAME(r12, regs[12]),
523+ REG_OFFSET_NAME(r13, regs[13]),
524+ REG_OFFSET_NAME(r14, regs[14]),
525+ REG_OFFSET_NAME(r15, regs[15]),
526+ REG_OFFSET_NAME(r16, regs[16]),
527+ REG_OFFSET_NAME(r17, regs[17]),
528+ REG_OFFSET_NAME(r18, regs[18]),
529+ REG_OFFSET_NAME(r19, regs[19]),
530+ REG_OFFSET_NAME(r20, regs[20]),
531+ REG_OFFSET_NAME(r21, regs[21]),
532+ REG_OFFSET_NAME(r22, regs[22]),
533+ REG_OFFSET_NAME(r23, regs[23]),
534+ REG_OFFSET_NAME(r24, regs[24]),
535+ REG_OFFSET_NAME(r25, regs[25]),
536+ REG_OFFSET_NAME(r26, regs[26]),
537+ REG_OFFSET_NAME(r27, regs[27]),
538+ REG_OFFSET_NAME(r28, regs[28]),
539+ REG_OFFSET_NAME(r29, regs[29]),
540+ REG_OFFSET_NAME(r30, regs[30]),
541+ REG_OFFSET_NAME(r31, regs[31]),
542+ REG_OFFSET_NAME(c0_status, cp0_status),
543+ REG_OFFSET_NAME(hi, hi),
544+ REG_OFFSET_NAME(lo, lo),
545+#ifdef CONFIG_CPU_HAS_SMARTMIPS
546+ REG_OFFSET_NAME(acx, acx),
547+#endif
548+ REG_OFFSET_NAME(c0_badvaddr, cp0_badvaddr),
549+ REG_OFFSET_NAME(c0_cause, cp0_cause),
550+ REG_OFFSET_NAME(c0_epc, cp0_epc),
551+#ifdef CONFIG_MIPS_MT_SMTC
552+ REG_OFFSET_NAME(c0_tcstatus, cp0_tcstatus),
553+#endif
554+#ifdef CONFIG_CPU_CAVIUM_OCTEON
555+ REG_OFFSET_NAME(mpl0, mpl[0]),
556+ REG_OFFSET_NAME(mpl1, mpl[1]),
557+ REG_OFFSET_NAME(mpl2, mpl[2]),
558+ REG_OFFSET_NAME(mtp0, mtp[0]),
559+ REG_OFFSET_NAME(mtp1, mtp[1]),
560+ REG_OFFSET_NAME(mtp2, mtp[2]),
561+#endif
562+ REG_OFFSET_END,
563+};
564+
565+/**
566+ * regs_query_register_offset() - query register offset from its name
567+ * @name: the name of a register
568+ *
569+ * regs_query_register_offset() returns the offset of a register in struct
570+ * pt_regs from its name. If the name is invalid, this returns -EINVAL;
571+ */
572+int regs_query_register_offset(const char *name)
573+{
574+ const struct pt_regs_offset *roff;
575+ for (roff = regoffset_table; roff->name != NULL; roff++)
576+ if (!strcmp(roff->name, name))
577+ return roff->offset;
578+ return -EINVAL;
579+}
580+
493581 #if defined(CONFIG_32BIT) || defined(CONFIG_MIPS32_O32)
494582
495583 static const struct user_regset mips_regsets[] = {
arch/mips/kernel/r4k_fpu.S+259−177
@@ -13,6 +13,7 @@ · 12 unmodified lines
1313 * Copyright (C) 1999, 2001 Silicon Graphics, Inc.
1414 */
1515 #include <asm/asm.h>
16+#include <asm/asmmacro.h>
1617 #include <asm/errno.h>
1718 #include <asm/fpregdef.h>
1819 #include <asm/mipsregs.h>
@@ -35,6 +36,14 @@ · 16 unmodified lines
3536
3637 .set noreorder
3738
39+/**
40+ * _save_fp_context() - save FP context from the FPU
41+ * @a0 - pointer to fpregs field of sigcontext
42+ * @a1 - pointer to fpc_csr field of sigcontext
43+ *
44+ * Save FP context, including the 32 FP data registers and the FP
45+ * control & status register, from the FPU to signal context.
46+ */
3847 LEAF(_save_fp_context)
3948 .set push
4049 SET_HARDFLOAT
@@ -54,117 +63,60 @@ LEAF(_save_fp_context) · 13 unmodified lines
5463 nop
5564 #endif
5665 /* Store the 16 odd double precision registers */
57− EX sdc1 $f1, SC_FPREGS+8(a0)
58− EX sdc1 $f3, SC_FPREGS+24(a0)
59− EX sdc1 $f5, SC_FPREGS+40(a0)
60− EX sdc1 $f7, SC_FPREGS+56(a0)
61− EX sdc1 $f9, SC_FPREGS+72(a0)
62− EX sdc1 $f11, SC_FPREGS+88(a0)
63− EX sdc1 $f13, SC_FPREGS+104(a0)
64− EX sdc1 $f15, SC_FPREGS+120(a0)
65− EX sdc1 $f17, SC_FPREGS+136(a0)
66− EX sdc1 $f19, SC_FPREGS+152(a0)
67− EX sdc1 $f21, SC_FPREGS+168(a0)
68− EX sdc1 $f23, SC_FPREGS+184(a0)
69− EX sdc1 $f25, SC_FPREGS+200(a0)
70− EX sdc1 $f27, SC_FPREGS+216(a0)
71− EX sdc1 $f29, SC_FPREGS+232(a0)
72− EX sdc1 $f31, SC_FPREGS+248(a0)
66+ EX sdc1 $f1, 8(a0)
67+ EX sdc1 $f3, 24(a0)
68+ EX sdc1 $f5, 40(a0)
69+ EX sdc1 $f7, 56(a0)
70+ EX sdc1 $f9, 72(a0)
71+ EX sdc1 $f11, 88(a0)
72+ EX sdc1 $f13, 104(a0)
73+ EX sdc1 $f15, 120(a0)
74+ EX sdc1 $f17, 136(a0)
75+ EX sdc1 $f19, 152(a0)
76+ EX sdc1 $f21, 168(a0)
77+ EX sdc1 $f23, 184(a0)
78+ EX sdc1 $f25, 200(a0)
79+ EX sdc1 $f27, 216(a0)
80+ EX sdc1 $f29, 232(a0)
81+ EX sdc1 $f31, 248(a0)
7382 1: .set pop
7483 #endif
7584
7685 .set push
7786 SET_HARDFLOAT
7887 /* Store the 16 even double precision registers */
79− EX sdc1 $f0, SC_FPREGS+0(a0)
80− EX sdc1 $f2, SC_FPREGS+16(a0)
81− EX sdc1 $f4, SC_FPREGS+32(a0)
82− EX sdc1 $f6, SC_FPREGS+48(a0)
83− EX sdc1 $f8, SC_FPREGS+64(a0)
84− EX sdc1 $f10, SC_FPREGS+80(a0)
85− EX sdc1 $f12, SC_FPREGS+96(a0)
86− EX sdc1 $f14, SC_FPREGS+112(a0)
87− EX sdc1 $f16, SC_FPREGS+128(a0)
88− EX sdc1 $f18, SC_FPREGS+144(a0)
89− EX sdc1 $f20, SC_FPREGS+160(a0)
90− EX sdc1 $f22, SC_FPREGS+176(a0)
91− EX sdc1 $f24, SC_FPREGS+192(a0)
92− EX sdc1 $f26, SC_FPREGS+208(a0)
93− EX sdc1 $f28, SC_FPREGS+224(a0)
94− EX sdc1 $f30, SC_FPREGS+240(a0)
95− EX sw t1, SC_FPC_CSR(a0)
88+ EX sdc1 $f0, 0(a0)
89+ EX sdc1 $f2, 16(a0)
90+ EX sdc1 $f4, 32(a0)
91+ EX sdc1 $f6, 48(a0)
92+ EX sdc1 $f8, 64(a0)
93+ EX sdc1 $f10, 80(a0)
94+ EX sdc1 $f12, 96(a0)
95+ EX sdc1 $f14, 112(a0)
96+ EX sdc1 $f16, 128(a0)
97+ EX sdc1 $f18, 144(a0)
98+ EX sdc1 $f20, 160(a0)
99+ EX sdc1 $f22, 176(a0)
100+ EX sdc1 $f24, 192(a0)
101+ EX sdc1 $f26, 208(a0)
102+ EX sdc1 $f28, 224(a0)
103+ EX sdc1 $f30, 240(a0)
104+ EX sw t1, 0(a1)
96105 jr ra
97106 li v0, 0 # success
98107 .set pop
99108 END(_save_fp_context)
100109
101−#ifdef CONFIG_MIPS32_COMPAT
102− /* Save 32-bit process floating point context */
103−LEAF(_save_fp_context32)
104− .set push
105− .set MIPS_ISA_ARCH_LEVEL_RAW
106− SET_HARDFLOAT
107− cfc1 t1, fcr31
108−
109−#ifndef CONFIG_CPU_MIPS64_R6
110− mfc0 t0, CP0_STATUS
111− sll t0, t0, 5
112− bgez t0, 1f # skip storing odd if FR=0
113− nop
114−#endif
115−
116− /* Store the 16 odd double precision registers */
117− EX sdc1 $f1, SC32_FPREGS+8(a0)
118− EX sdc1 $f3, SC32_FPREGS+24(a0)
119− EX sdc1 $f5, SC32_FPREGS+40(a0)
120− EX sdc1 $f7, SC32_FPREGS+56(a0)
121− EX sdc1 $f9, SC32_FPREGS+72(a0)
122− EX sdc1 $f11, SC32_FPREGS+88(a0)
123− EX sdc1 $f13, SC32_FPREGS+104(a0)
124− EX sdc1 $f15, SC32_FPREGS+120(a0)
125− EX sdc1 $f17, SC32_FPREGS+136(a0)
126− EX sdc1 $f19, SC32_FPREGS+152(a0)
127− EX sdc1 $f21, SC32_FPREGS+168(a0)
128− EX sdc1 $f23, SC32_FPREGS+184(a0)
129− EX sdc1 $f25, SC32_FPREGS+200(a0)
130− EX sdc1 $f27, SC32_FPREGS+216(a0)
131− EX sdc1 $f29, SC32_FPREGS+232(a0)
132− EX sdc1 $f31, SC32_FPREGS+248(a0)
133−
134− /* Store the 16 even double precision registers */
135−1: EX sdc1 $f0, SC32_FPREGS+0(a0)
136− EX sdc1 $f2, SC32_FPREGS+16(a0)
137− EX sdc1 $f4, SC32_FPREGS+32(a0)
138− EX sdc1 $f6, SC32_FPREGS+48(a0)
139− EX sdc1 $f8, SC32_FPREGS+64(a0)
140− EX sdc1 $f10, SC32_FPREGS+80(a0)
141− EX sdc1 $f12, SC32_FPREGS+96(a0)
142− EX sdc1 $f14, SC32_FPREGS+112(a0)
143− EX sdc1 $f16, SC32_FPREGS+128(a0)
144− EX sdc1 $f18, SC32_FPREGS+144(a0)
145− EX sdc1 $f20, SC32_FPREGS+160(a0)
146− EX sdc1 $f22, SC32_FPREGS+176(a0)
147− EX sdc1 $f24, SC32_FPREGS+192(a0)
148− EX sdc1 $f26, SC32_FPREGS+208(a0)
149− EX sdc1 $f28, SC32_FPREGS+224(a0)
150− EX sdc1 $f30, SC32_FPREGS+240(a0)
151− EX sw t1, SC32_FPC_CSR(a0)
152− cfc1 t0, $0 # implementation/version
153− EX sw t0, SC32_FPC_EIR(a0)
154− .set pop
155−
156− jr ra
157− li v0, 0 # success
158− END(_save_fp_context32)
159−#endif
160−
161−/*
162− * Restore FPU state:
163− * - fp gp registers
164− * - cp1 status/control register
110+/**
111+ * _restore_fp_context() - restore FP context to the FPU
112+ * @a0 - pointer to fpregs field of sigcontext
113+ * @a1 - pointer to fpc_csr field of sigcontext
114+ *
115+ * Restore FP context, including the 32 FP data registers and the FP
116+ * control & status register, from signal context to the FPU.
165117 */
166118 LEAF(_restore_fp_context)
167− EX lw t1, SC_FPC_CSR(a0)
119+ EX lw t1, 0(a1)
168120
169121 #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
170122 defined(CONFIG_CPU_MIPS32_R6)
@@ -178,101 +130,231 @@ LEAF(_restore_fp_context) · 7 unmodified lines
178130 bgez t0, 1f # skip loading odd if FR=0
179131 nop
180132 #endif
181− EX ldc1 $f1, SC_FPREGS+8(a0)
182− EX ldc1 $f3, SC_FPREGS+24(a0)
183− EX ldc1 $f5, SC_FPREGS+40(a0)
184− EX ldc1 $f7, SC_FPREGS+56(a0)
185− EX ldc1 $f9, SC_FPREGS+72(a0)
186− EX ldc1 $f11, SC_FPREGS+88(a0)
187− EX ldc1 $f13, SC_FPREGS+104(a0)
188− EX ldc1 $f15, SC_FPREGS+120(a0)
189− EX ldc1 $f17, SC_FPREGS+136(a0)
190− EX ldc1 $f19, SC_FPREGS+152(a0)
191− EX ldc1 $f21, SC_FPREGS+168(a0)
192− EX ldc1 $f23, SC_FPREGS+184(a0)
193− EX ldc1 $f25, SC_FPREGS+200(a0)
194− EX ldc1 $f27, SC_FPREGS+216(a0)
195− EX ldc1 $f29, SC_FPREGS+232(a0)
196− EX ldc1 $f31, SC_FPREGS+248(a0)
133+ EX ldc1 $f1, 8(a0)
134+ EX ldc1 $f3, 24(a0)
135+ EX ldc1 $f5, 40(a0)
136+ EX ldc1 $f7, 56(a0)
137+ EX ldc1 $f9, 72(a0)
138+ EX ldc1 $f11, 88(a0)
139+ EX ldc1 $f13, 104(a0)
140+ EX ldc1 $f15, 120(a0)
141+ EX ldc1 $f17, 136(a0)
142+ EX ldc1 $f19, 152(a0)
143+ EX ldc1 $f21, 168(a0)
144+ EX ldc1 $f23, 184(a0)
145+ EX ldc1 $f25, 200(a0)
146+ EX ldc1 $f27, 216(a0)
147+ EX ldc1 $f29, 232(a0)
148+ EX ldc1 $f31, 248(a0)
197149 1: .set pop
198150 #endif
199151 .set push
200152 SET_HARDFLOAT
201− EX ldc1 $f0, SC_FPREGS+0(a0)
202− EX ldc1 $f2, SC_FPREGS+16(a0)
203− EX ldc1 $f4, SC_FPREGS+32(a0)
204− EX ldc1 $f6, SC_FPREGS+48(a0)
205− EX ldc1 $f8, SC_FPREGS+64(a0)
206− EX ldc1 $f10, SC_FPREGS+80(a0)
207− EX ldc1 $f12, SC_FPREGS+96(a0)
208− EX ldc1 $f14, SC_FPREGS+112(a0)
209− EX ldc1 $f16, SC_FPREGS+128(a0)
210− EX ldc1 $f18, SC_FPREGS+144(a0)
211− EX ldc1 $f20, SC_FPREGS+160(a0)
212− EX ldc1 $f22, SC_FPREGS+176(a0)
213− EX ldc1 $f24, SC_FPREGS+192(a0)
214− EX ldc1 $f26, SC_FPREGS+208(a0)
215− EX ldc1 $f28, SC_FPREGS+224(a0)
216− EX ldc1 $f30, SC_FPREGS+240(a0)
153+ EX ldc1 $f0, 0(a0)
154+ EX ldc1 $f2, 16(a0)
155+ EX ldc1 $f4, 32(a0)
156+ EX ldc1 $f6, 48(a0)
157+ EX ldc1 $f8, 64(a0)
158+ EX ldc1 $f10, 80(a0)
159+ EX ldc1 $f12, 96(a0)
160+ EX ldc1 $f14, 112(a0)
161+ EX ldc1 $f16, 128(a0)
162+ EX ldc1 $f18, 144(a0)
163+ EX ldc1 $f20, 160(a0)
164+ EX ldc1 $f22, 176(a0)
165+ EX ldc1 $f24, 192(a0)
166+ EX ldc1 $f26, 208(a0)
167+ EX ldc1 $f28, 224(a0)
168+ EX ldc1 $f30, 240(a0)
217169 ctc1 t1, fcr31
218170 .set pop
219171 jr ra
220172 li v0, 0 # success
221173 END(_restore_fp_context)
222174
223−#ifdef CONFIG_MIPS32_COMPAT
224−LEAF(_restore_fp_context32)
225− /* Restore an o32 sigcontext. */
226− .set push
227− SET_HARDFLOAT
228− EX lw t1, SC32_FPC_CSR(a0)
175+#ifdef CONFIG_CPU_HAS_MSA
229176
230−#ifndef CONFIG_CPU_MIPS64_R6
231− mfc0 t0, CP0_STATUS
232− sll t0, t0, 5
233− bgez t0, 1f # skip loading odd if FR=0
177+ .macro op_one_wr op, idx, base
178+ .align 4
179+\idx: \op \idx, 0, \base
180+ jr ra
234181 nop
235−#endif
182+ .endm
236183
237− EX ldc1 $f1, SC32_FPREGS+8(a0)
238− EX ldc1 $f3, SC32_FPREGS+24(a0)
239− EX ldc1 $f5, SC32_FPREGS+40(a0)
240− EX ldc1 $f7, SC32_FPREGS+56(a0)
241− EX ldc1 $f9, SC32_FPREGS+72(a0)
242− EX ldc1 $f11, SC32_FPREGS+88(a0)
243− EX ldc1 $f13, SC32_FPREGS+104(a0)
244− EX ldc1 $f15, SC32_FPREGS+120(a0)
245− EX ldc1 $f17, SC32_FPREGS+136(a0)
246− EX ldc1 $f19, SC32_FPREGS+152(a0)
247− EX ldc1 $f21, SC32_FPREGS+168(a0)
248− EX ldc1 $f23, SC32_FPREGS+184(a0)
249− EX ldc1 $f25, SC32_FPREGS+200(a0)
250− EX ldc1 $f27, SC32_FPREGS+216(a0)
251− EX ldc1 $f29, SC32_FPREGS+232(a0)
252− EX ldc1 $f31, SC32_FPREGS+248(a0)
184+ .macro op_msa_wr name, op
185+LEAF(\name)
186+ .set push
187+ .set noreorder
188+ sll t0, a0, 4
189+ PTR_LA t1, 0f
190+ PTR_ADDU t0, t0, t1
191+ jr t0
192+ nop
193+ op_one_wr \op, 0, a1
194+ op_one_wr \op, 1, a1
195+ op_one_wr \op, 2, a1
196+ op_one_wr \op, 3, a1
197+ op_one_wr \op, 4, a1
198+ op_one_wr \op, 5, a1
199+ op_one_wr \op, 6, a1
200+ op_one_wr \op, 7, a1
201+ op_one_wr \op, 8, a1
202+ op_one_wr \op, 9, a1
203+ op_one_wr \op, 10, a1
204+ op_one_wr \op, 11, a1
205+ op_one_wr \op, 12, a1
206+ op_one_wr \op, 13, a1
207+ op_one_wr \op, 14, a1
208+ op_one_wr \op, 15, a1
209+ op_one_wr \op, 16, a1
210+ op_one_wr \op, 17, a1
211+ op_one_wr \op, 18, a1
212+ op_one_wr \op, 19, a1
213+ op_one_wr \op, 20, a1
214+ op_one_wr \op, 21, a1
215+ op_one_wr \op, 22, a1
216+ op_one_wr \op, 23, a1
217+ op_one_wr \op, 24, a1
218+ op_one_wr \op, 25, a1
219+ op_one_wr \op, 26, a1
220+ op_one_wr \op, 27, a1
221+ op_one_wr \op, 28, a1
222+ op_one_wr \op, 29, a1
223+ op_one_wr \op, 30, a1
224+ op_one_wr \op, 31, a1
225+ .set pop
226+ END(\name)
227+ .endm
253228
254−1: EX ldc1 $f0, SC32_FPREGS+0(a0)
255− EX ldc1 $f2, SC32_FPREGS+16(a0)
256− EX ldc1 $f4, SC32_FPREGS+32(a0)
257− EX ldc1 $f6, SC32_FPREGS+48(a0)
258− EX ldc1 $f8, SC32_FPREGS+64(a0)
259− EX ldc1 $f10, SC32_FPREGS+80(a0)
260− EX ldc1 $f12, SC32_FPREGS+96(a0)
261− EX ldc1 $f14, SC32_FPREGS+112(a0)
262− EX ldc1 $f16, SC32_FPREGS+128(a0)
263− EX ldc1 $f18, SC32_FPREGS+144(a0)
264− EX ldc1 $f20, SC32_FPREGS+160(a0)
265− EX ldc1 $f22, SC32_FPREGS+176(a0)
266− EX ldc1 $f24, SC32_FPREGS+192(a0)
267− EX ldc1 $f26, SC32_FPREGS+208(a0)
268− EX ldc1 $f28, SC32_FPREGS+224(a0)
269− EX ldc1 $f30, SC32_FPREGS+240(a0)
270− ctc1 t1, fcr31
229+ op_msa_wr read_msa_wr_b, st_b
230+ op_msa_wr read_msa_wr_h, st_h
231+ op_msa_wr read_msa_wr_w, st_w
232+ op_msa_wr read_msa_wr_d, st_d
233+
234+ op_msa_wr write_msa_wr_b, ld_b
235+ op_msa_wr write_msa_wr_h, ld_h
236+ op_msa_wr write_msa_wr_w, ld_w
237+ op_msa_wr write_msa_wr_d, ld_d
238+
239+#endif /* CONFIG_CPU_HAS_MSA */
240+
241+#ifdef CONFIG_CPU_HAS_MSA
242+
243+ .macro save_msa_upper wr, off, base
244+ .set push
245+ .set noat
246+#ifdef CONFIG_64BIT
247+ copy_u_d \wr, 1
248+ EX sd $1, \off(\base)
249+#elif defined(CONFIG_CPU_LITTLE_ENDIAN)
250+ copy_u_w \wr, 2
251+ EX sw $1, \off(\base)
252+ copy_u_w \wr, 3
253+ EX sw $1, (\off+4)(\base)
254+#else /* CONFIG_CPU_BIG_ENDIAN */
255+ copy_u_w \wr, 2
256+ EX sw $1, (\off+4)(\base)
257+ copy_u_w \wr, 3
258+ EX sw $1, \off(\base)
259+#endif
260+ .set pop
261+ .endm
262+
263+LEAF(_save_msa_all_upper)
264+ save_msa_upper 0, 0x00, a0
265+ save_msa_upper 1, 0x08, a0
266+ save_msa_upper 2, 0x10, a0
267+ save_msa_upper 3, 0x18, a0
268+ save_msa_upper 4, 0x20, a0
269+ save_msa_upper 5, 0x28, a0
270+ save_msa_upper 6, 0x30, a0
271+ save_msa_upper 7, 0x38, a0
272+ save_msa_upper 8, 0x40, a0
273+ save_msa_upper 9, 0x48, a0
274+ save_msa_upper 10, 0x50, a0
275+ save_msa_upper 11, 0x58, a0
276+ save_msa_upper 12, 0x60, a0
277+ save_msa_upper 13, 0x68, a0
278+ save_msa_upper 14, 0x70, a0
279+ save_msa_upper 15, 0x78, a0
280+ save_msa_upper 16, 0x80, a0
281+ save_msa_upper 17, 0x88, a0
282+ save_msa_upper 18, 0x90, a0
283+ save_msa_upper 19, 0x98, a0
284+ save_msa_upper 20, 0xa0, a0
285+ save_msa_upper 21, 0xa8, a0
286+ save_msa_upper 22, 0xb0, a0
287+ save_msa_upper 23, 0xb8, a0
288+ save_msa_upper 24, 0xc0, a0
289+ save_msa_upper 25, 0xc8, a0
290+ save_msa_upper 26, 0xd0, a0
291+ save_msa_upper 27, 0xd8, a0
292+ save_msa_upper 28, 0xe0, a0
293+ save_msa_upper 29, 0xe8, a0
294+ save_msa_upper 30, 0xf0, a0
295+ save_msa_upper 31, 0xf8, a0
271296 jr ra
272− li v0, 0 # success
273− .set pop
274− END(_restore_fp_context32)
297+ li v0, 0
298+ END(_save_msa_all_upper)
299+
300+ .macro restore_msa_upper wr, off, base
301+ .set push
302+ .set noat
303+#ifdef CONFIG_64BIT
304+ EX ld $1, \off(\base)
305+ insert_d \wr, 1
306+#elif defined(CONFIG_CPU_LITTLE_ENDIAN)
307+ EX lw $1, \off(\base)
308+ insert_w \wr, 2
309+ EX lw $1, (\off+4)(\base)
310+ insert_w \wr, 3
311+#else /* CONFIG_CPU_BIG_ENDIAN */
312+ EX lw $1, (\off+4)(\base)
313+ insert_w \wr, 2
314+ EX lw $1, \off(\base)
315+ insert_w \wr, 3
275316 #endif
317+ .set pop
318+ .endm
319+
320+LEAF(_restore_msa_all_upper)
321+ restore_msa_upper 0, 0x00, a0
322+ restore_msa_upper 1, 0x08, a0
323+ restore_msa_upper 2, 0x10, a0
324+ restore_msa_upper 3, 0x18, a0
325+ restore_msa_upper 4, 0x20, a0
326+ restore_msa_upper 5, 0x28, a0
327+ restore_msa_upper 6, 0x30, a0
328+ restore_msa_upper 7, 0x38, a0
329+ restore_msa_upper 8, 0x40, a0
330+ restore_msa_upper 9, 0x48, a0
331+ restore_msa_upper 10, 0x50, a0
332+ restore_msa_upper 11, 0x58, a0
333+ restore_msa_upper 12, 0x60, a0
334+ restore_msa_upper 13, 0x68, a0
335+ restore_msa_upper 14, 0x70, a0
336+ restore_msa_upper 15, 0x78, a0
337+ restore_msa_upper 16, 0x80, a0
338+ restore_msa_upper 17, 0x88, a0
339+ restore_msa_upper 18, 0x90, a0
340+ restore_msa_upper 19, 0x98, a0
341+ restore_msa_upper 20, 0xa0, a0
342+ restore_msa_upper 21, 0xa8, a0
343+ restore_msa_upper 22, 0xb0, a0
344+ restore_msa_upper 23, 0xb8, a0
345+ restore_msa_upper 24, 0xc0, a0
346+ restore_msa_upper 25, 0xc8, a0
347+ restore_msa_upper 26, 0xd0, a0
348+ restore_msa_upper 27, 0xd8, a0
349+ restore_msa_upper 28, 0xe0, a0
350+ restore_msa_upper 29, 0xe8, a0
351+ restore_msa_upper 30, 0xf0, a0
352+ restore_msa_upper 31, 0xf8, a0
353+ jr ra
354+ li v0, 0
355+ END(_restore_msa_all_upper)
356+
357+#endif /* CONFIG_CPU_HAS_MSA */
276358
277359 .set reorder
278360
arch/mips/kernel/r4k_switch.S+1−40
@@ -34,7 +34,7 @@ · 33 unmodified lines
3434 #ifndef USE_ALTERNATE_RESUME_IMPL
3535 /*
3636 * task_struct *resume(task_struct *prev, task_struct *next,
37− * struct thread_info *next_ti, s32 fp_save)
37+ * struct thread_info *next_ti)
3838 */
3939 .align 5
4040 LEAF(resume)
@@ -43,45 +43,6 @@ · 2 unmodified lines
4343 cpu_save_nonscratch a0
4444 LONG_S ra, THREAD_REG31(a0)
4545
46− /*
47− * Check whether we need to save any FP context. FP context is saved
48− * iff the process has used the context with the scalar FPU or the MSA
49− * ASE in the current time slice, as indicated by _TIF_USEDFPU and
50− * _TIF_USEDMSA respectively. switch_to will have set fp_save
51− * accordingly to an FP_SAVE_ enum value.
52− */
53− beqz a3, 2f
54−
55− /*
56− * We do. Clear the saved CU1 bit for prev, such that next time it is
57− * scheduled it will start in userland with the FPU disabled. If the
58− * task uses the FPU then it will be enabled again via the do_cpu trap.
59− * This allows us to lazily restore the FP context.
60− */
61− PTR_L t3, TASK_THREAD_INFO(a0)
62− LONG_L t0, ST_OFF(t3)
63− li t1, ~ST0_CU1
64− and t0, t0, t1
65− LONG_S t0, ST_OFF(t3)
66−
67− /* Check whether we're saving scalar or vector context. */
68− bgtz a3, 1f
69−
70− /* Save 128b MSA vector context + scalar FP control & status. */
71− .set push
72− SET_HARDFLOAT
73− cfc1 t1, fcr31
74− msa_save_all a0
75− .set pop /* SET_HARDFLOAT */
76−
77− sw t1, THREAD_FCR31(a0)
78− b 2f
79−
80−1: /* Save 32b/64b scalar FP context. */
81− fpu_save_double a0 t0 t1 # c0_status passed in t0
82− # clobbers t1
83−2:
84−
8546 #if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
8647 PTR_LA t8, __stack_chk_guard
8748 LONG_L t9, TASK_STACK_CANARY(a1)
arch/mips/kernel/signal-common.h+9−0
@@ -31,4 +31,13 @@ extern int fpcsr_pending(unsigned int __user *fpcsr); · 30 unmodified lines
3131 #define lock_fpu_owner() ({ preempt_disable(); pagefault_disable(); })
3232 #define unlock_fpu_owner() ({ pagefault_enable(); preempt_enable(); })
3333
34+/* Assembly functions to move context to/from the FPU */
35+extern asmlinkage int
36+_save_fp_context(void __user *fpregs, void __user *csr);
37+extern asmlinkage int
38+_restore_fp_context(void __user *fpregs, void __user *csr);
39+
40+extern asmlinkage int _save_msa_all_upper(void __user *buf);
41+extern asmlinkage int _restore_msa_all_upper(void __user *buf);
42+
3443 #endif /* __SIGNAL_COMMON_H */
arch/mips/kernel/signal.c+340−93
@@ -21,6 +21,7 @@ · 20 unmodified lines
2121 #include <linux/wait.h>
2222 #include <linux/ptrace.h>
2323 #include <linux/unistd.h>
24+#include <linux/uprobes.h>
2425 #include <linux/compiler.h>
2526 #include <linux/syscalls.h>
2627 #include <linux/uaccess.h>
@@ -38,20 +39,21 @@ · 11 unmodified lines
3839 #include <asm/vdso.h>
3940 #include <asm/dsp.h>
4041 #include <asm/inst.h>
42+#include <asm/msa.h>
4143
4244 #include "signal-common.h"
4345
44−static int (*save_fp_context)(struct sigcontext __user *sc);
45−static int (*restore_fp_context)(struct sigcontext __user *sc);
46−
47−extern asmlinkage int _save_fp_context(struct sigcontext __user *sc);
48−extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc);
46+static int (*save_fp_context)(void __user *sc);
47+static int (*restore_fp_context)(void __user *sc);
4948
5049 struct sigframe {
5150 u32 sf_ass[4]; /* argument save space for o32 */
5251 u32 sf_pad[2]; /* Was: signal trampoline */
52+
53+ /* Matches struct ucontext from its uc_mcontext field onwards */
5354 struct sigcontext sf_sc;
5455 sigset_t sf_mask;
56+ unsigned long long sf_extcontext[0];
5557 };
5658
5759 struct rt_sigframe {
@@ -65,43 +67,255 @@ struct rt_sigframe { · 7 unmodified lines
6567 * Thread saved context copy to/from a signal context presumed to be on the
6668 * user stack, and therefore accessed with appropriate macros from uaccess.h.
6769 */
68−static int copy_fp_to_sigcontext(struct sigcontext __user *sc)
70+static int copy_fp_to_sigcontext(void __user *sc)
6971 {
72+ struct mips_abi *abi = current->thread.abi;
73+ uint64_t __user *fpregs = sc + abi->off_sc_fpregs;
74+ uint32_t __user *csr = sc + abi->off_sc_fpc_csr;
7075 int i;
7176 int err = 0;
77+ int inc = test_thread_flag(TIF_32BIT_FPREGS) ? 2 : 1;
7278
73− for (i = 0; i < NUM_FPU_REGS; i++) {
79+ for (i = 0; i < NUM_FPU_REGS; i += inc) {
7480 err |=
7581 __put_user(get_fpr64(&current->thread.fpu.fpr[i], 0),
76− &sc->sc_fpregs[i]);
82+ &fpregs[i]);
7783 }
78− err |= __put_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
84+ err |= __put_user(current->thread.fpu.fcr31, csr);
7985
8086 return err;
8187 }
8288
83−static int copy_fp_from_sigcontext(struct sigcontext __user *sc)
89+static int copy_fp_from_sigcontext(void __user *sc)
8490 {
91+ struct mips_abi *abi = current->thread.abi;
92+ uint64_t __user *fpregs = sc + abi->off_sc_fpregs;
93+ uint32_t __user *csr = sc + abi->off_sc_fpc_csr;
8594 int i;
8695 int err = 0;
96+ int inc = test_thread_flag(TIF_32BIT_FPREGS) ? 2 : 1;
8797 u64 fpr_val;
8898
89− for (i = 0; i < NUM_FPU_REGS; i++) {
90− err |= __get_user(fpr_val, &sc->sc_fpregs[i]);
99+ for (i = 0; i < NUM_FPU_REGS; i += inc) {
100+ err |= __get_user(fpr_val, &fpregs[i]);
91101 set_fpr64(&current->thread.fpu.fpr[i], 0, fpr_val);
92102 }
93− err |= __get_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
103+ err |= __get_user(current->thread.fpu.fcr31, csr);
94104
95105 return err;
96106 }
97107
108+/*
109+ * Wrappers for the assembly _{save,restore}_fp_context functions.
110+ */
111+static int save_hw_fp_context(void __user *sc)
112+{
113+ struct mips_abi *abi = current->thread.abi;
114+ uint64_t __user *fpregs = sc + abi->off_sc_fpregs;
115+ uint32_t __user *csr = sc + abi->off_sc_fpc_csr;
116+
117+ return _save_fp_context(fpregs, csr);
118+}
119+
120+static int restore_hw_fp_context(void __user *sc)
121+{
122+ struct mips_abi *abi = current->thread.abi;
123+ uint64_t __user *fpregs = sc + abi->off_sc_fpregs;
124+ uint32_t __user *csr = sc + abi->off_sc_fpc_csr;
125+
126+ return _restore_fp_context(fpregs, csr);
127+}
128+
129+/*
130+ * Extended context handling.
131+ */
132+
133+static inline void __user *sc_to_extcontext(void __user *sc)
134+{
135+ struct ucontext __user *uc;
136+
137+ /*
138+ * We can just pretend the sigcontext is always embedded in a struct
139+ * ucontext here, because the offset from sigcontext to extended
140+ * context is the same in the struct sigframe case.
141+ */
142+ uc = container_of(sc, struct ucontext, uc_mcontext);
143+ return &uc->uc_extcontext;
144+}
145+
146+static int save_msa_extcontext(void __user *buf)
147+{
148+ struct msa_extcontext __user *msa = buf;
149+ uint64_t val;
150+ int i, err;
151+
152+ if (!thread_msa_context_live())
153+ return 0;
154+
155+ /*
156+ * Ensure that we can't lose the live MSA context between checking
157+ * for it & writing it to memory.
158+ */
159+ preempt_disable();
160+
161+ if (is_msa_enabled()) {
162+ /*
163+ * There are no EVA versions of the vector register load/store
164+ * instructions, so MSA context has to be saved to kernel memory
165+ * and then copied to user memory. The save to kernel memory
166+ * should already have been done when handling scalar FP
167+ * context.
168+ */
169+ BUG_ON(config_enabled(CONFIG_EVA));
170+
171+ err = __put_user(read_msa_csr(), &msa->csr);
172+ err |= _save_msa_all_upper(&msa->wr);
173+
174+ preempt_enable();
175+ } else {
176+ preempt_enable();
177+
178+ err = __put_user(current->thread.fpu.msacsr, &msa->csr);
179+
180+ for (i = 0; i < NUM_FPU_REGS; i++) {
181+ val = get_fpr64(&current->thread.fpu.fpr[i], 1);
182+ err |= __put_user(val, &msa->wr[i]);
183+ }
184+ }
185+
186+ err |= __put_user(MSA_EXTCONTEXT_MAGIC, &msa->ext.magic);
187+ err |= __put_user(sizeof(*msa), &msa->ext.size);
188+
189+ return err ? -EFAULT : sizeof(*msa);
190+}
191+
192+static int restore_msa_extcontext(void __user *buf, unsigned int size)
193+{
194+ struct msa_extcontext __user *msa = buf;
195+ unsigned long long val;
196+ unsigned int csr;
197+ int i, err;
198+
199+ if (size != sizeof(*msa))
200+ return -EINVAL;
201+
202+ err = get_user(csr, &msa->csr);
203+ if (err)
204+ return err;
205+
206+ preempt_disable();
207+
208+ if (is_msa_enabled()) {
209+ /*
210+ * There are no EVA versions of the vector register load/store
211+ * instructions, so MSA context has to be copied to kernel
212+ * memory and later loaded to registers. The same is true of
213+ * scalar FP context, so FPU & MSA should have already been
214+ * disabled whilst handling scalar FP context.
215+ */
216+ BUG_ON(config_enabled(CONFIG_EVA));
217+
218+ write_msa_csr(csr);
219+ err |= _restore_msa_all_upper(&msa->wr);
220+ preempt_enable();
221+ } else {
222+ preempt_enable();
223+
224+ current->thread.fpu.msacsr = csr;
225+
226+ for (i = 0; i < NUM_FPU_REGS; i++) {
227+ err |= __get_user(val, &msa->wr[i]);
228+ set_fpr64(&current->thread.fpu.fpr[i], 1, val);
229+ }
230+ }
231+
232+ return err;
233+}
234+
235+static int save_extcontext(void __user *buf)
236+{
237+ int sz;
238+
239+ sz = save_msa_extcontext(buf);
240+ if (sz < 0)
241+ return sz;
242+ buf += sz;
243+
244+ /* If no context was saved then trivially return */
245+ if (!sz)
246+ return 0;
247+
248+ /* Write the end marker */
249+ if (__put_user(END_EXTCONTEXT_MAGIC, (u32 *)buf))
250+ return -EFAULT;
251+
252+ sz += sizeof(((struct extcontext *)NULL)->magic);
253+ return sz;
254+}
255+
256+static int restore_extcontext(void __user *buf)
257+{
258+ struct extcontext ext;
259+ int err;
260+
261+ while (1) {
262+ err = __get_user(ext.magic, (unsigned int *)buf);
263+ if (err)
264+ return err;
265+
266+ if (ext.magic == END_EXTCONTEXT_MAGIC)
267+ return 0;
268+
269+ err = __get_user(ext.size, (unsigned int *)(buf
270+ + offsetof(struct extcontext, size)));
271+ if (err)
272+ return err;
273+
274+ switch (ext.magic) {
275+ case MSA_EXTCONTEXT_MAGIC:
276+ err = restore_msa_extcontext(buf, ext.size);
277+ break;
278+
279+ default:
280+ err = -EINVAL;
281+ break;
282+ }
283+
284+ if (err)
285+ return err;
286+
287+ buf += ext.size;
288+ }
289+}
290+
98291 /*
99292 * Helper routines
100293 */
101−static int protected_save_fp_context(struct sigcontext __user *sc)
294+int protected_save_fp_context(void __user *sc)
102295 {
296+ struct mips_abi *abi = current->thread.abi;
297+ uint64_t __user *fpregs = sc + abi->off_sc_fpregs;
298+ uint32_t __user *csr = sc + abi->off_sc_fpc_csr;
299+ uint32_t __user *used_math = sc + abi->off_sc_used_math;
300+ unsigned int used, ext_sz;
103301 int err;
104−#ifndef CONFIG_EVA
302+
303+ used = used_math() ? USED_FP : 0;
304+ if (!used)
305+ goto fp_done;
306+
307+ if (!test_thread_flag(TIF_32BIT_FPREGS))
308+ used |= USED_FR1;
309+ if (test_thread_flag(TIF_HYBRID_FPREGS))
310+ used |= USED_HYBRID_FPRS;
311+
312+ /*
313+ * EVA does not have userland equivalents of ldc1 or sdc1, so
314+ * save to the kernel FP context & copy that to userland below.
315+ */
316+ if (config_enabled(CONFIG_EVA))
317+ lose_fpu(1);
318+
105319 while (1) {
106320 lock_fpu_owner();
107321 if (is_fpu_owner()) {
@@ -114,27 +328,57 @@ static int protected_save_fp_context(struct sigcontext __user *sc) · 6 unmodified lines
114328 if (likely(!err))
115329 break;
116330 /* touch the sigcontext and try again */
117− err = __put_user(0, &sc->sc_fpregs[0]) |
118− __put_user(0, &sc->sc_fpregs[31]) |
119− __put_user(0, &sc->sc_fpc_csr);
331+ err = __put_user(0, &fpregs[0]) |
332+ __put_user(0, &fpregs[31]) |
333+ __put_user(0, csr);
120334 if (err)
121− break; /* really bad sigcontext */
335+ return err; /* really bad sigcontext */
122336 }
123−#else
124− /*
125− * EVA does not have FPU EVA instructions so saving fpu context directly
126− * does not work.
127− */
128− lose_fpu(1);
129− err = save_fp_context(sc); /* this might fail */
130−#endif
131− return err;
337+
338+fp_done:
339+ ext_sz = err = save_extcontext(sc_to_extcontext(sc));
340+ if (err < 0)
341+ return err;
342+ used |= ext_sz ? USED_EXTCONTEXT : 0;
343+
344+ return __put_user(used, used_math);
132345 }
133346
134−static int protected_restore_fp_context(struct sigcontext __user *sc)
347+int protected_restore_fp_context(void __user *sc)
135348 {
136− int err, tmp __maybe_unused;
137−#ifndef CONFIG_EVA
349+ struct mips_abi *abi = current->thread.abi;
350+ uint64_t __user *fpregs = sc + abi->off_sc_fpregs;
351+ uint32_t __user *csr = sc + abi->off_sc_fpc_csr;
352+ uint32_t __user *used_math = sc + abi->off_sc_used_math;
353+ unsigned int used;
354+ int err, sig = 0, tmp __maybe_unused;
355+
356+ err = __get_user(used, used_math);
357+ conditional_used_math(used & USED_FP);
358+
359+ /*
360+ * The signal handler may have used FPU; give it up if the program
361+ * doesn't want it following sigreturn.
362+ */
363+ if (err || !(used & USED_FP))
364+ lose_fpu(0);
365+ if (err)
366+ return err;
367+ if (!(used & USED_FP))
368+ goto fp_done;
369+
370+ err = sig = fpcsr_pending(csr);
371+ if (err < 0)
372+ return err;
373+
374+ /*
375+ * EVA does not have userland equivalents of ldc1 or sdc1, so we
376+ * disable the FPU here such that the code below simply copies to
377+ * the kernel FP context.
378+ */
379+ if (config_enabled(CONFIG_EVA))
380+ lose_fpu(0);
381+
138382 while (1) {
139383 lock_fpu_owner();
140384 if (is_fpu_owner()) {
@@ -147,28 +391,24 @@ static int protected_restore_fp_context(struct sigcontext __user *sc) · 6 unmodified lines
147391 if (likely(!err))
148392 break;
149393 /* touch the sigcontext and try again */
150− err = __get_user(tmp, &sc->sc_fpregs[0]) |
151− __get_user(tmp, &sc->sc_fpregs[31]) |
152− __get_user(tmp, &sc->sc_fpc_csr);
394+ err = __get_user(tmp, &fpregs[0]) |
395+ __get_user(tmp, &fpregs[31]) |
396+ __get_user(tmp, csr);
153397 if (err)
154398 break; /* really bad sigcontext */
155399 }
156−#else
157− /*
158− * EVA does not have FPU EVA instructions so restoring fpu context
159− * directly does not work.
160− */
161− lose_fpu(0);
162− err = restore_fp_context(sc); /* this might fail */
163−#endif
164− return err;
400+
401+fp_done:
402+ if (used & USED_EXTCONTEXT)
403+ err |= restore_extcontext(sc_to_extcontext(sc));
404+
405+ return err ?: sig;
165406 }
166407
167408 int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
168409 {
169410 int err = 0;
170411 int i;
171− unsigned int used_math;
172412
173413 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
174414
@@ -191,19 +431,38 @@ int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) · 16 unmodified lines
191431 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
192432 }
193433
194− used_math = !!used_math();
195− err |= __put_user(used_math, &sc->sc_used_math);
196434
197− if (used_math) {
198− /*
199− * Save FPU state to signal context. Signal handler
200− * will "inherit" current FPU state.
201− */
202− err |= protected_save_fp_context(sc);
203− }
435+ /*
436+ * Save FPU state to signal context. Signal handler
437+ * will "inherit" current FPU state.
438+ */
439+ err |= protected_save_fp_context(sc);
440+
204441 return err;
205442 }
206443
444+static size_t extcontext_max_size(void)
445+{
446+ size_t sz = 0;
447+
448+ /*
449+ * The assumption here is that between this point & the point at which
450+ * the extended context is saved the size of the context should only
451+ * ever be able to shrink (if the task is preempted), but never grow.
452+ * That is, what this function returns is an upper bound on the size of
453+ * the extended context for the current task at the current time.
454+ */
455+
456+ if (thread_msa_context_live())
457+ sz += sizeof(struct msa_extcontext);
458+
459+ /* If any context is saved then we'll append the end marker */
460+ if (sz)
461+ sz += sizeof(((struct extcontext *)NULL)->magic);
462+
463+ return sz;
464+}
465+
207466 int fpcsr_pending(unsigned int __user *fpcsr)
208467 {
209468 int err, sig = 0;
@@ -223,21 +482,8 @@ int fpcsr_pending(unsigned int __user *fpcsr) · 13 unmodified lines
223482 return err ?: sig;
224483 }
225484
226−static int
227−check_and_restore_fp_context(struct sigcontext __user *sc)
228−{
229− int err, sig;
230−
231− err = sig = fpcsr_pending(&sc->sc_fpc_csr);
232− if (err > 0)
233− err = 0;
234− err |= protected_restore_fp_context(sc);
235− return err ?: sig;
236−}
237−
238485 int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
239486 {
240− unsigned int used_math;
241487 unsigned long treg;
242488 int err = 0;
243489 int i;
@@ -265,19 +511,7 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) · 21 unmodified lines
265511 for (i = 1; i < 32; i++)
266512 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
267513
268− err |= __get_user(used_math, &sc->sc_used_math);
269− conditional_used_math(used_math);
270−
271− if (used_math) {
272− /* restore fpu context if we have used it before */
273− if (!err)
274− err = check_and_restore_fp_context(sc);
275− } else {
276− /* signal handler may have used FPU. Give it up. */
277− lose_fpu(0);
278− }
279−
280− return err;
514+ return err ?: protected_restore_fp_context(sc);
281515 }
282516
283517 void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
@@ -285,6 +519,9 @@ void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, · 1 unmodified line
285519 {
286520 unsigned long sp;
287521
522+ /* Leave space for potential extended context */
523+ frame_size += extcontext_max_size();
524+
288525 /* Default to using normal stack */
289526 sp = regs->regs[29];
290527
@@ -520,7 +757,11 @@ struct mips_abi mips_abi = { · 229 unmodified lines
520757 .setup_rt_frame = setup_rt_frame,
521758 .rt_signal_return_offset =
522759 offsetof(struct mips_vdso, rt_signal_trampoline),
523− .restart = __NR_restart_syscall
760+ .restart = __NR_restart_syscall,
761+
762+ .off_sc_fpregs = offsetof(struct sigcontext, sc_fpregs),
763+ .off_sc_fpc_csr = offsetof(struct sigcontext, sc_fpc_csr),
764+ .off_sc_used_math = offsetof(struct sigcontext, sc_used_math),
524765 };
525766
526767 static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
@@ -616,6 +857,9 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused, · 89 unmodified lines
616857
617858 user_exit();
618859
860+ if (thread_info_flags & _TIF_UPROBE)
861+ uprobe_notify_resume(regs);
862+
619863 /* deal with pending signal delivery */
620864 if (thread_info_flags & _TIF_SIGPENDING)
621865 do_signal(regs);
@@ -629,43 +873,46 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused, · 7 unmodified lines
629873 }
630874
631875 #ifdef CONFIG_SMP
632−#ifndef CONFIG_EVA
633−static int smp_save_fp_context(struct sigcontext __user *sc)
876+static int smp_save_fp_context(void __user *sc)
634877 {
635878 return raw_cpu_has_fpu
636− ? _save_fp_context(sc)
879+ ? save_hw_fp_context(sc)
637880 : copy_fp_to_sigcontext(sc);
638881 }
639882
640−static int smp_restore_fp_context(struct sigcontext __user *sc)
883+static int smp_restore_fp_context(void __user *sc)
641884 {
642885 return raw_cpu_has_fpu
643− ? _restore_fp_context(sc)
886+ ? restore_hw_fp_context(sc)
644887 : copy_fp_from_sigcontext(sc);
645888 }
646−#endif /* CONFIG_EVA */
647889 #endif
648890
649891 static int signal_setup(void)
650892 {
651−#ifndef CONFIG_EVA
893+ /*
894+ * The offset from sigcontext to extended context should be the same
895+ * regardless of the type of signal, such that userland can always know
896+ * where to look if it wishes to find the extended context structures.
897+ */
898+ BUILD_BUG_ON((offsetof(struct sigframe, sf_extcontext) -
899+ offsetof(struct sigframe, sf_sc)) !=
900+ (offsetof(struct rt_sigframe, rs_uc.uc_extcontext) -
901+ offsetof(struct rt_sigframe, rs_uc.uc_mcontext)));
902+
652903 #ifdef CONFIG_SMP
653904 /* For now just do the cpu_has_fpu check when the functions are invoked */
654905 save_fp_context = smp_save_fp_context;
655906 restore_fp_context = smp_restore_fp_context;
656907 #else
657908 if (cpu_has_fpu) {
658− save_fp_context = _save_fp_context;
659− restore_fp_context = _restore_fp_context;
909+ save_fp_context = save_hw_fp_context;
910+ restore_fp_context = restore_hw_fp_context;
660911 } else {
661912 save_fp_context = copy_fp_to_sigcontext;
662913 restore_fp_context = copy_fp_from_sigcontext;
663914 }
664915 #endif /* CONFIG_SMP */
665−#else
666− save_fp_context = copy_fp_to_sigcontext;
667− restore_fp_context = copy_fp_from_sigcontext;
668−#endif
669916
670917 return 0;
671918 }
arch/mips/kernel/signal32.c+11−196
@@ -36,12 +36,6 @@ · 35 unmodified lines
3636
3737 #include "signal-common.h"
3838
39−static int (*save_fp_context32)(struct sigcontext32 __user *sc);
40−static int (*restore_fp_context32)(struct sigcontext32 __user *sc);
41−
42−extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc);
43−extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc);
44−
4539 /*
4640 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
4741 */
@@ -74,99 +68,11 @@ struct rt_sigframe32 { · 26 unmodified lines
7468 struct ucontext32 rs_uc;
7569 };
7670
77−/*
78− * Thread saved context copy to/from a signal context presumed to be on the
79− * user stack, and therefore accessed with appropriate macros from uaccess.h.
80− */
81−static int copy_fp_to_sigcontext32(struct sigcontext32 __user *sc)
82−{
83− int i;
84− int err = 0;
85− int inc = test_thread_flag(TIF_32BIT_FPREGS) ? 2 : 1;
86−
87− for (i = 0; i < NUM_FPU_REGS; i += inc) {
88− err |=
89− __put_user(get_fpr64(&current->thread.fpu.fpr[i], 0),
90− &sc->sc_fpregs[i]);
91− }
92− err |= __put_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
93−
94− return err;
95−}
96−
97−static int copy_fp_from_sigcontext32(struct sigcontext32 __user *sc)
98−{
99− int i;
100− int err = 0;
101− int inc = test_thread_flag(TIF_32BIT_FPREGS) ? 2 : 1;
102− u64 fpr_val;
103−
104− for (i = 0; i < NUM_FPU_REGS; i += inc) {
105− err |= __get_user(fpr_val, &sc->sc_fpregs[i]);
106− set_fpr64(&current->thread.fpu.fpr[i], 0, fpr_val);
107− }
108− err |= __get_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
109−
110− return err;
111−}
112−
113−/*
114− * sigcontext handlers
115− */
116−static int protected_save_fp_context32(struct sigcontext32 __user *sc)
117−{
118− int err;
119− while (1) {
120− lock_fpu_owner();
121− if (is_fpu_owner()) {
122− err = save_fp_context32(sc);
123− unlock_fpu_owner();
124− } else {
125− unlock_fpu_owner();
126− err = copy_fp_to_sigcontext32(sc);
127− }
128− if (likely(!err))
129− break;
130− /* touch the sigcontext and try again */
131− err = __put_user(0, &sc->sc_fpregs[0]) |
132− __put_user(0, &sc->sc_fpregs[31]) |
133− __put_user(0, &sc->sc_fpc_csr);
134− if (err)
135− break; /* really bad sigcontext */
136− }
137− return err;
138−}
139−
140−static int protected_restore_fp_context32(struct sigcontext32 __user *sc)
141−{
142− int err, tmp __maybe_unused;
143− while (1) {
144− lock_fpu_owner();
145− if (is_fpu_owner()) {
146− err = restore_fp_context32(sc);
147− unlock_fpu_owner();
148− } else {
149− unlock_fpu_owner();
150− err = copy_fp_from_sigcontext32(sc);
151− }
152− if (likely(!err))
153− break;
154− /* touch the sigcontext and try again */
155− err = __get_user(tmp, &sc->sc_fpregs[0]) |
156− __get_user(tmp, &sc->sc_fpregs[31]) |
157− __get_user(tmp, &sc->sc_fpc_csr);
158− if (err)
159− break; /* really bad sigcontext */
160− }
161− return err;
162−}
163−
16471 static int setup_sigcontext32(struct pt_regs *regs,
16572 struct sigcontext32 __user *sc)
16673 {
16774 int err = 0;
16875 int i;
169− u32 used_math;
17076
17177 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
17278
@@ -186,35 +92,18 @@ static int setup_sigcontext32(struct pt_regs *regs, · 13 unmodified lines
18692 err |= __put_user(mflo3(), &sc->sc_lo3);
18793 }
18894
189− used_math = !!used_math();
190− err |= __put_user(used_math, &sc->sc_used_math);
95+ /*
96+ * Save FPU state to signal context. Signal handler
97+ * will "inherit" current FPU state.
98+ */
99+ err |= protected_save_fp_context(sc);
191100
192− if (used_math) {
193− /*
194− * Save FPU state to signal context. Signal handler
195− * will "inherit" current FPU state.
196− */
197− err |= protected_save_fp_context32(sc);
198− }
199101 return err;
200102 }
201103
202−static int
203−check_and_restore_fp_context32(struct sigcontext32 __user *sc)
204−{
205− int err, sig;
206−
207− err = sig = fpcsr_pending(&sc->sc_fpc_csr);
208− if (err > 0)
209− err = 0;
210− err |= protected_restore_fp_context32(sc);
211− return err ?: sig;
212−}
213−
214104 static int restore_sigcontext32(struct pt_regs *regs,
215105 struct sigcontext32 __user *sc)
216106 {
217− u32 used_math;
218107 int err = 0;
219108 s32 treg;
220109 int i;
@@ -238,70 +127,7 @@ static int restore_sigcontext32(struct pt_regs *regs, · 17 unmodified lines
238127 for (i = 1; i < 32; i++)
239128 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
240129
241− err |= __get_user(used_math, &sc->sc_used_math);
242− conditional_used_math(used_math);
243−
244− if (used_math) {
245− /* restore fpu context if we have used it before */
246− if (!err)
247− err = check_and_restore_fp_context32(sc);
248− } else {
249− /* signal handler may have used FPU. Give it up. */
250− lose_fpu(0);
251− }
252−
253− return err;
254−}
255−
256−/*
257− *
258− */
259−extern void __put_sigset_unknown_nsig(void);
260−extern void __get_sigset_unknown_nsig(void);
261−
262−static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf)
263−{
264− int err = 0;
265−
266− if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
267− return -EFAULT;
268−
269− switch (_NSIG_WORDS) {
270− default:
271− __put_sigset_unknown_nsig();
272− case 2:
273− err |= __put_user(kbuf->sig[1] >> 32, &ubuf->sig[3]);
274− err |= __put_user(kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
275− case 1:
276− err |= __put_user(kbuf->sig[0] >> 32, &ubuf->sig[1]);
277− err |= __put_user(kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
278− }
279−
280− return err;
281−}
282−
283−static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t __user *ubuf)
284−{
285− int err = 0;
286− unsigned long sig[4];
287−
288− if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
289− return -EFAULT;
290−
291− switch (_NSIG_WORDS) {
292− default:
293− __get_sigset_unknown_nsig();
294− case 2:
295− err |= __get_user(sig[3], &ubuf->sig[3]);
296− err |= __get_user(sig[2], &ubuf->sig[2]);
297− kbuf->sig[1] = sig[2] | (sig[3] << 32);
298− case 1:
299− err |= __get_user(sig[1], &ubuf->sig[1]);
300− err |= __get_user(sig[0], &ubuf->sig[0]);
301− kbuf->sig[0] = sig[0] | (sig[1] << 32);
302− }
303−
304− return err;
130+ return err ?: protected_restore_fp_context(sc);
305131 }
306132
307133 /*
@@ -585,20 +411,9 @@ struct mips_abi mips_abi_32 = { · 277 unmodified lines
585411 .setup_rt_frame = setup_rt_frame_32,
586412 .rt_signal_return_offset =
587413 offsetof(struct mips_vdso, o32_rt_signal_trampoline),
588− .restart = __NR_O32_restart_syscall
589−};
590−
591−static int signal32_init(void)
592−{
593− if (cpu_has_fpu) {
594− save_fp_context32 = _save_fp_context32;
595− restore_fp_context32 = _restore_fp_context32;
596− } else {
597− save_fp_context32 = copy_fp_to_sigcontext32;
598− restore_fp_context32 = copy_fp_from_sigcontext32;
599− }
414+ .restart = __NR_O32_restart_syscall,
600415
601− return 0;
602−}
603−
604−arch_initcall(signal32_init);
416+ .off_sc_fpregs = offsetof(struct sigcontext32, sc_fpregs),
417+ .off_sc_fpc_csr = offsetof(struct sigcontext32, sc_fpc_csr),
418+ .off_sc_used_math = offsetof(struct sigcontext32, sc_used_math),
419+};
arch/mips/kernel/signal_n32.c+5−1
@@ -153,5 +153,9 @@ struct mips_abi mips_abi_n32 = { · 152 unmodified lines
153153 .setup_rt_frame = setup_rt_frame_n32,
154154 .rt_signal_return_offset =
155155 offsetof(struct mips_vdso, n32_rt_signal_trampoline),
156− .restart = __NR_N32_restart_syscall
156+ .restart = __NR_N32_restart_syscall,
157+
158+ .off_sc_fpregs = offsetof(struct sigcontext, sc_fpregs),
159+ .off_sc_fpc_csr = offsetof(struct sigcontext, sc_fpc_csr),
160+ .off_sc_used_math = offsetof(struct sigcontext, sc_used_math),
157161 };
arch/mips/kernel/spram.c+1−0
@@ -209,6 +209,7 @@ void spram_config(void) · 208 unmodified lines
209209 case CPU_PROAPTIV:
210210 case CPU_P5600:
211211 case CPU_QEMU_GENERIC:
212+ case CPU_I6400:
212213 config0 = read_c0_config();
213214 /* FIXME: addresses are Malta specific */
214215 if (config0 & (1<<24)) {
arch/mips/kernel/sysrq.c+1−13
@@ -21,24 +21,12 @@ static DEFINE_SPINLOCK(show_lock); · 20 unmodified lines
2121
2222 static void sysrq_tlbdump_single(void *dummy)
2323 {
24− const int field = 2 * sizeof(unsigned long);
2524 unsigned long flags;
2625
2726 spin_lock_irqsave(&show_lock, flags);
2827
2928 pr_info("CPU%d:\n", smp_processor_id());
30− pr_info("Index : %0x\n", read_c0_index());
31− pr_info("Pagemask: %0x\n", read_c0_pagemask());
32− pr_info("EntryHi : %0*lx\n", field, read_c0_entryhi());
33− pr_info("EntryLo0: %0*lx\n", field, read_c0_entrylo0());
34− pr_info("EntryLo1: %0*lx\n", field, read_c0_entrylo1());
35− pr_info("Wired : %0x\n", read_c0_wired());
36− pr_info("Pagegrain: %0x\n", read_c0_pagegrain());
37− if (cpu_has_htw) {
38− pr_info("PWField : %0*lx\n", field, read_c0_pwfield());
39− pr_info("PWSize : %0*lx\n", field, read_c0_pwsize());
40− pr_info("PWCtl : %0x\n", read_c0_pwctl());
41− }
29+ dump_tlb_regs();
4230 pr_info("\n");
4331 dump_tlb_all();
4432 pr_info("\n");
arch/mips/kernel/traps.c+29−28
@@ -370,11 +370,6 @@ void show_registers(struct pt_regs *regs) · 369 unmodified lines
370370 set_fs(old_fs);
371371 }
372372
373−static int regs_to_trapnr(struct pt_regs *regs)
374−{
375− return (regs->cp0_cause >> 2) & 0x1f;
376−}
377−
378373 static DEFINE_RAW_SPINLOCK(die_lock);
379374
380375 void __noreturn die(const char *str, struct pt_regs *regs)
@@ -384,7 +379,7 @@ void __noreturn die(const char *str, struct pt_regs *regs) · 3 unmodified lines
384379
385380 oops_enter();
386381
387− if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs),
382+ if (notify_die(DIE_OOPS, str, regs, 0, current->thread.trap_nr,
388383 SIGSEGV) == NOTIFY_STOP)
389384 sig = 0;
390385
@@ -470,7 +465,7 @@ asmlinkage void do_be(struct pt_regs *regs) · 79 unmodified lines
470465 printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n",
471466 data ? "Data" : "Instruction",
472467 field, regs->cp0_epc, field, regs->regs[31]);
473− if (notify_die(DIE_OOPS, "bus error", regs, 0, regs_to_trapnr(regs),
468+ if (notify_die(DIE_OOPS, "bus error", regs, 0, current->thread.trap_nr,
474469 SIGBUS) == NOTIFY_STOP)
475470 goto out;
476471
@@ -826,7 +821,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) · 349 unmodified lines
826821 int sig;
827822
828823 prev_state = exception_enter();
829− if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs),
824+ if (notify_die(DIE_FP, "FP exception", regs, 0, current->thread.trap_nr,
830825 SIGFPE) == NOTIFY_STOP)
831826 goto out;
832827
@@ -882,11 +877,12 @@ void do_trap_or_bp(struct pt_regs *regs, unsigned int code, · 49 unmodified lines
882877 char b[40];
883878
884879 #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
885− if (kgdb_ll_trap(DIE_TRAP, str, regs, code, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
880+ if (kgdb_ll_trap(DIE_TRAP, str, regs, code, current->thread.trap_nr,
881+ SIGTRAP) == NOTIFY_STOP)
886882 return;
887883 #endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
888884
889− if (notify_die(DIE_TRAP, str, regs, code, regs_to_trapnr(regs),
885+ if (notify_die(DIE_TRAP, str, regs, code, current->thread.trap_nr,
890886 SIGTRAP) == NOTIFY_STOP)
891887 return;
892888
@@ -948,6 +944,7 @@ asmlinkage void do_bp(struct pt_regs *regs) · 55 unmodified lines
948944 set_fs(KERNEL_DS);
949945
950946 prev_state = exception_enter();
947+ current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
951948 if (get_isa16_mode(regs->cp0_epc)) {
952949 u16 instr[2];
953950
@@ -987,15 +984,27 @@ asmlinkage void do_bp(struct pt_regs *regs) · 33 unmodified lines
987984 * pertain to them.
988985 */
989986 switch (bcode) {
987+ case BRK_UPROBE:
988+ if (notify_die(DIE_UPROBE, "uprobe", regs, bcode,
989+ current->thread.trap_nr, SIGTRAP) == NOTIFY_STOP)
990+ goto out;
991+ else
992+ break;
993+ case BRK_UPROBE_XOL:
994+ if (notify_die(DIE_UPROBE_XOL, "uprobe_xol", regs, bcode,
995+ current->thread.trap_nr, SIGTRAP) == NOTIFY_STOP)
996+ goto out;
997+ else
998+ break;
990999 case BRK_KPROBE_BP:
9911000 if (notify_die(DIE_BREAK, "debug", regs, bcode,
992− regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
1001+ current->thread.trap_nr, SIGTRAP) == NOTIFY_STOP)
9931002 goto out;
9941003 else
9951004 break;
9961005 case BRK_KPROBE_SSTEPBP:
9971006 if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode,
998− regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)
1007+ current->thread.trap_nr, SIGTRAP) == NOTIFY_STOP)
9991008 goto out;
10001009 else
10011010 break;
@@ -1028,6 +1037,7 @@ asmlinkage void do_tr(struct pt_regs *regs) · 26 unmodified lines
10281037 set_fs(get_ds());
10291038
10301039 prev_state = exception_enter();
1040+ current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
10311041 if (get_isa16_mode(regs->cp0_epc)) {
10321042 if (__get_user(instr[0], (u16 __user *)(epc + 0)) ||
10331043 __get_user(instr[1], (u16 __user *)(epc + 2)))
@@ -1094,8 +1104,9 @@ asmlinkage void do_ri(struct pt_regs *regs) · 60 unmodified lines
10941104 no_r2_instr:
10951105
10961106 prev_state = exception_enter();
1107+ current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
10971108
1098− if (notify_die(DIE_RI, "RI Fault", regs, 0, regs_to_trapnr(regs),
1109+ if (notify_die(DIE_RI, "RI Fault", regs, 0, current->thread.trap_nr,
10991110 SIGILL) == NOTIFY_STOP)
11001111 goto out;
11011112
@@ -1444,8 +1455,9 @@ asmlinkage void do_msa_fpe(struct pt_regs *regs, unsigned int msacsr) · 342 unmodified lines
14441455 enum ctx_state prev_state;
14451456
14461457 prev_state = exception_enter();
1458+ current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
14471459 if (notify_die(DIE_MSAFP, "MSA FP exception", regs, 0,
1448− regs_to_trapnr(regs), SIGFPE) == NOTIFY_STOP)
1460+ current->thread.trap_nr, SIGFPE) == NOTIFY_STOP)
14491461 goto out;
14501462
14511463 /* Clear MSACSR.Cause before enabling interrupts */
@@ -1523,7 +1535,6 @@ asmlinkage void do_watch(struct pt_regs *regs) · 71 unmodified lines
15231535
15241536 asmlinkage void do_mcheck(struct pt_regs *regs)
15251537 {
1526− const int field = 2 * sizeof(unsigned long);
15271538 int multi_match = regs->cp0_status & ST0_TS;
15281539 enum ctx_state prev_state;
15291540 mm_segment_t old_fs = get_fs();
@@ -1532,19 +1543,8 @@ asmlinkage void do_mcheck(struct pt_regs *regs) · 2 unmodified lines
15321543 show_regs(regs);
15331544
15341545 if (multi_match) {
1535− pr_err("Index : %0x\n", read_c0_index());
1536− pr_err("Pagemask: %0x\n", read_c0_pagemask());
1537− pr_err("EntryHi : %0*lx\n", field, read_c0_entryhi());
1538− pr_err("EntryLo0: %0*lx\n", field, read_c0_entrylo0());
1539− pr_err("EntryLo1: %0*lx\n", field, read_c0_entrylo1());
1540− pr_err("Wired : %0x\n", read_c0_wired());
1541− pr_err("Pagegrain: %0x\n", read_c0_pagegrain());
1542− if (cpu_has_htw) {
1543− pr_err("PWField : %0*lx\n", field, read_c0_pwfield());
1544− pr_err("PWSize : %0*lx\n", field, read_c0_pwsize());
1545− pr_err("PWCtl : %0x\n", read_c0_pwctl());
1546− }
1547− pr_err("\n");
1546+ dump_tlb_regs();
1547+ pr_info("\n");
15481548 dump_tlb_all();
15491549 }
15501550
@@ -1651,6 +1651,7 @@ static inline void parity_protection_init(void) · 100 unmodified lines
16511651 case CPU_PROAPTIV:
16521652 case CPU_P5600:
16531653 case CPU_QEMU_GENERIC:
1654+ case CPU_I6400:
16541655 {
16551656 #define ERRCTL_PE 0x80000000
16561657 #define ERRCTL_L2P 0x00800000
arch/mips/kernel/unaligned.c+73−1
@@ -891,6 +891,9 @@ static void emulate_load_store_insn(struct pt_regs *regs, · 890 unmodified lines
891891 #ifdef CONFIG_EVA
892892 mm_segment_t seg;
893893 #endif
894+ union fpureg *fpr;
895+ enum msa_2b_fmt df;
896+ unsigned int wd;
894897 origpc = (unsigned long)pc;
895898 orig31 = regs->regs[31];
896899
@@ -1202,6 +1205,75 @@ static void emulate_load_store_insn(struct pt_regs *regs, · 305 unmodified lines
12021205 break;
12031206 return;
12041207
1208+ case msa_op:
1209+ if (!cpu_has_msa)
1210+ goto sigill;
1211+
1212+ /*
1213+ * If we've reached this point then userland should have taken
1214+ * the MSA disabled exception & initialised vector context at
1215+ * some point in the past.
1216+ */
1217+ BUG_ON(!thread_msa_context_live());
1218+
1219+ df = insn.msa_mi10_format.df;
1220+ wd = insn.msa_mi10_format.wd;
1221+ fpr = &current->thread.fpu.fpr[wd];
1222+
1223+ switch (insn.msa_mi10_format.func) {
1224+ case msa_ld_op:
1225+ if (!access_ok(VERIFY_READ, addr, sizeof(*fpr)))
1226+ goto sigbus;
1227+
1228+ /*
1229+ * Disable preemption to avoid a race between copying
1230+ * state from userland, migrating to another CPU and
1231+ * updating the hardware vector register below.
1232+ */
1233+ preempt_disable();
1234+
1235+ res = __copy_from_user_inatomic(fpr, addr,
1236+ sizeof(*fpr));
1237+ if (res)
1238+ goto fault;
1239+
1240+ /*
1241+ * Update the hardware register if it is in use by the
1242+ * task in this quantum, in order to avoid having to
1243+ * save & restore the whole vector context.
1244+ */
1245+ if (test_thread_flag(TIF_USEDMSA))
1246+ write_msa_wr(wd, fpr, df);
1247+
1248+ preempt_enable();
1249+ break;
1250+
1251+ case msa_st_op:
1252+ if (!access_ok(VERIFY_WRITE, addr, sizeof(*fpr)))
1253+ goto sigbus;
1254+
1255+ /*
1256+ * Update from the hardware register if it is in use by
1257+ * the task in this quantum, in order to avoid having to
1258+ * save & restore the whole vector context.
1259+ */
1260+ preempt_disable();
1261+ if (test_thread_flag(TIF_USEDMSA))
1262+ read_msa_wr(wd, fpr, df);
1263+ preempt_enable();
1264+
1265+ res = __copy_to_user_inatomic(addr, fpr, sizeof(*fpr));
1266+ if (res)
1267+ goto fault;
1268+ break;
1269+
1270+ default:
1271+ goto sigbus;
1272+ }
1273+
1274+ compute_return_epc(regs);
1275+ break;
1276+
12051277 #ifndef CONFIG_CPU_MIPSR6
12061278 /*
12071279 * COP2 is available to implementor for application specific use.
@@ -2240,5 +2312,5 @@ static int __init debugfs_unaligned(void) · 1032 unmodified lines
22402312 return -ENOMEM;
22412313 return 0;
22422314 }
2243−__initcall(debugfs_unaligned);
2315+arch_initcall(debugfs_unaligned);
22442316 #endif
arch/mips/kernel/uprobes.c+341−0
@@ -0,0 +1,341 @@
1+#include <linux/highmem.h>
2+#include <linux/kdebug.h>
3+#include <linux/types.h>
4+#include <linux/notifier.h>
5+#include <linux/sched.h>
6+#include <linux/uprobes.h>
7+
8+#include <asm/branch.h>
9+#include <asm/cpu-features.h>
10+#include <asm/ptrace.h>
11+#include <asm/inst.h>
12+
13+static inline int insn_has_delay_slot(const union mips_instruction insn)
14+{
15+ switch (insn.i_format.opcode) {
16+ /*
17+ * jr and jalr are in r_format format.
18+ */
19+ case spec_op:
20+ switch (insn.r_format.func) {
21+ case jalr_op:
22+ case jr_op:
23+ return 1;
24+ }
25+ break;
26+
27+ /*
28+ * This group contains:
29+ * bltz_op, bgez_op, bltzl_op, bgezl_op,
30+ * bltzal_op, bgezal_op, bltzall_op, bgezall_op.
31+ */
32+ case bcond_op:
33+ switch (insn.i_format.rt) {
34+ case bltz_op:
35+ case bltzl_op:
36+ case bgez_op:
37+ case bgezl_op:
38+ case bltzal_op:
39+ case bltzall_op:
40+ case bgezal_op:
41+ case bgezall_op:
42+ case bposge32_op:
43+ return 1;
44+ }
45+ break;
46+
47+ /*
48+ * These are unconditional and in j_format.
49+ */
50+ case jal_op:
51+ case j_op:
52+ case beq_op:
53+ case beql_op:
54+ case bne_op:
55+ case bnel_op:
56+ case blez_op: /* not really i_format */
57+ case blezl_op:
58+ case bgtz_op:
59+ case bgtzl_op:
60+ return 1;
61+
62+ /*
63+ * And now the FPA/cp1 branch instructions.
64+ */
65+ case cop1_op:
66+#ifdef CONFIG_CPU_CAVIUM_OCTEON
67+ case lwc2_op: /* This is bbit0 on Octeon */
68+ case ldc2_op: /* This is bbit032 on Octeon */
69+ case swc2_op: /* This is bbit1 on Octeon */
70+ case sdc2_op: /* This is bbit132 on Octeon */
71+#endif
72+ return 1;
73+ }
74+
75+ return 0;
76+}
77+
78+/**
79+ * arch_uprobe_analyze_insn - instruction analysis including validity and fixups.
80+ * @mm: the probed address space.
81+ * @arch_uprobe: the probepoint information.
82+ * @addr: virtual address at which to install the probepoint
83+ * Return 0 on success or a -ve number on error.
84+ */
85+int arch_uprobe_analyze_insn(struct arch_uprobe *aup,
86+ struct mm_struct *mm, unsigned long addr)
87+{
88+ union mips_instruction inst;
89+
90+ /*
91+ * For the time being this also blocks attempts to use uprobes with
92+ * MIPS16 and microMIPS.
93+ */
94+ if (addr & 0x03)
95+ return -EINVAL;
96+
97+ inst.word = aup->insn[0];
98+ aup->ixol[0] = aup->insn[insn_has_delay_slot(inst)];
99+ aup->ixol[1] = UPROBE_BRK_UPROBE_XOL; /* NOP */
100+
101+ return 0;
102+}
103+
104+/**
105+ * is_trap_insn - check if the instruction is a trap variant
106+ * @insn: instruction to be checked.
107+ * Returns true if @insn is a trap variant.
108+ *
109+ * This definition overrides the weak definition in kernel/events/uprobes.c.
110+ * and is needed for the case where an architecture has multiple trap
111+ * instructions (like PowerPC or MIPS). We treat BREAK just like the more
112+ * modern conditional trap instructions.
113+ */
114+bool is_trap_insn(uprobe_opcode_t *insn)
115+{
116+ union mips_instruction inst;
117+
118+ inst.word = *insn;
119+
120+ switch (inst.i_format.opcode) {
121+ case spec_op:
122+ switch (inst.r_format.func) {
123+ case break_op:
124+ case teq_op:
125+ case tge_op:
126+ case tgeu_op:
127+ case tlt_op:
128+ case tltu_op:
129+ case tne_op:
130+ return 1;
131+ }
132+ break;
133+
134+ case bcond_op: /* Yes, really ... */
135+ switch (inst.u_format.rt) {
136+ case teqi_op:
137+ case tgei_op:
138+ case tgeiu_op:
139+ case tlti_op:
140+ case tltiu_op:
141+ case tnei_op:
142+ return 1;
143+ }
144+ break;
145+ }
146+
147+ return 0;
148+}
149+
150+#define UPROBE_TRAP_NR ULONG_MAX
151+
152+/*
153+ * arch_uprobe_pre_xol - prepare to execute out of line.
154+ * @auprobe: the probepoint information.
155+ * @regs: reflects the saved user state of current task.
156+ */
157+int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs)
158+{
159+ struct uprobe_task *utask = current->utask;
160+ union mips_instruction insn;
161+
162+ /*
163+ * Now find the EPC where to resume after the breakpoint has been
164+ * dealt with. This may require emulation of a branch.
165+ */
166+ aup->resume_epc = regs->cp0_epc + 4;
167+ if (insn_has_delay_slot((union mips_instruction) aup->insn[0])) {
168+ unsigned long epc;
169+
170+ epc = regs->cp0_epc;
171+ __compute_return_epc_for_insn(regs, insn);
172+ aup->resume_epc = regs->cp0_epc;
173+ }
174+
175+ utask->autask.saved_trap_nr = current->thread.trap_nr;
176+ current->thread.trap_nr = UPROBE_TRAP_NR;
177+ regs->cp0_epc = current->utask->xol_vaddr;
178+
179+ return 0;
180+}
181+
182+int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs)
183+{
184+ struct uprobe_task *utask = current->utask;
185+
186+ current->thread.trap_nr = utask->autask.saved_trap_nr;
187+ regs->cp0_epc = aup->resume_epc;
188+
189+ return 0;
190+}
191+
192+/*
193+ * If xol insn itself traps and generates a signal(Say,
194+ * SIGILL/SIGSEGV/etc), then detect the case where a singlestepped
195+ * instruction jumps back to its own address. It is assumed that anything
196+ * like do_page_fault/do_trap/etc sets thread.trap_nr != -1.
197+ *
198+ * arch_uprobe_pre_xol/arch_uprobe_post_xol save/restore thread.trap_nr,
199+ * arch_uprobe_xol_was_trapped() simply checks that ->trap_nr is not equal to
200+ * UPROBE_TRAP_NR == -1 set by arch_uprobe_pre_xol().
201+ */
202+bool arch_uprobe_xol_was_trapped(struct task_struct *tsk)
203+{
204+ if (tsk->thread.trap_nr != UPROBE_TRAP_NR)
205+ return true;
206+
207+ return false;
208+}
209+
210+int arch_uprobe_exception_notify(struct notifier_block *self,
211+ unsigned long val, void *data)
212+{
213+ struct die_args *args = data;
214+ struct pt_regs *regs = args->regs;
215+
216+ /* regs == NULL is a kernel bug */
217+ if (WARN_ON(!regs))
218+ return NOTIFY_DONE;
219+
220+ /* We are only interested in userspace traps */
221+ if (!user_mode(regs))
222+ return NOTIFY_DONE;
223+
224+ switch (val) {
225+ case DIE_BREAK:
226+ if (uprobe_pre_sstep_notifier(regs))
227+ return NOTIFY_STOP;
228+ break;
229+ case DIE_UPROBE_XOL:
230+ if (uprobe_post_sstep_notifier(regs))
231+ return NOTIFY_STOP;
232+ default:
233+ break;
234+ }
235+
236+ return 0;
237+}
238+
239+/*
240+ * This function gets called when XOL instruction either gets trapped or
241+ * the thread has a fatal signal. Reset the instruction pointer to its
242+ * probed address for the potential restart or for post mortem analysis.
243+ */
244+void arch_uprobe_abort_xol(struct arch_uprobe *aup,
245+ struct pt_regs *regs)
246+{
247+ struct uprobe_task *utask = current->utask;
248+
249+ instruction_pointer_set(regs, utask->vaddr);
250+}
251+
252+unsigned long arch_uretprobe_hijack_return_addr(
253+ unsigned long trampoline_vaddr, struct pt_regs *regs)
254+{
255+ unsigned long ra;
256+
257+ ra = regs->regs[31];
258+
259+ /* Replace the return address with the trampoline address */
260+ regs->regs[31] = ra;
261+
262+ return ra;
263+}
264+
265+/**
266+ * set_swbp - store breakpoint at a given address.
267+ * @auprobe: arch specific probepoint information.
268+ * @mm: the probed process address space.
269+ * @vaddr: the virtual address to insert the opcode.
270+ *
271+ * For mm @mm, store the breakpoint instruction at @vaddr.
272+ * Return 0 (success) or a negative errno.
273+ *
274+ * This version overrides the weak version in kernel/events/uprobes.c.
275+ * It is required to handle MIPS16 and microMIPS.
276+ */
277+int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm,
278+ unsigned long vaddr)
279+{
280+ return uprobe_write_opcode(mm, vaddr, UPROBE_SWBP_INSN);
281+}
282+
283+/**
284+ * set_orig_insn - Restore the original instruction.
285+ * @mm: the probed process address space.
286+ * @auprobe: arch specific probepoint information.
287+ * @vaddr: the virtual address to insert the opcode.
288+ *
289+ * For mm @mm, restore the original opcode (opcode) at @vaddr.
290+ * Return 0 (success) or a negative errno.
291+ *
292+ * This overrides the weak version in kernel/events/uprobes.c.
293+ */
294+int set_orig_insn(struct arch_uprobe *auprobe, struct mm_struct *mm,
295+ unsigned long vaddr)
296+{
297+ return uprobe_write_opcode(mm, vaddr,
298+ *(uprobe_opcode_t *)&auprobe->orig_inst[0].word);
299+}
300+
301+void __weak arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,
302+ void *src, unsigned long len)
303+{
304+ void *kaddr;
305+
306+ /* Initialize the slot */
307+ kaddr = kmap_atomic(page);
308+ memcpy(kaddr + (vaddr & ~PAGE_MASK), src, len);
309+ kunmap_atomic(kaddr);
310+
311+ /*
312+ * The MIPS version of flush_icache_range will operate safely on
313+ * user space addresses and more importantly, it doesn't require a
314+ * VMA argument.
315+ */
316+ flush_icache_range(vaddr, vaddr + len);
317+}
318+
319+/**
320+ * uprobe_get_swbp_addr - compute address of swbp given post-swbp regs
321+ * @regs: Reflects the saved state of the task after it has hit a breakpoint
322+ * instruction.
323+ * Return the address of the breakpoint instruction.
324+ *
325+ * This overrides the weak version in kernel/events/uprobes.c.
326+ */
327+unsigned long uprobe_get_swbp_addr(struct pt_regs *regs)
328+{
329+ return instruction_pointer(regs);
330+}
331+
332+/*
333+ * See if the instruction can be emulated.
334+ * Returns true if instruction was emulated, false otherwise.
335+ *
336+ * For now we always emulate so this function just returns 0.
337+ */
338+bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
339+{
340+ return 0;
341+}
arch/mips/kernel/vpe.c+6−1
@@ -817,6 +817,7 @@ static int vpe_open(struct inode *inode, struct file *filp) · 816 unmodified lines
817817
818818 static int vpe_release(struct inode *inode, struct file *filp)
819819 {
820+#if defined(CONFIG_MIPS_VPE_LOADER_MT) || defined(CONFIG_MIPS_VPE_LOADER_CMP)
820821 struct vpe *v;
821822 Elf_Ehdr *hdr;
822823 int ret = 0;
@@ -827,7 +828,7 @@ static int vpe_release(struct inode *inode, struct file *filp) · 4 unmodified lines
827828
828829 hdr = (Elf_Ehdr *) v->pbuffer;
829830 if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) == 0) {
830− if ((vpe_elfload(v) >= 0) && vpe_run) {
831+ if (vpe_elfload(v) >= 0) {
831832 vpe_run(v);
832833 } else {
833834 pr_warn("VPE loader: ELF load failed.\n");
@@ -850,6 +851,10 @@ static int vpe_release(struct inode *inode, struct file *filp) · 16 unmodified lines
850851 v->plen = 0;
851852
852853 return ret;
854+#else
855+ pr_warn("VPE loader: ELF load failed.\n");
856+ return -ENOEXEC;
857+#endif
853858 }
854859
855860 static ssize_t vpe_write(struct file *file, const char __user *buffer,
arch/mips/lasat/sysctl.c+1−1
@@ -270,4 +270,4 @@ static int __init lasat_register_sysctl(void) · 269 unmodified lines
270270 return 0;
271271 }
272272
273−__initcall(lasat_register_sysctl);
273+arch_initcall(lasat_register_sysctl);
arch/mips/lib/dump_tlb.c+36−9
@@ -13,6 +13,33 @@ · 12 unmodified lines
1313 #include <asm/pgtable.h>
1414 #include <asm/tlbdebug.h>
1515
16+void dump_tlb_regs(void)
17+{
18+ const int field = 2 * sizeof(unsigned long);
19+
20+ pr_info("Index : %0x\n", read_c0_index());
21+ pr_info("PageMask : %0x\n", read_c0_pagemask());
22+ pr_info("EntryHi : %0*lx\n", field, read_c0_entryhi());
23+ pr_info("EntryLo0 : %0*lx\n", field, read_c0_entrylo0());
24+ pr_info("EntryLo1 : %0*lx\n", field, read_c0_entrylo1());
25+ pr_info("Wired : %0x\n", read_c0_wired());
26+ switch (current_cpu_type()) {
27+ case CPU_R10000:
28+ case CPU_R12000:
29+ case CPU_R14000:
30+ case CPU_R16000:
31+ pr_info("FrameMask: %0x\n", read_c0_framemask());
32+ break;
33+ }
34+ if (cpu_has_small_pages || cpu_has_rixi || cpu_has_xpa)
35+ pr_info("PageGrain: %0x\n", read_c0_pagegrain());
36+ if (cpu_has_htw) {
37+ pr_info("PWField : %0*lx\n", field, read_c0_pwfield());
38+ pr_info("PWSize : %0*lx\n", field, read_c0_pwsize());
39+ pr_info("PWCtl : %0x\n", read_c0_pwctl());
40+ }
41+}
42+
1643 static inline const char *msk2str(unsigned int mask)
1744 {
1845 switch (mask) {
@@ -87,7 +114,7 @@ static void dump_tlb(int first, int last) · 68 unmodified lines
87114 * leave only a single G bit set after a machine check exception
88115 * due to duplicate TLB entry.
89116 */
90− if (!((entrylo0 | entrylo1) & MIPS_ENTRYLO_G) &&
117+ if (!((entrylo0 | entrylo1) & ENTRYLO_G) &&
91118 (entryhi & 0xff) != asid)
92119 continue;
93120
@@ -96,8 +123,8 @@ static void dump_tlb(int first, int last) · 2 unmodified lines
96123 */
97124 printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
98125
99− c0 = (entrylo0 & MIPS_ENTRYLO_C) >> MIPS_ENTRYLO_C_SHIFT;
100− c1 = (entrylo1 & MIPS_ENTRYLO_C) >> MIPS_ENTRYLO_C_SHIFT;
126+ c0 = (entrylo0 & ENTRYLO_C) >> ENTRYLO_C_SHIFT;
127+ c1 = (entrylo1 & ENTRYLO_C) >> ENTRYLO_C_SHIFT;
101128
102129 printk("va=%0*lx asid=%02lx\n",
103130 vwidth, (entryhi & ~0x1fffUL),
@@ -114,9 +141,9 @@ static void dump_tlb(int first, int last) · 10 unmodified lines
114141 (entrylo0 & MIPS_ENTRYLO_XI) ? 1 : 0);
115142 printk("pa=%0*llx c=%d d=%d v=%d g=%d] [",
116143 pwidth, pa, c0,
117− (entrylo0 & MIPS_ENTRYLO_D) ? 1 : 0,
118− (entrylo0 & MIPS_ENTRYLO_V) ? 1 : 0,
119− (entrylo0 & MIPS_ENTRYLO_G) ? 1 : 0);
144+ (entrylo0 & ENTRYLO_D) ? 1 : 0,
145+ (entrylo0 & ENTRYLO_V) ? 1 : 0,
146+ (entrylo0 & ENTRYLO_G) ? 1 : 0);
120147 /* RI/XI are in awkward places, so mask them off separately */
121148 pa = entrylo1 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI);
122149 if (xpa)
@@ -128,9 +155,9 @@ static void dump_tlb(int first, int last) · 5 unmodified lines
128155 (entrylo1 & MIPS_ENTRYLO_XI) ? 1 : 0);
129156 printk("pa=%0*llx c=%d d=%d v=%d g=%d]\n",
130157 pwidth, pa, c1,
131− (entrylo1 & MIPS_ENTRYLO_D) ? 1 : 0,
132− (entrylo1 & MIPS_ENTRYLO_V) ? 1 : 0,
133− (entrylo1 & MIPS_ENTRYLO_G) ? 1 : 0);
158+ (entrylo1 & ENTRYLO_D) ? 1 : 0,
159+ (entrylo1 & ENTRYLO_V) ? 1 : 0,
160+ (entrylo1 & ENTRYLO_G) ? 1 : 0);
134161 }
135162 printk("\n");
136163
arch/mips/lib/r3k_dump_tlb.c+11−0
@@ -14,6 +14,17 @@ · 13 unmodified lines
1414 #include <asm/pgtable.h>
1515 #include <asm/tlbdebug.h>
1616
17+extern int r3k_have_wired_reg;
18+
19+void dump_tlb_regs(void)
20+{
21+ pr_info("Index : %0x\n", read_c0_index());
22+ pr_info("EntryHi : %0lx\n", read_c0_entryhi());
23+ pr_info("EntryLo : %0lx\n", read_c0_entrylo0());
24+ if (r3k_have_wired_reg)
25+ pr_info("Wired : %0x\n", read_c0_wired());
26+}
27+
1728 static void dump_tlb(int first, int last)
1829 {
1930 int i;
arch/mips/loongson32/common/time.c+34−23
@@ -126,26 +126,34 @@ static irqreturn_t ls1x_clockevent_isr(int irq, void *devid) · 125 unmodified lines
126126 return IRQ_HANDLED;
127127 }
128128
129−static void ls1x_clockevent_set_mode(enum clock_event_mode mode,
130− struct clock_event_device *cd)
129+static int ls1x_clockevent_set_state_periodic(struct clock_event_device *cd)
131130 {
132131 raw_spin_lock(&ls1x_timer_lock);
133− switch (mode) {
134− case CLOCK_EVT_MODE_PERIODIC:
135− ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick);
136− ls1x_pwmtimer_restart();
137− case CLOCK_EVT_MODE_RESUME:
138− __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL);
139− break;
140− case CLOCK_EVT_MODE_ONESHOT:
141− case CLOCK_EVT_MODE_SHUTDOWN:
142− __raw_writel(__raw_readl(timer_base + PWM_CTRL) & ~CNT_EN,
143− timer_base + PWM_CTRL);
144− break;
145− default:
146− break;
147− }
132+ ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick);
133+ ls1x_pwmtimer_restart();
134+ __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL);
148135 raw_spin_unlock(&ls1x_timer_lock);
136+
137+ return 0;
138+}
139+
140+static int ls1x_clockevent_tick_resume(struct clock_event_device *cd)
141+{
142+ raw_spin_lock(&ls1x_timer_lock);
143+ __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL);
144+ raw_spin_unlock(&ls1x_timer_lock);
145+
146+ return 0;
147+}
148+
149+static int ls1x_clockevent_set_state_shutdown(struct clock_event_device *cd)
150+{
151+ raw_spin_lock(&ls1x_timer_lock);
152+ __raw_writel(__raw_readl(timer_base + PWM_CTRL) & ~CNT_EN,
153+ timer_base + PWM_CTRL);
154+ raw_spin_unlock(&ls1x_timer_lock);
155+
156+ return 0;
149157 }
150158
151159 static int ls1x_clockevent_set_next(unsigned long evt,
@@ -160,12 +168,15 @@ static int ls1x_clockevent_set_next(unsigned long evt, · 8 unmodified lines
160168 }
161169
162170 static struct clock_event_device ls1x_clockevent = {
163− .name = "ls1x-pwmtimer",
164− .features = CLOCK_EVT_FEAT_PERIODIC,
165− .rating = 300,
166− .irq = LS1X_TIMER_IRQ,
167− .set_next_event = ls1x_clockevent_set_next,
168− .set_mode = ls1x_clockevent_set_mode,
171+ .name = "ls1x-pwmtimer",
172+ .features = CLOCK_EVT_FEAT_PERIODIC,
173+ .rating = 300,
174+ .irq = LS1X_TIMER_IRQ,
175+ .set_next_event = ls1x_clockevent_set_next,
176+ .set_state_shutdown = ls1x_clockevent_set_state_shutdown,
177+ .set_state_periodic = ls1x_clockevent_set_state_periodic,
178+ .set_state_oneshot = ls1x_clockevent_set_state_shutdown,
179+ .tick_resume = ls1x_clockevent_tick_resume,
169180 };
170181
171182 static struct irqaction ls1x_pwmtimer_irqaction = {
arch/mips/loongson64/common/cs5536/cs5536_mfgpt.c+21−25
@@ -51,40 +51,36 @@ void enable_mfgpt0_counter(void) · 50 unmodified lines
5151 }
5252 EXPORT_SYMBOL(enable_mfgpt0_counter);
5353
54−static void init_mfgpt_timer(enum clock_event_mode mode,
55− struct clock_event_device *evt)
54+static int mfgpt_timer_set_periodic(struct clock_event_device *evt)
5655 {
5756 raw_spin_lock(&mfgpt_lock);
5857
59− switch (mode) {
60− case CLOCK_EVT_MODE_PERIODIC:
61− outw(COMPARE, MFGPT0_CMP2); /* set comparator2 */
62− outw(0, MFGPT0_CNT); /* set counter to 0 */
63− enable_mfgpt0_counter();
64− break;
65−
66− case CLOCK_EVT_MODE_SHUTDOWN:
67− case CLOCK_EVT_MODE_UNUSED:
68− if (evt->mode == CLOCK_EVT_MODE_PERIODIC ||
69− evt->mode == CLOCK_EVT_MODE_ONESHOT)
70− disable_mfgpt0_counter();
71− break;
72−
73− case CLOCK_EVT_MODE_ONESHOT:
74− /* The oneshot mode have very high deviation, Not use it! */
75− break;
76−
77− case CLOCK_EVT_MODE_RESUME:
78− /* Nothing to do here */
79− break;
80− }
58+ outw(COMPARE, MFGPT0_CMP2); /* set comparator2 */
59+ outw(0, MFGPT0_CNT); /* set counter to 0 */
60+ enable_mfgpt0_counter();
61+
8162 raw_spin_unlock(&mfgpt_lock);
63+ return 0;
64+}
65+
66+static int mfgpt_timer_shutdown(struct clock_event_device *evt)
67+{
68+ if (clockevent_state_periodic(evt) || clockevent_state_oneshot(evt)) {
69+ raw_spin_lock(&mfgpt_lock);
70+ disable_mfgpt0_counter();
71+ raw_spin_unlock(&mfgpt_lock);
72+ }
73+
74+ return 0;
8275 }
8376
8477 static struct clock_event_device mfgpt_clockevent = {
8578 .name = "mfgpt",
8679 .features = CLOCK_EVT_FEAT_PERIODIC,
87− .set_mode = init_mfgpt_timer,
80+
81+ /* The oneshot mode have very high deviation, don't use it! */
82+ .set_state_shutdown = mfgpt_timer_shutdown,
83+ .set_state_periodic = mfgpt_timer_set_periodic,
8884 .irq = CS5536_MFGPT_INTR,
8985 };
9086
arch/mips/loongson64/loongson-3/hpet.c+71−46
@@ -78,55 +78,77 @@ static void hpet_enable_legacy_int(void) · 77 unmodified lines
7878 /* Do nothing on Loongson-3 */
7979 }
8080
81−static void hpet_set_mode(enum clock_event_mode mode,
82− struct clock_event_device *evt)
81+static int hpet_set_state_periodic(struct clock_event_device *evt)
8382 {
84− int cfg = 0;
83+ int cfg;
8584
8685 spin_lock(&hpet_lock);
87− switch (mode) {
88− case CLOCK_EVT_MODE_PERIODIC:
89− pr_info("set clock event to periodic mode!\n");
90− /* stop counter */
91− hpet_stop_counter();
92−
93− /* enables the timer0 to generate a periodic interrupt */
94− cfg = hpet_read(HPET_T0_CFG);
95− cfg &= ~HPET_TN_LEVEL;
96− cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |
97− HPET_TN_SETVAL | HPET_TN_32BIT;
98− hpet_write(HPET_T0_CFG, cfg);
99−
100− /* set the comparator */
101− hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL);
102− udelay(1);
103− hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL);
104−
105− /* start counter */
106− hpet_start_counter();
107− break;
108− case CLOCK_EVT_MODE_SHUTDOWN:
109− case CLOCK_EVT_MODE_UNUSED:
110− cfg = hpet_read(HPET_T0_CFG);
111− cfg &= ~HPET_TN_ENABLE;
112− hpet_write(HPET_T0_CFG, cfg);
113− break;
114− case CLOCK_EVT_MODE_ONESHOT:
115− pr_info("set clock event to one shot mode!\n");
116− cfg = hpet_read(HPET_T0_CFG);
117− /* set timer0 type
118− * 1 : periodic interrupt
119− * 0 : non-periodic(oneshot) interrupt
120− */
121− cfg &= ~HPET_TN_PERIODIC;
122− cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
123− hpet_write(HPET_T0_CFG, cfg);
124− break;
125− case CLOCK_EVT_MODE_RESUME:
126− hpet_enable_legacy_int();
127− break;
128− }
86+
87+ pr_info("set clock event to periodic mode!\n");
88+ /* stop counter */
89+ hpet_stop_counter();
90+
91+ /* enables the timer0 to generate a periodic interrupt */
92+ cfg = hpet_read(HPET_T0_CFG);
93+ cfg &= ~HPET_TN_LEVEL;
94+ cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
95+ HPET_TN_32BIT;
96+ hpet_write(HPET_T0_CFG, cfg);
97+
98+ /* set the comparator */
99+ hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL);
100+ udelay(1);
101+ hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL);
102+
103+ /* start counter */
104+ hpet_start_counter();
105+
106+ spin_unlock(&hpet_lock);
107+ return 0;
108+}
109+
110+static int hpet_set_state_shutdown(struct clock_event_device *evt)
111+{
112+ int cfg;
113+
114+ spin_lock(&hpet_lock);
115+
116+ cfg = hpet_read(HPET_T0_CFG);
117+ cfg &= ~HPET_TN_ENABLE;
118+ hpet_write(HPET_T0_CFG, cfg);
119+
129120 spin_unlock(&hpet_lock);
121+ return 0;
122+}
123+
124+static int hpet_set_state_oneshot(struct clock_event_device *evt)
125+{
126+ int cfg;
127+
128+ spin_lock(&hpet_lock);
129+
130+ pr_info("set clock event to one shot mode!\n");
131+ cfg = hpet_read(HPET_T0_CFG);
132+ /*
133+ * set timer0 type
134+ * 1 : periodic interrupt
135+ * 0 : non-periodic(oneshot) interrupt
136+ */
137+ cfg &= ~HPET_TN_PERIODIC;
138+ cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
139+ hpet_write(HPET_T0_CFG, cfg);
140+
141+ spin_unlock(&hpet_lock);
142+ return 0;
143+}
144+
145+static int hpet_tick_resume(struct clock_event_device *evt)
146+{
147+ spin_lock(&hpet_lock);
148+ hpet_enable_legacy_int();
149+ spin_unlock(&hpet_lock);
150+
151+ return 0;
130152 }
131153
132154 static int hpet_next_event(unsigned long delta,
@@ -206,7 +228,10 @@ void __init setup_hpet_timer(void) · 73 unmodified lines
206228 cd->name = "hpet";
207229 cd->rating = 320;
208230 cd->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
209− cd->set_mode = hpet_set_mode;
231+ cd->set_state_shutdown = hpet_set_state_shutdown;
232+ cd->set_state_periodic = hpet_set_state_periodic;
233+ cd->set_state_oneshot = hpet_set_state_oneshot;
234+ cd->tick_resume = hpet_tick_resume;
210235 cd->set_next_event = hpet_next_event;
211236 cd->irq = HPET_T0_IRQ;
212237 cd->cpumask = cpumask_of(cpu);
arch/mips/math-emu/Makefile+2−2
@@ -4,9 +4,9 @@ · 3 unmodified lines
44
55 obj-y += cp1emu.o ieee754dp.o ieee754sp.o ieee754.o \
66 dp_div.o dp_mul.o dp_sub.o dp_add.o dp_fsp.o dp_cmp.o dp_simple.o \
7− dp_tint.o dp_fint.o \
7+ dp_tint.o dp_fint.o dp_maddf.o dp_msubf.o dp_2008class.o dp_fmin.o dp_fmax.o \
88 sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_simple.o \
9− sp_tint.o sp_fint.o \
9+ sp_tint.o sp_fint.o sp_maddf.o sp_msubf.o sp_2008class.o sp_fmin.o sp_fmax.o \
1010 dsemul.o
1111
1212 lib-y += ieee754d.o \
arch/mips/math-emu/cp1emu.c+387−13
@@ -1137,7 +1137,7 @@ emul: · 1136 unmodified lines
11371137 break;
11381138
11391139 case mfhc_op:
1140− if (!cpu_has_mips_r2)
1140+ if (!cpu_has_mips_r2_r6)
11411141 goto sigill;
11421142
11431143 /* copregister rd -> gpr[rt] */
@@ -1148,7 +1148,7 @@ emul: · 4 unmodified lines
11481148 break;
11491149
11501150 case mthc_op:
1151− if (!cpu_has_mips_r2)
1151+ if (!cpu_has_mips_r2_r6)
11521152 goto sigill;
11531153
11541154 /* copregister rd <- gpr[rt] */
@@ -1181,6 +1181,24 @@ emul: · 26 unmodified lines
11811181 }
11821182 break;
11831183
1184+ case bc1eqz_op:
1185+ case bc1nez_op:
1186+ if (!cpu_has_mips_r6 || delay_slot(xcp))
1187+ return SIGILL;
1188+
1189+ cond = likely = 0;
1190+ switch (MIPSInst_RS(ir)) {
1191+ case bc1eqz_op:
1192+ if (get_fpr32(&current->thread.fpu.fpr[MIPSInst_RT(ir)], 0) & 0x1)
1193+ cond = 1;
1194+ break;
1195+ case bc1nez_op:
1196+ if (!(get_fpr32(&current->thread.fpu.fpr[MIPSInst_RT(ir)], 0) & 0x1))
1197+ cond = 1;
1198+ break;
1199+ }
1200+ goto branch_common;
1201+
11841202 case bc_op:
11851203 if (delay_slot(xcp))
11861204 return SIGILL;
@@ -1207,7 +1225,7 @@ emul: · 20 unmodified lines
12071225 case bct_op:
12081226 break;
12091227 }
1210−
1228+branch_common:
12111229 set_delay_slot(xcp);
12121230 if (cond) {
12131231 /*
@@ -1376,6 +1394,14 @@ static const unsigned char cmptab[8] = { · 162 unmodified lines
13761394 IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN, /* cmp_ule (sig) cmp_ngt */
13771395 };
13781396
1397+static const unsigned char negative_cmptab[8] = {
1398+ 0, /* Reserved */
1399+ IEEE754_CLT | IEEE754_CGT | IEEE754_CEQ,
1400+ IEEE754_CLT | IEEE754_CGT | IEEE754_CUN,
1401+ IEEE754_CLT | IEEE754_CGT,
1402+ /* Reserved */
1403+};
1404+
13791405
13801406 /*
13811407 * Additional MIPS4 instructions
@@ -1717,6 +1743,126 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 335 unmodified lines
17171743 SPFROMREG(rv.s, MIPSInst_FS(ir));
17181744 break;
17191745
1746+ case fseleqz_op:
1747+ if (!cpu_has_mips_r6)
1748+ return SIGILL;
1749+
1750+ SPFROMREG(rv.s, MIPSInst_FT(ir));
1751+ if (rv.w & 0x1)
1752+ rv.w = 0;
1753+ else
1754+ SPFROMREG(rv.s, MIPSInst_FS(ir));
1755+ break;
1756+
1757+ case fselnez_op:
1758+ if (!cpu_has_mips_r6)
1759+ return SIGILL;
1760+
1761+ SPFROMREG(rv.s, MIPSInst_FT(ir));
1762+ if (rv.w & 0x1)
1763+ SPFROMREG(rv.s, MIPSInst_FS(ir));
1764+ else
1765+ rv.w = 0;
1766+ break;
1767+
1768+ case fmaddf_op: {
1769+ union ieee754sp ft, fs, fd;
1770+
1771+ if (!cpu_has_mips_r6)
1772+ return SIGILL;
1773+
1774+ SPFROMREG(ft, MIPSInst_FT(ir));
1775+ SPFROMREG(fs, MIPSInst_FS(ir));
1776+ SPFROMREG(fd, MIPSInst_FD(ir));
1777+ rv.s = ieee754sp_maddf(fd, fs, ft);
1778+ break;
1779+ }
1780+
1781+ case fmsubf_op: {
1782+ union ieee754sp ft, fs, fd;
1783+
1784+ if (!cpu_has_mips_r6)
1785+ return SIGILL;
1786+
1787+ SPFROMREG(ft, MIPSInst_FT(ir));
1788+ SPFROMREG(fs, MIPSInst_FS(ir));
1789+ SPFROMREG(fd, MIPSInst_FD(ir));
1790+ rv.s = ieee754sp_msubf(fd, fs, ft);
1791+ break;
1792+ }
1793+
1794+ case frint_op: {
1795+ union ieee754sp fs;
1796+
1797+ if (!cpu_has_mips_r6)
1798+ return SIGILL;
1799+
1800+ SPFROMREG(fs, MIPSInst_FS(ir));
1801+ rv.l = ieee754sp_tlong(fs);
1802+ rv.s = ieee754sp_flong(rv.l);
1803+ goto copcsr;
1804+ }
1805+
1806+ case fclass_op: {
1807+ union ieee754sp fs;
1808+
1809+ if (!cpu_has_mips_r6)
1810+ return SIGILL;
1811+
1812+ SPFROMREG(fs, MIPSInst_FS(ir));
1813+ rv.w = ieee754sp_2008class(fs);
1814+ rfmt = w_fmt;
1815+ break;
1816+ }
1817+
1818+ case fmin_op: {
1819+ union ieee754sp fs, ft;
1820+
1821+ if (!cpu_has_mips_r6)
1822+ return SIGILL;
1823+
1824+ SPFROMREG(ft, MIPSInst_FT(ir));
1825+ SPFROMREG(fs, MIPSInst_FS(ir));
1826+ rv.s = ieee754sp_fmin(fs, ft);
1827+ break;
1828+ }
1829+
1830+ case fmina_op: {
1831+ union ieee754sp fs, ft;
1832+
1833+ if (!cpu_has_mips_r6)
1834+ return SIGILL;
1835+
1836+ SPFROMREG(ft, MIPSInst_FT(ir));
1837+ SPFROMREG(fs, MIPSInst_FS(ir));
1838+ rv.s = ieee754sp_fmina(fs, ft);
1839+ break;
1840+ }
1841+
1842+ case fmax_op: {
1843+ union ieee754sp fs, ft;
1844+
1845+ if (!cpu_has_mips_r6)
1846+ return SIGILL;
1847+
1848+ SPFROMREG(ft, MIPSInst_FT(ir));
1849+ SPFROMREG(fs, MIPSInst_FS(ir));
1850+ rv.s = ieee754sp_fmax(fs, ft);
1851+ break;
1852+ }
1853+
1854+ case fmaxa_op: {
1855+ union ieee754sp fs, ft;
1856+
1857+ if (!cpu_has_mips_r6)
1858+ return SIGILL;
1859+
1860+ SPFROMREG(ft, MIPSInst_FT(ir));
1861+ SPFROMREG(fs, MIPSInst_FS(ir));
1862+ rv.s = ieee754sp_fmaxa(fs, ft);
1863+ break;
1864+ }
1865+
17201866 case fabs_op:
17211867 handler.u = ieee754sp_abs;
17221868 goto scopuop;
@@ -1820,7 +1966,7 @@ copcsr: · 97 unmodified lines
18201966 goto copcsr;
18211967
18221968 default:
1823− if (MIPSInst_FUNC(ir) >= fcmp_op) {
1969+ if (!NO_R6EMU && MIPSInst_FUNC(ir) >= fcmp_op) {
18241970 unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
18251971 union ieee754sp fs, ft;
18261972
@@ -1914,6 +2060,127 @@ copcsr: · 87 unmodified lines
19142060 return 0;
19152061 DPFROMREG(rv.d, MIPSInst_FS(ir));
19162062 break;
2063+
2064+ case fseleqz_op:
2065+ if (!cpu_has_mips_r6)
2066+ return SIGILL;
2067+
2068+ DPFROMREG(rv.d, MIPSInst_FT(ir));
2069+ if (rv.l & 0x1)
2070+ rv.l = 0;
2071+ else
2072+ DPFROMREG(rv.d, MIPSInst_FS(ir));
2073+ break;
2074+
2075+ case fselnez_op:
2076+ if (!cpu_has_mips_r6)
2077+ return SIGILL;
2078+
2079+ DPFROMREG(rv.d, MIPSInst_FT(ir));
2080+ if (rv.l & 0x1)
2081+ DPFROMREG(rv.d, MIPSInst_FS(ir));
2082+ else
2083+ rv.l = 0;
2084+ break;
2085+
2086+ case fmaddf_op: {
2087+ union ieee754dp ft, fs, fd;
2088+
2089+ if (!cpu_has_mips_r6)
2090+ return SIGILL;
2091+
2092+ DPFROMREG(ft, MIPSInst_FT(ir));
2093+ DPFROMREG(fs, MIPSInst_FS(ir));
2094+ DPFROMREG(fd, MIPSInst_FD(ir));
2095+ rv.d = ieee754dp_maddf(fd, fs, ft);
2096+ break;
2097+ }
2098+
2099+ case fmsubf_op: {
2100+ union ieee754dp ft, fs, fd;
2101+
2102+ if (!cpu_has_mips_r6)
2103+ return SIGILL;
2104+
2105+ DPFROMREG(ft, MIPSInst_FT(ir));
2106+ DPFROMREG(fs, MIPSInst_FS(ir));
2107+ DPFROMREG(fd, MIPSInst_FD(ir));
2108+ rv.d = ieee754dp_msubf(fd, fs, ft);
2109+ break;
2110+ }
2111+
2112+ case frint_op: {
2113+ union ieee754dp fs;
2114+
2115+ if (!cpu_has_mips_r6)
2116+ return SIGILL;
2117+
2118+ DPFROMREG(fs, MIPSInst_FS(ir));
2119+ rv.l = ieee754dp_tlong(fs);
2120+ rv.d = ieee754dp_flong(rv.l);
2121+ goto copcsr;
2122+ }
2123+
2124+ case fclass_op: {
2125+ union ieee754dp fs;
2126+
2127+ if (!cpu_has_mips_r6)
2128+ return SIGILL;
2129+
2130+ DPFROMREG(fs, MIPSInst_FS(ir));
2131+ rv.w = ieee754dp_2008class(fs);
2132+ rfmt = w_fmt;
2133+ break;
2134+ }
2135+
2136+ case fmin_op: {
2137+ union ieee754dp fs, ft;
2138+
2139+ if (!cpu_has_mips_r6)
2140+ return SIGILL;
2141+
2142+ DPFROMREG(ft, MIPSInst_FT(ir));
2143+ DPFROMREG(fs, MIPSInst_FS(ir));
2144+ rv.d = ieee754dp_fmin(fs, ft);
2145+ break;
2146+ }
2147+
2148+ case fmina_op: {
2149+ union ieee754dp fs, ft;
2150+
2151+ if (!cpu_has_mips_r6)
2152+ return SIGILL;
2153+
2154+ DPFROMREG(ft, MIPSInst_FT(ir));
2155+ DPFROMREG(fs, MIPSInst_FS(ir));
2156+ rv.d = ieee754dp_fmina(fs, ft);
2157+ break;
2158+ }
2159+
2160+ case fmax_op: {
2161+ union ieee754dp fs, ft;
2162+
2163+ if (!cpu_has_mips_r6)
2164+ return SIGILL;
2165+
2166+ DPFROMREG(ft, MIPSInst_FT(ir));
2167+ DPFROMREG(fs, MIPSInst_FS(ir));
2168+ rv.d = ieee754dp_fmax(fs, ft);
2169+ break;
2170+ }
2171+
2172+ case fmaxa_op: {
2173+ union ieee754dp fs, ft;
2174+
2175+ if (!cpu_has_mips_r6)
2176+ return SIGILL;
2177+
2178+ DPFROMREG(ft, MIPSInst_FT(ir));
2179+ DPFROMREG(fs, MIPSInst_FS(ir));
2180+ rv.d = ieee754dp_fmaxa(fs, ft);
2181+ break;
2182+ }
2183+
19172184 case fabs_op:
19182185 handler.u = ieee754dp_abs;
19192186 goto dcopuop;
@@ -1997,7 +2264,7 @@ dcopuop: · 77 unmodified lines
19972264 goto copcsr;
19982265
19992266 default:
2000− if (MIPSInst_FUNC(ir) >= fcmp_op) {
2267+ if (!NO_R6EMU && MIPSInst_FUNC(ir) >= fcmp_op) {
20012268 unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
20022269 union ieee754dp fs, ft;
20032270
@@ -2021,8 +2288,11 @@ dcopuop: · 17 unmodified lines
20212288 break;
20222289 }
20232290 break;
2291+ }
2292+
2293+ case w_fmt: {
2294+ union ieee754dp fs;
20242295
2025− case w_fmt:
20262296 switch (MIPSInst_FUNC(ir)) {
20272297 case fcvts_op:
20282298 /* convert word to single precision real */
@@ -2036,10 +2306,65 @@ dcopuop: · 7 unmodified lines
20362306 rv.d = ieee754dp_fint(fs.bits);
20372307 rfmt = d_fmt;
20382308 goto copcsr;
2039− default:
2040− return SIGILL;
2309+ default: {
2310+ /* Emulating the new CMP.condn.fmt R6 instruction */
2311+#define CMPOP_MASK 0x7
2312+#define SIGN_BIT (0x1 << 3)
2313+#define PREDICATE_BIT (0x1 << 4)
2314+
2315+ int cmpop = MIPSInst_FUNC(ir) & CMPOP_MASK;
2316+ int sig = MIPSInst_FUNC(ir) & SIGN_BIT;
2317+ union ieee754sp fs, ft;
2318+
2319+ /* This is an R6 only instruction */
2320+ if (!cpu_has_mips_r6 ||
2321+ (MIPSInst_FUNC(ir) & 0x20))
2322+ return SIGILL;
2323+
2324+ /* fmt is w_fmt for single precision so fix it */
2325+ rfmt = s_fmt;
2326+ /* default to false */
2327+ rv.w = 0;
2328+
2329+ /* CMP.condn.S */
2330+ SPFROMREG(fs, MIPSInst_FS(ir));
2331+ SPFROMREG(ft, MIPSInst_FT(ir));
2332+
2333+ /* positive predicates */
2334+ if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2335+ if (ieee754sp_cmp(fs, ft, cmptab[cmpop],
2336+ sig))
2337+ rv.w = -1; /* true, all 1s */
2338+ if ((sig) &&
2339+ ieee754_cxtest(IEEE754_INVALID_OPERATION))
2340+ rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2341+ else
2342+ goto copcsr;
2343+ } else {
2344+ /* negative predicates */
2345+ switch (cmpop) {
2346+ case 1:
2347+ case 2:
2348+ case 3:
2349+ if (ieee754sp_cmp(fs, ft,
2350+ negative_cmptab[cmpop],
2351+ sig))
2352+ rv.w = -1; /* true, all 1s */
2353+ if (sig &&
2354+ ieee754_cxtest(IEEE754_INVALID_OPERATION))
2355+ rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2356+ else
2357+ goto copcsr;
2358+ break;
2359+ default:
2360+ /* Reserved R6 ops */
2361+ pr_err("Reserved MIPS R6 CMP.condn.S operation\n");
2362+ return SIGILL;
2363+ }
2364+ }
2365+ break;
2366+ }
20412367 }
2042− break;
20432368 }
20442369
20452370 case l_fmt:
@@ -2060,11 +2385,60 @@ dcopuop: · 14 unmodified lines
20602385 rv.d = ieee754dp_flong(bits);
20612386 rfmt = d_fmt;
20622387 goto copcsr;
2063− default:
2064− return SIGILL;
2065− }
2066− break;
2388+ default: {
2389+ /* Emulating the new CMP.condn.fmt R6 instruction */
2390+ int cmpop = MIPSInst_FUNC(ir) & CMPOP_MASK;
2391+ int sig = MIPSInst_FUNC(ir) & SIGN_BIT;
2392+ union ieee754dp fs, ft;
2393+
2394+ if (!cpu_has_mips_r6 ||
2395+ (MIPSInst_FUNC(ir) & 0x20))
2396+ return SIGILL;
2397+
2398+ /* fmt is l_fmt for double precision so fix it */
2399+ rfmt = d_fmt;
2400+ /* default to false */
2401+ rv.l = 0;
20672402
2403+ /* CMP.condn.D */
2404+ DPFROMREG(fs, MIPSInst_FS(ir));
2405+ DPFROMREG(ft, MIPSInst_FT(ir));
2406+
2407+ /* positive predicates */
2408+ if (!(MIPSInst_FUNC(ir) & PREDICATE_BIT)) {
2409+ if (ieee754dp_cmp(fs, ft,
2410+ cmptab[cmpop], sig))
2411+ rv.l = -1LL; /* true, all 1s */
2412+ if (sig &&
2413+ ieee754_cxtest(IEEE754_INVALID_OPERATION))
2414+ rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2415+ else
2416+ goto copcsr;
2417+ } else {
2418+ /* negative predicates */
2419+ switch (cmpop) {
2420+ case 1:
2421+ case 2:
2422+ case 3:
2423+ if (ieee754dp_cmp(fs, ft,
2424+ negative_cmptab[cmpop],
2425+ sig))
2426+ rv.l = -1LL; /* true, all 1s */
2427+ if (sig &&
2428+ ieee754_cxtest(IEEE754_INVALID_OPERATION))
2429+ rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;
2430+ else
2431+ goto copcsr;
2432+ break;
2433+ default:
2434+ /* Reserved R6 ops */
2435+ pr_err("Reserved MIPS R6 CMP.condn.D operation\n");
2436+ return SIGILL;
2437+ }
2438+ }
2439+ break;
2440+ }
2441+ }
20682442 default:
20692443 return SIGILL;
20702444 }
arch/mips/math-emu/dp_2008class.c+55−0
@@ -0,0 +1,55 @@
1+/*
2+ * IEEE754 floating point arithmetic
3+ * double precision: CLASS.f
4+ * FPR[fd] = class(FPR[fs])
5+ *
6+ * MIPS floating point support
7+ * Copyright (C) 2015 Imagination Technologies, Ltd.
8+ * Author: Markos Chandras <markos.chandras@imgtec.com>
9+ *
10+ * This program is free software; you can distribute it and/or modify it
11+ * under the terms of the GNU General Public License as published by the
12+ * Free Software Foundation; version 2 of the License.
13+ */
14+
15+#include "ieee754dp.h"
16+
17+int ieee754dp_2008class(union ieee754dp x)
18+{
19+ COMPXDP;
20+
21+ EXPLODEXDP;
22+
23+ /*
24+ * 10 bit mask as follows:
25+ *
26+ * bit0 = SNAN
27+ * bit1 = QNAN
28+ * bit2 = -INF
29+ * bit3 = -NORM
30+ * bit4 = -DNORM
31+ * bit5 = -ZERO
32+ * bit6 = INF
33+ * bit7 = NORM
34+ * bit8 = DNORM
35+ * bit9 = ZERO
36+ */
37+
38+ switch(xc) {
39+ case IEEE754_CLASS_SNAN:
40+ return 0x01;
41+ case IEEE754_CLASS_QNAN:
42+ return 0x02;
43+ case IEEE754_CLASS_INF:
44+ return 0x04 << (xs ? 0 : 4);
45+ case IEEE754_CLASS_NORM:
46+ return 0x08 << (xs ? 0 : 4);
47+ case IEEE754_CLASS_DNORM:
48+ return 0x10 << (xs ? 0 : 4);
49+ case IEEE754_CLASS_ZERO:
50+ return 0x20 << (xs ? 0 : 4);
51+ default:
52+ pr_err("Unknown class: %d\n", xc);
53+ return 0;
54+ }
55+}
arch/mips/math-emu/dp_fmax.c+213−0
@@ -0,0 +1,213 @@
1+/*
2+ * IEEE754 floating point arithmetic
3+ * double precision: MIN{,A}.f
4+ * MIN : Scalar Floating-Point Minimum
5+ * MINA: Scalar Floating-Point argument with Minimum Absolute Value
6+ *
7+ * MIN.D : FPR[fd] = minNum(FPR[fs],FPR[ft])
8+ * MINA.D: FPR[fd] = maxNumMag(FPR[fs],FPR[ft])
9+ *
10+ * MIPS floating point support
11+ * Copyright (C) 2015 Imagination Technologies, Ltd.
12+ * Author: Markos Chandras <markos.chandras@imgtec.com>
13+ *
14+ * This program is free software; you can distribute it and/or modify it
15+ * under the terms of the GNU General Public License as published by the
16+ * Free Software Foundation; version 2 of the License.
17+ */
18+
19+#include "ieee754dp.h"
20+
21+union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y)
22+{
23+ COMPXDP;
24+ COMPYDP;
25+
26+ EXPLODEXDP;
27+ EXPLODEYDP;
28+
29+ FLUSHXDP;
30+ FLUSHYDP;
31+
32+ ieee754_clearcx();
33+
34+ switch (CLPAIR(xc, yc)) {
35+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
36+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
37+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
38+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
39+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
40+ return ieee754dp_nanxcpt(y);
41+
42+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
43+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
44+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
45+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
46+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
47+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
48+ return ieee754dp_nanxcpt(x);
49+
50+ /* numbers are preferred to NaNs */
51+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
52+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
53+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
54+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
55+ return x;
56+
57+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
58+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
59+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
60+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
61+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
62+ return y;
63+
64+ /*
65+ * Infinity and zero handling
66+ */
67+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
68+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
69+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
70+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
71+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
72+ return xs ? y : x;
73+
74+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
75+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
76+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
77+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
78+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
79+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
80+ return ys ? x : y;
81+
82+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
83+ if (xs == ys)
84+ return x;
85+ return ieee754dp_zero(1);
86+
87+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
88+ DPDNORMX;
89+
90+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
91+ DPDNORMY;
92+ break;
93+
94+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
95+ DPDNORMX;
96+ }
97+
98+ /* Finally get to do some computation */
99+
100+ assert(xm & DP_HIDDEN_BIT);
101+ assert(ym & DP_HIDDEN_BIT);
102+
103+ /* Compare signs */
104+ if (xs > ys)
105+ return y;
106+ else if (xs < ys)
107+ return x;
108+
109+ /* Compare exponent */
110+ if (xe > ye)
111+ return x;
112+ else if (xe < ye)
113+ return y;
114+
115+ /* Compare mantissa */
116+ if (xm <= ym)
117+ return y;
118+ return x;
119+}
120+
121+union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y)
122+{
123+ COMPXDP;
124+ COMPYDP;
125+
126+ EXPLODEXDP;
127+ EXPLODEYDP;
128+
129+ FLUSHXDP;
130+ FLUSHYDP;
131+
132+ ieee754_clearcx();
133+
134+ switch (CLPAIR(xc, yc)) {
135+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
136+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
137+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
138+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
139+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
140+ return ieee754dp_nanxcpt(y);
141+
142+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
143+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
144+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
145+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
146+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
147+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
148+ return ieee754dp_nanxcpt(x);
149+
150+ /* numbers are preferred to NaNs */
151+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
152+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
153+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
154+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
155+ return x;
156+
157+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
158+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
159+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
160+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
161+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
162+ return y;
163+
164+ /*
165+ * Infinity and zero handling
166+ */
167+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
168+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
169+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
170+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
171+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
172+ return x;
173+
174+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
175+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
176+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
177+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
178+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
179+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
180+ return y;
181+
182+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
183+ if (xs == ys)
184+ return x;
185+ return ieee754dp_zero(1);
186+
187+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
188+ DPDNORMX;
189+
190+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
191+ DPDNORMY;
192+ break;
193+
194+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
195+ DPDNORMX;
196+ }
197+
198+ /* Finally get to do some computation */
199+
200+ assert(xm & DP_HIDDEN_BIT);
201+ assert(ym & DP_HIDDEN_BIT);
202+
203+ /* Compare exponent */
204+ if (xe > ye)
205+ return x;
206+ else if (xe < ye)
207+ return y;
208+
209+ /* Compare mantissa */
210+ if (xm <= ym)
211+ return y;
212+ return x;
213+}
arch/mips/math-emu/dp_fmin.c+213−0
@@ -0,0 +1,213 @@
1+/*
2+ * IEEE754 floating point arithmetic
3+ * double precision: MIN{,A}.f
4+ * MIN : Scalar Floating-Point Minimum
5+ * MINA: Scalar Floating-Point argument with Minimum Absolute Value
6+ *
7+ * MIN.D : FPR[fd] = minNum(FPR[fs],FPR[ft])
8+ * MINA.D: FPR[fd] = maxNumMag(FPR[fs],FPR[ft])
9+ *
10+ * MIPS floating point support
11+ * Copyright (C) 2015 Imagination Technologies, Ltd.
12+ * Author: Markos Chandras <markos.chandras@imgtec.com>
13+ *
14+ * This program is free software; you can distribute it and/or modify it
15+ * under the terms of the GNU General Public License as published by the
16+ * Free Software Foundation; version 2 of the License.
17+ */
18+
19+#include "ieee754dp.h"
20+
21+union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y)
22+{
23+ COMPXDP;
24+ COMPYDP;
25+
26+ EXPLODEXDP;
27+ EXPLODEYDP;
28+
29+ FLUSHXDP;
30+ FLUSHYDP;
31+
32+ ieee754_clearcx();
33+
34+ switch (CLPAIR(xc, yc)) {
35+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
36+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
37+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
38+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
39+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
40+ return ieee754dp_nanxcpt(y);
41+
42+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
43+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
44+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
45+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
46+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
47+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
48+ return ieee754dp_nanxcpt(x);
49+
50+ /* numbers are preferred to NaNs */
51+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
52+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
53+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
54+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
55+ return x;
56+
57+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
58+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
59+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
60+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
61+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
62+ return y;
63+
64+ /*
65+ * Infinity and zero handling
66+ */
67+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
68+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
69+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
70+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
71+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
72+ return xs ? x : y;
73+
74+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
75+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
76+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
77+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
78+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
79+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
80+ return ys ? y : x;
81+
82+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
83+ if (xs == ys)
84+ return x;
85+ return ieee754dp_zero(1);
86+
87+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
88+ DPDNORMX;
89+
90+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
91+ DPDNORMY;
92+ break;
93+
94+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
95+ DPDNORMX;
96+ }
97+
98+ /* Finally get to do some computation */
99+
100+ assert(xm & DP_HIDDEN_BIT);
101+ assert(ym & DP_HIDDEN_BIT);
102+
103+ /* Compare signs */
104+ if (xs > ys)
105+ return x;
106+ else if (xs < ys)
107+ return y;
108+
109+ /* Compare exponent */
110+ if (xe > ye)
111+ return y;
112+ else if (xe < ye)
113+ return x;
114+
115+ /* Compare mantissa */
116+ if (xm <= ym)
117+ return x;
118+ return y;
119+}
120+
121+union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y)
122+{
123+ COMPXDP;
124+ COMPYDP;
125+
126+ EXPLODEXDP;
127+ EXPLODEYDP;
128+
129+ FLUSHXDP;
130+ FLUSHYDP;
131+
132+ ieee754_clearcx();
133+
134+ switch (CLPAIR(xc, yc)) {
135+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
136+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
137+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
138+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
139+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
140+ return ieee754dp_nanxcpt(y);
141+
142+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
143+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
144+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
145+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
146+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
147+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
148+ return ieee754dp_nanxcpt(x);
149+
150+ /* numbers are preferred to NaNs */
151+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
152+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
153+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
154+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
155+ return x;
156+
157+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
158+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
159+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
160+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
161+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
162+ return y;
163+
164+ /*
165+ * Infinity and zero handling
166+ */
167+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
168+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
169+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
170+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
171+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
172+ return x;
173+
174+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
175+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
176+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
177+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
178+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
179+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
180+ return y;
181+
182+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
183+ if (xs == ys)
184+ return x;
185+ return ieee754dp_zero(1);
186+
187+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
188+ DPDNORMX;
189+
190+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
191+ DPDNORMY;
192+ break;
193+
194+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
195+ DPDNORMX;
196+ }
197+
198+ /* Finally get to do some computation */
199+
200+ assert(xm & DP_HIDDEN_BIT);
201+ assert(ym & DP_HIDDEN_BIT);
202+
203+ /* Compare exponent */
204+ if (xe > ye)
205+ return y;
206+ else if (xe < ye)
207+ return x;
208+
209+ /* Compare mantissa */
210+ if (xm <= ym)
211+ return x;
212+ return y;
213+}
arch/mips/math-emu/dp_maddf.c+265−0
@@ -0,0 +1,265 @@
1+/*
2+ * IEEE754 floating point arithmetic
3+ * double precision: MADDF.f (Fused Multiply Add)
4+ * MADDF.fmt: FPR[fd] = FPR[fd] + (FPR[fs] x FPR[ft])
5+ *
6+ * MIPS floating point support
7+ * Copyright (C) 2015 Imagination Technologies, Ltd.
8+ * Author: Markos Chandras <markos.chandras@imgtec.com>
9+ *
10+ * This program is free software; you can distribute it and/or modify it
11+ * under the terms of the GNU General Public License as published by the
12+ * Free Software Foundation; version 2 of the License.
13+ */
14+
15+#include "ieee754dp.h"
16+
17+union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x,
18+ union ieee754dp y)
19+{
20+ int re;
21+ int rs;
22+ u64 rm;
23+ unsigned lxm;
24+ unsigned hxm;
25+ unsigned lym;
26+ unsigned hym;
27+ u64 lrm;
28+ u64 hrm;
29+ u64 t;
30+ u64 at;
31+ int s;
32+
33+ COMPXDP;
34+ COMPYDP;
35+
36+ u64 zm; int ze; int zs __maybe_unused; int zc;
37+
38+ EXPLODEXDP;
39+ EXPLODEYDP;
40+ EXPLODEDP(z, zc, zs, ze, zm)
41+
42+ FLUSHXDP;
43+ FLUSHYDP;
44+ FLUSHDP(z, zc, zs, ze, zm);
45+
46+ ieee754_clearcx();
47+
48+ switch (zc) {
49+ case IEEE754_CLASS_SNAN:
50+ ieee754_setcx(IEEE754_INVALID_OPERATION);
51+ return ieee754dp_nanxcpt(z);
52+ case IEEE754_CLASS_DNORM:
53+ DPDNORMx(zm, ze);
54+ /* QNAN is handled separately below */
55+ }
56+
57+ switch (CLPAIR(xc, yc)) {
58+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
59+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
60+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
61+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
62+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
63+ return ieee754dp_nanxcpt(y);
64+
65+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
66+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
67+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
68+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
69+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
70+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
71+ return ieee754dp_nanxcpt(x);
72+
73+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
74+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
75+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
76+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
77+ return y;
78+
79+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
80+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
81+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
82+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
83+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
84+ return x;
85+
86+
87+ /*
88+ * Infinity handling
89+ */
90+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
91+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
92+ if (zc == IEEE754_CLASS_QNAN)
93+ return z;
94+ ieee754_setcx(IEEE754_INVALID_OPERATION);
95+ return ieee754dp_indef();
96+
97+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
98+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
99+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
100+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
101+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
102+ if (zc == IEEE754_CLASS_QNAN)
103+ return z;
104+ return ieee754dp_inf(xs ^ ys);
105+
106+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
107+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
108+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
109+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
110+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
111+ if (zc == IEEE754_CLASS_INF)
112+ return ieee754dp_inf(zs);
113+ /* Multiplication is 0 so just return z */
114+ return z;
115+
116+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
117+ DPDNORMX;
118+
119+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
120+ if (zc == IEEE754_CLASS_QNAN)
121+ return z;
122+ else if (zc == IEEE754_CLASS_INF)
123+ return ieee754dp_inf(zs);
124+ DPDNORMY;
125+ break;
126+
127+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
128+ if (zc == IEEE754_CLASS_QNAN)
129+ return z;
130+ else if (zc == IEEE754_CLASS_INF)
131+ return ieee754dp_inf(zs);
132+ DPDNORMX;
133+ break;
134+
135+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
136+ if (zc == IEEE754_CLASS_QNAN)
137+ return z;
138+ else if (zc == IEEE754_CLASS_INF)
139+ return ieee754dp_inf(zs);
140+ /* fall through to real computations */
141+ }
142+
143+ /* Finally get to do some computation */
144+
145+ /*
146+ * Do the multiplication bit first
147+ *
148+ * rm = xm * ym, re = xe + ye basically
149+ *
150+ * At this point xm and ym should have been normalized.
151+ */
152+ assert(xm & DP_HIDDEN_BIT);
153+ assert(ym & DP_HIDDEN_BIT);
154+
155+ re = xe + ye;
156+ rs = xs ^ ys;
157+
158+ /* shunt to top of word */
159+ xm <<= 64 - (DP_FBITS + 1);
160+ ym <<= 64 - (DP_FBITS + 1);
161+
162+ /*
163+ * Multiply 32 bits xm, ym to give high 32 bits rm with stickness.
164+ */
165+
166+ /* 32 * 32 => 64 */
167+#define DPXMULT(x, y) ((u64)(x) * (u64)y)
168+
169+ lxm = xm;
170+ hxm = xm >> 32;
171+ lym = ym;
172+ hym = ym >> 32;
173+
174+ lrm = DPXMULT(lxm, lym);
175+ hrm = DPXMULT(hxm, hym);
176+
177+ t = DPXMULT(lxm, hym);
178+
179+ at = lrm + (t << 32);
180+ hrm += at < lrm;
181+ lrm = at;
182+
183+ hrm = hrm + (t >> 32);
184+
185+ t = DPXMULT(hxm, lym);
186+
187+ at = lrm + (t << 32);
188+ hrm += at < lrm;
189+ lrm = at;
190+
191+ hrm = hrm + (t >> 32);
192+
193+ rm = hrm | (lrm != 0);
194+
195+ /*
196+ * Sticky shift down to normal rounding precision.
197+ */
198+ if ((s64) rm < 0) {
199+ rm = (rm >> (64 - (DP_FBITS + 1 + 3))) |
200+ ((rm << (DP_FBITS + 1 + 3)) != 0);
201+ re++;
202+ } else {
203+ rm = (rm >> (64 - (DP_FBITS + 1 + 3 + 1))) |
204+ ((rm << (DP_FBITS + 1 + 3 + 1)) != 0);
205+ }
206+ assert(rm & (DP_HIDDEN_BIT << 3));
207+
208+ /* And now the addition */
209+ assert(zm & DP_HIDDEN_BIT);
210+
211+ /*
212+ * Provide guard,round and stick bit space.
213+ */
214+ zm <<= 3;
215+
216+ if (ze > re) {
217+ /*
218+ * Have to shift y fraction right to align.
219+ */
220+ s = ze - re;
221+ rm = XDPSRS(rm, s);
222+ re += s;
223+ } else if (re > ze) {
224+ /*
225+ * Have to shift x fraction right to align.
226+ */
227+ s = re - ze;
228+ zm = XDPSRS(zm, s);
229+ ze += s;
230+ }
231+ assert(ze == re);
232+ assert(ze <= DP_EMAX);
233+
234+ if (zs == rs) {
235+ /*
236+ * Generate 28 bit result of adding two 27 bit numbers
237+ * leaving result in xm, xs and xe.
238+ */
239+ zm = zm + rm;
240+
241+ if (zm >> (DP_FBITS + 1 + 3)) { /* carry out */
242+ zm = XDPSRS1(zm);
243+ ze++;
244+ }
245+ } else {
246+ if (zm >= rm) {
247+ zm = zm - rm;
248+ } else {
249+ zm = rm - zm;
250+ zs = rs;
251+ }
252+ if (zm == 0)
253+ return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD);
254+
255+ /*
256+ * Normalize to rounding precision.
257+ */
258+ while ((zm >> (DP_FBITS + 3)) == 0) {
259+ zm <<= 1;
260+ ze--;
261+ }
262+ }
263+
264+ return ieee754dp_format(zs, ze, zm);
265+}
arch/mips/math-emu/dp_msubf.c+269−0
@@ -0,0 +1,269 @@
1+/*
2+ * IEEE754 floating point arithmetic
3+ * double precision: MSUB.f (Fused Multiply Subtract)
4+ * MSUBF.fmt: FPR[fd] = FPR[fd] - (FPR[fs] x FPR[ft])
5+ *
6+ * MIPS floating point support
7+ * Copyright (C) 2015 Imagination Technologies, Ltd.
8+ * Author: Markos Chandras <markos.chandras@imgtec.com>
9+ *
10+ * This program is free software; you can distribute it and/or modify it
11+ * under the terms of the GNU General Public License as published by the
12+ * Free Software Foundation; version 2 of the License.
13+ */
14+
15+#include "ieee754dp.h"
16+
17+union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x,
18+ union ieee754dp y)
19+{
20+ int re;
21+ int rs;
22+ u64 rm;
23+ unsigned lxm;
24+ unsigned hxm;
25+ unsigned lym;
26+ unsigned hym;
27+ u64 lrm;
28+ u64 hrm;
29+ u64 t;
30+ u64 at;
31+ int s;
32+
33+ COMPXDP;
34+ COMPYDP;
35+
36+ u64 zm; int ze; int zs __maybe_unused; int zc;
37+
38+ EXPLODEXDP;
39+ EXPLODEYDP;
40+ EXPLODEDP(z, zc, zs, ze, zm)
41+
42+ FLUSHXDP;
43+ FLUSHYDP;
44+ FLUSHDP(z, zc, zs, ze, zm);
45+
46+ ieee754_clearcx();
47+
48+ switch (zc) {
49+ case IEEE754_CLASS_SNAN:
50+ ieee754_setcx(IEEE754_INVALID_OPERATION);
51+ return ieee754dp_nanxcpt(z);
52+ case IEEE754_CLASS_DNORM:
53+ DPDNORMx(zm, ze);
54+ /* QNAN is handled separately below */
55+ }
56+
57+ switch (CLPAIR(xc, yc)) {
58+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
59+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
60+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
61+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
62+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
63+ return ieee754dp_nanxcpt(y);
64+
65+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
66+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
67+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
68+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
69+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
70+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
71+ return ieee754dp_nanxcpt(x);
72+
73+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
74+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
75+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
76+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
77+ return y;
78+
79+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
80+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
81+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
82+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
83+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
84+ return x;
85+
86+
87+ /*
88+ * Infinity handling
89+ */
90+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
91+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
92+ if (zc == IEEE754_CLASS_QNAN)
93+ return z;
94+ ieee754_setcx(IEEE754_INVALID_OPERATION);
95+ return ieee754dp_indef();
96+
97+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
98+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
99+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
100+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
101+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
102+ if (zc == IEEE754_CLASS_QNAN)
103+ return z;
104+ return ieee754dp_inf(xs ^ ys);
105+
106+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
107+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
108+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
109+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
110+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
111+ if (zc == IEEE754_CLASS_INF)
112+ return ieee754dp_inf(zs);
113+ /* Multiplication is 0 so just return z */
114+ return z;
115+
116+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
117+ DPDNORMX;
118+
119+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
120+ if (zc == IEEE754_CLASS_QNAN)
121+ return z;
122+ else if (zc == IEEE754_CLASS_INF)
123+ return ieee754dp_inf(zs);
124+ DPDNORMY;
125+ break;
126+
127+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
128+ if (zc == IEEE754_CLASS_QNAN)
129+ return z;
130+ else if (zc == IEEE754_CLASS_INF)
131+ return ieee754dp_inf(zs);
132+ DPDNORMX;
133+ break;
134+
135+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
136+ if (zc == IEEE754_CLASS_QNAN)
137+ return z;
138+ else if (zc == IEEE754_CLASS_INF)
139+ return ieee754dp_inf(zs);
140+ /* fall through to real computations */
141+ }
142+
143+ /* Finally get to do some computation */
144+
145+ /*
146+ * Do the multiplication bit first
147+ *
148+ * rm = xm * ym, re = xe + ye basically
149+ *
150+ * At this point xm and ym should have been normalized.
151+ */
152+ assert(xm & DP_HIDDEN_BIT);
153+ assert(ym & DP_HIDDEN_BIT);
154+
155+ re = xe + ye;
156+ rs = xs ^ ys;
157+
158+ /* shunt to top of word */
159+ xm <<= 64 - (DP_FBITS + 1);
160+ ym <<= 64 - (DP_FBITS + 1);
161+
162+ /*
163+ * Multiply 32 bits xm, ym to give high 32 bits rm with stickness.
164+ */
165+
166+ /* 32 * 32 => 64 */
167+#define DPXMULT(x, y) ((u64)(x) * (u64)y)
168+
169+ lxm = xm;
170+ hxm = xm >> 32;
171+ lym = ym;
172+ hym = ym >> 32;
173+
174+ lrm = DPXMULT(lxm, lym);
175+ hrm = DPXMULT(hxm, hym);
176+
177+ t = DPXMULT(lxm, hym);
178+
179+ at = lrm + (t << 32);
180+ hrm += at < lrm;
181+ lrm = at;
182+
183+ hrm = hrm + (t >> 32);
184+
185+ t = DPXMULT(hxm, lym);
186+
187+ at = lrm + (t << 32);
188+ hrm += at < lrm;
189+ lrm = at;
190+
191+ hrm = hrm + (t >> 32);
192+
193+ rm = hrm | (lrm != 0);
194+
195+ /*
196+ * Sticky shift down to normal rounding precision.
197+ */
198+ if ((s64) rm < 0) {
199+ rm = (rm >> (64 - (DP_FBITS + 1 + 3))) |
200+ ((rm << (DP_FBITS + 1 + 3)) != 0);
201+ re++;
202+ } else {
203+ rm = (rm >> (64 - (DP_FBITS + 1 + 3 + 1))) |
204+ ((rm << (DP_FBITS + 1 + 3 + 1)) != 0);
205+ }
206+ assert(rm & (DP_HIDDEN_BIT << 3));
207+
208+ /* And now the subtraction */
209+
210+ /* flip sign of r and handle as add */
211+ rs ^= 1;
212+
213+ assert(zm & DP_HIDDEN_BIT);
214+
215+ /*
216+ * Provide guard,round and stick bit space.
217+ */
218+ zm <<= 3;
219+
220+ if (ze > re) {
221+ /*
222+ * Have to shift y fraction right to align.
223+ */
224+ s = ze - re;
225+ rm = XDPSRS(rm, s);
226+ re += s;
227+ } else if (re > ze) {
228+ /*
229+ * Have to shift x fraction right to align.
230+ */
231+ s = re - ze;
232+ zm = XDPSRS(zm, s);
233+ ze += s;
234+ }
235+ assert(ze == re);
236+ assert(ze <= DP_EMAX);
237+
238+ if (zs == rs) {
239+ /*
240+ * Generate 28 bit result of adding two 27 bit numbers
241+ * leaving result in xm, xs and xe.
242+ */
243+ zm = zm + rm;
244+
245+ if (zm >> (DP_FBITS + 1 + 3)) { /* carry out */
246+ zm = XDPSRS1(zm);
247+ ze++;
248+ }
249+ } else {
250+ if (zm >= rm) {
251+ zm = zm - rm;
252+ } else {
253+ zm = rm - zm;
254+ zs = rs;
255+ }
256+ if (zm == 0)
257+ return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD);
258+
259+ /*
260+ * Normalize to rounding precision.
261+ */
262+ while ((zm >> (DP_FBITS + 3)) == 0) {
263+ zm <<= 1;
264+ ze--;
265+ }
266+ }
267+
268+ return ieee754dp_format(zs, ze, zm);
269+}
arch/mips/math-emu/dsemul.c+0−1
@@ -33,7 +33,6 @@ struct emuframe { · 32 unmodified lines
3333
3434 int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
3535 {
36− extern asmlinkage void handle_dsemulret(void);
3736 struct emuframe __user *fr;
3837 int err;
3938
arch/mips/math-emu/ieee754.h+19−0
@@ -75,6 +75,16 @@ int ieee754sp_cmp(union ieee754sp x, union ieee754sp y, int cop, int sig); · 74 unmodified lines
7575
7676 union ieee754sp ieee754sp_sqrt(union ieee754sp x);
7777
78+union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x,
79+ union ieee754sp y);
80+union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x,
81+ union ieee754sp y);
82+int ieee754sp_2008class(union ieee754sp x);
83+union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y);
84+union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y);
85+union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y);
86+union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y);
87+
7888 /*
7989 * double precision (often aka double)
8090 */
@@ -99,6 +109,15 @@ int ieee754dp_cmp(union ieee754dp x, union ieee754dp y, int cop, int sig); · 18 unmodified lines
99109
100110 union ieee754dp ieee754dp_sqrt(union ieee754dp x);
101111
112+union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x,
113+ union ieee754dp y);
114+union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x,
115+ union ieee754dp y);
116+int ieee754dp_2008class(union ieee754dp x);
117+union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y);
118+union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y);
119+union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y);
120+union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y);
102121
103122
104123 /* 5 types of floating point number
arch/mips/math-emu/ieee754int.h+4−4
@@ -65,8 +65,8 @@ static inline int ieee754_class_nan(int xc) · 64 unmodified lines
6565 vc = IEEE754_CLASS_INF; \
6666 else if (vm & SP_MBIT(SP_FBITS-1)) \
6767 vc = IEEE754_CLASS_SNAN; \
68− else \
69− vc = IEEE754_CLASS_QNAN; \
68+ else \
69+ vc = IEEE754_CLASS_QNAN; \
7070 } else if (ve == SP_EMIN-1+SP_EBIAS) { \
7171 if (vm) { \
7272 ve = SP_EMIN; \
@@ -105,8 +105,8 @@ static inline int ieee754_class_nan(int xc) · 32 unmodified lines
105105 if (vm) { \
106106 ve = DP_EMIN; \
107107 vc = IEEE754_CLASS_DNORM; \
108− } else \
109− vc = IEEE754_CLASS_ZERO; \
108+ } else \
109+ vc = IEEE754_CLASS_ZERO; \
110110 } else { \
111111 ve -= DP_EBIAS; \
112112 vm |= DP_HIDDEN_BIT; \
arch/mips/math-emu/me-debugfs.c+1−1
@@ -65,4 +65,4 @@ do { \ · 64 unmodified lines
6565
6666 return 0;
6767 }
68−__initcall(debugfs_fpuemu);
68+arch_initcall(debugfs_fpuemu);
arch/mips/math-emu/sp_2008class.c+55−0
@@ -0,0 +1,55 @@
1+/*
2+ * IEEE754 floating point arithmetic
3+ * single precision: CLASS.f
4+ * FPR[fd] = class(FPR[fs])
5+ *
6+ * MIPS floating point support
7+ * Copyright (C) 2015 Imagination Technologies, Ltd.
8+ * Author: Markos Chandras <markos.chandras@imgtec.com>
9+ *
10+ * This program is free software; you can distribute it and/or modify it
11+ * under the terms of the GNU General Public License as published by the
12+ * Free Software Foundation; version 2 of the License.
13+ */
14+
15+#include "ieee754sp.h"
16+
17+int ieee754sp_2008class(union ieee754sp x)
18+{
19+ COMPXSP;
20+
21+ EXPLODEXSP;
22+
23+ /*
24+ * 10 bit mask as follows:
25+ *
26+ * bit0 = SNAN
27+ * bit1 = QNAN
28+ * bit2 = -INF
29+ * bit3 = -NORM
30+ * bit4 = -DNORM
31+ * bit5 = -ZERO
32+ * bit6 = INF
33+ * bit7 = NORM
34+ * bit8 = DNORM
35+ * bit9 = ZERO
36+ */
37+
38+ switch(xc) {
39+ case IEEE754_CLASS_SNAN:
40+ return 0x01;
41+ case IEEE754_CLASS_QNAN:
42+ return 0x02;
43+ case IEEE754_CLASS_INF:
44+ return 0x04 << (xs ? 0 : 4);
45+ case IEEE754_CLASS_NORM:
46+ return 0x08 << (xs ? 0 : 4);
47+ case IEEE754_CLASS_DNORM:
48+ return 0x10 << (xs ? 0 : 4);
49+ case IEEE754_CLASS_ZERO:
50+ return 0x20 << (xs ? 0 : 4);
51+ default:
52+ pr_err("Unknown class: %d\n", xc);
53+ return 0;
54+ }
55+}
arch/mips/math-emu/sp_fmax.c+213−0
@@ -0,0 +1,213 @@
1+/*
2+ * IEEE754 floating point arithmetic
3+ * single precision: MAX{,A}.f
4+ * MAX : Scalar Floating-Point Maximum
5+ * MAXA: Scalar Floating-Point argument with Maximum Absolute Value
6+ *
7+ * MAX.S : FPR[fd] = maxNum(FPR[fs],FPR[ft])
8+ * MAXA.S: FPR[fd] = maxNumMag(FPR[fs],FPR[ft])
9+ *
10+ * MIPS floating point support
11+ * Copyright (C) 2015 Imagination Technologies, Ltd.
12+ * Author: Markos Chandras <markos.chandras@imgtec.com>
13+ *
14+ * This program is free software; you can distribute it and/or modify it
15+ * under the terms of the GNU General Public License as published by the
16+ * Free Software Foundation; version 2 of the License.
17+ */
18+
19+#include "ieee754sp.h"
20+
21+union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y)
22+{
23+ COMPXSP;
24+ COMPYSP;
25+
26+ EXPLODEXSP;
27+ EXPLODEYSP;
28+
29+ FLUSHXSP;
30+ FLUSHYSP;
31+
32+ ieee754_clearcx();
33+
34+ switch (CLPAIR(xc, yc)) {
35+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
36+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
37+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
38+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
39+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
40+ return ieee754sp_nanxcpt(y);
41+
42+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
43+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
44+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
45+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
46+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
47+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
48+ return ieee754sp_nanxcpt(x);
49+
50+ /* numbers are preferred to NaNs */
51+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
52+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
53+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
54+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
55+ return x;
56+
57+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
58+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
59+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
60+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
61+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
62+ return y;
63+
64+ /*
65+ * Infinity and zero handling
66+ */
67+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
68+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
69+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
70+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
71+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
72+ return xs ? y : x;
73+
74+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
75+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
76+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
77+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
78+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
79+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
80+ return ys ? x : y;
81+
82+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
83+ if (xs == ys)
84+ return x;
85+ return ieee754sp_zero(1);
86+
87+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
88+ SPDNORMX;
89+
90+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
91+ SPDNORMY;
92+ break;
93+
94+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
95+ SPDNORMX;
96+ }
97+
98+ /* Finally get to do some computation */
99+
100+ assert(xm & SP_HIDDEN_BIT);
101+ assert(ym & SP_HIDDEN_BIT);
102+
103+ /* Compare signs */
104+ if (xs > ys)
105+ return y;
106+ else if (xs < ys)
107+ return x;
108+
109+ /* Compare exponent */
110+ if (xe > ye)
111+ return x;
112+ else if (xe < ye)
113+ return y;
114+
115+ /* Compare mantissa */
116+ if (xm <= ym)
117+ return y;
118+ return x;
119+}
120+
121+union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y)
122+{
123+ COMPXSP;
124+ COMPYSP;
125+
126+ EXPLODEXSP;
127+ EXPLODEYSP;
128+
129+ FLUSHXSP;
130+ FLUSHYSP;
131+
132+ ieee754_clearcx();
133+
134+ switch (CLPAIR(xc, yc)) {
135+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
136+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
137+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
138+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
139+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
140+ return ieee754sp_nanxcpt(y);
141+
142+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
143+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
144+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
145+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
146+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
147+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
148+ return ieee754sp_nanxcpt(x);
149+
150+ /* numbers are preferred to NaNs */
151+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
152+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
153+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
154+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
155+ return x;
156+
157+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
158+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
159+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
160+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
161+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
162+ return y;
163+
164+ /*
165+ * Infinity and zero handling
166+ */
167+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
168+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
169+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
170+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
171+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
172+ return x;
173+
174+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
175+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
176+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
177+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
178+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
179+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
180+ return y;
181+
182+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
183+ if (xs == ys)
184+ return x;
185+ return ieee754sp_zero(1);
186+
187+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
188+ SPDNORMX;
189+
190+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
191+ SPDNORMY;
192+ break;
193+
194+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
195+ SPDNORMX;
196+ }
197+
198+ /* Finally get to do some computation */
199+
200+ assert(xm & SP_HIDDEN_BIT);
201+ assert(ym & SP_HIDDEN_BIT);
202+
203+ /* Compare exponent */
204+ if (xe > ye)
205+ return x;
206+ else if (xe < ye)
207+ return y;
208+
209+ /* Compare mantissa */
210+ if (xm <= ym)
211+ return y;
212+ return x;
213+}
arch/mips/math-emu/sp_fmin.c+213−0
@@ -0,0 +1,213 @@
1+/*
2+ * IEEE754 floating point arithmetic
3+ * single precision: MIN{,A}.f
4+ * MIN : Scalar Floating-Point Minimum
5+ * MINA: Scalar Floating-Point argument with Minimum Absolute Value
6+ *
7+ * MIN.S : FPR[fd] = minNum(FPR[fs],FPR[ft])
8+ * MINA.S: FPR[fd] = maxNumMag(FPR[fs],FPR[ft])
9+ *
10+ * MIPS floating point support
11+ * Copyright (C) 2015 Imagination Technologies, Ltd.
12+ * Author: Markos Chandras <markos.chandras@imgtec.com>
13+ *
14+ * This program is free software; you can distribute it and/or modify it
15+ * under the terms of the GNU General Public License as published by the
16+ * Free Software Foundation; version 2 of the License.
17+ */
18+
19+#include "ieee754sp.h"
20+
21+union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y)
22+{
23+ COMPXSP;
24+ COMPYSP;
25+
26+ EXPLODEXSP;
27+ EXPLODEYSP;
28+
29+ FLUSHXSP;
30+ FLUSHYSP;
31+
32+ ieee754_clearcx();
33+
34+ switch (CLPAIR(xc, yc)) {
35+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
36+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
37+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
38+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
39+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
40+ return ieee754sp_nanxcpt(y);
41+
42+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
43+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
44+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
45+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
46+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
47+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
48+ return ieee754sp_nanxcpt(x);
49+
50+ /* numbers are preferred to NaNs */
51+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
52+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
53+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
54+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
55+ return x;
56+
57+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
58+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
59+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
60+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
61+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
62+ return y;
63+
64+ /*
65+ * Infinity and zero handling
66+ */
67+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
68+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
69+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
70+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
71+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
72+ return xs ? x : y;
73+
74+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
75+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
76+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
77+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
78+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
79+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
80+ return ys ? y : x;
81+
82+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
83+ if (xs == ys)
84+ return x;
85+ return ieee754sp_zero(1);
86+
87+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
88+ SPDNORMX;
89+
90+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
91+ SPDNORMY;
92+ break;
93+
94+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
95+ SPDNORMX;
96+ }
97+
98+ /* Finally get to do some computation */
99+
100+ assert(xm & SP_HIDDEN_BIT);
101+ assert(ym & SP_HIDDEN_BIT);
102+
103+ /* Compare signs */
104+ if (xs > ys)
105+ return x;
106+ else if (xs < ys)
107+ return y;
108+
109+ /* Compare exponent */
110+ if (xe > ye)
111+ return y;
112+ else if (xe < ye)
113+ return x;
114+
115+ /* Compare mantissa */
116+ if (xm <= ym)
117+ return x;
118+ return y;
119+}
120+
121+union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y)
122+{
123+ COMPXSP;
124+ COMPYSP;
125+
126+ EXPLODEXSP;
127+ EXPLODEYSP;
128+
129+ FLUSHXSP;
130+ FLUSHYSP;
131+
132+ ieee754_clearcx();
133+
134+ switch (CLPAIR(xc, yc)) {
135+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
136+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
137+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
138+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
139+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
140+ return ieee754sp_nanxcpt(y);
141+
142+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
143+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
144+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
145+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
146+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
147+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
148+ return ieee754sp_nanxcpt(x);
149+
150+ /* numbers are preferred to NaNs */
151+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
152+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
153+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
154+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
155+ return x;
156+
157+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
158+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
159+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
160+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
161+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
162+ return y;
163+
164+ /*
165+ * Infinity and zero handling
166+ */
167+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
168+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
169+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
170+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
171+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
172+ return x;
173+
174+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
175+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
176+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
177+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
178+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
179+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
180+ return y;
181+
182+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
183+ if (xs == ys)
184+ return x;
185+ return ieee754sp_zero(1);
186+
187+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
188+ SPDNORMX;
189+
190+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
191+ SPDNORMY;
192+ break;
193+
194+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
195+ SPDNORMX;
196+ }
197+
198+ /* Finally get to do some computation */
199+
200+ assert(xm & SP_HIDDEN_BIT);
201+ assert(ym & SP_HIDDEN_BIT);
202+
203+ /* Compare exponent */
204+ if (xe > ye)
205+ return y;
206+ else if (xe < ye)
207+ return x;
208+
209+ /* Compare mantissa */
210+ if (xm <= ym)
211+ return x;
212+ return y;
213+}
arch/mips/math-emu/sp_maddf.c+255−0
@@ -0,0 +1,255 @@
1+/*
2+ * IEEE754 floating point arithmetic
3+ * single precision: MADDF.f (Fused Multiply Add)
4+ * MADDF.fmt: FPR[fd] = FPR[fd] + (FPR[fs] x FPR[ft])
5+ *
6+ * MIPS floating point support
7+ * Copyright (C) 2015 Imagination Technologies, Ltd.
8+ * Author: Markos Chandras <markos.chandras@imgtec.com>
9+ *
10+ * This program is free software; you can distribute it and/or modify it
11+ * under the terms of the GNU General Public License as published by the
12+ * Free Software Foundation; version 2 of the License.
13+ */
14+
15+#include "ieee754sp.h"
16+
17+union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x,
18+ union ieee754sp y)
19+{
20+ int re;
21+ int rs;
22+ unsigned rm;
23+ unsigned short lxm;
24+ unsigned short hxm;
25+ unsigned short lym;
26+ unsigned short hym;
27+ unsigned lrm;
28+ unsigned hrm;
29+ unsigned t;
30+ unsigned at;
31+ int s;
32+
33+ COMPXSP;
34+ COMPYSP;
35+ u32 zm; int ze; int zs __maybe_unused; int zc;
36+
37+ EXPLODEXSP;
38+ EXPLODEYSP;
39+ EXPLODESP(z, zc, zs, ze, zm)
40+
41+ FLUSHXSP;
42+ FLUSHYSP;
43+ FLUSHSP(z, zc, zs, ze, zm);
44+
45+ ieee754_clearcx();
46+
47+ switch (zc) {
48+ case IEEE754_CLASS_SNAN:
49+ ieee754_setcx(IEEE754_INVALID_OPERATION);
50+ return ieee754sp_nanxcpt(z);
51+ case IEEE754_CLASS_DNORM:
52+ SPDNORMx(zm, ze);
53+ /* QNAN is handled separately below */
54+ }
55+
56+ switch (CLPAIR(xc, yc)) {
57+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
58+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
59+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
60+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
61+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
62+ return ieee754sp_nanxcpt(y);
63+
64+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
65+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
66+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
67+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
68+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
69+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
70+ return ieee754sp_nanxcpt(x);
71+
72+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
73+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
74+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
75+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
76+ return y;
77+
78+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
79+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
80+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
81+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
82+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
83+ return x;
84+
85+ /*
86+ * Infinity handling
87+ */
88+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
89+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
90+ if (zc == IEEE754_CLASS_QNAN)
91+ return z;
92+ ieee754_setcx(IEEE754_INVALID_OPERATION);
93+ return ieee754sp_indef();
94+
95+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
96+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
97+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
98+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
99+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
100+ if (zc == IEEE754_CLASS_QNAN)
101+ return z;
102+ return ieee754sp_inf(xs ^ ys);
103+
104+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
105+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
106+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
107+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
108+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
109+ if (zc == IEEE754_CLASS_INF)
110+ return ieee754sp_inf(zs);
111+ /* Multiplication is 0 so just return z */
112+ return z;
113+
114+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
115+ SPDNORMX;
116+
117+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
118+ if (zc == IEEE754_CLASS_QNAN)
119+ return z;
120+ else if (zc == IEEE754_CLASS_INF)
121+ return ieee754sp_inf(zs);
122+ SPDNORMY;
123+ break;
124+
125+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
126+ if (zc == IEEE754_CLASS_QNAN)
127+ return z;
128+ else if (zc == IEEE754_CLASS_INF)
129+ return ieee754sp_inf(zs);
130+ SPDNORMX;
131+ break;
132+
133+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
134+ if (zc == IEEE754_CLASS_QNAN)
135+ return z;
136+ else if (zc == IEEE754_CLASS_INF)
137+ return ieee754sp_inf(zs);
138+ /* fall through to real computations */
139+ }
140+
141+ /* Finally get to do some computation */
142+
143+ /*
144+ * Do the multiplication bit first
145+ *
146+ * rm = xm * ym, re = xe + ye basically
147+ *
148+ * At this point xm and ym should have been normalized.
149+ */
150+
151+ /* rm = xm * ym, re = xe+ye basically */
152+ assert(xm & SP_HIDDEN_BIT);
153+ assert(ym & SP_HIDDEN_BIT);
154+
155+ re = xe + ye;
156+ rs = xs ^ ys;
157+
158+ /* shunt to top of word */
159+ xm <<= 32 - (SP_FBITS + 1);
160+ ym <<= 32 - (SP_FBITS + 1);
161+
162+ /*
163+ * Multiply 32 bits xm, ym to give high 32 bits rm with stickness.
164+ */
165+ lxm = xm & 0xffff;
166+ hxm = xm >> 16;
167+ lym = ym & 0xffff;
168+ hym = ym >> 16;
169+
170+ lrm = lxm * lym; /* 16 * 16 => 32 */
171+ hrm = hxm * hym; /* 16 * 16 => 32 */
172+
173+ t = lxm * hym; /* 16 * 16 => 32 */
174+ at = lrm + (t << 16);
175+ hrm += at < lrm;
176+ lrm = at;
177+ hrm = hrm + (t >> 16);
178+
179+ t = hxm * lym; /* 16 * 16 => 32 */
180+ at = lrm + (t << 16);
181+ hrm += at < lrm;
182+ lrm = at;
183+ hrm = hrm + (t >> 16);
184+
185+ rm = hrm | (lrm != 0);
186+
187+ /*
188+ * Sticky shift down to normal rounding precision.
189+ */
190+ if ((int) rm < 0) {
191+ rm = (rm >> (32 - (SP_FBITS + 1 + 3))) |
192+ ((rm << (SP_FBITS + 1 + 3)) != 0);
193+ re++;
194+ } else {
195+ rm = (rm >> (32 - (SP_FBITS + 1 + 3 + 1))) |
196+ ((rm << (SP_FBITS + 1 + 3 + 1)) != 0);
197+ }
198+ assert(rm & (SP_HIDDEN_BIT << 3));
199+
200+ /* And now the addition */
201+
202+ assert(zm & SP_HIDDEN_BIT);
203+
204+ /*
205+ * Provide guard,round and stick bit space.
206+ */
207+ zm <<= 3;
208+
209+ if (ze > re) {
210+ /*
211+ * Have to shift y fraction right to align.
212+ */
213+ s = ze - re;
214+ SPXSRSYn(s);
215+ } else if (re > ze) {
216+ /*
217+ * Have to shift x fraction right to align.
218+ */
219+ s = re - ze;
220+ SPXSRSYn(s);
221+ }
222+ assert(ze == re);
223+ assert(ze <= SP_EMAX);
224+
225+ if (zs == rs) {
226+ /*
227+ * Generate 28 bit result of adding two 27 bit numbers
228+ * leaving result in zm, zs and ze.
229+ */
230+ zm = zm + rm;
231+
232+ if (zm >> (SP_FBITS + 1 + 3)) { /* carry out */
233+ SPXSRSX1();
234+ }
235+ } else {
236+ if (zm >= rm) {
237+ zm = zm - rm;
238+ } else {
239+ zm = rm - zm;
240+ zs = rs;
241+ }
242+ if (zm == 0)
243+ return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD);
244+
245+ /*
246+ * Normalize in extended single precision
247+ */
248+ while ((zm >> (SP_MBITS + 3)) == 0) {
249+ zm <<= 1;
250+ ze--;
251+ }
252+
253+ }
254+ return ieee754sp_format(zs, ze, zm);
255+}
arch/mips/math-emu/sp_msubf.c+258−0
@@ -0,0 +1,258 @@
1+/*
2+ * IEEE754 floating point arithmetic
3+ * single precision: MSUB.f (Fused Multiply Subtract)
4+ * MSUBF.fmt: FPR[fd] = FPR[fd] - (FPR[fs] x FPR[ft])
5+ *
6+ * MIPS floating point support
7+ * Copyright (C) 2015 Imagination Technologies, Ltd.
8+ * Author: Markos Chandras <markos.chandras@imgtec.com>
9+ *
10+ * This program is free software; you can distribute it and/or modify it
11+ * under the terms of the GNU General Public License as published by the
12+ * Free Software Foundation; version 2 of the License.
13+ */
14+
15+#include "ieee754sp.h"
16+
17+union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x,
18+ union ieee754sp y)
19+{
20+ int re;
21+ int rs;
22+ unsigned rm;
23+ unsigned short lxm;
24+ unsigned short hxm;
25+ unsigned short lym;
26+ unsigned short hym;
27+ unsigned lrm;
28+ unsigned hrm;
29+ unsigned t;
30+ unsigned at;
31+ int s;
32+
33+ COMPXSP;
34+ COMPYSP;
35+ u32 zm; int ze; int zs __maybe_unused; int zc;
36+
37+ EXPLODEXSP;
38+ EXPLODEYSP;
39+ EXPLODESP(z, zc, zs, ze, zm)
40+
41+ FLUSHXSP;
42+ FLUSHYSP;
43+ FLUSHSP(z, zc, zs, ze, zm);
44+
45+ ieee754_clearcx();
46+
47+ switch (zc) {
48+ case IEEE754_CLASS_SNAN:
49+ ieee754_setcx(IEEE754_INVALID_OPERATION);
50+ return ieee754sp_nanxcpt(z);
51+ case IEEE754_CLASS_DNORM:
52+ SPDNORMx(zm, ze);
53+ /* QNAN is handled separately below */
54+ }
55+
56+ switch (CLPAIR(xc, yc)) {
57+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
58+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
59+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
60+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
61+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
62+ return ieee754sp_nanxcpt(y);
63+
64+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
65+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
66+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
67+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
68+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
69+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
70+ return ieee754sp_nanxcpt(x);
71+
72+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
73+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
74+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
75+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
76+ return y;
77+
78+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
79+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
80+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
81+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
82+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
83+ return x;
84+
85+ /*
86+ * Infinity handling
87+ */
88+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
89+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
90+ if (zc == IEEE754_CLASS_QNAN)
91+ return z;
92+ ieee754_setcx(IEEE754_INVALID_OPERATION);
93+ return ieee754sp_indef();
94+
95+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
96+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
97+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
98+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
99+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
100+ if (zc == IEEE754_CLASS_QNAN)
101+ return z;
102+ return ieee754sp_inf(xs ^ ys);
103+
104+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
105+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
106+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
107+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
108+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
109+ if (zc == IEEE754_CLASS_INF)
110+ return ieee754sp_inf(zs);
111+ /* Multiplication is 0 so just return z */
112+ return z;
113+
114+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
115+ SPDNORMX;
116+
117+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
118+ if (zc == IEEE754_CLASS_QNAN)
119+ return z;
120+ else if (zc == IEEE754_CLASS_INF)
121+ return ieee754sp_inf(zs);
122+ SPDNORMY;
123+ break;
124+
125+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
126+ if (zc == IEEE754_CLASS_QNAN)
127+ return z;
128+ else if (zc == IEEE754_CLASS_INF)
129+ return ieee754sp_inf(zs);
130+ SPDNORMX;
131+ break;
132+
133+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
134+ if (zc == IEEE754_CLASS_QNAN)
135+ return z;
136+ else if (zc == IEEE754_CLASS_INF)
137+ return ieee754sp_inf(zs);
138+ /* fall through to real compuation */
139+ }
140+
141+ /* Finally get to do some computation */
142+
143+ /*
144+ * Do the multiplication bit first
145+ *
146+ * rm = xm * ym, re = xe + ye basically
147+ *
148+ * At this point xm and ym should have been normalized.
149+ */
150+
151+ /* rm = xm * ym, re = xe+ye basically */
152+ assert(xm & SP_HIDDEN_BIT);
153+ assert(ym & SP_HIDDEN_BIT);
154+
155+ re = xe + ye;
156+ rs = xs ^ ys;
157+
158+ /* shunt to top of word */
159+ xm <<= 32 - (SP_FBITS + 1);
160+ ym <<= 32 - (SP_FBITS + 1);
161+
162+ /*
163+ * Multiply 32 bits xm, ym to give high 32 bits rm with stickness.
164+ */
165+ lxm = xm & 0xffff;
166+ hxm = xm >> 16;
167+ lym = ym & 0xffff;
168+ hym = ym >> 16;
169+
170+ lrm = lxm * lym; /* 16 * 16 => 32 */
171+ hrm = hxm * hym; /* 16 * 16 => 32 */
172+
173+ t = lxm * hym; /* 16 * 16 => 32 */
174+ at = lrm + (t << 16);
175+ hrm += at < lrm;
176+ lrm = at;
177+ hrm = hrm + (t >> 16);
178+
179+ t = hxm * lym; /* 16 * 16 => 32 */
180+ at = lrm + (t << 16);
181+ hrm += at < lrm;
182+ lrm = at;
183+ hrm = hrm + (t >> 16);
184+
185+ rm = hrm | (lrm != 0);
186+
187+ /*
188+ * Sticky shift down to normal rounding precision.
189+ */
190+ if ((int) rm < 0) {
191+ rm = (rm >> (32 - (SP_FBITS + 1 + 3))) |
192+ ((rm << (SP_FBITS + 1 + 3)) != 0);
193+ re++;
194+ } else {
195+ rm = (rm >> (32 - (SP_FBITS + 1 + 3 + 1))) |
196+ ((rm << (SP_FBITS + 1 + 3 + 1)) != 0);
197+ }
198+ assert(rm & (SP_HIDDEN_BIT << 3));
199+
200+ /* And now the subtraction */
201+
202+ /* Flip sign of r and handle as add */
203+ rs ^= 1;
204+
205+ assert(zm & SP_HIDDEN_BIT);
206+
207+ /*
208+ * Provide guard,round and stick bit space.
209+ */
210+ zm <<= 3;
211+
212+ if (ze > re) {
213+ /*
214+ * Have to shift y fraction right to align.
215+ */
216+ s = ze - re;
217+ SPXSRSYn(s);
218+ } else if (re > ze) {
219+ /*
220+ * Have to shift x fraction right to align.
221+ */
222+ s = re - ze;
223+ SPXSRSYn(s);
224+ }
225+ assert(ze == re);
226+ assert(ze <= SP_EMAX);
227+
228+ if (zs == rs) {
229+ /*
230+ * Generate 28 bit result of adding two 27 bit numbers
231+ * leaving result in zm, zs and ze.
232+ */
233+ zm = zm + rm;
234+
235+ if (zm >> (SP_FBITS + 1 + 3)) { /* carry out */
236+ SPXSRSX1(); /* shift preserving sticky */
237+ }
238+ } else {
239+ if (zm >= rm) {
240+ zm = zm - rm;
241+ } else {
242+ zm = rm - zm;
243+ zs = rs;
244+ }
245+ if (zm == 0)
246+ return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD);
247+
248+ /*
249+ * Normalize in extended single precision
250+ */
251+ while ((zm >> (SP_MBITS + 3)) == 0) {
252+ zm <<= 1;
253+ ze--;
254+ }
255+
256+ }
257+ return ieee754sp_format(zs, ze, zm);
258+}
arch/mips/mm/c-r4k.c+1−0
@@ -1276,6 +1276,7 @@ static void probe_pcache(void) · 1275 unmodified lines
12761276 case CPU_PROAPTIV:
12771277 case CPU_M5150:
12781278 case CPU_QEMU_GENERIC:
1279+ case CPU_I6400:
12791280 if (!(read_c0_config7() & MIPS_CONF7_IAR) &&
12801281 (c->icache.waysize > PAGE_SIZE))
12811282 c->icache.flags |= MIPS_CACHE_ALIASES;
arch/mips/mm/dma-default.c+35−0
@@ -194,6 +194,40 @@ static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, · 193 unmodified lines
194194 __free_pages(page, get_order(size));
195195 }
196196
197+static int mips_dma_mmap(struct device *dev, struct vm_area_struct *vma,
198+ void *cpu_addr, dma_addr_t dma_addr, size_t size,
199+ struct dma_attrs *attrs)
200+{
201+ unsigned long user_count = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
202+ unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
203+ unsigned long addr = (unsigned long)cpu_addr;
204+ unsigned long off = vma->vm_pgoff;
205+ unsigned long pfn;
206+ int ret = -ENXIO;
207+
208+ if (!plat_device_is_coherent(dev) && !hw_coherentio)
209+ addr = CAC_ADDR(addr);
210+
211+ pfn = page_to_pfn(virt_to_page((void *)addr));
212+
213+ if (dma_get_attr(DMA_ATTR_WRITE_COMBINE, attrs))
214+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
215+ else
216+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
217+
218+ if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
219+ return ret;
220+
221+ if (off < count && user_count <= (count - off)) {
222+ ret = remap_pfn_range(vma, vma->vm_start,
223+ pfn + off,
224+ user_count << PAGE_SHIFT,
225+ vma->vm_page_prot);
226+ }
227+
228+ return ret;
229+}
230+
197231 static inline void __dma_sync_virtual(void *addr, size_t size,
198232 enum dma_data_direction direction)
199233 {
@@ -380,6 +414,7 @@ EXPORT_SYMBOL(dma_cache_sync); · 180 unmodified lines
380414 static struct dma_map_ops mips_default_dma_map_ops = {
381415 .alloc = mips_dma_alloc_coherent,
382416 .free = mips_dma_free_coherent,
417+ .mmap = mips_dma_mmap,
383418 .map_page = mips_dma_map_page,
384419 .unmap_page = mips_dma_unmap_page,
385420 .map_sg = mips_dma_map_sg,
arch/mips/mm/fault.c+4−4
@@ -57,12 +57,10 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write, · 56 unmodified lines
5757
5858 #ifdef CONFIG_KPROBES
5959 /*
60− * This is to notify the fault handler of the kprobes. The
61− * exception code is redundant as it is also carried in REGS,
62− * but we pass it anyhow.
60+ * This is to notify the fault handler of the kprobes.
6361 */
6462 if (notify_die(DIE_PAGE_FAULT, "page fault", regs, -1,
65− (regs->cp0_cause >> 2) & 0x1f, SIGSEGV) == NOTIFY_STOP)
63+ current->thread.trap_nr, SIGSEGV) == NOTIFY_STOP)
6664 return;
6765 #endif
6866
@@ -224,6 +222,7 @@ bad_area_nosemaphore: · 155 unmodified lines
224222 print_vma_addr(" ", regs->regs[31]);
225223 pr_info("\n");
226224 }
225+ current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
227226 info.si_signo = SIGSEGV;
228227 info.si_errno = 0;
229228 /* info.si_code has been set above */
@@ -282,6 +281,7 @@ do_sigbus: · 52 unmodified lines
282281 field, (unsigned long) regs->cp0_epc,
283282 field, (unsigned long) regs->regs[31]);
284283 #endif
284+ current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
285285 tsk->thread.cp0_badvaddr = address;
286286 info.si_signo = SIGBUS;
287287 info.si_errno = 0;
arch/mips/mm/init.c+34−2
@@ -37,6 +37,7 @@ · 36 unmodified lines
3737 #include <asm/cpu.h>
3838 #include <asm/dma.h>
3939 #include <asm/kmap_types.h>
40+#include <asm/maar.h>
4041 #include <asm/mmu_context.h>
4142 #include <asm/sections.h>
4243 #include <asm/pgtable.h>
@@ -333,9 +334,40 @@ static inline void mem_init_free_highmem(void) · 290 unmodified lines
333334 #endif
334335 }
335336
336−unsigned __weak platform_maar_init(unsigned num_maars)
337+unsigned __weak platform_maar_init(unsigned num_pairs)
337338 {
338− return 0;
339+ struct maar_config cfg[BOOT_MEM_MAP_MAX];
340+ unsigned i, num_configured, num_cfg = 0;
341+ phys_addr_t skip;
342+
343+ for (i = 0; i < boot_mem_map.nr_map; i++) {
344+ switch (boot_mem_map.map[i].type) {
345+ case BOOT_MEM_RAM:
346+ case BOOT_MEM_INIT_RAM:
347+ break;
348+ default:
349+ continue;
350+ }
351+
352+ skip = 0x10000 - (boot_mem_map.map[i].addr & 0xffff);
353+
354+ cfg[num_cfg].lower = boot_mem_map.map[i].addr;
355+ cfg[num_cfg].lower += skip;
356+
357+ cfg[num_cfg].upper = cfg[num_cfg].lower;
358+ cfg[num_cfg].upper += boot_mem_map.map[i].size - 1;
359+ cfg[num_cfg].upper -= skip;
360+
361+ cfg[num_cfg].attrs = MIPS_MAAR_S;
362+ num_cfg++;
363+ }
364+
365+ num_configured = maar_config(cfg, num_cfg, num_pairs);
366+ if (num_configured < num_cfg)
367+ pr_warn("Not enough MAAR pairs (%u) for all bootmem regions (%u)\n",
368+ num_pairs, num_cfg);
369+
370+ return num_configured;
339371 }
340372
341373 static void maar_init(void)
arch/mips/mm/sc-mips.c+42−0
@@ -14,6 +14,7 @@ · 13 unmodified lines
1414 #include <asm/pgtable.h>
1515 #include <asm/mmu_context.h>
1616 #include <asm/r4kcache.h>
17+#include <asm/mips-cm.h>
1718
1819 /*
1920 * MIPS32/MIPS64 L2 cache handling
@@ -94,6 +95,38 @@ static inline int mips_sc_is_activated(struct cpuinfo_mips *c) · 74 unmodified lines
9495 return 1;
9596 }
9697
98+static int __init mips_sc_probe_cm3(void)
99+{
100+ struct cpuinfo_mips *c = &current_cpu_data;
101+ unsigned long cfg = read_gcr_l2_config();
102+ unsigned long sets, line_sz, assoc;
103+
104+ if (cfg & CM_GCR_L2_CONFIG_BYPASS_MSK)
105+ return 0;
106+
107+ sets = cfg & CM_GCR_L2_CONFIG_SET_SIZE_MSK;
108+ sets >>= CM_GCR_L2_CONFIG_SET_SIZE_SHF;
109+ c->scache.sets = 64 << sets;
110+
111+ line_sz = cfg & CM_GCR_L2_CONFIG_LINE_SIZE_MSK;
112+ line_sz >>= CM_GCR_L2_CONFIG_LINE_SIZE_SHF;
113+ c->scache.linesz = 2 << line_sz;
114+
115+ assoc = cfg & CM_GCR_L2_CONFIG_ASSOC_MSK;
116+ assoc >>= CM_GCR_L2_CONFIG_ASSOC_SHF;
117+ c->scache.ways = assoc + 1;
118+ c->scache.waysize = c->scache.sets * c->scache.linesz;
119+ c->scache.waybit = __ffs(c->scache.waysize);
120+
121+ c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
122+
123+ return 1;
124+}
125+
126+void __weak platform_early_l2_init(void)
127+{
128+}
129+
97130 static inline int __init mips_sc_probe(void)
98131 {
99132 struct cpuinfo_mips *c = &current_cpu_data;
@@ -103,6 +136,15 @@ static inline int __init mips_sc_probe(void) · 3 unmodified lines
103136 /* Mark as not present until probe completed */
104137 c->scache.flags |= MIPS_CACHE_NOT_PRESENT;
105138
139+ /*
140+ * Do we need some platform specific probing before
141+ * we configure L2?
142+ */
143+ platform_early_l2_init();
144+
145+ if (mips_cm_revision() >= CM_REV_CM3)
146+ return mips_sc_probe_cm3();
147+
106148 /* Ignore anything but MIPSxx processors */
107149 if (!(c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 |
108150 MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R1 |
arch/mips/mm/tlb-r3k.c+1−1
@@ -36,7 +36,7 @@ extern void build_tlb_refill_handler(void); · 35 unmodified lines
3636 "nop\n\t" \
3737 ".set pop\n\t")
3838
39−static int r3k_have_wired_reg; /* Should be in cpu_data? */
39+int r3k_have_wired_reg; /* Should be in cpu_data? */
4040
4141 /* TLB operations. */
4242 static void local_flush_tlb_from(int entry)
arch/mips/mti-malta/malta-init.c+7−0
@@ -303,3 +303,10 @@ mips_pci_controller: · 302 unmodified lines
303303 if (!register_vsmp_smp_ops())
304304 return;
305305 }
306+
307+void platform_early_l2_init(void)
308+{
309+ /* L2 configuration lives in the CM3 */
310+ if (mips_cm_revision() >= CM_REV_CM3)
311+ mips_cm_probe();
312+}
arch/mips/mti-malta/malta-int.c+1−111
@@ -382,122 +382,12 @@ void malta_be_init(void) · 381 unmodified lines
382382 /* Could change CM error mask register. */
383383 }
384384
385−
386−static char *tr[8] = {
387− "mem", "gcr", "gic", "mmio",
388− "0x04", "0x05", "0x06", "0x07"
389−};
390−
391−static char *mcmd[32] = {
392− [0x00] = "0x00",
393− [0x01] = "Legacy Write",
394− [0x02] = "Legacy Read",
395− [0x03] = "0x03",
396− [0x04] = "0x04",
397− [0x05] = "0x05",
398− [0x06] = "0x06",
399− [0x07] = "0x07",
400− [0x08] = "Coherent Read Own",
401− [0x09] = "Coherent Read Share",
402− [0x0a] = "Coherent Read Discard",
403− [0x0b] = "Coherent Ready Share Always",
404− [0x0c] = "Coherent Upgrade",
405− [0x0d] = "Coherent Writeback",
406− [0x0e] = "0x0e",
407− [0x0f] = "0x0f",
408− [0x10] = "Coherent Copyback",
409− [0x11] = "Coherent Copyback Invalidate",
410− [0x12] = "Coherent Invalidate",
411− [0x13] = "Coherent Write Invalidate",
412− [0x14] = "Coherent Completion Sync",
413− [0x15] = "0x15",
414− [0x16] = "0x16",
415− [0x17] = "0x17",
416− [0x18] = "0x18",
417− [0x19] = "0x19",
418− [0x1a] = "0x1a",
419− [0x1b] = "0x1b",
420− [0x1c] = "0x1c",
421− [0x1d] = "0x1d",
422− [0x1e] = "0x1e",
423− [0x1f] = "0x1f"
424−};
425−
426−static char *core[8] = {
427− "Invalid/OK", "Invalid/Data",
428− "Shared/OK", "Shared/Data",
429− "Modified/OK", "Modified/Data",
430− "Exclusive/OK", "Exclusive/Data"
431−};
432−
433−static char *causes[32] = {
434− "None", "GC_WR_ERR", "GC_RD_ERR", "COH_WR_ERR",
435− "COH_RD_ERR", "MMIO_WR_ERR", "MMIO_RD_ERR", "0x07",
436− "0x08", "0x09", "0x0a", "0x0b",
437− "0x0c", "0x0d", "0x0e", "0x0f",
438− "0x10", "0x11", "0x12", "0x13",
439− "0x14", "0x15", "0x16", "INTVN_WR_ERR",
440− "INTVN_RD_ERR", "0x19", "0x1a", "0x1b",
441− "0x1c", "0x1d", "0x1e", "0x1f"
442−};
443−
444385 int malta_be_handler(struct pt_regs *regs, int is_fixup)
445386 {
446387 /* This duplicates the handling in do_be which seems wrong */
447388 int retval = is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL;
448389
449− if (mips_cm_present()) {
450− unsigned long cm_error = read_gcr_error_cause();
451− unsigned long cm_addr = read_gcr_error_addr();
452− unsigned long cm_other = read_gcr_error_mult();
453− unsigned long cause, ocause;
454− char buf[256];
455−
456− cause = cm_error & CM_GCR_ERROR_CAUSE_ERRTYPE_MSK;
457− if (cause != 0) {
458− cause >>= CM_GCR_ERROR_CAUSE_ERRTYPE_SHF;
459− if (cause < 16) {
460− unsigned long cca_bits = (cm_error >> 15) & 7;
461− unsigned long tr_bits = (cm_error >> 12) & 7;
462− unsigned long cmd_bits = (cm_error >> 7) & 0x1f;
463− unsigned long stag_bits = (cm_error >> 3) & 15;
464− unsigned long sport_bits = (cm_error >> 0) & 7;
465−
466− snprintf(buf, sizeof(buf),
467− "CCA=%lu TR=%s MCmd=%s STag=%lu "
468− "SPort=%lu\n",
469− cca_bits, tr[tr_bits], mcmd[cmd_bits],
470− stag_bits, sport_bits);
471− } else {
472− /* glob state & sresp together */
473− unsigned long c3_bits = (cm_error >> 18) & 7;
474− unsigned long c2_bits = (cm_error >> 15) & 7;
475− unsigned long c1_bits = (cm_error >> 12) & 7;
476− unsigned long c0_bits = (cm_error >> 9) & 7;
477− unsigned long sc_bit = (cm_error >> 8) & 1;
478− unsigned long cmd_bits = (cm_error >> 3) & 0x1f;
479− unsigned long sport_bits = (cm_error >> 0) & 7;
480− snprintf(buf, sizeof(buf),
481− "C3=%s C2=%s C1=%s C0=%s SC=%s "
482− "MCmd=%s SPort=%lu\n",
483− core[c3_bits], core[c2_bits],
484− core[c1_bits], core[c0_bits],
485− sc_bit ? "True" : "False",
486− mcmd[cmd_bits], sport_bits);
487− }
488−
489− ocause = (cm_other & CM_GCR_ERROR_MULT_ERR2ND_MSK) >>
490− CM_GCR_ERROR_MULT_ERR2ND_SHF;
491−
492− pr_err("CM_ERROR=%08lx %s <%s>\n", cm_error,
493− causes[cause], buf);
494− pr_err("CM_ADDR =%08lx\n", cm_addr);
495− pr_err("CM_OTHER=%08lx %s\n", cm_other, causes[ocause]);
496−
497− /* reprime cause register */
498− write_gcr_error_cause(0);
499− }
500− }
390+ mips_cm_error_report();
501391
502392 return retval;
503393 }
arch/mips/mti-malta/malta-memory.c+0−25
@@ -179,31 +179,6 @@ void __init prom_free_prom_memory(void) · 178 unmodified lines
179179 }
180180 }
181181
182−unsigned platform_maar_init(unsigned num_pairs)
183−{
184− phys_addr_t mem_end = (physical_memsize & ~0xffffull) - 1;
185− struct maar_config cfg[] = {
186− /* DRAM preceding I/O */
187− { 0x00000000, 0x0fffffff, MIPS_MAAR_S },
188−
189− /* DRAM following I/O */
190− { 0x20000000, mem_end, MIPS_MAAR_S },
191−
192− /* DRAM alias in upper half of physical */
193− { 0x80000000, 0x80000000 + mem_end, MIPS_MAAR_S },
194− };
195− unsigned i, num_cfg = ARRAY_SIZE(cfg);
196−
197− /* If DRAM fits before I/O, drop the region following it */
198− if (physical_memsize <= 0x10000000) {
199− num_cfg--;
200− for (i = 1; i < num_cfg; i++)
201− cfg[i] = cfg[i + 1];
202− }
203−
204− return maar_config(cfg, num_cfg, num_pairs);
205−}
206−
207182 phys_addr_t mips_cdmm_phys_base(void)
208183 {
209184 /* This address is "typically unused" */
arch/mips/netlogic/common/irq.c+6−6
@@ -87,7 +87,7 @@ struct nlm_pic_irq { · 86 unmodified lines
8787 static void xlp_pic_enable(struct irq_data *d)
8888 {
8989 unsigned long flags;
90− struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d);
90+ struct nlm_pic_irq *pd = irq_data_get_irq_chip_data(d);
9191
9292 BUG_ON(!pd);
9393 spin_lock_irqsave(&pd->node->piclock, flags);
@@ -97,7 +97,7 @@ static void xlp_pic_enable(struct irq_data *d) · 3 unmodified lines
9797
9898 static void xlp_pic_disable(struct irq_data *d)
9999 {
100− struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d);
100+ struct nlm_pic_irq *pd = irq_data_get_irq_chip_data(d);
101101 unsigned long flags;
102102
103103 BUG_ON(!pd);
@@ -108,7 +108,7 @@ static void xlp_pic_disable(struct irq_data *d) · 4 unmodified lines
108108
109109 static void xlp_pic_mask_ack(struct irq_data *d)
110110 {
111− struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d);
111+ struct nlm_pic_irq *pd = irq_data_get_irq_chip_data(d);
112112
113113 clear_c0_eimr(pd->picirq);
114114 ack_c0_eirr(pd->picirq);
@@ -116,7 +116,7 @@ static void xlp_pic_mask_ack(struct irq_data *d) · 1 unmodified line
116116
117117 static void xlp_pic_unmask(struct irq_data *d)
118118 {
119− struct nlm_pic_irq *pd = irq_data_get_irq_handler_data(d);
119+ struct nlm_pic_irq *pd = irq_data_get_irq_chip_data(d);
120120
121121 BUG_ON(!pd);
122122
@@ -193,7 +193,7 @@ void nlm_setup_pic_irq(int node, int picirq, int irq, int irt) · 70 unmodified lines
193193 pic_data->picirq = picirq;
194194 pic_data->node = nlm_get_node(node);
195195 irq_set_chip_and_handler(xirq, &xlp_pic, handle_level_irq);
196− irq_set_handler_data(xirq, pic_data);
196+ irq_set_chip_data(xirq, pic_data);
197197 }
198198
199199 void nlm_set_pic_extra_ack(int node, int irq, void (*xack)(struct irq_data *))
@@ -202,7 +202,7 @@ void nlm_set_pic_extra_ack(int node, int irq, void (*xack)(struct irq_data *)) · 2 unmodified lines
202202 int xirq;
203203
204204 xirq = nlm_irq_to_xirq(node, irq);
205− pic_data = irq_get_handler_data(xirq);
205+ pic_data = irq_get_chip_data(xirq);
206206 if (WARN_ON(!pic_data))
207207 return;
208208 pic_data->extra_ack = xack;
arch/mips/netlogic/common/smp.c+4−2
@@ -82,8 +82,9 @@ void nlm_send_ipi_mask(const struct cpumask *mask, unsigned int action) · 81 unmodified lines
8282 }
8383
8484 /* IRQ_IPI_SMP_FUNCTION Handler */
85−void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc)
85+void nlm_smp_function_ipi_handler(unsigned int __irq, struct irq_desc *desc)
8686 {
87+ unsigned int irq = irq_desc_get_irq(desc);
8788 clear_c0_eimr(irq);
8889 ack_c0_eirr(irq);
8990 generic_smp_call_function_interrupt();
@@ -91,8 +92,9 @@ void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc) · 1 unmodified line
9192 }
9293
9394 /* IRQ_IPI_SMP_RESCHEDULE handler */
94−void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc)
95+void nlm_smp_resched_ipi_handler(unsigned int __irq, struct irq_desc *desc)
9596 {
97+ unsigned int irq = irq_desc_get_irq(desc);
9698 clear_c0_eimr(irq);
9799 ack_c0_eirr(irq);
98100 scheduler_ipi();
arch/mips/netlogic/xlp/ahci-init-xlp2.c+1−1
@@ -152,7 +152,7 @@ static const u8 sata_phy_config1[] = { · 151 unmodified lines
152152 0xC9, 0xC9, 0x07, 0x07, 0x18, 0x18, 0x01, 0x01, 0x22, 0x00
153153 };
154154
155−/* SATA PHY config for register block 2 0x0x8065 .. 0x0x80A4 */
155+/* SATA PHY config for register block 2 0x8065 .. 0x80A4 */
156156 static const u8 sata_phy_config2[] = {
157157 0xAA, 0x00, 0x4C, 0xC9, 0xC9, 0x07, 0x07, 0x18,
158158 0x18, 0x05, 0x0C, 0x10, 0x00, 0x10, 0x00, 0xFF,
arch/mips/netlogic/xlp/nlm_hal.c+2−0
@@ -91,6 +91,8 @@ static int xlp9xx_irq_to_irt(int irq) · 90 unmodified lines
9191 return 134;
9292 case PIC_SATA_IRQ:
9393 return 143;
94+ case PIC_NAND_IRQ:
95+ return 151;
9496 case PIC_SPI_IRQ:
9597 return 152;
9698 case PIC_MMC_IRQ:
arch/mips/oprofile/common.c+1−0
@@ -91,6 +91,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) · 90 unmodified lines
9191 case CPU_INTERAPTIV:
9292 case CPU_PROAPTIV:
9393 case CPU_P5600:
94+ case CPU_I6400:
9495 case CPU_M5150:
9596 case CPU_LOONGSON1:
9697 case CPU_SB1:
arch/mips/oprofile/op_model_mipsxx.c+4−0
@@ -392,6 +392,10 @@ static int __init mipsxx_init(void) · 391 unmodified lines
392392 op_model_mipsxx_ops.cpu_type = "mips/P5600";
393393 break;
394394
395+ case CPU_I6400:
396+ op_model_mipsxx_ops.cpu_type = "mips/I6400";
397+ break;
398+
395399 case CPU_M5150:
396400 op_model_mipsxx_ops.cpu_type = "mips/M5150";
397401 break;
arch/mips/pci/msi-xlp.c+10−10
@@ -131,7 +131,7 @@ struct xlp_msi_data { · 130 unmodified lines
131131 */
132132 static void xlp_msi_enable(struct irq_data *d)
133133 {
134− struct xlp_msi_data *md = irq_data_get_irq_handler_data(d);
134+ struct xlp_msi_data *md = irq_data_get_irq_chip_data(d);
135135 unsigned long flags;
136136 int vec;
137137
@@ -148,7 +148,7 @@ static void xlp_msi_enable(struct irq_data *d) · 10 unmodified lines
148148
149149 static void xlp_msi_disable(struct irq_data *d)
150150 {
151− struct xlp_msi_data *md = irq_data_get_irq_handler_data(d);
151+ struct xlp_msi_data *md = irq_data_get_irq_chip_data(d);
152152 unsigned long flags;
153153 int vec;
154154
@@ -165,7 +165,7 @@ static void xlp_msi_disable(struct irq_data *d) · 10 unmodified lines
165165
166166 static void xlp_msi_mask_ack(struct irq_data *d)
167167 {
168− struct xlp_msi_data *md = irq_data_get_irq_handler_data(d);
168+ struct xlp_msi_data *md = irq_data_get_irq_chip_data(d);
169169 int link, vec;
170170
171171 link = nlm_irq_msilink(d->irq);
@@ -211,7 +211,7 @@ static void xlp_msix_mask_ack(struct irq_data *d) · 39 unmodified lines
211211 msixvec = nlm_irq_msixvec(d->irq);
212212 link = nlm_irq_msixlink(msixvec);
213213 pci_msi_mask_irq(d);
214− md = irq_data_get_irq_handler_data(d);
214+ md = irq_data_get_irq_chip_data(d);
215215
216216 /* Ack MSI on bridge */
217217 if (cpu_is_xlp9xx()) {
@@ -302,7 +302,7 @@ static int xlp_setup_msi(uint64_t lnkbase, int node, int link, · 84 unmodified lines
302302 /* Get MSI data for the link */
303303 lirq = PIC_PCIE_LINK_MSI_IRQ(link);
304304 xirq = nlm_irq_to_xirq(node, nlm_link_msiirq(link, 0));
305− md = irq_get_handler_data(xirq);
305+ md = irq_get_chip_data(xirq);
306306 msiaddr = MSI_LINK_ADDR(node, link);
307307
308308 spin_lock_irqsave(&md->msi_lock, flags);
@@ -409,7 +409,7 @@ static int xlp_setup_msix(uint64_t lnkbase, int node, int link, · 100 unmodified lines
409409 /* Get MSI data for the link */
410410 lirq = PIC_PCIE_MSIX_IRQ(link);
411411 xirq = nlm_irq_to_xirq(node, nlm_link_msixirq(link, 0));
412− md = irq_get_handler_data(xirq);
412+ md = irq_get_chip_data(xirq);
413413 msixaddr = MSIX_LINK_ADDR(node, link);
414414
415415 spin_lock_irqsave(&md->msi_lock, flags);
@@ -485,7 +485,7 @@ void __init xlp_init_node_msi_irqs(int node, int link) · 69 unmodified lines
485485 irq = nlm_irq_to_xirq(node, nlm_link_msiirq(link, 0));
486486 for (i = irq; i < irq + XLP_MSIVEC_PER_LINK; i++) {
487487 irq_set_chip_and_handler(i, &xlp_msi_chip, handle_level_irq);
488− irq_set_handler_data(i, md);
488+ irq_set_chip_data(i, md);
489489 }
490490
491491 for (i = 0; i < XLP_MSIXVEC_PER_LINK ; i++) {
@@ -508,7 +508,7 @@ void __init xlp_init_node_msi_irqs(int node, int link) · 16 unmodified lines
508508 /* Initialize MSI-X extended irq space for the link */
509509 irq = nlm_irq_to_xirq(node, nlm_link_msixirq(link, i));
510510 irq_set_chip_and_handler(irq, &xlp_msix_chip, handle_level_irq);
511− irq_set_handler_data(irq, md);
511+ irq_set_chip_data(irq, md);
512512 }
513513 }
514514
@@ -520,7 +520,7 @@ void nlm_dispatch_msi(int node, int lirq) · 5 unmodified lines
520520
521521 link = lirq - PIC_PCIE_LINK_MSI_IRQ_BASE;
522522 irqbase = nlm_irq_to_xirq(node, nlm_link_msiirq(link, 0));
523− md = irq_get_handler_data(irqbase);
523+ md = irq_get_chip_data(irqbase);
524524 if (cpu_is_xlp9xx())
525525 status = nlm_read_reg(md->lnkbase, PCIE_9XX_MSI_STATUS) &
526526 md->msi_enabled_mask;
@@ -550,7 +550,7 @@ void nlm_dispatch_msix(int node, int lirq) · 23 unmodified lines
550550
551551 link = lirq - PIC_PCIE_MSIX_IRQ_BASE;
552552 irqbase = nlm_irq_to_xirq(node, nlm_link_msixirq(link, 0));
553− md = irq_get_handler_data(irqbase);
553+ md = irq_get_chip_data(irqbase);
554554 if (cpu_is_xlp9xx())
555555 status = nlm_read_reg(md->lnkbase, PCIE_9XX_MSIX_STATUSX(link));
556556 else
arch/mips/pci/ops-emma2rh.c+2−4
@@ -25,7 +25,6 @@ · 24 unmodified lines
2525 #include <linux/types.h>
2626
2727 #include <asm/addrspace.h>
28−#include <asm/debug.h>
2928
3029 #include <asm/emma/emma2rh.h>
3130
@@ -40,10 +39,9 @@ · 8 unmodified lines
4039 static int check_args(struct pci_bus *bus, u32 devfn, u32 * bus_num)
4140 {
4241 /* check if the bus is top-level */
43− if (bus->parent != NULL) {
42+ if (bus->parent != NULL)
4443 *bus_num = bus->number;
45− db_assert(bus_num != NULL);
46− } else
44+ else
4745 *bus_num = 0;
4846
4947 if (*bus_num == 0) {
arch/mips/pci/pci-ar71xx.c+2−2
@@ -312,8 +312,8 @@ static void ar71xx_pci_irq_init(struct ar71xx_pci_controller *apc) · 311 unmodified lines
312312 irq_set_chip_data(i, apc);
313313 }
314314
315− irq_set_handler_data(apc->irq, apc);
316− irq_set_chained_handler(apc->irq, ar71xx_pci_irq_handler);
315+ irq_set_chained_handler_and_data(apc->irq, ar71xx_pci_irq_handler,
316+ apc);
317317 }
318318
319319 static void ar71xx_pci_reset(void)
arch/mips/pci/pci-ar724x.c+2−2
@@ -321,8 +321,8 @@ static void ar724x_pci_irq_init(struct ar724x_pci_controller *apc, · 320 unmodified lines
321321 irq_set_chip_data(i, apc);
322322 }
323323
324− irq_set_handler_data(apc->irq, apc);
325− irq_set_chained_handler(apc->irq, ar724x_pci_irq_handler);
324+ irq_set_chained_handler_and_data(apc->irq, ar724x_pci_irq_handler,
325+ apc);
326326 }
327327
328328 static int ar724x_pci_probe(struct platform_device *pdev)
arch/mips/pci/pci-lantiq.c+0−1
@@ -20,7 +20,6 @@ · 19 unmodified lines
2020 #include <linux/of_irq.h>
2121 #include <linux/of_pci.h>
2222
23−#include <asm/gpio.h>
2423 #include <asm/addrspace.h>
2524
2625 #include <lantiq_soc.h>
arch/mips/pci/pci-rt3883.c+3−4
@@ -129,7 +129,7 @@ static void rt3883_pci_write_cfg32(struct rt3883_pci_controller *rpc, · 128 unmodified lines
129129 rt3883_pci_w32(rpc, val, RT3883_PCI_REG_CFGDATA);
130130 }
131131
132−static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
132+static void rt3883_pci_irq_handler(unsigned int __irq, struct irq_desc *desc)
133133 {
134134 struct rt3883_pci_controller *rpc;
135135 u32 pending;
@@ -145,7 +145,7 @@ static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc) · 9 unmodified lines
145145 }
146146
147147 while (pending) {
148− unsigned bit = __ffs(pending);
148+ unsigned irq, bit = __ffs(pending);
149149
150150 irq = irq_find_mapping(rpc->irq_domain, bit);
151151 generic_handle_irq(irq);
@@ -225,8 +225,7 @@ static int rt3883_pci_irq_init(struct device *dev, · 73 unmodified lines
225225 return -ENODEV;
226226 }
227227
228− irq_set_handler_data(irq, rpc);
229− irq_set_chained_handler(irq, rt3883_pci_irq_handler);
228+ irq_set_chained_handler_and_data(irq, rt3883_pci_irq_handler, rpc);
230229
231230 return 0;
232231 }
arch/mips/pistachio/Kconfig+13−0
@@ -0,0 +1,13 @@
1+config PISTACHIO_GPTIMER_CLKSRC
2+ bool "Enable General Purpose Timer based clocksource"
3+ depends on MACH_PISTACHIO
4+ select CLKSRC_PISTACHIO
5+ select MIPS_EXTERNAL_TIMER
6+ help
7+ This option enables a clocksource driver based on a Pistachio
8+ SoC General Purpose external timer.
9+
10+ If you want to enable the CPUFreq, you need to enable
11+ this option.
12+
13+ If you don't want to enable CPUFreq, you can leave this disabled.
arch/mips/pmcs-msp71xx/msp_irq_cic.c+2−1
@@ -88,7 +88,8 @@ static void unmask_cic_irq(struct irq_data *d) · 87 unmodified lines
8888 * Make sure we have IRQ affinity. It may have changed while
8989 * we were processing the IRQ.
9090 */
91− if (!cpumask_test_cpu(smp_processor_id(), d->affinity))
91+ if (!cpumask_test_cpu(smp_processor_id(),
92+ irq_data_get_affinity_mask(d)))
9293 return;
9394 #endif
9495
arch/mips/ralink/cevt-rt3352.c+30−29
@@ -36,8 +36,8 @@ struct systick_device { · 35 unmodified lines
3636 int freq_scale;
3737 };
3838
39−static void systick_set_clock_mode(enum clock_event_mode mode,
40− struct clock_event_device *evt);
39+static int systick_set_oneshot(struct clock_event_device *evt);
40+static int systick_shutdown(struct clock_event_device *evt);
4141
4242 static int systick_next_event(unsigned long delta,
4343 struct clock_event_device *evt)
@@ -73,11 +73,12 @@ static struct systick_device systick = { · 29 unmodified lines
7373 * cevt-r4k uses 300, make sure systick
7474 * gets used if available
7575 */
76− .rating = 310,
77− .features = CLOCK_EVT_FEAT_ONESHOT,
78− .set_next_event = systick_next_event,
79− .set_mode = systick_set_clock_mode,
80− .event_handler = systick_event_handler,
76+ .rating = 310,
77+ .features = CLOCK_EVT_FEAT_ONESHOT,
78+ .set_next_event = systick_next_event,
79+ .set_state_shutdown = systick_shutdown,
80+ .set_state_oneshot = systick_set_oneshot,
81+ .event_handler = systick_event_handler,
8182 },
8283 };
8384
@@ -87,33 +88,33 @@ static struct irqaction systick_irqaction = { · 3 unmodified lines
8788 .dev_id = &systick.dev,
8889 };
8990
90−static void systick_set_clock_mode(enum clock_event_mode mode,
91− struct clock_event_device *evt)
91+static int systick_shutdown(struct clock_event_device *evt)
9292 {
9393 struct systick_device *sdev;
9494
9595 sdev = container_of(evt, struct systick_device, dev);
9696
97− switch (mode) {
98− case CLOCK_EVT_MODE_ONESHOT:
99− if (!sdev->irq_requested)
100− setup_irq(systick.dev.irq, &systick_irqaction);
101− sdev->irq_requested = 1;
102− iowrite32(CFG_EXT_STK_EN | CFG_CNT_EN,
103− systick.membase + SYSTICK_CONFIG);
104− break;
105−
106− case CLOCK_EVT_MODE_SHUTDOWN:
107− if (sdev->irq_requested)
108− free_irq(systick.dev.irq, &systick_irqaction);
109− sdev->irq_requested = 0;
110− iowrite32(0, systick.membase + SYSTICK_CONFIG);
111− break;
112−
113− default:
114− pr_err("%s: Unhandeled mips clock_mode\n", systick.dev.name);
115− break;
116− }
97+ if (sdev->irq_requested)
98+ free_irq(systick.dev.irq, &systick_irqaction);
99+ sdev->irq_requested = 0;
100+ iowrite32(0, systick.membase + SYSTICK_CONFIG);
101+
102+ return 0;
103+}
104+
105+static int systick_set_oneshot(struct clock_event_device *evt)
106+{
107+ struct systick_device *sdev;
108+
109+ sdev = container_of(evt, struct systick_device, dev);
110+
111+ if (!sdev->irq_requested)
112+ setup_irq(systick.dev.irq, &systick_irqaction);
113+ sdev->irq_requested = 1;
114+ iowrite32(CFG_EXT_STK_EN | CFG_CNT_EN,
115+ systick.membase + SYSTICK_CONFIG);
116+
117+ return 0;
117118 }
118119
119120 static void __init ralink_systick_init(struct device_node *np)
arch/mips/rb532/devices.c+1−0
@@ -23,6 +23,7 @@ · 22 unmodified lines
2323 #include <linux/mtd/nand.h>
2424 #include <linux/mtd/mtd.h>
2525 #include <linux/mtd/partitions.h>
26+#include <linux/gpio.h>
2627 #include <linux/gpio_keys.h>
2728 #include <linux/input.h>
2829 #include <linux/serial_8250.h>
arch/mips/rb532/gpio.c+6−0
@@ -140,6 +140,11 @@ static int rb532_gpio_direction_output(struct gpio_chip *chip, · 139 unmodified lines
140140 return 0;
141141 }
142142
143+static int rb532_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
144+{
145+ return 8 + 4 * 32 + gpio;
146+}
147+
143148 static struct rb532_gpio_chip rb532_gpio_chip[] = {
144149 [0] = {
145150 .chip = {
@@ -148,6 +153,7 @@ static struct rb532_gpio_chip rb532_gpio_chip[] = { · 2 unmodified lines
148153 .direction_output = rb532_gpio_direction_output,
149154 .get = rb532_gpio_get,
150155 .set = rb532_gpio_set,
156+ .to_irq = rb532_gpio_to_irq,
151157 .base = 0,
152158 .ngpio = 32,
153159 },
arch/mips/sgi-ip27/ip27-timer.c+0−7
@@ -64,12 +64,6 @@ static int rt_next_event(unsigned long delta, struct clock_event_device *evt) · 63 unmodified lines
6464 return LOCAL_HUB_L(PI_RT_COUNT) >= cnt ? -ETIME : 0;
6565 }
6666
67−static void rt_set_mode(enum clock_event_mode mode,
68− struct clock_event_device *evt)
69−{
70− /* Nothing to do ... */
71−}
72−
7367 unsigned int rt_timer_irq;
7468
7569 static DEFINE_PER_CPU(struct clock_event_device, hub_rt_clockevent);
@@ -124,7 +118,6 @@ void hub_rt_clock_event_init(void) · 48 unmodified lines
124118 cd->irq = irq;
125119 cd->cpumask = cpumask_of(cpu);
126120 cd->set_next_event = rt_next_event;
127− cd->set_mode = rt_set_mode;
128121 clockevents_register_device(cd);
129122 }
130123
arch/mips/sibyte/common/bus_watcher.c+1−1
@@ -250,4 +250,4 @@ int __init sibyte_bus_watcher(void) · 249 unmodified lines
250250 return 0;
251251 }
252252
253−__initcall(sibyte_bus_watcher);
253+device_initcall(sibyte_bus_watcher);
arch/mips/sni/time.c+19−30
@@ -14,44 +14,33 @@ · 13 unmodified lines
1414 #define SNI_COUNTER2_DIV 64
1515 #define SNI_COUNTER0_DIV ((SNI_CLOCK_TICK_RATE / SNI_COUNTER2_DIV) / HZ)
1616
17−static void a20r_set_mode(enum clock_event_mode mode,
18− struct clock_event_device *evt)
17+static int a20r_set_periodic(struct clock_event_device *evt)
1918 {
20− switch (mode) {
21− case CLOCK_EVT_MODE_PERIODIC:
22− *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0x34;
23− wmb();
24− *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV;
25− wmb();
26− *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV >> 8;
27− wmb();
28−
29− *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0xb4;
30− wmb();
31− *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV;
32− wmb();
33− *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV >> 8;
34− wmb();
19+ *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0x34;
20+ wmb();
21+ *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV;
22+ wmb();
23+ *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV >> 8;
24+ wmb();
3525
36− break;
37− case CLOCK_EVT_MODE_ONESHOT:
38− case CLOCK_EVT_MODE_UNUSED:
39− case CLOCK_EVT_MODE_SHUTDOWN:
40− break;
41− case CLOCK_EVT_MODE_RESUME:
42− break;
43− }
26+ *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0xb4;
27+ wmb();
28+ *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV;
29+ wmb();
30+ *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV >> 8;
31+ wmb();
32+ return 0;
4433 }
4534
4635 static struct clock_event_device a20r_clockevent_device = {
47− .name = "a20r-timer",
48− .features = CLOCK_EVT_FEAT_PERIODIC,
36+ .name = "a20r-timer",
37+ .features = CLOCK_EVT_FEAT_PERIODIC,
4938
5039 /* .mult, .shift, .max_delta_ns and .min_delta_ns left uninitialized */
5140
52− .rating = 300,
53− .irq = SNI_A20R_IRQ_TIMER,
54− .set_mode = a20r_set_mode,
41+ .rating = 300,
42+ .irq = SNI_A20R_IRQ_TIMER,
43+ .set_state_periodic = a20r_set_periodic,
5544 };
5645
5746 static irqreturn_t a20r_interrupt(int irq, void *dev_id)
arch/mips/txx9/generic/setup.c+0−16
@@ -117,22 +117,6 @@ void clk_put(struct clk *clk) · 116 unmodified lines
117117 }
118118 EXPORT_SYMBOL(clk_put);
119119
120−/* GPIO support */
121−
122−#ifdef CONFIG_GPIOLIB
123−int gpio_to_irq(unsigned gpio)
124−{
125− return -EINVAL;
126−}
127−EXPORT_SYMBOL(gpio_to_irq);
128−
129−int irq_to_gpio(unsigned irq)
130−{
131− return -EINVAL;
132−}
133−EXPORT_SYMBOL(irq_to_gpio);
134−#endif
135−
136120 #define BOARD_VEC(board) extern struct txx9_board_vec board;
137121 #include <asm/txx9/boards.h>
138122 #undef BOARD_VEC
drivers/ata/pata_rb532_cf.c+1−2
@@ -27,12 +27,11 @@ · 26 unmodified lines
2727 #include <linux/io.h>
2828 #include <linux/interrupt.h>
2929 #include <linux/irq.h>
30+#include <linux/gpio.h>
3031
3132 #include <linux/libata.h>
3233 #include <scsi/scsi_host.h>
3334
34−#include <asm/gpio.h>
35−
3635 #define DRV_NAME "pata-rb532-cf"
3736 #define DRV_VERSION "0.1.0"
3837 #define DRV_DESC "PATA driver for RouterBOARD 532 Compact Flash"
drivers/bus/mips_cdmm.c+13−1
@@ -331,6 +331,18 @@ static phys_addr_t mips_cdmm_cur_base(void) · 330 unmodified lines
331331 << MIPS_CDMMBASE_ADDR_START;
332332 }
333333
334+/**
335+ * mips_cdmm_phys_base() - Choose a physical base address for CDMM region.
336+ *
337+ * Picking a suitable physical address at which to map the CDMM region is
338+ * platform specific, so this weak function can be overridden by platform
339+ * code to pick a suitable value if none is configured by the bootloader.
340+ */
341+phys_addr_t __weak mips_cdmm_phys_base(void)
342+{
343+ return 0;
344+}
345+
334346 /**
335347 * mips_cdmm_setup() - Ensure the CDMM bus is initialised and usable.
336348 * @bus: Pointer to bus information for current CPU.
@@ -368,7 +380,7 @@ static int mips_cdmm_setup(struct mips_cdmm_bus *bus) · 31 unmodified lines
368380 if (!bus->phys)
369381 bus->phys = mips_cdmm_cur_base();
370382 /* Otherwise, ask platform code for suggestions */
371− if (!bus->phys && mips_cdmm_phys_base)
383+ if (!bus->phys)
372384 bus->phys = mips_cdmm_phys_base();
373385 /* Otherwise, copy what other CPUs have done */
374386 if (!bus->phys)
drivers/clocksource/Kconfig+4−0
@@ -111,6 +111,10 @@ config CLKSRC_LPC32XX · 110 unmodified lines
111111 select CLKSRC_MMIO
112112 select CLKSRC_OF
113113
114+config CLKSRC_PISTACHIO
115+ bool
116+ select CLKSRC_OF
117+
114118 config CLKSRC_STM32
115119 bool "Clocksource for STM32 SoCs" if !ARCH_STM32
116120 depends on OF && ARM && (ARCH_STM32 || COMPILE_TEST)
drivers/clocksource/Makefile+1−0
@@ -44,6 +44,7 @@ obj-$(CONFIG_FSL_FTM_TIMER) += fsl_ftm_timer.o · 43 unmodified lines
4444 obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o
4545 obj-$(CONFIG_CLKSRC_QCOM) += qcom-timer.o
4646 obj-$(CONFIG_MTK_TIMER) += mtk_timer.o
47+obj-$(CONFIG_CLKSRC_PISTACHIO) += time-pistachio.o
4748
4849 obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
4950 obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o
drivers/clocksource/mips-gic-timer.c+56−9
@@ -72,6 +72,13 @@ static void gic_clockevent_cpu_exit(struct clock_event_device *cd) · 71 unmodified lines
7272 disable_percpu_irq(gic_timer_irq);
7373 }
7474
75+static void gic_update_frequency(void *data)
76+{
77+ unsigned long rate = (unsigned long)data;
78+
79+ clockevents_update_freq(this_cpu_ptr(&gic_clockevent_device), rate);
80+}
81+
7582 static int gic_cpu_notifier(struct notifier_block *nb, unsigned long action,
7683 void *data)
7784 {
@@ -87,18 +94,40 @@ static int gic_cpu_notifier(struct notifier_block *nb, unsigned long action, · 9 unmodified lines
8794 return NOTIFY_OK;
8895 }
8996
97+static int gic_clk_notifier(struct notifier_block *nb, unsigned long action,
98+ void *data)
99+{
100+ struct clk_notifier_data *cnd = data;
101+
102+ if (action == POST_RATE_CHANGE)
103+ on_each_cpu(gic_update_frequency, (void *)cnd->new_rate, 1);
104+
105+ return NOTIFY_OK;
106+}
107+
108+
90109 static struct notifier_block gic_cpu_nb = {
91110 .notifier_call = gic_cpu_notifier,
92111 };
93112
113+static struct notifier_block gic_clk_nb = {
114+ .notifier_call = gic_clk_notifier,
115+};
116+
94117 static int gic_clockevent_init(void)
95118 {
119+ int ret;
120+
96121 if (!cpu_has_counter || !gic_frequency)
97122 return -ENXIO;
98123
99− setup_percpu_irq(gic_timer_irq, &gic_compare_irqaction);
124+ ret = setup_percpu_irq(gic_timer_irq, &gic_compare_irqaction);
125+ if (ret < 0)
126+ return ret;
100127
101− register_cpu_notifier(&gic_cpu_nb);
128+ ret = register_cpu_notifier(&gic_cpu_nb);
129+ if (ret < 0)
130+ pr_warn("GIC: Unable to register CPU notifier\n");
102131
103132 gic_clockevent_cpu_init(this_cpu_ptr(&gic_clockevent_device));
104133
@@ -118,18 +147,17 @@ static struct clocksource gic_clocksource = { · 13 unmodified lines
118147
119148 static void __init __gic_clocksource_init(void)
120149 {
150+ int ret;
151+
121152 /* Set clocksource mask. */
122153 gic_clocksource.mask = CLOCKSOURCE_MASK(gic_get_count_width());
123154
124155 /* Calculate a somewhat reasonable rating value. */
125156 gic_clocksource.rating = 200 + gic_frequency / 10000000;
126157
127− clocksource_register_hz(&gic_clocksource, gic_frequency);
128−
129− gic_clockevent_init();
130−
131− /* And finally start the counter */
132− gic_start_count();
158+ ret = clocksource_register_hz(&gic_clocksource, gic_frequency);
159+ if (ret < 0)
160+ pr_warn("GIC: Unable to register clocksource\n");
133161 }
134162
135163 void __init gic_clocksource_init(unsigned int frequency)
@@ -139,11 +167,16 @@ void __init gic_clocksource_init(unsigned int frequency) · 3 unmodified lines
139167 GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE);
140168
141169 __gic_clocksource_init();
170+ gic_clockevent_init();
171+
172+ /* And finally start the counter */
173+ gic_start_count();
142174 }
143175
144176 static void __init gic_clocksource_of_init(struct device_node *node)
145177 {
146178 struct clk *clk;
179+ int ret;
147180
148181 if (WARN_ON(!gic_present || !node->parent ||
149182 !of_device_is_compatible(node->parent, "mti,gic")))
@@ -151,8 +184,13 @@ static void __init gic_clocksource_of_init(struct device_node *node) · 1 unmodified line
151184
152185 clk = of_clk_get(node, 0);
153186 if (!IS_ERR(clk)) {
187+ if (clk_prepare_enable(clk) < 0) {
188+ pr_err("GIC failed to enable clock\n");
189+ clk_put(clk);
190+ return;
191+ }
192+
154193 gic_frequency = clk_get_rate(clk);
155− clk_put(clk);
156194 } else if (of_property_read_u32(node, "clock-frequency",
157195 &gic_frequency)) {
158196 pr_err("GIC frequency not specified.\n");
@@ -165,6 +203,15 @@ static void __init gic_clocksource_of_init(struct device_node *node) · 6 unmodified lines
165203 }
166204
167205 __gic_clocksource_init();
206+
207+ ret = gic_clockevent_init();
208+ if (!ret && !IS_ERR(clk)) {
209+ if (clk_notifier_register(clk, &gic_clk_nb) < 0)
210+ pr_warn("GIC: Unable to register clock notifier\n");
211+ }
212+
213+ /* And finally start the counter */
214+ gic_start_count();
168215 }
169216 CLOCKSOURCE_OF_DECLARE(mips_gic_timer, "mti,gic-timer",
170217 gic_clocksource_of_init);
drivers/clocksource/time-pistachio.c+217−0
@@ -0,0 +1,217 @@
1+/*
2+ * Pistachio clocksource based on general-purpose timers
3+ *
4+ * Copyright (C) 2015 Imagination Technologies
5+ *
6+ * This file is subject to the terms and conditions of the GNU General Public
7+ * License. See the file "COPYING" in the main directory of this archive
8+ * for more details.
9+ */
10+
11+#define pr_fmt(fmt) "%s: " fmt, __func__
12+
13+#include <linux/clk.h>
14+#include <linux/clocksource.h>
15+#include <linux/clockchips.h>
16+#include <linux/delay.h>
17+#include <linux/err.h>
18+#include <linux/init.h>
19+#include <linux/spinlock.h>
20+#include <linux/mfd/syscon.h>
21+#include <linux/of.h>
22+#include <linux/of_address.h>
23+#include <linux/platform_device.h>
24+#include <linux/regmap.h>
25+#include <linux/sched_clock.h>
26+#include <linux/time.h>
27+
28+/* Top level reg */
29+#define CR_TIMER_CTRL_CFG 0x00
30+#define TIMER_ME_GLOBAL BIT(0)
31+#define CR_TIMER_REV 0x10
32+
33+/* Timer specific registers */
34+#define TIMER_CFG 0x20
35+#define TIMER_ME_LOCAL BIT(0)
36+#define TIMER_RELOAD_VALUE 0x24
37+#define TIMER_CURRENT_VALUE 0x28
38+#define TIMER_CURRENT_OVERFLOW_VALUE 0x2C
39+#define TIMER_IRQ_STATUS 0x30
40+#define TIMER_IRQ_CLEAR 0x34
41+#define TIMER_IRQ_MASK 0x38
42+
43+#define PERIP_TIMER_CONTROL 0x90
44+
45+/* Timer specific configuration Values */
46+#define RELOAD_VALUE 0xffffffff
47+
48+struct pistachio_clocksource {
49+ void __iomem *base;
50+ raw_spinlock_t lock;
51+ struct clocksource cs;
52+};
53+
54+static struct pistachio_clocksource pcs_gpt;
55+
56+#define to_pistachio_clocksource(cs) \
57+ container_of(cs, struct pistachio_clocksource, cs)
58+
59+static inline u32 gpt_readl(void __iomem *base, u32 offset, u32 gpt_id)
60+{
61+ return readl(base + 0x20 * gpt_id + offset);
62+}
63+
64+static inline void gpt_writel(void __iomem *base, u32 value, u32 offset,
65+ u32 gpt_id)
66+{
67+ writel(value, base + 0x20 * gpt_id + offset);
68+}
69+
70+static cycle_t pistachio_clocksource_read_cycles(struct clocksource *cs)
71+{
72+ struct pistachio_clocksource *pcs = to_pistachio_clocksource(cs);
73+ u32 counter, overflw;
74+ unsigned long flags;
75+
76+ /*
77+ * The counter value is only refreshed after the overflow value is read.
78+ * And they must be read in strict order, hence raw spin lock added.
79+ */
80+
81+ raw_spin_lock_irqsave(&pcs->lock, flags);
82+ overflw = gpt_readl(pcs->base, TIMER_CURRENT_OVERFLOW_VALUE, 0);
83+ counter = gpt_readl(pcs->base, TIMER_CURRENT_VALUE, 0);
84+ raw_spin_unlock_irqrestore(&pcs->lock, flags);
85+
86+ return ~(cycle_t)counter;
87+}
88+
89+static u64 notrace pistachio_read_sched_clock(void)
90+{
91+ return pistachio_clocksource_read_cycles(&pcs_gpt.cs);
92+}
93+
94+static void pistachio_clksrc_set_mode(struct clocksource *cs, int timeridx,
95+ int enable)
96+{
97+ struct pistachio_clocksource *pcs = to_pistachio_clocksource(cs);
98+ u32 val;
99+
100+ val = gpt_readl(pcs->base, TIMER_CFG, timeridx);
101+ if (enable)
102+ val |= TIMER_ME_LOCAL;
103+ else
104+ val &= ~TIMER_ME_LOCAL;
105+
106+ gpt_writel(pcs->base, val, TIMER_CFG, timeridx);
107+}
108+
109+static void pistachio_clksrc_enable(struct clocksource *cs, int timeridx)
110+{
111+ struct pistachio_clocksource *pcs = to_pistachio_clocksource(cs);
112+
113+ /* Disable GPT local before loading reload value */
114+ pistachio_clksrc_set_mode(cs, timeridx, false);
115+ gpt_writel(pcs->base, RELOAD_VALUE, TIMER_RELOAD_VALUE, timeridx);
116+ pistachio_clksrc_set_mode(cs, timeridx, true);
117+}
118+
119+static void pistachio_clksrc_disable(struct clocksource *cs, int timeridx)
120+{
121+ /* Disable GPT local */
122+ pistachio_clksrc_set_mode(cs, timeridx, false);
123+}
124+
125+static int pistachio_clocksource_enable(struct clocksource *cs)
126+{
127+ pistachio_clksrc_enable(cs, 0);
128+ return 0;
129+}
130+
131+static void pistachio_clocksource_disable(struct clocksource *cs)
132+{
133+ pistachio_clksrc_disable(cs, 0);
134+}
135+
136+/* Desirable clock source for pistachio platform */
137+static struct pistachio_clocksource pcs_gpt = {
138+ .cs = {
139+ .name = "gptimer",
140+ .rating = 300,
141+ .enable = pistachio_clocksource_enable,
142+ .disable = pistachio_clocksource_disable,
143+ .read = pistachio_clocksource_read_cycles,
144+ .mask = CLOCKSOURCE_MASK(32),
145+ .flags = CLOCK_SOURCE_IS_CONTINUOUS |
146+ CLOCK_SOURCE_SUSPEND_NONSTOP,
147+ },
148+};
149+
150+static void __init pistachio_clksrc_of_init(struct device_node *node)
151+{
152+ struct clk *sys_clk, *fast_clk;
153+ struct regmap *periph_regs;
154+ unsigned long rate;
155+ int ret;
156+
157+ pcs_gpt.base = of_iomap(node, 0);
158+ if (!pcs_gpt.base) {
159+ pr_err("cannot iomap\n");
160+ return;
161+ }
162+
163+ periph_regs = syscon_regmap_lookup_by_phandle(node, "img,cr-periph");
164+ if (IS_ERR(periph_regs)) {
165+ pr_err("cannot get peripheral regmap (%lu)\n",
166+ PTR_ERR(periph_regs));
167+ return;
168+ }
169+
170+ /* Switch to using the fast counter clock */
171+ ret = regmap_update_bits(periph_regs, PERIP_TIMER_CONTROL,
172+ 0xf, 0x0);
173+ if (ret)
174+ return;
175+
176+ sys_clk = of_clk_get_by_name(node, "sys");
177+ if (IS_ERR(sys_clk)) {
178+ pr_err("clock get failed (%lu)\n", PTR_ERR(sys_clk));
179+ return;
180+ }
181+
182+ fast_clk = of_clk_get_by_name(node, "fast");
183+ if (IS_ERR(fast_clk)) {
184+ pr_err("clock get failed (%lu)\n", PTR_ERR(fast_clk));
185+ return;
186+ }
187+
188+ ret = clk_prepare_enable(sys_clk);
189+ if (ret < 0) {
190+ pr_err("failed to enable clock (%d)\n", ret);
191+ return;
192+ }
193+
194+ ret = clk_prepare_enable(fast_clk);
195+ if (ret < 0) {
196+ pr_err("failed to enable clock (%d)\n", ret);
197+ clk_disable_unprepare(sys_clk);
198+ return;
199+ }
200+
201+ rate = clk_get_rate(fast_clk);
202+
203+ /* Disable irq's for clocksource usage */
204+ gpt_writel(&pcs_gpt.base, 0, TIMER_IRQ_MASK, 0);
205+ gpt_writel(&pcs_gpt.base, 0, TIMER_IRQ_MASK, 1);
206+ gpt_writel(&pcs_gpt.base, 0, TIMER_IRQ_MASK, 2);
207+ gpt_writel(&pcs_gpt.base, 0, TIMER_IRQ_MASK, 3);
208+
209+ /* Enable timer block */
210+ writel(TIMER_ME_GLOBAL, pcs_gpt.base);
211+
212+ raw_spin_lock_init(&pcs_gpt.lock);
213+ sched_clock_register(pistachio_read_sched_clock, 32, rate);
214+ clocksource_register_hz(&pcs_gpt.cs, rate);
215+}
216+CLOCKSOURCE_OF_DECLARE(pistachio_gptimer, "img,pistachio-gptimer",
217+ pistachio_clksrc_of_init);
drivers/gpio/Makefile+1−0
@@ -20,6 +20,7 @@ obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o · 19 unmodified lines
2020 obj-$(CONFIG_GPIO_ALTERA) += gpio-altera.o
2121 obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o
2222 obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o
23+obj-$(CONFIG_ATH79) += gpio-ath79.o
2324 obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o
2425 obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o
2526 obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o
drivers/gpio/gpio-ath79.crenamed from arch/mips/ath79/gpio.c+0−75
@@ -24,8 +24,6 @@ · 23 unmodified lines
2424 #include <linux/of_device.h>
2525
2626 #include <asm/mach-ath79/ar71xx_regs.h>
27−#include <asm/mach-ath79/ath79.h>
28−#include "common.h"
2927
3028 static void __iomem *ath79_gpio_base;
3129 static u32 ath79_gpio_count;
@@ -139,47 +137,6 @@ static struct gpio_chip ath79_gpio_chip = { · 107 unmodified lines
139137 .base = 0,
140138 };
141139
142−static void __iomem *ath79_gpio_get_function_reg(void)
143−{
144− u32 reg = 0;
145−
146− if (soc_is_ar71xx() ||
147− soc_is_ar724x() ||
148− soc_is_ar913x() ||
149− soc_is_ar933x())
150− reg = AR71XX_GPIO_REG_FUNC;
151− else if (soc_is_ar934x())
152− reg = AR934X_GPIO_REG_FUNC;
153− else
154− BUG();
155−
156− return ath79_gpio_base + reg;
157−}
158−
159−void ath79_gpio_function_setup(u32 set, u32 clear)
160−{
161− void __iomem *reg = ath79_gpio_get_function_reg();
162− unsigned long flags;
163−
164− spin_lock_irqsave(&ath79_gpio_lock, flags);
165−
166− __raw_writel((__raw_readl(reg) & ~clear) | set, reg);
167− /* flush write */
168− __raw_readl(reg);
169−
170− spin_unlock_irqrestore(&ath79_gpio_lock, flags);
171−}
172−
173−void ath79_gpio_function_enable(u32 mask)
174−{
175− ath79_gpio_function_setup(mask, 0);
176−}
177−
178−void ath79_gpio_function_disable(u32 mask)
179−{
180− ath79_gpio_function_setup(0, mask);
181−}
182−
183140 static const struct of_device_id ath79_gpio_of_match[] = {
184141 { .compatible = "qca,ar7100-gpio" },
185142 { .compatible = "qca,ar9340-gpio" },
@@ -245,35 +202,3 @@ static struct platform_driver ath79_gpio_driver = { · 59 unmodified lines
245202 };
246203
247204 module_platform_driver(ath79_gpio_driver);
248−
249−int gpio_get_value(unsigned gpio)
250−{
251− if (gpio < ath79_gpio_count)
252− return __ath79_gpio_get_value(gpio);
253−
254− return __gpio_get_value(gpio);
255−}
256−EXPORT_SYMBOL(gpio_get_value);
257−
258−void gpio_set_value(unsigned gpio, int value)
259−{
260− if (gpio < ath79_gpio_count)
261− __ath79_gpio_set_value(gpio, value);
262− else
263− __gpio_set_value(gpio, value);
264−}
265−EXPORT_SYMBOL(gpio_set_value);
266−
267−int gpio_to_irq(unsigned gpio)
268−{
269− /* FIXME */
270− return -EINVAL;
271−}
272−EXPORT_SYMBOL(gpio_to_irq);
273−
274−int irq_to_gpio(unsigned irq)
275−{
276− /* FIXME */
277− return -EINVAL;
278−}
279−EXPORT_SYMBOL(irq_to_gpio);
drivers/input/misc/rb532_button.c+1−0
@@ -7,6 +7,7 @@ · 6 unmodified lines
77 #include <linux/input-polldev.h>
88 #include <linux/module.h>
99 #include <linux/platform_device.h>
10+#include <linux/gpio.h>
1011
1112 #include <asm/mach-rc32434/gpio.h>
1213 #include <asm/mach-rc32434/rb.h>
drivers/irqchip/irq-mips-gic.c+94−48
@@ -41,20 +41,46 @@ static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller; · 40 unmodified lines
4141
4242 static void __gic_irq_dispatch(void);
4343
44−static inline unsigned int gic_read(unsigned int reg)
44+static inline u32 gic_read32(unsigned int reg)
4545 {
4646 return __raw_readl(gic_base + reg);
4747 }
4848
49−static inline void gic_write(unsigned int reg, unsigned int val)
49+static inline u64 gic_read64(unsigned int reg)
5050 {
51− __raw_writel(val, gic_base + reg);
51+ return __raw_readq(gic_base + reg);
5252 }
5353
54−static inline void gic_update_bits(unsigned int reg, unsigned int mask,
55− unsigned int val)
54+static inline unsigned long gic_read(unsigned int reg)
5655 {
57− unsigned int regval;
56+ if (!mips_cm_is64)
57+ return gic_read32(reg);
58+ else
59+ return gic_read64(reg);
60+}
61+
62+static inline void gic_write32(unsigned int reg, u32 val)
63+{
64+ return __raw_writel(val, gic_base + reg);
65+}
66+
67+static inline void gic_write64(unsigned int reg, u64 val)
68+{
69+ return __raw_writeq(val, gic_base + reg);
70+}
71+
72+static inline void gic_write(unsigned int reg, unsigned long val)
73+{
74+ if (!mips_cm_is64)
75+ return gic_write32(reg, (u32)val);
76+ else
77+ return gic_write64(reg, (u64)val);
78+}
79+
80+static inline void gic_update_bits(unsigned int reg, unsigned long mask,
81+ unsigned long val)
82+{
83+ unsigned long regval;
5884
5985 regval = gic_read(reg);
6086 regval &= ~mask;
@@ -65,40 +91,40 @@ static inline void gic_update_bits(unsigned int reg, unsigned int mask, · 4 unmodified lines
6591 static inline void gic_reset_mask(unsigned int intr)
6692 {
6793 gic_write(GIC_REG(SHARED, GIC_SH_RMASK) + GIC_INTR_OFS(intr),
68− 1 << GIC_INTR_BIT(intr));
94+ 1ul << GIC_INTR_BIT(intr));
6995 }
7096
7197 static inline void gic_set_mask(unsigned int intr)
7298 {
7399 gic_write(GIC_REG(SHARED, GIC_SH_SMASK) + GIC_INTR_OFS(intr),
74− 1 << GIC_INTR_BIT(intr));
100+ 1ul << GIC_INTR_BIT(intr));
75101 }
76102
77103 static inline void gic_set_polarity(unsigned int intr, unsigned int pol)
78104 {
79105 gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_POLARITY) +
80− GIC_INTR_OFS(intr), 1 << GIC_INTR_BIT(intr),
81− pol << GIC_INTR_BIT(intr));
106+ GIC_INTR_OFS(intr), 1ul << GIC_INTR_BIT(intr),
107+ (unsigned long)pol << GIC_INTR_BIT(intr));
82108 }
83109
84110 static inline void gic_set_trigger(unsigned int intr, unsigned int trig)
85111 {
86112 gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_TRIGGER) +
87− GIC_INTR_OFS(intr), 1 << GIC_INTR_BIT(intr),
88− trig << GIC_INTR_BIT(intr));
113+ GIC_INTR_OFS(intr), 1ul << GIC_INTR_BIT(intr),
114+ (unsigned long)trig << GIC_INTR_BIT(intr));
89115 }
90116
91117 static inline void gic_set_dual_edge(unsigned int intr, unsigned int dual)
92118 {
93119 gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_DUAL) + GIC_INTR_OFS(intr),
94− 1 << GIC_INTR_BIT(intr),
95− dual << GIC_INTR_BIT(intr));
120+ 1ul << GIC_INTR_BIT(intr),
121+ (unsigned long)dual << GIC_INTR_BIT(intr));
96122 }
97123
98124 static inline void gic_map_to_pin(unsigned int intr, unsigned int pin)
99125 {
100− gic_write(GIC_REG(SHARED, GIC_SH_INTR_MAP_TO_PIN_BASE) +
101− GIC_SH_MAP_TO_PIN(intr), GIC_MAP_TO_PIN_MSK | pin);
126+ gic_write32(GIC_REG(SHARED, GIC_SH_INTR_MAP_TO_PIN_BASE) +
127+ GIC_SH_MAP_TO_PIN(intr), GIC_MAP_TO_PIN_MSK | pin);
102128 }
103129
104130 static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe)
@@ -113,10 +139,13 @@ cycle_t gic_read_count(void) · 8 unmodified lines
113139 {
114140 unsigned int hi, hi2, lo;
115141
142+ if (mips_cm_is64)
143+ return (cycle_t)gic_read(GIC_REG(SHARED, GIC_SH_COUNTER));
144+
116145 do {
117− hi = gic_read(GIC_REG(SHARED, GIC_SH_COUNTER_63_32));
118− lo = gic_read(GIC_REG(SHARED, GIC_SH_COUNTER_31_00));
119− hi2 = gic_read(GIC_REG(SHARED, GIC_SH_COUNTER_63_32));
146+ hi = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_63_32));
147+ lo = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_31_00));
148+ hi2 = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_63_32));
120149 } while (hi2 != hi);
121150
122151 return (((cycle_t) hi) << 32) + lo;
@@ -135,10 +164,14 @@ unsigned int gic_get_count_width(void) · 12 unmodified lines
135164
136165 void gic_write_compare(cycle_t cnt)
137166 {
138− gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI),
139− (int)(cnt >> 32));
140− gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO),
141− (int)(cnt & 0xffffffff));
167+ if (mips_cm_is64) {
168+ gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE), cnt);
169+ } else {
170+ gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI),
171+ (int)(cnt >> 32));
172+ gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO),
173+ (int)(cnt & 0xffffffff));
174+ }
142175 }
143176
144177 void gic_write_cpu_compare(cycle_t cnt, int cpu)
@@ -148,10 +181,15 @@ void gic_write_cpu_compare(cycle_t cnt, int cpu) · 3 unmodified lines
148181 local_irq_save(flags);
149182
150183 gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), cpu);
151− gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI),
152− (int)(cnt >> 32));
153− gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO),
154− (int)(cnt & 0xffffffff));
184+
185+ if (mips_cm_is64) {
186+ gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE), cnt);
187+ } else {
188+ gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI),
189+ (int)(cnt >> 32));
190+ gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO),
191+ (int)(cnt & 0xffffffff));
192+ }
155193
156194 local_irq_restore(flags);
157195 }
@@ -160,8 +198,11 @@ cycle_t gic_read_compare(void) · 2 unmodified lines
160198 {
161199 unsigned int hi, lo;
162200
163− hi = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI));
164− lo = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO));
201+ if (mips_cm_is64)
202+ return (cycle_t)gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE));
203+
204+ hi = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI));
205+ lo = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO));
165206
166207 return (((cycle_t) hi) << 32) + lo;
167208 }
@@ -196,7 +237,7 @@ static bool gic_local_irq_is_routable(int intr) · 28 unmodified lines
196237 if (cpu_has_veic)
197238 return true;
198239
199− vpe_ctl = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_CTL));
240+ vpe_ctl = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_CTL));
200241 switch (intr) {
201242 case GIC_LOCAL_INT_TIMER:
202243 return vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK;
@@ -262,7 +303,7 @@ int gic_get_c0_fdc_int(void) · 59 unmodified lines
262303
263304 static void gic_handle_shared_int(bool chained)
264305 {
265− unsigned int i, intr, virq;
306+ unsigned int i, intr, virq, gic_reg_step = mips_cm_is64 ? 8 : 4;
266307 unsigned long *pcpu_mask;
267308 unsigned long pending_reg, intrmask_reg;
268309 DECLARE_BITMAP(pending, GIC_MAX_INTRS);
@@ -277,8 +318,8 @@ static void gic_handle_shared_int(bool chained) · 8 unmodified lines
277318 for (i = 0; i < BITS_TO_LONGS(gic_shared_intrs); i++) {
278319 pending[i] = gic_read(pending_reg);
279320 intrmask[i] = gic_read(intrmask_reg);
280− pending_reg += 0x4;
281− intrmask_reg += 0x4;
321+ pending_reg += gic_reg_step;
322+ intrmask_reg += gic_reg_step;
282323 }
283324
284325 bitmap_and(pending, pending, intrmask, gic_shared_intrs);
@@ -425,8 +466,8 @@ static void gic_handle_local_int(bool chained) · 140 unmodified lines
425466 unsigned long pending, masked;
426467 unsigned int intr, virq;
427468
428− pending = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_PEND));
429− masked = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_MASK));
469+ pending = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_PEND));
470+ masked = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_MASK));
430471
431472 bitmap_and(&pending, &pending, &masked, GIC_NUM_LOCAL_INTRS);
432473
@@ -449,14 +490,14 @@ static void gic_mask_local_irq(struct irq_data *d) · 16 unmodified lines
449490 {
450491 int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);
451492
452− gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_RMASK), 1 << intr);
493+ gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_RMASK), 1 << intr);
453494 }
454495
455496 static void gic_unmask_local_irq(struct irq_data *d)
456497 {
457498 int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);
458499
459− gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), 1 << intr);
500+ gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), 1 << intr);
460501 }
461502
462503 static struct irq_chip gic_local_irq_controller = {
@@ -474,7 +515,7 @@ static void gic_mask_local_irq_all_vpes(struct irq_data *d) · 11 unmodified lines
474515 spin_lock_irqsave(&gic_lock, flags);
475516 for (i = 0; i < gic_vpes; i++) {
476517 gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i);
477− gic_write(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << intr);
518+ gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << intr);
478519 }
479520 spin_unlock_irqrestore(&gic_lock, flags);
480521 }
@@ -488,7 +529,7 @@ static void gic_unmask_local_irq_all_vpes(struct irq_data *d) · 7 unmodified lines
488529 spin_lock_irqsave(&gic_lock, flags);
489530 for (i = 0; i < gic_vpes; i++) {
490531 gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i);
491− gic_write(GIC_REG(VPE_OTHER, GIC_VPE_SMASK), 1 << intr);
532+ gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_SMASK), 1 << intr);
492533 }
493534 spin_unlock_irqrestore(&gic_lock, flags);
494535 }
@@ -608,7 +649,7 @@ static void __init gic_basic_init(void) · 113 unmodified lines
608649 for (j = 0; j < GIC_NUM_LOCAL_INTRS; j++) {
609650 if (!gic_local_irq_is_routable(j))
610651 continue;
611− gic_write(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << j);
652+ gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << j);
612653 }
613654 }
614655 }
@@ -653,27 +694,32 @@ static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq, · 38 unmodified lines
653694
654695 switch (intr) {
655696 case GIC_LOCAL_INT_WD:
656− gic_write(GIC_REG(VPE_OTHER, GIC_VPE_WD_MAP), val);
697+ gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_WD_MAP), val);
657698 break;
658699 case GIC_LOCAL_INT_COMPARE:
659− gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_MAP), val);
700+ gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_MAP),
701+ val);
660702 break;
661703 case GIC_LOCAL_INT_TIMER:
662704 /* CONFIG_MIPS_CMP workaround (see __gic_init) */
663705 val = GIC_MAP_TO_PIN_MSK | timer_cpu_pin;
664− gic_write(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP), val);
706+ gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP),
707+ val);
665708 break;
666709 case GIC_LOCAL_INT_PERFCTR:
667− gic_write(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP), val);
710+ gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP),
711+ val);
668712 break;
669713 case GIC_LOCAL_INT_SWINT0:
670− gic_write(GIC_REG(VPE_OTHER, GIC_VPE_SWINT0_MAP), val);
714+ gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_SWINT0_MAP),
715+ val);
671716 break;
672717 case GIC_LOCAL_INT_SWINT1:
673− gic_write(GIC_REG(VPE_OTHER, GIC_VPE_SWINT1_MAP), val);
718+ gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_SWINT1_MAP),
719+ val);
674720 break;
675721 case GIC_LOCAL_INT_FDC:
676− gic_write(GIC_REG(VPE_OTHER, GIC_VPE_FDC_MAP), val);
722+ gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_FDC_MAP), val);
677723 break;
678724 default:
679725 pr_err("Invalid local IRQ %d\n", intr);
@@ -778,7 +824,7 @@ static void __init __gic_init(unsigned long gic_base_addr, · 98 unmodified lines
778824 */
779825 if (IS_ENABLED(CONFIG_MIPS_CMP) &&
780826 gic_local_irq_is_routable(GIC_LOCAL_INT_TIMER)) {
781− timer_cpu_pin = gic_read(GIC_REG(VPE_LOCAL,
827+ timer_cpu_pin = gic_read32(GIC_REG(VPE_LOCAL,
782828 GIC_VPE_TIMER_MAP)) &
783829 GIC_MAP_MSK;
784830 irq_set_chained_handler(MIPS_CPU_IRQ_BASE +
drivers/net/ethernet/ti/cpmac.c+2−0
@@ -41,6 +41,8 @@ · 40 unmodified lines
4141 #include <linux/gpio.h>
4242 #include <linux/atomic.h>
4343
44+#include <asm/mach-ar7/ar7.h>
45+
4446 MODULE_AUTHOR("Eugene Konev <ejka@imfi.kspu.ru>");
4547 MODULE_DESCRIPTION("TI AR7 ethernet driver (CPMAC)");
4648 MODULE_LICENSE("GPL");
drivers/staging/octeon/ethernet-rx.c+92−41
@@ -70,7 +70,14 @@ static irqreturn_t cvm_oct_do_interrupt(int cpl, void *dev_id) · 69 unmodified lines
7070 */
7171 static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work)
7272 {
73− if ((work->word2.snoip.err_code == 10) && (work->len <= 64)) {
73+ int port;
74+
75+ if (octeon_has_feature(OCTEON_FEATURE_PKND))
76+ port = work->word0.pip.cn68xx.pknd;
77+ else
78+ port = work->word1.cn38xx.ipprt;
79+
80+ if ((work->word2.snoip.err_code == 10) && (work->word1.len <= 64)) {
7481 /*
7582 * Ignore length errors on min size packets. Some
7683 * equipment incorrectly pads packets to 64+4FCS
@@ -87,8 +94,8 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) · 10 unmodified lines
8794 * packet to determine if we can remove a non spec
8895 * preamble and generate a correct packet.
8996 */
90− int interface = cvmx_helper_get_interface_num(work->ipprt);
91− int index = cvmx_helper_get_interface_index_num(work->ipprt);
97+ int interface = cvmx_helper_get_interface_num(port);
98+ int index = cvmx_helper_get_interface_index_num(port);
9299 union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
93100
94101 gmxx_rxx_frm_ctl.u64 =
@@ -99,7 +106,7 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) · 4 unmodified lines
99106 cvmx_phys_to_ptr(work->packet_ptr.s.addr);
100107 int i = 0;
101108
102− while (i < work->len - 1) {
109+ while (i < work->word1.len - 1) {
103110 if (*ptr != 0x55)
104111 break;
105112 ptr++;
@@ -109,18 +116,18 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) · 3 unmodified lines
109116 if (*ptr == 0xd5) {
110117 /*
111118 printk_ratelimited("Port %d received 0xd5 preamble\n",
112− work->ipprt);
119+ port);
113120 */
114121 work->packet_ptr.s.addr += i + 1;
115− work->len -= i + 5;
122+ work->word1.len -= i + 5;
116123 } else if ((*ptr & 0xf) == 0xd) {
117124 /*
118125 printk_ratelimited("Port %d received 0x?d preamble\n",
119− work->ipprt);
126+ port);
120127 */
121128 work->packet_ptr.s.addr += i;
122− work->len -= i + 4;
123− for (i = 0; i < work->len; i++) {
129+ work->word1.len -= i + 4;
130+ for (i = 0; i < work->word1.len; i++) {
124131 *ptr =
125132 ((*ptr & 0xf0) >> 4) |
126133 ((*(ptr + 1) & 0xf) << 4);
@@ -128,7 +135,7 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) · 1 unmodified line
128135 }
129136 } else {
130137 printk_ratelimited("Port %d unknown preamble, packet dropped\n",
131− work->ipprt);
138+ port);
132139 /*
133140 cvmx_helper_dump_packet(work);
134141 */
@@ -138,7 +145,7 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) · 3 unmodified lines
138145 }
139146 } else {
140147 printk_ratelimited("Port %d receive error code %d, packet dropped\n",
141− work->ipprt, work->word2.snoip.err_code);
148+ port, work->word2.snoip.err_code);
142149 cvm_oct_free_work(work);
143150 return 1;
144151 }
@@ -172,9 +179,16 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) · 27 unmodified lines
172179 }
173180
174181 /* Only allow work for our group (and preserve priorities) */
175− old_group_mask = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(coreid));
176− cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid),
177− (old_group_mask & ~0xFFFFull) | 1 << pow_receive_group);
182+ if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
183+ old_group_mask = cvmx_read_csr(CVMX_SSO_PPX_GRP_MSK(coreid));
184+ cvmx_write_csr(CVMX_SSO_PPX_GRP_MSK(coreid),
185+ 1ull << pow_receive_group);
186+ cvmx_read_csr(CVMX_SSO_PPX_GRP_MSK(coreid)); /* Flush */
187+ } else {
188+ old_group_mask = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(coreid));
189+ cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid),
190+ (old_group_mask & ~0xFFFFull) | 1 << pow_receive_group);
191+ }
178192
179193 if (USE_ASYNC_IOBDMA) {
180194 cvmx_pow_work_request_async(CVMX_SCR_SCRATCH, CVMX_POW_NO_WAIT);
@@ -186,6 +200,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) · 5 unmodified lines
186200 struct sk_buff **pskb = NULL;
187201 int skb_in_hw;
188202 cvmx_wqe_t *work;
203+ int port;
189204
190205 if (USE_ASYNC_IOBDMA && did_work_request)
191206 work = cvmx_pow_work_response_async(CVMX_SCR_SCRATCH);
@@ -195,12 +210,19 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) · 3 unmodified lines
195210 prefetch(work);
196211 did_work_request = 0;
197212 if (work == NULL) {
198− union cvmx_pow_wq_int wq_int;
213+ if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
214+ cvmx_write_csr(CVMX_SSO_WQ_IQ_DIS,
215+ 1ull << pow_receive_group);
216+ cvmx_write_csr(CVMX_SSO_WQ_INT,
217+ 1ull << pow_receive_group);
218+ } else {
219+ union cvmx_pow_wq_int wq_int;
199220
200− wq_int.u64 = 0;
201− wq_int.s.iq_dis = 1 << pow_receive_group;
202− wq_int.s.wq_int = 1 << pow_receive_group;
203− cvmx_write_csr(CVMX_POW_WQ_INT, wq_int.u64);
221+ wq_int.u64 = 0;
222+ wq_int.s.iq_dis = 1 << pow_receive_group;
223+ wq_int.s.wq_int = 1 << pow_receive_group;
224+ cvmx_write_csr(CVMX_POW_WQ_INT, wq_int.u64);
225+ }
204226 break;
205227 }
206228 pskb = (struct sk_buff **)(cvm_oct_get_buffer_ptr(work->packet_ptr) -
@@ -220,7 +242,13 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) · 13 unmodified lines
220242 prefetch(&skb->head);
221243 prefetch(&skb->len);
222244 }
223− prefetch(cvm_oct_device[work->ipprt]);
245+
246+ if (octeon_has_feature(OCTEON_FEATURE_PKND))
247+ port = work->word0.pip.cn68xx.pknd;
248+ else
249+ port = work->word1.cn38xx.ipprt;
250+
251+ prefetch(cvm_oct_device[port]);
224252
225253 /* Immediately throw away all packets with receive errors */
226254 if (unlikely(work->word2.snoip.rcv_error)) {
@@ -237,7 +265,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) · 10 unmodified lines
237265 skb->data = skb->head + work->packet_ptr.s.addr -
238266 cvmx_ptr_to_phys(skb->head);
239267 prefetch(skb->data);
240− skb->len = work->len;
268+ skb->len = work->word1.len;
241269 skb_set_tail_pointer(skb, skb->len);
242270 packet_not_copied = 1;
243271 } else {
@@ -245,7 +273,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) · 1 unmodified line
245273 * We have to copy the packet. First allocate
246274 * an skbuff for it.
247275 */
248− skb = dev_alloc_skb(work->len);
276+ skb = dev_alloc_skb(work->word1.len);
249277 if (!skb) {
250278 cvm_oct_free_work(work);
251279 continue;
@@ -268,13 +296,14 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) · 16 unmodified lines
268296 else
269297 ptr += 6;
270298 }
271− memcpy(skb_put(skb, work->len), ptr, work->len);
299+ memcpy(skb_put(skb, work->word1.len), ptr,
300+ work->word1.len);
272301 /* No packet buffers to free */
273302 } else {
274303 int segments = work->word2.s.bufs;
275304 union cvmx_buf_ptr segment_ptr =
276305 work->packet_ptr;
277− int len = work->len;
306+ int len = work->word1.len;
278307
279308 while (segments--) {
280309 union cvmx_buf_ptr next_ptr =
@@ -310,10 +339,9 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) · 29 unmodified lines
310339 }
311340 packet_not_copied = 0;
312341 }
313−
314− if (likely((work->ipprt < TOTAL_NUMBER_OF_PORTS) &&
315− cvm_oct_device[work->ipprt])) {
316− struct net_device *dev = cvm_oct_device[work->ipprt];
342+ if (likely((port < TOTAL_NUMBER_OF_PORTS) &&
343+ cvm_oct_device[port])) {
344+ struct net_device *dev = cvm_oct_device[port];
317345 struct octeon_ethernet *priv = netdev_priv(dev);
318346
319347 /*
@@ -333,7 +361,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) · 13 unmodified lines
333361 skb->ip_summed = CHECKSUM_UNNECESSARY;
334362
335363 /* Increment RX stats for virtual ports */
336− if (work->ipprt >= CVMX_PIP_NUM_INPUT_PORTS) {
364+ if (port >= CVMX_PIP_NUM_INPUT_PORTS) {
337365 #ifdef CONFIG_64BIT
338366 atomic64_add(1,
339367 (atomic64_t *)&priv->stats.rx_packets);
@@ -368,7 +396,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) · 28 unmodified lines
368396 * doesn't exist.
369397 */
370398 printk_ratelimited("Port %d not controlled by Linux, packet dropped\n",
371− work->ipprt);
399+ port);
372400 dev_kfree_skb_irq(skb);
373401 }
374402 /*
@@ -390,7 +418,13 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) · 15 unmodified lines
390418 }
391419 }
392420 /* Restore the original POW group mask */
393− cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid), old_group_mask);
421+ if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
422+ cvmx_write_csr(CVMX_SSO_PPX_GRP_MSK(coreid), old_group_mask);
423+ cvmx_read_csr(CVMX_SSO_PPX_GRP_MSK(coreid)); /* Flush */
424+ } else {
425+ cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid), old_group_mask);
426+ }
427+
394428 if (USE_ASYNC_IOBDMA) {
395429 /* Restore the scratch area */
396430 cvmx_scratch_write64(CVMX_SCR_SCRATCH, old_scratch);
@@ -422,8 +456,6 @@ void cvm_oct_rx_initialize(void) · 25 unmodified lines
422456 {
423457 int i;
424458 struct net_device *dev_for_napi = NULL;
425− union cvmx_pow_wq_int_thrx int_thr;
426− union cvmx_pow_wq_int_pc int_pc;
427459
428460 for (i = 0; i < TOTAL_NUMBER_OF_PORTS; i++) {
429461 if (cvm_oct_device[i]) {
@@ -449,15 +481,34 @@ void cvm_oct_rx_initialize(void) · 19 unmodified lines
449481
450482 disable_irq_nosync(OCTEON_IRQ_WORKQ0 + pow_receive_group);
451483
452− int_thr.u64 = 0;
453− int_thr.s.tc_en = 1;
454− int_thr.s.tc_thr = 1;
455484 /* Enable POW interrupt when our port has at least one packet */
456− cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), int_thr.u64);
457−
458− int_pc.u64 = 0;
459− int_pc.s.pc_thr = 5;
460− cvmx_write_csr(CVMX_POW_WQ_INT_PC, int_pc.u64);
485+ if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
486+ union cvmx_sso_wq_int_thrx int_thr;
487+ union cvmx_pow_wq_int_pc int_pc;
488+
489+ int_thr.u64 = 0;
490+ int_thr.s.tc_en = 1;
491+ int_thr.s.tc_thr = 1;
492+ cvmx_write_csr(CVMX_SSO_WQ_INT_THRX(pow_receive_group),
493+ int_thr.u64);
494+
495+ int_pc.u64 = 0;
496+ int_pc.s.pc_thr = 5;
497+ cvmx_write_csr(CVMX_SSO_WQ_INT_PC, int_pc.u64);
498+ } else {
499+ union cvmx_pow_wq_int_thrx int_thr;
500+ union cvmx_pow_wq_int_pc int_pc;
501+
502+ int_thr.u64 = 0;
503+ int_thr.s.tc_en = 1;
504+ int_thr.s.tc_thr = 1;
505+ cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group),
506+ int_thr.u64);
507+
508+ int_pc.u64 = 0;
509+ int_pc.s.pc_thr = 5;
510+ cvmx_write_csr(CVMX_POW_WQ_INT_PC, int_pc.u64);
511+ }
461512
462513 /* Schedule NAPI now. This will indirectly enable the interrupt. */
463514 napi_schedule(&cvm_oct_napi);
drivers/staging/octeon/ethernet-tx.c+10−9
@@ -591,13 +591,14 @@ int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev) · 590 unmodified lines
591591 * Fill in some of the work queue fields. We may need to add
592592 * more if the software at the other end needs them.
593593 */
594− work->hw_chksum = skb->csum;
595− work->len = skb->len;
596− work->ipprt = priv->port;
597− work->qos = priv->port & 0x7;
598− work->grp = pow_send_group;
599− work->tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
600− work->tag = pow_send_group; /* FIXME */
594+ if (!OCTEON_IS_MODEL(OCTEON_CN68XX))
595+ work->word0.pip.cn38xx.hw_chksum = skb->csum;
596+ work->word1.len = skb->len;
597+ cvmx_wqe_set_port(work, priv->port);
598+ cvmx_wqe_set_qos(work, priv->port & 0x7);
599+ cvmx_wqe_set_grp(work, pow_send_group);
600+ work->word1.tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
601+ work->word1.tag = pow_send_group; /* FIXME */
601602 /* Default to zero. Sets of zero later are commented out */
602603 work->word2.u64 = 0;
603604 work->word2.s.bufs = 1;
@@ -677,8 +678,8 @@ int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev) · 73 unmodified lines
677678 }
678679
679680 /* Submit the packet to the POW */
680− cvmx_pow_work_submit(work, work->tag, work->tag_type, work->qos,
681− work->grp);
681+ cvmx_pow_work_submit(work, work->word1.tag, work->word1.tag_type,
682+ cvmx_wqe_get_qos(work), cvmx_wqe_get_grp(work));
682683 priv->stats.tx_packets++;
683684 priv->stats.tx_bytes += skb->len;
684685 dev_consume_skb_any(skb);
drivers/staging/octeon/ethernet-util.h+11−11
@@ -8,6 +8,10 @@ · 7 unmodified lines
88 * published by the Free Software Foundation.
99 */
1010
11+#include <asm/octeon/cvmx-pip.h>
12+#include <asm/octeon/cvmx-helper.h>
13+#include <asm/octeon/cvmx-helper-util.h>
14+
1115 /**
1216 * cvm_oct_get_buffer_ptr - convert packet data address to pointer
1317 * @packet_ptr: Packet data hardware address
@@ -28,14 +32,12 @@ static inline void *cvm_oct_get_buffer_ptr(union cvmx_buf_ptr packet_ptr) · 14 unmodified lines
2832 */
2933 static inline int INTERFACE(int ipd_port)
3034 {
31− if (ipd_port < 32) /* Interface 0 or 1 for RGMII,GMII,SPI, etc */
32− return ipd_port >> 4;
33− else if (ipd_port < 36) /* Interface 2 for NPI */
34− return 2;
35− else if (ipd_port < 40) /* Interface 3 for loopback */
36− return 3;
37− else if (ipd_port == 40) /* Non existent interface for POW0 */
38− return 4;
35+ int interface = cvmx_helper_get_interface_num(ipd_port);
36+
37+ if (interface >= 0)
38+ return interface;
39+ else if (ipd_port == CVMX_PIP_NUM_INPUT_PORTS)
40+ return 10;
3941 panic("Illegal ipd_port %d passed to INTERFACE\n", ipd_port);
4042 }
4143
@@ -47,7 +49,5 @@ static inline int INTERFACE(int ipd_port) · 5 unmodified lines
4749 */
4850 static inline int INDEX(int ipd_port)
4951 {
50− if (ipd_port < 32)
51− return ipd_port & 15;
52− return ipd_port & 3;
52+ return cvmx_helper_get_interface_index_num(ipd_port);
5353 }
drivers/staging/octeon/ethernet.c+5−2
@@ -152,7 +152,7 @@ static void cvm_oct_configure_common_hw(void) · 151 unmodified lines
152152 num_packet_buffers);
153153 if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL)
154154 cvm_oct_mem_fill_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
155− CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128);
155+ CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 1024);
156156
157157 #ifdef __LITTLE_ENDIAN
158158 {
@@ -860,7 +860,10 @@ static int cvm_oct_remove(struct platform_device *pdev) · 701 unmodified lines
860860 int port;
861861
862862 /* Disable POW interrupt */
863− cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0);
863+ if (OCTEON_IS_MODEL(OCTEON_CN68XX))
864+ cvmx_write_csr(CVMX_SSO_WQ_INT_THRX(pow_receive_group), 0);
865+ else
866+ cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0);
864867
865868 cvmx_ipd_disable();
866869
drivers/tty/mips_ejtag_fdc.c+6−3
@@ -879,6 +879,11 @@ static const struct tty_operations mips_ejtag_fdc_tty_ops = { · 878 unmodified lines
879879 .chars_in_buffer = mips_ejtag_fdc_tty_chars_in_buffer,
880880 };
881881
882+int __weak get_c0_fdc_int(void)
883+{
884+ return -1;
885+}
886+
882887 static int mips_ejtag_fdc_tty_probe(struct mips_cdmm_device *dev)
883888 {
884889 int ret, nport;
@@ -967,9 +972,7 @@ static int mips_ejtag_fdc_tty_probe(struct mips_cdmm_device *dev) · 82 unmodified lines
967972 wake_up_process(priv->thread);
968973
969974 /* Look for an FDC IRQ */
970− priv->irq = -1;
971− if (get_c0_fdc_int)
972− priv->irq = get_c0_fdc_int();
975+ priv->irq = get_c0_fdc_int();
973976
974977 /* Try requesting the IRQ */
975978 if (priv->irq >= 0) {
include/linux/irqchip/mips-gic.h+12−2
@@ -41,12 +41,20 @@ · 40 unmodified lines
4141
4242 /* Shared Global Counter */
4343 #define GIC_SH_COUNTER_31_00_OFS 0x0010
44+/* 64-bit counter register for CM3 */
45+#define GIC_SH_COUNTER_OFS GIC_SH_COUNTER_31_00_OFS
4446 #define GIC_SH_COUNTER_63_32_OFS 0x0014
4547 #define GIC_SH_REVISIONID_OFS 0x0020
4648
4749 /* Convert an interrupt number to a byte offset/bit for multi-word registers */
48−#define GIC_INTR_OFS(intr) (((intr) / 32) * 4)
49−#define GIC_INTR_BIT(intr) ((intr) % 32)
50+#define GIC_INTR_OFS(intr) ({ \
51+ unsigned bits = mips_cm_is64 ? 64 : 32; \
52+ unsigned reg_idx = (intr) / bits; \
53+ unsigned reg_width = bits / 8; \
54+ \
55+ reg_idx * reg_width; \
56+})
57+#define GIC_INTR_BIT(intr) ((intr) % (mips_cm_is64 ? 64 : 32))
5058
5159 /* Polarity : Reset Value is always 0 */
5260 #define GIC_SH_SET_POLARITY_OFS 0x0100
@@ -98,6 +106,8 @@ · 45 unmodified lines
98106 #define GIC_VPE_WD_COUNT0_OFS 0x0094
99107 #define GIC_VPE_WD_INITIAL0_OFS 0x0098
100108 #define GIC_VPE_COMPARE_LO_OFS 0x00a0
109+/* 64-bit Compare register on CM3 */
110+#define GIC_VPE_COMPARE_OFS GIC_VPE_COMPARE_LO_OFS
101111 #define GIC_VPE_COMPARE_HI_OFS 0x00a4
102112
103113 #define GIC_VPE_EIC_SHADOW_SET_BASE_OFS 0x0100

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t