LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/12] IB/ehca: New features and fixes for 2.6.24
From: Joachim Fenkes @ 2007-09-11 13:18 UTC (permalink / raw)
  To: LinuxPPC-Dev, LKML, OF-General, Roland Dreier, OF-EWG
  Cc: Stefan Roscher, Christoph Raisch

Here are some fresh eHCA driver features and fixes for your reviewing
pleasure. They have passed internal testing and checkpatch.pl, so we think
they are ready for inclusion.

[01/12] adds userspace support for small QPs
[02/12] changes a nit in firmware communication
[03/12] adds support for more than 4096 QPs/CQs in user space
[04/12] enables mapping firmware contexts into uspace on 64K-page kernels
[05/12] changes hvCall debug trace formatting
[06/12] outputs return codes as signed decimal integers
[07/12] makes warnings also appear in non-debug mode, like they should
[08/12] replaces get_paca()->paca_index by the portable smp_processor_id()
[09/12] checks the allowed max number of SGEs when creating a QP
[10/12] fixes some Path Migration problems
[11/12] works around a firmware race condition
[12/12] bumps the driver's version number

The patches should apply cleanly, in order, against Roland's git. Please
review the changes and apply the patches for 2.6.24 if they are okay.

Regards,
  Joachim

=2D-=20
Joachim Fenkes =A0-- =A0eHCA Linux Driver Developer and Hardware Tamer
IBM Deutschland Entwicklung GmbH =A0-- =A0Dept. 3627 (I/O Firmware Dev. 2)
Schoenaicher Strasse 220 =A0-- =A071032 Boeblingen =A0-- =A0Germany
eMail: fenkes@de.ibm.com

^ permalink raw reply

* Re: Interrupt-problem mpc5200
From: WITTROCK @ 2007-09-11 12:49 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <20070910090305.GG11807@sfrouter>


Hello,

Is it possible that this call failed?
intr = ioremap(MPC52xx_MBAR+MPC52xx_INTR_OFFSET, MPC52xx_INTR_SIZE); 

Maybe intr is invalid at this point?
out_be32(&intr->ctrl, intr_ctrl);       // ERROR!


Regards,
WITTROCK


S. Fricke wrote:
> 
> Hello all.
> 
> What are the steps to configure an MPC500B-Board to react on an IRQ (2)?
> 
> I have written a test-driver with this code-snippets, but the prozessor
> hangs when loading the driver.
> 
> my __init-function looks like:
> 
> static int __init mod_init( void ) 
> {
>     volatile static struct mpc52xx_intr __iomem *intr;
>     u32 intr_ctrl;
> 
>     // ...
> 
>     printk( "intmod.ko: interrupt init ");
>     if (request_irq(MPC52xx_IRQ2, intmod_isr, IRQF_SHARED , "intmod",
>                 INTMOD_IRQ_BOARD) == -EBUSY)
>         printk("KO\n");
>     else
>         printk("OK\n");
> 
>     intr = ioremap(MPC52xx_MBAR+MPC52xx_INTR_OFFSET, MPC52xx_INTR_SIZE);
> 
>     // read - modify - write
>     intr_ctrl = in_be32(&intr->ctrl);
>     intr_ctrl &= 0xfff3ffff;
>     intr_ctrl |= 0x00080200;
>     out_be32(&intr->ctrl, intr_ctrl);       // ERROR!
> 
>     if(intr) iounmap(intr);
> 
>     // ...
> }
> 
> On the Line, marked with "ERROR!" the prozessor hangs and the kernel drops
> out.
> 
> TIA: Silvio
> 
> 
> Mit freundlichen Gruessen
> Silvio Fricke
> 
> -- 
> -- S. Fricke ----------------------------- MAILTO:silvio.fricke@gmail.com
> --
>    Diplom-Informatiker (FH)
>    Linux-Entwicklung                       JABBER:      fricke@jabber.org
> ----------------------------------------------------------------------------
> 
> 
>  
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
> 

-- 
View this message in context: http://www.nabble.com/Interrupt-problem-mpc5200-tf4413834.html#a12613692
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply

* Re: Interrupt-problem mpc5200
From: S. Fricke @ 2007-09-11 12:43 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <20070910090305.GG11807@sfrouter>

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


Dear Linux-enthusiasts,

I'm still at the same problem.

I have now implemented a irq_chip for the hardwired IRQ2. Now I have


--==>
volatile static struct mpc52xx_intr __iomem *intr;
unsigned long flags;
static DEFINE_SPINLOCK(my_irq_controller_lock);

/*
 * HELPER-Function
 */
static inline void io_be_setbit(u32 __iomem *addr, int bitno)
{
    out_be32(addr, in_be32(addr) | (1 << bitno));
}

static inline void io_be_clrbit(u32 __iomem *addr, int bitno)
{
    out_be32(addr, in_be32(addr) & ~(1 << bitno));
}

/*
 * IRQ-Zeugs
 */
static void my_irq_ack(unsigned int irq)
{
    printk("%s(%s/%d):\n", __FILE__, __FUNCTION__, __LINE__);
    spin_lock_irqsave(&my_irq_controller_lock, flags);
    if(intr)
        io_be_setbit(&intr->ctrl, 25);
    spin_unlock_irqrestore(&my_irq_controller_lock, flags);
    printk("%s(%s/%d):\n", __FILE__, __FUNCTION__, __LINE__);
}

/* irq - disabled */
static void my_irq_mask(unsigned int irq)
{
    printk("%s(%s/%d):\n", __FILE__, __FUNCTION__, __LINE__);
    spin_lock_irqsave(&my_irq_controller_lock, flags);
    if(intr)
        io_be_clrbit(&intr->ctrl, 9); 
    spin_unlock_irqrestore(&my_irq_controller_lock, flags);
    printk("%s(%s/%d):\n", __FILE__, __FUNCTION__, __LINE__);
}

/* irq - enable */
static void my_irq_unmask(unsigned int irq)
{
    printk("%s(%s/%d):\n", __FILE__, __FUNCTION__, __LINE__);
    spin_lock_irqsave(&my_irq_controller_lock, flags);
    if(intr)
        io_be_setbit(&intr->ctrl, 9);
    spin_unlock_irqrestore(&my_irq_controller_lock, flags);
    printk("%s(%s/%d):\n", __FILE__, __FUNCTION__, __LINE__);
}

static struct irq_chip my_irq_chip = { 
    .typename   = "MY_IRQ_TEST",
    .ack        = my_irq_ack,
    .mask       = my_irq_mask,
    .unmask     = my_irq_unmask,
};

static int __init mod_init( void )
{
    // ...

    intr = mpc52xx_find_and_map("mpc52xx-pic");
    if(!intr) {
        panic(__FILE__ ": mpc52xx-pic - MAP failed");
    }

    set_irq_chip(MPC52xx_IRQ2, &my_irq_chip);
    a = request_irq(2, intmod_isr, IRQF_DISABLED , "intmod", INTMOD_IRQ_BOARD);
    printk("a: 0x%08x\n", a);

    // ...
}

<==--

Now my code hangs on the my_irq_unmask(...)-function on "io_be_setbit". Why?
Can anyone help me, or point me to the right newsgroup/forum?

So long!

Silvio


-- 
-- S. Fricke ----------------------------- MAILTO:silvio.fricke@gmail.com --
   Diplom-Informatiker (FH)
   Linux-Entwicklung                       JABBER:      fricke@jabber.org
----------------------------------------------------------------------------


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

^ permalink raw reply

* Re: [NEWBIE] Interrupt-problem mpc5200
From: S. Fricke @ 2007-09-11 12:41 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <20070906133050.GE11807@sfrouter>

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


Dear Linux-enthusiasts,

I'm still at the same problem.

I have now implemented a irq_chip for the hardwired IRQ2. Now I have:


--==>
volatile static struct mpc52xx_intr __iomem *intr;
unsigned long flags;
static DEFINE_SPINLOCK(my_irq_controller_lock);

/*
 * HELPER-Function
 */
static inline void io_be_setbit(u32 __iomem *addr, int bitno)
{
    out_be32(addr, in_be32(addr) | (1 << bitno));
}

static inline void io_be_clrbit(u32 __iomem *addr, int bitno)
{
    out_be32(addr, in_be32(addr) & ~(1 << bitno));
}

/*
 * IRQ-Zeugs
 */
static void my_irq_ack(unsigned int irq)
{
    printk("%s(%s/%d):\n", __FILE__, __FUNCTION__, __LINE__);
    spin_lock_irqsave(&my_irq_controller_lock, flags);
    if(intr)
        io_be_setbit(&intr->ctrl, 25);
    spin_unlock_irqrestore(&my_irq_controller_lock, flags);
    printk("%s(%s/%d):\n", __FILE__, __FUNCTION__, __LINE__);
}

/* irq - disabled */
static void my_irq_mask(unsigned int irq)
{
    printk("%s(%s/%d):\n", __FILE__, __FUNCTION__, __LINE__);
    spin_lock_irqsave(&my_irq_controller_lock, flags);
    if(intr)
        io_be_clrbit(&intr->ctrl, 9); 
    spin_unlock_irqrestore(&my_irq_controller_lock, flags);
    printk("%s(%s/%d):\n", __FILE__, __FUNCTION__, __LINE__);
}

/* irq - enable */
static void my_irq_unmask(unsigned int irq)
{
    printk("%s(%s/%d):\n", __FILE__, __FUNCTION__, __LINE__);
    spin_lock_irqsave(&my_irq_controller_lock, flags);
    if(intr)
        io_be_setbit(&intr->ctrl, 9);
    spin_unlock_irqrestore(&my_irq_controller_lock, flags);
    printk("%s(%s/%d):\n", __FILE__, __FUNCTION__, __LINE__);
}

static struct irq_chip my_irq_chip = { 
    .typename   = "MY_IRQ_TEST",
    .ack        = my_irq_ack,
    .mask       = my_irq_mask,
    .unmask     = my_irq_unmask,
};

static int __init mod_init( void )
{
    // ...

    intr = mpc52xx_find_and_map("mpc52xx-pic");
    if(!intr) {
        panic(__FILE__ ": mpc52xx-pic - MAP failed");
    }

    set_irq_chip(MPC52xx_IRQ2, &my_irq_chip);
    a = request_irq(2, intmod_isr, IRQF_DISABLED , "intmod", INTMOD_IRQ_BOARD);
    printk("a: 0x%08x\n", a);

    // ...
}

<==--

Now my code hangs on the my_irq_unmask(...)-function on "io_be_setbit". Why?
Can anyone help me, or point me to the right newsgroup/forum?

So long!

Silvio


-- 
-- S. Fricke ----------------------------- MAILTO:silvio.fricke@gmail.com --
   Diplom-Informatiker (FH)
   Linux-Entwicklung                       JABBER:      fricke@jabber.org
----------------------------------------------------------------------------


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

^ permalink raw reply

