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