Skip to content

Commit b3ca988

Browse files
Dinh NguyenpH5
authored andcommitted
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>
1 parent 151f72f commit b3ca988

File tree

5 files changed

+105
-11
lines changed

5 files changed

+105
-11
lines changed

arch/arm/mach-socfpga/socfpga.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ void __iomem *rst_manager_base_addr;
3232
void __iomem *sdr_ctl_base_addr;
3333
unsigned long socfpga_cpu1start_addr;
3434

35+
extern void __init socfpga_reset_init(void);
36+
3537
static void __init socfpga_sysmgr_init(void)
3638
{
3739
struct device_node *np;
@@ -64,6 +66,7 @@ static void __init socfpga_init_irq(void)
6466

6567
if (IS_ENABLED(CONFIG_EDAC_ALTERA_OCRAM))
6668
socfpga_init_ocram_ecc();
69+
socfpga_reset_init();
6770
}
6871

6972
static void __init socfpga_arria10_init_irq(void)
@@ -74,6 +77,7 @@ static void __init socfpga_arria10_init_irq(void)
7477
socfpga_init_arria10_l2_ecc();
7578
if (IS_ENABLED(CONFIG_EDAC_ALTERA_OCRAM))
7679
socfpga_init_arria10_ocram_ecc();
80+
socfpga_reset_init();
7781
}
7882

7983
static void socfpga_cyclone5_restart(enum reboot_mode mode, const char *cmd)

drivers/reset/Kconfig

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ config RESET_QCOM_PDC
109109

110110
config RESET_SIMPLE
111111
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
113113
help
114114
This enables a simple reset controller driver for reset lines that
115115
that can be asserted and deasserted by toggling bits in a contiguous,
@@ -128,6 +128,14 @@ config RESET_STM32MP157
128128
help
129129
This enables the RCC reset controller driver for STM32 MPUs.
130130

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.
138+
131139
config RESET_SUNXI
132140
bool "Allwinner SoCs Reset Driver" if COMPILE_TEST && !ARCH_SUNXI
133141
default ARCH_SUNXI

drivers/reset/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ obj-$(CONFIG_RESET_QCOM_AOSS) += reset-qcom-aoss.o
1919
obj-$(CONFIG_RESET_QCOM_PDC) += reset-qcom-pdc.o
2020
obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
2121
obj-$(CONFIG_RESET_STM32MP157) += reset-stm32mp1.o
22+
obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
2223
obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
2324
obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
2425
obj-$(CONFIG_RESET_TI_SYSCON) += reset-ti-syscon.o

drivers/reset/reset-simple.c

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ struct reset_simple_devdata {
109109
#define SOCFPGA_NR_BANKS 8
110110

111111
static const struct reset_simple_devdata reset_simple_socfpga = {
112-
.reg_offset = 0x10,
112+
.reg_offset = 0x20,
113113
.nr_resets = SOCFPGA_NR_BANKS * 32,
114114
.status_active_low = true,
115115
};
@@ -120,7 +120,8 @@ static const struct reset_simple_devdata reset_simple_active_low = {
120120
};
121121

122122
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 },
124125
{ .compatible = "st,stm32-rcc", },
125126
{ .compatible = "allwinner,sun6i-a31-clock-reset",
126127
.data = &reset_simple_active_low },
@@ -166,14 +167,6 @@ static int reset_simple_probe(struct platform_device *pdev)
166167
data->status_active_low = devdata->status_active_low;
167168
}
168169

169-
if (of_device_is_compatible(dev->of_node, "altr,rst-mgr") &&
170-
of_property_read_u32(dev->of_node, "altr,modrst-offset",
171-
&reg_offset)) {
172-
dev_warn(dev,
173-
"missing altr,modrst-offset property, assuming 0x%x!\n",
174-
reg_offset);
175-
}
176-
177170
data->membase += reg_offset;
178171

179172
return devm_reset_controller_register(dev, &data->rcdev);

drivers/reset/reset-socfpga.c

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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+
}

0 commit comments

Comments
 (0)