* RE: [PATCH 5/5] Add DMA engine driver for Freescale MPC85xx processors.
From: Zhang Wei-r63237 @ 2007-09-11 10:30 UTC (permalink / raw)
  To: Dan Williams; +Cc: shannon.nelson, linux-kernel, linuxppc-dev, paulus
In-Reply-To: <e9c3a7c20709091053u607e710ay1eb76c53312706ea@mail.gmail.com>

Hi, Dan,

Does I have followed your new API? :-)

> > ---
> Greetings,
>=20
> Please copy me on any updates to this driver, drivers/dma, or=20
> crypto/async_tx.

Ok.

>=20
> Below are a few review comments...
>=20
> Regards,
> Dan
>=20
> > +/**
> > + * fsl_dma_alloc_descriptor - Allocate descriptor from=20
> channel's DMA pool.
> > + *
> > + * Return - The descriptor allocated. NULL for failed.
> > + */
> > +static struct fsl_desc_sw *fsl_dma_alloc_descriptor(
> > +                                       struct fsl_dma_chan=20
> *fsl_chan,
> > +                                       gfp_t flags)
> > +{
> > +       dma_addr_t pdesc;
> > +       struct fsl_desc_sw *desc_sw;
> > +
> > +       desc_sw =3D dma_pool_alloc(fsl_chan->desc_pool,=20
> flags, &pdesc);
> > +       if (desc_sw) {
> > +               memset(desc_sw, 0, sizeof(struct fsl_desc_sw));
> > +               dma_async_tx_descriptor_init(&desc_sw->async_tx,
> > +                                               &fsl_chan->common);
> > +               desc_sw->async_tx.tx_set_src =3D fsl_dma_set_src;
> > +               desc_sw->async_tx.tx_set_dest =3D fsl_dma_set_dest;
> > +               desc_sw->async_tx.tx_submit =3D fsl_dma_tx_submit;
> > +               INIT_LIST_HEAD(&desc_sw->async_tx.tx_list);
> > +               desc_sw->async_tx.phys =3D pdesc;
> > +       }
> > +
> > +       return desc_sw;
> > +}
>=20
> I suggest pre-allocating the descriptors:
> 1/ It alleviates the need to initialize these async_tx fields=20
> which never change

The dma pool has already stored the descriptors in it's list,

> 2/ The GFP_ATOMIC allocation can be removed.
>=20

Ok.

