int omap_hwmod_init_module()

in mach-omap2/omap_hwmod.c [3544:3630]


int omap_hwmod_init_module(struct device *dev,
			   const struct ti_sysc_module_data *data,
			   struct ti_sysc_cookie *cookie)
{
	struct omap_hwmod *oh;
	struct sysc_regbits *sysc_fields;
	s32 rev_offs, sysc_offs, syss_offs;
	u32 sysc_flags, idlemodes;
	int error;

	if (!dev || !data || !data->name || !cookie)
		return -EINVAL;

	oh = _lookup(data->name);
	if (!oh) {
		oh = kzalloc(sizeof(*oh), GFP_KERNEL);
		if (!oh)
			return -ENOMEM;

		oh->name = data->name;
		oh->_state = _HWMOD_STATE_UNKNOWN;
		lockdep_register_key(&oh->hwmod_key);

		/* Unused, can be handled by PRM driver handling resets */
		oh->prcm.omap4.flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT;

		oh->class = kzalloc(sizeof(*oh->class), GFP_KERNEL);
		if (!oh->class) {
			kfree(oh);
			return -ENOMEM;
		}

		omap_hwmod_init_reset_quirks(dev, oh, data);

		oh->class->name = data->name;
		mutex_lock(&list_lock);
		error = _register(oh);
		mutex_unlock(&list_lock);
	}

	cookie->data = oh;

	error = omap_hwmod_init_regbits(dev, oh, data, &sysc_fields);
	if (error)
		return error;

	error = omap_hwmod_init_reg_offs(dev, data, &rev_offs,
					 &sysc_offs, &syss_offs);
	if (error)
		return error;

	error = omap_hwmod_init_sysc_flags(dev, data, &sysc_flags);
	if (error)
		return error;

	error = omap_hwmod_init_idlemodes(dev, data, &idlemodes);
	if (error)
		return error;

	if (data->cfg->quirks & SYSC_QUIRK_NO_IDLE)
		oh->flags |= HWMOD_NO_IDLE;
	if (data->cfg->quirks & SYSC_QUIRK_NO_IDLE_ON_INIT)
		oh->flags |= HWMOD_INIT_NO_IDLE;
	if (data->cfg->quirks & SYSC_QUIRK_NO_RESET_ON_INIT)
		oh->flags |= HWMOD_INIT_NO_RESET;
	if (data->cfg->quirks & SYSC_QUIRK_USE_CLOCKACT)
		oh->flags |= HWMOD_SET_DEFAULT_CLOCKACT;
	if (data->cfg->quirks & SYSC_QUIRK_SWSUP_SIDLE)
		oh->flags |= HWMOD_SWSUP_SIDLE;
	if (data->cfg->quirks & SYSC_QUIRK_SWSUP_SIDLE_ACT)
		oh->flags |= HWMOD_SWSUP_SIDLE_ACT;
	if (data->cfg->quirks & SYSC_QUIRK_SWSUP_MSTANDBY)
		oh->flags |= HWMOD_SWSUP_MSTANDBY;
	if (data->cfg->quirks & SYSC_QUIRK_CLKDM_NOAUTO)
		oh->flags |= HWMOD_CLKDM_NOAUTO;

	error = omap_hwmod_check_module(dev, oh, data, sysc_fields,
					rev_offs, sysc_offs, syss_offs,
					sysc_flags, idlemodes);
	if (!error)
		return error;

	return omap_hwmod_allocate_module(dev, oh, data, sysc_fields,
					  cookie->clkdm, rev_offs,
					  sysc_offs, syss_offs,
					  sysc_flags, idlemodes);
}