drivers/bus/fsl-mc/dprc-driver.c

Source file repositories/reference/linux-study-clean/drivers/bus/fsl-mc/dprc-driver.c

File Facts

System
Linux kernel
Corpus path
drivers/bus/fsl-mc/dprc-driver.c
Extension
.c
Size
22139 bytes
Lines
873
Domain
Driver Families
Bucket
drivers/bus
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct fsl_mc_child_objs {
	int child_count;
	struct fsl_mc_obj_desc *child_array;
};

static bool fsl_mc_device_match(const struct fsl_mc_device *mc_dev,
				const struct fsl_mc_obj_desc *obj_desc)
{
	return mc_dev->obj_desc.id == obj_desc->id &&
	       strcmp(mc_dev->obj_desc.type, obj_desc->type) == 0;
}

static bool fsl_mc_obj_desc_is_allocatable(struct fsl_mc_obj_desc *obj)
{
	if (strcmp(obj->type, "dpmcp") == 0 ||
	    strcmp(obj->type, "dpcon") == 0 ||
	    strcmp(obj->type, "dpbp") == 0)
		return true;
	else
		return false;
}

static int __fsl_mc_device_remove_if_not_in_mc(struct device *dev, void *data)
{
	int i;
	struct fsl_mc_child_objs *objs;
	struct fsl_mc_device *mc_dev;

	if (!dev_is_fsl_mc(dev))
		return 0;

	mc_dev = to_fsl_mc_device(dev);
	objs = data;

	for (i = 0; i < objs->child_count; i++) {
		struct fsl_mc_obj_desc *obj_desc = &objs->child_array[i];

		if (strlen(obj_desc->type) != 0 &&
		    fsl_mc_device_match(mc_dev, obj_desc))
			break;
	}

	if (i == objs->child_count)
		fsl_mc_device_remove(mc_dev);

	return 0;
}

static int __fsl_mc_device_remove(struct device *dev, void *data)
{
	if (!dev_is_fsl_mc(dev))
		return 0;

	fsl_mc_device_remove(to_fsl_mc_device(dev));
	return 0;
}

/**
 * dprc_remove_devices - Removes devices for objects removed from a DPRC
 *
 * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
 * @obj_desc_array: array of object descriptors for child objects currently
 * present in the DPRC in the MC.
 * @num_child_objects_in_mc: number of entries in obj_desc_array
 *
 * Synchronizes the state of the Linux bus driver with the actual state of
 * the MC by removing devices that represent MC objects that have
 * been dynamically removed in the physical DPRC.
 */
void dprc_remove_devices(struct fsl_mc_device *mc_bus_dev,
			 struct fsl_mc_obj_desc *obj_desc_array,
			 int num_child_objects_in_mc)
{
	if (num_child_objects_in_mc != 0) {
		/*
		 * Remove child objects that are in the DPRC in Linux,
		 * but not in the MC:
		 */
		struct fsl_mc_child_objs objs;

		objs.child_count = num_child_objects_in_mc;
		objs.child_array = obj_desc_array;
		device_for_each_child(&mc_bus_dev->dev, &objs,
				      __fsl_mc_device_remove_if_not_in_mc);
	} else {
		/*
		 * There are no child objects for this DPRC in the MC.
		 * So, remove all the child devices from Linux:
		 */
		device_for_each_child(&mc_bus_dev->dev, NULL,

Annotation

Implementation Notes