1 /*
2 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 /**
18 * DOC: wlan_gpio_api.c
19 */
20 #include <wlan_gpio_api.h>
21 #include <wlan_gpio_priv_api.h>
22 #include <wlan_objmgr_global_obj.h>
23
24 /**
25 * gpio_psoc_obj_created_notification() - PSOC obj create callback
26 * @psoc: PSOC object
27 * @arg_list: Variable argument list
28 *
29 * This callback is registered with object manager during initialization to
30 * get notified when the object is created.
31 *
32 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
33 */
34 static QDF_STATUS
gpio_psoc_obj_created_notification(struct wlan_objmgr_psoc * psoc,void * arg_list)35 gpio_psoc_obj_created_notification(struct wlan_objmgr_psoc *psoc,
36 void *arg_list)
37 {
38 QDF_STATUS status = QDF_STATUS_SUCCESS;
39 struct gpio_psoc_priv_obj *gpio_obj;
40
41 gpio_obj = qdf_mem_malloc(sizeof(*gpio_obj));
42 if (!gpio_obj)
43 return QDF_STATUS_E_NOMEM;
44
45 qdf_spinlock_create(&gpio_obj->lock);
46 status = wlan_objmgr_psoc_component_obj_attach(psoc,
47 WLAN_UMAC_COMP_GPIO,
48 gpio_obj,
49 QDF_STATUS_SUCCESS);
50 if (QDF_IS_STATUS_ERROR(status)) {
51 gpio_err("obj attach with psoc failed");
52 goto gpio_psoc_attach_failed;
53 }
54
55 return QDF_STATUS_SUCCESS;
56
57 gpio_psoc_attach_failed:
58 qdf_spinlock_destroy(&gpio_obj->lock);
59 qdf_mem_free(gpio_obj);
60 return status;
61 }
62
63 /**
64 * gpio_psoc_obj_destroyed_notification() - obj delete callback
65 * @psoc: PSOC object
66 * @arg_list: Variable argument list
67 *
68 * This callback is registered with object manager during initialization to
69 * get notified when the object is deleted.
70 *
71 * Return: QDF_STATUS_SUCCESS on success, QDF_STATUS_E_** on error
72 */
73 static QDF_STATUS
gpio_psoc_obj_destroyed_notification(struct wlan_objmgr_psoc * psoc,void * arg_list)74 gpio_psoc_obj_destroyed_notification(struct wlan_objmgr_psoc *psoc,
75 void *arg_list)
76 {
77 QDF_STATUS status = QDF_STATUS_SUCCESS;
78 struct gpio_psoc_priv_obj *gpio_obj;
79
80 gpio_obj = gpio_get_psoc_priv_obj(psoc);
81
82 if (!gpio_obj) {
83 gpio_err("gpio_obj is NULL");
84 return QDF_STATUS_E_FAULT;
85 }
86
87 status = wlan_objmgr_psoc_component_obj_detach(psoc,
88 WLAN_UMAC_COMP_GPIO,
89 gpio_obj);
90 if (QDF_IS_STATUS_ERROR(status))
91 gpio_err("gpio_obj detach failed");
92
93 qdf_spinlock_destroy(&gpio_obj->lock);
94 qdf_mem_free(gpio_obj);
95
96 return status;
97 }
98
wlan_gpio_init(void)99 QDF_STATUS wlan_gpio_init(void)
100 {
101 QDF_STATUS status;
102
103 /* register psoc create handler functions. */
104 status = wlan_objmgr_register_psoc_create_handler(
105 WLAN_UMAC_COMP_GPIO,
106 gpio_psoc_obj_created_notification,
107 NULL);
108 if (QDF_IS_STATUS_ERROR(status)) {
109 gpio_err("register create handler failed");
110 return status;
111 }
112
113 /* register psoc delete handler functions. */
114 status = wlan_objmgr_register_psoc_destroy_handler(
115 WLAN_UMAC_COMP_GPIO,
116 gpio_psoc_obj_destroyed_notification,
117 NULL);
118 if (QDF_IS_STATUS_ERROR(status)) {
119 gpio_err("register destroy handler failed");
120 goto fail_delete_psoc;
121 }
122
123 return status;
124
125 fail_delete_psoc:
126 wlan_objmgr_unregister_psoc_create_handler(
127 WLAN_UMAC_COMP_GPIO,
128 gpio_psoc_obj_created_notification,
129 NULL);
130 return status;
131 }
132
wlan_gpio_deinit(void)133 QDF_STATUS wlan_gpio_deinit(void)
134 {
135 QDF_STATUS ret = QDF_STATUS_SUCCESS, status;
136
137 /* unregister psoc delete handler functions. */
138 status = wlan_objmgr_unregister_psoc_destroy_handler(
139 WLAN_UMAC_COMP_GPIO,
140 gpio_psoc_obj_destroyed_notification,
141 NULL);
142 if (QDF_IS_STATUS_ERROR(status)) {
143 gpio_err("unregister destroy handler failed");
144 ret = status;
145 }
146
147 /* unregister psoc create handler functions. */
148 status = wlan_objmgr_unregister_psoc_create_handler(
149 WLAN_UMAC_COMP_GPIO,
150 gpio_psoc_obj_created_notification,
151 NULL);
152 if (QDF_IS_STATUS_ERROR(status)) {
153 gpio_err("unregister create handler failed");
154 ret = status;
155 }
156
157 return ret;
158 }
159