aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/reset
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/reset')
-rw-r--r--drivers/reset/Kconfig20
-rw-r--r--drivers/reset/Makefile3
-rw-r--r--drivers/reset/core.c42
-rw-r--r--drivers/reset/reset-hsdk.c1
-rw-r--r--drivers/reset/reset-simple.c13
-rw-r--r--drivers/reset/reset-socfpga.c88
-rw-r--r--drivers/reset/reset-uniphier-glue.c (renamed from drivers/reset/reset-uniphier-usb3.c)50
7 files changed, 181 insertions, 36 deletions
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index c21da9fe51ec..2e01bd833ffd 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -109,7 +109,7 @@ config RESET_QCOM_PDC
109 109
110config RESET_SIMPLE 110config RESET_SIMPLE
111 bool "Simple Reset Controller Driver" if COMPILE_TEST 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 help 113 help
114 This enables a simple reset controller driver for reset lines that 114 This enables a simple reset controller driver for reset lines that
115 that can be asserted and deasserted by toggling bits in a contiguous, 115 that can be asserted and deasserted by toggling bits in a contiguous,
@@ -128,6 +128,14 @@ config RESET_STM32MP157
128 help 128 help
129 This enables the RCC reset controller driver for STM32 MPUs. 129 This enables the RCC reset controller driver for STM32 MPUs.
130 130
131config 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
131config RESET_SUNXI 139config RESET_SUNXI
132 bool "Allwinner SoCs Reset Driver" if COMPILE_TEST && !ARCH_SUNXI 140 bool "Allwinner SoCs Reset Driver" if COMPILE_TEST && !ARCH_SUNXI
133 default ARCH_SUNXI 141 default ARCH_SUNXI
@@ -163,15 +171,15 @@ config RESET_UNIPHIER
163 Say Y if you want to control reset signals provided by System Control 171 Say Y if you want to control reset signals provided by System Control
164 block, Media I/O block, Peripheral Block. 172 block, Media I/O block, Peripheral Block.
165 173
166config RESET_UNIPHIER_USB3 174config RESET_UNIPHIER_GLUE
167 tristate "USB3 reset driver for UniPhier SoCs" 175 tristate "Reset driver in glue layer for UniPhier SoCs"
168 depends on (ARCH_UNIPHIER || COMPILE_TEST) && OF 176 depends on (ARCH_UNIPHIER || COMPILE_TEST) && OF
169 default ARCH_UNIPHIER 177 default ARCH_UNIPHIER
170 select RESET_SIMPLE 178 select RESET_SIMPLE
171 help 179 help
172 Support for the USB3 core reset on UniPhier SoCs. 180 Support for peripheral core reset included in its own glue layer
173 Say Y if you want to control reset signals provided by 181 on UniPhier SoCs. Say Y if you want to control reset signals
174 USB3 glue layer. 182 provided by the glue layer.
175 183
176config RESET_ZYNQ 184config RESET_ZYNQ
177 bool "ZYNQ Reset Driver" if COMPILE_TEST 185 bool "ZYNQ Reset Driver" if COMPILE_TEST
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index d08e8b90046a..dc7874df78d9 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -19,10 +19,11 @@ obj-$(CONFIG_RESET_QCOM_AOSS) += reset-qcom-aoss.o
19obj-$(CONFIG_RESET_QCOM_PDC) += reset-qcom-pdc.o 19obj-$(CONFIG_RESET_QCOM_PDC) += reset-qcom-pdc.o
20obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o 20obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
21obj-$(CONFIG_RESET_STM32MP157) += reset-stm32mp1.o 21obj-$(CONFIG_RESET_STM32MP157) += reset-stm32mp1.o
22obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
22obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o 23obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
23obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o 24obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
24obj-$(CONFIG_RESET_TI_SYSCON) += reset-ti-syscon.o 25obj-$(CONFIG_RESET_TI_SYSCON) += reset-ti-syscon.o
25obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o 26obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o
26obj-$(CONFIG_RESET_UNIPHIER_USB3) += reset-uniphier-usb3.o 27obj-$(CONFIG_RESET_UNIPHIER_GLUE) += reset-uniphier-glue.o
27obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o 28obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o
28 29
diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index d1887c0ed5d3..9582efb70025 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -795,3 +795,45 @@ devm_reset_control_array_get(struct device *dev, bool shared, bool optional)
795 return rstc; 795 return rstc;
796} 796}
797EXPORT_SYMBOL_GPL(devm_reset_control_array_get); 797EXPORT_SYMBOL_GPL(devm_reset_control_array_get);
798
799static int reset_control_get_count_from_lookup(struct device *dev)
800{
801 const struct reset_control_lookup *lookup;
802 const char *dev_id;
803 int count = 0;
804
805 if (!dev)
806 return -EINVAL;
807
808 dev_id = dev_name(dev);
809 mutex_lock(&reset_lookup_mutex);
810
811 list_for_each_entry(lookup, &reset_lookup_list, list) {
812 if (!strcmp(lookup->dev_id, dev_id))
813 count++;
814 }
815
816 mutex_unlock(&reset_lookup_mutex);
817
818 if (count == 0)
819 count = -ENOENT;
820
821 return count;
822}
823
824/**
825 * reset_control_get_count - Count number of resets available with a device
826 *
827 * @dev: device for which to return the number of resets
828 *
829 * Returns positive reset count on success, or error number on failure and
830 * on count being zero.
831 */
832int reset_control_get_count(struct device *dev)
833{
834 if (dev->of_node)
835 return of_reset_control_get_count(dev->of_node);
836
837 return reset_control_get_count_from_lookup(dev);
838}
839EXPORT_SYMBOL_GPL(reset_control_get_count);
diff --git a/drivers/reset/reset-hsdk.c b/drivers/reset/reset-hsdk.c
index 8bce391c6943..4c7b8647b49c 100644
--- a/drivers/reset/reset-hsdk.c
+++ b/drivers/reset/reset-hsdk.c
@@ -86,6 +86,7 @@ static int hsdk_reset_reset(struct reset_controller_dev *rcdev,
86 86
87static const struct reset_control_ops hsdk_reset_ops = { 87static const struct reset_control_ops hsdk_reset_ops = {
88 .reset = hsdk_reset_reset, 88 .reset = hsdk_reset_reset,
89 .deassert = hsdk_reset_reset,
89}; 90};
90 91
91static int hsdk_reset_probe(struct platform_device *pdev) 92static int hsdk_reset_probe(struct platform_device *pdev)
diff --git a/drivers/reset/reset-simple.c b/drivers/reset/reset-simple.c
index a91107fc9e27..77fbba3100c8 100644
--- a/drivers/reset/reset-simple.c
+++ b/drivers/reset/reset-simple.c
@@ -109,7 +109,7 @@ struct reset_simple_devdata {
109#define SOCFPGA_NR_BANKS 8 109#define SOCFPGA_NR_BANKS 8
110 110
111static const struct reset_simple_devdata reset_simple_socfpga = { 111static const struct reset_simple_devdata reset_simple_socfpga = {
112 .reg_offset = 0x10, 112 .reg_offset = 0x20,
113 .nr_resets = SOCFPGA_NR_BANKS * 32, 113 .nr_resets = SOCFPGA_NR_BANKS * 32,
114 .status_active_low = true, 114 .status_active_low = true,
115}; 115};
@@ -120,7 +120,8 @@ static const struct reset_simple_devdata reset_simple_active_low = {
120}; 120};
121 121
122static const struct of_device_id reset_simple_dt_ids[] = { 122static 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 { .compatible = "st,stm32-rcc", }, 125 { .compatible = "st,stm32-rcc", },
125 { .compatible = "allwinner,sun6i-a31-clock-reset", 126 { .compatible = "allwinner,sun6i-a31-clock-reset",
126 .data = &reset_simple_active_low }, 127 .data = &reset_simple_active_low },
@@ -166,14 +167,6 @@ static int reset_simple_probe(struct platform_device *pdev)
166 data->status_active_low = devdata->status_active_low; 167 data->status_active_low = devdata->status_active_low;
167 } 168 }
168 169
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
177 data->membase += reg_offset; 170 data->membase += reg_offset;
178 171
179 return devm_reset_controller_register(dev, &data->rcdev); 172 return devm_reset_controller_register(dev, &data->rcdev);
diff --git a/drivers/reset/reset-socfpga.c b/drivers/reset/reset-socfpga.c
new file mode 100644
index 000000000000..318cfc51c441
--- /dev/null
+++ b/drivers/reset/reset-socfpga.c
@@ -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
21void __init socfpga_reset_init(void);
22
23static 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
65err_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 */
77static const struct of_device_id socfpga_early_reset_dt_ids[] __initconst = {
78 { .compatible = "altr,rst-mgr", },
79 { /* sentinel */ },
80};
81
82void __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}
diff --git a/drivers/reset/reset-uniphier-usb3.c b/drivers/reset/reset-uniphier-glue.c
index ffa1b19b594d..a45923f4df6d 100644
--- a/drivers/reset/reset-uniphier-usb3.c
+++ b/drivers/reset/reset-uniphier-glue.c
@@ -1,6 +1,6 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: GPL-2.0
2// 2//
3// reset-uniphier-usb3.c - USB3 reset driver for UniPhier 3// reset-uniphier-glue.c - Glue layer reset driver for UniPhier
4// Copyright 2018 Socionext Inc. 4// Copyright 2018 Socionext Inc.
5// Author: Kunihiko Hayashi <hayashi.kunihiko@socionext.com> 5// Author: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
6 6
@@ -15,24 +15,24 @@
15#define MAX_CLKS 2 15#define MAX_CLKS 2
16#define MAX_RSTS 2 16#define MAX_RSTS 2
17 17
18struct uniphier_usb3_reset_soc_data { 18struct uniphier_glue_reset_soc_data {
19 int nclks; 19 int nclks;
20 const char * const *clock_names; 20 const char * const *clock_names;
21 int nrsts; 21 int nrsts;
22 const char * const *reset_names; 22 const char * const *reset_names;
23}; 23};
24 24
25struct uniphier_usb3_reset_priv { 25struct uniphier_glue_reset_priv {
26 struct clk_bulk_data clk[MAX_CLKS]; 26 struct clk_bulk_data clk[MAX_CLKS];
27 struct reset_control *rst[MAX_RSTS]; 27 struct reset_control *rst[MAX_RSTS];
28 struct reset_simple_data rdata; 28 struct reset_simple_data rdata;
29 const struct uniphier_usb3_reset_soc_data *data; 29 const struct uniphier_glue_reset_soc_data *data;
30}; 30};
31 31
32static int uniphier_usb3_reset_probe(struct platform_device *pdev) 32static int uniphier_glue_reset_probe(struct platform_device *pdev)
33{ 33{
34 struct device *dev = &pdev->dev; 34 struct device *dev = &pdev->dev;
35 struct uniphier_usb3_reset_priv *priv; 35 struct uniphier_glue_reset_priv *priv;
36 struct resource *res; 36 struct resource *res;
37 resource_size_t size; 37 resource_size_t size;
38 const char *name; 38 const char *name;
@@ -100,9 +100,9 @@ out_rst_assert:
100 return ret; 100 return ret;
101} 101}
102 102
103static int uniphier_usb3_reset_remove(struct platform_device *pdev) 103static int uniphier_glue_reset_remove(struct platform_device *pdev)
104{ 104{
105 struct uniphier_usb3_reset_priv *priv = platform_get_drvdata(pdev); 105 struct uniphier_glue_reset_priv *priv = platform_get_drvdata(pdev);
106 int i; 106 int i;
107 107
108 for (i = 0; i < priv->data->nrsts; i++) 108 for (i = 0; i < priv->data->nrsts; i++)
@@ -117,7 +117,7 @@ static const char * const uniphier_pro4_clock_reset_names[] = {
117 "gio", "link", 117 "gio", "link",
118}; 118};
119 119
120static const struct uniphier_usb3_reset_soc_data uniphier_pro4_data = { 120static const struct uniphier_glue_reset_soc_data uniphier_pro4_data = {
121 .nclks = ARRAY_SIZE(uniphier_pro4_clock_reset_names), 121 .nclks = ARRAY_SIZE(uniphier_pro4_clock_reset_names),
122 .clock_names = uniphier_pro4_clock_reset_names, 122 .clock_names = uniphier_pro4_clock_reset_names,
123 .nrsts = ARRAY_SIZE(uniphier_pro4_clock_reset_names), 123 .nrsts = ARRAY_SIZE(uniphier_pro4_clock_reset_names),
@@ -128,14 +128,14 @@ static const char * const uniphier_pxs2_clock_reset_names[] = {
128 "link", 128 "link",
129}; 129};
130 130
131static const struct uniphier_usb3_reset_soc_data uniphier_pxs2_data = { 131static const struct uniphier_glue_reset_soc_data uniphier_pxs2_data = {
132 .nclks = ARRAY_SIZE(uniphier_pxs2_clock_reset_names), 132 .nclks = ARRAY_SIZE(uniphier_pxs2_clock_reset_names),
133 .clock_names = uniphier_pxs2_clock_reset_names, 133 .clock_names = uniphier_pxs2_clock_reset_names,
134 .nrsts = ARRAY_SIZE(uniphier_pxs2_clock_reset_names), 134 .nrsts = ARRAY_SIZE(uniphier_pxs2_clock_reset_names),
135 .reset_names = uniphier_pxs2_clock_reset_names, 135 .reset_names = uniphier_pxs2_clock_reset_names,
136}; 136};
137 137
138static const struct of_device_id uniphier_usb3_reset_match[] = { 138static const struct of_device_id uniphier_glue_reset_match[] = {
139 { 139 {
140 .compatible = "socionext,uniphier-pro4-usb3-reset", 140 .compatible = "socionext,uniphier-pro4-usb3-reset",
141 .data = &uniphier_pro4_data, 141 .data = &uniphier_pro4_data,
@@ -152,20 +152,32 @@ static const struct of_device_id uniphier_usb3_reset_match[] = {
152 .compatible = "socionext,uniphier-pxs3-usb3-reset", 152 .compatible = "socionext,uniphier-pxs3-usb3-reset",
153 .data = &uniphier_pxs2_data, 153 .data = &uniphier_pxs2_data,
154 }, 154 },
155 {
156 .compatible = "socionext,uniphier-pro4-ahci-reset",
157 .data = &uniphier_pro4_data,
158 },
159 {
160 .compatible = "socionext,uniphier-pxs2-ahci-reset",
161 .data = &uniphier_pxs2_data,
162 },
163 {
164 .compatible = "socionext,uniphier-pxs3-ahci-reset",
165 .data = &uniphier_pxs2_data,
166 },
155 { /* Sentinel */ } 167 { /* Sentinel */ }
156}; 168};
157MODULE_DEVICE_TABLE(of, uniphier_usb3_reset_match); 169MODULE_DEVICE_TABLE(of, uniphier_glue_reset_match);
158 170
159static struct platform_driver uniphier_usb3_reset_driver = { 171static struct platform_driver uniphier_glue_reset_driver = {
160 .probe = uniphier_usb3_reset_probe, 172 .probe = uniphier_glue_reset_probe,
161 .remove = uniphier_usb3_reset_remove, 173 .remove = uniphier_glue_reset_remove,
162 .driver = { 174 .driver = {
163 .name = "uniphier-usb3-reset", 175 .name = "uniphier-glue-reset",
164 .of_match_table = uniphier_usb3_reset_match, 176 .of_match_table = uniphier_glue_reset_match,
165 }, 177 },
166}; 178};
167module_platform_driver(uniphier_usb3_reset_driver); 179module_platform_driver(uniphier_glue_reset_driver);
168 180
169MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>"); 181MODULE_AUTHOR("Kunihiko Hayashi <hayashi.kunihiko@socionext.com>");
170MODULE_DESCRIPTION("UniPhier USB3 Reset Driver"); 182MODULE_DESCRIPTION("UniPhier Glue layer reset driver");
171MODULE_LICENSE("GPL"); 183MODULE_LICENSE("GPL");