> iop-adma gets by with one PAGE_SIZE buffer (128 descriptors).
>=20
> [..]
> > +static irqreturn_t fsl_dma_chan_do_interrupt(int irq, void *data)
> > +{
> > +       struct fsl_dma_chan *fsl_chan =3D (struct fsl_dma_chan =
*)data;
> > +       dma_addr_t stat;
> > +
> > +       stat =3D get_sr(fsl_chan);
> > +       dev_dbg(fsl_chan->device->dev, "event: channel %d,=20
> stat =3D 0x%x\n",
> > +                                               fsl_chan->id, stat);
> > +       set_sr(fsl_chan, stat);         /* Clear the event=20
> register */
> > +
> > +       stat &=3D ~(FSL_DMA_SR_CB | FSL_DMA_SR_CH);
> > +       if (!stat)
> > +               return IRQ_NONE;
> > +
> > +       /* If the link descriptor segment transfer finishes,
> > +        * we will recycle the used descriptor.
> > +        */
> > +       if (stat & FSL_DMA_SR_EOSI) {
> > +               dev_dbg(fsl_chan->device->dev, "event:=20
> End-of-segments INT\n");
> > +               dev_dbg(fsl_chan->device->dev, "event:=20
> clndar 0x%016llx, "
> > +                               "nlndar 0x%016llx\n",=20
> (u64)get_cdar(fsl_chan),
> > +                               (u64)get_ndar(fsl_chan));
> > +               stat &=3D ~FSL_DMA_SR_EOSI;
> > +               fsl_chan_ld_cleanup(fsl_chan, 1);
> > +       }
> > +
> > +       /* If it current transfer is the end-of-transfer,
> > +        * we should clear the Channel Start bit for
> > +        * prepare next transfer.
> > +        */
> > +       if (stat & (FSL_DMA_SR_EOLNI | FSL_DMA_SR_EOCDI)) {
> > +               dev_dbg(fsl_chan->device->dev, "event:=20
> End-of-link INT\n");
> > +               stat &=3D ~FSL_DMA_SR_EOLNI;
> > +               fsl_chan_xfer_ld_queue(fsl_chan);
> > +       }
> > +
> > +       if (stat)
> > +               dev_dbg(fsl_chan->device->dev, "event:=20
> unhandled sr 0x%02x\n",
> > +                                       stat);
> > +
> > +       dev_dbg(fsl_chan->device->dev, "event: Exit\n");
> > +       tasklet_hi_schedule(&dma_tasklet);
> > +       return IRQ_HANDLED;
> > +}
>=20
> This driver implements locking and callbacks inconsistently with how
> it is done in ioatdma and iop-adma.  The big changes are that all
> locks have been upgraded from 'spin_lock_bh' to 'spin_lock_irqsave',
> and async_tx callbacks can happen in irq context.  I would like to
> keep everything in bottom-half context to lessen the restrictions on
> what async_tx clients can perform in their callback routines.  What
> are the implications of moving 'fsl_chan_ld_cleanup' to the tasklet
> and changing the 'tasklet_hi_schedule' to 'tasklet_schedule'?

A good suggestion :), I need some investigation here.

>=20
> [..]
> > +static struct dma_chan=20
> *of_find_dma_chan_by_phandle(phandle phandle)
> > +{
> > +       struct device_node *np;
> > +       struct dma_chan *chan;
> > +       struct fsl_dma_device *fdev;
> > +
> > +       np =3D of_find_node_by_phandle(phandle);
> > +       if (!np || !of_device_is_compatible(np->parent, "fsl,dma"))
> > +               return NULL;
> > +
> > +       fdev =3D=20
> dev_get_drvdata(&of_find_device_by_node(np->parent)->dev);
> > +
> > +       list_for_each_entry(chan, &fdev->common.channels,=20
> device_node)
> > +               if=20
> (to_of_device(to_fsl_chan(chan)->chan_dev)->node =3D=3D np)
> > +                       return chan;
> > +       return NULL;
> > +}
> > +EXPORT_SYMBOL(of_find_dma_chan_by_phandle);
>=20
> This routine implies that there is a piece of code somewhere that
> wants to select which channels it can use.  A similar effect can be
> achieved by registering a dma_client with the dmaengine interface
> ('dma_async_client_register').  Then when the client code makes a call
> to 'dma_async_client_chan_request' it receives a 'dma_event_callback'
> for each channel in the system.  It will also be asynchronously
> notified of channels entering and leaving the system.  The goal is to
> share a common infrastructure for channel management.
>=20

It's speacial codes for our processors. Some device need the speacial =
DMA channel, such as must be DMA channel 0. So I add these codes. Or, is =
it possible to add a API for the special DMA channel getting?

> > +
> > +static int __devinit of_fsl_dma_probe(struct of_device *dev,
> > +                       const struct of_device_id *match)
> > +{
> > +       int err;
> > +       unsigned int irq;
> > +       struct fsl_dma_device *fdev;
> > +
> > +       fdev =3D kzalloc(sizeof(struct fsl_dma_device), GFP_KERNEL);
> > +       if (!fdev) {
> > +               dev_err(&dev->dev, "No enough memory for 'priv'\n");
> > +               err =3D -ENOMEM;
> > +               goto err;
> > +       }
> > +       fdev->dev =3D &dev->dev;
> > +       INIT_LIST_HEAD(&fdev->common.channels);
> > +
> > +       /* get DMA controller register base */
> > +       err =3D of_address_to_resource(dev->node, 0, &fdev->reg);
> > +       if (err) {
> > +               dev_err(&dev->dev, "Can't get %s property 'reg'\n",
> > +                               dev->node->full_name);
> > +               goto err;
> > +       }
> > +
> > +       dev_info(&dev->dev, "Probe the Freescale DMA driver for %s "
> > +                       "controller at 0x%08x...\n",
> > +                       match->compatible, fdev->reg.start);
> > +       fdev->reg_base =3D ioremap(fdev->reg.start, fdev->reg.end
> > +                                               -=20
> fdev->reg.start + 1);
> > +
> > +       dma_cap_set(DMA_MEMCPY, fdev->common.cap_mask);
> > +       fdev->common.device_alloc_chan_resources =3D=20
> fsl_dma_alloc_chan_resources;
> > +       fdev->common.device_free_chan_resources =3D=20
> fsl_dma_free_chan_resources;
> > +       fdev->common.device_prep_dma_memcpy =3D fsl_dma_prep_memcpy;
> > +       fdev->common.device_is_tx_complete =3D fsl_dma_is_complete;
> > +       fdev->common.device_issue_pending =3D=20
> fsl_dma_memcpy_issue_pending;
> > +       fdev->common.device_dependency_added =3D=20
> fsl_dma_dependency_added;
> > +       fdev->common.dev =3D &dev->dev;
> > +
> If this driver adds:
>=20
> dma_cap_set(DMA_INTERRUPT, fdev->common.cap_mask);
> fdev->common.device_prep_dma_interrupt =3D fsl_dma_prep_interrupt;
>=20
> It will be able to take advantage of interrupt triggered callbacks in
> async_tx.  Without these changes async_tx will poll for the completion
> of each transaction.
>=20

The new API have lacking documents :) I'll make some study here.

Thanks!
- zw

^ permalink raw reply

* RE: [PATCH 5/5] Add DMA engine driver for Freescale MPC85xx processors.
From: Zhang Wei-r63237 @ 2007-09-11 10:10 UTC (permalink / raw)
  To: Nelson, Shannon, paulus; +Cc: linuxppc-dev, dan.j.williams, linux-kernel
In-Reply-To: <BAE9DCEF64577A439B3A37F36F9B691C02FF08A1@orsmsx418.amr.corp.intel.com>

>=20
> If this is experimental, perhaps you should mark the depends line as
> such
> 	depends on on DMA_ENGINE && PPC && EXPERIMENTAL

I'll add EXPERIMENTAL for MPC83xx only.

>=20
> [...]
>=20
> >+
> >+	fsl_dma_memcpy_issue_pending(chan);
> >+	while (fsl_dma_is_complete(chan, cookie, NULL, NULL)
> >+			!=3D DMA_SUCCESS);
>=20
> Again, is it possible to hang your thread here?
>=20
> [...]

I'll add msleep here.

Thanks!

- zw

^ permalink raw reply

* RE: [PATCH 2/5] Add Freescale DMA engine driver maintainer.
From: Zhang Wei-r63237 @ 2007-09-11 10:07 UTC (permalink / raw)
  To: David Gibson; +Cc: linuxppc-dev, paulus
In-Reply-To: <20070910032737.GB27828@localhost.localdomain>

I'll merge them.

Thanks!=20
- zw

> -----Original Message-----
> From: David Gibson [mailto:david@gibson.dropbear.id.au]=20
> Sent: Monday, September 10, 2007 11:28 AM
> To: Zhang Wei-r63237
> Cc: paulus@samba.org; linuxppc-dev@ozlabs.org
> Subject: Re: [PATCH 2/5] Add Freescale DMA engine driver maintainer.
>=20
> On Fri, Sep 07, 2007 at 06:53:53PM +0800, Zhang Wei wrote:
> > This patch adds Freescale DMA engine driver maintainer.
>=20
> This is meaningless without the actual driver, so it shouldn't be a
> separate patch.  Fold it into the patch that actually adds the driver
> support.
>=20
> --=20
> David Gibson			| I'll have my music baroque,=20
> and my code
> david AT gibson.dropbear.id.au	| minimalist, thank=20
> you.  NOT _the_ _other_
> 				| _way_ _around_!
> http://www.ozlabs.org/~dgibson
>=20

^ permalink raw reply

* RE: [PATCH 5/5] Add DMA engine driver for Freescale MPC85xx processors.
From: Zhang Wei-r63237 @ 2007-09-11 10:06 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: shannon.nelson, linux-kernel, linuxppc-dev, paulus,
	dan.j.williams
In-Reply-To: <20070907085845.54dc88f8.randy.dunlap@oracle.com>

Hi,=20
> --- /dev/null
> > +++ b/drivers/dma/fsldma.c
> > @@ -0,0 +1,995 @@
>=20
> Thanks for using kernel-doc notation.  However, ...
>=20
> > +/**
> > + * fsl_dma_alloc_descriptor - Allocate descriptor from=20
> channel's DMA pool.
>=20
> Function parameters need to be listed & described here.
> See Documentation/kernel-doc-nano-HOWTO.txt or other source files
> for examples.
>=20
> (Applies to all documented function interfaces here.)

All right, I'll add full descriptions here. :P

>=20
> > + *
> > + * Return - The descriptor allocated. NULL for failed.
> > + */
> > +static struct fsl_desc_sw *fsl_dma_alloc_descriptor(
> > +					struct fsl_dma_chan *fsl_chan,
> > +					gfp_t flags)
> > +{
> ...
> > +}
>=20
> > +/**
> > + * fsl_chan_xfer_ld_queue -- Transfer the link descriptors=20
> in channel
> > + *                           ld_queue.
>=20
> The function's "short description" (unfortunately) must be on only one
> line.  E.g.:
>=20
>  * fsl_chan_xfer_ld_queue - Transfer link descriptors in=20
> channel ld_queue.
>=20

How about it's length greater than 80?

> > + */
> > +static void fsl_chan_xfer_ld_queue(struct fsl_dma_chan *fsl_chan)
> > +{
> ...
> > +}
>=20
> > diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h
> > new file mode 100644
> > index 0000000..05be9ed
> > --- /dev/null
> > +++ b/drivers/dma/fsldma.h
> > @@ -0,0 +1,188 @@
> > +struct fsl_dma_chan_regs {
> > +	__mix32	mr;		/* 0x00 - Mode Register */
> > +	__mix32	sr;		/* 0x04 - Status Register */
> > +	__mix64	cdar;		/* 0x08 - Cureent descriptor=20
> address register */
>=20
>                                           Current
>=20

I'll fix it.

Thanks!
- zw

^ permalink raw reply

* RE: [PATCH 1/5] Add Freescale DMA and DMA channel to Documentation/powerpc/booting-without-of.txt file.
From: Zhang Wei-r63237 @ 2007-09-11 10:01 UTC (permalink / raw)
  To: David Gibson, Segher Boessenkool; +Cc: linuxppc-dev, paulus
In-Reply-To: <20070910032529.GA27828@localhost.localdomain>

=20
>=20
> On Fri, Sep 07, 2007 at 04:43:35PM +0200, Segher Boessenkool wrote:
> > > +   l) Freescale DMA
> >=20
> > > +    - compatible : Should be "fsl,dma".
> >=20
> > Please choose some more specific name.  "fsl,mpc8540-dma" would
> > be a reasonable choice perhaps.
>=20
> More precisely, the compatible property should always have an specific
> entry based on the exact chip the DMA engine resides in, as well as a
> more general entry for any fsl dma engine of this type.
>=20
There is only difference in DMA channel and not in DMA node now. Does it
need add the precise compatible property name?

Thanks!
- zw

^ permalink raw reply

* SYSFS: need a noncaching read
From: Heiko Schocher @ 2007-09-11  9:43 UTC (permalink / raw)
  To: linux-kernel; +Cc: linuxppc-dev, Detlev Zundel

Hello,

I have developed a device driver and use the sysFS to export some
registers to userspace. I opened the sysFS File for one register and did
some reads from this File, but I alwas becoming the same value from the
register, whats not OK, because they are changing. So I found out that
the sysFS caches the reads ... :-(

Is there a way to retrigger the reads (in that way, that the sysFS
rereads the values from the driver), without closing and opening the
sysFS Files? Or must I better use the ioctl () Driver-interface for
exporting these registers?

I am asking this, because I must read every 10 ms 2 registers, so
doing a open/read/close for reading one registers is a little bit too
much overhead.

I made a sysFS seek function, which retriggers the read, and that works
fine, but I have again 2 syscalls, whats also is not optimal.

Or can we make a open () with a (new?)Flag, that informs the sysFS to
always reread the values from the underlying driver?

Or a new flag in the "struct attribute_group" in include/linux/sysfs.h,
which let the sysfs rereading the values?

suggestions are welcome

thanks
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

^ permalink raw reply

* Lite5200B and Carmine Board PCI problem
From: Dr. Thomas Fiksel @ 2007-09-11  9:07 UTC (permalink / raw)
  To: Linuxppc Mailing list

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

Hi Linuxppc-embedded,

I'm trying to run a Fujitsu Carmine Evaluation Board MB86297-EB01 on a 
Freescale Lite5200B board.
With a 'standard' Linux kernel 2.4 or 2.6 there are problems while 
allocating/maping of the PCI memory space. The Carmine board requires 2 
PCI IO space segments of 256 byte each, 1 PCI memory space segment of 
256 MByte and 1 PCI memory space segment of 64 MByte.

The U-Boot and kernel log shows :

Scanning PCI devices on bus 0
BusDevFun  VendorId   DeviceId   Device Class       Sub-Class
_____________________________________________________________
00.18.00   0x10cf     0x202b     Display controller      0x80
00.1a.00   0x1057     0x5809     Bridge device           0x80
...
PCI: Probing PCI hardware
...
PCI:00:18.0 Resource 0 [00000000-000000ff] is unassigned
PCI:00:18.0 Resource 1 [00000000-000000ff] is unassigned
PCI:00:18.0 Resource 2 [00000000-0fffffff] is unassigned
PCI:00:18.0 Resource 3 [00000000-03ffffff] is unassigned
PCI:00:1a.0 Resource 0 [00000000-0003ffff] is unassigned
PCI:00:1a.0 Resource 1 [00000000-3fffffff] is unassigned
PCI: bridge rsrc 50000000..50ffffff (100), parent c015debc, resource 
c027f038
PCI: bridge rsrc 40000000..4fffffff (200), parent c015ded8, resource 
c027f054
PCI: moved device 00:18.0 resource 0 (101) to 50000000
   got res[50000000:500000ff] for resource 0 of PCI device 10cf:202b
PCI: moved device 00:18.0 resource 1 (101) to 50000400
   got res[50000400:500004ff] for resource 1 of PCI device 10cf:202b
PCI: moved device 00:18.0 resource 2 (1208) to 40000000
   got res[40000000:4fffffff] for resource 2 of PCI device 10cf:202b
PCI: Failed to allocate resource 3(50000000-4fffffff) for 00:18.0


Because the PCI bridge shows only 256 MByte available memory area it is 
clear that the PCI memory space segment of 64 MByte (resource 3) is not 
allocated/mapped.

I tried to change the constants MPC5xxx_PCI_MEM_START and 
MPC5xxx_PCI_MEM_END constants (and other constants) in the related *.h 
file for arch/ppc/kernel/mpc5xxx_pci.c, recompiled the kernel and run it 
again.

Now the U-Boot and kernel log shows :

Scanning PCI devices on bus 0
BusDevFun  VendorId   DeviceId   Device Class       Sub-Class
_____________________________________________________________
00.18.00   0x10cf     0x202b     Display controller      0x80
00.1a.00   0x1057     0x5809     Bridge device           0x80
...
PCI: Probing PCI hardware
...
PCI:00:18.0 Resource 0 [00000000-000000ff] is unassigned
PCI:00:18.0 Resource 1 [00000000-000000ff] is unassigned
PCI:00:18.0 Resource 2 [00000000-0fffffff] is unassigned
PCI:00:18.0 Resource 3 [00000000-03ffffff] is unassigned
PCI:00:1a.0 Resource 0 [00000000-0003ffff] is unassigned
PCI:00:1a.0 Resource 1 [00000000-3fffffff] is unassigned
PCI: bridge rsrc 60000000..60ffffff (100), parent c015debc, resource 
c027f038
PCI: bridge rsrc 40000000..5fffffff (200), parent c015ded8, resource 
c027f054
PCI: moved device 00:18.0 resource 0 (101) to 60000000
   got res[60000000:600000ff] for resource 0 of PCI device 10cf:202b
PCI: moved device 00:18.0 resource 1 (101) to 60000400
   got res[60000400:600004ff] for resource 1 of PCI device 10cf:202b
PCI: moved device 00:18.0 resource 2 (1208) to 40000000
   got res[40000000:4fffffff] for resource 2 of PCI device 10cf:202b
PCI: moved device 00:18.0 resource 3 (1208) to 50000000
   got res[50000000:53ffffff] for resource 3 of PCI device 10cf:202b


The PCI bridge shows now a creater area and both PCI memory space 
segments of 256 Mbyte and 64 Mbyte are mapped.

But in case if I have a simple read or write acces to the register of 
Carmine (which are located in the 64 Mbyte segment in adress region 
above 0x50000000) the kernel gives the oops :

MB86290: fb_init called.
MB86290: initialize called.
Oops: kernel access of bad area, sig: 11
NIP: C00C2630 XER: 00000000 LR: C0004F3C SP: C0549D80 REGS: c0549cd0 
TRAP: 0300    Not tainted
MSR: 00001032 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 11
DAR: 00000020, DSISR: 20000000
TASK = c0548000[1] 'swapper' Last syscall: 120
last math 00000000 last altivec 00000000
GPR00: C0004F3C C0549D80 C0548000 00000000 C01B788C C0549E10 C014CA74 
F0000C00
GPR08: F0001200 00000000 C0170000 00000020 C0190000 1008D5C4 0FFBA000 
00000000
GPR16: 00000000 00000001 FFFFFFFF 007FFF00 00001032 00549E00 00000000 
C0003E40
GPR24: C0004FA4 00000000 C0546420 C016EF20 C0549E10 C01B788C 24000000 
C0546420
Call backtrace:
00009032 C0004F3C C0005000 C0003E40 C0004840 C00049B8 C00C2C14
C017ED7C C017E008 C017A140 C01725F4 C0172640 C0003970 C0006318
Kernel panic: Aiee, killing interrupt handler!

(Please note, the register access in the MB86290 driver code is still 
directed to the new register locations of the Carmine)


Therefore my questions:

It is allowed to increase the PCI bridge memory area by th simple change 
of MPC5xxx_PCI_MEM_START and MPC5xxx_PCI_MEM_END (and related constants)?

Or there are technical/hardware restrictions that this area can only be 
256 MByte?

If not, must be changed other constants in the kernel configuration the 
increase the PCI bridge memory area?

There are known problems to plug the Carmine board in the Lite5200B board?

All jumpers on both boards are in default settings.

TIA

Thomas Fiksel



[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 1970 bytes --]

^ permalink raw reply

* Re: PCI target implementation on AMCC PPC CPUs
From: Matthias Fuchs @ 2007-09-11  9:13 UTC (permalink / raw)
  To: linuxppc-embedded; +Cc: Leonid
In-Reply-To: <46E06259.5010305@ovro.caltech.edu>

Hi David,

we build a couple of PCI target designs using AMCC PowerPCs.
You are right that some things could be better. But ..

On Thursday 06 September 2007 22:26, David Hawkins wrote:
> There are several fundamental problems with the AMCC 440EP
> acting as a PCI target/slave;
> 
> 2. Look in the data sheet and see if you can figure out
>     how the host processor can generate an interrupt to
>     the PowerPC core ... oops, you can't. That kind of
>     makes it difficult to work with doesn't it.
You CAN! You can generate an interrupt to the PowerPC from the host
CPU bei writing to the PCI command register. You have to read the user manual
carefully. Perhaps it not that obvious.

Matthias

^ permalink raw reply

* Re: [RFC/PATCH] Implement {read,update}_persistent_clock.
From: Gabriel Paubert @ 2007-09-11  8:28 UTC (permalink / raw)
  To: Tony Breeds; +Cc: LinuxPPC-dev, Paul Mackerras
In-Reply-To: <20070911074917.GE9814@bakeyournoodle.com>

On Tue, Sep 11, 2007 at 05:49:17PM +1000, Tony Breeds wrote:
> With these functions implemented we cooperate better with the generic
> timekeeping code.  This obsoletes the need for the timer sysdev as a bonus.

Looks fine, there is still the problem that most PPC RTC
seem to prefer update on the second boundary instead of
the half second used by Wintel clones.

> 
> Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
> 
> ---
> 
> * Compile tested for arch/powerpc/configs/*_defconfig
> * Booted on pSeries, iSeries, Cell and PS3
> * Really needs booting on powermac and a quad G5 (hint hint)
> * Should remove arch/powerpc/sysdev/timer.c at the same time.

Realistically this can only be tested with a running ntp
process which locks to a server.

> 
>  arch/powerpc/Kconfig         |    3 +
>  arch/powerpc/kernel/time.c   |   58 ++++++++++-------------------------
>  arch/powerpc/sysdev/Makefile |    5 ---
>  3 files changed, 20 insertions(+), 46 deletions(-)
> 
> Index: working/arch/powerpc/Kconfig
> ===================================================================
> --- working.orig/arch/powerpc/Kconfig
> +++ working/arch/powerpc/Kconfig
> @@ -21,6 +21,9 @@ config MMU
>  	bool
>  	default y
>  
> +config GENERIC_CMOS_UPDATE
> +	def_bool y
> +
>  config GENERIC_HARDIRQS
>  	bool
>  	default y
> Index: working/arch/powerpc/kernel/time.c
> ===================================================================
> --- working.orig/arch/powerpc/kernel/time.c
> +++ working/arch/powerpc/kernel/time.c
> @@ -74,16 +74,11 @@
>  #endif
>  #include <asm/smp.h>
>  
> -/* keep track of when we need to update the rtc */
> -time_t last_rtc_update;
>  #ifdef CONFIG_PPC_ISERIES
>  static unsigned long __initdata iSeries_recal_titan;
>  static signed long __initdata iSeries_recal_tb;
>  #endif
>  
> -/* The decrementer counts down by 128 every 128ns on a 601. */
> -#define DECREMENTER_COUNT_601	(1000000000 / HZ)
> -
>  #define XSEC_PER_SEC (1024*1024)
>  
>  #ifdef CONFIG_PPC64
> @@ -349,38 +344,7 @@ void udelay(unsigned long usecs)
>  }
>  EXPORT_SYMBOL(udelay);
>  
> -static __inline__ void timer_check_rtc(void)
> -{
> -        /*
> -         * update the rtc when needed, this should be performed on the
> -         * right fraction of a second. Half or full second ?
> -         * Full second works on mk48t59 clocks, others need testing.
> -         * Note that this update is basically only used through 
> -         * the adjtimex system calls. Setting the HW clock in
> -         * any other way is a /dev/rtc and userland business.
> -         * This is still wrong by -0.5/+1.5 jiffies because of the
> -         * timer interrupt resolution and possible delay, but here we 
> -         * hit a quantization limit which can only be solved by higher
> -         * resolution timers and decoupling time management from timer
> -         * interrupts. This is also wrong on the clocks
> -         * which require being written at the half second boundary.
> -         * We should have an rtc call that only sets the minutes and
> -         * seconds like on Intel to avoid problems with non UTC clocks.
> -         */
> -        if (ppc_md.set_rtc_time && ntp_synced() &&
> -	    xtime.tv_sec - last_rtc_update >= 659 &&
> -	    abs((xtime.tv_nsec/1000) - (1000000-1000000/HZ)) < 500000/HZ) {
> -		struct rtc_time tm;
> -		to_tm(xtime.tv_sec + 1 + timezone_offset, &tm);
> -		tm.tm_year -= 1900;
> -		tm.tm_mon -= 1;
> -		if (ppc_md.set_rtc_time(&tm) == 0)
> -			last_rtc_update = xtime.tv_sec + 1;
> -		else
> -			/* Try again one minute later */
> -			last_rtc_update += 60;
> -        }
> -}
> +
>  
>  /*
>   * This version of gettimeofday has microsecond resolution.
> @@ -688,7 +652,6 @@ void timer_interrupt(struct pt_regs * re
>  			tb_last_jiffy = tb_next_jiffy;
>  			do_timer(1);
>  			timer_recalc_offset(tb_last_jiffy);
> -			timer_check_rtc();
>  		}
>  		write_sequnlock(&xtime_lock);
>  	}
> @@ -800,11 +763,6 @@ int do_settimeofday(struct timespec *tv)
>   	set_normalized_timespec(&xtime, new_sec, new_nsec);
>  	set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
>  
> -	/* In case of a large backwards jump in time with NTP, we want the 
> -	 * clock to be updated as soon as the PLL is again in lock.
> -	 */
> -	last_rtc_update = new_sec - 658;
> -
>  	ntp_clear();
>  
>  	new_xsec = xtime.tv_nsec;
> @@ -880,12 +838,36 @@ void __init generic_calibrate_decr(void)
>  #endif
>  }
>  
> -unsigned long get_boot_time(void)
> +int update_persistent_clock(struct timespec now)
>  {
>  	struct rtc_time tm;
>  
> -	if (ppc_md.get_boot_time)
> -		return ppc_md.get_boot_time();
> +	if (!ppc_md.set_rtc_time)
> +		return 0;
> +
> +	to_tm(now.tv_sec + 1 + timezone_offset, &tm);
> +	tm.tm_year -= 1900;
> +	tm.tm_mon -= 1;
> +
> +	return ppc_md.set_rtc_time(&tm);
> +}
> +
> +unsigned long read_persistent_clock(void)
> +{
> +	struct rtc_time tm;
> +	static int first = 1;
> +	unsigned long time = 0;
> +
> +	if (first) {
> +		first = 0;
> +		if (ppc_md.time_init)
> +			timezone_offset = ppc_md.time_init();
> +	}
> +
> +	/* get_boot_time() isn't guaranteed to be safe to call late */
> +	if (system_state != SYSTEM_RUNNING && ppc_md.get_boot_time) {
> +		return ppc_md.get_boot_time() -timezone_offset;
> +	}
>  	if (!ppc_md.get_rtc_time)
>  		return 0;
>  	ppc_md.get_rtc_time(&tm);
> @@ -897,14 +879,10 @@ unsigned long get_boot_time(void)
>  void __init time_init(void)
>  {
>  	unsigned long flags;
> -	unsigned long tm = 0;
>  	struct div_result res;
>  	u64 scale, x;
>  	unsigned shift;
>  
> -        if (ppc_md.time_init != NULL)
> -                timezone_offset = ppc_md.time_init();
> -
>  	if (__USE_RTC()) {
>  		/* 601 processor: dec counts down by 128 every 128ns */
>  		ppc_tb_freq = 1000000000;
> @@ -979,19 +957,14 @@ void __init time_init(void)
>  	/* Save the current timebase to pretty up CONFIG_PRINTK_TIME */
>  	boot_tb = get_tb();
>  
> -	tm = get_boot_time();
> -
>  	write_seqlock_irqsave(&xtime_lock, flags);
>  
>  	/* If platform provided a timezone (pmac), we correct the time */
>          if (timezone_offset) {
>  		sys_tz.tz_minuteswest = -timezone_offset / 60;
>  		sys_tz.tz_dsttime = 0;
> -		tm -= timezone_offset;
>          }
>  
> -	xtime.tv_sec = tm;
> -	xtime.tv_nsec = 0;
>  	do_gtod.varp = &do_gtod.vars[0];
>  	do_gtod.var_idx = 0;
>  	do_gtod.varp->tb_orig_stamp = tb_last_jiffy;
> @@ -1009,9 +982,6 @@ void __init time_init(void)
>  
>  	time_freq = 0;
>  
> -	last_rtc_update = xtime.tv_sec;
> -	set_normalized_timespec(&wall_to_monotonic,
> -	                        -xtime.tv_sec, -xtime.tv_nsec);
>  	write_sequnlock_irqrestore(&xtime_lock, flags);
>  
>  	/* Not exact, but the timer interrupt takes care of this */
> Index: working/arch/powerpc/sysdev/Makefile
> ===================================================================
> --- working.orig/arch/powerpc/sysdev/Makefile
> +++ working/arch/powerpc/sysdev/Makefile
> @@ -20,11 +20,6 @@ obj-$(CONFIG_MV64X60)		+= $(mv64x60-y) m
>  obj-$(CONFIG_RTC_DRV_CMOS)	+= rtc_cmos_setup.o
>  obj-$(CONFIG_AXON_RAM)		+= axonram.o
>  
> -# contains only the suspend handler for time
> -ifeq ($(CONFIG_RTC_CLASS),)
> -obj-$(CONFIG_PM)		+= timer.o
> -endif
> -
>  ifeq ($(CONFIG_PPC_MERGE),y)
>  obj-$(CONFIG_PPC_INDIRECT_PCI)	+= indirect_pci.o
>  obj-$(CONFIG_PPC_I8259)		+= i8259.o
> 
> 
> Yours Tony
> 
>   linux.conf.au        http://linux.conf.au/ || http://lca2008.linux.org.au/
>   Jan 28 - Feb 02 2008 The Australian Linux Technical Conference!
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* Re: Fix "no_sync_cmos_clock"  logic inversion in kernel/time/ntp.c
From: Thomas Gleixner @ 2007-09-11  7:57 UTC (permalink / raw)
  To: Tony Breeds
  Cc: zach, John Stultz, Linux Kernel ML, LinuxPPC-dev, Paul Mackerras,
	Andrew Morton
In-Reply-To: <20070911074608.GD9814@bakeyournoodle.com>

On Tue, 2007-09-11 at 17:46 +1000, Tony Breeds wrote:
> Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>
> 
> ---
> 
> Seems to me that this timer will only get started on platforms that say
> they don't want it?

Hell, yes. Good catch !

	tglx

>  kernel/time/ntp.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> Index: working/kernel/time/ntp.c
> ===================================================================
> --- working.orig/kernel/time/ntp.c	2007-09-11 17:34:44.000000000 +1000
> +++ working/kernel/time/ntp.c	2007-09-11 17:34:55.000000000 +1000
> @@ -226,7 +226,7 @@ static void sync_cmos_clock(unsigned lon
>  
>  static void notify_cmos_timer(void)
>  {
> -	if (no_sync_cmos_clock)
> +	if (!no_sync_cmos_clock)
>  		mod_timer(&sync_cmos_timer, jiffies + 1);
>  }
>  
> 
> Yours Tony
> 
>   linux.conf.au        http://linux.conf.au/ || http://lca2008.linux.org.au/
>   Jan 28 - Feb 02 2008 The Australian Linux Technical Conference!
> 

^ permalink raw reply

* Re: [RFC/PATCH] Implement {read,update}_persistent_clock. v2
From: Tony Breeds @ 2007-09-11  8:17 UTC (permalink / raw)
  To: LinuxPPC-dev, Paul Mackerras
In-Reply-To: <20070911074917.GE9814@bakeyournoodle.com>

From: Tony Breeds <tony@bakeyournoodle.com>

Implement {read,update}_persistent_clock.

With these functions implemented we cooperate better with the generic
timekeeping code.  This obsoletes the need for the timer sysdev as a bonus.

Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>

---

Functionally is the same as previous version,  Just a few cleanups.

* Compile tested for arch/powerpc/configs/*_defconfig
* Booted on pSeries, iSeries, Cell and PS3
* Really needs booting on powermac and a quad G5 (hint hint)
* Should remove arch/powerpc/sysdev/timer.c

 arch/powerpc/Kconfig         |    3 +
 arch/powerpc/kernel/time.c   |   58 ++++++++++-------------------------
 arch/powerpc/sysdev/Makefile |    5 ---
 3 files changed, 20 insertions(+), 46 deletions(-)

Index: working/arch/powerpc/Kconfig
===================================================================
--- working.orig/arch/powerpc/Kconfig
+++ working/arch/powerpc/Kconfig
@@ -21,6 +21,9 @@ config MMU
 	bool
 	default y
 
+config GENERIC_CMOS_UPDATE
+	def_bool y
+
 config GENERIC_HARDIRQS
 	bool
 	default y
Index: working/arch/powerpc/kernel/time.c
===================================================================
--- working.orig/arch/powerpc/kernel/time.c
+++ working/arch/powerpc/kernel/time.c
@@ -74,16 +74,11 @@
 #endif
 #include <asm/smp.h>
 
-/* keep track of when we need to update the rtc */
-time_t last_rtc_update;
 #ifdef CONFIG_PPC_ISERIES
 static unsigned long __initdata iSeries_recal_titan;
 static signed long __initdata iSeries_recal_tb;
 #endif
 
-/* The decrementer counts down by 128 every 128ns on a 601. */
-#define DECREMENTER_COUNT_601	(1000000000 / HZ)
-
 #define XSEC_PER_SEC (1024*1024)
 
 #ifdef CONFIG_PPC64
@@ -349,39 +344,6 @@ void udelay(unsigned long usecs)
 }
 EXPORT_SYMBOL(udelay);
 
-static __inline__ void timer_check_rtc(void)
-{
-        /*
-         * update the rtc when needed, this should be performed on the
-         * right fraction of a second. Half or full second ?
-         * Full second works on mk48t59 clocks, others need testing.
-         * Note that this update is basically only used through 
-         * the adjtimex system calls. Setting the HW clock in
-         * any other way is a /dev/rtc and userland business.
-         * This is still wrong by -0.5/+1.5 jiffies because of the
-         * timer interrupt resolution and possible delay, but here we 
-         * hit a quantization limit which can only be solved by higher
-         * resolution timers and decoupling time management from timer
-         * interrupts. This is also wrong on the clocks
-         * which require being written at the half second boundary.
-         * We should have an rtc call that only sets the minutes and
-         * seconds like on Intel to avoid problems with non UTC clocks.
-         */
-        if (ppc_md.set_rtc_time && ntp_synced() &&
-	    xtime.tv_sec - last_rtc_update >= 659 &&
-	    abs((xtime.tv_nsec/1000) - (1000000-1000000/HZ)) < 500000/HZ) {
-		struct rtc_time tm;
-		to_tm(xtime.tv_sec + 1 + timezone_offset, &tm);
-		tm.tm_year -= 1900;
-		tm.tm_mon -= 1;
-		if (ppc_md.set_rtc_time(&tm) == 0)
-			last_rtc_update = xtime.tv_sec + 1;
-		else
-			/* Try again one minute later */
-			last_rtc_update += 60;
-        }
-}
-
 /*
  * This version of gettimeofday has microsecond resolution.
  */
@@ -688,7 +650,6 @@ void timer_interrupt(struct pt_regs * re
 			tb_last_jiffy = tb_next_jiffy;
 			do_timer(1);
 			timer_recalc_offset(tb_last_jiffy);
-			timer_check_rtc();
 		}
 		write_sequnlock(&xtime_lock);
 	}
@@ -800,11 +761,6 @@ int do_settimeofday(struct timespec *tv)
  	set_normalized_timespec(&xtime, new_sec, new_nsec);
 	set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
 
-	/* In case of a large backwards jump in time with NTP, we want the 
-	 * clock to be updated as soon as the PLL is again in lock.
-	 */
-	last_rtc_update = new_sec - 658;
-
 	ntp_clear();
 
 	new_xsec = xtime.tv_nsec;
@@ -880,12 +836,35 @@ void __init generic_calibrate_decr(void)
 #endif
 }
 
-unsigned long get_boot_time(void)
+int update_persistent_clock(struct timespec now)
+{
+	struct rtc_time tm;
+
+	if (!ppc_md.set_rtc_time)
+		return 0;
+
+	to_tm(now.tv_sec + 1 + timezone_offset, &tm);
+	tm.tm_year -= 1900;
+	tm.tm_mon -= 1;
+
+	return ppc_md.set_rtc_time(&tm);
+}
+
+unsigned long read_persistent_clock(void)
 {
 	struct rtc_time tm;
+	static int first = 1;
+
+	if (first) {
+		first = 0;
+		if (ppc_md.time_init)
+			timezone_offset = ppc_md.time_init();
+	}
 
-	if (ppc_md.get_boot_time)
-		return ppc_md.get_boot_time();
+	/* get_boot_time() isn't guaranteed to be safe to call late */
+	/* FIXME: is the a better check available here? */
+	if (system_state != SYSTEM_RUNNING && ppc_md.get_boot_time)
+		return ppc_md.get_boot_time() -timezone_offset;
 	if (!ppc_md.get_rtc_time)
 		return 0;
 	ppc_md.get_rtc_time(&tm);
@@ -897,14 +876,10 @@ unsigned long get_boot_time(void)
 void __init time_init(void)
 {
 	unsigned long flags;
-	unsigned long tm = 0;
 	struct div_result res;
 	u64 scale, x;
 	unsigned shift;
 
-        if (ppc_md.time_init != NULL)
-                timezone_offset = ppc_md.time_init();
-
 	if (__USE_RTC()) {
 		/* 601 processor: dec counts down by 128 every 128ns */
 		ppc_tb_freq = 1000000000;
@@ -979,19 +954,14 @@ void __init time_init(void)
 	/* Save the current timebase to pretty up CONFIG_PRINTK_TIME */
 	boot_tb = get_tb();
 
-	tm = get_boot_time();
-
 	write_seqlock_irqsave(&xtime_lock, flags);
 
 	/* If platform provided a timezone (pmac), we correct the time */
         if (timezone_offset) {
 		sys_tz.tz_minuteswest = -timezone_offset / 60;
 		sys_tz.tz_dsttime = 0;
-		tm -= timezone_offset;
         }
 
-	xtime.tv_sec = tm;
-	xtime.tv_nsec = 0;
 	do_gtod.varp = &do_gtod.vars[0];
 	do_gtod.var_idx = 0;
 	do_gtod.varp->tb_orig_stamp = tb_last_jiffy;
@@ -1009,9 +979,6 @@ void __init time_init(void)
 
 	time_freq = 0;
 
-	last_rtc_update = xtime.tv_sec;
-	set_normalized_timespec(&wall_to_monotonic,
-	                        -xtime.tv_sec, -xtime.tv_nsec);
 	write_sequnlock_irqrestore(&xtime_lock, flags);
 
 	/* Not exact, but the timer interrupt takes care of this */
Index: working/arch/powerpc/sysdev/Makefile
===================================================================
--- working.orig/arch/powerpc/sysdev/Makefile
+++ working/arch/powerpc/sysdev/Makefile
@@ -20,11 +20,6 @@ obj-$(CONFIG_MV64X60)		+= $(mv64x60-y) m
 obj-$(CONFIG_RTC_DRV_CMOS)	+= rtc_cmos_setup.o
 obj-$(CONFIG_AXON_RAM)		+= axonram.o
 
-# contains only the suspend handler for time
-ifeq ($(CONFIG_RTC_CLASS),)
-obj-$(CONFIG_PM)		+= timer.o
-endif
-
 ifeq ($(CONFIG_PPC_MERGE),y)
 obj-$(CONFIG_PPC_INDIRECT_PCI)	+= indirect_pci.o
 obj-$(CONFIG_PPC_I8259)		+= i8259.o

^ permalink raw reply

* [RFC/PATCH] Implement {read,update}_persistent_clock.
From: Tony Breeds @ 2007-09-11  7:49 UTC (permalink / raw)
  To: LinuxPPC-dev, Paul Mackerras

With these functions implemented we cooperate better with the generic
timekeeping code.  This obsoletes the need for the timer sysdev as a bonus.

Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>

---

* Compile tested for arch/powerpc/configs/*_defconfig
* Booted on pSeries, iSeries, Cell and PS3
* Really needs booting on powermac and a quad G5 (hint hint)
* Should remove arch/powerpc/sysdev/timer.c at the same time.

 arch/powerpc/Kconfig         |    3 +
 arch/powerpc/kernel/time.c   |   58 ++++++++++-------------------------
 arch/powerpc/sysdev/Makefile |    5 ---
 3 files changed, 20 insertions(+), 46 deletions(-)

Index: working/arch/powerpc/Kconfig
===================================================================
--- working.orig/arch/powerpc/Kconfig
+++ working/arch/powerpc/Kconfig
@@ -21,6 +21,9 @@ config MMU
 	bool
 	default y
 
+config GENERIC_CMOS_UPDATE
+	def_bool y
+
 config GENERIC_HARDIRQS
 	bool
 	default y
Index: working/arch/powerpc/kernel/time.c
===================================================================
--- working.orig/arch/powerpc/kernel/time.c
+++ working/arch/powerpc/kernel/time.c
@@ -74,16 +74,11 @@
 #endif
 #include <asm/smp.h>
 
-/* keep track of when we need to update the rtc */
-time_t last_rtc_update;
 #ifdef CONFIG_PPC_ISERIES
 static unsigned long __initdata iSeries_recal_titan;
 static signed long __initdata iSeries_recal_tb;
 #endif
 
-/* The decrementer counts down by 128 every 128ns on a 601. */
-#define DECREMENTER_COUNT_601	(1000000000 / HZ)
-
 #define XSEC_PER_SEC (1024*1024)
 
 #ifdef CONFIG_PPC64
@@ -349,38 +344,7 @@ void udelay(unsigned long usecs)
 }
 EXPORT_SYMBOL(udelay);
 
-static __inline__ void timer_check_rtc(void)
-{
-        /*
-         * update the rtc when needed, this should be performed on the
-         * right fraction of a second. Half or full second ?
-         * Full second works on mk48t59 clocks, others need testing.
-         * Note that this update is basically only used through 
-         * the adjtimex system calls. Setting the HW clock in
-         * any other way is a /dev/rtc and userland business.
-         * This is still wrong by -0.5/+1.5 jiffies because of the
-         * timer interrupt resolution and possible delay, but here we 
-         * hit a quantization limit which can only be solved by higher
-         * resolution timers and decoupling time management from timer
-         * interrupts. This is also wrong on the clocks
-         * which require being written at the half second boundary.
-         * We should have an rtc call that only sets the minutes and
-         * seconds like on Intel to avoid problems with non UTC clocks.
-         */
-        if (ppc_md.set_rtc_time && ntp_synced() &&
-	    xtime.tv_sec - last_rtc_update >= 659 &&
-	    abs((xtime.tv_nsec/1000) - (1000000-1000000/HZ)) < 500000/HZ) {
-		struct rtc_time tm;
-		to_tm(xtime.tv_sec + 1 + timezone_offset, &tm);
-		tm.tm_year -= 1900;
-		tm.tm_mon -= 1;
-		if (ppc_md.set_rtc_time(&tm) == 0)
-			last_rtc_update = xtime.tv_sec + 1;
-		else
-			/* Try again one minute later */
-			last_rtc_update += 60;
-        }
-}
+
 
 /*
  * This version of gettimeofday has microsecond resolution.
@@ -688,7 +652,6 @@ void timer_interrupt(struct pt_regs * re
 			tb_last_jiffy = tb_next_jiffy;
 			do_timer(1);
 			timer_recalc_offset(tb_last_jiffy);
-			timer_check_rtc();
 		}
 		write_sequnlock(&xtime_lock);
 	}
@@ -800,11 +763,6 @@ int do_settimeofday(struct timespec *tv)
  	set_normalized_timespec(&xtime, new_sec, new_nsec);
 	set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
 
-	/* In case of a large backwards jump in time with NTP, we want the 
-	 * clock to be updated as soon as the PLL is again in lock.
-	 */
-	last_rtc_update = new_sec - 658;
-
 	ntp_clear();
 
 	new_xsec = xtime.tv_nsec;
@@ -880,12 +838,36 @@ void __init generic_calibrate_decr(void)
 #endif
 }
 
-unsigned long get_boot_time(void)
+int update_persistent_clock(struct timespec now)
 {
 	struct rtc_time tm;
 
-	if (ppc_md.get_boot_time)
-		return ppc_md.get_boot_time();
+	if (!ppc_md.set_rtc_time)
+		return 0;
+
+	to_tm(now.tv_sec + 1 + timezone_offset, &tm);
+	tm.tm_year -= 1900;
+	tm.tm_mon -= 1;
+
+	return ppc_md.set_rtc_time(&tm);
+}
+
+unsigned long read_persistent_clock(void)
+{
+	struct rtc_time tm;
+	static int first = 1;
+	unsigned long time = 0;
+
+	if (first) {
+		first = 0;
+		if (ppc_md.time_init)
+			timezone_offset = ppc_md.time_init();
+	}
+
+	/* get_boot_time() isn't guaranteed to be safe to call late */
+	if (system_state != SYSTEM_RUNNING && ppc_md.get_boot_time) {
+		return ppc_md.get_boot_time() -timezone_offset;
+	}
 	if (!ppc_md.get_rtc_time)
 		return 0;
 	ppc_md.get_rtc_time(&tm);
@@ -897,14 +879,10 @@ unsigned long get_boot_time(void)
 void __init time_init(void)
 {
 	unsigned long flags;
-	unsigned long tm = 0;
 	struct div_result res;
 	u64 scale, x;
 	unsigned shift;
 
-        if (ppc_md.time_init != NULL)
-                timezone_offset = ppc_md.time_init();
-
 	if (__USE_RTC()) {
 		/* 601 processor: dec counts down by 128 every 128ns */
 		ppc_tb_freq = 1000000000;
@@ -979,19 +957,14 @@ void __init time_init(void)
 	/* Save the current timebase to pretty up CONFIG_PRINTK_TIME */
 	boot_tb = get_tb();
 
-	tm = get_boot_time();
-
 	write_seqlock_irqsave(&xtime_lock, flags);
 
 	/* If platform provided a timezone (pmac), we correct the time */
         if (timezone_offset) {
 		sys_tz.tz_minuteswest = -timezone_offset / 60;
 		sys_tz.tz_dsttime = 0;
-		tm -= timezone_offset;
         }
 
-	xtime.tv_sec = tm;
-	xtime.tv_nsec = 0;
 	do_gtod.varp = &do_gtod.vars[0];
 	do_gtod.var_idx = 0;
 	do_gtod.varp->tb_orig_stamp = tb_last_jiffy;
@@ -1009,9 +982,6 @@ void __init time_init(void)
 
 	time_freq = 0;
 
-	last_rtc_update = xtime.tv_sec;
-	set_normalized_timespec(&wall_to_monotonic,
-	                        -xtime.tv_sec, -xtime.tv_nsec);
 	write_sequnlock_irqrestore(&xtime_lock, flags);
 
 	/* Not exact, but the timer interrupt takes care of this */
Index: working/arch/powerpc/sysdev/Makefile
===================================================================
--- working.orig/arch/powerpc/sysdev/Makefile
+++ working/arch/powerpc/sysdev/Makefile
@@ -20,11 +20,6 @@ obj-$(CONFIG_MV64X60)		+= $(mv64x60-y) m
 obj-$(CONFIG_RTC_DRV_CMOS)	+= rtc_cmos_setup.o
 obj-$(CONFIG_AXON_RAM)		+= axonram.o
 
-# contains only the suspend handler for time
-ifeq ($(CONFIG_RTC_CLASS),)
-obj-$(CONFIG_PM)		+= timer.o
-endif
-
 ifeq ($(CONFIG_PPC_MERGE),y)
 obj-$(CONFIG_PPC_INDIRECT_PCI)	+= indirect_pci.o
 obj-$(CONFIG_PPC_I8259)		+= i8259.o


Yours Tony

  linux.conf.au        http://linux.conf.au/ || http://lca2008.linux.org.au/
  Jan 28 - Feb 02 2008 The Australian Linux Technical Conference!

^ permalink raw reply

* Fix "no_sync_cmos_clock"  logic inversion in kernel/time/ntp.c
From: Tony Breeds @ 2007-09-11  7:46 UTC (permalink / raw)
  To: Linux Kernel ML, LinuxPPC-dev
  Cc: zach, John Stultz, Paul Mackerras, Andrew Morton, Thomas Gleixner


Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>

---

Seems to me that this timer will only get started on platforms that say
they don't want it?

 kernel/time/ntp.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: working/kernel/time/ntp.c
===================================================================
--- working.orig/kernel/time/ntp.c	2007-09-11 17:34:44.000000000 +1000
+++ working/kernel/time/ntp.c	2007-09-11 17:34:55.000000000 +1000
@@ -226,7 +226,7 @@ static void sync_cmos_clock(unsigned lon
 
 static void notify_cmos_timer(void)
 {
-	if (no_sync_cmos_clock)
+	if (!no_sync_cmos_clock)
 		mod_timer(&sync_cmos_timer, jiffies + 1);
 }
 

Yours Tony

  linux.conf.au        http://linux.conf.au/ || http://lca2008.linux.org.au/
  Jan 28 - Feb 02 2008 The Australian Linux Technical Conference!

^ permalink raw reply

* [PATCH] [POWERPC] 85xx: Add basic Uniprocessor MPC8572 DS port
From: Kumar Gala @ 2007-09-11  6:29 UTC (permalink / raw)
  To: linuxppc-dev

Added basic board port for MPC8572 DS reference platform that is
similiar to the MPC8544/33 DS reference platform in uniprocessor mode.

---

Posted here for review.  Patch exists in my for-2.6.24 branch. Removed
defconfig to reduce patch review size.

 arch/powerpc/boot/dts/mpc8572ds.dts       |  378 ++++++++
 arch/powerpc/configs/mpc8572_ds_defconfig | 1496 +++++++++++++++++++++++++++++
 arch/powerpc/platforms/85xx/mpc85xx_ds.c  |   31 +
 arch/powerpc/sysdev/fsl_pci.c             |    2 +
 include/linux/pci_ids.h                   |    5 +-
 5 files changed, 1910 insertions(+), 2 deletions(-)
 create mode 100644 arch/powerpc/boot/dts/mpc8572ds.dts
 create mode 100644 arch/powerpc/configs/mpc8572_ds_defconfig

diff --git a/arch/powerpc/boot/dts/mpc8572ds.dts b/arch/powerpc/boot/dts/mpc8572ds.dts
new file mode 100644
index 0000000..9d23561
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc8572ds.dts
@@ -0,0 +1,378 @@
+/*
+ * MPC8572 DS Device Tree Source
+ *
+ * Copyright 2007 Freescale Semiconductor Inc.
+ *
+ * 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.
+ */
+
+/ {
+	model = "MPC8572DS";
+	compatible = "MPC8572DS", "MPC85xxDS";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#cpus = <1>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,8572@0 {
+			device_type = "cpu";
+			reg = <0>;
+			d-cache-line-size = <20>;	// 32 bytes
+			i-cache-line-size = <20>;	// 32 bytes
+			d-cache-size = <8000>;		// L1, 32K
+			i-cache-size = <8000>;		// L1, 32K
+			timebase-frequency = <0>;
+			bus-frequency = <0>;
+			clock-frequency = <0>;
+			32-bit;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <00000000 00000000>;	// Filled by U-Boot
+	};
+
+	soc8572@ffe00000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		#interrupt-cells = <2>;
+		device_type = "soc";
+		ranges = <00000000 ffe00000 00100000
+			  80000000 80000000 20000000
+			  a0000000 a0000000 20000000
+			  c0000000 c0000000 20000000
+			  ffc00000 ffc00000 00010000
+			  ffc10000 ffc10000 00010000
+			  ffc20000 ffc20000 00010000>;
+
+		reg = <ffe00000 00001000>;	// CCSRBAR 1M
+		bus-frequency = <0>;		// Filled out by uboot.
+
+		memory-controller@2000 {
+			compatible = "fsl,8572-memory-controller";
+			reg = <2000 1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <12 2>;
+		};
+
+		l2-cache-controller@20000 {
+			compatible = "fsl,8572-l2-cache-controller";
+			reg = <20000 1000>;
+			cache-line-size = <20>;	// 32 bytes
+			cache-size = <80000>;	// L2, 512K
+			interrupt-parent = <&mpic>;
+			interrupts = <10 2>;
+		};
+
+		i2c@3000 {
+			device_type = "i2c";
+			compatible = "fsl-i2c";
+			reg = <3000 100>;
+			interrupts = <2b 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+		};
+
+		mdio@24520 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "mdio";
+			compatible = "gianfar";
+			reg = <24520 20>;
+			phy0: ethernet-phy@0 {
+				interrupt-parent = <&mpic>;
+				interrupts = <a 1>;
+				reg = <0>;
+				device_type = "ethernet-phy";
+			};
+			phy1: ethernet-phy@1 {
+				interrupt-parent = <&mpic>;
+				interrupts = <a 1>;
+				reg = <1>;
+				device_type = "ethernet-phy";
+			};
+			phy2: ethernet-phy@2 {
+				interrupt-parent = <&mpic>;
+				interrupts = <a 1>;
+				reg = <2>;
+				device_type = "ethernet-phy";
+			};
+			phy3: ethernet-phy@3 {
+				interrupt-parent = <&mpic>;
+				interrupts = <a 1>;
+				reg = <3>;
+				device_type = "ethernet-phy";
+			};
+		};
+
+		ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <24000 1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <1d 2 1e 2 22 2>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy0>;
+			phy-connection-type = "rgmii-id";
+		};
+
+		ethernet@25000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <25000 1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <23 2 24 2 28 2>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy1>;
+			phy-connection-type = "rgmii-id";
+		};
+
+		ethernet@26000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <26000 1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <1f 2 20 2 21 2>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy2>;
+			phy-connection-type = "rgmii-id";
+		};
+
+		ethernet@27000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <27000 1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <25 2 26 2 27 2>;
+			interrupt-parent = <&mpic>;
+			phy-handle = <&phy3>;
+			phy-connection-type = "rgmii-id";
+		};
+
+		serial@4500 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <4500 100>;
+			clock-frequency = <0>;
+			interrupts = <2a 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		serial@4600 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <4600 100>;
+			clock-frequency = <0>;
+			interrupts = <2a 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		pcie@8000 {
+			compatible = "fsl,mpc8641-pcie";
+			device_type = "pci";
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			reg = <8000 1000>;
+			bus-range = <0 ff>;
+			ranges = <02000000 0 80000000 80000000 0 20000000
+				  01000000 0 00000000 ffc00000 0 00010000>;
+			clock-frequency = <1fca055>;
+			interrupt-parent = <&mpic>;
+			interrupts = <18 2>;
+			interrupt-map-mask = <fb00 0 0 0>;
+			interrupt-map = <
+				/* IDSEL 0x11 - PCI slot 1 */
+				8800 0 0 1 &mpic 2 1
+				8800 0 0 2 &mpic 3 1
+				8800 0 0 3 &mpic 4 1
+				8800 0 0 4 &mpic 1 1
+
+				/* IDSEL 0x12 - PCI slot 2 */
+				9000 0 0 1 &mpic 3 1
+				9000 0 0 2 &mpic 4 1
+				9000 0 0 3 &mpic 1 1
+				9000 0 0 4 &mpic 2 1
+
+				// IDSEL 0x1c  USB
+				e000 0 0 0 &i8259 c 2
+				e100 0 0 0 &i8259 9 2
+				e200 0 0 0 &i8259 a 2
+				e300 0 0 0 &i8259 b 2
+
+				// IDSEL 0x1d  Audio
+				e800 0 0 0 &i8259 6 2
+
+				// IDSEL 0x1e Legacy
+				f000 0 0 0 &i8259 7 2
+				f100 0 0 0 &i8259 7 2
+
+				// IDSEL 0x1f IDE/SATA
+				f800 0 0 0 &i8259 e 2
+				f900 0 0 0 &i8259 5 2
+
+				>;
+			uli1575@0 {
+				reg = <0 0 0 0 0>;
+				#size-cells = <2>;
+				#address-cells = <3>;
+				ranges = <02000000 0 80000000
+					  02000000 0 80000000
+					  0 20000000
+					  01000000 0 00000000
+					  01000000 0 00000000
+					  0 00100000>;
+
+				pci_bridge@0 {
+					reg = <0 0 0 0 0>;
+					#size-cells = <2>;
+					#address-cells = <3>;
+					ranges = <02000000 0 80000000
+						  02000000 0 80000000
+						  0 20000000
+						  01000000 0 00000000
+						  01000000 0 00000000
+						  0 00100000>;
+
+					isa@1e {
+						device_type = "isa";
+						#interrupt-cells = <2>;
+						#size-cells = <1>;
+						#address-cells = <2>;
+						reg = <f000 0 0 0 0>;
+						ranges = <1 0 01000000 0 0
+							  00001000>;
+						interrupt-parent = <&i8259>;
+
+						i8259: interrupt-controller@20 {
+							reg = <1 20 2
+							       1 a0 2
+							       1 4d0 2>;
+							clock-frequency = <0>;
+							interrupt-controller;
+							device_type = "interrupt-controller";
+							#address-cells = <0>;
+							#interrupt-cells = <2>;
+							built-in;
+							compatible = "chrp,iic";
+							interrupts = <9 2>;
+							interrupt-parent =
+								<&mpic>;
+						};
+
+						i8042@60 {
+							#size-cells = <0>;
+							#address-cells = <1>;
+							reg = <1 60 1 1 64 1>;
+							interrupts = <1 3 c 3>;
+							interrupt-parent =
+								<&i8259>;
+
+							keyboard@0 {
+								reg = <0>;
+								compatible = "pnpPNP,303";
+							};
+
+							mouse@1 {
+								reg = <1>;
+								compatible = "pnpPNP,f03";
+							};
+						};
+
+						rtc@70 {
+							compatible = "pnpPNP,b00";
+							reg = <1 70 2>;
+						};
+
+						gpio@400 {
+							reg = <1 400 80>;
+						};
+					};
+				};
+			};
+
+		};
+
+		pcie@9000 {
+			compatible = "fsl,mpc8548-pcie";
+			device_type = "pci";
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			reg = <9000 1000>;
+			bus-range = <0 ff>;
+			ranges = <02000000 0 a0000000 a0000000 0 20000000
+				  01000000 0 00000000 ffc10000 0 00010000>;
+			clock-frequency = <1fca055>;
+			interrupt-parent = <&mpic>;
+			interrupts = <1a 2>;
+			interrupt-map-mask = <f800 0 0 7>;
+			interrupt-map = <
+				/* IDSEL 0x0 */
+				0000 0 0 1 &mpic 4 1
+				0000 0 0 2 &mpic 5 1
+				0000 0 0 3 &mpic 6 1
+				0000 0 0 4 &mpic 7 1
+				>;
+		};
+
+		pcie@a000 {
+			compatible = "fsl,mpc8548-pcie";
+			device_type = "pci";
+			#interrupt-cells = <1>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			reg = <a000 1000>;
+			bus-range = <0 ff>;
+			ranges = <02000000 0 c0000000 c0000000 0 20000000
+				  01000000 0 00000000 ffc20000 0 00010000>;
+			clock-frequency = <1fca055>;
+			interrupt-parent = <&mpic>;
+			interrupts = <1b 2>;
+			interrupt-map = <
+				/* IDSEL 0x0 */
+				0000 0 0 1 &mpic 0 1
+				0000 0 0 2 &mpic 1 1
+				0000 0 0 3 &mpic 2 1
+				0000 0 0 4 &mpic 3 1
+				>;
+		};
+
+		global-utilities@e0000 {	//global utilities block
+			compatible = "fsl,mpc8548-guts";
+			reg = <e0000 1000>;
+			fsl,has-rstcr;
+		};
+
+		mpic: pic@40000 {
+			clock-frequency = <0>;
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <40000 40000>;
+			built-in;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+			big-endian;
+		};
+	};
+};
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
index 3a5c3c4..1e2eba8 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
@@ -181,6 +181,23 @@ static int __init mpc8544_ds_probe(void)
 	}
 }

