blob: ae69090a361ca1ff05f588b5a0d1e56b1246ddbb [file] [log] [blame]
Patrick Williams8dd68482022-10-04 07:57:18 -05001Upstream-Status: Pending[Not submitted to upstream yet]
2Signed-off-by: Emekcan Aras <emekcan.aras@arm.com>
3
4From 97509e82b51c57935fc8e918b33c09c4f6648ed7 Mon Sep 17 00:00:00 2001
5From: Emekcan <emekcan.aras@arm.com>
6Date: Fri, 19 Aug 2022 14:51:08 +0100
7Subject: [PATCH] Add external system driver
8
9Adds external system driver to control it
10from user-space. It provides run and reset
11functionality at the moment.
12
13Signed-off-by: Emekcan Aras <emekcan.aras@arm.com>
14---
15 drivers/misc/Kconfig | 2 +
16 drivers/misc/Makefile | 1 +
17 drivers/misc/arm/Kconfig | 5 ++
18 drivers/misc/arm/Makefile | 1 +
19 drivers/misc/arm/extsys_ctrl.c | 151 +++++++++++++++++++++++++++++++++
20 5 files changed, 160 insertions(+)
21 create mode 100644 drivers/misc/arm/Kconfig
22 create mode 100644 drivers/misc/arm/Makefile
23 create mode 100644 drivers/misc/arm/extsys_ctrl.c
24
25diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
26index 0f5a49fc7c9e..5ca195110b3f 100644
27--- a/drivers/misc/Kconfig
28+++ b/drivers/misc/Kconfig
29@@ -487,4 +487,6 @@ source "drivers/misc/cardreader/Kconfig"
30 source "drivers/misc/habanalabs/Kconfig"
31 source "drivers/misc/uacce/Kconfig"
32 source "drivers/misc/pvpanic/Kconfig"
33+source "drivers/misc/arm/Kconfig"
34+
35 endmenu
36diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
37index a086197af544..f5c1bd5747f7 100644
38--- a/drivers/misc/Makefile
39+++ b/drivers/misc/Makefile
40@@ -59,3 +59,4 @@ obj-$(CONFIG_UACCE) += uacce/
41 obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o
42 obj-$(CONFIG_HISI_HIKEY_USB) += hisi_hikey_usb.o
43 obj-$(CONFIG_HI6421V600_IRQ) += hi6421v600-irq.o
44+obj-y += arm/
45diff --git a/drivers/misc/arm/Kconfig b/drivers/misc/arm/Kconfig
46new file mode 100644
47index 000000000000..3c4b3f08e6b4
48--- /dev/null
49+++ b/drivers/misc/arm/Kconfig
50@@ -0,0 +1,5 @@
51+config EXTSYS_CTRL
52+ tristate "Arm External System control driver"
53+ help
54+ Say y here to enable support for external system control
55+ driver for the Arm Corstone-700 and Corstone1000 platform
56\ No newline at end of file
57diff --git a/drivers/misc/arm/Makefile b/drivers/misc/arm/Makefile
58new file mode 100644
59index 000000000000..1ca3084cf8a0
60--- /dev/null
61+++ b/drivers/misc/arm/Makefile
62@@ -0,0 +1 @@
63+obj-$(CONFIG_EXTSYS_CTRL) += extsys_ctrl.o
64diff --git a/drivers/misc/arm/extsys_ctrl.c b/drivers/misc/arm/extsys_ctrl.c
65new file mode 100644
66index 000000000000..1c6ef14a32ae
67--- /dev/null
68+++ b/drivers/misc/arm/extsys_ctrl.c
69@@ -0,0 +1,151 @@
70+// SPDX-License-Identifier: GPL-2.0
71+/*
72+ * Arm Corstone700 and Corstone1000 external system reset control driver
73+ *
74+ * Copyright (C) 2019 Arm Ltd.
75+ *
76+ */
77+
78+#include <linux/fs.h>
79+#include <linux/clk.h>
80+#include <linux/err.h>
81+#include <linux/interrupt.h>
82+#include <linux/io.h>
83+#include <linux/kernel.h>
84+#include <linux/mod_devicetable.h>
85+#include <linux/module.h>
86+#include <linux/platform_device.h>
87+#include <linux/miscdevice.h>
88+#include <linux/init.h>
89+
90+#define EXTSYS_DRV_NAME "extsys_ctrl"
91+#define EXTSYS_MAX_DEVS 4
92+
93+#define EXTSYS_RST_SIZE U(0x8)
94+#define EXTSYS_RST_CTRL_OFF U(0x0)
95+#define EXTSYS_RST_ST_OFF U(0x4)
96+
97+/* External system reset control indexes */
98+#define EXTSYS_CPU_WAIT (0x0)
99+#define EXTSYS_RST_REQ (0x1)
100+
101+/* External system reset status masks */
102+#define EXTSYS_RST_ST_ACK_OFF U(0x1)
103+
104+/* No Reset Requested */
105+#define EXTSYS_RST_ST_ACK_NRR (0x0 << EXTSYS_RST_ST_ACK_OFF)
106+
107+/* Reset Request Complete */
108+#define EXTSYS_RST_ST_ACK_RRC (0x2 << EXTSYS_RST_ST_ACK_OFF)
109+
110+/* Reset Request Unable to Complete */
111+#define EXTSYS_RST_ST_ACK_RRUC (0x3 << EXTSYS_RST_ST_ACK_OFF)
112+
113+/* IOCTL commands */
114+#define EXTSYS_CPU_WAIT_DISABLE 0x0
115+#define EXTSYS_RESET_REQ_ENABLE 0x1
116+
117+struct extsys_ctrl {
118+ struct miscdevice miscdev;
119+ void __iomem *reset_reg;
120+ void __iomem *set_reg;
121+};
122+
123+#define CLEAR_BIT(addr, index) writel(readl(addr) & ~(1UL << index), addr)
124+#define SET_BIT(addr, index) writel(readl(addr) | (1UL << index), addr)
125+
126+static long extsys_ctrl_ioctl(struct file *f, unsigned int cmd,
127+ unsigned long arg)
128+{
129+ struct extsys_ctrl *extsys;
130+
131+ extsys = container_of(f->private_data, struct extsys_ctrl, miscdev);
132+
133+ switch (cmd) {
134+ case EXTSYS_CPU_WAIT_DISABLE:
135+ CLEAR_BIT(extsys->reset_reg, EXTSYS_CPU_WAIT);
136+ break;
137+ case EXTSYS_RESET_REQ_ENABLE:
138+ SET_BIT(extsys->reset_reg, EXTSYS_RST_REQ);
139+ break;
140+ default:
141+ break;
142+ }
143+
144+ return 0;
145+}
146+
147+static const struct file_operations extsys_ctrl_fops = {
148+ .owner = THIS_MODULE,
149+ .unlocked_ioctl = extsys_ctrl_ioctl,
150+};
151+
152+static int extsys_ctrl_probe(struct platform_device *pdev)
153+{
154+ struct device *dev = &pdev->dev;
155+ struct extsys_ctrl *extsys;
156+ struct resource *res;
157+ void __iomem *reset_reg;
158+ void __iomem *set_reg;
159+ int ret;
160+
161+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rstreg");
162+ reset_reg = devm_ioremap_resource(dev, res);
163+ if (IS_ERR(reset_reg))
164+ return PTR_ERR(reset_reg);
165+
166+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "streg");
167+ set_reg = devm_ioremap_resource(dev, res);
168+ if (IS_ERR(set_reg))
169+ return PTR_ERR(set_reg);
170+
171+ extsys = devm_kzalloc(dev, sizeof(*extsys), GFP_KERNEL);
172+ if (!extsys)
173+ return -ENOMEM;
174+
175+ extsys->reset_reg = reset_reg;
176+ extsys->set_reg = set_reg;
177+
178+ extsys->miscdev.minor = MISC_DYNAMIC_MINOR;
179+ extsys->miscdev.name = EXTSYS_DRV_NAME;
180+ extsys->miscdev.fops = &extsys_ctrl_fops;
181+ extsys->miscdev.parent = dev;
182+
183+ ret = misc_register(&extsys->miscdev);
184+ if (ret)
185+ return ret;
186+
187+ dev_info(dev, "external system controller ready\n");
188+
189+ return 0;
190+}
191+
192+static int extsys_ctrl_remove(struct platform_device *pdev)
193+{
194+ struct extsys_ctrl *extsys = dev_get_drvdata(&pdev->dev);
195+
196+ misc_deregister(&extsys->miscdev);
197+
198+ return 0;
199+}
200+
201+static const struct of_device_id extsys_ctrl_match[] = {
202+ { .compatible = "arm,extsys_ctrl" },
203+ { },
204+};
205+MODULE_DEVICE_TABLE(of, extsys_ctrl_match);
206+
207+static struct platform_driver extsys_ctrl_driver = {
208+ .driver = {
209+ .name = EXTSYS_DRV_NAME,
210+ .of_match_table = extsys_ctrl_match,
211+ },
212+ .probe = extsys_ctrl_probe,
213+ .remove = extsys_ctrl_remove,
214+};
215+module_platform_driver(extsys_ctrl_driver);
216+
217+MODULE_LICENSE("GPL v2");
218+MODULE_DESCRIPTION("Arm External System Control Driver");
219+MODULE_AUTHOR("Morten Borup Petersen");
220+MODULE_AUTHOR("Rui Miguel Silva <rui.silva@arm.com>");
221--
2222.17.1
223