Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a2f6309e authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: hda - Add power on/off counter



Added the power on/off counter and expose via sysfs files.
The sysfs files, power_on_acct and power_off_acct, are created under
each codec hwdep sysfs directory (e.g. /sys/class/sound/hwC0D0).
The files show the msec length of the codec power-on and power-off,
respectively.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 8f217a22
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -515,6 +515,7 @@ static int snd_hda_bus_dev_register(struct snd_device *device)
	struct hda_codec *codec;
	list_for_each_entry(codec, &bus->codec_list, list) {
		snd_hda_hwdep_add_sysfs(codec);
		snd_hda_hwdep_add_power_sysfs(codec);
	}
	return 0;
}
@@ -2452,9 +2453,11 @@ static void hda_call_codec_suspend(struct hda_codec *codec)
			    codec->afg ? codec->afg : codec->mfg,
			    AC_PWRST_D3);
#ifdef CONFIG_SND_HDA_POWER_SAVE
	snd_hda_update_power_acct(codec);
	cancel_delayed_work(&codec->power_work);
	codec->power_on = 0;
	codec->power_transition = 0;
	codec->power_jiffies = jiffies;
#endif
}

@@ -3191,6 +3194,17 @@ static void hda_keep_power_on(struct hda_codec *codec)
{
	codec->power_count++;
	codec->power_on = 1;
	codec->power_jiffies = jiffies;
}

void snd_hda_update_power_acct(struct hda_codec *codec)
{
	unsigned long delta = jiffies - codec->power_jiffies;
	if (codec->power_on)
		codec->power_on_acct += delta;
	else
		codec->power_off_acct += delta;
	codec->power_jiffies += delta;
}

void snd_hda_power_up(struct hda_codec *codec)
@@ -3201,7 +3215,9 @@ void snd_hda_power_up(struct hda_codec *codec)
	if (codec->power_on || codec->power_transition)
		return;

	snd_hda_update_power_acct(codec);
	codec->power_on = 1;
	codec->power_jiffies = jiffies;
	if (bus->ops.pm_notify)
		bus->ops.pm_notify(bus);
	hda_call_codec_resume(codec);
+4 −0
Original line number Diff line number Diff line
@@ -812,6 +812,9 @@ struct hda_codec {
	unsigned int power_transition :1; /* power-state in transition */
	int power_count;	/* current (global) power refcount */
	struct delayed_work power_work; /* delayed task for powerdown */
	unsigned long power_on_acct;
	unsigned long power_off_acct;
	unsigned long power_jiffies;
#endif

	/* codec-specific additional proc output */
@@ -936,6 +939,7 @@ const char *snd_hda_get_jack_location(u32 cfg);
void snd_hda_power_up(struct hda_codec *codec);
void snd_hda_power_down(struct hda_codec *codec);
#define snd_hda_codec_needs_resume(codec) codec->power_count
void snd_hda_update_power_acct(struct hda_codec *codec);
#else
static inline void snd_hda_power_up(struct hda_codec *codec) {}
static inline void snd_hda_power_down(struct hda_codec *codec) {}
+38 −0
Original line number Diff line number Diff line
@@ -154,6 +154,44 @@ int /*__devinit*/ snd_hda_create_hwdep(struct hda_codec *codec)
	return 0;
}

#ifdef CONFIG_SND_HDA_POWER_SAVE
static ssize_t power_on_acct_show(struct device *dev,
				  struct device_attribute *attr,
				  char *buf)
{
	struct snd_hwdep *hwdep = dev_get_drvdata(dev);
	struct hda_codec *codec = hwdep->private_data;
	snd_hda_update_power_acct(codec);
	return sprintf(buf, "%u\n", jiffies_to_msecs(codec->power_on_acct));
}

static ssize_t power_off_acct_show(struct device *dev,
				   struct device_attribute *attr,
				   char *buf)
{
	struct snd_hwdep *hwdep = dev_get_drvdata(dev);
	struct hda_codec *codec = hwdep->private_data;
	snd_hda_update_power_acct(codec);
	return sprintf(buf, "%u\n", jiffies_to_msecs(codec->power_off_acct));
}

static struct device_attribute power_attrs[] = {
	__ATTR_RO(power_on_acct),
	__ATTR_RO(power_off_acct),
};

int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec)
{
	struct snd_hwdep *hwdep = codec->hwdep;
	int i;

	for (i = 0; i < ARRAY_SIZE(power_attrs); i++)
		snd_add_device_sysfs_file(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card,
					  hwdep->device, &power_attrs[i]);
	return 0;
}
#endif /* CONFIG_SND_HDA_POWER_SAVE */

#ifdef CONFIG_SND_HDA_RECONFIG

/*
+9 −0
Original line number Diff line number Diff line
@@ -437,6 +437,15 @@ int snd_hda_create_hwdep(struct hda_codec *codec);
static inline int snd_hda_create_hwdep(struct hda_codec *codec) { return 0; }
#endif

#ifdef CONFIG_SND_HDA_POWER_SAVE
int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec);
#else
static inline int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec)
{
	return 0;
}
#endif

#ifdef CONFIG_SND_HDA_RECONFIG
int snd_hda_hwdep_add_sysfs(struct hda_codec *codec);
#else