xref: /wlan-driver/qca-wifi-host-cmn/gpio/core/src/wlan_gpio_api.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
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