1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright 2023 Google LLC. |
4 | */ |
5 | |
6 | #include <linux/device.h> |
7 | #include <linux/spmi.h> |
8 | |
9 | static void devm_spmi_controller_release(struct device *parent, void *res) |
10 | { |
11 | spmi_controller_put(ctrl: *(struct spmi_controller **)res); |
12 | } |
13 | |
14 | struct spmi_controller *devm_spmi_controller_alloc(struct device *parent, size_t size) |
15 | { |
16 | struct spmi_controller **ptr, *ctrl; |
17 | |
18 | ptr = devres_alloc(devm_spmi_controller_release, sizeof(*ptr), GFP_KERNEL); |
19 | if (!ptr) |
20 | return ERR_PTR(error: -ENOMEM); |
21 | |
22 | ctrl = spmi_controller_alloc(parent, size); |
23 | if (IS_ERR(ptr: ctrl)) { |
24 | devres_free(res: ptr); |
25 | return ctrl; |
26 | } |
27 | |
28 | *ptr = ctrl; |
29 | devres_add(dev: parent, res: ptr); |
30 | |
31 | return ctrl; |
32 | } |
33 | EXPORT_SYMBOL_GPL(devm_spmi_controller_alloc); |
34 | |
35 | static void devm_spmi_controller_remove(struct device *parent, void *res) |
36 | { |
37 | spmi_controller_remove(ctrl: *(struct spmi_controller **)res); |
38 | } |
39 | |
40 | int devm_spmi_controller_add(struct device *parent, struct spmi_controller *ctrl) |
41 | { |
42 | struct spmi_controller **ptr; |
43 | int ret; |
44 | |
45 | ptr = devres_alloc(devm_spmi_controller_remove, sizeof(*ptr), GFP_KERNEL); |
46 | if (!ptr) |
47 | return -ENOMEM; |
48 | |
49 | ret = spmi_controller_add(ctrl); |
50 | if (ret) { |
51 | devres_free(res: ptr); |
52 | return ret; |
53 | } |
54 | |
55 | *ptr = ctrl; |
56 | devres_add(dev: parent, res: ptr); |
57 | |
58 | return 0; |
59 | |
60 | } |
61 | EXPORT_SYMBOL_GPL(devm_spmi_controller_add); |
62 | |
63 | MODULE_LICENSE("GPL" ); |
64 | MODULE_DESCRIPTION("SPMI devres helpers" ); |
65 | |