LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v2] powerpc: don't enable cpu hotplug on mpic-based pseries
From: Olof Johansson @ 2007-10-11  5:59 UTC (permalink / raw)
  To: Paul Mackerras
  Cc: Stephen Rothwell, Greg KH, Greg KH, linux-kernel, Chris Wedgwood,
	linuxppc-dev, tgall.foo, Thomas Gleixner, Linus Torvalds, stable
In-Reply-To: <18189.47620.466515.645055@cargo.ozlabs.ibm.com>

On Thu, Oct 11, 2007 at 03:52:04PM +1000, Paul Mackerras wrote:
> Olof Johansson writes:
> 
> > Don't allow cpu hotplug on systems lacking XICS interrupt controller,
> > since current code is hardcoded for it.
> ...
> > +	for (np = NULL; (np = of_find_node_by_name(np,
> > +						   "interrupt-controller"));) {
> 
> Looks like for_each_node_by_name would be nicer here.
> 
> If you agree, I'll hand-edit your patch to do that and apply it.

Go for it, I just stole that out of the detection code. That
could be changed accordingly as well at some point (I'm guessing
for_each_node_by_name didn't exist when that was written).

> Of course, ultimately we should implement the necessary mpic bits to
> support cpu hotplug.

Yep. I'll leave that to people who have hardware access. :-)


Thanks,

-Olof

^ permalink raw reply

* Re: [PATCH v2] powerpc: don't enable cpu hotplug on mpic-based pseries
From: Paul Mackerras @ 2007-10-11  5:52 UTC (permalink / raw)
  To: Olof Johansson
  Cc: Stephen Rothwell, Greg KH, Greg KH, linux-kernel, Chris Wedgwood,
	linuxppc-dev, tgall.foo, Thomas Gleixner, Linus Torvalds, stable
In-Reply-To: <20071010003824.GA8477@lixom.net>

Olof Johansson writes:

> Don't allow cpu hotplug on systems lacking XICS interrupt controller,
> since current code is hardcoded for it.
...
> +	for (np = NULL; (np = of_find_node_by_name(np,
> +						   "interrupt-controller"));) {

Looks like for_each_node_by_name would be nicer here.

If you agree, I'll hand-edit your patch to do that and apply it.  Of
course, ultimately we should implement the necessary mpic bits to
support cpu hotplug.

Paul.

^ permalink raw reply

* Re: [PATCH 3/7] [POWERPC] remove iSeries_vio_dev
From: Olof Johansson @ 2007-10-11  5:55 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: ppc-dev, paulus, Jens Axboe
In-Reply-To: <20071011152949.4a78ec1b.sfr@canb.auug.org.au>

On Thu, Oct 11, 2007 at 03:29:49PM +1000, Stephen Rothwell wrote:
> Hi Olof,
> 
> On Thu, 11 Oct 2007 00:27:31 -0500 Olof Johansson <olof@lixom.net> wrote:
> >
> > Oh nevermind, I just noticed the variable got moved in the next
> > patch. Twice the review work!
> 
> Thanks for the review in any case.

No problem. It's hard to split up changes like that anyway, I don't
blame you.

Rest of the patches look good to me. I had another couple of comments
but they were fixed by the end of the series too. :-)


-Olof

^ permalink raw reply

* Re: [PATCH 3/7] [POWERPC] remove iSeries_vio_dev
From: Stephen Rothwell @ 2007-10-11  5:29 UTC (permalink / raw)
  To: Olof Johansson; +Cc: ppc-dev, paulus, Jens Axboe
In-Reply-To: <20071011052731.GB578@lixom.net>

[-- Attachment #1: Type: text/plain, Size: 337 bytes --]

Hi Olof,

On Thu, 11 Oct 2007 00:27:31 -0500 Olof Johansson <olof@lixom.net> wrote:
>
> Oh nevermind, I just noticed the variable got moved in the next
> patch. Twice the review work!

Thanks for the review in any case.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [PATCH] Device tree bindings for Xilinx devices
From: Grant Likely @ 2007-10-11  5:27 UTC (permalink / raw)
  To: Grant Likely, Josh Boyer, linuxppc-dev
In-Reply-To: <20071011050850.GI14873@localhost.localdomain>

On 10/10/07, David Gibson <dwg@au1.ibm.com> wrote:
> > My main concern is that I don't like the implicit numbering that
> > occurs simply based on the order of devices in the device tree.  If
> > the probe algorithm ever changes to parse in reverse order or
> > something reorders the tree, then the device numbers also change.  :-(
>
> Way of the future, apparently, everything's supposed to use udev to
> give things logical names.  No, I'm not thrilled at the prospect
> either.

...

So in the OF aliases approach, would udev need to read the aliases
node when assigning names to devices?

>
> > I'd rather be explicit.  In fact I've already been bitten by this
> > where the mpc5200 has 6 PSC, each of which can be configured as a
> > serial port.  However, I've got access to 3 different boards; each of
> > which has the logical port numbers 100% unrelated to the 'cell'
> > number.
>
> In any case, this can't really belong in a *device* binding.  Because
> the numbering has to cross devices of the same basic type, but
> different implementations.  Where "basic type" is based on how device
> names are allocated, and is thus inherently Linux specific.

Okay, that makes sense.

> > > Segher's suggestion of using OF-style aliases for this is a fairly
> > > good one, actually.  I just need to get to implementing it...
> >
> > /me needs to look up what that look like and how I would use it.  My
> > knowledge of OF is sadly lacking.
>
> Short version by example:
> / {
>         /* ... */
>         aliases {
>                 hd = "/pci@f0000000/sata@f4000000/....";
>                 enet0 = "/soc/ethernet@c000";
>                 enet1 = "/soc/ethernet@d000";
>                 enet2 = "/pci@f0000000/isa/ethernet@i480"
>                 ttya = "/soc/serial@e000";
>                 ttyb = "/pci/isa/serail@3f8";
>         }
> }

Ah, my plan worked...  I got you to teach me about OF aliases and I
have to do any work myself.  :-)

Hmm, yes that would provide the information nicely.  As long as the
data is in the tree, I'm pretty happy.

Cheers,
g.

>
> --
> David Gibson                    | I'll have my music baroque, and my code
> david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
>                                 | _way_ _around_!
> http://www.ozlabs.org/~dgibson
>


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

^ permalink raw reply

* Re: [PATCH] [POWERPC] move of_platform_driver initialisations: arch/powerpc
From: Olof Johansson @ 2007-10-11  5:30 UTC (permalink / raw)
  To: Stephen Rothwell
  Cc: Maxim Shchetynin, ppc-dev, paulus, Arnd Bergmann,
	Christian Krafft
In-Reply-To: <20071011151903.efa8fdb8.sfr@canb.auug.org.au>

On Thu, Oct 11, 2007 at 03:19:03PM +1000, Stephen Rothwell wrote:
> We no longer initialise the name and owner fields of the
> of_platform_driver, but use the fields of the embedded device_driver's
> name field instead.
> 
> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>

Acked-by: Olof Johansson <olof@lixom.net>


-Olof

^ permalink raw reply

* Re: [PATCH 3/7] [POWERPC] remove iSeries_vio_dev
From: Olof Johansson @ 2007-10-11  5:27 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: ppc-dev, paulus, Jens Axboe
In-Reply-To: <20071011052535.GA578@lixom.net>

On Thu, Oct 11, 2007 at 12:25:35AM -0500, Olof Johansson wrote:
> Hi Stephen,
> 
> > @@ -189,6 +191,34 @@ void iommu_devnode_init_iSeries(struct pci_dev *pdev, struct device_node *dn)
> >  }
> >  #endif
> >  
> > +extern struct iommu_table vio_iommu_table;
> 
> This looks like it really should go in a header file
> instead. include/asm-powerpc/vio.h perhaps?

Oh nevermind, I just noticed the variable got moved in the next
patch. Twice the review work!


-Olof

^ permalink raw reply

* Re: [PATCH 3/7] [POWERPC] remove iSeries_vio_dev
From: Olof Johansson @ 2007-10-11  5:25 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: ppc-dev, paulus, Jens Axboe
In-Reply-To: <20071011145332.e3638c2e.sfr@canb.auug.org.au>

Hi Stephen,

On Thu, Oct 11, 2007 at 02:53:32PM +1000, Stephen Rothwell wrote:
> It was only being used to carry around dma_iommu_ops and vio_iommu_table
> which we can use directly instead.  This also means that vio_bus_device
> doesn't need to refer to them either.
> 
> diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
> index fd631d4..eaf7f69 100644
> --- a/arch/powerpc/kernel/vio.c
> +++ b/arch/powerpc/kernel/vio.c
> @@ -49,11 +49,8 @@ static struct vio_dev vio_bus_device  = { /* fake "parent" device */
>  };
>  
>  #ifdef CONFIG_PPC_ISERIES
> -struct device *iSeries_vio_dev = &vio_bus_device.dev;
> -EXPORT_SYMBOL(iSeries_vio_dev);
> -
>  static struct iommu_table veth_iommu_table;
> -static struct iommu_table vio_iommu_table;
> +struct iommu_table vio_iommu_table;
>  
>  static void __init iommu_vio_init(void)
>  {
> @@ -66,8 +63,6 @@ static void __init iommu_vio_init(void)
>  		printk("Virtual Bus VETH TCE table failed.\n");
>  	if (!iommu_init_table(&vio_iommu_table, -1))
>  		printk("Virtual Bus VIO TCE table failed.\n");
> -	vio_bus_device.dev.archdata.dma_ops = &dma_iommu_ops;
> -	vio_bus_device.dev.archdata.dma_data = &vio_iommu_table;
>  }
>  #else
>  static void __init iommu_vio_init(void)
> diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
> index 3b6a966..3281f10 100644
> --- a/arch/powerpc/platforms/iseries/iommu.c
> +++ b/arch/powerpc/platforms/iseries/iommu.c
> @@ -28,6 +28,7 @@
>  #include <linux/dma-mapping.h>
>  #include <linux/list.h>
>  #include <linux/pci.h>
> +#include <linux/module.h>
>  
>  #include <asm/iommu.h>
>  #include <asm/tce.h>
> @@ -36,6 +37,7 @@
>  #include <asm/prom.h>
>  #include <asm/pci-bridge.h>
>  #include <asm/iseries/hv_call_xm.h>
> +#include <asm/iseries/hv_call_event.h>
>  #include <asm/iseries/iommu.h>
>  
>  static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,
> @@ -189,6 +191,34 @@ void iommu_devnode_init_iSeries(struct pci_dev *pdev, struct device_node *dn)
>  }
>  #endif
>  
> +extern struct iommu_table vio_iommu_table;

This looks like it really should go in a header file
instead. include/asm-powerpc/vio.h perhaps?



-Olof

^ permalink raw reply

* [PATCH] [POWERPC] move of_platform_driver initialisations: arch/powerpc
From: Stephen Rothwell @ 2007-10-11  5:19 UTC (permalink / raw)
  To: paulus
  Cc: Olof Johansson, ppc-dev, Arnd Bergmann, Maxim Shchetynin,
	Christian Krafft

We no longer initialise the name and owner fields of the
of_platform_driver, but use the fields of the embedded device_driver's
name field instead.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 arch/powerpc/platforms/pasemi/gpio_mdio.c |    4 +++-
 arch/powerpc/sysdev/axonram.c             |    8 +++++---
 arch/powerpc/sysdev/pmi.c                 |    6 ++++--
 3 files changed, 12 insertions(+), 6 deletions(-)

This patch depends on my "Prepare to remove of_platform_driver name"
patch.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c
index c91a335..dae9f65 100644
--- a/arch/powerpc/platforms/pasemi/gpio_mdio.c
+++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c
@@ -320,10 +320,12 @@ static struct of_device_id gpio_mdio_match[] =
 
 static struct of_platform_driver gpio_mdio_driver =
 {
-	.name		= "gpio-mdio-bitbang",
 	.match_table	= gpio_mdio_match,
 	.probe		= gpio_mdio_probe,
 	.remove		= gpio_mdio_remove,
+	.driver		= {
+		.name	= "gpio-mdio-bitbang",
+	},
 };
 
 int gpio_mdio_init(void)
diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c
index ab037a3..4d3ba63 100644
--- a/arch/powerpc/sysdev/axonram.c
+++ b/arch/powerpc/sysdev/axonram.c
@@ -324,11 +324,13 @@ static struct of_device_id axon_ram_device_id[] = {
 };
 
 static struct of_platform_driver axon_ram_driver = {
-	.owner		= THIS_MODULE,
-	.name		= AXON_RAM_MODULE_NAME,
 	.match_table	= axon_ram_device_id,
 	.probe		= axon_ram_probe,
-	.remove		= axon_ram_remove
+	.remove		= axon_ram_remove,
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= AXON_RAM_MODULE_NAME,
+	},
 };
 
 /**
diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c
index 2f91b55..20edd1e 100644
--- a/arch/powerpc/sysdev/pmi.c
+++ b/arch/powerpc/sysdev/pmi.c
@@ -205,10 +205,12 @@ static int pmi_of_remove(struct of_device *dev)
 }
 
 static struct of_platform_driver pmi_of_platform_driver = {
-	.name		= "pmi",
 	.match_table	= pmi_match,
 	.probe		= pmi_of_probe,
-	.remove		= pmi_of_remove
+	.remove		= pmi_of_remove,
+	.driver		= {
+		.name	= "pmi",
+	},
 };
 
 static int __init pmi_module_init(void)
-- 
1.5.3.4

^ permalink raw reply related

* Re: [PATCH] Device tree bindings for Xilinx devices
From: David Gibson @ 2007-10-11  5:08 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <fa686aa40710102158r5d488d3kae3d02177625da1e@mail.gmail.com>

On Wed, Oct 10, 2007 at 10:58:25PM -0600, Grant Likely wrote:
> On 10/10/07, David Gibson <dwg@au1.ibm.com> wrote:
> > On Wed, Oct 10, 2007 at 10:18:50PM -0600, Grant Likely wrote:
> > > On 10/10/07, David Gibson <dwg@au1.ibm.com> wrote:
> > > > On Wed, Oct 10, 2007 at 08:25:36PM -0600, Grant Likely wrote:
> > > > > On 10/10/07, David Gibson <dwg@au1.ibm.com> wrote:
> > > > > > We've used 'cell-index' for similar purposes on other 4xx.
> > > > >
> > > > > Unfortunately, 'cell' has been used in the sense of a logic cell in an
> > > > > SoC.  In the case of the SystemACE, it is an external chip.
> > > > >
> > > > > What about "device-number"?
> > > >
> > > > Ok, I misunderstood.  If it's not on chip, what significance does this
> > > > serial number have?  Where would a driver need it?
> > >
> > > If there were 2 systemace devices on board; one attached to a CF slot
> > > labeled "1" and the other to one labeled "2".  :-)  Same problem as
> > > lining up serial device files to physical port numbers.
> > >
> > > The driver doesn't technically need it, but the information does need
> > > to flow through to the creation of logically numbered device files.
> >
> > Ah.  Then, I'm afraid it doesn't belong in the core binding.
> >
> > Preferably, you should just figure out something without help of this
> > property - plenty of other things have to figure out device names
> > without assistance like this.
> 
> I'm not too stuck on the method used, but I do think it is appropriate
> to encode this kind of data in the device tree in some form...
> However, for this particular device I'm probably just borrowing
> trouble.  I'll drop the property.
> 
> My main concern is that I don't like the implicit numbering that
> occurs simply based on the order of devices in the device tree.  If
> the probe algorithm ever changes to parse in reverse order or
> something reorders the tree, then the device numbers also change.  :-(

Way of the future, apparently, everything's supposed to use udev to
give things logical names.  No, I'm not thrilled at the prospect
either.

> I'd rather be explicit.  In fact I've already been bitten by this
> where the mpc5200 has 6 PSC, each of which can be configured as a
> serial port.  However, I've got access to 3 different boards; each of
> which has the logical port numbers 100% unrelated to the 'cell'
> number.

In any case, this can't really belong in a *device* binding.  Because
the numbering has to cross devices of the same basic type, but
different implementations.  Where "basic type" is based on how device
names are allocated, and is thus inherently Linux specific.

> > If you really must you could do this in analogy with the
> > "linux,network-index" property - but this would be, as that is, an
> > ugly hack, and should be recognized as such
> >
> > Segher's suggestion of using OF-style aliases for this is a fairly
> > good one, actually.  I just need to get to implementing it...
> 
> /me needs to look up what that look like and how I would use it.  My
> knowledge of OF is sadly lacking.

Short version by example:
/ {
	/* ... */
	aliases {
		hd = "/pci@f0000000/sata@f4000000/....";
		enet0 = "/soc/ethernet@c000";
		enet1 = "/soc/ethernet@d000";
		enet2 = "/pci@f0000000/isa/ethernet@i480"
		ttya = "/soc/serial@e000";
		ttyb = "/pci/isa/serail@3f8";
	}
}

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* [PATCH 7/7] [POWERPC] iSeries: move viodasd probing
From: Stephen Rothwell @ 2007-10-11  4:59 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev, Jens Axboe
In-Reply-To: <20071011145831.20c4e691.sfr@canb.auug.org.au>

