/* pointer to hid device */
struct hid_device *hdev;
+ struct mutex hdev_lock;
};
static int atvr_mic_ctrl(struct hid_device *hdev, bool enable)
struct snd_pcm_runtime *runtime = substream->runtime;
int ret;
+ mutex_lock(&atvr_snd->hdev_lock);
if (atvr_snd->hdev == NULL) {
pr_warn("%s: remote is not ready\n", __func__);
+ mutex_unlock(&atvr_snd->hdev_lock);
return -EAGAIN;
}
ret = atvr_mic_ctrl(atvr_snd->hdev, true);
+ mutex_unlock(&atvr_snd->hdev_lock);
if (ret)
return ret;
}
spin_unlock(&s_substream_lock);
+ mutex_lock(&atvr_snd->hdev_lock);
if (atvr_snd->hdev)
atvr_mic_ctrl(atvr_snd->hdev, false);
else
pr_warn("%s: unexpected remote connection lost\n", __func__);
+ mutex_unlock(&atvr_snd->hdev_lock);
return 0;
}
}
atvr_snd = atvr_card->private_data;
atvr_snd->card = atvr_card;
+ mutex_init(&atvr_snd->hdev_lock);
/* dummy initialization */
setup_timer(&atvr_snd->decoding_timer,
static void atvr_remove(struct hid_device *hdev)
{
- struct snd_atvr *atvr_snd = hid_get_drvdata(hdev);
+ struct snd_atvr *atvr_snd;
+ unsigned long flags;
+
+ if (atvr_card == NULL)
+ return -EIO;
+ atvr_snd = atvr_card->private_data;
+ mutex_lock(&atvr_snd->hdev_lock);
atvr_snd->hdev = NULL;
+ mutex_unlock(&atvr_snd->hdev_lock);
switch_set_state(&shdr_mic_switch, false);
hid_set_drvdata(hdev, NULL);
misc_deregister(&pcm_dev_node);
#endif
+ if (atvr_card) {
+ struct snd_atvr *atvr_snd = atvr_card->private_data;
+ mutex_destroy(&atvr_snd->hdev_lock);
+ snd_card_free(atvr_card);
+ atvr_card = NULL;
+ }
+
hid_unregister_driver(&atvr_driver);
}