1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright 2017 Google, Inc
4 * Copyright 2020 ASPEED Technology Inc.
12 #include <reset-uclass.h>
13 #include <linux/err.h>
15 #include <asm/arch/scu_ast2500.h>
17 struct ast2500_reset_priv {
18 struct ast2500_scu *scu;
21 static int ast2500_reset_assert(struct reset_ctl *reset_ctl)
23 struct ast2500_reset_priv *priv = dev_get_priv(reset_ctl->dev);
24 struct ast2500_scu *scu = priv->scu;
26 debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id);
28 if (reset_ctl->id < 32)
29 setbits_le32(&scu->sysreset_ctrl1, BIT(reset_ctl->id));
31 setbits_le32(&scu->sysreset_ctrl2, BIT(reset_ctl->id - 32));
36 static int ast2500_reset_deassert(struct reset_ctl *reset_ctl)
38 struct ast2500_reset_priv *priv = dev_get_priv(reset_ctl->dev);
39 struct ast2500_scu *scu = priv->scu;
41 debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id);
43 if (reset_ctl->id < 32)
44 clrbits_le32(&scu->sysreset_ctrl1, BIT(reset_ctl->id));
46 clrbits_le32(&scu->sysreset_ctrl2, BIT(reset_ctl->id - 32));
51 static int ast2500_reset_status(struct reset_ctl *reset_ctl)
53 struct ast2500_reset_priv *priv = dev_get_priv(reset_ctl->dev);
54 struct ast2500_scu *scu = priv->scu;
57 debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id);
59 if (reset_ctl->id < 32)
60 status = BIT(reset_ctl->id) & readl(&scu->sysreset_ctrl1);
62 status = BIT(reset_ctl->id - 32) & readl(&scu->sysreset_ctrl2);
69 static int ast2500_reset_probe(struct udevice *dev)
72 struct ast2500_reset_priv *priv = dev_get_priv(dev);
73 struct udevice *scu_dev;
75 /* get SCU base from clock device */
76 rc = uclass_get_device_by_driver(UCLASS_CLK,
77 DM_DRIVER_GET(aspeed_ast2500_scu), &scu_dev);
79 debug("%s: clock device not found, rc=%d\n", __func__, rc);
83 priv->scu = devfdt_get_addr_ptr(scu_dev);
84 if (IS_ERR_OR_NULL(priv->scu)) {
85 debug("%s: invalid SCU base pointer\n", __func__);
86 return PTR_ERR(priv->scu);
92 static const struct udevice_id ast2500_reset_ids[] = {
93 { .compatible = "aspeed,ast2500-reset" },
97 struct reset_ops ast2500_reset_ops = {
98 .rst_assert = ast2500_reset_assert,
99 .rst_deassert = ast2500_reset_deassert,
100 .rst_status = ast2500_reset_status,
103 U_BOOT_DRIVER(ast2500_reset) = {
104 .name = "ast2500_reset",
106 .of_match = ast2500_reset_ids,
107 .probe = ast2500_reset_probe,
108 .ops = &ast2500_reset_ops,
109 .priv_auto = sizeof(struct ast2500_reset_priv),