static int arm_cmn_init_dtcs()

in arm-cmn.c [1578:1621]


static int arm_cmn_init_dtcs(struct arm_cmn *cmn)
{
	struct arm_cmn_node *dn, *xp;
	int dtc_idx = 0;
	u8 dtcs_present = (1 << cmn->num_dtcs) - 1;

	cmn->dtc = devm_kcalloc(cmn->dev, cmn->num_dtcs, sizeof(cmn->dtc[0]), GFP_KERNEL);
	if (!cmn->dtc)
		return -ENOMEM;

	sort(cmn->dns, cmn->num_dns, sizeof(cmn->dns[0]), arm_cmn_node_cmp, NULL);

	cmn->xps = arm_cmn_node(cmn, CMN_TYPE_XP);

	for (dn = cmn->dns; dn->type; dn++) {
		if (dn->type == CMN_TYPE_XP) {
			dn->dtc &= dtcs_present;
			continue;
		}

		xp = arm_cmn_node_to_xp(cmn, dn);
		dn->dtm = xp->dtm;
		if (cmn->multi_dtm)
			dn->dtm += arm_cmn_nid(cmn, dn->id).port / 2;

		if (dn->type == CMN_TYPE_DTC) {
			int err;
			/* We do at least know that a DTC's XP must be in that DTC's domain */
			if (xp->dtc == 0xf)
				xp->dtc = 1 << dtc_idx;
			err = arm_cmn_init_dtc(cmn, dn, dtc_idx++);
			if (err)
				return err;
		}

		/* To the PMU, RN-Ds don't add anything over RN-Is, so smoosh them together */
		if (dn->type == CMN_TYPE_RND)
			dn->type = CMN_TYPE_RNI;
	}

	writel_relaxed(CMN_DT_DTC_CTL_DT_EN, cmn->dtc[0].base + CMN_DT_DTC_CTL);

	return 0;
}