This way we only have entries in the device tree for disks that actually
exist.  A slight complication is that disks may be attached to LPARs
at runtime.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Acked-by: Jens Axboe <jens.axboe@oracle.com>
---
 arch/powerpc/platforms/iseries/dt.c  |    6 -
 arch/powerpc/platforms/iseries/vio.c |  301 +++++++++++++++++++++++----------
 drivers/block/viodasd.c              |   77 +++------
 include/asm-powerpc/iseries/vio.h    |   47 ++++++
 4 files changed, 282 insertions(+), 149 deletions(-)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
index 2e4ad6b..4543c4b 100644
--- a/arch/powerpc/platforms/iseries/dt.c
+++ b/arch/powerpc/platforms/iseries/dt.c
@@ -72,7 +72,6 @@ static char __initdata device_type_cpu[] = "cpu";
 static char __initdata device_type_memory[] = "memory";
 static char __initdata device_type_serial[] = "serial";
 static char __initdata device_type_network[] = "network";
-static char __initdata device_type_block[] = "block";
 static char __initdata device_type_pci[] = "pci";
 static char __initdata device_type_vdevice[] = "vdevice";
 static char __initdata device_type_vscsi[] = "vscsi";
@@ -374,11 +373,6 @@ static void __init dt_vdevices(struct iseries_flat_dt *dt)
 
 		dt_end_node(dt);
 	}
-	reg += HVMAXARCHITECTEDVIRTUALLANS;
-
-	for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++)
-		dt_do_vdevice(dt, "viodasd", reg, i, device_type_block,
-				"IBM,iSeries-viodasd", 1);
 
 	dt_end_node(dt);
 }
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index b4f7433..d6435b0 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -25,8 +25,10 @@
 #include <linux/gfp.h>
 #include <linux/completion.h>
 #include <linux/proc_fs.h>
+#include <linux/module.h>
 
 #include <asm/firmware.h>
+#include <asm/vio.h>
 #include <asm/iseries/vio.h>
 #include <asm/iseries/iommu.h>
 #include <asm/iseries/hv_types.h>
@@ -57,7 +59,7 @@ struct vio_resource {
 	char	model[3];
 };
 
