1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (c) 2013, The Linux Foundation. All rights reserved. |
4 | */ |
5 | |
6 | #include <linux/bitops.h> |
7 | #include <linux/export.h> |
8 | #include <linux/regmap.h> |
9 | #include <linux/reset-controller.h> |
10 | #include <linux/delay.h> |
11 | |
12 | #include "reset.h" |
13 | |
14 | static int qcom_reset(struct reset_controller_dev *rcdev, unsigned long id) |
15 | { |
16 | struct qcom_reset_controller *rst = to_qcom_reset_controller(rcdev); |
17 | |
18 | rcdev->ops->assert(rcdev, id); |
19 | fsleep(usecs: rst->reset_map[id].udelay ?: 1); /* use 1 us as default */ |
20 | |
21 | rcdev->ops->deassert(rcdev, id); |
22 | return 0; |
23 | } |
24 | |
25 | static int qcom_reset_set_assert(struct reset_controller_dev *rcdev, |
26 | unsigned long id, bool assert) |
27 | { |
28 | struct qcom_reset_controller *rst; |
29 | const struct qcom_reset_map *map; |
30 | u32 mask; |
31 | |
32 | rst = to_qcom_reset_controller(rcdev); |
33 | map = &rst->reset_map[id]; |
34 | mask = map->bitmask ? map->bitmask : BIT(map->bit); |
35 | |
36 | regmap_update_bits(map: rst->regmap, reg: map->reg, mask, val: assert ? mask : 0); |
37 | |
38 | /* Read back the register to ensure write completion, ignore the value */ |
39 | regmap_read(map: rst->regmap, reg: map->reg, val: &mask); |
40 | |
41 | return 0; |
42 | } |
43 | |
44 | static int qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) |
45 | { |
46 | return qcom_reset_set_assert(rcdev, id, assert: true); |
47 | } |
48 | |
49 | static int qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id) |
50 | { |
51 | return qcom_reset_set_assert(rcdev, id, assert: false); |
52 | } |
53 | |
54 | const struct reset_control_ops qcom_reset_ops = { |
55 | .reset = qcom_reset, |
56 | .assert = qcom_reset_assert, |
57 | .deassert = qcom_reset_deassert, |
58 | }; |
59 | EXPORT_SYMBOL_GPL(qcom_reset_ops); |
60 | |