mirror of https://gitee.com/openkylin/linux.git
greybus: audio: Remove redundant lock protection & is_connected field
Each module maintains connected status & a lock to protect it. Using codec->lock we can safely serialize ASoC specific callbacks (in response to mixer_ctl update or dai_ops) and gb module disconnect. Thus is_connected field can be removed. Signed-off-by: Vaibhav Agarwal <vaibhav.agarwal@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
parent
e6ab7a154c
commit
852859ab81
|
@ -60,7 +60,6 @@ static int gbaudio_module_disable(struct gbaudio_codec_info *codec,
|
||||||
|
|
||||||
dai_name = codec->stream[dir].dai_name;
|
dai_name = codec->stream[dir].dai_name;
|
||||||
|
|
||||||
mutex_lock(&module->lock);
|
|
||||||
module_state = module->ctrlstate[dir];
|
module_state = module->ctrlstate[dir];
|
||||||
if (module_state == GBAUDIO_CODEC_SHUTDOWN) {
|
if (module_state == GBAUDIO_CODEC_SHUTDOWN) {
|
||||||
dev_dbg(codec->dev, "%s: module already configured\n",
|
dev_dbg(codec->dev, "%s: module already configured\n",
|
||||||
|
@ -129,7 +128,6 @@ static int gbaudio_module_disable(struct gbaudio_codec_info *codec,
|
||||||
module->ctrlstate[dir] = GBAUDIO_CODEC_SHUTDOWN;
|
module->ctrlstate[dir] = GBAUDIO_CODEC_SHUTDOWN;
|
||||||
|
|
||||||
func_exit:
|
func_exit:
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
mutex_unlock(&codec->lock);
|
mutex_unlock(&codec->lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -160,7 +158,6 @@ static int gbaudio_module_enable(struct gbaudio_codec_info *codec,
|
||||||
rate = codec->stream[dir].rate;
|
rate = codec->stream[dir].rate;
|
||||||
sig_bits = codec->stream[dir].sig_bits;
|
sig_bits = codec->stream[dir].sig_bits;
|
||||||
|
|
||||||
mutex_lock(&module->lock);
|
|
||||||
module_state = module->ctrlstate[dir];
|
module_state = module->ctrlstate[dir];
|
||||||
if (module_state == codec_state) {
|
if (module_state == codec_state) {
|
||||||
dev_dbg(codec->dev, "%s: module already configured\n",
|
dev_dbg(codec->dev, "%s: module already configured\n",
|
||||||
|
@ -272,7 +269,6 @@ static int gbaudio_module_enable(struct gbaudio_codec_info *codec,
|
||||||
|
|
||||||
func_exit:
|
func_exit:
|
||||||
module->ctrlstate[dir] = module_state;
|
module->ctrlstate[dir] = module_state;
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
mutex_unlock(&codec->lock);
|
mutex_unlock(&codec->lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -342,18 +338,11 @@ static int gbcodec_startup(struct snd_pcm_substream *substream,
|
||||||
|
|
||||||
state = codec->stream[substream->stream].state;
|
state = codec->stream[substream->stream].state;
|
||||||
list_for_each_entry(module, &codec->module_list, list) {
|
list_for_each_entry(module, &codec->module_list, list) {
|
||||||
mutex_lock(&module->lock);
|
|
||||||
if (!module->is_connected) {
|
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find the dai */
|
/* find the dai */
|
||||||
data = find_data(module, dai->name);
|
data = find_data(module, dai->name);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
dev_err(dai->dev, "%s:%s DATA connection missing\n",
|
dev_err(dai->dev, "%s:%s DATA connection missing\n",
|
||||||
dai->name, module->name);
|
dai->name, module->name);
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -375,7 +364,6 @@ static int gbcodec_startup(struct snd_pcm_substream *substream,
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(dai->dev, "Inavlid stream\n");
|
dev_err(dai->dev, "Inavlid stream\n");
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
mutex_unlock(&codec->lock);
|
mutex_unlock(&codec->lock);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -384,7 +372,6 @@ static int gbcodec_startup(struct snd_pcm_substream *substream,
|
||||||
state = GBAUDIO_CODEC_STARTUP;
|
state = GBAUDIO_CODEC_STARTUP;
|
||||||
module->ctrlstate[substream->stream] = state;
|
module->ctrlstate[substream->stream] = state;
|
||||||
dev_dbg(dai->dev, "%s: state:%d\n", module->name, state);
|
dev_dbg(dai->dev, "%s: state:%d\n", module->name, state);
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
}
|
}
|
||||||
codec->stream[substream->stream].state = state;
|
codec->stream[substream->stream].state = state;
|
||||||
codec->stream[substream->stream].dai_name = dai->name;
|
codec->stream[substream->stream].dai_name = dai->name;
|
||||||
|
@ -492,19 +479,11 @@ static void gbcodec_shutdown(struct snd_pcm_substream *substream,
|
||||||
|
|
||||||
state = codec->stream[substream->stream].state;
|
state = codec->stream[substream->stream].state;
|
||||||
list_for_each_entry(module, &codec->module_list, list) {
|
list_for_each_entry(module, &codec->module_list, list) {
|
||||||
mutex_lock(&module->lock);
|
|
||||||
if (!module->is_connected) {
|
|
||||||
dev_err(dai->dev, "%s:%s module not connected\n",
|
|
||||||
__func__, module->name);
|
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* find the dai */
|
/* find the dai */
|
||||||
data = find_data(module, dai->name);
|
data = find_data(module, dai->name);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
dev_err(dai->dev, "%s:%s DATA connection missing\n",
|
dev_err(dai->dev, "%s:%s DATA connection missing\n",
|
||||||
dai->name, module->name);
|
dai->name, module->name);
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,7 +502,6 @@ static void gbcodec_shutdown(struct snd_pcm_substream *substream,
|
||||||
state = GBAUDIO_CODEC_SHUTDOWN;
|
state = GBAUDIO_CODEC_SHUTDOWN;
|
||||||
module->ctrlstate[substream->stream] = state;
|
module->ctrlstate[substream->stream] = state;
|
||||||
dev_dbg(dai->dev, "%s: state:%d\n", module->name, state);
|
dev_dbg(dai->dev, "%s: state:%d\n", module->name, state);
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
}
|
}
|
||||||
codec->stream[substream->stream].state = state;
|
codec->stream[substream->stream].state = state;
|
||||||
codec->stream[substream->stream].dai_name = NULL;
|
codec->stream[substream->stream].dai_name = NULL;
|
||||||
|
@ -583,21 +561,11 @@ static int gbcodec_hw_params(struct snd_pcm_substream *substream,
|
||||||
|
|
||||||
state = codec->stream[substream->stream].state;
|
state = codec->stream[substream->stream].state;
|
||||||
list_for_each_entry(module, &codec->module_list, list) {
|
list_for_each_entry(module, &codec->module_list, list) {
|
||||||
mutex_lock(&module->lock);
|
|
||||||
if (!module->is_connected) {
|
|
||||||
dev_err(dai->dev, "%s:%s module not connected\n",
|
|
||||||
__func__, module->name);
|
|
||||||
ret = -ENODEV;
|
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find the data connection */
|
/* find the data connection */
|
||||||
data = find_data(module, dai->name);
|
data = find_data(module, dai->name);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
dev_err(dai->dev, "%s:%s DATA connection missing\n",
|
dev_err(dai->dev, "%s:%s DATA connection missing\n",
|
||||||
dai->name, module->name);
|
dai->name, module->name);
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -612,7 +580,6 @@ static int gbcodec_hw_params(struct snd_pcm_substream *substream,
|
||||||
format, rate, channels, sig_bits);
|
format, rate, channels, sig_bits);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dai->dev, "%d: Error during set_pcm\n", ret);
|
dev_err(dai->dev, "%d: Error during set_pcm\n", ret);
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
if (state < GBAUDIO_CODEC_HWPARAMS) {
|
if (state < GBAUDIO_CODEC_HWPARAMS) {
|
||||||
|
@ -623,14 +590,12 @@ static int gbcodec_hw_params(struct snd_pcm_substream *substream,
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dai->dev,
|
dev_err(dai->dev,
|
||||||
"%d: Error during set_config\n", ret);
|
"%d: Error during set_config\n", ret);
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state = GBAUDIO_CODEC_HWPARAMS;
|
state = GBAUDIO_CODEC_HWPARAMS;
|
||||||
module->ctrlstate[substream->stream] = state;
|
module->ctrlstate[substream->stream] = state;
|
||||||
dev_dbg(dai->dev, "%s: state:%d\n", module->name, state);
|
dev_dbg(dai->dev, "%s: state:%d\n", module->name, state);
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
}
|
}
|
||||||
codec->stream[substream->stream].state = state;
|
codec->stream[substream->stream].state = state;
|
||||||
codec->stream[substream->stream].format = format;
|
codec->stream[substream->stream].format = format;
|
||||||
|
@ -731,18 +696,11 @@ static int gbcodec_prepare(struct snd_pcm_substream *substream,
|
||||||
|
|
||||||
state = codec->stream[substream->stream].state;
|
state = codec->stream[substream->stream].state;
|
||||||
list_for_each_entry(module, &codec->module_list, list) {
|
list_for_each_entry(module, &codec->module_list, list) {
|
||||||
mutex_lock(&module->lock);
|
|
||||||
if (!module->is_connected) {
|
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find the dai */
|
/* find the dai */
|
||||||
data = find_data(module, dai->name);
|
data = find_data(module, dai->name);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
dev_err(dai->dev, "%s:%s DATA connection missing\n",
|
dev_err(dai->dev, "%s:%s DATA connection missing\n",
|
||||||
dai->name, module->name);
|
dai->name, module->name);
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -759,14 +717,12 @@ static int gbcodec_prepare(struct snd_pcm_substream *substream,
|
||||||
if (ret == -ENODEV)
|
if (ret == -ENODEV)
|
||||||
continue;
|
continue;
|
||||||
if (ret) {
|
if (ret) {
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
state = GBAUDIO_CODEC_PREPARE;
|
state = GBAUDIO_CODEC_PREPARE;
|
||||||
module->ctrlstate[substream->stream] = state;
|
module->ctrlstate[substream->stream] = state;
|
||||||
dev_dbg(dai->dev, "%s: state:%d\n", module->name, state);
|
dev_dbg(dai->dev, "%s: state:%d\n", module->name, state);
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
}
|
}
|
||||||
codec->stream[substream->stream].state = state;
|
codec->stream[substream->stream].state = state;
|
||||||
|
|
||||||
|
@ -824,12 +780,6 @@ static int gbcodec_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry(module, &codec->module_list, list) {
|
list_for_each_entry(module, &codec->module_list, list) {
|
||||||
mutex_lock(&module->lock);
|
|
||||||
if (!module->is_connected) {
|
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find the dai */
|
/* find the dai */
|
||||||
data = find_data(module, dai->name);
|
data = find_data(module, dai->name);
|
||||||
if (data)
|
if (data)
|
||||||
|
@ -839,7 +789,6 @@ static int gbcodec_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||||
dev_err(dai->dev, "%s:%s DATA connection missing\n",
|
dev_err(dai->dev, "%s:%s DATA connection missing\n",
|
||||||
dai->name, module->name);
|
dai->name, module->name);
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
goto func_exit;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
if (start && tx) {
|
if (start && tx) {
|
||||||
|
@ -873,7 +822,6 @@ static int gbcodec_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||||
if (ret)
|
if (ret)
|
||||||
dev_err(dai->dev, "%s:Error during %s stream:%d\n",
|
dev_err(dai->dev, "%s:Error during %s stream:%d\n",
|
||||||
module->name, start ? "Start" : "Stop", ret);
|
module->name, start ? "Start" : "Stop", ret);
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
|
|
||||||
func_exit:
|
func_exit:
|
||||||
mutex_unlock(&codec->lock);
|
mutex_unlock(&codec->lock);
|
||||||
|
@ -1118,7 +1066,6 @@ void gbaudio_unregister_module(struct gbaudio_module_info *module)
|
||||||
down_write(&card->controls_rwsem);
|
down_write(&card->controls_rwsem);
|
||||||
mutex_lock(&gbcodec->lock);
|
mutex_lock(&gbcodec->lock);
|
||||||
dev_dbg(codec->dev, "Process Unregister %s module\n", module->name);
|
dev_dbg(codec->dev, "Process Unregister %s module\n", module->name);
|
||||||
mutex_lock(&module->lock);
|
|
||||||
|
|
||||||
#ifdef CONFIG_SND_JACK
|
#ifdef CONFIG_SND_JACK
|
||||||
/* free jack devices for this module from codec->jack_list */
|
/* free jack devices for this module from codec->jack_list */
|
||||||
|
@ -1133,7 +1080,6 @@ void gbaudio_unregister_module(struct gbaudio_module_info *module)
|
||||||
|
|
||||||
gbaudio_codec_cleanup(module);
|
gbaudio_codec_cleanup(module);
|
||||||
|
|
||||||
module->is_connected = 0;
|
|
||||||
if (module->dapm_routes) {
|
if (module->dapm_routes) {
|
||||||
dev_dbg(codec->dev, "Removing %d routes\n",
|
dev_dbg(codec->dev, "Removing %d routes\n",
|
||||||
module->num_dapm_routes);
|
module->num_dapm_routes);
|
||||||
|
@ -1153,8 +1099,6 @@ void gbaudio_unregister_module(struct gbaudio_module_info *module)
|
||||||
module->num_dapm_widgets);
|
module->num_dapm_widgets);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
|
|
||||||
list_del(&module->list);
|
list_del(&module->list);
|
||||||
dev_dbg(codec->dev, "Unregistered %s module\n", module->name);
|
dev_dbg(codec->dev, "Unregistered %s module\n", module->name);
|
||||||
|
|
||||||
|
|
|
@ -172,8 +172,6 @@ struct gbaudio_module_info {
|
||||||
struct snd_soc_jack button_jack;
|
struct snd_soc_jack button_jack;
|
||||||
|
|
||||||
/* used by codec_ops */
|
/* used by codec_ops */
|
||||||
struct mutex lock;
|
|
||||||
int is_connected;
|
|
||||||
int ctrlstate[2]; /* PB/CAP */
|
int ctrlstate[2]; /* PB/CAP */
|
||||||
|
|
||||||
/* connection info */
|
/* connection info */
|
||||||
|
|
|
@ -26,12 +26,10 @@ static int gbaudio_request_jack(struct gbaudio_module_info *module,
|
||||||
dev_warn(module->dev, "Jack Event received: type: %u, event: %u\n",
|
dev_warn(module->dev, "Jack Event received: type: %u, event: %u\n",
|
||||||
req->jack_attribute, req->event);
|
req->jack_attribute, req->event);
|
||||||
|
|
||||||
mutex_lock(&module->lock);
|
|
||||||
if (req->event == GB_AUDIO_JACK_EVENT_REMOVAL) {
|
if (req->event == GB_AUDIO_JACK_EVENT_REMOVAL) {
|
||||||
module->jack_type = 0;
|
module->jack_type = 0;
|
||||||
button_status = module->button_status;
|
button_status = module->button_status;
|
||||||
module->button_status = 0;
|
module->button_status = 0;
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
if (button_status)
|
if (button_status)
|
||||||
snd_soc_jack_report(&module->button_jack, 0,
|
snd_soc_jack_report(&module->button_jack, 0,
|
||||||
GBCODEC_JACK_BUTTON_MASK);
|
GBCODEC_JACK_BUTTON_MASK);
|
||||||
|
@ -48,7 +46,6 @@ static int gbaudio_request_jack(struct gbaudio_module_info *module,
|
||||||
module->jack_type, report);
|
module->jack_type, report);
|
||||||
|
|
||||||
module->jack_type = report;
|
module->jack_type = report;
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
snd_soc_jack_report(&module->headset_jack, report, GBCODEC_JACK_MASK);
|
snd_soc_jack_report(&module->headset_jack, report, GBCODEC_JACK_MASK);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -63,10 +60,8 @@ static int gbaudio_request_button(struct gbaudio_module_info *module,
|
||||||
req->button_id, req->event);
|
req->button_id, req->event);
|
||||||
|
|
||||||
/* currently supports 4 buttons only */
|
/* currently supports 4 buttons only */
|
||||||
mutex_lock(&module->lock);
|
|
||||||
if (!module->jack_type) {
|
if (!module->jack_type) {
|
||||||
dev_err(module->dev, "Jack not present. Bogus event!!\n");
|
dev_err(module->dev, "Jack not present. Bogus event!!\n");
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,8 +95,6 @@ static int gbaudio_request_button(struct gbaudio_module_info *module,
|
||||||
|
|
||||||
module->button_status = report;
|
module->button_status = report;
|
||||||
|
|
||||||
mutex_unlock(&module->lock);
|
|
||||||
|
|
||||||
snd_soc_jack_report(&module->button_jack, report,
|
snd_soc_jack_report(&module->button_jack, report,
|
||||||
GBCODEC_JACK_BUTTON_MASK);
|
GBCODEC_JACK_BUTTON_MASK);
|
||||||
|
|
||||||
|
@ -247,7 +240,6 @@ static int gb_audio_probe(struct gb_bundle *bundle,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
gbmodule->num_data_connections = bundle->num_cports - 1;
|
gbmodule->num_data_connections = bundle->num_cports - 1;
|
||||||
mutex_init(&gbmodule->lock);
|
|
||||||
INIT_LIST_HEAD(&gbmodule->data_list);
|
INIT_LIST_HEAD(&gbmodule->data_list);
|
||||||
INIT_LIST_HEAD(&gbmodule->widget_list);
|
INIT_LIST_HEAD(&gbmodule->widget_list);
|
||||||
INIT_LIST_HEAD(&gbmodule->ctl_list);
|
INIT_LIST_HEAD(&gbmodule->ctl_list);
|
||||||
|
@ -327,7 +319,6 @@ static int gb_audio_probe(struct gb_bundle *bundle,
|
||||||
if (ret)
|
if (ret)
|
||||||
goto disable_data_connection;
|
goto disable_data_connection;
|
||||||
}
|
}
|
||||||
gbmodule->is_connected = 1;
|
|
||||||
|
|
||||||
/* inform above layer for uevent */
|
/* inform above layer for uevent */
|
||||||
dev_dbg(dev, "Inform set_event:%d to above layer\n", 1);
|
dev_dbg(dev, "Inform set_event:%d to above layer\n", 1);
|
||||||
|
|
Loading…
Reference in New Issue