root/drivers/bus/fsl-mc/fsl-mc-bus.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fsl_mc_bus_match
  2. fsl_mc_bus_uevent
  3. fsl_mc_dma_configure
  4. modalias_show
  5. fsl_mc_get_device_type
  6. fsl_mc_driver_probe
  7. fsl_mc_driver_remove
  8. fsl_mc_driver_shutdown
  9. __fsl_mc_driver_register
  10. fsl_mc_driver_unregister
  11. mc_get_version
  12. fsl_mc_get_root_dprc
  13. get_dprc_attr
  14. get_dprc_icid
  15. translate_mc_addr
  16. fsl_mc_device_get_mmio_regions
  17. fsl_mc_is_root_dprc
  18. fsl_mc_device_release
  19. fsl_mc_device_add
  20. fsl_mc_device_remove
  21. parse_mc_ranges
  22. get_mc_addr_translation_ranges
  23. fsl_mc_bus_probe
  24. fsl_mc_bus_remove
  25. fsl_mc_bus_driver_init

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Freescale Management Complex (MC) bus driver
   4  *
   5  * Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
   6  * Author: German Rivera <German.Rivera@freescale.com>
   7  *
   8  */
   9 
  10 #define pr_fmt(fmt) "fsl-mc: " fmt
  11 
  12 #include <linux/module.h>
  13 #include <linux/of_device.h>
  14 #include <linux/of_address.h>
  15 #include <linux/ioport.h>
  16 #include <linux/slab.h>
  17 #include <linux/limits.h>
  18 #include <linux/bitops.h>
  19 #include <linux/msi.h>
  20 #include <linux/dma-mapping.h>
  21 
  22 #include "fsl-mc-private.h"
  23 
  24 /**
  25  * Default DMA mask for devices on a fsl-mc bus
  26  */
  27 #define FSL_MC_DEFAULT_DMA_MASK (~0ULL)
  28 
  29 /**
  30  * struct fsl_mc - Private data of a "fsl,qoriq-mc" platform device
  31  * @root_mc_bus_dev: fsl-mc device representing the root DPRC
  32  * @num_translation_ranges: number of entries in addr_translation_ranges
  33  * @translation_ranges: array of bus to system address translation ranges
  34  */
  35 struct fsl_mc {
  36         struct fsl_mc_device *root_mc_bus_dev;
  37         u8 num_translation_ranges;
  38         struct fsl_mc_addr_translation_range *translation_ranges;
  39 };
  40 
  41 /**
  42  * struct fsl_mc_addr_translation_range - bus to system address translation
  43  * range
  44  * @mc_region_type: Type of MC region for the range being translated
  45  * @start_mc_offset: Start MC offset of the range being translated
  46  * @end_mc_offset: MC offset of the first byte after the range (last MC
  47  * offset of the range is end_mc_offset - 1)
  48  * @start_phys_addr: system physical address corresponding to start_mc_addr
  49  */
  50 struct fsl_mc_addr_translation_range {
  51         enum dprc_region_type mc_region_type;
  52         u64 start_mc_offset;
  53         u64 end_mc_offset;
  54         phys_addr_t start_phys_addr;
  55 };
  56 
  57 /**
  58  * struct mc_version
  59  * @major: Major version number: incremented on API compatibility changes
  60  * @minor: Minor version number: incremented on API additions (that are
  61  *              backward compatible); reset when major version is incremented
  62  * @revision: Internal revision number: incremented on implementation changes
  63  *              and/or bug fixes that have no impact on API
  64  */
  65 struct mc_version {
  66         u32 major;
  67         u32 minor;
  68         u32 revision;
  69 };
  70 
  71 /**
  72  * fsl_mc_bus_match - device to driver matching callback
  73  * @dev: the fsl-mc device to match against
  74  * @drv: the device driver to search for matching fsl-mc object type
  75  * structures
  76  *
  77  * Returns 1 on success, 0 otherwise.
  78  */
  79 static int fsl_mc_bus_match(struct device *dev, struct device_driver *drv)
  80 {
  81         const struct fsl_mc_device_id *id;
  82         struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
  83         struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(drv);
  84         bool found = false;
  85 
  86         if (!mc_drv->match_id_table)
  87                 goto out;
  88 
  89         /*
  90          * If the object is not 'plugged' don't match.
  91          * Only exception is the root DPRC, which is a special case.
  92          */
  93         if ((mc_dev->obj_desc.state & FSL_MC_OBJ_STATE_PLUGGED) == 0 &&
  94             !fsl_mc_is_root_dprc(&mc_dev->dev))
  95                 goto out;
  96 
  97         /*
  98          * Traverse the match_id table of the given driver, trying to find
  99          * a matching for the given device.
 100          */
 101         for (id = mc_drv->match_id_table; id->vendor != 0x0; id++) {
 102                 if (id->vendor == mc_dev->obj_desc.vendor &&
 103                     strcmp(id->obj_type, mc_dev->obj_desc.type) == 0) {
 104                         found = true;
 105 
 106                         break;
 107                 }
 108         }
 109 
 110 out:
 111         dev_dbg(dev, "%smatched\n", found ? "" : "not ");
 112         return found;
 113 }
 114 
 115 /**
 116  * fsl_mc_bus_uevent - callback invoked when a device is added
 117  */
 118 static int fsl_mc_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
 119 {
 120         struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
 121 
 122         if (add_uevent_var(env, "MODALIAS=fsl-mc:v%08Xd%s",
 123                            mc_dev->obj_desc.vendor,
 124                            mc_dev->obj_desc.type))
 125                 return -ENOMEM;
 126 
 127         return 0;
 128 }
 129 
 130 static int fsl_mc_dma_configure(struct device *dev)
 131 {
 132         struct device *dma_dev = dev;
 133 
 134         while (dev_is_fsl_mc(dma_dev))
 135                 dma_dev = dma_dev->parent;
 136 
 137         return of_dma_configure(dev, dma_dev->of_node, 0);
 138 }
 139 
 140 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 141                              char *buf)
 142 {
 143         struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
 144 
 145         return sprintf(buf, "fsl-mc:v%08Xd%s\n", mc_dev->obj_desc.vendor,
 146                        mc_dev->obj_desc.type);
 147 }
 148 static DEVICE_ATTR_RO(modalias);
 149 
 150 static struct attribute *fsl_mc_dev_attrs[] = {
 151         &dev_attr_modalias.attr,
 152         NULL,
 153 };
 154 
 155 ATTRIBUTE_GROUPS(fsl_mc_dev);
 156 
 157 struct bus_type fsl_mc_bus_type = {
 158         .name = "fsl-mc",
 159         .match = fsl_mc_bus_match,
 160         .uevent = fsl_mc_bus_uevent,
 161         .dma_configure  = fsl_mc_dma_configure,
 162         .dev_groups = fsl_mc_dev_groups,
 163 };
 164 EXPORT_SYMBOL_GPL(fsl_mc_bus_type);
 165 
 166 struct device_type fsl_mc_bus_dprc_type = {
 167         .name = "fsl_mc_bus_dprc"
 168 };
 169 
 170 struct device_type fsl_mc_bus_dpni_type = {
 171         .name = "fsl_mc_bus_dpni"
 172 };
 173 
 174 struct device_type fsl_mc_bus_dpio_type = {
 175         .name = "fsl_mc_bus_dpio"
 176 };
 177 
 178 struct device_type fsl_mc_bus_dpsw_type = {
 179         .name = "fsl_mc_bus_dpsw"
 180 };
 181 
 182 struct device_type fsl_mc_bus_dpbp_type = {
 183         .name = "fsl_mc_bus_dpbp"
 184 };
 185 
 186 struct device_type fsl_mc_bus_dpcon_type = {
 187         .name = "fsl_mc_bus_dpcon"
 188 };
 189 
 190 struct device_type fsl_mc_bus_dpmcp_type = {
 191         .name = "fsl_mc_bus_dpmcp"
 192 };
 193 
 194 struct device_type fsl_mc_bus_dpmac_type = {
 195         .name = "fsl_mc_bus_dpmac"
 196 };
 197 
 198 struct device_type fsl_mc_bus_dprtc_type = {
 199         .name = "fsl_mc_bus_dprtc"
 200 };
 201 
 202 struct device_type fsl_mc_bus_dpseci_type = {
 203         .name = "fsl_mc_bus_dpseci"
 204 };
 205 
 206 static struct device_type *fsl_mc_get_device_type(const char *type)
 207 {
 208         static const struct {
 209                 struct device_type *dev_type;
 210                 const char *type;
 211         } dev_types[] = {
 212                 { &fsl_mc_bus_dprc_type, "dprc" },
 213                 { &fsl_mc_bus_dpni_type, "dpni" },
 214                 { &fsl_mc_bus_dpio_type, "dpio" },
 215                 { &fsl_mc_bus_dpsw_type, "dpsw" },
 216                 { &fsl_mc_bus_dpbp_type, "dpbp" },
 217                 { &fsl_mc_bus_dpcon_type, "dpcon" },
 218                 { &fsl_mc_bus_dpmcp_type, "dpmcp" },
 219                 { &fsl_mc_bus_dpmac_type, "dpmac" },
 220                 { &fsl_mc_bus_dprtc_type, "dprtc" },
 221                 { &fsl_mc_bus_dpseci_type, "dpseci" },
 222                 { NULL, NULL }
 223         };
 224         int i;
 225 
 226         for (i = 0; dev_types[i].dev_type; i++)
 227                 if (!strcmp(dev_types[i].type, type))
 228                         return dev_types[i].dev_type;
 229 
 230         return NULL;
 231 }
 232 
 233 static int fsl_mc_driver_probe(struct device *dev)
 234 {
 235         struct fsl_mc_driver *mc_drv;
 236         struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
 237         int error;
 238 
 239         mc_drv = to_fsl_mc_driver(dev->driver);
 240 
 241         error = mc_drv->probe(mc_dev);
 242         if (error < 0) {
 243                 if (error != -EPROBE_DEFER)
 244                         dev_err(dev, "%s failed: %d\n", __func__, error);
 245                 return error;
 246         }
 247 
 248         return 0;
 249 }
 250 
 251 static int fsl_mc_driver_remove(struct device *dev)
 252 {
 253         struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(dev->driver);
 254         struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
 255         int error;
 256 
 257         error = mc_drv->remove(mc_dev);
 258         if (error < 0) {
 259                 dev_err(dev, "%s failed: %d\n", __func__, error);
 260                 return error;
 261         }
 262 
 263         return 0;
 264 }
 265 
 266 static void fsl_mc_driver_shutdown(struct device *dev)
 267 {
 268         struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(dev->driver);
 269         struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
 270 
 271         mc_drv->shutdown(mc_dev);
 272 }
 273 
 274 /**
 275  * __fsl_mc_driver_register - registers a child device driver with the
 276  * MC bus
 277  *
 278  * This function is implicitly invoked from the registration function of
 279  * fsl_mc device drivers, which is generated by the
 280  * module_fsl_mc_driver() macro.
 281  */
 282 int __fsl_mc_driver_register(struct fsl_mc_driver *mc_driver,
 283                              struct module *owner)
 284 {
 285         int error;
 286 
 287         mc_driver->driver.owner = owner;
 288         mc_driver->driver.bus = &fsl_mc_bus_type;
 289 
 290         if (mc_driver->probe)
 291                 mc_driver->driver.probe = fsl_mc_driver_probe;
 292 
 293         if (mc_driver->remove)
 294                 mc_driver->driver.remove = fsl_mc_driver_remove;
 295 
 296         if (mc_driver->shutdown)
 297                 mc_driver->driver.shutdown = fsl_mc_driver_shutdown;
 298 
 299         error = driver_register(&mc_driver->driver);
 300         if (error < 0) {
 301                 pr_err("driver_register() failed for %s: %d\n",
 302                        mc_driver->driver.name, error);
 303                 return error;
 304         }
 305 
 306         return 0;
 307 }
 308 EXPORT_SYMBOL_GPL(__fsl_mc_driver_register);
 309 
 310 /**
 311  * fsl_mc_driver_unregister - unregisters a device driver from the
 312  * MC bus
 313  */
 314 void fsl_mc_driver_unregister(struct fsl_mc_driver *mc_driver)
 315 {
 316         driver_unregister(&mc_driver->driver);
 317 }
 318 EXPORT_SYMBOL_GPL(fsl_mc_driver_unregister);
 319 
 320 /**
 321  * mc_get_version() - Retrieves the Management Complex firmware
 322  *                      version information
 323  * @mc_io:              Pointer to opaque I/O object
 324  * @cmd_flags:          Command flags; one or more of 'MC_CMD_FLAG_'
 325  * @mc_ver_info:        Returned version information structure
 326  *
 327  * Return:      '0' on Success; Error code otherwise.
 328  */
 329 static int mc_get_version(struct fsl_mc_io *mc_io,
 330                           u32 cmd_flags,
 331                           struct mc_version *mc_ver_info)
 332 {
 333         struct fsl_mc_command cmd = { 0 };
 334         struct dpmng_rsp_get_version *rsp_params;
 335         int err;
 336 
 337         /* prepare command */
 338         cmd.header = mc_encode_cmd_header(DPMNG_CMDID_GET_VERSION,
 339                                           cmd_flags,
 340                                           0);
 341 
 342         /* send command to mc*/
 343         err = mc_send_command(mc_io, &cmd);
 344         if (err)
 345                 return err;
 346 
 347         /* retrieve response parameters */
 348         rsp_params = (struct dpmng_rsp_get_version *)cmd.params;
 349         mc_ver_info->revision = le32_to_cpu(rsp_params->revision);
 350         mc_ver_info->major = le32_to_cpu(rsp_params->version_major);
 351         mc_ver_info->minor = le32_to_cpu(rsp_params->version_minor);
 352 
 353         return 0;
 354 }
 355 
 356 /**
 357  * fsl_mc_get_root_dprc - function to traverse to the root dprc
 358  */
 359 static void fsl_mc_get_root_dprc(struct device *dev,
 360                                  struct device **root_dprc_dev)
 361 {
 362         if (!dev) {
 363                 *root_dprc_dev = NULL;
 364         } else if (!dev_is_fsl_mc(dev)) {
 365                 *root_dprc_dev = NULL;
 366         } else {
 367                 *root_dprc_dev = dev;
 368                 while (dev_is_fsl_mc((*root_dprc_dev)->parent))
 369                         *root_dprc_dev = (*root_dprc_dev)->parent;
 370         }
 371 }
 372 
 373 static int get_dprc_attr(struct fsl_mc_io *mc_io,
 374                          int container_id, struct dprc_attributes *attr)
 375 {
 376         u16 dprc_handle;
 377         int error;
 378 
 379         error = dprc_open(mc_io, 0, container_id, &dprc_handle);
 380         if (error < 0) {
 381                 dev_err(mc_io->dev, "dprc_open() failed: %d\n", error);
 382                 return error;
 383         }
 384 
 385         memset(attr, 0, sizeof(struct dprc_attributes));
 386         error = dprc_get_attributes(mc_io, 0, dprc_handle, attr);
 387         if (error < 0) {
 388                 dev_err(mc_io->dev, "dprc_get_attributes() failed: %d\n",
 389                         error);
 390                 goto common_cleanup;
 391         }
 392 
 393         error = 0;
 394 
 395 common_cleanup:
 396         (void)dprc_close(mc_io, 0, dprc_handle);
 397         return error;
 398 }
 399 
 400 static int get_dprc_icid(struct fsl_mc_io *mc_io,
 401                          int container_id, u16 *icid)
 402 {
 403         struct dprc_attributes attr;
 404         int error;
 405 
 406         error = get_dprc_attr(mc_io, container_id, &attr);
 407         if (error == 0)
 408                 *icid = attr.icid;
 409 
 410         return error;
 411 }
 412 
 413 static int translate_mc_addr(struct fsl_mc_device *mc_dev,
 414                              enum dprc_region_type mc_region_type,
 415                              u64 mc_offset, phys_addr_t *phys_addr)
 416 {
 417         int i;
 418         struct device *root_dprc_dev;
 419         struct fsl_mc *mc;
 420 
 421         fsl_mc_get_root_dprc(&mc_dev->dev, &root_dprc_dev);
 422         mc = dev_get_drvdata(root_dprc_dev->parent);
 423 
 424         if (mc->num_translation_ranges == 0) {
 425                 /*
 426                  * Do identity mapping:
 427                  */
 428                 *phys_addr = mc_offset;
 429                 return 0;
 430         }
 431 
 432         for (i = 0; i < mc->num_translation_ranges; i++) {
 433                 struct fsl_mc_addr_translation_range *range =
 434                         &mc->translation_ranges[i];
 435 
 436                 if (mc_region_type == range->mc_region_type &&
 437                     mc_offset >= range->start_mc_offset &&
 438                     mc_offset < range->end_mc_offset) {
 439                         *phys_addr = range->start_phys_addr +
 440                                      (mc_offset - range->start_mc_offset);
 441                         return 0;
 442                 }
 443         }
 444 
 445         return -EFAULT;
 446 }
 447 
 448 static int fsl_mc_device_get_mmio_regions(struct fsl_mc_device *mc_dev,
 449                                           struct fsl_mc_device *mc_bus_dev)
 450 {
 451         int i;
 452         int error;
 453         struct resource *regions;
 454         struct fsl_mc_obj_desc *obj_desc = &mc_dev->obj_desc;
 455         struct device *parent_dev = mc_dev->dev.parent;
 456         enum dprc_region_type mc_region_type;
 457 
 458         if (is_fsl_mc_bus_dprc(mc_dev) ||
 459             is_fsl_mc_bus_dpmcp(mc_dev)) {
 460                 mc_region_type = DPRC_REGION_TYPE_MC_PORTAL;
 461         } else if (is_fsl_mc_bus_dpio(mc_dev)) {
 462                 mc_region_type = DPRC_REGION_TYPE_QBMAN_PORTAL;
 463         } else {
 464                 /*
 465                  * This function should not have been called for this MC object
 466                  * type, as this object type is not supposed to have MMIO
 467                  * regions
 468                  */
 469                 return -EINVAL;
 470         }
 471 
 472         regions = kmalloc_array(obj_desc->region_count,
 473                                 sizeof(regions[0]), GFP_KERNEL);
 474         if (!regions)
 475                 return -ENOMEM;
 476 
 477         for (i = 0; i < obj_desc->region_count; i++) {
 478                 struct dprc_region_desc region_desc;
 479 
 480                 error = dprc_get_obj_region(mc_bus_dev->mc_io,
 481                                             0,
 482                                             mc_bus_dev->mc_handle,
 483                                             obj_desc->type,
 484                                             obj_desc->id, i, &region_desc);
 485                 if (error < 0) {
 486                         dev_err(parent_dev,
 487                                 "dprc_get_obj_region() failed: %d\n", error);
 488                         goto error_cleanup_regions;
 489                 }
 490                 /*
 491                  * Older MC only returned region offset and no base address
 492                  * If base address is in the region_desc use it otherwise
 493                  * revert to old mechanism
 494                  */
 495                 if (region_desc.base_address)
 496                         regions[i].start = region_desc.base_address +
 497                                                 region_desc.base_offset;
 498                 else
 499                         error = translate_mc_addr(mc_dev, mc_region_type,
 500                                           region_desc.base_offset,
 501                                           &regions[i].start);
 502 
 503                 if (error < 0) {
 504                         dev_err(parent_dev,
 505                                 "Invalid MC offset: %#x (for %s.%d\'s region %d)\n",
 506                                 region_desc.base_offset,
 507                                 obj_desc->type, obj_desc->id, i);
 508                         goto error_cleanup_regions;
 509                 }
 510 
 511                 regions[i].end = regions[i].start + region_desc.size - 1;
 512                 regions[i].name = "fsl-mc object MMIO region";
 513                 regions[i].flags = IORESOURCE_IO;
 514                 if (region_desc.flags & DPRC_REGION_CACHEABLE)
 515                         regions[i].flags |= IORESOURCE_CACHEABLE;
 516                 if (region_desc.flags & DPRC_REGION_SHAREABLE)
 517                         regions[i].flags |= IORESOURCE_MEM;
 518         }
 519 
 520         mc_dev->regions = regions;
 521         return 0;
 522 
 523 error_cleanup_regions:
 524         kfree(regions);
 525         return error;
 526 }
 527 
 528 /**
 529  * fsl_mc_is_root_dprc - function to check if a given device is a root dprc
 530  */
 531 bool fsl_mc_is_root_dprc(struct device *dev)
 532 {
 533         struct device *root_dprc_dev;
 534 
 535         fsl_mc_get_root_dprc(dev, &root_dprc_dev);
 536         if (!root_dprc_dev)
 537                 return false;
 538         return dev == root_dprc_dev;
 539 }
 540 
 541 static void fsl_mc_device_release(struct device *dev)
 542 {
 543         struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
 544 
 545         kfree(mc_dev->regions);
 546 
 547         if (is_fsl_mc_bus_dprc(mc_dev))
 548                 kfree(to_fsl_mc_bus(mc_dev));
 549         else
 550                 kfree(mc_dev);
 551 }
 552 
 553 /**
 554  * Add a newly discovered fsl-mc device to be visible in Linux
 555  */
 556 int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc,
 557                       struct fsl_mc_io *mc_io,
 558                       struct device *parent_dev,
 559                       struct fsl_mc_device **new_mc_dev)
 560 {
 561         int error;
 562         struct fsl_mc_device *mc_dev = NULL;
 563         struct fsl_mc_bus *mc_bus = NULL;
 564         struct fsl_mc_device *parent_mc_dev;
 565 
 566         if (dev_is_fsl_mc(parent_dev))
 567                 parent_mc_dev = to_fsl_mc_device(parent_dev);
 568         else
 569                 parent_mc_dev = NULL;
 570 
 571         if (strcmp(obj_desc->type, "dprc") == 0) {
 572                 /*
 573                  * Allocate an MC bus device object:
 574                  */
 575                 mc_bus = kzalloc(sizeof(*mc_bus), GFP_KERNEL);
 576                 if (!mc_bus)
 577                         return -ENOMEM;
 578 
 579                 mc_dev = &mc_bus->mc_dev;
 580         } else {
 581                 /*
 582                  * Allocate a regular fsl_mc_device object:
 583                  */
 584                 mc_dev = kzalloc(sizeof(*mc_dev), GFP_KERNEL);
 585                 if (!mc_dev)
 586                         return -ENOMEM;
 587         }
 588 
 589         mc_dev->obj_desc = *obj_desc;
 590         mc_dev->mc_io = mc_io;
 591         device_initialize(&mc_dev->dev);
 592         mc_dev->dev.parent = parent_dev;
 593         mc_dev->dev.bus = &fsl_mc_bus_type;
 594         mc_dev->dev.release = fsl_mc_device_release;
 595         mc_dev->dev.type = fsl_mc_get_device_type(obj_desc->type);
 596         if (!mc_dev->dev.type) {
 597                 error = -ENODEV;
 598                 dev_err(parent_dev, "unknown device type %s\n", obj_desc->type);
 599                 goto error_cleanup_dev;
 600         }
 601         dev_set_name(&mc_dev->dev, "%s.%d", obj_desc->type, obj_desc->id);
 602 
 603         if (strcmp(obj_desc->type, "dprc") == 0) {
 604                 struct fsl_mc_io *mc_io2;
 605 
 606                 mc_dev->flags |= FSL_MC_IS_DPRC;
 607 
 608                 /*
 609                  * To get the DPRC's ICID, we need to open the DPRC
 610                  * in get_dprc_icid(). For child DPRCs, we do so using the
 611                  * parent DPRC's MC portal instead of the child DPRC's MC
 612                  * portal, in case the child DPRC is already opened with
 613                  * its own portal (e.g., the DPRC used by AIOP).
 614                  *
 615                  * NOTE: There cannot be more than one active open for a
 616                  * given MC object, using the same MC portal.
 617                  */
 618                 if (parent_mc_dev) {
 619                         /*
 620                          * device being added is a child DPRC device
 621                          */
 622                         mc_io2 = parent_mc_dev->mc_io;
 623                 } else {
 624                         /*
 625                          * device being added is the root DPRC device
 626                          */
 627                         if (!mc_io) {
 628                                 error = -EINVAL;
 629                                 goto error_cleanup_dev;
 630                         }
 631 
 632                         mc_io2 = mc_io;
 633                 }
 634 
 635                 error = get_dprc_icid(mc_io2, obj_desc->id, &mc_dev->icid);
 636                 if (error < 0)
 637                         goto error_cleanup_dev;
 638         } else {
 639                 /*
 640                  * A non-DPRC object has to be a child of a DPRC, use the
 641                  * parent's ICID and interrupt domain.
 642                  */
 643                 mc_dev->icid = parent_mc_dev->icid;
 644                 mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK;
 645                 mc_dev->dev.dma_mask = &mc_dev->dma_mask;
 646                 mc_dev->dev.coherent_dma_mask = mc_dev->dma_mask;
 647                 dev_set_msi_domain(&mc_dev->dev,
 648                                    dev_get_msi_domain(&parent_mc_dev->dev));
 649         }
 650 
 651         /*
 652          * Get MMIO regions for the device from the MC:
 653          *
 654          * NOTE: the root DPRC is a special case as its MMIO region is
 655          * obtained from the device tree
 656          */
 657         if (parent_mc_dev && obj_desc->region_count != 0) {
 658                 error = fsl_mc_device_get_mmio_regions(mc_dev,
 659                                                        parent_mc_dev);
 660                 if (error < 0)
 661                         goto error_cleanup_dev;
 662         }
 663 
 664         /*
 665          * The device-specific probe callback will get invoked by device_add()
 666          */
 667         error = device_add(&mc_dev->dev);
 668         if (error < 0) {
 669                 dev_err(parent_dev,
 670                         "device_add() failed for device %s: %d\n",
 671                         dev_name(&mc_dev->dev), error);
 672                 goto error_cleanup_dev;
 673         }
 674 
 675         dev_dbg(parent_dev, "added %s\n", dev_name(&mc_dev->dev));
 676 
 677         *new_mc_dev = mc_dev;
 678         return 0;
 679 
 680 error_cleanup_dev:
 681         kfree(mc_dev->regions);
 682         kfree(mc_bus);
 683         kfree(mc_dev);
 684 
 685         return error;
 686 }
 687 EXPORT_SYMBOL_GPL(fsl_mc_device_add);
 688 
 689 /**
 690  * fsl_mc_device_remove - Remove an fsl-mc device from being visible to
 691  * Linux
 692  *
 693  * @mc_dev: Pointer to an fsl-mc device
 694  */
 695 void fsl_mc_device_remove(struct fsl_mc_device *mc_dev)
 696 {
 697         /*
 698          * The device-specific remove callback will get invoked by device_del()
 699          */
 700         device_del(&mc_dev->dev);
 701         put_device(&mc_dev->dev);
 702 }
 703 EXPORT_SYMBOL_GPL(fsl_mc_device_remove);
 704 
 705 static int parse_mc_ranges(struct device *dev,
 706                            int *paddr_cells,
 707                            int *mc_addr_cells,
 708                            int *mc_size_cells,
 709                            const __be32 **ranges_start)
 710 {
 711         const __be32 *prop;
 712         int range_tuple_cell_count;
 713         int ranges_len;
 714         int tuple_len;
 715         struct device_node *mc_node = dev->of_node;
 716 
 717         *ranges_start = of_get_property(mc_node, "ranges", &ranges_len);
 718         if (!(*ranges_start) || !ranges_len) {
 719                 dev_warn(dev,
 720                          "missing or empty ranges property for device tree node '%pOFn'\n",
 721                          mc_node);
 722                 return 0;
 723         }
 724 
 725         *paddr_cells = of_n_addr_cells(mc_node);
 726 
 727         prop = of_get_property(mc_node, "#address-cells", NULL);
 728         if (prop)
 729                 *mc_addr_cells = be32_to_cpup(prop);
 730         else
 731                 *mc_addr_cells = *paddr_cells;
 732 
 733         prop = of_get_property(mc_node, "#size-cells", NULL);
 734         if (prop)
 735                 *mc_size_cells = be32_to_cpup(prop);
 736         else
 737                 *mc_size_cells = of_n_size_cells(mc_node);
 738 
 739         range_tuple_cell_count = *paddr_cells + *mc_addr_cells +
 740                                  *mc_size_cells;
 741 
 742         tuple_len = range_tuple_cell_count * sizeof(__be32);
 743         if (ranges_len % tuple_len != 0) {
 744                 dev_err(dev, "malformed ranges property '%pOFn'\n", mc_node);
 745                 return -EINVAL;
 746         }
 747 
 748         return ranges_len / tuple_len;
 749 }
 750 
 751 static int get_mc_addr_translation_ranges(struct device *dev,
 752                                           struct fsl_mc_addr_translation_range
 753                                                 **ranges,
 754                                           u8 *num_ranges)
 755 {
 756         int ret;
 757         int paddr_cells;
 758         int mc_addr_cells;
 759         int mc_size_cells;
 760         int i;
 761         const __be32 *ranges_start;
 762         const __be32 *cell;
 763 
 764         ret = parse_mc_ranges(dev,
 765                               &paddr_cells,
 766                               &mc_addr_cells,
 767                               &mc_size_cells,
 768                               &ranges_start);
 769         if (ret < 0)
 770                 return ret;
 771 
 772         *num_ranges = ret;
 773         if (!ret) {
 774                 /*
 775                  * Missing or empty ranges property ("ranges;") for the
 776                  * 'fsl,qoriq-mc' node. In this case, identity mapping
 777                  * will be used.
 778                  */
 779                 *ranges = NULL;
 780                 return 0;
 781         }
 782 
 783         *ranges = devm_kcalloc(dev, *num_ranges,
 784                                sizeof(struct fsl_mc_addr_translation_range),
 785                                GFP_KERNEL);
 786         if (!(*ranges))
 787                 return -ENOMEM;
 788 
 789         cell = ranges_start;
 790         for (i = 0; i < *num_ranges; ++i) {
 791                 struct fsl_mc_addr_translation_range *range = &(*ranges)[i];
 792 
 793                 range->mc_region_type = of_read_number(cell, 1);
 794                 range->start_mc_offset = of_read_number(cell + 1,
 795                                                         mc_addr_cells - 1);
 796                 cell += mc_addr_cells;
 797                 range->start_phys_addr = of_read_number(cell, paddr_cells);
 798                 cell += paddr_cells;
 799                 range->end_mc_offset = range->start_mc_offset +
 800                                      of_read_number(cell, mc_size_cells);
 801 
 802                 cell += mc_size_cells;
 803         }
 804 
 805         return 0;
 806 }
 807 
 808 /**
 809  * fsl_mc_bus_probe - callback invoked when the root MC bus is being
 810  * added
 811  */
 812 static int fsl_mc_bus_probe(struct platform_device *pdev)
 813 {
 814         struct fsl_mc_obj_desc obj_desc;
 815         int error;
 816         struct fsl_mc *mc;
 817         struct fsl_mc_device *mc_bus_dev = NULL;
 818         struct fsl_mc_io *mc_io = NULL;
 819         int container_id;
 820         phys_addr_t mc_portal_phys_addr;
 821         u32 mc_portal_size;
 822         struct mc_version mc_version;
 823         struct resource res;
 824 
 825         mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
 826         if (!mc)
 827                 return -ENOMEM;
 828 
 829         platform_set_drvdata(pdev, mc);
 830 
 831         /*
 832          * Get physical address of MC portal for the root DPRC:
 833          */
 834         error = of_address_to_resource(pdev->dev.of_node, 0, &res);
 835         if (error < 0) {
 836                 dev_err(&pdev->dev,
 837                         "of_address_to_resource() failed for %pOF\n",
 838                         pdev->dev.of_node);
 839                 return error;
 840         }
 841 
 842         mc_portal_phys_addr = res.start;
 843         mc_portal_size = resource_size(&res);
 844         error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr,
 845                                  mc_portal_size, NULL,
 846                                  FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, &mc_io);
 847         if (error < 0)
 848                 return error;
 849 
 850         error = mc_get_version(mc_io, 0, &mc_version);
 851         if (error != 0) {
 852                 dev_err(&pdev->dev,
 853                         "mc_get_version() failed with error %d\n", error);
 854                 goto error_cleanup_mc_io;
 855         }
 856 
 857         dev_info(&pdev->dev, "MC firmware version: %u.%u.%u\n",
 858                  mc_version.major, mc_version.minor, mc_version.revision);
 859 
 860         error = get_mc_addr_translation_ranges(&pdev->dev,
 861                                                &mc->translation_ranges,
 862                                                &mc->num_translation_ranges);
 863         if (error < 0)
 864                 goto error_cleanup_mc_io;
 865 
 866         error = dprc_get_container_id(mc_io, 0, &container_id);
 867         if (error < 0) {
 868                 dev_err(&pdev->dev,
 869                         "dprc_get_container_id() failed: %d\n", error);
 870                 goto error_cleanup_mc_io;
 871         }
 872 
 873         memset(&obj_desc, 0, sizeof(struct fsl_mc_obj_desc));
 874         error = dprc_get_api_version(mc_io, 0,
 875                                      &obj_desc.ver_major,
 876                                      &obj_desc.ver_minor);
 877         if (error < 0)
 878                 goto error_cleanup_mc_io;
 879 
 880         obj_desc.vendor = FSL_MC_VENDOR_FREESCALE;
 881         strcpy(obj_desc.type, "dprc");
 882         obj_desc.id = container_id;
 883         obj_desc.irq_count = 1;
 884         obj_desc.region_count = 0;
 885 
 886         error = fsl_mc_device_add(&obj_desc, mc_io, &pdev->dev, &mc_bus_dev);
 887         if (error < 0)
 888                 goto error_cleanup_mc_io;
 889 
 890         mc->root_mc_bus_dev = mc_bus_dev;
 891         return 0;
 892 
 893 error_cleanup_mc_io:
 894         fsl_destroy_mc_io(mc_io);
 895         return error;
 896 }
 897 
 898 /**
 899  * fsl_mc_bus_remove - callback invoked when the root MC bus is being
 900  * removed
 901  */
 902 static int fsl_mc_bus_remove(struct platform_device *pdev)
 903 {
 904         struct fsl_mc *mc = platform_get_drvdata(pdev);
 905 
 906         if (!fsl_mc_is_root_dprc(&mc->root_mc_bus_dev->dev))
 907                 return -EINVAL;
 908 
 909         fsl_mc_device_remove(mc->root_mc_bus_dev);
 910 
 911         fsl_destroy_mc_io(mc->root_mc_bus_dev->mc_io);
 912         mc->root_mc_bus_dev->mc_io = NULL;
 913 
 914         return 0;
 915 }
 916 
 917 static const struct of_device_id fsl_mc_bus_match_table[] = {
 918         {.compatible = "fsl,qoriq-mc",},
 919         {},
 920 };
 921 
 922 MODULE_DEVICE_TABLE(of, fsl_mc_bus_match_table);
 923 
 924 static struct platform_driver fsl_mc_bus_driver = {
 925         .driver = {
 926                    .name = "fsl_mc_bus",
 927                    .pm = NULL,
 928                    .of_match_table = fsl_mc_bus_match_table,
 929                    },
 930         .probe = fsl_mc_bus_probe,
 931         .remove = fsl_mc_bus_remove,
 932 };
 933 
 934 static int __init fsl_mc_bus_driver_init(void)
 935 {
 936         int error;
 937 
 938         error = bus_register(&fsl_mc_bus_type);
 939         if (error < 0) {
 940                 pr_err("bus type registration failed: %d\n", error);
 941                 goto error_cleanup_cache;
 942         }
 943 
 944         error = platform_driver_register(&fsl_mc_bus_driver);
 945         if (error < 0) {
 946                 pr_err("platform_driver_register() failed: %d\n", error);
 947                 goto error_cleanup_bus;
 948         }
 949 
 950         error = dprc_driver_init();
 951         if (error < 0)
 952                 goto error_cleanup_driver;
 953 
 954         error = fsl_mc_allocator_driver_init();
 955         if (error < 0)
 956                 goto error_cleanup_dprc_driver;
 957 
 958         return 0;
 959 
 960 error_cleanup_dprc_driver:
 961         dprc_driver_exit();
 962 
 963 error_cleanup_driver:
 964         platform_driver_unregister(&fsl_mc_bus_driver);
 965 
 966 error_cleanup_bus:
 967         bus_unregister(&fsl_mc_bus_type);
 968 
 969 error_cleanup_cache:
 970         return error;
 971 }
 972 postcore_initcall(fsl_mc_bus_driver_init);

/* [<][>][^][v][top][bottom][index][help] */