162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/******************************************************************************
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci    AudioScience HPI driver
562306a36Sopenharmony_ci    Copyright (C) 1997-2012  AudioScience Inc. <support@audioscience.com>
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci
862306a36Sopenharmony_ciHPI Operating System function implementation for Linux
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci(C) Copyright AudioScience Inc. 1997-2003
1162306a36Sopenharmony_ci******************************************************************************/
1262306a36Sopenharmony_ci#define SOURCEFILE_NAME "hpios.c"
1362306a36Sopenharmony_ci#include "hpi_internal.h"
1462306a36Sopenharmony_ci#include "hpidebug.h"
1562306a36Sopenharmony_ci#include <linux/delay.h>
1662306a36Sopenharmony_ci#include <linux/sched.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_civoid hpios_delay_micro_seconds(u32 num_micro_sec)
1962306a36Sopenharmony_ci{
2062306a36Sopenharmony_ci	if ((usecs_to_jiffies(num_micro_sec) > 1) && !in_interrupt()) {
2162306a36Sopenharmony_ci		/* MUST NOT SCHEDULE IN INTERRUPT CONTEXT! */
2262306a36Sopenharmony_ci		schedule_timeout_uninterruptible(usecs_to_jiffies
2362306a36Sopenharmony_ci			(num_micro_sec));
2462306a36Sopenharmony_ci	} else if (num_micro_sec <= 2000)
2562306a36Sopenharmony_ci		udelay(num_micro_sec);
2662306a36Sopenharmony_ci	else
2762306a36Sopenharmony_ci		mdelay(num_micro_sec / 1000);
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci}
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci/** Allocate an area of locked memory for bus master DMA operations.
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ciIf allocation fails, return 1, and *pMemArea.size = 0
3462306a36Sopenharmony_ci*/
3562306a36Sopenharmony_ciu16 hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size,
3662306a36Sopenharmony_ci	struct pci_dev *pdev)
3762306a36Sopenharmony_ci{
3862306a36Sopenharmony_ci	/*?? any benefit in using managed dmam_alloc_coherent? */
3962306a36Sopenharmony_ci	p_mem_area->vaddr =
4062306a36Sopenharmony_ci		dma_alloc_coherent(&pdev->dev, size, &p_mem_area->dma_handle,
4162306a36Sopenharmony_ci		GFP_KERNEL);
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	if (p_mem_area->vaddr) {
4462306a36Sopenharmony_ci		HPI_DEBUG_LOG(DEBUG, "allocated %d bytes, dma 0x%x vma %p\n",
4562306a36Sopenharmony_ci			size, (unsigned int)p_mem_area->dma_handle,
4662306a36Sopenharmony_ci			p_mem_area->vaddr);
4762306a36Sopenharmony_ci		p_mem_area->pdev = &pdev->dev;
4862306a36Sopenharmony_ci		p_mem_area->size = size;
4962306a36Sopenharmony_ci		return 0;
5062306a36Sopenharmony_ci	} else {
5162306a36Sopenharmony_ci		HPI_DEBUG_LOG(WARNING,
5262306a36Sopenharmony_ci			"failed to allocate %d bytes locked memory\n", size);
5362306a36Sopenharmony_ci		p_mem_area->size = 0;
5462306a36Sopenharmony_ci		return 1;
5562306a36Sopenharmony_ci	}
5662306a36Sopenharmony_ci}
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ciu16 hpios_locked_mem_free(struct consistent_dma_area *p_mem_area)
5962306a36Sopenharmony_ci{
6062306a36Sopenharmony_ci	if (p_mem_area->size) {
6162306a36Sopenharmony_ci		dma_free_coherent(p_mem_area->pdev, p_mem_area->size,
6262306a36Sopenharmony_ci			p_mem_area->vaddr, p_mem_area->dma_handle);
6362306a36Sopenharmony_ci		HPI_DEBUG_LOG(DEBUG, "freed %lu bytes, dma 0x%x vma %p\n",
6462306a36Sopenharmony_ci			(unsigned long)p_mem_area->size,
6562306a36Sopenharmony_ci			(unsigned int)p_mem_area->dma_handle,
6662306a36Sopenharmony_ci			p_mem_area->vaddr);
6762306a36Sopenharmony_ci		p_mem_area->size = 0;
6862306a36Sopenharmony_ci		return 0;
6962306a36Sopenharmony_ci	} else {
7062306a36Sopenharmony_ci		return 1;
7162306a36Sopenharmony_ci	}
7262306a36Sopenharmony_ci}
73