diff options
-rw-r--r-- | sound/pci/hda/hda_codec.c | 16 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 4 | ||||
-rw-r--r-- | sound/pci/hda/hda_hwdep.c | 38 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 9 |
4 files changed, 67 insertions, 0 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 2b787b013e93..444d9039c1ac 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -515,6 +515,7 @@ static int snd_hda_bus_dev_register(struct snd_device *device) | |||
515 | struct hda_codec *codec; | 515 | struct hda_codec *codec; |
516 | list_for_each_entry(codec, &bus->codec_list, list) { | 516 | list_for_each_entry(codec, &bus->codec_list, list) { |
517 | snd_hda_hwdep_add_sysfs(codec); | 517 | snd_hda_hwdep_add_sysfs(codec); |
518 | snd_hda_hwdep_add_power_sysfs(codec); | ||
518 | } | 519 | } |
519 | return 0; | 520 | return 0; |
520 | } | 521 | } |
@@ -2452,9 +2453,11 @@ static void hda_call_codec_suspend(struct hda_codec *codec) | |||
2452 | codec->afg ? codec->afg : codec->mfg, | 2453 | codec->afg ? codec->afg : codec->mfg, |
2453 | AC_PWRST_D3); | 2454 | AC_PWRST_D3); |
2454 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 2455 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
2456 | snd_hda_update_power_acct(codec); | ||
2455 | cancel_delayed_work(&codec->power_work); | 2457 | cancel_delayed_work(&codec->power_work); |
2456 | codec->power_on = 0; | 2458 | codec->power_on = 0; |
2457 | codec->power_transition = 0; | 2459 | codec->power_transition = 0; |
2460 | codec->power_jiffies = jiffies; | ||
2458 | #endif | 2461 | #endif |
2459 | } | 2462 | } |
2460 | 2463 | ||
@@ -3191,6 +3194,17 @@ static void hda_keep_power_on(struct hda_codec *codec) | |||
3191 | { | 3194 | { |
3192 | codec->power_count++; | 3195 | codec->power_count++; |
3193 | codec->power_on = 1; | 3196 | codec->power_on = 1; |
3197 | codec->power_jiffies = jiffies; | ||
3198 | } | ||
3199 | |||
3200 | void snd_hda_update_power_acct(struct hda_codec *codec) | ||
3201 | { | ||
3202 | unsigned long delta = jiffies - codec->power_jiffies; | ||
3203 | if (codec->power_on) | ||
3204 | codec->power_on_acct += delta; | ||
3205 | else | ||
3206 | codec->power_off_acct += delta; | ||
3207 | codec->power_jiffies += delta; | ||
3194 | } | 3208 | } |
3195 | 3209 | ||
3196 | void snd_hda_power_up(struct hda_codec *codec) | 3210 | void snd_hda_power_up(struct hda_codec *codec) |
@@ -3201,7 +3215,9 @@ void snd_hda_power_up(struct hda_codec *codec) | |||
3201 | if (codec->power_on || codec->power_transition) | 3215 | if (codec->power_on || codec->power_transition) |
3202 | return; | 3216 | return; |
3203 | 3217 | ||
3218 | snd_hda_update_power_acct(codec); | ||
3204 | codec->power_on = 1; | 3219 | codec->power_on = 1; |
3220 | codec->power_jiffies = jiffies; | ||
3205 | if (bus->ops.pm_notify) | 3221 | if (bus->ops.pm_notify) |
3206 | bus->ops.pm_notify(bus); | 3222 | bus->ops.pm_notify(bus); |
3207 | hda_call_codec_resume(codec); | 3223 | hda_call_codec_resume(codec); |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index cbf199a98ab2..b16678cade18 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -812,6 +812,9 @@ struct hda_codec { | |||
812 | unsigned int power_transition :1; /* power-state in transition */ | 812 | unsigned int power_transition :1; /* power-state in transition */ |
813 | int power_count; /* current (global) power refcount */ | 813 | int power_count; /* current (global) power refcount */ |
814 | struct delayed_work power_work; /* delayed task for powerdown */ | 814 | struct delayed_work power_work; /* delayed task for powerdown */ |
815 | unsigned long power_on_acct; | ||
816 | unsigned long power_off_acct; | ||
817 | unsigned long power_jiffies; | ||
815 | #endif | 818 | #endif |
816 | 819 | ||
817 | /* codec-specific additional proc output */ | 820 | /* codec-specific additional proc output */ |
@@ -936,6 +939,7 @@ const char *snd_hda_get_jack_location(u32 cfg); | |||
936 | void snd_hda_power_up(struct hda_codec *codec); | 939 | void snd_hda_power_up(struct hda_codec *codec); |
937 | void snd_hda_power_down(struct hda_codec *codec); | 940 | void snd_hda_power_down(struct hda_codec *codec); |
938 | #define snd_hda_codec_needs_resume(codec) codec->power_count | 941 | #define snd_hda_codec_needs_resume(codec) codec->power_count |
942 | void snd_hda_update_power_acct(struct hda_codec *codec); | ||
939 | #else | 943 | #else |
940 | static inline void snd_hda_power_up(struct hda_codec *codec) {} | 944 | static inline void snd_hda_power_up(struct hda_codec *codec) {} |
941 | static inline void snd_hda_power_down(struct hda_codec *codec) {} | 945 | static inline void snd_hda_power_down(struct hda_codec *codec) {} |
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index cc24e6721d74..d24328661c6a 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c | |||
@@ -154,6 +154,44 @@ int /*__devinit*/ snd_hda_create_hwdep(struct hda_codec *codec) | |||
154 | return 0; | 154 | return 0; |
155 | } | 155 | } |
156 | 156 | ||
157 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
158 | static ssize_t power_on_acct_show(struct device *dev, | ||
159 | struct device_attribute *attr, | ||
160 | char *buf) | ||
161 | { | ||
162 | struct snd_hwdep *hwdep = dev_get_drvdata(dev); | ||
163 | struct hda_codec *codec = hwdep->private_data; | ||
164 | snd_hda_update_power_acct(codec); | ||
165 | return sprintf(buf, "%u\n", jiffies_to_msecs(codec->power_on_acct)); | ||
166 | } | ||
167 | |||
168 | static ssize_t power_off_acct_show(struct device *dev, | ||
169 | struct device_attribute *attr, | ||
170 | char *buf) | ||
171 | { | ||
172 | struct snd_hwdep *hwdep = dev_get_drvdata(dev); | ||
173 | struct hda_codec *codec = hwdep->private_data; | ||
174 | snd_hda_update_power_acct(codec); | ||
175 | return sprintf(buf, "%u\n", jiffies_to_msecs(codec->power_off_acct)); | ||
176 | } | ||
177 | |||
178 | static struct device_attribute power_attrs[] = { | ||
179 | __ATTR_RO(power_on_acct), | ||
180 | __ATTR_RO(power_off_acct), | ||
181 | }; | ||
182 | |||
183 | int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec) | ||
184 | { | ||
185 | struct snd_hwdep *hwdep = codec->hwdep; | ||
186 | int i; | ||
187 | |||
188 | for (i = 0; i < ARRAY_SIZE(power_attrs); i++) | ||
189 | snd_add_device_sysfs_file(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, | ||
190 | hwdep->device, &power_attrs[i]); | ||
191 | return 0; | ||
192 | } | ||
193 | #endif /* CONFIG_SND_HDA_POWER_SAVE */ | ||
194 | |||
157 | #ifdef CONFIG_SND_HDA_RECONFIG | 195 | #ifdef CONFIG_SND_HDA_RECONFIG |
158 | 196 | ||
159 | /* | 197 | /* |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 461e0c15c77a..015fbac914b3 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -437,6 +437,15 @@ int snd_hda_create_hwdep(struct hda_codec *codec); | |||
437 | static inline int snd_hda_create_hwdep(struct hda_codec *codec) { return 0; } | 437 | static inline int snd_hda_create_hwdep(struct hda_codec *codec) { return 0; } |
438 | #endif | 438 | #endif |
439 | 439 | ||
440 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
441 | int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec); | ||
442 | #else | ||
443 | static inline int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec) | ||
444 | { | ||
445 | return 0; | ||
446 | } | ||
447 | #endif | ||
448 | |||
440 | #ifdef CONFIG_SND_HDA_RECONFIG | 449 | #ifdef CONFIG_SND_HDA_RECONFIG |
441 | int snd_hda_hwdep_add_sysfs(struct hda_codec *codec); | 450 | int snd_hda_hwdep_add_sysfs(struct hda_codec *codec); |
442 | #else | 451 | #else |