Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3/5] of/irq: introduce of_irq_init
From: Grant Likely @ 2011-09-17 23:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316017900-19918-4-git-send-email-robherring2@gmail.com>

On Wed, Sep 14, 2011 at 11:31:38AM -0500, Rob Herring wrote:
> From: Rob Herring <rob.herring@calxeda.com>
> 
> of_irq_init will scan the devicetree for matching interrupt controller
> nodes. Then it calls an initialization function for each found controller
> in the proper order with parent nodes initialized before child nodes.
> 
> Based on initial pseudo code from Grant Likely.
> 
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> ---
>  drivers/of/irq.c       |   96 ++++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/of_irq.h |    1 +
>  2 files changed, 97 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/of/irq.c b/drivers/of/irq.c
> index 9f689f1..a0cd7e8 100644
> --- a/drivers/of/irq.c
> +++ b/drivers/of/irq.c
> @@ -19,10 +19,13 @@
>   */
>  
>  #include <linux/errno.h>
> +#include <linux/list.h>
> +#include <linux/list_sort.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/of_irq.h>
>  #include <linux/string.h>
> +#include <linux/slab.h>
>  
>  /* For archs that don't support NO_IRQ (such as x86), provide a dummy value */
>  #ifndef NO_IRQ
> @@ -386,3 +389,96 @@ int of_irq_to_resource_table(struct device_node *dev, struct resource *res,
>  
>  	return i;
>  }
> +
> +struct intc_desc {
> +	struct list_head	list;
> +	struct device_node	*dev;
> +	struct device_node	*parent;
> +};
> +
> +typedef void (*irq_init_cb_t)(struct device_node *, struct device_node *);
> +
> +static int __init irq_cmp_intc_desc(void *unused, struct list_head *a,
> +				    struct list_head *b)
> +{
> +	const struct intc_desc *da = list_entry(a, typeof(*da), list);
> +	const struct intc_desc *db = list_entry(b, typeof(*db), list);
> +
> +	/* same parent, so order doesn't matter */
> +	if (da->parent == db->parent)
> +		return 0;
> +
> +	/* NULL parent comes first */
> +	if (!da->parent && db->parent)
> +		return -1;
> +	if (!db->parent && da->parent)
> +		return 1;
> +
> +	/* parent node must be before child node */
> +	if (da->dev == db->parent)
> +		return -1;
> +	if (db->dev == da->parent)
> +		return 1;

Does sort_list work for relationships 4 or more levels deep?  ie. if
there was a relationship of A <- B <- C <- D, then B compared with D
would return 0 from this function which could potentially result in an
incorrectly ordered list.

The other option for implementing this would be to take the probe
deferral approach and not try to sort the list, but instead allow
probe functions to fail & request retry if the parent hasn't yet been
probed.  I haven't thought enough about it though to say which would
be the best approach.

> +
> +	return 0;
> +}
> +
> +/**
> + * of_irq_init - Scan the device tree for matching interrupt controllers and
> + * call their initialization functions in order with parents first.
> + * @matches: 0 terminated array of nodes to match and initialization function
> + * to call on match
> + */
> +void __init of_irq_init(const struct of_device_id *matches)
> +{
> +	struct device_node *np;
> +	const struct of_device_id *match;
> +	struct intc_desc *desc;
> +	struct intc_desc *temp_desc;
> +	struct list_head intc_desc_list;
> +
> +	INIT_LIST_HEAD(&intc_desc_list);
> +
> +	for_each_matching_node(np, matches) {
> +		if (!of_find_property(np, "interrupt-controller", NULL))
> +			continue;
> +		/* Here, we allocate and populate an intc_desc with the node
> +		* pointer, interrupt-parent device_node etc. */
> +		desc = kzalloc(sizeof(*desc), GFP_KERNEL);
> +		if (!desc) {
> +			WARN_ON(1);
> +			goto err;
> +		}
> +		desc->dev = np;
> +		desc->parent = of_irq_find_parent(np);
> +		list_add(&desc->list, &intc_desc_list);
> +	}
> +	if (list_empty(&intc_desc_list))
> +		return;
> +
> +	/*
> +	 * The root irq controller is the one without an interrupt-parent.
> +	 * That one goes first, followed by the controllers that reference it,
> +	 * followed by the ones that reference the 2nd level controllers, etc
> +	 */

I don't believe that this actually turns out to be true (and yes I
know it is how I originally described it).  :-)  When the
interrupt-parent property is at the root of the tree, then the root
interrupt controller may very well inherit itself as it's interrupt
parent, and of_irq_find_parent() will still return a value.  This
should probably be considered a bug in of_irq_find_parent(), and it
should return NULL if the parent is itself.

of_irq_find_parent should probably be implemented thusly (completely
untested); although the only functional change is the line:
	return (p == child) ? NULL : p;

/**
 * of_irq_find_parent - Given a device node, find its interrupt parent node
 * @child: pointer to device node
 *
 * Returns a pointer to the interrupt parent node, or NULL if the
 * interrupt parent could not be determined.
 */
struct device_node *of_irq_find_parent(struct device_node *child)
{
	struct device_node *p, *c = child;
	const __be32 *parp;

	if (!of_node_get(c))
		return NULL;

	do {
		p = of_parse_phandle(c, "interrupt-parent", 0);

		if (!p && (of_irq_workarounds & OF_IMAP_NO_PHANDLE) &&
		    of_find_property(c, "interrupt-parent", NULL))
			p = of_node_get(of_irq_dflt_pic);

		if (!p)
			p = of_get_parent(c);

		of_node_put(c);
		c = p;
	} while (p && !of_find_property(p, "#interrupt-cells", NULL));

	return (p == child) ? NULL : p;
}


> +	list_sort(NULL, &intc_desc_list, irq_cmp_intc_desc);
> +
> +	list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
> +		match = of_match_node(matches, desc->dev);
> +		if (match && match->data) {
> +			irq_init_cb_t irq_init_cb = match->data;
> +			pr_debug("of_irq_init: init %s @ %p, parent %p\n",
> +				 match->compatible, desc->dev, desc->parent);
> +			irq_init_cb(desc->dev, desc->parent);
> +		}
> +		list_del(&desc->list);
> +		kfree(desc);
> +	}
> +	return;
> +
> +err:
> +	list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
> +		list_del(&desc->list);
> +		kfree(desc);
> +	}
> +}

Overall, I'm pretty happy with how this is looking.  Great job!

g.

> diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
> index cd2e61c..032d76c 100644
> --- a/include/linux/of_irq.h
> +++ b/include/linux/of_irq.h
> @@ -73,6 +73,7 @@ extern int of_irq_to_resource_table(struct device_node *dev,
>  		struct resource *res, int nr_irqs);
>  extern struct device_node *of_irq_find_parent(struct device_node *child);
>  
> +extern void of_irq_init(const struct of_device_id *matches);
>  
>  #endif /* CONFIG_OF_IRQ */
>  #endif /* CONFIG_OF */
> -- 
> 1.7.5.4
> 

^ permalink raw reply

* [PATCH 2/5] irq: fix existing domain check in irq_domain_add
From: Grant Likely @ 2011-09-17 23:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.02.1109141838510.2723@ionos>

On Wed, Sep 14, 2011 at 06:44:50PM +0200, Thomas Gleixner wrote:
> On Wed, 14 Sep 2011, Rob Herring wrote:
> 
> > From: Rob Herring <rob.herring@calxeda.com>
> > 
> > irq_data will normally exist, so the domain was prevented from being set.
> > The simple domain code did not hit this as nr_irq is always 0.
> > 
> > Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> > Cc: Grant Likely <grant.likely@secretlab.ca>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> 
> I take this and 1/5 through irq/urgent

Thanks Thomas.

g.