-static struct property * __init new_property(const char *name, int length,
+static struct property *new_property(const char *name, int length,
 		const void *value)
 {
 	struct property *np = kzalloc(sizeof(*np) + strlen(name) + 1 + length,
@@ -78,7 +80,7 @@ static void __init free_property(struct property *np)
 	kfree(np);
 }
 
-static struct device_node * __init new_node(const char *path,
+static struct device_node *new_node(const char *path,
 		struct device_node *parent)
 {
 	struct device_node *np = kzalloc(sizeof(*np), GFP_KERNEL);
@@ -97,7 +99,7 @@ static struct device_node * __init new_node(const char *path,
 	return np;
 }
 
-static void __init free_node(struct device_node *np)
+static void free_node(struct device_node *np)
 {
 	struct property *next;
 	struct property *prop;
@@ -113,7 +115,7 @@ static void __init free_node(struct device_node *np)
 	kfree(np);
 }
 
-static int __init add_string_property(struct device_node *np, const char *name,
+static int add_string_property(struct device_node *np, const char *name,
 		const char *value)
 {
 	struct property *nprop = new_property(name, strlen(value) + 1, value);
@@ -124,7 +126,7 @@ static int __init add_string_property(struct device_node *np, const char *name,
 	return 1;
 }
 
-static int __init add_raw_property(struct device_node *np, const char *name,
+static int add_raw_property(struct device_node *np, const char *name,
 		int length, const void *value)
 {
 	struct property *nprop = new_property(name, length, value);
@@ -135,6 +137,201 @@ static int __init add_raw_property(struct device_node *np, const char *name,
 	return 1;
 }
 
+static struct device_node *do_device_node(struct device_node *parent,
+		const char *name, u32 reg, u32 unit, const char *type,
+		const char *compat, struct vio_resource *res)
+{
+	struct device_node *np;
+	char path[32];
+
+	snprintf(path, sizeof(path), "/vdevice/%s@%08x", name, reg);
+	np = new_node(path, parent);
+	if (!np)
+		return NULL;
+	if (!add_string_property(np, "name", name) ||
+		!add_string_property(np, "device_type", type) ||
+		!add_string_property(np, "compatible", compat) ||
+		!add_raw_property(np, "reg", sizeof(reg), &reg) ||
+		!add_raw_property(np, "linux,unit_address",
+			sizeof(unit), &unit)) {
+		goto node_free;
+	}
+	if (res) {
+		if (!add_raw_property(np, "linux,vio_rsrcname",
+				sizeof(res->rsrcname), res->rsrcname) ||
+			!add_raw_property(np, "linux,vio_type",
+				sizeof(res->type), res->type) ||
+			!add_raw_property(np, "linux,vio_model",
+				sizeof(res->model), res->model))
+			goto node_free;
+	}
+	np->name = of_get_property(np, "name", NULL);
+	np->type = of_get_property(np, "device_type", NULL);
+	of_attach_node(np);
+#ifdef CONFIG_PROC_DEVICETREE
+	if (parent->pde) {
+		struct proc_dir_entry *ent;
+
+		ent = proc_mkdir(strrchr(np->full_name, '/') + 1, parent->pde);
+		if (ent)
+			proc_device_tree_add_node(np, ent);
+	}
+#endif
+	return np;
+
+ node_free:
+	free_node(np);
+	return NULL;
+}
+
+/*
+ * This is here so that we can dynamically add viodasd
+ * devices without exposing all the above infrastructure.
+ */
+struct vio_dev *vio_create_viodasd(u32 unit)
+{
+	struct device_node *vio_root;
+	struct device_node *np;
+	struct vio_dev *vdev = NULL;
+
+	vio_root = of_find_node_by_path("/vdevice");
+	if (!vio_root)
+		return NULL;
+	np = do_device_node(vio_root, "viodasd", FIRST_VIODASD + unit, unit,
+			"block", "IBM,iSeries-viodasd", NULL);
+	of_node_put(vio_root);
+	if (np) {
+		vdev = vio_register_device_node(np);
+		if (!vdev)
+			free_node(np);
+	}
+	return vdev;
+}
+EXPORT_SYMBOL_GPL(vio_create_viodasd);
+
+static void __init handle_block_event(struct HvLpEvent *event)
+{
+	struct vioblocklpevent *bevent = (struct vioblocklpevent *)event;
+	struct vio_waitevent *pwe;
+
+	if (event == NULL)
+		/* Notification that a partition went away! */
+		return;
+	/* First, we should NEVER get an int here...only acks */
+	if (hvlpevent_is_int(event)) {
+		printk(KERN_WARNING "handle_viod_request: "
+		       "Yikes! got an int in viodasd event handler!\n");
+		if (hvlpevent_need_ack(event)) {
+			event->xRc = HvLpEvent_Rc_InvalidSubtype;
+			HvCallEvent_ackLpEvent(event);
+		}
+		return;
+	}
+
+	switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) {
+	case vioblockopen:
+		/*
+		 * Handle a response to an open request.  We get all the
+		 * disk information in the response, so update it.  The
+		 * correlation token contains a pointer to a waitevent
+		 * structure that has a completion in it.  update the
+		 * return code in the waitevent structure and post the
+		 * completion to wake up the guy who sent the request
+		 */
+		pwe = (struct vio_waitevent *)event->xCorrelationToken;
+		pwe->rc = event->xRc;
+		pwe->sub_result = bevent->sub_result;
+		complete(&pwe->com);
+		break;
+	case vioblockclose:
+		break;
+	default:
+		printk(KERN_WARNING "handle_viod_request: unexpected subtype!");
+		if (hvlpevent_need_ack(event)) {
+			event->xRc = HvLpEvent_Rc_InvalidSubtype;
+			HvCallEvent_ackLpEvent(event);
+		}
+	}
+}
+
+static void __init probe_disk(struct device_node *vio_root, u32 unit)
+{
+	HvLpEvent_Rc hvrc;
+	struct vio_waitevent we;
+	u16 flags = 0;
+
+retry:
+	init_completion(&we.com);
+
+	/* Send the open event to OS/400 */
+	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
+			HvLpEvent_Type_VirtualIo,
+			viomajorsubtype_blockio | vioblockopen,
+			HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
+			viopath_sourceinst(viopath_hostLp),
+			viopath_targetinst(viopath_hostLp),
+			(u64)(unsigned long)&we, VIOVERSION << 16,
+			((u64)unit << 48) | ((u64)flags<< 32),
+			0, 0, 0);
+	if (hvrc != 0) {
+		printk(KERN_WARNING "probe_disk: bad rc on HV open %d\n",
+			(int)hvrc);
+		return;
+	}
+
+	wait_for_completion(&we.com);
+
+	if (we.rc != 0) {
+		if (flags != 0)
+			return;
+		/* try again with read only flag set */
+		flags = vioblockflags_ro;
+		goto retry;
+	}
+
+	/* Send the close event to OS/400.  We DON'T expect a response */
+	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
+			HvLpEvent_Type_VirtualIo,
+			viomajorsubtype_blockio | vioblockclose,
+			HvLpEvent_AckInd_NoAck, HvLpEvent_AckType_ImmediateAck,
+			viopath_sourceinst(viopath_hostLp),
+			viopath_targetinst(viopath_hostLp),
+			0, VIOVERSION << 16,
+			((u64)unit << 48) | ((u64)flags << 32),
+			0, 0, 0);
+	if (hvrc != 0) {
+		printk(KERN_WARNING "probe_disk: "
+		       "bad rc sending event to OS/400 %d\n", (int)hvrc);
+		return;
+	}
+
+	do_device_node(vio_root, "viodasd", FIRST_VIODASD + unit, unit,
+			"block", "IBM,iSeries-viodasd", NULL);
+}
+
+static void __init get_viodasd_info(struct device_node *vio_root)
+{
+	int rc;
+	u32 unit;
+
+	rc = viopath_open(viopath_hostLp, viomajorsubtype_blockio, 2);
+	if (rc) {
+		printk(KERN_WARNING "get_viodasd_info: "
+		       "error opening path to host partition %d\n",
+		       viopath_hostLp);
+		return;
+	}
+
+	/* Initialize our request handler */
+	vio_setHandler(viomajorsubtype_blockio, handle_block_event);
+
+	for (unit = 0; unit < HVMAXARCHITECTEDVIRTUALDISKS; unit++)
+		probe_disk(vio_root, unit);
+
+	vio_clearHandler(viomajorsubtype_blockio);
+	viopath_close(viopath_hostLp, viomajorsubtype_blockio, 2);
+}
+
 static void __init handle_cd_event(struct HvLpEvent *event)
 {
 	struct viocdlpevent *bevent;
@@ -233,49 +430,9 @@ static void __init get_viocd_info(struct device_node *vio_root)
 
 	for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALCDROMS) &&
 			unitinfo[unit].rsrcname[0]; unit++) {
-		struct device_node *np;
-		char name[64];
-		u32 reg = FIRST_VIOCD + unit;
-
-		snprintf(name, sizeof(name), "/vdevice/viocd@%08x", reg);
-		np = new_node(name, vio_root);
-		if (!np)
-			goto hv_free;
-		if (!add_string_property(np, "name", "viocd") ||
-			!add_string_property(np, "device_type", "block") ||
-			!add_string_property(np, "compatible",
-				"IBM,iSeries-viocd") ||
-			!add_raw_property(np, "reg", sizeof(reg), &reg) ||
-			!add_raw_property(np, "linux,unit_address",
-				sizeof(unit), &unit) ||
-			!add_raw_property(np, "linux,vio_rsrcname",
-				sizeof(unitinfo[unit].rsrcname),
-				unitinfo[unit].rsrcname) ||
-			!add_raw_property(np, "linux,vio_type",
-				sizeof(unitinfo[unit].type),
-				unitinfo[unit].type) ||
-			!add_raw_property(np, "linux,vio_model",
-				sizeof(unitinfo[unit].model),
-				unitinfo[unit].model))
-			goto node_free;
-		np->name = of_get_property(np, "name", NULL);
-		np->type = of_get_property(np, "device_type", NULL);
-		of_attach_node(np);
-#ifdef CONFIG_PROC_DEVICETREE
-		if (vio_root->pde) {
-			struct proc_dir_entry *ent;
-
-			ent = proc_mkdir(strrchr(np->full_name, '/') + 1,
-					vio_root->pde);
-			if (ent)
-				proc_device_tree_add_node(np, ent);
-		}
-#endif
-		continue;
-
- node_free:
-		free_node(np);
-		break;
+		if (!do_device_node(vio_root, "viocd", FIRST_VIOCD + unit, unit,
+				"block", "IBM,iSeries-viocd", &unitinfo[unit]))
+			break;
 	}
 
  hv_free:
@@ -350,49 +507,10 @@ static void __init get_viotape_info(struct device_node *vio_root)
 
 	for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALTAPES) &&
 			unitinfo[unit].rsrcname[0]; unit++) {
-		struct device_node *np;
-		char name[64];
-		u32 reg = FIRST_VIOTAPE + unit;
-
-		snprintf(name, sizeof(name), "/vdevice/viotape@%08x", reg);
-		np = new_node(name, vio_root);
-		if (!np)
-			goto hv_free;
-		if (!add_string_property(np, "name", "viotape") ||
-			!add_string_property(np, "device_type", "byte") ||
-			!add_string_property(np, "compatible",
-				"IBM,iSeries-viotape") ||
-			!add_raw_property(np, "reg", sizeof(reg), &reg) ||
-			!add_raw_property(np, "linux,unit_address",
-				sizeof(unit), &unit) ||
-			!add_raw_property(np, "linux,vio_rsrcname",
-				sizeof(unitinfo[unit].rsrcname),
-				unitinfo[unit].rsrcname) ||
-			!add_raw_property(np, "linux,vio_type",
-				sizeof(unitinfo[unit].type),
-				unitinfo[unit].type) ||
-			!add_raw_property(np, "linux,vio_model",
-				sizeof(unitinfo[unit].model),
-				unitinfo[unit].model))
-			goto node_free;
-		np->name = of_get_property(np, "name", NULL);
-		np->type = of_get_property(np, "device_type", NULL);
-		of_attach_node(np);
-#ifdef CONFIG_PROC_DEVICETREE
-		if (vio_root->pde) {
-			struct proc_dir_entry *ent;
-
-			ent = proc_mkdir(strrchr(np->full_name, '/') + 1,
-					vio_root->pde);
-			if (ent)
-				proc_device_tree_add_node(np, ent);
-		}
-#endif
-		continue;
-
- node_free:
-		free_node(np);
-		break;
+		if (!do_device_node(vio_root, "viotape", FIRST_VIOTAPE + unit,
+				unit, "byte", "IBM,iSeries-viotape",
+				&unitinfo[unit]))
+			break;
 	}
 
  hv_free:
@@ -422,6 +540,7 @@ static int __init iseries_vio_init(void)
 			goto put_node;
 	}
 
+	get_viodasd_info(vio_root);
 	get_viocd_info(vio_root);
 	get_viotape_info(vio_root);
 
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index af3969a..e824b67 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -74,53 +74,9 @@ enum {
 static DEFINE_SPINLOCK(viodasd_spinlock);
 
 #define VIOMAXREQ		16
-#define VIOMAXBLOCKDMA		12
 
 #define DEVICE_NO(cell)	((struct viodasd_device *)(cell) - &viodasd_devices[0])
 
-struct open_data {
-	u64	disk_size;
-	u16	max_disk;
-	u16	cylinders;
-	u16	tracks;
-	u16	sectors;
-	u16	bytes_per_sector;
-};
-
-struct rw_data {
-	u64	offset;
-	struct {
-		u32	token;
-		u32	reserved;
-		u64	len;
-	} dma_info[VIOMAXBLOCKDMA];
-};
-
-struct vioblocklpevent {
-	struct HvLpEvent	event;
-	u32			reserved;
-	u16			version;
-	u16			sub_result;
-	u16			disk;
-	u16			flags;
-	union {
-		struct open_data	open_data;
-		struct rw_data		rw_data;
-		u64			changed;
-	} u;
-};
-
-#define vioblockflags_ro   0x0001
-
-enum vioblocksubtype {
-	vioblockopen = 0x0001,
-	vioblockclose = 0x0002,
-	vioblockread = 0x0003,
-	vioblockwrite = 0x0004,
-	vioblockflush = 0x0005,
-	vioblockcheck = 0x0007
-};
-
 struct viodasd_waitevent {
 	struct completion	com;
 	int			rc;
@@ -429,7 +385,7 @@ static void do_viodasd_request(struct request_queue *q)
  * Probe a single disk and fill in the viodasd_device structure
  * for it.
  */
-static void probe_disk(struct viodasd_device *d)
+static int probe_disk(struct viodasd_device *d)
 {
 	HvLpEvent_Rc hvrc;
 	struct viodasd_waitevent we;
@@ -453,14 +409,14 @@ retry:
 			0, 0, 0);
 	if (hvrc != 0) {
 		printk(VIOD_KERN_WARNING "bad rc on HV open %d\n", (int)hvrc);
-		return;
+		return 0;
 	}
 
 	wait_for_completion(&we.com);
 
 	if (we.rc != 0) {
 		if (flags != 0)
-			return;
+			return 0;
 		/* try again with read only flag set */
 		flags = vioblockflags_ro;
 		goto retry;
@@ -490,15 +446,32 @@ retry:
 	if (hvrc != 0) {
 		printk(VIOD_KERN_WARNING
 		       "bad rc sending event to OS/400 %d\n", (int)hvrc);
-		return;
+		return 0;
 	}
+
+	if (d->dev == NULL) {
+		/* this is when we reprobe for new disks */
+		if (vio_create_viodasd(dev_no) == NULL) {
+			printk(VIOD_KERN_WARNING
+				"cannot allocate virtual device for disk %d\n",
+				dev_no);
+			return 0;
+		}
+		/*
+		 * The vio_create_viodasd will have recursed into this
+		 * routine with d->dev set to the new vio device and
+		 * will finish the setup of the disk below.
+		 */
+		return 1;
+	}
+
 	/* create the request queue for the disk */
 	spin_lock_init(&d->q_lock);
 	q = blk_init_queue(do_viodasd_request, &d->q_lock);
 	if (q == NULL) {
 		printk(VIOD_KERN_WARNING "cannot allocate queue for disk %d\n",
 				dev_no);
-		return;
+		return 0;
 	}
 	g = alloc_disk(1 << PARTITION_SHIFT);
 	if (g == NULL) {
@@ -506,7 +479,7 @@ retry:
 				"cannot allocate disk structure for disk %d\n",
 				dev_no);
 		blk_cleanup_queue(q);
-		return;
+		return 0;
 	}
 
 	d->disk = g;
@@ -538,6 +511,7 @@ retry:
 
 	/* register us in the global list */
 	add_disk(g);
+	return 1;
 }
 
 /* returns the total number of scatterlist elements converted */
@@ -718,8 +692,7 @@ static int viodasd_probe(struct vio_dev *vdev, const struct vio_device_id *id)
 	struct viodasd_device *d = &viodasd_devices[vdev->unit_address];
 
 	d->dev = &vdev->dev;
-	probe_disk(d);
-	if (d->disk == NULL)
+	if (!probe_disk(d))
 		return -ENODEV;
 	return 0;
 }
diff --git a/include/asm-powerpc/iseries/vio.h b/include/asm-powerpc/iseries/vio.h
index 2555dfd..f9ac0d0 100644
--- a/include/asm-powerpc/iseries/vio.h
+++ b/include/asm-powerpc/iseries/vio.h
@@ -51,6 +51,51 @@
  */
 #define VIO_MAX_SUBTYPES 8
 
+#define VIOMAXBLOCKDMA	12
+
+struct open_data {
+	u64	disk_size;
+	u16	max_disk;
+	u16	cylinders;
+	u16	tracks;
+	u16	sectors;
+	u16	bytes_per_sector;
+};
+
+struct rw_data {
+	u64	offset;
+	struct {
+		u32	token;
+		u32	reserved;
+		u64	len;
+	} dma_info[VIOMAXBLOCKDMA];
+};
+
+struct vioblocklpevent {
+	struct HvLpEvent	event;
+	u32			reserved;
+	u16			version;
+	u16			sub_result;
+	u16			disk;
+	u16			flags;
+	union {
+		struct open_data	open_data;
+		struct rw_data		rw_data;
+		u64			changed;
+	} u;
+};
+
+#define vioblockflags_ro   0x0001
+
+enum vioblocksubtype {
+	vioblockopen = 0x0001,
+	vioblockclose = 0x0002,
+	vioblockread = 0x0003,
+	vioblockwrite = 0x0004,
+	vioblockflush = 0x0005,
+	vioblockcheck = 0x0007
+};
+
 struct viocdlpevent {
 	struct HvLpEvent	event;
 	u32			reserved;
@@ -133,6 +178,8 @@ extern void vio_set_hostlp(void);
 extern void *vio_get_event_buffer(int subtype);
 extern void vio_free_event_buffer(int subtype, void *buffer);
 
+extern struct vio_dev *vio_create_viodasd(u32 unit);
+
 extern HvLpIndex viopath_hostLp;
 extern HvLpIndex viopath_ourLp;
 
-- 
1.5.3.4

^ permalink raw reply related

* [PATCH 6/7] [POWERPC] iSeries: move detection of virtual tapes
From: Stephen Rothwell @ 2007-10-11  4:58 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev
In-Reply-To: <20071011145726.59bcbc02.sfr@canb.auug.org.au>

Now we will only have entries in the device tree for the actual existing
devices (including their OS/400 properties).  This way viotape.c gets
all the information about the devices from the device tree.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 arch/powerpc/platforms/iseries/dt.c  |    7 --
 arch/powerpc/platforms/iseries/vio.c |  149 ++++++++++++++++++++++++++++++----
 drivers/char/viotape.c               |  124 ++++------------------------
 include/asm-powerpc/iseries/vio.h    |   41 +++++++++
 4 files changed, 192 insertions(+), 129 deletions(-)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
index 84fcee1..2e4ad6b 100644
--- a/arch/powerpc/platforms/iseries/dt.c
+++ b/arch/powerpc/platforms/iseries/dt.c
@@ -73,7 +73,6 @@ static char __initdata device_type_memory[] = "memory";
 static char __initdata device_type_serial[] = "serial";
 static char __initdata device_type_network[] = "network";
 static char __initdata device_type_block[] = "block";
-static char __initdata device_type_byte[] = "byte";
 static char __initdata device_type_pci[] = "pci";
 static char __initdata device_type_vdevice[] = "vdevice";
 static char __initdata device_type_vscsi[] = "vscsi";
@@ -380,12 +379,6 @@ static void __init dt_vdevices(struct iseries_flat_dt *dt)
 	for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++)
 		dt_do_vdevice(dt, "viodasd", reg, i, device_type_block,
 				"IBM,iSeries-viodasd", 1);
-	reg += HVMAXARCHITECTEDVIRTUALDISKS;
-	reg += HVMAXARCHITECTEDVIRTUALCDROMS;
-
-	for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++)
-		dt_do_vdevice(dt, "viotape", reg, i, device_type_byte,
-				"IBM,iSeries-viotape", 1);
 
 	dt_end_node(dt);
 }
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index 08f6884..b4f7433 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -45,6 +45,18 @@
 #define FIRST_VIOTAPE	(FIRST_VIOCD + NUM_VIOCDS)
 #define NUM_VIOTAPES	HVMAXARCHITECTEDVIRTUALTAPES
 
+struct vio_waitevent {
+	struct completion	com;
+	int			rc;
+	u16			sub_result;
+};
+
+struct vio_resource {
+	char	rsrcname[10];
+	char	type[4];
+	char	model[3];
+};
+
 static struct property * __init new_property(const char *name, int length,
 		const void *value)
 {
@@ -123,22 +135,10 @@ static int __init add_raw_property(struct device_node *np, const char *name,
 	return 1;
 }
 
-struct viocd_waitevent {
-	struct completion	com;
-	int			rc;
-	u16			sub_result;
-};
-
-struct cdrom_info {
-	char	rsrcname[10];
-	char	type[4];
-	char	model[3];
-};
-
 static void __init handle_cd_event(struct HvLpEvent *event)
 {
 	struct viocdlpevent *bevent;
-	struct viocd_waitevent *pwe;
+	struct vio_waitevent *pwe;
 
 	if (!event)
 		/* Notification that a partition went away! */
@@ -158,7 +158,7 @@ static void __init handle_cd_event(struct HvLpEvent *event)
 
 	switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) {
 	case viocdgetinfo:
-		pwe = (struct viocd_waitevent *)event->xCorrelationToken;
+		pwe = (struct vio_waitevent *)event->xCorrelationToken;
 		pwe->rc = event->xRc;
 		pwe->sub_result = bevent->sub_result;
 		complete(&pwe->com);
@@ -179,8 +179,8 @@ static void __init get_viocd_info(struct device_node *vio_root)
 {
 	HvLpEvent_Rc hvrc;
 	u32 unit;
-	struct viocd_waitevent we;
-	struct cdrom_info *unitinfo;
+	struct vio_waitevent we;
+	struct vio_resource *unitinfo;
 	dma_addr_t unitinfo_dmaaddr;
 	int ret;
 
@@ -286,6 +286,122 @@ static void __init get_viocd_info(struct device_node *vio_root)
 	viopath_close(viopath_hostLp, viomajorsubtype_cdio, 2);
 }
 
+/* Handle interrupt events for tape */
+static void __init handle_tape_event(struct HvLpEvent *event)
+{
+	struct vio_waitevent *we;
+	struct viotapelpevent *tevent = (struct viotapelpevent *)event;
+
+	if (event == NULL)
+		/* Notification that a partition went away! */
+		return;
+
+	we = (struct vio_waitevent *)event->xCorrelationToken;
+	switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) {
+	case viotapegetinfo:
+		we->rc = tevent->sub_type_result;
+		complete(&we->com);
+		break;
+	default:
+		printk(KERN_WARNING "handle_tape_event: weird ack\n");
+	}
+}
+
+static void __init get_viotape_info(struct device_node *vio_root)
+{
+	HvLpEvent_Rc hvrc;
+	u32 unit;
+	struct vio_resource *unitinfo;
+	dma_addr_t unitinfo_dmaaddr;
+	size_t len = sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALTAPES;
+	struct vio_waitevent we;
+	int ret;
+
+	ret = viopath_open(viopath_hostLp, viomajorsubtype_tape, 2);
+	if (ret) {
+		printk(KERN_WARNING "get_viotape_info: "
+			"error on viopath_open to hostlp %d\n", ret);
+		return;
+	}
+
+	vio_setHandler(viomajorsubtype_tape, handle_tape_event);
+
+	unitinfo = iseries_hv_alloc(len, &unitinfo_dmaaddr, GFP_ATOMIC);
+	if (!unitinfo)
+		goto clear_handler;
+
+	memset(unitinfo, 0, len);
+
+	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
+			HvLpEvent_Type_VirtualIo,
+			viomajorsubtype_tape | viotapegetinfo,
+			HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
+			viopath_sourceinst(viopath_hostLp),
+			viopath_targetinst(viopath_hostLp),
+			(u64)(unsigned long)&we, VIOVERSION << 16,
+			unitinfo_dmaaddr, len, 0, 0);
+	if (hvrc != HvLpEvent_Rc_Good) {
+		printk(KERN_WARNING "get_viotape_info: hv error on op %d\n",
+				(int)hvrc);
+		goto hv_free;
+	}
+
+	wait_for_completion(&we.com);
+
+	for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALTAPES) &&
+			unitinfo[unit].rsrcname[0]; unit++) {
+		struct device_node *np;
+		char name[64];
+		u32 reg = FIRST_VIOTAPE + unit;
+
+		snprintf(name, sizeof(name), "/vdevice/viotape@%08x", reg);
+		np = new_node(name, vio_root);
+		if (!np)
+			goto hv_free;
+		if (!add_string_property(np, "name", "viotape") ||
+			!add_string_property(np, "device_type", "byte") ||
+			!add_string_property(np, "compatible",
+				"IBM,iSeries-viotape") ||
+			!add_raw_property(np, "reg", sizeof(reg), &reg) ||
+			!add_raw_property(np, "linux,unit_address",
+				sizeof(unit), &unit) ||
+			!add_raw_property(np, "linux,vio_rsrcname",
+				sizeof(unitinfo[unit].rsrcname),
+				unitinfo[unit].rsrcname) ||
+			!add_raw_property(np, "linux,vio_type",
+				sizeof(unitinfo[unit].type),
+				unitinfo[unit].type) ||
+			!add_raw_property(np, "linux,vio_model",
+				sizeof(unitinfo[unit].model),
+				unitinfo[unit].model))
+			goto node_free;
+		np->name = of_get_property(np, "name", NULL);
+		np->type = of_get_property(np, "device_type", NULL);
+		of_attach_node(np);
+#ifdef CONFIG_PROC_DEVICETREE
+		if (vio_root->pde) {
+			struct proc_dir_entry *ent;
+
+			ent = proc_mkdir(strrchr(np->full_name, '/') + 1,
+					vio_root->pde);
+			if (ent)
+				proc_device_tree_add_node(np, ent);
+		}
+#endif
+		continue;
+
+ node_free:
+		free_node(np);
+		break;
+	}
+
+ hv_free:
+	iseries_hv_free(len, unitinfo, unitinfo_dmaaddr);
+ clear_handler:
+	vio_clearHandler(viomajorsubtype_tape);
+	viopath_close(viopath_hostLp, viomajorsubtype_tape, 2);
+}
+
 static int __init iseries_vio_init(void)
 {
 	struct device_node *vio_root;
@@ -307,6 +423,7 @@ static int __init iseries_vio_init(void)
 	}
 
 	get_viocd_info(vio_root);
