ARM: versatile: move integrator/realview/vexpress to versatile
authorArnd Bergmann <arnd@arndb.de>
Fri, 1 Apr 2022 12:35:42 +0000 (14:35 +0200)
committerArnd Bergmann <arnd@arndb.de>
Mon, 4 Apr 2022 08:22:37 +0000 (10:22 +0200)
These are all fairly small platforms by now, and they are
closely related. Just move them all into a single directory.

Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Liviu Dudau <liviu.dudau@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Tested-by: Sudeep Holla <sudeep.holla@arm.com>
Acked-by: Sudeep Holla <sudeep.holla@arm.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
58 files changed:
MAINTAINERS
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/mach-integrator/Kconfig [deleted file]
arch/arm/mach-integrator/Makefile [deleted file]
arch/arm/mach-integrator/cm.h [deleted file]
arch/arm/mach-integrator/common.h [deleted file]
arch/arm/mach-integrator/core.c [deleted file]
arch/arm/mach-integrator/hardware.h [deleted file]
arch/arm/mach-integrator/integrator_ap.c [deleted file]
arch/arm/mach-integrator/integrator_cp.c [deleted file]
arch/arm/mach-realview/Kconfig [deleted file]
arch/arm/mach-realview/Makefile [deleted file]
arch/arm/mach-realview/platsmp-dt.c [deleted file]
arch/arm/mach-realview/realview-dt.c [deleted file]
arch/arm/mach-versatile/Kconfig
arch/arm/mach-versatile/Makefile
arch/arm/mach-versatile/Makefile.boot [new file with mode: 0644]
arch/arm/mach-versatile/dcscb.c [new file with mode: 0644]
arch/arm/mach-versatile/dcscb_setup.S [new file with mode: 0644]
arch/arm/mach-versatile/headsmp.S [new file with mode: 0644]
arch/arm/mach-versatile/hotplug.c [new file with mode: 0644]
arch/arm/mach-versatile/integrator-cm.h [new file with mode: 0644]
arch/arm/mach-versatile/integrator-hardware.h [new file with mode: 0644]
arch/arm/mach-versatile/integrator.c [new file with mode: 0644]
arch/arm/mach-versatile/integrator.h [new file with mode: 0644]
arch/arm/mach-versatile/integrator_ap.c [new file with mode: 0644]
arch/arm/mach-versatile/integrator_cp.c [new file with mode: 0644]
arch/arm/mach-versatile/platsmp-realview.c [new file with mode: 0644]
arch/arm/mach-versatile/platsmp-vexpress.c [new file with mode: 0644]
arch/arm/mach-versatile/platsmp.c [new file with mode: 0644]
arch/arm/mach-versatile/platsmp.h [new file with mode: 0644]
arch/arm/mach-versatile/realview.c [new file with mode: 0644]
arch/arm/mach-versatile/spc.c [new file with mode: 0644]
arch/arm/mach-versatile/spc.h [new file with mode: 0644]
arch/arm/mach-versatile/tc2_pm.c [new file with mode: 0644]
arch/arm/mach-versatile/v2m-mps2.c [new file with mode: 0644]
arch/arm/mach-versatile/v2m.c [new file with mode: 0644]
arch/arm/mach-versatile/versatile.c [new file with mode: 0644]
arch/arm/mach-versatile/versatile_dt.c [deleted file]
arch/arm/mach-versatile/vexpress.h [new file with mode: 0644]
arch/arm/mach-vexpress/Kconfig [deleted file]
arch/arm/mach-vexpress/Makefile [deleted file]
arch/arm/mach-vexpress/Makefile.boot [deleted file]
arch/arm/mach-vexpress/core.h [deleted file]
arch/arm/mach-vexpress/dcscb.c [deleted file]
arch/arm/mach-vexpress/dcscb_setup.S [deleted file]
arch/arm/mach-vexpress/platsmp.c [deleted file]
arch/arm/mach-vexpress/spc.c [deleted file]
arch/arm/mach-vexpress/spc.h [deleted file]
arch/arm/mach-vexpress/tc2_pm.c [deleted file]
arch/arm/mach-vexpress/v2m-mps2.c [deleted file]
arch/arm/mach-vexpress/v2m.c [deleted file]
arch/arm/plat-versatile/Makefile [deleted file]
arch/arm/plat-versatile/headsmp.S [deleted file]
arch/arm/plat-versatile/hotplug.c [deleted file]
arch/arm/plat-versatile/include/plat/platsmp.h [deleted file]
arch/arm/plat-versatile/platsmp.c [deleted file]

index fd768d43e048299a0cb36fefc86e78fe0388c98f..6a0363b0f106c5c1d2cd464ce60283b566f9d5f5 100644 (file)
@@ -1525,10 +1525,7 @@ F:       Documentation/devicetree/bindings/mtd/mtd-physmap.yaml
 F:     arch/arm/boot/dts/arm-realview-*
 F:     arch/arm/boot/dts/integrator*
 F:     arch/arm/boot/dts/versatile*
-F:     arch/arm/mach-integrator/
-F:     arch/arm/mach-realview/
 F:     arch/arm/mach-versatile/
-F:     arch/arm/plat-versatile/
 F:     drivers/bus/arm-integrator-lm.c
 F:     drivers/clk/versatile/
 F:     drivers/i2c/busses/i2c-versatile.c
index 2e8091e2d8a86d12d40c4d83fce2b2eb9ed43edf..31f024e6e92535bb46faf0cade8d730b66c7eb83 100644 (file)
@@ -622,8 +622,6 @@ source "arch/arm/mach-hisi/Kconfig"
 
 source "arch/arm/mach-imx/Kconfig"
 
-source "arch/arm/mach-integrator/Kconfig"
-
 source "arch/arm/mach-iop32x/Kconfig"
 
 source "arch/arm/mach-ixp4xx/Kconfig"
@@ -675,8 +673,6 @@ source "arch/arm/mach-rda/Kconfig"
 
 source "arch/arm/mach-realtek/Kconfig"
 
-source "arch/arm/mach-realview/Kconfig"
-
 source "arch/arm/mach-rockchip/Kconfig"
 
 source "arch/arm/mach-s3c/Kconfig"
@@ -705,8 +701,6 @@ source "arch/arm/mach-ux500/Kconfig"
 
 source "arch/arm/mach-versatile/Kconfig"
 
-source "arch/arm/mach-vexpress/Kconfig"
-
 source "arch/arm/mach-vt8500/Kconfig"
 
 source "arch/arm/mach-zynq/Kconfig"
index a2391b8de5a556a8bef253b32c0cbd04680b55c8..8740e3a63afb4e45bf7af126438b34567378d3b9 100644 (file)
@@ -179,7 +179,6 @@ machine-$(CONFIG_ARCH_FOOTBRIDGE)   += footbridge
 machine-$(CONFIG_ARCH_GEMINI)          += gemini
 machine-$(CONFIG_ARCH_HIGHBANK)                += highbank
 machine-$(CONFIG_ARCH_HISI)            += hisi
-machine-$(CONFIG_ARCH_INTEGRATOR)      += integrator
 machine-$(CONFIG_ARCH_IOP32X)          += iop32x
 machine-$(CONFIG_ARCH_IXP4XX)          += ixp4xx
 machine-$(CONFIG_ARCH_KEYSTONE)                += keystone
@@ -187,7 +186,6 @@ machine-$(CONFIG_ARCH_LPC18XX)              += lpc18xx
 machine-$(CONFIG_ARCH_LPC32XX)         += lpc32xx
 machine-$(CONFIG_ARCH_MESON)           += meson
 machine-$(CONFIG_ARCH_MMP)             += mmp
-machine-$(CONFIG_ARCH_MPS2)            += vexpress
 machine-$(CONFIG_ARCH_MOXART)          += moxart
 machine-$(CONFIG_ARCH_MV78XX0)         += mv78xx0
 machine-$(CONFIG_ARCH_MVEBU)           += mvebu
@@ -207,7 +205,6 @@ machine-$(CONFIG_ARCH_PXA)          += pxa
 machine-$(CONFIG_ARCH_QCOM)            += qcom
 machine-$(CONFIG_ARCH_RDA)             += rda
 machine-$(CONFIG_ARCH_REALTEK)         += realtek
-machine-$(CONFIG_ARCH_REALVIEW)                += realview
 machine-$(CONFIG_ARCH_ROCKCHIP)                += rockchip
 machine-$(CONFIG_ARCH_RPC)             += rpc
 machine-$(CONFIG_PLAT_SAMSUNG)         += s3c
@@ -220,10 +217,9 @@ machine-$(CONFIG_ARCH_STM32)               += stm32
 machine-$(CONFIG_ARCH_SUNXI)           += sunxi
 machine-$(CONFIG_ARCH_TEGRA)           += tegra
 machine-$(CONFIG_ARCH_U8500)           += ux500
-machine-$(CONFIG_ARCH_VERSATILE)       += versatile
-machine-$(CONFIG_ARCH_VEXPRESS)                += vexpress
 machine-$(CONFIG_ARCH_VT8500)          += vt8500
 machine-$(CONFIG_ARCH_ZYNQ)            += zynq
+machine-$(CONFIG_PLAT_VERSATILE)       += versatile
 machine-$(CONFIG_PLAT_SPEAR)           += spear
 
 # Platform directory name.  This list is sorted alphanumerically
@@ -231,7 +227,6 @@ machine-$(CONFIG_PLAT_SPEAR)                += spear
 plat-$(CONFIG_ARCH_OMAP)       += omap
 plat-$(CONFIG_PLAT_ORION)      += orion
 plat-$(CONFIG_PLAT_PXA)                += pxa
