aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2017-08-22 07:59:44 -0400
committerMark Brown <broonie@kernel.org>2017-08-22 08:38:35 -0400
commitbd29ae969042c87413157c02d4f2a787d0212da3 (patch)
tree2780978ae938a2f83e385e37892fac79b6e0bfd6
parent77a4525bc282b7072ebda5d6f6925ca6d604a16f (diff)
ASoC: jack: Manage gpios via devres
Let's be lazy -- this patch adds the devres code to snd_soc_jack_add_gpios() for releasing the gpio resources at device removal automagically. After this patch, you don't have to call snd_soc_jack_free_gpios() manually as long as it's managed from the machine driver. What about the gpios assigned in other levels? Well, you might still need to free the resources manually, depending on how the component unbind works. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/soc-jack.c52
1 files changed, 41 insertions, 11 deletions
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 42ca9f19843b..4c83734ae596 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -22,6 +22,12 @@
22#include <linux/suspend.h> 22#include <linux/suspend.h>
23#include <trace/events/asoc.h> 23#include <trace/events/asoc.h>
24 24
25struct jack_gpio_tbl {
26 int count;
27 struct snd_soc_jack *jack;
28 struct snd_soc_jack_gpio *gpios;
29};
30
25/** 31/**
26 * snd_soc_codec_set_jack - configure codec jack. 32 * snd_soc_codec_set_jack - configure codec jack.
27 * @codec: CODEC 33 * @codec: CODEC
@@ -333,6 +339,28 @@ static int snd_soc_jack_pm_notifier(struct notifier_block *nb,
333 return NOTIFY_DONE; 339 return NOTIFY_DONE;
334} 340}
335 341
342static void jack_free_gpios(struct snd_soc_jack *jack, int count,
343 struct snd_soc_jack_gpio *gpios)
344{
345 int i;
346
347 for (i = 0; i < count; i++) {
348 gpiod_unexport(gpios[i].desc);
349 unregister_pm_notifier(&gpios[i].pm_notifier);
350 free_irq(gpiod_to_irq(gpios[i].desc), &gpios[i]);
351 cancel_delayed_work_sync(&gpios[i].work);
352 gpiod_put(gpios[i].desc);
353 gpios[i].jack = NULL;
354 }
355}
356
357static void jack_devres_free_gpios(struct device *dev, void *res)
358{
359 struct jack_gpio_tbl *tbl = res;
360
361 jack_free_gpios(tbl->jack, tbl->count, tbl->gpios);
362}
363
336/** 364/**
337 * snd_soc_jack_add_gpios - Associate GPIO pins with an ASoC jack 365 * snd_soc_jack_add_gpios - Associate GPIO pins with an ASoC jack
338 * 366 *
@@ -347,6 +375,14 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
347 struct snd_soc_jack_gpio *gpios) 375 struct snd_soc_jack_gpio *gpios)
348{ 376{
349 int i, ret; 377 int i, ret;
378 struct jack_gpio_tbl *tbl;
379
380 tbl = devres_alloc(jack_devres_free_gpios, sizeof(*tbl), GFP_KERNEL);
381 if (!tbl)
382 return -ENOMEM;
383 tbl->jack = jack;
384 tbl->count = count;
385 tbl->gpios = gpios;
350 386
351 for (i = 0; i < count; i++) { 387 for (i = 0; i < count; i++) {
352 if (!gpios[i].name) { 388 if (!gpios[i].name) {
@@ -424,12 +460,14 @@ got_gpio:
424 msecs_to_jiffies(gpios[i].debounce_time)); 460 msecs_to_jiffies(gpios[i].debounce_time));
425 } 461 }
426 462
463 devres_add(jack->card->dev, tbl);
427 return 0; 464 return 0;
428 465
429err: 466err:
430 gpio_free(gpios[i].gpio); 467 gpio_free(gpios[i].gpio);
431undo: 468undo:
432 snd_soc_jack_free_gpios(jack, i, gpios); 469 jack_free_gpios(jack, i, gpios);
470 devres_free(tbl);
433 471
434 return ret; 472 return ret;
435} 473}
@@ -471,16 +509,8 @@ EXPORT_SYMBOL_GPL(snd_soc_jack_add_gpiods);
471void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count, 509void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
472 struct snd_soc_jack_gpio *gpios) 510 struct snd_soc_jack_gpio *gpios)
473{ 511{
474 int i; 512 jack_free_gpios(jack, count, gpios);
475 513 devres_destroy(jack->card->dev, jack_devres_free_gpios, NULL, NULL);
476 for (i = 0; i < count; i++) {
477 gpiod_unexport(gpios[i].desc);
478 unregister_pm_notifier(&gpios[i].pm_notifier);
479 free_irq(gpiod_to_irq(gpios[i].desc), &gpios[i]);
480 cancel_delayed_work_sync(&gpios[i].work);
481 gpiod_put(gpios[i].desc);
482 gpios[i].jack = NULL;
483 }
484} 514}
485EXPORT_SYMBOL_GPL(snd_soc_jack_free_gpios); 515EXPORT_SYMBOL_GPL(snd_soc_jack_free_gpios);
486#endif /* CONFIG_GPIOLIB */ 516#endif /* CONFIG_GPIOLIB */