+	get_viotape_info(vio_root);
 
 	return 0;
 
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 064c091..f1d60f0 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -92,47 +92,6 @@ struct viot_devinfo_struct {
 #define VIOTAPOP_SETPART       14
 #define VIOTAPOP_UNLOAD        15
 
-struct viotapelpevent {
-	struct HvLpEvent event;
-	u32 reserved;
-	u16 version;
-	u16 sub_type_result;
-	u16 tape;
-	u16 flags;
-	u32 token;
-	u64 len;
-	union {
-		struct {
-			u32 tape_op;
-			u32 count;
-		} op;
-		struct {
-			u32 type;
-			u32 resid;
-			u32 dsreg;
-			u32 gstat;
-			u32 erreg;
-			u32 file_no;
-			u32 block_no;
-		} get_status;
-		struct {
-			u32 block_no;
-		} get_pos;
-	} u;
-};
-
-enum viotapesubtype {
-	viotapeopen = 0x0001,
-	viotapeclose = 0x0002,
-	viotaperead = 0x0003,
-	viotapewrite = 0x0004,
-	viotapegetinfo = 0x0005,
-	viotapeop = 0x0006,
-	viotapegetpos = 0x0007,
-	viotapesetpos = 0x0008,
-	viotapegetstatus = 0x0009
-};
-
 enum viotaperc {
 	viotape_InvalidRange = 0x0601,
 	viotape_InvalidToken = 0x0602,
@@ -223,14 +182,11 @@ static const struct vio_error_entry viotape_err_table[] = {
 #define VIOT_WRITING		2
 
 /* Our info on the tapes */
-struct tape_descr {
-	char rsrcname[10];
-	char type[4];
-	char model[3];
-};
-
-static struct tape_descr *viotape_unitinfo;
-static dma_addr_t viotape_unitinfo_token;
+static struct {
+	const char *rsrcname;
+	const char *type;
+	const char *model;
+} viotape_unitinfo[VIOTAPE_MAX_TAPE];
 
 static struct mtget viomtget[VIOTAPE_MAX_TAPE];
 
@@ -381,53 +337,6 @@ int tape_rc_to_errno(int tape_rc, char *operation, int tapeno)
 	return -err->errno;
 }
 
-/* Get info on all tapes from OS/400 */
-static int get_viotape_info(void)
-{
-	HvLpEvent_Rc hvrc;
-	int i;
-	size_t len = sizeof(*viotape_unitinfo) * VIOTAPE_MAX_TAPE;
-	struct op_struct *op = get_op_struct();
-
-	if (op == NULL)
-		return -ENOMEM;
-
-	viotape_unitinfo = iseries_hv_alloc(len, &viotape_unitinfo_token,
-		GFP_ATOMIC);
-	if (viotape_unitinfo == NULL) {
-		free_op_struct(op);
-		return -ENOMEM;
-	}
-
-	memset(viotape_unitinfo, 0, len);
-
-	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
-			HvLpEvent_Type_VirtualIo,
-			viomajorsubtype_tape | viotapegetinfo,
-			HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
-			viopath_sourceinst(viopath_hostLp),
-			viopath_targetinst(viopath_hostLp),
-			(u64) (unsigned long) op, VIOVERSION << 16,
-			viotape_unitinfo_token, len, 0, 0);
-	if (hvrc != HvLpEvent_Rc_Good) {
-		printk(VIOTAPE_KERN_WARN "hv error on op %d\n",
-				(int)hvrc);
-		free_op_struct(op);
-		return -EIO;
-	}
-
-	wait_for_completion(&op->com);
-
-	free_op_struct(op);
-
-	for (i = 0;
-	     ((i < VIOTAPE_MAX_TAPE) && (viotape_unitinfo[i].rsrcname[0]));
-	     i++)
-		viotape_numdev++;
-	return 0;
-}
-
-
 /* Write */
 static ssize_t viotap_write(struct file *file, const char *buf,
 		size_t count, loff_t * ppos)
@@ -899,7 +808,6 @@ static void vioHandleTapeEvent(struct HvLpEvent *event)
 	tapeminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK;
 	op = (struct op_struct *)event->xCorrelationToken;
 	switch (tapeminor) {
-	case viotapegetinfo:
 	case viotapeopen:
 	case viotapeclose:
 		op->rc = tevent->sub_type_result;
@@ -942,11 +850,23 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
 {
 	int i = vdev->unit_address;
 	int j;
+	struct device_node *node = vdev->dev.archdata.of_node;
 
-	if (i >= viotape_numdev)
+	if (i > VIOTAPE_MAX_TAPE)
+		return -ENODEV;
+	if (!node)
 		return -ENODEV;
 
+	if (i >= viotape_numdev)
+		viotape_numdev = i + 1;
+
 	tape_device[i] = &vdev->dev;
+	viotape_unitinfo[i].rsrcname = of_get_property(node,
+					"linux,vio_rsrcname", NULL);
+	viotape_unitinfo[i].type = of_get_property(node, "linux,vio_type",
+					NULL);
+	viotape_unitinfo[i].model = of_get_property(node, "linux,vio_model",
+					NULL);
 
 	state[i].cur_part = 0;
 	for (j = 0; j < MAX_PARTITIONS; ++j)
@@ -1044,11 +964,6 @@ int __init viotap_init(void)
 		goto unreg_chrdev;
 	}
 
-	if ((ret = get_viotape_info()) < 0) {
-		printk(VIOTAPE_KERN_WARN "Unable to obtain virtual device information");
-		goto unreg_class;
-	}
-
 	ret = vio_register_driver(&viotape_driver);
 	if (ret)
 		goto unreg_class;
@@ -1102,9 +1017,6 @@ static void __exit viotap_exit(void)
 	vio_unregister_driver(&viotape_driver);
 	class_destroy(tape_class);
 	unregister_chrdev(VIOTAPE_MAJOR, "viotape");
-	if (viotape_unitinfo)
-		iseries_hv_free(sizeof(viotape_unitinfo[0]) * VIOTAPE_MAX_TAPE,
-				viotape_unitinfo, viotape_unitinfo_token);
 	viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2);
 	vio_clearHandler(viomajorsubtype_tape);
 	clear_op_struct_pool();
diff --git a/include/asm-powerpc/iseries/vio.h b/include/asm-powerpc/iseries/vio.h
index e5a405b..2555dfd 100644
--- a/include/asm-powerpc/iseries/vio.h
+++ b/include/asm-powerpc/iseries/vio.h
@@ -75,6 +75,47 @@ enum viocdsubtype {
 	viocdcheck = 0x0007
 };
 
+struct viotapelpevent {
+	struct HvLpEvent event;
+	u32 reserved;
+	u16 version;
+	u16 sub_type_result;
+	u16 tape;
+	u16 flags;
+	u32 token;
+	u64 len;
+	union {
+		struct {
+			u32 tape_op;
+			u32 count;
+		} op;
+		struct {
+			u32 type;
+			u32 resid;
+			u32 dsreg;
+			u32 gstat;
+			u32 erreg;
+			u32 file_no;
+			u32 block_no;
+		} get_status;
+		struct {
+			u32 block_no;
+		} get_pos;
+	} u;
+};
+
+enum viotapesubtype {
+	viotapeopen = 0x0001,
+	viotapeclose = 0x0002,
+	viotaperead = 0x0003,
+	viotapewrite = 0x0004,
+	viotapegetinfo = 0x0005,
+	viotapeop = 0x0006,
+	viotapegetpos = 0x0007,
+	viotapesetpos = 0x0008,
+	viotapegetstatus = 0x0009
+};
+
 /*
  * Each subtype can register a handler to process their events.
  * The handler must have this interface.
-- 
1.5.3.4

^ permalink raw reply related

* [PATCH 5/7] [POWERPC] iSeries: move detection of virtual cdroms
From: Stephen Rothwell @ 2007-10-11  4:57 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev, Jens Axboe
In-Reply-To: <20071011145502.49a16436.sfr@canb.auug.org.au>

Now we will only have entries in the device tree for the actual existing
devices (including their OS/400 properties).  This way viocd.c gets all
the information about the devices from the device tree.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Acked-by: Jens Axboe <jens.axboe@oracle.com>
---
 arch/powerpc/kernel/vio.c               |    3 -
 arch/powerpc/platforms/iseries/Makefile |    2 +-
 arch/powerpc/platforms/iseries/dt.c     |    4 -
 arch/powerpc/platforms/iseries/vio.c    |  317 +++++++++++++++++++++++++++++++
 drivers/cdrom/viocd.c                   |  116 ++----------
 include/asm-powerpc/iseries/vio.h       |   24 +++
 6 files changed, 361 insertions(+), 105 deletions(-)
 create mode 100644 arch/powerpc/platforms/iseries/vio.c

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index b7c9e44..cb22a35 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -247,9 +247,6 @@ static int __init vio_bus_init(void)
 	int err;
 	struct device_node *node_vroot;
 
-	if (firmware_has_feature(FW_FEATURE_ISERIES))
-		iommu_vio_init();
-
 	err = bus_register(&vio_bus_type);
 	if (err) {
 		printk(KERN_ERR "failed to register VIO bus\n");
diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile
index 60db509..a65f1b4 100644
--- a/arch/powerpc/platforms/iseries/Makefile
+++ b/arch/powerpc/platforms/iseries/Makefile
@@ -7,7 +7,7 @@ obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt_mod.o mf.o lpevents.o \
 	hvcall.o proc.o htab.o iommu.o misc.o irq.o
 obj-$(CONFIG_PCI) += pci.o vpdinfo.o
 obj-$(CONFIG_SMP) += smp.o
-obj-$(CONFIG_VIOPATH) += viopath.o
+obj-$(CONFIG_VIOPATH) += viopath.o vio.o
 obj-$(CONFIG_MODULES) += ksyms.o
 
 quiet_cmd_dt_strings = DT_STR  $@
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
index 9e8a334..84fcee1 100644
--- a/arch/powerpc/platforms/iseries/dt.c
+++ b/arch/powerpc/platforms/iseries/dt.c
@@ -381,10 +381,6 @@ static void __init dt_vdevices(struct iseries_flat_dt *dt)
 		dt_do_vdevice(dt, "viodasd", reg, i, device_type_block,
 				"IBM,iSeries-viodasd", 1);
 	reg += HVMAXARCHITECTEDVIRTUALDISKS;
-
-	for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++)
-		dt_do_vdevice(dt, "viocd", reg, i, device_type_block,
-				"IBM,iSeries-viocd", 1);
 	reg += HVMAXARCHITECTEDVIRTUALCDROMS;
 
 	for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++)
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
new file mode 100644
index 0000000..08f6884
--- /dev/null
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -0,0 +1,317 @@
+/*
+ * Legacy iSeries specific vio initialisation
+ * that needs to be built in (not a module).
+ *
+ * © Copyright 2007 IBM Corporation
+ *	Author: Stephen Rothwell
+ *	Some parts collected from various other files
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/of.h>
+#include <linux/init.h>
+#include <linux/gfp.h>
+#include <linux/completion.h>
+#include <linux/proc_fs.h>
+
+#include <asm/firmware.h>
+#include <asm/iseries/vio.h>
+#include <asm/iseries/iommu.h>
+#include <asm/iseries/hv_types.h>
+#include <asm/iseries/hv_lp_event.h>
+
+#define FIRST_VTY	0
+#define NUM_VTYS	1
+#define FIRST_VSCSI	(FIRST_VTY + NUM_VTYS)
+#define NUM_VSCSIS	1
+#define FIRST_VLAN	(FIRST_VSCSI + NUM_VSCSIS)
+#define NUM_VLANS	HVMAXARCHITECTEDVIRTUALLANS
+#define FIRST_VIODASD	(FIRST_VLAN + NUM_VLANS)
+#define NUM_VIODASDS	HVMAXARCHITECTEDVIRTUALDISKS
+#define FIRST_VIOCD	(FIRST_VIODASD + NUM_VIODASDS)
+#define NUM_VIOCDS	HVMAXARCHITECTEDVIRTUALCDROMS
+#define FIRST_VIOTAPE	(FIRST_VIOCD + NUM_VIOCDS)
+#define NUM_VIOTAPES	HVMAXARCHITECTEDVIRTUALTAPES
+
+static struct property * __init new_property(const char *name, int length,
+		const void *value)
+{
+	struct property *np = kzalloc(sizeof(*np) + strlen(name) + 1 + length,
+			GFP_KERNEL);
+
+	if (!np)
+		return NULL;
+	np->name = (char *)(np + 1);
+	np->value = np->name + strlen(name) + 1;
+	strcpy(np->name, name);
+	memcpy(np->value, value, length);
+	np->length = length;
+	return np;
+}
+
+static void __init free_property(struct property *np)
+{
+	kfree(np);
+}
+
+static struct device_node * __init new_node(const char *path,
+		struct device_node *parent)
+{
+	struct device_node *np = kzalloc(sizeof(*np), GFP_KERNEL);
+
+	if (!np)
+		return NULL;
+	np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL);
+	if (!np->full_name) {
+		kfree(np);
+		return NULL;
+	}
+	strcpy(np->full_name, path);
+	of_node_set_flag(np, OF_DYNAMIC);
+	kref_init(&np->kref);
+	np->parent = of_node_get(parent);
+	return np;
+}
+
+static void __init free_node(struct device_node *np)
+{
+	struct property *next;
+	struct property *prop;
+
+	next = np->properties;
+	while (next) {
+		prop = next;
+		next = prop->next;
+		free_property(prop);
+	}
+	of_node_put(np->parent);
+	kfree(np->full_name);
+	kfree(np);
+}
+
+static int __init add_string_property(struct device_node *np, const char *name,
+		const char *value)
+{
+	struct property *nprop = new_property(name, strlen(value) + 1, value);
+
+	if (!nprop)
+		return 0;
+	prom_add_property(np, nprop);
+	return 1;
+}
+
+static int __init add_raw_property(struct device_node *np, const char *name,
+		int length, const void *value)
+{
+	struct property *nprop = new_property(name, length, value);
+
+	if (!nprop)
+		return 0;
+	prom_add_property(np, nprop);
+	return 1;
+}
+
+struct viocd_waitevent {
+	struct completion	com;
+	int			rc;
+	u16			sub_result;
+};
+
+struct cdrom_info {
+	char	rsrcname[10];
+	char	type[4];
+	char	model[3];
+};
+
+static void __init handle_cd_event(struct HvLpEvent *event)
+{
+	struct viocdlpevent *bevent;
+	struct viocd_waitevent *pwe;
+
+	if (!event)
+		/* Notification that a partition went away! */
+		return;
+
+	/* First, we should NEVER get an int here...only acks */
+	if (hvlpevent_is_int(event)) {
+		printk(KERN_WARNING "handle_cd_event: got an unexpected int\n");
+		if (hvlpevent_need_ack(event)) {
+			event->xRc = HvLpEvent_Rc_InvalidSubtype;
+			HvCallEvent_ackLpEvent(event);
+		}
+		return;
+	}
+
+	bevent = (struct viocdlpevent *)event;
+
+	switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) {
+	case viocdgetinfo:
+		pwe = (struct viocd_waitevent *)event->xCorrelationToken;
+		pwe->rc = event->xRc;
+		pwe->sub_result = bevent->sub_result;
+		complete(&pwe->com);
+		break;
+
+	default:
+		printk(KERN_WARNING "handle_cd_event: "
+			"message with unexpected subtype %0x04X!\n",
+			event->xSubtype & VIOMINOR_SUBTYPE_MASK);
+		if (hvlpevent_need_ack(event)) {
+			event->xRc = HvLpEvent_Rc_InvalidSubtype;
+			HvCallEvent_ackLpEvent(event);
+		}
+	}
+}
+
+static void __init get_viocd_info(struct device_node *vio_root)
+{
+	HvLpEvent_Rc hvrc;
+	u32 unit;
+	struct viocd_waitevent we;
+	struct cdrom_info *unitinfo;
+	dma_addr_t unitinfo_dmaaddr;
+	int ret;
+
+	ret = viopath_open(viopath_hostLp, viomajorsubtype_cdio, 2);
+	if (ret) {
+		printk(KERN_WARNING
+			"get_viocd_info: error opening path to host partition %d\n",
+			viopath_hostLp);
+		return;
+	}
+
+	/* Initialize our request handler */
+	vio_setHandler(viomajorsubtype_cdio, handle_cd_event);
+
+	unitinfo = iseries_hv_alloc(
+			sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS,
+			&unitinfo_dmaaddr, GFP_ATOMIC);
+	if (!unitinfo) {
+		printk(KERN_WARNING
+			"get_viocd_info: error allocating unitinfo\n");
+		goto clear_handler;
+	}
+
+	memset(unitinfo, 0, sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS);
+
+	init_completion(&we.com);
+
+	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
+			HvLpEvent_Type_VirtualIo,
+			viomajorsubtype_cdio | viocdgetinfo,
+			HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
+			viopath_sourceinst(viopath_hostLp),
+			viopath_targetinst(viopath_hostLp),
+			(u64)&we, VIOVERSION << 16, unitinfo_dmaaddr, 0,
+			sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS, 0);
+	if (hvrc != HvLpEvent_Rc_Good) {
+		printk(KERN_WARNING
+			"get_viocd_info: cdrom error sending event. rc %d\n",
+			(int)hvrc);
+		goto hv_free;
+	}
+
+	wait_for_completion(&we.com);
+
+	if (we.rc) {
+		printk(KERN_WARNING "get_viocd_info: bad rc %d:0x%04X\n",
+			we.rc, we.sub_result);
+		goto hv_free;
+	}
+
+	for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALCDROMS) &&
+			unitinfo[unit].rsrcname[0]; unit++) {
+		struct device_node *np;
+		char name[64];
+		u32 reg = FIRST_VIOCD + unit;
+
+		snprintf(name, sizeof(name), "/vdevice/viocd@%08x", reg);
+		np = new_node(name, vio_root);
+		if (!np)
+			goto hv_free;
+		if (!add_string_property(np, "name", "viocd") ||
+			!add_string_property(np, "device_type", "block") ||
+			!add_string_property(np, "compatible",
+				"IBM,iSeries-viocd") ||
+			!add_raw_property(np, "reg", sizeof(reg), &reg) ||
+			!add_raw_property(np, "linux,unit_address",
+				sizeof(unit), &unit) ||
+			!add_raw_property(np, "linux,vio_rsrcname",
+				sizeof(unitinfo[unit].rsrcname),
+				unitinfo[unit].rsrcname) ||
+			!add_raw_property(np, "linux,vio_type",
+				sizeof(unitinfo[unit].type),
+				unitinfo[unit].type) ||
+			!add_raw_property(np, "linux,vio_model",
+				sizeof(unitinfo[unit].model),
+				unitinfo[unit].model))
+			goto node_free;
+		np->name = of_get_property(np, "name", NULL);
+		np->type = of_get_property(np, "device_type", NULL);
+		of_attach_node(np);
+#ifdef CONFIG_PROC_DEVICETREE
+		if (vio_root->pde) {
+			struct proc_dir_entry *ent;
+
+			ent = proc_mkdir(strrchr(np->full_name, '/') + 1,
+					vio_root->pde);
+			if (ent)
+				proc_device_tree_add_node(np, ent);
+		}
+#endif
+		continue;
+
+ node_free:
+		free_node(np);
+		break;
+	}
+
+ hv_free:
+	iseries_hv_free(sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS,
+			unitinfo, unitinfo_dmaaddr);
+ clear_handler:
+	vio_clearHandler(viomajorsubtype_cdio);
+	viopath_close(viopath_hostLp, viomajorsubtype_cdio, 2);
+}
+
+static int __init iseries_vio_init(void)
+{
+	struct device_node *vio_root;
+
+	if (!firmware_has_feature(FW_FEATURE_ISERIES))
+		return -ENODEV;
+
+	iommu_vio_init();
+
+	vio_root = of_find_node_by_path("/vdevice");
+	if (!vio_root)
+		return -ENODEV;
+
+	if (viopath_hostLp == HvLpIndexInvalid) {
+		vio_set_hostlp();
+		/* If we don't have a host, bail out */
+		if (viopath_hostLp == HvLpIndexInvalid)
+			goto put_node;
+	}
+
+	get_viocd_info(vio_root);
+
+	return 0;
+
+ put_node:
+	of_node_put(vio_root);
+	return -ENODEV;
+}
+arch_initcall(iseries_vio_init);
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index c081e54..880b5dc 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -56,30 +56,6 @@
 #define VIOCD_KERN_WARNING		KERN_WARNING "viocd: "
 #define VIOCD_KERN_INFO			KERN_INFO "viocd: "
 
