int fsl_mc_ldpaa_init(bd_t *bis) { int i, error = 0; int dprc_opened = 0, container_id; int num_child_objects = 0; error = mc_init(); if (error < 0) goto error; error = dprc_get_container_id(dflt_mc_io, MC_CMD_NO_FLAGS, &container_id); if (error < 0) { printf("dprc_get_container_id() failed: %d\n", error); goto error; } debug("fsl-mc: Container id=0x%x\n", container_id); error = dprc_open(dflt_mc_io, MC_CMD_NO_FLAGS, container_id, &dflt_dprc_handle); if (error < 0) { printf("dprc_open() failed: %d\n", error); goto error; } dprc_opened = true; error = dprc_get_obj_count(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dprc_handle, &num_child_objects); if (error < 0) { printf("dprc_get_obj_count() failed: %d\n", error); goto error; } debug("Total child in container %d = %d\n", container_id, num_child_objects); if (num_child_objects != 0) { /* * Discover objects currently in the DPRC container in the MC: */ for (i = 0; i < num_child_objects; i++) error = dprc_scan_container_obj(dflt_dprc_handle, "dpbp", i); for (i = 0; i < num_child_objects; i++) error = dprc_scan_container_obj(dflt_dprc_handle, "dpio", i); for (i = 0; i < num_child_objects; i++) error = dprc_scan_container_obj(dflt_dprc_handle, "dpni", i); } error: if (dprc_opened) dprc_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dprc_handle); return error; }
/** * dprc_scan_objects - Discover objects in a DPRC * * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object * @total_irq_count: total number of IRQs needed by objects in the DPRC. * * Detects objects added and removed from a DPRC and synchronizes the * state of the Linux bus driver, MC by adding and removing * devices accordingly. * Two types of devices can be found in a DPRC: allocatable objects (e.g., * dpbp, dpmcp) and non-allocatable devices (e.g., dprc, dpni). * All allocatable devices needed to be probed before all non-allocatable * devices, to ensure that device drivers for non-allocatable * devices can allocate any type of allocatable devices. * That is, we need to ensure that the corresponding resource pools are * populated before they can get allocation requests from probe callbacks * of the device drivers for the non-allocatable devices. */ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev, unsigned int *total_irq_count) { int num_child_objects; int dprc_get_obj_failures; int error; unsigned int irq_count = mc_bus_dev->obj_desc.irq_count; struct dprc_obj_desc *child_obj_desc_array = NULL; error = dprc_get_obj_count(mc_bus_dev->mc_io, 0, mc_bus_dev->mc_handle, &num_child_objects); if (error < 0) { dev_err(&mc_bus_dev->dev, "dprc_get_obj_count() failed: %d\n", error); return error; } if (num_child_objects != 0) { int i; child_obj_desc_array = devm_kmalloc_array(&mc_bus_dev->dev, num_child_objects, sizeof(*child_obj_desc_array), GFP_KERNEL); if (!child_obj_desc_array) return -ENOMEM; /* * Discover objects currently present in the physical DPRC: */ dprc_get_obj_failures = 0; for (i = 0; i < num_child_objects; i++) { struct dprc_obj_desc *obj_desc = &child_obj_desc_array[i]; error = dprc_get_obj(mc_bus_dev->mc_io, 0, mc_bus_dev->mc_handle, i, obj_desc); if (error < 0) { dev_err(&mc_bus_dev->dev, "dprc_get_obj(i=%d) failed: %d\n", i, error); /* * Mark the obj entry as "invalid", by using the * empty string as obj type: */ obj_desc->type[0] = '\0'; obj_desc->id = error; dprc_get_obj_failures++; continue; } /* * add a quirk for all versions of dpsec < 4.0...none * are coherent regardless of what the MC reports. */ if ((strcmp(obj_desc->type, "dpseci") == 0) && (obj_desc->ver_major < 4)) obj_desc->flags |= DPRC_OBJ_FLAG_NO_MEM_SHAREABILITY; irq_count += obj_desc->irq_count; dev_dbg(&mc_bus_dev->dev, "Discovered object: type %s, id %d\n", obj_desc->type, obj_desc->id); } if (dprc_get_obj_failures != 0) { dev_err(&mc_bus_dev->dev, "%d out of %d devices could not be retrieved\n", dprc_get_obj_failures, num_child_objects); } } *total_irq_count = irq_count; dprc_remove_devices(mc_bus_dev, child_obj_desc_array, num_child_objects); dprc_add_new_devices(mc_bus_dev, child_obj_desc_array, num_child_objects); if (child_obj_desc_array) devm_kfree(&mc_bus_dev->dev, child_obj_desc_array); return 0; }