xref: /OK3568_Linux_fs/u-boot/drivers/remoteproc/rproc-uclass.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * (C) Copyright 2015
3*4882a593Smuzhiyun  * Texas Instruments Incorporated - http://www.ti.com/
4*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun #define pr_fmt(fmt) "%s: " fmt, __func__
7*4882a593Smuzhiyun #include <common.h>
8*4882a593Smuzhiyun #include <errno.h>
9*4882a593Smuzhiyun #include <fdtdec.h>
10*4882a593Smuzhiyun #include <malloc.h>
11*4882a593Smuzhiyun #include <remoteproc.h>
12*4882a593Smuzhiyun #include <asm/io.h>
13*4882a593Smuzhiyun #include <dm/device-internal.h>
14*4882a593Smuzhiyun #include <dm.h>
15*4882a593Smuzhiyun #include <dm/uclass.h>
16*4882a593Smuzhiyun #include <dm/uclass-internal.h>
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun /**
21*4882a593Smuzhiyun  * for_each_remoteproc_device() - iterate through the list of rproc devices
22*4882a593Smuzhiyun  * @fn: check function to call per match, if this function returns fail,
23*4882a593Smuzhiyun  *	iteration is aborted with the resultant error value
24*4882a593Smuzhiyun  * @skip_dev:	Device to skip calling the callback about.
25*4882a593Smuzhiyun  * @data:	Data to pass to the callback function
26*4882a593Smuzhiyun  *
27*4882a593Smuzhiyun  * Return: 0 if none of the callback returned a non 0 result, else returns the
28*4882a593Smuzhiyun  * result from the callback function
29*4882a593Smuzhiyun  */
for_each_remoteproc_device(int (* fn)(struct udevice * dev,struct dm_rproc_uclass_pdata * uc_pdata,const void * data),struct udevice * skip_dev,const void * data)30*4882a593Smuzhiyun static int for_each_remoteproc_device(int (*fn) (struct udevice *dev,
31*4882a593Smuzhiyun 					struct dm_rproc_uclass_pdata *uc_pdata,
32*4882a593Smuzhiyun 					const void *data),
33*4882a593Smuzhiyun 				      struct udevice *skip_dev,
34*4882a593Smuzhiyun 				      const void *data)
35*4882a593Smuzhiyun {
36*4882a593Smuzhiyun 	struct udevice *dev;
37*4882a593Smuzhiyun 	struct dm_rproc_uclass_pdata *uc_pdata;
38*4882a593Smuzhiyun 	int ret;
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun 	for (ret = uclass_find_first_device(UCLASS_REMOTEPROC, &dev); dev;
41*4882a593Smuzhiyun 	     ret = uclass_find_next_device(&dev)) {
42*4882a593Smuzhiyun 		if (ret || dev == skip_dev)
43*4882a593Smuzhiyun 			continue;
44*4882a593Smuzhiyun 		uc_pdata = dev_get_uclass_platdata(dev);
45*4882a593Smuzhiyun 		ret = fn(dev, uc_pdata, data);
46*4882a593Smuzhiyun 		if (ret)
47*4882a593Smuzhiyun 			return ret;
48*4882a593Smuzhiyun 	}
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 	return 0;
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun /**
54*4882a593Smuzhiyun  * _rproc_name_is_unique() - iteration helper to check if rproc name is unique
55*4882a593Smuzhiyun  * @dev:	device that we are checking name for
56*4882a593Smuzhiyun  * @uc_pdata:	uclass platform data
57*4882a593Smuzhiyun  * @data:	compare data (this is the name we want to ensure is unique)
58*4882a593Smuzhiyun  *
59*4882a593Smuzhiyun  * Return: 0 is there is no match(is unique); if there is a match(we dont
60*4882a593Smuzhiyun  * have a unique name), return -EINVAL.
61*4882a593Smuzhiyun  */
_rproc_name_is_unique(struct udevice * dev,struct dm_rproc_uclass_pdata * uc_pdata,const void * data)62*4882a593Smuzhiyun static int _rproc_name_is_unique(struct udevice *dev,
63*4882a593Smuzhiyun 				 struct dm_rproc_uclass_pdata *uc_pdata,
64*4882a593Smuzhiyun 				 const void *data)
65*4882a593Smuzhiyun {
66*4882a593Smuzhiyun 	const char *check_name = data;
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun 	/* devices not yet populated with data - so skip them */
69*4882a593Smuzhiyun 	if (!uc_pdata->name || !check_name)
70*4882a593Smuzhiyun 		return 0;
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 	/* Return 0 to search further if we dont match */
73*4882a593Smuzhiyun 	if (strlen(uc_pdata->name) != strlen(check_name))
74*4882a593Smuzhiyun 		return 0;
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	if (!strcmp(uc_pdata->name, check_name))
77*4882a593Smuzhiyun 		return -EINVAL;
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun 	return 0;
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun /**
83*4882a593Smuzhiyun  * rproc_name_is_unique() - Check if the rproc name is unique
84*4882a593Smuzhiyun  * @check_dev:	Device we are attempting to ensure is unique
85*4882a593Smuzhiyun  * @check_name:	Name we are trying to ensure is unique.
86*4882a593Smuzhiyun  *
87*4882a593Smuzhiyun  * Return: true if we have a unique name, false if name is not unique.
88*4882a593Smuzhiyun  */
rproc_name_is_unique(struct udevice * check_dev,const char * check_name)89*4882a593Smuzhiyun static bool rproc_name_is_unique(struct udevice *check_dev,
90*4882a593Smuzhiyun 				 const char *check_name)
91*4882a593Smuzhiyun {
92*4882a593Smuzhiyun 	int ret;
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	ret = for_each_remoteproc_device(_rproc_name_is_unique,
95*4882a593Smuzhiyun 					 check_dev, check_name);
96*4882a593Smuzhiyun 	return ret ? false : true;
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun /**
100*4882a593Smuzhiyun  * rproc_pre_probe() - Pre probe accessor for the uclass
101*4882a593Smuzhiyun  * @dev:	device for which we are preprobing
102*4882a593Smuzhiyun  *
103*4882a593Smuzhiyun  * Parses and fills up the uclass pdata for use as needed by core and
104*4882a593Smuzhiyun  * remote proc drivers.
105*4882a593Smuzhiyun  *
106*4882a593Smuzhiyun  * Return: 0 if all wernt ok, else appropriate error value.
107*4882a593Smuzhiyun  */
rproc_pre_probe(struct udevice * dev)108*4882a593Smuzhiyun static int rproc_pre_probe(struct udevice *dev)
109*4882a593Smuzhiyun {
110*4882a593Smuzhiyun 	struct dm_rproc_uclass_pdata *uc_pdata;
111*4882a593Smuzhiyun 	const struct dm_rproc_ops *ops;
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun 	uc_pdata = dev_get_uclass_platdata(dev);
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun 	/* See if we need to populate via fdt */
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 	if (!dev->platdata) {
118*4882a593Smuzhiyun #if CONFIG_IS_ENABLED(OF_CONTROL)
119*4882a593Smuzhiyun 		int node = dev_of_offset(dev);
120*4882a593Smuzhiyun 		const void *blob = gd->fdt_blob;
121*4882a593Smuzhiyun 		bool tmp;
122*4882a593Smuzhiyun 		if (!blob) {
123*4882a593Smuzhiyun 			debug("'%s' no dt?\n", dev->name);
124*4882a593Smuzhiyun 			return -EINVAL;
125*4882a593Smuzhiyun 		}
126*4882a593Smuzhiyun 		debug("'%s': using fdt\n", dev->name);
127*4882a593Smuzhiyun 		uc_pdata->name = fdt_getprop(blob, node,
128*4882a593Smuzhiyun 					     "remoteproc-name", NULL);
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 		/* Default is internal memory mapped */
131*4882a593Smuzhiyun 		uc_pdata->mem_type = RPROC_INTERNAL_MEMORY_MAPPED;
132*4882a593Smuzhiyun 		tmp = fdtdec_get_bool(blob, node,
133*4882a593Smuzhiyun 				      "remoteproc-internal-memory-mapped");
134*4882a593Smuzhiyun 		if (tmp)
135*4882a593Smuzhiyun 			uc_pdata->mem_type = RPROC_INTERNAL_MEMORY_MAPPED;
136*4882a593Smuzhiyun #else
137*4882a593Smuzhiyun 		/* Nothing much we can do about this, can we? */
138*4882a593Smuzhiyun 		return -EINVAL;
139*4882a593Smuzhiyun #endif
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	} else {
142*4882a593Smuzhiyun 		struct dm_rproc_uclass_pdata *pdata = dev->platdata;
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun 		debug("'%s': using legacy data\n", dev->name);
145*4882a593Smuzhiyun 		if (pdata->name)
146*4882a593Smuzhiyun 			uc_pdata->name = pdata->name;
147*4882a593Smuzhiyun 		uc_pdata->mem_type = pdata->mem_type;
148*4882a593Smuzhiyun 		uc_pdata->driver_plat_data = pdata->driver_plat_data;
149*4882a593Smuzhiyun 	}
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	/* Else try using device Name */
152*4882a593Smuzhiyun 	if (!uc_pdata->name)
153*4882a593Smuzhiyun 		uc_pdata->name = dev->name;
154*4882a593Smuzhiyun 	if (!uc_pdata->name) {
155*4882a593Smuzhiyun 		debug("Unnamed device!");
156*4882a593Smuzhiyun 		return -EINVAL;
157*4882a593Smuzhiyun 	}
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 	if (!rproc_name_is_unique(dev, uc_pdata->name)) {
160*4882a593Smuzhiyun 		debug("%s duplicate name '%s'\n", dev->name, uc_pdata->name);
161*4882a593Smuzhiyun 		return -EINVAL;
162*4882a593Smuzhiyun 	}
163*4882a593Smuzhiyun 
164*4882a593Smuzhiyun 	ops = rproc_get_ops(dev);
165*4882a593Smuzhiyun 	if (!ops) {
166*4882a593Smuzhiyun 		debug("%s driver has no ops?\n", dev->name);
167*4882a593Smuzhiyun 		return -EINVAL;
168*4882a593Smuzhiyun 	}
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun 	if (!ops->load || !ops->start) {
171*4882a593Smuzhiyun 		debug("%s driver has missing mandatory ops?\n", dev->name);
172*4882a593Smuzhiyun 		return -EINVAL;
173*4882a593Smuzhiyun 	}
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	return 0;
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun /**
179*4882a593Smuzhiyun  * rproc_post_probe() - post probe accessor for the uclass
180*4882a593Smuzhiyun  * @dev:	deivce we finished probing
181*4882a593Smuzhiyun  *
182*4882a593Smuzhiyun  * initiate init function after the probe is completed. This allows
183*4882a593Smuzhiyun  * the remote processor drivers to split up the initializations between
184*4882a593Smuzhiyun  * probe and init as needed.
185*4882a593Smuzhiyun  *
186*4882a593Smuzhiyun  * Return: if the remote proc driver has a init routine, invokes it and
187*4882a593Smuzhiyun  * hands over the return value. overall, 0 if all went well, else appropriate
188*4882a593Smuzhiyun  * error value.
189*4882a593Smuzhiyun  */
rproc_post_probe(struct udevice * dev)190*4882a593Smuzhiyun static int rproc_post_probe(struct udevice *dev)
191*4882a593Smuzhiyun {
192*4882a593Smuzhiyun 	const struct dm_rproc_ops *ops;
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	ops = rproc_get_ops(dev);
195*4882a593Smuzhiyun 	if (!ops) {
196*4882a593Smuzhiyun 		debug("%s driver has no ops?\n", dev->name);
197*4882a593Smuzhiyun 		return -EINVAL;
198*4882a593Smuzhiyun 	}
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	if (ops->init)
201*4882a593Smuzhiyun 		return ops->init(dev);
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 	return 0;
204*4882a593Smuzhiyun }
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun UCLASS_DRIVER(rproc) = {
207*4882a593Smuzhiyun 	.id = UCLASS_REMOTEPROC,
208*4882a593Smuzhiyun 	.name = "remoteproc",
209*4882a593Smuzhiyun 	.flags = DM_UC_FLAG_SEQ_ALIAS,
210*4882a593Smuzhiyun 	.pre_probe = rproc_pre_probe,
211*4882a593Smuzhiyun 	.post_probe = rproc_post_probe,
212*4882a593Smuzhiyun 	.per_device_platdata_auto_alloc_size =
213*4882a593Smuzhiyun 		sizeof(struct dm_rproc_uclass_pdata),
214*4882a593Smuzhiyun };
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun /* Remoteproc subsystem access functions */
217*4882a593Smuzhiyun /**
218*4882a593Smuzhiyun  * _rproc_probe_dev() - iteration helper to probe a rproc device
219*4882a593Smuzhiyun  * @dev:	device to probe
220*4882a593Smuzhiyun  * @uc_pdata:	uclass data allocated for the device
221*4882a593Smuzhiyun  * @data:	unused
222*4882a593Smuzhiyun  *
223*4882a593Smuzhiyun  * Return: 0 if all ok, else appropriate error value.
224*4882a593Smuzhiyun  */
_rproc_probe_dev(struct udevice * dev,struct dm_rproc_uclass_pdata * uc_pdata,const void * data)225*4882a593Smuzhiyun static int _rproc_probe_dev(struct udevice *dev,
226*4882a593Smuzhiyun 			    struct dm_rproc_uclass_pdata *uc_pdata,
227*4882a593Smuzhiyun 			    const void *data)
228*4882a593Smuzhiyun {
229*4882a593Smuzhiyun 	int ret;
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun 	ret = device_probe(dev);
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 	if (ret)
234*4882a593Smuzhiyun 		debug("%s: Failed to initialize - %d\n", dev->name, ret);
235*4882a593Smuzhiyun 	return ret;
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun /**
239*4882a593Smuzhiyun  * _rproc_dev_is_probed() - check if the device has been probed
240*4882a593Smuzhiyun  * @dev:	device to check
241*4882a593Smuzhiyun  * @uc_pdata:	unused
242*4882a593Smuzhiyun  * @data:	unused
243*4882a593Smuzhiyun  *
244*4882a593Smuzhiyun  * Return: -EAGAIN if not probed else return 0
245*4882a593Smuzhiyun  */
_rproc_dev_is_probed(struct udevice * dev,struct dm_rproc_uclass_pdata * uc_pdata,const void * data)246*4882a593Smuzhiyun static int _rproc_dev_is_probed(struct udevice *dev,
247*4882a593Smuzhiyun 			    struct dm_rproc_uclass_pdata *uc_pdata,
248*4882a593Smuzhiyun 			    const void *data)
249*4882a593Smuzhiyun {
250*4882a593Smuzhiyun 	if (dev->flags & DM_FLAG_ACTIVATED)
251*4882a593Smuzhiyun 		return 0;
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	return -EAGAIN;
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun 
rproc_is_initialized(void)256*4882a593Smuzhiyun bool rproc_is_initialized(void)
257*4882a593Smuzhiyun {
258*4882a593Smuzhiyun 	int ret = for_each_remoteproc_device(_rproc_dev_is_probed, NULL, NULL);
259*4882a593Smuzhiyun 	return ret ? false : true;
260*4882a593Smuzhiyun }
261*4882a593Smuzhiyun 
rproc_init(void)262*4882a593Smuzhiyun int rproc_init(void)
263*4882a593Smuzhiyun {
264*4882a593Smuzhiyun 	int ret;
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 	if (rproc_is_initialized()) {
267*4882a593Smuzhiyun 		debug("Already initialized\n");
268*4882a593Smuzhiyun 		return -EINVAL;
269*4882a593Smuzhiyun 	}
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun 	ret = for_each_remoteproc_device(_rproc_probe_dev, NULL, NULL);
272*4882a593Smuzhiyun 	return ret;
273*4882a593Smuzhiyun }
274*4882a593Smuzhiyun 
rproc_load(int id,ulong addr,ulong size)275*4882a593Smuzhiyun int rproc_load(int id, ulong addr, ulong size)
276*4882a593Smuzhiyun {
277*4882a593Smuzhiyun 	struct udevice *dev = NULL;
278*4882a593Smuzhiyun 	struct dm_rproc_uclass_pdata *uc_pdata;
279*4882a593Smuzhiyun 	const struct dm_rproc_ops *ops;
280*4882a593Smuzhiyun 	int ret;
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun 	ret = uclass_get_device_by_seq(UCLASS_REMOTEPROC, id, &dev);
283*4882a593Smuzhiyun 	if (ret) {
284*4882a593Smuzhiyun 		debug("Unknown remote processor id '%d' requested(%d)\n",
285*4882a593Smuzhiyun 		      id, ret);
286*4882a593Smuzhiyun 		return ret;
287*4882a593Smuzhiyun 	}
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun 	uc_pdata = dev_get_uclass_platdata(dev);
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun 	ops = rproc_get_ops(dev);
292*4882a593Smuzhiyun 	if (!ops) {
293*4882a593Smuzhiyun 		debug("%s driver has no ops?\n", dev->name);
294*4882a593Smuzhiyun 		return -EINVAL;
295*4882a593Smuzhiyun 	}
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun 	debug("Loading to '%s' from address 0x%08lX size of %lu bytes\n",
298*4882a593Smuzhiyun 	      uc_pdata->name, addr, size);
299*4882a593Smuzhiyun 	if (ops->load)
300*4882a593Smuzhiyun 		return ops->load(dev, addr, size);
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	debug("%s: data corruption?? mandatory function is missing!\n",
303*4882a593Smuzhiyun 	      dev->name);
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 	return -EINVAL;
306*4882a593Smuzhiyun };
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun /*
309*4882a593Smuzhiyun  * Completely internal helper enums..
310*4882a593Smuzhiyun  * Keeping this isolated helps this code evolve independent of other
311*4882a593Smuzhiyun  * parts..
312*4882a593Smuzhiyun  */
313*4882a593Smuzhiyun enum rproc_ops {
314*4882a593Smuzhiyun 	RPROC_START,
315*4882a593Smuzhiyun 	RPROC_STOP,
316*4882a593Smuzhiyun 	RPROC_RESET,
317*4882a593Smuzhiyun 	RPROC_PING,
318*4882a593Smuzhiyun 	RPROC_RUNNING,
319*4882a593Smuzhiyun };
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun /**
322*4882a593Smuzhiyun  * _rproc_ops_wrapper() - wrapper for invoking remote proc driver callback
323*4882a593Smuzhiyun  * @id:		id of the remote processor
324*4882a593Smuzhiyun  * @op:		one of rproc_ops that indicate what operation to invoke
325*4882a593Smuzhiyun  *
326*4882a593Smuzhiyun  * Most of the checks and verification for remoteproc operations are more
327*4882a593Smuzhiyun  * or less same for almost all operations. This allows us to put a wrapper
328*4882a593Smuzhiyun  * and use the common checks to allow the driver to function appropriately.
329*4882a593Smuzhiyun  *
330*4882a593Smuzhiyun  * Return: 0 if all ok, else appropriate error value.
331*4882a593Smuzhiyun  */
_rproc_ops_wrapper(int id,enum rproc_ops op)332*4882a593Smuzhiyun static int _rproc_ops_wrapper(int id, enum rproc_ops op)
333*4882a593Smuzhiyun {
334*4882a593Smuzhiyun 	struct udevice *dev = NULL;
335*4882a593Smuzhiyun 	struct dm_rproc_uclass_pdata *uc_pdata;
336*4882a593Smuzhiyun 	const struct dm_rproc_ops *ops;
337*4882a593Smuzhiyun 	int (*fn)(struct udevice *dev);
338*4882a593Smuzhiyun 	bool mandatory = false;
339*4882a593Smuzhiyun 	char *op_str;
340*4882a593Smuzhiyun 	int ret;
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 	ret = uclass_get_device_by_seq(UCLASS_REMOTEPROC, id, &dev);
343*4882a593Smuzhiyun 	if (ret) {
344*4882a593Smuzhiyun 		debug("Unknown remote processor id '%d' requested(%d)\n",
345*4882a593Smuzhiyun 		      id, ret);
346*4882a593Smuzhiyun 		return ret;
347*4882a593Smuzhiyun 	}
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun 	uc_pdata = dev_get_uclass_platdata(dev);
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun 	ops = rproc_get_ops(dev);
352*4882a593Smuzhiyun 	if (!ops) {
353*4882a593Smuzhiyun 		debug("%s driver has no ops?\n", dev->name);
354*4882a593Smuzhiyun 		return -EINVAL;
355*4882a593Smuzhiyun 	}
356*4882a593Smuzhiyun 	switch (op) {
357*4882a593Smuzhiyun 	case RPROC_START:
358*4882a593Smuzhiyun 		fn = ops->start;
359*4882a593Smuzhiyun 		mandatory = true;
360*4882a593Smuzhiyun 		op_str = "Starting";
361*4882a593Smuzhiyun 		break;
362*4882a593Smuzhiyun 	case RPROC_STOP:
363*4882a593Smuzhiyun 		fn = ops->stop;
364*4882a593Smuzhiyun 		op_str = "Stopping";
365*4882a593Smuzhiyun 		break;
366*4882a593Smuzhiyun 	case RPROC_RESET:
367*4882a593Smuzhiyun 		fn = ops->reset;
368*4882a593Smuzhiyun 		op_str = "Resetting";
369*4882a593Smuzhiyun 		break;
370*4882a593Smuzhiyun 	case RPROC_RUNNING:
371*4882a593Smuzhiyun 		fn = ops->is_running;
372*4882a593Smuzhiyun 		op_str = "Checking if running:";
373*4882a593Smuzhiyun 		break;
374*4882a593Smuzhiyun 	case RPROC_PING:
375*4882a593Smuzhiyun 		fn = ops->ping;
376*4882a593Smuzhiyun 		op_str = "Pinging";
377*4882a593Smuzhiyun 		break;
378*4882a593Smuzhiyun 	default:
379*4882a593Smuzhiyun 		debug("what is '%d' operation??\n", op);
380*4882a593Smuzhiyun 		return -EINVAL;
381*4882a593Smuzhiyun 	}
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 	debug("%s %s...\n", op_str, uc_pdata->name);
384*4882a593Smuzhiyun 	if (fn)
385*4882a593Smuzhiyun 		return fn(dev);
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun 	if (mandatory)
388*4882a593Smuzhiyun 		debug("%s: data corruption?? mandatory function is missing!\n",
389*4882a593Smuzhiyun 		      dev->name);
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 	return -ENOSYS;
392*4882a593Smuzhiyun }
393*4882a593Smuzhiyun 
rproc_start(int id)394*4882a593Smuzhiyun int rproc_start(int id)
395*4882a593Smuzhiyun {
396*4882a593Smuzhiyun 	return _rproc_ops_wrapper(id, RPROC_START);
397*4882a593Smuzhiyun };
398*4882a593Smuzhiyun 
rproc_stop(int id)399*4882a593Smuzhiyun int rproc_stop(int id)
400*4882a593Smuzhiyun {
401*4882a593Smuzhiyun 	return _rproc_ops_wrapper(id, RPROC_STOP);
402*4882a593Smuzhiyun };
403*4882a593Smuzhiyun 
rproc_reset(int id)404*4882a593Smuzhiyun int rproc_reset(int id)
405*4882a593Smuzhiyun {
406*4882a593Smuzhiyun 	return _rproc_ops_wrapper(id, RPROC_RESET);
407*4882a593Smuzhiyun };
408*4882a593Smuzhiyun 
rproc_ping(int id)409*4882a593Smuzhiyun int rproc_ping(int id)
410*4882a593Smuzhiyun {
411*4882a593Smuzhiyun 	return _rproc_ops_wrapper(id, RPROC_PING);
412*4882a593Smuzhiyun };
413*4882a593Smuzhiyun 
rproc_is_running(int id)414*4882a593Smuzhiyun int rproc_is_running(int id)
415*4882a593Smuzhiyun {
416*4882a593Smuzhiyun 	return _rproc_ops_wrapper(id, RPROC_RUNNING);
417*4882a593Smuzhiyun };
418