-struct viocdlpevent {
-	struct HvLpEvent	event;
-	u32			reserved;
-	u16			version;
-	u16			sub_result;
-	u16			disk;
-	u16			flags;
-	u32			token;
-	u64			offset;		/* On open, max number of disks */
-	u64			len;		/* On open, size of the disk */
-	u32			block_size;	/* Only set on open */
-	u32			media_size;	/* Only set on open */
-};
-
-enum viocdsubtype {
-	viocdopen = 0x0001,
-	viocdclose = 0x0002,
-	viocdread = 0x0003,
-	viocdwrite = 0x0004,
-	viocdlockdoor = 0x0005,
-	viocdgetinfo = 0x0006,
-	viocdcheck = 0x0007
-};
-
 /*
  * Should probably make this a module parameter....sigh
  */
@@ -131,17 +107,13 @@ static struct capability_entry capability_table[] __initdata = {
 /* These are our internal structures for keeping track of devices */
 static int viocd_numdev;
 
-struct cdrom_info {
-	char	rsrcname[10];
-	char	type[4];
-	char	model[3];
-};
-
 struct disk_info {
 	struct gendisk			*viocd_disk;
 	struct cdrom_device_info	viocd_info;
 	struct device			*dev;
-	struct cdrom_info		unitinfo;
+	const char			*rsrcname;
+	const char			*type;
+	const char			*model;
 };
 static struct disk_info viocd_diskinfo[VIOCD_MAX_CD];
 
@@ -159,9 +131,9 @@ static int proc_viocd_show(struct seq_file *m, void *v)
 	for (i = 0; i < viocd_numdev; i++) {
 		seq_printf(m, "viocd device %d is iSeries resource %10.10s"
 				"type %4.4s, model %3.3s\n",
-				i, viocd_diskinfo[i].unitinfo.rsrcname,
-				viocd_diskinfo[i].unitinfo.type,
-				viocd_diskinfo[i].unitinfo.model);
+				i, viocd_diskinfo[i].rsrcname,
+				viocd_diskinfo[i].type,
+				viocd_diskinfo[i].model);
 	}
 	return 0;
 }
@@ -211,61 +183,6 @@ struct block_device_operations viocd_fops = {
 	.media_changed =	viocd_blk_media_changed,
 };
 
-/* Get info on CD devices from OS/400 */
-static void __init get_viocd_info(void)
-{
-	HvLpEvent_Rc hvrc;
-	int i;
-	struct viocd_waitevent we;
-	struct cdrom_info *viocd_unitinfo;
-	dma_addr_t unitinfo_dmaaddr;
-
-	viocd_unitinfo = iseries_hv_alloc(
-			sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
-			&unitinfo_dmaaddr, GFP_ATOMIC);
-	if (viocd_unitinfo == NULL) {
-		printk(VIOCD_KERN_WARNING "error allocating unitinfo\n");
-		return;
-	}
-
-	memset(viocd_unitinfo, 0, sizeof(*viocd_unitinfo) * VIOCD_MAX_CD);
-
-	init_completion(&we.com);
-
-	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
-			HvLpEvent_Type_VirtualIo,
-			viomajorsubtype_cdio | viocdgetinfo,
-			HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
-			viopath_sourceinst(viopath_hostLp),
-			viopath_targetinst(viopath_hostLp),
-			(u64)&we, VIOVERSION << 16, unitinfo_dmaaddr, 0,
-			sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, 0);
-	if (hvrc != HvLpEvent_Rc_Good) {
-		printk(VIOCD_KERN_WARNING "cdrom error sending event. rc %d\n",
-				(int)hvrc);
-		goto error_ret;
-	}
-
-	wait_for_completion(&we.com);
-
-	if (we.rc) {
-		const struct vio_error_entry *err =
-			vio_lookup_rc(viocd_err_table, we.sub_result);
-		printk(VIOCD_KERN_WARNING "bad rc %d:0x%04X on getinfo: %s\n",
-				we.rc, we.sub_result, err->msg);
-		goto error_ret;
-	}
-
-	for (i = 0; (i < VIOCD_MAX_CD) && viocd_unitinfo[i].rsrcname[0]; i++) {
-		viocd_diskinfo[viocd_numdev].unitinfo = viocd_unitinfo[i];
-		viocd_numdev++;
-	}
-
-error_ret:
-	iseries_hv_free(sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
-			viocd_unitinfo, unitinfo_dmaaddr);
-}
-
 static int viocd_open(struct cdrom_device_info *cdi, int purpose)
 {
         struct disk_info *diskinfo = cdi->handle;
@@ -576,7 +493,6 @@ static void vio_handle_cd_event(struct HvLpEvent *event)
 					bevent->block_size / 512);
 		}
 		/* FALLTHROUGH !! */
-	case viocdgetinfo:
 	case viocdlockdoor:
 		pwe = (struct viocd_waitevent *)event->xCorrelationToken;
 return_complete:
@@ -660,22 +576,30 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id)
 	int deviceno;
 	struct disk_info *d;
 	struct cdrom_device_info *c;
-	struct cdrom_info *ci;
 	struct request_queue *q;
+	struct device_node *node = vdev->dev.archdata.of_node;
 
 	deviceno = vdev->unit_address;
-	if (deviceno >= viocd_numdev)
+	if (deviceno > VIOCD_MAX_CD)
 		return -ENODEV;
+	if (!node)
+		return -ENODEV;
+
+	if (deviceno >= viocd_numdev)
+		viocd_numdev = deviceno + 1;
 
 	d = &viocd_diskinfo[deviceno];
+	d->rsrcname = of_get_property(node, "linux,vio_rsrcname", NULL);
+	d->type = of_get_property(node, "linux,vio_type", NULL);
+	d->model = of_get_property(node, "linux,vio_model", NULL);
+
 	c = &d->viocd_info;
-	ci = &d->unitinfo;
 
 	c->ops = &viocd_dops;
 	c->speed = 4;
 	c->capacity = 1;
 	c->handle = d;
