/*****************************************************************************
 @Function                FreePages
******************************************************************************/
static IMG_VOID FreePages(
	SYSMEM_Heap *			heap,
	IMG_HANDLE				hPagesHandle
)
{
    size_t numPages;
    SYSMEMU_sPages *     psPages = hPagesHandle;
    struct ion_client *ion_client;
    struct ion_handle *ion_handle;

    ion_client = heap->priv;

    if (psPages->bImported)
    {
		IMG_RESULT result = IMG_ERROR_FATAL;
		struct ion_client *pIONcl;
		struct ion_handle *ionHandle;

		DEBUG_REPORT(REPORT_MODULE_SYSMEM, "Releasing ion_handle 0x%p", psPages->pvImplData);

		IMG_ASSERT(psPages->pvImplData);
		ionHandle = (struct ion_handle *)psPages->pvImplData;

		pIONcl = get_ion_client();
		if (pIONcl) {
#if defined(ION_SYSTEM_HEAP)
			if (psPages->pvCpuKmAddr)
				ion_unmap_kernel(pIONcl, ionHandle);
#endif
			ion_free(pIONcl, ionHandle);
			result = IMG_SUCCESS;
		} else {
			REPORT(REPORT_MODULE_SYSMEM, REPORT_ERR, "Releasing cannot find ION client");
		}

        return;
    }

    if (psPages->bDuplicated)
    	return;

    /* Remove from the list of mappable regions */
    SYSBRGU_DestroyMappableRegion(psPages->hRegHandle);

    /* Free array with physical addresses */
    numPages = (psPages->ui32Size + HOST_MMU_PAGE_SIZE - 1)/HOST_MMU_PAGE_SIZE;
    IMG_BIGORSMALL_FREE(numPages * sizeof(*psPages->ppaPhysAddr), psPages->ppaPhysAddr);

    /* Free memory */
    ion_handle = psPages->pvImplData;

    if (psPages->pvCpuKmAddr)
        ion_unmap_kernel(ion_client, ion_handle);

    ion_free(ion_client, ion_handle);
}
/*!
******************************************************************************

 @Function                FreePages

******************************************************************************/
static IMG_VOID FreePages(
    SYSMEM_Heap *  heap,
    IMG_HANDLE     hPagesHandle
)
{
    struct priv_params *  prv = (struct priv_params *)heap->priv;
    SYSMEMU_sPages *      psPages = hPagesHandle;
    IMG_UINT32            ui32NoPages;
    IMG_UINT32            ui32PageIndex;
    IMG_UINT32            i;
    IMG_UINT32            physAddrArrSize;

    /* Calculate required no. of pages...*/
    ui32NoPages = (psPages->ui32Size + (HOST_MMU_PAGE_SIZE-1)) / HOST_MMU_PAGE_SIZE;

    /* If mapping then free on the copy of the page structure. */
    if (psPages->bImported)
    {
        if(IMG_NULL != psPages->ppaPhysAddr)
        {
            IMG_BIGORSMALL_FREE(ui32NoPages * sizeof(psPages->ppaPhysAddr[0]), psPages->ppaPhysAddr);
            psPages->ppaPhysAddr = IMG_NULL;
        }

        return;
    }

    if (psPages->bDuplicated)
    	return;

    /* Removed this from the list of mappable regions...*/
    SYSBRGU_DestroyMappableRegion(psPages->hRegHandle);

    /* Free memory...*/
    SYSOSKM_DisableInt();
    IMG_ASSERT((IMG_UINTPTR)psPages->pvCpuKmAddr >= prv->vstart);
    IMG_ASSERT((IMG_UINTPTR)psPages->pvCpuKmAddr < (prv->vstart + prv->size));

    /* Calculate page table size and index...*/
    physAddrArrSize = sizeof(psPages->ppaPhysAddr[0]) * ui32NoPages;
    ui32PageIndex = (IMG_UINT32) ((((IMG_UINTPTR)psPages->pvCpuKmAddr) - prv->vstart) / HOST_MMU_PAGE_SIZE);

    /* Mark pages as unallocated...*/
    for (i=0; i<ui32NoPages; i++)
    {
        IMG_ASSERT(prv->alloc_pool[ui32PageIndex+i]);
        prv->alloc_pool[ui32PageIndex+i] = IMG_FALSE;
    }
    prv->cur_index -= ui32NoPages;
    SYSOSKM_EnableInt();
    IMG_BIGORSMALL_FREE(physAddrArrSize, psPages->ppaPhysAddr);

}
/*!
******************************************************************************

 @Function                SYSMEMKM_FreePages

******************************************************************************/
static IMG_VOID FreePages(
    SYSMEM_Heap *  heap,
    IMG_HANDLE     hPagesHandle
)
{
    struct priv_params *  prv = (struct priv_params *)heap->priv;
    SYSMEMU_sPages *      psPages = hPagesHandle;
    IMG_UINT32            ui32NoPages;
    IMG_UINT32            physAddrArrSize;

    /* Calculate required no. of pages...*/
    ui32NoPages = (psPages->ui32Size + (HOST_MMU_PAGE_SIZE-1)) / HOST_MMU_PAGE_SIZE;

    /* If mapping then free on the copy of the page structure. */
    /* This will happen after we call this function by sysmemutils */
    if (psPages->bImported)
    {
        if(psPages->bMappingOnly && (IMG_NULL != psPages->ppaPhysAddr))
        {
            IMG_BIGORSMALL_FREE(ui32NoPages * sizeof(psPages->ppaPhysAddr[0]), psPages->ppaPhysAddr);
            psPages->ppaPhysAddr = IMG_NULL;
        }
        return;
    }

    IMG_ASSERT((!psPages->bMappingOnly));            /* Mapping is not supported via this implementation of the SYSMEM API. */

    /* Removed this from the list of mappable regions...*/
    SYSBRGU_DestroyMappableRegion(psPages->hRegHandle);

    /* Calculate the size of page table...*/
    physAddrArrSize = sizeof(psPages->ppaPhysAddr[0]) * ui32NoPages;

    /* Free memory...*/
    gen_pool_free(prv->pool, (unsigned long)psPages->pvImplData, psPages->ui32Size);
    IMG_BIGORSMALL_FREE(physAddrArrSize, psPages->ppaPhysAddr);
    psPages->ppaPhysAddr = IMG_NULL;
    psPages->hRegHandle = IMG_NULL;
}