LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Please pull from 'for-2.6.24' branch of 4xx tree
From: Josh Boyer @ 2007-10-02 12:54 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

Hi Paul,

Please pull from

 master.kernel.org:/pub/scm/linux/kernel/git/jwboyer/powerpc-4xx.git for-2.6.24

to pick up a handful of new items for 2.6.24.  Initial Virtex support
from Grant, some cpu setup functions for 4xx from Valentine, a compile
fix for the Walnut wrapper, and a small number of arch/ppc fixes for
Xilinx boards.

Grant Likely (15):
      [POWERPC] Virtex: Add uartlite bootwrapper driver
      [POWERPC] Virtex: Add Kconfig macros for Xilinx Virtex board support
      [POWERPC] Virtex: add xilinx interrupt controller driver
      [POWERPC] Virtex: Add generic Xilinx Virtex board support
      [POWERPC] Add PowerPC Xilinx Virtex entry to maintainers
      [POWERPC] Uartlite: Fix reg io to access documented register size
      [POWERPC] Uartlite: change name of ports to ulite_ports
      [POWERPC] Uartlite: Add macro for uartlite device name
      [POWERPC] Uartlite: Separate the bus binding from the driver proper
      [POWERPC] Uartlite: Comment block tidy
      [POWERPC] Uartlite: Add of-platform-bus binding
      [POWERPC] Uartlite: Let the console be initialized earlier
      [POWERPC] Uartlite: Flush RX fifo in bootwrapper
      [POWERPC] XilinxFB: Move xilinxfb_platform_data definition to a shared hea
      [POWERPC] Setup default eth addr in embed_config for Xilinx Virtex platfor

Josh Boyer (2):
      [POWERPC] 4xx: Fix Walnut wrapper compile errors
      [POWERPC] Add treeImage to .gitignore

Valentine Barshak (3):
      [POWERPC] 4xx: Introduce cpu_setup functionality to 44x platform
      [POWERPC] 4xx: Move 440EP(x) FPU setup from head_44x to cpu_setup_4xx
      [POWERPC] 4xx: 440EPx/GRx incorrect write to DDR SDRAM errata workaround

 MAINTAINERS                          |    7 +
 arch/powerpc/boot/.gitignore         |    1 +
 arch/powerpc/boot/Makefile           |    3 +-
 arch/powerpc/boot/ops.h              |    1 +
 arch/powerpc/boot/serial.c           |    2 +
 arch/powerpc/boot/uartlite.c         |   64 +++++++
 arch/powerpc/kernel/Makefile         |    1 +
 arch/powerpc/kernel/cpu_setup_44x.S  |   56 ++++++
 arch/powerpc/kernel/cputable.c       |   22 ++-
 arch/powerpc/kernel/head_44x.S       |   10 -
 arch/powerpc/platforms/40x/Kconfig   |   38 +++--
 arch/powerpc/platforms/40x/Makefile  |    1 +
 arch/powerpc/platforms/40x/virtex.c  |   50 ++++++
 arch/powerpc/sysdev/Makefile         |    1 +
 arch/powerpc/sysdev/xilinx_intc.c    |  151 ++++++++++++++++
 arch/ppc/boot/simple/embed_config.c  |    8 +
 arch/ppc/boot/simple/misc-embedded.c |    4 +-
 arch/ppc/boot/simple/uartlite_tty.c  |    8 +
 arch/ppc/syslib/virtex_devices.c     |    2 +-
 arch/ppc/syslib/virtex_devices.h     |    8 +-
 drivers/serial/uartlite.c            |  318 +++++++++++++++++++++++++++-------
 drivers/video/xilinxfb.c             |    2 +-
 include/asm-powerpc/xilinx_intc.h    |   20 ++
 include/linux/xilinxfb.h             |   23 +++
 24 files changed, 698 insertions(+), 103 deletions(-)
 create mode 100644 arch/powerpc/boot/uartlite.c
 create mode 100644 arch/powerpc/kernel/cpu_setup_44x.S
 create mode 100644 arch/powerpc/platforms/40x/virtex.c
 create mode 100644 arch/powerpc/sysdev/xilinx_intc.c
 create mode 100644 include/asm-powerpc/xilinx_intc.h
 create mode 100644 include/linux/xilinxfb.h

^ permalink raw reply

* Re: [RFC PATCH v0.2] net driver: mpc52xx fec
From: Sascha Hauer @ 2007-10-02 12:49 UTC (permalink / raw)
  To: Domen Puncer; +Cc: netdev, linuxppc-embedded
In-Reply-To: <20070902074143.GB2642@nd47.coderock.org>


Hi Domen,

On Sun, Sep 02, 2007 at 09:41:43AM +0200, Domen Puncer wrote:
 + */
