xref: /wlan-driver/qcacld-3.0/core/pld/src/pld_snoc.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name  * above copyright notice and this permission notice appear in all
8*5113495bSYour Name  * copies.
9*5113495bSYour Name  *
10*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name  */
19*5113495bSYour Name 
20*5113495bSYour Name #include <linux/platform_device.h>
21*5113495bSYour Name #include <linux/err.h>
22*5113495bSYour Name #include <linux/list.h>
23*5113495bSYour Name #include <linux/slab.h>
24*5113495bSYour Name 
25*5113495bSYour Name #ifdef CONFIG_CNSS_OUT_OF_TREE
26*5113495bSYour Name #ifdef CONFIG_PLD_SNOC_ICNSS
27*5113495bSYour Name #ifdef CONFIG_PLD_SNOC_ICNSS2
28*5113495bSYour Name #include "icnss2.h"
29*5113495bSYour Name #else
30*5113495bSYour Name #include "icnss.h"
31*5113495bSYour Name #endif
32*5113495bSYour Name #endif
33*5113495bSYour Name #else
34*5113495bSYour Name #ifdef CONFIG_PLD_SNOC_ICNSS
35*5113495bSYour Name #ifdef CONFIG_PLD_SNOC_ICNSS2
36*5113495bSYour Name #include <soc/qcom/icnss2.h>
37*5113495bSYour Name #else
38*5113495bSYour Name #include <soc/qcom/icnss.h>
39*5113495bSYour Name #endif
40*5113495bSYour Name #endif
41*5113495bSYour Name #endif
42*5113495bSYour Name 
43*5113495bSYour Name #include "pld_internal.h"
44*5113495bSYour Name #include "pld_snoc.h"
45*5113495bSYour Name #include "osif_psoc_sync.h"
46*5113495bSYour Name 
47*5113495bSYour Name #ifdef CONFIG_PLD_SNOC_ICNSS
48*5113495bSYour Name 
49*5113495bSYour Name #define ADRASTEA_DEVICE_ID 0xabcd
50*5113495bSYour Name 
51*5113495bSYour Name /**
52*5113495bSYour Name  * pld_snoc_idle_restart_cb() - Perform idle restart
53*5113495bSYour Name  * @dev: platform device
54*5113495bSYour Name  *
55*5113495bSYour Name  * This function will be called if there is an idle restart request
56*5113495bSYour Name  *
57*5113495bSYour Name  * Return: int
58*5113495bSYour Name  **/
pld_snoc_idle_restart_cb(struct device * dev)59*5113495bSYour Name static int pld_snoc_idle_restart_cb(struct device *dev)
60*5113495bSYour Name {
61*5113495bSYour Name 	struct pld_context *pld_context;
62*5113495bSYour Name 
63*5113495bSYour Name 	pld_context = pld_get_global_context();
64*5113495bSYour Name 	if (pld_context->ops->idle_restart)
65*5113495bSYour Name 		return pld_context->ops->idle_restart(dev, PLD_BUS_TYPE_SNOC);
66*5113495bSYour Name 
67*5113495bSYour Name 	return -ENODEV;
68*5113495bSYour Name }
69*5113495bSYour Name 
70*5113495bSYour Name /**
71*5113495bSYour Name  * pld_snoc_idle_shutdown_cb() - Perform idle shutdown
72*5113495bSYour Name  * @dev: PCIE device
73*5113495bSYour Name  *
74*5113495bSYour Name  * This function will be called if there is an idle shutdown request
75*5113495bSYour Name  *
76*5113495bSYour Name  * Return: int
77*5113495bSYour Name  */
pld_snoc_idle_shutdown_cb(struct device * dev)78*5113495bSYour Name static int pld_snoc_idle_shutdown_cb(struct device *dev)
79*5113495bSYour Name {
80*5113495bSYour Name 	struct pld_context *pld_context;
81*5113495bSYour Name 
82*5113495bSYour Name 	pld_context = pld_get_global_context();
83*5113495bSYour Name 	if (pld_context->ops->shutdown)
84*5113495bSYour Name 		return pld_context->ops->idle_shutdown(dev, PLD_BUS_TYPE_SNOC);
85*5113495bSYour Name 
86*5113495bSYour Name 	return -ENODEV;
87*5113495bSYour Name }
88*5113495bSYour Name 
89*5113495bSYour Name /**
90*5113495bSYour Name  * pld_snoc_probe() - Probe function for platform driver
91*5113495bSYour Name  * @dev: device
92*5113495bSYour Name  *
93*5113495bSYour Name  * The probe function will be called when platform device
94*5113495bSYour Name  * is detected.
95*5113495bSYour Name  *
96*5113495bSYour Name  * Return: int
97*5113495bSYour Name  */
pld_snoc_probe(struct device * dev)98*5113495bSYour Name static int pld_snoc_probe(struct device *dev)
99*5113495bSYour Name {
100*5113495bSYour Name 	struct pld_context *pld_context;
101*5113495bSYour Name 	int ret = 0;
102*5113495bSYour Name 
103*5113495bSYour Name 	pld_context = pld_get_global_context();
104*5113495bSYour Name 	if (!pld_context) {
105*5113495bSYour Name 		ret = -ENODEV;
106*5113495bSYour Name 		goto out;
107*5113495bSYour Name 	}
108*5113495bSYour Name 
109*5113495bSYour Name 	ret = pld_add_dev(pld_context, dev, NULL, PLD_BUS_TYPE_SNOC);
110*5113495bSYour Name 	if (ret)
111*5113495bSYour Name 		goto out;
112*5113495bSYour Name 
113*5113495bSYour Name 	return pld_context->ops->probe(dev, PLD_BUS_TYPE_SNOC,
114*5113495bSYour Name 				       NULL, NULL);
115*5113495bSYour Name 
116*5113495bSYour Name out:
117*5113495bSYour Name 	return ret;
118*5113495bSYour Name }
119*5113495bSYour Name 
120*5113495bSYour Name /**
121*5113495bSYour Name  * pld_snoc_remove() - Remove function for platform device
122*5113495bSYour Name  * @dev: device
123*5113495bSYour Name  *
124*5113495bSYour Name  * The remove function will be called when platform device
125*5113495bSYour Name  * is disconnected
126*5113495bSYour Name  *
127*5113495bSYour Name  * Return: void
128*5113495bSYour Name  */
pld_snoc_remove(struct device * dev)129*5113495bSYour Name static void pld_snoc_remove(struct device *dev)
130*5113495bSYour Name {
131*5113495bSYour Name 	struct pld_context *pld_context;
132*5113495bSYour Name 	int errno;
133*5113495bSYour Name 	struct osif_psoc_sync *psoc_sync;
134*5113495bSYour Name 
135*5113495bSYour Name 	errno = osif_psoc_sync_trans_start_wait(dev, &psoc_sync);
136*5113495bSYour Name 	if (errno)
137*5113495bSYour Name 		return;
138*5113495bSYour Name 
139*5113495bSYour Name 	osif_psoc_sync_unregister(dev);
140*5113495bSYour Name 	osif_psoc_sync_wait_for_ops(psoc_sync);
141*5113495bSYour Name 
142*5113495bSYour Name 	pld_context = pld_get_global_context();
143*5113495bSYour Name 
144*5113495bSYour Name 	if (!pld_context)
145*5113495bSYour Name 		goto out;
146*5113495bSYour Name 
147*5113495bSYour Name 	pld_context->ops->remove(dev, PLD_BUS_TYPE_SNOC);
148*5113495bSYour Name 
149*5113495bSYour Name 	pld_del_dev(pld_context, dev);
150*5113495bSYour Name 
151*5113495bSYour Name out:
152*5113495bSYour Name 	osif_psoc_sync_trans_stop(psoc_sync);
153*5113495bSYour Name 	osif_psoc_sync_destroy(psoc_sync);
154*5113495bSYour Name }
155*5113495bSYour Name 
156*5113495bSYour Name /**
157*5113495bSYour Name  * pld_snoc_reinit() - SSR re-initialize function for platform device
158*5113495bSYour Name  * @dev: device
159*5113495bSYour Name  *
160*5113495bSYour Name  * During subsystem restart(SSR), this function will be called to
161*5113495bSYour Name  * re-initialize platform device.
162*5113495bSYour Name  *
163*5113495bSYour Name  * Return: int
164*5113495bSYour Name  */
pld_snoc_reinit(struct device * dev)165*5113495bSYour Name static int pld_snoc_reinit(struct device *dev)
166*5113495bSYour Name {
167*5113495bSYour Name 	struct pld_context *pld_context;
168*5113495bSYour Name 
169*5113495bSYour Name 	pld_context = pld_get_global_context();
170*5113495bSYour Name 	if (pld_context->ops->reinit)
171*5113495bSYour Name 		return pld_context->ops->reinit(dev, PLD_BUS_TYPE_SNOC,
172*5113495bSYour Name 						NULL, NULL);
173*5113495bSYour Name 
174*5113495bSYour Name 	return -ENODEV;
175*5113495bSYour Name }
176*5113495bSYour Name 
177*5113495bSYour Name /**
178*5113495bSYour Name  * pld_snoc_shutdown() - SSR shutdown function for platform device
179*5113495bSYour Name  * @dev: device
180*5113495bSYour Name  *
181*5113495bSYour Name  * During SSR, this function will be called to shutdown platform device.
182*5113495bSYour Name  *
183*5113495bSYour Name  * Return: void
184*5113495bSYour Name  */
pld_snoc_shutdown(struct device * dev)185*5113495bSYour Name static void pld_snoc_shutdown(struct device *dev)
186*5113495bSYour Name {
187*5113495bSYour Name 	struct pld_context *pld_context;
188*5113495bSYour Name 
189*5113495bSYour Name 	pld_context = pld_get_global_context();
190*5113495bSYour Name 	if (pld_context->ops->shutdown)
191*5113495bSYour Name 		pld_context->ops->shutdown(dev, PLD_BUS_TYPE_SNOC);
192*5113495bSYour Name }
193*5113495bSYour Name 
194*5113495bSYour Name /**
195*5113495bSYour Name  * pld_snoc_crash_shutdown() - Crash shutdown function for platform device
196*5113495bSYour Name  * @dev: device
197*5113495bSYour Name  *
198*5113495bSYour Name  * This function will be called when a crash is detected, it will shutdown
199*5113495bSYour Name  * platform device.
200*5113495bSYour Name  *
201*5113495bSYour Name  * Return: void
202*5113495bSYour Name  */
pld_snoc_crash_shutdown(void * dev)203*5113495bSYour Name static void pld_snoc_crash_shutdown(void *dev)
204*5113495bSYour Name {
205*5113495bSYour Name 	struct pld_context *pld_context;
206*5113495bSYour Name 
207*5113495bSYour Name 	pld_context = pld_get_global_context();
208*5113495bSYour Name 	if (pld_context->ops->crash_shutdown)
209*5113495bSYour Name 		pld_context->ops->crash_shutdown(dev, PLD_BUS_TYPE_SNOC);
210*5113495bSYour Name }
211*5113495bSYour Name 
212*5113495bSYour Name /**
213*5113495bSYour Name  * pld_snoc_pm_suspend() - PM suspend callback function for power management
214*5113495bSYour Name  * @dev: device
215*5113495bSYour Name  *
216*5113495bSYour Name  * This function is to suspend the platform device when power management
217*5113495bSYour Name  * is enabled.
218*5113495bSYour Name  *
219*5113495bSYour Name  * Return: void
220*5113495bSYour Name  */
pld_snoc_pm_suspend(struct device * dev)221*5113495bSYour Name static int pld_snoc_pm_suspend(struct device *dev)
222*5113495bSYour Name {
223*5113495bSYour Name 	struct pld_context *pld_context;
224*5113495bSYour Name 	pm_message_t state;
225*5113495bSYour Name 
226*5113495bSYour Name 	state.event = PM_EVENT_SUSPEND;
227*5113495bSYour Name 	pld_context = pld_get_global_context();
228*5113495bSYour Name 	return pld_context->ops->suspend(dev, PLD_BUS_TYPE_SNOC, state);
229*5113495bSYour Name }
230*5113495bSYour Name 
231*5113495bSYour Name /**
232*5113495bSYour Name  * pld_snoc_pm_resume() - PM resume callback function for power management
233*5113495bSYour Name  * @dev: device
234*5113495bSYour Name  *
235*5113495bSYour Name  * This function is to resume the platform device when power management
236*5113495bSYour Name  * is enabled.
237*5113495bSYour Name  *
238*5113495bSYour Name  * Return: void
239*5113495bSYour Name  */
pld_snoc_pm_resume(struct device * dev)240*5113495bSYour Name static int pld_snoc_pm_resume(struct device *dev)
241*5113495bSYour Name {
242*5113495bSYour Name 	struct pld_context *pld_context;
243*5113495bSYour Name 
244*5113495bSYour Name 	pld_context = pld_get_global_context();
245*5113495bSYour Name 	return pld_context->ops->resume(dev, PLD_BUS_TYPE_SNOC);
246*5113495bSYour Name }
247*5113495bSYour Name 
248*5113495bSYour Name /**
249*5113495bSYour Name  * pld_snoc_suspend_noirq() - Complete the actions started by suspend()
250*5113495bSYour Name  * @dev: device
251*5113495bSYour Name  *
252*5113495bSYour Name  * Complete the actions started by suspend().  Carry out any
253*5113495bSYour Name  * additional operations required for suspending the device that might be
254*5113495bSYour Name  * racing with its driver's interrupt handler, which is guaranteed not to
255*5113495bSYour Name  * run while suspend_noirq() is being executed.
256*5113495bSYour Name  *
257*5113495bSYour Name  * Return: 0 for success
258*5113495bSYour Name  *         Non zero failure code for errors
259*5113495bSYour Name  */
pld_snoc_suspend_noirq(struct device * dev)260*5113495bSYour Name static int pld_snoc_suspend_noirq(struct device *dev)
261*5113495bSYour Name {
262*5113495bSYour Name 	struct pld_context *pld_context;
263*5113495bSYour Name 
264*5113495bSYour Name 	pld_context = pld_get_global_context();
265*5113495bSYour Name 	if (!pld_context)
266*5113495bSYour Name 		return -EINVAL;
267*5113495bSYour Name 
268*5113495bSYour Name 	if (pld_context->ops->suspend_noirq)
269*5113495bSYour Name 		return pld_context->ops->suspend_noirq(dev, PLD_BUS_TYPE_SNOC);
270*5113495bSYour Name 	return 0;
271*5113495bSYour Name }
272*5113495bSYour Name 
273*5113495bSYour Name /**
274*5113495bSYour Name  * pld_snoc_resume_noirq() - Prepare for the execution of resume()
275*5113495bSYour Name  * @dev: device
276*5113495bSYour Name  *
277*5113495bSYour Name  * Prepare for the execution of resume() by carrying out any
278*5113495bSYour Name  * operations required for resuming the device that might be racing with
279*5113495bSYour Name  * its driver's interrupt handler, which is guaranteed not to run while
280*5113495bSYour Name  * resume_noirq() is being executed.
281*5113495bSYour Name  *
282*5113495bSYour Name  * Return: 0 for success
283*5113495bSYour Name  *         Non zero failure code for errors
284*5113495bSYour Name  */
pld_snoc_resume_noirq(struct device * dev)285*5113495bSYour Name static int pld_snoc_resume_noirq(struct device *dev)
286*5113495bSYour Name {
287*5113495bSYour Name 	struct pld_context *pld_context;
288*5113495bSYour Name 
289*5113495bSYour Name 	pld_context = pld_get_global_context();
290*5113495bSYour Name 	if (!pld_context)
291*5113495bSYour Name 		return -EINVAL;
292*5113495bSYour Name 
293*5113495bSYour Name 	if (pld_context->ops->resume_noirq)
294*5113495bSYour Name 		return pld_context->ops->resume_noirq(dev, PLD_BUS_TYPE_SNOC);
295*5113495bSYour Name 
296*5113495bSYour Name 	return 0;
297*5113495bSYour Name }
298*5113495bSYour Name 
299*5113495bSYour Name #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
pld_update_hang_evt_data(struct icnss_uevent_hang_data * evt_data,struct pld_uevent_data * data)300*5113495bSYour Name static int pld_update_hang_evt_data(struct icnss_uevent_hang_data *evt_data,
301*5113495bSYour Name 				    struct pld_uevent_data *data)
302*5113495bSYour Name {
303*5113495bSYour Name 	if (!evt_data || !data)
304*5113495bSYour Name 		return -EINVAL;
305*5113495bSYour Name 
306*5113495bSYour Name 	data->hang_data.hang_event_data = evt_data->hang_event_data;
307*5113495bSYour Name 	data->hang_data.hang_event_data_len = evt_data->hang_event_data_len;
308*5113495bSYour Name 	return 0;
309*5113495bSYour Name }
310*5113495bSYour Name 
pld_snoc_uevent(struct device * dev,struct icnss_uevent_data * uevent)311*5113495bSYour Name static int pld_snoc_uevent(struct device *dev,
312*5113495bSYour Name 			   struct icnss_uevent_data *uevent)
313*5113495bSYour Name {
314*5113495bSYour Name 	struct pld_context *pld_context;
315*5113495bSYour Name 	struct icnss_uevent_fw_down_data *fw_down_data = NULL;
316*5113495bSYour Name 	struct icnss_uevent_hang_data *hang_data = NULL;
317*5113495bSYour Name 	struct pld_uevent_data data = {0};
318*5113495bSYour Name 
319*5113495bSYour Name 	pld_context = pld_get_global_context();
320*5113495bSYour Name 	if (!pld_context)
321*5113495bSYour Name 		return -EINVAL;
322*5113495bSYour Name 
323*5113495bSYour Name 	if (!pld_context->ops->uevent)
324*5113495bSYour Name 		goto out;
325*5113495bSYour Name 
326*5113495bSYour Name 	if (!uevent)
327*5113495bSYour Name 		return -EINVAL;
328*5113495bSYour Name 
329*5113495bSYour Name 	switch (uevent->uevent) {
330*5113495bSYour Name 	case ICNSS_UEVENT_FW_CRASHED:
331*5113495bSYour Name 		data.uevent = PLD_FW_CRASHED;
332*5113495bSYour Name 		break;
333*5113495bSYour Name 	case ICNSS_UEVENT_FW_DOWN:
334*5113495bSYour Name 		if (!uevent->data)
335*5113495bSYour Name 			return -EINVAL;
336*5113495bSYour Name 		fw_down_data = (struct icnss_uevent_fw_down_data *)uevent->data;
337*5113495bSYour Name 		data.uevent = PLD_FW_DOWN;
338*5113495bSYour Name 		data.fw_down.crashed = fw_down_data->crashed;
339*5113495bSYour Name 		break;
340*5113495bSYour Name 	case ICNSS_UEVENT_HANG_DATA:
341*5113495bSYour Name 		if (!uevent->data)
342*5113495bSYour Name 			return -EINVAL;
343*5113495bSYour Name 		hang_data = (struct icnss_uevent_hang_data *)uevent->data;
344*5113495bSYour Name 		data.uevent = PLD_FW_HANG_EVENT;
345*5113495bSYour Name 		pld_update_hang_evt_data(hang_data, &data);
346*5113495bSYour Name 		break;
347*5113495bSYour Name 	default:
348*5113495bSYour Name 		goto out;
349*5113495bSYour Name 	}
350*5113495bSYour Name 
351*5113495bSYour Name 	pld_context->ops->uevent(dev, &data);
352*5113495bSYour Name out:
353*5113495bSYour Name 	return 0;
354*5113495bSYour Name }
355*5113495bSYour Name #else
pld_snoc_uevent(struct device * dev,struct icnss_uevent_data * uevent)356*5113495bSYour Name static int pld_snoc_uevent(struct device *dev,
357*5113495bSYour Name 			   struct icnss_uevent_data *uevent)
358*5113495bSYour Name {
359*5113495bSYour Name 	struct pld_context *pld_context;
360*5113495bSYour Name 	struct icnss_uevent_fw_down_data *fw_down_data = NULL;
361*5113495bSYour Name 	struct pld_uevent_data data = {0};
362*5113495bSYour Name 
363*5113495bSYour Name 	pld_context = pld_get_global_context();
364*5113495bSYour Name 	if (!pld_context)
365*5113495bSYour Name 		return -EINVAL;
366*5113495bSYour Name 
367*5113495bSYour Name 	if (!pld_context->ops->uevent)
368*5113495bSYour Name 		goto out;
369*5113495bSYour Name 
370*5113495bSYour Name 	if (!uevent)
371*5113495bSYour Name 		return -EINVAL;
372*5113495bSYour Name 
373*5113495bSYour Name 	switch (uevent->uevent) {
374*5113495bSYour Name 	case ICNSS_UEVENT_FW_CRASHED:
375*5113495bSYour Name 		data.uevent = PLD_FW_CRASHED;
376*5113495bSYour Name 		break;
377*5113495bSYour Name 	case ICNSS_UEVENT_FW_DOWN:
378*5113495bSYour Name 		if (!uevent->data)
379*5113495bSYour Name 			return -EINVAL;
380*5113495bSYour Name 		fw_down_data = (struct icnss_uevent_fw_down_data *)uevent->data;
381*5113495bSYour Name 		data.uevent = PLD_FW_DOWN;
382*5113495bSYour Name 		data.fw_down.crashed = fw_down_data->crashed;
383*5113495bSYour Name 		break;
384*5113495bSYour Name 	default:
385*5113495bSYour Name 		goto out;
386*5113495bSYour Name 	}
387*5113495bSYour Name 
388*5113495bSYour Name 	pld_context->ops->uevent(dev, &data);
389*5113495bSYour Name out:
390*5113495bSYour Name 	return 0;
391*5113495bSYour Name }
392*5113495bSYour Name #endif
393*5113495bSYour Name 
394*5113495bSYour Name #ifdef MULTI_IF_NAME
395*5113495bSYour Name #define PLD_SNOC_OPS_NAME "pld_snoc_" MULTI_IF_NAME
396*5113495bSYour Name #else
397*5113495bSYour Name #define PLD_SNOC_OPS_NAME "pld_snoc"
398*5113495bSYour Name #endif
399*5113495bSYour Name 
400*5113495bSYour Name #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0))
401*5113495bSYour Name static struct device_info pld_snoc_dev_info[] = {
402*5113495bSYour Name 	{ "ADRASTEA", ADRASTEA_DEVICE_ID },
403*5113495bSYour Name 	{ 0 }
404*5113495bSYour Name };
405*5113495bSYour Name #endif
406*5113495bSYour Name 
407*5113495bSYour Name struct icnss_driver_ops pld_snoc_ops = {
408*5113495bSYour Name 	.name       = PLD_SNOC_OPS_NAME,
409*5113495bSYour Name #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0))
410*5113495bSYour Name 	.dev_info   = pld_snoc_dev_info,
411*5113495bSYour Name #endif
412*5113495bSYour Name 	.probe      = pld_snoc_probe,
413*5113495bSYour Name 	.remove     = pld_snoc_remove,
414*5113495bSYour Name 	.shutdown   = pld_snoc_shutdown,
415*5113495bSYour Name 	.reinit     = pld_snoc_reinit,
416*5113495bSYour Name 	.crash_shutdown = pld_snoc_crash_shutdown,
417*5113495bSYour Name 	.pm_suspend = pld_snoc_pm_suspend,
418*5113495bSYour Name 	.pm_resume  = pld_snoc_pm_resume,
419*5113495bSYour Name 	.suspend_noirq = pld_snoc_suspend_noirq,
420*5113495bSYour Name 	.resume_noirq = pld_snoc_resume_noirq,
421*5113495bSYour Name 	.uevent = pld_snoc_uevent,
422*5113495bSYour Name 	.idle_restart  = pld_snoc_idle_restart_cb,
423*5113495bSYour Name 	.idle_shutdown = pld_snoc_idle_shutdown_cb,
424*5113495bSYour Name };
425*5113495bSYour Name 
pld_snoc_register_driver(void)426*5113495bSYour Name int pld_snoc_register_driver(void)
427*5113495bSYour Name {
428*5113495bSYour Name 	return icnss_register_driver(&pld_snoc_ops);
429*5113495bSYour Name }
430*5113495bSYour Name 
pld_snoc_unregister_driver(void)431*5113495bSYour Name void pld_snoc_unregister_driver(void)
432*5113495bSYour Name {
433*5113495bSYour Name 	icnss_unregister_driver(&pld_snoc_ops);
434*5113495bSYour Name }
435*5113495bSYour Name 
pld_snoc_wlan_enable(struct device * dev,struct pld_wlan_enable_cfg * config,enum pld_driver_mode mode,const char * host_version)436*5113495bSYour Name int pld_snoc_wlan_enable(struct device *dev, struct pld_wlan_enable_cfg *config,
437*5113495bSYour Name 			 enum pld_driver_mode mode, const char *host_version)
438*5113495bSYour Name {
439*5113495bSYour Name 	struct icnss_wlan_enable_cfg cfg;
440*5113495bSYour Name 	enum icnss_driver_mode icnss_mode;
441*5113495bSYour Name 
442*5113495bSYour Name 	if (!dev)
443*5113495bSYour Name 		return -ENODEV;
444*5113495bSYour Name 
445*5113495bSYour Name 	cfg.num_ce_tgt_cfg = config->num_ce_tgt_cfg;
446*5113495bSYour Name 	cfg.ce_tgt_cfg = (struct ce_tgt_pipe_cfg *)
447*5113495bSYour Name 		config->ce_tgt_cfg;
448*5113495bSYour Name 	cfg.num_ce_svc_pipe_cfg = config->num_ce_svc_pipe_cfg;
449*5113495bSYour Name 	cfg.ce_svc_cfg = (struct ce_svc_pipe_cfg *)
450*5113495bSYour Name 		config->ce_svc_cfg;
451*5113495bSYour Name 	cfg.num_shadow_reg_cfg = config->num_shadow_reg_cfg;
452*5113495bSYour Name 	cfg.shadow_reg_cfg = (struct icnss_shadow_reg_cfg *)
453*5113495bSYour Name 		config->shadow_reg_cfg;
454*5113495bSYour Name 
455*5113495bSYour Name 	switch (mode) {
456*5113495bSYour Name 	case PLD_FTM:
457*5113495bSYour Name 		icnss_mode = ICNSS_FTM;
458*5113495bSYour Name 		break;
459*5113495bSYour Name 	case PLD_EPPING:
460*5113495bSYour Name 		icnss_mode = ICNSS_EPPING;
461*5113495bSYour Name 		break;
462*5113495bSYour Name 	default:
463*5113495bSYour Name 		icnss_mode = ICNSS_MISSION;
464*5113495bSYour Name 		break;
465*5113495bSYour Name 	}
466*5113495bSYour Name 
467*5113495bSYour Name 	return icnss_wlan_enable(dev, &cfg, icnss_mode, host_version);
468*5113495bSYour Name }
469*5113495bSYour Name 
pld_snoc_wlan_disable(struct device * dev,enum pld_driver_mode mode)470*5113495bSYour Name int pld_snoc_wlan_disable(struct device *dev, enum pld_driver_mode mode)
471*5113495bSYour Name {
472*5113495bSYour Name 	if (!dev)
473*5113495bSYour Name 		return -ENODEV;
474*5113495bSYour Name 
475*5113495bSYour Name 	return icnss_wlan_disable(dev, ICNSS_OFF);
476*5113495bSYour Name }
477*5113495bSYour Name 
pld_snoc_get_soc_info(struct device * dev,struct pld_soc_info * info)478*5113495bSYour Name int pld_snoc_get_soc_info(struct device *dev, struct pld_soc_info *info)
479*5113495bSYour Name {
480*5113495bSYour Name 	int errno;
481*5113495bSYour Name 	struct icnss_soc_info icnss_info = {0};
482*5113495bSYour Name 
483*5113495bSYour Name 	if (!info || !dev)
484*5113495bSYour Name 		return -ENODEV;
485*5113495bSYour Name 
486*5113495bSYour Name 	errno = icnss_get_soc_info(dev, &icnss_info);
487*5113495bSYour Name 	if (errno)
488*5113495bSYour Name 		return errno;
489*5113495bSYour Name 
490*5113495bSYour Name 	info->v_addr = icnss_info.v_addr;
491*5113495bSYour Name 	info->p_addr = icnss_info.p_addr;
492*5113495bSYour Name 	info->chip_id = icnss_info.chip_id;
493*5113495bSYour Name 	info->chip_family = icnss_info.chip_family;
494*5113495bSYour Name 	info->board_id = icnss_info.board_id;
495*5113495bSYour Name 	info->soc_id = icnss_info.soc_id;
496*5113495bSYour Name 	info->fw_version = icnss_info.fw_version;
497*5113495bSYour Name 	strlcpy(info->fw_build_timestamp, icnss_info.fw_build_timestamp,
498*5113495bSYour Name 		sizeof(info->fw_build_timestamp));
499*5113495bSYour Name 
500*5113495bSYour Name 	return 0;
501*5113495bSYour Name }
502*5113495bSYour Name #endif
503