+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init mpc8572_ds_probe(void)
+{
+	unsigned long root = of_get_flat_dt_root();
+
+	if (of_flat_dt_is_compatible(root, "MPC8572DS")) {
+#ifdef CONFIG_PCI
+		primary_phb_addr = 0x8000;
+#endif
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
 define_machine(mpc8544_ds) {
 	.name			= "MPC8544 DS",
 	.probe			= mpc8544_ds_probe,
@@ -194,3 +211,17 @@ define_machine(mpc8544_ds) {
 	.calibrate_decr		= generic_calibrate_decr,
 	.progress		= udbg_progress,
 };
+
+define_machine(mpc8572_ds) {
+	.name			= "MPC8572 DS",
+	.probe			= mpc8572_ds_probe,
+	.setup_arch		= mpc85xx_ds_setup_arch,
+	.init_IRQ		= mpc85xx_ds_pic_init,
+#ifdef CONFIG_PCI
+	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+#endif
+	.get_irq		= mpic_get_irq,
+	.restart		= mpc85xx_restart,
+	.calibrate_decr		= generic_calibrate_decr,
+	.progress		= udbg_progress,
+};
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 114c90f..34cad96 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -255,5 +255,7 @@ DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533E, quirk_fsl_pcie_transpare
 DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533, quirk_fsl_pcie_transparent);
 DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544E, quirk_fsl_pcie_transparent);
 DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544, quirk_fsl_pcie_transparent);
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8572E, quirk_fsl_pcie_transparent)
+DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8572, quirk_fsl_pcie_transparent);
 DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_transparent);
 DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_transparent);
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 06d23e1..c98b867 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -374,10 +374,9 @@
 #define PCI_DEVICE_ID_ATI_IXP400_SATA   0x4379
 #define PCI_DEVICE_ID_ATI_IXP400_SATA2	0x437a
 #define PCI_DEVICE_ID_ATI_IXP600_SATA	0x4380