> +static void fec_start(struct net_device *dev)
> +{
> +	struct fec_priv *priv = netdev_priv(dev);
> +	struct mpc52xx_fec __iomem *fec = priv->fec;
> +	u32 rcntrl;
> +	u32 tcntrl;
> +	u32 tmp;
> +
> +	/* clear sticky error bits */
> +	tmp = FEC_FIFO_STATUS_ERR | FEC_FIFO_STATUS_UF | FEC_FIFO_STATUS_OF;
> +	out_be32(&fec->rfifo_status, in_be32(&fec->rfifo_status) & tmp);
> +	out_be32(&fec->tfifo_status, in_be32(&fec->tfifo_status) & tmp);
> +
> +	/* FIFOs will reset on fec_enable */
> +	out_be32(&fec->reset_cntrl, FEC_RESET_CNTRL_ENABLE_IS_RESET);
> +
> +	/* Set station address. */
> +	fec_set_paddr(dev, dev->dev_addr);
> +
> +	fec_set_multicast_list(dev);
> +
> +	/* set max frame len, enable flow control, select mii mode */
> +	rcntrl = FEC_RX_BUFFER_SIZE << 16;	/* max frame length */
> +	rcntrl |= FEC_RCNTRL_FCE;
> +	rcntrl |= MII_RCNTL_MODE;
> +	if (priv->duplex == DUPLEX_FULL)
> +		tcntrl = FEC_TCNTRL_FDEN;	/* FD enable */
> +	else {
> +		rcntrl |= FEC_RCNTRL_DRT;	/* disable Rx on Tx (HD) */
> +		tcntrl = 0;
> +	}
> +	out_be32(&fec->r_cntrl, rcntrl);
> +	out_be32(&fec->x_cntrl, tcntrl);
> +
> +	/* Clear any outstanding interrupt. */
> +	out_be32(&fec->ievent, 0xffffffff);
> +
> +	/* Enable interrupts we wish to service. */
> +	out_be32(&fec->imask, FEC_IMASK_ENABLE);


This disables phy interrupts.


> +static int fec_mdio_read(struct mii_bus *bus, int phy_id, int reg)
> +{
> +	struct fec_mdio_priv *priv = bus->priv;
> +	int tries = 100;
> +
> +	u32 request = FEC_MII_READ_FRAME;
> +	request |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
> +	request |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
> +
> +	out_be32(&priv->regs->mii_data, request);
> +
> +	/* wait for it to finish, this takes about 23 us on lite5200b */
> +	while (priv->completed == 0 && tries--)
> +		udelay(5);
> +
> +	priv->completed = 0;
> +
> +	if (tries == 0)
> +		return -ETIMEDOUT;

This does not work as expected. When a timeout occurs tries is -1 not 0,
so the test above will never trigger.
Using --tries instead of tries-- reveals another bug. We get a timeout
everytime now, because MII interrupts are accidently disabled in
fec_start().

We cannot use a waitqueue or similar for waiting for the mii transfer
because we are atomic here.
A simple fix is provided below. It removes the need for the interrupt
handler in the phy handling routines. Anyway, it might be better to fix
the phy layer not to use atomic contexts, so this patch might not be the
way to go.


Regards, 
  Sascha

 +
> +static int fec_mdio_probe(struct of_device *of, const struct of_device_id *match)
> +{
> +	struct device *dev = &of->dev;
>
>       [...]
>
> +	init_waitqueue_head(&priv->wq);

This waitqueue is never used. wake_up() is called in the interrupt
handler, but noone ever sleeps on the queue.


---
 drivers/net/fec_mpc52xx/fec.c     |    7 +---
 drivers/net/fec_mpc52xx/fec_phy.c |   59 +++++++-------------------------------
 2 files changed, 15 insertions(+), 51 deletions(-)

Index: linux-2.6.23-rc8/drivers/net/fec_mpc52xx/fec.c
===================================================================
--- linux-2.6.23-rc8.orig/drivers/net/fec_mpc52xx/fec.c
+++ linux-2.6.23-rc8/drivers/net/fec_mpc52xx/fec.c
@@ -265,7 +265,6 @@ static void fec_phy_hw_init(struct fec_p
 		return;
 
 	out_be32(&fec->mii_speed, priv->phy_speed);
-	out_be32(&fec->imask, in_be32(&fec->imask) | FEC_IMASK_MII);
 }
 
 static int fec_open(struct net_device *dev)
@@ -654,7 +653,7 @@ static void fec_hw_init(struct net_devic
 	out_be32(&fec->iaddr1, 0x00000000);	/* No individual filter */
 	out_be32(&fec->iaddr2, 0x00000000);	/* No individual filter */
 
-	/* set phy speed and enable MII interrupt
+	/* set phy speed.
 	 * this can't be done in phy driver, since it needs to be called
 	 * before fec stuff (even on resume) */
 	fec_phy_hw_init(priv);
@@ -730,8 +729,8 @@ static void fec_stop(struct net_device *
 	struct mpc52xx_fec __iomem *fec = priv->fec;
 	unsigned long timeout;
 
-	/* disable all but MII interrupt */
-	out_be32(&fec->imask, in_be32(&fec->imask) & FEC_IMASK_MII);
+	/* disable all interrupts */
+	out_be32(&fec->imask, 0);
 
 	/* Disable the rx task. */
 	bcom_disable(priv->rx_dmatsk);
Index: linux-2.6.23-rc8/drivers/net/fec_mpc52xx/fec_phy.c
===================================================================
--- linux-2.6.23-rc8.orig/drivers/net/fec_mpc52xx/fec_phy.c
+++ linux-2.6.23-rc8/drivers/net/fec_mpc52xx/fec_phy.c
@@ -18,29 +18,28 @@
 #include "fec.h"
 
 struct fec_mdio_priv {
-	int completed;
-	wait_queue_head_t wq;
 	struct mpc52xx_fec __iomem *regs;
-	int irq;
 };
 
 static int fec_mdio_read(struct mii_bus *bus, int phy_id, int reg)
 {
 	struct fec_mdio_priv *priv = bus->priv;
+	struct mpc52xx_fec __iomem *fec;
 	int tries = 100;
-
 	u32 request = FEC_MII_READ_FRAME;
+
+	fec = priv->regs;
+	out_be32(&fec->ievent, FEC_IEVENT_MII);
+
 	request |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
 	request |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
 
 	out_be32(&priv->regs->mii_data, request);
 
 	/* wait for it to finish, this takes about 23 us on lite5200b */
-	while (priv->completed == 0 && tries--)
+	while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries)
 		udelay(5);
 
-	priv->completed = 0;
-
 	if (tries == 0)
 		return -ETIMEDOUT;
 
@@ -50,9 +49,13 @@ static int fec_mdio_read(struct mii_bus 
 static int fec_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 data)
 {
 	struct fec_mdio_priv *priv = bus->priv;
+	struct mpc52xx_fec __iomem *fec;
 	u32 value = data;
 	int tries = 100;
 
+	fec = priv->regs;
+	out_be32(&fec->ievent, FEC_IEVENT_MII);
+
 	value |= FEC_MII_WRITE_FRAME;
 	value |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
 	value |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
@@ -60,38 +63,15 @@ static int fec_mdio_write(struct mii_bus
 	out_be32(&priv->regs->mii_data, value);
 
 	/* wait for request to finish */
-	while (priv->completed == 0 && tries--)
+	while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries)
 		udelay(5);
 
-	priv->completed = 0;
-
 	if (tries == 0)
 		return -ETIMEDOUT;
 
 	return 0;
 }
 
-static irqreturn_t fec_mdio_interrupt(int irq, void *dev_id)
-{
-	struct fec_mdio_priv *priv = dev_id;
-	struct mpc52xx_fec __iomem *fec;
-	int ievent;
-
-	fec = priv->regs;
-	ievent = in_be32(&fec->ievent);
-
-	ievent &= FEC_IEVENT_MII;
-	if (!ievent)
-		return IRQ_NONE;
-
-	out_be32(&fec->ievent, ievent);
-
-	priv->completed = 1;
-	wake_up(&priv->wq);
-
-	return IRQ_HANDLED;
-}
-
 static int fec_mdio_probe(struct of_device *of, const struct of_device_id *match)
 {
 	struct device *dev = &of->dev;
@@ -143,22 +123,12 @@ static int fec_mdio_probe(struct of_devi
 		goto out_free;
 	}
 
-	priv->irq = irq_of_parse_and_map(np, 0);
-	err = request_irq(priv->irq, &fec_mdio_interrupt, IRQF_DISABLED | IRQF_SHARED,
-	                "fec_mdio", priv);
-	if (err) {
-		printk(KERN_ERR "%s: interrupt request failed with %i\n", __func__, err);
-		goto out_unmap;
-	}
-
 	bus->id = res.start;
 	bus->priv = priv;
 
 	bus->dev = dev;
 	dev_set_drvdata(dev, bus);
 
-	init_waitqueue_head(&priv->wq);
-
 	/* set MII speed */
 	out_be32(&priv->regs->mii_speed, ((mpc52xx_find_ipb_freq(of->node) >> 20) / 5) << 1);
 
@@ -167,13 +137,10 @@ static int fec_mdio_probe(struct of_devi
 
 	err = mdiobus_register(bus);
 	if (err)
-		goto out_free_irq;
+		goto out_unmap;
 
 	return 0;
 
- out_free_irq:
-	free_irq(priv->irq, dev);
-	irq_dispose_mapping(priv->irq);
  out_unmap:
 	iounmap(priv->regs);
  out_free:
@@ -197,8 +164,6 @@ static int fec_mdio_remove(struct of_dev
 	mdiobus_unregister(bus);
 	dev_set_drvdata(dev, NULL);
 
-	free_irq(priv->irq, dev);
-	irq_dispose_mapping(priv->irq);
 	iounmap(priv->regs);
 	for (i=0; i<PHY_MAX_ADDR; i++)
 		if (bus->irq[i])

--
Pengutronix - Linux Solutions for Science and Industry
Entwicklungszentrum Nord     http://www.pengutronix.de

^ permalink raw reply

* Re: Problem with OF interrupt parsing code
From: Gerhard Pircher @ 2007-10-02 12:46 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <470165F6.7030505@freescale.com>


-------- Original-Nachricht --------
> Datum: Mon, 01 Oct 2007 16:26:14 -0500
> Von: Scott Wood <scottwood@freescale.com>
> An: Gerhard Pircher <gerhard_pircher@gmx.net>
> CC: linuxppc-dev@ozlabs.org
> Betreff: Re: Problem with OF interrupt parsing code

> > Secondly the AmigaOne is a desktop system with 4 PCI/AGP slots,
> > thus I can't specify device nodes for all possible devices. By looking
> > at pci_read_irq_line() in pci_common.c it should be possible for the
> > kernel to fall back to the interrupt settings in the PCI config space
> > of every device.
> 
> Those interrupt settings are purely a communication vector from firmware 
> to OS.  Is your firmware putting i8259 interrupt numbers in there, and 
> did you set the default interrupt controller?
Yes, the firmware puts the i8259 interrupt numbers in the PCI interrupt
line register and the PIC is setup as default interrupt controller.

Gerhard

-- 
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen! 
Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer

^ permalink raw reply

* Re: Problem with OF interrupt parsing code
From: Gerhard Pircher @ 2007-10-02 12:40 UTC (permalink / raw)
  To: benh, segher; +Cc: linuxppc-dev


-------- Original-Nachricht --------
> Datum: Tue, 02 Oct 2007 08:54:04 +1000
> Von: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> An: Segher Boessenkool <segher@kernel.crashing.org>
> CC: Gerhard Pircher <gerhard_pircher@gmx.net>, linuxppc-dev@ozlabs.org
> Betreff: Re: Problem with OF interrupt parsing code

> It shoudn't normally happen. The reason it -does- happen in fact is that
> the above node is also missing the #interrupt-cells property, which
> cause the parent-lookup routine to skip it before it gets a chance to
> see that there's an "interrupt-controller" property in there.
> 
> I'm not sure whether linux behaviour is a bug or not since I believe we
> are clearly in undefined-land as an interrupt controller should always
> have a #interrupt-cells property.
I think these properties weren't specified in the OF CHRP ISA PIC device
binding document for the PIC node, thus I may have forgotten about them
(CHRP also defines a parent interrupt controller for the PIC, right?).
But the AmigaOne is not a CHRP platform, so I'll add them to the device
tree and then I will see how it works.

Thanks!

Gerhard

^ permalink raw reply

* Re: Problem with OF interrupt parsing code
From: Gerhard Pircher @ 2007-10-02 12:38 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev
In-Reply-To: <1191279244.6310.32.camel@pasglop>


-------- Original-Nachricht --------
> Datum: Tue, 02 Oct 2007 07:39:47 +1000
> Von: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> An: Gerhard Pircher <gerhard_pircher@gmx.net>
> CC: linuxppc-dev@ozlabs.org
> Betreff: Re: Problem with OF interrupt parsing code

> Part of your problem is that interrupt-parent property. You shouldn't
> have such a property in a PCI host bridge. It's not technically illegal,
> but it's triggering the "loop" you've been experiencing.
Okay, I'll remove this one.

> If you want the parsing to fail for PCI devices (to get the fallback to
> config space values), you need to make sure it does fail. 
> 
> Another option is to put an empty interrupt-map in there. That will
> guarantee failure.
> 
> But that's all very ugly. I don't understand why you don't setup a
> proper map either from your bootloader, zImage wrapper or even prom_init
> or platform code.
I know that it's ugly, but the problem is how to distinguish the boards.
The only real difference I know of is the PCI interrupt mapping. The
northbridges chip revision for example is always the same, but CPU type,
amount of memory and PCI devices can appear in all possible combinations.
The firmware doesn't tell me, which board the kernel is runnning on, so I
would like to rely on this fall back here until I get the chance to
update the firmware (which is beyond my control).

Gerhard
-- 
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen! 
Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer

^ permalink raw reply

* Re: [PATCH 2/7] [POWERPC] Fix QEIC->MPIC cascading
From: Anton Vorontsov @ 2007-10-02 12:20 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1191280461.6310.37.camel@pasglop>

On Tue, Oct 02, 2007 at 09:14:21AM +1000, Benjamin Herrenschmidt wrote:
> 
> On Tue, 2007-09-25 at 18:34 +0400, Anton Vorontsov wrote:
> > set_irq_chained_handler overwrites MPIC's handle_irq function
> > (handle_fasteoi_irq) thus MPIC never gets eoi event from the
> > cascaded IRQ. This situation hangs MPIC on MPC8568E.
> > 
> > Patch adds flow level "end" handler to the MPIC, and QEIC calls
> > it when QEIC's interrupt processing finished.
> > 
> > Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
> 
> Not sure if I already NAKed it on the list, so if I didn't here's it :-)
> 
> The proper way of doing that is to have the cascade handler perform the
> EOI call to mpic.

Exactly, this is what that patch is trying to do. QEIC cascade handler is
calling mpic's eoi() (end() actually, as it's flow level, but end == eoi.
Is it main objection? Ok, I can get rid of it, and use chip level eoi()
directly).

> Look at how it's done for i8259 mpic cascade handlers.

void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc)
{       
        unsigned int cascade_irq = i8259_irq();
        if (cascade_irq != NO_IRQ)
                generic_handle_irq(cascade_irq);
        desc->chip->eoi(irq);
}
...
set_irq_chained_handler(cascade_irq, pseries_8259_cascade);

Quite similar... except that it's written in the board file.

> Basically, when doing a cascade nowadays, you can either just do a
> normal request_irq() of the cascade, in which case your handler don't
> have to care about the parent controller at all, but you get various
> limitations and/or overhead from being a full blown interrupt handler,

Though viable, but not an option.

> or you can use the chained handler mechanism which is a "shortcut" but
> implies that your cascade handler "knows" what needs to be done to the
> parent (and thus is specific to the combination parent/child).

Yup, exactly. Actually, QEIC's cascade handlers do not really know
what needs to be done, but they're good at guessing (if (chip->eoi)).

Sure, I can place board-specific QEIC handlers in the board file, but
that will be quite big code duplication for all machines using QEIC.

> Cheers,
> Ben.

Thanks,

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

^ permalink raw reply

* [PATCH] Fix typo in new EMAC driver.
From: Valentine Barshak @ 2007-10-02 12:01 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1191283028.10089.15.camel@localhost.localdomain>

Fix an obvious typo in emac_xmit_finish.

Signed-off-by: Valentine Barshak <vbarshak@ru.mvista.com>
---
 drivers/net/ibm_newemac/core.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff -ruNp linux-2.6.orig/drivers/net/ibm_newemac/core.c linux-2.6/drivers/net/ibm_newemac/core.c
--- linux-2.6.orig/drivers/net/ibm_newemac/core.c	2007-10-01 17:23:35.000000000 +0400
+++ linux-2.6/drivers/net/ibm_newemac/core.c	2007-10-01 17:44:57.000000000 +0400
@@ -1232,9 +1232,9 @@ static inline int emac_xmit_finish(struc
 	 * instead
 	 */
 	if (emac_has_feature(dev, EMAC_FTR_EMAC4))
-		out_be32(&p->tmr0, EMAC_TMR0_XMIT);
-	else
 		out_be32(&p->tmr0, EMAC4_TMR0_XMIT);
+	else
+		out_be32(&p->tmr0, EMAC_TMR0_XMIT);
 
 	if (unlikely(++dev->tx_cnt == NUM_TX_BUFF)) {
 		netif_stop_queue(ndev);

^ permalink raw reply

* mem_init_done (was: Re: [PATCH] [POWERPC] Limit range of __init_ref_ok somewhat)
From: Geert Uytterhoeven @ 2007-10-02 11:42 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: ppc-dev, paulus
In-Reply-To: <20071002133753.662397db.sfr@canb.auug.org.au>

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1396 bytes --]

On Tue, 2 Oct 2007, Stephen Rothwell wrote:
> +void * __init_refok zalloc_maybe_bootmem(size_t size, gfp_t mask)
> +{
> +	void *p;
> +
> +	if (mem_init_done)
> +		p = kzalloc(size, mask);
> +	else {
> +		p = alloc_bootmem(size);
> +		if (p)
> +			memset(p, 0, size);
> +	}
> +	return p;
> +}

BTW, is this `mem_init_done' flag the recommended(TM) way to handle this?
Or is it just something that always stayed under the radar of the reviewers, as
only PPC has it (and Atari)?

I remember we had something similar globally when __init was introduced,
which was used by the frame buffer code to determine whether to draw the
penguin logo (which is __initdata) or not. This code had to be ripped out (and
was replaced by the FBINFO_MODULE logic), because people didn't like
mem_init_done flags...

With kind regards,
 
Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium
 
Phone:    +32 (0)2 700 8453	
Fax:      +32 (0)2 700 8622	
E-mail:   Geert.Uytterhoeven@sonycom.com	
Internet: http://www.sony-europe.com/
 	
Sony Network and Software Technology Center Europe	
A division of Sony Service Centre (Europe) N.V.	
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium	
VAT BE 0413.825.160 · RPR Brussels	
Fortis Bank Zaventem · Swift GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* Re: [PATCH 5/5] Celleb: update for PCI
From: Arnd Bergmann @ 2007-10-02 11:30 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: paulus
In-Reply-To: <20071002.172653.-1962661557.kouish@swc.toshiba.co.jp>

On Tuesday 02 October 2007, Ishizaki Kou wrote:
> This is a patch kit to support PCI bus on Celleb with new "I/O routines
> for PowerPC." External PCI on Celleb must do explicit synchronization
> with devices (Bus has no automatic synchronization feature).
> 
> Signed-off-by: Kou Ishizaki <Kou.Ishizaki@toshiba.co.jp>

Acked-by: Arnd Bergmann <arnd@arndb.de>

The patch is not the final solution, as we discussed before, but it's
a big step in the right direction.

^ permalink raw reply

* Re: [PATCH 4/5] Celleb: Serial I/O update
From: Arnd Bergmann @ 2007-10-02 11:27 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: paulus
In-Reply-To: <20071002.172516.-494087187.kouish@swc.toshiba.co.jp>

On Tuesday 02 October 2007, Ishizaki Kou wrote:
> This is an update patch for Serial I/O on Celleb.
>   - Detection algorithm has been changed
> 
> Signed-off-by: Kou Ishizaki <Kou.Ishizaki@toshiba.co.jp>

Acked-by: Arnd Bergmann <arnd@arndb.de>

^ permalink raw reply

* Re: [PATCH 2/5] Celleb: Support for Power/Reset buttons
From: Arnd Bergmann @ 2007-10-02 11:25 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: paulus
In-Reply-To: <20071002.172121.-1625870824.kouish@swc.toshiba.co.jp>

On Tuesday 02 October 2007, Ishizaki Kou wrote:
> This is a patch to support Power/Reset buttons on Beat on Celleb.
> 
> On Beat, we have an event from Beat if Power button or Reset button
> is pressed. This patch catches the event and convert it to a signal
> to INIT process by calling ctrl_alt_del() function.
> 
> /sbin/inittab have no entry to turn the machine power off so we have
> to detect if power button is pressed or not internally in our driver.
> This idea is taken from PS3's event handling subsystem.
> 
> Signed-off-by: Kou Ishizaki <Kou.Ishizaki@toshiba.co.jp>

Acked-by: Arnd Bergmann <arnd@arndb.de>

^ permalink raw reply

* Re: What's the preferred way to export board information to userspace ?
From: Laurent Pinchart @ 2007-10-02  9:02 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev
In-Reply-To: <1191314363.22572.9.camel@pasglop>

Hi Ben,

On Tuesday 02 October 2007 10:39, Benjamin Herrenschmidt wrote:
> On Tue, 2007-10-02 at 10:10 +0200, Laurent Pinchart wrote:
> > Hi everybody,
> >
> > it seems linuxppc-embedded is going away. I should have posted this here
> > in the first place, so sorry for the cross-post.
> >
> > I need to export some read-only board-specific information (serial
> > number, boot mode jumper configuration, ...) that are collected from
> > various locations (CPLD, flash, U-Boot, ...) to userspace applications.
> >
> > Could anyone advice me on the preferred way to do that ? I can easily a=
dd
> > a quick&dirty sysfs/procfs based implementation, but I was wondering if
> > there was some kind of clean and generic way.
>
> Userspace can read /proc/device-tree no ? :-)

Except I'm still using ARCH=3Dppc. I know I shouldn't :-) The MPC8272 isn't=
 well=20
supported in ARCH=3Dpowerpc. Scott Wood submitted some patches I need befor=
e=20
switching.

> Appart from that, it's common to stick that sort of thing
> in /proc/cpuinfo... /sys/firmware may be an option if you have shitloads
> of stuff ..

It's not really CPU information, but I guess I can stick that in there.

Best regards,

=2D-=20
Laurent Pinchart
CSE Semaphore Belgium

Chauss=C3=A9e de Bruxelles, 732A
B-1410 Waterloo
Belgium

T +32 (2) 387 42 59
=46 +32 (2) 387 42 75

^ permalink raw reply

* Re: What's the preferred way to export board information to userspace ?
From: Benjamin Herrenschmidt @ 2007-10-02  8:39 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linuxppc-dev
In-Reply-To: <200710021011.00224.laurentp@cse-semaphore.com>


On Tue, 2007-10-02 at 10:10 +0200, Laurent Pinchart wrote:
> Hi everybody,
> 
> it seems linuxppc-embedded is going away. I should have posted this here in 
> the first place, so sorry for the cross-post.
> 
> I need to export some read-only board-specific information (serial number, 
> boot mode jumper configuration, ...) that are collected from various locations 
> (CPLD, flash, U-Boot, ...) to userspace applications.
> 
> Could anyone advice me on the preferred way to do that ? I can easily add a 
> quick&dirty sysfs/procfs based implementation, but I was wondering if there 
> was some kind of clean and generic way.

Userspace can read /proc/device-tree no ? :-)

Appart from that, it's common to stick that sort of thing
in /proc/cpuinfo... /sys/firmware may be an option if you have shitloads
of stuff ..

Ben.

^ permalink raw reply

* Re: [PATCH 3/4] Simplify rtas_change_msi() error semantics
From: Benjamin Herrenschmidt @ 2007-10-02  8:37 UTC (permalink / raw)
  To: michael; +Cc: linuxppc-dev
In-Reply-To: <1191310825.6593.21.camel@concordia>


On Tue, 2007-10-02 at 17:40 +1000, Michael Ellerman wrote:
> 
> rtas_disable_msi() asks firmware to configure 0 MSIs on the device,
> that
> hopefully succeeds. AFAIK configuring 0 MSIs is as close as we can get
> to disabling MSI via RTAS.
> 
> Perhaps that should also (re)enable INTX?

Not sure... maybe. RTAS doesn't do it ? Then there,s the question of
what happens on machines that don't support INTx ...

Cheers.
Ben.

^ permalink raw reply

* [PATCH 5/5] Celleb: update for PCI
From: Ishizaki Kou @ 2007-10-02  8:26 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

This is a patch kit to support PCI bus on Celleb with new "I/O routines
for PowerPC." External PCI on Celleb must do explicit synchronization
with devices (Bus has no automatic synchronization feature).

Signed-off-by: Kou Ishizaki <Kou.Ishizaki@toshiba.co.jp>
---

Index: linux-powerpc-git/arch/powerpc/platforms/celleb/pci.h
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/pci.h
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/pci.h
@@ -25,11 +25,18 @@
 
 #include <asm/pci-bridge.h>
 #include <asm/prom.h>
+#include <asm/ppc-pci.h>
 
 extern int celleb_setup_phb(struct pci_controller *);
 extern int celleb_pci_probe_mode(struct pci_bus *);
 
-extern struct pci_ops celleb_epci_ops;
 extern int celleb_setup_epci(struct device_node *, struct pci_controller *);
 
+extern void *celleb_dummy_page_va;
+extern int __init celleb_pci_workaround_init(void);
+extern void __init celleb_pci_add_one(struct pci_controller *,
+				      void (*)(struct pci_controller *));
+extern void fake_pci_workaround_init(struct pci_controller *);
+extern void epci_workaround_init(struct pci_controller *);
+
 #endif /* _CELLEB_PCI_H */
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/scc.h
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/scc.h
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/scc.h
@@ -53,7 +53,7 @@
 #define SCC_EPCI_STATUS         0x808
 #define SCC_EPCI_ABTSET         0x80c
 #define SCC_EPCI_WATRP          0x810
-#define SCC_EPCI_DUMMYRADR      0x814
+#define SCC_EPCI_DUMYRADR       0x814
 #define SCC_EPCI_SWRESP         0x818
 #define SCC_EPCI_CNTOPT         0x81c
 #define SCC_EPCI_ECMODE         0xf00
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/Makefile
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/Makefile
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/Makefile
@@ -1,6 +1,7 @@
 obj-y				+= interrupt.o iommu.o setup.o \
-				   htab.o beat.o pci.o \
-				   scc_epci.o scc_uhc.o hvCall.o
+				   htab.o beat.o hvCall.o pci.o \
+				   scc_epci.o scc_uhc.o \
+				   io-workarounds.o
 
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_PPC_UDBG_BEAT)	+= udbg_beat.o
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/setup.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/setup.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/setup.c
@@ -137,6 +137,8 @@ static int __init celleb_publish_devices
 	/* Publish OF platform devices for southbridge IOs */
 	of_platform_bus_probe(NULL, celleb_bus_ids, NULL);
 
+	celleb_pci_workaround_init();
+
 	return 0;
 }
 device_initcall(celleb_publish_devices);
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/pci.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/pci.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/pci.c
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/pci_regs.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -435,36 +436,58 @@ static void __init celleb_alloc_private_
 			GFP_KERNEL);
 }
 
+static int __init celleb_setup_fake_pci(struct device_node *dev,
+					struct pci_controller *phb)
+{
+	struct device_node *node;
+
+	phb->ops = &celleb_fake_pci_ops;
+	celleb_alloc_private_mem(phb);
+
+	for (node = of_get_next_child(dev, NULL);
+	     node != NULL; node = of_get_next_child(dev, node))
+		celleb_setup_fake_pci_device(node, phb);
+
+	return 0;
+}
+
+void __init fake_pci_workaround_init(struct pci_controller *phb)
+{
+	/**
+	 *  We will add fake pci bus to scc_pci_bus for the purpose to improve
+	 *  I/O Macro performance. But device-tree and device drivers
+	 *  are not ready to use address with a token.
+	 */
+
+	/* celleb_pci_add_one(phb, NULL); */
+}
+
+static struct of_device_id celleb_phb_match[] __initdata = {
+	{
+		.name = "pci-pseudo",
+		.data = celleb_setup_fake_pci,
+	}, {
+		.name = "epci",
+		.data = celleb_setup_epci,
+	}, {
+	},
+};
+
 int __init celleb_setup_phb(struct pci_controller *phb)
 {
-	const char *name;
 	struct device_node *dev = phb->arch_data;
-	struct device_node *node;
-	unsigned int rlen;
+	const struct of_device_id *match;
+	int (*setup_func)(struct device_node *, struct pci_controller *);
 
-	name = of_get_property(dev, "name", &rlen);
-	if (!name)
+	match = of_match_node(celleb_phb_match, dev);
+	if (!match)
 		return 1;
 
-	pr_debug("PCI: celleb_setup_phb() %s\n", name);
 	phb_set_bus_ranges(dev, phb);
 	phb->buid = 1;
 
-	if (strcmp(name, "epci") == 0) {
-		phb->ops = &celleb_epci_ops;
-		return celleb_setup_epci(dev, phb);
-
-	} else if (strcmp(name, "pci-pseudo") == 0) {
-		phb->ops = &celleb_fake_pci_ops;
-		celleb_alloc_private_mem(phb);
-		for (node = of_get_next_child(dev, NULL);
-		     node != NULL; node = of_get_next_child(dev, node))
-			celleb_setup_fake_pci_device(node, phb);
-
-	} else
-		return 1;
-
-	return 0;
+	setup_func = match->data;
+	return (*setup_func)(dev, phb);
 }
 
 int celleb_pci_probe_mode(struct pci_bus *bus)
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/scc_epci.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/scc_epci.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/scc_epci.c
@@ -43,7 +43,11 @@
 
 #define iob()  __asm__ __volatile__("eieio; sync":::"memory")
 
-static inline volatile void __iomem *celleb_epci_get_epci_base(
+struct epci_private {
+	dma_addr_t	dummy_page_da;
+};
+
+static inline PCI_IO_ADDR celleb_epci_get_epci_base(
 					struct pci_controller *hose)
 {
 	/*
@@ -55,7 +59,7 @@ static inline volatile void __iomem *cel
 	return hose->cfg_addr;
 }
 
-static inline volatile void __iomem *celleb_epci_get_epci_cfg(
+static inline PCI_IO_ADDR celleb_epci_get_epci_cfg(
 					struct pci_controller *hose)
 {
 	/*
@@ -67,20 +71,11 @@ static inline volatile void __iomem *cel
 	return hose->cfg_data;
 }
 
-#if 0 /* test code for epci dummy read */
-static void celleb_epci_dummy_read(struct pci_dev *dev)
+static void scc_epci_dummy_read(struct pci_controller *hose)
 {
-	volatile void __iomem *epci_base;
-	struct device_node *node;
-	struct pci_controller *hose;
+	PCI_IO_ADDR epci_base;
 	u32 val;
 
-	node = (struct device_node *)dev->bus->sysdata;
-	hose = pci_find_hose_for_OF_device(node);
-
-	if (!hose)
-		return;
-
 	epci_base = celleb_epci_get_epci_base(hose);
 
 	val = in_be32(epci_base + SCC_EPCI_WATRP);
@@ -88,21 +83,45 @@ static void celleb_epci_dummy_read(struc
 
 	return;
 }
-#endif
+
+void __init epci_workaround_init(struct pci_controller *hose)
+{
+	PCI_IO_ADDR epci_base;
+	PCI_IO_ADDR reg;
+	struct epci_private *private = hose->private_data;
+
+	BUG_ON(!private);
+
+	private->dummy_page_da = dma_map_single(hose->parent,
+		celleb_dummy_page_va, PAGE_SIZE, DMA_FROM_DEVICE);
+	if (private->dummy_page_da == DMA_ERROR_CODE) {
+		printk(KERN_ERR "EPCI: dummy read disabled."
+		       "Map dummy page failed.\n");
+		return;
+	}
+
+	celleb_pci_add_one(hose, scc_epci_dummy_read);
+	epci_base = celleb_epci_get_epci_base(hose);
+
+	reg = epci_base + SCC_EPCI_DUMYRADR;
+	out_be32(reg, private->dummy_page_da);
+}
 
 static inline void clear_and_disable_master_abort_interrupt(
 					struct pci_controller *hose)
 {
-	volatile void __iomem *epci_base, *reg;
+	PCI_IO_ADDR epci_base;
+	PCI_IO_ADDR reg;
 	epci_base = celleb_epci_get_epci_base(hose);
 	reg = epci_base + PCI_COMMAND;
 	out_be32(reg, in_be32(reg) | (PCI_STATUS_REC_MASTER_ABORT << 16));
 }
 
 static int celleb_epci_check_abort(struct pci_controller *hose,
-				   volatile void __iomem *addr)
+				   PCI_IO_ADDR addr)
 {
-	volatile void __iomem *reg, *epci_base;
+	PCI_IO_ADDR reg;
+	PCI_IO_ADDR epci_base;
 	u32 val;
 
 	iob();
@@ -132,12 +151,12 @@ static int celleb_epci_check_abort(struc
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static volatile void __iomem *celleb_epci_make_config_addr(
+static PCI_IO_ADDR celleb_epci_make_config_addr(
 					struct pci_bus *bus,
 					struct pci_controller *hose,
 					unsigned int devfn, int where)
 {
-	volatile void __iomem *addr;
+	PCI_IO_ADDR addr;
 
 	if (bus != hose->bus)
 		addr = celleb_epci_get_epci_cfg(hose) +
@@ -157,7 +176,8 @@ static volatile void __iomem *celleb_epc
 static int celleb_epci_read_config(struct pci_bus *bus,
 			unsigned int devfn, int where, int size, u32 * val)
 {
-	volatile void __iomem *epci_base, *addr;
+	PCI_IO_ADDR epci_base;
+	PCI_IO_ADDR addr;
 	struct device_node *node;
 	struct pci_controller *hose;
 
@@ -220,7 +240,8 @@ static int celleb_epci_read_config(struc
 static int celleb_epci_write_config(struct pci_bus *bus,
 			unsigned int devfn, int where, int size, u32 val)
 {
-	volatile void __iomem *epci_base, *addr;
+	PCI_IO_ADDR epci_base;
+	PCI_IO_ADDR addr;
 	struct device_node *node;
 	struct pci_controller *hose;
 
@@ -286,7 +307,8 @@ struct pci_ops celleb_epci_ops = {
 static int __init celleb_epci_init(struct pci_controller *hose)
 {
 	u32 val;
-	volatile void __iomem *reg, *epci_base;
+	PCI_IO_ADDR reg;
+	PCI_IO_ADDR epci_base;
 	int hwres = 0;
 
 	epci_base = celleb_epci_get_epci_base(hose);
@@ -440,10 +462,24 @@ int __init celleb_setup_epci(struct devi
 		 r.start, (unsigned long)hose->cfg_data,
 		(r.end - r.start + 1));
 
+	hose->private_data = kzalloc(sizeof(struct epci_private), GFP_KERNEL);
+	if (hose->private_data == NULL) {
+		printk(KERN_ERR "EPCI: no memory for private data.\n");
+		goto error;
+	}
+
+	hose->ops = &celleb_epci_ops;
 	celleb_epci_init(hose);
 
 	return 0;
 
 error:
+	kfree(hose->private_data);
+
+	if (hose->cfg_addr)
+		iounmap(hose->cfg_addr);
+
+	if (hose->cfg_data)
+		iounmap(hose->cfg_data);
 	return 1;
 }
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/io-workarounds.c
===================================================================
--- /dev/null
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/io-workarounds.c
@@ -0,0 +1,279 @@
+/*
+ * Support for Celleb io workarounds
+ *
+ * (C) Copyright 2006-2007 TOSHIBA CORPORATION
+ *
+ * This file is based to arch/powerpc/platform/cell/io-workarounds.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#undef DEBUG
+
+#include <linux/of_device.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/ppc-pci.h>
+
+#include "pci.h"
+
+#define MAX_CELLEB_PCI_BUS	4
+
+void *celleb_dummy_page_va;
+
+static struct celleb_pci_bus {
+	struct pci_controller *phb;
+	void (*dummy_read)(struct pci_controller *);
+} celleb_pci_busses[MAX_CELLEB_PCI_BUS];
+
+static int celleb_pci_count = 0;
+
+static struct celleb_pci_bus *celleb_pci_find(unsigned long vaddr,
+					      unsigned long paddr)
+{
+	int i, j;
+	struct resource *res;
+
+	for (i = 0; i < celleb_pci_count; i++) {
+		struct celleb_pci_bus *bus = &celleb_pci_busses[i];
+		struct pci_controller *phb = bus->phb;
+		if (paddr)
+			for (j = 0; j < 3; j++) {
+				res = &phb->mem_resources[j];
+				if (paddr >= res->start && paddr <= res->end)
+					return bus;
+			}
+		res = &phb->io_resource;
+		if (vaddr && vaddr >= res->start && vaddr <= res->end)
+			return bus;
+	}
+	return NULL;
+}
+
+static void celleb_io_flush(const PCI_IO_ADDR addr)
+{
+	struct celleb_pci_bus *bus;
+	int token;
+
+	token = PCI_GET_ADDR_TOKEN(addr);
+
+	if (token && token <= celleb_pci_count)
+		bus = &celleb_pci_busses[token - 1];
+	else {
+		unsigned long vaddr, paddr;
+		pte_t *ptep;
+
+		vaddr = (unsigned long)PCI_FIX_ADDR(addr);
+		if (vaddr < PHB_IO_BASE || vaddr >= PHB_IO_END)
+			return;
+
+		ptep = find_linux_pte(init_mm.pgd, vaddr);
+		if (ptep == NULL)
+			paddr = 0;
+		else
+			paddr = pte_pfn(*ptep) << PAGE_SHIFT;
+		bus = celleb_pci_find(vaddr, paddr);
+
+		if (bus == NULL)
+			return;
+	}
+
+	if (bus->dummy_read)
+		bus->dummy_read(bus->phb);
+}
+
+static u8 celleb_readb(const PCI_IO_ADDR addr)
+{
+	u8 val;
+	val = __do_readb(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static u16 celleb_readw(const PCI_IO_ADDR addr)
+{
+	u16 val;
+	val = __do_readw(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static u32 celleb_readl(const PCI_IO_ADDR addr)
+{
+	u32 val;
+	val = __do_readl(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static u64 celleb_readq(const PCI_IO_ADDR addr)
+{
+	u64 val;
+	val = __do_readq(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static u16 celleb_readw_be(const PCI_IO_ADDR addr)
+{
+	u16 val;
+	val = __do_readw_be(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static u32 celleb_readl_be(const PCI_IO_ADDR addr)
+{
+	u32 val;
+	val = __do_readl_be(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static u64 celleb_readq_be(const PCI_IO_ADDR addr)
+{
+	u64 val;
+	val = __do_readq_be(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static void celleb_readsb(const PCI_IO_ADDR addr,
+			  void *buf, unsigned long count)
+{
+	__do_readsb(addr, buf, count);
+	celleb_io_flush(addr);
+}
+
+static void celleb_readsw(const PCI_IO_ADDR addr,
+			  void *buf, unsigned long count)
+{
+	__do_readsw(addr, buf, count);
+	celleb_io_flush(addr);
+}
+
+static void celleb_readsl(const PCI_IO_ADDR addr,
+			  void *buf, unsigned long count)
+{
+	__do_readsl(addr, buf, count);
+	celleb_io_flush(addr);
+}
+
+static void celleb_memcpy_fromio(void *dest,
+				 const PCI_IO_ADDR src,
+				 unsigned long n)
+{
+	__do_memcpy_fromio(dest, src, n);
+	celleb_io_flush(src);
+}
+
+static void __iomem *celleb_ioremap(unsigned long addr,
+				     unsigned long size,
+				     unsigned long flags)
+{
+	struct celleb_pci_bus *bus;
+	void __iomem *res = __ioremap(addr, size, flags);
+	int busno;
+
+	bus = celleb_pci_find(0, addr);
+	if (bus != NULL) {
+		busno = bus - celleb_pci_busses;
+		PCI_SET_ADDR_TOKEN(res, busno + 1);
+	}
+	return res;
+}
+
+static void celleb_iounmap(volatile void __iomem *addr)
+{
+	return __iounmap(PCI_FIX_ADDR(addr));
+}
+
+static struct ppc_pci_io celleb_pci_io __initdata = {
+	.readb = celleb_readb,
+	.readw = celleb_readw,
+	.readl = celleb_readl,
+	.readq = celleb_readq,
+	.readw_be = celleb_readw_be,
+	.readl_be = celleb_readl_be,
+	.readq_be = celleb_readq_be,
+	.readsb = celleb_readsb,
+	.readsw = celleb_readsw,
+	.readsl = celleb_readsl,
+	.memcpy_fromio = celleb_memcpy_fromio,
+};
+
+void __init celleb_pci_add_one(struct pci_controller *phb,
+			       void (*dummy_read)(struct pci_controller *))
+{
+	struct celleb_pci_bus *bus = &celleb_pci_busses[celleb_pci_count];
+	struct device_node *np = phb->arch_data;
+
+	if (celleb_pci_count >= MAX_CELLEB_PCI_BUS) {
+		printk(KERN_ERR "Too many pci bridges, workarounds"
+		       " disabled for %s\n", np->full_name);
+		return;
+	}
+
+	celleb_pci_count++;
+
+	bus->phb = phb;
+	bus->dummy_read = dummy_read;
+}
+
+static struct of_device_id celleb_pci_workaround_match[] __initdata = {
+	{
+		.name = "pci-pseudo",
+		.data = fake_pci_workaround_init,
+	}, {
+		.name = "epci",
+		.data = epci_workaround_init,
+	}, {
+	},
+};
+
+int __init celleb_pci_workaround_init(void)
+{
+	struct pci_controller *phb;
+	struct device_node *node;
+	const struct  of_device_id *match;
+	void (*init_func)(struct pci_controller *);
+
+	celleb_dummy_page_va = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!celleb_dummy_page_va) {
+		printk(KERN_ERR "Celleb: dummy read disabled."
+			"Alloc celleb_dummy_page_va failed\n");
+		return 1;
+	}
+
+	list_for_each_entry(phb, &hose_list, list_node) {
+		node = phb->arch_data;
+		match = of_match_node(celleb_pci_workaround_match, node);
+
+		if (match) {
+			init_func = match->data;
+			(*init_func)(phb);
+		}
+	}
+
+	ppc_pci_io = celleb_pci_io;
+	ppc_md.ioremap = celleb_ioremap;
+	ppc_md.iounmap = celleb_iounmap;
+
+	return 0;
+}
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/Kconfig
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/Kconfig
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/Kconfig
@@ -2,6 +2,7 @@ config PPC_CELLEB
 	bool "Toshiba's Cell Reference Set 'Celleb' Architecture"
 	depends on PPC_MULTIPLATFORM && PPC64
 	select PPC_CELL
+	select PPC_INDIRECT_IO
 	select PPC_OF_PLATFORM_PCI
 	select HAS_TXX9_SERIAL
 	select PPC_UDBG_BEAT

^ permalink raw reply

* [PATCH 4/5] Celleb: Serial I/O update
From: Ishizaki Kou @ 2007-10-02  8:25 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

This is an update patch for Serial I/O on Celleb.
  - Detection algorithm has been changed

Signed-off-by: Kou Ishizaki <Kou.Ishizaki@toshiba.co.jp>
---

Index: linux-powerpc-git/arch/powerpc/platforms/celleb/scc_sio.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/scc_sio.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/scc_sio.c
@@ -1,7 +1,7 @@
 /*
  * setup serial port in SCC
  *
- * (C) Copyright 2006 TOSHIBA CORPORATION
+ * (C) Copyright 2006-2007 TOSHIBA CORPORATION
  *
  * 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
@@ -42,40 +42,40 @@ static struct {
 static int __init txx9_serial_init(void)
 {
 	extern int early_serial_txx9_setup(struct uart_port *port);
-	struct device_node *node;
+	struct device_node *node = NULL;
 	int i;
 	struct uart_port req;
 	struct of_irq irq;
 	struct resource res;
 
-	node = of_find_node_by_path("/ioif1/sio");
-	if (!node)
-		return 0;
-
-	for(i = 0; i < sizeof(txx9_scc_tab)/sizeof(txx9_scc_tab[0]); i++) {
-		if (!(txx9_serial_bitmap & (1<<i)))
-			continue;
-
-		if (of_irq_map_one(node, i, &irq))
-			continue;
-		if (of_address_to_resource(node, txx9_scc_tab[i].index, &res))
-			continue;
-
-		memset(&req, 0, sizeof(req));
-		req.line = i;
-		req.iotype = UPIO_MEM;
-		req.mapbase = res.start + txx9_scc_tab[i].offset;
+	while ((node = of_find_compatible_node(node,
+				"serial", "toshiba,sio-scc")) != NULL) {
+		for (i = 0; i < ARRAY_SIZE(txx9_scc_tab); i++) {
+			if (!(txx9_serial_bitmap & (1<<i)))
+				continue;
+
+			if (of_irq_map_one(node, i, &irq))
+				continue;
+			if (of_address_to_resource(node,
+				txx9_scc_tab[i].index, &res))
+				continue;
+
+			memset(&req, 0, sizeof(req));
+			req.line = i;
+			req.iotype = UPIO_MEM;
+			req.mapbase = res.start + txx9_scc_tab[i].offset;
 #ifdef CONFIG_SERIAL_TXX9_CONSOLE
-		req.membase = ioremap(req.mapbase, 0x24);
+			req.membase = ioremap(req.mapbase, 0x24);
 #endif
-		req.irq = irq_create_of_mapping(irq.controller,
-			irq.specifier, irq.size);
-		req.flags |= UPF_IOREMAP | UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
-		req.uartclk = 83300000;
-		early_serial_txx9_setup(&req);
+			req.irq = irq_create_of_mapping(irq.controller,
+				irq.specifier, irq.size);
+			req.flags |= UPF_IOREMAP | UPF_BUGGY_UART
+				/*HAVE_CTS_LINE*/;
+			req.uartclk = 83300000;
+			early_serial_txx9_setup(&req);
+		}
 	}
 
-	of_node_put(node);
 	return 0;
 }
 

^ permalink raw reply

* [PATCH 3/5] Celleb: New HTAB Guest OS Interface on Beat
From: Ishizaki Kou @ 2007-10-02  8:23 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

This is a patch kit to work with new Guest OS Interface
to tweak HTAB on Beat. It detects old and new Guest OS Interfaces
automatically.

Signed-off-by: Kou Ishizaki <Kou.Ishizaki@toshiba.co.jp>
Acked-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
---

Index: linux-powerpc-git/arch/powerpc/platforms/celleb/setup.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/setup.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/setup.c
@@ -119,7 +119,7 @@ static int __init celleb_probe(void)
 		return 0;
 
 	powerpc_firmware_features |= FW_FEATURE_CELLEB_POSSIBLE;
-	hpte_init_beat();
+	hpte_init_beat_v3();
 	return 1;
 }
 
Index: linux-powerpc-git/include/asm-powerpc/mmu-hash64.h
===================================================================
--- linux-powerpc-git.orig/include/asm-powerpc/mmu-hash64.h
+++ linux-powerpc-git/include/asm-powerpc/mmu-hash64.h
@@ -256,6 +256,7 @@ extern void hpte_init_native(void);
 extern void hpte_init_lpar(void);
 extern void hpte_init_iSeries(void);
 extern void hpte_init_beat(void);
+extern void hpte_init_beat_v3(void);
 
 extern void stabs_alloc(void);
 extern void slb_initialize(void);
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/beat_syscall.h
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/beat_syscall.h
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/beat_syscall.h
@@ -157,4 +157,8 @@
 #define HV_rtc_write __BEAT_ADD_VENDOR_ID(0x191, 1)
 #define HV_eeprom_read __BEAT_ADD_VENDOR_ID(0x192, 1)
 #define HV_eeprom_write __BEAT_ADD_VENDOR_ID(0x193, 1)
+#define HV_insert_htab_entry3 __BEAT_ADD_VENDOR_ID(0x104, 1)
+#define HV_invalidate_htab_entry3 __BEAT_ADD_VENDOR_ID(0x105, 1)
+#define HV_update_htab_permission3 __BEAT_ADD_VENDOR_ID(0x106, 1)
+#define HV_clear_htab3 __BEAT_ADD_VENDOR_ID(0x107, 1)
 #endif
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/beat_wrapper.h
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/beat_wrapper.h
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/beat_wrapper.h
@@ -98,6 +98,37 @@ static inline s64 beat_write_htab_entry(
 	return ret;
 }
 
+static inline s64 beat_insert_htab_entry3(u64 htab_id, u64 group,
+	u64 hpte_v, u64 hpte_r, u64 mask_v, u64 value_v, u64 *slot)
+{
+	u64 dummy[1];
+	s64 ret;
+
+	ret = beat_hcall1(HV_insert_htab_entry3, dummy, htab_id, group,
+		hpte_v, hpte_r, mask_v, value_v);
+	*slot = dummy[0];
+	return ret;
+}
+
+static inline s64 beat_invalidate_htab_entry3(u64 htab_id, u64 group,
+	u64 va, u64 pss)
+{
+	return beat_hcall_norets(HV_invalidate_htab_entry3,
+		htab_id, group, va, pss);
+}
+
+static inline s64 beat_update_htab_permission3(u64 htab_id, u64 group,
+	u64 va, u64 pss, u64 ptel_mask, u64 ptel_value)
+{
+	return beat_hcall_norets(HV_update_htab_permission3,
+		htab_id, group, va, pss, ptel_mask, ptel_value);
+}
+
+static inline s64 beat_clear_htab3(u64 htab_id)
+{
+	return beat_hcall_norets(HV_clear_htab3, htab_id);
+}
+
 static inline void beat_shutdown_logical_partition(u64 code)
 {
 	(void)beat_hcall_norets(HV_shutdown_logical_partition, code);
@@ -217,4 +248,41 @@ static inline s64 beat_put_iopte(u64 ioa
 		ioid, flags);
 }
 
+static inline s64 beat_construct_event_receive_port(u64 *port)
+{
+	u64 dummy[1];
+	s64 ret;
+
+	ret = beat_hcall1(HV_construct_event_receive_port, dummy);
+	*port = dummy[0];
+	return ret;
+}
+
+static inline s64 beat_destruct_event_receive_port(u64 port)
+{
+	s64 ret;
+
+	ret = beat_hcall_norets(HV_destruct_event_receive_port, port);
+	return ret;
+}
+
+static inline s64 beat_create_repository_node(u64 path[4], u64 data[2])
+{
+	s64 ret;
+
+	ret = beat_hcall_norets(HV_create_repository_node2,
+		path[0], path[1], path[2], path[3], data[0], data[1]);
+	return ret;
+}
+
+static inline s64 beat_get_repository_node_value(u64 lpid, u64 path[4],
+	u64 data[2])
+{
+	s64 ret;
+
+	ret = beat_hcall2(HV_get_repository_node_value2, data,
+		lpid, path[0], path[1], path[2], path[3]);
+	return ret;
+}
+
 #endif
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/htab.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/htab.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/htab.c
@@ -306,3 +306,133 @@ void __init hpte_init_beat(void)
 	ppc_md.hpte_remove	= beat_lpar_hpte_remove;
 	ppc_md.hpte_clear_all	= beat_lpar_hptab_clear;
 }
+
+static long beat_lpar_hpte_insert_v3(unsigned long hpte_group,
+				  unsigned long va, unsigned long pa,
+				  unsigned long rflags, unsigned long vflags,
+				  int psize)
+{
+	unsigned long lpar_rc;
+	unsigned long slot;
+	unsigned long hpte_v, hpte_r;
+
+	/* same as iseries */
+	if (vflags & HPTE_V_SECONDARY)
+		return -1;
+
+	if (!(vflags & HPTE_V_BOLTED))
+		DBG_LOW("hpte_insert(group=%lx, va=%016lx, pa=%016lx, "
+			"rflags=%lx, vflags=%lx, psize=%d)\n",
+		hpte_group, va, pa, rflags, vflags, psize);
+
+	hpte_v = hpte_encode_v(va, psize) | vflags | HPTE_V_VALID;
+	hpte_r = hpte_encode_r(pa, psize) | rflags;
+
+	if (!(vflags & HPTE_V_BOLTED))
+		DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r);
+
+	if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE))
+		hpte_r &= ~_PAGE_COHERENT;
+
+	/* insert into not-volted entry */
+	lpar_rc = beat_insert_htab_entry3(0, hpte_group, hpte_v, hpte_r,
+		HPTE_V_BOLTED, 0, &slot);
+	/*
+	 * Since we try and ioremap PHBs we don't own, the pte insert
+	 * will fail. However we must catch the failure in hash_page
+	 * or we will loop forever, so return -2 in this case.
+	 */
+	if (unlikely(lpar_rc != 0)) {
+		if (!(vflags & HPTE_V_BOLTED))
+			DBG_LOW(" lpar err %lx\n", lpar_rc);
+		return -2;
+	}
+	if (!(vflags & HPTE_V_BOLTED))
+		DBG_LOW(" -> slot: %lx\n", slot);
+
+	/* We have to pass down the secondary bucket bit here as well */
+	return (slot ^ hpte_group) & 15;
+}
+
+/*
+ * NOTE: for updatepp ops we are fortunate that the linux "newpp" bits and
+ * the low 3 bits of flags happen to line up.  So no transform is needed.
+ * We can probably optimize here and assume the high bits of newpp are
+ * already zero.  For now I am paranoid.
+ */
+static long beat_lpar_hpte_updatepp_v3(unsigned long slot,
+				    unsigned long newpp,
+				    unsigned long va,
+				    int psize, int local)
+{
+	unsigned long lpar_rc;
+	unsigned long want_v;
+	unsigned long pss;
+
+	want_v = hpte_encode_v(va, psize);
+	pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc;
+
+	DBG_LOW("    update: "
+		"avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ",
+		want_v & HPTE_V_AVPN, slot, psize, newpp);
+
+	lpar_rc = beat_update_htab_permission3(0, slot, want_v, pss, 7, newpp);
+
+	if (lpar_rc == 0xfffffff7) {
+		DBG_LOW("not found !\n");
+		return -1;
+	}
+
+	DBG_LOW("ok\n");
+
+	BUG_ON(lpar_rc != 0);
+
+	return 0;
+}
+
+static void beat_lpar_hpte_invalidate_v3(unsigned long slot, unsigned long va,
+					 int psize, int local)
+{
+	unsigned long want_v;
+	unsigned long lpar_rc;
+	unsigned long pss;
+
+	DBG_LOW("    inval : slot=%lx, va=%016lx, psize: %d, local: %d\n",
+		slot, va, psize, local);
+	want_v = hpte_encode_v(va, psize);
+	pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc;
+
+	lpar_rc = beat_invalidate_htab_entry3(0, slot, want_v, pss);
+
+	/* E_busy can be valid output: page may be already replaced */
+	BUG_ON(lpar_rc != 0 && lpar_rc != 0xfffffff7);
+}
+
+static int64_t _beat_lpar_hptab_clear_v3(void)
+{
+	return beat_clear_htab3(0);
+}
+
+static void beat_lpar_hptab_clear_v3(void)
+{
+	_beat_lpar_hptab_clear_v3();
+}
+
+void __init hpte_init_beat_v3(void)
+{
+	if (_beat_lpar_hptab_clear_v3() == 0) {
+		ppc_md.hpte_invalidate	= beat_lpar_hpte_invalidate_v3;
+		ppc_md.hpte_updatepp	= beat_lpar_hpte_updatepp_v3;
+		ppc_md.hpte_updateboltedpp = beat_lpar_hpte_updateboltedpp;
+		ppc_md.hpte_insert	= beat_lpar_hpte_insert_v3;
+		ppc_md.hpte_remove	= beat_lpar_hpte_remove;
+		ppc_md.hpte_clear_all	= beat_lpar_hptab_clear_v3;
+	} else {
+		ppc_md.hpte_invalidate	= beat_lpar_hpte_invalidate;
+		ppc_md.hpte_updatepp	= beat_lpar_hpte_updatepp;
+		ppc_md.hpte_updateboltedpp = beat_lpar_hpte_updateboltedpp;
+		ppc_md.hpte_insert	= beat_lpar_hpte_insert;
+		ppc_md.hpte_remove	= beat_lpar_hpte_remove;
+		ppc_md.hpte_clear_all	= beat_lpar_hptab_clear;
+	}
+}

^ permalink raw reply

* [PATCH 2/5] Celleb: Support for Power/Reset buttons
From: Ishizaki Kou @ 2007-10-02  8:21 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

This is a patch to support Power/Reset buttons on Beat on Celleb.

On Beat, we have an event from Beat if Power button or Reset button
is pressed. This patch catches the event and convert it to a signal
to INIT process by calling ctrl_alt_del() function.

/sbin/inittab have no entry to turn the machine power off so we have
to detect if power button is pressed or not internally in our driver.
This idea is taken from PS3's event handling subsystem.

Signed-off-by: Kou Ishizaki <Kou.Ishizaki@toshiba.co.jp>
---

This patch is taken after "[PATCH 1/5] Move pause() and kexec_cpu_down()
to beat.c" applied, so some lines are taken in from that patch.
No functional dependency is incorporated.


Index: linux-powerpc-git/arch/powerpc/platforms/celleb/beat.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/beat.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/beat.c
@@ -22,16 +22,24 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/rtc.h>
+#include <linux/interrupt.h>
+#include <linux/irqreturn.h>
+#include <linux/reboot.h>
 
 #include <asm/hvconsole.h>
 #include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/firmware.h>
 
 #include "beat_wrapper.h"
 #include "beat.h"
+#include "interrupt.h"
+
+static int beat_pm_poweroff_flag;
 
 void beat_restart(char *cmd)
 {
-	beat_shutdown_logical_partition(1);
+	beat_shutdown_logical_partition(!beat_pm_poweroff_flag);
 }
 
 void beat_power_off(void)
@@ -170,6 +178,90 @@ void beat_kexec_cpu_down(int crash, int 
 }
 #endif
 
+static irqreturn_t beat_power_event(int virq, void *arg)
+{
+	printk(KERN_DEBUG "Beat: power button pressed\n");
+	beat_pm_poweroff_flag = 1;
+	ctrl_alt_del();
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t beat_reset_event(int virq, void *arg)
+{
+	printk(KERN_DEBUG "Beat: reset button pressed\n");
+	beat_pm_poweroff_flag = 0;
+	ctrl_alt_del();
+	return IRQ_HANDLED;
+}
+
+static struct beat_event_list {
+	const char *typecode;
+	irq_handler_t handler;
+	unsigned int virq;
+} beat_event_list[] = {
+	{ "power", beat_power_event, 0 },
+	{ "reset", beat_reset_event, 0 },
+};
+
+static int __init beat_register_event(void)
+{
+	u64 path[4], data[2];
+	int rc, i;
+	unsigned int virq;
+
+	for (i = 0; i < ARRAY_SIZE(beat_event_list); i++) {
+		struct beat_event_list *ev = &beat_event_list[i];
+
+		if (beat_construct_event_receive_port(data) != 0) {
+			printk(KERN_ERR "Beat: "
+			       "cannot construct event receive port for %s\n",
+			       ev->typecode);
+			return -EINVAL;
+		}
+
+		virq = irq_create_mapping(NULL, data[0]);
+		if (virq == NO_IRQ) {
+			printk(KERN_ERR "Beat: failed to get virtual IRQ"
+			       " for event receive port for %s\n",
+			       ev->typecode);
+			beat_destruct_event_receive_port(data[0]);
+			return -EIO;
+		}
+		ev->virq = virq;
+
+		rc = request_irq(virq, ev->handler, IRQF_DISABLED,
+				      ev->typecode, NULL);
+		if (rc != 0) {
+			printk(KERN_ERR "Beat: failed to request virtual IRQ"
+			       " for event receive port for %s\n",
+			       ev->typecode);
+			beat_destruct_event_receive_port(data[0]);
+			return rc;
+		}
+
+		path[0] = 0x1000000065780000ul;	/* 1,ex */
+		path[1] = 0x627574746f6e0000ul;	/* button */
+		path[2] = 0;
+		strncpy((char *)&path[2], ev->typecode, 8);
+		path[3] = 0;
+		data[1] = 0;
+
+		beat_create_repository_node(path, data);
+	}
+	return 0;
+}
+
+static int __init beat_event_init(void)
+{
+	if (!firmware_has_feature(FW_FEATURE_BEAT))
+		return -EINVAL;
+
+	beat_pm_poweroff_flag = 0;
+	return beat_register_event();
+}
+
+device_initcall(beat_event_init);
+
 EXPORT_SYMBOL(beat_get_term_char);
 EXPORT_SYMBOL(beat_put_term_char);
 EXPORT_SYMBOL(beat_halt_code);

^ permalink raw reply

* Re: [PATCH 7/7] Celleb: update for PCI
From: Arnd Bergmann @ 2007-10-02  8:18 UTC (permalink / raw)
  To: Ishizaki Kou; +Cc: linuxppc-dev, paulus
In-Reply-To: <20071002.170439.-1300534196.kouish@swc.toshiba.co.jp>

On Tuesday 02 October 2007, Ishizaki Kou wrote:
> Though I agree it's better to make code common, I hope to keep them
> separate for now. Because I'm now developing PCI Express support and
> it also uses io-workaround mechanism. I'll try to make them common in
> this work.

Ok, fair enough. Let's use your current version for 2.6.24 and then
work on a new version that handles both PCI and PCIe correctly
on both platforms. I'm certainly interested in getting the PCIe
workarounds running on QS20 as well.

	Arnd <><

^ permalink raw reply

* [PATCH 1/5] Celleb: Move pause, kexec_cpu_down to beat.c
From: Ishizaki Kou @ 2007-10-02  8:18 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

This patch is an update for "Beat on Celleb"
  - Move beat_pause(), beat_kexec_cpu_down() from setup.c to beat.c

Signed-off-by: <Kou.Ishizaki@toshiba.co.jp>
Acked-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
---

Index: linux-powerpc-git/arch/powerpc/platforms/celleb/beat.h
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/beat.h
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/beat.h
@@ -36,5 +36,7 @@ ssize_t beat_nvram_get_size(void);
 ssize_t beat_nvram_read(char *, size_t, loff_t *);
 ssize_t beat_nvram_write(char *, size_t, loff_t *);
 int beat_set_xdabr(unsigned long);
+void beat_power_save(void);
+void beat_kexec_cpu_down(int, int);
 
 #endif /* _CELLEB_BEAT_H */
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/setup.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/setup.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/setup.c
@@ -111,11 +111,6 @@ static void __init celleb_setup_arch(voi
 #endif
 }
 
-static void beat_power_save(void)
-{
-	beat_pause(0);
-}
-
 static int __init celleb_probe(void)
 {
 	unsigned long root = of_get_flat_dt_root();
@@ -128,13 +123,6 @@ static int __init celleb_probe(void)
 	return 1;
 }
 
-#ifdef CONFIG_KEXEC
-static void celleb_kexec_cpu_down(int crash, int secondary)
-{
-	beatic_deinit_IRQ();
-}
-#endif
-
 static struct of_device_id celleb_bus_ids[] __initdata = {
 	{ .type = "scc", },
 	{ .type = "ioif", },	/* old style */
@@ -175,7 +163,7 @@ define_machine(celleb) {
 	.pci_probe_mode 	= celleb_pci_probe_mode,
 	.pci_setup_phb		= celleb_setup_phb,
 #ifdef CONFIG_KEXEC
-	.kexec_cpu_down		= celleb_kexec_cpu_down,
+	.kexec_cpu_down		= beat_kexec_cpu_down,
 	.machine_kexec		= default_machine_kexec,
 	.machine_kexec_prepare	= default_machine_kexec_prepare,
 	.machine_crash_shutdown	= default_machine_crash_shutdown,
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/beat.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/beat.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/beat.c
@@ -158,6 +158,18 @@ int64_t beat_put_term_char(u64 vterm, u6
 	return beat_put_characters_to_console(vterm, len, (u8*)db);
 }
 
+void beat_power_save(void)
+{
+	beat_pause(0);
+}
+
+#ifdef CONFIG_KEXEC
+void beat_kexec_cpu_down(int crash, int secondary)
+{
+	beatic_deinit_IRQ();
+}
+#endif
+
 EXPORT_SYMBOL(beat_get_term_char);
 EXPORT_SYMBOL(beat_put_term_char);
 EXPORT_SYMBOL(beat_halt_code);

^ permalink raw reply

* [PATCH 0/5] Updates of "Celleb" patches for 2.6.24
From: Ishizaki Kou @ 2007-10-02  8:16 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

Follwing patch series is an update to support Cell Reference Set (Celleb).
Two patches of former series are declined, two are updated, and rest 
three still remain.

Declined patches are "fixing SLB initialization" and "VFD support for
Celleb 2." I found former patch not necessary anymore, and latter seems
under discussion to drive such device generally.

[PATCH 1/5] Celleb: Move pause, kexec_cpu_down to beat.c
  This is quite simple patch to move two functions from "setup.c" to
"beat.c". This patch is slightly updated to declare beat_kexec_cpu_down()
function unconditionally.

[PATCH 2/5] Celleb: Support for Power/Reset buttons
  This is patch to add support Power/Reset buttons on Celleb. With
this patch, Power/Reset button causes call of ctrl_alt_del() function,
not to call machine dependent routines.

  I think it is better than this to handle such buttons in consistent way,
such as 'event', but I have to make working such buttons with existing
Fedora's inittab. I feel we have to have acpi or like that, but currently
we don't have such subsystem.

[PATCH 3/5] Celleb: New HTAB Guest OS Interface on Beat
  This is a patch to support new HTAB Guest OS Interface on Beat. Beat v3
and later will provide you such interface. Beat v2 or former provide you
older Guest OS Interface only, so this patch detects whether the new inter-
face is available or not, and reflect it to ppc_md.

  Not changed from former patch.

[PATCH 4/5] Celleb: Serial I/O update
  This patch updates scc_sio.c to support newer serial-port detection
algorithm.

  Not changed from former patch.

[PATCH 5/5] Celleb: update for PCI
  This patch incorporates PCI support for Celleb.
  - io_workarounds.c: Kicks synchronization port whenever reading
  MMIO registers (so-called "dummy read").
  - Replaced "volatile void * __iommu" to "PCI_IO_ADDR" because the
  compiler complains on volatile pointer.
  - Setup via bus name.
  - alloc_maybe_bootmem() has been gone.

  Not changed from former patch.


Best regards,
Kou Ishizaki

^ permalink raw reply

* What's the preferred way to export board information to userspace ?
From: Laurent Pinchart @ 2007-10-02  8:10 UTC (permalink / raw)
  To: linuxppc-dev

Hi everybody,

it seems linuxppc-embedded is going away. I should have posted this here in=
=20
the first place, so sorry for the cross-post.

I need to export some read-only board-specific information (serial number,=
=20
boot mode jumper configuration, ...) that are collected from various locati=
ons=20
(CPLD, flash, U-Boot, ...) to userspace applications.

Could anyone advice me on the preferred way to do that ? I can easily add a=
=20
quick&dirty sysfs/procfs based implementation, but I was wondering if there=
=20
was some kind of clean and generic way.

Best regards,

=2D-=20
Laurent Pinchart
CSE Semaphore Belgium

Chauss=E9e de Bruxelles, 732A
B-1410 Waterloo
Belgium

T +32 (2) 387 42 59
=46 +32 (2) 387 42 75

^ permalink raw reply

* Re: [PATCH 7/7] Celleb: update for PCI
From: Ishizaki Kou @ 2007-10-02  8:04 UTC (permalink / raw)
  To: arnd; +Cc: linuxppc-dev, paulus
In-Reply-To: <200709261409.32231.arnd@arndb.de>

Arnd Bergmann <arnd@arndb.de> wrote:
> On Wednesday 26 September 2007, Ishizaki Kou wrote:
> > This is a patch kit to support PCI bus on Celleb with new "I/O routines
> > for PowerPC." External PCI on Celleb must do explicit synchronization
> > with devices (Bus has no automatic synchronization feature).
> 
> It seems you are duplicating a lot of
> arch/powerpc/platforms/cell/io-workarounds.c, in order to work around
> the same problem:

 (snip)

> Is there a way that we can make that code common? I guess there could be a
> file in arch/powerpc/sysdev that can handle this correctly for all hardware
> that requires this particular workaround (currently celleb and QS20, but
> potentially more).

Though I agree it's better to make code common, I hope to keep them
separate for now. Because I'm now developing PCI Express support and
it also uses io-workaround mechanism. I'll try to make them common in
this work.

Best regards,
Kou Ishizaki

^ permalink raw reply

* Stdout console clogging => 300ms blocked
From: Willaert, Bernard @ 2007-10-02  7:41 UTC (permalink / raw)
  To: linuxppc-dev

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

System details:
Freescale MPC8347@200MHz
Kernel 2.6.18

Problem:
When we log debug output via the serial console on a multithreaded
application, the console throughput may get clogged and then we
experience a >300ms deadlock.

Quick and dirty test program: threadtest.c:
//----------------------------------------------------------------------
-------------------------
#include <pthread.h>
#include <stdio.h>
#include <sys/time.h>

#define THREAD_DELAY 1000

void* thread_1(void* unused)
{
	while (1)
	{
		usleep(THREAD_DELAY);
		fprintf(stdout," <----- thread 1\n");
	}
	return NULL;
}

void* thread_2(void* unused)
{
	static long ts_old;
	long ts;
	struct timeval tv;

	while (1)
	{
		usleep(THREAD_DELAY);
		fprintf(stdout," <----- thread 2\n");

		gettimeofday (&tv, NULL);
		ts = (tv.tv_sec * 1000L) + (tv.tv_usec / 1000L);
		if ((ts - ts_old) > 100)
		{
			fprintf(stdout, "!!!!!!!!!!! thread2 interval
timeout = %d ms\n",(int)(ts - ts_old));
		}
		ts_old = ts;
	}
	return NULL;			

}



int main()
{
	pthread_t pthread_id_1, pthread_id_2;
	
	pthread_create(&pthread_id_1,NULL,&thread_1,NULL);
	pthread_create(&pthread_id_2,NULL,&thread_2,NULL);
	while (1)
	{
	}
	return 0;

}

//----------------------------------------------------------------------
-------------------------

Build command on our platform: 
powerpc-linux-uclibc-gcc threadtest.c  -lpthread -o threadtest
Execute: ./threadtest > /dev/console &

Uboot settings for the serial console:
consoledev=ttyS0
baudrate=115200
stdin=serial
stdout=serial
stderr=serial
boot_go=setenv bootargs console=$consoledev,$baudrate $args_rtc
$args_mtd $args_nfs $args_debug;bootm $addr_kernel $addr_root $addr_dtb


Expected output [snippet] on the console:
.... /\ ........
 <----- thread 1
 <----- thread 2
 <----- thread 1
 <----- thread 2
 <----- thread 1
 <----- thread 2
 <----- thread 1
 <----- thread 2
 <----- thread 1
 <----- thread 2
 <----- thread 1
.... /\ ........

Real output on the console:

.... /\ ........
 <----- thread 1
 <----- thread 2
 <----- thread 1
 <----- thread 2
 <----- thread 1
 <----- thread 2
!!!!!!!!!!! thread2 interval timeout = 335 ms
 <----- thread 1
 <----- thread 2
 <----- thread 1
 <----- thread 2
 <----- thread 1
.... /\ ........ 

This timeout shows up around every second and has always about the same
value of 335 ms.
Can somebody reproduce this behaviour ( the console speed and/or thread
interval may have to be tweaked to clog the serial output) ?
Thank you in advance for your help.
Bernard




-----------------------------------------------------------
Bernard Willaert
Software Development Engineer Modality OEM Solutions
BARCO Medical Imaging Division
President Kennedypark 35 - B-8500 KORTRIJK - BELGIUM
Tel.  +32 56 233 439  Fax +32 56 233 457
www.barco.com/medical
mailto:bernard.willaert@barco.com





DISCLAIMER:
Unless indicated otherwise, the information contained in this message is privileged and confidential, and is intended only for the use of the addressee(s) named above and others who have been specifically authorized to receive it. If you are not the intended recipient, you are hereby notified that any dissemination, distribution or copying of this message and/or attachments is strictly prohibited. The company accepts no liability for any damage caused by any virus transmitted by this email. Furthermore, the company does not warrant a proper and complete transmission of this information, nor does it accept liability for any delays. If you have received this message in error, please contact the sender and delete the message. Thank you.

[-- Attachment #2: Type: text/html, Size: 10872 bytes --]

^ permalink raw reply

* Re: [PATCH 3/4] Simplify rtas_change_msi() error semantics
From: Michael Ellerman @ 2007-10-02  7:40 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev
In-Reply-To: <1191306253.6310.106.camel@pasglop>

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

On Tue, 2007-10-02 at 16:24 +1000, Benjamin Herrenschmidt wrote:
> On Tue, 2007-10-02 at 15:58 +1000, Michael Ellerman wrote:
> > > Looks allright, just a question tho... what do we do if it fails ?
> > Do we
> > > try to fallback to a lower number of MSIs ? Or what ? Dead device ?
> > 
> > That's all up to the device driver. In theory the driver could try again
> > with a lower count - but that might require extra logic in the driver to
> > handle shared irq handlers etc. In practice I think the current drivers
> > will just fail.
> 
> Question is badly phrased.. I meant something more like... what do we do
> if RTAS returns a lower count ?
> 
> That is, we end up with that device with that lower count of MSIs
> enabled, we fail at the driver level, do we still somewhat keep track ?
> Drivers might assume that means it can use LSIs no ? which may not be
> the case... Shouldn't we try to switch back to LSI mode (or does the
> RTAS interface doesnt allow it ?)

OK I get you. So:

rtas_setup_msi_irqs() detects that it got fewer MSIs than it asked for
and returns an error.

The generic code (drivers/pci/msi.c) notices the error and calls
msi_free_irqs().

That calls back into rtas_teardown_msi_irqs() which disposes of the virq
mappings and calls rtas_disable_msi().

rtas_disable_msi() asks firmware to configure 0 MSIs on the device, that
hopefully succeeds. AFAIK configuring 0 MSIs is as close as we can get
to disabling MSI via RTAS.

Perhaps that should also (re)enable INTX?

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply


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