Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * fsl-mc object allocator driver
0004  *
0005  * Copyright (C) 2013-2016 Freescale Semiconductor, Inc.
0006  *
0007  */
0008 
0009 #include <linux/module.h>
0010 #include <linux/msi.h>
0011 #include <linux/fsl/mc.h>
0012 
0013 #include "fsl-mc-private.h"
0014 
0015 static bool __must_check fsl_mc_is_allocatable(struct fsl_mc_device *mc_dev)
0016 {
0017     return is_fsl_mc_bus_dpbp(mc_dev) ||
0018            is_fsl_mc_bus_dpmcp(mc_dev) ||
0019            is_fsl_mc_bus_dpcon(mc_dev);
0020 }
0021 
0022 /**
0023  * fsl_mc_resource_pool_add_device - add allocatable object to a resource
0024  * pool of a given fsl-mc bus
0025  *
0026  * @mc_bus: pointer to the fsl-mc bus
0027  * @pool_type: pool type
0028  * @mc_dev: pointer to allocatable fsl-mc device
0029  */
0030 static int __must_check fsl_mc_resource_pool_add_device(struct fsl_mc_bus
0031                                 *mc_bus,
0032                             enum fsl_mc_pool_type
0033                                 pool_type,
0034                             struct fsl_mc_device
0035                                 *mc_dev)
0036 {
0037     struct fsl_mc_resource_pool *res_pool;
0038     struct fsl_mc_resource *resource;
0039     struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
0040     int error = -EINVAL;
0041 
0042     if (pool_type < 0 || pool_type >= FSL_MC_NUM_POOL_TYPES)
0043         goto out;
0044     if (!fsl_mc_is_allocatable(mc_dev))
0045         goto out;
0046     if (mc_dev->resource)
0047         goto out;
0048 
0049     res_pool = &mc_bus->resource_pools[pool_type];
0050     if (res_pool->type != pool_type)
0051         goto out;
0052     if (res_pool->mc_bus != mc_bus)
0053         goto out;
0054 
0055     mutex_lock(&res_pool->mutex);
0056 
0057     if (res_pool->max_count < 0)
0058         goto out_unlock;
0059     if (res_pool->free_count < 0 ||
0060         res_pool->free_count > res_pool->max_count)
0061         goto out_unlock;
0062 
0063     resource = devm_kzalloc(&mc_bus_dev->dev, sizeof(*resource),
0064                 GFP_KERNEL);
0065     if (!resource) {
0066         error = -ENOMEM;
0067         dev_err(&mc_bus_dev->dev,
0068             "Failed to allocate memory for fsl_mc_resource\n");
0069         goto out_unlock;
0070     }
0071 
0072     resource->type = pool_type;
0073     resource->id = mc_dev->obj_desc.id;
0074     resource->data = mc_dev;
0075     resource->parent_pool = res_pool;
0076     INIT_LIST_HEAD(&resource->node);
0077     list_add_tail(&resource->node, &res_pool->free_list);
0078     mc_dev->resource = resource;
0079     res_pool->free_count++;
0080     res_pool->max_count++;
0081     error = 0;
0082 out_unlock:
0083     mutex_unlock(&res_pool->mutex);
0084 out:
0085     return error;
0086 }
0087 
0088 /**
0089  * fsl_mc_resource_pool_remove_device - remove an allocatable device from a
0090  * resource pool
0091  *
0092  * @mc_dev: pointer to allocatable fsl-mc device
0093  *
0094  * It permanently removes an allocatable fsl-mc device from the resource
0095  * pool. It's an error if the device is in use.
0096  */
0097 static int __must_check fsl_mc_resource_pool_remove_device(struct fsl_mc_device
0098                                    *mc_dev)
0099 {
0100     struct fsl_mc_device *mc_bus_dev;
0101     struct fsl_mc_bus *mc_bus;
0102     struct fsl_mc_resource_pool *res_pool;
0103     struct fsl_mc_resource *resource;
0104     int error = -EINVAL;
0105 
0106     if (!fsl_mc_is_allocatable(mc_dev))
0107         goto out;
0108 
0109     resource = mc_dev->resource;
0110     if (!resource || resource->data != mc_dev)
0111         goto out;
0112 
0113     mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent);
0114     mc_bus = to_fsl_mc_bus(mc_bus_dev);
0115     res_pool = resource->parent_pool;
0116     if (res_pool != &mc_bus->resource_pools[resource->type])
0117         goto out;
0118 
0119     mutex_lock(&res_pool->mutex);
0120 
0121     if (res_pool->max_count <= 0)
0122         goto out_unlock;
0123     if (res_pool->free_count <= 0 ||
0124         res_pool->free_count > res_pool->max_count)
0125         goto out_unlock;
0126 
0127     /*
0128      * If the device is currently allocated, its resource is not
0129      * in the free list and thus, the device cannot be removed.
0130      */
0131     if (list_empty(&resource->node)) {
0132         error = -EBUSY;
0133         dev_err(&mc_bus_dev->dev,
0134             "Device %s cannot be removed from resource pool\n",
0135             dev_name(&mc_dev->dev));
0136         goto out_unlock;
0137     }
0138 
0139     list_del_init(&resource->node);
0140     res_pool->free_count--;
0141     res_pool->max_count--;
0142 
0143     devm_kfree(&mc_bus_dev->dev, resource);
0144     mc_dev->resource = NULL;
0145     error = 0;
0146 out_unlock:
0147     mutex_unlock(&res_pool->mutex);
0148 out:
0149     return error;
0150 }
0151 
0152 static const char *const fsl_mc_pool_type_strings[] = {
0153     [FSL_MC_POOL_DPMCP] = "dpmcp",
0154     [FSL_MC_POOL_DPBP] = "dpbp",
0155     [FSL_MC_POOL_DPCON] = "dpcon",
0156     [FSL_MC_POOL_IRQ] = "irq",
0157 };
0158 
0159 static int __must_check object_type_to_pool_type(const char *object_type,
0160                          enum fsl_mc_pool_type
0161                                 *pool_type)
0162 {
0163     unsigned int i;
0164 
0165     for (i = 0; i < ARRAY_SIZE(fsl_mc_pool_type_strings); i++) {
0166         if (strcmp(object_type, fsl_mc_pool_type_strings[i]) == 0) {
0167             *pool_type = i;
0168             return 0;
0169         }
0170     }
0171 
0172     return -EINVAL;
0173 }
0174 
0175 int __must_check fsl_mc_resource_allocate(struct fsl_mc_bus *mc_bus,
0176                       enum fsl_mc_pool_type pool_type,
0177                       struct fsl_mc_resource **new_resource)
0178 {
0179     struct fsl_mc_resource_pool *res_pool;
0180     struct fsl_mc_resource *resource;
0181     struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
0182     int error = -EINVAL;
0183 
0184     BUILD_BUG_ON(ARRAY_SIZE(fsl_mc_pool_type_strings) !=
0185              FSL_MC_NUM_POOL_TYPES);
0186 
0187     *new_resource = NULL;
0188     if (pool_type < 0 || pool_type >= FSL_MC_NUM_POOL_TYPES)
0189         goto out;
0190 
0191     res_pool = &mc_bus->resource_pools[pool_type];
0192     if (res_pool->mc_bus != mc_bus)
0193         goto out;
0194 
0195     mutex_lock(&res_pool->mutex);
0196     resource = list_first_entry_or_null(&res_pool->free_list,
0197                         struct fsl_mc_resource, node);
0198 
0199     if (!resource) {
0200         error = -ENXIO;
0201         dev_err(&mc_bus_dev->dev,
0202             "No more resources of type %s left\n",
0203             fsl_mc_pool_type_strings[pool_type]);
0204         goto out_unlock;
0205     }
0206 
0207     if (resource->type != pool_type)
0208         goto out_unlock;
0209     if (resource->parent_pool != res_pool)
0210         goto out_unlock;
0211     if (res_pool->free_count <= 0 ||
0212         res_pool->free_count > res_pool->max_count)
0213         goto out_unlock;
0214 
0215     list_del_init(&resource->node);
0216 
0217     res_pool->free_count--;
0218     error = 0;
0219 out_unlock:
0220     mutex_unlock(&res_pool->mutex);
0221     *new_resource = resource;
0222 out:
0223     return error;
0224 }
0225 EXPORT_SYMBOL_GPL(fsl_mc_resource_allocate);
0226 
0227 void fsl_mc_resource_free(struct fsl_mc_resource *resource)
0228 {
0229     struct fsl_mc_resource_pool *res_pool;
0230 
0231     res_pool = resource->parent_pool;
0232     if (resource->type != res_pool->type)
0233         return;
0234 
0235     mutex_lock(&res_pool->mutex);
0236     if (res_pool->free_count < 0 ||
0237         res_pool->free_count >= res_pool->max_count)
0238         goto out_unlock;
0239 
0240     if (!list_empty(&resource->node))
0241         goto out_unlock;
0242 
0243     list_add_tail(&resource->node, &res_pool->free_list);
0244     res_pool->free_count++;
0245 out_unlock:
0246     mutex_unlock(&res_pool->mutex);
0247 }
0248 EXPORT_SYMBOL_GPL(fsl_mc_resource_free);
0249 
0250 /**
0251  * fsl_mc_object_allocate - Allocates an fsl-mc object of the given
0252  * pool type from a given fsl-mc bus instance
0253  *
0254  * @mc_dev: fsl-mc device which is used in conjunction with the
0255  * allocated object
0256  * @pool_type: pool type
0257  * @new_mc_adev: pointer to area where the pointer to the allocated device
0258  * is to be returned
0259  *
0260  * Allocatable objects are always used in conjunction with some functional
0261  * device.  This function allocates an object of the specified type from
0262  * the DPRC containing the functional device.
0263  *
0264  * NOTE: pool_type must be different from FSL_MC_POOL_MCP, since MC
0265  * portals are allocated using fsl_mc_portal_allocate(), instead of
0266  * this function.
0267  */
0268 int __must_check fsl_mc_object_allocate(struct fsl_mc_device *mc_dev,
0269                     enum fsl_mc_pool_type pool_type,
0270                     struct fsl_mc_device **new_mc_adev)
0271 {
0272     struct fsl_mc_device *mc_bus_dev;
0273     struct fsl_mc_bus *mc_bus;
0274     struct fsl_mc_device *mc_adev;
0275     int error = -EINVAL;
0276     struct fsl_mc_resource *resource = NULL;
0277 
0278     *new_mc_adev = NULL;
0279     if (mc_dev->flags & FSL_MC_IS_DPRC)
0280         goto error;
0281 
0282     if (!dev_is_fsl_mc(mc_dev->dev.parent))
0283         goto error;
0284 
0285     if (pool_type == FSL_MC_POOL_DPMCP)
0286         goto error;
0287 
0288     mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent);
0289     mc_bus = to_fsl_mc_bus(mc_bus_dev);
0290     error = fsl_mc_resource_allocate(mc_bus, pool_type, &resource);
0291     if (error < 0)
0292         goto error;
0293 
0294     mc_adev = resource->data;
0295     if (!mc_adev) {
0296         error = -EINVAL;
0297         goto error;
0298     }
0299 
0300     mc_adev->consumer_link = device_link_add(&mc_dev->dev,
0301                          &mc_adev->dev,
0302                          DL_FLAG_AUTOREMOVE_CONSUMER);
0303     if (!mc_adev->consumer_link) {
0304         error = -EINVAL;
0305         goto error;
0306     }
0307 
0308     *new_mc_adev = mc_adev;
0309     return 0;
0310 error:
0311     if (resource)
0312         fsl_mc_resource_free(resource);
0313 
0314     return error;
0315 }
0316 EXPORT_SYMBOL_GPL(fsl_mc_object_allocate);
0317 
0318 /**
0319  * fsl_mc_object_free - Returns an fsl-mc object to the resource
0320  * pool where it came from.
0321  * @mc_adev: Pointer to the fsl-mc device
0322  */
0323 void fsl_mc_object_free(struct fsl_mc_device *mc_adev)
0324 {
0325     struct fsl_mc_resource *resource;
0326 
0327     resource = mc_adev->resource;
0328     if (resource->type == FSL_MC_POOL_DPMCP)
0329         return;
0330     if (resource->data != mc_adev)
0331         return;
0332 
0333     fsl_mc_resource_free(resource);
0334 
0335     mc_adev->consumer_link = NULL;
0336 }
0337 EXPORT_SYMBOL_GPL(fsl_mc_object_free);
0338 
0339 /*
0340  * A DPRC and the devices in the DPRC all share the same GIC-ITS device
0341  * ID.  A block of IRQs is pre-allocated and maintained in a pool
0342  * from which devices can allocate them when needed.
0343  */
0344 
0345 /*
0346  * Initialize the interrupt pool associated with an fsl-mc bus.
0347  * It allocates a block of IRQs from the GIC-ITS.
0348  */
0349 int fsl_mc_populate_irq_pool(struct fsl_mc_device *mc_bus_dev,
0350                  unsigned int irq_count)
0351 {
0352     unsigned int i;
0353     struct fsl_mc_device_irq *irq_resources;
0354     struct fsl_mc_device_irq *mc_dev_irq;
0355     int error;
0356     struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
0357     struct fsl_mc_resource_pool *res_pool =
0358             &mc_bus->resource_pools[FSL_MC_POOL_IRQ];
0359 
0360     /* do nothing if the IRQ pool is already populated */
0361     if (mc_bus->irq_resources)
0362         return 0;
0363 
0364     if (irq_count == 0 ||
0365         irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS)
0366         return -EINVAL;
0367 
0368     error = fsl_mc_msi_domain_alloc_irqs(&mc_bus_dev->dev, irq_count);
0369     if (error < 0)
0370         return error;
0371 
0372     irq_resources = devm_kcalloc(&mc_bus_dev->dev,
0373                      irq_count, sizeof(*irq_resources),
0374                      GFP_KERNEL);
0375     if (!irq_resources) {
0376         error = -ENOMEM;
0377         goto cleanup_msi_irqs;
0378     }
0379 
0380     for (i = 0; i < irq_count; i++) {
0381         mc_dev_irq = &irq_resources[i];
0382 
0383         /*
0384          * NOTE: This mc_dev_irq's MSI addr/value pair will be set
0385          * by the fsl_mc_msi_write_msg() callback
0386          */
0387         mc_dev_irq->resource.type = res_pool->type;
0388         mc_dev_irq->resource.data = mc_dev_irq;
0389         mc_dev_irq->resource.parent_pool = res_pool;
0390         mc_dev_irq->virq = msi_get_virq(&mc_bus_dev->dev, i);
0391         mc_dev_irq->resource.id = mc_dev_irq->virq;
0392         INIT_LIST_HEAD(&mc_dev_irq->resource.node);
0393         list_add_tail(&mc_dev_irq->resource.node, &res_pool->free_list);
0394     }
0395 
0396     res_pool->max_count = irq_count;
0397     res_pool->free_count = irq_count;
0398     mc_bus->irq_resources = irq_resources;
0399     return 0;
0400 
0401 cleanup_msi_irqs:
0402     fsl_mc_msi_domain_free_irqs(&mc_bus_dev->dev);
0403     return error;
0404 }
0405 EXPORT_SYMBOL_GPL(fsl_mc_populate_irq_pool);
0406 
0407 /*
0408  * Teardown the interrupt pool associated with an fsl-mc bus.
0409  * It frees the IRQs that were allocated to the pool, back to the GIC-ITS.
0410  */
0411 void fsl_mc_cleanup_irq_pool(struct fsl_mc_device *mc_bus_dev)
0412 {
0413     struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
0414     struct fsl_mc_resource_pool *res_pool =
0415             &mc_bus->resource_pools[FSL_MC_POOL_IRQ];
0416 
0417     if (!mc_bus->irq_resources)
0418         return;
0419 
0420     if (res_pool->max_count == 0)
0421         return;
0422 
0423     if (res_pool->free_count != res_pool->max_count)
0424         return;
0425 
0426     INIT_LIST_HEAD(&res_pool->free_list);
0427     res_pool->max_count = 0;
0428     res_pool->free_count = 0;
0429     mc_bus->irq_resources = NULL;
0430     fsl_mc_msi_domain_free_irqs(&mc_bus_dev->dev);
0431 }
0432 EXPORT_SYMBOL_GPL(fsl_mc_cleanup_irq_pool);
0433 
0434 /*
0435  * Allocate the IRQs required by a given fsl-mc device.
0436  */
0437 int __must_check fsl_mc_allocate_irqs(struct fsl_mc_device *mc_dev)
0438 {
0439     int i;
0440     int irq_count;
0441     int res_allocated_count = 0;
0442     int error = -EINVAL;
0443     struct fsl_mc_device_irq **irqs = NULL;
0444     struct fsl_mc_bus *mc_bus;
0445     struct fsl_mc_resource_pool *res_pool;
0446 
0447     if (mc_dev->irqs)
0448         return -EINVAL;
0449 
0450     irq_count = mc_dev->obj_desc.irq_count;
0451     if (irq_count == 0)
0452         return -EINVAL;
0453 
0454     if (is_fsl_mc_bus_dprc(mc_dev))
0455         mc_bus = to_fsl_mc_bus(mc_dev);
0456     else
0457         mc_bus = to_fsl_mc_bus(to_fsl_mc_device(mc_dev->dev.parent));
0458 
0459     if (!mc_bus->irq_resources)
0460         return -EINVAL;
0461 
0462     res_pool = &mc_bus->resource_pools[FSL_MC_POOL_IRQ];
0463     if (res_pool->free_count < irq_count) {
0464         dev_err(&mc_dev->dev,
0465             "Not able to allocate %u irqs for device\n", irq_count);
0466         return -ENOSPC;
0467     }
0468 
0469     irqs = devm_kcalloc(&mc_dev->dev, irq_count, sizeof(irqs[0]),
0470                 GFP_KERNEL);
0471     if (!irqs)
0472         return -ENOMEM;
0473 
0474     for (i = 0; i < irq_count; i++) {
0475         struct fsl_mc_resource *resource;
0476 
0477         error = fsl_mc_resource_allocate(mc_bus, FSL_MC_POOL_IRQ,
0478                          &resource);
0479         if (error < 0)
0480             goto error_resource_alloc;
0481 
0482         irqs[i] = to_fsl_mc_irq(resource);
0483         res_allocated_count++;
0484 
0485         irqs[i]->mc_dev = mc_dev;
0486         irqs[i]->dev_irq_index = i;
0487     }
0488 
0489     mc_dev->irqs = irqs;
0490     return 0;
0491 
0492 error_resource_alloc:
0493     for (i = 0; i < res_allocated_count; i++) {
0494         irqs[i]->mc_dev = NULL;
0495         fsl_mc_resource_free(&irqs[i]->resource);
0496     }
0497 
0498     return error;
0499 }
0500 EXPORT_SYMBOL_GPL(fsl_mc_allocate_irqs);
0501 
0502 /*
0503  * Frees the IRQs that were allocated for an fsl-mc device.
0504  */
0505 void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev)
0506 {
0507     int i;
0508     int irq_count;
0509     struct fsl_mc_bus *mc_bus;
0510     struct fsl_mc_device_irq **irqs = mc_dev->irqs;
0511 
0512     if (!irqs)
0513         return;
0514 
0515     irq_count = mc_dev->obj_desc.irq_count;
0516 
0517     if (is_fsl_mc_bus_dprc(mc_dev))
0518         mc_bus = to_fsl_mc_bus(mc_dev);
0519     else
0520         mc_bus = to_fsl_mc_bus(to_fsl_mc_device(mc_dev->dev.parent));
0521 
0522     if (!mc_bus->irq_resources)
0523         return;
0524 
0525     for (i = 0; i < irq_count; i++) {
0526         irqs[i]->mc_dev = NULL;
0527         fsl_mc_resource_free(&irqs[i]->resource);
0528     }
0529 
0530     mc_dev->irqs = NULL;
0531 }
0532 EXPORT_SYMBOL_GPL(fsl_mc_free_irqs);
0533 
0534 void fsl_mc_init_all_resource_pools(struct fsl_mc_device *mc_bus_dev)
0535 {
0536     int pool_type;
0537     struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
0538 
0539     for (pool_type = 0; pool_type < FSL_MC_NUM_POOL_TYPES; pool_type++) {
0540         struct fsl_mc_resource_pool *res_pool =
0541             &mc_bus->resource_pools[pool_type];
0542 
0543         res_pool->type = pool_type;
0544         res_pool->max_count = 0;
0545         res_pool->free_count = 0;
0546         res_pool->mc_bus = mc_bus;
0547         INIT_LIST_HEAD(&res_pool->free_list);
0548         mutex_init(&res_pool->mutex);
0549     }
0550 }
0551 
0552 static void fsl_mc_cleanup_resource_pool(struct fsl_mc_device *mc_bus_dev,
0553                      enum fsl_mc_pool_type pool_type)
0554 {
0555     struct fsl_mc_resource *resource;
0556     struct fsl_mc_resource *next;
0557     struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
0558     struct fsl_mc_resource_pool *res_pool =
0559                     &mc_bus->resource_pools[pool_type];
0560     int free_count = 0;
0561 
0562     list_for_each_entry_safe(resource, next, &res_pool->free_list, node) {
0563         free_count++;
0564         devm_kfree(&mc_bus_dev->dev, resource);
0565     }
0566 }
0567 
0568 void fsl_mc_cleanup_all_resource_pools(struct fsl_mc_device *mc_bus_dev)
0569 {
0570     int pool_type;
0571 
0572     for (pool_type = 0; pool_type < FSL_MC_NUM_POOL_TYPES; pool_type++)
0573         fsl_mc_cleanup_resource_pool(mc_bus_dev, pool_type);
0574 }
0575 
0576 /*
0577  * fsl_mc_allocator_probe - callback invoked when an allocatable device is
0578  * being added to the system
0579  */
0580 static int fsl_mc_allocator_probe(struct fsl_mc_device *mc_dev)
0581 {
0582     enum fsl_mc_pool_type pool_type;
0583     struct fsl_mc_device *mc_bus_dev;
0584     struct fsl_mc_bus *mc_bus;
0585     int error;
0586 
0587     if (!fsl_mc_is_allocatable(mc_dev))
0588         return -EINVAL;
0589 
0590     mc_bus_dev = to_fsl_mc_device(mc_dev->dev.parent);
0591     if (!dev_is_fsl_mc(&mc_bus_dev->dev))
0592         return -EINVAL;
0593 
0594     mc_bus = to_fsl_mc_bus(mc_bus_dev);
0595     error = object_type_to_pool_type(mc_dev->obj_desc.type, &pool_type);
0596     if (error < 0)
0597         return error;
0598 
0599     error = fsl_mc_resource_pool_add_device(mc_bus, pool_type, mc_dev);
0600     if (error < 0)
0601         return error;
0602 
0603     dev_dbg(&mc_dev->dev,
0604         "Allocatable fsl-mc device bound to fsl_mc_allocator driver");
0605     return 0;
0606 }
0607 
0608 /*
0609  * fsl_mc_allocator_remove - callback invoked when an allocatable device is
0610  * being removed from the system
0611  */
0612 static int fsl_mc_allocator_remove(struct fsl_mc_device *mc_dev)
0613 {
0614     int error;
0615 
0616     if (!fsl_mc_is_allocatable(mc_dev))
0617         return -EINVAL;
0618 
0619     if (mc_dev->resource) {
0620         error = fsl_mc_resource_pool_remove_device(mc_dev);
0621         if (error < 0)
0622             return error;
0623     }
0624 
0625     dev_dbg(&mc_dev->dev,
0626         "Allocatable fsl-mc device unbound from fsl_mc_allocator driver");
0627     return 0;
0628 }
0629 
0630 static const struct fsl_mc_device_id match_id_table[] = {
0631     {
0632      .vendor = FSL_MC_VENDOR_FREESCALE,
0633      .obj_type = "dpbp",
0634     },
0635     {
0636      .vendor = FSL_MC_VENDOR_FREESCALE,
0637      .obj_type = "dpmcp",
0638     },
0639     {
0640      .vendor = FSL_MC_VENDOR_FREESCALE,
0641      .obj_type = "dpcon",
0642     },
0643     {.vendor = 0x0},
0644 };
0645 
0646 static struct fsl_mc_driver fsl_mc_allocator_driver = {
0647     .driver = {
0648            .name = "fsl_mc_allocator",
0649            .pm = NULL,
0650            },
0651     .match_id_table = match_id_table,
0652     .probe = fsl_mc_allocator_probe,
0653     .remove = fsl_mc_allocator_remove,
0654 };
0655 
0656 int __init fsl_mc_allocator_driver_init(void)
0657 {
0658     return fsl_mc_driver_register(&fsl_mc_allocator_driver);
0659 }
0660 
0661 void fsl_mc_allocator_driver_exit(void)
0662 {
0663     fsl_mc_driver_unregister(&fsl_mc_allocator_driver);
0664 }