All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Morton <akpm@linux-foundation.org>
To: Paul Sokolovsky <pmiscml@gmail.com>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [RFC, PATCH 1/4] SoC base drivers: SoC helper API
Date: Mon, 30 Apr 2007 23:56:30 -0700	[thread overview]
Message-ID: <20070430235630.e862aefc.akpm@linux-foundation.org> (raw)
In-Reply-To: <181733600.20070501080827@gmail.com>

On Tue, 1 May 2007 08:08:27 +0300 Paul Sokolovsky <pmiscml@gmail.com> wrote:

> diff --git a/drivers/soc/soc-core.c b/drivers/soc/soc-core.c
> new file mode 100644
> index 0000000..24c654c
> --- /dev/null
> +++ b/drivers/soc/soc-core.c
> @@ -0,0 +1,106 @@
> +/*
> + * drivers/soc/soc-core.c
> + *
> + * core SoC support
> + * Copyright (c) 2006 Ian Molton
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This file contains functionality used by many SoC type devices.
> + *
> + * Created: 2006-11-28
> + *
> + */
> +
> +#include <linux/ioport.h>
> +#include <linux/slab.h>
> +#include <linux/kernel.h>
> +#include <linux/platform_device.h>
> +#include "soc-core.h"
> +
> +void soc_free_devices(struct platform_device *devices, int nr_devs)
> +{
> +	struct platform_device *dev = devices;
> +	int i;
> +
> +	for (i = 0; i < nr_devs; i++) {
> +		struct resource *res = dev->resource;
> +		platform_device_unregister(dev++);
> +		kfree(res);
> +	}
> +	kfree(devices);
> +}
> +EXPORT_SYMBOL_GPL(soc_free_devices);
> +
> +#define SIGNED_SHIFT(val, shift) ((shift) >= 0 ? ((val) << (shift)) : ((val) >> -(shift)))

This will do bad things with

	SIGNED_SHIFT(val, distance++);

So either

a) take a copy of the args inside the macro or, better

b) use a static inline.

It's probably worth putting the result into include/linux/kernel.h as well.
It's quite generic.  If so, that's a standalone patch, please.  Or keep it
here if you can't be bothered with that.

> +struct platform_device *soc_add_devices(struct platform_device *dev,
> +					struct soc_device_data *soc, int nr_devs,
> +					struct resource *mem,
> +					int relative_addr_shift, int irq_base)
> +{
> +	struct platform_device *devices;
> +	int i, r, base;
> +
> +	devices = kzalloc(nr_devs * sizeof(struct platform_device), GFP_KERNEL);
> +	if (!devices)
> +		return NULL;
> +
> +	for (i = 0; i < nr_devs; i++) {
> +		struct platform_device *sdev = &devices[i];
> +		struct soc_device_data *blk = &soc[i];
> +		struct resource *res;
> +
> +		sdev->id = -1;
> +		sdev->name = blk->name;
> +
> +		sdev->dev.parent = &dev->dev;
> +		sdev->dev.platform_data = (void *)blk->hwconfig;
> +		sdev->num_resources = blk->num_resources;
> +
> +		/* Allocate space for the subdevice resources */
> +		res = kzalloc (blk->num_resources * sizeof (struct resource), GFP_KERNEL);
> +		if (!res)
> +			goto fail;
> +
> +		for (r = 0 ; r < blk->num_resources ; r++) {
> +			res[r].name = blk->res[r].name; // Fixme - should copy

fix me then ;)

With kstrdup(), presumably.

> +
> +			/* Find out base to use */
> +			base = 0;
> +			if (blk->res[r].flags & IORESOURCE_MEM) {
> +				base = mem->start;

mem->start is of type resource_size_t, and `base' should be of that type as
well.

> +			} else if ((blk->res[r].flags & IORESOURCE_IRQ) &&
> +				(blk->res[r].flags & IORESOURCE_IRQ_SOC_SUBDEVICE)) {
> +				base = irq_base;
> +			}
> +
> +			/* Adjust resource */
> +			if (blk->res[r].flags & IORESOURCE_MEM) {
> +				res[r].parent = mem;
> +				res[r].start = base + SIGNED_SHIFT(blk->res[r].start, relative_addr_shift);
> +				res[r].end   = base + SIGNED_SHIFT(blk->res[r].end,   relative_addr_shift);

Which means that SIGNED_SHIFT really has to be a macro, as it needs to
handle resource_size_t's and you don't know what type they have.

Also, things get interesting when working out how to handle right-shift of
a negative quantity of unknown type.

> +			} else {
> +				res[r].start = base + blk->res[r].start;
> +				res[r].end   = base + blk->res[r].end;
> +			}
> +			res[r].flags = blk->res[r].flags;
> +		}
> +
> +		sdev->resource = res;
> +		if (platform_device_register(sdev)) {
> +			kfree(res);
> +			goto fail;
> +		}
> +
> +		printk(KERN_INFO "SoC: registering %s\n", blk->name);
> +	}
> +	return devices;
> +
> +fail:
> +	soc_free_devices(devices, i + 1);
> +	return NULL;
> +}
> +EXPORT_SYMBOL_GPL(soc_add_devices);
> diff --git a/drivers/soc/soc-core.h b/drivers/soc/soc-core.h
> new file mode 100644
> index 0000000..8659f7e
> --- /dev/null
> +++ b/drivers/soc/soc-core.h
> @@ -0,0 +1,30 @@
> +/*
> + * drivers/soc/soc-core.h
> + *
> + * core SoC support
> + * Copyright (c) 2006 Ian Molton
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This file contains prototypes for the functions in soc-core.c
> + *
> + * Created: 2006-11-28
> + *
> + */
> +
> +struct soc_device_data {
> +	char *name;
> +	struct resource *res;
> +	int num_resources;
> +	void *hwconfig; /* platform_data to pass to the subdevice */
> +};
> +
> +struct platform_device *soc_add_devices(struct platform_device *dev,
> +					struct soc_device_data *soc, int n_devs,
> +					struct resource *mem,
> +					int relative_addr_shift, int irq_base);
> +
> +void soc_free_devices(struct platform_device *devices, int nr_devs);
> +
> diff --git a/include/linux/ioport.h b/include/linux/ioport.h
> index 6859a3b..65f0fcd 100644
> --- a/include/linux/ioport.h
> +++ b/include/linux/ioport.h
> @@ -57,6 +57,9 @@ struct resource_list {
>  #define IORESOURCE_IRQ_LOWLEVEL		(1<<3)
>  #define IORESOURCE_IRQ_SHAREABLE	(1<<4)
>  
> +/* SoC device IRQ specific bits (IORESOURCE_BITS) */
> +#define IORESOURCE_IRQ_SOC_SUBDEVICE    (1<<5)
> +
>  /* ISA PnP DMA specific bits (IORESOURCE_BITS) */
>  #define IORESOURCE_DMA_TYPE_MASK	(3<<0)
>  #define IORESOURCE_DMA_8BIT		(0<<0)
> 

It looks reasonable to me, but I'm not Greg or Russell or anything like
that.


  reply	other threads:[~2007-05-01  6:56 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-01  5:08 [RFC, PATCH 1/4] SoC base drivers: SoC helper API Paul Sokolovsky
2007-05-01  6:56 ` Andrew Morton [this message]
2007-05-01 14:06 ` Ben Pfaff
2007-05-01 19:08 ` Russell King

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070430235630.e862aefc.akpm@linux-foundation.org \
    --to=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pmiscml@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.