Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
dda5202b
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
dda5202b
编写于
7月 12, 2017
作者:
D
Dmitry Torokhov
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'next' into for-linus
Prepare second round of input updates for 4.13 merge window.
上级
ede2e7cd
340d394a
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
204 addition
and
44 deletion
+204
-44
drivers/input/keyboard/gpio_keys.c
drivers/input/keyboard/gpio_keys.c
+16
-1
drivers/input/misc/xen-kbdfront.c
drivers/input/misc/xen-kbdfront.c
+179
-40
drivers/input/serio/i8042.c
drivers/input/serio/i8042.c
+9
-3
未找到文件。
drivers/input/keyboard/gpio_keys.c
浏览文件 @
dda5202b
...
...
@@ -48,6 +48,7 @@ struct gpio_button_data {
spinlock_t
lock
;
bool
disabled
;
bool
key_pressed
;
bool
suspended
;
};
struct
gpio_keys_drvdata
{
...
...
@@ -396,8 +397,20 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id)
BUG_ON
(
irq
!=
bdata
->
irq
);
if
(
bdata
->
button
->
wakeup
)
if
(
bdata
->
button
->
wakeup
)
{
const
struct
gpio_keys_button
*
button
=
bdata
->
button
;
pm_stay_awake
(
bdata
->
input
->
dev
.
parent
);
if
(
bdata
->
suspended
&&
(
button
->
type
==
0
||
button
->
type
==
EV_KEY
))
{
/*
* Simulate wakeup key press in case the key has
* already released by the time we got interrupt
* handler to run.
*/
input_report_key
(
bdata
->
input
,
button
->
code
,
1
);
}
}
mod_delayed_work
(
system_wq
,
&
bdata
->
work
,
...
...
@@ -855,6 +868,7 @@ static int __maybe_unused gpio_keys_suspend(struct device *dev)
struct
gpio_button_data
*
bdata
=
&
ddata
->
data
[
i
];
if
(
bdata
->
button
->
wakeup
)
enable_irq_wake
(
bdata
->
irq
);
bdata
->
suspended
=
true
;
}
}
else
{
mutex_lock
(
&
input
->
mutex
);
...
...
@@ -878,6 +892,7 @@ static int __maybe_unused gpio_keys_resume(struct device *dev)
struct
gpio_button_data
*
bdata
=
&
ddata
->
data
[
i
];
if
(
bdata
->
button
->
wakeup
)
disable_irq_wake
(
bdata
->
irq
);
bdata
->
suspended
=
false
;
}
}
else
{
mutex_lock
(
&
input
->
mutex
);
...
...
drivers/input/misc/xen-kbdfront.c
浏览文件 @
dda5202b
...
...
@@ -17,6 +17,7 @@
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/slab.h>
#include <asm/xen/hypervisor.h>
...
...
@@ -34,11 +35,14 @@
struct
xenkbd_info
{
struct
input_dev
*
kbd
;
struct
input_dev
*
ptr
;
struct
input_dev
*
mtouch
;
struct
xenkbd_page
*
page
;
int
gref
;
int
irq
;
struct
xenbus_device
*
xbdev
;
char
phys
[
32
];
/* current MT slot/contact ID we are injecting events in */
int
mtouch_cur_contact_id
;
};
enum
{
KPARAM_X
,
KPARAM_Y
,
KPARAM_CNT
};
...
...
@@ -56,54 +60,124 @@ static void xenkbd_disconnect_backend(struct xenkbd_info *);
* to do that.
*/
static
irqreturn_t
input_handler
(
int
rq
,
void
*
dev_id
)
static
void
xenkbd_handle_motion_event
(
struct
xenkbd_info
*
info
,
struct
xenkbd_motion
*
motion
)
{
struct
xenkbd_info
*
info
=
dev_id
;
struct
xenkbd_page
*
page
=
info
->
page
;
__u32
cons
,
prod
;
input_report_rel
(
info
->
ptr
,
REL_X
,
motion
->
rel_x
);
input_report_rel
(
info
->
ptr
,
REL_Y
,
motion
->
rel_y
);
if
(
motion
->
rel_z
)
input_report_rel
(
info
->
ptr
,
REL_WHEEL
,
-
motion
->
rel_z
);
input_sync
(
info
->
ptr
);
}
prod
=
page
->
in_prod
;
if
(
prod
==
page
->
in_cons
)
return
IRQ_HANDLED
;
rmb
();
/* ensure we see ring contents up to prod */
for
(
cons
=
page
->
in_cons
;
cons
!=
prod
;
cons
++
)
{
union
xenkbd_in_event
*
event
;
static
void
xenkbd_handle_position_event
(
struct
xenkbd_info
*
info
,
struct
xenkbd_position
*
pos
)
{
input_report_abs
(
info
->
ptr
,
ABS_X
,
pos
->
abs_x
);
input_report_abs
(
info
->
ptr
,
ABS_Y
,
pos
->
abs_y
);
if
(
pos
->
rel_z
)
input_report_rel
(
info
->
ptr
,
REL_WHEEL
,
-
pos
->
rel_z
);
input_sync
(
info
->
ptr
);
}
static
void
xenkbd_handle_key_event
(
struct
xenkbd_info
*
info
,
struct
xenkbd_key
*
key
)
{
struct
input_dev
*
dev
;
event
=
&
XENKBD_IN_RING_REF
(
page
,
cons
);
if
(
test_bit
(
key
->
keycode
,
info
->
ptr
->
keybit
))
{
dev
=
info
->
ptr
;
}
else
if
(
test_bit
(
key
->
keycode
,
info
->
kbd
->
keybit
))
{
dev
=
info
->
kbd
;
}
else
{
pr_warn
(
"unhandled keycode 0x%x
\n
"
,
key
->
keycode
);
return
;
}
input_report_key
(
dev
,
key
->
keycode
,
key
->
pressed
);
input_sync
(
dev
);
}
static
void
xenkbd_handle_mt_event
(
struct
xenkbd_info
*
info
,
struct
xenkbd_mtouch
*
mtouch
)
{
if
(
unlikely
(
!
info
->
mtouch
))
return
;
if
(
mtouch
->
contact_id
!=
info
->
mtouch_cur_contact_id
)
{
info
->
mtouch_cur_contact_id
=
mtouch
->
contact_id
;
input_mt_slot
(
info
->
mtouch
,
mtouch
->
contact_id
);
}
switch
(
mtouch
->
event_type
)
{
case
XENKBD_MT_EV_DOWN
:
input_mt_report_slot_state
(
info
->
mtouch
,
MT_TOOL_FINGER
,
true
);
/* fall through */
case
XENKBD_MT_EV_MOTION
:
input_report_abs
(
info
->
mtouch
,
ABS_MT_POSITION_X
,
mtouch
->
u
.
pos
.
abs_x
);
input_report_abs
(
info
->
mtouch
,
ABS_MT_POSITION_Y
,
mtouch
->
u
.
pos
.
abs_y
);
break
;
case
XENKBD_MT_EV_SHAPE
:
input_report_abs
(
info
->
mtouch
,
ABS_MT_TOUCH_MAJOR
,
mtouch
->
u
.
shape
.
major
);
input_report_abs
(
info
->
mtouch
,
ABS_MT_TOUCH_MINOR
,
mtouch
->
u
.
shape
.
minor
);
break
;
case
XENKBD_MT_EV_ORIENT
:
input_report_abs
(
info
->
mtouch
,
ABS_MT_ORIENTATION
,
mtouch
->
u
.
orientation
);
break
;
case
XENKBD_MT_EV_UP
:
input_mt_report_slot_state
(
info
->
mtouch
,
MT_TOOL_FINGER
,
false
);
break
;
case
XENKBD_MT_EV_SYN
:
input_mt_sync_frame
(
info
->
mtouch
);
input_sync
(
info
->
mtouch
);
break
;
}
}
static
void
xenkbd_handle_event
(
struct
xenkbd_info
*
info
,
union
xenkbd_in_event
*
event
)
{
switch
(
event
->
type
)
{
case
XENKBD_TYPE_MOTION
:
input_report_rel
(
dev
,
REL_X
,
event
->
motion
.
rel_x
);
input_report_rel
(
dev
,
REL_Y
,
event
->
motion
.
rel_y
);
if
(
event
->
motion
.
rel_z
)
input_report_rel
(
dev
,
REL_WHEEL
,
-
event
->
motion
.
rel_z
);
xenkbd_handle_motion_event
(
info
,
&
event
->
motion
);
break
;
case
XENKBD_TYPE_KEY
:
dev
=
NULL
;
if
(
test_bit
(
event
->
key
.
keycode
,
info
->
kbd
->
keybit
))
dev
=
info
->
kbd
;
if
(
test_bit
(
event
->
key
.
keycode
,
info
->
ptr
->
keybit
))
dev
=
info
->
ptr
;
if
(
dev
)
input_report_key
(
dev
,
event
->
key
.
keycode
,
event
->
key
.
pressed
);
else
pr_warn
(
"unhandled keycode 0x%x
\n
"
,
event
->
key
.
keycode
);
xenkbd_handle_key_event
(
info
,
&
event
->
key
);
break
;
case
XENKBD_TYPE_POS
:
input_report_abs
(
dev
,
ABS_X
,
event
->
pos
.
abs_x
);
input_report_abs
(
dev
,
ABS_Y
,
event
->
pos
.
abs_y
)
;
if
(
event
->
pos
.
rel_z
)
input_report_rel
(
dev
,
REL_WHEEL
,
-
event
->
pos
.
rel_z
);
xenkbd_handle_position_event
(
info
,
&
event
->
pos
);
break
;
case
XENKBD_TYPE_MTOUCH
:
xenkbd_handle_mt_event
(
info
,
&
event
->
mtouch
);
break
;
}
if
(
dev
)
input_sync
(
dev
);
}
}
static
irqreturn_t
input_handler
(
int
rq
,
void
*
dev_id
)
{
struct
xenkbd_info
*
info
=
dev_id
;
struct
xenkbd_page
*
page
=
info
->
page
;
__u32
cons
,
prod
;
prod
=
page
->
in_prod
;
if
(
prod
==
page
->
in_cons
)
return
IRQ_HANDLED
;
rmb
();
/* ensure we see ring contents up to prod */
for
(
cons
=
page
->
in_cons
;
cons
!=
prod
;
cons
++
)
xenkbd_handle_event
(
info
,
&
XENKBD_IN_RING_REF
(
page
,
cons
));
mb
();
/* ensure we got ring contents */
page
->
in_cons
=
cons
;
notify_remote_via_irq
(
info
->
irq
);
...
...
@@ -115,9 +189,9 @@ static int xenkbd_probe(struct xenbus_device *dev,
const
struct
xenbus_device_id
*
id
)
{
int
ret
,
i
;
unsigned
int
abs
;
unsigned
int
abs
,
touch
;
struct
xenkbd_info
*
info
;
struct
input_dev
*
kbd
,
*
ptr
;
struct
input_dev
*
kbd
,
*
ptr
,
*
mtouch
;
info
=
kzalloc
(
sizeof
(
*
info
),
GFP_KERNEL
);
if
(
!
info
)
{
...
...
@@ -152,6 +226,17 @@ static int xenkbd_probe(struct xenbus_device *dev,
}
}
touch
=
xenbus_read_unsigned
(
dev
->
nodename
,
XENKBD_FIELD_FEAT_MTOUCH
,
0
);
if
(
touch
)
{
ret
=
xenbus_write
(
XBT_NIL
,
dev
->
nodename
,
XENKBD_FIELD_REQ_MTOUCH
,
"1"
);
if
(
ret
)
{
pr_warn
(
"xenkbd: can't request multi-touch"
);
touch
=
0
;
}
}
/* keyboard */
kbd
=
input_allocate_device
();
if
(
!
kbd
)
...
...
@@ -208,6 +293,58 @@ static int xenkbd_probe(struct xenbus_device *dev,
}
info
->
ptr
=
ptr
;
/* multi-touch device */
if
(
touch
)
{
int
num_cont
,
width
,
height
;
mtouch
=
input_allocate_device
();
if
(
!
mtouch
)
goto
error_nomem
;
num_cont
=
xenbus_read_unsigned
(
info
->
xbdev
->
nodename
,
XENKBD_FIELD_MT_NUM_CONTACTS
,
1
);
width
=
xenbus_read_unsigned
(
info
->
xbdev
->
nodename
,
XENKBD_FIELD_MT_WIDTH
,
XENFB_WIDTH
);
height
=
xenbus_read_unsigned
(
info
->
xbdev
->
nodename
,
XENKBD_FIELD_MT_HEIGHT
,
XENFB_HEIGHT
);
mtouch
->
name
=
"Xen Virtual Multi-touch"
;
mtouch
->
phys
=
info
->
phys
;
mtouch
->
id
.
bustype
=
BUS_PCI
;
mtouch
->
id
.
vendor
=
0x5853
;
mtouch
->
id
.
product
=
0xfffd
;
input_set_abs_params
(
mtouch
,
ABS_MT_TOUCH_MAJOR
,
0
,
255
,
0
,
0
);
input_set_abs_params
(
mtouch
,
ABS_MT_POSITION_X
,
0
,
width
,
0
,
0
);
input_set_abs_params
(
mtouch
,
ABS_MT_POSITION_Y
,
0
,
height
,
0
,
0
);
input_set_abs_params
(
mtouch
,
ABS_MT_PRESSURE
,
0
,
255
,
0
,
0
);
ret
=
input_mt_init_slots
(
mtouch
,
num_cont
,
INPUT_MT_DIRECT
);
if
(
ret
)
{
input_free_device
(
mtouch
);
xenbus_dev_fatal
(
info
->
xbdev
,
ret
,
"input_mt_init_slots"
);
goto
error
;
}
ret
=
input_register_device
(
mtouch
);
if
(
ret
)
{
input_free_device
(
mtouch
);
xenbus_dev_fatal
(
info
->
xbdev
,
ret
,
"input_register_device(mtouch)"
);
goto
error
;
}
info
->
mtouch_cur_contact_id
=
-
1
;
info
->
mtouch
=
mtouch
;
}
ret
=
xenkbd_connect_backend
(
dev
,
info
);
if
(
ret
<
0
)
goto
error
;
...
...
@@ -240,6 +377,8 @@ static int xenkbd_remove(struct xenbus_device *dev)
input_unregister_device
(
info
->
kbd
);
if
(
info
->
ptr
)
input_unregister_device
(
info
->
ptr
);
if
(
info
->
mtouch
)
input_unregister_device
(
info
->
mtouch
);
free_page
((
unsigned
long
)
info
->
page
);
kfree
(
info
);
return
0
;
...
...
drivers/input/serio/i8042.c
浏览文件 @
dda5202b
...
...
@@ -436,8 +436,10 @@ static int i8042_start(struct serio *serio)
{
struct
i8042_port
*
port
=
serio
->
port_data
;
spin_lock_irq
(
&
i8042_lock
);
port
->
exists
=
true
;
mb
();
spin_unlock_irq
(
&
i8042_lock
);
return
0
;
}
...
...
@@ -450,16 +452,20 @@ static void i8042_stop(struct serio *serio)
{
struct
i8042_port
*
port
=
serio
->
port_data
;
spin_lock_irq
(
&
i8042_lock
);
port
->
exists
=
false
;
port
->
serio
=
NULL
;
spin_unlock_irq
(
&
i8042_lock
);
/*
* We need to make sure that interrupt handler finishes using
* our serio port before we return from this function.
* We synchronize with both AUX and KBD IRQs because there is
* a (very unlikely) chance that AUX IRQ is raised for KBD port
* and vice versa.
*/
synchronize_irq
(
I8042_AUX_IRQ
);
synchronize_irq
(
I8042_KBD_IRQ
);
port
->
serio
=
NULL
;
}
/*
...
...
@@ -576,7 +582,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
spin_unlock_irqrestore
(
&
i8042_lock
,
flags
);
if
(
likely
(
port
->
exists
&&
!
filtered
))
if
(
likely
(
serio
&&
!
filtered
))
serio_interrupt
(
serio
,
data
,
dfl
);
out:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录