.. | .. |
---|
3 | 3 | * Freescale data path resource container (DPRC) driver |
---|
4 | 4 | * |
---|
5 | 5 | * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. |
---|
| 6 | + * Copyright 2019-2020 NXP |
---|
6 | 7 | * Author: German Rivera <German.Rivera@freescale.com> |
---|
7 | 8 | * |
---|
8 | 9 | */ |
---|
.. | .. |
---|
27 | 28 | { |
---|
28 | 29 | return mc_dev->obj_desc.id == obj_desc->id && |
---|
29 | 30 | strcmp(mc_dev->obj_desc.type, obj_desc->type) == 0; |
---|
| 31 | +} |
---|
30 | 32 | |
---|
| 33 | +static bool fsl_mc_obj_desc_is_allocatable(struct fsl_mc_obj_desc *obj) |
---|
| 34 | +{ |
---|
| 35 | + if (strcmp(obj->type, "dpmcp") == 0 || |
---|
| 36 | + strcmp(obj->type, "dpcon") == 0 || |
---|
| 37 | + strcmp(obj->type, "dpbp") == 0) |
---|
| 38 | + return true; |
---|
| 39 | + else |
---|
| 40 | + return false; |
---|
31 | 41 | } |
---|
32 | 42 | |
---|
33 | 43 | static int __fsl_mc_device_remove_if_not_in_mc(struct device *dev, void *data) |
---|
.. | .. |
---|
71 | 81 | * the MC by removing devices that represent MC objects that have |
---|
72 | 82 | * been dynamically removed in the physical DPRC. |
---|
73 | 83 | */ |
---|
74 | | -static void dprc_remove_devices(struct fsl_mc_device *mc_bus_dev, |
---|
75 | | - struct fsl_mc_obj_desc *obj_desc_array, |
---|
76 | | - int num_child_objects_in_mc) |
---|
| 84 | +void dprc_remove_devices(struct fsl_mc_device *mc_bus_dev, |
---|
| 85 | + struct fsl_mc_obj_desc *obj_desc_array, |
---|
| 86 | + int num_child_objects_in_mc) |
---|
77 | 87 | { |
---|
78 | 88 | if (num_child_objects_in_mc != 0) { |
---|
79 | 89 | /* |
---|
.. | .. |
---|
95 | 105 | __fsl_mc_device_remove); |
---|
96 | 106 | } |
---|
97 | 107 | } |
---|
| 108 | +EXPORT_SYMBOL_GPL(dprc_remove_devices); |
---|
98 | 109 | |
---|
99 | 110 | static int __fsl_mc_device_match(struct device *dev, void *data) |
---|
100 | 111 | { |
---|
.. | .. |
---|
104 | 115 | return fsl_mc_device_match(mc_dev, obj_desc); |
---|
105 | 116 | } |
---|
106 | 117 | |
---|
107 | | -static struct fsl_mc_device *fsl_mc_device_lookup(struct fsl_mc_obj_desc |
---|
108 | | - *obj_desc, |
---|
109 | | - struct fsl_mc_device |
---|
110 | | - *mc_bus_dev) |
---|
| 118 | +struct fsl_mc_device *fsl_mc_device_lookup(struct fsl_mc_obj_desc *obj_desc, |
---|
| 119 | + struct fsl_mc_device *mc_bus_dev) |
---|
111 | 120 | { |
---|
112 | 121 | struct device *dev; |
---|
113 | 122 | |
---|
.. | .. |
---|
152 | 161 | } |
---|
153 | 162 | } |
---|
154 | 163 | |
---|
| 164 | +static void fsl_mc_obj_device_add(struct fsl_mc_device *mc_bus_dev, |
---|
| 165 | + struct fsl_mc_obj_desc *obj_desc) |
---|
| 166 | +{ |
---|
| 167 | + int error; |
---|
| 168 | + struct fsl_mc_device *child_dev; |
---|
| 169 | + |
---|
| 170 | + /* |
---|
| 171 | + * Check if device is already known to Linux: |
---|
| 172 | + */ |
---|
| 173 | + child_dev = fsl_mc_device_lookup(obj_desc, mc_bus_dev); |
---|
| 174 | + if (child_dev) { |
---|
| 175 | + check_plugged_state_change(child_dev, obj_desc); |
---|
| 176 | + put_device(&child_dev->dev); |
---|
| 177 | + } else { |
---|
| 178 | + error = fsl_mc_device_add(obj_desc, NULL, &mc_bus_dev->dev, |
---|
| 179 | + &child_dev); |
---|
| 180 | + if (error < 0) |
---|
| 181 | + return; |
---|
| 182 | + } |
---|
| 183 | +} |
---|
| 184 | + |
---|
155 | 185 | /** |
---|
156 | 186 | * dprc_add_new_devices - Adds devices to the logical bus for a DPRC |
---|
157 | 187 | * |
---|
.. | .. |
---|
168 | 198 | struct fsl_mc_obj_desc *obj_desc_array, |
---|
169 | 199 | int num_child_objects_in_mc) |
---|
170 | 200 | { |
---|
171 | | - int error; |
---|
172 | 201 | int i; |
---|
173 | 202 | |
---|
| 203 | + /* probe the allocable objects first */ |
---|
174 | 204 | for (i = 0; i < num_child_objects_in_mc; i++) { |
---|
175 | | - struct fsl_mc_device *child_dev; |
---|
176 | 205 | struct fsl_mc_obj_desc *obj_desc = &obj_desc_array[i]; |
---|
177 | 206 | |
---|
178 | | - if (strlen(obj_desc->type) == 0) |
---|
179 | | - continue; |
---|
| 207 | + if (strlen(obj_desc->type) > 0 && |
---|
| 208 | + fsl_mc_obj_desc_is_allocatable(obj_desc)) |
---|
| 209 | + fsl_mc_obj_device_add(mc_bus_dev, obj_desc); |
---|
| 210 | + } |
---|
180 | 211 | |
---|
181 | | - /* |
---|
182 | | - * Check if device is already known to Linux: |
---|
183 | | - */ |
---|
184 | | - child_dev = fsl_mc_device_lookup(obj_desc, mc_bus_dev); |
---|
185 | | - if (child_dev) { |
---|
186 | | - check_plugged_state_change(child_dev, obj_desc); |
---|
187 | | - put_device(&child_dev->dev); |
---|
188 | | - continue; |
---|
189 | | - } |
---|
| 212 | + for (i = 0; i < num_child_objects_in_mc; i++) { |
---|
| 213 | + struct fsl_mc_obj_desc *obj_desc = &obj_desc_array[i]; |
---|
190 | 214 | |
---|
191 | | - error = fsl_mc_device_add(obj_desc, NULL, &mc_bus_dev->dev, |
---|
192 | | - &child_dev); |
---|
193 | | - if (error < 0) |
---|
194 | | - continue; |
---|
| 215 | + if (strlen(obj_desc->type) > 0 && |
---|
| 216 | + !fsl_mc_obj_desc_is_allocatable(obj_desc)) |
---|
| 217 | + fsl_mc_obj_device_add(mc_bus_dev, obj_desc); |
---|
195 | 218 | } |
---|
196 | 219 | } |
---|
197 | 220 | |
---|
.. | .. |
---|
199 | 222 | * dprc_scan_objects - Discover objects in a DPRC |
---|
200 | 223 | * |
---|
201 | 224 | * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object |
---|
202 | | - * @total_irq_count: If argument is provided the function populates the |
---|
203 | | - * total number of IRQs created by objects in the DPRC. |
---|
| 225 | + * @alloc_interrupts: if true the function allocates the interrupt pool, |
---|
| 226 | + * otherwise the interrupt allocation is delayed |
---|
204 | 227 | * |
---|
205 | 228 | * Detects objects added and removed from a DPRC and synchronizes the |
---|
206 | 229 | * state of the Linux bus driver, MC by adding and removing |
---|
.. | .. |
---|
215 | 238 | * of the device drivers for the non-allocatable devices. |
---|
216 | 239 | */ |
---|
217 | 240 | static int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, |
---|
218 | | - unsigned int *total_irq_count) |
---|
| 241 | + bool alloc_interrupts) |
---|
219 | 242 | { |
---|
220 | 243 | int num_child_objects; |
---|
221 | 244 | int dprc_get_obj_failures; |
---|
.. | .. |
---|
296 | 319 | * Allocate IRQ's before binding the scanned devices with their |
---|
297 | 320 | * respective drivers. |
---|
298 | 321 | */ |
---|
299 | | - if (dev_get_msi_domain(&mc_bus_dev->dev) && !mc_bus->irq_resources) { |
---|
| 322 | + if (dev_get_msi_domain(&mc_bus_dev->dev)) { |
---|
300 | 323 | if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) { |
---|
301 | 324 | dev_warn(&mc_bus_dev->dev, |
---|
302 | 325 | "IRQs needed (%u) exceed IRQs preallocated (%u)\n", |
---|
303 | 326 | irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS); |
---|
304 | 327 | } |
---|
305 | 328 | |
---|
306 | | - error = fsl_mc_populate_irq_pool(mc_bus, |
---|
307 | | - FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS); |
---|
308 | | - if (error < 0) |
---|
309 | | - return error; |
---|
| 329 | + if (alloc_interrupts && !mc_bus->irq_resources) { |
---|
| 330 | + error = fsl_mc_populate_irq_pool(mc_bus_dev, |
---|
| 331 | + FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS); |
---|
| 332 | + if (error < 0) |
---|
| 333 | + return error; |
---|
| 334 | + } |
---|
310 | 335 | } |
---|
311 | | - |
---|
312 | | - if (total_irq_count) |
---|
313 | | - *total_irq_count = irq_count; |
---|
314 | 336 | |
---|
315 | 337 | dprc_remove_devices(mc_bus_dev, child_obj_desc_array, |
---|
316 | 338 | num_child_objects); |
---|
.. | .. |
---|
333 | 355 | * bus driver with the actual state of the MC by adding and removing |
---|
334 | 356 | * devices as appropriate. |
---|
335 | 357 | */ |
---|
336 | | -static int dprc_scan_container(struct fsl_mc_device *mc_bus_dev) |
---|
| 358 | +int dprc_scan_container(struct fsl_mc_device *mc_bus_dev, |
---|
| 359 | + bool alloc_interrupts) |
---|
337 | 360 | { |
---|
338 | | - int error; |
---|
| 361 | + int error = 0; |
---|
339 | 362 | struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev); |
---|
340 | 363 | |
---|
341 | 364 | fsl_mc_init_all_resource_pools(mc_bus_dev); |
---|
.. | .. |
---|
344 | 367 | * Discover objects in the DPRC: |
---|
345 | 368 | */ |
---|
346 | 369 | mutex_lock(&mc_bus->scan_mutex); |
---|
347 | | - error = dprc_scan_objects(mc_bus_dev, NULL); |
---|
| 370 | + error = dprc_scan_objects(mc_bus_dev, alloc_interrupts); |
---|
348 | 371 | mutex_unlock(&mc_bus->scan_mutex); |
---|
349 | | - if (error < 0) { |
---|
350 | | - fsl_mc_cleanup_all_resource_pools(mc_bus_dev); |
---|
351 | | - return error; |
---|
352 | | - } |
---|
353 | 372 | |
---|
354 | | - return 0; |
---|
| 373 | + return error; |
---|
355 | 374 | } |
---|
356 | | - |
---|
| 375 | +EXPORT_SYMBOL_GPL(dprc_scan_container); |
---|
357 | 376 | /** |
---|
358 | 377 | * dprc_irq0_handler - Regular ISR for DPRC interrupt 0 |
---|
359 | 378 | * |
---|
.. | .. |
---|
413 | 432 | DPRC_IRQ_EVENT_CONTAINER_DESTROYED | |
---|
414 | 433 | DPRC_IRQ_EVENT_OBJ_DESTROYED | |
---|
415 | 434 | DPRC_IRQ_EVENT_OBJ_CREATED)) { |
---|
416 | | - unsigned int irq_count; |
---|
417 | 435 | |
---|
418 | | - error = dprc_scan_objects(mc_dev, &irq_count); |
---|
| 436 | + error = dprc_scan_objects(mc_dev, true); |
---|
419 | 437 | if (error < 0) { |
---|
420 | 438 | /* |
---|
421 | 439 | * If the error is -ENXIO, we ignore it, as it indicates |
---|
.. | .. |
---|
429 | 447 | } |
---|
430 | 448 | |
---|
431 | 449 | goto out; |
---|
432 | | - } |
---|
433 | | - |
---|
434 | | - if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) { |
---|
435 | | - dev_warn(dev, |
---|
436 | | - "IRQs needed (%u) exceed IRQs preallocated (%u)\n", |
---|
437 | | - irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS); |
---|
438 | 450 | } |
---|
439 | 451 | } |
---|
440 | 452 | |
---|
.. | .. |
---|
576 | 588 | } |
---|
577 | 589 | |
---|
578 | 590 | /** |
---|
579 | | - * dprc_probe - callback invoked when a DPRC is being bound to this driver |
---|
| 591 | + * dprc_setup - opens and creates a mc_io for DPRC |
---|
580 | 592 | * |
---|
581 | 593 | * @mc_dev: Pointer to fsl-mc device representing a DPRC |
---|
582 | 594 | * |
---|
583 | 595 | * It opens the physical DPRC in the MC. |
---|
584 | | - * It scans the DPRC to discover the MC objects contained in it. |
---|
585 | | - * It creates the interrupt pool for the MC bus associated with the DPRC. |
---|
586 | | - * It configures the interrupts for the DPRC device itself. |
---|
| 596 | + * It configures the DPRC portal used to communicate with MC |
---|
587 | 597 | */ |
---|
588 | | -static int dprc_probe(struct fsl_mc_device *mc_dev) |
---|
| 598 | + |
---|
| 599 | +int dprc_setup(struct fsl_mc_device *mc_dev) |
---|
589 | 600 | { |
---|
590 | | - int error; |
---|
591 | | - size_t region_size; |
---|
592 | 601 | struct device *parent_dev = mc_dev->dev.parent; |
---|
593 | 602 | struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); |
---|
| 603 | + struct irq_domain *mc_msi_domain; |
---|
594 | 604 | bool mc_io_created = false; |
---|
595 | 605 | bool msi_domain_set = false; |
---|
596 | 606 | u16 major_ver, minor_ver; |
---|
| 607 | + size_t region_size; |
---|
| 608 | + int error; |
---|
597 | 609 | |
---|
598 | 610 | if (!is_fsl_mc_bus_dprc(mc_dev)) |
---|
599 | 611 | return -EINVAL; |
---|
.. | .. |
---|
623 | 635 | return error; |
---|
624 | 636 | |
---|
625 | 637 | mc_io_created = true; |
---|
| 638 | + } |
---|
626 | 639 | |
---|
627 | | - /* |
---|
628 | | - * Inherit parent MSI domain: |
---|
629 | | - */ |
---|
630 | | - dev_set_msi_domain(&mc_dev->dev, |
---|
631 | | - dev_get_msi_domain(parent_dev)); |
---|
632 | | - msi_domain_set = true; |
---|
| 640 | + mc_msi_domain = fsl_mc_find_msi_domain(&mc_dev->dev); |
---|
| 641 | + if (!mc_msi_domain) { |
---|
| 642 | + dev_warn(&mc_dev->dev, |
---|
| 643 | + "WARNING: MC bus without interrupt support\n"); |
---|
633 | 644 | } else { |
---|
634 | | - /* |
---|
635 | | - * This is a root DPRC |
---|
636 | | - */ |
---|
637 | | - struct irq_domain *mc_msi_domain; |
---|
638 | | - |
---|
639 | | - if (dev_is_fsl_mc(parent_dev)) |
---|
640 | | - return -EINVAL; |
---|
641 | | - |
---|
642 | | - error = fsl_mc_find_msi_domain(parent_dev, |
---|
643 | | - &mc_msi_domain); |
---|
644 | | - if (error < 0) { |
---|
645 | | - dev_warn(&mc_dev->dev, |
---|
646 | | - "WARNING: MC bus without interrupt support\n"); |
---|
647 | | - } else { |
---|
648 | | - dev_set_msi_domain(&mc_dev->dev, mc_msi_domain); |
---|
649 | | - msi_domain_set = true; |
---|
650 | | - } |
---|
| 645 | + dev_set_msi_domain(&mc_dev->dev, mc_msi_domain); |
---|
| 646 | + msi_domain_set = true; |
---|
651 | 647 | } |
---|
652 | 648 | |
---|
653 | 649 | error = dprc_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id, |
---|
.. | .. |
---|
684 | 680 | goto error_cleanup_open; |
---|
685 | 681 | } |
---|
686 | 682 | |
---|
687 | | - mutex_init(&mc_bus->scan_mutex); |
---|
688 | | - |
---|
689 | | - /* |
---|
690 | | - * Discover MC objects in DPRC object: |
---|
691 | | - */ |
---|
692 | | - error = dprc_scan_container(mc_dev); |
---|
693 | | - if (error < 0) |
---|
694 | | - goto error_cleanup_open; |
---|
695 | | - |
---|
696 | | - /* |
---|
697 | | - * Configure interrupt for the DPRC object associated with this MC bus: |
---|
698 | | - */ |
---|
699 | | - error = dprc_setup_irq(mc_dev); |
---|
700 | | - if (error < 0) |
---|
701 | | - goto error_cleanup_open; |
---|
702 | | - |
---|
703 | | - dev_info(&mc_dev->dev, "DPRC device bound to driver"); |
---|
704 | 683 | return 0; |
---|
705 | 684 | |
---|
706 | 685 | error_cleanup_open: |
---|
.. | .. |
---|
715 | 694 | mc_dev->mc_io = NULL; |
---|
716 | 695 | } |
---|
717 | 696 | |
---|
| 697 | + return error; |
---|
| 698 | +} |
---|
| 699 | +EXPORT_SYMBOL_GPL(dprc_setup); |
---|
| 700 | + |
---|
| 701 | +/** |
---|
| 702 | + * dprc_probe - callback invoked when a DPRC is being bound to this driver |
---|
| 703 | + * |
---|
| 704 | + * @mc_dev: Pointer to fsl-mc device representing a DPRC |
---|
| 705 | + * |
---|
| 706 | + * It opens the physical DPRC in the MC. |
---|
| 707 | + * It scans the DPRC to discover the MC objects contained in it. |
---|
| 708 | + * It creates the interrupt pool for the MC bus associated with the DPRC. |
---|
| 709 | + * It configures the interrupts for the DPRC device itself. |
---|
| 710 | + */ |
---|
| 711 | +static int dprc_probe(struct fsl_mc_device *mc_dev) |
---|
| 712 | +{ |
---|
| 713 | + int error; |
---|
| 714 | + |
---|
| 715 | + error = dprc_setup(mc_dev); |
---|
| 716 | + if (error < 0) |
---|
| 717 | + return error; |
---|
| 718 | + |
---|
| 719 | + /* |
---|
| 720 | + * Discover MC objects in DPRC object: |
---|
| 721 | + */ |
---|
| 722 | + error = dprc_scan_container(mc_dev, true); |
---|
| 723 | + if (error < 0) |
---|
| 724 | + goto dprc_cleanup; |
---|
| 725 | + |
---|
| 726 | + /* |
---|
| 727 | + * Configure interrupt for the DPRC object associated with this MC bus: |
---|
| 728 | + */ |
---|
| 729 | + error = dprc_setup_irq(mc_dev); |
---|
| 730 | + if (error < 0) |
---|
| 731 | + goto scan_cleanup; |
---|
| 732 | + |
---|
| 733 | + dev_info(&mc_dev->dev, "DPRC device bound to driver"); |
---|
| 734 | + return 0; |
---|
| 735 | + |
---|
| 736 | +scan_cleanup: |
---|
| 737 | + device_for_each_child(&mc_dev->dev, NULL, __fsl_mc_device_remove); |
---|
| 738 | +dprc_cleanup: |
---|
| 739 | + dprc_cleanup(mc_dev); |
---|
718 | 740 | return error; |
---|
719 | 741 | } |
---|
720 | 742 | |
---|
.. | .. |
---|
733 | 755 | } |
---|
734 | 756 | |
---|
735 | 757 | /** |
---|
| 758 | + * dprc_cleanup - function that cleanups a DPRC |
---|
| 759 | + * |
---|
| 760 | + * @mc_dev: Pointer to fsl-mc device representing the DPRC |
---|
| 761 | + * |
---|
| 762 | + * It closes the DPRC device in the MC. |
---|
| 763 | + * It destroys the interrupt pool associated with this MC bus. |
---|
| 764 | + */ |
---|
| 765 | + |
---|
| 766 | +int dprc_cleanup(struct fsl_mc_device *mc_dev) |
---|
| 767 | +{ |
---|
| 768 | + int error; |
---|
| 769 | + |
---|
| 770 | + /* this function should be called only for DPRCs, it |
---|
| 771 | + * is an error to call it for regular objects |
---|
| 772 | + */ |
---|
| 773 | + if (!is_fsl_mc_bus_dprc(mc_dev)) |
---|
| 774 | + return -EINVAL; |
---|
| 775 | + |
---|
| 776 | + if (dev_get_msi_domain(&mc_dev->dev)) { |
---|
| 777 | + fsl_mc_cleanup_irq_pool(mc_dev); |
---|
| 778 | + dev_set_msi_domain(&mc_dev->dev, NULL); |
---|
| 779 | + } |
---|
| 780 | + |
---|
| 781 | + fsl_mc_cleanup_all_resource_pools(mc_dev); |
---|
| 782 | + |
---|
| 783 | + /* if this step fails we cannot go further with cleanup as there is no way of |
---|
| 784 | + * communicating with the firmware |
---|
| 785 | + */ |
---|
| 786 | + if (!mc_dev->mc_io) { |
---|
| 787 | + dev_err(&mc_dev->dev, "mc_io is NULL, tear down cannot be performed in firmware\n"); |
---|
| 788 | + return -EINVAL; |
---|
| 789 | + } |
---|
| 790 | + |
---|
| 791 | + error = dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle); |
---|
| 792 | + if (error < 0) |
---|
| 793 | + dev_err(&mc_dev->dev, "dprc_close() failed: %d\n", error); |
---|
| 794 | + |
---|
| 795 | + if (!fsl_mc_is_root_dprc(&mc_dev->dev)) { |
---|
| 796 | + fsl_destroy_mc_io(mc_dev->mc_io); |
---|
| 797 | + mc_dev->mc_io = NULL; |
---|
| 798 | + } |
---|
| 799 | + |
---|
| 800 | + return 0; |
---|
| 801 | +} |
---|
| 802 | +EXPORT_SYMBOL_GPL(dprc_cleanup); |
---|
| 803 | + |
---|
| 804 | +/** |
---|
736 | 805 | * dprc_remove - callback invoked when a DPRC is being unbound from this driver |
---|
737 | 806 | * |
---|
738 | 807 | * @mc_dev: Pointer to fsl-mc device representing the DPRC |
---|
.. | .. |
---|
744 | 813 | */ |
---|
745 | 814 | static int dprc_remove(struct fsl_mc_device *mc_dev) |
---|
746 | 815 | { |
---|
747 | | - int error; |
---|
748 | 816 | struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); |
---|
749 | 817 | |
---|
750 | 818 | if (!is_fsl_mc_bus_dprc(mc_dev)) |
---|
751 | | - return -EINVAL; |
---|
752 | | - if (!mc_dev->mc_io) |
---|
753 | 819 | return -EINVAL; |
---|
754 | 820 | |
---|
755 | 821 | if (!mc_bus->irq_resources) |
---|
.. | .. |
---|
760 | 826 | |
---|
761 | 827 | device_for_each_child(&mc_dev->dev, NULL, __fsl_mc_device_remove); |
---|
762 | 828 | |
---|
763 | | - if (dev_get_msi_domain(&mc_dev->dev)) { |
---|
764 | | - fsl_mc_cleanup_irq_pool(mc_bus); |
---|
765 | | - dev_set_msi_domain(&mc_dev->dev, NULL); |
---|
766 | | - } |
---|
767 | | - |
---|
768 | | - fsl_mc_cleanup_all_resource_pools(mc_dev); |
---|
769 | | - |
---|
770 | | - error = dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle); |
---|
771 | | - if (error < 0) |
---|
772 | | - dev_err(&mc_dev->dev, "dprc_close() failed: %d\n", error); |
---|
773 | | - |
---|
774 | | - if (!fsl_mc_is_root_dprc(&mc_dev->dev)) { |
---|
775 | | - fsl_destroy_mc_io(mc_dev->mc_io); |
---|
776 | | - mc_dev->mc_io = NULL; |
---|
777 | | - } |
---|
| 829 | + dprc_cleanup(mc_dev); |
---|
778 | 830 | |
---|
779 | 831 | dev_info(&mc_dev->dev, "DPRC device unbound from driver"); |
---|
780 | 832 | return 0; |
---|