1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Qualcomm PSHOLD reset driver
4  *
5  * Copyright (c) 2024 Sartura Ltd.
6  *
7  * Author: Robert Marko <robert.marko@sartura.hr>
8  * Based on the Linux msm-poweroff driver.
9  *
10  */
11 
12 #include <dm.h>
13 #include <sysreset.h>
14 #include <asm/io.h>
15 #include <linux/delay.h>
16 
17 struct qcom_pshold_priv {
18 	phys_addr_t base;
19 };
20 
qcom_pshold_request(struct udevice * dev,enum sysreset_t type)21 static int qcom_pshold_request(struct udevice *dev, enum sysreset_t type)
22 {
23 	struct qcom_pshold_priv *priv = dev_get_priv(dev);
24 
25 	writel(0, priv->base);
26 	mdelay(10000);
27 
28 	return 0;
29 }
30 
31 static struct sysreset_ops qcom_pshold_ops = {
32 	.request = qcom_pshold_request,
33 };
34 
qcom_pshold_probe(struct udevice * dev)35 static int qcom_pshold_probe(struct udevice *dev)
36 {
37 	struct qcom_pshold_priv *priv = dev_get_priv(dev);
38 
39 	priv->base = dev_read_addr(dev);
40 	return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0;
41 }
42 
43 static const struct udevice_id qcom_pshold_ids[] = {
44 	{ .compatible = "qcom,pshold", },
45 	{ /* sentinel */ }
46 };
47 
48 U_BOOT_DRIVER(qcom_pshold) = {
49 	.name 		= "qcom_pshold",
50 	.id 		= UCLASS_SYSRESET,
51 	.of_match 	= qcom_pshold_ids,
52 	.probe 		= qcom_pshold_probe,
53 	.priv_auto	= sizeof(struct qcom_pshold_priv),
54 	.ops 		= &qcom_pshold_ops,
55 };
56