aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-12-05 05:55:05 -0500
committerTakashi Iwai <tiwai@suse.de>2013-12-06 02:51:51 -0500
commitf4d6a55d7be3f5b944c17e6aafb84d96c4dd09d7 (patch)
treef2d63df469db8290b4ff346cf53c7f78ee20273a
parentb13a714923fe4d444977dccb7a0f7ad1346724cf (diff)
ALSA: hda - Clean up async codec PM using standard async infrastructure
This simplifies lots of codes indeed. Tested-by: Mengdong Lin <mengdong.lin@intel.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/hda_codec.c64
-rw-r--r--sound/pci/hda/hda_codec.h6
2 files changed, 19 insertions, 51 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 5b7622034eee..2e090c8d7144 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -26,6 +26,7 @@
26#include <linux/pci.h> 26#include <linux/pci.h>
27#include <linux/mutex.h> 27#include <linux/mutex.h>
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/async.h>
29#include <sound/core.h> 30#include <sound/core.h>
30#include "hda_codec.h" 31#include "hda_codec.h"
31#include <sound/asoundef.h> 32#include <sound/asoundef.h>
@@ -96,8 +97,6 @@ EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset);
96 97
97#ifdef CONFIG_PM 98#ifdef CONFIG_PM
98#define codec_in_pm(codec) ((codec)->in_pm) 99#define codec_in_pm(codec) ((codec)->in_pm)
99static void hda_suspend_work(struct work_struct *work);
100static void hda_resume_work(struct work_struct *work);
101static void hda_power_work(struct work_struct *work); 100static void hda_power_work(struct work_struct *work);
102static void hda_keep_power_on(struct hda_codec *codec); 101static void hda_keep_power_on(struct hda_codec *codec);
103#define hda_codec_is_power_on(codec) ((codec)->power_on) 102#define hda_codec_is_power_on(codec) ((codec)->power_on)
@@ -842,11 +841,6 @@ static int snd_hda_bus_free(struct hda_bus *bus)
842 if (bus->workq) 841 if (bus->workq)
843 destroy_workqueue(bus->workq); 842 destroy_workqueue(bus->workq);
844 843
845#ifdef CONFIG_PM
846 if (bus->pm_wq)
847 destroy_workqueue(bus->pm_wq);
848#endif
849
850 kfree(bus); 844 kfree(bus);
851 return 0; 845 return 0;
852} 846}
@@ -891,9 +885,6 @@ int snd_hda_bus_new(struct snd_card *card,
891 .dev_register = snd_hda_bus_dev_register, 885 .dev_register = snd_hda_bus_dev_register,
892 .dev_free = snd_hda_bus_dev_free, 886 .dev_free = snd_hda_bus_dev_free,
893 }; 887 };
894#ifdef CONFIG_PM
895 char wqname[16];
896#endif
897 888
898 if (snd_BUG_ON(!temp)) 889 if (snd_BUG_ON(!temp))
899 return -EINVAL; 890 return -EINVAL;
@@ -930,16 +921,6 @@ int snd_hda_bus_new(struct snd_card *card,
930 return -ENOMEM; 921 return -ENOMEM;
931 } 922 }
932 923
933#ifdef CONFIG_PM
934 sprintf(wqname, "hda-pm-wq-%d", card->number);
935 bus->pm_wq = create_workqueue(wqname);
936 if (!bus->pm_wq) {
937 snd_printk(KERN_ERR "cannot create PM workqueue\n");
938 snd_hda_bus_free(bus);
939 return -ENOMEM;
940 }
941#endif
942
943 err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops); 924 err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops);
944 if (err < 0) { 925 if (err < 0) {
945 snd_hda_bus_free(bus); 926 snd_hda_bus_free(bus);
@@ -1476,8 +1457,6 @@ int snd_hda_codec_new(struct hda_bus *bus,
1476#ifdef CONFIG_PM 1457#ifdef CONFIG_PM
1477 spin_lock_init(&codec->power_lock); 1458 spin_lock_init(&codec->power_lock);
1478 INIT_DELAYED_WORK(&codec->power_work, hda_power_work); 1459 INIT_DELAYED_WORK(&codec->power_work, hda_power_work);
1479 INIT_WORK(&codec->suspend_work, hda_suspend_work);
1480 INIT_WORK(&codec->resume_work, hda_resume_work);
1481 /* snd_hda_codec_new() marks the codec as power-up, and leave it as is. 1460 /* snd_hda_codec_new() marks the codec as power-up, and leave it as is.
1482 * the caller has to power down appropriatley after initialization 1461 * the caller has to power down appropriatley after initialization
1483 * phase. 1462 * phase.
@@ -1495,9 +1474,6 @@ int snd_hda_codec_new(struct hda_bus *bus,
1495 1474
1496 list_add_tail(&codec->list, &bus->codec_list); 1475 list_add_tail(&codec->list, &bus->codec_list);
1497 bus->num_codecs++; 1476 bus->num_codecs++;
1498#ifdef CONFIG_PM
1499 workqueue_set_max_active(bus->pm_wq, bus->num_codecs);
1500#endif
1501 1477
1502 bus->caddr_tbl[codec_addr] = codec; 1478 bus->caddr_tbl[codec_addr] = codec;
1503 1479
@@ -5120,22 +5096,6 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
5120 return 0; 5096 return 0;
5121} 5097}
5122EXPORT_SYMBOL_HDA(snd_hda_check_amp_list_power); 5098EXPORT_SYMBOL_HDA(snd_hda_check_amp_list_power);
5123
5124static void hda_suspend_work(struct work_struct *work)
5125{
5126 struct hda_codec *codec =
5127 container_of(work, struct hda_codec, suspend_work);
5128
5129 hda_call_codec_suspend(codec, false);
5130}
5131
5132static void hda_resume_work(struct work_struct *work)
5133{
5134 struct hda_codec *codec =
5135 container_of(work, struct hda_codec, resume_work);
5136
5137 hda_call_codec_resume(codec);
5138}
5139#endif 5099#endif
5140 5100
5141/* 5101/*
@@ -5699,6 +5659,17 @@ EXPORT_SYMBOL_HDA(snd_hda_add_imux_item);
5699 * power management 5659 * power management
5700 */ 5660 */
5701 5661
5662
5663static void hda_async_suspend(void *data, async_cookie_t cookie)
5664{
5665 hda_call_codec_suspend(data, false);
5666}
5667
5668static void hda_async_resume(void *data, async_cookie_t cookie)
5669{
5670 hda_call_codec_resume(data);
5671}
5672
5702/** 5673/**
5703 * snd_hda_suspend - suspend the codecs 5674 * snd_hda_suspend - suspend the codecs
5704 * @bus: the HDA bus 5675 * @bus: the HDA bus
@@ -5708,19 +5679,21 @@ EXPORT_SYMBOL_HDA(snd_hda_add_imux_item);
5708int snd_hda_suspend(struct hda_bus *bus) 5679int snd_hda_suspend(struct hda_bus *bus)
5709{ 5680{
5710 struct hda_codec *codec; 5681 struct hda_codec *codec;
5682 ASYNC_DOMAIN_EXCLUSIVE(domain);
5711 5683
5712 list_for_each_entry(codec, &bus->codec_list, list) { 5684 list_for_each_entry(codec, &bus->codec_list, list) {
5713 cancel_delayed_work_sync(&codec->jackpoll_work); 5685 cancel_delayed_work_sync(&codec->jackpoll_work);
5714 if (hda_codec_is_power_on(codec)) { 5686 if (hda_codec_is_power_on(codec)) {
5715 if (bus->num_codecs > 1) 5687 if (bus->num_codecs > 1)
5716 queue_work(bus->pm_wq, &codec->suspend_work); 5688 async_schedule_domain(hda_async_suspend, codec,
5689 &domain);
5717 else 5690 else
5718 hda_call_codec_suspend(codec, false); 5691 hda_call_codec_suspend(codec, false);
5719 } 5692 }
5720 } 5693 }
5721 5694
5722 if (bus->num_codecs > 1) 5695 if (bus->num_codecs > 1)
5723 flush_workqueue(bus->pm_wq); 5696 async_synchronize_full_domain(&domain);
5724 5697
5725 return 0; 5698 return 0;
5726} 5699}
@@ -5735,16 +5708,17 @@ EXPORT_SYMBOL_HDA(snd_hda_suspend);
5735int snd_hda_resume(struct hda_bus *bus) 5708int snd_hda_resume(struct hda_bus *bus)
5736{ 5709{
5737 struct hda_codec *codec; 5710 struct hda_codec *codec;
5711 ASYNC_DOMAIN_EXCLUSIVE(domain);
5738 5712
5739 list_for_each_entry(codec, &bus->codec_list, list) { 5713 list_for_each_entry(codec, &bus->codec_list, list) {
5740 if (bus->num_codecs > 1) 5714 if (bus->num_codecs > 1)
5741 queue_work(bus->pm_wq, &codec->resume_work); 5715 async_schedule_domain(hda_async_resume, codec, &domain);
5742 else 5716 else
5743 hda_call_codec_resume(codec); 5717 hda_call_codec_resume(codec);
5744 } 5718 }
5745 5719
5746 if (bus->num_codecs > 1) 5720 if (bus->num_codecs > 1)
5747 flush_workqueue(bus->pm_wq); 5721 async_synchronize_full_domain(&domain);
5748 5722
5749 return 0; 5723 return 0;
5750} 5724}
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 3ab4834761a8..260b190adf74 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -684,9 +684,6 @@ struct hda_bus {
684 struct hda_bus_unsolicited *unsol; 684 struct hda_bus_unsolicited *unsol;
685 char workq_name[16]; 685 char workq_name[16];
686 struct workqueue_struct *workq; /* common workqueue for codecs */ 686 struct workqueue_struct *workq; /* common workqueue for codecs */
687#ifdef CONFIG_PM
688 struct workqueue_struct *pm_wq; /* workqueue to parallel codec PM */
689#endif
690 687
691 /* assigned PCMs */ 688 /* assigned PCMs */
692 DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES); 689 DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES);
@@ -921,9 +918,6 @@ struct hda_codec {
921 unsigned long power_off_acct; 918 unsigned long power_off_acct;
922 unsigned long power_jiffies; 919 unsigned long power_jiffies;
923 spinlock_t power_lock; 920 spinlock_t power_lock;
924 /* tasks to parallel multi-codec suspend/resume */
925 struct work_struct suspend_work;
926 struct work_struct resume_work;
927#endif 921#endif
928 922
929 /* filter the requested power state per nid */ 923 /* filter the requested power state per nid */