Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
24c75d48
Commit
24c75d48
authored
Mar 28, 2004
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://bk.arm.linux.org.uk/linux-2.6-rmk
into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents
18ccf569
ba3cfbd6
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
201 additions
and
146 deletions
+201
-146
arch/arm/Kconfig
arch/arm/Kconfig
+0
-4
arch/arm/mm/consistent.c
arch/arm/mm/consistent.c
+81
-81
drivers/acorn/char/i2c.c
drivers/acorn/char/i2c.c
+68
-32
drivers/video/acornfb.c
drivers/video/acornfb.c
+20
-18
drivers/video/acornfb.h
drivers/video/acornfb.h
+1
-0
drivers/video/sa1100fb.c
drivers/video/sa1100fb.c
+11
-4
drivers/video/sa1100fb.h
drivers/video/sa1100fb.h
+1
-0
include/asm-arm/dma-mapping.h
include/asm-arm/dma-mapping.h
+19
-7
No files found.
arch/arm/Kconfig
View file @
24c75d48
...
...
@@ -601,12 +601,8 @@ source "arch/arm/oprofile/Kconfig"
source "drivers/video/Kconfig"
if ARCH_ACORN || ARCH_CLPS7500 || ARCH_TBOX || ARCH_SHARK || ARCH_SA1100 || PCI
source "sound/Kconfig"
endif
source "drivers/misc/Kconfig"
source "drivers/usb/Kconfig"
...
...
arch/arm/mm/consistent.c
View file @
24c75d48
...
...
@@ -76,34 +76,27 @@ static struct vm_region consistent_head = {
.
vm_end
=
CONSISTENT_END
,
};
#if 0
static void vm_region_dump(struct vm_region *head, char *fn
)
static
struct
vm_region
*
vm_region_alloc
(
struct
vm_region
*
head
,
size_t
size
,
int
gfp
)
{
struct vm_region *c;
unsigned
long
addr
=
head
->
vm_start
,
end
=
head
->
vm_end
-
size
;
unsigned
long
flags
;
struct
vm_region
*
c
,
*
new
;
printk("Consistent Allocation Map (%s):\n", fn);
list_for_each_entry(c, &head->vm_list, vm_list) {
printk(" %p: %08lx - %08lx (0x%08x)\n", c,
c->vm_start, c->vm_end, c->vm_end - c->vm_start);
}
}
#else
#define vm_region_dump(head,fn) do { } while(0)
#endif
new
=
kmalloc
(
sizeof
(
struct
vm_region
),
gfp
);
if
(
!
new
)
goto
out
;
static
int
vm_region_alloc
(
struct
vm_region
*
head
,
struct
vm_region
*
new
,
size_t
size
)
{
unsigned
long
addr
=
head
->
vm_start
,
end
=
head
->
vm_end
-
size
;
struct
vm_region
*
c
;
spin_lock_irqsave
(
&
consistent_lock
,
flags
);
list_for_each_entry
(
c
,
&
head
->
vm_list
,
vm_list
)
{
if
((
addr
+
size
)
<
addr
)
goto
out
;
goto
nospc
;
if
((
addr
+
size
)
<=
c
->
vm_start
)
goto
found
;
addr
=
c
->
vm_end
;
if
(
addr
>
end
)
goto
out
;
goto
nospc
;
}
found:
...
...
@@ -114,10 +107,14 @@ static int vm_region_alloc(struct vm_region *head, struct vm_region *new, size_t
new
->
vm_start
=
addr
;
new
->
vm_end
=
addr
+
size
;
return
0
;
spin_unlock_irqrestore
(
&
consistent_lock
,
flags
);
return
new
;
nospc:
spin_unlock_irqrestore
(
&
consistent_lock
,
flags
);
kfree
(
new
);
out:
return
-
ENOMEM
;
return
NULL
;
}
static
struct
vm_region
*
vm_region_find
(
struct
vm_region
*
head
,
unsigned
long
addr
)
...
...
@@ -133,28 +130,46 @@ static struct vm_region *vm_region_find(struct vm_region *head, unsigned long ad
return
c
;
}
/*
* This allocates one page of cache-coherent memory space and returns
* both the virtual and a "dma" address to that space.
*/
void
*
consistent_alloc
(
int
gfp
,
size_t
size
,
dma_addr_t
*
handle
,
unsigned
long
cache_flags
)
#ifdef CONFIG_HUGETLB_PAGE
#error ARM Coherent DMA allocator does not (yet) support huge TLB
#endif
static
void
*
__dma_alloc
(
struct
device
*
dev
,
size_t
size
,
dma_addr_t
*
handle
,
int
gfp
,
pgprot_t
prot
)
{
struct
page
*
page
;
struct
vm_region
*
c
;
unsigned
long
order
,
flags
;
void
*
ret
=
NULL
;
int
res
;
unsigned
long
order
;
u64
mask
=
0x00ffffff
,
limit
;
/* ISA default */
if
(
!
consistent_pte
)
{
printk
(
KERN_ERR
"
consistent_alloc: not initialised
\n
"
);
printk
(
KERN_ERR
"
%s: not initialised
\n
"
,
__func__
);
dump_stack
();
return
NULL
;
}
if
(
dev
)
{
mask
=
dev
->
coherent_dma_mask
;
if
(
mask
==
0
)
{
dev_warn
(
dev
,
"coherent DMA mask is unset
\n
"
);
return
NULL
;
}
}
size
=
PAGE_ALIGN
(
size
);
limit
=
(
mask
+
1
)
&
~
mask
;
if
((
limit
&&
size
>=
limit
)
||
size
>=
(
CONSISTENT_END
-
CONSISTENT_BASE
))
{
printk
(
KERN_WARNING
"coherent allocation too big (requested %#x mask %#Lx)
\n
"
,
size
,
mask
);
return
NULL
;
}
order
=
get_order
(
size
);
if
(
mask
!=
0xffffffff
)
gfp
|=
GFP_DMA
;
page
=
alloc_pages
(
gfp
,
order
);
if
(
!
page
)
goto
no_page
;
...
...
@@ -165,36 +180,18 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle,
*/
{
unsigned
long
kaddr
=
(
unsigned
long
)
page_address
(
page
);
dmac_inv_range
(
kaddr
,
kaddr
+
size
);
memset
(
page_address
(
page
),
0
,
size
);
dmac_flush_range
(
kaddr
,
kaddr
+
size
);
}
/*
* Our housekeeping doesn't need to come from DMA,
* but it must not come from highmem.
* Allocate a virtual address in the consistent mapping region.
*/
c
=
kmalloc
(
sizeof
(
struct
vm_region
)
,
c
=
vm_region_alloc
(
&
consistent_head
,
size
,
gfp
&
~
(
__GFP_DMA
|
__GFP_HIGHMEM
));
if
(
!
c
)
goto
no_remap
;
/*
* Attempt to allocate a virtual address in the
* consistent mapping region.
*/
spin_lock_irqsave
(
&
consistent_lock
,
flags
);
vm_region_dump
(
&
consistent_head
,
"before alloc"
);
res
=
vm_region_alloc
(
&
consistent_head
,
c
,
size
);
vm_region_dump
(
&
consistent_head
,
"after alloc"
);
spin_unlock_irqrestore
(
&
consistent_lock
,
flags
);
if
(
!
res
)
{
if
(
c
)
{
pte_t
*
pte
=
consistent_pte
+
CONSISTENT_OFFSET
(
c
->
vm_start
);
struct
page
*
end
=
page
+
(
1
<<
order
);
pgprot_t
prot
=
__pgprot
(
L_PTE_PRESENT
|
L_PTE_YOUNG
|
L_PTE_DIRTY
|
L_PTE_WRITE
|
cache_flags
);
/*
* Set the "dma handle"
...
...
@@ -220,38 +217,43 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle,
page
++
;
}
ret
=
(
void
*
)
c
->
vm_start
;
ret
urn
(
void
*
)
c
->
vm_start
;
}
no_remap:
if
(
ret
==
NULL
)
{
kfree
(
c
);
if
(
page
)
__free_pages
(
page
,
order
);
}
no_page:
return
ret
;
return
NULL
;
}
EXPORT_SYMBOL
(
consistent_alloc
);
/*
* Since we have the DMA mask available to us here, we could try to do
* a normal allocation, and only fall back to a "DMA" allocation if the
* resulting bus address does not satisfy the dma_mask requirements.
* Allocate DMA-coherent memory space and return both the kernel remapped
* virtual and bus address for that space.
*/
void
*
dma_alloc_coherent
(
struct
device
*
dev
,
size_t
size
,
dma_addr_t
*
handle
,
int
gfp
)
{
if
(
dev
==
NULL
||
*
dev
->
dma_mask
!=
0xffffffff
)
gfp
|=
GFP_DMA
;
return
consistent_alloc
(
gfp
,
size
,
handle
,
0
);
return
__dma_alloc
(
dev
,
size
,
handle
,
gfp
,
pgprot_noncached
(
pgprot_kernel
));
}
EXPORT_SYMBOL
(
dma_alloc_coherent
);
/*
* Allocate a writecombining region, in much the same way as
* dma_alloc_coherent above.
*/
void
*
dma_alloc_writecombine
(
struct
device
*
dev
,
size_t
size
,
dma_addr_t
*
handle
,
int
gfp
)
{
return
__dma_alloc
(
dev
,
size
,
handle
,
gfp
,
pgprot_writecombine
(
pgprot_kernel
));
}
EXPORT_SYMBOL
(
dma_alloc_writecombine
);
/*
* free a page as defined by the above mapping.
*/
void
consistent_free
(
void
*
vaddr
,
size_t
size
,
dma_addr_t
handle
)
void
dma_free_coherent
(
struct
device
*
dev
,
size_t
size
,
void
*
cpu_addr
,
dma_addr_t
handle
)
{
struct
vm_region
*
c
;
unsigned
long
flags
;
...
...
@@ -260,15 +262,14 @@ void consistent_free(void *vaddr, size_t size, dma_addr_t handle)
size
=
PAGE_ALIGN
(
size
);
spin_lock_irqsave
(
&
consistent_lock
,
flags
);
vm_region_dump
(
&
consistent_head
,
"before free"
);
c
=
vm_region_find
(
&
consistent_head
,
(
unsigned
long
)
v
addr
);
c
=
vm_region_find
(
&
consistent_head
,
(
unsigned
long
)
cpu_
addr
);
if
(
!
c
)
goto
no_area
;
if
((
c
->
vm_end
-
c
->
vm_start
)
!=
size
)
{
printk
(
KERN_ERR
"
consistent_free: wrong
size (%ld != %d)
\n
"
,
c
->
vm_end
-
c
->
vm_start
,
size
);
printk
(
KERN_ERR
"
%s: freeing wrong coherent
size (%ld != %d)
\n
"
,
__func__
,
c
->
vm_end
-
c
->
vm_start
,
size
);
dump_stack
();
size
=
c
->
vm_end
-
c
->
vm_start
;
}
...
...
@@ -292,15 +293,14 @@ void consistent_free(void *vaddr, size_t size, dma_addr_t handle)
}
}
printk
(
KERN_CRIT
"
consistent_free: bad page in kernel page "
"table
\n
"
);
printk
(
KERN_CRIT
"
%s: bad page in kernel page table
\n
"
,
__func__
);
}
while
(
size
-=
PAGE_SIZE
);
flush_tlb_kernel_range
(
c
->
vm_start
,
c
->
vm_end
);
list_del
(
&
c
->
vm_list
);
vm_region_dump
(
&
consistent_head
,
"after free"
);
spin_unlock_irqrestore
(
&
consistent_lock
,
flags
);
kfree
(
c
);
...
...
@@ -308,11 +308,11 @@ void consistent_free(void *vaddr, size_t size, dma_addr_t handle)
no_area:
spin_unlock_irqrestore
(
&
consistent_lock
,
flags
);
printk
(
KERN_ERR
"
consistent_free: trying to free "
"invalid area: %p
\n
"
,
v
addr
);
printk
(
KERN_ERR
"
%s: trying to free invalid coherent area: %p
\n
"
,
__func__
,
cpu_
addr
);
dump_stack
();
}
EXPORT_SYMBOL
(
consistent_free
);
EXPORT_SYMBOL
(
dma_free_coherent
);
/*
* Initialise the consistent memory allocation.
...
...
@@ -330,7 +330,7 @@ static int __init consistent_init(void)
pgd
=
pgd_offset
(
&
init_mm
,
CONSISTENT_BASE
);
pmd
=
pmd_alloc
(
&
init_mm
,
pgd
,
CONSISTENT_BASE
);
if
(
!
pmd
)
{
printk
(
KERN_ERR
"
consistent_init: no pmd tables
\n
"
);
printk
(
KERN_ERR
"
%s: no pmd tables
\n
"
,
__func__
);
ret
=
-
ENOMEM
;
break
;
}
...
...
@@ -338,7 +338,7 @@ static int __init consistent_init(void)
pte
=
pte_alloc_kernel
(
&
init_mm
,
pmd
,
CONSISTENT_BASE
);
if
(
!
pte
)
{
printk
(
KERN_ERR
"
consistent_init: no pte tables
\n
"
);
printk
(
KERN_ERR
"
%s: no pte tables
\n
"
,
__func__
);
ret
=
-
ENOMEM
;
break
;
}
...
...
drivers/acorn/char/i2c.c
View file @
24c75d48
...
...
@@ -34,9 +34,13 @@ extern int (*set_rtc)(void);
static
struct
i2c_client
*
rtc_client
;
static
const
unsigned
char
days_in_mon
[]
=
{
0
,
31
,
28
,
31
,
30
,
31
,
30
,
31
,
31
,
30
,
31
,
30
,
31
};
static
unsigned
int
rtc_epoch
=
1900
;
#define CMOS_CHECKSUM (63)
/*
* Acorn machines store the year in the static RAM at
* location 128.
*/
#define CMOS_YEAR (64 + 128)
static
inline
int
rtc_command
(
int
cmd
,
void
*
data
)
...
...
@@ -49,6 +53,38 @@ static inline int rtc_command(int cmd, void *data)
return
ret
;
}
/*
* Update the century + year bytes in the CMOS RAM, ensuring
* that the check byte is correctly adjusted for the change.
*/
static
int
rtc_update_year
(
unsigned
int
new_year
)
{
unsigned
char
yr
[
2
],
chk
;
struct
mem
cmos_year
=
{
CMOS_YEAR
,
sizeof
(
yr
),
yr
};
struct
mem
cmos_check
=
{
CMOS_CHECKSUM
,
1
,
&
chk
};
int
ret
;
ret
=
rtc_command
(
MEM_READ
,
&
cmos_check
);
if
(
ret
)
goto
out
;
ret
=
rtc_command
(
MEM_READ
,
&
cmos_year
);
if
(
ret
)
goto
out
;
chk
-=
yr
[
1
]
+
yr
[
0
];
yr
[
1
]
=
new_year
/
100
;
yr
[
0
]
=
new_year
%
100
;
chk
+=
yr
[
1
]
+
yr
[
0
];
ret
=
rtc_command
(
MEM_WRITE
,
&
cmos_year
);
if
(
ret
==
0
)
ret
=
rtc_command
(
MEM_WRITE
,
&
cmos_check
);
out:
return
ret
;
}
/*
* Read the current RTC time and date, and update xtime.
*/
...
...
@@ -56,45 +92,51 @@ static void get_rtc_time(struct rtc_tm *rtctm, unsigned int *year)
{
unsigned
char
ctrl
,
yr
[
2
];
struct
mem
rtcmem
=
{
CMOS_YEAR
,
sizeof
(
yr
),
yr
};
int
real_year
,
year_offset
;
/*
* Ensure that the RTC is running.
*/
rtc_command
(
RTC_GETCTRL
,
&
ctrl
);
if
(
ctrl
&
0xc0
)
{
unsigned
char
new_ctrl
;
new_ctrl
=
ctrl
&
~
0xc0
;
unsigned
char
new_ctrl
=
ctrl
&
~
0xc0
;
printk
(
"RTC: resetting control %02X -> %02X
\n
"
,
printk
(
KERN_WARNING
"RTC: resetting control %02x -> %02x
\n
"
,
ctrl
,
new_ctrl
);
rtc_command
(
RTC_SETCTRL
,
&
new_ctrl
);
}
/*
* Acorn machines store the year in
* the static RAM at location 192.
*/
if
(
rtc_command
(
MEM_READ
,
&
rtcmem
))
if
(
rtc_command
(
RTC_GETDATETIME
,
rtctm
)
||
rtc_command
(
MEM_READ
,
&
rtcmem
))
return
;
if
(
rtc_command
(
RTC_GETDATETIME
,
rtctm
))
return
;
real_year
=
yr
[
0
];
/*
* The RTC year holds the LSB two bits of the current
* year, which should reflect the LSB two bits of the
* CMOS copy of the year. Any difference indicates
* that we have to correct the CMOS version.
*/
year_offset
=
rtctm
->
year_off
-
(
real_year
&
3
);
if
(
year_offset
<
0
)
/*
* RTC year wrapped. Adjust it appropriately.
*/
year_offset
+=
4
;
*
year
=
yr
[
1
]
*
100
+
yr
[
0
]
;
*
year
=
real_year
+
year_offset
+
yr
[
1
]
*
100
;
}
static
int
set_rtc_time
(
struct
rtc_tm
*
rtctm
,
unsigned
int
year
)
{
unsigned
char
yr
[
2
],
leap
,
chk
;
struct
mem
cmos_year
=
{
CMOS_YEAR
,
sizeof
(
yr
),
yr
};
struct
mem
cmos_check
=
{
CMOS_CHECKSUM
,
1
,
&
chk
};
unsigned
char
leap
;
int
ret
;
leap
=
(
!
(
year
%
4
)
&&
(
year
%
100
))
||
!
(
year
%
400
);
if
(
rtctm
->
mon
>
12
||
rtctm
->
mday
==
0
)
if
(
rtctm
->
mon
>
12
||
rtctm
->
m
on
==
0
||
rtctm
->
m
day
==
0
)
return
-
EINVAL
;
if
(
rtctm
->
mday
>
(
days_in_mon
[
rtctm
->
mon
]
+
(
rtctm
->
mon
==
2
&&
leap
)))
...
...
@@ -103,21 +145,16 @@ static int set_rtc_time(struct rtc_tm *rtctm, unsigned int year)
if
(
rtctm
->
hours
>=
24
||
rtctm
->
mins
>=
60
||
rtctm
->
secs
>=
60
)
return
-
EINVAL
;
ret
=
rtc_command
(
RTC_SETDATETIME
,
rtctm
);
if
(
ret
==
0
)
{
rtc_command
(
MEM_READ
,
&
cmos_check
);
rtc_command
(
MEM_READ
,
&
cmos_year
);
chk
-=
yr
[
1
]
+
yr
[
0
];
yr
[
1
]
=
year
/
100
;
yr
[
0
]
=
year
%
100
;
/*
* The RTC's own 2-bit year must reflect the least
* significant two bits of the CMOS year.
*/
rtctm
->
year_off
=
(
year
%
100
)
&
3
;
chk
+=
yr
[
1
]
+
yr
[
0
];
ret
=
rtc_command
(
RTC_SETDATETIME
,
rtctm
);
if
(
ret
==
0
)
ret
=
rtc_update_year
(
year
);
rtc_command
(
MEM_WRITE
,
&
cmos_year
);
rtc_command
(
MEM_WRITE
,
&
cmos_check
);
}
return
ret
;
}
...
...
@@ -189,13 +226,12 @@ static int rtc_ioctl(struct inode *inode, struct file *file,
rtc_raw
.
hours
=
rtctm
.
tm_hour
;
rtc_raw
.
mday
=
rtctm
.
tm_mday
;
rtc_raw
.
mon
=
rtctm
.
tm_mon
+
1
;
rtc_raw
.
year_off
=
2
;
year
=
rtctm
.
tm_year
+
1900
;
return
set_rtc_time
(
&
rtc_raw
,
year
);
break
;
case
RTC_EPOCH_READ
:
return
put_user
(
rtc_epoch
,
(
unsigned
long
*
)
arg
);
return
put_user
(
1900
,
(
unsigned
long
*
)
arg
);
}
return
-
EINVAL
;
...
...
drivers/video/acornfb.c
View file @
24c75d48
...
...
@@ -29,6 +29,8 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/fb.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <asm/hardware.h>
#include <asm/io.h>
...
...
@@ -1254,6 +1256,11 @@ free_unused_pages(unsigned int virtual_start, unsigned int virtual_end)
printk
(
"acornfb: freed %dK memory
\n
"
,
mb_freed
);
}
static
struct
device
acornfb_device
=
{
.
bus_id
=
"acornfb"
,
.
coherent_dma_mask
=
0xffffffff
,
};
int
__init
acornfb_init
(
void
)
{
...
...
@@ -1263,6 +1270,8 @@ acornfb_init(void)
acornfb_init_fbinfo
();
current_par
.
dev
=
&
acornfb_device
;
if
(
current_par
.
montype
==
-
1
)
current_par
.
montype
=
acornfb_detect_monitortype
();
...
...
@@ -1323,37 +1332,30 @@ acornfb_init(void)
#if defined(HAS_VIDC20)
if
(
!
current_par
.
using_vram
)
{
dma_addr_t
handle
;
void
*
base
;
/*
* RiscPC needs to allocate the DRAM memory
* for the framebuffer if we are not using
* VRAM. Archimedes/A5000 machines use a
* fixed address for their framebuffers.
* VRAM.
*/
unsigned
long
page
,
top
,
base
;
int
order
=
get_order
(
size
);
base
=
__get_free_pages
(
GFP_KERNEL
,
order
);
if
(
base
==
0
)
{
base
=
dma_alloc_writecombine
(
current_par
.
dev
,
size
,
&
handle
,
GFP_KERNEL
);
if
(
base
==
NULL
)
{
printk
(
KERN_ERR
"acornfb: unable to allocate screen "
"memory
\n
"
);
return
-
ENOMEM
;
}
top
=
base
+
(
PAGE_SIZE
<<
order
);
/* Mark the framebuffer pages as reserved so mmap will work. */
for
(
page
=
base
;
page
<
PAGE_ALIGN
(
base
+
size
);
page
+=
PAGE_SIZE
)
SetPageReserved
(
virt_to_page
(
page
));
/* Hand back any excess pages that we allocated. */
for
(
page
=
base
+
size
;
page
<
top
;
page
+=
PAGE_SIZE
)
free_page
(
page
);
fb_info
.
screen_base
=
(
char
*
)
base
;
fb_info
.
fix
.
smem_start
=
virt_to_phys
(
fb_info
.
screen_base
)
;
fb_info
.
screen_base
=
base
;
fb_info
.
fix
.
smem_start
=
handle
;
}
#endif
#if defined(HAS_VIDC)
/*
* Free unused pages
* Archimedes/A5000 machines use a fixed address for their
* framebuffers. Free unused pages
*/
free_unused_pages
(
PAGE_OFFSET
+
size
,
PAGE_OFFSET
+
MAX_SIZE
);
#endif
...
...
drivers/video/acornfb.h
View file @
24c75d48
...
...
@@ -47,6 +47,7 @@ union palette {
};
struct
acornfb_par
{
struct
device
*
dev
;
unsigned
long
screen_end
;
unsigned
int
dram_size
;
unsigned
int
vram_half_sam
;
...
...
drivers/video/sa1100fb.c
View file @
24c75d48
...
...
@@ -1595,12 +1595,18 @@ static int __init sa1100fb_map_video_memory(struct sa1100fb_info *fbi)
* of the framebuffer.
*/
fbi
->
map_size
=
PAGE_ALIGN
(
fbi
->
fb
.
fix
.
smem_len
+
PAGE_SIZE
);
fbi
->
map_cpu
=
consistent_alloc
(
GFP_KERNEL
,
fbi
->
map_size
,
&
fbi
->
map_dma
,
PTE_BUFFERABLE
);
fbi
->
map_cpu
=
dma_alloc_writecombine
(
fbi
->
dev
,
fbi
->
map_size
,
&
fbi
->
map_dma
,
GFP_KERNEL
);
if
(
fbi
->
map_cpu
)
{
fbi
->
fb
.
screen_base
=
fbi
->
map_cpu
+
PAGE_SIZE
;
fbi
->
screen_dma
=
fbi
->
map_dma
+
PAGE_SIZE
;
/*
* FIXME: this is actually the wrong thing to place in
* smem_start. But fbdev suffers from the problem that
* it needs an API which doesn't exist (in this case,
* dma_writecombine_mmap)
*/
fbi
->
fb
.
fix
.
smem_start
=
fbi
->
screen_dma
;
}
...
...
@@ -1613,7 +1619,7 @@ static struct fb_monspecs monspecs __initdata = {
};
static
struct
sa1100fb_info
*
__init
sa1100fb_init_fbinfo
(
void
)
static
struct
sa1100fb_info
*
__init
sa1100fb_init_fbinfo
(
struct
device
*
dev
)
{
struct
sa1100fb_mach_info
*
inf
;
struct
sa1100fb_info
*
fbi
;
...
...
@@ -1624,6 +1630,7 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(void)
return
NULL
;
memset
(
fbi
,
0
,
sizeof
(
struct
sa1100fb_info
));
fbi
->
dev
=
dev
;
strcpy
(
fbi
->
fb
.
fix
.
id
,
SA1100_NAME
);
...
...
@@ -1703,7 +1710,7 @@ static int __init sa1100fb_probe(struct device *dev)
if
(
!
request_mem_region
(
0xb0100000
,
0x10000
,
"LCD"
))
return
-
EBUSY
;
fbi
=
sa1100fb_init_fbinfo
();
fbi
=
sa1100fb_init_fbinfo
(
dev
);
ret
=
-
ENOMEM
;
if
(
!
fbi
)
goto
failed
;
...
...
drivers/video/sa1100fb.h
View file @
24c75d48
...
...
@@ -63,6 +63,7 @@ struct sa1100fb_lcd_reg {
struct
sa1100fb_info
{
struct
fb_info
fb
;
struct
device
*
dev
;
struct
sa1100fb_rgb
*
rgb
[
NR_RGB
];
u_int
max_bpp
;
...
...
include/asm-arm/dma-mapping.h
View file @
24c75d48
...
...
@@ -14,8 +14,6 @@
* devices. This is the "generic" version. The PCI specific version
* is in pci.h
*/
extern
void
*
consistent_alloc
(
int
gfp
,
size_t
size
,
dma_addr_t
*
handle
,
unsigned
long
flags
);
extern
void
consistent_free
(
void
*
vaddr
,
size_t
size
,
dma_addr_t
handle
);
extern
void
consistent_sync
(
void
*
kaddr
,
size_t
size
,
int
rw
);
/*
...
...
@@ -99,12 +97,26 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp)
* References to memory and mappings associated with cpu_addr/handle
* during and after this call executing are illegal.
*/
static
inline
void
extern
void
dma_free_coherent
(
struct
device
*
dev
,
size_t
size
,
void
*
cpu_addr
,
dma_addr_t
handle
)
{
consistent_free
(
cpu_addr
,
size
,
handle
);
}
dma_addr_t
handle
);
/**
* dma_alloc_writecombine - allocate writecombining memory for DMA
* @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
* @size: required memory size
* @handle: bus-specific DMA address
*
* Allocate some uncached, buffered memory for a device for
* performing DMA. This function allocates pages, and will
* return the CPU-viewed address, and sets @handle to be the
* device-viewed address.
*/
extern
void
*
dma_alloc_writecombine
(
struct
device
*
dev
,
size_t
size
,
dma_addr_t
*
handle
,
int
gfp
);
#define dma_free_writecombine(dev,size,cpu_addr,handle) \
dma_free_coherent(dev,size,cpu_addr,handle)
/**
* dma_map_single - map a single buffer for streaming DMA
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment