LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 3/4] PowerPC: Add PCI entry to 440EPx Sequoia DTS.
From: Benjamin Herrenschmidt @ 2007-12-21 21:21 UTC (permalink / raw)
  To: Valentine Barshak; +Cc: linuxppc-dev
In-Reply-To: <20071221162601.GA1700@ru.mvista.com>


On Fri, 2007-12-21 at 19:26 +0300, Valentine Barshak wrote:
> +
> +                       /* All PCI interrupts are routed to IRQ 67 */
> +                       interrupt-map-mask = <0000 0 0 0>;
> +                       interrupt-map = < 0000 0 0 0 &UIC2 3 8 >;
> +               };
>         };

Wow, all 4 lines of all slots ?

Ben.

^ permalink raw reply

* Re: [PATCH 1/3] [POWERPC] FSL UPM: routines to manage FSL UPMs
From: Olof Johansson @ 2007-12-21 21:28 UTC (permalink / raw)
  To: Anton Vorontsov; +Cc: linuxppc-dev
In-Reply-To: <20071221203925.GA4829@localhost.localdomain>

On Fri, Dec 21, 2007 at 11:39:25PM +0300, Anton Vorontsov wrote:
> Here are few routines needed to manage FSL UPMs. It doesn't include
> UPM programming, yet. So far u-boot manages to program everything.
> 
> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
> ---
>  arch/powerpc/Kconfig          |    3 +
>  arch/powerpc/sysdev/Makefile  |    1 +
>  arch/powerpc/sysdev/fsl_upm.c |   65 +++++++++++++++++++++++++++++
>  include/asm-powerpc/fsl_upm.h |   90 +++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 159 insertions(+), 0 deletions(-)
>  create mode 100644 arch/powerpc/sysdev/fsl_upm.c
>  create mode 100644 include/asm-powerpc/fsl_upm.h
> 
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index a4fa173..aab8106 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -463,6 +463,9 @@ config FSL_PCI
>   	bool
>  	select PPC_INDIRECT_PCI
>  
> +config FSL_UPM
> +	bool

Please describe new config options, even if they're silent ones.


-Olof

^ permalink raw reply

* Re: [PATCH 1/4] [POWERPC] qe_lib and users: get rid of device_type and model
From: Olof Johansson @ 2007-12-21 21:25 UTC (permalink / raw)
  To: Anton Vorontsov; +Cc: linuxppc-dev
In-Reply-To: <20071221202054.GA4502@localhost.localdomain>

Hi,

On Fri, Dec 21, 2007 at 11:20:54PM +0300, Anton Vorontsov wrote:
> diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
> index e6c63a5..a152bf8 100644
> --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
> +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
> @@ -94,7 +94,8 @@ static void __init mpc85xx_mds_setup_arch(void)
>  #endif
>  
>  #ifdef CONFIG_QUICC_ENGINE
> -	if ((np = of_find_node_by_name(NULL, "qe")) != NULL) {
> +	np = of_find_node_by_name(NULL, "fsl,qe");
> +	if (np) {

That won't work. Did you mean of_find_compatible_node()? If so, you
still need to fall back to looking up by name for older device trees
that don't have the compatible field.


-Olof

^ permalink raw reply

* Re: [PATCH 0/4] PowerPC: implement GPIO API
From: Grant Likely @ 2007-12-21 21:17 UTC (permalink / raw)
  To: avorontsov; +Cc: linuxppc-dev
In-Reply-To: <20071221210445.GA5190@localhost.localdomain>

On 12/21/07, Anton Vorontsov <avorontsov@ru.mvista.com> wrote:
> As I've probably said once already: if there are plans to build single
> kernel with QE+CPM1+CPM2 inside tomorrow -- then of course, I'd better
> wait.
>
> But if these plans are distant enough, I see no reason why we can't
> enjoy of current API.

Oh, I'm not saying don't enjoy it.  :-)  I'm just saying keep it out
of mainline.  I've got a bunch of Virtex stuff that falls into that
category.  Those who are interested can pick the non mainlined patches
out of my git tree.

I suggest doing the same with the GPIO support.  Either that or do our
own simple ppc specific GPIO multiplexer until the common stuff has
its act together.  :-)  We can always migrate over later.

I don't want to see more barriers added to prevent all of 8xxx going
multiplatform.

Cheers,
g.


-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195

^ permalink raw reply

* Re: [PATCH 18/21] [POWERPC] bamboo: remove bogus "ranges" property in EBC node
From: Benjamin Herrenschmidt @ 2007-12-21 21:16 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <20071221060921.4ae5bc20@zod.rchland.ibm.com>


On Fri, 2007-12-21 at 06:09 -0600, Josh Boyer wrote:
> On Fri, 21 Dec 2007 15:39:35 +1100
> Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> 
> > This removes a bogus empty "ranges" property in the EBC device node
> > of the Bamboo board device-tree.
> > 
> > The "ranges" property will be created by the boot wrapper, there is
> > no need to have an empty property there, and that causes recent
> > dtc to complain.
> 
> The wrapper doesn't do anything with EBC for bamboo because the EBC
> stuff is a nightmare on this board.  The patch can stand, but I'll
> fixup the comments in the changelog.

The wrapper could still create ranges for the chip select settings no ?

In any case, empty "ranges" is bogus.

Ben.

^ permalink raw reply

* Re: [PATCH 3/4] [POWERPC] CPM2: implement GPIO API
From: Arnd Bergmann @ 2007-12-21 21:16 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <20071221203123.GC4633@localhost.localdomain>

On Friday 21 December 2007, Anton Vorontsov wrote:
>  
> +static spinlock_t cpm2_port_lock = __SPIN_LOCK_UNLOCKED(cpm2_port_lock);

This needs to be

static DEFINE_SPINLOCK(cpm2_port_lock);

I think at least lockdep doesn't work the way you do it here.

> +int cpm2_init_par_io(void)
> +{
> +	struct device_node *np;
> +	const u32 *num_ports;
> +
> +	np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pario");
> +	if (!np)
> +		return -ENOENT;
> +
> +	num_ports = of_get_property(np, "num-ports", NULL);
> +	if (!num_ports) {
> +		of_node_put(np);
> +		return -ENOENT;
> +	}
> +	cpm2_num_ports = *num_ports;
> +
> +	np->data = &of_gpio_chip;
> +
> +	return 0;
> +}

This function should also do the call to of_iomap, so you don't
need to pull the address out of the cpm2_immr, which I believe
we're trying to get rid of.

	Arnd <><

^ permalink raw reply

* Re: [PATCH 1/21] [POWERPC] Reworking machine check handling and Fix 440/440A
From: Benjamin Herrenschmidt @ 2007-12-21 21:16 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <20071221060136.611eb899@zod.rchland.ibm.com>


On Fri, 2007-12-21 at 06:01 -0600, Josh Boyer wrote:
> On Fri, 21 Dec 2007 15:39:21 +1100
> Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> 
> 
> > Index: linux-merge/include/asm-ppc/reg_booke.h
> > ===================================================================
> > --- linux-merge.orig/include/asm-ppc/reg_booke.h	2007-09-28 11:42:10.000000000 +1000
> > +++ linux-merge/include/asm-ppc/reg_booke.h	2007-12-20 11:35:40.000000000 +1100
> > @@ -207,7 +207,7 @@
> >  #define	CCR1_TCS	0x00000080 /* Timer Clock Select */
> > 
> >  /* Bit definitions for the MCSR. */
> > -#ifdef CONFIG_440A
> > +#ifdef CONFIG_44x
> 
> Should be #ifdef CONFIG_4xx as I pointed out last time.  I'll fix it
> when I commit.

Ah weird, I though I fixed it... I must have fixed powerpc and not ppc.

Ben.

^ permalink raw reply

* Re: [PATCH POWERPC] i2c: adds support for i2c bus on Frescale CPM1/CPM2 controllers
From: Vitaly Bordug @ 2007-12-21 21:11 UTC (permalink / raw)
  To: Jochen Friedrich; +Cc: Scott Wood, linuxppc-dev, khali, linux-kernel, i2c
In-Reply-To: <476C15BC.3090807@scram.de>

On Fri, 21 Dec 2007 20:36:28 +0100
Jochen Friedrich wrote:

> Using the port of 2.4 code from Vitaly Bordug
> <vitb@kernel.crashing.org> and the actual algorithm used by the i2c
> driver of the DBox code on cvs.tuxboc.org from Tmbinc, Gillem
> (htoa@gmx.net). Renamed i2c-rpx.c and i2c-algo-8xx.c to i2c-cpm.c and
> converted the driver to an of_platform_driver.
> 

I had an attempt a while ago to do this but haven't had enough time to get it completed, so
I am glad to see it finally picked up. There was some sort of discussion that time, you seem to have some of those points
addressed but  something not, please
check: http://lkml.org/lkml/2007/5/8/45

(for instance, cpm_i2c_shutdown() and i2c_cpm_del_bus() are void because they cant' fail) 

Also, why this was directed to Scott? This is lm-sensors stuff and is
Jean Delvare <khali@linux-fr.org> material...

-- 
Sincerely, Vitaly

^ permalink raw reply

* Re: [PATCH 0/4] PowerPC: implement GPIO API
From: Anton Vorontsov @ 2007-12-21 21:04 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <fa686aa40712211250l2645d34dr45c5be2bf1c9006d@mail.gmail.com>

On Fri, Dec 21, 2007 at 01:50:10PM -0700, Grant Likely wrote:
> On 12/21/07, Anton Vorontsov <avorontsov@ru.mvista.com> wrote:
> > Also, in the upcoming kernels, there will be GPIOLIB[1] addition to
> > the generic GPIO API, to support off-chip GPIO expanders (like MFDs
> > on I2C/LBC). But so far we support on-chip GPIOs only, with single
> > controller built-in.
> >
> > Changes since RFC:
> > - Implemented #gpio-cells handling;
> > - Per-bank spinlocks removed;
> > - Added a patch which implements GPIO API for CPM1;
> > - Few minor fixes.
> 
> Also need to add documentation to booting-without-of.txt.
> 
> In general this looks like a good direction, but I do not like the
> hard linking for QE and CPM gpios to the 'top level' gpio API.  I
> think I'd prefer this stuff to stay out of mainline until the gpiolib

Well, generally I'm okay to wait for gpiolib. Though...

> stuff gets merged (which should be soon IIRC).
                                     ^^^^ I doubt about that. :-)

I'm looking after gpiolib development (and, well, I also partipiated
in the discussion of earlier versions with former name "gpiodev") for
almost a _year_.

And they're still arguing about fluffy details of implementation.. :-/

As I've probably said once already: if there are plans to build single
kernel with QE+CPM1+CPM2 inside tomorrow -- then of course, I'd better
wait.

But if these plans are distant enough, I see no reason why we can't
enjoy of current API.

Thanks!

-- 
Anton Vorontsov
email: cbou@mail.ru
backup email: ya-cbou@yandex.ru
irc://irc.freenode.net/bd2

^ permalink raw reply

* Re: [PATCH 0/4] PowerPC: implement GPIO API
From: Grant Likely @ 2007-12-21 20:50 UTC (permalink / raw)
  To: avorontsov; +Cc: linuxppc-dev
In-Reply-To: <20071221202824.GA4607@localhost.localdomain>

On 12/21/07, Anton Vorontsov <avorontsov@ru.mvista.com> wrote:
> Also, in the upcoming kernels, there will be GPIOLIB[1] addition to
> the generic GPIO API, to support off-chip GPIO expanders (like MFDs
> on I2C/LBC). But so far we support on-chip GPIOs only, with single
> controller built-in.
>
> Changes since RFC:
> - Implemented #gpio-cells handling;
> - Per-bank spinlocks removed;
> - Added a patch which implements GPIO API for CPM1;
> - Few minor fixes.

Also need to add documentation to booting-without-of.txt.

In general this looks like a good direction, but I do not like the
hard linking for QE and CPM gpios to the 'top level' gpio API.  I
think I'd prefer this stuff to stay out of mainline until the gpiolib
stuff gets merged (which should be soon IIRC).

Cheers,
g.


-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195

^ permalink raw reply

* [PATCH 3/3] [POWERPC] MPC8360E-RDK: add support for NAND on UPM
From: Anton Vorontsov @ 2007-12-21 20:41 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <20071221203552.GA4738@localhost.localdomain>

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 arch/powerpc/boot/dts/mpc836x_rdk.dts |   19 +++++++++++++++++--
 arch/powerpc/platforms/83xx/Kconfig   |    1 +
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc836x_rdk.dts b/arch/powerpc/boot/dts/mpc836x_rdk.dts
index 3f8d2b0..43420b1 100644
--- a/arch/powerpc/boot/dts/mpc836x_rdk.dts
+++ b/arch/powerpc/boot/dts/mpc836x_rdk.dts
@@ -126,7 +126,8 @@
 			reg = <0x700 0x100>;
 		};
 
-		par_io@1400 {
+		qe_pio: par_io@1400 {
+			#gpio-cells = <2>;
 			compatible = "fsl,qe-pario";
 			reg = <0x1400 0x100>;
 			num-ports = <7>;
@@ -292,7 +293,8 @@
 		compatible = "fsl,mpc8360-localbus",
 			     "fsl,pq2pro-localbus";
 		reg = <0xe0005000 0xd8>;
-		ranges = <0 0 0xff800000 0x800000>;
+		ranges = <0 0 0xff800000 0x800000
+			  1 0 0x60000000 0x001000>;
 
 		nor-flash@0,0 {
 			compatible = "intel,PC28F640P30T85", "cfi-flash";
@@ -300,6 +302,19 @@
 			bank-width = <2>;
 			device-width = <1>;
 		};
+
+		nand-flash@1,0 {
+			compatible = "stmicro,NAND512W3A2BN6E", "fsl,upm-nand";
+			reg = <1 0 1>;
+			width = <1>;
+			upm = "A";
+			upm-addr-offset = <16>;
+			upm-cmd-offset = <8>;
+			gpios = <4 18>;
+			gpio-parent = <&qe_pio>;
+			wait-pattern;
+			wait-write;
+		};
 	};
 
 	pci0: pci@e0008500 {
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 0d5a87c..723a8fe 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -88,6 +88,7 @@ config PPC_MPC836x
 	bool
 	select PPC_UDBG_16550
 	select PPC_INDIRECT_PCI
+	select FSL_UPM
 	default y if MPC836x_MDS || MPC836x_RDK
 
 config PPC_MPC837x
-- 
1.5.2.2

^ permalink raw reply related

* [PATCH 2/3] [POWERPC][NAND] FSL UPM NAND driver
From: Anton Vorontsov @ 2007-12-21 20:41 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev, linux-mtd
In-Reply-To: <20071221203552.GA4738@localhost.localdomain>

It's using FSL UPM infrastructure. So far only 8 bit accessors
are implemented.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 drivers/mtd/nand/Kconfig   |    7 +
 drivers/mtd/nand/Makefile  |    1 +
 drivers/mtd/nand/fsl_upm.c |  313 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 321 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mtd/nand/fsl_upm.c

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 246d451..91b448f 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -306,4 +306,11 @@ config MTD_ALAUDA
 	  These two (and possibly other) Alauda-based cardreaders for
 	  SmartMedia and xD allow raw flash access.
 
+config MTD_NAND_FSL_UPM
+	tristate "MTD driver for NAND on Freescale UPM"
+	depends on MTD_NAND && FSL_UPM && GENERIC_GPIO
+	help
+	  Enables support for NAND Flash wired to Freescale processors'
+	  localbus with pre-programmed User-Programmable Machine.
+
 endif # MTD_NAND
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 3ad6c01..d553ea3 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -29,5 +29,6 @@ obj-$(CONFIG_MTD_NAND_CM_X270)		+= cmx270_nand.o
 obj-$(CONFIG_MTD_NAND_BASLER_EXCITE)	+= excite_nandflash.o
 obj-$(CONFIG_MTD_NAND_PLATFORM)		+= plat_nand.o
 obj-$(CONFIG_MTD_ALAUDA)		+= alauda.o
+obj-$(CONFIG_MTD_NAND_FSL_UPM)		+= fsl_upm.o
 
 nand-objs := nand_base.o nand_bbt.o
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c
new file mode 100644
index 0000000..ac26199
--- /dev/null
+++ b/drivers/mtd/nand/fsl_upm.c
@@ -0,0 +1,313 @@
+/*
+ * Freescale UPM NAND driver.
+ *
+ * Copyright (c) 2007  MontaVista Software, Inc.
+ * Copyright (c) 2007  Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/mtd.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/fsl_upm.h>
+
+struct upm_data {
+	struct device *dev;
+	struct mtd_info mtd;
+	struct nand_chip chip;
+	int last_ctrl;
+#ifdef CONFIG_MTD_PARTITIONS
+	struct mtd_partition *parts;
+#endif
+
+	struct fsl_upm upm;
+
+	int width;
+	int upm_addr_offset;
+	int upm_cmd_offset;
+	void __iomem *io_base;
+	int rnb_gpio;
+	const u32 *wait_pattern;
+	const u32 *wait_write;
+	int chip_delay;
+};
+
+#define to_upm_data(mtd) container_of(mtd, struct upm_data, mtd)
+
+static int upm_chip_ready(struct mtd_info *mtd)
+{
+	struct upm_data *ud = to_upm_data(mtd);
+
+	if (gpio_get_value(ud->rnb_gpio))
+		return 1;
+
+	dev_vdbg(ud->dev, "busy\n");
+	return 0;
+}
+
+static void upm_wait_rnb(struct upm_data *ud)
+{
+	int cnt = 1000000;
+
+	if (ud->rnb_gpio >= 0) {
+		while (--cnt && !upm_chip_ready(&ud->mtd))
+			cpu_relax();
+	}
+
+	if (!cnt)
+		dev_err(ud->dev, "tired waiting for RNB\n");
+}
+
+static void upm_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+	struct upm_data *ud = to_upm_data(mtd);
+
+	if (!(ctrl & ud->last_ctrl)) {
+		fsl_upm_end_pattern(&ud->upm);
+
+		if (cmd == NAND_CMD_NONE)
+			return;
+
+		ud->last_ctrl = ctrl & (NAND_ALE | NAND_CLE);
+	}
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		if (ctrl & NAND_ALE)
+			fsl_upm_start_pattern(&ud->upm, ud->upm_addr_offset);
+		else if (ctrl & NAND_CLE)
+			fsl_upm_start_pattern(&ud->upm, ud->upm_cmd_offset);
+	}
+
+	fsl_upm_run_pattern(&ud->upm, ud->io_base, ud->width, cmd);
+
+	if (ud->wait_pattern)
+		upm_wait_rnb(ud);
+}
+
+static uint8_t upm_read_byte(struct mtd_info *mtd)
+{
+	struct upm_data *ud = to_upm_data(mtd);
+
+	return in_8(ud->chip.IO_ADDR_R);
+}
+
+static void upm_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+	struct upm_data *ud = to_upm_data(mtd);
+	int i;
+
+	for (i = 0; i < len; i++)
+		buf[i] = in_8(ud->chip.IO_ADDR_R);
+}
+
+static void upm_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+	struct upm_data *ud = to_upm_data(mtd);
+	int i;
+
+	for (i = 0; i < len; i++) {
+		out_8(ud->chip.IO_ADDR_W, buf[i]);
+		if (ud->wait_write)
+			upm_wait_rnb(ud);
+	}
+}
+
+static int __devinit upm_chip_init(struct upm_data *ud)
+{
+	int ret;
+#ifdef CONFIG_MTD_PARTITIONS
+	static const char *part_types[] = { "cmdlinepart", NULL, };
+#endif
+
+	ud->chip.IO_ADDR_R = ud->io_base;
+	ud->chip.IO_ADDR_W = ud->io_base;
+	ud->chip.cmd_ctrl = upm_cmd_ctrl;
+	ud->chip.chip_delay = ud->chip_delay;
+	ud->chip.read_byte = upm_read_byte;
+	ud->chip.read_buf = upm_read_buf;
+	ud->chip.write_buf = upm_write_buf;
+	ud->chip.ecc.mode = NAND_ECC_SOFT;
+
+	if (ud->rnb_gpio >= 0)
+		ud->chip.dev_ready = upm_chip_ready;
+
+	ud->mtd.priv = &ud->chip;
+	ud->mtd.owner = THIS_MODULE;
+
+	ret = nand_scan(&ud->mtd, 1);
+	if (ret)
+		return ret;
+
+	ud->mtd.name = ud->dev->bus_id;
+
+#ifdef CONFIG_MTD_PARTITIONS
+	ret = parse_mtd_partitions(&ud->mtd, part_types, &ud->parts, 0);
+	if (ret > 0)
+		return add_mtd_partitions(&ud->mtd, ud->parts, ret);
+#endif
+	return add_mtd_device(&ud->mtd);
+}
+
+static int __devinit upm_chip_probe(struct of_device *ofdev,
+				    const struct of_device_id *ofid)
+{
+	struct upm_data *ud;
+	struct resource io_res;
+	const u32 *prop;
+	int ret;
+	int size;
+
+	ud = kzalloc(sizeof(*ud), GFP_KERNEL);
+	if (!ud)
+		return -ENOMEM;
+
+	ret = of_address_to_resource(ofdev->node, 0, &io_res);
+	if (ret) {
+		dev_err(&ofdev->dev, "can't get IO base\n");
+		goto err;
+	}
+
+	prop = of_get_property(ofdev->node, "width", &size);
+	if (!prop || size != sizeof(u32)) {
+		dev_err(&ofdev->dev, "can't get chip width\n");
+		goto err;
+	}
+	ud->width = *prop * 8;
+
+	prop = of_get_property(ofdev->node, "upm", &size);
+	if (!prop || size < 1) {
+		dev_err(&ofdev->dev, "can't get UPM to use\n");
+		ret = -EINVAL;
+		goto err;
+	}
+
+	ret = fsl_upm_get_for(ofdev->node, (const char *)prop, &ud->upm);
+	if (ret) {
+		dev_err(&ofdev->dev, "can't get FSL UPM\n");
+		goto err;
+	}
+
+	prop = of_get_property(ofdev->node, "upm-addr-offset", &size);
+	if (!prop || size != sizeof(u32)) {
+		dev_err(&ofdev->dev, "can't get UPM address offset\n");
+		ret = -EINVAL;
+		goto err;
+	}
+	ud->upm_addr_offset = *prop;
+
+	prop = of_get_property(ofdev->node, "upm-cmd-offset", &size);
+	if (!prop || size != sizeof(u32)) {
+		dev_err(&ofdev->dev, "can't get UPM command offset\n");
+		ret = -EINVAL;
+		goto err;
+	}
+	ud->upm_cmd_offset = *prop;
+
+	ud->rnb_gpio = of_get_gpio(ofdev->node, 0);
+	if (ud->rnb_gpio >= 0) {
+		ret = gpio_request(ud->rnb_gpio, ofdev->dev.bus_id);
+		if (ret) {
+			dev_err(&ofdev->dev, "can't request RNB gpio\n");
+			goto err;
+		}
+		gpio_direction_input(ud->rnb_gpio);
+	} else if (ud->rnb_gpio == -EINVAL) {
+		dev_err(&ofdev->dev, "specified RNB gpio is invalid\n");
+		goto err;
+	}
+
+	ud->io_base = devm_ioremap_nocache(&ofdev->dev, io_res.start,
+					  io_res.end - io_res.start + 1);
+	if (!ud->io_base) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	ud->dev = &ofdev->dev;
+	ud->last_ctrl = NAND_CLE;
+	ud->wait_pattern = of_get_property(ofdev->node, "wait-pattern", NULL);
+	ud->wait_write = of_get_property(ofdev->node, "wait-write", NULL);
+
+	prop = of_get_property(ofdev->node, "chip-delay", NULL);
+	if (prop)
+		ud->chip_delay = *prop;
+	else
+		ud->chip_delay = 50;
+
+	ret = upm_chip_init(ud);
+	if (ret)
+		goto err;
+
+	dev_set_drvdata(&ofdev->dev, ud);
+
+	return 0;
+
+err:
+	if (fsl_upm_got(&ud->upm))
+		fsl_upm_free(&ud->upm);
+
+	if (ud->rnb_gpio >= 0)
+		gpio_free(ud->rnb_gpio);
+
+	kfree(ud);
+
+	return ret;
+}
+
+static int __devexit upm_chip_remove(struct of_device *ofdev)
+{
+	struct upm_data *ud = dev_get_drvdata(&ofdev->dev);
+
+	nand_release(&ud->mtd);
+
+	fsl_upm_free(&ud->upm);
+
+	if (ud->rnb_gpio >= 0)
+		gpio_free(ud->rnb_gpio);
+
+	kfree(ud);
+
+	return 0;
+}
+
+static struct of_device_id of_upm_nand_match[] = {
+	{ .compatible = "fsl,upm-nand" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, of_upm_nand_match);
+
+static struct of_platform_driver of_upm_chip_driver = {
+	.name		= "fsl_upm_nand",
+	.match_table	= of_upm_nand_match,
+	.probe		= upm_chip_probe,
+	.remove		= __devexit_p(upm_chip_remove),
+};
+
+static int __init upm_nand_init(void)
+{
+	return of_register_platform_driver(&of_upm_chip_driver);
+}
+
+static void __exit upm_nand_exit(void)
+{
+	of_unregister_platform_driver(&of_upm_chip_driver);
+}
+
+module_init(upm_nand_init);
+module_exit(upm_nand_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>");
+MODULE_DESCRIPTION("Driver for NAND chips working through Freescale "
+		   "LocalBus User-Programmable Machine");
-- 
1.5.2.2

^ permalink raw reply related

* [PATCH 1/3] [POWERPC] FSL UPM: routines to manage FSL UPMs
From: Anton Vorontsov @ 2007-12-21 20:39 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <20071221203552.GA4738@localhost.localdomain>

Here are few routines needed to manage FSL UPMs. It doesn't include
UPM programming, yet. So far u-boot manages to program everything.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 arch/powerpc/Kconfig          |    3 +
 arch/powerpc/sysdev/Makefile  |    1 +
 arch/powerpc/sysdev/fsl_upm.c |   65 +++++++++++++++++++++++++++++
 include/asm-powerpc/fsl_upm.h |   90 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 159 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/sysdev/fsl_upm.c
 create mode 100644 include/asm-powerpc/fsl_upm.h

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a4fa173..aab8106 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -463,6 +463,9 @@ config FSL_PCI
  	bool
 	select PPC_INDIRECT_PCI
 
+config FSL_UPM
+	bool
+
 # Yes MCA RS/6000s exist but Linux-PPC does not currently support any
 config MCA
 	bool
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 99a77d7..98dbfdd 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_U3_DART)		+= dart_iommu.o
 obj-$(CONFIG_MMIO_NVRAM)	+= mmio_nvram.o
 obj-$(CONFIG_FSL_SOC)		+= fsl_soc.o
 obj-$(CONFIG_FSL_PCI)		+= fsl_pci.o
+obj-$(CONFIG_FSL_UPM)		+= fsl_upm.o
 obj-$(CONFIG_TSI108_BRIDGE)	+= tsi108_pci.o tsi108_dev.o
 obj-$(CONFIG_QUICC_ENGINE)	+= qe_lib/
 obj-$(CONFIG_PPC_BESTCOMM)	+= bestcomm/
diff --git a/arch/powerpc/sysdev/fsl_upm.c b/arch/powerpc/sysdev/fsl_upm.c
new file mode 100644
index 0000000..6e35bf4
--- /dev/null
+++ b/arch/powerpc/sysdev/fsl_upm.c
@@ -0,0 +1,65 @@
+/*
+ * Freescale UPM routines.
+ *
+ * Copyright (c) 2007  MontaVista Software, Inc.
+ * Copyright (c) 2007  Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <asm/fsl_upm.h>
+
+spinlock_t upm_lock = __SPIN_LOCK_UNLOCKED(upm_lock);
+unsigned long upm_lock_flags;
+
+int fsl_upm_get_for(struct device_node *node, const char *name,
+		    struct fsl_upm *upm)
+{
+	int ret;
+	struct device_node *lbus;
+	struct resource lbc_res;
+	ptrdiff_t mxmr_offs;
+
+	lbus = of_get_parent(node);
+	if (!lbus) {
+		pr_err("FSL UPM: can't get parent local bus node\n");
+		return -ENOENT;
+	}
+
+	ret = of_address_to_resource(lbus, 0, &lbc_res);
+	if (ret) {
+		pr_err("FSL UPM: can't get parent local bus base\n");
+		return -ENOMEM;
+	}
+
+	switch (name[0]) {
+	case 'A':
+		mxmr_offs = LBC_MAMR;
+		break;
+	case 'B':
+		mxmr_offs = LBC_MBMR;
+		break;
+	case 'C':
+		mxmr_offs = LBC_MCMR;
+		break;
+	default:
+		pr_err("FSL UPM: unknown UPM requested\n");
+		return -EINVAL;
+		break;
+	}
+
+	upm->lbc_base = ioremap_nocache(lbc_res.start,
+					lbc_res.end - lbc_res.start + 1);
+	if (!upm->lbc_base)
+		return -ENOMEM;
+
+	upm->mxmr = upm->lbc_base + mxmr_offs;
+	upm->mar = upm->lbc_base + LBC_MAR;
+
+	return 0;
+}
diff --git a/include/asm-powerpc/fsl_upm.h b/include/asm-powerpc/fsl_upm.h
new file mode 100644
index 0000000..fe5a5d9
--- /dev/null
+++ b/include/asm-powerpc/fsl_upm.h
@@ -0,0 +1,90 @@
+/*
+ * Freescale UPM routines.
+ *
+ * Copyright (c) 2007  MontaVista Software, Inc.
+ * Copyright (c) 2007  Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * 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_POWERPC_FSL_UPM
+#define __ASM_POWERPC_FSL_UPM
+
+#include <linux/spinlock.h>
+#include <asm/io.h>
+
+#define LBC_MAR		0x68
+#define LBC_MAMR	0x70
+#define LBC_MBMR	0x74
+#define LBC_MCMR	0x78
+
+#define LBC_MXMR_RUNP	0x30000000
+
+struct fsl_upm {
+	void __iomem *lbc_base;
+	void __iomem *mxmr;
+	void __iomem *mar;
+};
+
+extern spinlock_t upm_lock;
+extern unsigned long upm_lock_flags;
+
+extern int fsl_upm_get_for(struct device_node *node, const char *name,
+			   struct fsl_upm *upm);
+
+static inline void fsl_upm_free(struct fsl_upm *upm)
+{
+	iounmap(upm->lbc_base);
+	upm->lbc_base = NULL;
+}
+
+static inline int fsl_upm_got(struct fsl_upm *upm)
+{
+	return !!upm->lbc_base;
+}
+
+static inline void fsl_upm_start_pattern(struct fsl_upm *upm, u32 pat_offset)
+{
+	spin_lock_irqsave(&upm_lock, upm_lock_flags);
+
+	out_be32(upm->mxmr, LBC_MXMR_RUNP | pat_offset);
+}
+
+static inline void fsl_upm_end_pattern(struct fsl_upm *upm)
+{
+	out_be32(upm->mxmr, 0x0);
+
+	while (in_be32(upm->mxmr) != 0x0)
+		cpu_relax();
+
+	spin_unlock_irqrestore(&upm_lock, upm_lock_flags);
+}
+
+static inline int fsl_upm_run_pattern(struct fsl_upm *upm,
+				      void __iomem *io_base,
+				      int width, u32 cmd)
+{
+	out_be32(upm->mar, cmd << (32 - width));
+
+	switch (width) {
+	case 8:
+		out_8(io_base, 0x0);
+		break;
+	case 16:
+		out_be16(io_base, 0x0);
+		break;
+	case 32:
+		out_be32(io_base, 0x0);
+		break;
+	default:
+		return -EINVAL;
+		break;
+	}
+
+	return 0;
+}
+
+#endif /* __ASM_POWERPC_FSL_UPM */
-- 
1.5.2.2

^ permalink raw reply related

* [PATCH 0/3] fsl upm, nand driver and MPC8360E-RDK as its first user
From: Anton Vorontsov @ 2007-12-21 20:35 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev

Hi all,

Here is the FSL UPM infrastructure and FSL UPM NAND driver which is
using it. This patchset depends on GPIO API.

Changes since RFC:
- Lockless variant removed;
- Implemented "width" property;
- Few cosmetic changes.

Thanks,

-- 
Anton Vorontsov
email: cbou@mail.ru
backup email: ya-cbou@yandex.ru
irc://irc.freenode.net/bd2

^ permalink raw reply

* [PATCH 4/4] [POWERPC] CPM1: implement GPIO API
From: Anton Vorontsov @ 2007-12-21 20:34 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <20071221202824.GA4607@localhost.localdomain>

From: Jochen Friedrich <jochen@scram.de>

Signed-off-by: Jochen Friedrich <jochen@scram.de>
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---

Jochen, I kept your Signed-off-by, though this isn't your original
patch. Hope you're okay with it. I also hope you'll test it. ;-)

 arch/powerpc/platforms/8xx/Kconfig |    1 +
 arch/powerpc/sysdev/commproc.c     |  178 +++++++++++++++++++++++++++++++++++-
 2 files changed, 178 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig
index 91fbe42..6962914 100644
--- a/arch/powerpc/platforms/8xx/Kconfig
+++ b/arch/powerpc/platforms/8xx/Kconfig
@@ -4,6 +4,7 @@ config FADS
 config CPM1
 	bool
 	select CPM
+	select GENERIC_GPIO
 
 choice
 	prompt "8xx Machine Type"
diff --git a/arch/powerpc/sysdev/commproc.c b/arch/powerpc/sysdev/commproc.c
index 621bc6c..8aea29c 100644
--- a/arch/powerpc/sysdev/commproc.c
+++ b/arch/powerpc/sysdev/commproc.c
@@ -27,6 +27,7 @@
 #include <linux/param.h>
 #include <linux/string.h>
 #include <linux/mm.h>
+#include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/module.h>
@@ -36,6 +37,7 @@
 #include <asm/8xx_immap.h>
 #include <asm/commproc.h>
 #include <asm/io.h>
+#include <asm/gpio.h>
 #include <asm/tlbflush.h>
 #include <asm/rheap.h>
 #include <asm/prom.h>
@@ -56,6 +58,39 @@ static cpic8xx_t __iomem *cpic_reg;
 
 static struct irq_host *cpm_pic_host;
 
+static spinlock_t cpm1_port_lock = __SPIN_LOCK_UNLOCKED(cpm1_port_lock);
+static int cpm1_num_ports;
+
+static int par_io_xlate(struct device_node *np, int index)
+{
+	return __of_parse_gpio_bank_pin(np, index, 32, cpm1_num_ports);
+}
+
+static struct of_gpio_chip of_gpio_chip = {
+	.xlate = par_io_xlate,
+};
+
+int cpm_init_par_io(void)
+{
+	struct device_node *np;
+	const u32 *num_ports;
+
+	np = of_find_node_by_name(NULL, "fsl,cpm1-pario");
+	if (!np)
+		return -ENOENT;
+
+	num_ports = of_get_property(np, "num-ports", NULL);
+	if (!num_ports) {
+		of_node_put(np);
+		return -ENOENT;
+	}
+	cpm1_num_ports = *num_ports;
+
+	np->data = &of_gpio_chip;
+
+	return 0;
+}
+
 static void cpm_mask_irq(unsigned int irq)
 {
 	unsigned int cpm_vec = (unsigned int)irq_map[irq].hwirq;
@@ -199,6 +234,7 @@ end:
 void __init cpm_reset(void)
 {
 	sysconf8xx_t __iomem *siu_conf;
+	int ret;
 
 	mpc8xx_immr = ioremap(get_immrbase(), 0x4000);
 	if (!mpc8xx_immr) {
@@ -238,6 +274,10 @@ void __init cpm_reset(void)
 	/* Reclaim the DP memory for our use. */
 	m8xx_cpm_dpinit();
 #endif
+
+	ret = cpm_init_par_io();
+	if (ret)
+		pr_warning("CPM PIO not initialized!\n");
 }
 
 static DEFINE_SPINLOCK(cmd_lock);
@@ -441,7 +481,7 @@ struct cpm_ioport16 {
 };
 
 struct cpm_ioport32 {
-	__be32 dir, par, sor;
+	__be32 dir, par, sor, dat;
 };
 
 static void cpm1_set_pin32(int port, int pin, int flags)
@@ -486,6 +526,39 @@ static void cpm1_set_pin32(int port, int pin, int flags)
 	}
 }
 
+static void cpm1_set_value32(int port, int pin, int value)
+{
+	struct cpm_ioport32 __iomem *iop;
+	pin = 1 << (31 - pin);
+
+	if (port == CPM_PORTB)
+		iop = (struct cpm_ioport32 __iomem *)
+		      &mpc8xx_immr->im_cpm.cp_pbdir;
+	else
+		iop = (struct cpm_ioport32 __iomem *)
+		      &mpc8xx_immr->im_cpm.cp_pedir;
+
+	if (value)
+		setbits32(&iop->dat, pin);
+	else
+		clrbits32(&iop->dat, pin);
+}
+
+static int cpm1_get_value32(int port, int pin)
+{
+	struct cpm_ioport32 __iomem *iop;
+	pin = 1 << (31 - pin);
+
+	if (port == CPM_PORTB)
+		iop = (struct cpm_ioport32 __iomem *)
+		      &mpc8xx_immr->im_cpm.cp_pbdir;
+	else
+		iop = (struct cpm_ioport32 __iomem *)
+		      &mpc8xx_immr->im_cpm.cp_pedir;
+
+	return !!(in_be32(&iop->dat) & pin);
+}
+
 static void cpm1_set_pin16(int port, int pin, int flags)
 {
 	struct cpm_ioport16 __iomem *iop =
@@ -520,6 +593,35 @@ static void cpm1_set_pin16(int port, int pin, int flags)
 	}
 }
 
