LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [BUG] 2.6.24-rc3-mm2 soft lockup while running tbench
From: Kamalesh Babulal @ 2007-11-30  5:09 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linuxppc-dev, balbir, linux-kernel
In-Reply-To: <20071129130905.c31431f3.akpm@linux-foundation.org>

Andrew Morton wrote:
> On Wed, 28 Nov 2007 20:03:22 +0530
> Kamalesh Babulal <kamalesh@linux.vnet.ibm.com> wrote:
> 
>> Hi Andrew,
>>
>> while running tbench on the powerpc with 2.6.24-rc3-mm2 softlock up occurs
>>
>> BUG: soft lockup - CPU#0 stuck for 11s! [tbench:12183]
>> NIP: c0000000000ac978 LR: c0000000000acff0 CTR: c00000000005c648
>> REGS: C00000076F0F3200 TRAP: 0901   Not tainted  (2.6.24-rc3-mm2-autotest)
>> MSR: 8000000000009032 <EE,ME,IR,DR>  CR: 44000482  XER: 00000000
>> TASK = C00000076F4BC000[12183] 'tbench' THREAD: C00000076F0F0000 CPU: 0
>> NIP [c0000000000ac978] .get_page_from_freelist+0x1cc/0x754
>> LR [c0000000000acff0] .__alloc_pages+0xb0/0x3a8
>> Call Trace:
>> [c00000076f0f3480] [c00000076f0f3560] 0xc00000076f0f3560 (unreliable)
>> [c00000076f0f3590] [c0000000000acff0] .__alloc_pages+0xb0/0x3a8
>> [c00000076f0f3680] [c0000000000ce2e4] .alloc_pages_current+0xa8/0xc8
>> [c00000076f0f3710] [c0000000000ac6ec] .__get_free_pages+0x20/0x70
>> [c00000076f0f3790] [c0000000000d75c8] .__kmalloc_node_track_caller+0x60/0x148
>> [c00000076f0f3840] [c0000000002c22b0] .__alloc_skb+0x98/0x184
>> [c00000076f0f38f0] [c000000000306cd8] .tcp_sendmsg+0x1fc/0xe24
>> [c00000076f0f3a10] [c0000000002b963c] .sock_sendmsg+0xe4/0x128
>> [c00000076f0f3c10] [c0000000002ba4ec] .sys_sendto+0xd4/0x120
>> [c00000076f0f3d90] [c0000000002df2f8] .compat_sys_socketcall+0x148/0x214
>> [c00000076f0f3e30] [c00000000000872c] syscall_exit+0x0/0x40
>> Instruction dump:
>> 720b0001 eb970000 40820070 72000002 4182000c e8bc0000 48000018 72080004 
>> 4182000c e8bc0008 48000008 e8bc0010 <e8c10078> 7f83e378 7de407b4 7e078378 
>>
> 
> hm.  Beats me.  Does the machine recover OK?
> -
Hi Andrew,

In the set of test cases ran serially, the softlockup in seen in tbench,
then the remaining test cases get to run successfully after the softlockup.

-- 
Thanks & Regards,
Kamalesh Babulal,
Linux Technology Center,
IBM, ISTL.

^ permalink raw reply

* [PATCH 0/11] ibm_newemac: Candidate patches for 2.6.25
From: Benjamin Herrenschmidt @ 2007-11-30  5:40 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev

Here are the patches I have pending for EMAC. With those, along with
some other powerpc patches scheduled for 2.6.25 for adding support
for those various boards, I have EMAC now working properly on a
variety of platforms, such as Taishan (440GX), Katmai (440SP),
EP405 (405GP), Bamboo (440EP), etc...

This serie apply on top of the patch:

"ibm_newemac: Fix possible lockup on close"

Which should be on its way to 2.6.24 already.

^ permalink raw reply

* [PATCH 1/11] ibm_newemac: Add BCM5248 and Marvell 88E1111 PHY support
From: Benjamin Herrenschmidt @ 2007-11-30  5:40 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <1196401223.5661.297518056501.qpush@grosgo>

From: Stefan Roese <sr@denx.de>

This patch adds BCM5248 and Marvell 88E1111 PHY support to NEW EMAC driver.
These PHY chips are used on PowerPC 440EPx boards.
The PHY code is based on the previous work by Stefan Roese <sr@denx.de>

Signed-off-by: Stefan Roese <sr@denx.de>
Signed-off-by: Valentine Barshak <vbarshak@ru.mvista.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

--- linux.orig/drivers/net/ibm_newemac/phy.c	2007-06-15 21:45:18.000000000 +0400
+++ linux/drivers/net/ibm_newemac/phy.c	2007-06-15 20:45:15.000000000 +0400
@@ -306,8 +306,47 @@
 	.ops		= &cis8201_phy_ops
 };
 
+static struct mii_phy_def bcm5248_phy_def = {
+
+	.phy_id		= 0x0143bc00,
+	.phy_id_mask	= 0x0ffffff0,
+	.name		= "BCM5248 10/100 SMII Ethernet",
+	.ops		= &generic_phy_ops
+};
+
+static int m88e1111_init(struct mii_phy *phy)
+{
+	printk("%s: Marvell 88E1111 Ethernet\n", __FUNCTION__);
+	phy_write(phy, 0x14, 0x0ce3);
+	phy_write(phy, 0x18, 0x4101);
+	phy_write(phy, 0x09, 0x0e00);
+	phy_write(phy, 0x04, 0x01e1);
+	phy_write(phy, 0x00, 0x9140);
+	phy_write(phy, 0x00, 0x1140);
+
+	return  0;
+}
+
+static struct mii_phy_ops m88e1111_phy_ops = {
+	.init		= m88e1111_init,
+	.setup_aneg	= genmii_setup_aneg,
+	.setup_forced	= genmii_setup_forced,
+	.poll_link	= genmii_poll_link,
+	.read_link	= genmii_read_link
+};
+
+static struct mii_phy_def m88e1111_phy_def = {
+
+	.phy_id		= 0x01410CC0,
+	.phy_id_mask	= 0x0ffffff0,
+	.name		= "Marvell 88E1111 Ethernet",
+	.ops		= &m88e1111_phy_ops,
+};
+
 static struct mii_phy_def *mii_phy_table[] = {
 	&cis8201_phy_def,
+	&bcm5248_phy_def,
+	&m88e1111_phy_def,
 	&genmii_phy_def,
 	NULL
 };
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* [PATCH 2/11] ibm_newemac: Add ET1011c PHY support
From: Benjamin Herrenschmidt @ 2007-11-30  5:40 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <1196401223.5661.297518056501.qpush@grosgo>

From: Stefan Roese <sr@denx.de>

This adds support for the Agere ET1011c PHY as found on the AMCC Taishan
board.

Signed-off-by: Stefan Roese <sr@denx.de>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

 drivers/net/ibm_newemac/phy.c |   37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

Index: linux-work/drivers/net/ibm_newemac/phy.c
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/phy.c	2007-11-08 18:54:12.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/phy.c	2007-11-08 18:54:13.000000000 +1100
@@ -327,6 +327,42 @@ static int m88e1111_init(struct mii_phy 
 	return  0;
 }
 