-#define PCI_DEVICE_ID_ATI_IXP600_SMBUS	0x4385
+#define PCI_DEVICE_ID_ATI_SBX00_SMBUS	0x4385
 #define PCI_DEVICE_ID_ATI_IXP600_IDE	0x438c
 #define PCI_DEVICE_ID_ATI_IXP700_SATA	0x4390
-#define PCI_DEVICE_ID_ATI_IXP700_SMBUS	0x4395
 #define PCI_DEVICE_ID_ATI_IXP700_IDE	0x439c

 #define PCI_VENDOR_ID_VLSI		0x1004
@@ -2100,6 +2099,8 @@
 #define PCI_DEVICE_ID_MPC8533		0x0031
 #define PCI_DEVICE_ID_MPC8544E		0x0032
 #define PCI_DEVICE_ID_MPC8544		0x0033
+#define PCI_DEVICE_ID_MPC8572E		0x0040
+#define PCI_DEVICE_ID_MPC8572		0x0041
 #define PCI_DEVICE_ID_MPC8641		0x7010
 #define PCI_DEVICE_ID_MPC8641D		0x7011

-- 
1.5.2.4

^ permalink raw reply related

* Re: [PATCH 1/3] fsl_soc.c cleanup
From: Kumar Gala @ 2007-09-11  5:35 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20070828201618.GA24210@ld0162-tx32.am.freescale.net>


