18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/******************************************************************************
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci    AudioScience HPI driver
58c2ecf20Sopenharmony_ci    Copyright (C) 1997-2012  AudioScience Inc. <support@audioscience.com>
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ciHPI Operating System function implementation for Linux
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci(C) Copyright AudioScience Inc. 1997-2003
118c2ecf20Sopenharmony_ci******************************************************************************/
128c2ecf20Sopenharmony_ci#define SOURCEFILE_NAME "hpios.c"
138c2ecf20Sopenharmony_ci#include "hpi_internal.h"
148c2ecf20Sopenharmony_ci#include "hpidebug.h"
158c2ecf20Sopenharmony_ci#include <linux/delay.h>
168c2ecf20Sopenharmony_ci#include <linux/sched.h>
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_civoid hpios_delay_micro_seconds(u32 num_micro_sec)
198c2ecf20Sopenharmony_ci{
208c2ecf20Sopenharmony_ci	if ((usecs_to_jiffies(num_micro_sec) > 1) && !in_interrupt()) {
218c2ecf20Sopenharmony_ci		/* MUST NOT SCHEDULE IN INTERRUPT CONTEXT! */
228c2ecf20Sopenharmony_ci		schedule_timeout_uninterruptible(usecs_to_jiffies
238c2ecf20Sopenharmony_ci			(num_micro_sec));
248c2ecf20Sopenharmony_ci	} else if (num_micro_sec <= 2000)
258c2ecf20Sopenharmony_ci		udelay(num_micro_sec);
268c2ecf20Sopenharmony_ci	else
278c2ecf20Sopenharmony_ci		mdelay(num_micro_sec / 1000);
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci}
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci/** Allocate an area of locked memory for bus master DMA operations.
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ciIf allocation fails, return 1, and *pMemArea.size = 0
348c2ecf20Sopenharmony_ci*/
358c2ecf20Sopenharmony_ciu16 hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size,
368c2ecf20Sopenharmony_ci	struct pci_dev *pdev)
378c2ecf20Sopenharmony_ci{
388c2ecf20Sopenharmony_ci	/*?? any benefit in using managed dmam_alloc_coherent? */
398c2ecf20Sopenharmony_ci	p_mem_area->vaddr =
408c2ecf20Sopenharmony_ci		dma_alloc_coherent(&pdev->dev, size, &p_mem_area->dma_handle,
418c2ecf20Sopenharmony_ci		GFP_KERNEL);
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	if (p_mem_area->vaddr) {
448c2ecf20Sopenharmony_ci		HPI_DEBUG_LOG(DEBUG, "allocated %d bytes, dma 0x%x vma %p\n",
458c2ecf20Sopenharmony_ci			size, (unsigned int)p_mem_area->dma_handle,
468c2ecf20Sopenharmony_ci			p_mem_area->vaddr);
478c2ecf20Sopenharmony_ci		p_mem_area->pdev = &pdev->dev;
488c2ecf20Sopenharmony_ci		p_mem_area->size = size;
498c2ecf20Sopenharmony_ci		return 0;
508c2ecf20Sopenharmony_ci	} else {
518c2ecf20Sopenharmony_ci		HPI_DEBUG_LOG(WARNING,
528c2ecf20Sopenharmony_ci			"failed to allocate %d bytes locked memory\n", size);
538c2ecf20Sopenharmony_ci		p_mem_area->size = 0;
548c2ecf20Sopenharmony_ci		return 1;
558c2ecf20Sopenharmony_ci	}
568c2ecf20Sopenharmony_ci}
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ciu16 hpios_locked_mem_free(struct consistent_dma_area *p_mem_area)
598c2ecf20Sopenharmony_ci{
608c2ecf20Sopenharmony_ci	if (p_mem_area->size) {
618c2ecf20Sopenharmony_ci		dma_free_coherent(p_mem_area->pdev, p_mem_area->size,
628c2ecf20Sopenharmony_ci			p_mem_area->vaddr, p_mem_area->dma_handle);
638c2ecf20Sopenharmony_ci		HPI_DEBUG_LOG(DEBUG, "freed %lu bytes, dma 0x%x vma %p\n",
648c2ecf20Sopenharmony_ci			(unsigned long)p_mem_area->size,
658c2ecf20Sopenharmony_ci			(unsigned int)p_mem_area->dma_handle,
668c2ecf20Sopenharmony_ci			p_mem_area->vaddr);
678c2ecf20Sopenharmony_ci		p_mem_area->size = 0;
688c2ecf20Sopenharmony_ci		return 0;
698c2ecf20Sopenharmony_ci	} else {
708c2ecf20Sopenharmony_ci		return 1;
718c2ecf20Sopenharmony_ci	}
728c2ecf20Sopenharmony_ci}
73