Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
17e8d03c
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 4 年多
通知
15
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
17e8d03c
编写于
10月 25, 2013
作者:
R
Rafael J. Wysocki
浏览文件
操作
浏览文件
下载
差异文件
Merge back earlier 'acpi-assorted' material.
上级
e37f14a5
5e2be4e0
变更
11
显示空白变更内容
内联
并排
Showing
11 changed file
with
335 addition
and
417 deletion
+335
-417
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/acpi/boot.c
+1
-1
drivers/acpi/ac.c
drivers/acpi/ac.c
+65
-191
drivers/acpi/acpi_lpss.c
drivers/acpi/acpi_lpss.c
+9
-3
drivers/acpi/acpi_platform.c
drivers/acpi/acpi_platform.c
+7
-0
drivers/acpi/button.c
drivers/acpi/button.c
+3
-6
drivers/acpi/ec.c
drivers/acpi/ec.c
+24
-25
drivers/acpi/osl.c
drivers/acpi/osl.c
+2
-2
drivers/acpi/sysfs.c
drivers/acpi/sysfs.c
+7
-2
drivers/acpi/thermal.c
drivers/acpi/thermal.c
+20
-23
drivers/acpi/utils.c
drivers/acpi/utils.c
+13
-4
drivers/platform/x86/ideapad-laptop.c
drivers/platform/x86/ideapad-laptop.c
+184
-160
未找到文件。
arch/x86/kernel/acpi/boot.c
浏览文件 @
17e8d03c
...
@@ -745,7 +745,7 @@ static int __init acpi_parse_sbf(struct acpi_table_header *table)
...
@@ -745,7 +745,7 @@ static int __init acpi_parse_sbf(struct acpi_table_header *table)
#ifdef CONFIG_HPET_TIMER
#ifdef CONFIG_HPET_TIMER
#include <asm/hpet.h>
#include <asm/hpet.h>
static
struct
__initdata
resource
*
hpet_res
;
static
struct
resource
*
hpet_res
__initdata
;
static
int
__init
acpi_parse_hpet
(
struct
acpi_table_header
*
table
)
static
int
__init
acpi_parse_hpet
(
struct
acpi_table_header
*
table
)
{
{
...
...
drivers/acpi/ac.c
浏览文件 @
17e8d03c
...
@@ -30,10 +30,7 @@
...
@@ -30,10 +30,7 @@
#include <linux/types.h>
#include <linux/types.h>
#include <linux/dmi.h>
#include <linux/dmi.h>
#include <linux/delay.h>
#include <linux/delay.h>
#ifdef CONFIG_ACPI_PROCFS_POWER
#include <linux/platform_device.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#endif
#include <linux/power_supply.h>
#include <linux/power_supply.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_drivers.h>
...
@@ -55,75 +52,30 @@ MODULE_AUTHOR("Paul Diefenbaugh");
...
@@ -55,75 +52,30 @@ MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION
(
"ACPI AC Adapter Driver"
);
MODULE_DESCRIPTION
(
"ACPI AC Adapter Driver"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
#ifdef CONFIG_ACPI_PROCFS_POWER
extern
struct
proc_dir_entry
*
acpi_lock_ac_dir
(
void
);
extern
void
*
acpi_unlock_ac_dir
(
struct
proc_dir_entry
*
acpi_ac_dir
);
static
int
acpi_ac_open_fs
(
struct
inode
*
inode
,
struct
file
*
file
);
#endif
static
int
acpi_ac_add
(
struct
acpi_device
*
device
);
static
int
acpi_ac_remove
(
struct
acpi_device
*
device
);
static
void
acpi_ac_notify
(
struct
acpi_device
*
device
,
u32
event
);
static
const
struct
acpi_device_id
ac_device_ids
[]
=
{
{
"ACPI0003"
,
0
},
{
""
,
0
},
};
MODULE_DEVICE_TABLE
(
acpi
,
ac_device_ids
);
#ifdef CONFIG_PM_SLEEP
static
int
acpi_ac_resume
(
struct
device
*
dev
);
#endif
static
SIMPLE_DEV_PM_OPS
(
acpi_ac_pm
,
NULL
,
acpi_ac_resume
);
static
int
ac_sleep_before_get_state_ms
;
static
int
ac_sleep_before_get_state_ms
;
static
struct
acpi_driver
acpi_ac_driver
=
{
.
name
=
"ac"
,
.
class
=
ACPI_AC_CLASS
,
.
ids
=
ac_device_ids
,
.
flags
=
ACPI_DRIVER_ALL_NOTIFY_EVENTS
,
.
ops
=
{
.
add
=
acpi_ac_add
,
.
remove
=
acpi_ac_remove
,
.
notify
=
acpi_ac_notify
,
},
.
drv
.
pm
=
&
acpi_ac_pm
,
};
struct
acpi_ac
{
struct
acpi_ac
{
struct
power_supply
charger
;
struct
power_supply
charger
;
struct
acpi_device
*
device
;
struct
acpi_device
*
adev
;
struct
platform_device
*
pdev
;
unsigned
long
long
state
;
unsigned
long
long
state
;
};
};
#define to_acpi_ac(x) container_of(x, struct acpi_ac, charger)
#define to_acpi_ac(x) container_of(x, struct acpi_ac, charger)
#ifdef CONFIG_ACPI_PROCFS_POWER
static
const
struct
file_operations
acpi_ac_fops
=
{
.
owner
=
THIS_MODULE
,
.
open
=
acpi_ac_open_fs
,
.
read
=
seq_read
,
.
llseek
=
seq_lseek
,
.
release
=
single_release
,
};
#endif
/* --------------------------------------------------------------------------
/* --------------------------------------------------------------------------
AC Adapter Management
AC Adapter Management
-------------------------------------------------------------------------- */
-------------------------------------------------------------------------- */
static
int
acpi_ac_get_state
(
struct
acpi_ac
*
ac
)
static
int
acpi_ac_get_state
(
struct
acpi_ac
*
ac
)
{
{
acpi_status
status
=
AE_OK
;
acpi_status
status
;
status
=
acpi_evaluate_integer
(
ac
->
adev
->
handle
,
"_PSR"
,
NULL
,
if
(
!
ac
)
&
ac
->
state
);
return
-
EINVAL
;
status
=
acpi_evaluate_integer
(
ac
->
device
->
handle
,
"_PSR"
,
NULL
,
&
ac
->
state
);
if
(
ACPI_FAILURE
(
status
))
{
if
(
ACPI_FAILURE
(
status
))
{
ACPI_EXCEPTION
((
AE_INFO
,
status
,
"Error reading AC Adapter state"
));
ACPI_EXCEPTION
((
AE_INFO
,
status
,
"Error reading AC Adapter state"
));
ac
->
state
=
ACPI_AC_STATUS_UNKNOWN
;
ac
->
state
=
ACPI_AC_STATUS_UNKNOWN
;
return
-
ENODEV
;
return
-
ENODEV
;
}
}
...
@@ -160,91 +112,13 @@ static enum power_supply_property ac_props[] = {
...
@@ -160,91 +112,13 @@ static enum power_supply_property ac_props[] = {
POWER_SUPPLY_PROP_ONLINE
,
POWER_SUPPLY_PROP_ONLINE
,
};
};
#ifdef CONFIG_ACPI_PROCFS_POWER
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
static
struct
proc_dir_entry
*
acpi_ac_dir
;
static
int
acpi_ac_seq_show
(
struct
seq_file
*
seq
,
void
*
offset
)
{
struct
acpi_ac
*
ac
=
seq
->
private
;
if
(
!
ac
)
return
0
;
if
(
acpi_ac_get_state
(
ac
))
{
seq_puts
(
seq
,
"ERROR: Unable to read AC Adapter state
\n
"
);
return
0
;
}
seq_puts
(
seq
,
"state: "
);
switch
(
ac
->
state
)
{
case
ACPI_AC_STATUS_OFFLINE
:
seq_puts
(
seq
,
"off-line
\n
"
);
break
;
case
ACPI_AC_STATUS_ONLINE
:
seq_puts
(
seq
,
"on-line
\n
"
);
break
;
default:
seq_puts
(
seq
,
"unknown
\n
"
);
break
;
}
return
0
;
}
static
int
acpi_ac_open_fs
(
struct
inode
*
inode
,
struct
file
*
file
)
{
return
single_open
(
file
,
acpi_ac_seq_show
,
PDE_DATA
(
inode
));
}
static
int
acpi_ac_add_fs
(
struct
acpi_device
*
device
)
{
struct
proc_dir_entry
*
entry
=
NULL
;
printk
(
KERN_WARNING
PREFIX
"Deprecated procfs I/F for AC is loaded,"
" please retry with CONFIG_ACPI_PROCFS_POWER cleared
\n
"
);
if
(
!
acpi_device_dir
(
device
))
{
acpi_device_dir
(
device
)
=
proc_mkdir
(
acpi_device_bid
(
device
),
acpi_ac_dir
);
if
(
!
acpi_device_dir
(
device
))
return
-
ENODEV
;
}
/* 'state' [R] */
entry
=
proc_create_data
(
ACPI_AC_FILE_STATE
,
S_IRUGO
,
acpi_device_dir
(
device
),
&
acpi_ac_fops
,
acpi_driver_data
(
device
));
if
(
!
entry
)
return
-
ENODEV
;
return
0
;
}
static
int
acpi_ac_remove_fs
(
struct
acpi_device
*
device
)
{
if
(
acpi_device_dir
(
device
))
{
remove_proc_entry
(
ACPI_AC_FILE_STATE
,
acpi_device_dir
(
device
));
remove_proc_entry
(
acpi_device_bid
(
device
),
acpi_ac_dir
);
acpi_device_dir
(
device
)
=
NULL
;
}
return
0
;
}
#endif
/* --------------------------------------------------------------------------
/* --------------------------------------------------------------------------
Driver Model
Driver Model
-------------------------------------------------------------------------- */
-------------------------------------------------------------------------- */
static
void
acpi_ac_notify
(
struct
acpi_device
*
device
,
u32
event
)
static
void
acpi_ac_notify
_handler
(
acpi_handle
handle
,
u32
event
,
void
*
data
)
{
{
struct
acpi_ac
*
ac
=
acpi_driver_data
(
device
);
struct
acpi_ac
*
ac
=
data
;
if
(
!
ac
)
if
(
!
ac
)
return
;
return
;
...
@@ -267,10 +141,10 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event)
...
@@ -267,10 +141,10 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event)
msleep
(
ac_sleep_before_get_state_ms
);
msleep
(
ac_sleep_before_get_state_ms
);
acpi_ac_get_state
(
ac
);
acpi_ac_get_state
(
ac
);
acpi_bus_generate_netlink_event
(
device
->
pnp
.
device_class
,
acpi_bus_generate_netlink_event
(
ac
->
adev
->
pnp
.
device_class
,
dev_name
(
&
device
->
dev
),
event
,
dev_name
(
&
ac
->
pdev
->
dev
)
,
(
u32
)
ac
->
state
);
event
,
(
u32
)
ac
->
state
);
acpi_notifier_call_chain
(
device
,
event
,
(
u32
)
ac
->
state
);
acpi_notifier_call_chain
(
ac
->
adev
,
event
,
(
u32
)
ac
->
state
);
kobject_uevent
(
&
ac
->
charger
.
dev
->
kobj
,
KOBJ_CHANGE
);
kobject_uevent
(
&
ac
->
charger
.
dev
->
kobj
,
KOBJ_CHANGE
);
}
}
...
@@ -295,53 +169,55 @@ static struct dmi_system_id ac_dmi_table[] = {
...
@@ -295,53 +169,55 @@ static struct dmi_system_id ac_dmi_table[] = {
{},
{},
};
};
static
int
acpi_ac_
add
(
struct
acpi_device
*
device
)
static
int
acpi_ac_
probe
(
struct
platform_device
*
pdev
)
{
{
int
result
=
0
;
int
result
=
0
;
struct
acpi_ac
*
ac
=
NULL
;
struct
acpi_ac
*
ac
=
NULL
;
struct
acpi_device
*
adev
;
if
(
!
pdev
)
if
(
!
device
)
return
-
EINVAL
;
return
-
EINVAL
;
result
=
acpi_bus_get_device
(
ACPI_HANDLE
(
&
pdev
->
dev
),
&
adev
);
if
(
result
)
return
-
ENODEV
;
ac
=
kzalloc
(
sizeof
(
struct
acpi_ac
),
GFP_KERNEL
);
ac
=
kzalloc
(
sizeof
(
struct
acpi_ac
),
GFP_KERNEL
);
if
(
!
ac
)
if
(
!
ac
)
return
-
ENOMEM
;
return
-
ENOMEM
;
ac
->
device
=
device
;
strcpy
(
acpi_device_name
(
adev
),
ACPI_AC_DEVICE_NAME
);
strcpy
(
acpi_device_name
(
device
),
ACPI_AC_DEVICE_NAME
);
strcpy
(
acpi_device_class
(
adev
),
ACPI_AC_CLASS
);
strcpy
(
acpi_device_class
(
device
),
ACPI_AC_CLASS
);
ac
->
adev
=
adev
;
device
->
driver_data
=
ac
;
ac
->
pdev
=
pdev
;
platform_set_drvdata
(
pdev
,
ac
);
result
=
acpi_ac_get_state
(
ac
);
result
=
acpi_ac_get_state
(
ac
);
if
(
result
)
if
(
result
)
goto
end
;
goto
end
;
#ifdef CONFIG_ACPI_PROCFS_POWER
ac
->
charger
.
name
=
acpi_device_bid
(
adev
);
result
=
acpi_ac_add_fs
(
device
);
#endif
if
(
result
)
goto
end
;
ac
->
charger
.
name
=
acpi_device_bid
(
device
);
ac
->
charger
.
type
=
POWER_SUPPLY_TYPE_MAINS
;
ac
->
charger
.
type
=
POWER_SUPPLY_TYPE_MAINS
;
ac
->
charger
.
properties
=
ac_props
;
ac
->
charger
.
properties
=
ac_props
;
ac
->
charger
.
num_properties
=
ARRAY_SIZE
(
ac_props
);
ac
->
charger
.
num_properties
=
ARRAY_SIZE
(
ac_props
);
ac
->
charger
.
get_property
=
get_ac_property
;
ac
->
charger
.
get_property
=
get_ac_property
;
result
=
power_supply_register
(
&
ac
->
device
->
dev
,
&
ac
->
charger
);
result
=
power_supply_register
(
&
pdev
->
dev
,
&
ac
->
charger
);
if
(
result
)
if
(
result
)
goto
end
;
goto
end
;
result
=
acpi_install_notify_handler
(
ACPI_HANDLE
(
&
pdev
->
dev
),
ACPI_DEVICE_NOTIFY
,
acpi_ac_notify_handler
,
ac
);
if
(
result
)
{
power_supply_unregister
(
&
ac
->
charger
);
goto
end
;
}
printk
(
KERN_INFO
PREFIX
"%s [%s] (%s)
\n
"
,
printk
(
KERN_INFO
PREFIX
"%s [%s] (%s)
\n
"
,
acpi_device_name
(
device
),
acpi_device_bid
(
device
),
acpi_device_name
(
adev
),
acpi_device_bid
(
adev
),
ac
->
state
?
"on-line"
:
"off-line"
);
ac
->
state
?
"on-line"
:
"off-line"
);
end:
end:
if
(
result
)
{
if
(
result
)
#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_ac_remove_fs
(
device
);
#endif
kfree
(
ac
);
kfree
(
ac
);
}
dmi_check_system
(
ac_dmi_table
);
dmi_check_system
(
ac_dmi_table
);
return
result
;
return
result
;
...
@@ -356,7 +232,7 @@ static int acpi_ac_resume(struct device *dev)
...
@@ -356,7 +232,7 @@ static int acpi_ac_resume(struct device *dev)
if
(
!
dev
)
if
(
!
dev
)
return
-
EINVAL
;
return
-
EINVAL
;
ac
=
acpi_driver_data
(
to_acpi
_device
(
dev
));
ac
=
platform_get_drvdata
(
to_platform
_device
(
dev
));
if
(
!
ac
)
if
(
!
ac
)
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -368,28 +244,44 @@ static int acpi_ac_resume(struct device *dev)
...
@@ -368,28 +244,44 @@ static int acpi_ac_resume(struct device *dev)
return
0
;
return
0
;
}
}
#endif
#endif
static
SIMPLE_DEV_PM_OPS
(
acpi_ac_pm_ops
,
NULL
,
acpi_ac_resume
);
static
int
acpi_ac_remove
(
struct
acpi_device
*
device
)
static
int
acpi_ac_remove
(
struct
platform_device
*
pdev
)
{
{
struct
acpi_ac
*
ac
=
NULL
;
struct
acpi_ac
*
ac
;
if
(
!
device
||
!
acpi_driver_data
(
device
)
)
if
(
!
pdev
)
return
-
EINVAL
;
return
-
EINVAL
;
ac
=
acpi_driver_data
(
device
);
acpi_remove_notify_handler
(
ACPI_HANDLE
(
&
pdev
->
dev
),
ACPI_DEVICE_NOTIFY
,
acpi_ac_notify_handler
);
ac
=
platform_get_drvdata
(
pdev
);
if
(
ac
->
charger
.
dev
)
if
(
ac
->
charger
.
dev
)
power_supply_unregister
(
&
ac
->
charger
);
power_supply_unregister
(
&
ac
->
charger
);
#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_ac_remove_fs
(
device
);
#endif
kfree
(
ac
);
kfree
(
ac
);
return
0
;
return
0
;
}
}
static
const
struct
acpi_device_id
acpi_ac_match
[]
=
{
{
"ACPI0003"
,
0
},
{
}
};
MODULE_DEVICE_TABLE
(
acpi
,
acpi_ac_match
);
static
struct
platform_driver
acpi_ac_driver
=
{
.
probe
=
acpi_ac_probe
,
.
remove
=
acpi_ac_remove
,
.
driver
=
{
.
name
=
"acpi-ac"
,
.
owner
=
THIS_MODULE
,
.
pm
=
&
acpi_ac_pm_ops
,
.
acpi_match_table
=
ACPI_PTR
(
acpi_ac_match
),
},
};
static
int
__init
acpi_ac_init
(
void
)
static
int
__init
acpi_ac_init
(
void
)
{
{
int
result
;
int
result
;
...
@@ -397,34 +289,16 @@ static int __init acpi_ac_init(void)
...
@@ -397,34 +289,16 @@ static int __init acpi_ac_init(void)
if
(
acpi_disabled
)
if
(
acpi_disabled
)
return
-
ENODEV
;
return
-
ENODEV
;
#ifdef CONFIG_ACPI_PROCFS_POWER
result
=
platform_driver_register
(
&
acpi_ac_driver
);
acpi_ac_dir
=
acpi_lock_ac_dir
();
if
(
result
<
0
)
if
(
!
acpi_ac_dir
)
return
-
ENODEV
;
#endif
result
=
acpi_bus_register_driver
(
&
acpi_ac_driver
);
if
(
result
<
0
)
{
#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_unlock_ac_dir
(
acpi_ac_dir
);
#endif
return
-
ENODEV
;
return
-
ENODEV
;
}
return
0
;
return
0
;
}
}
static
void
__exit
acpi_ac_exit
(
void
)
static
void
__exit
acpi_ac_exit
(
void
)
{
{
platform_driver_unregister
(
&
acpi_ac_driver
);
acpi_bus_unregister_driver
(
&
acpi_ac_driver
);
#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_unlock_ac_dir
(
acpi_ac_dir
);
#endif
return
;
}
}
module_init
(
acpi_ac_init
);
module_init
(
acpi_ac_init
);
module_exit
(
acpi_ac_exit
);
module_exit
(
acpi_ac_exit
);
drivers/acpi/acpi_lpss.c
浏览文件 @
17e8d03c
...
@@ -30,6 +30,7 @@ ACPI_MODULE_NAME("acpi_lpss");
...
@@ -30,6 +30,7 @@ ACPI_MODULE_NAME("acpi_lpss");
/* Offsets relative to LPSS_PRIVATE_OFFSET */
/* Offsets relative to LPSS_PRIVATE_OFFSET */
#define LPSS_GENERAL 0x08
#define LPSS_GENERAL 0x08
#define LPSS_GENERAL_LTR_MODE_SW BIT(2)
#define LPSS_GENERAL_LTR_MODE_SW BIT(2)
#define LPSS_GENERAL_UART_RTS_OVRD BIT(3)
#define LPSS_SW_LTR 0x10
#define LPSS_SW_LTR 0x10
#define LPSS_AUTO_LTR 0x14
#define LPSS_AUTO_LTR 0x14
#define LPSS_TX_INT 0x20
#define LPSS_TX_INT 0x20
...
@@ -68,11 +69,16 @@ struct lpss_private_data {
...
@@ -68,11 +69,16 @@ struct lpss_private_data {
static
void
lpss_uart_setup
(
struct
lpss_private_data
*
pdata
)
static
void
lpss_uart_setup
(
struct
lpss_private_data
*
pdata
)
{
{
unsigned
int
tx_int_offset
=
pdata
->
dev_desc
->
prv_offset
+
LPSS_TX_INT
;
unsigned
int
offset
;
u32
reg
;
u32
reg
;
reg
=
readl
(
pdata
->
mmio_base
+
tx_int_offset
);
offset
=
pdata
->
dev_desc
->
prv_offset
+
LPSS_TX_INT
;
writel
(
reg
|
LPSS_TX_INT_MASK
,
pdata
->
mmio_base
+
tx_int_offset
);
reg
=
readl
(
pdata
->
mmio_base
+
offset
);
writel
(
reg
|
LPSS_TX_INT_MASK
,
pdata
->
mmio_base
+
offset
);
offset
=
pdata
->
dev_desc
->
prv_offset
+
LPSS_GENERAL
;
reg
=
readl
(
pdata
->
mmio_base
+
offset
);
writel
(
reg
|
LPSS_GENERAL_UART_RTS_OVRD
,
pdata
->
mmio_base
+
offset
);
}
}
static
struct
lpss_device_desc
lpt_dev_desc
=
{
static
struct
lpss_device_desc
lpt_dev_desc
=
{
...
...
drivers/acpi/acpi_platform.c
浏览文件 @
17e8d03c
...
@@ -29,6 +29,13 @@ ACPI_MODULE_NAME("platform");
...
@@ -29,6 +29,13 @@ ACPI_MODULE_NAME("platform");
static
const
struct
acpi_device_id
acpi_platform_device_ids
[]
=
{
static
const
struct
acpi_device_id
acpi_platform_device_ids
[]
=
{
{
"PNP0D40"
},
{
"PNP0D40"
},
{
"ACPI0003"
},
{
"VPC2004"
},
{
"BCM4752"
},
/* Intel Smart Sound Technology */
{
"INT33C8"
},
{
"80860F28"
},
{
}
{
}
};
};
...
...
drivers/acpi/button.c
浏览文件 @
17e8d03c
...
@@ -383,18 +383,15 @@ static int acpi_button_add(struct acpi_device *device)
...
@@ -383,18 +383,15 @@ static int acpi_button_add(struct acpi_device *device)
switch
(
button
->
type
)
{
switch
(
button
->
type
)
{
case
ACPI_BUTTON_TYPE_POWER
:
case
ACPI_BUTTON_TYPE_POWER
:
input
->
evbit
[
0
]
=
BIT_MASK
(
EV_KEY
);
input_set_capability
(
input
,
EV_KEY
,
KEY_POWER
);
set_bit
(
KEY_POWER
,
input
->
keybit
);
break
;
break
;
case
ACPI_BUTTON_TYPE_SLEEP
:
case
ACPI_BUTTON_TYPE_SLEEP
:
input
->
evbit
[
0
]
=
BIT_MASK
(
EV_KEY
);
input_set_capability
(
input
,
EV_KEY
,
KEY_SLEEP
);
set_bit
(
KEY_SLEEP
,
input
->
keybit
);
break
;
break
;
case
ACPI_BUTTON_TYPE_LID
:
case
ACPI_BUTTON_TYPE_LID
:
input
->
evbit
[
0
]
=
BIT_MASK
(
EV_SW
);
input_set_capability
(
input
,
EV_SW
,
SW_LID
);
set_bit
(
SW_LID
,
input
->
swbit
);
break
;
break
;
}
}
...
...
drivers/acpi/ec.c
浏览文件 @
17e8d03c
...
@@ -28,6 +28,7 @@
...
@@ -28,6 +28,7 @@
/* Uncomment next line to get verbose printout */
/* Uncomment next line to get verbose printout */
/* #define DEBUG */
/* #define DEBUG */
#define pr_fmt(fmt) "ACPI : EC: " fmt
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/module.h>
...
@@ -49,9 +50,6 @@
...
@@ -49,9 +50,6 @@
#define ACPI_EC_DEVICE_NAME "Embedded Controller"
#define ACPI_EC_DEVICE_NAME "Embedded Controller"
#define ACPI_EC_FILE_INFO "info"
#define ACPI_EC_FILE_INFO "info"
#undef PREFIX
#define PREFIX "ACPI: EC: "
/* EC status register */
/* EC status register */
#define ACPI_EC_FLAG_OBF 0x01
/* Output buffer full */
#define ACPI_EC_FLAG_OBF 0x01
/* Output buffer full */
#define ACPI_EC_FLAG_IBF 0x02
/* Input buffer full */
#define ACPI_EC_FLAG_IBF 0x02
/* Input buffer full */
...
@@ -131,26 +129,26 @@ static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */
...
@@ -131,26 +129,26 @@ static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */
static
inline
u8
acpi_ec_read_status
(
struct
acpi_ec
*
ec
)
static
inline
u8
acpi_ec_read_status
(
struct
acpi_ec
*
ec
)
{
{
u8
x
=
inb
(
ec
->
command_addr
);
u8
x
=
inb
(
ec
->
command_addr
);
pr_debug
(
PREFIX
"---> status = 0x%2.2x
\n
"
,
x
);
pr_debug
(
"---> status = 0x%2.2x
\n
"
,
x
);
return
x
;
return
x
;
}
}
static
inline
u8
acpi_ec_read_data
(
struct
acpi_ec
*
ec
)
static
inline
u8
acpi_ec_read_data
(
struct
acpi_ec
*
ec
)
{
{
u8
x
=
inb
(
ec
->
data_addr
);
u8
x
=
inb
(
ec
->
data_addr
);
pr_debug
(
PREFIX
"---> data = 0x%2.2x
\n
"
,
x
);
pr_debug
(
"---> data = 0x%2.2x
\n
"
,
x
);
return
x
;
return
x
;
}
}
static
inline
void
acpi_ec_write_cmd
(
struct
acpi_ec
*
ec
,
u8
command
)
static
inline
void
acpi_ec_write_cmd
(
struct
acpi_ec
*
ec
,
u8
command
)
{
{
pr_debug
(
PREFIX
"<--- command = 0x%2.2x
\n
"
,
command
);
pr_debug
(
"<--- command = 0x%2.2x
\n
"
,
command
);
outb
(
command
,
ec
->
command_addr
);
outb
(
command
,
ec
->
command_addr
);
}
}
static
inline
void
acpi_ec_write_data
(
struct
acpi_ec
*
ec
,
u8
data
)
static
inline
void
acpi_ec_write_data
(
struct
acpi_ec
*
ec
,
u8
data
)
{
{
pr_debug
(
PREFIX
"<--- data = 0x%2.2x
\n
"
,
data
);
pr_debug
(
"<--- data = 0x%2.2x
\n
"
,
data
);
outb
(
data
,
ec
->
data_addr
);
outb
(
data
,
ec
->
data_addr
);
}
}
...
@@ -241,7 +239,7 @@ static int ec_poll(struct acpi_ec *ec)
...
@@ -241,7 +239,7 @@ static int ec_poll(struct acpi_ec *ec)
}
}
advance_transaction
(
ec
,
acpi_ec_read_status
(
ec
));
advance_transaction
(
ec
,
acpi_ec_read_status
(
ec
));
}
while
(
time_before
(
jiffies
,
delay
));
}
while
(
time_before
(
jiffies
,
delay
));
pr_debug
(
PREFIX
"controller reset, restart transaction
\n
"
);
pr_debug
(
"controller reset, restart transaction
\n
"
);
spin_lock_irqsave
(
&
ec
->
lock
,
flags
);
spin_lock_irqsave
(
&
ec
->
lock
,
flags
);
start_transaction
(
ec
);
start_transaction
(
ec
);
spin_unlock_irqrestore
(
&
ec
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
ec
->
lock
,
flags
);
...
@@ -309,12 +307,12 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
...
@@ -309,12 +307,12 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
}
}
}
}
if
(
ec_wait_ibf0
(
ec
))
{
if
(
ec_wait_ibf0
(
ec
))
{
pr_err
(
PREFIX
"input buffer is not empty, "
pr_err
(
"input buffer is not empty, "
"aborting transaction
\n
"
);
"aborting transaction
\n
"
);
status
=
-
ETIME
;
status
=
-
ETIME
;
goto
end
;
goto
end
;
}
}
pr_debug
(
PREFIX
"transaction start (cmd=0x%02x, addr=0x%02x)
\n
"
,
pr_debug
(
"transaction start (cmd=0x%02x, addr=0x%02x)
\n
"
,
t
->
command
,
t
->
wdata
?
t
->
wdata
[
0
]
:
0
);
t
->
command
,
t
->
wdata
?
t
->
wdata
[
0
]
:
0
);
/* disable GPE during transaction if storm is detected */
/* disable GPE during transaction if storm is detected */
if
(
test_bit
(
EC_FLAGS_GPE_STORM
,
&
ec
->
flags
))
{
if
(
test_bit
(
EC_FLAGS_GPE_STORM
,
&
ec
->
flags
))
{
...
@@ -331,12 +329,12 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
...
@@ -331,12 +329,12 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
/* It is safe to enable the GPE outside of the transaction. */
/* It is safe to enable the GPE outside of the transaction. */
acpi_enable_gpe
(
NULL
,
ec
->
gpe
);
acpi_enable_gpe
(
NULL
,
ec
->
gpe
);
}
else
if
(
t
->
irq_count
>
ec_storm_threshold
)
{
}
else
if
(
t
->
irq_count
>
ec_storm_threshold
)
{
pr_info
(
PREFIX
"GPE storm detected(%d GPEs), "
pr_info
(
"GPE storm detected(%d GPEs), "
"transactions will use polling mode
\n
"
,
"transactions will use polling mode
\n
"
,
t
->
irq_count
);
t
->
irq_count
);
set_bit
(
EC_FLAGS_GPE_STORM
,
&
ec
->
flags
);
set_bit
(
EC_FLAGS_GPE_STORM
,
&
ec
->
flags
);
}
}
pr_debug
(
PREFIX
"transaction end
\n
"
);
pr_debug
(
"transaction end
\n
"
);
end:
end:
if
(
ec
->
global_lock
)
if
(
ec
->
global_lock
)
acpi_release_global_lock
(
glk
);
acpi_release_global_lock
(
glk
);
...
@@ -570,12 +568,12 @@ static void acpi_ec_run(void *cxt)
...
@@ -570,12 +568,12 @@ static void acpi_ec_run(void *cxt)
struct
acpi_ec_query_handler
*
handler
=
cxt
;
struct
acpi_ec_query_handler
*
handler
=
cxt
;
if
(
!
handler
)
if
(
!
handler
)
return
;
return
;
pr_debug
(
PREFIX
"start query execution
\n
"
);
pr_debug
(
"start query execution
\n
"
);
if
(
handler
->
func
)
if
(
handler
->
func
)
handler
->
func
(
handler
->
data
);
handler
->
func
(
handler
->
data
);
else
if
(
handler
->
handle
)
else
if
(
handler
->
handle
)
acpi_evaluate_object
(
handler
->
handle
,
NULL
,
NULL
,
NULL
);
acpi_evaluate_object
(
handler
->
handle
,
NULL
,
NULL
,
NULL
);
pr_debug
(
PREFIX
"stop query execution
\n
"
);
pr_debug
(
"stop query execution
\n
"
);
kfree
(
handler
);
kfree
(
handler
);
}
}
...
@@ -593,7 +591,8 @@ static int acpi_ec_sync_query(struct acpi_ec *ec)
...
@@ -593,7 +591,8 @@ static int acpi_ec_sync_query(struct acpi_ec *ec)
if
(
!
copy
)
if
(
!
copy
)
return
-
ENOMEM
;
return
-
ENOMEM
;
memcpy
(
copy
,
handler
,
sizeof
(
*
copy
));
memcpy
(
copy
,
handler
,
sizeof
(
*
copy
));
pr_debug
(
PREFIX
"push query execution (0x%2x) on queue
\n
"
,
value
);
pr_debug
(
"push query execution (0x%2x) on queue
\n
"
,
value
);
return
acpi_os_execute
((
copy
->
func
)
?
return
acpi_os_execute
((
copy
->
func
)
?
OSL_NOTIFY_HANDLER
:
OSL_GPE_HANDLER
,
OSL_NOTIFY_HANDLER
:
OSL_GPE_HANDLER
,
acpi_ec_run
,
copy
);
acpi_ec_run
,
copy
);
...
@@ -616,7 +615,7 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state)
...
@@ -616,7 +615,7 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state)
{
{
if
(
state
&
ACPI_EC_FLAG_SCI
)
{
if
(
state
&
ACPI_EC_FLAG_SCI
)
{
if
(
!
test_and_set_bit
(
EC_FLAGS_QUERY_PENDING
,
&
ec
->
flags
))
{
if
(
!
test_and_set_bit
(
EC_FLAGS_QUERY_PENDING
,
&
ec
->
flags
))
{
pr_debug
(
PREFIX
"push gpe query to the queue
\n
"
);
pr_debug
(
"push gpe query to the queue
\n
"
);
return
acpi_os_execute
(
OSL_NOTIFY_HANDLER
,
return
acpi_os_execute
(
OSL_NOTIFY_HANDLER
,
acpi_ec_gpe_query
,
ec
);
acpi_ec_gpe_query
,
ec
);
}
}
...
@@ -630,7 +629,7 @@ static u32 acpi_ec_gpe_handler(acpi_handle gpe_device,
...
@@ -630,7 +629,7 @@ static u32 acpi_ec_gpe_handler(acpi_handle gpe_device,
struct
acpi_ec
*
ec
=
data
;
struct
acpi_ec
*
ec
=
data
;
u8
status
=
acpi_ec_read_status
(
ec
);
u8
status
=
acpi_ec_read_status
(
ec
);
pr_debug
(
PREFIX
"~~~> interrupt, status:0x%02x
\n
"
,
status
);
pr_debug
(
"~~~> interrupt, status:0x%02x
\n
"
,
status
);
advance_transaction
(
ec
,
status
);
advance_transaction
(
ec
,
status
);
if
(
ec_transaction_done
(
ec
)
&&
if
(
ec_transaction_done
(
ec
)
&&
...
@@ -776,7 +775,7 @@ static int ec_install_handlers(struct acpi_ec *ec)
...
@@ -776,7 +775,7 @@ static int ec_install_handlers(struct acpi_ec *ec)
* The AE_NOT_FOUND error will be ignored and OS
* The AE_NOT_FOUND error will be ignored and OS
* continue to initialize EC.
* continue to initialize EC.
*/
*/
pr
intk
(
KERN_ERR
"Fail in evaluating the _REG object"
pr
_err
(
"Fail in evaluating the _REG object"
" of EC device. Broken bios is suspected.
\n
"
);
" of EC device. Broken bios is suspected.
\n
"
);
}
else
{
}
else
{
acpi_remove_gpe_handler
(
NULL
,
ec
->
gpe
,
acpi_remove_gpe_handler
(
NULL
,
ec
->
gpe
,
...
@@ -795,10 +794,10 @@ static void ec_remove_handlers(struct acpi_ec *ec)
...
@@ -795,10 +794,10 @@ static void ec_remove_handlers(struct acpi_ec *ec)
acpi_disable_gpe
(
NULL
,
ec
->
gpe
);
acpi_disable_gpe
(
NULL
,
ec
->
gpe
);
if
(
ACPI_FAILURE
(
acpi_remove_address_space_handler
(
ec
->
handle
,
if
(
ACPI_FAILURE
(
acpi_remove_address_space_handler
(
ec
->
handle
,
ACPI_ADR_SPACE_EC
,
&
acpi_ec_space_handler
)))
ACPI_ADR_SPACE_EC
,
&
acpi_ec_space_handler
)))
pr_err
(
PREFIX
"failed to remove space handler
\n
"
);
pr_err
(
"failed to remove space handler
\n
"
);
if
(
ACPI_FAILURE
(
acpi_remove_gpe_handler
(
NULL
,
ec
->
gpe
,
if
(
ACPI_FAILURE
(
acpi_remove_gpe_handler
(
NULL
,
ec
->
gpe
,
&
acpi_ec_gpe_handler
)))
&
acpi_ec_gpe_handler
)))
pr_err
(
PREFIX
"failed to remove gpe handler
\n
"
);
pr_err
(
"failed to remove gpe handler
\n
"
);
clear_bit
(
EC_FLAGS_HANDLERS_INSTALLED
,
&
ec
->
flags
);
clear_bit
(
EC_FLAGS_HANDLERS_INSTALLED
,
&
ec
->
flags
);
}
}
...
@@ -840,7 +839,7 @@ static int acpi_ec_add(struct acpi_device *device)
...
@@ -840,7 +839,7 @@ static int acpi_ec_add(struct acpi_device *device)
ret
=
!!
request_region
(
ec
->
command_addr
,
1
,
"EC cmd"
);
ret
=
!!
request_region
(
ec
->
command_addr
,
1
,
"EC cmd"
);
WARN
(
!
ret
,
"Could not request EC cmd io port 0x%lx"
,
ec
->
command_addr
);
WARN
(
!
ret
,
"Could not request EC cmd io port 0x%lx"
,
ec
->
command_addr
);
pr_info
(
PREFIX
"GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx
\n
"
,
pr_info
(
"GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx
\n
"
,
ec
->
gpe
,
ec
->
command_addr
,
ec
->
data_addr
);
ec
->
gpe
,
ec
->
command_addr
,
ec
->
data_addr
);
ret
=
ec_install_handlers
(
ec
);
ret
=
ec_install_handlers
(
ec
);
...
@@ -931,7 +930,7 @@ static int ec_validate_ecdt(const struct dmi_system_id *id)
...
@@ -931,7 +930,7 @@ static int ec_validate_ecdt(const struct dmi_system_id *id)
/* MSI EC needs special treatment, enable it */
/* MSI EC needs special treatment, enable it */
static
int
ec_flag_msi
(
const
struct
dmi_system_id
*
id
)
static
int
ec_flag_msi
(
const
struct
dmi_system_id
*
id
)
{
{
pr
intk
(
KERN_DEBUG
PREFIX
"Detected MSI hardware, enabling workarounds.
\n
"
);
pr
_debug
(
"Detected MSI hardware, enabling workarounds.
\n
"
);
EC_FLAGS_MSI
=
1
;
EC_FLAGS_MSI
=
1
;
EC_FLAGS_VALIDATE_ECDT
=
1
;
EC_FLAGS_VALIDATE_ECDT
=
1
;
return
0
;
return
0
;
...
@@ -1010,7 +1009,7 @@ int __init acpi_ec_ecdt_probe(void)
...
@@ -1010,7 +1009,7 @@ int __init acpi_ec_ecdt_probe(void)
status
=
acpi_get_table
(
ACPI_SIG_ECDT
,
1
,
status
=
acpi_get_table
(
ACPI_SIG_ECDT
,
1
,
(
struct
acpi_table_header
**
)
&
ecdt_ptr
);
(
struct
acpi_table_header
**
)
&
ecdt_ptr
);
if
(
ACPI_SUCCESS
(
status
))
{
if
(
ACPI_SUCCESS
(
status
))
{
pr_info
(
PREFIX
"EC description table is found, configuring boot EC
\n
"
);
pr_info
(
"EC description table is found, configuring boot EC
\n
"
);
boot_ec
->
command_addr
=
ecdt_ptr
->
control
.
address
;
boot_ec
->
command_addr
=
ecdt_ptr
->
control
.
address
;
boot_ec
->
data_addr
=
ecdt_ptr
->
data
.
address
;
boot_ec
->
data_addr
=
ecdt_ptr
->
data
.
address
;
boot_ec
->
gpe
=
ecdt_ptr
->
gpe
;
boot_ec
->
gpe
=
ecdt_ptr
->
gpe
;
...
@@ -1030,7 +1029,7 @@ int __init acpi_ec_ecdt_probe(void)
...
@@ -1030,7 +1029,7 @@ int __init acpi_ec_ecdt_probe(void)
/* This workaround is needed only on some broken machines,
/* This workaround is needed only on some broken machines,
* which require early EC, but fail to provide ECDT */
* which require early EC, but fail to provide ECDT */
pr
intk
(
KERN_DEBUG
PREFIX
"Look up EC in DSDT
\n
"
);
pr
_debug
(
"Look up EC in DSDT
\n
"
);
status
=
acpi_get_devices
(
ec_device_ids
[
0
].
id
,
ec_parse_device
,
status
=
acpi_get_devices
(
ec_device_ids
[
0
].
id
,
ec_parse_device
,
boot_ec
,
NULL
);
boot_ec
,
NULL
);
/* Check that acpi_get_devices actually find something */
/* Check that acpi_get_devices actually find something */
...
@@ -1042,7 +1041,7 @@ int __init acpi_ec_ecdt_probe(void)
...
@@ -1042,7 +1041,7 @@ int __init acpi_ec_ecdt_probe(void)
saved_ec
->
data_addr
!=
boot_ec
->
data_addr
||
saved_ec
->
data_addr
!=
boot_ec
->
data_addr
||
saved_ec
->
gpe
!=
boot_ec
->
gpe
||
saved_ec
->
gpe
!=
boot_ec
->
gpe
||
saved_ec
->
handle
!=
boot_ec
->
handle
)
saved_ec
->
handle
!=
boot_ec
->
handle
)
pr_info
(
PREFIX
"ASUSTek keeps feeding us with broken "
pr_info
(
"ASUSTek keeps feeding us with broken "
"ECDT tables, which are very hard to workaround. "
"ECDT tables, which are very hard to workaround. "
"Trying to use DSDT EC info instead. Please send "
"Trying to use DSDT EC info instead. Please send "
"output of acpidump to linux-acpi@vger.kernel.org
\n
"
);
"output of acpidump to linux-acpi@vger.kernel.org
\n
"
);
...
...
drivers/acpi/osl.c
浏览文件 @
17e8d03c
...
@@ -820,7 +820,7 @@ acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
...
@@ -820,7 +820,7 @@ acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
void
acpi_os_sleep
(
u64
ms
)
void
acpi_os_sleep
(
u64
ms
)
{
{
schedule_timeout_interruptible
(
msecs_to_jiffies
(
ms
)
);
msleep
(
ms
);
}
}
void
acpi_os_stall
(
u32
us
)
void
acpi_os_stall
(
u32
us
)
...
@@ -1335,7 +1335,7 @@ static int __init acpi_os_name_setup(char *str)
...
@@ -1335,7 +1335,7 @@ static int __init acpi_os_name_setup(char *str)
if
(
!
str
||
!*
str
)
if
(
!
str
||
!*
str
)
return
0
;
return
0
;
for
(;
count
--
&&
str
&&
*
str
;
str
++
)
{
for
(;
count
--
&&
*
str
;
str
++
)
{
if
(
isalnum
(
*
str
)
||
*
str
==
' '
||
*
str
==
':'
)
if
(
isalnum
(
*
str
)
||
*
str
==
' '
||
*
str
==
':'
)
*
p
++
=
*
str
;
*
p
++
=
*
str
;
else
if
(
*
str
==
'\''
||
*
str
==
'"'
)
else
if
(
*
str
==
'\''
||
*
str
==
'"'
)
...
...
drivers/acpi/sysfs.c
浏览文件 @
17e8d03c
...
@@ -564,6 +564,7 @@ static ssize_t counter_set(struct kobject *kobj,
...
@@ -564,6 +564,7 @@ static ssize_t counter_set(struct kobject *kobj,
acpi_event_status
status
;
acpi_event_status
status
;
acpi_handle
handle
;
acpi_handle
handle
;
int
result
=
0
;
int
result
=
0
;
unsigned
long
tmp
;
if
(
index
==
num_gpes
+
ACPI_NUM_FIXED_EVENTS
+
COUNT_SCI
)
{
if
(
index
==
num_gpes
+
ACPI_NUM_FIXED_EVENTS
+
COUNT_SCI
)
{
int
i
;
int
i
;
...
@@ -596,8 +597,10 @@ static ssize_t counter_set(struct kobject *kobj,
...
@@ -596,8 +597,10 @@ static ssize_t counter_set(struct kobject *kobj,
else
if
(
!
strcmp
(
buf
,
"clear
\n
"
)
&&
else
if
(
!
strcmp
(
buf
,
"clear
\n
"
)
&&
(
status
&
ACPI_EVENT_FLAG_SET
))
(
status
&
ACPI_EVENT_FLAG_SET
))
result
=
acpi_clear_gpe
(
handle
,
index
);
result
=
acpi_clear_gpe
(
handle
,
index
);
else
if
(
!
kstrtoul
(
buf
,
0
,
&
tmp
))
all_counters
[
index
].
count
=
tmp
;
else
else
all_counters
[
index
].
count
=
strtoul
(
buf
,
NULL
,
0
)
;
result
=
-
EINVAL
;
}
else
if
(
index
<
num_gpes
+
ACPI_NUM_FIXED_EVENTS
)
{
}
else
if
(
index
<
num_gpes
+
ACPI_NUM_FIXED_EVENTS
)
{
int
event
=
index
-
num_gpes
;
int
event
=
index
-
num_gpes
;
if
(
!
strcmp
(
buf
,
"disable
\n
"
)
&&
if
(
!
strcmp
(
buf
,
"disable
\n
"
)
&&
...
@@ -609,8 +612,10 @@ static ssize_t counter_set(struct kobject *kobj,
...
@@ -609,8 +612,10 @@ static ssize_t counter_set(struct kobject *kobj,
else
if
(
!
strcmp
(
buf
,
"clear
\n
"
)
&&
else
if
(
!
strcmp
(
buf
,
"clear
\n
"
)
&&
(
status
&
ACPI_EVENT_FLAG_SET
))
(
status
&
ACPI_EVENT_FLAG_SET
))
result
=
acpi_clear_event
(
event
);
result
=
acpi_clear_event
(
event
);
else
if
(
!
kstrtoul
(
buf
,
0
,
&
tmp
))
all_counters
[
index
].
count
=
tmp
;
else
else
all_counters
[
index
].
count
=
strtoul
(
buf
,
NULL
,
0
)
;
result
=
-
EINVAL
;
}
else
}
else
all_counters
[
index
].
count
=
strtoul
(
buf
,
NULL
,
0
);
all_counters
[
index
].
count
=
strtoul
(
buf
,
NULL
,
0
);
...
...
drivers/acpi/thermal.c
浏览文件 @
17e8d03c
...
@@ -299,8 +299,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
...
@@ -299,8 +299,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
ACPI_DEBUG_PRINT
((
ACPI_DB_INFO
,
"No critical threshold
\n
"
));
"No critical threshold
\n
"
));
}
else
if
(
tmp
<=
2732
)
{
}
else
if
(
tmp
<=
2732
)
{
pr
intk
(
KERN_WARNING
FW_BUG
"Invalid critical threshold "
pr
_warn
(
FW_BUG
"Invalid critical threshold (%llu)
\n
"
,
"(%llu)
\n
"
,
tmp
);
tmp
);
tz
->
trips
.
critical
.
flags
.
valid
=
0
;
tz
->
trips
.
critical
.
flags
.
valid
=
0
;
}
else
{
}
else
{
tz
->
trips
.
critical
.
flags
.
valid
=
1
;
tz
->
trips
.
critical
.
flags
.
valid
=
1
;
...
@@ -317,8 +317,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
...
@@ -317,8 +317,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
* Allow override critical threshold
* Allow override critical threshold
*/
*/
if
(
crt_k
>
tz
->
trips
.
critical
.
temperature
)
if
(
crt_k
>
tz
->
trips
.
critical
.
temperature
)
pr
intk
(
KERN_WARNING
PREFIX
pr
_warn
(
PREFIX
"Critical threshold %d C
\n
"
,
"Critical threshold %d C
\n
"
,
crt
);
crt
);
tz
->
trips
.
critical
.
temperature
=
crt_k
;
tz
->
trips
.
critical
.
temperature
=
crt_k
;
}
}
}
}
...
@@ -390,8 +390,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
...
@@ -390,8 +390,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
status
=
acpi_evaluate_reference
(
tz
->
device
->
handle
,
"_PSL"
,
status
=
acpi_evaluate_reference
(
tz
->
device
->
handle
,
"_PSL"
,
NULL
,
&
devices
);
NULL
,
&
devices
);
if
(
ACPI_FAILURE
(
status
))
{
if
(
ACPI_FAILURE
(
status
))
{
printk
(
KERN_WARNING
PREFIX
pr_warn
(
PREFIX
"Invalid passive threshold
\n
"
);
"Invalid passive threshold
\n
"
);
tz
->
trips
.
passive
.
flags
.
valid
=
0
;
tz
->
trips
.
passive
.
flags
.
valid
=
0
;
}
}
else
else
...
@@ -453,8 +452,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
...
@@ -453,8 +452,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
status
=
acpi_evaluate_reference
(
tz
->
device
->
handle
,
status
=
acpi_evaluate_reference
(
tz
->
device
->
handle
,
name
,
NULL
,
&
devices
);
name
,
NULL
,
&
devices
);
if
(
ACPI_FAILURE
(
status
))
{
if
(
ACPI_FAILURE
(
status
))
{
pr
intk
(
KERN_WARNING
PREFIX
pr
_warn
(
PREFIX
"Invalid active%d threshold
\n
"
,
"Invalid active%d threshold
\n
"
,
i
);
i
);
tz
->
trips
.
active
[
i
].
flags
.
valid
=
0
;
tz
->
trips
.
active
[
i
].
flags
.
valid
=
0
;
}
}
else
else
...
@@ -505,7 +504,7 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
...
@@ -505,7 +504,7 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
valid
|=
tz
->
trips
.
active
[
i
].
flags
.
valid
;
valid
|=
tz
->
trips
.
active
[
i
].
flags
.
valid
;
if
(
!
valid
)
{
if
(
!
valid
)
{
pr
intk
(
KERN_WARNING
FW_BUG
"No valid trip found
\n
"
);
pr
_warn
(
FW_BUG
"No valid trip found
\n
"
);
return
-
ENODEV
;
return
-
ENODEV
;
}
}
return
0
;
return
0
;
...
@@ -923,8 +922,7 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
...
@@ -923,8 +922,7 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
acpi_bus_private_data_handler
,
acpi_bus_private_data_handler
,
tz
->
thermal_zone
);
tz
->
thermal_zone
);
if
(
ACPI_FAILURE
(
status
))
{
if
(
ACPI_FAILURE
(
status
))
{
printk
(
KERN_ERR
PREFIX
pr_err
(
PREFIX
"Error attaching device data
\n
"
);
"Error attaching device data
\n
"
);
return
-
ENODEV
;
return
-
ENODEV
;
}
}
...
@@ -1094,9 +1092,8 @@ static int acpi_thermal_add(struct acpi_device *device)
...
@@ -1094,9 +1092,8 @@ static int acpi_thermal_add(struct acpi_device *device)
if
(
result
)
if
(
result
)
goto
free_memory
;
goto
free_memory
;
printk
(
KERN_INFO
PREFIX
"%s [%s] (%ld C)
\n
"
,
pr_info
(
PREFIX
"%s [%s] (%ld C)
\n
"
,
acpi_device_name
(
device
),
acpi_device_name
(
device
),
acpi_device_bid
(
device
),
acpi_device_bid
(
device
),
KELVIN_TO_CELSIUS
(
tz
->
temperature
));
KELVIN_TO_CELSIUS
(
tz
->
temperature
));
goto
end
;
goto
end
;
free_memory:
free_memory:
...
@@ -1159,7 +1156,7 @@ static int acpi_thermal_resume(struct device *dev)
...
@@ -1159,7 +1156,7 @@ static int acpi_thermal_resume(struct device *dev)
static
int
thermal_act
(
const
struct
dmi_system_id
*
d
)
{
static
int
thermal_act
(
const
struct
dmi_system_id
*
d
)
{
if
(
act
==
0
)
{
if
(
act
==
0
)
{
pr
intk
(
KERN_NOTICE
"ACPI:
%s detected: "
pr
_notice
(
PREFIX
"
%s detected: "
"disabling all active thermal trip points
\n
"
,
d
->
ident
);
"disabling all active thermal trip points
\n
"
,
d
->
ident
);
act
=
-
1
;
act
=
-
1
;
}
}
...
@@ -1167,7 +1164,7 @@ static int thermal_act(const struct dmi_system_id *d) {
...
@@ -1167,7 +1164,7 @@ static int thermal_act(const struct dmi_system_id *d) {
}
}
static
int
thermal_nocrt
(
const
struct
dmi_system_id
*
d
)
{
static
int
thermal_nocrt
(
const
struct
dmi_system_id
*
d
)
{
pr
intk
(
KERN_NOTICE
"ACPI:
%s detected: "
pr
_notice
(
PREFIX
"
%s detected: "
"disabling all critical thermal trip point actions.
\n
"
,
d
->
ident
);
"disabling all critical thermal trip point actions.
\n
"
,
d
->
ident
);
nocrt
=
1
;
nocrt
=
1
;
return
0
;
return
0
;
...
@@ -1175,7 +1172,7 @@ static int thermal_nocrt(const struct dmi_system_id *d) {
...
@@ -1175,7 +1172,7 @@ static int thermal_nocrt(const struct dmi_system_id *d) {
static
int
thermal_tzp
(
const
struct
dmi_system_id
*
d
)
{
static
int
thermal_tzp
(
const
struct
dmi_system_id
*
d
)
{
if
(
tzp
==
0
)
{
if
(
tzp
==
0
)
{
pr
intk
(
KERN_NOTICE
"ACPI:
%s detected: "
pr
_notice
(
PREFIX
"
%s detected: "
"enabling thermal zone polling
\n
"
,
d
->
ident
);
"enabling thermal zone polling
\n
"
,
d
->
ident
);
tzp
=
300
;
/* 300 dS = 30 Seconds */
tzp
=
300
;
/* 300 dS = 30 Seconds */
}
}
...
@@ -1184,7 +1181,7 @@ static int thermal_tzp(const struct dmi_system_id *d) {
...
@@ -1184,7 +1181,7 @@ static int thermal_tzp(const struct dmi_system_id *d) {
static
int
thermal_psv
(
const
struct
dmi_system_id
*
d
)
{
static
int
thermal_psv
(
const
struct
dmi_system_id
*
d
)
{
if
(
psv
==
0
)
{
if
(
psv
==
0
)
{
pr
intk
(
KERN_NOTICE
"ACPI:
%s detected: "
pr
_notice
(
PREFIX
"
%s detected: "
"disabling all passive thermal trip points
\n
"
,
d
->
ident
);
"disabling all passive thermal trip points
\n
"
,
d
->
ident
);
psv
=
-
1
;
psv
=
-
1
;
}
}
...
@@ -1238,7 +1235,7 @@ static int __init acpi_thermal_init(void)
...
@@ -1238,7 +1235,7 @@ static int __init acpi_thermal_init(void)
dmi_check_system
(
thermal_dmi_table
);
dmi_check_system
(
thermal_dmi_table
);
if
(
off
)
{
if
(
off
)
{
pr
intk
(
KERN_NOTICE
"ACPI:
thermal control disabled
\n
"
);
pr
_notice
(
PREFIX
"
thermal control disabled
\n
"
);
return
-
ENODEV
;
return
-
ENODEV
;
}
}
...
...
drivers/acpi/utils.c
浏览文件 @
17e8d03c
...
@@ -169,12 +169,21 @@ acpi_extract_package(union acpi_object *package,
...
@@ -169,12 +169,21 @@ acpi_extract_package(union acpi_object *package,
/*
/*
* Validate output buffer.
* Validate output buffer.
*/
*/
if
(
buffer
->
length
==
ACPI_ALLOCATE_BUFFER
)
{
buffer
->
pointer
=
ACPI_ALLOCATE
(
size_required
);
if
(
!
buffer
->
pointer
)
return
AE_NO_MEMORY
;
buffer
->
length
=
size_required
;
memset
(
buffer
->
pointer
,
0
,
size_required
);
}
else
{
if
(
buffer
->
length
<
size_required
)
{
if
(
buffer
->
length
<
size_required
)
{
buffer
->
length
=
size_required
;
buffer
->
length
=
size_required
;
return
AE_BUFFER_OVERFLOW
;
return
AE_BUFFER_OVERFLOW
;
}
else
if
(
buffer
->
length
!=
size_required
||
!
buffer
->
pointer
)
{
}
else
if
(
buffer
->
length
!=
size_required
||
!
buffer
->
pointer
)
{
return
AE_BAD_PARAMETER
;
return
AE_BAD_PARAMETER
;
}
}
}
head
=
buffer
->
pointer
;
head
=
buffer
->
pointer
;
tail
=
buffer
->
pointer
+
tail_offset
;
tail
=
buffer
->
pointer
+
tail_offset
;
...
...
drivers/platform/x86/ideapad-laptop.c
浏览文件 @
17e8d03c
...
@@ -72,8 +72,15 @@ enum {
...
@@ -72,8 +72,15 @@ enum {
VPCCMD_W_BL_POWER
=
0x33
,
VPCCMD_W_BL_POWER
=
0x33
,
};
};
struct
ideapad_rfk_priv
{
int
dev
;
struct
ideapad_private
*
priv
;
};
struct
ideapad_private
{
struct
ideapad_private
{
struct
acpi_device
*
adev
;
struct
rfkill
*
rfk
[
IDEAPAD_RFKILL_DEV_NUM
];
struct
rfkill
*
rfk
[
IDEAPAD_RFKILL_DEV_NUM
];
struct
ideapad_rfk_priv
rfk_priv
[
IDEAPAD_RFKILL_DEV_NUM
];
struct
platform_device
*
platform_device
;
struct
platform_device
*
platform_device
;
struct
input_dev
*
inputdev
;
struct
input_dev
*
inputdev
;
struct
backlight_device
*
blightdev
;
struct
backlight_device
*
blightdev
;
...
@@ -81,8 +88,6 @@ struct ideapad_private {
...
@@ -81,8 +88,6 @@ struct ideapad_private {
unsigned
long
cfg
;
unsigned
long
cfg
;
};
};
static
acpi_handle
ideapad_handle
;
static
struct
ideapad_private
*
ideapad_priv
;
static
bool
no_bt_rfkill
;
static
bool
no_bt_rfkill
;
module_param
(
no_bt_rfkill
,
bool
,
0444
);
module_param
(
no_bt_rfkill
,
bool
,
0444
);
MODULE_PARM_DESC
(
no_bt_rfkill
,
"No rfkill for bluetooth."
);
MODULE_PARM_DESC
(
no_bt_rfkill
,
"No rfkill for bluetooth."
);
...
@@ -200,34 +205,38 @@ static int write_ec_cmd(acpi_handle handle, int cmd, unsigned long data)
...
@@ -200,34 +205,38 @@ static int write_ec_cmd(acpi_handle handle, int cmd, unsigned long data)
*/
*/
static
int
debugfs_status_show
(
struct
seq_file
*
s
,
void
*
data
)
static
int
debugfs_status_show
(
struct
seq_file
*
s
,
void
*
data
)
{
{
struct
ideapad_private
*
priv
=
s
->
private
;
unsigned
long
value
;
unsigned
long
value
;
if
(
!
read_ec_data
(
ideapad_handle
,
VPCCMD_R_BL_MAX
,
&
value
))
if
(
!
priv
)
return
-
EINVAL
;
if
(
!
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_BL_MAX
,
&
value
))
seq_printf
(
s
,
"Backlight max:
\t
%lu
\n
"
,
value
);
seq_printf
(
s
,
"Backlight max:
\t
%lu
\n
"
,
value
);
if
(
!
read_ec_data
(
ideapad_
handle
,
VPCCMD_R_BL
,
&
value
))
if
(
!
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_BL
,
&
value
))
seq_printf
(
s
,
"Backlight now:
\t
%lu
\n
"
,
value
);
seq_printf
(
s
,
"Backlight now:
\t
%lu
\n
"
,
value
);
if
(
!
read_ec_data
(
ideapad_
handle
,
VPCCMD_R_BL_POWER
,
&
value
))
if
(
!
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_BL_POWER
,
&
value
))
seq_printf
(
s
,
"BL power value:
\t
%s
\n
"
,
value
?
"On"
:
"Off"
);
seq_printf
(
s
,
"BL power value:
\t
%s
\n
"
,
value
?
"On"
:
"Off"
);
seq_printf
(
s
,
"=====================
\n
"
);
seq_printf
(
s
,
"=====================
\n
"
);
if
(
!
read_ec_data
(
ideapad_
handle
,
VPCCMD_R_RF
,
&
value
))
if
(
!
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_RF
,
&
value
))
seq_printf
(
s
,
"Radio status:
\t
%s(%lu)
\n
"
,
seq_printf
(
s
,
"Radio status:
\t
%s(%lu)
\n
"
,
value
?
"On"
:
"Off"
,
value
);
value
?
"On"
:
"Off"
,
value
);
if
(
!
read_ec_data
(
ideapad_
handle
,
VPCCMD_R_WIFI
,
&
value
))
if
(
!
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_WIFI
,
&
value
))
seq_printf
(
s
,
"Wifi status:
\t
%s(%lu)
\n
"
,
seq_printf
(
s
,
"Wifi status:
\t
%s(%lu)
\n
"
,
value
?
"On"
:
"Off"
,
value
);
value
?
"On"
:
"Off"
,
value
);
if
(
!
read_ec_data
(
ideapad_
handle
,
VPCCMD_R_BT
,
&
value
))
if
(
!
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_BT
,
&
value
))
seq_printf
(
s
,
"BT status:
\t
%s(%lu)
\n
"
,
seq_printf
(
s
,
"BT status:
\t
%s(%lu)
\n
"
,
value
?
"On"
:
"Off"
,
value
);
value
?
"On"
:
"Off"
,
value
);
if
(
!
read_ec_data
(
ideapad_
handle
,
VPCCMD_R_3G
,
&
value
))
if
(
!
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_3G
,
&
value
))
seq_printf
(
s
,
"3G status:
\t
%s(%lu)
\n
"
,
seq_printf
(
s
,
"3G status:
\t
%s(%lu)
\n
"
,
value
?
"On"
:
"Off"
,
value
);
value
?
"On"
:
"Off"
,
value
);
seq_printf
(
s
,
"=====================
\n
"
);
seq_printf
(
s
,
"=====================
\n
"
);
if
(
!
read_ec_data
(
ideapad_
handle
,
VPCCMD_R_TOUCHPAD
,
&
value
))
if
(
!
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_TOUCHPAD
,
&
value
))
seq_printf
(
s
,
"Touchpad status:%s(%lu)
\n
"
,
seq_printf
(
s
,
"Touchpad status:%s(%lu)
\n
"
,
value
?
"On"
:
"Off"
,
value
);
value
?
"On"
:
"Off"
,
value
);
if
(
!
read_ec_data
(
ideapad_
handle
,
VPCCMD_R_CAMERA
,
&
value
))
if
(
!
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_CAMERA
,
&
value
))
seq_printf
(
s
,
"Camera status:
\t
%s(%lu)
\n
"
,
seq_printf
(
s
,
"Camera status:
\t
%s(%lu)
\n
"
,
value
?
"On"
:
"Off"
,
value
);
value
?
"On"
:
"Off"
,
value
);
...
@@ -236,7 +245,7 @@ static int debugfs_status_show(struct seq_file *s, void *data)
...
@@ -236,7 +245,7 @@ static int debugfs_status_show(struct seq_file *s, void *data)
static
int
debugfs_status_open
(
struct
inode
*
inode
,
struct
file
*
file
)
static
int
debugfs_status_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
{
return
single_open
(
file
,
debugfs_status_show
,
NULL
);
return
single_open
(
file
,
debugfs_status_show
,
inode
->
i_private
);
}
}
static
const
struct
file_operations
debugfs_status_fops
=
{
static
const
struct
file_operations
debugfs_status_fops
=
{
...
@@ -249,21 +258,23 @@ static const struct file_operations debugfs_status_fops = {
...
@@ -249,21 +258,23 @@ static const struct file_operations debugfs_status_fops = {
static
int
debugfs_cfg_show
(
struct
seq_file
*
s
,
void
*
data
)
static
int
debugfs_cfg_show
(
struct
seq_file
*
s
,
void
*
data
)
{
{
if
(
!
ideapad_priv
)
{
struct
ideapad_private
*
priv
=
s
->
private
;
if
(
!
priv
)
{
seq_printf
(
s
,
"cfg: N/A
\n
"
);
seq_printf
(
s
,
"cfg: N/A
\n
"
);
}
else
{
}
else
{
seq_printf
(
s
,
"cfg: 0x%.8lX
\n\n
Capability: "
,
seq_printf
(
s
,
"cfg: 0x%.8lX
\n\n
Capability: "
,
ideapad_
priv
->
cfg
);
priv
->
cfg
);
if
(
test_bit
(
CFG_BT_BIT
,
&
ideapad_
priv
->
cfg
))
if
(
test_bit
(
CFG_BT_BIT
,
&
priv
->
cfg
))
seq_printf
(
s
,
"Bluetooth "
);
seq_printf
(
s
,
"Bluetooth "
);
if
(
test_bit
(
CFG_3G_BIT
,
&
ideapad_
priv
->
cfg
))
if
(
test_bit
(
CFG_3G_BIT
,
&
priv
->
cfg
))
seq_printf
(
s
,
"3G "
);
seq_printf
(
s
,
"3G "
);
if
(
test_bit
(
CFG_WIFI_BIT
,
&
ideapad_
priv
->
cfg
))
if
(
test_bit
(
CFG_WIFI_BIT
,
&
priv
->
cfg
))
seq_printf
(
s
,
"Wireless "
);
seq_printf
(
s
,
"Wireless "
);
if
(
test_bit
(
CFG_CAMERA_BIT
,
&
ideapad_
priv
->
cfg
))
if
(
test_bit
(
CFG_CAMERA_BIT
,
&
priv
->
cfg
))
seq_printf
(
s
,
"Camera "
);
seq_printf
(
s
,
"Camera "
);
seq_printf
(
s
,
"
\n
Graphic: "
);
seq_printf
(
s
,
"
\n
Graphic: "
);
switch
((
ideapad_
priv
->
cfg
)
&
0x700
)
{
switch
((
priv
->
cfg
)
&
0x700
)
{
case
0x100
:
case
0x100
:
seq_printf
(
s
,
"Intel"
);
seq_printf
(
s
,
"Intel"
);
break
;
break
;
...
@@ -287,7 +298,7 @@ static int debugfs_cfg_show(struct seq_file *s, void *data)
...
@@ -287,7 +298,7 @@ static int debugfs_cfg_show(struct seq_file *s, void *data)
static
int
debugfs_cfg_open
(
struct
inode
*
inode
,
struct
file
*
file
)
static
int
debugfs_cfg_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
{
return
single_open
(
file
,
debugfs_cfg_show
,
NULL
);
return
single_open
(
file
,
debugfs_cfg_show
,
inode
->
i_private
);
}
}
static
const
struct
file_operations
debugfs_cfg_fops
=
{
static
const
struct
file_operations
debugfs_cfg_fops
=
{
...
@@ -308,14 +319,14 @@ static int ideapad_debugfs_init(struct ideapad_private *priv)
...
@@ -308,14 +319,14 @@ static int ideapad_debugfs_init(struct ideapad_private *priv)
goto
errout
;
goto
errout
;
}
}
node
=
debugfs_create_file
(
"cfg"
,
S_IRUGO
,
priv
->
debug
,
NULL
,
node
=
debugfs_create_file
(
"cfg"
,
S_IRUGO
,
priv
->
debug
,
priv
,
&
debugfs_cfg_fops
);
&
debugfs_cfg_fops
);
if
(
!
node
)
{
if
(
!
node
)
{
pr_err
(
"failed to create cfg in debugfs"
);
pr_err
(
"failed to create cfg in debugfs"
);
goto
errout
;
goto
errout
;
}
}
node
=
debugfs_create_file
(
"status"
,
S_IRUGO
,
priv
->
debug
,
NULL
,
node
=
debugfs_create_file
(
"status"
,
S_IRUGO
,
priv
->
debug
,
priv
,
&
debugfs_status_fops
);
&
debugfs_status_fops
);
if
(
!
node
)
{
if
(
!
node
)
{
pr_err
(
"failed to create status in debugfs"
);
pr_err
(
"failed to create status in debugfs"
);
...
@@ -342,8 +353,9 @@ static ssize_t show_ideapad_cam(struct device *dev,
...
@@ -342,8 +353,9 @@ static ssize_t show_ideapad_cam(struct device *dev,
char
*
buf
)
char
*
buf
)
{
{
unsigned
long
result
;
unsigned
long
result
;
struct
ideapad_private
*
priv
=
dev_get_drvdata
(
dev
);
if
(
read_ec_data
(
ideapad_
handle
,
VPCCMD_R_CAMERA
,
&
result
))
if
(
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_CAMERA
,
&
result
))
return
sprintf
(
buf
,
"-1
\n
"
);
return
sprintf
(
buf
,
"-1
\n
"
);
return
sprintf
(
buf
,
"%lu
\n
"
,
result
);
return
sprintf
(
buf
,
"%lu
\n
"
,
result
);
}
}
...
@@ -353,12 +365,13 @@ static ssize_t store_ideapad_cam(struct device *dev,
...
@@ -353,12 +365,13 @@ static ssize_t store_ideapad_cam(struct device *dev,
const
char
*
buf
,
size_t
count
)
const
char
*
buf
,
size_t
count
)
{
{
int
ret
,
state
;
int
ret
,
state
;
struct
ideapad_private
*
priv
=
dev_get_drvdata
(
dev
);
if
(
!
count
)
if
(
!
count
)
return
0
;
return
0
;
if
(
sscanf
(
buf
,
"%i"
,
&
state
)
!=
1
)
if
(
sscanf
(
buf
,
"%i"
,
&
state
)
!=
1
)
return
-
EINVAL
;
return
-
EINVAL
;
ret
=
write_ec_cmd
(
ideapad_
handle
,
VPCCMD_W_CAMERA
,
state
);
ret
=
write_ec_cmd
(
priv
->
adev
->
handle
,
VPCCMD_W_CAMERA
,
state
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
-
EIO
;
return
-
EIO
;
return
count
;
return
count
;
...
@@ -371,8 +384,9 @@ static ssize_t show_ideapad_fan(struct device *dev,
...
@@ -371,8 +384,9 @@ static ssize_t show_ideapad_fan(struct device *dev,
char
*
buf
)
char
*
buf
)
{
{
unsigned
long
result
;
unsigned
long
result
;
struct
ideapad_private
*
priv
=
dev_get_drvdata
(
dev
);
if
(
read_ec_data
(
ideapad_
handle
,
VPCCMD_R_FAN
,
&
result
))
if
(
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_FAN
,
&
result
))
return
sprintf
(
buf
,
"-1
\n
"
);
return
sprintf
(
buf
,
"-1
\n
"
);
return
sprintf
(
buf
,
"%lu
\n
"
,
result
);
return
sprintf
(
buf
,
"%lu
\n
"
,
result
);
}
}
...
@@ -382,6 +396,7 @@ static ssize_t store_ideapad_fan(struct device *dev,
...
@@ -382,6 +396,7 @@ static ssize_t store_ideapad_fan(struct device *dev,
const
char
*
buf
,
size_t
count
)
const
char
*
buf
,
size_t
count
)
{
{
int
ret
,
state
;
int
ret
,
state
;
struct
ideapad_private
*
priv
=
dev_get_drvdata
(
dev
);
if
(
!
count
)
if
(
!
count
)
return
0
;
return
0
;
...
@@ -389,7 +404,7 @@ static ssize_t store_ideapad_fan(struct device *dev,
...
@@ -389,7 +404,7 @@ static ssize_t store_ideapad_fan(struct device *dev,
return
-
EINVAL
;
return
-
EINVAL
;
if
(
state
<
0
||
state
>
4
||
state
==
3
)
if
(
state
<
0
||
state
>
4
||
state
==
3
)
return
-
EINVAL
;
return
-
EINVAL
;
ret
=
write_ec_cmd
(
ideapad_
handle
,
VPCCMD_W_FAN
,
state
);
ret
=
write_ec_cmd
(
priv
->
adev
->
handle
,
VPCCMD_W_FAN
,
state
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
-
EIO
;
return
-
EIO
;
return
count
;
return
count
;
...
@@ -415,7 +430,8 @@ static umode_t ideapad_is_visible(struct kobject *kobj,
...
@@ -415,7 +430,8 @@ static umode_t ideapad_is_visible(struct kobject *kobj,
supported
=
test_bit
(
CFG_CAMERA_BIT
,
&
(
priv
->
cfg
));
supported
=
test_bit
(
CFG_CAMERA_BIT
,
&
(
priv
->
cfg
));
else
if
(
attr
==
&
dev_attr_fan_mode
.
attr
)
{
else
if
(
attr
==
&
dev_attr_fan_mode
.
attr
)
{
unsigned
long
value
;
unsigned
long
value
;
supported
=
!
read_ec_data
(
ideapad_handle
,
VPCCMD_R_FAN
,
&
value
);
supported
=
!
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_FAN
,
&
value
);
}
else
}
else
supported
=
true
;
supported
=
true
;
...
@@ -445,9 +461,9 @@ const struct ideapad_rfk_data ideapad_rfk_data[] = {
...
@@ -445,9 +461,9 @@ const struct ideapad_rfk_data ideapad_rfk_data[] = {
static
int
ideapad_rfk_set
(
void
*
data
,
bool
blocked
)
static
int
ideapad_rfk_set
(
void
*
data
,
bool
blocked
)
{
{
unsigned
long
opcode
=
(
unsigned
long
)
data
;
struct
ideapad_rfk_priv
*
priv
=
data
;
return
write_ec_cmd
(
ideapad_handle
,
opcode
,
!
blocked
);
return
write_ec_cmd
(
priv
->
priv
->
adev
->
handle
,
priv
->
dev
,
!
blocked
);
}
}
static
struct
rfkill_ops
ideapad_rfk_ops
=
{
static
struct
rfkill_ops
ideapad_rfk_ops
=
{
...
@@ -459,7 +475,7 @@ static void ideapad_sync_rfk_state(struct ideapad_private *priv)
...
@@ -459,7 +475,7 @@ static void ideapad_sync_rfk_state(struct ideapad_private *priv)
unsigned
long
hw_blocked
;
unsigned
long
hw_blocked
;
int
i
;
int
i
;
if
(
read_ec_data
(
ideapad_
handle
,
VPCCMD_R_RF
,
&
hw_blocked
))
if
(
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_RF
,
&
hw_blocked
))
return
;
return
;
hw_blocked
=
!
hw_blocked
;
hw_blocked
=
!
hw_blocked
;
...
@@ -468,27 +484,30 @@ static void ideapad_sync_rfk_state(struct ideapad_private *priv)
...
@@ -468,27 +484,30 @@ static void ideapad_sync_rfk_state(struct ideapad_private *priv)
rfkill_set_hw_state
(
priv
->
rfk
[
i
],
hw_blocked
);
rfkill_set_hw_state
(
priv
->
rfk
[
i
],
hw_blocked
);
}
}
static
int
ideapad_register_rfkill
(
struct
acpi_device
*
adevice
,
int
dev
)
static
int
ideapad_register_rfkill
(
struct
ideapad_private
*
priv
,
int
dev
)
{
{
struct
ideapad_private
*
priv
=
dev_get_drvdata
(
&
adevice
->
dev
);
int
ret
;
int
ret
;
unsigned
long
sw_blocked
;
unsigned
long
sw_blocked
;
if
(
no_bt_rfkill
&&
if
(
no_bt_rfkill
&&
(
ideapad_rfk_data
[
dev
].
type
==
RFKILL_TYPE_BLUETOOTH
))
{
(
ideapad_rfk_data
[
dev
].
type
==
RFKILL_TYPE_BLUETOOTH
))
{
/* Force to enable bluetooth when no_bt_rfkill=1 */
/* Force to enable bluetooth when no_bt_rfkill=1 */
write_ec_cmd
(
ideapad_
handle
,
write_ec_cmd
(
priv
->
adev
->
handle
,
ideapad_rfk_data
[
dev
].
opcode
,
1
);
ideapad_rfk_data
[
dev
].
opcode
,
1
);
return
0
;
return
0
;
}
}
priv
->
rfk_priv
[
dev
].
dev
=
dev
;
priv
->
rfk_priv
[
dev
].
priv
=
priv
;
priv
->
rfk
[
dev
]
=
rfkill_alloc
(
ideapad_rfk_data
[
dev
].
name
,
&
adevice
->
dev
,
priv
->
rfk
[
dev
]
=
rfkill_alloc
(
ideapad_rfk_data
[
dev
].
name
,
ideapad_rfk_data
[
dev
].
type
,
&
ideapad_rfk_ops
,
&
priv
->
platform_device
->
dev
,
(
void
*
)(
long
)
dev
);
ideapad_rfk_data
[
dev
].
type
,
&
ideapad_rfk_ops
,
&
priv
->
rfk_priv
[
dev
]);
if
(
!
priv
->
rfk
[
dev
])
if
(
!
priv
->
rfk
[
dev
])
return
-
ENOMEM
;
return
-
ENOMEM
;
if
(
read_ec_data
(
ideapad_
handle
,
ideapad_rfk_data
[
dev
].
opcode
-
1
,
if
(
read_ec_data
(
priv
->
adev
->
handle
,
ideapad_rfk_data
[
dev
].
opcode
-
1
,
&
sw_blocked
))
{
&
sw_blocked
))
{
rfkill_init_sw_state
(
priv
->
rfk
[
dev
],
0
);
rfkill_init_sw_state
(
priv
->
rfk
[
dev
],
0
);
}
else
{
}
else
{
...
@@ -504,10 +523,8 @@ static int ideapad_register_rfkill(struct acpi_device *adevice, int dev)
...
@@ -504,10 +523,8 @@ static int ideapad_register_rfkill(struct acpi_device *adevice, int dev)
return
0
;
return
0
;
}
}
static
void
ideapad_unregister_rfkill
(
struct
acpi_device
*
adevice
,
int
dev
)
static
void
ideapad_unregister_rfkill
(
struct
ideapad_private
*
priv
,
int
dev
)
{
{
struct
ideapad_private
*
priv
=
dev_get_drvdata
(
&
adevice
->
dev
);
if
(
!
priv
->
rfk
[
dev
])
if
(
!
priv
->
rfk
[
dev
])
return
;
return
;
...
@@ -518,37 +535,16 @@ static void ideapad_unregister_rfkill(struct acpi_device *adevice, int dev)
...
@@ -518,37 +535,16 @@ static void ideapad_unregister_rfkill(struct acpi_device *adevice, int dev)
/*
/*
* Platform device
* Platform device
*/
*/
static
int
ideapad_
platform
_init
(
struct
ideapad_private
*
priv
)
static
int
ideapad_
sysfs
_init
(
struct
ideapad_private
*
priv
)
{
{
int
result
;
return
sysfs_create_group
(
&
priv
->
platform_device
->
dev
.
kobj
,
priv
->
platform_device
=
platform_device_alloc
(
"ideapad"
,
-
1
);
if
(
!
priv
->
platform_device
)
return
-
ENOMEM
;
platform_set_drvdata
(
priv
->
platform_device
,
priv
);
result
=
platform_device_add
(
priv
->
platform_device
);
if
(
result
)
goto
fail_platform_device
;
result
=
sysfs_create_group
(
&
priv
->
platform_device
->
dev
.
kobj
,
&
ideapad_attribute_group
);
&
ideapad_attribute_group
);
if
(
result
)
goto
fail_sysfs
;
return
0
;
fail_sysfs:
platform_device_del
(
priv
->
platform_device
);
fail_platform_device:
platform_device_put
(
priv
->
platform_device
);
return
result
;
}
}
static
void
ideapad_
platform
_exit
(
struct
ideapad_private
*
priv
)
static
void
ideapad_
sysfs
_exit
(
struct
ideapad_private
*
priv
)
{
{
sysfs_remove_group
(
&
priv
->
platform_device
->
dev
.
kobj
,
sysfs_remove_group
(
&
priv
->
platform_device
->
dev
.
kobj
,
&
ideapad_attribute_group
);
&
ideapad_attribute_group
);
platform_device_unregister
(
priv
->
platform_device
);
}
}
/*
/*
...
@@ -623,7 +619,7 @@ static void ideapad_input_novokey(struct ideapad_private *priv)
...
@@ -623,7 +619,7 @@ static void ideapad_input_novokey(struct ideapad_private *priv)
{
{
unsigned
long
long_pressed
;
unsigned
long
long_pressed
;
if
(
read_ec_data
(
ideapad_
handle
,
VPCCMD_R_NOVO
,
&
long_pressed
))
if
(
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_NOVO
,
&
long_pressed
))
return
;
return
;
if
(
long_pressed
)
if
(
long_pressed
)
ideapad_input_report
(
priv
,
17
);
ideapad_input_report
(
priv
,
17
);
...
@@ -635,7 +631,7 @@ static void ideapad_check_special_buttons(struct ideapad_private *priv)
...
@@ -635,7 +631,7 @@ static void ideapad_check_special_buttons(struct ideapad_private *priv)
{
{
unsigned
long
bit
,
value
;
unsigned
long
bit
,
value
;
read_ec_data
(
ideapad_
handle
,
VPCCMD_R_SPECIAL_BUTTONS
,
&
value
);
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_SPECIAL_BUTTONS
,
&
value
);
for
(
bit
=
0
;
bit
<
16
;
bit
++
)
{
for
(
bit
=
0
;
bit
<
16
;
bit
++
)
{
if
(
test_bit
(
bit
,
&
value
))
{
if
(
test_bit
(
bit
,
&
value
))
{
...
@@ -662,19 +658,28 @@ static void ideapad_check_special_buttons(struct ideapad_private *priv)
...
@@ -662,19 +658,28 @@ static void ideapad_check_special_buttons(struct ideapad_private *priv)
*/
*/
static
int
ideapad_backlight_get_brightness
(
struct
backlight_device
*
blightdev
)
static
int
ideapad_backlight_get_brightness
(
struct
backlight_device
*
blightdev
)
{
{
struct
ideapad_private
*
priv
=
bl_get_data
(
blightdev
);
unsigned
long
now
;
unsigned
long
now
;
if
(
read_ec_data
(
ideapad_handle
,
VPCCMD_R_BL
,
&
now
))
if
(
!
priv
)
return
-
EINVAL
;
if
(
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_BL
,
&
now
))
return
-
EIO
;
return
-
EIO
;
return
now
;
return
now
;
}
}
static
int
ideapad_backlight_update_status
(
struct
backlight_device
*
blightdev
)
static
int
ideapad_backlight_update_status
(
struct
backlight_device
*
blightdev
)
{
{
if
(
write_ec_cmd
(
ideapad_handle
,
VPCCMD_W_BL
,
struct
ideapad_private
*
priv
=
bl_get_data
(
blightdev
);
if
(
!
priv
)
return
-
EINVAL
;
if
(
write_ec_cmd
(
priv
->
adev
->
handle
,
VPCCMD_W_BL
,
blightdev
->
props
.
brightness
))
blightdev
->
props
.
brightness
))
return
-
EIO
;
return
-
EIO
;
if
(
write_ec_cmd
(
ideapad_
handle
,
VPCCMD_W_BL_POWER
,
if
(
write_ec_cmd
(
priv
->
adev
->
handle
,
VPCCMD_W_BL_POWER
,
blightdev
->
props
.
power
==
FB_BLANK_POWERDOWN
?
0
:
1
))
blightdev
->
props
.
power
==
FB_BLANK_POWERDOWN
?
0
:
1
))
return
-
EIO
;
return
-
EIO
;
...
@@ -692,11 +697,11 @@ static int ideapad_backlight_init(struct ideapad_private *priv)
...
@@ -692,11 +697,11 @@ static int ideapad_backlight_init(struct ideapad_private *priv)
struct
backlight_properties
props
;
struct
backlight_properties
props
;
unsigned
long
max
,
now
,
power
;
unsigned
long
max
,
now
,
power
;
if
(
read_ec_data
(
ideapad_
handle
,
VPCCMD_R_BL_MAX
,
&
max
))
if
(
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_BL_MAX
,
&
max
))
return
-
EIO
;
return
-
EIO
;
if
(
read_ec_data
(
ideapad_
handle
,
VPCCMD_R_BL
,
&
now
))
if
(
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_BL
,
&
now
))
return
-
EIO
;
return
-
EIO
;
if
(
read_ec_data
(
ideapad_
handle
,
VPCCMD_R_BL_POWER
,
&
power
))
if
(
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_BL_POWER
,
&
power
))
return
-
EIO
;
return
-
EIO
;
memset
(
&
props
,
0
,
sizeof
(
struct
backlight_properties
));
memset
(
&
props
,
0
,
sizeof
(
struct
backlight_properties
));
...
@@ -734,7 +739,7 @@ static void ideapad_backlight_notify_power(struct ideapad_private *priv)
...
@@ -734,7 +739,7 @@ static void ideapad_backlight_notify_power(struct ideapad_private *priv)
if
(
!
blightdev
)
if
(
!
blightdev
)
return
;
return
;
if
(
read_ec_data
(
ideapad_
handle
,
VPCCMD_R_BL_POWER
,
&
power
))
if
(
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_BL_POWER
,
&
power
))
return
;
return
;
blightdev
->
props
.
power
=
power
?
FB_BLANK_UNBLANK
:
FB_BLANK_POWERDOWN
;
blightdev
->
props
.
power
=
power
?
FB_BLANK_UNBLANK
:
FB_BLANK_POWERDOWN
;
}
}
...
@@ -745,7 +750,7 @@ static void ideapad_backlight_notify_brightness(struct ideapad_private *priv)
...
@@ -745,7 +750,7 @@ static void ideapad_backlight_notify_brightness(struct ideapad_private *priv)
/* if we control brightness via acpi video driver */
/* if we control brightness via acpi video driver */
if
(
priv
->
blightdev
==
NULL
)
{
if
(
priv
->
blightdev
==
NULL
)
{
read_ec_data
(
ideapad_
handle
,
VPCCMD_R_BL
,
&
now
);
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_BL
,
&
now
);
return
;
return
;
}
}
...
@@ -755,19 +760,12 @@ static void ideapad_backlight_notify_brightness(struct ideapad_private *priv)
...
@@ -755,19 +760,12 @@ static void ideapad_backlight_notify_brightness(struct ideapad_private *priv)
/*
/*
* module init/exit
* module init/exit
*/
*/
static
const
struct
acpi_device_id
ideapad_device_ids
[]
=
{
static
void
ideapad_sync_touchpad_state
(
struct
ideapad_private
*
priv
)
{
"VPC2004"
,
0
},
{
""
,
0
},
};
MODULE_DEVICE_TABLE
(
acpi
,
ideapad_device_ids
);
static
void
ideapad_sync_touchpad_state
(
struct
acpi_device
*
adevice
)
{
{
struct
ideapad_private
*
priv
=
dev_get_drvdata
(
&
adevice
->
dev
);
unsigned
long
value
;
unsigned
long
value
;
/* Without reading from EC touchpad LED doesn't switch state */
/* Without reading from EC touchpad LED doesn't switch state */
if
(
!
read_ec_data
(
adevice
->
handle
,
VPCCMD_R_TOUCHPAD
,
&
value
))
{
if
(
!
read_ec_data
(
priv
->
adev
->
handle
,
VPCCMD_R_TOUCHPAD
,
&
value
))
{
/* Some IdeaPads don't really turn off touchpad - they only
/* Some IdeaPads don't really turn off touchpad - they only
* switch the LED state. We (de)activate KBC AUX port to turn
* switch the LED state. We (de)activate KBC AUX port to turn
* touchpad off and on. We send KEY_TOUCHPAD_OFF and
* touchpad off and on. We send KEY_TOUCHPAD_OFF and
...
@@ -779,26 +777,77 @@ static void ideapad_sync_touchpad_state(struct acpi_device *adevice)
...
@@ -779,26 +777,77 @@ static void ideapad_sync_touchpad_state(struct acpi_device *adevice)
}
}
}
}
static
int
ideapad_acpi_add
(
struct
acpi_device
*
adevice
)
static
void
ideapad_acpi_notify
(
acpi_handle
handle
,
u32
event
,
void
*
data
)
{
struct
ideapad_private
*
priv
=
data
;
unsigned
long
vpc1
,
vpc2
,
vpc_bit
;
if
(
read_ec_data
(
handle
,
VPCCMD_R_VPC1
,
&
vpc1
))
return
;
if
(
read_ec_data
(
handle
,
VPCCMD_R_VPC2
,
&
vpc2
))
return
;
vpc1
=
(
vpc2
<<
8
)
|
vpc1
;
for
(
vpc_bit
=
0
;
vpc_bit
<
16
;
vpc_bit
++
)
{
if
(
test_bit
(
vpc_bit
,
&
vpc1
))
{
switch
(
vpc_bit
)
{
case
9
:
ideapad_sync_rfk_state
(
priv
);
break
;
case
13
:
case
11
:
case
7
:
case
6
:
ideapad_input_report
(
priv
,
vpc_bit
);
break
;
case
5
:
ideapad_sync_touchpad_state
(
priv
);
break
;
case
4
:
ideapad_backlight_notify_brightness
(
priv
);
break
;
case
3
:
ideapad_input_novokey
(
priv
);
break
;
case
2
:
ideapad_backlight_notify_power
(
priv
);
break
;
case
0
:
ideapad_check_special_buttons
(
priv
);
break
;
default:
pr_info
(
"Unknown event: %lu
\n
"
,
vpc_bit
);
}
}
}
}
static
int
ideapad_acpi_add
(
struct
platform_device
*
pdev
)
{
{
int
ret
,
i
;
int
ret
,
i
;
int
cfg
;
int
cfg
;
struct
ideapad_private
*
priv
;
struct
ideapad_private
*
priv
;
struct
acpi_device
*
adev
;
if
(
read_method_int
(
adevice
->
handle
,
"_CFG"
,
&
cfg
))
ret
=
acpi_bus_get_device
(
ACPI_HANDLE
(
&
pdev
->
dev
),
&
adev
);
if
(
ret
)
return
-
ENODEV
;
if
(
read_method_int
(
adev
->
handle
,
"_CFG"
,
&
cfg
))
return
-
ENODEV
;
return
-
ENODEV
;
priv
=
kzalloc
(
sizeof
(
*
priv
),
GFP_KERNEL
);
priv
=
kzalloc
(
sizeof
(
*
priv
),
GFP_KERNEL
);
if
(
!
priv
)
if
(
!
priv
)
return
-
ENOMEM
;
return
-
ENOMEM
;
dev_set_drvdata
(
&
adevice
->
dev
,
priv
);
ideapad_priv
=
priv
;
dev_set_drvdata
(
&
pdev
->
dev
,
priv
);
ideapad_handle
=
adevice
->
handle
;
priv
->
cfg
=
cfg
;
priv
->
cfg
=
cfg
;
priv
->
adev
=
adev
;
priv
->
platform_device
=
pdev
;
ret
=
ideapad_
platform
_init
(
priv
);
ret
=
ideapad_
sysfs
_init
(
priv
);
if
(
ret
)
if
(
ret
)
goto
platform
_failed
;
goto
sysfs
_failed
;
ret
=
ideapad_debugfs_init
(
priv
);
ret
=
ideapad_debugfs_init
(
priv
);
if
(
ret
)
if
(
ret
)
...
@@ -810,117 +859,92 @@ static int ideapad_acpi_add(struct acpi_device *adevice)
...
@@ -810,117 +859,92 @@ static int ideapad_acpi_add(struct acpi_device *adevice)
for
(
i
=
0
;
i
<
IDEAPAD_RFKILL_DEV_NUM
;
i
++
)
{
for
(
i
=
0
;
i
<
IDEAPAD_RFKILL_DEV_NUM
;
i
++
)
{
if
(
test_bit
(
ideapad_rfk_data
[
i
].
cfgbit
,
&
priv
->
cfg
))
if
(
test_bit
(
ideapad_rfk_data
[
i
].
cfgbit
,
&
priv
->
cfg
))
ideapad_register_rfkill
(
adevice
,
i
);
ideapad_register_rfkill
(
priv
,
i
);
else
else
priv
->
rfk
[
i
]
=
NULL
;
priv
->
rfk
[
i
]
=
NULL
;
}
}
ideapad_sync_rfk_state
(
priv
);
ideapad_sync_rfk_state
(
priv
);
ideapad_sync_touchpad_state
(
adevice
);
ideapad_sync_touchpad_state
(
priv
);
if
(
!
acpi_video_backlight_support
())
{
if
(
!
acpi_video_backlight_support
())
{
ret
=
ideapad_backlight_init
(
priv
);
ret
=
ideapad_backlight_init
(
priv
);
if
(
ret
&&
ret
!=
-
ENODEV
)
if
(
ret
&&
ret
!=
-
ENODEV
)
goto
backlight_failed
;
goto
backlight_failed
;
}
}
ret
=
acpi_install_notify_handler
(
adev
->
handle
,
ACPI_DEVICE_NOTIFY
,
ideapad_acpi_notify
,
priv
);
if
(
ret
)
goto
notification_failed
;
return
0
;
return
0
;
notification_failed:
ideapad_backlight_exit
(
priv
);
backlight_failed:
backlight_failed:
for
(
i
=
0
;
i
<
IDEAPAD_RFKILL_DEV_NUM
;
i
++
)
for
(
i
=
0
;
i
<
IDEAPAD_RFKILL_DEV_NUM
;
i
++
)
ideapad_unregister_rfkill
(
adevice
,
i
);
ideapad_unregister_rfkill
(
priv
,
i
);
ideapad_input_exit
(
priv
);
ideapad_input_exit
(
priv
);
input_failed:
input_failed:
ideapad_debugfs_exit
(
priv
);
ideapad_debugfs_exit
(
priv
);
debugfs_failed:
debugfs_failed:
ideapad_
platform
_exit
(
priv
);
ideapad_
sysfs
_exit
(
priv
);
platform
_failed:
sysfs
_failed:
kfree
(
priv
);
kfree
(
priv
);
return
ret
;
return
ret
;
}
}
static
int
ideapad_acpi_remove
(
struct
acpi_device
*
adevice
)
static
int
ideapad_acpi_remove
(
struct
platform_device
*
pdev
)
{
{
struct
ideapad_private
*
priv
=
dev_get_drvdata
(
&
adevice
->
dev
);
struct
ideapad_private
*
priv
=
dev_get_drvdata
(
&
pdev
->
dev
);
int
i
;
int
i
;
acpi_remove_notify_handler
(
priv
->
adev
->
handle
,
ACPI_DEVICE_NOTIFY
,
ideapad_acpi_notify
);
ideapad_backlight_exit
(
priv
);
ideapad_backlight_exit
(
priv
);
for
(
i
=
0
;
i
<
IDEAPAD_RFKILL_DEV_NUM
;
i
++
)
for
(
i
=
0
;
i
<
IDEAPAD_RFKILL_DEV_NUM
;
i
++
)
ideapad_unregister_rfkill
(
adevice
,
i
);
ideapad_unregister_rfkill
(
priv
,
i
);
ideapad_input_exit
(
priv
);
ideapad_input_exit
(
priv
);
ideapad_debugfs_exit
(
priv
);
ideapad_debugfs_exit
(
priv
);
ideapad_
platform
_exit
(
priv
);
ideapad_
sysfs
_exit
(
priv
);
dev_set_drvdata
(
&
adevice
->
dev
,
NULL
);
dev_set_drvdata
(
&
pdev
->
dev
,
NULL
);
kfree
(
priv
);
kfree
(
priv
);
return
0
;
return
0
;
}
}
static
void
ideapad_acpi_notify
(
struct
acpi_device
*
adevice
,
u32
event
)
#ifdef CONFIG_PM_SLEEP
static
int
ideapad_acpi_resume
(
struct
device
*
device
)
{
{
struct
ideapad_private
*
priv
=
dev_get_drvdata
(
&
adevice
->
dev
);
struct
ideapad_private
*
priv
;
acpi_handle
handle
=
adevice
->
handle
;
unsigned
long
vpc1
,
vpc2
,
vpc_bit
;
if
(
read_ec_data
(
handle
,
VPCCMD_R_VPC1
,
&
vpc1
))
if
(
!
device
)
return
;
return
-
EINVAL
;
if
(
read_ec_data
(
handle
,
VPCCMD_R_VPC2
,
&
vpc2
))
priv
=
dev_get_drvdata
(
device
);
return
;
vpc1
=
(
vpc2
<<
8
)
|
vpc1
;
for
(
vpc_bit
=
0
;
vpc_bit
<
16
;
vpc_bit
++
)
{
if
(
test_bit
(
vpc_bit
,
&
vpc1
))
{
switch
(
vpc_bit
)
{
case
9
:
ideapad_sync_rfk_state
(
priv
);
ideapad_sync_rfk_state
(
priv
);
break
;
ideapad_sync_touchpad_state
(
priv
);
case
13
:
case
11
:
case
7
:
case
6
:
ideapad_input_report
(
priv
,
vpc_bit
);
break
;
case
5
:
ideapad_sync_touchpad_state
(
adevice
);
break
;
case
4
:
ideapad_backlight_notify_brightness
(
priv
);
break
;
case
3
:
ideapad_input_novokey
(
priv
);
break
;
case
2
:
ideapad_backlight_notify_power
(
priv
);
break
;
case
0
:
ideapad_check_special_buttons
(
priv
);
break
;
default:
pr_info
(
"Unknown event: %lu
\n
"
,
vpc_bit
);
}
}
}
}
static
int
ideapad_acpi_resume
(
struct
device
*
device
)
{
ideapad_sync_rfk_state
(
ideapad_priv
);
ideapad_sync_touchpad_state
(
to_acpi_device
(
device
));
return
0
;
return
0
;
}
}
#endif
static
SIMPLE_DEV_PM_OPS
(
ideapad_pm
,
NULL
,
ideapad_acpi_resume
);
static
SIMPLE_DEV_PM_OPS
(
ideapad_pm
,
NULL
,
ideapad_acpi_resume
);
static
struct
acpi_driver
ideapad_acpi_driver
=
{
static
const
struct
acpi_device_id
ideapad_device_ids
[]
=
{
{
"VPC2004"
,
0
},
{
""
,
0
},
};
MODULE_DEVICE_TABLE
(
acpi
,
ideapad_device_ids
);
static
struct
platform_driver
ideapad_acpi_driver
=
{
.
probe
=
ideapad_acpi_add
,
.
remove
=
ideapad_acpi_remove
,
.
driver
=
{
.
name
=
"ideapad_acpi"
,
.
name
=
"ideapad_acpi"
,
.
class
=
"IdeaPad"
,
.
ids
=
ideapad_device_ids
,
.
ops
.
add
=
ideapad_acpi_add
,
.
ops
.
remove
=
ideapad_acpi_remove
,
.
ops
.
notify
=
ideapad_acpi_notify
,
.
drv
.
pm
=
&
ideapad_pm
,
.
owner
=
THIS_MODULE
,
.
owner
=
THIS_MODULE
,
.
pm
=
&
ideapad_pm
,
.
acpi_match_table
=
ACPI_PTR
(
ideapad_device_ids
),
},
};
};
module_acpi_driver
(
ideapad_acpi_driver
);
module_platform_driver
(
ideapad_acpi_driver
);
MODULE_AUTHOR
(
"David Woodhouse <dwmw2@infradead.org>"
);
MODULE_AUTHOR
(
"David Woodhouse <dwmw2@infradead.org>"
);
MODULE_DESCRIPTION
(
"IdeaPad ACPI Extras"
);
MODULE_DESCRIPTION
(
"IdeaPad ACPI Extras"
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录