1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (C) 2016 NVIDIA Corporation |
4 | */ |
5 | |
6 | #include <linux/reset-controller.h> |
7 | |
8 | #include <soc/tegra/bpmp.h> |
9 | #include <soc/tegra/bpmp-abi.h> |
10 | |
11 | static struct tegra_bpmp *to_tegra_bpmp(struct reset_controller_dev *rstc) |
12 | { |
13 | return container_of(rstc, struct tegra_bpmp, rstc); |
14 | } |
15 | |
16 | static int tegra_bpmp_reset_common(struct reset_controller_dev *rstc, |
17 | enum mrq_reset_commands command, |
18 | unsigned int id) |
19 | { |
20 | struct tegra_bpmp *bpmp = to_tegra_bpmp(rstc); |
21 | struct mrq_reset_request request; |
22 | struct tegra_bpmp_message msg; |
23 | int err; |
24 | |
25 | memset(&request, 0, sizeof(request)); |
26 | request.cmd = command; |
27 | request.reset_id = id; |
28 | |
29 | memset(&msg, 0, sizeof(msg)); |
30 | msg.mrq = MRQ_RESET; |
31 | msg.tx.data = &request; |
32 | msg.tx.size = sizeof(request); |
33 | |
34 | err = tegra_bpmp_transfer(bpmp, msg: &msg); |
35 | if (err) |
36 | return err; |
37 | if (msg.rx.ret) |
38 | return -EINVAL; |
39 | |
40 | return 0; |
41 | } |
42 | |
43 | static int tegra_bpmp_reset_module(struct reset_controller_dev *rstc, |
44 | unsigned long id) |
45 | { |
46 | return tegra_bpmp_reset_common(rstc, command: CMD_RESET_MODULE, id); |
47 | } |
48 | |
49 | static int tegra_bpmp_reset_assert(struct reset_controller_dev *rstc, |
50 | unsigned long id) |
51 | { |
52 | return tegra_bpmp_reset_common(rstc, command: CMD_RESET_ASSERT, id); |
53 | } |
54 | |
55 | static int tegra_bpmp_reset_deassert(struct reset_controller_dev *rstc, |
56 | unsigned long id) |
57 | { |
58 | return tegra_bpmp_reset_common(rstc, command: CMD_RESET_DEASSERT, id); |
59 | } |
60 | |
61 | static const struct reset_control_ops tegra_bpmp_reset_ops = { |
62 | .reset = tegra_bpmp_reset_module, |
63 | .assert = tegra_bpmp_reset_assert, |
64 | .deassert = tegra_bpmp_reset_deassert, |
65 | }; |
66 | |
67 | int tegra_bpmp_init_resets(struct tegra_bpmp *bpmp) |
68 | { |
69 | bpmp->rstc.ops = &tegra_bpmp_reset_ops; |
70 | bpmp->rstc.owner = THIS_MODULE; |
71 | bpmp->rstc.of_node = bpmp->dev->of_node; |
72 | bpmp->rstc.nr_resets = bpmp->soc->num_resets; |
73 | |
74 | return devm_reset_controller_register(dev: bpmp->dev, rcdev: &bpmp->rstc); |
75 | } |
76 | |