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, ®ion_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 error = translate_mc_addr(mc_dev, mc_region_type, 492 region_desc.base_offset, 493 ®ions[i].start); 494 if (error < 0) { 495 dev_err(parent_dev, 496 "Invalid MC offset: %#x (for %s.%d\'s region %d)\n", 497 region_desc.base_offset, 498 obj_desc->type, obj_desc->id, i); 499 goto error_cleanup_regions; 500 } 501 502 regions[i].end = regions[i].start + region_desc.size - 1; 503 regions[i].name = "fsl-mc object MMIO region"; 504 regions[i].flags = IORESOURCE_IO; 505 if (region_desc.flags & DPRC_REGION_CACHEABLE) 506 regions[i].flags |= IORESOURCE_CACHEABLE; 507 } 508 509 mc_dev->regions = regions; 510 return 0; 511 512 error_cleanup_regions: 513 kfree(regions); 514 return error; 515 } 516 517 /** 518 * fsl_mc_is_root_dprc - function to check if a given device is a root dprc 519 */ 520 bool fsl_mc_is_root_dprc(struct device *dev) 521 { 522 struct device *root_dprc_dev; 523 524 fsl_mc_get_root_dprc(dev, &root_dprc_dev); 525 if (!root_dprc_dev) 526 return false; 527 return dev == root_dprc_dev; 528 } 529 530 static void fsl_mc_device_release(struct device *dev) 531 { 532 struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); 533 534 kfree(mc_dev->regions); 535 536 if (is_fsl_mc_bus_dprc(mc_dev)) 537 kfree(to_fsl_mc_bus(mc_dev)); 538 else 539 kfree(mc_dev); 540 } 541 542 /** 543 * Add a newly discovered fsl-mc device to be visible in Linux 544 */ 545 int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, 546 struct fsl_mc_io *mc_io, 547 struct device *parent_dev, 548 struct fsl_mc_device **new_mc_dev) 549 { 550 int error; 551 struct fsl_mc_device *mc_dev = NULL; 552 struct fsl_mc_bus *mc_bus = NULL; 553 struct fsl_mc_device *parent_mc_dev; 554 555 if (dev_is_fsl_mc(parent_dev)) 556 parent_mc_dev = to_fsl_mc_device(parent_dev); 557 else 558 parent_mc_dev = NULL; 559 560 if (strcmp(obj_desc->type, "dprc") == 0) { 561 /* 562 * Allocate an MC bus device object: 563 */ 564 mc_bus = kzalloc(sizeof(*mc_bus), GFP_KERNEL); 565 if (!mc_bus) 566 return -ENOMEM; 567 568 mc_dev = &mc_bus->mc_dev; 569 } else { 570 /* 571 * Allocate a regular fsl_mc_device object: 572 */ 573 mc_dev = kzalloc(sizeof(*mc_dev), GFP_KERNEL); 574 if (!mc_dev) 575 return -ENOMEM; 576 } 577 578 mc_dev->obj_desc = *obj_desc; 579 mc_dev->mc_io = mc_io; 580 device_initialize(&mc_dev->dev); 581 mc_dev->dev.parent = parent_dev; 582 mc_dev->dev.bus = &fsl_mc_bus_type; 583 mc_dev->dev.release = fsl_mc_device_release; 584 mc_dev->dev.type = fsl_mc_get_device_type(obj_desc->type); 585 if (!mc_dev->dev.type) { 586 error = -ENODEV; 587 dev_err(parent_dev, "unknown device type %s\n", obj_desc->type); 588 goto error_cleanup_dev; 589 } 590 dev_set_name(&mc_dev->dev, "%s.%d", obj_desc->type, obj_desc->id); 591 592 if (strcmp(obj_desc->type, "dprc") == 0) { 593 struct fsl_mc_io *mc_io2; 594 595 mc_dev->flags |= FSL_MC_IS_DPRC; 596 597 /* 598 * To get the DPRC's ICID, we need to open the DPRC 599 * in get_dprc_icid(). For child DPRCs, we do so using the 600 * parent DPRC's MC portal instead of the child DPRC's MC 601 * portal, in case the child DPRC is already opened with 602 * its own portal (e.g., the DPRC used by AIOP). 603 * 604 * NOTE: There cannot be more than one active open for a 605 * given MC object, using the same MC portal. 606 */ 607 if (parent_mc_dev) { 608 /* 609 * device being added is a child DPRC device 610 */ 611 mc_io2 = parent_mc_dev->mc_io; 612 } else { 613 /* 614 * device being added is the root DPRC device 615 */ 616 if (!mc_io) { 617 error = -EINVAL; 618 goto error_cleanup_dev; 619 } 620 621 mc_io2 = mc_io; 622 } 623 624 error = get_dprc_icid(mc_io2, obj_desc->id, &mc_dev->icid); 625 if (error < 0) 626 goto error_cleanup_dev; 627 } else { 628 /* 629 * A non-DPRC object has to be a child of a DPRC, use the 630 * parent's ICID and interrupt domain. 631 */ 632 mc_dev->icid = parent_mc_dev->icid; 633 mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK; 634 mc_dev->dev.dma_mask = &mc_dev->dma_mask; 635 mc_dev->dev.coherent_dma_mask = mc_dev->dma_mask; 636 dev_set_msi_domain(&mc_dev->dev, 637 dev_get_msi_domain(&parent_mc_dev->dev)); 638 } 639 640 /* 641 * Get MMIO regions for the device from the MC: 642 * 643 * NOTE: the root DPRC is a special case as its MMIO region is 644 * obtained from the device tree 645 */ 646 if (parent_mc_dev && obj_desc->region_count != 0) { 647 error = fsl_mc_device_get_mmio_regions(mc_dev, 648 parent_mc_dev); 649 if (error < 0) 650 goto error_cleanup_dev; 651 } 652 653 /* 654 * The device-specific probe callback will get invoked by device_add() 655 */ 656 error = device_add(&mc_dev->dev); 657 if (error < 0) { 658 dev_err(parent_dev, 659 "device_add() failed for device %s: %d\n", 660 dev_name(&mc_dev->dev), error); 661 goto error_cleanup_dev; 662 } 663 664 dev_dbg(parent_dev, "added %s\n", dev_name(&mc_dev->dev)); 665 666 *new_mc_dev = mc_dev; 667 return 0; 668 669 error_cleanup_dev: 670 kfree(mc_dev->regions); 671 kfree(mc_bus); 672 kfree(mc_dev); 673 674 return error; 675 } 676 EXPORT_SYMBOL_GPL(fsl_mc_device_add); 677 678 /** 679 * fsl_mc_device_remove - Remove an fsl-mc device from being visible to 680 * Linux 681 * 682 * @mc_dev: Pointer to an fsl-mc device 683 */ 684 void fsl_mc_device_remove(struct fsl_mc_device *mc_dev) 685 { 686 /* 687 * The device-specific remove callback will get invoked by device_del() 688 */ 689 device_del(&mc_dev->dev); 690 put_device(&mc_dev->dev); 691 } 692 EXPORT_SYMBOL_GPL(fsl_mc_device_remove); 693 694 static int parse_mc_ranges(struct device *dev, 695 int *paddr_cells, 696 int *mc_addr_cells, 697 int *mc_size_cells, 698 const __be32 **ranges_start) 699 { 700 const __be32 *prop; 701 int range_tuple_cell_count; 702 int ranges_len; 703 int tuple_len; 704 struct device_node *mc_node = dev->of_node; 705 706 *ranges_start = of_get_property(mc_node, "ranges", &ranges_len); 707 if (!(*ranges_start) || !ranges_len) { 708 dev_warn(dev, 709 "missing or empty ranges property for device tree node '%pOFn'\n", 710 mc_node); 711 return 0; 712 } 713 714 *paddr_cells = of_n_addr_cells(mc_node); 715 716 prop = of_get_property(mc_node, "#address-cells", NULL); 717 if (prop) 718 *mc_addr_cells = be32_to_cpup(prop); 719 else 720 *mc_addr_cells = *paddr_cells; 721 722 prop = of_get_property(mc_node, "#size-cells", NULL); 723 if (prop) 724 *mc_size_cells = be32_to_cpup(prop); 725 else 726 *mc_size_cells = of_n_size_cells(mc_node); 727 728 range_tuple_cell_count = *paddr_cells + *mc_addr_cells + 729 *mc_size_cells; 730 731 tuple_len = range_tuple_cell_count * sizeof(__be32); 732 if (ranges_len % tuple_len != 0) { 733 dev_err(dev, "malformed ranges property '%pOFn'\n", mc_node); 734 return -EINVAL; 735 } 736 737 return ranges_len / tuple_len; 738 } 739 740 static int get_mc_addr_translation_ranges(struct device *dev, 741 struct fsl_mc_addr_translation_range 742 **ranges, 743 u8 *num_ranges) 744 { 745 int ret; 746 int paddr_cells; 747 int mc_addr_cells; 748 int mc_size_cells; 749 int i; 750 const __be32 *ranges_start; 751 const __be32 *cell; 752 753 ret = parse_mc_ranges(dev, 754 &paddr_cells, 755 &mc_addr_cells, 756 &mc_size_cells, 757 &ranges_start); 758 if (ret < 0) 759 return ret; 760 761 *num_ranges = ret; 762 if (!ret) { 763 /* 764 * Missing or empty ranges property ("ranges;") for the 765 * 'fsl,qoriq-mc' node. In this case, identity mapping 766 * will be used. 767 */ 768 *ranges = NULL; 769 return 0; 770 } 771 772 *ranges = devm_kcalloc(dev, *num_ranges, 773 sizeof(struct fsl_mc_addr_translation_range), 774 GFP_KERNEL); 775 if (!(*ranges)) 776 return -ENOMEM; 777 778 cell = ranges_start; 779 for (i = 0; i < *num_ranges; ++i) { 780 struct fsl_mc_addr_translation_range *range = &(*ranges)[i]; 781 782 range->mc_region_type = of_read_number(cell, 1); 783 range->start_mc_offset = of_read_number(cell + 1, 784 mc_addr_cells - 1); 785 cell += mc_addr_cells; 786 range->start_phys_addr = of_read_number(cell, paddr_cells); 787 cell += paddr_cells; 788 range->end_mc_offset = range->start_mc_offset + 789 of_read_number(cell, mc_size_cells); 790 791 cell += mc_size_cells; 792 } 793 794 return 0; 795 } 796 797 /** 798 * fsl_mc_bus_probe - callback invoked when the root MC bus is being 799 * added 800 */ 801 static int fsl_mc_bus_probe(struct platform_device *pdev) 802 { 803 struct fsl_mc_obj_desc obj_desc; 804 int error; 805 struct fsl_mc *mc; 806 struct fsl_mc_device *mc_bus_dev = NULL; 807 struct fsl_mc_io *mc_io = NULL; 808 int container_id; 809 phys_addr_t mc_portal_phys_addr; 810 u32 mc_portal_size; 811 struct mc_version mc_version; 812 struct resource res; 813 814 mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL); 815 if (!mc) 816 return -ENOMEM; 817 818 platform_set_drvdata(pdev, mc); 819 820 /* 821 * Get physical address of MC portal for the root DPRC: 822 */ 823 error = of_address_to_resource(pdev->dev.of_node, 0, &res); 824 if (error < 0) { 825 dev_err(&pdev->dev, 826 "of_address_to_resource() failed for %pOF\n", 827 pdev->dev.of_node); 828 return error; 829 } 830 831 mc_portal_phys_addr = res.start; 832 mc_portal_size = resource_size(&res); 833 error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr, 834 mc_portal_size, NULL, 835 FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, &mc_io); 836 if (error < 0) 837 return error; 838 839 error = mc_get_version(mc_io, 0, &mc_version); 840 if (error != 0) { 841 dev_err(&pdev->dev, 842 "mc_get_version() failed with error %d\n", error); 843 goto error_cleanup_mc_io; 844 } 845 846 dev_info(&pdev->dev, "MC firmware version: %u.%u.%u\n", 847 mc_version.major, mc_version.minor, mc_version.revision); 848 849 error = get_mc_addr_translation_ranges(&pdev->dev, 850 &mc->translation_ranges, 851 &mc->num_translation_ranges); 852 if (error < 0) 853 goto error_cleanup_mc_io; 854 855 error = dprc_get_container_id(mc_io, 0, &container_id); 856 if (error < 0) { 857 dev_err(&pdev->dev, 858 "dprc_get_container_id() failed: %d\n", error); 859 goto error_cleanup_mc_io; 860 } 861 862 memset(&obj_desc, 0, sizeof(struct fsl_mc_obj_desc)); 863 error = dprc_get_api_version(mc_io, 0, 864 &obj_desc.ver_major, 865 &obj_desc.ver_minor); 866 if (error < 0) 867 goto error_cleanup_mc_io; 868 869 obj_desc.vendor = FSL_MC_VENDOR_FREESCALE; 870 strcpy(obj_desc.type, "dprc"); 871 obj_desc.id = container_id; 872 obj_desc.irq_count = 1; 873 obj_desc.region_count = 0; 874 875 error = fsl_mc_device_add(&obj_desc, mc_io, &pdev->dev, &mc_bus_dev); 876 if (error < 0) 877 goto error_cleanup_mc_io; 878 879 mc->root_mc_bus_dev = mc_bus_dev; 880 return 0; 881 882 error_cleanup_mc_io: 883 fsl_destroy_mc_io(mc_io); 884 return error; 885 } 886 887 /** 888 * fsl_mc_bus_remove - callback invoked when the root MC bus is being 889 * removed 890 */ 891 static int fsl_mc_bus_remove(struct platform_device *pdev) 892 { 893 struct fsl_mc *mc = platform_get_drvdata(pdev); 894 895 if (!fsl_mc_is_root_dprc(&mc->root_mc_bus_dev->dev)) 896 return -EINVAL; 897 898 fsl_mc_device_remove(mc->root_mc_bus_dev); 899 900 fsl_destroy_mc_io(mc->root_mc_bus_dev->mc_io); 901 mc->root_mc_bus_dev->mc_io = NULL; 902 903 return 0; 904 } 905 906 static const struct of_device_id fsl_mc_bus_match_table[] = { 907 {.compatible = "fsl,qoriq-mc",}, 908 {}, 909 }; 910 911 MODULE_DEVICE_TABLE(of, fsl_mc_bus_match_table); 912 913 static struct platform_driver fsl_mc_bus_driver = { 914 .driver = { 915 .name = "fsl_mc_bus", 916 .pm = NULL, 917 .of_match_table = fsl_mc_bus_match_table, 918 }, 919 .probe = fsl_mc_bus_probe, 920 .remove = fsl_mc_bus_remove, 921 }; 922 923 static int __init fsl_mc_bus_driver_init(void) 924 { 925 int error; 926 927 error = bus_register(&fsl_mc_bus_type); 928 if (error < 0) { 929 pr_err("bus type registration failed: %d\n", error); 930 goto error_cleanup_cache; 931 } 932 933 error = platform_driver_register(&fsl_mc_bus_driver); 934 if (error < 0) { 935 pr_err("platform_driver_register() failed: %d\n", error); 936 goto error_cleanup_bus; 937 } 938 939 error = dprc_driver_init(); 940 if (error < 0) 941 goto error_cleanup_driver; 942 943 error = fsl_mc_allocator_driver_init(); 944 if (error < 0) 945 goto error_cleanup_dprc_driver; 946 947 return 0; 948 949 error_cleanup_dprc_driver: 950 dprc_driver_exit(); 951 952 error_cleanup_driver: 953 platform_driver_unregister(&fsl_mc_bus_driver); 954 955 error_cleanup_bus: 956 bus_unregister(&fsl_mc_bus_type); 957 958 error_cleanup_cache: 959 return error; 960 } 961 postcore_initcall(fsl_mc_bus_driver_init); 962