+static void cpm1_set_value16(int port, int pin, int value)
+{
+	struct cpm_ioport16 __iomem *iop =
+		(struct cpm_ioport16 __iomem *)&mpc8xx_immr->im_ioport;
+
+	pin = 1 << (15 - pin);
+
+	if (port != 0)
+		iop += port - 1;
+
+	if (value)
+		setbits16(&iop->dat, pin);
+	else
+		clrbits16(&iop->dat, pin);
+}
+
+static int cpm1_get_value16(int port, int pin)
+{
+	struct cpm_ioport16 __iomem *iop =
+		(struct cpm_ioport16 __iomem *)&mpc8xx_immr->im_ioport;
+
+	pin = 1 << (15 - pin);
+
+	if (port != 0)
+		iop += port - 1;
+
+	return !!(in_be16(&iop->dat) & pin);
+}
+
 void cpm1_set_pin(enum cpm_port port, int pin, int flags)
 {
 	if (port == CPM_PORTB || port == CPM_PORTE)
@@ -648,3 +750,77 @@ int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode)
 
 	return 0;
 }
+
+int gpio_request(unsigned int gpio, const char *label)
+{
+	if (gpio / 32 >= cpm1_num_ports)
+		return -EINVAL;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(gpio_request);
+
+int gpio_direction_input(unsigned int gpio)
+{
+	unsigned long flags;
+	int port = gpio / 32;
+	int pin = gpio % 32;
+
+	spin_lock_irqsave(&cpm1_port_lock, flags);
+
+	cpm1_set_pin(port, pin, CPM_PIN_INPUT | CPM_PIN_GPIO);
+
+	spin_unlock_irqrestore(&cpm1_port_lock, flags);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(gpio_direction_input);
+
+int gpio_direction_output(unsigned int gpio, int value)
+{
+	int port = gpio / 32;
+	int pin = gpio % 32;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cpm1_port_lock, flags);
+
+	cpm1_set_pin(port, pin, CPM_PIN_OUTPUT | CPM_PIN_GPIO);
+
+	if (port == CPM_PORTB || port == CPM_PORTE)
+		cpm1_set_value32(port, pin, value);
+	else
+		cpm1_set_value16(port, pin, value);
+
+	spin_unlock_irqrestore(&cpm1_port_lock, flags);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(gpio_direction_output);
+
+int gpio_get_value(unsigned int gpio)
+{
+	int port = gpio / 32;
+	int pin = gpio % 32;
+
+	if (port == CPM_PORTB || port == CPM_PORTE)
+		return cpm1_get_value32(port, pin);
+	else
+		return cpm1_get_value16(port, pin);
+}
+EXPORT_SYMBOL_GPL(gpio_get_value);
+
+int gpio_set_value(unsigned int gpio, int value)
+{
+	int port = gpio / 32;
+	int pin = gpio % 32;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cpm1_port_lock, flags);
+
+	if (port == CPM_PORTB || port == CPM_PORTE)
+		cpm1_set_value32(port, pin, value);
+	else
+		cpm1_set_value16(port, pin, value);
+
+	spin_unlock_irqrestore(&cpm1_port_lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(gpio_set_value);
-- 
1.5.2.2

^ permalink raw reply related

* [PATCH 3/4] [POWERPC] CPM2: implement GPIO API
From: Anton Vorontsov @ 2007-12-21 20:31 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <20071221202824.GA4607@localhost.localdomain>

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 arch/powerpc/platforms/Kconfig    |    1 +
 arch/powerpc/sysdev/cpm2_common.c |  121 +++++++++++++++++++++++++++++++++++++
 2 files changed, 122 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 3d9ff27..cc2d54e 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -277,6 +277,7 @@ config CPM2
 	default n
 	select CPM
 	select PPC_LIB_RHEAP
+	select GENERIC_GPIO
 	help
 	  The CPM2 (Communications Processor Module) is a coprocessor on
 	  embedded CPUs made by Freescale.  Selecting this option means that
diff --git a/arch/powerpc/sysdev/cpm2_common.c b/arch/powerpc/sysdev/cpm2_common.c
index f7188e2..fe25978 100644
--- a/arch/powerpc/sysdev/cpm2_common.c
+++ b/arch/powerpc/sysdev/cpm2_common.c
@@ -31,12 +31,14 @@
 #include <linux/param.h>
 #include <linux/string.h>
 #include <linux/mm.h>
+#include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/of.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/gpio.h>
 #include <asm/mpc8260.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -61,8 +63,43 @@ cpm2_map_t __iomem *cpm2_immr;
 					   of space for CPM as it is larger
 					   than on PQ2 */
 
+static spinlock_t cpm2_port_lock = __SPIN_LOCK_UNLOCKED(cpm2_port_lock);
+static int cpm2_num_ports;
+
+static int par_io_xlate(struct device_node *np, int index)
+{
+	return __of_parse_gpio_bank_pin(np, index, 32, cpm2_num_ports);
+}
+
+static struct of_gpio_chip of_gpio_chip = {
+	.xlate = par_io_xlate,
+};
+
+int cpm2_init_par_io(void)
+{
+	struct device_node *np;
+	const u32 *num_ports;
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pario");
+	if (!np)
+		return -ENOENT;
+
+	num_ports = of_get_property(np, "num-ports", NULL);
+	if (!num_ports) {
+		of_node_put(np);
+		return -ENOENT;
+	}
+	cpm2_num_ports = *num_ports;
+
+	np->data = &of_gpio_chip;
+
+	return 0;
+}
+
 void __init cpm2_reset(void)
 {
+	int ret;
+
 #ifdef CONFIG_PPC_85xx
 	cpm2_immr = ioremap(CPM_MAP_ADDR, CPM_MAP_SIZE);
 #else
@@ -80,6 +117,10 @@ void __init cpm2_reset(void)
 	/* Tell everyone where the comm processor resides.
 	 */
 	cpmp = &cpm2_immr->im_cpm;
+
+	ret = cpm2_init_par_io();
+	if (ret)
+		pr_warning("CPM2 PIO not initialized!\n");
 }
 
 static DEFINE_SPINLOCK(cmd_lock);
@@ -468,3 +509,83 @@ void cpm2_set_pin(int port, int pin, int flags)
 	else
 		clrbits32(&iop[port].odr, pin);
 }
+
+int gpio_request(unsigned int gpio, const char *label)
+{
+	if (gpio / 32 >= cpm2_num_ports)
+		return -EINVAL;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(gpio_request);
+
+int gpio_direction_input(unsigned int gpio)
+{
+	unsigned long flags;
+	int port = gpio / 32;
+	int pin = gpio % 32;
+
+	spin_lock_irqsave(&cpm2_port_lock, flags);
+
+	cpm2_set_pin(port, pin, CPM_PIN_INPUT | CPM_PIN_GPIO);
+
+	spin_unlock_irqrestore(&cpm2_port_lock, flags);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(gpio_direction_input);
+
+int gpio_direction_output(unsigned int gpio, int value)
+{
+	struct cpm2_ioports __iomem *iop =
+		(struct cpm2_ioports __iomem *)&cpm2_immr->im_ioport;
+	int port = gpio / 32;
+	int pin = gpio % 32;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cpm2_port_lock, flags);
+
+	cpm2_set_pin(port, pin, CPM_PIN_OUTPUT | CPM_PIN_GPIO);
+
+	pin = 1 << (31 - pin);
+	if (value)
+		setbits32(&iop[port].dat, pin);
+	else
+		clrbits32(&iop[port].dat, pin);
+
+	spin_unlock_irqrestore(&cpm2_port_lock, flags);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(gpio_direction_output);
+
+int gpio_get_value(unsigned int gpio)
+{
+	struct cpm2_ioports __iomem *iop =
+		(struct cpm2_ioports __iomem *)&cpm2_immr->im_ioport;
+	int port = gpio / 32;
+	int pin = gpio % 32;
+
+	pin = 1 << (31 - pin);
+
+	return !!(in_be32(&iop[port].dat) & pin);
+}
+EXPORT_SYMBOL_GPL(gpio_get_value);
+
+int gpio_set_value(unsigned int gpio, int value)
+{
+	struct cpm2_ioports __iomem *iop =
+		(struct cpm2_ioports __iomem *)&cpm2_immr->im_ioport;
+	int port = gpio / 32;
+	int pin = gpio % 32;
+	unsigned long flags;
+
+	pin = 1 << (31 - pin);
+
+	spin_lock_irqsave(&cpm2_port_lock, flags);
+	if (value)
+		setbits32(&iop[port].dat, pin);
+	else
+		clrbits32(&iop[port].dat, pin);
+	spin_unlock_irqrestore(&cpm2_port_lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(gpio_set_value);
-- 
1.5.2.2

^ permalink raw reply related

* [PATCH 2/4] [POWERPC] QE: implement GPIO API
From: Anton Vorontsov @ 2007-12-21 20:31 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <20071221202824.GA4607@localhost.localdomain>

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 arch/powerpc/platforms/Kconfig     |    1 +
 arch/powerpc/sysdev/qe_lib/qe_io.c |   82 +++++++++++++++++++++++++++++++++++-
 2 files changed, 81 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index ea22cad..3d9ff27 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -265,6 +265,7 @@ config TAU_AVERAGE
 config QUICC_ENGINE
 	bool
 	select PPC_LIB_RHEAP
+	select GENERIC_GPIO
 	help
 	  The QUICC Engine (QE) is a new generation of communications
 	  coprocessors on Freescale embedded CPUs (akin to CPM in older chips).
diff --git a/arch/powerpc/sysdev/qe_lib/qe_io.c b/arch/powerpc/sysdev/qe_lib/qe_io.c
index e53ea4d..3c9e5fe 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_io.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_io.c
@@ -23,6 +23,7 @@
 
 #include <asm/io.h>
 #include <asm/prom.h>
+#include <asm/gpio.h>
 #include <sysdev/fsl_soc.h>
 
 #undef DEBUG
@@ -43,6 +44,16 @@ struct port_regs {
 
 static struct port_regs *par_io = NULL;
 static int num_par_io_ports = 0;
+static spinlock_t qe_pio_lock = __SPIN_LOCK_UNLOCKED(qe_pio_lock);
+
+static int par_io_xlate(struct device_node *np, int index)
+{
+	return __of_parse_gpio_bank_pin(np, index, 32, num_par_io_ports);
+}
+
+static struct of_gpio_chip of_gpio_chip = {
+	.xlate = par_io_xlate,
+};
 
 int par_io_init(struct device_node *np)
 {
@@ -60,6 +71,8 @@ int par_io_init(struct device_node *np)
 	if (num_ports)
 		num_par_io_ports = *num_ports;
 
+	np->data = &of_gpio_chip;
+
 	return 0;
 }
 
@@ -67,9 +80,12 @@ int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain,
 		      int assignment, int has_irq)
 {
 	u32 pin_mask1bit, pin_mask2bits, new_mask2bits, tmp_val;
+	unsigned long flags;
 
-	if (!par_io)
-		return -1;
+	if (!par_io || port >= num_par_io_ports)
+		return -EINVAL;
+
+	spin_lock_irqsave(&qe_pio_lock, flags);
 
 	/* calculate pin location for single and 2 bits information */
 	pin_mask1bit = (u32) (1 << (NUM_OF_PINS - (pin + 1)));
@@ -126,6 +142,8 @@ int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain,
 		out_be32(&par_io[port].cppar1, new_mask2bits | tmp_val);
 	}
 
+	spin_unlock_irqrestore(&qe_pio_lock, flags);
+
 	return 0;
 }
 EXPORT_SYMBOL(par_io_config_pin);
@@ -133,6 +151,7 @@ EXPORT_SYMBOL(par_io_config_pin);
 int par_io_data_set(u8 port, u8 pin, u8 val)
 {
 	u32 pin_mask, tmp_val;
+	unsigned long flags;
 
 	if (port >= num_par_io_ports)
 		return -EINVAL;
@@ -141,6 +160,8 @@ int par_io_data_set(u8 port, u8 pin, u8 val)
 	/* calculate pin location */
 	pin_mask = (u32) (1 << (NUM_OF_PINS - 1 - pin));
 
+	spin_lock_irqsave(&qe_pio_lock, flags);
+
 	tmp_val = in_be32(&par_io[port].cpdata);
 
 	if (val == 0)		/* clear */
@@ -148,10 +169,25 @@ int par_io_data_set(u8 port, u8 pin, u8 val)
 	else			/* set */
 		out_be32(&par_io[port].cpdata, pin_mask | tmp_val);
 
+	spin_unlock_irqrestore(&qe_pio_lock, flags);
 	return 0;
 }
 EXPORT_SYMBOL(par_io_data_set);
 
+static inline int par_io_data_get(u8 port, u8 pin)
+{
+	u32 pin_mask;
+
+	if (port >= num_par_io_ports)
+		return -EINVAL;
+	if (pin >= NUM_OF_PINS)
+		return -EINVAL;
+	/* calculate pin location */
+	pin_mask = (u32) (1 << (NUM_OF_PINS - 1 - pin));
+
+	return !!(in_be32(&par_io[port].cpdata) & pin_mask);
+}
+
 int par_io_of_config(struct device_node *np)
 {
 	struct device_node *pio;
@@ -195,6 +231,48 @@ int par_io_of_config(struct device_node *np)
 }
 EXPORT_SYMBOL(par_io_of_config);
 
+int gpio_request(unsigned int gpio, const char *label)
+{
+	if (!par_io)
+		return -ENODEV;
+
+	if (gpio / 32 >= num_par_io_ports)
+		return -EINVAL;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(gpio_request);
+
+int gpio_direction_input(unsigned int gpio)
+{
+	return par_io_config_pin(gpio / 32, gpio % 32, 2, 0, 0, 0);
+}
+EXPORT_SYMBOL_GPL(gpio_direction_input);
+
+int gpio_direction_output(unsigned int gpio, int value)
+{
+	int ret;
+
+	ret = par_io_config_pin(gpio / 32, gpio % 32, 1, 0, 0, 0);
+	if (ret)
+		return ret;
+
+	return par_io_data_set(gpio / 32, gpio % 32, value);
+}
+EXPORT_SYMBOL_GPL(gpio_direction_output);
+
+int gpio_get_value(unsigned int gpio)
+{
+	return par_io_data_get(gpio / 32, gpio % 32);
+}
+EXPORT_SYMBOL_GPL(gpio_get_value);
+
+int gpio_set_value(unsigned int gpio, int value)
+{
+	return par_io_data_set(gpio / 32, gpio % 32, value);
+}
+EXPORT_SYMBOL_GPL(gpio_set_value);
+
 #ifdef DEBUG
 static void dump_par_io(void)
 {
-- 
1.5.2.2

^ permalink raw reply related

* [PATCH 1/4] [POWERPC] Implement GPIO API embryo
From: Anton Vorontsov @ 2007-12-21 20:31 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <20071221202824.GA4607@localhost.localdomain>

This patch implements GPIO API as described in Documentation/gpio.txt.
Two calls unimplemented though: irq_to_gpio and gpio_to_irq.

This patch also provides OF helpers.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 arch/powerpc/Kconfig             |    3 ++
 arch/powerpc/kernel/prom_parse.c |   64 ++++++++++++++++++++++++++++++++++++++
 include/asm-powerpc/gpio.h       |   47 ++++++++++++++++++++++++++++
 include/asm-powerpc/prom.h       |   23 +++++++++++++
 4 files changed, 137 insertions(+), 0 deletions(-)
 create mode 100644 include/asm-powerpc/gpio.h

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 232c298..a4fa173 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -73,6 +73,9 @@ config GENERIC_FIND_NEXT_BIT
 	bool
 	default y
 
+config GENERIC_GPIO
+	bool
+
 config ARCH_NO_VIRT_TO_BUS
 	def_bool PPC64
 
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 90eb3a3..9875598 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -7,6 +7,7 @@
 #include <linux/ioport.h>
 #include <linux/etherdevice.h>
 #include <asm/prom.h>
+#include <asm/gpio.h>
 #include <asm/pci-bridge.h>
 
 #ifdef DEBUG
@@ -1079,3 +1080,66 @@ void __iomem *of_iomap(struct device_node *np, int index)
 	return ioremap(res.start, 1 + res.end - res.start);
 }
 EXPORT_SYMBOL(of_iomap);
+
+int __of_parse_gpio_bank_pin(struct device_node *np, int index,
+			     int bank_width, int max_bank)
+{
+	int bank;
+	int pin;
+	const u32 *gpios;
+
+	/*
+	 * We can get there only if of_get_gpio() succeeded, thus
+	 * no need checking for "gpios" existence.
+	 */
+	gpios = of_get_property(np, "gpios", NULL);
+	bank = gpios[index * 2];
+	pin = gpios[index * 2 + 1];
+
+	if (bank >= max_bank || pin >= bank_width)
+		return -EINVAL;
+
+	return bank * bank_width + pin;
+}
+EXPORT_SYMBOL_GPL(__of_parse_gpio_bank_pin);
+
+int of_get_gpio(struct device_node *np, int index)
+{
+	int ret = -EINVAL;
+	const phandle *gc_ph;
+	struct device_node *gc;
+	struct of_gpio_chip *of_gpio_chip;
+	int size;
+	const u32 *gpio_cells;
+	const u32 *gpios;
+	u32 nr_cells;
+
+	gc_ph = of_get_property(np, "gpio-parent", NULL);
+	if (!gc_ph)
+		return ret;
+
+	gc = of_find_node_by_phandle(*gc_ph);
+	if (!gc || !gc->data)
+		return ret;
+
+	gpio_cells = of_get_property(gc, "#gpio-cells", &size);
+	if (!gpio_cells || size != sizeof(*gpio_cells) || *gpio_cells == 0)
+		goto err;
+
+	gpios = of_get_property(np, "gpios", &size);
+	if (!gpios)
+		goto err;
+	nr_cells = size / sizeof(u32);
+
+	if (nr_cells < *gpio_cells || nr_cells % *gpio_cells ||
+			index > nr_cells / *gpio_cells - 1)
+		goto err;
+
+	of_gpio_chip = gc->data;
+
+	ret = of_gpio_chip->xlate(np, index);
+err:
+	of_node_put(gc);
+	return ret;
+}
+EXPORT_SYMBOL(of_get_gpio);
diff --git a/include/asm-powerpc/gpio.h b/include/asm-powerpc/gpio.h
new file mode 100644
index 0000000..e0a4f85
--- /dev/null
+++ b/include/asm-powerpc/gpio.h
@@ -0,0 +1,47 @@
+/*
+ * Generic GPIO API implementation for PowerPC.
+ *
+ * Copyright (c) 2007  MontaVista Software, Inc.
+ * Copyright (c) 2007  Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * 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_POWERPC_GPIO_H
+#define __ASM_POWERPC_GPIO_H
+
+extern int gpio_request(unsigned int gpio, const char *label);
+static inline void gpio_free(unsigned int gpio) {}
+
+extern int gpio_direction_input(unsigned int gpio);
+extern int gpio_direction_output(unsigned int gpio, int value);
+
+extern int gpio_get_value(unsigned int gpio);
+extern int gpio_set_value(unsigned int gpio, int value);
+
+/*
+ * Not implemented, yet.
+ */
+static inline int gpio_to_irq(unsigned int gpio)
+{
+	return -ENOSYS;
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+	return -ENOSYS;
+}
+
+/*
+ * OF specific gpio_chip handler.
+ */
+struct of_gpio_chip {
+	int (*xlate)(struct device_node *np, int index);
+};
+
+#include <asm-generic/gpio.h>
+
+#endif /* __ASM_POWERPC_GPIO_H */
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index 78b7b0d..f882efc 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -330,6 +330,29 @@ extern int of_irq_to_resource(struct device_node *dev, int index,
  */
 extern void __iomem *of_iomap(struct device_node *device, int index);
 
+/**
+ * __of_parse_gpio_bank_pin - Helper function to translate "bank pin" GPIOs
+ * @np:		device node to get GPIO from
+ * @index:	index of the GPIO
+ * @bank_width:	pins per bank
+ * @max_bank:	maximum value to represent a bank
+ *
+ * Returns GPIO number to use with Linux generic GPIO api, or
+ * one of the errno value on the error condition.
+ */
+extern int __of_parse_gpio_bank_pin(struct device_node *np, int index,
+				    int bank_width, int max_bank);
+
+/**
+ * of_get_gpio - Translate GPIO number given in the device tree
+ * @np:		device node to get GPIO from
+ * @index:	index of the GPIO
+ *
+ * Returns GPIO number to use with Linux generic GPIO API, or
+ * one of the errno value on the error condition.
+ */
+extern int of_get_gpio(struct device_node *np, int index);
+
 /*
  * NB:  This is here while we transition from using asm/prom.h
  * to linux/of.h
-- 
1.5.2.2

^ permalink raw reply related

* Re: [PATCH -mm 18/43] powerpc compat_binfmt_elf
From: Sam Ravnborg @ 2007-12-21 20:00 UTC (permalink / raw)
  To: Kyle McMartin
  Cc: linux-arch, linux-kernel, Christoph Hellwig, linuxppc-dev,
	Paul Mackerras, Andrew Morton, Linus Torvalds, Roland McGrath
In-Reply-To: <20071221175106.GB17656@fattire.cabal.ca>

On Fri, Dec 21, 2007 at 12:51:06PM -0500, Kyle McMartin wrote:
> On Fri, Dec 21, 2007 at 12:56:09AM -0800, Roland McGrath wrote:
> > > On Thu, Dec 20, 2007 at 03:58:16AM -0800, Roland McGrath wrote:
> > > > +obj-$(CONFIG_PPC64)		+= ../../../fs/compat_binfmt_elf.o
> > > 
> > > Building files from another directory is nasty.  Please add a
> > > CONFIG_BINFMT_COMPAT_ELF so we can simply build it in fs/
> > 
> > If that's better, please post the precise Kconfig magic you have in mind to
> > have it set when it should be.
Kyle made a proposal but I like to get in to the party too...

> > 
> 
> Just taking a stab that hch means,
> 
> config BINFMT_COMPAT_ELF
> 	def_bool n
> 	depends on 64BIT
> 
> and then in arch/powerpc/Kconfig
> 
> config COMPAT
> 	bool
> 	default y if PPC64
> 	select BINFMT_COMPAT_ELF
> 
> or somesuch.

We recently discussed a common prefix for the selctable symbols
and consensus pointed out "HAVE_" so let us try to use it.
I did not quite understand the "depends on 64BIT" in Kyles example.
Does we really want to use compat_binfmt_elf for all archs that
define 64BIT? Anyway I added this in the example below.

fs/Makefile:
obj-$(COMPAT_BINFMT_ELF) += compat_binfmt_elf.o

fs/Kconfig:
config COMPAT_BINFMT_ELF
	depends on HAVE_COMPAT_BINFMT_ELF || 64BIT

# COMPAT_BINFMT_ELF must be selected when an
# architecture supoorts ...
config HAVE_COMPAT_BINFMT_ELF


arch/powerpc/Kconfig:

config COMPAT
	bool
	default PPC64
	select HAVE_COMPAT_BINFMT_ELF


In the example above the extra indirection:
HAVE_COMPAT_BINFMT_ELF => COMPAT_BNFMT_ELF is not really needed
but tomorrow when we add another "depends on" to COMPAT_INFMT_ELF
it is needed to avoid the misbehaving select that just ignore the
dependencies and select the symbol anyway.

	Sam

^ permalink raw reply

* [PATCH 0/4] PowerPC: implement GPIO API
From: Anton Vorontsov @ 2007-12-21 20:28 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev

Hi all,

OF device tree GPIOs bindings are similar to IRQs:

pario0: gpio-controller@0 {
	#gpio-cells = <2>;
	num-ports = <7>;
};

device@0 {
	gpios = <bank pin bank pin bank pin>;
	gpio-parent = <&pario0>;
};

"bank pin" scheme is controller specific, so controllers that want
to implement flat mappings or any other could do so.

So far I implemented GPIO API for QE and CPM2 chips. GPIO API for
CPM1 implemented by Jochen Friedrich <jochen@scram.de>, included in
this patchset.

- QE GPIO API tested to work with FSL UPM NAND driver and
  MPC8360E-RDK (STMicro NAND512W3A2BN6E);
- CPM2 GPIO API tested to work with MPC8555E+Samsung HY27UF081G6 (LP);
- CPM1 GPIO API untested.

GPIO API is described in Documentation/gpio.txt, and these
patches are tend to support most of it.

As an additional bonus, PowerPC now gets access to few pleasing
drivers:

- drivers/leds/leds-gpio.c (we could use it to play with
  on-board LEDs);
- drivers/i2c/busses/i2c-gpio.c (generic I2C bit-banging driver);
- drivers/input/keyboard/gpio_keys.c - gpio keys (requires
  gpio_to_irq, so far not implemented);
- Could be more (I named the ones I knew about).

Also, in the upcoming kernels, there will be GPIOLIB[1] addition to
the generic GPIO API, to support off-chip GPIO expanders (like MFDs
on I2C/LBC). But so far we support on-chip GPIOs only, with single
controller built-in.

Changes since RFC:
- Implemented #gpio-cells handling;
- Per-bank spinlocks removed;
- Added a patch which implements GPIO API for CPM1;
- Few minor fixes.

Thanks,

[1] http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.24-rc4/2.6.24-rc4-mm1/broken-out/generic-gpio-gpio_chip-support.patch

-- 
Anton Vorontsov
email: cbou@mail.ru
backup email: ya-cbou@yandex.ru
irc://irc.freenode.net/bd2

^ permalink raw reply

* [PATCH] [POWERPC] MPC8360E-RDK: Device tree and board file
From: Anton Vorontsov @ 2007-12-21 20:23 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev

This is new board made by Freescale Semiconductor Inc. and
Logic Product Development.

Currently supported:
1. UEC1,2,7,4
2. I2C
3. SPI
4. NS16550 serial
5. PCI and miniPCI
6. Intel NOR StrataFlash X16 64Mbit PC28F640P30T85

Not supported so far:
1. StMICRO NAND512W3A2BN6E, 512 Mbit (supported with FSL UPM patches)
2. QE SCCs (slow UCCs, used as an UARTs)
3. ADC AD7843
4. FHCI USB
5. Graphics controller, Fujitsu MB86277

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 arch/powerpc/boot/dts/mpc836x_rdk.dts     |  331 +++++++++++++++++++++++++++++
 arch/powerpc/platforms/83xx/Kconfig       |   11 +-
 arch/powerpc/platforms/83xx/Makefile      |    1 +
 arch/powerpc/platforms/83xx/mpc836x_rdk.c |  118 ++++++++++
 4 files changed, 460 insertions(+), 1 deletions(-)
 create mode 100644 arch/powerpc/boot/dts/mpc836x_rdk.dts
 create mode 100644 arch/powerpc/platforms/83xx/mpc836x_rdk.c

diff --git a/arch/powerpc/boot/dts/mpc836x_rdk.dts b/arch/powerpc/boot/dts/mpc836x_rdk.dts
new file mode 100644
index 0000000..3f8d2b0
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc836x_rdk.dts
@@ -0,0 +1,331 @@
+/*
+ * MPC8360E RDK Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ * Copyright 2007 MontaVista Software, Inc.
+ * 		  Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * 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.
+ */
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "MPC8360ERDK", "MPC836xRDK", "MPC83xxRDK";
+	model = "MPC8360RDK";
+
+	aliases {
+		serial0 = &serial0;
+		serial1 = &serial1;
+		ethernet0 = &enet0;
+		ethernet1 = &enet1;
+		ethernet2 = &enet2;
+		ethernet3 = &enet3;
+		pci0 = &pci0;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,8360@0 {
+			device_type = "cpu";
+			reg = <0>;
+			d-cache-line-size = <32>;
+			i-cache-line-size = <32>;
+			d-cache-size = <32768>;
+			i-cache-size = <32768>;
+			/* filled by u-boot */
+			timebase-frequency = <0>; 
+			bus-frequency = <0>;
+			clock-frequency = <0>;
+		};
+	};
+
+	soc8360@e0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		device_type = "soc";
+		ranges = <0 0xe0000000 0x00100000>;
+		reg = <0xe0000000 0x00000200>;
+		/* filled by u-boot */
+		bus-frequency = <0>;
+
+		wdt@200 {
+			compatible = "mpc83xx_wdt";
+			reg = <0x200 0x100>;
+		};
+
+		i2c@3000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <0>;
+			compatible = "fsl-i2c";
+			reg = <0x3000 0x100>;
+			interrupts = <14 8>;
+			interrupt-parent = <&ipic>;
+			dfsrr;
+		};
+
+		i2c@3100 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <1>;
+			compatible = "fsl-i2c";
+			reg = <0x3100 0x100>;
+			interrupts = <16 8>;
+			interrupt-parent = <&ipic>;
+			dfsrr;
+		};
+
+		serial0: serial@4500 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4500 0x100>;
+			interrupts = <9 8>;
+			interrupt-parent = <&ipic>;
+			/* filled by u-boot */
+			clock-frequency = <0>;
+		};
+
+		serial1: serial@4600 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4600 0x100>;
+			interrupts = <10 8>;
+			interrupt-parent = <&ipic>;
+			/* filled by u-boot */
+			clock-frequency = <0>;
+		};
+
+		crypto@30000 {
+			compatible = "fsl,sec2-crypto";
+			reg = <0x30000 0x10000>;
+			interrupts = <11 8>;
+			interrupt-parent = <&ipic>;
+			num-channels = <4>;
+			channel-fifo-len = <24>;
+			exec-units-mask = <0x0000007e>;
+			/*
+			 * desc mask is for rev1.x, we need runtime fixup
+			 * for >=2.x
+			 */
+			descriptor-types-mask = <0x01010ebf>;
+		};
+
+		ipic: interrupt-controller@700 {
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			compatible = "fsl,pq2pro-pic", "fsl,ipic";
+			interrupt-controller;
+			reg = <0x700 0x100>;
+		};
+
+		par_io@1400 {
+			compatible = "fsl,qe-pario";
+			reg = <0x1400 0x100>;
+			num-ports = <7>;
+		};
+	};
+
+	qe@e0100000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "fsl,qe";
+		ranges = <0 0xe0100000 0x00100000>;
+		reg = <0xe0100000 0x480>;
+		/* filled by u-boot */
+		brg-frequency = <0>;
+
+		muram@10000 {
+			compatible = "fsl,qe-muram", "fsl,cpm-muram";
+			ranges = <0 0x00010000 0x0000c000>;
+
+			data-only@0 {
+				compatible = "fsl,qe-muram-data",
+					     "fsl,cpm-muram-data";
+				reg = <0 0xc000>;
+			};
+		};
+
+		spi@4c0 {
+			cell-index = <0>;
+			compatible = "fsl,spi";
+			reg = <0x4c0 0x40>;
+			interrupts = <2>;
+			interrupt-parent = <&qeic>;
+			mode = "cpu-qe";
+		};
+
+		spi@500 {
+			cell-index = <1>;
+			compatible = "fsl,spi";
+			reg = <0x500 0x40>;
+			interrupts = <1>;
+			interrupt-parent = <&qeic>;
+			mode = "cpu-qe";
+		};
+
+		usb@6c0 {
+			compatible = "qe_udc";
+			reg = <0x6c0 0x40 0x8b00 0x100>;
+			interrupts = <11>;
+			interrupt-parent = <&qeic>;
+			mode = "slave";
+		};
+
+		enet0: ucc@2000 {
+			device_type = "network";
+			compatible = "ucc_geth";
+			model = "UCC";
+			device-id = <1>;
+			reg = <0x2000 0x200>;
+			interrupts = <32>;
+			interrupt-parent = <&qeic>;
+			rx-clock = <0>;
+			tx-clock = <25>;
+			phy-handle = <&phy2>;
+			phy-connection-type = "rgmii-id";
+			/* filled by u-boot */
+			local-mac-address = [ 00 00 00 00 00 00 ];
+		};
+
+		enet1: ucc@3000 {
+			device_type = "network";
+			compatible = "ucc_geth";
+			model = "UCC";
+			device-id = <2>;
+			reg = <0x3000 0x200>;
+			interrupts = <33>;
+			interrupt-parent = <&qeic>;
+			rx-clock = <0>;
+			tx-clock = <20>;
+			phy-handle = <&phy4>;
+			phy-connection-type = "rgmii-id";
+			/* filled by u-boot */
+			local-mac-address = [ 00 00 00 00 00 00 ];
+		};
+
+		enet2: ucc@2600 {
+			device_type = "network";
+			compatible = "ucc_geth";
+			model = "UCC";
+			device-id = <7>;
+			reg = <0x2600 0x200>;
+			interrupts = <34>;
+			interrupt-parent = <&qeic>;
+			rx-clock = <36>;
+			tx-clock = <35>;
+			phy-handle = <&phy1>;
+			phy-connection-type = "mii";
+			/* filled by u-boot */
+			local-mac-address = [ 00 00 00 00 00 00 ];
+		};
+
+		enet3: ucc@3200 {
+			device_type = "network";
+			compatible = "ucc_geth";
+			model = "UCC";
+			device-id = <4>;
+			reg = <0x3200 0x200>;
+			interrupts = <35>;
+			interrupt-parent = <&qeic>;
+			rx-clock = <24>;
+			tx-clock = <23>;
+			phy-handle = <&phy3>;
+			phy-connection-type = "mii";
+			/* filled by u-boot */
+			local-mac-address = [ 00 00 00 00 00 00 ];
+		};
+
+		mdio@2120 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x2120 0x18>;
+			compatible = "fsl,ucc-mdio";
+
+			phy1: ethernet-phy@1 {
+				compatible = "national,DP83848VV";
+				reg = <1>;
+				device_type = "ethernet-phy";
+			};
+
+			phy2: ethernet-phy@2 {
+				compatible = "broadcom,BCM5481UA2KMLG";
+				reg = <2>;
+				device_type = "ethernet-phy";
+			};
+
+			phy3: ethernet-phy@3 {
+				compatible = "national,DP83848VV";
+				reg = <3>;
+				device_type = "ethernet-phy";
+			};
+
+			phy4: ethernet-phy@4 {
+				compatible = "broadcom,BCM5481UA2KMLG";
+				reg = <4>;
+				device_type = "ethernet-phy";
+			};
+		};
+
+		qeic: interrupt-controller@80 {
+			#address-cells = <0>;
+			#interrupt-cells = <1>;
+			compatible = "fsl,qe-pic";
+			interrupt-controller;
+			reg = <0x80 0x80>;
+			big-endian;
+			interrupts = <32 8 33 8>;
+			interrupt-parent = <&ipic>;
+		};
+	};
+
+	localbus@e0005000 {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		compatible = "fsl,mpc8360-localbus",
+			     "fsl,pq2pro-localbus";
+		reg = <0xe0005000 0xd8>;
+		ranges = <0 0 0xff800000 0x800000>;
+
+		nor-flash@0,0 {
+			compatible = "intel,PC28F640P30T85", "cfi-flash";
+			reg = <0 0 0x800000>;
+			bank-width = <2>;
+			device-width = <1>;
+		};
+	};
+
+	pci0: pci@e0008500 {
+		#address-cells = <3>;
+		#size-cells = <2>;
+		#interrupt-cells = <1>;
+		device_type = "pci";
+		compatible = "fsl,mpc8360-pci", "fsl,mpc8349-pci";
+		reg = <0xe0008500 0x100>;
+		ranges = <0x02000000 0 0x90000000 0x90000000 0 0x10000000
+			  0x42000000 0 0x80000000 0x80000000 0 0x10000000
+			  0x01000000 0 0xe0300000 0xe0300000 0 0x00100000>;
+		interrupts = <66 8>;
+		interrupt-parent = <&ipic>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = </* miniPCI0 IDSEL 0x14 AD20 */
+				 0xa000 0 0 1 &ipic 18 8
+				 0xa000 0 0 2 &ipic 19 8
+
+				 /* PCI1 IDSEL 0x15 AD21 */
+				 0xa800 0 0 1 &ipic 19 8
+				 0xa800 0 0 2 &ipic 20 8
+				 0xa800 0 0 3 &ipic 21 8
+				 0xa800 0 0 4 &ipic 18 8>;
+		/* filled by u-boot */
+		bus-range = <0 0>;
+		clock-frequency = <0>;
+	};
+};
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 2430ac8..0d5a87c 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -55,6 +55,15 @@ config MPC837x_MDS
 	select DEFAULT_UIMAGE
 	help
 	  This option enables support for the MPC837x MDS Processor Board.