-	c->mask = ~find_capability(ci->type);
+	c->mask = ~find_capability(d->type);
 	sprintf(c->name, VIOCD_DEVICE "%c", 'a' + deviceno);
 
 	if (register_cdrom(c) != 0) {
@@ -685,7 +609,7 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id)
 	}
 	printk(VIOCD_KERN_INFO "cd %s is iSeries resource %10.10s "
 			"type %4.4s, model %3.3s\n",
-			c->name, ci->rsrcname, ci->type, ci->model);
+			c->name, d->rsrcname, d->type, d->model);
 	q = blk_init_queue(do_viocd_request, &viocd_reqlock);
 	if (q == NULL) {
 		printk(VIOCD_KERN_WARNING "Cannot allocate queue for %s!\n",
@@ -794,8 +718,6 @@ static int __init viocd_init(void)
 	/* Initialize our request handler */
 	vio_setHandler(viomajorsubtype_cdio, vio_handle_cd_event);
 
-	get_viocd_info();
-
 	spin_lock_init(&viocd_reqlock);
 
 	ret = vio_register_driver(&viocd_driver);
diff --git a/include/asm-powerpc/iseries/vio.h b/include/asm-powerpc/iseries/vio.h
index 5a5cd0f..e5a405b 100644
--- a/include/asm-powerpc/iseries/vio.h
+++ b/include/asm-powerpc/iseries/vio.h
@@ -51,6 +51,30 @@
  */
 #define VIO_MAX_SUBTYPES 8
 
+struct viocdlpevent {
+	struct HvLpEvent	event;
+	u32			reserved;
+	u16			version;
+	u16			sub_result;
+	u16			disk;
+	u16			flags;
+	u32			token;
+	u64			offset;		/* On open, max number of disks */
+	u64			len;		/* On open, size of the disk */
+	u32			block_size;	/* Only set on open */
+	u32			media_size;	/* Only set on open */
+};
+
+enum viocdsubtype {
+	viocdopen = 0x0001,
+	viocdclose = 0x0002,
+	viocdread = 0x0003,
+	viocdwrite = 0x0004,
+	viocdlockdoor = 0x0005,
+	viocdgetinfo = 0x0006,
+	viocdcheck = 0x0007
+};
+
 /*
  * Each subtype can register a handler to process their events.
  * The handler must have this interface.
-- 
1.5.3.4

^ permalink raw reply related

* [PATCH 4/7] [POWERPC] Remove more iSeries specific stuff from vio.c
From: Stephen Rothwell @ 2007-10-11  4:55 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev
In-Reply-To: <20071011145332.e3638c2e.sfr@canb.auug.org.au>


Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 arch/powerpc/kernel/vio.c              |   78 ++++++++++---------------------
 arch/powerpc/platforms/iseries/iommu.c |   24 +++++++++-
 include/asm-powerpc/iseries/iommu.h    |    4 ++
 3 files changed, 52 insertions(+), 54 deletions(-)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index eaf7f69..b7c9e44 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -48,61 +48,33 @@ static struct vio_dev vio_bus_device  = { /* fake "parent" device */
 	.dev.bus = &vio_bus_type,
 };
 
-#ifdef CONFIG_PPC_ISERIES
-static struct iommu_table veth_iommu_table;
-struct iommu_table vio_iommu_table;
-
-static void __init iommu_vio_init(void)
-{
-	iommu_table_getparms_iSeries(255, 0, 0xff, &veth_iommu_table);
-	veth_iommu_table.it_size /= 2;
-	vio_iommu_table = veth_iommu_table;
-	vio_iommu_table.it_offset += veth_iommu_table.it_size;
-
-	if (!iommu_init_table(&veth_iommu_table, -1))
-		printk("Virtual Bus VETH TCE table failed.\n");
-	if (!iommu_init_table(&vio_iommu_table, -1))
-		printk("Virtual Bus VIO TCE table failed.\n");
-}
-#else
-static void __init iommu_vio_init(void)
-{
-}
-#endif
-
 static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
 {
-#ifdef CONFIG_PPC_ISERIES
-	if (firmware_has_feature(FW_FEATURE_ISERIES)) {
-		if (strcmp(dev->type, "network") == 0)
-			return &veth_iommu_table;
-		return &vio_iommu_table;
-	} else
-#endif
-	{
-		const unsigned char *dma_window;
-		struct iommu_table *tbl;
-		unsigned long offset, size;
-
-		dma_window = of_get_property(dev->dev.archdata.of_node,
-					  "ibm,my-dma-window", NULL);
-		if (!dma_window)
-			return NULL;
-
-		tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
-
-		of_parse_dma_window(dev->dev.archdata.of_node, dma_window,
-				    &tbl->it_index, &offset, &size);
-
-		/* TCE table size - measured in tce entries */
-		tbl->it_size = size >> IOMMU_PAGE_SHIFT;
-		/* offset for VIO should always be 0 */
-		tbl->it_offset = offset >> IOMMU_PAGE_SHIFT;
-		tbl->it_busno = 0;
-		tbl->it_type = TCE_VB;
-
-		return iommu_init_table(tbl, -1);
-	}
+	const unsigned char *dma_window;
+	struct iommu_table *tbl;
+	unsigned long offset, size;
+
+	if (firmware_has_feature(FW_FEATURE_ISERIES))
+		return vio_build_iommu_table_iseries(dev);
+
+	dma_window = of_get_property(dev->dev.archdata.of_node,
+				  "ibm,my-dma-window", NULL);
+	if (!dma_window)
+		return NULL;
+
+	tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
+
+	of_parse_dma_window(dev->dev.archdata.of_node, dma_window,
+			    &tbl->it_index, &offset, &size);
+
+	/* TCE table size - measured in tce entries */
+	tbl->it_size = size >> IOMMU_PAGE_SHIFT;
+	/* offset for VIO should always be 0 */
+	tbl->it_offset = offset >> IOMMU_PAGE_SHIFT;
+	tbl->it_busno = 0;
+	tbl->it_type = TCE_VB;
+
+	return iommu_init_table(tbl, -1);
 }
 
 /**
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index 3281f10..49e9c66 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 
 #include <asm/iommu.h>
+#include <asm/vio.h>
 #include <asm/tce.h>
 #include <asm/machdep.h>
 #include <asm/abs_addr.h>
@@ -191,7 +192,8 @@ void iommu_devnode_init_iSeries(struct pci_dev *pdev, struct device_node *dn)
 }
 #endif
 
-extern struct iommu_table vio_iommu_table;
+static struct iommu_table veth_iommu_table;
+static struct iommu_table vio_iommu_table;
 
 void *iseries_hv_alloc(size_t size, dma_addr_t *dma_handle, gfp_t flag)
 {
@@ -219,6 +221,26 @@ void iseries_hv_unmap(dma_addr_t dma_handle, size_t size,
 	iommu_unmap_single(&vio_iommu_table, dma_handle, size, direction);
 }
 
+void __init iommu_vio_init(void)
+{
+	iommu_table_getparms_iSeries(255, 0, 0xff, &veth_iommu_table);
+	veth_iommu_table.it_size /= 2;
+	vio_iommu_table = veth_iommu_table;
+	vio_iommu_table.it_offset += veth_iommu_table.it_size;
+
+	if (!iommu_init_table(&veth_iommu_table, -1))
+		printk("Virtual Bus VETH TCE table failed.\n");
+	if (!iommu_init_table(&vio_iommu_table, -1))
+		printk("Virtual Bus VIO TCE table failed.\n");
+}
+
+struct iommu_table *vio_build_iommu_table_iseries(struct vio_dev *dev)
+{
+	if (strcmp(dev->type, "network") == 0)
+		return &veth_iommu_table;
+	return &vio_iommu_table;
+}
+
 void iommu_init_early_iSeries(void)
 {
 	ppc_md.tce_build = tce_build_iSeries;
diff --git a/include/asm-powerpc/iseries/iommu.h b/include/asm-powerpc/iseries/iommu.h
index 6e323a1..c59ee7e 100644
--- a/include/asm-powerpc/iseries/iommu.h
+++ b/include/asm-powerpc/iseries/iommu.h
@@ -22,6 +22,7 @@
  */
 
 struct pci_dev;
+struct vio_dev;
 struct device_node;
 struct iommu_table;
 
@@ -34,4 +35,7 @@ extern void iommu_table_getparms_iSeries(unsigned long busno,
 		unsigned char slotno, unsigned char virtbus,
 		struct iommu_table *tbl);
 
+extern struct iommu_table *vio_build_iommu_table_iseries(struct vio_dev *dev);
+extern void iommu_vio_init(void);
+
 #endif /* _ASM_POWERPC_ISERIES_IOMMU_H */
-- 
1.5.3.4

^ permalink raw reply related

* [PATCH 3/7] [POWERPC] remove iSeries_vio_dev
From: Stephen Rothwell @ 2007-10-11  4:53 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev, Jens Axboe
In-Reply-To: <20071011145055.1de13742.sfr@canb.auug.org.au>

It was only being used to carry around dma_iommu_ops and vio_iommu_table
which we can use directly instead.  This also means that vio_bus_device
doesn't need to refer to them either.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Acked-by: Jens Axboe <jens.axboe@oracle.com>
---
 arch/powerpc/kernel/vio.c                   |    7 +-----
 arch/powerpc/platforms/iseries/iommu.c      |   30 +++++++++++++++++++++++++++
 arch/powerpc/platforms/iseries/mf.c         |   23 ++++++++------------
 arch/powerpc/platforms/iseries/viopath.c    |    6 +---
 drivers/cdrom/viocd.c                       |    5 +--
 drivers/char/viotape.c                      |    7 ++---
 include/asm-powerpc/iseries/hv_call_event.h |   10 +++++++++
 include/asm-powerpc/iseries/vio.h           |    4 ---
 8 files changed, 57 insertions(+), 35 deletions(-)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index fd631d4..eaf7f69 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -49,11 +49,8 @@ static struct vio_dev vio_bus_device  = { /* fake "parent" device */
 };
 
 #ifdef CONFIG_PPC_ISERIES
-struct device *iSeries_vio_dev = &vio_bus_device.dev;
-EXPORT_SYMBOL(iSeries_vio_dev);
-
 static struct iommu_table veth_iommu_table;
-static struct iommu_table vio_iommu_table;
+struct iommu_table vio_iommu_table;
 
 static void __init iommu_vio_init(void)
 {
@@ -66,8 +63,6 @@ static void __init iommu_vio_init(void)
 		printk("Virtual Bus VETH TCE table failed.\n");
 	if (!iommu_init_table(&vio_iommu_table, -1))
 		printk("Virtual Bus VIO TCE table failed.\n");
-	vio_bus_device.dev.archdata.dma_ops = &dma_iommu_ops;
-	vio_bus_device.dev.archdata.dma_data = &vio_iommu_table;
 }
 #else
 static void __init iommu_vio_init(void)
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index 3b6a966..3281f10 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -28,6 +28,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/list.h>
 #include <linux/pci.h>
+#include <linux/module.h>
 
 #include <asm/iommu.h>
 #include <asm/tce.h>
@@ -36,6 +37,7 @@
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #include <asm/iseries/hv_call_xm.h>
+#include <asm/iseries/hv_call_event.h>
 #include <asm/iseries/iommu.h>
 
 static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,
@@ -189,6 +191,34 @@ void iommu_devnode_init_iSeries(struct pci_dev *pdev, struct device_node *dn)
 }
 #endif
 
