xref: /openbmc/linux/sound/pci/asihpi/hpios.c (revision 719f82d3987aad4cc9f46d19c35f362672545cad)
1*719f82d3SEliot Blennerhassett /******************************************************************************
2*719f82d3SEliot Blennerhassett 
3*719f82d3SEliot Blennerhassett     AudioScience HPI driver
4*719f82d3SEliot Blennerhassett     Copyright (C) 1997-2010  AudioScience Inc. <support@audioscience.com>
5*719f82d3SEliot Blennerhassett 
6*719f82d3SEliot Blennerhassett     This program is free software; you can redistribute it and/or modify
7*719f82d3SEliot Blennerhassett     it under the terms of version 2 of the GNU General Public License as
8*719f82d3SEliot Blennerhassett     published by the Free Software Foundation;
9*719f82d3SEliot Blennerhassett 
10*719f82d3SEliot Blennerhassett     This program is distributed in the hope that it will be useful,
11*719f82d3SEliot Blennerhassett     but WITHOUT ANY WARRANTY; without even the implied warranty of
12*719f82d3SEliot Blennerhassett     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13*719f82d3SEliot Blennerhassett     GNU General Public License for more details.
14*719f82d3SEliot Blennerhassett 
15*719f82d3SEliot Blennerhassett     You should have received a copy of the GNU General Public License
16*719f82d3SEliot Blennerhassett     along with this program; if not, write to the Free Software
17*719f82d3SEliot Blennerhassett     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18*719f82d3SEliot Blennerhassett 
19*719f82d3SEliot Blennerhassett HPI Operating System function implementation for Linux
20*719f82d3SEliot Blennerhassett 
21*719f82d3SEliot Blennerhassett (C) Copyright AudioScience Inc. 1997-2003
22*719f82d3SEliot Blennerhassett ******************************************************************************/
23*719f82d3SEliot Blennerhassett #define SOURCEFILE_NAME "hpios.c"
24*719f82d3SEliot Blennerhassett #include "hpi_internal.h"
25*719f82d3SEliot Blennerhassett #include "hpidebug.h"
26*719f82d3SEliot Blennerhassett #include <linux/delay.h>
27*719f82d3SEliot Blennerhassett #include <linux/sched.h>
28*719f82d3SEliot Blennerhassett 
29*719f82d3SEliot Blennerhassett void hpios_delay_micro_seconds(u32 num_micro_sec)
30*719f82d3SEliot Blennerhassett {
31*719f82d3SEliot Blennerhassett 	if ((usecs_to_jiffies(num_micro_sec) > 1) && !in_interrupt()) {
32*719f82d3SEliot Blennerhassett 		/* MUST NOT SCHEDULE IN INTERRUPT CONTEXT! */
33*719f82d3SEliot Blennerhassett 		schedule_timeout_uninterruptible(usecs_to_jiffies
34*719f82d3SEliot Blennerhassett 			(num_micro_sec));
35*719f82d3SEliot Blennerhassett 	} else if (num_micro_sec <= 2000)
36*719f82d3SEliot Blennerhassett 		udelay(num_micro_sec);
37*719f82d3SEliot Blennerhassett 	else
38*719f82d3SEliot Blennerhassett 		mdelay(num_micro_sec / 1000);
39*719f82d3SEliot Blennerhassett 
40*719f82d3SEliot Blennerhassett }
41*719f82d3SEliot Blennerhassett 
42*719f82d3SEliot Blennerhassett void hpios_locked_mem_init(void)
43*719f82d3SEliot Blennerhassett {
44*719f82d3SEliot Blennerhassett }
45*719f82d3SEliot Blennerhassett 
46*719f82d3SEliot Blennerhassett /** Allocated an area of locked memory for bus master DMA operations.
47*719f82d3SEliot Blennerhassett 
48*719f82d3SEliot Blennerhassett On error, return -ENOMEM, and *pMemArea.size = 0
49*719f82d3SEliot Blennerhassett */
50*719f82d3SEliot Blennerhassett u16 hpios_locked_mem_alloc(struct consistent_dma_area *p_mem_area, u32 size,
51*719f82d3SEliot Blennerhassett 	struct pci_dev *pdev)
52*719f82d3SEliot Blennerhassett {
53*719f82d3SEliot Blennerhassett 	/*?? any benefit in using managed dmam_alloc_coherent? */
54*719f82d3SEliot Blennerhassett 	p_mem_area->vaddr =
55*719f82d3SEliot Blennerhassett 		dma_alloc_coherent(&pdev->dev, size, &p_mem_area->dma_handle,
56*719f82d3SEliot Blennerhassett 		GFP_DMA32 | GFP_KERNEL);
57*719f82d3SEliot Blennerhassett 
58*719f82d3SEliot Blennerhassett 	if (p_mem_area->vaddr) {
59*719f82d3SEliot Blennerhassett 		HPI_DEBUG_LOG(DEBUG, "allocated %d bytes, dma 0x%x vma %p\n",
60*719f82d3SEliot Blennerhassett 			size, (unsigned int)p_mem_area->dma_handle,
61*719f82d3SEliot Blennerhassett 			p_mem_area->vaddr);
62*719f82d3SEliot Blennerhassett 		p_mem_area->pdev = &pdev->dev;
63*719f82d3SEliot Blennerhassett 		p_mem_area->size = size;
64*719f82d3SEliot Blennerhassett 		return 0;
65*719f82d3SEliot Blennerhassett 	} else {
66*719f82d3SEliot Blennerhassett 		HPI_DEBUG_LOG(WARNING,
67*719f82d3SEliot Blennerhassett 			"failed to allocate %d bytes locked memory\n", size);
68*719f82d3SEliot Blennerhassett 		p_mem_area->size = 0;
69*719f82d3SEliot Blennerhassett 		return -ENOMEM;
70*719f82d3SEliot Blennerhassett 	}
71*719f82d3SEliot Blennerhassett }
72*719f82d3SEliot Blennerhassett 
73*719f82d3SEliot Blennerhassett u16 hpios_locked_mem_free(struct consistent_dma_area *p_mem_area)
74*719f82d3SEliot Blennerhassett {
75*719f82d3SEliot Blennerhassett 	if (p_mem_area->size) {
76*719f82d3SEliot Blennerhassett 		dma_free_coherent(p_mem_area->pdev, p_mem_area->size,
77*719f82d3SEliot Blennerhassett 			p_mem_area->vaddr, p_mem_area->dma_handle);
78*719f82d3SEliot Blennerhassett 		HPI_DEBUG_LOG(DEBUG, "freed %lu bytes, dma 0x%x vma %p\n",
79*719f82d3SEliot Blennerhassett 			(unsigned long)p_mem_area->size,
80*719f82d3SEliot Blennerhassett 			(unsigned int)p_mem_area->dma_handle,
81*719f82d3SEliot Blennerhassett 			p_mem_area->vaddr);
82*719f82d3SEliot Blennerhassett 		p_mem_area->size = 0;
83*719f82d3SEliot Blennerhassett 		return 0;
84*719f82d3SEliot Blennerhassett 	} else {
85*719f82d3SEliot Blennerhassett 		return 1;
86*719f82d3SEliot Blennerhassett 	}
87*719f82d3SEliot Blennerhassett }
88*719f82d3SEliot Blennerhassett 
89*719f82d3SEliot Blennerhassett void hpios_locked_mem_free_all(void)
90*719f82d3SEliot Blennerhassett {
91*719f82d3SEliot Blennerhassett }
92*719f82d3SEliot Blennerhassett 
93*719f82d3SEliot Blennerhassett void __iomem *hpios_map_io(struct pci_dev *pci_dev, int idx,
94*719f82d3SEliot Blennerhassett 	unsigned int length)
95*719f82d3SEliot Blennerhassett {
96*719f82d3SEliot Blennerhassett 	HPI_DEBUG_LOG(DEBUG, "mapping %d %s %08llx-%08llx %04llx len 0x%x\n",
97*719f82d3SEliot Blennerhassett 		idx, pci_dev->resource[idx].name,
98*719f82d3SEliot Blennerhassett 		(unsigned long long)pci_resource_start(pci_dev, idx),
99*719f82d3SEliot Blennerhassett 		(unsigned long long)pci_resource_end(pci_dev, idx),
100*719f82d3SEliot Blennerhassett 		(unsigned long long)pci_resource_flags(pci_dev, idx), length);
101*719f82d3SEliot Blennerhassett 
102*719f82d3SEliot Blennerhassett 	if (!(pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM)) {
103*719f82d3SEliot Blennerhassett 		HPI_DEBUG_LOG(ERROR, "not an io memory resource\n");
104*719f82d3SEliot Blennerhassett 		return NULL;
105*719f82d3SEliot Blennerhassett 	}
106*719f82d3SEliot Blennerhassett 
107*719f82d3SEliot Blennerhassett 	if (length > pci_resource_len(pci_dev, idx)) {
108*719f82d3SEliot Blennerhassett 		HPI_DEBUG_LOG(ERROR, "resource too small for requested %d \n",
109*719f82d3SEliot Blennerhassett 			length);
110*719f82d3SEliot Blennerhassett 		return NULL;
111*719f82d3SEliot Blennerhassett 	}
112*719f82d3SEliot Blennerhassett 
113*719f82d3SEliot Blennerhassett 	return ioremap(pci_resource_start(pci_dev, idx), length);
114*719f82d3SEliot Blennerhassett }
115