-plat-$(CONFIG_PLAT_VERSATILE)  += versatile
 
 # The byte offset of the kernel image in RAM from the start of RAM.
 TEXT_OFFSET := $(textofs-y)
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig
deleted file mode 100644 (file)
index d61ea61..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-menuconfig ARCH_INTEGRATOR
-       bool "ARM Ltd. Integrator family"
-       depends on ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V6
-       select ARM_AMBA
-       select CMA
-       select DMA_CMA
-       select HAVE_TCM
-       select CLK_ICST
-       select MFD_SYSCON
-       select PLAT_VERSATILE
-       select POWER_RESET
-       select POWER_RESET_VERSATILE
-       select POWER_SUPPLY
-       select SOC_INTEGRATOR_CM
-       select VERSATILE_FPGA_IRQ
-       help
-         Support for ARM's Integrator platform.
-
-if ARCH_INTEGRATOR
-
-config ARCH_INTEGRATOR_AP
-       bool "Support Integrator/AP and Integrator/PP2 platforms"
-       select INTEGRATOR_AP_TIMER
-       select SERIAL_AMBA_PL010 if TTY
-       select SERIAL_AMBA_PL010_CONSOLE if TTY
-       select SOC_BUS
-       help
-         Include support for the ARM(R) Integrator/AP and
-         Integrator/PP2 platforms.
-
-config INTEGRATOR_IMPD1
-       bool "Include support for Integrator/IM-PD1"
-       depends on ARCH_INTEGRATOR_AP
-       select ARM_VIC
-       select GPIO_PL061
-       select GPIOLIB
-       select REGULATOR
-       select REGULATOR_FIXED_VOLTAGE
-       help
-         The IM-PD1 is an add-on logic module for the Integrator which
-         allows ARM(R) Ltd PrimeCells to be developed and evaluated.
-         The IM-PD1 can be found on the Integrator/PP2 platform.
-
-config INTEGRATOR_CM720T
-       bool "Integrator/CM720T core module"
-       depends on ARCH_INTEGRATOR_AP
-       depends on ARCH_MULTI_V4T
-       select CPU_ARM720T
-
-config INTEGRATOR_CM920T
-       bool "Integrator/CM920T core module"
-       depends on ARCH_INTEGRATOR_AP
-       depends on ARCH_MULTI_V4T
-       select CPU_ARM920T
-
-config INTEGRATOR_CM922T_XA10
-       bool "Integrator/CM922T-XA10 core module"
-       depends on ARCH_MULTI_V4T
-       depends on ARCH_INTEGRATOR_AP
-       select CPU_ARM922T
-
-config INTEGRATOR_CM926EJS
-       bool "Integrator/CM926EJ-S core module"
-       depends on ARCH_INTEGRATOR_AP
-       depends on ARCH_MULTI_V5
-       select CPU_ARM926T
-
-config INTEGRATOR_CM10200E_REV0
-       bool "Integrator/CM10200E rev.0 core module"
-       depends on ARCH_INTEGRATOR_AP && n
-       depends on ARCH_MULTI_V5
-       select CPU_ARM1020
-
-config INTEGRATOR_CM10200E
-       bool "Integrator/CM10200E core module"
-       depends on ARCH_INTEGRATOR_AP && n
-       depends on ARCH_MULTI_V5
-       select CPU_ARM1020E
-
-config INTEGRATOR_CM10220E
-       bool "Integrator/CM10220E core module"
-       depends on ARCH_INTEGRATOR_AP
-       depends on ARCH_MULTI_V5
-       select CPU_ARM1022
-
-config INTEGRATOR_CM1026EJS
-       bool "Integrator/CM1026EJ-S core module"
-       depends on ARCH_INTEGRATOR_AP
-       depends on ARCH_MULTI_V5
-       select CPU_ARM1026
-
-config INTEGRATOR_CM1136JFS
-       bool "Integrator/CM1136JF-S core module"
-       depends on ARCH_INTEGRATOR_AP
-       depends on ARCH_MULTI_V6
-       select CPU_V6
-
-config ARCH_INTEGRATOR_CP
-       bool "Support Integrator/CP platform"
-       depends on ARCH_MULTI_V5 || ARCH_MULTI_V6
-       select ARM_TIMER_SP804
-       select SERIAL_AMBA_PL011 if TTY
-       select SERIAL_AMBA_PL011_CONSOLE if TTY
-       select SOC_BUS
-       help
-         Include support for the ARM(R) Integrator CP platform.
-
-config INTEGRATOR_CT926
-       bool "Integrator/CT926 (ARM926EJ-S) core tile"
-       depends on ARCH_INTEGRATOR_CP
-       depends on ARCH_MULTI_V5
-       select CPU_ARM926T
-
-config INTEGRATOR_CTB36
-       bool "Integrator/CTB36 (ARM1136JF-S) core tile"
-       depends on ARCH_INTEGRATOR_CP
-       depends on ARCH_MULTI_V6
-       select CPU_V6
-
-config ARCH_CINTEGRATOR
-       depends on ARCH_INTEGRATOR_CP
-       def_bool y
-
-endif
diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile
deleted file mode 100644 (file)
index 7857a55..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the linux kernel.
-#
-
-# Object file lists.
-
-obj-y                                  := core.o
-obj-$(CONFIG_ARCH_INTEGRATOR_AP)       += integrator_ap.o
-obj-$(CONFIG_ARCH_INTEGRATOR_CP)       += integrator_cp.o
diff --git a/arch/arm/mach-integrator/cm.h b/arch/arm/mach-integrator/cm.h
deleted file mode 100644 (file)
index f09ea18..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * access the core module control register.
- */
-u32 cm_get(void);
-void cm_control(u32, u32);
-
-struct device_node;
-void cm_init(void);
-void cm_clear_irqs(void);
-
-#define CM_CTRL_LED                    (1 << 0)
-#define CM_CTRL_nMBDET                 (1 << 1)
-#define CM_CTRL_REMAP                  (1 << 2)
-
-/*
- * Integrator/AP,PP2 specific
- */
-#define CM_CTRL_HIGHVECTORS            (1 << 4)
-#define CM_CTRL_BIGENDIAN              (1 << 5)
-#define CM_CTRL_FASTBUS                        (1 << 6)
-#define CM_CTRL_SYNC                   (1 << 7)
-
-/*
- * ARM926/946/966 Integrator/CP specific
- */
-#define CM_CTRL_LCDBIASEN              (1 << 8)
-#define CM_CTRL_LCDBIASUP              (1 << 9)
-#define CM_CTRL_LCDBIASDN              (1 << 10)
-#define CM_CTRL_LCDMUXSEL_MASK         (7 << 11)
-#define CM_CTRL_LCDMUXSEL_GENLCD       (1 << 11)
-#define CM_CTRL_LCDMUXSEL_VGA565_TFT555        (2 << 11)
-#define CM_CTRL_LCDMUXSEL_SHARPLCD     (3 << 11)
-#define CM_CTRL_LCDMUXSEL_VGA555_TFT555        (4 << 11)
-#define CM_CTRL_LCDEN0                 (1 << 14)
-#define CM_CTRL_LCDEN1                 (1 << 15)
-#define CM_CTRL_STATIC1                        (1 << 16)
-#define CM_CTRL_STATIC2                        (1 << 17)
-#define CM_CTRL_STATIC                 (1 << 18)
-#define CM_CTRL_n24BITEN               (1 << 19)
-#define CM_CTRL_EBIWP                  (1 << 20)
diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h
deleted file mode 100644 (file)
index f053aee..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <linux/reboot.h>
-#include <linux/amba/serial.h>
-extern struct amba_pl010_data ap_uart_data;
-void integrator_init_early(void);
-int integrator_init(bool is_cp);
-void integrator_reserve(void);
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
deleted file mode 100644 (file)
index 0fe5e1d..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *  linux/arch/arm/mach-integrator/core.c
- *
- *  Copyright (C) 2000-2003 Deep Blue Solutions Ltd
- */
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/export.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/memblock.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/amba/bus.h>
-#include <linux/amba/serial.h>
-#include <linux/io.h>
-#include <linux/stat.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/pgtable.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/time.h>
-
-#include "hardware.h"
-#include "cm.h"
-#include "common.h"
-
-static DEFINE_RAW_SPINLOCK(cm_lock);
-static void __iomem *cm_base;
-
-/**
- * cm_get - get the value from the CM_CTRL register
- */
-u32 cm_get(void)
-{
-       return readl(cm_base + INTEGRATOR_HDR_CTRL_OFFSET);
-}
-
-/**
- * cm_control - update the CM_CTRL register.
- * @mask: bits to change
- * @set: bits to set
- */
-void cm_control(u32 mask, u32 set)
-{
-       unsigned long flags;
-       u32 val;
-
-       raw_spin_lock_irqsave(&cm_lock, flags);
-       val = readl(cm_base + INTEGRATOR_HDR_CTRL_OFFSET) & ~mask;
-       writel(val | set, cm_base + INTEGRATOR_HDR_CTRL_OFFSET);
-       raw_spin_unlock_irqrestore(&cm_lock, flags);
-}
-
-void cm_clear_irqs(void)
-{
-       /* disable core module IRQs */
-       writel(0xffffffffU, cm_base + INTEGRATOR_HDR_IC_OFFSET +
-               IRQ_ENABLE_CLEAR);
-}
-
-static const struct of_device_id cm_match[] = {
-       { .compatible = "arm,core-module-integrator"},
-       { },
-};
-
-void cm_init(void)
-{
-       struct device_node *cm = of_find_matching_node(NULL, cm_match);
-
-       if (!cm) {
-               pr_crit("no core module node found in device tree\n");
-               return;
-       }
-       cm_base = of_iomap(cm, 0);
-       if (!cm_base) {
-               pr_crit("could not remap core module\n");
-               return;
-       }
-       cm_clear_irqs();
-}
-
-/*
- * We need to stop things allocating the low memory; ideally we need a
- * better implementation of GFP_DMA which does not assume that DMA-able
- * memory starts at zero.
- */
-void __init integrator_reserve(void)
-{
-       memblock_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
-}
diff --git a/arch/arm/mach-integrator/hardware.h b/arch/arm/mach-integrator/hardware.h
deleted file mode 100644 (file)
index 81ce09e..0000000
+++ /dev/null
@@ -1,336 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- *  This file contains the hardware definitions of the Integrator.
- *
- *  Copyright (C) 1998-1999 ARM Limited.
- */
-#ifndef INTEGRATOR_HARDWARE_H
-#define INTEGRATOR_HARDWARE_H
-
-/*
- * Where in virtual memory the IO devices (timers, system controllers
- * and so on)
- */
-#define IO_BASE                        0xF0000000                 // VA of IO
-#define IO_SIZE                        0x0B000000                 // How much?
-#define IO_START               INTEGRATOR_HDR_BASE        // PA of IO
-
-/* macro to get at IO space when running virtually */
-#define IO_ADDRESS(x)  (((x) & 0x000fffff) | (((x) >> 4) & 0x0ff00000) | IO_BASE)
-#define __io_address(n)                ((void __iomem *)IO_ADDRESS(n))
-
-/*
- *  Integrator memory map
- */
-#define INTEGRATOR_BOOT_ROM_LO          0x00000000
-#define INTEGRATOR_BOOT_ROM_HI          0x20000000
-#define INTEGRATOR_BOOT_ROM_BASE        INTEGRATOR_BOOT_ROM_HI  /*  Normal position */
-#define INTEGRATOR_BOOT_ROM_SIZE        SZ_512K
-
-/*
- * New Core Modules have different amounts of SSRAM, the amount of SSRAM
- * fitted can be found in HDR_STAT.
- *
- * The symbol INTEGRATOR_SSRAM_SIZE is kept, however this now refers to
- * the minimum amount of SSRAM fitted on any core module.
- *
- * New Core Modules also alias the SSRAM.
- *
- */
-#define INTEGRATOR_SSRAM_BASE           0x00000000
-#define INTEGRATOR_SSRAM_ALIAS_BASE     0x10800000
-#define INTEGRATOR_SSRAM_SIZE           SZ_256K
-
-#define INTEGRATOR_FLASH_BASE           0x24000000
-#define INTEGRATOR_FLASH_SIZE           SZ_32M
-
-#define INTEGRATOR_MBRD_SSRAM_BASE      0x28000000
-#define INTEGRATOR_MBRD_SSRAM_SIZE      SZ_512K
-
-/*
- *  SDRAM is a SIMM therefore the size is not known.
- */
-#define INTEGRATOR_SDRAM_BASE           0x00040000
-
-#define INTEGRATOR_SDRAM_ALIAS_BASE     0x80000000
-#define INTEGRATOR_HDR0_SDRAM_BASE      0x80000000
-#define INTEGRATOR_HDR1_SDRAM_BASE      0x90000000
-#define INTEGRATOR_HDR2_SDRAM_BASE      0xA0000000
-#define INTEGRATOR_HDR3_SDRAM_BASE      0xB0000000
-
-/*
- *  Logic expansion modules
- *
- */
-#define INTEGRATOR_LOGIC_MODULES_BASE   0xC0000000
-#define INTEGRATOR_LOGIC_MODULE0_BASE   0xC0000000
-#define INTEGRATOR_LOGIC_MODULE1_BASE   0xD0000000
-#define INTEGRATOR_LOGIC_MODULE2_BASE   0xE0000000
-#define INTEGRATOR_LOGIC_MODULE3_BASE   0xF0000000
-
-/*
- * Integrator header card registers
- */
-#define INTEGRATOR_HDR_ID_OFFSET        0x00
-#define INTEGRATOR_HDR_PROC_OFFSET      0x04
-#define INTEGRATOR_HDR_OSC_OFFSET       0x08
-#define INTEGRATOR_HDR_CTRL_OFFSET      0x0C
-#define INTEGRATOR_HDR_STAT_OFFSET      0x10
-#define INTEGRATOR_HDR_LOCK_OFFSET      0x14
-#define INTEGRATOR_HDR_SDRAM_OFFSET     0x20
-#define INTEGRATOR_HDR_INIT_OFFSET      0x24    /*  CM9x6 */
-#define INTEGRATOR_HDR_IC_OFFSET        0x40
-#define INTEGRATOR_HDR_SPDBASE_OFFSET   0x100
-#define INTEGRATOR_HDR_SPDTOP_OFFSET    0x200
-
-#define INTEGRATOR_HDR_BASE             0x10000000
-#define INTEGRATOR_HDR_ID               (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_ID_OFFSET)
-#define INTEGRATOR_HDR_PROC             (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_PROC_OFFSET)
-#define INTEGRATOR_HDR_OSC              (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_OSC_OFFSET)
-#define INTEGRATOR_HDR_CTRL             (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_CTRL_OFFSET)
-#define INTEGRATOR_HDR_STAT             (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_STAT_OFFSET)
-#define INTEGRATOR_HDR_LOCK             (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_LOCK_OFFSET)
-#define INTEGRATOR_HDR_SDRAM            (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_SDRAM_OFFSET)
-#define INTEGRATOR_HDR_INIT             (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_INIT_OFFSET)
-#define INTEGRATOR_HDR_IC               (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_IC_OFFSET)
-#define INTEGRATOR_HDR_SPDBASE          (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_SPDBASE_OFFSET)
-#define INTEGRATOR_HDR_SPDTOP           (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_SPDTOP_OFFSET)
-
-#define INTEGRATOR_HDR_CTRL_LED         0x01
-#define INTEGRATOR_HDR_CTRL_MBRD_DETECH 0x02
-#define INTEGRATOR_HDR_CTRL_REMAP       0x04
-#define INTEGRATOR_HDR_CTRL_RESET       0x08
-#define INTEGRATOR_HDR_CTRL_HIGHVECTORS 0x10
-#define INTEGRATOR_HDR_CTRL_BIG_ENDIAN  0x20
-#define INTEGRATOR_HDR_CTRL_FASTBUS     0x40
-#define INTEGRATOR_HDR_CTRL_SYNC        0x80
-
-#define INTEGRATOR_HDR_OSC_CORE_10MHz   0x102
-#define INTEGRATOR_HDR_OSC_CORE_15MHz   0x107
-#define INTEGRATOR_HDR_OSC_CORE_20MHz   0x10C
-#define INTEGRATOR_HDR_OSC_CORE_25MHz   0x111
-#define INTEGRATOR_HDR_OSC_CORE_30MHz   0x116
-#define INTEGRATOR_HDR_OSC_CORE_35MHz   0x11B
-#define INTEGRATOR_HDR_OSC_CORE_40MHz   0x120
-#define INTEGRATOR_HDR_OSC_CORE_45MHz   0x125
-#define INTEGRATOR_HDR_OSC_CORE_50MHz   0x12A
-#define INTEGRATOR_HDR_OSC_CORE_55MHz   0x12F
-#define INTEGRATOR_HDR_OSC_CORE_60MHz   0x134
-#define INTEGRATOR_HDR_OSC_CORE_65MHz   0x139
-#define INTEGRATOR_HDR_OSC_CORE_70MHz   0x13E
-#define INTEGRATOR_HDR_OSC_CORE_75MHz   0x143
-#define INTEGRATOR_HDR_OSC_CORE_80MHz   0x148
-#define INTEGRATOR_HDR_OSC_CORE_85MHz   0x14D
-#define INTEGRATOR_HDR_OSC_CORE_90MHz   0x152
-#define INTEGRATOR_HDR_OSC_CORE_95MHz   0x157
-#define INTEGRATOR_HDR_OSC_CORE_100MHz  0x15C
-#define INTEGRATOR_HDR_OSC_CORE_105MHz  0x161
-#define INTEGRATOR_HDR_OSC_CORE_110MHz  0x166
-#define INTEGRATOR_HDR_OSC_CORE_115MHz  0x16B
-#define INTEGRATOR_HDR_OSC_CORE_120MHz  0x170
-#define INTEGRATOR_HDR_OSC_CORE_125MHz  0x175
-#define INTEGRATOR_HDR_OSC_CORE_130MHz  0x17A
-#define INTEGRATOR_HDR_OSC_CORE_135MHz  0x17F
-#define INTEGRATOR_HDR_OSC_CORE_140MHz  0x184
-#define INTEGRATOR_HDR_OSC_CORE_145MHz  0x189
-#define INTEGRATOR_HDR_OSC_CORE_150MHz  0x18E
-#define INTEGRATOR_HDR_OSC_CORE_155MHz  0x193
-#define INTEGRATOR_HDR_OSC_CORE_160MHz  0x198
-#define INTEGRATOR_HDR_OSC_CORE_MASK    0x7FF
-
-#define INTEGRATOR_HDR_OSC_MEM_10MHz    0x10C000
-#define INTEGRATOR_HDR_OSC_MEM_15MHz    0x116000
-#define INTEGRATOR_HDR_OSC_MEM_20MHz    0x120000
-#define INTEGRATOR_HDR_OSC_MEM_25MHz    0x12A000
-#define INTEGRATOR_HDR_OSC_MEM_30MHz    0x134000
-#define INTEGRATOR_HDR_OSC_MEM_33MHz    0x13A000
-#define INTEGRATOR_HDR_OSC_MEM_40MHz    0x148000
-#define INTEGRATOR_HDR_OSC_MEM_50MHz    0x15C000
-#define INTEGRATOR_HDR_OSC_MEM_60MHz    0x170000
-#define INTEGRATOR_HDR_OSC_MEM_66MHz    0x17C000
-#define INTEGRATOR_HDR_OSC_MEM_MASK     0x7FF000
-
-#define INTEGRATOR_HDR_OSC_BUS_MODE_CM7x0  0x0
-#define INTEGRATOR_HDR_OSC_BUS_MODE_CM9x0  0x0800000
-#define INTEGRATOR_HDR_OSC_BUS_MODE_CM9x6  0x1000000
-#define INTEGRATOR_HDR_OSC_BUS_MODE_CM10x00  0x1800000
-#define INTEGRATOR_HDR_OSC_BUS_MODE_MASK  0x1800000
-
-#define INTEGRATOR_HDR_SDRAM_SPD_OK     (1 << 5)
-
-/*
- * Integrator system registers
- */
-
-/*
- *  System Controller
- */
-#define INTEGRATOR_SC_ID_OFFSET         0x00
-#define INTEGRATOR_SC_OSC_OFFSET        0x04
-#define INTEGRATOR_SC_CTRLS_OFFSET      0x08
-#define INTEGRATOR_SC_CTRLC_OFFSET      0x0C
-#define INTEGRATOR_SC_DEC_OFFSET        0x10
-#define INTEGRATOR_SC_ARB_OFFSET        0x14
-#define INTEGRATOR_SC_LOCK_OFFSET       0x1C
-
-#define INTEGRATOR_SC_BASE              0x11000000
-#define INTEGRATOR_SC_ID                (INTEGRATOR_SC_BASE + INTEGRATOR_SC_ID_OFFSET)
-#define INTEGRATOR_SC_OSC               (INTEGRATOR_SC_BASE + INTEGRATOR_SC_OSC_OFFSET)
-#define INTEGRATOR_SC_CTRLS             (INTEGRATOR_SC_BASE + INTEGRATOR_SC_CTRLS_OFFSET)
-#define INTEGRATOR_SC_CTRLC             (INTEGRATOR_SC_BASE + INTEGRATOR_SC_CTRLC_OFFSET)
-#define INTEGRATOR_SC_DEC               (INTEGRATOR_SC_BASE + INTEGRATOR_SC_DEC_OFFSET)
-#define INTEGRATOR_SC_ARB               (INTEGRATOR_SC_BASE + INTEGRATOR_SC_ARB_OFFSET)
-#define INTEGRATOR_SC_PCIENABLE         (INTEGRATOR_SC_BASE + INTEGRATOR_SC_PCIENABLE_OFFSET)
-#define INTEGRATOR_SC_LOCK              (INTEGRATOR_SC_BASE + INTEGRATOR_SC_LOCK_OFFSET)
-
-#define INTEGRATOR_SC_OSC_SYS_10MHz     0x20
-#define INTEGRATOR_SC_OSC_SYS_15MHz     0x34
-#define INTEGRATOR_SC_OSC_SYS_20MHz     0x48
-#define INTEGRATOR_SC_OSC_SYS_25MHz     0x5C
-#define INTEGRATOR_SC_OSC_SYS_33MHz     0x7C
-#define INTEGRATOR_SC_OSC_SYS_MASK      0xFF
-
-#define INTEGRATOR_SC_OSC_PCI_25MHz     0x100
-#define INTEGRATOR_SC_OSC_PCI_33MHz     0x0
-#define INTEGRATOR_SC_OSC_PCI_MASK      0x100
-
-#define INTEGRATOR_SC_CTRL_SOFTRST      (1 << 0)
-#define INTEGRATOR_SC_CTRL_nFLVPPEN     (1 << 1)
-#define INTEGRATOR_SC_CTRL_nFLWP        (1 << 2)
-#define INTEGRATOR_SC_CTRL_URTS0        (1 << 4)
-#define INTEGRATOR_SC_CTRL_UDTR0        (1 << 5)
-#define INTEGRATOR_SC_CTRL_URTS1        (1 << 6)
-#define INTEGRATOR_SC_CTRL_UDTR1        (1 << 7)
-
-/*
- *  External Bus Interface
- */
-#define INTEGRATOR_EBI_BASE             0x12000000
-
-#define INTEGRATOR_EBI_CSR0_OFFSET      0x00
-#define INTEGRATOR_EBI_CSR1_OFFSET      0x04
-#define INTEGRATOR_EBI_CSR2_OFFSET      0x08
-#define INTEGRATOR_EBI_CSR3_OFFSET      0x0C
-#define INTEGRATOR_EBI_LOCK_OFFSET      0x20
-
-#define INTEGRATOR_EBI_CSR0             (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR0_OFFSET)
-#define INTEGRATOR_EBI_CSR1             (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET)
-#define INTEGRATOR_EBI_CSR2             (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR2_OFFSET)
-#define INTEGRATOR_EBI_CSR3             (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR3_OFFSET)
-#define INTEGRATOR_EBI_LOCK             (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET)
-
-#define INTEGRATOR_EBI_8_BIT            0x00
-#define INTEGRATOR_EBI_16_BIT           0x01
-#define INTEGRATOR_EBI_32_BIT           0x02
-#define INTEGRATOR_EBI_WRITE_ENABLE     0x04
-#define INTEGRATOR_EBI_SYNC             0x08
-#define INTEGRATOR_EBI_WS_2             0x00
-#define INTEGRATOR_EBI_WS_3             0x10
-#define INTEGRATOR_EBI_WS_4             0x20
-#define INTEGRATOR_EBI_WS_5             0x30
-#define INTEGRATOR_EBI_WS_6             0x40
-#define INTEGRATOR_EBI_WS_7             0x50
-#define INTEGRATOR_EBI_WS_8             0x60
-#define INTEGRATOR_EBI_WS_9             0x70
-#define INTEGRATOR_EBI_WS_10            0x80
-#define INTEGRATOR_EBI_WS_11            0x90
-#define INTEGRATOR_EBI_WS_12            0xA0
-#define INTEGRATOR_EBI_WS_13            0xB0
-#define INTEGRATOR_EBI_WS_14            0xC0
-#define INTEGRATOR_EBI_WS_15            0xD0
-#define INTEGRATOR_EBI_WS_16            0xE0
-#define INTEGRATOR_EBI_WS_17            0xF0
-
-
-#define INTEGRATOR_CT_BASE              0x13000000      /*  Counter/Timers */
-#define INTEGRATOR_IC_BASE              0x14000000      /*  Interrupt Controller */
-#define INTEGRATOR_RTC_BASE             0x15000000      /*  Real Time Clock */
-#define INTEGRATOR_UART0_BASE           0x16000000      /*  UART 0 */
-#define INTEGRATOR_UART1_BASE           0x17000000      /*  UART 1 */
-#define INTEGRATOR_KBD_BASE             0x18000000      /*  Keyboard */
-#define INTEGRATOR_MOUSE_BASE           0x19000000      /*  Mouse */
-
-/*
- *  LED's & Switches
- */
-#define INTEGRATOR_DBG_ALPHA_OFFSET     0x00
-#define INTEGRATOR_DBG_LEDS_OFFSET      0x04
-#define INTEGRATOR_DBG_SWITCH_OFFSET    0x08
-
-#define INTEGRATOR_DBG_BASE             0x1A000000
-#define INTEGRATOR_DBG_ALPHA            (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_ALPHA_OFFSET)
-#define INTEGRATOR_DBG_LEDS             (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_LEDS_OFFSET)
-#define INTEGRATOR_DBG_SWITCH           (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_SWITCH_OFFSET)
-
-#define INTEGRATOR_AP_GPIO_BASE                0x1B000000      /* GPIO */
-
-#define INTEGRATOR_CP_MMC_BASE         0x1C000000      /* MMC */
-#define INTEGRATOR_CP_AACI_BASE                0x1D000000      /* AACI */
-#define INTEGRATOR_CP_ETH_BASE         0xC8000000      /* Ethernet */
-#define INTEGRATOR_CP_GPIO_BASE                0xC9000000      /* GPIO */
-#define INTEGRATOR_CP_SIC_BASE         0xCA000000      /* SIC */
-#define INTEGRATOR_CP_CTL_BASE         0xCB000000      /* CP system control */
-
-/* PS2 Keyboard interface */
-#define KMI0_BASE                       INTEGRATOR_KBD_BASE
-
-/* PS2 Mouse interface */
-#define KMI1_BASE                       INTEGRATOR_MOUSE_BASE
-
-/*
- * Integrator Interrupt Controllers
- *
- *
- * Offsets from interrupt controller base
- *
- * System Controller interrupt controller base is
- *
- *     INTEGRATOR_IC_BASE + (header_number << 6)
- *
- * Core Module interrupt controller base is
- *
- *     INTEGRATOR_HDR_IC
- */
-#define IRQ_STATUS                      0
-#define IRQ_RAW_STATUS                  0x04
-#define IRQ_ENABLE                      0x08
-#define IRQ_ENABLE_SET                  0x08
-#define IRQ_ENABLE_CLEAR                0x0C
-
-#define INT_SOFT_SET                    0x10
-#define INT_SOFT_CLEAR                  0x14
-
-#define FIQ_STATUS                      0x20
-#define FIQ_RAW_STATUS                  0x24
-#define FIQ_ENABLE                      0x28
-#define FIQ_ENABLE_SET                  0x28
-#define FIQ_ENABLE_CLEAR                0x2C
-
-
-/*
- * LED's
- */
-#define GREEN_LED                       0x01
-#define YELLOW_LED                      0x02
-#define RED_LED                         0x04
-#define GREEN_LED_2                     0x08
-#define ALL_LEDS                        0x0F
-
-#define LED_BANK                        INTEGRATOR_DBG_LEDS
-
-/*
- *  Timer definitions
- *
- *  Only use timer 1 & 2
- *  (both run at 24MHz and will need the clock divider set to 16).
- *
- *  Timer 0 runs at bus frequency
- */
-#define INTEGRATOR_TIMER0_BASE          INTEGRATOR_CT_BASE
-#define INTEGRATOR_TIMER1_BASE          (INTEGRATOR_CT_BASE + 0x100)
-#define INTEGRATOR_TIMER2_BASE          (INTEGRATOR_CT_BASE + 0x200)
-
-#define INTEGRATOR_CSR_BASE             0x10000000
-#define INTEGRATOR_CSR_SIZE             0x10000000
-
-#endif /* INTEGRATOR_HARDWARE_H */
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
deleted file mode 100644 (file)
index 58b02cb..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *  linux/arch/arm/mach-integrator/integrator_ap.c
- *
- *  Copyright (C) 2000-2003 Deep Blue Solutions Ltd
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/syscore_ops.h>
-#include <linux/amba/bus.h>
-#include <linux/io.h>
-#include <linux/irqchip.h>
-#include <linux/of_irq.h>
-#include <linux/of_address.h>
-#include <linux/of_platform.h>
-#include <linux/termios.h>
-#include <linux/mfd/syscon.h>
-#include <linux/regmap.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include "hardware.h"
-#include "cm.h"
-#include "common.h"
-
-/* Regmap to the AP system controller */
-static struct regmap *ap_syscon_map;
-
-/*
- * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
- * is the (PA >> 12).
- *
- * Setup a VA for the Integrator interrupt controller (for header #0,
- * just for now).
- */
-#define VA_IC_BASE     __io_address(INTEGRATOR_IC_BASE)
-
-/*
- * Logical      Physical
- * f1400000    14000000        Interrupt controller
- * f1600000    16000000        UART 0
- */
-
-static struct map_desc ap_io_desc[] __initdata __maybe_unused = {
-       {
-               .virtual        = IO_ADDRESS(INTEGRATOR_IC_BASE),
-               .pfn            = __phys_to_pfn(INTEGRATOR_IC_BASE),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE
-       }, {
-               .virtual        = IO_ADDRESS(INTEGRATOR_UART0_BASE),
-               .pfn            = __phys_to_pfn(INTEGRATOR_UART0_BASE),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE
-       }
-};
-
-static void __init ap_map_io(void)
-{
-       iotable_init(ap_io_desc, ARRAY_SIZE(ap_io_desc));
-}
-
-#ifdef CONFIG_PM
-static unsigned long ic_irq_enable;
-
-static int irq_suspend(void)
-{
-       ic_irq_enable = readl(VA_IC_BASE + IRQ_ENABLE);
-       return 0;
-}
-
-static void irq_resume(void)
-{
-       /* disable all irq sources */
-       cm_clear_irqs();
-       writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
-       writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
-
-       writel(ic_irq_enable, VA_IC_BASE + IRQ_ENABLE_SET);
-}
-#else
-#define irq_suspend NULL
-#define irq_resume NULL
-#endif
-
-static struct syscore_ops irq_syscore_ops = {
-       .suspend        = irq_suspend,
-       .resume         = irq_resume,
-};
-
-static int __init irq_syscore_init(void)
-{
-       register_syscore_ops(&irq_syscore_ops);
-
-       return 0;
-}
-
-device_initcall(irq_syscore_init);
-
-/*
- * For the PL010 found in the Integrator/AP some of the UART control is
- * implemented in the system controller and accessed using a callback
- * from the driver.
- */
-static void integrator_uart_set_mctrl(struct amba_device *dev,
-                               void __iomem *base, unsigned int mctrl)
-{
-       unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask;
-       u32 phybase = dev->res.start;
-       int ret;
-
-       if (phybase == INTEGRATOR_UART0_BASE) {
-               /* UART0 */
-               rts_mask = 1 << 4;
-               dtr_mask = 1 << 5;
-       } else {
-               /* UART1 */
-               rts_mask = 1 << 6;
-               dtr_mask = 1 << 7;
-       }
-
-       if (mctrl & TIOCM_RTS)
-               ctrlc |= rts_mask;
-       else
-               ctrls |= rts_mask;
-
-       if (mctrl & TIOCM_DTR)
-               ctrlc |= dtr_mask;
-       else
-               ctrls |= dtr_mask;
-
-       ret = regmap_write(ap_syscon_map,
-                          INTEGRATOR_SC_CTRLS_OFFSET,
-                          ctrls);
-       if (ret)
-               pr_err("MODEM: unable to write PL010 UART CTRLS\n");
-
-       ret = regmap_write(ap_syscon_map,
-                          INTEGRATOR_SC_CTRLC_OFFSET,
-                          ctrlc);
-       if (ret)
-               pr_err("MODEM: unable to write PL010 UART CRTLC\n");
-}
-
-struct amba_pl010_data ap_uart_data = {
-       .set_mctrl = integrator_uart_set_mctrl,
-};
-
-void __init ap_init_early(void)
-{
-}
-
-static void __init ap_init_irq_of(void)
-{
-       cm_init();
-       irqchip_init();
-}
-
-/* For the Device Tree, add in the UART callbacks as AUXDATA */
-static struct of_dev_auxdata ap_auxdata_lookup[] __initdata = {
-       OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE,
-               "uart0", &ap_uart_data),
-       OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE,
-               "uart1", &ap_uart_data),
-       { /* sentinel */ },
-};
-
-static const struct of_device_id ap_syscon_match[] = {
-       { .compatible = "arm,integrator-ap-syscon"},
-       { },
-};
-
-static void __init ap_init_of(void)
-{
-       struct device_node *syscon;
-
-       of_platform_default_populate(NULL, ap_auxdata_lookup, NULL);
-
-       syscon = of_find_matching_node(NULL, ap_syscon_match);
-       if (!syscon)
-               return;
-       ap_syscon_map = syscon_node_to_regmap(syscon);
-       if (IS_ERR(ap_syscon_map)) {
-               pr_crit("could not find Integrator/AP system controller\n");
-               return;
-       }
-}
-
-static const char * ap_dt_board_compat[] = {
-       "arm,integrator-ap",
-       NULL,
-};
-
-DT_MACHINE_START(INTEGRATOR_AP_DT, "ARM Integrator/AP (Device Tree)")
-       .reserve        = integrator_reserve,
-       .map_io         = ap_map_io,
-       .init_early     = ap_init_early,
-       .init_irq       = ap_init_irq_of,
-       .init_machine   = ap_init_of,
-       .dt_compat      = ap_dt_board_compat,
-MACHINE_END
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
deleted file mode 100644 (file)
index b7eb403..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *  linux/arch/arm/mach-integrator/integrator_cp.c
- *
- *  Copyright (C) 2003 Deep Blue Solutions Ltd
- */
-#include <linux/kernel.h>
-#include <linux/amba/mmci.h>
-#include <linux/io.h>
-#include <linux/irqchip.h>
-#include <linux/of_irq.h>
-#include <linux/of_address.h>
-#include <linux/of_platform.h>
-#include <linux/sched_clock.h>
-#include <linux/regmap.h>
-#include <linux/mfd/syscon.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include "hardware.h"
-#include "cm.h"
-#include "common.h"
-
-/* Base address to the core module header */
-static struct regmap *cm_map;
-/* Base address to the CP controller */
-static void __iomem *intcp_con_base;
-
-#define CM_COUNTER_OFFSET 0x28
-
-/*
- * Logical      Physical
- * f1400000    14000000        Interrupt controller
- * f1600000    16000000        UART 0
- * fca00000    ca000000        SIC
- */
-
-static struct map_desc intcp_io_desc[] __initdata __maybe_unused = {
-       {
-               .virtual        = IO_ADDRESS(INTEGRATOR_IC_BASE),
-               .pfn            = __phys_to_pfn(INTEGRATOR_IC_BASE),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE
-       }, {
-               .virtual        = IO_ADDRESS(INTEGRATOR_UART0_BASE),
-               .pfn            = __phys_to_pfn(INTEGRATOR_UART0_BASE),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE
-       }, {
-               .virtual        = IO_ADDRESS(INTEGRATOR_CP_SIC_BASE),
-               .pfn            = __phys_to_pfn(INTEGRATOR_CP_SIC_BASE),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE
-       }
-};
-
-static void __init intcp_map_io(void)
-{
-       iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc));
-}
-
-/*
- * It seems that the card insertion interrupt remains active after
- * we've acknowledged it.  We therefore ignore the interrupt, and
- * rely on reading it from the SIC.  This also means that we must
- * clear the latched interrupt.
- */
-static unsigned int mmc_status(struct device *dev)
-{
-       unsigned int status = readl(__io_address(0xca000000 + 4));
-       writel(8, intcp_con_base + 8);
-
-       return status & 8;
-}
-
-static struct mmci_platform_data mmc_data = {
-       .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
-       .status         = mmc_status,
-};
-
-static u64 notrace intcp_read_sched_clock(void)
-{
-       unsigned int val;
-
-       /* MMIO so discard return code */
-       regmap_read(cm_map, CM_COUNTER_OFFSET, &val);
-       return val;
-}
-
-static void __init intcp_init_early(void)
-{
-       cm_map = syscon_regmap_lookup_by_compatible("arm,core-module-integrator");
-       if (IS_ERR(cm_map))
-               return;
-       sched_clock_register(intcp_read_sched_clock, 32, 24000000);
-}
-
-static void __init intcp_init_irq_of(void)
-{
-       cm_init();
-       irqchip_init();
-}
-
-/*
- * For the Device Tree, add in the UART, MMC and CLCD specifics as AUXDATA
- * and enforce the bus names since these are used for clock lookups.
- */
-static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = {
-       OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_CP_MMC_BASE,
-               "mmci", &mmc_data),
-       { /* sentinel */ },
-};
-
-static const struct of_device_id intcp_syscon_match[] = {
-       { .compatible = "arm,integrator-cp-syscon"},
-       { },
-};
-
-static void __init intcp_init_of(void)
-{
-       struct device_node *cpcon;
-
-       cpcon = of_find_matching_node(NULL, intcp_syscon_match);
-       if (!cpcon)
-               return;
-
-       intcp_con_base = of_iomap(cpcon, 0);
-       if (!intcp_con_base)
-               return;
-
-       of_platform_default_populate(NULL, intcp_auxdata_lookup, NULL);
-}
-
-static const char * intcp_dt_board_compat[] = {
-       "arm,integrator-cp",
-       NULL,
-};
-
-DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)")
-       .reserve        = integrator_reserve,
-       .map_io         = intcp_map_io,
-       .init_early     = intcp_init_early,
-       .init_irq       = intcp_init_irq_of,
-       .init_machine   = intcp_init_of,
-       .dt_compat      = intcp_dt_board_compat,
-MACHINE_END
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
deleted file mode 100644 (file)
index a4c3602..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-menuconfig ARCH_REALVIEW
-       bool "ARM Ltd. RealView family"
-       depends on ARCH_MULTI_V5 || ARCH_MULTI_V6 || ARCH_MULTI_V7
-       select ARM_AMBA
-       select ARM_GIC
-       select ARM_TIMER_SP804
-       select CLK_SP810
-       select GPIO_PL061 if GPIOLIB
-       select HAVE_ARM_SCU if SMP
-       select HAVE_ARM_TWD if SMP
-       select HAVE_PATA_PLATFORM
-       select HAVE_TCM
-       select CLK_ICST
-       select MACH_REALVIEW_EB if ARCH_MULTI_V5
-       select MFD_SYSCON
-       select PLAT_VERSATILE
-       select POWER_RESET
-       select POWER_RESET_VERSATILE
-       select POWER_SUPPLY
-       select SOC_REALVIEW
-       help
-         This enables support for ARM Ltd RealView boards.
-
-if ARCH_REALVIEW
-
-config MACH_REALVIEW_EB
-       bool "Support RealView(R) Emulation Baseboard"
-       select ARM_GIC
-       select CPU_ARM926T if ARCH_MULTI_V5
-       help
-         Include support for the ARM(R) RealView(R) Emulation Baseboard
-         platform. On an ARMv5 kernel, this will include support for
-         the ARM926EJ-S core tile, while on an ARMv6/v7 kernel, at least
-         one of the ARM1136, ARM1176, ARM11MPCore or Cortex-A9MPCore
-         core tile options should be enabled.
-
-config REALVIEW_EB_ARM1136
-       bool "Support ARM1136J(F)-S Tile"
-       depends on MACH_REALVIEW_EB && ARCH_MULTI_V6
-       select CPU_V6
-       help
-         Enable support for the ARM1136 tile fitted to the
-         Realview(R) Emulation Baseboard platform.
-
-config REALVIEW_EB_ARM1176
-       bool "Support ARM1176JZ(F)-S Tile"
-       depends on MACH_REALVIEW_EB && ARCH_MULTI_V6
-       help
-         Enable support for the ARM1176 tile fitted to the
-         Realview(R) Emulation Baseboard platform.
-
-config REALVIEW_EB_A9MP
-       bool "Support Multicore Cortex-A9 Tile"
-       depends on MACH_REALVIEW_EB && ARCH_MULTI_V7
-       help
-         Enable support for the Cortex-A9MPCore tile fitted to the
-         Realview(R) Emulation Baseboard platform.
-
-config REALVIEW_EB_ARM11MP
-       bool "Support ARM11MPCore Tile"
-       depends on MACH_REALVIEW_EB && ARCH_MULTI_V6
-       select HAVE_SMP
-       help
-         Enable support for the ARM11MPCore tile fitted to the Realview(R)
-         Emulation Baseboard platform.
-
-config MACH_REALVIEW_PB11MP
-       bool "Support RealView(R) Platform Baseboard for ARM11MPCore"
-       depends on ARCH_MULTI_V6
-       select HAVE_SMP
-       help
-         Include support for the ARM(R) RealView(R) Platform Baseboard for
-         the ARM11MPCore.  This platform has an on-board ARM11MPCore and has
-         support for PCI-E and Compact Flash.
-
-# ARMv6 CPU without K extensions, but does have the new exclusive ops
-config MACH_REALVIEW_PB1176
-       bool "Support RealView(R) Platform Baseboard for ARM1176JZF-S"
-       depends on ARCH_MULTI_V6
-       select CPU_V6
-       select HAVE_TCM
-       help
-         Include support for the ARM(R) RealView(R) Platform Baseboard for
-         ARM1176JZF-S.
-
-config MACH_REALVIEW_PBA8
-       bool "Support RealView(R) Platform Baseboard for Cortex(tm)-A8 platform"
-       depends on ARCH_MULTI_V7
-       help
-         Include support for the ARM(R) RealView Platform Baseboard for
-         Cortex(tm)-A8.  This platform has an on-board Cortex-A8 and has
-         support for PCI-E and Compact Flash.
-
-config MACH_REALVIEW_PBX
-       bool "Support RealView(R) Platform Baseboard Explore for Cortex-A9"
-       depends on ARCH_MULTI_V7
-       select ZONE_DMA
-       help
-         Include support for the ARM(R) RealView(R) Platform Baseboard
-         Explore.
-
-endif
diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile
deleted file mode 100644 (file)
index e259091..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Makefile for the linux kernel.
-#
-ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/arch/arm/plat-versatile/include
-
-obj-y                                  += realview-dt.o
-obj-$(CONFIG_SMP)                      += platsmp-dt.o
diff --git a/arch/arm/mach-realview/platsmp-dt.c b/arch/arm/mach-realview/platsmp-dt.c
deleted file mode 100644 (file)
index 5ae7837..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2015 Linus Walleij
- */
-#include <linux/smp.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/regmap.h>
-#include <linux/mfd/syscon.h>
-
-#include <asm/cacheflush.h>
-#include <asm/smp_plat.h>
-#include <asm/smp_scu.h>
-
-#include <plat/platsmp.h>
-
-#define REALVIEW_SYS_FLAGSSET_OFFSET   0x30
-
-static const struct of_device_id realview_scu_match[] = {
-       { .compatible = "arm,arm11mp-scu", },
-       { .compatible = "arm,cortex-a9-scu", },
-       { .compatible = "arm,cortex-a5-scu", },
-       { }
-};
-
-static const struct of_device_id realview_syscon_match[] = {
-        { .compatible = "arm,core-module-integrator", },
-        { .compatible = "arm,realview-eb-syscon", },
-        { .compatible = "arm,realview-pb11mp-syscon", },
-        { .compatible = "arm,realview-pbx-syscon", },
-        { },
-};
-
-static void __init realview_smp_prepare_cpus(unsigned int max_cpus)
-{
-       struct device_node *np;
-       void __iomem *scu_base;
-       struct regmap *map;
-       unsigned int ncores;
-       int i;
-
-       np = of_find_matching_node(NULL, realview_scu_match);
-       if (!np) {
-               pr_err("PLATSMP: No SCU base address\n");
-               return;
-       }
-       scu_base = of_iomap(np, 0);
-       of_node_put(np);
-       if (!scu_base) {
-               pr_err("PLATSMP: No SCU remap\n");
-               return;
-       }
-
-       scu_enable(scu_base);
-       ncores = scu_get_core_count(scu_base);
-       pr_info("SCU: %d cores detected\n", ncores);
-       for (i = 0; i < ncores; i++)
-               set_cpu_possible(i, true);
-       iounmap(scu_base);
-
-       /* The syscon contains the magic SMP start address registers */
-       np = of_find_matching_node(NULL, realview_syscon_match);
-       if (!np) {
-               pr_err("PLATSMP: No syscon match\n");
-               return;
-       }
-       map = syscon_node_to_regmap(np);
-       if (IS_ERR(map)) {
-               pr_err("PLATSMP: No syscon regmap\n");
-               return;
-       }
-       /* Put the boot address in this magic register */
-       regmap_write(map, REALVIEW_SYS_FLAGSSET_OFFSET,
-                    __pa_symbol(versatile_secondary_startup));
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-static void realview_cpu_die(unsigned int cpu)
-{
-       return versatile_immitation_cpu_die(cpu, 0x20);
-}
-#endif
-
-static const struct smp_operations realview_dt_smp_ops __initconst = {
-       .smp_prepare_cpus       = realview_smp_prepare_cpus,
-       .smp_secondary_init     = versatile_secondary_init,
-       .smp_boot_secondary     = versatile_boot_secondary,
-#ifdef CONFIG_HOTPLUG_CPU
-       .cpu_die                = realview_cpu_die,
-#endif
-};
-CPU_METHOD_OF_DECLARE(realview_smp, "arm,realview-smp", &realview_dt_smp_ops);
diff --git a/arch/arm/mach-realview/realview-dt.c b/arch/arm/mach-realview/realview-dt.c
deleted file mode 100644 (file)
index feab660..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2014 Linaro Ltd.
- *
- * Author: Linus Walleij <linus.walleij@linaro.org>
- */
-#include <linux/of_platform.h>
-#include <asm/mach/arch.h>
-#include <asm/hardware/cache-l2x0.h>
-
-static const char *const realview_dt_platform_compat[] __initconst = {
-       "arm,realview-eb",
-       "arm,realview-pb1176",
-       "arm,realview-pb11mp",
-       "arm,realview-pba8",
-       "arm,realview-pbx",
-       NULL,
-};
-
-DT_MACHINE_START(REALVIEW_DT, "ARM RealView Machine (Device Tree Support)")
-#ifdef CONFIG_ZONE_DMA
-       .dma_zone_size  = SZ_256M,
-#endif
-       .dt_compat      = realview_dt_platform_compat,
-       .l2c_aux_val = 0x0,
-       .l2c_aux_mask = ~0x0,
-MACHINE_END
index f78a1d358031d3f17d4c75c7dc6838079fb9e0c0..94b492c12e8d8e997a16b095c92b7123192134db 100644 (file)
@@ -16,3 +16,311 @@ config ARCH_VERSATILE
        help
          This enables support for ARM Ltd Versatile board.
 
+menuconfig ARCH_INTEGRATOR
+       bool "ARM Ltd. Integrator family"
+       depends on ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V6
+       select ARM_AMBA
+       select CMA
+       select DMA_CMA
+       select HAVE_TCM
+       select CLK_ICST
+       select MFD_SYSCON
+       select PLAT_VERSATILE
+       select POWER_RESET
+       select POWER_RESET_VERSATILE
+       select POWER_SUPPLY
+       select SOC_INTEGRATOR_CM
+       select VERSATILE_FPGA_IRQ
+       help
+         Support for ARM's Integrator platform.
+
+if ARCH_INTEGRATOR
+
+config ARCH_INTEGRATOR_AP
+       bool "Support Integrator/AP and Integrator/PP2 platforms"
+       select INTEGRATOR_AP_TIMER
+       select SERIAL_AMBA_PL010 if TTY
+       select SERIAL_AMBA_PL010_CONSOLE if TTY
+       select SOC_BUS
+       help
+         Include support for the ARM(R) Integrator/AP and
+         Integrator/PP2 platforms.
+
+config INTEGRATOR_IMPD1
+       bool "Include support for Integrator/IM-PD1"
+       depends on ARCH_INTEGRATOR_AP
+       select ARM_VIC
+       select GPIO_PL061
+       select GPIOLIB
+       select REGULATOR
+       select REGULATOR_FIXED_VOLTAGE
+       help
+         The IM-PD1 is an add-on logic module for the Integrator which
+         allows ARM(R) Ltd PrimeCells to be developed and evaluated.
+         The IM-PD1 can be found on the Integrator/PP2 platform.
+
+config INTEGRATOR_CM720T
+       bool "Integrator/CM720T core module"
+       depends on ARCH_INTEGRATOR_AP
+       depends on ARCH_MULTI_V4T
+       select CPU_ARM720T
+
+config INTEGRATOR_CM920T
+       bool "Integrator/CM920T core module"
+       depends on ARCH_INTEGRATOR_AP
+       depends on ARCH_MULTI_V4T
+       select CPU_ARM920T
+
+config INTEGRATOR_CM922T_XA10
+       bool "Integrator/CM922T-XA10 core module"
+       depends on ARCH_MULTI_V4T
+       depends on ARCH_INTEGRATOR_AP
+       select CPU_ARM922T
+
+config INTEGRATOR_CM926EJS
+       bool "Integrator/CM926EJ-S core module"
+       depends on ARCH_INTEGRATOR_AP
+       depends on ARCH_MULTI_V5
+       select CPU_ARM926T
+
+config INTEGRATOR_CM10200E_REV0
+       bool "Integrator/CM10200E rev.0 core module"
+       depends on ARCH_INTEGRATOR_AP && n
+       depends on ARCH_MULTI_V5
+       select CPU_ARM1020
+
+config INTEGRATOR_CM10200E
+       bool "Integrator/CM10200E core module"
+       depends on ARCH_INTEGRATOR_AP && n
+       depends on ARCH_MULTI_V5
+       select CPU_ARM1020E
+
+config INTEGRATOR_CM10220E
+       bool "Integrator/CM10220E core module"
+       depends on ARCH_INTEGRATOR_AP
+       depends on ARCH_MULTI_V5
+       select CPU_ARM1022
+
+config INTEGRATOR_CM1026EJS
+       bool "Integrator/CM1026EJ-S core module"
+       depends on ARCH_INTEGRATOR_AP
+       depends on ARCH_MULTI_V5
+       select CPU_ARM1026
+
+config INTEGRATOR_CM1136JFS
+       bool "Integrator/CM1136JF-S core module"
+       depends on ARCH_INTEGRATOR_AP
+       depends on ARCH_MULTI_V6
+       select CPU_V6
+
+config ARCH_INTEGRATOR_CP
+       bool "Support Integrator/CP platform"
+       depends on ARCH_MULTI_V5 || ARCH_MULTI_V6
+       select ARM_TIMER_SP804
+       select SERIAL_AMBA_PL011 if TTY
+       select SERIAL_AMBA_PL011_CONSOLE if TTY
+       select SOC_BUS
+       help
+         Include support for the ARM(R) Integrator CP platform.
+
+config INTEGRATOR_CT926
+       bool "Integrator/CT926 (ARM926EJ-S) core tile"
+       depends on ARCH_INTEGRATOR_CP
+       depends on ARCH_MULTI_V5
+       select CPU_ARM926T
+
+config INTEGRATOR_CTB36
+       bool "Integrator/CTB36 (ARM1136JF-S) core tile"
+       depends on ARCH_INTEGRATOR_CP
+       depends on ARCH_MULTI_V6
+       select CPU_V6
+
+config ARCH_CINTEGRATOR
+       depends on ARCH_INTEGRATOR_CP
+       def_bool y
+
+endif
+
+menuconfig ARCH_REALVIEW
+       bool "ARM Ltd. RealView family"
+       depends on ARCH_MULTI_V5 || ARCH_MULTI_V6 || ARCH_MULTI_V7
+       select ARM_AMBA
+       select ARM_GIC
+       select ARM_TIMER_SP804
+       select CLK_SP810
+       select GPIO_PL061 if GPIOLIB
+       select HAVE_ARM_SCU if SMP
+       select HAVE_ARM_TWD if SMP
+       select HAVE_PATA_PLATFORM
+       select HAVE_TCM
+       select CLK_ICST
+       select MACH_REALVIEW_EB if ARCH_MULTI_V5
+       select MFD_SYSCON
+       select PLAT_VERSATILE
+       select POWER_RESET
+       select POWER_RESET_VERSATILE
+       select POWER_SUPPLY
+       select SOC_REALVIEW
+       help
+         This enables support for ARM Ltd RealView boards.
+
+if ARCH_REALVIEW
+
+config MACH_REALVIEW_EB
+       bool "Support RealView(R) Emulation Baseboard"
+       select ARM_GIC
+       select CPU_ARM926T if ARCH_MULTI_V5
+       help
+         Include support for the ARM(R) RealView(R) Emulation Baseboard
+         platform. On an ARMv5 kernel, this will include support for
+         the ARM926EJ-S core tile, while on an ARMv6/v7 kernel, at least
+         one of the ARM1136, ARM1176, ARM11MPCore or Cortex-A9MPCore
+         core tile options should be enabled.
+
+config REALVIEW_EB_ARM1136
+       bool "Support ARM1136J(F)-S Tile"
+       depends on MACH_REALVIEW_EB && ARCH_MULTI_V6
+       select CPU_V6
+       help
+         Enable support for the ARM1136 tile fitted to the
+         Realview(R) Emulation Baseboard platform.
+
+config REALVIEW_EB_ARM1176
+       bool "Support ARM1176JZ(F)-S Tile"
+       depends on MACH_REALVIEW_EB && ARCH_MULTI_V6
+       help
+         Enable support for the ARM1176 tile fitted to the
+         Realview(R) Emulation Baseboard platform.
+
+config REALVIEW_EB_A9MP
+       bool "Support Multicore Cortex-A9 Tile"
+       depends on MACH_REALVIEW_EB && ARCH_MULTI_V7
+       help
+         Enable support for the Cortex-A9MPCore tile fitted to the
+         Realview(R) Emulation Baseboard platform.
+
+config REALVIEW_EB_ARM11MP
+       bool "Support ARM11MPCore Tile"
+       depends on MACH_REALVIEW_EB && ARCH_MULTI_V6
+       select HAVE_SMP
+       help
+         Enable support for the ARM11MPCore tile fitted to the Realview(R)
+         Emulation Baseboard platform.
+
+config MACH_REALVIEW_PB11MP
+       bool "Support RealView(R) Platform Baseboard for ARM11MPCore"
+       depends on ARCH_MULTI_V6
+       select HAVE_SMP
+       help
+         Include support for the ARM(R) RealView(R) Platform Baseboard for
+         the ARM11MPCore.  This platform has an on-board ARM11MPCore and has
+         support for PCI-E and Compact Flash.
+
+# ARMv6 CPU without K extensions, but does have the new exclusive ops
+config MACH_REALVIEW_PB1176
+       bool "Support RealView(R) Platform Baseboard for ARM1176JZF-S"
+       depends on ARCH_MULTI_V6
+       select CPU_V6
+       select HAVE_TCM
+       help
+         Include support for the ARM(R) RealView(R) Platform Baseboard for
+         ARM1176JZF-S.
+
+config MACH_REALVIEW_PBA8
+       bool "Support RealView(R) Platform Baseboard for Cortex(tm)-A8 platform"
+       depends on ARCH_MULTI_V7
+       help
+         Include support for the ARM(R) RealView Platform Baseboard for
+         Cortex(tm)-A8.  This platform has an on-board Cortex-A8 and has
+         support for PCI-E and Compact Flash.
+
+config MACH_REALVIEW_PBX
+       bool "Support RealView(R) Platform Baseboard Explore for Cortex-A9"
+       depends on ARCH_MULTI_V7
+       select ZONE_DMA
+       help
+         Include support for the ARM(R) RealView(R) Platform Baseboard
+         Explore.
+
+endif
+
+menuconfig ARCH_VEXPRESS
+       bool "ARM Ltd. Versatile Express family"
+       depends on ARCH_MULTI_V7
+       select ARCH_SUPPORTS_BIG_ENDIAN
+       select ARM_AMBA
+       select ARM_GIC
+       select ARM_GLOBAL_TIMER
+       select ARM_TIMER_SP804
+       select GPIOLIB
+       select HAVE_ARM_SCU if SMP
+       select HAVE_ARM_TWD if SMP
+       select HAVE_PATA_PLATFORM
+       select CLK_ICST
+       select NO_IOPORT_MAP
+       select PLAT_VERSATILE
+       select POWER_RESET
+       select POWER_RESET_VEXPRESS
+       select POWER_SUPPLY
+       select REGULATOR if MMC_ARMMMCI
+       select REGULATOR_FIXED_VOLTAGE if REGULATOR
+       select VEXPRESS_CONFIG
+       help
+         This option enables support for systems using Cortex processor based
+         ARM core and logic (FPGA) tiles on the Versatile Express motherboard,
+         for example:
+
+         - CoreTile Express A5x2 (V2P-CA5s)
+         - CoreTile Express A9x4 (V2P-CA9)
+         - CoreTile Express A15x2 (V2P-CA15)
+         - LogicTile Express 13MG (V2F-2XV6) with A5, A7, A9 or A15 SMMs
+           (Soft Macrocell Models)
+         - Versatile Express RTSMs (Models)
+
+         You must boot using a Flattened Device Tree in order to use these
+         platforms. The traditional (ATAGs) boot method is not usable on
+         these boards with this option.
+
+if ARCH_VEXPRESS
+
+config ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA
+       bool "Enable A5 and A9 only errata work-arounds"
+       default y
+       select ARM_ERRATA_643719 if SMP
+       select ARM_ERRATA_720789
+       select PL310_ERRATA_753970 if CACHE_L2X0
+       help
+         Provides common dependencies for Versatile Express platforms
+         based on Cortex-A5 and Cortex-A9 processors. In order to
+         build a working kernel, you must also enable relevant core
+         tile support or Flattened Device Tree based support options.
+
+config ARCH_VEXPRESS_DCSCB
+       bool "Dual Cluster System Control Block (DCSCB) support"
+       depends on MCPM
+       select ARM_CCI400_PORT_CTRL
+       help
+         Support for the Dual Cluster System Configuration Block (DCSCB).
+         This is needed to provide CPU and cluster power management
+         on RTSM implementing big.LITTLE.
+
+config ARCH_VEXPRESS_SPC
+       bool "Versatile Express Serial Power Controller (SPC)"
+       select PM_OPP
+       help
+         The TC2 (A15x2 A7x3) versatile express core tile integrates a logic
+         block called Serial Power Controller (SPC) that provides the interface
+         between the dual cluster test-chip and the M3 microcontroller that
+         carries out power management.
+
+config ARCH_VEXPRESS_TC2_PM
+       bool "Versatile Express TC2 power management"
+       depends on MCPM
+       select ARM_CCI400_PORT_CTRL
+       select ARCH_VEXPRESS_SPC
+       select ARM_CPU_SUSPEND
+       help
+         Support for CPU and cluster power management on Versatile Express
+         with a TC2 (A15x2 A7x3) big.LITTLE core tile.
+
+endif
index 2b907718d46742f1d5fec7b1b80a46d45e5f3ef1..27d712bcf1afd1c84e934a258d12d0129ddced98 100644 (file)
@@ -3,4 +3,34 @@
 # Makefile for the linux kernel.
 #
 
-obj-y                                  := versatile_dt.o
+# versatile
+obj-$(CONFIG_ARCH_VERSATILE)           += versatile.o
+
+# integrator
+obj-$(CONFIG_ARCH_INTEGRATOR)          += integrator.o
+obj-$(CONFIG_ARCH_INTEGRATOR_AP)       += integrator_ap.o
+obj-$(CONFIG_ARCH_INTEGRATOR_CP)       += integrator_cp.o
+
+# realview
+obj-$(CONFIG_ARCH_REALVIEW)            += realview.o
+
+# vexpress
+obj-$(CONFIG_ARCH_VEXPRESS)            := v2m.o
+obj-$(CONFIG_ARCH_VEXPRESS_DCSCB)      += dcscb.o      dcscb_setup.o
+CFLAGS_dcscb.o                         += -march=armv7-a
+CFLAGS_REMOVE_dcscb.o                  = -pg
+obj-$(CONFIG_ARCH_VEXPRESS_SPC)                += spc.o
+CFLAGS_REMOVE_spc.o                    = -pg
+obj-$(CONFIG_ARCH_VEXPRESS_TC2_PM)     += tc2_pm.o
+CFLAGS_tc2_pm.o                                += -march=armv7-a
+CFLAGS_REMOVE_tc2_pm.o                 = -pg
+
+# mps2
+obj-$(CONFIG_ARCH_MPS2)                        += v2m-mps2.o
+
+ifdef CONFIG_SMP
+obj-y                                  += headsmp.o platsmp.o
+obj-$(CONFIG_ARCH_REALVIEW)            += platsmp-realview.o
+obj-$(CONFIG_ARCH_VEXPRESS)            += platsmp-vexpress.o
+obj-$(CONFIG_HOTPLUG_CPU)              += hotplug.o
+endif
diff --git a/arch/arm/mach-versatile/Makefile.boot b/arch/arm/mach-versatile/Makefile.boot
new file mode 100644 (file)
index 0000000..cec195d
--- /dev/null
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
+# Empty file waiting for deletion once Makefile.boot isn't needed any more.
+# Patch waits for application at
+# http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7889/1 .
diff --git a/arch/arm/mach-versatile/dcscb.c b/arch/arm/mach-versatile/dcscb.c
new file mode 100644 (file)
index 0000000..866270e
--- /dev/null
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * dcscb.c - Dual Cluster System Configuration Block
+ *
+ * Created by: Nicolas Pitre, May 2012
+ * Copyright:  (C) 2012-2013  Linaro Limited
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/of_address.h>
+#include <linux/vexpress.h>
+#include <linux/arm-cci.h>
+
+#include <asm/mcpm.h>
+#include <asm/proc-fns.h>
+#include <asm/cacheflush.h>
+#include <asm/cputype.h>
+#include <asm/cp15.h>
+
+#include "vexpress.h"
+
+#define RST_HOLD0      0x0
+#define RST_HOLD1      0x4
+#define SYS_SWRESET    0x8
+#define RST_STAT0      0xc
+#define RST_STAT1      0x10
+#define EAG_CFG_R      0x20
+#define EAG_CFG_W      0x24
+#define KFC_CFG_R      0x28
+#define KFC_CFG_W      0x2c
+#define DCS_CFG_R      0x30
+
+static void __iomem *dcscb_base;
+static int dcscb_allcpus_mask[2];
+
+static int dcscb_cpu_powerup(unsigned int cpu, unsigned int cluster)
+{
+       unsigned int rst_hold, cpumask = (1 << cpu);
+
+       pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+       if (cluster >= 2 || !(cpumask & dcscb_allcpus_mask[cluster]))
+               return -EINVAL;
+
+       rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4);
+       rst_hold &= ~(cpumask | (cpumask << 4));
+       writel_relaxed(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4);
+       return 0;
+}
+
+static int dcscb_cluster_powerup(unsigned int cluster)
+{
+       unsigned int rst_hold;
+
+       pr_debug("%s: cluster %u\n", __func__, cluster);
+       if (cluster >= 2)
+               return -EINVAL;
+
+       /* remove cluster reset and add individual CPU's reset */
+       rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4);
+       rst_hold &= ~(1 << 8);
+       rst_hold |= dcscb_allcpus_mask[cluster];
+       writel_relaxed(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4);
+       return 0;
+}
+
+static void dcscb_cpu_powerdown_prepare(unsigned int cpu, unsigned int cluster)
+{
+       unsigned int rst_hold;
+
+       pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+       BUG_ON(cluster >= 2 || !((1 << cpu) & dcscb_allcpus_mask[cluster]));
+
+       rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4);
+       rst_hold |= (1 << cpu);
+       writel_relaxed(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4);
+}
+
+static void dcscb_cluster_powerdown_prepare(unsigned int cluster)
+{
+       unsigned int rst_hold;
+
+       pr_debug("%s: cluster %u\n", __func__, cluster);
+       BUG_ON(cluster >= 2);
+
+       rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4);
+       rst_hold |= (1 << 8);
+       writel_relaxed(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4);
+}
+
+static void dcscb_cpu_cache_disable(void)
+{
+       /* Disable and flush the local CPU cache. */
+       v7_exit_coherency_flush(louis);
+}
+
+static void dcscb_cluster_cache_disable(void)
+{
+       /* Flush all cache levels for this cluster. */
+       v7_exit_coherency_flush(all);
+
+       /*
+        * A full outer cache flush could be needed at this point
+        * on platforms with such a cache, depending on where the
+        * outer cache sits. In some cases the notion of a "last
+        * cluster standing" would need to be implemented if the
+        * outer cache is shared across clusters. In any case, when
+        * the outer cache needs flushing, there is no concurrent
+        * access to the cache controller to worry about and no
+        * special locking besides what is already provided by the
+        * MCPM state machinery is needed.
+        */
+
+       /*
+        * Disable cluster-level coherency by masking
+        * incoming snoops and DVM messages:
+        */
+       cci_disable_port_by_cpu(read_cpuid_mpidr());
+}
+
+static const struct mcpm_platform_ops dcscb_power_ops = {
+       .cpu_powerup            = dcscb_cpu_powerup,
+       .cluster_powerup        = dcscb_cluster_powerup,
+       .cpu_powerdown_prepare  = dcscb_cpu_powerdown_prepare,
+       .cluster_powerdown_prepare = dcscb_cluster_powerdown_prepare,
+       .cpu_cache_disable      = dcscb_cpu_cache_disable,
+       .cluster_cache_disable  = dcscb_cluster_cache_disable,
+};
+
+extern void dcscb_power_up_setup(unsigned int affinity_level);
+
+static int __init dcscb_init(void)
+{
+       struct device_node *node;
+       unsigned int cfg;
+       int ret;
+
+       if (!cci_probed())
+               return -ENODEV;
+
+       node = of_find_compatible_node(NULL, NULL, "arm,rtsm,dcscb");
+       if (!node)
+               return -ENODEV;
+       dcscb_base = of_iomap(node, 0);
+       if (!dcscb_base)
+               return -EADDRNOTAVAIL;
+       cfg = readl_relaxed(dcscb_base + DCS_CFG_R);
+       dcscb_allcpus_mask[0] = (1 << (((cfg >> 16) >> (0 << 2)) & 0xf)) - 1;
+       dcscb_allcpus_mask[1] = (1 << (((cfg >> 16) >> (1 << 2)) & 0xf)) - 1;
+
+       ret = mcpm_platform_register(&dcscb_power_ops);
+       if (!ret)
+               ret = mcpm_sync_init(dcscb_power_up_setup);
+       if (ret) {
+               iounmap(dcscb_base);
+               return ret;
+       }
+
+       pr_info("VExpress DCSCB support installed\n");
+
+       /*
+        * Future entries into the kernel can now go
+        * through the cluster entry vectors.
+        */
+       vexpress_flags_set(__pa_symbol(mcpm_entry_point));
+
+       return 0;
+}
+
+early_initcall(dcscb_init);
diff --git a/arch/arm/mach-versatile/dcscb_setup.S b/arch/arm/mach-versatile/dcscb_setup.S
new file mode 100644 (file)
index 0000000..92d1fd9
--- /dev/null
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Created by:  Dave Martin, 2012-06-22
+ * Copyright:   (C) 2012-2013  Linaro Limited
+ */
+
+#include <linux/linkage.h>
+
+
+ENTRY(dcscb_power_up_setup)
+
+       cmp     r0, #0                  @ check affinity level
+       beq     2f
+
+/*
+ * Enable cluster-level coherency, in preparation for turning on the MMU.
+ * The ACTLR SMP bit does not need to be set here, because cpu_resume()
+ * already restores that.
+ *
+ * A15/A7 may not require explicit L2 invalidation on reset, dependent
+ * on hardware integration decisions.
+ * For now, this code assumes that L2 is either already invalidated,
+ * or invalidation is not required.
+ */
+
+       b       cci_enable_port_for_self
+
+2:     @ Implementation-specific local CPU setup operations should go here,
+       @ if any.  In this case, there is nothing to do.
+
+       bx      lr
+
+ENDPROC(dcscb_power_up_setup)
diff --git a/arch/arm/mach-versatile/headsmp.S b/arch/arm/mach-versatile/headsmp.S
new file mode 100644 (file)
index 0000000..99c32db
--- /dev/null
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ *  Copyright (c) 2003 ARM Limited
+ *  All Rights Reserved
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/assembler.h>
+
+/*
+ * Realview/Versatile Express specific entry point for secondary CPUs.
+ * This provides a "holding pen" into which all secondary cores are held
+ * until we're ready for them to initialise.
+ */
+ENTRY(versatile_secondary_startup)
+ ARM_BE8(setend        be)
+       mrc     p15, 0, r0, c0, c0, 5
+       bic     r0, #0xff000000
+       adr     r4, 1f
+       ldmia   r4, {r5, r6}
+       sub     r4, r4, r5
+       add     r6, r6, r4
+pen:   ldr     r7, [r6]
+       cmp     r7, r0
+       bne     pen
+
+       /*
+        * we've been released from the holding pen: secondary_stack
+        * should now contain the SVC stack for this core
+        */
+       b       secondary_startup
+
+       .align
+1:     .long   .
+       .long   versatile_cpu_release
+ENDPROC(versatile_secondary_startup)
diff --git a/arch/arm/mach-versatile/hotplug.c b/arch/arm/mach-versatile/hotplug.c
new file mode 100644 (file)
index 0000000..5a15217
--- /dev/null
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  Copyright (C) 2002 ARM Ltd.
+ *  All Rights Reserved
+ *
+ * This hotplug implementation is _specific_ to the situation found on
+ * ARM development platforms where there is _no_ possibility of actually
+ * taking a CPU offline, resetting it, or otherwise.  Real platforms must
+ * NOT copy this code.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+
+#include <asm/smp_plat.h>
+#include <asm/cp15.h>
+
+#include "platsmp.h"
+
+static inline void versatile_immitation_enter_lowpower(unsigned int actrl_mask)
+{
+       unsigned int v;
+
+       asm volatile(
+               "mcr    p15, 0, %1, c7, c5, 0\n"
+       "       mcr     p15, 0, %1, c7, c10, 4\n"
+       /*
+        * Turn off coherency
+        */
+       "       mrc     p15, 0, %0, c1, c0, 1\n"
+       "       bic     %0, %0, %3\n"
+       "       mcr     p15, 0, %0, c1, c0, 1\n"
+       "       mrc     p15, 0, %0, c1, c0, 0\n"
+       "       bic     %0, %0, %2\n"
+       "       mcr     p15, 0, %0, c1, c0, 0\n"
+         : "=&r" (v)
+         : "r" (0), "Ir" (CR_C), "Ir" (actrl_mask)
+         : "cc");
+}
+
+static inline void versatile_immitation_leave_lowpower(unsigned int actrl_mask)
+{
+       unsigned int v;
+
+       asm volatile(
+               "mrc    p15, 0, %0, c1, c0, 0\n"
+       "       orr     %0, %0, %1\n"
+       "       mcr     p15, 0, %0, c1, c0, 0\n"
+       "       mrc     p15, 0, %0, c1, c0, 1\n"
+       "       orr     %0, %0, %2\n"
+       "       mcr     p15, 0, %0, c1, c0, 1\n"
+         : "=&r" (v)
+         : "Ir" (CR_C), "Ir" (actrl_mask)
+         : "cc");
+}
+
+static inline void versatile_immitation_do_lowpower(unsigned int cpu, int *spurious)
+{
+       /*
+        * there is no power-control hardware on this platform, so all
+        * we can do is put the core into WFI; this is safe as the calling
+        * code will have already disabled interrupts.
+        *
+        * This code should not be used outside Versatile platforms.
+        */
+       for (;;) {
+               wfi();
+
+               if (versatile_cpu_release == cpu_logical_map(cpu)) {
+                       /*
+                        * OK, proper wakeup, we're done
+                        */
+                       break;
+               }
+
+               /*
+                * Getting here, means that we have come out of WFI without
+                * having been woken up - this shouldn't happen
+                *
+                * Just note it happening - when we're woken, we can report
+                * its occurrence.
+                */
+               (*spurious)++;
+       }
+}
+
+/*
+ * platform-specific code to shutdown a CPU.
+ * This code supports immitation-style CPU hotplug for Versatile/Realview/
+ * Versatile Express platforms that are unable to do real CPU hotplug.
+ */
+void versatile_immitation_cpu_die(unsigned int cpu, unsigned int actrl_mask)
+{
+       int spurious = 0;
+
+       versatile_immitation_enter_lowpower(actrl_mask);
+       versatile_immitation_do_lowpower(cpu, &spurious);
+       versatile_immitation_leave_lowpower(actrl_mask);
+
+       if (spurious)
+               pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
+}
diff --git a/arch/arm/mach-versatile/integrator-cm.h b/arch/arm/mach-versatile/integrator-cm.h
new file mode 100644 (file)
index 0000000..f09ea18
--- /dev/null
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * access the core module control register.
+ */
+u32 cm_get(void);
+void cm_control(u32, u32);
+
+struct device_node;
+void cm_init(void);
+void cm_clear_irqs(void);
+
+#define CM_CTRL_LED                    (1 << 0)
+#define CM_CTRL_nMBDET                 (1 << 1)
+#define CM_CTRL_REMAP                  (1 << 2)
+
+/*
+ * Integrator/AP,PP2 specific
+ */
+#define CM_CTRL_HIGHVECTORS            (1 << 4)
+#define CM_CTRL_BIGENDIAN              (1 << 5)
+#define CM_CTRL_FASTBUS                        (1 << 6)
+#define CM_CTRL_SYNC                   (1 << 7)
+
+/*
+ * ARM926/946/966 Integrator/CP specific
+ */
+#define CM_CTRL_LCDBIASEN              (1 << 8)
+#define CM_CTRL_LCDBIASUP              (1 << 9)
+#define CM_CTRL_LCDBIASDN              (1 << 10)
+#define CM_CTRL_LCDMUXSEL_MASK         (7 << 11)
+#define CM_CTRL_LCDMUXSEL_GENLCD       (1 << 11)
+#define CM_CTRL_LCDMUXSEL_VGA565_TFT555        (2 << 11)
+#define CM_CTRL_LCDMUXSEL_SHARPLCD     (3 << 11)
+#define CM_CTRL_LCDMUXSEL_VGA555_TFT555        (4 << 11)
+#define CM_CTRL_LCDEN0                 (1 << 14)
+#define CM_CTRL_LCDEN1                 (1 << 15)
+#define CM_CTRL_STATIC1                        (1 << 16)
+#define CM_CTRL_STATIC2                        (1 << 17)
+#define CM_CTRL_STATIC                 (1 << 18)
+#define CM_CTRL_n24BITEN               (1 << 19)
+#define CM_CTRL_EBIWP                  (1 << 20)
diff --git a/arch/arm/mach-versatile/integrator-hardware.h b/arch/arm/mach-versatile/integrator-hardware.h
new file mode 100644 (file)
index 0000000..81ce09e
--- /dev/null
@@ -0,0 +1,336 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ *  This file contains the hardware definitions of the Integrator.
+ *
+ *  Copyright (C) 1998-1999 ARM Limited.
+ */
+#ifndef INTEGRATOR_HARDWARE_H
+#define INTEGRATOR_HARDWARE_H
+
+/*
+ * Where in virtual memory the IO devices (timers, system controllers
+ * and so on)
+ */
+#define IO_BASE                        0xF0000000                 // VA of IO
+#define IO_SIZE                        0x0B000000                 // How much?
+#define IO_START               INTEGRATOR_HDR_BASE        // PA of IO
+
+/* macro to get at IO space when running virtually */
+#define IO_ADDRESS(x)  (((x) & 0x000fffff) | (((x) >> 4) & 0x0ff00000) | IO_BASE)
+#define __io_address(n)                ((void __iomem *)IO_ADDRESS(n))
+
+/*
+ *  Integrator memory map
+ */
+#define INTEGRATOR_BOOT_ROM_LO          0x00000000
+#define INTEGRATOR_BOOT_ROM_HI          0x20000000
+#define INTEGRATOR_BOOT_ROM_BASE        INTEGRATOR_BOOT_ROM_HI  /*  Normal position */
+#define INTEGRATOR_BOOT_ROM_SIZE        SZ_512K
+
+/*
+ * New Core Modules have different amounts of SSRAM, the amount of SSRAM
+ * fitted can be found in HDR_STAT.
+ *
+ * The symbol INTEGRATOR_SSRAM_SIZE is kept, however this now refers to
+ * the minimum amount of SSRAM fitted on any core module.
+ *
+ * New Core Modules also alias the SSRAM.
+ *
+ */
+#define INTEGRATOR_SSRAM_BASE           0x00000000
+#define INTEGRATOR_SSRAM_ALIAS_BASE     0x10800000
+#define INTEGRATOR_SSRAM_SIZE           SZ_256K
+
+#define INTEGRATOR_FLASH_BASE           0x24000000
+#define INTEGRATOR_FLASH_SIZE           SZ_32M
+
+#define INTEGRATOR_MBRD_SSRAM_BASE      0x28000000
+#define INTEGRATOR_MBRD_SSRAM_SIZE      SZ_512K
+
+/*
+ *  SDRAM is a SIMM therefore the size is not known.
+ */
+#define INTEGRATOR_SDRAM_BASE           0x00040000
+
+#define INTEGRATOR_SDRAM_ALIAS_BASE     0x80000000
+#define INTEGRATOR_HDR0_SDRAM_BASE      0x80000000
+#define INTEGRATOR_HDR1_SDRAM_BASE      0x90000000
+#define INTEGRATOR_HDR2_SDRAM_BASE      0xA0000000
+#define INTEGRATOR_HDR3_SDRAM_BASE      0xB0000000
+
+/*
+ *  Logic expansion modules
+ *
+ */
+#define INTEGRATOR_LOGIC_MODULES_BASE   0xC0000000
+#define INTEGRATOR_LOGIC_MODULE0_BASE   0xC0000000
+#define INTEGRATOR_LOGIC_MODULE1_BASE   0xD0000000
+#define INTEGRATOR_LOGIC_MODULE2_BASE   0xE0000000
+#define INTEGRATOR_LOGIC_MODULE3_BASE   0xF0000000
+
+/*
+ * Integrator header card registers
+ */
+#define INTEGRATOR_HDR_ID_OFFSET        0x00
+#define INTEGRATOR_HDR_PROC_OFFSET      0x04
+#define INTEGRATOR_HDR_OSC_OFFSET       0x08
+#define INTEGRATOR_HDR_CTRL_OFFSET      0x0C
+#define INTEGRATOR_HDR_STAT_OFFSET      0x10
+#define INTEGRATOR_HDR_LOCK_OFFSET      0x14
+#define INTEGRATOR_HDR_SDRAM_OFFSET     0x20
+#define INTEGRATOR_HDR_INIT_OFFSET      0x24    /*  CM9x6 */
+#define INTEGRATOR_HDR_IC_OFFSET        0x40
+#define INTEGRATOR_HDR_SPDBASE_OFFSET   0x100
+#define INTEGRATOR_HDR_SPDTOP_OFFSET    0x200
+
+#define INTEGRATOR_HDR_BASE             0x10000000
+#define INTEGRATOR_HDR_ID               (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_ID_OFFSET)
+#define INTEGRATOR_HDR_PROC             (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_PROC_OFFSET)
+#define INTEGRATOR_HDR_OSC              (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_OSC_OFFSET)
+#define INTEGRATOR_HDR_CTRL             (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_CTRL_OFFSET)
+#define INTEGRATOR_HDR_STAT             (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_STAT_OFFSET)
+#define INTEGRATOR_HDR_LOCK             (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_LOCK_OFFSET)
+#define INTEGRATOR_HDR_SDRAM            (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_SDRAM_OFFSET)
+#define INTEGRATOR_HDR_INIT             (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_INIT_OFFSET)
+#define INTEGRATOR_HDR_IC               (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_IC_OFFSET)
+#define INTEGRATOR_HDR_SPDBASE          (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_SPDBASE_OFFSET)
+#define INTEGRATOR_HDR_SPDTOP           (INTEGRATOR_HDR_BASE + INTEGRATOR_HDR_SPDTOP_OFFSET)
+
+#define INTEGRATOR_HDR_CTRL_LED         0x01
+#define INTEGRATOR_HDR_CTRL_MBRD_DETECH 0x02
+#define INTEGRATOR_HDR_CTRL_REMAP       0x04
+#define INTEGRATOR_HDR_CTRL_RESET       0x08
+#define INTEGRATOR_HDR_CTRL_HIGHVECTORS 0x10
+#define INTEGRATOR_HDR_CTRL_BIG_ENDIAN  0x20
+#define INTEGRATOR_HDR_CTRL_FASTBUS     0x40
+#define INTEGRATOR_HDR_CTRL_SYNC        0x80
+
+#define INTEGRATOR_HDR_OSC_CORE_10MHz   0x102
+#define INTEGRATOR_HDR_OSC_CORE_15MHz   0x107
+#define INTEGRATOR_HDR_OSC_CORE_20MHz   0x10C
+#define INTEGRATOR_HDR_OSC_CORE_25MHz   0x111
+#define INTEGRATOR_HDR_OSC_CORE_30MHz   0x116
+#define INTEGRATOR_HDR_OSC_CORE_35MHz   0x11B
+#define INTEGRATOR_HDR_OSC_CORE_40MHz   0x120
+#define INTEGRATOR_HDR_OSC_CORE_45MHz   0x125
+#define INTEGRATOR_HDR_OSC_CORE_50MHz   0x12A
+#define INTEGRATOR_HDR_OSC_CORE_55MHz   0x12F
+#define INTEGRATOR_HDR_OSC_CORE_60MHz   0x134
+#define INTEGRATOR_HDR_OSC_CORE_65MHz   0x139
+#define INTEGRATOR_HDR_OSC_CORE_70MHz   0x13E
+#define INTEGRATOR_HDR_OSC_CORE_75MHz   0x143
+#define INTEGRATOR_HDR_OSC_CORE_80MHz   0x148
+#define INTEGRATOR_HDR_OSC_CORE_85MHz   0x14D
+#define INTEGRATOR_HDR_OSC_CORE_90MHz   0x152
+#define INTEGRATOR_HDR_OSC_CORE_95MHz   0x157
+#define INTEGRATOR_HDR_OSC_CORE_100MHz  0x15C
+#define INTEGRATOR_HDR_OSC_CORE_105MHz  0x161
+#define INTEGRATOR_HDR_OSC_CORE_110MHz  0x166
+#define INTEGRATOR_HDR_OSC_CORE_115MHz  0x16B
+#define INTEGRATOR_HDR_OSC_CORE_120MHz  0x170
+#define INTEGRATOR_HDR_OSC_CORE_125MHz  0x175
+#define INTEGRATOR_HDR_OSC_CORE_130MHz  0x17A
+#define INTEGRATOR_HDR_OSC_CORE_135MHz  0x17F
+#define INTEGRATOR_HDR_OSC_CORE_140MHz  0x184
+#define INTEGRATOR_HDR_OSC_CORE_145MHz  0x189
+#define INTEGRATOR_HDR_OSC_CORE_150MHz  0x18E
+#define INTEGRATOR_HDR_OSC_CORE_155MHz  0x193
+#define INTEGRATOR_HDR_OSC_CORE_160MHz  0x198
+#define INTEGRATOR_HDR_OSC_CORE_MASK    0x7FF
+
+#define INTEGRATOR_HDR_OSC_MEM_10MHz    0x10C000
+#define INTEGRATOR_HDR_OSC_MEM_15MHz    0x116000
+#define INTEGRATOR_HDR_OSC_MEM_20MHz    0x120000
+#define INTEGRATOR_HDR_OSC_MEM_25MHz    0x12A000
+#define INTEGRATOR_HDR_OSC_MEM_30MHz    0x134000
+#define INTEGRATOR_HDR_OSC_MEM_33MHz    0x13A000
+#define INTEGRATOR_HDR_OSC_MEM_40MHz    0x148000
+#define INTEGRATOR_HDR_OSC_MEM_50MHz    0x15C000
+#define INTEGRATOR_HDR_OSC_MEM_60MHz    0x170000
+#define INTEGRATOR_HDR_OSC_MEM_66MHz    0x17C000
+#define INTEGRATOR_HDR_OSC_MEM_MASK     0x7FF000
+
+#define INTEGRATOR_HDR_OSC_BUS_MODE_CM7x0  0x0
+#define INTEGRATOR_HDR_OSC_BUS_MODE_CM9x0  0x0800000
+#define INTEGRATOR_HDR_OSC_BUS_MODE_CM9x6  0x1000000
+#define INTEGRATOR_HDR_OSC_BUS_MODE_CM10x00  0x1800000
+#define INTEGRATOR_HDR_OSC_BUS_MODE_MASK  0x1800000
+
+#define INTEGRATOR_HDR_SDRAM_SPD_OK     (1 << 5)
+
+/*
+ * Integrator system registers
+ */
+
+/*
+ *  System Controller
+ */
+#define INTEGRATOR_SC_ID_OFFSET         0x00
+#define INTEGRATOR_SC_OSC_OFFSET        0x04
+#define INTEGRATOR_SC_CTRLS_OFFSET      0x08
+#define INTEGRATOR_SC_CTRLC_OFFSET      0x0C
+#define INTEGRATOR_SC_DEC_OFFSET        0x10
+#define INTEGRATOR_SC_ARB_OFFSET        0x14
+#define INTEGRATOR_SC_LOCK_OFFSET       0x1C
+
+#define INTEGRATOR_SC_BASE              0x11000000
+#define INTEGRATOR_SC_ID                (INTEGRATOR_SC_BASE + INTEGRATOR_SC_ID_OFFSET)
+#define INTEGRATOR_SC_OSC               (INTEGRATOR_SC_BASE + INTEGRATOR_SC_OSC_OFFSET)
+#define INTEGRATOR_SC_CTRLS             (INTEGRATOR_SC_BASE + INTEGRATOR_SC_CTRLS_OFFSET)
+#define INTEGRATOR_SC_CTRLC             (INTEGRATOR_SC_BASE + INTEGRATOR_SC_CTRLC_OFFSET)
+#define INTEGRATOR_SC_DEC               (INTEGRATOR_SC_BASE + INTEGRATOR_SC_DEC_OFFSET)
+#define INTEGRATOR_SC_ARB               (INTEGRATOR_SC_BASE + INTEGRATOR_SC_ARB_OFFSET)
+#define INTEGRATOR_SC_PCIENABLE         (INTEGRATOR_SC_BASE + INTEGRATOR_SC_PCIENABLE_OFFSET)
+#define INTEGRATOR_SC_LOCK              (INTEGRATOR_SC_BASE + INTEGRATOR_SC_LOCK_OFFSET)
+
+#define INTEGRATOR_SC_OSC_SYS_10MHz     0x20
+#define INTEGRATOR_SC_OSC_SYS_15MHz     0x34
+#define INTEGRATOR_SC_OSC_SYS_20MHz     0x48
+#define INTEGRATOR_SC_OSC_SYS_25MHz     0x5C
+#define INTEGRATOR_SC_OSC_SYS_33MHz     0x7C
+#define INTEGRATOR_SC_OSC_SYS_MASK      0xFF
+
+#define INTEGRATOR_SC_OSC_PCI_25MHz     0x100
+#define INTEGRATOR_SC_OSC_PCI_33MHz     0x0
+#define INTEGRATOR_SC_OSC_PCI_MASK      0x100
+
+#define INTEGRATOR_SC_CTRL_SOFTRST      (1 << 0)
+#define INTEGRATOR_SC_CTRL_nFLVPPEN     (1 << 1)
+#define INTEGRATOR_SC_CTRL_nFLWP        (1 << 2)
+#define INTEGRATOR_SC_CTRL_URTS0        (1 << 4)
+#define INTEGRATOR_SC_CTRL_UDTR0        (1 << 5)
+#define INTEGRATOR_SC_CTRL_URTS1        (1 << 6)
+#define INTEGRATOR_SC_CTRL_UDTR1        (1 << 7)
+
+/*
+ *  External Bus Interface
+ */
+#define INTEGRATOR_EBI_BASE             0x12000000
+
+#define INTEGRATOR_EBI_CSR0_OFFSET      0x00
+#define INTEGRATOR_EBI_CSR1_OFFSET      0x04
+#define INTEGRATOR_EBI_CSR2_OFFSET      0x08
+#define INTEGRATOR_EBI_CSR3_OFFSET      0x0C
+#define INTEGRATOR_EBI_LOCK_OFFSET      0x20
+
+#define INTEGRATOR_EBI_CSR0             (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR0_OFFSET)
+#define INTEGRATOR_EBI_CSR1             (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET)
+#define INTEGRATOR_EBI_CSR2             (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR2_OFFSET)
+#define INTEGRATOR_EBI_CSR3             (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_CSR3_OFFSET)
+#define INTEGRATOR_EBI_LOCK             (INTEGRATOR_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET)
+
+#define INTEGRATOR_EBI_8_BIT            0x00
+#define INTEGRATOR_EBI_16_BIT           0x01
+#define INTEGRATOR_EBI_32_BIT           0x02
+#define INTEGRATOR_EBI_WRITE_ENABLE     0x04
+#define INTEGRATOR_EBI_SYNC             0x08
+#define INTEGRATOR_EBI_WS_2             0x00
+#define INTEGRATOR_EBI_WS_3             0x10
+#define INTEGRATOR_EBI_WS_4             0x20
+#define INTEGRATOR_EBI_WS_5             0x30
+#define INTEGRATOR_EBI_WS_6             0x40
+#define INTEGRATOR_EBI_WS_7             0x50
+#define INTEGRATOR_EBI_WS_8             0x60
+#define INTEGRATOR_EBI_WS_9             0x70
+#define INTEGRATOR_EBI_WS_10            0x80
+#define INTEGRATOR_EBI_WS_11            0x90
+#define INTEGRATOR_EBI_WS_12            0xA0
+#define INTEGRATOR_EBI_WS_13            0xB0
+#define INTEGRATOR_EBI_WS_14            0xC0
+#define INTEGRATOR_EBI_WS_15            0xD0
+#define INTEGRATOR_EBI_WS_16            0xE0
+#define INTEGRATOR_EBI_WS_17            0xF0
+
+
+#define INTEGRATOR_CT_BASE              0x13000000      /*  Counter/Timers */
+#define INTEGRATOR_IC_BASE              0x14000000      /*  Interrupt Controller */
+#define INTEGRATOR_RTC_BASE             0x15000000      /*  Real Time Clock */
+#define INTEGRATOR_UART0_BASE           0x16000000      /*  UART 0 */
+#define INTEGRATOR_UART1_BASE           0x17000000      /*  UART 1 */
+#define INTEGRATOR_KBD_BASE             0x18000000      /*  Keyboard */
+#define INTEGRATOR_MOUSE_BASE           0x19000000      /*  Mouse */
+
+/*
+ *  LED's & Switches
+ */
+#define INTEGRATOR_DBG_ALPHA_OFFSET     0x00
+#define INTEGRATOR_DBG_LEDS_OFFSET      0x04
+#define INTEGRATOR_DBG_SWITCH_OFFSET    0x08
+
+#define INTEGRATOR_DBG_BASE             0x1A000000
+#define INTEGRATOR_DBG_ALPHA            (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_ALPHA_OFFSET)
+#define INTEGRATOR_DBG_LEDS             (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_LEDS_OFFSET)
+#define INTEGRATOR_DBG_SWITCH           (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_SWITCH_OFFSET)
+
+#define INTEGRATOR_AP_GPIO_BASE                0x1B000000      /* GPIO */
+
+#define INTEGRATOR_CP_MMC_BASE         0x1C000000      /* MMC */
+#define INTEGRATOR_CP_AACI_BASE                0x1D000000      /* AACI */
+#define INTEGRATOR_CP_ETH_BASE         0xC8000000      /* Ethernet */
+#define INTEGRATOR_CP_GPIO_BASE                0xC9000000      /* GPIO */
+#define INTEGRATOR_CP_SIC_BASE         0xCA000000      /* SIC */
+#define INTEGRATOR_CP_CTL_BASE         0xCB000000      /* CP system control */
+
+/* PS2 Keyboard interface */
+#define KMI0_BASE                       INTEGRATOR_KBD_BASE
+
+/* PS2 Mouse interface */
+#define KMI1_BASE                       INTEGRATOR_MOUSE_BASE
+
+/*
+ * Integrator Interrupt Controllers
+ *
+ *
+ * Offsets from interrupt controller base
+ *
+ * System Controller interrupt controller base is
+ *
+ *     INTEGRATOR_IC_BASE + (header_number << 6)
+ *
+ * Core Module interrupt controller base is
+ *
+ *     INTEGRATOR_HDR_IC
+ */
+#define IRQ_STATUS                      0
+#define IRQ_RAW_STATUS                  0x04
+#define IRQ_ENABLE                      0x08
+#define IRQ_ENABLE_SET                  0x08
+#define IRQ_ENABLE_CLEAR                0x0C
+
+#define INT_SOFT_SET                    0x10
+#define INT_SOFT_CLEAR                  0x14
+
+#define FIQ_STATUS                      0x20
+#define FIQ_RAW_STATUS                  0x24
+#define FIQ_ENABLE                      0x28
+#define FIQ_ENABLE_SET                  0x28
+#define FIQ_ENABLE_CLEAR                0x2C
+
+
+/*
+ * LED's
+ */
+#define GREEN_LED                       0x01
+#define YELLOW_LED                      0x02
+#define RED_LED                         0x04
+#define GREEN_LED_2                     0x08
+#define ALL_LEDS                        0x0F
+
+#define LED_BANK                        INTEGRATOR_DBG_LEDS
+
+/*
+ *  Timer definitions
+ *
+ *  Only use timer 1 & 2
+ *  (both run at 24MHz and will need the clock divider set to 16).
+ *
+ *  Timer 0 runs at bus frequency
+ */
+#define INTEGRATOR_TIMER0_BASE          INTEGRATOR_CT_BASE
+#define INTEGRATOR_TIMER1_BASE          (INTEGRATOR_CT_BASE + 0x100)
+#define INTEGRATOR_TIMER2_BASE          (INTEGRATOR_CT_BASE + 0x200)
+
+#define INTEGRATOR_CSR_BASE             0x10000000
+#define INTEGRATOR_CSR_SIZE             0x10000000
+
+#endif /* INTEGRATOR_HARDWARE_H */
diff --git a/arch/arm/mach-versatile/integrator.c b/arch/arm/mach-versatile/integrator.c
new file mode 100644 (file)
index 0000000..fdf9c4d
--- /dev/null
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  Copyright (C) 2000-2003 Deep Blue Solutions Ltd
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/memblock.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/serial.h>
+#include <linux/io.h>
+#include <linux/stat.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/pgtable.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/time.h>
+
+#include "integrator-hardware.h"
+#include "integrator-cm.h"
+#include "integrator.h"
+
+static DEFINE_RAW_SPINLOCK(cm_lock);
+static void __iomem *cm_base;
+
+/**
+ * cm_get - get the value from the CM_CTRL register
+ */
+u32 cm_get(void)
+{
+       return readl(cm_base + INTEGRATOR_HDR_CTRL_OFFSET);
+}
+
+/**
+ * cm_control - update the CM_CTRL register.
+ * @mask: bits to change
+ * @set: bits to set
+ */
+void cm_control(u32 mask, u32 set)
+{
+       unsigned long flags;
+       u32 val;
+
+       raw_spin_lock_irqsave(&cm_lock, flags);
+       val = readl(cm_base + INTEGRATOR_HDR_CTRL_OFFSET) & ~mask;
+       writel(val | set, cm_base + INTEGRATOR_HDR_CTRL_OFFSET);
+       raw_spin_unlock_irqrestore(&cm_lock, flags);
+}
+
+void cm_clear_irqs(void)
+{
+       /* disable core module IRQs */
+       writel(0xffffffffU, cm_base + INTEGRATOR_HDR_IC_OFFSET +
+               IRQ_ENABLE_CLEAR);
+}
+
+static const struct of_device_id cm_match[] = {
+       { .compatible = "arm,core-module-integrator"},
+       { },
+};
+
+void cm_init(void)
+{
+       struct device_node *cm = of_find_matching_node(NULL, cm_match);
+
+       if (!cm) {
+               pr_crit("no core module node found in device tree\n");
+               return;
+       }
+       cm_base = of_iomap(cm, 0);
+       if (!cm_base) {
+               pr_crit("could not remap core module\n");
+               return;
+       }
+       cm_clear_irqs();
+}
+
+/*
+ * We need to stop things allocating the low memory; ideally we need a
+ * better implementation of GFP_DMA which does not assume that DMA-able
+ * memory starts at zero.
+ */
+void __init integrator_reserve(void)
+{
+       memblock_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
+}
diff --git a/arch/arm/mach-versatile/integrator.h b/arch/arm/mach-versatile/integrator.h
new file mode 100644 (file)
index 0000000..f053aee
--- /dev/null
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <linux/reboot.h>
+#include <linux/amba/serial.h>
+extern struct amba_pl010_data ap_uart_data;
+void integrator_init_early(void);
+int integrator_init(bool is_cp);
+void integrator_reserve(void);
diff --git a/arch/arm/mach-versatile/integrator_ap.c b/arch/arm/mach-versatile/integrator_ap.c
new file mode 100644 (file)
index 0000000..44a69cc
--- /dev/null
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *  Copyright (C) 2000-2003 Deep Blue Solutions Ltd
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/syscore_ops.h>
+#include <linux/amba/bus.h>
+#include <linux/io.h>
+#include <linux/irqchip.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/termios.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "integrator-hardware.h"
+#include "integrator-cm.h"
+#include "integrator.h"
+
+/* Regmap to the AP system controller */
+static struct regmap *ap_syscon_map;
+
+/*
+ * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
+ * is the (PA >> 12).
+ *
+ * Setup a VA for the Integrator interrupt controller (for header #0,
+ * just for now).
+ */
+#define VA_IC_BASE     __io_address(INTEGRATOR_IC_BASE)
+
+/*
+ * Logical      Physical
+ * f1400000    14000000        Interrupt controller
+ * f1600000    16000000        UART 0
+ */
+
+static struct map_desc ap_io_desc[] __initdata __maybe_unused = {
+       {
+               .virtual        = IO_ADDRESS(INTEGRATOR_IC_BASE),
+               .pfn            = __phys_to_pfn(INTEGRATOR_IC_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE
+       }, {
+               .virtual        = IO_ADDRESS(INTEGRATOR_UART0_BASE),
+               .pfn            = __phys_to_pfn(INTEGRATOR_UART0_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE
+       }
+};
+
+static void __init ap_map_io(void)
+{
+       iotable_init(ap_io_desc, ARRAY_SIZE(ap_io_desc));
+}
+
+#ifdef CONFIG_PM
+static unsigned long ic_irq_enable;
+
+static int irq_suspend(void)
+{
+       ic_irq_enable = readl(VA_IC_BASE + IRQ_ENABLE);
+       return 0;
+}
+
+static void irq_resume(void)
+{
+       /* disable all irq sources */
+       cm_clear_irqs();
+       writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR);
+       writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
+
+       writel(ic_irq_enable, VA_IC_BASE + IRQ_ENABLE_SET);
+}
+#else
+#define irq_suspend NULL
+#define irq_resume NULL
+#endif
+
+static struct syscore_ops irq_syscore_ops = {
+       .suspend        = irq_suspend,
+       .resume         = irq_resume,
+};
+
+static int __init irq_syscore_init(void)
+{
+       register_syscore_ops(&irq_syscore_ops);
+
+       return 0;
+}
+
+device_initcall(irq_syscore_init);
+
+/*
+ * For the PL010 found in the Integrator/AP some of the UART control is
+ * implemented in the system controller and accessed using a callback
+ * from the driver.
+ */
+static void integrator_uart_set_mctrl(struct amba_device *dev,
+                               void __iomem *base, unsigned int mctrl)
+{
+       unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask;
+       u32 phybase = dev->res.start;
+       int ret;
+
+       if (phybase == INTEGRATOR_UART0_BASE) {
+               /* UART0 */
+               rts_mask = 1 << 4;
+               dtr_mask = 1 << 5;
+       } else {
+               /* UART1 */
+               rts_mask = 1 << 6;
+               dtr_mask = 1 << 7;
+       }
+
+       if (mctrl & TIOCM_RTS)
+               ctrlc |= rts_mask;
+       else
+               ctrls |= rts_mask;
+
+       if (mctrl & TIOCM_DTR)
+               ctrlc |= dtr_mask;
+       else
+               ctrls |= dtr_mask;
+
+       ret = regmap_write(ap_syscon_map,
+                          INTEGRATOR_SC_CTRLS_OFFSET,
+                          ctrls);
+       if (ret)
+               pr_err("MODEM: unable to write PL010 UART CTRLS\n");
+
+       ret = regmap_write(ap_syscon_map,
+                          INTEGRATOR_SC_CTRLC_OFFSET,
+                          ctrlc);
+       if (ret)
+               pr_err("MODEM: unable to write PL010 UART CRTLC\n");
+}
+
+struct amba_pl010_data ap_uart_data = {
+       .set_mctrl = integrator_uart_set_mctrl,
+};
+
+void __init ap_init_early(void)
+{
+}
+
+static void __init ap_init_irq_of(void)
+{
+       cm_init();
+       irqchip_init();
+}
+
+/* For the Device Tree, add in the UART callbacks as AUXDATA */
+static struct of_dev_auxdata ap_auxdata_lookup[] __initdata = {
+       OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE,
+               "uart0", &ap_uart_data),
+       OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE,
+               "uart1", &ap_uart_data),
+       { /* sentinel */ },
+};
+
+static const struct of_device_id ap_syscon_match[] = {
+       { .compatible = "arm,integrator-ap-syscon"},
+       { },
+};
+
+static void __init ap_init_of(void)
+{
+       struct device_node *syscon;
+
+       of_platform_default_populate(NULL, ap_auxdata_lookup, NULL);
+
+       syscon = of_find_matching_node(NULL, ap_syscon_match);
+       if (!syscon)
+               return;
+       ap_syscon_map = syscon_node_to_regmap(syscon);
+       if (IS_ERR(ap_syscon_map)) {
+               pr_crit("could not find Integrator/AP system controller\n");
+               return;
+       }
+}
+
+static const char * ap_dt_board_compat[] = {
+       "arm,integrator-ap",
+       NULL,
+};
+
+DT_MACHINE_START(INTEGRATOR_AP_DT, "ARM Integrator/AP (Device Tree)")
+       .reserve        = integrator_reserve,
+       .map_io         = ap_map_io,
+       .init_early     = ap_init_early,
+       .init_irq       = ap_init_irq_of,
+       .init_machine   = ap_init_of,
+       .dt_compat      = ap_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-versatile/integrator_cp.c b/arch/arm/mach-versatile/integrator_cp.c
new file mode 100644 (file)
index 0000000..2ed4ded
--- /dev/null
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  Copyright (C) 2003 Deep Blue Solutions Ltd
+ */
+#include <linux/kernel.h>
+#include <linux/amba/mmci.h>
+#include <linux/io.h>
+#include <linux/irqchip.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/sched_clock.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include "integrator-hardware.h"
+#include "integrator-cm.h"
+#include "integrator.h"
+
+/* Base address to the core module header */
+static struct regmap *cm_map;
+/* Base address to the CP controller */
+static void __iomem *intcp_con_base;
+
+#define CM_COUNTER_OFFSET 0x28
+
+/*
+ * Logical      Physical
+ * f1400000    14000000        Interrupt controller
+ * f1600000    16000000        UART 0
+ * fca00000    ca000000        SIC
+ */
+
+static struct map_desc intcp_io_desc[] __initdata __maybe_unused = {
+       {
+               .virtual        = IO_ADDRESS(INTEGRATOR_IC_BASE),
+               .pfn            = __phys_to_pfn(INTEGRATOR_IC_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE
+       }, {
+               .virtual        = IO_ADDRESS(INTEGRATOR_UART0_BASE),
+               .pfn            = __phys_to_pfn(INTEGRATOR_UART0_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE
+       }, {
+               .virtual        = IO_ADDRESS(INTEGRATOR_CP_SIC_BASE),
+               .pfn            = __phys_to_pfn(INTEGRATOR_CP_SIC_BASE),
+               .length         = SZ_4K,
+               .type           = MT_DEVICE
+       }
+};
+
+static void __init intcp_map_io(void)
+{
+       iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc));
+}
+
+/*
+ * It seems that the card insertion interrupt remains active after
+ * we've acknowledged it.  We therefore ignore the interrupt, and
+ * rely on reading it from the SIC.  This also means that we must
+ * clear the latched interrupt.
+ */
+static unsigned int mmc_status(struct device *dev)
+{
+       unsigned int status = readl(__io_address(0xca000000 + 4));
+       writel(8, intcp_con_base + 8);
+
+       return status & 8;
+}
+
+static struct mmci_platform_data mmc_data = {
+       .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
+       .status         = mmc_status,
+};
+
+static u64 notrace intcp_read_sched_clock(void)
+{
+       unsigned int val;
+
+       /* MMIO so discard return code */
+       regmap_read(cm_map, CM_COUNTER_OFFSET, &val);
+       return val;
+}
+
+static void __init intcp_init_early(void)
+{
+       cm_map = syscon_regmap_lookup_by_compatible("arm,core-module-integrator");
+       if (IS_ERR(cm_map))
+               return;
+       sched_clock_register(intcp_read_sched_clock, 32, 24000000);
+}
+
+static void __init intcp_init_irq_of(void)
+{
+       cm_init();
+       irqchip_init();
+}
+
+/*
+ * For the Device Tree, add in the UART, MMC and CLCD specifics as AUXDATA
+ * and enforce the bus names since these are used for clock lookups.
+ */
+static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = {
+       OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_CP_MMC_BASE,
+               "mmci", &mmc_data),
+       { /* sentinel */ },
+};
+
+static const struct of_device_id intcp_syscon_match[] = {
+       { .compatible = "arm,integrator-cp-syscon"},
+       { },
+};
+
+static void __init intcp_init_of(void)
+{
+       struct device_node *cpcon;
+
+       cpcon = of_find_matching_node(NULL, intcp_syscon_match);
+       if (!cpcon)
+               return;
+
+       intcp_con_base = of_iomap(cpcon, 0);
+       if (!intcp_con_base)
+               return;
+
+       of_platform_default_populate(NULL, intcp_auxdata_lookup, NULL);
+}
+
+static const char * intcp_dt_board_compat[] = {
+       "arm,integrator-cp",
+       NULL,
+};
+
+DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)")
+       .reserve        = integrator_reserve,
+       .map_io         = intcp_map_io,
+       .init_early     = intcp_init_early,
+       .init_irq       = intcp_init_irq_of,
+       .init_machine   = intcp_init_of,
+       .dt_compat      = intcp_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-versatile/platsmp-realview.c b/arch/arm/mach-versatile/platsmp-realview.c
new file mode 100644 (file)
index 0000000..5d36338
--- /dev/null
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2015 Linus Walleij
+ */
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+#include <asm/smp_scu.h>
+
+#include "platsmp.h"
+
+#define REALVIEW_SYS_FLAGSSET_OFFSET   0x30
+
+static const struct of_device_id realview_scu_match[] = {
+       { .compatible = "arm,arm11mp-scu", },
+       { .compatible = "arm,cortex-a9-scu", },
+       { .compatible = "arm,cortex-a5-scu", },
+       { }
+};
+
+static const struct of_device_id realview_syscon_match[] = {
+        { .compatible = "arm,core-module-integrator", },
+        { .compatible = "arm,realview-eb-syscon", },
+        { .compatible = "arm,realview-pb11mp-syscon", },
+        { .compatible = "arm,realview-pbx-syscon", },
+        { },
+};
+
+static void __init realview_smp_prepare_cpus(unsigned int max_cpus)
+{
+       struct device_node *np;
+       void __iomem *scu_base;
+       struct regmap *map;
+       unsigned int ncores;
+       int i;
+
+       np = of_find_matching_node(NULL, realview_scu_match);
+       if (!np) {
+               pr_err("PLATSMP: No SCU base address\n");
+               return;
+       }
+       scu_base = of_iomap(np, 0);
+       of_node_put(np);
+       if (!scu_base) {
+               pr_err("PLATSMP: No SCU remap\n");
+               return;
+       }
+
+       scu_enable(scu_base);
+       ncores = scu_get_core_count(scu_base);
+       pr_info("SCU: %d cores detected\n", ncores);
+       for (i = 0; i < ncores; i++)
+               set_cpu_possible(i, true);
+       iounmap(scu_base);
+
+       /* The syscon contains the magic SMP start address registers */
+       np = of_find_matching_node(NULL, realview_syscon_match);
+       if (!np) {
+               pr_err("PLATSMP: No syscon match\n");
+               return;
+       }
+       map = syscon_node_to_regmap(np);
+       if (IS_ERR(map)) {
+               pr_err("PLATSMP: No syscon regmap\n");
+               return;
+       }
+       /* Put the boot address in this magic register */
+       regmap_write(map, REALVIEW_SYS_FLAGSSET_OFFSET,
+                    __pa_symbol(versatile_secondary_startup));
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void realview_cpu_die(unsigned int cpu)
+{
+       return versatile_immitation_cpu_die(cpu, 0x20);
+}
+#endif
+
+static const struct smp_operations realview_dt_smp_ops __initconst = {
+       .smp_prepare_cpus       = realview_smp_prepare_cpus,
+       .smp_secondary_init     = versatile_secondary_init,
+       .smp_boot_secondary     = versatile_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+       .cpu_die                = realview_cpu_die,
+#endif
+};
+CPU_METHOD_OF_DECLARE(realview_smp, "arm,realview-smp", &realview_dt_smp_ops);
diff --git a/arch/arm/mach-versatile/platsmp-vexpress.c b/arch/arm/mach-versatile/platsmp-vexpress.c
new file mode 100644 (file)
index 0000000..1ee3c45
--- /dev/null
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  Copyright (C) 2002 ARM Ltd.
+ *  All Rights Reserved
+ */
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/vexpress.h>
+
+#include <asm/mcpm.h>
+#include <asm/smp_scu.h>
+#include <asm/mach/map.h>
+
+#include "platsmp.h"
+#include "vexpress.h"
+
+bool __init vexpress_smp_init_ops(void)
+{
+#ifdef CONFIG_MCPM
+       int cpu;
+       struct device_node *cpu_node, *cci_node;
+
+       /*
+        * The best way to detect a multi-cluster configuration
+        * is to detect if the kernel can take over CCI ports
+        * control. Loop over possible CPUs and check if CCI
+        * port control is available.
+        * Override the default vexpress_smp_ops if so.
+        */
+       for_each_possible_cpu(cpu) {
+               bool available;
+
+               cpu_node = of_get_cpu_node(cpu, NULL);
+               if (WARN(!cpu_node, "Missing cpu device node!"))
+                       return false;
+
+               cci_node = of_parse_phandle(cpu_node, "cci-control-port", 0);
+               available = cci_node && of_device_is_available(cci_node);
+               of_node_put(cci_node);
+               of_node_put(cpu_node);
+
+               if (!available)
+                       return false;
+       }
+
+       mcpm_smp_set_ops();
+       return true;
+#else
+       return false;
+#endif
+}
+
+static const struct of_device_id vexpress_smp_dt_scu_match[] __initconst = {
+       { .compatible = "arm,cortex-a5-scu", },
+       { .compatible = "arm,cortex-a9-scu", },
+       {}
+};
+
+static void __init vexpress_smp_dt_prepare_cpus(unsigned int max_cpus)
+{
+       struct device_node *scu = of_find_matching_node(NULL,
+                       vexpress_smp_dt_scu_match);
+
+       if (scu)
+               scu_enable(of_iomap(scu, 0));
+
+       /*
+        * Write the address of secondary startup into the
+        * system-wide flags register. The boot monitor waits
+        * until it receives a soft interrupt, and then the
+        * secondary CPU branches to this address.
+        */
+       vexpress_flags_set(__pa_symbol(versatile_secondary_startup));
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+static void vexpress_cpu_die(unsigned int cpu)
+{
+       versatile_immitation_cpu_die(cpu, 0x40);
+}
+#endif
+
+const struct smp_operations vexpress_smp_dt_ops __initconst = {
+       .smp_prepare_cpus       = vexpress_smp_dt_prepare_cpus,
+       .smp_secondary_init     = versatile_secondary_init,
+       .smp_boot_secondary     = versatile_boot_secondary,
+#ifdef CONFIG_HOTPLUG_CPU
+       .cpu_die                = vexpress_cpu_die,
+#endif
+};
diff --git a/arch/arm/mach-versatile/platsmp.c b/arch/arm/mach-versatile/platsmp.c
new file mode 100644 (file)
index 0000000..fa73783
--- /dev/null
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  Copyright (C) 2002 ARM Ltd.
+ *  All Rights Reserved
+ *
+ * This code is specific to the hardware found on ARM Realview and
+ * Versatile Express platforms where the CPUs are unable to be individually
+ * woken, and where there is no way to hot-unplug CPUs.  Real platforms
+ * should not copy this code.
+ */
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/smp.h>
+
+#include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
+
+#include "platsmp.h"
+
+/*
+ * versatile_cpu_release controls the release of CPUs from the holding
+ * pen in headsmp.S, which exists because we are not always able to
+ * control the release of individual CPUs from the board firmware.
+ * Production platforms do not need this.
+ */
+volatile int versatile_cpu_release = -1;
+
+/*
+ * Write versatile_cpu_release in a way that is guaranteed to be visible to
+ * all observers, irrespective of whether they're taking part in coherency
+ * or not.  This is necessary for the hotplug code to work reliably.
+ */
+static void versatile_write_cpu_release(int val)
+{
+       versatile_cpu_release = val;
+       smp_wmb();
+       sync_cache_w(&versatile_cpu_release);
+}
+
+/*
+ * versatile_lock exists to avoid running the loops_per_jiffy delay loop
+ * calibrations on the secondary CPU while the requesting CPU is using
+ * the limited-bandwidth bus - which affects the calibration value.
+ * Production platforms do not need this.
+ */
+static DEFINE_RAW_SPINLOCK(versatile_lock);
+
+void versatile_secondary_init(unsigned int cpu)
+{
+       /*
+        * let the primary processor know we're out of the
+        * pen, then head off into the C entry point
+        */
+       versatile_write_cpu_release(-1);
+
+       /*
+        * Synchronise with the boot thread.
+        */
+       raw_spin_lock(&versatile_lock);
+       raw_spin_unlock(&versatile_lock);
+}
+
+int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+       unsigned long timeout;
+
+       /*
+        * Set synchronisation state between this boot processor
+        * and the secondary one
+        */
+       raw_spin_lock(&versatile_lock);
+
+       /*
+        * This is really belt and braces; we hold unintended secondary
+        * CPUs in the holding pen until we're ready for them.  However,
+        * since we haven't sent them a soft interrupt, they shouldn't
+        * be there.
+        */
+       versatile_write_cpu_release(cpu_logical_map(cpu));
+
+       /*
+        * Send the secondary CPU a soft interrupt, thereby causing
+        * the boot monitor to read the system wide flags register,
+        * and branch to the address found there.
+        */
+       arch_send_wakeup_ipi_mask(cpumask_of(cpu));
+
+       timeout = jiffies + (1 * HZ);
+       while (time_before(jiffies, timeout)) {
+               smp_rmb();
+               if (versatile_cpu_release == -1)
+                       break;
+
+               udelay(10);
+       }
+
+       /*
+        * now the secondary core is starting up let it run its
+        * calibrations, then wait for it to finish
+        */
+       raw_spin_unlock(&versatile_lock);
+
+       return versatile_cpu_release != -1 ? -ENOSYS : 0;
+}
diff --git a/arch/arm/mach-versatile/platsmp.h b/arch/arm/mach-versatile/platsmp.h
new file mode 100644 (file)
index 0000000..171a0ab
--- /dev/null
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ *  Copyright (C) 2011 ARM Ltd.
+ *  All Rights Reserved
+ */
+extern volatile int versatile_cpu_release;
+
+extern void versatile_secondary_startup(void);
+extern void versatile_secondary_init(unsigned int cpu);
+extern int  versatile_boot_secondary(unsigned int cpu, struct task_struct *idle);
+void versatile_immitation_cpu_die(unsigned int cpu, unsigned int actrl_mask);
diff --git a/arch/arm/mach-versatile/realview.c b/arch/arm/mach-versatile/realview.c
new file mode 100644 (file)
index 0000000..feab660
--- /dev/null
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2014 Linaro Ltd.
+ *
+ * Author: Linus Walleij <linus.walleij@linaro.org>
+ */
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include <asm/hardware/cache-l2x0.h>
+
+static const char *const realview_dt_platform_compat[] __initconst = {
+       "arm,realview-eb",
+       "arm,realview-pb1176",
+       "arm,realview-pb11mp",
+       "arm,realview-pba8",
+       "arm,realview-pbx",
+       NULL,
+};
+
+DT_MACHINE_START(REALVIEW_DT, "ARM RealView Machine (Device Tree Support)")
+#ifdef CONFIG_ZONE_DMA
+       .dma_zone_size  = SZ_256M,
+#endif
+       .dt_compat      = realview_dt_platform_compat,
+       .l2c_aux_val = 0x0,
+       .l2c_aux_mask = ~0x0,
+MACHINE_END
diff --git a/arch/arm/mach-versatile/spc.c b/arch/arm/mach-versatile/spc.c
new file mode 100644 (file)
index 0000000..1da11bd
--- /dev/null
@@ -0,0 +1,598 @@
+/*
+ * Versatile Express Serial Power Controller (SPC) support
+ *
+ * Copyright (C) 2013 ARM Ltd.
+ *
+ * Authors: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
+ *          Achin Gupta           <achin.gupta@arm.com>
+ *          Lorenzo Pieralisi     <lorenzo.pieralisi@arm.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.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/cpu.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/slab.h>
+#include <linux/semaphore.h>
+
+#include <asm/cacheflush.h>
+
+#include "spc.h"
+
+#define SPCLOG "vexpress-spc: "
+
+#define PERF_LVL_A15           0x00
+#define PERF_REQ_A15           0x04
+#define PERF_LVL_A7            0x08
+#define PERF_REQ_A7            0x0c
+#define COMMS                  0x10
+#define COMMS_REQ              0x14
+#define PWC_STATUS             0x18
+#define PWC_FLAG               0x1c
+
+/* SPC wake-up IRQs status and mask */
+#define WAKE_INT_MASK          0x24
+#define WAKE_INT_RAW           0x28
+#define WAKE_INT_STAT          0x2c
+/* SPC power down registers */
+#define A15_PWRDN_EN           0x30
+#define A7_PWRDN_EN            0x34
+/* SPC per-CPU mailboxes */
+#define A15_BX_ADDR0           0x68
+#define A7_BX_ADDR0            0x78
+
+/* SPC CPU/cluster reset statue */
+#define STANDBYWFI_STAT                0x3c
+#define STANDBYWFI_STAT_A15_CPU_MASK(cpu)      (1 << (cpu))
+#define STANDBYWFI_STAT_A7_CPU_MASK(cpu)       (1 << (3 + (cpu)))
+
+/* SPC system config interface registers */
+#define SYSCFG_WDATA           0x70
+#define SYSCFG_RDATA           0x74
+
+/* A15/A7 OPP virtual register base */
+#define A15_PERFVAL_BASE       0xC10
+#define A7_PERFVAL_BASE                0xC30
+
+/* Config interface control bits */
+#define SYSCFG_START           BIT(31)
+#define SYSCFG_SCC             (6 << 20)
+#define SYSCFG_STAT            (14 << 20)
+
+/* wake-up interrupt masks */
+#define GBL_WAKEUP_INT_MSK     (0x3 << 10)
+
+/* TC2 static dual-cluster configuration */
+#define MAX_CLUSTERS           2
+
+/*
+ * Even though the SPC takes max 3-5 ms to complete any OPP/COMMS
+ * operation, the operation could start just before jiffie is about
+ * to be incremented. So setting timeout value of 20ms = 2jiffies@100Hz
+ */
+#define TIMEOUT_US     20000
+
+#define MAX_OPPS       8
+#define CA15_DVFS      0
+#define CA7_DVFS       1
+#define SPC_SYS_CFG    2
+#define STAT_COMPLETE(type)    ((1 << 0) << (type << 2))
+#define STAT_ERR(type)         ((1 << 1) << (type << 2))
+#define RESPONSE_MASK(type)    (STAT_COMPLETE(type) | STAT_ERR(type))
+
+struct ve_spc_opp {
+       unsigned long freq;
+       unsigned long u_volt;
+};
+
+struct ve_spc_drvdata {
+       void __iomem *baseaddr;
+       /*
+        * A15s cluster identifier
+        * It corresponds to A15 processors MPIDR[15:8] bitfield
+        */
+       u32 a15_clusid;
+       uint32_t cur_rsp_mask;
+       uint32_t cur_rsp_stat;
+       struct semaphore sem;
+       struct completion done;
+       struct ve_spc_opp *opps[MAX_CLUSTERS];
+       int num_opps[MAX_CLUSTERS];
+};
+
+static struct ve_spc_drvdata *info;
+
+static inline bool cluster_is_a15(u32 cluster)
+{
+       return cluster == info->a15_clusid;
+}
+
+/**
+ * ve_spc_global_wakeup_irq()
+ *
+ * Function to set/clear global wakeup IRQs. Not protected by locking since
+ * it might be used in code paths where normal cacheable locks are not
+ * working. Locking must be provided by the caller to ensure atomicity.
+ *
+ * @set: if true, global wake-up IRQs are set, if false they are cleared
+ */
+void ve_spc_global_wakeup_irq(bool set)
+{
+       u32 reg;
+
+       reg = readl_relaxed(info->baseaddr + WAKE_INT_MASK);
+
+       if (set)
+               reg |= GBL_WAKEUP_INT_MSK;
+       else
+               reg &= ~GBL_WAKEUP_INT_MSK;
+
+       writel_relaxed(reg, info->baseaddr + WAKE_INT_MASK);
+}
+
+/**
+ * ve_spc_cpu_wakeup_irq()
+ *
+ * Function to set/clear per-CPU wake-up IRQs. Not protected by locking since
+ * it might be used in code paths where normal cacheable locks are not
+ * working. Locking must be provided by the caller to ensure atomicity.
+ *
+ * @cluster: mpidr[15:8] bitfield describing cluster affinity level
+ * @cpu: mpidr[7:0] bitfield describing cpu affinity level
+ * @set: if true, wake-up IRQs are set, if false they are cleared
+ */
+void ve_spc_cpu_wakeup_irq(u32 cluster, u32 cpu, bool set)
+{
+       u32 mask, reg;
+
+       if (cluster >= MAX_CLUSTERS)
+               return;
+
+       mask = BIT(cpu);
+
+       if (!cluster_is_a15(cluster))
+               mask <<= 4;
+
+       reg = readl_relaxed(info->baseaddr + WAKE_INT_MASK);
+
+       if (set)
+               reg |= mask;
+       else
+               reg &= ~mask;
+
+       writel_relaxed(reg, info->baseaddr + WAKE_INT_MASK);
+}
+
+/**
+ * ve_spc_set_resume_addr() - set the jump address used for warm boot
+ *
+ * @cluster: mpidr[15:8] bitfield describing cluster affinity level
+ * @cpu: mpidr[7:0] bitfield describing cpu affinity level
+ * @addr: physical resume address
+ */
+void ve_spc_set_resume_addr(u32 cluster, u32 cpu, u32 addr)
+{
+       void __iomem *baseaddr;
+
+       if (cluster >= MAX_CLUSTERS)
+               return;
+
+       if (cluster_is_a15(cluster))
+               baseaddr = info->baseaddr + A15_BX_ADDR0 + (cpu << 2);
+       else
+               baseaddr = info->baseaddr + A7_BX_ADDR0 + (cpu << 2);
+
+       writel_relaxed(addr, baseaddr);
+}
+
+/**
+ * ve_spc_powerdown()
+ *
+ * Function to enable/disable cluster powerdown. Not protected by locking
+ * since it might be used in code paths where normal cacheable locks are not
+ * working. Locking must be provided by the caller to ensure atomicity.
+ *
+ * @cluster: mpidr[15:8] bitfield describing cluster affinity level
+ * @enable: if true enables powerdown, if false disables it
+ */
+void ve_spc_powerdown(u32 cluster, bool enable)
+{
+       u32 pwdrn_reg;
+
+       if (cluster >= MAX_CLUSTERS)
+               return;
+
+       pwdrn_reg = cluster_is_a15(cluster) ? A15_PWRDN_EN : A7_PWRDN_EN;
+       writel_relaxed(enable, info->baseaddr + pwdrn_reg);
+}
+
+static u32 standbywfi_cpu_mask(u32 cpu, u32 cluster)
+{
+       return cluster_is_a15(cluster) ?
+                 STANDBYWFI_STAT_A15_CPU_MASK(cpu)
+               : STANDBYWFI_STAT_A7_CPU_MASK(cpu);
+}
+
+/**
+ * ve_spc_cpu_in_wfi(u32 cpu, u32 cluster)
+ *
+ * @cpu: mpidr[7:0] bitfield describing CPU affinity level within cluster
+ * @cluster: mpidr[15:8] bitfield describing cluster affinity level
+ *
+ * @return: non-zero if and only if the specified CPU is in WFI
+ *
+ * Take care when interpreting the result of this function: a CPU might
+ * be in WFI temporarily due to idle, and is not necessarily safely
+ * parked.
+ */
+int ve_spc_cpu_in_wfi(u32 cpu, u32 cluster)
+{
+       int ret;
+       u32 mask = standbywfi_cpu_mask(cpu, cluster);
+
+       if (cluster >= MAX_CLUSTERS)
+               return 1;
+
+       ret = readl_relaxed(info->baseaddr + STANDBYWFI_STAT);
+
+       pr_debug("%s: PCFGREG[0x%X] = 0x%08X, mask = 0x%X\n",
+                __func__, STANDBYWFI_STAT, ret, mask);
+
+       return ret & mask;
+}
+
+static int ve_spc_get_performance(int cluster, u32 *freq)
+{
+       struct ve_spc_opp *opps = info->opps[cluster];
+       u32 perf_cfg_reg = 0;
+       u32 perf;
+
+       perf_cfg_reg = cluster_is_a15(cluster) ? PERF_LVL_A15 : PERF_LVL_A7;
+
+       perf = readl_relaxed(info->baseaddr + perf_cfg_reg);
+       if (perf >= info->num_opps[cluster])
+               return -EINVAL;
+
+       opps += perf;
+       *freq = opps->freq;
+
+       return 0;
+}
+
+/* find closest match to given frequency in OPP table */
+static int ve_spc_round_performance(int cluster, u32 freq)
+{
+       int idx, max_opp = info->num_opps[cluster];
+       struct ve_spc_opp *opps = info->opps[cluster];
+       u32 fmin = 0, fmax = ~0, ftmp;
+
+       freq /= 1000; /* OPP entries in kHz */
+       for (idx = 0; idx < max_opp; idx++, opps++) {
+               ftmp = opps->freq;
+               if (ftmp >= freq) {
+                       if (ftmp <= fmax)
+                               fmax = ftmp;
+               } else {
+                       if (ftmp >= fmin)
+                               fmin = ftmp;
+               }
+       }
+       if (fmax != ~0)
+               return fmax * 1000;
+       else
+               return fmin * 1000;
+}
+
+static int ve_spc_find_performance_index(int cluster, u32 freq)
+{
+       int idx, max_opp = info->num_opps[cluster];
+       struct ve_spc_opp *opps = info->opps[cluster];
+
+       for (idx = 0; idx < max_opp; idx++, opps++)
+               if (opps->freq == freq)
+                       break;
+       return (idx == max_opp) ? -EINVAL : idx;
+}
+
+static int ve_spc_waitforcompletion(int req_type)
+{
+       int ret = wait_for_completion_interruptible_timeout(
+                       &info->done, usecs_to_jiffies(TIMEOUT_US));
+       if (ret == 0)
+               ret = -ETIMEDOUT;
+       else if (ret > 0)
+               ret = info->cur_rsp_stat & STAT_COMPLETE(req_type) ? 0 : -EIO;
+       return ret;
+}
+
+static int ve_spc_set_performance(int cluster, u32 freq)
+{
+       u32 perf_cfg_reg;
+       int ret, perf, req_type;
+
+       if (cluster_is_a15(cluster)) {
+               req_type = CA15_DVFS;
+               perf_cfg_reg = PERF_LVL_A15;
+       } else {
+               req_type = CA7_DVFS;
+               perf_cfg_reg = PERF_LVL_A7;
+       }
+
+       perf = ve_spc_find_performance_index(cluster, freq);
+
+       if (perf < 0)
+               return perf;
+
+       if (down_timeout(&info->sem, usecs_to_jiffies(TIMEOUT_US)))
+               return -ETIME;
+
+       init_completion(&info->done);
+       info->cur_rsp_mask = RESPONSE_MASK(req_type);
+
+       writel(perf, info->baseaddr + perf_cfg_reg);
+       ret = ve_spc_waitforcompletion(req_type);
+
+       info->cur_rsp_mask = 0;
+       up(&info->sem);
+
+       return ret;
+}
+
+static int ve_spc_read_sys_cfg(int func, int offset, uint32_t *data)
+{
+       int ret;
+
+       if (down_timeout(&info->sem, usecs_to_jiffies(TIMEOUT_US)))
+               return -ETIME;
+
+       init_completion(&info->done);
+       info->cur_rsp_mask = RESPONSE_MASK(SPC_SYS_CFG);
+
+       /* Set the control value */
+       writel(SYSCFG_START | func | offset >> 2, info->baseaddr + COMMS);
+       ret = ve_spc_waitforcompletion(SPC_SYS_CFG);
+
+       if (ret == 0)
+               *data = readl(info->baseaddr + SYSCFG_RDATA);
+
+       info->cur_rsp_mask = 0;
+       up(&info->sem);
+
+       return ret;
+}
+
+static irqreturn_t ve_spc_irq_handler(int irq, void *data)
+{
+       struct ve_spc_drvdata *drv_data = data;
+       uint32_t status = readl_relaxed(drv_data->baseaddr + PWC_STATUS);
+
+       if (info->cur_rsp_mask & status) {
+               info->cur_rsp_stat = status;
+               complete(&drv_data->done);
+       }
+
+       return IRQ_HANDLED;
+}
+
+/*
+ *  +--------------------------+
+ *  | 31      20 | 19        0 |
+ *  +--------------------------+
+ *  |   m_volt   |  freq(kHz)  |
+ *  +--------------------------+
+ */
+#define MULT_FACTOR    20
+#define VOLT_SHIFT     20
+#define FREQ_MASK      (0xFFFFF)
+static int ve_spc_populate_opps(uint32_t cluster)
+{
+       uint32_t data = 0, off, ret, idx;
+       struct ve_spc_opp *opps;
+
+       opps = kcalloc(MAX_OPPS, sizeof(*opps), GFP_KERNEL);
+       if (!opps)
+               return -ENOMEM;
+
+       info->opps[cluster] = opps;
+
+       off = cluster_is_a15(cluster) ? A15_PERFVAL_BASE : A7_PERFVAL_BASE;
+       for (idx = 0; idx < MAX_OPPS; idx++, off += 4, opps++) {
+               ret = ve_spc_read_sys_cfg(SYSCFG_SCC, off, &data);
+               if (!ret) {
+                       opps->freq = (data & FREQ_MASK) * MULT_FACTOR;
+                       opps->u_volt = (data >> VOLT_SHIFT) * 1000;
+               } else {
+                       break;
+               }
+       }
+       info->num_opps[cluster] = idx;
+
+       return ret;
+}
+
+static int ve_init_opp_table(struct device *cpu_dev)
+{
+       int cluster;
+       int idx, ret = 0, max_opp;
+       struct ve_spc_opp *opps;
+
+       cluster = topology_physical_package_id(cpu_dev->id);
+       cluster = cluster < 0 ? 0 : cluster;
+
+       max_opp = info->num_opps[cluster];
+       opps = info->opps[cluster];
+
+       for (idx = 0; idx < max_opp; idx++, opps++) {
+               ret = dev_pm_opp_add(cpu_dev, opps->freq * 1000, opps->u_volt);
+               if (ret) {
+                       dev_warn(cpu_dev, "failed to add opp %lu %lu\n",
+                                opps->freq, opps->u_volt);
+                       return ret;
+               }
+       }
+       return ret;
+}
+
+int __init ve_spc_init(void __iomem *baseaddr, u32 a15_clusid, int irq)
+{
+       int ret;
+       info = kzalloc(sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       info->baseaddr = baseaddr;
+       info->a15_clusid = a15_clusid;
+
+       if (irq <= 0) {
+               pr_err(SPCLOG "Invalid IRQ %d\n", irq);
+               kfree(info);
+               return -EINVAL;
+       }
+
+       init_completion(&info->done);
+
+       readl_relaxed(info->baseaddr + PWC_STATUS);
+
+       ret = request_irq(irq, ve_spc_irq_handler, IRQF_TRIGGER_HIGH
+                               | IRQF_ONESHOT, "vexpress-spc", info);
+       if (ret) {
+               pr_err(SPCLOG "IRQ %d request failed\n", irq);
+               kfree(info);
+               return -ENODEV;
+       }
+
+       sema_init(&info->sem, 1);
+       /*
+        * Multi-cluster systems may need this data when non-coherent, during
+        * cluster power-up/power-down. Make sure driver info reaches main
+        * memory.
+        */
+       sync_cache_w(info);
+       sync_cache_w(&info);
+
+       return 0;
+}
+
+struct clk_spc {
+       struct clk_hw hw;
+       int cluster;
+};
+
+#define to_clk_spc(spc) container_of(spc, struct clk_spc, hw)
+static unsigned long spc_recalc_rate(struct clk_hw *hw,
+               unsigned long parent_rate)
+{
+       struct clk_spc *spc = to_clk_spc(hw);
+       u32 freq;
+
+       if (ve_spc_get_performance(spc->cluster, &freq))
+               return -EIO;
+
+       return freq * 1000;
+}
+
+static long spc_round_rate(struct clk_hw *hw, unsigned long drate,
+               unsigned long *parent_rate)
+{
+       struct clk_spc *spc = to_clk_spc(hw);
+
+       return ve_spc_round_performance(spc->cluster, drate);
+}
+
+static int spc_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct clk_spc *spc = to_clk_spc(hw);
+
+       return ve_spc_set_performance(spc->cluster, rate / 1000);
+}
+
+static struct clk_ops clk_spc_ops = {
+       .recalc_rate = spc_recalc_rate,
+       .round_rate = spc_round_rate,
+       .set_rate = spc_set_rate,
+};
+
+static struct clk *ve_spc_clk_register(struct device *cpu_dev)
+{
+       struct clk_init_data init;
+       struct clk_spc *spc;
+
+       spc = kzalloc(sizeof(*spc), GFP_KERNEL);
+       if (!spc)
+               return ERR_PTR(-ENOMEM);
+
+       spc->hw.init = &init;
+       spc->cluster = topology_physical_package_id(cpu_dev->id);
+
+       spc->cluster = spc->cluster < 0 ? 0 : spc->cluster;
+
+       init.name = dev_name(cpu_dev);
+       init.ops = &clk_spc_ops;
+       init.flags = CLK_GET_RATE_NOCACHE;
+       init.num_parents = 0;
+
+       return devm_clk_register(cpu_dev, &spc->hw);
+}
+
+static int __init ve_spc_clk_init(void)
+{
+       int cpu, cluster;
+       struct clk *clk;
+       bool init_opp_table[MAX_CLUSTERS] = { false };
+
+       if (!info)
+               return 0; /* Continue only if SPC is initialised */
+
+       if (ve_spc_populate_opps(0) || ve_spc_populate_opps(1)) {
+               pr_err("failed to build OPP table\n");
+               return -ENODEV;
+       }
+
+       for_each_possible_cpu(cpu) {
+               struct device *cpu_dev = get_cpu_device(cpu);
+               if (!cpu_dev) {
+                       pr_warn("failed to get cpu%d device\n", cpu);
+                       continue;
+               }
+               clk = ve_spc_clk_register(cpu_dev);
+               if (IS_ERR(clk)) {
+                       pr_warn("failed to register cpu%d clock\n", cpu);
+                       continue;
+               }
+               if (clk_register_clkdev(clk, NULL, dev_name(cpu_dev))) {
+                       pr_warn("failed to register cpu%d clock lookup\n", cpu);
+                       continue;
+               }
+
+               cluster = topology_physical_package_id(cpu_dev->id);
+               if (init_opp_table[cluster])
+                       continue;
+
+               if (ve_init_opp_table(cpu_dev))
+                       pr_warn("failed to initialise cpu%d opp table\n", cpu);
+               else if (dev_pm_opp_set_sharing_cpus(cpu_dev,
+                        topology_core_cpumask(cpu_dev->id)))
+                       pr_warn("failed to mark OPPs shared for cpu%d\n", cpu);
+               else
+                       init_opp_table[cluster] = true;
+       }
+
+       platform_device_register_simple("vexpress-spc-cpufreq", -1, NULL, 0);
+       return 0;
+}
+device_initcall(ve_spc_clk_init);
diff --git a/arch/arm/mach-versatile/spc.h b/arch/arm/mach-versatile/spc.h
new file mode 100644 (file)
index 0000000..288569f
--- /dev/null
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ *
+ * Copyright (C) 2012 ARM Limited
+ */
+
+
+#ifndef __SPC_H_
+#define __SPC_H_
+
+int __init ve_spc_init(void __iomem *base, u32 a15_clusid, int irq);
+void ve_spc_global_wakeup_irq(bool set);
+void ve_spc_cpu_wakeup_irq(u32 cluster, u32 cpu, bool set);
+void ve_spc_set_resume_addr(u32 cluster, u32 cpu, u32 addr);
+void ve_spc_powerdown(u32 cluster, bool enable);
+int ve_spc_cpu_in_wfi(u32 cpu, u32 cluster);
+
+#endif
diff --git a/arch/arm/mach-versatile/tc2_pm.c b/arch/arm/mach-versatile/tc2_pm.c
new file mode 100644 (file)
index 0000000..0fe78da
--- /dev/null
@@ -0,0 +1,261 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Created by: Nicolas Pitre, October 2012
+ * Copyright:  (C) 2012-2013  Linaro Limited
+ *
+ * Some portions of this file were originally written by Achin Gupta
+ * Copyright:   (C) 2012  ARM Limited
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/errno.h>
+#include <linux/irqchip/arm-gic.h>
+
+#include <asm/mcpm.h>
+#include <asm/proc-fns.h>
+#include <asm/cacheflush.h>
+#include <asm/cputype.h>
+#include <asm/cp15.h>
+
+#include <linux/arm-cci.h>
+
+#include "spc.h"
+
+/* SCC conf registers */
+#define RESET_CTRL             0x018
+#define RESET_A15_NCORERESET(cpu)      (1 << (2 + (cpu)))
+#define RESET_A7_NCORERESET(cpu)       (1 << (16 + (cpu)))
+
+#define A15_CONF               0x400
+#define A7_CONF                        0x500
+#define SYS_INFO               0x700
+#define SPC_BASE               0xb00
+
+static void __iomem *scc;
+
+#define TC2_CLUSTERS                   2
+#define TC2_MAX_CPUS_PER_CLUSTER       3
+
+static unsigned int tc2_nr_cpus[TC2_CLUSTERS];
+
+static int tc2_pm_cpu_powerup(unsigned int cpu, unsigned int cluster)
+{
+       pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+       if (cluster >= TC2_CLUSTERS || cpu >= tc2_nr_cpus[cluster])
+               return -EINVAL;
+       ve_spc_set_resume_addr(cluster, cpu,
+                              __pa_symbol(mcpm_entry_point));
+       ve_spc_cpu_wakeup_irq(cluster, cpu, true);
+       return 0;
+}
+
+static int tc2_pm_cluster_powerup(unsigned int cluster)
+{
+       pr_debug("%s: cluster %u\n", __func__, cluster);
+       if (cluster >= TC2_CLUSTERS)
+               return -EINVAL;
+       ve_spc_powerdown(cluster, false);
+       return 0;
+}
+
+static void tc2_pm_cpu_powerdown_prepare(unsigned int cpu, unsigned int cluster)
+{
+       pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+       BUG_ON(cluster >= TC2_CLUSTERS || cpu >= TC2_MAX_CPUS_PER_CLUSTER);
+       ve_spc_cpu_wakeup_irq(cluster, cpu, true);
+       /*
+        * If the CPU is committed to power down, make sure
+        * the power controller will be in charge of waking it
+        * up upon IRQ, ie IRQ lines are cut from GIC CPU IF
+        * to the CPU by disabling the GIC CPU IF to prevent wfi
+        * from completing execution behind power controller back
+        */
+       gic_cpu_if_down(0);
+}
+
+static void tc2_pm_cluster_powerdown_prepare(unsigned int cluster)
+{
+       pr_debug("%s: cluster %u\n", __func__, cluster);
+       BUG_ON(cluster >= TC2_CLUSTERS);
+       ve_spc_powerdown(cluster, true);
+       ve_spc_global_wakeup_irq(true);
+}
+
+static void tc2_pm_cpu_cache_disable(void)
+{
+       v7_exit_coherency_flush(louis);
+}
+
+static void tc2_pm_cluster_cache_disable(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\t"
+               "isb    \n\t"
+               "dsb    "
+               : : "r" (0x400) );
+       }
+
+       v7_exit_coherency_flush(all);
+       cci_disable_port_by_cpu(read_cpuid_mpidr());
+}
+
+static int tc2_core_in_reset(unsigned int cpu, unsigned int cluster)
+{
+       u32 mask = cluster ?
+                 RESET_A7_NCORERESET(cpu)
+               : RESET_A15_NCORERESET(cpu);
+
+       return !(readl_relaxed(scc + RESET_CTRL) & mask);
+}
+
+#define POLL_MSEC 10
+#define TIMEOUT_MSEC 1000
+
+static int tc2_pm_wait_for_powerdown(unsigned int cpu, unsigned int cluster)
+{
+       unsigned tries;
+
+       pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+       BUG_ON(cluster >= TC2_CLUSTERS || cpu >= TC2_MAX_CPUS_PER_CLUSTER);
+
+       for (tries = 0; tries < TIMEOUT_MSEC / POLL_MSEC; ++tries) {
+               pr_debug("%s(cpu=%u, cluster=%u): RESET_CTRL = 0x%08X\n",
+                        __func__, cpu, cluster,
+                        readl_relaxed(scc + RESET_CTRL));
+
+               /*
+                * We need the CPU to reach WFI, but the power
+                * controller may put the cluster in reset and
+                * power it off as soon as that happens, before
+                * we have a chance to see STANDBYWFI.
+                *
+                * So we need to check for both conditions:
+                */
+               if (tc2_core_in_reset(cpu, cluster) ||
+                   ve_spc_cpu_in_wfi(cpu, cluster))
+                       return 0; /* success: the CPU is halted */
+
+               /* Otherwise, wait and retry: */
+               msleep(POLL_MSEC);
+       }
+
+       return -ETIMEDOUT; /* timeout */
+}
+
+static void tc2_pm_cpu_suspend_prepare(unsigned int cpu, unsigned int cluster)
+{
+       ve_spc_set_resume_addr(cluster, cpu, __pa_symbol(mcpm_entry_point));
+}
+
+static void tc2_pm_cpu_is_up(unsigned int cpu, unsigned int cluster)
+{
+       pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+       BUG_ON(cluster >= TC2_CLUSTERS || cpu >= TC2_MAX_CPUS_PER_CLUSTER);
+       ve_spc_cpu_wakeup_irq(cluster, cpu, false);
+       ve_spc_set_resume_addr(cluster, cpu, 0);
+}
+
+static void tc2_pm_cluster_is_up(unsigned int cluster)
+{
+       pr_debug("%s: cluster %u\n", __func__, cluster);
+       BUG_ON(cluster >= TC2_CLUSTERS);
+       ve_spc_powerdown(cluster, false);
+       ve_spc_global_wakeup_irq(false);
+}
+
+static const struct mcpm_platform_ops tc2_pm_power_ops = {
+       .cpu_powerup            = tc2_pm_cpu_powerup,
+       .cluster_powerup        = tc2_pm_cluster_powerup,
+       .cpu_suspend_prepare    = tc2_pm_cpu_suspend_prepare,
+       .cpu_powerdown_prepare  = tc2_pm_cpu_powerdown_prepare,
+       .cluster_powerdown_prepare = tc2_pm_cluster_powerdown_prepare,
+       .cpu_cache_disable      = tc2_pm_cpu_cache_disable,
+       .cluster_cache_disable  = tc2_pm_cluster_cache_disable,
+       .wait_for_powerdown     = tc2_pm_wait_for_powerdown,
+       .cpu_is_up              = tc2_pm_cpu_is_up,
+       .cluster_is_up          = tc2_pm_cluster_is_up,
+};
+
+/*
+ * Enable cluster-level coherency, in preparation for turning on the MMU.
+ */
+static void __naked tc2_pm_power_up_setup(unsigned int affinity_level)
+{
+       asm volatile (" \n"
+"      cmp     r0, #1 \n"
+"      bxne    lr \n"
+"      b       cci_enable_port_for_self ");
+}
+
+static int __init tc2_pm_init(void)
+{
+       unsigned int mpidr, cpu, cluster;
+       int ret, irq;
+       u32 a15_cluster_id, a7_cluster_id, sys_info;
+       struct device_node *np;
+
+       /*
+        * The power management-related features are hidden behind
+        * SCC registers. We need to extract runtime information like
+        * cluster ids and number of CPUs really available in clusters.
+        */
+       np = of_find_compatible_node(NULL, NULL,
+                       "arm,vexpress-scc,v2p-ca15_a7");
+       scc = of_iomap(np, 0);
+       if (!scc)
+               return -ENODEV;
+
+       a15_cluster_id = readl_relaxed(scc + A15_CONF) & 0xf;
+       a7_cluster_id = readl_relaxed(scc + A7_CONF) & 0xf;
+       if (a15_cluster_id >= TC2_CLUSTERS || a7_cluster_id >= TC2_CLUSTERS)
+               return -EINVAL;
+
+       sys_info = readl_relaxed(scc + SYS_INFO);
+       tc2_nr_cpus[a15_cluster_id] = (sys_info >> 16) & 0xf;
+       tc2_nr_cpus[a7_cluster_id] = (sys_info >> 20) & 0xf;
+
+       irq = irq_of_parse_and_map(np, 0);
+
+       /*
+        * A subset of the SCC registers is also used to communicate
+        * with the SPC (power controller). We need to be able to
+        * drive it very early in the boot process to power up
+        * processors, so we initialize the SPC driver here.
+        */
+       ret = ve_spc_init(scc + SPC_BASE, a15_cluster_id, irq);
+       if (ret)
+               return ret;
+
+       if (!cci_probed())
+               return -ENODEV;
+
+       mpidr = read_cpuid_mpidr();
+       cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
+       cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+       pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
+       if (cluster >= TC2_CLUSTERS || cpu >= tc2_nr_cpus[cluster]) {
+               pr_err("%s: boot CPU is out of bound!\n", __func__);
+               return -EINVAL;
+       }
+
+       ret = mcpm_platform_register(&tc2_pm_power_ops);
+       if (!ret) {
+               mcpm_sync_init(tc2_pm_power_up_setup);
+               /* test if we can (re)enable the CCI on our own */
+               BUG_ON(mcpm_loopback(tc2_pm_cluster_cache_disable) != 0);
+               pr_info("TC2 power management initialized\n");
+       }
+       return ret;
+}
+
+early_initcall(tc2_pm_init);
diff --git a/arch/arm/mach-versatile/v2m-mps2.c b/arch/arm/mach-versatile/v2m-mps2.c
new file mode 100644 (file)
index 0000000..5b50d8e
--- /dev/null
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2015 ARM Limited
+ *
+ * Author: Vladimir Murzin <vladimir.murzin@arm.com>
+ */
+
+#include <asm/mach/arch.h>
+
+static const char *const mps2_compat[] __initconst = {
+       "arm,mps2",
+       NULL
+};
+
+DT_MACHINE_START(MPS2DT, "MPS2 (Device Tree Support)")
+       .dt_compat = mps2_compat,
+MACHINE_END
diff --git a/arch/arm/mach-versatile/v2m.c b/arch/arm/mach-versatile/v2m.c
new file mode 100644 (file)
index 0000000..79afdf2
--- /dev/null
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <asm/mach/arch.h>
+
+#include "vexpress.h"
+
+#define SYS_FLAGSSET           0x030
+#define SYS_FLAGSCLR           0x034
+
+void vexpress_flags_set(u32 data)
+{
+       static void __iomem *base;
+
+       if (!base) {
+               struct device_node *node = of_find_compatible_node(NULL, NULL,
+                               "arm,vexpress-sysreg");
+
+               base = of_iomap(node, 0);
+       }
+
+       if (WARN_ON(!base))
+               return;
+
+       writel(~0, base + SYS_FLAGSCLR);
+       writel(data, base + SYS_FLAGSSET);
+}
+
+static const char * const v2m_dt_match[] __initconst = {
+       "arm,vexpress",
+       NULL,
+};
+
+DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express")
+       .dt_compat      = v2m_dt_match,
+       .l2c_aux_val    = 0x00400000,
+       .l2c_aux_mask   = 0xfe0fffff,
+       .smp            = smp_ops(vexpress_smp_dt_ops),
+       .smp_init       = smp_init_ops(vexpress_smp_init_ops),
+MACHINE_END
diff --git a/arch/arm/mach-versatile/versatile.c b/arch/arm/mach-versatile/versatile.c
new file mode 100644 (file)
index 0000000..02ba68a
--- /dev/null
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Versatile board support using the device tree
+ *
+ *  Copyright (C) 2010 Secret Lab Technologies Ltd.
+ *  Copyright (C) 2009 Jeremy Kerr <jeremy.kerr@canonical.com>
+ *  Copyright (C) 2004 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/mmci.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+/* macro to get at MMIO space when running virtually */
+#define IO_ADDRESS(x)          (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
+#define __io_address(n)                ((void __iomem __force *)IO_ADDRESS(n))
+
+/*
+ * ------------------------------------------------------------------------
+ *  Versatile Registers
+ * ------------------------------------------------------------------------
+ */
+#define VERSATILE_SYS_PCICTL_OFFSET           0x44
+#define VERSATILE_SYS_MCI_OFFSET              0x48
+
+/*
+ * VERSATILE peripheral addresses
+ */
+#define VERSATILE_MMCI0_BASE           0x10005000      /* MMC interface */
+#define VERSATILE_MMCI1_BASE           0x1000B000      /* MMC Interface */
+#define VERSATILE_SCTL_BASE            0x101E0000      /* System controller */
+
+/*
+ * System controller bit assignment
+ */
+#define VERSATILE_REFCLK       0
+#define VERSATILE_TIMCLK       1
+
+#define VERSATILE_TIMER1_EnSel 15
+#define VERSATILE_TIMER2_EnSel 17
+#define VERSATILE_TIMER3_EnSel 19
+#define VERSATILE_TIMER4_EnSel 21
+
+static void __iomem *versatile_sys_base;
+
+unsigned int mmc_status(struct device *dev)
+{
+       struct amba_device *adev = container_of(dev, struct amba_device, dev);
+       u32 mask;
+
+       if (adev->res.start == VERSATILE_MMCI0_BASE)
+               mask = 1;
+       else
+               mask = 2;
+
+       return readl(versatile_sys_base + VERSATILE_SYS_MCI_OFFSET) & mask;
+}
+
+static struct mmci_platform_data mmc0_plat_data = {
+       .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
+       .status         = mmc_status,
+};
+
+static struct mmci_platform_data mmc1_plat_data = {
+       .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
+       .status         = mmc_status,
+};
+
+/*
+ * Lookup table for attaching a specific name and platform_data pointer to
+ * devices as they get created by of_platform_populate().  Ideally this table
+ * would not exist, but the current clock implementation depends on some devices
+ * having a specific name.
+ */
+struct of_dev_auxdata versatile_auxdata_lookup[] __initdata = {
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI0_BASE, "fpga:05", &mmc0_plat_data),
+       OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI1_BASE, "fpga:0b", &mmc1_plat_data),
+       {}
+};
+
+static struct map_desc versatile_io_desc[] __initdata __maybe_unused = {
+       {
+               .virtual        =  IO_ADDRESS(VERSATILE_SCTL_BASE),
+               .pfn            = __phys_to_pfn(VERSATILE_SCTL_BASE),
+               .length         = SZ_4K * 9,
+               .type           = MT_DEVICE
+       }
+};
+
+static void __init versatile_map_io(void)
+{
+       debug_ll_io_init();
+       iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));
+}
+
+static void __init versatile_init_early(void)
+{
+       u32 val;
+
+       /*
+        * set clock frequency:
+        *      VERSATILE_REFCLK is 32KHz
+        *      VERSATILE_TIMCLK is 1MHz
+        */
+       val = readl(__io_address(VERSATILE_SCTL_BASE));
+       writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) |
+              (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) |
+              (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) |
+              (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
+              __io_address(VERSATILE_SCTL_BASE));
+}
+
+static void __init versatile_dt_pci_init(void)
+{
+       u32 val;
+       struct device_node *np;
+       struct property *newprop;
+
+       np = of_find_compatible_node(NULL, NULL, "arm,versatile-pci");
+       if (!np)
+               return;
+
+       /* Check if PCI backplane is detected */
+       val = readl(versatile_sys_base + VERSATILE_SYS_PCICTL_OFFSET);
+       if (val & 1) {
+               /*
+                * Enable PCI accesses. Note that the documentaton is
+                * inconsistent whether or not this is needed, but the old
+                * driver had it so we will keep it.
+                */
+               writel(1, versatile_sys_base + VERSATILE_SYS_PCICTL_OFFSET);
+               goto out_put_node;
+       }
+
+       newprop = kzalloc(sizeof(*newprop), GFP_KERNEL);
+       if (!newprop)
+               goto out_put_node;
+
+       newprop->name = kstrdup("status", GFP_KERNEL);
+       newprop->value = kstrdup("disabled", GFP_KERNEL);
+       newprop->length = sizeof("disabled");
+       of_update_property(np, newprop);
+
+       pr_info("Not plugged into PCI backplane!\n");
+
+out_put_node:
+       of_node_put(np);
+}
+
+static void __init versatile_dt_init(void)
+{
+       struct device_node *np;
+
+       np = of_find_compatible_node(NULL, NULL, "arm,core-module-versatile");
+       if (np)
+               versatile_sys_base = of_iomap(np, 0);
+       WARN_ON(!versatile_sys_base);
+
+       versatile_dt_pci_init();
+
+       of_platform_default_populate(NULL, versatile_auxdata_lookup, NULL);
+}
+
+static const char *const versatile_dt_match[] __initconst = {
+       "arm,versatile-ab",
+       "arm,versatile-pb",
+       NULL,
+};
+
+DT_MACHINE_START(VERSATILE_PB, "ARM-Versatile (Device Tree Support)")
+       .map_io         = versatile_map_io,
+       .init_early     = versatile_init_early,
+       .init_machine   = versatile_dt_init,
+       .dt_compat      = versatile_dt_match,
+MACHINE_END
diff --git a/arch/arm/mach-versatile/versatile_dt.c b/arch/arm/mach-versatile/versatile_dt.c
deleted file mode 100644 (file)
index 02ba68a..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Versatile board support using the device tree
- *
- *  Copyright (C) 2010 Secret Lab Technologies Ltd.
- *  Copyright (C) 2009 Jeremy Kerr <jeremy.kerr@canonical.com>
- *  Copyright (C) 2004 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- */
-
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
-#include <linux/slab.h>
-#include <linux/amba/bus.h>
-#include <linux/amba/mmci.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-/* macro to get at MMIO space when running virtually */
-#define IO_ADDRESS(x)          (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000)
-#define __io_address(n)                ((void __iomem __force *)IO_ADDRESS(n))
-
-/*
- * ------------------------------------------------------------------------
- *  Versatile Registers
- * ------------------------------------------------------------------------
- */
-#define VERSATILE_SYS_PCICTL_OFFSET           0x44
-#define VERSATILE_SYS_MCI_OFFSET              0x48
-
-/*
- * VERSATILE peripheral addresses
- */
-#define VERSATILE_MMCI0_BASE           0x10005000      /* MMC interface */
-#define VERSATILE_MMCI1_BASE           0x1000B000      /* MMC Interface */
-#define VERSATILE_SCTL_BASE            0x101E0000      /* System controller */
-
-/*
- * System controller bit assignment
- */
-#define VERSATILE_REFCLK       0
-#define VERSATILE_TIMCLK       1
-
-#define VERSATILE_TIMER1_EnSel 15
-#define VERSATILE_TIMER2_EnSel 17
-#define VERSATILE_TIMER3_EnSel 19
-#define VERSATILE_TIMER4_EnSel 21
-
-static void __iomem *versatile_sys_base;
-
-unsigned int mmc_status(struct device *dev)
-{
-       struct amba_device *adev = container_of(dev, struct amba_device, dev);
-       u32 mask;
-
-       if (adev->res.start == VERSATILE_MMCI0_BASE)
-               mask = 1;
-       else
-               mask = 2;
-
-       return readl(versatile_sys_base + VERSATILE_SYS_MCI_OFFSET) & mask;
-}
-
-static struct mmci_platform_data mmc0_plat_data = {
-       .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
-       .status         = mmc_status,
-};
-
-static struct mmci_platform_data mmc1_plat_data = {
-       .ocr_mask       = MMC_VDD_32_33|MMC_VDD_33_34,
-       .status         = mmc_status,
-};
-
-/*
- * Lookup table for attaching a specific name and platform_data pointer to
- * devices as they get created by of_platform_populate().  Ideally this table
- * would not exist, but the current clock implementation depends on some devices
- * having a specific name.
- */
-struct of_dev_auxdata versatile_auxdata_lookup[] __initdata = {
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI0_BASE, "fpga:05", &mmc0_plat_data),
-       OF_DEV_AUXDATA("arm,primecell", VERSATILE_MMCI1_BASE, "fpga:0b", &mmc1_plat_data),
-       {}
-};
-
-static struct map_desc versatile_io_desc[] __initdata __maybe_unused = {
-       {
-               .virtual        =  IO_ADDRESS(VERSATILE_SCTL_BASE),
-               .pfn            = __phys_to_pfn(VERSATILE_SCTL_BASE),
-               .length         = SZ_4K * 9,
-               .type           = MT_DEVICE
-       }
-};
-
-static void __init versatile_map_io(void)
-{
-       debug_ll_io_init();
-       iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));
-}
-
-static void __init versatile_init_early(void)
-{
-       u32 val;
-
-       /*
-        * set clock frequency:
-        *      VERSATILE_REFCLK is 32KHz
-        *      VERSATILE_TIMCLK is 1MHz
-        */
-       val = readl(__io_address(VERSATILE_SCTL_BASE));
-       writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) |
-              (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) |
-              (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) |
-              (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
-              __io_address(VERSATILE_SCTL_BASE));
-}
-
-static void __init versatile_dt_pci_init(void)
-{
-       u32 val;
-       struct device_node *np;
-       struct property *newprop;
-
-       np = of_find_compatible_node(NULL, NULL, "arm,versatile-pci");
-       if (!np)
-               return;
-
-       /* Check if PCI backplane is detected */
-       val = readl(versatile_sys_base + VERSATILE_SYS_PCICTL_OFFSET);
-       if (val & 1) {
-               /*
-                * Enable PCI accesses. Note that the documentaton is
-                * inconsistent whether or not this is needed, but the old
-                * driver had it so we will keep it.
-                */
-               writel(1, versatile_sys_base + VERSATILE_SYS_PCICTL_OFFSET);
-               goto out_put_node;
-       }
-
-       newprop = kzalloc(sizeof(*newprop), GFP_KERNEL);
-       if (!newprop)
-               goto out_put_node;
-
-       newprop->name = kstrdup("status", GFP_KERNEL);
-       newprop->value = kstrdup("disabled", GFP_KERNEL);
-       newprop->length = sizeof("disabled");
-       of_update_property(np, newprop);
-
-       pr_info("Not plugged into PCI backplane!\n");
-
-out_put_node:
-       of_node_put(np);
-}
-
-static void __init versatile_dt_init(void)
-{
-       struct device_node *np;
-
-       np = of_find_compatible_node(NULL, NULL, "arm,core-module-versatile");
-       if (np)
-               versatile_sys_base = of_iomap(np, 0);
-       WARN_ON(!versatile_sys_base);
-
-       versatile_dt_pci_init();
-
-       of_platform_default_populate(NULL, versatile_auxdata_lookup, NULL);
-}
-
-static const char *const versatile_dt_match[] __initconst = {
-       "arm,versatile-ab",
-       "arm,versatile-pb",
-       NULL,
-};
-
-DT_MACHINE_START(VERSATILE_PB, "ARM-Versatile (Device Tree Support)")
-       .map_io         = versatile_map_io,
-       .init_early     = versatile_init_early,
-       .init_machine   = versatile_dt_init,
-       .dt_compat      = versatile_dt_match,
-MACHINE_END
diff --git a/arch/arm/mach-versatile/vexpress.h b/arch/arm/mach-versatile/vexpress.h
new file mode 100644 (file)
index 0000000..bda7867
--- /dev/null
@@ -0,0 +1,4 @@
+bool vexpress_smp_init_ops(void);
+void vexpress_flags_set(u32 data);
+
+extern const struct smp_operations vexpress_smp_dt_ops;
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
deleted file mode 100644 (file)
index 2e6aff5..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-menuconfig ARCH_VEXPRESS
-       bool "ARM Ltd. Versatile Express family"
-       depends on ARCH_MULTI_V7
-       select ARCH_SUPPORTS_BIG_ENDIAN
-       select ARM_AMBA
-       select ARM_GIC
-       select ARM_GLOBAL_TIMER
-       select ARM_TIMER_SP804
-       select GPIOLIB
-       select HAVE_ARM_SCU if SMP
-       select HAVE_ARM_TWD if SMP
-       select HAVE_PATA_PLATFORM
-       select CLK_ICST
-       select NO_IOPORT_MAP
-       select PLAT_VERSATILE
-       select POWER_RESET
-       select POWER_RESET_VEXPRESS
-       select POWER_SUPPLY
-       select REGULATOR if MMC_ARMMMCI
-       select REGULATOR_FIXED_VOLTAGE if REGULATOR
-       select VEXPRESS_CONFIG
-       help
-         This option enables support for systems using Cortex processor based
-         ARM core and logic (FPGA) tiles on the Versatile Express motherboard,
-         for example:
-
-         - CoreTile Express A5x2 (V2P-CA5s)
-         - CoreTile Express A9x4 (V2P-CA9)
-         - CoreTile Express A15x2 (V2P-CA15)
-         - LogicTile Express 13MG (V2F-2XV6) with A5, A7, A9 or A15 SMMs
-           (Soft Macrocell Models)
-         - Versatile Express RTSMs (Models)
-
-         You must boot using a Flattened Device Tree in order to use these
-         platforms. The traditional (ATAGs) boot method is not usable on
-         these boards with this option.
-
-if ARCH_VEXPRESS
-
-config ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA
-       bool "Enable A5 and A9 only errata work-arounds"
-       default y
-       select ARM_ERRATA_643719 if SMP
-       select ARM_ERRATA_720789
-       select PL310_ERRATA_753970 if CACHE_L2X0
-       help
-         Provides common dependencies for Versatile Express platforms
-         based on Cortex-A5 and Cortex-A9 processors. In order to
-         build a working kernel, you must also enable relevant core
-         tile support or Flattened Device Tree based support options.
-
-config ARCH_VEXPRESS_DCSCB
-       bool "Dual Cluster System Control Block (DCSCB) support"
-       depends on MCPM
-       select ARM_CCI400_PORT_CTRL
-       help
-         Support for the Dual Cluster System Configuration Block (DCSCB).
-         This is needed to provide CPU and cluster power management
-         on RTSM implementing big.LITTLE.
-
-config ARCH_VEXPRESS_SPC
-       bool "Versatile Express Serial Power Controller (SPC)"
-       select PM_OPP
-       help
-         The TC2 (A15x2 A7x3) versatile express core tile integrates a logic
-         block called Serial Power Controller (SPC) that provides the interface
-         between the dual cluster test-chip and the M3 microcontroller that
-         carries out power management.
-
-config ARCH_VEXPRESS_TC2_PM
-       bool "Versatile Express TC2 power management"
-       depends on MCPM
-       select ARM_CCI400_PORT_CTRL
-       select ARCH_VEXPRESS_SPC
-       select ARM_CPU_SUSPEND
-       help
-         Support for CPU and cluster power management on Versatile Express
-         with a TC2 (A15x2 A7x3) big.LITTLE core tile.
-
-endif
diff --git a/arch/arm/mach-vexpress/Makefile b/arch/arm/mach-vexpress/Makefile
deleted file mode 100644 (file)
index 3651a1e..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the linux kernel.
-#
-ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := \
-       -I$(srctree)/arch/arm/plat-versatile/include
-
-obj-$(CONFIG_ARCH_VEXPRESS)            := v2m.o
-obj-$(CONFIG_ARCH_VEXPRESS_DCSCB)      += dcscb.o      dcscb_setup.o
-CFLAGS_dcscb.o                         += -march=armv7-a
-CFLAGS_REMOVE_dcscb.o                  = -pg
-obj-$(CONFIG_ARCH_VEXPRESS_SPC)                += spc.o
-CFLAGS_REMOVE_spc.o                    = -pg
-obj-$(CONFIG_ARCH_VEXPRESS_TC2_PM)     += tc2_pm.o
-CFLAGS_tc2_pm.o                                += -march=armv7-a
-CFLAGS_REMOVE_tc2_pm.o                 = -pg
-obj-$(CONFIG_SMP)                      += platsmp.o
-
-obj-$(CONFIG_ARCH_MPS2)                        += v2m-mps2.o
diff --git a/arch/arm/mach-vexpress/Makefile.boot b/arch/arm/mach-vexpress/Makefile.boot
deleted file mode 100644 (file)
index cec195d..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-# Empty file waiting for deletion once Makefile.boot isn't needed any more.
-# Patch waits for application at
-# http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7889/1 .
diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h
deleted file mode 100644 (file)
index bda7867..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-bool vexpress_smp_init_ops(void);
-void vexpress_flags_set(u32 data);
-
-extern const struct smp_operations vexpress_smp_dt_ops;
diff --git a/arch/arm/mach-vexpress/dcscb.c b/arch/arm/mach-vexpress/dcscb.c
deleted file mode 100644 (file)
index a0554d7..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * arch/arm/mach-vexpress/dcscb.c - Dual Cluster System Configuration Block
- *
- * Created by: Nicolas Pitre, May 2012
- * Copyright:  (C) 2012-2013  Linaro Limited
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/errno.h>
-#include <linux/of_address.h>
-#include <linux/vexpress.h>
-#include <linux/arm-cci.h>
-
-#include <asm/mcpm.h>
-#include <asm/proc-fns.h>
-#include <asm/cacheflush.h>
-#include <asm/cputype.h>
-#include <asm/cp15.h>
-
-#include "core.h"
-
-#define RST_HOLD0      0x0
-#define RST_HOLD1      0x4
-#define SYS_SWRESET    0x8
-#define RST_STAT0      0xc
-#define RST_STAT1      0x10
-#define EAG_CFG_R      0x20
-#define EAG_CFG_W      0x24
-#define KFC_CFG_R      0x28
-#define KFC_CFG_W      0x2c
-#define DCS_CFG_R      0x30
-
-static void __iomem *dcscb_base;
-static int dcscb_allcpus_mask[2];
-
-static int dcscb_cpu_powerup(unsigned int cpu, unsigned int cluster)
-{
-       unsigned int rst_hold, cpumask = (1 << cpu);
-
-       pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
-       if (cluster >= 2 || !(cpumask & dcscb_allcpus_mask[cluster]))
-               return -EINVAL;
-
-       rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4);
-       rst_hold &= ~(cpumask | (cpumask << 4));
-       writel_relaxed(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4);
-       return 0;
-}
-
-static int dcscb_cluster_powerup(unsigned int cluster)
-{
-       unsigned int rst_hold;
-
-       pr_debug("%s: cluster %u\n", __func__, cluster);
-       if (cluster >= 2)
-               return -EINVAL;
-
-       /* remove cluster reset and add individual CPU's reset */
-       rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4);
-       rst_hold &= ~(1 << 8);
-       rst_hold |= dcscb_allcpus_mask[cluster];
-       writel_relaxed(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4);
-       return 0;
-}
-
-static void dcscb_cpu_powerdown_prepare(unsigned int cpu, unsigned int cluster)
-{
-       unsigned int rst_hold;
-
-       pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
-       BUG_ON(cluster >= 2 || !((1 << cpu) & dcscb_allcpus_mask[cluster]));
-
-       rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4);
-       rst_hold |= (1 << cpu);
-       writel_relaxed(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4);
-}
-
-static void dcscb_cluster_powerdown_prepare(unsigned int cluster)
-{
-       unsigned int rst_hold;
-
-       pr_debug("%s: cluster %u\n", __func__, cluster);
-       BUG_ON(cluster >= 2);
-
-       rst_hold = readl_relaxed(dcscb_base + RST_HOLD0 + cluster * 4);
-       rst_hold |= (1 << 8);
-       writel_relaxed(rst_hold, dcscb_base + RST_HOLD0 + cluster * 4);
-}
-
-static void dcscb_cpu_cache_disable(void)
-{
-       /* Disable and flush the local CPU cache. */
-       v7_exit_coherency_flush(louis);
-}
-
-static void dcscb_cluster_cache_disable(void)
-{
-       /* Flush all cache levels for this cluster. */
-       v7_exit_coherency_flush(all);
-
-       /*
-        * A full outer cache flush could be needed at this point
-        * on platforms with such a cache, depending on where the
-        * outer cache sits. In some cases the notion of a "last
-        * cluster standing" would need to be implemented if the
-        * outer cache is shared across clusters. In any case, when
-        * the outer cache needs flushing, there is no concurrent
-        * access to the cache controller to worry about and no
-        * special locking besides what is already provided by the
-        * MCPM state machinery is needed.
-        */
-
-       /*
-        * Disable cluster-level coherency by masking
-        * incoming snoops and DVM messages:
-        */
-       cci_disable_port_by_cpu(read_cpuid_mpidr());
-}
-
-static const struct mcpm_platform_ops dcscb_power_ops = {
-       .cpu_powerup            = dcscb_cpu_powerup,
-       .cluster_powerup        = dcscb_cluster_powerup,
-       .cpu_powerdown_prepare  = dcscb_cpu_powerdown_prepare,
-       .cluster_powerdown_prepare = dcscb_cluster_powerdown_prepare,
-       .cpu_cache_disable      = dcscb_cpu_cache_disable,
-       .cluster_cache_disable  = dcscb_cluster_cache_disable,
-};
-
-extern void dcscb_power_up_setup(unsigned int affinity_level);
-
-static int __init dcscb_init(void)
-{
-       struct device_node *node;
-       unsigned int cfg;
-       int ret;
-
-       if (!cci_probed())
-               return -ENODEV;
-
-       node = of_find_compatible_node(NULL, NULL, "arm,rtsm,dcscb");
-       if (!node)
-               return -ENODEV;
-       dcscb_base = of_iomap(node, 0);
-       if (!dcscb_base)
-               return -EADDRNOTAVAIL;
-       cfg = readl_relaxed(dcscb_base + DCS_CFG_R);
-       dcscb_allcpus_mask[0] = (1 << (((cfg >> 16) >> (0 << 2)) & 0xf)) - 1;
-       dcscb_allcpus_mask[1] = (1 << (((cfg >> 16) >> (1 << 2)) & 0xf)) - 1;
-
-       ret = mcpm_platform_register(&dcscb_power_ops);
-       if (!ret)
-               ret = mcpm_sync_init(dcscb_power_up_setup);
-       if (ret) {
-               iounmap(dcscb_base);
-               return ret;
-       }
-
-       pr_info("VExpress DCSCB support installed\n");
-
-       /*
-        * Future entries into the kernel can now go
-        * through the cluster entry vectors.
-        */
-       vexpress_flags_set(__pa_symbol(mcpm_entry_point));
-
-       return 0;
-}
-
-early_initcall(dcscb_init);
diff --git a/arch/arm/mach-vexpress/dcscb_setup.S b/arch/arm/mach-vexpress/dcscb_setup.S
deleted file mode 100644 (file)
index 0614b2e..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/include/asm/dcscb_setup.S
- *
- * Created by:  Dave Martin, 2012-06-22
- * Copyright:   (C) 2012-2013  Linaro Limited
- */
-
-#include <linux/linkage.h>
-
-
-ENTRY(dcscb_power_up_setup)
-
-       cmp     r0, #0                  @ check affinity level
-       beq     2f
-
-/*
- * Enable cluster-level coherency, in preparation for turning on the MMU.
- * The ACTLR SMP bit does not need to be set here, because cpu_resume()
- * already restores that.
- *
- * A15/A7 may not require explicit L2 invalidation on reset, dependent
- * on hardware integration decisions.
- * For now, this code assumes that L2 is either already invalidated,
- * or invalidation is not required.
- */
-
-       b       cci_enable_port_for_self
-
-2:     @ Implementation-specific local CPU setup operations should go here,
-       @ if any.  In this case, there is nothing to do.
-
-       bx      lr
-
-ENDPROC(dcscb_power_up_setup)
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
deleted file mode 100644 (file)
index 99c9312..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *  linux/arch/arm/mach-vexpress/platsmp.c
- *
- *  Copyright (C) 2002 ARM Ltd.
- *  All Rights Reserved
- */
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/smp.h>
-#include <linux/io.h>
-#include <linux/of_address.h>
-#include <linux/vexpress.h>
-
-#include <asm/mcpm.h>
-#include <asm/smp_scu.h>
-#include <asm/mach/map.h>
-
-#include <plat/platsmp.h>
-
-#include "core.h"
-
-bool __init vexpress_smp_init_ops(void)
-{
-#ifdef CONFIG_MCPM
-       int cpu;
-       struct device_node *cpu_node, *cci_node;
-
-       /*
-        * The best way to detect a multi-cluster configuration
-        * is to detect if the kernel can take over CCI ports
-        * control. Loop over possible CPUs and check if CCI
-        * port control is available.
-        * Override the default vexpress_smp_ops if so.
-        */
-       for_each_possible_cpu(cpu) {
-               bool available;
-
-               cpu_node = of_get_cpu_node(cpu, NULL);
-               if (WARN(!cpu_node, "Missing cpu device node!"))
-                       return false;
-
-               cci_node = of_parse_phandle(cpu_node, "cci-control-port", 0);
-               available = cci_node && of_device_is_available(cci_node);
-               of_node_put(cci_node);
-               of_node_put(cpu_node);
-
-               if (!available)
-                       return false;
-       }
-
-       mcpm_smp_set_ops();
-       return true;
-#else
-       return false;
-#endif
-}
-
-static const struct of_device_id vexpress_smp_dt_scu_match[] __initconst = {
-       { .compatible = "arm,cortex-a5-scu", },
-       { .compatible = "arm,cortex-a9-scu", },
-       {}
-};
-
-static void __init vexpress_smp_dt_prepare_cpus(unsigned int max_cpus)
-{
-       struct device_node *scu = of_find_matching_node(NULL,
-                       vexpress_smp_dt_scu_match);
-
-       if (scu)
-               scu_enable(of_iomap(scu, 0));
-
-       /*
-        * Write the address of secondary startup into the
-        * system-wide flags register. The boot monitor waits
-        * until it receives a soft interrupt, and then the
-        * secondary CPU branches to this address.
-        */
-       vexpress_flags_set(__pa_symbol(versatile_secondary_startup));
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-static void vexpress_cpu_die(unsigned int cpu)
-{
-       versatile_immitation_cpu_die(cpu, 0x40);
-}
-#endif
-
-const struct smp_operations vexpress_smp_dt_ops __initconst = {
-       .smp_prepare_cpus       = vexpress_smp_dt_prepare_cpus,
-       .smp_secondary_init     = versatile_secondary_init,
-       .smp_boot_secondary     = versatile_boot_secondary,
-#ifdef CONFIG_HOTPLUG_CPU
-       .cpu_die                = vexpress_cpu_die,
-#endif
-};
diff --git a/arch/arm/mach-vexpress/spc.c b/arch/arm/mach-vexpress/spc.c
deleted file mode 100644 (file)
index 1da11bd..0000000
+++ /dev/null
@@ -1,598 +0,0 @@
-/*
- * Versatile Express Serial Power Controller (SPC) support
- *
- * Copyright (C) 2013 ARM Ltd.
- *
- * Authors: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
- *          Achin Gupta           <achin.gupta@arm.com>
- *          Lorenzo Pieralisi     <lorenzo.pieralisi@arm.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.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/clk-provider.h>
-#include <linux/clkdev.h>
-#include <linux/cpu.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/pm_opp.h>
-#include <linux/slab.h>
-#include <linux/semaphore.h>
-
-#include <asm/cacheflush.h>
-
-#include "spc.h"
-
-#define SPCLOG "vexpress-spc: "
-
-#define PERF_LVL_A15           0x00
-#define PERF_REQ_A15           0x04
-#define PERF_LVL_A7            0x08
-#define PERF_REQ_A7            0x0c
-#define COMMS                  0x10
-#define COMMS_REQ              0x14
-#define PWC_STATUS             0x18
-#define PWC_FLAG               0x1c
-
-/* SPC wake-up IRQs status and mask */
-#define WAKE_INT_MASK          0x24
-#define WAKE_INT_RAW           0x28
-#define WAKE_INT_STAT          0x2c
-/* SPC power down registers */
-#define A15_PWRDN_EN           0x30
-#define A7_PWRDN_EN            0x34
-/* SPC per-CPU mailboxes */
-#define A15_BX_ADDR0           0x68
-#define A7_BX_ADDR0            0x78
-
-/* SPC CPU/cluster reset statue */
-#define STANDBYWFI_STAT                0x3c
-#define STANDBYWFI_STAT_A15_CPU_MASK(cpu)      (1 << (cpu))
-#define STANDBYWFI_STAT_A7_CPU_MASK(cpu)       (1 << (3 + (cpu)))
-
-/* SPC system config interface registers */
-#define SYSCFG_WDATA           0x70
-#define SYSCFG_RDATA           0x74
-
-/* A15/A7 OPP virtual register base */
-#define A15_PERFVAL_BASE       0xC10
-#define A7_PERFVAL_BASE                0xC30
-
-/* Config interface control bits */
-#define SYSCFG_START           BIT(31)
-#define SYSCFG_SCC             (6 << 20)
-#define SYSCFG_STAT            (14 << 20)
-
-/* wake-up interrupt masks */
-#define GBL_WAKEUP_INT_MSK     (0x3 << 10)
-
-/* TC2 static dual-cluster configuration */
-#define MAX_CLUSTERS           2
-
-/*
- * Even though the SPC takes max 3-5 ms to complete any OPP/COMMS
- * operation, the operation could start just before jiffie is about
- * to be incremented. So setting timeout value of 20ms = 2jiffies@100Hz
- */
-#define TIMEOUT_US     20000
-
-#define MAX_OPPS       8
-#define CA15_DVFS      0
-#define CA7_DVFS       1
-#define SPC_SYS_CFG    2
-#define STAT_COMPLETE(type)    ((1 << 0) << (type << 2))
-#define STAT_ERR(type)         ((1 << 1) << (type << 2))
-#define RESPONSE_MASK(type)    (STAT_COMPLETE(type) | STAT_ERR(type))
-
-struct ve_spc_opp {
-       unsigned long freq;
-       unsigned long u_volt;
-};
-
-struct ve_spc_drvdata {
-       void __iomem *baseaddr;
-       /*
-        * A15s cluster identifier
-        * It corresponds to A15 processors MPIDR[15:8] bitfield
-        */
-       u32 a15_clusid;
-       uint32_t cur_rsp_mask;
-       uint32_t cur_rsp_stat;
-       struct semaphore sem;
-       struct completion done;
-       struct ve_spc_opp *opps[MAX_CLUSTERS];
-       int num_opps[MAX_CLUSTERS];
-};
-
-static struct ve_spc_drvdata *info;
-
-static inline bool cluster_is_a15(u32 cluster)
-{
-       return cluster == info->a15_clusid;
-}
-
-/**
- * ve_spc_global_wakeup_irq()
- *
- * Function to set/clear global wakeup IRQs. Not protected by locking since
- * it might be used in code paths where normal cacheable locks are not
- * working. Locking must be provided by the caller to ensure atomicity.
- *
- * @set: if true, global wake-up IRQs are set, if false they are cleared
- */
-void ve_spc_global_wakeup_irq(bool set)
-{
-       u32 reg;
-
-       reg = readl_relaxed(info->baseaddr + WAKE_INT_MASK);
-
-       if (set)
-               reg |= GBL_WAKEUP_INT_MSK;
-       else
-               reg &= ~GBL_WAKEUP_INT_MSK;
-
-       writel_relaxed(reg, info->baseaddr + WAKE_INT_MASK);
-}
-
-/**
- * ve_spc_cpu_wakeup_irq()
- *
- * Function to set/clear per-CPU wake-up IRQs. Not protected by locking since
- * it might be used in code paths where normal cacheable locks are not
- * working. Locking must be provided by the caller to ensure atomicity.
- *
- * @cluster: mpidr[15:8] bitfield describing cluster affinity level
- * @cpu: mpidr[7:0] bitfield describing cpu affinity level
- * @set: if true, wake-up IRQs are set, if false they are cleared
- */
-void ve_spc_cpu_wakeup_irq(u32 cluster, u32 cpu, bool set)
-{
-       u32 mask, reg;
-
-       if (cluster >= MAX_CLUSTERS)
-               return;
-
-       mask = BIT(cpu);
-
-       if (!cluster_is_a15(cluster))
-               mask <<= 4;
-
-       reg = readl_relaxed(info->baseaddr + WAKE_INT_MASK);
-
-       if (set)
-               reg |= mask;
-       else
-               reg &= ~mask;
-
-       writel_relaxed(reg, info->baseaddr + WAKE_INT_MASK);
-}
-
-/**
- * ve_spc_set_resume_addr() - set the jump address used for warm boot
- *
- * @cluster: mpidr[15:8] bitfield describing cluster affinity level
- * @cpu: mpidr[7:0] bitfield describing cpu affinity level
- * @addr: physical resume address
- */
-void ve_spc_set_resume_addr(u32 cluster, u32 cpu, u32 addr)
-{
-       void __iomem *baseaddr;
-
-       if (cluster >= MAX_CLUSTERS)
-               return;
-
-       if (cluster_is_a15(cluster))
-               baseaddr = info->baseaddr + A15_BX_ADDR0 + (cpu << 2);
-       else
-               baseaddr = info->baseaddr + A7_BX_ADDR0 + (cpu << 2);
-
-       writel_relaxed(addr, baseaddr);
-}
-
-/**
- * ve_spc_powerdown()
- *
- * Function to enable/disable cluster powerdown. Not protected by locking
- * since it might be used in code paths where normal cacheable locks are not
- * working. Locking must be provided by the caller to ensure atomicity.
- *
- * @cluster: mpidr[15:8] bitfield describing cluster affinity level
- * @enable: if true enables powerdown, if false disables it
- */
-void ve_spc_powerdown(u32 cluster, bool enable)
-{
-       u32 pwdrn_reg;
-
-       if (cluster >= MAX_CLUSTERS)
-               return;
-
-       pwdrn_reg = cluster_is_a15(cluster) ? A15_PWRDN_EN : A7_PWRDN_EN;
-       writel_relaxed(enable, info->baseaddr + pwdrn_reg);
-}
-
-static u32 standbywfi_cpu_mask(u32 cpu, u32 cluster)
-{
-       return cluster_is_a15(cluster) ?
-                 STANDBYWFI_STAT_A15_CPU_MASK(cpu)
-               : STANDBYWFI_STAT_A7_CPU_MASK(cpu);
-}
-
-/**
- * ve_spc_cpu_in_wfi(u32 cpu, u32 cluster)
- *
- * @cpu: mpidr[7:0] bitfield describing CPU affinity level within cluster
- * @cluster: mpidr[15:8] bitfield describing cluster affinity level
- *
- * @return: non-zero if and only if the specified CPU is in WFI
- *
- * Take care when interpreting the result of this function: a CPU might
- * be in WFI temporarily due to idle, and is not necessarily safely
- * parked.
- */
-int ve_spc_cpu_in_wfi(u32 cpu, u32 cluster)
-{
-       int ret;
-       u32 mask = standbywfi_cpu_mask(cpu, cluster);
-
-       if (cluster >= MAX_CLUSTERS)
-               return 1;
-
-       ret = readl_relaxed(info->baseaddr + STANDBYWFI_STAT);
-
-       pr_debug("%s: PCFGREG[0x%X] = 0x%08X, mask = 0x%X\n",
-                __func__, STANDBYWFI_STAT, ret, mask);
-
-       return ret & mask;
-}
-
-static int ve_spc_get_performance(int cluster, u32 *freq)
-{
-       struct ve_spc_opp *opps = info->opps[cluster];
-       u32 perf_cfg_reg = 0;
-       u32 perf;
-
-       perf_cfg_reg = cluster_is_a15(cluster) ? PERF_LVL_A15 : PERF_LVL_A7;
-
-       perf = readl_relaxed(info->baseaddr + perf_cfg_reg);
-       if (perf >= info->num_opps[cluster])
-               return -EINVAL;
-
-       opps += perf;
-       *freq = opps->freq;
-
-       return 0;
-}
-
-/* find closest match to given frequency in OPP table */
-static int ve_spc_round_performance(int cluster, u32 freq)
-{
-       int idx, max_opp = info->num_opps[cluster];
-       struct ve_spc_opp *opps = info->opps[cluster];
-       u32 fmin = 0, fmax = ~0, ftmp;
-
-       freq /= 1000; /* OPP entries in kHz */
-       for (idx = 0; idx < max_opp; idx++, opps++) {
-               ftmp = opps->freq;
-               if (ftmp >= freq) {
-                       if (ftmp <= fmax)
-                               fmax = ftmp;
-               } else {
-                       if (ftmp >= fmin)
-                               fmin = ftmp;
-               }
-       }
-       if (fmax != ~0)
-               return fmax * 1000;
-       else
-               return fmin * 1000;
-}
-
-static int ve_spc_find_performance_index(int cluster, u32 freq)
-{
-       int idx, max_opp = info->num_opps[cluster];
-       struct ve_spc_opp *opps = info->opps[cluster];
-
-       for (idx = 0; idx < max_opp; idx++, opps++)
-               if (opps->freq == freq)
-                       break;
-       return (idx == max_opp) ? -EINVAL : idx;
-}
-
-static int ve_spc_waitforcompletion(int req_type)
-{
-       int ret = wait_for_completion_interruptible_timeout(
-                       &info->done, usecs_to_jiffies(TIMEOUT_US));
-       if (ret == 0)
-               ret = -ETIMEDOUT;
-       else if (ret > 0)
-               ret = info->cur_rsp_stat & STAT_COMPLETE(req_type) ? 0 : -EIO;
-       return ret;
-}
-
-static int ve_spc_set_performance(int cluster, u32 freq)
-{
-       u32 perf_cfg_reg;
-       int ret, perf, req_type;
-
-       if (cluster_is_a15(cluster)) {
-               req_type = CA15_DVFS;
-               perf_cfg_reg = PERF_LVL_A15;
-       } else {
-               req_type = CA7_DVFS;
-               perf_cfg_reg = PERF_LVL_A7;
-       }
-
-       perf = ve_spc_find_performance_index(cluster, freq);
-
-       if (perf < 0)
-               return perf;
-
-       if (down_timeout(&info->sem, usecs_to_jiffies(TIMEOUT_US)))
-               return -ETIME;
-
-       init_completion(&info->done);
-       info->cur_rsp_mask = RESPONSE_MASK(req_type);
-
-       writel(perf, info->baseaddr + perf_cfg_reg);
-       ret = ve_spc_waitforcompletion(req_type);
-
-       info->cur_rsp_mask = 0;
-       up(&info->sem);
-
-       return ret;
-}
-
-static int ve_spc_read_sys_cfg(int func, int offset, uint32_t *data)
-{
-       int ret;
-
-       if (down_timeout(&info->sem, usecs_to_jiffies(TIMEOUT_US)))
-               return -ETIME;
-
-       init_completion(&info->done);
-       info->cur_rsp_mask = RESPONSE_MASK(SPC_SYS_CFG);
-
-       /* Set the control value */
-       writel(SYSCFG_START | func | offset >> 2, info->baseaddr + COMMS);
-       ret = ve_spc_waitforcompletion(SPC_SYS_CFG);
-
-       if (ret == 0)
-               *data = readl(info->baseaddr + SYSCFG_RDATA);
-
-       info->cur_rsp_mask = 0;
-       up(&info->sem);
-
-       return ret;
-}
-
-static irqreturn_t ve_spc_irq_handler(int irq, void *data)
-{
-       struct ve_spc_drvdata *drv_data = data;
-       uint32_t status = readl_relaxed(drv_data->baseaddr + PWC_STATUS);
-
-       if (info->cur_rsp_mask & status) {
-               info->cur_rsp_stat = status;
-               complete(&drv_data->done);
-       }
-
-       return IRQ_HANDLED;
-}
-
-/*
- *  +--------------------------+
- *  | 31      20 | 19        0 |
- *  +--------------------------+
- *  |   m_volt   |  freq(kHz)  |
- *  +--------------------------+
- */
-#define MULT_FACTOR    20
-#define VOLT_SHIFT     20
-#define FREQ_MASK      (0xFFFFF)
-static int ve_spc_populate_opps(uint32_t cluster)
-{
-       uint32_t data = 0, off, ret, idx;
-       struct ve_spc_opp *opps;
-
-       opps = kcalloc(MAX_OPPS, sizeof(*opps), GFP_KERNEL);
-       if (!opps)
-               return -ENOMEM;
-
-       info->opps[cluster] = opps;
-
-       off = cluster_is_a15(cluster) ? A15_PERFVAL_BASE : A7_PERFVAL_BASE;
-       for (idx = 0; idx < MAX_OPPS; idx++, off += 4, opps++) {
-               ret = ve_spc_read_sys_cfg(SYSCFG_SCC, off, &data);
-               if (!ret) {
-                       opps->freq = (data & FREQ_MASK) * MULT_FACTOR;
-                       opps->u_volt = (data >> VOLT_SHIFT) * 1000;
-               } else {
-                       break;
-               }
-       }
-       info->num_opps[cluster] = idx;
-
-       return ret;
-}
-
-static int ve_init_opp_table(struct device *cpu_dev)
-{
-       int cluster;
-       int idx, ret = 0, max_opp;
-       struct ve_spc_opp *opps;
-
-       cluster = topology_physical_package_id(cpu_dev->id);
-       cluster = cluster < 0 ? 0 : cluster;
-
-       max_opp = info->num_opps[cluster];
-       opps = info->opps[cluster];
-
-       for (idx = 0; idx < max_opp; idx++, opps++) {
-               ret = dev_pm_opp_add(cpu_dev, opps->freq * 1000, opps->u_volt);
-               if (ret) {
-                       dev_warn(cpu_dev, "failed to add opp %lu %lu\n",
-                                opps->freq, opps->u_volt);
-                       return ret;
-               }
-       }
-       return ret;
-}
-
-int __init ve_spc_init(void __iomem *baseaddr, u32 a15_clusid, int irq)
-{
-       int ret;
-       info = kzalloc(sizeof(*info), GFP_KERNEL);
-       if (!info)
-               return -ENOMEM;
-
-       info->baseaddr = baseaddr;
-       info->a15_clusid = a15_clusid;
-
-       if (irq <= 0) {
-               pr_err(SPCLOG "Invalid IRQ %d\n", irq);
-               kfree(info);
-               return -EINVAL;
-       }
-
-       init_completion(&info->done);
-
-       readl_relaxed(info->baseaddr + PWC_STATUS);
-
-       ret = request_irq(irq, ve_spc_irq_handler, IRQF_TRIGGER_HIGH
-                               | IRQF_ONESHOT, "vexpress-spc", info);
-       if (ret) {
-               pr_err(SPCLOG "IRQ %d request failed\n", irq);
-               kfree(info);
-               return -ENODEV;
-       }
-
-       sema_init(&info->sem, 1);
-       /*
-        * Multi-cluster systems may need this data when non-coherent, during
-        * cluster power-up/power-down. Make sure driver info reaches main
-        * memory.
-        */
-       sync_cache_w(info);
-       sync_cache_w(&info);
-
-       return 0;
-}
-
-struct clk_spc {
-       struct clk_hw hw;
-       int cluster;
-};
-
-#define to_clk_spc(spc) container_of(spc, struct clk_spc, hw)
-static unsigned long spc_recalc_rate(struct clk_hw *hw,
-               unsigned long parent_rate)
-{
-       struct clk_spc *spc = to_clk_spc(hw);
-       u32 freq;
-
-       if (ve_spc_get_performance(spc->cluster, &freq))
-               return -EIO;
-
-       return freq * 1000;
-}
-
-static long spc_round_rate(struct clk_hw *hw, unsigned long drate,
-               unsigned long *parent_rate)
-{
-       struct clk_spc *spc = to_clk_spc(hw);
-
-       return ve_spc_round_performance(spc->cluster, drate);
-}
-
-static int spc_set_rate(struct clk_hw *hw, unsigned long rate,
-               unsigned long parent_rate)
-{
-       struct clk_spc *spc = to_clk_spc(hw);
-
-       return ve_spc_set_performance(spc->cluster, rate / 1000);
-}
-
-static struct clk_ops clk_spc_ops = {
-       .recalc_rate = spc_recalc_rate,
-       .round_rate = spc_round_rate,
-       .set_rate = spc_set_rate,
-};
-
-static struct clk *ve_spc_clk_register(struct device *cpu_dev)
-{
-       struct clk_init_data init;
-       struct clk_spc *spc;
-
-       spc = kzalloc(sizeof(*spc), GFP_KERNEL);
-       if (!spc)
-               return ERR_PTR(-ENOMEM);
-
-       spc->hw.init = &init;
-       spc->cluster = topology_physical_package_id(cpu_dev->id);
-
-       spc->cluster = spc->cluster < 0 ? 0 : spc->cluster;
-
-       init.name = dev_name(cpu_dev);
-       init.ops = &clk_spc_ops;
-       init.flags = CLK_GET_RATE_NOCACHE;
-       init.num_parents = 0;
-
-       return devm_clk_register(cpu_dev, &spc->hw);
-}
-
-static int __init ve_spc_clk_init(void)
-{
-       int cpu, cluster;
-       struct clk *clk;
-       bool init_opp_table[MAX_CLUSTERS] = { false };
-
-       if (!info)
-               return 0; /* Continue only if SPC is initialised */
-
-       if (ve_spc_populate_opps(0) || ve_spc_populate_opps(1)) {
-               pr_err("failed to build OPP table\n");
-               return -ENODEV;
-       }
-
-       for_each_possible_cpu(cpu) {
-               struct device *cpu_dev = get_cpu_device(cpu);
-               if (!cpu_dev) {
-                       pr_warn("failed to get cpu%d device\n", cpu);
-                       continue;
-               }
-               clk = ve_spc_clk_register(cpu_dev);
-               if (IS_ERR(clk)) {
-                       pr_warn("failed to register cpu%d clock\n", cpu);
-                       continue;
-               }
-               if (clk_register_clkdev(clk, NULL, dev_name(cpu_dev))) {
-                       pr_warn("failed to register cpu%d clock lookup\n", cpu);
-                       continue;
-               }
-
-               cluster = topology_physical_package_id(cpu_dev->id);
-               if (init_opp_table[cluster])
-                       continue;
-
-               if (ve_init_opp_table(cpu_dev))
-                       pr_warn("failed to initialise cpu%d opp table\n", cpu);
-               else if (dev_pm_opp_set_sharing_cpus(cpu_dev,
-                        topology_core_cpumask(cpu_dev->id)))
-                       pr_warn("failed to mark OPPs shared for cpu%d\n", cpu);
-               else
-                       init_opp_table[cluster] = true;
-       }
-
-       platform_device_register_simple("vexpress-spc-cpufreq", -1, NULL, 0);
-       return 0;
-}
-device_initcall(ve_spc_clk_init);
diff --git a/arch/arm/mach-vexpress/spc.h b/arch/arm/mach-vexpress/spc.h
deleted file mode 100644 (file)
index 288569f..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- *
- * Copyright (C) 2012 ARM Limited
- */
-
-
-#ifndef __SPC_H_
-#define __SPC_H_
-
-int __init ve_spc_init(void __iomem *base, u32 a15_clusid, int irq);
-void ve_spc_global_wakeup_irq(bool set);
-void ve_spc_cpu_wakeup_irq(u32 cluster, u32 cpu, bool set);
-void ve_spc_set_resume_addr(u32 cluster, u32 cpu, u32 addr);
-void ve_spc_powerdown(u32 cluster, bool enable);
-int ve_spc_cpu_in_wfi(u32 cpu, u32 cluster);
-
-#endif
diff --git a/arch/arm/mach-vexpress/tc2_pm.c b/arch/arm/mach-vexpress/tc2_pm.c
deleted file mode 100644 (file)
index e96c42a..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * arch/arm/mach-vexpress/tc2_pm.c - TC2 power management support
- *
- * Created by: Nicolas Pitre, October 2012
- * Copyright:  (C) 2012-2013  Linaro Limited
- *
- * Some portions of this file were originally written by Achin Gupta
- * Copyright:   (C) 2012  ARM Limited
- */
-
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
-#include <linux/errno.h>
-#include <linux/irqchip/arm-gic.h>
-
-#include <asm/mcpm.h>
-#include <asm/proc-fns.h>
-#include <asm/cacheflush.h>
-#include <asm/cputype.h>
-#include <asm/cp15.h>
-
-#include <linux/arm-cci.h>
-
-#include "spc.h"
-
-/* SCC conf registers */
-#define RESET_CTRL             0x018
-#define RESET_A15_NCORERESET(cpu)      (1 << (2 + (cpu)))
-#define RESET_A7_NCORERESET(cpu)       (1 << (16 + (cpu)))
-
-#define A15_CONF               0x400
-#define A7_CONF                        0x500
-#define SYS_INFO               0x700
-#define SPC_BASE               0xb00
-
-static void __iomem *scc;
-
-#define TC2_CLUSTERS                   2
-#define TC2_MAX_CPUS_PER_CLUSTER       3
-
-static unsigned int tc2_nr_cpus[TC2_CLUSTERS];
-
-static int tc2_pm_cpu_powerup(unsigned int cpu, unsigned int cluster)
-{
-       pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
-       if (cluster >= TC2_CLUSTERS || cpu >= tc2_nr_cpus[cluster])
-               return -EINVAL;
-       ve_spc_set_resume_addr(cluster, cpu,
-                              __pa_symbol(mcpm_entry_point));
-       ve_spc_cpu_wakeup_irq(cluster, cpu, true);
-       return 0;
-}
-
-static int tc2_pm_cluster_powerup(unsigned int cluster)
-{
-       pr_debug("%s: cluster %u\n", __func__, cluster);
-       if (cluster >= TC2_CLUSTERS)
-               return -EINVAL;
-       ve_spc_powerdown(cluster, false);
-       return 0;
-}
-
-static void tc2_pm_cpu_powerdown_prepare(unsigned int cpu, unsigned int cluster)
-{
-       pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
-       BUG_ON(cluster >= TC2_CLUSTERS || cpu >= TC2_MAX_CPUS_PER_CLUSTER);
-       ve_spc_cpu_wakeup_irq(cluster, cpu, true);
-       /*
-        * If the CPU is committed to power down, make sure
-        * the power controller will be in charge of waking it
-        * up upon IRQ, ie IRQ lines are cut from GIC CPU IF
-        * to the CPU by disabling the GIC CPU IF to prevent wfi
-        * from completing execution behind power controller back
-        */
-       gic_cpu_if_down(0);
-}
-
-static void tc2_pm_cluster_powerdown_prepare(unsigned int cluster)
-{
-       pr_debug("%s: cluster %u\n", __func__, cluster);
-       BUG_ON(cluster >= TC2_CLUSTERS);
-       ve_spc_powerdown(cluster, true);
-       ve_spc_global_wakeup_irq(true);
-}
-
-static void tc2_pm_cpu_cache_disable(void)
-{
-       v7_exit_coherency_flush(louis);
-}
-
-static void tc2_pm_cluster_cache_disable(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\t"
-               "isb    \n\t"
-               "dsb    "
-               : : "r" (0x400) );
-       }
-
-       v7_exit_coherency_flush(all);
-       cci_disable_port_by_cpu(read_cpuid_mpidr());
-}
-
-static int tc2_core_in_reset(unsigned int cpu, unsigned int cluster)
-{
-       u32 mask = cluster ?
-                 RESET_A7_NCORERESET(cpu)
-               : RESET_A15_NCORERESET(cpu);
-
-       return !(readl_relaxed(scc + RESET_CTRL) & mask);
-}
-
-#define POLL_MSEC 10
-#define TIMEOUT_MSEC 1000
-
-static int tc2_pm_wait_for_powerdown(unsigned int cpu, unsigned int cluster)
-{
-       unsigned tries;
-
-       pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
-       BUG_ON(cluster >= TC2_CLUSTERS || cpu >= TC2_MAX_CPUS_PER_CLUSTER);
-
-       for (tries = 0; tries < TIMEOUT_MSEC / POLL_MSEC; ++tries) {
-               pr_debug("%s(cpu=%u, cluster=%u): RESET_CTRL = 0x%08X\n",
-                        __func__, cpu, cluster,
-                        readl_relaxed(scc + RESET_CTRL));
-
-               /*
-                * We need the CPU to reach WFI, but the power
-                * controller may put the cluster in reset and
-                * power it off as soon as that happens, before
-                * we have a chance to see STANDBYWFI.
-                *
-                * So we need to check for both conditions:
-                */
-               if (tc2_core_in_reset(cpu, cluster) ||
-                   ve_spc_cpu_in_wfi(cpu, cluster))
-                       return 0; /* success: the CPU is halted */
-
-               /* Otherwise, wait and retry: */
-               msleep(POLL_MSEC);
-       }
-
-       return -ETIMEDOUT; /* timeout */
-}
-
-static void tc2_pm_cpu_suspend_prepare(unsigned int cpu, unsigned int cluster)
-{
-       ve_spc_set_resume_addr(cluster, cpu, __pa_symbol(mcpm_entry_point));
-}
-
-static void tc2_pm_cpu_is_up(unsigned int cpu, unsigned int cluster)
-{
-       pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
-       BUG_ON(cluster >= TC2_CLUSTERS || cpu >= TC2_MAX_CPUS_PER_CLUSTER);
-       ve_spc_cpu_wakeup_irq(cluster, cpu, false);
-       ve_spc_set_resume_addr(cluster, cpu, 0);
-}
-
-static void tc2_pm_cluster_is_up(unsigned int cluster)
-{
-       pr_debug("%s: cluster %u\n", __func__, cluster);
-       BUG_ON(cluster >= TC2_CLUSTERS);
-       ve_spc_powerdown(cluster, false);
-       ve_spc_global_wakeup_irq(false);
-}
-
-static const struct mcpm_platform_ops tc2_pm_power_ops = {
-       .cpu_powerup            = tc2_pm_cpu_powerup,
-       .cluster_powerup        = tc2_pm_cluster_powerup,
-       .cpu_suspend_prepare    = tc2_pm_cpu_suspend_prepare,
-       .cpu_powerdown_prepare  = tc2_pm_cpu_powerdown_prepare,
-       .cluster_powerdown_prepare = tc2_pm_cluster_powerdown_prepare,
-       .cpu_cache_disable      = tc2_pm_cpu_cache_disable,
-       .cluster_cache_disable  = tc2_pm_cluster_cache_disable,
-       .wait_for_powerdown     = tc2_pm_wait_for_powerdown,
-       .cpu_is_up              = tc2_pm_cpu_is_up,
-       .cluster_is_up          = tc2_pm_cluster_is_up,
-};
-
-/*
- * Enable cluster-level coherency, in preparation for turning on the MMU.
- */
-static void __naked tc2_pm_power_up_setup(unsigned int affinity_level)
-{
-       asm volatile (" \n"
-"      cmp     r0, #1 \n"
-"      bxne    lr \n"
-"      b       cci_enable_port_for_self ");
-}
-
-static int __init tc2_pm_init(void)
-{
-       unsigned int mpidr, cpu, cluster;
-       int ret, irq;
-       u32 a15_cluster_id, a7_cluster_id, sys_info;
-       struct device_node *np;
-
-       /*
-        * The power management-related features are hidden behind
-        * SCC registers. We need to extract runtime information like
-        * cluster ids and number of CPUs really available in clusters.
-        */
-       np = of_find_compatible_node(NULL, NULL,
-                       "arm,vexpress-scc,v2p-ca15_a7");
-       scc = of_iomap(np, 0);
-       if (!scc)
-               return -ENODEV;
-
-       a15_cluster_id = readl_relaxed(scc + A15_CONF) & 0xf;
-       a7_cluster_id = readl_relaxed(scc + A7_CONF) & 0xf;
-       if (a15_cluster_id >= TC2_CLUSTERS || a7_cluster_id >= TC2_CLUSTERS)
-               return -EINVAL;
-
-       sys_info = readl_relaxed(scc + SYS_INFO);
-       tc2_nr_cpus[a15_cluster_id] = (sys_info >> 16) & 0xf;
-       tc2_nr_cpus[a7_cluster_id] = (sys_info >> 20) & 0xf;
-
-       irq = irq_of_parse_and_map(np, 0);
-
-       /*
-        * A subset of the SCC registers is also used to communicate
-        * with the SPC (power controller). We need to be able to
-        * drive it very early in the boot process to power up
-        * processors, so we initialize the SPC driver here.
-        */
-       ret = ve_spc_init(scc + SPC_BASE, a15_cluster_id, irq);
-       if (ret)
-               return ret;
-
-       if (!cci_probed())
-               return -ENODEV;
-
-       mpidr = read_cpuid_mpidr();
-       cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0);
-       cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1);
-       pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster);
-       if (cluster >= TC2_CLUSTERS || cpu >= tc2_nr_cpus[cluster]) {
-               pr_err("%s: boot CPU is out of bound!\n", __func__);
-               return -EINVAL;
-       }
-
-       ret = mcpm_platform_register(&tc2_pm_power_ops);
-       if (!ret) {
-               mcpm_sync_init(tc2_pm_power_up_setup);
-               /* test if we can (re)enable the CCI on our own */
-               BUG_ON(mcpm_loopback(tc2_pm_cluster_cache_disable) != 0);
-               pr_info("TC2 power management initialized\n");
-       }
-       return ret;
-}
-
-early_initcall(tc2_pm_init);
diff --git a/arch/arm/mach-vexpress/v2m-mps2.c b/arch/arm/mach-vexpress/v2m-mps2.c
deleted file mode 100644 (file)
index 5b50d8e..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2015 ARM Limited
- *
- * Author: Vladimir Murzin <vladimir.murzin@arm.com>
- */
-
-#include <asm/mach/arch.h>
-
-static const char *const mps2_compat[] __initconst = {
-       "arm,mps2",
-       NULL
-};
-
-DT_MACHINE_START(MPS2DT, "MPS2 (Device Tree Support)")
-       .dt_compat = mps2_compat,
-MACHINE_END
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
deleted file mode 100644 (file)
index ffe7c7a..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <asm/mach/arch.h>
-
-#include "core.h"
-
-#define SYS_FLAGSSET           0x030
-#define SYS_FLAGSCLR           0x034
-
-void vexpress_flags_set(u32 data)
-{
-       static void __iomem *base;
-
-       if (!base) {
-               struct device_node *node = of_find_compatible_node(NULL, NULL,
-                               "arm,vexpress-sysreg");
-
-               base = of_iomap(node, 0);
-       }
-
-       if (WARN_ON(!base))
-               return;
-
-       writel(~0, base + SYS_FLAGSCLR);
-       writel(data, base + SYS_FLAGSSET);
-}
-
-static const char * const v2m_dt_match[] __initconst = {
-       "arm,vexpress",
-       NULL,
-};
-
-DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express")
-       .dt_compat      = v2m_dt_match,
-       .l2c_aux_val    = 0x00400000,
-       .l2c_aux_mask   = 0xfe0fffff,
-       .smp            = smp_ops(vexpress_smp_dt_ops),
-       .smp_init       = smp_init_ops(vexpress_smp_init_ops),
-MACHINE_END
diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile
deleted file mode 100644 (file)
index 5de44a5..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
-
-obj-$(CONFIG_SMP) += headsmp.o platsmp.o
-obj-$(CONFIG_HOTPLUG_CPU)              += hotplug.o
diff --git a/arch/arm/plat-versatile/headsmp.S b/arch/arm/plat-versatile/headsmp.S
deleted file mode 100644 (file)
index 09d9fc3..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- *  linux/arch/arm/plat-versatile/headsmp.S
- *
- *  Copyright (c) 2003 ARM Limited
- *  All Rights Reserved
- */
-#include <linux/linkage.h>
-#include <linux/init.h>
-#include <asm/assembler.h>
-
-/*
- * Realview/Versatile Express specific entry point for secondary CPUs.
- * This provides a "holding pen" into which all secondary cores are held
- * until we're ready for them to initialise.
- */
-ENTRY(versatile_secondary_startup)
- ARM_BE8(setend        be)
-       mrc     p15, 0, r0, c0, c0, 5
-       bic     r0, #0xff000000
-       adr     r4, 1f
-       ldmia   r4, {r5, r6}
-       sub     r4, r4, r5
-       add     r6, r6, r4
-pen:   ldr     r7, [r6]
-       cmp     r7, r0
-       bne     pen
-
-       /*
-        * we've been released from the holding pen: secondary_stack
-        * should now contain the SVC stack for this core
-        */
-       b       secondary_startup
-
-       .align
-1:     .long   .
-       .long   versatile_cpu_release
-ENDPROC(versatile_secondary_startup)
diff --git a/arch/arm/plat-versatile/hotplug.c b/arch/arm/plat-versatile/hotplug.c
deleted file mode 100644 (file)
index 2e9dca3..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *  Copyright (C) 2002 ARM Ltd.
- *  All Rights Reserved
- *
- * This hotplug implementation is _specific_ to the situation found on
- * ARM development platforms where there is _no_ possibility of actually
- * taking a CPU offline, resetting it, or otherwise.  Real platforms must
- * NOT copy this code.
- */
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/smp.h>
-
-#include <asm/smp_plat.h>
-#include <asm/cp15.h>
-
-#include <plat/platsmp.h>
-
-static inline void versatile_immitation_enter_lowpower(unsigned int actrl_mask)
-{
-       unsigned int v;
-
-       asm volatile(
-               "mcr    p15, 0, %1, c7, c5, 0\n"
-       "       mcr     p15, 0, %1, c7, c10, 4\n"
-       /*
-        * Turn off coherency
-        */
-       "       mrc     p15, 0, %0, c1, c0, 1\n"
-       "       bic     %0, %0, %3\n"
-       "       mcr     p15, 0, %0, c1, c0, 1\n"
-       "       mrc     p15, 0, %0, c1, c0, 0\n"
-       "       bic     %0, %0, %2\n"
-       "       mcr     p15, 0, %0, c1, c0, 0\n"
-         : "=&r" (v)
-         : "r" (0), "Ir" (CR_C), "Ir" (actrl_mask)
-         : "cc");
-}
-
-static inline void versatile_immitation_leave_lowpower(unsigned int actrl_mask)
-{
-       unsigned int v;
-
-       asm volatile(
-               "mrc    p15, 0, %0, c1, c0, 0\n"
-       "       orr     %0, %0, %1\n"
-       "       mcr     p15, 0, %0, c1, c0, 0\n"
-       "       mrc     p15, 0, %0, c1, c0, 1\n"
-       "       orr     %0, %0, %2\n"
-       "       mcr     p15, 0, %0, c1, c0, 1\n"
-         : "=&r" (v)
-         : "Ir" (CR_C), "Ir" (actrl_mask)
-         : "cc");
-}
-
-static inline void versatile_immitation_do_lowpower(unsigned int cpu, int *spurious)
-{
-       /*
-        * there is no power-control hardware on this platform, so all
-        * we can do is put the core into WFI; this is safe as the calling
-        * code will have already disabled interrupts.
-        *
-        * This code should not be used outside Versatile platforms.
-        */
-       for (;;) {
-               wfi();
-
-               if (versatile_cpu_release == cpu_logical_map(cpu)) {
-                       /*
-                        * OK, proper wakeup, we're done
-                        */
-                       break;
-               }
-
-               /*
-                * Getting here, means that we have come out of WFI without
-                * having been woken up - this shouldn't happen
-                *
-                * Just note it happening - when we're woken, we can report
-                * its occurrence.
-                */
-               (*spurious)++;
-       }
-}
-
-/*
- * platform-specific code to shutdown a CPU.
- * This code supports immitation-style CPU hotplug for Versatile/Realview/
- * Versatile Express platforms that are unable to do real CPU hotplug.
- */
-void versatile_immitation_cpu_die(unsigned int cpu, unsigned int actrl_mask)
-{
-       int spurious = 0;
-
-       versatile_immitation_enter_lowpower(actrl_mask);
-       versatile_immitation_do_lowpower(cpu, &spurious);
-       versatile_immitation_leave_lowpower(actrl_mask);
-
-       if (spurious)
-               pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
-}
diff --git a/arch/arm/plat-versatile/include/plat/platsmp.h b/arch/arm/plat-versatile/include/plat/platsmp.h
deleted file mode 100644 (file)
index 500605f..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- *  linux/arch/arm/plat-versatile/include/plat/platsmp.h
- *
- *  Copyright (C) 2011 ARM Ltd.
- *  All Rights Reserved
- */
-extern volatile int versatile_cpu_release;
-
-extern void versatile_secondary_startup(void);
-extern void versatile_secondary_init(unsigned int cpu);
-extern int  versatile_boot_secondary(unsigned int cpu, struct task_struct *idle);
-void versatile_immitation_cpu_die(unsigned int cpu, unsigned int actrl_mask);
diff --git a/arch/arm/plat-versatile/platsmp.c b/arch/arm/plat-versatile/platsmp.c
deleted file mode 100644 (file)
index 3567296..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *  linux/arch/arm/plat-versatile/platsmp.c
- *
- *  Copyright (C) 2002 ARM Ltd.
- *  All Rights Reserved
- *
- * This code is specific to the hardware found on ARM Realview and
- * Versatile Express platforms where the CPUs are unable to be individually
- * woken, and where there is no way to hot-unplug CPUs.  Real platforms
- * should not copy this code.
- */
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/jiffies.h>
-#include <linux/smp.h>
-
-#include <asm/cacheflush.h>
-#include <asm/smp_plat.h>
-
-#include <plat/platsmp.h>
-
-/*
- * versatile_cpu_release controls the release of CPUs from the holding
- * pen in headsmp.S, which exists because we are not always able to
- * control the release of individual CPUs from the board firmware.
- * Production platforms do not need this.
- */
-volatile int versatile_cpu_release = -1;
-
-/*
- * Write versatile_cpu_release in a way that is guaranteed to be visible to
- * all observers, irrespective of whether they're taking part in coherency
- * or not.  This is necessary for the hotplug code to work reliably.
- */
-static void versatile_write_cpu_release(int val)
-{
-       versatile_cpu_release = val;
-       smp_wmb();
-       sync_cache_w(&versatile_cpu_release);
-}
-
-/*
- * versatile_lock exists to avoid running the loops_per_jiffy delay loop
- * calibrations on the secondary CPU while the requesting CPU is using
- * the limited-bandwidth bus - which affects the calibration value.
- * Production platforms do not need this.
- */
-static DEFINE_RAW_SPINLOCK(versatile_lock);
-
-void versatile_secondary_init(unsigned int cpu)
-{
-       /*
-        * let the primary processor know we're out of the
-        * pen, then head off into the C entry point
-        */
-       versatile_write_cpu_release(-1);
-
-       /*
-        * Synchronise with the boot thread.
-        */
-       raw_spin_lock(&versatile_lock);
-       raw_spin_unlock(&versatile_lock);
-}
-
-int versatile_boot_secondary(unsigned int cpu, struct task_struct *idle)
-{
-       unsigned long timeout;
-
-       /*
-        * Set synchronisation state between this boot processor
-        * and the secondary one
-        */
-       raw_spin_lock(&versatile_lock);
-
-       /*
-        * This is really belt and braces; we hold unintended secondary
-        * CPUs in the holding pen until we're ready for them.  However,
-        * since we haven't sent them a soft interrupt, they shouldn't
-        * be there.
-        */
-       versatile_write_cpu_release(cpu_logical_map(cpu));
-
-       /*
-        * Send the secondary CPU a soft interrupt, thereby causing
-        * the boot monitor to read the system wide flags register,
-        * and branch to the address found there.
-        */
-       arch_send_wakeup_ipi_mask(cpumask_of(cpu));
-
-       timeout = jiffies + (1 * HZ);
-       while (time_before(jiffies, timeout)) {
-               smp_rmb();
-               if (versatile_cpu_release == -1)
-                       break;
-
-               udelay(10);
-       }
-
-       /*
-        * now the secondary core is starting up let it run its
-        * calibrations, then wait for it to finish
-        */
-       raw_spin_unlock(&versatile_lock);
-
-       return versatile_cpu_release != -1 ? -ENOSYS : 0;
-}