+static int et1011c_init(struct mii_phy *phy)
+{
+        u16 reg_short;
+
+        reg_short = (u16)(phy_read(phy,0x16));
+        reg_short &= ~(0x7);
+        reg_short |= 0x6;       /* RGMII Trace Delay*/
+        phy_write(phy, 0x16, reg_short);
+
+        reg_short = (u16)(phy_read(phy, 0x17));
+        reg_short &= ~(0x40);
+        phy_write(phy, 0x17, reg_short);
+
+        phy_write(phy,0x1c,0x74f0);
+        return 0;
+}
+
+static struct mii_phy_ops et1011c_phy_ops = {
+        .init           = et1011c_init,
+        .setup_aneg     = genmii_setup_aneg,
+        .setup_forced   = genmii_setup_forced,
+        .poll_link      = genmii_poll_link,
+        .read_link      = genmii_read_link
+};
+
+static struct mii_phy_def et1011c_phy_def = {
+        .phy_id         = 0x0282f000,
+        .phy_id_mask    = 0x0fffff00,
+        .name           = "ET1011C Gigabit Ethernet",
+        .ops            = &et1011c_phy_ops
+};
+
+
+
+
+
 static struct mii_phy_ops m88e1111_phy_ops = {
 	.init		= m88e1111_init,
 	.setup_aneg	= genmii_setup_aneg,
@@ -344,6 +380,7 @@ static struct mii_phy_def m88e1111_phy_d
 };
 
 static struct mii_phy_def *mii_phy_table[] = {
+	&et1011c_phy_def,
 	&cis8201_phy_def,
 	&bcm5248_phy_def,
 	&m88e1111_phy_def,

^ permalink raw reply

* [PATCH 3/11] ibm_newemac: Fix ZMII refcounting bug
From: Benjamin Herrenschmidt @ 2007-11-30  5:40 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <1196401223.5661.297518056501.qpush@grosgo>

When using ZMII for MDIO only (such as 440GX with RGMII for data and ZMII for
MDIO), the ZMII code would fail to properly refcount, thus triggering a
BUG_ON().

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Stefan Roese <sr@denx.de>
---

 drivers/net/ibm_newemac/zmii.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Index: linux-work/drivers/net/ibm_newemac/zmii.c
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/zmii.c	2007-11-08 15:45:32.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/zmii.c	2007-11-08 15:46:21.000000000 +1100
@@ -83,12 +83,14 @@ int __devinit zmii_attach(struct of_devi
 
 	ZMII_DBG(dev, "init(%d, %d)" NL, input, *mode);
 
-	if (!zmii_valid_mode(*mode))
+	if (!zmii_valid_mode(*mode)) {
 		/* Probably an EMAC connected to RGMII,
 		 * but it still may need ZMII for MDIO so
 		 * we don't fail here.
 		 */
+		dev->users++;
 		return 0;
+	}
 
 	mutex_lock(&dev->lock);
 

^ permalink raw reply

* [PATCH 4/11] ibm_newemac: Workaround reset timeout when no link
From: Benjamin Herrenschmidt @ 2007-11-30  5:40 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <1196401223.5661.297518056501.qpush@grosgo>

With some PHYs, when the link goes away, the EMAC reset fails due
to the loss of the RX clock I believe.

The old EMAC driver worked around that using some internal chip-specific
clock force bits that are different on various 44x implementations.

This is an attempt at doing it differently, by avoiding the reset when
there is no link, but forcing loopback mode instead. It seems to work
on my Taishan 440GX based board so far.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Stefan Roese <sr@denx.de>
---

 drivers/net/ibm_newemac/core.c |   20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

Index: linux-work/drivers/net/ibm_newemac/core.c
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/core.c	2007-11-20 14:46:51.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/core.c	2007-11-20 14:46:58.000000000 +1100
@@ -464,26 +464,34 @@ static int emac_configure(struct emac_in
 {
 	struct emac_regs __iomem *p = dev->emacp;
 	struct net_device *ndev = dev->ndev;
-	int tx_size, rx_size;
+	int tx_size, rx_size, link = netif_carrier_ok(dev->ndev);
 	u32 r, mr1 = 0;
 
 	DBG(dev, "configure" NL);
 
-	if (emac_reset(dev) < 0)
+	if (!link) {
+		out_be32(&p->mr1, in_be32(&p->mr1)
+			 | EMAC_MR1_FDE | EMAC_MR1_ILE);
+		udelay(100);
+	} else if (emac_reset(dev) < 0)
 		return -ETIMEDOUT;
 
 	if (emac_has_feature(dev, EMAC_FTR_HAS_TAH))
 		tah_reset(dev->tah_dev);
 
-	DBG(dev, " duplex = %d, pause = %d, asym_pause = %d\n",
-	    dev->phy.duplex, dev->phy.pause, dev->phy.asym_pause);
+	DBG(dev, " link = %d duplex = %d, pause = %d, asym_pause = %d\n",
+	    link, dev->phy.duplex, dev->phy.pause, dev->phy.asym_pause);
 
 	/* Default fifo sizes */
 	tx_size = dev->tx_fifo_size;
 	rx_size = dev->rx_fifo_size;
 
+	/* No link, force loopback */
+	if (!link)
+		mr1 = EMAC_MR1_FDE | EMAC_MR1_ILE;
+
 	/* Check for full duplex */
-	if (dev->phy.duplex == DUPLEX_FULL)
+	else if (dev->phy.duplex == DUPLEX_FULL)
 		mr1 |= EMAC_MR1_FDE | EMAC_MR1_MWSW_001;
 
 	/* Adjust fifo sizes, mr1 and timeouts based on link speed */
@@ -1165,9 +1173,9 @@ static void emac_link_timer(struct work_
 		link_poll_interval = PHY_POLL_LINK_ON;
 	} else {
 		if (netif_carrier_ok(dev->ndev)) {
-			emac_reinitialize(dev);
 			netif_carrier_off(dev->ndev);
 			netif_tx_disable(dev->ndev);
+			emac_reinitialize(dev);
 			emac_print_link_status(dev);
 		}
 		link_poll_interval = PHY_POLL_LINK_OFF;

^ permalink raw reply

* [PATCH 5/11] ibm_newemac: Cleanup/Fix RGMII MDIO support detection
From: Benjamin Herrenschmidt @ 2007-11-30  5:40 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <1196401223.5661.297518056501.qpush@grosgo>

More than just "AXON" version of EMAC RGMII supports MDIO, so replace
the current test with a generic property in the device-tree that
indicates such support.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Stefan Roese <sr@denx.de>
---

 arch/powerpc/boot/dts/sequoia.dts |    1 +
 drivers/net/ibm_newemac/rgmii.c   |   20 +++++++++++---------
 drivers/net/ibm_newemac/rgmii.h   |    5 +++--
 3 files changed, 15 insertions(+), 11 deletions(-)

Index: linux-work/drivers/net/ibm_newemac/rgmii.c
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/rgmii.c	2007-11-12 10:55:54.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/rgmii.c	2007-11-12 10:56:56.000000000 +1100
@@ -140,7 +140,7 @@ void rgmii_get_mdio(struct of_device *of
 
 	RGMII_DBG2(dev, "get_mdio(%d)" NL, input);
 
-	if (dev->type != RGMII_AXON)
+	if (!(dev->flags & EMAC_RGMII_FLAG_HAS_MDIO))
 		return;
 
 	mutex_lock(&dev->lock);
@@ -161,7 +161,7 @@ void rgmii_put_mdio(struct of_device *of
 
 	RGMII_DBG2(dev, "put_mdio(%d)" NL, input);
 
-	if (dev->type != RGMII_AXON)
+	if (!(dev->flags & EMAC_RGMII_FLAG_HAS_MDIO))
 		return;
 
 	fer = in_be32(&p->fer);
@@ -250,11 +250,13 @@ static int __devinit rgmii_probe(struct 
 		goto err_free;
 	}
 
-	/* Check for RGMII type */
+	/* Check for RGMII flags */
+	if (of_get_property(ofdev->node, "has-mdio", NULL))
+		dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO;
+
+	/* CAB lacks the right properties, fix this up */
 	if (of_device_is_compatible(ofdev->node, "ibm,rgmii-axon"))
-		dev->type = RGMII_AXON;
-	else
-		dev->type = RGMII_STANDARD;
+		dev->flags |= EMAC_RGMII_FLAG_HAS_MDIO;
 
 	DBG2(dev, " Boot FER = 0x%08x, SSR = 0x%08x\n",
 	     in_be32(&dev->base->fer), in_be32(&dev->base->ssr));
@@ -263,9 +265,9 @@ static int __devinit rgmii_probe(struct 
 	out_be32(&dev->base->fer, 0);
 
 	printk(KERN_INFO
-	       "RGMII %s %s initialized\n",
-	       dev->type == RGMII_STANDARD ? "standard" : "axon",
-	       ofdev->node->full_name);
+	       "RGMII %s initialized with%s MDIO support\n",
+	       ofdev->node->full_name,
+	       (dev->flags & EMAC_RGMII_FLAG_HAS_MDIO) ? "" : "out");
 
 	wmb();
 	dev_set_drvdata(&ofdev->dev, dev);
Index: linux-work/drivers/net/ibm_newemac/rgmii.h
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/rgmii.h	2007-11-12 10:55:54.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/rgmii.h	2007-11-12 10:56:56.000000000 +1100
@@ -35,8 +35,9 @@ struct rgmii_regs {
 struct rgmii_instance {
 	struct rgmii_regs __iomem	*base;
 
-	/* Type of RGMII bridge */
-	int				type;
+	/* RGMII bridge flags */
+	int				flags;
+#define EMAC_RGMII_FLAG_HAS_MDIO	0x00000001
 
 	/* Only one EMAC whacks us at a time */
 	struct mutex			lock;
Index: linux-work/arch/powerpc/boot/dts/sequoia.dts
===================================================================
--- linux-work.orig/arch/powerpc/boot/dts/sequoia.dts	2007-11-12 10:58:38.000000000 +1100
+++ linux-work/arch/powerpc/boot/dts/sequoia.dts	2007-11-12 10:58:47.000000000 +1100
@@ -245,6 +245,7 @@
 				device_type = "rgmii-interface";
 				compatible = "ibm,rgmii-440epx", "ibm,rgmii";
 				reg = <ef601000 8>;
+				has-mdio;
 			};
 
 			EMAC0: ethernet@ef600e00 {

^ permalink raw reply

* [PATCH 6/11] ibm_newemac: Cleanup/fix support for STACR register variants
From: Benjamin Herrenschmidt @ 2007-11-30  5:40 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <1196401223.5661.297518056501.qpush@grosgo>

There are a few variants of the STACR register that affect more than
just the "AXON" version of EMAC. Replace the current test of various
chip models with tests for generic properties in the device-tree.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Stefan Roese <sr@denx.de>
---

 arch/powerpc/boot/dts/sequoia.dts |    4 ++++
 drivers/net/ibm_newemac/core.c    |   23 +++++++++++++----------
 drivers/net/ibm_newemac/core.h    |    6 +++---
 3 files changed, 20 insertions(+), 13 deletions(-)

Index: linux-work/arch/powerpc/boot/dts/sequoia.dts
===================================================================
--- linux-work.orig/arch/powerpc/boot/dts/sequoia.dts	2007-11-20 14:47:01.000000000 +1100
+++ linux-work/arch/powerpc/boot/dts/sequoia.dts	2007-11-20 14:47:02.000000000 +1100
@@ -274,6 +274,8 @@
 				zmii-channel = <0>;
 				rgmii-device = <&RGMII0>;
 				rgmii-channel = <0>;
+				has-inverted-stacr-oc;
+				has-new-stacr-staopc;
 			};
 
 			EMAC1: ethernet@ef600f00 {
@@ -302,6 +304,8 @@
 				zmii-channel = <1>;
 				rgmii-device = <&RGMII0>;
 				rgmii-channel = <1>;
+				has-inverted-stacr-oc;
+				has-new-stacr-staopc;
 			};
 		};
 	};
Index: linux-work/drivers/net/ibm_newemac/core.c
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/core.c	2007-11-20 14:46:58.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/core.c	2007-11-20 14:47:02.000000000 +1100
@@ -711,7 +711,7 @@ static int __emac_mdio_read(struct emac_
 		r = EMAC_STACR_BASE(dev->opb_bus_freq);
 	if (emac_has_feature(dev, EMAC_FTR_STACR_OC_INVERT))
 		r |= EMAC_STACR_OC;
-	if (emac_has_feature(dev, EMAC_FTR_HAS_AXON_STACR))
+	if (emac_has_feature(dev, EMAC_FTR_HAS_NEW_STACR))
 		r |= EMACX_STACR_STAC_READ;
 	else
 		r |= EMAC_STACR_STAC_READ;
@@ -783,7 +783,7 @@ static void __emac_mdio_write(struct ema
 		r = EMAC_STACR_BASE(dev->opb_bus_freq);
 	if (emac_has_feature(dev, EMAC_FTR_STACR_OC_INVERT))
 		r |= EMAC_STACR_OC;
-	if (emac_has_feature(dev, EMAC_FTR_HAS_AXON_STACR))
+	if (emac_has_feature(dev, EMAC_FTR_HAS_NEW_STACR))
 		r |= EMACX_STACR_STAC_WRITE;
 	else
 		r |= EMAC_STACR_STAC_WRITE;
@@ -2480,16 +2480,19 @@ static int __devinit emac_init_config(st
 	/* Check EMAC version */
 	if (of_device_is_compatible(np, "ibm,emac4"))
 		dev->features |= EMAC_FTR_EMAC4;
-	if (of_device_is_compatible(np, "ibm,emac-axon")
-	    || of_device_is_compatible(np, "ibm,emac-440epx"))
-		dev->features |= EMAC_FTR_HAS_AXON_STACR
-			| EMAC_FTR_STACR_OC_INVERT;
-	if (of_device_is_compatible(np, "ibm,emac-440spe"))
+
+	/* Fixup some feature bits based on the device tree */
+	if (of_get_property(np, "has-inverted-stacr-oc", NULL))
 		dev->features |= EMAC_FTR_STACR_OC_INVERT;
+	if (of_get_property(np, "has-new-stacr-staopc", NULL))
+		dev->features |= EMAC_FTR_HAS_NEW_STACR;
 
-	/* Fixup some feature bits based on the device tree and verify
-	 * we have support for them compiled in
-	 */
+	/* CAB lacks the appropriate properties */
+	if (of_device_is_compatible(np, "ibm,emac-axon"))
+		dev->features |= EMAC_FTR_HAS_NEW_STACR |
+			EMAC_FTR_STACR_OC_INVERT;
+
+	/* Enable TAH/ZMII/RGMII features as found */
 	if (dev->tah_ph != 0) {
 #ifdef CONFIG_IBM_NEW_EMAC_TAH
 		dev->features |= EMAC_FTR_HAS_TAH;
Index: linux-work/drivers/net/ibm_newemac/core.h
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/core.h	2007-11-20 14:46:51.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/core.h	2007-11-20 14:47:02.000000000 +1100
@@ -293,9 +293,9 @@ struct emac_instance {
  */
 #define EMAC_FTR_HAS_RGMII		0x00000020
 /*
- * Set if we have axon-type STACR
+ * Set if we have new type STACR with STAOPC
  */
-#define EMAC_FTR_HAS_AXON_STACR		0x00000040
+#define EMAC_FTR_HAS_NEW_STACR		0x00000040
 
 
 /* Right now, we don't quite handle the always/possible masks on the
@@ -307,7 +307,7 @@ enum {
 
 	EMAC_FTRS_POSSIBLE	=
 #ifdef CONFIG_IBM_NEW_EMAC_EMAC4
-	    EMAC_FTR_EMAC4	| EMAC_FTR_HAS_AXON_STACR	|
+	    EMAC_FTR_EMAC4	| EMAC_FTR_HAS_NEW_STACR	|
 	    EMAC_FTR_STACR_OC_INVERT	|
 #endif
 #ifdef CONFIG_IBM_NEW_EMAC_TAH

^ permalink raw reply

* [PATCH 7/11] ibm_newemac: Skip EMACs that are marked unused by the firmware
From: Benjamin Herrenschmidt @ 2007-11-30  5:40 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <1196401223.5661.297518056501.qpush@grosgo>

From: Hugh Blemings <hugh@blemings.org>

Depending on how the 44x processors are wired, some EMAC cells
might not be useable (and not connected to a PHY). However, some
device-trees may choose to still expose them (since their registers
are present in the MMIO space) but with an "unused" property in them.

Signed-off-by: Hugh Blemings <hugh@blemings.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

 drivers/net/ibm_newemac/core.c |    4 ++++
 1 file changed, 4 insertions(+)

Index: linux-work/drivers/net/ibm_newemac/core.c
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/core.c	2007-11-20 14:47:02.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/core.c	2007-11-20 14:47:05.000000000 +1100
@@ -2550,6 +2550,10 @@ static int __devinit emac_probe(struct o
 	struct device_node **blist = NULL;
 	int err, i;
 
+	/* Skip unused/unwired EMACS */
+	if (of_get_property(np, "unused", NULL))
+		return -ENODEV;
+
 	/* Find ourselves in the bootlist if we are there */
 	for (i = 0; i < EMAC_BOOT_LIST_SIZE; i++)
 		if (emac_boot_list[i] == np)

^ permalink raw reply

* [PATCH 8/11] ibm_newemac: Correct opb_bus_freq value
From: Benjamin Herrenschmidt @ 2007-11-30  5:40 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <1196401223.5661.297518056501.qpush@grosgo>

From: Valentine Barshak <vbarshak@ru.mvista.com>

The EMAC4_MR1_OBCI(freq) macro expects freg in MHz,
while opb_bus_freq is kept in Hz. Correct this.

Signed-off-by: Valentine Barshak <vbarshak@ru.mvista.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

diff -pruN 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-11-23 21:27:57.000000000 +0300
+++ linux-2.6/drivers/net/ibm_newemac/core.c	2007-11-23 21:47:53.000000000 +0300
@@ -402,7 +402,7 @@ static u32 __emac_calc_base_mr1(struct e
 static u32 __emac4_calc_base_mr1(struct emac_instance *dev, int tx_size, int rx_size)
 {
 	u32 ret = EMAC_MR1_VLE | EMAC_MR1_IST | EMAC4_MR1_TR |
-		EMAC4_MR1_OBCI(dev->opb_bus_freq);
+		EMAC4_MR1_OBCI(dev->opb_bus_freq / 1000000);
 
 	DBG2(dev, "__emac4_calc_base_mr1" NL);
 

^ permalink raw reply

* [PATCH 9/11] ibm_newemac: Fix typo reading TAH channel info
From: Benjamin Herrenschmidt @ 2007-11-30  5:40 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <1196401223.5661.297518056501.qpush@grosgo>

From: Valentine Barshak <vbarshak@ru.mvista.com>

This patch fixes a typo in ibm_newemac/core.c
(tah_port should be used instead of tah_ph)

Signed-off-by: Valentine Barshak <vbarshak@ru.mvista.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

 drivers/net/ibm_newemac/core.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux-work/drivers/net/ibm_newemac/core.c
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/core.c	2007-11-26 09:43:04.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/core.c	2007-11-26 09:43:05.000000000 +1100
@@ -2442,7 +2442,7 @@ static int __devinit emac_init_config(st
 	if (emac_read_uint_prop(np, "tah-device", &dev->tah_ph, 0))
 		dev->tah_ph = 0;
 	if (emac_read_uint_prop(np, "tah-channel", &dev->tah_port, 0))
-		dev->tah_ph = 0;
+		dev->tah_port = 0;
 	if (emac_read_uint_prop(np, "mdio-device", &dev->mdio_ph, 0))
 		dev->mdio_ph = 0;
 	if (emac_read_uint_prop(np, "zmii-device", &dev->zmii_ph, 0))

^ permalink raw reply

* [PATCH 10/11] ibm_newemac: Call dev_set_drvdata() before tah_reset()
From: Benjamin Herrenschmidt @ 2007-11-30  5:40 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <1196401223.5661.297518056501.qpush@grosgo>

From: Valentine Barshak <vbarshak@ru.mvista.com>

The patch moves dev_set_drvdata(&ofdev->dev, dev) up before tah_reset(ofdev)
is called to avoid a NULL pointer dereference, since tah_reset uses drvdata.

Signed-off-by: Valentine Barshak <vbarshak@ru.mvista.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

diff -pruN linux-2.6.orig/drivers/net/ibm_newemac/tah.c linux-2.6/drivers/net/ibm_newemac/tah.c
--- linux-2.6.orig/drivers/net/ibm_newemac/tah.c	2007-11-23 21:27:57.000000000 +0300
+++ linux-2.6/drivers/net/ibm_newemac/tah.c	2007-11-23 21:35:12.000000000 +0300
@@ -116,13 +116,14 @@ static int __devinit tah_probe(struct of
 		goto err_free;
 	}
 
+	dev_set_drvdata(&ofdev->dev, dev);
+
 	/* Initialize TAH and enable IPv4 checksum verification, no TSO yet */
 	tah_reset(ofdev);
 
 	printk(KERN_INFO
 	       "TAH %s initialized\n", ofdev->node->full_name);
 	wmb();
-	dev_set_drvdata(&ofdev->dev, dev);
 
 	return 0;
 

^ permalink raw reply

* [PATCH 11/11] emac: Update file headers copyright notices
From: Benjamin Herrenschmidt @ 2007-11-30  5:40 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev
In-Reply-To: <1196401223.5661.297518056501.qpush@grosgo>

This updates the copyright notices of the new EMAC driver to
avoid confusion as who is to be blamed for new bugs.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 
 drivers/net/ibm_newemac/core.c  |    5 +++++
 drivers/net/ibm_newemac/core.h  |    5 +++++
 drivers/net/ibm_newemac/debug.c |    5 +++++
 drivers/net/ibm_newemac/debug.h |    5 +++++
 drivers/net/ibm_newemac/emac.h  |    5 +++++
 drivers/net/ibm_newemac/mal.c   |    5 +++++
 drivers/net/ibm_newemac/mal.h   |    5 +++++
 drivers/net/ibm_newemac/phy.c   |    5 +++++
 drivers/net/ibm_newemac/phy.h   |    5 +++++
 drivers/net/ibm_newemac/rgmii.c |    5 +++++
 drivers/net/ibm_newemac/rgmii.h |    5 +++++
 drivers/net/ibm_newemac/tah.c   |    5 +++++
 drivers/net/ibm_newemac/tah.h   |    5 +++++
 drivers/net/ibm_newemac/zmii.c  |    5 +++++
 drivers/net/ibm_newemac/zmii.h  |    5 +++++
 15 files changed, 75 insertions(+)

Index: linux-work/drivers/net/ibm_newemac/core.c
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/core.c	2007-11-30 15:35:50.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/core.c	2007-11-30 16:03:30.000000000 +1100
@@ -3,6 +3,11 @@
  *
  * Driver for PowerPC 4xx on-chip ethernet controller.
  *
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ *                <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
  * Copyright (c) 2004, 2005 Zultys Technologies.
  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
  *
Index: linux-work/drivers/net/ibm_newemac/core.h
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/core.h	2007-11-30 15:35:50.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/core.h	2007-11-30 16:03:23.000000000 +1100
@@ -3,6 +3,11 @@
  *
  * Driver for PowerPC 4xx on-chip ethernet controller.
  *
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ *                <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
  * Copyright (c) 2004, 2005 Zultys Technologies.
  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
  *
Index: linux-work/drivers/net/ibm_newemac/debug.c
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/debug.c	2007-11-30 15:35:50.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/debug.c	2007-11-30 16:03:18.000000000 +1100
@@ -3,6 +3,11 @@
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines.
  *
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ *                <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
  * Copyright (c) 2004, 2005 Zultys Technologies
  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
  *
Index: linux-work/drivers/net/ibm_newemac/debug.h
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/debug.h	2007-11-30 15:35:50.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/debug.h	2007-11-30 16:03:15.000000000 +1100
@@ -3,6 +3,11 @@
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines.
  *
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ *                <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
  * Copyright (c) 2004, 2005 Zultys Technologies
  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
  *
Index: linux-work/drivers/net/ibm_newemac/emac.h
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/emac.h	2007-11-30 15:35:50.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/emac.h	2007-11-30 16:03:09.000000000 +1100
@@ -3,6 +3,11 @@
  *
  * Register definitions for PowerPC 4xx on-chip ethernet contoller
  *
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ *                <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
  * Copyright (c) 2004, 2005 Zultys Technologies.
  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
  *
Index: linux-work/drivers/net/ibm_newemac/mal.c
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/mal.c	2007-11-30 15:35:51.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/mal.c	2007-11-30 16:03:02.000000000 +1100
@@ -3,6 +3,11 @@
  *
  * Memory Access Layer (MAL) support
  *
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ *                <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
  * Copyright (c) 2004, 2005 Zultys Technologies.
  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
  *
Index: linux-work/drivers/net/ibm_newemac/mal.h
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/mal.h	2007-11-30 15:35:51.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/mal.h	2007-11-30 16:02:55.000000000 +1100
@@ -3,6 +3,11 @@
  *
  * Memory Access Layer (MAL) support
  *
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ *                <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
  * Copyright (c) 2004, 2005 Zultys Technologies.
  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
  *
Index: linux-work/drivers/net/ibm_newemac/phy.c
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/phy.c	2007-11-30 15:35:51.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/phy.c	2007-11-30 16:02:47.000000000 +1100
@@ -8,6 +8,11 @@
  * This file should be shared with other drivers or eventually
  * merged as the "low level" part of miilib
  *
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ *                <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
  * (c) 2003, Benjamin Herrenscmidt (benh@kernel.crashing.org)
  * (c) 2004-2005, Eugene Surovegin <ebs@ebshome.net>
  *
Index: linux-work/drivers/net/ibm_newemac/phy.h
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/phy.h	2007-11-30 15:35:51.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/phy.h	2007-11-30 16:02:32.000000000 +1100
@@ -3,6 +3,11 @@
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, PHY support
  *
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ *                <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
  * Benjamin Herrenschmidt <benh@kernel.crashing.org>
  * February 2003
  *
Index: linux-work/drivers/net/ibm_newemac/rgmii.c
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/rgmii.c	2007-11-30 15:35:51.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/rgmii.c	2007-11-30 16:02:23.000000000 +1100
@@ -3,6 +3,11 @@
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support.
  *
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ *                <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
  * Copyright (c) 2004, 2005 Zultys Technologies.
  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
  *
Index: linux-work/drivers/net/ibm_newemac/rgmii.h
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/rgmii.h	2007-11-30 15:35:51.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/rgmii.h	2007-11-30 16:02:19.000000000 +1100
@@ -3,6 +3,11 @@
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support.
  *
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ *                <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
  * Based on ocp_zmii.h/ibm_emac_zmii.h
  * Armin Kuster akuster@mvista.com
  *
Index: linux-work/drivers/net/ibm_newemac/tah.c
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/tah.c	2007-11-30 15:35:51.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/tah.c	2007-11-30 16:02:11.000000000 +1100
@@ -3,6 +3,11 @@
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, TAH support.
  *
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ *                <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
  * Copyright 2004 MontaVista Software, Inc.
  * Matt Porter <mporter@kernel.crashing.org>
  *
Index: linux-work/drivers/net/ibm_newemac/tah.h
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/tah.h	2007-11-30 15:35:51.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/tah.h	2007-11-30 16:02:06.000000000 +1100
@@ -3,6 +3,11 @@
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, TAH support.
  *
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ *                <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
  * Copyright 2004 MontaVista Software, Inc.
  * Matt Porter <mporter@kernel.crashing.org>
  *
Index: linux-work/drivers/net/ibm_newemac/zmii.c
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/zmii.c	2007-11-30 15:35:51.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/zmii.c	2007-11-30 16:01:53.000000000 +1100
@@ -3,6 +3,11 @@
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support.
  *
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ *                <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
  * Copyright (c) 2004, 2005 Zultys Technologies.
  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
  *
Index: linux-work/drivers/net/ibm_newemac/zmii.h
===================================================================
--- linux-work.orig/drivers/net/ibm_newemac/zmii.h	2007-11-30 15:35:51.000000000 +1100
+++ linux-work/drivers/net/ibm_newemac/zmii.h	2007-11-30 16:01:33.000000000 +1100
@@ -3,6 +3,11 @@
  *
  * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support.
  *
+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ *                <benh@kernel.crashing.org>
+ *
+ * Based on the arch/ppc version of the driver:
+ *
  * Copyright (c) 2004, 2005 Zultys Technologies.
  * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
  *

^ permalink raw reply

* Re: [PATCH] Add MPC837xEMDS PCIE RC mode support
From: Li Li @ 2007-11-30  5:33 UTC (permalink / raw)
  To: Olof Johansson; +Cc: linuxppc-dev, Gala Kumar, Li Tony
In-Reply-To: <20071130041404.GB26982@lixom.net>

On Fri, 2007-11-30 at 12:14 +0800, Olof Johansson wrote:
> Hi,
> 
> On Fri, Nov 30, 2007 at 11:45:34AM +0800, Li Li wrote:
> 
> > +     pci2@e0009000 {
> 
> Why call it pci2@ (and pci3@ below)? They are clearly identifiable
> with 
> their unit addresses anyway.
> 
> > +config PPC_MPC83XX_PCIE 
> > +     bool "MPC837X PCI Express support" 
> > +     depends on PCIEPORTBUS && PPC_MPC837x 
> > +     default n 
> > +     help 
> > +       Enables MPC837x PCI express RC mode
> 
> Why have a separate config option for this?
> 
> For systems where you don't want PCI-e configured, it should be left 
> out of the device tree instead.

It is easy to configure kernel than modify and recompile the dts.
The pcie is default enabled in dts.

> 
> 
> 
> -Olof
> 
- Tony

^ permalink raw reply

* Re: [PATCH] powerpc: fix os-term usage on kernel panic
From: Stephen Rothwell @ 2007-11-30  5:56 UTC (permalink / raw)
  To: will_schmidt; +Cc: linuxppc-dev, paulus
In-Reply-To: <1196208960.11297.26.camel@farscape.rchland.ibm.com>

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

On Tue, 27 Nov 2007 18:15:59 -0600 Will Schmidt <will_schmidt@vnet.ibm.com> wrote:
>
> (resending with the proper "from" addr this time). 
> 
> 
> I'm seeing some funky behavior on power5/power6 partitions with this
> patch.    A "/sbin/reboot" is now behaving much more like a
> "/sbin/halt".
> 
> Anybody else seeing this, or is it time for me to call an exorcist for
> my boxes? 

On my Power5+ box, I get an error (code B200A101) logged every time I
reboot and about half the time, the machine does not reboot but need to
be power cycled. Removing the cited patch makes the error not by logged
and reboots work fine.

Paul and I have been having a look at this and Paul has asked the
architects for clarification of when os-term should be used.

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

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

^ permalink raw reply

* [PATCH 0/24] powerpc: 4xx PCI, PCI-X and PCI-Express support among others
From: Benjamin Herrenschmidt @ 2007-11-30  6:10 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev

Here's a set of patches that bring PCI, PCI-X and PCI-Express
support to 4xx on arch/powerpc. It also changes/fixed various
bits and pieces, such as a bit of rework of arch/powerpc/boot
4xx code, adding a couple of new platforms along the way. 

There are some issues with the SCSI stack vs. non-coherent
DMA that I'm working on fixing separately, and there's a
problem I noticed with the e1000 driver vs. 64 bits resources
on 32 bits architectures for which I also have a patch that
I posted separately. Appart from that, I got it working fine
with a USB2 card in an ebony and 2 USB storage devices.

Some of these patches are _NOT_ yet candidate for merging
(mostly the board support ones), but you can review them and
Josh can put them in an experimental tree.

There will be further cleanups and fixes before 2.6.25 opens

^ permalink raw reply

* [PATCH 1/24] powerpc: Make isa_mem_base common to 32 and 64 bits
From: Benjamin Herrenschmidt @ 2007-11-30  6:10 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <1196403038.569525.367459803520.qpush@grosgo>

This defines isa_mem_base on both 32 and 64 bits (it used to be 32 bits
only). This avoids a few ifdef's in later patches and potentially can
allow support for VGA text mode on 64 bits powerpc.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

Small cleanup pre-requisite for my next patch

 arch/powerpc/kernel/pci-common.c |    4 ++++
 arch/powerpc/kernel/pci_32.c     |    1 -
 include/asm-powerpc/io.h         |    5 +++--
 3 files changed, 7 insertions(+), 3 deletions(-)

Index: linux-work/arch/powerpc/kernel/pci-common.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci-common.c	2007-11-20 14:42:49.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci-common.c	2007-11-20 15:03:02.000000000 +1100
@@ -52,6 +52,10 @@ int global_phb_number;		/* Global phb co
 
 extern struct list_head hose_list;
 
+/* ISA Memory physical address */
+resource_size_t isa_mem_base;
+
+
 /*
  * pci_controller(phb) initialized common variables.
  */
Index: linux-work/include/asm-powerpc/io.h
===================================================================
--- linux-work.orig/include/asm-powerpc/io.h	2007-11-20 14:42:49.000000000 +1100
+++ linux-work/include/asm-powerpc/io.h	2007-11-20 14:47:11.000000000 +1100
@@ -50,15 +50,16 @@ extern int check_legacy_ioport(unsigned 
 #define PCI_DRAM_OFFSET	pci_dram_offset
 #else
 #define _IO_BASE	pci_io_base
-#define _ISA_MEM_BASE	0
+#define _ISA_MEM_BASE	isa_mem_base
 #define PCI_DRAM_OFFSET	0
 #endif
 
 extern unsigned long isa_io_base;
-extern unsigned long isa_mem_base;
 extern unsigned long pci_io_base;
 extern unsigned long pci_dram_offset;
 
+extern resource_size_t isa_mem_base;
+
 #if defined(CONFIG_PPC32) && defined(CONFIG_PPC_INDIRECT_IO)
 #error CONFIG_PPC_INDIRECT_IO is not yet supported on 32 bits
 #endif
Index: linux-work/arch/powerpc/kernel/pci_32.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci_32.c	2007-11-20 14:42:49.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci_32.c	2007-11-20 15:02:43.000000000 +1100
@@ -32,7 +32,6 @@
 #endif
 
 unsigned long isa_io_base     = 0;
-unsigned long isa_mem_base    = 0;
 unsigned long pci_dram_offset = 0;
 int pcibios_assign_bus_offset = 1;
 

^ permalink raw reply

* [PATCH 2/24] powerpc: Merge pci_process_bridge_OF_ranges()
From: Benjamin Herrenschmidt @ 2007-11-30  6:10 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <1196403038.569525.367459803520.qpush@grosgo>

This patch merges the 32 and 64 bits implementations of
pci_process_bridge_OF_ranges(). The new function is cleaner than both
the old ones supports 64 bits ranges on ppc32 which is necessary for
the 4xx port.

It also adds some better (hopefully) output to the kernel log which
should help disagnose problems and makes better use of existing OF
parsing helpers (avoiding a few bugs of both implementations along
the way).

There are still a few unfortunate ifdef's but there is no way around
these for now at least not until some other bits of the PCI code are
made common.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

Tested on a few pSeries, PowerMac G5, and a 32 bits PowerMacs and
a BriQ. Please let me know if it misbehaves anywhere else.

 arch/powerpc/kernel/pci-common.c |  176 +++++++++++++++++++++++++++++++++++++++
 arch/powerpc/kernel/pci_32.c     |  114 -------------------------
 arch/powerpc/kernel/pci_64.c     |   93 --------------------
 include/asm-powerpc/pci-bridge.h |    1 
 4 files changed, 177 insertions(+), 207 deletions(-)

Index: linux-work/arch/powerpc/kernel/pci-common.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci-common.c	2007-11-13 14:15:43.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci-common.c	2007-11-13 16:04:06.000000000 +1100
@@ -479,3 +479,179 @@ void pci_resource_to_user(const struct p
 	*start = rsrc->start - offset;
 	*end = rsrc->end - offset;
 }
+
+/**
+ * pci_process_bridge_OF_ranges - Parse PCI bridge resources from device tree
+ * @hose: newly allocated pci_controller to be setup
+ * @dev: device node of the host bridge
+ * @primary: set if primary bus (32 bits only, soon to be deprecated)
+ *
+ * This function will parse the "ranges" property of a PCI host bridge device
+ * node and setup the resource mapping of a pci controller based on its
+ * content.
+ *
+ * Life would be boring if it wasn't for a few issues that we have to deal
+ * with here:
+ *
+ *   - We can only cope with one IO space range and up to 3 Memory space
+ *     ranges. However, some machines (thanks Apple !) tend to split their
+ *     space into lots of small contiguous ranges. So we have to coalesce.
+ *
+ *   - We can only cope with all memory ranges having the same offset
+ *     between CPU addresses and PCI addresses. Unfortunately, some bridges
+ *     are setup for a large 1:1 mapping along with a small "window" which
+ *     maps PCI address 0 to some arbitrary high address of the CPU space in
+ *     order to give access to the ISA memory hole.
+ *     The way out of here that I've chosen for now is to always set the
+ *     offset based on the first resource found, then override it if we
+ *     have a different offset and the previous was set by an ISA hole.
+ *
+ *   - Some busses have IO space not starting at 0, which causes trouble with
+ *     the way we do our IO resource renumbering. The code somewhat deals with
+ *     it for 64 bits but I would expect problems on 32 bits.
+ *
+ *   - Some 32 bits platforms such as 4xx can have physical space larger than
+ *     32 bits so we need to use 64 bits values for the parsing
+ */
+void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
+					    struct device_node *dev,
+					    int primary)
+{
+	const u32 *ranges;
+	int rlen;
+	int pna = of_n_addr_cells(dev);
+	int np = pna + 5;
+	int memno = 0, isa_hole = -1;
+	u32 pci_space;
+	unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size;
+	unsigned long long isa_mb = 0;
+	struct resource *res;
+
+	printk(KERN_INFO "PCI host bridge %s %s ranges:\n",
+	       dev->full_name, primary ? "(primary)" : "");
+
+	/* Get ranges property */
+	ranges = of_get_property(dev, "ranges", &rlen);
+	if (ranges == NULL)
+		return;
+
+	/* Parse it */
+	while ((rlen -= np * 4) >= 0) {
+		/* Read next ranges element */
+		pci_space = ranges[0];
+		pci_addr = of_read_number(ranges + 1, 2);
+		cpu_addr = of_translate_address(dev, ranges + 3);
+		size = of_read_number(ranges + pna + 3, 2);
+		ranges += np;
+		if (cpu_addr == OF_BAD_ADDR || size == 0)
+			continue;
+
+		/* Now consume following elements while they are contiguous */
+		for (;rlen >= np * sizeof(u32); ranges += np, rlen -= np * 4) {
+			if (ranges[0] != pci_space)
+				break;
+			pci_next = of_read_number(ranges + 1, 2);
+			cpu_next = of_translate_address(dev, ranges + 3);
+			if (pci_next != pci_addr + size ||
+			    cpu_next != cpu_addr + size)
+				break;
+			size += of_read_number(ranges + pna + 3, 2);
+		}
+
+		/* Act based on address space type */
+		res = NULL;
+		switch ((pci_space >> 24) & 0x3) {
+		case 1:		/* PCI IO space */
+			printk(KERN_INFO
+			       "  IO 0x%016llx..0x%016llx -> 0x%016llx\n",
+			       cpu_addr, cpu_addr + size - 1, pci_addr);
+
+			/* We support only one IO range */
+			if (hose->pci_io_size) {
+				printk(KERN_WARNING
+				       " \\--> Skipped (too many) !\n");
+				continue;
+			}
+#ifdef CONFIG_PPC32
+			/* On 32 bits, limit I/O space to 16MB */
+			if (size > 0x01000000)
+				size = 0x01000000;
+
+			/* 32 bits needs to map IOs here */
+			hose->io_base_virt = ioremap(cpu_addr, size);
+
+			/* Expect trouble if pci_addr is not 0 */
+			if (primary)
+				isa_io_base =
+					(unsigned long)hose->io_base_virt;
+#endif /* CONFIG_PPC32 */
+			/* pci_io_size and io_base_phys always represent IO
+			 * space starting at 0 so we factor in pci_addr
+			 */
+			hose->pci_io_size = pci_addr + size;
+			hose->io_base_phys = cpu_addr - pci_addr;
+
+			/* Build resource */
+			res = &hose->io_resource;
+			res->flags = IORESOURCE_IO;
+			res->start = pci_addr;
+			break;
+		case 2:		/* PCI Memory space */
+			printk(KERN_INFO
+			       " MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n",
+			       cpu_addr, cpu_addr + size - 1, pci_addr,
+			       (pci_space & 0x40000000) ? "Prefetch" : "");
+
+			/* We support only 3 memory ranges */
+			if (memno >= 3) {
+				printk(KERN_WARNING
+				       " \\--> Skipped (too many) !\n");
+				continue;
+			}
+			/* Handles ISA memory hole space here */
+			if (pci_addr == 0) {
+				isa_mb = cpu_addr;
+				isa_hole = memno;
+				if (primary || isa_mem_base == 0)
+					isa_mem_base = cpu_addr;
+			}
+
+			/* We get the PCI/Mem offset from the first range or the,
+			 * current one if the offset came from an ISA hole.
+			 * If they don't match, bugger.
+			 */
+			if (memno == 0 ||
+			    (isa_hole >= 0 && pci_addr != 0 &&
+			     hose->pci_mem_offset == isa_mb))
+				hose->pci_mem_offset = cpu_addr - pci_addr;
+			else if (pci_addr != 0 &&
+				 hose->pci_mem_offset != cpu_addr - pci_addr) {
+				printk(KERN_WARNING
+				       " \\--> Skipped (offset mismatch) !\n");
+				continue;
+			}
+
+			/* Build resource */
+			res = &hose->mem_resources[memno++];
+			res->flags = IORESOURCE_MEM;
+			if (pci_space & 0x40000000)
+				res->flags |= IORESOURCE_PREFETCH;
+			res->start = cpu_addr;
+			break;
+		}
+		if (res != NULL) {
+			res->name = dev->full_name;
+			res->end = res->start + size - 1;
+			res->parent = NULL;
+			res->sibling = NULL;
+			res->child = NULL;
+		}
+	}
+
+	/* Out of paranoia, let's put the ISA hole last if any */
+	if (isa_hole >= 0 && memno > 0 && isa_hole != (memno-1)) {
+		struct resource tmp = hose->mem_resources[isa_hole];
+		hose->mem_resources[isa_hole] = hose->mem_resources[memno-1];
+		hose->mem_resources[memno-1] = tmp;
+	}
+}
Index: linux-work/arch/powerpc/kernel/pci_32.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci_32.c	2007-11-13 14:16:17.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci_32.c	2007-11-13 14:16:24.000000000 +1100
@@ -842,120 +842,6 @@ pci_device_from_OF_node(struct device_no
 }
 EXPORT_SYMBOL(pci_device_from_OF_node);
 
-void __init
-pci_process_bridge_OF_ranges(struct pci_controller *hose,
-			   struct device_node *dev, int primary)
-{
-	static unsigned int static_lc_ranges[256] __initdata;
-	const unsigned int *dt_ranges;
-	unsigned int *lc_ranges, *ranges, *prev, size;
-	int rlen = 0, orig_rlen;
-	int memno = 0;
-	struct resource *res;
-	int np, na = of_n_addr_cells(dev);
-	np = na + 5;
-
-	/* First we try to merge ranges to fix a problem with some pmacs
-	 * that can have more than 3 ranges, fortunately using contiguous
-	 * addresses -- BenH
-	 */
-	dt_ranges = of_get_property(dev, "ranges", &rlen);
-	if (!dt_ranges)
-		return;
-	/* Sanity check, though hopefully that never happens */
-	if (rlen > sizeof(static_lc_ranges)) {
-		printk(KERN_WARNING "OF ranges property too large !\n");
-		rlen = sizeof(static_lc_ranges);
-	}
-	lc_ranges = static_lc_ranges;
-	memcpy(lc_ranges, dt_ranges, rlen);
-	orig_rlen = rlen;
-
-	/* Let's work on a copy of the "ranges" property instead of damaging
-	 * the device-tree image in memory
-	 */
-	ranges = lc_ranges;
-	prev = NULL;
-	while ((rlen -= np * sizeof(unsigned int)) >= 0) {
-		if (prev) {
-			if (prev[0] == ranges[0] && prev[1] == ranges[1] &&
-				(prev[2] + prev[na+4]) == ranges[2] &&
-				(prev[na+2] + prev[na+4]) == ranges[na+2]) {
-				prev[na+4] += ranges[na+4];
-				ranges[0] = 0;
-				ranges += np;
-				continue;
-			}
-		}
-		prev = ranges;
-		ranges += np;
-	}
-
-	/*
-	 * The ranges property is laid out as an array of elements,
-	 * each of which comprises:
-	 *   cells 0 - 2:	a PCI address
-	 *   cells 3 or 3+4:	a CPU physical address
-	 *			(size depending on dev->n_addr_cells)
-	 *   cells 4+5 or 5+6:	the size of the range
-	 */
-	ranges = lc_ranges;
-	rlen = orig_rlen;
-	while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) {
-		res = NULL;
-		size = ranges[na+4];
-		switch ((ranges[0] >> 24) & 0x3) {
-		case 1:		/* I/O space */
-			if (ranges[2] != 0)
-				break;
-			hose->io_base_phys = ranges[na+2];
-			/* limit I/O space to 16MB */
-			if (size > 0x01000000)
-				size = 0x01000000;
-			hose->io_base_virt = ioremap(ranges[na+2], size);
-			if (primary)
-				isa_io_base = (unsigned long) hose->io_base_virt;
-			res = &hose->io_resource;
-			res->flags = IORESOURCE_IO;
-			res->start = ranges[2];
-			DBG("PCI: IO 0x%llx -> 0x%llx\n",
-			    (u64)res->start, (u64)res->start + size - 1);
-			break;
-		case 2:		/* memory space */
-			memno = 0;
-			if (ranges[1] == 0 && ranges[2] == 0
-			    && ranges[na+4] <= (16 << 20)) {
-				/* 1st 16MB, i.e. ISA memory area */
-				if (primary)
-					isa_mem_base = ranges[na+2];
-				memno = 1;
-			}
-			while (memno < 3 && hose->mem_resources[memno].flags)
-				++memno;
-			if (memno == 0)
-				hose->pci_mem_offset = ranges[na+2] - ranges[2];
-			if (memno < 3) {
-				res = &hose->mem_resources[memno];
-				res->flags = IORESOURCE_MEM;
-				if(ranges[0] & 0x40000000)
-					res->flags |= IORESOURCE_PREFETCH;
-				res->start = ranges[na+2];
-				DBG("PCI: MEM[%d] 0x%llx -> 0x%llx\n", memno,
-				    (u64)res->start, (u64)res->start + size - 1);
-			}
-			break;
-		}
-		if (res != NULL) {
-			res->name = dev->full_name;
-			res->end = res->start + size - 1;
-			res->parent = NULL;
-			res->sibling = NULL;
-			res->child = NULL;
-		}
-		ranges += np;
-	}
-}
-
 /* We create the "pci-OF-bus-map" property now so it appears in the
  * /proc device tree
  */
Index: linux-work/arch/powerpc/kernel/pci_64.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci_64.c	2007-11-13 14:15:43.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci_64.c	2007-11-13 14:16:24.000000000 +1100
@@ -592,99 +592,6 @@ int pci_proc_domain(struct pci_bus *bus)
 	}
 }
 
-void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
-					    struct device_node *dev, int prim)
-{
-	const unsigned int *ranges;
-	unsigned int pci_space;
-	unsigned long size;
-	int rlen = 0;
-	int memno = 0;
-	struct resource *res;
-	int np, na = of_n_addr_cells(dev);
-	unsigned long pci_addr, cpu_phys_addr;
-
-	np = na + 5;
-
-	/* From "PCI Binding to 1275"
-	 * The ranges property is laid out as an array of elements,
-	 * each of which comprises:
-	 *   cells 0 - 2:	a PCI address
-	 *   cells 3 or 3+4:	a CPU physical address
-	 *			(size depending on dev->n_addr_cells)
-	 *   cells 4+5 or 5+6:	the size of the range
-	 */
-	ranges = of_get_property(dev, "ranges", &rlen);
-	if (ranges == NULL)
-		return;
-	hose->io_base_phys = 0;
-	while ((rlen -= np * sizeof(unsigned int)) >= 0) {
-		res = NULL;
-		pci_space = ranges[0];
-		pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2];
-		cpu_phys_addr = of_translate_address(dev, &ranges[3]);
-		size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4];
-		ranges += np;
-		if (size == 0)
-			continue;
-
-		/* Now consume following elements while they are contiguous */
-		while (rlen >= np * sizeof(unsigned int)) {
-			unsigned long addr, phys;
-
-			if (ranges[0] != pci_space)
-				break;
-			addr = ((unsigned long)ranges[1] << 32) | ranges[2];
-			phys = ranges[3];
-			if (na >= 2)
-				phys = (phys << 32) | ranges[4];
-			if (addr != pci_addr + size ||
-			    phys != cpu_phys_addr + size)
-				break;
-
-			size += ((unsigned long)ranges[na+3] << 32)
-				| ranges[na+4];
-			ranges += np;
-			rlen -= np * sizeof(unsigned int);
-		}
-
-		switch ((pci_space >> 24) & 0x3) {
-		case 1:		/* I/O space */
-			hose->io_base_phys = cpu_phys_addr - pci_addr;
-			/* handle from 0 to top of I/O window */
-			hose->pci_io_size = pci_addr + size;
-
-			res = &hose->io_resource;
-			res->flags = IORESOURCE_IO;
-			res->start = pci_addr;
-			DBG("phb%d: IO 0x%lx -> 0x%lx\n", hose->global_number,
-				    res->start, res->start + size - 1);
-			break;
-		case 2:		/* memory space */
-			memno = 0;
-			while (memno < 3 && hose->mem_resources[memno].flags)
-				++memno;
-
-			if (memno == 0)
-				hose->pci_mem_offset = cpu_phys_addr - pci_addr;
-			if (memno < 3) {
-				res = &hose->mem_resources[memno];
-				res->flags = IORESOURCE_MEM;
-				res->start = cpu_phys_addr;
-				DBG("phb%d: MEM 0x%lx -> 0x%lx\n", hose->global_number,
-					    res->start, res->start + size - 1);
-			}
-			break;
-		}
-		if (res != NULL) {
-			res->name = dev->full_name;
-			res->end = res->start + size - 1;
-			res->parent = NULL;
-			res->sibling = NULL;
-			res->child = NULL;
-		}
-	}
-}
 
 #ifdef CONFIG_HOTPLUG
 
Index: linux-work/include/asm-powerpc/pci-bridge.h
===================================================================
--- linux-work.orig/include/asm-powerpc/pci-bridge.h	2007-11-13 14:15:43.000000000 +1100
+++ linux-work/include/asm-powerpc/pci-bridge.h	2007-11-13 14:16:24.000000000 +1100
@@ -27,6 +27,7 @@ struct pci_controller {
 
 	void __iomem *io_base_virt;
 	resource_size_t io_base_phys;
+	resource_size_t pci_io_size;
 
 	/* Some machines (PReP) have a non 1:1 mapping of
 	 * the PCI memory space in the CPU bus space

^ permalink raw reply

* [PATCH 3/24] powerpc: Fix powerpc 32 bits resource fixup for 64 bits resources
From: Benjamin Herrenschmidt @ 2007-11-30  6:10 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <1196403038.569525.367459803520.qpush@grosgo>

The 32bits powerpc resource fixup code uses unsigned longs to do the
offseting of resources which overflows on platforms such as 4xx where
resources can be 64 bits.

This fixes it by using resource_size_t instead.

However, the IO stuff does rely on some 32 bits arithmetic, so we hack
by cropping the result of the fixups for IO resources with a 32 bits
mask.

This isn't the prettiest but should work for now until we change the
32 bits PCI code to do IO mappings like 64 bits does, within a reserved
are of the kernel address space.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

This needs some regression testing.

 arch/powerpc/kernel/pci_32.c |   44 +++++++++++++++++++++++--------------------
 1 file changed, 24 insertions(+), 20 deletions(-)

Index: linux-work/arch/powerpc/kernel/pci_32.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci_32.c	2007-11-16 15:48:27.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci_32.c	2007-11-16 15:55:54.000000000 +1100
@@ -104,7 +104,7 @@ pcibios_fixup_resources(struct pci_dev *
 {
 	struct pci_controller* hose = (struct pci_controller *)dev->sysdata;
 	int i;
-	unsigned long offset;
+	resource_size_t offset, mask;
 
 	if (!hose) {
 		printk(KERN_ERR "No hose for PCI dev %s!\n", pci_name(dev));
@@ -123,15 +123,17 @@ pcibios_fixup_resources(struct pci_dev *
 			continue;
 		}
 		offset = 0;
+		mask = (resource_size_t)-1;
 		if (res->flags & IORESOURCE_MEM) {
 			offset = hose->pci_mem_offset;
 		} else if (res->flags & IORESOURCE_IO) {
 			offset = (unsigned long) hose->io_base_virt
 				- isa_io_base;
+			mask = 0xffffffffu;
 		}
 		if (offset != 0) {
-			res->start += offset;
-			res->end += offset;
+			res->start = (res->start + offset) & mask;
+			res->end = (res->end + offset) & mask;
 			DBG("Fixup res %d (%lx) of dev %s: %llx -> %llx\n",
 			    i, res->flags, pci_name(dev),
 			    (u64)res->start - offset, (u64)res->start);
@@ -147,30 +149,32 @@ DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID,		PC
 void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
 			struct resource *res)
 {
-	unsigned long offset = 0;
+	resource_size_t offset = 0, mask = (resource_size_t)-1;
 	struct pci_controller *hose = dev->sysdata;
 
-	if (hose && res->flags & IORESOURCE_IO)
+	if (hose && res->flags & IORESOURCE_IO) {
 		offset = (unsigned long)hose->io_base_virt - isa_io_base;
-	else if (hose && res->flags & IORESOURCE_MEM)
+		mask = 0xffffffffu;
+	} else if (hose && res->flags & IORESOURCE_MEM)
 		offset = hose->pci_mem_offset;
-	region->start = res->start - offset;
-	region->end = res->end - offset;
+	region->start = (res->start - offset) & mask;
+	region->end = (res->end - offset) & mask;
 }
 EXPORT_SYMBOL(pcibios_resource_to_bus);
 
 void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
 			     struct pci_bus_region *region)
 {
-	unsigned long offset = 0;
+	resource_size_t offset = 0, mask = (resource_size_t)-1;
 	struct pci_controller *hose = dev->sysdata;
 
-	if (hose && res->flags & IORESOURCE_IO)
+	if (hose && res->flags & IORESOURCE_IO) {
 		offset = (unsigned long)hose->io_base_virt - isa_io_base;
-	else if (hose && res->flags & IORESOURCE_MEM)
+		mask = 0xffffffffu;
+	} else if (hose && res->flags & IORESOURCE_MEM)
 		offset = hose->pci_mem_offset;
-	res->start = region->start + offset;
-	res->end = region->end + offset;
+	res->start = (region->start + offset) & mask;
+	res->end = (region->end + offset) & mask;
 }
 EXPORT_SYMBOL(pcibios_bus_to_resource);
 
@@ -334,9 +338,9 @@ static int __init
 pci_relocate_bridge_resource(struct pci_bus *bus, int i)
 {
 	struct resource *res, *pr, *conflict;
-	unsigned long try, size;
-	int j;
+	resource_size_t try, size;
 	struct pci_bus *parent = bus->parent;
+	int j;
 
 	if (parent == NULL) {
 		/* shouldn't ever happen */
@@ -438,7 +442,7 @@ update_bridge_resource(struct pci_dev *d
 	u8 io_base_lo, io_limit_lo;
 	u16 mem_base, mem_limit;
 	u16 cmd;
-	unsigned long start, end, off;
+	resource_size_t start, end, off;
 	struct pci_controller *hose = dev->sysdata;
 
 	if (!hose) {
@@ -1157,8 +1161,8 @@ void pcibios_fixup_bus(struct pci_bus *b
 			res->end = IO_SPACE_LIMIT;
 			res->flags = IORESOURCE_IO;
 		}
-		res->start += io_offset;
-		res->end += io_offset;
+		res->start = (res->start + io_offset) & 0xffffffffu;
+		res->end = (res->end + io_offset) & 0xffffffffu;
 
 		for (i = 0; i < 3; ++i) {
 			res = &hose->mem_resources[i];
@@ -1183,8 +1187,8 @@ void pcibios_fixup_bus(struct pci_bus *b
 			if (!res->flags || bus->self->transparent)
 				continue;
 			if (io_offset && (res->flags & IORESOURCE_IO)) {
-				res->start += io_offset;
-				res->end += io_offset;
+				res->start = (res->start + io_offset) & 0xffffffffu;
+				res->end = (res->end + io_offset) & 0xffffffffu;
 			} else if (hose->pci_mem_offset
 				   && (res->flags & IORESOURCE_MEM)) {
 				res->start += hose->pci_mem_offset;

^ permalink raw reply

* [PATCH 4/24] powerpc: Fix 440/440A machine check handling
From: Benjamin Herrenschmidt @ 2007-11-30  6:10 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <1196403038.569525.367459803520.qpush@grosgo>

This removes CONFIG_440A which was a problem for multiplatform
kernels and instead fixes up the IVOR at runtime from a setup_cpu
function. The "A" version of the machine check also tweaks the
regs->trap value to differenciate the 2 versions at the C level.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

I know we should add a cputable hook for the processor machine check
handler and get rid of the ifdef's, I just didn't have time to do
it yet.

 arch/powerpc/kernel/cpu_setup_44x.S |    8 ++++
 arch/powerpc/kernel/cputable.c      |    5 +++
 arch/powerpc/kernel/head_44x.S      |   14 ++++++--
 arch/powerpc/kernel/head_booke.h    |    2 -
 arch/powerpc/kernel/traps.c         |   58 +++++++++++++++++++++++++++++-------
 arch/powerpc/platforms/44x/Kconfig  |    5 ---
 include/asm-powerpc/ptrace.h        |    3 +
 include/asm-powerpc/reg_booke.h     |    3 -
 8 files changed, 75 insertions(+), 23 deletions(-)

Index: linux-work/arch/powerpc/kernel/cpu_setup_44x.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/cpu_setup_44x.S	2007-11-26 09:38:47.000000000 +1100
+++ linux-work/arch/powerpc/kernel/cpu_setup_44x.S	2007-11-26 10:09:37.000000000 +1100
@@ -23,11 +23,19 @@ _GLOBAL(__setup_cpu_440epx)
 	mflr	r4
 	bl	__init_fpu_44x
 	bl	__plb_disable_wrp
+	bl	__fixup_440A_mcheck
 	mtlr	r4
 	blr
 _GLOBAL(__setup_cpu_440grx)
 	b	__plb_disable_wrp
+_GLOBAL(__setup_cpu_440gx)
+	b	__fixup_440A_mcheck
 
+ /* Temporary fixup for arch/ppc until we kill the whole thing */
+#ifndef CONFIG_PPC_MERGE
+_GLOBAL(__fixup_440A_mcheck)
+	blr
+#endif
 
 /* enable APU between CPU and FPU */
 _GLOBAL(__init_fpu_44x)
Index: linux-work/arch/powerpc/kernel/cputable.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/cputable.c	2007-11-26 09:38:47.000000000 +1100
+++ linux-work/arch/powerpc/kernel/cputable.c	2007-11-26 09:43:51.000000000 +1100
@@ -33,6 +33,7 @@ EXPORT_SYMBOL(cur_cpu_spec);
 #ifdef CONFIG_PPC32
 extern void __setup_cpu_440ep(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_440gx(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_440grx(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec);
@@ -1193,6 +1194,7 @@ static struct cpu_spec __initdata cpu_sp
 		.cpu_user_features	= COMMON_USER_BOOKE,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.cpu_setup		= __setup_cpu_440gx,
 		.platform		= "ppc440",
 	},
 	{ /* 440GX Rev. B */
@@ -1203,6 +1205,7 @@ static struct cpu_spec __initdata cpu_sp
 		.cpu_user_features	= COMMON_USER_BOOKE,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.cpu_setup		= __setup_cpu_440gx,
 		.platform		= "ppc440",
 	},
 	{ /* 440GX Rev. C */
@@ -1213,6 +1216,7 @@ static struct cpu_spec __initdata cpu_sp
 		.cpu_user_features	= COMMON_USER_BOOKE,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.cpu_setup		= __setup_cpu_440gx,
 		.platform		= "ppc440",
 	},
 	{ /* 440GX Rev. F */
@@ -1223,6 +1227,7 @@ static struct cpu_spec __initdata cpu_sp
 		.cpu_user_features	= COMMON_USER_BOOKE,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.cpu_setup		= __setup_cpu_440gx,
 		.platform		= "ppc440",
 	},
 	{ /* 440SP Rev. A */
Index: linux-work/arch/powerpc/kernel/head_44x.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/head_44x.S	2007-11-26 09:38:47.000000000 +1100
+++ linux-work/arch/powerpc/kernel/head_44x.S	2007-11-26 09:43:51.000000000 +1100
@@ -289,11 +289,8 @@ interrupt_base:
 	CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception)
 
 	/* Machine Check Interrupt */
-#ifdef CONFIG_440A
-	MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
-#else
 	CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
-#endif
+	MCHECK_EXCEPTION(0x0210, MachineCheckA, machine_check_exception)
 
 	/* Data Storage Interrupt */
 	START_EXCEPTION(DataStorage)
@@ -674,6 +671,15 @@ finish_tlb_load:
  */
 
 /*
+ * Adjust the machine check IVOR on 440A cores
+ */
+_GLOBAL(__fixup_440A_mcheck)
+	li	r3,MachineCheckA@l
+	mtspr	SPRN_IVOR1,r3
+	sync
+	blr
+
+/*
  * extern void giveup_altivec(struct task_struct *prev)
  *
  * The 44x core does not have an AltiVec unit.
Index: linux-work/arch/powerpc/kernel/traps.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/traps.c	2007-11-26 09:38:47.000000000 +1100
+++ linux-work/arch/powerpc/kernel/traps.c	2007-11-26 09:43:51.000000000 +1100
@@ -334,18 +334,25 @@ static inline int check_io_access(struct
 #define clear_single_step(regs)	((regs)->msr &= ~MSR_SE)
 #endif
 
-static int generic_machine_check_exception(struct pt_regs *regs)
+#if defined(CONFIG_4xx)
+static int decode_machine_check_4xx(struct pt_regs *regs)
 {
 	unsigned long reason = get_mc_reason(regs);
 
-#if defined(CONFIG_4xx) && !defined(CONFIG_440A)
 	if (reason & ESR_IMCP) {
 		printk("Instruction");
 		mtspr(SPRN_ESR, reason & ~ESR_IMCP);
 	} else
 		printk("Data");
 	printk(" machine check in kernel mode.\n");
-#elif defined(CONFIG_440A)
+
+	return 0;
+}
+
+static int decode_machine_check_4xxA(struct pt_regs *regs)
+{
+	unsigned long reason = get_mc_reason(regs);
+
 	printk("Machine check in kernel mode.\n");
 	if (reason & ESR_IMCP){
 		printk("Instruction Synchronous Machine Check exception\n");
@@ -375,7 +382,13 @@ static int generic_machine_check_excepti
 		/* Clear MCSR */
 		mtspr(SPRN_MCSR, mcsr);
 	}
-#elif defined (CONFIG_E500)
+	return 0;
+}
+#elif defined(CONFIG_E500)
+static int decode_machine_check_e500(struct pt_regs *regs)
+{
+	unsigned long reason = get_mc_reason(regs);
+
 	printk("Machine check in kernel mode.\n");
 	printk("Caused by (from MCSR=%lx): ", reason);
 
@@ -403,7 +416,14 @@ static int generic_machine_check_excepti
 		printk("Bus - Instruction Parity Error\n");
 	if (reason & MCSR_BUS_RPERR)
 		printk("Bus - Read Parity Error\n");
-#elif defined (CONFIG_E200)
+
+	return 0;
+}
+#elif defined(CONFIG_E200)
+static int decode_machine_check_e200(struct pt_regs *regs)
+{
+	unsigned long reason = get_mc_reason(regs);
+
 	printk("Machine check in kernel mode.\n");
 	printk("Caused by (from MCSR=%lx): ", reason);
 
@@ -421,7 +441,14 @@ static int generic_machine_check_excepti
 		printk("Bus - Read Bus Error on data load\n");
 	if (reason & MCSR_BUS_WRERR)
 		printk("Bus - Write Bus Error on buffered store or cache line push\n");
-#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */
+
+	return 0;
+}
+#else
+static int decode_machine_check_generic(struct pt_regs *regs)
+{
+	unsigned long reason = get_mc_reason(regs);
+
 	printk("Machine check in kernel mode.\n");
 	printk("Caused by (from SRR1=%lx): ", reason);
 	switch (reason & 0x601F0000) {
@@ -451,10 +478,9 @@ static int generic_machine_check_excepti
 	default:
 		printk("Unknown values in msr\n");
 	}
-#endif /* CONFIG_4xx */
-
 	return 0;
 }
+#endif /* everything else */
 
 void machine_check_exception(struct pt_regs *regs)
 {
@@ -463,8 +489,20 @@ void machine_check_exception(struct pt_r
 	/* See if any machine dependent calls */
 	if (ppc_md.machine_check_exception)
 		recover = ppc_md.machine_check_exception(regs);
-	else
-		recover = generic_machine_check_exception(regs);
+	else {
+#ifdef CONFIG_4xx
+		if (IS_MCHECK_EXC(regs))
+			recover = decode_machine_check_4xxA(regs);
+		else
+			recover = decode_machine_check_4xx(regs);
+#elif defined (CONFIG_E500)
+		recover = decode_machine_check_e500(regs);
+#elif defined (CONFIG_E200)
+		recover = decode_machine_check_e200(regs);
+#else
+		recover = decode_machine_check_generic(regs);
+#endif
+	}
 
 	if (recover)
 		return;
Index: linux-work/arch/powerpc/platforms/44x/Kconfig
===================================================================
--- linux-work.orig/arch/powerpc/platforms/44x/Kconfig	2007-11-26 09:38:47.000000000 +1100
+++ linux-work/arch/powerpc/platforms/44x/Kconfig	2007-11-26 10:08:44.000000000 +1100
@@ -62,11 +62,6 @@ config 440GX
 config 440SP
 	bool
 
-config 440A
-	bool
-	depends on 440GX || 440EPX
-	default y
-
 # 44x errata/workaround config symbols, selected by the CPU models above
 config IBM440EP_ERR42
 	bool
Index: linux-work/arch/powerpc/kernel/head_booke.h
===================================================================
--- linux-work.orig/arch/powerpc/kernel/head_booke.h	2007-11-26 09:38:47.000000000 +1100
+++ linux-work/arch/powerpc/kernel/head_booke.h	2007-11-26 09:43:51.000000000 +1100
@@ -166,7 +166,7 @@ label:
 	mfspr	r5,SPRN_ESR;					\
 	stw	r5,_ESR(r11);					\
 	addi	r3,r1,STACK_FRAME_OVERHEAD;			\
-	EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
+	EXC_XFER_TEMPLATE(hdlr, n+4, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
 			  NOCOPY, mcheck_transfer_to_handler,   \
 			  ret_from_mcheck_exc)
 
Index: linux-work/include/asm-powerpc/ptrace.h
===================================================================
--- linux-work.orig/include/asm-powerpc/ptrace.h	2007-11-26 09:38:47.000000000 +1100
+++ linux-work/include/asm-powerpc/ptrace.h	2007-11-26 09:43:51.000000000 +1100
@@ -106,7 +106,8 @@ extern int ptrace_put_reg(struct task_st
  */
 #define FULL_REGS(regs)		(((regs)->trap & 1) == 0)
 #ifndef __powerpc64__
-#define IS_CRITICAL_EXC(regs)	(((regs)->trap & 2) == 0)
+#define IS_CRITICAL_EXC(regs)	(((regs)->trap & 2) != 0)
+#define IS_MCHECK_EXC(regs)	(((regs)->trap & 4) != 0)
 #endif /* ! __powerpc64__ */
 #define TRAP(regs)		((regs)->trap & ~0xF)
 #ifdef __powerpc64__
Index: linux-work/include/asm-powerpc/reg_booke.h
===================================================================
--- linux-work.orig/include/asm-powerpc/reg_booke.h	2007-11-26 09:38:47.000000000 +1100
+++ linux-work/include/asm-powerpc/reg_booke.h	2007-11-26 09:43:51.000000000 +1100
@@ -207,7 +207,6 @@
 #define	CCR1_TCS	0x00000080 /* Timer Clock Select */
 
 /* Bit definitions for the MCSR. */
-#ifdef CONFIG_440A
 #define MCSR_MCS	0x80000000 /* Machine Check Summary */
 #define MCSR_IB		0x40000000 /* Instruction PLB Error */
 #define MCSR_DRB	0x20000000 /* Data Read PLB Error */
@@ -217,7 +216,7 @@
 #define MCSR_DCSP	0x02000000 /* D-Cache Search Parity Error */
 #define MCSR_DCFP	0x01000000 /* D-Cache Flush Parity Error */
 #define MCSR_IMPE	0x00800000 /* Imprecise Machine Check Exception */
-#endif
+
 #ifdef CONFIG_E500
 #define MCSR_MCP 	0x80000000UL /* Machine Check Input Pin */
 #define MCSR_ICPERR 	0x40000000UL /* I-Cache Parity Error */

^ permalink raw reply

* [PATCH 5/24] powerpc: Fix 440SPE machine check
From: Benjamin Herrenschmidt @ 2007-11-30  6:10 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <1196403038.569525.367459803520.qpush@grosgo>

The 440SPE has a 440A core, and thus needs a setup_cpu function to
fixup its machine check handler.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

 arch/powerpc/kernel/cpu_setup_44x.S |    1 +
 arch/powerpc/kernel/cputable.c      |    3 +++
 2 files changed, 4 insertions(+)

Index: linux-work/arch/powerpc/kernel/cpu_setup_44x.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/cpu_setup_44x.S	2007-11-27 16:13:04.000000000 +1100
+++ linux-work/arch/powerpc/kernel/cpu_setup_44x.S	2007-11-27 16:13:09.000000000 +1100
@@ -29,6 +29,7 @@ _GLOBAL(__setup_cpu_440epx)
 _GLOBAL(__setup_cpu_440grx)
 	b	__plb_disable_wrp
 _GLOBAL(__setup_cpu_440gx)
+_GLOBAL(__setup_cpu_440spe)
 	b	__fixup_440A_mcheck
 
  /* Temporary fixup for arch/ppc until we kill the whole thing */
Index: linux-work/arch/powerpc/kernel/cputable.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/cputable.c	2007-11-27 16:11:27.000000000 +1100
+++ linux-work/arch/powerpc/kernel/cputable.c	2007-11-27 16:13:51.000000000 +1100
@@ -35,6 +35,7 @@ extern void __setup_cpu_440ep(unsigned l
 extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_440gx(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_440grx(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_440spe(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec);
@@ -1248,6 +1249,7 @@ static struct cpu_spec __initdata cpu_sp
 		.cpu_user_features      = COMMON_USER_BOOKE,
 		.icache_bsize           = 32,
 		.dcache_bsize           = 32,
+		.cpu_setup		= __setup_cpu_440spe,
 		.platform               = "ppc440",
 	},
 	{ /* 440SPe Rev. B */
@@ -1258,6 +1260,7 @@ static struct cpu_spec __initdata cpu_sp
 		.cpu_user_features	= COMMON_USER_BOOKE,
 		.icache_bsize		= 32,
 		.dcache_bsize		= 32,
+		.cpu_setup		= __setup_cpu_440spe,
 		.platform		= "ppc440",
 	},
 #endif /* CONFIG_44x */

^ permalink raw reply

* [PATCH 6/24] powerpc: Add xmon function to dump 44x TLB
From: Benjamin Herrenschmidt @ 2007-11-30  6:10 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <1196403038.569525.367459803520.qpush@grosgo>

This adds a function to xmon to dump the content of the 44x processor
TLB with a little bit of decoding (but not much).

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

Did that to track down some machine checks I was having while working
on PCI support due to 32/64 bits resource screwage.
Useful to see where a given MMIO virtual address really maps to.

 arch/powerpc/xmon/xmon.c |   38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

Index: linux-work/arch/powerpc/xmon/xmon.c
===================================================================
--- linux-work.orig/arch/powerpc/xmon/xmon.c	2007-11-20 15:02:43.000000000 +1100
+++ linux-work/arch/powerpc/xmon/xmon.c	2007-11-20 17:04:48.000000000 +1100
@@ -153,6 +153,10 @@ static const char *getvecname(unsigned l
 
 static int do_spu_cmd(void);
 
+#ifdef CONFIG_44x
+static void dump_tlb_44x(void);
+#endif
+
 int xmon_no_auto_backtrace;
 
 extern void xmon_enter(void);
@@ -231,6 +235,9 @@ Commands:\n\
 #ifdef CONFIG_PPC_STD_MMU_32
 "  u	dump segment registers\n"
 #endif
+#ifdef CONFIG_44x
+"  u	dump TLB\n"
+#endif
 "  ?	help\n"
 "  zr	reboot\n\
   zh	halt\n"
@@ -856,6 +863,11 @@ cmds(struct pt_regs *excp)
 			dump_segments();
 			break;
 #endif
+#ifdef CONFIG_44x
+		case 'u':
+			dump_tlb_44x();
+			break;
+#endif
 		default:
 			printf("Unrecognized command: ");
 		        do {
@@ -2581,6 +2593,32 @@ void dump_segments(void)
 }
 #endif
 
+#ifdef CONFIG_44x
+static void dump_tlb_44x(void)
+{
+	int i;
+
+	for (i = 0; i < PPC44x_TLB_SIZE; i++) {
+		unsigned long w0,w1,w2;
+		asm volatile("tlbre  %0,%1,0" : "=r" (w0) : "r" (i));
+		asm volatile("tlbre  %0,%1,1" : "=r" (w1) : "r" (i));
+		asm volatile("tlbre  %0,%1,2" : "=r" (w2) : "r" (i));
+		printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
+		if (w0 & PPC44x_TLB_VALID) {
+			printf("V %08x -> %01x%08x %c%c%c%c%c",
+			       w0 & PPC44x_TLB_EPN_MASK,
+			       w1 & PPC44x_TLB_ERPN_MASK,
+			       w1 & PPC44x_TLB_RPN_MASK,
+			       (w2 & PPC44x_TLB_W) ? 'W' : 'w',
+			       (w2 & PPC44x_TLB_I) ? 'I' : 'i',
+			       (w2 & PPC44x_TLB_M) ? 'M' : 'm',
+			       (w2 & PPC44x_TLB_G) ? 'G' : 'g',
+			       (w2 & PPC44x_TLB_E) ? 'E' : 'e');
+		}
+		printf("\n");
+	}
+}
+#endif /* CONFIG_44x */
 void xmon_init(int enable)
 {
 #ifdef CONFIG_PPC_ISERIES

^ permalink raw reply

* [PATCH 7/24] powerpc: Change 32 bits PCI message about resource allocation
From: Benjamin Herrenschmidt @ 2007-11-30  6:10 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <1196403038.569525.367459803520.qpush@grosgo>

The 32 bits PCI code will display a rather scary error message

   PCI: Cannot allocate resource region N of device XXX

at boot when the existing setup of a device as left by the
firmware doesn't match the kernel needs and the device needs
to be moved. This is often not an error at all, as the kernel
will generally easily reallocate the device elsewhere.

This changes the message to something less scary and lowers
its level from error to warning.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

 arch/powerpc/kernel/pci_32.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux-work/arch/powerpc/kernel/pci_32.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci_32.c	2007-11-20 17:04:07.000000000 +1100
+++ linux-work/arch/powerpc/kernel/pci_32.c	2007-11-21 16:53:53.000000000 +1100
@@ -508,7 +508,7 @@ static inline void alloc_resource(struct
 	    pci_name(dev), idx, (u64)r->start, (u64)r->end, r->flags);
 	pr = pci_find_parent_resource(dev, r);
 	if (!pr || request_resource(pr, r) < 0) {
-		printk(KERN_ERR "PCI: Cannot allocate resource region %d"
+		printk(KERN_WARNING "PCI: Remapping resource region %d"
 		       " of device %s\n", idx, pci_name(dev));
 		if (pr)
 			DBG("PCI:  parent is %p: %016llx-%016llx (f=%lx)\n",

^ permalink raw reply

* [PATCH 8/24] powerpc: Add of_translate_dma_address
From: Benjamin Herrenschmidt @ 2007-11-30  6:10 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <1196403038.569525.367459803520.qpush@grosgo>

This adds a variant of of_translate_address that uses the dma-ranges
property instead of "ranges", it's to be used by PCI code in parsing
the dma-ranges property.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

 arch/powerpc/kernel/prom_parse.c |   20 ++++++++++++++++----
 include/asm-powerpc/prom.h       |    4 ++++
 2 files changed, 20 insertions(+), 4 deletions(-)

Index: linux-work/arch/powerpc/kernel/prom_parse.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/prom_parse.c	2007-11-22 13:18:32.000000000 +1100
+++ linux-work/arch/powerpc/kernel/prom_parse.c	2007-11-22 13:50:45.000000000 +1100
@@ -419,7 +419,7 @@ static struct of_bus *of_match_bus(struc
 
 static int of_translate_one(struct device_node *parent, struct of_bus *bus,
 			    struct of_bus *pbus, u32 *addr,
-			    int na, int ns, int pna)
+			    int na, int ns, int pna, const char *rprop)
 {
 	const u32 *ranges;
 	unsigned int rlen;
@@ -438,7 +438,7 @@ static int of_translate_one(struct devic
 	 * to translate addresses that aren't supposed to be translated in
 	 * the first place. --BenH.
 	 */
-	ranges = of_get_property(parent, "ranges", &rlen);
+	ranges = of_get_property(parent, rprop, &rlen);
 	if (ranges == NULL || rlen == 0) {
 		offset = of_read_number(addr, na);
 		memset(addr, 0, pna * 4);
@@ -481,7 +481,8 @@ static int of_translate_one(struct devic
  * that can be mapped to a cpu physical address). This is not really specified
  * that way, but this is traditionally the way IBM at least do things
  */
-u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
+u64 __of_translate_address(struct device_node *dev, const u32 *in_addr,
+			   const char *rprop)
 {
 	struct device_node *parent = NULL;
 	struct of_bus *bus, *pbus;
@@ -540,7 +541,7 @@ u64 of_translate_address(struct device_n
 		    pbus->name, pna, pns, parent->full_name);
 
 		/* Apply bus translation */
-		if (of_translate_one(dev, bus, pbus, addr, na, ns, pna))
+		if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop))
 			break;
 
 		/* Complete the move up one level */
@@ -556,8 +557,19 @@ u64 of_translate_address(struct device_n
 
 	return result;
 }
+
+u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
+{
+	return __of_translate_address(dev, in_addr, "ranges");
+}
 EXPORT_SYMBOL(of_translate_address);
 
+u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr)
+{
+	return __of_translate_address(dev, in_addr, "dma-ranges");
+}
+EXPORT_SYMBOL(of_translate_dma_address);
+
 const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
 		    unsigned int *flags)
 {
Index: linux-work/include/asm-powerpc/prom.h
===================================================================
--- linux-work.orig/include/asm-powerpc/prom.h	2007-11-22 13:48:21.000000000 +1100
+++ linux-work/include/asm-powerpc/prom.h	2007-11-22 13:48:57.000000000 +1100
@@ -202,6 +202,10 @@ static inline unsigned long of_read_ulon
  */
 extern u64 of_translate_address(struct device_node *np, const u32 *addr);
 
+/* Translate a DMA address from device space to CPU space */
+extern u64 of_translate_dma_address(struct device_node *dev,
+				    const u32 *in_addr);
+
 /* Extract an address from a device, returns the region size and
  * the address space flags too. The PCI version uses a BAR number
  * instead of an absolute index

^ permalink raw reply

* [PATCH 9/24] powerpc: Improve support for 4xx indirect DCRs
From: Benjamin Herrenschmidt @ 2007-11-30  6:10 UTC (permalink / raw)
  To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <1196403038.569525.367459803520.qpush@grosgo>

Accessing indirect DCRs is done via a pair of address/data DCRs.

Such accesses are thus inherently racy, vs. interrupts, preemption
and possibly SMP if 4xx SMP cores are ever used.

This updates the mfdcri/mtdcri macros in dcr-native.h (which were
so far unused) to use a spinlock.

In addition, add some common definitions to a new dcr-regs.h file.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---


 arch/powerpc/sysdev/dcr.c        |    1 
 include/asm-powerpc/dcr-native.h |   30 +++++++++++-----
 include/asm-powerpc/dcr-regs.h   |   72 +++++++++++++++++++++++++++++++++++++++
 include/asm-powerpc/dcr.h        |    1 
 4 files changed, 96 insertions(+), 8 deletions(-)

Index: linux-work/arch/powerpc/sysdev/dcr.c
===================================================================
--- linux-work.orig/arch/powerpc/sysdev/dcr.c	2007-11-28 13:34:45.000000000 +1100
+++ linux-work/arch/powerpc/sysdev/dcr.c	2007-11-28 13:34:48.000000000 +1100
@@ -139,3 +139,4 @@ void dcr_unmap(dcr_host_t host, unsigned
 EXPORT_SYMBOL_GPL(dcr_unmap);
 
 #endif /* !defined(CONFIG_PPC_DCR_NATIVE) */
+
Index: linux-work/include/asm-powerpc/dcr-native.h
===================================================================
--- linux-work.orig/include/asm-powerpc/dcr-native.h	2007-11-28 13:33:51.000000000 +1100
+++ linux-work/include/asm-powerpc/dcr-native.h	2007-11-28 15:22:22.000000000 +1100
@@ -22,6 +22,8 @@
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
 
+#include <linux/spinlock.h>
+
 typedef struct {
 	unsigned int base;
 } dcr_host_t;
@@ -55,18 +57,30 @@ do {								\
 } while (0)
 
 /* R/W of indirect DCRs make use of standard naming conventions for DCRs */
-#define mfdcri(base, reg)			\
-({						\
-	mtdcr(base ## _CFGADDR, base ## _ ## reg);	\
-	mfdcr(base ## _CFGDATA);			\
+extern spinlock_t dcr_ind_lock;
+
+#define mfdcri(base, reg)				\
+({							\
+	unsigned long flags; 				\
+	unsigned int val;				\
+	spin_lock_irqsave(&dcr_ind_lock, flags);	\
+	mtdcr(DCRN_ ## base ## _CONFIG_ADDR, reg);	\
+	val = mfdcr(DCRN_ ## base ## _CONFIG_DATA);	\
+	spin_unlock_irqrestore(&dcr_ind_lock, flags);	\
+	val;						\
 })
 
-#define mtdcri(base, reg, data)			\
-do {						\
-	mtdcr(base ## _CFGADDR, base ## _ ## reg);	\
-	mtdcr(base ## _CFGDATA, data);		\
+#define mtdcri(base, reg, data)				\
+do {							\
+	unsigned long flags; 				\
+	spin_lock_irqsave(&dcr_ind_lock, flags);	\
+	mtdcr(DCRN_ ## base ## _CONFIG_ADDR, reg);	\
+	mtdcr(DCRN_ ## base ## _CONFIG_DATA, data);	\
+	spin_unlock_irqrestore(&dcr_ind_lock, flags);	\
 } while (0)
 
+
+
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_DCR_NATIVE_H */
Index: linux-work/include/asm-powerpc/dcr.h
===================================================================
--- linux-work.orig/include/asm-powerpc/dcr.h	2007-11-28 13:40:13.000000000 +1100
+++ linux-work/include/asm-powerpc/dcr.h	2007-11-28 13:49:37.000000000 +1100
@@ -40,6 +40,7 @@ extern unsigned int dcr_resource_len(str
 				     unsigned int index);
 #endif /* CONFIG_PPC_MERGE */
 
+
 #endif /* CONFIG_PPC_DCR */
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_DCR_H */
Index: linux-work/include/asm-powerpc/dcr-regs.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-work/include/asm-powerpc/dcr-regs.h	2007-11-28 14:43:25.000000000 +1100
@@ -0,0 +1,72 @@
+/*
+ * Common DCR / SDR / CPR register definitions used on various IBM/AMCC
+ * 4xx processors
+ *
+ *    Copyright 2007 Benjamin Herrenschmidt, IBM Corp
+ *                   <benh@kernel.crashing.org>
+ *
+ * Mostly lifted from asm-ppc/ibm4xx.h by
+ *
+ *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ */
+
+#ifndef __DCR_REGS_H__
+#define __DCR_REGS_H__
+
+/*
+ * Most DCRs used for controlling devices such as the MAL, DMA engine,
+ * etc... are obtained for the device tree.
+ *
+ * The definitions in this files are fixed DCRs and indirect DCRs that
+ * are commonly used outside of specific drivers or refer to core
+ * common registers that may occasionally have to be tweaked outside
+ * of the driver main register set
+ */
+
+/* CPRs (440GX and 440SP/440SPe) */
+#define DCRN_CPR0_CONFIG_ADDR	0xc
+#define DCRN_CPR0_CONFIG_DATA	0xd
+
+/* SDRs (440GX and 440SP/440SPe) */
+#define DCRN_SDR0_CONFIG_ADDR 	0xe
+#define DCRN_SDR0_CONFIG_DATA	0xf
+
+#define SDR0_PFC0		0x4100
+#define SDR0_PFC1		0x4101
+#define SDR0_PFC1_EPS		0x1c00000
+#define SDR0_PFC1_EPS_SHIFT	22
+#define SDR0_PFC1_RMII		0x02000000
+#define SDR0_MFR		0x4300
+#define SDR0_MFR_TAH0 		0x80000000  	/* TAHOE0 Enable */
+#define SDR0_MFR_TAH1 		0x40000000  	/* TAHOE1 Enable */
+#define SDR0_MFR_PCM  		0x10000000  	/* PPC440GP irq compat mode */
+#define SDR0_MFR_ECS  		0x08000000  	/* EMAC int clk */
+#define SDR0_MFR_T0TXFL		0x00080000
+#define SDR0_MFR_T0TXFH		0x00040000
+#define SDR0_MFR_T1TXFL		0x00020000
+#define SDR0_MFR_T1TXFH		0x00010000
+#define SDR0_MFR_E0TXFL		0x00008000
+#define SDR0_MFR_E0TXFH		0x00004000
+#define SDR0_MFR_E0RXFL		0x00002000
+#define SDR0_MFR_E0RXFH		0x00001000
+#define SDR0_MFR_E1TXFL		0x00000800
+#define SDR0_MFR_E1TXFH		0x00000400
+#define SDR0_MFR_E1RXFL		0x00000200
+#define SDR0_MFR_E1RXFH		0x00000100
+#define SDR0_MFR_E2TXFL		0x00000080
+#define SDR0_MFR_E2TXFH		0x00000040
+#define SDR0_MFR_E2RXFL		0x00000020
+#define SDR0_MFR_E2RXFH		0x00000010
+#define SDR0_MFR_E3TXFL		0x00000008
+#define SDR0_MFR_E3TXFH		0x00000004
+#define SDR0_MFR_E3RXFL		0x00000002
+#define SDR0_MFR_E3RXFH		0x00000001
+#define SDR0_UART0		0x0120
+#define SDR0_UART1		0x0121
+#define SDR0_UART2		0x0122
+#define SDR0_UART3		0x0123
+#define SDR0_CUST0		0x4000
+
+
+#endif /* __DCR_REGS_H__ */

^ 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