Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
xtensa
kernel
pci-dma.c
Go to the documentation of this file.
1
/*
2
* arch/xtensa/kernel/pci-dma.c
3
*
4
* DMA coherent memory allocation.
5
*
6
* This program is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License as published by the
8
* Free Software Foundation; either version 2 of the License, or (at your
9
* option) any later version.
10
*
11
* Copyright (C) 2002 - 2005 Tensilica Inc.
12
*
13
* Based on version for i386.
14
*
15
* Chris Zankel <
[email protected]
>
16
* Joe Taylor <
[email protected]
,
[email protected]
>
17
*/
18
19
#include <linux/types.h>
20
#include <
linux/mm.h
>
21
#include <linux/string.h>
22
#include <linux/pci.h>
23
#include <
linux/gfp.h
>
24
#include <linux/module.h>
25
#include <asm/io.h>
26
#include <asm/cacheflush.h>
27
28
/*
29
* Note: We assume that the full memory space is always mapped to 'kseg'
30
* Otherwise we have to use page attributes (not implemented).
31
*/
32
33
void
*
34
dma_alloc_coherent
(
struct
device
*
dev
,
size_t
size
,
dma_addr_t
*
handle
,
gfp_t
flag
)
35
{
36
unsigned
long
ret
;
37
unsigned
long
uncached
= 0;
38
39
/* ignore region speicifiers */
40
41
flag &= ~(
__GFP_DMA
|
__GFP_HIGHMEM
);
42
43
if
(dev ==
NULL
|| (dev->
coherent_dma_mask
< 0xffffffff))
44
flag |=
GFP_DMA
;
45
ret = (
unsigned
long
)
__get_free_pages
(flag,
get_order
(size));
46
47
if
(ret == 0)
48
return
NULL
;
49
50
/* We currently don't support coherent memory outside KSEG */
51
52
if
(ret <
XCHAL_KSEG_CACHED_VADDR
53
|| ret >=
XCHAL_KSEG_CACHED_VADDR
+
XCHAL_KSEG_SIZE
)
54
BUG
();
55
56
57
if
(ret != 0) {
58
memset
((
void
*) ret, 0, size);
59
uncached = ret+
XCHAL_KSEG_BYPASS_VADDR
-
XCHAL_KSEG_CACHED_VADDR
;
60
*handle =
virt_to_bus
((
void
*)ret);
61
__flush_invalidate_dcache_range(ret, size);
62
}
63
64
return
(
void
*)
uncached
;
65
}
66
EXPORT_SYMBOL
(
dma_alloc_coherent
);
67
68
void
dma_free_coherent
(
struct
device
*hwdev,
size_t
size
,
69
void
*
vaddr
,
dma_addr_t
dma_handle
)
70
{
71
long
addr
=(
long
)vaddr+
XCHAL_KSEG_CACHED_VADDR
-
XCHAL_KSEG_BYPASS_VADDR
;
72
73
if
(addr < 0 || addr >=
XCHAL_KSEG_SIZE
)
74
BUG
();
75
76
free_pages
(addr,
get_order
(size));
77
}
78
EXPORT_SYMBOL
(
dma_free_coherent
);
79
80
81
void
consistent_sync
(
void
*
vaddr
,
size_t
size
,
int
direction
)
82
{
83
switch
(direction) {
84
case
PCI_DMA_NONE
:
85
BUG
();
86
case
PCI_DMA_FROMDEVICE
:
/* invalidate only */
87
__invalidate_dcache_range((
unsigned
long
)vaddr,
88
(
unsigned
long
)size);
89
break
;
90
91
case
PCI_DMA_TODEVICE
:
/* writeback only */
92
case
PCI_DMA_BIDIRECTIONAL
:
/* writeback and invalidate */
93
__flush_invalidate_dcache_range((
unsigned
long
)vaddr,
94
(
unsigned
long
)size);
95
break
;
96
}
97
}
98
EXPORT_SYMBOL
(
consistent_sync
);
Generated on Thu Jan 10 2013 13:05:48 for Linux Kernel by
1.8.2