> 
> Thanks,
> 
> 	tglx
> 
> > ---
> >  kernel/irq/irqdomain.c |    2 +-
> >  1 files changed, 1 insertions(+), 1 deletions(-)
> > 
> > diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> > index d5828da..84f4110 100644
> > --- a/kernel/irq/irqdomain.c
> > +++ b/kernel/irq/irqdomain.c
> > @@ -29,7 +29,7 @@ void irq_domain_add(struct irq_domain *domain)
> >  	 */
> >  	for (hwirq = 0; hwirq < domain->nr_irq; hwirq++) {
> >  		d = irq_get_irq_data(irq_domain_to_irq(domain, hwirq));
> > -		if (d || d->domain) {
> > +		if (d && d->domain) {
> >  			/* things are broken; just report, don't clean up */
> >  			WARN(1, "error: irq_desc already assigned to a domain");
> >  			return;
> > -- 
> > 1.7.5.4
> > 
> > 

^ permalink raw reply

* [PATCH v2] arm: omap3evm: Add support for an MT9M032 based camera board.
From: Laurent Pinchart @ 2011-09-17 22:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4E751870.5080605@gmail.com>

On Sunday 18 September 2011 00:00:16 Sylwester Nawrocki wrote:
> On 09/17/2011 11:34 AM, Martin Hostettler wrote:
> > Adds board support for an MT9M032 based camera to omap3evm.
> 
> ...
> 
> > +
> > +static int __init camera_init(void)
> > +{
> > +	int ret = -EINVAL;
> > +
> > +	omap_mux_init_gpio(nCAM_VD_SEL, OMAP_PIN_OUTPUT);
> > +	if (gpio_request(nCAM_VD_SEL, "nCAM_VD_SEL")<  0) {
> > +		pr_err("omap3evm-camera: Failed to get GPIO nCAM_VD_SEL(%d)\n",
> > +		       nCAM_VD_SEL);
> > +		goto err;
> > +	}
> > +	if (gpio_direction_output(nCAM_VD_SEL, 1)<  0) {
> > +		pr_err("omap3evm-camera: Failed to set GPIO nCAM_VD_SEL(%d)
> > direction\n", +		       nCAM_VD_SEL);
> > +		goto err_vdsel;
> > +	}
> 
> How about replacing gpio_request + gpio_direction_output with:
> 
> 	gpio_request_one(nCAM_VD_SEL, GPIOF_OUT_INIT_HIGH, "nCAM_VD_SEL");

I'd even propose gpio_request_array().

> > +
> > +	if (gpio_request(EVM_TWL_GPIO_BASE + 2, "T2_GPIO2")<  0) {
> > +		pr_err("omap3evm-camera: Failed to get GPIO T2_GPIO2(%d)\n",
> > +		       EVM_TWL_GPIO_BASE + 2);
> > +		goto err_vdsel;
> > +	}
> > +	if (gpio_direction_output(EVM_TWL_GPIO_BASE + 2, 0)<  0) {
> > +		pr_err("omap3evm-camera: Failed to set GPIO T2_GPIO2(%d) 
direction\n",
> > +		       EVM_TWL_GPIO_BASE + 2);
> > +		goto err_2;
> > +	}
> 
>  	gpio_request_one(EVM_TWL_GPIO_BASE + 2, GPIOF_OUT_INIT_LOW, "T2_GPIO2");
> 
> > +
> > +	if (gpio_request(EVM_TWL_GPIO_BASE + 8, "nCAM_VD_EN")<  0) {
> > +		pr_err("omap3evm-camera: Failed to get GPIO nCAM_VD_EN(%d)\n",
> > +		       EVM_TWL_GPIO_BASE + 8);
> > +		goto err_2;
> > +	}
> > +	if (gpio_direction_output(EVM_TWL_GPIO_BASE + 8, 0)<  0) {
> > +		pr_err("omap3evm-camera: Failed to set GPIO nCAM_VD_EN(%d)
> > direction\n", +		       EVM_TWL_GPIO_BASE + 8);
> > +		goto err_8;
> > +	}
> 
> ...and	gpio_request_one(EVM_TWL_GPIO_BASE + 8, GPIOF_OUT_INIT_LOW,
> "nCAM_VD_EN") ?
> 
> > +
> > +	omap3evm_set_mux(MUX_CAMERA_SENSOR);
> > +
> > +
> > +	ret = omap3_init_camera(&isp_platform_data);
> > +	if (ret<  0)
> > +		goto err_8;
> > +	return 0;
> > +
> > +err_8:
> > +	gpio_free(EVM_TWL_GPIO_BASE + 8);
> > +err_2:
> > +	gpio_free(EVM_TWL_GPIO_BASE + 2);
> > +err_vdsel:
> > +	gpio_free(nCAM_VD_SEL);
> > +err:
> > +	return ret;
> > +}
> > +
> > +device_initcall(camera_init);

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* [PATCH v2] arm: omap3evm: Add support for an MT9M032 based camera board.
From: Sylwester Nawrocki @ 2011-09-17 22:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316252097-4213-1-git-send-email-martin@neutronstar.dyndns.org>

On 09/17/2011 11:34 AM, Martin Hostettler wrote:
> Adds board support for an MT9M032 based camera to omap3evm.
...
> +
> +static int __init camera_init(void)
> +{
> +	int ret = -EINVAL;
> +	
> +	omap_mux_init_gpio(nCAM_VD_SEL, OMAP_PIN_OUTPUT);
> +	if (gpio_request(nCAM_VD_SEL, "nCAM_VD_SEL")<  0) {
> +		pr_err("omap3evm-camera: Failed to get GPIO nCAM_VD_SEL(%d)\n",
> +		       nCAM_VD_SEL);
> +		goto err;
> +	}
> +	if (gpio_direction_output(nCAM_VD_SEL, 1)<  0) {
> +		pr_err("omap3evm-camera: Failed to set GPIO nCAM_VD_SEL(%d) direction\n",
> +		       nCAM_VD_SEL);
> +		goto err_vdsel;
> +	}

How about replacing gpio_request + gpio_direction_output with:

	gpio_request_one(nCAM_VD_SEL, GPIOF_OUT_INIT_HIGH, "nCAM_VD_SEL");

> +
> +	if (gpio_request(EVM_TWL_GPIO_BASE + 2, "T2_GPIO2")<  0) {
> +		pr_err("omap3evm-camera: Failed to get GPIO T2_GPIO2(%d)\n",
> +		       EVM_TWL_GPIO_BASE + 2);
> +		goto err_vdsel;
> +	}
> +	if (gpio_direction_output(EVM_TWL_GPIO_BASE + 2, 0)<  0) {
> +		pr_err("omap3evm-camera: Failed to set GPIO T2_GPIO2(%d) direction\n",
> +		       EVM_TWL_GPIO_BASE + 2);
> +		goto err_2;
> +	}

 	gpio_request_one(EVM_TWL_GPIO_BASE + 2, GPIOF_OUT_INIT_LOW, "T2_GPIO2");

> +
> +	if (gpio_request(EVM_TWL_GPIO_BASE + 8, "nCAM_VD_EN")<  0) {
> +		pr_err("omap3evm-camera: Failed to get GPIO nCAM_VD_EN(%d)\n",
> +		       EVM_TWL_GPIO_BASE + 8);
> +		goto err_2;
> +	}
> +	if (gpio_direction_output(EVM_TWL_GPIO_BASE + 8, 0)<  0) {
> +		pr_err("omap3evm-camera: Failed to set GPIO nCAM_VD_EN(%d) direction\n",
> +		       EVM_TWL_GPIO_BASE + 8);
> +		goto err_8;
> +	}

...and	gpio_request_one(EVM_TWL_GPIO_BASE + 8, GPIOF_OUT_INIT_LOW, "nCAM_VD_EN") ?

> +
> +	omap3evm_set_mux(MUX_CAMERA_SENSOR);
> +
> +	
> +	ret = omap3_init_camera(&isp_platform_data);
> +	if (ret<  0)
> +		goto err_8;
> +	return 0;
> +	
> +err_8:
> +	gpio_free(EVM_TWL_GPIO_BASE + 8);
> +err_2:
> +	gpio_free(EVM_TWL_GPIO_BASE + 2);
> +err_vdsel:
> +	gpio_free(nCAM_VD_SEL);
> +err:
> +	return ret;
> +}
> +
> +device_initcall(camera_init);

--
Regards,
Sylwester

^ permalink raw reply

* [PATCH v2] pata-generic/of: Make probing via device tree non-powerpc-specific
From: Grant Likely @ 2011-09-17 21:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <2615461.zA8fCfbHH2@wuerfel>

On Sat, Sep 17, 2011 at 12:40 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Saturday 17 September 2011 09:37:32 Grant Likely wrote:
>> What driver is normally used for versatile express pata? ?This driver
>> is kind of legacy in that it was created when there was a split
>> between platform_device and of_platform_devices. ?But that split was a
>> bad idea and the same driver should be used regardless of whether or
>> not DT is enabled. ?pata_of_platform.c really should be removed.
>
> It normally uses the plain pata_platform.c driver.
>
> Note that the pata_of_platform driver is already just a shim on
> top of the regular pata_platform driver. They could easily be combined,
> but the current state is also ok, since there is very little code
> duplication.

A bunch of the code is actually redundant since the resource table is
no populated for DT devices.  I also see some directly references to
reg-shift and pio-mode property values without using be32_to_cpu(), so
that will also need to be fixed.  The of_irq_to_resource() and
of_address_to_resource() calls are now redundant since
platform_get_*() works for DT sourced platform device (with one quirk
for the electra-ide device).  Given that the conversion is straight
forward, I'd rather see pata_of_platform.c dropped and rolled into
pata_platform.c.  I've hacked together a patch to do so, but I've only
compile tested it.  Dave, if I send it to you, can you take care of
testing it?

Thanks,
g.

^ permalink raw reply

* [PATCH] arm/dt: Add SoC detection macros
From: Arnd Bergmann @ 2011-09-17 20:56 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110917181907.GA16141@game.jcrosoft.org>

On Saturday 17 September 2011 20:19:07 Jean-Christophe PLAGNIOL-VILLARD wrote:
> 
> I agree about it I just mean that if you have the same board with 2 SoC which
> are pin to pin compatible detect the soc type will be usefull as the soc
> resource may not be the same

In that scenario, you would put all SOC specific data into one .dtsi
file and all board data into another .dtsi file and then create a
description for the combination using a trivial .dts file with two
include statements. This is all solved outside of the kernel already,
so there is no need for infrastructure in the kernel.

	Arnd

^ permalink raw reply

* [PATCH 0/19] removal of mach/vmalloc.h and generic optimizations
From: Arnd Bergmann @ 2011-09-17 20:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316156850-31013-1-git-send-email-nico@fluxnic.net>

On Friday 16 September 2011 03:07:11 Nicolas Pitre wrote:
> This patch series removes all instances of mach/vmalloc.h in order to
> have a more unified memory map across all ARM architectures.  To do so,
> the static mappings are moved inside the vmalloc area.  And finally this
> allows for a generic optimization to ioremap where static mappings are
> reused whenever possible, using common code instead of having this
> duplicated in a couple places.
> 
> This also provides a net reduction of more than 1200 lines of code.
> 
> Those patches are also available in the following repository:
> 
>         git://git.linaro.org/people/nico/linux vmalloc

Hi Nicolas,

I like the series a lot. I had planned to work on this myself, but
I guess you did a better job than I could have anyway.

Doing some randconfig tests, I noticed that your series is currently broken
on shmobile, which triggers a 

	BUILD_BUG_ON(VMALLOC_END > CONSISTENT_BASE);

in mem_init(), because the platform has a CONSISTENT_DMA_SIZE of 158MB.
All other platforms have a CONSISTENT_DMA_SIZE of at most 14MB, which
works correctly.

My feeling is that a 158MB CONSISTENT_DMA_SIZE causes other problems
anyway because we cannot map regular RAM both cached and uncached,
but this is still a regression. The problem might be solved using
Marek's CMA patches, which should eliminate the need for a huge
CONSISTENT_DMA_SIZE.

	Arnd

^ permalink raw reply

* [PATCH v2] arm: omap3evm: Add support for an MT9M032 based camera board.
From: Joe Perches @ 2011-09-17 20:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316252097-4213-1-git-send-email-martin@neutronstar.dyndns.org>

On Sat, 2011-09-17 at 11:34 +0200, Martin Hostettler wrote:
> Adds board support for an MT9M032 based camera to omap3evm.

All of the logging messages could be
prefixed by the printk subsystem if you
add #define pr_fmt before any #include

> diff --git a/arch/arm/mach-omap2/board-omap3evm-camera.c b/arch/arm/mach-omap2/board-omap3evm-camera.c
[]
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
[]
> +static int omap3evm_set_mux(enum omap3evmdc_mux mux_id)
[]
> +	switch (mux_id) {
[]
> +	default:
> +		pr_err("omap3evm-camera: Invalid mux id #%d\n", mux_id);

		pr_err("Invalid mux id #%d\n", mux_id);
[]
> +static int __init camera_init(void)
[]
> +	if (gpio_request(nCAM_VD_SEL, "nCAM_VD_SEL") < 0) {
> +		pr_err("omap3evm-camera: Failed to get GPIO nCAM_VD_SEL(%d)\n",
> +		       nCAM_VD_SEL);

		pr_err("Failed to get GPIO nCAM_VD_SEL(%d)\n",
		       nCAM_VD_SEL);
etc.

^ permalink raw reply

* [PATCH 3/3] at91/gpio: fix display of number of irq setuped
From: Jean-Christophe PLAGNIOL-VILLARD @ 2011-09-17 18:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316285923-12461-1-git-send-email-plagnioj@jcrosoft.com>

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 arch/arm/mach-at91/gpio.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index e709406..743f668 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -528,7 +528,7 @@ void __init at91_gpio_irq_setup(void)
 		irq_set_chip_data(id, this);
 		irq_set_chained_handler(id, gpio_irq_handler);
 	}
-	pr_info("AT91: %d gpio irqs in %d banks\n", irq, gpio_banks);
+	pr_info("AT91: %d gpio irqs in %d banks\n", irq - gpio_to_irq(0), gpio_banks);
 }
 
 /* gpiolib support */
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 2/3] at91/gpio: drop PIN_BASE
From: Jean-Christophe PLAGNIOL-VILLARD @ 2011-09-17 18:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316285923-12461-1-git-send-email-plagnioj@jcrosoft.com>

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 arch/arm/mach-at91/gpio.c              |   54 ++--
 arch/arm/mach-at91/include/mach/gpio.h |  454 ++++++++++++++++----------------
 2 files changed, 254 insertions(+), 254 deletions(-)
 rewrite arch/arm/mach-at91/include/mach/gpio.h (78%)

diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index 04beff1..e709406 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -60,18 +60,17 @@ static int at91_gpiolib_direction_input(struct gpio_chip *chip,
 	}
 
 static struct at91_gpio_chip gpio_chip[] = {
-	AT91_GPIO_CHIP("A", 0x00 + PIN_BASE, 32),
-	AT91_GPIO_CHIP("B", 0x20 + PIN_BASE, 32),
-	AT91_GPIO_CHIP("C", 0x40 + PIN_BASE, 32),
-	AT91_GPIO_CHIP("D", 0x60 + PIN_BASE, 32),
-	AT91_GPIO_CHIP("E", 0x80 + PIN_BASE, 32),
+	AT91_GPIO_CHIP("A", 0x00, 32),
+	AT91_GPIO_CHIP("B", 0x20, 32),
+	AT91_GPIO_CHIP("C", 0x40, 32),
+	AT91_GPIO_CHIP("D", 0x60, 32),
+	AT91_GPIO_CHIP("E", 0x80, 32),
 };
 
 static int gpio_banks;
 
 static inline void __iomem *pin_to_controller(unsigned pin)
 {
-	pin -= PIN_BASE;
 	pin /= 32;
 	if (likely(pin < gpio_banks))
 		return gpio_chip[pin].regbase;
@@ -81,7 +80,6 @@ static inline void __iomem *pin_to_controller(unsigned pin)
 
 static inline unsigned pin_to_mask(unsigned pin)
 {
-	pin -= PIN_BASE;
 	return 1 << (pin % 32);
 }
 
@@ -276,8 +274,9 @@ static u32 backups[MAX_GPIO_BANKS];
 
 static int gpio_irq_set_wake(struct irq_data *d, unsigned state)
 {
-	unsigned	mask = pin_to_mask(d->irq);
-	unsigned	bank = (d->irq - PIN_BASE) / 32;
+	unsigned	pin = irq_to_gpio(d->irq);
+	unsigned	mask = pin_to_mask(pin);
+	unsigned	bank = pin / 32;
 
 	if (unlikely(bank >= MAX_GPIO_BANKS))
 		return -EINVAL;
@@ -346,8 +345,9 @@ void at91_gpio_resume(void)
 
 static void gpio_irq_mask(struct irq_data *d)
 {
-	void __iomem	*pio = pin_to_controller(d->irq);
-	unsigned	mask = pin_to_mask(d->irq);
+	unsigned	pin = irq_to_gpio(d->irq);
+	void __iomem	*pio = pin_to_controller(pin);
+	unsigned	mask = pin_to_mask(pin);
 
 	if (pio)
 		__raw_writel(mask, pio + PIO_IDR);
@@ -355,8 +355,9 @@ static void gpio_irq_mask(struct irq_data *d)
 
 static void gpio_irq_unmask(struct irq_data *d)
 {
-	void __iomem	*pio = pin_to_controller(d->irq);
-	unsigned	mask = pin_to_mask(d->irq);
+	unsigned	pin = irq_to_gpio(d->irq);
+	void __iomem	*pio = pin_to_controller(pin);
+	unsigned	mask = pin_to_mask(pin);
 
 	if (pio)
 		__raw_writel(mask, pio + PIO_IER);
@@ -384,7 +385,7 @@ static struct irq_chip gpio_irqchip = {
 
 static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 {
-	unsigned	pin;
+	unsigned	irq_pin;
 	struct irq_data *idata = irq_desc_get_irq_data(desc);
 	struct irq_chip *chip = irq_data_get_irq_chip(idata);
 	struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata);
@@ -407,12 +408,12 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 			continue;
 		}
 
-		pin = at91_gpio->chip.base;
+		irq_pin = gpio_to_irq(at91_gpio->chip.base);
 
 		while (isr) {
 			if (isr & 1)
-				generic_handle_irq(pin);
-			pin++;
+				generic_handle_irq(irq_pin);
+			irq_pin++;
 			isr >>= 1;
 		}
 	}
@@ -440,7 +441,7 @@ static int at91_gpio_show(struct seq_file *s, void *unused)
 		seq_printf(s, "%i:\t", j);
 
 		for (bank = 0; bank < gpio_banks; bank++) {
-			unsigned	pin  = PIN_BASE + (32 * bank) + j;
+			unsigned	pin  = (32 * bank) + j;
 			void __iomem	*pio = pin_to_controller(pin);
 			unsigned	mask = pin_to_mask(pin);
 
@@ -493,10 +494,10 @@ static struct lock_class_key gpio_lock_class;
  */
 void __init at91_gpio_irq_setup(void)
 {
-	unsigned		pioc, pin;
+	unsigned		pioc, irq = gpio_to_irq(0);
 	struct at91_gpio_chip	*this, *prev;
 
-	for (pioc = 0, pin = PIN_BASE, this = gpio_chip, prev = NULL;
+	for (pioc = 0, this = gpio_chip, prev = NULL;
 			pioc++ < gpio_banks;
 			prev = this, this++) {
 		unsigned	id = this->bank->id;
@@ -504,16 +505,17 @@ void __init at91_gpio_irq_setup(void)
 
 		__raw_writel(~0, this->regbase + PIO_IDR);
 
-		for (i = 0, pin = this->chip.base; i < 32; i++, pin++) {
-			irq_set_lockdep_class(pin, &gpio_lock_class);
+		for (i = 0, irq = gpio_to_irq(this->chip.base); i < 32;
+		     i++, irq++) {
+			irq_set_lockdep_class(irq, &gpio_lock_class);
 
 			/*
 			 * Can use the "simple" and not "edge" handler since it's
 			 * shorter, and the AIC handles interrupts sanely.
 			 */
-			irq_set_chip_and_handler(pin, &gpio_irqchip,
+			irq_set_chip_and_handler(irq, &gpio_irqchip,
 						 handle_simple_irq);
-			set_irq_flags(pin, IRQF_VALID);
+			set_irq_flags(irq, IRQF_VALID);
 		}
 
 		/* The toplevel handler handles one bank of GPIOs, except
@@ -526,7 +528,7 @@ void __init at91_gpio_irq_setup(void)
 		irq_set_chip_data(id, this);
 		irq_set_chained_handler(id, gpio_irq_handler);
 	}
-	pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks);
+	pr_info("AT91: %d gpio irqs in %d banks\n", irq, gpio_banks);
 }
 
 /* gpiolib support */
@@ -615,7 +617,7 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
 		at91_gpio = &gpio_chip[i];
 
 		at91_gpio->bank = &data[i];
-		at91_gpio->chip.base = PIN_BASE + i * 32;
+		at91_gpio->chip.base = i * 32;
 
 		at91_gpio->regbase = ioremap(at91_gpio->bank->regbase, 512);
 		if (!at91_gpio->regbase) {
diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h
dissimilarity index 78%
index 056dc66..5213879 100644
--- a/arch/arm/mach-at91/include/mach/gpio.h
+++ b/arch/arm/mach-at91/include/mach/gpio.h
@@ -1,228 +1,226 @@
-/*
- * arch/arm/mach-at91/include/mach/gpio.h
- *
- *  Copyright (C) 2005 HP Labs
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#ifndef __ASM_ARCH_AT91RM9200_GPIO_H
-#define __ASM_ARCH_AT91RM9200_GPIO_H
-
-#include <linux/kernel.h>
-#include <asm/irq.h>
-
-#define PIN_BASE		NR_AIC_IRQS
-
-#define MAX_GPIO_BANKS		5
-#define NR_BUILTIN_GPIO		(PIN_BASE + (MAX_GPIO_BANKS * 32))
-
-/* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */
-
-#define	AT91_PIN_PA0	(PIN_BASE + 0x00 + 0)
-#define	AT91_PIN_PA1	(PIN_BASE + 0x00 + 1)
-#define	AT91_PIN_PA2	(PIN_BASE + 0x00 + 2)
-#define	AT91_PIN_PA3	(PIN_BASE + 0x00 + 3)
-#define	AT91_PIN_PA4	(PIN_BASE + 0x00 + 4)
-#define	AT91_PIN_PA5	(PIN_BASE + 0x00 + 5)
-#define	AT91_PIN_PA6	(PIN_BASE + 0x00 + 6)
-#define	AT91_PIN_PA7	(PIN_BASE + 0x00 + 7)
-#define	AT91_PIN_PA8	(PIN_BASE + 0x00 + 8)
-#define	AT91_PIN_PA9	(PIN_BASE + 0x00 + 9)
-#define	AT91_PIN_PA10	(PIN_BASE + 0x00 + 10)
-#define	AT91_PIN_PA11	(PIN_BASE + 0x00 + 11)
-#define	AT91_PIN_PA12	(PIN_BASE + 0x00 + 12)
-#define	AT91_PIN_PA13	(PIN_BASE + 0x00 + 13)
-#define	AT91_PIN_PA14	(PIN_BASE + 0x00 + 14)
-#define	AT91_PIN_PA15	(PIN_BASE + 0x00 + 15)
-#define	AT91_PIN_PA16	(PIN_BASE + 0x00 + 16)
-#define	AT91_PIN_PA17	(PIN_BASE + 0x00 + 17)
-#define	AT91_PIN_PA18	(PIN_BASE + 0x00 + 18)
-#define	AT91_PIN_PA19	(PIN_BASE + 0x00 + 19)
-#define	AT91_PIN_PA20	(PIN_BASE + 0x00 + 20)
-#define	AT91_PIN_PA21	(PIN_BASE + 0x00 + 21)
-#define	AT91_PIN_PA22	(PIN_BASE + 0x00 + 22)
-#define	AT91_PIN_PA23	(PIN_BASE + 0x00 + 23)
-#define	AT91_PIN_PA24	(PIN_BASE + 0x00 + 24)
-#define	AT91_PIN_PA25	(PIN_BASE + 0x00 + 25)
-#define	AT91_PIN_PA26	(PIN_BASE + 0x00 + 26)
-#define	AT91_PIN_PA27	(PIN_BASE + 0x00 + 27)
-#define	AT91_PIN_PA28	(PIN_BASE + 0x00 + 28)
-#define	AT91_PIN_PA29	(PIN_BASE + 0x00 + 29)
-#define	AT91_PIN_PA30	(PIN_BASE + 0x00 + 30)
-#define	AT91_PIN_PA31	(PIN_BASE + 0x00 + 31)
-
-#define	AT91_PIN_PB0	(PIN_BASE + 0x20 + 0)
-#define	AT91_PIN_PB1	(PIN_BASE + 0x20 + 1)
-#define	AT91_PIN_PB2	(PIN_BASE + 0x20 + 2)
-#define	AT91_PIN_PB3	(PIN_BASE + 0x20 + 3)
-#define	AT91_PIN_PB4	(PIN_BASE + 0x20 + 4)
-#define	AT91_PIN_PB5	(PIN_BASE + 0x20 + 5)
-#define	AT91_PIN_PB6	(PIN_BASE + 0x20 + 6)
-#define	AT91_PIN_PB7	(PIN_BASE + 0x20 + 7)
-#define	AT91_PIN_PB8	(PIN_BASE + 0x20 + 8)
-#define	AT91_PIN_PB9	(PIN_BASE + 0x20 + 9)
-#define	AT91_PIN_PB10	(PIN_BASE + 0x20 + 10)
-#define	AT91_PIN_PB11	(PIN_BASE + 0x20 + 11)
-#define	AT91_PIN_PB12	(PIN_BASE + 0x20 + 12)
-#define	AT91_PIN_PB13	(PIN_BASE + 0x20 + 13)
-#define	AT91_PIN_PB14	(PIN_BASE + 0x20 + 14)
-#define	AT91_PIN_PB15	(PIN_BASE + 0x20 + 15)
-#define	AT91_PIN_PB16	(PIN_BASE + 0x20 + 16)
-#define	AT91_PIN_PB17	(PIN_BASE + 0x20 + 17)
-#define	AT91_PIN_PB18	(PIN_BASE + 0x20 + 18)
-#define	AT91_PIN_PB19	(PIN_BASE + 0x20 + 19)
-#define	AT91_PIN_PB20	(PIN_BASE + 0x20 + 20)
-#define	AT91_PIN_PB21	(PIN_BASE + 0x20 + 21)
-#define	AT91_PIN_PB22	(PIN_BASE + 0x20 + 22)
-#define	AT91_PIN_PB23	(PIN_BASE + 0x20 + 23)
-#define	AT91_PIN_PB24	(PIN_BASE + 0x20 + 24)
-#define	AT91_PIN_PB25	(PIN_BASE + 0x20 + 25)
-#define	AT91_PIN_PB26	(PIN_BASE + 0x20 + 26)
-#define	AT91_PIN_PB27	(PIN_BASE + 0x20 + 27)
-#define	AT91_PIN_PB28	(PIN_BASE + 0x20 + 28)
-#define	AT91_PIN_PB29	(PIN_BASE + 0x20 + 29)
-#define	AT91_PIN_PB30	(PIN_BASE + 0x20 + 30)
-#define	AT91_PIN_PB31	(PIN_BASE + 0x20 + 31)
-
-#define	AT91_PIN_PC0	(PIN_BASE + 0x40 + 0)
-#define	AT91_PIN_PC1	(PIN_BASE + 0x40 + 1)
-#define	AT91_PIN_PC2	(PIN_BASE + 0x40 + 2)
-#define	AT91_PIN_PC3	(PIN_BASE + 0x40 + 3)
-#define	AT91_PIN_PC4	(PIN_BASE + 0x40 + 4)
-#define	AT91_PIN_PC5	(PIN_BASE + 0x40 + 5)
-#define	AT91_PIN_PC6	(PIN_BASE + 0x40 + 6)
-#define	AT91_PIN_PC7	(PIN_BASE + 0x40 + 7)
-#define	AT91_PIN_PC8	(PIN_BASE + 0x40 + 8)
-#define	AT91_PIN_PC9	(PIN_BASE + 0x40 + 9)
-#define	AT91_PIN_PC10	(PIN_BASE + 0x40 + 10)
-#define	AT91_PIN_PC11	(PIN_BASE + 0x40 + 11)
-#define	AT91_PIN_PC12	(PIN_BASE + 0x40 + 12)
-#define	AT91_PIN_PC13	(PIN_BASE + 0x40 + 13)
-#define	AT91_PIN_PC14	(PIN_BASE + 0x40 + 14)
-#define	AT91_PIN_PC15	(PIN_BASE + 0x40 + 15)
-#define	AT91_PIN_PC16	(PIN_BASE + 0x40 + 16)
-#define	AT91_PIN_PC17	(PIN_BASE + 0x40 + 17)
-#define	AT91_PIN_PC18	(PIN_BASE + 0x40 + 18)
-#define	AT91_PIN_PC19	(PIN_BASE + 0x40 + 19)
-#define	AT91_PIN_PC20	(PIN_BASE + 0x40 + 20)
-#define	AT91_PIN_PC21	(PIN_BASE + 0x40 + 21)
-#define	AT91_PIN_PC22	(PIN_BASE + 0x40 + 22)
-#define	AT91_PIN_PC23	(PIN_BASE + 0x40 + 23)
-#define	AT91_PIN_PC24	(PIN_BASE + 0x40 + 24)
-#define	AT91_PIN_PC25	(PIN_BASE + 0x40 + 25)
-#define	AT91_PIN_PC26	(PIN_BASE + 0x40 + 26)
-#define	AT91_PIN_PC27	(PIN_BASE + 0x40 + 27)
-#define	AT91_PIN_PC28	(PIN_BASE + 0x40 + 28)
-#define	AT91_PIN_PC29	(PIN_BASE + 0x40 + 29)
-#define	AT91_PIN_PC30	(PIN_BASE + 0x40 + 30)
-#define	AT91_PIN_PC31	(PIN_BASE + 0x40 + 31)
-
-#define	AT91_PIN_PD0	(PIN_BASE + 0x60 + 0)
-#define	AT91_PIN_PD1	(PIN_BASE + 0x60 + 1)
-#define	AT91_PIN_PD2	(PIN_BASE + 0x60 + 2)
-#define	AT91_PIN_PD3	(PIN_BASE + 0x60 + 3)
-#define	AT91_PIN_PD4	(PIN_BASE + 0x60 + 4)
-#define	AT91_PIN_PD5	(PIN_BASE + 0x60 + 5)
-#define	AT91_PIN_PD6	(PIN_BASE + 0x60 + 6)
-#define	AT91_PIN_PD7	(PIN_BASE + 0x60 + 7)
-#define	AT91_PIN_PD8	(PIN_BASE + 0x60 + 8)
-#define	AT91_PIN_PD9	(PIN_BASE + 0x60 + 9)
-#define	AT91_PIN_PD10	(PIN_BASE + 0x60 + 10)
-#define	AT91_PIN_PD11	(PIN_BASE + 0x60 + 11)
-#define	AT91_PIN_PD12	(PIN_BASE + 0x60 + 12)
-#define	AT91_PIN_PD13	(PIN_BASE + 0x60 + 13)
-#define	AT91_PIN_PD14	(PIN_BASE + 0x60 + 14)
-#define	AT91_PIN_PD15	(PIN_BASE + 0x60 + 15)
-#define	AT91_PIN_PD16	(PIN_BASE + 0x60 + 16)
-#define	AT91_PIN_PD17	(PIN_BASE + 0x60 + 17)
-#define	AT91_PIN_PD18	(PIN_BASE + 0x60 + 18)
-#define	AT91_PIN_PD19	(PIN_BASE + 0x60 + 19)
-#define	AT91_PIN_PD20	(PIN_BASE + 0x60 + 20)
-#define	AT91_PIN_PD21	(PIN_BASE + 0x60 + 21)
-#define	AT91_PIN_PD22	(PIN_BASE + 0x60 + 22)
-#define	AT91_PIN_PD23	(PIN_BASE + 0x60 + 23)
-#define	AT91_PIN_PD24	(PIN_BASE + 0x60 + 24)
-#define	AT91_PIN_PD25	(PIN_BASE + 0x60 + 25)
-#define	AT91_PIN_PD26	(PIN_BASE + 0x60 + 26)
-#define	AT91_PIN_PD27	(PIN_BASE + 0x60 + 27)
-#define	AT91_PIN_PD28	(PIN_BASE + 0x60 + 28)
-#define	AT91_PIN_PD29	(PIN_BASE + 0x60 + 29)
-#define	AT91_PIN_PD30	(PIN_BASE + 0x60 + 30)
-#define	AT91_PIN_PD31	(PIN_BASE + 0x60 + 31)
-
-#define	AT91_PIN_PE0	(PIN_BASE + 0x80 + 0)
-#define	AT91_PIN_PE1	(PIN_BASE + 0x80 + 1)
-#define	AT91_PIN_PE2	(PIN_BASE + 0x80 + 2)
-#define	AT91_PIN_PE3	(PIN_BASE + 0x80 + 3)
-#define	AT91_PIN_PE4	(PIN_BASE + 0x80 + 4)
-#define	AT91_PIN_PE5	(PIN_BASE + 0x80 + 5)
-#define	AT91_PIN_PE6	(PIN_BASE + 0x80 + 6)
-#define	AT91_PIN_PE7	(PIN_BASE + 0x80 + 7)
-#define	AT91_PIN_PE8	(PIN_BASE + 0x80 + 8)
-#define	AT91_PIN_PE9	(PIN_BASE + 0x80 + 9)
-#define	AT91_PIN_PE10	(PIN_BASE + 0x80 + 10)
-#define	AT91_PIN_PE11	(PIN_BASE + 0x80 + 11)
-#define	AT91_PIN_PE12	(PIN_BASE + 0x80 + 12)
-#define	AT91_PIN_PE13	(PIN_BASE + 0x80 + 13)
-#define	AT91_PIN_PE14	(PIN_BASE + 0x80 + 14)
-#define	AT91_PIN_PE15	(PIN_BASE + 0x80 + 15)
-#define	AT91_PIN_PE16	(PIN_BASE + 0x80 + 16)
-#define	AT91_PIN_PE17	(PIN_BASE + 0x80 + 17)
-#define	AT91_PIN_PE18	(PIN_BASE + 0x80 + 18)
-#define	AT91_PIN_PE19	(PIN_BASE + 0x80 + 19)
-#define	AT91_PIN_PE20	(PIN_BASE + 0x80 + 20)
-#define	AT91_PIN_PE21	(PIN_BASE + 0x80 + 21)
-#define	AT91_PIN_PE22	(PIN_BASE + 0x80 + 22)
-#define	AT91_PIN_PE23	(PIN_BASE + 0x80 + 23)
-#define	AT91_PIN_PE24	(PIN_BASE + 0x80 + 24)
-#define	AT91_PIN_PE25	(PIN_BASE + 0x80 + 25)
-#define	AT91_PIN_PE26	(PIN_BASE + 0x80 + 26)
-#define	AT91_PIN_PE27	(PIN_BASE + 0x80 + 27)
-#define	AT91_PIN_PE28	(PIN_BASE + 0x80 + 28)
-#define	AT91_PIN_PE29	(PIN_BASE + 0x80 + 29)
-#define	AT91_PIN_PE30	(PIN_BASE + 0x80 + 30)
-#define	AT91_PIN_PE31	(PIN_BASE + 0x80 + 31)
-
-#ifndef __ASSEMBLY__
-/* setup setup routines, called from board init or driver probe() */
-extern int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup);
-extern int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup);
-extern int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup);
-extern int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup);
-extern int __init_or_module at91_set_gpio_output(unsigned pin, int value);
-extern int __init_or_module at91_set_deglitch(unsigned pin, int is_on);
-extern int __init_or_module at91_set_multi_drive(unsigned pin, int is_on);
-
-/* callable at any time */
-extern int at91_set_gpio_value(unsigned pin, int value);
-extern int at91_get_gpio_value(unsigned pin);
-
-/* callable only from core power-management code */
-extern void at91_gpio_suspend(void);
-extern void at91_gpio_resume(void);
-
-/*-------------------------------------------------------------------------*/
-
-/* wrappers for "new style" GPIO calls. the old AT91-specific ones should
- * eventually be removed (along with this errno.h inclusion), and the
- * gpio request/free calls should probably be implemented.
- */
-
-#include <asm/errno.h>
-#include <asm-generic/gpio.h>		/* cansleep wrappers */
-
-#define gpio_get_value	__gpio_get_value
-#define gpio_set_value	__gpio_set_value
-#define gpio_cansleep	__gpio_cansleep
-
-#define gpio_to_irq(gpio) (gpio)
-#define irq_to_gpio(irq)  (irq)
-
-#endif	/* __ASSEMBLY__ */
-
-#endif
+/*
+ * arch/arm/mach-at91/include/mach/gpio.h
+ *
+ *  Copyright (C) 2005 HP Labs
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#ifndef __ASM_ARCH_AT91RM9200_GPIO_H
+#define __ASM_ARCH_AT91RM9200_GPIO_H
+
+#include <linux/kernel.h>
+#include <asm/irq.h>
+
+#define MAX_GPIO_BANKS		5
+#define NR_BUILTIN_GPIO		(MAX_GPIO_BANKS * 32)
+
+/* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */
+
+#define	AT91_PIN_PA0	(0x00 + 0)
+#define	AT91_PIN_PA1	(0x00 + 1)
+#define	AT91_PIN_PA2	(0x00 + 2)
+#define	AT91_PIN_PA3	(0x00 + 3)
+#define	AT91_PIN_PA4	(0x00 + 4)
+#define	AT91_PIN_PA5	(0x00 + 5)
+#define	AT91_PIN_PA6	(0x00 + 6)
+#define	AT91_PIN_PA7	(0x00 + 7)
+#define	AT91_PIN_PA8	(0x00 + 8)
+#define	AT91_PIN_PA9	(0x00 + 9)
+#define	AT91_PIN_PA10	(0x00 + 10)
+#define	AT91_PIN_PA11	(0x00 + 11)
+#define	AT91_PIN_PA12	(0x00 + 12)
+#define	AT91_PIN_PA13	(0x00 + 13)
+#define	AT91_PIN_PA14	(0x00 + 14)
+#define	AT91_PIN_PA15	(0x00 + 15)
+#define	AT91_PIN_PA16	(0x00 + 16)
+#define	AT91_PIN_PA17	(0x00 + 17)
+#define	AT91_PIN_PA18	(0x00 + 18)
+#define	AT91_PIN_PA19	(0x00 + 19)
+#define	AT91_PIN_PA20	(0x00 + 20)
+#define	AT91_PIN_PA21	(0x00 + 21)
+#define	AT91_PIN_PA22	(0x00 + 22)
+#define	AT91_PIN_PA23	(0x00 + 23)
+#define	AT91_PIN_PA24	(0x00 + 24)
+#define	AT91_PIN_PA25	(0x00 + 25)
+#define	AT91_PIN_PA26	(0x00 + 26)
+#define	AT91_PIN_PA27	(0x00 + 27)
+#define	AT91_PIN_PA28	(0x00 + 28)
+#define	AT91_PIN_PA29	(0x00 + 29)
+#define	AT91_PIN_PA30	(0x00 + 30)
+#define	AT91_PIN_PA31	(0x00 + 31)
+
+#define	AT91_PIN_PB0	(0x20 + 0)
+#define	AT91_PIN_PB1	(0x20 + 1)
+#define	AT91_PIN_PB2	(0x20 + 2)
+#define	AT91_PIN_PB3	(0x20 + 3)
+#define	AT91_PIN_PB4	(0x20 + 4)
+#define	AT91_PIN_PB5	(0x20 + 5)
+#define	AT91_PIN_PB6	(0x20 + 6)
+#define	AT91_PIN_PB7	(0x20 + 7)
+#define	AT91_PIN_PB8	(0x20 + 8)
+#define	AT91_PIN_PB9	(0x20 + 9)
+#define	AT91_PIN_PB10	(0x20 + 10)
+#define	AT91_PIN_PB11	(0x20 + 11)
+#define	AT91_PIN_PB12	(0x20 + 12)
+#define	AT91_PIN_PB13	(0x20 + 13)
+#define	AT91_PIN_PB14	(0x20 + 14)
+#define	AT91_PIN_PB15	(0x20 + 15)
+#define	AT91_PIN_PB16	(0x20 + 16)
+#define	AT91_PIN_PB17	(0x20 + 17)
+#define	AT91_PIN_PB18	(0x20 + 18)
+#define	AT91_PIN_PB19	(0x20 + 19)
+#define	AT91_PIN_PB20	(0x20 + 20)
+#define	AT91_PIN_PB21	(0x20 + 21)
+#define	AT91_PIN_PB22	(0x20 + 22)
+#define	AT91_PIN_PB23	(0x20 + 23)
+#define	AT91_PIN_PB24	(0x20 + 24)
+#define	AT91_PIN_PB25	(0x20 + 25)
+#define	AT91_PIN_PB26	(0x20 + 26)
+#define	AT91_PIN_PB27	(0x20 + 27)
+#define	AT91_PIN_PB28	(0x20 + 28)
+#define	AT91_PIN_PB29	(0x20 + 29)
+#define	AT91_PIN_PB30	(0x20 + 30)
+#define	AT91_PIN_PB31	(0x20 + 31)
+
+#define	AT91_PIN_PC0	(0x40 + 0)
+#define	AT91_PIN_PC1	(0x40 + 1)
+#define	AT91_PIN_PC2	(0x40 + 2)
+#define	AT91_PIN_PC3	(0x40 + 3)
+#define	AT91_PIN_PC4	(0x40 + 4)
+#define	AT91_PIN_PC5	(0x40 + 5)
+#define	AT91_PIN_PC6	(0x40 + 6)
+#define	AT91_PIN_PC7	(0x40 + 7)
+#define	AT91_PIN_PC8	(0x40 + 8)
+#define	AT91_PIN_PC9	(0x40 + 9)
+#define	AT91_PIN_PC10	(0x40 + 10)
+#define	AT91_PIN_PC11	(0x40 + 11)
+#define	AT91_PIN_PC12	(0x40 + 12)
+#define	AT91_PIN_PC13	(0x40 + 13)
+#define	AT91_PIN_PC14	(0x40 + 14)
+#define	AT91_PIN_PC15	(0x40 + 15)
+#define	AT91_PIN_PC16	(0x40 + 16)
+#define	AT91_PIN_PC17	(0x40 + 17)
+#define	AT91_PIN_PC18	(0x40 + 18)
+#define	AT91_PIN_PC19	(0x40 + 19)
+#define	AT91_PIN_PC20	(0x40 + 20)
+#define	AT91_PIN_PC21	(0x40 + 21)
+#define	AT91_PIN_PC22	(0x40 + 22)
+#define	AT91_PIN_PC23	(0x40 + 23)
+#define	AT91_PIN_PC24	(0x40 + 24)
+#define	AT91_PIN_PC25	(0x40 + 25)
+#define	AT91_PIN_PC26	(0x40 + 26)
+#define	AT91_PIN_PC27	(0x40 + 27)
+#define	AT91_PIN_PC28	(0x40 + 28)
+#define	AT91_PIN_PC29	(0x40 + 29)
+#define	AT91_PIN_PC30	(0x40 + 30)
+#define	AT91_PIN_PC31	(0x40 + 31)
+
+#define	AT91_PIN_PD0	(0x60 + 0)
+#define	AT91_PIN_PD1	(0x60 + 1)
+#define	AT91_PIN_PD2	(0x60 + 2)
+#define	AT91_PIN_PD3	(0x60 + 3)
+#define	AT91_PIN_PD4	(0x60 + 4)
+#define	AT91_PIN_PD5	(0x60 + 5)
+#define	AT91_PIN_PD6	(0x60 + 6)
+#define	AT91_PIN_PD7	(0x60 + 7)
+#define	AT91_PIN_PD8	(0x60 + 8)
+#define	AT91_PIN_PD9	(0x60 + 9)
+#define	AT91_PIN_PD10	(0x60 + 10)
+#define	AT91_PIN_PD11	(0x60 + 11)
+#define	AT91_PIN_PD12	(0x60 + 12)
+#define	AT91_PIN_PD13	(0x60 + 13)
+#define	AT91_PIN_PD14	(0x60 + 14)
+#define	AT91_PIN_PD15	(0x60 + 15)
+#define	AT91_PIN_PD16	(0x60 + 16)
+#define	AT91_PIN_PD17	(0x60 + 17)
+#define	AT91_PIN_PD18	(0x60 + 18)
+#define	AT91_PIN_PD19	(0x60 + 19)
+#define	AT91_PIN_PD20	(0x60 + 20)
+#define	AT91_PIN_PD21	(0x60 + 21)
+#define	AT91_PIN_PD22	(0x60 + 22)
+#define	AT91_PIN_PD23	(0x60 + 23)
+#define	AT91_PIN_PD24	(0x60 + 24)
+#define	AT91_PIN_PD25	(0x60 + 25)
+#define	AT91_PIN_PD26	(0x60 + 26)
+#define	AT91_PIN_PD27	(0x60 + 27)
+#define	AT91_PIN_PD28	(0x60 + 28)
+#define	AT91_PIN_PD29	(0x60 + 29)
+#define	AT91_PIN_PD30	(0x60 + 30)
+#define	AT91_PIN_PD31	(0x60 + 31)
+
+#define	AT91_PIN_PE0	(0x80 + 0)
+#define	AT91_PIN_PE1	(0x80 + 1)
+#define	AT91_PIN_PE2	(0x80 + 2)
+#define	AT91_PIN_PE3	(0x80 + 3)
+#define	AT91_PIN_PE4	(0x80 + 4)
+#define	AT91_PIN_PE5	(0x80 + 5)
+#define	AT91_PIN_PE6	(0x80 + 6)
+#define	AT91_PIN_PE7	(0x80 + 7)
+#define	AT91_PIN_PE8	(0x80 + 8)
+#define	AT91_PIN_PE9	(0x80 + 9)
+#define	AT91_PIN_PE10	(0x80 + 10)
+#define	AT91_PIN_PE11	(0x80 + 11)
+#define	AT91_PIN_PE12	(0x80 + 12)
+#define	AT91_PIN_PE13	(0x80 + 13)
+#define	AT91_PIN_PE14	(0x80 + 14)
+#define	AT91_PIN_PE15	(0x80 + 15)
+#define	AT91_PIN_PE16	(0x80 + 16)
+#define	AT91_PIN_PE17	(0x80 + 17)
+#define	AT91_PIN_PE18	(0x80 + 18)
+#define	AT91_PIN_PE19	(0x80 + 19)
+#define	AT91_PIN_PE20	(0x80 + 20)
+#define	AT91_PIN_PE21	(0x80 + 21)
+#define	AT91_PIN_PE22	(0x80 + 22)
+#define	AT91_PIN_PE23	(0x80 + 23)
+#define	AT91_PIN_PE24	(0x80 + 24)
+#define	AT91_PIN_PE25	(0x80 + 25)
+#define	AT91_PIN_PE26	(0x80 + 26)
+#define	AT91_PIN_PE27	(0x80 + 27)
+#define	AT91_PIN_PE28	(0x80 + 28)
+#define	AT91_PIN_PE29	(0x80 + 29)
+#define	AT91_PIN_PE30	(0x80 + 30)
+#define	AT91_PIN_PE31	(0x80 + 31)
+
+#ifndef __ASSEMBLY__
+/* setup setup routines, called from board init or driver probe() */
+extern int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup);
+extern int __init_or_module at91_set_A_periph(unsigned pin, int use_pullup);
+extern int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup);
+extern int __init_or_module at91_set_gpio_input(unsigned pin, int use_pullup);
+extern int __init_or_module at91_set_gpio_output(unsigned pin, int value);
+extern int __init_or_module at91_set_deglitch(unsigned pin, int is_on);
+extern int __init_or_module at91_set_multi_drive(unsigned pin, int is_on);
+
+/* callable at any time */
+extern int at91_set_gpio_value(unsigned pin, int value);
+extern int at91_get_gpio_value(unsigned pin);
+
+/* callable only from core power-management code */
+extern void at91_gpio_suspend(void);
+extern void at91_gpio_resume(void);
+
+/*-------------------------------------------------------------------------*/
+
+/* wrappers for "new style" GPIO calls. the old AT91-specific ones should
+ * eventually be removed (along with this errno.h inclusion), and the
+ * gpio request/free calls should probably be implemented.
+ */
+
+#include <asm/errno.h>
+#include <asm-generic/gpio.h>		/* cansleep wrappers */
+
+#define gpio_get_value	__gpio_get_value
+#define gpio_set_value	__gpio_set_value
+#define gpio_cansleep	__gpio_cansleep
+
+#define gpio_to_irq(gpio) (gpio + NR_AIC_IRQS)
+#define irq_to_gpio(irq)  (irq - NR_AIC_IRQS)
+
+#endif	/* __ASSEMBLY__ */
+
+#endif
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 1/3] at91/gpio: make gpio register base soc independant
From: Jean-Christophe PLAGNIOL-VILLARD @ 2011-09-17 18:58 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
---
 arch/arm/mach-at91/at91cap9.c                 |    8 ++++----
 arch/arm/mach-at91/at91rm9200.c               |    8 ++++----
 arch/arm/mach-at91/at91sam9260.c              |    6 +++---
 arch/arm/mach-at91/at91sam9261.c              |    6 +++---
 arch/arm/mach-at91/at91sam9263.c              |   10 +++++-----
 arch/arm/mach-at91/at91sam9g45.c              |   10 +++++-----
 arch/arm/mach-at91/at91sam9rl.c               |    8 ++++----
 arch/arm/mach-at91/generic.h                  |    2 +-
 arch/arm/mach-at91/gpio.c                     |    8 ++++++--
 arch/arm/mach-at91/include/mach/at91cap9.h    |    9 +++++----
 arch/arm/mach-at91/include/mach/at91rm9200.h  |    9 +++++----
 arch/arm/mach-at91/include/mach/at91sam9260.h |    7 ++++---
 arch/arm/mach-at91/include/mach/at91sam9261.h |    7 ++++---
 arch/arm/mach-at91/include/mach/at91sam9263.h |   11 ++++++-----
 arch/arm/mach-at91/include/mach/at91sam9g45.h |   11 ++++++-----
 arch/arm/mach-at91/include/mach/at91sam9rl.h  |    9 +++++----
 16 files changed, 70 insertions(+), 59 deletions(-)

diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c
index ecdd54d..fe00dce 100644
--- a/arch/arm/mach-at91/at91cap9.c
+++ b/arch/arm/mach-at91/at91cap9.c
@@ -296,19 +296,19 @@ void __init at91cap9_set_console_clock(int id)
 static struct at91_gpio_bank at91cap9_gpio[] = {
 	{
 		.id		= AT91CAP9_ID_PIOABCD,
-		.offset		= AT91_PIOA,
+		.regbase	= AT91CAP9_BASE_PIOA,
 		.clock		= &pioABCD_clk,
 	}, {
 		.id		= AT91CAP9_ID_PIOABCD,
-		.offset		= AT91_PIOB,
+		.regbase	= AT91CAP9_BASE_PIOB,
 		.clock		= &pioABCD_clk,
 	}, {
 		.id		= AT91CAP9_ID_PIOABCD,
-		.offset		= AT91_PIOC,
+		.regbase	= AT91CAP9_BASE_PIOC,
 		.clock		= &pioABCD_clk,
 	}, {
 		.id		= AT91CAP9_ID_PIOABCD,
-		.offset		= AT91_PIOD,
+		.regbase	= AT91CAP9_BASE_PIOD,
 		.clock		= &pioABCD_clk,
 	}
 };
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index 713d3bd..8ce8675 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -271,19 +271,19 @@ void __init at91rm9200_set_console_clock(int id)
 static struct at91_gpio_bank at91rm9200_gpio[] = {
 	{
 		.id		= AT91RM9200_ID_PIOA,
-		.offset		= AT91_PIOA,
+		.regbase	= AT91RM9200_BASE_PIOA,
 		.clock		= &pioA_clk,
 	}, {
 		.id		= AT91RM9200_ID_PIOB,
-		.offset		= AT91_PIOB,
+		.regbase	= AT91RM9200_BASE_PIOB,
 		.clock		= &pioB_clk,
 	}, {
 		.id		= AT91RM9200_ID_PIOC,
-		.offset		= AT91_PIOC,
+		.regbase	= AT91RM9200_BASE_PIOC,
 		.clock		= &pioC_clk,
 	}, {
 		.id		= AT91RM9200_ID_PIOD,
-		.offset		= AT91_PIOD,
+		.regbase	= AT91RM9200_BASE_PIOD,
 		.clock		= &pioD_clk,
 	}
 };
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index a9be758..d7ad3e0 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -265,15 +265,15 @@ void __init at91sam9260_set_console_clock(int id)
 static struct at91_gpio_bank at91sam9260_gpio[] = {
 	{
 		.id		= AT91SAM9260_ID_PIOA,
-		.offset		= AT91_PIOA,
+		.regbase	= AT91SAM9260_BASE_PIOA,
 		.clock		= &pioA_clk,
 	}, {
 		.id		= AT91SAM9260_ID_PIOB,
-		.offset		= AT91_PIOB,
+		.regbase	= AT91SAM9260_BASE_PIOB,
 		.clock		= &pioB_clk,
 	}, {
 		.id		= AT91SAM9260_ID_PIOC,
-		.offset		= AT91_PIOC,
+		.regbase	= AT91SAM9260_BASE_PIOC,
 		.clock		= &pioC_clk,
 	}
 };
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index 658a518..574aa6b 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -254,15 +254,15 @@ void __init at91sam9261_set_console_clock(int id)
 static struct at91_gpio_bank at91sam9261_gpio[] = {
 	{
 		.id		= AT91SAM9261_ID_PIOA,
-		.offset		= AT91_PIOA,
+		.regbase	= AT91SAM9261_BASE_PIOA,
 		.clock		= &pioA_clk,
 	}, {
 		.id		= AT91SAM9261_ID_PIOB,
-		.offset		= AT91_PIOB,
+		.regbase	= AT91SAM9261_BASE_PIOB,
 		.clock		= &pioB_clk,
 	}, {
 		.id		= AT91SAM9261_ID_PIOC,
-		.offset		= AT91_PIOC,
+		.regbase	= AT91SAM9261_BASE_PIOC,
 		.clock		= &pioC_clk,
 	}
 };
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index f83fbb0..dee0ed7 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -266,23 +266,23 @@ void __init at91sam9263_set_console_clock(int id)
 static struct at91_gpio_bank at91sam9263_gpio[] = {
 	{
 		.id		= AT91SAM9263_ID_PIOA,
-		.offset		= AT91_PIOA,
+		.regbase	= AT91SAM9263_BASE_PIOA,
 		.clock		= &pioA_clk,
 	}, {
 		.id		= AT91SAM9263_ID_PIOB,
-		.offset		= AT91_PIOB,
+		.regbase	= AT91SAM9263_BASE_PIOB,
 		.clock		= &pioB_clk,
 	}, {
 		.id		= AT91SAM9263_ID_PIOCDE,
-		.offset		= AT91_PIOC,
+		.regbase	= AT91SAM9263_BASE_PIOC,
 		.clock		= &pioCDE_clk,
 	}, {
 		.id		= AT91SAM9263_ID_PIOCDE,
-		.offset		= AT91_PIOD,
+		.regbase	= AT91SAM9263_BASE_PIOD,
 		.clock		= &pioCDE_clk,
 	}, {
 		.id		= AT91SAM9263_ID_PIOCDE,
-		.offset		= AT91_PIOE,
+		.regbase	= AT91SAM9263_BASE_PIOE,
 		.clock		= &pioCDE_clk,
 	}
 };
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index 8f5db7b..753df63 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -282,23 +282,23 @@ void __init at91sam9g45_set_console_clock(int id)
 static struct at91_gpio_bank at91sam9g45_gpio[] = {
 	{
 		.id		= AT91SAM9G45_ID_PIOA,
-		.offset		= AT91_PIOA,
+		.regbase	= AT91SAM9G45_BASE_PIOA,
 		.clock		= &pioA_clk,
 	}, {
 		.id		= AT91SAM9G45_ID_PIOB,
-		.offset		= AT91_PIOB,
+		.regbase	= AT91SAM9G45_BASE_PIOB,
 		.clock		= &pioB_clk,
 	}, {
 		.id		= AT91SAM9G45_ID_PIOC,
-		.offset		= AT91_PIOC,
+		.regbase	= AT91SAM9G45_BASE_PIOC,
 		.clock		= &pioC_clk,
 	}, {
 		.id		= AT91SAM9G45_ID_PIODE,
-		.offset		= AT91_PIOD,
+		.regbase	= AT91SAM9G45_BASE_PIOD,
 		.clock		= &pioDE_clk,
 	}, {
 		.id		= AT91SAM9G45_ID_PIODE,
-		.offset		= AT91_PIOE,
+		.regbase	= AT91SAM9G45_BASE_PIOE,
 		.clock		= &pioDE_clk,
 	}
 };
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index a238105..c4004e2 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -246,19 +246,19 @@ void __init at91sam9rl_set_console_clock(int id)
 static struct at91_gpio_bank at91sam9rl_gpio[] = {
 	{
 		.id		= AT91SAM9RL_ID_PIOA,
-		.offset		= AT91_PIOA,
+		.regbase	= AT91SAM9RL_BASE_PIOA,
 		.clock		= &pioA_clk,
 	}, {
 		.id		= AT91SAM9RL_ID_PIOB,
-		.offset		= AT91_PIOB,
+		.regbase	= AT91SAM9RL_BASE_PIOB,
 		.clock		= &pioB_clk,
 	}, {
 		.id		= AT91SAM9RL_ID_PIOC,
-		.offset		= AT91_PIOC,
+		.regbase	= AT91SAM9RL_BASE_PIOC,
 		.clock		= &pioC_clk,
 	}, {
 		.id		= AT91SAM9RL_ID_PIOD,
-		.offset		= AT91_PIOD,
+		.regbase	= AT91SAM9RL_BASE_PIOD,
 		.clock		= &pioD_clk,
 	}
 };
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index 938b34f..11d7297 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -65,7 +65,7 @@ extern void at91sam9_alt_reset(void);
 
 struct at91_gpio_bank {
 	unsigned short id;		/* peripheral ID */
-	unsigned long offset;		/* offset from system peripheral base */
+	unsigned long regbase;		/* offset from system peripheral base */
 	struct clk *clock;		/* associated clock */
 };
 extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks);
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index 4615528..04beff1 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -616,8 +616,12 @@ void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
 
 		at91_gpio->bank = &data[i];
 		at91_gpio->chip.base = PIN_BASE + i * 32;
-		at91_gpio->regbase = at91_gpio->bank->offset +
-			(void __iomem *)AT91_VA_BASE_SYS;
+
+		at91_gpio->regbase = ioremap(at91_gpio->bank->regbase, 512);
+		if (!at91_gpio->regbase) {
+			pr_err("at91_gpio.%d, failed to map registers, ignoring.\n", i);
+			continue;
+		}
 
 		/* enable PIO controller's clock */
 		clk_enable(at91_gpio->bank->clock);
diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h
index c5df1e8..f65d083 100644
--- a/arch/arm/mach-at91/include/mach/at91cap9.h
+++ b/arch/arm/mach-at91/include/mach/at91cap9.h
@@ -88,10 +88,6 @@
 #define AT91_DMA	(0xffffec00 - AT91_BASE_SYS)
 #define AT91_DBGU	(0xffffee00 - AT91_BASE_SYS)
 #define AT91_AIC	(0xfffff000 - AT91_BASE_SYS)
-#define AT91_PIOA	(0xfffff200 - AT91_BASE_SYS)
-#define AT91_PIOB	(0xfffff400 - AT91_BASE_SYS)
-#define AT91_PIOC	(0xfffff600 - AT91_BASE_SYS)
-#define AT91_PIOD	(0xfffff800 - AT91_BASE_SYS)
 #define AT91_PMC	(0xfffffc00 - AT91_BASE_SYS)
 #define AT91_RSTC	(0xfffffd00 - AT91_BASE_SYS)
 #define AT91_SHDWC	(0xfffffd10 - AT91_BASE_SYS)
@@ -102,6 +98,11 @@
 			(0xfffffd50 - AT91_BASE_SYS) :	\
 			(0xfffffd60 - AT91_BASE_SYS))
 
+#define AT91CAP9_BASE_PIOA	0xfffff200
+#define AT91CAP9_BASE_PIOB	0xfffff400
+#define AT91CAP9_BASE_PIOC	0xfffff600
+#define AT91CAP9_BASE_PIOD	0xfffff800
+
 #define AT91_USART0	AT91CAP9_BASE_US0
 #define AT91_USART1	AT91CAP9_BASE_US1
 #define AT91_USART2	AT91CAP9_BASE_US2
diff --git a/arch/arm/mach-at91/include/mach/at91rm9200.h b/arch/arm/mach-at91/include/mach/at91rm9200.h
index e4037b5..5740954 100644
--- a/arch/arm/mach-at91/include/mach/at91rm9200.h
+++ b/arch/arm/mach-at91/include/mach/at91rm9200.h
@@ -81,15 +81,16 @@
  */
 #define AT91_AIC	(0xfffff000 - AT91_BASE_SYS)	/* Advanced Interrupt Controller */
 #define AT91_DBGU	(0xfffff200 - AT91_BASE_SYS)	/* Debug Unit */
-#define AT91_PIOA	(0xfffff400 - AT91_BASE_SYS)	/* PIO Controller A */
-#define AT91_PIOB	(0xfffff600 - AT91_BASE_SYS)	/* PIO Controller B */
-#define AT91_PIOC	(0xfffff800 - AT91_BASE_SYS)	/* PIO Controller C */
-#define AT91_PIOD	(0xfffffa00 - AT91_BASE_SYS)	/* PIO Controller D */
 #define AT91_PMC	(0xfffffc00 - AT91_BASE_SYS)	/* Power Management Controller */
 #define AT91_ST		(0xfffffd00 - AT91_BASE_SYS)	/* System Timer */
 #define AT91_RTC	(0xfffffe00 - AT91_BASE_SYS)	/* Real-Time Clock */
 #define AT91_MC		(0xffffff00 - AT91_BASE_SYS)	/* Memory Controllers */
 
+#define AT91RM9200_BASE_PIOA	0xfffff400	/* PIO Controller A */
+#define AT91RM9200_BASE_PIOB	0xfffff600	/* PIO Controller B */
+#define AT91RM9200_BASE_PIOC	0xfffff800	/* PIO Controller C */
+#define AT91RM9200_BASE_PIOD	0xfffffa00	/* PIO Controller D */
+
 #define AT91_USART0	AT91RM9200_BASE_US0
 #define AT91_USART1	AT91RM9200_BASE_US1
 #define AT91_USART2	AT91RM9200_BASE_US2
diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h
index 9a79116..1bea3dc 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9260.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9260.h
@@ -87,9 +87,6 @@
 #define AT91_CCFG	(0xffffef10 - AT91_BASE_SYS)
 #define AT91_AIC	(0xfffff000 - AT91_BASE_SYS)
 #define AT91_DBGU	(0xfffff200 - AT91_BASE_SYS)
-#define AT91_PIOA	(0xfffff400 - AT91_BASE_SYS)
-#define AT91_PIOB	(0xfffff600 - AT91_BASE_SYS)
-#define AT91_PIOC	(0xfffff800 - AT91_BASE_SYS)
 #define AT91_PMC	(0xfffffc00 - AT91_BASE_SYS)
 #define AT91_RSTC	(0xfffffd00 - AT91_BASE_SYS)
 #define AT91_SHDWC	(0xfffffd10 - AT91_BASE_SYS)
@@ -98,6 +95,10 @@
 #define AT91_WDT	(0xfffffd40 - AT91_BASE_SYS)
 #define AT91_GPBR	(0xfffffd50 - AT91_BASE_SYS)
 
+#define AT91SAM9260_BASE_PIOA	0xfffff400
+#define AT91SAM9260_BASE_PIOB	0xfffff600
+#define AT91SAM9260_BASE_PIOC	0xfffff800
+
 #define AT91_USART0	AT91SAM9260_BASE_US0
 #define AT91_USART1	AT91SAM9260_BASE_US1
 #define AT91_USART2	AT91SAM9260_BASE_US2
diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h
index ce59620..17ae9c7 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9261.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9261.h
@@ -70,9 +70,6 @@
 #define AT91_MATRIX	(0xffffee00 - AT91_BASE_SYS)
 #define AT91_AIC	(0xfffff000 - AT91_BASE_SYS)
 #define AT91_DBGU	(0xfffff200 - AT91_BASE_SYS)
-#define AT91_PIOA	(0xfffff400 - AT91_BASE_SYS)
-#define AT91_PIOB	(0xfffff600 - AT91_BASE_SYS)
-#define AT91_PIOC	(0xfffff800 - AT91_BASE_SYS)
 #define AT91_PMC	(0xfffffc00 - AT91_BASE_SYS)
 #define AT91_RSTC	(0xfffffd00 - AT91_BASE_SYS)
 #define AT91_SHDWC	(0xfffffd10 - AT91_BASE_SYS)
@@ -81,6 +78,10 @@
 #define AT91_WDT	(0xfffffd40 - AT91_BASE_SYS)
 #define AT91_GPBR	(0xfffffd50 - AT91_BASE_SYS)
 
+#define AT91SAM9261_BASE_PIOA	0xfffff400
+#define AT91SAM9261_BASE_PIOB	0xfffff600
+#define AT91SAM9261_BASE_PIOC	0xfffff800
+
 #define AT91_USART0	AT91SAM9261_BASE_US0
 #define AT91_USART1	AT91SAM9261_BASE_US1
 #define AT91_USART2	AT91SAM9261_BASE_US2
diff --git a/arch/arm/mach-at91/include/mach/at91sam9263.h b/arch/arm/mach-at91/include/mach/at91sam9263.h
index f1b9296..dd54079 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9263.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9263.h
@@ -84,11 +84,6 @@
 #define AT91_CCFG	(0xffffed10 - AT91_BASE_SYS)
 #define AT91_DBGU	(0xffffee00 - AT91_BASE_SYS)
 #define AT91_AIC	(0xfffff000 - AT91_BASE_SYS)
-#define AT91_PIOA	(0xfffff200 - AT91_BASE_SYS)
-#define AT91_PIOB	(0xfffff400 - AT91_BASE_SYS)
-#define AT91_PIOC	(0xfffff600 - AT91_BASE_SYS)
-#define AT91_PIOD	(0xfffff800 - AT91_BASE_SYS)
-#define AT91_PIOE	(0xfffffa00 - AT91_BASE_SYS)
 #define AT91_PMC	(0xfffffc00 - AT91_BASE_SYS)
 #define AT91_RSTC	(0xfffffd00 - AT91_BASE_SYS)
 #define AT91_SHDWC	(0xfffffd10 - AT91_BASE_SYS)
@@ -98,6 +93,12 @@
 #define AT91_RTT1	(0xfffffd50 - AT91_BASE_SYS)
 #define AT91_GPBR	(0xfffffd60 - AT91_BASE_SYS)
 
+#define AT91SAM9263_BASE_PIOA	0xfffff200
+#define AT91SAM9263_BASE_PIOB	0xfffff400
+#define AT91SAM9263_BASE_PIOC	0xfffff600
+#define AT91SAM9263_BASE_PIOD	0xfffff800
+#define AT91SAM9263_BASE_PIOE	0xfffffa00
+
 #define AT91_USART0	AT91SAM9263_BASE_US0
 #define AT91_USART1	AT91SAM9263_BASE_US1
 #define AT91_USART2	AT91SAM9263_BASE_US2
diff --git a/arch/arm/mach-at91/include/mach/at91sam9g45.h b/arch/arm/mach-at91/include/mach/at91sam9g45.h
index 2c611b9..ec370cc 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9g45.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9g45.h
@@ -94,11 +94,6 @@
 #define AT91_DMA	(0xffffec00 - AT91_BASE_SYS)
 #define AT91_DBGU	(0xffffee00 - AT91_BASE_SYS)
 #define AT91_AIC	(0xfffff000 - AT91_BASE_SYS)
-#define AT91_PIOA	(0xfffff200 - AT91_BASE_SYS)
-#define AT91_PIOB	(0xfffff400 - AT91_BASE_SYS)
-#define AT91_PIOC	(0xfffff600 - AT91_BASE_SYS)
-#define AT91_PIOD	(0xfffff800 - AT91_BASE_SYS)
-#define AT91_PIOE	(0xfffffa00 - AT91_BASE_SYS)
 #define AT91_PMC	(0xfffffc00 - AT91_BASE_SYS)
 #define AT91_RSTC	(0xfffffd00 - AT91_BASE_SYS)
 #define AT91_SHDWC	(0xfffffd10 - AT91_BASE_SYS)
@@ -108,6 +103,12 @@
 #define AT91_GPBR	(0xfffffd60 - AT91_BASE_SYS)
 #define AT91_RTC	(0xfffffdb0 - AT91_BASE_SYS)
 
+#define AT91SAM9G45_BASE_PIOA	0xfffff200
+#define AT91SAM9G45_BASE_PIOB	0xfffff400
+#define AT91SAM9G45_BASE_PIOC	0xfffff600
+#define AT91SAM9G45_BASE_PIOD	0xfffff800
+#define AT91SAM9G45_BASE_PIOE	0xfffffa00
+
 #define AT91_USART0	AT91SAM9G45_BASE_US0
 #define AT91_USART1	AT91SAM9G45_BASE_US1
 #define AT91_USART2	AT91SAM9G45_BASE_US2
diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h
index 1aabacd..d3ef11a 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9rl.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h
@@ -77,10 +77,6 @@
 #define AT91_CCFG	(0xffffef10 - AT91_BASE_SYS)
 #define AT91_AIC	(0xfffff000 - AT91_BASE_SYS)
 #define AT91_DBGU	(0xfffff200 - AT91_BASE_SYS)
-#define AT91_PIOA	(0xfffff400 - AT91_BASE_SYS)
-#define AT91_PIOB	(0xfffff600 - AT91_BASE_SYS)
-#define AT91_PIOC	(0xfffff800 - AT91_BASE_SYS)
-#define AT91_PIOD	(0xfffffa00 - AT91_BASE_SYS)
 #define AT91_PMC	(0xfffffc00 - AT91_BASE_SYS)
 #define AT91_RSTC	(0xfffffd00 - AT91_BASE_SYS)
 #define AT91_SHDWC	(0xfffffd10 - AT91_BASE_SYS)
@@ -91,6 +87,11 @@
 #define AT91_GPBR	(0xfffffd60 - AT91_BASE_SYS)
 #define AT91_RTC	(0xfffffe00 - AT91_BASE_SYS)
 
+#define AT91SAM9RL_BASE_PIOA	0xfffff400
+#define AT91SAM9RL_BASE_PIOB	0xfffff600
+#define AT91SAM9RL_BASE_PIOC	0xfffff800
+#define AT91SAM9RL_BASE_PIOD	0xfffffa00
+
 #define AT91_USART0	AT91SAM9RL_BASE_US0
 #define AT91_USART1	AT91SAM9RL_BASE_US1
 #define AT91_USART2	AT91SAM9RL_BASE_US2
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH v2] pata-generic/of: Make probing via device tree non-powerpc-specific
From: Arnd Bergmann @ 2011-09-17 18:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110917153732.GR3523@ponder.secretlab.ca>

On Saturday 17 September 2011 09:37:32 Grant Likely wrote:
> What driver is normally used for versatile express pata?  This driver
> is kind of legacy in that it was created when there was a split
> between platform_device and of_platform_devices.  But that split was a
> bad idea and the same driver should be used regardless of whether or
> not DT is enabled.  pata_of_platform.c really should be removed.

It normally uses the plain pata_platform.c driver.

Note that the pata_of_platform driver is already just a shim on
top of the regular pata_platform driver. They could easily be combined,
but the current state is also ok, since there is very little code
duplication.

	Arnd

^ permalink raw reply

* [PATCH] pata-generic/of: Make probing via device tree non-powerpc-specific
From: Arnd Bergmann @ 2011-09-17 18:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110916214313.GB16381@n2100.arm.linux.org.uk>

On Friday 16 September 2011 22:43:13 Russell King - ARM Linux wrote:
> On Fri, Sep 16, 2011 at 03:38:10PM +0100, Dave Martin wrote:
> > This patch enables device-tree-based probing of the pata-generic
> > platform driver across all architectures:
> > 
> >   * make the pata_of_generic module depend on OF instead of PPC_OF;
> >   * supply some missing inclues;
> >   * replace endianness-sensitive raw access to device tree data
> >     with of_property_read_u32() calls.
> > 
> > Signed-off-by: Dave Martin <dave.martin@linaro.org>
> > ---
> > 
> > Tested on ARM Versatile Express, with my soon-to-be-posted device
> > tree support patches.
> 
> This may not be the correct way to support the CF slot on Versatile
> Express - it depends whether the CF slot on VE supports just CF
> memory cards or whether it can take any CF card.
> 
> If the latter, then what may be inserted could be a CF network card,
> and that means it's probably wrong to tell the kernel that what's
> there is a PATA interface.

The documentation at
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0447e/CACECHFJ.html
claims that the slot only supports TrueIDE and PIO/Taskfile mode, which
are the two modes for CF memory cards. Of course this is highly dependent
on what you load into the FPGA that implements the CF interface on
the versatile express, but at least for the currect Versatile Express
FPGA load it should be right.

Also, the patch makes sense regardless of versatile express, it's just
basic cleanup.

One extension we might want to add eventually is support for the UDMA
modes that are present on most of the current CF cards but not supported
by this driver (AFAICT).

	Arnd

^ permalink raw reply

* [PATCH] arm/dt: Add SoC detection macros
From: Jean-Christophe PLAGNIOL-VILLARD @ 2011-09-17 18:19 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110917112321.GE16381@n2100.arm.linux.org.uk>

On 12:23 Sat 17 Sep     , Russell King - ARM Linux wrote:
> On Sat, Sep 17, 2011 at 12:34:57PM +0200, Jean-Christophe PLAGNIOL-VILLARD wrote:
> > On 11:28 Sat 17 Sep     , Russell King - ARM Linux wrote:
> > > One last point to raise here is - and it's quite a fundamental one - do we
> > > really want this?  If we're making decisions based on the SoC type, that
> > > suggests to me that the hardware description in DT is incomplete, and
> > > we're hiding stuff in the kernel behind the SoC type.  That doesn't sound
> > > particularly appealing given the point of DT is to encode the hardware
> > > specific information outside the kernel code.
> >
> > except if a machine can run on 2 soc so detect it will avoid to have 2 Device
> > Tree
> 
> This code is structured to match the SoC based upon an entry in the DT,
> so for tegra2 vs tegra3 it's already having to have two different DTs
> to distinguish between them.
> 
> However, I still go back to my original point: the point of DT is to
> provide a description of the hardware which the kernel is running on -
> not only for current hardware but possibly future hardware as well.  Eg,
> if Tegra4 comes along with more peripherals than Tegra3 but has basic
> hardware which the kernel already supports, just wired up differently,
> then Tegra4 should just work with a new DT file and no code changes.
> 
> What I'm saying is that in that scenario it should not be necessary to
> edit the kernel to invent new SoC types, and then teach it that Tegra4
> is mostly the same as Tegra3.  That information should all be encoded
> into the DT rather than the C code in the kernel.
> 
> So, I think adding this SoC type stuff is the wrong approach to the
> problem.

I agree about it I just mean that if you have the same board with 2 SoC which
are pin to pin compatible detect the soc type will be usefull as the soc
resource may not be the same

Best Regards,
J.

^ permalink raw reply

* [PATCH v4] power: bq20z75: devicetree init support
From: Grant Likely @ 2011-09-17 17:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316023462-3287-1-git-send-email-rklein@nvidia.com>

On Wed, Sep 14, 2011 at 11:04:22AM -0700, Rhyland Klein wrote:
> Adding support to generate platform data when kernel is configured
> through device tree.
> 
> Also adding the binding for the TI bq20z75 fuel gadge and the
> bq20z75 driver.
> 
> Signed-off-by: Rhyland Klein <rklein@nvidia.com>

Acked-by: Grant Likely <grant.likely@secretlab.ca>

> ---
> 	v2: Fixed typo in binding description
> 	v3: Changed to use "ti," for properties
> 	    Changed to use single gpio entry for battery detect info.
> 	    Removed unnecessary call to of_match_device.
> 	v4: squashed bindings and drivers changes together.
> 	    fixed case where CONFIG_OF is not selected, to return existing
> 	    pdata pointer if it exists.
> 
>  .../bindings/power_supply/ti_bq20z75.txt           |   23 ++++++
>  drivers/power/bq20z75.c                            |   75 ++++++++++++++++++++
>  2 files changed, 98 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/power_supply/ti_bq20z75.txt
> 
> diff --git a/Documentation/devicetree/bindings/power_supply/ti_bq20z75.txt b/Documentation/devicetree/bindings/power_supply/ti_bq20z75.txt
> new file mode 100644
> index 0000000..7571294
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power_supply/ti_bq20z75.txt
> @@ -0,0 +1,23 @@
> +TI bq20z75
> +~~~~~~~~~~
> +
> +Required properties :
> + - compatible : "ti,bq20z75"
> +
> +Optional properties :
> + - ti,i2c-retry-count : The number of times to retry i2c transactions on i2c
> +   IO failure.
> + - ti,poll-retry-count : The number of times to try looking for new status
> +   after an external change notification.
> + - ti,battery-detect-gpios : The gpio which signals battery detection and
> +   a flag specifying its polarity.
> +
> +Example:
> +
> +	bq20z75 at b {
> +		compatible = "ti,bq20z75";
> +		reg = < 0xb >;
> +		ti,i2c-retry-count = <2>;
> +		ti,poll-retry-count = <10>;
> +		ti,battery-detect-gpios = <&gpio-controller 122 1>;
> +	}
> diff --git a/drivers/power/bq20z75.c b/drivers/power/bq20z75.c
> index 9c5e5be..4c4669e 100644
> --- a/drivers/power/bq20z75.c
> +++ b/drivers/power/bq20z75.c
> @@ -613,6 +613,78 @@ static void bq20z75_delayed_work(struct work_struct *work)
>  	}
>  }
>  
> +#if defined(CONFIG_OF)
> +#include <linux/of_device.h>
> +static const struct of_device_id bq20z75_dt_ids[] = {
> +	{ .compatible = "ti,bq20z75" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(platform, bq20z75_dt_ids);
> +
> +static struct bq20z75_platform_data *bq20z75_of_populate_pdata(
> +	struct i2c_client *client)
> +{
> +	const struct of_device_id *dtid;
> +	struct device_node *of_node = client->dev.of_node;
> +	struct bq20z75_platform_data *pdata = client->dev.platform_data;
> +	enum of_gpio_flags gpio_flags;
> +	int rc;
> +	u32 prop;
> +
> +	/* verify this driver matches this device */
> +	if (!of_node)
> +		return NULL;
> +
> +	/* if platform data is set, honor it */
> +	if (pdata)
> +		return pdata;
> +
> +	/* first make sure at least one property is set, otherwise
> +	 * it won't change behavior from running without pdata.
> +	 */
> +	if (!of_get_property(of_node, "ti,i2c-retry-count", NULL) &&
> +		!of_get_property(of_node, "ti,poll-retry-count", NULL) &&
> +		!of_get_property(of_node, "ti,battery-detect-gpios", NULL))
> +		goto of_out;
> +
> +	pdata = devm_kzalloc(&client->dev, sizeof(struct bq20z75_platform_data),
> +				GFP_KERNEL);
> +	if (!pdata)
> +		goto of_out;
> +
> +	rc = of_property_read_u32(of_node, "ti,i2c-retry-count", &prop);
> +	if (!rc)
> +		pdata->i2c_retry_count = prop;
> +
> +	rc = of_property_read_u32(of_node, "ti,poll-retry-count", &prop);
> +	if (!rc)
> +		pdata->poll_retry_count = prop;
> +
> +	if (!of_get_property(of_node, "ti,battery-detect-gpios", NULL)) {
> +		pdata->battery_detect = -1;
> +		goto of_out;
> +	}
> +
> +	pdata->battery_detect = of_get_named_gpio_flags(of_node,
> +			"ti,battery-detect-gpios", 0, &gpio_flags);
> +
> +	if (gpio_flags & OF_GPIO_ACTIVE_LOW)
> +		pdata->battery_detect_present = 0;
> +	else
> +		pdata->battery_detect_present = 1;
> +
> +of_out:
> +	return pdata;
> +}
> +#else
> +#define bq20z75_dt_ids NULL
> +static struct bq20z75_platform_data *bq20z75_of_populate_pdata(
> +	struct i2c_client *client)
> +{
> +	return client->dev.platform_data;
> +}
> +#endif
> +
>  static int __devinit bq20z75_probe(struct i2c_client *client,
>  	const struct i2c_device_id *id)
>  {
> @@ -642,6 +714,8 @@ static int __devinit bq20z75_probe(struct i2c_client *client,
>  	bq20z75_device->power_supply.external_power_changed =
>  		bq20z75_external_power_changed;
>  
> +	pdata = bq20z75_of_populate_pdata(client);
> +
>  	if (pdata) {
>  		bq20z75_device->gpio_detect =
>  			gpio_is_valid(pdata->battery_detect);
> @@ -775,6 +849,7 @@ static struct i2c_driver bq20z75_battery_driver = {
>  	.id_table	= bq20z75_id,
>  	.driver = {
>  		.name	= "bq20z75-battery",
> +		.of_match_table = bq20z75_dt_ids,
>  	},
>  };
>  
> -- 
> 1.7.6
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v2 1/2] OMAP: omap_device: Add omap_device_[alloc|delete] for DT integration
From: Grant Likely @ 2011-09-17 16:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110917162701.GB16591@n2100.arm.linux.org.uk>

On Sat, Sep 17, 2011 at 05:27:01PM +0100, Russell King - ARM Linux wrote:
> On Sat, Sep 17, 2011 at 10:05:14AM -0600, Grant Likely wrote:
> > > +static struct omap_device *omap_device_alloc(struct platform_device *pdev,
> > > +					struct omap_hwmod **ohs, int oh_cnt,
> > > +					struct omap_device_pm_latency *pm_lats,
> > > +					int pm_lats_cnt)
> > > +{
> > > +	int ret = -ENOMEM;
> > > +	struct omap_device *od;
> > > +	struct resource *res = NULL;
> > > +	int i, res_count;
> > > +	struct omap_hwmod **hwmods;
> > > +
> > > +	od = kzalloc(sizeof(struct omap_device), GFP_KERNEL);
> > 
> > possible enhancement:  devm_kzalloc() perhaps?  Would simplify the cleanup
> > paths.
> 
> Are you sure about that - have you thought about the lifetime issues?
> devm_*() lifetime is supposed to be from driver binding to driver
> unbinding.
> 
> The lifetime of 'omap_device' appears to be from device creation to
> device destruction, which is different from what devm_*() gives you.
> 
> So, using devm_*() will result in the 'omap_device' being destroyed
> when a driver is unbound - and presumably an oops if its attempted to
> be re-bound later (because the 'omap_device' structure will have been
> freed.)

Ugh, yes.  You're absolutely right.  devm_*() is doesn't at all work here.

g.

^ permalink raw reply

* [PATCH v2 1/2] OMAP: omap_device: Add omap_device_[alloc|delete] for DT integration
From: Russell King - ARM Linux @ 2011-09-17 16:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110917160514.GU3523@ponder.secretlab.ca>

On Sat, Sep 17, 2011 at 10:05:14AM -0600, Grant Likely wrote:
> > +static struct omap_device *omap_device_alloc(struct platform_device *pdev,
> > +					struct omap_hwmod **ohs, int oh_cnt,
> > +					struct omap_device_pm_latency *pm_lats,
> > +					int pm_lats_cnt)
> > +{
> > +	int ret = -ENOMEM;
> > +	struct omap_device *od;
> > +	struct resource *res = NULL;
> > +	int i, res_count;
> > +	struct omap_hwmod **hwmods;
> > +
> > +	od = kzalloc(sizeof(struct omap_device), GFP_KERNEL);
> 
> possible enhancement:  devm_kzalloc() perhaps?  Would simplify the cleanup
> paths.

Are you sure about that - have you thought about the lifetime issues?
devm_*() lifetime is supposed to be from driver binding to driver
unbinding.

The lifetime of 'omap_device' appears to be from device creation to
device destruction, which is different from what devm_*() gives you.

So, using devm_*() will result in the 'omap_device' being destroyed
when a driver is unbound - and presumably an oops if its attempted to
be re-bound later (because the 'omap_device' structure will have been
freed.)

^ permalink raw reply

* [PATCH 16/19] ARM: move iotable mappings within the vmalloc region
From: Russell King - ARM Linux @ 2011-09-17 16:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.00.1109171150320.20358@xanadu.home>

On Sat, Sep 17, 2011 at 12:05:02PM -0400, Nicolas Pitre wrote:
> On Sat, 17 Sep 2011, Russell King - ARM Linux wrote:
> 
> > On Fri, Sep 16, 2011 at 03:07:27AM -0400, Nicolas Pitre wrote:
> > >  void __init iotable_init(struct map_desc *io_desc, int nr)
> > >  {
> > > -	int i;
> > > +	struct map_desc *md;
> > > +	struct vm_struct *vm;
> > > +
> > > +	vm = __va(memblock_alloc(sizeof(*vm) * nr, __alignof__(*vm)));
> > > +	memset(vm, 0, sizeof(*vm) * nr);
> > 
> > Any reason not to adapt early_alloc() ?
> 
> It uses the size for the alignment argument.  This is way too large an 
> alignment in this case.  The size as alignment makes perfect sense in 
> the other cases, and providing it explicitly for those cases might look 
> strange.  But if you prefer that I'll just do it.

Just change early_alloc() to also take the alignment and then fix up the
existing callers.  It's silly to open-code the __va() + memset().

> > This is silly.  You're defining VMALLOC_END to be 0xff000000UL, and
> > then defining this to be 0xf0000000UL - 8MB.  Why hide the 240MB
> > inside these constants?  Why not set it to VMALLOC_END - 240MB -
> > VMALLOC_OFFSET - making the size in their _explicit_ instead of hidden?
> 
> Actually I care more about the absolute start address than the size this 
> ends up creating.  This is to accommodate some of the static mappings 
> that starts at 0xf0000000 on machines with a potential to have enough 
> RAM that could map higher than that.  It just happens that this 
> corresponds to 240MB.

We should stick to dealing with the size of vmalloc area rather than an
absolute address range as that's what we present to users via the
vmalloc= argument to the kernel.

> > >  /*
> > >   * vmalloc=size forces the vmalloc area to be exactly 'size'
> > >   * bytes. This can be used to increase (or decrease) the vmalloc
> > > - * area - the default is 128m.
> > > + * area - the default is 240m.
> > >   */
> > >  static int __init early_vmalloc(char *arg)
> > >  {
> > > @@ -853,6 +866,7 @@ void __init sanity_check_meminfo(void)
> > >  #endif
> > >  	meminfo.nr_banks = j;
> > >  	memblock_set_current_limit(lowmem_limit);
> > > +	high_memory = __va(lowmem_limit - 1) + 1;
> > 
> > NAK.  This ends up initializing this setting twice during the boot,
> > potentially leading to bugs because they're both done in different ways.
> 
> In that case I should remove the other one.

If you do that, don't forget to fix nommu as well.

> > > @@ -977,6 +991,12 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
> > >  	}
> > >  
> > >  	/*
> > > +	 * Clear the vmalloc area.
> > > +	 */
> > > +	for (addr = VMALLOC_START; addr < VMALLOC_END; addr += PGDIR_SIZE)
> > > +		pmd_clear(pmd_off_k(addr));
> > 
> > Why not combine this with the clearance above:
> > 
> >         for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
> >                 pmd_clear(pmd_off_k(addr));
> > 
> > ?
> 
> Because I wanted to keep the mapping for the DEBUG_LL code alive as long 
> as possible.

You can't put DEUBG_LL code into create_mapping() anyway because at some
point it will be called without the mapping in place, even with your
modified code.

It's not like we have a lot of code between those two points - we've
done most of the allocation (eg vectors page), so the only failure point
is if L2 page table allocation fails - but that's true of almost any
create_mapping() call.

So, I don't see the benefit of delaying the clearance.

^ permalink raw reply

* [PATCH v2 2/2] OMAP: omap_device: Add a method to build an omap_device from a DT node
From: Grant Likely @ 2011-09-17 16:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316184199-12599-3-git-send-email-b-cousson@ti.com>

On Fri, Sep 16, 2011 at 04:43:19PM +0200, Benoit Cousson wrote:
> Add a notifier called during device_add phase. If an of_node is present,
> retrieve the hwmod entry in order to populate properly the omap_device
> structure.
> For the moment the resource from the device-tree are overloaded.
> DT does not support named resource yet, and thus, most driver
> will not work without that information.
> 
> Add two helpers function to parse a property that contains multiple
> strings.
> 
> Signed-off-by: Benoit Cousson <b-cousson@ti.com>
> Cc: Kevin Hilman <khilman@ti.com>
> ---
>  arch/arm/plat-omap/omap_device.c |  144 ++++++++++++++++++++++++++++++++++++++
>  1 files changed, 144 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
> index cac7b9a..da13630 100644
> --- a/arch/arm/plat-omap/omap_device.c
> +++ b/arch/arm/plat-omap/omap_device.c
> @@ -85,6 +85,8 @@
>  #include <linux/clk.h>
>  #include <linux/clkdev.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/of.h>
> +#include <linux/notifier.h>
>  
>  #include <plat/omap_device.h>
>  #include <plat/omap_hwmod.h>
> @@ -94,12 +96,15 @@
>  #define USE_WAKEUP_LAT			0
>  #define IGNORE_WAKEUP_LAT		1
>  
> +#define MAX_HWMOD_NAME_SIZE		32
> +
>  static int omap_device_register(struct platform_device *pdev);
>  static int omap_early_device_register(struct platform_device *pdev);
>  static struct omap_device *omap_device_alloc(struct platform_device *pdev,
>  				      struct omap_hwmod **ohs, int oh_cnt,
>  				      struct omap_device_pm_latency *pm_lats,
>  				      int pm_lats_cnt);
> +static void omap_device_delete(struct omap_device *od);
>  
>  
>  static struct omap_device_pm_latency omap_default_latency[] = {
> @@ -315,6 +320,138 @@ static void _add_hwmod_clocks_clkdev(struct omap_device *od,
>  		_add_clkdev(od, oh->opt_clks[i].role, oh->opt_clks[i].clk);
>  }
>  
> +/*
> + * XXX: DT helper functions that should probably move elsewhere if
> + * they become usefull for other needs.
> + */

Lets just *assume* these are useful for other needs and start with
them in drivers/of so that other people know that they actually exist.
Otherwise they will never be made generic. :-)

> +static int _dt_count_property_string(const char *prop, int len)
> +{
> +	int i = 0;
> +	size_t l = 0, total = 0;
> +
> +	if (!prop || !len)
> +		return -EINVAL;
> +
> +	for (i = 0; len >= total; total += l, prop += l) {
> +		l = strlen(prop) + 1;
> +		if (*prop != 0)
> +			i++;
> +	}
> +	return i;
> +}
> +
> +static int _dt_get_property(const char *prop, int len, int index, char *output,
> +			    int size)
> +{
> +	int i = 0;
> +	size_t l = 0, total = 0;
> +
> +	if (!prop || !len)
> +		return -EINVAL;
> +
> +	for (i = 0; len >= total; total += l, prop += l) {
> +		l = strlcpy(output, prop, size) + 1;
> +		if (*prop != 0) {
> +			if (i++ == index)
> +				return 0;
> +		}
> +	}
> +	return -ENODEV;
> +}
> +
> +static struct dev_pm_domain omap_device_pm_domain;
> +
> +/**
> + * omap_device_build_from_dt - build an omap_device with multiple hwmods
> + * @pdev_name: name of the platform_device driver to use
> + * @pdev_id: this platform_device's connection ID
> + * @oh: ptr to the single omap_hwmod that backs this omap_device
> + * @pdata: platform_data ptr to associate with the platform_device
> + * @pdata_len: amount of memory pointed to by @pdata
> + * @pm_lats: pointer to a omap_device_pm_latency array for this device
> + * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
> + * @is_early_device: should the device be registered as an early device or not
> + *
> + * Function for building an omap_device already registered from device-tree
> + *
> + * Returns 0 or PTR_ERR() on error.
> + */
> +static int omap_device_build_from_dt(struct platform_device *pdev)
> +{
> +	struct omap_hwmod **hwmods;
> +	struct omap_device *od;
> +	struct omap_hwmod *oh;
> +	char oh_name[MAX_HWMOD_NAME_SIZE];
> +	const char *prop;
> +	int oh_cnt, i, prop_len;
> +	int ret = 0;
> +
> +	prop = of_get_property(pdev->dev.of_node, "hwmods", &prop_len);

I know you've posted it before, but what is the status of the "hwmods"
binding documentation.  I would expect it to be part of this patch.

> +	oh_cnt = _dt_count_property_string(prop, prop_len);
> +	if (!oh_cnt || IS_ERR_VALUE(oh_cnt)) {
> +		dev_warn(&pdev->dev, "No 'hwmods' to build omap_device\n");
> +		return -ENODEV;
> +	}
> +
> +	hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL);
> +	if (!hwmods) {
> +		ret = -ENOMEM;
> +		goto odbfd_exit;
> +	}
> +
> +	for (i = 0; i < oh_cnt; i++) {
> +		_dt_get_property(prop, prop_len, i, oh_name,
> +				 MAX_HWMOD_NAME_SIZE);
> +
> +		oh = omap_hwmod_lookup(oh_name);
> +		if (!oh) {
> +			dev_err(&pdev->dev, "Cannot lookup hwmod '%s'\n",
> +				oh_name);
> +			ret = -EINVAL;
> +			goto odbfd_exit1;
> +		}
> +		hwmods[i] = oh;
> +	}
> +
> +	od = omap_device_alloc(pdev, hwmods, oh_cnt, NULL, 0);
> +	if (!od) {
> +		dev_err(&pdev->dev, "Cannot allocate omap_device for :%s\n",
> +			oh_name);
> +		ret = PTR_ERR(od);
> +		goto odbfd_exit1;
> +	}
> +
> +	if (of_get_property(pdev->dev.of_node, "no_idle_on_suspend", NULL))
> +		omap_device_disable_idle_on_suspend(pdev);
> +
> +	pdev->dev.pm_domain = &omap_device_pm_domain;
> +
> +odbfd_exit1:
> +	kfree(hwmods);
> +odbfd_exit:
> +	return ret;
> +}
> +
> +static int _omap_device_notifier_call(struct notifier_block *nb,
> +				      unsigned long event, void *dev)

Nit: Why the preceding underscore?  Generally that is only done for
'special' variants of public functions.  ie. for a variant that
expects a lock to already be held.

> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +
> +	switch (event) {
> +	case BUS_NOTIFY_ADD_DEVICE:
> +		if (pdev->dev.of_node)
> +			omap_device_build_from_dt(pdev);
> +		break;
> +
> +	case BUS_NOTIFY_DEL_DEVICE:
> +		if (pdev->archdata.od)
> +			omap_device_delete(pdev->archdata.od);
> +		break;
> +	}
> +
> +	return NOTIFY_DONE;
> +}
> +
>  
>  /* Public functions for use by core code */
>  
> @@ -499,6 +636,9 @@ oda_exit1:
>  
>  static void omap_device_delete(struct omap_device *od)
>  {
> +	if (!od)
> +		return;
> +
>  	od->pdev->archdata.od = NULL;
>  	kfree(od->pm_lats);
>  	kfree(od->hwmods);
> @@ -1034,8 +1174,12 @@ struct device omap_device_parent = {
>  	.parent         = &platform_bus,
>  };
>  
> +static struct notifier_block platform_nb;

Nit: Since it is static initialization, you can do the following
instead of setting it up in the init function.

static struct notifier_block platform_nb = {
	.notifier_call = _omap_device_notifier_call;
};

> +
>  static int __init omap_device_init(void)
>  {
> +	platform_nb.notifier_call = _omap_device_notifier_call;
> +	bus_register_notifier(&platform_bus_type, &platform_nb);
>  	return device_register(&omap_device_parent);
>  }
>  core_initcall(omap_device_init);
> -- 
> 1.7.0.4
> 

^ permalink raw reply

* [PATCH v2 1/2] OMAP: omap_device: Add omap_device_[alloc|delete] for DT integration
From: Grant Likely @ 2011-09-17 16:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316184199-12599-2-git-send-email-b-cousson@ti.com>

On Fri, Sep 16, 2011 at 04:43:18PM +0200, Benoit Cousson wrote:
> Split the omap_device_build_ss into two smaller functions
> that will allow to populate a platform_device already allocated by
> device-tree.
> The functionality of the omap_device_build_ss is still the same, but
> the omap_device_alloc will be usable with devices already built by
> device-tree.
> 
> Signed-off-by: Benoit Cousson <b-cousson@ti.com>
> Cc: Kevin Hilman <khilman@ti.com>

Looks pretty good.  Comments below.

g.

> ---
>  arch/arm/plat-omap/omap_device.c |  177 +++++++++++++++++++++++++------------
>  1 files changed, 119 insertions(+), 58 deletions(-)
> 
> diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
> index 54bbe7b..cac7b9a 100644
> --- a/arch/arm/plat-omap/omap_device.c
> +++ b/arch/arm/plat-omap/omap_device.c
> @@ -96,6 +96,11 @@
>  
>  static int omap_device_register(struct platform_device *pdev);
>  static int omap_early_device_register(struct platform_device *pdev);
> +static struct omap_device *omap_device_alloc(struct platform_device *pdev,
> +				      struct omap_hwmod **ohs, int oh_cnt,
> +				      struct omap_device_pm_latency *pm_lats,
> +				      int pm_lats_cnt);
> +
>  
>  static struct omap_device_pm_latency omap_default_latency[] = {
>  	{
> @@ -397,6 +402,110 @@ static int omap_device_fill_resources(struct omap_device *od,
>  }
>  
>  /**
> + * omap_device_alloc - allocate an omap_device
> + * @pdev: platform_device that will be included in this omap_device
> + * @oh: ptr to the single omap_hwmod that backs this omap_device
> + * @pdata: platform_data ptr to associate with the platform_device
> + * @pdata_len: amount of memory pointed to by @pdata
> + * @pm_lats: pointer to a omap_device_pm_latency array for this device
> + * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
> + *
> + * Convenience function for allocating an omap_device structure and filling
> + * hwmods, resources and pm_latency attributes.
> + *
> + * Returns an struct omap_device pointer or ERR_PTR() on error;
> + */
> +static struct omap_device *omap_device_alloc(struct platform_device *pdev,
> +					struct omap_hwmod **ohs, int oh_cnt,
> +					struct omap_device_pm_latency *pm_lats,
> +					int pm_lats_cnt)
> +{
> +	int ret = -ENOMEM;
> +	struct omap_device *od;
> +	struct resource *res = NULL;
> +	int i, res_count;
> +	struct omap_hwmod **hwmods;
> +
> +	od = kzalloc(sizeof(struct omap_device), GFP_KERNEL);

possible enhancement:  devm_kzalloc() perhaps?  Would simplify the cleanup paths.

> +	if (!od) {
> +		ret = -ENOMEM;
> +		goto oda_exit1;
> +	}
> +	od->hwmods_cnt = oh_cnt;
> +
> +	hwmods = kmemdup(ohs, sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL);

Ditto here.  would require creation of devm_kmemdup()

> +	if (!hwmods)
> +		goto oda_exit2;
> +
> +	od->hwmods = hwmods;
> +	od->pdev = pdev;
> +
> +	/*
> +	 * HACK: Ideally the resources from DT should match, and hwmod
> +	 * should just add the missing ones. Since the name is not
> +	 * properly populated by DT, stick to hwmod resources only.
> +	 */
> +	if (pdev->num_resources && pdev->resource)
> +		dev_warn(&pdev->dev, "%s(): resources already allocated %d\n",
> +			__func__, pdev->num_resources);
> +
> +	res_count = omap_device_count_resources(od);
> +	if (res_count > 0) {
> +		dev_dbg(&pdev->dev, "%s(): resources allocated from hwmod %d\n",
> +			__func__, res_count);
> +		res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
> +		if (!res)
> +			goto oda_exit3;
> +
> +		omap_device_fill_resources(od, res);
> +
> +		ret = platform_device_add_resources(pdev, res, res_count);
> +		kfree(res);

How big is res_count?  Struct resource isn't very big.  It can
probably be on the stack.

> +
> +		if (ret)
> +			goto oda_exit3;
> +	}
> +
> +	if (!pm_lats) {
> +		pm_lats = omap_default_latency;
> +		pm_lats_cnt = ARRAY_SIZE(omap_default_latency);
> +	}
> +
> +	od->pm_lats_cnt = pm_lats_cnt;
> +	od->pm_lats = kmemdup(pm_lats,
> +			sizeof(struct omap_device_pm_latency) * pm_lats_cnt,
> +			GFP_KERNEL);
> +	if (!od->pm_lats)
> +		goto oda_exit3;
> +
> +	pdev->archdata.od = od;
> +
> +	for (i = 0; i < oh_cnt; i++) {
> +		hwmods[i]->od = od;
> +		_add_hwmod_clocks_clkdev(od, hwmods[i]);
> +	}
> +
> +	return od;
> +
> +oda_exit3:
> +	kfree(hwmods);
> +oda_exit2:
> +	kfree(od);
> +oda_exit1:
> +	dev_err(&pdev->dev, "omap_device: build failed (%d)\n", ret);
> +
> +	return ERR_PTR(ret);
> +}
> +
> +static void omap_device_delete(struct omap_device *od)
> +{
> +	od->pdev->archdata.od = NULL;
> +	kfree(od->pm_lats);
> +	kfree(od->hwmods);
> +	kfree(od);
> +}
> +
> +/**
>   * omap_device_build - build and register an omap_device with one omap_hwmod
>   * @pdev_name: name of the platform_device driver to use
>   * @pdev_id: this platform_device's connection ID
> @@ -455,9 +564,6 @@ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
>  	int ret = -ENOMEM;
>  	struct platform_device *pdev;
>  	struct omap_device *od;
> -	struct resource *res = NULL;
> -	int i, res_count;
> -	struct omap_hwmod **hwmods;
>  
>  	if (!ohs || oh_cnt == 0 || !pdev_name)
>  		return ERR_PTR(-EINVAL);
> @@ -471,76 +577,31 @@ struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
>  		goto odbs_exit;
>  	}
>  
> -	pr_debug("omap_device: %s: building with %d hwmods\n", pdev_name,
> -		 oh_cnt);
> +	/* Set the dev_name early to allow dev_xxx in omap_device_alloc */
> +	if (pdev->id != -1)
> +		dev_set_name(&pdev->dev, "%s.%d", pdev->name,  pdev->id);
> +	else
> +		dev_set_name(&pdev->dev, "%s", pdev->name);

This is duplicated from the core platform_device code.  What is the
reasoning for doing it again here?

>  
> -	od = kzalloc(sizeof(struct omap_device), GFP_KERNEL);
> -	if (!od) {
> -		ret = -ENOMEM;
> +	od = omap_device_alloc(pdev, ohs, oh_cnt, pm_lats, pm_lats_cnt);
> +	if (!od)
>  		goto odbs_exit1;
> -	}
> -	od->hwmods_cnt = oh_cnt;
> -
> -	hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt,
> -			 GFP_KERNEL);
> -	if (!hwmods)
> -		goto odbs_exit2;
> -
> -	memcpy(hwmods, ohs, sizeof(struct omap_hwmod *) * oh_cnt);
> -	od->hwmods = hwmods;
> -	od->pdev = pdev;
> -
> -	res_count = omap_device_count_resources(od);
> -	if (res_count > 0) {
> -		res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
> -		if (!res)
> -			goto odbs_exit3;
> -
> -		omap_device_fill_resources(od, res);
> -
> -		ret = platform_device_add_resources(pdev, res, res_count);
> -		kfree(res);
> -
> -		if (ret)
> -			goto odbs_exit3;
> -	}
>  
>  	ret = platform_device_add_data(pdev, pdata, pdata_len);
>  	if (ret)
> -		goto odbs_exit3;
> -
> -	pdev->archdata.od = od;
> +		goto odbs_exit2;
>  
>  	if (is_early_device)
>  		ret = omap_early_device_register(pdev);
>  	else
>  		ret = omap_device_register(pdev);
>  	if (ret)
> -		goto odbs_exit3;
> -
> -	if (!pm_lats) {
> -		pm_lats = omap_default_latency;
> -		pm_lats_cnt = ARRAY_SIZE(omap_default_latency);
> -	}
> -
> -	od->pm_lats_cnt = pm_lats_cnt;
> -	od->pm_lats = kmemdup(pm_lats,
> -			sizeof(struct omap_device_pm_latency) * pm_lats_cnt,
> -			GFP_KERNEL);
> -	if (!od->pm_lats)
> -		goto odbs_exit3;
> -
> -	for (i = 0; i < oh_cnt; i++) {
> -		hwmods[i]->od = od;
> -		_add_hwmod_clocks_clkdev(od, hwmods[i]);
> -	}
> +		goto odbs_exit2;
>  
>  	return pdev;
>  
> -odbs_exit3:
> -	kfree(hwmods);
>  odbs_exit2:
> -	kfree(od);
> +	omap_device_delete(od);
>  odbs_exit1:
>  	platform_device_put(pdev);
>  odbs_exit:
> -- 
> 1.7.0.4
> 

^ permalink raw reply

* [PATCH 16/19] ARM: move iotable mappings within the vmalloc region
From: Nicolas Pitre @ 2011-09-17 16:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110917151953.GJ16381@n2100.arm.linux.org.uk>

On Sat, 17 Sep 2011, Russell King - ARM Linux wrote:

> On Fri, Sep 16, 2011 at 03:07:27AM -0400, Nicolas Pitre wrote:
> >  void __init iotable_init(struct map_desc *io_desc, int nr)
> >  {
> > -	int i;
> > +	struct map_desc *md;
> > +	struct vm_struct *vm;
> > +
> > +	vm = __va(memblock_alloc(sizeof(*vm) * nr, __alignof__(*vm)));
> > +	memset(vm, 0, sizeof(*vm) * nr);
> 
> Any reason not to adapt early_alloc() ?

It uses the size for the alignment argument.  This is way too large an 
alignment in this case.  The size as alignment makes perfect sense in 
the other cases, and providing it explicitly for those cases might look 
strange.  But if you prefer that I'll just do it.

> >  
> > -	for (i = 0; i < nr; i++)
> > -		create_mapping(io_desc + i);
> > +	for (md = io_desc; nr; md++, nr--) {
> > +		create_mapping(md);
> > +		vm->addr = (void *)(md->virtual & PAGE_MASK);
> > +		vm->size = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK));
> > +		vm->phys_addr = __pfn_to_phys(md->pfn); 
> > +		vm->flags = VM_IOREMAP;
> > +		vm->caller = iotable_init;
> > +		vm_area_add_early(vm++);
> > +	}
> >  }
> >  
> > -static void * __initdata vmalloc_min = (void *)(VMALLOC_END - SZ_128M);
> > +static void * __initdata vmalloc_min = (void *)(0xf0000000UL - VMALLOC_OFFSET);
> 
> This is silly.  You're defining VMALLOC_END to be 0xff000000UL, and
> then defining this to be 0xf0000000UL - 8MB.  Why hide the 240MB
> inside these constants?  Why not set it to VMALLOC_END - 240MB -
> VMALLOC_OFFSET - making the size in their _explicit_ instead of hidden?

Actually I care more about the absolute start address than the size this 
ends up creating.  This is to accommodate some of the static mappings 
that starts at 0xf0000000 on machines with a potential to have enough 
RAM that could map higher than that.  It just happens that this 
corresponds to 240MB.

> >  /*
> >   * vmalloc=size forces the vmalloc area to be exactly 'size'
> >   * bytes. This can be used to increase (or decrease) the vmalloc
> > - * area - the default is 128m.
> > + * area - the default is 240m.
> >   */
> >  static int __init early_vmalloc(char *arg)
> >  {
> > @@ -853,6 +866,7 @@ void __init sanity_check_meminfo(void)
> >  #endif
> >  	meminfo.nr_banks = j;
> >  	memblock_set_current_limit(lowmem_limit);
> > +	high_memory = __va(lowmem_limit - 1) + 1;
> 
> NAK.  This ends up initializing this setting twice during the boot,
> potentially leading to bugs because they're both done in different ways.

In that case I should remove the other one.

> You don't describe why this change is necessary so I assume that it's
> part of some debugging you were trying and shouldn't be in this patch.

No, it noe has to be set before create_mapping() is called so the final 
VMALLOC_START address is known.

> > @@ -977,6 +991,12 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
> >  	}
> >  
> >  	/*
> > +	 * Clear the vmalloc area.
> > +	 */
> > +	for (addr = VMALLOC_START; addr < VMALLOC_END; addr += PGDIR_SIZE)
> > +		pmd_clear(pmd_off_k(addr));
> 
> Why not combine this with the clearance above:
> 
>         for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
>                 pmd_clear(pmd_off_k(addr));
> 
> ?

Because I wanted to keep the mapping for the DEBUG_LL code alive as long 
as possible.


Nicolas

^ permalink raw reply

* [PATCH v2] dmaengine: add CSR SiRFprimaII DMAC driver
From: Jassi Brar @ 2011-09-17 15:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAGsJ_4za8HZ6hoyRyU=NR8TXhN+iFOQvfOeA1F_GTH6h6Zs+=A@mail.gmail.com>

On 17 September 2011 20:27, Barry Song <21cnbao@gmail.com> wrote:
>>> +static int sirfsoc_dma_slave_config(struct sirfsoc_dma_chan *schan,
>>> + ? ? ? struct dma_slave_config *config)
>>> +{
>>> + ? ? ? u32 addr, direction;
>>> + ? ? ? unsigned long flags;
>>> +
>>> + ? ? ? switch (config->direction) {
>>> + ? ? ? case DMA_FROM_DEVICE:
>>> + ? ? ? ? ? ? ? direction = 0;
>>> + ? ? ? ? ? ? ? addr = config->dst_addr;
>>> + ? ? ? ? ? ? ? break;
>>> +
>>> + ? ? ? case DMA_TO_DEVICE:
>>> + ? ? ? ? ? ? ? direction = 1;
>>> + ? ? ? ? ? ? ? addr = config->src_addr;
>>> + ? ? ? ? ? ? ? break;
>>> +
>>> + ? ? ? default:
>>> + ? ? ? ? ? ? ? return -EINVAL;
>>> + ? ? ? }
>>> +
>>> + ? ? ? if ((config->src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES) ||
>>> + ? ? ? ? ? ? ? (config->dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES))
>>> + ? ? ? ? ? ? ? return -EINVAL;
>>> +
>>> + ? ? ? spin_lock_irqsave(&schan->lock, flags);
>>> + ? ? ? schan->addr = addr;
>>> + ? ? ? schan->direction = direction;
>>> + ? ? ? schan->mode = (config->src_maxburst == 4 ? 1 : 0);
>>> + ? ? ? spin_unlock_irqrestore(&schan->lock, flags);
>>> +
>>> + ? ? ? return 0;
>>> +}
>> You don't need to pass as much info via dma_slave_config as you do here.
>>
>> dmaxfer_template.src_inc ?&& !dmaxfer_template.dst_inc ?=> DMA_TO_DEVICE
>> !dmaxfer_template.src_inc ?&& dmaxfer_template.dst_inc ?=> DMA_FROM_DEVICE
>
> it seems direct DMA_TO_DEVICE/DMA_FROM_DEVICE is more feasible and
> explict to me.

> "dmaxfer_template.src_inc ?&& !dmaxfer_template.dst_inc" is probably
> DMA_TO_DEVICE, but it is not always true for all scenerios to all kinds of devices.
For which scenarios do you think it won't hold (remember that dmac already
knows if the channel is SLAVE or not) ?

^ permalink raw reply

* [PATCH 01/19] ARM: sort the meminfo array earlier
From: Nicolas Pitre @ 2011-09-17 15:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110917150522.GI16381@n2100.arm.linux.org.uk>

On Sat, 17 Sep 2011, Russell King - ARM Linux wrote:

> On Fri, Sep 16, 2011 at 03:07:12AM -0400, Nicolas Pitre wrote:
> > From: Nicolas Pitre <nicolas.pitre@linaro.org>
> > 
> > The meminfo array has to be sorted before sanity_check_meminfo() can work
> > properly.
> 
> This is unrelated to the patch series, so it should be separate from the
> series.  I don't see anything in the series depending on it.

True.  I just stumbled across this issue while working on the rest.


Nicolas

^ permalink raw reply

* [PATCH v2] pata-generic/of: Make probing via device tree non-powerpc-specific
From: Grant Likely @ 2011-09-17 15:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1316190120-17010-1-git-send-email-dave.martin@linaro.org>

On Fri, Sep 16, 2011 at 05:22:00PM +0100, Dave Martin wrote:
> This patch enables device-tree-based probing of the pata-generic
> platform driver across all architectures:
> 
>   * make the pata_of_generic module depend on OF instead of PPC_OF;
>   * supply some missing inclues;
>   * replace endianness-sensitive raw access to device tree data
>     with of_property_read_u32() calls.
> 
> Signed-off-by: Dave Martin <dave.martin@linaro.org>
> ---
> v2: correct sense of the check of_property_read_u32(dn, "pio-mode",
> &pio_mode).  Somehow I posted an old version of this patch, depite
> having already fixed this...
> 
> Tested on ARM Versatile Express, with my soon-to-be-posted device
> tree support patches.
> 
> I'm not in a position to build/test this for powerpc easily --
> if anyone is able to do that, it would be appreciated.

What driver is normally used for versatile express pata?  This driver
is kind of legacy in that it was created when there was a split
between platform_device and of_platform_devices.  But that split was a
bad idea and the same driver should be used regardless of whether or
not DT is enabled.  pata_of_platform.c really should be removed.

So, instead of removing the PPC_OF restriction from
pata_of_platform.c, you should look at adding DT support to the
existing binding.  Bonus points if you can roll pata_of_platform.c
support into pata_platform.c (assuming that is the correct driver).

g.

^ permalink raw reply

* [PATCH v2] dmaengine: add CSR SiRFprimaII DMAC driver
From: Barry Song @ 2011-09-17 15:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110917150246.GH16381@n2100.arm.linux.org.uk>

2011/9/17 Russell King - ARM Linux <linux@arm.linux.org.uk>:
> On Fri, Sep 16, 2011 at 02:56:00AM -0700, Barry Song wrote:
>> +static int sirfsoc_dma_slave_config(struct sirfsoc_dma_chan *schan,
>> + ? ? struct dma_slave_config *config)
>> +{
>> + ? ? u32 addr, direction;
>> + ? ? unsigned long flags;
>> +
>> + ? ? switch (config->direction) {
>
> config->direction is deprecated, please don't use it.

ok.

>
>> + ? ? case DMA_FROM_DEVICE:
>> + ? ? ? ? ? ? direction = 0;
>> + ? ? ? ? ? ? addr = config->dst_addr;
>> + ? ? ? ? ? ? break;
>> +
>> + ? ? case DMA_TO_DEVICE:
>> + ? ? ? ? ? ? direction = 1;
>> + ? ? ? ? ? ? addr = config->src_addr;
>> + ? ? ? ? ? ? break;
>> +
>> + ? ? default:
>> + ? ? ? ? ? ? return -EINVAL;
>> + ? ? }
>> +
>> + ? ? if ((config->src_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES) ||
>> + ? ? ? ? ? ? (config->dst_addr_width != DMA_SLAVE_BUSWIDTH_4_BYTES))
>> + ? ? ? ? ? ? return -EINVAL;
>> +
>> + ? ? spin_lock_irqsave(&schan->lock, flags);
>> + ? ? schan->addr = addr;
>> + ? ? schan->direction = direction;
>> + ? ? schan->mode = (config->src_maxburst == 4 ? 1 : 0);
>
> Please store the source address, destination address, and mode separately
> for each direction. ?You should then select from that at prepare time.

the dmac has fixed route. every channel has fixed function. one
channel is for one device and one direction. for example, spi0 can
have two fixed channel: spi0-tx, spi0-rx.
then for every schan, device address is always fixed and we don't care
it at all. we only need to write the memory address to dmac address
register.

>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>

-barry

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox