Fix: close work_switch when codec removeing
This commit is contained in:
parent
d0d9107c91
commit
0548a6d0a3
1 changed files with 6 additions and 39 deletions
45
ac101.c
45
ac101.c
|
@ -105,13 +105,6 @@ int ac101_update_bits(struct snd_soc_codec *codec, unsigned reg,
|
||||||
#define KEY_HEADSETHOOK 226 /* key define */
|
#define KEY_HEADSETHOOK 226 /* key define */
|
||||||
#define HEADSET_FILTER_CNT (10)
|
#define HEADSET_FILTER_CNT (10)
|
||||||
|
|
||||||
#define _AC101_CREATE_QUEUE 0
|
|
||||||
|
|
||||||
#if _AC101_CREATE_QUEUE
|
|
||||||
static struct workqueue_struct *queue_switch_detect;
|
|
||||||
static struct workqueue_struct *queue_codec_irq;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* switch_hw_config:config the 53 codec register
|
* switch_hw_config:config the 53 codec register
|
||||||
*/
|
*/
|
||||||
|
@ -199,11 +192,7 @@ static void work_cb_clear_irq(struct work_struct *work)
|
||||||
ac10x->irq_cntr--;
|
ac10x->irq_cntr--;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if _AC101_CREATE_QUEUE
|
|
||||||
if (0 == queue_work(queue_switch_detect, &ac10x->work_switch)) {
|
|
||||||
#else
|
|
||||||
if (0 == schedule_work(&ac10x->work_switch)) {
|
if (0 == schedule_work(&ac10x->work_switch)) {
|
||||||
#endif
|
|
||||||
ac10x->irq_cntr--;
|
ac10x->irq_cntr--;
|
||||||
AC101_DBG("[work_cb_clear_irq] add work struct failed!\n");
|
AC101_DBG("[work_cb_clear_irq] add work struct failed!\n");
|
||||||
}
|
}
|
||||||
|
@ -218,7 +207,9 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __ac101_get_hmic_data(struct snd_soc_codec *codec) {
|
static int __ac101_get_hmic_data(struct snd_soc_codec *codec) {
|
||||||
|
#ifdef AC101_DEBG
|
||||||
static long counter;
|
static long counter;
|
||||||
|
#endif
|
||||||
int r;
|
int r;
|
||||||
int d;
|
int d;
|
||||||
|
|
||||||
|
@ -315,7 +306,7 @@ static void work_cb_earphone_switch(struct work_struct *work)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (ac10x->irq_cntr == 0) {
|
while (ac10x->irq_cntr == 0 && ac10x->irq != 0) {
|
||||||
msleep(20);
|
msleep(20);
|
||||||
|
|
||||||
t = __ac101_get_hmic_data(codec);
|
t = __ac101_get_hmic_data(codec);
|
||||||
|
@ -357,17 +348,7 @@ static irqreturn_t audio_hmic_irq(int irq, void *para)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if _AC101_CREATE_QUEUE
|
|
||||||
if (queue_codec_irq == NULL) {
|
|
||||||
AC101_DBG("------------queue_codec_irq is null !!----------");
|
|
||||||
return IRQ_NONE;
|
|
||||||
}
|
|
||||||
if (0 == queue_work(queue_codec_irq, &ac10x->work_clear_irq)){
|
|
||||||
|
|
||||||
#else
|
|
||||||
if (0 == schedule_work(&ac10x->work_clear_irq)){
|
if (0 == schedule_work(&ac10x->work_clear_irq)){
|
||||||
#endif
|
|
||||||
|
|
||||||
AC101_DBG("[audio_hmic_irq] work already in queue_codec_irq, adding failed!\n");
|
AC101_DBG("[audio_hmic_irq] work already in queue_codec_irq, adding failed!\n");
|
||||||
}
|
}
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
|
@ -437,27 +418,10 @@ static int ac101_switch_probe(struct ac10x_priv *ac10x) {
|
||||||
/* the first headset state checking */
|
/* the first headset state checking */
|
||||||
switch_hw_config(ac10x->codec);
|
switch_hw_config(ac10x->codec);
|
||||||
ac10x->irq_cntr = 1;
|
ac10x->irq_cntr = 1;
|
||||||
#if _AC101_CREATE_QUEUE
|
|
||||||
queue_codec_irq = create_singlethread_workqueue("codec_irq");
|
|
||||||
queue_switch_detect = create_singlethread_workqueue("codec_switch");
|
|
||||||
if (queue_switch_detect == NULL || queue_codec_irq == NULL) {
|
|
||||||
AC101_DBG("try to create workqueue for codec failed!\n");
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto _err_switch_work_queue;
|
|
||||||
}
|
|
||||||
|
|
||||||
queue_work(queue_switch_detect, &ac10x->work_switch);
|
|
||||||
#else
|
|
||||||
schedule_work(&ac10x->work_switch);
|
schedule_work(&ac10x->work_switch);
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#if _AC101_CREATE_QUEUE
|
|
||||||
_err_switch_work_queue:
|
|
||||||
|
|
||||||
input_unregister_device(ac10x->inpdev);
|
|
||||||
#endif
|
|
||||||
_err_input_register_device:
|
_err_input_register_device:
|
||||||
_err_input_allocate_device:
|
_err_input_allocate_device:
|
||||||
|
|
||||||
|
@ -1479,6 +1443,9 @@ int ac101_codec_remove(struct snd_soc_codec *codec)
|
||||||
/* devm_free_irq(codec->dev, ac10x->irq, NULL); */
|
/* devm_free_irq(codec->dev, ac10x->irq, NULL); */
|
||||||
ac10x->irq = 0;
|
ac10x->irq = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cancel_work_sync(&ac10x->work_switch) != 0) {
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue