struct gbaudio_dai *gb_dai;
struct gbaudio_codec_info *gb = dev_get_drvdata(dai->dev);
- if (!atomic_read(&gb->is_connected))
- return;
-
/* find the dai */
- mutex_lock(&gb->lock);
gb_dai = gbaudio_find_dai(gb, -1, dai->name);
if (!gb_dai) {
dev_err(dai->dev, "%s: DAI not registered\n", dai->name);
atomic_dec(&gb_dai->users);
+ if (!atomic_read(&gb->is_connected)) {
+ if (!atomic_read(&gb_dai->users))
+ wake_up_interruptible(&gb_dai->wait_queue);
+ return;
+ }
+
+ mutex_lock(&gb->lock);
/* deactivate rx/tx */
cportid = gb_dai->connection->intf_cport_id;
func_exit:
mutex_unlock(&gb->lock);
+ /*
+ if (!atomic_read(&gb_dai->users))
+ wake_up_interruptible(&gb_dai->wait_queue);
+ */
+
return;
}
struct gbaudio_dai *gb_dai;
struct gbaudio_codec_info *gb = dev_get_drvdata(dai->dev);
- if (!atomic_read(&gb->is_connected))
+ if (!atomic_read(&gb->is_connected)) {
+ if (cmd == SNDRV_PCM_TRIGGER_STOP)
+ return 0;
return -ENODEV;
+ }
/* find the dai */
mutex_lock(&gb->lock);
*/
static void gb_audio_cleanup(struct gbaudio_codec_info *gb)
{
- int cportid, ret;
+ int cportid, ret, timeout_result;
struct gbaudio_dai *gb_dai;
struct gb_connection *connection;
+ long timeout = msecs_to_jiffies(50); /* 50ms */
struct device *dev = gb->dev;
list_for_each_entry(gb_dai, &gb->dai_list, list) {
* manually
*/
if (atomic_read(&gb_dai->users)) {
+ /* schedule a wait event */
+ timeout_result =
+ wait_event_interruptible_timeout(
+ gb_dai->wait_queue,
+ !atomic_read(&gb_dai->users),
+ timeout);
+ if (!timeout_result)
+ dev_warn(dev, "%s:DAI still in use.\n",
+ gb_dai->name);
+
connection = gb_dai->connection;
/* PB active */
ret = gb_audio_apbridgea_stop_tx(connection, 0);
if (ret)
dev_info(dev, "%d:Failed during unregister cport\n",
ret);
- atomic_dec(&gb_dai->users);
}
}
}
connection->private = gbcodec;
atomic_set(&dai->users, 0);
+ init_waitqueue_head(&dai->wait_queue);
dai->data_cport = connection->intf_cport_id;
dai->connection = connection;
list_add(&dai->list, &gbcodec->dai_list);