xref: /openbmc/linux/sound/pci/asihpi/hpios.c (revision 23fdf223bbe4bd42bbb3f0f5b9d5e64a58956ef7)
1719f82d3SEliot Blennerhassett /******************************************************************************
2719f82d3SEliot Blennerhassett 
3719f82d3SEliot Blennerhassett     AudioScience HPI driver
492fd918cSEliot Blennerhassett     Copyright (C) 1997-2012  AudioScience Inc. <support@audioscience.com>
5719f82d3SEliot Blennerhassett 
6719f82d3SEliot Blennerhassett     This program is free software; you can redistribute it and/or modify
7719f82d3SEliot Blennerhassett     it under the terms of version 2 of the GNU General Public License as
8719f82d3SEliot Blennerhassett     published by the Free Software Foundation;
9719f82d3SEliot Blennerhassett 
10719f82d3SEliot Blennerhassett     This program is distributed in the hope that it will be useful,
11719f82d3SEliot Blennerhassett     but WITHOUT ANY WARRANTY; without even the implied warranty of
12719f82d3SEliot Blennerhassett     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13719f82d3SEliot Blennerhassett     GNU General Public License for more details.
14719f82d3SEliot Blennerhassett 
15719f82d3SEliot Blennerhassett     You should have received a copy of the GNU General Public License
16719f82d3SEliot Blennerhassett     along with this program; if not, write to the Free Software
17719f82d3SEliot Blennerhassett     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18719f82d3SEliot Blennerhassett 
19719f82d3SEliot Blennerhassett HPI Operating System function implementation for Linux
20719f82d3SEliot Blennerhassett 
21719f82d3SEliot Blennerhassett (C) Copyright AudioScience Inc. 1997-2003
22719f82d3SEliot Blennerhassett ******************************************************************************/
23719f82d3SEliot Blennerhassett #define SOURCEFILE_NAME "hpios.c"
24719f82d3SEliot Blennerhassett #include "hpi_internal.h"
25719f82d3SEliot Blennerhassett #include "hpidebug.h"
26719f82d3SEliot Blennerhassett #include <linux/delay.h>
27719f82d3SEliot Blennerhassett #include <linux/sched.h>
28719f82d3SEliot Blennerhassett 
29719f82d3SEliot Blennerhassett void hpios_delay_micro_seconds(u32 num_micro_sec)
30719f82d3SEliot Blennerhassett {
31719f82d3SEliot Blennerhassett 	if ((usecs_to_jiffies(num_micro_sec) > 1) && !in_interrupt()) {
32719f82d3SEliot Blennerhassett 		/* MUST NOT SCHEDULE IN INTERRUPT CONTEXT! */
33719f82d3SEliot Blennerhassett 		schedule_timeout_uninterruptible(usecs_to_jiffies
34719f82d3SEliot Blennerhassett 			(num_micro_sec));
35719f82d3SEliot Blennerhassett 	} else if (num_micro_sec <= 2000)
36719f82d3SEliot Blennerhassett 		udelay(num_micro_sec);
37719f82d3SEliot Blennerhassett 	else
38719f82d3SEliot Blennerhassett 		mdelay(num_micro_sec / 1000);
39719f82d3SEliot Blennerhassett 
40719f82d3SEliot Blennerhassett }
41719f82d3SEliot Blennerhassett 
4292fd918cSEliot Blennerhassett /** Allocate an area of locked memory for bus master DMA operations.
43719f82d3SEliot Blennerhassett 
4492fd918cSEliot Blennerhassett If allocation fails, return 1, and *pMemArea.size = 0
45719f82d3SEliot Blennerhassett */
4692fd918cSEliot Blennerhassett u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size,
47719f82d3SEliot Blennerhassett 	struct pci_dev *pdev)
48719f82d3SEliot Blennerhassett {
49719f82d3SEliot Blennerhassett 	/*?? any benefit in using managed dmam_alloc_coherent? */
50719f82d3SEliot Blennerhassett 	p_mem_area->vaddr =
51719f82d3SEliot Blennerhassett 		dma_alloc_coherent(&pdev->dev, size, &p_mem_area->dma_handle,
52*23fdf223SChristoph Hellwig 		GFP_KERNEL);
53719f82d3SEliot Blennerhassett 
54719f82d3SEliot Blennerhassett 	if (p_mem_area->vaddr) {
55719f82d3SEliot Blennerhassett 		HPI_DEBUG_LOG(DEBUG, "allocated %d bytes, dma 0x%x vma %p\n",
56719f82d3SEliot Blennerhassett 			size, (unsigned int)p_mem_area->dma_handle,
57719f82d3SEliot Blennerhassett 			p_mem_area->vaddr);
58719f82d3SEliot Blennerhassett 		p_mem_area->pdev = &pdev->dev;
59719f82d3SEliot Blennerhassett 		p_mem_area->size = size;
60719f82d3SEliot Blennerhassett 		return 0;
61719f82d3SEliot Blennerhassett 	} else {
62719f82d3SEliot Blennerhassett 		HPI_DEBUG_LOG(WARNING,
63719f82d3SEliot Blennerhassett 			"failed to allocate %d bytes locked memory\n", size);
64719f82d3SEliot Blennerhassett 		p_mem_area->size = 0;
6592fd918cSEliot Blennerhassett 		return 1;
66719f82d3SEliot Blennerhassett 	}
67719f82d3SEliot Blennerhassett }
68719f82d3SEliot Blennerhassett 
69719f82d3SEliot Blennerhassett u16 hpios_locked_mem_free(struct consistent_dma_area *p_mem_area)
70719f82d3SEliot Blennerhassett {
71719f82d3SEliot Blennerhassett 	if (p_mem_area->size) {
72719f82d3SEliot Blennerhassett 		dma_free_coherent(p_mem_area->pdev, p_mem_area->size,
73719f82d3SEliot Blennerhassett 			p_mem_area->vaddr, p_mem_area->dma_handle);
74719f82d3SEliot Blennerhassett 		HPI_DEBUG_LOG(DEBUG, "freed %lu bytes, dma 0x%x vma %p\n",
75719f82d3SEliot Blennerhassett 			(unsigned long)p_mem_area->size,
76719f82d3SEliot Blennerhassett 			(unsigned int)p_mem_area->dma_handle,
77719f82d3SEliot Blennerhassett 			p_mem_area->vaddr);
78719f82d3SEliot Blennerhassett 		p_mem_area->size = 0;
79719f82d3SEliot Blennerhassett 		return 0;
80719f82d3SEliot Blennerhassett 	} else {
81719f82d3SEliot Blennerhassett 		return 1;
82719f82d3SEliot Blennerhassett 	}
83719f82d3SEliot Blennerhassett }
84