+
+config MPC836x_RDK
+	bool "Freescale/Logic MPC836x RDK"
+	select DEFAULT_UIMAGE
+	select QUICC_ENGINE
+	help
+	  This option enables support for the MPC836x RDK Processor Board,
+	  also known as ZOOM PowerQUICC Kit.
+
 endchoice
 
 config PPC_MPC831x
@@ -79,7 +88,7 @@ config PPC_MPC836x
 	bool
 	select PPC_UDBG_16550
 	select PPC_INDIRECT_PCI
-	default y if MPC836x_MDS
+	default y if MPC836x_MDS || MPC836x_RDK
 
 config PPC_MPC837x
 	bool
diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile
index df46629..bf1b799 100644
--- a/arch/powerpc/platforms/83xx/Makefile
+++ b/arch/powerpc/platforms/83xx/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_MPC834x_ITX)	+= mpc834x_itx.o
 obj-$(CONFIG_MPC836x_MDS)	+= mpc836x_mds.o
 obj-$(CONFIG_MPC832x_MDS)	+= mpc832x_mds.o
 obj-$(CONFIG_MPC837x_MDS)	+= mpc837x_mds.o
+obj-$(CONFIG_MPC836x_RDK)	+= mpc836x_rdk.o
diff --git a/arch/powerpc/platforms/83xx/mpc836x_rdk.c b/arch/powerpc/platforms/83xx/mpc836x_rdk.c
new file mode 100644
index 0000000..999cfa2
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/mpc836x_rdk.c
@@ -0,0 +1,118 @@
+/*
+ * MPC8360E-RDK board file.
+ *
+ * Copyright (c) 2006  Freescale Semicondutor, Inc.
+ * Copyright (c) 2007  MontaVista Software, Inc.
+ * 		       Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/of_platform.h>
+#include <asm/prom.h>
+#include <asm/time.h>
+#include <asm/ipic.h>
+#include <asm/udbg.h>
+#include <asm/io.h>
+#include <asm/qe.h>
+#include <asm/qe_ic.h>
+#include <sysdev/fsl_soc.h>
+
+#include "mpc83xx.h"
+
+static struct of_device_id mpc836x_rdk_ids[] = {
+	{ .compatible = "soc", },
+	{ .compatible = "fsl,qe", },
+	{ .compatible = "fsl,pq2pro-localbus", },
+	{},
+};
+
+static int __init mpc836x_rdk_declare_of_platform_devices(void)
+{
+	if (!machine_is(mpc836x_rdk))
+		return 0;
+
+	of_platform_bus_probe(NULL, mpc836x_rdk_ids, NULL);
+
+	return 0;
+}
+device_initcall(mpc836x_rdk_declare_of_platform_devices);
+
+static void __init mpc836x_rdk_setup_arch(void)
+{
+	struct device_node *np;
+
+	if (ppc_md.progress)
+		ppc_md.progress("mpc836x_rdk_setup_arch()", 0);
+
+#ifdef CONFIG_PCI
+	for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
+		mpc83xx_add_bridge(np);
+#endif
+
+#ifdef CONFIG_QUICC_ENGINE
+	qe_reset();
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,qe-pario");
+	if (np) {
+		par_io_init(np);
+		of_node_put(np);
+	} else {
+		pr_warning("QE PIO not initialized!\n");
+	}
+#endif
+}
+
+static void __init mpc836x_rdk_init_IRQ(void)
+{
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, "fsl,ipic");
+	if (!np)
+		return;
+
+	ipic_init(np, 0);
+
+	/*
+	 * Initialize the default interrupt mapping priorities,
+	 * in case the boot rom changed something on us.
+	 */
+	ipic_set_default_priority();
+	of_node_put(np);
+
+#ifdef CONFIG_QUICC_ENGINE
+	np = of_find_compatible_node(NULL, NULL, "fsl,qe-pic");
+	if (!np)
+		return;
+
+	qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic);
+	of_node_put(np);
+#endif
+}
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened.
+ */
+static int __init mpc836x_rdk_probe(void)
+{
+	unsigned long root = of_get_flat_dt_root();
+
+	return of_flat_dt_is_compatible(root, "MPC836xRDK");
+}
+
+define_machine(mpc836x_rdk) {
+	.name		= "MPC836x RDK",
+	.probe		= mpc836x_rdk_probe,
+	.setup_arch	= mpc836x_rdk_setup_arch,
+	.init_IRQ	= mpc836x_rdk_init_IRQ,
+	.get_irq	= ipic_get_irq,
+	.restart	= mpc83xx_restart,
+	.time_init	= mpc83xx_time_init,
+	.calibrate_decr	= generic_calibrate_decr,
+	.progress	= udbg_progress,
+};
-- 
1.5.2.2