On Aug 28, 2007, at 3:16 PM, Scott Wood wrote:

> 1. Fix get_immrbase() to use ranges, rather than reg.
>
> It is not always the case that the SoC's first reg property points
> to the beginning of the entire SoC block.

when is this true?

Upon further testing this breaks some platforms.  I don't think  
assuming the first range entry is mapping to the SOC register space  
is a good idea.

I've dropped this portion of the patch from my tree for the time being.

- k

^ permalink raw reply

* Re: [PATCH] export new __io{re,un}map_at() symbols
From: Olof Johansson @ 2007-09-10 23:34 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <18149.52956.875510.937857@cargo.ozlabs.ibm.com>

On Tue, Sep 11, 2007 at 09:10:20AM +1000, Paul Mackerras wrote:
> Olof Johansson writes:
> 
> > electra_cf uses it, that driver is currently in -mm including below
> > update to use benh's rewritten interfaces:
> > 
> > http://patchwork.ozlabs.org/linuxppc/patch?id=13237
> > 
> > It gets the effective addresses to use out of the device tree.
> 
> Huh?  What does firmware (or the device tree) know about how the
> kernel uses effective addresses?

Oh, sorry, of course it doesn't (I was thinking of the physical address
but writing effective).

I get effective address by allocating it with __get_vm_area same way
the pseries pci hotplug does:

	area = __get_vm_area(cf->io_size, 0, PHB_IO_BASE, PHB_IO_END);
	if (area == NULL)
		return -ENOMEM;

	cf->io_virt = (void __iomem *)(area->addr);


