[alsa-devel] [PATCH 4/7] ASoC: Intel: mrfld - add the dsp sst driver

Mark Brown broonie at kernel.org
Fri Jul 18 18:59:03 CEST 2014


On Fri, Jul 18, 2014 at 07:43:59PM +0530, Vinod Koul wrote:
> On Fri, Jul 18, 2014 at 12:35:48PM +0100, Mark Brown wrote:
> > On Wed, Jul 09, 2014 at 02:57:52PM +0530, Vinod Koul wrote:

> > Have you looked at the mailbox framework (not merged yet but hopefully
> > getting close to it)?

Not seeing an answer to this...

> > > +	if (list_empty(&drv->rx_list))
> > > +		return IRQ_HANDLED;

> > Why would the IRQ thread be running with nothing to do, and if it can
> > be...

> Cant think of, we need to remove this!

> > > +	spin_lock_irqsave(&drv->rx_msg_lock, irq_flags);
> > > +	list_for_each_entry_safe(msg, __msg, &drv->rx_list, node) {

> > ...won't we handle that gracefully anyway?

> Are you referring to lock + irqsave?

This is part of the thing about the list_empty() check being redundant.

> > > +static inline int sst_pm_runtime_put(struct intel_sst_drv *sst_drv)
> > > +{
> > > +	int ret;
> > > +
> > > +	ret = pm_runtime_put_sync(sst_drv->dev);
> > > +	if (ret < 0)
> > > +		return ret;
> > > +	atomic_dec(&sst_drv->pm_usage_count);
> > > +
> > > +	pr_debug("%s: count is %d now..\n", __func__,
> > > +			atomic_read(&sst_drv->pm_usage_count));
> > > +	return 0;
> > > +}

> > I'm not entirely clear why this is here but if it's to provide trace
> > just instrument the runtime PM core.

> Well the only usage of pm_usage_count locally is to check in runtime pm
> suspend to S3 transitions. When we are runtime suspended and S3 triggers,
> the device usage count goes up to 1. Then runtime resume and classic suspend
> is invoked in that order. So if we are in this scenario we can't rely on
> checks using frameworks count.

Yes, you can.  You can check to see if the device is runtime suspended
and really this isn't at all specific to this driver - it's a general
thing that affects lots of drivers so shouldn't be open coded in this
one.  IIRC you're looking for pm_runtime_is_suspended().

Essentially any time you need to use atomic variables in a driver you're
probably doing something wrong.

> > > +static inline unsigned int sst_assign_pvt_id(struct intel_sst_drv *sst_drv_ctx)
> > > +{
> > > +	unsigned int local;
> > > +
> > > +	spin_lock(&sst_drv_ctx->block_lock);
> > > +	sst_drv_ctx->pvt_id++;
> > > +	if (sst_drv_ctx->pvt_id > MAX_BLOCKS)
> > > +		sst_drv_ctx->pvt_id = 1;
> > > +	local = sst_drv_ctx->pvt_id;
> > > +	spin_unlock(&sst_drv_ctx->block_lock);
> > > +	return local;
> > > +}

> > I would expect this to be checking to see if the IDs are free but it
> > just hands them out in sequence?  There appears to be an array of
> > streams statically allocated, why not look there for an unused one?

> we use these incrementally. The driver stamps each IPC to DSP with a number.
> The size is limited by bits in the IPCs. So we keep going till we hit max,
> that time we set it back to 1

> These ids are not freed or allocated as IPC latency is small enough and IPCs
> less. We haven't hot scenarios where we go complete round but IPC is still
> pending :)

Yet.

> > > +int free_stream_context(unsigned int str_id)
> > > +{
> > > +	struct stream_info *stream;
> > > +	int ret = 0;
> > > +
> > > +	stream = get_stream_info(str_id);
> > > +	if (stream) {

> > It's a bit scary that this might be used with an invalid ID - what
> > happens if the ID got reallocated?

> The free routine checks for valid ID first

That's not the point - the point is that if you're freeing what might be
an invalid ID I don't see any guarantee that the ID hasn't been
allocated to something else.  It's different if there's a specific ID
that can be used for an invalid ID but this looks like it's working
around double frees.

> > > +	while (header.p.header_high.part.busy) {
> > > +		if (loop_count > 10) {
> > > +			pr_err("sst: Busy wait failed, cant send this msg\n");
> > > +			retval = -EBUSY;
> > > +			goto out;
> > > +		}
> > > +		udelay(500);
> > > +		loop_count++;
> > > +		header.full = sst_shim_read64(sst_drv_ctx->shim, SST_IPCX);
> > > +	}

> > Throw a cpu_relax() in there if we need to spin...

> its more busy wait for the bit to be freed. Since IPC latency is supposed to
> be minimal checking like this helps to minimize.

It's a udelay(500) which is pretty long for a busy wait...

> > > +	if (!list_empty(&sst_drv_ctx->memcpy_list)) {
> > > +		list_for_each_entry_safe(listnode, tmplistnode,
> > > +				&sst_drv_ctx->memcpy_list, memcpylist) {
> > > +			list_del(&listnode->memcpylist);
> > > +			kfree(listnode);
> > > +		}
> > > +	}
> > > +	sst_memcpy_free_lib_resources();
> > > +}

> > I'm having a hard time seeing why we don't just copy the data as we go
> > rather than allocating this list?  It seems to just be making the code
> > more complex.

> because we support DMA too. so common parsing and then later we either do
> memcpy and dma. Will push DMA bits after this series.

Keep it simple for now and just memcpy() directly, leaving the functions
that select I/O vs memcpy() - you can always go back and add the DMA
later.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://mailman.alsa-project.org/pipermail/alsa-devel/attachments/20140718/04cbdff9/attachment.sig>


More information about the Alsa-devel mailing list