aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/reset/oxnas,reset.txt58
-rw-r--r--drivers/reset/Kconfig3
-rw-r--r--drivers/reset/Makefile1
-rw-r--r--drivers/reset/reset-oxnas.c136
-rw-r--r--include/linux/reset.h6
5 files changed, 204 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/reset/oxnas,reset.txt b/Documentation/devicetree/bindings/reset/oxnas,reset.txt
new file mode 100644
index 000000000000..6f06db930030
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/oxnas,reset.txt
@@ -0,0 +1,58 @@
1Oxford Semiconductor OXNAS SoC Family RESET Controller
2================================================
3
4Please also refer to reset.txt in this directory for common reset
5controller binding usage.
6
7Required properties:
8- compatible: Should be "oxsemi,ox810se-reset"
9- #reset-cells: 1, see below
10
11Parent node should have the following properties :
12- compatible: Should be "oxsemi,ox810se-sys-ctrl", "syscon", "simple-mfd"
13
14For OX810SE, the indices are :
15 - 0 : ARM
16 - 1 : COPRO
17 - 2 : Reserved
18 - 3 : Reserved
19 - 4 : USBHS
20 - 5 : USBHSPHY
21 - 6 : MAC
22 - 7 : PCI
23 - 8 : DMA
24 - 9 : DPE
25 - 10 : DDR
26 - 11 : SATA
27 - 12 : SATA_LINK
28 - 13 : SATA_PHY
29 - 14 : Reserved
30 - 15 : NAND
31 - 16 : GPIO
32 - 17 : UART1
33 - 18 : UART2
34 - 19 : MISC
35 - 20 : I2S
36 - 21 : AHB_MON
37 - 22 : UART3
38 - 23 : UART4
39 - 24 : SGDMA
40 - 25 : Reserved
41 - 26 : Reserved
42 - 27 : Reserved
43 - 28 : Reserved
44 - 29 : Reserved
45 - 30 : Reserved
46 - 31 : BUS
47
48example:
49
50sys: sys-ctrl@000000 {
51 compatible = "oxsemi,ox810se-sys-ctrl", "syscon", "simple-mfd";
52 reg = <0x000000 0x100000>;
53
54 reset: reset-controller {
55 compatible = "oxsemi,ox810se-reset";
56 #reset-cells = <1>;
57 };
58};
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index df37212a5cbd..0b2733db0e9e 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -12,5 +12,8 @@ menuconfig RESET_CONTROLLER
12 12
13 If unsure, say no. 13 If unsure, say no.
14 14
15config RESET_OXNAS
16 bool
17
15source "drivers/reset/sti/Kconfig" 18source "drivers/reset/sti/Kconfig"
16source "drivers/reset/hisilicon/Kconfig" 19source "drivers/reset/hisilicon/Kconfig"
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index a1fc8eda79f3..f173fc3847b4 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_ARCH_STI) += sti/
8obj-$(CONFIG_ARCH_HISI) += hisilicon/ 8obj-$(CONFIG_ARCH_HISI) += hisilicon/
9obj-$(CONFIG_ARCH_ZYNQ) += reset-zynq.o 9obj-$(CONFIG_ARCH_ZYNQ) += reset-zynq.o
10obj-$(CONFIG_ATH79) += reset-ath79.o 10obj-$(CONFIG_ATH79) += reset-ath79.o
11obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o
diff --git a/drivers/reset/reset-oxnas.c b/drivers/reset/reset-oxnas.c
new file mode 100644
index 000000000000..c60fb2dace3e
--- /dev/null
+++ b/drivers/reset/reset-oxnas.c
@@ -0,0 +1,136 @@
1/*
2 * drivers/reset/reset-oxnas.c
3 *
4 * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
5 * Copyright (C) 2014 Ma Haijun <mahaijuns@gmail.com>
6 * Copyright (C) 2009 Oxford Semiconductor Ltd
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms and conditions of the GNU General Public License,
10 * version 2, as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20#include <linux/err.h>
21#include <linux/module.h>
22#include <linux/of.h>
23#include <linux/platform_device.h>
24#include <linux/reset-controller.h>
25#include <linux/slab.h>
26#include <linux/delay.h>
27#include <linux/types.h>
28#include <linux/regmap.h>
29#include <linux/mfd/syscon.h>
30
31/* Regmap offsets */
32#define RST_SET_REGOFFSET 0x34
33#define RST_CLR_REGOFFSET 0x38
34
35struct oxnas_reset {
36 struct regmap *regmap;
37 struct reset_controller_dev rcdev;
38};
39
40static int oxnas_reset_reset(struct reset_controller_dev *rcdev,
41 unsigned long id)
42{
43 struct oxnas_reset *data =
44 container_of(rcdev, struct oxnas_reset, rcdev);
45
46 regmap_write(data->regmap, RST_SET_REGOFFSET, BIT(id));
47 msleep(50);
48 regmap_write(data->regmap, RST_CLR_REGOFFSET, BIT(id));
49
50 return 0;
51}
52
53static int oxnas_reset_assert(struct reset_controller_dev *rcdev,
54 unsigned long id)
55{
56 struct oxnas_reset *data =
57 container_of(rcdev, struct oxnas_reset, rcdev);
58
59 regmap_write(data->regmap, RST_SET_REGOFFSET, BIT(id));
60
61 return 0;
62}
63
64static int oxnas_reset_deassert(struct reset_controller_dev *rcdev,
65 unsigned long id)
66{
67 struct oxnas_reset *data =
68 container_of(rcdev, struct oxnas_reset, rcdev);
69
70 regmap_write(data->regmap, RST_CLR_REGOFFSET, BIT(id));
71
72 return 0;
73}
74
75static const struct reset_control_ops oxnas_reset_ops = {
76 .reset = oxnas_reset_reset,
77 .assert = oxnas_reset_assert,
78 .deassert = oxnas_reset_deassert,
79};
80
81static const struct of_device_id oxnas_reset_dt_ids[] = {
82 { .compatible = "oxsemi,ox810se-reset", },
83 { /* sentinel */ },
84};
85MODULE_DEVICE_TABLE(of, oxnas_reset_dt_ids);
86
87static int oxnas_reset_probe(struct platform_device *pdev)
88{
89 struct oxnas_reset *data;
90 struct device *parent;
91
92 parent = pdev->dev.parent;
93 if (!parent) {
94 dev_err(&pdev->dev, "no parent\n");
95 return -ENODEV;
96 }
97
98 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
99 if (!data)
100 return -ENOMEM;
101
102 data->regmap = syscon_node_to_regmap(parent->of_node);
103 if (IS_ERR(data->regmap)) {
104 dev_err(&pdev->dev, "failed to get parent regmap\n");
105 return PTR_ERR(data->regmap);
106 }
107
108 platform_set_drvdata(pdev, data);
109
110 data->rcdev.owner = THIS_MODULE;
111 data->rcdev.nr_resets = 32;
112 data->rcdev.ops = &oxnas_reset_ops;
113 data->rcdev.of_node = pdev->dev.of_node;
114
115 return reset_controller_register(&data->rcdev);
116}
117
118static int oxnas_reset_remove(struct platform_device *pdev)
119{
120 struct oxnas_reset *data = platform_get_drvdata(pdev);
121
122 reset_controller_unregister(&data->rcdev);
123
124 return 0;
125}
126
127static struct platform_driver oxnas_reset_driver = {
128 .probe = oxnas_reset_probe,
129 .remove = oxnas_reset_remove,
130 .driver = {
131 .name = "oxnas-reset",
132 .of_match_table = oxnas_reset_dt_ids,
133 },
134};
135
136module_platform_driver(oxnas_reset_driver);
diff --git a/include/linux/reset.h b/include/linux/reset.h
index a552134a209e..ec0306ce7b92 100644
--- a/include/linux/reset.h
+++ b/include/linux/reset.h
@@ -56,6 +56,12 @@ static inline void reset_control_put(struct reset_control *rstc)
56 WARN_ON(1); 56 WARN_ON(1);
57} 57}
58 58
59static inline int __must_check device_reset(struct device *dev)
60{
61 WARN_ON(1);
62 return -ENOTSUPP;
63}
64
59static inline int device_reset_optional(struct device *dev) 65static inline int device_reset_optional(struct device *dev)
60{ 66{
61 return -ENOTSUPP; 67 return -ENOTSUPP;