Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
85abf3ec
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看板
提交
85abf3ec
编写于
4月 29, 2015
作者:
T
Takashi Iwai
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'topic/hda' into for-next
上级
49c4a4c5
2bd1f73f
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
99 addition
and
12 deletion
+99
-12
include/sound/hdaudio.h
include/sound/hdaudio.h
+4
-0
sound/hda/hdac_device.c
sound/hda/hdac_device.c
+15
-0
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.c
+4
-0
sound/pci/hda/hda_controller.c
sound/pci/hda/hda_controller.c
+11
-0
sound/pci/hda/hda_controller.h
sound/pci/hda/hda_controller.h
+2
-0
sound/pci/hda/hda_i915.c
sound/pci/hda/hda_i915.c
+14
-4
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_intel.c
+38
-8
sound/pci/hda/hda_intel.h
sound/pci/hda/hda_intel.h
+2
-0
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_hdmi.c
+9
-0
未找到文件。
include/sound/hdaudio.h
浏览文件 @
85abf3ec
...
@@ -74,6 +74,7 @@ struct hdac_device {
...
@@ -74,6 +74,7 @@ struct hdac_device {
/* misc flags */
/* misc flags */
atomic_t
in_pm
;
/* suspend/resume being performed */
atomic_t
in_pm
;
/* suspend/resume being performed */
bool
link_power_control
:
1
;
/* sysfs */
/* sysfs */
struct
hdac_widget_tree
*
widgets
;
struct
hdac_widget_tree
*
widgets
;
...
@@ -184,6 +185,8 @@ struct hdac_bus_ops {
...
@@ -184,6 +185,8 @@ struct hdac_bus_ops {
/* get a response from the last command */
/* get a response from the last command */
int
(
*
get_response
)(
struct
hdac_bus
*
bus
,
unsigned
int
addr
,
int
(
*
get_response
)(
struct
hdac_bus
*
bus
,
unsigned
int
addr
,
unsigned
int
*
res
);
unsigned
int
*
res
);
/* control the link power */
int
(
*
link_power
)(
struct
hdac_bus
*
bus
,
bool
enable
);
};
};
/*
/*
...
@@ -311,6 +314,7 @@ static inline void snd_hdac_codec_link_down(struct hdac_device *codec)
...
@@ -311,6 +314,7 @@ static inline void snd_hdac_codec_link_down(struct hdac_device *codec)
int
snd_hdac_bus_send_cmd
(
struct
hdac_bus
*
bus
,
unsigned
int
val
);
int
snd_hdac_bus_send_cmd
(
struct
hdac_bus
*
bus
,
unsigned
int
val
);
int
snd_hdac_bus_get_response
(
struct
hdac_bus
*
bus
,
unsigned
int
addr
,
int
snd_hdac_bus_get_response
(
struct
hdac_bus
*
bus
,
unsigned
int
addr
,
unsigned
int
*
res
);
unsigned
int
*
res
);
int
snd_hdac_link_power
(
struct
hdac_device
*
codec
,
bool
enable
);
bool
snd_hdac_bus_init_chip
(
struct
hdac_bus
*
bus
,
bool
full_reset
);
bool
snd_hdac_bus_init_chip
(
struct
hdac_bus
*
bus
,
bool
full_reset
);
void
snd_hdac_bus_stop_chip
(
struct
hdac_bus
*
bus
);
void
snd_hdac_bus_stop_chip
(
struct
hdac_bus
*
bus
);
...
...
sound/hda/hdac_device.c
浏览文件 @
85abf3ec
...
@@ -552,6 +552,21 @@ void snd_hdac_power_down_pm(struct hdac_device *codec)
...
@@ -552,6 +552,21 @@ void snd_hdac_power_down_pm(struct hdac_device *codec)
EXPORT_SYMBOL_GPL
(
snd_hdac_power_down_pm
);
EXPORT_SYMBOL_GPL
(
snd_hdac_power_down_pm
);
#endif
#endif
/*
* Enable/disable the link power for a codec.
*/
int
snd_hdac_link_power
(
struct
hdac_device
*
codec
,
bool
enable
)
{
if
(
!
codec
->
link_power_control
)
return
0
;
if
(
codec
->
bus
->
ops
->
link_power
)
return
codec
->
bus
->
ops
->
link_power
(
codec
->
bus
,
enable
);
else
return
-
EINVAL
;
}
EXPORT_SYMBOL_GPL
(
snd_hdac_link_power
);
/* codec vendor labels */
/* codec vendor labels */
struct
hda_vendor_id
{
struct
hda_vendor_id
{
unsigned
int
id
;
unsigned
int
id
;
...
...
sound/pci/hda/hda_codec.c
浏览文件 @
85abf3ec
...
@@ -858,6 +858,7 @@ void snd_hda_codec_register(struct hda_codec *codec)
...
@@ -858,6 +858,7 @@ void snd_hda_codec_register(struct hda_codec *codec)
return
;
return
;
if
(
device_is_registered
(
hda_codec_dev
(
codec
)))
{
if
(
device_is_registered
(
hda_codec_dev
(
codec
)))
{
snd_hda_register_beep_device
(
codec
);
snd_hda_register_beep_device
(
codec
);
snd_hdac_link_power
(
&
codec
->
core
,
true
);
pm_runtime_enable
(
hda_codec_dev
(
codec
));
pm_runtime_enable
(
hda_codec_dev
(
codec
));
/* it was powered up in snd_hda_codec_new(), now all done */
/* it was powered up in snd_hda_codec_new(), now all done */
snd_hda_power_down
(
codec
);
snd_hda_power_down
(
codec
);
...
@@ -884,6 +885,7 @@ static int snd_hda_codec_dev_free(struct snd_device *device)
...
@@ -884,6 +885,7 @@ static int snd_hda_codec_dev_free(struct snd_device *device)
struct
hda_codec
*
codec
=
device
->
device_data
;
struct
hda_codec
*
codec
=
device
->
device_data
;
codec
->
in_freeing
=
1
;
codec
->
in_freeing
=
1
;
snd_hdac_link_power
(
&
codec
->
core
,
false
);
snd_hdac_device_unregister
(
&
codec
->
core
);
snd_hdac_device_unregister
(
&
codec
->
core
);
put_device
(
hda_codec_dev
(
codec
));
put_device
(
hda_codec_dev
(
codec
));
return
0
;
return
0
;
...
@@ -3106,6 +3108,7 @@ static int hda_codec_runtime_suspend(struct device *dev)
...
@@ -3106,6 +3108,7 @@ static int hda_codec_runtime_suspend(struct device *dev)
if
(
codec_has_clkstop
(
codec
)
&&
codec_has_epss
(
codec
)
&&
if
(
codec_has_clkstop
(
codec
)
&&
codec_has_epss
(
codec
)
&&
(
state
&
AC_PWRST_CLK_STOP_OK
))
(
state
&
AC_PWRST_CLK_STOP_OK
))
snd_hdac_codec_link_down
(
&
codec
->
core
);
snd_hdac_codec_link_down
(
&
codec
->
core
);
snd_hdac_link_power
(
&
codec
->
core
,
false
);
return
0
;
return
0
;
}
}
...
@@ -3113,6 +3116,7 @@ static int hda_codec_runtime_resume(struct device *dev)
...
@@ -3113,6 +3116,7 @@ static int hda_codec_runtime_resume(struct device *dev)
{
{
struct
hda_codec
*
codec
=
dev_to_hda_codec
(
dev
);
struct
hda_codec
*
codec
=
dev_to_hda_codec
(
dev
);
snd_hdac_link_power
(
&
codec
->
core
,
true
);
snd_hdac_codec_link_up
(
&
codec
->
core
);
snd_hdac_codec_link_up
(
&
codec
->
core
);
hda_call_codec_resume
(
codec
);
hda_call_codec_resume
(
codec
);
pm_runtime_mark_last_busy
(
dev
);
pm_runtime_mark_last_busy
(
dev
);
...
...
sound/pci/hda/hda_controller.c
浏览文件 @
85abf3ec
...
@@ -775,9 +775,20 @@ static int azx_get_response(struct hdac_bus *bus, unsigned int addr,
...
@@ -775,9 +775,20 @@ static int azx_get_response(struct hdac_bus *bus, unsigned int addr,
return
azx_rirb_get_response
(
bus
,
addr
,
res
);
return
azx_rirb_get_response
(
bus
,
addr
,
res
);
}
}
static
int
azx_link_power
(
struct
hdac_bus
*
bus
,
bool
enable
)
{
struct
azx
*
chip
=
bus_to_azx
(
bus
);
if
(
chip
->
ops
->
link_power
)
return
chip
->
ops
->
link_power
(
chip
,
enable
);
else
return
-
EINVAL
;
}
static
const
struct
hdac_bus_ops
bus_core_ops
=
{
static
const
struct
hdac_bus_ops
bus_core_ops
=
{
.
command
=
azx_send_cmd
,
.
command
=
azx_send_cmd
,
.
get_response
=
azx_get_response
,
.
get_response
=
azx_get_response
,
.
link_power
=
azx_link_power
,
};
};
#ifdef CONFIG_SND_HDA_DSP_LOADER
#ifdef CONFIG_SND_HDA_DSP_LOADER
...
...
sound/pci/hda/hda_controller.h
浏览文件 @
85abf3ec
...
@@ -89,6 +89,8 @@ struct hda_controller_ops {
...
@@ -89,6 +89,8 @@ struct hda_controller_ops {
struct
vm_area_struct
*
area
);
struct
vm_area_struct
*
area
);
/* Check if current position is acceptable */
/* Check if current position is acceptable */
int
(
*
position_check
)(
struct
azx
*
chip
,
struct
azx_dev
*
azx_dev
);
int
(
*
position_check
)(
struct
azx
*
chip
,
struct
azx_dev
*
azx_dev
);
/* enable/disable the link power */
int
(
*
link_power
)(
struct
azx
*
chip
,
bool
enable
);
};
};
struct
azx_pcm
{
struct
azx_pcm
{
...
...
sound/pci/hda/hda_i915.c
浏览文件 @
85abf3ec
...
@@ -42,10 +42,15 @@ int hda_display_power(struct hda_intel *hda, bool enable)
...
@@ -42,10 +42,15 @@ int hda_display_power(struct hda_intel *hda, bool enable)
dev_dbg
(
&
hda
->
chip
.
pci
->
dev
,
"display power %s
\n
"
,
dev_dbg
(
&
hda
->
chip
.
pci
->
dev
,
"display power %s
\n
"
,
enable
?
"enable"
:
"disable"
);
enable
?
"enable"
:
"disable"
);
if
(
enable
)
acomp
->
ops
->
get_power
(
acomp
->
dev
);
if
(
enable
)
{
else
if
(
!
hda
->
i915_power_refcount
++
)
acomp
->
ops
->
put_power
(
acomp
->
dev
);
acomp
->
ops
->
get_power
(
acomp
->
dev
);
}
else
{
WARN_ON
(
!
hda
->
i915_power_refcount
);
if
(
!--
hda
->
i915_power_refcount
)
acomp
->
ops
->
put_power
(
acomp
->
dev
);
}
return
0
;
return
0
;
}
}
...
@@ -189,6 +194,11 @@ int hda_i915_init(struct hda_intel *hda)
...
@@ -189,6 +194,11 @@ int hda_i915_init(struct hda_intel *hda)
int
hda_i915_exit
(
struct
hda_intel
*
hda
)
int
hda_i915_exit
(
struct
hda_intel
*
hda
)
{
{
struct
device
*
dev
=
&
hda
->
chip
.
pci
->
dev
;
struct
device
*
dev
=
&
hda
->
chip
.
pci
->
dev
;
struct
i915_audio_component
*
acomp
=
&
hda
->
audio_component
;
WARN_ON
(
hda
->
i915_power_refcount
);
if
(
hda
->
i915_power_refcount
>
0
&&
acomp
->
ops
)
acomp
->
ops
->
put_power
(
acomp
->
dev
);
component_master_del
(
dev
,
&
hda_component_master_ops
);
component_master_del
(
dev
,
&
hda_component_master_ops
);
...
...
sound/pci/hda/hda_intel.c
浏览文件 @
85abf3ec
...
@@ -543,6 +543,14 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
...
@@ -543,6 +543,14 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
return
0
;
return
0
;
}
}
/* Enable/disable i915 display power for the link */
static
int
azx_intel_link_power
(
struct
azx
*
chip
,
bool
enable
)
{
struct
hda_intel
*
hda
=
container_of
(
chip
,
struct
hda_intel
,
chip
);
return
hda_display_power
(
hda
,
enable
);
}
/*
/*
* Check whether the current DMA position is acceptable for updating
* Check whether the current DMA position is acceptable for updating
* periods. Returns non-zero if it's OK.
* periods. Returns non-zero if it's OK.
...
@@ -809,7 +817,8 @@ static int azx_suspend(struct device *dev)
...
@@ -809,7 +817,8 @@ static int azx_suspend(struct device *dev)
if
(
chip
->
msi
)
if
(
chip
->
msi
)
pci_disable_msi
(
chip
->
pci
);
pci_disable_msi
(
chip
->
pci
);
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
)
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
&&
hda
->
need_i915_power
)
hda_display_power
(
hda
,
false
);
hda_display_power
(
hda
,
false
);
return
0
;
return
0
;
}
}
...
@@ -829,7 +838,8 @@ static int azx_resume(struct device *dev)
...
@@ -829,7 +838,8 @@ static int azx_resume(struct device *dev)
if
(
chip
->
disabled
||
hda
->
init_failed
)
if
(
chip
->
disabled
||
hda
->
init_failed
)
return
0
;
return
0
;
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
)
{
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
&&
hda
->
need_i915_power
)
{
hda_display_power
(
hda
,
true
);
hda_display_power
(
hda
,
true
);
haswell_set_bclk
(
hda
);
haswell_set_bclk
(
hda
);
}
}
...
@@ -872,7 +882,8 @@ static int azx_runtime_suspend(struct device *dev)
...
@@ -872,7 +882,8 @@ static int azx_runtime_suspend(struct device *dev)
azx_stop_chip
(
chip
);
azx_stop_chip
(
chip
);
azx_enter_link_reset
(
chip
);
azx_enter_link_reset
(
chip
);
azx_clear_irq_pending
(
chip
);
azx_clear_irq_pending
(
chip
);
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
)
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
&&
hda
->
need_i915_power
)
hda_display_power
(
hda
,
false
);
hda_display_power
(
hda
,
false
);
return
0
;
return
0
;
...
@@ -897,7 +908,8 @@ static int azx_runtime_resume(struct device *dev)
...
@@ -897,7 +908,8 @@ static int azx_runtime_resume(struct device *dev)
if
(
!
azx_has_pm_runtime
(
chip
))
if
(
!
azx_has_pm_runtime
(
chip
))
return
0
;
return
0
;
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
)
{
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
&&
hda
->
need_i915_power
)
{
hda_display_power
(
hda
,
true
);
hda_display_power
(
hda
,
true
);
haswell_set_bclk
(
hda
);
haswell_set_bclk
(
hda
);
}
}
...
@@ -1118,7 +1130,8 @@ static int azx_free(struct azx *chip)
...
@@ -1118,7 +1130,8 @@ static int azx_free(struct azx *chip)
release_firmware
(
chip
->
fw
);
release_firmware
(
chip
->
fw
);
#endif
#endif
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
)
{
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
)
{
hda_display_power
(
hda
,
false
);
if
(
hda
->
need_i915_power
)
hda_display_power
(
hda
,
false
);
hda_i915_exit
(
hda
);
hda_i915_exit
(
hda
);
}
}
kfree
(
hda
);
kfree
(
hda
);
...
@@ -1789,6 +1802,7 @@ static const struct hda_controller_ops pci_hda_ops = {
...
@@ -1789,6 +1802,7 @@ static const struct hda_controller_ops pci_hda_ops = {
.
substream_free_pages
=
substream_free_pages
,
.
substream_free_pages
=
substream_free_pages
,
.
pcm_mmap_prepare
=
pcm_mmap_prepare
,
.
pcm_mmap_prepare
=
pcm_mmap_prepare
,
.
position_check
=
azx_position_check
,
.
position_check
=
azx_position_check
,
.
link_power
=
azx_intel_link_power
,
};
};
static
int
azx_probe
(
struct
pci_dev
*
pci
,
static
int
azx_probe
(
struct
pci_dev
*
pci
,
...
@@ -1882,17 +1896,28 @@ static int azx_probe_continue(struct azx *chip)
...
@@ -1882,17 +1896,28 @@ static int azx_probe_continue(struct azx *chip)
int
err
;
int
err
;
hda
->
probe_continued
=
1
;
hda
->
probe_continued
=
1
;
/* Request power well for Haswell HDA controller and codec */
/* Request display power well for the HDA controller or codec. For
* Haswell/Broadwell, both the display HDA controller and codec need
* this power. For other platforms, like Baytrail/Braswell, only the
* display codec needs the power and it can be released after probe.
*/
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
)
{
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
)
{
/* Baytral/Braswell controllers don't need this power */
if
(
pci
->
device
!=
0x0f04
&&
pci
->
device
!=
0x2284
)
hda
->
need_i915_power
=
1
;
#ifdef CONFIG_SND_HDA_I915
#ifdef CONFIG_SND_HDA_I915
err
=
hda_i915_init
(
hda
);
err
=
hda_i915_init
(
hda
);
if
(
err
<
0
)
if
(
err
<
0
)
goto
out_free
;
goto
i915_power_fail
;
err
=
hda_display_power
(
hda
,
true
);
err
=
hda_display_power
(
hda
,
true
);
if
(
err
<
0
)
{
if
(
err
<
0
)
{
dev_err
(
chip
->
card
->
dev
,
dev_err
(
chip
->
card
->
dev
,
"Cannot turn on display power on i915
\n
"
);
"Cannot turn on display power on i915
\n
"
);
goto
out_free
;
goto
i915_power_fail
;
}
}
#endif
#endif
}
}
...
@@ -1939,6 +1964,11 @@ static int azx_probe_continue(struct azx *chip)
...
@@ -1939,6 +1964,11 @@ static int azx_probe_continue(struct azx *chip)
pm_runtime_put_noidle
(
&
pci
->
dev
);
pm_runtime_put_noidle
(
&
pci
->
dev
);
out_free:
out_free:
if
(
chip
->
driver_caps
&
AZX_DCAPS_I915_POWERWELL
&&
!
hda
->
need_i915_power
)
hda_display_power
(
hda
,
false
);
i915_power_fail:
if
(
err
<
0
)
if
(
err
<
0
)
hda
->
init_failed
=
1
;
hda
->
init_failed
=
1
;
complete_all
(
&
hda
->
probe_wait
);
complete_all
(
&
hda
->
probe_wait
);
...
...
sound/pci/hda/hda_intel.h
浏览文件 @
85abf3ec
...
@@ -45,7 +45,9 @@ struct hda_intel {
...
@@ -45,7 +45,9 @@ struct hda_intel {
struct
dev_pm_domain
hdmi_pm_domain
;
struct
dev_pm_domain
hdmi_pm_domain
;
/* i915 component interface */
/* i915 component interface */
bool
need_i915_power
:
1
;
/* the hda controller needs i915 power */
struct
i915_audio_component
audio_component
;
struct
i915_audio_component
audio_component
;
int
i915_power_refcount
;
};
};
#ifdef CONFIG_SND_HDA_I915
#ifdef CONFIG_SND_HDA_I915
...
...
sound/pci/hda/patch_hdmi.c
浏览文件 @
85abf3ec
...
@@ -2335,6 +2335,15 @@ static int patch_generic_hdmi(struct hda_codec *codec)
...
@@ -2335,6 +2335,15 @@ static int patch_generic_hdmi(struct hda_codec *codec)
intel_haswell_fixup_enable_dp12
(
codec
);
intel_haswell_fixup_enable_dp12
(
codec
);
}
}
/* For Valleyview/Cherryview, only the display codec is in the display
* power well and can use link_power ops to request/release the power.
* For Haswell/Broadwell, the controller is also in the power well and
* can cover the codec power request, and so need not set this flag.
* For previous platforms, there is no such power well feature.
*/
if
(
is_valleyview_plus
(
codec
))
codec
->
core
.
link_power_control
=
1
;
if
(
is_haswell_plus
(
codec
)
||
is_valleyview_plus
(
codec
))
if
(
is_haswell_plus
(
codec
)
||
is_valleyview_plus
(
codec
))
codec
->
depop_delay
=
0
;
codec
->
depop_delay
=
0
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录