On Mon, Apr 13, 2009 at 10:49 AM, Stephen Neuendorffer
<stephen.neuendorf...@xilinx.com> wrote:
>
> I think the mainline driver might (still) assume the presence of a PLB->DCR 
> bridge?

Correct.

> So there are really 4 cases:
> Core has DCR access, accessed directly using DCR.
> Core has DCR access, accessed indirectly using DCR.
> Core has DCR access, accessed through plb->dcr bridge.
> Core has PLB access.

sounds right to me.

g.

>
> Steve
>
>> -----Original Message-----
>> From: linuxppc-dev-bounces+stephen.neuendorffer=xilinx....@ozlabs.org 
>> [mailto:linuxppc-dev-
>> bounces+stephen.neuendorffer=xilinx....@ozlabs.org] On Behalf Of John Linn
>> Sent: Monday, April 13, 2009 7:13 AM
>> To: grant.lik...@secretlab.ca
>> Cc: linux-fbdev-de...@lists.sourceforge.net; adap...@gmail.com; Suneel 
>> Garapati; linuxppc-
>> d...@ozlabs.org; akonova...@ru.mvista.com
>> Subject: RE: [PATCH] [V2] Xilinx : Framebuffer Driver: Add PLB 
>> support(non-DCR)
>>
>> I thought it was based on mainline, but I now see the weirdness you're 
>> talking about.  I'll dig in on
>> this and let you know more as I'm confused also.
>>
>> -- John
>>
>> > -----Original Message-----
>> > From: Grant Likely [mailto:grant.lik...@secretlab.ca]
>> > Sent: Sunday, April 12, 2009 12:15 AM
>> > To: John Linn
>> > Cc: jwbo...@linux.vnet.ibm.com; linux-fbdev-de...@lists.sourceforge.net; 
>> > linuxppc-dev@ozlabs.org;
>> > akonova...@ru.mvista.com; adap...@gmail.com; Suneel Garapati
>> > Subject: Re: [PATCH] [V2] Xilinx : Framebuffer Driver: Add PLB support 
>> > (non-DCR)
>> >
>> > What tree is this patch prepared against?  The version in mainline
>> > already does PLB access, and doesn't support DCR at all.  It appears
>> > that this driver is based on something that does the opposite.
>> >
>> > g.
>> >
>> > On Fri, Apr 10, 2009 at 3:17 PM, John Linn <john.l...@xilinx.com> wrote:
>> > > From: Suneel <sune...@xilinx.com>
>> > >
>> > > Added support for the new xps tft controller.
>> > >
>> > > The new core has PLB interface support in addition to existing
>> > > DCR interface.
>> > >
>> > > The driver has been modified to support this new core which
>> > > can be connected on PLB or DCR bus.
>> > >
>> > > Signed-off-by: Suneel <sune...@xilinx.com>
>> > > Signed-off-by: John Linn <john.l...@xilinx.com>
>> > > ---
>> > >
>> > > V2 - Incorporated comments from Josh, Grant and others
>> > >
>> > >  drivers/video/xilinxfb.c |  213 
>> > > ++++++++++++++++++++++++++++++++--------------
>> > >  1 files changed, 150 insertions(+), 63 deletions(-)
>> > >
>> > > diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c
>> > > index a82c530..d151237 100644
>> > > --- a/drivers/video/xilinxfb.c
>> > > +++ b/drivers/video/xilinxfb.c
>> > > @@ -1,13 +1,13 @@
>> > >  /*
>> > > - * xilinxfb.c
>> > >  *
>> > > - * Xilinx TFT LCD frame buffer driver
>> > > + * Xilinx TFT frame buffer driver
>> > >  *
>> > >  * Author: MontaVista Software, Inc.
>> > >  *         sou...@mvista.com
>> > >  *
>> > >  * 2002-2007 (c) MontaVista Software, Inc.
>> > >  * 2007 (c) Secret Lab Technologies, Ltd.
>> > > + * 2009 (c) Xilinx Inc.
>> > >  *
>> > >  * This file is licensed under the terms of the GNU General Public 
>> > > License
>> > >  * version 2.  This program is licensed "as is" without any warranty of 
>> > > any
>> > > @@ -31,27 +31,31 @@
>> > >  #include <linux/fb.h>
>> > >  #include <linux/init.h>
>> > >  #include <linux/dma-mapping.h>
>> > > -#if defined(CONFIG_OF)
>> > >  #include <linux/of_device.h>
>> > >  #include <linux/of_platform.h>
>> > > -#endif
>> > > -#include <asm/io.h>
>> > > +#include <linux/io.h>
>> > >  #include <linux/xilinxfb.h>
>> > >  #include <asm/dcr.h>
>> > >
>> > >  #define DRIVER_NAME            "xilinxfb"
>> > > -#define DRIVER_DESCRIPTION     "Xilinx TFT LCD frame buffer driver"
>> > > +
>> > >
>> > >  /*
>> > >  * Xilinx calls it "PLB TFT LCD Controller" though it can also be used 
>> > > for
>> > > - * the VGA port on the Xilinx ML40x board. This is a hardware display 
>> > > controller
>> > > - * for a 640x480 resolution TFT or VGA screen.
>> > > + * the VGA port on the Xilinx ML40x board. This is a hardware display
>> > > + * controller for a 640x480 resolution TFT or VGA screen.
>> > >  *
>> > >  * The interface to the framebuffer is nice and simple.  There are two
>> > >  * control registers.  The first tells the LCD interface where in memory
>> > >  * the frame buffer is (only the 11 most significant bits are used, so
>> > >  * don't start thinking about scrolling).  The second allows the LCD to
>> > >  * be turned on or off as well as rotated 180 degrees.
>> > > + *
>> > > + * In case of direct PLB access the second control register will be at
>> > > + * an offset of 4 as compared to the DCR access where the offset is 1
>> > > + * i.e. REG_CTRL. So this is taken care in the function
>> > > + * xilinx_fb_out_be32 where it left shifts the offset 2 times in case of
>> > > + * direct PLB access.
>> > >  */
>> > >  #define NUM_REGS       2
>> > >  #define REG_FB_ADDR    0
>> > > @@ -108,10 +112,18 @@ static struct fb_var_screeninfo xilinx_fb_var = {
>> > >        .activate =     FB_ACTIVATE_NOW
>> > >  };
>> > >
>> > > +
>> > > +#define PLB_ACCESS_FLAG        0x1             /* 1 = PLB, 0 = DCR */
>> > > +
>> > >  struct xilinxfb_drvdata {
>> > >
>> > >        struct fb_info  info;           /* FB driver info record */
>> > >
>> > > +       phys_addr_t     regs_phys;      /* phys. address of the control
>> > > +                                               registers */
>> > > +       void __iomem    *regs;          /* virt. address of the control
>> > > +                                               registers */
>> > > +
>> > >        dcr_host_t      dcr_host;
>> > >        unsigned int    dcr_start;
>> > >        unsigned int    dcr_len;
>> > > @@ -120,6 +132,8 @@ struct xilinxfb_drvdata {
>> > >        dma_addr_t      fb_phys;        /* phys. address of the frame 
>> > > buffer */
>> > >        int             fb_alloced;     /* Flag, was the fb memory 
>> > > alloced? */
>> > >
>> > > +       u8              flags;          /* features of the driver */
>> > > +
>> > >        u32             reg_ctrl_default;
>> > >
>> > >        u32             pseudo_palette[PALETTE_ENTRIES_NO];
>> > > @@ -130,14 +144,19 @@ struct xilinxfb_drvdata {
>> > >        container_of(_info, struct xilinxfb_drvdata, info)
>> > >
>> > >  /*
>> > > - * The LCD controller has DCR interface to its registers, but all
>> > > - * the boards and configurations the driver has been tested with
>> > > - * use opb2dcr bridge. So the registers are seen as memory mapped.
>> > > - * This macro is to make it simple to add the direct DCR access
>> > > - * when it's needed.
>> > > + * The XPS TFT Controller can be accessed through PLB or DCR interface.
>> > > + * To perform the read/write on the registers we need to check on
>> > > + * which bus its connected and call the appropriate write API.
>> > >  */
>> > > -#define xilinx_fb_out_be32(driverdata, offset, val) \
>> > > -       dcr_write(driverdata->dcr_host, offset, val)
>> > > +static void xilinx_fb_out_be32(struct xilinxfb_drvdata *drvdata, u32 
>> > > offset,
>> > > +                               u32 val)
>> > > +{
>> > > +       if (drvdata->flags & PLB_ACCESS_FLAG)
>> > > +               out_be32(drvdata->regs + (offset << 2), val);
>> > > +       else
>> > > +               dcr_write(drvdata->dcr_host, offset, val);
>> > > +
>> > > +}
>> > >
>> > >  static int
>> > >  xilinx_fb_setcolreg(unsigned regno, unsigned red, unsigned green, 
>> > > unsigned blue,
>> > > @@ -175,7 +194,8 @@ xilinx_fb_blank(int blank_mode, struct fb_info *fbi)
>> > >        switch (blank_mode) {
>> > >        case FB_BLANK_UNBLANK:
>> > >                /* turn on panel */
>> > > -               xilinx_fb_out_be32(drvdata, REG_CTRL, 
>> > > drvdata->reg_ctrl_default);
>> > > +               xilinx_fb_out_be32(drvdata, REG_CTRL,
>> > > +                                       drvdata->reg_ctrl_default);
>> > >                break;
>> > >
>> > >        case FB_BLANK_NORMAL:
>> > > @@ -191,8 +211,7 @@ xilinx_fb_blank(int blank_mode, struct fb_info *fbi)
>> > >        return 0; /* success */
>> > >  }
>> > >
>> > > -static struct fb_ops xilinxfb_ops =
>> > > -{
>> > > +static struct fb_ops xilinxfb_ops = {
>> > >        .owner                  = THIS_MODULE,
>> > >        .fb_setcolreg           = xilinx_fb_setcolreg,
>> > >        .fb_blank               = xilinx_fb_blank,
>> > > @@ -205,25 +224,35 @@ static struct fb_ops xilinxfb_ops =
>> > >  * Bus independent setup/teardown
>> > >  */
>> > >
>> > > -static int xilinxfb_assign(struct device *dev, dcr_host_t dcr_host,
>> > > -                          unsigned int dcr_start, unsigned int dcr_len,
>> > > +static int xilinxfb_assign(struct device *dev,
>> > > +                          struct xilinxfb_drvdata *drvdata,
>> > > +                          unsigned long physaddr,
>> > >                           struct xilinxfb_platform_data *pdata)
>> > >  {
>> > > -       struct xilinxfb_drvdata *drvdata;
>> > >        int rc;
>> > >        int fbsize = pdata->xvirt * pdata->yvirt * BYTES_PER_PIXEL;
>> > >
>> > > -       /* Allocate the driver data region */
>> > > -       drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
>> > > -       if (!drvdata) {
>> > > -               dev_err(dev, "Couldn't allocate device private 
>> > > record\n");
>> > > -               return -ENOMEM;
>> > > +       if (drvdata->flags & PLB_ACCESS_FLAG) {
>> > > +               /*
>> > > +                * Map the control registers in if the controller
>> > > +                * is on direct PLB interface.
>> > > +                */
>> > > +               if (!request_mem_region(physaddr, 8, DRIVER_NAME)) {
>> > > +                       dev_err(dev, "Couldn't lock memory region at 
>> > > 0x%08lX\n",
>> > > +                               physaddr);
>> > > +                       rc = -ENODEV;
>> > > +                       goto err_region;
>> > > +               }
>> > > +
>> > > +               drvdata->regs_phys = physaddr;
>> > > +               drvdata->regs = ioremap(physaddr, 8);
>> > > +               if (!drvdata->regs) {
>> > > +                       dev_err(dev, "Couldn't lock memory region at 
>> > > 0x%08lX\n",
>> > > +                               physaddr);
>> > > +                       rc = -ENODEV;
>> > > +                       goto err_map;
>> > > +               }
>> > >        }
>> > > -       dev_set_drvdata(dev, drvdata);
>> > > -
>> > > -       drvdata->dcr_start = dcr_start;
>> > > -       drvdata->dcr_len = dcr_len;
>> > > -       drvdata->dcr_host = dcr_host;
>> > >
>> > >        /* Allocate the framebuffer memory */
>> > >        if (pdata->fb_phys) {
>> > > @@ -238,7 +267,10 @@ static int xilinxfb_assign(struct device *dev, 
>> > > dcr_host_t dcr_host,
>> > >        if (!drvdata->fb_virt) {
>> > >                dev_err(dev, "Could not allocate frame buffer memory\n");
>> > >                rc = -ENOMEM;
>> > > -               goto err_region;
>> > > +               if (drvdata->flags & PLB_ACCESS_FLAG)
>> > > +                       goto err_fbmem;
>> > > +               else
>> > > +                       goto err_region;
>> > >        }
>> > >
>> > >        /* Clear (turn to black) the framebuffer */
>> > > @@ -251,7 +283,8 @@ static int xilinxfb_assign(struct device *dev, 
>> > > dcr_host_t dcr_host,
>> > >        drvdata->reg_ctrl_default = REG_CTRL_ENABLE;
>> > >        if (pdata->rotate_screen)
>> > >                drvdata->reg_ctrl_default |= REG_CTRL_ROTATE;
>> > > -       xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default);
>> > > +       xilinx_fb_out_be32(drvdata, REG_CTRL,
>> > > +                                       drvdata->reg_ctrl_default);
>> > >
>> > >        /* Fill struct fb_info */
>> > >        drvdata->info.device = dev;
>> > > @@ -287,9 +320,14 @@ static int xilinxfb_assign(struct device *dev, 
>> > > dcr_host_t dcr_host,
>> > >                goto err_regfb;
>> > >        }
>> > >
>> > > +       if (drvdata->flags & PLB_ACCESS_FLAG) {
>> > > +               /* Put a banner in the log (for DEBUG) */
>> > > +               dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr,
>> > > +                                       drvdata->regs);
>> > > +       }
>> > >        /* Put a banner in the log (for DEBUG) */
>> > >        dev_dbg(dev, "fb: phys=%p, virt=%p, size=%x\n",
>> > > -               (void*)drvdata->fb_phys, drvdata->fb_virt, fbsize);
>> > > +               (void *)drvdata->fb_phys, drvdata->fb_virt, fbsize);
>> > >
>> > >        return 0;       /* success */
>> > >
>> > > @@ -300,9 +338,20 @@ err_cmap:
>> > >        if (drvdata->fb_alloced)
>> > >                dma_free_coherent(dev, PAGE_ALIGN(fbsize), 
>> > > drvdata->fb_virt,
>> > >                        drvdata->fb_phys);
>> > > +       else
>> > > +               iounmap(drvdata->fb_virt);
>> > > +
>> > >        /* Turn off the display */
>> > >        xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
>> > >
>> > > +err_fbmem:
>> > > +       if (drvdata->flags & PLB_ACCESS_FLAG)
>> > > +               iounmap(drvdata->regs);
>> > > +
>> > > +err_map:
>> > > +       if (drvdata->flags & PLB_ACCESS_FLAG)
>> > > +               release_mem_region(physaddr, 8);
>> > > +
>> > >  err_region:
>> > >        kfree(drvdata);
>> > >        dev_set_drvdata(dev, NULL);
>> > > @@ -325,11 +374,18 @@ static int xilinxfb_release(struct device *dev)
>> > >        if (drvdata->fb_alloced)
>> > >                dma_free_coherent(dev, 
>> > > PAGE_ALIGN(drvdata->info.fix.smem_len),
>> > >                                  drvdata->fb_virt, drvdata->fb_phys);
>> > > +       else
>> > > +               iounmap(drvdata->fb_virt);
>> > >
>> > >        /* Turn off the display */
>> > >        xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
>> > >
>> > > -       dcr_unmap(drvdata->dcr_host, drvdata->dcr_len);
>> > > +       /* Release the resources, as allocated based on interface */
>> > > +       if (drvdata->flags & PLB_ACCESS_FLAG) {
>> > > +               iounmap(drvdata->regs);
>> > > +               release_mem_region(drvdata->regs_phys, 8);
>> > > +       } else
>> > > +               dcr_unmap(drvdata->dcr_host, drvdata->dcr_len);
>> > >
>> > >        kfree(drvdata);
>> > >        dev_set_drvdata(dev, NULL);
>> > > @@ -341,27 +397,54 @@ static int xilinxfb_release(struct device *dev)
>> > >  * OF bus binding
>> > >  */
>> > >
>> > > -#if defined(CONFIG_OF)
>> > >  static int __devinit
>> > >  xilinxfb_of_probe(struct of_device *op, const struct of_device_id 
>> > > *match)
>> > >  {
>> > >        const u32 *prop;
>> > > +       u32 *p;
>> > > +       u32 tft_access;
>> > >        struct xilinxfb_platform_data pdata;
>> > > +       struct resource res;
>> > >        int size, rc;
>> > > -       int start, len;
>> > > +       int start = 0, len = 0;
>> > >        dcr_host_t dcr_host;
>> > > +       struct xilinxfb_drvdata *drvdata;
>> > >
>> > >        /* Copy with the default pdata (not a ptr reference!) */
>> > >        pdata = xilinx_fb_default_pdata;
>> > >
>> > >        dev_dbg(&op->dev, "xilinxfb_of_probe(%p, %p)\n", op, match);
>> > >
>> > > -       start = dcr_resource_start(op->node, 0);
>> > > -       len = dcr_resource_len(op->node, 0);
>> > > -       dcr_host = dcr_map(op->node, start, len);
>> > > -       if (!DCR_MAP_OK(dcr_host)) {
>> > > -               dev_err(&op->dev, "invalid address\n");
>> > > -               return -ENODEV;
>> > > +       /*
>> > > +        * To check whether the core is connected directly to DCR or PLB
>> > > +        * interface and initialize the tft_access accordingly.
>> > > +        */
>> > > +       p = (u32 *)of_get_property(op->node, "xlnx,dcr-splb-slave-if", 
>> > > NULL);
>> > > +
>> > > +       if (p)
>> > > +               tft_access = *p;
>> > > +       else
>> > > +               tft_access = 0;         /* For backward compatibility */
>> > > +
>> > > +       /*
>> > > +        * Fill the resource structure if its direct PLB interface
>> > > +        * otherwise fill the dcr_host structure.
>> > > +        */
>> > > +       if (tft_access) {
>> > > +               rc = of_address_to_resource(op->node, 0, &res);
>> > > +               if (rc) {
>> > > +                       dev_err(&op->dev, "invalid address\n");
>> > > +                       return -ENODEV;
>> > > +               }
>> > > +
>> > > +       } else {
>> > > +               start = dcr_resource_start(op->node, 0);
>> > > +               len = dcr_resource_len(op->node, 0);
>> > > +               dcr_host = dcr_map(op->node, start, len);
>> > > +               if (!DCR_MAP_OK(dcr_host)) {
>> > > +                       dev_err(&op->dev, "invalid address\n");
>> > > +                       return -ENODEV;
>> > > +               }
>> > >        }
>> > >
>> > >        prop = of_get_property(op->node, "phys-size", &size);
>> > > @@ -385,7 +468,26 @@ xilinxfb_of_probe(struct of_device *op, const 
>> > > struct of_device_id *match)
>> > >        if (of_find_property(op->node, "rotate-display", NULL))
>> > >                pdata.rotate_screen = 1;
>> > >
>> > > -       return xilinxfb_assign(&op->dev, dcr_host, start, len, &pdata);
>> > > +       /* Allocate the driver data region */
>> > > +       drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
>> > > +       if (!drvdata) {
>> > > +               dev_err(&op->dev, "Couldn't allocate device private 
>> > > record\n");
>> > > +               return -ENOMEM;
>> > > +       }
>> > > +       dev_set_drvdata(&op->dev, drvdata);
>> > > +
>> > > +       if (tft_access)
>> > > +               drvdata->flags |= PLB_ACCESS_FLAG;
>> > > +
>> > > +       /* Arguments are passed based on the interface */
>> > > +       if (drvdata->flags & PLB_ACCESS_FLAG) {
>> > > +               return xilinxfb_assign(&op->dev, drvdata, res.start, 
>> > > &pdata);
>> > > +       } else {
>> > > +               drvdata->dcr_start = start;
>> > > +               drvdata->dcr_len = len;
>> > > +               drvdata->dcr_host = dcr_host;
>> > > +               return xilinxfb_assign(&op->dev, drvdata, 0, &pdata);
>> > > +       }
>> > >  }
>> > >
>> > >  static int __devexit xilinxfb_of_remove(struct of_device *op)
>> > > @@ -395,6 +497,7 @@ static int __devexit xilinxfb_of_remove(struct 
>> > > of_device *op)
>> > >
>> > >  /* Match table for of_platform binding */
>> > >  static struct of_device_id xilinxfb_of_match[] __devinitdata = {
>> > > +       { .compatible = "xlnx,xps-tft-1.00.a", },
>> > >        { .compatible = "xlnx,plb-tft-cntlr-ref-1.00.a", },
>> > >        { .compatible = "xlnx,plb-dvi-cntlr-ref-1.00.c", },
>> > >        {},
>> > > @@ -412,22 +515,6 @@ static struct of_platform_driver xilinxfb_of_driver 
>> > > = {
>> > >        },
>> > >  };
>> > >
>> > > -/* Registration helpers to keep the number of #ifdefs to a minimum */
>> > > -static inline int __init xilinxfb_of_register(void)
>> > > -{
>> > > -       pr_debug("xilinxfb: calling of_register_platform_driver()\n");
>> > > -       return of_register_platform_driver(&xilinxfb_of_driver);
>> > > -}
>> > > -
>> > > -static inline void __exit xilinxfb_of_unregister(void)
>> > > -{
>> > > -       of_unregister_platform_driver(&xilinxfb_of_driver);
>> > > -}
>> > > -#else /* CONFIG_OF */
>> > > -/* CONFIG_OF not enabled; do nothing helpers */
>> > > -static inline int __init xilinxfb_of_register(void) { return 0; }
>> > > -static inline void __exit xilinxfb_of_unregister(void) { }
>> > > -#endif /* CONFIG_OF */
>> > >
>> > >  /* ---------------------------------------------------------------------
>> > >  * Module setup and teardown
>> > > @@ -436,18 +523,18 @@ static inline void __exit 
>> > > xilinxfb_of_unregister(void) { }
>> > >  static int __init
>> > >  xilinxfb_init(void)
>> > >  {
>> > > -       return xilinxfb_of_register();
>> > > +       return of_register_platform_driver(&xilinxfb_of_driver);
>> > >  }
>> > >
>> > >  static void __exit
>> > >  xilinxfb_cleanup(void)
>> > >  {
>> > > -       xilinxfb_of_unregister();
>> > > +       of_unregister_platform_driver(&xilinxfb_of_driver);
>> > >  }
>> > >
>> > >  module_init(xilinxfb_init);
>> > >  module_exit(xilinxfb_cleanup);
>> > >
>> > >  MODULE_AUTHOR("MontaVista Software, Inc. <sou...@mvista.com>");
>> > > -MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
>> > > +MODULE_DESCRIPTION("Xilinx TFT frame buffer driver");
>> > >  MODULE_LICENSE("GPL");
>> > > --
>> > > 1.6.2.1
>> > >
>> > >
>> > >
>> > > This email and any attachments are intended for the sole use of the 
>> > > named recipient(s) and
>> > contain(s) confidential information that may be proprietary, privileged or 
>> > copyrighted under
>> > applicable law. If you are not the intended recipient, do not read, copy, 
>> > or forward this email
>> > message or any attachments. Delete this email message and any attachments 
>> > immediately.
>> > >
>> > >
>> > >
>> >
>> >
>> >
>> > --
>> > Grant Likely, B.Sc., P.Eng.
>> > Secret Lab Technologies Ltd.
>>
>>
>> This email and any attachments are intended for the sole use of the named 
>> recipient(s) and contain(s)
>> confidential information that may be proprietary, privileged or copyrighted 
>> under applicable law. If
>> you are not the intended recipient, do not read, copy, or forward this email 
>> message or any
>> attachments. Delete this email message and any attachments immediately.
>>
>>
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev@ozlabs.org
>> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>
>
> This email and any attachments are intended for the sole use of the named 
> recipient(s) and contain(s) confidential information that may be proprietary, 
> privileged or copyrighted under applicable law. If you are not the intended 
> recipient, do not read, copy, or forward this email message or any 
> attachments. Delete this email message and any attachments immediately.
>
>
>



-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Reply via email to