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

Configure Feed

Select the types of activity you want to include in your feed.

reset: socfpga: add an early reset driver for SoCFPGA

Create a separate reset driver that uses the reset operations in
reset-simple. The reset driver for the SoCFPGA platform needs to
register early in order to be able bring online timers that needed
early in the kernel bootup.

We do not need this early reset driver for Stratix10, because on
arm64, Linux does not need the timers are that in reset. Linux is
able to run just fine with the internal armv8 timer. Thus, we use
a new binding "altr,stratix10-rst-mgr" for the Stratix10 platform.
The Stratix10 platform will continue to use the reset-simple platform
driver, while the 32-bit platforms(Cyclone5/Arria5/Arria10) will use
the early reset driver.

Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
[p.zabel@pengutronix.de: fixed socfpga of_device_id in reset-simple]
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>

authored by

Dinh Nguyen and committed by
Philipp Zabel
b3ca9888 151f72f4

+105 -11
+4
arch/arm/mach-socfpga/socfpga.c
··· 32 32 void __iomem *sdr_ctl_base_addr; 33 33 unsigned long socfpga_cpu1start_addr; 34 34 35 + extern void __init socfpga_reset_init(void); 36 + 35 37 static void __init socfpga_sysmgr_init(void) 36 38 { 37 39 struct device_node *np; ··· 66 64 67 65 if (IS_ENABLED(CONFIG_EDAC_ALTERA_OCRAM)) 68 66 socfpga_init_ocram_ecc(); 67 + socfpga_reset_init(); 69 68 } 70 69 71 70 static void __init socfpga_arria10_init_irq(void) ··· 77 74 socfpga_init_arria10_l2_ecc(); 78 75 if (IS_ENABLED(CONFIG_EDAC_ALTERA_OCRAM)) 79 76 socfpga_init_arria10_ocram_ecc(); 77 + socfpga_reset_init(); 80 78 } 81 79 82 80 static void socfpga_cyclone5_restart(enum reboot_mode mode, const char *cmd)
+9 -1
drivers/reset/Kconfig
··· 109 109 110 110 config RESET_SIMPLE 111 111 bool "Simple Reset Controller Driver" if COMPILE_TEST 112 - default ARCH_SOCFPGA || ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX || ARCH_ASPEED 112 + default ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX || ARCH_ASPEED 113 113 help 114 114 This enables a simple reset controller driver for reset lines that 115 115 that can be asserted and deasserted by toggling bits in a contiguous, ··· 127 127 default MACH_STM32MP157 128 128 help 129 129 This enables the RCC reset controller driver for STM32 MPUs. 130 + 131 + config RESET_SOCFPGA 132 + bool "SoCFPGA Reset Driver" if COMPILE_TEST && !ARCH_SOCFPGA 133 + default ARCH_SOCFPGA 134 + select RESET_SIMPLE 135 + help 136 + This enables the reset driver for the SoCFPGA ARMv7 platforms. This 137 + driver gets initialized early during platform init calls. 130 138 131 139 config RESET_SUNXI 132 140 bool "Allwinner SoCs Reset Driver" if COMPILE_TEST && !ARCH_SUNXI
+1
drivers/reset/Makefile
··· 19 19 obj-$(CONFIG_RESET_QCOM_PDC) += reset-qcom-pdc.o 20 20 obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o 21 21 obj-$(CONFIG_RESET_STM32MP157) += reset-stm32mp1.o 22 + obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o 22 23 obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o 23 24 obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o 24 25 obj-$(CONFIG_RESET_TI_SYSCON) += reset-ti-syscon.o
+3 -10
drivers/reset/reset-simple.c
··· 109 109 #define SOCFPGA_NR_BANKS 8 110 110 111 111 static const struct reset_simple_devdata reset_simple_socfpga = { 112 - .reg_offset = 0x10, 112 + .reg_offset = 0x20, 113 113 .nr_resets = SOCFPGA_NR_BANKS * 32, 114 114 .status_active_low = true, 115 115 }; ··· 120 120 }; 121 121 122 122 static const struct of_device_id reset_simple_dt_ids[] = { 123 - { .compatible = "altr,rst-mgr", .data = &reset_simple_socfpga }, 123 + { .compatible = "altr,stratix10-rst-mgr", 124 + .data = &reset_simple_socfpga }, 124 125 { .compatible = "st,stm32-rcc", }, 125 126 { .compatible = "allwinner,sun6i-a31-clock-reset", 126 127 .data = &reset_simple_active_low }, ··· 165 164 data->rcdev.nr_resets = devdata->nr_resets; 166 165 data->active_low = devdata->active_low; 167 166 data->status_active_low = devdata->status_active_low; 168 - } 169 - 170 - if (of_device_is_compatible(dev->of_node, "altr,rst-mgr") && 171 - of_property_read_u32(dev->of_node, "altr,modrst-offset", 172 - &reg_offset)) { 173 - dev_warn(dev, 174 - "missing altr,modrst-offset property, assuming 0x%x!\n", 175 - reg_offset); 176 167 } 177 168 178 169 data->membase += reg_offset;
+88
drivers/reset/reset-socfpga.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2018, Intel Corporation 4 + * Copied from reset-sunxi.c 5 + */ 6 + 7 + #include <linux/err.h> 8 + #include <linux/io.h> 9 + #include <linux/init.h> 10 + #include <linux/of.h> 11 + #include <linux/of_address.h> 12 + #include <linux/platform_device.h> 13 + #include <linux/reset-controller.h> 14 + #include <linux/slab.h> 15 + #include <linux/spinlock.h> 16 + #include <linux/types.h> 17 + 18 + #include "reset-simple.h" 19 + 20 + #define SOCFPGA_NR_BANKS 8 21 + void __init socfpga_reset_init(void); 22 + 23 + static int a10_reset_init(struct device_node *np) 24 + { 25 + struct reset_simple_data *data; 26 + struct resource res; 27 + resource_size_t size; 28 + int ret; 29 + u32 reg_offset = 0x10; 30 + 31 + data = kzalloc(sizeof(*data), GFP_KERNEL); 32 + if (!data) 33 + return -ENOMEM; 34 + 35 + ret = of_address_to_resource(np, 0, &res); 36 + if (ret) 37 + goto err_alloc; 38 + 39 + size = resource_size(&res); 40 + if (!request_mem_region(res.start, size, np->name)) { 41 + ret = -EBUSY; 42 + goto err_alloc; 43 + } 44 + 45 + data->membase = ioremap(res.start, size); 46 + if (!data->membase) { 47 + ret = -ENOMEM; 48 + goto err_alloc; 49 + } 50 + 51 + if (of_property_read_u32(np, "altr,modrst-offset", &reg_offset)) 52 + pr_warn("missing altr,modrst-offset property, assuming 0x10\n"); 53 + data->membase += reg_offset; 54 + 55 + spin_lock_init(&data->lock); 56 + 57 + data->rcdev.owner = THIS_MODULE; 58 + data->rcdev.nr_resets = SOCFPGA_NR_BANKS * 32; 59 + data->rcdev.ops = &reset_simple_ops; 60 + data->rcdev.of_node = np; 61 + data->status_active_low = true; 62 + 63 + return reset_controller_register(&data->rcdev); 64 + 65 + err_alloc: 66 + kfree(data); 67 + return ret; 68 + }; 69 + 70 + /* 71 + * These are the reset controller we need to initialize early on in 72 + * our system, before we can even think of using a regular device 73 + * driver for it. 74 + * The controllers that we can register through the regular device 75 + * model are handled by the simple reset driver directly. 76 + */ 77 + static const struct of_device_id socfpga_early_reset_dt_ids[] __initconst = { 78 + { .compatible = "altr,rst-mgr", }, 79 + { /* sentinel */ }, 80 + }; 81 + 82 + void __init socfpga_reset_init(void) 83 + { 84 + struct device_node *np; 85 + 86 + for_each_matching_node(np, socfpga_early_reset_dt_ids) 87 + a10_reset_init(np); 88 + }