-Olof

^ permalink raw reply

* Re: Which 2.6 kernel for MPC5200
From: Jon Smirl @ 2007-09-10 23:22 UTC (permalink / raw)
  To: Grant Likely; +Cc: Babarovic Ivica, linuxppc-embedded
In-Reply-To: <fa686aa40709101120u1310845et866b8fa6df7c5154@mail.gmail.com>

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

On 9/10/07, Grant Likely <grant.likely@secretlab.ca> wrote:
> On 9/10/07, Babarovic Ivica <ivica.babarovic@asist.si> wrote:
> > Hi!
> >
> > What kernel should I get/pull for MPC5200 clone board.
> > I've been away from coding on mpc5200 for quite some time now.
> > I've read some archives from ML.
> > Git repo on Sylvain Munauts url:
> > http://gitbits.246tNt.com/gitbits/linux-2.6-mpc52xx.gitpage
> > isn't working. Nothing on http://*git*.secretlab.ca/cgi-bin/*gitweb*.cgi
> > <http://git.secretlab.ca/cgi-bin/gitweb.cgi> to.
> >
> > I've pulled the sources from kernel.org git server.
> > git clone
> > git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
> > linux-2.6-mpc52xx
>
> My 52xx git tree became way out of date, so I dropped it from the
> server.  Best bet is to use mainline which gives your everything
> except the drivers that use the bestcomm DMA engine (like Ethernet).
>
> Then you need to apply the bestcomm patches.  You can get them here:
>
> http://www.246tnt.com/mpc52xx/dev_full/

