asoc: add pm qos mixer controls
When device enters LPM, it hurts audio latency as CPU spends more time in entering/exiting LPM. Hence, for LL and/or ULL, LPM is disabled. Add pm qos mixer controls for cpu affinity and increase the delay for the cores to enter LPM mode. Change-Id: I3aa2d17f6b3ec3ffad180205085bd2f4961858b7 Signed-off-by: Srinivas Marka <quic_smarka@quicinc.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||||
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2021-2022. Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
@@ -51,9 +51,6 @@
|
|||||||
#define DEV_NAME_STR_LEN 32
|
#define DEV_NAME_STR_LEN 32
|
||||||
#define WCD_MBHC_HS_V_MAX 1600
|
#define WCD_MBHC_HS_V_MAX 1600
|
||||||
|
|
||||||
#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */
|
|
||||||
|
|
||||||
|
|
||||||
#define WCN_CDC_SLIM_RX_CH_MAX 2
|
#define WCN_CDC_SLIM_RX_CH_MAX 2
|
||||||
#define WCN_CDC_SLIM_TX_CH_MAX 2
|
#define WCN_CDC_SLIM_TX_CH_MAX 2
|
||||||
#define WCN_CDC_SLIM_TX_CH_MAX_LITO 3
|
#define WCN_CDC_SLIM_TX_CH_MAX_LITO 3
|
||||||
@@ -123,53 +120,6 @@ static struct wcd_mbhc_config wcd_mbhc_cfg = {
|
|||||||
.moisture_duty_cycle_en = true,
|
.moisture_duty_cycle_en = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* set audio task affinity to core 1 & 2 */
|
|
||||||
static const unsigned int audio_core_list[] = {1, 2};
|
|
||||||
static cpumask_t audio_cpu_map = CPU_MASK_NONE;
|
|
||||||
static struct dev_pm_qos_request *msm_audio_req = NULL;
|
|
||||||
|
|
||||||
static void msm_audio_add_qos_request()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int cpu = 0;
|
|
||||||
|
|
||||||
msm_audio_req = kzalloc(sizeof(struct dev_pm_qos_request) * NR_CPUS,
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!msm_audio_req) {
|
|
||||||
pr_err("%s failed to alloc mem for qos req.\n", __func__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(audio_core_list); i++) {
|
|
||||||
if (audio_core_list[i] >= NR_CPUS)
|
|
||||||
pr_err("%s incorrect cpu id: %d specified.\n", __func__, audio_core_list[i]);
|
|
||||||
else
|
|
||||||
cpumask_set_cpu(audio_core_list[i], &audio_cpu_map);
|
|
||||||
}
|
|
||||||
|
|
||||||
for_each_cpu(cpu, &audio_cpu_map) {
|
|
||||||
dev_pm_qos_add_request(get_cpu_device(cpu),
|
|
||||||
&msm_audio_req[cpu],
|
|
||||||
DEV_PM_QOS_RESUME_LATENCY,
|
|
||||||
PM_QOS_CPU_LATENCY_DEFAULT_VALUE);
|
|
||||||
pr_debug("%s set cpu affinity to core %d.\n", __func__, cpu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void msm_audio_remove_qos_request()
|
|
||||||
{
|
|
||||||
int cpu = 0;
|
|
||||||
|
|
||||||
if (msm_audio_req) {
|
|
||||||
for_each_cpu(cpu, &audio_cpu_map) {
|
|
||||||
dev_pm_qos_remove_request(
|
|
||||||
&msm_audio_req[cpu]);
|
|
||||||
pr_debug("%s remove cpu affinity of core %d.\n", __func__, cpu);
|
|
||||||
}
|
|
||||||
kfree(msm_audio_req);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool msm_usbc_swap_gnd_mic(struct snd_soc_component *component, bool active)
|
static bool msm_usbc_swap_gnd_mic(struct snd_soc_component *component, bool active)
|
||||||
{
|
{
|
||||||
struct snd_soc_card *card = component->card;
|
struct snd_soc_card *card = component->card;
|
||||||
@@ -1919,9 +1869,6 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
is_initial_boot = true;
|
is_initial_boot = true;
|
||||||
|
|
||||||
/* Add QoS request for audio tasks */
|
|
||||||
msm_audio_add_qos_request();
|
|
||||||
|
|
||||||
/* change card status to ONLINE */
|
/* change card status to ONLINE */
|
||||||
dev_dbg(&pdev->dev, "%s: setting snd_card to ONLINE\n", __func__);
|
dev_dbg(&pdev->dev, "%s: setting snd_card to ONLINE\n", __func__);
|
||||||
snd_card_set_card_status(SND_CARD_STATUS_ONLINE);
|
snd_card_set_card_status(SND_CARD_STATUS_ONLINE);
|
||||||
@@ -1947,7 +1894,6 @@ static int msm_asoc_machine_remove(struct platform_device *pdev)
|
|||||||
msm_common_snd_deinit(common_pdata);
|
msm_common_snd_deinit(common_pdata);
|
||||||
snd_event_master_deregister(&pdev->dev);
|
snd_event_master_deregister(&pdev->dev);
|
||||||
snd_soc_unregister_card(card);
|
snd_soc_unregister_card(card);
|
||||||
msm_audio_remove_qos_request();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -1,13 +1,7 @@
|
|||||||
/* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
*
|
/*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
|
||||||
* it under the terms of the GNU General Public License version 2 and
|
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
* only version 2 as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
@@ -79,6 +73,16 @@ struct chmap_pdata {
|
|||||||
|
|
||||||
#define MAX_USR_INPUT 10
|
#define MAX_USR_INPUT 10
|
||||||
|
|
||||||
|
static int qos_vote_status;
|
||||||
|
static struct dev_pm_qos_request latency_pm_qos_req; /* pm_qos request */
|
||||||
|
static unsigned int qos_client_active_cnt;
|
||||||
|
/* set audio task affinity to core 1 & 2 */
|
||||||
|
static const unsigned int audio_core_list[] = {1, 2};
|
||||||
|
static cpumask_t audio_cpu_map = CPU_MASK_NONE;
|
||||||
|
static struct dev_pm_qos_request *msm_audio_req = NULL;
|
||||||
|
static bool kregister_pm_qos_latency_controls = false;
|
||||||
|
#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */
|
||||||
|
|
||||||
static ssize_t aud_dev_sysfs_store(struct kobject *kobj,
|
static ssize_t aud_dev_sysfs_store(struct kobject *kobj,
|
||||||
struct attribute *attr,
|
struct attribute *attr,
|
||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
@@ -594,6 +598,55 @@ void msm_common_snd_shutdown(struct snd_pcm_substream *substream)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void msm_audio_add_qos_request()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int cpu = 0;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
msm_audio_req = kcalloc(num_possible_cpus(),
|
||||||
|
sizeof(struct dev_pm_qos_request), GFP_KERNEL);
|
||||||
|
if (!msm_audio_req)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(audio_core_list); i++) {
|
||||||
|
if (audio_core_list[i] >= num_possible_cpus())
|
||||||
|
pr_err("%s incorrect cpu id: %d specified.\n",
|
||||||
|
__func__, audio_core_list[i]);
|
||||||
|
else
|
||||||
|
cpumask_set_cpu(audio_core_list[i], &audio_cpu_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
for_each_cpu(cpu, &audio_cpu_map) {
|
||||||
|
ret = dev_pm_qos_add_request(get_cpu_device(cpu),
|
||||||
|
&msm_audio_req[cpu],
|
||||||
|
DEV_PM_QOS_RESUME_LATENCY,
|
||||||
|
PM_QOS_CPU_LATENCY_DEFAULT_VALUE);
|
||||||
|
if (ret < 0)
|
||||||
|
pr_err("%s error (%d) adding resume latency to cpu %d.\n",
|
||||||
|
__func__, ret, cpu);
|
||||||
|
pr_debug("%s set cpu affinity to core %d.\n", __func__, cpu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void msm_audio_remove_qos_request()
|
||||||
|
{
|
||||||
|
int cpu = 0;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (msm_audio_req) {
|
||||||
|
for_each_cpu(cpu, &audio_cpu_map) {
|
||||||
|
ret = dev_pm_qos_remove_request(
|
||||||
|
&msm_audio_req[cpu]);
|
||||||
|
if (ret < 0)
|
||||||
|
pr_err("%s error (%d) removing request from cpu %d.\n",
|
||||||
|
__func__, ret, cpu);
|
||||||
|
pr_debug("%s remove cpu affinity of core %d.\n", __func__, cpu);
|
||||||
|
}
|
||||||
|
kfree(msm_audio_req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int msm_common_snd_init(struct platform_device *pdev, struct snd_soc_card *card)
|
int msm_common_snd_init(struct platform_device *pdev, struct snd_soc_card *card)
|
||||||
{
|
{
|
||||||
struct msm_common_pdata *common_pdata = NULL;
|
struct msm_common_pdata *common_pdata = NULL;
|
||||||
@@ -699,6 +752,10 @@ int msm_common_snd_init(struct platform_device *pdev, struct snd_soc_card *card)
|
|||||||
aud_dev_sysfs_init(common_pdata);
|
aud_dev_sysfs_init(common_pdata);
|
||||||
|
|
||||||
msm_common_set_pdata(card, common_pdata);
|
msm_common_set_pdata(card, common_pdata);
|
||||||
|
|
||||||
|
/* Add QoS request for audio tasks */
|
||||||
|
msm_audio_add_qos_request();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -709,6 +766,8 @@ void msm_common_snd_deinit(struct msm_common_pdata *common_pdata)
|
|||||||
if (!common_pdata)
|
if (!common_pdata)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
msm_audio_remove_qos_request();
|
||||||
|
|
||||||
for (count = 0; count < MI2S_TDM_AUXPCM_MAX; count++) {
|
for (count = 0; count < MI2S_TDM_AUXPCM_MAX; count++) {
|
||||||
mutex_destroy(&common_pdata->lock[count]);
|
mutex_destroy(&common_pdata->lock[count]);
|
||||||
}
|
}
|
||||||
@@ -854,6 +913,88 @@ void msm_common_get_backend_name(const char *stream_name, char **backend_name)
|
|||||||
strlcpy(*backend_name, arg, ARRAY_SZ);
|
strlcpy(*backend_name, arg, ARRAY_SZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void msm_audio_update_qos_request(u32 latency)
|
||||||
|
{
|
||||||
|
int cpu = 0;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (msm_audio_req) {
|
||||||
|
for_each_cpu(cpu, &audio_cpu_map) {
|
||||||
|
ret = dev_pm_qos_update_request(
|
||||||
|
&msm_audio_req[cpu], latency);
|
||||||
|
if (1 == ret ) {
|
||||||
|
pr_debug("%s: updated latency of core %d to %u.\n",
|
||||||
|
__func__, cpu, latency);
|
||||||
|
} else if (0 == ret) {
|
||||||
|
pr_debug("%s: latency of core %d not changed. latency %u.\n",
|
||||||
|
__func__, cpu, latency);
|
||||||
|
} else {
|
||||||
|
pr_err("%s: failed to update latency of core %d, error %d \n",
|
||||||
|
__func__, cpu, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int msm_qos_ctl_put(struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
qos_vote_status = ucontrol->value.enumerated.item[0];
|
||||||
|
if (qos_vote_status) {
|
||||||
|
if (dev_pm_qos_request_active(&latency_pm_qos_req))
|
||||||
|
dev_pm_qos_remove_request(&latency_pm_qos_req);
|
||||||
|
|
||||||
|
qos_client_active_cnt++;
|
||||||
|
if (qos_client_active_cnt == 1)
|
||||||
|
msm_audio_update_qos_request(MSM_LL_QOS_VALUE);
|
||||||
|
} else {
|
||||||
|
if (qos_client_active_cnt > 0)
|
||||||
|
qos_client_active_cnt--;
|
||||||
|
if (qos_client_active_cnt == 0)
|
||||||
|
msm_audio_update_qos_request(PM_QOS_CPU_LATENCY_DEFAULT_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int msm_qos_ctl_get(struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
ucontrol->value.enumerated.item[0] = qos_vote_status;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *const qos_text[] = {"Disable", "Enable"};
|
||||||
|
|
||||||
|
static SOC_ENUM_SINGLE_EXT_DECL(qos_vote, qos_text);
|
||||||
|
|
||||||
|
static const struct snd_kcontrol_new card_pm_qos_controls[] = {
|
||||||
|
SOC_ENUM_EXT("PM_QOS Vote", qos_vote,
|
||||||
|
msm_qos_ctl_get, msm_qos_ctl_put),
|
||||||
|
};
|
||||||
|
|
||||||
|
static int msm_register_pm_qos_latency_controls(struct snd_soc_pcm_runtime *rtd)
|
||||||
|
{
|
||||||
|
struct snd_soc_component *lpass_cdc_component = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
lpass_cdc_component = snd_soc_rtdcom_lookup(rtd, "lpass-cdc");
|
||||||
|
if (!lpass_cdc_component) {
|
||||||
|
pr_err("%s: could not find component for lpass-cdc\n",
|
||||||
|
__func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = snd_soc_add_component_controls(lpass_cdc_component,
|
||||||
|
card_pm_qos_controls, ARRAY_SIZE(card_pm_qos_controls));
|
||||||
|
if (ret < 0) {
|
||||||
|
pr_err("%s: add common snd controls failed: %d\n",
|
||||||
|
__func__, ret);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int msm_common_dai_link_init(struct snd_soc_pcm_runtime *rtd)
|
int msm_common_dai_link_init(struct snd_soc_pcm_runtime *rtd)
|
||||||
{
|
{
|
||||||
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
|
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
|
||||||
@@ -933,9 +1074,20 @@ int msm_common_dai_link_init(struct snd_soc_pcm_runtime *rtd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
kctl->private_data = pdata;
|
kctl->private_data = pdata;
|
||||||
|
}
|
||||||
|
if (!kregister_pm_qos_latency_controls) {
|
||||||
|
if (!msm_register_pm_qos_latency_controls(rtd))
|
||||||
|
kregister_pm_qos_latency_controls = true;
|
||||||
|
}
|
||||||
|
|
||||||
free_mixer_str:
|
free_mixer_str:
|
||||||
|
if (backend_name) {
|
||||||
kfree(backend_name);
|
kfree(backend_name);
|
||||||
|
backend_name = NULL;
|
||||||
|
}
|
||||||
|
if (mixer_str) {
|
||||||
kfree(mixer_str);
|
kfree(mixer_str);
|
||||||
|
mixer_str = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||||
|
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
@@ -50,9 +51,6 @@
|
|||||||
#define DEV_NAME_STR_LEN 32
|
#define DEV_NAME_STR_LEN 32
|
||||||
#define WCD_MBHC_HS_V_MAX 1600
|
#define WCD_MBHC_HS_V_MAX 1600
|
||||||
|
|
||||||
#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */
|
|
||||||
|
|
||||||
|
|
||||||
#define WCN_CDC_SLIM_RX_CH_MAX 2
|
#define WCN_CDC_SLIM_RX_CH_MAX 2
|
||||||
#define WCN_CDC_SLIM_TX_CH_MAX 2
|
#define WCN_CDC_SLIM_TX_CH_MAX 2
|
||||||
#define WCN_CDC_SLIM_TX_CH_MAX_LITO 3
|
#define WCN_CDC_SLIM_TX_CH_MAX_LITO 3
|
||||||
@@ -120,53 +118,6 @@ static struct wcd_mbhc_config wcd_mbhc_cfg = {
|
|||||||
.moisture_duty_cycle_en = true,
|
.moisture_duty_cycle_en = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* set audio task affinity to core 1 & 2 */
|
|
||||||
static const unsigned int audio_core_list[] = {1, 2};
|
|
||||||
static cpumask_t audio_cpu_map = CPU_MASK_NONE;
|
|
||||||
static struct dev_pm_qos_request *msm_audio_req = NULL;
|
|
||||||
|
|
||||||
static void msm_audio_add_qos_request()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int cpu = 0;
|
|
||||||
|
|
||||||
msm_audio_req = kzalloc(sizeof(struct dev_pm_qos_request) * NR_CPUS,
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!msm_audio_req) {
|
|
||||||
pr_err("%s failed to alloc mem for qos req.\n", __func__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(audio_core_list); i++) {
|
|
||||||
if (audio_core_list[i] >= NR_CPUS)
|
|
||||||
pr_err("%s incorrect cpu id: %d specified.\n", __func__, audio_core_list[i]);
|
|
||||||
else
|
|
||||||
cpumask_set_cpu(audio_core_list[i], &audio_cpu_map);
|
|
||||||
}
|
|
||||||
|
|
||||||
for_each_cpu(cpu, &audio_cpu_map) {
|
|
||||||
dev_pm_qos_add_request(get_cpu_device(cpu),
|
|
||||||
&msm_audio_req[cpu],
|
|
||||||
DEV_PM_QOS_RESUME_LATENCY,
|
|
||||||
PM_QOS_CPU_LATENCY_DEFAULT_VALUE);
|
|
||||||
pr_debug("%s set cpu affinity to core %d.\n", __func__, cpu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void msm_audio_remove_qos_request()
|
|
||||||
{
|
|
||||||
int cpu = 0;
|
|
||||||
|
|
||||||
if (msm_audio_req) {
|
|
||||||
for_each_cpu(cpu, &audio_cpu_map) {
|
|
||||||
dev_pm_qos_remove_request(
|
|
||||||
&msm_audio_req[cpu]);
|
|
||||||
pr_debug("%s remove cpu affinity of core %d.\n", __func__, cpu);
|
|
||||||
}
|
|
||||||
kfree(msm_audio_req);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool msm_usbc_swap_gnd_mic(struct snd_soc_component *component, bool active)
|
static bool msm_usbc_swap_gnd_mic(struct snd_soc_component *component, bool active)
|
||||||
{
|
{
|
||||||
struct snd_soc_card *card = component->card;
|
struct snd_soc_card *card = component->card;
|
||||||
@@ -1891,9 +1842,6 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
is_initial_boot = true;
|
is_initial_boot = true;
|
||||||
|
|
||||||
/* Add QoS request for audio tasks */
|
|
||||||
msm_audio_add_qos_request();
|
|
||||||
|
|
||||||
/* change card status to ONLINE */
|
/* change card status to ONLINE */
|
||||||
dev_dbg(&pdev->dev, "%s: setting snd_card to ONLINE\n", __func__);
|
dev_dbg(&pdev->dev, "%s: setting snd_card to ONLINE\n", __func__);
|
||||||
snd_card_set_card_status(SND_CARD_STATUS_ONLINE);
|
snd_card_set_card_status(SND_CARD_STATUS_ONLINE);
|
||||||
@@ -1919,7 +1867,6 @@ static int msm_asoc_machine_remove(struct platform_device *pdev)
|
|||||||
msm_common_snd_deinit(common_pdata);
|
msm_common_snd_deinit(common_pdata);
|
||||||
snd_event_master_deregister(&pdev->dev);
|
snd_event_master_deregister(&pdev->dev);
|
||||||
snd_soc_unregister_card(card);
|
snd_soc_unregister_card(card);
|
||||||
msm_audio_remove_qos_request();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user