|  | @@ -2614,3 +2614,118 @@ static int __init _register(struct omap_hwmod *oh)
 | 
	
		
			
				|  |  |   * @sl: pointer to a struct omap_hwmod_link * for the slave link
 | 
	
		
			
				|  |  |   *
 | 
	
		
			
				|  |  |   * Return pointers to two struct omap_hwmod_link records, via the
 | 
	
		
			
				|  |  | + * addresses pointed to by @ml and @sl.  Will first attempt to return
 | 
	
		
			
				|  |  | + * memory allocated as part of a large initial block, but if that has
 | 
	
		
			
				|  |  | + * been exhausted, will allocate memory itself.  Since ideally this
 | 
	
		
			
				|  |  | + * second allocation path will never occur, the number of these
 | 
	
		
			
				|  |  | + * 'supplemental' allocations will be logged when debugging is
 | 
	
		
			
				|  |  | + * enabled.  Returns 0.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +static int __init _alloc_links(struct omap_hwmod_link **ml,
 | 
	
		
			
				|  |  | +			       struct omap_hwmod_link **sl)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	unsigned int sz;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if ((free_ls + LINKS_PER_OCP_IF) <= max_ls) {
 | 
	
		
			
				|  |  | +		*ml = &linkspace[free_ls++];
 | 
	
		
			
				|  |  | +		*sl = &linkspace[free_ls++];
 | 
	
		
			
				|  |  | +		return 0;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	sz = sizeof(struct omap_hwmod_link) * LINKS_PER_OCP_IF;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	*sl = NULL;
 | 
	
		
			
				|  |  | +	*ml = alloc_bootmem(sz);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	memset(*ml, 0, sz);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	*sl = (void *)(*ml) + sizeof(struct omap_hwmod_link);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	ls_supp++;
 | 
	
		
			
				|  |  | +	pr_debug("omap_hwmod: supplemental link allocations needed: %d\n",
 | 
	
		
			
				|  |  | +		 ls_supp * LINKS_PER_OCP_IF);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return 0;
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * _add_link - add an interconnect between two IP blocks
 | 
	
		
			
				|  |  | + * @oi: pointer to a struct omap_hwmod_ocp_if record
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Add struct omap_hwmod_link records connecting the master IP block
 | 
	
		
			
				|  |  | + * specified in @oi->master to @oi, and connecting the slave IP block
 | 
	
		
			
				|  |  | + * specified in @oi->slave to @oi.  This code is assumed to run before
 | 
	
		
			
				|  |  | + * preemption or SMP has been enabled, thus avoiding the need for
 | 
	
		
			
				|  |  | + * locking in this code.  Changes to this assumption will require
 | 
	
		
			
				|  |  | + * additional locking.  Returns 0.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +static int __init _add_link(struct omap_hwmod_ocp_if *oi)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	struct omap_hwmod_link *ml, *sl;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	pr_debug("omap_hwmod: %s -> %s: adding link\n", oi->master->name,
 | 
	
		
			
				|  |  | +		 oi->slave->name);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	_alloc_links(&ml, &sl);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	ml->ocp_if = oi;
 | 
	
		
			
				|  |  | +	INIT_LIST_HEAD(&ml->node);
 | 
	
		
			
				|  |  | +	list_add(&ml->node, &oi->master->master_ports);
 | 
	
		
			
				|  |  | +	oi->master->masters_cnt++;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	sl->ocp_if = oi;
 | 
	
		
			
				|  |  | +	INIT_LIST_HEAD(&sl->node);
 | 
	
		
			
				|  |  | +	list_add(&sl->node, &oi->slave->slave_ports);
 | 
	
		
			
				|  |  | +	oi->slave->slaves_cnt++;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return 0;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * _register_link - register a struct omap_hwmod_ocp_if
 | 
	
		
			
				|  |  | + * @oi: struct omap_hwmod_ocp_if *
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Registers the omap_hwmod_ocp_if record @oi.  Returns -EEXIST if it
 | 
	
		
			
				|  |  | + * has already been registered; -EINVAL if @oi is NULL or if the
 | 
	
		
			
				|  |  | + * record pointed to by @oi is missing required fields; or 0 upon
 | 
	
		
			
				|  |  | + * success.
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * XXX The data should be copied into bootmem, so the original data
 | 
	
		
			
				|  |  | + * should be marked __initdata and freed after init.  This would allow
 | 
	
		
			
				|  |  | + * unneeded omap_hwmods to be freed on multi-OMAP configurations.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +static int __init _register_link(struct omap_hwmod_ocp_if *oi)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	if (!oi || !oi->master || !oi->slave || !oi->user)
 | 
	
		
			
				|  |  | +		return -EINVAL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (oi->_int_flags & _OCPIF_INT_FLAGS_REGISTERED)
 | 
	
		
			
				|  |  | +		return -EEXIST;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	pr_debug("omap_hwmod: registering link from %s to %s\n",
 | 
	
		
			
				|  |  | +		 oi->master->name, oi->slave->name);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/*
 | 
	
		
			
				|  |  | +	 * Register the connected hwmods, if they haven't been
 | 
	
		
			
				|  |  | +	 * registered already
 | 
	
		
			
				|  |  | +	 */
 | 
	
		
			
				|  |  | +	if (oi->master->_state != _HWMOD_STATE_REGISTERED)
 | 
	
		
			
				|  |  | +		_register(oi->master);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (oi->slave->_state != _HWMOD_STATE_REGISTERED)
 | 
	
		
			
				|  |  | +		_register(oi->slave);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	_add_link(oi);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	oi->_int_flags |= _OCPIF_INT_FLAGS_REGISTERED;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return 0;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * _alloc_linkspace - allocate large block of hwmod links
 | 
	
		
			
				|  |  | + * @ois: pointer to an array of struct omap_hwmod_ocp_if records to count
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Allocate a large block of struct omap_hwmod_link records.  This
 | 
	
		
			
				|  |  | + * improves boot time significantly by avoiding the need to allocate
 | 
	
		
			
				|  |  | + * individual records one by one.  If the number of records to
 |