I just finished rebasing the Efika version of those patches to current mainline.

I'm working on merging support for my Phytec pcm030 into them.
After I get stable the plan is to switch over to Domon's new FEC driver.


>
> Have fun,
> g.
>
> --
> Grant Likely, B.Sc., P.Eng.
> Secret Lab Technologies Ltd.
> grant.likely@secretlab.ca
> (403) 399-0195
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>


-- 
Jon Smirl
jonsmirl@gmail.com

[-- Attachment #2: mpc.tgz --]
[-- Type: application/x-gzip, Size: 45497 bytes --]

^ permalink raw reply

* Re: [PATCH] export new __io{re,un}map_at() symbols
From: Paul Mackerras @ 2007-09-10 23:10 UTC (permalink / raw)
  To: Olof Johansson; +Cc: linuxppc-dev
In-Reply-To: <20070910224136.GA28808@lixom.net>

Olof Johansson writes:

> electra_cf uses it, that driver is currently in -mm including below
> update to use benh's rewritten interfaces:
> 
> http://patchwork.ozlabs.org/linuxppc/patch?id=13237
> 
> It gets the effective addresses to use out of the device tree.

Huh?  What does firmware (or the device tree) know about how the
kernel uses effective addresses?

Paul.

^ permalink raw reply

* [PATCH] add Vitaly as PPC8xx maintainer
From: Marcelo Tosatti @ 2007-09-10 22:46 UTC (permalink / raw)
  To: Paul Mackerras, Vitaly Bordug; +Cc: linux-ppc-embedded


Hi Paul,

Vitaly has been doing most of the 8xx maintenance work.

Please apply, thanks.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

diff --git a/MAINTAINERS b/MAINTAINERS
index a723adc..318792b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2219,6 +2219,8 @@ L:        linuxppc-embedded@ozlabs.org
 S:     Maintained

 LINUX FOR POWERPC EMBEDDED PPC8XX
+P:     Vitaly Bordug
+M:     vitb@kernel.crashing.org
 P:     Marcelo Tosatti
 M:     marcelo@kvack.org
 W:     http://www.penguinppc.org/

^ permalink raw reply related

* Re: [PATCH] export new __io{re,un}map_at() symbols
From: Olof Johansson @ 2007-09-10 22:41 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <18149.48608.754709.782967@cargo.ozlabs.ibm.com>

Hi,

On Tue, Sep 11, 2007 at 07:57:52AM +1000, Paul Mackerras wrote:
> Olof Johansson writes:
> 
> > Export new __io{re,un}map_at() symbols so modules can use them.
> 
> What module wants to use these?  How is it going to work out what
> effective address to use?

electra_cf uses it, that driver is currently in -mm including below
update to use benh's rewritten interfaces:

http://patchwork.ozlabs.org/linuxppc/patch?id=13237

It gets the effective addresses to use out of the device tree.


-Olof

^ permalink raw reply

* RE: futex priority based wakeup
From: Benedict, Michael @ 2007-09-10 21:41 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <000e01c7f177$05ab1990$3a0d10ac@Radstone.Local>

Ilya Lipovsky wrote:
> Your code looks correct to me, so if the kernel developers
> did their job
> correctly, the only potentially weak link is glibc.
>=20

Well, either the kernel developers didn't do their job, or I am missing
something.  The following also fails, and it should be bypassing glibc:

#define _XOPEN_SOURCE 600

#include <linux/futex.h>
#include <sys/time.h>
#include <asm/atomic.h>

#include <sys/syscall.h>
#include <unistd.h>

#include <sched.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

int myfutex =3D 0;

void *important(void *ign)
{
        sleep(1);
        printf("important waiting for futex\n");
        fflush(stdout);
        if(syscall(SYS_futex, &myfutex, FUTEX_WAIT, 0, NULL)) {
                perror("futex");
                exit(1);
        } else {
                printf("important got futex!\n");
                fflush(stdout);
                syscall(SYS_futex, &myfutex, FUTEX_WAKE, 1, NULL);
}

        return NULL;
}


void *unimportant(void *ign)
{
        printf("unimportant waiting for futex\n");
        fflush(stdout);
        if(syscall(SYS_futex, &myfutex, FUTEX_WAIT, 0, NULL)) {
                perror("futex");
                exit(1);
        } else {
                printf("unimportant got futex!\n");
                fflush(stdout);
                syscall(SYS_futex, &myfutex, FUTEX_WAKE, 1, NULL);
}

        return NULL;
}

int main()
{
        struct sched_param p;
        pthread_attr_t attr;
        pthread_t i, u;

        p.__sched_priority =3D sched_get_priority_min(SCHED_FIFO);
        if(-1 =3D=3D p.__sched_priority) {
                perror("sched_get_priority_min");
                return 1;
        }
        pthread_attr_init(&attr);
        pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
        pthread_attr_setschedparam(&attr, &p);
        pthread_create(&u, &attr, unimportant, NULL);

        p.__sched_priority =3D sched_get_priority_max(SCHED_FIFO);
        pthread_attr_setschedparam(&attr, &p);
        pthread_create(&i, &attr, important, NULL);

        sleep(5);
        printf("futex FUTEX_WAKE\n");
        fflush(stdout);
        syscall(SYS_futex, &myfutex, FUTEX_WAKE, 1, NULL);

        pthread_join(u, NULL);
        pthread_join(i, NULL);

        return 0;
}

Which produces:
unimportant waiting for futex
important waiting for futex
futex FUTEX_WAKE
unimportant got futex!
important got futex!


Could someone with 2.6.22 please verify? =20

^ 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