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
3Required 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
15Example:
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
22 | m68k: | TODO |22 | m68k: | TODO |
23 | metag: | TODO |23 | metag: | TODO |
24 | microblaze: | TODO |24 | microblaze: | TODO |
25 | mips: | TODO |25 | mips: | ok |
26 | mn10300: | TODO |26 | mn10300: | TODO |
27 | nios2: | TODO |27 | nios2: | TODO |
28 | openrisc: | TODO |28 | 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
119 119
120'x' - Used by xmon interface on ppc/powerpc platforms.120'x' - Used by xmon interface on ppc/powerpc platforms.
121 Show global PMU Registers on sparc64.121 Show global PMU Registers on sparc64.
122 Dump all TLB entries on MIPS.
122 123
123'y' - Show global CPU Registers [SPARC-64 specific]124'y' - Show global CPU Registers [SPARC-64 specific]
124 125
arch/mips/Kconfig+17−8
@@ -1,8 +1,10 @@
1config MIPS1config MIPS
2 bool2 bool
3 default y3 default y
4 select ARCH_SUPPORTS_UPROBES
4 select ARCH_MIGHT_HAVE_PC_PARPORT5 select ARCH_MIGHT_HAVE_PC_PARPORT
5 select ARCH_MIGHT_HAVE_PC_SERIO6 select ARCH_MIGHT_HAVE_PC_SERIO
7 select ARCH_USE_CMPXCHG_LOCKREF if 64BIT
6 select HAVE_CONTEXT_TRACKING8 select HAVE_CONTEXT_TRACKING
7 select HAVE_GENERIC_DMA_COHERENT9 select HAVE_GENERIC_DMA_COHERENT
8 select HAVE_IDE10 select HAVE_IDE
@@ -13,7 +15,6 @@ config MIPS · 4 unmodified lines
13 select HAVE_ARCH_SECCOMP_FILTER15 select HAVE_ARCH_SECCOMP_FILTER
14 select HAVE_ARCH_TRACEHOOK16 select HAVE_ARCH_TRACEHOOK
15 select HAVE_BPF_JIT if !CPU_MICROMIPS17 select HAVE_BPF_JIT if !CPU_MICROMIPS
16 select ARCH_HAVE_CUSTOM_GPIO_H
17 select HAVE_FUNCTION_TRACER18 select HAVE_FUNCTION_TRACER
18 select HAVE_DYNAMIC_FTRACE19 select HAVE_DYNAMIC_FTRACE
19 select HAVE_FTRACE_MCOUNT_RECORD20 select HAVE_FTRACE_MCOUNT_RECORD
@@ -409,6 +410,7 @@ config MIPS_MALTA · 389 unmodified lines
409 select CEVT_R4K410 select CEVT_R4K
410 select CSRC_R4K411 select CSRC_R4K
411 select CLKSRC_MIPS_GIC412 select CLKSRC_MIPS_GIC
413 select COMMON_CLK
412 select DMA_MAYBE_COHERENT414 select DMA_MAYBE_COHERENT
413 select GENERIC_ISA_DMA415 select GENERIC_ISA_DMA
414 select HAVE_PCSPKR_PLATFORM416 select HAVE_PCSPKR_PLATFORM
@@ -459,6 +461,7 @@ config MIPS_SEAD3 · 44 unmodified lines
459 select CEVT_R4K461 select CEVT_R4K
460 select CSRC_R4K462 select CSRC_R4K
461 select CLKSRC_MIPS_GIC463 select CLKSRC_MIPS_GIC
464 select COMMON_CLK
462 select CPU_MIPSR2_IRQ_VI465 select CPU_MIPSR2_IRQ_VI
463 select CPU_MIPSR2_IRQ_EI466 select CPU_MIPSR2_IRQ_EI
464 select DMA_NONCOHERENT467 select DMA_NONCOHERENT
@@ -899,6 +902,7 @@ config NLM_XLP_BOARD · 434 unmodified lines
899 select SYS_SUPPORTS_32BIT_KERNEL902 select SYS_SUPPORTS_32BIT_KERNEL
900 select SYS_SUPPORTS_64BIT_KERNEL903 select SYS_SUPPORTS_64BIT_KERNEL
901 select ARCH_PHYS_ADDR_T_64BIT904 select ARCH_PHYS_ADDR_T_64BIT
905 select ARCH_REQUIRE_GPIOLIB
902 select SYS_SUPPORTS_BIG_ENDIAN906 select SYS_SUPPORTS_BIG_ENDIAN
903 select SYS_SUPPORTS_LITTLE_ENDIAN907 select SYS_SUPPORTS_LITTLE_ENDIAN
904 select SYS_SUPPORTS_HIGHMEM908 select SYS_SUPPORTS_HIGHMEM
@@ -948,6 +952,7 @@ source "arch/mips/jazz/Kconfig" · 43 unmodified lines
948source "arch/mips/jz4740/Kconfig"952source "arch/mips/jz4740/Kconfig"
949source "arch/mips/lantiq/Kconfig"953source "arch/mips/lantiq/Kconfig"
950source "arch/mips/lasat/Kconfig"954source "arch/mips/lasat/Kconfig"
955source "arch/mips/pistachio/Kconfig"
951source "arch/mips/pmcs-msp71xx/Kconfig"956source "arch/mips/pmcs-msp71xx/Kconfig"
952source "arch/mips/ralink/Kconfig"957source "arch/mips/ralink/Kconfig"
953source "arch/mips/sgi-ip27/Kconfig"958source "arch/mips/sgi-ip27/Kconfig"
@@ -1041,6 +1046,9 @@ config FW_CFE · 87 unmodified lines
1041config ARCH_DMA_ADDR_T_64BIT1046config ARCH_DMA_ADDR_T_64BIT
1042 def_bool (HIGHMEM && ARCH_PHYS_ADDR_T_64BIT) || 64BIT1047 def_bool (HIGHMEM && ARCH_PHYS_ADDR_T_64BIT) || 64BIT
1043 1048
1049config ARCH_SUPPORTS_UPROBES
1050 bool
1051
1044config DMA_MAYBE_COHERENT1052config DMA_MAYBE_COHERENT
1045 select DMA_NONCOHERENT1053 select DMA_NONCOHERENT
1046 bool1054 bool
@@ -1364,7 +1372,7 @@ config CPU_MIPS32_R2 · 317 unmodified lines
1364 otherwise CPU_MIPS32_R1 is a safe bet for any MIPS32 system.1372 otherwise CPU_MIPS32_R1 is a safe bet for any MIPS32 system.
1365 1373
1366config CPU_MIPS32_R61374config CPU_MIPS32_R6
1367 bool "MIPS32 Release 6 (EXPERIMENTAL)"1375 bool "MIPS32 Release 6"
1368 depends on SYS_HAS_CPU_MIPS32_R61376 depends on SYS_HAS_CPU_MIPS32_R6
1369 select CPU_HAS_PREFETCH1377 select CPU_HAS_PREFETCH
1370 select CPU_SUPPORTS_32BIT_KERNEL1378 select CPU_SUPPORTS_32BIT_KERNEL
@@ -1415,7 +1423,7 @@ config CPU_MIPS64_R2 · 44 unmodified lines
1415 otherwise CPU_MIPS64_R1 is a safe bet for any MIPS64 system.1423 otherwise CPU_MIPS64_R1 is a safe bet for any MIPS64 system.
1416 1424
1417config CPU_MIPS64_R61425config CPU_MIPS64_R6
1418 bool "MIPS64 Release 6 (EXPERIMENTAL)"1426 bool "MIPS64 Release 6"
1419 depends on SYS_HAS_CPU_MIPS64_R61427 depends on SYS_HAS_CPU_MIPS64_R6
1420 select CPU_HAS_PREFETCH1428 select CPU_HAS_PREFETCH
1421 select CPU_SUPPORTS_32BIT_KERNEL1429 select CPU_SUPPORTS_32BIT_KERNEL
@@ -1965,6 +1973,7 @@ config 32BIT · 543 unmodified lines
1965 select TRAD_SIGNALS1973 select TRAD_SIGNALS
1966 help1974 help
1967 Select this option if you want to build a 32-bit kernel.1975 Select this option if you want to build a 32-bit kernel.
1976
1968config 64BIT1977config 64BIT
1969 bool "64-bit kernel"1978 bool "64-bit kernel"
1970 depends on CPU_SUPPORTS_64BIT_KERNEL && SYS_SUPPORTS_64BIT_KERNEL1979 depends on CPU_SUPPORTS_64BIT_KERNEL && SYS_SUPPORTS_64BIT_KERNEL
@@ -2110,7 +2119,7 @@ config CPU_R4K_CACHE_TLB · 139 unmodified lines
2110 2119
2111config MIPS_MT_SMP2120config MIPS_MT_SMP
2112 bool "MIPS MT SMP support (1 TC on each available VPE)"2121 bool "MIPS MT SMP support (1 TC on each available VPE)"
2113 depends on SYS_SUPPORTS_MULTITHREADING2122 depends on SYS_SUPPORTS_MULTITHREADING && !CPU_MIPSR6
2114 select CPU_MIPSR2_IRQ_VI2123 select CPU_MIPSR2_IRQ_VI
2115 select CPU_MIPSR2_IRQ_EI2124 select CPU_MIPSR2_IRQ_EI
2116 select SYNC_R4K2125 select SYNC_R4K
@@ -2211,7 +2220,7 @@ config MIPS_VPE_APSP_API_MT · 94 unmodified lines
2211 2220
2212config MIPS_CMP2221config MIPS_CMP
2213 bool "MIPS CMP framework support (DEPRECATED)"2222 bool "MIPS CMP framework support (DEPRECATED)"
2214 depends on SYS_SUPPORTS_MIPS_CMP2223 depends on SYS_SUPPORTS_MIPS_CMP && !CPU_MIPSR6
2215 select MIPS_GIC_IPI2224 select MIPS_GIC_IPI
2216 select SMP2225 select SMP
2217 select SYNC_R4K2226 select SYNC_R4K
@@ -2228,7 +2237,7 @@ config MIPS_CMP · 10 unmodified lines
2228 2237
2229config MIPS_CPS2238config MIPS_CPS
2230 bool "MIPS Coherent Processing System support"2239 bool "MIPS Coherent Processing System support"
2231 depends on SYS_SUPPORTS_MIPS_CPS2240 depends on SYS_SUPPORTS_MIPS_CPS && !CPU_MIPSR6
2232 select MIPS_CM2241 select MIPS_CM
2233 select MIPS_CPC2242 select MIPS_CPC
2234 select MIPS_CPS_PM if HOTPLUG_CPU2243 select MIPS_CPS_PM if HOTPLUG_CPU
@@ -2303,7 +2312,7 @@ config CPU_MICROMIPS · 68 unmodified lines
2303endchoice2312endchoice
2304 2313
2305config CPU_HAS_MSA2314config CPU_HAS_MSA
2306 bool "Support for the MIPS SIMD Architecture (EXPERIMENTAL)"2315 bool "Support for the MIPS SIMD Architecture"
2307 depends on CPU_SUPPORTS_MSA2316 depends on CPU_SUPPORTS_MSA
2308 depends on 64BIT || MIPS_O32_FP64_SUPPORT2317 depends on 64BIT || MIPS_O32_FP64_SUPPORT
2309 help2318 help
@@ -2643,7 +2652,7 @@ config SECCOMP · 333 unmodified lines
2643 If unsure, say Y. Only embedded should say N here.2652 If unsure, say Y. Only embedded should say N here.
2644 2653
2645config MIPS_O32_FP64_SUPPORT2654config 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"
2647 depends on 32BIT || MIPS32_O322656 depends on 32BIT || MIPS32_O32
2648 help2657 help
2649 When this is enabled, the kernel will support use of 64-bit floating2658 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
87 Select compile flags that produce code that can be processed by the87 Select compile flags that produce code that can be processed by the
88 Corelis mksym utility and UDB Emulator.88 Corelis mksym utility and UDB Emulator.
89 89
90config 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
99config DEBUG_ZBOOT90config DEBUG_ZBOOT
100 bool "Enable compressed kernel support debugging"91 bool "Enable compressed kernel support debugging"
101 depends on DEBUG_KERNEL && SYS_SUPPORTS_ZBOOT92 depends on DEBUG_KERNEL && SYS_SUPPORTS_ZBOOT
arch/mips/alchemy/Kconfig+0−7
@@ -6,13 +6,6 @@ config ALCHEMY_GPIOINT_AU1000 · 5 unmodified lines
6config ALCHEMY_GPIOINT_AU13006config ALCHEMY_GPIOINT_AU1300
7 bool7 bool
8 8
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.
13config ALCHEMY_GPIO_INDIRECT
14 def_bool n
15
16choice9choice
17 prompt "Machine type"10 prompt "Machine type"
18 depends on MIPS_ALCHEMY11 depends on MIPS_ALCHEMY
arch/mips/alchemy/board-gpr.c+1−0
@@ -34,6 +34,7 @@ · 33 unmodified lines
34#include <asm/idle.h>34#include <asm/idle.h>
35#include <asm/reboot.h>35#include <asm/reboot.h>
36#include <asm/mach-au1x00/au1000.h>36#include <asm/mach-au1x00/au1000.h>
37#include <asm/mach-au1x00/gpio-au1000.h>
37#include <prom.h>38#include <prom.h>
38 39
39const char *get_system_type(void)40const char *get_system_type(void)
arch/mips/alchemy/board-mtx1.c+1−0
@@ -32,6 +32,7 @@ · 31 unmodified lines
32#include <asm/bootinfo.h>32#include <asm/bootinfo.h>
33#include <asm/reboot.h>33#include <asm/reboot.h>
34#include <asm/mach-au1x00/au1000.h>34#include <asm/mach-au1x00/au1000.h>
35#include <asm/mach-au1x00/gpio-au1000.h>
35#include <asm/mach-au1x00/au1xxx_eth.h>36#include <asm/mach-au1x00/au1xxx_eth.h>
36#include <prom.h>37#include <prom.h>
37 38
arch/mips/alchemy/common/Makefile+1−6
@@ -5,10 +5,5 @@ · 4 unmodified lines
5# Makefile for the Alchemy Au1xx0 CPUs, generic files.5# Makefile for the Alchemy Au1xx0 CPUs, generic files.
6#6#
7 7
8obj-y += prom.o time.o clock.o platform.o power.o \8obj-y += prom.o time.o clock.o platform.o power.o gpiolib.o \
9 setup.o sleeper.o dma.o dbdma.o vss.o irq.o usb.o9 setup.o sleeper.o dma.o dbdma.o vss.o irq.o usb.o
10
11# optional gpiolib support
12ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),)
13 obj-$(CONFIG_GPIOLIB) += gpiolib.o
14endif
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
491 default:491 default:
492 ret = -EINVAL;492 ret = -EINVAL;
493 }493 }
494 __irq_set_chip_handler_name_locked(d->irq, chip, handler, name);494 irq_set_chip_handler_name_locked(d, chip, handler, name);
495 495
496 wmb();496 wmb();
497 497
@@ -703,7 +703,7 @@ static int au1300_gpic_settype(struct irq_data *d, unsigned int type) · 205 unmodified lines
703 return -EINVAL;703 return -EINVAL;
704 }704 }
705 705
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);
707 707
708 au1300_gpic_chgcfg(d->irq - ALCHEMY_GPIC_INT_BASE, GPIC_CFG_IC_MASK, s);708 au1300_gpic_chgcfg(d->irq - ALCHEMY_GPIC_INT_BASE, GPIC_CFG_IC_MASK, s);
709 709
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
69 return 0;69 return 0;
70}70}
71 71
72static void au1x_rtcmatch2_set_mode(enum clock_event_mode mode,
73 struct clock_event_device *cd)
74{
75}
76
77static irqreturn_t au1x_rtcmatch2_irq(int irq, void *dev_id)72static irqreturn_t au1x_rtcmatch2_irq(int irq, void *dev_id)
78{73{
79 struct clock_event_device *cd = dev_id;74 struct clock_event_device *cd = dev_id;
@@ -86,7 +81,6 @@ static struct clock_event_device au1x_rtcmatch2_clockdev = { · 6 unmodified lines
86 .features = CLOCK_EVT_FEAT_ONESHOT,81 .features = CLOCK_EVT_FEAT_ONESHOT,
87 .rating = 1500,82 .rating = 1500,
88 .set_next_event = au1x_rtcmatch2_set_next_event,83 .set_next_event = au1x_rtcmatch2_set_next_event,
89 .set_mode = au1x_rtcmatch2_set_mode,
90 .cpumask = cpu_all_mask,84 .cpumask = cpu_all_mask,
91};85};
92 86
arch/mips/alchemy/devboards/bcsr.c+4−2
@@ -8,6 +8,7 @@ · 7 unmodified lines
8 */8 */
9 9
10#include <linux/interrupt.h>10#include <linux/interrupt.h>
11#include <linux/irqchip/chained_irq.h>
11#include <linux/module.h>12#include <linux/module.h>
12#include <linux/spinlock.h>13#include <linux/spinlock.h>
13#include <linux/irq.h>14#include <linux/irq.h>
@@ -88,10 +89,11 @@ EXPORT_SYMBOL_GPL(bcsr_mod); · 74 unmodified lines
88static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d)89static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d)
89{90{
90 unsigned short bisr = __raw_readw(bcsr_virt + BCSR_REG_INTSTAT);91 unsigned short bisr = __raw_readw(bcsr_virt + BCSR_REG_INTSTAT);
92 struct irq_chip *chip = irq_desc_get_chip(d);
91 93
92 disable_irq_nosync(irq);94 chained_irq_enter(chip, d);
93 generic_handle_irq(bcsr_csc_base + __ffs(bisr));95 generic_handle_irq(bcsr_csc_base + __ffs(bisr));
94 enable_irq(irq);96 chained_irq_exit(chip, d);
95}97}
96 98
97static void bcsr_irq_mask(struct irq_data *d)99static void bcsr_irq_mask(struct irq_data *d)
arch/mips/alchemy/devboards/db1000.c+1−0
@@ -33,6 +33,7 @@ · 32 unmodified lines
33#include <linux/spi/spi_gpio.h>33#include <linux/spi/spi_gpio.h>
34#include <linux/spi/ads7846.h>34#include <linux/spi/ads7846.h>
35#include <asm/mach-au1x00/au1000.h>35#include <asm/mach-au1x00/au1000.h>
36#include <asm/mach-au1x00/gpio-au1000.h>
36#include <asm/mach-au1x00/au1000_dma.h>37#include <asm/mach-au1x00/au1000_dma.h>
37#include <asm/mach-au1x00/au1100_mmc.h>38#include <asm/mach-au1x00/au1100_mmc.h>
38#include <asm/mach-db1x00/bcsr.h>39#include <asm/mach-db1x00/bcsr.h>
arch/mips/alchemy/devboards/db1300.c+1−0
@@ -24,6 +24,7 @@ · 23 unmodified lines
24#include <linux/wm97xx.h>24#include <linux/wm97xx.h>
25 25
26#include <asm/mach-au1x00/au1000.h>26#include <asm/mach-au1x00/au1000.h>
27#include <asm/mach-au1x00/gpio-au1300.h>
27#include <asm/mach-au1x00/au1100_mmc.h>28#include <asm/mach-au1x00/au1100_mmc.h>
28#include <asm/mach-au1x00/au1200fb.h>29#include <asm/mach-au1x00/au1200fb.h>
29#include <asm/mach-au1x00/au1xxx_dbdma.h>30#include <asm/mach-au1x00/au1xxx_dbdma.h>
arch/mips/alchemy/devboards/db1550.c+1−0
@@ -20,6 +20,7 @@ · 19 unmodified lines
20#include <linux/spi/flash.h>20#include <linux/spi/flash.h>
21#include <asm/bootinfo.h>21#include <asm/bootinfo.h>
22#include <asm/mach-au1x00/au1000.h>22#include <asm/mach-au1x00/au1000.h>
23#include <asm/mach-au1x00/gpio-au1000.h>
23#include <asm/mach-au1x00/au1xxx_eth.h>24#include <asm/mach-au1x00/au1xxx_eth.h>
24#include <asm/mach-au1x00/au1xxx_dbdma.h>25#include <asm/mach-au1x00/au1xxx_dbdma.h>
25#include <asm/mach-au1x00/au1xxx_psc.h>26#include <asm/mach-au1x00/au1xxx_psc.h>
arch/mips/alchemy/devboards/pm.c+1−1
@@ -9,7 +9,7 @@ · 8 unmodified lines
9#include <linux/suspend.h>9#include <linux/suspend.h>
10#include <linux/sysfs.h>10#include <linux/sysfs.h>
11#include <asm/mach-au1x00/au1000.h>11#include <asm/mach-au1x00/au1000.h>
12#include <asm/mach-au1x00/gpio.h>12#include <asm/mach-au1x00/gpio-au1000.h>
13#include <asm/mach-db1x00/bcsr.h>13#include <asm/mach-db1x00/bcsr.h>
14 14
15/*15/*
arch/mips/ar7/gpio.c+4−1
@@ -21,7 +21,10 @@ · 20 unmodified lines
21#include <linux/module.h>21#include <linux/module.h>
22#include <linux/gpio.h>22#include <linux/gpio.h>
23 23
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
25 28
26struct ar7_gpio_chip {29struct ar7_gpio_chip {
27 void __iomem *regs;30 void __iomem *regs;
arch/mips/ar7/platform.c+0−1
@@ -39,7 +39,6 @@ · 38 unmodified lines
39 39
40#include <asm/addrspace.h>40#include <asm/addrspace.h>
41#include <asm/mach-ar7/ar7.h>41#include <asm/mach-ar7/ar7.h>
42#include <asm/mach-ar7/gpio.h>
43#include <asm/mach-ar7/prom.h>42#include <asm/mach-ar7/prom.h>
44 43
45/*****************************************************************************44/*****************************************************************************
arch/mips/ar7/setup.c+0−1
@@ -23,7 +23,6 @@ · 22 unmodified lines
23#include <asm/reboot.h>23#include <asm/reboot.h>
24#include <asm/mach-ar7/ar7.h>24#include <asm/mach-ar7/ar7.h>
25#include <asm/mach-ar7/prom.h>25#include <asm/mach-ar7/prom.h>
26#include <asm/mach-ar7/gpio.h>
27 26
28static void ar7_machine_restart(char *command)27static void ar7_machine_restart(char *command)
29{28{
arch/mips/ath79/Makefile+1−1
@@ -8,7 +8,7 @@ · 7 unmodified lines
8# under the terms of the GNU General Public License version 2 as published8# under the terms of the GNU General Public License version 2 as published
9# by the Free Software Foundation.9# by the Free Software Foundation.
10 10
11obj-y := prom.o setup.o irq.o common.o clock.o gpio.o11obj-y := prom.o setup.o irq.o common.o clock.o
12 12
13obj-$(CONFIG_EARLY_PRINTK) += early_printk.o13obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
14obj-$(CONFIG_PCI) += pci.o14obj-$(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
25void ath79_ddr_ctrl_init(void);25void ath79_ddr_ctrl_init(void);
26void ath79_ddr_wb_flush(unsigned int reg);26void ath79_ddr_wb_flush(unsigned int reg);
27 27
28void ath79_gpio_function_enable(u32 mask);
29void ath79_gpio_function_disable(u32 mask);
30void ath79_gpio_function_setup(u32 set, u32 clear);
31void ath79_gpio_init(void);28void ath79_gpio_init(void);
32 29
33#endif /* __ATH79_COMMON_H */30#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
123{123{
124 u32 status;124 u32 status;
125 125
126 disable_irq_nosync(irq);
127
128 status = ath79_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS);126 status = ath79_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS);
129 127
130 if (status & AR934X_PCIE_WMAC_INT_PCIE_ALL) {128 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
136 } else {134 } else {
137 spurious_interrupt();135 spurious_interrupt();
138 }136 }
139
140 enable_irq(irq);
141}137}
142 138
143static void ar934x_ip2_irq_init(void)139static 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
156{152{
157 u32 status;153 u32 status;
158 154
159 disable_irq_nosync(irq);
160
161 status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS);155 status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS);
162 status &= QCA955X_EXT_INT_PCIE_RC1_ALL | QCA955X_EXT_INT_WMAC_ALL;156 status &= QCA955X_EXT_INT_PCIE_RC1_ALL | QCA955X_EXT_INT_WMAC_ALL;
163 157
164 if (status == 0) {158 if (status == 0) {
165 spurious_interrupt();159 spurious_interrupt();
166 goto enable;160 return;
167 }161 }
168 162
169 if (status & QCA955X_EXT_INT_PCIE_RC1_ALL) {163 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
175 /* TODO: flush DDR? */169 /* TODO: flush DDR? */
176 generic_handle_irq(ATH79_IP2_IRQ(1));170 generic_handle_irq(ATH79_IP2_IRQ(1));
177 }171 }
178
179enable:
180 enable_irq(irq);
181}172}
182 173
183static void qca955x_ip3_irq_dispatch(unsigned int irq, struct irq_desc *desc)174static void qca955x_ip3_irq_dispatch(unsigned int irq, struct irq_desc *desc)
184{175{
185 u32 status;176 u32 status;
186 177
187 disable_irq_nosync(irq);
188
189 status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS);178 status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS);
190 status &= QCA955X_EXT_INT_PCIE_RC2_ALL |179 status &= QCA955X_EXT_INT_PCIE_RC2_ALL |
191 QCA955X_EXT_INT_USB1 |180 QCA955X_EXT_INT_USB1 |
@@ -193,7 +182,7 @@ static void qca955x_ip3_irq_dispatch(unsigned int irq, struct irq_desc *desc) · 1 unmodified line
193 182
194 if (status == 0) {183 if (status == 0) {
195 spurious_interrupt();184 spurious_interrupt();
196 goto enable;185 return;
197 }186 }
198 187
199 if (status & QCA955X_EXT_INT_USB1) {188 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
210 /* TODO: flush DDR? */199 /* TODO: flush DDR? */
211 generic_handle_irq(ATH79_IP3_IRQ(2));200 generic_handle_irq(ATH79_IP3_IRQ(2));
212 }201 }
213
214enable:
215 enable_irq(irq);
216}202}
217 203
218static void qca955x_irq_init(void)204static 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
396{396{
397 size_t size = nbuttons * sizeof(*buttons);397 size_t size = nbuttons * sizeof(*buttons);
398 398
399 bcm47xx_button_pdata.buttons = kmalloc(size, GFP_KERNEL);399 bcm47xx_button_pdata.buttons = kmemdup(buttons, size, GFP_KERNEL);
400 if (!bcm47xx_button_pdata.buttons)400 if (!bcm47xx_button_pdata.buttons)
401 return -ENOMEM;401 return -ENOMEM;
402 memcpy(bcm47xx_button_pdata.buttons, buttons, size);
403 bcm47xx_button_pdata.nbuttons = nbuttons;402 bcm47xx_button_pdata.nbuttons = nbuttons;
404 403
405 return 0;404 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
60 if (m)60 if (m)
61 enable &= cpumask_test_cpu(cpu, m);61 enable &= cpumask_test_cpu(cpu, m);
62 else if (irqd_affinity_was_set(d))62 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));
64#endif64#endif
65 return enable;65 return enable;
66}66}
@@ -365,9 +365,9 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d, · 298 unmodified lines
365 365
366 irqd_set_trigger_type(d, flow_type);366 irqd_set_trigger_type(d, flow_type);
367 if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))367 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);
369 else369 else
370 __irq_set_handler_locked(d->irq, handle_edge_irq);370 irq_set_handler_locked(d, handle_edge_irq);
371 371
372 return IRQ_SET_MASK_OK_NOCOPY;372 return IRQ_SET_MASK_OK_NOCOPY;
373}373}
arch/mips/boot/compressed/Makefile+1−1
@@ -78,7 +78,7 @@ endif · 77 unmodified lines
78 78
79vmlinuzobjs-y += $(obj)/piggy.o79vmlinuzobjs-y += $(obj)/piggy.o
80 80
81quiet_cmd_zld = LD $@81quiet_cmd_zld = LD $@
82 cmd_zld = $(LD) $(LDFLAGS) -Ttext $(VMLINUZ_LOAD_ADDRESS) -T $< $(vmlinuzobjs-y) -o $@82 cmd_zld = $(LD) $(LDFLAGS) -Ttext $(VMLINUZ_LOAD_ADDRESS) -T $< $(vmlinuzobjs-y) -o $@
83quiet_cmd_strip = STRIP $@83quiet_cmd_strip = STRIP $@
84 cmd_strip = $(STRIP) -s $@84 cmd_strip = $(STRIP) -s $@
arch/mips/boot/dts/netlogic/xlp_evp.dts+12−0
@@ -110,6 +110,18 @@ · 109 unmodified lines
110 read-only;110 read-only;
111 };111 };
112 };112 };
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 };
113 };125 };
114 126
115 chosen {127 chosen {
arch/mips/boot/dts/netlogic/xlp_fvp.dts+12−0
@@ -110,6 +110,18 @@ · 109 unmodified lines
110 read-only;110 read-only;
111 };111 };
112 };112 };
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 };
113 };125 };
114 126
115 chosen {127 chosen {
arch/mips/boot/dts/netlogic/xlp_gvp.dts+11−0
@@ -69,6 +69,17 @@ · 68 unmodified lines
69 };69 };
70 };70 };
71 71
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 };
72 };83 };
73 84
74 chosen {85 chosen {
arch/mips/boot/dts/netlogic/xlp_rvp.dts+11−0
@@ -69,6 +69,17 @@ · 68 unmodified lines
69 };69 };
70 };70 };
71 71
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 };
72 };83 };
73 84
74 chosen {85 chosen {
arch/mips/boot/dts/netlogic/xlp_svp.dts+12−0
@@ -110,6 +110,18 @@ · 109 unmodified lines
110 read-only;110 read-only;
111 };111 };
112 };112 };
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 };
113 };125 };
114 126
115 chosen {127 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
195 return 8;195 return 8;
196 else196 else
197 return -1;197 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
198 }204 }
199 205
200 /* Some unknown board. Somebody forgot to update this function... */206 /* 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
95 uint8_t *data_address;95 uint8_t *data_address;
96 uint8_t *end_of_data;96 uint8_t *end_of_data;
97 97
98 cvmx_dprintf("Packet Length: %u\n", work->len);98 cvmx_dprintf("Packet Length: %u\n", work->word1.len);
99 cvmx_dprintf(" Input Port: %u\n", work->ipprt);99 cvmx_dprintf(" Input Port: %u\n", cvmx_wqe_get_port(work));
100 cvmx_dprintf(" QoS: %u\n", work->qos);100 cvmx_dprintf(" QoS: %u\n", cvmx_wqe_get_qos(work));
101 cvmx_dprintf(" Buffers: %u\n", work->word2.s.bufs);101 cvmx_dprintf(" Buffers: %u\n", work->word2.s.bufs);
102 102
103 if (work->word2.s.bufs == 0) {103 if (work->word2.s.bufs == 0) {
@@ -127,7 +127,7 @@ int cvmx_helper_dump_packet(cvmx_wqe_t *work) · 23 unmodified lines
127 }127 }
128 } else128 } else
129 buffer_ptr = work->packet_ptr;129 buffer_ptr = work->packet_ptr;
130 remaining_bytes = work->len;130 remaining_bytes = work->word1.len;
131 131
132 while (remaining_bytes) {132 while (remaining_bytes) {
133 start_of_buffer =133 start_of_buffer =
@@ -382,6 +382,10 @@ int cvmx_helper_get_ipd_port(int interface, int port) · 248 unmodified lines
382 return port + 32;382 return port + 32;
383 case 3:383 case 3:
384 return port + 36;384 return port + 36;
385 case 4:
386 return port + 40;
387 case 5:
388 return port + 44;
385 }389 }
386 return -1;390 return -1;
387}391}
@@ -404,6 +408,10 @@ int cvmx_helper_get_interface_num(int ipd_port) · 16 unmodified lines
404 return 2;408 return 2;
405 else if (ipd_port < 40)409 else if (ipd_port < 40)
406 return 3;410 return 3;
411 else if (ipd_port < 44)
412 return 4;
413 else if (ipd_port < 48)
414 return 5;
407 else415 else
408 cvmx_dprintf("cvmx_helper_get_interface_num: Illegal IPD "416 cvmx_dprintf("cvmx_helper_get_interface_num: Illegal IPD "
409 "port number\n");417 "port number\n");
@@ -428,6 +436,10 @@ int cvmx_helper_get_interface_index_num(int ipd_port) · 18 unmodified lines
428 return ipd_port & 3;436 return ipd_port & 3;
429 else if (ipd_port < 40)437 else if (ipd_port < 40)
430 return ipd_port & 3;438 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;
431 else443 else
432 cvmx_dprintf("cvmx_helper_get_interface_index_num: "444 cvmx_dprintf("cvmx_helper_get_interface_index_num: "
433 "Illegal IPD port number\n");445 "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
124 union cvmx_gmxx_tx_int_en gmx_tx_int_en;124 union cvmx_gmxx_tx_int_en gmx_tx_int_en;
125 union cvmx_pcsxx_int_en_reg pcsx_int_en_reg;125 union cvmx_pcsxx_int_en_reg pcsx_int_en_reg;
126 126
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
127 /* (1) Interface has already been enabled. */134 /* (1) Interface has already been enabled. */
128 135
129 /* (2) Disable GMX. */136 /* (2) Disable GMX. */
@@ -151,7 +158,12 @@ int __cvmx_helper_xaui_enable(int interface) · 21 unmodified lines
151 /* (4)c Aply reset sequence */158 /* (4)c Aply reset sequence */
152 xauiCtl.u64 = cvmx_read_csr(CVMX_PCSXX_CONTROL1_REG(interface));159 xauiCtl.u64 = cvmx_read_csr(CVMX_PCSXX_CONTROL1_REG(interface));
153 xauiCtl.s.lo_pwr = 0;160 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
155 cvmx_write_csr(CVMX_PCSXX_CONTROL1_REG(interface), xauiCtl.u64);167 cvmx_write_csr(CVMX_PCSXX_CONTROL1_REG(interface), xauiCtl.u64);
156 168
157 /* Wait for PCS to come out of reset */169 /* 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
83 */83 */
84int cvmx_helper_get_number_of_interfaces(void)84int cvmx_helper_get_number_of_interfaces(void)
85{85{
86 if (OCTEON_IS_MODEL(OCTEON_CN68XX))
87 return 9;
86 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))88 if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
87 return 4;89 return 4;
88 else90 else
@@ -656,6 +658,21 @@ static int __cvmx_helper_global_setup_pko(void) · 567 unmodified lines
656 fau_to.s.tout_val = 0xfff;658 fau_to.s.tout_val = 0xfff;
657 fau_to.s.tout_enb = 0;659 fau_to.s.tout_enb = 0;
658 cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_to.u64);660 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
659 return 0;676 return 0;
660}677}
661 678
arch/mips/cavium-octeon/executive/cvmx-pko.c+144−5
@@ -39,6 +39,143 @@ · 38 unmodified lines
39 * Internal state of packet output39 * Internal state of packet output
40 */40 */
41 41
42static 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
68static 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
111static 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
119static 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
158static 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
42/**179/**
43 * Call before any other calls to initialize the packet180 * Call before any other calls to initialize the packet
44 * output system. This does chip global config, and should only be181 * output system. This does chip global config, and should only be
@@ -47,8 +184,6 @@ · 2 unmodified lines
47 184
48void cvmx_pko_initialize_global(void)185void cvmx_pko_initialize_global(void)
49{186{
50 int i;
51 uint64_t priority = 8;
52 union cvmx_pko_reg_cmd_buf config;187 union cvmx_pko_reg_cmd_buf config;
53 188
54 /*189 /*
@@ -62,9 +197,10 @@ void cvmx_pko_initialize_global(void) · 7 unmodified lines
62 197
63 cvmx_write_csr(CVMX_PKO_REG_CMD_BUF, config.u64);198 cvmx_write_csr(CVMX_PKO_REG_CMD_BUF, config.u64);
64 199
65 for (i = 0; i < CVMX_PKO_MAX_OUTPUT_QUEUES; i++)200 /*
66 cvmx_pko_config_port(CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID, i, 1,201 * Chip-specific setup.
67 &priority);202 */
203 __cvmx_pko_chip_init();
68 204
69 /*205 /*
70 * If we aren't using all of the queues optimize PKO's206 * 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
212 int static_priority_base = -1;348 int static_priority_base = -1;
213 int static_priority_end = -1;349 int static_priority_end = -1;
214 350
351 if (OCTEON_IS_MODEL(OCTEON_CN68XX))
352 return CVMX_PKO_SUCCESS;
353
215 if ((port >= CVMX_PKO_NUM_OUTPUT_PORTS)354 if ((port >= CVMX_PKO_NUM_OUTPUT_PORTS)
216 && (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID)) {355 && (port != CVMX_PKO_MEM_QUEUE_PTRS_ILLEGAL_PID)) {
217 cvmx_dprintf("ERROR: cvmx_pko_config_port: Invalid port %llu\n",356 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
225 225
226#ifdef CONFIG_SMP226#ifdef CONFIG_SMP
227 int cpu;227 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);
229 struct octeon_ciu_chip_data *cd = irq_data_get_irq_chip_data(data);230 struct octeon_ciu_chip_data *cd = irq_data_get_irq_chip_data(data);
230 231
231 if (weight > 1) {232 if (weight > 1) {
232 cpu = cd->current_cpu;233 cpu = cd->current_cpu;
233 for (;;) {234 for (;;) {
234 cpu = cpumask_next(cpu, data->affinity);235 cpu = cpumask_next(cpu, mask);
235 if (cpu >= nr_cpu_ids) {236 if (cpu >= nr_cpu_ids) {
236 cpu = -1;237 cpu = -1;
237 continue;238 continue;
@@ -240,7 +241,7 @@ static int next_cpu_for_irq(struct irq_data *data) · 2 unmodified lines
240 }241 }
241 }242 }
242 } else if (weight == 1) {243 } else if (weight == 1) {
243 cpu = cpumask_first(data->affinity);244 cpu = cpumask_first(mask);
244 } else {245 } else {
245 cpu = smp_processor_id();246 cpu = smp_processor_id();
246 }247 }
@@ -662,6 +663,11 @@ static int octeon_irq_ciu_gpio_set_type(struct irq_data *data, unsigned int t) · 415 unmodified lines
662 irqd_set_trigger_type(data, t);663 irqd_set_trigger_type(data, t);
663 octeon_irq_gpio_setup(data);664 octeon_irq_gpio_setup(data);
664 665
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
665 return IRQ_SET_MASK_OK;671 return IRQ_SET_MASK_OK;
666}672}
667 673
@@ -696,32 +702,23 @@ static void octeon_irq_ciu_gpio_ack(struct irq_data *data) · 28 unmodified lines
696 cvmx_write_csr(CVMX_GPIO_INT_CLR, mask);702 cvmx_write_csr(CVMX_GPIO_INT_CLR, mask);
697}703}
698 704
699static 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
709#ifdef CONFIG_SMP705#ifdef CONFIG_SMP
710 706
711static void octeon_irq_cpu_offline_ciu(struct irq_data *data)707static void octeon_irq_cpu_offline_ciu(struct irq_data *data)
712{708{
713 int cpu = smp_processor_id();709 int cpu = smp_processor_id();
714 cpumask_t new_affinity;710 cpumask_t new_affinity;
711 struct cpumask *mask = irq_data_get_affinity_mask(data);
715 712
716 if (!cpumask_test_cpu(cpu, data->affinity))713 if (!cpumask_test_cpu(cpu, mask))
717 return;714 return;
718 715
719 if (cpumask_weight(data->affinity) > 1) {716 if (cpumask_weight(mask) > 1) {
720 /*717 /*
721 * It has multi CPU affinity, just remove this CPU718 * It has multi CPU affinity, just remove this CPU
722 * from the affinity set.719 * from the affinity set.
723 */720 */
724 cpumask_copy(&new_affinity, data->affinity);721 cpumask_copy(&new_affinity, mask);
725 cpumask_clear_cpu(cpu, &new_affinity);722 cpumask_clear_cpu(cpu, &new_affinity);
726 } else {723 } else {
727 /* Otherwise, put it on lowest numbered online CPU. */724 /* 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
1227 octeon_irq_ciu_to_irq[line][bit] != 0)1224 octeon_irq_ciu_to_irq[line][bit] != 0)
1228 return -EINVAL;1225 return -EINVAL;
1229 1226
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 */
1230 r = octeon_irq_set_ciu_mapping(virq, line, bit, hw,1232 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);
1232 return r;1234 return r;
1233}1235}
1234 1236
arch/mips/include/asm/Kbuild+0−1
@@ -16,6 +16,5 @@ generic-y += sections.h · 15 unmodified lines
16generic-y += segment.h16generic-y += segment.h
17generic-y += serial.h17generic-y += serial.h
18generic-y += trace_clock.h18generic-y += trace_clock.h
19generic-y += ucontext.h
20generic-y += user.h19generic-y += user.h
21generic-y += xor.h20generic-y += xor.h
arch/mips/include/asm/abi.h+4−0
@@ -20,6 +20,10 @@ struct mips_abi { · 19 unmodified lines
20 struct pt_regs *regs, sigset_t *set);20 struct pt_regs *regs, sigset_t *set);
21 const unsigned long rt_signal_return_offset;21 const unsigned long rt_signal_return_offset;
22 const unsigned long restart;22 const unsigned long restart;
23
24 unsigned off_sc_fpregs;
25 unsigned off_sc_fpc_csr;
26 unsigned off_sc_used_math;
23};27};
24 28
25#endif /* _ASM_ABI_H */29#endif /* _ASM_ABI_H */
arch/mips/include/asm/asmmacro.h+114−0
@@ -232,6 +232,30 @@ · 231 unmodified lines
232 .set pop232 .set pop
233 .endm233 .endm
234 234
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
235 .macro ld_d wd, off, base259 .macro ld_d wd, off, base
236 .set push260 .set push
237 .set mips32r2261 .set mips32r2
@@ -241,6 +265,30 @@ · 3 unmodified lines
241 .set pop265 .set pop
242 .endm266 .endm
243 267
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
244 .macro st_d wd, off, base292 .macro st_d wd, off, base
245 .set push293 .set push
246 .set mips32r2294 .set mips32r2
@@ -290,7 +338,13 @@ · 43 unmodified lines
290#ifdef CONFIG_CPU_MICROMIPS338#ifdef CONFIG_CPU_MICROMIPS
291#define CFC_MSA_INSN 0x587e0056339#define CFC_MSA_INSN 0x587e0056
292#define CTC_MSA_INSN 0x583e0816340#define CTC_MSA_INSN 0x583e0816
341#define LDB_MSA_INSN 0x58000807
342#define LDH_MSA_INSN 0x58000817
343#define LDW_MSA_INSN 0x58000827
293#define LDD_MSA_INSN 0x58000837344#define LDD_MSA_INSN 0x58000837
345#define STB_MSA_INSN 0x5800080f
346#define STH_MSA_INSN 0x5800081f
347#define STW_MSA_INSN 0x5800082f
294#define STD_MSA_INSN 0x5800083f348#define STD_MSA_INSN 0x5800083f
295#define COPY_UW_MSA_INSN 0x58f00056349#define COPY_UW_MSA_INSN 0x58f00056
296#define COPY_UD_MSA_INSN 0x58f80056350#define COPY_UD_MSA_INSN 0x58f80056
@@ -299,7 +353,13 @@ · 2 unmodified lines
299#else353#else
300#define CFC_MSA_INSN 0x787e0059354#define CFC_MSA_INSN 0x787e0059
301#define CTC_MSA_INSN 0x783e0819355#define CTC_MSA_INSN 0x783e0819
356#define LDB_MSA_INSN 0x78000820
357#define LDH_MSA_INSN 0x78000821
358#define LDW_MSA_INSN 0x78000822
302#define LDD_MSA_INSN 0x78000823359#define LDD_MSA_INSN 0x78000823
360#define STB_MSA_INSN 0x78000824
361#define STH_MSA_INSN 0x78000825
362#define STW_MSA_INSN 0x78000826
303#define STD_MSA_INSN 0x78000827363#define STD_MSA_INSN 0x78000827
304#define COPY_UW_MSA_INSN 0x78f00059364#define COPY_UW_MSA_INSN 0x78f00059
305#define COPY_UD_MSA_INSN 0x78f80059365#define COPY_UD_MSA_INSN 0x78f80059
@@ -329,6 +389,33 @@ · 23 unmodified lines
329 .set pop389 .set pop
330 .endm390 .endm
331 391
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
332 .macro ld_d wd, off, base419 .macro ld_d wd, off, base
333 .set push420 .set push
334 .set noat421 .set noat
@@ -338,6 +425,33 @@ · 3 unmodified lines
338 .set pop425 .set pop
339 .endm426 .endm
340 427
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
341 .macro st_d wd, off, base455 .macro st_d wd, off, base
342 .set push456 .set push
343 .set noat457 .set noat
arch/mips/include/asm/cdmm.h+2−2
@@ -53,7 +53,7 @@ struct mips_cdmm_driver { · 52 unmodified lines
53 * mips_cdmm_phys_base() - Choose a physical base address for CDMM region.53 * mips_cdmm_phys_base() - Choose a physical base address for CDMM region.
54 *54 *
55 * Picking a suitable physical address at which to map the CDMM region is55 * 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 to56 * platform specific, so this function can be defined by platform code to
57 * pick a suitable value if none is configured by the bootloader.57 * pick a suitable value if none is configured by the bootloader.
58 *58 *
59 * This address must be 32kB aligned, and the region occupies a maximum of 32kB59 * 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
61 *61 *
62 * Returns: Physical base address for CDMM region, or 0 on failure.62 * Returns: Physical base address for CDMM region, or 0 on failure.
63 */63 */
64phys_addr_t __weak mips_cdmm_phys_base(void);64phys_addr_t mips_cdmm_phys_base(void);
65 65
66extern struct bus_type mips_cdmm_bustype;66extern struct bus_type mips_cdmm_bustype;
67void __iomem *mips_cdmm_early_probe(unsigned int dev_type);67void __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
21 21
22void mips_event_handler(struct clock_event_device *dev);22void mips_event_handler(struct clock_event_device *dev);
23int c0_compare_int_usable(void);23int c0_compare_int_usable(void);
24void mips_set_clock_mode(enum clock_event_mode, struct clock_event_device *);
25irqreturn_t c0_compare_interrupt(int, void *);24irqreturn_t c0_compare_interrupt(int, void *);
26 25
27extern struct irqaction c0_compare_irqaction;26extern struct irqaction c0_compare_irqaction;
arch/mips/include/asm/cpu-features.h+4−0
@@ -411,4 +411,8 @@ · 410 unmodified lines
411# define cpu_has_cdmm (cpu_data[0].options & MIPS_CPU_CDMM)411# define cpu_has_cdmm (cpu_data[0].options & MIPS_CPU_CDMM)
412#endif412#endif
413 413
414#ifndef cpu_has_small_pages
415# define cpu_has_small_pages (cpu_data[0].options & MIPS_CPU_SP)
416#endif
417
414#endif /* __ASM_CPU_FEATURES_H */418#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
77 */77 */
78#endif78#endif
79 79
80#ifdef CONFIG_SYS_HAS_CPU_MIPS64_R6
81 case CPU_I6400:
82#endif
83
80#ifdef CONFIG_SYS_HAS_CPU_R300084#ifdef CONFIG_SYS_HAS_CPU_R3000
81 case CPU_R2000:85 case CPU_R2000:
82 case CPU_R3000:86 case CPU_R3000:
arch/mips/include/asm/cpu.h+3−0
@@ -120,6 +120,7 @@ · 119 unmodified lines
120#define PRID_IMP_PROAPTIV_MP 0xa300120#define PRID_IMP_PROAPTIV_MP 0xa300
121#define PRID_IMP_M5150 0xa700121#define PRID_IMP_M5150 0xa700
122#define PRID_IMP_P5600 0xa800122#define PRID_IMP_P5600 0xa800
123#define PRID_IMP_I6400 0xa900
123 124
124/*125/*
125 * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE126 * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE
@@ -307,6 +308,7 @@ enum cpu_type_enum { · 181 unmodified lines
307 CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350,308 CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350,
308 CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_LOONGSON1, CPU_M14KC,309 CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_LOONGSON1, CPU_M14KC,
309 CPU_M14KEC, CPU_INTERAPTIV, CPU_P5600, CPU_PROAPTIV, CPU_1074K, CPU_M5150,310 CPU_M14KEC, CPU_INTERAPTIV, CPU_P5600, CPU_PROAPTIV, CPU_1074K, CPU_M5150,
311 CPU_I6400,
310 312
311 /*313 /*
312 * MIPS64 class processors314 * MIPS64 class processors
@@ -382,6 +384,7 @@ enum cpu_type_enum { · 69 unmodified lines
382#define MIPS_CPU_XPA 0x2000000000ull /* CPU supports Extended Physical Addressing */384#define MIPS_CPU_XPA 0x2000000000ull /* CPU supports Extended Physical Addressing */
383#define MIPS_CPU_CDMM 0x4000000000ull /* CPU has Common Device Memory Map */385#define MIPS_CPU_CDMM 0x4000000000ull /* CPU has Common Device Memory Map */
384#define MIPS_CPU_BP_GHIST 0x8000000000ull /* R12K+ Branch Prediction Global History */386#define MIPS_CPU_BP_GHIST 0x8000000000ull /* R12K+ Branch Prediction Global History */
387#define MIPS_CPU_SP 0x10000000000ull /* Small (1KB) page support */
385 388
386/*389/*
387 * CPU ASE encodings390 * 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
382 instruction set this cpu supports. This could be done in userspace,382 instruction set this cpu supports. This could be done in userspace,
383 but it's not easy, and we've already done it here. */383 but it's not easy, and we've already done it here. */
384 384
385#define ELF_HWCAP (0)385#define ELF_HWCAP (elf_hwcap)
386extern unsigned int elf_hwcap;
387#include <asm/hwcap.h>
386 388
387/*389/*
388 * This yields a string that ld.so will use to load implementation390 * 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
164 return ret;164 return ret;
165}165}
166 166
167static inline void lose_fpu(int save)167static inline void lose_fpu_inatomic(int save, struct task_struct *tsk)
168{168{
169 preempt_disable();
170 if (is_msa_enabled()) {169 if (is_msa_enabled()) {
171 if (save) {170 if (save) {
172 save_msa(current);171 save_msa(tsk);
173 current->thread.fpu.fcr31 =172 tsk->thread.fpu.fcr31 =
174 read_32bit_cp1_register(CP1_STATUS);173 read_32bit_cp1_register(CP1_STATUS);
175 }174 }
176 disable_msa();175 disable_msa();
177 clear_thread_flag(TIF_USEDMSA);176 clear_tsk_thread_flag(tsk, TIF_USEDMSA);
178 __disable_fpu();177 __disable_fpu();
179 } else if (is_fpu_owner()) {178 } else if (is_fpu_owner()) {
180 if (save)179 if (save)
181 _save_fp(current);180 _save_fp(tsk);
182 __disable_fpu();181 __disable_fpu();
183 }182 }
184 KSTK_STATUS(current) &= ~ST0_CU1;183 KSTK_STATUS(tsk) &= ~ST0_CU1;
185 clear_thread_flag(TIF_USEDFPU);184 clear_tsk_thread_flag(tsk, TIF_USEDFPU);
185}
186
187static inline void lose_fpu(int save)
188{
189 preempt_disable();
190 lose_fpu_inatomic(save, current);
186 preempt_enable();191 preempt_enable();
187}192}
188 193
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
49extern int cp0_perfcount_irq;49extern int cp0_perfcount_irq;
50extern int cp0_fdc_irq;50extern int cp0_fdc_irq;
51 51
52extern int __weak get_c0_fdc_int(void);52extern int get_c0_fdc_int(void);
53 53
54void arch_trigger_all_cpu_backtrace(bool);54void arch_trigger_all_cpu_backtrace(bool);
55#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace55#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
11 DIE_PAGE_FAULT,11 DIE_PAGE_FAULT,
12 DIE_BREAK,12 DIE_BREAK,
13 DIE_SSTEPBP,13 DIE_SSTEPBP,
14 DIE_MSAFP14 DIE_MSAFP,
15 DIE_UPROBE,
16 DIE_UPROBE_XOL,
15};17};
16 18
17#endif /* _ASM_MIPS_KDEBUG_H */19#endif /* _ASM_MIPS_KDEBUG_H */
arch/mips/include/asm/linkage.h+0−1
@@ -5,7 +5,6 @@ · 4 unmodified lines
5#include <asm/asm.h>5#include <asm/asm.h>
6#endif6#endif
7 7
8#define __weak __attribute__((weak))
9#define cond_syscall(x) asm(".weak\t" #x "\n" #x "\t=\tsys_ni_syscall")8#define cond_syscall(x) asm(".weak\t" #x "\n" #x "\t=\tsys_ni_syscall")
10#define SYSCALL_ALIAS(alias, name) \9#define SYSCALL_ALIAS(alias, name) \
11 asm ( #alias " = " #name "\n\t.globl " #alias)10 asm ( #alias " = " #name "\n\t.globl " #alias)
arch/mips/include/asm/maar.h+1−1
@@ -26,7 +26,7 @@ · 25 unmodified lines
26 *26 *
27 * Return: The number of MAAR pairs configured.27 * Return: The number of MAAR pairs configured.
28 */28 */
29unsigned __weak platform_maar_init(unsigned num_pairs);29unsigned platform_maar_init(unsigned num_pairs);
30 30
31/**31/**
32 * write_maar_pair() - write to a pair of MAARs32 * 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
203int __init ar7_gpio_init(void);203int __init ar7_gpio_init(void);
204void __init ar7_init_clocks(void);204void __init ar7_init_clocks(void);
205 205
206/* Board specific GPIO functions */
207int ar7_gpio_enable(unsigned gpio);
208int ar7_gpio_disable(unsigned gpio);
209
206#endif /* __AR7_H__ */210#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 */
36int ar7_gpio_enable(unsigned gpio);
37int 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
11static 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
19int gpio_to_irq(unsigned gpio);
20int irq_to_gpio(unsigned irq);
21int gpio_get_value(unsigned gpio);
22void 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
266 return -ENXIO;266 return -ENXIO;
267}267}
268 268
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 */
273static 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
269/*280/*
270 * GPIO2 block macros for common linux GPIO functions. The 'gpio'281 * GPIO2 block macros for common linux GPIO functions. The 'gpio'
271 * parameter must be in range of ALCHEMY_GPIO2_BASE..ALCHEMY_GPIO2_MAX.282 * 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
518 return -ENXIO;529 return -ENXIO;
519}530}
520 531
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
553static inline int gpio_direction_input(int gpio)
554{
555 return alchemy_gpio_direction_input(gpio);
556}
557
558static inline int gpio_direction_output(int gpio, int v)
559{
560 return alchemy_gpio_direction_output(gpio, v);
561}
562
563static inline int gpio_get_value(int gpio)
564{
565 return alchemy_gpio_get_value(gpio);
566}
567
568static inline void gpio_set_value(int gpio, int v)
569{
570 alchemy_gpio_set_value(gpio, v);
571}
572
573static inline int gpio_get_value_cansleep(unsigned gpio)
574{
575 return gpio_get_value(gpio);
576}
577
578static inline void gpio_set_value_cansleep(unsigned gpio, int value)
579{
580 gpio_set_value(gpio, value);
581}
582
583static inline int gpio_is_valid(int gpio)
584{
585 return alchemy_gpio_is_valid(gpio);
586}
587
588static inline int gpio_cansleep(int gpio)
589{
590 return alchemy_gpio_cansleep(gpio);
591}
592
593static inline int gpio_to_irq(int gpio)
594{
595 return alchemy_gpio_to_irq(gpio);
596}
597
598static inline int irq_to_gpio(int irq)
599{
600 return alchemy_irq_to_gpio(irq);
601}
602
603static inline int gpio_request(unsigned gpio, const char *label)
604{
605 return 0;
606}
607
608static inline int gpio_request_one(unsigned gpio,
609 unsigned long flags, const char *label)
610{
611 return 0;
612}
613
614static inline int gpio_request_array(struct gpio *array, size_t num)
615{
616 return 0;
617}
618
619static inline void gpio_free(unsigned gpio)
620{
621}
622
623static inline void gpio_free_array(struct gpio *array, size_t num)
624{
625}
626
627static inline int gpio_set_debounce(unsigned gpio, unsigned debounce)
628{
629 return -ENOSYS;
630}
631
632static inline int gpio_export(unsigned gpio, bool direction_may_change)
633{
634 return -ENOSYS;
635}
636
637static inline int gpio_export_link(struct device *dev, const char *name,
638 unsigned gpio)
639{
640 return -ENOSYS;
641}
642
643static inline int gpio_sysfs_set_active_low(unsigned gpio, int value)
644{
645 return -ENOSYS;
646}
647
648static 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
658#endif /* _ALCHEMY_GPIO_AU1000_H_ */532#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 */
21static 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 */
57static 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
12static 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
9int gpio_request(unsigned gpio, const char *label);
10void gpio_free(unsigned gpio);
11int gpio_direction_input(unsigned gpio);
12int gpio_direction_output(unsigned gpio, int value);
13int gpio_get_value(unsigned gpio);
14void 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
9int gpio_request(unsigned gpio, const char *label);
10void gpio_free(unsigned gpio);
11int gpio_direction_input(unsigned gpio);
12int gpio_direction_output(unsigned gpio, int value);
13int gpio_get_value(unsigned gpio);
14void gpio_set_value(unsigned gpio, int value);
15#endif
16int gpio_to_irq(unsigned gpio);
17int 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
73void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask);73void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask);
74uint32_t jz_gpio_port_get_value(int port, uint32_t mask);74uint32_t jz_gpio_port_get_value(int port, uint32_t mask);
75 75
76#include <asm/mach-generic/gpio.h>
77
78#define JZ_GPIO_PORTA(x) ((x) + 32 * 0)76#define JZ_GPIO_PORTA(x) ((x) + 32 * 0)
79#define JZ_GPIO_PORTB(x) ((x) + 32 * 1)77#define JZ_GPIO_PORTB(x) ((x) + 32 * 1)
80#define JZ_GPIO_PORTC(x) ((x) + 32 * 2)78#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 */
26static inline int gpio_to_irq(int gpio)
27{
28 return -EINVAL;
29}
30
31static 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
13#ifndef _RC32434_GPIO_H_13#ifndef _RC32434_GPIO_H_
14#define _RC32434_GPIO_H_14#define _RC32434_GPIO_H_
15 15
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
28struct rb532_gpio_reg {16struct rb532_gpio_reg {
29 u32 gpiofunc; /* GPIO Function Register17 u32 gpiofunc; /* GPIO Function Register
30 * gpiofunc[x]==0 bit = gpio18 * 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
33 */33 */
34extern phys_addr_t __mips_cm_phys_base(void);34extern phys_addr_t __mips_cm_phys_base(void);
35 35
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 */
48extern int mips_cm_is64;
49
50/**
51 * mips_cm_error_report - Report CM cache errors
52 */
53#ifdef CONFIG_MIPS_CM
54extern void mips_cm_error_report(void);
55#else
56static inline void mips_cm_error_report(void) {}
57#endif
58
36/**59/**
37 * mips_cm_probe - probe for a Coherence Manager60 * mips_cm_probe - probe for a Coherence Manager
38 *61 *
@@ -90,20 +113,46 @@ static inline bool mips_cm_has_l2sync(void) · 51 unmodified lines
90 113
91/* Macros to ease the creation of register access functions */114/* Macros to ease the creation of register access functions */
92#define BUILD_CM_R_(name, off) \115#define BUILD_CM_R_(name, off) \
93static inline u32 __iomem *addr_gcr_##name(void) \116static inline unsigned long __iomem *addr_gcr_##name(void) \
94{ \117{ \
95 return (u32 __iomem *)(mips_cm_base + (off)); \118 return (unsigned long __iomem *)(mips_cm_base + (off)); \
96} \119} \
97 \120 \
98static inline u32 read_gcr_##name(void) \121static inline u32 read32_gcr_##name(void) \
99{ \122{ \
100 return __raw_readl(addr_gcr_##name()); \123 return __raw_readl(addr_gcr_##name()); \
124} \
125 \
126static inline u64 read64_gcr_##name(void) \
127{ \
128 return __raw_readq(addr_gcr_##name()); \
129} \
130 \
131static 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(); \
101}137}
102 138
103#define BUILD_CM__W(name, off) \139#define BUILD_CM__W(name, off) \
104static inline void write_gcr_##name(u32 value) \140static inline void write32_gcr_##name(u32 value) \
105{ \141{ \
106 __raw_writel(value, addr_gcr_##name()); \142 __raw_writel(value, addr_gcr_##name()); \
143} \
144 \
145static inline void write64_gcr_##name(u64 value) \
146{ \
147 __raw_writeq(value, addr_gcr_##name()); \
148} \
149 \
150static 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); \
107}156}
108 157
109#define BUILD_CM_RW(name, off) \158#define BUILD_CM_RW(name, off) \
@@ -144,6 +193,7 @@ BUILD_CM_RW(reg3_base, MIPS_CM_GCB_OFS + 0xc0) · 34 unmodified lines
144BUILD_CM_RW(reg3_mask, MIPS_CM_GCB_OFS + 0xc8)193BUILD_CM_RW(reg3_mask, MIPS_CM_GCB_OFS + 0xc8)
145BUILD_CM_R_(gic_status, MIPS_CM_GCB_OFS + 0xd0)194BUILD_CM_R_(gic_status, MIPS_CM_GCB_OFS + 0xd0)
146BUILD_CM_R_(cpc_status, MIPS_CM_GCB_OFS + 0xf0)195BUILD_CM_R_(cpc_status, MIPS_CM_GCB_OFS + 0xf0)
196BUILD_CM_RW(l2_config, MIPS_CM_GCB_OFS + 0x130)
147 197
148/* Core Local & Core Other register accessor functions */198/* Core Local & Core Other register accessor functions */
149BUILD_CM_Cx_RW(reset_release, 0x00)199BUILD_CM_Cx_RW(reset_release, 0x00)
@@ -189,6 +239,13 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80) · 39 unmodified lines
189#define CM_GCR_REV_MINOR_SHF 0239#define CM_GCR_REV_MINOR_SHF 0
190#define CM_GCR_REV_MINOR_MSK (_ULCAST_(0xff) << 0)240#define CM_GCR_REV_MINOR_MSK (_ULCAST_(0xff) << 0)
191 241
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
192/* GCR_ERROR_CAUSE register fields */249/* GCR_ERROR_CAUSE register fields */
193#define CM_GCR_ERROR_CAUSE_ERRTYPE_SHF 27250#define CM_GCR_ERROR_CAUSE_ERRTYPE_SHF 27
194#define CM_GCR_ERROR_CAUSE_ERRTYPE_MSK (_ULCAST_(0x1f) << 27)251#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
249#define CM_GCR_CPC_STATUS_EX_SHF 0306#define CM_GCR_CPC_STATUS_EX_SHF 0
250#define CM_GCR_CPC_STATUS_EX_MSK (_ULCAST_(0x1) << 0)307#define CM_GCR_CPC_STATUS_EX_MSK (_ULCAST_(0x1) << 0)
251 308
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
252/* GCR_Cx_COHERENCE register fields */319/* GCR_Cx_COHERENCE register fields */
253#define CM_GCR_Cx_COHERENCE_COHDOMAINEN_SHF 0320#define CM_GCR_Cx_COHERENCE_COHDOMAINEN_SHF 0
254#define CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK (_ULCAST_(0xff) << 0)321#define CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK (_ULCAST_(0xff) << 0)
@@ -324,4 +391,18 @@ static inline int mips_cm_l2sync(void) · 69 unmodified lines
324 return 0;391 return 0;
325}392}
326 393
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 */
400static inline int mips_cm_revision(void)
401{
402 if (!mips_cm_present())
403 return 0;
404
405 return read_gcr_rev();
406}
407
327#endif /* __MIPS_ASM_MIPS_CM_H__ */408#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
27 */27 */
28extern phys_addr_t mips_cpc_default_phys_base(void);28extern phys_addr_t mips_cpc_default_phys_base(void);
29 29
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 */
38extern phys_addr_t __weak mips_cpc_phys_base(void);
39
40/**30/**
41 * mips_cpc_probe - probe for a Cluster Power Controller31 * mips_cpc_probe - probe for a Cluster Power Controller
42 *32 *
arch/mips/include/asm/mipsregs.h+32−28
@@ -112,6 +112,30 @@ · 111 unmodified lines
112#define CP0_TX39_CACHE $7112#define CP0_TX39_CACHE $7
113 113
114 114
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
115/*139/*
116 * Values for PageMask register140 * Values for PageMask register
117 */141 */
@@ -203,6 +227,9 @@ · 85 unmodified lines
203#define PG_ESP (_ULCAST_(1) << 28)227#define PG_ESP (_ULCAST_(1) << 28)
204#define PG_IEC (_ULCAST_(1) << 27)228#define PG_IEC (_ULCAST_(1) << 27)
205 229
230/* MIPS32/64 EntryHI bit definitions */
231#define MIPS_ENTRYHI_EHINV (_ULCAST_(1) << 10)
232
206/*233/*
207 * R4x00 interrupt enable / cause bits234 * R4x00 interrupt enable / cause bits
208 */235 */
@@ -579,6 +606,8 @@ · 370 unmodified lines
579 606
580#define MIPS_CONF7_IAR (_ULCAST_(1) << 10)607#define MIPS_CONF7_IAR (_ULCAST_(1) << 10)
581#define MIPS_CONF7_AR (_ULCAST_(1) << 16)608#define MIPS_CONF7_AR (_ULCAST_(1) << 16)
609/* FTLB probability bits for R6 */
610#define MIPS_CONF7_FTLBP_SHIFT (18)
582 611
583/* MAAR bit definitions */612/* MAAR bit definitions */
584#define MIPS_MAAR_ADDR ((BIT_ULL(BITS_PER_LONG - 12) - 1) << 12)613#define MIPS_MAAR_ADDR ((BIT_ULL(BITS_PER_LONG - 12) - 1) << 12)
@@ -586,31 +615,6 @@ · 1 unmodified line
586#define MIPS_MAAR_S (_ULCAST_(1) << 1)615#define MIPS_MAAR_S (_ULCAST_(1) << 1)
587#define MIPS_MAAR_V (_ULCAST_(1) << 0)616#define MIPS_MAAR_V (_ULCAST_(1) << 0)
588 617
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
614/* CMGCRBase bit definitions */618/* CMGCRBase bit definitions */
615#define MIPS_CMGCRB_BASE 11619#define MIPS_CMGCRB_BASE 11
616#define MIPS_CMGCRF_BASE (~_ULCAST_((1 << MIPS_CMGCRB_BASE) - 1))620#define MIPS_CMGCRF_BASE (~_ULCAST_((1 << MIPS_CMGCRB_BASE) - 1))
@@ -932,7 +936,7 @@ do { \ · 315 unmodified lines
932 */936 */
933 937
934#define __read_32bit_c0_register(source, sel) \938#define __read_32bit_c0_register(source, sel) \
935({ int __res; \939({ unsigned int __res; \
936 if (sel == 0) \940 if (sel == 0) \
937 __asm__ __volatile__( \941 __asm__ __volatile__( \
938 "mfc0\t%0, " #source "\n\t" \942 "mfc0\t%0, " #source "\n\t" \
@@ -1014,7 +1018,7 @@ do { \ · 75 unmodified lines
1014 * On RM7000/RM9000 these are uses to access cop0 set 1 registers1018 * On RM7000/RM9000 these are uses to access cop0 set 1 registers
1015 */1019 */
1016#define __read_32bit_c0_ctrl_register(source) \1020#define __read_32bit_c0_ctrl_register(source) \
1017({ int __res; \1021({ unsigned int __res; \
1018 __asm__ __volatile__( \1022 __asm__ __volatile__( \
1019 "cfc0\t%0, " #source "\n\t" \1023 "cfc0\t%0, " #source "\n\t" \
1020 : "=r" (__res)); \1024 : "=r" (__res)); \
@@ -1471,7 +1475,7 @@ do { \ · 450 unmodified lines
1471 */1475 */
1472#define _read_32bit_cp1_register(source, gas_hardfloat) \1476#define _read_32bit_cp1_register(source, gas_hardfloat) \
1473({ \1477({ \
1474 int __res; \1478 unsigned int __res; \
1475 \1479 \
1476 __asm__ __volatile__( \1480 __asm__ __volatile__( \
1477 " .set push \n" \1481 " .set push \n" \
arch/mips/include/asm/msa.h+80−0
@@ -14,10 +14,90 @@ · 13 unmodified lines
14 14
15#ifndef __ASSEMBLY__15#ifndef __ASSEMBLY__
16 16
17#include <asm/inst.h>
18
17extern void _save_msa(struct task_struct *);19extern void _save_msa(struct task_struct *);
18extern void _restore_msa(struct task_struct *);20extern void _restore_msa(struct task_struct *);
19extern void _init_msa_upper(void);21extern void _init_msa_upper(void);
20 22
23extern void read_msa_wr_b(unsigned idx, union fpureg *to);
24extern void read_msa_wr_h(unsigned idx, union fpureg *to);
25extern void read_msa_wr_w(unsigned idx, union fpureg *to);
26extern 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 */
37static 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
62extern void write_msa_wr_b(unsigned idx, union fpureg *from);
63extern void write_msa_wr_h(unsigned idx, union fpureg *from);
64extern void write_msa_wr_w(unsigned idx, union fpureg *from);
65extern 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 */
76static 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
21static inline void enable_msa(void)101static inline void enable_msa(void)
22{102{
23 if (cpu_has_msa) {103 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
284 CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001,284 CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001,
285 CVMX_BOARD_TYPE_UBNT_E100 = 20002,285 CVMX_BOARD_TYPE_UBNT_E100 = 20002,
286 CVMX_BOARD_TYPE_CUST_DSR1000N = 20006,286 CVMX_BOARD_TYPE_CUST_DSR1000N = 20006,
287 CVMX_BOARD_TYPE_KONTRON_S1901 = 21901,
287 CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000,288 CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000,
288 289
289 /* The remaining range is reserved for future use. */290 /* 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
384 ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MIN)385 ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MIN)
385 ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E100)386 ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E100)
386 ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DSR1000N)387 ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DSR1000N)
388 ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_KONTRON_S1901)
387 ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX)389 ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX)
388 }390 }
389 return "Unsupported Board";391 return "Unsupported Board";
arch/mips/include/asm/octeon/cvmx-pip.h+1−1
@@ -37,7 +37,7 @@ · 36 unmodified lines
37#include <asm/octeon/cvmx-fpa.h>37#include <asm/octeon/cvmx-fpa.h>
38#include <asm/octeon/cvmx-pip-defs.h>38#include <asm/octeon/cvmx-pip-defs.h>
39 39
40#define CVMX_PIP_NUM_INPUT_PORTS 4040#define CVMX_PIP_NUM_INPUT_PORTS 48
41#define CVMX_PIP_NUM_WATCHERS 441#define CVMX_PIP_NUM_WATCHERS 4
42 42
43/*43/*
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
542 */542 */
543static inline int cvmx_pko_get_base_queue(int port)543static inline int cvmx_pko_get_base_queue(int port)
544{544{
545 if (OCTEON_IS_MODEL(OCTEON_CN68XX))
546 return port;
547
545 return cvmx_pko_get_base_queue_per_core(port, 0);548 return cvmx_pko_get_base_queue_per_core(port, 0);
546}549}
547 550
arch/mips/include/asm/octeon/cvmx-pow-defs.h+29−0
@@ -52,6 +52,12 @@ · 51 unmodified lines
52#define CVMX_POW_WQ_INT_THRX(offset) (CVMX_ADD_IO_SEG(0x0001670000000080ull) + ((offset) & 15) * 8)52#define CVMX_POW_WQ_INT_THRX(offset) (CVMX_ADD_IO_SEG(0x0001670000000080ull) + ((offset) & 15) * 8)
53#define CVMX_POW_WS_PCX(offset) (CVMX_ADD_IO_SEG(0x0001670000000280ull) + ((offset) & 15) * 8)53#define CVMX_POW_WS_PCX(offset) (CVMX_ADD_IO_SEG(0x0001670000000280ull) + ((offset) & 15) * 8)
54 54
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
55union cvmx_pow_bist_stat {61union cvmx_pow_bist_stat {
56 uint64_t u64;62 uint64_t u64;
57 struct cvmx_pow_bist_stat_s {63 struct cvmx_pow_bist_stat_s {
@@ -1286,4 +1292,27 @@ union cvmx_pow_ws_pcx { · 1228 unmodified lines
1286 struct cvmx_pow_ws_pcx_s cnf71xx;1292 struct cvmx_pow_ws_pcx_s cnf71xx;
1287};1293};
1288 1294
1295union 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
1289#endif1318#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
1810 cvmx_addr_t ptr;1810 cvmx_addr_t ptr;
1811 cvmx_pow_tag_req_t tag_req;1811 cvmx_pow_tag_req_t tag_req;
1812 1812
1813 wqp->qos = qos;1813 wqp->word1.tag = tag;
1814 wqp->tag = tag;1814 wqp->word1.tag_type = tag_type;
1815 wqp->tag_type = tag_type;1815
1816 wqp->grp = grp;1816 cvmx_wqe_set_qos(wqp, qos);
1817 cvmx_wqe_set_grp(wqp, grp);
1817 1818
1818 tag_req.u64 = 0;1819 tag_req.u64 = 0;
1819 tag_req.s.op = CVMX_POW_TAG_OP_ADDWQ;1820 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
193 uint64_t bufs:8;193 uint64_t bufs:8;
194#endif194#endif
195 } s;195 } 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;
196 243
197 /* use this to get at the 16 vlan bits */244 /* use this to get at the 16 vlan bits */
198 struct {245 struct {
@@ -355,6 +402,146 @@ typedef union { · 156 unmodified lines
355 402
356} cvmx_pip_wqe_word2;403} cvmx_pip_wqe_word2;
357 404
405union 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
452union cvmx_wqe_word0 {
453 uint64_t u64;
454 union cvmx_pip_wqe_word0 pip;
455};
456
457union 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
358/**545/**
359 * Work queue entry format546 * Work queue entry format
360 *547 *
@@ -366,70 +553,13 @@ typedef struct { · 5 unmodified lines
366 * WORD 0553 * WORD 0
367 * HW WRITE: the following 64 bits are filled by HW when a packet arrives554 * HW WRITE: the following 64 bits are filled by HW when a packet arrives
368 */555 */
369 556 union cvmx_wqe_word0 word0;
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
391 557
392 /*****************************************************************558 /*****************************************************************
393 * WORD 1559 * WORD 1
394 * HW WRITE: the following 64 bits are filled by HW when a packet arrives560 * HW WRITE: the following 64 bits are filled by HW when a packet arrives
395 */561 */
396 562 union cvmx_wqe_word1 word1;
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
433 563
434 /**564 /**
435 * WORD 2 HW WRITE: the following 64-bits are filled in by565 * WORD 2 HW WRITE: the following 64-bits are filled in by
@@ -465,4 +595,64 @@ typedef struct { · 29 unmodified lines
465 595
466} CVMX_CACHE_LINE_ALIGNED cvmx_wqe_t;596} CVMX_CACHE_LINE_ALIGNED cvmx_wqe_t;
467 597
598static 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
610static 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
618static 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
630static 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
638static 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
650static 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
468#endif /* __CVMX_WQE_H__ */658#endif /* __CVMX_WQE_H__ */
arch/mips/include/asm/pgtable-bits.h+10−15
@@ -133,20 +133,13 @@ · 132 unmodified lines
133#define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT)133#define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT)
134#define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT + 1)134#define _PAGE_SPLITTING_SHIFT (_PAGE_HUGE_SHIFT + 1)
135#define _PAGE_SPLITTING (1 << _PAGE_SPLITTING_SHIFT)135#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
145#endif /* CONFIG_64BIT && CONFIG_MIPS_HUGE_TLB_SUPPORT */136#endif /* CONFIG_64BIT && CONFIG_MIPS_HUGE_TLB_SUPPORT */
146 137
147#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)138#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
148/* XI - page cannot be executed */139/* XI - page cannot be executed */
149#ifndef _PAGE_NO_EXEC_SHIFT140#ifdef _PAGE_SPLITTING_SHIFT
141#define _PAGE_NO_EXEC_SHIFT (_PAGE_SPLITTING_SHIFT + 1)
142#else
150#define _PAGE_NO_EXEC_SHIFT (_PAGE_MODIFIED_SHIFT + 1)143#define _PAGE_NO_EXEC_SHIFT (_PAGE_MODIFIED_SHIFT + 1)
151#endif144#endif
152#define _PAGE_NO_EXEC (cpu_has_rixi ? (1 << _PAGE_NO_EXEC_SHIFT) : 0)145#define _PAGE_NO_EXEC (cpu_has_rixi ? (1 << _PAGE_NO_EXEC_SHIFT) : 0)
@@ -156,14 +149,16 @@ · 3 unmodified lines
156#define _PAGE_READ (cpu_has_rixi ? 0 : (1 << _PAGE_READ_SHIFT))149#define _PAGE_READ (cpu_has_rixi ? 0 : (1 << _PAGE_READ_SHIFT))
157#define _PAGE_NO_READ_SHIFT _PAGE_READ_SHIFT150#define _PAGE_NO_READ_SHIFT _PAGE_READ_SHIFT
158#define _PAGE_NO_READ (cpu_has_rixi ? (1 << _PAGE_READ_SHIFT) : 0)151#define _PAGE_NO_READ (cpu_has_rixi ? (1 << _PAGE_READ_SHIFT) : 0)
152#endif /* defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) */
159 153
154#if defined(_PAGE_NO_READ_SHIFT)
160#define _PAGE_GLOBAL_SHIFT (_PAGE_NO_READ_SHIFT + 1)155#define _PAGE_GLOBAL_SHIFT (_PAGE_NO_READ_SHIFT + 1)
161#define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT)156#elif defined(_PAGE_SPLITTING_SHIFT)
162 157#define _PAGE_GLOBAL_SHIFT (_PAGE_SPLITTING_SHIFT + 1)
163#else /* !CONFIG_CPU_MIPSR2 && !CONFIG_CPU_MIPSR6 */158#else
164#define _PAGE_GLOBAL_SHIFT (_PAGE_MODIFIED_SHIFT + 1)159#define _PAGE_GLOBAL_SHIFT (_PAGE_MODIFIED_SHIFT + 1)
160#endif
165#define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT)161#define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT)
166#endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
167 162
168#define _PAGE_VALID_SHIFT (_PAGE_GLOBAL_SHIFT + 1)163#define _PAGE_VALID_SHIFT (_PAGE_GLOBAL_SHIFT + 1)
169#define _PAGE_VALID (1 << _PAGE_VALID_SHIFT)164#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
249#define _CACHE_CACHABLE_NONCOHERENT (3<<_CACHE_SHIFT) /* LOONGSON */244#define _CACHE_CACHABLE_NONCOHERENT (3<<_CACHE_SHIFT) /* LOONGSON */
250#define _CACHE_CACHABLE_COHERENT (3<<_CACHE_SHIFT) /* LOONGSON-3 */245#define _CACHE_CACHABLE_COHERENT (3<<_CACHE_SHIFT) /* LOONGSON-3 */
251 246
252#elif defined(CONFIG_MACH_JZ4740)247#elif defined(CONFIG_MACH_INGENIC)
253 248
254/* Ingenic uses the WA bit to achieve write-combine memory writes */249/* Ingenic uses the WA bit to achieve write-combine memory writes */
255#define _CACHE_UNCACHED_ACCELERATED (1<<_CACHE_SHIFT)250#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
393 return __pgprot(prot);393 return __pgprot(prot);
394}394}
395 395
396#define pgprot_writecombine pgprot_writecombine
397
396static inline pgprot_t pgprot_writecombine(pgprot_t _prot)398static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
397{399{
398 unsigned long prot = pgprot_val(_prot);400 unsigned long prot = pgprot_val(_prot);
arch/mips/include/asm/processor.h+2−0
@@ -275,6 +275,7 @@ struct thread_struct { · 274 unmodified lines
275 unsigned long cp0_badvaddr; /* Last user fault */275 unsigned long cp0_badvaddr; /* Last user fault */
276 unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */276 unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */
277 unsigned long error_code;277 unsigned long error_code;
278 unsigned long trap_nr;
278#ifdef CONFIG_CPU_CAVIUM_OCTEON279#ifdef CONFIG_CPU_CAVIUM_OCTEON
279 struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128)));280 struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128)));
280 struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128)));281 struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128)));
@@ -341,6 +342,7 @@ struct thread_struct { · 60 unmodified lines
341 .cp0_badvaddr = 0, \342 .cp0_badvaddr = 0, \
342 .cp0_baduaddr = 0, \343 .cp0_baduaddr = 0, \
343 .error_code = 0, \344 .error_code = 0, \
345 .trap_nr = 0, \
344 /* \346 /* \
345 * Platform specific cop2 registers(null if no COP2) \347 * Platform specific cop2 registers(null if no COP2) \
346 */ \348 */ \
arch/mips/include/asm/ptrace.h+80−0
@@ -14,11 +14,16 @@ · 13 unmodified lines
14#include <linux/linkage.h>14#include <linux/linkage.h>
15#include <linux/types.h>15#include <linux/types.h>
16#include <asm/isadep.h>16#include <asm/isadep.h>
17#include <asm/page.h>
18#include <asm/thread_info.h>
17#include <uapi/asm/ptrace.h>19#include <uapi/asm/ptrace.h>
18 20
19/*21/*
20 * This struct defines the way the registers are stored on the stack during a22 * This struct defines the way the registers are stored on the stack during a
21 * system call/exception. As usual the registers k0/k1 aren't being saved.23 * 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.
22 */27 */
23struct pt_regs {28struct pt_regs {
24#ifdef CONFIG_32BIT29#ifdef CONFIG_32BIT
@@ -43,8 +48,83 @@ struct pt_regs { · 18 unmodified lines
43 unsigned long long mpl[6]; /* MTM{0-5} */48 unsigned long long mpl[6]; /* MTM{0-5} */
44 unsigned long long mtp[6]; /* MTP{0-5} */49 unsigned long long mtp[6]; /* MTP{0-5} */
45#endif50#endif
51 unsigned long __last[0];
46} __aligned(8);52} __aligned(8);
47 53
54static 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
64static 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 */
71extern 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 */
83static 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 */
100static 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 */
116static 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
48struct task_struct;128struct task_struct;
49 129
50extern int ptrace_getregs(struct task_struct *child,130extern int ptrace_getregs(struct task_struct *child,
arch/mips/include/asm/signal.h+3−0
@@ -23,4 +23,7 @@ · 22 unmodified lines
23 23
24#define __ARCH_HAS_IRIX_SIGACTION24#define __ARCH_HAS_IRIX_SIGACTION
25 25
26extern int protected_save_fp_context(void __user *sc);
27extern int protected_restore_fp_context(void __user *sc);
28
26#endif /* _ASM_SIGNAL_H */29#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
42 return ((counters >> 16) ^ counters) & 0xffff;42 return ((counters >> 16) ^ counters) & 0xffff;
43}43}
44 44
45static inline int arch_spin_value_unlocked(arch_spinlock_t lock)
46{
47 return lock.h.serving_now == lock.h.ticket;
48}
49
45#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)50#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
46#define arch_spin_unlock_wait(x) \51#define arch_spin_unlock_wait(x) \
47 while (arch_spin_is_locked(x)) { cpu_relax(); }52 while (arch_spin_is_locked(x)) { cpu_relax(); }
arch/mips/include/asm/switch_to.h+4−17
@@ -16,29 +16,21 @@ · 15 unmodified lines
16#include <asm/watch.h>16#include <asm/watch.h>
17#include <asm/dsp.h>17#include <asm/dsp.h>
18#include <asm/cop2.h>18#include <asm/cop2.h>
19#include <asm/msa.h>19#include <asm/fpu.h>
20 20
21struct task_struct;21struct task_struct;
22 22
23enum {
24 FP_SAVE_NONE = 0,
25 FP_SAVE_VECTOR = -1,
26 FP_SAVE_SCALAR = 1,
27};
28
29/**23/**
30 * resume - resume execution of a task24 * resume - resume execution of a task
31 * @prev: The task previously executed.25 * @prev: The task previously executed.
32 * @next: The task to begin executing.26 * @next: The task to begin executing.
33 * @next_ti: task_thread_info(next).27 * @next_ti: task_thread_info(next).
34 * @fp_save: Which, if any, FP context to save for prev.
35 *28 *
36 * This function is used whilst scheduling to save the context of prev & load29 * This function is used whilst scheduling to save the context of prev & load
37 * the context of next. Returns prev.30 * the context of next. Returns prev.
38 */31 */
39extern asmlinkage struct task_struct *resume(struct task_struct *prev,32extern asmlinkage struct task_struct *resume(struct task_struct *prev,
40 struct task_struct *next, struct thread_info *next_ti,33 struct task_struct *next, struct thread_info *next_ti);
41 s32 fp_save);
42 34
43extern unsigned int ll_bit;35extern unsigned int ll_bit;
44extern struct task_struct *ll_task;36extern struct task_struct *ll_task;
@@ -91,8 +83,8 @@ do { if (cpu_has_rw_llb) { \ · 46 unmodified lines
91 */83 */
92#define switch_to(prev, next, last) \84#define switch_to(prev, next, last) \
93do { \85do { \
94 s32 __fpsave = FP_SAVE_NONE; \
95 __mips_mt_fpaff_switch_to(prev); \86 __mips_mt_fpaff_switch_to(prev); \
87 lose_fpu_inatomic(1, prev); \
96 if (cpu_has_dsp) { \88 if (cpu_has_dsp) { \
97 __save_dsp(prev); \89 __save_dsp(prev); \
98 __restore_dsp(next); \90 __restore_dsp(next); \
@@ -111,15 +103,10 @@ do { \ · 12 unmodified lines
111 clear_c0_status(ST0_CU2); \103 clear_c0_status(ST0_CU2); \
112 } \104 } \
113 __clear_software_ll_bit(); \105 __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; \
118 if (cpu_has_userlocal) \106 if (cpu_has_userlocal) \
119 write_c0_userlocal(task_thread_info(next)->tp_value); \107 write_c0_userlocal(task_thread_info(next)->tp_value); \
120 __restore_watch(); \108 __restore_watch(); \
121 disable_msa(); \109 (last) = resume(prev, next, task_thread_info(next)); \
122 (last) = resume(prev, next, task_thread_info(next), __fpsave); \
123} while (0)110} while (0)
124 111
125#endif /* _ASM_SWITCH_TO_H */112#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
99#define TIF_SYSCALL_AUDIT 3 /* syscall auditing active */99#define TIF_SYSCALL_AUDIT 3 /* syscall auditing active */
100#define TIF_SECCOMP 4 /* secure computing */100#define TIF_SECCOMP 4 /* secure computing */
101#define TIF_NOTIFY_RESUME 5 /* callback before returning to user */101#define TIF_NOTIFY_RESUME 5 /* callback before returning to user */
102#define TIF_UPROBE 6 /* breakpointed or singlestepping */
102#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */103#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */
103#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */104#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
104#define TIF_MEMDIE 18 /* is terminating due to OOM killer */105#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
122#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)123#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
123#define _TIF_SECCOMP (1<<TIF_SECCOMP)124#define _TIF_SECCOMP (1<<TIF_SECCOMP)
124#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)125#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
126#define _TIF_UPROBE (1<<TIF_UPROBE)
125#define _TIF_USEDFPU (1<<TIF_USEDFPU)127#define _TIF_USEDFPU (1<<TIF_USEDFPU)
126#define _TIF_NOHZ (1<<TIF_NOHZ)128#define _TIF_NOHZ (1<<TIF_NOHZ)
127#define _TIF_FIXADE (1<<TIF_FIXADE)129#define _TIF_FIXADE (1<<TIF_FIXADE)
@@ -146,7 +148,8 @@ static inline struct thread_info *current_thread_info(void) · 18 unmodified lines
146 148
147/* work to do on interrupt/exception return */149/* work to do on interrupt/exception return */
148#define _TIF_WORK_MASK \150#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)
150/* work to do on any return to u-space */153/* work to do on any return to u-space */
151#define _TIF_ALLWORK_MASK (_TIF_NOHZ | _TIF_WORK_MASK | \154#define _TIF_ALLWORK_MASK (_TIF_NOHZ | _TIF_WORK_MASK | \
152 _TIF_WORK_SYSCALL_EXIT | \155 _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
51/*51/*
52 * Initialize the calling CPU's compare interrupt as clockevent device52 * Initialize the calling CPU's compare interrupt as clockevent device
53 */53 */
54extern unsigned int __weak get_c0_compare_int(void);54extern unsigned int get_c0_compare_int(void);
55extern int r4k_clockevent_init(void);55extern int r4k_clockevent_init(void);
56 56
57static inline int mips_clockevent_init(void)57static inline int mips_clockevent_init(void)
arch/mips/include/asm/tlbdebug.h+1−0
@@ -11,6 +11,7 @@ · 10 unmodified lines
11/*11/*
12 * TLB debugging functions:12 * TLB debugging functions:
13 */13 */
14extern void dump_tlb_regs(void);
14extern void dump_tlb_all(void);15extern void dump_tlb_all(void);
15 16
16#endif /* __ASM_TLBDEBUG_H */17#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 */
19typedef 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
35struct 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
42struct arch_uprobe_task {
43 unsigned long saved_trap_nr;
44};
45
46extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup,
47 struct mm_struct *mm, unsigned long addr);
48extern int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs);
49extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs);
50extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk);
51extern int arch_uprobe_exception_notify(struct notifier_block *self,
52 unsigned long val, void *data);
53extern void arch_uprobe_abort_xol(struct arch_uprobe *aup,
54 struct pt_regs *regs);
55extern 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
122void *alloc_progmem(unsigned long len);122void *alloc_progmem(unsigned long len);
123void release_progmem(void *ptr);123void release_progmem(void *ptr);
124 124
125int __weak vpe_run(struct vpe *v);125int vpe_run(struct vpe *v);
126void cleanup_tc(struct tc *tc);126void cleanup_tc(struct tc *tc);
127 127
128int __init vpe_module_init(void);128int __init vpe_module_init(void);
arch/mips/include/uapi/asm/break.h+2−0
@@ -21,6 +21,8 @@ · 20 unmodified lines
21#define BRK_DIVZERO 7 /* Divide by zero check */21#define BRK_DIVZERO 7 /* Divide by zero check */
22#define BRK_RANGE 8 /* Range error check */22#define BRK_RANGE 8 /* Range error check */
23#define BRK_BUG 12 /* Used by BUG() */23#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> */
24#define BRK_MEMU 514 /* Used by FPU emulator */26#define BRK_MEMU 514 /* Used by FPU emulator */
25#define BRK_KPROBE_BP 515 /* Kprobe break */27#define BRK_KPROBE_BP 515 /* Kprobe break */
26#define BRK_KPROBE_SSTEPBP 516 /* Kprobe single step software implementation */28#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
26 cop0_op, cop1_op, cop2_op, cop1x_op,26 cop0_op, cop1_op, cop2_op, cop1x_op,
27 beql_op, bnel_op, blezl_op, bgtzl_op,27 beql_op, bnel_op, blezl_op, bgtzl_op,
28 daddi_op, cbcond1_op = daddi_op, daddiu_op, ldl_op, ldr_op,28 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,
30 lb_op, lh_op, lwl_op, lw_op,30 lb_op, lh_op, lwl_op, lw_op,
31 lbu_op, lhu_op, lwr_op, lwu_op,31 lbu_op, lhu_op, lwr_op, lwu_op,
32 sb_op, sh_op, swl_op, sw_op,32 sb_op, sh_op, swl_op, sw_op,
@@ -167,8 +167,13 @@ enum cop1_sdw_func { · 134 unmodified lines
167 fround_op = 0x0c, ftrunc_op = 0x0d,167 fround_op = 0x0c, ftrunc_op = 0x0d,
168 fceil_op = 0x0e, ffloor_op = 0x0f,168 fceil_op = 0x0e, ffloor_op = 0x0f,
169 fmovc_op = 0x11, fmovz_op = 0x12,169 fmovc_op = 0x11, fmovz_op = 0x12,
170 fmovn_op = 0x13, frecip_op = 0x15,170 fmovn_op = 0x13, fseleqz_op = 0x14,
171 frsqrt_op = 0x16, fcvts_op = 0x20,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,
172 fcvtd_op = 0x21, fcvte_op = 0x22,177 fcvtd_op = 0x21, fcvte_op = 0x22,
173 fcvtw_op = 0x24, fcvtl_op = 0x25,178 fcvtw_op = 0x24, fcvtl_op = 0x25,
174 fcmp_op = 0x30179 fcmp_op = 0x30
@@ -220,6 +225,24 @@ enum bshfl_func { · 45 unmodified lines
220 seh_op = 0x18,225 seh_op = 0x18,
221};226};
222 227
228/*
229 * func field for MSA MI10 format.
230 */
231enum msa_mi10_func {
232 msa_ld_op = 8,
233 msa_st_op = 9,
234};
235
236/*
237 * MSA 2 bit format fields.
238 */
239enum 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
223/*246/*
224 * (microMIPS) Major opcodes.247 * (microMIPS) Major opcodes.
225 */248 */
@@ -611,6 +634,16 @@ struct v_format { /* MDMX vector format */ · 385 unmodified lines
611 ;)))))))634 ;)))))))
612};635};
613 636
637struct 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
614struct spec3_format { /* SPEC3 */647struct spec3_format { /* SPEC3 */
615 __BITFIELD_FIELD(unsigned int opcode:6,648 __BITFIELD_FIELD(unsigned int opcode:6,
616 __BITFIELD_FIELD(unsigned int rs:5,649 __BITFIELD_FIELD(unsigned int rs:5,
@@ -888,6 +921,7 @@ union mips_instruction { · 271 unmodified lines
888 struct p_format p_format;921 struct p_format p_format;
889 struct f_format f_format;922 struct f_format f_format;
890 struct ma_format ma_format;923 struct ma_format ma_format;
924 struct msa_mi10_format msa_mi10_format;
891 struct b_format b_format;925 struct b_format b_format;
892 struct ps_format ps_format;926 struct ps_format ps_format;
893 struct v_format v_format;927 struct v_format v_format;
arch/mips/include/uapi/asm/sigcontext.h+12−0
@@ -12,6 +12,18 @@ · 11 unmodified lines
12#include <linux/types.h>12#include <linux/types.h>
13#include <asm/sgidefs.h>13#include <asm/sgidefs.h>
14 14
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
15#if _MIPS_SIM == _MIPS_SIM_ABI3227#if _MIPS_SIM == _MIPS_SIM_ABI32
16 28
17/*29/*
arch/mips/include/uapi/asm/swab.h+9−3
@@ -16,11 +16,13 @@ · 15 unmodified lines
16#if (defined(__mips_isa_rev) && (__mips_isa_rev >= 2)) || \16#if (defined(__mips_isa_rev) && (__mips_isa_rev >= 2)) || \
17 defined(_MIPS_ARCH_LOONGSON3A)17 defined(_MIPS_ARCH_LOONGSON3A)
18 18
19static inline __attribute_const__ __u16 __arch_swab16(__u16 x)19static inline __attribute__((nomips16)) __attribute_const__
20 __u16 __arch_swab16(__u16 x)
20{21{
21 __asm__(22 __asm__(
22 " .set push \n"23 " .set push \n"
23 " .set arch=mips32r2 \n"24 " .set arch=mips32r2 \n"
25 " .set nomips16 \n"
24 " wsbh %0, %1 \n"26 " wsbh %0, %1 \n"
25 " .set pop \n"27 " .set pop \n"
26 : "=r" (x)28 : "=r" (x)
@@ -30,11 +32,13 @@ static inline __attribute_const__ __u16 __arch_swab16(__u16 x) · 3 unmodified lines
30}32}
31#define __arch_swab16 __arch_swab1633#define __arch_swab16 __arch_swab16
32 34
33static inline __attribute_const__ __u32 __arch_swab32(__u32 x)35static inline __attribute__((nomips16)) __attribute_const__
36 __u32 __arch_swab32(__u32 x)
34{37{
35 __asm__(38 __asm__(
36 " .set push \n"39 " .set push \n"
37 " .set arch=mips32r2 \n"40 " .set arch=mips32r2 \n"
41 " .set nomips16 \n"
38 " wsbh %0, %1 \n"42 " wsbh %0, %1 \n"
39 " rotr %0, %0, 16 \n"43 " rotr %0, %0, 16 \n"
40 " .set pop \n"44 " .set pop \n"
@@ -50,11 +54,13 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x) · 9 unmodified lines
50 * 64-bit kernel on r2 CPUs.54 * 64-bit kernel on r2 CPUs.
51 */55 */
52#ifdef __mips6456#ifdef __mips64
53static inline __attribute_const__ __u64 __arch_swab64(__u64 x)57static inline __attribute__((nomips16)) __attribute_const__
58 __u64 __arch_swab64(__u64 x)
54{59{
55 __asm__(60 __asm__(
56 " .set push \n"61 " .set push \n"
57 " .set arch=mips64r2 \n"62 " .set arch=mips64r2 \n"
63 " .set nomips16 \n"
58 " dsbh %0, %1 \n"64 " dsbh %0, %1 \n"
59 " dshd %0, %0 \n"65 " dshd %0, %0 \n"
60 " .set pop \n"66 " .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 */
19struct 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 */
34struct 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 */
53struct 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
110 }110 }
111}111}
112 112
113static void r4030_set_mode(enum clock_event_mode mode,
114 struct clock_event_device *evt)
115{
116 /* Nothing to do ... */
117}
118
119struct clock_event_device r4030_clockevent = {113struct clock_event_device r4030_clockevent = {
120 .name = "r4030",114 .name = "r4030",
121 .features = CLOCK_EVT_FEAT_PERIODIC,115 .features = CLOCK_EVT_FEAT_PERIODIC,
122 .rating = 300,116 .rating = 300,
123 .irq = JAZZ_TIMER_IRQ,117 .irq = JAZZ_TIMER_IRQ,
124 .set_mode = r4030_set_mode,
125};118};
126 119
127static irqreturn_t r4030_timer_interrupt(int irq, void *dev_id)120static 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
231 return 0;231 return 0;
232}232}
233 233
234static 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
234int jz_gpio_port_direction_input(int port, uint32_t mask)241int jz_gpio_port_direction_input(int port, uint32_t mask)
235{242{
236 writel(mask, GPIO_TO_REG(port, JZ_REG_GPIO_DIRECTION_CLEAR));243 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
262}269}
263EXPORT_SYMBOL(jz_gpio_port_get_value);270EXPORT_SYMBOL(jz_gpio_port_get_value);
264 271
265int gpio_to_irq(unsigned gpio)
266{
267 return JZ4740_IRQ_GPIO(0) + gpio;
268}
269EXPORT_SYMBOL_GPL(gpio_to_irq);
270
271int irq_to_gpio(unsigned irq)
272{
273 return irq - JZ4740_IRQ_GPIO(0);
274}
275EXPORT_SYMBOL_GPL(irq_to_gpio);
276
277#define IRQ_TO_BIT(irq) BIT(irq_to_gpio(irq) & 0x1f)272#define IRQ_TO_BIT(irq) BIT(irq_to_gpio(irq) & 0x1f)
278 273
279static void jz_gpio_check_trigger_both(struct jz_gpio_chip *chip, unsigned int irq)274static 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
403 .get = jz_gpio_get_value, \398 .get = jz_gpio_get_value, \
404 .direction_output = jz_gpio_direction_output, \399 .direction_output = jz_gpio_direction_output, \
405 .direction_input = jz_gpio_direction_input, \400 .direction_input = jz_gpio_direction_input, \
401 .to_irq = jz_gpio_to_irq, \
406 .base = JZ4740_GPIO_BASE_ ## _bank, \402 .base = JZ4740_GPIO_BASE_ ## _bank, \
407 .ngpio = JZ4740_GPIO_NUM_ ## _bank, \403 .ngpio = JZ4740_GPIO_NUM_ ## _bank, \
408 }, \404 }, \
@@ -423,8 +419,8 @@ static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id) · 14 unmodified lines
423 chip->base = ioremap(JZ4740_GPIO_BASE_ADDR + (id * 0x100), 0x100);419 chip->base = ioremap(JZ4740_GPIO_BASE_ADDR + (id * 0x100), 0x100);
424 420
425 chip->irq = JZ4740_IRQ_INTC_GPIO(id);421 chip->irq = JZ4740_IRQ_INTC_GPIO(id);
426 irq_set_handler_data(chip->irq, chip);422 irq_set_chained_handler_and_data(chip->irq,
427 irq_set_chained_handler(chip->irq, jz_gpio_irq_demux_handler);423 jz_gpio_irq_demux_handler, chip);
428 424
429 gc = irq_alloc_generic_chip(chip->gpio_chip.label, 1, chip->irq_base,425 gc = irq_alloc_generic_chip(chip->gpio_chip.label, 1, chip->irq_base,
430 chip->base, handle_level_irq);426 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
58 58
59 jz4740_timer_ack_full(TIMER_CLOCKEVENT);59 jz4740_timer_ack_full(TIMER_CLOCKEVENT);
60 60
61 if (cd->mode != CLOCK_EVT_MODE_PERIODIC)61 if (!clockevent_state_periodic(cd))
62 jz4740_timer_disable(TIMER_CLOCKEVENT);62 jz4740_timer_disable(TIMER_CLOCKEVENT);
63 63
64 cd->event_handler(cd);64 cd->event_handler(cd);
@@ -66,24 +66,29 @@ static irqreturn_t jz4740_clockevent_irq(int irq, void *devid) · 1 unmodified line
66 return IRQ_HANDLED;66 return IRQ_HANDLED;
67}67}
68 68
69static void jz4740_clockevent_set_mode(enum clock_event_mode mode,69static int jz4740_clockevent_set_periodic(struct clock_event_device *evt)
70 struct clock_event_device *cd)
71{70{
72 switch (mode) {71 jz4740_timer_set_count(TIMER_CLOCKEVENT, 0);
73 case CLOCK_EVT_MODE_PERIODIC:72 jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick);
74 jz4740_timer_set_count(TIMER_CLOCKEVENT, 0);73 jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT);
75 jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick);74 jz4740_timer_enable(TIMER_CLOCKEVENT);
76 case CLOCK_EVT_MODE_RESUME:75
77 jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT);76 return 0;
78 jz4740_timer_enable(TIMER_CLOCKEVENT);77}
79 break;78
80 case CLOCK_EVT_MODE_ONESHOT:79static int jz4740_clockevent_resume(struct clock_event_device *evt)
81 case CLOCK_EVT_MODE_SHUTDOWN:80{
82 jz4740_timer_disable(TIMER_CLOCKEVENT);81 jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT);
83 break;82 jz4740_timer_enable(TIMER_CLOCKEVENT);
84 default:83
85 break;84 return 0;
86 }85}
86
87static int jz4740_clockevent_shutdown(struct clock_event_device *evt)
88{
89 jz4740_timer_disable(TIMER_CLOCKEVENT);
90
91 return 0;
87}92}
88 93
89static int jz4740_clockevent_set_next(unsigned long evt,94static int jz4740_clockevent_set_next(unsigned long evt,
@@ -100,7 +105,10 @@ static struct clock_event_device jz4740_clockevent = { · 10 unmodified lines
100 .name = "jz4740-timer",105 .name = "jz4740-timer",
101 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,106 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
102 .set_next_event = jz4740_clockevent_set_next,107 .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,
104 .rating = 200,112 .rating = 200,
105#ifdef CONFIG_MACH_JZ4740113#ifdef CONFIG_MACH_JZ4740
106 .irq = JZ4740_IRQ_TCU0,114 .irq = JZ4740_IRQ_TCU0,
arch/mips/kernel/Makefile+1−0
@@ -99,6 +99,7 @@ obj-$(CONFIG_PERF_EVENTS) += perf_event.o · 98 unmodified lines
99obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_mipsxx.o99obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_mipsxx.o
100 100
101obj-$(CONFIG_JUMP_LABEL) += jump_label.o101obj-$(CONFIG_JUMP_LABEL) += jump_label.o
102obj-$(CONFIG_UPROBES) += uprobes.o
102 103
103obj-$(CONFIG_MIPS_CM) += mips-cm.o104obj-$(CONFIG_MIPS_CM) += mips-cm.o
104obj-$(CONFIG_MIPS_CPC) += mips-cpc.o105obj-$(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
128 thread.cp0_baduaddr);128 thread.cp0_baduaddr);
129 OFFSET(THREAD_ECODE, task_struct, \129 OFFSET(THREAD_ECODE, task_struct, \
130 thread.error_code);130 thread.error_code);
131 OFFSET(THREAD_TRAPNO, task_struct, thread.trap_nr);
131 BLANK();132 BLANK();
132}133}
133 134
@@ -245,17 +246,6 @@ void output_sc_defines(void) · 111 unmodified lines
245}246}
246#endif247#endif
247 248
248#ifdef CONFIG_MIPS32_COMPAT
249void 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
259void output_signal_defined(void)249void output_signal_defined(void)
260{250{
261 COMMENT("Linux signal numbers.");251 COMMENT("Linux signal numbers.");
arch/mips/kernel/cevt-bcm1480.c+22−22
@@ -40,8 +40,8 @@ · 39 unmodified lines
40 * The general purpose timer ticks at 1MHz independent if40 * The general purpose timer ticks at 1MHz independent if
41 * the rest of the system41 * the rest of the system
42 */42 */
43static void sibyte_set_mode(enum clock_event_mode mode,43
44 struct clock_event_device *evt)44static int sibyte_set_periodic(struct clock_event_device *evt)
45{45{
46 unsigned int cpu = smp_processor_id();46 unsigned int cpu = smp_processor_id();
47 void __iomem *cfg, *init;47 void __iomem *cfg, *init;
@@ -49,24 +49,22 @@ static void sibyte_set_mode(enum clock_event_mode mode, · 1 unmodified line
49 cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));49 cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
50 init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));50 init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
51 51
52 switch (mode) {52 __raw_writeq(0, cfg);
53 case CLOCK_EVT_MODE_PERIODIC:53 __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, init);
54 __raw_writeq(0, cfg);54 __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, cfg);
55 __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, init);55 return 0;
56 __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,56}
57 cfg);57
58 break;58static int sibyte_shutdown(struct clock_event_device *evt)
59 59{
60 case CLOCK_EVT_MODE_ONESHOT:60 unsigned int cpu = smp_processor_id();
61 /* Stop the timer until we actually program a shot */61 void __iomem *cfg;
62 case CLOCK_EVT_MODE_SHUTDOWN:62
63 __raw_writeq(0, cfg);63 cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
64 break;64
65 65 /* Stop the timer until we actually program a shot */
66 case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */66 __raw_writeq(0, cfg);
67 case CLOCK_EVT_MODE_RESUME:67 return 0;
68 ;
69 }
70}68}
71 69
72static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd)70static 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
91 void __iomem *cfg;89 void __iomem *cfg;
92 unsigned long tmode;90 unsigned long tmode;
93 91
94 if (cd->mode == CLOCK_EVT_MODE_PERIODIC)92 if (clockevent_state_periodic(cd))
95 tmode = M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS;93 tmode = M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS;
96 else94 else
97 tmode = 0;95 tmode = 0;
@@ -130,7 +128,9 @@ void sb1480_clockevent_init(void) · 32 unmodified lines
130 cd->irq = irq;128 cd->irq = irq;
131 cd->cpumask = cpumask_of(cpu);129 cd->cpumask = cpumask_of(cpu);
132 cd->set_next_event = sibyte_next_event;130 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;
134 clockevents_register_device(cd);134 clockevents_register_device(cd);
135 135
136 bcm1480_mask_irq(cpu, irq);136 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
59 return -EINVAL;59 return -EINVAL;
60}60}
61 61
62static void ds1287_set_mode(enum clock_event_mode mode,62static int ds1287_shutdown(struct clock_event_device *evt)
63 struct clock_event_device *evt)
64{63{
65 u8 val;64 u8 val;
66 65
67 spin_lock(&rtc_lock);66 spin_lock(&rtc_lock);
68 67
69 val = CMOS_READ(RTC_REG_B);68 val = CMOS_READ(RTC_REG_B);
69 val &= ~RTC_PIE;
70 CMOS_WRITE(val, RTC_REG_B);
70 71
71 switch (mode) {72 spin_unlock(&rtc_lock);
72 case CLOCK_EVT_MODE_PERIODIC:73 return 0;
73 val |= RTC_PIE;74}
74 break;
75 default:
76 val &= ~RTC_PIE;
77 break;
78 }
79 75
76static 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;
80 CMOS_WRITE(val, RTC_REG_B);84 CMOS_WRITE(val, RTC_REG_B);
81 85
82 spin_unlock(&rtc_lock);86 spin_unlock(&rtc_lock);
87 return 0;
83}88}
84 89
85static void ds1287_event_handler(struct clock_event_device *dev)90static 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
87}92}
88 93
89static struct clock_event_device ds1287_clockevent = {94static struct clock_event_device ds1287_clockevent = {
90 .name = "ds1287",95 .name = "ds1287",
91 .features = CLOCK_EVT_FEAT_PERIODIC,96 .features = CLOCK_EVT_FEAT_PERIODIC,
92 .set_next_event = ds1287_set_next_event,97 .set_next_event = ds1287_set_next_event,
93 .set_mode = ds1287_set_mode,98 .set_state_shutdown = ds1287_shutdown,
94 .event_handler = ds1287_event_handler,99 .set_state_periodic = ds1287_set_periodic,
100 .tick_resume = ds1287_shutdown,
101 .event_handler = ds1287_event_handler,
95};102};
96 103
97static irqreturn_t ds1287_interrupt(int irq, void *dev_id)104static 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
64 return 0;64 return 0;
65}65}
66 66
67static void gt641xx_timer0_set_mode(enum clock_event_mode mode,67static int gt641xx_timer0_shutdown(struct clock_event_device *evt)
68 struct clock_event_device *evt)
69{68{
70 u32 ctrl;69 u32 ctrl;
71 70
@@ -73,21 +72,39 @@ static void gt641xx_timer0_set_mode(enum clock_event_mode mode, · 1 unmodified line
73 72
74 ctrl = GT_READ(GT_TC_CONTROL_OFS);73 ctrl = GT_READ(GT_TC_CONTROL_OFS);
75 ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);74 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
81static 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}
76 95
77 switch (mode) {96static int gt641xx_timer0_set_periodic(struct clock_event_device *evt)
78 case CLOCK_EVT_MODE_PERIODIC:97{
79 ctrl |= GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK;98 u32 ctrl;
80 break;99
81 case CLOCK_EVT_MODE_ONESHOT:100 raw_spin_lock(&gt641xx_timer_lock);
82 ctrl |= GT_TC_CONTROL_ENTC0_MSK;
83 break;
84 default:
85 break;
86 }
87 101
102 ctrl = GT_READ(GT_TC_CONTROL_OFS);
103 ctrl |= GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK;
88 GT_WRITE(GT_TC_CONTROL_OFS, ctrl);104 GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
89 105
90 raw_spin_unlock(&gt641xx_timer_lock);106 raw_spin_unlock(&gt641xx_timer_lock);
107 return 0;
91}108}
92 109
93static void gt641xx_timer0_event_handler(struct clock_event_device *dev)110static 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
95}112}
96 113
97static struct clock_event_device gt641xx_timer0_clockevent = {114static struct clock_event_device gt641xx_timer0_clockevent = {
98 .name = "gt641xx-timer0",115 .name = "gt641xx-timer0",
99 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,116 .features = CLOCK_EVT_FEAT_PERIODIC |
100 .irq = GT641XX_TIMER0_IRQ,117 CLOCK_EVT_FEAT_ONESHOT,
101 .set_next_event = gt641xx_timer0_set_next_event,118 .irq = GT641XX_TIMER0_IRQ,
102 .set_mode = gt641xx_timer0_set_mode,119 .set_next_event = gt641xx_timer0_set_next_event,
103 .event_handler = gt641xx_timer0_event_handler,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,
104};125};
105 126
106static irqreturn_t gt641xx_timer0_interrupt(int irq, void *dev_id)127static 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
28 return res;28 return res;
29}29}
30 30
31void mips_set_clock_mode(enum clock_event_mode mode,
32 struct clock_event_device *evt)
33{
34 /* Nothing to do ... */
35}
36
37DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device);31DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device);
38int cp0_timer_irq_installed;32int cp0_timer_irq_installed;
39 33
@@ -174,6 +168,11 @@ int c0_compare_int_usable(void) · 134 unmodified lines
174 return 1;168 return 1;
175}169}
176 170
171unsigned int __weak get_c0_compare_int(void)
172{
173 return MIPS_CPU_IRQ_BASE + cp0_compare_irq;
174}
175
177int r4k_clockevent_init(void)176int r4k_clockevent_init(void)
178{177{
179 unsigned int cpu = smp_processor_id();178 unsigned int cpu = smp_processor_id();
@@ -189,11 +188,9 @@ int r4k_clockevent_init(void) · 9 unmodified lines
189 /*188 /*
190 * With vectored interrupts things are getting platform specific.189 * With vectored interrupts things are getting platform specific.
191 * get_c0_compare_int is a hook to allow a platform to return the190 * 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.
193 */192 */
194 irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;193 irq = get_c0_compare_int();
195 if (get_c0_compare_int)
196 irq = get_c0_compare_int();
197 194
198 cd = &per_cpu(mips_clockevent_device, cpu);195 cd = &per_cpu(mips_clockevent_device, cpu);
199 196
@@ -212,7 +209,6 @@ int r4k_clockevent_init(void) · 12 unmodified lines
212 cd->irq = irq;209 cd->irq = irq;
213 cd->cpumask = cpumask_of(cpu);210 cd->cpumask = cpumask_of(cpu);
214 cd->set_next_event = mips_next_event;211 cd->set_next_event = mips_next_event;
215 cd->set_mode = mips_set_clock_mode;
216 cd->event_handler = mips_event_handler;212 cd->event_handler = mips_event_handler;
217 213
218 clockevents_register_device(cd);214 clockevents_register_device(cd);
arch/mips/kernel/cevt-sb1250.c+23−22
@@ -38,8 +38,20 @@ · 37 unmodified lines
38 * The general purpose timer ticks at 1MHz independent if38 * The general purpose timer ticks at 1MHz independent if
39 * the rest of the system39 * the rest of the system
40 */40 */
41static void sibyte_set_mode(enum clock_event_mode mode,41
42 struct clock_event_device *evt)42static 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
54static int sibyte_set_periodic(struct clock_event_device *evt)
43{55{
44 unsigned int cpu = smp_processor_id();56 unsigned int cpu = smp_processor_id();
45 void __iomem *cfg, *init;57 void __iomem *cfg, *init;
@@ -47,24 +59,11 @@ static void sibyte_set_mode(enum clock_event_mode mode, · 1 unmodified line
47 cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));59 cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
48 init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));60 init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
49 61
50 switch (mode) {62 __raw_writeq(0, cfg);
51 case CLOCK_EVT_MODE_PERIODIC:63 __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, init);
52 __raw_writeq(0, cfg);64 __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, cfg);
53 __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, init);65
54 __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,66 return 0;
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 }
68}67}
69 68
70static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd)69static 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
89 void __iomem *cfg;88 void __iomem *cfg;
90 unsigned long tmode;89 unsigned long tmode;
91 90
92 if (cd->mode == CLOCK_EVT_MODE_PERIODIC)91 if (clockevent_state_periodic(cd))
93 tmode = M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS;92 tmode = M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS;
94 else93 else
95 tmode = 0;94 tmode = 0;
@@ -129,7 +128,9 @@ void sb1250_clockevent_init(void) · 33 unmodified lines
129 cd->irq = irq;128 cd->irq = irq;
130 cd->cpumask = cpumask_of(cpu);129 cd->cpumask = cpumask_of(cpu);
131 cd->set_next_event = sibyte_next_event;130 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;
133 clockevents_register_device(cd);134 clockevents_register_device(cd);
134 135
135 sb1250_mask_irq(cpu, irq);136 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
85 __raw_writel(0, &tmrptr->tisr);85 __raw_writel(0, &tmrptr->tisr);
86}86}
87 87
88static void txx9tmr_set_mode(enum clock_event_mode mode,88static int txx9tmr_set_state_periodic(struct clock_event_device *evt)
89 struct clock_event_device *evt)
90{89{
91 struct txx9_clock_event_device *txx9_cd =90 struct txx9_clock_event_device *txx9_cd =
92 container_of(evt, struct txx9_clock_event_device, cd);91 container_of(evt, struct txx9_clock_event_device, cd);
93 struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;92 struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
94 93
95 txx9tmr_stop_and_clear(tmrptr);94 txx9tmr_stop_and_clear(tmrptr);
96 switch (mode) {95
97 case CLOCK_EVT_MODE_PERIODIC:96 __raw_writel(TXx9_TMITMR_TIIE | TXx9_TMITMR_TZCE, &tmrptr->itmr);
98 __raw_writel(TXx9_TMITMR_TIIE | TXx9_TMITMR_TZCE,97 /* start timer */
99 &tmrptr->itmr);98 __raw_writel(((u64)(NSEC_PER_SEC / HZ) * evt->mult) >> evt->shift,
100 /* start timer */99 &tmrptr->cpra);
101 __raw_writel(((u64)(NSEC_PER_SEC / HZ) * evt->mult) >>100 __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
102 evt->shift,101 return 0;
103 &tmrptr->cpra);102}
104 __raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);103
105 break;104static int txx9tmr_set_state_oneshot(struct clock_event_device *evt)
106 case CLOCK_EVT_MODE_SHUTDOWN:105{
107 case CLOCK_EVT_MODE_UNUSED:106 struct txx9_clock_event_device *txx9_cd =
108 __raw_writel(0, &tmrptr->itmr);107 container_of(evt, struct txx9_clock_event_device, cd);
109 break;108 struct txx9_tmr_reg __iomem *tmrptr = txx9_cd->tmrptr;
110 case CLOCK_EVT_MODE_ONESHOT:109
111 __raw_writel(TXx9_TMITMR_TIIE, &tmrptr->itmr);110 txx9tmr_stop_and_clear(tmrptr);
112 break;111 __raw_writel(TXx9_TMITMR_TIIE, &tmrptr->itmr);
113 case CLOCK_EVT_MODE_RESUME:112 return 0;
114 __raw_writel(TIMER_CCD, &tmrptr->ccdr);113}
115 __raw_writel(0, &tmrptr->itmr);114
116 break;115static int txx9tmr_set_state_shutdown(struct clock_event_device *evt)
117 }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
126static 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;
118}136}
119 137
120static int txx9tmr_set_next_event(unsigned long delta,138static int txx9tmr_set_next_event(unsigned long delta,
@@ -133,12 +151,15 @@ static int txx9tmr_set_next_event(unsigned long delta, · 12 unmodified lines
133 151
134static struct txx9_clock_event_device txx9_clock_event_device = {152static struct txx9_clock_event_device txx9_clock_event_device = {
135 .cd = {153 .cd = {
136 .name = "TXx9",154 .name = "TXx9",
137 .features = CLOCK_EVT_FEAT_PERIODIC |155 .features = CLOCK_EVT_FEAT_PERIODIC |
138 CLOCK_EVT_FEAT_ONESHOT,156 CLOCK_EVT_FEAT_ONESHOT,
139 .rating = 200,157 .rating = 200,
140 .set_mode = txx9tmr_set_mode,158 .set_state_shutdown = txx9tmr_set_state_shutdown,
141 .set_next_event = txx9tmr_set_next_event,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,
142 },163 },
143};164};
144 165
arch/mips/kernel/cps-vec.S+2−2
@@ -152,7 +152,7 @@ dcache_done: · 151 unmodified lines
152 152
153 /* Enter the coherent domain */153 /* Enter the coherent domain */
154 li t0, 0xff154 li t0, 0xff
155 PTR_S t0, GCR_CL_COHERENCE_OFS(v1)155 sw t0, GCR_CL_COHERENCE_OFS(v1)
156 ehb156 ehb
157 157
158 /* Jump to kseg0 */158 /* Jump to kseg0 */
@@ -302,7 +302,7 @@ LEAF(mips_cps_boot_vpes) · 143 unmodified lines
302 PTR_L t0, 0(t0)302 PTR_L t0, 0(t0)
303 303
304 /* Calculate a pointer to this cores struct core_boot_config */304 /* 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)
306 li t1, COREBOOTCFG_SIZE306 li t1, COREBOOTCFG_SIZE
307 mul t0, t0, t1307 mul t0, t0, t1
308 PTR_LA t1, mips_cps_core_bootcfg308 PTR_LA t1, mips_cps_core_bootcfg
arch/mips/kernel/cpu-probe.c+46−10
@@ -32,6 +32,9 @@ · 31 unmodified lines
32#include <asm/spram.h>32#include <asm/spram.h>
33#include <asm/uaccess.h>33#include <asm/uaccess.h>
34 34
35/* Hardware capabilities */
36unsigned int elf_hwcap __read_mostly;
37
35/*38/*
36 * Get the FPU Implementation/Revision.39 * Get the FPU Implementation/Revision.
37 */40 */
@@ -188,7 +191,7 @@ __setup("nohtw", htw_disable); · 150 unmodified lines
188static int mips_ftlb_disabled;191static int mips_ftlb_disabled;
189static int mips_has_ftlb_configured;192static int mips_has_ftlb_configured;
190 193
191static void set_ftlb_enable(struct cpuinfo_mips *c, int enable);194static int set_ftlb_enable(struct cpuinfo_mips *c, int enable);
192 195
193static int __init ftlb_disable(char *s)196static int __init ftlb_disable(char *s)
194{197{
@@ -202,7 +205,10 @@ static int __init ftlb_disable(char *s) · 7 unmodified lines
202 return 1;205 return 1;
203 206
204 /* Disable it in the boot cpu */207 /* 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 }
206 212
207 back_to_back_c0_hazard();213 back_to_back_c0_hazard();
208 214
@@ -364,30 +370,41 @@ static unsigned int calculate_ftlb_probability(struct cpuinfo_mips *c) · 155 unmodified lines
364 return 3;370 return 3;
365}371}
366 372
367static void set_ftlb_enable(struct cpuinfo_mips *c, int enable)373static int set_ftlb_enable(struct cpuinfo_mips *c, int enable)
368{374{
369 unsigned int config6;375 unsigned int config;
370 376
371 /* It's implementation dependent how the FTLB can be enabled */377 /* It's implementation dependent how the FTLB can be enabled */
372 switch (c->cputype) {378 switch (c->cputype) {
373 case CPU_PROAPTIV:379 case CPU_PROAPTIV:
374 case CPU_P5600:380 case CPU_P5600:
375 /* proAptiv & related cores use Config6 to enable the FTLB */381 /* proAptiv & related cores use Config6 to enable the FTLB */
376 config6 = read_c0_config6();382 config = read_c0_config6();
377 /* Clear the old probability value */383 /* Clear the old probability value */
378 config6 &= ~(3 << MIPS_CONF6_FTLBP_SHIFT);384 config &= ~(3 << MIPS_CONF6_FTLBP_SHIFT);
379 if (enable)385 if (enable)
380 /* Enable FTLB */386 /* Enable FTLB */
381 write_c0_config6(config6 |387 write_c0_config6(config |
382 (calculate_ftlb_probability(c)388 (calculate_ftlb_probability(c)
383 << MIPS_CONF6_FTLBP_SHIFT)389 << MIPS_CONF6_FTLBP_SHIFT)
384 | MIPS_CONF6_FTLBEN);390 | MIPS_CONF6_FTLBEN);
385 else391 else
386 /* Disable FTLB */392 /* Disable FTLB */
387 write_c0_config6(config6 & ~MIPS_CONF6_FTLBEN);393 write_c0_config6(config & ~MIPS_CONF6_FTLBEN);
388 back_to_back_c0_hazard();
389 break;394 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;
390 }405 }
406
407 return 0;
391}408}
392 409
393static inline unsigned int decode_config0(struct cpuinfo_mips *c)410static 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
524 }541 }
525 if (config3 & MIPS_CONF3_CDMM)542 if (config3 & MIPS_CONF3_CDMM)
526 c->options |= MIPS_CPU_CDMM;543 c->options |= MIPS_CPU_CDMM;
544 if (config3 & MIPS_CONF3_SP)
545 c->options |= MIPS_CPU_SP;
527 546
528 return config3 & MIPS_CONF_M;547 return config3 & MIPS_CONF_M;
529}548}
@@ -540,7 +559,16 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c) · 10 unmodified lines
540 if (cpu_has_tlb) {559 if (cpu_has_tlb) {
541 if (((config4 & MIPS_CONF4_IE) >> 29) == 2)560 if (((config4 & MIPS_CONF4_IE) >> 29) == 2)
542 c->options |= MIPS_CPU_TLBINV;561 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
544 switch (mmuextdef) {572 switch (mmuextdef) {
545 case MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT:573 case MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT:
546 c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;574 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
1121 c->cputype = CPU_P5600;1149 c->cputype = CPU_P5600;
1122 __cpu_name[cpu] = "MIPS P5600";1150 __cpu_name[cpu] = "MIPS P5600";
1123 break;1151 break;
1152 case PRID_IMP_I6400:
1153 c->cputype = CPU_I6400;
1154 __cpu_name[cpu] = "MIPS I6400";
1155 break;
1124 case PRID_IMP_M5150:1156 case PRID_IMP_M5150:
1125 c->cputype = CPU_M5150;1157 c->cputype = CPU_M5150;
1126 __cpu_name[cpu] = "MIPS M5150";1158 __cpu_name[cpu] = "MIPS M5150";
@@ -1492,10 +1524,14 @@ void cpu_probe(void) · 365 unmodified lines
1492 else1524 else
1493 c->srsets = 1;1525 c->srsets = 1;
1494 1526
1527 if (cpu_has_mips_r6)
1528 elf_hwcap |= HWCAP_MIPS_R6;
1529
1495 if (cpu_has_msa) {1530 if (cpu_has_msa) {
1496 c->msa_id = cpu_get_msa_id();1531 c->msa_id = cpu_get_msa_id();
1497 WARN(c->msa_id & MSA_IR_WRPF,1532 WARN(c->msa_id & MSA_IR_WRPF,
1498 "Vector register partitioning unimplemented!");1533 "Vector register partitioning unimplemented!");
1534 elf_hwcap |= HWCAP_MIPS_MSA;
1499 }1535 }
1500 1536
1501 cpu_probe_vmbits(c);1537 cpu_probe_vmbits(c);
arch/mips/kernel/idle.c+1−0
@@ -196,6 +196,7 @@ void __init check_wait(void) · 195 unmodified lines
196 case CPU_INTERAPTIV:196 case CPU_INTERAPTIV:
197 case CPU_M5150:197 case CPU_M5150:
198 case CPU_QEMU_GENERIC:198 case CPU_QEMU_GENERIC:
199 case CPU_I6400:
199 cpu_wait = r4k_wait;200 cpu_wait = r4k_wait;
200 if (read_c0_config7() & MIPS_CONF7_WII)201 if (read_c0_config7() & MIPS_CONF7_WII)
201 cpu_wait = r4k_wait_irqoff;202 cpu_wait = r4k_wait_irqoff;
arch/mips/kernel/mips-cm.c+256−1
@@ -15,11 +15,131 @@ · 14 unmodified lines
15 15
16void __iomem *mips_cm_base;16void __iomem *mips_cm_base;
17void __iomem *mips_cm_l2sync_base;17void __iomem *mips_cm_l2sync_base;
18int mips_cm_is64;
19
20static char *cm2_tr[8] = {
21 "mem", "gcr", "gic", "mmio",
22 "0x04", "cpc", "0x06", "0x07"
23};
24
25/* CM3 Tag ECC transation type */
26static 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
45static 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 */
81static 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 */
101static 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
112static 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
119static 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
130static 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};
18 138
19phys_addr_t __mips_cm_phys_base(void)139phys_addr_t __mips_cm_phys_base(void)
20{140{
21 u32 config3 = read_c0_config3();141 u32 config3 = read_c0_config3();
22 u32 cmgcr;142 unsigned long cmgcr;
23 143
24 /* Check the CMGCRBase register is implemented */144 /* Check the CMGCRBase register is implemented */
25 if (!(config3 & MIPS_CONF3_CMGCR))145 if (!(config3 & MIPS_CONF3_CMGCR))
@@ -81,6 +201,13 @@ int mips_cm_probe(void) · 55 unmodified lines
81 phys_addr_t addr;201 phys_addr_t addr;
82 u32 base_reg;202 u32 base_reg;
83 203
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
84 addr = mips_cm_phys_base();211 addr = mips_cm_phys_base();
85 BUG_ON((addr & CM_GCR_BASE_GCRBASE_MSK) != addr);212 BUG_ON((addr & CM_GCR_BASE_GCRBASE_MSK) != addr);
86 if (!addr)213 if (!addr)
@@ -117,5 +244,133 @@ int mips_cm_probe(void) · 30 unmodified lines
117 /* probe for an L2-only sync region */244 /* probe for an L2-only sync region */
118 mips_cm_probe_l2sync();245 mips_cm_probe_l2sync();
119 246
247 /* determine register width for this CM */
248 mips_cm_is64 = config_enabled(CONFIG_64BIT) && (mips_cm_revision() >= CM_REV_CM3);
249
120 return 0;250 return 0;
121}251}
252
253void 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
21 21
22static DEFINE_PER_CPU_ALIGNED(unsigned long, cpc_core_lock_flags);22static DEFINE_PER_CPU_ALIGNED(unsigned long, cpc_core_lock_flags);
23 23
24phys_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 */
31static phys_addr_t mips_cpc_phys_base(void)
25{32{
26 u32 cpc_base;33 unsigned long cpc_base;
27 34
28 if (!mips_cm_present())35 if (!mips_cm_present())
29 return 0;36 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
1556#endif1556#endif
1557 break;1557 break;
1558 case CPU_P5600:1558 case CPU_P5600:
1559 case CPU_I6400:
1559 /* 8-bit event numbers */1560 /* 8-bit event numbers */
1560 raw_id = config & 0x1ff;1561 raw_id = config & 0x1ff;
1561 base_id = raw_id & 0xff;1562 base_id = raw_id & 0xff;
@@ -1717,6 +1718,11 @@ init_hw_perf_events(void) · 155 unmodified lines
1717 mipspmu.general_event_map = &mipsxxcore_event_map2;1718 mipspmu.general_event_map = &mipsxxcore_event_map2;
1718 mipspmu.cache_event_map = &mipsxxcore_cache_map2;1719 mipspmu.cache_event_map = &mipsxxcore_cache_map2;
1719 break;1720 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;
1720 case CPU_1004K:1726 case CPU_1004K:
1721 mipspmu.name = "mips/1004K";1727 mipspmu.name = "mips/1004K";
1722 mipspmu.general_event_map = &mipsxxcore_event_map;1728 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
267 267
268 /* CPUs which do not require the workaround */268 /* CPUs which do not require the workaround */
269 case CPU_P5600:269 case CPU_P5600:
270 case CPU_I6400:
270 return 0;271 return 0;
271 272
272 default:273 default:
@@ -671,6 +672,7 @@ static int __init cps_pm_init(void) · 398 unmodified lines
671 case CPU_PROAPTIV:672 case CPU_PROAPTIV:
672 case CPU_M5150:673 case CPU_M5150:
673 case CPU_P5600:674 case CPU_P5600:
675 case CPU_I6400:
674 stype_intervention = 0x2;676 stype_intervention = 0x2;
675 stype_memory = 0x3;677 stype_memory = 0x3;
676 stype_ordering = 0x10;678 stype_ordering = 0x10;
arch/mips/kernel/ptrace.c+88−0
@@ -25,6 +25,7 @@ · 24 unmodified lines
25#include <linux/regset.h>25#include <linux/regset.h>
26#include <linux/smp.h>26#include <linux/smp.h>
27#include <linux/security.h>27#include <linux/security.h>
28#include <linux/stddef.h>
28#include <linux/tracehook.h>29#include <linux/tracehook.h>
29#include <linux/audit.h>30#include <linux/audit.h>
30#include <linux/seccomp.h>31#include <linux/seccomp.h>
@@ -490,6 +491,93 @@ enum mips_regset { · 459 unmodified lines
490 REGSET_FPR,491 REGSET_FPR,
491};492};
492 493
494struct 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
509static 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 */
572int 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
493#if defined(CONFIG_32BIT) || defined(CONFIG_MIPS32_O32)581#if defined(CONFIG_32BIT) || defined(CONFIG_MIPS32_O32)
494 582
495static const struct user_regset mips_regsets[] = {583static const struct user_regset mips_regsets[] = {
arch/mips/kernel/r4k_fpu.S+259−177
@@ -13,6 +13,7 @@ · 12 unmodified lines
13 * Copyright (C) 1999, 2001 Silicon Graphics, Inc.13 * Copyright (C) 1999, 2001 Silicon Graphics, Inc.
14 */14 */
15#include <asm/asm.h>15#include <asm/asm.h>
16#include <asm/asmmacro.h>
16#include <asm/errno.h>17#include <asm/errno.h>
17#include <asm/fpregdef.h>18#include <asm/fpregdef.h>
18#include <asm/mipsregs.h>19#include <asm/mipsregs.h>
@@ -35,6 +36,14 @@ · 16 unmodified lines
35 36
36 .set noreorder37 .set noreorder
37 38
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 */
38LEAF(_save_fp_context)47LEAF(_save_fp_context)
39 .set push48 .set push
40 SET_HARDFLOAT49 SET_HARDFLOAT
@@ -54,117 +63,60 @@ LEAF(_save_fp_context) · 13 unmodified lines
54 nop63 nop
55#endif64#endif
56 /* Store the 16 odd double precision registers */65 /* Store the 16 odd double precision registers */
57 EX sdc1 $f1, SC_FPREGS+8(a0)66 EX sdc1 $f1, 8(a0)
58 EX sdc1 $f3, SC_FPREGS+24(a0)67 EX sdc1 $f3, 24(a0)
59 EX sdc1 $f5, SC_FPREGS+40(a0)68 EX sdc1 $f5, 40(a0)
60 EX sdc1 $f7, SC_FPREGS+56(a0)69 EX sdc1 $f7, 56(a0)
61 EX sdc1 $f9, SC_FPREGS+72(a0)70 EX sdc1 $f9, 72(a0)
62 EX sdc1 $f11, SC_FPREGS+88(a0)71 EX sdc1 $f11, 88(a0)
63 EX sdc1 $f13, SC_FPREGS+104(a0)72 EX sdc1 $f13, 104(a0)
64 EX sdc1 $f15, SC_FPREGS+120(a0)73 EX sdc1 $f15, 120(a0)
65 EX sdc1 $f17, SC_FPREGS+136(a0)74 EX sdc1 $f17, 136(a0)
66 EX sdc1 $f19, SC_FPREGS+152(a0)75 EX sdc1 $f19, 152(a0)
67 EX sdc1 $f21, SC_FPREGS+168(a0)76 EX sdc1 $f21, 168(a0)
68 EX sdc1 $f23, SC_FPREGS+184(a0)77 EX sdc1 $f23, 184(a0)
69 EX sdc1 $f25, SC_FPREGS+200(a0)78 EX sdc1 $f25, 200(a0)
70 EX sdc1 $f27, SC_FPREGS+216(a0)79 EX sdc1 $f27, 216(a0)
71 EX sdc1 $f29, SC_FPREGS+232(a0)80 EX sdc1 $f29, 232(a0)
72 EX sdc1 $f31, SC_FPREGS+248(a0)81 EX sdc1 $f31, 248(a0)
731: .set pop821: .set pop
74#endif83#endif
75 84
76 .set push85 .set push
77 SET_HARDFLOAT86 SET_HARDFLOAT
78 /* Store the 16 even double precision registers */87 /* Store the 16 even double precision registers */
79 EX sdc1 $f0, SC_FPREGS+0(a0)88 EX sdc1 $f0, 0(a0)
80 EX sdc1 $f2, SC_FPREGS+16(a0)89 EX sdc1 $f2, 16(a0)
81 EX sdc1 $f4, SC_FPREGS+32(a0)90 EX sdc1 $f4, 32(a0)
82 EX sdc1 $f6, SC_FPREGS+48(a0)91 EX sdc1 $f6, 48(a0)
83 EX sdc1 $f8, SC_FPREGS+64(a0)92 EX sdc1 $f8, 64(a0)
84 EX sdc1 $f10, SC_FPREGS+80(a0)93 EX sdc1 $f10, 80(a0)
85 EX sdc1 $f12, SC_FPREGS+96(a0)94 EX sdc1 $f12, 96(a0)
86 EX sdc1 $f14, SC_FPREGS+112(a0)95 EX sdc1 $f14, 112(a0)
87 EX sdc1 $f16, SC_FPREGS+128(a0)96 EX sdc1 $f16, 128(a0)
88 EX sdc1 $f18, SC_FPREGS+144(a0)97 EX sdc1 $f18, 144(a0)
89 EX sdc1 $f20, SC_FPREGS+160(a0)98 EX sdc1 $f20, 160(a0)
90 EX sdc1 $f22, SC_FPREGS+176(a0)99 EX sdc1 $f22, 176(a0)
91 EX sdc1 $f24, SC_FPREGS+192(a0)100 EX sdc1 $f24, 192(a0)
92 EX sdc1 $f26, SC_FPREGS+208(a0)101 EX sdc1 $f26, 208(a0)
93 EX sdc1 $f28, SC_FPREGS+224(a0)102 EX sdc1 $f28, 224(a0)
94 EX sdc1 $f30, SC_FPREGS+240(a0)103 EX sdc1 $f30, 240(a0)
95 EX sw t1, SC_FPC_CSR(a0)104 EX sw t1, 0(a1)
96 jr ra105 jr ra
97 li v0, 0 # success106 li v0, 0 # success
98 .set pop107 .set pop
99 END(_save_fp_context)108 END(_save_fp_context)
100 109
101#ifdef CONFIG_MIPS32_COMPAT110/**
102 /* Save 32-bit process floating point context */111 * _restore_fp_context() - restore FP context to the FPU
103LEAF(_save_fp_context32)112 * @a0 - pointer to fpregs field of sigcontext
104 .set push113 * @a1 - pointer to fpc_csr field of sigcontext
105 .set MIPS_ISA_ARCH_LEVEL_RAW114 *
106 SET_HARDFLOAT115 * Restore FP context, including the 32 FP data registers and the FP
107 cfc1 t1, fcr31116 * control & status register, from signal context to the FPU.
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 */
1351: 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
165 */117 */
166LEAF(_restore_fp_context)118LEAF(_restore_fp_context)
167 EX lw t1, SC_FPC_CSR(a0)119 EX lw t1, 0(a1)
168 120
169#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \121#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
170 defined(CONFIG_CPU_MIPS32_R6)122 defined(CONFIG_CPU_MIPS32_R6)
@@ -178,101 +130,231 @@ LEAF(_restore_fp_context) · 7 unmodified lines
178 bgez t0, 1f # skip loading odd if FR=0130 bgez t0, 1f # skip loading odd if FR=0
179 nop131 nop
180#endif132#endif
181 EX ldc1 $f1, SC_FPREGS+8(a0)133 EX ldc1 $f1, 8(a0)
182 EX ldc1 $f3, SC_FPREGS+24(a0)134 EX ldc1 $f3, 24(a0)
183 EX ldc1 $f5, SC_FPREGS+40(a0)135 EX ldc1 $f5, 40(a0)
184 EX ldc1 $f7, SC_FPREGS+56(a0)136 EX ldc1 $f7, 56(a0)
185 EX ldc1 $f9, SC_FPREGS+72(a0)137 EX ldc1 $f9, 72(a0)
186 EX ldc1 $f11, SC_FPREGS+88(a0)138 EX ldc1 $f11, 88(a0)
187 EX ldc1 $f13, SC_FPREGS+104(a0)139 EX ldc1 $f13, 104(a0)
188 EX ldc1 $f15, SC_FPREGS+120(a0)140 EX ldc1 $f15, 120(a0)
189 EX ldc1 $f17, SC_FPREGS+136(a0)141 EX ldc1 $f17, 136(a0)
190 EX ldc1 $f19, SC_FPREGS+152(a0)142 EX ldc1 $f19, 152(a0)
191 EX ldc1 $f21, SC_FPREGS+168(a0)143 EX ldc1 $f21, 168(a0)
192 EX ldc1 $f23, SC_FPREGS+184(a0)144 EX ldc1 $f23, 184(a0)
193 EX ldc1 $f25, SC_FPREGS+200(a0)145 EX ldc1 $f25, 200(a0)
194 EX ldc1 $f27, SC_FPREGS+216(a0)146 EX ldc1 $f27, 216(a0)
195 EX ldc1 $f29, SC_FPREGS+232(a0)147 EX ldc1 $f29, 232(a0)
196 EX ldc1 $f31, SC_FPREGS+248(a0)148 EX ldc1 $f31, 248(a0)
1971: .set pop1491: .set pop
198#endif150#endif
199 .set push151 .set push
200 SET_HARDFLOAT152 SET_HARDFLOAT
201 EX ldc1 $f0, SC_FPREGS+0(a0)153 EX ldc1 $f0, 0(a0)
202 EX ldc1 $f2, SC_FPREGS+16(a0)154 EX ldc1 $f2, 16(a0)
203 EX ldc1 $f4, SC_FPREGS+32(a0)155 EX ldc1 $f4, 32(a0)
204 EX ldc1 $f6, SC_FPREGS+48(a0)156 EX ldc1 $f6, 48(a0)
205 EX ldc1 $f8, SC_FPREGS+64(a0)157 EX ldc1 $f8, 64(a0)
206 EX ldc1 $f10, SC_FPREGS+80(a0)158 EX ldc1 $f10, 80(a0)
207 EX ldc1 $f12, SC_FPREGS+96(a0)159 EX ldc1 $f12, 96(a0)
208 EX ldc1 $f14, SC_FPREGS+112(a0)160 EX ldc1 $f14, 112(a0)
209 EX ldc1 $f16, SC_FPREGS+128(a0)161 EX ldc1 $f16, 128(a0)
210 EX ldc1 $f18, SC_FPREGS+144(a0)162 EX ldc1 $f18, 144(a0)
211 EX ldc1 $f20, SC_FPREGS+160(a0)163 EX ldc1 $f20, 160(a0)
212 EX ldc1 $f22, SC_FPREGS+176(a0)164 EX ldc1 $f22, 176(a0)
213 EX ldc1 $f24, SC_FPREGS+192(a0)165 EX ldc1 $f24, 192(a0)
214 EX ldc1 $f26, SC_FPREGS+208(a0)166 EX ldc1 $f26, 208(a0)
215 EX ldc1 $f28, SC_FPREGS+224(a0)167 EX ldc1 $f28, 224(a0)
216 EX ldc1 $f30, SC_FPREGS+240(a0)168 EX ldc1 $f30, 240(a0)
217 ctc1 t1, fcr31169 ctc1 t1, fcr31
218 .set pop170 .set pop
219 jr ra171 jr ra
220 li v0, 0 # success172 li v0, 0 # success
221 END(_restore_fp_context)173 END(_restore_fp_context)
222 174
223#ifdef CONFIG_MIPS32_COMPAT175#ifdef CONFIG_CPU_HAS_MSA
224LEAF(_restore_fp_context32)
225 /* Restore an o32 sigcontext. */
226 .set push
227 SET_HARDFLOAT
228 EX lw t1, SC32_FPC_CSR(a0)
229 176
230#ifndef CONFIG_CPU_MIPS64_R6177 .macro op_one_wr op, idx, base
231 mfc0 t0, CP0_STATUS178 .align 4
232 sll t0, t0, 5179\idx: \op \idx, 0, \base
233 bgez t0, 1f # skip loading odd if FR=0180 jr ra
234 nop181 nop
235#endif182 .endm
236 183
237 EX ldc1 $f1, SC32_FPREGS+8(a0)184 .macro op_msa_wr name, op
238 EX ldc1 $f3, SC32_FPREGS+24(a0)185LEAF(\name)
239 EX ldc1 $f5, SC32_FPREGS+40(a0)186 .set push
240 EX ldc1 $f7, SC32_FPREGS+56(a0)187 .set noreorder
241 EX ldc1 $f9, SC32_FPREGS+72(a0)188 sll t0, a0, 4
242 EX ldc1 $f11, SC32_FPREGS+88(a0)189 PTR_LA t1, 0f
243 EX ldc1 $f13, SC32_FPREGS+104(a0)190 PTR_ADDU t0, t0, t1
244 EX ldc1 $f15, SC32_FPREGS+120(a0)191 jr t0
245 EX ldc1 $f17, SC32_FPREGS+136(a0)192 nop
246 EX ldc1 $f19, SC32_FPREGS+152(a0)193 op_one_wr \op, 0, a1
247 EX ldc1 $f21, SC32_FPREGS+168(a0)194 op_one_wr \op, 1, a1
248 EX ldc1 $f23, SC32_FPREGS+184(a0)195 op_one_wr \op, 2, a1
249 EX ldc1 $f25, SC32_FPREGS+200(a0)196 op_one_wr \op, 3, a1
250 EX ldc1 $f27, SC32_FPREGS+216(a0)197 op_one_wr \op, 4, a1
251 EX ldc1 $f29, SC32_FPREGS+232(a0)198 op_one_wr \op, 5, a1
252 EX ldc1 $f31, SC32_FPREGS+248(a0)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
253 228
2541: EX ldc1 $f0, SC32_FPREGS+0(a0)229 op_msa_wr read_msa_wr_b, st_b
255 EX ldc1 $f2, SC32_FPREGS+16(a0)230 op_msa_wr read_msa_wr_h, st_h
256 EX ldc1 $f4, SC32_FPREGS+32(a0)231 op_msa_wr read_msa_wr_w, st_w
257 EX ldc1 $f6, SC32_FPREGS+48(a0)232 op_msa_wr read_msa_wr_d, st_d
258 EX ldc1 $f8, SC32_FPREGS+64(a0)233
259 EX ldc1 $f10, SC32_FPREGS+80(a0)234 op_msa_wr write_msa_wr_b, ld_b
260 EX ldc1 $f12, SC32_FPREGS+96(a0)235 op_msa_wr write_msa_wr_h, ld_h
261 EX ldc1 $f14, SC32_FPREGS+112(a0)236 op_msa_wr write_msa_wr_w, ld_w
262 EX ldc1 $f16, SC32_FPREGS+128(a0)237 op_msa_wr write_msa_wr_d, ld_d
263 EX ldc1 $f18, SC32_FPREGS+144(a0)238
264 EX ldc1 $f20, SC32_FPREGS+160(a0)239#endif /* CONFIG_CPU_HAS_MSA */
265 EX ldc1 $f22, SC32_FPREGS+176(a0)240
266 EX ldc1 $f24, SC32_FPREGS+192(a0)241#ifdef CONFIG_CPU_HAS_MSA
267 EX ldc1 $f26, SC32_FPREGS+208(a0)242
268 EX ldc1 $f28, SC32_FPREGS+224(a0)243 .macro save_msa_upper wr, off, base
269 EX ldc1 $f30, SC32_FPREGS+240(a0)244 .set push
270 ctc1 t1, fcr31245 .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
263LEAF(_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
271 jr ra296 jr ra
272 li v0, 0 # success297 li v0, 0
273 .set pop298 END(_save_msa_all_upper)
274 END(_restore_fp_context32)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
275#endif316#endif
317 .set pop
318 .endm
319
320LEAF(_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 */
276 358
277 .set reorder359 .set reorder
278 360
arch/mips/kernel/r4k_switch.S+1−40
@@ -34,7 +34,7 @@ · 33 unmodified lines
34#ifndef USE_ALTERNATE_RESUME_IMPL34#ifndef USE_ALTERNATE_RESUME_IMPL
35/*35/*
36 * task_struct *resume(task_struct *prev, task_struct *next,36 * task_struct *resume(task_struct *prev, task_struct *next,
37 * struct thread_info *next_ti, s32 fp_save)37 * struct thread_info *next_ti)
38 */38 */
39 .align 539 .align 5
40 LEAF(resume)40 LEAF(resume)
@@ -43,45 +43,6 @@ · 2 unmodified lines
43 cpu_save_nonscratch a043 cpu_save_nonscratch a0
44 LONG_S ra, THREAD_REG31(a0)44 LONG_S ra, THREAD_REG31(a0)
45 45
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
801: /* Save 32b/64b scalar FP context. */
81 fpu_save_double a0 t0 t1 # c0_status passed in t0
82 # clobbers t1
832:
84
85#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)46#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
86 PTR_LA t8, __stack_chk_guard47 PTR_LA t8, __stack_chk_guard
87 LONG_L t9, TASK_STACK_CANARY(a1)48 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
31#define lock_fpu_owner() ({ preempt_disable(); pagefault_disable(); })31#define lock_fpu_owner() ({ preempt_disable(); pagefault_disable(); })
32#define unlock_fpu_owner() ({ pagefault_enable(); preempt_enable(); })32#define unlock_fpu_owner() ({ pagefault_enable(); preempt_enable(); })
33 33
34/* Assembly functions to move context to/from the FPU */
35extern asmlinkage int
36_save_fp_context(void __user *fpregs, void __user *csr);
37extern asmlinkage int
38_restore_fp_context(void __user *fpregs, void __user *csr);
39
40extern asmlinkage int _save_msa_all_upper(void __user *buf);
41extern asmlinkage int _restore_msa_all_upper(void __user *buf);
42
34#endif /* __SIGNAL_COMMON_H */43#endif /* __SIGNAL_COMMON_H */
arch/mips/kernel/signal.c+340−93
@@ -21,6 +21,7 @@ · 20 unmodified lines
21#include <linux/wait.h>21#include <linux/wait.h>
22#include <linux/ptrace.h>22#include <linux/ptrace.h>
23#include <linux/unistd.h>23#include <linux/unistd.h>
24#include <linux/uprobes.h>
24#include <linux/compiler.h>25#include <linux/compiler.h>
25#include <linux/syscalls.h>26#include <linux/syscalls.h>
26#include <linux/uaccess.h>27#include <linux/uaccess.h>
@@ -38,20 +39,21 @@ · 11 unmodified lines
38#include <asm/vdso.h>39#include <asm/vdso.h>
39#include <asm/dsp.h>40#include <asm/dsp.h>
40#include <asm/inst.h>41#include <asm/inst.h>
42#include <asm/msa.h>
41 43
42#include "signal-common.h"44#include "signal-common.h"
43 45
44static int (*save_fp_context)(struct sigcontext __user *sc);46static int (*save_fp_context)(void __user *sc);
45static int (*restore_fp_context)(struct sigcontext __user *sc);47static int (*restore_fp_context)(void __user *sc);
46
47extern asmlinkage int _save_fp_context(struct sigcontext __user *sc);
48extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc);
49 48
50struct sigframe {49struct sigframe {
51 u32 sf_ass[4]; /* argument save space for o32 */50 u32 sf_ass[4]; /* argument save space for o32 */
52 u32 sf_pad[2]; /* Was: signal trampoline */51 u32 sf_pad[2]; /* Was: signal trampoline */
52
53 /* Matches struct ucontext from its uc_mcontext field onwards */
53 struct sigcontext sf_sc;54 struct sigcontext sf_sc;
54 sigset_t sf_mask;55 sigset_t sf_mask;
56 unsigned long long sf_extcontext[0];
55};57};
56 58
57struct rt_sigframe {59struct rt_sigframe {
@@ -65,43 +67,255 @@ struct rt_sigframe { · 7 unmodified lines
65 * Thread saved context copy to/from a signal context presumed to be on the67 * Thread saved context copy to/from a signal context presumed to be on the
66 * user stack, and therefore accessed with appropriate macros from uaccess.h.68 * user stack, and therefore accessed with appropriate macros from uaccess.h.
67 */69 */
68static int copy_fp_to_sigcontext(struct sigcontext __user *sc)70static int copy_fp_to_sigcontext(void __user *sc)
69{71{
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;
70 int i;75 int i;
71 int err = 0;76 int err = 0;
77 int inc = test_thread_flag(TIF_32BIT_FPREGS) ? 2 : 1;
72 78
73 for (i = 0; i < NUM_FPU_REGS; i++) {79 for (i = 0; i < NUM_FPU_REGS; i += inc) {
74 err |=80 err |=
75 __put_user(get_fpr64(&current->thread.fpu.fpr[i], 0),81 __put_user(get_fpr64(&current->thread.fpu.fpr[i], 0),
76 &sc->sc_fpregs[i]);82 &fpregs[i]);
77 }83 }
78 err |= __put_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);84 err |= __put_user(current->thread.fpu.fcr31, csr);
79 85
80 return err;86 return err;
81}87}
82 88
83static int copy_fp_from_sigcontext(struct sigcontext __user *sc)89static int copy_fp_from_sigcontext(void __user *sc)
84{90{
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;
85 int i;94 int i;
86 int err = 0;95 int err = 0;
96 int inc = test_thread_flag(TIF_32BIT_FPREGS) ? 2 : 1;
87 u64 fpr_val;97 u64 fpr_val;
88 98
89 for (i = 0; i < NUM_FPU_REGS; i++) {99 for (i = 0; i < NUM_FPU_REGS; i += inc) {
90 err |= __get_user(fpr_val, &sc->sc_fpregs[i]);100 err |= __get_user(fpr_val, &fpregs[i]);
91 set_fpr64(&current->thread.fpu.fpr[i], 0, fpr_val);101 set_fpr64(&current->thread.fpu.fpr[i], 0, fpr_val);
92 }102 }
93 err |= __get_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);103 err |= __get_user(current->thread.fpu.fcr31, csr);
94 104
95 return err;105 return err;
96}106}
97 107
108/*
109 * Wrappers for the assembly _{save,restore}_fp_context functions.
110 */
111static 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
120static 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
133static 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
146static 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
192static 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
235static 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
256static 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
98/*291/*
99 * Helper routines292 * Helper routines
100 */293 */
101static int protected_save_fp_context(struct sigcontext __user *sc)294int protected_save_fp_context(void __user *sc)
102{295{
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;
103 int err;301 int err;
104#ifndef CONFIG_EVA302
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
105 while (1) {319 while (1) {
106 lock_fpu_owner();320 lock_fpu_owner();
107 if (is_fpu_owner()) {321 if (is_fpu_owner()) {
@@ -114,27 +328,57 @@ static int protected_save_fp_context(struct sigcontext __user *sc) · 6 unmodified lines
114 if (likely(!err))328 if (likely(!err))
115 break;329 break;
116 /* touch the sigcontext and try again */330 /* touch the sigcontext and try again */
117 err = __put_user(0, &sc->sc_fpregs[0]) |331 err = __put_user(0, &fpregs[0]) |
118 __put_user(0, &sc->sc_fpregs[31]) |332 __put_user(0, &fpregs[31]) |
119 __put_user(0, &sc->sc_fpc_csr);333 __put_user(0, csr);
120 if (err)334 if (err)
121 break; /* really bad sigcontext */335 return err; /* really bad sigcontext */
122 }336 }
123#else337
124 /*338fp_done:
125 * EVA does not have FPU EVA instructions so saving fpu context directly339 ext_sz = err = save_extcontext(sc_to_extcontext(sc));
126 * does not work.340 if (err < 0)
127 */341 return err;
128 lose_fpu(1);342 used |= ext_sz ? USED_EXTCONTEXT : 0;
129 err = save_fp_context(sc); /* this might fail */343
130#endif344 return __put_user(used, used_math);
131 return err;
132}345}
133 346
134static int protected_restore_fp_context(struct sigcontext __user *sc)347int protected_restore_fp_context(void __user *sc)
135{348{
136 int err, tmp __maybe_unused;349 struct mips_abi *abi = current->thread.abi;
137#ifndef CONFIG_EVA350 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
138 while (1) {382 while (1) {
139 lock_fpu_owner();383 lock_fpu_owner();
140 if (is_fpu_owner()) {384 if (is_fpu_owner()) {
@@ -147,28 +391,24 @@ static int protected_restore_fp_context(struct sigcontext __user *sc) · 6 unmodified lines
147 if (likely(!err))391 if (likely(!err))
148 break;392 break;
149 /* touch the sigcontext and try again */393 /* touch the sigcontext and try again */
150 err = __get_user(tmp, &sc->sc_fpregs[0]) |394 err = __get_user(tmp, &fpregs[0]) |
151 __get_user(tmp, &sc->sc_fpregs[31]) |395 __get_user(tmp, &fpregs[31]) |
152 __get_user(tmp, &sc->sc_fpc_csr);396 __get_user(tmp, csr);
153 if (err)397 if (err)
154 break; /* really bad sigcontext */398 break; /* really bad sigcontext */
155 }399 }
156#else400
157 /*401fp_done:
158 * EVA does not have FPU EVA instructions so restoring fpu context402 if (used & USED_EXTCONTEXT)
159 * directly does not work.403 err |= restore_extcontext(sc_to_extcontext(sc));
160 */404
161 lose_fpu(0);405 return err ?: sig;
162 err = restore_fp_context(sc); /* this might fail */
163#endif
164 return err;
165}406}
166 407
167int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)408int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
168{409{
169 int err = 0;410 int err = 0;
170 int i;411 int i;
171 unsigned int used_math;
172 412
173 err |= __put_user(regs->cp0_epc, &sc->sc_pc);413 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
174 414
@@ -191,19 +431,38 @@ int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) · 16 unmodified lines
191 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);431 err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
192 }432 }
193 433
194 used_math = !!used_math();
195 err |= __put_user(used_math, &sc->sc_used_math);
196 434
197 if (used_math) {435 /*
198 /*436 * Save FPU state to signal context. Signal handler
199 * Save FPU state to signal context. Signal handler437 * will "inherit" current FPU state.
200 * will "inherit" current FPU state.438 */
201 */439 err |= protected_save_fp_context(sc);
202 err |= protected_save_fp_context(sc);440
203 }
204 return err;441 return err;
205}442}
206 443
444static 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
207int fpcsr_pending(unsigned int __user *fpcsr)466int fpcsr_pending(unsigned int __user *fpcsr)
208{467{
209 int err, sig = 0;468 int err, sig = 0;
@@ -223,21 +482,8 @@ int fpcsr_pending(unsigned int __user *fpcsr) · 13 unmodified lines
223 return err ?: sig;482 return err ?: sig;
224}483}
225 484
226static int
227check_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
238int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)485int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
239{486{
240 unsigned int used_math;
241 unsigned long treg;487 unsigned long treg;
242 int err = 0;488 int err = 0;
243 int i;489 int i;
@@ -265,19 +511,7 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) · 21 unmodified lines
265 for (i = 1; i < 32; i++)511 for (i = 1; i < 32; i++)
266 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);512 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
267 513
268 err |= __get_user(used_math, &sc->sc_used_math);514 return err ?: protected_restore_fp_context(sc);
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;
281}515}
282 516
283void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,517void __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
285{519{
286 unsigned long sp;520 unsigned long sp;
287 521
522 /* Leave space for potential extended context */
523 frame_size += extcontext_max_size();
524
288 /* Default to using normal stack */525 /* Default to using normal stack */
289 sp = regs->regs[29];526 sp = regs->regs[29];
290 527
@@ -520,7 +757,11 @@ struct mips_abi mips_abi = { · 229 unmodified lines
520 .setup_rt_frame = setup_rt_frame,757 .setup_rt_frame = setup_rt_frame,
521 .rt_signal_return_offset =758 .rt_signal_return_offset =
522 offsetof(struct mips_vdso, rt_signal_trampoline),759 offsetof(struct mips_vdso, rt_signal_trampoline),
523 .restart = __NR_restart_syscall760 .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),
524};765};
525 766
526static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)767static 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
616 857
617 user_exit();858 user_exit();
618 859
860 if (thread_info_flags & _TIF_UPROBE)
861 uprobe_notify_resume(regs);
862
619 /* deal with pending signal delivery */863 /* deal with pending signal delivery */
620 if (thread_info_flags & _TIF_SIGPENDING)864 if (thread_info_flags & _TIF_SIGPENDING)
621 do_signal(regs);865 do_signal(regs);
@@ -629,43 +873,46 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused, · 7 unmodified lines
629}873}
630 874
631#ifdef CONFIG_SMP875#ifdef CONFIG_SMP
632#ifndef CONFIG_EVA876static int smp_save_fp_context(void __user *sc)
633static int smp_save_fp_context(struct sigcontext __user *sc)
634{877{
635 return raw_cpu_has_fpu878 return raw_cpu_has_fpu
636 ? _save_fp_context(sc)879 ? save_hw_fp_context(sc)
637 : copy_fp_to_sigcontext(sc);880 : copy_fp_to_sigcontext(sc);
638}881}
639 882
640static int smp_restore_fp_context(struct sigcontext __user *sc)883static int smp_restore_fp_context(void __user *sc)
641{884{
642 return raw_cpu_has_fpu885 return raw_cpu_has_fpu
643 ? _restore_fp_context(sc)886 ? restore_hw_fp_context(sc)
644 : copy_fp_from_sigcontext(sc);887 : copy_fp_from_sigcontext(sc);
645}888}
646#endif /* CONFIG_EVA */
647#endif889#endif
648 890
649static int signal_setup(void)891static int signal_setup(void)
650{892{
651#ifndef CONFIG_EVA893 /*
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
652#ifdef CONFIG_SMP903#ifdef CONFIG_SMP
653 /* For now just do the cpu_has_fpu check when the functions are invoked */904 /* For now just do the cpu_has_fpu check when the functions are invoked */
654 save_fp_context = smp_save_fp_context;905 save_fp_context = smp_save_fp_context;
655 restore_fp_context = smp_restore_fp_context;906 restore_fp_context = smp_restore_fp_context;
656#else907#else
657 if (cpu_has_fpu) {908 if (cpu_has_fpu) {
658 save_fp_context = _save_fp_context;909 save_fp_context = save_hw_fp_context;
659 restore_fp_context = _restore_fp_context;910 restore_fp_context = restore_hw_fp_context;
660 } else {911 } else {
661 save_fp_context = copy_fp_to_sigcontext;912 save_fp_context = copy_fp_to_sigcontext;
662 restore_fp_context = copy_fp_from_sigcontext;913 restore_fp_context = copy_fp_from_sigcontext;
663 }914 }
664#endif /* CONFIG_SMP */915#endif /* CONFIG_SMP */
665#else
666 save_fp_context = copy_fp_to_sigcontext;
667 restore_fp_context = copy_fp_from_sigcontext;
668#endif
669 916
670 return 0;917 return 0;
671}918}
arch/mips/kernel/signal32.c+11−196
@@ -36,12 +36,6 @@ · 35 unmodified lines
36 36
37#include "signal-common.h"37#include "signal-common.h"
38 38
39static int (*save_fp_context32)(struct sigcontext32 __user *sc);
40static int (*restore_fp_context32)(struct sigcontext32 __user *sc);
41
42extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc);
43extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc);
44
45/*39/*
46 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...40 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
47 */41 */
@@ -74,99 +68,11 @@ struct rt_sigframe32 { · 26 unmodified lines
74 struct ucontext32 rs_uc;68 struct ucontext32 rs_uc;
75};69};
76 70
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 */
81static 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
97static 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 */
116static 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
140static 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
164static int setup_sigcontext32(struct pt_regs *regs,71static int setup_sigcontext32(struct pt_regs *regs,
165 struct sigcontext32 __user *sc)72 struct sigcontext32 __user *sc)
166{73{
167 int err = 0;74 int err = 0;
168 int i;75 int i;
169 u32 used_math;
170 76
171 err |= __put_user(regs->cp0_epc, &sc->sc_pc);77 err |= __put_user(regs->cp0_epc, &sc->sc_pc);
172 78
@@ -186,35 +92,18 @@ static int setup_sigcontext32(struct pt_regs *regs, · 13 unmodified lines
186 err |= __put_user(mflo3(), &sc->sc_lo3);92 err |= __put_user(mflo3(), &sc->sc_lo3);
187 }93 }
188 94
189 used_math = !!used_math();95 /*
190 err |= __put_user(used_math, &sc->sc_used_math);96 * Save FPU state to signal context. Signal handler
97 * will "inherit" current FPU state.
98 */
99 err |= protected_save_fp_context(sc);
191 100
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 }
199 return err;101 return err;
200}102}
201 103
202static int
203check_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
214static int restore_sigcontext32(struct pt_regs *regs,104static int restore_sigcontext32(struct pt_regs *regs,
215 struct sigcontext32 __user *sc)105 struct sigcontext32 __user *sc)
216{106{
217 u32 used_math;
218 int err = 0;107 int err = 0;
219 s32 treg;108 s32 treg;
220 int i;109 int i;
@@ -238,70 +127,7 @@ static int restore_sigcontext32(struct pt_regs *regs, · 17 unmodified lines
238 for (i = 1; i < 32; i++)127 for (i = 1; i < 32; i++)
239 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);128 err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
240 129
241 err |= __get_user(used_math, &sc->sc_used_math);130 return err ?: protected_restore_fp_context(sc);
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 */
259extern void __put_sigset_unknown_nsig(void);
260extern void __get_sigset_unknown_nsig(void);
261
262static 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
283static 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;
305}131}
306 132
307/*133/*
@@ -585,20 +411,9 @@ struct mips_abi mips_abi_32 = { · 277 unmodified lines
585 .setup_rt_frame = setup_rt_frame_32,411 .setup_rt_frame = setup_rt_frame_32,
586 .rt_signal_return_offset =412 .rt_signal_return_offset =
587 offsetof(struct mips_vdso, o32_rt_signal_trampoline),413 offsetof(struct mips_vdso, o32_rt_signal_trampoline),
588 .restart = __NR_O32_restart_syscall414 .restart = __NR_O32_restart_syscall,
589};
590
591static 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 }
600 415
601 return 0;416 .off_sc_fpregs = offsetof(struct sigcontext32, sc_fpregs),
602}417 .off_sc_fpc_csr = offsetof(struct sigcontext32, sc_fpc_csr),
603 418 .off_sc_used_math = offsetof(struct sigcontext32, sc_used_math),
604arch_initcall(signal32_init);419};
arch/mips/kernel/signal_n32.c+5−1
@@ -153,5 +153,9 @@ struct mips_abi mips_abi_n32 = { · 152 unmodified lines
153 .setup_rt_frame = setup_rt_frame_n32,153 .setup_rt_frame = setup_rt_frame_n32,
154 .rt_signal_return_offset =154 .rt_signal_return_offset =
155 offsetof(struct mips_vdso, n32_rt_signal_trampoline),155 offsetof(struct mips_vdso, n32_rt_signal_trampoline),
156 .restart = __NR_N32_restart_syscall156 .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),
157};161};
arch/mips/kernel/spram.c+1−0
@@ -209,6 +209,7 @@ void spram_config(void) · 208 unmodified lines
209 case CPU_PROAPTIV:209 case CPU_PROAPTIV:
210 case CPU_P5600:210 case CPU_P5600:
211 case CPU_QEMU_GENERIC:211 case CPU_QEMU_GENERIC:
212 case CPU_I6400:
212 config0 = read_c0_config();213 config0 = read_c0_config();
213 /* FIXME: addresses are Malta specific */214 /* FIXME: addresses are Malta specific */
214 if (config0 & (1<<24)) {215 if (config0 & (1<<24)) {
arch/mips/kernel/sysrq.c+1−13
@@ -21,24 +21,12 @@ static DEFINE_SPINLOCK(show_lock); · 20 unmodified lines
21 21
22static void sysrq_tlbdump_single(void *dummy)22static void sysrq_tlbdump_single(void *dummy)
23{23{
24 const int field = 2 * sizeof(unsigned long);
25 unsigned long flags;24 unsigned long flags;
26 25
27 spin_lock_irqsave(&show_lock, flags);26 spin_lock_irqsave(&show_lock, flags);
28 27
29 pr_info("CPU%d:\n", smp_processor_id());28 pr_info("CPU%d:\n", smp_processor_id());
30 pr_info("Index : %0x\n", read_c0_index());29 dump_tlb_regs();
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 }
42 pr_info("\n");30 pr_info("\n");
43 dump_tlb_all();31 dump_tlb_all();
44 pr_info("\n");32 pr_info("\n");
arch/mips/kernel/traps.c+29−28
@@ -370,11 +370,6 @@ void show_registers(struct pt_regs *regs) · 369 unmodified lines
370 set_fs(old_fs);370 set_fs(old_fs);
371}371}
372 372
373static int regs_to_trapnr(struct pt_regs *regs)
374{
375 return (regs->cp0_cause >> 2) & 0x1f;
376}
377
378static DEFINE_RAW_SPINLOCK(die_lock);373static DEFINE_RAW_SPINLOCK(die_lock);
379 374
380void __noreturn die(const char *str, struct pt_regs *regs)375void __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
384 379
385 oops_enter();380 oops_enter();
386 381
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,
388 SIGSEGV) == NOTIFY_STOP)383 SIGSEGV) == NOTIFY_STOP)
389 sig = 0;384 sig = 0;
390 385
@@ -470,7 +465,7 @@ asmlinkage void do_be(struct pt_regs *regs) · 79 unmodified lines
470 printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n",465 printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n",
471 data ? "Data" : "Instruction",466 data ? "Data" : "Instruction",
472 field, regs->cp0_epc, field, regs->regs[31]);467 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,
474 SIGBUS) == NOTIFY_STOP)469 SIGBUS) == NOTIFY_STOP)
475 goto out;470 goto out;
476 471
@@ -826,7 +821,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) · 349 unmodified lines
826 int sig;821 int sig;
827 822
828 prev_state = exception_enter();823 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,
830 SIGFPE) == NOTIFY_STOP)825 SIGFPE) == NOTIFY_STOP)
831 goto out;826 goto out;
832 827
@@ -882,11 +877,12 @@ void do_trap_or_bp(struct pt_regs *regs, unsigned int code, · 49 unmodified lines
882 char b[40];877 char b[40];
883 878
884#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP879#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)
886 return;882 return;
887#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */883#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
888 884
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,
890 SIGTRAP) == NOTIFY_STOP)886 SIGTRAP) == NOTIFY_STOP)
891 return;887 return;
892 888
@@ -948,6 +944,7 @@ asmlinkage void do_bp(struct pt_regs *regs) · 55 unmodified lines
948 set_fs(KERNEL_DS);944 set_fs(KERNEL_DS);
949 945
950 prev_state = exception_enter();946 prev_state = exception_enter();
947 current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
951 if (get_isa16_mode(regs->cp0_epc)) {948 if (get_isa16_mode(regs->cp0_epc)) {
952 u16 instr[2];949 u16 instr[2];
953 950
@@ -987,15 +984,27 @@ asmlinkage void do_bp(struct pt_regs *regs) · 33 unmodified lines
987 * pertain to them.984 * pertain to them.
988 */985 */
989 switch (bcode) {986 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;
990 case BRK_KPROBE_BP:999 case BRK_KPROBE_BP:
991 if (notify_die(DIE_BREAK, "debug", regs, bcode,1000 if (notify_die(DIE_BREAK, "debug", regs, bcode,
992 regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP)1001 current->thread.trap_nr, SIGTRAP) == NOTIFY_STOP)
993 goto out;1002 goto out;
994 else1003 else
995 break;1004 break;
996 case BRK_KPROBE_SSTEPBP:1005 case BRK_KPROBE_SSTEPBP:
997 if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode,1006 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)
999 goto out;1008 goto out;
1000 else1009 else
1001 break;1010 break;
@@ -1028,6 +1037,7 @@ asmlinkage void do_tr(struct pt_regs *regs) · 26 unmodified lines
1028 set_fs(get_ds());1037 set_fs(get_ds());
1029 1038
1030 prev_state = exception_enter();1039 prev_state = exception_enter();
1040 current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
1031 if (get_isa16_mode(regs->cp0_epc)) {1041 if (get_isa16_mode(regs->cp0_epc)) {
1032 if (__get_user(instr[0], (u16 __user *)(epc + 0)) ||1042 if (__get_user(instr[0], (u16 __user *)(epc + 0)) ||
1033 __get_user(instr[1], (u16 __user *)(epc + 2)))1043 __get_user(instr[1], (u16 __user *)(epc + 2)))
@@ -1094,8 +1104,9 @@ asmlinkage void do_ri(struct pt_regs *regs) · 60 unmodified lines
1094no_r2_instr:1104no_r2_instr:
1095 1105
1096 prev_state = exception_enter();1106 prev_state = exception_enter();
1107 current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
1097 1108
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,
1099 SIGILL) == NOTIFY_STOP)1110 SIGILL) == NOTIFY_STOP)
1100 goto out;1111 goto out;
1101 1112
@@ -1444,8 +1455,9 @@ asmlinkage void do_msa_fpe(struct pt_regs *regs, unsigned int msacsr) · 342 unmodified lines
1444 enum ctx_state prev_state;1455 enum ctx_state prev_state;
1445 1456
1446 prev_state = exception_enter();1457 prev_state = exception_enter();
1458 current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
1447 if (notify_die(DIE_MSAFP, "MSA FP exception", regs, 0,1459 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)
1449 goto out;1461 goto out;
1450 1462
1451 /* Clear MSACSR.Cause before enabling interrupts */1463 /* Clear MSACSR.Cause before enabling interrupts */
@@ -1523,7 +1535,6 @@ asmlinkage void do_watch(struct pt_regs *regs) · 71 unmodified lines
1523 1535
1524asmlinkage void do_mcheck(struct pt_regs *regs)1536asmlinkage void do_mcheck(struct pt_regs *regs)
1525{1537{
1526 const int field = 2 * sizeof(unsigned long);
1527 int multi_match = regs->cp0_status & ST0_TS;1538 int multi_match = regs->cp0_status & ST0_TS;
1528 enum ctx_state prev_state;1539 enum ctx_state prev_state;
1529 mm_segment_t old_fs = get_fs();1540 mm_segment_t old_fs = get_fs();
@@ -1532,19 +1543,8 @@ asmlinkage void do_mcheck(struct pt_regs *regs) · 2 unmodified lines
1532 show_regs(regs);1543 show_regs(regs);
1533 1544
1534 if (multi_match) {1545 if (multi_match) {
1535 pr_err("Index : %0x\n", read_c0_index());1546 dump_tlb_regs();
1536 pr_err("Pagemask: %0x\n", read_c0_pagemask());1547 pr_info("\n");
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");
1548 dump_tlb_all();1548 dump_tlb_all();
1549 }1549 }
1550 1550
@@ -1651,6 +1651,7 @@ static inline void parity_protection_init(void) · 100 unmodified lines
1651 case CPU_PROAPTIV:1651 case CPU_PROAPTIV:
1652 case CPU_P5600:1652 case CPU_P5600:
1653 case CPU_QEMU_GENERIC:1653 case CPU_QEMU_GENERIC:
1654 case CPU_I6400:
1654 {1655 {
1655#define ERRCTL_PE 0x800000001656#define ERRCTL_PE 0x80000000
1656#define ERRCTL_L2P 0x008000001657#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
891#ifdef CONFIG_EVA891#ifdef CONFIG_EVA
892 mm_segment_t seg;892 mm_segment_t seg;
893#endif893#endif
894 union fpureg *fpr;
895 enum msa_2b_fmt df;
896 unsigned int wd;
894 origpc = (unsigned long)pc;897 origpc = (unsigned long)pc;
895 orig31 = regs->regs[31];898 orig31 = regs->regs[31];
896 899
@@ -1202,6 +1205,75 @@ static void emulate_load_store_insn(struct pt_regs *regs, · 305 unmodified lines
1202 break;1205 break;
1203 return;1206 return;
1204 1207
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
1205#ifndef CONFIG_CPU_MIPSR61277#ifndef CONFIG_CPU_MIPSR6
1206 /*1278 /*
1207 * COP2 is available to implementor for application specific use.1279 * COP2 is available to implementor for application specific use.
@@ -2240,5 +2312,5 @@ static int __init debugfs_unaligned(void) · 1032 unmodified lines
2240 return -ENOMEM;2312 return -ENOMEM;
2241 return 0;2313 return 0;
2242}2314}
2243__initcall(debugfs_unaligned);2315arch_initcall(debugfs_unaligned);
2244#endif2316#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
13static 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 */
85int 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 */
114bool 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 */
157int 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
182int 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 */
202bool 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
210int 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 */
244void 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
252unsigned 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 */
277int __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 */
294int 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
301void __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 */
327unsigned 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 */
338bool 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
817 817
818static int vpe_release(struct inode *inode, struct file *filp)818static int vpe_release(struct inode *inode, struct file *filp)
819{819{
820#if defined(CONFIG_MIPS_VPE_LOADER_MT) || defined(CONFIG_MIPS_VPE_LOADER_CMP)
820 struct vpe *v;821 struct vpe *v;
821 Elf_Ehdr *hdr;822 Elf_Ehdr *hdr;
822 int ret = 0;823 int ret = 0;
@@ -827,7 +828,7 @@ static int vpe_release(struct inode *inode, struct file *filp) · 4 unmodified lines
827 828
828 hdr = (Elf_Ehdr *) v->pbuffer;829 hdr = (Elf_Ehdr *) v->pbuffer;
829 if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) == 0) {830 if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) == 0) {
830 if ((vpe_elfload(v) >= 0) && vpe_run) {831 if (vpe_elfload(v) >= 0) {
831 vpe_run(v);832 vpe_run(v);
832 } else {833 } else {
833 pr_warn("VPE loader: ELF load failed.\n");834 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
850 v->plen = 0;851 v->plen = 0;
851 852
852 return ret;853 return ret;
854#else
855 pr_warn("VPE loader: ELF load failed.\n");
856 return -ENOEXEC;
857#endif
853}858}
854 859
855static ssize_t vpe_write(struct file *file, const char __user *buffer,860static 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
270 return 0;270 return 0;
271}271}
272 272
273__initcall(lasat_register_sysctl);273arch_initcall(lasat_register_sysctl);
arch/mips/lib/dump_tlb.c+36−9
@@ -13,6 +13,33 @@ · 12 unmodified lines
13#include <asm/pgtable.h>13#include <asm/pgtable.h>
14#include <asm/tlbdebug.h>14#include <asm/tlbdebug.h>
15 15
16void 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
16static inline const char *msk2str(unsigned int mask)43static inline const char *msk2str(unsigned int mask)
17{44{
18 switch (mask) {45 switch (mask) {
@@ -87,7 +114,7 @@ static void dump_tlb(int first, int last) · 68 unmodified lines
87 * leave only a single G bit set after a machine check exception114 * leave only a single G bit set after a machine check exception
88 * due to duplicate TLB entry.115 * due to duplicate TLB entry.
89 */116 */
90 if (!((entrylo0 | entrylo1) & MIPS_ENTRYLO_G) &&117 if (!((entrylo0 | entrylo1) & ENTRYLO_G) &&
91 (entryhi & 0xff) != asid)118 (entryhi & 0xff) != asid)
92 continue;119 continue;
93 120
@@ -96,8 +123,8 @@ static void dump_tlb(int first, int last) · 2 unmodified lines
96 */123 */
97 printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));124 printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
98 125
99 c0 = (entrylo0 & MIPS_ENTRYLO_C) >> MIPS_ENTRYLO_C_SHIFT;126 c0 = (entrylo0 & ENTRYLO_C) >> ENTRYLO_C_SHIFT;
100 c1 = (entrylo1 & MIPS_ENTRYLO_C) >> MIPS_ENTRYLO_C_SHIFT;127 c1 = (entrylo1 & ENTRYLO_C) >> ENTRYLO_C_SHIFT;
101 128
102 printk("va=%0*lx asid=%02lx\n",129 printk("va=%0*lx asid=%02lx\n",
103 vwidth, (entryhi & ~0x1fffUL),130 vwidth, (entryhi & ~0x1fffUL),
@@ -114,9 +141,9 @@ static void dump_tlb(int first, int last) · 10 unmodified lines
114 (entrylo0 & MIPS_ENTRYLO_XI) ? 1 : 0);141 (entrylo0 & MIPS_ENTRYLO_XI) ? 1 : 0);
115 printk("pa=%0*llx c=%d d=%d v=%d g=%d] [",142 printk("pa=%0*llx c=%d d=%d v=%d g=%d] [",
116 pwidth, pa, c0,143 pwidth, pa, c0,
117 (entrylo0 & MIPS_ENTRYLO_D) ? 1 : 0,144 (entrylo0 & ENTRYLO_D) ? 1 : 0,
118 (entrylo0 & MIPS_ENTRYLO_V) ? 1 : 0,145 (entrylo0 & ENTRYLO_V) ? 1 : 0,
119 (entrylo0 & MIPS_ENTRYLO_G) ? 1 : 0);146 (entrylo0 & ENTRYLO_G) ? 1 : 0);
120 /* RI/XI are in awkward places, so mask them off separately */147 /* RI/XI are in awkward places, so mask them off separately */
121 pa = entrylo1 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI);148 pa = entrylo1 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI);
122 if (xpa)149 if (xpa)
@@ -128,9 +155,9 @@ static void dump_tlb(int first, int last) · 5 unmodified lines
128 (entrylo1 & MIPS_ENTRYLO_XI) ? 1 : 0);155 (entrylo1 & MIPS_ENTRYLO_XI) ? 1 : 0);
129 printk("pa=%0*llx c=%d d=%d v=%d g=%d]\n",156 printk("pa=%0*llx c=%d d=%d v=%d g=%d]\n",
130 pwidth, pa, c1,157 pwidth, pa, c1,
131 (entrylo1 & MIPS_ENTRYLO_D) ? 1 : 0,158 (entrylo1 & ENTRYLO_D) ? 1 : 0,
132 (entrylo1 & MIPS_ENTRYLO_V) ? 1 : 0,159 (entrylo1 & ENTRYLO_V) ? 1 : 0,
133 (entrylo1 & MIPS_ENTRYLO_G) ? 1 : 0);160 (entrylo1 & ENTRYLO_G) ? 1 : 0);
134 }161 }
135 printk("\n");162 printk("\n");
136 163
arch/mips/lib/r3k_dump_tlb.c+11−0
@@ -14,6 +14,17 @@ · 13 unmodified lines
14#include <asm/pgtable.h>14#include <asm/pgtable.h>
15#include <asm/tlbdebug.h>15#include <asm/tlbdebug.h>
16 16
17extern int r3k_have_wired_reg;
18
19void 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
17static void dump_tlb(int first, int last)28static void dump_tlb(int first, int last)
18{29{
19 int i;30 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
126 return IRQ_HANDLED;126 return IRQ_HANDLED;
127}127}
128 128
129static void ls1x_clockevent_set_mode(enum clock_event_mode mode,129static int ls1x_clockevent_set_state_periodic(struct clock_event_device *cd)
130 struct clock_event_device *cd)
131{130{
132 raw_spin_lock(&ls1x_timer_lock);131 raw_spin_lock(&ls1x_timer_lock);
133 switch (mode) {132 ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick);
134 case CLOCK_EVT_MODE_PERIODIC:133 ls1x_pwmtimer_restart();
135 ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick);134 __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL);
136 ls1x_pwmtimer_restart();
137 case CLOCK_EVT_MODE_RESUME:
138 __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL);
139 break;
140 case CLOCK_EVT_MODE_ONESHOT:
141 case CLOCK_EVT_MODE_SHUTDOWN:
142 __raw_writel(__raw_readl(timer_base + PWM_CTRL) & ~CNT_EN,
143 timer_base + PWM_CTRL);
144 break;
145 default:
146 break;
147 }
148 raw_spin_unlock(&ls1x_timer_lock);135 raw_spin_unlock(&ls1x_timer_lock);
136
137 return 0;
138}
139
140static 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
149static 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;
149}157}
150 158
151static int ls1x_clockevent_set_next(unsigned long evt,159static int ls1x_clockevent_set_next(unsigned long evt,
@@ -160,12 +168,15 @@ static int ls1x_clockevent_set_next(unsigned long evt, · 8 unmodified lines
160}168}
161 169
162static struct clock_event_device ls1x_clockevent = {170static struct clock_event_device ls1x_clockevent = {
163 .name = "ls1x-pwmtimer",171 .name = "ls1x-pwmtimer",
164 .features = CLOCK_EVT_FEAT_PERIODIC,172 .features = CLOCK_EVT_FEAT_PERIODIC,
165 .rating = 300,173 .rating = 300,
166 .irq = LS1X_TIMER_IRQ,174 .irq = LS1X_TIMER_IRQ,
167 .set_next_event = ls1x_clockevent_set_next,175 .set_next_event = ls1x_clockevent_set_next,
168 .set_mode = ls1x_clockevent_set_mode,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,
169};180};
170 181
171static struct irqaction ls1x_pwmtimer_irqaction = {182static 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
51}51}
52EXPORT_SYMBOL(enable_mfgpt0_counter);52EXPORT_SYMBOL(enable_mfgpt0_counter);
53 53
54static void init_mfgpt_timer(enum clock_event_mode mode,54static int mfgpt_timer_set_periodic(struct clock_event_device *evt)
55 struct clock_event_device *evt)
56{55{
57 raw_spin_lock(&mfgpt_lock);56 raw_spin_lock(&mfgpt_lock);
58 57
59 switch (mode) {58 outw(COMPARE, MFGPT0_CMP2); /* set comparator2 */
60 case CLOCK_EVT_MODE_PERIODIC:59 outw(0, MFGPT0_CNT); /* set counter to 0 */
61 outw(COMPARE, MFGPT0_CMP2); /* set comparator2 */60 enable_mfgpt0_counter();
62 outw(0, MFGPT0_CNT); /* set counter to 0 */61
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 }
81 raw_spin_unlock(&mfgpt_lock);62 raw_spin_unlock(&mfgpt_lock);
63 return 0;
64}
65
66static 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;
82}75}
83 76
84static struct clock_event_device mfgpt_clockevent = {77static struct clock_event_device mfgpt_clockevent = {
85 .name = "mfgpt",78 .name = "mfgpt",
86 .features = CLOCK_EVT_FEAT_PERIODIC,79 .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,
88 .irq = CS5536_MFGPT_INTR,84 .irq = CS5536_MFGPT_INTR,
89};85};
90 86
arch/mips/loongson64/loongson-3/hpet.c+71−46
@@ -78,55 +78,77 @@ static void hpet_enable_legacy_int(void) · 77 unmodified lines
78 /* Do nothing on Loongson-3 */78 /* Do nothing on Loongson-3 */
79}79}
80 80
81static void hpet_set_mode(enum clock_event_mode mode,81static int hpet_set_state_periodic(struct clock_event_device *evt)
82 struct clock_event_device *evt)
83{82{
84 int cfg = 0;83 int cfg;
85 84
86 spin_lock(&hpet_lock);85 spin_lock(&hpet_lock);
87 switch (mode) {86
88 case CLOCK_EVT_MODE_PERIODIC:87 pr_info("set clock event to periodic mode!\n");
89 pr_info("set clock event to periodic mode!\n");88 /* stop counter */
90 /* stop counter */89 hpet_stop_counter();
91 hpet_stop_counter();90
92 91 /* enables the timer0 to generate a periodic interrupt */
93 /* enables the timer0 to generate a periodic interrupt */92 cfg = hpet_read(HPET_T0_CFG);
94 cfg = hpet_read(HPET_T0_CFG);93 cfg &= ~HPET_TN_LEVEL;
95 cfg &= ~HPET_TN_LEVEL;94 cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
96 cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |95 HPET_TN_32BIT;
97 HPET_TN_SETVAL | HPET_TN_32BIT;96 hpet_write(HPET_T0_CFG, cfg);
98 hpet_write(HPET_T0_CFG, cfg);97
99 98 /* set the comparator */
100 /* set the comparator */99 hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL);
101 hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL);100 udelay(1);
102 udelay(1);101 hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL);
103 hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL);102
104 103 /* start counter */
105 /* start counter */104 hpet_start_counter();
106 hpet_start_counter();105
107 break;106 spin_unlock(&hpet_lock);
108 case CLOCK_EVT_MODE_SHUTDOWN:107 return 0;
109 case CLOCK_EVT_MODE_UNUSED:108}
110 cfg = hpet_read(HPET_T0_CFG);109
111 cfg &= ~HPET_TN_ENABLE;110static int hpet_set_state_shutdown(struct clock_event_device *evt)
112 hpet_write(HPET_T0_CFG, cfg);111{
113 break;112 int cfg;
114 case CLOCK_EVT_MODE_ONESHOT:113
115 pr_info("set clock event to one shot mode!\n");114 spin_lock(&hpet_lock);
116 cfg = hpet_read(HPET_T0_CFG);115
117 /* set timer0 type116 cfg = hpet_read(HPET_T0_CFG);
118 * 1 : periodic interrupt117 cfg &= ~HPET_TN_ENABLE;
119 * 0 : non-periodic(oneshot) interrupt118 hpet_write(HPET_T0_CFG, cfg);
120 */119
121 cfg &= ~HPET_TN_PERIODIC;
122 cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
123 hpet_write(HPET_T0_CFG, cfg);
124 break;
125 case CLOCK_EVT_MODE_RESUME:
126 hpet_enable_legacy_int();
127 break;
128 }
129 spin_unlock(&hpet_lock);120 spin_unlock(&hpet_lock);
121 return 0;
122}
123
124static 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
145static 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;
130}152}
131 153
132static int hpet_next_event(unsigned long delta,154static int hpet_next_event(unsigned long delta,
@@ -206,7 +228,10 @@ void __init setup_hpet_timer(void) · 73 unmodified lines
206 cd->name = "hpet";228 cd->name = "hpet";
207 cd->rating = 320;229 cd->rating = 320;
208 cd->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;230 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;
210 cd->set_next_event = hpet_next_event;235 cd->set_next_event = hpet_next_event;
211 cd->irq = HPET_T0_IRQ;236 cd->irq = HPET_T0_IRQ;
212 cd->cpumask = cpumask_of(cpu);237 cd->cpumask = cpumask_of(cpu);
arch/mips/math-emu/Makefile+2−2
@@ -4,9 +4,9 @@ · 3 unmodified lines
4 4
5obj-y += cp1emu.o ieee754dp.o ieee754sp.o ieee754.o \5obj-y += cp1emu.o ieee754dp.o ieee754sp.o ieee754.o \
6 dp_div.o dp_mul.o dp_sub.o dp_add.o dp_fsp.o dp_cmp.o dp_simple.o \6 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 \
8 sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_simple.o \8 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 \
10 dsemul.o10 dsemul.o
11 11
12lib-y += ieee754d.o \12lib-y += ieee754d.o \
arch/mips/math-emu/cp1emu.c+387−13
@@ -1137,7 +1137,7 @@ emul: · 1136 unmodified lines
1137 break;1137 break;
1138 1138
1139 case mfhc_op:1139 case mfhc_op:
1140 if (!cpu_has_mips_r2)1140 if (!cpu_has_mips_r2_r6)
1141 goto sigill;1141 goto sigill;
1142 1142
1143 /* copregister rd -> gpr[rt] */1143 /* copregister rd -> gpr[rt] */
@@ -1148,7 +1148,7 @@ emul: · 4 unmodified lines
1148 break;1148 break;
1149 1149
1150 case mthc_op:1150 case mthc_op:
1151 if (!cpu_has_mips_r2)1151 if (!cpu_has_mips_r2_r6)
1152 goto sigill;1152 goto sigill;
1153 1153
1154 /* copregister rd <- gpr[rt] */1154 /* copregister rd <- gpr[rt] */
@@ -1181,6 +1181,24 @@ emul: · 26 unmodified lines
1181 }1181 }
1182 break;1182 break;
1183 1183
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
1184 case bc_op:1202 case bc_op:
1185 if (delay_slot(xcp))1203 if (delay_slot(xcp))
1186 return SIGILL;1204 return SIGILL;
@@ -1207,7 +1225,7 @@ emul: · 20 unmodified lines
1207 case bct_op:1225 case bct_op:
1208 break;1226 break;
1209 }1227 }
1210 1228branch_common:
1211 set_delay_slot(xcp);1229 set_delay_slot(xcp);
1212 if (cond) {1230 if (cond) {
1213 /*1231 /*
@@ -1376,6 +1394,14 @@ static const unsigned char cmptab[8] = { · 162 unmodified lines
1376 IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN, /* cmp_ule (sig) cmp_ngt */1394 IEEE754_CLT | IEEE754_CEQ | IEEE754_CUN, /* cmp_ule (sig) cmp_ngt */
1377};1395};
1378 1396
1397static 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
1379 1405
1380/*1406/*
1381 * Additional MIPS4 instructions1407 * Additional MIPS4 instructions
@@ -1717,6 +1743,126 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, · 335 unmodified lines
1717 SPFROMREG(rv.s, MIPSInst_FS(ir));1743 SPFROMREG(rv.s, MIPSInst_FS(ir));
1718 break;1744 break;
1719 1745
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
1720 case fabs_op:1866 case fabs_op:
1721 handler.u = ieee754sp_abs;1867 handler.u = ieee754sp_abs;
1722 goto scopuop;1868 goto scopuop;
@@ -1820,7 +1966,7 @@ copcsr: · 97 unmodified lines
1820 goto copcsr;1966 goto copcsr;
1821 1967
1822 default:1968 default:
1823 if (MIPSInst_FUNC(ir) >= fcmp_op) {1969 if (!NO_R6EMU && MIPSInst_FUNC(ir) >= fcmp_op) {
1824 unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;1970 unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
1825 union ieee754sp fs, ft;1971 union ieee754sp fs, ft;
1826 1972
@@ -1914,6 +2060,127 @@ copcsr: · 87 unmodified lines
1914 return 0;2060 return 0;
1915 DPFROMREG(rv.d, MIPSInst_FS(ir));2061 DPFROMREG(rv.d, MIPSInst_FS(ir));
1916 break;2062 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
1917 case fabs_op:2184 case fabs_op:
1918 handler.u = ieee754dp_abs;2185 handler.u = ieee754dp_abs;
1919 goto dcopuop;2186 goto dcopuop;
@@ -1997,7 +2264,7 @@ dcopuop: · 77 unmodified lines
1997 goto copcsr;2264 goto copcsr;
1998 2265
1999 default:2266 default:
2000 if (MIPSInst_FUNC(ir) >= fcmp_op) {2267 if (!NO_R6EMU && MIPSInst_FUNC(ir) >= fcmp_op) {
2001 unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;2268 unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;
2002 union ieee754dp fs, ft;2269 union ieee754dp fs, ft;
2003 2270
@@ -2021,8 +2288,11 @@ dcopuop: · 17 unmodified lines
2021 break;2288 break;
2022 }2289 }
2023 break;2290 break;
2291 }
2292
2293 case w_fmt: {
2294 union ieee754dp fs;
2024 2295
2025 case w_fmt:
2026 switch (MIPSInst_FUNC(ir)) {2296 switch (MIPSInst_FUNC(ir)) {
2027 case fcvts_op:2297 case fcvts_op:
2028 /* convert word to single precision real */2298 /* convert word to single precision real */
@@ -2036,10 +2306,65 @@ dcopuop: · 7 unmodified lines
2036 rv.d = ieee754dp_fint(fs.bits);2306 rv.d = ieee754dp_fint(fs.bits);
2037 rfmt = d_fmt;2307 rfmt = d_fmt;
2038 goto copcsr;2308 goto copcsr;
2039 default:2309 default: {
2040 return SIGILL;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 }
2041 }2367 }
2042 break;
2043 }2368 }
2044 2369
2045 case l_fmt:2370 case l_fmt:
@@ -2060,11 +2385,60 @@ dcopuop: · 14 unmodified lines
2060 rv.d = ieee754dp_flong(bits);2385 rv.d = ieee754dp_flong(bits);
2061 rfmt = d_fmt;2386 rfmt = d_fmt;
2062 goto copcsr;2387 goto copcsr;
2063 default:2388 default: {
2064 return SIGILL;2389 /* Emulating the new CMP.condn.fmt R6 instruction */
2065 }2390 int cmpop = MIPSInst_FUNC(ir) & CMPOP_MASK;
2066 break;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;
2067 2402
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 }
2068 default:2442 default:
2069 return SIGILL;2443 return SIGILL;
2070 }2444 }
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
17int 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
21union 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
121union 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
21union 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
121union 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
17union 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
17union 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
33 33
34int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)34int mips_dsemul(struct pt_regs *regs, mips_instruction ir, unsigned long cpc)
35{35{
36 extern asmlinkage void handle_dsemulret(void);
37 struct emuframe __user *fr;36 struct emuframe __user *fr;
38 int err;37 int err;
39 38
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
75 75
76union ieee754sp ieee754sp_sqrt(union ieee754sp x);76union ieee754sp ieee754sp_sqrt(union ieee754sp x);
77 77
78union ieee754sp ieee754sp_maddf(union ieee754sp z, union ieee754sp x,
79 union ieee754sp y);
80union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x,
81 union ieee754sp y);
82int ieee754sp_2008class(union ieee754sp x);
83union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y);
84union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y);
85union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y);
86union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y);
87
78/*88/*
79 * double precision (often aka double)89 * double precision (often aka double)
80*/90*/
@@ -99,6 +109,15 @@ int ieee754dp_cmp(union ieee754dp x, union ieee754dp y, int cop, int sig); · 18 unmodified lines
99 109
100union ieee754dp ieee754dp_sqrt(union ieee754dp x);110union ieee754dp ieee754dp_sqrt(union ieee754dp x);
101 111
112union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x,
113 union ieee754dp y);
114union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x,
115 union ieee754dp y);
116int ieee754dp_2008class(union ieee754dp x);
117union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y);
118union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y);
119union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y);
120union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y);
102 121
103 122
104/* 5 types of floating point number123/* 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
65 vc = IEEE754_CLASS_INF; \65 vc = IEEE754_CLASS_INF; \
66 else if (vm & SP_MBIT(SP_FBITS-1)) \66 else if (vm & SP_MBIT(SP_FBITS-1)) \
67 vc = IEEE754_CLASS_SNAN; \67 vc = IEEE754_CLASS_SNAN; \
68 else \68 else \
69 vc = IEEE754_CLASS_QNAN; \69 vc = IEEE754_CLASS_QNAN; \
70 } else if (ve == SP_EMIN-1+SP_EBIAS) { \70 } else if (ve == SP_EMIN-1+SP_EBIAS) { \
71 if (vm) { \71 if (vm) { \
72 ve = SP_EMIN; \72 ve = SP_EMIN; \
@@ -105,8 +105,8 @@ static inline int ieee754_class_nan(int xc) · 32 unmodified lines
105 if (vm) { \105 if (vm) { \
106 ve = DP_EMIN; \106 ve = DP_EMIN; \
107 vc = IEEE754_CLASS_DNORM; \107 vc = IEEE754_CLASS_DNORM; \
108 } else \108 } else \
109 vc = IEEE754_CLASS_ZERO; \109 vc = IEEE754_CLASS_ZERO; \
110 } else { \110 } else { \
111 ve -= DP_EBIAS; \111 ve -= DP_EBIAS; \
112 vm |= DP_HIDDEN_BIT; \112 vm |= DP_HIDDEN_BIT; \
arch/mips/math-emu/me-debugfs.c+1−1
@@ -65,4 +65,4 @@ do { \ · 64 unmodified lines
65 65
66 return 0;66 return 0;
67}67}
68__initcall(debugfs_fpuemu);68arch_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
17int 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
21union 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
121union 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
21union 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
121union 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
17union 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
17union 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
1276 case CPU_PROAPTIV:1276 case CPU_PROAPTIV:
1277 case CPU_M5150:1277 case CPU_M5150:
1278 case CPU_QEMU_GENERIC:1278 case CPU_QEMU_GENERIC:
1279 case CPU_I6400:
1279 if (!(read_c0_config7() & MIPS_CONF7_IAR) &&1280 if (!(read_c0_config7() & MIPS_CONF7_IAR) &&
1280 (c->icache.waysize > PAGE_SIZE))1281 (c->icache.waysize > PAGE_SIZE))
1281 c->icache.flags |= MIPS_CACHE_ALIASES;1282 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
194 __free_pages(page, get_order(size));194 __free_pages(page, get_order(size));
195}195}
196 196
197static 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
197static inline void __dma_sync_virtual(void *addr, size_t size,231static inline void __dma_sync_virtual(void *addr, size_t size,
198 enum dma_data_direction direction)232 enum dma_data_direction direction)
199{233{
@@ -380,6 +414,7 @@ EXPORT_SYMBOL(dma_cache_sync); · 180 unmodified lines
380static struct dma_map_ops mips_default_dma_map_ops = {414static struct dma_map_ops mips_default_dma_map_ops = {
381 .alloc = mips_dma_alloc_coherent,415 .alloc = mips_dma_alloc_coherent,
382 .free = mips_dma_free_coherent,416 .free = mips_dma_free_coherent,
417 .mmap = mips_dma_mmap,
383 .map_page = mips_dma_map_page,418 .map_page = mips_dma_map_page,
384 .unmap_page = mips_dma_unmap_page,419 .unmap_page = mips_dma_unmap_page,
385 .map_sg = mips_dma_map_sg,420 .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
57 57
58#ifdef CONFIG_KPROBES58#ifdef CONFIG_KPROBES
59 /*59 /*
60 * This is to notify the fault handler of the kprobes. The60 * This is to notify the fault handler of the kprobes.
61 * exception code is redundant as it is also carried in REGS,
62 * but we pass it anyhow.
63 */61 */
64 if (notify_die(DIE_PAGE_FAULT, "page fault", regs, -1,62 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)
66 return;64 return;
67#endif65#endif
68 66
@@ -224,6 +222,7 @@ bad_area_nosemaphore: · 155 unmodified lines
224 print_vma_addr(" ", regs->regs[31]);222 print_vma_addr(" ", regs->regs[31]);
225 pr_info("\n");223 pr_info("\n");
226 }224 }
225 current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
227 info.si_signo = SIGSEGV;226 info.si_signo = SIGSEGV;
228 info.si_errno = 0;227 info.si_errno = 0;
229 /* info.si_code has been set above */228 /* info.si_code has been set above */
@@ -282,6 +281,7 @@ do_sigbus: · 52 unmodified lines
282 field, (unsigned long) regs->cp0_epc,281 field, (unsigned long) regs->cp0_epc,
283 field, (unsigned long) regs->regs[31]);282 field, (unsigned long) regs->regs[31]);
284#endif283#endif
284 current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
285 tsk->thread.cp0_badvaddr = address;285 tsk->thread.cp0_badvaddr = address;
286 info.si_signo = SIGBUS;286 info.si_signo = SIGBUS;
287 info.si_errno = 0;287 info.si_errno = 0;
arch/mips/mm/init.c+34−2
@@ -37,6 +37,7 @@ · 36 unmodified lines
37#include <asm/cpu.h>37#include <asm/cpu.h>
38#include <asm/dma.h>38#include <asm/dma.h>
39#include <asm/kmap_types.h>39#include <asm/kmap_types.h>
40#include <asm/maar.h>
40#include <asm/mmu_context.h>41#include <asm/mmu_context.h>
41#include <asm/sections.h>42#include <asm/sections.h>
42#include <asm/pgtable.h>43#include <asm/pgtable.h>
@@ -333,9 +334,40 @@ static inline void mem_init_free_highmem(void) · 290 unmodified lines
333#endif334#endif
334}335}
335 336
336unsigned __weak platform_maar_init(unsigned num_maars)337unsigned __weak platform_maar_init(unsigned num_pairs)
337{338{
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;
339}371}
340 372
341static void maar_init(void)373static void maar_init(void)
arch/mips/mm/sc-mips.c+42−0
@@ -14,6 +14,7 @@ · 13 unmodified lines
14#include <asm/pgtable.h>14#include <asm/pgtable.h>
15#include <asm/mmu_context.h>15#include <asm/mmu_context.h>
16#include <asm/r4kcache.h>16#include <asm/r4kcache.h>
17#include <asm/mips-cm.h>
17 18
18/*19/*
19 * MIPS32/MIPS64 L2 cache handling20 * MIPS32/MIPS64 L2 cache handling
@@ -94,6 +95,38 @@ static inline int mips_sc_is_activated(struct cpuinfo_mips *c) · 74 unmodified lines
94 return 1;95 return 1;
95}96}
96 97
98static 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
126void __weak platform_early_l2_init(void)
127{
128}
129
97static inline int __init mips_sc_probe(void)130static inline int __init mips_sc_probe(void)
98{131{
99 struct cpuinfo_mips *c = &current_cpu_data;132 struct cpuinfo_mips *c = &current_cpu_data;
@@ -103,6 +136,15 @@ static inline int __init mips_sc_probe(void) · 3 unmodified lines
103 /* Mark as not present until probe completed */136 /* Mark as not present until probe completed */
104 c->scache.flags |= MIPS_CACHE_NOT_PRESENT;137 c->scache.flags |= MIPS_CACHE_NOT_PRESENT;
105 138
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
106 /* Ignore anything but MIPSxx processors */148 /* Ignore anything but MIPSxx processors */
107 if (!(c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 |149 if (!(c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 |
108 MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R1 |150 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
36 "nop\n\t" \36 "nop\n\t" \
37 ".set pop\n\t")37 ".set pop\n\t")
38 38
39static int r3k_have_wired_reg; /* Should be in cpu_data? */39int r3k_have_wired_reg; /* Should be in cpu_data? */
40 40
41/* TLB operations. */41/* TLB operations. */
42static void local_flush_tlb_from(int entry)42static 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
303 if (!register_vsmp_smp_ops())303 if (!register_vsmp_smp_ops())
304 return;304 return;
305}305}
306
307void 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
382 /* Could change CM error mask register. */382 /* Could change CM error mask register. */
383}383}
384 384
385
386static char *tr[8] = {
387 "mem", "gcr", "gic", "mmio",
388 "0x04", "0x05", "0x06", "0x07"
389};
390
391static 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
426static 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
433static 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
444int malta_be_handler(struct pt_regs *regs, int is_fixup)385int malta_be_handler(struct pt_regs *regs, int is_fixup)
445{386{
446 /* This duplicates the handling in do_be which seems wrong */387 /* This duplicates the handling in do_be which seems wrong */
447 int retval = is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL;388 int retval = is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL;
448 389
449 if (mips_cm_present()) {390 mips_cm_error_report();
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 }
501 391
502 return retval;392 return retval;
503}393}
arch/mips/mti-malta/malta-memory.c+0−25
@@ -179,31 +179,6 @@ void __init prom_free_prom_memory(void) · 178 unmodified lines
179 }179 }
180}180}
181 181
182unsigned 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
207phys_addr_t mips_cdmm_phys_base(void)182phys_addr_t mips_cdmm_phys_base(void)
208{183{
209 /* This address is "typically unused" */184 /* This address is "typically unused" */
arch/mips/netlogic/common/irq.c+6−6
@@ -87,7 +87,7 @@ struct nlm_pic_irq { · 86 unmodified lines
87static void xlp_pic_enable(struct irq_data *d)87static void xlp_pic_enable(struct irq_data *d)
88{88{
89 unsigned long flags;89 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);
91 91
92 BUG_ON(!pd);92 BUG_ON(!pd);
93 spin_lock_irqsave(&pd->node->piclock, flags);93 spin_lock_irqsave(&pd->node->piclock, flags);
@@ -97,7 +97,7 @@ static void xlp_pic_enable(struct irq_data *d) · 3 unmodified lines
97 97
98static void xlp_pic_disable(struct irq_data *d)98static void xlp_pic_disable(struct irq_data *d)
99{99{
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);
101 unsigned long flags;101 unsigned long flags;
102 102
103 BUG_ON(!pd);103 BUG_ON(!pd);
@@ -108,7 +108,7 @@ static void xlp_pic_disable(struct irq_data *d) · 4 unmodified lines
108 108
109static void xlp_pic_mask_ack(struct irq_data *d)109static void xlp_pic_mask_ack(struct irq_data *d)
110{110{
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);
112 112
113 clear_c0_eimr(pd->picirq);113 clear_c0_eimr(pd->picirq);
114 ack_c0_eirr(pd->picirq);114 ack_c0_eirr(pd->picirq);
@@ -116,7 +116,7 @@ static void xlp_pic_mask_ack(struct irq_data *d) · 1 unmodified line
116 116
117static void xlp_pic_unmask(struct irq_data *d)117static void xlp_pic_unmask(struct irq_data *d)
118{118{
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);
120 120
121 BUG_ON(!pd);121 BUG_ON(!pd);
122 122
@@ -193,7 +193,7 @@ void nlm_setup_pic_irq(int node, int picirq, int irq, int irt) · 70 unmodified lines
193 pic_data->picirq = picirq;193 pic_data->picirq = picirq;
194 pic_data->node = nlm_get_node(node);194 pic_data->node = nlm_get_node(node);
195 irq_set_chip_and_handler(xirq, &xlp_pic, handle_level_irq);195 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);
197}197}
198 198
199void nlm_set_pic_extra_ack(int node, int irq, void (*xack)(struct irq_data *))199void 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
202 int xirq;202 int xirq;
203 203
204 xirq = nlm_irq_to_xirq(node, irq);204 xirq = nlm_irq_to_xirq(node, irq);
205 pic_data = irq_get_handler_data(xirq);205 pic_data = irq_get_chip_data(xirq);
206 if (WARN_ON(!pic_data))206 if (WARN_ON(!pic_data))
207 return;207 return;
208 pic_data->extra_ack = xack;208 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
82}82}
83 83
84/* IRQ_IPI_SMP_FUNCTION Handler */84/* IRQ_IPI_SMP_FUNCTION Handler */
85void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc)85void nlm_smp_function_ipi_handler(unsigned int __irq, struct irq_desc *desc)
86{86{
87 unsigned int irq = irq_desc_get_irq(desc);
87 clear_c0_eimr(irq);88 clear_c0_eimr(irq);
88 ack_c0_eirr(irq);89 ack_c0_eirr(irq);
89 generic_smp_call_function_interrupt();90 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
91}92}
92 93
93/* IRQ_IPI_SMP_RESCHEDULE handler */94/* IRQ_IPI_SMP_RESCHEDULE handler */
94void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc)95void nlm_smp_resched_ipi_handler(unsigned int __irq, struct irq_desc *desc)
95{96{
97 unsigned int irq = irq_desc_get_irq(desc);
96 clear_c0_eimr(irq);98 clear_c0_eimr(irq);
97 ack_c0_eirr(irq);99 ack_c0_eirr(irq);
98 scheduler_ipi();100 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
152 0xC9, 0xC9, 0x07, 0x07, 0x18, 0x18, 0x01, 0x01, 0x22, 0x00152 0xC9, 0xC9, 0x07, 0x07, 0x18, 0x18, 0x01, 0x01, 0x22, 0x00
153};153};
154 154
155/* SATA PHY config for register block 2 0x0x8065 .. 0x0x80A4 */155/* SATA PHY config for register block 2 0x8065 .. 0x80A4 */
156static const u8 sata_phy_config2[] = {156static const u8 sata_phy_config2[] = {
157 0xAA, 0x00, 0x4C, 0xC9, 0xC9, 0x07, 0x07, 0x18,157 0xAA, 0x00, 0x4C, 0xC9, 0xC9, 0x07, 0x07, 0x18,
158 0x18, 0x05, 0x0C, 0x10, 0x00, 0x10, 0x00, 0xFF,158 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
91 return 134;91 return 134;
92 case PIC_SATA_IRQ:92 case PIC_SATA_IRQ:
93 return 143;93 return 143;
94 case PIC_NAND_IRQ:
95 return 151;
94 case PIC_SPI_IRQ:96 case PIC_SPI_IRQ:
95 return 152;97 return 152;
96 case PIC_MMC_IRQ:98 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
91 case CPU_INTERAPTIV:91 case CPU_INTERAPTIV:
92 case CPU_PROAPTIV:92 case CPU_PROAPTIV:
93 case CPU_P5600:93 case CPU_P5600:
94 case CPU_I6400:
94 case CPU_M5150:95 case CPU_M5150:
95 case CPU_LOONGSON1:96 case CPU_LOONGSON1:
96 case CPU_SB1:97 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
392 op_model_mipsxx_ops.cpu_type = "mips/P5600";392 op_model_mipsxx_ops.cpu_type = "mips/P5600";
393 break;393 break;
394 394
395 case CPU_I6400:
396 op_model_mipsxx_ops.cpu_type = "mips/I6400";
397 break;
398
395 case CPU_M5150:399 case CPU_M5150:
396 op_model_mipsxx_ops.cpu_type = "mips/M5150";400 op_model_mipsxx_ops.cpu_type = "mips/M5150";
397 break;401 break;
arch/mips/pci/msi-xlp.c+10−10
@@ -131,7 +131,7 @@ struct xlp_msi_data { · 130 unmodified lines
131 */131 */
132static void xlp_msi_enable(struct irq_data *d)132static void xlp_msi_enable(struct irq_data *d)
133{133{
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);
135 unsigned long flags;135 unsigned long flags;
136 int vec;136 int vec;
137 137
@@ -148,7 +148,7 @@ static void xlp_msi_enable(struct irq_data *d) · 10 unmodified lines
148 148
149static void xlp_msi_disable(struct irq_data *d)149static void xlp_msi_disable(struct irq_data *d)
150{150{
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);
152 unsigned long flags;152 unsigned long flags;
153 int vec;153 int vec;
154 154
@@ -165,7 +165,7 @@ static void xlp_msi_disable(struct irq_data *d) · 10 unmodified lines
165 165
166static void xlp_msi_mask_ack(struct irq_data *d)166static void xlp_msi_mask_ack(struct irq_data *d)
167{167{
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);
169 int link, vec;169 int link, vec;
170 170
171 link = nlm_irq_msilink(d->irq);171 link = nlm_irq_msilink(d->irq);
@@ -211,7 +211,7 @@ static void xlp_msix_mask_ack(struct irq_data *d) · 39 unmodified lines
211 msixvec = nlm_irq_msixvec(d->irq);211 msixvec = nlm_irq_msixvec(d->irq);
212 link = nlm_irq_msixlink(msixvec);212 link = nlm_irq_msixlink(msixvec);
213 pci_msi_mask_irq(d);213 pci_msi_mask_irq(d);
214 md = irq_data_get_irq_handler_data(d);214 md = irq_data_get_irq_chip_data(d);
215 215
216 /* Ack MSI on bridge */216 /* Ack MSI on bridge */
217 if (cpu_is_xlp9xx()) {217 if (cpu_is_xlp9xx()) {
@@ -302,7 +302,7 @@ static int xlp_setup_msi(uint64_t lnkbase, int node, int link, · 84 unmodified lines
302 /* Get MSI data for the link */302 /* Get MSI data for the link */
303 lirq = PIC_PCIE_LINK_MSI_IRQ(link);303 lirq = PIC_PCIE_LINK_MSI_IRQ(link);
304 xirq = nlm_irq_to_xirq(node, nlm_link_msiirq(link, 0));304 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);
306 msiaddr = MSI_LINK_ADDR(node, link);306 msiaddr = MSI_LINK_ADDR(node, link);
307 307
308 spin_lock_irqsave(&md->msi_lock, flags);308 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
409 /* Get MSI data for the link */409 /* Get MSI data for the link */
410 lirq = PIC_PCIE_MSIX_IRQ(link);410 lirq = PIC_PCIE_MSIX_IRQ(link);
411 xirq = nlm_irq_to_xirq(node, nlm_link_msixirq(link, 0));411 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);
413 msixaddr = MSIX_LINK_ADDR(node, link);413 msixaddr = MSIX_LINK_ADDR(node, link);
414 414
415 spin_lock_irqsave(&md->msi_lock, flags);415 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
485 irq = nlm_irq_to_xirq(node, nlm_link_msiirq(link, 0));485 irq = nlm_irq_to_xirq(node, nlm_link_msiirq(link, 0));
486 for (i = irq; i < irq + XLP_MSIVEC_PER_LINK; i++) {486 for (i = irq; i < irq + XLP_MSIVEC_PER_LINK; i++) {
487 irq_set_chip_and_handler(i, &xlp_msi_chip, handle_level_irq);487 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);
489 }489 }
490 490
491 for (i = 0; i < XLP_MSIXVEC_PER_LINK ; i++) {491 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
508 /* Initialize MSI-X extended irq space for the link */508 /* Initialize MSI-X extended irq space for the link */
509 irq = nlm_irq_to_xirq(node, nlm_link_msixirq(link, i));509 irq = nlm_irq_to_xirq(node, nlm_link_msixirq(link, i));
510 irq_set_chip_and_handler(irq, &xlp_msix_chip, handle_level_irq);510 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);
512 }512 }
513}513}
514 514
@@ -520,7 +520,7 @@ void nlm_dispatch_msi(int node, int lirq) · 5 unmodified lines
520 520
521 link = lirq - PIC_PCIE_LINK_MSI_IRQ_BASE;521 link = lirq - PIC_PCIE_LINK_MSI_IRQ_BASE;
522 irqbase = nlm_irq_to_xirq(node, nlm_link_msiirq(link, 0));522 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);
524 if (cpu_is_xlp9xx())524 if (cpu_is_xlp9xx())
525 status = nlm_read_reg(md->lnkbase, PCIE_9XX_MSI_STATUS) &525 status = nlm_read_reg(md->lnkbase, PCIE_9XX_MSI_STATUS) &
526 md->msi_enabled_mask;526 md->msi_enabled_mask;
@@ -550,7 +550,7 @@ void nlm_dispatch_msix(int node, int lirq) · 23 unmodified lines
550 550
551 link = lirq - PIC_PCIE_MSIX_IRQ_BASE;551 link = lirq - PIC_PCIE_MSIX_IRQ_BASE;
552 irqbase = nlm_irq_to_xirq(node, nlm_link_msixirq(link, 0));552 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);
554 if (cpu_is_xlp9xx())554 if (cpu_is_xlp9xx())
555 status = nlm_read_reg(md->lnkbase, PCIE_9XX_MSIX_STATUSX(link));555 status = nlm_read_reg(md->lnkbase, PCIE_9XX_MSIX_STATUSX(link));
556 else556 else
arch/mips/pci/ops-emma2rh.c+2−4
@@ -25,7 +25,6 @@ · 24 unmodified lines
25#include <linux/types.h>25#include <linux/types.h>
26 26
27#include <asm/addrspace.h>27#include <asm/addrspace.h>
28#include <asm/debug.h>
29 28
30#include <asm/emma/emma2rh.h>29#include <asm/emma/emma2rh.h>
31 30
@@ -40,10 +39,9 @@ · 8 unmodified lines
40static int check_args(struct pci_bus *bus, u32 devfn, u32 * bus_num)39static int check_args(struct pci_bus *bus, u32 devfn, u32 * bus_num)
41{40{
42 /* check if the bus is top-level */41 /* check if the bus is top-level */
43 if (bus->parent != NULL) {42 if (bus->parent != NULL)
44 *bus_num = bus->number;43 *bus_num = bus->number;
45 db_assert(bus_num != NULL);44 else
46 } else
47 *bus_num = 0;45 *bus_num = 0;
48 46
49 if (*bus_num == 0) {47 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
312 irq_set_chip_data(i, apc);312 irq_set_chip_data(i, apc);
313 }313 }
314 314
315 irq_set_handler_data(apc->irq, apc);315 irq_set_chained_handler_and_data(apc->irq, ar71xx_pci_irq_handler,
316 irq_set_chained_handler(apc->irq, ar71xx_pci_irq_handler);316 apc);
317}317}
318 318
319static void ar71xx_pci_reset(void)319static 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
321 irq_set_chip_data(i, apc);321 irq_set_chip_data(i, apc);
322 }322 }
323 323
324 irq_set_handler_data(apc->irq, apc);324 irq_set_chained_handler_and_data(apc->irq, ar724x_pci_irq_handler,
325 irq_set_chained_handler(apc->irq, ar724x_pci_irq_handler);325 apc);
326}326}
327 327
328static int ar724x_pci_probe(struct platform_device *pdev)328static int ar724x_pci_probe(struct platform_device *pdev)
arch/mips/pci/pci-lantiq.c+0−1
@@ -20,7 +20,6 @@ · 19 unmodified lines
20#include <linux/of_irq.h>20#include <linux/of_irq.h>
21#include <linux/of_pci.h>21#include <linux/of_pci.h>
22 22
23#include <asm/gpio.h>
24#include <asm/addrspace.h>23#include <asm/addrspace.h>
25 24
26#include <lantiq_soc.h>25#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
129 rt3883_pci_w32(rpc, val, RT3883_PCI_REG_CFGDATA);129 rt3883_pci_w32(rpc, val, RT3883_PCI_REG_CFGDATA);
130}130}
131 131
132static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc)132static void rt3883_pci_irq_handler(unsigned int __irq, struct irq_desc *desc)
133{133{
134 struct rt3883_pci_controller *rpc;134 struct rt3883_pci_controller *rpc;
135 u32 pending;135 u32 pending;
@@ -145,7 +145,7 @@ static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc) · 9 unmodified lines
145 }145 }
146 146
147 while (pending) {147 while (pending) {
148 unsigned bit = __ffs(pending);148 unsigned irq, bit = __ffs(pending);
149 149
150 irq = irq_find_mapping(rpc->irq_domain, bit);150 irq = irq_find_mapping(rpc->irq_domain, bit);
151 generic_handle_irq(irq);151 generic_handle_irq(irq);
@@ -225,8 +225,7 @@ static int rt3883_pci_irq_init(struct device *dev, · 73 unmodified lines
225 return -ENODEV;225 return -ENODEV;
226 }226 }
227 227
228 irq_set_handler_data(irq, rpc);228 irq_set_chained_handler_and_data(irq, rt3883_pci_irq_handler, rpc);
229 irq_set_chained_handler(irq, rt3883_pci_irq_handler);
230 229
231 return 0;230 return 0;
232}231}
arch/mips/pistachio/Kconfig+13−0
@@ -0,0 +1,13 @@
1config 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
88 * Make sure we have IRQ affinity. It may have changed while88 * Make sure we have IRQ affinity. It may have changed while
89 * we were processing the IRQ.89 * we were processing the IRQ.
90 */90 */
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)))
92 return;93 return;
93#endif94#endif
94 95
arch/mips/ralink/cevt-rt3352.c+30−29
@@ -36,8 +36,8 @@ struct systick_device { · 35 unmodified lines
36 int freq_scale;36 int freq_scale;
37};37};
38 38
39static void systick_set_clock_mode(enum clock_event_mode mode,39static int systick_set_oneshot(struct clock_event_device *evt);
40 struct clock_event_device *evt);40static int systick_shutdown(struct clock_event_device *evt);
41 41
42static int systick_next_event(unsigned long delta,42static int systick_next_event(unsigned long delta,
43 struct clock_event_device *evt)43 struct clock_event_device *evt)
@@ -73,11 +73,12 @@ static struct systick_device systick = { · 29 unmodified lines
73 * cevt-r4k uses 300, make sure systick73 * cevt-r4k uses 300, make sure systick
74 * gets used if available74 * gets used if available
75 */75 */
76 .rating = 310,76 .rating = 310,
77 .features = CLOCK_EVT_FEAT_ONESHOT,77 .features = CLOCK_EVT_FEAT_ONESHOT,
78 .set_next_event = systick_next_event,78 .set_next_event = systick_next_event,
79 .set_mode = systick_set_clock_mode,79 .set_state_shutdown = systick_shutdown,
80 .event_handler = systick_event_handler,80 .set_state_oneshot = systick_set_oneshot,
81 .event_handler = systick_event_handler,
81 },82 },
82};83};
83 84
@@ -87,33 +88,33 @@ static struct irqaction systick_irqaction = { · 3 unmodified lines
87 .dev_id = &systick.dev,88 .dev_id = &systick.dev,
88};89};
89 90
90static void systick_set_clock_mode(enum clock_event_mode mode,91static int systick_shutdown(struct clock_event_device *evt)
91 struct clock_event_device *evt)
92{92{
93 struct systick_device *sdev;93 struct systick_device *sdev;
94 94
95 sdev = container_of(evt, struct systick_device, dev);95 sdev = container_of(evt, struct systick_device, dev);
96 96
97 switch (mode) {97 if (sdev->irq_requested)
98 case CLOCK_EVT_MODE_ONESHOT:98 free_irq(systick.dev.irq, &systick_irqaction);
99 if (!sdev->irq_requested)99 sdev->irq_requested = 0;
100 setup_irq(systick.dev.irq, &systick_irqaction);100 iowrite32(0, systick.membase + SYSTICK_CONFIG);
101 sdev->irq_requested = 1;101
102 iowrite32(CFG_EXT_STK_EN | CFG_CNT_EN,102 return 0;
103 systick.membase + SYSTICK_CONFIG);103}
104 break;104
105 105static int systick_set_oneshot(struct clock_event_device *evt)
106 case CLOCK_EVT_MODE_SHUTDOWN:106{
107 if (sdev->irq_requested)107 struct systick_device *sdev;
108 free_irq(systick.dev.irq, &systick_irqaction);108
109 sdev->irq_requested = 0;109 sdev = container_of(evt, struct systick_device, dev);
110 iowrite32(0, systick.membase + SYSTICK_CONFIG);110
111 break;111 if (!sdev->irq_requested)
112 112 setup_irq(systick.dev.irq, &systick_irqaction);
113 default:113 sdev->irq_requested = 1;
114 pr_err("%s: Unhandeled mips clock_mode\n", systick.dev.name);114 iowrite32(CFG_EXT_STK_EN | CFG_CNT_EN,
115 break;115 systick.membase + SYSTICK_CONFIG);
116 }116
117 return 0;
117}118}
118 119
119static void __init ralink_systick_init(struct device_node *np)120static void __init ralink_systick_init(struct device_node *np)
arch/mips/rb532/devices.c+1−0
@@ -23,6 +23,7 @@ · 22 unmodified lines
23#include <linux/mtd/nand.h>23#include <linux/mtd/nand.h>
24#include <linux/mtd/mtd.h>24#include <linux/mtd/mtd.h>
25#include <linux/mtd/partitions.h>25#include <linux/mtd/partitions.h>
26#include <linux/gpio.h>
26#include <linux/gpio_keys.h>27#include <linux/gpio_keys.h>
27#include <linux/input.h>28#include <linux/input.h>
28#include <linux/serial_8250.h>29#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
140 return 0;140 return 0;
141}141}
142 142
143static int rb532_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
144{
145 return 8 + 4 * 32 + gpio;
146}
147
143static struct rb532_gpio_chip rb532_gpio_chip[] = {148static struct rb532_gpio_chip rb532_gpio_chip[] = {
144 [0] = {149 [0] = {
145 .chip = {150 .chip = {
@@ -148,6 +153,7 @@ static struct rb532_gpio_chip rb532_gpio_chip[] = { · 2 unmodified lines
148 .direction_output = rb532_gpio_direction_output,153 .direction_output = rb532_gpio_direction_output,
149 .get = rb532_gpio_get,154 .get = rb532_gpio_get,
150 .set = rb532_gpio_set,155 .set = rb532_gpio_set,
156 .to_irq = rb532_gpio_to_irq,
151 .base = 0,157 .base = 0,
152 .ngpio = 32,158 .ngpio = 32,
153 },159 },
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
64 return LOCAL_HUB_L(PI_RT_COUNT) >= cnt ? -ETIME : 0;64 return LOCAL_HUB_L(PI_RT_COUNT) >= cnt ? -ETIME : 0;
65}65}
66 66
67static void rt_set_mode(enum clock_event_mode mode,
68 struct clock_event_device *evt)
69{
70 /* Nothing to do ... */
71}
72
73unsigned int rt_timer_irq;67unsigned int rt_timer_irq;
74 68
75static DEFINE_PER_CPU(struct clock_event_device, hub_rt_clockevent);69static DEFINE_PER_CPU(struct clock_event_device, hub_rt_clockevent);
@@ -124,7 +118,6 @@ void hub_rt_clock_event_init(void) · 48 unmodified lines
124 cd->irq = irq;118 cd->irq = irq;
125 cd->cpumask = cpumask_of(cpu);119 cd->cpumask = cpumask_of(cpu);
126 cd->set_next_event = rt_next_event;120 cd->set_next_event = rt_next_event;
127 cd->set_mode = rt_set_mode;
128 clockevents_register_device(cd);121 clockevents_register_device(cd);
129}122}
130 123
arch/mips/sibyte/common/bus_watcher.c+1−1
@@ -250,4 +250,4 @@ int __init sibyte_bus_watcher(void) · 249 unmodified lines
250 return 0;250 return 0;
251}251}
252 252
253__initcall(sibyte_bus_watcher);253device_initcall(sibyte_bus_watcher);
arch/mips/sni/time.c+19−30
@@ -14,44 +14,33 @@ · 13 unmodified lines
14#define SNI_COUNTER2_DIV 6414#define SNI_COUNTER2_DIV 64
15#define SNI_COUNTER0_DIV ((SNI_CLOCK_TICK_RATE / SNI_COUNTER2_DIV) / HZ)15#define SNI_COUNTER0_DIV ((SNI_CLOCK_TICK_RATE / SNI_COUNTER2_DIV) / HZ)
16 16
17static void a20r_set_mode(enum clock_event_mode mode,17static int a20r_set_periodic(struct clock_event_device *evt)
18 struct clock_event_device *evt)
19{18{
20 switch (mode) {19 *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0x34;
21 case CLOCK_EVT_MODE_PERIODIC:20 wmb();
22 *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0x34;21 *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV;
23 wmb();22 wmb();
24 *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV;23 *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = SNI_COUNTER0_DIV >> 8;
25 wmb();24 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();
35 25
36 break;26 *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0xb4;
37 case CLOCK_EVT_MODE_ONESHOT:27 wmb();
38 case CLOCK_EVT_MODE_UNUSED:28 *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV;
39 case CLOCK_EVT_MODE_SHUTDOWN:29 wmb();
40 break;30 *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = SNI_COUNTER2_DIV >> 8;
41 case CLOCK_EVT_MODE_RESUME:31 wmb();
42 break;32 return 0;
43 }
44}33}
45 34
46static struct clock_event_device a20r_clockevent_device = {35static struct clock_event_device a20r_clockevent_device = {
47 .name = "a20r-timer",36 .name = "a20r-timer",
48 .features = CLOCK_EVT_FEAT_PERIODIC,37 .features = CLOCK_EVT_FEAT_PERIODIC,
49 38
50 /* .mult, .shift, .max_delta_ns and .min_delta_ns left uninitialized */39 /* .mult, .shift, .max_delta_ns and .min_delta_ns left uninitialized */
51 40
52 .rating = 300,41 .rating = 300,
53 .irq = SNI_A20R_IRQ_TIMER,42 .irq = SNI_A20R_IRQ_TIMER,
54 .set_mode = a20r_set_mode,43 .set_state_periodic = a20r_set_periodic,
55};44};
56 45
57static irqreturn_t a20r_interrupt(int irq, void *dev_id)46static 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
117}117}
118EXPORT_SYMBOL(clk_put);118EXPORT_SYMBOL(clk_put);
119 119
120/* GPIO support */
121
122#ifdef CONFIG_GPIOLIB
123int gpio_to_irq(unsigned gpio)
124{
125 return -EINVAL;
126}
127EXPORT_SYMBOL(gpio_to_irq);
128
129int irq_to_gpio(unsigned irq)
130{
131 return -EINVAL;
132}
133EXPORT_SYMBOL(irq_to_gpio);
134#endif
135
136#define BOARD_VEC(board) extern struct txx9_board_vec board;120#define BOARD_VEC(board) extern struct txx9_board_vec board;
137#include <asm/txx9/boards.h>121#include <asm/txx9/boards.h>
138#undef BOARD_VEC122#undef BOARD_VEC
drivers/ata/pata_rb532_cf.c+1−2
@@ -27,12 +27,11 @@ · 26 unmodified lines
27#include <linux/io.h>27#include <linux/io.h>
28#include <linux/interrupt.h>28#include <linux/interrupt.h>
29#include <linux/irq.h>29#include <linux/irq.h>
30#include <linux/gpio.h>
30 31
31#include <linux/libata.h>32#include <linux/libata.h>
32#include <scsi/scsi_host.h>33#include <scsi/scsi_host.h>
33 34
34#include <asm/gpio.h>
35
36#define DRV_NAME "pata-rb532-cf"35#define DRV_NAME "pata-rb532-cf"
37#define DRV_VERSION "0.1.0"36#define DRV_VERSION "0.1.0"
38#define DRV_DESC "PATA driver for RouterBOARD 532 Compact Flash"37#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
331 << MIPS_CDMMBASE_ADDR_START;331 << MIPS_CDMMBASE_ADDR_START;
332}332}
333 333
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 */
341phys_addr_t __weak mips_cdmm_phys_base(void)
342{
343 return 0;
344}
345
334/**346/**
335 * mips_cdmm_setup() - Ensure the CDMM bus is initialised and usable.347 * mips_cdmm_setup() - Ensure the CDMM bus is initialised and usable.
336 * @bus: Pointer to bus information for current CPU.348 * @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
368 if (!bus->phys)380 if (!bus->phys)
369 bus->phys = mips_cdmm_cur_base();381 bus->phys = mips_cdmm_cur_base();
370 /* Otherwise, ask platform code for suggestions */382 /* Otherwise, ask platform code for suggestions */
371 if (!bus->phys && mips_cdmm_phys_base)383 if (!bus->phys)
372 bus->phys = mips_cdmm_phys_base();384 bus->phys = mips_cdmm_phys_base();
373 /* Otherwise, copy what other CPUs have done */385 /* Otherwise, copy what other CPUs have done */
374 if (!bus->phys)386 if (!bus->phys)
drivers/clocksource/Kconfig+4−0
@@ -111,6 +111,10 @@ config CLKSRC_LPC32XX · 110 unmodified lines
111 select CLKSRC_MMIO111 select CLKSRC_MMIO
112 select CLKSRC_OF112 select CLKSRC_OF
113 113
114config CLKSRC_PISTACHIO
115 bool
116 select CLKSRC_OF
117
114config CLKSRC_STM32118config CLKSRC_STM32
115 bool "Clocksource for STM32 SoCs" if !ARCH_STM32119 bool "Clocksource for STM32 SoCs" if !ARCH_STM32
116 depends on OF && ARM && (ARCH_STM32 || COMPILE_TEST)120 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
44obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o44obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o
45obj-$(CONFIG_CLKSRC_QCOM) += qcom-timer.o45obj-$(CONFIG_CLKSRC_QCOM) += qcom-timer.o
46obj-$(CONFIG_MTK_TIMER) += mtk_timer.o46obj-$(CONFIG_MTK_TIMER) += mtk_timer.o
47obj-$(CONFIG_CLKSRC_PISTACHIO) += time-pistachio.o
47 48
48obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o49obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
49obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o50obj-$(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
72 disable_percpu_irq(gic_timer_irq);72 disable_percpu_irq(gic_timer_irq);
73}73}
74 74
75static 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
75static int gic_cpu_notifier(struct notifier_block *nb, unsigned long action,82static int gic_cpu_notifier(struct notifier_block *nb, unsigned long action,
76 void *data)83 void *data)
77{84{
@@ -87,18 +94,40 @@ static int gic_cpu_notifier(struct notifier_block *nb, unsigned long action, · 9 unmodified lines
87 return NOTIFY_OK;94 return NOTIFY_OK;
88}95}
89 96
97static 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
90static struct notifier_block gic_cpu_nb = {109static struct notifier_block gic_cpu_nb = {
91 .notifier_call = gic_cpu_notifier,110 .notifier_call = gic_cpu_notifier,
92};111};
93 112
113static struct notifier_block gic_clk_nb = {
114 .notifier_call = gic_clk_notifier,
115};
116
94static int gic_clockevent_init(void)117static int gic_clockevent_init(void)
95{118{
119 int ret;
120
96 if (!cpu_has_counter || !gic_frequency)121 if (!cpu_has_counter || !gic_frequency)
97 return -ENXIO;122 return -ENXIO;
98 123
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;
100 127
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");
102 131
103 gic_clockevent_cpu_init(this_cpu_ptr(&gic_clockevent_device));132 gic_clockevent_cpu_init(this_cpu_ptr(&gic_clockevent_device));
104 133
@@ -118,18 +147,17 @@ static struct clocksource gic_clocksource = { · 13 unmodified lines
118 147
119static void __init __gic_clocksource_init(void)148static void __init __gic_clocksource_init(void)
120{149{
150 int ret;
151
121 /* Set clocksource mask. */152 /* Set clocksource mask. */
122 gic_clocksource.mask = CLOCKSOURCE_MASK(gic_get_count_width());153 gic_clocksource.mask = CLOCKSOURCE_MASK(gic_get_count_width());
123 154
124 /* Calculate a somewhat reasonable rating value. */155 /* Calculate a somewhat reasonable rating value. */
125 gic_clocksource.rating = 200 + gic_frequency / 10000000;156 gic_clocksource.rating = 200 + gic_frequency / 10000000;
126 157
127 clocksource_register_hz(&gic_clocksource, gic_frequency);158 ret = clocksource_register_hz(&gic_clocksource, gic_frequency);
128 159 if (ret < 0)
129 gic_clockevent_init();160 pr_warn("GIC: Unable to register clocksource\n");
130
131 /* And finally start the counter */
132 gic_start_count();
133}161}
134 162
135void __init gic_clocksource_init(unsigned int frequency)163void __init gic_clocksource_init(unsigned int frequency)
@@ -139,11 +167,16 @@ void __init gic_clocksource_init(unsigned int frequency) · 3 unmodified lines
139 GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE);167 GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE);
140 168
141 __gic_clocksource_init();169 __gic_clocksource_init();
170 gic_clockevent_init();
171
172 /* And finally start the counter */
173 gic_start_count();
142}174}
143 175
144static void __init gic_clocksource_of_init(struct device_node *node)176static void __init gic_clocksource_of_init(struct device_node *node)
145{177{
146 struct clk *clk;178 struct clk *clk;
179 int ret;
147 180
148 if (WARN_ON(!gic_present || !node->parent ||181 if (WARN_ON(!gic_present || !node->parent ||
149 !of_device_is_compatible(node->parent, "mti,gic")))182 !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
151 184
152 clk = of_clk_get(node, 0);185 clk = of_clk_get(node, 0);
153 if (!IS_ERR(clk)) {186 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
154 gic_frequency = clk_get_rate(clk);193 gic_frequency = clk_get_rate(clk);
155 clk_put(clk);
156 } else if (of_property_read_u32(node, "clock-frequency",194 } else if (of_property_read_u32(node, "clock-frequency",
157 &gic_frequency)) {195 &gic_frequency)) {
158 pr_err("GIC frequency not specified.\n");196 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
165 }203 }
166 204
167 __gic_clocksource_init();205 __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();
168}215}
169CLOCKSOURCE_OF_DECLARE(mips_gic_timer, "mti,gic-timer",216CLOCKSOURCE_OF_DECLARE(mips_gic_timer, "mti,gic-timer",
170 gic_clocksource_of_init);217 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
48struct pistachio_clocksource {
49 void __iomem *base;
50 raw_spinlock_t lock;
51 struct clocksource cs;
52};
53
54static struct pistachio_clocksource pcs_gpt;
55
56#define to_pistachio_clocksource(cs) \
57 container_of(cs, struct pistachio_clocksource, cs)
58
59static inline u32 gpt_readl(void __iomem *base, u32 offset, u32 gpt_id)
60{
61 return readl(base + 0x20 * gpt_id + offset);
62}
63
64static 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
70static 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
89static u64 notrace pistachio_read_sched_clock(void)
90{
91 return pistachio_clocksource_read_cycles(&pcs_gpt.cs);
92}
93
94static 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
109static 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
119static void pistachio_clksrc_disable(struct clocksource *cs, int timeridx)
120{
121 /* Disable GPT local */
122 pistachio_clksrc_set_mode(cs, timeridx, false);
123}
124
125static int pistachio_clocksource_enable(struct clocksource *cs)
126{
127 pistachio_clksrc_enable(cs, 0);
128 return 0;
129}
130
131static void pistachio_clocksource_disable(struct clocksource *cs)
132{
133 pistachio_clksrc_disable(cs, 0);
134}
135
136/* Desirable clock source for pistachio platform */
137static 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
150static 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}
216CLOCKSOURCE_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
20obj-$(CONFIG_GPIO_ALTERA) += gpio-altera.o20obj-$(CONFIG_GPIO_ALTERA) += gpio-altera.o
21obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o21obj-$(CONFIG_GPIO_AMD8111) += gpio-amd8111.o
22obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o22obj-$(CONFIG_GPIO_ARIZONA) += gpio-arizona.o
23obj-$(CONFIG_ATH79) += gpio-ath79.o
23obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o24obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o
24obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o25obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o
25obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o26obj-$(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
24#include <linux/of_device.h>24#include <linux/of_device.h>
25 25
26#include <asm/mach-ath79/ar71xx_regs.h>26#include <asm/mach-ath79/ar71xx_regs.h>
27#include <asm/mach-ath79/ath79.h>
28#include "common.h"
29 27
30static void __iomem *ath79_gpio_base;28static void __iomem *ath79_gpio_base;
31static u32 ath79_gpio_count;29static u32 ath79_gpio_count;
@@ -139,47 +137,6 @@ static struct gpio_chip ath79_gpio_chip = { · 107 unmodified lines
139 .base = 0,137 .base = 0,
140};138};
141 139
142static 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
159void 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
173void ath79_gpio_function_enable(u32 mask)
174{
175 ath79_gpio_function_setup(mask, 0);
176}
177
178void ath79_gpio_function_disable(u32 mask)
179{
180 ath79_gpio_function_setup(0, mask);
181}
182
183static const struct of_device_id ath79_gpio_of_match[] = {140static const struct of_device_id ath79_gpio_of_match[] = {
184 { .compatible = "qca,ar7100-gpio" },141 { .compatible = "qca,ar7100-gpio" },
185 { .compatible = "qca,ar9340-gpio" },142 { .compatible = "qca,ar9340-gpio" },
@@ -245,35 +202,3 @@ static struct platform_driver ath79_gpio_driver = { · 59 unmodified lines
245};202};
246 203
247module_platform_driver(ath79_gpio_driver);204module_platform_driver(ath79_gpio_driver);
248
249int 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}
256EXPORT_SYMBOL(gpio_get_value);
257
258void 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}
265EXPORT_SYMBOL(gpio_set_value);
266
267int gpio_to_irq(unsigned gpio)
268{
269 /* FIXME */
270 return -EINVAL;
271}
272EXPORT_SYMBOL(gpio_to_irq);
273
274int irq_to_gpio(unsigned irq)
275{
276 /* FIXME */
277 return -EINVAL;
278}
279EXPORT_SYMBOL(irq_to_gpio);
drivers/input/misc/rb532_button.c+1−0
@@ -7,6 +7,7 @@ · 6 unmodified lines
7#include <linux/input-polldev.h>7#include <linux/input-polldev.h>
8#include <linux/module.h>8#include <linux/module.h>
9#include <linux/platform_device.h>9#include <linux/platform_device.h>
10#include <linux/gpio.h>
10 11
11#include <asm/mach-rc32434/gpio.h>12#include <asm/mach-rc32434/gpio.h>
12#include <asm/mach-rc32434/rb.h>13#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
41 41
42static void __gic_irq_dispatch(void);42static void __gic_irq_dispatch(void);
43 43
44static inline unsigned int gic_read(unsigned int reg)44static inline u32 gic_read32(unsigned int reg)
45{45{
46 return __raw_readl(gic_base + reg);46 return __raw_readl(gic_base + reg);
47}47}
48 48
49static inline void gic_write(unsigned int reg, unsigned int val)49static inline u64 gic_read64(unsigned int reg)
50{50{
51 __raw_writel(val, gic_base + reg);51 return __raw_readq(gic_base + reg);
52}52}
53 53
54static inline void gic_update_bits(unsigned int reg, unsigned int mask,54static inline unsigned long gic_read(unsigned int reg)
55 unsigned int val)
56{55{
57 unsigned int regval;56 if (!mips_cm_is64)
57 return gic_read32(reg);
58 else
59 return gic_read64(reg);
60}
61
62static inline void gic_write32(unsigned int reg, u32 val)
63{
64 return __raw_writel(val, gic_base + reg);
65}
66
67static inline void gic_write64(unsigned int reg, u64 val)
68{
69 return __raw_writeq(val, gic_base + reg);
70}
71
72static 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
80static inline void gic_update_bits(unsigned int reg, unsigned long mask,
81 unsigned long val)
82{
83 unsigned long regval;
58 84
59 regval = gic_read(reg);85 regval = gic_read(reg);
60 regval &= ~mask;86 regval &= ~mask;
@@ -65,40 +91,40 @@ static inline void gic_update_bits(unsigned int reg, unsigned int mask, · 4 unmodified lines
65static inline void gic_reset_mask(unsigned int intr)91static inline void gic_reset_mask(unsigned int intr)
66{92{
67 gic_write(GIC_REG(SHARED, GIC_SH_RMASK) + GIC_INTR_OFS(intr),93 gic_write(GIC_REG(SHARED, GIC_SH_RMASK) + GIC_INTR_OFS(intr),
68 1 << GIC_INTR_BIT(intr));94 1ul << GIC_INTR_BIT(intr));
69}95}
70 96
71static inline void gic_set_mask(unsigned int intr)97static inline void gic_set_mask(unsigned int intr)
72{98{
73 gic_write(GIC_REG(SHARED, GIC_SH_SMASK) + GIC_INTR_OFS(intr),99 gic_write(GIC_REG(SHARED, GIC_SH_SMASK) + GIC_INTR_OFS(intr),
74 1 << GIC_INTR_BIT(intr));100 1ul << GIC_INTR_BIT(intr));
75}101}
76 102
77static inline void gic_set_polarity(unsigned int intr, unsigned int pol)103static inline void gic_set_polarity(unsigned int intr, unsigned int pol)
78{104{
79 gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_POLARITY) +105 gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_POLARITY) +
80 GIC_INTR_OFS(intr), 1 << GIC_INTR_BIT(intr),106 GIC_INTR_OFS(intr), 1ul << GIC_INTR_BIT(intr),
81 pol << GIC_INTR_BIT(intr));107 (unsigned long)pol << GIC_INTR_BIT(intr));
82}108}
83 109
84static inline void gic_set_trigger(unsigned int intr, unsigned int trig)110static inline void gic_set_trigger(unsigned int intr, unsigned int trig)
85{111{
86 gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_TRIGGER) +112 gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_TRIGGER) +
87 GIC_INTR_OFS(intr), 1 << GIC_INTR_BIT(intr),113 GIC_INTR_OFS(intr), 1ul << GIC_INTR_BIT(intr),
88 trig << GIC_INTR_BIT(intr));114 (unsigned long)trig << GIC_INTR_BIT(intr));
89}115}
90 116
91static inline void gic_set_dual_edge(unsigned int intr, unsigned int dual)117static inline void gic_set_dual_edge(unsigned int intr, unsigned int dual)
92{118{
93 gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_DUAL) + GIC_INTR_OFS(intr),119 gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_DUAL) + GIC_INTR_OFS(intr),
94 1 << GIC_INTR_BIT(intr),120 1ul << GIC_INTR_BIT(intr),
95 dual << GIC_INTR_BIT(intr));121 (unsigned long)dual << GIC_INTR_BIT(intr));
96}122}
97 123
98static inline void gic_map_to_pin(unsigned int intr, unsigned int pin)124static inline void gic_map_to_pin(unsigned int intr, unsigned int pin)
99{125{
100 gic_write(GIC_REG(SHARED, GIC_SH_INTR_MAP_TO_PIN_BASE) +126 gic_write32(GIC_REG(SHARED, GIC_SH_INTR_MAP_TO_PIN_BASE) +
101 GIC_SH_MAP_TO_PIN(intr), GIC_MAP_TO_PIN_MSK | pin);127 GIC_SH_MAP_TO_PIN(intr), GIC_MAP_TO_PIN_MSK | pin);
102}128}
103 129
104static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe)130static 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
113{139{
114 unsigned int hi, hi2, lo;140 unsigned int hi, hi2, lo;
115 141
142 if (mips_cm_is64)
143 return (cycle_t)gic_read(GIC_REG(SHARED, GIC_SH_COUNTER));
144
116 do {145 do {
117 hi = gic_read(GIC_REG(SHARED, GIC_SH_COUNTER_63_32));146 hi = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_63_32));
118 lo = gic_read(GIC_REG(SHARED, GIC_SH_COUNTER_31_00));147 lo = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_31_00));
119 hi2 = gic_read(GIC_REG(SHARED, GIC_SH_COUNTER_63_32));148 hi2 = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_63_32));
120 } while (hi2 != hi);149 } while (hi2 != hi);
121 150
122 return (((cycle_t) hi) << 32) + lo;151 return (((cycle_t) hi) << 32) + lo;
@@ -135,10 +164,14 @@ unsigned int gic_get_count_width(void) · 12 unmodified lines
135 164
136void gic_write_compare(cycle_t cnt)165void gic_write_compare(cycle_t cnt)
137{166{
138 gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI),167 if (mips_cm_is64) {
139 (int)(cnt >> 32));168 gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE), cnt);
140 gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO),169 } else {
141 (int)(cnt & 0xffffffff));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 }
142}175}
143 176
144void gic_write_cpu_compare(cycle_t cnt, int cpu)177void 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
148 local_irq_save(flags);181 local_irq_save(flags);
149 182
150 gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), cpu);183 gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), cpu);
151 gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI),184
152 (int)(cnt >> 32));185 if (mips_cm_is64) {
153 gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO),186 gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE), cnt);
154 (int)(cnt & 0xffffffff));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 }
155 193
156 local_irq_restore(flags);194 local_irq_restore(flags);
157}195}
@@ -160,8 +198,11 @@ cycle_t gic_read_compare(void) · 2 unmodified lines
160{198{
161 unsigned int hi, lo;199 unsigned int hi, lo;
162 200
163 hi = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI));201 if (mips_cm_is64)
164 lo = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO));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));
165 206
166 return (((cycle_t) hi) << 32) + lo;207 return (((cycle_t) hi) << 32) + lo;
167}208}
@@ -196,7 +237,7 @@ static bool gic_local_irq_is_routable(int intr) · 28 unmodified lines
196 if (cpu_has_veic)237 if (cpu_has_veic)
197 return true;238 return true;
198 239
199 vpe_ctl = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_CTL));240 vpe_ctl = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_CTL));
200 switch (intr) {241 switch (intr) {
201 case GIC_LOCAL_INT_TIMER:242 case GIC_LOCAL_INT_TIMER:
202 return vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK;243 return vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK;
@@ -262,7 +303,7 @@ int gic_get_c0_fdc_int(void) · 59 unmodified lines
262 303
263static void gic_handle_shared_int(bool chained)304static void gic_handle_shared_int(bool chained)
264{305{
265 unsigned int i, intr, virq;306 unsigned int i, intr, virq, gic_reg_step = mips_cm_is64 ? 8 : 4;
266 unsigned long *pcpu_mask;307 unsigned long *pcpu_mask;
267 unsigned long pending_reg, intrmask_reg;308 unsigned long pending_reg, intrmask_reg;
268 DECLARE_BITMAP(pending, GIC_MAX_INTRS);309 DECLARE_BITMAP(pending, GIC_MAX_INTRS);
@@ -277,8 +318,8 @@ static void gic_handle_shared_int(bool chained) · 8 unmodified lines
277 for (i = 0; i < BITS_TO_LONGS(gic_shared_intrs); i++) {318 for (i = 0; i < BITS_TO_LONGS(gic_shared_intrs); i++) {
278 pending[i] = gic_read(pending_reg);319 pending[i] = gic_read(pending_reg);
279 intrmask[i] = gic_read(intrmask_reg);320 intrmask[i] = gic_read(intrmask_reg);
280 pending_reg += 0x4;321 pending_reg += gic_reg_step;
281 intrmask_reg += 0x4;322 intrmask_reg += gic_reg_step;
282 }323 }
283 324
284 bitmap_and(pending, pending, intrmask, gic_shared_intrs);325 bitmap_and(pending, pending, intrmask, gic_shared_intrs);
@@ -425,8 +466,8 @@ static void gic_handle_local_int(bool chained) · 140 unmodified lines
425 unsigned long pending, masked;466 unsigned long pending, masked;
426 unsigned int intr, virq;467 unsigned int intr, virq;
427 468
428 pending = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_PEND));469 pending = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_PEND));
429 masked = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_MASK));470 masked = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_MASK));
430 471
431 bitmap_and(&pending, &pending, &masked, GIC_NUM_LOCAL_INTRS);472 bitmap_and(&pending, &pending, &masked, GIC_NUM_LOCAL_INTRS);
432 473
@@ -449,14 +490,14 @@ static void gic_mask_local_irq(struct irq_data *d) · 16 unmodified lines
449{490{
450 int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);491 int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);
451 492
452 gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_RMASK), 1 << intr);493 gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_RMASK), 1 << intr);
453}494}
454 495
455static void gic_unmask_local_irq(struct irq_data *d)496static void gic_unmask_local_irq(struct irq_data *d)
456{497{
457 int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);498 int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq);
458 499
459 gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), 1 << intr);500 gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), 1 << intr);
460}501}
461 502
462static struct irq_chip gic_local_irq_controller = {503static 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
474 spin_lock_irqsave(&gic_lock, flags);515 spin_lock_irqsave(&gic_lock, flags);
475 for (i = 0; i < gic_vpes; i++) {516 for (i = 0; i < gic_vpes; i++) {
476 gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i);517 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);
478 }519 }
479 spin_unlock_irqrestore(&gic_lock, flags);520 spin_unlock_irqrestore(&gic_lock, flags);
480}521}
@@ -488,7 +529,7 @@ static void gic_unmask_local_irq_all_vpes(struct irq_data *d) · 7 unmodified lines
488 spin_lock_irqsave(&gic_lock, flags);529 spin_lock_irqsave(&gic_lock, flags);
489 for (i = 0; i < gic_vpes; i++) {530 for (i = 0; i < gic_vpes; i++) {
490 gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i);531 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);
492 }533 }
493 spin_unlock_irqrestore(&gic_lock, flags);534 spin_unlock_irqrestore(&gic_lock, flags);
494}535}
@@ -608,7 +649,7 @@ static void __init gic_basic_init(void) · 113 unmodified lines
608 for (j = 0; j < GIC_NUM_LOCAL_INTRS; j++) {649 for (j = 0; j < GIC_NUM_LOCAL_INTRS; j++) {
609 if (!gic_local_irq_is_routable(j))650 if (!gic_local_irq_is_routable(j))
610 continue;651 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);
612 }653 }
613 }654 }
614}655}
@@ -653,27 +694,32 @@ static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq, · 38 unmodified lines
653 694
654 switch (intr) {695 switch (intr) {
655 case GIC_LOCAL_INT_WD:696 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);
657 break;698 break;
658 case GIC_LOCAL_INT_COMPARE:699 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);
660 break;702 break;
661 case GIC_LOCAL_INT_TIMER:703 case GIC_LOCAL_INT_TIMER:
662 /* CONFIG_MIPS_CMP workaround (see __gic_init) */704 /* CONFIG_MIPS_CMP workaround (see __gic_init) */
663 val = GIC_MAP_TO_PIN_MSK | timer_cpu_pin;705 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);
665 break;708 break;
666 case GIC_LOCAL_INT_PERFCTR:709 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);
668 break;712 break;
669 case GIC_LOCAL_INT_SWINT0:713 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);
671 break;716 break;
672 case GIC_LOCAL_INT_SWINT1:717 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);
674 break;720 break;
675 case GIC_LOCAL_INT_FDC:721 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);
677 break;723 break;
678 default:724 default:
679 pr_err("Invalid local IRQ %d\n", intr);725 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
778 */824 */
779 if (IS_ENABLED(CONFIG_MIPS_CMP) &&825 if (IS_ENABLED(CONFIG_MIPS_CMP) &&
780 gic_local_irq_is_routable(GIC_LOCAL_INT_TIMER)) {826 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,
782 GIC_VPE_TIMER_MAP)) &828 GIC_VPE_TIMER_MAP)) &
783 GIC_MAP_MSK;829 GIC_MAP_MSK;
784 irq_set_chained_handler(MIPS_CPU_IRQ_BASE +830 irq_set_chained_handler(MIPS_CPU_IRQ_BASE +
drivers/net/ethernet/ti/cpmac.c+2−0
@@ -41,6 +41,8 @@ · 40 unmodified lines
41#include <linux/gpio.h>41#include <linux/gpio.h>
42#include <linux/atomic.h>42#include <linux/atomic.h>
43 43
44#include <asm/mach-ar7/ar7.h>
45
44MODULE_AUTHOR("Eugene Konev <ejka@imfi.kspu.ru>");46MODULE_AUTHOR("Eugene Konev <ejka@imfi.kspu.ru>");
45MODULE_DESCRIPTION("TI AR7 ethernet driver (CPMAC)");47MODULE_DESCRIPTION("TI AR7 ethernet driver (CPMAC)");
46MODULE_LICENSE("GPL");48MODULE_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
70 */70 */
71static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work)71static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work)
72{72{
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)) {
74 /*81 /*
75 * Ignore length errors on min size packets. Some82 * Ignore length errors on min size packets. Some
76 * equipment incorrectly pads packets to 64+4FCS83 * 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
87 * packet to determine if we can remove a non spec94 * packet to determine if we can remove a non spec
88 * preamble and generate a correct packet.95 * preamble and generate a correct packet.
89 */96 */
90 int interface = cvmx_helper_get_interface_num(work->ipprt);97 int interface = cvmx_helper_get_interface_num(port);
91 int index = cvmx_helper_get_interface_index_num(work->ipprt);98 int index = cvmx_helper_get_interface_index_num(port);
92 union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;99 union cvmx_gmxx_rxx_frm_ctl gmxx_rxx_frm_ctl;
93 100
94 gmxx_rxx_frm_ctl.u64 =101 gmxx_rxx_frm_ctl.u64 =
@@ -99,7 +106,7 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) · 4 unmodified lines
99 cvmx_phys_to_ptr(work->packet_ptr.s.addr);106 cvmx_phys_to_ptr(work->packet_ptr.s.addr);
100 int i = 0;107 int i = 0;
101 108
102 while (i < work->len - 1) {109 while (i < work->word1.len - 1) {
103 if (*ptr != 0x55)110 if (*ptr != 0x55)
104 break;111 break;
105 ptr++;112 ptr++;
@@ -109,18 +116,18 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) · 3 unmodified lines
109 if (*ptr == 0xd5) {116 if (*ptr == 0xd5) {
110 /*117 /*
111 printk_ratelimited("Port %d received 0xd5 preamble\n",118 printk_ratelimited("Port %d received 0xd5 preamble\n",
112 work->ipprt);119 port);
113 */120 */
114 work->packet_ptr.s.addr += i + 1;121 work->packet_ptr.s.addr += i + 1;
115 work->len -= i + 5;122 work->word1.len -= i + 5;
116 } else if ((*ptr & 0xf) == 0xd) {123 } else if ((*ptr & 0xf) == 0xd) {
117 /*124 /*
118 printk_ratelimited("Port %d received 0x?d preamble\n",125 printk_ratelimited("Port %d received 0x?d preamble\n",
119 work->ipprt);126 port);
120 */127 */
121 work->packet_ptr.s.addr += i;128 work->packet_ptr.s.addr += i;
122 work->len -= i + 4;129 work->word1.len -= i + 4;
123 for (i = 0; i < work->len; i++) {130 for (i = 0; i < work->word1.len; i++) {
124 *ptr =131 *ptr =
125 ((*ptr & 0xf0) >> 4) |132 ((*ptr & 0xf0) >> 4) |
126 ((*(ptr + 1) & 0xf) << 4);133 ((*(ptr + 1) & 0xf) << 4);
@@ -128,7 +135,7 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) · 1 unmodified line
128 }135 }
129 } else {136 } else {
130 printk_ratelimited("Port %d unknown preamble, packet dropped\n",137 printk_ratelimited("Port %d unknown preamble, packet dropped\n",
131 work->ipprt);138 port);
132 /*139 /*
133 cvmx_helper_dump_packet(work);140 cvmx_helper_dump_packet(work);
134 */141 */
@@ -138,7 +145,7 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work) · 3 unmodified lines
138 }145 }
139 } else {146 } else {
140 printk_ratelimited("Port %d receive error code %d, packet dropped\n",147 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);
142 cvm_oct_free_work(work);149 cvm_oct_free_work(work);
143 return 1;150 return 1;
144 }151 }
@@ -172,9 +179,16 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) · 27 unmodified lines
172 }179 }
173 180
174 /* Only allow work for our group (and preserve priorities) */181 /* Only allow work for our group (and preserve priorities) */
175 old_group_mask = cvmx_read_csr(CVMX_POW_PP_GRP_MSKX(coreid));182 if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
176 cvmx_write_csr(CVMX_POW_PP_GRP_MSKX(coreid),183 old_group_mask = cvmx_read_csr(CVMX_SSO_PPX_GRP_MSK(coreid));
177 (old_group_mask & ~0xFFFFull) | 1 << pow_receive_group);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 }
178 192
179 if (USE_ASYNC_IOBDMA) {193 if (USE_ASYNC_IOBDMA) {
180 cvmx_pow_work_request_async(CVMX_SCR_SCRATCH, CVMX_POW_NO_WAIT);194 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
186 struct sk_buff **pskb = NULL;200 struct sk_buff **pskb = NULL;
187 int skb_in_hw;201 int skb_in_hw;
188 cvmx_wqe_t *work;202 cvmx_wqe_t *work;
203 int port;
189 204
190 if (USE_ASYNC_IOBDMA && did_work_request)205 if (USE_ASYNC_IOBDMA && did_work_request)
191 work = cvmx_pow_work_response_async(CVMX_SCR_SCRATCH);206 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
195 prefetch(work);210 prefetch(work);
196 did_work_request = 0;211 did_work_request = 0;
197 if (work == NULL) {212 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;
199 220
200 wq_int.u64 = 0;221 wq_int.u64 = 0;
201 wq_int.s.iq_dis = 1 << pow_receive_group;222 wq_int.s.iq_dis = 1 << pow_receive_group;
202 wq_int.s.wq_int = 1 << pow_receive_group;223 wq_int.s.wq_int = 1 << pow_receive_group;
203 cvmx_write_csr(CVMX_POW_WQ_INT, wq_int.u64);224 cvmx_write_csr(CVMX_POW_WQ_INT, wq_int.u64);
225 }
204 break;226 break;
205 }227 }
206 pskb = (struct sk_buff **)(cvm_oct_get_buffer_ptr(work->packet_ptr) -228 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
220 prefetch(&skb->head);242 prefetch(&skb->head);
221 prefetch(&skb->len);243 prefetch(&skb->len);
222 }244 }
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]);
224 252
225 /* Immediately throw away all packets with receive errors */253 /* Immediately throw away all packets with receive errors */
226 if (unlikely(work->word2.snoip.rcv_error)) {254 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
237 skb->data = skb->head + work->packet_ptr.s.addr -265 skb->data = skb->head + work->packet_ptr.s.addr -
238 cvmx_ptr_to_phys(skb->head);266 cvmx_ptr_to_phys(skb->head);
239 prefetch(skb->data);267 prefetch(skb->data);
240 skb->len = work->len;268 skb->len = work->word1.len;
241 skb_set_tail_pointer(skb, skb->len);269 skb_set_tail_pointer(skb, skb->len);
242 packet_not_copied = 1;270 packet_not_copied = 1;
243 } else {271 } else {
@@ -245,7 +273,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) · 1 unmodified line
245 * We have to copy the packet. First allocate273 * We have to copy the packet. First allocate
246 * an skbuff for it.274 * an skbuff for it.
247 */275 */
248 skb = dev_alloc_skb(work->len);276 skb = dev_alloc_skb(work->word1.len);
249 if (!skb) {277 if (!skb) {
250 cvm_oct_free_work(work);278 cvm_oct_free_work(work);
251 continue;279 continue;
@@ -268,13 +296,14 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) · 16 unmodified lines
268 else296 else
269 ptr += 6;297 ptr += 6;
270 }298 }
271 memcpy(skb_put(skb, work->len), ptr, work->len);299 memcpy(skb_put(skb, work->word1.len), ptr,
300 work->word1.len);
272 /* No packet buffers to free */301 /* No packet buffers to free */
273 } else {302 } else {
274 int segments = work->word2.s.bufs;303 int segments = work->word2.s.bufs;
275 union cvmx_buf_ptr segment_ptr =304 union cvmx_buf_ptr segment_ptr =
276 work->packet_ptr;305 work->packet_ptr;
277 int len = work->len;306 int len = work->word1.len;
278 307
279 while (segments--) {308 while (segments--) {
280 union cvmx_buf_ptr next_ptr =309 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
310 }339 }
311 packet_not_copied = 0;340 packet_not_copied = 0;
312 }341 }
313 342 if (likely((port < TOTAL_NUMBER_OF_PORTS) &&
314 if (likely((work->ipprt < TOTAL_NUMBER_OF_PORTS) &&343 cvm_oct_device[port])) {
315 cvm_oct_device[work->ipprt])) {344 struct net_device *dev = cvm_oct_device[port];
316 struct net_device *dev = cvm_oct_device[work->ipprt];
317 struct octeon_ethernet *priv = netdev_priv(dev);345 struct octeon_ethernet *priv = netdev_priv(dev);
318 346
319 /*347 /*
@@ -333,7 +361,7 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) · 13 unmodified lines
333 skb->ip_summed = CHECKSUM_UNNECESSARY;361 skb->ip_summed = CHECKSUM_UNNECESSARY;
334 362
335 /* Increment RX stats for virtual ports */363 /* Increment RX stats for virtual ports */
336 if (work->ipprt >= CVMX_PIP_NUM_INPUT_PORTS) {364 if (port >= CVMX_PIP_NUM_INPUT_PORTS) {
337#ifdef CONFIG_64BIT365#ifdef CONFIG_64BIT
338 atomic64_add(1,366 atomic64_add(1,
339 (atomic64_t *)&priv->stats.rx_packets);367 (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
368 * doesn't exist.396 * doesn't exist.
369 */397 */
370 printk_ratelimited("Port %d not controlled by Linux, packet dropped\n",398 printk_ratelimited("Port %d not controlled by Linux, packet dropped\n",
371 work->ipprt);399 port);
372 dev_kfree_skb_irq(skb);400 dev_kfree_skb_irq(skb);
373 }401 }
374 /*402 /*
@@ -390,7 +418,13 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget) · 15 unmodified lines
390 }418 }
391 }419 }
392 /* Restore the original POW group mask */420 /* 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
394 if (USE_ASYNC_IOBDMA) {428 if (USE_ASYNC_IOBDMA) {
395 /* Restore the scratch area */429 /* Restore the scratch area */
396 cvmx_scratch_write64(CVMX_SCR_SCRATCH, old_scratch);430 cvmx_scratch_write64(CVMX_SCR_SCRATCH, old_scratch);
@@ -422,8 +456,6 @@ void cvm_oct_rx_initialize(void) · 25 unmodified lines
422{456{
423 int i;457 int i;
424 struct net_device *dev_for_napi = NULL;458 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;
427 459
428 for (i = 0; i < TOTAL_NUMBER_OF_PORTS; i++) {460 for (i = 0; i < TOTAL_NUMBER_OF_PORTS; i++) {
429 if (cvm_oct_device[i]) {461 if (cvm_oct_device[i]) {
@@ -449,15 +481,34 @@ void cvm_oct_rx_initialize(void) · 19 unmodified lines
449 481
450 disable_irq_nosync(OCTEON_IRQ_WORKQ0 + pow_receive_group);482 disable_irq_nosync(OCTEON_IRQ_WORKQ0 + pow_receive_group);
451 483
452 int_thr.u64 = 0;
453 int_thr.s.tc_en = 1;
454 int_thr.s.tc_thr = 1;
455 /* Enable POW interrupt when our port has at least one packet */484 /* 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);485 if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
457 486 union cvmx_sso_wq_int_thrx int_thr;
458 int_pc.u64 = 0;487 union cvmx_pow_wq_int_pc int_pc;
459 int_pc.s.pc_thr = 5;488
460 cvmx_write_csr(CVMX_POW_WQ_INT_PC, int_pc.u64);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 }
461 512
462 /* Schedule NAPI now. This will indirectly enable the interrupt. */513 /* Schedule NAPI now. This will indirectly enable the interrupt. */
463 napi_schedule(&cvm_oct_napi);514 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
591 * Fill in some of the work queue fields. We may need to add591 * Fill in some of the work queue fields. We may need to add
592 * more if the software at the other end needs them.592 * more if the software at the other end needs them.
593 */593 */
594 work->hw_chksum = skb->csum;594 if (!OCTEON_IS_MODEL(OCTEON_CN68XX))
595 work->len = skb->len;595 work->word0.pip.cn38xx.hw_chksum = skb->csum;
596 work->ipprt = priv->port;596 work->word1.len = skb->len;
597 work->qos = priv->port & 0x7;597 cvmx_wqe_set_port(work, priv->port);
598 work->grp = pow_send_group;598 cvmx_wqe_set_qos(work, priv->port & 0x7);
599 work->tag_type = CVMX_HELPER_INPUT_TAG_TYPE;599 cvmx_wqe_set_grp(work, pow_send_group);
600 work->tag = pow_send_group; /* FIXME */600 work->word1.tag_type = CVMX_HELPER_INPUT_TAG_TYPE;
601 work->word1.tag = pow_send_group; /* FIXME */
601 /* Default to zero. Sets of zero later are commented out */602 /* Default to zero. Sets of zero later are commented out */
602 work->word2.u64 = 0;603 work->word2.u64 = 0;
603 work->word2.s.bufs = 1;604 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
677 }678 }
678 679
679 /* Submit the packet to the POW */680 /* Submit the packet to the POW */
680 cvmx_pow_work_submit(work, work->tag, work->tag_type, work->qos,681 cvmx_pow_work_submit(work, work->word1.tag, work->word1.tag_type,
681 work->grp);682 cvmx_wqe_get_qos(work), cvmx_wqe_get_grp(work));
682 priv->stats.tx_packets++;683 priv->stats.tx_packets++;
683 priv->stats.tx_bytes += skb->len;684 priv->stats.tx_bytes += skb->len;
684 dev_consume_skb_any(skb);685 dev_consume_skb_any(skb);
drivers/staging/octeon/ethernet-util.h+11−11
@@ -8,6 +8,10 @@ · 7 unmodified lines
8 * published by the Free Software Foundation.8 * published by the Free Software Foundation.
9 */9 */
10 10
11#include <asm/octeon/cvmx-pip.h>
12#include <asm/octeon/cvmx-helper.h>
13#include <asm/octeon/cvmx-helper-util.h>
14
11/**15/**
12 * cvm_oct_get_buffer_ptr - convert packet data address to pointer16 * cvm_oct_get_buffer_ptr - convert packet data address to pointer
13 * @packet_ptr: Packet data hardware address17 * @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
28 */32 */
29static inline int INTERFACE(int ipd_port)33static inline int INTERFACE(int ipd_port)
30{34{
31 if (ipd_port < 32) /* Interface 0 or 1 for RGMII,GMII,SPI, etc */35 int interface = cvmx_helper_get_interface_num(ipd_port);
32 return ipd_port >> 4;36
33 else if (ipd_port < 36) /* Interface 2 for NPI */37 if (interface >= 0)
34 return 2;38 return interface;
35 else if (ipd_port < 40) /* Interface 3 for loopback */39 else if (ipd_port == CVMX_PIP_NUM_INPUT_PORTS)
36 return 3;40 return 10;
37 else if (ipd_port == 40) /* Non existent interface for POW0 */
38 return 4;
39 panic("Illegal ipd_port %d passed to INTERFACE\n", ipd_port);41 panic("Illegal ipd_port %d passed to INTERFACE\n", ipd_port);
40}42}
41 43
@@ -47,7 +49,5 @@ static inline int INTERFACE(int ipd_port) · 5 unmodified lines
47 */49 */
48static inline int INDEX(int ipd_port)50static inline int INDEX(int ipd_port)
49{51{
50 if (ipd_port < 32)52 return cvmx_helper_get_interface_index_num(ipd_port);
51 return ipd_port & 15;
52 return ipd_port & 3;
53}53}
drivers/staging/octeon/ethernet.c+5−2
@@ -152,7 +152,7 @@ static void cvm_oct_configure_common_hw(void) · 151 unmodified lines
152 num_packet_buffers);152 num_packet_buffers);
153 if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL)153 if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL)
154 cvm_oct_mem_fill_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,154 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);
156 156
157#ifdef __LITTLE_ENDIAN157#ifdef __LITTLE_ENDIAN
158 {158 {
@@ -860,7 +860,10 @@ static int cvm_oct_remove(struct platform_device *pdev) · 701 unmodified lines
860 int port;860 int port;
861 861
862 /* Disable POW interrupt */862 /* 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);
864 867
865 cvmx_ipd_disable();868 cvmx_ipd_disable();
866 869
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
879 .chars_in_buffer = mips_ejtag_fdc_tty_chars_in_buffer,879 .chars_in_buffer = mips_ejtag_fdc_tty_chars_in_buffer,
880};880};
881 881
882int __weak get_c0_fdc_int(void)
883{
884 return -1;
885}
886
882static int mips_ejtag_fdc_tty_probe(struct mips_cdmm_device *dev)887static int mips_ejtag_fdc_tty_probe(struct mips_cdmm_device *dev)
883{888{
884 int ret, nport;889 int ret, nport;
@@ -967,9 +972,7 @@ static int mips_ejtag_fdc_tty_probe(struct mips_cdmm_device *dev) · 82 unmodified lines
967 wake_up_process(priv->thread);972 wake_up_process(priv->thread);
968 973
969 /* Look for an FDC IRQ */974 /* Look for an FDC IRQ */
970 priv->irq = -1;975 priv->irq = get_c0_fdc_int();
971 if (get_c0_fdc_int)
972 priv->irq = get_c0_fdc_int();
973 976
974 /* Try requesting the IRQ */977 /* Try requesting the IRQ */
975 if (priv->irq >= 0) {978 if (priv->irq >= 0) {
include/linux/irqchip/mips-gic.h+12−2
@@ -41,12 +41,20 @@ · 40 unmodified lines
41 41
42/* Shared Global Counter */42/* Shared Global Counter */
43#define GIC_SH_COUNTER_31_00_OFS 0x001043#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
44#define GIC_SH_COUNTER_63_32_OFS 0x001446#define GIC_SH_COUNTER_63_32_OFS 0x0014
45#define GIC_SH_REVISIONID_OFS 0x002047#define GIC_SH_REVISIONID_OFS 0x0020
46 48
47/* Convert an interrupt number to a byte offset/bit for multi-word registers */49/* Convert an interrupt number to a byte offset/bit for multi-word registers */
48#define GIC_INTR_OFS(intr) (((intr) / 32) * 4)50#define GIC_INTR_OFS(intr) ({ \
49#define GIC_INTR_BIT(intr) ((intr) % 32)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))
50 58
51/* Polarity : Reset Value is always 0 */59/* Polarity : Reset Value is always 0 */
52#define GIC_SH_SET_POLARITY_OFS 0x010060#define GIC_SH_SET_POLARITY_OFS 0x0100
@@ -98,6 +106,8 @@ · 45 unmodified lines
98#define GIC_VPE_WD_COUNT0_OFS 0x0094106#define GIC_VPE_WD_COUNT0_OFS 0x0094
99#define GIC_VPE_WD_INITIAL0_OFS 0x0098107#define GIC_VPE_WD_INITIAL0_OFS 0x0098
100#define GIC_VPE_COMPARE_LO_OFS 0x00a0108#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
101#define GIC_VPE_COMPARE_HI_OFS 0x00a4111#define GIC_VPE_COMPARE_HI_OFS 0x00a4
102 112
103#define GIC_VPE_EIC_SHADOW_SET_BASE_OFS 0x0100113#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