^ permalink raw reply related

* [PATCH 4/4] [POWERPC] fsl_spi_init and users: stop using device_type = "spi"
From: Anton Vorontsov @ 2007-12-21 20:21 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <20071221201844.GA4278@localhost.localdomain>

Also:
- rename "fsl_spi" to "fsl,spi";
- add and use cell-index property, if found;
- split probing code out of fsl_spi_init, thus we can call
  it for legacy device_type probing and new "compatible" probing.

Per http://ozlabs.org/pipermail/linuxppc-dev/2007-December/048388.html

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 arch/powerpc/boot/dts/mpc8313erdb.dts    |    4 +-
 arch/powerpc/boot/dts/mpc832x_mds.dts    |    8 ++--
 arch/powerpc/boot/dts/mpc832x_rdb.dts    |    8 ++--
 arch/powerpc/boot/dts/mpc8349emitx.dts   |    4 +-
 arch/powerpc/boot/dts/mpc8349emitxgp.dts |    4 +-
 arch/powerpc/boot/dts/mpc834x_mds.dts    |    4 +-
 arch/powerpc/boot/dts/mpc836x_mds.dts    |    8 ++--
 arch/powerpc/boot/dts/mpc8568mds.dts     |    8 ++--
 arch/powerpc/sysdev/fsl_soc.c            |   87 ++++++++++++++++++-----------
 9 files changed, 78 insertions(+), 57 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc8313erdb.dts b/arch/powerpc/boot/dts/mpc8313erdb.dts
