[alsa-devel] [RFC PATCH] ALSA: hda - suspend codecs in parallel

Takashi Iwai tiwai at suse.de
Tue Nov 26 07:35:45 CET 2013


At Tue, 26 Nov 2013 05:44:43 +0000,
Lin, Mengdong wrote:
> 
> Hi Takashi,
> 
> > -----Original Message-----
> > From: Takashi Iwai [mailto:tiwai at suse.de]
> > Sent: Monday, November 25, 2013 6:51 PM
> 
> > >  int snd_hda_suspend(struct hda_bus *bus)  {
> > >  	struct hda_codec *codec;
> > > +	unsigned int mask = 0;
> > >
> > >  	list_for_each_entry(codec, &bus->codec_list, list) {
> > >  		cancel_delayed_work_sync(&codec->jackpoll_work);
> > > -		if (hda_codec_is_power_on(codec))
> > > -			hda_call_codec_suspend(codec, false);
> > > +		if (hda_codec_is_power_on(codec)) {
> > > +			if (codec->epss || bus->num_codecs == 1)
> > > +				hda_call_codec_suspend(codec, false);
> > 
> > What's the reason for codec->epss check exceptionally?
> 
> Check on codec->epss should be removed here. It's better to always parallel if there are multiple codecs.
> I had thought codec with EPSS support can change power state quickly and so we can tolerate not paralleling. 

OK.

> > > +			else {
> > > +				mask |= 1 << codec->addr;
> > > +				queue_work(codec->pm_wq, &codec->pm_work);
> > > +			}
> > > +		}
> > > +	}
> > > +
> > > +	list_for_each_entry(codec, &bus->codec_list, list) {
> > > +		if (mask & (1 << codec->addr))
> > > +			flush_work(&codec->pm_work);
> > > +
> > >  	}
> > 
> > I thought that the recent workqueue is performed asynchronously as
> > default (unless an ordered workqueue is used), so it should be enough to
> > have a single workqueue in the bus, and flush it.
> 
> If using the single work queue in the bus, I observe that the codecs are suspended one after one, not in parallel. 

You need to increase the max active of the queue via
workqueue_set_max_active().  Otherwise it's default to 1 when you
created via create_workqueue().  Also, it'd be better with WQ_UNBOUND
flag in this case, I guess.


Takashi


More information about the Alsa-devel mailing list