Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
2e54a007
K
Kernel
项目概览
openeuler
/
Kernel
12 个月 前同步成功
通知
5
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
2e54a007
编写于
10月 24, 2006
作者:
=
=?utf-8?q?Michel_D=C3=A4nzer?=
提交者:
airlied
12月 07, 2006
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
drm: Add support for interrupt triggered driver callback with lock held to DRM core.
Signed-off-by:
N
Dave Airlie
<
airlied@linux.ie
>
上级
bea5679f
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
90 addition
and
0 deletion
+90
-0
drivers/char/drm/drmP.h
drivers/char/drm/drmP.h
+3
-0
drivers/char/drm/drm_irq.c
drivers/char/drm/drm_irq.c
+76
-0
drivers/char/drm/drm_lock.c
drivers/char/drm/drm_lock.c
+11
-0
未找到文件。
drivers/char/drm/drmP.h
浏览文件 @
2e54a007
...
...
@@ -715,6 +715,8 @@ typedef struct drm_device {
drm_vbl_sig_t
vbl_sigs
;
/**< signal list to send on VBLANK */
drm_vbl_sig_t
vbl_sigs2
;
/**< signals to send on secondary VBLANK */
unsigned
int
vbl_pending
;
spinlock_t
tasklet_lock
;
/**< For drm_locked_tasklet */
void
(
*
locked_tasklet_func
)(
struct
drm_device
*
dev
);
/*@} */
cycles_t
ctx_start
;
...
...
@@ -966,6 +968,7 @@ extern int drm_wait_vblank(struct inode *inode, struct file *filp,
unsigned
int
cmd
,
unsigned
long
arg
);
extern
int
drm_vblank_wait
(
drm_device_t
*
dev
,
unsigned
int
*
vbl_seq
);
extern
void
drm_vbl_send_signals
(
drm_device_t
*
dev
);
extern
void
drm_locked_tasklet
(
drm_device_t
*
dev
,
void
(
*
func
)(
drm_device_t
*
));
/* AGP/GART support (drm_agpsupport.h) */
extern
drm_agp_head_t
*
drm_agp_init
(
drm_device_t
*
dev
);
...
...
drivers/char/drm/drm_irq.c
浏览文件 @
2e54a007
...
...
@@ -119,6 +119,7 @@ static int drm_irq_install(drm_device_t * dev)
init_waitqueue_head
(
&
dev
->
vbl_queue
);
spin_lock_init
(
&
dev
->
vbl_lock
);
spin_lock_init
(
&
dev
->
tasklet_lock
);
INIT_LIST_HEAD
(
&
dev
->
vbl_sigs
.
head
);
INIT_LIST_HEAD
(
&
dev
->
vbl_sigs2
.
head
);
...
...
@@ -176,6 +177,8 @@ int drm_irq_uninstall(drm_device_t * dev)
free_irq
(
dev
->
irq
,
dev
);
dev
->
locked_tasklet_func
=
NULL
;
return
0
;
}
...
...
@@ -399,3 +402,76 @@ void drm_vbl_send_signals(drm_device_t * dev)
}
EXPORT_SYMBOL
(
drm_vbl_send_signals
);
/**
* Tasklet wrapper function.
*
* \param data DRM device in disguise.
*
* Attempts to grab the HW lock and calls the driver callback on success. On
* failure, leave the lock marked as contended so the callback can be called
* from drm_unlock().
*/
static
void
drm_locked_tasklet_func
(
unsigned
long
data
)
{
drm_device_t
*
dev
=
(
drm_device_t
*
)
data
;
unsigned
long
irqflags
;
spin_lock_irqsave
(
&
dev
->
tasklet_lock
,
irqflags
);
if
(
!
dev
->
locked_tasklet_func
||
!
drm_lock_take
(
&
dev
->
lock
.
hw_lock
->
lock
,
DRM_KERNEL_CONTEXT
))
{
spin_unlock_irqrestore
(
&
dev
->
tasklet_lock
,
irqflags
);
return
;
}
dev
->
lock
.
lock_time
=
jiffies
;
atomic_inc
(
&
dev
->
counts
[
_DRM_STAT_LOCKS
]);
dev
->
locked_tasklet_func
(
dev
);
drm_lock_free
(
dev
,
&
dev
->
lock
.
hw_lock
->
lock
,
DRM_KERNEL_CONTEXT
);
dev
->
locked_tasklet_func
=
NULL
;
spin_unlock_irqrestore
(
&
dev
->
tasklet_lock
,
irqflags
);
}
/**
* Schedule a tasklet to call back a driver hook with the HW lock held.
*
* \param dev DRM device.
* \param func Driver callback.
*
* This is intended for triggering actions that require the HW lock from an
* interrupt handler. The lock will be grabbed ASAP after the interrupt handler
* completes. Note that the callback may be called from interrupt or process
* context, it must not make any assumptions about this. Also, the HW lock will
* be held with the kernel context or any client context.
*/
void
drm_locked_tasklet
(
drm_device_t
*
dev
,
void
(
*
func
)(
drm_device_t
*
))
{
unsigned
long
irqflags
;
static
DECLARE_TASKLET
(
drm_tasklet
,
drm_locked_tasklet_func
,
0
);
if
(
test_bit
(
TASKLET_STATE_SCHED
,
&
drm_tasklet
.
state
))
return
;
spin_lock_irqsave
(
&
dev
->
tasklet_lock
,
irqflags
);
if
(
dev
->
locked_tasklet_func
)
{
spin_unlock_irqrestore
(
&
dev
->
tasklet_lock
,
irqflags
);
return
;
}
dev
->
locked_tasklet_func
=
func
;
spin_unlock_irqrestore
(
&
dev
->
tasklet_lock
,
irqflags
);
drm_tasklet
.
data
=
(
unsigned
long
)
dev
;
tasklet_hi_schedule
(
&
drm_tasklet
);
}
EXPORT_SYMBOL
(
drm_locked_tasklet
);
drivers/char/drm/drm_lock.c
浏览文件 @
2e54a007
...
...
@@ -155,6 +155,7 @@ int drm_unlock(struct inode *inode, struct file *filp,
drm_file_t
*
priv
=
filp
->
private_data
;
drm_device_t
*
dev
=
priv
->
head
->
dev
;
drm_lock_t
lock
;
unsigned
int
irqflags
;
if
(
copy_from_user
(
&
lock
,
(
drm_lock_t
__user
*
)
arg
,
sizeof
(
lock
)))
return
-
EFAULT
;
...
...
@@ -165,6 +166,16 @@ int drm_unlock(struct inode *inode, struct file *filp,
return
-
EINVAL
;
}
spin_lock_irqsave
(
&
dev
->
tasklet_lock
,
irqflags
);
if
(
dev
->
locked_tasklet_func
)
{
dev
->
locked_tasklet_func
(
dev
);
dev
->
locked_tasklet_func
=
NULL
;
}
spin_unlock_irqrestore
(
&
dev
->
tasklet_lock
,
irqflags
);
atomic_inc
(
&
dev
->
counts
[
_DRM_STAT_UNLOCKS
]);
/* kernel_context_switch isn't used by any of the x86 drm
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录