示例#1
0
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;
}
示例#2
0
/**
 * 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;
}