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 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 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 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 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