+extern struct iommu_table vio_iommu_table;
+
+void *iseries_hv_alloc(size_t size, dma_addr_t *dma_handle, gfp_t flag)
+{
+	return iommu_alloc_coherent(&vio_iommu_table, size, dma_handle,
+				DMA_32BIT_MASK, flag, -1);
+}
+EXPORT_SYMBOL_GPL(iseries_hv_alloc);
+
+void iseries_hv_free(size_t size, void *vaddr, dma_addr_t dma_handle)
+{
+	iommu_free_coherent(&vio_iommu_table, size, vaddr, dma_handle);
+}
+EXPORT_SYMBOL_GPL(iseries_hv_free);
+
+dma_addr_t iseries_hv_map(void *vaddr, size_t size,
+			enum dma_data_direction direction)
+{
+	return iommu_map_single(&vio_iommu_table, vaddr, size,
+				DMA_32BIT_MASK, direction);
+}
+
+void iseries_hv_unmap(dma_addr_t dma_handle, size_t size,
+			enum dma_data_direction direction)
+{
+	iommu_unmap_single(&vio_iommu_table, dma_handle, size, direction);
+}
+
 void iommu_init_early_iSeries(void)
 {
 	ppc_md.tce_build = tce_build_iSeries;
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c
index b1187d9..c0f2433 100644
--- a/arch/powerpc/platforms/iseries/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -39,9 +39,9 @@
 #include <asm/paca.h>
 #include <asm/abs_addr.h>
 #include <asm/firmware.h>
-#include <asm/iseries/vio.h>
 #include <asm/iseries/mf.h>
 #include <asm/iseries/hv_lp_config.h>
+#include <asm/iseries/hv_lp_event.h>
 #include <asm/iseries/it_lp_queue.h>
 
 #include "setup.h"
@@ -870,8 +870,7 @@ static int proc_mf_dump_cmdline(char *page, char **start, off_t off,
 	if ((off + count) > 256)
 		count = 256 - off;
 
-	dma_addr = dma_map_single(iSeries_vio_dev, page, off + count,
-			DMA_FROM_DEVICE);
+	dma_addr = iseries_hv_map(page, off + count, DMA_FROM_DEVICE);
 	if (dma_mapping_error(dma_addr))
 		return -ENOMEM;
 	memset(page, 0, off + count);
@@ -883,8 +882,7 @@ static int proc_mf_dump_cmdline(char *page, char **start, off_t off,
 	vsp_cmd.sub_data.kern.length = off + count;
 	mb();
 	rc = signal_vsp_instruction(&vsp_cmd);
-	dma_unmap_single(iSeries_vio_dev, dma_addr, off + count,
-			DMA_FROM_DEVICE);
+	iseries_hv_unmap(dma_addr, off + count, DMA_FROM_DEVICE);
 	if (rc)
 		return rc;
 	if (vsp_cmd.result_code != 0)
@@ -919,8 +917,7 @@ static int mf_getVmlinuxChunk(char *buffer, int *size, int offset, u64 side)
 	int len = *size;
 	dma_addr_t dma_addr;
 
-	dma_addr = dma_map_single(iSeries_vio_dev, buffer, len,
-			DMA_FROM_DEVICE);
+	dma_addr = iseries_hv_map(buffer, len, DMA_FROM_DEVICE);
 	memset(buffer, 0, len);
 	memset(&vsp_cmd, 0, sizeof(vsp_cmd));
 	vsp_cmd.cmd = 32;
@@ -938,7 +935,7 @@ static int mf_getVmlinuxChunk(char *buffer, int *size, int offset, u64 side)
 			rc = -ENOMEM;
 	}
 
-	dma_unmap_single(iSeries_vio_dev, dma_addr, len, DMA_FROM_DEVICE);
+	iseries_hv_unmap(dma_addr, len, DMA_FROM_DEVICE);
 
 	return rc;
 }
@@ -1149,8 +1146,7 @@ static int proc_mf_change_cmdline(struct file *file, const char __user *buffer,
 		goto out;
 
 	dma_addr = 0;
-	page = dma_alloc_coherent(iSeries_vio_dev, count, &dma_addr,
-			GFP_ATOMIC);
+	page = iseries_hv_alloc(count, &dma_addr, GFP_ATOMIC);
 	ret = -ENOMEM;
 	if (page == NULL)
 		goto out;
@@ -1170,7 +1166,7 @@ static int proc_mf_change_cmdline(struct file *file, const char __user *buffer,
 	ret = count;
 
 out_free:
-	dma_free_coherent(iSeries_vio_dev, count, page, dma_addr);
+	iseries_hv_free(count, page, dma_addr);
 out:
 	return ret;
 }
@@ -1190,8 +1186,7 @@ static ssize_t proc_mf_change_vmlinux(struct file *file,
 		goto out;
 
 	dma_addr = 0;
-	page = dma_alloc_coherent(iSeries_vio_dev, count, &dma_addr,
-			GFP_ATOMIC);
+	page = iseries_hv_alloc(count, &dma_addr, GFP_ATOMIC);
 	rc = -ENOMEM;
 	if (page == NULL) {
 		printk(KERN_ERR "mf.c: couldn't allocate memory to set vmlinux chunk\n");
@@ -1219,7 +1214,7 @@ static ssize_t proc_mf_change_vmlinux(struct file *file,
 	*ppos += count;
 	rc = count;
 out_free:
-	dma_free_coherent(iSeries_vio_dev, count, page, dma_addr);
+	iseries_hv_free(count, page, dma_addr);
 out:
 	return rc;
 }
diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c
index 45f2fe3..df23331 100644
--- a/arch/powerpc/platforms/iseries/viopath.c
+++ b/arch/powerpc/platforms/iseries/viopath.c
@@ -124,8 +124,7 @@ static int proc_viopath_show(struct seq_file *m, void *v)
 	if (!buf)
 		return 0;
 
-	handle = dma_map_single(iSeries_vio_dev, buf, HW_PAGE_SIZE,
-				DMA_FROM_DEVICE);
+	handle = iseries_hv_map(buf, HW_PAGE_SIZE, DMA_FROM_DEVICE);
 
 	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
 			HvLpEvent_Type_VirtualIo,
@@ -146,8 +145,7 @@ static int proc_viopath_show(struct seq_file *m, void *v)
 	buf[HW_PAGE_SIZE-1] = '\0';
 	seq_printf(m, "%s", buf);
 
-	dma_unmap_single(iSeries_vio_dev, handle, HW_PAGE_SIZE,
-			 DMA_FROM_DEVICE);
+	iseries_hv_unmap(handle, HW_PAGE_SIZE, DMA_FROM_DEVICE);
 	kfree(buf);
 
 	seq_printf(m, "AVAILABLE_VETH=%x\n", vlanMap);
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index b88fdeb..c081e54 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -220,7 +220,7 @@ static void __init get_viocd_info(void)
 	struct cdrom_info *viocd_unitinfo;
 	dma_addr_t unitinfo_dmaaddr;
 
-	viocd_unitinfo = dma_alloc_coherent(iSeries_vio_dev,
+	viocd_unitinfo = iseries_hv_alloc(
 			sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
 			&unitinfo_dmaaddr, GFP_ATOMIC);
 	if (viocd_unitinfo == NULL) {
@@ -262,8 +262,7 @@ static void __init get_viocd_info(void)
 	}
 
 error_ret:
-	dma_free_coherent(iSeries_vio_dev,
-			sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
+	iseries_hv_free(sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
 			viocd_unitinfo, unitinfo_dmaaddr);
 }
 
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index e12275d..064c091 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -392,8 +392,8 @@ static int get_viotape_info(void)
 	if (op == NULL)
 		return -ENOMEM;
 
-	viotape_unitinfo = dma_alloc_coherent(iSeries_vio_dev, len,
-		&viotape_unitinfo_token, GFP_ATOMIC);
+	viotape_unitinfo = iseries_hv_alloc(len, &viotape_unitinfo_token,
+		GFP_ATOMIC);
 	if (viotape_unitinfo == NULL) {
 		free_op_struct(op);
 		return -ENOMEM;
@@ -1103,8 +1103,7 @@ static void __exit viotap_exit(void)
 	class_destroy(tape_class);
 	unregister_chrdev(VIOTAPE_MAJOR, "viotape");
 	if (viotape_unitinfo)
-		dma_free_coherent(iSeries_vio_dev,
-				sizeof(viotape_unitinfo[0]) * VIOTAPE_MAX_TAPE,
+		iseries_hv_free(sizeof(viotape_unitinfo[0]) * VIOTAPE_MAX_TAPE,
 				viotape_unitinfo, viotape_unitinfo_token);
 	viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2);
 	vio_clearHandler(viomajorsubtype_tape);
diff --git a/include/asm-powerpc/iseries/hv_call_event.h b/include/asm-powerpc/iseries/hv_call_event.h
index 4cec476..cc029d3 100644
--- a/include/asm-powerpc/iseries/hv_call_event.h
+++ b/include/asm-powerpc/iseries/hv_call_event.h
@@ -21,6 +21,9 @@
 #ifndef _ASM_POWERPC_ISERIES_HV_CALL_EVENT_H
 #define _ASM_POWERPC_ISERIES_HV_CALL_EVENT_H
 
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+
 #include <asm/iseries/hv_call_sc.h>
 #include <asm/iseries/hv_types.h>
 #include <asm/abs_addr.h>
@@ -113,6 +116,13 @@ static inline HvLpEvent_Rc HvCallEvent_signalLpEventFast(HvLpIndex targetLp,
 			eventData3, eventData4, eventData5);
 }
 
+extern void *iseries_hv_alloc(size_t size, dma_addr_t *dma_handle, gfp_t flag);
+extern void iseries_hv_free(size_t size, void *vaddr, dma_addr_t dma_handle);
+extern dma_addr_t iseries_hv_map(void *vaddr, size_t size,
+			enum dma_data_direction direction);
+extern void iseries_hv_unmap(dma_addr_t dma_handle, size_t size,
+			enum dma_data_direction direction);
+
 static inline HvLpEvent_Rc HvCallEvent_ackLpEvent(struct HvLpEvent *event)
 {
 	return HvCall1(HvCallEventAckLpEvent, virt_to_abs(event));
diff --git a/include/asm-powerpc/iseries/vio.h b/include/asm-powerpc/iseries/vio.h
index 7a95d29..5a5cd0f 100644
--- a/include/asm-powerpc/iseries/vio.h
+++ b/include/asm-powerpc/iseries/vio.h
@@ -150,8 +150,4 @@ enum viochar_rc {
 	viochar_rc_ebusy = 1
 };
 
-struct device;
-
-extern struct device *iSeries_vio_dev;
-
 #endif /* _ASM_POWERPC_ISERIES_VIO_H */
-- 
1.5.3.4

^ permalink raw reply related

* [PATCH 2/7] [POWERPC] iSeries: simplify viocd initialisation
From: Stephen Rothwell @ 2007-10-11  4:50 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev, Jens Axboe
In-Reply-To: <20071011144824.a5e3de59.sfr@canb.auug.org.au>

We don't need to keep a lump of dma coherent memory around for the life
of the module.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Acked-by: Jens Axboe <jens.axboe@oracle.com>
---
 drivers/cdrom/viocd.c |   37 +++++++++++++------------------------
 1 files changed, 13 insertions(+), 24 deletions(-)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index e51550d..b88fdeb 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -136,17 +136,12 @@ struct cdrom_info {
 	char	type[4];
 	char	model[3];
 };
-/*
- * This needs to be allocated since it is passed to the
- * Hypervisor and we may be a module.
- */
-static struct cdrom_info *viocd_unitinfo;
-static dma_addr_t unitinfo_dmaaddr;
 
 struct disk_info {
 	struct gendisk			*viocd_disk;
 	struct cdrom_device_info	viocd_info;
 	struct device			*dev;
+	struct cdrom_info		unitinfo;
 };
 static struct disk_info viocd_diskinfo[VIOCD_MAX_CD];
 
@@ -164,9 +159,9 @@ static int proc_viocd_show(struct seq_file *m, void *v)
 	for (i = 0; i < viocd_numdev; i++) {
 		seq_printf(m, "viocd device %d is iSeries resource %10.10s"
 				"type %4.4s, model %3.3s\n",
-				i, viocd_unitinfo[i].rsrcname,
-				viocd_unitinfo[i].type,
-				viocd_unitinfo[i].model);
+				i, viocd_diskinfo[i].unitinfo.rsrcname,
+				viocd_diskinfo[i].unitinfo.type,
+				viocd_diskinfo[i].unitinfo.model);
 	}
 	return 0;
 }
@@ -222,6 +217,8 @@ static void __init get_viocd_info(void)
 	HvLpEvent_Rc hvrc;
 	int i;
 	struct viocd_waitevent we;
+	struct cdrom_info *viocd_unitinfo;
+	dma_addr_t unitinfo_dmaaddr;
 
 	viocd_unitinfo = dma_alloc_coherent(iSeries_vio_dev,
 			sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
@@ -259,16 +256,15 @@ static void __init get_viocd_info(void)
 		goto error_ret;
 	}
 
-	for (i = 0; (i < VIOCD_MAX_CD) && viocd_unitinfo[i].rsrcname[0]; i++)
+	for (i = 0; (i < VIOCD_MAX_CD) && viocd_unitinfo[i].rsrcname[0]; i++) {
+		viocd_diskinfo[viocd_numdev].unitinfo = viocd_unitinfo[i];
 		viocd_numdev++;
+	}
 
 error_ret:
-	if (viocd_numdev == 0) {
-		dma_free_coherent(iSeries_vio_dev,
-				sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
-				viocd_unitinfo, unitinfo_dmaaddr);
-		viocd_unitinfo = NULL;
-	}
+	dma_free_coherent(iSeries_vio_dev,
+			sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
+			viocd_unitinfo, unitinfo_dmaaddr);
 }
 
 static int viocd_open(struct cdrom_device_info *cdi, int purpose)
@@ -674,7 +670,7 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id)
 
 	d = &viocd_diskinfo[deviceno];
 	c = &d->viocd_info;
-	ci = &viocd_unitinfo[deviceno];
+	ci = &d->unitinfo;
 
 	c->ops = &viocd_dops;
 	c->speed = 4;
@@ -816,9 +812,6 @@ static int __init viocd_init(void)
 	return 0;
 
 out_free_info:
-	dma_free_coherent(iSeries_vio_dev,
-			sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
-			viocd_unitinfo, unitinfo_dmaaddr);
 	vio_clearHandler(viomajorsubtype_cdio);
 	viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2);
 out_unregister:
@@ -830,10 +823,6 @@ static void __exit viocd_exit(void)
 {
 	remove_proc_entry("iSeries/viocd", NULL);
 	vio_unregister_driver(&viocd_driver);
-	if (viocd_unitinfo != NULL)
-		dma_free_coherent(iSeries_vio_dev,
-				sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
-				viocd_unitinfo, unitinfo_dmaaddr);
 	viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2);
 	vio_clearHandler(viomajorsubtype_cdio);
 	unregister_blkdev(VIOCD_MAJOR, VIOCD_DEVICE);
-- 
1.5.3.4

^ permalink raw reply related

* [PATCH 1/7] [POWERPC] Clean up vio.h
From: Stephen Rothwell @ 2007-10-11  4:48 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev

Remove vio_dma_ops declaration (since it no longer exists) and some
unused fields from struct vio_driver.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 arch/powerpc/kernel/vio.c |   11 -----------
 include/asm-powerpc/vio.h |    5 -----
 2 files changed, 0 insertions(+), 16 deletions(-)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 1d7b272..fd631d4 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -168,16 +168,6 @@ static int vio_bus_remove(struct device *dev)
 	return 1;
 }
 
