diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-05 21:21:08 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-05 21:21:08 -0700 |
commit | 167569343fac74ec6825a3ab982f795b5880e63e (patch) | |
tree | 965adb59fbe10d9f45a7fb90cb1ec1bc18d4613c | |
parent | b240b419db5d624ce7a5a397d6f62a1a686009ec (diff) | |
parent | cd903711fd9dce808b5cc07e509135886d962b0c (diff) | |
download | linux-167569343fac74ec6825a3ab982f795b5880e63e.tar.gz linux-167569343fac74ec6825a3ab982f795b5880e63e.tar.bz2 linux-167569343fac74ec6825a3ab982f795b5880e63e.zip |
Merge tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC platform updates from Arnd Bergmann:
"This release brings up a new platform based on the old ARM9 core: the
Nuvoton NPCM is used as a baseboard management controller, competing
with the better known ASpeed AST2xx series.
Another important change is the addition of ARMv7-A based chips in
mach-stm32. The older parts in this platform are ARMv7-M based
microcontrollers, now they are expanding to general-purpose workloads.
The other changes are the usual defconfig updates to enable additional
drivers, lesser bugfixes. The largest updates as often are the ongoing
OMAP cleanups, but we also have a number of changes for the older PXA
and davinci platforms this time.
For the Renesas shmobile/r-car platform, some new infrastructure is
needed to make the watchdog work correctly.
Supporting Multiprocessing on Allwinner A80 required a significant
amount of new code, but is not doing anything unexpected"
* tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (179 commits)
arm: npcm: modify configuration for the NPCM7xx BMC.
MAINTAINERS: update entry for ARM/berlin
ARM: omap2: fix am43xx build without L2X0
ARM: davinci: da8xx: simplify CFGCHIP regmap_config
ARM: davinci: da8xx: fix oops in USB PHY driver due to stack allocated platform_data
ARM: multi_v7_defconfig: add NXP FlexCAN IP support
ARM: multi_v7_defconfig: enable thermal driver for i.MX devices
ARM: multi_v7_defconfig: add RN5T618 PMIC family support
ARM: multi_v7_defconfig: add NXP graphics drivers
ARM: multi_v7_defconfig: add GPMI NAND controller support
ARM: multi_v7_defconfig: add OCOTP driver for NXP SoCs
ARM: multi_v7_defconfig: configure I2C driver built-in
arm64: defconfig: add CONFIG_UNIPHIER_THERMAL and CONFIG_SNI_AVE
ARM: imx: fix imx6sll-only build
ARM: imx: select ARM_CPU_SUSPEND for CPU_IDLE as well
ARM: mxs_defconfig: Re-sync defconfig
ARM: imx_v4_v5_defconfig: Use the generic fsl-asoc-card driver
ARM: imx_v4_v5_defconfig: Re-sync defconfig
arm64: defconfig: enable stmmac ethernet to defconfig
ARM: EXYNOS: Simplify code in coupled CPU idle hot path
...
189 files changed, 4973 insertions, 3960 deletions
diff --git a/Documentation/arm/Atmel/README b/Documentation/arm/Microchip/README index afb13c15389d..a366f37d38f1 100644 --- a/Documentation/arm/Atmel/README +++ b/Documentation/arm/Microchip/README @@ -1,54 +1,54 @@ -ARM Atmel SoCs (aka AT91) -========================= +ARM Microchip SoCs (aka AT91) +============================= Introduction ------------ -This document gives useful information about the ARM Atmel SoCs that are +This document gives useful information about the ARM Microchip SoCs that are currently supported in Linux Mainline (you know, the one on kernel.org). -It is important to note that the Atmel | SMART ARM-based MPU product line is -historically named "AT91" or "at91" throughout the Linux kernel development -process even if this product prefix has completely disappeared from the -official Atmel product name. Anyway, files, directories, git trees, +It is important to note that the Microchip (previously Atmel) ARM-based MPU +product line is historically named "AT91" or "at91" throughout the Linux kernel +development process even if this product prefix has completely disappeared from +the official Microchip product name. Anyway, files, directories, git trees, git branches/tags and email subject always contain this "at91" sub-string. AT91 SoCs --------- Documentation and detailed datasheet for each product are available on -the Atmel website: http://www.atmel.com. +the Microchip website: http://www.microchip.com. Flavors: * ARM 920 based SoC - at91rm9200 + Datasheet - http://www.atmel.com/Images/doc1768.pdf + http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-1768-32-bit-ARM920T-Embedded-Microprocessor-AT91RM9200_Datasheet.pdf * ARM 926 based SoCs - at91sam9260 + Datasheet - http://www.atmel.com/Images/doc6221.pdf + http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-6221-32-bit-ARM926EJ-S-Embedded-Microprocessor-SAM9260_Datasheet.pdf - at91sam9xe + Datasheet - http://www.atmel.com/Images/Atmel-6254-32-bit-ARM926EJ-S-Embedded-Microprocessor-SAM9XE_Datasheet.pdf + http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-6254-32-bit-ARM926EJ-S-Embedded-Microprocessor-SAM9XE_Datasheet.pdf - at91sam9261 + Datasheet - http://www.atmel.com/Images/doc6062.pdf + http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-6062-ARM926EJ-S-Microprocessor-SAM9261_Datasheet.pdf - at91sam9263 + Datasheet - http://www.atmel.com/Images/Atmel_6249_32-bit-ARM926EJ-S-Microcontroller_SAM9263_Datasheet.pdf + http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-6249-32-bit-ARM926EJ-S-Embedded-Microprocessor-SAM9263_Datasheet.pdf - at91sam9rl + Datasheet - http://www.atmel.com/Images/doc6289.pdf + http://ww1.microchip.com/downloads/en/DeviceDoc/doc6289.pdf - at91sam9g20 + Datasheet - http://www.atmel.com/Images/doc6384.pdf + http://ww1.microchip.com/downloads/en/DeviceDoc/DS60001516A.pdf - at91sam9g45 family - at91sam9g45 @@ -56,7 +56,7 @@ the Atmel website: http://www.atmel.com. - at91sam9m10 - at91sam9m11 (device superset) + Datasheet - http://www.atmel.com/Images/Atmel-6437-32-bit-ARM926-Embedded-Microprocessor-SAM9M11_Datasheet.pdf + http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-6437-32-bit-ARM926-Embedded-Microprocessor-SAM9M11_Datasheet.pdf - at91sam9x5 family (aka "The 5 series") - at91sam9g15 @@ -65,11 +65,11 @@ the Atmel website: http://www.atmel.com. - at91sam9x25 - at91sam9x35 + Datasheet (can be considered as covering the whole family) - http://www.atmel.com/Images/Atmel_11055_32-bit-ARM926EJ-S-Microcontroller_SAM9X35_Datasheet.pdf + http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11055-32-bit-ARM926EJ-S-Microcontroller-SAM9X35_Datasheet.pdf - at91sam9n12 + Datasheet - http://www.atmel.com/Images/Atmel_11063_32-bit-ARM926EJ-S-Microcontroller_SAM9N12CN11CN12_Datasheet.pdf + http://ww1.microchip.com/downloads/en/DeviceDoc/DS60001517A.pdf * ARM Cortex-A5 based SoCs - sama5d3 family @@ -79,7 +79,7 @@ the Atmel website: http://www.atmel.com. - sama5d35 - sama5d36 (device superset) + Datasheet - http://www.atmel.com/Images/Atmel-11121-32-bit-Cortex-A5-Microcontroller-SAMA5D3_Datasheet.pdf + http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11121-32-bit-Cortex-A5-Microcontroller-SAMA5D3_Datasheet.pdf * ARM Cortex-A5 + NEON based SoCs - sama5d4 family @@ -88,7 +88,7 @@ the Atmel website: http://www.atmel.com. - sama5d43 - sama5d44 (device superset) + Datasheet - http://www.atmel.com/Images/Atmel-11238-32-bit-Cortex-A5-Microcontroller-SAMA5D4_Datasheet.pdf + http://ww1.microchip.com/downloads/en/DeviceDoc/60001525A.pdf - sama5d2 family - sama5d21 @@ -99,7 +99,7 @@ the Atmel website: http://www.atmel.com. - sama5d27 (device superset) - sama5d28 (device superset + environmental monitors) + Datasheet - http://www.atmel.com/Images/Atmel-11267-32-bit-Cortex-A5-Microcontroller-SAMA5D2_Datasheet.pdf + http://ww1.microchip.com/downloads/en/DeviceDoc/DS60001476B.pdf * ARM Cortex-M7 MCUs - sams70 family @@ -112,8 +112,6 @@ the Atmel website: http://www.atmel.com. - sams70q19 - sams70q20 - sams70q21 - + Datasheet - http://www.atmel.com/Images/Atmel-11242-32-bit-Cortex-M7-Microcontroller-SAM-S70Q-SAM-S70N-SAM-S70J_Datasheet.pdf - samv70 family - samv70j19 @@ -122,8 +120,6 @@ the Atmel website: http://www.atmel.com. - samv70n20 - samv70q19 - samv70q20 - + Datasheet - http://www.atmel.com/Images/Atmel-11297-32-bit-Cortex-M7-Microcontroller-SAM-V70Q-SAM-V70N-SAM-V70J_Datasheet.pdf - samv71 family - samv71j19 @@ -135,13 +131,15 @@ the Atmel website: http://www.atmel.com. - samv71q19 - samv71q20 - samv71q21 + + Datasheet - http://www.atmel.com/Images/Atmel-44003-32-bit-Cortex-M7-Microcontroller-SAM-V71Q-SAM-V71N-SAM-V71J_Datasheet.pdf + http://ww1.microchip.com/downloads/en/DeviceDoc/60001527A.pdf + Linux kernel information ------------------------ Linux kernel mach directory: arch/arm/mach-at91 -MAINTAINERS entry is: "ARM/ATMEL AT91RM9200 AND AT91SAM ARM ARCHITECTURES" +MAINTAINERS entry is: "ARM/Microchip (AT91) SoC support" Device Tree for AT91 SoCs and boards diff --git a/Documentation/arm/stm32/overview.rst b/Documentation/arm/stm32/overview.rst new file mode 100644 index 000000000000..85cfc8410798 --- /dev/null +++ b/Documentation/arm/stm32/overview.rst @@ -0,0 +1,34 @@ +======================== +STM32 ARM Linux Overview +======================== + +Introduction +------------ + +The STMicroelectronics STM32 family of Cortex-A microprocessors (MPUs) and +Cortex-M microcontrollers (MCUs) are supported by the 'STM32' platform of +ARM Linux. + +Configuration +------------- + +For MCUs, use the provided default configuration: + make stm32_defconfig +For MPUs, use multi_v7 configuration: + make multi_v7_defconfig + +Layout +------ + +All the files for multiple machine families are located in the platform code +contained in arch/arm/mach-stm32 + +There is a generic board board-dt.c in the mach folder which support +Flattened Device Tree, which means, it works with any compatible board with +Device Trees. + +:Authors: + +- Maxime Coquelin <mcoquelin.stm32@gmail.com> +- Ludovic Barre <ludovic.barre@st.com> +- Gerald Baeza <gerald.baeza@st.com> diff --git a/Documentation/arm/stm32/overview.txt b/Documentation/arm/stm32/overview.txt deleted file mode 100644 index a03b0357c017..000000000000 --- a/Documentation/arm/stm32/overview.txt +++ /dev/null @@ -1,33 +0,0 @@ - STM32 ARM Linux Overview - ======================== - -Introduction ------------- - - The STMicroelectronics family of Cortex-M based MCUs are supported by the - 'STM32' platform of ARM Linux. Currently only the STM32F429 (Cortex-M4) - and STM32F746 (Cortex-M7) are supported. - - -Configuration -------------- - - A generic configuration is provided for STM32 family, and can be used as the - default by - make stm32_defconfig - -Layout ------- - - All the files for multiple machine families are located in the platform code - contained in arch/arm/mach-stm32 - - There is a generic board board-dt.c in the mach folder which support - Flattened Device Tree, which means, it works with any compatible board with - Device Trees. - - -Document Author ---------------- - - Maxime Coquelin <mcoquelin.stm32@gmail.com> diff --git a/Documentation/arm/stm32/stm32f429-overview.rst b/Documentation/arm/stm32/stm32f429-overview.rst new file mode 100644 index 000000000000..18feda97f483 --- /dev/null +++ b/Documentation/arm/stm32/stm32f429-overview.rst @@ -0,0 +1,26 @@ +STM32F429 Overview +================== + +Introduction +------------ + +The STM32F429 is a Cortex-M4 MCU aimed at various applications. +It features: + +- ARM Cortex-M4 up to 180MHz with FPU +- 2MB internal Flash Memory +- External memory support through FMC controller (PSRAM, SDRAM, NOR, NAND) +- I2C, SPI, SAI, CAN, USB OTG, Ethernet controllers +- LCD controller & Camera interface +- Cryptographic processor + +Resources +--------- + +Datasheet and reference manual are publicly available on ST website (STM32F429_). + +.. _STM32F429: http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1577/LN1806?ecmp=stm32f429-439_pron_pr-ces2014_nov2013 + +:Authors: + +Maxime Coquelin <mcoquelin.stm32@gmail.com> diff --git a/Documentation/arm/stm32/stm32f429-overview.txt b/Documentation/arm/stm32/stm32f429-overview.txt deleted file mode 100644 index 5206822bd8ef..000000000000 --- a/Documentation/arm/stm32/stm32f429-overview.txt +++ /dev/null @@ -1,22 +0,0 @@ - STM32F429 Overview - ================== - - Introduction - ------------ - The STM32F429 is a Cortex-M4 MCU aimed at various applications. - It features: - - ARM Cortex-M4 up to 180MHz with FPU - - 2MB internal Flash Memory - - External memory support through FMC controller (PSRAM, SDRAM, NOR, NAND) - - I2C, SPI, SAI, CAN, USB OTG, Ethernet controllers - - LCD controller & Camera interface - - Cryptographic processor - - Resources - --------- - Datasheet and reference manual are publicly available on ST website: - - http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1577/LN1806?ecmp=stm32f429-439_pron_pr-ces2014_nov2013 - - Document Author - --------------- - Maxime Coquelin <mcoquelin.stm32@gmail.com> diff --git a/Documentation/arm/stm32/stm32f746-overview.rst b/Documentation/arm/stm32/stm32f746-overview.rst new file mode 100644 index 000000000000..b5f4b6ce7656 --- /dev/null +++ b/Documentation/arm/stm32/stm32f746-overview.rst @@ -0,0 +1,33 @@ +STM32F746 Overview +================== + +Introduction +------------ + +The STM32F746 is a Cortex-M7 MCU aimed at various applications. +It features: + +- Cortex-M7 core running up to @216MHz +- 1MB internal flash, 320KBytes internal RAM (+4KB of backup SRAM) +- FMC controller to connect SDRAM, NOR and NAND memories +- Dual mode QSPI +- SD/MMC/SDIO support +- Ethernet controller +- USB OTFG FS & HS controllers +- I2C, SPI, CAN busses support +- Several 16 & 32 bits general purpose timers +- Serial Audio interface +- LCD controller +- HDMI-CEC +- SPDIFRX + +Resources +--------- + +Datasheet and reference manual are publicly available on ST website (STM32F746_). + +.. _STM32F746: http://www.st.com/content/st_com/en/products/microcontrollers/stm32-32-bit-arm-cortex-mcus/stm32f7-series/stm32f7x6/stm32f746ng.html + +:Authors: + +Alexandre Torgue <alexandre.torgue@st.com> diff --git a/Documentation/arm/stm32/stm32f746-overview.txt b/Documentation/arm/stm32/stm32f746-overview.txt deleted file mode 100644 index cffd2b1ccd6f..000000000000 --- a/Documentation/arm/stm32/stm32f746-overview.txt +++ /dev/null @@ -1,34 +0,0 @@ - STM32F746 Overview - ================== - - Introduction - ------------ - The STM32F746 is a Cortex-M7 MCU aimed at various applications. - It features: - - Cortex-M7 core running up to @216MHz - - 1MB internal flash, 320KBytes internal RAM (+4KB of backup SRAM) - - FMC controller to connect SDRAM, NOR and NAND memories - - Dual mode QSPI - - SD/MMC/SDIO support - - Ethernet controller - - USB OTFG FS & HS controllers - - I2C, SPI, CAN busses support - - Several 16 & 32 bits general purpose timers - - Serial Audio interface - - LCD controller - - HDMI-CEC - - SPDIFRX - - Resources - --------- - Datasheet and reference manual are publicly available on ST website: - - http://www.st.com/content/st_com/en/products/microcontrollers/stm32-32-bit-arm-cortex-mcus/stm32f7-series/stm32f7x6/stm32f746ng.html - - Document Author - --------------- - Alexandre Torgue <alexandre.torgue@st.com> - - - - - diff --git a/Documentation/arm/stm32/stm32f769-overview.rst b/Documentation/arm/stm32/stm32f769-overview.rst new file mode 100644 index 000000000000..228656ced2fe --- /dev/null +++ b/Documentation/arm/stm32/stm32f769-overview.rst @@ -0,0 +1,35 @@ +STM32F769 Overview +================== + +Introduction +------------ + +The STM32F769 is a Cortex-M7 MCU aimed at various applications. +It features: + +- Cortex-M7 core running up to @216MHz +- 2MB internal flash, 512KBytes internal RAM (+4KB of backup SRAM) +- FMC controller to connect SDRAM, NOR and NAND memories +- Dual mode QSPI +- SD/MMC/SDIO support*2 +- Ethernet controller +- USB OTFG FS & HS controllers +- I2C*4, SPI*6, CAN*3 busses support +- Several 16 & 32 bits general purpose timers +- Serial Audio interface*2 +- LCD controller +- HDMI-CEC +- DSI +- SPDIFRX +- MDIO salave interface + +Resources +--------- + +Datasheet and reference manual are publicly available on ST website (STM32F769_). + +.. _STM32F769: http://www.st.com/content/st_com/en/products/microcontrollers/stm32-32-bit-arm-cortex-mcus/stm32-high-performance-mcus/stm32f7-series/stm32f7x9/stm32f769ni.html + +:Authors: + +Alexandre Torgue <alexandre.torgue@st.com> diff --git a/Documentation/arm/stm32/stm32h743-overview.rst b/Documentation/arm/stm32/stm32h743-overview.rst new file mode 100644 index 000000000000..3458dc00095d --- /dev/null +++ b/Documentation/arm/stm32/stm32h743-overview.rst @@ -0,0 +1,34 @@ +STM32H743 Overview +================== + +Introduction +------------ + +The STM32H743 is a Cortex-M7 MCU aimed at various applications. +It features: + +- Cortex-M7 core running up to @400MHz +- 2MB internal flash, 1MBytes internal RAM +- FMC controller to connect SDRAM, NOR and NAND memories +- Dual mode QSPI +- SD/MMC/SDIO support +- Ethernet controller +- USB OTFG FS & HS controllers +- I2C, SPI, CAN busses support +- Several 16 & 32 bits general purpose timers +- Serial Audio interface +- LCD controller +- HDMI-CEC +- SPDIFRX +- DFSDM + +Resources +--------- + +Datasheet and reference manual are publicly available on ST website (STM32H743_). + +.. _STM32H743: http://www.st.com/en/microcontrollers/stm32h7x3.html?querycriteria=productId=LN2033 + +:Authors: + +Alexandre Torgue <alexandre.torgue@st.com> diff --git a/Documentation/arm/stm32/stm32h743-overview.txt b/Documentation/arm/stm32/stm32h743-overview.txt deleted file mode 100644 index 3031cbae31a5..000000000000 --- a/Documentation/arm/stm32/stm32h743-overview.txt +++ /dev/null @@ -1,30 +0,0 @@ - STM32H743 Overview - ================== - - Introduction - ------------ - The STM32H743 is a Cortex-M7 MCU aimed at various applications. - It features: - - Cortex-M7 core running up to @400MHz - - 2MB internal flash, 1MBytes internal RAM - - FMC controller to connect SDRAM, NOR and NAND memories - - Dual mode QSPI - - SD/MMC/SDIO support - - Ethernet controller - - USB OTFG FS & HS controllers - - I2C, SPI, CAN busses support - - Several 16 & 32 bits general purpose timers - - Serial Audio interface - - LCD controller - - HDMI-CEC - - SPDIFRX - - DFSDM - - Resources - --------- - Datasheet and reference manual are publicly available on ST website: - - http://www.st.com/en/microcontrollers/stm32h7x3.html?querycriteria=productId=LN2033 - - Document Author - --------------- - Alexandre Torgue <alexandre.torgue@st.com> diff --git a/Documentation/arm/stm32/stm32mp157-overview.rst b/Documentation/arm/stm32/stm32mp157-overview.rst new file mode 100644 index 000000000000..62e176d47ca7 --- /dev/null +++ b/Documentation/arm/stm32/stm32mp157-overview.rst @@ -0,0 +1,19 @@ +STM32MP157 Overview +=================== + +Introduction +------------ + +The STM32MP157 is a Cortex-A MPU aimed at various applications. +It features: + +- Dual core Cortex-A7 application core +- 2D/3D image composition with GPU +- Standard memories interface support +- Standard connectivity, widely inherited from the STM32 MCU family +- Comprehensive security support + +:Authors: + +- Ludovic Barre <ludovic.barre@st.com> +- Gerald Baeza <gerald.baeza@st.com> diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt index 8b0328ff951d..29e1dc5d506d 100644 --- a/Documentation/devicetree/bindings/arm/cpus.txt +++ b/Documentation/devicetree/bindings/arm/cpus.txt @@ -199,6 +199,7 @@ described below. "actions,s500-smp" "allwinner,sun6i-a31" "allwinner,sun8i-a23" + "allwinner,sun9i-a80-smp" "amlogic,meson8-smp" "amlogic,meson8b-smp" "arm,realview-smp" diff --git a/Documentation/devicetree/bindings/arm/omap/mpu.txt b/Documentation/devicetree/bindings/arm/omap/mpu.txt index 763695db2bd9..f301e636fd52 100644 --- a/Documentation/devicetree/bindings/arm/omap/mpu.txt +++ b/Documentation/devicetree/bindings/arm/omap/mpu.txt @@ -13,6 +13,13 @@ Required properties: Optional properties: - sram: Phandle to the ocmcram node +am335x and am437x only: +- pm-sram: Phandles to ocmcram nodes to be used for power management. + First should be type 'protect-exec' for the driver to use to copy + and run PM functions, second should be regular pool to be used for + data region for code. See Documentation/devicetree/bindings/sram/sram.txt + for more details. + Examples: - For an OMAP5 SMP system: @@ -36,3 +43,12 @@ mpu { compatible = "ti,omap3-mpu"; ti,hwmods = "mpu"; }; + +- For an AM335x system: + +mpu { + compatible = "ti,omap3-mpu"; + ti,hwmods = "mpu"; + pm-sram = <&pm_sram_code + &pm_sram_data>; +}; diff --git a/Documentation/devicetree/bindings/arm/sunxi/smp-sram.txt b/Documentation/devicetree/bindings/arm/sunxi/smp-sram.txt new file mode 100644 index 000000000000..082e6a9382d3 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/sunxi/smp-sram.txt @@ -0,0 +1,44 @@ +Allwinner SRAM for smp bringup: +------------------------------------------------ + +Allwinner's A80 SoC uses part of the secure sram for hotplugging of the +primary core (cpu0). Once the core gets powered up it checks if a magic +value is set at a specific location. If it is then the BROM will jump +to the software entry address, instead of executing a standard boot. + +Therefore a reserved section sub-node has to be added to the mmio-sram +declaration. + +Note that this is separate from the Allwinner SRAM controller found in +../../sram/sunxi-sram.txt. This SRAM is secure only and not mappable to +any device. + +Also there are no "secure-only" properties. The implementation should +check if this SRAM is usable first. + +Required sub-node properties: +- compatible : depending on the SoC this should be one of: + "allwinner,sun9i-a80-smp-sram" + +The rest of the properties should follow the generic mmio-sram discription +found in ../../misc/sram.txt + +Example: + + sram_b: sram@20000 { + /* 256 KiB secure SRAM at 0x20000 */ + compatible = "mmio-sram"; + reg = <0x00020000 0x40000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x00020000 0x40000>; + + smp-sram@1000 { + /* + * This is checked by BROM to determine if + * cpu0 should jump to SMP entry vector + */ + compatible = "allwinner,sun9i-a80-smp-sram"; + reg = <0x1000 0x8>; + }; + }; diff --git a/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt b/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt deleted file mode 100644 index d4ee4da58463..000000000000 --- a/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt +++ /dev/null @@ -1,50 +0,0 @@ -PXA3xx NAND DT bindings - -Required properties: - - - compatible: Should be set to one of the following: - marvell,pxa3xx-nand - marvell,armada370-nand - marvell,armada-8k-nand - - reg: The register base for the controller - - interrupts: The interrupt to map - - #address-cells: Set to <1> if the node includes partitions - - marvell,system-controller: Set to retrieve the syscon node that handles - NAND controller related registers (only required - with marvell,armada-8k-nand compatible). - -Optional properties: - - - dmas: dma data channel, see dma.txt binding doc - - marvell,nand-enable-arbiter: Set to enable the bus arbiter - - marvell,nand-keep-config: Set to keep the NAND controller config as set - by the bootloader - - num-cs: Number of chipselect lines to use - - nand-on-flash-bbt: boolean to enable on flash bbt option if - not present false - - nand-ecc-strength: number of bits to correct per ECC step - - nand-ecc-step-size: number of data bytes covered by a single ECC step - -The following ECC strength and step size are currently supported: - - - nand-ecc-strength = <1>, nand-ecc-step-size = <512> - - nand-ecc-strength = <4>, nand-ecc-step-size = <512> - - nand-ecc-strength = <8>, nand-ecc-step-size = <512> - -Example: - - nand0: nand@43100000 { - compatible = "marvell,pxa3xx-nand"; - reg = <0x43100000 90>; - interrupts = <45>; - dmas = <&pdma 97 0>; - dma-names = "data"; - #address-cells = <1>; - - marvell,nand-enable-arbiter; - marvell,nand-keep-config; - num-cs = <1>; - - /* partitions (optional) */ - }; - diff --git a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt index 8690f10426a3..ab399e559257 100644 --- a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt +++ b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt @@ -17,7 +17,9 @@ Required properties: - "renesas,r8a7794-sysc" (R-Car E2) - "renesas,r8a7795-sysc" (R-Car H3) - "renesas,r8a7796-sysc" (R-Car M3-W) + - "renesas,r8a77965-sysc" (R-Car M3-N) - "renesas,r8a77970-sysc" (R-Car V3M) + - "renesas,r8a77980-sysc" (R-Car V3H) - "renesas,r8a77995-sysc" (R-Car D3) - reg: Address start and address range for the device. - #power-domain-cells: Must be 1. diff --git a/Documentation/devicetree/bindings/reset/renesas,rst.txt b/Documentation/devicetree/bindings/reset/renesas,rst.txt index a8014f3ab8ba..294a0dae106a 100644 --- a/Documentation/devicetree/bindings/reset/renesas,rst.txt +++ b/Documentation/devicetree/bindings/reset/renesas,rst.txt @@ -26,7 +26,9 @@ Required properties: - "renesas,r8a7794-rst" (R-Car E2) - "renesas,r8a7795-rst" (R-Car H3) - "renesas,r8a7796-rst" (R-Car M3-W) + - "renesas,r8a77965-rst" (R-Car M3-N) - "renesas,r8a77970-rst" (R-Car V3M) + - "renesas,r8a77980-rst" (R-Car V3H) - "renesas,r8a77995-rst" (R-Car D3) - reg: Address start and address range for the device. diff --git a/MAINTAINERS b/MAINTAINERS index 8fa200fddd16..2f983928d74c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1242,27 +1242,6 @@ M: Boris Brezillon <boris.brezillon@free-electrons.com> S: Maintained F: drivers/clk/at91 -ARM/ATMEL AT91RM9200, AT91SAM9 AND SAMA5 SOC SUPPORT -M: Nicolas Ferre <nicolas.ferre@microchip.com> -M: Alexandre Belloni <alexandre.belloni@bootlin.com> -L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -W: http://www.linux4sam.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91.git -S: Supported -N: at91 -N: atmel -F: arch/arm/mach-at91/ -F: include/soc/at91/ -F: arch/arm/boot/dts/at91*.dts -F: arch/arm/boot/dts/at91*.dtsi -F: arch/arm/boot/dts/sama*.dts -F: arch/arm/boot/dts/sama*.dtsi -F: arch/arm/include/debug/at91.S -F: drivers/memory/atmel* -F: drivers/watchdog/sama5d4_wdt.c -X: drivers/input/touchscreen/atmel_mxt_ts.c -X: drivers/net/wireless/atmel/ - ARM/CALXEDA HIGHBANK ARCHITECTURE M: Rob Herring <robh@kernel.org> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -1583,15 +1562,6 @@ ARM/MAGICIAN MACHINE SUPPORT M: Philipp Zabel <philipp.zabel@gmail.com> S: Maintained -ARM/Marvell Berlin SoC support -M: Jisheng Zhang <jszhang@marvell.com> -M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> -L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -S: Maintained -F: arch/arm/mach-berlin/ -F: arch/arm/boot/dts/berlin* -F: arch/arm64/boot/dts/marvell/berlin* - ARM/Marvell Dove/MV78xx0/Orion SOC support M: Jason Cooper <jason@lakedaemon.net> M: Andrew Lunn <andrew@lunn.ch> @@ -1662,6 +1632,27 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) F: arch/arm/mach-ks8695/ S: Odd Fixes +ARM/Microchip (AT91) SoC support +M: Nicolas Ferre <nicolas.ferre@microchip.com> +M: Alexandre Belloni <alexandre.belloni@bootlin.com> +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +W: http://www.linux4sam.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/nferre/linux-at91.git +S: Supported +N: at91 +N: atmel +F: arch/arm/mach-at91/ +F: include/soc/at91/ +F: arch/arm/boot/dts/at91*.dts +F: arch/arm/boot/dts/at91*.dtsi +F: arch/arm/boot/dts/sama*.dts +F: arch/arm/boot/dts/sama*.dtsi +F: arch/arm/include/debug/at91.S +F: drivers/memory/atmel* +F: drivers/watchdog/sama5d4_wdt.c +X: drivers/input/touchscreen/atmel_mxt_ts.c +X: drivers/net/wireless/atmel/ + ARM/MIOA701 MACHINE SUPPORT M: Robert Jarzmik <robert.jarzmik@free.fr> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -1706,6 +1697,20 @@ F: Documentation/devicetree/bindings/arm/ste-* F: Documentation/devicetree/bindings/arm/ux500/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git +ARM/NUVOTON NPCM ARCHITECTURE +M: Avi Fishman <avifishman70@gmail.com> +M: Tomer Maimon <tmaimon77@gmail.com> +R: Patrick Venture <venture@google.com> +R: Nancy Yuen <yuenn@google.com> +R: Brendan Higgins <brendanhiggins@google.com> +L: openbmc@lists.ozlabs.org (moderated for non-subscribers) +S: Supported +F: arch/arm/mach-npcm/ +F: arch/arm/boot/dts/nuvoton-npcm* +F: include/dt-bindings/clock/nuvoton,npcm7xx-clks.h +F: drivers/*/*npcm* +F: Documentation/*/*npcm* + ARM/NUVOTON W90X900 ARM ARCHITECTURE M: Wan ZongShun <mcuos.com@gmail.com> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -1968,6 +1973,14 @@ M: Thor Thayer <thor.thayer@linux.intel.com> S: Maintained F: drivers/edac/altera_edac. +ARM/SPREADTRUM SoC SUPPORT +M: Orson Zhai <orsonzhai@gmail.com> +M: Baolin Wang <baolin.wang@linaro.org> +M: Chunyan Zhang <zhang.lyra@gmail.com> +S: Maintained +F: arch/arm64/boot/dts/sprd +N: sprd + ARM/STI ARCHITECTURE M: Patrice Chotard <patrice.chotard@st.com> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) @@ -2010,6 +2023,15 @@ F: arch/arm/boot/dts/stm32* F: arch/arm/mach-stm32/ F: drivers/clocksource/armv7m_systick.c +ARM/Synaptics Berlin SoC support +M: Jisheng Zhang <Jisheng.Zhang@synaptics.com> +M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: arch/arm/mach-berlin/ +F: arch/arm/boot/dts/berlin* +F: arch/arm64/boot/dts/marvell/berlin* + ARM/TANGO ARCHITECTURE M: Marc Gonzalez <marc.w.gonzalez@free.fr> M: Mans Rullgard <mans@mansr.com> @@ -11416,12 +11438,6 @@ F: include/sound/pxa2xx-lib.h F: sound/arm/pxa* F: sound/soc/pxa/ -PXA3xx NAND FLASH DRIVER -M: Ezequiel Garcia <ezequiel.garcia@free-electrons.com> -L: linux-mtd@lists.infradead.org -S: Maintained -F: drivers/mtd/nand/pxa3xx_nand.c - QAT DRIVER M: Giovanni Cabiddu <giovanni.cabiddu@intel.com> L: qat-linux@intel.com diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 7e3d53575486..1878083771af 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -709,8 +709,6 @@ config ARCH_VIRT # Kconfigs may be included either alphabetically (according to the # plat- suffix) or along side the corresponding mach-* source. # -source "arch/arm/mach-mvebu/Kconfig" - source "arch/arm/mach-actions/Kconfig" source "arch/arm/mach-alpine/Kconfig" @@ -719,6 +717,8 @@ source "arch/arm/mach-artpec/Kconfig" source "arch/arm/mach-asm9260/Kconfig" +source "arch/arm/mach-aspeed/Kconfig" + source "arch/arm/mach-at91/Kconfig" source "arch/arm/mach-axxia/Kconfig" @@ -739,6 +739,9 @@ source "arch/arm/mach-dove/Kconfig" source "arch/arm/mach-ep93xx/Kconfig" +source "arch/arm/mach-exynos/Kconfig" +source "arch/arm/plat-samsung/Kconfig" + source "arch/arm/mach-footbridge/Kconfig" source "arch/arm/mach-gemini/Kconfig" @@ -747,31 +750,33 @@ source "arch/arm/mach-highbank/Kconfig" source "arch/arm/mach-hisi/Kconfig" +source "arch/arm/mach-imx/Kconfig" + source "arch/arm/mach-integrator/Kconfig" +source "arch/arm/mach-iop13xx/Kconfig" + source "arch/arm/mach-iop32x/Kconfig" source "arch/arm/mach-iop33x/Kconfig" -source "arch/arm/mach-iop13xx/Kconfig" - source "arch/arm/mach-ixp4xx/Kconfig" source "arch/arm/mach-keystone/Kconfig" source "arch/arm/mach-ks8695/Kconfig" +source "arch/arm/mach-mediatek/Kconfig" + source "arch/arm/mach-meson/Kconfig" -source "arch/arm/mach-moxart/Kconfig" +source "arch/arm/mach-mmp/Kconfig" -source "arch/arm/mach-aspeed/Kconfig" +source "arch/arm/mach-moxart/Kconfig" source "arch/arm/mach-mv78xx0/Kconfig" -source "arch/arm/mach-imx/Kconfig" - -source "arch/arm/mach-mediatek/Kconfig" +source "arch/arm/mach-mvebu/Kconfig" source "arch/arm/mach-mxs/Kconfig" @@ -779,6 +784,8 @@ source "arch/arm/mach-netx/Kconfig" source "arch/arm/mach-nomadik/Kconfig" +source "arch/arm/mach-npcm/Kconfig" + source "arch/arm/mach-nspire/Kconfig" source "arch/arm/plat-omap/Kconfig" @@ -789,23 +796,31 @@ source "arch/arm/mach-omap2/Kconfig" source "arch/arm/mach-orion5x/Kconfig" +source "arch/arm/mach-oxnas/Kconfig" + source "arch/arm/mach-picoxcell/Kconfig" +source "arch/arm/mach-prima2/Kconfig" + source "arch/arm/mach-pxa/Kconfig" source "arch/arm/plat-pxa/Kconfig" -source "arch/arm/mach-mmp/Kconfig" - -source "arch/arm/mach-oxnas/Kconfig" - source "arch/arm/mach-qcom/Kconfig" source "arch/arm/mach-realview/Kconfig" source "arch/arm/mach-rockchip/Kconfig" +source "arch/arm/mach-s3c24xx/Kconfig" + +source "arch/arm/mach-s3c64xx/Kconfig" + +source "arch/arm/mach-s5pv210/Kconfig" + source "arch/arm/mach-sa1100/Kconfig" +source "arch/arm/mach-shmobile/Kconfig" + source "arch/arm/mach-socfpga/Kconfig" source "arch/arm/mach-spear/Kconfig" @@ -814,21 +829,8 @@ source "arch/arm/mach-sti/Kconfig" source "arch/arm/mach-stm32/Kconfig" -source "arch/arm/mach-s3c24xx/Kconfig" - -source "arch/arm/mach-s3c64xx/Kconfig" - -source "arch/arm/mach-s5pv210/Kconfig" - -source "arch/arm/mach-exynos/Kconfig" -source "arch/arm/plat-samsung/Kconfig" - -source "arch/arm/mach-shmobile/Kconfig" - source "arch/arm/mach-sunxi/Kconfig" -source "arch/arm/mach-prima2/Kconfig" - source "arch/arm/mach-tango/Kconfig" source "arch/arm/mach-tegra/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index e83f5161fdd8..e4e537f27339 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -196,6 +196,7 @@ machine-$(CONFIG_ARCH_MEDIATEK) += mediatek machine-$(CONFIG_ARCH_MXS) += mxs machine-$(CONFIG_ARCH_NETX) += netx machine-$(CONFIG_ARCH_NOMADIK) += nomadik +machine-$(CONFIG_ARCH_NPCM) += npcm machine-$(CONFIG_ARCH_NSPIRE) += nspire machine-$(CONFIG_ARCH_OXNAS) += oxnas machine-$(CONFIG_ARCH_OMAP1) += omap1 diff --git a/arch/arm/boot/dts/pxa3xx.dtsi b/arch/arm/boot/dts/pxa3xx.dtsi index 55c75b67351c..982d1a62661d 100644 --- a/arch/arm/boot/dts/pxa3xx.dtsi +++ b/arch/arm/boot/dts/pxa3xx.dtsi @@ -117,15 +117,15 @@ status = "disabled"; }; - nand0: nand@43100000 { - compatible = "marvell,pxa3xx-nand"; + nand_controller: nand-controller@43100000 { + compatible = "marvell,pxa3xx-nand-controller"; reg = <0x43100000 90>; interrupts = <45>; clocks = <&clks CLK_NAND>; dmas = <&pdma 97 3>; dma-names = "data"; #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; status = "disabled"; }; diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig index 43dab4890ad3..8682b15336b9 100644 --- a/arch/arm/configs/bcm2835_defconfig +++ b/arch/arm/configs/bcm2835_defconfig @@ -49,6 +49,9 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_NETWORK_SECMARK=y CONFIG_NETFILTER=y +CONFIG_BT=y +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCM=y CONFIG_CFG80211=y CONFIG_MAC80211=y CONFIG_DEVTMPFS=y @@ -74,6 +77,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_8250_BCM2835AUX=y CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_DEV_BUS=y CONFIG_TTY_PRINTK=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_BCM2835=y diff --git a/arch/arm/configs/cm_x300_defconfig b/arch/arm/configs/cm_x300_defconfig index c0418e03d180..5e349c625b71 100644 --- a/arch/arm/configs/cm_x300_defconfig +++ b/arch/arm/configs/cm_x300_defconfig @@ -49,7 +49,7 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y CONFIG_MTD_BLOCK=y CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_PXA3xx=y +CONFIG_MTD_NAND_MARVELL=y CONFIG_MTD_UBI=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig index 026154c1d55a..c302a04e8cbc 100644 --- a/arch/arm/configs/davinci_all_defconfig +++ b/arch/arm/configs/davinci_all_defconfig @@ -126,9 +126,10 @@ CONFIG_GPIO_PCA953X=y CONFIG_GPIO_PCA953X_IRQ=y CONFIG_POWER_RESET=y CONFIG_POWER_RESET_GPIO=y +CONFIG_SYSCON_REBOOT_MODE=m CONFIG_BATTERY_LEGO_EV3=m CONFIG_WATCHDOG=y -CONFIG_DAVINCI_WATCHDOG=m +CONFIG_DAVINCI_WATCHDOG=y CONFIG_MFD_DM355EVM_MSP=y CONFIG_TPS6507X=y CONFIG_REGULATOR=y diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig index ca0f13cafe38..054591dc9a00 100644 --- a/arch/arm/configs/imx_v4_v5_defconfig +++ b/arch/arm/configs/imx_v4_v5_defconfig @@ -1,7 +1,6 @@ # CONFIG_SWAP is not set CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_LOG_BUF_SHIFT=14 @@ -78,7 +77,6 @@ CONFIG_SMC91X=y CONFIG_SMC911X=y CONFIG_SMSC911X=y CONFIG_SMSC_PHY=y -# CONFIG_INPUT_MOUSEDEV is not set CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_GPIO=y CONFIG_KEYBOARD_IMX=y @@ -105,8 +103,8 @@ CONFIG_HWMON=m CONFIG_SENSORS_MC13783_ADC=m CONFIG_WATCHDOG=y CONFIG_IMX2_WDT=y -CONFIG_MFD_MX25_TSADC=y CONFIG_MFD_MC13XXX_SPI=y +CONFIG_MFD_MX25_TSADC=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_GPIO=y @@ -116,10 +114,8 @@ CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_V4L_PLATFORM_DRIVERS=y CONFIG_SOC_CAMERA=y -CONFIG_VIDEO_MX2=y CONFIG_V4L_MEM2MEM_DRIVERS=y CONFIG_VIDEO_CODA=y -CONFIG_SOC_CAMERA_OV2640=y CONFIG_FB=y CONFIG_FB_IMX=y CONFIG_LCD_L4F00242T03=y @@ -134,8 +130,9 @@ CONFIG_SND_IMX_SOC=y CONFIG_SND_SOC_MX27VIS_AIC32X4=y CONFIG_SND_SOC_PHYCORE_AC97=y CONFIG_SND_SOC_EUKREA_TLV320=y -CONFIG_SND_SOC_IMX_SGTL5000=y CONFIG_SND_SOC_IMX_MC13783=y +CONFIG_SND_SOC_FSL_ASOC_CARD=y +CONFIG_SND_SOC_SGTL5000=y CONFIG_USB_HID=m CONFIG_USB=y CONFIG_USB_EHCI_HCD=y diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 4cb9829fccd1..3a308437b088 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -48,9 +48,7 @@ CONFIG_PCI_IMX6=y CONFIG_SMP=y CONFIG_ARM_PSCI=y CONFIG_PREEMPT_VOLUNTARY=y -CONFIG_AEABI=y CONFIG_HIGHMEM=y -CONFIG_CMA=y CONFIG_FORCE_MAX_ZONEORDER=14 CONFIG_CMDLINE="noinitrd console=ttymxc0,115200" CONFIG_KEXEC=y @@ -60,6 +58,7 @@ CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPUFREQ_DT=y CONFIG_ARM_IMX6Q_CPUFREQ=y CONFIG_CPU_IDLE=y CONFIG_VFP=y @@ -81,7 +80,6 @@ CONFIG_CAN=y CONFIG_CAN_FLEXCAN=y CONFIG_BT=y CONFIG_BT_HCIUART=y -CONFIG_BT_HCIUART_SERDEV=y CONFIG_BT_HCIUART_H4=y CONFIG_BT_HCIUART_LL=y CONFIG_CFG80211=y @@ -92,7 +90,6 @@ CONFIG_RFKILL_INPUT=y CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y # CONFIG_STANDALONE is not set -CONFIG_DMA_CMA=y CONFIG_CMA_SIZE_MBYTES=64 CONFIG_IMX_WEIM=y CONFIG_CONNECTOR=y @@ -170,9 +167,9 @@ CONFIG_MOUSE_PS2_ELANTECH=y CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_ADS7846=y CONFIG_TOUCHSCREEN_EGALAX=y +CONFIG_TOUCHSCREEN_MAX11801=y CONFIG_TOUCHSCREEN_IMX6UL_TSC=y CONFIG_TOUCHSCREEN_EDT_FT5X06=y -CONFIG_TOUCHSCREEN_MAX11801=y CONFIG_TOUCHSCREEN_MC13783=y CONFIG_TOUCHSCREEN_TSC2004=y CONFIG_TOUCHSCREEN_TSC2007=y @@ -181,7 +178,6 @@ CONFIG_TOUCHSCREEN_SX8654=y CONFIG_TOUCHSCREEN_COLIBRI_VF50=y CONFIG_INPUT_MISC=y CONFIG_INPUT_MMA8450=y -CONFIG_HID_MULTITOUCH=y CONFIG_SERIO_SERPORT=m # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_IMX=y @@ -189,7 +185,6 @@ CONFIG_SERIAL_IMX_CONSOLE=y CONFIG_SERIAL_FSL_LPUART=y CONFIG_SERIAL_FSL_LPUART_CONSOLE=y CONFIG_SERIAL_DEV_BUS=y -CONFIG_SERIAL_DEV_CTRL_TTYPORT=y # CONFIG_I2C_COMPAT is not set CONFIG_I2C_CHARDEV=y CONFIG_I2C_MUX=y @@ -209,19 +204,19 @@ CONFIG_GPIO_PCA953X=y CONFIG_GPIO_STMPE=y CONFIG_GPIO_74X164=y CONFIG_POWER_RESET=y -CONFIG_POWER_RESET_IMX=y CONFIG_POWER_RESET_SYSCON=y CONFIG_POWER_RESET_SYSCON_POWEROFF=y CONFIG_POWER_SUPPLY=y CONFIG_SENSORS_GPIO_FAN=y CONFIG_SENSORS_IIO_HWMON=y -CONFIG_THERMAL=y CONFIG_THERMAL_WRITABLE_TRIPS=y CONFIG_CPU_THERMAL=y CONFIG_IMX_THERMAL=y CONFIG_WATCHDOG=y +CONFIG_DA9062_WATCHDOG=y CONFIG_IMX2_WDT=y CONFIG_MFD_DA9052_I2C=y +CONFIG_MFD_DA9062=y CONFIG_MFD_MC13XXX_SPI=y CONFIG_MFD_MC13XXX_I2C=y CONFIG_MFD_STMPE=y @@ -229,17 +224,18 @@ CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_ANATOP=y CONFIG_REGULATOR_DA9052=y +CONFIG_REGULATOR_DA9062=y CONFIG_REGULATOR_GPIO=y CONFIG_REGULATOR_MC13783=y CONFIG_REGULATOR_MC13892=y CONFIG_REGULATOR_PFUZE100=y +CONFIG_RC_CORE=y +CONFIG_RC_DEVICES=y +CONFIG_IR_GPIO_CIR=y CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y -CONFIG_RC_CORE=y CONFIG_MEDIA_CONTROLLER=y CONFIG_VIDEO_V4L2_SUBDEV_API=y -CONFIG_RC_DEVICES=y -CONFIG_IR_GPIO_CIR=y CONFIG_MEDIA_USB_SUPPORT=y CONFIG_USB_VIDEO_CLASS=m CONFIG_V4L_PLATFORM_DRIVERS=y @@ -250,7 +246,6 @@ CONFIG_VIDEO_CODA=m # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set CONFIG_VIDEO_ADV7180=m CONFIG_VIDEO_OV5640=m -CONFIG_SOC_CAMERA_OV2640=y CONFIG_IMX_IPUV3_CORE=y CONFIG_DRM=y CONFIG_DRM_PANEL_LVDS=y @@ -285,10 +280,13 @@ CONFIG_SND_SOC_IMX_SGTL5000=y CONFIG_SND_SOC_IMX_SPDIF=y CONFIG_SND_SOC_IMX_MC13783=y CONFIG_SND_SOC_FSL_ASOC_CARD=y +CONFIG_SND_SOC_AC97_CODEC=y CONFIG_SND_SOC_CS42XX8_I2C=y CONFIG_SND_SOC_TLV320AIC3X=y CONFIG_SND_SOC_WM8960=y +CONFIG_SND_SOC_WM8962=y CONFIG_SND_SIMPLE_CARD=y +CONFIG_HID_MULTITOUCH=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_MXC=y @@ -354,6 +352,7 @@ CONFIG_RTC_DRV_ISL1208=y CONFIG_RTC_DRV_PCF8523=y CONFIG_RTC_DRV_PCF8563=y CONFIG_RTC_DRV_M41T80=y +CONFIG_RTC_DRV_DA9063=y CONFIG_RTC_DRV_MC13XXX=y CONFIG_RTC_DRV_MXC=y CONFIG_RTC_DRV_MXC_V2=y @@ -369,11 +368,14 @@ CONFIG_COMMON_CLK_PWM=y CONFIG_IIO=y CONFIG_IMX7D_ADC=y CONFIG_VF610_ADC=y +CONFIG_MAG3110=y CONFIG_MPL3115=y CONFIG_PWM=y CONFIG_PWM_FSL_FTM=y CONFIG_PWM_IMX=y CONFIG_NVMEM_IMX_OCOTP=y +CONFIG_TEE=y +CONFIG_OPTEE=y CONFIG_MUX_MMIO=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index 28f1d714e5b9..e6b3c96d4c09 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -80,6 +80,7 @@ CONFIG_ARCH_SPEAR13XX=y CONFIG_MACH_SPEAR1310=y CONFIG_MACH_SPEAR1340=y CONFIG_ARCH_STI=y +CONFIG_ARCH_STM32=y CONFIG_ARCH_EXYNOS=y CONFIG_EXYNOS5420_MCPM=y CONFIG_ARCH_RENESAS=y @@ -174,6 +175,7 @@ CONFIG_CAN_RAW=y CONFIG_CAN_BCM=y CONFIG_CAN_DEV=y CONFIG_CAN_AT91=m +CONFIG_CAN_FLEXCAN=m CONFIG_CAN_RCAR=m CONFIG_CAN_XILINXCAN=y CONFIG_CAN_MCP251X=y @@ -208,6 +210,7 @@ CONFIG_MTD_NAND_DENALI_DT=y CONFIG_MTD_NAND_OMAP2=y CONFIG_MTD_NAND_OMAP_BCH=y CONFIG_MTD_NAND_ATMEL=y +CONFIG_MTD_NAND_GPMI_NAND=y CONFIG_MTD_NAND_BRCMNAND=y CONFIG_MTD_NAND_VF610_NFC=y CONFIG_MTD_NAND_DAVINCI=y @@ -307,11 +310,15 @@ CONFIG_TOUCHSCREEN_WM97XX=m CONFIG_INPUT_MISC=y CONFIG_INPUT_MAX77693_HAPTIC=m CONFIG_INPUT_MAX8997_HAPTIC=m +CONFIG_INPUT_CPCAP_PWRBUTTON=m CONFIG_INPUT_AXP20X_PEK=m CONFIG_INPUT_ADXL34X=m CONFIG_SERIO_AMBAKMI=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_8250_BCM2835AUX=y CONFIG_SERIAL_8250_DW=y CONFIG_SERIAL_8250_EM=y CONFIG_SERIAL_8250_MT6577=y @@ -351,6 +358,8 @@ CONFIG_SERIAL_CONEXANT_DIGICOLOR=y CONFIG_SERIAL_CONEXANT_DIGICOLOR_CONSOLE=y CONFIG_SERIAL_ST_ASC=y CONFIG_SERIAL_ST_ASC_CONSOLE=y +CONFIG_SERIAL_STM32=y +CONFIG_SERIAL_STM32_CONSOLE=y CONFIG_HVC_DRIVER=y CONFIG_VIRTIO_CONSOLE=y CONFIG_I2C_CHARDEV=y @@ -368,7 +377,7 @@ CONFIG_I2C_DIGICOLOR=m CONFIG_I2C_EMEV2=m CONFIG_I2C_GPIO=m CONFIG_I2C_EXYNOS5=y -CONFIG_I2C_IMX=m +CONFIG_I2C_IMX=y CONFIG_I2C_MV64XXX=y CONFIG_I2C_RIIC=y CONFIG_I2C_RK3X=y @@ -438,9 +447,11 @@ CONFIG_GPIO_SYSCON=y CONFIG_GPIO_TPS6586X=y CONFIG_GPIO_TPS65910=y CONFIG_BATTERY_ACT8945A=y +CONFIG_BATTERY_CPCAP=m CONFIG_BATTERY_SBS=y CONFIG_BATTERY_MAX17040=m CONFIG_BATTERY_MAX17042=m +CONFIG_CHARGER_CPCAP=m CONFIG_CHARGER_MAX14577=m CONFIG_CHARGER_MAX77693=m CONFIG_CHARGER_MAX8997=m @@ -462,7 +473,9 @@ CONFIG_SENSORS_NTC_THERMISTOR=m CONFIG_SENSORS_PWM_FAN=m CONFIG_SENSORS_INA2XX=m CONFIG_CPU_THERMAL=y +CONFIG_BCM2835_THERMAL=m CONFIG_BRCMSTB_THERMAL=m +CONFIG_IMX_THERMAL=y CONFIG_ROCKCHIP_THERMAL=y CONFIG_RCAR_THERMAL=y CONFIG_ARMADA_THERMAL=y @@ -476,6 +489,7 @@ CONFIG_ARM_SP805_WATCHDOG=y CONFIG_AT91SAM9X_WATCHDOG=y CONFIG_SAMA5D4_WATCHDOG=y CONFIG_ORION_WATCHDOG=y +CONFIG_RN5T618_WATCHDOG=y CONFIG_ST_LPC_WATCHDOG=y CONFIG_SUNXI_WATCHDOG=y CONFIG_IMX2_WDT=y @@ -508,9 +522,11 @@ CONFIG_MFD_MAX8907=y CONFIG_MFD_MAX8997=y CONFIG_MFD_MAX8998=y CONFIG_MFD_RK808=y +CONFIG_MFD_CPCAP=y CONFIG_MFD_PM8XXX=y CONFIG_MFD_QCOM_RPM=y CONFIG_MFD_SPMI_PMIC=y +CONFIG_MFD_RN5T618=y CONFIG_MFD_SEC_CORE=y CONFIG_MFD_STMPE=y CONFIG_MFD_PALMAS=y @@ -527,6 +543,7 @@ CONFIG_REGULATOR_AS3711=y CONFIG_REGULATOR_AS3722=y CONFIG_REGULATOR_AXP20X=y CONFIG_REGULATOR_BCM590XX=y +CONFIG_REGULATOR_CPCAP=y CONFIG_REGULATOR_DA9210=y CONFIG_REGULATOR_FAN53555=y CONFIG_REGULATOR_RK808=y @@ -547,6 +564,7 @@ CONFIG_REGULATOR_PBIAS=y CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_QCOM_RPM=y CONFIG_REGULATOR_QCOM_SMD_RPM=y +CONFIG_REGULATOR_RN5T618=y CONFIG_REGULATOR_S2MPS11=y CONFIG_REGULATOR_S5M8767=y CONFIG_REGULATOR_TI_ABB=y @@ -617,6 +635,7 @@ CONFIG_DRM_ATMEL_HLCDC=m CONFIG_DRM_RCAR_DU=m CONFIG_DRM_RCAR_LVDS=y CONFIG_DRM_SUN4I=m +CONFIG_DRM_FSL_DCU=m CONFIG_DRM_TEGRA=y CONFIG_DRM_PANEL_SAMSUNG_LD9040=m CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=m @@ -624,6 +643,8 @@ CONFIG_DRM_PANEL_SIMPLE=y CONFIG_DRM_SII9234=m CONFIG_DRM_STI=m CONFIG_DRM_VC4=y +CONFIG_DRM_ETNAVIV=m +CONFIG_DRM_MXSFB=m CONFIG_FB_ARMCLCD=y CONFIG_FB_EFI=y CONFIG_FB_WM8505=y @@ -674,6 +695,7 @@ CONFIG_SND_SOC_TEGRA_WM8903=m CONFIG_SND_SOC_TEGRA_WM9712=m CONFIG_SND_SOC_TEGRA_TRIMSLICE=m CONFIG_SND_SOC_TEGRA_ALC5632=m +CONFIG_SND_SOC_CPCAP=m CONFIG_SND_SOC_TEGRA_MAX98090=m CONFIG_SND_SOC_AK4642=m CONFIG_SND_SOC_SGTL5000=m @@ -683,6 +705,7 @@ CONFIG_SND_SOC_STI=m CONFIG_SND_SOC_STI_SAS=m CONFIG_SND_SIMPLE_CARD=m CONFIG_USB=y +CONFIG_USB_OTG=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_MVEBU=y CONFIG_USB_XHCI_RCAR=m @@ -704,6 +727,15 @@ CONFIG_USB_STORAGE=y CONFIG_USB_UAS=m CONFIG_USB_MUSB_HDRC=m CONFIG_USB_MUSB_SUNXI=m +CONFIG_USB_MUSB_TUSB6010=m +CONFIG_USB_MUSB_OMAP2PLUS=m +CONFIG_USB_MUSB_AM35X=m +CONFIG_USB_MUSB_DSPS=m +CONFIG_USB_MUSB_UX500=m +CONFIG_USB_UX500_DMA=y +CONFIG_USB_INVENTRA_DMA=y +CONFIG_USB_TI_CPPI41_DMA=y +CONFIG_USB_TUSB_OMAP_DMA=y CONFIG_USB_DWC3=y CONFIG_USB_DWC2=y CONFIG_USB_HSIC_USB3503=y @@ -712,6 +744,9 @@ CONFIG_USB_CHIPIDEA_UDC=y CONFIG_USB_CHIPIDEA_HOST=y CONFIG_AB8500_USB=y CONFIG_KEYSTONE_USB_PHY=y +CONFIG_NOP_USB_XCEIV=m +CONFIG_AM335X_PHY_USB=m +CONFIG_TWL6030_USB=m CONFIG_USB_GPIO_VBUS=y CONFIG_USB_ISP1301=y CONFIG_USB_MSM_OTG=m @@ -719,6 +754,25 @@ CONFIG_USB_MXS_PHY=y CONFIG_USB_GADGET=y CONFIG_USB_FSL_USB2=y CONFIG_USB_RENESAS_USBHS_UDC=m +CONFIG_USB_CONFIGFS=m +CONFIG_USB_CONFIGFS_SERIAL=y +CONFIG_USB_CONFIGFS_ACM=y +CONFIG_USB_CONFIGFS_OBEX=y +CONFIG_USB_CONFIGFS_NCM=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_ECM_SUBSET=y +CONFIG_USB_CONFIGFS_RNDIS=y +CONFIG_USB_CONFIGFS_EEM=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_CONFIGFS_F_LB_SS=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_F_UAC1=y +CONFIG_USB_CONFIGFS_F_UAC1_LEGACY=y +CONFIG_USB_CONFIGFS_F_UAC2=y +CONFIG_USB_CONFIGFS_F_MIDI=y +CONFIG_USB_CONFIGFS_F_HID=y +CONFIG_USB_CONFIGFS_F_UVC=y +CONFIG_USB_CONFIGFS_F_PRINTER=y CONFIG_USB_ETH=m CONFIG_MMC=y CONFIG_MMC_BLOCK_MINORS=16 @@ -755,6 +809,7 @@ CONFIG_MMC_SDHCI_OMAP=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_CLASS_FLASH=m +CONFIG_LEDS_CPCAP=m CONFIG_LEDS_GPIO=y CONFIG_LEDS_PWM=y CONFIG_LEDS_MAX77693=m @@ -805,6 +860,7 @@ CONFIG_RTC_DRV_SUN6I=y CONFIG_RTC_DRV_SUNXI=y CONFIG_RTC_DRV_MV=y CONFIG_RTC_DRV_TEGRA=y +CONFIG_RTC_DRV_CPCAP=m CONFIG_DMADEVICES=y CONFIG_DW_DMAC=y CONFIG_AT_HDMAC=y @@ -877,6 +933,7 @@ CONFIG_IIO_SW_TRIGGER=y CONFIG_AT91_ADC=m CONFIG_AT91_SAMA5D2_ADC=m CONFIG_BERLIN2_ADC=m +CONFIG_CPCAP_ADC=m CONFIG_EXYNOS_ADC=m CONFIG_VF610_ADC=m CONFIG_XILINX_XADC=y @@ -902,9 +959,12 @@ CONFIG_E1000E=y CONFIG_PWM_STI=y CONFIG_PWM_BCM2835=y CONFIG_PWM_BRCMSTB=m +CONFIG_PHY_DM816X_USB=m CONFIG_OMAP_USB2=y CONFIG_TI_PIPE3=y +CONFIG_TWL4030_USB=m CONFIG_PHY_BERLIN_USB=y +CONFIG_PHY_CPCAP_USB=m CONFIG_PHY_BERLIN_SATA=y CONFIG_PHY_ROCKCHIP_DP=m CONFIG_PHY_ROCKCHIP_USB=y @@ -918,7 +978,9 @@ CONFIG_PHY_SAMSUNG_USB2=m CONFIG_PHY_TEGRA_XUSB=y CONFIG_PHY_BRCM_SATA=y CONFIG_NVMEM=y +CONFIG_NVMEM_IMX_OCOTP=y CONFIG_NVMEM_SUNXI_SID=y +CONFIG_NVMEM_VF610_OCOTP=y CONFIG_BCM2835_MBOX=y CONFIG_RASPBERRYPI_FIRMWARE=y CONFIG_EFI_VARS=m diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig index bbfb6759447b..a508eb302e7a 100644 --- a/arch/arm/configs/mxs_defconfig +++ b/arch/arm/configs/mxs_defconfig @@ -1,5 +1,4 @@ CONFIG_SYSVIPC=y -CONFIG_FHANDLE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_TASKSTATS=y @@ -62,14 +61,13 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y CONFIG_ENC28J60=y -CONFIG_SMSC_PHY=y CONFIG_ICPLUS_PHY=y -CONFIG_REALTEK_PHY=y CONFIG_MICREL_PHY=y +CONFIG_REALTEK_PHY=y +CONFIG_SMSC_PHY=y CONFIG_USB_USBNET=y CONFIG_USB_NET_SMSC95XX=y # CONFIG_WLAN is not set -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_KEYBOARD is not set # CONFIG_INPUT_MOUSE is not set @@ -77,9 +75,7 @@ CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_MXS_LRADC=y CONFIG_TOUCHSCREEN_TSC2007=m # CONFIG_SERIO is not set -CONFIG_DEVPTS_MULTIPLE_INSTANCES=y # CONFIG_LEGACY_PTYS is not set -# CONFIG_DEVKMEM is not set CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_SERIAL_MXS_AUART=y @@ -138,11 +134,10 @@ CONFIG_RTC_DRV_STMP=y CONFIG_DMADEVICES=y CONFIG_MXS_DMA=y CONFIG_IIO=y -CONFIG_IIO_SYSFS_TRIGGER=y CONFIG_MXS_LRADC_ADC=y +CONFIG_IIO_SYSFS_TRIGGER=y CONFIG_PWM=y CONFIG_PWM_MXS=y -CONFIG_NVMEM=y CONFIG_NVMEM_MXS_OCOTP=y CONFIG_EXT4_FS=y # CONFIG_DNOTIFY is not set @@ -172,8 +167,7 @@ CONFIG_FRAME_WARN=2048 CONFIG_UNUSED_SYMBOLS=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y -CONFIG_LOCKUP_DETECTOR=y -CONFIG_TIMER_STATS=y +CONFIG_SOFTLOCKUP_DETECTOR=y CONFIG_PROVE_LOCKING=y CONFIG_BLK_DEV_IO_TRACE=y CONFIG_STRICT_DEVMEM=y diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index bce7e5abcc05..6491419b1dad 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -50,7 +50,6 @@ CONFIG_ARM_THUMBEE=y CONFIG_ARM_ERRATA_411920=y CONFIG_PCI=y CONFIG_PCI_MSI=y -CONFIG_PCI_DRA7XX=y CONFIG_PCI_DRA7XX_EP=y CONFIG_PCI_ENDPOINT=y CONFIG_PCI_ENDPOINT_CONFIGFS=y @@ -71,9 +70,10 @@ CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y CONFIG_CPUFREQ_DT=m -CONFIG_ARM_TI_CPUFREQ=y # CONFIG_ARM_OMAP2PLUS_CPUFREQ is not set +CONFIG_ARM_TI_CPUFREQ=y CONFIG_CPU_IDLE=y +CONFIG_KERNEL_MODE_NEON=y CONFIG_BINFMT_MISC=y CONFIG_PM_DEBUG=y CONFIG_NET=y @@ -103,9 +103,11 @@ CONFIG_BT_HIDP=m CONFIG_BT_HCIBTUSB=m CONFIG_BT_HCIBTSDIO=m CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_NOKIA=m CONFIG_BT_HCIUART_BCSP=y CONFIG_BT_HCIUART_LL=y CONFIG_BT_HCIUART_3WIRE=y +CONFIG_BT_HCIUART_BCM=y CONFIG_BT_HCIBCM203X=m CONFIG_BT_HCIBPA10X=m CONFIG_BT_HCIBFUSB=m @@ -232,7 +234,9 @@ CONFIG_INPUT_MISC=y CONFIG_INPUT_CPCAP_PWRBUTTON=m CONFIG_INPUT_TPS65218_PWRBUTTON=m CONFIG_INPUT_TWL4030_PWRBUTTON=m +CONFIG_INPUT_UINPUT=m CONFIG_INPUT_PALMAS_PWRBUTTON=m +CONFIG_INPUT_PWM_VIBRA=m CONFIG_SERIO=m # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_8250=y @@ -244,9 +248,11 @@ CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_8250_DETECT_IRQ=y CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_OMAP=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_OMAP=y CONFIG_SERIAL_OMAP_CONSOLE=y +CONFIG_SERIAL_DEV_BUS=y CONFIG_I2C_CHARDEV=y CONFIG_SPI=y CONFIG_SPI_OMAP24XX=y @@ -291,6 +297,7 @@ CONFIG_OMAP_WATCHDOG=m CONFIG_TWL4030_WATCHDOG=m CONFIG_MFD_CPCAP=y CONFIG_MFD_TI_AM335X_TSCADC=m +CONFIG_MFD_TI_LMU=m CONFIG_MFD_PALMAS=y CONFIG_MFD_TPS65217=y CONFIG_MFD_TI_LP873X=y @@ -314,40 +321,47 @@ CONFIG_REGULATOR_TPS65217=y CONFIG_REGULATOR_TPS65218=y CONFIG_REGULATOR_TPS65910=y CONFIG_REGULATOR_TWL4030=y -CONFIG_MEDIA_SUPPORT=m -CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_RC_CORE=m -CONFIG_MEDIA_CONTROLLER=y -CONFIG_VIDEO_V4L2_SUBDEV_API=y CONFIG_LIRC=y CONFIG_RC_DEVICES=y +CONFIG_IR_SPI=m CONFIG_IR_RX51=m +CONFIG_IR_GPIO_TX=m +CONFIG_IR_PWM_TX=m +CONFIG_MEDIA_SUPPORT=m +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_CEC_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y CONFIG_V4L_PLATFORM_DRIVERS=y CONFIG_VIDEO_OMAP3=m +CONFIG_CEC_PLATFORM_DRIVERS=y # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set CONFIG_VIDEO_TVP5150=m +CONFIG_DRM=m +CONFIG_DRM_OMAP=m +CONFIG_OMAP5_DSS_HDMI=y +CONFIG_OMAP2_DSS_SDI=y +CONFIG_OMAP2_DSS_DSI=y +CONFIG_DRM_OMAP_ENCODER_OPA362=m +CONFIG_DRM_OMAP_ENCODER_TFP410=m +CONFIG_DRM_OMAP_ENCODER_TPD12S015=m +CONFIG_DRM_OMAP_CONNECTOR_DVI=m +CONFIG_DRM_OMAP_CONNECTOR_HDMI=m +CONFIG_DRM_OMAP_CONNECTOR_ANALOG_TV=m +CONFIG_DRM_OMAP_PANEL_DPI=m +CONFIG_DRM_OMAP_PANEL_DSI_CM=m +CONFIG_DRM_OMAP_PANEL_SONY_ACX565AKM=m +CONFIG_DRM_OMAP_PANEL_LGPHILIPS_LB035Q02=m +CONFIG_DRM_OMAP_PANEL_SHARP_LS037V7DW01=m +CONFIG_DRM_OMAP_PANEL_TPO_TD028TTEC1=m +CONFIG_DRM_OMAP_PANEL_TPO_TD043MTEA1=m +CONFIG_DRM_OMAP_PANEL_NEC_NL8048HL11=m +CONFIG_DRM_TILCDC=m CONFIG_FB=y CONFIG_FIRMWARE_EDID=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y -CONFIG_FB_OMAP2=m -CONFIG_FB_OMAP5_DSS_HDMI=y -CONFIG_FB_OMAP2_DSS_SDI=y -CONFIG_FB_OMAP2_DSS_DSI=y -CONFIG_FB_OMAP2_ENCODER_TFP410=m -CONFIG_FB_OMAP2_ENCODER_TPD12S015=m -CONFIG_FB_OMAP2_CONNECTOR_DVI=m -CONFIG_FB_OMAP2_CONNECTOR_HDMI=m -CONFIG_FB_OMAP2_CONNECTOR_ANALOG_TV=m -CONFIG_FB_OMAP2_PANEL_DPI=m -CONFIG_FB_OMAP2_PANEL_DSI_CM=m -CONFIG_FB_OMAP2_PANEL_SONY_ACX565AKM=m -CONFIG_FB_OMAP2_PANEL_LGPHILIPS_LB035Q02=m -CONFIG_FB_OMAP2_PANEL_SHARP_LS037V7DW01=m -CONFIG_FB_OMAP2_PANEL_TPO_TD028TTEC1=m -CONFIG_FB_OMAP2_PANEL_TPO_TD043MTEA1=m -CONFIG_FB_OMAP2_PANEL_NEC_NL8048HL11=m -CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_LCD_PLATFORM=y CONFIG_BACKLIGHT_CLASS_DEVICE=y @@ -356,11 +370,11 @@ CONFIG_BACKLIGHT_PWM=m CONFIG_BACKLIGHT_PANDORA=m CONFIG_BACKLIGHT_GPIO=m CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_LOGO=y CONFIG_SOUND=m CONFIG_SND=m +CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m CONFIG_SND_VERBOSE_PRINTK=y @@ -374,7 +388,9 @@ CONFIG_SND_OMAP_SOC_HDMI_AUDIO=m CONFIG_SND_OMAP_SOC_OMAP_TWL4030=m CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040=m CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m +CONFIG_SND_SOC_CPCAP=m CONFIG_SND_SIMPLE_CARD=m +CONFIG_SND_AUDIO_GRAPH_CARD=m CONFIG_HID_GENERIC=m CONFIG_USB_HIDDEV=y CONFIG_USB_KBD=m @@ -385,7 +401,6 @@ CONFIG_USB_MON=m CONFIG_USB_XHCI_HCD=m CONFIG_USB_EHCI_HCD=m CONFIG_USB_OHCI_HCD=m -CONFIG_USB_WDM=m CONFIG_USB_ACM=m CONFIG_USB_STORAGE=m CONFIG_USB_MUSB_HDRC=m @@ -462,10 +477,16 @@ CONFIG_DMADEVICES=y CONFIG_DMA_OMAP=y CONFIG_TI_EDMA=y CONFIG_OMAP_IOMMU=y -CONFIG_EXTCON=m +CONFIG_REMOTEPROC=m +CONFIG_OMAP_REMOTEPROC=m +CONFIG_WKUP_M3_RPROC=m +CONFIG_SOC_TI=y +CONFIG_AMX3_PM=m +CONFIG_WKUP_M3_IPC=m CONFIG_EXTCON_PALMAS=m CONFIG_EXTCON_USB_GPIO=m CONFIG_TI_EMIF=m +CONFIG_TI_EMIF_SRAM=m CONFIG_IIO=m CONFIG_IIO_SW_DEVICE=m CONFIG_IIO_SW_TRIGGER=m @@ -480,6 +501,7 @@ CONFIG_PWM_TIEHRPWM=m CONFIG_PWM_TWL=m CONFIG_PWM_TWL_LED=m CONFIG_PHY_CPCAP_USB=m +CONFIG_PHY_MAPPHONE_MDM6600=m CONFIG_PHY_DM816X_USB=m CONFIG_OMAP_USB2=m CONFIG_TI_PIPE3=y @@ -494,7 +516,6 @@ CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y -CONFIG_CONFIGFS_FS=y CONFIG_JFFS2_FS=y CONFIG_JFFS2_SUMMARY=y CONFIG_JFFS2_FS_XATTR=y @@ -515,11 +536,18 @@ CONFIG_DEBUG_INFO_SPLIT=y CONFIG_DEBUG_INFO_DWARF4=y CONFIG_MAGIC_SYSRQ=y CONFIG_SCHEDSTATS=y -CONFIG_TIMER_STATS=y CONFIG_PROVE_LOCKING=y # CONFIG_DEBUG_BUGVERBOSE is not set CONFIG_SECURITY=y CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_ARM_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM_NEON=m +CONFIG_CRYPTO_SHA256_ARM=m +CONFIG_CRYPTO_SHA512_ARM=m +CONFIG_CRYPTO_AES_ARM=m +CONFIG_CRYPTO_AES_ARM_BS=m +CONFIG_CRYPTO_GHASH_ARM_CE=m +CONFIG_CRYPTO_CHACHA20_NEON=m CONFIG_CRC_CCITT=y CONFIG_CRC_T10DIF=y CONFIG_CRC_ITU_T=y @@ -528,13 +556,3 @@ CONFIG_LIBCRC32C=y CONFIG_FONTS=y CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y -CONFIG_KERNEL_MODE_NEON=y -CONFIG_ARM_CRYPTO=y -CONFIG_CRYPTO_SHA1_ARM=m -CONFIG_CRYPTO_SHA1_ARM_NEON=m -CONFIG_CRYPTO_SHA256_ARM=m -CONFIG_CRYPTO_SHA512_ARM=m -CONFIG_CRYPTO_AES_ARM=m -CONFIG_CRYPTO_AES_ARM_BS=m -CONFIG_CRYPTO_CHACHA20_NEON=m -CONFIG_CRYPTO_GHASH_ARM_CE=m diff --git a/arch/arm/configs/oxnas_v6_defconfig b/arch/arm/configs/oxnas_v6_defconfig new file mode 100644 index 000000000000..f6ba32c9d173 --- /dev/null +++ b/arch/arm/configs/oxnas_v6_defconfig @@ -0,0 +1,93 @@ +CONFIG_SYSVIPC=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_CGROUPS=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EMBEDDED=y +CONFIG_PERF_EVENTS=y +CONFIG_STRICT_KERNEL_RWX=y +CONFIG_STRICT_MODULE_RWX=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_PARTITION_ADVANCED=y +CONFIG_CMDLINE_PARTITION=y +CONFIG_ARCH_MULTI_V6=y +CONFIG_ARCH_OXNAS=y +CONFIG_MACH_OX820=y +CONFIG_SMP=y +CONFIG_NR_CPUS=16 +CONFIG_CMA=y +CONFIG_FORCE_MAX_ZONEORDER=12 +CONFIG_SECCOMP=y +CONFIG_ARM_APPENDED_DTB=y +CONFIG_ARM_ATAG_DTB_COMPAT=y +CONFIG_KEXEC=y +CONFIG_EFI=y +CONFIG_CPU_IDLE=y +CONFIG_ARM_CPUIDLE=y +CONFIG_VFP=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_IPV6_MIP6=m +CONFIG_IPV6_TUNNEL=m +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=64 +CONFIG_SIMPLE_PM_BUS=y +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_OXNAS=y +CONFIG_MTD_UBI=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_NETDEVICES=y +CONFIG_STMMAC_ETH=y +CONFIG_REALTEK_PHY=y +CONFIG_INPUT_EVDEV=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_GPIO_GENERIC_PLATFORM=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_CLASS_FLASH=m +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_GPIO=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_ARM_TIMER_SP804=y +CONFIG_EXT4_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_UBIFS_FS=y +CONFIG_PSTORE=y +CONFIG_PSTORE_CONSOLE=y +CONFIG_PSTORE_PMSG=y +CONFIG_PSTORE_RAM=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_UTF8=y +CONFIG_PRINTK_TIME=y +CONFIG_MAGIC_SYSRQ=y diff --git a/arch/arm/configs/pxa3xx_defconfig b/arch/arm/configs/pxa3xx_defconfig index bfea6874b0a1..3e0de035ab77 100644 --- a/arch/arm/configs/pxa3xx_defconfig +++ b/arch/arm/configs/pxa3xx_defconfig @@ -32,8 +32,7 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y CONFIG_MTD_BLOCK=y CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_PXA3xx=y -CONFIG_MTD_NAND_PXA3xx_BUILTIN=y +CONFIG_MTD_NAND_MARVELL=y CONFIG_MTD_ONENAND=y CONFIG_MTD_ONENAND_VERIFY_WRITE=y CONFIG_MTD_ONENAND_GENERIC=y diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig index 837d0c9c8b0e..5655a1cee87d 100644 --- a/arch/arm/configs/pxa_defconfig +++ b/arch/arm/configs/pxa_defconfig @@ -197,7 +197,7 @@ CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0x4000000 CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH=y CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE=y CONFIG_MTD_NAND_SHARPSL=m -CONFIG_MTD_NAND_PXA3xx=m +CONFIG_MTD_NAND_MARVELL=m CONFIG_MTD_NAND_CM_X270=m CONFIG_MTD_NAND_TMIO=m CONFIG_MTD_NAND_BRCMNAND=m diff --git a/arch/arm/configs/raumfeld_defconfig b/arch/arm/configs/raumfeld_defconfig index 77a56c23c6ef..2dd56e9a484e 100644 --- a/arch/arm/configs/raumfeld_defconfig +++ b/arch/arm/configs/raumfeld_defconfig @@ -33,7 +33,7 @@ CONFIG_NFTL=y CONFIG_NFTL_RW=y CONFIG_MTD_BLOCK2MTD=y CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_PXA3xx=y +CONFIG_MTD_NAND_MARVELL=y CONFIG_MTD_UBI=y CONFIG_BLK_DEV_LOOP=y CONFIG_ISL29003=y diff --git a/arch/arm/configs/realview_defconfig b/arch/arm/configs/realview_defconfig index 2a6d69d896bd..cc9fa24d4b8f 100644 --- a/arch/arm/configs/realview_defconfig +++ b/arch/arm/configs/realview_defconfig @@ -11,19 +11,17 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_IOSCHED_CFQ is not set CONFIG_ARCH_MULTI_V6=y CONFIG_ARCH_REALVIEW=y -CONFIG_REALVIEW_DT=y CONFIG_MACH_REALVIEW_EB=y CONFIG_REALVIEW_EB_ARM1136=y CONFIG_REALVIEW_EB_ARM1176=y CONFIG_REALVIEW_EB_A9MP=y CONFIG_REALVIEW_EB_ARM11MP=y -CONFIG_REALVIEW_EB_ARM11MP_REVB=y CONFIG_MACH_REALVIEW_PB11MP=y CONFIG_MACH_REALVIEW_PB1176=y CONFIG_MACH_REALVIEW_PBA8=y CONFIG_MACH_REALVIEW_PBX=y CONFIG_SMP=y -CONFIG_AEABI=y +CONFIG_CMA=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE="root=/dev/nfs nfsroot=10.1.69.3:/work/nfsroot ip=dhcp console=ttyAMA0 mem=128M" @@ -46,7 +44,7 @@ CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_ROM=y CONFIG_MTD_PHYSMAP=y -CONFIG_ARM_CHARLCD=y +CONFIG_MTD_PHYSMAP_OF=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y @@ -59,21 +57,21 @@ CONFIG_LEGACY_PTY_COUNT=16 CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y # CONFIG_HW_RANDOM is not set -CONFIG_I2C=y CONFIG_I2C_VERSATILE=y CONFIG_SPI=y CONFIG_GPIOLIB=y # CONFIG_HWMON is not set -CONFIG_FB=y -CONFIG_FB_ARMCLCD=y -CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_DRM=y +CONFIG_DRM_PANEL_SIMPLE=y +CONFIG_DRM_PL111=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_SOUND=y CONFIG_SND=y -CONFIG_SND_MIXER_OSS=y -CONFIG_SND_PCM_OSS=y # CONFIG_SND_DRIVERS is not set CONFIG_SND_ARMAACI=y CONFIG_USB=y @@ -83,13 +81,14 @@ CONFIG_MMC=y CONFIG_MMC_ARMMMCI=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y -CONFIG_LEDS_VERSATILE=y CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_CPU=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_DS1307=y CONFIG_RTC_DRV_PL031=y +CONFIG_AUXDISPLAY=y +CONFIG_ARM_CHARLCD=y CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_CRAMFS=y diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig index 578434cfd1a0..a701601fbd76 100644 --- a/arch/arm/configs/shmobile_defconfig +++ b/arch/arm/configs/shmobile_defconfig @@ -5,8 +5,6 @@ CONFIG_IKCONFIG_PROC=y CONFIG_CGROUPS=y CONFIG_BLK_DEV_INITRD=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_EMBEDDED=y CONFIG_PERF_EVENTS=y CONFIG_SLAB=y CONFIG_ARCH_RENESAS=y @@ -34,7 +32,6 @@ CONFIG_SMP=y CONFIG_SCHED_MC=y CONFIG_HAVE_ARM_ARCH_TIMER=y CONFIG_NR_CPUS=8 -CONFIG_AEABI=y CONFIG_HIGHMEM=y CONFIG_CMA=y CONFIG_ZBOOT_ROM_TEXT=0x0 @@ -104,9 +101,6 @@ CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_EM=y CONFIG_SERIAL_SH_SCI=y -CONFIG_SERIAL_SH_SCI_NR_UARTS=20 -CONFIG_SERIAL_SH_SCI_CONSOLE=y -CONFIG_SERIAL_SH_SCI_DMA=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MUX=y CONFIG_I2C_DEMUX_PINCTRL=y @@ -120,6 +114,7 @@ CONFIG_SPI=y CONFIG_SPI_RSPI=y CONFIG_SPI_SH_MSIOF=y CONFIG_SPI_SH_HSPI=y +CONFIG_PINCTRL_RZA1=y CONFIG_GPIO_EM=y CONFIG_GPIO_RCAR=y CONFIG_GPIO_PCF857X=y @@ -166,7 +161,6 @@ CONFIG_FB_SH_MOBILE_MERAM=y # CONFIG_BACKLIGHT_GENERIC is not set CONFIG_BACKLIGHT_PWM=y CONFIG_BACKLIGHT_AS3711=y -CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_SOC=y @@ -227,4 +221,5 @@ CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_DEBUG_KERNEL=y # CONFIG_ARM_UNWIND is not set diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig index bb358ffde7d2..ba805b757a8d 100644 --- a/arch/arm/configs/stm32_defconfig +++ b/arch/arm/configs/stm32_defconfig @@ -57,6 +57,8 @@ CONFIG_MFD_STMPE=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y # CONFIG_USB_SUPPORT is not set +CONFIG_MMC=y +CONFIG_MMC_ARMMMCI=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_GPIO=y @@ -71,6 +73,7 @@ CONFIG_STM32_MDMA=y CONFIG_IIO=y CONFIG_STM32_ADC_CORE=y CONFIG_STM32_ADC=y +CONFIG_EXT3_FS=y # CONFIG_FILE_LOCKING is not set # CONFIG_DNOTIFY is not set # CONFIG_INOTIFY_USER is not set diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig index 295408ea9dc7..df68dc4056e5 100644 --- a/arch/arm/configs/versatile_defconfig +++ b/arch/arm/configs/versatile_defconfig @@ -12,6 +12,7 @@ CONFIG_PARTITION_ADVANCED=y CONFIG_ARCH_VERSATILE=y CONFIG_AEABI=y CONFIG_OABI_COMPAT=y +CONFIG_CMA=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE="root=1f03 mem=32M" @@ -32,7 +33,9 @@ CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_ADV_OPTIONS=y CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y CONFIG_BLK_DEV_RAM=y CONFIG_EEPROM_LEGACY=m CONFIG_NETDEVICES=y @@ -47,21 +50,22 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_8250_RSA=y CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -CONFIG_I2C=y CONFIG_I2C_CHARDEV=m CONFIG_I2C_VERSATILE=y CONFIG_SPI=y CONFIG_GPIOLIB=y CONFIG_GPIO_PL061=y # CONFIG_HWMON is not set -CONFIG_MFD_SYSCON=y -CONFIG_FB=y -CONFIG_FB_ARMCLCD=y -CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_DRM=y +CONFIG_DRM_PANEL_ARM_VERSATILE=y +CONFIG_DRM_PANEL_SIMPLE=y +CONFIG_DRM_PL111=y +CONFIG_FB_MODE_HELPERS=y +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_LOGO=y CONFIG_SOUND=y CONFIG_SND=m -CONFIG_SND_MIXER_OSS=m -CONFIG_SND_PCM_OSS=m CONFIG_SND_ARMAACI=m CONFIG_MMC=y CONFIG_MMC_ARMMMCI=y diff --git a/arch/arm/include/debug/exynos.S b/arch/arm/include/debug/exynos.S index 60bf3c23200d..74b56769f9cb 100644 --- a/arch/arm/include/debug/exynos.S +++ b/arch/arm/include/debug/exynos.S @@ -1,11 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. * http://www.samsung.com - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ + */ /* pull in the relevant register and map files. */ diff --git a/arch/arm/include/debug/samsung.S b/arch/arm/include/debug/samsung.S index f4eeed2a1981..69201d7fb48f 100644 --- a/arch/arm/include/debug/samsung.S +++ b/arch/arm/include/debug/samsung.S @@ -1,13 +1,9 @@ -/* arch/arm/plat-samsung/include/plat/debug-macro.S - * +/* SPDX-License-Identifier: GPL-2.0 */ +/* * Copyright 2005, 2007 Simtec Electronics * http://armlinux.simtec.co.uk/ * Ben Dooks <ben@simtec.co.uk> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ + */ #include <linux/serial_s3c.h> diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 6d870421a7a6..1254bf9d91b4 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -1,5 +1,5 @@ menuconfig ARCH_AT91 - bool "Atmel SoCs" + bool "AT91/Microchip SoCs" depends on ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V7 || ARM_SINGLE_ARMV7M select ARM_CPU_SUSPEND if PM && ARCH_MULTI_V7 select COMMON_CLK_AT91 @@ -13,7 +13,7 @@ config SOC_SAMV7 select COMMON_CLK_AT91 select PINCTRL_AT91 help - Select this if you are using an SoC from Atmel's SAME7, SAMS7 or SAMV7 + Select this if you are using an SoC from Microchip's SAME7, SAMS7 or SAMV7 families. config SOC_SAMA5D2 @@ -29,7 +29,7 @@ config SOC_SAMA5D2 select HAVE_AT91_AUDIO_PLL select PINCTRL_AT91PIO4 help - Select this if ou are using one of Atmel's SAMA5D2 family SoC. + Select this if ou are using one of Microchip's SAMA5D2 family SoC. config SOC_SAMA5D3 bool "SAMA5D3 family" @@ -41,7 +41,7 @@ config SOC_SAMA5D3 select HAVE_AT91_USB_CLK select PINCTRL_AT91 help - Select this if you are using one of Atmel's SAMA5D3 family SoC. + Select this if you are using one of Microchip's SAMA5D3 family SoC. This support covers SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35, SAMA5D36. config SOC_SAMA5D4 @@ -56,7 +56,7 @@ config SOC_SAMA5D4 select HAVE_AT91_H32MX select PINCTRL_AT91 help - Select this if you are using one of Atmel's SAMA5D4 family SoC. + Select this if you are using one of Microchip's SAMA5D4 family SoC. config SOC_AT91RM9200 bool "AT91RM9200" @@ -70,7 +70,7 @@ config SOC_AT91RM9200 select SOC_SAM_V4_V5 select SRAM if PM help - Select this if you are using Atmel's AT91RM9200 SoC. + Select this if you are using Microchip's AT91RM9200 SoC. config SOC_AT91SAM9 bool "AT91SAM9" @@ -88,7 +88,7 @@ config SOC_AT91SAM9 select SOC_SAM_V4_V5 select SRAM if PM help - Select this if you are using one of those Atmel SoC: + Select this if you are using one of those Microchip SoC: AT91SAM9260 AT91SAM9261 AT91SAM9263 diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index f673cd7a6766..004f9c8de032 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -239,20 +239,6 @@ static inline void da830_evm_init_mmc(void) } } -/* - * UI board NAND/NOR flashes only use 8-bit data bus. - */ -static const short da830_evm_emif25_pins[] = { - DA830_EMA_D_0, DA830_EMA_D_1, DA830_EMA_D_2, DA830_EMA_D_3, - DA830_EMA_D_4, DA830_EMA_D_5, DA830_EMA_D_6, DA830_EMA_D_7, - DA830_EMA_A_0, DA830_EMA_A_1, DA830_EMA_A_2, DA830_EMA_A_3, - DA830_EMA_A_4, DA830_EMA_A_5, DA830_EMA_A_6, DA830_EMA_A_7, - DA830_EMA_A_8, DA830_EMA_A_9, DA830_EMA_A_10, DA830_EMA_A_11, - DA830_EMA_A_12, DA830_EMA_BA_0, DA830_EMA_BA_1, DA830_NEMA_WE, - DA830_NEMA_CS_2, DA830_NEMA_CS_3, DA830_NEMA_OE, DA830_EMA_WAIT_0, - -1 -}; - #define HAS_MMC IS_ENABLED(CONFIG_MMC_DAVINCI) #ifdef CONFIG_DA830_UI_NAND @@ -357,6 +343,20 @@ static struct platform_device da830_evm_nand_device = { .resource = da830_evm_nand_resources, }; +/* + * UI board NAND/NOR flashes only use 8-bit data bus. + */ +static const short da830_evm_emif25_pins[] = { + DA830_EMA_D_0, DA830_EMA_D_1, DA830_EMA_D_2, DA830_EMA_D_3, + DA830_EMA_D_4, DA830_EMA_D_5, DA830_EMA_D_6, DA830_EMA_D_7, + DA830_EMA_A_0, DA830_EMA_A_1, DA830_EMA_A_2, DA830_EMA_A_3, + DA830_EMA_A_4, DA830_EMA_A_5, DA830_EMA_A_6, DA830_EMA_A_7, + DA830_EMA_A_8, DA830_EMA_A_9, DA830_EMA_A_10, DA830_EMA_A_11, + DA830_EMA_A_12, DA830_EMA_BA_0, DA830_EMA_BA_1, DA830_NEMA_WE, + DA830_NEMA_CS_2, DA830_NEMA_CS_3, DA830_NEMA_OE, DA830_EMA_WAIT_0, + -1 +}; + static inline void da830_evm_init_nand(int mux_mode) { int ret; @@ -551,10 +551,6 @@ static __init void da830_evm_init(void) struct davinci_soc_info *soc_info = &davinci_soc_info; int ret; - ret = da8xx_register_cfgchip(); - if (ret) - pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret); - ret = da830_register_gpio(); if (ret) pr_warn("%s: GPIO init failed: %d\n", __func__, ret); @@ -638,9 +634,8 @@ MACHINE_START(DAVINCI_DA830_EVM, "DaVinci DA830/OMAP-L137/AM17x EVM") .atag_offset = 0x100, .map_io = da830_evm_map_io, .init_irq = cp_intc_init, - .init_time = davinci_timer_init, + .init_time = da830_init_time, .init_machine = da830_evm_init, .init_late = davinci_init_late, .dma_zone_size = SZ_128M, - .restart = da8xx_restart, MACHINE_END diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index d898a94f6eae..3063478bcc36 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -1334,10 +1334,6 @@ static __init void da850_evm_init(void) { int ret; - ret = da8xx_register_cfgchip(); - if (ret) - pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret); - ret = da850_register_gpio(); if (ret) pr_warn("%s: GPIO init failed: %d\n", __func__, ret); @@ -1481,10 +1477,9 @@ MACHINE_START(DAVINCI_DA850_EVM, "DaVinci DA850/OMAP-L138/AM18x EVM") .atag_offset = 0x100, .map_io = da850_evm_map_io, .init_irq = cp_intc_init, - .init_time = davinci_timer_init, + .init_time = da850_init_time, .init_machine = da850_evm_init, .init_late = davinci_init_late, .dma_zone_size = SZ_128M, - .restart = da8xx_restart, .reserve = da8xx_rproc_reserve_cma, MACHINE_END diff --git a/arch/arm/mach-davinci/board-dm355-evm.c b/arch/arm/mach-davinci/board-dm355-evm.c index d6b11907380c..cb30637d9eaf 100644 --- a/arch/arm/mach-davinci/board-dm355-evm.c +++ b/arch/arm/mach-davinci/board-dm355-evm.c @@ -427,9 +427,8 @@ MACHINE_START(DAVINCI_DM355_EVM, "DaVinci DM355 EVM") .atag_offset = 0x100, .map_io = dm355_evm_map_io, .init_irq = davinci_irq_init, - .init_time = davinci_timer_init, + .init_time = dm355_init_time, .init_machine = dm355_evm_init, .init_late = davinci_init_late, .dma_zone_size = SZ_128M, - .restart = davinci_restart, MACHINE_END diff --git a/arch/arm/mach-davinci/board-dm355-leopard.c b/arch/arm/mach-davinci/board-dm355-leopard.c index fad9a5611a5d..59743bd76793 100644 --- a/arch/arm/mach-davinci/board-dm355-leopard.c +++ b/arch/arm/mach-davinci/board-dm355-leopard.c @@ -271,9 +271,8 @@ MACHINE_START(DM355_LEOPARD, "DaVinci DM355 leopard") .atag_offset = 0x100, .map_io = dm355_leopard_map_io, .init_irq = davinci_irq_init, - .init_time = davinci_timer_init, + .init_time = dm355_init_time, .init_machine = dm355_leopard_init, .init_late = davinci_init_late, .dma_zone_size = SZ_128M, - .restart = davinci_restart, MACHINE_END diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index e3780986d2a3..0ac085b58a2b 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -774,10 +774,9 @@ MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM") .atag_offset = 0x100, .map_io = dm365_evm_map_io, .init_irq = davinci_irq_init, - .init_time = davinci_timer_init, + .init_time = dm365_init_time, .init_machine = dm365_evm_init, .init_late = davinci_init_late, .dma_zone_size = SZ_128M, - .restart = davinci_restart, MACHINE_END diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 85e6fb33b1ee..95b55aae1366 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -828,9 +828,8 @@ MACHINE_START(DAVINCI_EVM, "DaVinci DM644x EVM") .atag_offset = 0x100, .map_io = davinci_evm_map_io, .init_irq = davinci_irq_init, - .init_time = davinci_timer_init, + .init_time = dm644x_init_time, .init_machine = davinci_evm_init, .init_late = davinci_init_late, .dma_zone_size = SZ_128M, - .restart = davinci_restart, MACHINE_END diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index cb0a41e83582..2d37f5b0e1f5 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -44,10 +44,8 @@ #include <mach/common.h> #include <mach/irqs.h> #include <mach/serial.h> -#include <mach/clock.h> #include "davinci.h" -#include "clock.h" #define NAND_BLOCK_SIZE SZ_128K @@ -716,14 +714,23 @@ static void __init evm_init_i2c(void) } #endif +#define DM646X_REF_FREQ 27000000 +#define DM646X_AUX_FREQ 24000000 #define DM6467T_EVM_REF_FREQ 33000000 static void __init davinci_map_io(void) { dm646x_init(); +} - if (machine_is_davinci_dm6467tevm()) - davinci_set_refclk_rate(DM6467T_EVM_REF_FREQ); +static void __init dm646x_evm_init_time(void) +{ + dm646x_init_time(DM646X_REF_FREQ, DM646X_AUX_FREQ); +} + +static void __init dm6467t_evm_init_time(void) +{ + dm646x_init_time(DM6467T_EVM_REF_FREQ, DM646X_AUX_FREQ); } #define DM646X_EVM_PHY_ID "davinci_mdio-0:01" @@ -797,21 +804,19 @@ MACHINE_START(DAVINCI_DM6467_EVM, "DaVinci DM646x EVM") .atag_offset = 0x100, .map_io = davinci_map_io, .init_irq = davinci_irq_init, - .init_time = davinci_timer_init, + .init_time = dm646x_evm_init_time, .init_machine = evm_init, .init_late = davinci_init_late, .dma_zone_size = SZ_128M, - .restart = davinci_restart, MACHINE_END MACHINE_START(DAVINCI_DM6467TEVM, "DaVinci DM6467T EVM") .atag_offset = 0x100, .map_io = davinci_map_io, .init_irq = davinci_irq_init, - .init_time = davinci_timer_init, + .init_time = dm6467t_evm_init_time, .init_machine = evm_init, .init_late = davinci_init_late, .dma_zone_size = SZ_128M, - .restart = davinci_restart, MACHINE_END diff --git a/arch/arm/mach-davinci/board-mityomapl138.c b/arch/arm/mach-davinci/board-mityomapl138.c index b73ce7bae81f..d1c85484c2e2 100644 --- a/arch/arm/mach-davinci/board-mityomapl138.c +++ b/arch/arm/mach-davinci/board-mityomapl138.c @@ -502,10 +502,6 @@ static void __init mityomapl138_init(void) { int ret; - ret = da8xx_register_cfgchip(); - if (ret) - pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret); - /* for now, no special EDMA channels are reserved */ ret = da850_register_edma(NULL); if (ret) @@ -570,9 +566,8 @@ MACHINE_START(MITYOMAPL138, "MityDSP-L138/MityARM-1808") .atag_offset = 0x100, .map_io = mityomapl138_map_io, .init_irq = cp_intc_init, - .init_time = davinci_timer_init, + .init_time = da850_init_time, .init_machine = mityomapl138_init, .init_late = davinci_init_late, .dma_zone_size = SZ_128M, - .restart = da8xx_restart, MACHINE_END diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c index 4da210a1a110..f2875770fbff 100644 --- a/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/arch/arm/mach-davinci/board-neuros-osd2.c @@ -227,9 +227,8 @@ MACHINE_START(NEUROS_OSD2, "Neuros OSD2") .atag_offset = 0x100, .map_io = davinci_ntosd2_map_io, .init_irq = davinci_irq_init, - .init_time = davinci_timer_init, + .init_time = dm644x_init_time, .init_machine = davinci_ntosd2_init, .init_late = davinci_init_late, .dma_zone_size = SZ_128M, - .restart = davinci_restart, MACHINE_END diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index 62eb7d668890..0d32042b728f 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -281,10 +281,6 @@ static __init void omapl138_hawk_init(void) { int ret; - ret = da8xx_register_cfgchip(); - if (ret) - pr_warn("%s: CFGCHIP registration failed: %d\n", __func__, ret); - ret = da850_register_gpio(); if (ret) pr_warn("%s: GPIO init failed: %d\n", __func__, ret); @@ -334,10 +330,9 @@ MACHINE_START(OMAPL138_HAWKBOARD, "AM18x/OMAP-L138 Hawkboard") .atag_offset = 0x100, .map_io = omapl138_hawk_map_io, .init_irq = cp_intc_init, - .init_time = davinci_timer_init, + .init_time = da850_init_time, .init_machine = omapl138_hawk_init, .init_late = davinci_init_late, .dma_zone_size = SZ_128M, - .restart = da8xx_restart, .reserve = da8xx_rproc_reserve_cma, MACHINE_END diff --git a/arch/arm/mach-davinci/board-sffsdr.c b/arch/arm/mach-davinci/board-sffsdr.c index d85accf7f760..2922da9d1684 100644 --- a/arch/arm/mach-davinci/board-sffsdr.c +++ b/arch/arm/mach-davinci/board-sffsdr.c @@ -150,9 +150,8 @@ MACHINE_START(SFFSDR, "Lyrtech SFFSDR") .atag_offset = 0x100, .map_io = davinci_sffsdr_map_io, .init_irq = davinci_irq_init, - .init_time = davinci_timer_init, + .init_time = dm644x_init_time, .init_machine = davinci_sffsdr_init, .init_late = davinci_init_late, .dma_zone_size = SZ_128M, - .restart = davinci_restart, MACHINE_END diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h index fa2b83752e03..d7894d5aaa25 100644 --- a/arch/arm/mach-davinci/clock.h +++ b/arch/arm/mach-davinci/clock.h @@ -135,9 +135,6 @@ int davinci_clk_reset(struct clk *clk, bool reset); void davinci_clk_enable(struct clk *clk); void davinci_clk_disable(struct clk *clk); -extern struct platform_device davinci_wdt_device; -extern void davinci_watchdog_reset(struct platform_device *); - #endif #endif diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c index 57ab18cf2a89..350d7673aa4d 100644 --- a/arch/arm/mach-davinci/da830.c +++ b/arch/arm/mach-davinci/da830.c @@ -1200,7 +1200,6 @@ static const struct davinci_soc_info davinci_soc_info_da830 = { .jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG, .ids = da830_ids, .ids_num = ARRAY_SIZE(da830_ids), - .cpu_clks = da830_clks, .psc_bases = da830_psc_bases, .psc_bases_num = ARRAY_SIZE(da830_psc_bases), .pinmux_base = DA8XX_SYSCFG0_BASE + 0x120, @@ -1220,6 +1219,10 @@ void __init da830_init(void) da8xx_syscfg0_base = ioremap(DA8XX_SYSCFG0_BASE, SZ_4K); WARN(!da8xx_syscfg0_base, "Unable to map syscfg0 module"); +} - davinci_clk_init(davinci_soc_info_da830.cpu_clks); +void __init da830_init_time(void) +{ + davinci_clk_init(da830_clks); + davinci_timer_init(); } diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c index aa37cbdf7d4d..34117e614e08 100644 --- a/arch/arm/mach-davinci/da850.c +++ b/arch/arm/mach-davinci/da850.c @@ -1353,7 +1353,6 @@ static const struct davinci_soc_info davinci_soc_info_da850 = { .jtag_id_reg = DA8XX_SYSCFG0_BASE + DA8XX_JTAG_ID_REG, .ids = da850_ids, .ids_num = ARRAY_SIZE(da850_ids), - .cpu_clks = da850_clks, .psc_bases = da850_psc_bases, .psc_bases_num = ARRAY_SIZE(da850_psc_bases), .pinmux_base = DA8XX_SYSCFG0_BASE + 0x120, @@ -1392,6 +1391,10 @@ void __init da850_init(void) v = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG)); v &= ~CFGCHIP3_PLL1_MASTER_LOCK; __raw_writel(v, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP3_REG)); +} - davinci_clk_init(davinci_soc_info_da850.cpu_clks); +void __init da850_init_time(void) +{ + davinci_clk_init(da850_clks); + davinci_timer_init(); } diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c index f06db6700ab2..ab199f4b9ce4 100644 --- a/arch/arm/mach-davinci/da8xx-dt.c +++ b/arch/arm/mach-davinci/da8xx-dt.c @@ -96,11 +96,10 @@ static const char *const da850_boards_compat[] __initconst = { DT_MACHINE_START(DA850_DT, "Generic DA850/OMAP-L138/AM18x") .map_io = da850_init, - .init_time = davinci_timer_init, + .init_time = da850_init_time, .init_machine = da850_init_machine, .dt_compat = da850_boards_compat, .init_late = davinci_init_late, - .restart = da8xx_restart, MACHINE_END #endif diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h index c62b90c6118a..270cef85750a 100644 --- a/arch/arm/mach-davinci/davinci.h +++ b/arch/arm/mach-davinci/davinci.h @@ -83,6 +83,7 @@ int davinci_init_wdt(void); /* DM355 function declarations */ void dm355_init(void); +void dm355_init_time(void); void dm355_init_spi0(unsigned chipselect_mask, const struct spi_board_info *info, unsigned len); void dm355_init_asp1(u32 evt_enable); @@ -91,6 +92,7 @@ int dm355_gpio_register(void); /* DM365 function declarations */ void dm365_init(void); +void dm365_init_time(void); void dm365_init_asp(void); void dm365_init_vc(void); void dm365_init_ks(struct davinci_ks_platform_data *pdata); @@ -102,12 +104,14 @@ int dm365_gpio_register(void); /* DM644x function declarations */ void dm644x_init(void); +void dm644x_init_time(void); void dm644x_init_asp(void); int dm644x_init_video(struct vpfe_config *, struct vpbe_config *); int dm644x_gpio_register(void); /* DM646x function declarations */ void dm646x_init(void); +void dm646x_init_time(unsigned long ref_clk_rate, unsigned long aux_clkin_rate); void dm646x_init_mcasp0(struct snd_platform_data *pdata); void dm646x_init_mcasp1(struct snd_platform_data *pdata); int dm646x_init_edma(struct edma_rsv_info *rsv); diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index e1c40e73d30a..78390c64e6ca 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -11,7 +11,6 @@ * (at your option) any later version. */ #include <linux/init.h> -#include <linux/platform_data/syscon.h> #include <linux/platform_device.h> #include <linux/dma-contiguous.h> #include <linux/serial_8250.h> @@ -371,19 +370,6 @@ static struct platform_device da8xx_wdt_device = { .resource = da8xx_watchdog_resources, }; -void da8xx_restart(enum reboot_mode mode, const char *cmd) -{ - struct device *dev; - - dev = bus_find_device_by_name(&platform_bus_type, NULL, "davinci-wdt"); - if (!dev) { - pr_err("%s: failed to find watchdog device\n", __func__); - return; - } - - davinci_watchdog_reset(to_platform_device(dev)); -} - int __init da8xx_register_watchdog(void) { return platform_device_register(&da8xx_wdt_device); @@ -1118,29 +1104,30 @@ int __init da850_register_sata(unsigned long refclkpn) } #endif -static struct syscon_platform_data da8xx_cfgchip_platform_data = { - .label = "cfgchip", -}; - -static struct resource da8xx_cfgchip_resources[] = { - { - .start = DA8XX_SYSCFG0_BASE + DA8XX_CFGCHIP0_REG, - .end = DA8XX_SYSCFG0_BASE + DA8XX_CFGCHIP4_REG + 3, - .flags = IORESOURCE_MEM, - }, -}; +static struct regmap *da8xx_cfgchip; -static struct platform_device da8xx_cfgchip_device = { - .name = "syscon", - .id = -1, - .dev = { - .platform_data = &da8xx_cfgchip_platform_data, - }, - .num_resources = ARRAY_SIZE(da8xx_cfgchip_resources), - .resource = da8xx_cfgchip_resources, +static const struct regmap_config da8xx_cfgchip_config __initconst = { + .name = "cfgchip", + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = DA8XX_CFGCHIP4_REG - DA8XX_CFGCHIP0_REG, }; -int __init da8xx_register_cfgchip(void) +/** + * da8xx_get_cfgchip - Lazy gets CFGCHIP as regmap + * + * This is for use on non-DT boards only. For DT boards, use + * syscon_regmap_lookup_by_compatible("ti,da830-cfgchip") + * + * Returns: Pointer to the CFGCHIP regmap or negative error code. + */ +struct regmap * __init da8xx_get_cfgchip(void) { - return platform_device_register(&da8xx_cfgchip_device); + if (IS_ERR_OR_NULL(da8xx_cfgchip)) + da8xx_cfgchip = regmap_init_mmio(NULL, + DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP0_REG), + &da8xx_cfgchip_config); + + return da8xx_cfgchip; } diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index 3ae70f2909b0..0edda4093e47 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -282,18 +282,13 @@ static struct resource wdt_resources[] = { }, }; -struct platform_device davinci_wdt_device = { +static struct platform_device davinci_wdt_device = { .name = "davinci-wdt", .id = -1, .num_resources = ARRAY_SIZE(wdt_resources), .resource = wdt_resources, }; -void davinci_restart(enum reboot_mode mode, const char *cmd) -{ - davinci_watchdog_reset(&davinci_wdt_device); -} - int davinci_init_wdt(void) { return platform_device_register(&davinci_wdt_device); diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 938747f20c22..f29480495c18 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c @@ -1012,7 +1012,6 @@ static const struct davinci_soc_info davinci_soc_info_dm355 = { .jtag_id_reg = 0x01c40028, .ids = dm355_ids, .ids_num = ARRAY_SIZE(dm355_ids), - .cpu_clks = dm355_clks, .psc_bases = dm355_psc_bases, .psc_bases_num = ARRAY_SIZE(dm355_psc_bases), .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE, @@ -1043,7 +1042,12 @@ void __init dm355_init(void) { davinci_common_init(&davinci_soc_info_dm355); davinci_map_sysmod(); - davinci_clk_init(davinci_soc_info_dm355.cpu_clks); +} + +void __init dm355_init_time(void) +{ + davinci_clk_init(dm355_clks); + davinci_timer_init(); } int __init dm355_init_video(struct vpfe_config *vpfe_cfg, diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 5d9f96df08e9..1e3df9df1e10 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -1116,7 +1116,6 @@ static const struct davinci_soc_info davinci_soc_info_dm365 = { .jtag_id_reg = 0x01c40028, .ids = dm365_ids, .ids_num = ARRAY_SIZE(dm365_ids), - .cpu_clks = dm365_clks, .psc_bases = dm365_psc_bases, .psc_bases_num = ARRAY_SIZE(dm365_psc_bases), .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE, @@ -1168,7 +1167,12 @@ void __init dm365_init(void) { davinci_common_init(&davinci_soc_info_dm365); davinci_map_sysmod(); - davinci_clk_init(davinci_soc_info_dm365.cpu_clks); +} + +void __init dm365_init_time(void) +{ + davinci_clk_init(dm365_clks); + davinci_timer_init(); } static struct resource dm365_vpss_resources[] = { diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 6b41e1ca511e..b409801649e1 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -905,7 +905,6 @@ static const struct davinci_soc_info davinci_soc_info_dm644x = { .jtag_id_reg = 0x01c40028, .ids = dm644x_ids, .ids_num = ARRAY_SIZE(dm644x_ids), - .cpu_clks = dm644x_clks, .psc_bases = dm644x_psc_bases, .psc_bases_num = ARRAY_SIZE(dm644x_psc_bases), .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE, @@ -931,7 +930,12 @@ void __init dm644x_init(void) { davinci_common_init(&davinci_soc_info_dm644x); davinci_map_sysmod(); - davinci_clk_init(davinci_soc_info_dm644x.cpu_clks); +} + +void __init dm644x_init_time(void) +{ + davinci_clk_init(dm644x_clks); + davinci_timer_init(); } int __init dm644x_init_video(struct vpfe_config *vpfe_cfg, diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 6fc06a6ad4f8..109ab1fa0d2c 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -39,12 +39,6 @@ #define VSCLKDIS_MASK (BIT_MASK(11) | BIT_MASK(10) | BIT_MASK(9) |\ BIT_MASK(8)) -/* - * Device specific clocks - */ -#define DM646X_REF_FREQ 27000000 -#define DM646X_AUX_FREQ 24000000 - #define DM646X_EMAC_BASE 0x01c80000 #define DM646X_EMAC_MDIO_BASE (DM646X_EMAC_BASE + 0x4000) #define DM646X_EMAC_CNTRL_OFFSET 0x0000 @@ -64,13 +58,12 @@ static struct pll_data pll2_data = { static struct clk ref_clk = { .name = "ref_clk", - .rate = DM646X_REF_FREQ, - .set_rate = davinci_simple_set_rate, + /* rate is initialized in dm646x_init_time() */ }; static struct clk aux_clkin = { .name = "aux_clkin", - .rate = DM646X_AUX_FREQ, + /* rate is initialized in dm646x_init_time() */ }; static struct clk pll1_clk = { @@ -888,7 +881,6 @@ static const struct davinci_soc_info davinci_soc_info_dm646x = { .jtag_id_reg = 0x01c40028, .ids = dm646x_ids, .ids_num = ARRAY_SIZE(dm646x_ids), - .cpu_clks = dm646x_clks, .psc_bases = dm646x_psc_bases, .psc_bases_num = ARRAY_SIZE(dm646x_psc_bases), .pinmux_base = DAVINCI_SYSTEM_MODULE_BASE, @@ -956,7 +948,15 @@ void __init dm646x_init(void) { davinci_common_init(&davinci_soc_info_dm646x); davinci_map_sysmod(); - davinci_clk_init(davinci_soc_info_dm646x.cpu_clks); +} + +void __init dm646x_init_time(unsigned long ref_clk_rate, + unsigned long aux_clkin_rate) +{ + ref_clk.rate = ref_clk_rate; + aux_clkin.rate = aux_clkin_rate; + davinci_clk_init(dm646x_clks); + davinci_timer_init(); } static int __init dm646x_init_devices(void) diff --git a/arch/arm/mach-davinci/include/mach/common.h b/arch/arm/mach-davinci/include/mach/common.h index 433a008ff796..f0d5e858f158 100644 --- a/arch/arm/mach-davinci/include/mach/common.h +++ b/arch/arm/mach-davinci/include/mach/common.h @@ -53,7 +53,6 @@ struct davinci_soc_info { u32 jtag_id_reg; struct davinci_id *ids; unsigned long ids_num; - struct clk_lookup *cpu_clks; u32 *psc_bases; unsigned long psc_bases_num; u32 pinmux_base; @@ -81,7 +80,6 @@ extern struct davinci_soc_info davinci_soc_info; extern void davinci_common_init(const struct davinci_soc_info *soc_info); extern void davinci_init_ide(void); -void davinci_restart(enum reboot_mode mode, const char *cmd); void davinci_init_late(void); #ifdef CONFIG_DAVINCI_RESET_CLOCKS diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index 93ff1569cee5..9fd6d0125762 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h @@ -18,6 +18,7 @@ #include <linux/spi/spi.h> #include <linux/platform_data/davinci_asp.h> #include <linux/reboot.h> +#include <linux/regmap.h> #include <linux/videodev2.h> #include <mach/serial.h> @@ -87,7 +88,10 @@ extern unsigned int da850_max_speed; #define DA8XX_ARM_RAM_BASE 0xffff0000 void da830_init(void); +void da830_init_time(void); + void da850_init(void); +void da850_init_time(void); int da830_register_edma(struct edma_rsv_info *rsv); int da850_register_edma(struct edma_rsv_info *rsv[2]); @@ -118,12 +122,11 @@ int da850_register_vpif_display (struct vpif_display_config *display_config); int da850_register_vpif_capture (struct vpif_capture_config *capture_config); -void da8xx_restart(enum reboot_mode mode, const char *cmd); void da8xx_rproc_reserve_cma(void); int da8xx_register_rproc(void); int da850_register_gpio(void); int da830_register_gpio(void); -int da8xx_register_cfgchip(void); +struct regmap *da8xx_get_cfgchip(void); extern struct platform_device da8xx_serial_device[]; extern struct emac_platform_data da8xx_emac_pdata; diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index 034f865fe78e..1bb991ad9c1e 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -80,13 +80,6 @@ enum { #define TGCR_UNRESET 0x1 #define TGCR_RESET_MASK 0x3 -#define WDTCR_WDEN_SHIFT 14 -#define WDTCR_WDEN_DISABLE 0x0 -#define WDTCR_WDEN_ENABLE 0x1 -#define WDTCR_WDKEY_SHIFT 16 -#define WDTCR_WDKEY_SEQ0 0xa5c6 -#define WDTCR_WDKEY_SEQ1 0xda7e - struct timer_s { char *name; unsigned int id; @@ -409,53 +402,3 @@ void __init davinci_timer_init(void) for (i=0; i< ARRAY_SIZE(timers); i++) timer32_config(&timers[i]); } - -/* reset board using watchdog timer */ -void davinci_watchdog_reset(struct platform_device *pdev) -{ - u32 tgcr, wdtcr; - void __iomem *base; - struct clk *wd_clk; - - base = ioremap(pdev->resource[0].start, SZ_4K); - if (WARN_ON(!base)) - return; - - wd_clk = clk_get(&pdev->dev, NULL); - if (WARN_ON(IS_ERR(wd_clk))) - return; - clk_prepare_enable(wd_clk); - - /* disable, internal clock source */ - __raw_writel(0, base + TCR); - - /* reset timer, set mode to 64-bit watchdog, and unreset */ - tgcr = 0; - __raw_writel(tgcr, base + TGCR); - tgcr = TGCR_TIMMODE_64BIT_WDOG << TGCR_TIMMODE_SHIFT; - tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) | - (TGCR_UNRESET << TGCR_TIM34RS_SHIFT); - __raw_writel(tgcr, base + TGCR); - - /* clear counter and period regs */ - __raw_writel(0, base + TIM12); - __raw_writel(0, base + TIM34); - __raw_writel(0, base + PRD12); - __raw_writel(0, base + PRD34); - - /* put watchdog in pre-active state */ - wdtcr = __raw_readl(base + WDTCR); - wdtcr = (WDTCR_WDKEY_SEQ0 << WDTCR_WDKEY_SHIFT) | - (WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT); - __raw_writel(wdtcr, base + WDTCR); - - /* put watchdog in active state */ - wdtcr = (WDTCR_WDKEY_SEQ1 << WDTCR_WDKEY_SHIFT) | - (WDTCR_WDEN_ENABLE << WDTCR_WDEN_SHIFT); - __raw_writel(wdtcr, base + WDTCR); - - /* write an invalid value to the WDKEY field to trigger - * a watchdog reset */ - wdtcr = 0x00004000; - __raw_writel(wdtcr, base + WDTCR); -} diff --git a/arch/arm/mach-davinci/usb-da8xx.c b/arch/arm/mach-davinci/usb-da8xx.c index d480a02e1298..50445f0e98de 100644 --- a/arch/arm/mach-davinci/usb-da8xx.c +++ b/arch/arm/mach-davinci/usb-da8xx.c @@ -8,6 +8,7 @@ #include <linux/init.h> #include <linux/mfd/da8xx-cfgchip.h> #include <linux/phy/phy.h> +#include <linux/platform_data/phy-da8xx-usb.h> #include <linux/platform_data/usb-davinci.h> #include <linux/platform_device.h> #include <linux/usb/musb.h> @@ -25,6 +26,8 @@ static struct clk *usb20_clk; +static struct da8xx_usb_phy_platform_data da8xx_usb_phy_pdata; + static struct platform_device da8xx_usb_phy = { .name = "da8xx-usb-phy", .id = -1, @@ -35,11 +38,14 @@ static struct platform_device da8xx_usb_phy = { * registered yet. */ .init_name = "da8xx-usb-phy", + .platform_data = &da8xx_usb_phy_pdata, }, }; int __init da8xx_register_usb_phy(void) { + da8xx_usb_phy_pdata.cfgchip = da8xx_get_cfgchip(); + return platform_device_register(&da8xx_usb_phy); } @@ -256,14 +262,14 @@ static int usb20_phy_clk_set_parent(struct clk *clk, struct clk *parent) } static struct clk usb20_phy_clk = { - .name = "usb20_phy", + .name = "usb0_clk48", .clk_enable = usb20_phy_clk_enable, .clk_disable = usb20_phy_clk_disable, .set_parent = usb20_phy_clk_set_parent, }; static struct clk_lookup usb20_phy_clk_lookup = - CLK("da8xx-usb-phy", "usb20_phy", &usb20_phy_clk); + CLK("da8xx-usb-phy", "usb0_clk48", &usb20_phy_clk); /** * da8xx_register_usb20_phy_clk - register USB0PHYCLKMUX clock @@ -320,18 +326,18 @@ static int usb11_phy_clk_set_parent(struct clk *clk, struct clk *parent) } static struct clk usb11_phy_clk = { - .name = "usb11_phy", + .name = "usb1_clk48", .set_parent = usb11_phy_clk_set_parent, }; static struct clk_lookup usb11_phy_clk_lookup = - CLK("da8xx-usb-phy", "usb11_phy", &usb11_phy_clk); + CLK("da8xx-usb-phy", "usb1_clk48", &usb11_phy_clk); /** * da8xx_register_usb11_phy_clk - register USB1PHYCLKMUX clock * * @use_usb_refclkin: Selects the parent clock - either "usb_refclkin" if true - * or "usb20_phy" if false. + * or "usb0_clk48" if false. */ int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin) { @@ -341,7 +347,7 @@ int __init da8xx_register_usb11_phy_clk(bool use_usb_refclkin) if (use_usb_refclkin) parent = clk_get(NULL, "usb_refclkin"); else - parent = clk_get(&da8xx_usb_phy.dev, "usb20_phy"); + parent = clk_get(&da8xx_usb_phy.dev, "usb0_clk48"); if (IS_ERR(parent)) return PTR_ERR(parent); diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c index fbd108ce8745..8c4f5e342dc1 100644 --- a/arch/arm/mach-exynos/exynos.c +++ b/arch/arm/mach-exynos/exynos.c @@ -192,7 +192,8 @@ static void __init exynos_dt_machine_init(void) #endif if (of_machine_is_compatible("samsung,exynos4210") || (of_machine_is_compatible("samsung,exynos4412") && - of_machine_is_compatible("samsung,trats2")) || + (of_machine_is_compatible("samsung,trats2") || + of_machine_is_compatible("samsung,midas"))) || of_machine_is_compatible("samsung,exynos3250") || of_machine_is_compatible("samsung,exynos5250")) platform_device_register(&exynos_cpuidle); diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c index dc4346ecf16d..a822c5073715 100644 --- a/arch/arm/mach-exynos/pm.c +++ b/arch/arm/mach-exynos/pm.c @@ -163,7 +163,7 @@ void exynos_enter_aftr(void) exynos_pm_central_suspend(); - if (of_machine_is_compatible("samsung,exynos4412")) { + if (soc_is_exynos4412()) { /* Setting SEQ_OPTION register */ pmu_raw_writel(S5P_USE_STANDBY_WFI0 | S5P_USE_STANDBY_WFE0, S5P_CENTRAL_SEQ_OPTION); @@ -271,11 +271,7 @@ abort: goto fail; call_firmware_op(cpu_boot, 1); - - if (soc_is_exynos3250()) - dsb_sev(); - else - arch_send_wakeup_ipi_mask(cpumask_of(1)); + dsb_sev(); } } fail: diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 782699e67600..e47fa13f4b0c 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -32,18 +32,6 @@ config MXC_DEBUG_BOARD data/address de-multiplexing and decode, signal level shift, interrupt control and various board functions. -config HAVE_EPIT - bool - -config MXC_USE_EPIT - bool "Use EPIT instead of GPT" - depends on HAVE_EPIT - help - Use EPIT as the system timer on systems that have it. Normally you - don't have a reason to do so as the EPIT has the same features and - uses the same clocks as the GPT. Anyway, on some systems the GPT - may be in use for other purposes. - config HAVE_IMX_ANATOP bool @@ -85,7 +73,6 @@ config SOC_IMX31 config SOC_IMX35 bool select ARCH_MXC_IOMUX_V3 - select HAVE_EPIT select MXC_AVIC select PINCTRL_IMX35 @@ -482,7 +469,7 @@ config SOC_IMX53 config SOC_IMX6 bool - select ARM_CPU_SUSPEND if PM + select ARM_CPU_SUSPEND if (PM || CPU_IDLE) select ARM_ERRATA_754322 select ARM_ERRATA_775420 select ARM_GIC @@ -512,6 +499,13 @@ config SOC_IMX6SL help This enables support for Freescale i.MX6 SoloLite processor. +config SOC_IMX6SLL + bool "i.MX6 SoloLiteLite support" + select SOC_IMX6 + + help + This enables support for Freescale i.MX6 SoloLiteLite processor. + config SOC_IMX6SX bool "i.MX6 SoloX support" select PINCTRL_IMX6SX diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 8ff71058207d..2327e3e876d8 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -20,13 +20,13 @@ obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o obj-$(CONFIG_MXC_TZIC) += tzic.o obj-$(CONFIG_MXC_AVIC) += avic.o -obj-$(CONFIG_MXC_USE_EPIT) += epit.o obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o ifeq ($(CONFIG_CPU_IDLE),y) obj-$(CONFIG_SOC_IMX5) += cpuidle-imx5.o obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o obj-$(CONFIG_SOC_IMX6SL) += cpuidle-imx6sl.o +obj-$(CONFIG_SOC_IMX6SLL) += cpuidle-imx6sl.o obj-$(CONFIG_SOC_IMX6SX) += cpuidle-imx6sx.o obj-$(CONFIG_SOC_IMX6UL) += cpuidle-imx6sx.o endif @@ -78,6 +78,7 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o endif obj-$(CONFIG_SOC_IMX6Q) += mach-imx6q.o obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o +obj-$(CONFIG_SOC_IMX6SLL) += mach-imx6sl.o obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o obj-$(CONFIG_SOC_IMX6UL) += mach-imx6ul.o obj-$(CONFIG_SOC_IMX7D) += mach-imx7d.o diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c index 649a84c251ad..61f3d94f1633 100644 --- a/arch/arm/mach-imx/anatop.c +++ b/arch/arm/mach-imx/anatop.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2013-2015 Freescale Semiconductor, Inc. + * Copyright 2017-2018 NXP. * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License @@ -116,6 +117,7 @@ void __init imx_init_revision_from_anatop(void) unsigned int revision; u32 digprog; u16 offset = ANADIG_DIGPROG; + u8 major_part, minor_part; np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop"); anatop_base = of_iomap(np, 0); @@ -127,45 +129,25 @@ void __init imx_init_revision_from_anatop(void) digprog = readl_relaxed(anatop_base + offset); iounmap(anatop_base); - switch (digprog & 0xff) { - case 0: - /* - * For i.MX6QP, most of the code for i.MX6Q can be resued, - * so internally, we identify it as i.MX6Q Rev 2.0 - */ - if (digprog >> 8 & 0x01) - revision = IMX_CHIP_REVISION_2_0; - else - revision = IMX_CHIP_REVISION_1_0; - break; - case 1: - revision = IMX_CHIP_REVISION_1_1; - break; - case 2: - revision = IMX_CHIP_REVISION_1_2; - break; - case 3: - revision = IMX_CHIP_REVISION_1_3; - break; - case 4: - revision = IMX_CHIP_REVISION_1_4; - break; - case 5: - /* - * i.MX6DQ TO1.5 is defined as Rev 1.3 in Data Sheet, marked - * as 'D' in Part Number last character. - */ - revision = IMX_CHIP_REVISION_1_5; - break; - default: + /* + * On i.MX7D digprog value match linux version format, so + * it needn't map again and we can use register value directly. + */ + if (of_device_is_compatible(np, "fsl,imx7d-anatop")) { + revision = digprog & 0xff; + } else { /* - * Fail back to return raw register value instead of 0xff. - * It will be easy to know version information in SOC if it - * can't be recognized by known version. And some chip's (i.MX7D) - * digprog value match linux version format, so it needn't map - * again and we can use register value directly. + * MAJOR: [15:8], the major silicon revison; + * MINOR: [7: 0], the minor silicon revison; + * + * please refer to the i.MX RM for the detailed + * silicon revison bit define. + * format the major part and minor part to match the + * linux kernel soc version format. */ - revision = digprog & 0xff; + major_part = (digprog >> 8) & 0xf; + minor_part = digprog & 0xf; + revision = ((major_part + 1) << 4) | minor_part; } mxc_set_cpu_type(digprog >> 16 & 0xff); diff --git a/arch/arm/mach-imx/avic.c b/arch/arm/mach-imx/avic.c index 1afccae0420c..c0434a36687a 100644 --- a/arch/arm/mach-imx/avic.c +++ b/arch/arm/mach-imx/avic.c @@ -22,6 +22,7 @@ #include <linux/irqdomain.h> #include <linux/io.h> #include <linux/of.h> +#include <linux/of_address.h> #include <asm/mach/irq.h> #include <asm/exception.h> @@ -51,7 +52,12 @@ #define AVIC_NUM_IRQS 64 +/* low power interrupt mask registers */ +#define MX25_CCM_LPIMR0 0x68 +#define MX25_CCM_LPIMR1 0x6C + static void __iomem *avic_base; +static void __iomem *mx25_ccm_base; static struct irq_domain *domain; #ifdef CONFIG_FIQ @@ -93,6 +99,18 @@ static void avic_irq_suspend(struct irq_data *d) avic_saved_mask_reg[idx] = imx_readl(avic_base + ct->regs.mask); imx_writel(gc->wake_active, avic_base + ct->regs.mask); + + if (mx25_ccm_base) { + u8 offs = d->hwirq < AVIC_NUM_IRQS / 2 ? + MX25_CCM_LPIMR0 : MX25_CCM_LPIMR1; + /* + * The interrupts which are still enabled will be used as wakeup + * sources. Allow those interrupts in low-power mode. + * The LPIMR registers use 0 to allow an interrupt, the AVIC + * registers use 1. + */ + imx_writel(~gc->wake_active, mx25_ccm_base + offs); + } } static void avic_irq_resume(struct irq_data *d) @@ -102,6 +120,13 @@ static void avic_irq_resume(struct irq_data *d) int idx = d->hwirq >> 5; imx_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask); + + if (mx25_ccm_base) { + u8 offs = d->hwirq < AVIC_NUM_IRQS / 2 ? + MX25_CCM_LPIMR0 : MX25_CCM_LPIMR1; + + imx_writel(0xffffffff, mx25_ccm_base + offs); + } } #else @@ -158,6 +183,18 @@ void __init mxc_init_irq(void __iomem *irqbase) avic_base = irqbase; + np = of_find_compatible_node(NULL, NULL, "fsl,imx25-ccm"); + mx25_ccm_base = of_iomap(np, 0); + + if (mx25_ccm_base) { + /* + * By default, we mask all interrupts. We set the actual mask + * before we go into low-power mode. + */ + imx_writel(0xffffffff, mx25_ccm_base + MX25_CCM_LPIMR0); + imx_writel(0xffffffff, mx25_ccm_base + MX25_CCM_LPIMR1); + } + /* put the AVIC into the reset value with * all interrupts disabled */ diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index d4e55f2a897e..32969f34486a 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -135,6 +135,9 @@ struct device * __init imx_soc_device_init(void) case MXC_CPU_IMX6ULL: soc_id = "i.MX6ULL"; break; + case MXC_CPU_IMX6SLL: + soc_id = "i.MX6SLL"; + break; case MXC_CPU_IMX7D: soc_id = "i.MX7D"; break; diff --git a/arch/arm/mach-imx/cpuidle-imx6sl.c b/arch/arm/mach-imx/cpuidle-imx6sl.c index 8d866fb674a8..fa8ead145d17 100644 --- a/arch/arm/mach-imx/cpuidle-imx6sl.c +++ b/arch/arm/mach-imx/cpuidle-imx6sl.c @@ -12,6 +12,7 @@ #include "common.h" #include "cpuidle.h" +#include "hardware.h" static int imx6sl_enter_wait(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) @@ -21,9 +22,11 @@ static int imx6sl_enter_wait(struct cpuidle_device *dev, * Software workaround for ERR005311, see function * description for details. */ - imx6sl_set_wait_clk(true); + if (cpu_is_imx6sl()) + imx6sl_set_wait_clk(true); cpu_do_idle(); - imx6sl_set_wait_clk(false); + if (cpu_is_imx6sl()) + imx6sl_set_wait_clk(false); imx6_set_lpm(WAIT_CLOCKED); return index; diff --git a/arch/arm/mach-imx/cpuidle-imx6sx.c b/arch/arm/mach-imx/cpuidle-imx6sx.c index c5a5c3a70ab1..d0f14b761ff7 100644 --- a/arch/arm/mach-imx/cpuidle-imx6sx.c +++ b/arch/arm/mach-imx/cpuidle-imx6sx.c @@ -89,6 +89,7 @@ static struct cpuidle_driver imx6sx_cpuidle_driver = { */ .exit_latency = 300, .target_residency = 500, + .flags = CPUIDLE_FLAG_TIMER_STOP, .enter = imx6sx_enter_wait, .name = "LOW-POWER-IDLE", .desc = "ARM power off", diff --git a/arch/arm/mach-imx/epit.c b/arch/arm/mach-imx/epit.c deleted file mode 100644 index fb9a73a57d00..000000000000 --- a/arch/arm/mach-imx/epit.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * linux/arch/arm/plat-mxc/epit.c - * - * Copyright (C) 2010 Sascha Hauer <s.hauer@pengutronix.de> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#define EPITCR 0x00 -#define EPITSR 0x04 -#define EPITLR 0x08 -#define EPITCMPR 0x0c -#define EPITCNR 0x10 - -#define EPITCR_EN (1 << 0) -#define EPITCR_ENMOD (1 << 1) -#define EPITCR_OCIEN (1 << 2) -#define EPITCR_RLD (1 << 3) -#define EPITCR_PRESC(x) (((x) & 0xfff) << 4) -#define EPITCR_SWR (1 << 16) -#define EPITCR_IOVW (1 << 17) -#define EPITCR_DBGEN (1 << 18) -#define EPITCR_WAITEN (1 << 19) -#define EPITCR_RES (1 << 20) -#define EPITCR_STOPEN (1 << 21) -#define EPITCR_OM_DISCON (0 << 22) -#define EPITCR_OM_TOGGLE (1 << 22) -#define EPITCR_OM_CLEAR (2 << 22) -#define EPITCR_OM_SET (3 << 22) -#define EPITCR_CLKSRC_OFF (0 << 24) -#define EPITCR_CLKSRC_PERIPHERAL (1 << 24) -#define EPITCR_CLKSRC_REF_HIGH (1 << 24) -#define EPITCR_CLKSRC_REF_LOW (3 << 24) - -#define EPITSR_OCIF (1 << 0) - -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/clockchips.h> -#include <linux/clk.h> -#include <linux/err.h> -#include <asm/mach/time.h> - -#include "common.h" -#include "hardware.h" - -static struct clock_event_device clockevent_epit; - -static void __iomem *timer_base; - -static inline void epit_irq_disable(void) -{ - u32 val; - - val = imx_readl(timer_base + EPITCR); - val &= ~EPITCR_OCIEN; - imx_writel(val, timer_base + EPITCR); -} - -static inline void epit_irq_enable(void) -{ - u32 val; - - val = imx_readl(timer_base + EPITCR); - val |= EPITCR_OCIEN; - imx_writel(val, timer_base + EPITCR); -} - -static void epit_irq_acknowledge(void) -{ - imx_writel(EPITSR_OCIF, timer_base + EPITSR); -} - -static int __init epit_clocksource_init(struct clk *timer_clk) -{ - unsigned int c = clk_get_rate(timer_clk); - - return clocksource_mmio_init(timer_base + EPITCNR, "epit", c, 200, 32, - clocksource_mmio_readl_down); -} - -/* clock event */ - -static int epit_set_next_event(unsigned long evt, - struct clock_event_device *unused) -{ - unsigned long tcmp; - - tcmp = imx_readl(timer_base + EPITCNR); - - imx_writel(tcmp - evt, timer_base + EPITCMPR); - - return 0; -} - -/* Left event sources disabled, no more interrupts appear */ -static int epit_shutdown(struct clock_event_device *evt) -{ - unsigned long flags; - - /* - * The timer interrupt generation is disabled at least - * for enough time to call epit_set_next_event() - */ - local_irq_save(flags); - - /* Disable interrupt in GPT module */ - epit_irq_disable(); - - /* Clear pending interrupt */ - epit_irq_acknowledge(); - - local_irq_restore(flags); - - return 0; -} - -static int epit_set_oneshot(struct clock_event_device *evt) -{ - unsigned long flags; - - /* - * The timer interrupt generation is disabled at least - * for enough time to call epit_set_next_event() - */ - local_irq_save(flags); - - /* Disable interrupt in GPT module */ - epit_irq_disable(); - - /* Clear pending interrupt, only while switching mode */ - if (!clockevent_state_oneshot(evt)) - epit_irq_acknowledge(); - - /* - * Do not put overhead of interrupt enable/disable into - * epit_set_next_event(), the core has about 4 minutes - * to call epit_set_next_event() or shutdown clock after - * mode switching - */ - epit_irq_enable(); - local_irq_restore(flags); - - return 0; -} - -/* - * IRQ handler for the timer - */ -static irqreturn_t epit_timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *evt = &clockevent_epit; - - epit_irq_acknowledge(); - - evt->event_handler(evt); - - return IRQ_HANDLED; -} - -static struct irqaction epit_timer_irq = { - .name = "i.MX EPIT Timer Tick", - .flags = IRQF_TIMER | IRQF_IRQPOLL, - .handler = epit_timer_interrupt, -}; - -static struct clock_event_device clockevent_epit = { - .name = "epit", - .features = CLOCK_EVT_FEAT_ONESHOT, - .set_state_shutdown = epit_shutdown, - .tick_resume = epit_shutdown, - .set_state_oneshot = epit_set_oneshot, - .set_next_event = epit_set_next_event, - .rating = 200, -}; - -static int __init epit_clockevent_init(struct clk *timer_clk) -{ - clockevent_epit.cpumask = cpumask_of(0); - clockevents_config_and_register(&clockevent_epit, - clk_get_rate(timer_clk), - 0x800, 0xfffffffe); - - return 0; -} - -void __init epit_timer_init(void __iomem *base, int irq) -{ - struct clk *timer_clk; - - timer_clk = clk_get_sys("imx-epit.0", NULL); - if (IS_ERR(timer_clk)) { - pr_err("i.MX epit: unable to get clk\n"); - return; - } - - clk_prepare_enable(timer_clk); - - timer_base = base; - - /* - * Initialise to a known state (all timers off, and timing reset) - */ - imx_writel(0x0, timer_base + EPITCR); - - imx_writel(0xffffffff, timer_base + EPITLR); - imx_writel(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN, - timer_base + EPITCR); - - /* init and register the timer to the framework */ - epit_clocksource_init(timer_clk); - epit_clockevent_init(timer_clk); - - /* Make irqs happen */ - setup_irq(irq, &epit_timer_irq); -} diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c index 04084900d810..c7a1ef180dda 100644 --- a/arch/arm/mach-imx/mach-imx6sl.c +++ b/arch/arm/mach-imx/mach-imx6sl.c @@ -18,6 +18,7 @@ #include "common.h" #include "cpuidle.h" +#include "hardware.h" static void __init imx6sl_fec_init(void) { @@ -54,7 +55,8 @@ static void __init imx6sl_init_machine(void) of_platform_default_populate(NULL, NULL, parent); - imx6sl_fec_init(); + if (cpu_is_imx6sl()) + imx6sl_fec_init(); imx_anatop_init(); imx6sl_pm_init(); } @@ -66,11 +68,15 @@ static void __init imx6sl_init_irq(void) imx_init_l2cache(); imx_src_init(); irqchip_init(); - imx6_pm_ccm_init("fsl,imx6sl-ccm"); + if (cpu_is_imx6sl()) + imx6_pm_ccm_init("fsl,imx6sl-ccm"); + else + imx6_pm_ccm_init("fsl,imx6sll-ccm"); } static const char * const imx6sl_dt_compat[] __initconst = { "fsl,imx6sl", + "fsl,imx6sll", NULL, }; diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h index e00d6260c3df..026e2ca45f1e 100644 --- a/arch/arm/mach-imx/mxc.h +++ b/arch/arm/mach-imx/mxc.h @@ -40,6 +40,7 @@ #define MXC_CPU_IMX6Q 0x63 #define MXC_CPU_IMX6UL 0x64 #define MXC_CPU_IMX6ULL 0x65 +#define MXC_CPU_IMX6SLL 0x67 #define MXC_CPU_IMX7D 0x72 #define IMX_DDR_TYPE_LPDDR2 1 @@ -79,6 +80,11 @@ static inline bool cpu_is_imx6ull(void) return __mxc_cpu_type == MXC_CPU_IMX6ULL; } +static inline bool cpu_is_imx6sll(void) +{ + return __mxc_cpu_type == MXC_CPU_IMX6SLL; +} + static inline bool cpu_is_imx6q(void) { return __mxc_cpu_type == MXC_CPU_IMX6Q; diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index ecdf071653d4..017539dd712b 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c @@ -428,10 +428,8 @@ static int __init imx6_pm_get_base(struct imx6_pm_base *base, int ret = 0; node = of_find_compatible_node(NULL, NULL, compat); - if (!node) { - ret = -ENODEV; - goto out; - } + if (!node) + return -ENODEV; ret = of_address_to_resource(node, 0, &res); if (ret) @@ -444,7 +442,6 @@ static int __init imx6_pm_get_base(struct imx6_pm_base *base, put_node: of_node_put(node); -out: return ret; } diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c index d2283009a5ff..6c2ebf01893a 100644 --- a/arch/arm/mach-mmp/aspenite.c +++ b/arch/arm/mach-mmp/aspenite.c @@ -172,10 +172,8 @@ static struct mtd_partition aspenite_nand_partitions[] = { }; static struct pxa3xx_nand_platform_data aspenite_nand_info = { - .enable_arbiter = 1, - .num_cs = 1, - .parts[0] = aspenite_nand_partitions, - .nr_parts[0] = ARRAY_SIZE(aspenite_nand_partitions), + .parts = aspenite_nand_partitions, + .nr_parts = ARRAY_SIZE(aspenite_nand_partitions), }; static struct i2c_board_info aspenite_i2c_info[] __initdata = { diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c index d90c74fa614d..c7897fb2b6da 100644 --- a/arch/arm/mach-mmp/ttc_dkb.c +++ b/arch/arm/mach-mmp/ttc_dkb.c @@ -178,11 +178,8 @@ static struct mv_usb_platform_data ttc_usb_pdata = { #endif #endif -#if IS_ENABLED(CONFIG_MTD_NAND_PXA3xx) -static struct pxa3xx_nand_platform_data dkb_nand_info = { - .enable_arbiter = 1, - .num_cs = 1, -}; +#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL) +static struct pxa3xx_nand_platform_data dkb_nand_info = {}; #endif #if IS_ENABLED(CONFIG_MMP_DISP) @@ -275,7 +272,7 @@ static void __init ttc_dkb_init(void) /* on-chip devices */ pxa910_add_uart(1); -#if IS_ENABLED(CONFIG_MTD_NAND_PXA3xx) +#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL) pxa910_add_nand(&dkb_nand_info); #endif diff --git a/arch/arm/mach-npcm/Kconfig b/arch/arm/mach-npcm/Kconfig new file mode 100644 index 000000000000..684c9c9a32bd --- /dev/null +++ b/arch/arm/mach-npcm/Kconfig @@ -0,0 +1,30 @@ +menuconfig ARCH_NPCM + bool "Nuvoton NPCM Architecture" + depends on ARCH_MULTI_V7 + select PINCTRL + +if ARCH_NPCM + +config ARCH_NPCM7XX + bool "Support for NPCM7xx BMC (Poleg)" + depends on ARCH_MULTI_V7 + select PINCTRL_NPCM7XX + select NPCM7XX_TIMER + select ARCH_REQUIRE_GPIOLIB + select CACHE_L2X0 + select ARM_GIC + select HAVE_ARM_TWD if SMP + select HAVE_ARM_SCU if SMP + select ARM_ERRATA_764369 if SMP + select ARM_ERRATA_720789 + select ARM_ERRATA_754322 + select ARM_ERRATA_794072 + select PL310_ERRATA_588369 + select PL310_ERRATA_727915 + select MFD_SYSCON + help + General support for NPCM7xx BMC (Poleg). + + Nuvoton NPCM7xx BMC based on the Cortex A9. + +endif diff --git a/arch/arm/mach-npcm/Makefile b/arch/arm/mach-npcm/Makefile new file mode 100644 index 000000000000..f5f67201419f --- /dev/null +++ b/arch/arm/mach-npcm/Makefile @@ -0,0 +1,4 @@ +AFLAGS_headsmp.o += -march=armv7-a + +obj-$(CONFIG_ARCH_NPCM7XX) += npcm7xx.o +obj-$(CONFIG_SMP) += platsmp.o headsmp.o diff --git a/arch/arm/mach-npcm/headsmp.S b/arch/arm/mach-npcm/headsmp.S new file mode 100644 index 000000000000..c083fe09a07b --- /dev/null +++ b/arch/arm/mach-npcm/headsmp.S @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018 Nuvoton Technology corporation. +// Copyright 2018 Google, Inc. + +#include <linux/linkage.h> +#include <linux/init.h> +#include <asm/assembler.h> + +/* + * The boot ROM does not start secondary CPUs in SVC mode, so we need to do that + * here. + */ +ENTRY(npcm7xx_secondary_startup) + safe_svcmode_maskall r0 + + b secondary_startup +ENDPROC(npcm7xx_secondary_startup) diff --git a/arch/arm/mach-npcm/npcm7xx.c b/arch/arm/mach-npcm/npcm7xx.c new file mode 100644 index 000000000000..5f7cd88103ef --- /dev/null +++ b/arch/arm/mach-npcm/npcm7xx.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018 Nuvoton Technology corporation. +// Copyright 2018 Google, Inc. + +#include <linux/kernel.h> +#include <linux/types.h> +#include <asm/mach/arch.h> +#include <asm/mach-types.h> +#include <asm/mach/map.h> +#include <asm/hardware/cache-l2x0.h> + +static const char *const npcm7xx_dt_match[] = { + "nuvoton,npcm750", + NULL +}; + +DT_MACHINE_START(NPCM7XX_DT, "NPCM7XX Chip family") + .atag_offset = 0x100, + .dt_compat = npcm7xx_dt_match, +MACHINE_END diff --git a/arch/arm/mach-npcm/platsmp.c b/arch/arm/mach-npcm/platsmp.c new file mode 100644 index 000000000000..21633c70fe7f --- /dev/null +++ b/arch/arm/mach-npcm/platsmp.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018 Nuvoton Technology corporation. +// Copyright 2018 Google, Inc. + +#define pr_fmt(fmt) "nuvoton,npcm7xx-smp: " fmt + +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/smp.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/of_platform.h> +#include <linux/of_address.h> +#include <asm/cacheflush.h> +#include <asm/smp.h> +#include <asm/smp_plat.h> +#include <asm/smp_scu.h> + +#define NPCM7XX_SCRPAD_REG 0x13c + +extern void npcm7xx_secondary_startup(void); + +static int npcm7xx_smp_boot_secondary(unsigned int cpu, + struct task_struct *idle) +{ + struct device_node *gcr_np; + void __iomem *gcr_base; + int ret = 0; + + gcr_np = of_find_compatible_node(NULL, NULL, "nuvoton,npcm750-gcr"); + if (!gcr_np) { + pr_err("no gcr device node\n"); + ret = -ENODEV; + goto out; + } + gcr_base = of_iomap(gcr_np, 0); + if (!gcr_base) { + pr_err("could not iomap gcr"); + ret = -ENOMEM; + goto out; + } + + /* give boot ROM kernel start address. */ + iowrite32(__pa_symbol(npcm7xx_secondary_startup), gcr_base + + NPCM7XX_SCRPAD_REG); + /* make sure the previous write is seen by all observers. */ + dsb_sev(); + + iounmap(gcr_base); +out: + return ret; +} + +static void __init npcm7xx_smp_prepare_cpus(unsigned int max_cpus) +{ + struct device_node *scu_np; + void __iomem *scu_base; + + scu_np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu"); + if (!scu_np) { + pr_err("no scu device node\n"); + return; + } + scu_base = of_iomap(scu_np, 0); + if (!scu_base) { + pr_err("could not iomap scu"); + return; + } + + scu_enable(scu_base); + + iounmap(scu_base); +} + +static struct smp_operations npcm7xx_smp_ops __initdata = { + .smp_prepare_cpus = npcm7xx_smp_prepare_cpus, + .smp_boot_secondary = npcm7xx_smp_boot_secondary, +}; + +CPU_METHOD_OF_DECLARE(npcm7xx_smp, "nuvoton,npcm750-smp", &npcm7xx_smp_ops); diff --git a/arch/arm/mach-nspire/nspire.c b/arch/arm/mach-nspire/nspire.c index f0808fcc5acc..8584cdd1c827 100644 --- a/arch/arm/mach-nspire/nspire.c +++ b/arch/arm/mach-nspire/nspire.c @@ -33,11 +33,6 @@ static const char *const nspire_dt_match[] __initconst = { NULL, }; -static void __init nspire_map_io(void) -{ - debug_ll_io_init(); -} - static struct clcd_board nspire_clcd_data = { .name = "LCD", .caps = CLCD_CAP_5551 | CLCD_CAP_565, @@ -71,7 +66,6 @@ static void nspire_restart(enum reboot_mode mode, const char *cmd) DT_MACHINE_START(NSPIRE, "TI-NSPIRE") .dt_compat = nspire_dt_match, - .map_io = nspire_map_io, .init_machine = nspire_init, .restart = nspire_restart, MACHINE_END diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig index 45c6b733c881..c4694f26b5c4 100644 --- a/arch/arm/mach-omap1/Kconfig +++ b/arch/arm/mach-omap1/Kconfig @@ -30,6 +30,7 @@ config ARCH_OMAP16XX bool "OMAP16xx Based System" select ARCH_OMAP_OTG select CPU_ARM926T + select OMAP_DM_TIMER config OMAP_MUX bool "OMAP multiplexing support" diff --git a/arch/arm/mach-omap1/common.h b/arch/arm/mach-omap1/common.h index 65bb6e8085de..d83ff257eaa8 100644 --- a/arch/arm/mach-omap1/common.h +++ b/arch/arm/mach-omap1/common.h @@ -32,11 +32,10 @@ #include <asm/exception.h> -#include <plat/i2c.h> - #include <mach/irqs.h> #include "soc.h" +#include "i2c.h" #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) void omap7xx_map_io(void); diff --git a/arch/arm/mach-omap1/i2c.c b/arch/arm/mach-omap1/i2c.c index 32f6c53367bf..5bdf3c4190f9 100644 --- a/arch/arm/mach-omap1/i2c.c +++ b/arch/arm/mach-omap1/i2c.c @@ -24,8 +24,6 @@ #include <mach/mux.h> #include "soc.h" -#include <plat/i2c.h> - #define OMAP_I2C_SIZE 0x3f #define OMAP1_I2C_BASE 0xfffb3800 diff --git a/arch/arm/plat-omap/include/plat/i2c.h b/arch/arm/mach-omap1/i2c.h index 810629d79668..54a2bce7879e 100644 --- a/arch/arm/plat-omap/include/plat/i2c.h +++ b/arch/arm/mach-omap1/i2c.h @@ -19,8 +19,8 @@ * */ -#ifndef __PLAT_OMAP_I2C_H -#define __PLAT_OMAP_I2C_H +#ifndef __ARCH_ARM_MACH_OMAP1_I2C_H +#define __ARCH_ARM_MACH_OMAP1_I2C_H struct i2c_board_info; struct omap_i2c_bus_platform_data; @@ -47,7 +47,4 @@ static inline int omap_register_i2c_bus_cmdline(void) } #endif -struct omap_hwmod; -int omap_i2c_reset(struct omap_hwmod *oh); - -#endif /* __PLAT_OMAP_I2C_H */ +#endif /* __ARCH_ARM_MACH_OMAP1_I2C_H */ diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index f1135bf8940e..3e1de14805e4 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c @@ -55,7 +55,7 @@ #include <mach/tc.h> #include <mach/mux.h> #include <linux/omap-dma.h> -#include <plat/dmtimer.h> +#include <clocksource/timer-ti-dm.h> #include <mach/irqs.h> diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c index 8fb1ec6fa999..4447210c9b0d 100644 --- a/arch/arm/mach-omap1/timer.c +++ b/arch/arm/mach-omap1/timer.c @@ -27,7 +27,7 @@ #include <linux/platform_device.h> #include <linux/platform_data/dmtimer-omap.h> -#include <plat/dmtimer.h> +#include <clocksource/timer-ti-dm.h> #include "soc.h" diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 00b1f17f8d44..9f27b486a536 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -72,6 +72,7 @@ config SOC_AM43XX select ARM_ERRATA_754322 select ARM_ERRATA_775420 select OMAP_INTERCONNECT + select ARM_CPU_SUSPEND if PM config SOC_DRA7XX bool "TI DRA7XX" diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index c15bbcad5f67..4603c30fef73 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -88,6 +88,8 @@ omap-4-5-pm-common += pm44xx.o obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-pm-common) obj-$(CONFIG_SOC_OMAP5) += $(omap-4-5-pm-common) obj-$(CONFIG_SOC_DRA7XX) += $(omap-4-5-pm-common) +obj-$(CONFIG_SOC_AM33XX) += pm33xx-core.o sleep33xx.o +obj-$(CONFIG_SOC_AM43XX) += pm33xx-core.o sleep43xx.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o obj-$(CONFIG_POWER_AVS_OMAP) += sr_device.o @@ -95,6 +97,8 @@ obj-$(CONFIG_POWER_AVS_OMAP_CLASS3) += smartreflex-class3.o AFLAGS_sleep24xx.o :=-Wa,-march=armv6 AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec) +AFLAGS_sleep33xx.o :=-Wa,-march=armv7-a$(plus_sec) +AFLAGS_sleep43xx.o :=-Wa,-march=armv7-a$(plus_sec) endif @@ -232,3 +236,15 @@ obj-y += $(omap-hsmmc-m) $(omap-hsmmc-y) obj-y += omap_phy_internal.o obj-$(CONFIG_MACH_OMAP2_TUSB6010) += usb-tusb6010.o + +arch/arm/mach-omap2/pm-asm-offsets.s: arch/arm/mach-omap2/pm-asm-offsets.c + $(call if_changed_dep,cc_s_c) + +include/generated/ti-pm-asm-offsets.h: arch/arm/mach-omap2/pm-asm-offsets.s FORCE + $(call filechk,offsets,__TI_PM_ASM_OFFSETS_H__) + +# For rule to generate ti-emif-asm-offsets.h dependency +include drivers/memory/Makefile.asm-offsets + +arch/arm/mach-omap2/sleep33xx.o: include/generated/ti-pm-asm-offsets.h include/generated/ti-emif-asm-offsets.h +arch/arm/mach-omap2/sleep43xx.o: include/generated/ti-pm-asm-offsets.h include/generated/ti-emif-asm-offsets.h diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index 20f25539d572..75bc18646df6 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -566,11 +566,11 @@ static int n8x0_menelaus_late_init(struct device *dev) } #endif -struct menelaus_platform_data n8x0_menelaus_platform_data __initdata = { +struct menelaus_platform_data n8x0_menelaus_platform_data = { .late_init = n8x0_menelaus_late_init, }; -struct aic3x_pdata n810_aic33_data __initdata = { +struct aic3x_pdata n810_aic33_data = { .gpio_reset = 118, }; diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index bc202835371b..fbe0b78bf489 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -77,6 +77,13 @@ static inline int omap4_pm_init_early(void) } #endif +#if defined(CONFIG_PM) && (defined(CONFIG_SOC_AM33XX) || \ + defined(CONFIG_SOC_AM43XX)) +void amx3_common_pm_init(void); +#else +static inline void amx3_common_pm_init(void) { } +#endif + extern void omap2_init_common_infrastructure(void); extern void omap_init_time(void); diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c index bd8089ff929f..180da403639e 100644 --- a/arch/arm/mach-omap2/control.c +++ b/arch/arm/mach-omap2/control.c @@ -623,6 +623,7 @@ void __init omap3_ctrl_init(void) struct control_init_data { int index; + void __iomem *mem; s16 offset; }; @@ -635,6 +636,10 @@ static const struct control_init_data omap2_ctrl_data = { .offset = -OMAP2_CONTROL_GENERAL, }; +static const struct control_init_data ctrl_aux_data = { + .index = TI_CLKM_CTRL_AUX, +}; + static const struct of_device_id omap_scrm_dt_match_table[] = { { .compatible = "ti,am3-scm", .data = &ctrl_data }, { .compatible = "ti,am4-scm", .data = &ctrl_data }, @@ -644,6 +649,7 @@ static const struct of_device_id omap_scrm_dt_match_table[] = { { .compatible = "ti,dm816-scrm", .data = &ctrl_data }, { .compatible = "ti,omap4-scm-core", .data = &ctrl_data }, { .compatible = "ti,omap5-scm-core", .data = &ctrl_data }, + { .compatible = "ti,omap5-scm-wkup-pad-conf", .data = &ctrl_aux_data }, { .compatible = "ti,dra7-scm-core", .data = &ctrl_data }, { } }; @@ -660,15 +666,21 @@ int __init omap2_control_base_init(void) struct device_node *np; const struct of_device_id *match; struct control_init_data *data; + void __iomem *mem; for_each_matching_node_and_match(np, omap_scrm_dt_match_table, &match) { data = (struct control_init_data *)match->data; - omap2_ctrl_base = of_iomap(np, 0); - if (!omap2_ctrl_base) + mem = of_iomap(np, 0); + if (!mem) return -ENOMEM; - omap2_ctrl_offset = data->offset; + if (data->index == TI_CLKM_CTRL) { + omap2_ctrl_base = mem; + omap2_ctrl_offset = data->offset; + } + + data->mem = mem; } return 0; @@ -713,7 +725,7 @@ int __init omap_control_init(void) } else { /* No scm_conf found, direct access */ ret = omap2_clk_provider_init(np, data->index, NULL, - omap2_ctrl_base); + data->mem); if (ret) return ret; } diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 93057fb65f44..ed6f074ea672 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -8,7 +8,7 @@ * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ -#include <linux/gpio.h> + #include <linux/kernel.h> #include <linux/init.h> #include <linux/platform_device.h> diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index 6d28aa20a7d3..b064066d431c 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -13,9 +13,7 @@ #include <linux/slab.h> #include <linux/string.h> #include <linux/delay.h> -#include <linux/gpio.h> #include <linux/mmc/host.h> -#include <linux/platform_data/gpio-omap.h> #include <linux/platform_data/hsmmc-omap.h> #include "soc.h" diff --git a/arch/arm/mach-omap2/i2c.h b/arch/arm/mach-omap2/i2c.h index 42b6f2e7d190..4d085c7ad425 100644 --- a/arch/arm/mach-omap2/i2c.h +++ b/arch/arm/mach-omap2/i2c.h @@ -19,23 +19,10 @@ * */ -#include <plat/i2c.h> - #ifndef __MACH_OMAP2_I2C_H #define __MACH_OMAP2_I2C_H -/** - * i2c_dev_attr - OMAP I2C controller device attributes for omap_hwmod - * @fifo_depth: total controller FIFO size (in bytes) - * @flags: differences in hardware support capability - * - * @fifo_depth represents what exists on the hardware, not what is - * actually configured at runtime by the device driver. - */ -struct omap_i2c_dev_attr { - u8 fifo_depth; - u32 flags; -}; +struct omap_hwmod; int omap_i2c_reset(struct omap_hwmod *oh); diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index cb5d7314cf99..cf546dfe3b32 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -622,6 +622,7 @@ void __init am33xx_init_early(void) void __init am33xx_init_late(void) { omap_common_late_init(); + amx3_common_pm_init(); } #endif @@ -646,6 +647,7 @@ void __init am43xx_init_late(void) { omap_common_late_init(); omap2_clk_enable_autoidle_all(); + amx3_common_pm_init(); } #endif diff --git a/arch/arm/mach-omap2/msdi.c b/arch/arm/mach-omap2/msdi.c index 5a3bc3de58d0..978fba722b82 100644 --- a/arch/arm/mach-omap2/msdi.c +++ b/arch/arm/mach-omap2/msdi.c @@ -23,7 +23,6 @@ #include <linux/kernel.h> #include <linux/err.h> -#include <linux/platform_data/gpio-omap.h> #include "prm.h" #include "common.h" diff --git a/arch/arm/mach-omap2/omap4-sar-layout.h b/arch/arm/mach-omap2/omap4-sar-layout.h index 5b2966a0f733..9fc4e2643ce7 100644 --- a/arch/arm/mach-omap2/omap4-sar-layout.h +++ b/arch/arm/mach-omap2/omap4-sar-layout.h @@ -28,7 +28,7 @@ #define L2X0_AUXCTRL_OFFSET 0xff8 #define L2X0_PREFETCH_CTRL_OFFSET 0xffc -/* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK3 */ +/* CPUx Wakeup Non-Secure Physical Address offsets in SAR_BANK1 */ #define CPU0_WAKEUP_NS_PA_ADDR_OFFSET 0xa04 #define CPU1_WAKEUP_NS_PA_ADDR_OFFSET 0xa08 #define OMAP5_CPU0_WAKEUP_NS_PA_ADDR_OFFSET 0xe00 diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index f0388058b7da..3b829a50d1db 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -140,6 +140,7 @@ static int omap_device_build_from_dt(struct platform_device *pdev) struct omap_device *od; struct omap_hwmod *oh; struct device_node *node = pdev->dev.of_node; + struct resource res; const char *oh_name; int oh_cnt, i, ret = 0; bool device_active = false; @@ -150,6 +151,10 @@ static int omap_device_build_from_dt(struct platform_device *pdev) return -ENODEV; } + /* Use ti-sysc driver instead of omap_device? */ + if (!omap_hwmod_parse_module_range(NULL, node, &res)) + return -ENODEV; + hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL); if (!hwmods) { ret = -ENOMEM; diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 34156eca8e23..e7d23e200ecc 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -145,6 +145,8 @@ #include <linux/platform_data/ti-sysc.h> +#include <dt-bindings/bus/ti-sysc.h> + #include <asm/system_misc.h> #include "clock.h" @@ -2498,7 +2500,7 @@ static void __init _setup_postsetup(struct omap_hwmod *oh) * affects the IP block hardware, or system integration hardware * associated with the IP block. Returns 0. */ -static int __init _setup(struct omap_hwmod *oh, void *data) +static int _setup(struct omap_hwmod *oh, void *data) { if (oh->_state != _HWMOD_STATE_INITIALIZED) return 0; @@ -3060,6 +3062,414 @@ int __init omap_hwmod_setup_one(const char *oh_name) return 0; } +static void omap_hwmod_check_one(struct device *dev, + const char *name, s8 v1, u8 v2) +{ + if (v1 < 0) + return; + + if (v1 != v2) + dev_warn(dev, "%s %d != %d\n", name, v1, v2); +} + +/** + * omap_hwmod_check_sysc - check sysc against platform sysc + * @dev: struct device + * @data: module data + * @sysc_fields: new sysc configuration + */ +static int omap_hwmod_check_sysc(struct device *dev, + const struct ti_sysc_module_data *data, + struct sysc_regbits *sysc_fields) +{ + const struct sysc_regbits *regbits = data->cap->regbits; + + omap_hwmod_check_one(dev, "dmadisable_shift", + regbits->dmadisable_shift, + sysc_fields->dmadisable_shift); + omap_hwmod_check_one(dev, "midle_shift", + regbits->midle_shift, + sysc_fields->midle_shift); + omap_hwmod_check_one(dev, "sidle_shift", + regbits->sidle_shift, + sysc_fields->sidle_shift); + omap_hwmod_check_one(dev, "clkact_shift", + regbits->clkact_shift, + sysc_fields->clkact_shift); + omap_hwmod_check_one(dev, "enwkup_shift", + regbits->enwkup_shift, + sysc_fields->enwkup_shift); + omap_hwmod_check_one(dev, "srst_shift", + regbits->srst_shift, + sysc_fields->srst_shift); + omap_hwmod_check_one(dev, "autoidle_shift", + regbits->autoidle_shift, + sysc_fields->autoidle_shift); + + return 0; +} + +/** + * omap_hwmod_init_regbits - init sysconfig specific register bits + * @dev: struct device + * @data: module data + * @sysc_fields: new sysc configuration + */ +static int omap_hwmod_init_regbits(struct device *dev, + const struct ti_sysc_module_data *data, + struct sysc_regbits **sysc_fields) +{ + *sysc_fields = NULL; + + switch (data->cap->type) { + case TI_SYSC_OMAP2: + case TI_SYSC_OMAP2_TIMER: + *sysc_fields = &omap_hwmod_sysc_type1; + break; + case TI_SYSC_OMAP3_SHAM: + *sysc_fields = &omap3_sham_sysc_fields; + break; + case TI_SYSC_OMAP3_AES: + *sysc_fields = &omap3xxx_aes_sysc_fields; + break; + case TI_SYSC_OMAP4: + case TI_SYSC_OMAP4_TIMER: + *sysc_fields = &omap_hwmod_sysc_type2; + break; + case TI_SYSC_OMAP4_SIMPLE: + *sysc_fields = &omap_hwmod_sysc_type3; + break; + case TI_SYSC_OMAP34XX_SR: + *sysc_fields = &omap34xx_sr_sysc_fields; + break; + case TI_SYSC_OMAP36XX_SR: + *sysc_fields = &omap36xx_sr_sysc_fields; + break; + case TI_SYSC_OMAP4_SR: + *sysc_fields = &omap36xx_sr_sysc_fields; + break; + case TI_SYSC_OMAP4_MCASP: + *sysc_fields = &omap_hwmod_sysc_type_mcasp; + break; + case TI_SYSC_OMAP4_USB_HOST_FS: + *sysc_fields = &omap_hwmod_sysc_type_usb_host_fs; + break; + default: + return -EINVAL; + } + + return omap_hwmod_check_sysc(dev, data, *sysc_fields); +} + +/** + * omap_hwmod_init_reg_offs - initialize sysconfig register offsets + * @dev: struct device + * @data: module data + * @rev_offs: revision register offset + * @sysc_offs: sysc register offset + * @syss_offs: syss register offset + */ +int omap_hwmod_init_reg_offs(struct device *dev, + const struct ti_sysc_module_data *data, + u32 *rev_offs, u32 *sysc_offs, u32 *syss_offs) +{ + *rev_offs = 0; + *sysc_offs = 0; + *syss_offs = 0; + + if (data->offsets[SYSC_REVISION] > 0) + *rev_offs = data->offsets[SYSC_REVISION]; + + if (data->offsets[SYSC_SYSCONFIG] > 0) + *sysc_offs = data->offsets[SYSC_SYSCONFIG]; + + if (data->offsets[SYSC_SYSSTATUS] > 0) + *syss_offs = data->offsets[SYSC_SYSSTATUS]; + + return 0; +} + +/** + * omap_hwmod_init_sysc_flags - initialize sysconfig features + * @dev: struct device + * @data: module data + * @sysc_flags: module configuration + */ +int omap_hwmod_init_sysc_flags(struct device *dev, + const struct ti_sysc_module_data *data, + u32 *sysc_flags) +{ + *sysc_flags = 0; + + switch (data->cap->type) { + case TI_SYSC_OMAP2: + case TI_SYSC_OMAP2_TIMER: + /* See SYSC_OMAP2_* in include/dt-bindings/bus/ti-sysc.h */ + if (data->cfg->sysc_val & SYSC_OMAP2_CLOCKACTIVITY) + *sysc_flags |= SYSC_HAS_CLOCKACTIVITY; + if (data->cfg->sysc_val & SYSC_OMAP2_EMUFREE) + *sysc_flags |= SYSC_HAS_EMUFREE; + if (data->cfg->sysc_val & SYSC_OMAP2_ENAWAKEUP) + *sysc_flags |= SYSC_HAS_ENAWAKEUP; + if (data->cfg->sysc_val & SYSC_OMAP2_SOFTRESET) + *sysc_flags |= SYSC_HAS_SOFTRESET; + if (data->cfg->sysc_val & SYSC_OMAP2_AUTOIDLE) + *sysc_flags |= SYSC_HAS_AUTOIDLE; + break; + case TI_SYSC_OMAP4: + case TI_SYSC_OMAP4_TIMER: + /* See SYSC_OMAP4_* in include/dt-bindings/bus/ti-sysc.h */ + if (data->cfg->sysc_val & SYSC_OMAP4_DMADISABLE) + *sysc_flags |= SYSC_HAS_DMADISABLE; + if (data->cfg->sysc_val & SYSC_OMAP4_FREEEMU) + *sysc_flags |= SYSC_HAS_EMUFREE; + if (data->cfg->sysc_val & SYSC_OMAP4_SOFTRESET) + *sysc_flags |= SYSC_HAS_SOFTRESET; + break; + case TI_SYSC_OMAP34XX_SR: + case TI_SYSC_OMAP36XX_SR: + /* See SYSC_OMAP3_SR_* in include/dt-bindings/bus/ti-sysc.h */ + if (data->cfg->sysc_val & SYSC_OMAP3_SR_ENAWAKEUP) + *sysc_flags |= SYSC_HAS_ENAWAKEUP; + break; + default: + if (data->cap->regbits->emufree_shift >= 0) + *sysc_flags |= SYSC_HAS_EMUFREE; + if (data->cap->regbits->enwkup_shift >= 0) + *sysc_flags |= SYSC_HAS_ENAWAKEUP; + if (data->cap->regbits->srst_shift >= 0) + *sysc_flags |= SYSC_HAS_SOFTRESET; + if (data->cap->regbits->autoidle_shift >= 0) + *sysc_flags |= SYSC_HAS_AUTOIDLE; + break; + } + + if (data->cap->regbits->midle_shift >= 0 && + data->cfg->midlemodes) + *sysc_flags |= SYSC_HAS_MIDLEMODE; + + if (data->cap->regbits->sidle_shift >= 0 && + data->cfg->sidlemodes) + *sysc_flags |= SYSC_HAS_SIDLEMODE; + + if (data->cfg->quirks & SYSC_QUIRK_UNCACHED) + *sysc_flags |= SYSC_NO_CACHE; + if (data->cfg->quirks & SYSC_QUIRK_RESET_STATUS) + *sysc_flags |= SYSC_HAS_RESET_STATUS; + + if (data->cfg->syss_mask & 1) + *sysc_flags |= SYSS_HAS_RESET_STATUS; + + return 0; +} + +/** + * omap_hwmod_init_idlemodes - initialize module idle modes + * @dev: struct device + * @data: module data + * @idlemodes: module supported idle modes + */ +int omap_hwmod_init_idlemodes(struct device *dev, + const struct ti_sysc_module_data *data, + u32 *idlemodes) +{ + *idlemodes = 0; + + if (data->cfg->midlemodes & BIT(SYSC_IDLE_FORCE)) + *idlemodes |= MSTANDBY_FORCE; + if (data->cfg->midlemodes & BIT(SYSC_IDLE_NO)) + *idlemodes |= MSTANDBY_NO; + if (data->cfg->midlemodes & BIT(SYSC_IDLE_SMART)) + *idlemodes |= MSTANDBY_SMART; + if (data->cfg->midlemodes & BIT(SYSC_IDLE_SMART_WKUP)) + *idlemodes |= MSTANDBY_SMART_WKUP; + + if (data->cfg->sidlemodes & BIT(SYSC_IDLE_FORCE)) + *idlemodes |= SIDLE_FORCE; + if (data->cfg->sidlemodes & BIT(SYSC_IDLE_NO)) + *idlemodes |= SIDLE_NO; + if (data->cfg->sidlemodes & BIT(SYSC_IDLE_SMART)) + *idlemodes |= SIDLE_SMART; + if (data->cfg->sidlemodes & BIT(SYSC_IDLE_SMART_WKUP)) + *idlemodes |= SIDLE_SMART_WKUP; + + return 0; +} + +/** + * omap_hwmod_check_module - check new module against platform data + * @dev: struct device + * @oh: module + * @data: new module data + * @sysc_fields: sysc register bits + * @rev_offs: revision register offset + * @sysc_offs: sysconfig register offset + * @syss_offs: sysstatus register offset + * @sysc_flags: sysc specific flags + * @idlemodes: sysc supported idlemodes + */ +static int omap_hwmod_check_module(struct device *dev, + struct omap_hwmod *oh, + const struct ti_sysc_module_data *data, + struct sysc_regbits *sysc_fields, + u32 rev_offs, u32 sysc_offs, + u32 syss_offs, u32 sysc_flags, + u32 idlemodes) +{ + if (!oh->class->sysc) + return -ENODEV; + + if (sysc_fields != oh->class->sysc->sysc_fields) + dev_warn(dev, "sysc_fields %p != %p\n", sysc_fields, + oh->class->sysc->sysc_fields); + + if (rev_offs != oh->class->sysc->rev_offs) + dev_warn(dev, "rev_offs %08x != %08x\n", rev_offs, + oh->class->sysc->rev_offs); + if (sysc_offs != oh->class->sysc->sysc_offs) + dev_warn(dev, "sysc_offs %08x != %08x\n", sysc_offs, + oh->class->sysc->sysc_offs); + if (syss_offs != oh->class->sysc->syss_offs) + dev_warn(dev, "syss_offs %08x != %08x\n", syss_offs, + oh->class->sysc->syss_offs); + + if (sysc_flags != oh->class->sysc->sysc_flags) + dev_warn(dev, "sysc_flags %08x != %08x\n", sysc_flags, + oh->class->sysc->sysc_flags); + + if (idlemodes != oh->class->sysc->idlemodes) + dev_warn(dev, "idlemodes %08x != %08x\n", idlemodes, + oh->class->sysc->idlemodes); + + if (data->cfg->srst_udelay != oh->class->sysc->srst_udelay) + dev_warn(dev, "srst_udelay %i != %i\n", + data->cfg->srst_udelay, + oh->class->sysc->srst_udelay); + + return 0; +} + +/** + * omap_hwmod_allocate_module - allocate new module + * @dev: struct device + * @oh: module + * @sysc_fields: sysc register bits + * @rev_offs: revision register offset + * @sysc_offs: sysconfig register offset + * @syss_offs: sysstatus register offset + * @sysc_flags: sysc specific flags + * @idlemodes: sysc supported idlemodes + * + * Note that the allocations here cannot use devm as ti-sysc can rebind. + */ +int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh, + const struct ti_sysc_module_data *data, + struct sysc_regbits *sysc_fields, + u32 rev_offs, u32 sysc_offs, u32 syss_offs, + u32 sysc_flags, u32 idlemodes) +{ + struct omap_hwmod_class_sysconfig *sysc; + struct omap_hwmod_class *class; + void __iomem *regs = NULL; + unsigned long flags; + + sysc = kzalloc(sizeof(*sysc), GFP_KERNEL); + if (!sysc) + return -ENOMEM; + + sysc->sysc_fields = sysc_fields; + sysc->rev_offs = rev_offs; + sysc->sysc_offs = sysc_offs; + sysc->syss_offs = syss_offs; + sysc->sysc_flags = sysc_flags; + sysc->idlemodes = idlemodes; + sysc->srst_udelay = data->cfg->srst_udelay; + + if (!oh->_mpu_rt_va) { + regs = ioremap(data->module_pa, + data->module_size); + if (!regs) + return -ENOMEM; + } + + /* + * We need new oh->class as the other devices in the same class + * may not yet have ioremapped their registers. + */ + class = kmemdup(oh->class, sizeof(*oh->class), GFP_KERNEL); + if (!class) + return -ENOMEM; + + class->sysc = sysc; + + spin_lock_irqsave(&oh->_lock, flags); + if (regs) + oh->_mpu_rt_va = regs; + oh->class = class; + oh->_state = _HWMOD_STATE_INITIALIZED; + _setup(oh, NULL); + spin_unlock_irqrestore(&oh->_lock, flags); + + return 0; +} + +/** + * omap_hwmod_init_module - initialize new module + * @dev: struct device + * @data: module data + * @cookie: cookie for the caller to use for later calls + */ +int omap_hwmod_init_module(struct device *dev, + const struct ti_sysc_module_data *data, + struct ti_sysc_cookie *cookie) +{ + struct omap_hwmod *oh; + struct sysc_regbits *sysc_fields; + u32 rev_offs, sysc_offs, syss_offs, sysc_flags, idlemodes; + int error; + + if (!dev || !data) + return -EINVAL; + + oh = _lookup(data->name); + if (!oh) + return -ENODEV; + + cookie->data = oh; + + error = omap_hwmod_init_regbits(dev, data, &sysc_fields); + if (error) + return error; + + error = omap_hwmod_init_reg_offs(dev, data, &rev_offs, + &sysc_offs, &syss_offs); + if (error) + return error; + + error = omap_hwmod_init_sysc_flags(dev, data, &sysc_flags); + if (error) + return error; + + error = omap_hwmod_init_idlemodes(dev, data, &idlemodes); + if (error) + return error; + + if (data->cfg->quirks & SYSC_QUIRK_NO_IDLE_ON_INIT) + oh->flags |= HWMOD_INIT_NO_IDLE; + if (data->cfg->quirks & SYSC_QUIRK_NO_RESET_ON_INIT) + oh->flags |= HWMOD_INIT_NO_RESET; + + error = omap_hwmod_check_module(dev, oh, data, sysc_fields, + rev_offs, sysc_offs, syss_offs, + sysc_flags, idlemodes); + if (!error) + return error; + + return omap_hwmod_allocate_module(dev, oh, data, sysc_fields, + rev_offs, sysc_offs, syss_offs, + sysc_flags, idlemodes); +} + /** * omap_hwmod_setup_earlycon_flags - set up flags for early console * @@ -3082,6 +3492,12 @@ static void __init omap_hwmod_setup_earlycon_flags(void) if (np) { uart = of_get_property(np, "ti,hwmods", NULL); oh = omap_hwmod_lookup(uart); + if (!oh) { + uart = of_get_property(np->parent, + "ti,hwmods", + NULL); + oh = omap_hwmod_lookup(uart); + } if (oh) oh->flags |= DEBUG_OMAPUART_FLAGS; } diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index 0b8e19f40402..c7122abbf977 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h @@ -620,6 +620,13 @@ int omap_hwmod_parse_module_range(struct omap_hwmod *oh, struct device_node *np, struct resource *res); +struct ti_sysc_module_data; +struct ti_sysc_cookie; + +int omap_hwmod_init_module(struct device *dev, + const struct ti_sysc_module_data *data, + struct ti_sysc_cookie *cookie); + int omap_hwmod_enable(struct omap_hwmod *oh); int omap_hwmod_idle(struct omap_hwmod *oh); int omap_hwmod_shutdown(struct omap_hwmod *oh); diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index 0afb014b211f..fe66cf247874 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -14,9 +14,7 @@ */ #include <linux/i2c-omap.h> -#include <linux/platform_data/spi-omap2-mcspi.h> #include <linux/omap-dma.h> -#include <plat/dmtimer.h> #include "omap_hwmod.h" #include "l3_2xxx.h" @@ -97,13 +95,6 @@ static struct omap_hwmod_class i2c_class = { .reset = &omap_i2c_reset, }; -static struct omap_i2c_dev_attr i2c_dev_attr = { - .flags = OMAP_I2C_FLAG_NO_FIFO | - OMAP_I2C_FLAG_SIMPLE_CLOCK | - OMAP_I2C_FLAG_16BIT_DATA_REG | - OMAP_I2C_FLAG_BUS_SHIFT_2, -}; - /* I2C1 */ static struct omap_hwmod omap2420_i2c1_hwmod = { .name = "i2c1", @@ -116,7 +107,6 @@ static struct omap_hwmod omap2420_i2c1_hwmod = { }, }, .class = &i2c_class, - .dev_attr = &i2c_dev_attr, /* * From mach-omap2/pm24xx.c: "Putting MPU into the WFI state * while a transfer is active seems to cause the I2C block to @@ -137,7 +127,6 @@ static struct omap_hwmod omap2420_i2c2_hwmod = { }, }, .class = &i2c_class, - .dev_attr = &i2c_dev_attr, .flags = HWMOD_16BIT_REG, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index 013b26b305d2..74eefd30518c 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -14,11 +14,8 @@ */ #include <linux/i2c-omap.h> -#include <linux/platform_data/asoc-ti-mcbsp.h> #include <linux/platform_data/hsmmc-omap.h> -#include <linux/platform_data/spi-omap2-mcspi.h> #include <linux/omap-dma.h> -#include <plat/dmtimer.h> #include "omap_hwmod.h" #include "l3_2xxx.h" @@ -75,12 +72,6 @@ static struct omap_hwmod_class i2c_class = { .reset = &omap_i2c_reset, }; -static struct omap_i2c_dev_attr i2c_dev_attr = { - .fifo_depth = 8, /* bytes */ - .flags = OMAP_I2C_FLAG_BUS_SHIFT_2 | - OMAP_I2C_FLAG_FORCE_19200_INT_CLK, -}; - /* I2C1 */ static struct omap_hwmod omap2430_i2c1_hwmod = { .name = "i2c1", @@ -102,7 +93,6 @@ static struct omap_hwmod omap2430_i2c1_hwmod = { }, }, .class = &i2c_class, - .dev_attr = &i2c_dev_attr, }; /* I2C2 */ @@ -118,7 +108,6 @@ static struct omap_hwmod omap2430_i2c2_hwmod = { }, }, .class = &i2c_class, - .dev_attr = &i2c_dev_attr, }; /* gpio5 */ @@ -134,7 +123,6 @@ static struct omap_hwmod omap2430_gpio5_hwmod = { }, }, .class = &omap2xxx_gpio_hwmod_class, - .dev_attr = &omap2xxx_gpio_dev_attr, }; /* dma attributes */ @@ -167,10 +155,6 @@ static struct omap_hwmod omap2430_mailbox_hwmod = { }; /* mcspi3 */ -static struct omap2_mcspi_dev_attr omap_mcspi3_dev_attr = { - .num_chipselect = 2, -}; - static struct omap_hwmod omap2430_mcspi3_hwmod = { .name = "mcspi3", .main_clk = "mcspi3_fck", @@ -182,7 +166,6 @@ static struct omap_hwmod omap2430_mcspi3_hwmod = { }, }, .class = &omap2xxx_mcspi_class, - .dev_attr = &omap_mcspi3_dev_attr, }; /* usbhsotg */ @@ -239,7 +222,6 @@ static struct omap_hwmod_class_sysconfig omap2430_mcbsp_sysc = { static struct omap_hwmod_class omap2430_mcbsp_hwmod_class = { .name = "mcbsp", .sysc = &omap2430_mcbsp_sysc, - .rev = MCBSP_CONFIG_TYPE2, }; static struct omap_hwmod_opt_clk mcbsp_opt_clks[] = { diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c index 4b094cb384cb..5345919a81f8 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c @@ -9,10 +9,8 @@ * published by the Free Software Foundation. */ -#include <linux/platform_data/gpio-omap.h> +#include <linux/types.h> #include <linux/omap-dma.h> -#include <plat/dmtimer.h> -#include <linux/platform_data/spi-omap2-mcspi.h> #include "omap_hwmod.h" #include "omap_hwmod_common_data.h" @@ -159,7 +157,6 @@ static struct omap_hwmod_class_sysconfig omap2xxx_mcspi_sysc = { struct omap_hwmod_class omap2xxx_mcspi_class = { .name = "mcspi", .sysc = &omap2xxx_mcspi_sysc, - .rev = OMAP2_MCSPI_REV, }; /* @@ -220,23 +217,7 @@ struct omap_hwmod omap2xxx_iva_hwmod = { .class = &iva_hwmod_class, }; -/* always-on timers dev attribute */ -static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = { - .timer_capability = OMAP_TIMER_ALWON, -}; - -/* pwm timers dev attribute */ -static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = { - .timer_capability = OMAP_TIMER_HAS_PWM, -}; - -/* timers with DSP interrupt dev attribute */ -static struct omap_timer_capability_dev_attr capability_dsp_dev_attr = { - .timer_capability = OMAP_TIMER_HAS_DSP_IRQ, -}; - /* timer1 */ - struct omap_hwmod omap2xxx_timer1_hwmod = { .name = "timer1", .main_clk = "gpt1_fck", @@ -247,13 +228,11 @@ struct omap_hwmod omap2xxx_timer1_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT1_SHIFT, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &omap2xxx_timer_hwmod_class, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; /* timer2 */ - struct omap_hwmod omap2xxx_timer2_hwmod = { .name = "timer2", .main_clk = "gpt2_fck", @@ -269,7 +248,6 @@ struct omap_hwmod omap2xxx_timer2_hwmod = { }; /* timer3 */ - struct omap_hwmod omap2xxx_timer3_hwmod = { .name = "timer3", .main_clk = "gpt3_fck", @@ -285,7 +263,6 @@ struct omap_hwmod omap2xxx_timer3_hwmod = { }; /* timer4 */ - struct omap_hwmod omap2xxx_timer4_hwmod = { .name = "timer4", .main_clk = "gpt4_fck", @@ -301,7 +278,6 @@ struct omap_hwmod omap2xxx_timer4_hwmod = { }; /* timer5 */ - struct omap_hwmod omap2xxx_timer5_hwmod = { .name = "timer5", .main_clk = "gpt5_fck", @@ -312,13 +288,11 @@ struct omap_hwmod omap2xxx_timer5_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT5_SHIFT, }, }, - .dev_attr = &capability_dsp_dev_attr, .class = &omap2xxx_timer_hwmod_class, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; /* timer6 */ - struct omap_hwmod omap2xxx_timer6_hwmod = { .name = "timer6", .main_clk = "gpt6_fck", @@ -329,13 +303,11 @@ struct omap_hwmod omap2xxx_timer6_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT6_SHIFT, }, }, - .dev_attr = &capability_dsp_dev_attr, .class = &omap2xxx_timer_hwmod_class, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; /* timer7 */ - struct omap_hwmod omap2xxx_timer7_hwmod = { .name = "timer7", .main_clk = "gpt7_fck", @@ -346,13 +318,11 @@ struct omap_hwmod omap2xxx_timer7_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT7_SHIFT, }, }, - .dev_attr = &capability_dsp_dev_attr, .class = &omap2xxx_timer_hwmod_class, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; /* timer8 */ - struct omap_hwmod omap2xxx_timer8_hwmod = { .name = "timer8", .main_clk = "gpt8_fck", @@ -363,13 +333,11 @@ struct omap_hwmod omap2xxx_timer8_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT8_SHIFT, }, }, - .dev_attr = &capability_dsp_dev_attr, .class = &omap2xxx_timer_hwmod_class, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; /* timer9 */ - struct omap_hwmod omap2xxx_timer9_hwmod = { .name = "timer9", .main_clk = "gpt9_fck", @@ -380,13 +348,11 @@ struct omap_hwmod omap2xxx_timer9_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT9_SHIFT, }, }, - .dev_attr = &capability_pwm_dev_attr, .class = &omap2xxx_timer_hwmod_class, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; /* timer10 */ - struct omap_hwmod omap2xxx_timer10_hwmod = { .name = "timer10", .main_clk = "gpt10_fck", @@ -397,13 +363,11 @@ struct omap_hwmod omap2xxx_timer10_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT10_SHIFT, }, }, - .dev_attr = &capability_pwm_dev_attr, .class = &omap2xxx_timer_hwmod_class, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; /* timer11 */ - struct omap_hwmod omap2xxx_timer11_hwmod = { .name = "timer11", .main_clk = "gpt11_fck", @@ -414,13 +378,11 @@ struct omap_hwmod omap2xxx_timer11_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT11_SHIFT, }, }, - .dev_attr = &capability_pwm_dev_attr, .class = &omap2xxx_timer_hwmod_class, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; /* timer12 */ - struct omap_hwmod omap2xxx_timer12_hwmod = { .name = "timer12", .main_clk = "gpt12_fck", @@ -431,7 +393,6 @@ struct omap_hwmod omap2xxx_timer12_hwmod = { .idlest_idle_bit = OMAP24XX_ST_GPT12_SHIFT, }, }, - .dev_attr = &capability_pwm_dev_attr, .class = &omap2xxx_timer_hwmod_class, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; @@ -568,12 +529,6 @@ struct omap_hwmod omap2xxx_dss_venc_hwmod = { .flags = HWMOD_NO_IDLEST, }; -/* gpio dev_attr */ -struct omap_gpio_dev_attr omap2xxx_gpio_dev_attr = { - .bank_width = 32, - .dbck_flag = false, -}; - /* gpio1 */ struct omap_hwmod omap2xxx_gpio1_hwmod = { .name = "gpio1", @@ -587,7 +542,6 @@ struct omap_hwmod omap2xxx_gpio1_hwmod = { }, }, .class = &omap2xxx_gpio_hwmod_class, - .dev_attr = &omap2xxx_gpio_dev_attr, }; /* gpio2 */ @@ -603,7 +557,6 @@ struct omap_hwmod omap2xxx_gpio2_hwmod = { }, }, .class = &omap2xxx_gpio_hwmod_class, - .dev_attr = &omap2xxx_gpio_dev_attr, }; /* gpio3 */ @@ -619,7 +572,6 @@ struct omap_hwmod omap2xxx_gpio3_hwmod = { }, }, .class = &omap2xxx_gpio_hwmod_class, - .dev_attr = &omap2xxx_gpio_dev_attr, }; /* gpio4 */ @@ -635,14 +587,9 @@ struct omap_hwmod omap2xxx_gpio4_hwmod = { }, }, .class = &omap2xxx_gpio_hwmod_class, - .dev_attr = &omap2xxx_gpio_dev_attr, }; /* mcspi1 */ -static struct omap2_mcspi_dev_attr omap_mcspi1_dev_attr = { - .num_chipselect = 4, -}; - struct omap_hwmod omap2xxx_mcspi1_hwmod = { .name = "mcspi1", .main_clk = "mcspi1_fck", @@ -654,14 +601,9 @@ struct omap_hwmod omap2xxx_mcspi1_hwmod = { }, }, .class = &omap2xxx_mcspi_class, - .dev_attr = &omap_mcspi1_dev_attr, }; /* mcspi2 */ -static struct omap2_mcspi_dev_attr omap_mcspi2_dev_attr = { - .num_chipselect = 2, -}; - struct omap_hwmod omap2xxx_mcspi2_hwmod = { .name = "mcspi2", .main_clk = "mcspi2_fck", @@ -673,7 +615,6 @@ struct omap_hwmod omap2xxx_mcspi2_hwmod = { }, }, .class = &omap2xxx_mcspi_class, - .dev_attr = &omap_mcspi2_dev_attr, }; static struct omap_hwmod_class omap2xxx_counter_hwmod_class = { diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h index 434bd1a77229..6f81d7a4fec1 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_common_data.h @@ -139,9 +139,6 @@ extern struct omap_hwmod_class am33xx_epwmss_hwmod_class; extern struct omap_hwmod_class am33xx_ehrpwm_hwmod_class; extern struct omap_hwmod_class am33xx_spi_hwmod_class; -extern struct omap_gpio_dev_attr gpio_dev_attr; -extern struct omap2_mcspi_dev_attr mcspi_attrib; - void omap_hwmod_am33xx_reg(void); void omap_hwmod_am43xx_reg(void); diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c index 4bcf9f3e1544..5efe91c6e95b 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c @@ -14,9 +14,9 @@ * GNU General Public License for more details. */ -#include <linux/platform_data/gpio-omap.h> +#include <linux/types.h> + #include <linux/platform_data/hsmmc-omap.h> -#include <linux/platform_data/spi-omap2-mcspi.h> #include "omap_hwmod.h" #include "i2c.h" #include "wd_timer.h" @@ -537,11 +537,6 @@ struct omap_hwmod_class am33xx_gpio_hwmod_class = { .rev = 2, }; -struct omap_gpio_dev_attr gpio_dev_attr = { - .bank_width = 32, - .dbck_flag = true, -}; - /* gpio1 */ static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { { .role = "dbclk", .clk = "gpio1_dbclk" }, @@ -560,7 +555,6 @@ struct omap_hwmod am33xx_gpio1_hwmod = { }, .opt_clks = gpio1_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio2 */ @@ -581,7 +575,6 @@ struct omap_hwmod am33xx_gpio2_hwmod = { }, .opt_clks = gpio2_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio3 */ @@ -602,7 +595,6 @@ struct omap_hwmod am33xx_gpio3_hwmod = { }, .opt_clks = gpio3_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpmc */ @@ -654,10 +646,6 @@ static struct omap_hwmod_class i2c_class = { .reset = &omap_i2c_reset, }; -static struct omap_i2c_dev_attr i2c_dev_attr = { - .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE, -}; - /* i2c1 */ struct omap_hwmod am33xx_i2c1_hwmod = { .name = "i2c1", @@ -670,7 +658,6 @@ struct omap_hwmod am33xx_i2c1_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &i2c_dev_attr, }; /* i2c1 */ @@ -685,7 +672,6 @@ struct omap_hwmod am33xx_i2c2_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &i2c_dev_attr, }; /* i2c3 */ @@ -700,7 +686,6 @@ struct omap_hwmod am33xx_i2c3_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &i2c_dev_attr, }; /* @@ -893,13 +878,9 @@ static struct omap_hwmod_class_sysconfig am33xx_mcspi_sysc = { struct omap_hwmod_class am33xx_spi_hwmod_class = { .name = "mcspi", .sysc = &am33xx_mcspi_sysc, - .rev = OMAP4_MCSPI_REV, }; /* spi0 */ -struct omap2_mcspi_dev_attr mcspi_attrib = { - .num_chipselect = 2, -}; struct omap_hwmod am33xx_spi0_hwmod = { .name = "spi0", .class = &am33xx_spi_hwmod_class, @@ -910,7 +891,6 @@ struct omap_hwmod am33xx_spi0_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &mcspi_attrib, }; /* spi1 */ @@ -924,7 +904,6 @@ struct omap_hwmod am33xx_spi1_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &mcspi_attrib, }; /* diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index 4d16b15bb0cf..53e1ac3724f2 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -17,9 +17,6 @@ #include <linux/i2c-omap.h> #include "omap_hwmod.h" -#include <linux/platform_data/gpio-omap.h> -#include <linux/platform_data/spi-omap2-mcspi.h> - #include "omap_hwmod_common_data.h" #include "control.h" @@ -252,7 +249,6 @@ static struct omap_hwmod am33xx_gpio0_hwmod = { }, .opt_clks = gpio0_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio0_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* lcdc */ diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 1a2f2242e31b..23336b6c7125 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -17,15 +17,11 @@ #include <linux/i2c-omap.h> #include <linux/power/smartreflex.h> -#include <linux/platform_data/gpio-omap.h> #include <linux/platform_data/hsmmc-omap.h> #include <linux/omap-dma.h> #include "l3_3xxx.h" #include "l4_3xxx.h" -#include <linux/platform_data/asoc-ti-mcbsp.h> -#include <linux/platform_data/spi-omap2-mcspi.h> -#include <plat/dmtimer.h> #include "soc.h" #include "omap_hwmod.h" @@ -155,31 +151,6 @@ static struct omap_hwmod_class omap3xxx_timer_hwmod_class = { .sysc = &omap3xxx_timer_sysc, }; -/* secure timers dev attribute */ -static struct omap_timer_capability_dev_attr capability_secure_dev_attr = { - .timer_capability = OMAP_TIMER_ALWON | OMAP_TIMER_SECURE, -}; - -/* always-on timers dev attribute */ -static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = { - .timer_capability = OMAP_TIMER_ALWON, -}; - -/* pwm timers dev attribute */ -static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = { - .timer_capability = OMAP_TIMER_HAS_PWM, -}; - -/* timers with DSP interrupt dev attribute */ -static struct omap_timer_capability_dev_attr capability_dsp_dev_attr = { - .timer_capability = OMAP_TIMER_HAS_DSP_IRQ, -}; - -/* pwm timers with DSP interrupt dev attribute */ -static struct omap_timer_capability_dev_attr capability_dsp_pwm_dev_attr = { - .timer_capability = OMAP_TIMER_HAS_DSP_IRQ | OMAP_TIMER_HAS_PWM, -}; - /* timer1 */ static struct omap_hwmod omap3xxx_timer1_hwmod = { .name = "timer1", @@ -191,7 +162,6 @@ static struct omap_hwmod omap3xxx_timer1_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT1_SHIFT, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &omap3xxx_timer_hwmod_class, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; @@ -252,7 +222,6 @@ static struct omap_hwmod omap3xxx_timer5_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT5_SHIFT, }, }, - .dev_attr = &capability_dsp_dev_attr, .class = &omap3xxx_timer_hwmod_class, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; @@ -268,7 +237,6 @@ static struct omap_hwmod omap3xxx_timer6_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT6_SHIFT, }, }, - .dev_attr = &capability_dsp_dev_attr, .class = &omap3xxx_timer_hwmod_class, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; @@ -284,7 +252,6 @@ static struct omap_hwmod omap3xxx_timer7_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT7_SHIFT, }, }, - .dev_attr = &capability_dsp_dev_attr, .class = &omap3xxx_timer_hwmod_class, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; @@ -300,7 +267,6 @@ static struct omap_hwmod omap3xxx_timer8_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT8_SHIFT, }, }, - .dev_attr = &capability_dsp_pwm_dev_attr, .class = &omap3xxx_timer_hwmod_class, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; @@ -316,7 +282,6 @@ static struct omap_hwmod omap3xxx_timer9_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT9_SHIFT, }, }, - .dev_attr = &capability_pwm_dev_attr, .class = &omap3xxx_timer_hwmod_class, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; @@ -332,7 +297,6 @@ static struct omap_hwmod omap3xxx_timer10_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT10_SHIFT, }, }, - .dev_attr = &capability_pwm_dev_attr, .class = &omap3xxx_timer_hwmod_class, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; @@ -348,13 +312,11 @@ static struct omap_hwmod omap3xxx_timer11_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT11_SHIFT, }, }, - .dev_attr = &capability_pwm_dev_attr, .class = &omap3xxx_timer_hwmod_class, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; /* timer12 */ - static struct omap_hwmod omap3xxx_timer12_hwmod = { .name = "timer12", .main_clk = "gpt12_fck", @@ -365,7 +327,6 @@ static struct omap_hwmod omap3xxx_timer12_hwmod = { .idlest_idle_bit = OMAP3430_ST_GPT12_SHIFT, }, }, - .dev_attr = &capability_secure_dev_attr, .class = &omap3xxx_timer_hwmod_class, .flags = HWMOD_SET_DEFAULT_CLOCKACT, }; @@ -683,11 +644,6 @@ static struct omap_hwmod omap3xxx_dss_venc_hwmod = { }; /* I2C1 */ -static struct omap_i2c_dev_attr i2c1_dev_attr = { - .fifo_depth = 8, /* bytes */ - .flags = OMAP_I2C_FLAG_BUS_SHIFT_2, -}; - static struct omap_hwmod omap3xxx_i2c1_hwmod = { .name = "i2c1", .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, @@ -700,15 +656,9 @@ static struct omap_hwmod omap3xxx_i2c1_hwmod = { }, }, .class = &i2c_class, - .dev_attr = &i2c1_dev_attr, }; /* I2C2 */ -static struct omap_i2c_dev_attr i2c2_dev_attr = { - .fifo_depth = 8, /* bytes */ - .flags = OMAP_I2C_FLAG_BUS_SHIFT_2, -}; - static struct omap_hwmod omap3xxx_i2c2_hwmod = { .name = "i2c2", .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, @@ -721,17 +671,9 @@ static struct omap_hwmod omap3xxx_i2c2_hwmod = { }, }, .class = &i2c_class, - .dev_attr = &i2c2_dev_attr, }; /* I2C3 */ -static struct omap_i2c_dev_attr i2c3_dev_attr = { - .fifo_depth = 64, /* bytes */ - .flags = OMAP_I2C_FLAG_BUS_SHIFT_2, -}; - - - static struct omap_hwmod omap3xxx_i2c3_hwmod = { .name = "i2c3", .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, @@ -744,7 +686,6 @@ static struct omap_hwmod omap3xxx_i2c3_hwmod = { }, }, .class = &i2c_class, - .dev_attr = &i2c3_dev_attr, }; /* @@ -769,12 +710,6 @@ static struct omap_hwmod_class omap3xxx_gpio_hwmod_class = { .rev = 1, }; -/* gpio_dev_attr */ -static struct omap_gpio_dev_attr gpio_dev_attr = { - .bank_width = 32, - .dbck_flag = true, -}; - /* gpio1 */ static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { { .role = "dbclk", .clk = "gpio1_dbck", }, @@ -794,7 +729,6 @@ static struct omap_hwmod omap3xxx_gpio1_hwmod = { }, }, .class = &omap3xxx_gpio_hwmod_class, - .dev_attr = &gpio_dev_attr, }; /* gpio2 */ @@ -816,7 +750,6 @@ static struct omap_hwmod omap3xxx_gpio2_hwmod = { }, }, .class = &omap3xxx_gpio_hwmod_class, - .dev_attr = &gpio_dev_attr, }; /* gpio3 */ @@ -838,7 +771,6 @@ static struct omap_hwmod omap3xxx_gpio3_hwmod = { }, }, .class = &omap3xxx_gpio_hwmod_class, - .dev_attr = &gpio_dev_attr, }; /* gpio4 */ @@ -860,7 +792,6 @@ static struct omap_hwmod omap3xxx_gpio4_hwmod = { }, }, .class = &omap3xxx_gpio_hwmod_class, - .dev_attr = &gpio_dev_attr, }; /* gpio5 */ @@ -883,7 +814,6 @@ static struct omap_hwmod omap3xxx_gpio5_hwmod = { }, }, .class = &omap3xxx_gpio_hwmod_class, - .dev_attr = &gpio_dev_attr, }; /* gpio6 */ @@ -906,7 +836,6 @@ static struct omap_hwmod omap3xxx_gpio6_hwmod = { }, }, .class = &omap3xxx_gpio_hwmod_class, - .dev_attr = &gpio_dev_attr, }; /* dma attributes */ @@ -966,7 +895,6 @@ static struct omap_hwmod_class_sysconfig omap3xxx_mcbsp_sysc = { static struct omap_hwmod_class omap3xxx_mcbsp_hwmod_class = { .name = "mcbsp", .sysc = &omap3xxx_mcbsp_sysc, - .rev = MCBSP_CONFIG_TYPE3, }; /* McBSP functional clock mapping */ @@ -981,7 +909,6 @@ static struct omap_hwmod_opt_clk mcbsp234_opt_clks[] = { }; /* mcbsp1 */ - static struct omap_hwmod omap3xxx_mcbsp1_hwmod = { .name = "mcbsp1", .class = &omap3xxx_mcbsp_hwmod_class, @@ -998,11 +925,6 @@ static struct omap_hwmod omap3xxx_mcbsp1_hwmod = { }; /* mcbsp2 */ - -static struct omap_mcbsp_dev_attr omap34xx_mcbsp2_dev_attr = { - .sidetone = "mcbsp2_sidetone", -}; - static struct omap_hwmod omap3xxx_mcbsp2_hwmod = { .name = "mcbsp2", .class = &omap3xxx_mcbsp_hwmod_class, @@ -1016,15 +938,9 @@ static struct omap_hwmod omap3xxx_mcbsp2_hwmod = { }, .opt_clks = mcbsp234_opt_clks, .opt_clks_cnt = ARRAY_SIZE(mcbsp234_opt_clks), - .dev_attr = &omap34xx_mcbsp2_dev_attr, }; /* mcbsp3 */ - -static struct omap_mcbsp_dev_attr omap34xx_mcbsp3_dev_attr = { - .sidetone = "mcbsp3_sidetone", -}; - static struct omap_hwmod omap3xxx_mcbsp3_hwmod = { .name = "mcbsp3", .class = &omap3xxx_mcbsp_hwmod_class, @@ -1038,12 +954,9 @@ static struct omap_hwmod omap3xxx_mcbsp3_hwmod = { }, .opt_clks = mcbsp234_opt_clks, .opt_clks_cnt = ARRAY_SIZE(mcbsp234_opt_clks), - .dev_attr = &omap34xx_mcbsp3_dev_attr, }; /* mcbsp4 */ - - static struct omap_hwmod omap3xxx_mcbsp4_hwmod = { .name = "mcbsp4", .class = &omap3xxx_mcbsp_hwmod_class, @@ -1060,8 +973,6 @@ static struct omap_hwmod omap3xxx_mcbsp4_hwmod = { }; /* mcbsp5 */ - - static struct omap_hwmod omap3xxx_mcbsp5_hwmod = { .name = "mcbsp5", .class = &omap3xxx_mcbsp_hwmod_class, @@ -1090,7 +1001,6 @@ static struct omap_hwmod_class omap3xxx_mcbsp_sidetone_hwmod_class = { }; /* mcbsp2_sidetone */ - static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod = { .name = "mcbsp2_sidetone", .class = &omap3xxx_mcbsp_sidetone_hwmod_class, @@ -1099,7 +1009,6 @@ static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod = { }; /* mcbsp3_sidetone */ - static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod = { .name = "mcbsp3_sidetone", .class = &omap3xxx_mcbsp_sidetone_hwmod_class, @@ -1258,14 +1167,9 @@ static struct omap_hwmod_class_sysconfig omap34xx_mcspi_sysc = { static struct omap_hwmod_class omap34xx_mcspi_class = { .name = "mcspi", .sysc = &omap34xx_mcspi_sysc, - .rev = OMAP3_MCSPI_REV, }; /* mcspi1 */ -static struct omap2_mcspi_dev_attr omap_mcspi1_dev_attr = { - .num_chipselect = 4, -}; - static struct omap_hwmod omap34xx_mcspi1 = { .name = "mcspi1", .main_clk = "mcspi1_fck", @@ -1277,14 +1181,9 @@ static struct omap_hwmod omap34xx_mcspi1 = { }, }, .class = &omap34xx_mcspi_class, - .dev_attr = &omap_mcspi1_dev_attr, }; /* mcspi2 */ -static struct omap2_mcspi_dev_attr omap_mcspi2_dev_attr = { - .num_chipselect = 2, -}; - static struct omap_hwmod omap34xx_mcspi2 = { .name = "mcspi2", .main_clk = "mcspi2_fck", @@ -1296,16 +1195,9 @@ static struct omap_hwmod omap34xx_mcspi2 = { }, }, .class = &omap34xx_mcspi_class, - .dev_attr = &omap_mcspi2_dev_attr, }; /* mcspi3 */ - - -static struct omap2_mcspi_dev_attr omap_mcspi3_dev_attr = { - .num_chipselect = 2, -}; - static struct omap_hwmod omap34xx_mcspi3 = { .name = "mcspi3", .main_clk = "mcspi3_fck", @@ -1317,16 +1209,9 @@ static struct omap_hwmod omap34xx_mcspi3 = { }, }, .class = &omap34xx_mcspi_class, - .dev_attr = &omap_mcspi3_dev_attr, }; /* mcspi4 */ - - -static struct omap2_mcspi_dev_attr omap_mcspi4_dev_attr = { - .num_chipselect = 1, -}; - static struct omap_hwmod omap34xx_mcspi4 = { .name = "mcspi4", .main_clk = "mcspi4_fck", @@ -1338,7 +1223,6 @@ static struct omap_hwmod omap34xx_mcspi4 = { }, }, .class = &omap34xx_mcspi_class, - .dev_attr = &omap_mcspi4_dev_attr, }; /* usbhsotg */ diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c index afbce1f6f641..5f73b730d4fc 100644 --- a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c @@ -14,8 +14,6 @@ * GNU General Public License for more details. */ -#include <linux/platform_data/gpio-omap.h> -#include <linux/platform_data/spi-omap2-mcspi.h> #include "omap_hwmod.h" #include "omap_hwmod_33xx_43xx_common_data.h" #include "prcm43xx.h" @@ -107,7 +105,6 @@ static struct omap_hwmod am43xx_gpio0_hwmod = { }, .opt_clks = gpio0_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio0_opt_clks), - .dev_attr = &gpio_dev_attr, }; static struct omap_hwmod_class_sysconfig am43xx_synctimer_sysc = { @@ -239,7 +236,6 @@ static struct omap_hwmod am43xx_spi2_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &mcspi_attrib, }; static struct omap_hwmod am43xx_spi3_hwmod = { @@ -253,7 +249,6 @@ static struct omap_hwmod am43xx_spi3_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &mcspi_attrib, }; static struct omap_hwmod am43xx_spi4_hwmod = { @@ -267,7 +262,6 @@ static struct omap_hwmod am43xx_spi4_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &mcspi_attrib, }; static struct omap_hwmod_opt_clk gpio4_opt_clks[] = { @@ -288,7 +282,6 @@ static struct omap_hwmod am43xx_gpio4_hwmod = { }, .opt_clks = gpio4_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks), - .dev_attr = &gpio_dev_attr, }; static struct omap_hwmod_opt_clk gpio5_opt_clks[] = { @@ -309,7 +302,6 @@ static struct omap_hwmod am43xx_gpio5_hwmod = { }, .opt_clks = gpio5_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks), - .dev_attr = &gpio_dev_attr, }; static struct omap_hwmod_class am43xx_ocp2scp_hwmod_class = { diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index a1901c22a0f0..e4f8ae9cd637 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -21,17 +21,12 @@ */ #include <linux/io.h> -#include <linux/platform_data/gpio-omap.h> #include <linux/platform_data/hsmmc-omap.h> #include <linux/power/smartreflex.h> #include <linux/i2c-omap.h> #include <linux/omap-dma.h> -#include <linux/platform_data/spi-omap2-mcspi.h> -#include <linux/platform_data/asoc-ti-mcbsp.h> -#include <plat/dmtimer.h> - #include "omap_hwmod.h" #include "omap_hwmod_common_data.h" #include "cm1_44xx.h" @@ -1083,12 +1078,6 @@ static struct omap_hwmod_class omap44xx_gpio_hwmod_class = { .rev = 2, }; -/* gpio dev_attr */ -static struct omap_gpio_dev_attr gpio_dev_attr = { - .bank_width = 32, - .dbck_flag = true, -}; - /* gpio1 */ static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { { .role = "dbclk", .clk = "gpio1_dbclk" }, @@ -1108,7 +1097,6 @@ static struct omap_hwmod omap44xx_gpio1_hwmod = { }, .opt_clks = gpio1_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio2 */ @@ -1131,7 +1119,6 @@ static struct omap_hwmod omap44xx_gpio2_hwmod = { }, .opt_clks = gpio2_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio3 */ @@ -1154,7 +1141,6 @@ static struct omap_hwmod omap44xx_gpio3_hwmod = { }, .opt_clks = gpio3_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio4 */ @@ -1177,7 +1163,6 @@ static struct omap_hwmod omap44xx_gpio4_hwmod = { }, .opt_clks = gpio4_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio5 */ @@ -1200,7 +1185,6 @@ static struct omap_hwmod omap44xx_gpio5_hwmod = { }, .opt_clks = gpio5_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio6 */ @@ -1223,7 +1207,6 @@ static struct omap_hwmod omap44xx_gpio6_hwmod = { }, .opt_clks = gpio6_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* @@ -1394,10 +1377,6 @@ static struct omap_hwmod_class omap44xx_i2c_hwmod_class = { .reset = &omap_i2c_reset, }; -static struct omap_i2c_dev_attr i2c_dev_attr = { - .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE, -}; - /* i2c1 */ static struct omap_hwmod omap44xx_i2c1_hwmod = { .name = "i2c1", @@ -1412,7 +1391,6 @@ static struct omap_hwmod omap44xx_i2c1_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &i2c_dev_attr, }; /* i2c2 */ @@ -1429,7 +1407,6 @@ static struct omap_hwmod omap44xx_i2c2_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &i2c_dev_attr, }; /* i2c3 */ @@ -1446,7 +1423,6 @@ static struct omap_hwmod omap44xx_i2c3_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &i2c_dev_attr, }; /* i2c4 */ @@ -1463,7 +1439,6 @@ static struct omap_hwmod omap44xx_i2c4_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &i2c_dev_attr, }; /* @@ -1702,7 +1677,6 @@ static struct omap_hwmod_class_sysconfig omap44xx_mcbsp_sysc = { static struct omap_hwmod_class omap44xx_mcbsp_hwmod_class = { .name = "mcbsp", .sysc = &omap44xx_mcbsp_sysc, - .rev = MCBSP_CONFIG_TYPE4, }; /* mcbsp1 */ @@ -1860,14 +1834,9 @@ static struct omap_hwmod_class_sysconfig omap44xx_mcspi_sysc = { static struct omap_hwmod_class omap44xx_mcspi_hwmod_class = { .name = "mcspi", .sysc = &omap44xx_mcspi_sysc, - .rev = OMAP4_MCSPI_REV, }; /* mcspi1 */ -static struct omap2_mcspi_dev_attr mcspi1_dev_attr = { - .num_chipselect = 4, -}; - static struct omap_hwmod omap44xx_mcspi1_hwmod = { .name = "mcspi1", .class = &omap44xx_mcspi_hwmod_class, @@ -1880,14 +1849,9 @@ static struct omap_hwmod omap44xx_mcspi1_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &mcspi1_dev_attr, }; /* mcspi2 */ -static struct omap2_mcspi_dev_attr mcspi2_dev_attr = { - .num_chipselect = 2, -}; - static struct omap_hwmod omap44xx_mcspi2_hwmod = { .name = "mcspi2", .class = &omap44xx_mcspi_hwmod_class, @@ -1900,14 +1864,9 @@ static struct omap_hwmod omap44xx_mcspi2_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &mcspi2_dev_attr, }; /* mcspi3 */ -static struct omap2_mcspi_dev_attr mcspi3_dev_attr = { - .num_chipselect = 2, -}; - static struct omap_hwmod omap44xx_mcspi3_hwmod = { .name = "mcspi3", .class = &omap44xx_mcspi_hwmod_class, @@ -1920,14 +1879,9 @@ static struct omap_hwmod omap44xx_mcspi3_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &mcspi3_dev_attr, }; /* mcspi4 */ -static struct omap2_mcspi_dev_attr mcspi4_dev_attr = { - .num_chipselect = 1, -}; - static struct omap_hwmod omap44xx_mcspi4_hwmod = { .name = "mcspi4", .class = &omap44xx_mcspi_hwmod_class, @@ -1940,7 +1894,6 @@ static struct omap_hwmod omap44xx_mcspi4_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &mcspi4_dev_attr, }; /* @@ -2547,26 +2500,6 @@ static struct omap_hwmod_class omap44xx_timer_hwmod_class = { .sysc = &omap44xx_timer_sysc, }; -/* always-on timers dev attribute */ -static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = { - .timer_capability = OMAP_TIMER_ALWON, -}; - -/* pwm timers dev attribute */ -static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = { - .timer_capability = OMAP_TIMER_HAS_PWM, -}; - -/* timers with DSP interrupt dev attribute */ -static struct omap_timer_capability_dev_attr capability_dsp_dev_attr = { - .timer_capability = OMAP_TIMER_HAS_DSP_IRQ, -}; - -/* pwm timers with DSP interrupt dev attribute */ -static struct omap_timer_capability_dev_attr capability_dsp_pwm_dev_attr = { - .timer_capability = OMAP_TIMER_HAS_DSP_IRQ | OMAP_TIMER_HAS_PWM, -}; - /* timer1 */ static struct omap_hwmod omap44xx_timer1_hwmod = { .name = "timer1", @@ -2581,7 +2514,6 @@ static struct omap_hwmod omap44xx_timer1_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_alwon_dev_attr, }; /* timer2 */ @@ -2643,7 +2575,6 @@ static struct omap_hwmod omap44xx_timer5_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_dsp_dev_attr, }; /* timer6 */ @@ -2659,7 +2590,6 @@ static struct omap_hwmod omap44xx_timer6_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_dsp_dev_attr, }; /* timer7 */ @@ -2675,7 +2605,6 @@ static struct omap_hwmod omap44xx_timer7_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_dsp_dev_attr, }; /* timer8 */ @@ -2691,7 +2620,6 @@ static struct omap_hwmod omap44xx_timer8_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_dsp_pwm_dev_attr, }; /* timer9 */ @@ -2707,7 +2635,6 @@ static struct omap_hwmod omap44xx_timer9_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_pwm_dev_attr, }; /* timer10 */ @@ -2724,7 +2651,6 @@ static struct omap_hwmod omap44xx_timer10_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_pwm_dev_attr, }; /* timer11 */ @@ -2740,7 +2666,6 @@ static struct omap_hwmod omap44xx_timer11_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_pwm_dev_attr, }; /* diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c index 988e7eaa1330..c72cd84b07ec 100644 --- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c @@ -18,15 +18,11 @@ */ #include <linux/io.h> -#include <linux/platform_data/gpio-omap.h> #include <linux/platform_data/hsmmc-omap.h> #include <linux/power/smartreflex.h> #include <linux/i2c-omap.h> #include <linux/omap-dma.h> -#include <linux/platform_data/spi-omap2-mcspi.h> -#include <linux/platform_data/asoc-ti-mcbsp.h> -#include <plat/dmtimer.h> #include "omap_hwmod.h" #include "omap_hwmod_common_data.h" @@ -627,12 +623,6 @@ static struct omap_hwmod_class omap54xx_gpio_hwmod_class = { .rev = 2, }; -/* gpio dev_attr */ -static struct omap_gpio_dev_attr gpio_dev_attr = { - .bank_width = 32, - .dbck_flag = true, -}; - /* gpio1 */ static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { { .role = "dbclk", .clk = "gpio1_dbclk" }, @@ -652,7 +642,6 @@ static struct omap_hwmod omap54xx_gpio1_hwmod = { }, .opt_clks = gpio1_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio2 */ @@ -675,7 +664,6 @@ static struct omap_hwmod omap54xx_gpio2_hwmod = { }, .opt_clks = gpio2_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio3 */ @@ -698,7 +686,6 @@ static struct omap_hwmod omap54xx_gpio3_hwmod = { }, .opt_clks = gpio3_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio4 */ @@ -721,7 +708,6 @@ static struct omap_hwmod omap54xx_gpio4_hwmod = { }, .opt_clks = gpio4_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio5 */ @@ -744,7 +730,6 @@ static struct omap_hwmod omap54xx_gpio5_hwmod = { }, .opt_clks = gpio5_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio6 */ @@ -767,7 +752,6 @@ static struct omap_hwmod omap54xx_gpio6_hwmod = { }, .opt_clks = gpio6_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio7 */ @@ -790,7 +774,6 @@ static struct omap_hwmod omap54xx_gpio7_hwmod = { }, .opt_clks = gpio7_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio7_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio8 */ @@ -813,7 +796,6 @@ static struct omap_hwmod omap54xx_gpio8_hwmod = { }, .opt_clks = gpio8_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio8_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* @@ -839,11 +821,6 @@ static struct omap_hwmod_class omap54xx_i2c_hwmod_class = { .rev = OMAP_I2C_IP_VERSION_2, }; -/* i2c dev_attr */ -static struct omap_i2c_dev_attr i2c_dev_attr = { - .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE, -}; - /* i2c1 */ static struct omap_hwmod omap54xx_i2c1_hwmod = { .name = "i2c1", @@ -858,7 +835,6 @@ static struct omap_hwmod omap54xx_i2c1_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &i2c_dev_attr, }; /* i2c2 */ @@ -875,7 +851,6 @@ static struct omap_hwmod omap54xx_i2c2_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &i2c_dev_attr, }; /* i2c3 */ @@ -892,7 +867,6 @@ static struct omap_hwmod omap54xx_i2c3_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &i2c_dev_attr, }; /* i2c4 */ @@ -909,7 +883,6 @@ static struct omap_hwmod omap54xx_i2c4_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &i2c_dev_attr, }; /* i2c5 */ @@ -926,7 +899,6 @@ static struct omap_hwmod omap54xx_i2c5_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &i2c_dev_attr, }; /* @@ -1012,7 +984,6 @@ static struct omap_hwmod_class_sysconfig omap54xx_mcbsp_sysc = { static struct omap_hwmod_class omap54xx_mcbsp_hwmod_class = { .name = "mcbsp", .sysc = &omap54xx_mcbsp_sysc, - .rev = MCBSP_CONFIG_TYPE4, }; /* mcbsp1 */ @@ -1149,15 +1120,9 @@ static struct omap_hwmod_class_sysconfig omap54xx_mcspi_sysc = { static struct omap_hwmod_class omap54xx_mcspi_hwmod_class = { .name = "mcspi", .sysc = &omap54xx_mcspi_sysc, - .rev = OMAP4_MCSPI_REV, }; /* mcspi1 */ -/* mcspi1 dev_attr */ -static struct omap2_mcspi_dev_attr mcspi1_dev_attr = { - .num_chipselect = 4, -}; - static struct omap_hwmod omap54xx_mcspi1_hwmod = { .name = "mcspi1", .class = &omap54xx_mcspi_hwmod_class, @@ -1170,15 +1135,9 @@ static struct omap_hwmod omap54xx_mcspi1_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &mcspi1_dev_attr, }; /* mcspi2 */ -/* mcspi2 dev_attr */ -static struct omap2_mcspi_dev_attr mcspi2_dev_attr = { - .num_chipselect = 2, -}; - static struct omap_hwmod omap54xx_mcspi2_hwmod = { .name = "mcspi2", .class = &omap54xx_mcspi_hwmod_class, @@ -1191,15 +1150,9 @@ static struct omap_hwmod omap54xx_mcspi2_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &mcspi2_dev_attr, }; /* mcspi3 */ -/* mcspi3 dev_attr */ -static struct omap2_mcspi_dev_attr mcspi3_dev_attr = { - .num_chipselect = 2, -}; - static struct omap_hwmod omap54xx_mcspi3_hwmod = { .name = "mcspi3", .class = &omap54xx_mcspi_hwmod_class, @@ -1212,15 +1165,9 @@ static struct omap_hwmod omap54xx_mcspi3_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &mcspi3_dev_attr, }; /* mcspi4 */ -/* mcspi4 dev_attr */ -static struct omap2_mcspi_dev_attr mcspi4_dev_attr = { - .num_chipselect = 1, -}; - static struct omap_hwmod omap54xx_mcspi4_hwmod = { .name = "mcspi4", .class = &omap54xx_mcspi_hwmod_class, @@ -1233,7 +1180,6 @@ static struct omap_hwmod omap54xx_mcspi4_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &mcspi4_dev_attr, }; /* diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c index 4c2a05b1bd19..62352d1e6361 100644 --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c @@ -18,15 +18,11 @@ */ #include <linux/io.h> -#include <linux/platform_data/gpio-omap.h> #include <linux/platform_data/hsmmc-omap.h> #include <linux/power/smartreflex.h> #include <linux/i2c-omap.h> #include <linux/omap-dma.h> -#include <linux/platform_data/spi-omap2-mcspi.h> -#include <linux/platform_data/asoc-ti-mcbsp.h> -#include <plat/dmtimer.h> #include "omap_hwmod.h" #include "omap_hwmod_common_data.h" @@ -818,12 +814,6 @@ static struct omap_hwmod_class dra7xx_gpio_hwmod_class = { .rev = 2, }; -/* gpio dev_attr */ -static struct omap_gpio_dev_attr gpio_dev_attr = { - .bank_width = 32, - .dbck_flag = true, -}; - /* gpio1 */ static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { { .role = "dbclk", .clk = "gpio1_dbclk" }, @@ -844,7 +834,6 @@ static struct omap_hwmod dra7xx_gpio1_hwmod = { }, .opt_clks = gpio1_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio2 */ @@ -867,7 +856,6 @@ static struct omap_hwmod dra7xx_gpio2_hwmod = { }, .opt_clks = gpio2_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio3 */ @@ -890,7 +878,6 @@ static struct omap_hwmod dra7xx_gpio3_hwmod = { }, .opt_clks = gpio3_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio3_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio4 */ @@ -913,7 +900,6 @@ static struct omap_hwmod dra7xx_gpio4_hwmod = { }, .opt_clks = gpio4_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio4_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio5 */ @@ -936,7 +922,6 @@ static struct omap_hwmod dra7xx_gpio5_hwmod = { }, .opt_clks = gpio5_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio5_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio6 */ @@ -959,7 +944,6 @@ static struct omap_hwmod dra7xx_gpio6_hwmod = { }, .opt_clks = gpio6_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio6_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio7 */ @@ -982,7 +966,6 @@ static struct omap_hwmod dra7xx_gpio7_hwmod = { }, .opt_clks = gpio7_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio7_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* gpio8 */ @@ -1005,7 +988,6 @@ static struct omap_hwmod dra7xx_gpio8_hwmod = { }, .opt_clks = gpio8_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio8_opt_clks), - .dev_attr = &gpio_dev_attr, }; /* @@ -1105,11 +1087,6 @@ static struct omap_hwmod_class dra7xx_i2c_hwmod_class = { .rev = OMAP_I2C_IP_VERSION_2, }; -/* i2c dev_attr */ -static struct omap_i2c_dev_attr i2c_dev_attr = { - .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE, -}; - /* i2c1 */ static struct omap_hwmod dra7xx_i2c1_hwmod = { .name = "i2c1", @@ -1124,7 +1101,6 @@ static struct omap_hwmod dra7xx_i2c1_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &i2c_dev_attr, }; /* i2c2 */ @@ -1141,7 +1117,6 @@ static struct omap_hwmod dra7xx_i2c2_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &i2c_dev_attr, }; /* i2c3 */ @@ -1158,7 +1133,6 @@ static struct omap_hwmod dra7xx_i2c3_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &i2c_dev_attr, }; /* i2c4 */ @@ -1175,7 +1149,6 @@ static struct omap_hwmod dra7xx_i2c4_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &i2c_dev_attr, }; /* i2c5 */ @@ -1192,7 +1165,6 @@ static struct omap_hwmod dra7xx_i2c5_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &i2c_dev_attr, }; /* @@ -1401,15 +1373,9 @@ static struct omap_hwmod_class_sysconfig dra7xx_mcspi_sysc = { static struct omap_hwmod_class dra7xx_mcspi_hwmod_class = { .name = "mcspi", .sysc = &dra7xx_mcspi_sysc, - .rev = OMAP4_MCSPI_REV, }; /* mcspi1 */ -/* mcspi1 dev_attr */ -static struct omap2_mcspi_dev_attr mcspi1_dev_attr = { - .num_chipselect = 4, -}; - static struct omap_hwmod dra7xx_mcspi1_hwmod = { .name = "mcspi1", .class = &dra7xx_mcspi_hwmod_class, @@ -1422,15 +1388,9 @@ static struct omap_hwmod dra7xx_mcspi1_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &mcspi1_dev_attr, }; /* mcspi2 */ -/* mcspi2 dev_attr */ -static struct omap2_mcspi_dev_attr mcspi2_dev_attr = { - .num_chipselect = 2, -}; - static struct omap_hwmod dra7xx_mcspi2_hwmod = { .name = "mcspi2", .class = &dra7xx_mcspi_hwmod_class, @@ -1443,15 +1403,9 @@ static struct omap_hwmod dra7xx_mcspi2_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &mcspi2_dev_attr, }; /* mcspi3 */ -/* mcspi3 dev_attr */ -static struct omap2_mcspi_dev_attr mcspi3_dev_attr = { - .num_chipselect = 2, -}; - static struct omap_hwmod dra7xx_mcspi3_hwmod = { .name = "mcspi3", .class = &dra7xx_mcspi_hwmod_class, @@ -1464,15 +1418,9 @@ static struct omap_hwmod dra7xx_mcspi3_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &mcspi3_dev_attr, }; /* mcspi4 */ -/* mcspi4 dev_attr */ -static struct omap2_mcspi_dev_attr mcspi4_dev_attr = { - .num_chipselect = 1, -}; - static struct omap_hwmod dra7xx_mcspi4_hwmod = { .name = "mcspi4", .class = &dra7xx_mcspi_hwmod_class, @@ -1485,7 +1433,6 @@ static struct omap_hwmod dra7xx_mcspi4_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &mcspi4_dev_attr, }; /* diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c index 84f118280a0e..686655f884c1 100644 --- a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c @@ -15,10 +15,9 @@ * */ -#include <linux/platform_data/gpio-omap.h> +#include <linux/types.h> + #include <linux/platform_data/hsmmc-omap.h> -#include <linux/platform_data/spi-omap2-mcspi.h> -#include <plat/dmtimer.h> #include "omap_hwmod_common_data.h" #include "cm81xx.h" @@ -488,11 +487,6 @@ static struct omap_hwmod_class dm81xx_gpio_hwmod_class = { .rev = 2, }; -static struct omap_gpio_dev_attr gpio_dev_attr = { - .bank_width = 32, - .dbck_flag = true, -}; - static struct omap_hwmod_opt_clk gpio1_opt_clks[] = { { .role = "dbclk", .clk = "sysclk18_ck" }, }; @@ -510,7 +504,6 @@ static struct omap_hwmod dm81xx_gpio1_hwmod = { }, .opt_clks = gpio1_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks), - .dev_attr = &gpio_dev_attr, }; static struct omap_hwmod_ocp_if dm81xx_l4_ls__gpio1 = { @@ -537,7 +530,6 @@ static struct omap_hwmod dm81xx_gpio2_hwmod = { }, .opt_clks = gpio2_opt_clks, .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks), - .dev_attr = &gpio_dev_attr, }; static struct omap_hwmod_ocp_if dm81xx_l4_ls__gpio2 = { @@ -654,15 +646,10 @@ static struct omap_hwmod_class dm816x_timer_hwmod_class = { .sysc = &dm816x_timer_sysc, }; -static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = { - .timer_capability = OMAP_TIMER_ALWON, -}; - static struct omap_hwmod dm814x_timer1_hwmod = { .name = "timer1", .clkdm_name = "alwon_l3s_clkdm", .main_clk = "timer1_fck", - .dev_attr = &capability_alwon_dev_attr, .class = &dm816x_timer_hwmod_class, .flags = HWMOD_NO_IDLEST, }; @@ -684,7 +671,6 @@ static struct omap_hwmod dm816x_timer1_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &dm816x_timer_hwmod_class, }; @@ -699,7 +685,6 @@ static struct omap_hwmod dm814x_timer2_hwmod = { .name = "timer2", .clkdm_name = "alwon_l3s_clkdm", .main_clk = "timer2_fck", - .dev_attr = &capability_alwon_dev_attr, .class = &dm816x_timer_hwmod_class, .flags = HWMOD_NO_IDLEST, }; @@ -721,7 +706,6 @@ static struct omap_hwmod dm816x_timer2_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &dm816x_timer_hwmod_class, }; @@ -742,7 +726,6 @@ static struct omap_hwmod dm816x_timer3_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &dm816x_timer_hwmod_class, }; @@ -763,7 +746,6 @@ static struct omap_hwmod dm816x_timer4_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &dm816x_timer_hwmod_class, }; @@ -784,7 +766,6 @@ static struct omap_hwmod dm816x_timer5_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &dm816x_timer_hwmod_class, }; @@ -805,7 +786,6 @@ static struct omap_hwmod dm816x_timer6_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &dm816x_timer_hwmod_class, }; @@ -826,7 +806,6 @@ static struct omap_hwmod dm816x_timer7_hwmod = { .modulemode = MODULEMODE_SWCTRL, }, }, - .dev_attr = &capability_alwon_dev_attr, .class = &dm816x_timer_hwmod_class, }; @@ -1138,11 +1117,6 @@ static struct omap_hwmod_class_sysconfig dm816x_mcspi_sysc = { static struct omap_hwmod_class dm816x_mcspi_class = { .name = "mcspi", .sysc = &dm816x_mcspi_sysc, - .rev = OMAP3_MCSPI_REV, -}; - -static struct omap2_mcspi_dev_attr dm816x_mcspi1_dev_attr = { - .num_chipselect = 4, }; static struct omap_hwmod dm81xx_mcspi1_hwmod = { @@ -1156,7 +1130,6 @@ static struct omap_hwmod dm81xx_mcspi1_hwmod = { }, }, .class = &dm816x_mcspi_class, - .dev_attr = &dm816x_mcspi1_dev_attr, }; static struct omap_hwmod_ocp_if dm81xx_l4_ls__mcspi1 = { diff --git a/arch/arm/mach-omap2/omap_hwmod_common_data.h b/arch/arm/mach-omap2/omap_hwmod_common_data.h index 29a52df2de26..56dbaca9a728 100644 --- a/arch/arm/mach-omap2/omap_hwmod_common_data.h +++ b/arch/arm/mach-omap2/omap_hwmod_common_data.h @@ -19,7 +19,6 @@ #include "display.h" /* Common IP block data across OMAP2xxx */ -extern struct omap_gpio_dev_attr omap2xxx_gpio_dev_attr; extern struct omap_hwmod omap2xxx_l3_main_hwmod; extern struct omap_hwmod omap2xxx_l4_core_hwmod; extern struct omap_hwmod omap2xxx_l4_wkup_hwmod; diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index 6b433fce65a5..6459816c2879 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -17,17 +17,17 @@ #include <linux/wl12xx.h> #include <linux/mmc/card.h> #include <linux/mmc/host.h> +#include <linux/power/smartreflex.h> #include <linux/regulator/machine.h> #include <linux/regulator/fixed.h> #include <linux/platform_data/pinctrl-single.h> #include <linux/platform_data/hsmmc-omap.h> #include <linux/platform_data/iommu-omap.h> +#include <linux/platform_data/ti-sysc.h> #include <linux/platform_data/wkup_m3.h> -#include <linux/platform_data/pwm_omap_dmtimer.h> #include <linux/platform_data/media/ir-rx51.h> #include <linux/platform_data/asoc-ti-mcbsp.h> -#include <plat/dmtimer.h> #include "common.h" #include "common-board-devices.h" @@ -454,6 +454,43 @@ static void __init dra7x_evm_mmc_quirk(void) } #endif +static int ti_sysc_enable_module(struct device *dev, + const struct ti_sysc_cookie *cookie) +{ + if (!cookie->data) + return -EINVAL; + + return omap_hwmod_enable(cookie->data); +} + +static int ti_sysc_idle_module(struct device *dev, + const struct ti_sysc_cookie *cookie) +{ + if (!cookie->data) + return -EINVAL; + + return omap_hwmod_idle(cookie->data); +} + +static int ti_sysc_shutdown_module(struct device *dev, + const struct ti_sysc_cookie *cookie) +{ + if (!cookie->data) + return -EINVAL; + + return omap_hwmod_shutdown(cookie->data); +} + +static struct of_dev_auxdata omap_auxdata_lookup[]; + +static struct ti_sysc_platform_data ti_sysc_pdata = { + .auxdata = omap_auxdata_lookup, + .init_module = omap_hwmod_init_module, + .enable_module = ti_sysc_enable_module, + .idle_module = ti_sysc_idle_module, + .shutdown_module = ti_sysc_shutdown_module, +}; + static struct pcs_pdata pcs_pdata; void omap_pcs_legacy_init(int irq, void (*rearm)(void)) @@ -477,33 +514,6 @@ void omap_auxdata_legacy_init(struct device *dev) dev->platform_data = &twl_gpio_auxdata; } -/* Dual mode timer PWM callbacks platdata */ -#if IS_ENABLED(CONFIG_OMAP_DM_TIMER) -static struct pwm_omap_dmtimer_pdata pwm_dmtimer_pdata = { - .request_by_node = omap_dm_timer_request_by_node, - .request_specific = omap_dm_timer_request_specific, - .request = omap_dm_timer_request, - .set_source = omap_dm_timer_set_source, - .get_irq = omap_dm_timer_get_irq, - .set_int_enable = omap_dm_timer_set_int_enable, - .set_int_disable = omap_dm_timer_set_int_disable, - .free = omap_dm_timer_free, - .enable = omap_dm_timer_enable, - .disable = omap_dm_timer_disable, - .get_fclk = omap_dm_timer_get_fclk, - .start = omap_dm_timer_start, - .stop = omap_dm_timer_stop, - .set_load = omap_dm_timer_set_load, - .set_match = omap_dm_timer_set_match, - .set_pwm = omap_dm_timer_set_pwm, - .set_prescaler = omap_dm_timer_set_prescaler, - .read_counter = omap_dm_timer_read_counter, - .write_counter = omap_dm_timer_write_counter, - .read_status = omap_dm_timer_read_status, - .write_status = omap_dm_timer_write_status, -}; -#endif - static struct ir_rx51_platform_data __maybe_unused rx51_ir_data = { .set_max_mpu_wakeup_lat = omap_pm_set_max_mpu_wakeup_lat, }; @@ -542,7 +552,9 @@ static struct pdata_init auxdata_quirks[] __initdata = { { /* sentinel */ }, }; -static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { +struct omap_sr_data __maybe_unused omap_sr_pdata[OMAP_SR_NR]; + +static struct of_dev_auxdata omap_auxdata_lookup[] = { #ifdef CONFIG_MACH_NOKIA_N8X0 OF_DEV_AUXDATA("ti,omap2420-mmc", 0x4809c000, "mmci-omap.0", NULL), OF_DEV_AUXDATA("menelaus", 0x72, "1-0072", &n8x0_menelaus_platform_data), @@ -551,6 +563,10 @@ static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { #ifdef CONFIG_ARCH_OMAP3 OF_DEV_AUXDATA("ti,omap2-iommu", 0x5d000000, "5d000000.mmu", &omap3_iommu_pdata), + OF_DEV_AUXDATA("ti,omap3-smartreflex-core", 0x480cb000, + "480cb000.smartreflex", &omap_sr_pdata[OMAP_SR_CORE]), + OF_DEV_AUXDATA("ti,omap3-smartreflex-mpu-iva", 0x480c9000, + "480c9000.smartreflex", &omap_sr_pdata[OMAP_SR_MPU]), OF_DEV_AUXDATA("ti,omap3-hsmmc", 0x4809c000, "4809c000.mmc", &mmc_pdata[0]), OF_DEV_AUXDATA("ti,omap3-hsmmc", 0x480b4000, "480b4000.mmc", &mmc_pdata[1]), OF_DEV_AUXDATA("nokia,n900-ir", 0, "n900-ir", &rx51_ir_data), @@ -572,14 +588,17 @@ static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("ti,am4372-wkup-m3", 0x44d00000, "44d00000.wkup_m3", &wkup_m3_data), #endif -#if IS_ENABLED(CONFIG_OMAP_DM_TIMER) - OF_DEV_AUXDATA("ti,omap-dmtimer-pwm", 0, NULL, &pwm_dmtimer_pdata), -#endif #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) OF_DEV_AUXDATA("ti,omap4-iommu", 0x4a066000, "4a066000.mmu", &omap4_iommu_pdata), OF_DEV_AUXDATA("ti,omap4-iommu", 0x55082000, "55082000.mmu", &omap4_iommu_pdata), + OF_DEV_AUXDATA("ti,omap4-smartreflex-iva", 0x4a0db000, + "4a0db000.smartreflex", &omap_sr_pdata[OMAP_SR_IVA]), + OF_DEV_AUXDATA("ti,omap4-smartreflex-core", 0x4a0dd000, + "4a0dd000.smartreflex", &omap_sr_pdata[OMAP_SR_CORE]), + OF_DEV_AUXDATA("ti,omap4-smartreflex-mpu", 0x4a0d9000, + "4a0d9000.smartreflex", &omap_sr_pdata[OMAP_SR_MPU]), #endif #ifdef CONFIG_SOC_DRA7XX OF_DEV_AUXDATA("ti,dra7-hsmmc", 0x4809c000, "4809c000.mmc", @@ -590,6 +609,7 @@ static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { &dra7_hsmmc_data_mmc3), #endif /* Common auxdata */ + OF_DEV_AUXDATA("ti,sysc", 0, NULL, &ti_sysc_pdata), OF_DEV_AUXDATA("pinctrl-single", 0, NULL, &pcs_pdata), { /* sentinel */ }, }; diff --git a/arch/arm/mach-omap2/pm-asm-offsets.c b/arch/arm/mach-omap2/pm-asm-offsets.c new file mode 100644 index 000000000000..6d4392da7c11 --- /dev/null +++ b/arch/arm/mach-omap2/pm-asm-offsets.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * TI AM33XX and AM43XX PM Assembly Offsets + * + * Copyright (C) 2017-2018 Texas Instruments Inc. + */ + +#include <linux/kbuild.h> +#include <linux/platform_data/pm33xx.h> + +int main(void) +{ + DEFINE(AMX3_PM_WFI_FLAGS_OFFSET, + offsetof(struct am33xx_pm_sram_data, wfi_flags)); + DEFINE(AMX3_PM_L2_AUX_CTRL_VAL_OFFSET, + offsetof(struct am33xx_pm_sram_data, l2_aux_ctrl_val)); + DEFINE(AMX3_PM_L2_PREFETCH_CTRL_VAL_OFFSET, + offsetof(struct am33xx_pm_sram_data, l2_prefetch_ctrl_val)); + DEFINE(AMX3_PM_SRAM_DATA_SIZE, sizeof(struct am33xx_pm_sram_data)); + + BLANK(); + + DEFINE(AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET, + offsetof(struct am33xx_pm_ro_sram_data, amx3_pm_sram_data_virt)); + DEFINE(AMX3_PM_RO_SRAM_DATA_PHYS_OFFSET, + offsetof(struct am33xx_pm_ro_sram_data, amx3_pm_sram_data_phys)); + DEFINE(AMX3_PM_RO_SRAM_DATA_SIZE, + sizeof(struct am33xx_pm_ro_sram_data)); + + return 0; +} diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 8e30772cfe32..c73776b82348 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -81,6 +81,9 @@ extern unsigned int omap3_do_wfi_sz; /* ... and its pointer from SRAM after copy */ extern void (*omap3_do_wfi_sram)(void); +extern struct am33xx_pm_sram_addr am33xx_pm_sram; +extern struct am33xx_pm_sram_addr am43xx_pm_sram; + extern void omap3_save_scratchpad_contents(void); #define PM_RTA_ERRATUM_i608 (1 << 0) diff --git a/arch/arm/mach-omap2/pm33xx-core.c b/arch/arm/mach-omap2/pm33xx-core.c new file mode 100644 index 000000000000..93c0b5ba9f09 --- /dev/null +++ b/arch/arm/mach-omap2/pm33xx-core.c @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AM33XX Arch Power Management Routines + * + * Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/ + * Dave Gerlach + */ + +#include <asm/smp_scu.h> +#include <asm/suspend.h> +#include <linux/errno.h> +#include <linux/platform_data/pm33xx.h> + +#include "cm33xx.h" +#include "common.h" +#include "control.h" +#include "clockdomain.h" +#include "iomap.h" +#include "omap_hwmod.h" +#include "pm.h" +#include "powerdomain.h" +#include "prm33xx.h" +#include "soc.h" +#include "sram.h" + +static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm, *mpu_pwrdm; +static struct clockdomain *gfx_l4ls_clkdm; +static void __iomem *scu_base; + +static int __init am43xx_map_scu(void) +{ + scu_base = ioremap(scu_a9_get_base(), SZ_256); + + if (!scu_base) + return -ENOMEM; + + return 0; +} + +static int amx3_common_init(void) +{ + gfx_pwrdm = pwrdm_lookup("gfx_pwrdm"); + per_pwrdm = pwrdm_lookup("per_pwrdm"); + mpu_pwrdm = pwrdm_lookup("mpu_pwrdm"); + + if ((!gfx_pwrdm) || (!per_pwrdm) || (!mpu_pwrdm)) + return -ENODEV; + + (void)clkdm_for_each(omap_pm_clkdms_setup, NULL); + + /* CEFUSE domain can be turned off post bootup */ + cefuse_pwrdm = pwrdm_lookup("cefuse_pwrdm"); + if (cefuse_pwrdm) + omap_set_pwrdm_state(cefuse_pwrdm, PWRDM_POWER_OFF); + else + pr_err("PM: Failed to get cefuse_pwrdm\n"); + + return 0; +} + +static int am33xx_suspend_init(void) +{ + int ret; + + gfx_l4ls_clkdm = clkdm_lookup("gfx_l4ls_gfx_clkdm"); + + if (!gfx_l4ls_clkdm) { + pr_err("PM: Cannot lookup gfx_l4ls_clkdm clockdomains\n"); + return -ENODEV; + } + + ret = amx3_common_init(); + + return ret; +} + +static int am43xx_suspend_init(void) +{ + int ret = 0; + + ret = am43xx_map_scu(); + if (ret) { + pr_err("PM: Could not ioremap SCU\n"); + return ret; + } + + ret = amx3_common_init(); + + return ret; +} + +static void amx3_pre_suspend_common(void) +{ + omap_set_pwrdm_state(gfx_pwrdm, PWRDM_POWER_OFF); +} + +static void amx3_post_suspend_common(void) +{ + int status; + /* + * Because gfx_pwrdm is the only one under MPU control, + * comment on transition status + */ + status = pwrdm_read_pwrst(gfx_pwrdm); + if (status != PWRDM_POWER_OFF) + pr_err("PM: GFX domain did not transition: %x\n", status); +} + +static int am33xx_suspend(unsigned int state, int (*fn)(unsigned long)) +{ + int ret = 0; + + amx3_pre_suspend_common(); + ret = cpu_suspend(0, fn); + amx3_post_suspend_common(); + + /* + * BUG: GFX_L4LS clock domain needs to be woken up to + * ensure thet L4LS clock domain does not get stuck in + * transition. If that happens L3 module does not get + * disabled, thereby leading to PER power domain + * transition failing + */ + + clkdm_wakeup(gfx_l4ls_clkdm); + clkdm_sleep(gfx_l4ls_clkdm); + + return ret; +} + +static int am43xx_suspend(unsigned int state, int (*fn)(unsigned long)) +{ + int ret = 0; + + amx3_pre_suspend_common(); + scu_power_mode(scu_base, SCU_PM_POWEROFF); + ret = cpu_suspend(0, fn); + scu_power_mode(scu_base, SCU_PM_NORMAL); + amx3_post_suspend_common(); + + return ret; +} + +static struct am33xx_pm_sram_addr *amx3_get_sram_addrs(void) +{ + if (soc_is_am33xx()) + return &am33xx_pm_sram; + else if (soc_is_am437x()) + return &am43xx_pm_sram; + else + return NULL; +} + +static struct am33xx_pm_platform_data am33xx_ops = { + .init = am33xx_suspend_init, + .soc_suspend = am33xx_suspend, + .get_sram_addrs = amx3_get_sram_addrs, +}; + +static struct am33xx_pm_platform_data am43xx_ops = { + .init = am43xx_suspend_init, + .soc_suspend = am43xx_suspend, + .get_sram_addrs = amx3_get_sram_addrs, +}; + +static struct am33xx_pm_platform_data *am33xx_pm_get_pdata(void) +{ + if (soc_is_am33xx()) + return &am33xx_ops; + else if (soc_is_am437x()) + return &am43xx_ops; + else + return NULL; +} + +void __init amx3_common_pm_init(void) +{ + struct am33xx_pm_platform_data *pdata; + struct platform_device_info devinfo; + + pdata = am33xx_pm_get_pdata(); + + memset(&devinfo, 0, sizeof(devinfo)); + devinfo.name = "pm33xx"; + devinfo.data = pdata; + devinfo.size_data = sizeof(*pdata); + devinfo.id = -1; + platform_device_register_full(&devinfo); +} diff --git a/arch/arm/mach-omap2/sleep33xx.S b/arch/arm/mach-omap2/sleep33xx.S new file mode 100644 index 000000000000..218d79930b04 --- /dev/null +++ b/arch/arm/mach-omap2/sleep33xx.S @@ -0,0 +1,214 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Low level suspend code for AM33XX SoCs + * + * Copyright (C) 2012-2018 Texas Instruments Incorporated - http://www.ti.com/ + * Dave Gerlach, Vaibhav Bedia + */ + +#include <generated/ti-emif-asm-offsets.h> +#include <generated/ti-pm-asm-offsets.h> +#include <linux/linkage.h> +#include <linux/ti-emif-sram.h> +#include <asm/assembler.h> +#include <asm/memory.h> + +#include "iomap.h" +#include "cm33xx.h" + +#define AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED 0x00030000 +#define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE 0x0003 +#define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE 0x0002 + + .arm + .align 3 + +ENTRY(am33xx_do_wfi) + stmfd sp!, {r4 - r11, lr} @ save registers on stack + + /* + * Flush all data from the L1 and L2 data cache before disabling + * SCTLR.C bit. + */ + ldr r1, kernel_flush + blx r1 + + /* + * Clear the SCTLR.C bit to prevent further data cache + * allocation. Clearing SCTLR.C would make all the data accesses + * strongly ordered and would not hit the cache. + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #(1 << 2) @ Disable the C bit + mcr p15, 0, r0, c1, c0, 0 + isb + + /* + * Invalidate L1 and L2 data cache. + */ + ldr r1, kernel_flush + blx r1 + + adr r9, am33xx_emif_sram_table + + ldr r3, [r9, #EMIF_PM_ENTER_SR_OFFSET] + blx r3 + + ldr r3, [r9, #EMIF_PM_SAVE_CONTEXT_OFFSET] + blx r3 + + /* Disable EMIF */ + ldr r1, virt_emif_clkctrl + ldr r2, [r1] + bic r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE + str r2, [r1] + + ldr r1, virt_emif_clkctrl +wait_emif_disable: + ldr r2, [r1] + mov r3, #AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED + cmp r2, r3 + bne wait_emif_disable + + /* + * For the MPU WFI to be registered as an interrupt + * to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set + * to DISABLED + */ + ldr r1, virt_mpu_clkctrl + ldr r2, [r1] + bic r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE + str r2, [r1] + + /* + * Execute an ISB instruction to ensure that all of the + * CP15 register changes have been committed. + */ + isb + + /* + * Execute a barrier instruction to ensure that all cache, + * TLB and branch predictor maintenance operations issued + * have completed. + */ + dsb + dmb + + /* + * Execute a WFI instruction and wait until the + * STANDBYWFI output is asserted to indicate that the + * CPU is in idle and low power state. CPU can specualatively + * prefetch the instructions so add NOPs after WFI. Thirteen + * NOPs as per Cortex-A8 pipeline. + */ + wfi + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + /* We come here in case of an abort due to a late interrupt */ + + /* Set MPU_CLKCTRL.MODULEMODE back to ENABLE */ + ldr r1, virt_mpu_clkctrl + mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE + str r2, [r1] + + /* Re-enable EMIF */ + ldr r1, virt_emif_clkctrl + mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE + str r2, [r1] +wait_emif_enable: + ldr r3, [r1] + cmp r2, r3 + bne wait_emif_enable + + + ldr r1, [r9, #EMIF_PM_ABORT_SR_OFFSET] + blx r1 + + /* + * Set SCTLR.C bit to allow data cache allocation + */ + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #(1 << 2) @ Enable the C bit + mcr p15, 0, r0, c1, c0, 0 + isb + + /* Let the suspend code know about the abort */ + mov r0, #1 + ldmfd sp!, {r4 - r11, pc} @ restore regs and return +ENDPROC(am33xx_do_wfi) + + .align +ENTRY(am33xx_resume_offset) + .word . - am33xx_do_wfi + +ENTRY(am33xx_resume_from_deep_sleep) + /* Re-enable EMIF */ + ldr r0, phys_emif_clkctrl + mov r1, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE + str r1, [r0] +wait_emif_enable1: + ldr r2, [r0] + cmp r1, r2 + bne wait_emif_enable1 + + adr r9, am33xx_emif_sram_table + + ldr r1, [r9, #EMIF_PM_RESTORE_CONTEXT_OFFSET] + blx r1 + + ldr r1, [r9, #EMIF_PM_EXIT_SR_OFFSET] + blx r1 + +resume_to_ddr: + /* We are back. Branch to the common CPU resume routine */ + mov r0, #0 + ldr pc, resume_addr +ENDPROC(am33xx_resume_from_deep_sleep) + +/* + * Local variables + */ + .align +resume_addr: + .word cpu_resume - PAGE_OFFSET + 0x80000000 +kernel_flush: + .word v7_flush_dcache_all +virt_mpu_clkctrl: + .word AM33XX_CM_MPU_MPU_CLKCTRL +virt_emif_clkctrl: + .word AM33XX_CM_PER_EMIF_CLKCTRL +phys_emif_clkctrl: + .word (AM33XX_CM_BASE + AM33XX_CM_PER_MOD + \ + AM33XX_CM_PER_EMIF_CLKCTRL_OFFSET) + +.align 3 +/* DDR related defines */ +am33xx_emif_sram_table: + .space EMIF_PM_FUNCTIONS_SIZE + +ENTRY(am33xx_pm_sram) + .word am33xx_do_wfi + .word am33xx_do_wfi_sz + .word am33xx_resume_offset + .word am33xx_emif_sram_table + .word am33xx_pm_ro_sram_data + +.align 3 +ENTRY(am33xx_pm_ro_sram_data) + .space AMX3_PM_RO_SRAM_DATA_SIZE + +ENTRY(am33xx_do_wfi_sz) + .word . - am33xx_do_wfi diff --git a/arch/arm/mach-omap2/sleep43xx.S b/arch/arm/mach-omap2/sleep43xx.S new file mode 100644 index 000000000000..b24be624e8b9 --- /dev/null +++ b/arch/arm/mach-omap2/sleep43xx.S @@ -0,0 +1,391 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Low level suspend code for AM43XX SoCs + * + * Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/ + * Dave Gerlach, Vaibhav Bedia + */ + +#include <generated/ti-emif-asm-offsets.h> +#include <generated/ti-pm-asm-offsets.h> +#include <linux/linkage.h> +#include <linux/ti-emif-sram.h> + +#include <asm/assembler.h> +#include <asm/hardware/cache-l2x0.h> +#include <asm/memory.h> + +#include "cm33xx.h" +#include "common.h" +#include "iomap.h" +#include "omap-secure.h" +#include "omap44xx.h" +#include "prm33xx.h" +#include "prcm43xx.h" + +#define AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED 0x00030000 +#define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE 0x0003 +#define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE 0x0002 + +#define AM43XX_EMIF_POWEROFF_ENABLE 0x1 +#define AM43XX_EMIF_POWEROFF_DISABLE 0x0 + +#define AM43XX_CM_CLKSTCTRL_CLKTRCTRL_SW_SLEEP 0x1 +#define AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO 0x3 + +#define AM43XX_CM_BASE 0x44DF0000 + +#define AM43XX_CM_REGADDR(inst, reg) \ + AM33XX_L4_WK_IO_ADDRESS(AM43XX_CM_BASE + (inst) + (reg)) + +#define AM43XX_CM_MPU_CLKSTCTRL AM43XX_CM_REGADDR(AM43XX_CM_MPU_INST, \ + AM43XX_CM_MPU_MPU_CDOFFS) +#define AM43XX_CM_MPU_MPU_CLKCTRL AM43XX_CM_REGADDR(AM43XX_CM_MPU_INST, \ + AM43XX_CM_MPU_MPU_CLKCTRL_OFFSET) +#define AM43XX_CM_PER_EMIF_CLKCTRL AM43XX_CM_REGADDR(AM43XX_CM_PER_INST, \ + AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET) +#define AM43XX_PRM_EMIF_CTRL_OFFSET 0x0030 + + .arm + .align 3 + +ENTRY(am43xx_do_wfi) + stmfd sp!, {r4 - r11, lr} @ save registers on stack + +#ifdef CONFIG_CACHE_L2X0 + /* Retrieve l2 cache virt address BEFORE we shut off EMIF */ + ldr r1, get_l2cache_base + blx r1 + mov r8, r0 +#endif + + /* + * Flush all data from the L1 and L2 data cache before disabling + * SCTLR.C bit. + */ + ldr r1, kernel_flush + blx r1 + + /* + * Clear the SCTLR.C bit to prevent further data cache + * allocation. Clearing SCTLR.C would make all the data accesses + * strongly ordered and would not hit the cache. + */ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #(1 << 2) @ Disable the C bit + mcr p15, 0, r0, c1, c0, 0 + isb + dsb + + /* + * Invalidate L1 and L2 data cache. + */ + ldr r1, kernel_flush + blx r1 + +#ifdef CONFIG_CACHE_L2X0 + /* + * Clean and invalidate the L2 cache. + */ +#ifdef CONFIG_PL310_ERRATA_727915 + mov r0, #0x03 + mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX + dsb + smc #0 + dsb +#endif + mov r0, r8 + adr r4, am43xx_pm_ro_sram_data + ldr r3, [r4, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET] + + mov r2, r0 + ldr r0, [r2, #L2X0_AUX_CTRL] + str r0, [r3, #AMX3_PM_L2_AUX_CTRL_VAL_OFFSET] + ldr r0, [r2, #L310_PREFETCH_CTRL] + str r0, [r3, #AMX3_PM_L2_PREFETCH_CTRL_VAL_OFFSET] + + ldr r0, l2_val + str r0, [r2, #L2X0_CLEAN_INV_WAY] +wait: + ldr r0, [r2, #L2X0_CLEAN_INV_WAY] + ldr r1, l2_val + ands r0, r0, r1 + bne wait +#ifdef CONFIG_PL310_ERRATA_727915 + mov r0, #0x00 + mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX + dsb + smc #0 + dsb +#endif +l2x_sync: + mov r0, r8 + mov r2, r0 + mov r0, #0x0 + str r0, [r2, #L2X0_CACHE_SYNC] +sync: + ldr r0, [r2, #L2X0_CACHE_SYNC] + ands r0, r0, #0x1 + bne sync +#endif + + adr r9, am43xx_emif_sram_table + + ldr r3, [r9, #EMIF_PM_ENTER_SR_OFFSET] + blx r3 + + ldr r3, [r9, #EMIF_PM_SAVE_CONTEXT_OFFSET] + blx r3 + + /* Disable EMIF */ + ldr r1, am43xx_virt_emif_clkctrl + ldr r2, [r1] + bic r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE + str r2, [r1] + +wait_emif_disable: + ldr r2, [r1] + mov r3, #AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED + cmp r2, r3 + bne wait_emif_disable + + /* + * For the MPU WFI to be registered as an interrupt + * to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set + * to DISABLED + */ + ldr r1, am43xx_virt_mpu_clkctrl + ldr r2, [r1] + bic r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE + str r2, [r1] + + /* + * Put MPU CLKDM to SW_SLEEP + */ + ldr r1, am43xx_virt_mpu_clkstctrl + mov r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_SW_SLEEP + str r2, [r1] + + /* + * Execute a barrier instruction to ensure that all cache, + * TLB and branch predictor maintenance operations issued + * have completed. + */ + dsb + dmb + + /* + * Execute a WFI instruction and wait until the + * STANDBYWFI output is asserted to indicate that the + * CPU is in idle and low power state. CPU can specualatively + * prefetch the instructions so add NOPs after WFI. Sixteen + * NOPs as per Cortex-A9 pipeline. + */ + wfi + + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + + /* We come here in case of an abort due to a late interrupt */ + ldr r1, am43xx_virt_mpu_clkstctrl + mov r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO + str r2, [r1] + + /* Set MPU_CLKCTRL.MODULEMODE back to ENABLE */ + ldr r1, am43xx_virt_mpu_clkctrl + mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE + str r2, [r1] + + /* Re-enable EMIF */ + ldr r1, am43xx_virt_emif_clkctrl + mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE + str r2, [r1] +wait_emif_enable: + ldr r3, [r1] + cmp r2, r3 + bne wait_emif_enable + + /* + * Set SCTLR.C bit to allow data cache allocation + */ + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #(1 << 2) @ Enable the C bit + mcr p15, 0, r0, c1, c0, 0 + isb + + ldr r1, [r9, #EMIF_PM_ABORT_SR_OFFSET] + blx r1 + + /* Let the suspend code know about the abort */ + mov r0, #1 + ldmfd sp!, {r4 - r11, pc} @ restore regs and return +ENDPROC(am43xx_do_wfi) + + .align +ENTRY(am43xx_resume_offset) + .word . - am43xx_do_wfi + +ENTRY(am43xx_resume_from_deep_sleep) + /* Set MPU CLKSTCTRL to HW AUTO so that CPUidle works properly */ + ldr r1, am43xx_virt_mpu_clkstctrl + mov r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO + str r2, [r1] + + /* For AM43xx, use EMIF power down until context is restored */ + ldr r2, am43xx_phys_emif_poweroff + mov r1, #AM43XX_EMIF_POWEROFF_ENABLE + str r1, [r2, #0x0] + + /* Re-enable EMIF */ + ldr r1, am43xx_phys_emif_clkctrl + mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE + str r2, [r1] +wait_emif_enable1: + ldr r3, [r1] + cmp r2, r3 + bne wait_emif_enable1 + + adr r9, am43xx_emif_sram_table + + ldr r1, [r9, #EMIF_PM_RESTORE_CONTEXT_OFFSET] + blx r1 + + ldr r1, [r9, #EMIF_PM_EXIT_SR_OFFSET] + blx r1 + + ldr r2, am43xx_phys_emif_poweroff + mov r1, #AM43XX_EMIF_POWEROFF_DISABLE + str r1, [r2, #0x0] + +#ifdef CONFIG_CACHE_L2X0 + ldr r2, l2_cache_base + ldr r0, [r2, #L2X0_CTRL] + and r0, #0x0f + cmp r0, #1 + beq skip_l2en @ Skip if already enabled + + adr r4, am43xx_pm_ro_sram_data + ldr r3, [r4, #AMX3_PM_RO_SRAM_DATA_PHYS_OFFSET] + ldr r0, [r3, #AMX3_PM_L2_PREFETCH_CTRL_VAL_OFFSET] + + ldr r12, l2_smc1 + dsb + smc #0 + dsb +set_aux_ctrl: + ldr r0, [r3, #AMX3_PM_L2_AUX_CTRL_VAL_OFFSET] + ldr r12, l2_smc2 + dsb + smc #0 + dsb + + /* L2 invalidate on resume */ + ldr r0, l2_val + ldr r2, l2_cache_base + str r0, [r2, #L2X0_INV_WAY] +wait2: + ldr r0, [r2, #L2X0_INV_WAY] + ldr r1, l2_val + ands r0, r0, r1 + bne wait2 +#ifdef CONFIG_PL310_ERRATA_727915 + mov r0, #0x00 + mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX + dsb + smc #0 + dsb +#endif +l2x_sync2: + ldr r2, l2_cache_base + mov r0, #0x0 + str r0, [r2, #L2X0_CACHE_SYNC] +sync2: + ldr r0, [r2, #L2X0_CACHE_SYNC] + ands r0, r0, #0x1 + bne sync2 + + mov r0, #0x1 + ldr r12, l2_smc3 + dsb + smc #0 + dsb +#endif +skip_l2en: + /* We are back. Branch to the common CPU resume routine */ + mov r0, #0 + ldr pc, resume_addr +ENDPROC(am43xx_resume_from_deep_sleep) + +/* + * Local variables + */ + .align +resume_addr: + .word cpu_resume - PAGE_OFFSET + 0x80000000 +kernel_flush: + .word v7_flush_dcache_all +ddr_start: + .word PAGE_OFFSET + +am43xx_phys_emif_poweroff: + .word (AM43XX_CM_BASE + AM43XX_PRM_DEVICE_INST + \ + AM43XX_PRM_EMIF_CTRL_OFFSET) +am43xx_virt_mpu_clkstctrl: + .word (AM43XX_CM_MPU_CLKSTCTRL) +am43xx_virt_mpu_clkctrl: + .word (AM43XX_CM_MPU_MPU_CLKCTRL) +am43xx_virt_emif_clkctrl: + .word (AM43XX_CM_PER_EMIF_CLKCTRL) +am43xx_phys_emif_clkctrl: + .word (AM43XX_CM_BASE + AM43XX_CM_PER_INST + \ + AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET) + +#ifdef CONFIG_CACHE_L2X0 +/* L2 cache related defines for AM437x */ +get_l2cache_base: + .word omap4_get_l2cache_base +l2_cache_base: + .word OMAP44XX_L2CACHE_BASE +l2_smc1: + .word OMAP4_MON_L2X0_PREFETCH_INDEX +l2_smc2: + .word OMAP4_MON_L2X0_AUXCTRL_INDEX +l2_smc3: + .word OMAP4_MON_L2X0_CTRL_INDEX +l2_val: + .word 0xffff +#endif + +.align 3 +/* DDR related defines */ +ENTRY(am43xx_emif_sram_table) + .space EMIF_PM_FUNCTIONS_SIZE + +ENTRY(am43xx_pm_sram) + .word am43xx_do_wfi + .word am43xx_do_wfi_sz + .word am43xx_resume_offset + .word am43xx_emif_sram_table + .word am43xx_pm_ro_sram_data + +.align 3 + +ENTRY(am43xx_pm_ro_sram_data) + .space AMX3_PM_RO_SRAM_DATA_SIZE + +ENTRY(am43xx_do_wfi_sz) + .word . - am43xx_do_wfi diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S index 56dfa2d5d0a8..0cae3b070208 100644 --- a/arch/arm/mach-omap2/sleep44xx.S +++ b/arch/arm/mach-omap2/sleep44xx.S @@ -90,12 +90,7 @@ skip_secure_l1_clean: mcr p15, 0, r0, c1, c0, 0 isb - /* - * Invalidate L1 data cache. Even though only invalidate is - * necessary exported flush API is used here. Doing clean - * on already clean cache would be almost NOP. - */ - bl v7_flush_dcache_all + bl v7_invalidate_l1 /* * Switch the CPU from Symmetric Multiprocessing (SMP) mode diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index eef6935e0403..0854ed9ff379 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c @@ -89,18 +89,27 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data, sr_data->nvalue_count = j; } +extern struct omap_sr_data omap_sr_pdata[]; + static int __init sr_dev_init(struct omap_hwmod *oh, void *user) { - struct omap_sr_data *sr_data; - struct platform_device *pdev; + struct omap_sr_data *sr_data = NULL; struct omap_volt_data *volt_data; struct omap_smartreflex_dev_attr *sr_dev_attr; - char *name = "smartreflex"; static int i; - sr_data = kzalloc(sizeof(*sr_data), GFP_KERNEL); - if (!sr_data) - return -ENOMEM; + if (!strncmp(oh->name, "smartreflex_mpu_iva", 20) || + !strncmp(oh->name, "smartreflex_mpu", 16)) + sr_data = &omap_sr_pdata[OMAP_SR_MPU]; + else if (!strncmp(oh->name, "smartreflex_core", 17)) + sr_data = &omap_sr_pdata[OMAP_SR_CORE]; + else if (!strncmp(oh->name, "smartreflex_iva", 16)) + sr_data = &omap_sr_pdata[OMAP_SR_IVA]; + + if (!sr_data) { + pr_err("%s: Unknown instance %s\n", __func__, oh->name); + return -EINVAL; + } sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr; if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) { @@ -145,13 +154,9 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user) sr_data->enable_on_init = sr_enable_on_init; - pdev = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data)); - if (IS_ERR(pdev)) - pr_warn("%s: Could not build omap_device for %s: %s\n", - __func__, name, oh->name); exit: i++; - kfree(sr_data); + return 0; } diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index d61fbd7a2840..4fb4dc24e5e9 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -49,7 +49,7 @@ #include "omap_hwmod.h" #include "omap_device.h" #include <plat/counter-32k.h> -#include <plat/dmtimer.h> +#include <clocksource/timer-ti-dm.h> #include "omap-pm.h" #include "soc.h" diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index 69d7f48a4183..c5c0ab8ac9f9 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -404,7 +404,7 @@ static void __init cm_x300_init_ac97(void) static inline void cm_x300_init_ac97(void) {} #endif -#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE) +#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL) static struct mtd_partition cm_x300_nand_partitions[] = { [0] = { .name = "OBM", @@ -442,11 +442,9 @@ static struct mtd_partition cm_x300_nand_partitions[] = { }; static struct pxa3xx_nand_platform_data cm_x300_nand_info = { - .enable_arbiter = 1, .keep_config = 1, - .num_cs = 1, - .parts[0] = cm_x300_nand_partitions, - .nr_parts[0] = ARRAY_SIZE(cm_x300_nand_partitions), + .parts = cm_x300_nand_partitions, + .nr_parts = ARRAY_SIZE(cm_x300_nand_partitions), }; static void __init cm_x300_init_nand(void) @@ -522,7 +520,7 @@ static int cm_x300_ulpi_phy_reset(void) return 0; } -static inline int cm_x300_u2d_init(struct device *dev) +static int cm_x300_u2d_init(struct device *dev) { int err = 0; @@ -534,7 +532,7 @@ static inline int cm_x300_u2d_init(struct device *dev) pr_err("failed to get CLK_POUT: %d\n", err); return err; } - clk_enable(pout_clk); + clk_prepare_enable(pout_clk); err = cm_x300_ulpi_phy_reset(); if (err) { @@ -549,7 +547,7 @@ static inline int cm_x300_u2d_init(struct device *dev) static void cm_x300_u2d_exit(struct device *dev) { if (cpu_is_pxa310()) { - clk_disable(pout_clk); + clk_disable_unprepare(pout_clk); clk_put(pout_clk); } } diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c index b04431bb4ba7..e31a591e949f 100644 --- a/arch/arm/mach-pxa/colibri-pxa3xx.c +++ b/arch/arm/mach-pxa/colibri-pxa3xx.c @@ -110,7 +110,7 @@ void __init colibri_pxa3xx_init_lcd(int bl_pin) } #endif -#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE) +#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL) static struct mtd_partition colibri_nand_partitions[] = { { .name = "bootloader", @@ -138,11 +138,9 @@ static struct mtd_partition colibri_nand_partitions[] = { }; static struct pxa3xx_nand_platform_data colibri_nand_info = { - .enable_arbiter = 1, .keep_config = 1, - .num_cs = 1, - .parts[0] = colibri_nand_partitions, - .nr_parts[0] = ARRAY_SIZE(colibri_nand_partitions), + .parts = colibri_nand_partitions, + .nr_parts = ARRAY_SIZE(colibri_nand_partitions), }; void __init colibri_pxa3xx_init_nand(void) diff --git a/arch/arm/mach-pxa/colibri.h b/arch/arm/mach-pxa/colibri.h index 673a131da875..85525d49e321 100644 --- a/arch/arm/mach-pxa/colibri.h +++ b/arch/arm/mach-pxa/colibri.h @@ -46,7 +46,7 @@ static inline void colibri_pxa3xx_init_lcd(int bl_pin) {} extern void colibri_pxa3xx_init_eth(struct ax_plat_data *plat_data); #endif -#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE) +#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL) extern void colibri_pxa3xx_init_nand(void); #else static inline void colibri_pxa3xx_init_nand(void) {} diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c index 4105614cc38e..9e132b3e48c6 100644 --- a/arch/arm/mach-pxa/littleton.c +++ b/arch/arm/mach-pxa/littleton.c @@ -291,7 +291,7 @@ static void __init littleton_init_mmc(void) static inline void littleton_init_mmc(void) {} #endif -#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE) +#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL) static struct mtd_partition littleton_nand_partitions[] = { [0] = { .name = "Bootloader", @@ -329,10 +329,8 @@ static struct mtd_partition littleton_nand_partitions[] = { }; static struct pxa3xx_nand_platform_data littleton_nand_info = { - .enable_arbiter = 1, - .num_cs = 1, - .parts[0] = littleton_nand_partitions, - .nr_parts[0] = ARRAY_SIZE(littleton_nand_partitions), + .parts = littleton_nand_partitions, + .nr_parts = ARRAY_SIZE(littleton_nand_partitions), }; static void __init littleton_init_nand(void) @@ -341,7 +339,7 @@ static void __init littleton_init_nand(void) } #else static inline void littleton_init_nand(void) {} -#endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */ +#endif /* IS_ENABLED(CONFIG_MTD_NAND_MARVELL) */ #if defined(CONFIG_I2C_PXA) || defined(CONFIG_I2C_PXA_MODULE) static struct led_info littleton_da9034_leds[] = { diff --git a/arch/arm/mach-pxa/mxm8x10.c b/arch/arm/mach-pxa/mxm8x10.c index f9e3d41a4609..616b22397d73 100644 --- a/arch/arm/mach-pxa/mxm8x10.c +++ b/arch/arm/mach-pxa/mxm8x10.c @@ -359,7 +359,7 @@ void __init mxm_8x10_ac97_init(void) } /* NAND flash Support */ -#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE) +#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL) #define NAND_BLOCK_SIZE SZ_128K #define NB(x) (NAND_BLOCK_SIZE * (x)) static struct mtd_partition mxm_8x10_nand_partitions[] = { @@ -389,11 +389,9 @@ static struct mtd_partition mxm_8x10_nand_partitions[] = { }; static struct pxa3xx_nand_platform_data mxm_8x10_nand_info = { - .enable_arbiter = 1, .keep_config = 1, - .num_cs = 1, - .parts[0] = mxm_8x10_nand_partitions, - .nr_parts[0] = ARRAY_SIZE(mxm_8x10_nand_partitions) + .parts = mxm_8x10_nand_partitions, + .nr_parts = ARRAY_SIZE(mxm_8x10_nand_partitions) }; static void __init mxm_8x10_nand_init(void) @@ -402,7 +400,7 @@ static void __init mxm_8x10_nand_init(void) } #else static inline void mxm_8x10_nand_init(void) {} -#endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */ +#endif /* IS_ENABLED(CONFIG_MTD_NAND_MARVELL) */ /* Ethernet support: Davicom DM9000 */ static struct resource dm9k_resources[] = { diff --git a/arch/arm/mach-pxa/pxa3xx-ulpi.c b/arch/arm/mach-pxa/pxa3xx-ulpi.c index 60cb59a7ebd1..b3e2016f24b1 100644 --- a/arch/arm/mach-pxa/pxa3xx-ulpi.c +++ b/arch/arm/mach-pxa/pxa3xx-ulpi.c @@ -256,7 +256,7 @@ int pxa3xx_u2d_start_hc(struct usb_bus *host) if (!u2d) return 0; - clk_enable(u2d->clk); + clk_prepare_enable(u2d->clk); if (cpu_is_pxa310()) { pxa310_u2d_setup_otg_hc(); @@ -276,7 +276,7 @@ void pxa3xx_u2d_stop_hc(struct usb_bus *host) if (cpu_is_pxa310()) pxa310_stop_otg_hc(); - clk_disable(u2d->clk); + clk_disable_unprepare(u2d->clk); } EXPORT_SYMBOL_GPL(pxa3xx_u2d_stop_hc); @@ -331,7 +331,7 @@ static int pxa3xx_u2d_probe(struct platform_device *pdev) goto err_free_plat; } - platform_set_drvdata(pdev, &u2d); + platform_set_drvdata(pdev, u2d); return 0; diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index e7ac7dcb95e9..034345546f84 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c @@ -346,11 +346,9 @@ static struct mtd_partition raumfeld_nand_partitions[] = { }; static struct pxa3xx_nand_platform_data raumfeld_nand_info = { - .enable_arbiter = 1, .keep_config = 1, - .num_cs = 1, - .parts[0] = raumfeld_nand_partitions, - .nr_parts[0] = ARRAY_SIZE(raumfeld_nand_partitions), + .parts = raumfeld_nand_partitions, + .nr_parts = ARRAY_SIZE(raumfeld_nand_partitions), }; /** @@ -378,9 +376,9 @@ static struct gpiod_lookup_table raumfeld_rotary_gpios_table = { }; static const struct property_entry raumfeld_rotary_properties[] __initconst = { - PROPERTY_ENTRY_INTEGER("rotary-encoder,steps-per-period", u32, 24), - PROPERTY_ENTRY_INTEGER("linux,axis", u32, REL_X), - PROPERTY_ENTRY_INTEGER("rotary-encoder,relative_axis", u32, 1), + PROPERTY_ENTRY_U32("rotary-encoder,steps-per-period", 24), + PROPERTY_ENTRY_U32("linux,axis", REL_X), + PROPERTY_ENTRY_U32("rotary-encoder,relative_axis", 1), { }, }; diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index 4268552d600d..d69de312d8d9 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -338,7 +338,7 @@ static void __init zylonite_init_keypad(void) static inline void zylonite_init_keypad(void) {} #endif -#if defined(CONFIG_MTD_NAND_PXA3xx) || defined(CONFIG_MTD_NAND_PXA3xx_MODULE) +#if IS_ENABLED(CONFIG_MTD_NAND_MARVELL) static struct mtd_partition zylonite_nand_partitions[] = { [0] = { .name = "Bootloader", @@ -376,10 +376,8 @@ static struct mtd_partition zylonite_nand_partitions[] = { }; static struct pxa3xx_nand_platform_data zylonite_nand_info = { - .enable_arbiter = 1, - .num_cs = 1, - .parts[0] = zylonite_nand_partitions, - .nr_parts[0] = ARRAY_SIZE(zylonite_nand_partitions), + .parts = zylonite_nand_partitions, + .nr_parts = ARRAY_SIZE(zylonite_nand_partitions), }; static void __init zylonite_init_nand(void) @@ -388,7 +386,7 @@ static void __init zylonite_init_nand(void) } #else static inline void zylonite_init_nand(void) {} -#endif /* CONFIG_MTD_NAND_PXA3xx || CONFIG_MTD_NAND_PXA3xx_MODULE */ +#endif /* IS_ENABLED(CONFIG_MTD_NAND_MARVELL) */ #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) static struct pxaohci_platform_data zylonite_ohci_info = { diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c index ecec340ca345..51984a40b097 100644 --- a/arch/arm/mach-rockchip/platsmp.c +++ b/arch/arm/mach-rockchip/platsmp.c @@ -208,6 +208,7 @@ static int __init rockchip_smp_prepare_sram(struct device_node *node) } static const struct regmap_config rockchip_pmu_regmap_config = { + .name = "rockchip-pmu", .reg_bits = 32, .val_bits = 32, .reg_stride = 4, diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h index a8fa4f7e1f60..43c1ac696274 100644 --- a/arch/arm/mach-shmobile/common.h +++ b/arch/arm/mach-shmobile/common.h @@ -7,6 +7,10 @@ extern void shmobile_init_delay(void); extern void shmobile_boot_vector(void); extern unsigned long shmobile_boot_fn; extern unsigned long shmobile_boot_size; +extern void shmobile_boot_vector_gen2(void); +extern unsigned long shmobile_boot_fn_gen2; +extern unsigned long shmobile_boot_cpu_gen2; +extern unsigned long shmobile_boot_size_gen2; extern void shmobile_smp_boot(void); extern void shmobile_smp_sleep(void); extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn, diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S index 32e0bf6e3ccb..cef8e8c555f8 100644 --- a/arch/arm/mach-shmobile/headsmp.S +++ b/arch/arm/mach-shmobile/headsmp.S @@ -16,6 +16,11 @@ #include <asm/assembler.h> #include <asm/memory.h> +#define SCTLR_MMU 0x01 +#define BOOTROM_ADDRESS 0xE6340000 +#define RWTCSRA_ADDRESS 0xE6020004 +#define RWTCSRA_WOVF 0x10 + /* * Reset vector for secondary CPUs. * This will be mapped at address 0 by SBAR register. @@ -37,6 +42,56 @@ shmobile_boot_fn: shmobile_boot_size: .long . - shmobile_boot_vector +#ifdef CONFIG_ARCH_RCAR_GEN2 +/* + * Reset vector for R-Car Gen2 and RZ/G1 secondary CPUs. + * This will be mapped at address 0 by SBAR register. + */ +ENTRY(shmobile_boot_vector_gen2) + mrc p15, 0, r0, c0, c0, 5 @ r0 = MPIDR + ldr r1, shmobile_boot_cpu_gen2 + cmp r0, r1 + bne shmobile_smp_continue_gen2 + + mrc p15, 0, r1, c1, c0, 0 @ r1 = SCTLR + and r0, r1, #SCTLR_MMU + cmp r0, #SCTLR_MMU + beq shmobile_smp_continue_gen2 + + ldr r0, rwtcsra + mov r1, #0 + ldrb r1, [r0] + and r0, r1, #RWTCSRA_WOVF + cmp r0, #RWTCSRA_WOVF + bne shmobile_smp_continue_gen2 + + ldr r0, bootrom + bx r0 + +shmobile_smp_continue_gen2: + ldr r1, shmobile_boot_fn_gen2 + bx r1 + +ENDPROC(shmobile_boot_vector_gen2) + + .align 4 +rwtcsra: + .word RWTCSRA_ADDRESS +bootrom: + .word BOOTROM_ADDRESS + .globl shmobile_boot_cpu_gen2 +shmobile_boot_cpu_gen2: + .word 0x00000000 + + .align 2 + .globl shmobile_boot_fn_gen2 +shmobile_boot_fn_gen2: + .space 4 + .globl shmobile_boot_size_gen2 +shmobile_boot_size_gen2: + .long . - shmobile_boot_vector_gen2 +#endif /* CONFIG_ARCH_RCAR_GEN2 */ + /* * Per-CPU SMP boot function/argument selection code based on MPIDR */ diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c index 4422b615a6ee..ba732effc90b 100644 --- a/arch/arm/mach-shmobile/platsmp-apmu.c +++ b/arch/arm/mach-shmobile/platsmp-apmu.c @@ -191,6 +191,7 @@ static void __init shmobile_smp_apmu_setup_boot(void) { /* install boot code shared by all CPUs */ shmobile_boot_fn = __pa_symbol(shmobile_smp_boot); + shmobile_boot_fn_gen2 = shmobile_boot_fn; } void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus, diff --git a/arch/arm/mach-shmobile/pm-rcar-gen2.c b/arch/arm/mach-shmobile/pm-rcar-gen2.c index e5f215c8b218..5a798b406af0 100644 --- a/arch/arm/mach-shmobile/pm-rcar-gen2.c +++ b/arch/arm/mach-shmobile/pm-rcar-gen2.c @@ -17,6 +17,7 @@ #include <linux/smp.h> #include <linux/soc/renesas/rcar-sysc.h> #include <asm/io.h> +#include <asm/cputype.h> #include "common.h" #include "rcar-gen2.h" @@ -37,7 +38,6 @@ #define CA7RESCNT_CODE 0x5a5a0000 #define CA7RESCNT_CPUS 0xf /* CPU0-3 */ - /* On-chip RAM */ #define ICRAM1 0xe63c0000 /* Inter Connect RAM1 (4 KiB) */ @@ -119,8 +119,17 @@ map: p = ioremap(res.start, resource_size(&res)); if (!p) return; - - memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size); + /* + * install the reset vector, use the largest version if we have enough + * memory available + */ + if (resource_size(&res) >= shmobile_boot_size_gen2) { + shmobile_boot_cpu_gen2 = read_cpuid_mpidr(); + memcpy_toio(p, shmobile_boot_vector_gen2, + shmobile_boot_size_gen2); + } else { + memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size); + } iounmap(p); /* setup reset vectors */ diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c index 44438f344dc8..93f628acfd94 100644 --- a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c +++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c @@ -1,9 +1,9 @@ /* * R-Car Generation 2 da9063/da9210 regulator quirk * - * The r8a7790/lager and r8a7791/koelsch development boards have da9063 and - * da9210 regulators. Both regulators have their interrupt request lines tied - * to the same interrupt pin (IRQ2) on the SoC. + * Certain Gen2 development boards have an da9063 and one or more da9210 + * regulators. All of these regulators have their interrupt request lines + * tied to the same interrupt pin (IRQ2) on the SoC. * * After cold boot or da9063-induced restart, both the da9063 and da9210 seem * to assert their interrupt request lines. Hence as soon as one driver @@ -50,7 +50,7 @@ static void __iomem *irqc; static u8 da9063_irq_clr[] = { DA9063_REG_IRQ_MASK_A, 0xff, 0xff, 0xff, 0xff }; static u8 da9210_irq_clr[] = { DA9210_REG_MASK_A, 0xff, 0xff }; -static struct i2c_msg da9xxx_msgs[2] = { +static struct i2c_msg da9xxx_msgs[3] = { { .addr = 0x58, .len = ARRAY_SIZE(da9063_irq_clr), @@ -59,6 +59,10 @@ static struct i2c_msg da9xxx_msgs[2] = { .addr = 0x68, .len = ARRAY_SIZE(da9210_irq_clr), .buf = da9210_irq_clr, + }, { + .addr = 0x70, + .len = ARRAY_SIZE(da9210_irq_clr), + .buf = da9210_irq_clr, }, }; @@ -85,12 +89,16 @@ static int regulator_quirk_notify(struct notifier_block *nb, dev_dbg(dev, "Detected %s\n", client->name); if ((client->addr == 0x58 && !strcmp(client->name, "da9063")) || - (client->addr == 0x68 && !strcmp(client->name, "da9210"))) { - int ret; + (client->addr == 0x68 && !strcmp(client->name, "da9210")) || + (client->addr == 0x70 && !strcmp(client->name, "da9210"))) { + int ret, len; + + /* There are two DA9210 on Stout, one on the other boards. */ + len = of_machine_is_compatible("renesas,stout") ? 3 : 2; dev_info(&client->dev, "clearing da9063/da9210 interrupts\n"); - ret = i2c_transfer(client->adapter, da9xxx_msgs, ARRAY_SIZE(da9xxx_msgs)); - if (ret != ARRAY_SIZE(da9xxx_msgs)) + ret = i2c_transfer(client->adapter, da9xxx_msgs, len); + if (ret != len) dev_err(&client->dev, "i2c error %d\n", ret); } @@ -118,6 +126,7 @@ static int __init rcar_gen2_regulator_quirk(void) if (!of_machine_is_compatible("renesas,koelsch") && !of_machine_is_compatible("renesas,lager") && + !of_machine_is_compatible("renesas,stout") && !of_machine_is_compatible("renesas,gose")) return -ENODEV; diff --git a/arch/arm/mach-socfpga/pm.c b/arch/arm/mach-socfpga/pm.c index c378ab0c2431..d4866788702c 100644 --- a/arch/arm/mach-socfpga/pm.c +++ b/arch/arm/mach-socfpga/pm.c @@ -116,7 +116,6 @@ static int socfpga_pm_suspend(unsigned long arg) static int socfpga_pm_enter(suspend_state_t state) { switch (state) { - case PM_SUSPEND_STANDBY: case PM_SUSPEND_MEM: outer_disable(); cpu_suspend(0, socfpga_pm_suspend); diff --git a/arch/arm/mach-stm32/Kconfig b/arch/arm/mach-stm32/Kconfig index 0d1889bbde58..713c068b953f 100644 --- a/arch/arm/mach-stm32/Kconfig +++ b/arch/arm/mach-stm32/Kconfig @@ -1,8 +1,10 @@ -config ARCH_STM32 - bool "STMicrolectronics STM32" - depends on ARM_SINGLE_ARMV7M +menuconfig ARCH_STM32 + bool "STMicroelectronics STM32 family" if ARM_SINGLE_ARMV7M || ARCH_MULTI_V7 + select ARMV7M_SYSTICK if ARM_SINGLE_ARMV7M + select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7 + select ARM_GIC if ARCH_MULTI_V7 + select ARM_PSCI if ARCH_MULTI_V7 select ARCH_HAS_RESET_CONTROLLER - select ARMV7M_SYSTICK select CLKSRC_STM32 select PINCTRL select RESET_CONTROLLER @@ -10,22 +12,42 @@ config ARCH_STM32 help Support for STMicroelectronics STM32 processors. +if ARCH_STM32 + +if ARM_SINGLE_ARMV7M + config MACH_STM32F429 - bool "STMicrolectronics STM32F429" - depends on ARCH_STM32 + bool "STMicroelectronics STM32F429" + select ARM_AMBA default y config MACH_STM32F469 - bool "STMicrolectronics STM32F469" - depends on ARCH_STM32 + bool "STMicroelectronics STM32F469" + select ARM_AMBA default y config MACH_STM32F746 - bool "STMicrolectronics STM32F746" - depends on ARCH_STM32 + bool "STMicroelectronics STM32F746" + select ARM_AMBA + default y + +config MACH_STM32F769 + bool "STMicroelectronics STM32F769" + select ARM_AMBA default y config MACH_STM32H743 - bool "STMicrolectronics STM32H743" - depends on ARCH_STM32 + bool "STMicroelectronics STM32H743" + default y + +endif # ARMv7-M + +if ARCH_MULTI_V7 + +config MACH_STM32MP157 + bool "STMicroelectronics STM32MP157" default y + +endif # ARMv7-A + +endif diff --git a/arch/arm/mach-stm32/board-dt.c b/arch/arm/mach-stm32/board-dt.c index e918686e4191..011d57b488c2 100644 --- a/arch/arm/mach-stm32/board-dt.c +++ b/arch/arm/mach-stm32/board-dt.c @@ -1,22 +1,29 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) Maxime Coquelin 2015 + * Copyright (C) STMicroelectronics 2017 * Author: Maxime Coquelin <mcoquelin.stm32@gmail.com> - * License terms: GNU General Public License (GPL), version 2 */ #include <linux/kernel.h> -#include <asm/v7m.h> #include <asm/mach/arch.h> +#ifdef CONFIG_ARM_SINGLE_ARMV7M +#include <asm/v7m.h> +#endif static const char *const stm32_compat[] __initconst = { "st,stm32f429", "st,stm32f469", "st,stm32f746", + "st,stm32f769", "st,stm32h743", + "st,stm32mp157", NULL }; DT_MACHINE_START(STM32DT, "STM32 (Device Tree Support)") .dt_compat = stm32_compat, +#ifdef CONFIG_ARM_SINGLE_ARMV7M .restart = armv7m_restart, +#endif MACHINE_END diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index 58153cdf025b..ce53ceaf4cc5 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -48,4 +48,11 @@ config MACH_SUN9I default ARCH_SUNXI select ARM_GIC +config ARCH_SUNXI_MC_SMP + bool + depends on SMP + default MACH_SUN9I + select ARM_CCI400_PORT_CTRL + select ARM_CPU_SUSPEND + endif diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile index 27b168f121a1..7de9cc286d53 100644 --- a/arch/arm/mach-sunxi/Makefile +++ b/arch/arm/mach-sunxi/Makefile @@ -1,2 +1,5 @@ +CFLAGS_mc_smp.o += -march=armv7-a + obj-$(CONFIG_ARCH_SUNXI) += sunxi.o +obj-$(CONFIG_ARCH_SUNXI_MC_SMP) += mc_smp.o obj-$(CONFIG_SMP) += platsmp.o diff --git a/arch/arm/mach-sunxi/mc_smp.c b/arch/arm/mach-sunxi/mc_smp.c new file mode 100644 index 000000000000..c0246ec54a0a --- /dev/null +++ b/arch/arm/mach-sunxi/mc_smp.c @@ -0,0 +1,856 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018 Chen-Yu Tsai + * + * Chen-Yu Tsai <wens@csie.org> + * + * arch/arm/mach-sunxi/mc_smp.c + * + * Based on Allwinner code, arch/arm/mach-exynos/mcpm-exynos.c, and + * arch/arm/mach-hisi/platmcpm.c + * Cluster cache enable trampoline code adapted from MCPM framework + */ + +#include <linux/arm-cci.h> +#include <linux/cpu_pm.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/iopoll.h> +#include <linux/irqchip/arm-gic.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/smp.h> + +#include <asm/cacheflush.h> +#include <asm/cp15.h> +#include <asm/cputype.h> +#include <asm/idmap.h> +#include <asm/smp_plat.h> +#include <asm/suspend.h> + +#define SUNXI_CPUS_PER_CLUSTER 4 +#define SUNXI_NR_CLUSTERS 2 + +#define POLL_USEC 100 +#define TIMEOUT_USEC 100000 + +#define CPUCFG_CX_CTRL_REG0(c) (0x10 * (c)) +#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE(n) BIT(n) +#define CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE_ALL 0xf +#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A7 BIT(4) +#define CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A15 BIT(0) +#define CPUCFG_CX_CTRL_REG1(c) (0x10 * (c) + 0x4) +#define CPUCFG_CX_CTRL_REG1_ACINACTM BIT(0) +#define CPUCFG_CX_STATUS(c) (0x30 + 0x4 * (c)) +#define CPUCFG_CX_STATUS_STANDBYWFI(n) BIT(16 + (n)) +#define CPUCFG_CX_STATUS_STANDBYWFIL2 BIT(0) +#define CPUCFG_CX_RST_CTRL(c) (0x80 + 0x4 * (c)) +#define CPUCFG_CX_RST_CTRL_DBG_SOC_RST BIT(24) +#define CPUCFG_CX_RST_CTRL_ETM_RST(n) BIT(20 + (n)) +#define CPUCFG_CX_RST_CTRL_ETM_RST_ALL (0xf << 20) +#define CPUCFG_CX_RST_CTRL_DBG_RST(n) BIT(16 + (n)) +#define CPUCFG_CX_RST_CTRL_DBG_RST_ALL (0xf << 16) +#define CPUCFG_CX_RST_CTRL_H_RST BIT(12) +#define CPUCFG_CX_RST_CTRL_L2_RST BIT(8) +#define CPUCFG_CX_RST_CTRL_CX_RST(n) BIT(4 + (n)) +#define CPUCFG_CX_RST_CTRL_CORE_RST(n) BIT(n) + +#define PRCM_CPU_PO_RST_CTRL(c) (0x4 + 0x4 * (c)) +#define PRCM_CPU_PO_RST_CTRL_CORE(n) BIT(n) +#define PRCM_CPU_PO_RST_CTRL_CORE_ALL 0xf +#define PRCM_PWROFF_GATING_REG(c) (0x100 + 0x4 * (c)) +#define PRCM_PWROFF_GATING_REG_CLUSTER BIT(4) +#define PRCM_PWROFF_GATING_REG_CORE(n) BIT(n) +#define PRCM_PWR_SWITCH_REG(c, cpu) (0x140 + 0x10 * (c) + 0x4 * (cpu)) +#define PRCM_CPU_SOFT_ENTRY_REG 0x164 + +#define CPU0_SUPPORT_HOTPLUG_MAGIC0 0xFA50392F +#define CPU0_SUPPORT_HOTPLUG_MAGIC1 0x790DCA3A + +static void __iomem *cpucfg_base; +static void __iomem *prcm_base; +static void __iomem *sram_b_smp_base; + +static bool sunxi_core_is_cortex_a15(unsigned int core, unsigned int cluster) +{ + struct device_node *node; + int cpu = cluster * SUNXI_CPUS_PER_CLUSTER + core; + + node = of_cpu_device_node_get(cpu); + + /* In case of_cpu_device_node_get fails */ + if (!node) + node = of_get_cpu_node(cpu, NULL); + + if (!node) { + /* + * There's no point in returning an error, since we + * would be mid way in a core or cluster power sequence. + */ + pr_err("%s: Couldn't get CPU cluster %u core %u device node\n", + __func__, cluster, core); + + return false; + } + + return of_device_is_compatible(node, "arm,cortex-a15"); +} + +static int sunxi_cpu_power_switch_set(unsigned int cpu, unsigned int cluster, + bool enable) +{ + u32 reg; + + /* control sequence from Allwinner A80 user manual v1.2 PRCM section */ + reg = readl(prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu)); + if (enable) { + if (reg == 0x00) { + pr_debug("power clamp for cluster %u cpu %u already open\n", + cluster, cpu); + return 0; + } + + writel(0xff, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu)); + udelay(10); + writel(0xfe, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu)); + udelay(10); + writel(0xf8, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu)); + udelay(10); + writel(0xf0, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu)); + udelay(10); + writel(0x00, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu)); + udelay(10); + } else { + writel(0xff, prcm_base + PRCM_PWR_SWITCH_REG(cluster, cpu)); + udelay(10); + } + + return 0; +} + +static void sunxi_cpu0_hotplug_support_set(bool enable) +{ + if (enable) { + writel(CPU0_SUPPORT_HOTPLUG_MAGIC0, sram_b_smp_base); + writel(CPU0_SUPPORT_HOTPLUG_MAGIC1, sram_b_smp_base + 0x4); + } else { + writel(0x0, sram_b_smp_base); + writel(0x0, sram_b_smp_base + 0x4); + } +} + +static int sunxi_cpu_powerup(unsigned int cpu, unsigned int cluster) +{ + u32 reg; + + pr_debug("%s: cluster %u cpu %u\n", __func__, cluster, cpu); + if (cpu >= SUNXI_CPUS_PER_CLUSTER || cluster >= SUNXI_NR_CLUSTERS) + return -EINVAL; + + /* Set hotplug support magic flags for cpu0 */ + if (cluster == 0 && cpu == 0) + sunxi_cpu0_hotplug_support_set(true); + + /* assert processor power-on reset */ + reg = readl(prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); + reg &= ~PRCM_CPU_PO_RST_CTRL_CORE(cpu); + writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); + + /* Cortex-A7: hold L1 reset disable signal low */ + if (!sunxi_core_is_cortex_a15(cpu, cluster)) { + reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG0(cluster)); + reg &= ~CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE(cpu); + writel(reg, cpucfg_base + CPUCFG_CX_CTRL_REG0(cluster)); + } + + /* assert processor related resets */ + reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); + reg &= ~CPUCFG_CX_RST_CTRL_DBG_RST(cpu); + + /* + * Allwinner code also asserts resets for NEON on A15. According + * to ARM manuals, asserting power-on reset is sufficient. + */ + if (!sunxi_core_is_cortex_a15(cpu, cluster)) + reg &= ~CPUCFG_CX_RST_CTRL_ETM_RST(cpu); + + writel(reg, cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); + + /* open power switch */ + sunxi_cpu_power_switch_set(cpu, cluster, true); + + /* clear processor power gate */ + reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster)); + reg &= ~PRCM_PWROFF_GATING_REG_CORE(cpu); + writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster)); + udelay(20); + + /* de-assert processor power-on reset */ + reg = readl(prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); + reg |= PRCM_CPU_PO_RST_CTRL_CORE(cpu); + writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); + + /* de-assert all processor resets */ + reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); + reg |= CPUCFG_CX_RST_CTRL_DBG_RST(cpu); + reg |= CPUCFG_CX_RST_CTRL_CORE_RST(cpu); + if (!sunxi_core_is_cortex_a15(cpu, cluster)) + reg |= CPUCFG_CX_RST_CTRL_ETM_RST(cpu); + else + reg |= CPUCFG_CX_RST_CTRL_CX_RST(cpu); /* NEON */ + writel(reg, cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); + + return 0; +} + +static int sunxi_cluster_powerup(unsigned int cluster) +{ + u32 reg; + + pr_debug("%s: cluster %u\n", __func__, cluster); + if (cluster >= SUNXI_NR_CLUSTERS) + return -EINVAL; + + /* assert ACINACTM */ + reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG1(cluster)); + reg |= CPUCFG_CX_CTRL_REG1_ACINACTM; + writel(reg, cpucfg_base + CPUCFG_CX_CTRL_REG1(cluster)); + + /* assert cluster processor power-on resets */ + reg = readl(prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); + reg &= ~PRCM_CPU_PO_RST_CTRL_CORE_ALL; + writel(reg, prcm_base + PRCM_CPU_PO_RST_CTRL(cluster)); + + /* assert cluster resets */ + reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); + reg &= ~CPUCFG_CX_RST_CTRL_DBG_SOC_RST; + reg &= ~CPUCFG_CX_RST_CTRL_DBG_RST_ALL; + reg &= ~CPUCFG_CX_RST_CTRL_H_RST; + reg &= ~CPUCFG_CX_RST_CTRL_L2_RST; + + /* + * Allwinner code also asserts resets for NEON on A15. According + * to ARM manuals, asserting power-on reset is sufficient. + */ + if (!sunxi_core_is_cortex_a15(0, cluster)) + reg &= ~CPUCFG_CX_RST_CTRL_ETM_RST_ALL; + + writel(reg, cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); + + /* hold L1/L2 reset disable signals low */ + reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG0(cluster)); + if (sunxi_core_is_cortex_a15(0, cluster)) { + /* Cortex-A15: hold L2RSTDISABLE low */ + reg &= ~CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A15; + } else { + /* Cortex-A7: hold L1RSTDISABLE and L2RSTDISABLE low */ + reg &= ~CPUCFG_CX_CTRL_REG0_L1_RST_DISABLE_ALL; + reg &= ~CPUCFG_CX_CTRL_REG0_L2_RST_DISABLE_A7; + } + writel(reg, cpucfg_base + CPUCFG_CX_CTRL_REG0(cluster)); + + /* clear cluster power gate */ + reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster)); + reg &= ~PRCM_PWROFF_GATING_REG_CLUSTER; + writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster)); + udelay(20); + + /* de-assert cluster resets */ + reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); + reg |= CPUCFG_CX_RST_CTRL_DBG_SOC_RST; + reg |= CPUCFG_CX_RST_CTRL_H_RST; + reg |= CPUCFG_CX_RST_CTRL_L2_RST; + writel(reg, cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); + + /* de-assert ACINACTM */ + reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG1(cluster)); + reg &= ~CPUCFG_CX_CTRL_REG1_ACINACTM; + writel(reg, cpucfg_base + CPUCFG_CX_CTRL_REG1(cluster)); + + return 0; +} + +/* + * This bit is shared between the initial nocache_trampoline call to + * enable CCI-400 and proper cluster cache disable before power down. + */ +static void sunxi_cluster_cache_disable_without_axi(void) +{ + if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A15) { + /* + * On the Cortex-A15 we need to disable + * L2 prefetching before flushing the cache. + */ + asm volatile( + "mcr p15, 1, %0, c15, c0, 3\n" + "isb\n" + "dsb" + : : "r" (0x400)); + } + + /* Flush all cache levels for this cluster. */ + v7_exit_coherency_flush(all); + + /* + * Disable cluster-level coherency by masking + * incoming snoops and DVM messages: + */ + cci_disable_port_by_cpu(read_cpuid_mpidr()); +} + +static int sunxi_mc_smp_cpu_table[SUNXI_NR_CLUSTERS][SUNXI_CPUS_PER_CLUSTER]; +static int sunxi_mc_smp_first_comer; + +/* + * Enable cluster-level coherency, in preparation for turning on the MMU. + * + * Also enable regional clock gating and L2 data latency settings for + * Cortex-A15. These settings are from the vendor kernel. + */ +static void __naked sunxi_mc_smp_cluster_cache_enable(void) +{ + asm volatile ( + "mrc p15, 0, r1, c0, c0, 0\n" + "movw r2, #" __stringify(ARM_CPU_PART_MASK & 0xffff) "\n" + "movt r2, #" __stringify(ARM_CPU_PART_MASK >> 16) "\n" + "and r1, r1, r2\n" + "movw r2, #" __stringify(ARM_CPU_PART_CORTEX_A15 & 0xffff) "\n" + "movt r2, #" __stringify(ARM_CPU_PART_CORTEX_A15 >> 16) "\n" + "cmp r1, r2\n" + "bne not_a15\n" + + /* The following is Cortex-A15 specific */ + + /* ACTLR2: Enable CPU regional clock gates */ + "mrc p15, 1, r1, c15, c0, 4\n" + "orr r1, r1, #(0x1<<31)\n" + "mcr p15, 1, r1, c15, c0, 4\n" + + /* L2ACTLR */ + "mrc p15, 1, r1, c15, c0, 0\n" + /* Enable L2, GIC, and Timer regional clock gates */ + "orr r1, r1, #(0x1<<26)\n" + /* Disable clean/evict from being pushed to external */ + "orr r1, r1, #(0x1<<3)\n" + "mcr p15, 1, r1, c15, c0, 0\n" + + /* L2CTRL: L2 data RAM latency */ + "mrc p15, 1, r1, c9, c0, 2\n" + "bic r1, r1, #(0x7<<0)\n" + "orr r1, r1, #(0x3<<0)\n" + "mcr p15, 1, r1, c9, c0, 2\n" + + /* End of Cortex-A15 specific setup */ + "not_a15:\n" + + /* Get value of sunxi_mc_smp_first_comer */ + "adr r1, first\n" + "ldr r0, [r1]\n" + "ldr r0, [r1, r0]\n" + + /* Skip cci_enable_port_for_self if not first comer */ + "cmp r0, #0\n" + "bxeq lr\n" + "b cci_enable_port_for_self\n" + + ".align 2\n" + "first: .word sunxi_mc_smp_first_comer - .\n" + ); +} + +static void __naked sunxi_mc_smp_secondary_startup(void) +{ + asm volatile( + "bl sunxi_mc_smp_cluster_cache_enable\n" + "b secondary_startup" + /* Let compiler know about sunxi_mc_smp_cluster_cache_enable */ + :: "i" (sunxi_mc_smp_cluster_cache_enable) + ); +} + +static DEFINE_SPINLOCK(boot_lock); + +static bool sunxi_mc_smp_cluster_is_down(unsigned int cluster) +{ + int i; + + for (i = 0; i < SUNXI_CPUS_PER_CLUSTER; i++) + if (sunxi_mc_smp_cpu_table[cluster][i]) + return false; + return true; +} + +static void sunxi_mc_smp_secondary_init(unsigned int cpu) +{ + /* Clear hotplug support magic flags for cpu0 */ + if (cpu == 0) + sunxi_cpu0_hotplug_support_set(false); +} + +static int sunxi_mc_smp_boot_secondary(unsigned int l_cpu, struct task_struct *idle) +{ + unsigned int mpidr, cpu, cluster; + + mpidr = cpu_logical_map(l_cpu); + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); + + if (!cpucfg_base) + return -ENODEV; + if (cluster >= SUNXI_NR_CLUSTERS || cpu >= SUNXI_CPUS_PER_CLUSTER) + return -EINVAL; + + spin_lock_irq(&boot_lock); + + if (sunxi_mc_smp_cpu_table[cluster][cpu]) + goto out; + + if (sunxi_mc_smp_cluster_is_down(cluster)) { + sunxi_mc_smp_first_comer = true; + sunxi_cluster_powerup(cluster); + } else { + sunxi_mc_smp_first_comer = false; + } + + /* This is read by incoming CPUs with their cache and MMU disabled */ + sync_cache_w(&sunxi_mc_smp_first_comer); + sunxi_cpu_powerup(cpu, cluster); + +out: + sunxi_mc_smp_cpu_table[cluster][cpu]++; + spin_unlock_irq(&boot_lock); + + return 0; +} + +#ifdef CONFIG_HOTPLUG_CPU +static void sunxi_cluster_cache_disable(void) +{ + unsigned int cluster = MPIDR_AFFINITY_LEVEL(read_cpuid_mpidr(), 1); + u32 reg; + + pr_debug("%s: cluster %u\n", __func__, cluster); + + sunxi_cluster_cache_disable_without_axi(); + + /* last man standing, assert ACINACTM */ + reg = readl(cpucfg_base + CPUCFG_CX_CTRL_REG1(cluster)); + reg |= CPUCFG_CX_CTRL_REG1_ACINACTM; + writel(reg, cpucfg_base + CPUCFG_CX_CTRL_REG1(cluster)); +} + +static void sunxi_mc_smp_cpu_die(unsigned int l_cpu) +{ + unsigned int mpidr, cpu, cluster; + bool last_man; + + mpidr = cpu_logical_map(l_cpu); + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); + pr_debug("%s: cluster %u cpu %u\n", __func__, cluster, cpu); + + spin_lock(&boot_lock); + sunxi_mc_smp_cpu_table[cluster][cpu]--; + if (sunxi_mc_smp_cpu_table[cluster][cpu] == 1) { + /* A power_up request went ahead of us. */ + pr_debug("%s: aborting due to a power up request\n", + __func__); + spin_unlock(&boot_lock); + return; + } else if (sunxi_mc_smp_cpu_table[cluster][cpu] > 1) { + pr_err("Cluster %d CPU%d boots multiple times\n", + cluster, cpu); + BUG(); + } + + last_man = sunxi_mc_smp_cluster_is_down(cluster); + spin_unlock(&boot_lock); + + gic_cpu_if_down(0); + if (last_man) + sunxi_cluster_cache_disable(); + else + v7_exit_coherency_flush(louis); + + for (;;) + wfi(); +} + +static int sunxi_cpu_powerdown(unsigned int cpu, unsigned int cluster) +{ + u32 reg; + + pr_debug("%s: cluster %u cpu %u\n", __func__, cluster, cpu); + if (cpu >= SUNXI_CPUS_PER_CLUSTER || cluster >= SUNXI_NR_CLUSTERS) + return -EINVAL; + + /* gate processor power */ + reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster)); + reg |= PRCM_PWROFF_GATING_REG_CORE(cpu); + writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster)); + udelay(20); + + /* close power switch */ + sunxi_cpu_power_switch_set(cpu, cluster, false); + + return 0; +} + +static int sunxi_cluster_powerdown(unsigned int cluster) +{ + u32 reg; + + pr_debug("%s: cluster %u\n", __func__, cluster); + if (cluster >= SUNXI_NR_CLUSTERS) + return -EINVAL; + + /* assert cluster resets or system will hang */ + pr_debug("%s: assert cluster reset\n", __func__); + reg = readl(cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); + reg &= ~CPUCFG_CX_RST_CTRL_DBG_SOC_RST; + reg &= ~CPUCFG_CX_RST_CTRL_H_RST; + reg &= ~CPUCFG_CX_RST_CTRL_L2_RST; + writel(reg, cpucfg_base + CPUCFG_CX_RST_CTRL(cluster)); + + /* gate cluster power */ + pr_debug("%s: gate cluster power\n", __func__); + reg = readl(prcm_base + PRCM_PWROFF_GATING_REG(cluster)); + reg |= PRCM_PWROFF_GATING_REG_CLUSTER; + writel(reg, prcm_base + PRCM_PWROFF_GATING_REG(cluster)); + udelay(20); + + return 0; +} + +static int sunxi_mc_smp_cpu_kill(unsigned int l_cpu) +{ + unsigned int mpidr, cpu, cluster; + unsigned int tries, count; + int ret = 0; + u32 reg; + + mpidr = cpu_logical_map(l_cpu); + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); + + /* This should never happen */ + if (WARN_ON(cluster >= SUNXI_NR_CLUSTERS || + cpu >= SUNXI_CPUS_PER_CLUSTER)) + return 0; + + /* wait for CPU core to die and enter WFI */ + count = TIMEOUT_USEC / POLL_USEC; + spin_lock_irq(&boot_lock); + for (tries = 0; tries < count; tries++) { + spin_unlock_irq(&boot_lock); + usleep_range(POLL_USEC / 2, POLL_USEC); + spin_lock_irq(&boot_lock); + + /* + * If the user turns off a bunch of cores at the same + * time, the kernel might call cpu_kill before some of + * them are ready. This is because boot_lock serializes + * both cpu_die and cpu_kill callbacks. Either one could + * run first. We should wait for cpu_die to complete. + */ + if (sunxi_mc_smp_cpu_table[cluster][cpu]) + continue; + + reg = readl(cpucfg_base + CPUCFG_CX_STATUS(cluster)); + if (reg & CPUCFG_CX_STATUS_STANDBYWFI(cpu)) + break; + } + + if (tries >= count) { + ret = ETIMEDOUT; + goto out; + } + + /* power down CPU core */ + sunxi_cpu_powerdown(cpu, cluster); + + if (!sunxi_mc_smp_cluster_is_down(cluster)) + goto out; + + /* wait for cluster L2 WFI */ + ret = readl_poll_timeout(cpucfg_base + CPUCFG_CX_STATUS(cluster), reg, + reg & CPUCFG_CX_STATUS_STANDBYWFIL2, + POLL_USEC, TIMEOUT_USEC); + if (ret) { + /* + * Ignore timeout on the cluster. Leaving the cluster on + * will not affect system execution, just use a bit more + * power. But returning an error here will only confuse + * the user as the CPU has already been shutdown. + */ + ret = 0; + goto out; + } + + /* Power down cluster */ + sunxi_cluster_powerdown(cluster); + +out: + spin_unlock_irq(&boot_lock); + pr_debug("%s: cluster %u cpu %u powerdown: %d\n", + __func__, cluster, cpu, ret); + return !ret; +} + +static bool sunxi_mc_smp_cpu_can_disable(unsigned int __unused) +{ + return true; +} +#endif + +static const struct smp_operations sunxi_mc_smp_smp_ops __initconst = { + .smp_secondary_init = sunxi_mc_smp_secondary_init, + .smp_boot_secondary = sunxi_mc_smp_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_die = sunxi_mc_smp_cpu_die, + .cpu_kill = sunxi_mc_smp_cpu_kill, + .cpu_can_disable = sunxi_mc_smp_cpu_can_disable, +#endif +}; + +static bool __init sunxi_mc_smp_cpu_table_init(void) +{ + unsigned int mpidr, cpu, cluster; + + mpidr = read_cpuid_mpidr(); + cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); + cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); + + if (cluster >= SUNXI_NR_CLUSTERS || cpu >= SUNXI_CPUS_PER_CLUSTER) { + pr_err("%s: boot CPU is out of bounds!\n", __func__); + return false; + } + sunxi_mc_smp_cpu_table[cluster][cpu] = 1; + return true; +} + +/* + * Adapted from arch/arm/common/mc_smp_entry.c + * + * We need the trampoline code to enable CCI-400 on the first cluster + */ +typedef typeof(cpu_reset) phys_reset_t; + +static void __init __naked sunxi_mc_smp_resume(void) +{ + asm volatile( + "bl sunxi_mc_smp_cluster_cache_enable\n" + "b cpu_resume" + /* Let compiler know about sunxi_mc_smp_cluster_cache_enable */ + :: "i" (sunxi_mc_smp_cluster_cache_enable) + ); +} + +static int __init nocache_trampoline(unsigned long __unused) +{ + phys_reset_t phys_reset; + + setup_mm_for_reboot(); + sunxi_cluster_cache_disable_without_axi(); + + phys_reset = (phys_reset_t)(unsigned long)__pa_symbol(cpu_reset); + phys_reset(__pa_symbol(sunxi_mc_smp_resume), false); + BUG(); +} + +static int __init sunxi_mc_smp_loopback(void) +{ + int ret; + + /* + * We're going to soft-restart the current CPU through the + * low-level MCPM code by leveraging the suspend/resume + * infrastructure. Let's play it safe by using cpu_pm_enter() + * in case the CPU init code path resets the VFP or similar. + */ + sunxi_mc_smp_first_comer = true; + local_irq_disable(); + local_fiq_disable(); + ret = cpu_pm_enter(); + if (!ret) { + ret = cpu_suspend(0, nocache_trampoline); + cpu_pm_exit(); + } + local_fiq_enable(); + local_irq_enable(); + sunxi_mc_smp_first_comer = false; + + return ret; +} + +/* + * This holds any device nodes that we requested resources for, + * so that we may easily release resources in the error path. + */ +struct sunxi_mc_smp_nodes { + struct device_node *prcm_node; + struct device_node *cpucfg_node; + struct device_node *sram_node; +}; + +/* This structure holds SoC-specific bits tied to an enable-method string. */ +struct sunxi_mc_smp_data { + const char *enable_method; + int (*get_smp_nodes)(struct sunxi_mc_smp_nodes *nodes); +}; + +static void __init sunxi_mc_smp_put_nodes(struct sunxi_mc_smp_nodes *nodes) +{ + of_node_put(nodes->prcm_node); + of_node_put(nodes->cpucfg_node); + of_node_put(nodes->sram_node); + memset(nodes, 0, sizeof(*nodes)); +} + +static int __init sun9i_a80_get_smp_nodes(struct sunxi_mc_smp_nodes *nodes) +{ + nodes->prcm_node = of_find_compatible_node(NULL, NULL, + "allwinner,sun9i-a80-prcm"); + if (!nodes->prcm_node) { + pr_err("%s: PRCM not available\n", __func__); + return -ENODEV; + } + + nodes->cpucfg_node = of_find_compatible_node(NULL, NULL, + "allwinner,sun9i-a80-cpucfg"); + if (!nodes->cpucfg_node) { + pr_err("%s: CPUCFG not available\n", __func__); + return -ENODEV; + } + + nodes->sram_node = of_find_compatible_node(NULL, NULL, + "allwinner,sun9i-a80-smp-sram"); + if (!nodes->sram_node) { + pr_err("%s: Secure SRAM not available\n", __func__); + return -ENODEV; + } + + return 0; +} + +static const struct sunxi_mc_smp_data sunxi_mc_smp_data[] __initconst = { + { + .enable_method = "allwinner,sun9i-a80-smp", + .get_smp_nodes = sun9i_a80_get_smp_nodes, + }, +}; + +static int __init sunxi_mc_smp_init(void) +{ + struct sunxi_mc_smp_nodes nodes = { 0 }; + struct device_node *node; + struct resource res; + int i, ret; + + /* + * Don't bother checking the "cpus" node, as an enable-method + * property in that node is undocumented. + */ + node = of_cpu_device_node_get(0); + if (!node) + return -ENODEV; + + /* + * We can't actually use the enable-method magic in the kernel. + * Our loopback / trampoline code uses the CPU suspend framework, + * which requires the identity mapping be available. It would not + * yet be available if we used the .init_cpus or .prepare_cpus + * callbacks in smp_operations, which we would use if we were to + * use CPU_METHOD_OF_DECLARE + */ + for (i = 0; i < ARRAY_SIZE(sunxi_mc_smp_data); i++) { + ret = of_property_match_string(node, "enable-method", + sunxi_mc_smp_data[i].enable_method); + if (!ret) + break; + } + + of_node_put(node); + if (ret) + return -ENODEV; + + if (!sunxi_mc_smp_cpu_table_init()) + return -EINVAL; + + if (!cci_probed()) { + pr_err("%s: CCI-400 not available\n", __func__); + return -ENODEV; + } + + /* Get needed device tree nodes */ + ret = sunxi_mc_smp_data[i].get_smp_nodes(&nodes); + if (ret) + goto err_put_nodes; + + /* + * Unfortunately we can not request the I/O region for the PRCM. + * It is shared with the PRCM clock. + */ + prcm_base = of_iomap(nodes.prcm_node, 0); + if (!prcm_base) { + pr_err("%s: failed to map PRCM registers\n", __func__); + ret = -ENOMEM; + goto err_put_nodes; + } + + cpucfg_base = of_io_request_and_map(nodes.cpucfg_node, 0, + "sunxi-mc-smp"); + if (IS_ERR(cpucfg_base)) { + ret = PTR_ERR(cpucfg_base); + pr_err("%s: failed to map CPUCFG registers: %d\n", + __func__, ret); + goto err_unmap_prcm; + } + + sram_b_smp_base = of_io_request_and_map(nodes.sram_node, 0, + "sunxi-mc-smp"); + if (IS_ERR(sram_b_smp_base)) { + ret = PTR_ERR(sram_b_smp_base); + pr_err("%s: failed to map secure SRAM\n", __func__); + goto err_unmap_release_cpucfg; + } + + /* Configure CCI-400 for boot cluster */ + ret = sunxi_mc_smp_loopback(); + if (ret) { + pr_err("%s: failed to configure boot cluster: %d\n", + __func__, ret); + goto err_unmap_release_secure_sram; + } + + /* We don't need the device nodes anymore */ + sunxi_mc_smp_put_nodes(&nodes); + + /* Set the hardware entry point address */ + writel(__pa_symbol(sunxi_mc_smp_secondary_startup), + prcm_base + PRCM_CPU_SOFT_ENTRY_REG); + + /* Actually enable multi cluster SMP */ + smp_set_ops(&sunxi_mc_smp_smp_ops); + + pr_info("sunxi multi cluster SMP support installed\n"); + + return 0; + +err_unmap_release_secure_sram: + iounmap(sram_b_smp_base); + of_address_to_resource(nodes.sram_node, 0, &res); + release_mem_region(res.start, resource_size(&res)); +err_unmap_release_cpucfg: + iounmap(cpucfg_base); + of_address_to_resource(nodes.cpucfg_node, 0, &res); + release_mem_region(res.start, resource_size(&res)); +err_unmap_prcm: + iounmap(prcm_base); +err_put_nodes: + sunxi_mc_smp_put_nodes(&nodes); + return ret; +} + +early_initcall(sunxi_mc_smp_init); diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index 7276afee30b3..afc1a1d4f7a5 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -106,12 +106,6 @@ config OMAP3_L2_AUX_SECURE_SERVICE_SET_ID help PPA routine service ID for setting L2 auxiliary control register. -config OMAP_DM_TIMER - bool "Use dual-mode timer" - depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS - help - Select this option if you want to use OMAP Dual-Mode timers. - config OMAP_SERIAL_WAKE bool "Enable wake-up events for serial ports" depends on ARCH_OMAP1 && OMAP_MUX diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile index 47e186729d44..7215ada707e4 100644 --- a/arch/arm/plat-omap/Makefile +++ b/arch/arm/plat-omap/Makefile @@ -9,5 +9,4 @@ obj-y := sram.o dma.o counter_32k.o # omap_device support (OMAP2+ only at the moment) -obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 634b373785c4..ecf613761e78 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -31,7 +31,6 @@ CONFIG_PROFILING=y CONFIG_JUMP_LABEL=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y -# CONFIG_IOSCHED_DEADLINE is not set CONFIG_ARCH_SUNXI=y CONFIG_ARCH_ALPINE=y CONFIG_ARCH_BCM2835=y @@ -51,11 +50,14 @@ CONFIG_ARCH_SEATTLE=y CONFIG_ARCH_RENESAS=y CONFIG_ARCH_R8A7795=y CONFIG_ARCH_R8A7796=y +CONFIG_ARCH_R8A77965=y CONFIG_ARCH_R8A77970=y +CONFIG_ARCH_R8A77980=y CONFIG_ARCH_R8A77995=y CONFIG_ARCH_STRATIX10=y CONFIG_ARCH_TEGRA=y CONFIG_ARCH_SPRD=y +CONFIG_ARCH_SYNQUACER=y CONFIG_ARCH_THUNDER=y CONFIG_ARCH_THUNDER2=y CONFIG_ARCH_UNIPHIER=y @@ -99,10 +101,19 @@ CONFIG_HIBERNATION=y CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y CONFIG_ARM_CPUIDLE=y CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=m +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y CONFIG_CPUFREQ_DT=y CONFIG_ARM_ARMADA_37XX_CPUFREQ=y CONFIG_ARM_BIG_LITTLE_CPUFREQ=y CONFIG_ARM_SCPI_CPUFREQ=y +CONFIG_ARM_TEGRA186_CPUFREQ=y CONFIG_ACPI_CPPC_CPUFREQ=m CONFIG_NET=y CONFIG_PACKET=y @@ -209,7 +220,14 @@ CONFIG_QCOM_EMAC=m CONFIG_RAVB=y CONFIG_SMC91X=y CONFIG_SMSC911X=y +CONFIG_SNI_AVE=y +CONFIG_SNI_NETSEC=y CONFIG_STMMAC_ETH=m +CONFIG_DWMAC_IPQ806X=m +CONFIG_DWMAC_MESON=m +CONFIG_DWMAC_ROCKCHIP=m +CONFIG_DWMAC_SUNXI=m +CONFIG_DWMAC_SUN8I=m CONFIG_MDIO_BUS_MUX_MMIOREG=y CONFIG_AT803X_PHY=m CONFIG_MARVELL_PHY=m @@ -305,6 +323,7 @@ CONFIG_PINCTRL_MSM8996=y CONFIG_PINCTRL_QDF2XXX=y CONFIG_PINCTRL_QCOM_SPMI_PMIC=y CONFIG_GPIO_DWAPB=y +CONFIG_GPIO_MB86S7X=y CONFIG_GPIO_PL061=y CONFIG_GPIO_RCAR=y CONFIG_GPIO_UNIPHIER=y @@ -327,7 +346,10 @@ CONFIG_THERMAL_EMULATION=y CONFIG_BRCMSTB_THERMAL=m CONFIG_EXYNOS_THERMAL=y CONFIG_RCAR_GEN3_THERMAL=y +CONFIG_QCOM_TSENS=y CONFIG_ROCKCHIP_THERMAL=m +CONFIG_TEGRA_BPMP_THERMAL=m +CONFIG_UNIPHIER_THERMAL=y CONFIG_WATCHDOG=y CONFIG_S3C2410_WATCHDOG=y CONFIG_MESON_GXBB_WATCHDOG=m @@ -444,12 +466,14 @@ CONFIG_NOP_USB_XCEIV=y CONFIG_USB_ULPI=y CONFIG_USB_GADGET=y CONFIG_USB_RENESAS_USBHS_UDC=m +CONFIG_USB_RENESAS_USB3=m CONFIG_USB_ULPI_BUS=y CONFIG_MMC=y CONFIG_MMC_BLOCK_MINORS=32 CONFIG_MMC_ARMMMCI=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ACPI=y +CONFIG_MMC_SDHCI_F_SDH30=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_OF_ARASAN=y CONFIG_MMC_SDHCI_OF_ESDHC=y @@ -500,6 +524,7 @@ CONFIG_QCOM_BAM_DMA=y CONFIG_QCOM_HIDMA_MGMT=y CONFIG_QCOM_HIDMA=y CONFIG_RCAR_DMAC=y +CONFIG_RENESAS_USB_DMAC=m CONFIG_VFIO=y CONFIG_VFIO_PCI=y CONFIG_VIRTIO_PCI=y @@ -525,7 +550,9 @@ CONFIG_ARM_MHU=y CONFIG_PLATFORM_MHU=y CONFIG_BCM2835_MBOX=y CONFIG_HI6220_MBOX=y +CONFIG_QCOM_APCS_IPC=y CONFIG_ROCKCHIP_IOMMU=y +CONFIG_TEGRA_IOMMU_SMMU=y CONFIG_ARM_SMMU=y CONFIG_ARM_SMMU_V3=y CONFIG_QCOM_IOMMU=y @@ -539,7 +566,10 @@ CONFIG_ROCKCHIP_PM_DOMAINS=y CONFIG_ARCH_TEGRA_132_SOC=y CONFIG_ARCH_TEGRA_210_SOC=y CONFIG_ARCH_TEGRA_186_SOC=y +CONFIG_ARCH_TEGRA_194_SOC=y CONFIG_EXTCON_USB_GPIO=y +CONFIG_MEMORY=y +CONFIG_TEGRA_MC=y CONFIG_IIO=y CONFIG_EXYNOS_ADC=y CONFIG_ROCKCHIP_SARADC=m @@ -547,10 +577,12 @@ CONFIG_PWM=y CONFIG_PWM_BCM2835=m CONFIG_PWM_CROS_EC=m CONFIG_PWM_MESON=m +CONFIG_PWM_RCAR=m CONFIG_PWM_ROCKCHIP=y CONFIG_PWM_SAMSUNG=y CONFIG_PWM_TEGRA=m CONFIG_PHY_RCAR_GEN3_USB2=y +CONFIG_PHY_RCAR_GEN3_USB3=m CONFIG_PHY_HI6220_USB=y CONFIG_PHY_QCOM_USB_HS=y CONFIG_PHY_SUN4I_USB=y @@ -562,6 +594,8 @@ CONFIG_PHY_XGENE=y CONFIG_PHY_TEGRA_XUSB=y CONFIG_QCOM_L2_PMU=y CONFIG_QCOM_L3_PMU=y +CONFIG_MESON_EFUSE=m +CONFIG_QCOM_QFPROM=y CONFIG_UNIPHIER_EFUSE=y CONFIG_TEE=y CONFIG_OPTEE=y @@ -629,3 +663,6 @@ CONFIG_CRYPTO_AES_ARM64_CE_BLK=y CONFIG_CRYPTO_AES_ARM64_NEON_BLK=m CONFIG_CRYPTO_CHACHA20_NEON=m CONFIG_CRYPTO_AES_ARM64_BS=m +CONFIG_CRYPTO_SHA512_ARM64_CE=m +CONFIG_CRYPTO_SHA3_ARM64=m +CONFIG_CRYPTO_SM3_ARM64_CE=m diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index cdaeeea7999c..7cd2fd04b212 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -13,22 +13,20 @@ #include <linux/io.h> #include <linux/clk.h> +#include <linux/clkdev.h> +#include <linux/delay.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/pm_domain.h> #include <linux/pm_runtime.h> #include <linux/of_address.h> #include <linux/of_platform.h> +#include <linux/slab.h> + #include <linux/platform_data/ti-sysc.h> #include <dt-bindings/bus/ti-sysc.h> -enum sysc_registers { - SYSC_REVISION, - SYSC_SYSCONFIG, - SYSC_SYSSTATUS, - SYSC_MAX_REGS, -}; - static const char * const reg_names[] = { "rev", "sysc", "syss", }; enum sysc_clocks { @@ -55,6 +53,7 @@ static const char * const clock_names[] = { "fck", "ick", }; * @cfg: interconnect target module configuration * @name: name if available * @revision: interconnect target module revision + * @needs_resume: runtime resume needed on resume from suspend */ struct sysc { struct device *dev; @@ -66,8 +65,13 @@ struct sysc { const char *legacy_mode; const struct sysc_capabilities *cap; struct sysc_config cfg; + struct ti_sysc_cookie cookie; const char *name; u32 revision; + bool enabled; + bool needs_resume; + bool child_needs_resume; + struct delayed_work idle_work; }; static u32 sysc_read(struct sysc *ddata, int offset) @@ -136,9 +140,6 @@ static int sysc_get_clocks(struct sysc *ddata) { int i, error; - if (ddata->legacy_mode) - return 0; - for (i = 0; i < SYSC_MAX_CLOCKS; i++) { error = sysc_get_one_clock(ddata, i); if (error && error != -ENOENT) @@ -197,12 +198,53 @@ static int sysc_parse_and_check_child_range(struct sysc *ddata) ddata->module_pa = of_translate_address(np, ranges++); ddata->module_size = be32_to_cpup(ranges); - dev_dbg(ddata->dev, "interconnect target 0x%llx size 0x%x for %pOF\n", - ddata->module_pa, ddata->module_size, np); - return 0; } +static struct device_node *stdout_path; + +static void sysc_init_stdout_path(struct sysc *ddata) +{ + struct device_node *np = NULL; + const char *uart; + + if (IS_ERR(stdout_path)) + return; + + if (stdout_path) + return; + + np = of_find_node_by_path("/chosen"); + if (!np) + goto err; + + uart = of_get_property(np, "stdout-path", NULL); + if (!uart) + goto err; + + np = of_find_node_by_path(uart); + if (!np) + goto err; + + stdout_path = np; + + return; + +err: + stdout_path = ERR_PTR(-ENODEV); +} + +static void sysc_check_quirk_stdout(struct sysc *ddata, + struct device_node *np) +{ + sysc_init_stdout_path(ddata); + if (np != stdout_path) + return; + + ddata->cfg.quirks |= SYSC_QUIRK_NO_IDLE_ON_INIT | + SYSC_QUIRK_NO_RESET_ON_INIT; +} + /** * sysc_check_one_child - check child configuration * @ddata: device driver data @@ -221,6 +263,8 @@ static int sysc_check_one_child(struct sysc *ddata, if (name) dev_warn(ddata->dev, "really a child ti,hwmods property?"); + sysc_check_quirk_stdout(ddata, np); + return 0; } @@ -246,11 +290,8 @@ static int sysc_check_children(struct sysc *ddata) */ static void sysc_check_quirk_16bit(struct sysc *ddata, struct resource *res) { - if (resource_size(res) == 8) { - dev_dbg(ddata->dev, - "enabling 16-bit and clockactivity quirks\n"); + if (resource_size(res) == 8) ddata->cfg.quirks |= SYSC_QUIRK_16BIT | SYSC_QUIRK_USE_CLOCKACT; - } } /** @@ -276,7 +317,6 @@ static int sysc_parse_one(struct sysc *ddata, enum sysc_registers reg) res = platform_get_resource_byname(to_platform_device(ddata->dev), IORESOURCE_MEM, name); if (!res) { - dev_dbg(ddata->dev, "has no %s register\n", name); ddata->offsets[reg] = -ENODEV; return 0; @@ -437,6 +477,14 @@ static int sysc_show_reg(struct sysc *ddata, return sprintf(bufp, ":%x", ddata->offsets[reg]); } +static int sysc_show_name(char *bufp, struct sysc *ddata) +{ + if (!ddata->name) + return 0; + + return sprintf(bufp, ":%s", ddata->name); +} + /** * sysc_show_registers - show information about interconnect target module * @ddata: device driver data @@ -451,6 +499,7 @@ static void sysc_show_registers(struct sysc *ddata) bufp += sysc_show_reg(ddata, bufp, i); bufp += sysc_show_rev(bufp, ddata); + bufp += sysc_show_name(bufp, ddata); dev_dbg(ddata->dev, "%llx:%x%s\n", ddata->module_pa, ddata->module_size, @@ -459,33 +508,70 @@ static void sysc_show_registers(struct sysc *ddata) static int __maybe_unused sysc_runtime_suspend(struct device *dev) { + struct ti_sysc_platform_data *pdata; struct sysc *ddata; - int i; + int error = 0, i; ddata = dev_get_drvdata(dev); - if (ddata->legacy_mode) + if (!ddata->enabled) return 0; + if (ddata->legacy_mode) { + pdata = dev_get_platdata(ddata->dev); + if (!pdata) + return 0; + + if (!pdata->idle_module) + return -ENODEV; + + error = pdata->idle_module(dev, &ddata->cookie); + if (error) + dev_err(dev, "%s: could not idle: %i\n", + __func__, error); + + goto idled; + } + for (i = 0; i < SYSC_MAX_CLOCKS; i++) { if (IS_ERR_OR_NULL(ddata->clocks[i])) continue; clk_disable(ddata->clocks[i]); } - return 0; +idled: + ddata->enabled = false; + + return error; } static int __maybe_unused sysc_runtime_resume(struct device *dev) { + struct ti_sysc_platform_data *pdata; struct sysc *ddata; - int i, error; + int error = 0, i; ddata = dev_get_drvdata(dev); - if (ddata->legacy_mode) + if (ddata->enabled) return 0; + if (ddata->legacy_mode) { + pdata = dev_get_platdata(ddata->dev); + if (!pdata) + return 0; + + if (!pdata->enable_module) + return -ENODEV; + + error = pdata->enable_module(dev, &ddata->cookie); + if (error) + dev_err(dev, "%s: could not enable: %i\n", + __func__, error); + + goto awake; + } + for (i = 0; i < SYSC_MAX_CLOCKS; i++) { if (IS_ERR_OR_NULL(ddata->clocks[i])) continue; @@ -494,20 +580,136 @@ static int __maybe_unused sysc_runtime_resume(struct device *dev) return error; } +awake: + ddata->enabled = true; + + return error; +} + +#ifdef CONFIG_PM_SLEEP +static int sysc_suspend(struct device *dev) +{ + struct sysc *ddata; + + ddata = dev_get_drvdata(dev); + + if (!ddata->enabled) + return 0; + + ddata->needs_resume = true; + + return sysc_runtime_suspend(dev); +} + +static int sysc_resume(struct device *dev) +{ + struct sysc *ddata; + + ddata = dev_get_drvdata(dev); + if (ddata->needs_resume) { + ddata->needs_resume = false; + + return sysc_runtime_resume(dev); + } + return 0; } +#endif static const struct dev_pm_ops sysc_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(sysc_suspend, sysc_resume) SET_RUNTIME_PM_OPS(sysc_runtime_suspend, sysc_runtime_resume, NULL) }; +/* Module revision register based quirks */ +struct sysc_revision_quirk { + const char *name; + u32 base; + int rev_offset; + int sysc_offset; + int syss_offset; + u32 revision; + u32 revision_mask; + u32 quirks; +}; + +#define SYSC_QUIRK(optname, optbase, optrev, optsysc, optsyss, \ + optrev_val, optrevmask, optquirkmask) \ + { \ + .name = (optname), \ + .base = (optbase), \ + .rev_offset = (optrev), \ + .sysc_offset = (optsysc), \ + .syss_offset = (optsyss), \ + .revision = (optrev_val), \ + .revision_mask = (optrevmask), \ + .quirks = (optquirkmask), \ + } + +static const struct sysc_revision_quirk sysc_revision_quirks[] = { + /* These drivers need to be fixed to not use pm_runtime_irq_safe() */ + SYSC_QUIRK("gpio", 0, 0, 0x10, 0x114, 0x50600801, 0xffffffff, + SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK("mmu", 0, 0, 0x10, 0x14, 0x00000020, 0xffffffff, + SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK("mmu", 0, 0, 0x10, 0x14, 0x00000030, 0xffffffff, + SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK("sham", 0, 0x100, 0x110, 0x114, 0x40000c03, 0xffffffff, + SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK("smartreflex", 0, -1, 0x24, -1, 0x00000000, 0xffffffff, + SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK("smartreflex", 0, -1, 0x38, -1, 0x00000000, 0xffffffff, + SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK("timer", 0, 0, 0x10, 0x14, 0x00000015, 0xffffffff, + SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff, + SYSC_QUIRK_LEGACY_IDLE), +}; + +static void sysc_init_revision_quirks(struct sysc *ddata) +{ + const struct sysc_revision_quirk *q; + int i; + + for (i = 0; i < ARRAY_SIZE(sysc_revision_quirks); i++) { + q = &sysc_revision_quirks[i]; + + if (q->base && q->base != ddata->module_pa) + continue; + + if (q->rev_offset >= 0 && + q->rev_offset != ddata->offsets[SYSC_REVISION]) + continue; + + if (q->sysc_offset >= 0 && + q->sysc_offset != ddata->offsets[SYSC_SYSCONFIG]) + continue; + + if (q->syss_offset >= 0 && + q->syss_offset != ddata->offsets[SYSC_SYSSTATUS]) + continue; + + if (q->revision == ddata->revision || + (q->revision & q->revision_mask) == + (ddata->revision & q->revision_mask)) { + ddata->name = q->name; + ddata->cfg.quirks |= q->quirks; + } + } +} + /* At this point the module is configured enough to read the revision */ static int sysc_init_module(struct sysc *ddata) { int error; + if (ddata->cfg.quirks & SYSC_QUIRK_NO_IDLE_ON_INIT) { + ddata->revision = sysc_read_revision(ddata); + goto rev_quirks; + } + error = pm_runtime_get_sync(ddata->dev); if (error < 0) { pm_runtime_put_noidle(ddata->dev); @@ -517,6 +719,9 @@ static int sysc_init_module(struct sysc *ddata) ddata->revision = sysc_read_revision(ddata); pm_runtime_put_sync(ddata->dev); +rev_quirks: + sysc_init_revision_quirks(ddata); + return 0; } @@ -605,6 +810,196 @@ static int sysc_init_syss_mask(struct sysc *ddata) return 0; } +/* + * Many child device drivers need to have fck available to get the clock + * rate for device internal configuration. + */ +static int sysc_child_add_fck(struct sysc *ddata, + struct device *child) +{ + struct clk *fck; + struct clk_lookup *l; + const char *name = clock_names[SYSC_FCK]; + + if (IS_ERR_OR_NULL(ddata->clocks[SYSC_FCK])) + return 0; + + fck = clk_get(child, name); + if (!IS_ERR(fck)) { + clk_put(fck); + + return -EEXIST; + } + + l = clkdev_create(ddata->clocks[SYSC_FCK], name, dev_name(child)); + + return l ? 0 : -ENODEV; +} + +static struct device_type sysc_device_type = { +}; + +static struct sysc *sysc_child_to_parent(struct device *dev) +{ + struct device *parent = dev->parent; + + if (!parent || parent->type != &sysc_device_type) + return NULL; + + return dev_get_drvdata(parent); +} + +static int __maybe_unused sysc_child_runtime_suspend(struct device *dev) +{ + struct sysc *ddata; + int error; + + ddata = sysc_child_to_parent(dev); + + error = pm_generic_runtime_suspend(dev); + if (error) + return error; + + if (!ddata->enabled) + return 0; + + return sysc_runtime_suspend(ddata->dev); +} + +static int __maybe_unused sysc_child_runtime_resume(struct device *dev) +{ + struct sysc *ddata; + int error; + + ddata = sysc_child_to_parent(dev); + + if (!ddata->enabled) { + error = sysc_runtime_resume(ddata->dev); + if (error < 0) + dev_err(ddata->dev, + "%s error: %i\n", __func__, error); + } + + return pm_generic_runtime_resume(dev); +} + +#ifdef CONFIG_PM_SLEEP +static int sysc_child_suspend_noirq(struct device *dev) +{ + struct sysc *ddata; + int error; + + ddata = sysc_child_to_parent(dev); + + error = pm_generic_suspend_noirq(dev); + if (error) + return error; + + if (!pm_runtime_status_suspended(dev)) { + error = pm_generic_runtime_suspend(dev); + if (error) + return error; + + error = sysc_runtime_suspend(ddata->dev); + if (error) + return error; + + ddata->child_needs_resume = true; + } + + return 0; +} + +static int sysc_child_resume_noirq(struct device *dev) +{ + struct sysc *ddata; + int error; + + ddata = sysc_child_to_parent(dev); + + if (ddata->child_needs_resume) { + ddata->child_needs_resume = false; + + error = sysc_runtime_resume(ddata->dev); + if (error) + dev_err(ddata->dev, + "%s runtime resume error: %i\n", + __func__, error); + + error = pm_generic_runtime_resume(dev); + if (error) + dev_err(ddata->dev, + "%s generic runtime resume: %i\n", + __func__, error); + } + + return pm_generic_resume_noirq(dev); +} +#endif + +struct dev_pm_domain sysc_child_pm_domain = { + .ops = { + SET_RUNTIME_PM_OPS(sysc_child_runtime_suspend, + sysc_child_runtime_resume, + NULL) + USE_PLATFORM_PM_SLEEP_OPS + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(sysc_child_suspend_noirq, + sysc_child_resume_noirq) + } +}; + +/** + * sysc_legacy_idle_quirk - handle children in omap_device compatible way + * @ddata: device driver data + * @child: child device driver + * + * Allow idle for child devices as done with _od_runtime_suspend(). + * Otherwise many child devices will not idle because of the permanent + * parent usecount set in pm_runtime_irq_safe(). + * + * Note that the long term solution is to just modify the child device + * drivers to not set pm_runtime_irq_safe() and then this can be just + * dropped. + */ +static void sysc_legacy_idle_quirk(struct sysc *ddata, struct device *child) +{ + if (!ddata->legacy_mode) + return; + + if (ddata->cfg.quirks & SYSC_QUIRK_LEGACY_IDLE) + dev_pm_domain_set(child, &sysc_child_pm_domain); +} + +static int sysc_notifier_call(struct notifier_block *nb, + unsigned long event, void *device) +{ + struct device *dev = device; + struct sysc *ddata; + int error; + + ddata = sysc_child_to_parent(dev); + if (!ddata) + return NOTIFY_DONE; + + switch (event) { + case BUS_NOTIFY_ADD_DEVICE: + error = sysc_child_add_fck(ddata, dev); + if (error && error != -EEXIST) + dev_warn(ddata->dev, "could not add %s fck: %i\n", + dev_name(dev), error); + sysc_legacy_idle_quirk(ddata, dev); + break; + default: + break; + } + + return NOTIFY_DONE; +} + +static struct notifier_block sysc_nb = { + .notifier_call = sysc_notifier_call, +}; + /* Device tree configured quirks */ struct sysc_dts_quirk { const char *name; @@ -797,7 +1192,8 @@ static const struct sysc_capabilities sysc_34xx_sr = { .type = TI_SYSC_OMAP34XX_SR, .sysc_mask = SYSC_OMAP2_CLOCKACTIVITY, .regbits = &sysc_regbits_omap34xx_sr, - .mod_quirks = SYSC_QUIRK_USE_CLOCKACT | SYSC_QUIRK_UNCACHED, + .mod_quirks = SYSC_QUIRK_USE_CLOCKACT | SYSC_QUIRK_UNCACHED | + SYSC_QUIRK_LEGACY_IDLE, }; /* @@ -818,12 +1214,13 @@ static const struct sysc_capabilities sysc_36xx_sr = { .type = TI_SYSC_OMAP36XX_SR, .sysc_mask = SYSC_OMAP3_SR_ENAWAKEUP, .regbits = &sysc_regbits_omap36xx_sr, - .mod_quirks = SYSC_QUIRK_UNCACHED, + .mod_quirks = SYSC_QUIRK_UNCACHED | SYSC_QUIRK_LEGACY_IDLE, }; static const struct sysc_capabilities sysc_omap4_sr = { .type = TI_SYSC_OMAP4_SR, .regbits = &sysc_regbits_omap36xx_sr, + .mod_quirks = SYSC_QUIRK_LEGACY_IDLE, }; /* @@ -865,6 +1262,33 @@ static const struct sysc_capabilities sysc_omap4_usb_host_fs = { .regbits = &sysc_regbits_omap4_usb_host_fs, }; +static int sysc_init_pdata(struct sysc *ddata) +{ + struct ti_sysc_platform_data *pdata = dev_get_platdata(ddata->dev); + struct ti_sysc_module_data mdata; + int error = 0; + + if (!pdata || !ddata->legacy_mode) + return 0; + + mdata.name = ddata->legacy_mode; + mdata.module_pa = ddata->module_pa; + mdata.module_size = ddata->module_size; + mdata.offsets = ddata->offsets; + mdata.nr_offsets = SYSC_MAX_REGS; + mdata.cap = ddata->cap; + mdata.cfg = &ddata->cfg; + + if (!pdata->init_module) + return -ENODEV; + + error = pdata->init_module(ddata->dev, &mdata, &ddata->cookie); + if (error == -EEXIST) + error = 0; + + return error; +} + static int sysc_init_match(struct sysc *ddata) { const struct sysc_capabilities *cap; @@ -880,8 +1304,19 @@ static int sysc_init_match(struct sysc *ddata) return 0; } +static void ti_sysc_idle(struct work_struct *work) +{ + struct sysc *ddata; + + ddata = container_of(work, struct sysc, idle_work.work); + + if (pm_runtime_active(ddata->dev)) + pm_runtime_put_sync(ddata->dev); +} + static int sysc_probe(struct platform_device *pdev) { + struct ti_sysc_platform_data *pdata = dev_get_platdata(&pdev->dev); struct sysc *ddata; int error; @@ -920,6 +1355,10 @@ static int sysc_probe(struct platform_device *pdev) if (error) goto unprepare; + error = sysc_init_pdata(ddata); + if (error) + goto unprepare; + pm_runtime_enable(ddata->dev); error = sysc_init_module(ddata); @@ -933,22 +1372,28 @@ static int sysc_probe(struct platform_device *pdev) goto unprepare; } - pm_runtime_use_autosuspend(ddata->dev); - sysc_show_registers(ddata); + ddata->dev->type = &sysc_device_type; error = of_platform_populate(ddata->dev->of_node, - NULL, NULL, ddata->dev); + NULL, pdata ? pdata->auxdata : NULL, + ddata->dev); if (error) goto err; - pm_runtime_mark_last_busy(ddata->dev); - pm_runtime_put_autosuspend(ddata->dev); + INIT_DELAYED_WORK(&ddata->idle_work, ti_sysc_idle); + + /* At least earlycon won't survive without deferred idle */ + if (ddata->cfg.quirks & (SYSC_QUIRK_NO_IDLE_ON_INIT | + SYSC_QUIRK_NO_RESET_ON_INIT)) { + schedule_delayed_work(&ddata->idle_work, 3000); + } else { + pm_runtime_put(&pdev->dev); + } return 0; err: - pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); unprepare: @@ -962,6 +1407,8 @@ static int sysc_remove(struct platform_device *pdev) struct sysc *ddata = platform_get_drvdata(pdev); int error; + cancel_delayed_work_sync(&ddata->idle_work); + error = pm_runtime_get_sync(ddata->dev); if (error < 0) { pm_runtime_put_noidle(ddata->dev); @@ -971,7 +1418,6 @@ static int sysc_remove(struct platform_device *pdev) of_platform_depopulate(&pdev->dev); - pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); @@ -1008,7 +1454,21 @@ static struct platform_driver sysc_driver = { .pm = &sysc_pm_ops, }, }; -module_platform_driver(sysc_driver); + +static int __init sysc_init(void) +{ + bus_register_notifier(&platform_bus_type, &sysc_nb); + + return platform_driver_register(&sysc_driver); +} +module_init(sysc_init); + +static void __exit sysc_exit(void) +{ + bus_unregister_notifier(&platform_bus_type, &sysc_nb); + platform_driver_unregister(&sysc_driver); +} +module_exit(sysc_exit); MODULE_DESCRIPTION("TI sysc interconnect target driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 6021a5af21da..9ee2888275c1 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -21,6 +21,9 @@ config CLKEVT_I8253 config I8253_LOCK bool +config OMAP_DM_TIMER + bool + config CLKBLD_I8253 def_bool y if CLKSRC_I8253 || CLKEVT_I8253 || I8253_LOCK diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index f0cb07637a65..e8e76dfef00b 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_EM_TIMER_STI) += em_sti.o obj-$(CONFIG_CLKBLD_I8253) += i8253.o obj-$(CONFIG_CLKSRC_MMIO) += mmio.o obj-$(CONFIG_DIGICOLOR_TIMER) += timer-digicolor.o +obj-$(CONFIG_OMAP_DM_TIMER) += timer-ti-dm.o obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o obj-$(CONFIG_DW_APB_TIMER_OF) += dw_apb_timer_of.o obj-$(CONFIG_FTTMR010_TIMER) += timer-fttmr010.o diff --git a/arch/arm/plat-omap/dmtimer.c b/drivers/clocksource/timer-ti-dm.c index 8805a59bae53..4cce6b224b87 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/drivers/clocksource/timer-ti-dm.c @@ -47,7 +47,7 @@ #include <linux/platform_device.h> #include <linux/platform_data/dmtimer-omap.h> -#include <plat/dmtimer.h> +#include <clocksource/timer-ti-dm.h> static u32 omap_reserved_systimers; static LIST_HEAD(omap_timer_list); @@ -163,6 +163,86 @@ static int omap_dm_timer_of_set_source(struct omap_dm_timer *timer) return ret; } +static int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) +{ + int ret; + const char *parent_name; + struct clk *parent; + struct dmtimer_platform_data *pdata; + + if (unlikely(!timer) || IS_ERR(timer->fclk)) + return -EINVAL; + + switch (source) { + case OMAP_TIMER_SRC_SYS_CLK: + parent_name = "timer_sys_ck"; + break; + case OMAP_TIMER_SRC_32_KHZ: + parent_name = "timer_32k_ck"; + break; + case OMAP_TIMER_SRC_EXT_CLK: + parent_name = "timer_ext_ck"; + break; + default: + return -EINVAL; + } + + pdata = timer->pdev->dev.platform_data; + + /* + * FIXME: Used for OMAP1 devices only because they do not currently + * use the clock framework to set the parent clock. To be removed + * once OMAP1 migrated to using clock framework for dmtimers + */ + if (pdata && pdata->set_timer_src) + return pdata->set_timer_src(timer->pdev, source); + +#if defined(CONFIG_COMMON_CLK) + /* Check if the clock has configurable parents */ + if (clk_hw_get_num_parents(__clk_get_hw(timer->fclk)) < 2) + return 0; +#endif + + parent = clk_get(&timer->pdev->dev, parent_name); + if (IS_ERR(parent)) { + pr_err("%s: %s not found\n", __func__, parent_name); + return -EINVAL; + } + + ret = clk_set_parent(timer->fclk, parent); + if (ret < 0) + pr_err("%s: failed to set %s as parent\n", __func__, + parent_name); + + clk_put(parent); + + return ret; +} + +static void omap_dm_timer_enable(struct omap_dm_timer *timer) +{ + int c; + + pm_runtime_get_sync(&timer->pdev->dev); + + if (!(timer->capability & OMAP_TIMER_ALWON)) { + if (timer->get_context_loss_count) { + c = timer->get_context_loss_count(&timer->pdev->dev); + if (c != timer->ctx_loss_count) { + omap_timer_restore_context(timer); + timer->ctx_loss_count = c; + } + } else { + omap_timer_restore_context(timer); + } + } +} + +static void omap_dm_timer_disable(struct omap_dm_timer *timer) +{ + pm_runtime_put_sync(&timer->pdev->dev); +} + static int omap_dm_timer_prepare(struct omap_dm_timer *timer) { int rc; @@ -298,24 +378,22 @@ found: return timer; } -struct omap_dm_timer *omap_dm_timer_request(void) +static struct omap_dm_timer *omap_dm_timer_request(void) { return _omap_dm_timer_request(REQUEST_ANY, NULL); } -EXPORT_SYMBOL_GPL(omap_dm_timer_request); -struct omap_dm_timer *omap_dm_timer_request_specific(int id) +static struct omap_dm_timer *omap_dm_timer_request_specific(int id) { /* Requesting timer by ID is not supported when device tree is used */ if (of_have_populated_dt()) { - pr_warn("%s: Please use omap_dm_timer_request_by_cap/node()\n", + pr_warn("%s: Please use omap_dm_timer_request_by_node()\n", __func__); return NULL; } return _omap_dm_timer_request(REQUEST_BY_ID, &id); } -EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific); /** * omap_dm_timer_request_by_cap - Request a timer by capability @@ -330,7 +408,6 @@ struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap) { return _omap_dm_timer_request(REQUEST_BY_CAP, &cap); } -EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_cap); /** * omap_dm_timer_request_by_node - Request a timer by device-tree node @@ -339,16 +416,15 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_cap); * Request a timer based upon a device node pointer. Returns pointer to * timer handle on success and a NULL pointer on failure. */ -struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np) +static struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np) { if (!np) return NULL; return _omap_dm_timer_request(REQUEST_BY_NODE, np); } -EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_node); -int omap_dm_timer_free(struct omap_dm_timer *timer) +static int omap_dm_timer_free(struct omap_dm_timer *timer) { if (unlikely(!timer)) return -EINVAL; @@ -359,33 +435,6 @@ int omap_dm_timer_free(struct omap_dm_timer *timer) timer->reserved = 0; return 0; } -EXPORT_SYMBOL_GPL(omap_dm_timer_free); - -void omap_dm_timer_enable(struct omap_dm_timer *timer) -{ - int c; - - pm_runtime_get_sync(&timer->pdev->dev); - - if (!(timer->capability & OMAP_TIMER_ALWON)) { - if (timer->get_context_loss_count) { - c = timer->get_context_loss_count(&timer->pdev->dev); - if (c != timer->ctx_loss_count) { - omap_timer_restore_context(timer); - timer->ctx_loss_count = c; - } - } else { - omap_timer_restore_context(timer); - } - } -} -EXPORT_SYMBOL_GPL(omap_dm_timer_enable); - -void omap_dm_timer_disable(struct omap_dm_timer *timer) -{ - pm_runtime_put_sync(&timer->pdev->dev); -} -EXPORT_SYMBOL_GPL(omap_dm_timer_disable); int omap_dm_timer_get_irq(struct omap_dm_timer *timer) { @@ -393,10 +442,15 @@ int omap_dm_timer_get_irq(struct omap_dm_timer *timer) return timer->irq; return -EINVAL; } -EXPORT_SYMBOL_GPL(omap_dm_timer_get_irq); #if defined(CONFIG_ARCH_OMAP1) #include <mach/hardware.h> + +static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) +{ + return NULL; +} + /** * omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR * @inputmask: current value of idlect mask @@ -429,17 +483,15 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) return inputmask; } -EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask); #else -struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) +static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) { if (timer && !IS_ERR(timer->fclk)) return timer->fclk; return NULL; } -EXPORT_SYMBOL_GPL(omap_dm_timer_get_fclk); __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) { @@ -447,7 +499,6 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) return 0; } -EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask); #endif @@ -461,9 +512,8 @@ int omap_dm_timer_trigger(struct omap_dm_timer *timer) omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0); return 0; } -EXPORT_SYMBOL_GPL(omap_dm_timer_trigger); -int omap_dm_timer_start(struct omap_dm_timer *timer) +static int omap_dm_timer_start(struct omap_dm_timer *timer) { u32 l; @@ -482,9 +532,8 @@ int omap_dm_timer_start(struct omap_dm_timer *timer) timer->context.tclr = l; return 0; } -EXPORT_SYMBOL_GPL(omap_dm_timer_start); -int omap_dm_timer_stop(struct omap_dm_timer *timer) +static int omap_dm_timer_stop(struct omap_dm_timer *timer) { unsigned long rate = 0; @@ -506,73 +555,9 @@ int omap_dm_timer_stop(struct omap_dm_timer *timer) omap_dm_timer_disable(timer); return 0; } -EXPORT_SYMBOL_GPL(omap_dm_timer_stop); - -int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) -{ - int ret; - char *parent_name = NULL; - struct clk *parent; - struct dmtimer_platform_data *pdata; - - if (unlikely(!timer)) - return -EINVAL; - - pdata = timer->pdev->dev.platform_data; - - if (source < 0 || source >= 3) - return -EINVAL; - - /* - * FIXME: Used for OMAP1 devices only because they do not currently - * use the clock framework to set the parent clock. To be removed - * once OMAP1 migrated to using clock framework for dmtimers - */ - if (pdata && pdata->set_timer_src) - return pdata->set_timer_src(timer->pdev, source); - - if (IS_ERR(timer->fclk)) - return -EINVAL; - -#if defined(CONFIG_COMMON_CLK) - /* Check if the clock has configurable parents */ - if (clk_hw_get_num_parents(__clk_get_hw(timer->fclk)) < 2) - return 0; -#endif - - switch (source) { - case OMAP_TIMER_SRC_SYS_CLK: - parent_name = "timer_sys_ck"; - break; - - case OMAP_TIMER_SRC_32_KHZ: - parent_name = "timer_32k_ck"; - break; - - case OMAP_TIMER_SRC_EXT_CLK: - parent_name = "timer_ext_ck"; - break; - } - - parent = clk_get(&timer->pdev->dev, parent_name); - if (IS_ERR(parent)) { - pr_err("%s: %s not found\n", __func__, parent_name); - return -EINVAL; - } - - ret = clk_set_parent(timer->fclk, parent); - if (ret < 0) - pr_err("%s: failed to set %s as parent\n", __func__, - parent_name); - - clk_put(parent); - - return ret; -} -EXPORT_SYMBOL_GPL(omap_dm_timer_set_source); -int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, - unsigned int load) +static int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, + unsigned int load) { u32 l; @@ -595,7 +580,6 @@ int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, omap_dm_timer_disable(timer); return 0; } -EXPORT_SYMBOL_GPL(omap_dm_timer_set_load); /* Optimized set_load which removes costly spin wait in timer_start */ int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, @@ -625,10 +609,8 @@ int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, timer->context.tcrr = load; return 0; } -EXPORT_SYMBOL_GPL(omap_dm_timer_set_load_start); - -int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, - unsigned int match) +static int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, + unsigned int match) { u32 l; @@ -650,10 +632,9 @@ int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, omap_dm_timer_disable(timer); return 0; } -EXPORT_SYMBOL_GPL(omap_dm_timer_set_match); -int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, - int toggle, int trigger) +static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, + int toggle, int trigger) { u32 l; @@ -676,19 +657,19 @@ int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, omap_dm_timer_disable(timer); return 0; } -EXPORT_SYMBOL_GPL(omap_dm_timer_set_pwm); -int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler) +static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, + int prescaler) { u32 l; - if (unlikely(!timer)) + if (unlikely(!timer) || prescaler < -1 || prescaler > 7) return -EINVAL; omap_dm_timer_enable(timer); l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2)); - if (prescaler >= 0x00 && prescaler <= 0x07) { + if (prescaler >= 0) { l |= OMAP_TIMER_CTRL_PRE; l |= prescaler << 2; } @@ -699,10 +680,9 @@ int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler) omap_dm_timer_disable(timer); return 0; } -EXPORT_SYMBOL_GPL(omap_dm_timer_set_prescaler); -int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, - unsigned int value) +static int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, + unsigned int value) { if (unlikely(!timer)) return -EINVAL; @@ -716,7 +696,6 @@ int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, omap_dm_timer_disable(timer); return 0; } -EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable); /** * omap_dm_timer_set_int_disable - disable timer interrupts @@ -725,7 +704,7 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable); * * Disables the specified timer interrupts for a timer. */ -int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask) +static int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask) { u32 l = mask; @@ -747,9 +726,8 @@ int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask) omap_dm_timer_disable(timer); return 0; } -EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_disable); -unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) +static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) { unsigned int l; @@ -762,9 +740,8 @@ unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) return l; } -EXPORT_SYMBOL_GPL(omap_dm_timer_read_status); -int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) +static int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) { if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) return -EINVAL; @@ -773,9 +750,8 @@ int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) return 0; } -EXPORT_SYMBOL_GPL(omap_dm_timer_write_status); -unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) +static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) { if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) { pr_err("%s: timer not iavailable or enabled.\n", __func__); @@ -784,9 +760,8 @@ unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) return __omap_dm_timer_read_counter(timer, timer->posted); } -EXPORT_SYMBOL_GPL(omap_dm_timer_read_counter); -int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value) +static int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value) { if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) { pr_err("%s: timer not available or enabled.\n", __func__); @@ -799,7 +774,6 @@ int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value) timer->context.tcrr = value; return 0; } -EXPORT_SYMBOL_GPL(omap_dm_timer_write_counter); int omap_dm_timers_active(void) { @@ -816,7 +790,6 @@ int omap_dm_timers_active(void) } return 0; } -EXPORT_SYMBOL_GPL(omap_dm_timers_active); static const struct of_device_id omap_timer_match[]; @@ -833,14 +806,16 @@ static int omap_dm_timer_probe(struct platform_device *pdev) struct omap_dm_timer *timer; struct resource *mem, *irq; struct device *dev = &pdev->dev; - const struct of_device_id *match; const struct dmtimer_platform_data *pdata; int ret; - match = of_match_device(of_match_ptr(omap_timer_match), dev); - pdata = match ? match->data : dev->platform_data; + pdata = of_device_get_match_data(dev); + if (!pdata) + pdata = dev_get_platdata(dev); + else + dev->platform_data = (void *)pdata; - if (!pdata && !dev->of_node) { + if (!pdata) { dev_err(dev, "%s: no platform data.\n", __func__); return -ENODEV; } @@ -946,8 +921,33 @@ static int omap_dm_timer_remove(struct platform_device *pdev) return ret; } +const static struct omap_dm_timer_ops dmtimer_ops = { + .request_by_node = omap_dm_timer_request_by_node, + .request_specific = omap_dm_timer_request_specific, + .request = omap_dm_timer_request, + .set_source = omap_dm_timer_set_source, + .get_irq = omap_dm_timer_get_irq, + .set_int_enable = omap_dm_timer_set_int_enable, + .set_int_disable = omap_dm_timer_set_int_disable, + .free = omap_dm_timer_free, + .enable = omap_dm_timer_enable, + .disable = omap_dm_timer_disable, + .get_fclk = omap_dm_timer_get_fclk, + .start = omap_dm_timer_start, + .stop = omap_dm_timer_stop, + .set_load = omap_dm_timer_set_load, + .set_match = omap_dm_timer_set_match, + .set_pwm = omap_dm_timer_set_pwm, + .set_prescaler = omap_dm_timer_set_prescaler, + .read_counter = omap_dm_timer_read_counter, + .write_counter = omap_dm_timer_write_counter, + .read_status = omap_dm_timer_read_status, + .write_status = omap_dm_timer_write_status, +}; + static const struct dmtimer_platform_data omap3plus_pdata = { .timer_errata = OMAP_TIMER_ERRATA_I103_I767, + .timer_ops = &dmtimer_ops, }; static const struct of_device_id omap_timer_match[] = { diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 736ac887303c..605ec8cce67b 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -313,17 +313,6 @@ config MTD_NAND_ATMEL Enables support for NAND Flash / Smart Media Card interface on Atmel AT91 processors. -config MTD_NAND_PXA3xx - tristate "NAND support on PXA3xx and Armada 370/XP" - depends on !MTD_NAND_MARVELL - depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU - help - - This enables the driver for the NAND flash device found on - PXA3xx processors (NFCv1) and also on 32-bit Armada - platforms (XP, 370, 375, 38x, 39x) and 64-bit Armada - platforms (7K, 8K) (NFCv2). - config MTD_NAND_MARVELL tristate "NAND controller support on Marvell boards" depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \ diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 921634ba400c..c882d5ef192a 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -31,7 +31,6 @@ omap2_nand-objs := omap2.o obj-$(CONFIG_MTD_NAND_OMAP2) += omap2_nand.o obj-$(CONFIG_MTD_NAND_OMAP_BCH_BUILD) += omap_elm.o obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o -obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o obj-$(CONFIG_MTD_NAND_MARVELL) += marvell_nand.o obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o diff --git a/drivers/mtd/nand/marvell_nand.c b/drivers/mtd/nand/marvell_nand.c index 2196f2a233d6..03805f9669da 100644 --- a/drivers/mtd/nand/marvell_nand.c +++ b/drivers/mtd/nand/marvell_nand.c @@ -2520,8 +2520,7 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc, if (pdata) /* Legacy bindings support only one chip */ - ret = mtd_device_register(mtd, pdata->parts[0], - pdata->nr_parts[0]); + ret = mtd_device_register(mtd, pdata->parts, pdata->nr_parts); else ret = mtd_device_register(mtd, NULL, 0); if (ret) { diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c deleted file mode 100644 index d1979c7dbe7e..000000000000 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ /dev/null @@ -1,2105 +0,0 @@ -/* - * drivers/mtd/nand/pxa3xx_nand.c - * - * Copyright © 2005 Intel Corporation - * Copyright © 2006 Marvell International Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * See Documentation/mtd/nand/pxa3xx-nand.txt for more details. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <linux/dmaengine.h> -#include <linux/dma-mapping.h> -#include <linux/dma/pxa-dma.h> -#include <linux/delay.h> -#include <linux/clk.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/rawnand.h> -#include <linux/mtd/partitions.h> -#include <linux/io.h> -#include <linux/iopoll.h> -#include <linux/irq.h> -#include <linux/slab.h> -#include <linux/of.h> -#include <linux/of_device.h> -#include <linux/platform_data/mtd-nand-pxa3xx.h> -#include <linux/mfd/syscon.h> -#include <linux/regmap.h> - -#define CHIP_DELAY_TIMEOUT msecs_to_jiffies(200) -#define NAND_STOP_DELAY msecs_to_jiffies(40) -#define PAGE_CHUNK_SIZE (2048) - -/* - * Define a buffer size for the initial command that detects the flash device: - * STATUS, READID and PARAM. - * ONFI param page is 256 bytes, and there are three redundant copies - * to be read. JEDEC param page is 512 bytes, and there are also three - * redundant copies to be read. - * Hence this buffer should be at least 512 x 3. Let's pick 2048. - */ -#define INIT_BUFFER_SIZE 2048 - -/* System control register and bit to enable NAND on some SoCs */ -#define GENCONF_SOC_DEVICE_MUX 0x208 -#define GENCONF_SOC_DEVICE_MUX_NFC_EN BIT(0) - -/* registers and bit definitions */ -#define NDCR (0x00) /* Control register */ -#define NDTR0CS0 (0x04) /* Timing Parameter 0 for CS0 */ -#define NDTR1CS0 (0x0C) /* Timing Parameter 1 for CS0 */ -#define NDSR (0x14) /* Status Register */ -#define NDPCR (0x18) /* Page Count Register */ -#define NDBDR0 (0x1C) /* Bad Block Register 0 */ -#define NDBDR1 (0x20) /* Bad Block Register 1 */ -#define NDECCCTRL (0x28) /* ECC control */ -#define NDDB (0x40) /* Data Buffer */ -#define NDCB0 (0x48) /* Command Buffer0 */ -#define NDCB1 (0x4C) /* Command Buffer1 */ -#define NDCB2 (0x50) /* Command Buffer2 */ - -#define NDCR_SPARE_EN (0x1 << 31) -#define NDCR_ECC_EN (0x1 << 30) -#define NDCR_DMA_EN (0x1 << 29) -#define NDCR_ND_RUN (0x1 << 28) -#define NDCR_DWIDTH_C (0x1 << 27) -#define NDCR_DWIDTH_M (0x1 << 26) -#define NDCR_PAGE_SZ (0x1 << 24) -#define NDCR_NCSX (0x1 << 23) -#define NDCR_ND_MODE (0x3 << 21) -#define NDCR_NAND_MODE (0x0) -#define NDCR_CLR_PG_CNT (0x1 << 20) -#define NFCV1_NDCR_ARB_CNTL (0x1 << 19) -#define NFCV2_NDCR_STOP_ON_UNCOR (0x1 << 19) -#define NDCR_RD_ID_CNT_MASK (0x7 << 16) -#define NDCR_RD_ID_CNT(x) (((x) << 16) & NDCR_RD_ID_CNT_MASK) - -#define NDCR_RA_START (0x1 << 15) -#define NDCR_PG_PER_BLK (0x1 << 14) -#define NDCR_ND_ARB_EN (0x1 << 12) -#define NDCR_INT_MASK (0xFFF) - -#define NDSR_MASK (0xfff) -#define NDSR_ERR_CNT_OFF (16) -#define NDSR_ERR_CNT_MASK (0x1f) -#define NDSR_ERR_CNT(sr) ((sr >> NDSR_ERR_CNT_OFF) & NDSR_ERR_CNT_MASK) -#define NDSR_RDY (0x1 << 12) -#define NDSR_FLASH_RDY (0x1 << 11) -#define NDSR_CS0_PAGED (0x1 << 10) -#define NDSR_CS1_PAGED (0x1 << 9) -#define NDSR_CS0_CMDD (0x1 << 8) -#define NDSR_CS1_CMDD (0x1 << 7) -#define NDSR_CS0_BBD (0x1 << 6) -#define NDSR_CS1_BBD (0x1 << 5) -#define NDSR_UNCORERR (0x1 << 4) -#define NDSR_CORERR (0x1 << 3) -#define NDSR_WRDREQ (0x1 << 2) -#define NDSR_RDDREQ (0x1 << 1) -#define NDSR_WRCMDREQ (0x1) - -#define NDCB0_LEN_OVRD (0x1 << 28) -#define NDCB0_ST_ROW_EN (0x1 << 26) -#define NDCB0_AUTO_RS (0x1 << 25) -#define NDCB0_CSEL (0x1 << 24) -#define NDCB0_EXT_CMD_TYPE_MASK (0x7 << 29) -#define NDCB0_EXT_CMD_TYPE(x) (((x) << 29) & NDCB0_EXT_CMD_TYPE_MASK) -#define NDCB0_CMD_TYPE_MASK (0x7 << 21) -#define NDCB0_CMD_TYPE(x) (((x) << 21) & NDCB0_CMD_TYPE_MASK) -#define NDCB0_NC (0x1 << 20) -#define NDCB0_DBC (0x1 << 19) -#define NDCB0_ADDR_CYC_MASK (0x7 << 16) -#define NDCB0_ADDR_CYC(x) (((x) << 16) & NDCB0_ADDR_CYC_MASK) -#define NDCB0_CMD2_MASK (0xff << 8) -#define NDCB0_CMD1_MASK (0xff) -#define NDCB0_ADDR_CYC_SHIFT (16) - -#define EXT_CMD_TYPE_DISPATCH 6 /* Command dispatch */ -#define EXT_CMD_TYPE_NAKED_RW 5 /* Naked read or Naked write */ -#define EXT_CMD_TYPE_READ 4 /* Read */ -#define EXT_CMD_TYPE_DISP_WR 4 /* Command dispatch with write */ -#define EXT_CMD_TYPE_FINAL 3 /* Final command */ -#define EXT_CMD_TYPE_LAST_RW 1 /* Last naked read/write */ -#define EXT_CMD_TYPE_MONO 0 /* Monolithic read/write */ - -/* - * This should be large enough to read 'ONFI' and 'JEDEC'. - * Let's use 7 bytes, which is the maximum ID count supported - * by the controller (see NDCR_RD_ID_CNT_MASK). - */ -#define READ_ID_BYTES 7 - -/* macros for registers read/write */ -#define nand_writel(info, off, val) \ - do { \ - dev_vdbg(&info->pdev->dev, \ - "%s():%d nand_writel(0x%x, 0x%04x)\n", \ - __func__, __LINE__, (val), (off)); \ - writel_relaxed((val), (info)->mmio_base + (off)); \ - } while (0) - -#define nand_readl(info, off) \ - ({ \ - unsigned int _v; \ - _v = readl_relaxed((info)->mmio_base + (off)); \ - dev_vdbg(&info->pdev->dev, \ - "%s():%d nand_readl(0x%04x) = 0x%x\n", \ - __func__, __LINE__, (off), _v); \ - _v; \ - }) - -/* error code and state */ -enum { - ERR_NONE = 0, - ERR_DMABUSERR = -1, - ERR_SENDCMD = -2, - ERR_UNCORERR = -3, - ERR_BBERR = -4, - ERR_CORERR = -5, -}; - -enum { - STATE_IDLE = 0, - STATE_PREPARED, - STATE_CMD_HANDLE, - STATE_DMA_READING, - STATE_DMA_WRITING, - STATE_DMA_DONE, - STATE_PIO_READING, - STATE_PIO_WRITING, - STATE_CMD_DONE, - STATE_READY, -}; - -enum pxa3xx_nand_variant { - PXA3XX_NAND_VARIANT_PXA, - PXA3XX_NAND_VARIANT_ARMADA370, - PXA3XX_NAND_VARIANT_ARMADA_8K, -}; - -struct pxa3xx_nand_host { - struct nand_chip chip; - void *info_data; - - /* page size of attached chip */ - int use_ecc; - int cs; - - /* calculated from pxa3xx_nand_flash data */ - unsigned int col_addr_cycles; - unsigned int row_addr_cycles; -}; - -struct pxa3xx_nand_info { - struct nand_hw_control controller; - struct platform_device *pdev; - - struct clk *clk; - void __iomem *mmio_base; - unsigned long mmio_phys; - struct completion cmd_complete, dev_ready; - - unsigned int buf_start; - unsigned int buf_count; - unsigned int buf_size; - unsigned int data_buff_pos; - unsigned int oob_buff_pos; - - /* DMA information */ - struct scatterlist sg; - enum dma_data_direction dma_dir; - struct dma_chan *dma_chan; - dma_cookie_t dma_cookie; - int drcmr_dat; - - unsigned char *data_buff; - unsigned char *oob_buff; - dma_addr_t data_buff_phys; - int data_dma_ch; - - struct pxa3xx_nand_host *host[NUM_CHIP_SELECT]; - unsigned int state; - - /* - * This driver supports NFCv1 (as found in PXA SoC) - * and NFCv2 (as found in Armada 370/XP SoC). - */ - enum pxa3xx_nand_variant variant; - - int cs; - int use_ecc; /* use HW ECC ? */ - int ecc_bch; /* using BCH ECC? */ - int use_dma; /* use DMA ? */ - int use_spare; /* use spare ? */ - int need_wait; - - /* Amount of real data per full chunk */ - unsigned int chunk_size; - - /* Amount of spare data per full chunk */ - unsigned int spare_size; - - /* Number of full chunks (i.e chunk_size + spare_size) */ - unsigned int nfullchunks; - - /* - * Total number of chunks. If equal to nfullchunks, then there - * are only full chunks. Otherwise, there is one last chunk of - * size (last_chunk_size + last_spare_size) - */ - unsigned int ntotalchunks; - - /* Amount of real data in the last chunk */ - unsigned int last_chunk_size; - - /* Amount of spare data in the last chunk */ - unsigned int last_spare_size; - - unsigned int ecc_size; - unsigned int ecc_err_cnt; - unsigned int max_bitflips; - int retcode; - - /* - * Variables only valid during command - * execution. step_chunk_size and step_spare_size is the - * amount of real data and spare data in the current - * chunk. cur_chunk is the current chunk being - * read/programmed. - */ - unsigned int step_chunk_size; - unsigned int step_spare_size; - unsigned int cur_chunk; - - /* cached register value */ - uint32_t reg_ndcr; - uint32_t ndtr0cs0; - uint32_t ndtr1cs0; - - /* generated NDCBx register values */ - uint32_t ndcb0; - uint32_t ndcb1; - uint32_t ndcb2; - uint32_t ndcb3; -}; - -static bool use_dma = 1; -module_param(use_dma, bool, 0444); -MODULE_PARM_DESC(use_dma, "enable DMA for data transferring to/from NAND HW"); - -struct pxa3xx_nand_timing { - unsigned int tCH; /* Enable signal hold time */ - unsigned int tCS; /* Enable signal setup time */ - unsigned int tWH; /* ND_nWE high duration */ - unsigned int tWP; /* ND_nWE pulse time */ - unsigned int tRH; /* ND_nRE high duration */ - unsigned int tRP; /* ND_nRE pulse width */ - unsigned int tR; /* ND_nWE high to ND_nRE low for read */ - unsigned int tWHR; /* ND_nWE high to ND_nRE low for status read */ - unsigned int tAR; /* ND_ALE low to ND_nRE low delay */ -}; - -struct pxa3xx_nand_flash { - uint32_t chip_id; - unsigned int flash_width; /* Width of Flash memory (DWIDTH_M) */ - unsigned int dfc_width; /* Width of flash controller(DWIDTH_C) */ - struct pxa3xx_nand_timing *timing; /* NAND Flash timing */ -}; - -static struct pxa3xx_nand_timing timing[] = { - { 40, 80, 60, 100, 80, 100, 90000, 400, 40, }, - { 10, 0, 20, 40, 30, 40, 11123, 110, 10, }, - { 10, 25, 15, 25, 15, 30, 25000, 60, 10, }, - { 10, 35, 15, 25, 15, 25, 25000, 60, 10, }, -}; - -static struct pxa3xx_nand_flash builtin_flash_types[] = { - { 0x46ec, 16, 16, &timing[1] }, - { 0xdaec, 8, 8, &timing[1] }, - { 0xd7ec, 8, 8, &timing[1] }, - { 0xa12c, 8, 8, &timing[2] }, - { 0xb12c, 16, 16, &timing[2] }, - { 0xdc2c, 8, 8, &timing[2] }, - { 0xcc2c, 16, 16, &timing[2] }, - { 0xba20, 16, 16, &timing[3] }, -}; - -static int pxa3xx_ooblayout_ecc(struct mtd_info *mtd, int section, - struct mtd_oob_region *oobregion) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - struct pxa3xx_nand_host *host = nand_get_controller_data(chip); - struct pxa3xx_nand_info *info = host->info_data; - int nchunks = mtd->writesize / info->chunk_size; - - if (section >= nchunks) - return -ERANGE; - - oobregion->offset = ((info->ecc_size + info->spare_size) * section) + - info->spare_size; - oobregion->length = info->ecc_size; - - return 0; -} - -static int pxa3xx_ooblayout_free(struct mtd_info *mtd, int section, - struct mtd_oob_region *oobregion) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - struct pxa3xx_nand_host *host = nand_get_controller_data(chip); - struct pxa3xx_nand_info *info = host->info_data; - int nchunks = mtd->writesize / info->chunk_size; - - if (section >= nchunks) - return -ERANGE; - - if (!info->spare_size) - return 0; - - oobregion->offset = section * (info->ecc_size + info->spare_size); - oobregion->length = info->spare_size; - if (!section) { - /* - * Bootrom looks in bytes 0 & 5 for bad blocks for the - * 4KB page / 4bit BCH combination. - */ - if (mtd->writesize == 4096 && info->chunk_size == 2048) { - oobregion->offset += 6; - oobregion->length -= 6; - } else { - oobregion->offset += 2; - oobregion->length -= 2; - } - } - - return 0; -} - -static const struct mtd_ooblayout_ops pxa3xx_ooblayout_ops = { - .ecc = pxa3xx_ooblayout_ecc, - .free = pxa3xx_ooblayout_free, -}; - -static u8 bbt_pattern[] = {'M', 'V', 'B', 'b', 't', '0' }; -static u8 bbt_mirror_pattern[] = {'1', 't', 'b', 'B', 'V', 'M' }; - -static struct nand_bbt_descr bbt_main_descr = { - .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE - | NAND_BBT_2BIT | NAND_BBT_VERSION, - .offs = 8, - .len = 6, - .veroffs = 14, - .maxblocks = 8, /* Last 8 blocks in each chip */ - .pattern = bbt_pattern -}; - -static struct nand_bbt_descr bbt_mirror_descr = { - .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE - | NAND_BBT_2BIT | NAND_BBT_VERSION, - .offs = 8, - .len = 6, - .veroffs = 14, - .maxblocks = 8, /* Last 8 blocks in each chip */ - .pattern = bbt_mirror_pattern -}; - -#define NDTR0_tCH(c) (min((c), 7) << 19) -#define NDTR0_tCS(c) (min((c), 7) << 16) -#define NDTR0_tWH(c) (min((c), 7) << 11) -#define NDTR0_tWP(c) (min((c), 7) << 8) -#define NDTR0_tRH(c) (min((c), 7) << 3) -#define NDTR0_tRP(c) (min((c), 7) << 0) - -#define NDTR1_tR(c) (min((c), 65535) << 16) -#define NDTR1_tWHR(c) (min((c), 15) << 4) -#define NDTR1_tAR(c) (min((c), 15) << 0) - -/* convert nano-seconds to nand flash controller clock cycles */ -#define ns2cycle(ns, clk) (int)((ns) * (clk / 1000000) / 1000) - -static const struct of_device_id pxa3xx_nand_dt_ids[] = { - { - .compatible = "marvell,pxa3xx-nand", - .data = (void *)PXA3XX_NAND_VARIANT_PXA, - }, - { - .compatible = "marvell,armada370-nand", - .data = (void *)PXA3XX_NAND_VARIANT_ARMADA370, - }, - { - .compatible = "marvell,armada-8k-nand", - .data = (void *)PXA3XX_NAND_VARIANT_ARMADA_8K, - }, - {} -}; -MODULE_DEVICE_TABLE(of, pxa3xx_nand_dt_ids); - -static enum pxa3xx_nand_variant -pxa3xx_nand_get_variant(struct platform_device *pdev) -{ - const struct of_device_id *of_id = - of_match_device(pxa3xx_nand_dt_ids, &pdev->dev); - if (!of_id) - return PXA3XX_NAND_VARIANT_PXA; - return (enum pxa3xx_nand_variant)of_id->data; -} - -static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host, - const struct pxa3xx_nand_timing *t) -{ - struct pxa3xx_nand_info *info = host->info_data; - unsigned long nand_clk = clk_get_rate(info->clk); - uint32_t ndtr0, ndtr1; - - ndtr0 = NDTR0_tCH(ns2cycle(t->tCH, nand_clk)) | - NDTR0_tCS(ns2cycle(t->tCS, nand_clk)) | - NDTR0_tWH(ns2cycle(t->tWH, nand_clk)) | - NDTR0_tWP(ns2cycle(t->tWP, nand_clk)) | - NDTR0_tRH(ns2cycle(t->tRH, nand_clk)) | - NDTR0_tRP(ns2cycle(t->tRP, nand_clk)); - - ndtr1 = NDTR1_tR(ns2cycle(t->tR, nand_clk)) | - NDTR1_tWHR(ns2cycle(t->tWHR, nand_clk)) | - NDTR1_tAR(ns2cycle(t->tAR, nand_clk)); - - info->ndtr0cs0 = ndtr0; - info->ndtr1cs0 = ndtr1; - nand_writel(info, NDTR0CS0, ndtr0); - nand_writel(info, NDTR1CS0, ndtr1); -} - -static void pxa3xx_nand_set_sdr_timing(struct pxa3xx_nand_host *host, - const struct nand_sdr_timings *t) -{ - struct pxa3xx_nand_info *info = host->info_data; - struct nand_chip *chip = &host->chip; - unsigned long nand_clk = clk_get_rate(info->clk); - uint32_t ndtr0, ndtr1; - - u32 tCH_min = DIV_ROUND_UP(t->tCH_min, 1000); - u32 tCS_min = DIV_ROUND_UP(t->tCS_min, 1000); - u32 tWH_min = DIV_ROUND_UP(t->tWH_min, 1000); - u32 tWP_min = DIV_ROUND_UP(t->tWC_min - t->tWH_min, 1000); - u32 tREH_min = DIV_ROUND_UP(t->tREH_min, 1000); - u32 tRP_min = DIV_ROUND_UP(t->tRC_min - t->tREH_min, 1000); - u32 tR = chip->chip_delay * 1000; - u32 tWHR_min = DIV_ROUND_UP(t->tWHR_min, 1000); - u32 tAR_min = DIV_ROUND_UP(t->tAR_min, 1000); - - /* fallback to a default value if tR = 0 */ - if (!tR) - tR = 20000; - - ndtr0 = NDTR0_tCH(ns2cycle(tCH_min, nand_clk)) | - NDTR0_tCS(ns2cycle(tCS_min, nand_clk)) | - NDTR0_tWH(ns2cycle(tWH_min, nand_clk)) | - NDTR0_tWP(ns2cycle(tWP_min, nand_clk)) | - NDTR0_tRH(ns2cycle(tREH_min, nand_clk)) | - NDTR0_tRP(ns2cycle(tRP_min, nand_clk)); - - ndtr1 = NDTR1_tR(ns2cycle(tR, nand_clk)) | - NDTR1_tWHR(ns2cycle(tWHR_min, nand_clk)) | - NDTR1_tAR(ns2cycle(tAR_min, nand_clk)); - - info->ndtr0cs0 = ndtr0; - info->ndtr1cs0 = ndtr1; - nand_writel(info, NDTR0CS0, ndtr0); - nand_writel(info, NDTR1CS0, ndtr1); -} - -static int pxa3xx_nand_init_timings_compat(struct pxa3xx_nand_host *host, - unsigned int *flash_width, - unsigned int *dfc_width) -{ - struct nand_chip *chip = &host->chip; - struct pxa3xx_nand_info *info = host->info_data; - const struct pxa3xx_nand_flash *f = NULL; - int i, id, ntypes; - u8 idbuf[2]; - - ntypes = ARRAY_SIZE(builtin_flash_types); - - nand_readid_op(chip, 0, idbuf, sizeof(idbuf)); - id = idbuf[0] | (idbuf[1] << 8); - - for (i = 0; i < ntypes; i++) { - f = &builtin_flash_types[i]; - - if (f->chip_id == id) - break; - } - - if (i == ntypes) { - dev_err(&info->pdev->dev, "Error: timings not found\n"); - return -EINVAL; - } - - pxa3xx_nand_set_timing(host, f->timing); - - *flash_width = f->flash_width; - *dfc_width = f->dfc_width; - - return 0; -} - -static int pxa3xx_nand_init_timings_onfi(struct pxa3xx_nand_host *host, - int mode) -{ - const struct nand_sdr_timings *timings; - - mode = fls(mode) - 1; - if (mode < 0) - mode = 0; - - timings = onfi_async_timing_mode_to_sdr_timings(mode); - if (IS_ERR(timings)) - return PTR_ERR(timings); - - pxa3xx_nand_set_sdr_timing(host, timings); - - return 0; -} - -static int pxa3xx_nand_init(struct pxa3xx_nand_host *host) -{ - struct nand_chip *chip = &host->chip; - struct pxa3xx_nand_info *info = host->info_data; - unsigned int flash_width = 0, dfc_width = 0; - int mode, err; - - mode = onfi_get_async_timing_mode(chip); - if (mode == ONFI_TIMING_MODE_UNKNOWN) { - err = pxa3xx_nand_init_timings_compat(host, &flash_width, - &dfc_width); - if (err) - return err; - - if (flash_width == 16) { - info->reg_ndcr |= NDCR_DWIDTH_M; - chip->options |= NAND_BUSWIDTH_16; - } - - info->reg_ndcr |= (dfc_width == 16) ? NDCR_DWIDTH_C : 0; - } else { - err = pxa3xx_nand_init_timings_onfi(host, mode); - if (err) - return err; - } - - return 0; -} - -/** - * NOTE: it is a must to set ND_RUN firstly, then write - * command buffer, otherwise, it does not work. - * We enable all the interrupt at the same time, and - * let pxa3xx_nand_irq to handle all logic. - */ -static void pxa3xx_nand_start(struct pxa3xx_nand_info *info) -{ - uint32_t ndcr; - - ndcr = info->reg_ndcr; - - if (info->use_ecc) { - ndcr |= NDCR_ECC_EN; - if (info->ecc_bch) - nand_writel(info, NDECCCTRL, 0x1); - } else { - ndcr &= ~NDCR_ECC_EN; - if (info->ecc_bch) - nand_writel(info, NDECCCTRL, 0x0); - } - - if (info->use_dma) - ndcr |= NDCR_DMA_EN; - else - ndcr &= ~NDCR_DMA_EN; - - if (info->use_spare) - ndcr |= NDCR_SPARE_EN; - else - ndcr &= ~NDCR_SPARE_EN; - - ndcr |= NDCR_ND_RUN; - - /* clear status bits and run */ - nand_writel(info, NDSR, NDSR_MASK); - nand_writel(info, NDCR, 0); - nand_writel(info, NDCR, ndcr); -} - -static void pxa3xx_nand_stop(struct pxa3xx_nand_info *info) -{ - uint32_t ndcr; - int timeout = NAND_STOP_DELAY; - - /* wait RUN bit in NDCR become 0 */ - ndcr = nand_readl(info, NDCR); - while ((ndcr & NDCR_ND_RUN) && (timeout-- > 0)) { - ndcr = nand_readl(info, NDCR); - udelay(1); - } - - if (timeout <= 0) { - ndcr &= ~NDCR_ND_RUN; - nand_writel(info, NDCR, ndcr); - } - if (info->dma_chan) - dmaengine_terminate_all(info->dma_chan); - - /* clear status bits */ - nand_writel(info, NDSR, NDSR_MASK); -} - -static void __maybe_unused -enable_int(struct pxa3xx_nand_info *info, uint32_t int_mask) -{ - uint32_t ndcr; - - ndcr = nand_readl(info, NDCR); - nand_writel(info, NDCR, ndcr & ~int_mask); -} - -static void disable_int(struct pxa3xx_nand_info *info, uint32_t int_mask) -{ - uint32_t ndcr; - - ndcr = nand_readl(info, NDCR); - nand_writel(info, NDCR, ndcr | int_mask); -} - -static void drain_fifo(struct pxa3xx_nand_info *info, void *data, int len) -{ - if (info->ecc_bch) { - u32 val; - int ret; - - /* - * According to the datasheet, when reading from NDDB - * with BCH enabled, after each 32 bytes reads, we - * have to make sure that the NDSR.RDDREQ bit is set. - * - * Drain the FIFO 8 32 bits reads at a time, and skip - * the polling on the last read. - */ - while (len > 8) { - ioread32_rep(info->mmio_base + NDDB, data, 8); - - ret = readl_relaxed_poll_timeout(info->mmio_base + NDSR, val, - val & NDSR_RDDREQ, 1000, 5000); - if (ret) { - dev_err(&info->pdev->dev, - "Timeout on RDDREQ while draining the FIFO\n"); - return; - } - - data += 32; - len -= 8; - } - } - - ioread32_rep(info->mmio_base + NDDB, data, len); -} - -static void handle_data_pio(struct pxa3xx_nand_info *info) -{ - switch (info->state) { - case STATE_PIO_WRITING: - if (info->step_chunk_size) - writesl(info->mmio_base + NDDB, - info->data_buff + info->data_buff_pos, - DIV_ROUND_UP(info->step_chunk_size, 4)); - - if (info->step_spare_size) - writesl(info->mmio_base + NDDB, - info->oob_buff + info->oob_buff_pos, - DIV_ROUND_UP(info->step_spare_size, 4)); - break; - case STATE_PIO_READING: - if (info->step_chunk_size) - drain_fifo(info, - info->data_buff + info->data_buff_pos, - DIV_ROUND_UP(info->step_chunk_size, 4)); - - if (info->step_spare_size) - drain_fifo(info, - info->oob_buff + info->oob_buff_pos, - DIV_ROUND_UP(info->step_spare_size, 4)); - break; - default: - dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__, - info->state); - BUG(); - } - - /* Update buffer pointers for multi-page read/write */ - info->data_buff_pos += info->step_chunk_size; - info->oob_buff_pos += info->step_spare_size; -} - -static void pxa3xx_nand_data_dma_irq(void *data) -{ - struct pxa3xx_nand_info *info = data; - struct dma_tx_state state; - enum dma_status status; - - status = dmaengine_tx_status(info->dma_chan, info->dma_cookie, &state); - if (likely(status == DMA_COMPLETE)) { - info->state = STATE_DMA_DONE; - } else { - dev_err(&info->pdev->dev, "DMA error on data channel\n"); - info->retcode = ERR_DMABUSERR; - } - dma_unmap_sg(info->dma_chan->device->dev, &info->sg, 1, info->dma_dir); - - nand_writel(info, NDSR, NDSR_WRDREQ | NDSR_RDDREQ); - enable_int(info, NDCR_INT_MASK); -} - -static void start_data_dma(struct pxa3xx_nand_info *info) -{ - enum dma_transfer_direction direction; - struct dma_async_tx_descriptor *tx; - - switch (info->state) { - case STATE_DMA_WRITING: - info->dma_dir = DMA_TO_DEVICE; - direction = DMA_MEM_TO_DEV; - break; - case STATE_DMA_READING: - info->dma_dir = DMA_FROM_DEVICE; - direction = DMA_DEV_TO_MEM; - break; - default: - dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__, - info->state); - BUG(); - } - info->sg.length = info->chunk_size; - if (info->use_spare) - info->sg.length += info->spare_size + info->ecc_size; - dma_map_sg(info->dma_chan->device->dev, &info->sg, 1, info->dma_dir); - - tx = dmaengine_prep_slave_sg(info->dma_chan, &info->sg, 1, direction, - DMA_PREP_INTERRUPT); - if (!tx) { - dev_err(&info->pdev->dev, "prep_slave_sg() failed\n"); - return; - } - tx->callback = pxa3xx_nand_data_dma_irq; - tx->callback_param = info; - info->dma_cookie = dmaengine_submit(tx); - dma_async_issue_pending(info->dma_chan); - dev_dbg(&info->pdev->dev, "%s(dir=%d cookie=%x size=%u)\n", - __func__, direction, info->dma_cookie, info->sg.length); -} - -static irqreturn_t pxa3xx_nand_irq_thread(int irq, void *data) -{ - struct pxa3xx_nand_info *info = data; - - handle_data_pio(info); - - info->state = STATE_CMD_DONE; - nand_writel(info, NDSR, NDSR_WRDREQ | NDSR_RDDREQ); - - return IRQ_HANDLED; -} - -static irqreturn_t pxa3xx_nand_irq(int irq, void *devid) -{ - struct pxa3xx_nand_info *info = devid; - unsigned int status, is_completed = 0, is_ready = 0; - unsigned int ready, cmd_done; - irqreturn_t ret = IRQ_HANDLED; - - if (info->cs == 0) { - ready = NDSR_FLASH_RDY; - cmd_done = NDSR_CS0_CMDD; - } else { - ready = NDSR_RDY; - cmd_done = NDSR_CS1_CMDD; - } - - status = nand_readl(info, NDSR); - - if (status & NDSR_UNCORERR) - info->retcode = ERR_UNCORERR; - if (status & NDSR_CORERR) { - info->retcode = ERR_CORERR; - if ((info->variant == PXA3XX_NAND_VARIANT_ARMADA370 || - info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K) && - info->ecc_bch) - info->ecc_err_cnt = NDSR_ERR_CNT(status); - else - info->ecc_err_cnt = 1; - - /* - * Each chunk composing a page is corrected independently, - * and we need to store maximum number of corrected bitflips - * to return it to the MTD layer in ecc.read_page(). - */ - info->max_bitflips = max_t(unsigned int, - info->max_bitflips, - info->ecc_err_cnt); - } - if (status & (NDSR_RDDREQ | NDSR_WRDREQ)) { - /* whether use dma to transfer data */ - if (info->use_dma) { - disable_int(info, NDCR_INT_MASK); - info->state = (status & NDSR_RDDREQ) ? - STATE_DMA_READING : STATE_DMA_WRITING; - start_data_dma(info); - goto NORMAL_IRQ_EXIT; - } else { - info->state = (status & NDSR_RDDREQ) ? - STATE_PIO_READING : STATE_PIO_WRITING; - ret = IRQ_WAKE_THREAD; - goto NORMAL_IRQ_EXIT; - } - } - if (status & cmd_done) { - info->state = STATE_CMD_DONE; - is_completed = 1; - } - if (status & ready) { - info->state = STATE_READY; - is_ready = 1; - } - - /* - * Clear all status bit before issuing the next command, which - * can and will alter the status bits and will deserve a new - * interrupt on its own. This lets the controller exit the IRQ - */ - nand_writel(info, NDSR, status); - - if (status & NDSR_WRCMDREQ) { - status &= ~NDSR_WRCMDREQ; - info->state = STATE_CMD_HANDLE; - - /* - * Command buffer registers NDCB{0-2} (and optionally NDCB3) - * must be loaded by writing directly either 12 or 16 - * bytes directly to NDCB0, four bytes at a time. - * - * Direct write access to NDCB1, NDCB2 and NDCB3 is ignored - * but each NDCBx register can be read. - */ - nand_writel(info, NDCB0, info->ndcb0); - nand_writel(info, NDCB0, info->ndcb1); - nand_writel(info, NDCB0, info->ndcb2); - - /* NDCB3 register is available in NFCv2 (Armada 370/XP SoC) */ - if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 || - info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K) - nand_writel(info, NDCB0, info->ndcb3); - } - - if (is_completed) - complete(&info->cmd_complete); - if (is_ready) - complete(&info->dev_ready); -NORMAL_IRQ_EXIT: - return ret; -} - -static inline int is_buf_blank(uint8_t *buf, size_t len) -{ - for (; len > 0; len--) - if (*buf++ != 0xff) - return 0; - return 1; -} - -static void set_command_address(struct pxa3xx_nand_info *info, - unsigned int page_size, uint16_t column, int page_addr) -{ - /* small page addr setting */ - if (page_size < PAGE_CHUNK_SIZE) { - info->ndcb1 = ((page_addr & 0xFFFFFF) << 8) - | (column & 0xFF); - - info->ndcb2 = 0; - } else { - info->ndcb1 = ((page_addr & 0xFFFF) << 16) - | (column & 0xFFFF); - - if (page_addr & 0xFF0000) - info->ndcb2 = (page_addr & 0xFF0000) >> 16; - else - info->ndcb2 = 0; - } -} - -static void prepare_start_command(struct pxa3xx_nand_info *info, int command) -{ - struct pxa3xx_nand_host *host = info->host[info->cs]; - struct mtd_info *mtd = nand_to_mtd(&host->chip); - - /* reset data and oob column point to handle data */ - info->buf_start = 0; - info->buf_count = 0; - info->data_buff_pos = 0; - info->oob_buff_pos = 0; - info->step_chunk_size = 0; - info->step_spare_size = 0; - info->cur_chunk = 0; - info->use_ecc = 0; - info->use_spare = 1; - info->retcode = ERR_NONE; - info->ecc_err_cnt = 0; - info->ndcb3 = 0; - info->need_wait = 0; - - switch (command) { - case NAND_CMD_READ0: - case NAND_CMD_READOOB: - case NAND_CMD_PAGEPROG: - info->use_ecc = 1; - break; - case NAND_CMD_PARAM: - info->use_spare = 0; - break; - default: - info->ndcb1 = 0; - info->ndcb2 = 0; - break; - } - - /* - * If we are about to issue a read command, or about to set - * the write address, then clean the data buffer. - */ - if (command == NAND_CMD_READ0 || - command == NAND_CMD_READOOB || - command == NAND_CMD_SEQIN) { - - info->buf_count = mtd->writesize + mtd->oobsize; - memset(info->data_buff, 0xFF, info->buf_count); - } - -} - -static int prepare_set_command(struct pxa3xx_nand_info *info, int command, - int ext_cmd_type, uint16_t column, int page_addr) -{ - int addr_cycle, exec_cmd; - struct pxa3xx_nand_host *host; - struct mtd_info *mtd; - - host = info->host[info->cs]; - mtd = nand_to_mtd(&host->chip); - addr_cycle = 0; - exec_cmd = 1; - - if (info->cs != 0) - info->ndcb0 = NDCB0_CSEL; - else - info->ndcb0 = 0; - - if (command == NAND_CMD_SEQIN) - exec_cmd = 0; - - addr_cycle = NDCB0_ADDR_CYC(host->row_addr_cycles - + host->col_addr_cycles); - - switch (command) { - case NAND_CMD_READOOB: - case NAND_CMD_READ0: - info->buf_start = column; - info->ndcb0 |= NDCB0_CMD_TYPE(0) - | addr_cycle - | NAND_CMD_READ0; - - if (command == NAND_CMD_READOOB) - info->buf_start += mtd->writesize; - - if (info->cur_chunk < info->nfullchunks) { - info->step_chunk_size = info->chunk_size; - info->step_spare_size = info->spare_size; - } else { - info->step_chunk_size = info->last_chunk_size; - info->step_spare_size = info->last_spare_size; - } - - /* - * Multiple page read needs an 'extended command type' field, - * which is either naked-read or last-read according to the - * state. - */ - if (mtd->writesize == PAGE_CHUNK_SIZE) { - info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8); - } else if (mtd->writesize > PAGE_CHUNK_SIZE) { - info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8) - | NDCB0_LEN_OVRD - | NDCB0_EXT_CMD_TYPE(ext_cmd_type); - info->ndcb3 = info->step_chunk_size + - info->step_spare_size; - } - - set_command_address(info, mtd->writesize, column, page_addr); - break; - - case NAND_CMD_SEQIN: - - info->buf_start = column; - set_command_address(info, mtd->writesize, 0, page_addr); - - /* - * Multiple page programming needs to execute the initial - * SEQIN command that sets the page address. - */ - if (mtd->writesize > PAGE_CHUNK_SIZE) { - info->ndcb0 |= NDCB0_CMD_TYPE(0x1) - | NDCB0_EXT_CMD_TYPE(ext_cmd_type) - | addr_cycle - | command; - exec_cmd = 1; - } - break; - - case NAND_CMD_PAGEPROG: - if (is_buf_blank(info->data_buff, - (mtd->writesize + mtd->oobsize))) { - exec_cmd = 0; - break; - } - - if (info->cur_chunk < info->nfullchunks) { - info->step_chunk_size = info->chunk_size; - info->step_spare_size = info->spare_size; - } else { - info->step_chunk_size = info->last_chunk_size; - info->step_spare_size = info->last_spare_size; - } - - /* Second command setting for large pages */ - if (mtd->writesize > PAGE_CHUNK_SIZE) { - /* - * Multiple page write uses the 'extended command' - * field. This can be used to issue a command dispatch - * or a naked-write depending on the current stage. - */ - info->ndcb0 |= NDCB0_CMD_TYPE(0x1) - | NDCB0_LEN_OVRD - | NDCB0_EXT_CMD_TYPE(ext_cmd_type); - info->ndcb3 = info->step_chunk_size + - info->step_spare_size; - - /* - * This is the command dispatch that completes a chunked - * page program operation. - */ - if (info->cur_chunk == info->ntotalchunks) { - info->ndcb0 = NDCB0_CMD_TYPE(0x1) - | NDCB0_EXT_CMD_TYPE(ext_cmd_type) - | command; - info->ndcb1 = 0; - info->ndcb2 = 0; - info->ndcb3 = 0; - } - } else { - info->ndcb0 |= NDCB0_CMD_TYPE(0x1) - | NDCB0_AUTO_RS - | NDCB0_ST_ROW_EN - | NDCB0_DBC - | (NAND_CMD_PAGEPROG << 8) - | NAND_CMD_SEQIN - | addr_cycle; - } - break; - - case NAND_CMD_PARAM: - info->buf_count = INIT_BUFFER_SIZE; - info->ndcb0 |= NDCB0_CMD_TYPE(0) - | NDCB0_ADDR_CYC(1) - | NDCB0_LEN_OVRD - | command; - info->ndcb1 = (column & 0xFF); - info->ndcb3 = INIT_BUFFER_SIZE; - info->step_chunk_size = INIT_BUFFER_SIZE; - break; - - case NAND_CMD_READID: - info->buf_count = READ_ID_BYTES; - info->ndcb0 |= NDCB0_CMD_TYPE(3) - | NDCB0_ADDR_CYC(1) - | command; - info->ndcb1 = (column & 0xFF); - - info->step_chunk_size = 8; - break; - case NAND_CMD_STATUS: - info->buf_count = 1; - info->ndcb0 |= NDCB0_CMD_TYPE(4) - | NDCB0_ADDR_CYC(1) - | command; - - info->step_chunk_size = 8; - break; - - case NAND_CMD_ERASE1: - info->ndcb0 |= NDCB0_CMD_TYPE(2) - | NDCB0_AUTO_RS - | NDCB0_ADDR_CYC(3) - | NDCB0_DBC - | (NAND_CMD_ERASE2 << 8) - | NAND_CMD_ERASE1; - info->ndcb1 = page_addr; - info->ndcb2 = 0; - - break; - case NAND_CMD_RESET: - info->ndcb0 |= NDCB0_CMD_TYPE(5) - | command; - - break; - - case NAND_CMD_ERASE2: - exec_cmd = 0; - break; - - default: - exec_cmd = 0; - dev_err(&info->pdev->dev, "non-supported command %x\n", - command); - break; - } - - return exec_cmd; -} - -static void nand_cmdfunc(struct mtd_info *mtd, unsigned command, - int column, int page_addr) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - struct pxa3xx_nand_host *host = nand_get_controller_data(chip); - struct pxa3xx_nand_info *info = host->info_data; - int exec_cmd; - - /* - * if this is a x16 device ,then convert the input - * "byte" address into a "word" address appropriate - * for indexing a word-oriented device - */ - if (info->reg_ndcr & NDCR_DWIDTH_M) - column /= 2; - - /* - * There may be different NAND chip hooked to - * different chip select, so check whether - * chip select has been changed, if yes, reset the timing - */ - if (info->cs != host->cs) { - info->cs = host->cs; - nand_writel(info, NDTR0CS0, info->ndtr0cs0); - nand_writel(info, NDTR1CS0, info->ndtr1cs0); - } - - prepare_start_command(info, command); - - info->state = STATE_PREPARED; - exec_cmd = prepare_set_command(info, command, 0, column, page_addr); - - if (exec_cmd) { - init_completion(&info->cmd_complete); - init_completion(&info->dev_ready); - info->need_wait = 1; - pxa3xx_nand_start(info); - - if (!wait_for_completion_timeout(&info->cmd_complete, - CHIP_DELAY_TIMEOUT)) { - dev_err(&info->pdev->dev, "Wait time out!!!\n"); - /* Stop State Machine for next command cycle */ - pxa3xx_nand_stop(info); - } - } - info->state = STATE_IDLE; -} - -static void nand_cmdfunc_extended(struct mtd_info *mtd, - const unsigned command, - int column, int page_addr) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - struct pxa3xx_nand_host *host = nand_get_controller_data(chip); - struct pxa3xx_nand_info *info = host->info_data; - int exec_cmd, ext_cmd_type; - - /* - * if this is a x16 device then convert the input - * "byte" address into a "word" address appropriate - * for indexing a word-oriented device - */ - if (info->reg_ndcr & NDCR_DWIDTH_M) - column /= 2; - - /* - * There may be different NAND chip hooked to - * different chip select, so check whether - * chip select has been changed, if yes, reset the timing - */ - if (info->cs != host->cs) { - info->cs = host->cs; - nand_writel(info, NDTR0CS0, info->ndtr0cs0); - nand_writel(info, NDTR1CS0, info->ndtr1cs0); - } - - /* Select the extended command for the first command */ - switch (command) { - case NAND_CMD_READ0: - case NAND_CMD_READOOB: - ext_cmd_type = EXT_CMD_TYPE_MONO; - break; - case NAND_CMD_SEQIN: - ext_cmd_type = EXT_CMD_TYPE_DISPATCH; - break; - case NAND_CMD_PAGEPROG: - ext_cmd_type = EXT_CMD_TYPE_NAKED_RW; - break; - default: - ext_cmd_type = 0; - break; - } - - prepare_start_command(info, command); - - /* - * Prepare the "is ready" completion before starting a command - * transaction sequence. If the command is not executed the - * completion will be completed, see below. - * - * We can do that inside the loop because the command variable - * is invariant and thus so is the exec_cmd. - */ - info->need_wait = 1; - init_completion(&info->dev_ready); - do { - info->state = STATE_PREPARED; - - exec_cmd = prepare_set_command(info, command, ext_cmd_type, - column, page_addr); - if (!exec_cmd) { - info->need_wait = 0; - complete(&info->dev_ready); - break; - } - - init_completion(&info->cmd_complete); - pxa3xx_nand_start(info); - - if (!wait_for_completion_timeout(&info->cmd_complete, - CHIP_DELAY_TIMEOUT)) { - dev_err(&info->pdev->dev, "Wait time out!!!\n"); - /* Stop State Machine for next command cycle */ - pxa3xx_nand_stop(info); - break; - } - - /* Only a few commands need several steps */ - if (command != NAND_CMD_PAGEPROG && - command != NAND_CMD_READ0 && - command != NAND_CMD_READOOB) - break; - - info->cur_chunk++; - - /* Check if the sequence is complete */ - if (info->cur_chunk == info->ntotalchunks && command != NAND_CMD_PAGEPROG) - break; - - /* - * After a splitted program command sequence has issued - * the command dispatch, the command sequence is complete. - */ - if (info->cur_chunk == (info->ntotalchunks + 1) && - command == NAND_CMD_PAGEPROG && - ext_cmd_type == EXT_CMD_TYPE_DISPATCH) - break; - - if (command == NAND_CMD_READ0 || command == NAND_CMD_READOOB) { - /* Last read: issue a 'last naked read' */ - if (info->cur_chunk == info->ntotalchunks - 1) - ext_cmd_type = EXT_CMD_TYPE_LAST_RW; - else - ext_cmd_type = EXT_CMD_TYPE_NAKED_RW; - - /* - * If a splitted program command has no more data to transfer, - * the command dispatch must be issued to complete. - */ - } else if (command == NAND_CMD_PAGEPROG && - info->cur_chunk == info->ntotalchunks) { - ext_cmd_type = EXT_CMD_TYPE_DISPATCH; - } - } while (1); - - info->state = STATE_IDLE; -} - -static int pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd, - struct nand_chip *chip, const uint8_t *buf, int oob_required, - int page) -{ - nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize); - chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); - - return nand_prog_page_end_op(chip); -} - -static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd, - struct nand_chip *chip, uint8_t *buf, int oob_required, - int page) -{ - struct pxa3xx_nand_host *host = nand_get_controller_data(chip); - struct pxa3xx_nand_info *info = host->info_data; - - nand_read_page_op(chip, page, 0, buf, mtd->writesize); - chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); - - if (info->retcode == ERR_CORERR && info->use_ecc) { - mtd->ecc_stats.corrected += info->ecc_err_cnt; - - } else if (info->retcode == ERR_UNCORERR) { - /* - * for blank page (all 0xff), HW will calculate its ECC as - * 0, which is different from the ECC information within - * OOB, ignore such uncorrectable errors - */ - if (is_buf_blank(buf, mtd->writesize)) - info->retcode = ERR_NONE; - else - mtd->ecc_stats.failed++; - } - - return info->max_bitflips; -} - -static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - struct pxa3xx_nand_host *host = nand_get_controller_data(chip); - struct pxa3xx_nand_info *info = host->info_data; - char retval = 0xFF; - - if (info->buf_start < info->buf_count) - /* Has just send a new command? */ - retval = info->data_buff[info->buf_start++]; - - return retval; -} - -static u16 pxa3xx_nand_read_word(struct mtd_info *mtd) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - struct pxa3xx_nand_host *host = nand_get_controller_data(chip); - struct pxa3xx_nand_info *info = host->info_data; - u16 retval = 0xFFFF; - - if (!(info->buf_start & 0x01) && info->buf_start < info->buf_count) { - retval = *((u16 *)(info->data_buff+info->buf_start)); - info->buf_start += 2; - } - return retval; -} - -static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - struct pxa3xx_nand_host *host = nand_get_controller_data(chip); - struct pxa3xx_nand_info *info = host->info_data; - int real_len = min_t(size_t, len, info->buf_count - info->buf_start); - - memcpy(buf, info->data_buff + info->buf_start, real_len); - info->buf_start += real_len; -} - -static void pxa3xx_nand_write_buf(struct mtd_info *mtd, - const uint8_t *buf, int len) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - struct pxa3xx_nand_host *host = nand_get_controller_data(chip); - struct pxa3xx_nand_info *info = host->info_data; - int real_len = min_t(size_t, len, info->buf_count - info->buf_start); - - memcpy(info->data_buff + info->buf_start, buf, real_len); - info->buf_start += real_len; -} - -static void pxa3xx_nand_select_chip(struct mtd_info *mtd, int chip) -{ - return; -} - -static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - struct pxa3xx_nand_host *host = nand_get_controller_data(chip); - struct pxa3xx_nand_info *info = host->info_data; - - if (info->need_wait) { - info->need_wait = 0; - if (!wait_for_completion_timeout(&info->dev_ready, - CHIP_DELAY_TIMEOUT)) { - dev_err(&info->pdev->dev, "Ready time out!!!\n"); - return NAND_STATUS_FAIL; - } - } - - /* pxa3xx_nand_send_command has waited for command complete */ - if (this->state == FL_WRITING || this->state == FL_ERASING) { - if (info->retcode == ERR_NONE) - return 0; - else - return NAND_STATUS_FAIL; - } - - return NAND_STATUS_READY; -} - -static int pxa3xx_nand_config_ident(struct pxa3xx_nand_info *info) -{ - struct pxa3xx_nand_host *host = info->host[info->cs]; - struct platform_device *pdev = info->pdev; - struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); - const struct nand_sdr_timings *timings; - - /* Configure default flash values */ - info->chunk_size = PAGE_CHUNK_SIZE; - info->reg_ndcr = 0x0; /* enable all interrupts */ - info->reg_ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0; - info->reg_ndcr |= NDCR_RD_ID_CNT(READ_ID_BYTES); - info->reg_ndcr |= NDCR_SPARE_EN; - - /* use the common timing to make a try */ - timings = onfi_async_timing_mode_to_sdr_timings(0); - if (IS_ERR(timings)) - return PTR_ERR(timings); - - pxa3xx_nand_set_sdr_timing(host, timings); - return 0; -} - -static void pxa3xx_nand_config_tail(struct pxa3xx_nand_info *info) -{ - struct pxa3xx_nand_host *host = info->host[info->cs]; - struct nand_chip *chip = &host->chip; - struct mtd_info *mtd = nand_to_mtd(chip); - - info->reg_ndcr |= (host->col_addr_cycles == 2) ? NDCR_RA_START : 0; - info->reg_ndcr |= (chip->page_shift == 6) ? NDCR_PG_PER_BLK : 0; - info->reg_ndcr |= (mtd->writesize == 2048) ? NDCR_PAGE_SZ : 0; -} - -static void pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) -{ - struct platform_device *pdev = info->pdev; - struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); - uint32_t ndcr = nand_readl(info, NDCR); - - /* Set an initial chunk size */ - info->chunk_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512; - info->reg_ndcr = ndcr & - ~(NDCR_INT_MASK | NDCR_ND_ARB_EN | NFCV1_NDCR_ARB_CNTL); - info->reg_ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0; - info->ndtr0cs0 = nand_readl(info, NDTR0CS0); - info->ndtr1cs0 = nand_readl(info, NDTR1CS0); -} - -static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info) -{ - struct platform_device *pdev = info->pdev; - struct dma_slave_config config; - dma_cap_mask_t mask; - struct pxad_param param; - int ret; - - info->data_buff = kmalloc(info->buf_size, GFP_KERNEL); - if (info->data_buff == NULL) - return -ENOMEM; - if (use_dma == 0) - return 0; - - ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); - if (ret) - return ret; - - sg_init_one(&info->sg, info->data_buff, info->buf_size); - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - param.prio = PXAD_PRIO_LOWEST; - param.drcmr = info->drcmr_dat; - info->dma_chan = dma_request_slave_channel_compat(mask, pxad_filter_fn, - ¶m, &pdev->dev, - "data"); - if (!info->dma_chan) { - dev_err(&pdev->dev, "unable to request data dma channel\n"); - return -ENODEV; - } - - memset(&config, 0, sizeof(config)); - config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - config.src_addr = info->mmio_phys + NDDB; - config.dst_addr = info->mmio_phys + NDDB; - config.src_maxburst = 32; - config.dst_maxburst = 32; - ret = dmaengine_slave_config(info->dma_chan, &config); - if (ret < 0) { - dev_err(&info->pdev->dev, - "dma channel configuration failed: %d\n", - ret); - return ret; - } - - /* - * Now that DMA buffers are allocated we turn on - * DMA proper for I/O operations. - */ - info->use_dma = 1; - return 0; -} - -static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info) -{ - if (info->use_dma) { - dmaengine_terminate_all(info->dma_chan); - dma_release_channel(info->dma_chan); - } - kfree(info->data_buff); -} - -static int pxa_ecc_init(struct pxa3xx_nand_info *info, - struct mtd_info *mtd, - int strength, int ecc_stepsize, int page_size) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - struct nand_ecc_ctrl *ecc = &chip->ecc; - - if (strength == 1 && ecc_stepsize == 512 && page_size == 2048) { - info->nfullchunks = 1; - info->ntotalchunks = 1; - info->chunk_size = 2048; - info->spare_size = 40; - info->ecc_size = 24; - ecc->mode = NAND_ECC_HW; - ecc->size = 512; - ecc->strength = 1; - - } else if (strength == 1 && ecc_stepsize == 512 && page_size == 512) { - info->nfullchunks = 1; - info->ntotalchunks = 1; - info->chunk_size = 512; - info->spare_size = 8; - info->ecc_size = 8; - ecc->mode = NAND_ECC_HW; - ecc->size = 512; - ecc->strength = 1; - - /* - * Required ECC: 4-bit correction per 512 bytes - * Select: 16-bit correction per 2048 bytes - */ - } else if (strength == 4 && ecc_stepsize == 512 && page_size == 2048) { - info->ecc_bch = 1; - info->nfullchunks = 1; - info->ntotalchunks = 1; - info->chunk_size = 2048; - info->spare_size = 32; - info->ecc_size = 32; - ecc->mode = NAND_ECC_HW; - ecc->size = info->chunk_size; - mtd_set_ooblayout(mtd, &pxa3xx_ooblayout_ops); - ecc->strength = 16; - - } else if (strength == 4 && ecc_stepsize == 512 && page_size == 4096) { - info->ecc_bch = 1; - info->nfullchunks = 2; - info->ntotalchunks = 2; - info->chunk_size = 2048; - info->spare_size = 32; - info->ecc_size = 32; - ecc->mode = NAND_ECC_HW; - ecc->size = info->chunk_size; - mtd_set_ooblayout(mtd, &pxa3xx_ooblayout_ops); - ecc->strength = 16; - - /* - * Required ECC: 8-bit correction per 512 bytes - * Select: 16-bit correction per 1024 bytes - */ - } else if (strength == 8 && ecc_stepsize == 512 && page_size == 4096) { - info->ecc_bch = 1; - info->nfullchunks = 4; - info->ntotalchunks = 5; - info->chunk_size = 1024; - info->spare_size = 0; - info->last_chunk_size = 0; - info->last_spare_size = 64; - info->ecc_size = 32; - ecc->mode = NAND_ECC_HW; - ecc->size = info->chunk_size; - mtd_set_ooblayout(mtd, &pxa3xx_ooblayout_ops); - ecc->strength = 16; - } else { - dev_err(&info->pdev->dev, - "ECC strength %d at page size %d is not supported\n", - strength, page_size); - return -ENODEV; - } - - dev_info(&info->pdev->dev, "ECC strength %d, ECC step size %d\n", - ecc->strength, ecc->size); - return 0; -} - -static int pxa3xx_nand_scan(struct mtd_info *mtd) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - struct pxa3xx_nand_host *host = nand_get_controller_data(chip); - struct pxa3xx_nand_info *info = host->info_data; - struct platform_device *pdev = info->pdev; - struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); - int ret; - uint16_t ecc_strength, ecc_step; - - if (pdata->keep_config) { - pxa3xx_nand_detect_config(info); - } else { - ret = pxa3xx_nand_config_ident(info); - if (ret) - return ret; - } - - if (info->reg_ndcr & NDCR_DWIDTH_M) - chip->options |= NAND_BUSWIDTH_16; - - /* Device detection must be done with ECC disabled */ - if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 || - info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K) - nand_writel(info, NDECCCTRL, 0x0); - - if (pdata->flash_bbt) - chip->bbt_options |= NAND_BBT_USE_FLASH; - - chip->ecc.strength = pdata->ecc_strength; - chip->ecc.size = pdata->ecc_step_size; - - ret = nand_scan_ident(mtd, 1, NULL); - if (ret) - return ret; - - if (!pdata->keep_config) { - ret = pxa3xx_nand_init(host); - if (ret) { - dev_err(&info->pdev->dev, "Failed to init nand: %d\n", - ret); - return ret; - } - } - - if (chip->bbt_options & NAND_BBT_USE_FLASH) { - /* - * We'll use a bad block table stored in-flash and don't - * allow writing the bad block marker to the flash. - */ - chip->bbt_options |= NAND_BBT_NO_OOB_BBM; - chip->bbt_td = &bbt_main_descr; - chip->bbt_md = &bbt_mirror_descr; - } - - /* - * If the page size is bigger than the FIFO size, let's check - * we are given the right variant and then switch to the extended - * (aka splitted) command handling, - */ - if (mtd->writesize > PAGE_CHUNK_SIZE) { - if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 || - info->variant == PXA3XX_NAND_VARIANT_ARMADA_8K) { - chip->cmdfunc = nand_cmdfunc_extended; - } else { - dev_err(&info->pdev->dev, - "unsupported page size on this variant\n"); - return -ENODEV; - } - } - - ecc_strength = chip->ecc.strength; - ecc_step = chip->ecc.size; - if (!ecc_strength || !ecc_step) { - ecc_strength = chip->ecc_strength_ds; - ecc_step = chip->ecc_step_ds; - } - - /* Set default ECC strength requirements on non-ONFI devices */ - if (ecc_strength < 1 && ecc_step < 1) { - ecc_strength = 1; - ecc_step = 512; - } - - ret = pxa_ecc_init(info, mtd, ecc_strength, - ecc_step, mtd->writesize); - if (ret) - return ret; - - /* calculate addressing information */ - if (mtd->writesize >= 2048) - host->col_addr_cycles = 2; - else - host->col_addr_cycles = 1; - - /* release the initial buffer */ - kfree(info->data_buff); - - /* allocate the real data + oob buffer */ - info->buf_size = mtd->writesize + mtd->oobsize; - ret = pxa3xx_nand_init_buff(info); - if (ret) - return ret; - info->oob_buff = info->data_buff + mtd->writesize; - - if ((mtd->size >> chip->page_shift) > 65536) - host->row_addr_cycles = 3; - else - host->row_addr_cycles = 2; - - if (!pdata->keep_config) - pxa3xx_nand_config_tail(info); - - return nand_scan_tail(mtd); -} - -static int alloc_nand_resource(struct platform_device *pdev) -{ - struct device_node *np = pdev->dev.of_node; - struct pxa3xx_nand_platform_data *pdata; - struct pxa3xx_nand_info *info; - struct pxa3xx_nand_host *host; - struct nand_chip *chip = NULL; - struct mtd_info *mtd; - struct resource *r; - int ret, irq, cs; - - pdata = dev_get_platdata(&pdev->dev); - if (pdata->num_cs <= 0) { - dev_err(&pdev->dev, "invalid number of chip selects\n"); - return -ENODEV; - } - - info = devm_kzalloc(&pdev->dev, - sizeof(*info) + sizeof(*host) * pdata->num_cs, - GFP_KERNEL); - if (!info) - return -ENOMEM; - - info->pdev = pdev; - info->variant = pxa3xx_nand_get_variant(pdev); - for (cs = 0; cs < pdata->num_cs; cs++) { - host = (void *)&info[1] + sizeof(*host) * cs; - chip = &host->chip; - nand_set_controller_data(chip, host); - mtd = nand_to_mtd(chip); - info->host[cs] = host; - host->cs = cs; - host->info_data = info; - mtd->dev.parent = &pdev->dev; - /* FIXME: all chips use the same device tree partitions */ - nand_set_flash_node(chip, np); - - nand_set_controller_data(chip, host); - chip->ecc.read_page = pxa3xx_nand_read_page_hwecc; - chip->ecc.write_page = pxa3xx_nand_write_page_hwecc; - chip->controller = &info->controller; - chip->waitfunc = pxa3xx_nand_waitfunc; - chip->select_chip = pxa3xx_nand_select_chip; - chip->read_word = pxa3xx_nand_read_word; - chip->read_byte = pxa3xx_nand_read_byte; - chip->read_buf = pxa3xx_nand_read_buf; - chip->write_buf = pxa3xx_nand_write_buf; - chip->options |= NAND_NO_SUBPAGE_WRITE; - chip->cmdfunc = nand_cmdfunc; - chip->onfi_set_features = nand_onfi_get_set_features_notsupp; - chip->onfi_get_features = nand_onfi_get_set_features_notsupp; - } - - nand_hw_control_init(chip->controller); - info->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(info->clk)) { - ret = PTR_ERR(info->clk); - dev_err(&pdev->dev, "failed to get nand clock: %d\n", ret); - return ret; - } - ret = clk_prepare_enable(info->clk); - if (ret < 0) - return ret; - - if (!np && use_dma) { - r = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (r == NULL) { - dev_err(&pdev->dev, - "no resource defined for data DMA\n"); - ret = -ENXIO; - goto fail_disable_clk; - } - info->drcmr_dat = r->start; - } - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "no IRQ resource defined\n"); - ret = -ENXIO; - goto fail_disable_clk; - } - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - info->mmio_base = devm_ioremap_resource(&pdev->dev, r); - if (IS_ERR(info->mmio_base)) { - ret = PTR_ERR(info->mmio_base); - dev_err(&pdev->dev, "failed to map register space: %d\n", ret); - goto fail_disable_clk; - } - info->mmio_phys = r->start; - - /* Allocate a buffer to allow flash detection */ - info->buf_size = INIT_BUFFER_SIZE; - info->data_buff = kmalloc(info->buf_size, GFP_KERNEL); - if (info->data_buff == NULL) { - ret = -ENOMEM; - goto fail_disable_clk; - } - - /* initialize all interrupts to be disabled */ - disable_int(info, NDSR_MASK); - - ret = request_threaded_irq(irq, pxa3xx_nand_irq, - pxa3xx_nand_irq_thread, IRQF_ONESHOT, - pdev->name, info); - if (ret < 0) { - dev_err(&pdev->dev, "failed to request IRQ: %d\n", ret); - goto fail_free_buf; - } - - platform_set_drvdata(pdev, info); - - return 0; - -fail_free_buf: - free_irq(irq, info); - kfree(info->data_buff); -fail_disable_clk: - clk_disable_unprepare(info->clk); - return ret; -} - -static int pxa3xx_nand_remove(struct platform_device *pdev) -{ - struct pxa3xx_nand_info *info = platform_get_drvdata(pdev); - struct pxa3xx_nand_platform_data *pdata; - int irq, cs; - - if (!info) - return 0; - - pdata = dev_get_platdata(&pdev->dev); - - irq = platform_get_irq(pdev, 0); - if (irq >= 0) - free_irq(irq, info); - pxa3xx_nand_free_buff(info); - - /* - * In the pxa3xx case, the DFI bus is shared between the SMC and NFC. - * In order to prevent a lockup of the system bus, the DFI bus - * arbitration is granted to SMC upon driver removal. This is done by - * setting the x_ARB_CNTL bit, which also prevents the NAND to have - * access to the bus anymore. - */ - nand_writel(info, NDCR, - (nand_readl(info, NDCR) & ~NDCR_ND_ARB_EN) | - NFCV1_NDCR_ARB_CNTL); - clk_disable_unprepare(info->clk); - - for (cs = 0; cs < pdata->num_cs; cs++) - nand_release(nand_to_mtd(&info->host[cs]->chip)); - return 0; -} - -static int pxa3xx_nand_probe_dt(struct platform_device *pdev) -{ - struct pxa3xx_nand_platform_data *pdata; - struct device_node *np = pdev->dev.of_node; - const struct of_device_id *of_id = - of_match_device(pxa3xx_nand_dt_ids, &pdev->dev); - - if (!of_id) - return 0; - - /* - * Some SoCs like A7k/A8k need to enable manually the NAND - * controller to avoid being bootloader dependent. This is done - * through the use of a single bit in the System Functions registers. - */ - if (pxa3xx_nand_get_variant(pdev) == PXA3XX_NAND_VARIANT_ARMADA_8K) { - struct regmap *sysctrl_base = syscon_regmap_lookup_by_phandle( - pdev->dev.of_node, "marvell,system-controller"); - u32 reg; - - if (IS_ERR(sysctrl_base)) - return PTR_ERR(sysctrl_base); - - regmap_read(sysctrl_base, GENCONF_SOC_DEVICE_MUX, ®); - reg |= GENCONF_SOC_DEVICE_MUX_NFC_EN; - regmap_write(sysctrl_base, GENCONF_SOC_DEVICE_MUX, reg); - } - - pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return -ENOMEM; - - if (of_get_property(np, "marvell,nand-enable-arbiter", NULL)) - pdata->enable_arbiter = 1; - if (of_get_property(np, "marvell,nand-keep-config", NULL)) - pdata->keep_config = 1; - of_property_read_u32(np, "num-cs", &pdata->num_cs); - - pdev->dev.platform_data = pdata; - - return 0; -} - -static int pxa3xx_nand_probe(struct platform_device *pdev) -{ - struct pxa3xx_nand_platform_data *pdata; - struct pxa3xx_nand_info *info; - int ret, cs, probe_success, dma_available; - - dma_available = IS_ENABLED(CONFIG_ARM) && - (IS_ENABLED(CONFIG_ARCH_PXA) || IS_ENABLED(CONFIG_ARCH_MMP)); - if (use_dma && !dma_available) { - use_dma = 0; - dev_warn(&pdev->dev, - "This platform can't do DMA on this device\n"); - } - - ret = pxa3xx_nand_probe_dt(pdev); - if (ret) - return ret; - - pdata = dev_get_platdata(&pdev->dev); - if (!pdata) { - dev_err(&pdev->dev, "no platform data defined\n"); - return -ENODEV; - } - - ret = alloc_nand_resource(pdev); - if (ret) - return ret; - - info = platform_get_drvdata(pdev); - probe_success = 0; - for (cs = 0; cs < pdata->num_cs; cs++) { - struct mtd_info *mtd = nand_to_mtd(&info->host[cs]->chip); - - /* - * The mtd name matches the one used in 'mtdparts' kernel - * parameter. This name cannot be changed or otherwise - * user's mtd partitions configuration would get broken. - */ - mtd->name = "pxa3xx_nand-0"; - info->cs = cs; - ret = pxa3xx_nand_scan(mtd); - if (ret) { - dev_warn(&pdev->dev, "failed to scan nand at cs %d\n", - cs); - continue; - } - - ret = mtd_device_register(mtd, pdata->parts[cs], - pdata->nr_parts[cs]); - if (!ret) - probe_success = 1; - } - - if (!probe_success) { - pxa3xx_nand_remove(pdev); - return -ENODEV; - } - - return 0; -} - -#ifdef CONFIG_PM -static int pxa3xx_nand_suspend(struct device *dev) -{ - struct pxa3xx_nand_info *info = dev_get_drvdata(dev); - - if (info->state) { - dev_err(dev, "driver busy, state = %d\n", info->state); - return -EAGAIN; - } - - clk_disable(info->clk); - return 0; -} - -static int pxa3xx_nand_resume(struct device *dev) -{ - struct pxa3xx_nand_info *info = dev_get_drvdata(dev); - int ret; - - ret = clk_enable(info->clk); - if (ret < 0) - return ret; - - /* We don't want to handle interrupt without calling mtd routine */ - disable_int(info, NDCR_INT_MASK); - - /* - * Directly set the chip select to a invalid value, - * then the driver would reset the timing according - * to current chip select at the beginning of cmdfunc - */ - info->cs = 0xff; - - /* - * As the spec says, the NDSR would be updated to 0x1800 when - * doing the nand_clk disable/enable. - * To prevent it damaging state machine of the driver, clear - * all status before resume - */ - nand_writel(info, NDSR, NDSR_MASK); - - return 0; -} -#else -#define pxa3xx_nand_suspend NULL -#define pxa3xx_nand_resume NULL -#endif - -static const struct dev_pm_ops pxa3xx_nand_pm_ops = { - .suspend = pxa3xx_nand_suspend, - .resume = pxa3xx_nand_resume, -}; - -static struct platform_driver pxa3xx_nand_driver = { - .driver = { - .name = "pxa3xx-nand", - .of_match_table = pxa3xx_nand_dt_ids, - .pm = &pxa3xx_nand_pm_ops, - }, - .probe = pxa3xx_nand_probe, - .remove = pxa3xx_nand_remove, -}; - -module_platform_driver(pxa3xx_nand_driver); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("PXA3xx NAND controller driver"); diff --git a/drivers/phy/ti/phy-da8xx-usb.c b/drivers/phy/ti/phy-da8xx-usb.c index 1b82bff6330f..befb886ff121 100644 --- a/drivers/phy/ti/phy-da8xx-usb.c +++ b/drivers/phy/ti/phy-da8xx-usb.c @@ -20,6 +20,7 @@ #include <linux/mfd/syscon.h> #include <linux/module.h> #include <linux/phy/phy.h> +#include <linux/platform_data/phy-da8xx-usb.h> #include <linux/platform_device.h> #include <linux/regmap.h> @@ -145,6 +146,7 @@ static struct phy *da8xx_usb_phy_of_xlate(struct device *dev, static int da8xx_usb_phy_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct da8xx_usb_phy_platform_data *pdata = dev->platform_data; struct device_node *node = dev->of_node; struct da8xx_usb_phy *d_phy; @@ -152,25 +154,25 @@ static int da8xx_usb_phy_probe(struct platform_device *pdev) if (!d_phy) return -ENOMEM; - if (node) + if (pdata) + d_phy->regmap = pdata->cfgchip; + else d_phy->regmap = syscon_regmap_lookup_by_compatible( "ti,da830-cfgchip"); - else - d_phy->regmap = syscon_regmap_lookup_by_pdevname("syscon"); if (IS_ERR(d_phy->regmap)) { dev_err(dev, "Failed to get syscon\n"); return PTR_ERR(d_phy->regmap); } - d_phy->usb11_clk = devm_clk_get(dev, "usb11_phy"); + d_phy->usb11_clk = devm_clk_get(dev, "usb1_clk48"); if (IS_ERR(d_phy->usb11_clk)) { - dev_err(dev, "Failed to get usb11_phy clock\n"); + dev_err(dev, "Failed to get usb1_clk48\n"); return PTR_ERR(d_phy->usb11_clk); } - d_phy->usb20_clk = devm_clk_get(dev, "usb20_phy"); + d_phy->usb20_clk = devm_clk_get(dev, "usb0_clk48"); if (IS_ERR(d_phy->usb20_clk)) { - dev_err(dev, "Failed to get usb20_phy clock\n"); + dev_err(dev, "Failed to get usb0_clk48\n"); return PTR_ERR(d_phy->usb20_clk); } diff --git a/drivers/power/avs/smartreflex.c b/drivers/power/avs/smartreflex.c index 89bf4d6cb486..cb0237143dbe 100644 --- a/drivers/power/avs/smartreflex.c +++ b/drivers/power/avs/smartreflex.c @@ -132,12 +132,16 @@ static void sr_set_clk_length(struct omap_sr *sr) struct clk *fck; u32 fclk_speed; - fck = clk_get(&sr->pdev->dev, "fck"); - + /* Try interconnect target module fck first if it already exists */ + fck = clk_get(sr->pdev->dev.parent, "fck"); if (IS_ERR(fck)) { - dev_err(&sr->pdev->dev, "%s: unable to get fck for device %s\n", - __func__, dev_name(&sr->pdev->dev)); - return; + fck = clk_get(&sr->pdev->dev, "fck"); + if (IS_ERR(fck)) { + dev_err(&sr->pdev->dev, + "%s: unable to get fck for device %s\n", + __func__, dev_name(&sr->pdev->dev)); + return; + } } fclk_speed = clk_get_rate(fck); @@ -838,7 +842,7 @@ static int omap_sr_autocomp_store(void *data, u64 val) DEFINE_SIMPLE_ATTRIBUTE(pm_sr_fops, omap_sr_autocomp_show, omap_sr_autocomp_store, "%llu\n"); -static int __init omap_sr_probe(struct platform_device *pdev) +static int omap_sr_probe(struct platform_device *pdev) { struct omap_sr *sr_info; struct omap_sr_data *pdata = pdev->dev.platform_data; @@ -898,6 +902,12 @@ static int __init omap_sr_probe(struct platform_device *pdev) list_add(&sr_info->node, &sr_list); + ret = pm_runtime_get_sync(&pdev->dev); + if (ret < 0) { + pm_runtime_put_noidle(&pdev->dev); + goto err_list_del; + } + /* * Call into late init to do initializations that require * both sr driver and sr class driver to be initiallized. @@ -966,12 +976,17 @@ static int __init omap_sr_probe(struct platform_device *pdev) } + pm_runtime_put_sync(&pdev->dev); + return ret; err_debugfs: debugfs_remove_recursive(sr_info->dbg_dir); err_list_del: list_del(&sr_info->node); + + pm_runtime_put_sync(&pdev->dev); + return ret; } @@ -1025,11 +1040,23 @@ static void omap_sr_shutdown(struct platform_device *pdev) return; } +static const struct of_device_id omap_sr_match[] = { + { .compatible = "ti,omap3-smartreflex-core", }, + { .compatible = "ti,omap3-smartreflex-mpu-iva", }, + { .compatible = "ti,omap4-smartreflex-core", }, + { .compatible = "ti,omap4-smartreflex-mpu", }, + { .compatible = "ti,omap4-smartreflex-iva", }, + { }, +}; +MODULE_DEVICE_TABLE(of, omap_sr_match); + static struct platform_driver smartreflex_driver = { + .probe = omap_sr_probe, .remove = omap_sr_remove, .shutdown = omap_sr_shutdown, .driver = { .name = DRIVER_NAME, + .of_match_table = omap_sr_match, }, }; @@ -1048,7 +1075,7 @@ static int __init sr_init(void) else pr_warn("%s: No PMIC hook to init smartreflex\n", __func__); - ret = platform_driver_probe(&smartreflex_driver, omap_sr_probe); + ret = platform_driver_register(&smartreflex_driver); if (ret) { pr_err("%s: platform driver register failed for SR\n", __func__); diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c index 5ad42f33e70c..665da3c8fbce 100644 --- a/drivers/pwm/pwm-omap-dmtimer.c +++ b/drivers/pwm/pwm-omap-dmtimer.c @@ -23,6 +23,7 @@ #include <linux/mutex.h> #include <linux/of.h> #include <linux/of_platform.h> +#include <linux/platform_data/dmtimer-omap.h> #include <linux/platform_data/pwm_omap_dmtimer.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> @@ -37,7 +38,7 @@ struct pwm_omap_dmtimer_chip { struct pwm_chip chip; struct mutex mutex; pwm_omap_dmtimer *dm_timer; - struct pwm_omap_dmtimer_pdata *pdata; + const struct omap_dm_timer_ops *pdata; struct platform_device *dm_timer_pdev; }; @@ -242,19 +243,35 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct device_node *timer; + struct platform_device *timer_pdev; struct pwm_omap_dmtimer_chip *omap; - struct pwm_omap_dmtimer_pdata *pdata; + struct dmtimer_platform_data *timer_pdata; + const struct omap_dm_timer_ops *pdata; pwm_omap_dmtimer *dm_timer; u32 v; - int status; + int ret = 0; - pdata = dev_get_platdata(&pdev->dev); - if (!pdata) { - dev_err(&pdev->dev, "Missing dmtimer platform data\n"); - return -EINVAL; + timer = of_parse_phandle(np, "ti,timers", 0); + if (!timer) + return -ENODEV; + + timer_pdev = of_find_device_by_node(timer); + if (!timer_pdev) { + dev_err(&pdev->dev, "Unable to find Timer pdev\n"); + ret = -ENODEV; + goto put; } - if (!pdata->request_by_node || + timer_pdata = dev_get_platdata(&timer_pdev->dev); + if (!timer_pdata) { + dev_err(&pdev->dev, "dmtimer pdata structure NULL\n"); + ret = -EINVAL; + goto put; + } + + pdata = timer_pdata->timer_ops; + + if (!pdata || !pdata->request_by_node || !pdata->free || !pdata->enable || !pdata->disable || @@ -267,21 +284,26 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) !pdata->set_prescaler || !pdata->write_counter) { dev_err(&pdev->dev, "Incomplete dmtimer pdata structure\n"); - return -EINVAL; + ret = -EINVAL; + goto put; } - timer = of_parse_phandle(np, "ti,timers", 0); - if (!timer) - return -ENODEV; - if (!of_get_property(timer, "ti,timer-pwm", NULL)) { dev_err(&pdev->dev, "Missing ti,timer-pwm capability\n"); - return -ENODEV; + ret = -ENODEV; + goto put; } dm_timer = pdata->request_by_node(timer); - if (!dm_timer) - return -EPROBE_DEFER; + if (!dm_timer) { + ret = -EPROBE_DEFER; + goto put; + } + +put: + of_node_put(timer); + if (ret < 0) + return ret; omap = devm_kzalloc(&pdev->dev, sizeof(*omap), GFP_KERNEL); if (!omap) { @@ -291,13 +313,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) omap->pdata = pdata; omap->dm_timer = dm_timer; - - omap->dm_timer_pdev = of_find_device_by_node(timer); - if (!omap->dm_timer_pdev) { - dev_err(&pdev->dev, "Unable to find timer pdev\n"); - omap->pdata->free(dm_timer); - return -EINVAL; - } + omap->dm_timer_pdev = timer_pdev; /* * Ensure that the timer is stopped before we allow PWM core to call @@ -322,11 +338,11 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev) mutex_init(&omap->mutex); - status = pwmchip_add(&omap->chip); - if (status < 0) { + ret = pwmchip_add(&omap->chip); + if (ret < 0) { dev_err(&pdev->dev, "failed to register PWM\n"); omap->pdata->free(omap->dm_timer); - return status; + return ret; } platform_set_drvdata(pdev, omap); diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig index 09550b1da56d..3bbe6114a420 100644 --- a/drivers/soc/renesas/Kconfig +++ b/drivers/soc/renesas/Kconfig @@ -3,8 +3,8 @@ config SOC_RENESAS default y if ARCH_RENESAS select SOC_BUS select RST_RCAR if ARCH_RCAR_GEN1 || ARCH_RCAR_GEN2 || \ - ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A77970 || \ - ARCH_R8A77995 + ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A77965 || \ + ARCH_R8A77970 || ARCH_R8A77980 || ARCH_R8A77995 select SYSC_R8A7743 if ARCH_R8A7743 select SYSC_R8A7745 if ARCH_R8A7745 select SYSC_R8A7779 if ARCH_R8A7779 @@ -14,7 +14,9 @@ config SOC_RENESAS select SYSC_R8A7794 if ARCH_R8A7794 select SYSC_R8A7795 if ARCH_R8A7795 select SYSC_R8A7796 if ARCH_R8A7796 + select SYSC_R8A77965 if ARCH_R8A77965 select SYSC_R8A77970 if ARCH_R8A77970 + select SYSC_R8A77980 if ARCH_R8A77980 select SYSC_R8A77995 if ARCH_R8A77995 if SOC_RENESAS @@ -56,10 +58,18 @@ config SYSC_R8A7796 bool "R-Car M3-W System Controller support" if COMPILE_TEST select SYSC_RCAR +config SYSC_R8A77965 + bool "R-Car M3-N System Controller support" if COMPILE_TEST + select SYSC_RCAR + config SYSC_R8A77970 bool "R-Car V3M System Controller support" if COMPILE_TEST select SYSC_RCAR +config SYSC_R8A77980 + bool "R-Car V3H System Controller support" if COMPILE_TEST + select SYSC_RCAR + config SYSC_R8A77995 bool "R-Car D3 System Controller support" if COMPILE_TEST select SYSC_RCAR diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile index 845d62a08ce1..ccb5ec57a262 100644 --- a/drivers/soc/renesas/Makefile +++ b/drivers/soc/renesas/Makefile @@ -12,7 +12,9 @@ obj-$(CONFIG_SYSC_R8A7792) += r8a7792-sysc.o obj-$(CONFIG_SYSC_R8A7794) += r8a7794-sysc.o obj-$(CONFIG_SYSC_R8A7795) += r8a7795-sysc.o obj-$(CONFIG_SYSC_R8A7796) += r8a7796-sysc.o +obj-$(CONFIG_SYSC_R8A77965) += r8a77965-sysc.o obj-$(CONFIG_SYSC_R8A77970) += r8a77970-sysc.o +obj-$(CONFIG_SYSC_R8A77980) += r8a77980-sysc.o obj-$(CONFIG_SYSC_R8A77995) += r8a77995-sysc.o # Family diff --git a/drivers/soc/renesas/r8a77965-sysc.c b/drivers/soc/renesas/r8a77965-sysc.c new file mode 100644 index 000000000000..d7f7928e3c07 --- /dev/null +++ b/drivers/soc/renesas/r8a77965-sysc.c @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Renesas R-Car M3-N System Controller + * Copyright (C) 2018 Jacopo Mondi <jacopo+renesas@jmondi.org> + * + * Based on Renesas R-Car M3-W System Controller + * Copyright (C) 2016 Glider bvba + */ + +#include <linux/bug.h> +#include <linux/kernel.h> + +#include <dt-bindings/power/r8a77965-sysc.h> + +#include "rcar-sysc.h" + +static const struct rcar_sysc_area r8a77965_areas[] __initconst = { + { "always-on", 0, 0, R8A77965_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, + { "ca57-scu", 0x1c0, 0, R8A77965_PD_CA57_SCU, R8A77965_PD_ALWAYS_ON, + PD_SCU }, + { "ca57-cpu0", 0x80, 0, R8A77965_PD_CA57_CPU0, R8A77965_PD_CA57_SCU, + PD_CPU_NOCR }, + { "ca57-cpu1", 0x80, 1, R8A77965_PD_CA57_CPU1, R8A77965_PD_CA57_SCU, + PD_CPU_NOCR }, + { "cr7", 0x240, 0, R8A77965_PD_CR7, R8A77965_PD_ALWAYS_ON }, + { "a3vc", 0x380, 0, R8A77965_PD_A3VC, R8A77965_PD_ALWAYS_ON }, + { "a3vp", 0x340, 0, R8A77965_PD_A3VP, R8A77965_PD_ALWAYS_ON }, + { "a2vc1", 0x3c0, 1, R8A77965_PD_A2VC1, R8A77965_PD_A3VC }, + { "3dg-a", 0x100, 0, R8A77965_PD_3DG_A, R8A77965_PD_ALWAYS_ON }, + { "3dg-b", 0x100, 1, R8A77965_PD_3DG_B, R8A77965_PD_3DG_A }, + { "a3ir", 0x180, 0, R8A77965_PD_A3IR, R8A77965_PD_ALWAYS_ON }, +}; + +const struct rcar_sysc_info r8a77965_sysc_info __initconst = { + .areas = r8a77965_areas, + .num_areas = ARRAY_SIZE(r8a77965_areas), +}; diff --git a/drivers/soc/renesas/r8a77970-sysc.c b/drivers/soc/renesas/r8a77970-sysc.c index 8c614164718e..caf894f193ed 100644 --- a/drivers/soc/renesas/r8a77970-sysc.c +++ b/drivers/soc/renesas/r8a77970-sysc.c @@ -25,12 +25,12 @@ static const struct rcar_sysc_area r8a77970_areas[] __initconst = { PD_CPU_NOCR }, { "cr7", 0x240, 0, R8A77970_PD_CR7, R8A77970_PD_ALWAYS_ON }, { "a3ir", 0x180, 0, R8A77970_PD_A3IR, R8A77970_PD_ALWAYS_ON }, - { "a2ir0", 0x400, 0, R8A77970_PD_A2IR0, R8A77970_PD_ALWAYS_ON }, - { "a2ir1", 0x400, 1, R8A77970_PD_A2IR1, R8A77970_PD_A2IR0 }, - { "a2ir2", 0x400, 2, R8A77970_PD_A2IR2, R8A77970_PD_A2IR0 }, - { "a2ir3", 0x400, 3, R8A77970_PD_A2IR3, R8A77970_PD_A2IR0 }, - { "a2sc0", 0x400, 4, R8A77970_PD_A2SC0, R8A77970_PD_ALWAYS_ON }, - { "a2sc1", 0x400, 5, R8A77970_PD_A2SC1, R8A77970_PD_A2SC0 }, + { "a2ir0", 0x400, 0, R8A77970_PD_A2IR0, R8A77970_PD_A3IR }, + { "a2ir1", 0x400, 1, R8A77970_PD_A2IR1, R8A77970_PD_A3IR }, + { "a2ir2", 0x400, 2, R8A77970_PD_A2IR2, R8A77970_PD_A3IR }, + { "a2ir3", 0x400, 3, R8A77970_PD_A2IR3, R8A77970_PD_A3IR }, + { "a2sc0", 0x400, 4, R8A77970_PD_A2SC0, R8A77970_PD_A3IR }, + { "a2sc1", 0x400, 5, R8A77970_PD_A2SC1, R8A77970_PD_A3IR }, }; const struct rcar_sysc_info r8a77970_sysc_info __initconst = { diff --git a/drivers/soc/renesas/r8a77980-sysc.c b/drivers/soc/renesas/r8a77980-sysc.c new file mode 100644 index 000000000000..9265fb525ef3 --- /dev/null +++ b/drivers/soc/renesas/r8a77980-sysc.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Renesas R-Car V3H System Controller + * + * Copyright (C) 2018 Renesas Electronics Corp. + * Copyright (C) 2018 Cogent Embedded, Inc. + */ + +#include <linux/bug.h> +#include <linux/kernel.h> + +#include <dt-bindings/power/r8a77980-sysc.h> + +#include "rcar-sysc.h" + +static const struct rcar_sysc_area r8a77980_areas[] __initconst = { + { "always-on", 0, 0, R8A77980_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, + { "ca53-scu", 0x140, 0, R8A77980_PD_CA53_SCU, R8A77980_PD_ALWAYS_ON, + PD_SCU }, + { "ca53-cpu0", 0x200, 0, R8A77980_PD_CA53_CPU0, R8A77980_PD_CA53_SCU, + PD_CPU_NOCR }, + { "ca53-cpu1", 0x200, 1, R8A77980_PD_CA53_CPU1, R8A77980_PD_CA53_SCU, + PD_CPU_NOCR }, + { "ca53-cpu2", 0x200, 2, R8A77980_PD_CA53_CPU2, R8A77980_PD_CA53_SCU, + PD_CPU_NOCR }, + { "ca53-cpu3", 0x200, 3, R8A77980_PD_CA53_CPU3, R8A77980_PD_CA53_SCU, + PD_CPU_NOCR }, + { "cr7", 0x240, 0, R8A77980_PD_CR7, R8A77980_PD_ALWAYS_ON }, + { "a3ir", 0x180, 0, R8A77980_PD_A3IR, R8A77980_PD_ALWAYS_ON }, + { "a2ir0", 0x400, 0, R8A77980_PD_A2IR0, R8A77980_PD_A3IR }, + { "a2ir1", 0x400, 1, R8A77980_PD_A2IR1, R8A77980_PD_A3IR }, + { "a2ir2", 0x400, 2, R8A77980_PD_A2IR2, R8A77980_PD_A3IR }, + { "a2ir3", 0x400, 3, R8A77980_PD_A2IR3, R8A77980_PD_A3IR }, + { "a2ir4", 0x400, 4, R8A77980_PD_A2IR4, R8A77980_PD_A3IR }, + { "a2ir5", 0x400, 5, R8A77980_PD_A2IR5, R8A77980_PD_A3IR }, + { "a2sc0", 0x400, 6, R8A77980_PD_A2SC0, R8A77980_PD_A3IR }, + { "a2sc1", 0x400, 7, R8A77980_PD_A2SC1, R8A77980_PD_A3IR }, + { "a2sc2", 0x400, 8, R8A77980_PD_A2SC2, R8A77980_PD_A3IR }, + { "a2sc3", 0x400, 9, R8A77980_PD_A2SC3, R8A77980_PD_A3IR }, + { "a2sc4", 0x400, 10, R8A77980_PD_A2SC4, R8A77980_PD_A3IR }, + { "a2pd0", 0x400, 11, R8A77980_PD_A2PD0, R8A77980_PD_A3IR }, + { "a2pd1", 0x400, 12, R8A77980_PD_A2PD1, R8A77980_PD_A3IR }, + { "a2cn", 0x400, 13, R8A77980_PD_A2CN, R8A77980_PD_A3IR }, + { "a3vip", 0x2c0, 0, R8A77980_PD_A3VIP, R8A77980_PD_ALWAYS_ON }, + { "a3vip1", 0x300, 0, R8A77980_PD_A3VIP1, R8A77980_PD_A3VIP }, + { "a3vip2", 0x280, 0, R8A77980_PD_A3VIP2, R8A77980_PD_A3VIP }, +}; + +const struct rcar_sysc_info r8a77980_sysc_info __initconst = { + .areas = r8a77980_areas, + .num_areas = ARRAY_SIZE(r8a77980_areas), +}; diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c index 3316b028f231..8e9cb7996ab0 100644 --- a/drivers/soc/renesas/rcar-rst.c +++ b/drivers/soc/renesas/rcar-rst.c @@ -13,8 +13,18 @@ #include <linux/of_address.h> #include <linux/soc/renesas/rcar-rst.h> +#define WDTRSTCR_RESET 0xA55A0002 +#define WDTRSTCR 0x0054 + +static int rcar_rst_enable_wdt_reset(void __iomem *base) +{ + iowrite32(WDTRSTCR_RESET, base + WDTRSTCR); + return 0; +} + struct rst_config { - unsigned int modemr; /* Mode Monitoring Register Offset */ + unsigned int modemr; /* Mode Monitoring Register Offset */ + int (*configure)(void *base); /* Platform specific configuration */ }; static const struct rst_config rcar_rst_gen1 __initconst = { @@ -23,6 +33,11 @@ static const struct rst_config rcar_rst_gen1 __initconst = { static const struct rst_config rcar_rst_gen2 __initconst = { .modemr = 0x60, + .configure = rcar_rst_enable_wdt_reset, +}; + +static const struct rst_config rcar_rst_gen3 __initconst = { + .modemr = 0x60, }; static const struct of_device_id rcar_rst_matches[] __initconst = { @@ -38,11 +53,13 @@ static const struct of_device_id rcar_rst_matches[] __initconst = { { .compatible = "renesas,r8a7792-rst", .data = &rcar_rst_gen2 }, { .compatible = "renesas,r8a7793-rst", .data = &rcar_rst_gen2 }, { .compatible = "renesas,r8a7794-rst", .data = &rcar_rst_gen2 }, - /* R-Car Gen3 is handled like R-Car Gen2 */ - { .compatible = "renesas,r8a7795-rst", .data = &rcar_rst_gen2 }, - { .compatible = "renesas,r8a7796-rst", .data = &rcar_rst_gen2 }, - { .compatible = "renesas,r8a77970-rst", .data = &rcar_rst_gen2 }, - { .compatible = "renesas,r8a77995-rst", .data = &rcar_rst_gen2 }, + /* R-Car Gen3 */ + { .compatible = "renesas,r8a7795-rst", .data = &rcar_rst_gen3 }, + { .compatible = "renesas,r8a7796-rst", .data = &rcar_rst_gen3 }, + { .compatible = "renesas,r8a77965-rst", .data = &rcar_rst_gen3 }, + { .compatible = "renesas,r8a77970-rst", .data = &rcar_rst_gen3 }, + { .compatible = "renesas,r8a77980-rst", .data = &rcar_rst_gen3 }, + { .compatible = "renesas,r8a77995-rst", .data = &rcar_rst_gen3 }, { /* sentinel */ } }; @@ -71,6 +88,14 @@ static int __init rcar_rst_init(void) rcar_rst_base = base; cfg = match->data; saved_mode = ioread32(base + cfg->modemr); + if (cfg->configure) { + error = cfg->configure(base); + if (error) { + pr_warn("%pOF: Cannot run SoC specific configuration\n", + np); + goto out_put; + } + } pr_debug("%pOF: MODE = 0x%08x\n", np, saved_mode); diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c index 52c25a5e2646..faf20e719361 100644 --- a/drivers/soc/renesas/rcar-sysc.c +++ b/drivers/soc/renesas/rcar-sysc.c @@ -254,7 +254,7 @@ finalize: pm_genpd_init(genpd, gov, false); } -static const struct of_device_id rcar_sysc_matches[] = { +static const struct of_device_id rcar_sysc_matches[] __initconst = { #ifdef CONFIG_SYSC_R8A7743 { .compatible = "renesas,r8a7743-sysc", .data = &r8a7743_sysc_info }, #endif @@ -284,9 +284,15 @@ static const struct of_device_id rcar_sysc_matches[] = { #ifdef CONFIG_SYSC_R8A7796 { .compatible = "renesas,r8a7796-sysc", .data = &r8a7796_sysc_info }, #endif +#ifdef CONFIG_SYSC_R8A77965 + { .compatible = "renesas,r8a77965-sysc", .data = &r8a77965_sysc_info }, +#endif #ifdef CONFIG_SYSC_R8A77970 { .compatible = "renesas,r8a77970-sysc", .data = &r8a77970_sysc_info }, #endif +#ifdef CONFIG_SYSC_R8A77980 + { .compatible = "renesas,r8a77980-sysc", .data = &r8a77980_sysc_info }, +#endif #ifdef CONFIG_SYSC_R8A77995 { .compatible = "renesas,r8a77995-sysc", .data = &r8a77995_sysc_info }, #endif diff --git a/drivers/soc/renesas/rcar-sysc.h b/drivers/soc/renesas/rcar-sysc.h index 9d9daf9eb91b..dcdc9ec8eba7 100644 --- a/drivers/soc/renesas/rcar-sysc.h +++ b/drivers/soc/renesas/rcar-sysc.h @@ -58,7 +58,9 @@ extern const struct rcar_sysc_info r8a7792_sysc_info; extern const struct rcar_sysc_info r8a7794_sysc_info; extern const struct rcar_sysc_info r8a7795_sysc_info; extern const struct rcar_sysc_info r8a7796_sysc_info; +extern const struct rcar_sysc_info r8a77965_sysc_info; extern const struct rcar_sysc_info r8a77970_sysc_info; +extern const struct rcar_sysc_info r8a77980_sysc_info; extern const struct rcar_sysc_info r8a77995_sysc_info; diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c index 926b7fd6db2d..ea71c413c926 100644 --- a/drivers/soc/renesas/renesas-soc.c +++ b/drivers/soc/renesas/renesas-soc.c @@ -144,11 +144,21 @@ static const struct renesas_soc soc_rcar_m3_w __initconst __maybe_unused = { .id = 0x52, }; +static const struct renesas_soc soc_rcar_m3_n __initconst __maybe_unused = { + .family = &fam_rcar_gen3, + .id = 0x55, +}; + static const struct renesas_soc soc_rcar_v3m __initconst __maybe_unused = { .family = &fam_rcar_gen3, .id = 0x54, }; +static const struct renesas_soc soc_rcar_v3h __initconst __maybe_unused = { + .family = &fam_rcar_gen3, + .id = 0x56, +}; + static const struct renesas_soc soc_rcar_d3 __initconst __maybe_unused = { .family = &fam_rcar_gen3, .id = 0x58, @@ -209,9 +219,15 @@ static const struct of_device_id renesas_socs[] __initconst = { #ifdef CONFIG_ARCH_R8A7796 { .compatible = "renesas,r8a7796", .data = &soc_rcar_m3_w }, #endif +#ifdef CONFIG_ARCH_R8A77965 + { .compatible = "renesas,r8a77965", .data = &soc_rcar_m3_n }, +#endif #ifdef CONFIG_ARCH_R8A77970 { .compatible = "renesas,r8a77970", .data = &soc_rcar_v3m }, #endif +#ifdef CONFIG_ARCH_R8A77980 + { .compatible = "renesas,r8a77980", .data = &soc_rcar_v3h }, +#endif #ifdef CONFIG_ARCH_R8A77995 { .compatible = "renesas,r8a77995", .data = &soc_rcar_d3 }, #endif diff --git a/drivers/soc/ti/Kconfig b/drivers/soc/ti/Kconfig index 39e152abe6b9..92770d84a288 100644 --- a/drivers/soc/ti/Kconfig +++ b/drivers/soc/ti/Kconfig @@ -28,6 +28,15 @@ config KEYSTONE_NAVIGATOR_DMA If unsure, say N. +config AMX3_PM + tristate "AMx3 Power Management" + depends on SOC_AM33XX || SOC_AM43XX + depends on WKUP_M3_IPC && TI_EMIF_SRAM && SRAM + help + Enable power management on AM335x and AM437x. Required for suspend to mem + and standby states on both AM335x and AM437x platforms and for deeper cpuidle + c-states on AM335x. + config WKUP_M3_IPC tristate "TI AMx3 Wkup-M3 IPC Driver" depends on WKUP_M3_RPROC diff --git a/drivers/soc/ti/Makefile b/drivers/soc/ti/Makefile index 8e205287f120..a22edc0b258a 100644 --- a/drivers/soc/ti/Makefile +++ b/drivers/soc/ti/Makefile @@ -5,5 +5,6 @@ obj-$(CONFIG_KEYSTONE_NAVIGATOR_QMSS) += knav_qmss.o knav_qmss-y := knav_qmss_queue.o knav_qmss_acc.o obj-$(CONFIG_KEYSTONE_NAVIGATOR_DMA) += knav_dma.o +obj-$(CONFIG_AMX3_PM) += pm33xx.o obj-$(CONFIG_WKUP_M3_IPC) += wkup_m3_ipc.o obj-$(CONFIG_TI_SCI_PM_DOMAINS) += ti_sci_pm_domains.o diff --git a/drivers/soc/ti/pm33xx.c b/drivers/soc/ti/pm33xx.c new file mode 100644 index 000000000000..652739c7f718 --- /dev/null +++ b/drivers/soc/ti/pm33xx.c @@ -0,0 +1,349 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * AM33XX Power Management Routines + * + * Copyright (C) 2012-2018 Texas Instruments Incorporated - http://www.ti.com/ + * Vaibhav Bedia, Dave Gerlach + */ + +#include <linux/cpu.h> +#include <linux/err.h> +#include <linux/genalloc.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_data/pm33xx.h> +#include <linux/platform_device.h> +#include <linux/sizes.h> +#include <linux/sram.h> +#include <linux/suspend.h> +#include <linux/ti-emif-sram.h> +#include <linux/wkup_m3_ipc.h> + +#include <asm/proc-fns.h> +#include <asm/suspend.h> +#include <asm/system_misc.h> + +#define AMX3_PM_SRAM_SYMBOL_OFFSET(sym) ((unsigned long)(sym) - \ + (unsigned long)pm_sram->do_wfi) + +static int (*am33xx_do_wfi_sram)(unsigned long unused); +static phys_addr_t am33xx_do_wfi_sram_phys; + +static struct gen_pool *sram_pool, *sram_pool_data; +static unsigned long ocmcram_location, ocmcram_location_data; + +static struct am33xx_pm_platform_data *pm_ops; +static struct am33xx_pm_sram_addr *pm_sram; + +static struct device *pm33xx_dev; +static struct wkup_m3_ipc *m3_ipc; + +static u32 sram_suspend_address(unsigned long addr) +{ + return ((unsigned long)am33xx_do_wfi_sram + + AMX3_PM_SRAM_SYMBOL_OFFSET(addr)); +} + +#ifdef CONFIG_SUSPEND +static int am33xx_pm_suspend(suspend_state_t suspend_state) +{ + int i, ret = 0; + + ret = pm_ops->soc_suspend((unsigned long)suspend_state, + am33xx_do_wfi_sram); + + if (ret) { + dev_err(pm33xx_dev, "PM: Kernel suspend failure\n"); + } else { + i = m3_ipc->ops->request_pm_status(m3_ipc); + + switch (i) { + case 0: + dev_info(pm33xx_dev, + "PM: Successfully put all powerdomains to target state\n"); + break; + case 1: + dev_err(pm33xx_dev, + "PM: Could not transition all powerdomains to target state\n"); + ret = -1; + break; + default: + dev_err(pm33xx_dev, + "PM: CM3 returned unknown result = %d\n", i); + ret = -1; + } + } + + return ret; +} + +static int am33xx_pm_enter(suspend_state_t suspend_state) +{ + int ret = 0; + + switch (suspend_state) { + case PM_SUSPEND_MEM: + case PM_SUSPEND_STANDBY: + ret = am33xx_pm_suspend(suspend_state); + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static int am33xx_pm_begin(suspend_state_t state) +{ + int ret = -EINVAL; + + switch (state) { + case PM_SUSPEND_MEM: + ret = m3_ipc->ops->prepare_low_power(m3_ipc, WKUP_M3_DEEPSLEEP); + break; + case PM_SUSPEND_STANDBY: + ret = m3_ipc->ops->prepare_low_power(m3_ipc, WKUP_M3_STANDBY); + break; + } + + return ret; +} + +static void am33xx_pm_end(void) +{ + m3_ipc->ops->finish_low_power(m3_ipc); +} + +static int am33xx_pm_valid(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_STANDBY: + case PM_SUSPEND_MEM: + return 1; + default: + return 0; + } +} + +static const struct platform_suspend_ops am33xx_pm_ops = { + .begin = am33xx_pm_begin, + .end = am33xx_pm_end, + .enter = am33xx_pm_enter, + .valid = am33xx_pm_valid, +}; +#endif /* CONFIG_SUSPEND */ + +static void am33xx_pm_set_ipc_ops(void) +{ + u32 resume_address; + int temp; + + temp = ti_emif_get_mem_type(); + if (temp < 0) { + dev_err(pm33xx_dev, "PM: Cannot determine memory type, no PM available\n"); + return; + } + m3_ipc->ops->set_mem_type(m3_ipc, temp); + + /* Physical resume address to be used by ROM code */ + resume_address = am33xx_do_wfi_sram_phys + + *pm_sram->resume_offset + 0x4; + + m3_ipc->ops->set_resume_address(m3_ipc, (void *)resume_address); +} + +static void am33xx_pm_free_sram(void) +{ + gen_pool_free(sram_pool, ocmcram_location, *pm_sram->do_wfi_sz); + gen_pool_free(sram_pool_data, ocmcram_location_data, + sizeof(struct am33xx_pm_ro_sram_data)); +} + +/* + * Push the minimal suspend-resume code to SRAM + */ +static int am33xx_pm_alloc_sram(void) +{ + struct device_node *np; + int ret = 0; + + np = of_find_compatible_node(NULL, NULL, "ti,omap3-mpu"); + if (!np) { + np = of_find_compatible_node(NULL, NULL, "ti,omap4-mpu"); + if (!np) { + dev_err(pm33xx_dev, "PM: %s: Unable to find device node for mpu\n", + __func__); + return -ENODEV; + } + } + + sram_pool = of_gen_pool_get(np, "pm-sram", 0); + if (!sram_pool) { + dev_err(pm33xx_dev, "PM: %s: Unable to get sram pool for ocmcram\n", + __func__); + ret = -ENODEV; + goto mpu_put_node; + } + + sram_pool_data = of_gen_pool_get(np, "pm-sram", 1); + if (!sram_pool_data) { + dev_err(pm33xx_dev, "PM: %s: Unable to get sram data pool for ocmcram\n", + __func__); + ret = -ENODEV; + goto mpu_put_node; + } + + ocmcram_location = gen_pool_alloc(sram_pool, *pm_sram->do_wfi_sz); + if (!ocmcram_location) { + dev_err(pm33xx_dev, "PM: %s: Unable to allocate memory from ocmcram\n", + __func__); + ret = -ENOMEM; + goto mpu_put_node; + } + + ocmcram_location_data = gen_pool_alloc(sram_pool_data, + sizeof(struct emif_regs_amx3)); + if (!ocmcram_location_data) { + dev_err(pm33xx_dev, "PM: Unable to allocate memory from ocmcram\n"); + gen_pool_free(sram_pool, ocmcram_location, *pm_sram->do_wfi_sz); + ret = -ENOMEM; + } + +mpu_put_node: + of_node_put(np); + return ret; +} + +static int am33xx_push_sram_idle(void) +{ + struct am33xx_pm_ro_sram_data ro_sram_data; + int ret; + u32 table_addr, ro_data_addr; + void *copy_addr; + + ro_sram_data.amx3_pm_sram_data_virt = ocmcram_location_data; + ro_sram_data.amx3_pm_sram_data_phys = + gen_pool_virt_to_phys(sram_pool_data, ocmcram_location_data); + + /* Save physical address to calculate resume offset during pm init */ + am33xx_do_wfi_sram_phys = gen_pool_virt_to_phys(sram_pool, + ocmcram_location); + + am33xx_do_wfi_sram = sram_exec_copy(sram_pool, (void *)ocmcram_location, + pm_sram->do_wfi, + *pm_sram->do_wfi_sz); + if (!am33xx_do_wfi_sram) { + dev_err(pm33xx_dev, + "PM: %s: am33xx_do_wfi copy to sram failed\n", + __func__); + return -ENODEV; + } + + table_addr = + sram_suspend_address((unsigned long)pm_sram->emif_sram_table); + ret = ti_emif_copy_pm_function_table(sram_pool, (void *)table_addr); + if (ret) { + dev_dbg(pm33xx_dev, + "PM: %s: EMIF function copy failed\n", __func__); + return -EPROBE_DEFER; + } + + ro_data_addr = + sram_suspend_address((unsigned long)pm_sram->ro_sram_data); + copy_addr = sram_exec_copy(sram_pool, (void *)ro_data_addr, + &ro_sram_data, + sizeof(ro_sram_data)); + if (!copy_addr) { + dev_err(pm33xx_dev, + "PM: %s: ro_sram_data copy to sram failed\n", + __func__); + return -ENODEV; + } + + return 0; +} + +static int am33xx_pm_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + int ret; + + if (!of_machine_is_compatible("ti,am33xx") && + !of_machine_is_compatible("ti,am43")) + return -ENODEV; + + pm_ops = dev->platform_data; + if (!pm_ops) { + dev_err(dev, "PM: Cannot get core PM ops!\n"); + return -ENODEV; + } + + pm_sram = pm_ops->get_sram_addrs(); + if (!pm_sram) { + dev_err(dev, "PM: Cannot get PM asm function addresses!!\n"); + return -ENODEV; + } + + pm33xx_dev = dev; + + ret = am33xx_pm_alloc_sram(); + if (ret) + return ret; + + ret = am33xx_push_sram_idle(); + if (ret) + goto err_free_sram; + + m3_ipc = wkup_m3_ipc_get(); + if (!m3_ipc) { + dev_dbg(dev, "PM: Cannot get wkup_m3_ipc handle\n"); + ret = -EPROBE_DEFER; + goto err_free_sram; + } + + am33xx_pm_set_ipc_ops(); + +#ifdef CONFIG_SUSPEND + suspend_set_ops(&am33xx_pm_ops); +#endif /* CONFIG_SUSPEND */ + + ret = pm_ops->init(); + if (ret) { + dev_err(dev, "Unable to call core pm init!\n"); + ret = -ENODEV; + goto err_put_wkup_m3_ipc; + } + + return 0; + +err_put_wkup_m3_ipc: + wkup_m3_ipc_put(m3_ipc); +err_free_sram: + am33xx_pm_free_sram(); + pm33xx_dev = NULL; + return ret; +} + +static int am33xx_pm_remove(struct platform_device *pdev) +{ + suspend_set_ops(NULL); + wkup_m3_ipc_put(m3_ipc); + am33xx_pm_free_sram(); + return 0; +} + +static struct platform_driver am33xx_pm_driver = { + .driver = { + .name = "pm33xx", + }, + .probe = am33xx_pm_probe, + .remove = am33xx_pm_remove, +}; +module_platform_driver(am33xx_pm_driver); + +MODULE_ALIAS("platform:pm33xx"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("am33xx power management driver"); diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/include/clocksource/timer-ti-dm.h index dd79f3005cdf..7d9598dc578d 100644 --- a/arch/arm/plat-omap/include/plat/dmtimer.h +++ b/include/clocksource/timer-ti-dm.h @@ -1,6 +1,4 @@ /* - * arch/arm/plat-omap/include/plat/dmtimer.h - * * OMAP Dual-Mode Timers * * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ @@ -36,8 +34,8 @@ #include <linux/io.h> #include <linux/platform_device.h> -#ifndef __ASM_ARCH_DMTIMER_H -#define __ASM_ARCH_DMTIMER_H +#ifndef __CLOCKSOURCE_DMTIMER_H +#define __CLOCKSOURCE_DMTIMER_H /* clock sources */ #define OMAP_TIMER_SRC_SYS_CLK 0x00 @@ -75,10 +73,6 @@ */ #define OMAP_TIMER_ERRATA_I103_I767 0x80000000 -struct omap_timer_capability_dev_attr { - u32 timer_capability; -}; - struct timer_regs { u32 tidr; u32 tier; @@ -125,37 +119,13 @@ struct omap_dm_timer { }; int omap_dm_timer_reserve_systimer(int id); -struct omap_dm_timer *omap_dm_timer_request(void); -struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id); struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap); -struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np); -int omap_dm_timer_free(struct omap_dm_timer *timer); -void omap_dm_timer_enable(struct omap_dm_timer *timer); -void omap_dm_timer_disable(struct omap_dm_timer *timer); int omap_dm_timer_get_irq(struct omap_dm_timer *timer); u32 omap_dm_timer_modify_idlect_mask(u32 inputmask); -struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer); int omap_dm_timer_trigger(struct omap_dm_timer *timer); -int omap_dm_timer_start(struct omap_dm_timer *timer); -int omap_dm_timer_stop(struct omap_dm_timer *timer); - -int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source); -int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value); -int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value); -int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match); -int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, int trigger); -int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler); - -int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value); -int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask); - -unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer); -int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value); -unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer); -int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value); int omap_dm_timers_active(void); @@ -276,6 +246,12 @@ int omap_dm_timers_active(void); #define OMAP_TIMER_TICK_INT_MASK_COUNT_REG \ (_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT)) +/* + * The below are inlined to optimize code size for system timers. Other code + * should not need these at all, see + * include/linux/platform_data/pwm_omap_dmtimer.h + */ +#if defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP2PLUS) static inline u32 __omap_dm_timer_read(struct omap_dm_timer *timer, u32 reg, int posted) { @@ -414,5 +390,5 @@ static inline void __omap_dm_timer_write_status(struct omap_dm_timer *timer, { writel_relaxed(value, timer->irq_stat); } - -#endif /* __ASM_ARCH_DMTIMER_H */ +#endif /* CONFIG_ARCH_OMAP1 || CONFIG_ARCH_OMAP2PLUS */ +#endif /* __CLOCKSOURCE_DMTIMER_H */ diff --git a/include/dt-bindings/power/r8a77965-sysc.h b/include/dt-bindings/power/r8a77965-sysc.h new file mode 100644 index 000000000000..05a4b5917314 --- /dev/null +++ b/include/dt-bindings/power/r8a77965-sysc.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 Jacopo Mondi <jacopo+renesas@jmondi.org> + * Copyright (C) 2016 Glider bvba + */ + +#ifndef __DT_BINDINGS_POWER_R8A77965_SYSC_H__ +#define __DT_BINDINGS_POWER_R8A77965_SYSC_H__ + +/* + * These power domain indices match the numbers of the interrupt bits + * representing the power areas in the various Interrupt Registers + * (e.g. SYSCISR, Interrupt Status Register) + */ + +#define R8A77965_PD_CA57_CPU0 0 +#define R8A77965_PD_CA57_CPU1 1 +#define R8A77965_PD_A3VP 9 +#define R8A77965_PD_CA57_SCU 12 +#define R8A77965_PD_CR7 13 +#define R8A77965_PD_A3VC 14 +#define R8A77965_PD_3DG_A 17 +#define R8A77965_PD_3DG_B 18 +#define R8A77965_PD_A3IR 24 +#define R8A77965_PD_A2VC1 26 + +/* Always-on power area */ +#define R8A77965_PD_ALWAYS_ON 32 + +#endif /* __DT_BINDINGS_POWER_R8A77965_SYSC_H__ */ diff --git a/include/dt-bindings/power/r8a77980-sysc.h b/include/dt-bindings/power/r8a77980-sysc.h new file mode 100644 index 000000000000..2c90c1237725 --- /dev/null +++ b/include/dt-bindings/power/r8a77980-sysc.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright (C) 2018 Renesas Electronics Corp. + * Copyright (C) 2018 Cogent Embedded, Inc. + */ +#ifndef __DT_BINDINGS_POWER_R8A77980_SYSC_H__ +#define __DT_BINDINGS_POWER_R8A77980_SYSC_H__ + +/* + * These power domain indices match the numbers of the interrupt bits + * representing the power areas in the various Interrupt Registers + * (e.g. SYSCISR, Interrupt Status Register) + */ + +#define R8A77980_PD_A2SC2 0 +#define R8A77980_PD_A2SC3 1 +#define R8A77980_PD_A2SC4 2 +#define R8A77980_PD_A2PD0 3 +#define R8A77980_PD_A2PD1 4 +#define R8A77980_PD_CA53_CPU0 5 +#define R8A77980_PD_CA53_CPU1 6 +#define R8A77980_PD_CA53_CPU2 7 +#define R8A77980_PD_CA53_CPU3 8 +#define R8A77980_PD_A2CN 10 +#define R8A77980_PD_A3VIP 11 +#define R8A77980_PD_A2IR5 12 +#define R8A77980_PD_CR7 13 +#define R8A77980_PD_A2IR4 15 +#define R8A77980_PD_CA53_SCU 21 +#define R8A77980_PD_A2IR0 23 +#define R8A77980_PD_A3IR 24 +#define R8A77980_PD_A3VIP1 25 +#define R8A77980_PD_A3VIP2 26 +#define R8A77980_PD_A2IR1 27 +#define R8A77980_PD_A2IR2 28 +#define R8A77980_PD_A2IR3 29 +#define R8A77980_PD_A2SC0 30 +#define R8A77980_PD_A2SC1 31 + +/* Always-on power area */ +#define R8A77980_PD_ALWAYS_ON 32 + +#endif /* __DT_BINDINGS_POWER_R8A77980_SYSC_H__ */ diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h index d18da839b810..7e3bceee3489 100644 --- a/include/linux/clk/ti.h +++ b/include/linux/clk/ti.h @@ -203,6 +203,7 @@ enum { TI_CLKM_PRM, TI_CLKM_SCRM, TI_CLKM_CTRL, + TI_CLKM_CTRL_AUX, TI_CLKM_PLLSS, CLK_MAX_MEMMAPS }; diff --git a/include/linux/platform_data/asoc-ti-mcbsp.h b/include/linux/platform_data/asoc-ti-mcbsp.h index e684543254f3..e319d0a2ec82 100644 --- a/include/linux/platform_data/asoc-ti-mcbsp.h +++ b/include/linux/platform_data/asoc-ti-mcbsp.h @@ -25,10 +25,6 @@ #include <linux/spinlock.h> #include <linux/clk.h> -#define MCBSP_CONFIG_TYPE2 0x2 -#define MCBSP_CONFIG_TYPE3 0x3 -#define MCBSP_CONFIG_TYPE4 0x4 - /* Platform specific configuration */ struct omap_mcbsp_ops { void (*request)(unsigned int); @@ -47,14 +43,6 @@ struct omap_mcbsp_platform_data { int (*force_ick_on)(struct clk *clk, bool force_on); }; -/** - * omap_mcbsp_dev_attr - OMAP McBSP device attributes for omap_hwmod - * @sidetone: name of the sidetone device - */ -struct omap_mcbsp_dev_attr { - const char *sidetone; -}; - void omap3_mcbsp_init_pdata_callback(struct omap_mcbsp_platform_data *pdata); #endif diff --git a/include/linux/platform_data/dmtimer-omap.h b/include/linux/platform_data/dmtimer-omap.h index a19b78d826e9..757a0f9e26f9 100644 --- a/include/linux/platform_data/dmtimer-omap.h +++ b/include/linux/platform_data/dmtimer-omap.h @@ -20,12 +20,50 @@ #ifndef __PLATFORM_DATA_DMTIMER_OMAP_H__ #define __PLATFORM_DATA_DMTIMER_OMAP_H__ +struct omap_dm_timer_ops { + struct omap_dm_timer *(*request_by_node)(struct device_node *np); + struct omap_dm_timer *(*request_specific)(int timer_id); + struct omap_dm_timer *(*request)(void); + + int (*free)(struct omap_dm_timer *timer); + + void (*enable)(struct omap_dm_timer *timer); + void (*disable)(struct omap_dm_timer *timer); + + int (*get_irq)(struct omap_dm_timer *timer); + int (*set_int_enable)(struct omap_dm_timer *timer, + unsigned int value); + int (*set_int_disable)(struct omap_dm_timer *timer, u32 mask); + + struct clk *(*get_fclk)(struct omap_dm_timer *timer); + + int (*start)(struct omap_dm_timer *timer); + int (*stop)(struct omap_dm_timer *timer); + int (*set_source)(struct omap_dm_timer *timer, int source); + + int (*set_load)(struct omap_dm_timer *timer, int autoreload, + unsigned int value); + int (*set_match)(struct omap_dm_timer *timer, int enable, + unsigned int match); + int (*set_pwm)(struct omap_dm_timer *timer, int def_on, + int toggle, int trigger); + int (*set_prescaler)(struct omap_dm_timer *timer, int prescaler); + + unsigned int (*read_counter)(struct omap_dm_timer *timer); + int (*write_counter)(struct omap_dm_timer *timer, + unsigned int value); + unsigned int (*read_status)(struct omap_dm_timer *timer); + int (*write_status)(struct omap_dm_timer *timer, + unsigned int value); +}; + struct dmtimer_platform_data { /* set_timer_src - Only used for OMAP1 devices */ int (*set_timer_src)(struct platform_device *pdev, int source); u32 timer_capability; u32 timer_errata; int (*get_context_loss_count)(struct device *); + const struct omap_dm_timer_ops *timer_ops; }; #endif /* __PLATFORM_DATA_DMTIMER_OMAP_H__ */ diff --git a/include/linux/platform_data/gpio-omap.h b/include/linux/platform_data/gpio-omap.h index cb2618147c34..8612855691b2 100644 --- a/include/linux/platform_data/gpio-omap.h +++ b/include/linux/platform_data/gpio-omap.h @@ -157,11 +157,6 @@ #define OMAP_MPUIO(nr) (OMAP_MAX_GPIO_LINES + (nr)) #define OMAP_GPIO_IS_MPUIO(nr) ((nr) >= OMAP_MAX_GPIO_LINES) -struct omap_gpio_dev_attr { - int bank_width; /* GPIO bank width */ - bool dbck_flag; /* dbck required or not - True for OMAP3&4 */ -}; - struct omap_gpio_reg_offs { u16 revision; u16 direction; diff --git a/include/linux/platform_data/mtd-nand-pxa3xx.h b/include/linux/platform_data/mtd-nand-pxa3xx.h index b42ad83cbc20..4fd0f592a2d2 100644 --- a/include/linux/platform_data/mtd-nand-pxa3xx.h +++ b/include/linux/platform_data/mtd-nand-pxa3xx.h @@ -6,41 +6,22 @@ #include <linux/mtd/partitions.h> /* - * Current pxa3xx_nand controller has two chip select which - * both be workable. - * - * Notice should be taken that: - * When you want to use this feature, you should not enable the - * keep configuration feature, for two chip select could be - * attached with different nand chip. The different page size - * and timing requirement make the keep configuration impossible. + * Current pxa3xx_nand controller has two chip select which both be workable but + * historically all platforms remaining on platform data used only one. Switch + * to device tree if you need more. */ - -/* The max num of chip select current support */ -#define NUM_CHIP_SELECT (2) struct pxa3xx_nand_platform_data { - - /* the data flash bus is shared between the Static Memory - * Controller and the Data Flash Controller, the arbiter - * controls the ownership of the bus - */ - int enable_arbiter; - - /* allow platform code to keep OBM/bootloader defined NFC config */ - int keep_config; - - /* indicate how many chip selects will be used */ - int num_cs; - - /* use an flash-based bad block table */ - bool flash_bbt; - - /* requested ECC strength and ECC step size */ + /* Keep OBM/bootloader NFC timing configuration */ + bool keep_config; + /* Use a flash-based bad block table */ + bool flash_bbt; + /* Requested ECC strength and ECC step size */ int ecc_strength, ecc_step_size; - - const struct mtd_partition *parts[NUM_CHIP_SELECT]; - unsigned int nr_parts[NUM_CHIP_SELECT]; + /* Partitions */ + const struct mtd_partition *parts; + unsigned int nr_parts; }; extern void pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info); + #endif /* __ASM_ARCH_PXA3XX_NAND_H */ diff --git a/include/linux/platform_data/phy-da8xx-usb.h b/include/linux/platform_data/phy-da8xx-usb.h new file mode 100644 index 000000000000..85c2b99381b2 --- /dev/null +++ b/include/linux/platform_data/phy-da8xx-usb.h @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * phy-da8xx-usb - TI DaVinci DA8xx USB PHY driver + * + * Copyright (C) 2018 David Lechner <david@lechnology.com> + */ + +#ifndef __LINUX_PLATFORM_DATA_PHY_DA8XX_USB_H__ +#define __LINUX_PLATFORM_DATA_PHY_DA8XX_USB_H__ + +#include <linux/regmap.h> + +/** + * da8xx_usb_phy_platform_data + * @cfgchip: CFGCHIP syscon regmap + */ +struct da8xx_usb_phy_platform_data { + struct regmap *cfgchip; +}; + +#endif /* __LINUX_PLATFORM_DATA_PHY_DA8XX_USB_H__ */ diff --git a/include/linux/platform_data/pm33xx.h b/include/linux/platform_data/pm33xx.h new file mode 100644 index 000000000000..f9bed2a0af9d --- /dev/null +++ b/include/linux/platform_data/pm33xx.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * TI pm33xx platform data + * + * Copyright (C) 2016-2018 Texas Instruments, Inc. + * Dave Gerlach <d-gerlach@ti.com> + */ + +#ifndef _LINUX_PLATFORM_DATA_PM33XX_H +#define _LINUX_PLATFORM_DATA_PM33XX_H + +#include <linux/kbuild.h> +#include <linux/types.h> + +#ifndef __ASSEMBLER__ +struct am33xx_pm_sram_addr { + void (*do_wfi)(void); + unsigned long *do_wfi_sz; + unsigned long *resume_offset; + unsigned long *emif_sram_table; + unsigned long *ro_sram_data; +}; + +struct am33xx_pm_platform_data { + int (*init)(void); + int (*soc_suspend)(unsigned int state, int (*fn)(unsigned long)); + struct am33xx_pm_sram_addr *(*get_sram_addrs)(void); +}; + +struct am33xx_pm_sram_data { + u32 wfi_flags; + u32 l2_aux_ctrl_val; + u32 l2_prefetch_ctrl_val; +} __packed __aligned(8); + +struct am33xx_pm_ro_sram_data { + u32 amx3_pm_sram_data_virt; + u32 amx3_pm_sram_data_phys; +} __packed __aligned(8); + +#endif /* __ASSEMBLER__ */ +#endif /* _LINUX_PLATFORM_DATA_PM33XX_H */ diff --git a/include/linux/platform_data/spi-omap2-mcspi.h b/include/linux/platform_data/spi-omap2-mcspi.h index 13c83a25958a..0bf9fddb8306 100644 --- a/include/linux/platform_data/spi-omap2-mcspi.h +++ b/include/linux/platform_data/spi-omap2-mcspi.h @@ -2,10 +2,6 @@ #ifndef _OMAP2_MCSPI_H #define _OMAP2_MCSPI_H -#define OMAP2_MCSPI_REV 0 -#define OMAP3_MCSPI_REV 1 -#define OMAP4_MCSPI_REV 2 - #define OMAP4_MCSPI_REG_OFFSET 0x100 #define MCSPI_PINDIR_D0_IN_D1_OUT 0 @@ -17,10 +13,6 @@ struct omap2_mcspi_platform_config { unsigned int pin_dir:1; }; -struct omap2_mcspi_dev_attr { - unsigned short num_chipselect; -}; - struct omap2_mcspi_device_config { unsigned turbo_mode:1; diff --git a/include/linux/platform_data/ti-sysc.h b/include/linux/platform_data/ti-sysc.h index 1be356330b96..80ce28d40832 100644 --- a/include/linux/platform_data/ti-sysc.h +++ b/include/linux/platform_data/ti-sysc.h @@ -16,6 +16,10 @@ enum ti_sysc_module_type { TI_SYSC_OMAP4_USB_HOST_FS, }; +struct ti_sysc_cookie { + void *data; +}; + /** * struct sysc_regbits - TI OCP_SYSCONFIG register field offsets * @midle_shift: Offset of the midle bit @@ -41,6 +45,7 @@ struct sysc_regbits { s8 emufree_shift; }; +#define SYSC_QUIRK_LEGACY_IDLE BIT(8) #define SYSC_QUIRK_RESET_STATUS BIT(7) #define SYSC_QUIRK_NO_IDLE_ON_INIT BIT(6) #define SYSC_QUIRK_NO_RESET_ON_INIT BIT(5) @@ -83,4 +88,49 @@ struct sysc_config { u32 quirks; }; +enum sysc_registers { + SYSC_REVISION, + SYSC_SYSCONFIG, + SYSC_SYSSTATUS, + SYSC_MAX_REGS, +}; + +/** + * struct ti_sysc_module_data - ti-sysc to hwmod translation data for a module + * @name: legacy "ti,hwmods" module name + * @module_pa: physical address of the interconnect target module + * @module_size: size of the interconnect target module + * @offsets: array of register offsets as listed in enum sysc_registers + * @nr_offsets: number of registers + * @cap: interconnect target module capabilities + * @cfg: interconnect target module configuration + * + * This data is enough to allocate a new struct omap_hwmod_class_sysconfig + * based on device tree data parsed by ti-sysc driver. + */ +struct ti_sysc_module_data { + const char *name; + u64 module_pa; + u32 module_size; + int *offsets; + int nr_offsets; + const struct sysc_capabilities *cap; + struct sysc_config *cfg; +}; + +struct device; + +struct ti_sysc_platform_data { + struct of_dev_auxdata *auxdata; + int (*init_module)(struct device *dev, + const struct ti_sysc_module_data *data, + struct ti_sysc_cookie *cookie); + int (*enable_module)(struct device *dev, + const struct ti_sysc_cookie *cookie); + int (*idle_module)(struct device *dev, + const struct ti_sysc_cookie *cookie); + int (*shutdown_module)(struct device *dev, + const struct ti_sysc_cookie *cookie); +}; + #endif /* __TI_SYSC_DATA_H__ */ diff --git a/include/linux/power/smartreflex.h b/include/linux/power/smartreflex.h index d8b187c3925d..7b81dad712de 100644 --- a/include/linux/power/smartreflex.h +++ b/include/linux/power/smartreflex.h @@ -143,6 +143,13 @@ #define OMAP3430_SR_ERRWEIGHT 0x04 #define OMAP3430_SR_ERRMAXLIMIT 0x02 +enum sr_instance { + OMAP_SR_MPU, /* shared with iva on omap3 */ + OMAP_SR_CORE, + OMAP_SR_IVA, + OMAP_SR_NR, +}; + struct omap_sr { char *name; struct list_head node; @@ -207,7 +214,6 @@ struct omap_smartreflex_dev_attr { const char *sensor_voltdm_name; }; -#ifdef CONFIG_POWER_AVS_OMAP /* * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR. * The smartreflex class driver should pass the class type. @@ -290,6 +296,8 @@ struct omap_sr_data { struct voltagedomain *voltdm; }; +#ifdef CONFIG_POWER_AVS_OMAP + /* Smartreflex module enable/disable interface */ void omap_sr_enable(struct voltagedomain *voltdm); void omap_sr_disable(struct voltagedomain *voltdm); diff --git a/include/linux/serial_s3c.h b/include/linux/serial_s3c.h index a7f004a3c177..463ed28d2b27 100644 --- a/include/linux/serial_s3c.h +++ b/include/linux/serial_s3c.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Internal header file for Samsung S3C2410 serial ports (UART0-2) * @@ -10,21 +11,7 @@ * Internal header file for MX1ADS serial ports (UART1 & 2) * * Copyright (C) 2002 Shane Nay (shane@minirl.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ + */ #ifndef __ASM_ARM_REGS_SERIAL_H #define __ASM_ARM_REGS_SERIAL_H |