xref: /linux/drivers/reset/spacemit/reset-spacemit-common.c (revision aba86f7bff0bfd6956aff9bbbfb0c6ea6d56809e)
1 // SPDX-License-Identifier: GPL-2.0-only
2 
3 /* SpacemiT reset controller driver - common implementation */
4 
5 #include <linux/container_of.h>
6 #include <linux/device.h>
7 #include <linux/module.h>
8 
9 #include <soc/spacemit/ccu.h>
10 
11 #include "reset-spacemit-common.h"
12 
13 static int spacemit_reset_update(struct reset_controller_dev *rcdev,
14 				 unsigned long id, bool assert)
15 {
16 	struct ccu_reset_controller *controller;
17 	const struct ccu_reset_data *data;
18 	u32 mask;
19 	u32 val;
20 
21 	controller = container_of(rcdev, struct ccu_reset_controller, rcdev);
22 	data = &controller->data->reset_data[id];
23 	mask = data->assert_mask | data->deassert_mask;
24 	val = assert ? data->assert_mask : data->deassert_mask;
25 
26 	return regmap_update_bits(controller->regmap, data->offset, mask, val);
27 }
28 
29 static int spacemit_reset_assert(struct reset_controller_dev *rcdev,
30 				 unsigned long id)
31 {
32 	return spacemit_reset_update(rcdev, id, true);
33 }
34 
35 static int spacemit_reset_deassert(struct reset_controller_dev *rcdev,
36 				   unsigned long id)
37 {
38 	return spacemit_reset_update(rcdev, id, false);
39 }
40 
41 static const struct reset_control_ops spacemit_reset_control_ops = {
42 	.assert		= spacemit_reset_assert,
43 	.deassert	= spacemit_reset_deassert,
44 };
45 
46 static int spacemit_reset_controller_register(struct device *dev,
47 					      struct ccu_reset_controller *controller)
48 {
49 	struct reset_controller_dev *rcdev = &controller->rcdev;
50 
51 	rcdev->ops = &spacemit_reset_control_ops;
52 	rcdev->owner = dev->driver->owner;
53 	rcdev->of_node = dev->of_node;
54 	rcdev->nr_resets = controller->data->count;
55 
56 	return devm_reset_controller_register(dev, &controller->rcdev);
57 }
58 
59 int spacemit_reset_probe(struct auxiliary_device *adev,
60 			 const struct auxiliary_device_id *id)
61 {
62 	struct spacemit_ccu_adev *rdev = to_spacemit_ccu_adev(adev);
63 	struct ccu_reset_controller *controller;
64 	struct device *dev = &adev->dev;
65 
66 	controller = devm_kzalloc(dev, sizeof(*controller), GFP_KERNEL);
67 	if (!controller)
68 		return -ENOMEM;
69 	controller->data = (const struct ccu_reset_controller_data *)id->driver_data;
70 	controller->regmap = rdev->regmap;
71 
72 	return spacemit_reset_controller_register(dev, controller);
73 }
74 EXPORT_SYMBOL_NS_GPL(spacemit_reset_probe, "RESET_SPACEMIT");
75 
76 MODULE_DESCRIPTION("SpacemiT reset controller driver - common code");
77 MODULE_LICENSE("GPL");
78