-/* convert from struct device to struct vio_dev and pass to driver. */
-static void vio_bus_shutdown(struct device *dev)
-{
-	struct vio_dev *viodev = to_vio_dev(dev);
-	struct vio_driver *viodrv = to_vio_driver(dev->driver);
-
-	if (dev->driver && viodrv->shutdown)
-		viodrv->shutdown(viodev);
-}
-
 /**
  * vio_register_driver: - Register a new vio driver
  * @drv:	The vio_driver structure to be registered.
@@ -397,7 +387,6 @@ static struct bus_type vio_bus_type = {
 	.match = vio_bus_match,
 	.probe = vio_bus_probe,
 	.remove = vio_bus_remove,
-	.shutdown = vio_bus_shutdown,
 };
 
 /**
diff --git a/include/asm-powerpc/vio.h b/include/asm-powerpc/vio.h
index 598d111..9204c15 100644
--- a/include/asm-powerpc/vio.h
+++ b/include/asm-powerpc/vio.h
@@ -53,17 +53,12 @@ struct vio_dev {
 };
 
 struct vio_driver {
-	struct list_head node;
 	const struct vio_device_id *id_table;
 	int (*probe)(struct vio_dev *dev, const struct vio_device_id *id);
 	int (*remove)(struct vio_dev *dev);
-	void (*shutdown)(struct vio_dev *dev);
-	unsigned long driver_data;
 	struct device_driver driver;
 };
 
-extern struct dma_mapping_ops vio_dma_ops;
-
 extern int vio_register_driver(struct vio_driver *drv);
 extern void vio_unregister_driver(struct vio_driver *drv);
 
-- 
1.5.3.4

^ permalink raw reply related

* Re: [PATCH] Device tree bindings for Xilinx devices
From: Grant Likely @ 2007-10-11  4:58 UTC (permalink / raw)
  To: Josh Boyer, linuxppc-dev
In-Reply-To: <20071011042441.GG14873@localhost.localdomain>

On 10/10/07, David Gibson <dwg@au1.ibm.com> wrote:
> On Wed, Oct 10, 2007 at 10:18:50PM -0600, Grant Likely wrote:
> > On 10/10/07, David Gibson <dwg@au1.ibm.com> wrote:
> > > On Wed, Oct 10, 2007 at 08:25:36PM -0600, Grant Likely wrote:
> > > > On 10/10/07, David Gibson <dwg@au1.ibm.com> wrote:
> > > > > We've used 'cell-index' for similar purposes on other 4xx.
> > > >
> > > > Unfortunately, 'cell' has been used in the sense of a logic cell in an
> > > > SoC.  In the case of the SystemACE, it is an external chip.
> > > >
> > > > What about "device-number"?
> > >
> > > Ok, I misunderstood.  If it's not on chip, what significance does this
> > > serial number have?  Where would a driver need it?
> >
> > If there were 2 systemace devices on board; one attached to a CF slot
> > labeled "1" and the other to one labeled "2".  :-)  Same problem as
> > lining up serial device files to physical port numbers.
> >
> > The driver doesn't technically need it, but the information does need
> > to flow through to the creation of logically numbered device files.
>
> Ah.  Then, I'm afraid it doesn't belong in the core binding.
>
> Preferably, you should just figure out something without help of this
> property - plenty of other things have to figure out device names
> without assistance like this.

I'm not too stuck on the method used, but I do think it is appropriate
to encode this kind of data in the device tree in some form...
However, for this particular device I'm probably just borrowing
trouble.  I'll drop the property.

My main concern is that I don't like the implicit numbering that
occurs simply based on the order of devices in the device tree.  If
the probe algorithm ever changes to parse in reverse order or
something reorders the tree, then the device numbers also change.  :-(

I'd rather be explicit.  In fact I've already been bitten by this
where the mpc5200 has 6 PSC, each of which can be configured as a
serial port.  However, I've got access to 3 different boards; each of
which has the logical port numbers 100% unrelated to the 'cell'
number.

> If you really must you could do this in analogy with the
> "linux,network-index" property - but this would be, as that is, an
> ugly hack, and should be recognized as such
>
> Segher's suggestion of using OF-style aliases for this is a fairly
> good one, actually.  I just need to get to implementing it...

/me needs to look up what that look like and how I would use it.  My
knowledge of OF is sadly lacking.

Cheers,
g.

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

^ permalink raw reply

* Re: [PATCH] Device tree bindings for Xilinx devices
From: David Gibson @ 2007-10-11  4:24 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <fa686aa40710102118p3e62d06eqff8db252772eb58c@mail.gmail.com>

On Wed, Oct 10, 2007 at 10:18:50PM -0600, Grant Likely wrote:
> On 10/10/07, David Gibson <dwg@au1.ibm.com> wrote:
> > On Wed, Oct 10, 2007 at 08:25:36PM -0600, Grant Likely wrote:
> > > On 10/10/07, David Gibson <dwg@au1.ibm.com> wrote:
> > > > We've used 'cell-index' for similar purposes on other 4xx.
> > >
> > > Unfortunately, 'cell' has been used in the sense of a logic cell in an
> > > SoC.  In the case of the SystemACE, it is an external chip.
> > >
> > > What about "device-number"?
> >
> > Ok, I misunderstood.  If it's not on chip, what significance does this
> > serial number have?  Where would a driver need it?
> 
> If there were 2 systemace devices on board; one attached to a CF slot
> labeled "1" and the other to one labeled "2".  :-)  Same problem as
> lining up serial device files to physical port numbers.
> 
> The driver doesn't technically need it, but the information does need
> to flow through to the creation of logically numbered device files.

Ah.  Then, I'm afraid it doesn't belong in the core binding.

Preferably, you should just figure out something without help of this
property - plenty of other things have to figure out device names
without assistance like this.

If you really must you could do this in analogy with the
"linux,network-index" property - but this would be, as that is, an
ugly hack, and should be recognized as such.

Segher's suggestion of using OF-style aliases for this is a fairly
good one, actually.  I just need to get to implementing it...

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: [PATCH] Device tree bindings for Xilinx devices
From: Grant Likely @ 2007-10-11  4:18 UTC (permalink / raw)
  To: Grant Likely, Josh Boyer, linuxppc-dev
In-Reply-To: <20071011040622.GE14873@localhost.localdomain>

On 10/10/07, David Gibson <dwg@au1.ibm.com> wrote:
> On Wed, Oct 10, 2007 at 08:25:36PM -0600, Grant Likely wrote:
> > On 10/10/07, David Gibson <dwg@au1.ibm.com> wrote:
> > > We've used 'cell-index' for similar purposes on other 4xx.
> >
> > Unfortunately, 'cell' has been used in the sense of a logic cell in an
> > SoC.  In the case of the SystemACE, it is an external chip.
> >
> > What about "device-number"?
>
> Ok, I misunderstood.  If it's not on chip, what significance does this
> serial number have?  Where would a driver need it?

If there were 2 systemace devices on board; one attached to a CF slot
labeled "1" and the other to one labeled "2".  :-)  Same problem as
lining up serial device files to physical port numbers.

The driver doesn't technically need it, but the information does need
to flow through to the creation of logically numbered device files.

Cheers,
g.

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

^ permalink raw reply

* Re: [PATCH] Device tree bindings for Xilinx devices
From: David Gibson @ 2007-10-11  4:06 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <fa686aa40710101925x6b005aa7paaeb072ba492c81f@mail.gmail.com>

On Wed, Oct 10, 2007 at 08:25:36PM -0600, Grant Likely wrote:
> On 10/10/07, David Gibson <dwg@au1.ibm.com> wrote:
> > On Wed, Oct 10, 2007 at 03:38:02PM -0500, Josh Boyer wrote:
[snip]
> > > "number" seems a bit to generic to me.  logical-number seems a bit more
> > > descriptive.
> >
> > We've used 'cell-index' for similar purposes on other 4xx.
> 
> Unfortunately, 'cell' has been used in the sense of a logic cell in an
> SoC.  In the case of the SystemACE, it is an external chip.
> 
> What about "device-number"?

Ok, I misunderstood.  If it's not on chip, what significance does this
serial number have?  Where would a driver need it?

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: [PATCH] Device tree bindings for Xilinx devices
From: Grant Likely @ 2007-10-11  2:25 UTC (permalink / raw)
  To: Josh Boyer, Grant Likely, linuxppc-dev
In-Reply-To: <20071011013817.GB14873@localhost.localdomain>

On 10/10/07, David Gibson <dwg@au1.ibm.com> wrote:
> On Wed, Oct 10, 2007 at 03:38:02PM -0500, Josh Boyer wrote:
> > On Mon, 2007-10-08 at 01:53 -0600, Grant Likely wrote:
> > > From: Grant Likely <grant.likely@secretlab.ca>
> > >
> > > Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> > > ---
> > >
> > > This is a first draft, please review and comment.
> >
> > I'll start off with the fact that I hardly consider myself a DT expert,
> > so take what I say with a grain of salt.
> >
> > > On a side node, I think booting-without-of.txt could get really unwieldly
> > > in the near future.  Perhaps the device tree bindings should be organized
> > > differently and separated from the functional description of device tree
> > > usage.  Thoughts?
> > >
> > > Cheers,
> > > g.
> > >
> > >  Documentation/powerpc/booting-without-of.txt |   58 ++++++++++++++++++++++++++
> > >  1 files changed, 58 insertions(+), 0 deletions(-)
> > >
> > > diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
> > > index 20e0e6c..a6d6056 100644
> > > --- a/Documentation/powerpc/booting-without-of.txt
> > > +++ b/Documentation/powerpc/booting-without-of.txt
> > > @@ -1850,6 +1850,64 @@ platforms are moved over to use the flattened-device-tree model.
> > >
> > >     More devices will be defined as this spec matures.
> > >
> > > +   l) Xilinx ML300 Framebuffer
> > > +
> > > +   Simple framebuffer device from the ML300 reference design (also on the
> > > +   ML403 reference design as well as others).
> > > +
> > > +   Required properties:
> > > +    - compatible : Must include "xilinx,ml300-fb"
> >
> > Similarly, "xilinx,ml403-fb" will be required for ML403 correct?  Or do
> > they share exact identical implementations?
> >
> > > +    - reg : offset and length of the framebuffer register set
> > > +
> > > +   Optional properties:
> > > +    - resolution : <xres yres> pixel resolution of framebuffer.  Some
> > > +                   implementations use a different resolution.  Default
> > > +                   is <d#640 d#480>
> > > +    - virt-resolution : <xvirt yvirt> Size of framebuffer in memory.
> > > +                        Default is <d#1024 d#480>.
> > > +    - rotate-display : rotate display 180 degrees.
> > > +    - display-number : Logical number of display
> > > +
> > > +   m) Xilinx SystemACE
> > > +
> > > +   The Xilinx SystemACE device is used to program FPGAs from an FPGA
> > > +   bitstream stored on a CF card.  It can also be used as a generic CF
> > > +   interface device.
> > > +
> > > +   Required properties:
> > > +    - compatible : Must include "xilinx,sysace"
> > > +    - reg : offset and length of SystemACE register set
> > > +
> > > +   Recommended properties:
> > > +    - interrupt-parent, interrupts : Connection of device irq signal.
> > > +
> > > +   Optional properties:
> > > +    - number : logical number of the SystemACE device based at 0.
> >
> > "number" seems a bit to generic to me.  logical-number seems a bit more
> > descriptive.
>
> We've used 'cell-index' for similar purposes on other 4xx.

Unfortunately, 'cell' has been used in the sense of a logic cell in an
SoC.  In the case of the SystemACE, it is an external chip.

What about "device-number"?

Cheers,
g.

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

^ permalink raw reply

* Re: [PATCH] Device tree bindings for Xilinx devices
From: David Gibson @ 2007-10-11  1:38 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <1192048682.5534.92.camel@localhost.localdomain>

On Wed, Oct 10, 2007 at 03:38:02PM -0500, Josh Boyer wrote:
> On Mon, 2007-10-08 at 01:53 -0600, Grant Likely wrote:
> > From: Grant Likely <grant.likely@secretlab.ca>
> > 
> > Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> > ---
> > 
> > This is a first draft, please review and comment.
> 
> I'll start off with the fact that I hardly consider myself a DT expert,
> so take what I say with a grain of salt.
> 
> > On a side node, I think booting-without-of.txt could get really unwieldly
> > in the near future.  Perhaps the device tree bindings should be organized
> > differently and separated from the functional description of device tree
> > usage.  Thoughts?
> > 
> > Cheers,
> > g.
> > 
> >  Documentation/powerpc/booting-without-of.txt |   58 ++++++++++++++++++++++++++
> >  1 files changed, 58 insertions(+), 0 deletions(-)
> > 
> > diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
> > index 20e0e6c..a6d6056 100644
> > --- a/Documentation/powerpc/booting-without-of.txt
> > +++ b/Documentation/powerpc/booting-without-of.txt
> > @@ -1850,6 +1850,64 @@ platforms are moved over to use the flattened-device-tree model.
> > 
> >     More devices will be defined as this spec matures.
> > 
> > +   l) Xilinx ML300 Framebuffer
> > +
> > +   Simple framebuffer device from the ML300 reference design (also on the
> > +   ML403 reference design as well as others).
> > +
> > +   Required properties:
> > +    - compatible : Must include "xilinx,ml300-fb"
> 
> Similarly, "xilinx,ml403-fb" will be required for ML403 correct?  Or do
> they share exact identical implementations?
> 
> > +    - reg : offset and length of the framebuffer register set
> > +
> > +   Optional properties:
> > +    - resolution : <xres yres> pixel resolution of framebuffer.  Some
> > +                   implementations use a different resolution.  Default
> > +                   is <d#640 d#480>
> > +    - virt-resolution : <xvirt yvirt> Size of framebuffer in memory.
> > +                        Default is <d#1024 d#480>.
> > +    - rotate-display : rotate display 180 degrees.
> > +    - display-number : Logical number of display
> > +
> > +   m) Xilinx SystemACE
> > +
> > +   The Xilinx SystemACE device is used to program FPGAs from an FPGA
> > +   bitstream stored on a CF card.  It can also be used as a generic CF
> > +   interface device.
> > +
> > +   Required properties:
> > +    - compatible : Must include "xilinx,sysace"
> > +    - reg : offset and length of SystemACE register set
> > +
> > +   Recommended properties:
> > +    - interrupt-parent, interrupts : Connection of device irq signal.
> > +
> > +   Optional properties:
> > +    - number : logical number of the SystemACE device based at 0.
> 
> "number" seems a bit to generic to me.  logical-number seems a bit more
> descriptive.

We've used 'cell-index' for similar purposes on other 4xx.

> 
> > +    - 8-bit (empty) : Set this property if the SystemACE must be in 8 bit mode
> > +
> > +   n) Xilinx EMAC and Xilinx TEMAC
> > +
> > +   Xilinx Ethernet devices.  Uses common properties from other Ethernet
> > +   devices with the following constraints:
> > +   
> > +   Required properties:
> > +    - compatible : Must include one of: "xilinx,plb-temac",
> > +                   "xilinx,plb-emac", "xilinx-opb-emac"
> 
> I think you mean "xilinx,opb-emac" on that last one.
> 
> > +    - dma-mode : Must be one of "none", "simple", "sg" (sg == scatter gather)
> > +
> > +   o) Xilinx Uartlite
> > +
> > +   Xilinx uartlite devices are simple fixed speed serial ports.  Uartlite
> > +   ports should be described in a node with the following properties.
> > +
> > +   Requred properties:
> > +    - compatible : Must include "xilinx,uartlite"
> > +    - reg : offset and length of uartlite register set
> > +
> > +    Recommended properties:
> > +    - port-number : logical port number of uartlite device based at 0.
> > +    - interrupt-parent, interrupts : Connection of device irq signal.
> > +
> 
> josh
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
> 

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: [PATCH] Bootwrapper: Enable debug info on boot wrapper
From: David Gibson @ 2007-10-11  1:34 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <fa686aa40710101256q3783994dr854e2bdecddf9820@mail.gmail.com>

On Wed, Oct 10, 2007 at 01:56:05PM -0600, Grant Likely wrote:
> Any comments on this one?  Scott?  David?

Seems reasonable AFAICT.

> On 10/3/07, Grant Likely <grant.likely@secretlab.ca> wrote:
> > From: Grant Likely <grant.likely@secretlab.ca>
> >
> > Add '-g' to BOOTCFLAGS if CONFIG_DEBUG_INFO is set.
> >
> > Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> > ---
> >
> >  arch/powerpc/boot/Makefile |    4 ++++
> >  1 files changed, 4 insertions(+), 0 deletions(-)
> >
> > diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
> > index cf80db3..9dfe79b 100644
> > --- a/arch/powerpc/boot/Makefile
> > +++ b/arch/powerpc/boot/Makefile
> > @@ -25,6 +25,10 @@ BOOTCFLAGS    := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
> >                  -isystem $(shell $(CROSS32CC) -print-file-name=include)
> >  BOOTAFLAGS     := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc
> >
> > +ifdef CONFIG_DEBUG_INFO
> > +BOOTCFLAGS     += -g
> > +endif
> > +
> >  ifeq ($(call cc-option-yn, -fstack-protector),y)
> >  BOOTCFLAGS     += -fno-stack-protector
> >  endif
> >
> > _______________________________________________
> > Linuxppc-dev mailing list
> > Linuxppc-dev@ozlabs.org
> > https://ozlabs.org/mailman/listinfo/linuxppc-dev
> >
> 
> 

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: [PATCH 4/9] add platform support for MPC837x MDS board
From: Stephen Rothwell @ 2007-10-11  1:05 UTC (permalink / raw)
  To: Li Yang; +Cc: linuxppc-dev, paulus
In-Reply-To: <1192010804-20071-4-git-send-email-leoli@freescale.com>

[-- Attachment #1: Type: text/plain, Size: 372 bytes --]

On Wed, 10 Oct 2007 18:06:39 +0800 Li Yang <leoli@freescale.com> wrote:
>
> +++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c
>
> +#include <asm/of_platform.h>

You actually neeed linux/of.h (for of_ routines) and asm/prom.h (for
of_flat_dt_is_compatible).

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ 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