index c5b6665..a0492b6 100644
--- a/arch/powerpc/boot/dts/mpc8313erdb.dts
+++ b/arch/powerpc/boot/dts/mpc8313erdb.dts
@@ -82,8 +82,8 @@
 		};
 
 		spi@7000 {
-			device_type = "spi";
-			compatible = "fsl_spi";
+			cell-index = <0>;
+			compatible = "fsl,spi";
 			reg = <7000 1000>;
 			interrupts = <10 8>;
 			interrupt-parent = < &ipic >;
diff --git a/arch/powerpc/boot/dts/mpc832x_mds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts
index 8844d30..36ecd39 100644
--- a/arch/powerpc/boot/dts/mpc832x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc832x_mds.dts
@@ -193,8 +193,8 @@
 		};
 
 		spi@4c0 {
-			device_type = "spi";
-			compatible = "fsl_spi";
+			cell-index = <0>;
+			compatible = "fsl,spi";
 			reg = <4c0 40>;
 			interrupts = <2>;
 			interrupt-parent = < &qeic >;
@@ -202,8 +202,8 @@
 		};
 
 		spi@500 {
-			device_type = "spi";
-			compatible = "fsl_spi";
+			cell-index = <1>;
+			compatible = "fsl,spi";
 			reg = <500 40>;
 			interrupts = <1>;
 			interrupt-parent = < &qeic >;
diff --git a/arch/powerpc/boot/dts/mpc832x_rdb.dts b/arch/powerpc/boot/dts/mpc832x_rdb.dts
index a7a2e45..ce63b13 100644
--- a/arch/powerpc/boot/dts/mpc832x_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts
@@ -183,8 +183,8 @@
 		};
 
 		spi@4c0 {
-			device_type = "spi";
-			compatible = "fsl_spi";
+			cell-index = <0>;
+			compatible = "fsl,spi";
 			reg = <4c0 40>;
 			interrupts = <2>;
 			interrupt-parent = <&qeic>;
@@ -192,8 +192,8 @@
 		};
 
 		spi@500 {
-			device_type = "spi";
-			compatible = "fsl_spi";
+			cell-index = <1>;
+			compatible = "fsl,spi";
 			reg = <500 40>;
 			interrupts = <1>;
 			interrupt-parent = <&qeic>;
diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts
index e354f26..f8fc5f6 100644
--- a/arch/powerpc/boot/dts/mpc8349emitx.dts
+++ b/arch/powerpc/boot/dts/mpc8349emitx.dts
@@ -82,8 +82,8 @@
 		};
 
 		spi@7000 {
-			device_type = "spi";
-			compatible = "fsl_spi";
+			cell-index = <0>;
+			compatible = "fsl,spi";
 			reg = <7000 1000>;
 			interrupts = <10 8>;
 			interrupt-parent = < &ipic >;
diff --git a/arch/powerpc/boot/dts/mpc8349emitxgp.dts b/arch/powerpc/boot/dts/mpc8349emitxgp.dts
index ebdf0b7..666650c 100644
--- a/arch/powerpc/boot/dts/mpc8349emitxgp.dts
+++ b/arch/powerpc/boot/dts/mpc8349emitxgp.dts
@@ -80,8 +80,8 @@
 		};
 
 		spi@7000 {
-			device_type = "spi";
-			compatible = "fsl_spi";
+			cell-index = <0>;
+			compatible = "fsl,spi";
 			reg = <7000 1000>;
 			interrupts = <10 8>;
 			interrupt-parent = < &ipic >;
diff --git a/arch/powerpc/boot/dts/mpc834x_mds.dts b/arch/powerpc/boot/dts/mpc834x_mds.dts
index 0ba13eb..6ed36a1 100644
--- a/arch/powerpc/boot/dts/mpc834x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc834x_mds.dts
@@ -93,8 +93,8 @@
 		};
 
 		spi@7000 {
-			device_type = "spi";
-			compatible = "fsl_spi";
+			cell-index = <0>;
+			compatible = "fsl,spi";
 			reg = <7000 1000>;
 			interrupts = <10 8>;
 			interrupt-parent = < &ipic >;
diff --git a/arch/powerpc/boot/dts/mpc836x_mds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts
index 5f0b427..7801e66 100644
--- a/arch/powerpc/boot/dts/mpc836x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc836x_mds.dts
@@ -224,8 +224,8 @@
 		};
 
 		spi@4c0 {
-			device_type = "spi";
-			compatible = "fsl_spi";
+			cell-index = <0>;
+			compatible = "fsl,spi";
 			reg = <4c0 40>;
 			interrupts = <2>;
 			interrupt-parent = < &qeic >;
@@ -233,8 +233,8 @@
 		};
 
 		spi@500 {
-			device_type = "spi";
-			compatible = "fsl_spi";
+			cell-index = <1>;
+			compatible = "fsl,spi";
 			reg = <500 40>;
 			interrupts = <1>;
 			interrupt-parent = < &qeic >;
diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts
index ea70010..2a0ba5f 100644
--- a/arch/powerpc/boot/dts/mpc8568mds.dts
+++ b/arch/powerpc/boot/dts/mpc8568mds.dts
@@ -301,8 +301,8 @@
 		};
 
 		spi@4c0 {
-			device_type = "spi";
-			compatible = "fsl_spi";
+			cell-index = <0>;
+			compatible = "fsl,spi";
 			reg = <4c0 40>;
 			interrupts = <2>;
 			interrupt-parent = <&qeic>;
@@ -310,8 +310,8 @@
 		};
 
 		spi@500 {
-			device_type = "spi";
-			compatible = "fsl_spi";
+			cell-index = <1>;
+			compatible = "fsl,spi";
 			reg = <500 40>;
 			interrupts = <1>;
 			interrupt-parent = <&qeic>;
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 746f4c5..5676a8a 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -1226,39 +1226,17 @@ arch_initcall(cpm_smc_uart_of_init);
 #endif /* CONFIG_8xx */
 #endif /* CONFIG_PPC_CPM_NEW_BINDING */
 
-int __init fsl_spi_init(struct spi_board_info *board_infos,
-			unsigned int num_board_infos,
-			void (*activate_cs)(u8 cs, u8 polarity),
-			void (*deactivate_cs)(u8 cs, u8 polarity))
+static int __init of_fsl_spi_probe(char *type, char *compatible, u32 sysclk,
+				   struct spi_board_info *board_infos,
+				   unsigned int num_board_infos,
+				   void (*activate_cs)(u8 cs, u8 polarity),
+				   void (*deactivate_cs)(u8 cs, u8 polarity))
 {
 	struct device_node *np;
-	unsigned int i;
-	u32 sysclk;
-
-	/* SPI controller is either clocked from QE or SoC clock */
-	sysclk = get_brgfreq();
-	if (sysclk == -1) {
-		const u32 *freq;
-		int size;
-
-		np = of_find_node_by_type(NULL, "soc");
-		if (!np)
-			return -ENODEV;
-
-		freq = of_get_property(np, "bus-frequency", &size);
-		if (!freq || size != sizeof(*freq)) {
-			of_node_put(np);
-			return -ENODEV;
-		}
-
-		sysclk = *freq;
-		of_node_put(np);
-	}
+	unsigned int i = 0;
 
-	for (np = NULL, i = 1;
-	     (np = of_find_compatible_node(np, "spi", "fsl_spi")) != NULL;
-	     i++) {
-		int ret = 0;
+	for_each_compatible_node(np, type, compatible) {
+		int ret;
 		unsigned int j;
 		const void *prop;
 		struct resource res[2];
@@ -1277,6 +1255,10 @@ int __init fsl_spi_init(struct spi_board_info *board_infos,
 			goto err;
 		pdata.bus_num = *(u32 *)prop;
 
+		prop = of_get_property(np, "cell-index", NULL);
+		if (prop)
+			i = *(u32 *)prop;
+
 		prop = of_get_property(np, "mode", NULL);
 		if (prop && !strcmp(prop, "cpu-qe"))
 			pdata.qe_mode = 1;
@@ -1287,7 +1269,7 @@ int __init fsl_spi_init(struct spi_board_info *board_infos,
 		}
 
 		if (!pdata.max_chipselect)
-			goto err;
+			continue;
 
 		ret = of_address_to_resource(np, 0, &res[0]);
 		if (ret)
@@ -1314,13 +1296,52 @@ int __init fsl_spi_init(struct spi_board_info *board_infos,
 		if (ret)
 			goto unreg;
 
-		continue;
+		goto next;
 unreg:
 		platform_device_del(pdev);
 err:
-		continue;
+		pr_err("%s: registration failed\n", np->full_name);
+next:
+		i++;
 	}
 
+	return i;
+}
+
+int __init fsl_spi_init(struct spi_board_info *board_infos,
+			unsigned int num_board_infos,
+			void (*activate_cs)(u8 cs, u8 polarity),
+			void (*deactivate_cs)(u8 cs, u8 polarity))
+{
+	u32 sysclk;
+	int ret;
+
+	/* SPI controller is either clocked from QE or SoC clock */
+	sysclk = get_brgfreq();
+	if (sysclk == -1) {
+		struct device_node *np;
+		const u32 *prop;
+
+		np = of_find_node_by_type(NULL, "soc");
+		if (!np)
+			return -ENODEV;
+
+		prop = of_get_property(np, "bus-frequency", NULL);
+		if (!prop) {
+			of_node_put(np);
+			return -ENODEV;
+		}
+
+		sysclk = *prop;
+		of_node_put(np);
+	}
+
+	ret = of_fsl_spi_probe(NULL, "fsl,spi", sysclk, board_infos,
+			       num_board_infos, activate_cs, deactivate_cs);
+	if (!ret)
+		of_fsl_spi_probe("spi", "fsl_spi", sysclk, board_infos,
+				 num_board_infos, activate_cs, deactivate_cs);
+
 	return spi_register_board_info(board_infos, num_board_infos);
 }
 
-- 
1.5.2.2

^ permalink raw reply related

* [PATCH 3/4] [POWERPC][SPI] use brg-frequency for SPI in QE
From: Anton Vorontsov @ 2007-12-21 20:21 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <20071221201844.GA4278@localhost.localdomain>

In case of QE we can use brg-frequency (which is qeclk/2).
Thus no need to divide sysclk in the spi_mpc83xx.

This patch also adds code to use get_brgfreq() on QE chips.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
---
 arch/powerpc/sysdev/fsl_soc.c |   39 +++++++++++++++++++++++++++------------
 drivers/spi/spi_mpc83xx.c     |    6 +-----
 2 files changed, 28 insertions(+), 17 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 60d9c4e..746f4c5 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -66,7 +66,7 @@ phys_addr_t get_immrbase(void)
 
 EXPORT_SYMBOL(get_immrbase);
 
-#if defined(CONFIG_CPM2) || defined(CONFIG_8xx)
+#if defined(CONFIG_CPM2) || defined(CONFIG_QUICC_ENGINE) || defined(CONFIG_8xx)
 
 static u32 brgfreq = -1;
 
@@ -91,11 +91,21 @@ u32 get_brgfreq(void)
 
 	/* Legacy device binding -- will go away when no users are left. */
 	node = of_find_node_by_type(NULL, "cpm");
+	if (!node)
+		node = of_find_compatible_node(NULL, NULL, "fsl,qe");
+	if (!node)
+		node = of_find_node_by_type(NULL, "qe");
+
 	if (node) {
 		prop = of_get_property(node, "brg-frequency", &size);
 		if (prop && size == 4)
 			brgfreq = *prop;
 
+		if (brgfreq == -1 || brgfreq == 0) {
+			prop = of_get_property(node, "bus-frequency", &size);
+			if (prop && size == 4)
+				brgfreq = *prop / 2;
+		}
 		of_node_put(node);
 	}
 
@@ -1223,22 +1233,27 @@ int __init fsl_spi_init(struct spi_board_info *board_infos,
 {
 	struct device_node *np;
 	unsigned int i;
-	const u32 *sysclk;
+	u32 sysclk;
 
 	/* SPI controller is either clocked from QE or SoC clock */
-	np = of_find_compatible_node(NULL, NULL, "fsl,qe");
-	if (!np)
-		np = of_find_node_by_type(NULL, "qe");
+	sysclk = get_brgfreq();
+	if (sysclk == -1) {
+		const u32 *freq;
+		int size;
 
-	if (!np)
 		np = of_find_node_by_type(NULL, "soc");
+		if (!np)
+			return -ENODEV;
 
-	if (!np)
-		return -ENODEV;
+		freq = of_get_property(np, "bus-frequency", &size);
+		if (!freq || size != sizeof(*freq)) {
+			of_node_put(np);
+			return -ENODEV;
+		}
 
-	sysclk = of_get_property(np, "bus-frequency", NULL);
-	if (!sysclk)
-		return -ENODEV;
+		sysclk = *freq;
+		of_node_put(np);
+	}
 
 	for (np = NULL, i = 1;
 	     (np = of_find_compatible_node(np, "spi", "fsl_spi")) != NULL;
@@ -1255,7 +1270,7 @@ int __init fsl_spi_init(struct spi_board_info *board_infos,
 
 		memset(res, 0, sizeof(res));
 
-		pdata.sysclk = *sysclk;
+		pdata.sysclk = sysclk;
 
 		prop = of_get_property(np, "reg", NULL);
 		if (!prop)
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index 4580b9c..04f7cd9 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -436,11 +436,7 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)
 	mpc83xx_spi->qe_mode = pdata->qe_mode;
 	mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8;
 	mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8;
-
-	if (mpc83xx_spi->qe_mode)
-		mpc83xx_spi->spibrg = pdata->sysclk / 2;
-	else
-		mpc83xx_spi->spibrg = pdata->sysclk;
+	mpc83xx_spi->spibrg = pdata->sysclk;
 
 	mpc83xx_spi->rx_shift = 0;
 	mpc83xx_spi->tx_shift = 0;
-- 
1.5.2.2

^ permalink raw reply related

* [PATCH 2/4] [POWERPC][NET] ucc_geth_mii and users: get rid of device_type
From: Anton Vorontsov @ 2007-12-21 20:20 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <20071221201844.GA4278@localhost.localdomain>

device_type property is bogus, thus use proper compatible.

Also change compatible property to "fsl,ucc-mdio".

Per http://ozlabs.org/pipermail/linuxppc-dev/2007-December/048388.html

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 arch/powerpc/boot/dts/mpc832x_mds.dts |    3 +--
 arch/powerpc/boot/dts/mpc832x_rdb.dts |    3 +--
 arch/powerpc/boot/dts/mpc836x_mds.dts |    3 +--
 arch/powerpc/boot/dts/mpc8568mds.dts  |    2 +-
 drivers/net/ucc_geth_mii.c            |    3 +++
 5 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc832x_mds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts
index 588d658..8844d30 100644
--- a/arch/powerpc/boot/dts/mpc832x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc832x_mds.dts
@@ -255,8 +255,7 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <2320 18>;
-			device_type = "mdio";
-			compatible = "ucc_geth_phy";
+			compatible = "fsl,ucc-mdio";
 
 			phy3: ethernet-phy@03 {
 				interrupt-parent = < &ipic >;
diff --git a/arch/powerpc/boot/dts/mpc832x_rdb.dts b/arch/powerpc/boot/dts/mpc832x_rdb.dts
index 719f375..a7a2e45 100644
--- a/arch/powerpc/boot/dts/mpc832x_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts
@@ -236,8 +236,7 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <3120 18>;
-			device_type = "mdio";
-			compatible = "ucc_geth_phy";
+			compatible = "fsl,ucc-mdio";
 
 			phy00:ethernet-phy@00 {
 				interrupt-parent = <&pic>;
diff --git a/arch/powerpc/boot/dts/mpc836x_mds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts
index 8d7124e..5f0b427 100644
--- a/arch/powerpc/boot/dts/mpc836x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc836x_mds.dts
@@ -288,8 +288,7 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <2120 18>;
-			device_type = "mdio";
-			compatible = "ucc_geth_phy";
+			compatible = "fsl,ucc-mdio";
 
 			phy0: ethernet-phy@00 {
 				interrupt-parent = < &ipic >;
diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts
index 89add8d..ea70010 100644
--- a/arch/powerpc/boot/dts/mpc8568mds.dts
+++ b/arch/powerpc/boot/dts/mpc8568mds.dts
@@ -356,7 +356,7 @@
 			#address-cells = <1>;
 			#size-cells = <0>;
 			reg = <2120 18>;
-			compatible = "ucc_geth_phy";
+			compatible = "fsl,ucc-mdio";
 
 			/* These are the same PHYs as on
 			 * gianfar's MDIO bus */
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c
index df884f0..e3ba14a 100644
--- a/drivers/net/ucc_geth_mii.c
+++ b/drivers/net/ucc_geth_mii.c
@@ -256,6 +256,9 @@ static struct of_device_id uec_mdio_match[] = {
 		.type = "mdio",
 		.compatible = "ucc_geth_phy",
 	},
+	{
+		.compatible = "fsl,ucc-mdio",
+	},
 	{},
 };
 
-- 
1.5.2.2

^ permalink raw reply related

* [PATCH 1/4] [POWERPC] qe_lib and users: get rid of device_type and model
From: Anton Vorontsov @ 2007-12-21 20:20 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <20071221201844.GA4278@localhost.localdomain>

Now we're searching for "fsl,qe", "fsl,qe-muram", "fsl,qe-muram-data".

Per http://ozlabs.org/pipermail/linuxppc-dev/2007-December/048388.html

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 arch/powerpc/boot/dts/mpc832x_mds.dts     |    7 ++++---
 arch/powerpc/boot/dts/mpc832x_rdb.dts     |    7 ++++---
 arch/powerpc/boot/dts/mpc836x_mds.dts     |    7 ++++---
 arch/powerpc/boot/dts/mpc8568mds.dts      |    7 ++++---
 arch/powerpc/platforms/83xx/mpc832x_mds.c |    1 +
 arch/powerpc/platforms/83xx/mpc832x_rdb.c |    1 +
 arch/powerpc/platforms/83xx/mpc836x_mds.c |    1 +
 arch/powerpc/platforms/85xx/mpc85xx_mds.c |    4 +++-
 arch/powerpc/sysdev/fsl_soc.c             |    5 ++++-
 arch/powerpc/sysdev/qe_lib/qe.c           |   16 +++++++++++++---
 10 files changed, 39 insertions(+), 17 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc832x_mds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts
index 26ac467..588d658 100644
--- a/arch/powerpc/boot/dts/mpc832x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc832x_mds.dts
@@ -175,18 +175,19 @@
 	qe@e0100000 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		device_type = "qe";
-		model = "QE";
+		compatible = "fsl,qe";
 		ranges = <0 e0100000 00100000>;
 		reg = <e0100000 480>;
 		brg-frequency = <0>;
 		bus-frequency = <BCD3D80>;
 
 		muram@10000 {
-			device_type = "muram";
+			compatible = "fsl,qe-muram", "fsl,cpm-muram";
 			ranges = <0 00010000 00004000>;
 
 			data-only@0 {
+				compatible = "fsl,qe-muram-data",
+					     "fsl,cpm-muram-data";
 				reg = <0 4000>;
 			};
 		};
diff --git a/arch/powerpc/boot/dts/mpc832x_rdb.dts b/arch/powerpc/boot/dts/mpc832x_rdb.dts
index 10ff7aa..719f375 100644
--- a/arch/powerpc/boot/dts/mpc832x_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts
@@ -165,18 +165,19 @@
 	qe@e0100000 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		device_type = "qe";
-		model = "QE";
+		compatible = "fsl,qe";
 		ranges = <0 e0100000 00100000>;
 		reg = <e0100000 480>;
 		brg-frequency = <0>;
 		bus-frequency = <BCD3D80>;
 
 		muram@10000 {
-			device_type = "muram";
+			compatible = "fsl,qe-muram", "fsl,cpm-muram";
 			ranges = <0 00010000 00004000>;
 
 			data-only@0 {
+				compatible = "fsl,qe-muram-data",
+					     "fsl,cpm-muram-data";
 				reg = <0 4000>;
 			};
 		};
diff --git a/arch/powerpc/boot/dts/mpc836x_mds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts
index fd841b2..8d7124e 100644
--- a/arch/powerpc/boot/dts/mpc836x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc836x_mds.dts
@@ -206,18 +206,19 @@
 	qe@e0100000 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		device_type = "qe";
-		model = "QE";
+		compatible = "fsl,qe";
 		ranges = <0 e0100000 00100000>;
 		reg = <e0100000 480>;
 		brg-frequency = <0>;
 		bus-frequency = <179A7B00>;
 
 		muram@10000 {
-			device_type = "muram";
+			device_type = "fsl,qe-muram", "fsl,cpm-muram";
 			ranges = <0 00010000 0000c000>;
 
 			data-only@0{
+				device_type = "fsl,qe-muram-data",
+					      "fsl,cpm-muram-data";
 				reg = <0 c000>;
 			};
 		};
diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts
index 5818a7c..89add8d 100644
--- a/arch/powerpc/boot/dts/mpc8568mds.dts
+++ b/arch/powerpc/boot/dts/mpc8568mds.dts
@@ -283,18 +283,19 @@
 	qe@e0080000 {
 		#address-cells = <1>;
 		#size-cells = <1>;
-		device_type = "qe";
-		model = "QE";
+		compatible = "fsl,qe";
 		ranges = <0 e0080000 00040000>;
 		reg = <e0080000 480>;
 		brg-frequency = <0>;
 		bus-frequency = <179A7B00>;
 
 		muram@10000 {
-			device_type = "muram";
+			compatible = "fsl,qe-muram", "fsl,cpm-muram";
 			ranges = <0 00010000 0000c000>;
 
 			data-only@0{
+				compatible = "fsl,qe-muram-data",
+					     "fsl,cpm-muram-data";
 				reg = <0 c000>;
 			};
 		};
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
index 1e570bb..516715e 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -105,6 +105,7 @@ static struct of_device_id mpc832x_ids[] = {
 	{ .type = "soc", },
 	{ .compatible = "soc", },
 	{ .type = "qe", },
+	{ .compatible = "fsl,qe", },
 	{},
 };
 
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index ffb2e93..a603def 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -118,6 +118,7 @@ static struct of_device_id mpc832x_ids[] = {
 	{ .type = "soc", },
 	{ .compatible = "soc", },
 	{ .type = "qe", },
+	{ .compatible = "fsl,qe", },
 	{},
 };
 
diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c
index 2ac9890..eb64cba 100644
--- a/arch/powerpc/platforms/83xx/mpc836x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c
@@ -136,6 +136,7 @@ static struct of_device_id mpc836x_ids[] = {
 	{ .type = "soc", },
 	{ .compatible = "soc", },
 	{ .type = "qe", },
+	{ .compatible = "fsl,qe", },
 	{},
 };
 
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index e6c63a5..a152bf8 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -94,7 +94,8 @@ static void __init mpc85xx_mds_setup_arch(void)
 #endif
 
 #ifdef CONFIG_QUICC_ENGINE
-	if ((np = of_find_node_by_name(NULL, "qe")) != NULL) {
+	np = of_find_node_by_name(NULL, "fsl,qe");
+	if (np) {
 		qe_reset();
 		of_node_put(np);
 	}
@@ -139,6 +140,7 @@ static struct of_device_id mpc85xx_ids[] = {
 	{ .type = "soc", },
 	{ .compatible = "soc", },
 	{ .type = "qe", },
+	{ .compatible = "fsl,qe", },
 	{},
 };
 
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 4baad80..60d9c4e 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -1226,7 +1226,10 @@ int __init fsl_spi_init(struct spi_board_info *board_infos,
 	const u32 *sysclk;
 
 	/* SPI controller is either clocked from QE or SoC clock */
-	np = of_find_node_by_type(NULL, "qe");
+	np = of_find_compatible_node(NULL, NULL, "fsl,qe");
+	if (!np)
+		np = of_find_node_by_type(NULL, "qe");
+
 	if (!np)
 		np = of_find_node_by_type(NULL, "soc");
 
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index 21e0106..cd6cee3 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -68,7 +68,10 @@ phys_addr_t get_qe_base(void)
 	if (qebase != -1)
 		return qebase;
 
-	qe = of_find_node_by_type(NULL, "qe");
+	qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
+	if (!qe)
+		qe = of_find_node_by_type(NULL, "qe");
+
 	if (qe) {
 		unsigned int size;
 		const void *prop = of_get_property(qe, "reg", &size);
@@ -155,7 +158,10 @@ unsigned int get_brg_clk(void)
 	if (brg_clk)
 		return brg_clk;
 
-	qe = of_find_node_by_type(NULL, "qe");
+	qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
+	if (!qe)
+		qe = of_find_node_by_type(NULL, "qe");
+
 	if (qe) {
 		unsigned int size;
 		const u32 *prop = of_get_property(qe, "brg-frequency", &size);
@@ -334,7 +340,11 @@ static void qe_muram_init(void)
 	/* XXX: This is a subset of the available muram. It
 	 * varies with the processor and the microcode patches activated.
 	 */
-	if ((np = of_find_node_by_name(NULL, "data-only")) != NULL) {
+	np = of_find_compatible_node(NULL, NULL, "fsl,qe-muram-data");
+	if (!np)
+		np = of_find_node_by_name(NULL, "data-only");
+
+	if (np) {
 		address = *of_get_address(np, 0, &size, &flags);
 		of_node_put(np);
 		rh_attach_region(&qe_muram_info, address, (int) size);
-- 
1.5.2.2

^ permalink raw reply related


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