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

Merge tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc

Pull ARM SoC platform updates from Olof Johansson:
"New and/or improved SoC support for this release:

Marvell Berlin:
- Enable standard DT-based cpufreq
- Add CPU hotplug support

Freescale:
- Ethernet init for i.MX7D
- Suspend/resume support for i.MX6UL

Allwinner:
- Support for R8 chipset (used on NTC's $9 C.H.I.P board)

Mediatek:
- SMP support for some platforms

Uniphier:
- L2 support
- Cleaned up SMP support, etc.

plus a handful of other patches around above functionality, and a few
other smaller changes"

* tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (42 commits)
ARM: uniphier: rework SMP operations to use trampoline code
ARM: uniphier: add outer cache support
Documentation: EXYNOS: Update bootloader interface on exynos542x
ARM: mvebu: add broken-idle option
ARM: orion5x: use mac_pton() helper
ARM: at91: pm: at91_pm_suspend_in_sram() must be 8-byte aligned
ARM: sunxi: Add R8 support
ARM: digicolor: select pinctrl/gpio driver
arm: berlin: add CPU hotplug support
arm: berlin: use non-self-cleared reset register to reset cpu
ARM: mediatek: add smp bringup code
ARM: mediatek: enable gpt6 on boot up to make arch timer working
soc: mediatek: Fix random hang up issue while kernel init
soc: ti: qmss: make acc queue support optional in the driver
soc: ti: add firmware file name as part of the driver
Documentation: dt: soc: Add description for knav qmss driver
ARM: S3C64XX: Use PWM lookup table for mach-smartq
ARM: S3C64XX: Use PWM lookup table for mach-hmt
ARM: S3C64XX: Use PWM lookup table for mach-crag6410
ARM: S3C64XX: Use PWM lookup table for smdk6410
...

+1888 -296
+3 -2
Documentation/arm/Samsung/Bootloader-interface.txt
··· 19 19 Address: sysram_ns_base_addr 20 20 Offset Value Purpose 21 21 ============================================================================= 22 - 0x08 exynos_cpu_resume_ns System suspend 22 + 0x08 exynos_cpu_resume_ns, mcpm_entry_point System suspend 23 23 0x0c 0x00000bad (Magic cookie) System suspend 24 24 0x1c exynos4_secondary_startup Secondary CPU boot 25 25 0x1c + 4*cpu exynos4_secondary_startup (Exynos4412) Secondary CPU boot ··· 56 56 Address: pmu_base_addr 57 57 Offset Value Purpose 58 58 ============================================================================= 59 - 0x0908 Non-zero (only Exynos3250) Secondary CPU boot up indicator 59 + 0x0908 Non-zero Secondary CPU boot up indicator 60 + on Exynos3250 and Exynos542x 60 61 61 62 62 63 4. Glossary
+56
Documentation/arm/keystone/knav-qmss.txt
··· 1 + * Texas Instruments Keystone Navigator Queue Management SubSystem driver 2 + 3 + Driver source code path 4 + drivers/soc/ti/knav_qmss.c 5 + drivers/soc/ti/knav_qmss_acc.c 6 + 7 + The QMSS (Queue Manager Sub System) found on Keystone SOCs is one of 8 + the main hardware sub system which forms the backbone of the Keystone 9 + multi-core Navigator. QMSS consist of queue managers, packed-data structure 10 + processors(PDSP), linking RAM, descriptor pools and infrastructure 11 + Packet DMA. 12 + The Queue Manager is a hardware module that is responsible for accelerating 13 + management of the packet queues. Packets are queued/de-queued by writing or 14 + reading descriptor address to a particular memory mapped location. The PDSPs 15 + perform QMSS related functions like accumulation, QoS, or event management. 16 + Linking RAM registers are used to link the descriptors which are stored in 17 + descriptor RAM. Descriptor RAM is configurable as internal or external memory. 18 + The QMSS driver manages the PDSP setups, linking RAM regions, 19 + queue pool management (allocation, push, pop and notify) and descriptor 20 + pool management. 21 + 22 + knav qmss driver provides a set of APIs to drivers to open/close qmss queues, 23 + allocate descriptor pools, map the descriptors, push/pop to queues etc. For 24 + details of the available APIs, please refers to include/linux/soc/ti/knav_qmss.h 25 + 26 + DT documentation is available at 27 + Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt 28 + 29 + Accumulator QMSS queues using PDSP firmware 30 + ============================================ 31 + The QMSS PDSP firmware support accumulator channel that can monitor a single 32 + queue or multiple contiguous queues. drivers/soc/ti/knav_qmss_acc.c is the 33 + driver that interface with the accumulator PDSP. This configures 34 + accumulator channels defined in DTS (example in DT documentation) to monitor 35 + 1 or 32 queues per channel. More description on the firmware is available in 36 + CPPI/QMSS Low Level Driver document (docs/CPPI_QMSS_LLD_SDS.pdf) at 37 + git://git.ti.com/keystone-rtos/qmss-lld.git 38 + 39 + k2_qmss_pdsp_acc48_k2_le_1_0_0_9.bin firmware supports upto 48 accumulator 40 + channels. This firmware is available under ti-keystone folder of 41 + firmware.git at 42 + git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git 43 + 44 + To use copy the firmware image to lib/firmware folder of the initramfs or 45 + ubifs file system and provide a sym link to k2_qmss_pdsp_acc48_k2_le_1_0_0_9.bin 46 + in the file system and boot up the kernel. User would see 47 + 48 + "firmware file ks2_qmss_pdsp_acc48.bin downloaded for PDSP" 49 + 50 + in the boot up log if loading of firmware to PDSP is successful. 51 + 52 + Use of accumulated queues requires the firmware image to be present in the 53 + file system. The driver doesn't acc queues to the supported queue range if 54 + PDSP is not running in the SoC. The API call fails if there is a queue open 55 + request to an acc queue and PDSP is not running. So make sure to copy firmware 56 + to file system before using these queue types.
+1 -1
Documentation/arm/sunxi/README
··· 25 25 + Datasheet 26 26 http://dl.linux-sunxi.org/A10s/A10s%20Datasheet%20-%20v1.20%20%282012-03-27%29.pdf 27 27 28 - - Allwinner A13 (sun5i) 28 + - Allwinner A13 / R8 (sun5i) 29 29 + Datasheet 30 30 http://dl.linux-sunxi.org/A13/A13%20Datasheet%20-%20v1.12%20%282012-03-29%29.pdf 31 31 + User Manual
+5
Documentation/devicetree/bindings/arm/coherency-fabric.txt
··· 27 27 * For "marvell,armada-380-coherency-fabric", only one pair is needed 28 28 for the per-CPU fabric registers. 29 29 30 + Optional properties: 31 + 32 + - broken-idle: boolean to set when the Idle mode is not supported by the 33 + hardware. 34 + 30 35 Examples: 31 36 32 37 coherency-fabric@d0020200 {
+20
Documentation/devicetree/bindings/arm/mvebu-cpu-config.txt
··· 1 + MVEBU CPU Config registers 2 + -------------------------- 3 + 4 + MVEBU (Marvell SOCs: Armada 370/XP) 5 + 6 + Required properties: 7 + 8 + - compatible: one of: 9 + - "marvell,armada-370-cpu-config" 10 + - "marvell,armada-xp-cpu-config" 11 + 12 + - reg: Should contain CPU config registers location and length, in 13 + their per-CPU variant 14 + 15 + Example: 16 + 17 + cpu-config@21000 { 18 + compatible = "marvell,armada-xp-cpu-config"; 19 + reg = <0x21000 0x8>; 20 + };
+1
Documentation/devicetree/bindings/arm/sunxi.txt
··· 6 6 allwinner,sun4i-a10 7 7 allwinner,sun5i-a10s 8 8 allwinner,sun5i-a13 9 + allwinner,sun5i-r8 9 10 allwinner,sun6i-a31 10 11 allwinner,sun7i-a20 11 12 allwinner,sun8i-a23
+60
Documentation/devicetree/bindings/arm/uniphier/cache-uniphier.txt
··· 1 + UniPhier outer cache controller 2 + 3 + UniPhier SoCs are integrated with a full-custom outer cache controller system. 4 + All of them have a level 2 cache controller, and some have a level 3 cache 5 + controller as well. 6 + 7 + Required properties: 8 + - compatible: should be "socionext,uniphier-system-cache" 9 + - reg: offsets and lengths of the register sets for the device. It should 10 + contain 3 regions: control register, revision register, operation register, 11 + in this order. 12 + - cache-unified: specifies the cache is a unified cache. 13 + - cache-size: specifies the size in bytes of the cache 14 + - cache-sets: specifies the number of associativity sets of the cache 15 + - cache-line-size: specifies the line size in bytes 16 + - cache-level: specifies the level in the cache hierarchy. The value should 17 + be 2 for L2 cache, 3 for L3 cache, etc. 18 + 19 + Optional properties: 20 + - next-level-cache: phandle to the next level cache if present. The next level 21 + cache should be also compatible with "socionext,uniphier-system-cache". 22 + 23 + The L2 cache must exist to use the L3 cache; the cache hierarchy must be 24 + indicated correctly with "next-level-cache" properties. 25 + 26 + Example 1 (system with L2): 27 + l2: l2-cache@500c0000 { 28 + compatible = "socionext,uniphier-system-cache"; 29 + reg = <0x500c0000 0x2000>, <0x503c0100 0x4>, 30 + <0x506c0000 0x400>; 31 + cache-unified; 32 + cache-size = <0x80000>; 33 + cache-sets = <256>; 34 + cache-line-size = <128>; 35 + cache-level = <2>; 36 + }; 37 + 38 + Example 2 (system with L2 and L3): 39 + l2: l2-cache@500c0000 { 40 + compatible = "socionext,uniphier-system-cache"; 41 + reg = <0x500c0000 0x2000>, <0x503c0100 0x8>, 42 + <0x506c0000 0x400>; 43 + cache-unified; 44 + cache-size = <0x200000>; 45 + cache-sets = <512>; 46 + cache-line-size = <128>; 47 + cache-level = <2>; 48 + next-level-cache = <&l3>; 49 + }; 50 + 51 + l3: l3-cache@500c8000 { 52 + compatible = "socionext,uniphier-system-cache"; 53 + reg = <0x500c8000 0x2000>, <0x503c8100 0x8>, 54 + <0x506c8000 0x400>; 55 + cache-unified; 56 + cache-size = <0x400000>; 57 + cache-sets = <512>; 58 + cache-line-size = <256>; 59 + cache-level = <3>; 60 + };
-1
Documentation/devicetree/bindings/soc/ti/keystone-navigator-qmss.txt
··· 221 221 #size-cells = <1>; 222 222 ranges; 223 223 pdsp0@0x2a10000 { 224 - firmware = "keystone/qmss_pdsp_acc48_k2_le_1_0_0_8.fw"; 225 224 reg = <0x2a10000 0x1000>, 226 225 <0x2a0f000 0x100>, 227 226 <0x2a0c000 0x3c8>,
+3 -1
MAINTAINERS
··· 920 920 S: Maintained 921 921 F: arch/arm/mach-alpine/ 922 922 923 - ARM/ATMEL AT91RM9200 AND AT91SAM ARM ARCHITECTURES 923 + ARM/ATMEL AT91RM9200, AT91SAM9 AND SAMA5 SOC SUPPORT 924 924 M: Nicolas Ferre <nicolas.ferre@atmel.com> 925 925 M: Alexandre Belloni <alexandre.belloni@free-electrons.com> 926 926 M: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com> ··· 1630 1630 L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 1631 1631 S: Maintained 1632 1632 F: arch/arm/boot/dts/uniphier* 1633 + F: arch/arm/include/asm/hardware/cache-uniphier.h 1633 1634 F: arch/arm/mach-uniphier/ 1635 + F: arch/arm/mm/cache-uniphier.c 1634 1636 F: drivers/i2c/busses/i2c-uniphier* 1635 1637 F: drivers/pinctrl/uniphier/ 1636 1638 F: drivers/tty/serial/8250/8250_uniphier.c
+16 -25
arch/arm/Kconfig.debug
··· 123 123 0x80020000 | 0xf0020000 | UART8 124 124 0x80024000 | 0xf0024000 | UART9 125 125 126 - config AT91_DEBUG_LL_DBGU0 127 - bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10, 9rl, 9x5, 9n12" 128 - select DEBUG_AT91_UART 126 + config DEBUG_AT91_UART 127 + bool "Kernel low-level debugging on Atmel SoCs" 129 128 depends on ARCH_AT91 130 - depends on SOC_AT91RM9200 || SOC_AT91SAM9 129 + help 130 + Say Y here if you want the debug print routines to direct 131 + their output to the serial port on atmel devices. 131 132 132 - config AT91_DEBUG_LL_DBGU1 133 - bool "Kernel low-level debugging on 9263, 9g45 and sama5d3" 134 - select DEBUG_AT91_UART 135 - depends on ARCH_AT91 136 - depends on SOC_AT91SAM9 || SOC_SAMA5 133 + SOC DEBUG_UART_PHYS DEBUG_UART_VIRT PORT 134 + rm9200, 9260/9g20, 0xfffff200 0xfefff200 DBGU 135 + 9261/9g10, 9rl 136 + 9263, 9g45, sama5d3 0xffffee00 0xfeffee00 DBGU 137 + sama5d4 0xfc00c000 0xfb00c000 USART3 138 + sama5d4 0xfc069000 0xfb069000 DBGU 139 + sama5d2 0xf8020000 0xf7020000 UART1 137 140 138 - config AT91_DEBUG_LL_DBGU2 139 - bool "Kernel low-level debugging on sama5d4" 140 - select DEBUG_AT91_UART 141 - depends on ARCH_AT91 142 - depends on SOC_SAMA5 143 - 144 - config AT91_DEBUG_LL_DBGU3 145 - bool "Kernel low-level debugging on sama5d2" 146 - select DEBUG_AT91_UART 147 - depends on ARCH_AT91 148 - depends on SOC_SAMA5 141 + Please adjust DEBUG_UART_PHYS configuration options based on 142 + your needs. 149 143 150 144 config DEBUG_BCM2835 151 145 bool "Kernel low-level debugging on BCM2835 PL011 UART" ··· 1243 1249 1244 1250 endchoice 1245 1251 1246 - config DEBUG_AT91_UART 1247 - bool 1248 - depends on ARCH_AT91 1249 - 1250 1252 config DEBUG_EXYNOS_UART 1251 1253 bool 1252 1254 ··· 1475 1485 DEBUG_RMOBILE_SCIFA0 || DEBUG_RMOBILE_SCIFA1 || \ 1476 1486 DEBUG_RMOBILE_SCIFA4 || DEBUG_S3C24XX_UART || \ 1477 1487 DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART || \ 1478 - DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 1488 + DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0 || \ 1489 + DEBUG_AT91_UART 1479 1490 1480 1491 config DEBUG_UART_VIRT 1481 1492 hex "Virtual base address of debug UART"
+46
arch/arm/include/asm/hardware/cache-uniphier.h
··· 1 + /* 2 + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + */ 14 + 15 + #ifndef __CACHE_UNIPHIER_H 16 + #define __CACHE_UNIPHIER_H 17 + 18 + #include <linux/types.h> 19 + 20 + #ifdef CONFIG_CACHE_UNIPHIER 21 + int uniphier_cache_init(void); 22 + int uniphier_cache_l2_is_enabled(void); 23 + void uniphier_cache_l2_touch_range(unsigned long start, unsigned long end); 24 + void uniphier_cache_l2_set_locked_ways(u32 way_mask); 25 + #else 26 + static inline int uniphier_cache_init(void) 27 + { 28 + return -ENODEV; 29 + } 30 + 31 + static inline int uniphier_cache_l2_is_enabled(void) 32 + { 33 + return 0; 34 + } 35 + 36 + static inline void uniphier_cache_l2_touch_range(unsigned long start, 37 + unsigned long end) 38 + { 39 + } 40 + 41 + static inline void uniphier_cache_l2_set_locked_ways(u32 way_mask) 42 + { 43 + } 44 + #endif 45 + 46 + #endif /* __CACHE_UNIPHIER_H */
+4 -14
arch/arm/include/debug/at91.S
··· 9 9 * 10 10 */ 11 11 12 - #if defined(CONFIG_AT91_DEBUG_LL_DBGU0) 13 - #define AT91_DBGU 0xfffff200 /* AT91_BASE_DBGU0 */ 14 - #elif defined(CONFIG_AT91_DEBUG_LL_DBGU1) 15 - #define AT91_DBGU 0xffffee00 /* AT91_BASE_DBGU1 */ 16 - #elif defined(CONFIG_AT91_DEBUG_LL_DBGU2) 17 - /* On sama5d4, use USART3 as low level serial console */ 18 - #define AT91_DBGU 0xfc00c000 /* SAMA5D4_BASE_USART3 */ 19 - #else 20 - /* On sama5d2, use UART1 as low level serial console */ 21 - #define AT91_DBGU 0xf8020000 22 - #endif 23 - 24 12 #ifdef CONFIG_MMU 25 13 #define AT91_IO_P2V(x) ((x) - 0x01000000) 26 14 #else 27 15 #define AT91_IO_P2V(x) (x) 28 16 #endif 17 + 18 + #define CONFIG_DEBUG_UART_VIRT AT91_IO_P2V(CONFIG_DEBUG_UART_PHYS) 29 19 30 20 #define AT91_DBGU_SR (0x14) /* Status Register */ 31 21 #define AT91_DBGU_THR (0x1c) /* Transmitter Holding Register */ ··· 23 33 #define AT91_DBGU_TXEMPTY (1 << 9) /* Transmitter Empty */ 24 34 25 35 .macro addruart, rp, rv, tmp 26 - ldr \rp, =AT91_DBGU @ System peripherals (phys address) 27 - ldr \rv, =AT91_IO_P2V(AT91_DBGU) @ System peripherals (virt address) 36 + ldr \rp, =CONFIG_DEBUG_UART_PHYS @ System peripherals (phys address) 37 + ldr \rv, =CONFIG_DEBUG_UART_VIRT @ System peripherals (virt address) 28 38 .endm 29 39 30 40 .macro senduart,rd,rx
+3
arch/arm/kernel/irq.c
··· 39 39 #include <linux/export.h> 40 40 41 41 #include <asm/hardware/cache-l2x0.h> 42 + #include <asm/hardware/cache-uniphier.h> 42 43 #include <asm/outercache.h> 43 44 #include <asm/exception.h> 44 45 #include <asm/mach/arch.h> ··· 98 97 if (ret) 99 98 pr_err("L2C: failed to init: %d\n", ret); 100 99 } 100 + 101 + uniphier_cache_init(); 101 102 } 102 103 103 104 #ifdef CONFIG_MULTI_IRQ_HANDLER
+2
arch/arm/mach-at91/pm_suspend.S
··· 80 80 * @r2: base address of second SDRAM Controller or 0 if not present 81 81 * @r3: pm information 82 82 */ 83 + /* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */ 84 + .align 3 83 85 ENTRY(at91_pm_suspend_in_sram) 84 86 /* Save registers on stack */ 85 87 stmfd sp!, {r4 - r12, lr}
+15
arch/arm/mach-bcm/Kconfig
··· 35 35 BCM11300, BCM11320, BCM11350, BCM11360, 36 36 BCM58300, BCM58302, BCM58303, BCM58305. 37 37 38 + config ARCH_BCM_NSP 39 + bool "Broadcom Northstar Plus SoC Support" if ARCH_MULTI_V7 40 + select ARCH_BCM_IPROC 41 + select ARM_ERRATA_754322 42 + select ARM_ERRATA_775420 43 + help 44 + Support for Broadcom Northstar Plus SoC. 45 + Broadcom Northstar Plus family of SoCs are used for switching control 46 + and management applications as well as residential router/gateway 47 + applications. The SoC features dual core Cortex A9 ARM CPUs, 48 + integrating several peripheral interfaces including multiple Gigabit 49 + Ethernet PHYs, DDR3 memory, PCIE Gen-2, USB 2.0 and USB 3.0, serial and 50 + NAND flash, SATA and several other IO controllers. 51 + 38 52 config ARCH_BCM_5301X 39 53 bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7 40 54 select ARCH_BCM_IPROC ··· 161 147 select BCM7120_L2_IRQ 162 148 select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE 163 149 select ARCH_WANT_OPTIONAL_GPIOLIB 150 + select SOC_BRCMSTB 164 151 help 165 152 Say Y if you intend to run the kernel on a Broadcom ARM-based STB 166 153 chipset.
+4 -1
arch/arm/mach-bcm/Makefile
··· 1 1 # 2 - # Copyright (C) 2012-2014 Broadcom Corporation 2 + # Copyright (C) 2012-2015 Broadcom Corporation 3 3 # 4 4 # This program is free software; you can redistribute it and/or 5 5 # modify it under the terms of the GNU General Public License as ··· 12 12 13 13 # Cygnus 14 14 obj-$(CONFIG_ARCH_BCM_CYGNUS) += bcm_cygnus.o 15 + 16 + # Northstar Plus 17 + obj-$(CONFIG_ARCH_BCM_NSP) += bcm_nsp.o 15 18 16 19 # BCM281XX 17 20 obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o
+25
arch/arm/mach-bcm/bcm_nsp.c
··· 1 + /* 2 + * Copyright (C) 2015 Broadcom Corporation 3 + * 4 + * This program is free software; you can redistribute it and/or 5 + * modify it under the terms of the GNU General Public License as 6 + * published by the Free Software Foundation version 2. 7 + * 8 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any 9 + * kind, whether express or implied; without even the implied warranty 10 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + */ 13 + 14 + #include <asm/mach/arch.h> 15 + 16 + static const char *const bcm_nsp_dt_compat[] __initconst = { 17 + "brcm,nsp", 18 + NULL, 19 + }; 20 + 21 + DT_MACHINE_START(NSP_DT, "Broadcom Northstar Plus SoC") 22 + .l2c_aux_val = 0, 23 + .l2c_aux_mask = ~0, 24 + .dt_compat = bcm_nsp_dt_compat, 25 + MACHINE_END
+9
arch/arm/mach-bcm/brcmstb.c
··· 12 12 */ 13 13 14 14 #include <linux/init.h> 15 + #include <linux/irqchip.h> 15 16 #include <linux/of_platform.h> 17 + #include <linux/soc/brcmstb/brcmstb.h> 16 18 17 19 #include <asm/mach-types.h> 18 20 #include <asm/mach/arch.h> 21 + 22 + static void __init brcmstb_init_irq(void) 23 + { 24 + irqchip_init(); 25 + brcmstb_biuctrl_init(); 26 + } 19 27 20 28 static const char *const brcmstb_match[] __initconst = { 21 29 "brcm,bcm7445", ··· 33 25 34 26 DT_MACHINE_START(BRCMSTB, "Broadcom STB (Flattened Device Tree)") 35 27 .dt_compat = brcmstb_match, 28 + .init_irq = brcmstb_init_irq, 36 29 MACHINE_END
+6
arch/arm/mach-berlin/berlin.c
··· 18 18 #include <asm/hardware/cache-l2x0.h> 19 19 #include <asm/mach/arch.h> 20 20 21 + static void __init berlin_init_late(void) 22 + { 23 + platform_device_register_simple("cpufreq-dt", -1, NULL, 0); 24 + } 25 + 21 26 static const char * const berlin_dt_compat[] = { 22 27 "marvell,berlin", 23 28 NULL, ··· 30 25 31 26 DT_MACHINE_START(BERLIN_DT, "Marvell Berlin") 32 27 .dt_compat = berlin_dt_compat, 28 + .init_late = berlin_init_late, 33 29 /* 34 30 * with DT probing for L2CCs, berlin_init_machine can be removed. 35 31 * Note: 88DE3005 (Armada 1500-mini) uses pl310 l2cc
+35 -3
arch/arm/mach-berlin/platsmp.c
··· 14 14 #include <linux/of_address.h> 15 15 16 16 #include <asm/cacheflush.h> 17 + #include <asm/cp15.h> 17 18 #include <asm/smp_plat.h> 18 19 #include <asm/smp_scu.h> 19 20 20 - #define CPU_RESET 0x00 21 + /* 22 + * There are two reset registers, one with self-clearing (SC) 23 + * reset and one with non-self-clearing reset (NON_SC). 24 + */ 25 + #define CPU_RESET_SC 0x00 26 + #define CPU_RESET_NON_SC 0x20 21 27 22 28 #define RESET_VECT 0x00 23 29 #define SW_RESET_ADDR 0x94 ··· 36 30 { 37 31 u32 val; 38 32 39 - val = readl(cpu_ctrl + CPU_RESET); 33 + val = readl(cpu_ctrl + CPU_RESET_NON_SC); 34 + val &= ~BIT(cpu_logical_map(cpu)); 35 + writel(val, cpu_ctrl + CPU_RESET_NON_SC); 40 36 val |= BIT(cpu_logical_map(cpu)); 41 - writel(val, cpu_ctrl + CPU_RESET); 37 + writel(val, cpu_ctrl + CPU_RESET_NON_SC); 42 38 } 43 39 44 40 static int berlin_boot_secondary(unsigned int cpu, struct task_struct *idle) ··· 99 91 iounmap(scu_base); 100 92 } 101 93 94 + #ifdef CONFIG_HOTPLUG_CPU 95 + static void berlin_cpu_die(unsigned int cpu) 96 + { 97 + v7_exit_coherency_flush(louis); 98 + while (1) 99 + cpu_do_idle(); 100 + } 101 + 102 + static int berlin_cpu_kill(unsigned int cpu) 103 + { 104 + u32 val; 105 + 106 + val = readl(cpu_ctrl + CPU_RESET_NON_SC); 107 + val &= ~BIT(cpu_logical_map(cpu)); 108 + writel(val, cpu_ctrl + CPU_RESET_NON_SC); 109 + 110 + return 1; 111 + } 112 + #endif 113 + 102 114 static struct smp_operations berlin_smp_ops __initdata = { 103 115 .smp_prepare_cpus = berlin_smp_prepare_cpus, 104 116 .smp_boot_secondary = berlin_boot_secondary, 117 + #ifdef CONFIG_HOTPLUG_CPU 118 + .cpu_die = berlin_cpu_die, 119 + .cpu_kill = berlin_cpu_kill, 120 + #endif 105 121 }; 106 122 CPU_METHOD_OF_DECLARE(berlin_smp, "marvell,berlin-smp", &berlin_smp_ops);
+3
arch/arm/mach-digicolor/Kconfig
··· 1 1 config ARCH_DIGICOLOR 2 2 bool "Conexant Digicolor SoC Support" 3 3 depends on ARCH_MULTI_V7 4 + select ARCH_REQUIRE_GPIOLIB 4 5 select CLKSRC_MMIO 5 6 select DIGICOLOR_TIMER 6 7 select GENERIC_IRQ_CHIP 7 8 select MFD_SYSCON 9 + select PINCTRL 10 + select PINCTRL_DIGICOLOR
+1
arch/arm/mach-imx/common.h
··· 131 131 void imx6dl_pm_init(void); 132 132 void imx6sl_pm_init(void); 133 133 void imx6sx_pm_init(void); 134 + void imx6ul_pm_init(void); 134 135 135 136 #ifdef CONFIG_PM 136 137 void imx51_pm_init(void);
+9
arch/arm/mach-imx/mach-imx6ul.c
··· 67 67 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 68 68 imx6ul_enet_init(); 69 69 imx_anatop_init(); 70 + imx6ul_pm_init(); 70 71 } 71 72 72 73 static void __init imx6ul_init_irq(void) ··· 75 74 imx_init_revision_from_anatop(); 76 75 imx_src_init(); 77 76 irqchip_init(); 77 + imx6_pm_ccm_init("fsl,imx6ul-ccm"); 78 + } 79 + 80 + static void __init imx6ul_init_late(void) 81 + { 82 + if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) 83 + platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0); 78 84 } 79 85 80 86 static const char *imx6ul_dt_compat[] __initconst = { ··· 92 84 DT_MACHINE_START(IMX6UL, "Freescale i.MX6 Ultralite (Device Tree)") 93 85 .init_irq = imx6ul_init_irq, 94 86 .init_machine = imx6ul_init_machine, 87 + .init_late = imx6ul_init_late, 95 88 .dt_compat = imx6ul_dt_compat, 96 89 MACHINE_END
+74
arch/arm/mach-imx/mach-imx7d.c
··· 6 6 * published by the Free Software Foundation. 7 7 */ 8 8 #include <linux/irqchip.h> 9 + #include <linux/mfd/syscon.h> 10 + #include <linux/mfd/syscon/imx7-iomuxc-gpr.h> 9 11 #include <linux/of_platform.h> 12 + #include <linux/phy.h> 13 + #include <linux/regmap.h> 14 + 10 15 #include <asm/mach/arch.h> 11 16 #include <asm/mach/map.h> 12 17 13 18 #include "common.h" 19 + 20 + static int ar8031_phy_fixup(struct phy_device *dev) 21 + { 22 + u16 val; 23 + 24 + /* Set RGMII IO voltage to 1.8V */ 25 + phy_write(dev, 0x1d, 0x1f); 26 + phy_write(dev, 0x1e, 0x8); 27 + 28 + /* disable phy AR8031 SmartEEE function. */ 29 + phy_write(dev, 0xd, 0x3); 30 + phy_write(dev, 0xe, 0x805d); 31 + phy_write(dev, 0xd, 0x4003); 32 + val = phy_read(dev, 0xe); 33 + val &= ~(0x1 << 8); 34 + phy_write(dev, 0xe, val); 35 + 36 + /* introduce tx clock delay */ 37 + phy_write(dev, 0x1d, 0x5); 38 + val = phy_read(dev, 0x1e); 39 + val |= 0x0100; 40 + phy_write(dev, 0x1e, val); 41 + 42 + return 0; 43 + } 44 + 45 + static int bcm54220_phy_fixup(struct phy_device *dev) 46 + { 47 + /* enable RXC skew select RGMII copper mode */ 48 + phy_write(dev, 0x1e, 0x21); 49 + phy_write(dev, 0x1f, 0x7ea8); 50 + phy_write(dev, 0x1e, 0x2f); 51 + phy_write(dev, 0x1f, 0x71b7); 52 + 53 + return 0; 54 + } 55 + 56 + #define PHY_ID_AR8031 0x004dd074 57 + #define PHY_ID_BCM54220 0x600d8589 58 + 59 + static void __init imx7d_enet_phy_init(void) 60 + { 61 + if (IS_BUILTIN(CONFIG_PHYLIB)) { 62 + phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffff, 63 + ar8031_phy_fixup); 64 + phy_register_fixup_for_uid(PHY_ID_BCM54220, 0xffffffff, 65 + bcm54220_phy_fixup); 66 + } 67 + } 68 + 69 + static void __init imx7d_enet_clk_sel(void) 70 + { 71 + struct regmap *gpr; 72 + 73 + gpr = syscon_regmap_lookup_by_compatible("fsl,imx7d-iomuxc-gpr"); 74 + if (!IS_ERR(gpr)) { 75 + regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_TX_CLK_SEL_MASK, 0); 76 + regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_ENET_CLK_DIR_MASK, 0); 77 + } else { 78 + pr_err("failed to find fsl,imx7d-iomux-gpr regmap\n"); 79 + } 80 + } 81 + 82 + static inline void imx7d_enet_init(void) 83 + { 84 + imx7d_enet_phy_init(); 85 + imx7d_enet_clk_sel(); 86 + } 14 87 15 88 static void __init imx7d_init_machine(void) 16 89 { ··· 95 22 96 23 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); 97 24 imx_anatop_init(); 25 + imx7d_enet_init(); 98 26 } 99 27 100 28 static void __init imx7d_init_irq(void)
+40 -6
arch/arm/mach-imx/pm-imx6.c
··· 93 93 const char *src_compat; 94 94 const char *iomuxc_compat; 95 95 const char *gpc_compat; 96 + const char *pl310_compat; 96 97 const u32 mmdc_io_num; 97 98 const u32 *mmdc_io_offset; 98 99 }; ··· 138 137 0x330, 0x334, 0x338, 0x33c, /* SDQS0 ~ SDQS3 */ 139 138 }; 140 139 140 + static const u32 imx6ul_mmdc_io_offset[] __initconst = { 141 + 0x244, 0x248, 0x24c, 0x250, /* DQM0, DQM1, RAS, CAS */ 142 + 0x27c, 0x498, 0x4a4, 0x490, /* SDCLK0, GPR_B0DS-B1DS, GPR_ADDS */ 143 + 0x280, 0x284, 0x260, 0x264, /* SDQS0~1, SODT0, SODT1 */ 144 + 0x494, 0x4b0, /* MODE_CTL, MODE, */ 145 + }; 146 + 141 147 static const struct imx6_pm_socdata imx6q_pm_data __initconst = { 142 148 .mmdc_compat = "fsl,imx6q-mmdc", 143 149 .src_compat = "fsl,imx6q-src", 144 150 .iomuxc_compat = "fsl,imx6q-iomuxc", 145 151 .gpc_compat = "fsl,imx6q-gpc", 152 + .pl310_compat = "arm,pl310-cache", 146 153 .mmdc_io_num = ARRAY_SIZE(imx6q_mmdc_io_offset), 147 154 .mmdc_io_offset = imx6q_mmdc_io_offset, 148 155 }; ··· 160 151 .src_compat = "fsl,imx6q-src", 161 152 .iomuxc_compat = "fsl,imx6dl-iomuxc", 162 153 .gpc_compat = "fsl,imx6q-gpc", 154 + .pl310_compat = "arm,pl310-cache", 163 155 .mmdc_io_num = ARRAY_SIZE(imx6dl_mmdc_io_offset), 164 156 .mmdc_io_offset = imx6dl_mmdc_io_offset, 165 157 }; ··· 170 160 .src_compat = "fsl,imx6sl-src", 171 161 .iomuxc_compat = "fsl,imx6sl-iomuxc", 172 162 .gpc_compat = "fsl,imx6sl-gpc", 163 + .pl310_compat = "arm,pl310-cache", 173 164 .mmdc_io_num = ARRAY_SIZE(imx6sl_mmdc_io_offset), 174 165 .mmdc_io_offset = imx6sl_mmdc_io_offset, 175 166 }; ··· 180 169 .src_compat = "fsl,imx6sx-src", 181 170 .iomuxc_compat = "fsl,imx6sx-iomuxc", 182 171 .gpc_compat = "fsl,imx6sx-gpc", 172 + .pl310_compat = "arm,pl310-cache", 183 173 .mmdc_io_num = ARRAY_SIZE(imx6sx_mmdc_io_offset), 184 174 .mmdc_io_offset = imx6sx_mmdc_io_offset, 175 + }; 176 + 177 + static const struct imx6_pm_socdata imx6ul_pm_data __initconst = { 178 + .mmdc_compat = "fsl,imx6ul-mmdc", 179 + .src_compat = "fsl,imx6ul-src", 180 + .iomuxc_compat = "fsl,imx6ul-iomuxc", 181 + .gpc_compat = "fsl,imx6ul-gpc", 182 + .pl310_compat = NULL, 183 + .mmdc_io_num = ARRAY_SIZE(imx6ul_mmdc_io_offset), 184 + .mmdc_io_offset = imx6ul_mmdc_io_offset, 185 185 }; 186 186 187 187 /* ··· 312 290 val |= BM_CLPCR_SBYOS; 313 291 if (cpu_is_imx6sl()) 314 292 val |= BM_CLPCR_BYPASS_PMIC_READY; 315 - if (cpu_is_imx6sl() || cpu_is_imx6sx()) 293 + if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul()) 316 294 val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS; 317 295 else 318 296 val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS; ··· 352 330 * as we need to float DDR IO. 353 331 */ 354 332 local_flush_tlb_all(); 333 + /* check if need to flush internal L2 cache */ 334 + if (!((struct imx6_cpu_pm_info *) 335 + suspend_ocram_base)->l2_base.vbase) 336 + flush_cache_all(); 355 337 imx6_suspend_in_ocram_fn(suspend_ocram_base); 356 338 } 357 339 ··· 496 470 suspend_ocram_base = __arm_ioremap_exec(ocram_pbase, 497 471 MX6Q_SUSPEND_OCRAM_SIZE, false); 498 472 473 + memset(suspend_ocram_base, 0, sizeof(*pm_info)); 499 474 pm_info = suspend_ocram_base; 500 475 pm_info->pbase = ocram_pbase; 501 476 pm_info->resume_addr = virt_to_phys(v7_cpu_resume); ··· 532 505 goto gpc_map_failed; 533 506 } 534 507 535 - ret = imx6_pm_get_base(&pm_info->l2_base, "arm,pl310-cache"); 536 - if (ret) { 537 - pr_warn("%s: failed to get pl310-cache base %d!\n", 538 - __func__, ret); 539 - goto pl310_cache_map_failed; 508 + if (socdata->pl310_compat) { 509 + ret = imx6_pm_get_base(&pm_info->l2_base, socdata->pl310_compat); 510 + if (ret) { 511 + pr_warn("%s: failed to get pl310-cache base %d!\n", 512 + __func__, ret); 513 + goto pl310_cache_map_failed; 514 + } 540 515 } 541 516 542 517 pm_info->ddr_type = imx_mmdc_get_ddr_type(); ··· 638 609 void __init imx6sx_pm_init(void) 639 610 { 640 611 imx6_pm_common_init(&imx6sx_pm_data); 612 + } 613 + 614 + void __init imx6ul_pm_init(void) 615 + { 616 + imx6_pm_common_init(&imx6ul_pm_data); 641 617 }
+3
arch/arm/mach-imx/suspend-imx6.S
··· 79 79 /* sync L2 cache to drain L2's buffers to DRAM. */ 80 80 #ifdef CONFIG_CACHE_L2X0 81 81 ldr r11, [r0, #PM_INFO_MX6Q_L2_V_OFFSET] 82 + teq r11, #0 83 + beq 6f 82 84 mov r6, #0x0 83 85 str r6, [r11, #L2X0_CACHE_SYNC] 84 86 1: 85 87 ldr r6, [r11, #L2X0_CACHE_SYNC] 86 88 ands r6, r6, #0x1 87 89 bne 1b 90 + 6: 88 91 #endif 89 92 90 93 .endm
+3
arch/arm/mach-mediatek/Makefile
··· 1 + ifeq ($(CONFIG_SMP),y) 2 + obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o 3 + endif 1 4 obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o
+27
arch/arm/mach-mediatek/mediatek.c
··· 16 16 */ 17 17 #include <linux/init.h> 18 18 #include <asm/mach/arch.h> 19 + #include <linux/of.h> 20 + #include <linux/clk-provider.h> 21 + #include <linux/clocksource.h> 22 + 23 + 24 + #define GPT6_CON_MT65xx 0x10008060 25 + #define GPT_ENABLE 0x31 26 + 27 + static void __init mediatek_timer_init(void) 28 + { 29 + void __iomem *gpt_base; 30 + 31 + if (of_machine_is_compatible("mediatek,mt6589") || 32 + of_machine_is_compatible("mediatek,mt8135") || 33 + of_machine_is_compatible("mediatek,mt8127")) { 34 + /* turn on GPT6 which ungates arch timer clocks */ 35 + gpt_base = ioremap(GPT6_CON_MT65xx, 0x04); 36 + 37 + /* enable clock and set to free-run */ 38 + writel(GPT_ENABLE, gpt_base); 39 + iounmap(gpt_base); 40 + } 41 + 42 + of_clk_init(NULL); 43 + clocksource_probe(); 44 + }; 19 45 20 46 static const char * const mediatek_board_dt_compat[] = { 21 47 "mediatek,mt6589", ··· 53 27 54 28 DT_MACHINE_START(MEDIATEK_DT, "Mediatek Cortex-A7 (Device Tree)") 55 29 .dt_compat = mediatek_board_dt_compat, 30 + .init_time = mediatek_timer_init, 56 31 MACHINE_END
+141
arch/arm/mach-mediatek/platsmp.c
··· 1 + /* 2 + * arch/arm/mach-mediatek/platsmp.c 3 + * 4 + * Copyright (c) 2014 Mediatek Inc. 5 + * Author: Shunli Wang <shunli.wang@mediatek.com> 6 + * Yingjoe Chen <yingjoe.chen@mediatek.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + */ 18 + #include <linux/io.h> 19 + #include <linux/memblock.h> 20 + #include <linux/of.h> 21 + #include <linux/of_address.h> 22 + #include <linux/string.h> 23 + #include <linux/threads.h> 24 + 25 + #define MTK_MAX_CPU 8 26 + #define MTK_SMP_REG_SIZE 0x1000 27 + 28 + struct mtk_smp_boot_info { 29 + unsigned long smp_base; 30 + unsigned int jump_reg; 31 + unsigned int core_keys[MTK_MAX_CPU - 1]; 32 + unsigned int core_regs[MTK_MAX_CPU - 1]; 33 + }; 34 + 35 + static const struct mtk_smp_boot_info mtk_mt8135_tz_boot = { 36 + 0x80002000, 0x3fc, 37 + { 0x534c4131, 0x4c415332, 0x41534c33 }, 38 + { 0x3f8, 0x3f8, 0x3f8 }, 39 + }; 40 + 41 + static const struct mtk_smp_boot_info mtk_mt6589_boot = { 42 + 0x10002000, 0x34, 43 + { 0x534c4131, 0x4c415332, 0x41534c33 }, 44 + { 0x38, 0x3c, 0x40 }, 45 + }; 46 + 47 + static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = { 48 + { .compatible = "mediatek,mt8135", .data = &mtk_mt8135_tz_boot }, 49 + { .compatible = "mediatek,mt8127", .data = &mtk_mt8135_tz_boot }, 50 + }; 51 + 52 + static const struct of_device_id mtk_smp_boot_infos[] __initconst = { 53 + { .compatible = "mediatek,mt6589", .data = &mtk_mt6589_boot }, 54 + }; 55 + 56 + static void __iomem *mtk_smp_base; 57 + static const struct mtk_smp_boot_info *mtk_smp_info; 58 + 59 + static int mtk_boot_secondary(unsigned int cpu, struct task_struct *idle) 60 + { 61 + if (!mtk_smp_base) 62 + return -EINVAL; 63 + 64 + if (!mtk_smp_info->core_keys[cpu-1]) 65 + return -EINVAL; 66 + 67 + writel_relaxed(mtk_smp_info->core_keys[cpu-1], 68 + mtk_smp_base + mtk_smp_info->core_regs[cpu-1]); 69 + 70 + arch_send_wakeup_ipi_mask(cpumask_of(cpu)); 71 + 72 + return 0; 73 + } 74 + 75 + static void __init __mtk_smp_prepare_cpus(unsigned int max_cpus, int trustzone) 76 + { 77 + int i, num; 78 + const struct of_device_id *infos; 79 + 80 + if (trustzone) { 81 + num = ARRAY_SIZE(mtk_tz_smp_boot_infos); 82 + infos = mtk_tz_smp_boot_infos; 83 + } else { 84 + num = ARRAY_SIZE(mtk_smp_boot_infos); 85 + infos = mtk_smp_boot_infos; 86 + } 87 + 88 + /* Find smp boot info for this SoC */ 89 + for (i = 0; i < num; i++) { 90 + if (of_machine_is_compatible(infos[i].compatible)) { 91 + mtk_smp_info = infos[i].data; 92 + break; 93 + } 94 + } 95 + 96 + if (!mtk_smp_info) { 97 + pr_err("%s: Device is not supported\n", __func__); 98 + return; 99 + } 100 + 101 + if (trustzone) { 102 + /* smp_base(trustzone-bootinfo) is reserved by device tree */ 103 + mtk_smp_base = phys_to_virt(mtk_smp_info->smp_base); 104 + } else { 105 + mtk_smp_base = ioremap(mtk_smp_info->smp_base, MTK_SMP_REG_SIZE); 106 + if (!mtk_smp_base) { 107 + pr_err("%s: Can't remap %lx\n", __func__, 108 + mtk_smp_info->smp_base); 109 + return; 110 + } 111 + } 112 + 113 + /* 114 + * write the address of slave startup address into the system-wide 115 + * jump register 116 + */ 117 + writel_relaxed(virt_to_phys(secondary_startup_arm), 118 + mtk_smp_base + mtk_smp_info->jump_reg); 119 + } 120 + 121 + static void __init mtk_tz_smp_prepare_cpus(unsigned int max_cpus) 122 + { 123 + __mtk_smp_prepare_cpus(max_cpus, 1); 124 + } 125 + 126 + static void __init mtk_smp_prepare_cpus(unsigned int max_cpus) 127 + { 128 + __mtk_smp_prepare_cpus(max_cpus, 0); 129 + } 130 + 131 + static struct smp_operations mt81xx_tz_smp_ops __initdata = { 132 + .smp_prepare_cpus = mtk_tz_smp_prepare_cpus, 133 + .smp_boot_secondary = mtk_boot_secondary, 134 + }; 135 + CPU_METHOD_OF_DECLARE(mt81xx_tz_smp, "mediatek,mt81xx-tz-smp", &mt81xx_tz_smp_ops); 136 + 137 + static struct smp_operations mt6589_smp_ops __initdata = { 138 + .smp_prepare_cpus = mtk_smp_prepare_cpus, 139 + .smp_boot_secondary = mtk_boot_secondary, 140 + }; 141 + CPU_METHOD_OF_DECLARE(mt6589_smp, "mediatek,mt6589-smp", &mt6589_smp_ops);
+5
arch/arm/mach-meson/Kconfig
··· 19 19 default ARCH_MESON 20 20 select MESON6_TIMER 21 21 22 + config MACH_MESON8B 23 + bool "Amlogic Meson8b SoCs support" 24 + default ARCH_MESON 25 + select MESON6_TIMER 26 + 22 27 endif
+1
arch/arm/mach-meson/meson.c
··· 19 19 static const char * const meson_common_board_compat[] = { 20 20 "amlogic,meson6", 21 21 "amlogic,meson8", 22 + "amlogic,meson8b", 22 23 NULL, 23 24 }; 24 25
+60
arch/arm/mach-mvebu/coherency.c
··· 40 40 unsigned long coherency_phys_base; 41 41 void __iomem *coherency_base; 42 42 static void __iomem *coherency_cpu_base; 43 + static void __iomem *cpu_config_base; 43 44 44 45 /* Coherency fabric registers */ 45 46 #define IO_SYNC_BARRIER_CTL_OFFSET 0x0 ··· 66 65 int ll_enable_coherency(void); 67 66 void ll_add_cpu_to_smp_group(void); 68 67 68 + #define CPU_CONFIG_SHARED_L2 BIT(16) 69 + 70 + /* 71 + * Disable the "Shared L2 Present" bit in CPU Configuration register 72 + * on Armada XP. 73 + * 74 + * The "Shared L2 Present" bit affects the "level of coherence" value 75 + * in the clidr CP15 register. Cache operation functions such as 76 + * "flush all" and "invalidate all" operate on all the cache levels 77 + * that included in the defined level of coherence. When HW I/O 78 + * coherency is used, this bit causes unnecessary flushes of the L2 79 + * cache. 80 + */ 81 + static void armada_xp_clear_shared_l2(void) 82 + { 83 + u32 reg; 84 + 85 + if (!cpu_config_base) 86 + return; 87 + 88 + reg = readl(cpu_config_base); 89 + reg &= ~CPU_CONFIG_SHARED_L2; 90 + writel(reg, cpu_config_base); 91 + } 92 + 69 93 static int mvebu_hwcc_notifier(struct notifier_block *nb, 70 94 unsigned long event, void *__dev) 71 95 { ··· 111 85 .notifier_call = mvebu_hwcc_notifier, 112 86 }; 113 87 88 + static int armada_xp_clear_shared_l2_notifier_func(struct notifier_block *nfb, 89 + unsigned long action, void *hcpu) 90 + { 91 + if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) 92 + armada_xp_clear_shared_l2(); 93 + 94 + return NOTIFY_OK; 95 + } 96 + 97 + static struct notifier_block armada_xp_clear_shared_l2_notifier = { 98 + .notifier_call = armada_xp_clear_shared_l2_notifier_func, 99 + .priority = 100, 100 + }; 101 + 114 102 static void __init armada_370_coherency_init(struct device_node *np) 115 103 { 116 104 struct resource res; 105 + struct device_node *cpu_config_np; 117 106 118 107 of_address_to_resource(np, 0, &res); 119 108 coherency_phys_base = res.start; ··· 141 100 sync_cache_w(&coherency_phys_base); 142 101 coherency_base = of_iomap(np, 0); 143 102 coherency_cpu_base = of_iomap(np, 1); 103 + 104 + cpu_config_np = of_find_compatible_node(NULL, NULL, 105 + "marvell,armada-xp-cpu-config"); 106 + if (!cpu_config_np) 107 + goto exit; 108 + 109 + cpu_config_base = of_iomap(cpu_config_np, 0); 110 + if (!cpu_config_base) { 111 + of_node_put(cpu_config_np); 112 + goto exit; 113 + } 114 + 115 + of_node_put(cpu_config_np); 116 + 117 + register_cpu_notifier(&armada_xp_clear_shared_l2_notifier); 118 + 119 + exit: 144 120 set_cpu_coherent(); 145 121 } 146 122 ··· 262 204 pr_warn("Coherency fabric is not initialized\n"); 263 205 return 1; 264 206 } 207 + 208 + armada_xp_clear_shared_l2(); 265 209 ll_add_cpu_to_smp_group(); 266 210 return ll_enable_coherency(); 267 211 }
+26 -3
arch/arm/mach-mvebu/pmsu.c
··· 379 379 380 380 static struct platform_device mvebu_v7_cpuidle_device; 381 381 382 + static int broken_idle(struct device_node *np) 383 + { 384 + if (of_property_read_bool(np, "broken-idle")) { 385 + pr_warn("CPU idle is currently broken: disabling\n"); 386 + return 1; 387 + } 388 + 389 + return 0; 390 + } 391 + 382 392 static __init int armada_370_cpuidle_init(void) 383 393 { 384 394 struct device_node *np; ··· 397 387 np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric"); 398 388 if (!np) 399 389 return -ENODEV; 400 - of_node_put(np); 390 + 391 + if (broken_idle(np)) 392 + goto end; 401 393 402 394 /* 403 395 * On Armada 370, there is "a slow exit process from the deep ··· 418 406 mvebu_v7_cpuidle_device.dev.platform_data = armada_370_xp_cpu_suspend; 419 407 mvebu_v7_cpuidle_device.name = "cpuidle-armada-370"; 420 408 409 + end: 410 + of_node_put(np); 421 411 return 0; 422 412 } 423 413 ··· 436 422 "marvell,armada-380-coherency-fabric"); 437 423 if (!np) 438 424 return -ENODEV; 425 + 426 + if (broken_idle(np)) 427 + goto end; 428 + 439 429 of_node_put(np); 440 430 441 431 np = of_find_compatible_node(NULL, NULL, ··· 448 430 return -ENODEV; 449 431 mpsoc_base = of_iomap(np, 0); 450 432 BUG_ON(!mpsoc_base); 451 - of_node_put(np); 452 433 453 434 /* Set up reset mask when powering down the cpus */ 454 435 reg = readl(mpsoc_base + MPCORE_RESET_CTL); ··· 467 450 mvebu_v7_cpuidle_device.dev.platform_data = armada_38x_cpu_suspend; 468 451 mvebu_v7_cpuidle_device.name = "cpuidle-armada-38x"; 469 452 453 + end: 454 + of_node_put(np); 470 455 return 0; 471 456 } 472 457 ··· 479 460 np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric"); 480 461 if (!np) 481 462 return -ENODEV; 482 - of_node_put(np); 463 + 464 + if (broken_idle(np)) 465 + goto end; 483 466 484 467 mvebu_cpu_resume = armada_370_xp_cpu_resume; 485 468 mvebu_v7_cpuidle_device.dev.platform_data = armada_370_xp_cpu_suspend; 486 469 mvebu_v7_cpuidle_device.name = "cpuidle-armada-xp"; 487 470 471 + end: 472 + of_node_put(np); 488 473 return 0; 489 474 } 490 475
+3
arch/arm/mach-orion5x/Kconfig
··· 45 45 46 46 config MACH_DNS323 47 47 bool "D-Link DNS-323" 48 + select GENERIC_NET_UTILS 48 49 select I2C_BOARDINFO 49 50 help 50 51 Say 'Y' here if you want your kernel to support the ··· 53 52 54 53 config MACH_TS209 55 54 bool "QNAP TS-109/TS-209" 55 + select GENERIC_NET_UTILS 56 56 help 57 57 Say 'Y' here if you want your kernel to support the 58 58 QNAP TS-109/TS-209 platform. ··· 95 93 96 94 config MACH_TS409 97 95 bool "QNAP TS-409" 96 + select GENERIC_NET_UTILS 98 97 help 99 98 Say 'Y' here if you want your kernel to support the 100 99 QNAP TS-409 platform.
+3 -50
arch/arm/mach-orion5x/dns323-setup.c
··· 173 173 .phy_addr = MV643XX_ETH_PHY_ADDR(8), 174 174 }; 175 175 176 - /* dns323_parse_hex_*() taken from tsx09-common.c; should a common copy of these 177 - * functions be kept somewhere? 178 - */ 179 - static int __init dns323_parse_hex_nibble(char n) 180 - { 181 - if (n >= '0' && n <= '9') 182 - return n - '0'; 183 - 184 - if (n >= 'A' && n <= 'F') 185 - return n - 'A' + 10; 186 - 187 - if (n >= 'a' && n <= 'f') 188 - return n - 'a' + 10; 189 - 190 - return -1; 191 - } 192 - 193 - static int __init dns323_parse_hex_byte(const char *b) 194 - { 195 - int hi; 196 - int lo; 197 - 198 - hi = dns323_parse_hex_nibble(b[0]); 199 - lo = dns323_parse_hex_nibble(b[1]); 200 - 201 - if (hi < 0 || lo < 0) 202 - return -1; 203 - 204 - return (hi << 4) | lo; 205 - } 206 - 207 176 static int __init dns323_read_mac_addr(void) 208 177 { 209 178 u_int8_t addr[6]; 210 - int i; 211 - char *mac_page; 179 + void __iomem *mac_page; 212 180 213 181 /* MAC address is stored as a regular ol' string in /dev/mtdblock4 214 182 * (0x007d0000-0x00800000) starting at offset 196480 (0x2ff80). ··· 185 217 if (!mac_page) 186 218 return -ENOMEM; 187 219 188 - /* Sanity check the string we're looking at */ 189 - for (i = 0; i < 5; i++) { 190 - if (*(mac_page + (i * 3) + 2) != ':') { 191 - goto error_fail; 192 - } 193 - } 194 - 195 - for (i = 0; i < 6; i++) { 196 - int byte; 197 - 198 - byte = dns323_parse_hex_byte(mac_page + (i * 3)); 199 - if (byte < 0) { 200 - goto error_fail; 201 - } 202 - 203 - addr[i] = byte; 204 - } 220 + if (!mac_pton((__force const char *) mac_page, addr)) 221 + goto error_fail; 205 222 206 223 iounmap(mac_page); 207 224 printk("DNS-323: Found ethernet MAC address: %pM\n", addr);
+4 -45
arch/arm/mach-orion5x/tsx09-common.c
··· 53 53 .phy_addr = MV643XX_ETH_PHY_ADDR(8), 54 54 }; 55 55 56 - static int __init qnap_tsx09_parse_hex_nibble(char n) 57 - { 58 - if (n >= '0' && n <= '9') 59 - return n - '0'; 60 - 61 - if (n >= 'A' && n <= 'F') 62 - return n - 'A' + 10; 63 - 64 - if (n >= 'a' && n <= 'f') 65 - return n - 'a' + 10; 66 - 67 - return -1; 68 - } 69 - 70 - static int __init qnap_tsx09_parse_hex_byte(const char *b) 71 - { 72 - int hi; 73 - int lo; 74 - 75 - hi = qnap_tsx09_parse_hex_nibble(b[0]); 76 - lo = qnap_tsx09_parse_hex_nibble(b[1]); 77 - 78 - if (hi < 0 || lo < 0) 79 - return -1; 80 - 81 - return (hi << 4) | lo; 82 - } 83 - 84 56 static int __init qnap_tsx09_check_mac_addr(const char *addr_str) 85 57 { 86 58 u_int8_t addr[6]; 87 - int i; 88 59 89 - for (i = 0; i < 6; i++) { 90 - int byte; 91 - 92 - /* 93 - * Enforce "xx:xx:xx:xx:xx:xx\n" format. 94 - */ 95 - if (addr_str[(i * 3) + 2] != ((i < 5) ? ':' : '\n')) 96 - return -1; 97 - 98 - byte = qnap_tsx09_parse_hex_byte(addr_str + (i * 3)); 99 - if (byte < 0) 100 - return -1; 101 - addr[i] = byte; 102 - } 60 + if (!mac_pton(addr_str, addr)) 61 + return -1; 103 62 104 63 printk(KERN_INFO "tsx09: found ethernet mac address %pM\n", addr); 105 64 ··· 77 118 unsigned long addr; 78 119 79 120 for (addr = mem_base; addr < (mem_base + size); addr += 1024) { 80 - char *nor_page; 121 + void __iomem *nor_page; 81 122 int ret = 0; 82 123 83 124 nor_page = ioremap(addr, 1024); 84 125 if (nor_page != NULL) { 85 - ret = qnap_tsx09_check_mac_addr(nor_page); 126 + ret = qnap_tsx09_check_mac_addr((__force const char *)nor_page); 86 127 iounmap(nor_page); 87 128 } 88 129
+7 -3
arch/arm/mach-s3c24xx/mach-h1940.c
··· 25 25 #include <linux/gpio.h> 26 26 #include <linux/input.h> 27 27 #include <linux/gpio_keys.h> 28 + #include <linux/pwm.h> 28 29 #include <linux/pwm_backlight.h> 29 30 #include <linux/i2c.h> 30 31 #include <linux/leds.h> ··· 470 469 .ocr_avail = MMC_VDD_32_33, 471 470 }; 472 471 472 + static struct pwm_lookup h1940_pwm_lookup[] = { 473 + PWM_LOOKUP("samsung-pwm", 0, "pwm-backlight", NULL, 36296, 474 + PWM_POLARITY_NORMAL), 475 + }; 476 + 473 477 static int h1940_backlight_init(struct device *dev) 474 478 { 475 479 gpio_request(S3C2410_GPB(0), "Backlight"); ··· 509 503 510 504 511 505 static struct platform_pwm_backlight_data backlight_data = { 512 - .pwm_id = 0, 513 506 .max_brightness = 100, 514 507 .dft_brightness = 50, 515 - /* tcnt = 0x31 */ 516 - .pwm_period_ns = 36296, 517 508 .enable_gpio = -1, 518 509 .init = h1940_backlight_init, 519 510 .notify = h1940_backlight_notify, ··· 728 725 gpio_request(H1940_LATCH_SD_POWER, "SD power"); 729 726 gpio_direction_output(H1940_LATCH_SD_POWER, 0); 730 727 728 + pwm_add_table(h1940_pwm_lookup, ARRAY_SIZE(h1940_pwm_lookup)); 731 729 platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices)); 732 730 733 731 gpio_request(S3C2410_GPA(1), "Red LED blink");
+6 -2
arch/arm/mach-s3c24xx/mach-rx1950.c
··· 375 375 376 376 }; 377 377 378 + static struct pwm_lookup rx1950_pwm_lookup[] = { 379 + PWM_LOOKUP("samsung-pwm", 0, "pwm-backlight.0", NULL, 48000, 380 + PWM_POLARITY_NORMAL), 381 + }; 382 + 378 383 static struct pwm_device *lcd_pwm; 379 384 380 385 static void rx1950_lcd_power(int enable) ··· 525 520 } 526 521 527 522 static struct platform_pwm_backlight_data rx1950_backlight_data = { 528 - .pwm_id = 0, 529 523 .max_brightness = 24, 530 524 .dft_brightness = 4, 531 - .pwm_period_ns = 48000, 532 525 .enable_gpio = -1, 533 526 .init = rx1950_backlight_init, 534 527 .notify = rx1950_backlight_notify, ··· 795 792 gpio_direction_output(S3C2410_GPA(4), 0); 796 793 gpio_direction_output(S3C2410_GPJ(6), 0); 797 794 795 + pwm_add_table(rx1950_pwm_lookup, ARRAY_SIZE(rx1950_pwm_lookup)); 798 796 platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices)); 799 797 800 798 i2c_register_board_info(0, rx1950_i2c_devices,
-4
arch/arm/mach-s3c64xx/dev-backlight.c
··· 69 69 .plat_data = { 70 70 .max_brightness = 255, 71 71 .dft_brightness = 255, 72 - .pwm_period_ns = 78770, 73 72 .enable_gpio = -1, 74 73 .init = samsung_bl_init, 75 74 .exit = samsung_bl_exit, ··· 110 111 samsung_bl_data = &samsung_bl_drvdata->plat_data; 111 112 112 113 /* Copy board specific data provided by user */ 113 - samsung_bl_data->pwm_id = bl_data->pwm_id; 114 114 samsung_bl_device->dev.parent = &samsung_device_pwm.dev; 115 115 116 116 if (bl_data->max_brightness) ··· 118 120 samsung_bl_data->dft_brightness = bl_data->dft_brightness; 119 121 if (bl_data->lth_brightness) 120 122 samsung_bl_data->lth_brightness = bl_data->lth_brightness; 121 - if (bl_data->pwm_period_ns) 122 - samsung_bl_data->pwm_period_ns = bl_data->pwm_period_ns; 123 123 if (bl_data->enable_gpio >= 0) 124 124 samsung_bl_data->enable_gpio = bl_data->enable_gpio; 125 125 if (bl_data->init)
+7 -2
arch/arm/mach-s3c64xx/mach-crag6410.c
··· 25 25 #include <linux/mmc/host.h> 26 26 #include <linux/regulator/machine.h> 27 27 #include <linux/regulator/fixed.h> 28 + #include <linux/pwm.h> 28 29 #include <linux/pwm_backlight.h> 29 30 #include <linux/dm9000.h> 30 31 #include <linux/gpio_keys.h> ··· 109 108 }, 110 109 }; 111 110 111 + static struct pwm_lookup crag6410_pwm_lookup[] = { 112 + PWM_LOOKUP("samsung-pwm", 0, "pwm-backlight", NULL, 100000, 113 + PWM_POLARITY_NORMAL), 114 + }; 115 + 112 116 static struct platform_pwm_backlight_data crag6410_backlight_data = { 113 - .pwm_id = 0, 114 117 .max_brightness = 1000, 115 118 .dft_brightness = 600, 116 - .pwm_period_ns = 100000, /* about 1kHz */ 117 119 .enable_gpio = -1, 118 120 }; 119 121 ··· 847 843 samsung_keypad_set_platdata(&crag6410_keypad_data); 848 844 s3c64xx_spi0_set_platdata(NULL, 0, 2); 849 845 846 + pwm_add_table(crag6410_pwm_lookup, ARRAY_SIZE(crag6410_pwm_lookup)); 850 847 platform_add_devices(crag6410_devices, ARRAY_SIZE(crag6410_devices)); 851 848 852 849 gpio_led_register_device(-1, &gpio_leds_pdata);
+7 -2
arch/arm/mach-s3c64xx/mach-hmt.c
··· 19 19 #include <linux/gpio.h> 20 20 #include <linux/delay.h> 21 21 #include <linux/leds.h> 22 + #include <linux/pwm.h> 22 23 #include <linux/pwm_backlight.h> 23 24 #include <linux/mtd/mtd.h> 24 25 #include <linux/mtd/partitions.h> ··· 74 73 }, 75 74 }; 76 75 76 + static struct pwm_lookup hmt_pwm_lookup[] = { 77 + PWM_LOOKUP("samsung-pwm", 1, "pwm-backlight.0", NULL, 78 + 1000000000 / (100 * 256 * 20), PWM_POLARITY_NORMAL), 79 + }; 80 + 77 81 static int hmt_bl_init(struct device *dev) 78 82 { 79 83 int ret; ··· 116 110 } 117 111 118 112 static struct platform_pwm_backlight_data hmt_backlight_data = { 119 - .pwm_id = 1, 120 113 .max_brightness = 100 * 256, 121 114 .dft_brightness = 40 * 256, 122 - .pwm_period_ns = 1000000000 / (100 * 256 * 20), 123 115 .enable_gpio = -1, 124 116 .init = hmt_bl_init, 125 117 .notify = hmt_bl_notify, ··· 272 268 gpio_request(S3C64XX_GPF(13), "usb power"); 273 269 gpio_direction_output(S3C64XX_GPF(13), 1); 274 270 271 + pwm_add_table(hmt_pwm_lookup, ARRAY_SIZE(hmt_pwm_lookup)); 275 272 platform_add_devices(hmt_devices, ARRAY_SIZE(hmt_devices)); 276 273 } 277 274
+7 -2
arch/arm/mach-s3c64xx/mach-smartq.c
··· 14 14 #include <linux/gpio.h> 15 15 #include <linux/init.h> 16 16 #include <linux/platform_device.h> 17 + #include <linux/pwm.h> 17 18 #include <linux/pwm_backlight.h> 18 19 #include <linux/serial_core.h> 19 20 #include <linux/serial_s3c.h> ··· 140 139 .dev.platform_data = &smartq_usb_otg_vbus_pdata, 141 140 }; 142 141 142 + static struct pwm_lookup smartq_pwm_lookup[] = { 143 + PWM_LOOKUP("samsung-pwm", 1, "pwm-backlight.0", NULL, 144 + 1000000000 / (1000 * 20), PWM_POLARITY_NORMAL), 145 + }; 146 + 143 147 static int smartq_bl_init(struct device *dev) 144 148 { 145 149 s3c_gpio_cfgpin(S3C64XX_GPF(15), S3C_GPIO_SFN(2)); ··· 153 147 } 154 148 155 149 static struct platform_pwm_backlight_data smartq_backlight_data = { 156 - .pwm_id = 1, 157 150 .max_brightness = 1000, 158 151 .dft_brightness = 600, 159 - .pwm_period_ns = 1000000000 / (1000 * 20), 160 152 .enable_gpio = -1, 161 153 .init = smartq_bl_init, 162 154 }; ··· 400 396 WARN_ON(smartq_usb_host_init()); 401 397 WARN_ON(smartq_wifi_init()); 402 398 399 + pwm_add_table(smartq_pwm_lookup, ARRAY_SIZE(smartq_pwm_lookup)); 403 400 platform_add_devices(smartq_devices, ARRAY_SIZE(smartq_devices)); 404 401 }
+7 -1
arch/arm/mach-s3c64xx/mach-smdk6410.c
··· 30 30 #include <linux/smsc911x.h> 31 31 #include <linux/regulator/fixed.h> 32 32 #include <linux/regulator/machine.h> 33 + #include <linux/pwm.h> 33 34 #include <linux/pwm_backlight.h> 34 35 #include <linux/platform_data/s3c-hsotg.h> 35 36 ··· 624 623 .func = S3C_GPIO_SFN(2), 625 624 }; 626 625 626 + static struct pwm_lookup smdk6410_pwm_lookup[] = { 627 + PWM_LOOKUP("samsung-pwm", 1, "pwm-backlight.0", NULL, 78770, 628 + PWM_POLARITY_NORMAL), 629 + }; 630 + 627 631 static struct platform_pwm_backlight_data smdk6410_bl_data = { 628 - .pwm_id = 1, 629 632 .enable_gpio = -1, 630 633 }; 631 634 ··· 700 695 701 696 platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices)); 702 697 698 + pwm_add_table(smdk6410_pwm_lookup, ARRAY_SIZE(smdk6410_pwm_lookup)); 703 699 samsung_bl_set(&smdk6410_bl_gpio_info, &smdk6410_bl_data); 704 700 } 705 701
+3 -32
arch/arm/mach-shmobile/pm-rmobile.c
··· 12 12 * License. See the file "COPYING" in the main directory of this archive 13 13 * for more details. 14 14 */ 15 + #include <linux/clk/shmobile.h> 15 16 #include <linux/console.h> 16 17 #include <linux/delay.h> 17 18 #include <linux/of.h> ··· 125 124 return true; 126 125 } 127 126 128 - static int rmobile_pd_attach_dev(struct generic_pm_domain *domain, 129 - struct device *dev) 130 - { 131 - int error; 132 - 133 - error = pm_clk_create(dev); 134 - if (error) { 135 - dev_err(dev, "pm_clk_create failed %d\n", error); 136 - return error; 137 - } 138 - 139 - error = pm_clk_add(dev, NULL); 140 - if (error) { 141 - dev_err(dev, "pm_clk_add failed %d\n", error); 142 - goto fail; 143 - } 144 - 145 - return 0; 146 - 147 - fail: 148 - pm_clk_destroy(dev); 149 - return error; 150 - } 151 - 152 - static void rmobile_pd_detach_dev(struct generic_pm_domain *domain, 153 - struct device *dev) 154 - { 155 - pm_clk_destroy(dev); 156 - } 157 - 158 127 static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) 159 128 { 160 129 struct generic_pm_domain *genpd = &rmobile_pd->genpd; ··· 135 164 genpd->dev_ops.active_wakeup = rmobile_pd_active_wakeup; 136 165 genpd->power_off = rmobile_pd_power_down; 137 166 genpd->power_on = rmobile_pd_power_up; 138 - genpd->attach_dev = rmobile_pd_attach_dev; 139 - genpd->detach_dev = rmobile_pd_detach_dev; 167 + genpd->attach_dev = cpg_mstp_attach_dev; 168 + genpd->detach_dev = cpg_mstp_detach_dev; 140 169 __rmobile_pd_power_up(rmobile_pd, false); 141 170 } 142 171
+2 -1
arch/arm/mach-sunxi/sunxi.c
··· 26 26 "allwinner,sun4i-a10", 27 27 "allwinner,sun5i-a10s", 28 28 "allwinner,sun5i-a13", 29 + "allwinner,sun5i-r8", 29 30 NULL, 30 31 }; 31 32 32 - DT_MACHINE_START(SUNXI_DT, "Allwinner A1X (Device Tree)") 33 + DT_MACHINE_START(SUNXI_DT, "Allwinner sun4i/sun5i Families") 33 34 .dt_compat = sunxi_board_dt_compat, 34 35 .init_late = sunxi_dt_cpufreq_init, 35 36 MACHINE_END
+2 -2
arch/arm/mach-tegra/board-paz00.c
··· 39 39 static struct gpiod_lookup_table wifi_gpio_lookup = { 40 40 .dev_id = "rfkill_gpio", 41 41 .table = { 42 - GPIO_LOOKUP_IDX("tegra-gpio", 25, NULL, 0, 0), 43 - GPIO_LOOKUP_IDX("tegra-gpio", 85, NULL, 1, 0), 42 + GPIO_LOOKUP("tegra-gpio", 25, "reset", 0), 43 + GPIO_LOOKUP("tegra-gpio", 85, "shutdown", 0), 44 44 { }, 45 45 }, 46 46 };
+1 -1
arch/arm/mach-uniphier/Makefile
··· 1 1 obj-y := uniphier.o 2 - obj-$(CONFIG_SMP) += platsmp.o 2 + obj-$(CONFIG_SMP) += platsmp.o headsmp.o
+43
arch/arm/mach-uniphier/headsmp.S
··· 1 + /* 2 + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + */ 14 + 15 + #include <linux/linkage.h> 16 + #include <asm/assembler.h> 17 + #include <asm/cp15.h> 18 + 19 + ENTRY(uniphier_smp_trampoline) 20 + ARM_BE8(setend be) @ ensure we are in BE8 mode 21 + mrc p15, 0, r0, c0, c0, 5 @ MPIDR (Multiprocessor Affinity Reg) 22 + and r2, r0, #0x3 @ CPU ID 23 + ldr r1, uniphier_smp_trampoline_jump 24 + ldr r3, uniphier_smp_trampoline_poll_addr 25 + mrc p15, 0, r0, c1, c0, 0 @ SCTLR (System Control Register) 26 + orr r0, r0, #CR_I @ Enable ICache 27 + bic r0, r0, #(CR_C | CR_M) @ Disable MMU and Dcache 28 + mcr p15, 0, r0, c1, c0, 0 29 + b 1f @ cache the following 5 instructions 30 + 0: wfe 31 + 1: ldr r0, [r3] 32 + cmp r0, r2 33 + bxeq r1 @ branch to secondary_startup 34 + b 0b 35 + .globl uniphier_smp_trampoline_jump 36 + uniphier_smp_trampoline_jump: 37 + .word 0 @ set virt_to_phys(secondary_startup) 38 + .globl uniphier_smp_trampoline_poll_addr 39 + uniphier_smp_trampoline_poll_addr: 40 + .word 0 @ set CPU ID to be kicked to this reg 41 + .globl uniphier_smp_trampoline_end 42 + uniphier_smp_trampoline_end: 43 + ENDPROC(uniphier_smp_trampoline)
+155 -30
arch/arm/mach-uniphier/platsmp.c
··· 12 12 * GNU General Public License for more details. 13 13 */ 14 14 15 - #include <linux/sizes.h> 16 - #include <linux/compiler.h> 15 + #define pr_fmt(fmt) "uniphier: " fmt 16 + 17 17 #include <linux/init.h> 18 18 #include <linux/io.h> 19 - #include <linux/regmap.h> 20 - #include <linux/mfd/syscon.h> 19 + #include <linux/ioport.h> 20 + #include <linux/of.h> 21 + #include <linux/of_address.h> 22 + #include <linux/sizes.h> 23 + #include <asm/cacheflush.h> 24 + #include <asm/hardware/cache-uniphier.h> 25 + #include <asm/pgtable.h> 21 26 #include <asm/smp.h> 22 27 #include <asm/smp_scu.h> 23 28 24 - static struct regmap *sbcm_regmap; 29 + /* 30 + * The secondary CPUs check this register from the boot ROM for the jump 31 + * destination. After that, it can be reused as a scratch register. 32 + */ 33 + #define UNIPHIER_SBC_ROM_BOOT_RSV2 0x1208 25 34 26 - static void __init uniphier_smp_prepare_cpus(unsigned int max_cpus) 35 + static void __iomem *uniphier_smp_rom_boot_rsv2; 36 + static unsigned int uniphier_smp_max_cpus; 37 + 38 + extern char uniphier_smp_trampoline; 39 + extern char uniphier_smp_trampoline_jump; 40 + extern char uniphier_smp_trampoline_poll_addr; 41 + extern char uniphier_smp_trampoline_end; 42 + 43 + /* 44 + * Copy trampoline code to the tail of the 1st section of the page table used 45 + * in the boot ROM. This area is directly accessible by the secondary CPUs 46 + * for all the UniPhier SoCs. 47 + */ 48 + static const phys_addr_t uniphier_smp_trampoline_dest_end = SECTION_SIZE; 49 + static phys_addr_t uniphier_smp_trampoline_dest; 50 + 51 + static int __init uniphier_smp_copy_trampoline(phys_addr_t poll_addr) 27 52 { 28 - static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 }; 53 + size_t trmp_size; 54 + static void __iomem *trmp_base; 55 + 56 + if (!uniphier_cache_l2_is_enabled()) { 57 + pr_warn("outer cache is needed for SMP, but not enabled\n"); 58 + return -ENODEV; 59 + } 60 + 61 + uniphier_cache_l2_set_locked_ways(1); 62 + 63 + outer_flush_all(); 64 + 65 + trmp_size = &uniphier_smp_trampoline_end - &uniphier_smp_trampoline; 66 + uniphier_smp_trampoline_dest = uniphier_smp_trampoline_dest_end - 67 + trmp_size; 68 + 69 + uniphier_cache_l2_touch_range(uniphier_smp_trampoline_dest, 70 + uniphier_smp_trampoline_dest_end); 71 + 72 + trmp_base = ioremap_cache(uniphier_smp_trampoline_dest, trmp_size); 73 + if (!trmp_base) { 74 + pr_err("failed to map trampoline destination area\n"); 75 + return -ENOMEM; 76 + } 77 + 78 + memcpy(trmp_base, &uniphier_smp_trampoline, trmp_size); 79 + 80 + writel(virt_to_phys(secondary_startup), 81 + trmp_base + (&uniphier_smp_trampoline_jump - 82 + &uniphier_smp_trampoline)); 83 + 84 + writel(poll_addr, trmp_base + (&uniphier_smp_trampoline_poll_addr - 85 + &uniphier_smp_trampoline)); 86 + 87 + flush_cache_all(); /* flush out trampoline code to outer cache */ 88 + 89 + iounmap(trmp_base); 90 + 91 + return 0; 92 + } 93 + 94 + static int __init uniphier_smp_prepare_trampoline(unsigned int max_cpus) 95 + { 96 + struct device_node *np; 97 + struct resource res; 98 + phys_addr_t rom_rsv2_phys; 99 + int ret; 100 + 101 + np = of_find_compatible_node(NULL, NULL, 102 + "socionext,uniphier-system-bus-controller"); 103 + ret = of_address_to_resource(np, 1, &res); 104 + if (ret) { 105 + pr_err("failed to get resource of system-bus-controller\n"); 106 + return ret; 107 + } 108 + 109 + rom_rsv2_phys = res.start + UNIPHIER_SBC_ROM_BOOT_RSV2; 110 + 111 + ret = uniphier_smp_copy_trampoline(rom_rsv2_phys); 112 + if (ret) 113 + return ret; 114 + 115 + uniphier_smp_rom_boot_rsv2 = ioremap(rom_rsv2_phys, sizeof(SZ_4)); 116 + if (!uniphier_smp_rom_boot_rsv2) { 117 + pr_err("failed to map ROM_BOOT_RSV2 register\n"); 118 + return -ENOMEM; 119 + } 120 + 121 + writel(uniphier_smp_trampoline_dest, uniphier_smp_rom_boot_rsv2); 122 + asm("sev"); /* Bring up all secondary CPUs to the trampoline code */ 123 + 124 + uniphier_smp_max_cpus = max_cpus; /* save for later use */ 125 + 126 + return 0; 127 + } 128 + 129 + static void __init uniphier_smp_unprepare_trampoline(void) 130 + { 131 + iounmap(uniphier_smp_rom_boot_rsv2); 132 + 133 + if (uniphier_smp_trampoline_dest) 134 + outer_inv_range(uniphier_smp_trampoline_dest, 135 + uniphier_smp_trampoline_dest_end); 136 + 137 + uniphier_cache_l2_set_locked_ways(0); 138 + } 139 + 140 + static int __init uniphier_smp_enable_scu(void) 141 + { 29 142 unsigned long scu_base_phys = 0; 30 143 void __iomem *scu_base; 31 - 32 - sbcm_regmap = syscon_regmap_lookup_by_compatible( 33 - "socionext,uniphier-system-bus-controller-misc"); 34 - if (IS_ERR(sbcm_regmap)) { 35 - pr_err("failed to regmap system-bus-controller-misc\n"); 36 - goto err; 37 - } 38 144 39 145 if (scu_a9_has_base()) 40 146 scu_base_phys = scu_a9_get_base(); 41 147 42 148 if (!scu_base_phys) { 43 149 pr_err("failed to get scu base\n"); 44 - goto err; 150 + return -ENODEV; 45 151 } 46 152 47 153 scu_base = ioremap(scu_base_phys, SZ_128); 48 154 if (!scu_base) { 49 - pr_err("failed to remap scu base (0x%08lx)\n", scu_base_phys); 50 - goto err; 155 + pr_err("failed to map scu base\n"); 156 + return -ENOMEM; 51 157 } 52 158 53 159 scu_enable(scu_base); 54 160 iounmap(scu_base); 55 161 162 + return 0; 163 + } 164 + 165 + static void __init uniphier_smp_prepare_cpus(unsigned int max_cpus) 166 + { 167 + static cpumask_t only_cpu_0 = { CPU_BITS_CPU0 }; 168 + int ret; 169 + 170 + ret = uniphier_smp_prepare_trampoline(max_cpus); 171 + if (ret) 172 + goto err; 173 + 174 + ret = uniphier_smp_enable_scu(); 175 + if (ret) 176 + goto err; 177 + 56 178 return; 57 179 err: 58 180 pr_warn("disabling SMP\n"); 59 181 init_cpu_present(&only_cpu_0); 60 - sbcm_regmap = NULL; 182 + uniphier_smp_unprepare_trampoline(); 61 183 } 62 184 63 - static int uniphier_boot_secondary(unsigned int cpu, 64 - struct task_struct *idle) 185 + static int __init uniphier_smp_boot_secondary(unsigned int cpu, 186 + struct task_struct *idle) 65 187 { 66 - int ret; 188 + if (WARN_ON_ONCE(!uniphier_smp_rom_boot_rsv2)) 189 + return -EFAULT; 67 190 68 - if (!sbcm_regmap) 69 - return -ENODEV; 191 + writel(cpu, uniphier_smp_rom_boot_rsv2); 192 + readl(uniphier_smp_rom_boot_rsv2); /* relax */ 70 193 71 - ret = regmap_write(sbcm_regmap, 0x1208, 72 - virt_to_phys(secondary_startup)); 73 - if (!ret) 74 - asm("sev"); /* wake up secondary CPU */ 194 + asm("sev"); /* wake up secondary CPUs sleeping in the trampoline */ 75 195 76 - return ret; 196 + if (cpu == uniphier_smp_max_cpus - 1) { 197 + /* clean up resources if this is the last CPU */ 198 + uniphier_smp_unprepare_trampoline(); 199 + } 200 + 201 + return 0; 77 202 } 78 203 79 - struct smp_operations uniphier_smp_ops __initdata = { 204 + static struct smp_operations uniphier_smp_ops __initdata = { 80 205 .smp_prepare_cpus = uniphier_smp_prepare_cpus, 81 - .smp_boot_secondary = uniphier_boot_secondary, 206 + .smp_boot_secondary = uniphier_smp_boot_secondary, 82 207 }; 83 208 CPU_METHOD_OF_DECLARE(uniphier_smp, "socionext,uniphier-smp", 84 209 &uniphier_smp_ops);
+10
arch/arm/mm/Kconfig
··· 974 974 This option enables the Tauros2 L2 cache controller (as 975 975 found on PJ1/PJ4). 976 976 977 + config CACHE_UNIPHIER 978 + bool "Enable the UniPhier outer cache controller" 979 + depends on ARCH_UNIPHIER 980 + default y 981 + select OUTER_CACHE 982 + select OUTER_CACHE_SYNC 983 + help 984 + This option enables the UniPhier outer cache (system cache) 985 + controller. 986 + 977 987 config CACHE_XSC3L2 978 988 bool "Enable the L2 cache on XScale3" 979 989 depends on CPU_XSC3
+1
arch/arm/mm/Makefile
··· 103 103 obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o l2c-l2x0-resume.o 104 104 obj-$(CONFIG_CACHE_XSC3L2) += cache-xsc3l2.o 105 105 obj-$(CONFIG_CACHE_TAUROS2) += cache-tauros2.o 106 + obj-$(CONFIG_CACHE_UNIPHIER) += cache-uniphier.o
+555
arch/arm/mm/cache-uniphier.c
··· 1 + /* 2 + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + */ 14 + 15 + #define pr_fmt(fmt) "uniphier: " fmt 16 + 17 + #include <linux/init.h> 18 + #include <linux/io.h> 19 + #include <linux/log2.h> 20 + #include <linux/of_address.h> 21 + #include <linux/slab.h> 22 + #include <asm/hardware/cache-uniphier.h> 23 + #include <asm/outercache.h> 24 + 25 + /* control registers */ 26 + #define UNIPHIER_SSCC 0x0 /* Control Register */ 27 + #define UNIPHIER_SSCC_BST BIT(20) /* UCWG burst read */ 28 + #define UNIPHIER_SSCC_ACT BIT(19) /* Inst-Data separate */ 29 + #define UNIPHIER_SSCC_WTG BIT(18) /* WT gathering on */ 30 + #define UNIPHIER_SSCC_PRD BIT(17) /* enable pre-fetch */ 31 + #define UNIPHIER_SSCC_ON BIT(0) /* enable cache */ 32 + #define UNIPHIER_SSCLPDAWCR 0x30 /* Unified/Data Active Way Control */ 33 + #define UNIPHIER_SSCLPIAWCR 0x34 /* Instruction Active Way Control */ 34 + 35 + /* revision registers */ 36 + #define UNIPHIER_SSCID 0x0 /* ID Register */ 37 + 38 + /* operation registers */ 39 + #define UNIPHIER_SSCOPE 0x244 /* Cache Operation Primitive Entry */ 40 + #define UNIPHIER_SSCOPE_CM_INV 0x0 /* invalidate */ 41 + #define UNIPHIER_SSCOPE_CM_CLEAN 0x1 /* clean */ 42 + #define UNIPHIER_SSCOPE_CM_FLUSH 0x2 /* flush */ 43 + #define UNIPHIER_SSCOPE_CM_SYNC 0x8 /* sync (drain bufs) */ 44 + #define UNIPHIER_SSCOPE_CM_FLUSH_PREFETCH 0x9 /* flush p-fetch buf */ 45 + #define UNIPHIER_SSCOQM 0x248 /* Cache Operation Queue Mode */ 46 + #define UNIPHIER_SSCOQM_TID_MASK (0x3 << 21) 47 + #define UNIPHIER_SSCOQM_TID_LRU_DATA (0x0 << 21) 48 + #define UNIPHIER_SSCOQM_TID_LRU_INST (0x1 << 21) 49 + #define UNIPHIER_SSCOQM_TID_WAY (0x2 << 21) 50 + #define UNIPHIER_SSCOQM_S_MASK (0x3 << 17) 51 + #define UNIPHIER_SSCOQM_S_RANGE (0x0 << 17) 52 + #define UNIPHIER_SSCOQM_S_ALL (0x1 << 17) 53 + #define UNIPHIER_SSCOQM_S_WAY (0x2 << 17) 54 + #define UNIPHIER_SSCOQM_CE BIT(15) /* notify completion */ 55 + #define UNIPHIER_SSCOQM_CM_INV 0x0 /* invalidate */ 56 + #define UNIPHIER_SSCOQM_CM_CLEAN 0x1 /* clean */ 57 + #define UNIPHIER_SSCOQM_CM_FLUSH 0x2 /* flush */ 58 + #define UNIPHIER_SSCOQM_CM_PREFETCH 0x3 /* prefetch to cache */ 59 + #define UNIPHIER_SSCOQM_CM_PREFETCH_BUF 0x4 /* prefetch to pf-buf */ 60 + #define UNIPHIER_SSCOQM_CM_TOUCH 0x5 /* touch */ 61 + #define UNIPHIER_SSCOQM_CM_TOUCH_ZERO 0x6 /* touch to zero */ 62 + #define UNIPHIER_SSCOQM_CM_TOUCH_DIRTY 0x7 /* touch with dirty */ 63 + #define UNIPHIER_SSCOQAD 0x24c /* Cache Operation Queue Address */ 64 + #define UNIPHIER_SSCOQSZ 0x250 /* Cache Operation Queue Size */ 65 + #define UNIPHIER_SSCOQMASK 0x254 /* Cache Operation Queue Address Mask */ 66 + #define UNIPHIER_SSCOQWN 0x258 /* Cache Operation Queue Way Number */ 67 + #define UNIPHIER_SSCOPPQSEF 0x25c /* Cache Operation Queue Set Complete*/ 68 + #define UNIPHIER_SSCOPPQSEF_FE BIT(1) 69 + #define UNIPHIER_SSCOPPQSEF_OE BIT(0) 70 + #define UNIPHIER_SSCOLPQS 0x260 /* Cache Operation Queue Status */ 71 + #define UNIPHIER_SSCOLPQS_EF BIT(2) 72 + #define UNIPHIER_SSCOLPQS_EST BIT(1) 73 + #define UNIPHIER_SSCOLPQS_QST BIT(0) 74 + 75 + /* Is the touch/pre-fetch destination specified by ways? */ 76 + #define UNIPHIER_SSCOQM_TID_IS_WAY(op) \ 77 + ((op & UNIPHIER_SSCOQM_TID_MASK) == UNIPHIER_SSCOQM_TID_WAY) 78 + /* Is the operation region specified by address range? */ 79 + #define UNIPHIER_SSCOQM_S_IS_RANGE(op) \ 80 + ((op & UNIPHIER_SSCOQM_S_MASK) == UNIPHIER_SSCOQM_S_RANGE) 81 + 82 + /** 83 + * uniphier_cache_data - UniPhier outer cache specific data 84 + * 85 + * @ctrl_base: virtual base address of control registers 86 + * @rev_base: virtual base address of revision registers 87 + * @op_base: virtual base address of operation registers 88 + * @way_present_mask: each bit specifies if the way is present 89 + * @way_locked_mask: each bit specifies if the way is locked 90 + * @nsets: number of associativity sets 91 + * @line_size: line size in bytes 92 + * @range_op_max_size: max size that can be handled by a single range operation 93 + * @list: list node to include this level in the whole cache hierarchy 94 + */ 95 + struct uniphier_cache_data { 96 + void __iomem *ctrl_base; 97 + void __iomem *rev_base; 98 + void __iomem *op_base; 99 + u32 way_present_mask; 100 + u32 way_locked_mask; 101 + u32 nsets; 102 + u32 line_size; 103 + u32 range_op_max_size; 104 + struct list_head list; 105 + }; 106 + 107 + /* 108 + * List of the whole outer cache hierarchy. This list is only modified during 109 + * the early boot stage, so no mutex is taken for the access to the list. 110 + */ 111 + static LIST_HEAD(uniphier_cache_list); 112 + 113 + /** 114 + * __uniphier_cache_sync - perform a sync point for a particular cache level 115 + * 116 + * @data: cache controller specific data 117 + */ 118 + static void __uniphier_cache_sync(struct uniphier_cache_data *data) 119 + { 120 + /* This sequence need not be atomic. Do not disable IRQ. */ 121 + writel_relaxed(UNIPHIER_SSCOPE_CM_SYNC, 122 + data->op_base + UNIPHIER_SSCOPE); 123 + /* need a read back to confirm */ 124 + readl_relaxed(data->op_base + UNIPHIER_SSCOPE); 125 + } 126 + 127 + /** 128 + * __uniphier_cache_maint_common - run a queue operation for a particular level 129 + * 130 + * @data: cache controller specific data 131 + * @start: start address of range operation (don't care for "all" operation) 132 + * @size: data size of range operation (don't care for "all" operation) 133 + * @operation: flags to specify the desired cache operation 134 + */ 135 + static void __uniphier_cache_maint_common(struct uniphier_cache_data *data, 136 + unsigned long start, 137 + unsigned long size, 138 + u32 operation) 139 + { 140 + unsigned long flags; 141 + 142 + /* 143 + * No spin lock is necessary here because: 144 + * 145 + * [1] This outer cache controller is able to accept maintenance 146 + * operations from multiple CPUs at a time in an SMP system; if a 147 + * maintenance operation is under way and another operation is issued, 148 + * the new one is stored in the queue. The controller performs one 149 + * operation after another. If the queue is full, the status register, 150 + * UNIPHIER_SSCOPPQSEF, indicates that the queue registration has 151 + * failed. The status registers, UNIPHIER_{SSCOPPQSEF, SSCOLPQS}, have 152 + * different instances for each CPU, i.e. each CPU can track the status 153 + * of the maintenance operations triggered by itself. 154 + * 155 + * [2] The cache command registers, UNIPHIER_{SSCOQM, SSCOQAD, SSCOQSZ, 156 + * SSCOQWN}, are shared between multiple CPUs, but the hardware still 157 + * guarantees the registration sequence is atomic; the write access to 158 + * them are arbitrated by the hardware. The first accessor to the 159 + * register, UNIPHIER_SSCOQM, holds the access right and it is released 160 + * by reading the status register, UNIPHIER_SSCOPPQSEF. While one CPU 161 + * is holding the access right, other CPUs fail to register operations. 162 + * One CPU should not hold the access right for a long time, so local 163 + * IRQs should be disabled while the following sequence. 164 + */ 165 + local_irq_save(flags); 166 + 167 + /* clear the complete notification flag */ 168 + writel_relaxed(UNIPHIER_SSCOLPQS_EF, data->op_base + UNIPHIER_SSCOLPQS); 169 + 170 + do { 171 + /* set cache operation */ 172 + writel_relaxed(UNIPHIER_SSCOQM_CE | operation, 173 + data->op_base + UNIPHIER_SSCOQM); 174 + 175 + /* set address range if needed */ 176 + if (likely(UNIPHIER_SSCOQM_S_IS_RANGE(operation))) { 177 + writel_relaxed(start, data->op_base + UNIPHIER_SSCOQAD); 178 + writel_relaxed(size, data->op_base + UNIPHIER_SSCOQSZ); 179 + } 180 + 181 + /* set target ways if needed */ 182 + if (unlikely(UNIPHIER_SSCOQM_TID_IS_WAY(operation))) 183 + writel_relaxed(data->way_locked_mask, 184 + data->op_base + UNIPHIER_SSCOQWN); 185 + } while (unlikely(readl_relaxed(data->op_base + UNIPHIER_SSCOPPQSEF) & 186 + (UNIPHIER_SSCOPPQSEF_FE | UNIPHIER_SSCOPPQSEF_OE))); 187 + 188 + /* wait until the operation is completed */ 189 + while (likely(readl_relaxed(data->op_base + UNIPHIER_SSCOLPQS) != 190 + UNIPHIER_SSCOLPQS_EF)) 191 + cpu_relax(); 192 + 193 + local_irq_restore(flags); 194 + } 195 + 196 + static void __uniphier_cache_maint_all(struct uniphier_cache_data *data, 197 + u32 operation) 198 + { 199 + __uniphier_cache_maint_common(data, 0, 0, 200 + UNIPHIER_SSCOQM_S_ALL | operation); 201 + 202 + __uniphier_cache_sync(data); 203 + } 204 + 205 + static void __uniphier_cache_maint_range(struct uniphier_cache_data *data, 206 + unsigned long start, unsigned long end, 207 + u32 operation) 208 + { 209 + unsigned long size; 210 + 211 + /* 212 + * If the start address is not aligned, 213 + * perform a cache operation for the first cache-line 214 + */ 215 + start = start & ~(data->line_size - 1); 216 + 217 + size = end - start; 218 + 219 + if (unlikely(size >= (unsigned long)(-data->line_size))) { 220 + /* this means cache operation for all range */ 221 + __uniphier_cache_maint_all(data, operation); 222 + return; 223 + } 224 + 225 + /* 226 + * If the end address is not aligned, 227 + * perform a cache operation for the last cache-line 228 + */ 229 + size = ALIGN(size, data->line_size); 230 + 231 + while (size) { 232 + unsigned long chunk_size = min_t(unsigned long, size, 233 + data->range_op_max_size); 234 + 235 + __uniphier_cache_maint_common(data, start, chunk_size, 236 + UNIPHIER_SSCOQM_S_RANGE | operation); 237 + 238 + start += chunk_size; 239 + size -= chunk_size; 240 + } 241 + 242 + __uniphier_cache_sync(data); 243 + } 244 + 245 + static void __uniphier_cache_enable(struct uniphier_cache_data *data, bool on) 246 + { 247 + u32 val = 0; 248 + 249 + if (on) 250 + val = UNIPHIER_SSCC_WTG | UNIPHIER_SSCC_PRD | UNIPHIER_SSCC_ON; 251 + 252 + writel_relaxed(val, data->ctrl_base + UNIPHIER_SSCC); 253 + } 254 + 255 + static void __init __uniphier_cache_set_locked_ways( 256 + struct uniphier_cache_data *data, 257 + u32 way_mask) 258 + { 259 + data->way_locked_mask = way_mask & data->way_present_mask; 260 + 261 + writel_relaxed(~data->way_locked_mask & data->way_present_mask, 262 + data->ctrl_base + UNIPHIER_SSCLPDAWCR); 263 + } 264 + 265 + static void uniphier_cache_maint_range(unsigned long start, unsigned long end, 266 + u32 operation) 267 + { 268 + struct uniphier_cache_data *data; 269 + 270 + list_for_each_entry(data, &uniphier_cache_list, list) 271 + __uniphier_cache_maint_range(data, start, end, operation); 272 + } 273 + 274 + static void uniphier_cache_maint_all(u32 operation) 275 + { 276 + struct uniphier_cache_data *data; 277 + 278 + list_for_each_entry(data, &uniphier_cache_list, list) 279 + __uniphier_cache_maint_all(data, operation); 280 + } 281 + 282 + static void uniphier_cache_inv_range(unsigned long start, unsigned long end) 283 + { 284 + uniphier_cache_maint_range(start, end, UNIPHIER_SSCOQM_CM_INV); 285 + } 286 + 287 + static void uniphier_cache_clean_range(unsigned long start, unsigned long end) 288 + { 289 + uniphier_cache_maint_range(start, end, UNIPHIER_SSCOQM_CM_CLEAN); 290 + } 291 + 292 + static void uniphier_cache_flush_range(unsigned long start, unsigned long end) 293 + { 294 + uniphier_cache_maint_range(start, end, UNIPHIER_SSCOQM_CM_FLUSH); 295 + } 296 + 297 + static void __init uniphier_cache_inv_all(void) 298 + { 299 + uniphier_cache_maint_all(UNIPHIER_SSCOQM_CM_INV); 300 + } 301 + 302 + static void uniphier_cache_flush_all(void) 303 + { 304 + uniphier_cache_maint_all(UNIPHIER_SSCOQM_CM_FLUSH); 305 + } 306 + 307 + static void uniphier_cache_disable(void) 308 + { 309 + struct uniphier_cache_data *data; 310 + 311 + list_for_each_entry_reverse(data, &uniphier_cache_list, list) 312 + __uniphier_cache_enable(data, false); 313 + 314 + uniphier_cache_flush_all(); 315 + } 316 + 317 + static void __init uniphier_cache_enable(void) 318 + { 319 + struct uniphier_cache_data *data; 320 + 321 + uniphier_cache_inv_all(); 322 + 323 + list_for_each_entry(data, &uniphier_cache_list, list) { 324 + __uniphier_cache_enable(data, true); 325 + __uniphier_cache_set_locked_ways(data, 0); 326 + } 327 + } 328 + 329 + static void uniphier_cache_sync(void) 330 + { 331 + struct uniphier_cache_data *data; 332 + 333 + list_for_each_entry(data, &uniphier_cache_list, list) 334 + __uniphier_cache_sync(data); 335 + } 336 + 337 + int __init uniphier_cache_l2_is_enabled(void) 338 + { 339 + struct uniphier_cache_data *data; 340 + 341 + data = list_first_entry_or_null(&uniphier_cache_list, 342 + struct uniphier_cache_data, list); 343 + if (!data) 344 + return 0; 345 + 346 + return !!(readl_relaxed(data->ctrl_base + UNIPHIER_SSCC) & 347 + UNIPHIER_SSCC_ON); 348 + } 349 + 350 + void __init uniphier_cache_l2_touch_range(unsigned long start, 351 + unsigned long end) 352 + { 353 + struct uniphier_cache_data *data; 354 + 355 + data = list_first_entry_or_null(&uniphier_cache_list, 356 + struct uniphier_cache_data, list); 357 + if (data) 358 + __uniphier_cache_maint_range(data, start, end, 359 + UNIPHIER_SSCOQM_TID_WAY | 360 + UNIPHIER_SSCOQM_CM_TOUCH); 361 + } 362 + 363 + void __init uniphier_cache_l2_set_locked_ways(u32 way_mask) 364 + { 365 + struct uniphier_cache_data *data; 366 + 367 + data = list_first_entry_or_null(&uniphier_cache_list, 368 + struct uniphier_cache_data, list); 369 + if (data) 370 + __uniphier_cache_set_locked_ways(data, way_mask); 371 + } 372 + 373 + static const struct of_device_id uniphier_cache_match[] __initconst = { 374 + { 375 + .compatible = "socionext,uniphier-system-cache", 376 + }, 377 + { /* sentinel */ } 378 + }; 379 + 380 + static struct device_node * __init uniphier_cache_get_next_level_node( 381 + struct device_node *np) 382 + { 383 + u32 phandle; 384 + 385 + if (of_property_read_u32(np, "next-level-cache", &phandle)) 386 + return NULL; 387 + 388 + return of_find_node_by_phandle(phandle); 389 + } 390 + 391 + static int __init __uniphier_cache_init(struct device_node *np, 392 + unsigned int *cache_level) 393 + { 394 + struct uniphier_cache_data *data; 395 + u32 level, cache_size; 396 + struct device_node *next_np; 397 + int ret = 0; 398 + 399 + if (!of_match_node(uniphier_cache_match, np)) { 400 + pr_err("L%d: not compatible with uniphier cache\n", 401 + *cache_level); 402 + return -EINVAL; 403 + } 404 + 405 + if (of_property_read_u32(np, "cache-level", &level)) { 406 + pr_err("L%d: cache-level is not specified\n", *cache_level); 407 + return -EINVAL; 408 + } 409 + 410 + if (level != *cache_level) { 411 + pr_err("L%d: cache-level is unexpected value %d\n", 412 + *cache_level, level); 413 + return -EINVAL; 414 + } 415 + 416 + if (!of_property_read_bool(np, "cache-unified")) { 417 + pr_err("L%d: cache-unified is not specified\n", *cache_level); 418 + return -EINVAL; 419 + } 420 + 421 + data = kzalloc(sizeof(*data), GFP_KERNEL); 422 + if (!data) 423 + return -ENOMEM; 424 + 425 + if (of_property_read_u32(np, "cache-line-size", &data->line_size) || 426 + !is_power_of_2(data->line_size)) { 427 + pr_err("L%d: cache-line-size is unspecified or invalid\n", 428 + *cache_level); 429 + ret = -EINVAL; 430 + goto err; 431 + } 432 + 433 + if (of_property_read_u32(np, "cache-sets", &data->nsets) || 434 + !is_power_of_2(data->nsets)) { 435 + pr_err("L%d: cache-sets is unspecified or invalid\n", 436 + *cache_level); 437 + ret = -EINVAL; 438 + goto err; 439 + } 440 + 441 + if (of_property_read_u32(np, "cache-size", &cache_size) || 442 + cache_size == 0 || cache_size % (data->nsets * data->line_size)) { 443 + pr_err("L%d: cache-size is unspecified or invalid\n", 444 + *cache_level); 445 + ret = -EINVAL; 446 + goto err; 447 + } 448 + 449 + data->way_present_mask = 450 + ((u32)1 << cache_size / data->nsets / data->line_size) - 1; 451 + 452 + data->ctrl_base = of_iomap(np, 0); 453 + if (!data->ctrl_base) { 454 + pr_err("L%d: failed to map control register\n", *cache_level); 455 + ret = -ENOMEM; 456 + goto err; 457 + } 458 + 459 + data->rev_base = of_iomap(np, 1); 460 + if (!data->rev_base) { 461 + pr_err("L%d: failed to map revision register\n", *cache_level); 462 + ret = -ENOMEM; 463 + goto err; 464 + } 465 + 466 + data->op_base = of_iomap(np, 2); 467 + if (!data->op_base) { 468 + pr_err("L%d: failed to map operation register\n", *cache_level); 469 + ret = -ENOMEM; 470 + goto err; 471 + } 472 + 473 + if (*cache_level == 2) { 474 + u32 revision = readl(data->rev_base + UNIPHIER_SSCID); 475 + /* 476 + * The size of range operation is limited to (1 << 22) or less 477 + * for PH-sLD8 or older SoCs. 478 + */ 479 + if (revision <= 0x16) 480 + data->range_op_max_size = (u32)1 << 22; 481 + } 482 + 483 + data->range_op_max_size -= data->line_size; 484 + 485 + INIT_LIST_HEAD(&data->list); 486 + list_add_tail(&data->list, &uniphier_cache_list); /* no mutex */ 487 + 488 + /* 489 + * OK, this level has been successfully initialized. Look for the next 490 + * level cache. Do not roll back even if the initialization of the 491 + * next level cache fails because we want to continue with available 492 + * cache levels. 493 + */ 494 + next_np = uniphier_cache_get_next_level_node(np); 495 + if (next_np) { 496 + (*cache_level)++; 497 + ret = __uniphier_cache_init(next_np, cache_level); 498 + } 499 + of_node_put(next_np); 500 + 501 + return ret; 502 + err: 503 + iounmap(data->op_base); 504 + iounmap(data->rev_base); 505 + iounmap(data->ctrl_base); 506 + kfree(data); 507 + 508 + return ret; 509 + } 510 + 511 + int __init uniphier_cache_init(void) 512 + { 513 + struct device_node *np = NULL; 514 + unsigned int cache_level; 515 + int ret = 0; 516 + 517 + /* look for level 2 cache */ 518 + while ((np = of_find_matching_node(np, uniphier_cache_match))) 519 + if (!of_property_read_u32(np, "cache-level", &cache_level) && 520 + cache_level == 2) 521 + break; 522 + 523 + if (!np) 524 + return -ENODEV; 525 + 526 + ret = __uniphier_cache_init(np, &cache_level); 527 + of_node_put(np); 528 + 529 + if (ret) { 530 + /* 531 + * Error out iif L2 initialization fails. Continue with any 532 + * error on L3 or outer because they are optional. 533 + */ 534 + if (cache_level == 2) { 535 + pr_err("failed to initialize L2 cache\n"); 536 + return ret; 537 + } 538 + 539 + cache_level--; 540 + ret = 0; 541 + } 542 + 543 + outer_cache.inv_range = uniphier_cache_inv_range; 544 + outer_cache.clean_range = uniphier_cache_clean_range; 545 + outer_cache.flush_range = uniphier_cache_flush_range; 546 + outer_cache.flush_all = uniphier_cache_flush_all; 547 + outer_cache.disable = uniphier_cache_disable; 548 + outer_cache.sync = uniphier_cache_sync; 549 + 550 + uniphier_cache_enable(); 551 + 552 + pr_info("enabled outer cache (cache level: %d)\n", cache_level); 553 + 554 + return ret; 555 + }
+1
arch/arm64/Kconfig.platforms
··· 7 7 8 8 config ARCH_BERLIN 9 9 bool "Marvell Berlin SoC Family" 10 + select ARCH_REQUIRE_GPIOLIB 10 11 select DW_APB_ICTL 11 12 help 12 13 This enables support for Marvell Berlin SoC Family
+4
drivers/clk/shmobile/clk-mstp.c
··· 259 259 "renesas,cpg-mstp-clocks")) 260 260 goto found; 261 261 262 + /* BSC on r8a73a4/sh73a0 uses zb_clk instead of an mstp clock */ 263 + if (!strcmp(clkspec.np->name, "zb_clk")) 264 + goto found; 265 + 262 266 of_node_put(clkspec.np); 263 267 i++; 264 268 }
+1
drivers/clk/sunxi/clk-sunxi.c
··· 1196 1196 } 1197 1197 CLK_OF_DECLARE(sun5i_a10s_clk_init, "allwinner,sun5i-a10s", sun5i_init_clocks); 1198 1198 CLK_OF_DECLARE(sun5i_a13_clk_init, "allwinner,sun5i-a13", sun5i_init_clocks); 1199 + CLK_OF_DECLARE(sun5i_r8_clk_init, "allwinner,sun5i-r8", sun5i_init_clocks); 1199 1200 CLK_OF_DECLARE(sun7i_a20_clk_init, "allwinner,sun7i-a20", sun5i_init_clocks); 1200 1201 1201 1202 static const char *sun6i_critical_clocks[] __initdata = {
+1
drivers/soc/Kconfig
··· 1 1 menu "SOC (System On Chip) specific Drivers" 2 2 3 + source "drivers/soc/brcmstb/Kconfig" 3 4 source "drivers/soc/mediatek/Kconfig" 4 5 source "drivers/soc/qcom/Kconfig" 5 6 source "drivers/soc/sunxi/Kconfig"
+1
drivers/soc/Makefile
··· 2 2 # Makefile for the Linux Kernel SOC specific device drivers. 3 3 # 4 4 5 + obj-$(CONFIG_SOC_BRCMSTB) += brcmstb/ 5 6 obj-$(CONFIG_MACH_DOVE) += dove/ 6 7 obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ 7 8 obj-$(CONFIG_ARCH_QCOM) += qcom/
+9
drivers/soc/brcmstb/Kconfig
··· 1 + menuconfig SOC_BRCMSTB 2 + bool "Broadcom STB SoC drivers" 3 + depends on ARM 4 + help 5 + Enables drivers for the Broadcom Set-Top Box (STB) series of chips. 6 + This option alone enables only some support code, while the drivers 7 + can be enabled individually within this menu. 8 + 9 + If unsure, say N.
+1
drivers/soc/brcmstb/Makefile
··· 1 + obj-y += common.o biuctrl.o
+116
drivers/soc/brcmstb/biuctrl.c
··· 1 + /* 2 + * Broadcom STB SoCs Bus Unit Interface controls 3 + * 4 + * Copyright (C) 2015, Broadcom Corporation 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + #define pr_fmt(fmt) "brcmstb: " KBUILD_MODNAME ": " fmt 17 + 18 + #include <linux/kernel.h> 19 + #include <linux/io.h> 20 + #include <linux/of_address.h> 21 + #include <linux/syscore_ops.h> 22 + 23 + #define CPU_CREDIT_REG_OFFSET 0x184 24 + #define CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK 0x70000000 25 + 26 + static void __iomem *cpubiuctrl_base; 27 + static bool mcp_wr_pairing_en; 28 + 29 + static int __init mcp_write_pairing_set(void) 30 + { 31 + u32 creds = 0; 32 + 33 + if (!cpubiuctrl_base) 34 + return -1; 35 + 36 + creds = readl_relaxed(cpubiuctrl_base + CPU_CREDIT_REG_OFFSET); 37 + if (mcp_wr_pairing_en) { 38 + pr_info("MCP: Enabling write pairing\n"); 39 + writel_relaxed(creds | CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK, 40 + cpubiuctrl_base + CPU_CREDIT_REG_OFFSET); 41 + } else if (creds & CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK) { 42 + pr_info("MCP: Disabling write pairing\n"); 43 + writel_relaxed(creds & ~CPU_CREDIT_REG_MCPx_WR_PAIRING_EN_MASK, 44 + cpubiuctrl_base + CPU_CREDIT_REG_OFFSET); 45 + } else { 46 + pr_info("MCP: Write pairing already disabled\n"); 47 + } 48 + 49 + return 0; 50 + } 51 + 52 + static int __init setup_hifcpubiuctrl_regs(void) 53 + { 54 + struct device_node *np; 55 + int ret = 0; 56 + 57 + np = of_find_compatible_node(NULL, NULL, "brcm,brcmstb-cpu-biu-ctrl"); 58 + if (!np) { 59 + pr_err("missing BIU control node\n"); 60 + return -ENODEV; 61 + } 62 + 63 + cpubiuctrl_base = of_iomap(np, 0); 64 + if (!cpubiuctrl_base) { 65 + pr_err("failed to remap BIU control base\n"); 66 + ret = -ENOMEM; 67 + goto out; 68 + } 69 + 70 + mcp_wr_pairing_en = of_property_read_bool(np, "brcm,write-pairing"); 71 + out: 72 + of_node_put(np); 73 + return ret; 74 + } 75 + 76 + #ifdef CONFIG_PM_SLEEP 77 + static u32 cpu_credit_reg_dump; /* for save/restore */ 78 + 79 + static int brcmstb_cpu_credit_reg_suspend(void) 80 + { 81 + if (cpubiuctrl_base) 82 + cpu_credit_reg_dump = 83 + readl_relaxed(cpubiuctrl_base + CPU_CREDIT_REG_OFFSET); 84 + return 0; 85 + } 86 + 87 + static void brcmstb_cpu_credit_reg_resume(void) 88 + { 89 + if (cpubiuctrl_base) 90 + writel_relaxed(cpu_credit_reg_dump, 91 + cpubiuctrl_base + CPU_CREDIT_REG_OFFSET); 92 + } 93 + 94 + static struct syscore_ops brcmstb_cpu_credit_syscore_ops = { 95 + .suspend = brcmstb_cpu_credit_reg_suspend, 96 + .resume = brcmstb_cpu_credit_reg_resume, 97 + }; 98 + #endif 99 + 100 + 101 + void __init brcmstb_biuctrl_init(void) 102 + { 103 + int ret; 104 + 105 + setup_hifcpubiuctrl_regs(); 106 + 107 + ret = mcp_write_pairing_set(); 108 + if (ret) { 109 + pr_err("MCP: Unable to disable write pairing!\n"); 110 + return; 111 + } 112 + 113 + #ifdef CONFIG_PM_SLEEP 114 + register_syscore_ops(&brcmstb_cpu_credit_syscore_ops); 115 + #endif 116 + }
+33
drivers/soc/brcmstb/common.c
··· 1 + /* 2 + * Copyright © 2014 NVIDIA Corporation 3 + * Copyright © 2015 Broadcom Corporation 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License version 2 as 7 + * published by the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + */ 14 + 15 + #include <linux/of.h> 16 + 17 + #include <soc/brcmstb/common.h> 18 + 19 + static const struct of_device_id brcmstb_machine_match[] = { 20 + { .compatible = "brcm,brcmstb", }, 21 + { } 22 + }; 23 + 24 + bool soc_is_brcmstb(void) 25 + { 26 + struct device_node *root; 27 + 28 + root = of_find_node_by_path("/"); 29 + if (!root) 30 + return false; 31 + 32 + return of_match_node(brcmstb_machine_match, root) != NULL; 33 + }
+6 -4
drivers/soc/mediatek/mtk-pmic-wrap.c
··· 725 725 pwrap_writel(wrp, 0x1, PWRAP_WACS2_EN); 726 726 pwrap_writel(wrp, 0x5, PWRAP_STAUPD_PRD); 727 727 pwrap_writel(wrp, 0xff, PWRAP_STAUPD_GRPEN); 728 - pwrap_writel(wrp, 0xf, PWRAP_WDT_UNIT); 729 - pwrap_writel(wrp, 0xffffffff, PWRAP_WDT_SRC_EN); 730 - pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN); 731 - pwrap_writel(wrp, ~((1 << 31) | (1 << 1)), PWRAP_INT_EN); 732 728 733 729 if (pwrap_is_mt8135(wrp)) { 734 730 /* enable pwrap events and pwrap bridge in AP side */ ··· 891 895 dev_dbg(wrp->dev, "initialization isn't finished\n"); 892 896 return -ENODEV; 893 897 } 898 + 899 + /* Initialize watchdog, may not be done by the bootloader */ 900 + pwrap_writel(wrp, 0xf, PWRAP_WDT_UNIT); 901 + pwrap_writel(wrp, 0xffffffff, PWRAP_WDT_SRC_EN); 902 + pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN); 903 + pwrap_writel(wrp, ~((1 << 31) | (1 << 1)), PWRAP_INT_EN); 894 904 895 905 irq = platform_get_irq(pdev, 0); 896 906 ret = devm_request_irq(wrp->dev, irq, pwrap_interrupt, IRQF_TRIGGER_HIGH,
+60 -23
drivers/soc/mediatek/mtk-scpsys.c
··· 54 54 #define PWR_STATUS_USB BIT(25) 55 55 56 56 enum clk_id { 57 + MT8173_CLK_NONE, 57 58 MT8173_CLK_MM, 58 59 MT8173_CLK_MFG, 59 - MT8173_CLK_NONE, 60 - MT8173_CLK_MAX = MT8173_CLK_NONE, 60 + MT8173_CLK_VENC, 61 + MT8173_CLK_VENC_LT, 62 + MT8173_CLK_MAX, 61 63 }; 64 + 65 + #define MAX_CLKS 2 62 66 63 67 struct scp_domain_data { 64 68 const char *name; ··· 71 67 u32 sram_pdn_bits; 72 68 u32 sram_pdn_ack_bits; 73 69 u32 bus_prot_mask; 74 - enum clk_id clk_id; 70 + enum clk_id clk_id[MAX_CLKS]; 71 + bool active_wakeup; 75 72 }; 76 73 77 74 static const struct scp_domain_data scp_domain_data[] __initconst = { ··· 82 77 .ctl_offs = SPM_VDE_PWR_CON, 83 78 .sram_pdn_bits = GENMASK(11, 8), 84 79 .sram_pdn_ack_bits = GENMASK(12, 12), 85 - .clk_id = MT8173_CLK_MM, 80 + .clk_id = {MT8173_CLK_MM}, 86 81 }, 87 82 [MT8173_POWER_DOMAIN_VENC] = { 88 83 .name = "venc", ··· 90 85 .ctl_offs = SPM_VEN_PWR_CON, 91 86 .sram_pdn_bits = GENMASK(11, 8), 92 87 .sram_pdn_ack_bits = GENMASK(15, 12), 93 - .clk_id = MT8173_CLK_MM, 88 + .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC}, 94 89 }, 95 90 [MT8173_POWER_DOMAIN_ISP] = { 96 91 .name = "isp", ··· 98 93 .ctl_offs = SPM_ISP_PWR_CON, 99 94 .sram_pdn_bits = GENMASK(11, 8), 100 95 .sram_pdn_ack_bits = GENMASK(13, 12), 101 - .clk_id = MT8173_CLK_MM, 96 + .clk_id = {MT8173_CLK_MM}, 102 97 }, 103 98 [MT8173_POWER_DOMAIN_MM] = { 104 99 .name = "mm", ··· 106 101 .ctl_offs = SPM_DIS_PWR_CON, 107 102 .sram_pdn_bits = GENMASK(11, 8), 108 103 .sram_pdn_ack_bits = GENMASK(12, 12), 109 - .clk_id = MT8173_CLK_MM, 104 + .clk_id = {MT8173_CLK_MM}, 110 105 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 | 111 106 MT8173_TOP_AXI_PROT_EN_MM_M1, 112 107 }, ··· 116 111 .ctl_offs = SPM_VEN2_PWR_CON, 117 112 .sram_pdn_bits = GENMASK(11, 8), 118 113 .sram_pdn_ack_bits = GENMASK(15, 12), 119 - .clk_id = MT8173_CLK_MM, 114 + .clk_id = {MT8173_CLK_MM, MT8173_CLK_VENC_LT}, 120 115 }, 121 116 [MT8173_POWER_DOMAIN_AUDIO] = { 122 117 .name = "audio", ··· 124 119 .ctl_offs = SPM_AUDIO_PWR_CON, 125 120 .sram_pdn_bits = GENMASK(11, 8), 126 121 .sram_pdn_ack_bits = GENMASK(15, 12), 127 - .clk_id = MT8173_CLK_NONE, 122 + .clk_id = {MT8173_CLK_NONE}, 128 123 }, 129 124 [MT8173_POWER_DOMAIN_USB] = { 130 125 .name = "usb", ··· 132 127 .ctl_offs = SPM_USB_PWR_CON, 133 128 .sram_pdn_bits = GENMASK(11, 8), 134 129 .sram_pdn_ack_bits = GENMASK(15, 12), 135 - .clk_id = MT8173_CLK_NONE, 130 + .clk_id = {MT8173_CLK_NONE}, 131 + .active_wakeup = true, 136 132 }, 137 133 [MT8173_POWER_DOMAIN_MFG_ASYNC] = { 138 134 .name = "mfg_async", ··· 141 135 .ctl_offs = SPM_MFG_ASYNC_PWR_CON, 142 136 .sram_pdn_bits = GENMASK(11, 8), 143 137 .sram_pdn_ack_bits = 0, 144 - .clk_id = MT8173_CLK_MFG, 138 + .clk_id = {MT8173_CLK_MFG}, 145 139 }, 146 140 [MT8173_POWER_DOMAIN_MFG_2D] = { 147 141 .name = "mfg_2d", ··· 149 143 .ctl_offs = SPM_MFG_2D_PWR_CON, 150 144 .sram_pdn_bits = GENMASK(11, 8), 151 145 .sram_pdn_ack_bits = GENMASK(13, 12), 152 - .clk_id = MT8173_CLK_NONE, 146 + .clk_id = {MT8173_CLK_NONE}, 153 147 }, 154 148 [MT8173_POWER_DOMAIN_MFG] = { 155 149 .name = "mfg", ··· 157 151 .ctl_offs = SPM_MFG_PWR_CON, 158 152 .sram_pdn_bits = GENMASK(13, 8), 159 153 .sram_pdn_ack_bits = GENMASK(21, 16), 160 - .clk_id = MT8173_CLK_NONE, 154 + .clk_id = {MT8173_CLK_NONE}, 161 155 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S | 162 156 MT8173_TOP_AXI_PROT_EN_MFG_M0 | 163 157 MT8173_TOP_AXI_PROT_EN_MFG_M1 | ··· 172 166 struct scp_domain { 173 167 struct generic_pm_domain genpd; 174 168 struct scp *scp; 175 - struct clk *clk; 169 + struct clk *clk[MAX_CLKS]; 176 170 u32 sta_mask; 177 171 void __iomem *ctl_addr; 178 172 u32 sram_pdn_bits; 179 173 u32 sram_pdn_ack_bits; 180 174 u32 bus_prot_mask; 175 + bool active_wakeup; 181 176 }; 182 177 183 178 struct scp { ··· 219 212 u32 sram_pdn_ack = scpd->sram_pdn_ack_bits; 220 213 u32 val; 221 214 int ret; 215 + int i; 222 216 223 - if (scpd->clk) { 224 - ret = clk_prepare_enable(scpd->clk); 225 - if (ret) 217 + for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++) { 218 + ret = clk_prepare_enable(scpd->clk[i]); 219 + if (ret) { 220 + for (--i; i >= 0; i--) 221 + clk_disable_unprepare(scpd->clk[i]); 222 + 226 223 goto err_clk; 224 + } 227 225 } 228 226 229 227 val = readl(ctl_addr); ··· 294 282 return 0; 295 283 296 284 err_pwr_ack: 297 - clk_disable_unprepare(scpd->clk); 285 + for (i = MAX_CLKS - 1; i >= 0; i--) { 286 + if (scpd->clk[i]) 287 + clk_disable_unprepare(scpd->clk[i]); 288 + } 298 289 err_clk: 299 290 dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name); 300 291 ··· 314 299 u32 pdn_ack = scpd->sram_pdn_ack_bits; 315 300 u32 val; 316 301 int ret; 302 + int i; 317 303 318 304 if (scpd->bus_prot_mask) { 319 305 ret = mtk_infracfg_set_bus_protection(scp->infracfg, ··· 376 360 expired = true; 377 361 } 378 362 379 - if (scpd->clk) 380 - clk_disable_unprepare(scpd->clk); 363 + for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++) 364 + clk_disable_unprepare(scpd->clk[i]); 381 365 382 366 return 0; 383 367 ··· 387 371 return ret; 388 372 } 389 373 374 + static bool scpsys_active_wakeup(struct device *dev) 375 + { 376 + struct generic_pm_domain *genpd; 377 + struct scp_domain *scpd; 378 + 379 + genpd = pd_to_genpd(dev->pm_domain); 380 + scpd = container_of(genpd, struct scp_domain, genpd); 381 + 382 + return scpd->active_wakeup; 383 + } 384 + 390 385 static int __init scpsys_probe(struct platform_device *pdev) 391 386 { 392 387 struct genpd_onecell_data *pd_data; 393 388 struct resource *res; 394 - int i, ret; 389 + int i, j, ret; 395 390 struct scp *scp; 396 391 struct clk *clk[MT8173_CLK_MAX]; 397 392 ··· 432 405 if (IS_ERR(clk[MT8173_CLK_MFG])) 433 406 return PTR_ERR(clk[MT8173_CLK_MFG]); 434 407 408 + clk[MT8173_CLK_VENC] = devm_clk_get(&pdev->dev, "venc"); 409 + if (IS_ERR(clk[MT8173_CLK_VENC])) 410 + return PTR_ERR(clk[MT8173_CLK_VENC]); 411 + 412 + clk[MT8173_CLK_VENC_LT] = devm_clk_get(&pdev->dev, "venc_lt"); 413 + if (IS_ERR(clk[MT8173_CLK_VENC_LT])) 414 + return PTR_ERR(clk[MT8173_CLK_VENC_LT]); 415 + 435 416 scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, 436 417 "infracfg"); 437 418 if (IS_ERR(scp->infracfg)) { ··· 463 428 scpd->sram_pdn_bits = data->sram_pdn_bits; 464 429 scpd->sram_pdn_ack_bits = data->sram_pdn_ack_bits; 465 430 scpd->bus_prot_mask = data->bus_prot_mask; 466 - if (data->clk_id != MT8173_CLK_NONE) 467 - scpd->clk = clk[data->clk_id]; 431 + scpd->active_wakeup = data->active_wakeup; 432 + for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) 433 + scpd->clk[j] = clk[data->clk_id[j]]; 468 434 469 435 genpd->name = data->name; 470 436 genpd->power_off = scpsys_power_off; 471 437 genpd->power_on = scpsys_power_on; 438 + genpd->dev_ops.active_wakeup = scpsys_active_wakeup; 472 439 473 440 /* 474 441 * Initially turn on all domains to make the domains usable
+2 -1
drivers/soc/ti/knav_qmss.h
··· 135 135 }; 136 136 void __iomem *intd; 137 137 u32 __iomem *iram; 138 - const char *firmware; 139 138 u32 id; 140 139 struct list_head list; 140 + bool loaded; 141 + bool started; 141 142 }; 142 143 143 144 struct knav_qmgr_info {
+8 -2
drivers/soc/ti/knav_qmss_acc.c
··· 486 486 * Return 0 on success or error 487 487 */ 488 488 int knav_init_acc_range(struct knav_device *kdev, 489 - struct device_node *node, 490 - struct knav_range_info *range) 489 + struct device_node *node, 490 + struct knav_range_info *range) 491 491 { 492 492 struct knav_acc_channel *acc; 493 493 struct knav_pdsp_info *pdsp; ··· 528 528 dev_err(kdev->dev, "pdsp id %d not found for range %s\n", 529 529 info->pdsp_id, range->name); 530 530 return -EINVAL; 531 + } 532 + 533 + if (!pdsp->started) { 534 + dev_err(kdev->dev, "pdsp id %d not started for range %s\n", 535 + info->pdsp_id, range->name); 536 + return -ENODEV; 531 537 } 532 538 533 539 info->pdsp = pdsp;
+43 -24
drivers/soc/ti/knav_qmss_queue.c
··· 68 68 idx < (kdev)->num_queues_in_use; \ 69 69 idx++, inst = knav_queue_idx_to_inst(kdev, idx)) 70 70 71 + /* All firmware file names end up here. List the firmware file names below. 72 + * Newest followed by older ones. Search is done from start of the array 73 + * until a firmware file is found. 74 + */ 75 + const char *knav_acc_firmwares[] = {"ks2_qmss_pdsp_acc48.bin"}; 76 + 71 77 /** 72 78 * knav_queue_notify: qmss queue notfier call 73 79 * ··· 1445 1439 struct device *dev = kdev->dev; 1446 1440 struct knav_pdsp_info *pdsp; 1447 1441 struct device_node *child; 1448 - int ret; 1449 1442 1450 1443 for_each_child_of_node(pdsps, child) { 1451 1444 pdsp = devm_kzalloc(dev, sizeof(*pdsp), GFP_KERNEL); ··· 1453 1448 return -ENOMEM; 1454 1449 } 1455 1450 pdsp->name = knav_queue_find_name(child); 1456 - ret = of_property_read_string(child, "firmware", 1457 - &pdsp->firmware); 1458 - if (ret < 0 || !pdsp->firmware) { 1459 - dev_err(dev, "unknown firmware for pdsp %s\n", 1460 - pdsp->name); 1461 - devm_kfree(dev, pdsp); 1462 - continue; 1463 - } 1464 - dev_dbg(dev, "pdsp name %s fw name :%s\n", pdsp->name, 1465 - pdsp->firmware); 1466 - 1467 1451 pdsp->iram = 1468 1452 knav_queue_map_reg(kdev, child, 1469 1453 KNAV_QUEUE_PDSP_IRAM_REG_INDEX); ··· 1483 1489 } 1484 1490 of_property_read_u32(child, "id", &pdsp->id); 1485 1491 list_add_tail(&pdsp->list, &kdev->pdsps); 1486 - dev_dbg(dev, "added pdsp %s: command %p, iram %p, regs %p, intd %p, firmware %s\n", 1492 + dev_dbg(dev, "added pdsp %s: command %p, iram %p, regs %p, intd %p\n", 1487 1493 pdsp->name, pdsp->command, pdsp->iram, pdsp->regs, 1488 - pdsp->intd, pdsp->firmware); 1494 + pdsp->intd); 1489 1495 } 1490 1496 return 0; 1491 1497 } ··· 1504 1510 dev_err(kdev->dev, "timed out on pdsp %s stop\n", pdsp->name); 1505 1511 return ret; 1506 1512 } 1513 + pdsp->loaded = false; 1514 + pdsp->started = false; 1507 1515 return 0; 1508 1516 } 1509 1517 ··· 1514 1518 { 1515 1519 int i, ret, fwlen; 1516 1520 const struct firmware *fw; 1521 + bool found = false; 1517 1522 u32 *fwdata; 1518 1523 1519 - ret = request_firmware(&fw, pdsp->firmware, kdev->dev); 1520 - if (ret) { 1521 - dev_err(kdev->dev, "failed to get firmware %s for pdsp %s\n", 1522 - pdsp->firmware, pdsp->name); 1523 - return ret; 1524 + for (i = 0; i < ARRAY_SIZE(knav_acc_firmwares); i++) { 1525 + if (knav_acc_firmwares[i]) { 1526 + ret = request_firmware(&fw, 1527 + knav_acc_firmwares[i], 1528 + kdev->dev); 1529 + if (!ret) { 1530 + found = true; 1531 + break; 1532 + } 1533 + } 1524 1534 } 1535 + 1536 + if (!found) { 1537 + dev_err(kdev->dev, "failed to get firmware for pdsp\n"); 1538 + return -ENODEV; 1539 + } 1540 + 1541 + dev_info(kdev->dev, "firmware file %s downloaded for PDSP\n", 1542 + knav_acc_firmwares[i]); 1543 + 1525 1544 writel_relaxed(pdsp->id + 1, pdsp->command + 0x18); 1526 1545 /* download the firmware */ 1527 1546 fwdata = (u32 *)fw->data; ··· 1594 1583 int ret; 1595 1584 1596 1585 knav_queue_stop_pdsps(kdev); 1597 - /* now load them all */ 1586 + /* now load them all. We return success even if pdsp 1587 + * is not loaded as acc channels are optional on having 1588 + * firmware availability in the system. We set the loaded 1589 + * and stated flag and when initialize the acc range, check 1590 + * it and init the range only if pdsp is started. 1591 + */ 1598 1592 for_each_pdsp(kdev, pdsp) { 1599 1593 ret = knav_queue_load_pdsp(kdev, pdsp); 1600 - if (ret < 0) 1601 - return ret; 1594 + if (!ret) 1595 + pdsp->loaded = true; 1602 1596 } 1603 1597 1604 1598 for_each_pdsp(kdev, pdsp) { 1605 - ret = knav_queue_start_pdsp(kdev, pdsp); 1606 - WARN_ON(ret); 1599 + if (pdsp->loaded) { 1600 + ret = knav_queue_start_pdsp(kdev, pdsp); 1601 + if (!ret) 1602 + pdsp->started = true; 1603 + } 1607 1604 } 1608 1605 return 0; 1609 1606 }
+47
include/linux/mfd/syscon/imx7-iomuxc-gpr.h
··· 1 + /* 2 + * Copyright (C) 2015 Freescale Semiconductor, Inc. 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */ 8 + 9 + #ifndef __LINUX_IMX7_IOMUXC_GPR_H 10 + #define __LINUX_IMX7_IOMUXC_GPR_H 11 + 12 + #define IOMUXC_GPR0 0x00 13 + #define IOMUXC_GPR1 0x04 14 + #define IOMUXC_GPR2 0x08 15 + #define IOMUXC_GPR3 0x0c 16 + #define IOMUXC_GPR4 0x10 17 + #define IOMUXC_GPR5 0x14 18 + #define IOMUXC_GPR6 0x18 19 + #define IOMUXC_GPR7 0x1c 20 + #define IOMUXC_GPR8 0x20 21 + #define IOMUXC_GPR9 0x24 22 + #define IOMUXC_GPR10 0x28 23 + #define IOMUXC_GPR11 0x2c 24 + #define IOMUXC_GPR12 0x30 25 + #define IOMUXC_GPR13 0x34 26 + #define IOMUXC_GPR14 0x38 27 + #define IOMUXC_GPR15 0x3c 28 + #define IOMUXC_GPR16 0x40 29 + #define IOMUXC_GPR17 0x44 30 + #define IOMUXC_GPR18 0x48 31 + #define IOMUXC_GPR19 0x4c 32 + #define IOMUXC_GPR20 0x50 33 + #define IOMUXC_GPR21 0x54 34 + #define IOMUXC_GPR22 0x58 35 + 36 + /* For imx7d iomux gpr register field define */ 37 + #define IMX7D_GPR1_IRQ_MASK (0x1 << 12) 38 + #define IMX7D_GPR1_ENET1_TX_CLK_SEL_MASK (0x1 << 13) 39 + #define IMX7D_GPR1_ENET2_TX_CLK_SEL_MASK (0x1 << 14) 40 + #define IMX7D_GPR1_ENET_TX_CLK_SEL_MASK (0x3 << 13) 41 + #define IMX7D_GPR1_ENET1_CLK_DIR_MASK (0x1 << 17) 42 + #define IMX7D_GPR1_ENET2_CLK_DIR_MASK (0x1 << 18) 43 + #define IMX7D_GPR1_ENET_CLK_DIR_MASK (0x3 << 17) 44 + 45 + #define IMX7D_GPR5_CSI_MUX_CONTROL_MIPI (0x1 << 4) 46 + 47 + #endif /* __LINUX_IMX7_IOMUXC_GPR_H */
-8
include/linux/platform_data/atmel.h
··· 9 9 10 10 #include <linux/mtd/nand.h> 11 11 #include <linux/mtd/partitions.h> 12 - #include <linux/device.h> 13 - #include <linux/i2c.h> 14 - #include <linux/leds.h> 15 - #include <linux/spi/spi.h> 16 - #include <linux/usb/atmel_usba_udc.h> 17 - #include <linux/atmel-mci.h> 18 - #include <sound/atmel-ac97c.h> 19 12 #include <linux/serial.h> 20 - #include <linux/platform_data/macb.h> 21 13 22 14 /* Compact Flash */ 23 15 struct at91_cf_data {
+10
include/linux/soc/brcmstb/brcmstb.h
··· 1 + #ifndef __BRCMSTB_SOC_H 2 + #define __BRCMSTB_SOC_H 3 + 4 + /* 5 + * Bus Interface Unit control register setup, must happen early during boot, 6 + * before SMP is brought up, called by machine entry point. 7 + */ 8 + void brcmstb_biuctrl_init(void); 9 + 10 + #endif /* __BRCMSTB_SOC_H */
+15
include/soc/brcmstb/common.h
··· 1 + /* 2 + * Copyright © 2014 NVIDIA Corporation 3 + * Copyright © 2015 Broadcom Corporation 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License version 2 as 7 + * published by the Free Software Foundation. 8 + */ 9 + 10 + #ifndef __SOC_BRCMSTB_COMMON_H__ 11 + #define __SOC_BRCMSTB_COMMON_H__ 12 + 13 + bool soc_is_brcmstb(void); 14 + 15 + #endif /* __SOC_BRCMSTB_COMMON_H__ */