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
nexedi
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