int __init omap3xxx_hwmod_init()

in mach-omap2/omap_hwmod_3xxx_data.c [2588:2696]


int __init omap3xxx_hwmod_init(void)
{
	int r;
	struct omap_hwmod_ocp_if **h = NULL, **h_sham = NULL;
	struct device_node *bus;
	unsigned int rev;

	omap_hwmod_init();

	/* Register hwmod links common to all OMAP3 */
	r = omap_hwmod_register_links(omap3xxx_hwmod_ocp_ifs);
	if (r < 0)
		return r;

	rev = omap_rev();

	/*
	 * Register hwmod links common to individual OMAP3 families, all
	 * silicon revisions (e.g., 34xx, or AM3505/3517, or 36xx)
	 * All possible revisions should be included in this conditional.
	 */
	if (rev == OMAP3430_REV_ES1_0 || rev == OMAP3430_REV_ES2_0 ||
	    rev == OMAP3430_REV_ES2_1 || rev == OMAP3430_REV_ES3_0 ||
	    rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2) {
		h = omap34xx_hwmod_ocp_ifs;
		h_sham = omap34xx_sham_hwmod_ocp_ifs;
	} else if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) {
		h = am35xx_hwmod_ocp_ifs;
		h_sham = am35xx_sham_hwmod_ocp_ifs;
	} else if (rev == OMAP3630_REV_ES1_0 || rev == OMAP3630_REV_ES1_1 ||
		   rev == OMAP3630_REV_ES1_2) {
		h = omap36xx_hwmod_ocp_ifs;
		h_sham = omap36xx_sham_hwmod_ocp_ifs;
	} else {
		WARN(1, "OMAP3 hwmod family init: unknown chip type\n");
		return -EINVAL;
	}

	r = omap_hwmod_register_links(h);
	if (r < 0)
		return r;

	/*
	 * Register crypto hwmod links only if they are not disabled in DT.
	 * If DT information is missing, enable them only for GP devices.
	 */

	bus = of_find_node_by_name(NULL, "ocp");

	if (h_sham && omap3xxx_hwmod_is_hs_ip_block_usable(bus, "sham")) {
		r = omap_hwmod_register_links(h_sham);
		if (r < 0)
			goto put_node;
	}

	of_node_put(bus);

	/*
	 * Register hwmod links specific to certain ES levels of a
	 * particular family of silicon (e.g., 34xx ES1.0)
	 */
	h = NULL;
	if (rev == OMAP3430_REV_ES1_0) {
		h = omap3430es1_hwmod_ocp_ifs;
	} else if (rev == OMAP3430_REV_ES2_0 || rev == OMAP3430_REV_ES2_1 ||
		   rev == OMAP3430_REV_ES3_0 || rev == OMAP3430_REV_ES3_1 ||
		   rev == OMAP3430_REV_ES3_1_2) {
		h = omap3430es2plus_hwmod_ocp_ifs;
	}

	if (h) {
		r = omap_hwmod_register_links(h);
		if (r < 0)
			return r;
	}

	h = NULL;
	if (rev == OMAP3430_REV_ES1_0 || rev == OMAP3430_REV_ES2_0 ||
	    rev == OMAP3430_REV_ES2_1) {
		h = omap3430_pre_es3_hwmod_ocp_ifs;
	} else if (rev == OMAP3430_REV_ES3_0 || rev == OMAP3430_REV_ES3_1 ||
		   rev == OMAP3430_REV_ES3_1_2) {
		h = omap3430_es3plus_hwmod_ocp_ifs;
	}

	if (h)
		r = omap_hwmod_register_links(h);
	if (r < 0)
		return r;

	/*
	 * DSS code presumes that dss_core hwmod is handled first,
	 * _before_ any other DSS related hwmods so register common
	 * DSS hwmod links last to ensure that dss_core is already
	 * registered.  Otherwise some change things may happen, for
	 * ex. if dispc is handled before dss_core and DSS is enabled
	 * in bootloader DISPC will be reset with outputs enabled
	 * which sometimes leads to unrecoverable L3 error.  XXX The
	 * long-term fix to this is to ensure hwmods are set up in
	 * dependency order in the hwmod core code.
	 */
	r = omap_hwmod_register_links(omap3xxx_dss_hwmod_ocp_ifs);

	return r;

put_node:
	of_node_put(bus);
	return r;
}