Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'mips_5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux

Pull MIPS updates from Paul Burton:
"Main MIPS changes:

- boot_mem_map is removed, providing a nice cleanup made possible by
the recent removal of bootmem.

- Some fixes to atomics, in general providing compiler barriers for
smp_mb__{before,after}_atomic plus fixes specific to Loongson CPUs
or MIPS32 systems using cmpxchg64().

- Conversion to the new generic VDSO infrastructure courtesy of
Vincenzo Frascino.

- Removal of undefined behavior in set_io_port_base(), fixing the
behavior of some MIPS kernel configurations when built with recent
clang versions.

- Initial MIPS32 huge page support, functional on at least Ingenic
SoCs.

- pte_special() is now supported for some configurations, allowing
among other things generic fast GUP to be used.

- Miscellaneous fixes & cleanups.

And platform specific changes:

- Major improvements to Ingenic SoC support from Paul Cercueil,
mostly enabled by the inclusion of the new TCU (timer-counter unit)
drivers he's spent a very patient year or so working on. Plus some
fixes for X1000 SoCs from Zhou Yanjie.

- Netgear R6200 v1 systems are now supported by the bcm47xx platform.

- DT updates for BMIPS, Lantiq & Microsemi Ocelot systems"

* tag 'mips_5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux: (89 commits)
MIPS: Detect bad _PFN_SHIFT values
MIPS: Disable pte_special() for MIPS32 with RiXi
MIPS: ralink: deactivate PCI support for SOC_MT7621
mips: compat: vdso: Use legacy syscalls as fallback
MIPS: Drop Loongson _CACHE_* definitions
MIPS: tlbex: Remove cpu_has_local_ebase
MIPS: tlbex: Simplify r3k check
MIPS: Select R3k-style TLB in Kconfig
MIPS: PCI: refactor ioc3 special handling
mips: remove ioremap_cachable
mips/atomic: Fix smp_mb__{before,after}_atomic()
mips/atomic: Fix loongson_llsc_mb() wreckage
mips/atomic: Fix cmpxchg64 barriers
MIPS: Octeon: remove duplicated include from dma-octeon.c
firmware: bcm47xx_nvram: Allow COMPILE_TEST
firmware: bcm47xx_nvram: Correct size_t printf format
MIPS: Treat Loongson Extensions as ASEs
MIPS: Remove dev_err() usage after platform_get_irq()
MIPS: dts: mscc: describe the PTP ready interrupt
MIPS: dts: mscc: describe the PTP register range
...

+2934 -4972
-22
Documentation/devicetree/bindings/pwm/ingenic,jz47xx-pwm.txt
··· 1 - Ingenic JZ47xx PWM Controller 2 - ============================= 3 - 4 - Required properties: 5 - - compatible: Should be "ingenic,jz4740-pwm" 6 - - #pwm-cells: Should be 3. See pwm.txt in this directory for a description 7 - of the cells format. 8 - - clocks : phandle to the external clock. 9 - - clock-names : Should be "ext". 10 - 11 - 12 - Example: 13 - 14 - pwm: pwm@10002000 { 15 - compatible = "ingenic,jz4740-pwm"; 16 - reg = <0x10002000 0x1000>; 17 - 18 - #pwm-cells = <3>; 19 - 20 - clocks = <&ext>; 21 - clock-names = "ext"; 22 - };
+137
Documentation/devicetree/bindings/timer/ingenic,tcu.txt
··· 1 + Ingenic JZ47xx SoCs Timer/Counter Unit devicetree bindings 2 + ========================================================== 3 + 4 + For a description of the TCU hardware and drivers, have a look at 5 + Documentation/mips/ingenic-tcu.txt. 6 + 7 + Required properties: 8 + 9 + - compatible: Must be one of: 10 + * ingenic,jz4740-tcu 11 + * ingenic,jz4725b-tcu 12 + * ingenic,jz4770-tcu 13 + followed by "simple-mfd". 14 + - reg: Should be the offset/length value corresponding to the TCU registers 15 + - clocks: List of phandle & clock specifiers for clocks external to the TCU. 16 + The "pclk", "rtc" and "ext" clocks should be provided. The "tcu" clock 17 + should be provided if the SoC has it. 18 + - clock-names: List of name strings for the external clocks. 19 + - #clock-cells: Should be <1>; 20 + Clock consumers specify this argument to identify a clock. The valid values 21 + may be found in <dt-bindings/clock/ingenic,tcu.h>. 22 + - interrupt-controller : Identifies the node as an interrupt controller 23 + - #interrupt-cells : Specifies the number of cells needed to encode an 24 + interrupt source. The value should be 1. 25 + - interrupts : Specifies the interrupt the controller is connected to. 26 + 27 + Optional properties: 28 + 29 + - ingenic,pwm-channels-mask: Bitmask of TCU channels reserved for PWM use. 30 + Default value is 0xfc. 31 + 32 + 33 + Children nodes 34 + ========================================================== 35 + 36 + 37 + PWM node: 38 + --------- 39 + 40 + Required properties: 41 + 42 + - compatible: Must be one of: 43 + * ingenic,jz4740-pwm 44 + * ingenic,jz4725b-pwm 45 + - #pwm-cells: Should be 3. See ../pwm/pwm.txt for a description of the cell 46 + format. 47 + - clocks: List of phandle & clock specifiers for the TCU clocks. 48 + - clock-names: List of name strings for the TCU clocks. 49 + 50 + 51 + Watchdog node: 52 + -------------- 53 + 54 + Required properties: 55 + 56 + - compatible: Must be "ingenic,jz4740-watchdog" 57 + - clocks: phandle to the WDT clock 58 + - clock-names: should be "wdt" 59 + 60 + 61 + OS Timer node: 62 + --------- 63 + 64 + Required properties: 65 + 66 + - compatible: Must be one of: 67 + * ingenic,jz4725b-ost 68 + * ingenic,jz4770-ost 69 + - clocks: phandle to the OST clock 70 + - clock-names: should be "ost" 71 + - interrupts : Specifies the interrupt the OST is connected to. 72 + 73 + 74 + Example 75 + ========================================================== 76 + 77 + #include <dt-bindings/clock/jz4770-cgu.h> 78 + #include <dt-bindings/clock/ingenic,tcu.h> 79 + 80 + / { 81 + tcu: timer@10002000 { 82 + compatible = "ingenic,jz4770-tcu", "simple-mfd"; 83 + reg = <0x10002000 0x1000>; 84 + #address-cells = <1>; 85 + #size-cells = <1>; 86 + ranges = <0x0 0x10002000 0x1000>; 87 + 88 + #clock-cells = <1>; 89 + 90 + clocks = <&cgu JZ4770_CLK_RTC 91 + &cgu JZ4770_CLK_EXT 92 + &cgu JZ4770_CLK_PCLK>; 93 + clock-names = "rtc", "ext", "pclk"; 94 + 95 + interrupt-controller; 96 + #interrupt-cells = <1>; 97 + 98 + interrupt-parent = <&intc>; 99 + interrupts = <27 26 25>; 100 + 101 + watchdog: watchdog@0 { 102 + compatible = "ingenic,jz4740-watchdog"; 103 + reg = <0x0 0xc>; 104 + 105 + clocks = <&tcu TCU_CLK_WDT>; 106 + clock-names = "wdt"; 107 + }; 108 + 109 + pwm: pwm@40 { 110 + compatible = "ingenic,jz4740-pwm"; 111 + reg = <0x40 0x80>; 112 + 113 + #pwm-cells = <3>; 114 + 115 + clocks = <&tcu TCU_CLK_TIMER0 116 + &tcu TCU_CLK_TIMER1 117 + &tcu TCU_CLK_TIMER2 118 + &tcu TCU_CLK_TIMER3 119 + &tcu TCU_CLK_TIMER4 120 + &tcu TCU_CLK_TIMER5 121 + &tcu TCU_CLK_TIMER6 122 + &tcu TCU_CLK_TIMER7>; 123 + clock-names = "timer0", "timer1", "timer2", "timer3", 124 + "timer4", "timer5", "timer6", "timer7"; 125 + }; 126 + 127 + ost: timer@e0 { 128 + compatible = "ingenic,jz4770-ost"; 129 + reg = <0xe0 0x20>; 130 + 131 + clocks = <&tcu TCU_CLK_OST>; 132 + clock-names = "ost"; 133 + 134 + interrupts = <15>; 135 + }; 136 + }; 137 + };
-17
Documentation/devicetree/bindings/watchdog/ingenic,jz4740-wdt.txt
··· 1 - Ingenic Watchdog Timer (WDT) Controller for JZ4740 & JZ4780 2 - 3 - Required properties: 4 - compatible: "ingenic,jz4740-watchdog" or "ingenic,jz4780-watchdog" 5 - reg: Register address and length for watchdog registers 6 - clocks: phandle to the RTC clock 7 - clock-names: should be "rtc" 8 - 9 - Example: 10 - 11 - watchdog: jz4740-watchdog@10002000 { 12 - compatible = "ingenic,jz4740-watchdog"; 13 - reg = <0x10002000 0x10>; 14 - 15 - clocks = <&cgu JZ4740_CLK_RTC>; 16 - clock-names = "rtc"; 17 - };
+1 -2
Documentation/index.rst
··· 144 144 .. toctree:: 145 145 :maxdepth: 2 146 146 147 - sh/index 148 147 arm/index 149 148 arm64/index 150 149 ia64/index 151 150 m68k/index 152 - powerpc/index 153 151 mips/index 154 152 nios2/nios2 155 153 openrisc/index 156 154 parisc/index 155 + powerpc/index 157 156 riscv/index 158 157 s390/index 159 158 sh/index
+6 -3
Documentation/mips/index.rst
··· 1 1 .. SPDX-License-Identifier: GPL-2.0 2 2 3 - ================= 4 - MIPS architecture 5 - ================= 3 + =========================== 4 + MIPS-specific Documentation 5 + =========================== 6 6 7 7 .. toctree:: 8 8 :maxdepth: 2 9 + :numbered: 10 + 11 + ingenic-tcu 9 12 10 13 au1xxx_ide 11 14
+71
Documentation/mips/ingenic-tcu.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 3 + =============================================== 4 + Ingenic JZ47xx SoCs Timer/Counter Unit hardware 5 + =============================================== 6 + 7 + The Timer/Counter Unit (TCU) in Ingenic JZ47xx SoCs is a multi-function 8 + hardware block. It features up to to eight channels, that can be used as 9 + counters, timers, or PWM. 10 + 11 + - JZ4725B, JZ4750, JZ4755 only have six TCU channels. The other SoCs all 12 + have eight channels. 13 + 14 + - JZ4725B introduced a separate channel, called Operating System Timer 15 + (OST). It is a 32-bit programmable timer. On JZ4760B and above, it is 16 + 64-bit. 17 + 18 + - Each one of the TCU channels has its own clock, which can be reparented to three 19 + different clocks (pclk, ext, rtc), gated, and reclocked, through their TCSR register. 20 + 21 + - The watchdog and OST hardware blocks also feature a TCSR register with the same 22 + format in their register space. 23 + - The TCU registers used to gate/ungate can also gate/ungate the watchdog and 24 + OST clocks. 25 + 26 + - Each TCU channel works in one of two modes: 27 + 28 + - mode TCU1: channels cannot work in sleep mode, but are easier to 29 + operate. 30 + - mode TCU2: channels can work in sleep mode, but the operation is a bit 31 + more complicated than with TCU1 channels. 32 + 33 + - The mode of each TCU channel depends on the SoC used: 34 + 35 + - On the oldest SoCs (up to JZ4740), all of the eight channels operate in 36 + TCU1 mode. 37 + - On JZ4725B, channel 5 operates as TCU2, the others operate as TCU1. 38 + - On newest SoCs (JZ4750 and above), channels 1-2 operate as TCU2, the 39 + others operate as TCU1. 40 + 41 + - Each channel can generate an interrupt. Some channels share an interrupt 42 + line, some don't, and this changes between SoC versions: 43 + 44 + - on older SoCs (JZ4740 and below), channel 0 and channel 1 have their 45 + own interrupt line; channels 2-7 share the last interrupt line. 46 + - On JZ4725B, channel 0 has its own interrupt; channels 1-5 share one 47 + interrupt line; the OST uses the last interrupt line. 48 + - on newer SoCs (JZ4750 and above), channel 5 has its own interrupt; 49 + channels 0-4 and (if eight channels) 6-7 all share one interrupt line; 50 + the OST uses the last interrupt line. 51 + 52 + Implementation 53 + ============== 54 + 55 + The functionalities of the TCU hardware are spread across multiple drivers: 56 + 57 + =========== ===== 58 + clocks drivers/clk/ingenic/tcu.c 59 + interrupts drivers/irqchip/irq-ingenic-tcu.c 60 + timers drivers/clocksource/ingenic-timer.c 61 + OST drivers/clocksource/ingenic-ost.c 62 + PWM drivers/pwm/pwm-jz4740.c 63 + watchdog drivers/watchdog/jz4740_wdt.c 64 + =========== ===== 65 + 66 + Because various functionalities of the TCU that belong to different drivers 67 + and frameworks can be controlled from the same registers, all of these 68 + drivers access their registers through the same regmap. 69 + 70 + For more information regarding the devicetree bindings of the TCU drivers, 71 + have a look at Documentation/devicetree/bindings/mfd/ingenic,tcu.txt.
+17 -48
arch/mips/Kconfig
··· 22 22 select GENERIC_CLOCKEVENTS 23 23 select GENERIC_CMOS_UPDATE 24 24 select GENERIC_CPU_AUTOPROBE 25 + select GENERIC_GETTIMEOFDAY 25 26 select GENERIC_IOMAP 26 27 select GENERIC_IRQ_PROBE 27 28 select GENERIC_IRQ_SHOW ··· 44 43 select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT 45 44 select HAVE_ARCH_SECCOMP_FILTER 46 45 select HAVE_ARCH_TRACEHOOK 47 - select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT 46 + select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES 48 47 select HAVE_ASM_MODVERSIONS 49 48 select HAVE_EBPF_JIT if (!CPU_MICROMIPS) 50 49 select HAVE_CONTEXT_TRACKING ··· 76 75 select HAVE_STACKPROTECTOR 77 76 select HAVE_SYSCALL_TRACEPOINTS 78 77 select HAVE_VIRT_CPU_ACCOUNTING_GEN if 64BIT || !SMP 78 + select HAVE_GENERIC_VDSO 79 79 select IRQ_FORCED_THREADING 80 80 select ISA if EISA 81 81 select MODULES_USE_ELF_RELA if MODULES && 64BIT ··· 85 83 select RTC_LIB 86 84 select SYSCTL_EXCEPTION_TRACE 87 85 select VIRT_TO_BUS 86 + select ARCH_HAS_PTE_SPECIAL if !(32BIT && CPU_HAS_RIXI) 88 87 89 88 menu "Machine selection" 90 89 ··· 388 385 select SYS_SUPPORTS_32BIT_KERNEL 389 386 select SYS_SUPPORTS_LITTLE_ENDIAN 390 387 select SYS_SUPPORTS_ZBOOT_UART16550 388 + select CPU_SUPPORTS_HUGEPAGES 391 389 select DMA_NONCOHERENT 392 390 select IRQ_MIPS_CPU 393 391 select PINCTRL ··· 1235 1231 1236 1232 config SYS_SUPPORTS_HUGETLBFS 1237 1233 bool 1238 - depends on CPU_SUPPORTS_HUGEPAGES && 64BIT 1234 + depends on CPU_SUPPORTS_HUGEPAGES 1239 1235 default y 1240 1236 1241 1237 config MIPS_HUGE_TLB_SUPPORT ··· 1583 1579 depends on SYS_HAS_CPU_R3000 1584 1580 select CPU_HAS_WB 1585 1581 select CPU_HAS_LOAD_STORE_LR 1582 + select CPU_R3K_TLB 1586 1583 select CPU_SUPPORTS_32BIT_KERNEL 1587 1584 select CPU_SUPPORTS_HIGHMEM 1588 1585 help ··· 1599 1594 depends on SYS_HAS_CPU_TX39XX 1600 1595 select CPU_SUPPORTS_32BIT_KERNEL 1601 1596 select CPU_HAS_LOAD_STORE_LR 1597 + select CPU_R3K_TLB 1602 1598 1603 1599 config CPU_VR41XX 1604 1600 bool "R41xx" ··· 1612 1606 Only choose this option if you have one of these processors as a 1613 1607 kernel built with this option will not run on any other type of 1614 1608 processor or vice versa. 1615 - 1616 - config CPU_R4300 1617 - bool "R4300" 1618 - depends on SYS_HAS_CPU_R4300 1619 - select CPU_SUPPORTS_32BIT_KERNEL 1620 - select CPU_SUPPORTS_64BIT_KERNEL 1621 - select CPU_HAS_LOAD_STORE_LR 1622 - help 1623 - MIPS Technologies R4300-series processors. 1624 1609 1625 1610 config CPU_R4X00 1626 1611 bool "R4x00" ··· 1643 1646 help 1644 1647 MIPS Technologies R5000-series processors other than the Nevada. 1645 1648 1646 - config CPU_R5432 1647 - bool "R5432" 1648 - depends on SYS_HAS_CPU_R5432 1649 - select CPU_SUPPORTS_32BIT_KERNEL 1650 - select CPU_SUPPORTS_64BIT_KERNEL 1651 - select CPU_SUPPORTS_HUGEPAGES 1652 - select CPU_HAS_LOAD_STORE_LR 1653 - 1654 1649 config CPU_R5500 1655 1650 bool "R5500" 1656 1651 depends on SYS_HAS_CPU_R5500 ··· 1663 1674 select CPU_HAS_LOAD_STORE_LR 1664 1675 help 1665 1676 QED / PMC-Sierra RM52xx-series ("Nevada") processors. 1666 - 1667 - config CPU_R8000 1668 - bool "R8000" 1669 - depends on SYS_HAS_CPU_R8000 1670 - select CPU_HAS_PREFETCH 1671 - select CPU_HAS_LOAD_STORE_LR 1672 - select CPU_SUPPORTS_64BIT_KERNEL 1673 - help 1674 - MIPS Technologies R8000 processors. Note these processors are 1675 - uncommon and the support for them is incomplete. 1676 1677 1677 1678 config CPU_R10000 1678 1679 bool "R10000" ··· 1956 1977 config SYS_HAS_CPU_VR41XX 1957 1978 bool 1958 1979 1959 - config SYS_HAS_CPU_R4300 1960 - bool 1961 - 1962 1980 config SYS_HAS_CPU_R4X00 1963 1981 bool 1964 1982 ··· 1965 1989 config SYS_HAS_CPU_R5000 1966 1990 bool 1967 1991 1968 - config SYS_HAS_CPU_R5432 1969 - bool 1970 - 1971 1992 config SYS_HAS_CPU_R5500 1972 1993 bool 1973 1994 1974 1995 config SYS_HAS_CPU_NEVADA 1975 - bool 1976 - 1977 - config SYS_HAS_CPU_R8000 1978 1996 bool 1979 1997 1980 1998 config SYS_HAS_CPU_R10000 ··· 2088 2118 bool 2089 2119 config CPU_SUPPORTS_HUGEPAGES 2090 2120 bool 2121 + depends on !(32BIT && (ARCH_PHYS_ADDR_T_64BIT || EVA)) 2091 2122 config CPU_SUPPORTS_UNCACHED_ACCELERATED 2092 2123 bool 2093 2124 config MIPS_PGD_C0_CONTEXT ··· 2171 2200 2172 2201 config PAGE_SIZE_8KB 2173 2202 bool "8kB" 2174 - depends on CPU_R8000 || CPU_CAVIUM_OCTEON 2203 + depends on CPU_CAVIUM_OCTEON 2175 2204 depends on !MIPS_VA_BITS_48 2176 2205 help 2177 2206 Using 8kB page size will result in higher performance kernel at 2178 2207 the price of higher memory consumption. This option is available 2179 - only on R8000 and cnMIPS processors. Note that you will need a 2180 - suitable Linux distribution to support this. 2208 + only on cnMIPS processors. Note that you will need a suitable Linux 2209 + distribution to support this. 2181 2210 2182 2211 config PAGE_SIZE_16KB 2183 2212 bool "16kB" ··· 2268 2297 2269 2298 config CPU_GENERIC_DUMP_TLB 2270 2299 bool 2271 - default y if !(CPU_R3000 || CPU_R8000 || CPU_TX39XX) 2300 + default y if !(CPU_R3000 || CPU_TX39XX) 2272 2301 2273 2302 config MIPS_FP_SUPPORT 2274 2303 bool "Floating Point support" if EXPERT ··· 2290 2319 depends on MIPS_FP_SUPPORT 2291 2320 default y if CPU_R3000 || CPU_TX39XX 2292 2321 2322 + config CPU_R3K_TLB 2323 + bool 2324 + 2293 2325 config CPU_R4K_FPU 2294 2326 bool 2295 2327 depends on MIPS_FP_SUPPORT ··· 2300 2326 2301 2327 config CPU_R4K_CACHE_TLB 2302 2328 bool 2303 - default y if !(CPU_R3000 || CPU_R8000 || CPU_SB1 || CPU_TX39XX || CPU_CAVIUM_OCTEON) 2329 + default y if !(CPU_R3K_TLB || CPU_SB1 || CPU_CAVIUM_OCTEON) 2304 2330 2305 2331 config MIPS_MT_SMP 2306 2332 bool "MIPS MT SMP support (1 TC on each available VPE)" ··· 2557 2583 config MIPS_ASID_SHIFT 2558 2584 int 2559 2585 default 6 if CPU_R3000 || CPU_TX39XX 2560 - default 4 if CPU_R8000 2561 2586 default 0 2562 2587 2563 2588 config MIPS_ASID_BITS ··· 3047 3074 default y 3048 3075 3049 3076 config STACKTRACE_SUPPORT 3050 - bool 3051 - default y 3052 - 3053 - config HAVE_LATENCYTOP_SUPPORT 3054 3077 bool 3055 3078 default y 3056 3079
-4
arch/mips/Makefile
··· 163 163 # 164 164 cflags-$(CONFIG_CPU_R3000) += -march=r3000 165 165 cflags-$(CONFIG_CPU_TX39XX) += -march=r3900 166 - cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap 167 166 cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap 168 167 cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap 169 168 cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap ··· 173 174 cflags-$(CONFIG_CPU_MIPS64_R2) += -march=mips64r2 -Wa,--trap 174 175 cflags-$(CONFIG_CPU_MIPS64_R6) += -march=mips64r6 -Wa,--trap 175 176 cflags-$(CONFIG_CPU_R5000) += -march=r5000 -Wa,--trap 176 - cflags-$(CONFIG_CPU_R5432) += $(call cc-option,-march=r5400,-march=r5000) \ 177 - -Wa,--trap 178 177 cflags-$(CONFIG_CPU_R5500) += $(call cc-option,-march=r5500,-march=r5000) \ 179 178 -Wa,--trap 180 179 cflags-$(CONFIG_CPU_NEVADA) += $(call cc-option,-march=rm5200,-march=r5000) \ ··· 183 186 -Wa,--trap 184 187 cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-mno-mdmx) 185 188 cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-mno-mips3d) 186 - cflags-$(CONFIG_CPU_R8000) += -march=r8000 -Wa,--trap 187 189 cflags-$(CONFIG_CPU_R10000) += $(call cc-option,-march=r10000,-march=r8000) \ 188 190 -Wa,--trap 189 191 cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += $(call cc-option,-march=octeon) -Wa,--trap
+1
arch/mips/bcm47xx/board.c
··· 160 160 {{BCM47XX_BOARD_LUXUL_XVW_P30_V1, "Luxul XVW-P30 V1"}, "luxul_xvwp30_v1"}, 161 161 {{BCM47XX_BOARD_LUXUL_XWR_600_V1, "Luxul XWR-600 V1"}, "luxul_xwr600_v1"}, 162 162 {{BCM47XX_BOARD_LUXUL_XWR_1750_V1, "Luxul XWR-1750 V1"}, "luxul_xwr1750_v1"}, 163 + {{BCM47XX_BOARD_NETGEAR_R6200_V1, "Netgear R6200 V1"}, "U12H192T00_NETGEAR"}, 163 164 {{BCM47XX_BOARD_NETGEAR_WGR614V8, "Netgear WGR614 V8"}, "U12H072T00_NETGEAR"}, 164 165 {{BCM47XX_BOARD_NETGEAR_WGR614V9, "Netgear WGR614 V9"}, "U12H094T00_NETGEAR"}, 165 166 {{BCM47XX_BOARD_NETGEAR_WGR614_V10, "Netgear WGR614 V10"}, "U12H139T01_NETGEAR"},
+10
arch/mips/bcm47xx/buttons.c
··· 385 385 /* Netgear */ 386 386 387 387 static const struct gpio_keys_button 388 + bcm47xx_buttons_netgear_r6200_v1[] __initconst = { 389 + BCM47XX_GPIO_KEY(2, KEY_RFKILL), 390 + BCM47XX_GPIO_KEY(3, KEY_RESTART), 391 + BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), 392 + }; 393 + 394 + static const struct gpio_keys_button 388 395 bcm47xx_buttons_netgear_wndr3400v1[] __initconst = { 389 396 BCM47XX_GPIO_KEY(4, KEY_RESTART), 390 397 BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON), ··· 671 664 err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_wr850gv2v3); 672 665 break; 673 666 667 + case BCM47XX_BOARD_NETGEAR_R6200_V1: 668 + err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_r6200_v1); 669 + break; 674 670 case BCM47XX_BOARD_NETGEAR_WNDR3400V1: 675 671 err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr3400v1); 676 672 break;
+9 -3
arch/mips/boot/dts/brcm/bcm3368.dtsi
··· 51 51 compatible = "simple-bus"; 52 52 ranges; 53 53 54 - periph_cntl: syscon@fff8c000 { 54 + clkctl: clock-controller@fff8c004 { 55 + compatible = "brcm,bcm3368-clocks"; 56 + reg = <0xfff8c004 0x4>; 57 + #clock-cells = <1>; 58 + }; 59 + 60 + periph_cntl: syscon@fff8c008 { 55 61 compatible = "syscon"; 56 - reg = <0xfff8c000 0xc>; 62 + reg = <0xfff8c000 0x4>; 57 63 native-endian; 58 64 }; 59 65 60 66 reboot: syscon-reboot@fff8c008 { 61 67 compatible = "syscon-reboot"; 62 68 regmap = <&periph_cntl>; 63 - offset = <0x8>; 69 + offset = <0x0>; 64 70 mask = <0x1>; 65 71 }; 66 72
+9 -3
arch/mips/boot/dts/brcm/bcm63268.dtsi
··· 51 51 compatible = "simple-bus"; 52 52 ranges; 53 53 54 - periph_cntl: syscon@10000000 { 54 + clkctl: clock-controller@10000004 { 55 + compatible = "brcm,bcm63268-clocks"; 56 + reg = <0x10000004 0x4>; 57 + #clock-cells = <1>; 58 + }; 59 + 60 + periph_cntl: syscon@10000008 { 55 61 compatible = "syscon"; 56 - reg = <0x10000000 0x14>; 62 + reg = <0x10000000 0xc>; 57 63 native-endian; 58 64 }; 59 65 60 66 reboot: syscon-reboot@10000008 { 61 67 compatible = "syscon-reboot"; 62 68 regmap = <&periph_cntl>; 63 - offset = <0x8>; 69 + offset = <0x0>; 64 70 mask = <0x1>; 65 71 }; 66 72
+6
arch/mips/boot/dts/brcm/bcm6328.dtsi
··· 51 51 compatible = "simple-bus"; 52 52 ranges; 53 53 54 + clkctl: clock-controller@10000004 { 55 + compatible = "brcm,bcm6328-clocks"; 56 + reg = <0x10000004 0x4>; 57 + #clock-cells = <1>; 58 + }; 59 + 54 60 periph_intc: interrupt-controller@10000020 { 55 61 compatible = "brcm,bcm6345-l1-intc"; 56 62 reg = <0x10000020 0x10>,
+9 -3
arch/mips/boot/dts/brcm/bcm6358.dtsi
··· 51 51 compatible = "simple-bus"; 52 52 ranges; 53 53 54 - periph_cntl: syscon@fffe0000 { 54 + clkctl: clock-controller@fffe0004 { 55 + compatible = "brcm,bcm6358-clocks"; 56 + reg = <0xfffe0004 0x4>; 57 + #clock-cells = <1>; 58 + }; 59 + 60 + periph_cntl: syscon@fffe0008 { 55 61 compatible = "syscon"; 56 - reg = <0xfffe0000 0xc>; 62 + reg = <0xfffe0000 0x4>; 57 63 native-endian; 58 64 }; 59 65 60 66 reboot: syscon-reboot@fffe0008 { 61 67 compatible = "syscon-reboot"; 62 68 regmap = <&periph_cntl>; 63 - offset = <0x8>; 69 + offset = <0x0>; 64 70 mask = <0x1>; 65 71 }; 66 72
+9 -3
arch/mips/boot/dts/brcm/bcm6362.dtsi
··· 51 51 compatible = "simple-bus"; 52 52 ranges; 53 53 54 - periph_cntl: syscon@10000000 { 54 + clkctl: clock-controller@10000004 { 55 + compatible = "brcm,bcm6362-clocks"; 56 + reg = <0x10000004 0x4>; 57 + #clock-cells = <1>; 58 + }; 59 + 60 + periph_cntl: syscon@10000008 { 55 61 compatible = "syscon"; 56 - reg = <0x10000000 0x14>; 62 + reg = <0x10000000 0xc>; 57 63 native-endian; 58 64 }; 59 65 60 66 reboot: syscon-reboot@10000008 { 61 67 compatible = "syscon-reboot"; 62 68 regmap = <&periph_cntl>; 63 - offset = <0x8>; 69 + offset = <0x0>; 64 70 mask = <0x1>; 65 71 }; 66 72
+9 -3
arch/mips/boot/dts/brcm/bcm6368.dtsi
··· 51 51 compatible = "simple-bus"; 52 52 ranges; 53 53 54 - periph_cntl: syscon@10000000 { 54 + clkctl: clock-controller@10000004 { 55 + compatible = "brcm,bcm6368-clocks"; 56 + reg = <0x10000004 0x4>; 57 + #clock-cells = <1>; 58 + }; 59 + 60 + periph_cntl: syscon@100000008 { 55 61 compatible = "syscon"; 56 - reg = <0x10000000 0x14>; 62 + reg = <0x10000000 0xc>; 57 63 native-endian; 58 64 }; 59 65 60 66 reboot: syscon-reboot@10000008 { 61 67 compatible = "syscon-reboot"; 62 68 regmap = <&periph_cntl>; 63 - offset = <0x8>; 69 + offset = <0x0>; 64 70 mask = <0x1>; 65 71 }; 66 72
+7
arch/mips/boot/dts/ingenic/ci20.dts
··· 2 2 /dts-v1/; 3 3 4 4 #include "jz4780.dtsi" 5 + #include <dt-bindings/clock/ingenic,tcu.h> 5 6 #include <dt-bindings/gpio/gpio.h> 6 7 7 8 / { ··· 238 237 groups = "mmc1-1bit-d", "mmc1-4bit-d"; 239 238 bias-disable; 240 239 }; 240 + }; 241 + 242 + &tcu { 243 + /* 3 MHz for the system timer and clocksource */ 244 + assigned-clocks = <&tcu TCU_CLK_TIMER0>, <&tcu TCU_CLK_TIMER1>; 245 + assigned-clock-rates = <3000000>, <3000000>; 241 246 };
+10
arch/mips/boot/dts/ingenic/gcw0.dts
··· 2 2 /dts-v1/; 3 3 4 4 #include "jz4770.dtsi" 5 + #include <dt-bindings/clock/ingenic,tcu.h> 5 6 6 7 / { 7 8 compatible = "gcw,zero", "ingenic,jz4770"; ··· 60 59 &uhc { 61 60 /* The WiFi module is connected to the UHC. */ 62 61 status = "okay"; 62 + }; 63 + 64 + &tcu { 65 + /* 750 kHz for the system timer and clocksource */ 66 + assigned-clocks = <&tcu TCU_CLK_TIMER0>, <&tcu TCU_CLK_TIMER2>; 67 + assigned-clock-rates = <750000>, <750000>; 68 + 69 + /* PWM1 is in use, so reserve channel #2 for the clocksource */ 70 + ingenic,pwm-channels-mask = <0xfa>; 63 71 };
+124 -3
arch/mips/boot/dts/ingenic/jz4740.dtsi
··· 53 53 clock-names = "rtc"; 54 54 }; 55 55 56 + tcu: timer@10002000 { 57 + compatible = "ingenic,jz4740-tcu", "simple-mfd"; 58 + reg = <0x10002000 0x1000>; 59 + #address-cells = <1>; 60 + #size-cells = <1>; 61 + ranges = <0x0 0x10002000 0x1000>; 62 + 63 + #clock-cells = <1>; 64 + 65 + clocks = <&cgu JZ4740_CLK_RTC 66 + &cgu JZ4740_CLK_EXT 67 + &cgu JZ4740_CLK_PCLK 68 + &cgu JZ4740_CLK_TCU>; 69 + clock-names = "rtc", "ext", "pclk", "tcu"; 70 + 71 + interrupt-controller; 72 + #interrupt-cells = <1>; 73 + 74 + interrupt-parent = <&intc>; 75 + interrupts = <23 22 21>; 76 + }; 77 + 56 78 rtc_dev: rtc@10003000 { 57 79 compatible = "ingenic,jz4740-rtc"; 58 80 reg = <0x10003000 0x40>; ··· 154 132 }; 155 133 }; 156 134 135 + aic: audio-controller@10020000 { 136 + compatible = "ingenic,jz4740-i2s"; 137 + reg = <0x10020000 0x38>; 138 + 139 + #sound-dai-cells = <0>; 140 + 141 + interrupt-parent = <&intc>; 142 + interrupts = <18>; 143 + 144 + clocks = <&cgu JZ4740_CLK_AIC>, 145 + <&cgu JZ4740_CLK_I2S>, 146 + <&cgu JZ4740_CLK_EXT>, 147 + <&cgu JZ4740_CLK_PLL_HALF>; 148 + clock-names = "aic", "i2s", "ext", "pll half"; 149 + 150 + dmas = <&dmac 25 0xffffffff>, <&dmac 24 0xffffffff>; 151 + dma-names = "rx", "tx"; 152 + }; 153 + 154 + codec: audio-codec@100200a4 { 155 + compatible = "ingenic,jz4740-codec"; 156 + reg = <0x10020080 0x8>; 157 + 158 + #sound-dai-cells = <0>; 159 + 160 + clocks = <&cgu JZ4740_CLK_AIC>; 161 + clock-names = "aic"; 162 + }; 163 + 164 + mmc: mmc@10021000 { 165 + compatible = "ingenic,jz4740-mmc"; 166 + reg = <0x10021000 0x1000>; 167 + 168 + clocks = <&cgu JZ4740_CLK_MMC>; 169 + clock-names = "mmc"; 170 + 171 + interrupt-parent = <&intc>; 172 + interrupts = <14>; 173 + 174 + dmas = <&dmac 27 0xffffffff>, <&dmac 26 0xffffffff>; 175 + dma-names = "rx", "tx"; 176 + 177 + cap-sd-highspeed; 178 + cap-mmc-highspeed; 179 + cap-sdio-irq; 180 + }; 181 + 157 182 uart0: serial@10030000 { 158 183 compatible = "ingenic,jz4740-uart"; 159 184 reg = <0x10030000 0x100>; ··· 223 154 clock-names = "baud", "module"; 224 155 }; 225 156 157 + adc: adc@10070000 { 158 + compatible = "ingenic,jz4740-adc"; 159 + reg = <0x10070000 0x30>; 160 + #io-channel-cells = <1>; 161 + 162 + clocks = <&cgu JZ4740_CLK_ADC>; 163 + clock-names = "adc"; 164 + 165 + interrupt-parent = <&intc>; 166 + interrupts = <12>; 167 + }; 168 + 169 + nemc: memory-controller@13010000 { 170 + compatible = "ingenic,jz4740-nemc"; 171 + reg = <0x13010000 0x54>; 172 + #address-cells = <2>; 173 + #size-cells = <1>; 174 + ranges = <1 0 0x18000000 0x4000000 175 + 2 0 0x14000000 0x4000000 176 + 3 0 0x0c000000 0x4000000 177 + 4 0 0x08000000 0x4000000>; 178 + 179 + clocks = <&cgu JZ4740_CLK_MCLK>; 180 + }; 181 + 182 + ecc: ecc-controller@13010100 { 183 + compatible = "ingenic,jz4740-ecc"; 184 + reg = <0x13010100 0x2C>; 185 + 186 + clocks = <&cgu JZ4740_CLK_MCLK>; 187 + }; 188 + 226 189 dmac: dma-controller@13020000 { 227 190 compatible = "ingenic,jz4740-dma"; 228 191 reg = <0x13020000 0xbc ··· 265 164 interrupts = <20>; 266 165 267 166 clocks = <&cgu JZ4740_CLK_DMA>; 268 - 269 - /* Disable dmac until we have something that uses it */ 270 - status = "disabled"; 271 167 }; 272 168 273 169 uhc: uhc@13030000 { ··· 279 181 interrupts = <3>; 280 182 281 183 status = "disabled"; 184 + }; 185 + 186 + udc: usb@13040000 { 187 + compatible = "ingenic,jz4740-musb"; 188 + reg = <0x13040000 0x10000>; 189 + 190 + interrupt-parent = <&intc>; 191 + interrupts = <24>; 192 + interrupt-names = "mc"; 193 + 194 + clocks = <&cgu JZ4740_CLK_UDC>; 195 + clock-names = "udc"; 196 + }; 197 + 198 + lcd: lcd-controller@13050000 { 199 + compatible = "ingenic,jz4740-lcd"; 200 + reg = <0x13050000 0x1000>; 201 + 202 + interrupt-parent = <&intc>; 203 + interrupts = <30>; 204 + 205 + clocks = <&cgu JZ4740_CLK_LCD_PCLK>, <&cgu JZ4740_CLK_LCD>; 206 + clock-names = "lcd_pclk", "lcd"; 282 207 }; 283 208 };
+21
arch/mips/boot/dts/ingenic/jz4770.dtsi
··· 46 46 #clock-cells = <1>; 47 47 }; 48 48 49 + tcu: timer@10002000 { 50 + compatible = "ingenic,jz4770-tcu", "simple-mfd"; 51 + reg = <0x10002000 0x1000>; 52 + #address-cells = <1>; 53 + #size-cells = <1>; 54 + ranges = <0x0 0x10002000 0x1000>; 55 + 56 + #clock-cells = <1>; 57 + 58 + clocks = <&cgu JZ4770_CLK_RTC 59 + &cgu JZ4770_CLK_EXT 60 + &cgu JZ4770_CLK_PCLK>; 61 + clock-names = "rtc", "ext", "pclk"; 62 + 63 + interrupt-controller; 64 + #interrupt-cells = <1>; 65 + 66 + interrupt-parent = <&intc>; 67 + interrupts = <27 26 25>; 68 + }; 69 + 49 70 pinctrl: pin-controller@10010000 { 50 71 compatible = "ingenic,jz4770-pinctrl"; 51 72 reg = <0x10010000 0x600>;
+23
arch/mips/boot/dts/ingenic/jz4780.dtsi
··· 46 46 #clock-cells = <1>; 47 47 }; 48 48 49 + tcu: timer@10002000 { 50 + compatible = "ingenic,jz4780-tcu", 51 + "ingenic,jz4770-tcu", 52 + "simple-mfd"; 53 + reg = <0x10002000 0x1000>; 54 + #address-cells = <1>; 55 + #size-cells = <1>; 56 + ranges = <0x0 0x10002000 0x1000>; 57 + 58 + #clock-cells = <1>; 59 + 60 + clocks = <&cgu JZ4780_CLK_RTCLK 61 + &cgu JZ4780_CLK_EXCLK 62 + &cgu JZ4780_CLK_PCLK>; 63 + clock-names = "rtc", "ext", "pclk"; 64 + 65 + interrupt-controller; 66 + #interrupt-cells = <1>; 67 + 68 + interrupt-parent = <&intc>; 69 + interrupts = <27 26 25>; 70 + }; 71 + 49 72 rtc_dev: rtc@10003000 { 50 73 compatible = "ingenic,jz4780-rtc"; 51 74 reg = <0x10003000 0x4c>;
+325
arch/mips/boot/dts/ingenic/qi_lb60.dts
··· 3 3 4 4 #include "jz4740.dtsi" 5 5 6 + #include <dt-bindings/gpio/gpio.h> 7 + #include <dt-bindings/iio/adc/ingenic,adc.h> 8 + #include <dt-bindings/clock/ingenic,tcu.h> 9 + #include <dt-bindings/input/input.h> 10 + 11 + #define KEY_QI_QI KEY_F13 12 + #define KEY_QI_UPRED KEY_RIGHTALT 13 + #define KEY_QI_VOLUP KEY_VOLUMEUP 14 + #define KEY_QI_VOLDOWN KEY_VOLUMEDOWN 15 + #define KEY_QI_FN KEY_LEFTCTRL 16 + 6 17 / { 7 18 compatible = "qi,lb60", "ingenic,jz4740"; 8 19 9 20 chosen { 10 21 stdout-path = &uart0; 22 + }; 23 + 24 + vcc: regulator@0 { 25 + compatible = "regulator-fixed"; 26 + regulator-name = "vcc"; 27 + 28 + regulator-min-microvolt = <3300000>; 29 + regulator-max-microvolt = <3300000>; 30 + regulator-always-on; 31 + }; 32 + 33 + mmc_power: regulator@1 { 34 + compatible = "regulator-fixed"; 35 + regulator-name = "mmc_vcc"; 36 + gpio = <&gpd 2 0>; 37 + 38 + regulator-min-microvolt = <3300000>; 39 + regulator-max-microvolt = <3300000>; 40 + }; 41 + 42 + amp_supply: regulator@2 { 43 + compatible = "regulator-fixed"; 44 + regulator-name = "amp_supply"; 45 + gpio = <&gpd 4 0>; 46 + enable-active-high; 47 + 48 + regulator-min-microvolt = <3300000>; 49 + regulator-max-microvolt = <3300000>; 50 + }; 51 + 52 + amp: analog-amplifier { 53 + compatible = "simple-audio-amplifier"; 54 + enable-gpios = <&gpb 29 GPIO_ACTIVE_HIGH>; 55 + VCC-supply = <&amp_supply>; 56 + }; 57 + 58 + sound { 59 + compatible = "simple-audio-card"; 60 + 61 + simple-audio-card,name = "QI LB60"; 62 + simple-audio-card,format = "i2s"; 63 + 64 + simple-audio-card,widgets = 65 + "Speaker", "Speaker", 66 + "Microphone", "Mic"; 67 + simple-audio-card,routing = 68 + "MIC", "Mic", 69 + "Speaker", "OUTL", 70 + "Speaker", "OUTR", 71 + "INL", "LOUT", 72 + "INL", "ROUT"; 73 + 74 + simple-audio-card,aux-devs = <&amp>; 75 + 76 + simple-audio-card,bitclock-master = <&dai_codec>; 77 + simple-audio-card,frame-master = <&dai_codec>; 78 + 79 + dai_cpu: simple-audio-card,cpu { 80 + sound-dai = <&aic>; 81 + }; 82 + 83 + dai_codec: simple-audio-card,codec { 84 + sound-dai = <&codec>; 85 + }; 86 + }; 87 + 88 + keys { 89 + compatible = "gpio-keys"; 90 + 91 + key { 92 + label = "Power"; 93 + wakeup-source; 94 + linux,code = <KEY_POWER>; 95 + gpios = <&gpd 29 GPIO_ACTIVE_LOW>; 96 + }; 97 + }; 98 + 99 + keyboard { 100 + compatible = "gpio-matrix-keypad"; 101 + 102 + col-scan-delay-us = <10>; 103 + debounce-delay-ms = <10>; 104 + wakeup-source; 105 + 106 + row-gpios = <&gpd 18 0 &gpd 19 0 &gpd 20 0 &gpd 21 0 107 + &gpd 22 0 &gpd 23 0 &gpd 24 0 &gpd 26 0>; 108 + col-gpios = <&gpc 10 0 &gpc 11 0 &gpc 12 0 &gpc 13 0 109 + &gpc 14 0 &gpc 15 0 &gpc 16 0 &gpc 17 0>; 110 + gpio-activelow; 111 + 112 + linux,keymap = < 113 + MATRIX_KEY(0, 0, KEY_F1) /* S2 */ 114 + MATRIX_KEY(0, 1, KEY_F2) /* S3 */ 115 + MATRIX_KEY(0, 2, KEY_F3) /* S4 */ 116 + MATRIX_KEY(0, 3, KEY_F4) /* S5 */ 117 + MATRIX_KEY(0, 4, KEY_F5) /* S6 */ 118 + MATRIX_KEY(0, 5, KEY_F6) /* S7 */ 119 + MATRIX_KEY(0, 6, KEY_F7) /* S8 */ 120 + 121 + MATRIX_KEY(1, 0, KEY_Q) /* S10 */ 122 + MATRIX_KEY(1, 1, KEY_W) /* S11 */ 123 + MATRIX_KEY(1, 2, KEY_E) /* S12 */ 124 + MATRIX_KEY(1, 3, KEY_R) /* S13 */ 125 + MATRIX_KEY(1, 4, KEY_T) /* S14 */ 126 + MATRIX_KEY(1, 5, KEY_Y) /* S15 */ 127 + MATRIX_KEY(1, 6, KEY_U) /* S16 */ 128 + MATRIX_KEY(1, 7, KEY_I) /* S17 */ 129 + MATRIX_KEY(2, 0, KEY_A) /* S18 */ 130 + MATRIX_KEY(2, 1, KEY_S) /* S19 */ 131 + MATRIX_KEY(2, 2, KEY_D) /* S20 */ 132 + MATRIX_KEY(2, 3, KEY_F) /* S21 */ 133 + MATRIX_KEY(2, 4, KEY_G) /* S22 */ 134 + MATRIX_KEY(2, 5, KEY_H) /* S23 */ 135 + MATRIX_KEY(2, 6, KEY_J) /* S24 */ 136 + MATRIX_KEY(2, 7, KEY_K) /* S25 */ 137 + MATRIX_KEY(3, 0, KEY_ESC) /* S26 */ 138 + MATRIX_KEY(3, 1, KEY_Z) /* S27 */ 139 + MATRIX_KEY(3, 2, KEY_X) /* S28 */ 140 + MATRIX_KEY(3, 3, KEY_C) /* S29 */ 141 + MATRIX_KEY(3, 4, KEY_V) /* S30 */ 142 + MATRIX_KEY(3, 5, KEY_B) /* S31 */ 143 + MATRIX_KEY(3, 6, KEY_N) /* S32 */ 144 + MATRIX_KEY(3, 7, KEY_M) /* S33 */ 145 + MATRIX_KEY(4, 0, KEY_TAB) /* S34 */ 146 + MATRIX_KEY(4, 1, KEY_CAPSLOCK) /* S35 */ 147 + MATRIX_KEY(4, 2, KEY_BACKSLASH) /* S36 */ 148 + MATRIX_KEY(4, 3, KEY_APOSTROPHE) /* S37 */ 149 + MATRIX_KEY(4, 4, KEY_COMMA) /* S38 */ 150 + MATRIX_KEY(4, 5, KEY_DOT) /* S39 */ 151 + MATRIX_KEY(4, 6, KEY_SLASH) /* S40 */ 152 + MATRIX_KEY(4, 7, KEY_UP) /* S41 */ 153 + MATRIX_KEY(5, 0, KEY_O) /* S42 */ 154 + MATRIX_KEY(5, 1, KEY_L) /* S43 */ 155 + MATRIX_KEY(5, 2, KEY_EQUAL) /* S44 */ 156 + MATRIX_KEY(5, 3, KEY_QI_UPRED) /* S45 */ 157 + MATRIX_KEY(5, 4, KEY_SPACE) /* S46 */ 158 + MATRIX_KEY(5, 5, KEY_QI_QI) /* S47 */ 159 + MATRIX_KEY(5, 6, KEY_RIGHTCTRL) /* S48 */ 160 + MATRIX_KEY(5, 7, KEY_LEFT) /* S49 */ 161 + MATRIX_KEY(6, 0, KEY_F8) /* S50 */ 162 + MATRIX_KEY(6, 1, KEY_P) /* S51 */ 163 + MATRIX_KEY(6, 2, KEY_BACKSPACE)/* S52 */ 164 + MATRIX_KEY(6, 3, KEY_ENTER) /* S53 */ 165 + MATRIX_KEY(6, 4, KEY_QI_VOLUP) /* S54 */ 166 + MATRIX_KEY(6, 5, KEY_QI_VOLDOWN) /* S55 */ 167 + MATRIX_KEY(6, 6, KEY_DOWN) /* S56 */ 168 + MATRIX_KEY(6, 7, KEY_RIGHT) /* S57 */ 169 + 170 + MATRIX_KEY(7, 0, KEY_LEFTSHIFT) /* S58 */ 171 + MATRIX_KEY(7, 1, KEY_LEFTALT) /* S59 */ 172 + MATRIX_KEY(7, 2, KEY_QI_FN) /* S60 */ 173 + >; 174 + }; 175 + 176 + spi { 177 + compatible = "spi-gpio"; 178 + #address-cells = <1>; 179 + #size-cells = <0>; 180 + 181 + sck-gpios = <&gpc 23 GPIO_ACTIVE_HIGH>; 182 + mosi-gpios = <&gpc 22 GPIO_ACTIVE_HIGH>; 183 + cs-gpios = <&gpc 21 GPIO_ACTIVE_LOW>; 184 + num-chipselects = <1>; 185 + }; 186 + 187 + usb_charger: charger { 188 + compatible = "gpio-charger"; 189 + charger-type = "usb-sdp"; 190 + gpios = <&gpd 28 GPIO_ACTIVE_LOW>; 191 + status-gpios = <&gpc 27 GPIO_ACTIVE_LOW>; 192 + }; 193 + 194 + simple_battery: battery { 195 + compatible = "simple-battery"; 196 + voltage-min-design-microvolt = <3600000>; 197 + voltage-max-design-microvolt = <4200000>; 198 + }; 199 + 200 + pmu { 201 + compatible = "ingenic,jz4740-battery"; 202 + io-channels = <&adc INGENIC_ADC_BATTERY>; 203 + io-channel-names = "battery"; 204 + power-supplies = <&usb_charger>; 205 + monitored-battery = <&simple_battery>; 206 + }; 207 + 208 + hwmon { 209 + compatible = "iio-hwmon"; 210 + io-channels = <&adc INGENIC_ADC_AUX>; 211 + }; 212 + 213 + panel: panel { 214 + compatible = "giantplus,gpm940b0"; 215 + 216 + power-supply = <&vcc>; 217 + 218 + port { 219 + panel_input: endpoint { 220 + remote-endpoint = <&panel_output>; 221 + }; 222 + }; 223 + }; 224 + 225 + usb_phy: usb-phy { 226 + compatible = "usb-nop-xceiv"; 227 + #phy-cells = <0>; 228 + 229 + vcc-supply = <&vcc>; 11 230 }; 12 231 }; 13 232 ··· 243 24 pinctrl-0 = <&pins_uart0>; 244 25 }; 245 26 27 + &uart1 { 28 + status = "disabled"; 29 + }; 30 + 31 + &nemc { 32 + nandc: nand-controller@1 { 33 + compatible = "ingenic,jz4740-nand"; 34 + reg = <1 0 0x4000000>; 35 + 36 + #address-cells = <1>; 37 + #size-cells = <0>; 38 + 39 + ingenic,bch-controller = <&ecc>; 40 + 41 + pinctrl-names = "default"; 42 + pinctrl-0 = <&pins_nemc>; 43 + 44 + rb-gpios = <&gpc 30 GPIO_ACTIVE_LOW>; 45 + 46 + nand@1 { 47 + reg = <1>; 48 + 49 + nand-ecc-step-size = <512>; 50 + nand-ecc-strength = <4>; 51 + nand-ecc-mode = "hw"; 52 + nand-is-boot-medium; 53 + nand-on-flash-bbt; 54 + 55 + partitions { 56 + compatible = "fixed-partitions"; 57 + #address-cells = <1>; 58 + #size-cells = <1>; 59 + 60 + partition@0 { 61 + label = "boot"; 62 + reg = <0x0 0x400000>; 63 + }; 64 + 65 + partition@400000 { 66 + label = "kernel"; 67 + reg = <0x400000 0x400000>; 68 + }; 69 + 70 + partition@800000 { 71 + label = "rootfs"; 72 + reg = <0x800000 0x0>; 73 + }; 74 + }; 75 + }; 76 + }; 77 + }; 78 + 79 + &lcd { 80 + pinctrl-names = "default"; 81 + pinctrl-0 = <&pins_lcd>; 82 + 83 + port { 84 + panel_output: endpoint { 85 + remote-endpoint = <&panel_input>; 86 + }; 87 + }; 88 + }; 89 + 90 + &udc { 91 + phys = <&usb_phy>; 92 + }; 93 + 246 94 &pinctrl { 95 + pins_lcd: lcd { 96 + function = "lcd"; 97 + groups = "lcd-8bit"; 98 + }; 99 + 100 + pins_nemc: nemc { 101 + function = "nand"; 102 + groups = "nand-cs1"; 103 + }; 104 + 247 105 pins_uart0: uart0 { 248 106 function = "uart0"; 249 107 groups = "uart0-data"; 250 108 bias-disable; 251 109 }; 110 + 111 + pins_mmc: mmc { 112 + mmc { 113 + function = "mmc"; 114 + groups = "mmc-1bit", "mmc-4bit"; 115 + bias-disable; 116 + }; 117 + 118 + mmc-gpios { 119 + pins = "PD0", "PD2"; 120 + bias-disable; 121 + }; 122 + }; 123 + }; 124 + 125 + &mmc { 126 + bus-width = <4>; 127 + max-frequency = <24000000>; 128 + cd-gpios = <&gpd 0 GPIO_ACTIVE_HIGH>; 129 + vmmc-supply = <&mmc_power>; 130 + 131 + pinctrl-names = "default"; 132 + pinctrl-0 = <&pins_mmc>; 133 + }; 134 + 135 + &tcu { 136 + /* 750 kHz for the system timer and clocksource */ 137 + assigned-clocks = <&tcu TCU_CLK_TIMER0>, <&tcu TCU_CLK_TIMER1>; 138 + assigned-clock-rates = <750000>, <750000>; 252 139 };
+4 -3
arch/mips/boot/dts/mscc/ocelot.dtsi
··· 120 120 reg = <0x1010000 0x10000>, 121 121 <0x1030000 0x10000>, 122 122 <0x1080000 0x100>, 123 + <0x10e0000 0x10000>, 123 124 <0x11e0000 0x100>, 124 125 <0x11f0000 0x100>, 125 126 <0x1200000 0x100>, ··· 135 134 <0x1800000 0x80000>, 136 135 <0x1880000 0x10000>, 137 136 <0x1060000 0x10000>; 138 - reg-names = "sys", "rew", "qs", "port0", "port1", 137 + reg-names = "sys", "rew", "qs", "ptp", "port0", "port1", 139 138 "port2", "port3", "port4", "port5", "port6", 140 139 "port7", "port8", "port9", "port10", "qsys", 141 140 "ana", "s2"; 142 - interrupts = <21 22>; 143 - interrupt-names = "xtr", "inj"; 141 + interrupts = <18 21 22>; 142 + interrupt-names = "ptp_rdy", "xtr", "inj"; 144 143 145 144 ethernet-ports { 146 145 #address-cells = <1>;
+6 -10
arch/mips/cavium-octeon/dma-octeon.c
··· 190 190 191 191 void __init plat_swiotlb_setup(void) 192 192 { 193 - int i; 193 + struct memblock_region *mem; 194 194 phys_addr_t max_addr; 195 195 phys_addr_t addr_size; 196 196 size_t swiotlbsize; ··· 199 199 max_addr = 0; 200 200 addr_size = 0; 201 201 202 - for (i = 0 ; i < boot_mem_map.nr_map; i++) { 203 - struct boot_mem_map_entry *e = &boot_mem_map.map[i]; 204 - if (e->type != BOOT_MEM_RAM && e->type != BOOT_MEM_INIT_RAM) 205 - continue; 206 - 202 + for_each_memblock(memory, mem) { 207 203 /* These addresses map low for PCI. */ 208 - if (e->addr > 0x410000000ull && !OCTEON_IS_OCTEON2()) 204 + if (mem->base > 0x410000000ull && !OCTEON_IS_OCTEON2()) 209 205 continue; 210 206 211 - addr_size += e->size; 207 + addr_size += mem->size; 212 208 213 - if (max_addr < e->addr + e->size) 214 - max_addr = e->addr + e->size; 209 + if (max_addr < mem->base + mem->size) 210 + max_addr = mem->base + mem->size; 215 211 216 212 } 217 213
+1 -2
arch/mips/cavium-octeon/setup.c
··· 1007 1007 * regions next to each other. 1008 1008 */ 1009 1009 cvmx_bootmem_lock(); 1010 - while ((boot_mem_map.nr_map < BOOT_MEM_MAP_MAX) 1011 - && (total < max_memory)) { 1010 + while (total < max_memory) { 1012 1011 memory = cvmx_bootmem_phy_alloc(mem_alloc_size, 1013 1012 __pa_symbol(&_end), -1, 1014 1013 0x100000,
+22 -22
arch/mips/configs/qi_lb60_defconfig
··· 1 1 # CONFIG_LOCALVERSION_AUTO is not set 2 2 CONFIG_SYSVIPC=y 3 3 # CONFIG_CROSS_MEMORY_ATTACH is not set 4 - CONFIG_PREEMPT=y 5 4 CONFIG_LOG_BUF_SHIFT=14 6 5 CONFIG_SYSCTL_SYSCALL=y 7 6 CONFIG_KALLSYMS_ALL=y ··· 16 17 # CONFIG_BLK_DEV_BSG is not set 17 18 CONFIG_PARTITION_ADVANCED=y 18 19 # CONFIG_EFI_PARTITION is not set 19 - # CONFIG_IOSCHED_CFQ is not set 20 20 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set 21 - # CONFIG_COMPACTION is not set 21 + CONFIG_CMA=y 22 22 CONFIG_NET=y 23 23 CONFIG_PACKET=y 24 24 CONFIG_UNIX=y ··· 29 31 CONFIG_IP_ROUTE_VERBOSE=y 30 32 CONFIG_IP_MROUTE=y 31 33 CONFIG_IP_MROUTE_MULTIPLE_TABLES=y 32 - # CONFIG_INET_XFRM_MODE_TRANSPORT is not set 33 - # CONFIG_INET_XFRM_MODE_TUNNEL is not set 34 - # CONFIG_INET_XFRM_MODE_BEET is not set 35 34 # CONFIG_INET_DIAG is not set 36 35 CONFIG_TCP_CONG_ADVANCED=y 37 36 # CONFIG_TCP_CONG_BIC is not set ··· 39 44 CONFIG_MTD=y 40 45 CONFIG_MTD_BLOCK=y 41 46 CONFIG_MTD_RAW_NAND=y 42 - CONFIG_MTD_NAND_JZ4740=y 47 + CONFIG_MTD_NAND_JZ4780=y 48 + CONFIG_MTD_NAND_JZ4740_ECC=y 43 49 CONFIG_MTD_UBI=y 44 50 CONFIG_NETDEVICES=y 45 51 # CONFIG_WLAN is not set ··· 62 66 CONFIG_SPI=y 63 67 CONFIG_SPI_GPIO=y 64 68 CONFIG_POWER_SUPPLY=y 65 - CONFIG_BATTERY_JZ4740=y 69 + CONFIG_BATTERY_INGENIC=y 66 70 CONFIG_CHARGER_GPIO=y 67 - # CONFIG_HWMON is not set 71 + CONFIG_SENSORS_IIO_HWMON=y 68 72 CONFIG_WATCHDOG=y 69 73 CONFIG_JZ4740_WDT=y 70 - CONFIG_MFD_JZ4740_ADC=y 71 74 CONFIG_REGULATOR=y 72 75 CONFIG_REGULATOR_FIXED_VOLTAGE=y 73 - CONFIG_FB=y 74 - CONFIG_FB_JZ4740=y 75 - CONFIG_LCD_CLASS_DEVICE=y 76 - # CONFIG_BACKLIGHT_CLASS_DEVICE is not set 76 + CONFIG_DRM=y 77 + CONFIG_DRM_FBDEV_OVERALLOC=200 78 + CONFIG_DRM_PANEL_SIMPLE=y 79 + CONFIG_DRM_INGENIC=y 80 + # CONFIG_LCD_CLASS_DEVICE is not set 81 + CONFIG_BACKLIGHT_CLASS_DEVICE=y 82 + # CONFIG_BACKLIGHT_GENERIC is not set 77 83 # CONFIG_VGA_CONSOLE is not set 78 84 CONFIG_FRAMEBUFFER_CONSOLE=y 79 85 CONFIG_LOGO=y ··· 90 92 # CONFIG_SND_SPI is not set 91 93 # CONFIG_SND_MIPS is not set 92 94 CONFIG_SND_SOC=y 93 - CONFIG_SND_JZ4740_SOC=y 94 - CONFIG_SND_JZ4740_SOC_QI_LB60=y 95 - CONFIG_USB=y 96 - CONFIG_USB_OTG_BLACKLIST_HUB=y 95 + CONFIG_SND_JZ4740_SOC_I2S=y 96 + CONFIG_SND_SOC_JZ4740_CODEC=y 97 + CONFIG_SND_SOC_SIMPLE_AMPLIFIER=y 98 + CONFIG_SND_SIMPLE_CARD=y 97 99 CONFIG_USB_MUSB_HDRC=y 98 - CONFIG_USB_MUSB_GADGET=y 99 100 CONFIG_USB_MUSB_JZ4740=y 101 + CONFIG_USB_INVENTRA_DMA=y 100 102 CONFIG_NOP_USB_XCEIV=y 101 103 CONFIG_USB_GADGET=y 102 104 CONFIG_USB_GADGET_DEBUG=y ··· 107 109 CONFIG_RTC_CLASS=y 108 110 CONFIG_RTC_DRV_JZ4740=y 109 111 CONFIG_DMADEVICES=y 110 - CONFIG_DMA_JZ4740=y 112 + CONFIG_DMA_JZ4780=y 113 + CONFIG_MEMORY=y 114 + CONFIG_IIO=y 115 + CONFIG_INGENIC_ADC=y 111 116 CONFIG_PWM=y 112 117 CONFIG_PWM_JZ4740=y 113 - CONFIG_EXT2_FS=y 114 - CONFIG_EXT3_FS=y 118 + CONFIG_EXT4_FS=y 115 119 # CONFIG_DNOTIFY is not set 116 120 CONFIG_VFAT_FS=y 117 121 CONFIG_PROC_KCORE=y
+18 -6
arch/mips/fw/arc/memory.c
··· 27 27 28 28 #undef DEBUG 29 29 30 + #define MAX_PROM_MEM 5 31 + static phys_addr_t prom_mem_base[MAX_PROM_MEM] __initdata; 32 + static phys_addr_t prom_mem_size[MAX_PROM_MEM] __initdata; 33 + static unsigned int nr_prom_mem __initdata; 34 + 30 35 /* 31 36 * For ARC firmware memory functions the unit of meassuring memory is always 32 37 * a 4k page of memory ··· 134 129 } 135 130 #endif 136 131 132 + nr_prom_mem = 0; 137 133 p = PROM_NULL_MDESC; 138 134 while ((p = ArcGetMemoryDescriptor(p))) { 139 135 unsigned long base, size; ··· 145 139 type = prom_memtype_classify(p->type); 146 140 147 141 add_memory_region(base, size, type); 142 + 143 + if (type == BOOT_MEM_ROM_DATA) { 144 + if (nr_prom_mem >= 5) { 145 + pr_err("Too many ROM DATA regions"); 146 + continue; 147 + } 148 + prom_mem_base[nr_prom_mem] = base; 149 + prom_mem_size[nr_prom_mem] = size; 150 + nr_prom_mem++; 151 + } 148 152 } 149 153 } 150 154 ··· 166 150 if (prom_flags & PROM_FLAG_DONT_FREE_TEMP) 167 151 return; 168 152 169 - for (i = 0; i < boot_mem_map.nr_map; i++) { 170 - if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) 171 - continue; 172 - 173 - addr = boot_mem_map.map[i].addr; 153 + for (i = 0; i < nr_prom_mem; i++) { 174 154 free_init_pages("prom memory", 175 - addr, addr + boot_mem_map.map[i].size); 155 + prom_mem_base[i], prom_mem_base[i] + prom_mem_size[i]); 176 156 } 177 157 }
-9
arch/mips/include/asm/addrspace.h
··· 135 135 */ 136 136 #define TO_PHYS_MASK _CONST64_(0x07ffffffffffffff) /* 2^^59 - 1 */ 137 137 138 - #ifndef CONFIG_CPU_R8000 139 - 140 - /* 141 - * The R8000 doesn't have the 32-bit compat spaces so we don't define them 142 - * in order to catch bugs in the source code. 143 - */ 144 - 145 138 #define COMPAT_K1BASE32 _CONST64_(0xffffffffa0000000) 146 139 #define PHYS_TO_COMPATK1(x) ((x) | COMPAT_K1BASE32) /* 32-bit compat k1 */ 147 - 148 - #endif 149 140 150 141 #define KDM_TO_PHYS(x) (_ACAST64_ (x) & TO_PHYS_MASK) 151 142 #define PHYS_TO_K0(x) (_ACAST64_ (x) | CAC_BASE)
+10 -9
arch/mips/include/asm/atomic.h
··· 68 68 "\t" __scbeqz " %0, 1b \n" \ 69 69 " .set pop \n" \ 70 70 : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \ 71 - : "Ir" (i)); \ 71 + : "Ir" (i) : __LLSC_CLOBBER); \ 72 72 } else { \ 73 73 unsigned long flags; \ 74 74 \ ··· 98 98 " .set pop \n" \ 99 99 : "=&r" (result), "=&r" (temp), \ 100 100 "+" GCC_OFF_SMALL_ASM() (v->counter) \ 101 - : "Ir" (i)); \ 101 + : "Ir" (i) : __LLSC_CLOBBER); \ 102 102 } else { \ 103 103 unsigned long flags; \ 104 104 \ ··· 132 132 " move %0, %1 \n" \ 133 133 : "=&r" (result), "=&r" (temp), \ 134 134 "+" GCC_OFF_SMALL_ASM() (v->counter) \ 135 - : "Ir" (i)); \ 135 + : "Ir" (i) : __LLSC_CLOBBER); \ 136 136 } else { \ 137 137 unsigned long flags; \ 138 138 \ ··· 193 193 if (kernel_uses_llsc) { 194 194 int temp; 195 195 196 + loongson_llsc_mb(); 196 197 __asm__ __volatile__( 197 198 " .set push \n" 198 199 " .set "MIPS_ISA_LEVEL" \n" ··· 201 200 " .set pop \n" 202 201 " subu %0, %1, %3 \n" 203 202 " move %1, %0 \n" 204 - " bltz %0, 1f \n" 203 + " bltz %0, 2f \n" 205 204 " .set push \n" 206 205 " .set "MIPS_ISA_LEVEL" \n" 207 206 " sc %1, %2 \n" 208 207 "\t" __scbeqz " %1, 1b \n" 209 - "1: \n" 208 + "2: \n" 210 209 " .set pop \n" 211 210 : "=&r" (result), "=&r" (temp), 212 211 "+" GCC_OFF_SMALL_ASM() (v->counter) 213 - : "Ir" (i)); 212 + : "Ir" (i) : __LLSC_CLOBBER); 214 213 } else { 215 214 unsigned long flags; 216 215 ··· 270 269 "\t" __scbeqz " %0, 1b \n" \ 271 270 " .set pop \n" \ 272 271 : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter) \ 273 - : "Ir" (i)); \ 272 + : "Ir" (i) : __LLSC_CLOBBER); \ 274 273 } else { \ 275 274 unsigned long flags; \ 276 275 \ ··· 300 299 " .set pop \n" \ 301 300 : "=&r" (result), "=&r" (temp), \ 302 301 "+" GCC_OFF_SMALL_ASM() (v->counter) \ 303 - : "Ir" (i)); \ 302 + : "Ir" (i) : __LLSC_CLOBBER); \ 304 303 } else { \ 305 304 unsigned long flags; \ 306 305 \ ··· 334 333 " .set pop \n" \ 335 334 : "=&r" (result), "=&r" (temp), \ 336 335 "+" GCC_OFF_SMALL_ASM() (v->counter) \ 337 - : "Ir" (i)); \ 336 + : "Ir" (i) : __LLSC_CLOBBER); \ 338 337 } else { \ 339 338 unsigned long flags; \ 340 339 \
+28 -16
arch/mips/include/asm/barrier.h
··· 211 211 #define __smp_wmb() barrier() 212 212 #endif 213 213 214 + /* 215 + * When LL/SC does imply order, it must also be a compiler barrier to avoid the 216 + * compiler from reordering where the CPU will not. When it does not imply 217 + * order, the compiler is also free to reorder across the LL/SC loop and 218 + * ordering will be done by smp_llsc_mb() and friends. 219 + */ 214 220 #if defined(CONFIG_WEAK_REORDERING_BEYOND_LLSC) && defined(CONFIG_SMP) 215 221 #define __WEAK_LLSC_MB " sync \n" 222 + #define smp_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory") 223 + #define __LLSC_CLOBBER 216 224 #else 217 225 #define __WEAK_LLSC_MB " \n" 226 + #define smp_llsc_mb() do { } while (0) 227 + #define __LLSC_CLOBBER "memory" 218 228 #endif 219 - 220 - #define smp_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory") 221 229 222 230 #ifdef CONFIG_CPU_CAVIUM_OCTEON 223 231 #define smp_mb__before_llsc() smp_wmb() ··· 246 238 247 239 /* 248 240 * Some Loongson 3 CPUs have a bug wherein execution of a memory access (load, 249 - * store or pref) in between an ll & sc can cause the sc instruction to 241 + * store or prefetch) in between an LL & SC can cause the SC instruction to 250 242 * erroneously succeed, breaking atomicity. Whilst it's unusual to write code 251 243 * containing such sequences, this bug bites harder than we might otherwise 252 244 * expect due to reordering & speculation: 253 245 * 254 - * 1) A memory access appearing prior to the ll in program order may actually 255 - * be executed after the ll - this is the reordering case. 246 + * 1) A memory access appearing prior to the LL in program order may actually 247 + * be executed after the LL - this is the reordering case. 256 248 * 257 - * In order to avoid this we need to place a memory barrier (ie. a sync 258 - * instruction) prior to every ll instruction, in between it & any earlier 259 - * memory access instructions. Many of these cases are already covered by 260 - * smp_mb__before_llsc() but for the remaining cases, typically ones in 261 - * which multiple CPUs may operate on a memory location but ordering is not 262 - * usually guaranteed, we use loongson_llsc_mb() below. 249 + * In order to avoid this we need to place a memory barrier (ie. a SYNC 250 + * instruction) prior to every LL instruction, in between it and any earlier 251 + * memory access instructions. 263 252 * 264 253 * This reordering case is fixed by 3A R2 CPUs, ie. 3A2000 models and later. 265 254 * 266 - * 2) If a conditional branch exists between an ll & sc with a target outside 267 - * of the ll-sc loop, for example an exit upon value mismatch in cmpxchg() 255 + * 2) If a conditional branch exists between an LL & SC with a target outside 256 + * of the LL-SC loop, for example an exit upon value mismatch in cmpxchg() 268 257 * or similar, then misprediction of the branch may allow speculative 269 - * execution of memory accesses from outside of the ll-sc loop. 258 + * execution of memory accesses from outside of the LL-SC loop. 270 259 * 271 - * In order to avoid this we need a memory barrier (ie. a sync instruction) 260 + * In order to avoid this we need a memory barrier (ie. a SYNC instruction) 272 261 * at each affected branch target, for which we also use loongson_llsc_mb() 273 262 * defined below. 274 263 * 275 264 * This case affects all current Loongson 3 CPUs. 265 + * 266 + * The above described cases cause an error in the cache coherence protocol; 267 + * such that the Invalidate of a competing LL-SC goes 'missing' and SC 268 + * erroneously observes its core still has Exclusive state and lets the SC 269 + * proceed. 270 + * 271 + * Therefore the error only occurs on SMP systems. 276 272 */ 277 273 #ifdef CONFIG_CPU_LOONGSON3_WORKAROUNDS /* Loongson-3's LLSC workaround */ 278 - #define loongson_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory") 274 + #define loongson_llsc_mb() __asm__ __volatile__("sync" : : :"memory") 279 275 #else 280 276 #define loongson_llsc_mb() do { } while (0) 281 277 #endif
+30 -17
arch/mips/include/asm/bitops.h
··· 66 66 " beqzl %0, 1b \n" 67 67 " .set pop \n" 68 68 : "=&r" (temp), "=" GCC_OFF_SMALL_ASM() (*m) 69 - : "ir" (1UL << bit), GCC_OFF_SMALL_ASM() (*m)); 69 + : "ir" (1UL << bit), GCC_OFF_SMALL_ASM() (*m) 70 + : __LLSC_CLOBBER); 70 71 #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) 71 72 } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { 72 73 loongson_llsc_mb(); ··· 77 76 " " __INS "%0, %3, %2, 1 \n" 78 77 " " __SC "%0, %1 \n" 79 78 : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) 80 - : "ir" (bit), "r" (~0)); 79 + : "ir" (bit), "r" (~0) 80 + : __LLSC_CLOBBER); 81 81 } while (unlikely(!temp)); 82 82 #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */ 83 83 } else if (kernel_uses_llsc) { ··· 92 90 " " __SC "%0, %1 \n" 93 91 " .set pop \n" 94 92 : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) 95 - : "ir" (1UL << bit)); 93 + : "ir" (1UL << bit) 94 + : __LLSC_CLOBBER); 96 95 } while (unlikely(!temp)); 97 96 } else 98 97 __mips_set_bit(nr, addr); ··· 125 122 " beqzl %0, 1b \n" 126 123 " .set pop \n" 127 124 : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) 128 - : "ir" (~(1UL << bit))); 125 + : "ir" (~(1UL << bit)) 126 + : __LLSC_CLOBBER); 129 127 #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) 130 128 } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { 131 129 loongson_llsc_mb(); ··· 136 132 " " __INS "%0, $0, %2, 1 \n" 137 133 " " __SC "%0, %1 \n" 138 134 : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) 139 - : "ir" (bit)); 135 + : "ir" (bit) 136 + : __LLSC_CLOBBER); 140 137 } while (unlikely(!temp)); 141 138 #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */ 142 139 } else if (kernel_uses_llsc) { ··· 151 146 " " __SC "%0, %1 \n" 152 147 " .set pop \n" 153 148 : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) 154 - : "ir" (~(1UL << bit))); 149 + : "ir" (~(1UL << bit)) 150 + : __LLSC_CLOBBER); 155 151 } while (unlikely(!temp)); 156 152 } else 157 153 __mips_clear_bit(nr, addr); ··· 198 192 " beqzl %0, 1b \n" 199 193 " .set pop \n" 200 194 : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) 201 - : "ir" (1UL << bit)); 195 + : "ir" (1UL << bit) 196 + : __LLSC_CLOBBER); 202 197 } else if (kernel_uses_llsc) { 203 198 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 204 199 unsigned long temp; ··· 214 207 " " __SC "%0, %1 \n" 215 208 " .set pop \n" 216 209 : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m) 217 - : "ir" (1UL << bit)); 210 + : "ir" (1UL << bit) 211 + : __LLSC_CLOBBER); 218 212 } while (unlikely(!temp)); 219 213 } else 220 214 __mips_change_bit(nr, addr); ··· 252 244 " .set pop \n" 253 245 : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) 254 246 : "r" (1UL << bit) 255 - : "memory"); 247 + : __LLSC_CLOBBER); 256 248 } else if (kernel_uses_llsc) { 257 249 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 258 250 unsigned long temp; 259 251 252 + loongson_llsc_mb(); 260 253 do { 261 254 __asm__ __volatile__( 262 255 " .set push \n" ··· 268 259 " .set pop \n" 269 260 : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) 270 261 : "r" (1UL << bit) 271 - : "memory"); 262 + : __LLSC_CLOBBER); 272 263 } while (unlikely(!res)); 273 264 274 265 res = temp & (1UL << bit); ··· 309 300 " .set pop \n" 310 301 : "=&r" (temp), "+m" (*m), "=&r" (res) 311 302 : "r" (1UL << bit) 312 - : "memory"); 303 + : __LLSC_CLOBBER); 313 304 } else if (kernel_uses_llsc) { 314 305 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 315 306 unsigned long temp; 316 307 308 + loongson_llsc_mb(); 317 309 do { 318 310 __asm__ __volatile__( 319 311 " .set push \n" ··· 325 315 " .set pop \n" 326 316 : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) 327 317 : "r" (1UL << bit) 328 - : "memory"); 318 + : __LLSC_CLOBBER); 329 319 } while (unlikely(!res)); 330 320 331 321 res = temp & (1UL << bit); ··· 368 358 " .set pop \n" 369 359 : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) 370 360 : "r" (1UL << bit) 371 - : "memory"); 361 + : __LLSC_CLOBBER); 372 362 #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) 373 363 } else if (kernel_uses_llsc && __builtin_constant_p(nr)) { 374 364 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 375 365 unsigned long temp; 376 366 367 + loongson_llsc_mb(); 377 368 do { 378 369 __asm__ __volatile__( 379 370 " " __LL "%0, %1 # test_and_clear_bit \n" ··· 383 372 " " __SC "%0, %1 \n" 384 373 : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) 385 374 : "ir" (bit) 386 - : "memory"); 375 + : __LLSC_CLOBBER); 387 376 } while (unlikely(!temp)); 388 377 #endif 389 378 } else if (kernel_uses_llsc) { 390 379 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 391 380 unsigned long temp; 392 381 382 + loongson_llsc_mb(); 393 383 do { 394 384 __asm__ __volatile__( 395 385 " .set push \n" ··· 402 390 " .set pop \n" 403 391 : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) 404 392 : "r" (1UL << bit) 405 - : "memory"); 393 + : __LLSC_CLOBBER); 406 394 } while (unlikely(!res)); 407 395 408 396 res = temp & (1UL << bit); ··· 445 433 " .set pop \n" 446 434 : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) 447 435 : "r" (1UL << bit) 448 - : "memory"); 436 + : __LLSC_CLOBBER); 449 437 } else if (kernel_uses_llsc) { 450 438 unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); 451 439 unsigned long temp; 452 440 441 + loongson_llsc_mb(); 453 442 do { 454 443 __asm__ __volatile__( 455 444 " .set push \n" ··· 461 448 " .set pop \n" 462 449 : "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m), "=&r" (res) 463 450 : "r" (1UL << bit) 464 - : "memory"); 451 + : __LLSC_CLOBBER); 465 452 } while (unlikely(!res)); 466 453 467 454 res = temp & (1UL << bit);
+1 -16
arch/mips/include/asm/bootinfo.h
··· 81 81 #define MACH_INGENIC_JZ4740 1 /* JZ4740 SOC */ 82 82 #define MACH_INGENIC_JZ4770 2 /* JZ4770 SOC */ 83 83 #define MACH_INGENIC_JZ4780 3 /* JZ4780 SOC */ 84 + #define MACH_INGENIC_X1000 4 /* X1000 SOC */ 84 85 85 86 extern char *system_type; 86 87 const char *get_system_type(void); 87 88 88 89 extern unsigned long mips_machtype; 89 90 90 - #define BOOT_MEM_MAP_MAX 32 91 91 #define BOOT_MEM_RAM 1 92 92 #define BOOT_MEM_ROM_DATA 2 93 93 #define BOOT_MEM_RESERVED 3 94 94 #define BOOT_MEM_INIT_RAM 4 95 95 #define BOOT_MEM_NOMAP 5 96 - 97 - /* 98 - * A memory map that's built upon what was determined 99 - * or specified on the command line. 100 - */ 101 - struct boot_mem_map { 102 - int nr_map; 103 - struct boot_mem_map_entry { 104 - phys_addr_t addr; /* start of memory segment */ 105 - phys_addr_t size; /* size of memory segment */ 106 - long type; /* type of memory segment */ 107 - } map[BOOT_MEM_MAP_MAX]; 108 - }; 109 - 110 - extern struct boot_mem_map boot_mem_map; 111 96 112 97 extern void add_memory_region(phys_addr_t start, phys_addr_t size, long type); 113 98 extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max);
+13 -5
arch/mips/include/asm/cmpxchg.h
··· 46 46 __typeof(*(m)) __ret; \ 47 47 \ 48 48 if (kernel_uses_llsc) { \ 49 + loongson_llsc_mb(); \ 49 50 __asm__ __volatile__( \ 50 51 " .set push \n" \ 51 52 " .set noat \n" \ ··· 61 60 " .set pop \n" \ 62 61 : "=&r" (__ret), "=" GCC_OFF_SMALL_ASM() (*m) \ 63 62 : GCC_OFF_SMALL_ASM() (*m), "Jr" (val) \ 64 - : "memory"); \ 63 + : __LLSC_CLOBBER); \ 65 64 } else { \ 66 65 unsigned long __flags; \ 67 66 \ ··· 118 117 __typeof(*(m)) __ret; \ 119 118 \ 120 119 if (kernel_uses_llsc) { \ 120 + loongson_llsc_mb(); \ 121 121 __asm__ __volatile__( \ 122 122 " .set push \n" \ 123 123 " .set noat \n" \ ··· 134 132 " .set pop \n" \ 135 133 "2: \n" \ 136 134 : "=&r" (__ret), "=" GCC_OFF_SMALL_ASM() (*m) \ 137 - : GCC_OFF_SMALL_ASM() (*m), "Jr" (old), "Jr" (new) \ 138 - : "memory"); \ 135 + : GCC_OFF_SMALL_ASM() (*m), "Jr" (old), "Jr" (new) \ 136 + : __LLSC_CLOBBER); \ 137 + loongson_llsc_mb(); \ 139 138 } else { \ 140 139 unsigned long __flags; \ 141 140 \ ··· 232 229 */ 233 230 local_irq_save(flags); 234 231 232 + loongson_llsc_mb(); 235 233 asm volatile( 236 234 " .set push \n" 237 235 " .set " MIPS_ISA_ARCH_LEVEL " \n" ··· 278 274 "r" (old), 279 275 "r" (new) 280 276 : "memory"); 277 + loongson_llsc_mb(); 281 278 282 279 local_irq_restore(flags); 283 280 return ret; ··· 295 290 * will cause a build error unless cpu_has_64bits is a \ 296 291 * compile-time constant 1. \ 297 292 */ \ 298 - if (cpu_has_64bits && kernel_uses_llsc) \ 293 + if (cpu_has_64bits && kernel_uses_llsc) { \ 294 + smp_mb__before_llsc(); \ 299 295 __res = __cmpxchg64((ptr), __old, __new); \ 300 - else \ 296 + smp_llsc_mb(); \ 297 + } else { \ 301 298 __res = __cmpxchg64_unsupported(); \ 299 + } \ 302 300 \ 303 301 __res; \ 304 302 })
+16 -3
arch/mips/include/asm/cpu-features.h
··· 243 243 #ifndef cpu_has_pindexed_dcache 244 244 #define cpu_has_pindexed_dcache (cpu_data[0].dcache.flags & MIPS_CACHE_PINDEX) 245 245 #endif 246 - #ifndef cpu_has_local_ebase 247 - #define cpu_has_local_ebase 1 248 - #endif 249 246 250 247 /* 251 248 * I-Cache snoops remote store. This only matters on SMP. Some multiprocessors ··· 392 395 393 396 #ifndef cpu_has_dsp3 394 397 #define cpu_has_dsp3 __ase(MIPS_ASE_DSP3) 398 + #endif 399 + 400 + #ifndef cpu_has_loongson_mmi 401 + #define cpu_has_loongson_mmi __ase(MIPS_ASE_LOONGSON_MMI) 402 + #endif 403 + 404 + #ifndef cpu_has_loongson_cam 405 + #define cpu_has_loongson_cam __ase(MIPS_ASE_LOONGSON_CAM) 406 + #endif 407 + 408 + #ifndef cpu_has_loongson_ext 409 + #define cpu_has_loongson_ext __ase(MIPS_ASE_LOONGSON_EXT) 410 + #endif 411 + 412 + #ifndef cpu_has_loongson_ext2 413 + #define cpu_has_loongson_ext2 __ase(MIPS_ASE_LOONGSON_EXT2) 395 414 #endif 396 415 397 416 #ifndef cpu_has_mipsmt
+1 -14
arch/mips/include/asm/cpu-type.h
··· 38 38 #if defined(CONFIG_SYS_HAS_CPU_MIPS32_R1) || \ 39 39 defined(CONFIG_SYS_HAS_CPU_MIPS32_R2) 40 40 case CPU_4KEC: 41 - case CPU_JZRISC: 41 + case CPU_XBURST: 42 42 #endif 43 43 44 44 #ifdef CONFIG_SYS_HAS_CPU_MIPS32_R2 ··· 116 116 case CPU_VR4181A: 117 117 #endif 118 118 119 - #ifdef CONFIG_SYS_HAS_CPU_R4300 120 - case CPU_R4300: 121 - case CPU_R4310: 122 - #endif 123 - 124 119 #ifdef CONFIG_SYS_HAS_CPU_R4X00 125 120 case CPU_R4000PC: 126 121 case CPU_R4000SC: ··· 138 143 case CPU_R5000: 139 144 #endif 140 145 141 - #ifdef CONFIG_SYS_HAS_CPU_R5432 142 - case CPU_R5432: 143 - #endif 144 - 145 146 #ifdef CONFIG_SYS_HAS_CPU_R5500 146 147 case CPU_R5500: 147 148 #endif 148 149 149 150 #ifdef CONFIG_SYS_HAS_CPU_NEVADA 150 151 case CPU_NEVADA: 151 - #endif 152 - 153 - #ifdef CONFIG_SYS_HAS_CPU_R8000 154 - case CPU_R8000: 155 152 #endif 156 153 157 154 #ifdef CONFIG_SYS_HAS_CPU_R10000
+9 -10
arch/mips/include/asm/cpu.h
··· 47 47 #define PRID_COMP_CAVIUM 0x0d0000 48 48 #define PRID_COMP_LOONGSON 0x140000 49 49 #define PRID_COMP_INGENIC_D0 0xd00000 /* JZ4740, JZ4750 */ 50 - #define PRID_COMP_INGENIC_D1 0xd10000 /* JZ4770, JZ4775 */ 50 + #define PRID_COMP_INGENIC_D1 0xd10000 /* JZ4770, JZ4775, X1000 */ 51 51 #define PRID_COMP_INGENIC_E1 0xe10000 /* JZ4780 */ 52 52 53 53 /* ··· 183 183 * These are the PRID's for when 23:16 == PRID_COMP_INGENIC_* 184 184 */ 185 185 186 - #define PRID_IMP_JZRISC 0x0200 186 + #define PRID_IMP_XBURST 0x0200 187 187 188 188 /* 189 189 * These are the PRID's for when 23:16 == PRID_COMP_NETLOGIC ··· 293 293 /* 294 294 * R4000 class processors 295 295 */ 296 - CPU_R4000PC, CPU_R4000SC, CPU_R4000MC, CPU_R4200, CPU_R4300, CPU_R4310, 296 + CPU_R4000PC, CPU_R4000SC, CPU_R4000MC, CPU_R4200, 297 297 CPU_R4400PC, CPU_R4400SC, CPU_R4400MC, CPU_R4600, CPU_R4640, CPU_R4650, 298 - CPU_R4700, CPU_R5000, CPU_R5500, CPU_NEVADA, CPU_R5432, CPU_R10000, 298 + CPU_R4700, CPU_R5000, CPU_R5500, CPU_NEVADA, CPU_R10000, 299 299 CPU_R12000, CPU_R14000, CPU_R16000, CPU_VR41XX, CPU_VR4111, CPU_VR4121, 300 300 CPU_VR4122, CPU_VR4131, CPU_VR4133, CPU_VR4181, CPU_VR4181A, CPU_RM7000, 301 301 CPU_SR71000, CPU_TX49XX, 302 - 303 - /* 304 - * R8000 class processors 305 - */ 306 - CPU_R8000, 307 302 308 303 /* 309 304 * TX3900 class processors ··· 310 315 */ 311 316 CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K, 312 317 CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350, 313 - CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_LOONGSON1, CPU_M14KC, 318 + CPU_BMIPS4380, CPU_BMIPS5000, CPU_XBURST, CPU_LOONGSON1, CPU_M14KC, 314 319 CPU_M14KEC, CPU_INTERAPTIV, CPU_P5600, CPU_PROAPTIV, CPU_1074K, 315 320 CPU_M5150, CPU_I6400, CPU_P6600, CPU_M6250, 316 321 ··· 428 433 #define MIPS_ASE_MSA 0x00000100 /* MIPS SIMD Architecture */ 429 434 #define MIPS_ASE_DSP3 0x00000200 /* Signal Processing ASE Rev 3*/ 430 435 #define MIPS_ASE_MIPS16E2 0x00000400 /* MIPS16e2 */ 436 + #define MIPS_ASE_LOONGSON_MMI 0x00000800 /* Loongson MultiMedia extensions Instructions */ 437 + #define MIPS_ASE_LOONGSON_CAM 0x00001000 /* Loongson CAM */ 438 + #define MIPS_ASE_LOONGSON_EXT 0x00002000 /* Loongson EXTensions */ 439 + #define MIPS_ASE_LOONGSON_EXT2 0x00004000 /* Loongson EXTensions R2 */ 431 440 432 441 #endif /* _ASM_CPU_H */
+5 -16
arch/mips/include/asm/io.h
··· 63 63 * instruction, so the lower 16 bits must be zero. Should be true on 64 64 * on any sane architecture; generic code does not use this assumption. 65 65 */ 66 - extern const unsigned long mips_io_port_base; 66 + extern unsigned long mips_io_port_base; 67 67 68 - /* 69 - * Gcc will generate code to load the value of mips_io_port_base after each 70 - * function call which may be fairly wasteful in some cases. So we don't 71 - * play quite by the book. We tell gcc mips_io_port_base is a long variable 72 - * which solves the code generation issue. Now we need to violate the 73 - * aliasing rules a little to make initialization possible and finally we 74 - * will need the barrier() to fight side effects of the aliasing chat. 75 - * This trickery will eventually collapse under gcc's optimizer. Oh well. 76 - */ 77 68 static inline void set_io_port_base(unsigned long base) 78 69 { 79 - * (unsigned long *) &mips_io_port_base = base; 80 - barrier(); 70 + mips_io_port_base = base; 81 71 } 82 72 83 73 /* ··· 252 262 #define ioremap_uc ioremap_nocache 253 263 254 264 /* 255 - * ioremap_cachable - map bus memory into CPU space 265 + * ioremap_cache - map bus memory into CPU space 256 266 * @offset: bus address of the memory 257 267 * @size: size of the resource to map 258 268 * 259 - * ioremap_nocache performs a platform specific sequence of operations to 269 + * ioremap_cache performs a platform specific sequence of operations to 260 270 * make bus memory CPU accessible via the readb/readw/readl/writeb/ 261 271 * writew/writel functions and the other mmio helpers. The returned 262 272 * address is not guaranteed to be usable directly as a virtual ··· 266 276 * the CPU. Also enables full write-combining. Useful for some 267 277 * memory-like regions on I/O busses. 268 278 */ 269 - #define ioremap_cachable(offset, size) \ 279 + #define ioremap_cache(offset, size) \ 270 280 __ioremap_mode((offset), (size), _page_cachable_default) 271 - #define ioremap_cache ioremap_cachable 272 281 273 282 /* 274 283 * ioremap_wc - map bus memory into CPU space
+1
arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
··· 98 98 BCM47XX_BOARD_MOTOROLA_WR850GP, 99 99 BCM47XX_BOARD_MOTOROLA_WR850GV2V3, 100 100 101 + BCM47XX_BOARD_NETGEAR_R6200_V1, 101 102 BCM47XX_BOARD_NETGEAR_WGR614V8, 102 103 BCM47XX_BOARD_NETGEAR_WGR614V9, 103 104 BCM47XX_BOARD_NETGEAR_WGR614_V10,
-9
arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
··· 45 45 #define cpu_has_ic_fills_f_dc 0 46 46 #define cpu_has_64bits 1 47 47 #define cpu_has_octeon_cache 1 48 - #define cpu_has_saa octeon_has_saa() 49 48 #define cpu_has_mips32r1 1 50 49 #define cpu_has_mips32r2 1 51 50 #define cpu_has_mips64r1 1 ··· 59 60 60 61 #define cpu_has_rixi (cpu_data[0].cputype != CPU_CAVIUM_OCTEON) 61 62 62 - #define ARCH_HAS_IRQ_PER_CPU 1 63 63 #define ARCH_HAS_SPINLOCK_PREFETCH 1 64 64 #define spin_lock_prefetch(x) prefetch(x) 65 65 #define PREFETCH_STRIDE 128 ··· 70 72 */ 71 73 #define ARCH_HAS_USABLE_BUILTIN_POPCOUNT 1 72 74 #endif 73 - 74 - static inline int octeon_has_saa(void) 75 - { 76 - int id; 77 - asm volatile ("mfc0 %0, $15,0" : "=r" (id)); 78 - return id >= 0x000d0300; 79 - } 80 75 81 76 /* 82 77 * The last 256MB are reserved for device to device mappings and the
-1
arch/mips/include/asm/mach-cavium-octeon/war.h
··· 12 12 #define R4600_V1_INDEX_ICACHEOP_WAR 0 13 13 #define R4600_V1_HIT_CACHEOP_WAR 0 14 14 #define R4600_V2_HIT_CACHEOP_WAR 0 15 - #define R5432_CP0_INTERRUPT_WAR 0 16 15 #define BCM1250_M3_WAR 0 17 16 #define SIBYTE_1956_WAR 0 18 17 #define MIPS4K_ICACHE_REFILL_WAR 0
-1
arch/mips/include/asm/mach-dec/cpu-feature-overrides.h
··· 32 32 #define cpu_has_vtag_icache 0 33 33 #define cpu_has_ic_fills_f_dc 0 34 34 #define cpu_has_pindexed_dcache 0 35 - #define cpu_has_local_ebase 0 36 35 #define cpu_icache_snoops_remote_store 1 37 36 #define cpu_has_mips_4 0 38 37 #define cpu_has_mips_5 0
-1
arch/mips/include/asm/mach-generic/war.h
··· 11 11 #define R4600_V1_INDEX_ICACHEOP_WAR 0 12 12 #define R4600_V1_HIT_CACHEOP_WAR 0 13 13 #define R4600_V2_HIT_CACHEOP_WAR 0 14 - #define R5432_CP0_INTERRUPT_WAR 0 15 14 #define BCM1250_M3_WAR 0 16 15 #define SIBYTE_1956_WAR 0 17 16 #define MIPS4K_ICACHE_REFILL_WAR 0
-1
arch/mips/include/asm/mach-ip22/war.h
··· 15 15 #define R4600_V1_INDEX_ICACHEOP_WAR 1 16 16 #define R4600_V1_HIT_CACHEOP_WAR 1 17 17 #define R4600_V2_HIT_CACHEOP_WAR 1 18 - #define R5432_CP0_INTERRUPT_WAR 0 19 18 #define BCM1250_M3_WAR 0 20 19 #define SIBYTE_1956_WAR 0 21 20 #define MIPS4K_ICACHE_REFILL_WAR 0
-1
arch/mips/include/asm/mach-ip27/war.h
··· 11 11 #define R4600_V1_INDEX_ICACHEOP_WAR 0 12 12 #define R4600_V1_HIT_CACHEOP_WAR 0 13 13 #define R4600_V2_HIT_CACHEOP_WAR 0 14 - #define R5432_CP0_INTERRUPT_WAR 0 15 14 #define BCM1250_M3_WAR 0 16 15 #define SIBYTE_1956_WAR 0 17 16 #define MIPS4K_ICACHE_REFILL_WAR 0
-1
arch/mips/include/asm/mach-ip28/war.h
··· 11 11 #define R4600_V1_INDEX_ICACHEOP_WAR 0 12 12 #define R4600_V1_HIT_CACHEOP_WAR 0 13 13 #define R4600_V2_HIT_CACHEOP_WAR 0 14 - #define R5432_CP0_INTERRUPT_WAR 0 15 14 #define BCM1250_M3_WAR 0 16 15 #define SIBYTE_1956_WAR 0 17 16 #define MIPS4K_ICACHE_REFILL_WAR 0
-1
arch/mips/include/asm/mach-ip32/war.h
··· 11 11 #define R4600_V1_INDEX_ICACHEOP_WAR 0 12 12 #define R4600_V1_HIT_CACHEOP_WAR 0 13 13 #define R4600_V2_HIT_CACHEOP_WAR 0 14 - #define R5432_CP0_INTERRUPT_WAR 0 15 14 #define BCM1250_M3_WAR 0 16 15 #define SIBYTE_1956_WAR 0 17 16 #define MIPS4K_ICACHE_REFILL_WAR 0
-15
arch/mips/include/asm/mach-jz4740/gpio.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 - /* 3 - * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> 4 - * JZ4740 GPIO pin definitions 5 - */ 6 - 7 - #ifndef _JZ_GPIO_H 8 - #define _JZ_GPIO_H 9 - 10 - #define JZ_GPIO_PORTA(x) ((x) + 32 * 0) 11 - #define JZ_GPIO_PORTB(x) ((x) + 32 * 1) 12 - #define JZ_GPIO_PORTC(x) ((x) + 32 * 2) 13 - #define JZ_GPIO_PORTD(x) ((x) + 32 * 3) 14 - 15 - #endif
-58
arch/mips/include/asm/mach-jz4740/jz4740_fb.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 - /* 3 - * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> 4 - */ 5 - 6 - #ifndef __ASM_MACH_JZ4740_JZ4740_FB_H__ 7 - #define __ASM_MACH_JZ4740_JZ4740_FB_H__ 8 - 9 - #include <linux/fb.h> 10 - 11 - enum jz4740_fb_lcd_type { 12 - JZ_LCD_TYPE_GENERIC_16_BIT = 0, 13 - JZ_LCD_TYPE_GENERIC_18_BIT = 0 | (1 << 4), 14 - JZ_LCD_TYPE_SPECIAL_TFT_1 = 1, 15 - JZ_LCD_TYPE_SPECIAL_TFT_2 = 2, 16 - JZ_LCD_TYPE_SPECIAL_TFT_3 = 3, 17 - JZ_LCD_TYPE_NON_INTERLACED_CCIR656 = 5, 18 - JZ_LCD_TYPE_INTERLACED_CCIR656 = 7, 19 - JZ_LCD_TYPE_SINGLE_COLOR_STN = 8, 20 - JZ_LCD_TYPE_SINGLE_MONOCHROME_STN = 9, 21 - JZ_LCD_TYPE_DUAL_COLOR_STN = 10, 22 - JZ_LCD_TYPE_DUAL_MONOCHROME_STN = 11, 23 - JZ_LCD_TYPE_8BIT_SERIAL = 12, 24 - }; 25 - 26 - #define JZ4740_FB_SPECIAL_TFT_CONFIG(start, stop) (((start) << 16) | (stop)) 27 - 28 - /* 29 - * width: width of the lcd display in mm 30 - * height: height of the lcd display in mm 31 - * num_modes: size of modes 32 - * modes: list of valid video modes 33 - * bpp: bits per pixel for the lcd 34 - * lcd_type: lcd type 35 - */ 36 - 37 - struct jz4740_fb_platform_data { 38 - unsigned int width; 39 - unsigned int height; 40 - 41 - size_t num_modes; 42 - struct fb_videomode *modes; 43 - 44 - unsigned int bpp; 45 - enum jz4740_fb_lcd_type lcd_type; 46 - 47 - struct { 48 - uint32_t spl; 49 - uint32_t cls; 50 - uint32_t ps; 51 - uint32_t rev; 52 - } special_tft_config; 53 - 54 - unsigned pixclk_falling_edge:1; 55 - unsigned date_enable_active_low:1; 56 - }; 57 - 58 - #endif
-12
arch/mips/include/asm/mach-jz4740/jz4740_mmc.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - #ifndef __LINUX_MMC_JZ4740_MMC 3 - #define __LINUX_MMC_JZ4740_MMC 4 - 5 - struct jz4740_mmc_platform_data { 6 - unsigned card_detect_active_low:1; 7 - unsigned read_only_active_low:1; 8 - 9 - unsigned data_1bit:1; 10 - }; 11 - 12 - #endif
-26
arch/mips/include/asm/mach-jz4740/platform.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 - /* 3 - * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> 4 - * JZ4740 platform device definitions 5 - */ 6 - 7 - 8 - #ifndef __JZ4740_PLATFORM_H 9 - #define __JZ4740_PLATFORM_H 10 - 11 - #include <linux/platform_device.h> 12 - 13 - extern struct platform_device jz4740_udc_device; 14 - extern struct platform_device jz4740_udc_xceiv_device; 15 - extern struct platform_device jz4740_mmc_device; 16 - extern struct platform_device jz4740_i2c_device; 17 - extern struct platform_device jz4740_nand_device; 18 - extern struct platform_device jz4740_framebuffer_device; 19 - extern struct platform_device jz4740_i2s_device; 20 - extern struct platform_device jz4740_pcm_device; 21 - extern struct platform_device jz4740_codec_device; 22 - extern struct platform_device jz4740_adc_device; 23 - extern struct platform_device jz4740_pwm_device; 24 - extern struct platform_device jz4740_dma_device; 25 - 26 - #endif
-1
arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h
··· 43 43 #define cpu_has_vint 0 44 44 #define cpu_has_vtag_icache 0 45 45 #define cpu_has_watch 1 46 - #define cpu_has_local_ebase 0 47 46 48 47 #ifdef CONFIG_CPU_LOONGSON3 49 48 #define cpu_has_wsbh 1
-1
arch/mips/include/asm/mach-malta/war.h
··· 11 11 #define R4600_V1_INDEX_ICACHEOP_WAR 0 12 12 #define R4600_V1_HIT_CACHEOP_WAR 0 13 13 #define R4600_V2_HIT_CACHEOP_WAR 0 14 - #define R5432_CP0_INTERRUPT_WAR 0 15 14 #define BCM1250_M3_WAR 0 16 15 #define SIBYTE_1956_WAR 0 17 16 #define MIPS4K_ICACHE_REFILL_WAR 1
-1
arch/mips/include/asm/mach-pmcs-msp71xx/war.h
··· 11 11 #define R4600_V1_INDEX_ICACHEOP_WAR 0 12 12 #define R4600_V1_HIT_CACHEOP_WAR 0 13 13 #define R4600_V2_HIT_CACHEOP_WAR 0 14 - #define R5432_CP0_INTERRUPT_WAR 0 15 14 #define BCM1250_M3_WAR 0 16 15 #define SIBYTE_1956_WAR 0 17 16 #define MIPS4K_ICACHE_REFILL_WAR 0
-1
arch/mips/include/asm/mach-rc32434/war.h
··· 11 11 #define R4600_V1_INDEX_ICACHEOP_WAR 0 12 12 #define R4600_V1_HIT_CACHEOP_WAR 0 13 13 #define R4600_V2_HIT_CACHEOP_WAR 0 14 - #define R5432_CP0_INTERRUPT_WAR 0 15 14 #define BCM1250_M3_WAR 0 16 15 #define SIBYTE_1956_WAR 0 17 16 #define MIPS4K_ICACHE_REFILL_WAR 1
-1
arch/mips/include/asm/mach-rm/war.h
··· 15 15 #define R4600_V1_INDEX_ICACHEOP_WAR 0 16 16 #define R4600_V1_HIT_CACHEOP_WAR 0 17 17 #define R4600_V2_HIT_CACHEOP_WAR 1 18 - #define R5432_CP0_INTERRUPT_WAR 0 19 18 #define BCM1250_M3_WAR 0 20 19 #define SIBYTE_1956_WAR 0 21 20 #define MIPS4K_ICACHE_REFILL_WAR 0
-1
arch/mips/include/asm/mach-sibyte/war.h
··· 11 11 #define R4600_V1_INDEX_ICACHEOP_WAR 0 12 12 #define R4600_V1_HIT_CACHEOP_WAR 0 13 13 #define R4600_V2_HIT_CACHEOP_WAR 0 14 - #define R5432_CP0_INTERRUPT_WAR 0 15 14 16 15 #if defined(CONFIG_SB1_PASS_2_WORKAROUNDS) 17 16
-1
arch/mips/include/asm/mach-tx49xx/war.h
··· 11 11 #define R4600_V1_INDEX_ICACHEOP_WAR 0 12 12 #define R4600_V1_HIT_CACHEOP_WAR 0 13 13 #define R4600_V2_HIT_CACHEOP_WAR 0 14 - #define R5432_CP0_INTERRUPT_WAR 0 15 14 #define BCM1250_M3_WAR 0 16 15 #define SIBYTE_1956_WAR 0 17 16 #define MIPS4K_ICACHE_REFILL_WAR 0
+4
arch/mips/include/asm/mipsregs.h
··· 689 689 #define MIPS_CONF7_IAR (_ULCAST_(1) << 10) 690 690 #define MIPS_CONF7_AR (_ULCAST_(1) << 16) 691 691 692 + /* Ingenic Config7 bits */ 693 + #define MIPS_CONF7_BTB_LOOP_EN (_ULCAST_(1) << 4) 694 + 692 695 /* Config7 Bits specific to MIPS Technologies. */ 693 696 694 697 /* Performance counters implemented Per TC */ ··· 2816 2813 __BUILD_SET_C0(cause) 2817 2814 __BUILD_SET_C0(config) 2818 2815 __BUILD_SET_C0(config5) 2816 + __BUILD_SET_C0(config7) 2819 2817 __BUILD_SET_C0(intcontrol) 2820 2818 __BUILD_SET_C0(intctl) 2821 2819 __BUILD_SET_C0(srsmap)
-6
arch/mips/include/asm/module.h
··· 103 103 #define MODULE_PROC_FAMILY "TX39XX " 104 104 #elif defined CONFIG_CPU_VR41XX 105 105 #define MODULE_PROC_FAMILY "VR41XX " 106 - #elif defined CONFIG_CPU_R4300 107 - #define MODULE_PROC_FAMILY "R4300 " 108 106 #elif defined CONFIG_CPU_R4X00 109 107 #define MODULE_PROC_FAMILY "R4X00 " 110 108 #elif defined CONFIG_CPU_TX49XX 111 109 #define MODULE_PROC_FAMILY "TX49XX " 112 110 #elif defined CONFIG_CPU_R5000 113 111 #define MODULE_PROC_FAMILY "R5000 " 114 - #elif defined CONFIG_CPU_R5432 115 - #define MODULE_PROC_FAMILY "R5432 " 116 112 #elif defined CONFIG_CPU_R5500 117 113 #define MODULE_PROC_FAMILY "R5500 " 118 114 #elif defined CONFIG_CPU_NEVADA 119 115 #define MODULE_PROC_FAMILY "NEVADA " 120 - #elif defined CONFIG_CPU_R8000 121 - #define MODULE_PROC_FAMILY "R8000 " 122 116 #elif defined CONFIG_CPU_R10000 123 117 #define MODULE_PROC_FAMILY "R10000 " 124 118 #elif defined CONFIG_CPU_RM7000
+2 -2
arch/mips/include/asm/octeon/octeon.h
··· 51 51 extern void octeon_io_clk_delay(unsigned long); 52 52 53 53 #define OCTEON_ARGV_MAX_ARGS 64 54 - #define OCTOEN_SERIAL_LEN 20 54 + #define OCTEON_SERIAL_LEN 20 55 55 56 56 struct octeon_boot_descriptor { 57 57 #ifdef __BIG_ENDIAN_BITFIELD ··· 102 102 uint16_t chip_type; 103 103 uint8_t chip_rev_major; 104 104 uint8_t chip_rev_minor; 105 - char board_serial_number[OCTOEN_SERIAL_LEN]; 105 + char board_serial_number[OCTEON_SERIAL_LEN]; 106 106 uint8_t mac_addr_base[6]; 107 107 uint8_t mac_addr_count; 108 108 uint64_t cvmx_desc_vaddr;
+54 -8
arch/mips/include/asm/pgtable-32.h
··· 23 23 #include <asm/highmem.h> 24 24 #endif 25 25 26 + /* 27 + * Regarding 32-bit MIPS huge page support (and the tradeoff it entails): 28 + * 29 + * We use the same huge page sizes as 64-bit MIPS. Assuming a 4KB page size, 30 + * our 2-level table layout would normally have a PGD entry cover a contiguous 31 + * 4MB virtual address region (pointing to a 4KB PTE page of 1,024 32-bit pte_t 32 + * pointers, each pointing to a 4KB physical page). The problem is that 4MB, 33 + * spanning both halves of a TLB EntryLo0,1 pair, requires 2MB hardware page 34 + * support, not one of the standard supported sizes (1MB,4MB,16MB,...). 35 + * To correct for this, when huge pages are enabled, we halve the number of 36 + * pointers a PTE page holds, making its last half go to waste. Correspondingly, 37 + * we double the number of PGD pages. Overall, page table memory overhead 38 + * increases to match 64-bit MIPS, but PTE lookups remain CPU cache-friendly. 39 + * 40 + * NOTE: We don't yet support huge pages if extended-addressing is enabled 41 + * (i.e. EVA, XPA, 36-bit Alchemy/Netlogic). 42 + */ 43 + 26 44 extern int temp_tlb_entry; 27 45 28 46 /* ··· 62 44 */ 63 45 64 46 /* PGDIR_SHIFT determines what a third-level page table entry can map */ 65 - #define PGDIR_SHIFT (2 * PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2) 47 + #if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) && !defined(CONFIG_PHYS_ADDR_T_64BIT) 48 + # define PGDIR_SHIFT (2 * PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2 - 1) 49 + #else 50 + # define PGDIR_SHIFT (2 * PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2) 51 + #endif 52 + 66 53 #define PGDIR_SIZE (1UL << PGDIR_SHIFT) 67 54 #define PGDIR_MASK (~(PGDIR_SIZE-1)) 68 55 ··· 75 52 * Entries per page directory level: we use two-level, so 76 53 * we don't really have any PUD/PMD directory physically. 77 54 */ 78 - #define __PGD_ORDER (32 - 3 * PAGE_SHIFT + PGD_T_LOG2 + PTE_T_LOG2) 55 + #if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) && !defined(CONFIG_PHYS_ADDR_T_64BIT) 56 + # define __PGD_ORDER (32 - 3 * PAGE_SHIFT + PGD_T_LOG2 + PTE_T_LOG2 + 1) 57 + #else 58 + # define __PGD_ORDER (32 - 3 * PAGE_SHIFT + PGD_T_LOG2 + PTE_T_LOG2) 59 + #endif 60 + 79 61 #define PGD_ORDER (__PGD_ORDER >= 0 ? __PGD_ORDER : 0) 80 62 #define PUD_ORDER aieeee_attempt_to_allocate_pud 81 - #define PMD_ORDER 1 63 + #define PMD_ORDER aieeee_attempt_to_allocate_pmd 82 64 #define PTE_ORDER 0 83 65 84 66 #define PTRS_PER_PGD (USER_PTRS_PER_PGD * 2) 85 - #define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t)) 67 + #if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) && !defined(CONFIG_PHYS_ADDR_T_64BIT) 68 + # define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t) / 2) 69 + #else 70 + # define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t)) 71 + #endif 86 72 87 73 #define USER_PTRS_PER_PGD (0x80000000UL/PGDIR_SIZE) 88 74 #define FIRST_USER_ADDRESS 0UL ··· 119 87 120 88 extern void load_pgd(unsigned long pg_dir); 121 89 122 - extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)]; 90 + extern pte_t invalid_pte_table[PTRS_PER_PTE]; 123 91 124 92 /* 125 93 * Empty pgd/pmd entries point to the invalid_pte_table. ··· 129 97 return pmd_val(pmd) == (unsigned long) invalid_pte_table; 130 98 } 131 99 132 - #define pmd_bad(pmd) (pmd_val(pmd) & ~PAGE_MASK) 100 + static inline int pmd_bad(pmd_t pmd) 101 + { 102 + #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT 103 + /* pmd_huge(pmd) but inline */ 104 + if (unlikely(pmd_val(pmd) & _PAGE_HUGE)) 105 + return 0; 106 + #endif 107 + 108 + if (unlikely(pmd_val(pmd) & ~PAGE_MASK)) 109 + return 1; 110 + 111 + return 0; 112 + } 133 113 134 114 static inline int pmd_present(pmd_t pmd) 135 115 { ··· 190 146 #else 191 147 #define pte_pfn(x) ((unsigned long)((x).pte >> _PFN_SHIFT)) 192 148 #define pfn_pte(pfn, prot) __pte(((unsigned long long)(pfn) << _PFN_SHIFT) | pgprot_val(prot)) 149 + #define pfn_pmd(pfn, prot) __pmd(((unsigned long long)(pfn) << _PFN_SHIFT) | pgprot_val(prot)) 193 150 #endif 194 151 #endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */ 195 152 ··· 204 159 #define pgd_offset_k(address) pgd_offset(&init_mm, address) 205 160 206 161 #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) 162 + #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) 207 163 208 164 /* to find an entry in a page-table-directory */ 209 165 #define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr)) ··· 221 175 ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address)) 222 176 #define pte_unmap(pte) ((void)(pte)) 223 177 224 - #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) 178 + #if defined(CONFIG_CPU_R3K_TLB) 225 179 226 180 /* Swap entries must have VALID bit cleared. */ 227 181 #define __swp_type(x) (((x).val >> 10) & 0x1f) ··· 266 220 267 221 #endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */ 268 222 269 - #endif /* defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) */ 223 + #endif /* defined(CONFIG_CPU_R3K_TLB) */ 270 224 271 225 #endif /* _ASM_PGTABLE_32_H */
+22 -12
arch/mips/include/asm/pgtable-bits.h
··· 52 52 _PAGE_WRITE_SHIFT, 53 53 _PAGE_ACCESSED_SHIFT, 54 54 _PAGE_MODIFIED_SHIFT, 55 + #if defined(CONFIG_ARCH_HAS_PTE_SPECIAL) 56 + _PAGE_SPECIAL_SHIFT, 57 + #endif 55 58 }; 56 59 57 60 /* ··· 81 78 _PAGE_WRITE_SHIFT, 82 79 _PAGE_ACCESSED_SHIFT, 83 80 _PAGE_MODIFIED_SHIFT, 81 + #if defined(CONFIG_ARCH_HAS_PTE_SPECIAL) 82 + _PAGE_SPECIAL_SHIFT, 83 + #endif 84 84 }; 85 85 86 - #elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) 86 + #elif defined(CONFIG_CPU_R3K_TLB) 87 87 88 88 /* Page table bits used for r3k systems */ 89 89 enum pgtable_bits { ··· 96 90 _PAGE_WRITE_SHIFT, 97 91 _PAGE_ACCESSED_SHIFT, 98 92 _PAGE_MODIFIED_SHIFT, 93 + #if defined(CONFIG_ARCH_HAS_PTE_SPECIAL) 94 + _PAGE_SPECIAL_SHIFT, 95 + #endif 99 96 100 97 /* Used by TLB hardware (placed in EntryLo) */ 101 98 _PAGE_GLOBAL_SHIFT = 8, ··· 119 110 _PAGE_WRITE_SHIFT, 120 111 _PAGE_ACCESSED_SHIFT, 121 112 _PAGE_MODIFIED_SHIFT, 122 - #if defined(CONFIG_64BIT) && defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) 113 + #if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) 123 114 _PAGE_HUGE_SHIFT, 115 + #endif 116 + #if defined(CONFIG_ARCH_HAS_PTE_SPECIAL) 117 + _PAGE_SPECIAL_SHIFT, 124 118 #endif 125 119 126 120 /* Used by TLB hardware (placed in EntryLo*) */ ··· 144 132 #define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) 145 133 #define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) 146 134 #define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) 147 - #if defined(CONFIG_64BIT) && defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) 135 + #if defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) 148 136 # define _PAGE_HUGE (1 << _PAGE_HUGE_SHIFT) 137 + #endif 138 + #if defined(CONFIG_ARCH_HAS_PTE_SPECIAL) 139 + # define _PAGE_SPECIAL (1 << _PAGE_SPECIAL_SHIFT) 140 + #else 141 + # define _PAGE_SPECIAL 0 149 142 #endif 150 143 151 144 /* Used by TLB hardware (placed in EntryLo*) */ ··· 163 146 #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) 164 147 #define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) 165 148 #define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT) 166 - #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) 149 + #if defined(CONFIG_CPU_R3K_TLB) 167 150 # define _CACHE_UNCACHED (1 << _CACHE_UNCACHED_SHIFT) 168 151 # define _CACHE_MASK _CACHE_UNCACHED 169 152 # define _PFN_SHIFT PAGE_SHIFT ··· 221 204 /* 222 205 * Cache attributes 223 206 */ 224 - #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) 207 + #if defined(CONFIG_CPU_R3K_TLB) 225 208 226 209 #define _CACHE_CACHABLE_NONCOHERENT 0 227 210 #define _CACHE_UNCACHED_ACCELERATED _CACHE_UNCACHED ··· 232 215 use it for "noncoherent" spaces, too. Shouldn't hurt. */ 233 216 234 217 #define _CACHE_CACHABLE_NONCOHERENT (5<<_CACHE_SHIFT) 235 - 236 - #elif defined(CONFIG_CPU_LOONGSON3) 237 - 238 - /* Using COHERENT flag for NONCOHERENT doesn't hurt. */ 239 - 240 - #define _CACHE_CACHABLE_NONCOHERENT (3<<_CACHE_SHIFT) /* LOONGSON */ 241 - #define _CACHE_CACHABLE_COHERENT (3<<_CACHE_SHIFT) /* LOONGSON-3 */ 242 218 243 219 #elif defined(CONFIG_MACH_INGENIC) 244 220
+16 -4
arch/mips/include/asm/pgtable.h
··· 199 199 static inline void set_pte(pte_t *ptep, pte_t pteval) 200 200 { 201 201 *ptep = pteval; 202 - #if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX) 202 + #if !defined(CONFIG_CPU_R3K_TLB) 203 203 if (pte_val(pteval) & _PAGE_GLOBAL) { 204 204 pte_t *buddy = ptep_buddy(ptep); 205 205 /* ··· 218 218 static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) 219 219 { 220 220 htw_stop(); 221 - #if !defined(CONFIG_CPU_R3000) && !defined(CONFIG_CPU_TX39XX) 221 + #if !defined(CONFIG_CPU_R3K_TLB) 222 222 /* Preserve global status for the pair */ 223 223 if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL) 224 224 set_pte_at(mm, addr, ptep, __pte(_PAGE_GLOBAL)); ··· 277 277 static inline int pte_write(pte_t pte) { return pte.pte_low & _PAGE_WRITE; } 278 278 static inline int pte_dirty(pte_t pte) { return pte.pte_low & _PAGE_MODIFIED; } 279 279 static inline int pte_young(pte_t pte) { return pte.pte_low & _PAGE_ACCESSED; } 280 + static inline int pte_special(pte_t pte) { return pte.pte_low & _PAGE_SPECIAL; } 280 281 281 282 static inline pte_t pte_wrprotect(pte_t pte) 282 283 { ··· 338 337 } 339 338 return pte; 340 339 } 340 + 341 + static inline pte_t pte_mkspecial(pte_t pte) 342 + { 343 + pte.pte_low |= _PAGE_SPECIAL; 344 + return pte; 345 + } 341 346 #else 342 347 static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; } 343 348 static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; } 344 349 static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } 350 + static inline int pte_special(pte_t pte) { return pte_val(pte) & _PAGE_SPECIAL; } 345 351 346 352 static inline pte_t pte_wrprotect(pte_t pte) 347 353 { ··· 392 384 return pte; 393 385 } 394 386 387 + static inline pte_t pte_mkspecial(pte_t pte) 388 + { 389 + pte_val(pte) |= _PAGE_SPECIAL; 390 + return pte; 391 + } 392 + 395 393 #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT 396 394 static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_HUGE; } 397 395 ··· 408 394 } 409 395 #endif /* CONFIG_MIPS_HUGE_TLB_SUPPORT */ 410 396 #endif 411 - static inline int pte_special(pte_t pte) { return 0; } 412 - static inline pte_t pte_mkspecial(pte_t pte) { return pte; } 413 397 414 398 /* 415 399 * Macro to make mark a page protection value as "uncacheable". Note
+7 -14
arch/mips/include/asm/syscall.h
··· 54 54 task_thread_info(task)->syscall = regs->regs[2]; 55 55 } 56 56 57 - static inline unsigned long mips_get_syscall_arg(unsigned long *arg, 57 + static inline void mips_get_syscall_arg(unsigned long *arg, 58 58 struct task_struct *task, struct pt_regs *regs, unsigned int n) 59 59 { 60 60 unsigned long usp __maybe_unused = regs->regs[29]; ··· 63 63 case 0: case 1: case 2: case 3: 64 64 *arg = regs->regs[4 + n]; 65 65 66 - return 0; 66 + return; 67 67 68 68 #ifdef CONFIG_32BIT 69 69 case 4: case 5: case 6: case 7: 70 - return get_user(*arg, (int *)usp + n); 70 + get_user(*arg, (int *)usp + n); 71 + return; 71 72 #endif 72 73 73 74 #ifdef CONFIG_64BIT 74 75 case 4: case 5: case 6: case 7: 75 76 #ifdef CONFIG_MIPS32_O32 76 77 if (test_tsk_thread_flag(task, TIF_32BIT_REGS)) 77 - return get_user(*arg, (int *)usp + n); 78 + get_user(*arg, (int *)usp + n); 78 79 else 79 80 #endif 80 81 *arg = regs->regs[4 + n]; 81 82 82 - return 0; 83 + return; 83 84 #endif 84 85 85 86 default: ··· 127 126 { 128 127 unsigned int i = 0; 129 128 unsigned int n = 6; 130 - int ret; 131 129 132 130 /* O32 ABI syscall() */ 133 131 if (mips_syscall_is_indirect(task, regs)) 134 132 i++; 135 133 136 134 while (n--) 137 - ret |= mips_get_syscall_arg(args++, task, regs, i++); 138 - 139 - /* 140 - * No way to communicate an error because this is a void function. 141 - */ 142 - #if 0 143 - return ret; 144 - #endif 135 + mips_get_syscall_arg(args++, task, regs, i++); 145 136 } 146 137 147 138 extern const unsigned long sys_call_table[];
+2 -76
arch/mips/include/asm/vdso.h
··· 8 8 #define __ASM_VDSO_H 9 9 10 10 #include <linux/mm_types.h> 11 + #include <vdso/datapage.h> 11 12 12 13 #include <asm/barrier.h> 13 14 ··· 50 49 extern struct mips_vdso_image vdso_image_n32; 51 50 #endif 52 51 53 - /** 54 - * union mips_vdso_data - Data provided by the kernel for the VDSO. 55 - * @xtime_sec: Current real time (seconds part). 56 - * @xtime_nsec: Current real time (nanoseconds part, shifted). 57 - * @wall_to_mono_sec: Wall-to-monotonic offset (seconds part). 58 - * @wall_to_mono_nsec: Wall-to-monotonic offset (nanoseconds part). 59 - * @seq_count: Counter to synchronise updates (odd = updating). 60 - * @cs_shift: Clocksource shift value. 61 - * @clock_mode: Clocksource to use for time functions. 62 - * @cs_mult: Clocksource multiplier value. 63 - * @cs_cycle_last: Clock cycle value at last update. 64 - * @cs_mask: Clocksource mask value. 65 - * @tz_minuteswest: Minutes west of Greenwich (from timezone). 66 - * @tz_dsttime: Type of DST correction (from timezone). 67 - * 68 - * This structure contains data needed by functions within the VDSO. It is 69 - * populated by the kernel and mapped read-only into user memory. The time 70 - * fields are mirrors of internal data from the timekeeping infrastructure. 71 - * 72 - * Note: Care should be taken when modifying as the layout must remain the same 73 - * for both 64- and 32-bit (for 32-bit userland on 64-bit kernel). 74 - */ 75 52 union mips_vdso_data { 76 - struct { 77 - u64 xtime_sec; 78 - u64 xtime_nsec; 79 - u64 wall_to_mono_sec; 80 - u64 wall_to_mono_nsec; 81 - u32 seq_count; 82 - u32 cs_shift; 83 - u8 clock_mode; 84 - u32 cs_mult; 85 - u64 cs_cycle_last; 86 - u64 cs_mask; 87 - s32 tz_minuteswest; 88 - s32 tz_dsttime; 89 - }; 90 - 53 + struct vdso_data data[CS_BASES]; 91 54 u8 page[PAGE_SIZE]; 92 55 }; 93 - 94 - static inline u32 vdso_data_read_begin(const union mips_vdso_data *data) 95 - { 96 - u32 seq; 97 - 98 - while (true) { 99 - seq = READ_ONCE(data->seq_count); 100 - if (likely(!(seq & 1))) { 101 - /* Paired with smp_wmb() in vdso_data_write_*(). */ 102 - smp_rmb(); 103 - return seq; 104 - } 105 - 106 - cpu_relax(); 107 - } 108 - } 109 - 110 - static inline bool vdso_data_read_retry(const union mips_vdso_data *data, 111 - u32 start_seq) 112 - { 113 - /* Paired with smp_wmb() in vdso_data_write_*(). */ 114 - smp_rmb(); 115 - return unlikely(data->seq_count != start_seq); 116 - } 117 - 118 - static inline void vdso_data_write_begin(union mips_vdso_data *data) 119 - { 120 - ++data->seq_count; 121 - 122 - /* Ensure sequence update is written before other data page values. */ 123 - smp_wmb(); 124 - } 125 - 126 - static inline void vdso_data_write_end(union mips_vdso_data *data) 127 - { 128 - /* Ensure data values are written before updating sequence again. */ 129 - smp_wmb(); 130 - ++data->seq_count; 131 - } 132 56 133 57 #endif /* __ASM_VDSO_H */
+222
arch/mips/include/asm/vdso/gettimeofday.h
··· 1 + /* 2 + * Copyright (C) 2018 ARM Limited 3 + * Copyright (C) 2015 Imagination Technologies 4 + * Author: Alex Smith <alex.smith@imgtec.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms of the GNU General Public License as published by the 8 + * Free Software Foundation; either version 2 of the License, or (at your 9 + * option) any later version. 10 + */ 11 + #ifndef __ASM_VDSO_GETTIMEOFDAY_H 12 + #define __ASM_VDSO_GETTIMEOFDAY_H 13 + 14 + #ifndef __ASSEMBLY__ 15 + 16 + #include <linux/compiler.h> 17 + #include <linux/time.h> 18 + 19 + #include <asm/vdso/vdso.h> 20 + #include <asm/clocksource.h> 21 + #include <asm/io.h> 22 + #include <asm/unistd.h> 23 + #include <asm/vdso.h> 24 + 25 + #define VDSO_HAS_CLOCK_GETRES 1 26 + 27 + #ifdef CONFIG_MIPS_CLOCK_VSYSCALL 28 + 29 + static __always_inline long gettimeofday_fallback( 30 + struct __kernel_old_timeval *_tv, 31 + struct timezone *_tz) 32 + { 33 + register struct timezone *tz asm("a1") = _tz; 34 + register struct __kernel_old_timeval *tv asm("a0") = _tv; 35 + register long ret asm("v0"); 36 + register long nr asm("v0") = __NR_gettimeofday; 37 + register long error asm("a3"); 38 + 39 + asm volatile( 40 + " syscall\n" 41 + : "=r" (ret), "=r" (error) 42 + : "r" (tv), "r" (tz), "r" (nr) 43 + : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", 44 + "$14", "$15", "$24", "$25", "hi", "lo", "memory"); 45 + 46 + return error ? -ret : ret; 47 + } 48 + 49 + #else 50 + 51 + static __always_inline long gettimeofday_fallback( 52 + struct __kernel_old_timeval *_tv, 53 + struct timezone *_tz) 54 + { 55 + return -1; 56 + } 57 + 58 + #endif 59 + 60 + static __always_inline long clock_gettime_fallback( 61 + clockid_t _clkid, 62 + struct __kernel_timespec *_ts) 63 + { 64 + register struct __kernel_timespec *ts asm("a1") = _ts; 65 + register clockid_t clkid asm("a0") = _clkid; 66 + register long ret asm("v0"); 67 + #if _MIPS_SIM == _MIPS_SIM_ABI64 68 + register long nr asm("v0") = __NR_clock_gettime; 69 + #else 70 + register long nr asm("v0") = __NR_clock_gettime64; 71 + #endif 72 + register long error asm("a3"); 73 + 74 + asm volatile( 75 + " syscall\n" 76 + : "=r" (ret), "=r" (error) 77 + : "r" (clkid), "r" (ts), "r" (nr) 78 + : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", 79 + "$14", "$15", "$24", "$25", "hi", "lo", "memory"); 80 + 81 + return error ? -ret : ret; 82 + } 83 + 84 + static __always_inline int clock_getres_fallback( 85 + clockid_t _clkid, 86 + struct __kernel_timespec *_ts) 87 + { 88 + register struct __kernel_timespec *ts asm("a1") = _ts; 89 + register clockid_t clkid asm("a0") = _clkid; 90 + register long ret asm("v0"); 91 + #if _MIPS_SIM == _MIPS_SIM_ABI64 92 + register long nr asm("v0") = __NR_clock_getres; 93 + #else 94 + register long nr asm("v0") = __NR_clock_getres_time64; 95 + #endif 96 + register long error asm("a3"); 97 + 98 + asm volatile( 99 + " syscall\n" 100 + : "=r" (ret), "=r" (error) 101 + : "r" (clkid), "r" (ts), "r" (nr) 102 + : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", 103 + "$14", "$15", "$24", "$25", "hi", "lo", "memory"); 104 + 105 + return error ? -ret : ret; 106 + } 107 + 108 + #if _MIPS_SIM != _MIPS_SIM_ABI64 109 + 110 + #define VDSO_HAS_32BIT_FALLBACK 1 111 + 112 + static __always_inline long clock_gettime32_fallback( 113 + clockid_t _clkid, 114 + struct old_timespec32 *_ts) 115 + { 116 + register struct old_timespec32 *ts asm("a1") = _ts; 117 + register clockid_t clkid asm("a0") = _clkid; 118 + register long ret asm("v0"); 119 + register long nr asm("v0") = __NR_clock_gettime; 120 + register long error asm("a3"); 121 + 122 + asm volatile( 123 + " syscall\n" 124 + : "=r" (ret), "=r" (error) 125 + : "r" (clkid), "r" (ts), "r" (nr) 126 + : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", 127 + "$14", "$15", "$24", "$25", "hi", "lo", "memory"); 128 + 129 + return error ? -ret : ret; 130 + } 131 + 132 + static __always_inline int clock_getres32_fallback( 133 + clockid_t _clkid, 134 + struct old_timespec32 *_ts) 135 + { 136 + register struct old_timespec32 *ts asm("a1") = _ts; 137 + register clockid_t clkid asm("a0") = _clkid; 138 + register long ret asm("v0"); 139 + register long nr asm("v0") = __NR_clock_getres; 140 + register long error asm("a3"); 141 + 142 + asm volatile( 143 + " syscall\n" 144 + : "=r" (ret), "=r" (error) 145 + : "r" (clkid), "r" (ts), "r" (nr) 146 + : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", 147 + "$14", "$15", "$24", "$25", "hi", "lo", "memory"); 148 + 149 + return error ? -ret : ret; 150 + } 151 + #endif 152 + 153 + #ifdef CONFIG_CSRC_R4K 154 + 155 + static __always_inline u64 read_r4k_count(void) 156 + { 157 + unsigned int count; 158 + 159 + __asm__ __volatile__( 160 + " .set push\n" 161 + " .set mips32r2\n" 162 + " rdhwr %0, $2\n" 163 + " .set pop\n" 164 + : "=r" (count)); 165 + 166 + return count; 167 + } 168 + 169 + #endif 170 + 171 + #ifdef CONFIG_CLKSRC_MIPS_GIC 172 + 173 + static __always_inline u64 read_gic_count(const struct vdso_data *data) 174 + { 175 + void __iomem *gic = get_gic(data); 176 + u32 hi, hi2, lo; 177 + 178 + do { 179 + hi = __raw_readl(gic + sizeof(lo)); 180 + lo = __raw_readl(gic); 181 + hi2 = __raw_readl(gic + sizeof(lo)); 182 + } while (hi2 != hi); 183 + 184 + return (((u64)hi) << 32) + lo; 185 + } 186 + 187 + #endif 188 + 189 + static __always_inline u64 __arch_get_hw_counter(s32 clock_mode) 190 + { 191 + #ifdef CONFIG_CLKSRC_MIPS_GIC 192 + const struct vdso_data *data = get_vdso_data(); 193 + #endif 194 + u64 cycle_now; 195 + 196 + switch (clock_mode) { 197 + #ifdef CONFIG_CSRC_R4K 198 + case VDSO_CLOCK_R4K: 199 + cycle_now = read_r4k_count(); 200 + break; 201 + #endif 202 + #ifdef CONFIG_CLKSRC_MIPS_GIC 203 + case VDSO_CLOCK_GIC: 204 + cycle_now = read_gic_count(data); 205 + break; 206 + #endif 207 + default: 208 + cycle_now = 0; 209 + break; 210 + } 211 + 212 + return cycle_now; 213 + } 214 + 215 + static __always_inline const struct vdso_data *__arch_get_vdso_data(void) 216 + { 217 + return get_vdso_data(); 218 + } 219 + 220 + #endif /* !__ASSEMBLY__ */ 221 + 222 + #endif /* __ASM_VDSO_GETTIMEOFDAY_H */
+43
arch/mips/include/asm/vdso/vsyscall.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __ASM_VDSO_VSYSCALL_H 3 + #define __ASM_VDSO_VSYSCALL_H 4 + 5 + #ifndef __ASSEMBLY__ 6 + 7 + #include <linux/timekeeper_internal.h> 8 + #include <vdso/datapage.h> 9 + 10 + extern struct vdso_data *vdso_data; 11 + 12 + /* 13 + * Update the vDSO data page to keep in sync with kernel timekeeping. 14 + */ 15 + static __always_inline 16 + struct vdso_data *__mips_get_k_vdso_data(void) 17 + { 18 + return vdso_data; 19 + } 20 + #define __arch_get_k_vdso_data __mips_get_k_vdso_data 21 + 22 + static __always_inline 23 + int __mips_get_clock_mode(struct timekeeper *tk) 24 + { 25 + u32 clock_mode = tk->tkr_mono.clock->archdata.vdso_clock_mode; 26 + 27 + return clock_mode; 28 + } 29 + #define __arch_get_clock_mode __mips_get_clock_mode 30 + 31 + static __always_inline 32 + int __mips_use_vsyscall(struct vdso_data *vdata) 33 + { 34 + return (vdata[CS_HRES_COARSE].clock_mode != VDSO_CLOCK_NONE); 35 + } 36 + #define __arch_use_vsyscall __mips_use_vsyscall 37 + 38 + /* The asm-generic header needs to be included after the definitions above */ 39 + #include <asm-generic/vdso/vsyscall.h> 40 + 41 + #endif /* !__ASSEMBLY__ */ 42 + 43 + #endif /* __ASM_VDSO_VSYSCALL_H */
-13
arch/mips/include/asm/war.h
··· 129 129 #endif 130 130 131 131 /* 132 - * When an interrupt happens on a CP0 register read instruction, CPU may 133 - * lock up or read corrupted values of CP0 registers after it enters 134 - * the exception handler. 135 - * 136 - * This workaround makes sure that we read a "safe" CP0 register as the 137 - * first thing in the exception handler, which breaks one of the 138 - * pre-conditions for this problem. 139 - */ 140 - #ifndef R5432_CP0_INTERRUPT_WAR 141 - #error Check setting of R5432_CP0_INTERRUPT_WAR for your platform 142 - #endif 143 - 144 - /* 145 132 * Workaround for the Sibyte M3 errata the text of which can be found at 146 133 * 147 134 * http://sibyte.broadcom.com/hw/bcm1250/docs/pass2errata.txt
+1 -6
arch/mips/jz4740/Makefile
··· 5 5 6 6 # Object file lists. 7 7 8 - obj-y += prom.o time.o reset.o setup.o \ 9 - platform.o timer.o 8 + obj-y += prom.o time.o reset.o setup.o timer.o 10 9 11 10 CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt 12 - 13 - # board specific support 14 - 15 - obj-$(CONFIG_JZ4740_QI_LB60) += board-qi_lb60.o 16 11 17 12 # PM support 18 13
-523
arch/mips/jz4740/board-qi_lb60.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-or-later 2 - /* 3 - * linux/arch/mips/jz4740/board-qi_lb60.c 4 - * 5 - * QI_LB60 board support 6 - * 7 - * Copyright (c) 2009 Qi Hardware inc., 8 - * Author: Xiangfu Liu <xiangfu@qi-hardware.com> 9 - * Copyright 2010, Lars-Peter Clausen <lars@metafoo.de> 10 - */ 11 - 12 - #include <linux/kernel.h> 13 - #include <linux/init.h> 14 - #include <linux/gpio.h> 15 - #include <linux/gpio/machine.h> 16 - 17 - #include <linux/input.h> 18 - #include <linux/gpio_keys.h> 19 - #include <linux/input/matrix_keypad.h> 20 - #include <linux/spi/spi.h> 21 - #include <linux/spi/spi_gpio.h> 22 - #include <linux/pinctrl/machine.h> 23 - #include <linux/pinctrl/pinconf-generic.h> 24 - #include <linux/power_supply.h> 25 - #include <linux/power/jz4740-battery.h> 26 - #include <linux/power/gpio-charger.h> 27 - #include <linux/pwm.h> 28 - 29 - #include <linux/platform_data/jz4740/jz4740_nand.h> 30 - 31 - #include <asm/mach-jz4740/gpio.h> 32 - #include <asm/mach-jz4740/jz4740_fb.h> 33 - #include <asm/mach-jz4740/jz4740_mmc.h> 34 - 35 - #include <linux/regulator/fixed.h> 36 - #include <linux/regulator/machine.h> 37 - 38 - #include <asm/mach-jz4740/platform.h> 39 - 40 - /* GPIOs */ 41 - #define QI_LB60_GPIO_KEYOUT(x) (JZ_GPIO_PORTC(10) + (x)) 42 - #define QI_LB60_GPIO_KEYIN(x) (JZ_GPIO_PORTD(18) + (x)) 43 - #define QI_LB60_GPIO_KEYIN8 JZ_GPIO_PORTD(26) 44 - 45 - /* NAND */ 46 - 47 - /* Early prototypes of the QI LB60 had only 1GB of NAND. 48 - * In order to support these devices as well the partition and ecc layout is 49 - * initialized depending on the NAND size */ 50 - static struct mtd_partition qi_lb60_partitions_1gb[] = { 51 - { 52 - .name = "NAND BOOT partition", 53 - .offset = 0 * 0x100000, 54 - .size = 4 * 0x100000, 55 - }, 56 - { 57 - .name = "NAND KERNEL partition", 58 - .offset = 4 * 0x100000, 59 - .size = 4 * 0x100000, 60 - }, 61 - { 62 - .name = "NAND ROOTFS partition", 63 - .offset = 8 * 0x100000, 64 - .size = (504 + 512) * 0x100000, 65 - }, 66 - }; 67 - 68 - static struct mtd_partition qi_lb60_partitions_2gb[] = { 69 - { 70 - .name = "NAND BOOT partition", 71 - .offset = 0 * 0x100000, 72 - .size = 4 * 0x100000, 73 - }, 74 - { 75 - .name = "NAND KERNEL partition", 76 - .offset = 4 * 0x100000, 77 - .size = 4 * 0x100000, 78 - }, 79 - { 80 - .name = "NAND ROOTFS partition", 81 - .offset = 8 * 0x100000, 82 - .size = (504 + 512 + 1024) * 0x100000, 83 - }, 84 - }; 85 - 86 - static int qi_lb60_ooblayout_ecc(struct mtd_info *mtd, int section, 87 - struct mtd_oob_region *oobregion) 88 - { 89 - if (section) 90 - return -ERANGE; 91 - 92 - oobregion->length = 36; 93 - oobregion->offset = 6; 94 - 95 - if (mtd->oobsize == 128) { 96 - oobregion->length *= 2; 97 - oobregion->offset *= 2; 98 - } 99 - 100 - return 0; 101 - } 102 - 103 - static int qi_lb60_ooblayout_free(struct mtd_info *mtd, int section, 104 - struct mtd_oob_region *oobregion) 105 - { 106 - int eccbytes = 36, eccoff = 6; 107 - 108 - if (section > 1) 109 - return -ERANGE; 110 - 111 - if (mtd->oobsize == 128) { 112 - eccbytes *= 2; 113 - eccoff *= 2; 114 - } 115 - 116 - if (!section) { 117 - oobregion->offset = 2; 118 - oobregion->length = eccoff - 2; 119 - } else { 120 - oobregion->offset = eccoff + eccbytes; 121 - oobregion->length = mtd->oobsize - oobregion->offset; 122 - } 123 - 124 - return 0; 125 - } 126 - 127 - static const struct mtd_ooblayout_ops qi_lb60_ooblayout_ops = { 128 - .ecc = qi_lb60_ooblayout_ecc, 129 - .free = qi_lb60_ooblayout_free, 130 - }; 131 - 132 - static void qi_lb60_nand_ident(struct platform_device *pdev, 133 - struct mtd_info *mtd, struct mtd_partition **partitions, 134 - int *num_partitions) 135 - { 136 - struct nand_chip *chip = mtd_to_nand(mtd); 137 - 138 - if (chip->page_shift == 12) { 139 - *partitions = qi_lb60_partitions_2gb; 140 - *num_partitions = ARRAY_SIZE(qi_lb60_partitions_2gb); 141 - } else { 142 - *partitions = qi_lb60_partitions_1gb; 143 - *num_partitions = ARRAY_SIZE(qi_lb60_partitions_1gb); 144 - } 145 - 146 - mtd_set_ooblayout(mtd, &qi_lb60_ooblayout_ops); 147 - } 148 - 149 - static struct jz_nand_platform_data qi_lb60_nand_pdata = { 150 - .ident_callback = qi_lb60_nand_ident, 151 - .banks = { 1 }, 152 - }; 153 - 154 - static struct gpiod_lookup_table qi_lb60_nand_gpio_table = { 155 - .dev_id = "jz4740-nand.0", 156 - .table = { 157 - GPIO_LOOKUP("GPIOC", 30, "busy", 0), 158 - { }, 159 - }, 160 - }; 161 - 162 - 163 - /* Keyboard*/ 164 - 165 - #define KEY_QI_QI KEY_F13 166 - #define KEY_QI_UPRED KEY_RIGHTALT 167 - #define KEY_QI_VOLUP KEY_VOLUMEUP 168 - #define KEY_QI_VOLDOWN KEY_VOLUMEDOWN 169 - #define KEY_QI_FN KEY_LEFTCTRL 170 - 171 - static const uint32_t qi_lb60_keymap[] = { 172 - KEY(0, 0, KEY_F1), /* S2 */ 173 - KEY(0, 1, KEY_F2), /* S3 */ 174 - KEY(0, 2, KEY_F3), /* S4 */ 175 - KEY(0, 3, KEY_F4), /* S5 */ 176 - KEY(0, 4, KEY_F5), /* S6 */ 177 - KEY(0, 5, KEY_F6), /* S7 */ 178 - KEY(0, 6, KEY_F7), /* S8 */ 179 - 180 - KEY(1, 0, KEY_Q), /* S10 */ 181 - KEY(1, 1, KEY_W), /* S11 */ 182 - KEY(1, 2, KEY_E), /* S12 */ 183 - KEY(1, 3, KEY_R), /* S13 */ 184 - KEY(1, 4, KEY_T), /* S14 */ 185 - KEY(1, 5, KEY_Y), /* S15 */ 186 - KEY(1, 6, KEY_U), /* S16 */ 187 - KEY(1, 7, KEY_I), /* S17 */ 188 - KEY(2, 0, KEY_A), /* S18 */ 189 - KEY(2, 1, KEY_S), /* S19 */ 190 - KEY(2, 2, KEY_D), /* S20 */ 191 - KEY(2, 3, KEY_F), /* S21 */ 192 - KEY(2, 4, KEY_G), /* S22 */ 193 - KEY(2, 5, KEY_H), /* S23 */ 194 - KEY(2, 6, KEY_J), /* S24 */ 195 - KEY(2, 7, KEY_K), /* S25 */ 196 - KEY(3, 0, KEY_ESC), /* S26 */ 197 - KEY(3, 1, KEY_Z), /* S27 */ 198 - KEY(3, 2, KEY_X), /* S28 */ 199 - KEY(3, 3, KEY_C), /* S29 */ 200 - KEY(3, 4, KEY_V), /* S30 */ 201 - KEY(3, 5, KEY_B), /* S31 */ 202 - KEY(3, 6, KEY_N), /* S32 */ 203 - KEY(3, 7, KEY_M), /* S33 */ 204 - KEY(4, 0, KEY_TAB), /* S34 */ 205 - KEY(4, 1, KEY_CAPSLOCK), /* S35 */ 206 - KEY(4, 2, KEY_BACKSLASH), /* S36 */ 207 - KEY(4, 3, KEY_APOSTROPHE), /* S37 */ 208 - KEY(4, 4, KEY_COMMA), /* S38 */ 209 - KEY(4, 5, KEY_DOT), /* S39 */ 210 - KEY(4, 6, KEY_SLASH), /* S40 */ 211 - KEY(4, 7, KEY_UP), /* S41 */ 212 - KEY(5, 0, KEY_O), /* S42 */ 213 - KEY(5, 1, KEY_L), /* S43 */ 214 - KEY(5, 2, KEY_EQUAL), /* S44 */ 215 - KEY(5, 3, KEY_QI_UPRED), /* S45 */ 216 - KEY(5, 4, KEY_SPACE), /* S46 */ 217 - KEY(5, 5, KEY_QI_QI), /* S47 */ 218 - KEY(5, 6, KEY_RIGHTCTRL), /* S48 */ 219 - KEY(5, 7, KEY_LEFT), /* S49 */ 220 - KEY(6, 0, KEY_F8), /* S50 */ 221 - KEY(6, 1, KEY_P), /* S51 */ 222 - KEY(6, 2, KEY_BACKSPACE),/* S52 */ 223 - KEY(6, 3, KEY_ENTER), /* S53 */ 224 - KEY(6, 4, KEY_QI_VOLUP), /* S54 */ 225 - KEY(6, 5, KEY_QI_VOLDOWN), /* S55 */ 226 - KEY(6, 6, KEY_DOWN), /* S56 */ 227 - KEY(6, 7, KEY_RIGHT), /* S57 */ 228 - 229 - KEY(7, 0, KEY_LEFTSHIFT), /* S58 */ 230 - KEY(7, 1, KEY_LEFTALT), /* S59 */ 231 - KEY(7, 2, KEY_QI_FN), /* S60 */ 232 - }; 233 - 234 - static const struct matrix_keymap_data qi_lb60_keymap_data = { 235 - .keymap = qi_lb60_keymap, 236 - .keymap_size = ARRAY_SIZE(qi_lb60_keymap), 237 - }; 238 - 239 - static const unsigned int qi_lb60_keypad_cols[] = { 240 - QI_LB60_GPIO_KEYOUT(0), 241 - QI_LB60_GPIO_KEYOUT(1), 242 - QI_LB60_GPIO_KEYOUT(2), 243 - QI_LB60_GPIO_KEYOUT(3), 244 - QI_LB60_GPIO_KEYOUT(4), 245 - QI_LB60_GPIO_KEYOUT(5), 246 - QI_LB60_GPIO_KEYOUT(6), 247 - QI_LB60_GPIO_KEYOUT(7), 248 - }; 249 - 250 - static const unsigned int qi_lb60_keypad_rows[] = { 251 - QI_LB60_GPIO_KEYIN(0), 252 - QI_LB60_GPIO_KEYIN(1), 253 - QI_LB60_GPIO_KEYIN(2), 254 - QI_LB60_GPIO_KEYIN(3), 255 - QI_LB60_GPIO_KEYIN(4), 256 - QI_LB60_GPIO_KEYIN(5), 257 - QI_LB60_GPIO_KEYIN(6), 258 - QI_LB60_GPIO_KEYIN8, 259 - }; 260 - 261 - static struct matrix_keypad_platform_data qi_lb60_pdata = { 262 - .keymap_data = &qi_lb60_keymap_data, 263 - .col_gpios = qi_lb60_keypad_cols, 264 - .row_gpios = qi_lb60_keypad_rows, 265 - .num_col_gpios = ARRAY_SIZE(qi_lb60_keypad_cols), 266 - .num_row_gpios = ARRAY_SIZE(qi_lb60_keypad_rows), 267 - .col_scan_delay_us = 10, 268 - .debounce_ms = 10, 269 - .wakeup = 1, 270 - .active_low = 1, 271 - }; 272 - 273 - static struct platform_device qi_lb60_keypad = { 274 - .name = "matrix-keypad", 275 - .id = -1, 276 - .dev = { 277 - .platform_data = &qi_lb60_pdata, 278 - }, 279 - }; 280 - 281 - /* Display */ 282 - static struct fb_videomode qi_lb60_video_modes[] = { 283 - { 284 - .name = "320x240", 285 - .xres = 320, 286 - .yres = 240, 287 - .refresh = 30, 288 - .left_margin = 140, 289 - .right_margin = 273, 290 - .upper_margin = 20, 291 - .lower_margin = 2, 292 - .hsync_len = 1, 293 - .vsync_len = 1, 294 - .sync = 0, 295 - .vmode = FB_VMODE_NONINTERLACED, 296 - }, 297 - }; 298 - 299 - static struct jz4740_fb_platform_data qi_lb60_fb_pdata = { 300 - .width = 60, 301 - .height = 45, 302 - .num_modes = ARRAY_SIZE(qi_lb60_video_modes), 303 - .modes = qi_lb60_video_modes, 304 - .bpp = 24, 305 - .lcd_type = JZ_LCD_TYPE_8BIT_SERIAL, 306 - .pixclk_falling_edge = 1, 307 - }; 308 - 309 - struct spi_gpio_platform_data qi_lb60_spigpio_platform_data = { 310 - .num_chipselect = 1, 311 - }; 312 - 313 - static struct platform_device qi_lb60_spigpio_device = { 314 - .name = "spi_gpio", 315 - .id = 1, 316 - .dev = { 317 - .platform_data = &qi_lb60_spigpio_platform_data, 318 - }, 319 - }; 320 - 321 - static struct gpiod_lookup_table qi_lb60_spigpio_gpio_table = { 322 - .dev_id = "spi_gpio", 323 - .table = { 324 - GPIO_LOOKUP("GPIOC", 23, 325 - "sck", GPIO_ACTIVE_HIGH), 326 - GPIO_LOOKUP("GPIOC", 22, 327 - "mosi", GPIO_ACTIVE_HIGH), 328 - GPIO_LOOKUP("GPIOC", 21, 329 - "cs", GPIO_ACTIVE_HIGH), 330 - { }, 331 - }, 332 - }; 333 - 334 - static struct spi_board_info qi_lb60_spi_board_info[] = { 335 - { 336 - .modalias = "ili8960", 337 - .chip_select = 0, 338 - .bus_num = 1, 339 - .max_speed_hz = 30 * 1000, 340 - .mode = SPI_3WIRE, 341 - }, 342 - }; 343 - 344 - /* Battery */ 345 - static struct jz_battery_platform_data qi_lb60_battery_pdata = { 346 - .gpio_charge = JZ_GPIO_PORTC(27), 347 - .gpio_charge_active_low = 1, 348 - .info = { 349 - .name = "battery", 350 - .technology = POWER_SUPPLY_TECHNOLOGY_LIPO, 351 - .voltage_max_design = 4200000, 352 - .voltage_min_design = 3600000, 353 - }, 354 - }; 355 - 356 - /* GPIO Key: power */ 357 - static struct gpio_keys_button qi_lb60_gpio_keys_buttons[] = { 358 - [0] = { 359 - .code = KEY_POWER, 360 - .gpio = JZ_GPIO_PORTD(29), 361 - .active_low = 1, 362 - .desc = "Power", 363 - .wakeup = 1, 364 - }, 365 - }; 366 - 367 - static struct gpio_keys_platform_data qi_lb60_gpio_keys_data = { 368 - .nbuttons = ARRAY_SIZE(qi_lb60_gpio_keys_buttons), 369 - .buttons = qi_lb60_gpio_keys_buttons, 370 - }; 371 - 372 - static struct platform_device qi_lb60_gpio_keys = { 373 - .name = "gpio-keys", 374 - .id = -1, 375 - .dev = { 376 - .platform_data = &qi_lb60_gpio_keys_data, 377 - } 378 - }; 379 - 380 - static struct jz4740_mmc_platform_data qi_lb60_mmc_pdata = { 381 - /* Intentionally left blank */ 382 - }; 383 - 384 - static struct gpiod_lookup_table qi_lb60_mmc_gpio_table = { 385 - .dev_id = "jz4740-mmc.0", 386 - .table = { 387 - GPIO_LOOKUP("GPIOD", 0, "cd", GPIO_ACTIVE_HIGH), 388 - GPIO_LOOKUP("GPIOD", 2, "power", GPIO_ACTIVE_LOW), 389 - { }, 390 - }, 391 - }; 392 - 393 - /* beeper */ 394 - static struct pwm_lookup qi_lb60_pwm_lookup[] = { 395 - PWM_LOOKUP("jz4740-pwm", 4, "pwm-beeper", NULL, 0, 396 - PWM_POLARITY_NORMAL), 397 - }; 398 - 399 - static struct platform_device qi_lb60_pwm_beeper = { 400 - .name = "pwm-beeper", 401 - .id = -1, 402 - }; 403 - 404 - /* charger */ 405 - static char *qi_lb60_batteries[] = { 406 - "battery", 407 - }; 408 - 409 - static struct gpio_charger_platform_data qi_lb60_charger_pdata = { 410 - .name = "usb", 411 - .type = POWER_SUPPLY_TYPE_USB, 412 - .gpio = JZ_GPIO_PORTD(28), 413 - .gpio_active_low = 1, 414 - .supplied_to = qi_lb60_batteries, 415 - .num_supplicants = ARRAY_SIZE(qi_lb60_batteries), 416 - }; 417 - 418 - static struct platform_device qi_lb60_charger_device = { 419 - .name = "gpio-charger", 420 - .dev = { 421 - .platform_data = &qi_lb60_charger_pdata, 422 - }, 423 - }; 424 - 425 - /* audio */ 426 - static struct platform_device qi_lb60_audio_device = { 427 - .name = "qi-lb60-audio", 428 - .id = -1, 429 - }; 430 - 431 - static struct gpiod_lookup_table qi_lb60_audio_gpio_table = { 432 - .dev_id = "qi-lb60-audio", 433 - .table = { 434 - GPIO_LOOKUP("GPIOB", 29, "snd", 0), 435 - GPIO_LOOKUP("GPIOD", 4, "amp", 0), 436 - { }, 437 - }, 438 - }; 439 - 440 - static struct platform_device *jz_platform_devices[] __initdata = { 441 - &jz4740_udc_device, 442 - &jz4740_udc_xceiv_device, 443 - &jz4740_mmc_device, 444 - &jz4740_nand_device, 445 - &qi_lb60_keypad, 446 - &qi_lb60_spigpio_device, 447 - &jz4740_framebuffer_device, 448 - &jz4740_pcm_device, 449 - &jz4740_i2s_device, 450 - &jz4740_codec_device, 451 - &jz4740_adc_device, 452 - &jz4740_pwm_device, 453 - &jz4740_dma_device, 454 - &qi_lb60_gpio_keys, 455 - &qi_lb60_pwm_beeper, 456 - &qi_lb60_charger_device, 457 - &qi_lb60_audio_device, 458 - }; 459 - 460 - static unsigned long pin_cfg_bias_disable[] = { 461 - PIN_CONFIG_BIAS_DISABLE, 462 - }; 463 - 464 - static struct pinctrl_map pin_map[] __initdata = { 465 - /* NAND pin configuration */ 466 - PIN_MAP_MUX_GROUP_DEFAULT("jz4740-nand", 467 - "10010000.pin-controller", "nand-cs1", "nand"), 468 - 469 - /* fbdev pin configuration */ 470 - PIN_MAP_MUX_GROUP("jz4740-fb", PINCTRL_STATE_DEFAULT, 471 - "10010000.pin-controller", "lcd-8bit", "lcd"), 472 - PIN_MAP_MUX_GROUP("jz4740-fb", PINCTRL_STATE_SLEEP, 473 - "10010000.pin-controller", "lcd-no-pins", "lcd"), 474 - 475 - /* MMC pin configuration */ 476 - PIN_MAP_MUX_GROUP_DEFAULT("jz4740-mmc.0", 477 - "10010000.pin-controller", "mmc-1bit", "mmc"), 478 - PIN_MAP_MUX_GROUP_DEFAULT("jz4740-mmc.0", 479 - "10010000.pin-controller", "mmc-4bit", "mmc"), 480 - PIN_MAP_CONFIGS_PIN_DEFAULT("jz4740-mmc.0", 481 - "10010000.pin-controller", "PD0", pin_cfg_bias_disable), 482 - PIN_MAP_CONFIGS_PIN_DEFAULT("jz4740-mmc.0", 483 - "10010000.pin-controller", "PD2", pin_cfg_bias_disable), 484 - 485 - /* PWM pin configuration */ 486 - PIN_MAP_MUX_GROUP_DEFAULT("jz4740-pwm", 487 - "10010000.pin-controller", "pwm4", "pwm4"), 488 - }; 489 - 490 - 491 - static int __init qi_lb60_init_platform_devices(void) 492 - { 493 - jz4740_framebuffer_device.dev.platform_data = &qi_lb60_fb_pdata; 494 - jz4740_nand_device.dev.platform_data = &qi_lb60_nand_pdata; 495 - jz4740_adc_device.dev.platform_data = &qi_lb60_battery_pdata; 496 - jz4740_mmc_device.dev.platform_data = &qi_lb60_mmc_pdata; 497 - 498 - gpiod_add_lookup_table(&qi_lb60_audio_gpio_table); 499 - gpiod_add_lookup_table(&qi_lb60_nand_gpio_table); 500 - gpiod_add_lookup_table(&qi_lb60_spigpio_gpio_table); 501 - gpiod_add_lookup_table(&qi_lb60_mmc_gpio_table); 502 - 503 - spi_register_board_info(qi_lb60_spi_board_info, 504 - ARRAY_SIZE(qi_lb60_spi_board_info)); 505 - 506 - pwm_add_table(qi_lb60_pwm_lookup, ARRAY_SIZE(qi_lb60_pwm_lookup)); 507 - pinctrl_register_mappings(pin_map, ARRAY_SIZE(pin_map)); 508 - 509 - return platform_add_devices(jz_platform_devices, 510 - ARRAY_SIZE(jz_platform_devices)); 511 - 512 - } 513 - 514 - static int __init qi_lb60_board_setup(void) 515 - { 516 - printk(KERN_INFO "Qi Hardware JZ4740 QI LB60 setup\n"); 517 - 518 - if (qi_lb60_init_platform_devices()) 519 - panic("Failed to initialize platform devices"); 520 - 521 - return 0; 522 - } 523 - arch_initcall(qi_lb60_board_setup);
-250
arch/mips/jz4740/platform.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-or-later 2 - /* 3 - * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> 4 - * JZ4740 platform devices 5 - */ 6 - 7 - #include <linux/clk.h> 8 - #include <linux/device.h> 9 - #include <linux/kernel.h> 10 - #include <linux/platform_device.h> 11 - #include <linux/resource.h> 12 - 13 - #include <linux/dma-mapping.h> 14 - 15 - #include <linux/usb/musb.h> 16 - 17 - #include <asm/mach-jz4740/platform.h> 18 - #include <asm/mach-jz4740/base.h> 19 - #include <asm/mach-jz4740/irq.h> 20 - 21 - #include <linux/serial_core.h> 22 - #include <linux/serial_8250.h> 23 - 24 - /* USB Device Controller */ 25 - struct platform_device jz4740_udc_xceiv_device = { 26 - .name = "usb_phy_generic", 27 - .id = 0, 28 - }; 29 - 30 - static struct resource jz4740_udc_resources[] = { 31 - [0] = { 32 - .start = JZ4740_UDC_BASE_ADDR, 33 - .end = JZ4740_UDC_BASE_ADDR + 0x10000 - 1, 34 - .flags = IORESOURCE_MEM, 35 - }, 36 - [1] = { 37 - .start = JZ4740_IRQ_UDC, 38 - .end = JZ4740_IRQ_UDC, 39 - .flags = IORESOURCE_IRQ, 40 - .name = "mc", 41 - }, 42 - }; 43 - 44 - struct platform_device jz4740_udc_device = { 45 - .name = "musb-jz4740", 46 - .id = -1, 47 - .dev = { 48 - .dma_mask = &jz4740_udc_device.dev.coherent_dma_mask, 49 - .coherent_dma_mask = DMA_BIT_MASK(32), 50 - }, 51 - .num_resources = ARRAY_SIZE(jz4740_udc_resources), 52 - .resource = jz4740_udc_resources, 53 - }; 54 - 55 - /* MMC/SD controller */ 56 - static struct resource jz4740_mmc_resources[] = { 57 - { 58 - .start = JZ4740_MSC_BASE_ADDR, 59 - .end = JZ4740_MSC_BASE_ADDR + 0x1000 - 1, 60 - .flags = IORESOURCE_MEM, 61 - }, 62 - { 63 - .start = JZ4740_IRQ_MSC, 64 - .end = JZ4740_IRQ_MSC, 65 - .flags = IORESOURCE_IRQ, 66 - } 67 - }; 68 - 69 - struct platform_device jz4740_mmc_device = { 70 - .name = "jz4740-mmc", 71 - .id = 0, 72 - .dev = { 73 - .dma_mask = &jz4740_mmc_device.dev.coherent_dma_mask, 74 - .coherent_dma_mask = DMA_BIT_MASK(32), 75 - }, 76 - .num_resources = ARRAY_SIZE(jz4740_mmc_resources), 77 - .resource = jz4740_mmc_resources, 78 - }; 79 - 80 - /* I2C controller */ 81 - static struct resource jz4740_i2c_resources[] = { 82 - { 83 - .start = JZ4740_I2C_BASE_ADDR, 84 - .end = JZ4740_I2C_BASE_ADDR + 0x1000 - 1, 85 - .flags = IORESOURCE_MEM, 86 - }, 87 - { 88 - .start = JZ4740_IRQ_I2C, 89 - .end = JZ4740_IRQ_I2C, 90 - .flags = IORESOURCE_IRQ, 91 - } 92 - }; 93 - 94 - struct platform_device jz4740_i2c_device = { 95 - .name = "jz4740-i2c", 96 - .id = 0, 97 - .num_resources = ARRAY_SIZE(jz4740_i2c_resources), 98 - .resource = jz4740_i2c_resources, 99 - }; 100 - 101 - /* NAND controller */ 102 - static struct resource jz4740_nand_resources[] = { 103 - { 104 - .name = "mmio", 105 - .start = JZ4740_EMC_BASE_ADDR, 106 - .end = JZ4740_EMC_BASE_ADDR + 0x1000 - 1, 107 - .flags = IORESOURCE_MEM, 108 - }, 109 - { 110 - .name = "bank1", 111 - .start = 0x18000000, 112 - .end = 0x180C0000 - 1, 113 - .flags = IORESOURCE_MEM, 114 - }, 115 - { 116 - .name = "bank2", 117 - .start = 0x14000000, 118 - .end = 0x140C0000 - 1, 119 - .flags = IORESOURCE_MEM, 120 - }, 121 - { 122 - .name = "bank3", 123 - .start = 0x0C000000, 124 - .end = 0x0C0C0000 - 1, 125 - .flags = IORESOURCE_MEM, 126 - }, 127 - { 128 - .name = "bank4", 129 - .start = 0x08000000, 130 - .end = 0x080C0000 - 1, 131 - .flags = IORESOURCE_MEM, 132 - }, 133 - }; 134 - 135 - struct platform_device jz4740_nand_device = { 136 - .name = "jz4740-nand", 137 - .num_resources = ARRAY_SIZE(jz4740_nand_resources), 138 - .resource = jz4740_nand_resources, 139 - }; 140 - 141 - /* LCD controller */ 142 - static struct resource jz4740_framebuffer_resources[] = { 143 - { 144 - .start = JZ4740_LCD_BASE_ADDR, 145 - .end = JZ4740_LCD_BASE_ADDR + 0x1000 - 1, 146 - .flags = IORESOURCE_MEM, 147 - }, 148 - }; 149 - 150 - struct platform_device jz4740_framebuffer_device = { 151 - .name = "jz4740-fb", 152 - .id = -1, 153 - .num_resources = ARRAY_SIZE(jz4740_framebuffer_resources), 154 - .resource = jz4740_framebuffer_resources, 155 - .dev = { 156 - .dma_mask = &jz4740_framebuffer_device.dev.coherent_dma_mask, 157 - .coherent_dma_mask = DMA_BIT_MASK(32), 158 - }, 159 - }; 160 - 161 - /* I2S controller */ 162 - static struct resource jz4740_i2s_resources[] = { 163 - { 164 - .start = JZ4740_AIC_BASE_ADDR, 165 - .end = JZ4740_AIC_BASE_ADDR + 0x38 - 1, 166 - .flags = IORESOURCE_MEM, 167 - }, 168 - }; 169 - 170 - struct platform_device jz4740_i2s_device = { 171 - .name = "jz4740-i2s", 172 - .id = -1, 173 - .num_resources = ARRAY_SIZE(jz4740_i2s_resources), 174 - .resource = jz4740_i2s_resources, 175 - }; 176 - 177 - /* PCM */ 178 - struct platform_device jz4740_pcm_device = { 179 - .name = "jz4740-pcm-audio", 180 - .id = -1, 181 - }; 182 - 183 - /* Codec */ 184 - static struct resource jz4740_codec_resources[] = { 185 - { 186 - .start = JZ4740_AIC_BASE_ADDR + 0x80, 187 - .end = JZ4740_AIC_BASE_ADDR + 0x88 - 1, 188 - .flags = IORESOURCE_MEM, 189 - }, 190 - }; 191 - 192 - struct platform_device jz4740_codec_device = { 193 - .name = "jz4740-codec", 194 - .id = -1, 195 - .num_resources = ARRAY_SIZE(jz4740_codec_resources), 196 - .resource = jz4740_codec_resources, 197 - }; 198 - 199 - /* ADC controller */ 200 - static struct resource jz4740_adc_resources[] = { 201 - { 202 - .start = JZ4740_SADC_BASE_ADDR, 203 - .end = JZ4740_SADC_BASE_ADDR + 0x30, 204 - .flags = IORESOURCE_MEM, 205 - }, 206 - { 207 - .start = JZ4740_IRQ_SADC, 208 - .end = JZ4740_IRQ_SADC, 209 - .flags = IORESOURCE_IRQ, 210 - }, 211 - { 212 - .start = JZ4740_IRQ_ADC_BASE, 213 - .end = JZ4740_IRQ_ADC_BASE, 214 - .flags = IORESOURCE_IRQ, 215 - }, 216 - }; 217 - 218 - struct platform_device jz4740_adc_device = { 219 - .name = "jz4740-adc", 220 - .id = -1, 221 - .num_resources = ARRAY_SIZE(jz4740_adc_resources), 222 - .resource = jz4740_adc_resources, 223 - }; 224 - 225 - /* PWM */ 226 - struct platform_device jz4740_pwm_device = { 227 - .name = "jz4740-pwm", 228 - .id = -1, 229 - }; 230 - 231 - /* DMA */ 232 - static struct resource jz4740_dma_resources[] = { 233 - { 234 - .start = JZ4740_DMAC_BASE_ADDR, 235 - .end = JZ4740_DMAC_BASE_ADDR + 0x400 - 1, 236 - .flags = IORESOURCE_MEM, 237 - }, 238 - { 239 - .start = JZ4740_IRQ_DMAC, 240 - .end = JZ4740_IRQ_DMAC, 241 - .flags = IORESOURCE_IRQ, 242 - }, 243 - }; 244 - 245 - struct platform_device jz4740_dma_device = { 246 - .name = "jz4740-dma", 247 - .id = -1, 248 - .num_resources = ARRAY_SIZE(jz4740_dma_resources), 249 - .resource = jz4740_dma_resources, 250 - };
-5
arch/mips/jz4740/prom.c
··· 4 4 * JZ4740 SoC prom code 5 5 */ 6 6 7 - #include <linux/kernel.h> 8 7 #include <linux/init.h> 9 - #include <linux/string.h> 10 - 11 - #include <linux/serial_reg.h> 12 8 13 9 #include <asm/bootinfo.h> 14 10 #include <asm/fw/fw.h> 15 - #include <asm/mach-jz4740/base.h> 16 11 17 12 void __init prom_init(void) 18 13 {
+5 -2
arch/mips/jz4740/setup.c
··· 15 15 #include <asm/bootinfo.h> 16 16 #include <asm/prom.h> 17 17 18 - #include <asm/mach-jz4740/base.h> 19 - 20 18 #include "reset.h" 21 19 20 + #define JZ4740_EMC_BASE_ADDR 0x13010000 22 21 23 22 #define JZ4740_EMC_SDRAM_CTRL 0x80 24 23 ··· 44 45 45 46 static unsigned long __init get_board_mach_type(const void *fdt) 46 47 { 48 + if (!fdt_node_check_compatible(fdt, 0, "ingenic,x1000")) 49 + return MACH_INGENIC_X1000; 47 50 if (!fdt_node_check_compatible(fdt, 0, "ingenic,jz4780")) 48 51 return MACH_INGENIC_JZ4780; 49 52 if (!fdt_node_check_compatible(fdt, 0, "ingenic,jz4770")) ··· 86 85 const char *get_system_type(void) 87 86 { 88 87 switch (mips_machtype) { 88 + case MACH_INGENIC_X1000: 89 + return "X1000"; 89 90 case MACH_INGENIC_JZ4780: 90 91 return "JZ4780"; 91 92 case MACH_INGENIC_JZ4770:
+2 -149
arch/mips/jz4740/time.c
··· 4 4 * JZ4740 platform time support 5 5 */ 6 6 7 - #include <linux/clk.h> 8 7 #include <linux/clk-provider.h> 9 - #include <linux/interrupt.h> 10 - #include <linux/kernel.h> 11 - #include <linux/time.h> 8 + #include <linux/clocksource.h> 12 9 13 - #include <linux/clockchips.h> 14 - #include <linux/sched_clock.h> 15 - 16 - #include <asm/mach-jz4740/irq.h> 17 10 #include <asm/mach-jz4740/timer.h> 18 - #include <asm/time.h> 19 - 20 - #define TIMER_CLOCKEVENT 0 21 - #define TIMER_CLOCKSOURCE 1 22 - 23 - static uint16_t jz4740_jiffies_per_tick; 24 - 25 - static u64 jz4740_clocksource_read(struct clocksource *cs) 26 - { 27 - return jz4740_timer_get_count(TIMER_CLOCKSOURCE); 28 - } 29 - 30 - static struct clocksource jz4740_clocksource = { 31 - .name = "jz4740-timer", 32 - .rating = 200, 33 - .read = jz4740_clocksource_read, 34 - .mask = CLOCKSOURCE_MASK(16), 35 - .flags = CLOCK_SOURCE_IS_CONTINUOUS, 36 - }; 37 - 38 - static u64 notrace jz4740_read_sched_clock(void) 39 - { 40 - return jz4740_timer_get_count(TIMER_CLOCKSOURCE); 41 - } 42 - 43 - static irqreturn_t jz4740_clockevent_irq(int irq, void *devid) 44 - { 45 - struct clock_event_device *cd = devid; 46 - 47 - jz4740_timer_ack_full(TIMER_CLOCKEVENT); 48 - 49 - if (!clockevent_state_periodic(cd)) 50 - jz4740_timer_disable(TIMER_CLOCKEVENT); 51 - 52 - cd->event_handler(cd); 53 - 54 - return IRQ_HANDLED; 55 - } 56 - 57 - static int jz4740_clockevent_set_periodic(struct clock_event_device *evt) 58 - { 59 - jz4740_timer_set_count(TIMER_CLOCKEVENT, 0); 60 - jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick); 61 - jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT); 62 - jz4740_timer_enable(TIMER_CLOCKEVENT); 63 - 64 - return 0; 65 - } 66 - 67 - static int jz4740_clockevent_resume(struct clock_event_device *evt) 68 - { 69 - jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT); 70 - jz4740_timer_enable(TIMER_CLOCKEVENT); 71 - 72 - return 0; 73 - } 74 - 75 - static int jz4740_clockevent_shutdown(struct clock_event_device *evt) 76 - { 77 - jz4740_timer_disable(TIMER_CLOCKEVENT); 78 - 79 - return 0; 80 - } 81 - 82 - static int jz4740_clockevent_set_next(unsigned long evt, 83 - struct clock_event_device *cd) 84 - { 85 - jz4740_timer_set_count(TIMER_CLOCKEVENT, 0); 86 - jz4740_timer_set_period(TIMER_CLOCKEVENT, evt); 87 - jz4740_timer_enable(TIMER_CLOCKEVENT); 88 - 89 - return 0; 90 - } 91 - 92 - static struct clock_event_device jz4740_clockevent = { 93 - .name = "jz4740-timer", 94 - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 95 - .set_next_event = jz4740_clockevent_set_next, 96 - .set_state_shutdown = jz4740_clockevent_shutdown, 97 - .set_state_periodic = jz4740_clockevent_set_periodic, 98 - .set_state_oneshot = jz4740_clockevent_shutdown, 99 - .tick_resume = jz4740_clockevent_resume, 100 - .rating = 200, 101 - #ifdef CONFIG_MACH_JZ4740 102 - .irq = JZ4740_IRQ_TCU0, 103 - #endif 104 - #if defined(CONFIG_MACH_JZ4770) || defined(CONFIG_MACH_JZ4780) 105 - .irq = JZ4780_IRQ_TCU2, 106 - #endif 107 - }; 108 - 109 - static struct irqaction timer_irqaction = { 110 - .handler = jz4740_clockevent_irq, 111 - .flags = IRQF_PERCPU | IRQF_TIMER, 112 - .name = "jz4740-timerirq", 113 - .dev_id = &jz4740_clockevent, 114 - }; 115 11 116 12 void __init plat_time_init(void) 117 13 { 118 - int ret; 119 - uint32_t clk_rate; 120 - uint16_t ctrl; 121 - struct clk *ext_clk; 122 - 123 14 of_clk_init(NULL); 124 15 jz4740_timer_init(); 125 - 126 - ext_clk = clk_get(NULL, "ext"); 127 - if (IS_ERR(ext_clk)) 128 - panic("unable to get ext clock"); 129 - clk_rate = clk_get_rate(ext_clk) >> 4; 130 - clk_put(ext_clk); 131 - 132 - jz4740_jiffies_per_tick = DIV_ROUND_CLOSEST(clk_rate, HZ); 133 - 134 - clockevent_set_clock(&jz4740_clockevent, clk_rate); 135 - jz4740_clockevent.min_delta_ns = clockevent_delta2ns(100, &jz4740_clockevent); 136 - jz4740_clockevent.min_delta_ticks = 100; 137 - jz4740_clockevent.max_delta_ns = clockevent_delta2ns(0xffff, &jz4740_clockevent); 138 - jz4740_clockevent.max_delta_ticks = 0xffff; 139 - jz4740_clockevent.cpumask = cpumask_of(0); 140 - 141 - clockevents_register_device(&jz4740_clockevent); 142 - 143 - ret = clocksource_register_hz(&jz4740_clocksource, clk_rate); 144 - 145 - if (ret) 146 - printk(KERN_ERR "Failed to register clocksource: %d\n", ret); 147 - 148 - sched_clock_register(jz4740_read_sched_clock, 16, clk_rate); 149 - 150 - setup_irq(jz4740_clockevent.irq, &timer_irqaction); 151 - 152 - ctrl = JZ_TIMER_CTRL_PRESCALE_16 | JZ_TIMER_CTRL_SRC_EXT; 153 - 154 - jz4740_timer_set_ctrl(TIMER_CLOCKEVENT, ctrl); 155 - jz4740_timer_set_ctrl(TIMER_CLOCKSOURCE, ctrl); 156 - 157 - jz4740_timer_set_period(TIMER_CLOCKEVENT, jz4740_jiffies_per_tick); 158 - jz4740_timer_irq_full_enable(TIMER_CLOCKEVENT); 159 - 160 - jz4740_timer_set_period(TIMER_CLOCKSOURCE, 0xffff); 161 - 162 - jz4740_timer_enable(TIMER_CLOCKEVENT); 163 - jz4740_timer_enable(TIMER_CLOCKSOURCE); 16 + timer_probe(); 164 17 }
+1 -1
arch/mips/kernel/branch.c
··· 58 58 unsigned long *contpc) 59 59 { 60 60 union mips_instruction insn = (union mips_instruction)dec_insn.insn; 61 + int __maybe_unused bc_false = 0; 61 62 62 63 if (!cpu_has_mmips) 63 64 return 0; ··· 140 139 #ifdef CONFIG_MIPS_FP_SUPPORT 141 140 case mm_bc2f_op: 142 141 case mm_bc1f_op: { 143 - int bc_false = 0; 144 142 unsigned int fcr31; 145 143 unsigned int bit; 146 144
+24 -29
arch/mips/kernel/cpu-probe.c
··· 1384 1384 break; 1385 1385 } 1386 1386 break; 1387 - case PRID_IMP_R4300: 1388 - c->cputype = CPU_R4300; 1389 - __cpu_name[cpu] = "R4300"; 1390 - set_isa(c, MIPS_CPU_ISA_III); 1391 - c->fpu_msk31 |= FPU_CSR_CONDX; 1392 - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | 1393 - MIPS_CPU_LLSC; 1394 - c->tlbsize = 32; 1395 - break; 1396 1387 case PRID_IMP_R4600: 1397 1388 c->cputype = CPU_R4600; 1398 1389 __cpu_name[cpu] = "R4600"; ··· 1459 1468 MIPS_CPU_LLSC; 1460 1469 c->tlbsize = 48; 1461 1470 break; 1462 - case PRID_IMP_R5432: 1463 - c->cputype = CPU_R5432; 1464 - __cpu_name[cpu] = "R5432"; 1465 - set_isa(c, MIPS_CPU_ISA_IV); 1466 - c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | 1467 - MIPS_CPU_WATCH | MIPS_CPU_LLSC; 1468 - c->tlbsize = 48; 1469 - break; 1470 1471 case PRID_IMP_R5500: 1471 1472 c->cputype = CPU_R5500; 1472 1473 __cpu_name[cpu] = "R5500"; ··· 1490 1507 * 0 => 48 entry JTLB 1491 1508 */ 1492 1509 c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48; 1493 - break; 1494 - case PRID_IMP_R8000: 1495 - c->cputype = CPU_R8000; 1496 - __cpu_name[cpu] = "RM8000"; 1497 - set_isa(c, MIPS_CPU_ISA_IV); 1498 - c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | 1499 - MIPS_CPU_FPU | MIPS_CPU_32FPR | 1500 - MIPS_CPU_LLSC; 1501 - c->tlbsize = 384; /* has weird TLB: 3-way x 128 */ 1502 1510 break; 1503 1511 case PRID_IMP_R10000: 1504 1512 c->cputype = CPU_R10000; ··· 1547 1573 __cpu_name[cpu] = "ICT Loongson-3"; 1548 1574 set_elf_platform(cpu, "loongson3a"); 1549 1575 set_isa(c, MIPS_CPU_ISA_M64R1); 1576 + c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM | 1577 + MIPS_ASE_LOONGSON_EXT); 1550 1578 break; 1551 1579 case PRID_REV_LOONGSON3B_R1: 1552 1580 case PRID_REV_LOONGSON3B_R2: ··· 1556 1580 __cpu_name[cpu] = "ICT Loongson-3"; 1557 1581 set_elf_platform(cpu, "loongson3b"); 1558 1582 set_isa(c, MIPS_CPU_ISA_M64R1); 1583 + c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM | 1584 + MIPS_ASE_LOONGSON_EXT); 1559 1585 break; 1560 1586 } 1561 1587 ··· 1924 1946 decode_configs(c); 1925 1947 c->options |= MIPS_CPU_FTLB | MIPS_CPU_TLBINV | MIPS_CPU_LDPTE; 1926 1948 c->writecombine = _CACHE_UNCACHED_ACCELERATED; 1949 + c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM | 1950 + MIPS_ASE_LOONGSON_EXT | MIPS_ASE_LOONGSON_EXT2); 1927 1951 break; 1928 1952 default: 1929 1953 panic("Unknown Loongson Processor ID!"); ··· 1936 1956 static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu) 1937 1957 { 1938 1958 decode_configs(c); 1939 - /* JZRISC does not implement the CP0 counter. */ 1959 + 1960 + /* 1961 + * XBurst misses a config2 register, so config3 decode was skipped in 1962 + * decode_configs(). 1963 + */ 1964 + decode_config3(c); 1965 + 1966 + /* XBurst does not implement the CP0 counter. */ 1940 1967 c->options &= ~MIPS_CPU_COUNTER; 1941 1968 BUG_ON(!__builtin_constant_p(cpu_has_counter) || cpu_has_counter); 1969 + 1942 1970 switch (c->processor_id & PRID_IMP_MASK) { 1943 - case PRID_IMP_JZRISC: 1944 - c->cputype = CPU_JZRISC; 1971 + case PRID_IMP_XBURST: 1972 + c->cputype = CPU_XBURST; 1945 1973 c->writecombine = _CACHE_UNCACHED_ACCELERATED; 1946 1974 __cpu_name[cpu] = "Ingenic JZRISC"; 1975 + /* 1976 + * The XBurst core by default attempts to avoid branch target 1977 + * buffer lookups by detecting & special casing loops. This 1978 + * feature will cause BogoMIPS and lpj calculate in error. 1979 + * Set cp0 config7 bit 4 to disable this feature. 1980 + */ 1981 + set_c0_config7(MIPS_CONF7_BTB_LOOP_EN); 1947 1982 break; 1948 1983 default: 1949 1984 panic("Unknown Ingenic Processor ID!");
-3
arch/mips/kernel/genex.S
··· 32 32 NESTED(except_vec3_generic, 0, sp) 33 33 .set push 34 34 .set noat 35 - #if R5432_CP0_INTERRUPT_WAR 36 - mfc0 k0, CP0_INDEX 37 - #endif 38 35 mfc0 k1, CP0_CAUSE 39 36 andi k1, k1, 0x7c 40 37 #ifdef CONFIG_64BIT
+1 -2
arch/mips/kernel/idle.c
··· 151 151 cpu_wait = r39xx_wait; 152 152 break; 153 153 case CPU_R4200: 154 - /* case CPU_R4300: */ 155 154 case CPU_R4600: 156 155 case CPU_R4640: 157 156 case CPU_R4650: ··· 172 173 case CPU_CAVIUM_OCTEON_PLUS: 173 174 case CPU_CAVIUM_OCTEON2: 174 175 case CPU_CAVIUM_OCTEON3: 175 - case CPU_JZRISC: 176 + case CPU_XBURST: 176 177 case CPU_LOONGSON1: 177 178 case CPU_XLR: 178 179 case CPU_XLP:
+4
arch/mips/kernel/proc.c
··· 124 124 if (cpu_has_eva) seq_printf(m, "%s", " eva"); 125 125 if (cpu_has_htw) seq_printf(m, "%s", " htw"); 126 126 if (cpu_has_xpa) seq_printf(m, "%s", " xpa"); 127 + if (cpu_has_loongson_mmi) seq_printf(m, "%s", " loongson-mmi"); 128 + if (cpu_has_loongson_cam) seq_printf(m, "%s", " loongson-cam"); 129 + if (cpu_has_loongson_ext) seq_printf(m, "%s", " loongson-ext"); 130 + if (cpu_has_loongson_ext2) seq_printf(m, "%s", " loongson-ext2"); 127 131 seq_printf(m, "\n"); 128 132 129 133 if (cpu_has_mmips) {
+1 -1
arch/mips/kernel/scall32-o32.S
··· 217 217 #define sys_sched_getaffinity mipsmt_sys_sched_getaffinity 218 218 #endif /* CONFIG_MIPS_MT_FPAFF */ 219 219 220 - #define __SYSCALL(nr, entry, nargs) PTR entry 220 + #define __SYSCALL(nr, entry) PTR entry 221 221 .align 2 222 222 .type sys_call_table, @object 223 223 EXPORT(sys_call_table)
+1 -1
arch/mips/kernel/scall64-n32.S
··· 101 101 102 102 END(handle_sysn32) 103 103 104 - #define __SYSCALL(nr, entry, nargs) PTR entry 104 + #define __SYSCALL(nr, entry) PTR entry 105 105 .type sysn32_call_table, @object 106 106 EXPORT(sysn32_call_table) 107 107 #include <asm/syscall_table_64_n32.h>
+1 -1
arch/mips/kernel/scall64-n64.S
··· 109 109 j n64_syscall_exit 110 110 END(handle_sys64) 111 111 112 - #define __SYSCALL(nr, entry, nargs) PTR entry 112 + #define __SYSCALL(nr, entry) PTR entry 113 113 .align 3 114 114 .type sys_call_table, @object 115 115 EXPORT(sys_call_table)
+1 -1
arch/mips/kernel/scall64-o32.S
··· 213 213 jr ra 214 214 END(sys32_syscall) 215 215 216 - #define __SYSCALL(nr, entry, nargs) PTR entry 216 + #define __SYSCALL(nr, entry) PTR entry 217 217 .align 3 218 218 .type sys32_call_table,@object 219 219 EXPORT(sys32_call_table)
+99 -284
arch/mips/kernel/setup.c
··· 63 63 64 64 EXPORT_SYMBOL(mips_machtype); 65 65 66 - struct boot_mem_map boot_mem_map; 67 - 68 66 static char __initdata command_line[COMMAND_LINE_SIZE]; 69 67 char __initdata arcs_cmdline[COMMAND_LINE_SIZE]; 70 68 ··· 74 76 * mips_io_port_base is the begin of the address space to which x86 style 75 77 * I/O ports are mapped. 76 78 */ 77 - const unsigned long mips_io_port_base = -1; 79 + unsigned long mips_io_port_base = -1; 78 80 EXPORT_SYMBOL(mips_io_port_base); 79 81 80 82 static struct resource code_resource = { .name = "Kernel code", }; ··· 90 92 91 93 void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type) 92 94 { 93 - int x = boot_mem_map.nr_map; 94 - int i; 95 + /* 96 + * Note: This function only exists for historical reason, 97 + * new code should use memblock_add or memblock_add_node instead. 98 + */ 95 99 96 100 /* 97 101 * If the region reaches the top of the physical address space, adjust ··· 108 108 return; 109 109 } 110 110 111 - /* 112 - * Try to merge with existing entry, if any. 113 - */ 114 - for (i = 0; i < boot_mem_map.nr_map; i++) { 115 - struct boot_mem_map_entry *entry = boot_mem_map.map + i; 116 - unsigned long top; 111 + memblock_add(start, size); 112 + /* Reserve any memory except the ordinary RAM ranges. */ 113 + switch (type) { 114 + case BOOT_MEM_RAM: 115 + break; 117 116 118 - if (entry->type != type) 119 - continue; 117 + case BOOT_MEM_NOMAP: /* Discard the range from the system. */ 118 + memblock_remove(start, size); 119 + break; 120 120 121 - if (start + size < entry->addr) 122 - continue; /* no overlap */ 123 - 124 - if (entry->addr + entry->size < start) 125 - continue; /* no overlap */ 126 - 127 - top = max(entry->addr + entry->size, start + size); 128 - entry->addr = min(entry->addr, start); 129 - entry->size = top - entry->addr; 130 - 131 - return; 121 + default: /* Reserve the rest of the memory types at boot time */ 122 + memblock_reserve(start, size); 123 + break; 132 124 } 133 - 134 - if (boot_mem_map.nr_map == BOOT_MEM_MAP_MAX) { 135 - pr_err("Ooops! Too many entries in the memory map!\n"); 136 - return; 137 - } 138 - 139 - boot_mem_map.map[x].addr = start; 140 - boot_mem_map.map[x].size = size; 141 - boot_mem_map.map[x].type = type; 142 - boot_mem_map.nr_map++; 143 125 } 144 126 145 127 void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max) ··· 141 159 ((unsigned long long) sz_max) / SZ_1M); 142 160 143 161 add_memory_region(start, size, BOOT_MEM_RAM); 144 - } 145 - 146 - static bool __init __maybe_unused memory_region_available(phys_addr_t start, 147 - phys_addr_t size) 148 - { 149 - int i; 150 - bool in_ram = false, free = true; 151 - 152 - for (i = 0; i < boot_mem_map.nr_map; i++) { 153 - phys_addr_t start_, end_; 154 - 155 - start_ = boot_mem_map.map[i].addr; 156 - end_ = boot_mem_map.map[i].addr + boot_mem_map.map[i].size; 157 - 158 - switch (boot_mem_map.map[i].type) { 159 - case BOOT_MEM_RAM: 160 - if (start >= start_ && start + size <= end_) 161 - in_ram = true; 162 - break; 163 - case BOOT_MEM_RESERVED: 164 - case BOOT_MEM_NOMAP: 165 - if ((start >= start_ && start < end_) || 166 - (start < start_ && start + size >= start_)) 167 - free = false; 168 - break; 169 - default: 170 - continue; 171 - } 172 - } 173 - 174 - return in_ram && free; 175 - } 176 - 177 - static void __init print_memory_map(void) 178 - { 179 - int i; 180 - const int field = 2 * sizeof(unsigned long); 181 - 182 - for (i = 0; i < boot_mem_map.nr_map; i++) { 183 - printk(KERN_INFO " memory: %0*Lx @ %0*Lx ", 184 - field, (unsigned long long) boot_mem_map.map[i].size, 185 - field, (unsigned long long) boot_mem_map.map[i].addr); 186 - 187 - switch (boot_mem_map.map[i].type) { 188 - case BOOT_MEM_RAM: 189 - printk(KERN_CONT "(usable)\n"); 190 - break; 191 - case BOOT_MEM_INIT_RAM: 192 - printk(KERN_CONT "(usable after init)\n"); 193 - break; 194 - case BOOT_MEM_ROM_DATA: 195 - printk(KERN_CONT "(ROM data)\n"); 196 - break; 197 - case BOOT_MEM_RESERVED: 198 - printk(KERN_CONT "(reserved)\n"); 199 - break; 200 - case BOOT_MEM_NOMAP: 201 - printk(KERN_CONT "(nomap)\n"); 202 - break; 203 - default: 204 - printk(KERN_CONT "type %lu\n", boot_mem_map.map[i].type); 205 - break; 206 - } 207 - } 208 162 } 209 163 210 164 /* ··· 294 376 295 377 static void __init bootmem_init(void) 296 378 { 297 - phys_addr_t ramstart = PHYS_ADDR_MAX; 298 - int i; 379 + struct memblock_region *mem; 380 + phys_addr_t ramstart, ramend; 381 + 382 + ramstart = memblock_start_of_DRAM(); 383 + ramend = memblock_end_of_DRAM(); 299 384 300 385 /* 301 386 * Sanity check any INITRD first. We don't take it into account ··· 312 391 memblock_reserve(__pa_symbol(&_text), 313 392 __pa_symbol(&_end) - __pa_symbol(&_text)); 314 393 315 - /* 316 - * max_low_pfn is not a number of pages. The number of pages 317 - * of the system is given by 'max_low_pfn - min_low_pfn'. 318 - */ 319 - min_low_pfn = ~0UL; 320 - max_low_pfn = 0; 321 - 322 - /* Find the highest and lowest page frame numbers we have available. */ 323 - for (i = 0; i < boot_mem_map.nr_map; i++) { 324 - unsigned long start, end; 325 - 326 - if (boot_mem_map.map[i].type != BOOT_MEM_RAM) 327 - continue; 328 - 329 - start = PFN_UP(boot_mem_map.map[i].addr); 330 - end = PFN_DOWN(boot_mem_map.map[i].addr 331 - + boot_mem_map.map[i].size); 332 - 333 - ramstart = min(ramstart, boot_mem_map.map[i].addr); 334 - 335 - #ifndef CONFIG_HIGHMEM 336 - /* 337 - * Skip highmem here so we get an accurate max_low_pfn if low 338 - * memory stops short of high memory. 339 - * If the region overlaps HIGHMEM_START, end is clipped so 340 - * max_pfn excludes the highmem portion. 341 - */ 342 - if (start >= PFN_DOWN(HIGHMEM_START)) 343 - continue; 344 - if (end > PFN_DOWN(HIGHMEM_START)) 345 - end = PFN_DOWN(HIGHMEM_START); 346 - #endif 347 - 348 - if (end > max_low_pfn) 349 - max_low_pfn = end; 350 - if (start < min_low_pfn) 351 - min_low_pfn = start; 352 - } 353 - 354 - if (min_low_pfn >= max_low_pfn) 355 - panic("Incorrect memory mapping !!!"); 394 + /* max_low_pfn is not a number of pages but the end pfn of low mem */ 356 395 357 396 #ifdef CONFIG_MIPS_AUTO_PFN_OFFSET 358 397 ARCH_PFN_OFFSET = PFN_UP(ramstart); ··· 320 439 /* 321 440 * Reserve any memory between the start of RAM and PHYS_OFFSET 322 441 */ 323 - if (ramstart > PHYS_OFFSET) { 324 - add_memory_region(PHYS_OFFSET, ramstart - PHYS_OFFSET, 325 - BOOT_MEM_RESERVED); 326 - memblock_reserve(PHYS_OFFSET, ramstart - PHYS_OFFSET); 327 - } 442 + if (ramstart > PHYS_OFFSET) 443 + memblock_reserve(PHYS_OFFSET, PFN_UP(ramstart) - PHYS_OFFSET); 328 444 329 - if (min_low_pfn > ARCH_PFN_OFFSET) { 445 + if (PFN_UP(ramstart) > ARCH_PFN_OFFSET) { 330 446 pr_info("Wasting %lu bytes for tracking %lu unused pages\n", 331 - (min_low_pfn - ARCH_PFN_OFFSET) * sizeof(struct page), 332 - min_low_pfn - ARCH_PFN_OFFSET); 333 - } else if (ARCH_PFN_OFFSET - min_low_pfn > 0UL) { 334 - pr_info("%lu free pages won't be used\n", 335 - ARCH_PFN_OFFSET - min_low_pfn); 447 + (unsigned long)((PFN_UP(ramstart) - ARCH_PFN_OFFSET) * sizeof(struct page)), 448 + (unsigned long)(PFN_UP(ramstart) - ARCH_PFN_OFFSET)); 336 449 } 450 + #endif 451 + 337 452 min_low_pfn = ARCH_PFN_OFFSET; 338 - #endif 339 - 340 - /* 341 - * Determine low and high memory ranges 342 - */ 343 - max_pfn = max_low_pfn; 344 - if (max_low_pfn > PFN_DOWN(HIGHMEM_START)) { 345 - #ifdef CONFIG_HIGHMEM 346 - highstart_pfn = PFN_DOWN(HIGHMEM_START); 347 - highend_pfn = max_low_pfn; 348 - #endif 349 - max_low_pfn = PFN_DOWN(HIGHMEM_START); 350 - } 351 - 352 - /* Install all valid RAM ranges to the memblock memory region */ 353 - for (i = 0; i < boot_mem_map.nr_map; i++) { 354 - unsigned long start, end; 355 - 356 - start = PFN_UP(boot_mem_map.map[i].addr); 357 - end = PFN_DOWN(boot_mem_map.map[i].addr 358 - + boot_mem_map.map[i].size); 359 - 360 - if (start < min_low_pfn) 361 - start = min_low_pfn; 362 - #ifndef CONFIG_HIGHMEM 363 - /* Ignore highmem regions if highmem is unsupported */ 364 - if (end > max_low_pfn) 365 - end = max_low_pfn; 366 - #endif 367 - if (end <= start) 368 - continue; 369 - 370 - memblock_add_node(PFN_PHYS(start), PFN_PHYS(end - start), 0); 371 - 372 - /* Reserve any memory except the ordinary RAM ranges. */ 373 - switch (boot_mem_map.map[i].type) { 374 - case BOOT_MEM_RAM: 375 - break; 376 - case BOOT_MEM_NOMAP: /* Discard the range from the system. */ 377 - memblock_remove(PFN_PHYS(start), PFN_PHYS(end - start)); 378 - continue; 379 - default: /* Reserve the rest of the memory types at boot time */ 380 - memblock_reserve(PFN_PHYS(start), PFN_PHYS(end - start)); 381 - break; 382 - } 453 + max_pfn = PFN_DOWN(ramend); 454 + for_each_memblock(memory, mem) { 455 + unsigned long start = memblock_region_memory_base_pfn(mem); 456 + unsigned long end = memblock_region_memory_end_pfn(mem); 383 457 384 458 /* 385 - * In any case the added to the memblock memory regions 386 - * (highmem/lowmem, available/reserved, etc) are considered 387 - * as present, so inform sparsemem about them. 459 + * Skip highmem here so we get an accurate max_low_pfn if low 460 + * memory stops short of high memory. 461 + * If the region overlaps HIGHMEM_START, end is clipped so 462 + * max_pfn excludes the highmem portion. 388 463 */ 389 - memory_present(0, start, end); 464 + if (memblock_is_nomap(mem)) 465 + continue; 466 + if (start >= PFN_DOWN(HIGHMEM_START)) 467 + continue; 468 + if (end > PFN_DOWN(HIGHMEM_START)) 469 + end = PFN_DOWN(HIGHMEM_START); 470 + if (end > max_low_pfn) 471 + max_low_pfn = end; 390 472 } 473 + 474 + if (min_low_pfn >= max_low_pfn) 475 + panic("Incorrect memory mapping !!!"); 476 + 477 + if (max_pfn > PFN_DOWN(HIGHMEM_START)) { 478 + #ifdef CONFIG_HIGHMEM 479 + highstart_pfn = PFN_DOWN(HIGHMEM_START); 480 + highend_pfn = max_pfn; 481 + #else 482 + max_low_pfn = PFN_DOWN(HIGHMEM_START); 483 + max_pfn = max_low_pfn; 484 + #endif 485 + } 486 + 487 + 488 + /* 489 + * In any case the added to the memblock memory regions 490 + * (highmem/lowmem, available/reserved, etc) are considered 491 + * as present, so inform sparsemem about them. 492 + */ 493 + memblocks_present(); 391 494 392 495 /* 393 496 * Reserve initrd memory if needed. ··· 393 528 * size. 394 529 */ 395 530 if (usermem == 0) { 396 - boot_mem_map.nr_map = 0; 397 531 usermem = 1; 532 + memblock_remove(memblock_start_of_DRAM(), 533 + memblock_end_of_DRAM() - memblock_start_of_DRAM()); 398 534 } 399 535 start = 0; 400 536 size = memparse(p, &p); ··· 452 586 unsigned long setup_elfcorehdr, setup_elfcorehdr_size; 453 587 static int __init early_parse_elfcorehdr(char *p) 454 588 { 455 - int i; 589 + struct memblock_region *mem; 456 590 457 591 setup_elfcorehdr = memparse(p, &p); 458 592 459 - for (i = 0; i < boot_mem_map.nr_map; i++) { 460 - unsigned long start = boot_mem_map.map[i].addr; 461 - unsigned long end = (boot_mem_map.map[i].addr + 462 - boot_mem_map.map[i].size); 593 + for_each_memblock(memory, mem) { 594 + unsigned long start = mem->base; 595 + unsigned long end = start + mem->size; 463 596 if (setup_elfcorehdr >= start && setup_elfcorehdr < end) { 464 597 /* 465 598 * Reserve from the elf core header to the end of ··· 478 613 early_param("elfcorehdr", early_parse_elfcorehdr); 479 614 #endif 480 615 481 - static void __init arch_mem_addpart(phys_addr_t mem, phys_addr_t end, int type) 482 - { 483 - phys_addr_t size; 484 - int i; 485 - 486 - size = end - mem; 487 - if (!size) 488 - return; 489 - 490 - /* Make sure it is in the boot_mem_map */ 491 - for (i = 0; i < boot_mem_map.nr_map; i++) { 492 - if (mem >= boot_mem_map.map[i].addr && 493 - mem < (boot_mem_map.map[i].addr + 494 - boot_mem_map.map[i].size)) 495 - return; 496 - } 497 - add_memory_region(mem, size, type); 498 - } 499 - 500 616 #ifdef CONFIG_KEXEC 501 - static inline unsigned long long get_total_mem(void) 502 - { 503 - unsigned long long total; 504 - 505 - total = max_pfn - min_low_pfn; 506 - return total << PAGE_SHIFT; 507 - } 508 - 509 617 static void __init mips_parse_crashkernel(void) 510 618 { 511 619 unsigned long long total_mem; 512 620 unsigned long long crash_size, crash_base; 513 621 int ret; 514 622 515 - total_mem = get_total_mem(); 623 + total_mem = memblock_phys_mem_size(); 516 624 ret = parse_crashkernel(boot_command_line, total_mem, 517 625 &crash_size, &crash_base); 518 626 if (ret != 0 || crash_size <= 0) 519 627 return; 520 628 521 - if (!memory_region_available(crash_base, crash_size)) { 629 + if (!memblock_find_in_range(crash_base, crash_base + crash_size, crash_size, 0)) { 522 630 pr_warn("Invalid memory region reserved for crash kernel\n"); 523 631 return; 524 632 } ··· 523 685 { 524 686 } 525 687 #endif /* !defined(CONFIG_KEXEC) */ 688 + 689 + static void __init check_kernel_sections_mem(void) 690 + { 691 + phys_addr_t start = PFN_PHYS(PFN_DOWN(__pa_symbol(&_text))); 692 + phys_addr_t size = PFN_PHYS(PFN_UP(__pa_symbol(&_end))) - start; 693 + 694 + if (!memblock_is_region_memory(start, size)) { 695 + pr_info("Kernel sections are not in the memory maps\n"); 696 + memblock_add(start, size); 697 + } 698 + } 526 699 527 700 #define USE_PROM_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER) 528 701 #define USE_DTB_CMDLINE IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB) ··· 580 731 plat_mem_setup(); 581 732 memblock_set_bottom_up(true); 582 733 583 - /* 584 - * Make sure all kernel memory is in the maps. The "UP" and 585 - * "DOWN" are opposite for initdata since if it crosses over 586 - * into another memory section you don't want that to be 587 - * freed when the initdata is freed. 588 - */ 589 - arch_mem_addpart(PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT, 590 - PFN_UP(__pa_symbol(&_edata)) << PAGE_SHIFT, 591 - BOOT_MEM_RAM); 592 - arch_mem_addpart(PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT, 593 - PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT, 594 - BOOT_MEM_INIT_RAM); 595 - arch_mem_addpart(PFN_DOWN(__pa_symbol(&__bss_start)) << PAGE_SHIFT, 596 - PFN_UP(__pa_symbol(&__bss_stop)) << PAGE_SHIFT, 597 - BOOT_MEM_RAM); 598 - 599 - pr_info("Determined physical RAM map:\n"); 600 - print_memory_map(); 601 - 602 734 #if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE) 603 735 strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE); 604 736 #else ··· 613 783 614 784 parse_early_param(); 615 785 616 - if (usermem) { 617 - pr_info("User-defined physical RAM map:\n"); 618 - print_memory_map(); 619 - } 786 + if (usermem) 787 + pr_info("User-defined physical RAM map overwrite\n"); 788 + 789 + check_kernel_sections_mem(); 620 790 621 791 early_init_fdt_reserve_self(); 622 792 early_init_fdt_scan_reserved_mem(); 623 793 794 + #ifndef CONFIG_NUMA 795 + memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0); 796 + #endif 624 797 bootmem_init(); 625 798 626 799 /* ··· 663 830 664 831 memblock_dump_all(); 665 832 666 - early_memtest(PFN_PHYS(min_low_pfn), PFN_PHYS(max_low_pfn)); 833 + early_memtest(PFN_PHYS(ARCH_PFN_OFFSET), PFN_PHYS(max_low_pfn)); 667 834 } 668 835 669 836 static void __init resource_init(void) 670 837 { 671 - int i; 838 + struct memblock_region *region; 672 839 673 840 if (UNCAC_BASE != IO_BASE) 674 841 return; ··· 680 847 bss_resource.start = __pa_symbol(&__bss_start); 681 848 bss_resource.end = __pa_symbol(&__bss_stop) - 1; 682 849 683 - for (i = 0; i < boot_mem_map.nr_map; i++) { 850 + for_each_memblock(memory, region) { 851 + phys_addr_t start = PFN_PHYS(memblock_region_memory_base_pfn(region)); 852 + phys_addr_t end = PFN_PHYS(memblock_region_memory_end_pfn(region)) - 1; 684 853 struct resource *res; 685 - unsigned long start, end; 686 - 687 - start = boot_mem_map.map[i].addr; 688 - end = boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1; 689 - if (start >= HIGHMEM_START) 690 - continue; 691 - if (end >= HIGHMEM_START) 692 - end = HIGHMEM_START - 1; 693 854 694 855 res = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES); 695 856 if (!res) ··· 692 865 693 866 res->start = start; 694 867 res->end = end; 695 - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; 696 - 697 - switch (boot_mem_map.map[i].type) { 698 - case BOOT_MEM_RAM: 699 - case BOOT_MEM_INIT_RAM: 700 - case BOOT_MEM_ROM_DATA: 701 - res->name = "System RAM"; 702 - res->flags |= IORESOURCE_SYSRAM; 703 - break; 704 - case BOOT_MEM_RESERVED: 705 - case BOOT_MEM_NOMAP: 706 - default: 707 - res->name = "reserved"; 708 - } 868 + res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY; 869 + res->name = "System RAM"; 709 870 710 871 request_resource(&iomem_resource, res); 711 872
+1
arch/mips/kernel/syscall.c
··· 132 132 [efault] "i" (-EFAULT) 133 133 : "memory"); 134 134 } else if (cpu_has_llsc) { 135 + loongson_llsc_mb(); 135 136 __asm__ __volatile__ ( 136 137 " .set push \n" 137 138 " .set "MIPS_ISA_ARCH_LEVEL" \n"
+2 -2
arch/mips/kernel/syscalls/syscalltbl.sh
··· 13 13 t_entry="$3" 14 14 15 15 while [ $t_nxt -lt $t_nr ]; do 16 - printf "__SYSCALL(%s, sys_ni_syscall, )\n" "${t_nxt}" 16 + printf "__SYSCALL(%s,sys_ni_syscall)\n" "${t_nxt}" 17 17 t_nxt=$((t_nxt+1)) 18 18 done 19 - printf "__SYSCALL(%s, %s, )\n" "${t_nxt}" "${t_entry}" 19 + printf "__SYSCALL(%s,%s)\n" "${t_nxt}" "${t_entry}" 20 20 } 21 21 22 22 grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
+6 -31
arch/mips/kernel/vdso.c
··· 20 20 #include <asm/mips-cps.h> 21 21 #include <asm/page.h> 22 22 #include <asm/vdso.h> 23 + #include <vdso/helpers.h> 24 + #include <vdso/vsyscall.h> 23 25 24 26 /* Kernel-provided data used by the VDSO. */ 25 - static union mips_vdso_data vdso_data __page_aligned_data; 27 + static union mips_vdso_data mips_vdso_data __page_aligned_data; 28 + struct vdso_data *vdso_data = mips_vdso_data.data; 26 29 27 30 /* 28 31 * Mapping for the VDSO data/GIC pages. The real pages are mapped manually, as ··· 68 65 return 0; 69 66 } 70 67 subsys_initcall(init_vdso); 71 - 72 - void update_vsyscall(struct timekeeper *tk) 73 - { 74 - vdso_data_write_begin(&vdso_data); 75 - 76 - vdso_data.xtime_sec = tk->xtime_sec; 77 - vdso_data.xtime_nsec = tk->tkr_mono.xtime_nsec; 78 - vdso_data.wall_to_mono_sec = tk->wall_to_monotonic.tv_sec; 79 - vdso_data.wall_to_mono_nsec = tk->wall_to_monotonic.tv_nsec; 80 - vdso_data.cs_shift = tk->tkr_mono.shift; 81 - 82 - vdso_data.clock_mode = tk->tkr_mono.clock->archdata.vdso_clock_mode; 83 - if (vdso_data.clock_mode != VDSO_CLOCK_NONE) { 84 - vdso_data.cs_mult = tk->tkr_mono.mult; 85 - vdso_data.cs_cycle_last = tk->tkr_mono.cycle_last; 86 - vdso_data.cs_mask = tk->tkr_mono.mask; 87 - } 88 - 89 - vdso_data_write_end(&vdso_data); 90 - } 91 - 92 - void update_vsyscall_tz(void) 93 - { 94 - if (vdso_data.clock_mode != VDSO_CLOCK_NONE) { 95 - vdso_data.tz_minuteswest = sys_tz.tz_minuteswest; 96 - vdso_data.tz_dsttime = sys_tz.tz_dsttime; 97 - } 98 - } 99 68 100 69 static unsigned long vdso_base(void) 101 70 { ··· 138 163 */ 139 164 if (cpu_has_dc_aliases) { 140 165 base = __ALIGN_MASK(base, shm_align_mask); 141 - base += ((unsigned long)&vdso_data - gic_size) & shm_align_mask; 166 + base += ((unsigned long)vdso_data - gic_size) & shm_align_mask; 142 167 } 143 168 144 169 data_addr = base + gic_size; ··· 164 189 165 190 /* Map data page. */ 166 191 ret = remap_pfn_range(vma, data_addr, 167 - virt_to_phys(&vdso_data) >> PAGE_SHIFT, 192 + virt_to_phys(vdso_data) >> PAGE_SHIFT, 168 193 PAGE_SIZE, PAGE_READONLY); 169 194 if (ret) 170 195 goto out;
+8 -8
arch/mips/lantiq/xway/sysctrl.c
··· 468 468 clkdev_add_pmu("1f203018.usb2-phy", "phy", 1, 2, PMU_ANALOG_USB0_P); 469 469 clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 2, PMU_ANALOG_USB1_P); 470 470 /* rc 0 */ 471 - clkdev_add_pmu("1d900000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE0_P); 471 + clkdev_add_pmu("1f106800.phy", "phy", 1, 2, PMU_ANALOG_PCIE0_P); 472 472 clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI); 473 - clkdev_add_pmu("1d900000.pcie", "pdi", 1, 1, PMU1_PCIE_PDI); 473 + clkdev_add_pmu("1f106800.phy", "pdi", 1, 1, PMU1_PCIE_PDI); 474 474 clkdev_add_pmu("1d900000.pcie", "ctl", 1, 1, PMU1_PCIE_CTL); 475 475 /* rc 1 */ 476 - clkdev_add_pmu("19000000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE1_P); 476 + clkdev_add_pmu("1f700400.phy", "phy", 1, 2, PMU_ANALOG_PCIE1_P); 477 477 clkdev_add_pmu("19000000.pcie", "msi", 1, 1, PMU1_PCIE1_MSI); 478 - clkdev_add_pmu("19000000.pcie", "pdi", 1, 1, PMU1_PCIE1_PDI); 478 + clkdev_add_pmu("1f700400.phy", "pdi", 1, 1, PMU1_PCIE1_PDI); 479 479 clkdev_add_pmu("19000000.pcie", "ctl", 1, 1, PMU1_PCIE1_CTL); 480 480 } 481 481 ··· 499 499 clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0); 500 500 clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1); 501 501 /* rc 2 */ 502 - clkdev_add_pmu("1a800000.pcie", "phy", 1, 2, PMU_ANALOG_PCIE2_P); 502 + clkdev_add_pmu("1f106a00.pcie", "phy", 1, 2, PMU_ANALOG_PCIE2_P); 503 503 clkdev_add_pmu("1a800000.pcie", "msi", 1, 1, PMU1_PCIE2_MSI); 504 - clkdev_add_pmu("1a800000.pcie", "pdi", 1, 1, PMU1_PCIE2_PDI); 504 + clkdev_add_pmu("1f106a00.pcie", "pdi", 1, 1, PMU1_PCIE2_PDI); 505 505 clkdev_add_pmu("1a800000.pcie", "ctl", 1, 1, PMU1_PCIE2_CTL); 506 506 clkdev_add_pmu("1e10b308.eth", NULL, 0, 0, PMU_SWITCH | PMU_PPE_DP); 507 507 clkdev_add_pmu("1da00000.usif", "NULL", 1, 0, PMU_USIF); ··· 526 526 clkdev_add_pmu("1e101000.usb", "otg", 1, 0, PMU_USB0 | PMU_AHBM); 527 527 clkdev_add_pmu("1f203034.usb2-phy", "phy", 1, 0, PMU_USB1_P); 528 528 clkdev_add_pmu("1e106000.usb", "otg", 1, 0, PMU_USB1 | PMU_AHBM); 529 - clkdev_add_pmu("1d900000.pcie", "phy", 1, 1, PMU1_PCIE_PHY); 529 + clkdev_add_pmu("1f106800.phy", "phy", 1, 1, PMU1_PCIE_PHY); 530 530 clkdev_add_pmu("1d900000.pcie", "bus", 1, 0, PMU_PCIE_CLK); 531 531 clkdev_add_pmu("1d900000.pcie", "msi", 1, 1, PMU1_PCIE_MSI); 532 - clkdev_add_pmu("1d900000.pcie", "pdi", 1, 1, PMU1_PCIE_PDI); 532 + clkdev_add_pmu("1f106800.phy", "pdi", 1, 1, PMU1_PCIE_PDI); 533 533 clkdev_add_pmu("1d900000.pcie", "ctl", 1, 1, PMU1_PCIE_CTL); 534 534 clkdev_add_pmu(NULL, "ahb", 1, 0, PMU_AHBM | PMU_AHBS); 535 535
+3 -3
arch/mips/mm/Makefile
··· 28 28 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 29 29 obj-$(CONFIG_DMA_NONCOHERENT) += dma-noncoherent.o 30 30 31 + obj-$(CONFIG_CPU_R3K_TLB) += tlb-r3k.o 31 32 obj-$(CONFIG_CPU_R4K_CACHE_TLB) += c-r4k.o cex-gen.o tlb-r4k.o 32 - obj-$(CONFIG_CPU_R3000) += c-r3k.o tlb-r3k.o 33 - obj-$(CONFIG_CPU_R8000) += c-r4k.o cex-gen.o tlb-r8k.o 33 + obj-$(CONFIG_CPU_R3000) += c-r3k.o 34 34 obj-$(CONFIG_CPU_SB1) += c-r4k.o cerr-sb1.o cex-sb1.o tlb-r4k.o 35 - obj-$(CONFIG_CPU_TX39XX) += c-tx39.o tlb-r3k.o 35 + obj-$(CONFIG_CPU_TX39XX) += c-tx39.o 36 36 obj-$(CONFIG_CPU_CAVIUM_OCTEON) += c-octeon.o cex-oct.o tlb-r4k.o 37 37 38 38 obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o
-2
arch/mips/mm/c-r4k.c
··· 1098 1098 c->options |= MIPS_CPU_CACHE_CDEX_P; 1099 1099 break; 1100 1100 1101 - case CPU_R5432: 1102 1101 case CPU_R5500: 1103 1102 icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); 1104 1103 c->icache.linesz = 16 << ((config & CONF_IB) >> 5); ··· 1133 1134 case CPU_R4400PC: 1134 1135 case CPU_R4400SC: 1135 1136 case CPU_R4400MC: 1136 - case CPU_R4300: 1137 1137 icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); 1138 1138 c->icache.linesz = 16 << ((config & CONF_IB) >> 5); 1139 1139 c->icache.ways = 1;
+44 -56
arch/mips/mm/init.c
··· 269 269 #endif 270 270 } 271 271 272 + struct maar_walk_info { 273 + struct maar_config cfg[16]; 274 + unsigned int num_cfg; 275 + }; 276 + 277 + static int maar_res_walk(unsigned long start_pfn, unsigned long nr_pages, 278 + void *data) 279 + { 280 + struct maar_walk_info *wi = data; 281 + struct maar_config *cfg = &wi->cfg[wi->num_cfg]; 282 + unsigned int maar_align; 283 + 284 + /* MAAR registers hold physical addresses right shifted by 4 bits */ 285 + maar_align = BIT(MIPS_MAAR_ADDR_SHIFT + 4); 286 + 287 + /* Fill in the MAAR config entry */ 288 + cfg->lower = ALIGN(PFN_PHYS(start_pfn), maar_align); 289 + cfg->upper = ALIGN_DOWN(PFN_PHYS(start_pfn + nr_pages), maar_align) - 1; 290 + cfg->attrs = MIPS_MAAR_S; 291 + 292 + /* Ensure we don't overflow the cfg array */ 293 + if (!WARN_ON(wi->num_cfg >= ARRAY_SIZE(wi->cfg))) 294 + wi->num_cfg++; 295 + 296 + return 0; 297 + } 298 + 299 + 272 300 unsigned __weak platform_maar_init(unsigned num_pairs) 273 301 { 274 - struct maar_config cfg[BOOT_MEM_MAP_MAX]; 275 - unsigned i, num_configured, num_cfg = 0; 302 + unsigned int num_configured; 303 + struct maar_walk_info wi; 276 304 277 - for (i = 0; i < boot_mem_map.nr_map; i++) { 278 - switch (boot_mem_map.map[i].type) { 279 - case BOOT_MEM_RAM: 280 - case BOOT_MEM_INIT_RAM: 281 - break; 282 - default: 283 - continue; 284 - } 305 + wi.num_cfg = 0; 306 + walk_system_ram_range(0, max_pfn, &wi, maar_res_walk); 285 307 286 - /* Round lower up */ 287 - cfg[num_cfg].lower = boot_mem_map.map[i].addr; 288 - cfg[num_cfg].lower = (cfg[num_cfg].lower + 0xffff) & ~0xffff; 289 - 290 - /* Round upper down */ 291 - cfg[num_cfg].upper = boot_mem_map.map[i].addr + 292 - boot_mem_map.map[i].size; 293 - cfg[num_cfg].upper = (cfg[num_cfg].upper & ~0xffff) - 1; 294 - 295 - cfg[num_cfg].attrs = MIPS_MAAR_S; 296 - num_cfg++; 297 - } 298 - 299 - num_configured = maar_config(cfg, num_cfg, num_pairs); 300 - if (num_configured < num_cfg) 301 - pr_warn("Not enough MAAR pairs (%u) for all bootmem regions (%u)\n", 302 - num_pairs, num_cfg); 308 + num_configured = maar_config(wi.cfg, wi.num_cfg, num_pairs); 309 + if (num_configured < wi.num_cfg) 310 + pr_warn("Not enough MAAR pairs (%u) for all memory regions (%u)\n", 311 + num_pairs, wi.num_cfg); 303 312 304 313 return num_configured; 305 314 } ··· 391 382 } 392 383 393 384 #ifndef CONFIG_NEED_MULTIPLE_NODES 394 - int page_is_ram(unsigned long pagenr) 395 - { 396 - int i; 397 - 398 - for (i = 0; i < boot_mem_map.nr_map; i++) { 399 - unsigned long addr, end; 400 - 401 - switch (boot_mem_map.map[i].type) { 402 - case BOOT_MEM_RAM: 403 - case BOOT_MEM_INIT_RAM: 404 - break; 405 - default: 406 - /* not usable memory */ 407 - continue; 408 - } 409 - 410 - addr = PFN_UP(boot_mem_map.map[i].addr); 411 - end = PFN_DOWN(boot_mem_map.map[i].addr + 412 - boot_mem_map.map[i].size); 413 - 414 - if (pagenr >= addr && pagenr < end) 415 - return 1; 416 - } 417 - 418 - return 0; 419 - } 420 - 421 385 void __init paging_init(void) 422 386 { 423 387 unsigned long max_zone_pfns[MAX_NR_ZONES]; ··· 425 443 static struct kcore_list kcore_kseg0; 426 444 #endif 427 445 428 - static inline void mem_init_free_highmem(void) 446 + static inline void __init mem_init_free_highmem(void) 429 447 { 430 448 #ifdef CONFIG_HIGHMEM 431 449 unsigned long tmp; ··· 436 454 for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) { 437 455 struct page *page = pfn_to_page(tmp); 438 456 439 - if (!page_is_ram(tmp)) 457 + if (!memblock_is_memory(PFN_PHYS(tmp))) 440 458 SetPageReserved(page); 441 459 else 442 460 free_highmem_page(page); ··· 446 464 447 465 void __init mem_init(void) 448 466 { 467 + /* 468 + * When _PFN_SHIFT is greater than PAGE_SHIFT we won't have enough PTE 469 + * bits to hold a full 32b physical address on MIPS32 systems. 470 + */ 471 + BUILD_BUG_ON(IS_ENABLED(CONFIG_32BIT) && (_PFN_SHIFT > PAGE_SHIFT)); 472 + 449 473 #ifdef CONFIG_HIGHMEM 450 474 #ifdef CONFIG_DISCONTIGMEM 451 475 #error "CONFIG_HIGHMEM and CONFIG_DISCONTIGMEM dont work together yet"
+20
arch/mips/mm/pgtable-32.c
··· 12 12 #include <asm/fixmap.h> 13 13 #include <asm/pgtable.h> 14 14 #include <asm/pgalloc.h> 15 + #include <asm/tlbflush.h> 15 16 16 17 void pgd_init(unsigned long page) 17 18 { ··· 30 29 p[i + 7] = (unsigned long) invalid_pte_table; 31 30 } 32 31 } 32 + 33 + #if defined(CONFIG_TRANSPARENT_HUGEPAGE) 34 + pmd_t mk_pmd(struct page *page, pgprot_t prot) 35 + { 36 + pmd_t pmd; 37 + 38 + pmd_val(pmd) = (page_to_pfn(page) << _PFN_SHIFT) | pgprot_val(prot); 39 + 40 + return pmd; 41 + } 42 + 43 + 44 + void set_pmd_at(struct mm_struct *mm, unsigned long addr, 45 + pmd_t *pmdp, pmd_t pmd) 46 + { 47 + *pmdp = pmd; 48 + flush_tlb_all(); 49 + } 50 + #endif /* defined(CONFIG_TRANSPARENT_HUGEPAGE) */ 33 51 34 52 void __init pagetable_init(void) 35 53 {
+20 -7
arch/mips/mm/sc-mips.c
··· 221 221 else 222 222 return 0; 223 223 224 - /* 225 - * According to config2 it would be 5-ways, but that is contradicted 226 - * by all documentation. 227 - */ 228 - if (current_cpu_type() == CPU_JZRISC && 229 - mips_machtype == MACH_INGENIC_JZ4770) 230 - c->scache.ways = 4; 224 + if (current_cpu_type() == CPU_XBURST) { 225 + switch (mips_machtype) { 226 + /* 227 + * According to config2 it would be 5-ways, but that is 228 + * contradicted by all documentation. 229 + */ 230 + case MACH_INGENIC_JZ4770: 231 + c->scache.ways = 4; 232 + break; 233 + 234 + /* 235 + * According to config2 it would be 5-ways and 512-sets, 236 + * but that is contradicted by all documentation. 237 + */ 238 + case MACH_INGENIC_X1000: 239 + c->scache.sets = 256; 240 + c->scache.ways = 4; 241 + break; 242 + } 243 + } 231 244 232 245 c->scache.waysize = c->scache.sets * c->scache.linesz; 233 246 c->scache.waybit = __ffs(c->scache.waysize);
-239
arch/mips/mm/tlb-r8k.c
··· 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 - * Copyright (C) 1996 David S. Miller (davem@davemloft.net) 7 - * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org 8 - * Carsten Langgaard, carstenl@mips.com 9 - * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. 10 - */ 11 - #include <linux/sched.h> 12 - #include <linux/smp.h> 13 - #include <linux/mm.h> 14 - 15 - #include <asm/cpu.h> 16 - #include <asm/bootinfo.h> 17 - #include <asm/mmu_context.h> 18 - #include <asm/pgtable.h> 19 - 20 - extern void build_tlb_refill_handler(void); 21 - 22 - #define TFP_TLB_SIZE 384 23 - #define TFP_TLB_SET_SHIFT 7 24 - 25 - /* CP0 hazard avoidance. */ 26 - #define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ 27 - "nop; nop; nop; nop; nop; nop;\n\t" \ 28 - ".set reorder\n\t") 29 - 30 - void local_flush_tlb_all(void) 31 - { 32 - unsigned long flags; 33 - unsigned long old_ctx; 34 - int entry; 35 - 36 - local_irq_save(flags); 37 - /* Save old context and create impossible VPN2 value */ 38 - old_ctx = read_c0_entryhi(); 39 - write_c0_entrylo(0); 40 - 41 - for (entry = 0; entry < TFP_TLB_SIZE; entry++) { 42 - write_c0_tlbset(entry >> TFP_TLB_SET_SHIFT); 43 - write_c0_vaddr(entry << PAGE_SHIFT); 44 - write_c0_entryhi(CKSEG0 + (entry << (PAGE_SHIFT + 1))); 45 - mtc0_tlbw_hazard(); 46 - tlb_write(); 47 - } 48 - tlbw_use_hazard(); 49 - write_c0_entryhi(old_ctx); 50 - local_irq_restore(flags); 51 - } 52 - 53 - void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, 54 - unsigned long end) 55 - { 56 - struct mm_struct *mm = vma->vm_mm; 57 - int cpu = smp_processor_id(); 58 - unsigned long flags; 59 - int oldpid, newpid, size; 60 - 61 - if (!cpu_context(cpu, mm)) 62 - return; 63 - 64 - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; 65 - size = (size + 1) >> 1; 66 - 67 - local_irq_save(flags); 68 - 69 - if (size > TFP_TLB_SIZE / 2) { 70 - drop_mmu_context(mm); 71 - goto out_restore; 72 - } 73 - 74 - oldpid = read_c0_entryhi(); 75 - newpid = cpu_asid(cpu, mm); 76 - 77 - write_c0_entrylo(0); 78 - 79 - start &= PAGE_MASK; 80 - end += (PAGE_SIZE - 1); 81 - end &= PAGE_MASK; 82 - while (start < end) { 83 - signed long idx; 84 - 85 - write_c0_vaddr(start); 86 - write_c0_entryhi(start); 87 - start += PAGE_SIZE; 88 - tlb_probe(); 89 - idx = read_c0_tlbset(); 90 - if (idx < 0) 91 - continue; 92 - 93 - write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1))); 94 - tlb_write(); 95 - } 96 - write_c0_entryhi(oldpid); 97 - 98 - out_restore: 99 - local_irq_restore(flags); 100 - } 101 - 102 - /* Usable for KV1 addresses only! */ 103 - void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) 104 - { 105 - unsigned long size, flags; 106 - 107 - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; 108 - size = (size + 1) >> 1; 109 - 110 - if (size > TFP_TLB_SIZE / 2) { 111 - local_flush_tlb_all(); 112 - return; 113 - } 114 - 115 - local_irq_save(flags); 116 - 117 - write_c0_entrylo(0); 118 - 119 - start &= PAGE_MASK; 120 - end += (PAGE_SIZE - 1); 121 - end &= PAGE_MASK; 122 - while (start < end) { 123 - signed long idx; 124 - 125 - write_c0_vaddr(start); 126 - write_c0_entryhi(start); 127 - start += PAGE_SIZE; 128 - tlb_probe(); 129 - idx = read_c0_tlbset(); 130 - if (idx < 0) 131 - continue; 132 - 133 - write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1))); 134 - tlb_write(); 135 - } 136 - 137 - local_irq_restore(flags); 138 - } 139 - 140 - void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) 141 - { 142 - int cpu = smp_processor_id(); 143 - unsigned long flags; 144 - int oldpid, newpid; 145 - signed long idx; 146 - 147 - if (!cpu_context(cpu, vma->vm_mm)) 148 - return; 149 - 150 - newpid = cpu_asid(cpu, vma->vm_mm); 151 - page &= PAGE_MASK; 152 - local_irq_save(flags); 153 - oldpid = read_c0_entryhi(); 154 - write_c0_vaddr(page); 155 - write_c0_entryhi(newpid); 156 - tlb_probe(); 157 - idx = read_c0_tlbset(); 158 - if (idx < 0) 159 - goto finish; 160 - 161 - write_c0_entrylo(0); 162 - write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1))); 163 - tlb_write(); 164 - 165 - finish: 166 - write_c0_entryhi(oldpid); 167 - local_irq_restore(flags); 168 - } 169 - 170 - /* 171 - * We will need multiple versions of update_mmu_cache(), one that just 172 - * updates the TLB with the new pte(s), and another which also checks 173 - * for the R4k "end of page" hardware bug and does the needy. 174 - */ 175 - void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) 176 - { 177 - unsigned long flags; 178 - pgd_t *pgdp; 179 - pmd_t *pmdp; 180 - pte_t *ptep; 181 - int pid; 182 - 183 - /* 184 - * Handle debugger faulting in for debugee. 185 - */ 186 - if (current->active_mm != vma->vm_mm) 187 - return; 188 - 189 - pid = read_c0_entryhi() & cpu_asid_mask(&current_cpu_data); 190 - 191 - local_irq_save(flags); 192 - address &= PAGE_MASK; 193 - write_c0_vaddr(address); 194 - write_c0_entryhi(pid); 195 - pgdp = pgd_offset(vma->vm_mm, address); 196 - pmdp = pmd_offset(pgdp, address); 197 - ptep = pte_offset_map(pmdp, address); 198 - tlb_probe(); 199 - 200 - write_c0_entrylo(pte_val(*ptep++) >> 6); 201 - tlb_write(); 202 - 203 - write_c0_entryhi(pid); 204 - local_irq_restore(flags); 205 - } 206 - 207 - static void probe_tlb(unsigned long config) 208 - { 209 - struct cpuinfo_mips *c = &current_cpu_data; 210 - 211 - c->tlbsize = 3 * 128; /* 3 sets each 128 entries */ 212 - } 213 - 214 - void tlb_init(void) 215 - { 216 - unsigned int config = read_c0_config(); 217 - unsigned long status; 218 - 219 - probe_tlb(config); 220 - 221 - status = read_c0_status(); 222 - status &= ~(ST0_UPS | ST0_KPS); 223 - #ifdef CONFIG_PAGE_SIZE_4KB 224 - status |= (TFP_PAGESIZE_4K << 32) | (TFP_PAGESIZE_4K << 36); 225 - #elif defined(CONFIG_PAGE_SIZE_8KB) 226 - status |= (TFP_PAGESIZE_8K << 32) | (TFP_PAGESIZE_8K << 36); 227 - #elif defined(CONFIG_PAGE_SIZE_16KB) 228 - status |= (TFP_PAGESIZE_16K << 32) | (TFP_PAGESIZE_16K << 36); 229 - #elif defined(CONFIG_PAGE_SIZE_64KB) 230 - status |= (TFP_PAGESIZE_64K << 32) | (TFP_PAGESIZE_64K << 36); 231 - #endif 232 - write_c0_status(status); 233 - 234 - write_c0_wired(0); 235 - 236 - local_flush_tlb_all(); 237 - 238 - build_tlb_refill_handler(); 239 - }
+26 -45
arch/mips/mm/tlbex.c
··· 545 545 tlbw(p); 546 546 break; 547 547 548 - case CPU_R4300: 549 548 case CPU_5KC: 550 549 case CPU_TX49XX: 551 550 case CPU_PR4450: ··· 603 604 604 605 case CPU_VR4131: 605 606 case CPU_VR4133: 606 - case CPU_R5432: 607 607 uasm_i_nop(p); 608 608 uasm_i_nop(p); 609 609 tlbw(p); 610 610 break; 611 611 612 - case CPU_JZRISC: 612 + case CPU_XBURST: 613 613 tlbw(p); 614 614 uasm_i_nop(p); 615 615 break; ··· 629 631 return; 630 632 } 631 633 632 - if (cpu_has_rixi && _PAGE_NO_EXEC) { 634 + if (cpu_has_rixi && !!_PAGE_NO_EXEC) { 633 635 if (fill_includes_sw_bits) { 634 636 UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL)); 635 637 } else { ··· 2607 2609 check_for_high_segbits = current_cpu_data.vmbits > (PGDIR_SHIFT + PGD_ORDER + PAGE_SHIFT - 3); 2608 2610 #endif 2609 2611 2610 - switch (current_cpu_type()) { 2611 - case CPU_R2000: 2612 - case CPU_R3000: 2613 - case CPU_R3000A: 2614 - case CPU_R3081E: 2615 - case CPU_TX3912: 2616 - case CPU_TX3922: 2617 - case CPU_TX3927: 2612 + if (cpu_has_3kex) { 2618 2613 #ifndef CONFIG_MIPS_PGD_C0_CONTEXT 2619 - if (cpu_has_local_ebase) 2620 - build_r3000_tlb_refill_handler(); 2621 2614 if (!run_once) { 2622 - if (!cpu_has_local_ebase) 2623 - build_r3000_tlb_refill_handler(); 2624 2615 build_setup_pgd(); 2616 + build_r3000_tlb_refill_handler(); 2625 2617 build_r3000_tlb_load_handler(); 2626 2618 build_r3000_tlb_store_handler(); 2627 2619 build_r3000_tlb_modify_handler(); ··· 2621 2633 #else 2622 2634 panic("No R3000 TLB refill handler"); 2623 2635 #endif 2624 - break; 2625 - 2626 - case CPU_R8000: 2627 - panic("No R8000 TLB refill handler yet"); 2628 - break; 2629 - 2630 - default: 2631 - if (cpu_has_ldpte) 2632 - setup_pw(); 2633 - 2634 - if (!run_once) { 2635 - scratch_reg = allocate_kscratch(); 2636 - build_setup_pgd(); 2637 - build_r4000_tlb_load_handler(); 2638 - build_r4000_tlb_store_handler(); 2639 - build_r4000_tlb_modify_handler(); 2640 - if (cpu_has_ldpte) 2641 - build_loongson3_tlb_refill_handler(); 2642 - else if (!cpu_has_local_ebase) 2643 - build_r4000_tlb_refill_handler(); 2644 - flush_tlb_handlers(); 2645 - run_once++; 2646 - } 2647 - if (cpu_has_local_ebase) 2648 - build_r4000_tlb_refill_handler(); 2649 - if (cpu_has_xpa) 2650 - config_xpa_params(); 2651 - if (cpu_has_htw) 2652 - config_htw_params(); 2636 + return; 2653 2637 } 2638 + 2639 + if (cpu_has_ldpte) 2640 + setup_pw(); 2641 + 2642 + if (!run_once) { 2643 + scratch_reg = allocate_kscratch(); 2644 + build_setup_pgd(); 2645 + build_r4000_tlb_load_handler(); 2646 + build_r4000_tlb_store_handler(); 2647 + build_r4000_tlb_modify_handler(); 2648 + if (cpu_has_ldpte) 2649 + build_loongson3_tlb_refill_handler(); 2650 + else 2651 + build_r4000_tlb_refill_handler(); 2652 + flush_tlb_handlers(); 2653 + run_once++; 2654 + } 2655 + if (cpu_has_xpa) 2656 + config_xpa_params(); 2657 + if (cpu_has_htw) 2658 + config_htw_params(); 2654 2659 }
-11
arch/mips/mti-malta/malta-memory.c
··· 39 39 40 40 void __init prom_free_prom_memory(void) 41 41 { 42 - unsigned long addr; 43 - int i; 44 - 45 - for (i = 0; i < boot_mem_map.nr_map; i++) { 46 - if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) 47 - continue; 48 - 49 - addr = boot_mem_map.map[i].addr; 50 - free_init_pages("YAMON memory", 51 - addr, addr + boot_mem_map.map[i].size); 52 - } 53 42 } 54 43 55 44 phys_addr_t mips_cdmm_phys_base(void)
+6 -6
arch/mips/netlogic/xlp/setup.c
··· 34 34 35 35 #include <linux/kernel.h> 36 36 #include <linux/of_fdt.h> 37 + #include <linux/memblock.h> 37 38 38 39 #include <asm/idle.h> 39 40 #include <asm/reboot.h> ··· 68 67 static void nlm_fixup_mem(void) 69 68 { 70 69 const int pref_backup = 512; 71 - int i; 70 + struct memblock_region *mem; 72 71 73 - for (i = 0; i < boot_mem_map.nr_map; i++) { 74 - if (boot_mem_map.map[i].type != BOOT_MEM_RAM) 75 - continue; 76 - boot_mem_map.map[i].size -= pref_backup; 72 + for_each_memblock(memory, mem) { 73 + memblock_remove(mem->base + mem->size - pref_backup, 74 + pref_backup); 77 75 } 78 76 } 79 77 ··· 110 110 /* memory and bootargs from DT */ 111 111 xlp_early_init_devtree(); 112 112 113 - if (boot_mem_map.nr_map == 0) { 113 + if (memblock_end_of_DRAM() == 0) { 114 114 pr_info("Using DRAM BARs for memory map.\n"); 115 115 xlp_init_mem_from_bars(); 116 116 }
+62 -105
arch/mips/pci/pci-xtalk-bridge.c
··· 20 20 * Most of the IOC3 PCI config register aren't present 21 21 * we emulate what is needed for a normal PCI enumeration 22 22 */ 23 - static u32 emulate_ioc3_cfg(int where, int size) 23 + static int ioc3_cfg_rd(void *addr, int where, int size, u32 *value) 24 24 { 25 - if (size == 1 && where == 0x3d) 26 - return 0x01; 27 - else if (size == 2 && where == 0x3c) 28 - return 0x0100; 29 - else if (size == 4 && where == 0x3c) 30 - return 0x00000100; 25 + u32 cf, shift, mask; 31 26 32 - return 0; 27 + switch (where & ~3) { 28 + case 0x00 ... 0x10: 29 + case 0x40 ... 0x44: 30 + if (get_dbe(cf, (u32 *)addr)) 31 + return PCIBIOS_DEVICE_NOT_FOUND; 32 + break; 33 + case 0x3c: 34 + /* emulate sane interrupt pin value */ 35 + cf = 0x00000100; 36 + break; 37 + default: 38 + cf = 0; 39 + break; 40 + } 41 + shift = (where & 3) << 3; 42 + mask = 0xffffffffU >> ((4 - size) << 3); 43 + *value = (cf >> shift) & mask; 44 + 45 + return PCIBIOS_SUCCESSFUL; 46 + } 47 + 48 + static int ioc3_cfg_wr(void *addr, int where, int size, u32 value) 49 + { 50 + u32 cf, shift, mask, smask; 51 + 52 + if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) 53 + return PCIBIOS_SUCCESSFUL; 54 + 55 + if (get_dbe(cf, (u32 *)addr)) 56 + return PCIBIOS_DEVICE_NOT_FOUND; 57 + 58 + shift = ((where & 3) << 3); 59 + mask = (0xffffffffU >> ((4 - size) << 3)); 60 + smask = mask << shift; 61 + 62 + cf = (cf & ~smask) | ((value & mask) << shift); 63 + if (put_dbe(cf, (u32 *)addr)) 64 + return PCIBIOS_DEVICE_NOT_FOUND; 65 + 66 + return PCIBIOS_SUCCESSFUL; 33 67 } 34 68 35 69 static void bridge_disable_swapping(struct pci_dev *dev) ··· 98 64 int slot = PCI_SLOT(devfn); 99 65 int fn = PCI_FUNC(devfn); 100 66 void *addr; 101 - u32 cf, shift, mask; 67 + u32 cf; 102 68 int res; 103 69 104 70 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID]; ··· 109 75 * IOC3 is broken beyond belief ... Don't even give the 110 76 * generic PCI code a chance to look at it for real ... 111 77 */ 112 - if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) 113 - goto is_ioc3; 78 + if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) { 79 + addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; 80 + return ioc3_cfg_rd(addr, where, size, value); 81 + } 114 82 115 83 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)]; 116 84 ··· 124 88 res = get_dbe(*value, (u32 *)addr); 125 89 126 90 return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; 127 - 128 - is_ioc3: 129 - 130 - /* 131 - * IOC3 special handling 132 - */ 133 - if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { 134 - *value = emulate_ioc3_cfg(where, size); 135 - return PCIBIOS_SUCCESSFUL; 136 - } 137 - 138 - addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; 139 - if (get_dbe(cf, (u32 *)addr)) 140 - return PCIBIOS_DEVICE_NOT_FOUND; 141 - 142 - shift = ((where & 3) << 3); 143 - mask = (0xffffffffU >> ((4 - size) << 3)); 144 - *value = (cf >> shift) & mask; 145 - 146 - return PCIBIOS_SUCCESSFUL; 147 91 } 148 92 149 93 static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn, ··· 135 119 int slot = PCI_SLOT(devfn); 136 120 int fn = PCI_FUNC(devfn); 137 121 void *addr; 138 - u32 cf, shift, mask; 122 + u32 cf; 139 123 int res; 140 124 141 125 bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11)); ··· 147 131 * IOC3 is broken beyond belief ... Don't even give the 148 132 * generic PCI code a chance to look at it for real ... 149 133 */ 150 - if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) 151 - goto is_ioc3; 134 + if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) { 135 + addr = &bridge->b_type1_cfg.c[(fn << 8) | (where & ~3)]; 136 + return ioc3_cfg_rd(addr, where, size, value); 137 + } 152 138 153 139 addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))]; 154 140 ··· 162 144 res = get_dbe(*value, (u32 *)addr); 163 145 164 146 return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; 165 - 166 - is_ioc3: 167 - 168 - /* 169 - * IOC3 special handling 170 - */ 171 - if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { 172 - *value = emulate_ioc3_cfg(where, size); 173 - return PCIBIOS_SUCCESSFUL; 174 - } 175 - 176 - addr = &bridge->b_type1_cfg.c[(fn << 8) | where]; 177 - if (get_dbe(cf, (u32 *)addr)) 178 - return PCIBIOS_DEVICE_NOT_FOUND; 179 - 180 - shift = ((where & 3) << 3); 181 - mask = (0xffffffffU >> ((4 - size) << 3)); 182 - *value = (cf >> shift) & mask; 183 - 184 - return PCIBIOS_SUCCESSFUL; 185 147 } 186 148 187 149 static int pci_read_config(struct pci_bus *bus, unsigned int devfn, ··· 181 183 int slot = PCI_SLOT(devfn); 182 184 int fn = PCI_FUNC(devfn); 183 185 void *addr; 184 - u32 cf, shift, mask, smask; 186 + u32 cf; 185 187 int res; 186 188 187 189 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID]; ··· 192 194 * IOC3 is broken beyond belief ... Don't even give the 193 195 * generic PCI code a chance to look at it for real ... 194 196 */ 195 - if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) 196 - goto is_ioc3; 197 + if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) { 198 + addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; 199 + return ioc3_cfg_wr(addr, where, size, value); 200 + } 197 201 198 202 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)]; 199 203 ··· 210 210 return PCIBIOS_DEVICE_NOT_FOUND; 211 211 212 212 return PCIBIOS_SUCCESSFUL; 213 - 214 - is_ioc3: 215 - 216 - /* 217 - * IOC3 special handling 218 - */ 219 - if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) 220 - return PCIBIOS_SUCCESSFUL; 221 - 222 - addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; 223 - 224 - if (get_dbe(cf, (u32 *)addr)) 225 - return PCIBIOS_DEVICE_NOT_FOUND; 226 - 227 - shift = ((where & 3) << 3); 228 - mask = (0xffffffffU >> ((4 - size) << 3)); 229 - smask = mask << shift; 230 - 231 - cf = (cf & ~smask) | ((value & mask) << shift); 232 - if (put_dbe(cf, (u32 *)addr)) 233 - return PCIBIOS_DEVICE_NOT_FOUND; 234 - 235 - return PCIBIOS_SUCCESSFUL; 236 213 } 237 214 238 215 static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn, ··· 221 244 int fn = PCI_FUNC(devfn); 222 245 int busno = bus->number; 223 246 void *addr; 224 - u32 cf, shift, mask, smask; 247 + u32 cf; 225 248 int res; 226 249 227 250 bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11)); ··· 233 256 * IOC3 is broken beyond belief ... Don't even give the 234 257 * generic PCI code a chance to look at it for real ... 235 258 */ 236 - if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) 237 - goto is_ioc3; 259 + if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) { 260 + addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; 261 + return ioc3_cfg_wr(addr, where, size, value); 262 + } 238 263 239 264 addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))]; 240 265 ··· 248 269 res = put_dbe(value, (u32 *)addr); 249 270 250 271 if (res) 251 - return PCIBIOS_DEVICE_NOT_FOUND; 252 - 253 - return PCIBIOS_SUCCESSFUL; 254 - 255 - is_ioc3: 256 - 257 - /* 258 - * IOC3 special handling 259 - */ 260 - if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) 261 - return PCIBIOS_SUCCESSFUL; 262 - 263 - addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; 264 - if (get_dbe(cf, (u32 *)addr)) 265 - return PCIBIOS_DEVICE_NOT_FOUND; 266 - 267 - shift = ((where & 3) << 3); 268 - mask = (0xffffffffU >> ((4 - size) << 3)); 269 - smask = mask << shift; 270 - 271 - cf = (cf & ~smask) | ((value & mask) << shift); 272 - if (put_dbe(cf, (u32 *)addr)) 273 272 return PCIBIOS_DEVICE_NOT_FOUND; 274 273 275 274 return PCIBIOS_SUCCESSFUL;
+16 -6
arch/mips/pmcs-msp71xx/msp_prom.c
··· 61 61 /* memory blocks */ 62 62 struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS]; 63 63 64 + static phys_addr_t prom_mem_base[MAX_PROM_MEM] __initdata; 65 + static phys_addr_t prom_mem_size[MAX_PROM_MEM] __initdata; 66 + static unsigned int nr_prom_mem __initdata; 67 + 64 68 /* default feature sets */ 65 69 static char msp_default_features[] = 66 70 #if defined(CONFIG_PMC_MSP4200_EVAL) \ ··· 356 352 357 353 add_memory_region(base, size, type); 358 354 p++; 355 + 356 + if (type == BOOT_MEM_ROM_DATA) { 357 + if (nr_prom_mem >= 5) { 358 + pr_err("Too many ROM DATA regions"); 359 + continue; 360 + } 361 + prom_mem_base[nr_prom_mem] = base; 362 + prom_mem_size[nr_prom_mem] = size; 363 + nr_prom_mem++; 364 + } 359 365 } 360 366 } 361 367 ··· 421 407 envp[i] = NULL; /* end array with null pointer */ 422 408 prom_envp = envp; 423 409 424 - for (i = 0; i < boot_mem_map.nr_map; i++) { 425 - if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) 426 - continue; 427 - 428 - addr = boot_mem_map.map[i].addr; 410 + for (i = 0; i < nr_prom_mem; i++) { 429 411 free_init_pages("prom memory", 430 - addr, addr + boot_mem_map.map[i].size); 412 + prom_mem_base[i], prom_mem_base[i] + prom_mem_size[i]); 431 413 } 432 414 } 433 415
-1
arch/mips/ralink/Kconfig
··· 51 51 select MIPS_GIC 52 52 select COMMON_CLK 53 53 select CLKSRC_MIPS_GIC 54 - select HAVE_PCI 55 54 endchoice 56 55 57 56 choice
+1 -3
arch/mips/ralink/timer.c
··· 106 106 } 107 107 108 108 rt->irq = platform_get_irq(pdev, 0); 109 - if (rt->irq < 0) { 110 - dev_err(&pdev->dev, "failed to load irq\n"); 109 + if (rt->irq < 0) 111 110 return rt->irq; 112 - } 113 111 114 112 rt->membase = devm_ioremap_resource(&pdev->dev, res); 115 113 if (IS_ERR(rt->membase))
+2 -18
arch/mips/sgi-ip22/ip28-berr.c
··· 8 8 9 9 #include <linux/init.h> 10 10 #include <linux/kernel.h> 11 + #include <linux/mm.h> 11 12 #include <linux/sched.h> 12 13 #include <linux/sched/debug.h> 13 14 #include <linux/sched/signal.h> ··· 301 300 field, regs->cp0_epc, field, regs->regs[31]); 302 301 } 303 302 304 - /* 305 - * Check, whether MC's (virtual) DMA address caused the bus error. 306 - * See "Virtual DMA Specification", Draft 1.5, Feb 13 1992, SGI 307 - */ 308 - 309 - static int addr_is_ram(unsigned long addr, unsigned sz) 310 - { 311 - int i; 312 - 313 - for (i = 0; i < boot_mem_map.nr_map; i++) { 314 - unsigned long a = boot_mem_map.map[i].addr; 315 - if (a <= addr && addr+sz <= a+boot_mem_map.map[i].size) 316 - return 1; 317 - } 318 - return 0; 319 - } 320 - 321 303 static int check_microtlb(u32 hi, u32 lo, unsigned long vaddr) 322 304 { 323 305 /* This is likely rather similar to correct code ;-) */ ··· 315 331 /* PTEIndex is VPN-low (bits [22:14]/[20:12] ?) */ 316 332 unsigned long pte = (lo >> 6) << 12; /* PTEBase */ 317 333 pte += 8*((vaddr >> pgsz) & 0x1ff); 318 - if (addr_is_ram(pte, 8)) { 334 + if (page_is_ram(PFN_DOWN(pte))) { 319 335 /* 320 336 * Note: Since DMA hardware does look up 321 337 * translation on its own, this PTE *must*
+34 -7
arch/mips/vdso/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 # Objects to go into the VDSO. 3 - obj-vdso-y := elf.o gettimeofday.o sigreturn.o 3 + 4 + # Absolute relocation type $(ARCH_REL_TYPE_ABS) needs to be defined before 5 + # the inclusion of generic Makefile. 6 + ARCH_REL_TYPE_ABS := R_MIPS_JUMP_SLOT|R_MIPS_GLOB_DAT 7 + include $(srctree)/lib/vdso/Makefile 8 + 9 + obj-vdso-y := elf.o vgettimeofday.o sigreturn.o 4 10 5 11 # Common compiler flags between ABIs. 6 12 ccflags-vdso := \ ··· 21 15 ccflags-vdso += $(filter --target=%,$(KBUILD_CFLAGS)) 22 16 endif 23 17 18 + # 19 + # The -fno-jump-tables flag only prevents the compiler from generating 20 + # jump tables but does not prevent the compiler from emitting absolute 21 + # offsets. 24 22 cflags-vdso := $(ccflags-vdso) \ 25 23 $(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \ 26 - -O2 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \ 27 - -DDISABLE_BRANCH_PROFILING \ 24 + -O3 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \ 25 + -fno-stack-protector -fno-jump-tables -DDISABLE_BRANCH_PROFILING \ 28 26 $(call cc-option, -fno-asynchronous-unwind-tables) \ 29 27 $(call cc-option, -fno-stack-protector) 30 28 aflags-vdso := $(ccflags-vdso) \ 31 29 -D__ASSEMBLY__ -Wa,-gdwarf-2 30 + 31 + ifneq ($(c-gettimeofday-y),) 32 + CFLAGS_vgettimeofday.o = -include $(c-gettimeofday-y) 33 + 34 + # config-n32-o32-env.c prepares the environment to build a 32bit vDSO 35 + # library on a 64bit kernel. 36 + # Note: Needs to be included before than the generic library. 37 + CFLAGS_vgettimeofday-o32.o = -include $(srctree)/$(src)/config-n32-o32-env.c -include $(c-gettimeofday-y) 38 + CFLAGS_vgettimeofday-n32.o = -include $(srctree)/$(src)/config-n32-o32-env.c -include $(c-gettimeofday-y) 39 + endif 40 + 41 + CFLAGS_REMOVE_vgettimeofday.o = -pg 32 42 33 43 # 34 44 # For the pre-R6 code in arch/mips/vdso/vdso.h for locating ··· 70 48 $(addprefix -Wl$(comma),$(filter -E%,$(KBUILD_CFLAGS))) \ 71 49 -nostdlib -shared -Wl,--hash-style=sysv -Wl,--build-id 72 50 51 + CFLAGS_REMOVE_vdso.o = -pg 52 + 73 53 GCOV_PROFILE := n 74 54 UBSAN_SANITIZE := n 75 55 ··· 79 55 # Shared build commands. 80 56 # 81 57 58 + quiet_cmd_vdsold_and_vdso_check = LD $@ 59 + cmd_vdsold_and_vdso_check = $(cmd_vdsold); $(cmd_vdso_check) 60 + 82 61 quiet_cmd_vdsold = VDSO $@ 83 62 cmd_vdsold = $(CC) $(c_flags) $(VDSO_LDFLAGS) \ 84 63 -Wl,-T $(filter %.lds,$^) $(filter %.o,$^) -o $@ 85 64 86 - quiet_cmd_vdsoas_o_S = AS $@ 65 + quiet_cmd_vdsoas_o_S = AS $@ 87 66 cmd_vdsoas_o_S = $(CC) $(a_flags) -c -o $@ $< 88 67 89 68 # Strip rule for the raw .so files ··· 122 95 $(obj)/vdso.lds: KBUILD_CPPFLAGS := $(ccflags-vdso) $(native-abi) 123 96 124 97 $(obj)/vdso.so.dbg.raw: $(obj)/vdso.lds $(obj-vdso) FORCE 125 - $(call if_changed,vdsold) 98 + $(call if_changed,vdsold_and_vdso_check) 126 99 127 100 $(obj)/vdso-image.c: $(obj)/vdso.so.dbg.raw $(obj)/vdso.so.raw \ 128 101 $(obj)/genvdso FORCE ··· 160 133 $(call if_changed_dep,cpp_lds_S) 161 134 162 135 $(obj)/vdso-o32.so.dbg.raw: $(obj)/vdso-o32.lds $(obj-vdso-o32) FORCE 163 - $(call if_changed,vdsold) 136 + $(call if_changed,vdsold_and_vdso_check) 164 137 165 138 $(obj)/vdso-o32-image.c: VDSO_NAME := o32 166 139 $(obj)/vdso-o32-image.c: $(obj)/vdso-o32.so.dbg.raw $(obj)/vdso-o32.so.raw \ ··· 200 173 $(call if_changed_dep,cpp_lds_S) 201 174 202 175 $(obj)/vdso-n32.so.dbg.raw: $(obj)/vdso-n32.lds $(obj-vdso-n32) FORCE 203 - $(call if_changed,vdsold) 176 + $(call if_changed,vdsold_and_vdso_check) 204 177 205 178 $(obj)/vdso-n32-image.c: VDSO_NAME := n32 206 179 $(obj)/vdso-n32-image.c: $(obj)/vdso-n32.so.dbg.raw $(obj)/vdso-n32.so.raw \
+19
arch/mips/vdso/config-n32-o32-env.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Configuration file for O32 and N32 binaries. 4 + * Note: To be included before lib/vdso/gettimeofday.c 5 + */ 6 + #if defined(CONFIG_MIPS32_O32) || defined(CONFIG_MIPS32_N32) 7 + /* 8 + * In case of a 32 bit VDSO for a 64 bit kernel fake a 32 bit kernel 9 + * configuration. 10 + */ 11 + #undef CONFIG_64BIT 12 + 13 + #define BUILD_VDSO32 14 + #define CONFIG_32BIT 1 15 + #define CONFIG_GENERIC_ATOMIC64 1 16 + #define BUILD_VDSO32_64 17 + 18 + #endif 19 +
+1 -1
arch/mips/vdso/elf.S
··· 4 4 * Author: Alex Smith <alex.smith@imgtec.com> 5 5 */ 6 6 7 - #include "vdso.h" 7 + #include <asm/vdso/vdso.h> 8 8 9 9 #include <asm/isa-rev.h> 10 10
+1 -1
arch/mips/vdso/sigreturn.S
··· 4 4 * Author: Alex Smith <alex.smith@imgtec.com> 5 5 */ 6 6 7 - #include "vdso.h" 7 + #include <asm/vdso/vdso.h> 8 8 9 9 #include <uapi/asm/unistd.h> 10 10
+3 -14
arch/mips/vdso/vdso.h arch/mips/include/asm/vdso/vdso.h
··· 6 6 7 7 #include <asm/sgidefs.h> 8 8 9 - #if _MIPS_SIM != _MIPS_SIM_ABI64 && defined(CONFIG_64BIT) 10 - 11 - /* Building 32-bit VDSO for the 64-bit kernel. Fake a 32-bit Kconfig. */ 12 - #define BUILD_VDSO32_64 13 - #undef CONFIG_64BIT 14 - #define CONFIG_32BIT 1 15 - #ifndef __ASSEMBLY__ 16 - #include <asm-generic/atomic64.h> 17 - #endif 18 - #endif 19 - 20 9 #ifndef __ASSEMBLY__ 21 10 22 11 #include <asm/asm.h> ··· 58 69 return addr; 59 70 } 60 71 61 - static inline const union mips_vdso_data *get_vdso_data(void) 72 + static inline const struct vdso_data *get_vdso_data(void) 62 73 { 63 - return (const union mips_vdso_data *)(get_vdso_base() - PAGE_SIZE); 74 + return (const struct vdso_data *)(get_vdso_base() - PAGE_SIZE); 64 75 } 65 76 66 77 #ifdef CONFIG_CLKSRC_MIPS_GIC 67 78 68 - static inline void __iomem *get_gic(const union mips_vdso_data *data) 79 + static inline void __iomem *get_gic(const struct vdso_data *data) 69 80 { 70 81 return (void __iomem *)data - PAGE_SIZE; 71 82 }
+4
arch/mips/vdso/vdso.lds.S
··· 95 95 global: 96 96 __vdso_clock_gettime; 97 97 __vdso_gettimeofday; 98 + __vdso_clock_getres; 99 + #if _MIPS_SIM != _MIPS_SIM_ABI64 100 + __vdso_clock_gettime64; 101 + #endif 98 102 #endif 99 103 local: *; 100 104 };
+58
arch/mips/vdso/vgettimeofday.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * MIPS64 and compat userspace implementations of gettimeofday() 4 + * and similar. 5 + * 6 + * Copyright (C) 2015 Imagination Technologies 7 + * Copyright (C) 2018 ARM Limited 8 + * 9 + */ 10 + #include <linux/time.h> 11 + #include <linux/types.h> 12 + 13 + #if _MIPS_SIM != _MIPS_SIM_ABI64 14 + int __vdso_clock_gettime(clockid_t clock, 15 + struct old_timespec32 *ts) 16 + { 17 + return __cvdso_clock_gettime32(clock, ts); 18 + } 19 + 20 + int __vdso_gettimeofday(struct __kernel_old_timeval *tv, 21 + struct timezone *tz) 22 + { 23 + return __cvdso_gettimeofday(tv, tz); 24 + } 25 + 26 + int __vdso_clock_getres(clockid_t clock_id, 27 + struct old_timespec32 *res) 28 + { 29 + return __cvdso_clock_getres_time32(clock_id, res); 30 + } 31 + 32 + int __vdso_clock_gettime64(clockid_t clock, 33 + struct __kernel_timespec *ts) 34 + { 35 + return __cvdso_clock_gettime(clock, ts); 36 + } 37 + 38 + #else 39 + 40 + int __vdso_clock_gettime(clockid_t clock, 41 + struct __kernel_timespec *ts) 42 + { 43 + return __cvdso_clock_gettime(clock, ts); 44 + } 45 + 46 + int __vdso_gettimeofday(struct __kernel_old_timeval *tv, 47 + struct timezone *tz) 48 + { 49 + return __cvdso_gettimeofday(tv, tz); 50 + } 51 + 52 + int __vdso_clock_getres(clockid_t clock_id, 53 + struct __kernel_timespec *res) 54 + { 55 + return __cvdso_clock_getres(clock_id, res); 56 + } 57 + 58 + #endif
+9 -1
drivers/clk/ingenic/Kconfig
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 - menu "Ingenic JZ47xx CGU drivers" 2 + menu "Ingenic SoCs drivers" 3 3 depends on MIPS 4 4 5 5 config INGENIC_CGU_COMMON ··· 44 44 and compatible SoCs. 45 45 46 46 If building for a JZ4780 SoC, you want to say Y here. 47 + 48 + config INGENIC_TCU_CLK 49 + bool "Ingenic JZ47xx TCU clocks driver" 50 + default MACH_INGENIC 51 + select MFD_SYSCON 52 + help 53 + Support the clocks of the Timer/Counter Unit (TCU) of the Ingenic 54 + JZ47xx SoCs. 47 55 48 56 endmenu
+1
drivers/clk/ingenic/Makefile
··· 4 4 obj-$(CONFIG_INGENIC_CGU_JZ4725B) += jz4725b-cgu.o 5 5 obj-$(CONFIG_INGENIC_CGU_JZ4770) += jz4770-cgu.o 6 6 obj-$(CONFIG_INGENIC_CGU_JZ4780) += jz4780-cgu.o 7 + obj-$(CONFIG_INGENIC_TCU_CLK) += tcu.o
+6
drivers/clk/ingenic/jz4740-cgu.c
··· 229 229 .parents = { JZ4740_CLK_EXT, -1, -1, -1 }, 230 230 .gate = { CGU_REG_CLKGR, 5 }, 231 231 }, 232 + 233 + [JZ4740_CLK_TCU] = { 234 + "tcu", CGU_CLK_GATE, 235 + .parents = { JZ4740_CLK_EXT, -1, -1, -1 }, 236 + .gate = { CGU_REG_CLKGR, 1 }, 237 + }, 232 238 }; 233 239 234 240 static void __init jz4740_cgu_init(struct device_node *np)
+474
drivers/clk/ingenic/tcu.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * JZ47xx SoCs TCU clocks driver 4 + * Copyright (C) 2019 Paul Cercueil <paul@crapouillou.net> 5 + */ 6 + 7 + #include <linux/clk.h> 8 + #include <linux/clk-provider.h> 9 + #include <linux/clockchips.h> 10 + #include <linux/mfd/ingenic-tcu.h> 11 + #include <linux/mfd/syscon.h> 12 + #include <linux/regmap.h> 13 + #include <linux/slab.h> 14 + #include <linux/syscore_ops.h> 15 + 16 + #include <dt-bindings/clock/ingenic,tcu.h> 17 + 18 + /* 8 channels max + watchdog + OST */ 19 + #define TCU_CLK_COUNT 10 20 + 21 + #undef pr_fmt 22 + #define pr_fmt(fmt) "ingenic-tcu-clk: " fmt 23 + 24 + enum tcu_clk_parent { 25 + TCU_PARENT_PCLK, 26 + TCU_PARENT_RTC, 27 + TCU_PARENT_EXT, 28 + }; 29 + 30 + struct ingenic_soc_info { 31 + unsigned int num_channels; 32 + bool has_ost; 33 + bool has_tcu_clk; 34 + }; 35 + 36 + struct ingenic_tcu_clk_info { 37 + struct clk_init_data init_data; 38 + u8 gate_bit; 39 + u8 tcsr_reg; 40 + }; 41 + 42 + struct ingenic_tcu_clk { 43 + struct clk_hw hw; 44 + unsigned int idx; 45 + struct ingenic_tcu *tcu; 46 + const struct ingenic_tcu_clk_info *info; 47 + }; 48 + 49 + struct ingenic_tcu { 50 + const struct ingenic_soc_info *soc_info; 51 + struct regmap *map; 52 + struct clk *clk; 53 + 54 + struct clk_hw_onecell_data *clocks; 55 + }; 56 + 57 + static struct ingenic_tcu *ingenic_tcu; 58 + 59 + static inline struct ingenic_tcu_clk *to_tcu_clk(struct clk_hw *hw) 60 + { 61 + return container_of(hw, struct ingenic_tcu_clk, hw); 62 + } 63 + 64 + static int ingenic_tcu_enable(struct clk_hw *hw) 65 + { 66 + struct ingenic_tcu_clk *tcu_clk = to_tcu_clk(hw); 67 + const struct ingenic_tcu_clk_info *info = tcu_clk->info; 68 + struct ingenic_tcu *tcu = tcu_clk->tcu; 69 + 70 + regmap_write(tcu->map, TCU_REG_TSCR, BIT(info->gate_bit)); 71 + 72 + return 0; 73 + } 74 + 75 + static void ingenic_tcu_disable(struct clk_hw *hw) 76 + { 77 + struct ingenic_tcu_clk *tcu_clk = to_tcu_clk(hw); 78 + const struct ingenic_tcu_clk_info *info = tcu_clk->info; 79 + struct ingenic_tcu *tcu = tcu_clk->tcu; 80 + 81 + regmap_write(tcu->map, TCU_REG_TSSR, BIT(info->gate_bit)); 82 + } 83 + 84 + static int ingenic_tcu_is_enabled(struct clk_hw *hw) 85 + { 86 + struct ingenic_tcu_clk *tcu_clk = to_tcu_clk(hw); 87 + const struct ingenic_tcu_clk_info *info = tcu_clk->info; 88 + unsigned int value; 89 + 90 + regmap_read(tcu_clk->tcu->map, TCU_REG_TSR, &value); 91 + 92 + return !(value & BIT(info->gate_bit)); 93 + } 94 + 95 + static bool ingenic_tcu_enable_regs(struct clk_hw *hw) 96 + { 97 + struct ingenic_tcu_clk *tcu_clk = to_tcu_clk(hw); 98 + const struct ingenic_tcu_clk_info *info = tcu_clk->info; 99 + struct ingenic_tcu *tcu = tcu_clk->tcu; 100 + bool enabled = false; 101 + 102 + /* 103 + * If the SoC has no global TCU clock, we must ungate the channel's 104 + * clock to be able to access its registers. 105 + * If we have a TCU clock, it will be enabled automatically as it has 106 + * been attached to the regmap. 107 + */ 108 + if (!tcu->clk) { 109 + enabled = !!ingenic_tcu_is_enabled(hw); 110 + regmap_write(tcu->map, TCU_REG_TSCR, BIT(info->gate_bit)); 111 + } 112 + 113 + return enabled; 114 + } 115 + 116 + static void ingenic_tcu_disable_regs(struct clk_hw *hw) 117 + { 118 + struct ingenic_tcu_clk *tcu_clk = to_tcu_clk(hw); 119 + const struct ingenic_tcu_clk_info *info = tcu_clk->info; 120 + struct ingenic_tcu *tcu = tcu_clk->tcu; 121 + 122 + if (!tcu->clk) 123 + regmap_write(tcu->map, TCU_REG_TSSR, BIT(info->gate_bit)); 124 + } 125 + 126 + static u8 ingenic_tcu_get_parent(struct clk_hw *hw) 127 + { 128 + struct ingenic_tcu_clk *tcu_clk = to_tcu_clk(hw); 129 + const struct ingenic_tcu_clk_info *info = tcu_clk->info; 130 + unsigned int val = 0; 131 + int ret; 132 + 133 + ret = regmap_read(tcu_clk->tcu->map, info->tcsr_reg, &val); 134 + WARN_ONCE(ret < 0, "Unable to read TCSR %d", tcu_clk->idx); 135 + 136 + return ffs(val & TCU_TCSR_PARENT_CLOCK_MASK) - 1; 137 + } 138 + 139 + static int ingenic_tcu_set_parent(struct clk_hw *hw, u8 idx) 140 + { 141 + struct ingenic_tcu_clk *tcu_clk = to_tcu_clk(hw); 142 + const struct ingenic_tcu_clk_info *info = tcu_clk->info; 143 + bool was_enabled; 144 + int ret; 145 + 146 + was_enabled = ingenic_tcu_enable_regs(hw); 147 + 148 + ret = regmap_update_bits(tcu_clk->tcu->map, info->tcsr_reg, 149 + TCU_TCSR_PARENT_CLOCK_MASK, BIT(idx)); 150 + WARN_ONCE(ret < 0, "Unable to update TCSR %d", tcu_clk->idx); 151 + 152 + if (!was_enabled) 153 + ingenic_tcu_disable_regs(hw); 154 + 155 + return 0; 156 + } 157 + 158 + static unsigned long ingenic_tcu_recalc_rate(struct clk_hw *hw, 159 + unsigned long parent_rate) 160 + { 161 + struct ingenic_tcu_clk *tcu_clk = to_tcu_clk(hw); 162 + const struct ingenic_tcu_clk_info *info = tcu_clk->info; 163 + unsigned int prescale; 164 + int ret; 165 + 166 + ret = regmap_read(tcu_clk->tcu->map, info->tcsr_reg, &prescale); 167 + WARN_ONCE(ret < 0, "Unable to read TCSR %d", tcu_clk->idx); 168 + 169 + prescale = (prescale & TCU_TCSR_PRESCALE_MASK) >> TCU_TCSR_PRESCALE_LSB; 170 + 171 + return parent_rate >> (prescale * 2); 172 + } 173 + 174 + static u8 ingenic_tcu_get_prescale(unsigned long rate, unsigned long req_rate) 175 + { 176 + u8 prescale; 177 + 178 + for (prescale = 0; prescale < 5; prescale++) 179 + if ((rate >> (prescale * 2)) <= req_rate) 180 + return prescale; 181 + 182 + return 5; /* /1024 divider */ 183 + } 184 + 185 + static long ingenic_tcu_round_rate(struct clk_hw *hw, unsigned long req_rate, 186 + unsigned long *parent_rate) 187 + { 188 + unsigned long rate = *parent_rate; 189 + u8 prescale; 190 + 191 + if (req_rate > rate) 192 + return -EINVAL; 193 + 194 + prescale = ingenic_tcu_get_prescale(rate, req_rate); 195 + 196 + return rate >> (prescale * 2); 197 + } 198 + 199 + static int ingenic_tcu_set_rate(struct clk_hw *hw, unsigned long req_rate, 200 + unsigned long parent_rate) 201 + { 202 + struct ingenic_tcu_clk *tcu_clk = to_tcu_clk(hw); 203 + const struct ingenic_tcu_clk_info *info = tcu_clk->info; 204 + u8 prescale = ingenic_tcu_get_prescale(parent_rate, req_rate); 205 + bool was_enabled; 206 + int ret; 207 + 208 + was_enabled = ingenic_tcu_enable_regs(hw); 209 + 210 + ret = regmap_update_bits(tcu_clk->tcu->map, info->tcsr_reg, 211 + TCU_TCSR_PRESCALE_MASK, 212 + prescale << TCU_TCSR_PRESCALE_LSB); 213 + WARN_ONCE(ret < 0, "Unable to update TCSR %d", tcu_clk->idx); 214 + 215 + if (!was_enabled) 216 + ingenic_tcu_disable_regs(hw); 217 + 218 + return 0; 219 + } 220 + 221 + static const struct clk_ops ingenic_tcu_clk_ops = { 222 + .get_parent = ingenic_tcu_get_parent, 223 + .set_parent = ingenic_tcu_set_parent, 224 + 225 + .recalc_rate = ingenic_tcu_recalc_rate, 226 + .round_rate = ingenic_tcu_round_rate, 227 + .set_rate = ingenic_tcu_set_rate, 228 + 229 + .enable = ingenic_tcu_enable, 230 + .disable = ingenic_tcu_disable, 231 + .is_enabled = ingenic_tcu_is_enabled, 232 + }; 233 + 234 + static const char * const ingenic_tcu_timer_parents[] = { 235 + [TCU_PARENT_PCLK] = "pclk", 236 + [TCU_PARENT_RTC] = "rtc", 237 + [TCU_PARENT_EXT] = "ext", 238 + }; 239 + 240 + #define DEF_TIMER(_name, _gate_bit, _tcsr) \ 241 + { \ 242 + .init_data = { \ 243 + .name = _name, \ 244 + .parent_names = ingenic_tcu_timer_parents, \ 245 + .num_parents = ARRAY_SIZE(ingenic_tcu_timer_parents),\ 246 + .ops = &ingenic_tcu_clk_ops, \ 247 + .flags = CLK_SET_RATE_UNGATE, \ 248 + }, \ 249 + .gate_bit = _gate_bit, \ 250 + .tcsr_reg = _tcsr, \ 251 + } 252 + static const struct ingenic_tcu_clk_info ingenic_tcu_clk_info[] = { 253 + [TCU_CLK_TIMER0] = DEF_TIMER("timer0", 0, TCU_REG_TCSRc(0)), 254 + [TCU_CLK_TIMER1] = DEF_TIMER("timer1", 1, TCU_REG_TCSRc(1)), 255 + [TCU_CLK_TIMER2] = DEF_TIMER("timer2", 2, TCU_REG_TCSRc(2)), 256 + [TCU_CLK_TIMER3] = DEF_TIMER("timer3", 3, TCU_REG_TCSRc(3)), 257 + [TCU_CLK_TIMER4] = DEF_TIMER("timer4", 4, TCU_REG_TCSRc(4)), 258 + [TCU_CLK_TIMER5] = DEF_TIMER("timer5", 5, TCU_REG_TCSRc(5)), 259 + [TCU_CLK_TIMER6] = DEF_TIMER("timer6", 6, TCU_REG_TCSRc(6)), 260 + [TCU_CLK_TIMER7] = DEF_TIMER("timer7", 7, TCU_REG_TCSRc(7)), 261 + }; 262 + 263 + static const struct ingenic_tcu_clk_info ingenic_tcu_watchdog_clk_info = 264 + DEF_TIMER("wdt", 16, TCU_REG_WDT_TCSR); 265 + static const struct ingenic_tcu_clk_info ingenic_tcu_ost_clk_info = 266 + DEF_TIMER("ost", 15, TCU_REG_OST_TCSR); 267 + #undef DEF_TIMER 268 + 269 + static int __init ingenic_tcu_register_clock(struct ingenic_tcu *tcu, 270 + unsigned int idx, enum tcu_clk_parent parent, 271 + const struct ingenic_tcu_clk_info *info, 272 + struct clk_hw_onecell_data *clocks) 273 + { 274 + struct ingenic_tcu_clk *tcu_clk; 275 + int err; 276 + 277 + tcu_clk = kzalloc(sizeof(*tcu_clk), GFP_KERNEL); 278 + if (!tcu_clk) 279 + return -ENOMEM; 280 + 281 + tcu_clk->hw.init = &info->init_data; 282 + tcu_clk->idx = idx; 283 + tcu_clk->info = info; 284 + tcu_clk->tcu = tcu; 285 + 286 + /* Reset channel and clock divider, set default parent */ 287 + ingenic_tcu_enable_regs(&tcu_clk->hw); 288 + regmap_update_bits(tcu->map, info->tcsr_reg, 0xffff, BIT(parent)); 289 + ingenic_tcu_disable_regs(&tcu_clk->hw); 290 + 291 + err = clk_hw_register(NULL, &tcu_clk->hw); 292 + if (err) { 293 + kfree(tcu_clk); 294 + return err; 295 + } 296 + 297 + clocks->hws[idx] = &tcu_clk->hw; 298 + 299 + return 0; 300 + } 301 + 302 + static const struct ingenic_soc_info jz4740_soc_info = { 303 + .num_channels = 8, 304 + .has_ost = false, 305 + .has_tcu_clk = true, 306 + }; 307 + 308 + static const struct ingenic_soc_info jz4725b_soc_info = { 309 + .num_channels = 6, 310 + .has_ost = true, 311 + .has_tcu_clk = true, 312 + }; 313 + 314 + static const struct ingenic_soc_info jz4770_soc_info = { 315 + .num_channels = 8, 316 + .has_ost = true, 317 + .has_tcu_clk = false, 318 + }; 319 + 320 + static const struct of_device_id ingenic_tcu_of_match[] __initconst = { 321 + { .compatible = "ingenic,jz4740-tcu", .data = &jz4740_soc_info, }, 322 + { .compatible = "ingenic,jz4725b-tcu", .data = &jz4725b_soc_info, }, 323 + { .compatible = "ingenic,jz4770-tcu", .data = &jz4770_soc_info, }, 324 + { /* sentinel */ } 325 + }; 326 + 327 + static int __init ingenic_tcu_probe(struct device_node *np) 328 + { 329 + const struct of_device_id *id = of_match_node(ingenic_tcu_of_match, np); 330 + struct ingenic_tcu *tcu; 331 + struct regmap *map; 332 + unsigned int i; 333 + int ret; 334 + 335 + map = device_node_to_regmap(np); 336 + if (IS_ERR(map)) 337 + return PTR_ERR(map); 338 + 339 + tcu = kzalloc(sizeof(*tcu), GFP_KERNEL); 340 + if (!tcu) 341 + return -ENOMEM; 342 + 343 + tcu->map = map; 344 + tcu->soc_info = id->data; 345 + 346 + if (tcu->soc_info->has_tcu_clk) { 347 + tcu->clk = of_clk_get_by_name(np, "tcu"); 348 + if (IS_ERR(tcu->clk)) { 349 + ret = PTR_ERR(tcu->clk); 350 + pr_crit("Cannot get TCU clock\n"); 351 + goto err_free_tcu; 352 + } 353 + 354 + ret = clk_prepare_enable(tcu->clk); 355 + if (ret) { 356 + pr_crit("Unable to enable TCU clock\n"); 357 + goto err_put_clk; 358 + } 359 + } 360 + 361 + tcu->clocks = kzalloc(sizeof(*tcu->clocks) + 362 + sizeof(*tcu->clocks->hws) * TCU_CLK_COUNT, 363 + GFP_KERNEL); 364 + if (!tcu->clocks) { 365 + ret = -ENOMEM; 366 + goto err_clk_disable; 367 + } 368 + 369 + tcu->clocks->num = TCU_CLK_COUNT; 370 + 371 + for (i = 0; i < tcu->soc_info->num_channels; i++) { 372 + ret = ingenic_tcu_register_clock(tcu, i, TCU_PARENT_EXT, 373 + &ingenic_tcu_clk_info[i], 374 + tcu->clocks); 375 + if (ret) { 376 + pr_crit("cannot register clock %d\n", i); 377 + goto err_unregister_timer_clocks; 378 + } 379 + } 380 + 381 + /* 382 + * We set EXT as the default parent clock for all the TCU clocks 383 + * except for the watchdog one, where we set the RTC clock as the 384 + * parent. Since the EXT and PCLK are much faster than the RTC clock, 385 + * the watchdog would kick after a maximum time of 5s, and we might 386 + * want a slower kicking time. 387 + */ 388 + ret = ingenic_tcu_register_clock(tcu, TCU_CLK_WDT, TCU_PARENT_RTC, 389 + &ingenic_tcu_watchdog_clk_info, 390 + tcu->clocks); 391 + if (ret) { 392 + pr_crit("cannot register watchdog clock\n"); 393 + goto err_unregister_timer_clocks; 394 + } 395 + 396 + if (tcu->soc_info->has_ost) { 397 + ret = ingenic_tcu_register_clock(tcu, TCU_CLK_OST, 398 + TCU_PARENT_EXT, 399 + &ingenic_tcu_ost_clk_info, 400 + tcu->clocks); 401 + if (ret) { 402 + pr_crit("cannot register ost clock\n"); 403 + goto err_unregister_watchdog_clock; 404 + } 405 + } 406 + 407 + ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, tcu->clocks); 408 + if (ret) { 409 + pr_crit("cannot add OF clock provider\n"); 410 + goto err_unregister_ost_clock; 411 + } 412 + 413 + ingenic_tcu = tcu; 414 + 415 + return 0; 416 + 417 + err_unregister_ost_clock: 418 + if (tcu->soc_info->has_ost) 419 + clk_hw_unregister(tcu->clocks->hws[i + 1]); 420 + err_unregister_watchdog_clock: 421 + clk_hw_unregister(tcu->clocks->hws[i]); 422 + err_unregister_timer_clocks: 423 + for (i = 0; i < tcu->clocks->num; i++) 424 + if (tcu->clocks->hws[i]) 425 + clk_hw_unregister(tcu->clocks->hws[i]); 426 + kfree(tcu->clocks); 427 + err_clk_disable: 428 + if (tcu->soc_info->has_tcu_clk) 429 + clk_disable_unprepare(tcu->clk); 430 + err_put_clk: 431 + if (tcu->soc_info->has_tcu_clk) 432 + clk_put(tcu->clk); 433 + err_free_tcu: 434 + kfree(tcu); 435 + return ret; 436 + } 437 + 438 + static int __maybe_unused tcu_pm_suspend(void) 439 + { 440 + struct ingenic_tcu *tcu = ingenic_tcu; 441 + 442 + if (tcu->clk) 443 + clk_disable(tcu->clk); 444 + 445 + return 0; 446 + } 447 + 448 + static void __maybe_unused tcu_pm_resume(void) 449 + { 450 + struct ingenic_tcu *tcu = ingenic_tcu; 451 + 452 + if (tcu->clk) 453 + clk_enable(tcu->clk); 454 + } 455 + 456 + static struct syscore_ops __maybe_unused tcu_pm_ops = { 457 + .suspend = tcu_pm_suspend, 458 + .resume = tcu_pm_resume, 459 + }; 460 + 461 + static void __init ingenic_tcu_init(struct device_node *np) 462 + { 463 + int ret = ingenic_tcu_probe(np); 464 + 465 + if (ret) 466 + pr_crit("Failed to initialize TCU clocks: %d\n", ret); 467 + 468 + if (IS_ENABLED(CONFIG_PM_SLEEP)) 469 + register_syscore_ops(&tcu_pm_ops); 470 + } 471 + 472 + CLK_OF_DECLARE_DRIVER(jz4740_cgu, "ingenic,jz4740-tcu", ingenic_tcu_init); 473 + CLK_OF_DECLARE_DRIVER(jz4725b_cgu, "ingenic,jz4725b-tcu", ingenic_tcu_init); 474 + CLK_OF_DECLARE_DRIVER(jz4770_cgu, "ingenic,jz4770-tcu", ingenic_tcu_init);
+11
drivers/clocksource/Kconfig
··· 685 685 help 686 686 Enables the support for Milbeaut timer driver. 687 687 688 + config INGENIC_TIMER 689 + bool "Clocksource/timer using the TCU in Ingenic JZ SoCs" 690 + default MACH_INGENIC 691 + depends on MIPS || COMPILE_TEST 692 + depends on COMMON_CLK 693 + select MFD_SYSCON 694 + select TIMER_OF 695 + select IRQ_DOMAIN 696 + help 697 + Support for the timer/counter unit of the Ingenic JZ SoCs. 698 + 688 699 endmenu
+1
drivers/clocksource/Makefile
··· 80 80 obj-$(CONFIG_H8300_TMR8) += h8300_timer8.o 81 81 obj-$(CONFIG_H8300_TMR16) += h8300_timer16.o 82 82 obj-$(CONFIG_H8300_TPU) += h8300_tpu.o 83 + obj-$(CONFIG_INGENIC_TIMER) += ingenic-timer.o 83 84 obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o 84 85 obj-$(CONFIG_X86_NUMACHIP) += numachip.o 85 86 obj-$(CONFIG_ATCPIT100_TIMER) += timer-atcpit100.o
+356
drivers/clocksource/ingenic-timer.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * JZ47xx SoCs TCU IRQ driver 4 + * Copyright (C) 2019 Paul Cercueil <paul@crapouillou.net> 5 + */ 6 + 7 + #include <linux/bitops.h> 8 + #include <linux/clk.h> 9 + #include <linux/clockchips.h> 10 + #include <linux/clocksource.h> 11 + #include <linux/interrupt.h> 12 + #include <linux/mfd/ingenic-tcu.h> 13 + #include <linux/mfd/syscon.h> 14 + #include <linux/of.h> 15 + #include <linux/of_address.h> 16 + #include <linux/of_irq.h> 17 + #include <linux/of_platform.h> 18 + #include <linux/platform_device.h> 19 + #include <linux/regmap.h> 20 + #include <linux/sched_clock.h> 21 + 22 + #include <dt-bindings/clock/ingenic,tcu.h> 23 + 24 + struct ingenic_soc_info { 25 + unsigned int num_channels; 26 + }; 27 + 28 + struct ingenic_tcu { 29 + struct regmap *map; 30 + struct clk *timer_clk, *cs_clk; 31 + unsigned int timer_channel, cs_channel; 32 + struct clock_event_device cevt; 33 + struct clocksource cs; 34 + char name[4]; 35 + unsigned long pwm_channels_mask; 36 + }; 37 + 38 + static struct ingenic_tcu *ingenic_tcu; 39 + 40 + static u64 notrace ingenic_tcu_timer_read(void) 41 + { 42 + struct ingenic_tcu *tcu = ingenic_tcu; 43 + unsigned int count; 44 + 45 + regmap_read(tcu->map, TCU_REG_TCNTc(tcu->cs_channel), &count); 46 + 47 + return count; 48 + } 49 + 50 + static u64 notrace ingenic_tcu_timer_cs_read(struct clocksource *cs) 51 + { 52 + return ingenic_tcu_timer_read(); 53 + } 54 + 55 + static inline struct ingenic_tcu *to_ingenic_tcu(struct clock_event_device *evt) 56 + { 57 + return container_of(evt, struct ingenic_tcu, cevt); 58 + } 59 + 60 + static int ingenic_tcu_cevt_set_state_shutdown(struct clock_event_device *evt) 61 + { 62 + struct ingenic_tcu *tcu = to_ingenic_tcu(evt); 63 + 64 + regmap_write(tcu->map, TCU_REG_TECR, BIT(tcu->timer_channel)); 65 + 66 + return 0; 67 + } 68 + 69 + static int ingenic_tcu_cevt_set_next(unsigned long next, 70 + struct clock_event_device *evt) 71 + { 72 + struct ingenic_tcu *tcu = to_ingenic_tcu(evt); 73 + 74 + if (next > 0xffff) 75 + return -EINVAL; 76 + 77 + regmap_write(tcu->map, TCU_REG_TDFRc(tcu->timer_channel), next); 78 + regmap_write(tcu->map, TCU_REG_TCNTc(tcu->timer_channel), 0); 79 + regmap_write(tcu->map, TCU_REG_TESR, BIT(tcu->timer_channel)); 80 + 81 + return 0; 82 + } 83 + 84 + static irqreturn_t ingenic_tcu_cevt_cb(int irq, void *dev_id) 85 + { 86 + struct clock_event_device *evt = dev_id; 87 + struct ingenic_tcu *tcu = to_ingenic_tcu(evt); 88 + 89 + regmap_write(tcu->map, TCU_REG_TECR, BIT(tcu->timer_channel)); 90 + 91 + if (evt->event_handler) 92 + evt->event_handler(evt); 93 + 94 + return IRQ_HANDLED; 95 + } 96 + 97 + static struct clk * __init ingenic_tcu_get_clock(struct device_node *np, int id) 98 + { 99 + struct of_phandle_args args; 100 + 101 + args.np = np; 102 + args.args_count = 1; 103 + args.args[0] = id; 104 + 105 + return of_clk_get_from_provider(&args); 106 + } 107 + 108 + static int __init ingenic_tcu_timer_init(struct device_node *np, 109 + struct ingenic_tcu *tcu) 110 + { 111 + unsigned int timer_virq, channel = tcu->timer_channel; 112 + struct irq_domain *domain; 113 + unsigned long rate; 114 + int err; 115 + 116 + tcu->timer_clk = ingenic_tcu_get_clock(np, channel); 117 + if (IS_ERR(tcu->timer_clk)) 118 + return PTR_ERR(tcu->timer_clk); 119 + 120 + err = clk_prepare_enable(tcu->timer_clk); 121 + if (err) 122 + goto err_clk_put; 123 + 124 + rate = clk_get_rate(tcu->timer_clk); 125 + if (!rate) { 126 + err = -EINVAL; 127 + goto err_clk_disable; 128 + } 129 + 130 + domain = irq_find_host(np); 131 + if (!domain) { 132 + err = -ENODEV; 133 + goto err_clk_disable; 134 + } 135 + 136 + timer_virq = irq_create_mapping(domain, channel); 137 + if (!timer_virq) { 138 + err = -EINVAL; 139 + goto err_clk_disable; 140 + } 141 + 142 + snprintf(tcu->name, sizeof(tcu->name), "TCU"); 143 + 144 + err = request_irq(timer_virq, ingenic_tcu_cevt_cb, IRQF_TIMER, 145 + tcu->name, &tcu->cevt); 146 + if (err) 147 + goto err_irq_dispose_mapping; 148 + 149 + tcu->cevt.cpumask = cpumask_of(smp_processor_id()); 150 + tcu->cevt.features = CLOCK_EVT_FEAT_ONESHOT; 151 + tcu->cevt.name = tcu->name; 152 + tcu->cevt.rating = 200; 153 + tcu->cevt.set_state_shutdown = ingenic_tcu_cevt_set_state_shutdown; 154 + tcu->cevt.set_next_event = ingenic_tcu_cevt_set_next; 155 + 156 + clockevents_config_and_register(&tcu->cevt, rate, 10, 0xffff); 157 + 158 + return 0; 159 + 160 + err_irq_dispose_mapping: 161 + irq_dispose_mapping(timer_virq); 162 + err_clk_disable: 163 + clk_disable_unprepare(tcu->timer_clk); 164 + err_clk_put: 165 + clk_put(tcu->timer_clk); 166 + return err; 167 + } 168 + 169 + static int __init ingenic_tcu_clocksource_init(struct device_node *np, 170 + struct ingenic_tcu *tcu) 171 + { 172 + unsigned int channel = tcu->cs_channel; 173 + struct clocksource *cs = &tcu->cs; 174 + unsigned long rate; 175 + int err; 176 + 177 + tcu->cs_clk = ingenic_tcu_get_clock(np, channel); 178 + if (IS_ERR(tcu->cs_clk)) 179 + return PTR_ERR(tcu->cs_clk); 180 + 181 + err = clk_prepare_enable(tcu->cs_clk); 182 + if (err) 183 + goto err_clk_put; 184 + 185 + rate = clk_get_rate(tcu->cs_clk); 186 + if (!rate) { 187 + err = -EINVAL; 188 + goto err_clk_disable; 189 + } 190 + 191 + /* Reset channel */ 192 + regmap_update_bits(tcu->map, TCU_REG_TCSRc(channel), 193 + 0xffff & ~TCU_TCSR_RESERVED_BITS, 0); 194 + 195 + /* Reset counter */ 196 + regmap_write(tcu->map, TCU_REG_TDFRc(channel), 0xffff); 197 + regmap_write(tcu->map, TCU_REG_TCNTc(channel), 0); 198 + 199 + /* Enable channel */ 200 + regmap_write(tcu->map, TCU_REG_TESR, BIT(channel)); 201 + 202 + cs->name = "ingenic-timer"; 203 + cs->rating = 200; 204 + cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; 205 + cs->mask = CLOCKSOURCE_MASK(16); 206 + cs->read = ingenic_tcu_timer_cs_read; 207 + 208 + err = clocksource_register_hz(cs, rate); 209 + if (err) 210 + goto err_clk_disable; 211 + 212 + return 0; 213 + 214 + err_clk_disable: 215 + clk_disable_unprepare(tcu->cs_clk); 216 + err_clk_put: 217 + clk_put(tcu->cs_clk); 218 + return err; 219 + } 220 + 221 + static const struct ingenic_soc_info jz4740_soc_info = { 222 + .num_channels = 8, 223 + }; 224 + 225 + static const struct ingenic_soc_info jz4725b_soc_info = { 226 + .num_channels = 6, 227 + }; 228 + 229 + static const struct of_device_id ingenic_tcu_of_match[] = { 230 + { .compatible = "ingenic,jz4740-tcu", .data = &jz4740_soc_info, }, 231 + { .compatible = "ingenic,jz4725b-tcu", .data = &jz4725b_soc_info, }, 232 + { .compatible = "ingenic,jz4770-tcu", .data = &jz4740_soc_info, }, 233 + { /* sentinel */ } 234 + }; 235 + 236 + static int __init ingenic_tcu_init(struct device_node *np) 237 + { 238 + const struct of_device_id *id = of_match_node(ingenic_tcu_of_match, np); 239 + const struct ingenic_soc_info *soc_info = id->data; 240 + struct ingenic_tcu *tcu; 241 + struct regmap *map; 242 + long rate; 243 + int ret; 244 + 245 + of_node_clear_flag(np, OF_POPULATED); 246 + 247 + map = device_node_to_regmap(np); 248 + if (IS_ERR(map)) 249 + return PTR_ERR(map); 250 + 251 + tcu = kzalloc(sizeof(*tcu), GFP_KERNEL); 252 + if (!tcu) 253 + return -ENOMEM; 254 + 255 + /* Enable all TCU channels for PWM use by default except channels 0/1 */ 256 + tcu->pwm_channels_mask = GENMASK(soc_info->num_channels - 1, 2); 257 + of_property_read_u32(np, "ingenic,pwm-channels-mask", 258 + (u32 *)&tcu->pwm_channels_mask); 259 + 260 + /* Verify that we have at least two free channels */ 261 + if (hweight8(tcu->pwm_channels_mask) > soc_info->num_channels - 2) { 262 + pr_crit("%s: Invalid PWM channel mask: 0x%02lx\n", __func__, 263 + tcu->pwm_channels_mask); 264 + ret = -EINVAL; 265 + goto err_free_ingenic_tcu; 266 + } 267 + 268 + tcu->map = map; 269 + ingenic_tcu = tcu; 270 + 271 + tcu->timer_channel = find_first_zero_bit(&tcu->pwm_channels_mask, 272 + soc_info->num_channels); 273 + tcu->cs_channel = find_next_zero_bit(&tcu->pwm_channels_mask, 274 + soc_info->num_channels, 275 + tcu->timer_channel + 1); 276 + 277 + ret = ingenic_tcu_clocksource_init(np, tcu); 278 + if (ret) { 279 + pr_crit("%s: Unable to init clocksource: %d\n", __func__, ret); 280 + goto err_free_ingenic_tcu; 281 + } 282 + 283 + ret = ingenic_tcu_timer_init(np, tcu); 284 + if (ret) 285 + goto err_tcu_clocksource_cleanup; 286 + 287 + /* Register the sched_clock at the end as there's no way to undo it */ 288 + rate = clk_get_rate(tcu->cs_clk); 289 + sched_clock_register(ingenic_tcu_timer_read, 16, rate); 290 + 291 + return 0; 292 + 293 + err_tcu_clocksource_cleanup: 294 + clocksource_unregister(&tcu->cs); 295 + clk_disable_unprepare(tcu->cs_clk); 296 + clk_put(tcu->cs_clk); 297 + err_free_ingenic_tcu: 298 + kfree(tcu); 299 + return ret; 300 + } 301 + 302 + TIMER_OF_DECLARE(jz4740_tcu_intc, "ingenic,jz4740-tcu", ingenic_tcu_init); 303 + TIMER_OF_DECLARE(jz4725b_tcu_intc, "ingenic,jz4725b-tcu", ingenic_tcu_init); 304 + TIMER_OF_DECLARE(jz4770_tcu_intc, "ingenic,jz4770-tcu", ingenic_tcu_init); 305 + 306 + 307 + static int __init ingenic_tcu_probe(struct platform_device *pdev) 308 + { 309 + platform_set_drvdata(pdev, ingenic_tcu); 310 + 311 + return 0; 312 + } 313 + 314 + static int __maybe_unused ingenic_tcu_suspend(struct device *dev) 315 + { 316 + struct ingenic_tcu *tcu = dev_get_drvdata(dev); 317 + 318 + clk_disable(tcu->cs_clk); 319 + clk_disable(tcu->timer_clk); 320 + return 0; 321 + } 322 + 323 + static int __maybe_unused ingenic_tcu_resume(struct device *dev) 324 + { 325 + struct ingenic_tcu *tcu = dev_get_drvdata(dev); 326 + int ret; 327 + 328 + ret = clk_enable(tcu->timer_clk); 329 + if (ret) 330 + return ret; 331 + 332 + ret = clk_enable(tcu->cs_clk); 333 + if (ret) { 334 + clk_disable(tcu->timer_clk); 335 + return ret; 336 + } 337 + 338 + return 0; 339 + } 340 + 341 + static const struct dev_pm_ops __maybe_unused ingenic_tcu_pm_ops = { 342 + /* _noirq: We want the TCU clocks to be gated last / ungated first */ 343 + .suspend_noirq = ingenic_tcu_suspend, 344 + .resume_noirq = ingenic_tcu_resume, 345 + }; 346 + 347 + static struct platform_driver ingenic_tcu_driver = { 348 + .driver = { 349 + .name = "ingenic-tcu-timer", 350 + #ifdef CONFIG_PM_SLEEP 351 + .pm = &ingenic_tcu_pm_ops, 352 + #endif 353 + .of_match_table = ingenic_tcu_of_match, 354 + }, 355 + }; 356 + builtin_platform_driver_probe(ingenic_tcu_driver, ingenic_tcu_probe);
-6
drivers/dma/Kconfig
··· 137 137 select DMA_ENGINE 138 138 select DMA_VIRTUAL_CHANNELS 139 139 140 - config DMA_JZ4740 141 - tristate "JZ4740 DMA support" 142 - depends on MACH_JZ4740 || COMPILE_TEST 143 - select DMA_ENGINE 144 - select DMA_VIRTUAL_CHANNELS 145 - 146 140 config DMA_JZ4780 147 141 tristate "JZ4780 DMA support" 148 142 depends on MIPS || COMPILE_TEST
-1
drivers/dma/Makefile
··· 22 22 obj-$(CONFIG_BCM_SBA_RAID) += bcm-sba-raid.o 23 23 obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o 24 24 obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o 25 - obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o 26 25 obj-$(CONFIG_DMA_JZ4780) += dma-jz4780.o 27 26 obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o 28 27 obj-$(CONFIG_DMA_SUN4I) += sun4i-dma.o
-623
drivers/dma/dma-jz4740.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-or-later 2 - /* 3 - * Copyright (C) 2013, Lars-Peter Clausen <lars@metafoo.de> 4 - * JZ4740 DMAC support 5 - */ 6 - 7 - #include <linux/dmaengine.h> 8 - #include <linux/dma-mapping.h> 9 - #include <linux/err.h> 10 - #include <linux/init.h> 11 - #include <linux/list.h> 12 - #include <linux/module.h> 13 - #include <linux/platform_device.h> 14 - #include <linux/slab.h> 15 - #include <linux/spinlock.h> 16 - #include <linux/irq.h> 17 - #include <linux/clk.h> 18 - 19 - #include "virt-dma.h" 20 - 21 - #define JZ_DMA_NR_CHANS 6 22 - 23 - #define JZ_REG_DMA_SRC_ADDR(x) (0x00 + (x) * 0x20) 24 - #define JZ_REG_DMA_DST_ADDR(x) (0x04 + (x) * 0x20) 25 - #define JZ_REG_DMA_TRANSFER_COUNT(x) (0x08 + (x) * 0x20) 26 - #define JZ_REG_DMA_REQ_TYPE(x) (0x0C + (x) * 0x20) 27 - #define JZ_REG_DMA_STATUS_CTRL(x) (0x10 + (x) * 0x20) 28 - #define JZ_REG_DMA_CMD(x) (0x14 + (x) * 0x20) 29 - #define JZ_REG_DMA_DESC_ADDR(x) (0x18 + (x) * 0x20) 30 - 31 - #define JZ_REG_DMA_CTRL 0x300 32 - #define JZ_REG_DMA_IRQ 0x304 33 - #define JZ_REG_DMA_DOORBELL 0x308 34 - #define JZ_REG_DMA_DOORBELL_SET 0x30C 35 - 36 - #define JZ_DMA_STATUS_CTRL_NO_DESC BIT(31) 37 - #define JZ_DMA_STATUS_CTRL_DESC_INV BIT(6) 38 - #define JZ_DMA_STATUS_CTRL_ADDR_ERR BIT(4) 39 - #define JZ_DMA_STATUS_CTRL_TRANSFER_DONE BIT(3) 40 - #define JZ_DMA_STATUS_CTRL_HALT BIT(2) 41 - #define JZ_DMA_STATUS_CTRL_COUNT_TERMINATE BIT(1) 42 - #define JZ_DMA_STATUS_CTRL_ENABLE BIT(0) 43 - 44 - #define JZ_DMA_CMD_SRC_INC BIT(23) 45 - #define JZ_DMA_CMD_DST_INC BIT(22) 46 - #define JZ_DMA_CMD_RDIL_MASK (0xf << 16) 47 - #define JZ_DMA_CMD_SRC_WIDTH_MASK (0x3 << 14) 48 - #define JZ_DMA_CMD_DST_WIDTH_MASK (0x3 << 12) 49 - #define JZ_DMA_CMD_INTERVAL_LENGTH_MASK (0x7 << 8) 50 - #define JZ_DMA_CMD_BLOCK_MODE BIT(7) 51 - #define JZ_DMA_CMD_DESC_VALID BIT(4) 52 - #define JZ_DMA_CMD_DESC_VALID_MODE BIT(3) 53 - #define JZ_DMA_CMD_VALID_IRQ_ENABLE BIT(2) 54 - #define JZ_DMA_CMD_TRANSFER_IRQ_ENABLE BIT(1) 55 - #define JZ_DMA_CMD_LINK_ENABLE BIT(0) 56 - 57 - #define JZ_DMA_CMD_FLAGS_OFFSET 22 58 - #define JZ_DMA_CMD_RDIL_OFFSET 16 59 - #define JZ_DMA_CMD_SRC_WIDTH_OFFSET 14 60 - #define JZ_DMA_CMD_DST_WIDTH_OFFSET 12 61 - #define JZ_DMA_CMD_TRANSFER_SIZE_OFFSET 8 62 - #define JZ_DMA_CMD_MODE_OFFSET 7 63 - 64 - #define JZ_DMA_CTRL_PRIORITY_MASK (0x3 << 8) 65 - #define JZ_DMA_CTRL_HALT BIT(3) 66 - #define JZ_DMA_CTRL_ADDRESS_ERROR BIT(2) 67 - #define JZ_DMA_CTRL_ENABLE BIT(0) 68 - 69 - enum jz4740_dma_width { 70 - JZ4740_DMA_WIDTH_32BIT = 0, 71 - JZ4740_DMA_WIDTH_8BIT = 1, 72 - JZ4740_DMA_WIDTH_16BIT = 2, 73 - }; 74 - 75 - enum jz4740_dma_transfer_size { 76 - JZ4740_DMA_TRANSFER_SIZE_4BYTE = 0, 77 - JZ4740_DMA_TRANSFER_SIZE_1BYTE = 1, 78 - JZ4740_DMA_TRANSFER_SIZE_2BYTE = 2, 79 - JZ4740_DMA_TRANSFER_SIZE_16BYTE = 3, 80 - JZ4740_DMA_TRANSFER_SIZE_32BYTE = 4, 81 - }; 82 - 83 - enum jz4740_dma_flags { 84 - JZ4740_DMA_SRC_AUTOINC = 0x2, 85 - JZ4740_DMA_DST_AUTOINC = 0x1, 86 - }; 87 - 88 - enum jz4740_dma_mode { 89 - JZ4740_DMA_MODE_SINGLE = 0, 90 - JZ4740_DMA_MODE_BLOCK = 1, 91 - }; 92 - 93 - struct jz4740_dma_sg { 94 - dma_addr_t addr; 95 - unsigned int len; 96 - }; 97 - 98 - struct jz4740_dma_desc { 99 - struct virt_dma_desc vdesc; 100 - 101 - enum dma_transfer_direction direction; 102 - bool cyclic; 103 - 104 - unsigned int num_sgs; 105 - struct jz4740_dma_sg sg[]; 106 - }; 107 - 108 - struct jz4740_dmaengine_chan { 109 - struct virt_dma_chan vchan; 110 - unsigned int id; 111 - struct dma_slave_config config; 112 - 113 - dma_addr_t fifo_addr; 114 - unsigned int transfer_shift; 115 - 116 - struct jz4740_dma_desc *desc; 117 - unsigned int next_sg; 118 - }; 119 - 120 - struct jz4740_dma_dev { 121 - struct dma_device ddev; 122 - void __iomem *base; 123 - struct clk *clk; 124 - 125 - struct jz4740_dmaengine_chan chan[JZ_DMA_NR_CHANS]; 126 - }; 127 - 128 - static struct jz4740_dma_dev *jz4740_dma_chan_get_dev( 129 - struct jz4740_dmaengine_chan *chan) 130 - { 131 - return container_of(chan->vchan.chan.device, struct jz4740_dma_dev, 132 - ddev); 133 - } 134 - 135 - static struct jz4740_dmaengine_chan *to_jz4740_dma_chan(struct dma_chan *c) 136 - { 137 - return container_of(c, struct jz4740_dmaengine_chan, vchan.chan); 138 - } 139 - 140 - static struct jz4740_dma_desc *to_jz4740_dma_desc(struct virt_dma_desc *vdesc) 141 - { 142 - return container_of(vdesc, struct jz4740_dma_desc, vdesc); 143 - } 144 - 145 - static inline uint32_t jz4740_dma_read(struct jz4740_dma_dev *dmadev, 146 - unsigned int reg) 147 - { 148 - return readl(dmadev->base + reg); 149 - } 150 - 151 - static inline void jz4740_dma_write(struct jz4740_dma_dev *dmadev, 152 - unsigned reg, uint32_t val) 153 - { 154 - writel(val, dmadev->base + reg); 155 - } 156 - 157 - static inline void jz4740_dma_write_mask(struct jz4740_dma_dev *dmadev, 158 - unsigned int reg, uint32_t val, uint32_t mask) 159 - { 160 - uint32_t tmp; 161 - 162 - tmp = jz4740_dma_read(dmadev, reg); 163 - tmp &= ~mask; 164 - tmp |= val; 165 - jz4740_dma_write(dmadev, reg, tmp); 166 - } 167 - 168 - static struct jz4740_dma_desc *jz4740_dma_alloc_desc(unsigned int num_sgs) 169 - { 170 - return kzalloc(sizeof(struct jz4740_dma_desc) + 171 - sizeof(struct jz4740_dma_sg) * num_sgs, GFP_ATOMIC); 172 - } 173 - 174 - static enum jz4740_dma_width jz4740_dma_width(enum dma_slave_buswidth width) 175 - { 176 - switch (width) { 177 - case DMA_SLAVE_BUSWIDTH_1_BYTE: 178 - return JZ4740_DMA_WIDTH_8BIT; 179 - case DMA_SLAVE_BUSWIDTH_2_BYTES: 180 - return JZ4740_DMA_WIDTH_16BIT; 181 - case DMA_SLAVE_BUSWIDTH_4_BYTES: 182 - return JZ4740_DMA_WIDTH_32BIT; 183 - default: 184 - return JZ4740_DMA_WIDTH_32BIT; 185 - } 186 - } 187 - 188 - static enum jz4740_dma_transfer_size jz4740_dma_maxburst(u32 maxburst) 189 - { 190 - if (maxburst <= 1) 191 - return JZ4740_DMA_TRANSFER_SIZE_1BYTE; 192 - else if (maxburst <= 3) 193 - return JZ4740_DMA_TRANSFER_SIZE_2BYTE; 194 - else if (maxburst <= 15) 195 - return JZ4740_DMA_TRANSFER_SIZE_4BYTE; 196 - else if (maxburst <= 31) 197 - return JZ4740_DMA_TRANSFER_SIZE_16BYTE; 198 - 199 - return JZ4740_DMA_TRANSFER_SIZE_32BYTE; 200 - } 201 - 202 - static int jz4740_dma_slave_config_write(struct dma_chan *c, 203 - struct dma_slave_config *config, 204 - enum dma_transfer_direction direction) 205 - { 206 - struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c); 207 - struct jz4740_dma_dev *dmadev = jz4740_dma_chan_get_dev(chan); 208 - enum jz4740_dma_width src_width; 209 - enum jz4740_dma_width dst_width; 210 - enum jz4740_dma_transfer_size transfer_size; 211 - enum jz4740_dma_flags flags; 212 - uint32_t cmd; 213 - 214 - switch (direction) { 215 - case DMA_MEM_TO_DEV: 216 - flags = JZ4740_DMA_SRC_AUTOINC; 217 - transfer_size = jz4740_dma_maxburst(config->dst_maxburst); 218 - chan->fifo_addr = config->dst_addr; 219 - break; 220 - case DMA_DEV_TO_MEM: 221 - flags = JZ4740_DMA_DST_AUTOINC; 222 - transfer_size = jz4740_dma_maxburst(config->src_maxburst); 223 - chan->fifo_addr = config->src_addr; 224 - break; 225 - default: 226 - return -EINVAL; 227 - } 228 - 229 - src_width = jz4740_dma_width(config->src_addr_width); 230 - dst_width = jz4740_dma_width(config->dst_addr_width); 231 - 232 - switch (transfer_size) { 233 - case JZ4740_DMA_TRANSFER_SIZE_2BYTE: 234 - chan->transfer_shift = 1; 235 - break; 236 - case JZ4740_DMA_TRANSFER_SIZE_4BYTE: 237 - chan->transfer_shift = 2; 238 - break; 239 - case JZ4740_DMA_TRANSFER_SIZE_16BYTE: 240 - chan->transfer_shift = 4; 241 - break; 242 - case JZ4740_DMA_TRANSFER_SIZE_32BYTE: 243 - chan->transfer_shift = 5; 244 - break; 245 - default: 246 - chan->transfer_shift = 0; 247 - break; 248 - } 249 - 250 - cmd = flags << JZ_DMA_CMD_FLAGS_OFFSET; 251 - cmd |= src_width << JZ_DMA_CMD_SRC_WIDTH_OFFSET; 252 - cmd |= dst_width << JZ_DMA_CMD_DST_WIDTH_OFFSET; 253 - cmd |= transfer_size << JZ_DMA_CMD_TRANSFER_SIZE_OFFSET; 254 - cmd |= JZ4740_DMA_MODE_SINGLE << JZ_DMA_CMD_MODE_OFFSET; 255 - cmd |= JZ_DMA_CMD_TRANSFER_IRQ_ENABLE; 256 - 257 - jz4740_dma_write(dmadev, JZ_REG_DMA_CMD(chan->id), cmd); 258 - jz4740_dma_write(dmadev, JZ_REG_DMA_STATUS_CTRL(chan->id), 0); 259 - jz4740_dma_write(dmadev, JZ_REG_DMA_REQ_TYPE(chan->id), 260 - config->slave_id); 261 - 262 - return 0; 263 - } 264 - 265 - static int jz4740_dma_slave_config(struct dma_chan *c, 266 - struct dma_slave_config *config) 267 - { 268 - struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c); 269 - 270 - memcpy(&chan->config, config, sizeof(*config)); 271 - return 0; 272 - } 273 - 274 - static int jz4740_dma_terminate_all(struct dma_chan *c) 275 - { 276 - struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c); 277 - struct jz4740_dma_dev *dmadev = jz4740_dma_chan_get_dev(chan); 278 - unsigned long flags; 279 - LIST_HEAD(head); 280 - 281 - spin_lock_irqsave(&chan->vchan.lock, flags); 282 - jz4740_dma_write_mask(dmadev, JZ_REG_DMA_STATUS_CTRL(chan->id), 0, 283 - JZ_DMA_STATUS_CTRL_ENABLE); 284 - chan->desc = NULL; 285 - vchan_get_all_descriptors(&chan->vchan, &head); 286 - spin_unlock_irqrestore(&chan->vchan.lock, flags); 287 - 288 - vchan_dma_desc_free_list(&chan->vchan, &head); 289 - 290 - return 0; 291 - } 292 - 293 - static int jz4740_dma_start_transfer(struct jz4740_dmaengine_chan *chan) 294 - { 295 - struct jz4740_dma_dev *dmadev = jz4740_dma_chan_get_dev(chan); 296 - dma_addr_t src_addr, dst_addr; 297 - struct virt_dma_desc *vdesc; 298 - struct jz4740_dma_sg *sg; 299 - 300 - jz4740_dma_write_mask(dmadev, JZ_REG_DMA_STATUS_CTRL(chan->id), 0, 301 - JZ_DMA_STATUS_CTRL_ENABLE); 302 - 303 - if (!chan->desc) { 304 - vdesc = vchan_next_desc(&chan->vchan); 305 - if (!vdesc) 306 - return 0; 307 - chan->desc = to_jz4740_dma_desc(vdesc); 308 - chan->next_sg = 0; 309 - } 310 - 311 - if (chan->next_sg == chan->desc->num_sgs) 312 - chan->next_sg = 0; 313 - 314 - sg = &chan->desc->sg[chan->next_sg]; 315 - 316 - if (chan->desc->direction == DMA_MEM_TO_DEV) { 317 - src_addr = sg->addr; 318 - dst_addr = chan->fifo_addr; 319 - } else { 320 - src_addr = chan->fifo_addr; 321 - dst_addr = sg->addr; 322 - } 323 - jz4740_dma_write(dmadev, JZ_REG_DMA_SRC_ADDR(chan->id), src_addr); 324 - jz4740_dma_write(dmadev, JZ_REG_DMA_DST_ADDR(chan->id), dst_addr); 325 - jz4740_dma_write(dmadev, JZ_REG_DMA_TRANSFER_COUNT(chan->id), 326 - sg->len >> chan->transfer_shift); 327 - 328 - chan->next_sg++; 329 - 330 - jz4740_dma_write_mask(dmadev, JZ_REG_DMA_STATUS_CTRL(chan->id), 331 - JZ_DMA_STATUS_CTRL_NO_DESC | JZ_DMA_STATUS_CTRL_ENABLE, 332 - JZ_DMA_STATUS_CTRL_HALT | JZ_DMA_STATUS_CTRL_NO_DESC | 333 - JZ_DMA_STATUS_CTRL_ENABLE); 334 - 335 - jz4740_dma_write_mask(dmadev, JZ_REG_DMA_CTRL, 336 - JZ_DMA_CTRL_ENABLE, 337 - JZ_DMA_CTRL_HALT | JZ_DMA_CTRL_ENABLE); 338 - 339 - return 0; 340 - } 341 - 342 - static void jz4740_dma_chan_irq(struct jz4740_dmaengine_chan *chan) 343 - { 344 - spin_lock(&chan->vchan.lock); 345 - if (chan->desc) { 346 - if (chan->desc->cyclic) { 347 - vchan_cyclic_callback(&chan->desc->vdesc); 348 - } else { 349 - if (chan->next_sg == chan->desc->num_sgs) { 350 - list_del(&chan->desc->vdesc.node); 351 - vchan_cookie_complete(&chan->desc->vdesc); 352 - chan->desc = NULL; 353 - } 354 - } 355 - } 356 - jz4740_dma_start_transfer(chan); 357 - spin_unlock(&chan->vchan.lock); 358 - } 359 - 360 - static irqreturn_t jz4740_dma_irq(int irq, void *devid) 361 - { 362 - struct jz4740_dma_dev *dmadev = devid; 363 - uint32_t irq_status; 364 - unsigned int i; 365 - 366 - irq_status = readl(dmadev->base + JZ_REG_DMA_IRQ); 367 - 368 - for (i = 0; i < 6; ++i) { 369 - if (irq_status & (1 << i)) { 370 - jz4740_dma_write_mask(dmadev, 371 - JZ_REG_DMA_STATUS_CTRL(i), 0, 372 - JZ_DMA_STATUS_CTRL_ENABLE | 373 - JZ_DMA_STATUS_CTRL_TRANSFER_DONE); 374 - 375 - jz4740_dma_chan_irq(&dmadev->chan[i]); 376 - } 377 - } 378 - 379 - return IRQ_HANDLED; 380 - } 381 - 382 - static void jz4740_dma_issue_pending(struct dma_chan *c) 383 - { 384 - struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c); 385 - unsigned long flags; 386 - 387 - spin_lock_irqsave(&chan->vchan.lock, flags); 388 - if (vchan_issue_pending(&chan->vchan) && !chan->desc) 389 - jz4740_dma_start_transfer(chan); 390 - spin_unlock_irqrestore(&chan->vchan.lock, flags); 391 - } 392 - 393 - static struct dma_async_tx_descriptor *jz4740_dma_prep_slave_sg( 394 - struct dma_chan *c, struct scatterlist *sgl, 395 - unsigned int sg_len, enum dma_transfer_direction direction, 396 - unsigned long flags, void *context) 397 - { 398 - struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c); 399 - struct jz4740_dma_desc *desc; 400 - struct scatterlist *sg; 401 - unsigned int i; 402 - 403 - desc = jz4740_dma_alloc_desc(sg_len); 404 - if (!desc) 405 - return NULL; 406 - 407 - for_each_sg(sgl, sg, sg_len, i) { 408 - desc->sg[i].addr = sg_dma_address(sg); 409 - desc->sg[i].len = sg_dma_len(sg); 410 - } 411 - 412 - desc->num_sgs = sg_len; 413 - desc->direction = direction; 414 - desc->cyclic = false; 415 - 416 - jz4740_dma_slave_config_write(c, &chan->config, direction); 417 - 418 - return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); 419 - } 420 - 421 - static struct dma_async_tx_descriptor *jz4740_dma_prep_dma_cyclic( 422 - struct dma_chan *c, dma_addr_t buf_addr, size_t buf_len, 423 - size_t period_len, enum dma_transfer_direction direction, 424 - unsigned long flags) 425 - { 426 - struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c); 427 - struct jz4740_dma_desc *desc; 428 - unsigned int num_periods, i; 429 - 430 - if (buf_len % period_len) 431 - return NULL; 432 - 433 - num_periods = buf_len / period_len; 434 - 435 - desc = jz4740_dma_alloc_desc(num_periods); 436 - if (!desc) 437 - return NULL; 438 - 439 - for (i = 0; i < num_periods; i++) { 440 - desc->sg[i].addr = buf_addr; 441 - desc->sg[i].len = period_len; 442 - buf_addr += period_len; 443 - } 444 - 445 - desc->num_sgs = num_periods; 446 - desc->direction = direction; 447 - desc->cyclic = true; 448 - 449 - jz4740_dma_slave_config_write(c, &chan->config, direction); 450 - 451 - return vchan_tx_prep(&chan->vchan, &desc->vdesc, flags); 452 - } 453 - 454 - static size_t jz4740_dma_desc_residue(struct jz4740_dmaengine_chan *chan, 455 - struct jz4740_dma_desc *desc, unsigned int next_sg) 456 - { 457 - struct jz4740_dma_dev *dmadev = jz4740_dma_chan_get_dev(chan); 458 - unsigned int residue, count; 459 - unsigned int i; 460 - 461 - residue = 0; 462 - 463 - for (i = next_sg; i < desc->num_sgs; i++) 464 - residue += desc->sg[i].len; 465 - 466 - if (next_sg != 0) { 467 - count = jz4740_dma_read(dmadev, 468 - JZ_REG_DMA_TRANSFER_COUNT(chan->id)); 469 - residue += count << chan->transfer_shift; 470 - } 471 - 472 - return residue; 473 - } 474 - 475 - static enum dma_status jz4740_dma_tx_status(struct dma_chan *c, 476 - dma_cookie_t cookie, struct dma_tx_state *state) 477 - { 478 - struct jz4740_dmaengine_chan *chan = to_jz4740_dma_chan(c); 479 - struct virt_dma_desc *vdesc; 480 - enum dma_status status; 481 - unsigned long flags; 482 - 483 - status = dma_cookie_status(c, cookie, state); 484 - if (status == DMA_COMPLETE || !state) 485 - return status; 486 - 487 - spin_lock_irqsave(&chan->vchan.lock, flags); 488 - vdesc = vchan_find_desc(&chan->vchan, cookie); 489 - if (cookie == chan->desc->vdesc.tx.cookie) { 490 - state->residue = jz4740_dma_desc_residue(chan, chan->desc, 491 - chan->next_sg); 492 - } else if (vdesc) { 493 - state->residue = jz4740_dma_desc_residue(chan, 494 - to_jz4740_dma_desc(vdesc), 0); 495 - } else { 496 - state->residue = 0; 497 - } 498 - spin_unlock_irqrestore(&chan->vchan.lock, flags); 499 - 500 - return status; 501 - } 502 - 503 - static void jz4740_dma_free_chan_resources(struct dma_chan *c) 504 - { 505 - vchan_free_chan_resources(to_virt_chan(c)); 506 - } 507 - 508 - static void jz4740_dma_desc_free(struct virt_dma_desc *vdesc) 509 - { 510 - kfree(container_of(vdesc, struct jz4740_dma_desc, vdesc)); 511 - } 512 - 513 - #define JZ4740_DMA_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \ 514 - BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | BIT(DMA_SLAVE_BUSWIDTH_4_BYTES)) 515 - 516 - static int jz4740_dma_probe(struct platform_device *pdev) 517 - { 518 - struct jz4740_dmaengine_chan *chan; 519 - struct jz4740_dma_dev *dmadev; 520 - struct dma_device *dd; 521 - unsigned int i; 522 - struct resource *res; 523 - int ret; 524 - int irq; 525 - 526 - dmadev = devm_kzalloc(&pdev->dev, sizeof(*dmadev), GFP_KERNEL); 527 - if (!dmadev) 528 - return -EINVAL; 529 - 530 - dd = &dmadev->ddev; 531 - 532 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 533 - dmadev->base = devm_ioremap_resource(&pdev->dev, res); 534 - if (IS_ERR(dmadev->base)) 535 - return PTR_ERR(dmadev->base); 536 - 537 - dmadev->clk = clk_get(&pdev->dev, "dma"); 538 - if (IS_ERR(dmadev->clk)) 539 - return PTR_ERR(dmadev->clk); 540 - 541 - clk_prepare_enable(dmadev->clk); 542 - 543 - dma_cap_set(DMA_SLAVE, dd->cap_mask); 544 - dma_cap_set(DMA_CYCLIC, dd->cap_mask); 545 - dd->device_free_chan_resources = jz4740_dma_free_chan_resources; 546 - dd->device_tx_status = jz4740_dma_tx_status; 547 - dd->device_issue_pending = jz4740_dma_issue_pending; 548 - dd->device_prep_slave_sg = jz4740_dma_prep_slave_sg; 549 - dd->device_prep_dma_cyclic = jz4740_dma_prep_dma_cyclic; 550 - dd->device_config = jz4740_dma_slave_config; 551 - dd->device_terminate_all = jz4740_dma_terminate_all; 552 - dd->src_addr_widths = JZ4740_DMA_BUSWIDTHS; 553 - dd->dst_addr_widths = JZ4740_DMA_BUSWIDTHS; 554 - dd->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); 555 - dd->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; 556 - dd->dev = &pdev->dev; 557 - INIT_LIST_HEAD(&dd->channels); 558 - 559 - for (i = 0; i < JZ_DMA_NR_CHANS; i++) { 560 - chan = &dmadev->chan[i]; 561 - chan->id = i; 562 - chan->vchan.desc_free = jz4740_dma_desc_free; 563 - vchan_init(&chan->vchan, dd); 564 - } 565 - 566 - ret = dma_async_device_register(dd); 567 - if (ret) 568 - goto err_clk; 569 - 570 - irq = platform_get_irq(pdev, 0); 571 - ret = request_irq(irq, jz4740_dma_irq, 0, dev_name(&pdev->dev), dmadev); 572 - if (ret) 573 - goto err_unregister; 574 - 575 - platform_set_drvdata(pdev, dmadev); 576 - 577 - return 0; 578 - 579 - err_unregister: 580 - dma_async_device_unregister(dd); 581 - err_clk: 582 - clk_disable_unprepare(dmadev->clk); 583 - return ret; 584 - } 585 - 586 - static void jz4740_cleanup_vchan(struct dma_device *dmadev) 587 - { 588 - struct jz4740_dmaengine_chan *chan, *_chan; 589 - 590 - list_for_each_entry_safe(chan, _chan, 591 - &dmadev->channels, vchan.chan.device_node) { 592 - list_del(&chan->vchan.chan.device_node); 593 - tasklet_kill(&chan->vchan.task); 594 - } 595 - } 596 - 597 - 598 - static int jz4740_dma_remove(struct platform_device *pdev) 599 - { 600 - struct jz4740_dma_dev *dmadev = platform_get_drvdata(pdev); 601 - int irq = platform_get_irq(pdev, 0); 602 - 603 - free_irq(irq, dmadev); 604 - 605 - jz4740_cleanup_vchan(&dmadev->ddev); 606 - dma_async_device_unregister(&dmadev->ddev); 607 - clk_disable_unprepare(dmadev->clk); 608 - 609 - return 0; 610 - } 611 - 612 - static struct platform_driver jz4740_dma_driver = { 613 - .probe = jz4740_dma_probe, 614 - .remove = jz4740_dma_remove, 615 - .driver = { 616 - .name = "jz4740-dma", 617 - }, 618 - }; 619 - module_platform_driver(jz4740_dma_driver); 620 - 621 - MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 622 - MODULE_DESCRIPTION("JZ4740 DMA driver"); 623 - MODULE_LICENSE("GPL v2");
+1 -1
drivers/firmware/broadcom/Kconfig
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 config BCM47XX_NVRAM 3 3 bool "Broadcom NVRAM driver" 4 - depends on BCM47XX || ARCH_BCM_5301X 4 + depends on BCM47XX || ARCH_BCM_5301X || COMPILE_TEST 5 5 help 6 6 Broadcom home routers contain flash partition called "nvram" with all 7 7 important hardware configuration as well as some minor user setup.
+2 -2
drivers/firmware/broadcom/bcm47xx_nvram.c
··· 96 96 nvram_len = size; 97 97 } 98 98 if (nvram_len >= NVRAM_SPACE) { 99 - pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", 99 + pr_err("nvram on flash (%zu bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", 100 100 nvram_len, NVRAM_SPACE - 1); 101 101 nvram_len = NVRAM_SPACE - 1; 102 102 } ··· 148 148 header.len > sizeof(header)) { 149 149 nvram_len = header.len; 150 150 if (nvram_len >= NVRAM_SPACE) { 151 - pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", 151 + pr_err("nvram on flash (%zu bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", 152 152 header.len, NVRAM_SPACE); 153 153 nvram_len = NVRAM_SPACE - 1; 154 154 }
-10
drivers/hwmon/Kconfig
··· 670 670 This driver can also be built as a module. If so, the module 671 671 will be called it87. 672 672 673 - config SENSORS_JZ4740 674 - tristate "Ingenic JZ4740 SoC ADC driver" 675 - depends on MACH_JZ4740 && MFD_JZ4740_ADC 676 - help 677 - If you say yes here you get support for reading adc values from the ADCIN 678 - pin on Ingenic JZ4740 SoC based boards. 679 - 680 - This driver can also be built as a module. If so, the module will be 681 - called jz4740-hwmon. 682 - 683 673 config SENSORS_JC42 684 674 tristate "JEDEC JC42.4 compliant memory module temperature sensors" 685 675 depends on I2C
-1
drivers/hwmon/Makefile
··· 85 85 obj-$(CONFIG_SENSORS_INA3221) += ina3221.o 86 86 obj-$(CONFIG_SENSORS_IT87) += it87.o 87 87 obj-$(CONFIG_SENSORS_JC42) += jc42.o 88 - obj-$(CONFIG_SENSORS_JZ4740) += jz4740-hwmon.o 89 88 obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o 90 89 obj-$(CONFIG_SENSORS_K10TEMP) += k10temp.o 91 90 obj-$(CONFIG_SENSORS_LINEAGE) += lineage-pem.o
-135
drivers/hwmon/jz4740-hwmon.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-or-later 2 - /* 3 - * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> 4 - * JZ4740 SoC HWMON driver 5 - */ 6 - 7 - #include <linux/err.h> 8 - #include <linux/interrupt.h> 9 - #include <linux/kernel.h> 10 - #include <linux/module.h> 11 - #include <linux/mutex.h> 12 - #include <linux/platform_device.h> 13 - #include <linux/slab.h> 14 - #include <linux/io.h> 15 - 16 - #include <linux/completion.h> 17 - #include <linux/mfd/core.h> 18 - 19 - #include <linux/hwmon.h> 20 - 21 - struct jz4740_hwmon { 22 - void __iomem *base; 23 - int irq; 24 - const struct mfd_cell *cell; 25 - struct platform_device *pdev; 26 - struct completion read_completion; 27 - struct mutex lock; 28 - }; 29 - 30 - static irqreturn_t jz4740_hwmon_irq(int irq, void *data) 31 - { 32 - struct jz4740_hwmon *hwmon = data; 33 - 34 - complete(&hwmon->read_completion); 35 - return IRQ_HANDLED; 36 - } 37 - 38 - static ssize_t in0_input_show(struct device *dev, 39 - struct device_attribute *dev_attr, char *buf) 40 - { 41 - struct jz4740_hwmon *hwmon = dev_get_drvdata(dev); 42 - struct platform_device *pdev = hwmon->pdev; 43 - struct completion *completion = &hwmon->read_completion; 44 - long t; 45 - unsigned long val; 46 - int ret; 47 - 48 - mutex_lock(&hwmon->lock); 49 - 50 - reinit_completion(completion); 51 - 52 - enable_irq(hwmon->irq); 53 - hwmon->cell->enable(pdev); 54 - 55 - t = wait_for_completion_interruptible_timeout(completion, HZ); 56 - 57 - if (t > 0) { 58 - val = readw(hwmon->base) & 0xfff; 59 - val = (val * 3300) >> 12; 60 - ret = sprintf(buf, "%lu\n", val); 61 - } else { 62 - ret = t ? t : -ETIMEDOUT; 63 - } 64 - 65 - hwmon->cell->disable(pdev); 66 - disable_irq(hwmon->irq); 67 - 68 - mutex_unlock(&hwmon->lock); 69 - 70 - return ret; 71 - } 72 - 73 - static DEVICE_ATTR_RO(in0_input); 74 - 75 - static struct attribute *jz4740_attrs[] = { 76 - &dev_attr_in0_input.attr, 77 - NULL 78 - }; 79 - 80 - ATTRIBUTE_GROUPS(jz4740); 81 - 82 - static int jz4740_hwmon_probe(struct platform_device *pdev) 83 - { 84 - int ret; 85 - struct device *dev = &pdev->dev; 86 - struct jz4740_hwmon *hwmon; 87 - struct device *hwmon_dev; 88 - 89 - hwmon = devm_kzalloc(dev, sizeof(*hwmon), GFP_KERNEL); 90 - if (!hwmon) 91 - return -ENOMEM; 92 - 93 - hwmon->cell = mfd_get_cell(pdev); 94 - 95 - hwmon->irq = platform_get_irq(pdev, 0); 96 - if (hwmon->irq < 0) { 97 - dev_err(&pdev->dev, "Failed to get platform irq: %d\n", 98 - hwmon->irq); 99 - return hwmon->irq; 100 - } 101 - 102 - hwmon->base = devm_platform_ioremap_resource(pdev, 0); 103 - if (IS_ERR(hwmon->base)) 104 - return PTR_ERR(hwmon->base); 105 - 106 - hwmon->pdev = pdev; 107 - init_completion(&hwmon->read_completion); 108 - mutex_init(&hwmon->lock); 109 - 110 - ret = devm_request_irq(dev, hwmon->irq, jz4740_hwmon_irq, 0, 111 - pdev->name, hwmon); 112 - if (ret) { 113 - dev_err(&pdev->dev, "Failed to request irq: %d\n", ret); 114 - return ret; 115 - } 116 - disable_irq(hwmon->irq); 117 - 118 - hwmon_dev = devm_hwmon_device_register_with_groups(dev, "jz4740", hwmon, 119 - jz4740_groups); 120 - return PTR_ERR_OR_ZERO(hwmon_dev); 121 - } 122 - 123 - static struct platform_driver jz4740_hwmon_driver = { 124 - .probe = jz4740_hwmon_probe, 125 - .driver = { 126 - .name = "jz4740-hwmon", 127 - }, 128 - }; 129 - 130 - module_platform_driver(jz4740_hwmon_driver); 131 - 132 - MODULE_DESCRIPTION("JZ4740 SoC HWMON driver"); 133 - MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 134 - MODULE_LICENSE("GPL"); 135 - MODULE_ALIAS("platform:jz4740-hwmon");
+12
drivers/irqchip/Kconfig
··· 315 315 depends on MACH_INGENIC 316 316 default y 317 317 318 + config INGENIC_TCU_IRQ 319 + bool "Ingenic JZ47xx TCU interrupt controller" 320 + default MACH_INGENIC 321 + depends on MIPS || COMPILE_TEST 322 + select MFD_SYSCON 323 + select GENERIC_IRQ_CHIP 324 + help 325 + Support for interrupts in the Timer/Counter Unit (TCU) of the Ingenic 326 + JZ47xx SoCs. 327 + 328 + If unsure, say N. 329 + 318 330 config RENESAS_H8300H_INTC 319 331 bool 320 332 select IRQ_DOMAIN
+1
drivers/irqchip/Makefile
··· 75 75 obj-$(CONFIG_RENESAS_H8S_INTC) += irq-renesas-h8s.o 76 76 obj-$(CONFIG_ARCH_SA1100) += irq-sa11x0.o 77 77 obj-$(CONFIG_INGENIC_IRQ) += irq-ingenic.o 78 + obj-$(CONFIG_INGENIC_TCU_IRQ) += irq-ingenic-tcu.o 78 79 obj-$(CONFIG_IMX_GPCV2) += irq-imx-gpcv2.o 79 80 obj-$(CONFIG_PIC32_EVIC) += irq-pic32-evic.o 80 81 obj-$(CONFIG_MSCC_OCELOT_IRQ) += irq-mscc-ocelot.o
+182
drivers/irqchip/irq-ingenic-tcu.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * JZ47xx SoCs TCU IRQ driver 4 + * Copyright (C) 2019 Paul Cercueil <paul@crapouillou.net> 5 + */ 6 + 7 + #include <linux/clk.h> 8 + #include <linux/interrupt.h> 9 + #include <linux/irqchip.h> 10 + #include <linux/irqchip/chained_irq.h> 11 + #include <linux/mfd/ingenic-tcu.h> 12 + #include <linux/mfd/syscon.h> 13 + #include <linux/of_irq.h> 14 + #include <linux/regmap.h> 15 + 16 + struct ingenic_tcu { 17 + struct regmap *map; 18 + struct clk *clk; 19 + struct irq_domain *domain; 20 + unsigned int nb_parent_irqs; 21 + u32 parent_irqs[3]; 22 + }; 23 + 24 + static void ingenic_tcu_intc_cascade(struct irq_desc *desc) 25 + { 26 + struct irq_chip *irq_chip = irq_data_get_irq_chip(&desc->irq_data); 27 + struct irq_domain *domain = irq_desc_get_handler_data(desc); 28 + struct irq_chip_generic *gc = irq_get_domain_generic_chip(domain, 0); 29 + struct regmap *map = gc->private; 30 + uint32_t irq_reg, irq_mask; 31 + unsigned int i; 32 + 33 + regmap_read(map, TCU_REG_TFR, &irq_reg); 34 + regmap_read(map, TCU_REG_TMR, &irq_mask); 35 + 36 + chained_irq_enter(irq_chip, desc); 37 + 38 + irq_reg &= ~irq_mask; 39 + 40 + for_each_set_bit(i, (unsigned long *)&irq_reg, 32) 41 + generic_handle_irq(irq_linear_revmap(domain, i)); 42 + 43 + chained_irq_exit(irq_chip, desc); 44 + } 45 + 46 + static void ingenic_tcu_gc_unmask_enable_reg(struct irq_data *d) 47 + { 48 + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 49 + struct irq_chip_type *ct = irq_data_get_chip_type(d); 50 + struct regmap *map = gc->private; 51 + u32 mask = d->mask; 52 + 53 + irq_gc_lock(gc); 54 + regmap_write(map, ct->regs.ack, mask); 55 + regmap_write(map, ct->regs.enable, mask); 56 + *ct->mask_cache |= mask; 57 + irq_gc_unlock(gc); 58 + } 59 + 60 + static void ingenic_tcu_gc_mask_disable_reg(struct irq_data *d) 61 + { 62 + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 63 + struct irq_chip_type *ct = irq_data_get_chip_type(d); 64 + struct regmap *map = gc->private; 65 + u32 mask = d->mask; 66 + 67 + irq_gc_lock(gc); 68 + regmap_write(map, ct->regs.disable, mask); 69 + *ct->mask_cache &= ~mask; 70 + irq_gc_unlock(gc); 71 + } 72 + 73 + static void ingenic_tcu_gc_mask_disable_reg_and_ack(struct irq_data *d) 74 + { 75 + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); 76 + struct irq_chip_type *ct = irq_data_get_chip_type(d); 77 + struct regmap *map = gc->private; 78 + u32 mask = d->mask; 79 + 80 + irq_gc_lock(gc); 81 + regmap_write(map, ct->regs.ack, mask); 82 + regmap_write(map, ct->regs.disable, mask); 83 + irq_gc_unlock(gc); 84 + } 85 + 86 + static int __init ingenic_tcu_irq_init(struct device_node *np, 87 + struct device_node *parent) 88 + { 89 + struct irq_chip_generic *gc; 90 + struct irq_chip_type *ct; 91 + struct ingenic_tcu *tcu; 92 + struct regmap *map; 93 + unsigned int i; 94 + int ret, irqs; 95 + 96 + map = device_node_to_regmap(np); 97 + if (IS_ERR(map)) 98 + return PTR_ERR(map); 99 + 100 + tcu = kzalloc(sizeof(*tcu), GFP_KERNEL); 101 + if (!tcu) 102 + return -ENOMEM; 103 + 104 + tcu->map = map; 105 + 106 + irqs = of_property_count_elems_of_size(np, "interrupts", sizeof(u32)); 107 + if (irqs < 0 || irqs > ARRAY_SIZE(tcu->parent_irqs)) { 108 + pr_crit("%s: Invalid 'interrupts' property\n", __func__); 109 + ret = -EINVAL; 110 + goto err_free_tcu; 111 + } 112 + 113 + tcu->nb_parent_irqs = irqs; 114 + 115 + tcu->domain = irq_domain_add_linear(np, 32, &irq_generic_chip_ops, 116 + NULL); 117 + if (!tcu->domain) { 118 + ret = -ENOMEM; 119 + goto err_free_tcu; 120 + } 121 + 122 + ret = irq_alloc_domain_generic_chips(tcu->domain, 32, 1, "TCU", 123 + handle_level_irq, 0, 124 + IRQ_NOPROBE | IRQ_LEVEL, 0); 125 + if (ret) { 126 + pr_crit("%s: Invalid 'interrupts' property\n", __func__); 127 + goto out_domain_remove; 128 + } 129 + 130 + gc = irq_get_domain_generic_chip(tcu->domain, 0); 131 + ct = gc->chip_types; 132 + 133 + gc->wake_enabled = IRQ_MSK(32); 134 + gc->private = tcu->map; 135 + 136 + ct->regs.disable = TCU_REG_TMSR; 137 + ct->regs.enable = TCU_REG_TMCR; 138 + ct->regs.ack = TCU_REG_TFCR; 139 + ct->chip.irq_unmask = ingenic_tcu_gc_unmask_enable_reg; 140 + ct->chip.irq_mask = ingenic_tcu_gc_mask_disable_reg; 141 + ct->chip.irq_mask_ack = ingenic_tcu_gc_mask_disable_reg_and_ack; 142 + ct->chip.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE; 143 + 144 + /* Mask all IRQs by default */ 145 + regmap_write(tcu->map, TCU_REG_TMSR, IRQ_MSK(32)); 146 + 147 + /* 148 + * On JZ4740, timer 0 and timer 1 have their own interrupt line; 149 + * timers 2-7 share one interrupt. 150 + * On SoCs >= JZ4770, timer 5 has its own interrupt line; 151 + * timers 0-4 and 6-7 share one single interrupt. 152 + * 153 + * To keep things simple, we just register the same handler to 154 + * all parent interrupts. The handler will properly detect which 155 + * channel fired the interrupt. 156 + */ 157 + for (i = 0; i < irqs; i++) { 158 + tcu->parent_irqs[i] = irq_of_parse_and_map(np, i); 159 + if (!tcu->parent_irqs[i]) { 160 + ret = -EINVAL; 161 + goto out_unmap_irqs; 162 + } 163 + 164 + irq_set_chained_handler_and_data(tcu->parent_irqs[i], 165 + ingenic_tcu_intc_cascade, 166 + tcu->domain); 167 + } 168 + 169 + return 0; 170 + 171 + out_unmap_irqs: 172 + for (; i > 0; i--) 173 + irq_dispose_mapping(tcu->parent_irqs[i - 1]); 174 + out_domain_remove: 175 + irq_domain_remove(tcu->domain); 176 + err_free_tcu: 177 + kfree(tcu); 178 + return ret; 179 + } 180 + IRQCHIP_DECLARE(jz4740_tcu_irq, "ingenic,jz4740-tcu", ingenic_tcu_irq_init); 181 + IRQCHIP_DECLARE(jz4725b_tcu_irq, "ingenic,jz4725b-tcu", ingenic_tcu_irq_init); 182 + IRQCHIP_DECLARE(jz4770_tcu_irq, "ingenic,jz4770-tcu", ingenic_tcu_irq_init);
+30 -16
drivers/mfd/syscon.c
··· 40 40 .reg_stride = 4, 41 41 }; 42 42 43 - static struct syscon *of_syscon_register(struct device_node *np) 43 + static struct syscon *of_syscon_register(struct device_node *np, bool check_clk) 44 44 { 45 45 struct clk *clk; 46 46 struct syscon *syscon; ··· 50 50 int ret; 51 51 struct regmap_config syscon_config = syscon_regmap_config; 52 52 struct resource res; 53 - 54 - if (!of_device_is_compatible(np, "syscon")) 55 - return ERR_PTR(-EINVAL); 56 53 57 54 syscon = kzalloc(sizeof(*syscon), GFP_KERNEL); 58 55 if (!syscon) ··· 114 117 goto err_regmap; 115 118 } 116 119 117 - clk = of_clk_get(np, 0); 118 - if (IS_ERR(clk)) { 119 - ret = PTR_ERR(clk); 120 - /* clock is optional */ 121 - if (ret != -ENOENT) 122 - goto err_clk; 123 - } else { 124 - ret = regmap_mmio_attach_clk(regmap, clk); 125 - if (ret) 126 - goto err_attach; 120 + if (check_clk) { 121 + clk = of_clk_get(np, 0); 122 + if (IS_ERR(clk)) { 123 + ret = PTR_ERR(clk); 124 + /* clock is optional */ 125 + if (ret != -ENOENT) 126 + goto err_clk; 127 + } else { 128 + ret = regmap_mmio_attach_clk(regmap, clk); 129 + if (ret) 130 + goto err_attach; 131 + } 127 132 } 128 133 129 134 syscon->regmap = regmap; ··· 149 150 return ERR_PTR(ret); 150 151 } 151 152 152 - struct regmap *syscon_node_to_regmap(struct device_node *np) 153 + static struct regmap *device_node_get_regmap(struct device_node *np, 154 + bool check_clk) 153 155 { 154 156 struct syscon *entry, *syscon = NULL; 155 157 ··· 165 165 spin_unlock(&syscon_list_slock); 166 166 167 167 if (!syscon) 168 - syscon = of_syscon_register(np); 168 + syscon = of_syscon_register(np, check_clk); 169 169 170 170 if (IS_ERR(syscon)) 171 171 return ERR_CAST(syscon); 172 172 173 173 return syscon->regmap; 174 + } 175 + 176 + struct regmap *device_node_to_regmap(struct device_node *np) 177 + { 178 + return device_node_get_regmap(np, false); 179 + } 180 + EXPORT_SYMBOL_GPL(device_node_to_regmap); 181 + 182 + struct regmap *syscon_node_to_regmap(struct device_node *np) 183 + { 184 + if (!of_device_is_compatible(np, "syscon")) 185 + return ERR_PTR(-EINVAL); 186 + 187 + return device_node_get_regmap(np, true); 174 188 } 175 189 EXPORT_SYMBOL_GPL(syscon_node_to_regmap); 176 190
-7
drivers/mtd/nand/raw/ingenic/Kconfig
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 - config MTD_NAND_JZ4740 3 - tristate "JZ4740 NAND controller" 4 - depends on MACH_JZ4740 || COMPILE_TEST 5 - depends on HAS_IOMEM 6 - help 7 - Enables support for NAND Flash on JZ4740 SoC based boards. 8 - 9 2 config MTD_NAND_JZ4780 10 3 tristate "JZ4780 NAND controller" 11 4 depends on JZ4780_NEMC
-1
drivers/mtd/nand/raw/ingenic/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 - obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o 3 2 obj-$(CONFIG_MTD_NAND_JZ4780) += ingenic_nand.o 4 3 5 4 ingenic_nand-y += ingenic_nand_drv.o
-536
drivers/mtd/nand/raw/ingenic/jz4740_nand.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-or-later 2 - /* 3 - * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> 4 - * JZ4740 SoC NAND controller driver 5 - */ 6 - 7 - #include <linux/io.h> 8 - #include <linux/ioport.h> 9 - #include <linux/kernel.h> 10 - #include <linux/module.h> 11 - #include <linux/platform_device.h> 12 - #include <linux/slab.h> 13 - 14 - #include <linux/mtd/mtd.h> 15 - #include <linux/mtd/rawnand.h> 16 - #include <linux/mtd/partitions.h> 17 - 18 - #include <linux/gpio/consumer.h> 19 - 20 - #include <linux/platform_data/jz4740/jz4740_nand.h> 21 - 22 - #define JZ_REG_NAND_CTRL 0x50 23 - #define JZ_REG_NAND_ECC_CTRL 0x100 24 - #define JZ_REG_NAND_DATA 0x104 25 - #define JZ_REG_NAND_PAR0 0x108 26 - #define JZ_REG_NAND_PAR1 0x10C 27 - #define JZ_REG_NAND_PAR2 0x110 28 - #define JZ_REG_NAND_IRQ_STAT 0x114 29 - #define JZ_REG_NAND_IRQ_CTRL 0x118 30 - #define JZ_REG_NAND_ERR(x) (0x11C + ((x) << 2)) 31 - 32 - #define JZ_NAND_ECC_CTRL_PAR_READY BIT(4) 33 - #define JZ_NAND_ECC_CTRL_ENCODING BIT(3) 34 - #define JZ_NAND_ECC_CTRL_RS BIT(2) 35 - #define JZ_NAND_ECC_CTRL_RESET BIT(1) 36 - #define JZ_NAND_ECC_CTRL_ENABLE BIT(0) 37 - 38 - #define JZ_NAND_STATUS_ERR_COUNT (BIT(31) | BIT(30) | BIT(29)) 39 - #define JZ_NAND_STATUS_PAD_FINISH BIT(4) 40 - #define JZ_NAND_STATUS_DEC_FINISH BIT(3) 41 - #define JZ_NAND_STATUS_ENC_FINISH BIT(2) 42 - #define JZ_NAND_STATUS_UNCOR_ERROR BIT(1) 43 - #define JZ_NAND_STATUS_ERROR BIT(0) 44 - 45 - #define JZ_NAND_CTRL_ENABLE_CHIP(x) BIT((x) << 1) 46 - #define JZ_NAND_CTRL_ASSERT_CHIP(x) BIT(((x) << 1) + 1) 47 - #define JZ_NAND_CTRL_ASSERT_CHIP_MASK 0xaa 48 - 49 - #define JZ_NAND_MEM_CMD_OFFSET 0x08000 50 - #define JZ_NAND_MEM_ADDR_OFFSET 0x10000 51 - 52 - struct jz_nand { 53 - struct nand_chip chip; 54 - void __iomem *base; 55 - struct resource *mem; 56 - 57 - unsigned char banks[JZ_NAND_NUM_BANKS]; 58 - void __iomem *bank_base[JZ_NAND_NUM_BANKS]; 59 - struct resource *bank_mem[JZ_NAND_NUM_BANKS]; 60 - 61 - int selected_bank; 62 - 63 - struct gpio_desc *busy_gpio; 64 - bool is_reading; 65 - }; 66 - 67 - static inline struct jz_nand *mtd_to_jz_nand(struct mtd_info *mtd) 68 - { 69 - return container_of(mtd_to_nand(mtd), struct jz_nand, chip); 70 - } 71 - 72 - static void jz_nand_select_chip(struct nand_chip *chip, int chipnr) 73 - { 74 - struct jz_nand *nand = mtd_to_jz_nand(nand_to_mtd(chip)); 75 - uint32_t ctrl; 76 - int banknr; 77 - 78 - ctrl = readl(nand->base + JZ_REG_NAND_CTRL); 79 - ctrl &= ~JZ_NAND_CTRL_ASSERT_CHIP_MASK; 80 - 81 - if (chipnr == -1) { 82 - banknr = -1; 83 - } else { 84 - banknr = nand->banks[chipnr] - 1; 85 - chip->legacy.IO_ADDR_R = nand->bank_base[banknr]; 86 - chip->legacy.IO_ADDR_W = nand->bank_base[banknr]; 87 - } 88 - writel(ctrl, nand->base + JZ_REG_NAND_CTRL); 89 - 90 - nand->selected_bank = banknr; 91 - } 92 - 93 - static void jz_nand_cmd_ctrl(struct nand_chip *chip, int dat, 94 - unsigned int ctrl) 95 - { 96 - struct jz_nand *nand = mtd_to_jz_nand(nand_to_mtd(chip)); 97 - uint32_t reg; 98 - void __iomem *bank_base = nand->bank_base[nand->selected_bank]; 99 - 100 - BUG_ON(nand->selected_bank < 0); 101 - 102 - if (ctrl & NAND_CTRL_CHANGE) { 103 - BUG_ON((ctrl & NAND_ALE) && (ctrl & NAND_CLE)); 104 - if (ctrl & NAND_ALE) 105 - bank_base += JZ_NAND_MEM_ADDR_OFFSET; 106 - else if (ctrl & NAND_CLE) 107 - bank_base += JZ_NAND_MEM_CMD_OFFSET; 108 - chip->legacy.IO_ADDR_W = bank_base; 109 - 110 - reg = readl(nand->base + JZ_REG_NAND_CTRL); 111 - if (ctrl & NAND_NCE) 112 - reg |= JZ_NAND_CTRL_ASSERT_CHIP(nand->selected_bank); 113 - else 114 - reg &= ~JZ_NAND_CTRL_ASSERT_CHIP(nand->selected_bank); 115 - writel(reg, nand->base + JZ_REG_NAND_CTRL); 116 - } 117 - if (dat != NAND_CMD_NONE) 118 - writeb(dat, chip->legacy.IO_ADDR_W); 119 - } 120 - 121 - static int jz_nand_dev_ready(struct nand_chip *chip) 122 - { 123 - struct jz_nand *nand = mtd_to_jz_nand(nand_to_mtd(chip)); 124 - return gpiod_get_value_cansleep(nand->busy_gpio); 125 - } 126 - 127 - static void jz_nand_hwctl(struct nand_chip *chip, int mode) 128 - { 129 - struct jz_nand *nand = mtd_to_jz_nand(nand_to_mtd(chip)); 130 - uint32_t reg; 131 - 132 - writel(0, nand->base + JZ_REG_NAND_IRQ_STAT); 133 - reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL); 134 - 135 - reg |= JZ_NAND_ECC_CTRL_RESET; 136 - reg |= JZ_NAND_ECC_CTRL_ENABLE; 137 - reg |= JZ_NAND_ECC_CTRL_RS; 138 - 139 - switch (mode) { 140 - case NAND_ECC_READ: 141 - reg &= ~JZ_NAND_ECC_CTRL_ENCODING; 142 - nand->is_reading = true; 143 - break; 144 - case NAND_ECC_WRITE: 145 - reg |= JZ_NAND_ECC_CTRL_ENCODING; 146 - nand->is_reading = false; 147 - break; 148 - default: 149 - break; 150 - } 151 - 152 - writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL); 153 - } 154 - 155 - static int jz_nand_calculate_ecc_rs(struct nand_chip *chip, const uint8_t *dat, 156 - uint8_t *ecc_code) 157 - { 158 - struct jz_nand *nand = mtd_to_jz_nand(nand_to_mtd(chip)); 159 - uint32_t reg, status; 160 - int i; 161 - unsigned int timeout = 1000; 162 - static uint8_t empty_block_ecc[] = {0xcd, 0x9d, 0x90, 0x58, 0xf4, 163 - 0x8b, 0xff, 0xb7, 0x6f}; 164 - 165 - if (nand->is_reading) 166 - return 0; 167 - 168 - do { 169 - status = readl(nand->base + JZ_REG_NAND_IRQ_STAT); 170 - } while (!(status & JZ_NAND_STATUS_ENC_FINISH) && --timeout); 171 - 172 - if (timeout == 0) 173 - return -1; 174 - 175 - reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL); 176 - reg &= ~JZ_NAND_ECC_CTRL_ENABLE; 177 - writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL); 178 - 179 - for (i = 0; i < 9; ++i) 180 - ecc_code[i] = readb(nand->base + JZ_REG_NAND_PAR0 + i); 181 - 182 - /* If the written data is completly 0xff, we also want to write 0xff as 183 - * ecc, otherwise we will get in trouble when doing subpage writes. */ 184 - if (memcmp(ecc_code, empty_block_ecc, 9) == 0) 185 - memset(ecc_code, 0xff, 9); 186 - 187 - return 0; 188 - } 189 - 190 - static void jz_nand_correct_data(uint8_t *dat, int index, int mask) 191 - { 192 - int offset = index & 0x7; 193 - uint16_t data; 194 - 195 - index += (index >> 3); 196 - 197 - data = dat[index]; 198 - data |= dat[index+1] << 8; 199 - 200 - mask ^= (data >> offset) & 0x1ff; 201 - data &= ~(0x1ff << offset); 202 - data |= (mask << offset); 203 - 204 - dat[index] = data & 0xff; 205 - dat[index+1] = (data >> 8) & 0xff; 206 - } 207 - 208 - static int jz_nand_correct_ecc_rs(struct nand_chip *chip, uint8_t *dat, 209 - uint8_t *read_ecc, uint8_t *calc_ecc) 210 - { 211 - struct jz_nand *nand = mtd_to_jz_nand(nand_to_mtd(chip)); 212 - int i, error_count, index; 213 - uint32_t reg, status, error; 214 - unsigned int timeout = 1000; 215 - 216 - for (i = 0; i < 9; ++i) 217 - writeb(read_ecc[i], nand->base + JZ_REG_NAND_PAR0 + i); 218 - 219 - reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL); 220 - reg |= JZ_NAND_ECC_CTRL_PAR_READY; 221 - writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL); 222 - 223 - do { 224 - status = readl(nand->base + JZ_REG_NAND_IRQ_STAT); 225 - } while (!(status & JZ_NAND_STATUS_DEC_FINISH) && --timeout); 226 - 227 - if (timeout == 0) 228 - return -ETIMEDOUT; 229 - 230 - reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL); 231 - reg &= ~JZ_NAND_ECC_CTRL_ENABLE; 232 - writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL); 233 - 234 - if (status & JZ_NAND_STATUS_ERROR) { 235 - if (status & JZ_NAND_STATUS_UNCOR_ERROR) 236 - return -EBADMSG; 237 - 238 - error_count = (status & JZ_NAND_STATUS_ERR_COUNT) >> 29; 239 - 240 - for (i = 0; i < error_count; ++i) { 241 - error = readl(nand->base + JZ_REG_NAND_ERR(i)); 242 - index = ((error >> 16) & 0x1ff) - 1; 243 - if (index >= 0 && index < 512) 244 - jz_nand_correct_data(dat, index, error & 0x1ff); 245 - } 246 - 247 - return error_count; 248 - } 249 - 250 - return 0; 251 - } 252 - 253 - static int jz_nand_ioremap_resource(struct platform_device *pdev, 254 - const char *name, struct resource **res, void __iomem **base) 255 - { 256 - int ret; 257 - 258 - *res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); 259 - if (!*res) { 260 - dev_err(&pdev->dev, "Failed to get platform %s memory\n", name); 261 - ret = -ENXIO; 262 - goto err; 263 - } 264 - 265 - *res = request_mem_region((*res)->start, resource_size(*res), 266 - pdev->name); 267 - if (!*res) { 268 - dev_err(&pdev->dev, "Failed to request %s memory region\n", name); 269 - ret = -EBUSY; 270 - goto err; 271 - } 272 - 273 - *base = ioremap((*res)->start, resource_size(*res)); 274 - if (!*base) { 275 - dev_err(&pdev->dev, "Failed to ioremap %s memory region\n", name); 276 - ret = -EBUSY; 277 - goto err_release_mem; 278 - } 279 - 280 - return 0; 281 - 282 - err_release_mem: 283 - release_mem_region((*res)->start, resource_size(*res)); 284 - err: 285 - *res = NULL; 286 - *base = NULL; 287 - return ret; 288 - } 289 - 290 - static inline void jz_nand_iounmap_resource(struct resource *res, 291 - void __iomem *base) 292 - { 293 - iounmap(base); 294 - release_mem_region(res->start, resource_size(res)); 295 - } 296 - 297 - static int jz_nand_detect_bank(struct platform_device *pdev, 298 - struct jz_nand *nand, unsigned char bank, 299 - size_t chipnr, uint8_t *nand_maf_id, 300 - uint8_t *nand_dev_id) 301 - { 302 - int ret; 303 - char res_name[6]; 304 - uint32_t ctrl; 305 - struct nand_chip *chip = &nand->chip; 306 - struct mtd_info *mtd = nand_to_mtd(chip); 307 - struct nand_memory_organization *memorg; 308 - u8 id[2]; 309 - 310 - memorg = nanddev_get_memorg(&chip->base); 311 - 312 - /* Request I/O resource. */ 313 - sprintf(res_name, "bank%d", bank); 314 - ret = jz_nand_ioremap_resource(pdev, res_name, 315 - &nand->bank_mem[bank - 1], 316 - &nand->bank_base[bank - 1]); 317 - if (ret) 318 - return ret; 319 - 320 - /* Enable chip in bank. */ 321 - ctrl = readl(nand->base + JZ_REG_NAND_CTRL); 322 - ctrl |= JZ_NAND_CTRL_ENABLE_CHIP(bank - 1); 323 - writel(ctrl, nand->base + JZ_REG_NAND_CTRL); 324 - 325 - if (chipnr == 0) { 326 - /* Detect first chip. */ 327 - ret = nand_scan(chip, 1); 328 - if (ret) 329 - goto notfound_id; 330 - 331 - /* Retrieve the IDs from the first chip. */ 332 - nand_select_target(chip, 0); 333 - nand_reset_op(chip); 334 - nand_readid_op(chip, 0, id, sizeof(id)); 335 - *nand_maf_id = id[0]; 336 - *nand_dev_id = id[1]; 337 - } else { 338 - /* Detect additional chip. */ 339 - nand_select_target(chip, chipnr); 340 - nand_reset_op(chip); 341 - nand_readid_op(chip, 0, id, sizeof(id)); 342 - if (*nand_maf_id != id[0] || *nand_dev_id != id[1]) { 343 - ret = -ENODEV; 344 - goto notfound_id; 345 - } 346 - 347 - /* Update size of the MTD. */ 348 - memorg->ntargets++; 349 - mtd->size += nanddev_target_size(&chip->base); 350 - } 351 - 352 - dev_info(&pdev->dev, "Found chip %zu on bank %i\n", chipnr, bank); 353 - return 0; 354 - 355 - notfound_id: 356 - dev_info(&pdev->dev, "No chip found on bank %i\n", bank); 357 - ctrl &= ~(JZ_NAND_CTRL_ENABLE_CHIP(bank - 1)); 358 - writel(ctrl, nand->base + JZ_REG_NAND_CTRL); 359 - jz_nand_iounmap_resource(nand->bank_mem[bank - 1], 360 - nand->bank_base[bank - 1]); 361 - return ret; 362 - } 363 - 364 - static int jz_nand_attach_chip(struct nand_chip *chip) 365 - { 366 - struct mtd_info *mtd = nand_to_mtd(chip); 367 - struct device *dev = mtd->dev.parent; 368 - struct jz_nand_platform_data *pdata = dev_get_platdata(dev); 369 - struct platform_device *pdev = to_platform_device(dev); 370 - 371 - if (pdata && pdata->ident_callback) 372 - pdata->ident_callback(pdev, mtd, &pdata->partitions, 373 - &pdata->num_partitions); 374 - 375 - return 0; 376 - } 377 - 378 - static const struct nand_controller_ops jz_nand_controller_ops = { 379 - .attach_chip = jz_nand_attach_chip, 380 - }; 381 - 382 - static int jz_nand_probe(struct platform_device *pdev) 383 - { 384 - int ret; 385 - struct jz_nand *nand; 386 - struct nand_chip *chip; 387 - struct mtd_info *mtd; 388 - struct jz_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); 389 - size_t chipnr, bank_idx; 390 - uint8_t nand_maf_id = 0, nand_dev_id = 0; 391 - 392 - nand = kzalloc(sizeof(*nand), GFP_KERNEL); 393 - if (!nand) 394 - return -ENOMEM; 395 - 396 - ret = jz_nand_ioremap_resource(pdev, "mmio", &nand->mem, &nand->base); 397 - if (ret) 398 - goto err_free; 399 - 400 - nand->busy_gpio = devm_gpiod_get_optional(&pdev->dev, "busy", GPIOD_IN); 401 - if (IS_ERR(nand->busy_gpio)) { 402 - ret = PTR_ERR(nand->busy_gpio); 403 - dev_err(&pdev->dev, "Failed to request busy gpio %d\n", 404 - ret); 405 - goto err_iounmap_mmio; 406 - } 407 - 408 - chip = &nand->chip; 409 - mtd = nand_to_mtd(chip); 410 - mtd->dev.parent = &pdev->dev; 411 - mtd->name = "jz4740-nand"; 412 - 413 - chip->ecc.hwctl = jz_nand_hwctl; 414 - chip->ecc.calculate = jz_nand_calculate_ecc_rs; 415 - chip->ecc.correct = jz_nand_correct_ecc_rs; 416 - chip->ecc.mode = NAND_ECC_HW_OOB_FIRST; 417 - chip->ecc.size = 512; 418 - chip->ecc.bytes = 9; 419 - chip->ecc.strength = 4; 420 - chip->ecc.options = NAND_ECC_GENERIC_ERASED_CHECK; 421 - 422 - chip->legacy.chip_delay = 50; 423 - chip->legacy.cmd_ctrl = jz_nand_cmd_ctrl; 424 - chip->legacy.select_chip = jz_nand_select_chip; 425 - chip->legacy.dummy_controller.ops = &jz_nand_controller_ops; 426 - 427 - if (nand->busy_gpio) 428 - chip->legacy.dev_ready = jz_nand_dev_ready; 429 - 430 - platform_set_drvdata(pdev, nand); 431 - 432 - /* We are going to autodetect NAND chips in the banks specified in the 433 - * platform data. Although nand_scan_ident() can detect multiple chips, 434 - * it requires those chips to be numbered consecuitively, which is not 435 - * always the case for external memory banks. And a fixed chip-to-bank 436 - * mapping is not practical either, since for example Dingoo units 437 - * produced at different times have NAND chips in different banks. 438 - */ 439 - chipnr = 0; 440 - for (bank_idx = 0; bank_idx < JZ_NAND_NUM_BANKS; bank_idx++) { 441 - unsigned char bank; 442 - 443 - /* If there is no platform data, look for NAND in bank 1, 444 - * which is the most likely bank since it is the only one 445 - * that can be booted from. 446 - */ 447 - bank = pdata ? pdata->banks[bank_idx] : bank_idx ^ 1; 448 - if (bank == 0) 449 - break; 450 - if (bank > JZ_NAND_NUM_BANKS) { 451 - dev_warn(&pdev->dev, 452 - "Skipping non-existing bank: %d\n", bank); 453 - continue; 454 - } 455 - /* The detection routine will directly or indirectly call 456 - * jz_nand_select_chip(), so nand->banks has to contain the 457 - * bank we're checking. 458 - */ 459 - nand->banks[chipnr] = bank; 460 - if (jz_nand_detect_bank(pdev, nand, bank, chipnr, 461 - &nand_maf_id, &nand_dev_id) == 0) 462 - chipnr++; 463 - else 464 - nand->banks[chipnr] = 0; 465 - } 466 - if (chipnr == 0) { 467 - dev_err(&pdev->dev, "No NAND chips found\n"); 468 - goto err_iounmap_mmio; 469 - } 470 - 471 - ret = mtd_device_register(mtd, pdata ? pdata->partitions : NULL, 472 - pdata ? pdata->num_partitions : 0); 473 - 474 - if (ret) { 475 - dev_err(&pdev->dev, "Failed to add mtd device\n"); 476 - goto err_cleanup_nand; 477 - } 478 - 479 - dev_info(&pdev->dev, "Successfully registered JZ4740 NAND driver\n"); 480 - 481 - return 0; 482 - 483 - err_cleanup_nand: 484 - nand_cleanup(chip); 485 - while (chipnr--) { 486 - unsigned char bank = nand->banks[chipnr]; 487 - jz_nand_iounmap_resource(nand->bank_mem[bank - 1], 488 - nand->bank_base[bank - 1]); 489 - } 490 - writel(0, nand->base + JZ_REG_NAND_CTRL); 491 - err_iounmap_mmio: 492 - jz_nand_iounmap_resource(nand->mem, nand->base); 493 - err_free: 494 - kfree(nand); 495 - return ret; 496 - } 497 - 498 - static int jz_nand_remove(struct platform_device *pdev) 499 - { 500 - struct jz_nand *nand = platform_get_drvdata(pdev); 501 - size_t i; 502 - 503 - nand_release(&nand->chip); 504 - 505 - /* Deassert and disable all chips */ 506 - writel(0, nand->base + JZ_REG_NAND_CTRL); 507 - 508 - for (i = 0; i < JZ_NAND_NUM_BANKS; ++i) { 509 - unsigned char bank = nand->banks[i]; 510 - if (bank != 0) { 511 - jz_nand_iounmap_resource(nand->bank_mem[bank - 1], 512 - nand->bank_base[bank - 1]); 513 - } 514 - } 515 - 516 - jz_nand_iounmap_resource(nand->mem, nand->base); 517 - 518 - kfree(nand); 519 - 520 - return 0; 521 - } 522 - 523 - static struct platform_driver jz_nand_driver = { 524 - .probe = jz_nand_probe, 525 - .remove = jz_nand_remove, 526 - .driver = { 527 - .name = "jz4740-nand", 528 - }, 529 - }; 530 - 531 - module_platform_driver(jz_nand_driver); 532 - 533 - MODULE_LICENSE("GPL"); 534 - MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 535 - MODULE_DESCRIPTION("NAND controller driver for JZ4740 SoC"); 536 - MODULE_ALIAS("platform:jz4740-nand");
-11
drivers/power/supply/Kconfig
··· 417 417 help 418 418 Say Y to include support for NXP PCF50633 Main Battery Charger. 419 419 420 - config BATTERY_JZ4740 421 - tristate "Ingenic JZ4740 battery" 422 - depends on MACH_JZ4740 423 - depends on MFD_JZ4740_ADC 424 - help 425 - Say Y to enable support for the battery on Ingenic JZ4740 based 426 - boards. 427 - 428 - This driver can be build as a module. If so, the module will be 429 - called jz4740-battery. 430 - 431 420 config BATTERY_RX51 432 421 tristate "Nokia RX-51 (N900) battery driver" 433 422 depends on TWL4030_MADC
-1
drivers/power/supply/Makefile
··· 58 58 obj-$(CONFIG_BATTERY_TWL4030_MADC) += twl4030_madc_battery.o 59 59 obj-$(CONFIG_CHARGER_88PM860X) += 88pm860x_charger.o 60 60 obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o 61 - obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o 62 61 obj-$(CONFIG_BATTERY_RX51) += rx51_battery.o 63 62 obj-$(CONFIG_AB8500_BM) += ab8500_bmdata.o ab8500_charger.o ab8500_fg.o ab8500_btemp.o abx500_chargalg.o pm2301_charger.o 64 63 obj-$(CONFIG_CHARGER_CPCAP) += cpcap-charger.o
-421
drivers/power/supply/jz4740-battery.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Battery measurement code for Ingenic JZ SOC. 4 - * 5 - * Copyright (C) 2009 Jiejing Zhang <kzjeef@gmail.com> 6 - * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de> 7 - * 8 - * based on tosa_battery.c 9 - * 10 - * Copyright (C) 2008 Marek Vasut <marek.vasut@gmail.com> 11 - */ 12 - 13 - #include <linux/interrupt.h> 14 - #include <linux/kernel.h> 15 - #include <linux/module.h> 16 - #include <linux/platform_device.h> 17 - #include <linux/slab.h> 18 - #include <linux/io.h> 19 - 20 - #include <linux/delay.h> 21 - #include <linux/err.h> 22 - #include <linux/gpio.h> 23 - #include <linux/mfd/core.h> 24 - #include <linux/power_supply.h> 25 - 26 - #include <linux/power/jz4740-battery.h> 27 - #include <linux/jz4740-adc.h> 28 - 29 - struct jz_battery { 30 - struct jz_battery_platform_data *pdata; 31 - struct platform_device *pdev; 32 - 33 - void __iomem *base; 34 - 35 - int irq; 36 - int charge_irq; 37 - 38 - const struct mfd_cell *cell; 39 - 40 - int status; 41 - long voltage; 42 - 43 - struct completion read_completion; 44 - 45 - struct power_supply *battery; 46 - struct power_supply_desc battery_desc; 47 - struct delayed_work work; 48 - 49 - struct mutex lock; 50 - }; 51 - 52 - static inline struct jz_battery *psy_to_jz_battery(struct power_supply *psy) 53 - { 54 - return power_supply_get_drvdata(psy); 55 - } 56 - 57 - static irqreturn_t jz_battery_irq_handler(int irq, void *devid) 58 - { 59 - struct jz_battery *battery = devid; 60 - 61 - complete(&battery->read_completion); 62 - return IRQ_HANDLED; 63 - } 64 - 65 - static long jz_battery_read_voltage(struct jz_battery *battery) 66 - { 67 - long t; 68 - unsigned long val; 69 - long voltage; 70 - 71 - mutex_lock(&battery->lock); 72 - 73 - reinit_completion(&battery->read_completion); 74 - 75 - enable_irq(battery->irq); 76 - battery->cell->enable(battery->pdev); 77 - 78 - t = wait_for_completion_interruptible_timeout(&battery->read_completion, 79 - HZ); 80 - 81 - if (t > 0) { 82 - val = readw(battery->base) & 0xfff; 83 - 84 - if (battery->pdata->info.voltage_max_design <= 2500000) 85 - val = (val * 78125UL) >> 7UL; 86 - else 87 - val = ((val * 924375UL) >> 9UL) + 33000; 88 - voltage = (long)val; 89 - } else { 90 - voltage = t ? t : -ETIMEDOUT; 91 - } 92 - 93 - battery->cell->disable(battery->pdev); 94 - disable_irq(battery->irq); 95 - 96 - mutex_unlock(&battery->lock); 97 - 98 - return voltage; 99 - } 100 - 101 - static int jz_battery_get_capacity(struct power_supply *psy) 102 - { 103 - struct jz_battery *jz_battery = psy_to_jz_battery(psy); 104 - struct power_supply_info *info = &jz_battery->pdata->info; 105 - long voltage; 106 - int ret; 107 - int voltage_span; 108 - 109 - voltage = jz_battery_read_voltage(jz_battery); 110 - 111 - if (voltage < 0) 112 - return voltage; 113 - 114 - voltage_span = info->voltage_max_design - info->voltage_min_design; 115 - ret = ((voltage - info->voltage_min_design) * 100) / voltage_span; 116 - 117 - if (ret > 100) 118 - ret = 100; 119 - else if (ret < 0) 120 - ret = 0; 121 - 122 - return ret; 123 - } 124 - 125 - static int jz_battery_get_property(struct power_supply *psy, 126 - enum power_supply_property psp, union power_supply_propval *val) 127 - { 128 - struct jz_battery *jz_battery = psy_to_jz_battery(psy); 129 - struct power_supply_info *info = &jz_battery->pdata->info; 130 - long voltage; 131 - 132 - switch (psp) { 133 - case POWER_SUPPLY_PROP_STATUS: 134 - val->intval = jz_battery->status; 135 - break; 136 - case POWER_SUPPLY_PROP_TECHNOLOGY: 137 - val->intval = jz_battery->pdata->info.technology; 138 - break; 139 - case POWER_SUPPLY_PROP_HEALTH: 140 - voltage = jz_battery_read_voltage(jz_battery); 141 - if (voltage < info->voltage_min_design) 142 - val->intval = POWER_SUPPLY_HEALTH_DEAD; 143 - else 144 - val->intval = POWER_SUPPLY_HEALTH_GOOD; 145 - break; 146 - case POWER_SUPPLY_PROP_CAPACITY: 147 - val->intval = jz_battery_get_capacity(psy); 148 - break; 149 - case POWER_SUPPLY_PROP_VOLTAGE_NOW: 150 - val->intval = jz_battery_read_voltage(jz_battery); 151 - if (val->intval < 0) 152 - return val->intval; 153 - break; 154 - case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 155 - val->intval = info->voltage_max_design; 156 - break; 157 - case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 158 - val->intval = info->voltage_min_design; 159 - break; 160 - case POWER_SUPPLY_PROP_PRESENT: 161 - val->intval = 1; 162 - break; 163 - default: 164 - return -EINVAL; 165 - } 166 - return 0; 167 - } 168 - 169 - static void jz_battery_external_power_changed(struct power_supply *psy) 170 - { 171 - struct jz_battery *jz_battery = psy_to_jz_battery(psy); 172 - 173 - mod_delayed_work(system_wq, &jz_battery->work, 0); 174 - } 175 - 176 - static irqreturn_t jz_battery_charge_irq(int irq, void *data) 177 - { 178 - struct jz_battery *jz_battery = data; 179 - 180 - mod_delayed_work(system_wq, &jz_battery->work, 0); 181 - 182 - return IRQ_HANDLED; 183 - } 184 - 185 - static void jz_battery_update(struct jz_battery *jz_battery) 186 - { 187 - int status; 188 - long voltage; 189 - bool has_changed = false; 190 - int is_charging; 191 - 192 - if (gpio_is_valid(jz_battery->pdata->gpio_charge)) { 193 - is_charging = gpio_get_value(jz_battery->pdata->gpio_charge); 194 - is_charging ^= jz_battery->pdata->gpio_charge_active_low; 195 - if (is_charging) 196 - status = POWER_SUPPLY_STATUS_CHARGING; 197 - else 198 - status = POWER_SUPPLY_STATUS_NOT_CHARGING; 199 - 200 - if (status != jz_battery->status) { 201 - jz_battery->status = status; 202 - has_changed = true; 203 - } 204 - } 205 - 206 - voltage = jz_battery_read_voltage(jz_battery); 207 - if (voltage >= 0 && abs(voltage - jz_battery->voltage) > 50000) { 208 - jz_battery->voltage = voltage; 209 - has_changed = true; 210 - } 211 - 212 - if (has_changed) 213 - power_supply_changed(jz_battery->battery); 214 - } 215 - 216 - static enum power_supply_property jz_battery_properties[] = { 217 - POWER_SUPPLY_PROP_STATUS, 218 - POWER_SUPPLY_PROP_TECHNOLOGY, 219 - POWER_SUPPLY_PROP_HEALTH, 220 - POWER_SUPPLY_PROP_CAPACITY, 221 - POWER_SUPPLY_PROP_VOLTAGE_NOW, 222 - POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 223 - POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 224 - POWER_SUPPLY_PROP_PRESENT, 225 - }; 226 - 227 - static void jz_battery_work(struct work_struct *work) 228 - { 229 - /* Too small interval will increase system workload */ 230 - const int interval = HZ * 30; 231 - struct jz_battery *jz_battery = container_of(work, struct jz_battery, 232 - work.work); 233 - 234 - jz_battery_update(jz_battery); 235 - schedule_delayed_work(&jz_battery->work, interval); 236 - } 237 - 238 - static int jz_battery_probe(struct platform_device *pdev) 239 - { 240 - int ret = 0; 241 - struct jz_battery_platform_data *pdata = pdev->dev.parent->platform_data; 242 - struct power_supply_config psy_cfg = {}; 243 - struct jz_battery *jz_battery; 244 - struct power_supply_desc *battery_desc; 245 - struct resource *mem; 246 - 247 - if (!pdata) { 248 - dev_err(&pdev->dev, "No platform_data supplied\n"); 249 - return -ENXIO; 250 - } 251 - 252 - jz_battery = devm_kzalloc(&pdev->dev, sizeof(*jz_battery), GFP_KERNEL); 253 - if (!jz_battery) { 254 - dev_err(&pdev->dev, "Failed to allocate driver structure\n"); 255 - return -ENOMEM; 256 - } 257 - 258 - jz_battery->cell = mfd_get_cell(pdev); 259 - 260 - jz_battery->irq = platform_get_irq(pdev, 0); 261 - if (jz_battery->irq < 0) { 262 - dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret); 263 - return jz_battery->irq; 264 - } 265 - 266 - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 267 - 268 - jz_battery->base = devm_ioremap_resource(&pdev->dev, mem); 269 - if (IS_ERR(jz_battery->base)) 270 - return PTR_ERR(jz_battery->base); 271 - 272 - battery_desc = &jz_battery->battery_desc; 273 - battery_desc->name = pdata->info.name; 274 - battery_desc->type = POWER_SUPPLY_TYPE_BATTERY; 275 - battery_desc->properties = jz_battery_properties; 276 - battery_desc->num_properties = ARRAY_SIZE(jz_battery_properties); 277 - battery_desc->get_property = jz_battery_get_property; 278 - battery_desc->external_power_changed = 279 - jz_battery_external_power_changed; 280 - battery_desc->use_for_apm = 1; 281 - 282 - psy_cfg.drv_data = jz_battery; 283 - 284 - jz_battery->pdata = pdata; 285 - jz_battery->pdev = pdev; 286 - 287 - init_completion(&jz_battery->read_completion); 288 - mutex_init(&jz_battery->lock); 289 - 290 - INIT_DELAYED_WORK(&jz_battery->work, jz_battery_work); 291 - 292 - ret = request_irq(jz_battery->irq, jz_battery_irq_handler, 0, pdev->name, 293 - jz_battery); 294 - if (ret) { 295 - dev_err(&pdev->dev, "Failed to request irq %d\n", ret); 296 - return ret; 297 - } 298 - disable_irq(jz_battery->irq); 299 - 300 - if (gpio_is_valid(pdata->gpio_charge)) { 301 - ret = gpio_request(pdata->gpio_charge, dev_name(&pdev->dev)); 302 - if (ret) { 303 - dev_err(&pdev->dev, "charger state gpio request failed.\n"); 304 - goto err_free_irq; 305 - } 306 - ret = gpio_direction_input(pdata->gpio_charge); 307 - if (ret) { 308 - dev_err(&pdev->dev, "charger state gpio set direction failed.\n"); 309 - goto err_free_gpio; 310 - } 311 - 312 - jz_battery->charge_irq = gpio_to_irq(pdata->gpio_charge); 313 - 314 - if (jz_battery->charge_irq >= 0) { 315 - ret = request_irq(jz_battery->charge_irq, 316 - jz_battery_charge_irq, 317 - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 318 - dev_name(&pdev->dev), jz_battery); 319 - if (ret) { 320 - dev_err(&pdev->dev, "Failed to request charge irq: %d\n", ret); 321 - goto err_free_gpio; 322 - } 323 - } 324 - } else { 325 - jz_battery->charge_irq = -1; 326 - } 327 - 328 - if (jz_battery->pdata->info.voltage_max_design <= 2500000) 329 - jz4740_adc_set_config(pdev->dev.parent, JZ_ADC_CONFIG_BAT_MB, 330 - JZ_ADC_CONFIG_BAT_MB); 331 - else 332 - jz4740_adc_set_config(pdev->dev.parent, JZ_ADC_CONFIG_BAT_MB, 0); 333 - 334 - jz_battery->battery = power_supply_register(&pdev->dev, battery_desc, 335 - &psy_cfg); 336 - if (IS_ERR(jz_battery->battery)) { 337 - dev_err(&pdev->dev, "power supply battery register failed.\n"); 338 - ret = PTR_ERR(jz_battery->battery); 339 - goto err_free_charge_irq; 340 - } 341 - 342 - platform_set_drvdata(pdev, jz_battery); 343 - schedule_delayed_work(&jz_battery->work, 0); 344 - 345 - return 0; 346 - 347 - err_free_charge_irq: 348 - if (jz_battery->charge_irq >= 0) 349 - free_irq(jz_battery->charge_irq, jz_battery); 350 - err_free_gpio: 351 - if (gpio_is_valid(pdata->gpio_charge)) 352 - gpio_free(jz_battery->pdata->gpio_charge); 353 - err_free_irq: 354 - free_irq(jz_battery->irq, jz_battery); 355 - return ret; 356 - } 357 - 358 - static int jz_battery_remove(struct platform_device *pdev) 359 - { 360 - struct jz_battery *jz_battery = platform_get_drvdata(pdev); 361 - 362 - cancel_delayed_work_sync(&jz_battery->work); 363 - 364 - if (gpio_is_valid(jz_battery->pdata->gpio_charge)) { 365 - if (jz_battery->charge_irq >= 0) 366 - free_irq(jz_battery->charge_irq, jz_battery); 367 - gpio_free(jz_battery->pdata->gpio_charge); 368 - } 369 - 370 - power_supply_unregister(jz_battery->battery); 371 - 372 - free_irq(jz_battery->irq, jz_battery); 373 - 374 - return 0; 375 - } 376 - 377 - #ifdef CONFIG_PM 378 - static int jz_battery_suspend(struct device *dev) 379 - { 380 - struct jz_battery *jz_battery = dev_get_drvdata(dev); 381 - 382 - cancel_delayed_work_sync(&jz_battery->work); 383 - jz_battery->status = POWER_SUPPLY_STATUS_UNKNOWN; 384 - 385 - return 0; 386 - } 387 - 388 - static int jz_battery_resume(struct device *dev) 389 - { 390 - struct jz_battery *jz_battery = dev_get_drvdata(dev); 391 - 392 - schedule_delayed_work(&jz_battery->work, 0); 393 - 394 - return 0; 395 - } 396 - 397 - static const struct dev_pm_ops jz_battery_pm_ops = { 398 - .suspend = jz_battery_suspend, 399 - .resume = jz_battery_resume, 400 - }; 401 - 402 - #define JZ_BATTERY_PM_OPS (&jz_battery_pm_ops) 403 - #else 404 - #define JZ_BATTERY_PM_OPS NULL 405 - #endif 406 - 407 - static struct platform_driver jz_battery_driver = { 408 - .probe = jz_battery_probe, 409 - .remove = jz_battery_remove, 410 - .driver = { 411 - .name = "jz4740-battery", 412 - .pm = JZ_BATTERY_PM_OPS, 413 - }, 414 - }; 415 - 416 - module_platform_driver(jz_battery_driver); 417 - 418 - MODULE_ALIAS("platform:jz4740-battery"); 419 - MODULE_LICENSE("GPL"); 420 - MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 421 - MODULE_DESCRIPTION("JZ4740 SoC battery driver");
-9
drivers/video/fbdev/Kconfig
··· 2197 2197 and could also have been called by other names when coupled with 2198 2198 a bridge adapter. 2199 2199 2200 - config FB_JZ4740 2201 - tristate "JZ4740 LCD framebuffer support" 2202 - depends on FB && MACH_JZ4740 2203 - select FB_SYS_FILLRECT 2204 - select FB_SYS_COPYAREA 2205 - select FB_SYS_IMAGEBLIT 2206 - help 2207 - Framebuffer support for the JZ4740 SoC. 2208 - 2209 2200 config FB_PUV3_UNIGFX 2210 2201 tristate "PKUnity v3 Unigfx framebuffer support" 2211 2202 depends on FB && UNICORE32 && ARCH_PUV3
-1
drivers/video/fbdev/Makefile
··· 116 116 obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o 117 117 obj-$(CONFIG_FB_CARMINE) += carminefb.o 118 118 obj-$(CONFIG_FB_MB862XX) += mb862xx/ 119 - obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o 120 119 obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o 121 120 obj-$(CONFIG_FB_HYPERV) += hyperv_fb.o 122 121 obj-$(CONFIG_FB_OPENCORES) += ocfb.o
-690
drivers/video/fbdev/jz4740_fb.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-or-later 2 - /* 3 - * Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de> 4 - * JZ4740 SoC LCD framebuffer driver 5 - */ 6 - 7 - #include <linux/kernel.h> 8 - #include <linux/module.h> 9 - #include <linux/mutex.h> 10 - #include <linux/platform_device.h> 11 - #include <linux/pinctrl/consumer.h> 12 - 13 - #include <linux/clk.h> 14 - #include <linux/delay.h> 15 - 16 - #include <linux/console.h> 17 - #include <linux/fb.h> 18 - 19 - #include <linux/dma-mapping.h> 20 - 21 - #include <asm/mach-jz4740/jz4740_fb.h> 22 - 23 - #define JZ_REG_LCD_CFG 0x00 24 - #define JZ_REG_LCD_VSYNC 0x04 25 - #define JZ_REG_LCD_HSYNC 0x08 26 - #define JZ_REG_LCD_VAT 0x0C 27 - #define JZ_REG_LCD_DAH 0x10 28 - #define JZ_REG_LCD_DAV 0x14 29 - #define JZ_REG_LCD_PS 0x18 30 - #define JZ_REG_LCD_CLS 0x1C 31 - #define JZ_REG_LCD_SPL 0x20 32 - #define JZ_REG_LCD_REV 0x24 33 - #define JZ_REG_LCD_CTRL 0x30 34 - #define JZ_REG_LCD_STATE 0x34 35 - #define JZ_REG_LCD_IID 0x38 36 - #define JZ_REG_LCD_DA0 0x40 37 - #define JZ_REG_LCD_SA0 0x44 38 - #define JZ_REG_LCD_FID0 0x48 39 - #define JZ_REG_LCD_CMD0 0x4C 40 - #define JZ_REG_LCD_DA1 0x50 41 - #define JZ_REG_LCD_SA1 0x54 42 - #define JZ_REG_LCD_FID1 0x58 43 - #define JZ_REG_LCD_CMD1 0x5C 44 - 45 - #define JZ_LCD_CFG_SLCD BIT(31) 46 - #define JZ_LCD_CFG_PS_DISABLE BIT(23) 47 - #define JZ_LCD_CFG_CLS_DISABLE BIT(22) 48 - #define JZ_LCD_CFG_SPL_DISABLE BIT(21) 49 - #define JZ_LCD_CFG_REV_DISABLE BIT(20) 50 - #define JZ_LCD_CFG_HSYNCM BIT(19) 51 - #define JZ_LCD_CFG_PCLKM BIT(18) 52 - #define JZ_LCD_CFG_INV BIT(17) 53 - #define JZ_LCD_CFG_SYNC_DIR BIT(16) 54 - #define JZ_LCD_CFG_PS_POLARITY BIT(15) 55 - #define JZ_LCD_CFG_CLS_POLARITY BIT(14) 56 - #define JZ_LCD_CFG_SPL_POLARITY BIT(13) 57 - #define JZ_LCD_CFG_REV_POLARITY BIT(12) 58 - #define JZ_LCD_CFG_HSYNC_ACTIVE_LOW BIT(11) 59 - #define JZ_LCD_CFG_PCLK_FALLING_EDGE BIT(10) 60 - #define JZ_LCD_CFG_DE_ACTIVE_LOW BIT(9) 61 - #define JZ_LCD_CFG_VSYNC_ACTIVE_LOW BIT(8) 62 - #define JZ_LCD_CFG_18_BIT BIT(7) 63 - #define JZ_LCD_CFG_PDW (BIT(5) | BIT(4)) 64 - #define JZ_LCD_CFG_MODE_MASK 0xf 65 - 66 - #define JZ_LCD_CTRL_BURST_4 (0x0 << 28) 67 - #define JZ_LCD_CTRL_BURST_8 (0x1 << 28) 68 - #define JZ_LCD_CTRL_BURST_16 (0x2 << 28) 69 - #define JZ_LCD_CTRL_RGB555 BIT(27) 70 - #define JZ_LCD_CTRL_OFUP BIT(26) 71 - #define JZ_LCD_CTRL_FRC_GRAYSCALE_16 (0x0 << 24) 72 - #define JZ_LCD_CTRL_FRC_GRAYSCALE_4 (0x1 << 24) 73 - #define JZ_LCD_CTRL_FRC_GRAYSCALE_2 (0x2 << 24) 74 - #define JZ_LCD_CTRL_PDD_MASK (0xff << 16) 75 - #define JZ_LCD_CTRL_EOF_IRQ BIT(13) 76 - #define JZ_LCD_CTRL_SOF_IRQ BIT(12) 77 - #define JZ_LCD_CTRL_OFU_IRQ BIT(11) 78 - #define JZ_LCD_CTRL_IFU0_IRQ BIT(10) 79 - #define JZ_LCD_CTRL_IFU1_IRQ BIT(9) 80 - #define JZ_LCD_CTRL_DD_IRQ BIT(8) 81 - #define JZ_LCD_CTRL_QDD_IRQ BIT(7) 82 - #define JZ_LCD_CTRL_REVERSE_ENDIAN BIT(6) 83 - #define JZ_LCD_CTRL_LSB_FISRT BIT(5) 84 - #define JZ_LCD_CTRL_DISABLE BIT(4) 85 - #define JZ_LCD_CTRL_ENABLE BIT(3) 86 - #define JZ_LCD_CTRL_BPP_1 0x0 87 - #define JZ_LCD_CTRL_BPP_2 0x1 88 - #define JZ_LCD_CTRL_BPP_4 0x2 89 - #define JZ_LCD_CTRL_BPP_8 0x3 90 - #define JZ_LCD_CTRL_BPP_15_16 0x4 91 - #define JZ_LCD_CTRL_BPP_18_24 0x5 92 - 93 - #define JZ_LCD_CMD_SOF_IRQ BIT(31) 94 - #define JZ_LCD_CMD_EOF_IRQ BIT(30) 95 - #define JZ_LCD_CMD_ENABLE_PAL BIT(28) 96 - 97 - #define JZ_LCD_SYNC_MASK 0x3ff 98 - 99 - #define JZ_LCD_STATE_DISABLED BIT(0) 100 - 101 - struct jzfb_framedesc { 102 - uint32_t next; 103 - uint32_t addr; 104 - uint32_t id; 105 - uint32_t cmd; 106 - } __packed; 107 - 108 - struct jzfb { 109 - struct fb_info *fb; 110 - struct platform_device *pdev; 111 - void __iomem *base; 112 - struct resource *mem; 113 - struct jz4740_fb_platform_data *pdata; 114 - 115 - size_t vidmem_size; 116 - void *vidmem; 117 - dma_addr_t vidmem_phys; 118 - struct jzfb_framedesc *framedesc; 119 - dma_addr_t framedesc_phys; 120 - 121 - struct clk *ldclk; 122 - struct clk *lpclk; 123 - 124 - unsigned is_enabled:1; 125 - struct mutex lock; 126 - 127 - uint32_t pseudo_palette[16]; 128 - }; 129 - 130 - static const struct fb_fix_screeninfo jzfb_fix = { 131 - .id = "JZ4740 FB", 132 - .type = FB_TYPE_PACKED_PIXELS, 133 - .visual = FB_VISUAL_TRUECOLOR, 134 - .xpanstep = 0, 135 - .ypanstep = 0, 136 - .ywrapstep = 0, 137 - .accel = FB_ACCEL_NONE, 138 - }; 139 - 140 - /* Based on CNVT_TOHW macro from skeletonfb.c */ 141 - static inline uint32_t jzfb_convert_color_to_hw(unsigned val, 142 - struct fb_bitfield *bf) 143 - { 144 - return (((val << bf->length) + 0x7FFF - val) >> 16) << bf->offset; 145 - } 146 - 147 - static int jzfb_setcolreg(unsigned regno, unsigned red, unsigned green, 148 - unsigned blue, unsigned transp, struct fb_info *fb) 149 - { 150 - uint32_t color; 151 - 152 - if (regno >= 16) 153 - return -EINVAL; 154 - 155 - color = jzfb_convert_color_to_hw(red, &fb->var.red); 156 - color |= jzfb_convert_color_to_hw(green, &fb->var.green); 157 - color |= jzfb_convert_color_to_hw(blue, &fb->var.blue); 158 - color |= jzfb_convert_color_to_hw(transp, &fb->var.transp); 159 - 160 - ((uint32_t *)(fb->pseudo_palette))[regno] = color; 161 - 162 - return 0; 163 - } 164 - 165 - static int jzfb_get_controller_bpp(struct jzfb *jzfb) 166 - { 167 - switch (jzfb->pdata->bpp) { 168 - case 18: 169 - case 24: 170 - return 32; 171 - case 15: 172 - return 16; 173 - default: 174 - return jzfb->pdata->bpp; 175 - } 176 - } 177 - 178 - static struct fb_videomode *jzfb_get_mode(struct jzfb *jzfb, 179 - struct fb_var_screeninfo *var) 180 - { 181 - size_t i; 182 - struct fb_videomode *mode = jzfb->pdata->modes; 183 - 184 - for (i = 0; i < jzfb->pdata->num_modes; ++i, ++mode) { 185 - if (mode->xres == var->xres && mode->yres == var->yres) 186 - return mode; 187 - } 188 - 189 - return NULL; 190 - } 191 - 192 - static int jzfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fb) 193 - { 194 - struct jzfb *jzfb = fb->par; 195 - struct fb_videomode *mode; 196 - 197 - if (var->bits_per_pixel != jzfb_get_controller_bpp(jzfb) && 198 - var->bits_per_pixel != jzfb->pdata->bpp) 199 - return -EINVAL; 200 - 201 - mode = jzfb_get_mode(jzfb, var); 202 - if (mode == NULL) 203 - return -EINVAL; 204 - 205 - fb_videomode_to_var(var, mode); 206 - 207 - switch (jzfb->pdata->bpp) { 208 - case 8: 209 - break; 210 - case 15: 211 - var->red.offset = 10; 212 - var->red.length = 5; 213 - var->green.offset = 6; 214 - var->green.length = 5; 215 - var->blue.offset = 0; 216 - var->blue.length = 5; 217 - break; 218 - case 16: 219 - var->red.offset = 11; 220 - var->red.length = 5; 221 - var->green.offset = 5; 222 - var->green.length = 6; 223 - var->blue.offset = 0; 224 - var->blue.length = 5; 225 - break; 226 - case 18: 227 - var->red.offset = 16; 228 - var->red.length = 6; 229 - var->green.offset = 8; 230 - var->green.length = 6; 231 - var->blue.offset = 0; 232 - var->blue.length = 6; 233 - var->bits_per_pixel = 32; 234 - break; 235 - case 32: 236 - case 24: 237 - var->transp.offset = 24; 238 - var->transp.length = 8; 239 - var->red.offset = 16; 240 - var->red.length = 8; 241 - var->green.offset = 8; 242 - var->green.length = 8; 243 - var->blue.offset = 0; 244 - var->blue.length = 8; 245 - var->bits_per_pixel = 32; 246 - break; 247 - default: 248 - break; 249 - } 250 - 251 - return 0; 252 - } 253 - 254 - static int jzfb_set_par(struct fb_info *info) 255 - { 256 - struct jzfb *jzfb = info->par; 257 - struct jz4740_fb_platform_data *pdata = jzfb->pdata; 258 - struct fb_var_screeninfo *var = &info->var; 259 - struct fb_videomode *mode; 260 - uint16_t hds, vds; 261 - uint16_t hde, vde; 262 - uint16_t ht, vt; 263 - uint32_t ctrl; 264 - uint32_t cfg; 265 - unsigned long rate; 266 - 267 - mode = jzfb_get_mode(jzfb, var); 268 - if (mode == NULL) 269 - return -EINVAL; 270 - 271 - if (mode == info->mode) 272 - return 0; 273 - 274 - info->mode = mode; 275 - 276 - hds = mode->hsync_len + mode->left_margin; 277 - hde = hds + mode->xres; 278 - ht = hde + mode->right_margin; 279 - 280 - vds = mode->vsync_len + mode->upper_margin; 281 - vde = vds + mode->yres; 282 - vt = vde + mode->lower_margin; 283 - 284 - ctrl = JZ_LCD_CTRL_OFUP | JZ_LCD_CTRL_BURST_16; 285 - 286 - switch (pdata->bpp) { 287 - case 1: 288 - ctrl |= JZ_LCD_CTRL_BPP_1; 289 - break; 290 - case 2: 291 - ctrl |= JZ_LCD_CTRL_BPP_2; 292 - break; 293 - case 4: 294 - ctrl |= JZ_LCD_CTRL_BPP_4; 295 - break; 296 - case 8: 297 - ctrl |= JZ_LCD_CTRL_BPP_8; 298 - break; 299 - case 15: 300 - ctrl |= JZ_LCD_CTRL_RGB555; /* Falltrough */ 301 - case 16: 302 - ctrl |= JZ_LCD_CTRL_BPP_15_16; 303 - break; 304 - case 18: 305 - case 24: 306 - case 32: 307 - ctrl |= JZ_LCD_CTRL_BPP_18_24; 308 - break; 309 - default: 310 - break; 311 - } 312 - 313 - cfg = pdata->lcd_type & 0xf; 314 - 315 - if (!(mode->sync & FB_SYNC_HOR_HIGH_ACT)) 316 - cfg |= JZ_LCD_CFG_HSYNC_ACTIVE_LOW; 317 - 318 - if (!(mode->sync & FB_SYNC_VERT_HIGH_ACT)) 319 - cfg |= JZ_LCD_CFG_VSYNC_ACTIVE_LOW; 320 - 321 - if (pdata->pixclk_falling_edge) 322 - cfg |= JZ_LCD_CFG_PCLK_FALLING_EDGE; 323 - 324 - if (pdata->date_enable_active_low) 325 - cfg |= JZ_LCD_CFG_DE_ACTIVE_LOW; 326 - 327 - if (pdata->lcd_type == JZ_LCD_TYPE_GENERIC_18_BIT) 328 - cfg |= JZ_LCD_CFG_18_BIT; 329 - 330 - if (mode->pixclock) { 331 - rate = PICOS2KHZ(mode->pixclock) * 1000; 332 - mode->refresh = rate / vt / ht; 333 - } else { 334 - if (pdata->lcd_type == JZ_LCD_TYPE_8BIT_SERIAL) 335 - rate = mode->refresh * (vt + 2 * mode->xres) * ht; 336 - else 337 - rate = mode->refresh * vt * ht; 338 - 339 - mode->pixclock = KHZ2PICOS(rate / 1000); 340 - } 341 - 342 - mutex_lock(&jzfb->lock); 343 - if (!jzfb->is_enabled) 344 - clk_enable(jzfb->ldclk); 345 - else 346 - ctrl |= JZ_LCD_CTRL_ENABLE; 347 - 348 - switch (pdata->lcd_type) { 349 - case JZ_LCD_TYPE_SPECIAL_TFT_1: 350 - case JZ_LCD_TYPE_SPECIAL_TFT_2: 351 - case JZ_LCD_TYPE_SPECIAL_TFT_3: 352 - writel(pdata->special_tft_config.spl, jzfb->base + JZ_REG_LCD_SPL); 353 - writel(pdata->special_tft_config.cls, jzfb->base + JZ_REG_LCD_CLS); 354 - writel(pdata->special_tft_config.ps, jzfb->base + JZ_REG_LCD_PS); 355 - writel(pdata->special_tft_config.ps, jzfb->base + JZ_REG_LCD_REV); 356 - break; 357 - default: 358 - cfg |= JZ_LCD_CFG_PS_DISABLE; 359 - cfg |= JZ_LCD_CFG_CLS_DISABLE; 360 - cfg |= JZ_LCD_CFG_SPL_DISABLE; 361 - cfg |= JZ_LCD_CFG_REV_DISABLE; 362 - break; 363 - } 364 - 365 - writel(mode->hsync_len, jzfb->base + JZ_REG_LCD_HSYNC); 366 - writel(mode->vsync_len, jzfb->base + JZ_REG_LCD_VSYNC); 367 - 368 - writel((ht << 16) | vt, jzfb->base + JZ_REG_LCD_VAT); 369 - 370 - writel((hds << 16) | hde, jzfb->base + JZ_REG_LCD_DAH); 371 - writel((vds << 16) | vde, jzfb->base + JZ_REG_LCD_DAV); 372 - 373 - writel(cfg, jzfb->base + JZ_REG_LCD_CFG); 374 - 375 - writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL); 376 - 377 - if (!jzfb->is_enabled) 378 - clk_disable_unprepare(jzfb->ldclk); 379 - 380 - mutex_unlock(&jzfb->lock); 381 - 382 - clk_set_rate(jzfb->lpclk, rate); 383 - clk_set_rate(jzfb->ldclk, rate * 3); 384 - 385 - return 0; 386 - } 387 - 388 - static void jzfb_enable(struct jzfb *jzfb) 389 - { 390 - uint32_t ctrl; 391 - 392 - clk_prepare_enable(jzfb->ldclk); 393 - 394 - pinctrl_pm_select_default_state(&jzfb->pdev->dev); 395 - 396 - writel(0, jzfb->base + JZ_REG_LCD_STATE); 397 - 398 - writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0); 399 - 400 - ctrl = readl(jzfb->base + JZ_REG_LCD_CTRL); 401 - ctrl |= JZ_LCD_CTRL_ENABLE; 402 - ctrl &= ~JZ_LCD_CTRL_DISABLE; 403 - writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL); 404 - } 405 - 406 - static void jzfb_disable(struct jzfb *jzfb) 407 - { 408 - uint32_t ctrl; 409 - 410 - ctrl = readl(jzfb->base + JZ_REG_LCD_CTRL); 411 - ctrl |= JZ_LCD_CTRL_DISABLE; 412 - writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL); 413 - do { 414 - ctrl = readl(jzfb->base + JZ_REG_LCD_STATE); 415 - } while (!(ctrl & JZ_LCD_STATE_DISABLED)); 416 - 417 - pinctrl_pm_select_sleep_state(&jzfb->pdev->dev); 418 - 419 - clk_disable_unprepare(jzfb->ldclk); 420 - } 421 - 422 - static int jzfb_blank(int blank_mode, struct fb_info *info) 423 - { 424 - struct jzfb *jzfb = info->par; 425 - 426 - switch (blank_mode) { 427 - case FB_BLANK_UNBLANK: 428 - mutex_lock(&jzfb->lock); 429 - if (jzfb->is_enabled) { 430 - mutex_unlock(&jzfb->lock); 431 - return 0; 432 - } 433 - 434 - jzfb_enable(jzfb); 435 - jzfb->is_enabled = 1; 436 - 437 - mutex_unlock(&jzfb->lock); 438 - break; 439 - default: 440 - mutex_lock(&jzfb->lock); 441 - if (!jzfb->is_enabled) { 442 - mutex_unlock(&jzfb->lock); 443 - return 0; 444 - } 445 - 446 - jzfb_disable(jzfb); 447 - jzfb->is_enabled = 0; 448 - 449 - mutex_unlock(&jzfb->lock); 450 - break; 451 - } 452 - 453 - return 0; 454 - } 455 - 456 - static int jzfb_alloc_devmem(struct jzfb *jzfb) 457 - { 458 - int max_videosize = 0; 459 - struct fb_videomode *mode = jzfb->pdata->modes; 460 - int i; 461 - 462 - for (i = 0; i < jzfb->pdata->num_modes; ++mode, ++i) { 463 - if (max_videosize < mode->xres * mode->yres) 464 - max_videosize = mode->xres * mode->yres; 465 - } 466 - 467 - max_videosize *= jzfb_get_controller_bpp(jzfb) >> 3; 468 - 469 - jzfb->framedesc = dma_alloc_coherent(&jzfb->pdev->dev, 470 - sizeof(*jzfb->framedesc), 471 - &jzfb->framedesc_phys, GFP_KERNEL); 472 - 473 - if (!jzfb->framedesc) 474 - return -ENOMEM; 475 - 476 - jzfb->vidmem_size = PAGE_ALIGN(max_videosize); 477 - jzfb->vidmem = dma_alloc_coherent(&jzfb->pdev->dev, 478 - jzfb->vidmem_size, 479 - &jzfb->vidmem_phys, GFP_KERNEL); 480 - 481 - if (!jzfb->vidmem) 482 - goto err_free_framedesc; 483 - 484 - jzfb->framedesc->next = jzfb->framedesc_phys; 485 - jzfb->framedesc->addr = jzfb->vidmem_phys; 486 - jzfb->framedesc->id = 0xdeafbead; 487 - jzfb->framedesc->cmd = 0; 488 - jzfb->framedesc->cmd |= max_videosize / 4; 489 - 490 - return 0; 491 - 492 - err_free_framedesc: 493 - dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc), 494 - jzfb->framedesc, jzfb->framedesc_phys); 495 - return -ENOMEM; 496 - } 497 - 498 - static void jzfb_free_devmem(struct jzfb *jzfb) 499 - { 500 - dma_free_coherent(&jzfb->pdev->dev, jzfb->vidmem_size, 501 - jzfb->vidmem, jzfb->vidmem_phys); 502 - dma_free_coherent(&jzfb->pdev->dev, sizeof(*jzfb->framedesc), 503 - jzfb->framedesc, jzfb->framedesc_phys); 504 - } 505 - 506 - static struct fb_ops jzfb_ops = { 507 - .owner = THIS_MODULE, 508 - .fb_check_var = jzfb_check_var, 509 - .fb_set_par = jzfb_set_par, 510 - .fb_blank = jzfb_blank, 511 - .fb_fillrect = sys_fillrect, 512 - .fb_copyarea = sys_copyarea, 513 - .fb_imageblit = sys_imageblit, 514 - .fb_setcolreg = jzfb_setcolreg, 515 - }; 516 - 517 - static int jzfb_probe(struct platform_device *pdev) 518 - { 519 - int ret; 520 - struct jzfb *jzfb; 521 - struct fb_info *fb; 522 - struct jz4740_fb_platform_data *pdata = pdev->dev.platform_data; 523 - struct resource *mem; 524 - 525 - if (!pdata) { 526 - dev_err(&pdev->dev, "Missing platform data\n"); 527 - return -ENXIO; 528 - } 529 - 530 - fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev); 531 - if (!fb) 532 - return -ENOMEM; 533 - 534 - fb->fbops = &jzfb_ops; 535 - fb->flags = FBINFO_DEFAULT; 536 - 537 - jzfb = fb->par; 538 - jzfb->pdev = pdev; 539 - jzfb->pdata = pdata; 540 - 541 - jzfb->ldclk = devm_clk_get(&pdev->dev, "lcd"); 542 - if (IS_ERR(jzfb->ldclk)) { 543 - ret = PTR_ERR(jzfb->ldclk); 544 - dev_err(&pdev->dev, "Failed to get lcd clock: %d\n", ret); 545 - goto err_framebuffer_release; 546 - } 547 - 548 - jzfb->lpclk = devm_clk_get(&pdev->dev, "lcd_pclk"); 549 - if (IS_ERR(jzfb->lpclk)) { 550 - ret = PTR_ERR(jzfb->lpclk); 551 - dev_err(&pdev->dev, "Failed to get lcd pixel clock: %d\n", ret); 552 - goto err_framebuffer_release; 553 - } 554 - 555 - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 556 - jzfb->base = devm_ioremap_resource(&pdev->dev, mem); 557 - if (IS_ERR(jzfb->base)) { 558 - ret = PTR_ERR(jzfb->base); 559 - goto err_framebuffer_release; 560 - } 561 - 562 - platform_set_drvdata(pdev, jzfb); 563 - 564 - mutex_init(&jzfb->lock); 565 - 566 - fb_videomode_to_modelist(pdata->modes, pdata->num_modes, 567 - &fb->modelist); 568 - fb_videomode_to_var(&fb->var, pdata->modes); 569 - fb->var.bits_per_pixel = pdata->bpp; 570 - jzfb_check_var(&fb->var, fb); 571 - 572 - ret = jzfb_alloc_devmem(jzfb); 573 - if (ret) { 574 - dev_err(&pdev->dev, "Failed to allocate video memory\n"); 575 - goto err_framebuffer_release; 576 - } 577 - 578 - fb->fix = jzfb_fix; 579 - fb->fix.line_length = fb->var.bits_per_pixel * fb->var.xres / 8; 580 - fb->fix.mmio_start = mem->start; 581 - fb->fix.mmio_len = resource_size(mem); 582 - fb->fix.smem_start = jzfb->vidmem_phys; 583 - fb->fix.smem_len = fb->fix.line_length * fb->var.yres; 584 - fb->screen_base = jzfb->vidmem; 585 - fb->pseudo_palette = jzfb->pseudo_palette; 586 - 587 - fb_alloc_cmap(&fb->cmap, 256, 0); 588 - 589 - clk_prepare_enable(jzfb->ldclk); 590 - jzfb->is_enabled = 1; 591 - 592 - writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0); 593 - 594 - fb->mode = NULL; 595 - jzfb_set_par(fb); 596 - 597 - ret = register_framebuffer(fb); 598 - if (ret) { 599 - dev_err(&pdev->dev, "Failed to register framebuffer: %d\n", ret); 600 - goto err_free_devmem; 601 - } 602 - 603 - jzfb->fb = fb; 604 - 605 - return 0; 606 - 607 - err_free_devmem: 608 - fb_dealloc_cmap(&fb->cmap); 609 - jzfb_free_devmem(jzfb); 610 - err_framebuffer_release: 611 - framebuffer_release(fb); 612 - return ret; 613 - } 614 - 615 - static int jzfb_remove(struct platform_device *pdev) 616 - { 617 - struct jzfb *jzfb = platform_get_drvdata(pdev); 618 - 619 - jzfb_blank(FB_BLANK_POWERDOWN, jzfb->fb); 620 - 621 - fb_dealloc_cmap(&jzfb->fb->cmap); 622 - jzfb_free_devmem(jzfb); 623 - 624 - framebuffer_release(jzfb->fb); 625 - 626 - return 0; 627 - } 628 - 629 - #ifdef CONFIG_PM 630 - 631 - static int jzfb_suspend(struct device *dev) 632 - { 633 - struct jzfb *jzfb = dev_get_drvdata(dev); 634 - 635 - console_lock(); 636 - fb_set_suspend(jzfb->fb, 1); 637 - console_unlock(); 638 - 639 - mutex_lock(&jzfb->lock); 640 - if (jzfb->is_enabled) 641 - jzfb_disable(jzfb); 642 - mutex_unlock(&jzfb->lock); 643 - 644 - return 0; 645 - } 646 - 647 - static int jzfb_resume(struct device *dev) 648 - { 649 - struct jzfb *jzfb = dev_get_drvdata(dev); 650 - clk_prepare_enable(jzfb->ldclk); 651 - 652 - mutex_lock(&jzfb->lock); 653 - if (jzfb->is_enabled) 654 - jzfb_enable(jzfb); 655 - mutex_unlock(&jzfb->lock); 656 - 657 - console_lock(); 658 - fb_set_suspend(jzfb->fb, 0); 659 - console_unlock(); 660 - 661 - return 0; 662 - } 663 - 664 - static const struct dev_pm_ops jzfb_pm_ops = { 665 - .suspend = jzfb_suspend, 666 - .resume = jzfb_resume, 667 - .poweroff = jzfb_suspend, 668 - .restore = jzfb_resume, 669 - }; 670 - 671 - #define JZFB_PM_OPS (&jzfb_pm_ops) 672 - 673 - #else 674 - #define JZFB_PM_OPS NULL 675 - #endif 676 - 677 - static struct platform_driver jzfb_driver = { 678 - .probe = jzfb_probe, 679 - .remove = jzfb_remove, 680 - .driver = { 681 - .name = "jz4740-fb", 682 - .pm = JZFB_PM_OPS, 683 - }, 684 - }; 685 - module_platform_driver(jzfb_driver); 686 - 687 - MODULE_LICENSE("GPL"); 688 - MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 689 - MODULE_DESCRIPTION("JZ4740 SoC LCD framebuffer driver"); 690 - MODULE_ALIAS("platform:jz4740-fb");
+20
include/dt-bindings/clock/ingenic,tcu.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * This header provides clock numbers for the ingenic,tcu DT binding. 4 + */ 5 + 6 + #ifndef __DT_BINDINGS_CLOCK_INGENIC_TCU_H__ 7 + #define __DT_BINDINGS_CLOCK_INGENIC_TCU_H__ 8 + 9 + #define TCU_CLK_TIMER0 0 10 + #define TCU_CLK_TIMER1 1 11 + #define TCU_CLK_TIMER2 2 12 + #define TCU_CLK_TIMER3 3 13 + #define TCU_CLK_TIMER4 4 14 + #define TCU_CLK_TIMER5 5 15 + #define TCU_CLK_TIMER6 6 16 + #define TCU_CLK_TIMER7 7 17 + #define TCU_CLK_WDT 8 18 + #define TCU_CLK_OST 9 19 + 20 + #endif /* __DT_BINDINGS_CLOCK_INGENIC_TCU_H__ */
+1
include/dt-bindings/clock/jz4740-cgu.h
··· 34 34 #define JZ4740_CLK_ADC 19 35 35 #define JZ4740_CLK_I2C 20 36 36 #define JZ4740_CLK_AIC 21 37 + #define JZ4740_CLK_TCU 22 37 38 38 39 #endif /* __DT_BINDINGS_CLOCK_JZ4740_CGU_H__ */
+6
include/linux/mfd/syscon.h
··· 17 17 struct device_node; 18 18 19 19 #ifdef CONFIG_MFD_SYSCON 20 + extern struct regmap *device_node_to_regmap(struct device_node *np); 20 21 extern struct regmap *syscon_node_to_regmap(struct device_node *np); 21 22 extern struct regmap *syscon_regmap_lookup_by_compatible(const char *s); 22 23 extern struct regmap *syscon_regmap_lookup_by_phandle( 23 24 struct device_node *np, 24 25 const char *property); 25 26 #else 27 + static inline struct regmap *device_node_to_regmap(struct device_node *np) 28 + { 29 + return ERR_PTR(-ENOTSUPP); 30 + } 31 + 26 32 static inline struct regmap *syscon_node_to_regmap(struct device_node *np) 27 33 { 28 34 return ERR_PTR(-ENOTSUPP);
+2 -23
sound/soc/jz4740/Kconfig
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 - config SND_JZ4740_SOC 3 - tristate "SoC Audio for Ingenic JZ4740 SoC" 4 - depends on MIPS || COMPILE_TEST 5 - select SND_SOC_GENERIC_DMAENGINE_PCM 6 - help 7 - Say Y or M if you want to add support for codecs attached to 8 - the JZ4740 I2S interface. You will also need to select the audio 9 - interfaces to support below. 10 - 11 - if SND_JZ4740_SOC 12 - 13 2 config SND_JZ4740_SOC_I2S 14 3 tristate "SoC Audio (I2S protocol) for Ingenic JZ4740 SoC" 4 + depends on MIPS || COMPILE_TEST 15 5 depends on HAS_IOMEM 6 + select SND_SOC_GENERIC_DMAENGINE_PCM 16 7 help 17 8 Say Y if you want to use I2S protocol and I2S codec on Ingenic JZ4740 18 9 based boards. 19 - 20 - config SND_JZ4740_SOC_QI_LB60 21 - tristate "SoC Audio support for Qi LB60" 22 - depends on HAS_IOMEM 23 - depends on JZ4740_QI_LB60 || COMPILE_TEST 24 - select SND_JZ4740_SOC_I2S 25 - select SND_SOC_JZ4740_CODEC 26 - help 27 - Say Y if you want to add support for ASoC audio on the Qi LB60 board 28 - a.k.a Qi Ben NanoNote. 29 - 30 - endif
-5
sound/soc/jz4740/Makefile
··· 5 5 snd-soc-jz4740-i2s-objs := jz4740-i2s.o 6 6 7 7 obj-$(CONFIG_SND_JZ4740_SOC_I2S) += snd-soc-jz4740-i2s.o 8 - 9 - # Jz4740 Machine Support 10 - snd-soc-qi-lb60-objs := qi_lb60.o 11 - 12 - obj-$(CONFIG_SND_JZ4740_SOC_QI_LB60) += snd-soc-qi-lb60.o
-106
sound/soc/jz4740/qi_lb60.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright (C) 2009, Lars-Peter Clausen <lars@metafoo.de> 4 - */ 5 - 6 - #include <linux/module.h> 7 - #include <linux/moduleparam.h> 8 - #include <linux/timer.h> 9 - #include <linux/interrupt.h> 10 - #include <linux/platform_device.h> 11 - #include <sound/core.h> 12 - #include <sound/pcm.h> 13 - #include <sound/soc.h> 14 - #include <linux/gpio/consumer.h> 15 - 16 - struct qi_lb60 { 17 - struct gpio_desc *snd_gpio; 18 - struct gpio_desc *amp_gpio; 19 - }; 20 - 21 - static int qi_lb60_spk_event(struct snd_soc_dapm_widget *widget, 22 - struct snd_kcontrol *ctrl, int event) 23 - { 24 - struct qi_lb60 *qi_lb60 = snd_soc_card_get_drvdata(widget->dapm->card); 25 - int on = !SND_SOC_DAPM_EVENT_OFF(event); 26 - 27 - gpiod_set_value_cansleep(qi_lb60->snd_gpio, on); 28 - gpiod_set_value_cansleep(qi_lb60->amp_gpio, on); 29 - 30 - return 0; 31 - } 32 - 33 - static const struct snd_soc_dapm_widget qi_lb60_widgets[] = { 34 - SND_SOC_DAPM_SPK("Speaker", qi_lb60_spk_event), 35 - SND_SOC_DAPM_MIC("Mic", NULL), 36 - }; 37 - 38 - static const struct snd_soc_dapm_route qi_lb60_routes[] = { 39 - {"Mic", NULL, "MIC"}, 40 - {"Speaker", NULL, "LOUT"}, 41 - {"Speaker", NULL, "ROUT"}, 42 - }; 43 - 44 - SND_SOC_DAILINK_DEFS(hifi, 45 - DAILINK_COMP_ARRAY(COMP_CPU("jz4740-i2s")), 46 - DAILINK_COMP_ARRAY(COMP_CODEC("jz4740-codec", "jz4740-hifi")), 47 - DAILINK_COMP_ARRAY(COMP_PLATFORM("jz4740-i2s"))); 48 - 49 - static struct snd_soc_dai_link qi_lb60_dai = { 50 - .name = "jz4740", 51 - .stream_name = "jz4740", 52 - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 53 - SND_SOC_DAIFMT_CBM_CFM, 54 - SND_SOC_DAILINK_REG(hifi), 55 - }; 56 - 57 - static struct snd_soc_card qi_lb60_card = { 58 - .name = "QI LB60", 59 - .owner = THIS_MODULE, 60 - .dai_link = &qi_lb60_dai, 61 - .num_links = 1, 62 - 63 - .dapm_widgets = qi_lb60_widgets, 64 - .num_dapm_widgets = ARRAY_SIZE(qi_lb60_widgets), 65 - .dapm_routes = qi_lb60_routes, 66 - .num_dapm_routes = ARRAY_SIZE(qi_lb60_routes), 67 - .fully_routed = true, 68 - }; 69 - 70 - static int qi_lb60_probe(struct platform_device *pdev) 71 - { 72 - struct qi_lb60 *qi_lb60; 73 - struct snd_soc_card *card = &qi_lb60_card; 74 - 75 - qi_lb60 = devm_kzalloc(&pdev->dev, sizeof(*qi_lb60), GFP_KERNEL); 76 - if (!qi_lb60) 77 - return -ENOMEM; 78 - 79 - qi_lb60->snd_gpio = devm_gpiod_get(&pdev->dev, "snd", GPIOD_OUT_LOW); 80 - if (IS_ERR(qi_lb60->snd_gpio)) 81 - return PTR_ERR(qi_lb60->snd_gpio); 82 - 83 - qi_lb60->amp_gpio = devm_gpiod_get(&pdev->dev, "amp", GPIOD_OUT_LOW); 84 - if (IS_ERR(qi_lb60->amp_gpio)) 85 - return PTR_ERR(qi_lb60->amp_gpio); 86 - 87 - card->dev = &pdev->dev; 88 - 89 - snd_soc_card_set_drvdata(card, qi_lb60); 90 - 91 - return devm_snd_soc_register_card(&pdev->dev, card); 92 - } 93 - 94 - static struct platform_driver qi_lb60_driver = { 95 - .driver = { 96 - .name = "qi-lb60-audio", 97 - }, 98 - .probe = qi_lb60_probe, 99 - }; 100 - 101 - module_platform_driver(qi_lb60_driver); 102 - 103 - MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 104 - MODULE_DESCRIPTION("ALSA SoC QI LB60 Audio support"); 105 - MODULE_LICENSE("GPL v2"); 106 - MODULE_ALIAS("platform:qi-lb60-audio");