[PATCH V2] ARM: NUC900: add GDMA driver support for nuc900 platform

Russell King - ARM Linux linux at arm.linux.org.uk
Thu Dec 10 05:20:48 EST 2009


On Wed, Dec 09, 2009 at 11:37:50PM +0800, Hu Ruihuan wrote:
> +static void match_dmachan_fromname(const char *dev_name,
> +					struct nuc900_dma  **dma)
> +{
> +	BUG_ON(!dev_name);
> +
> +	if (dmachan1->device) {
> +		if (strcmp(dmachan1->device, dev_name) == 0)
> +			*dma = dmachan1;
> +	} else if (dmachan0->device) {
> +		if (strcmp(dmachan0->device, dev_name) == 0)
> +			*dma = dmachan0;
> +	}
> +}

Never write functions like this without explaination of why you're doing
it this way: having a void function returning something through a
double pointer is just silly, and leads to bugs (when someone forgets
to NULL-initialize before-hand.)

static struct nuc900_dma *match_dmachan_fromname(const char *dev_name)
{
	BUG_ON(!dev_name);

	if (dmachan1->device) {
		if (strcmp(dmachan1->device, dev_name) == 0)
			return dmachan1;
	} else if (dmachan0->device) {
		if (strcmp(dmachan0->device, dev_name) == 0)
			return dmachan0;
	}
	return NULL;
}

This way, whenever you do:

	dmachan = match_dmachan_fromname(foo);

you know that dmachan will always be initialized, whereas:

	match_dmachan_fromname(foo, &dmachan);

there's little to tell the compiler that dmachan will be initialized -
in fact, the compiler _can't_ tell you whether you're possibly using it
without it having been initialized.

> +int nuc900_request_dma(const char *dev_name, dma_callback_t callback,
> +								void *data)
> +{
> +	struct nuc900_dma  *dma = NULL;
> +	int err, irq_request;
> +	err = 0;
> +	irq_request = 0;
> +	spin_lock(&dma_chan_lock);
> +	dma = register_dmachan_fromname(dev_name, &irq_request);

It seems that the irq_request handling is now unnecessary, please remove.

> +	if (IS_ERR(dma)) {
> +		err = PTR_ERR(dma);
> +		spin_unlock(&dma_chan_lock);
> +		return err;
> +	}
> +	dma->device = dev_name;
> +	atomic_inc(&shared_irq_using);

shared_irq_using is not required anymore.

> +	dma->callback = callback;
> +	dma->data = data;
> +	spin_unlock(&dma_chan_lock);
> +	return 0;
> +}
> +EXPORT_SYMBOL(nuc900_request_dma);
> +
> +int nuc900_free_dma(const char *dev_name)
> +{
> +	struct nuc900_dma  *dma = NULL;
> +
> +	BUG_ON(!dev_name);
> +	WARN_ON(shared_irq_using.counter == 0);

This is buggy, never go inside an 'atomic' object - use the accessor
functions.  In any case, shared_irq_using is not required so this can
be deleted.

> +	spin_lock(&dma_chan_lock);
> +	match_dmachan_fromname(dev_name, &dma);
> +
> +	if (!dma)
> +		return -ENXIO;
> +
> +	dma->device = NULL;
> +	spin_unlock(&dma_chan_lock);
> +
> +	atomic_dec(&shared_irq_using);

Can be removed.

> +
> +	kzfree(dma->descp);
> +	return 0;
> +}
> +EXPORT_SYMBOL(nuc900_free_dma);
> +
> +static unsigned int set_start_cmd(unsigned int start)
> +{
> +	unsigned int dscp_cmd;
> +
> +	dscp_cmd = 0;
> +
> +	if (start) {
> +		dscp_cmd = (ORDEN|RUN);
> +		dscp_cmd &= ~(NON_DSCRIP|RESET);
> +	} else {
> +		dscp_cmd = (NON_DSCRIP);
> +	}
> +		dscp_cmd &= DSCRIPMASK;

Weird formatting - is this correctly placed?  It looks like it should
be within the else { } clause.

> +
> +	return dscp_cmd;
> +}



More information about the linux-arm-kernel mailing list