struct gbaudio_dai *gb_dai;
struct gbaudio_codec_info *gb = dev_get_drvdata(dai->dev);
+ if (!atomic_read(&gb->is_connected))
+ return -ENODEV;
+
/* find the dai */
mutex_lock(&gb->lock);
gb_dai = gbaudio_find_dai(gb, -1, dai->name);
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);
struct gbaudio_dai *gb_dai;
struct gbaudio_codec_info *gb = dev_get_drvdata(dai->dev);
+ if (!atomic_read(&gb->is_connected))
+ return -ENODEV;
+
/* find the dai */
mutex_lock(&gb->lock);
gb_dai = gbaudio_find_dai(gb, -1, dai->name);
struct gbaudio_dai *gb_dai;
struct gbaudio_codec_info *gb = dev_get_drvdata(dai->dev);
+ if (!atomic_read(&gb->is_connected))
+ return -ENODEV;
+
/* find the dai */
mutex_lock(&gb->lock);
gb_dai = gbaudio_find_dai(gb, -1, dai->name);
struct gbaudio_dai *gb_dai;
struct gbaudio_codec_info *gb = dev_get_drvdata(dai->dev);
+ if (!atomic_read(&gb->is_connected))
+ return -ENODEV;
+
/* find the dai */
mutex_lock(&gb->lock);
gb_dai = gbaudio_find_dai(gb, -1, dai->name);
desc.devices = 0x2; /* todo */
gbcodec->manager_id = gb_audio_manager_add(&desc);
+ atomic_set(&gbcodec->is_connected, 1);
list_add(&gbcodec->list, &gb_codec_list);
dev_dbg(dev, "Add GB Audio device:%s\n", gbcodec->name);
mutex_unlock(&gb_codec_list_lock);
struct gbaudio_dai *dai, *_dai;
mutex_lock(&gb_codec_list_lock);
+ atomic_set(&gbcodec->is_connected, 0);
list_del(&gbcodec->list);
/* inform uevent to above layers */
gb_audio_manager_remove(gbcodec->manager_id);
int manager_id;
char name[NAME_SIZE];
+ /*
+ * there can be a rece condition between gb_audio_disconnect()
+ * and dai->trigger from above ASoC layer.
+ * To avoid any deadlock over codec_info->lock, atomic variable
+ * is used.
+ */
+ atomic_t is_connected;
+ struct mutex lock;
+
/* soc related data */
struct snd_soc_codec *codec;
struct device *dev;
struct list_head widget_list;
struct list_head codec_ctl_list;
struct list_head widget_ctl_list;
- struct mutex lock;
};
struct gbaudio_dai *gbaudio_find_dai(struct gbaudio_codec_info *gbcodec,
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
+ if (!atomic_read(&gb->is_connected))
+ return -ENODEV;
+
data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
info = (struct gb_audio_ctl_elem_info *)data->info;
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
+ if (!atomic_read(&gb->is_connected))
+ return -ENODEV;
+
data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
info = (struct gb_audio_ctl_elem_info *)data->info;
struct snd_soc_codec *codec = widget->codec;
struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
+ if (!atomic_read(&gb->is_connected))
+ return -ENODEV;
+
data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
info = (struct gb_audio_ctl_elem_info *)data->info;
struct snd_soc_codec *codec = widget->codec;
struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
+ if (!atomic_read(&gb->is_connected))
+ return -ENODEV;
+
data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
info = (struct gb_audio_ctl_elem_info *)data->info;