Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
ad57c394
cloud-kernel
项目概览
openanolis
/
cloud-kernel
大约 1 年 前同步成功
通知
158
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
ad57c394
编写于
5月 20, 2010
作者:
T
Tony Lindgren
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'v2.6.34-rc7.iommu' of
git://gitorious.org/~doyu/lk/mainline
into omap-for-linus
上级
0581b52e
4abb7617
变更
7
显示空白变更内容
内联
并排
Showing
7 changed file
with
244 addition
and
46 deletion
+244
-46
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/Makefile
+1
-4
arch/arm/mach-omap2/iommu2.c
arch/arm/mach-omap2/iommu2.c
+4
-2
arch/arm/mach-omap2/omap-iommu.c
arch/arm/mach-omap2/omap-iommu.c
+157
-0
arch/arm/plat-omap/Kconfig
arch/arm/plat-omap/Kconfig
+7
-2
arch/arm/plat-omap/include/plat/omap44xx.h
arch/arm/plat-omap/include/plat/omap44xx.h
+3
-0
arch/arm/plat-omap/iommu.c
arch/arm/plat-omap/iommu.c
+66
-35
arch/arm/plat-omap/iovmm.c
arch/arm/plat-omap/iovmm.c
+6
-3
未找到文件。
arch/arm/mach-omap2/Makefile
浏览文件 @
ad57c394
...
...
@@ -89,10 +89,7 @@ obj-$(CONFIG_OMAP3_EMU) += emu.o
obj-$(CONFIG_OMAP_MBOX_FWK)
+=
mailbox_mach.o
mailbox_mach-objs
:=
mailbox.o
iommu-y
+=
iommu2.o
iommu-$(CONFIG_ARCH_OMAP3)
+=
omap3-iommu.o
obj-$(CONFIG_OMAP_IOMMU)
+=
$
(
iommu-y
)
obj-$(CONFIG_OMAP_IOMMU)
:=
iommu2.o omap-iommu.o
i2c-omap-$(CONFIG_I2C_OMAP)
:=
i2c.o
obj-y
+=
$
(
i2c-omap-m
)
$
(
i2c-omap-y
)
...
...
arch/arm/mach-omap2/iommu2.c
浏览文件 @
ad57c394
...
...
@@ -147,6 +147,7 @@ static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra)
printk
(
"
\n
"
);
iommu_write_reg
(
obj
,
stat
,
MMU_IRQSTATUS
);
omap2_iommu_disable
(
obj
);
return
stat
;
}
...
...
@@ -184,7 +185,7 @@ static struct cr_regs *omap2_alloc_cr(struct iommu *obj, struct iotlb_entry *e)
if
(
!
cr
)
return
ERR_PTR
(
-
ENOMEM
);
cr
->
cam
=
(
e
->
da
&
MMU_CAM_VATAG_MASK
)
|
e
->
prsvd
|
e
->
pgsz
;
cr
->
cam
=
(
e
->
da
&
MMU_CAM_VATAG_MASK
)
|
e
->
prsvd
|
e
->
pgsz
|
e
->
valid
;
cr
->
ram
=
e
->
pa
|
e
->
endian
|
e
->
elsz
|
e
->
mixed
;
return
cr
;
...
...
@@ -212,7 +213,8 @@ static ssize_t omap2_dump_cr(struct iommu *obj, struct cr_regs *cr, char *buf)
char
*
p
=
buf
;
/* FIXME: Need more detail analysis of cam/ram */
p
+=
sprintf
(
p
,
"%08x %08x
\n
"
,
cr
->
cam
,
cr
->
ram
);
p
+=
sprintf
(
p
,
"%08x %08x %01x
\n
"
,
cr
->
cam
,
cr
->
ram
,
(
cr
->
cam
&
MMU_CAM_P
)
?
1
:
0
);
return
p
-
buf
;
}
...
...
arch/arm/mach-omap2/omap
3
-iommu.c
→
arch/arm/mach-omap2/omap-iommu.c
浏览文件 @
ad57c394
/*
* omap iommu: omap
3
device registration
* omap iommu: omap device registration
*
* Copyright (C) 2008-2009 Nokia Corporation
*
...
...
@@ -13,6 +13,7 @@
#include <linux/platform_device.h>
#include <plat/iommu.h>
#include <plat/irqs.h>
struct
iommu_device
{
resource_size_t
base
;
...
...
@@ -20,8 +21,11 @@ struct iommu_device {
struct
iommu_platform_data
pdata
;
struct
resource
res
[
2
];
};
static
struct
iommu_device
*
devices
;
static
int
num_iommu_devices
;
static
struct
iommu_device
devices
[]
=
{
#ifdef CONFIG_ARCH_OMAP3
static
struct
iommu_device
omap3_devices
[]
=
{
{
.
base
=
0x480bd400
,
.
irq
=
24
,
...
...
@@ -43,11 +47,48 @@ static struct iommu_device devices[] = {
},
#endif
};
#define NR_IOMMU_DEVICES ARRAY_SIZE(devices)
#define NR_OMAP3_IOMMU_DEVICES ARRAY_SIZE(omap3_devices)
static
struct
platform_device
*
omap3_iommu_pdev
[
NR_OMAP3_IOMMU_DEVICES
];
#else
#define omap3_devices NULL
#define NR_OMAP3_IOMMU_DEVICES 0
#define omap3_iommu_pdev NULL
#endif
#ifdef CONFIG_ARCH_OMAP4
static
struct
iommu_device
omap4_devices
[]
=
{
{
.
base
=
OMAP4_MMU1_BASE
,
.
irq
=
INT_44XX_DUCATI_MMU_IRQ
,
.
pdata
=
{
.
name
=
"ducati"
,
.
nr_tlb_entries
=
32
,
.
clk_name
=
"ducati_ick"
,
},
},
#if defined(CONFIG_MPU_TESLA_IOMMU)
{
.
base
=
OMAP4_MMU2_BASE
,
.
irq
=
INT_44XX_DSP_MMU
,
.
pdata
=
{
.
name
=
"tesla"
,
.
nr_tlb_entries
=
32
,
.
clk_name
=
"tesla_ick"
,
},
},
#endif
};
#define NR_OMAP4_IOMMU_DEVICES ARRAY_SIZE(omap4_devices)
static
struct
platform_device
*
omap4_iommu_pdev
[
NR_OMAP4_IOMMU_DEVICES
];
#else
#define omap4_devices NULL
#define NR_OMAP4_IOMMU_DEVICES 0
#define omap4_iommu_pdev NULL
#endif
static
struct
platform_device
*
omap3_iommu_pdev
[
NR_IOMMU_DEVICES
]
;
static
struct
platform_device
*
*
omap_iommu_pdev
;
static
int
__init
omap
3
_iommu_init
(
void
)
static
int
__init
omap_iommu_init
(
void
)
{
int
i
,
err
;
struct
resource
res
[]
=
{
...
...
@@ -55,7 +96,18 @@ static int __init omap3_iommu_init(void)
{
.
flags
=
IORESOURCE_IRQ
},
};
for
(
i
=
0
;
i
<
NR_IOMMU_DEVICES
;
i
++
)
{
if
(
cpu_is_omap34xx
())
{
devices
=
omap3_devices
;
omap_iommu_pdev
=
omap3_iommu_pdev
;
num_iommu_devices
=
NR_OMAP3_IOMMU_DEVICES
;
}
else
if
(
cpu_is_omap44xx
())
{
devices
=
omap4_devices
;
omap_iommu_pdev
=
omap4_iommu_pdev
;
num_iommu_devices
=
NR_OMAP4_IOMMU_DEVICES
;
}
else
return
-
ENODEV
;
for
(
i
=
0
;
i
<
num_iommu_devices
;
i
++
)
{
struct
platform_device
*
pdev
;
const
struct
iommu_device
*
d
=
&
devices
[
i
];
...
...
@@ -80,26 +132,26 @@ static int __init omap3_iommu_init(void)
err
=
platform_device_add
(
pdev
);
if
(
err
)
goto
err_out
;
omap
3
_iommu_pdev
[
i
]
=
pdev
;
omap_iommu_pdev
[
i
]
=
pdev
;
}
return
0
;
err_out:
while
(
i
--
)
platform_device_put
(
omap
3
_iommu_pdev
[
i
]);
platform_device_put
(
omap_iommu_pdev
[
i
]);
return
err
;
}
module_init
(
omap
3
_iommu_init
);
module_init
(
omap_iommu_init
);
static
void
__exit
omap
3
_iommu_exit
(
void
)
static
void
__exit
omap_iommu_exit
(
void
)
{
int
i
;
for
(
i
=
0
;
i
<
NR_IOMMU_DEVICES
;
i
++
)
platform_device_unregister
(
omap
3
_iommu_pdev
[
i
]);
for
(
i
=
0
;
i
<
num_iommu_devices
;
i
++
)
platform_device_unregister
(
omap_iommu_pdev
[
i
]);
}
module_exit
(
omap
3
_iommu_exit
);
module_exit
(
omap_iommu_exit
);
MODULE_AUTHOR
(
"Hiroshi DOYU"
);
MODULE_DESCRIPTION
(
"omap iommu: omap
3
device registration"
);
MODULE_DESCRIPTION
(
"omap iommu: omap device registration"
);
MODULE_LICENSE
(
"GPL v2"
);
arch/arm/plat-omap/Kconfig
浏览文件 @
ad57c394
...
...
@@ -110,8 +110,13 @@ config OMAP_IOMMU
tristate
config OMAP_IOMMU_DEBUG
depends on OMAP_IOMMU
tristate
tristate "Export OMAP IOMMU internals in DebugFS"
depends on OMAP_IOMMU && DEBUG_FS
help
Select this to see extensive information about
the internal state of OMAP IOMMU in debugfs.
Say N unless you know you need this.
choice
prompt "System timer"
...
...
arch/arm/plat-omap/include/plat/omap44xx.h
浏览文件 @
ad57c394
...
...
@@ -48,5 +48,8 @@
#define OMAP44XX_MAILBOX_BASE (L4_44XX_BASE + 0xF4000)
#define OMAP44XX_HSUSB_OTG_BASE (L4_44XX_BASE + 0xAB000)
#define OMAP4_MMU1_BASE 0x55082000
#define OMAP4_MMU2_BASE 0x4A066000
#endif
/* __ASM_ARCH_OMAP44XX_H */
arch/arm/plat-omap/iommu.c
浏览文件 @
ad57c394
...
...
@@ -25,6 +25,11 @@
#include "iopgtable.h"
#define for_each_iotlb_cr(obj, n, __i, cr) \
for (__i = 0; \
(__i < (n)) && (cr = __iotlb_read_cr((obj), __i), true); \
__i++)
/* accommodate the difference between omap1 and omap2/3 */
static
const
struct
iommu_functions
*
arch_iommu
;
...
...
@@ -172,15 +177,12 @@ static void iotlb_lock_get(struct iommu *obj, struct iotlb_lock *l)
l
->
base
=
MMU_LOCK_BASE
(
val
);
l
->
vict
=
MMU_LOCK_VICT
(
val
);
BUG_ON
(
l
->
base
!=
0
);
/* Currently no preservation is used */
}
static
void
iotlb_lock_set
(
struct
iommu
*
obj
,
struct
iotlb_lock
*
l
)
{
u32
val
;
BUG_ON
(
l
->
base
!=
0
);
/* Currently no preservation is used */
val
=
(
l
->
base
<<
MMU_LOCK_BASE_SHIFT
);
val
|=
(
l
->
vict
<<
MMU_LOCK_VICT_SHIFT
);
...
...
@@ -214,6 +216,20 @@ static inline ssize_t iotlb_dump_cr(struct iommu *obj, struct cr_regs *cr,
return
arch_iommu
->
dump_cr
(
obj
,
cr
,
buf
);
}
/* only used in iotlb iteration for-loop */
static
struct
cr_regs
__iotlb_read_cr
(
struct
iommu
*
obj
,
int
n
)
{
struct
cr_regs
cr
;
struct
iotlb_lock
l
;
iotlb_lock_get
(
obj
,
&
l
);
l
.
vict
=
n
;
iotlb_lock_set
(
obj
,
&
l
);
iotlb_read_cr
(
obj
,
&
cr
);
return
cr
;
}
/**
* load_iotlb_entry - Set an iommu tlb entry
* @obj: target iommu
...
...
@@ -221,7 +237,6 @@ static inline ssize_t iotlb_dump_cr(struct iommu *obj, struct cr_regs *cr,
**/
int
load_iotlb_entry
(
struct
iommu
*
obj
,
struct
iotlb_entry
*
e
)
{
int
i
;
int
err
=
0
;
struct
iotlb_lock
l
;
struct
cr_regs
*
cr
;
...
...
@@ -231,16 +246,19 @@ int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e)
clk_enable
(
obj
->
clk
);
for
(
i
=
0
;
i
<
obj
->
nr_tlb_entries
;
i
++
)
{
iotlb_lock_get
(
obj
,
&
l
);
if
(
l
.
base
==
obj
->
nr_tlb_entries
)
{
dev_warn
(
obj
->
dev
,
"%s: preserve entries full
\n
"
,
__func__
);
err
=
-
EBUSY
;
goto
out
;
}
if
(
!
e
->
prsvd
)
{
int
i
;
struct
cr_regs
tmp
;
iotlb_lock_get
(
obj
,
&
l
);
l
.
vict
=
i
;
iotlb_lock_set
(
obj
,
&
l
);
iotlb_read_cr
(
obj
,
&
tmp
);
for_each_iotlb_cr
(
obj
,
obj
->
nr_tlb_entries
,
i
,
tmp
)
if
(
!
iotlb_cr_valid
(
&
tmp
))
break
;
}
if
(
i
==
obj
->
nr_tlb_entries
)
{
dev_dbg
(
obj
->
dev
,
"%s: full: no entry
\n
"
,
__func__
);
...
...
@@ -248,6 +266,12 @@ int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e)
goto
out
;
}
iotlb_lock_get
(
obj
,
&
l
);
}
else
{
l
.
vict
=
l
.
base
;
iotlb_lock_set
(
obj
,
&
l
);
}
cr
=
iotlb_alloc_cr
(
obj
,
e
);
if
(
IS_ERR
(
cr
))
{
clk_disable
(
obj
->
clk
);
...
...
@@ -257,9 +281,11 @@ int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e)
iotlb_load_cr
(
obj
,
cr
);
kfree
(
cr
);
if
(
e
->
prsvd
)
l
.
base
++
;
/* increment victim for next tlb load */
if
(
++
l
.
vict
==
obj
->
nr_tlb_entries
)
l
.
vict
=
0
;
l
.
vict
=
l
.
base
;
iotlb_lock_set
(
obj
,
&
l
);
out:
clk_disable
(
obj
->
clk
);
...
...
@@ -276,20 +302,15 @@ EXPORT_SYMBOL_GPL(load_iotlb_entry);
**/
void
flush_iotlb_page
(
struct
iommu
*
obj
,
u32
da
)
{
struct
iotlb_lock
l
;
int
i
;
struct
cr_regs
cr
;
clk_enable
(
obj
->
clk
);
for
(
i
=
0
;
i
<
obj
->
nr_tlb_entries
;
i
++
)
{
struct
cr_regs
cr
;
for_each_iotlb_cr
(
obj
,
obj
->
nr_tlb_entries
,
i
,
cr
)
{
u32
start
;
size_t
bytes
;
iotlb_lock_get
(
obj
,
&
l
);
l
.
vict
=
i
;
iotlb_lock_set
(
obj
,
&
l
);
iotlb_read_cr
(
obj
,
&
cr
);
if
(
!
iotlb_cr_valid
(
&
cr
))
continue
;
...
...
@@ -299,7 +320,6 @@ void flush_iotlb_page(struct iommu *obj, u32 da)
if
((
start
<=
da
)
&&
(
da
<
start
+
bytes
))
{
dev_dbg
(
obj
->
dev
,
"%s: %08x<=%08x(%x)
\n
"
,
__func__
,
start
,
da
,
bytes
);
iotlb_load_cr
(
obj
,
&
cr
);
iommu_write_reg
(
obj
,
1
,
MMU_FLUSH_ENTRY
);
}
}
...
...
@@ -370,26 +390,19 @@ EXPORT_SYMBOL_GPL(iommu_dump_ctx);
static
int
__dump_tlb_entries
(
struct
iommu
*
obj
,
struct
cr_regs
*
crs
,
int
num
)
{
int
i
;
struct
iotlb_lock
saved
,
l
;
struct
iotlb_lock
saved
;
struct
cr_regs
tmp
;
struct
cr_regs
*
p
=
crs
;
clk_enable
(
obj
->
clk
);
iotlb_lock_get
(
obj
,
&
saved
);
memcpy
(
&
l
,
&
saved
,
sizeof
(
saved
));
for
(
i
=
0
;
i
<
num
;
i
++
)
{
struct
cr_regs
tmp
;
iotlb_lock_get
(
obj
,
&
l
);
l
.
vict
=
i
;
iotlb_lock_set
(
obj
,
&
l
);
iotlb_read_cr
(
obj
,
&
tmp
);
for_each_iotlb_cr
(
obj
,
num
,
i
,
tmp
)
{
if
(
!
iotlb_cr_valid
(
&
tmp
))
continue
;
*
p
++
=
tmp
;
}
iotlb_lock_set
(
obj
,
&
saved
);
clk_disable
(
obj
->
clk
);
...
...
@@ -503,6 +516,12 @@ static int iopgd_alloc_section(struct iommu *obj, u32 da, u32 pa, u32 prot)
{
u32
*
iopgd
=
iopgd_offset
(
obj
,
da
);
if
((
da
|
pa
)
&
~
IOSECTION_MASK
)
{
dev_err
(
obj
->
dev
,
"%s: %08x:%08x should aligned on %08lx
\n
"
,
__func__
,
da
,
pa
,
IOSECTION_SIZE
);
return
-
EINVAL
;
}
*
iopgd
=
(
pa
&
IOSECTION_MASK
)
|
prot
|
IOPGD_SECTION
;
flush_iopgd_range
(
iopgd
,
iopgd
);
return
0
;
...
...
@@ -513,6 +532,12 @@ static int iopgd_alloc_super(struct iommu *obj, u32 da, u32 pa, u32 prot)
u32
*
iopgd
=
iopgd_offset
(
obj
,
da
);
int
i
;
if
((
da
|
pa
)
&
~
IOSUPER_MASK
)
{
dev_err
(
obj
->
dev
,
"%s: %08x:%08x should aligned on %08lx
\n
"
,
__func__
,
da
,
pa
,
IOSUPER_SIZE
);
return
-
EINVAL
;
}
for
(
i
=
0
;
i
<
16
;
i
++
)
*
(
iopgd
+
i
)
=
(
pa
&
IOSUPER_MASK
)
|
prot
|
IOPGD_SUPER
;
flush_iopgd_range
(
iopgd
,
iopgd
+
15
);
...
...
@@ -542,6 +567,12 @@ static int iopte_alloc_large(struct iommu *obj, u32 da, u32 pa, u32 prot)
u32
*
iopte
=
iopte_alloc
(
obj
,
iopgd
,
da
);
int
i
;
if
((
da
|
pa
)
&
~
IOLARGE_MASK
)
{
dev_err
(
obj
->
dev
,
"%s: %08x:%08x should aligned on %08lx
\n
"
,
__func__
,
da
,
pa
,
IOLARGE_SIZE
);
return
-
EINVAL
;
}
if
(
IS_ERR
(
iopte
))
return
PTR_ERR
(
iopte
);
...
...
arch/arm/plat-omap/iovmm.c
浏览文件 @
ad57c394
...
...
@@ -287,16 +287,19 @@ static struct iovm_struct *alloc_iovm_area(struct iommu *obj, u32 da,
prev_end
=
0
;
list_for_each_entry
(
tmp
,
&
obj
->
mmap
,
list
)
{
if
((
prev_end
<=
start
)
&&
(
start
+
bytes
<
tmp
->
da_start
))
if
(
prev_end
>=
start
)
break
;
if
(
start
+
bytes
<
tmp
->
da_start
)
goto
found
;
if
(
flags
&
IOVMF_DA_ANON
)
start
=
roundup
(
tmp
->
da_end
,
alignement
);
start
=
roundup
(
tmp
->
da_end
+
1
,
alignement
);
prev_end
=
tmp
->
da_end
;
}
if
((
start
>
=
prev_end
)
&&
(
ULONG_MAX
-
start
>=
bytes
))
if
((
start
>
prev_end
)
&&
(
ULONG_MAX
-
start
>=
bytes
))
goto
found
;
dev_dbg
(
obj
->
dev
,
"%s: no space to fit %08x(%x) flags: %08x
\n
"
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录