1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Greybus Firmware Management Protocol Driver.
4  *
5  * Copyright 2016 Google Inc.
6  * Copyright 2016 Linaro Ltd.
7  */
8 
9 #include <linux/cdev.h>
10 #include <linux/completion.h>
11 #include <linux/firmware.h>
12 #include <linux/fs.h>
13 #include <linux/idr.h>
14 #include <linux/ioctl.h>
15 #include <linux/uaccess.h>
16 #include <linux/greybus.h>
17 
18 #include "firmware.h"
19 #include "greybus_firmware.h"
20 
21 #define FW_MGMT_TIMEOUT_MS		1000
22 
23 struct fw_mgmt {
24 	struct device		*parent;
25 	struct gb_connection	*connection;
26 	struct kref		kref;
27 	struct list_head	node;
28 
29 	/* Common id-map for interface and backend firmware requests */
30 	struct ida		id_map;
31 	struct mutex		mutex;
32 	struct completion	completion;
33 	struct cdev		cdev;
34 	struct device		*class_device;
35 	dev_t			dev_num;
36 	unsigned int		timeout_jiffies;
37 	bool			disabled; /* connection getting disabled */
38 
39 	/* Interface Firmware specific fields */
40 	bool			mode_switch_started;
41 	bool			intf_fw_loaded;
42 	u8			intf_fw_request_id;
43 	u8			intf_fw_status;
44 	u16			intf_fw_major;
45 	u16			intf_fw_minor;
46 
47 	/* Backend Firmware specific fields */
48 	u8			backend_fw_request_id;
49 	u8			backend_fw_status;
50 };
51 
52 /*
53  * Number of minor devices this driver supports.
54  * There will be exactly one required per Interface.
55  */
56 #define NUM_MINORS		U8_MAX
57 
58 static struct class *fw_mgmt_class;
59 static dev_t fw_mgmt_dev_num;
60 static DEFINE_IDA(fw_mgmt_minors_map);
61 static LIST_HEAD(fw_mgmt_list);
62 static DEFINE_MUTEX(list_mutex);
63 
64 static void fw_mgmt_kref_release(struct kref *kref)
65 {
66 	struct fw_mgmt *fw_mgmt = container_of(kref, struct fw_mgmt, kref);
67 
68 	ida_destroy(&fw_mgmt->id_map);
69 	kfree(fw_mgmt);
70 }
71 
72 /*
73  * All users of fw_mgmt take a reference (from within list_mutex lock), before
74  * they get a pointer to play with. And the structure will be freed only after
75  * the last user has put the reference to it.
76  */
77 static void put_fw_mgmt(struct fw_mgmt *fw_mgmt)
78 {
79 	kref_put(&fw_mgmt->kref, fw_mgmt_kref_release);
80 }
81 
82 /* Caller must call put_fw_mgmt() after using struct fw_mgmt */
83 static struct fw_mgmt *get_fw_mgmt(struct cdev *cdev)
84 {
85 	struct fw_mgmt *fw_mgmt;
86 
87 	mutex_lock(&list_mutex);
88 
89 	list_for_each_entry(fw_mgmt, &fw_mgmt_list, node) {
90 		if (&fw_mgmt->cdev == cdev) {
91 			kref_get(&fw_mgmt->kref);
92 			goto unlock;
93 		}
94 	}
95 
96 	fw_mgmt = NULL;
97 
98 unlock:
99 	mutex_unlock(&list_mutex);
100 
101 	return fw_mgmt;
102 }
103 
104 static int fw_mgmt_interface_fw_version_operation(struct fw_mgmt *fw_mgmt,
105 		struct fw_mgmt_ioc_get_intf_version *fw_info)
106 {
107 	struct gb_connection *connection = fw_mgmt->connection;
108 	struct gb_fw_mgmt_interface_fw_version_response response;
109 	int ret;
110 
111 	ret = gb_operation_sync(connection,
112 				GB_FW_MGMT_TYPE_INTERFACE_FW_VERSION, NULL, 0,
113 				&response, sizeof(response));
114 	if (ret) {
115 		dev_err(fw_mgmt->parent,
116 			"failed to get interface firmware version (%d)\n", ret);
117 		return ret;
118 	}
119 
120 	fw_info->major = le16_to_cpu(response.major);
121 	fw_info->minor = le16_to_cpu(response.minor);
122 
123 	strncpy(fw_info->firmware_tag, response.firmware_tag,
124 		GB_FIRMWARE_TAG_MAX_SIZE);
125 
126 	/*
127 	 * The firmware-tag should be NULL terminated, otherwise throw error but
128 	 * don't fail.
129 	 */
130 	if (fw_info->firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
131 		dev_err(fw_mgmt->parent,
132 			"fw-version: firmware-tag is not NULL terminated\n");
133 		fw_info->firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] = '\0';
134 	}
135 
136 	return 0;
137 }
138 
139 static int fw_mgmt_load_and_validate_operation(struct fw_mgmt *fw_mgmt,
140 					       u8 load_method, const char *tag)
141 {
142 	struct gb_fw_mgmt_load_and_validate_fw_request request;
143 	int ret;
144 
145 	if (load_method != GB_FW_LOAD_METHOD_UNIPRO &&
146 	    load_method != GB_FW_LOAD_METHOD_INTERNAL) {
147 		dev_err(fw_mgmt->parent,
148 			"invalid load-method (%d)\n", load_method);
149 		return -EINVAL;
150 	}
151 
152 	request.load_method = load_method;
153 	strncpy(request.firmware_tag, tag, GB_FIRMWARE_TAG_MAX_SIZE);
154 
155 	/*
156 	 * The firmware-tag should be NULL terminated, otherwise throw error and
157 	 * fail.
158 	 */
159 	if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
160 		dev_err(fw_mgmt->parent, "load-and-validate: firmware-tag is not NULL terminated\n");
161 		return -EINVAL;
162 	}
163 
164 	/* Allocate ids from 1 to 255 (u8-max), 0 is an invalid id */
165 	ret = ida_simple_get(&fw_mgmt->id_map, 1, 256, GFP_KERNEL);
166 	if (ret < 0) {
167 		dev_err(fw_mgmt->parent, "failed to allocate request id (%d)\n",
168 			ret);
169 		return ret;
170 	}
171 
172 	fw_mgmt->intf_fw_request_id = ret;
173 	fw_mgmt->intf_fw_loaded = false;
174 	request.request_id = ret;
175 
176 	ret = gb_operation_sync(fw_mgmt->connection,
177 				GB_FW_MGMT_TYPE_LOAD_AND_VALIDATE_FW, &request,
178 				sizeof(request), NULL, 0);
179 	if (ret) {
180 		ida_simple_remove(&fw_mgmt->id_map,
181 				  fw_mgmt->intf_fw_request_id);
182 		fw_mgmt->intf_fw_request_id = 0;
183 		dev_err(fw_mgmt->parent,
184 			"load and validate firmware request failed (%d)\n",
185 			ret);
186 		return ret;
187 	}
188 
189 	return 0;
190 }
191 
192 static int fw_mgmt_interface_fw_loaded_operation(struct gb_operation *op)
193 {
194 	struct gb_connection *connection = op->connection;
195 	struct fw_mgmt *fw_mgmt = gb_connection_get_data(connection);
196 	struct gb_fw_mgmt_loaded_fw_request *request;
197 
198 	/* No pending load and validate request ? */
199 	if (!fw_mgmt->intf_fw_request_id) {
200 		dev_err(fw_mgmt->parent,
201 			"unexpected firmware loaded request received\n");
202 		return -ENODEV;
203 	}
204 
205 	if (op->request->payload_size != sizeof(*request)) {
206 		dev_err(fw_mgmt->parent, "illegal size of firmware loaded request (%zu != %zu)\n",
207 			op->request->payload_size, sizeof(*request));
208 		return -EINVAL;
209 	}
210 
211 	request = op->request->payload;
212 
213 	/* Invalid request-id ? */
214 	if (request->request_id != fw_mgmt->intf_fw_request_id) {
215 		dev_err(fw_mgmt->parent, "invalid request id for firmware loaded request (%02u != %02u)\n",
216 			fw_mgmt->intf_fw_request_id, request->request_id);
217 		return -ENODEV;
218 	}
219 
220 	ida_simple_remove(&fw_mgmt->id_map, fw_mgmt->intf_fw_request_id);
221 	fw_mgmt->intf_fw_request_id = 0;
222 	fw_mgmt->intf_fw_status = request->status;
223 	fw_mgmt->intf_fw_major = le16_to_cpu(request->major);
224 	fw_mgmt->intf_fw_minor = le16_to_cpu(request->minor);
225 
226 	if (fw_mgmt->intf_fw_status == GB_FW_LOAD_STATUS_FAILED)
227 		dev_err(fw_mgmt->parent,
228 			"failed to load interface firmware, status:%02x\n",
229 			fw_mgmt->intf_fw_status);
230 	else if (fw_mgmt->intf_fw_status == GB_FW_LOAD_STATUS_VALIDATION_FAILED)
231 		dev_err(fw_mgmt->parent,
232 			"failed to validate interface firmware, status:%02x\n",
233 			fw_mgmt->intf_fw_status);
234 	else
235 		fw_mgmt->intf_fw_loaded = true;
236 
237 	complete(&fw_mgmt->completion);
238 
239 	return 0;
240 }
241 
242 static int fw_mgmt_backend_fw_version_operation(struct fw_mgmt *fw_mgmt,
243 		struct fw_mgmt_ioc_get_backend_version *fw_info)
244 {
245 	struct gb_connection *connection = fw_mgmt->connection;
246 	struct gb_fw_mgmt_backend_fw_version_request request;
247 	struct gb_fw_mgmt_backend_fw_version_response response;
248 	int ret;
249 
250 	strncpy(request.firmware_tag, fw_info->firmware_tag,
251 		GB_FIRMWARE_TAG_MAX_SIZE);
252 
253 	/*
254 	 * The firmware-tag should be NULL terminated, otherwise throw error and
255 	 * fail.
256 	 */
257 	if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
258 		dev_err(fw_mgmt->parent, "backend-version: firmware-tag is not NULL terminated\n");
259 		return -EINVAL;
260 	}
261 
262 	ret = gb_operation_sync(connection,
263 				GB_FW_MGMT_TYPE_BACKEND_FW_VERSION, &request,
264 				sizeof(request), &response, sizeof(response));
265 	if (ret) {
266 		dev_err(fw_mgmt->parent, "failed to get version of %s backend firmware (%d)\n",
267 			fw_info->firmware_tag, ret);
268 		return ret;
269 	}
270 
271 	fw_info->status = response.status;
272 
273 	/* Reset version as that should be non-zero only for success case */
274 	fw_info->major = 0;
275 	fw_info->minor = 0;
276 
277 	switch (fw_info->status) {
278 	case GB_FW_BACKEND_VERSION_STATUS_SUCCESS:
279 		fw_info->major = le16_to_cpu(response.major);
280 		fw_info->minor = le16_to_cpu(response.minor);
281 		break;
282 	case GB_FW_BACKEND_VERSION_STATUS_NOT_AVAILABLE:
283 	case GB_FW_BACKEND_VERSION_STATUS_RETRY:
284 		break;
285 	case GB_FW_BACKEND_VERSION_STATUS_NOT_SUPPORTED:
286 		dev_err(fw_mgmt->parent,
287 			"Firmware with tag %s is not supported by Interface\n",
288 			fw_info->firmware_tag);
289 		break;
290 	default:
291 		dev_err(fw_mgmt->parent, "Invalid status received: %u\n",
292 			fw_info->status);
293 	}
294 
295 	return 0;
296 }
297 
298 static int fw_mgmt_backend_fw_update_operation(struct fw_mgmt *fw_mgmt,
299 					       char *tag)
300 {
301 	struct gb_fw_mgmt_backend_fw_update_request request;
302 	int ret;
303 
304 	strncpy(request.firmware_tag, tag, GB_FIRMWARE_TAG_MAX_SIZE);
305 
306 	/*
307 	 * The firmware-tag should be NULL terminated, otherwise throw error and
308 	 * fail.
309 	 */
310 	if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
311 		dev_err(fw_mgmt->parent, "backend-update: firmware-tag is not NULL terminated\n");
312 		return -EINVAL;
313 	}
314 
315 	/* Allocate ids from 1 to 255 (u8-max), 0 is an invalid id */
316 	ret = ida_simple_get(&fw_mgmt->id_map, 1, 256, GFP_KERNEL);
317 	if (ret < 0) {
318 		dev_err(fw_mgmt->parent, "failed to allocate request id (%d)\n",
319 			ret);
320 		return ret;
321 	}
322 
323 	fw_mgmt->backend_fw_request_id = ret;
324 	request.request_id = ret;
325 
326 	ret = gb_operation_sync(fw_mgmt->connection,
327 				GB_FW_MGMT_TYPE_BACKEND_FW_UPDATE, &request,
328 				sizeof(request), NULL, 0);
329 	if (ret) {
330 		ida_simple_remove(&fw_mgmt->id_map,
331 				  fw_mgmt->backend_fw_request_id);
332 		fw_mgmt->backend_fw_request_id = 0;
333 		dev_err(fw_mgmt->parent,
334 			"backend %s firmware update request failed (%d)\n", tag,
335 			ret);
336 		return ret;
337 	}
338 
339 	return 0;
340 }
341 
342 static int fw_mgmt_backend_fw_updated_operation(struct gb_operation *op)
343 {
344 	struct gb_connection *connection = op->connection;
345 	struct fw_mgmt *fw_mgmt = gb_connection_get_data(connection);
346 	struct gb_fw_mgmt_backend_fw_updated_request *request;
347 
348 	/* No pending load and validate request ? */
349 	if (!fw_mgmt->backend_fw_request_id) {
350 		dev_err(fw_mgmt->parent, "unexpected backend firmware updated request received\n");
351 		return -ENODEV;
352 	}
353 
354 	if (op->request->payload_size != sizeof(*request)) {
355 		dev_err(fw_mgmt->parent, "illegal size of backend firmware updated request (%zu != %zu)\n",
356 			op->request->payload_size, sizeof(*request));
357 		return -EINVAL;
358 	}
359 
360 	request = op->request->payload;
361 
362 	/* Invalid request-id ? */
363 	if (request->request_id != fw_mgmt->backend_fw_request_id) {
364 		dev_err(fw_mgmt->parent, "invalid request id for backend firmware updated request (%02u != %02u)\n",
365 			fw_mgmt->backend_fw_request_id, request->request_id);
366 		return -ENODEV;
367 	}
368 
369 	ida_simple_remove(&fw_mgmt->id_map, fw_mgmt->backend_fw_request_id);
370 	fw_mgmt->backend_fw_request_id = 0;
371 	fw_mgmt->backend_fw_status = request->status;
372 
373 	if ((fw_mgmt->backend_fw_status != GB_FW_BACKEND_FW_STATUS_SUCCESS) &&
374 	    (fw_mgmt->backend_fw_status != GB_FW_BACKEND_FW_STATUS_RETRY))
375 		dev_err(fw_mgmt->parent,
376 			"failed to load backend firmware: %02x\n",
377 			fw_mgmt->backend_fw_status);
378 
379 	complete(&fw_mgmt->completion);
380 
381 	return 0;
382 }
383 
384 /* Char device fops */
385 
386 static int fw_mgmt_open(struct inode *inode, struct file *file)
387 {
388 	struct fw_mgmt *fw_mgmt = get_fw_mgmt(inode->i_cdev);
389 
390 	/* fw_mgmt structure can't get freed until file descriptor is closed */
391 	if (fw_mgmt) {
392 		file->private_data = fw_mgmt;
393 		return 0;
394 	}
395 
396 	return -ENODEV;
397 }
398 
399 static int fw_mgmt_release(struct inode *inode, struct file *file)
400 {
401 	struct fw_mgmt *fw_mgmt = file->private_data;
402 
403 	put_fw_mgmt(fw_mgmt);
404 	return 0;
405 }
406 
407 static int fw_mgmt_ioctl(struct fw_mgmt *fw_mgmt, unsigned int cmd,
408 			 void __user *buf)
409 {
410 	struct fw_mgmt_ioc_get_intf_version intf_fw_info;
411 	struct fw_mgmt_ioc_get_backend_version backend_fw_info;
412 	struct fw_mgmt_ioc_intf_load_and_validate intf_load;
413 	struct fw_mgmt_ioc_backend_fw_update backend_update;
414 	unsigned int timeout;
415 	int ret;
416 
417 	/* Reject any operations after mode-switch has started */
418 	if (fw_mgmt->mode_switch_started)
419 		return -EBUSY;
420 
421 	switch (cmd) {
422 	case FW_MGMT_IOC_GET_INTF_FW:
423 		ret = fw_mgmt_interface_fw_version_operation(fw_mgmt,
424 							     &intf_fw_info);
425 		if (ret)
426 			return ret;
427 
428 		if (copy_to_user(buf, &intf_fw_info, sizeof(intf_fw_info)))
429 			return -EFAULT;
430 
431 		return 0;
432 	case FW_MGMT_IOC_GET_BACKEND_FW:
433 		if (copy_from_user(&backend_fw_info, buf,
434 				   sizeof(backend_fw_info)))
435 			return -EFAULT;
436 
437 		ret = fw_mgmt_backend_fw_version_operation(fw_mgmt,
438 							   &backend_fw_info);
439 		if (ret)
440 			return ret;
441 
442 		if (copy_to_user(buf, &backend_fw_info,
443 				 sizeof(backend_fw_info)))
444 			return -EFAULT;
445 
446 		return 0;
447 	case FW_MGMT_IOC_INTF_LOAD_AND_VALIDATE:
448 		if (copy_from_user(&intf_load, buf, sizeof(intf_load)))
449 			return -EFAULT;
450 
451 		ret = fw_mgmt_load_and_validate_operation(fw_mgmt,
452 				intf_load.load_method, intf_load.firmware_tag);
453 		if (ret)
454 			return ret;
455 
456 		if (!wait_for_completion_timeout(&fw_mgmt->completion,
457 						 fw_mgmt->timeout_jiffies)) {
458 			dev_err(fw_mgmt->parent, "timed out waiting for firmware load and validation to finish\n");
459 			return -ETIMEDOUT;
460 		}
461 
462 		intf_load.status = fw_mgmt->intf_fw_status;
463 		intf_load.major = fw_mgmt->intf_fw_major;
464 		intf_load.minor = fw_mgmt->intf_fw_minor;
465 
466 		if (copy_to_user(buf, &intf_load, sizeof(intf_load)))
467 			return -EFAULT;
468 
469 		return 0;
470 	case FW_MGMT_IOC_INTF_BACKEND_FW_UPDATE:
471 		if (copy_from_user(&backend_update, buf,
472 				   sizeof(backend_update)))
473 			return -EFAULT;
474 
475 		ret = fw_mgmt_backend_fw_update_operation(fw_mgmt,
476 				backend_update.firmware_tag);
477 		if (ret)
478 			return ret;
479 
480 		if (!wait_for_completion_timeout(&fw_mgmt->completion,
481 						 fw_mgmt->timeout_jiffies)) {
482 			dev_err(fw_mgmt->parent, "timed out waiting for backend firmware update to finish\n");
483 			return -ETIMEDOUT;
484 		}
485 
486 		backend_update.status = fw_mgmt->backend_fw_status;
487 
488 		if (copy_to_user(buf, &backend_update, sizeof(backend_update)))
489 			return -EFAULT;
490 
491 		return 0;
492 	case FW_MGMT_IOC_SET_TIMEOUT_MS:
493 		if (get_user(timeout, (unsigned int __user *)buf))
494 			return -EFAULT;
495 
496 		if (!timeout) {
497 			dev_err(fw_mgmt->parent, "timeout can't be zero\n");
498 			return -EINVAL;
499 		}
500 
501 		fw_mgmt->timeout_jiffies = msecs_to_jiffies(timeout);
502 
503 		return 0;
504 	case FW_MGMT_IOC_MODE_SWITCH:
505 		if (!fw_mgmt->intf_fw_loaded) {
506 			dev_err(fw_mgmt->parent,
507 				"Firmware not loaded for mode-switch\n");
508 			return -EPERM;
509 		}
510 
511 		/*
512 		 * Disallow new ioctls as the fw-core bundle driver is going to
513 		 * get disconnected soon and the character device will get
514 		 * removed.
515 		 */
516 		fw_mgmt->mode_switch_started = true;
517 
518 		ret = gb_interface_request_mode_switch(fw_mgmt->connection->intf);
519 		if (ret) {
520 			dev_err(fw_mgmt->parent, "Mode-switch failed: %d\n",
521 				ret);
522 			fw_mgmt->mode_switch_started = false;
523 			return ret;
524 		}
525 
526 		return 0;
527 	default:
528 		return -ENOTTY;
529 	}
530 }
531 
532 static long fw_mgmt_ioctl_unlocked(struct file *file, unsigned int cmd,
533 				   unsigned long arg)
534 {
535 	struct fw_mgmt *fw_mgmt = file->private_data;
536 	struct gb_bundle *bundle = fw_mgmt->connection->bundle;
537 	int ret = -ENODEV;
538 
539 	/*
540 	 * Serialize ioctls.
541 	 *
542 	 * We don't want the user to do few operations in parallel. For example,
543 	 * updating Interface firmware in parallel for the same Interface. There
544 	 * is no need to do things in parallel for speed and we can avoid having
545 	 * complicated code for now.
546 	 *
547 	 * This is also used to protect ->disabled, which is used to check if
548 	 * the connection is getting disconnected, so that we don't start any
549 	 * new operations.
550 	 */
551 	mutex_lock(&fw_mgmt->mutex);
552 	if (!fw_mgmt->disabled) {
553 		ret = gb_pm_runtime_get_sync(bundle);
554 		if (!ret) {
555 			ret = fw_mgmt_ioctl(fw_mgmt, cmd, (void __user *)arg);
556 			gb_pm_runtime_put_autosuspend(bundle);
557 		}
558 	}
559 	mutex_unlock(&fw_mgmt->mutex);
560 
561 	return ret;
562 }
563 
564 static const struct file_operations fw_mgmt_fops = {
565 	.owner		= THIS_MODULE,
566 	.open		= fw_mgmt_open,
567 	.release	= fw_mgmt_release,
568 	.unlocked_ioctl	= fw_mgmt_ioctl_unlocked,
569 };
570 
571 int gb_fw_mgmt_request_handler(struct gb_operation *op)
572 {
573 	u8 type = op->type;
574 
575 	switch (type) {
576 	case GB_FW_MGMT_TYPE_LOADED_FW:
577 		return fw_mgmt_interface_fw_loaded_operation(op);
578 	case GB_FW_MGMT_TYPE_BACKEND_FW_UPDATED:
579 		return fw_mgmt_backend_fw_updated_operation(op);
580 	default:
581 		dev_err(&op->connection->bundle->dev,
582 			"unsupported request: %u\n", type);
583 		return -EINVAL;
584 	}
585 }
586 
587 int gb_fw_mgmt_connection_init(struct gb_connection *connection)
588 {
589 	struct fw_mgmt *fw_mgmt;
590 	int ret, minor;
591 
592 	if (!connection)
593 		return 0;
594 
595 	fw_mgmt = kzalloc(sizeof(*fw_mgmt), GFP_KERNEL);
596 	if (!fw_mgmt)
597 		return -ENOMEM;
598 
599 	fw_mgmt->parent = &connection->bundle->dev;
600 	fw_mgmt->timeout_jiffies = msecs_to_jiffies(FW_MGMT_TIMEOUT_MS);
601 	fw_mgmt->connection = connection;
602 
603 	gb_connection_set_data(connection, fw_mgmt);
604 	init_completion(&fw_mgmt->completion);
605 	ida_init(&fw_mgmt->id_map);
606 	mutex_init(&fw_mgmt->mutex);
607 	kref_init(&fw_mgmt->kref);
608 
609 	mutex_lock(&list_mutex);
610 	list_add(&fw_mgmt->node, &fw_mgmt_list);
611 	mutex_unlock(&list_mutex);
612 
613 	ret = gb_connection_enable(connection);
614 	if (ret)
615 		goto err_list_del;
616 
617 	minor = ida_simple_get(&fw_mgmt_minors_map, 0, NUM_MINORS, GFP_KERNEL);
618 	if (minor < 0) {
619 		ret = minor;
620 		goto err_connection_disable;
621 	}
622 
623 	/* Add a char device to allow userspace to interact with fw-mgmt */
624 	fw_mgmt->dev_num = MKDEV(MAJOR(fw_mgmt_dev_num), minor);
625 	cdev_init(&fw_mgmt->cdev, &fw_mgmt_fops);
626 
627 	ret = cdev_add(&fw_mgmt->cdev, fw_mgmt->dev_num, 1);
628 	if (ret)
629 		goto err_remove_ida;
630 
631 	/* Add a soft link to the previously added char-dev within the bundle */
632 	fw_mgmt->class_device = device_create(fw_mgmt_class, fw_mgmt->parent,
633 					      fw_mgmt->dev_num, NULL,
634 					      "gb-fw-mgmt-%d", minor);
635 	if (IS_ERR(fw_mgmt->class_device)) {
636 		ret = PTR_ERR(fw_mgmt->class_device);
637 		goto err_del_cdev;
638 	}
639 
640 	return 0;
641 
642 err_del_cdev:
643 	cdev_del(&fw_mgmt->cdev);
644 err_remove_ida:
645 	ida_simple_remove(&fw_mgmt_minors_map, minor);
646 err_connection_disable:
647 	gb_connection_disable(connection);
648 err_list_del:
649 	mutex_lock(&list_mutex);
650 	list_del(&fw_mgmt->node);
651 	mutex_unlock(&list_mutex);
652 
653 	put_fw_mgmt(fw_mgmt);
654 
655 	return ret;
656 }
657 
658 void gb_fw_mgmt_connection_exit(struct gb_connection *connection)
659 {
660 	struct fw_mgmt *fw_mgmt;
661 
662 	if (!connection)
663 		return;
664 
665 	fw_mgmt = gb_connection_get_data(connection);
666 
667 	device_destroy(fw_mgmt_class, fw_mgmt->dev_num);
668 	cdev_del(&fw_mgmt->cdev);
669 	ida_simple_remove(&fw_mgmt_minors_map, MINOR(fw_mgmt->dev_num));
670 
671 	/*
672 	 * Disallow any new ioctl operations on the char device and wait for
673 	 * existing ones to finish.
674 	 */
675 	mutex_lock(&fw_mgmt->mutex);
676 	fw_mgmt->disabled = true;
677 	mutex_unlock(&fw_mgmt->mutex);
678 
679 	/* All pending greybus operations should have finished by now */
680 	gb_connection_disable(fw_mgmt->connection);
681 
682 	/* Disallow new users to get access to the fw_mgmt structure */
683 	mutex_lock(&list_mutex);
684 	list_del(&fw_mgmt->node);
685 	mutex_unlock(&list_mutex);
686 
687 	/*
688 	 * All current users of fw_mgmt would have taken a reference to it by
689 	 * now, we can drop our reference and wait the last user will get
690 	 * fw_mgmt freed.
691 	 */
692 	put_fw_mgmt(fw_mgmt);
693 }
694 
695 int fw_mgmt_init(void)
696 {
697 	int ret;
698 
699 	fw_mgmt_class = class_create(THIS_MODULE, "gb_fw_mgmt");
700 	if (IS_ERR(fw_mgmt_class))
701 		return PTR_ERR(fw_mgmt_class);
702 
703 	ret = alloc_chrdev_region(&fw_mgmt_dev_num, 0, NUM_MINORS,
704 				  "gb_fw_mgmt");
705 	if (ret)
706 		goto err_remove_class;
707 
708 	return 0;
709 
710 err_remove_class:
711 	class_destroy(fw_mgmt_class);
712 	return ret;
713 }
714 
715 void fw_mgmt_exit(void)
716 {
717 	unregister_chrdev_region(fw_mgmt_dev_num, NUM_MINORS);
718 	class_destroy(fw_mgmt_class);
719 	ida_destroy(&fw_mgmt_minors_map);
720 }
721