|  | @@ -431,3 +431,181 @@ int omap_device_get_context_loss_count(struct platform_device *pdev)
 | 
	
		
			
				|  |  |  	u32 ret = 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	od = to_omap_device(pdev);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (od->hwmods_cnt)
 | 
	
		
			
				|  |  | +		ret = omap_hwmod_get_context_loss_count(od->hwmods[0]);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return ret;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * omap_device_count_resources - count number of struct resource entries needed
 | 
	
		
			
				|  |  | + * @od: struct omap_device *
 | 
	
		
			
				|  |  | + * @flags: Type of resources to include when counting (IRQ/DMA/MEM)
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Count the number of struct resource entries needed for this
 | 
	
		
			
				|  |  | + * omap_device @od.  Used by omap_device_build_ss() to determine how
 | 
	
		
			
				|  |  | + * much memory to allocate before calling
 | 
	
		
			
				|  |  | + * omap_device_fill_resources().  Returns the count.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +static int omap_device_count_resources(struct omap_device *od,
 | 
	
		
			
				|  |  | +				       unsigned long flags)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	int c = 0;
 | 
	
		
			
				|  |  | +	int i;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	for (i = 0; i < od->hwmods_cnt; i++)
 | 
	
		
			
				|  |  | +		c += omap_hwmod_count_resources(od->hwmods[i], flags);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	pr_debug("omap_device: %s: counted %d total resources across %d hwmods\n",
 | 
	
		
			
				|  |  | +		 od->pdev->name, c, od->hwmods_cnt);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return c;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * omap_device_fill_resources - fill in array of struct resource
 | 
	
		
			
				|  |  | + * @od: struct omap_device *
 | 
	
		
			
				|  |  | + * @res: pointer to an array of struct resource to be filled in
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Populate one or more empty struct resource pointed to by @res with
 | 
	
		
			
				|  |  | + * the resource data for this omap_device @od.  Used by
 | 
	
		
			
				|  |  | + * omap_device_build_ss() after calling omap_device_count_resources().
 | 
	
		
			
				|  |  | + * Ideally this function would not be needed at all.  If omap_device
 | 
	
		
			
				|  |  | + * replaces platform_device, then we can specify our own
 | 
	
		
			
				|  |  | + * get_resource()/ get_irq()/etc functions that use the underlying
 | 
	
		
			
				|  |  | + * omap_hwmod information.  Or if platform_device is extended to use
 | 
	
		
			
				|  |  | + * subarchitecture-specific function pointers, the various
 | 
	
		
			
				|  |  | + * platform_device functions can simply call omap_device internal
 | 
	
		
			
				|  |  | + * functions to get device resources.  Hacking around the existing
 | 
	
		
			
				|  |  | + * platform_device code wastes memory.  Returns 0.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +static int omap_device_fill_resources(struct omap_device *od,
 | 
	
		
			
				|  |  | +				      struct resource *res)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	int i, r;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	for (i = 0; i < od->hwmods_cnt; i++) {
 | 
	
		
			
				|  |  | +		r = omap_hwmod_fill_resources(od->hwmods[i], res);
 | 
	
		
			
				|  |  | +		res += r;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return 0;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * _od_fill_dma_resources - fill in array of struct resource with dma resources
 | 
	
		
			
				|  |  | + * @od: struct omap_device *
 | 
	
		
			
				|  |  | + * @res: pointer to an array of struct resource to be filled in
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Populate one or more empty struct resource pointed to by @res with
 | 
	
		
			
				|  |  | + * the dma resource data for this omap_device @od.  Used by
 | 
	
		
			
				|  |  | + * omap_device_alloc() after calling omap_device_count_resources().
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Ideally this function would not be needed at all.  If we have
 | 
	
		
			
				|  |  | + * mechanism to get dma resources from DT.
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Returns 0.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +static int _od_fill_dma_resources(struct omap_device *od,
 | 
	
		
			
				|  |  | +				      struct resource *res)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	int i, r;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	for (i = 0; i < od->hwmods_cnt; i++) {
 | 
	
		
			
				|  |  | +		r = omap_hwmod_fill_dma_resources(od->hwmods[i], res);
 | 
	
		
			
				|  |  | +		res += r;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return 0;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * omap_device_alloc - allocate an omap_device
 | 
	
		
			
				|  |  | + * @pdev: platform_device that will be included in this omap_device
 | 
	
		
			
				|  |  | + * @oh: ptr to the single omap_hwmod that backs this omap_device
 | 
	
		
			
				|  |  | + * @pdata: platform_data ptr to associate with the platform_device
 | 
	
		
			
				|  |  | + * @pdata_len: amount of memory pointed to by @pdata
 | 
	
		
			
				|  |  | + * @pm_lats: pointer to a omap_device_pm_latency array for this device
 | 
	
		
			
				|  |  | + * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Convenience function for allocating an omap_device structure and filling
 | 
	
		
			
				|  |  | + * hwmods, resources and pm_latency attributes.
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Returns an struct omap_device pointer or ERR_PTR() on error;
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +struct omap_device *omap_device_alloc(struct platform_device *pdev,
 | 
	
		
			
				|  |  | +					struct omap_hwmod **ohs, int oh_cnt,
 | 
	
		
			
				|  |  | +					struct omap_device_pm_latency *pm_lats,
 | 
	
		
			
				|  |  | +					int pm_lats_cnt)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	int ret = -ENOMEM;
 | 
	
		
			
				|  |  | +	struct omap_device *od;
 | 
	
		
			
				|  |  | +	struct resource *res = NULL;
 | 
	
		
			
				|  |  | +	int i, res_count;
 | 
	
		
			
				|  |  | +	struct omap_hwmod **hwmods;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	od = kzalloc(sizeof(struct omap_device), GFP_KERNEL);
 | 
	
		
			
				|  |  | +	if (!od) {
 | 
	
		
			
				|  |  | +		ret = -ENOMEM;
 | 
	
		
			
				|  |  | +		goto oda_exit1;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	od->hwmods_cnt = oh_cnt;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	hwmods = kmemdup(ohs, sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL);
 | 
	
		
			
				|  |  | +	if (!hwmods)
 | 
	
		
			
				|  |  | +		goto oda_exit2;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	od->hwmods = hwmods;
 | 
	
		
			
				|  |  | +	od->pdev = pdev;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/*
 | 
	
		
			
				|  |  | +	 * Non-DT Boot:
 | 
	
		
			
				|  |  | +	 *   Here, pdev->num_resources = 0, and we should get all the
 | 
	
		
			
				|  |  | +	 *   resources from hwmod.
 | 
	
		
			
				|  |  | +	 *
 | 
	
		
			
				|  |  | +	 * DT Boot:
 | 
	
		
			
				|  |  | +	 *   OF framework will construct the resource structure (currently
 | 
	
		
			
				|  |  | +	 *   does for MEM & IRQ resource) and we should respect/use these
 | 
	
		
			
				|  |  | +	 *   resources, killing hwmod dependency.
 | 
	
		
			
				|  |  | +	 *   If pdev->num_resources > 0, we assume that MEM & IRQ resources
 | 
	
		
			
				|  |  | +	 *   have been allocated by OF layer already (through DTB).
 | 
	
		
			
				|  |  | +	 *   As preparation for the future we examine the OF provided resources
 | 
	
		
			
				|  |  | +	 *   to see if we have DMA resources provided already. In this case
 | 
	
		
			
				|  |  | +	 *   there is no need to update the resources for the device, we use the
 | 
	
		
			
				|  |  | +	 *   OF provided ones.
 | 
	
		
			
				|  |  | +	 *
 | 
	
		
			
				|  |  | +	 * TODO: Once DMA resource is available from OF layer, we should
 | 
	
		
			
				|  |  | +	 *   kill filling any resources from hwmod.
 | 
	
		
			
				|  |  | +	 */
 | 
	
		
			
				|  |  | +	if (!pdev->num_resources) {
 | 
	
		
			
				|  |  | +		/* Count all resources for the device */
 | 
	
		
			
				|  |  | +		res_count = omap_device_count_resources(od, IORESOURCE_IRQ |
 | 
	
		
			
				|  |  | +							    IORESOURCE_DMA |
 | 
	
		
			
				|  |  | +							    IORESOURCE_MEM);
 | 
	
		
			
				|  |  | +	} else {
 | 
	
		
			
				|  |  | +		/* Take a look if we already have DMA resource via DT */
 | 
	
		
			
				|  |  | +		for (i = 0; i < pdev->num_resources; i++) {
 | 
	
		
			
				|  |  | +			struct resource *r = &pdev->resource[i];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			/* We have it, no need to touch the resources */
 | 
	
		
			
				|  |  | +			if (r->flags == IORESOURCE_DMA)
 | 
	
		
			
				|  |  | +				goto have_everything;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		/* Count only DMA resources for the device */
 | 
	
		
			
				|  |  | +		res_count = omap_device_count_resources(od, IORESOURCE_DMA);
 | 
	
		
			
				|  |  | +		/* The device has no DMA resource, no need for update */
 | 
	
		
			
				|  |  | +		if (!res_count)
 | 
	
		
			
				|  |  | +			goto have_everything;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		res_count += pdev->num_resources;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* Allocate resources memory to account for new resources */
 | 
	
		
			
				|  |  | +	res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
 | 
	
		
			
				|  |  | +	if (!res)
 | 
	
		
			
				|  |  | +		goto oda_exit3;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (!pdev->num_resources) {
 | 
	
		
			
				|  |  | +		dev_dbg(&pdev->dev, "%s: using %d resources from hwmod\n",
 | 
	
		
			
				|  |  | +			__func__, res_count);
 |