diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-05-26 10:43:09 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-05-26 10:43:09 -0700 |
commit | ecf0aa5317b0ad6bb015128a5b763c954fd58708 (patch) | |
tree | 2bf6f0eb2ad2922bc644b72be2a75ac0df6e4403 /arch/arm/mach-versatile/integrator_cp.c | |
parent | a0439cf4eca05fe562f19ece4b6761852d911adb (diff) | |
parent | 1a23accae82d780b5d5de6254d32c270aeb7f664 (diff) | |
download | linux-stable-ecf0aa5317b0ad6bb015128a5b763c954fd58708.tar.gz |
Merge tag 'arm-multiplatform-5.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
Pull ARMv4T/v5 multiplatform support from Arnd Bergmann:
"This series has been 12 years in the making, it mostly finishes the
work that was started with the founding of Linaro to clean up platform
support in the kernel.
The largest change here is a cleanup of the omap1 platform, which is
the final ARM machine type to get converted to the common-clk
subsystem. All the omap1 specific drivers are now made independent of
the mach/*.h headers to allow the platform to be part of a generic
ARMv4/v5 multiplatform kernel.
The last bit that enables this support is still missing here while we
wait for some last dependencies to make it into the mainline kernel
through other subsystems.
The s3c24xx, ixp4xx, iop32x, ep93xx and dove platforms were all almost
at the point of allowing multiplatform kernels, this work gets
completed here along with a few additional cleanup. At the same time,
the s3c24xx and s3c64xx are now deprecated and expected to get removed
in the future.
The PXA and OMAP1 bits are in a separate branch because of
dependencies. Once both branches are merged, only the three Intel
StrongARM platforms (RiscPC, Footbridge/NetWinder and StrongARM1100)
need separate kernels, and there are no plans to include these"
* tag 'arm-multiplatform-5.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc: (61 commits)
ARM: ixp4xx: Consolidate Kconfig fixing issue
ARM: versatile: Add missing of_node_put in dcscb_init
ARM: config: Refresh IXP4xx config after multiplatform
ARM: omap1: add back omap_set_dma_priority() stub
ARM: omap: fix missing declaration warnings
ARM: omap: fix address space warnings from sparse
ARM: spear: remove include/mach/ subdirectory
ARM: davinci: remove include/mach/ subdirectory
ARM: omap2: remove include/mach/ subdirectory
integrator: remove empty ap_init_early()
ARM: s3c: fix include path
MAINTAINERS: omap1: Add Janusz as an additional maintainer
ARM: omap1: htc_herald: fix typos in comments
ARM: OMAP1: fix typos in comments
ARM: OMAP1: clock: Remove noop code
ARM: OMAP1: clock: Remove unused code
ARM: OMAP1: clock: Fix UART rate reporting algorithm
ARM: OMAP1: clock: Fix early UART rate issues
ARM: OMAP1: Prepare for conversion of OMAP1 clocks to CCF
ARM: omap1: fix build with no SoC selected
...
Diffstat (limited to 'arch/arm/mach-versatile/integrator_cp.c')
-rw-r--r-- | arch/arm/mach-versatile/integrator_cp.c | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/arch/arm/mach-versatile/integrator_cp.c b/arch/arm/mach-versatile/integrator_cp.c new file mode 100644 index 000000000000..2ed4ded56b3f --- /dev/null +++ b/arch/arm/mach-versatile/integrator_cp.c @@ -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 |