LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* RE: PTE entries
From: Benjamin Herrenschmidt @ 2007-05-02 22:12 UTC (permalink / raw)
  To: Siva Prasad; +Cc: linuxppc-dev, linuxppc-embedded
In-Reply-To: <D83235F0F3C86D4D889D8B9A0DA8C6D762D0F8@corpexc01.corp.networkrobots.com>

On Wed, 2007-05-02 at 12:58 -0700, Siva Prasad wrote:
> Hi Ben,
> 
> First, 
> Are there any other places where we have self modifying code in Linux
> kernel, other than in arch/powerpc/mm/ppc_mmu_32.c:MMU_init_hw()
> (basically modified create_hpte and flush_hash_page)

There is the cpu feature fixup code, there might also be something
around the SMP code.

> Second,
> Instead of using addis, why can't we move it from SDR1 register and mask
> the second half. SDR1 has the required value. Right?
> May be I am missing something here.

Would be slower. Accessing SPRs is slow.

^ permalink raw reply

* RE: How do external irq's get mapped?
From: Charles Krinke @ 2007-05-02 22:11 UTC (permalink / raw)
  To: Andy Fleming; +Cc: Randy Brown, Chris Carlson, Kevin Smith, linuxppc-embedded
In-Reply-To: <762644B1-26D0-4D16-BA36-55364CACB0D4@freescale.com>

> The new problem is that if I set the irq to 112, when it is =20
> insmodded, I
> get an error from open_pic.c of the form:
>
> Open_pic.c:720 invalid irq 112
>
> This seems to be coming from the macro at line 144 in open_pic.c
>
> #define check_arg_irq(irq) \
>     if (irq < open_pic_irq_offset || irq >=3D
> NumSources+open_pic_irq_offset \
> 	|| ISR[irq - open_pic_irq_offset] =3D=3D 0) { \
>       printk("open_pic.c:%d: invalid irq %d\n", __LINE__, irq); \
>       dump_stack(); }


Any  chance you can identify:

1) Where this macro is being called from when it fails

2) Which of the 3 conditions above are actually true

Andy

Dear Andy:

In our system, open_pic_irq_offset=3D80, numSources=3D60, *but* ISR[irq =
-
open_pic_irq_offset]=3DNULL when irq 112 is enabled.

It looks to me like each call to openpic_set_sources inits ISR[]
elements according to the first two arguments. We have two calls to
openpic_set_sources.=20

Internal irqs 00..31, 1st openpic_set_sources(0, 32) -- ISR[0..32]
External irqs 48..60, 2nd openpic_set_sources(48, 12) -- ISR[48..60]=20

But ISR[112] is never initialized in the source base.

I tried the cheap shot of adding a third openpic_set_sources(112, 12),
but I suspect the real answer is a bit more complicated then that.

Again, I thank you for your kind words while I struggle through this
external interrupt initalization for the PPC8541 in the Linux-2.6.17.11
kernel.

Charles Krinke

^ permalink raw reply

* Re: [PATCH] powermac: support G5 CPU hotplug
From: Benjamin Herrenschmidt @ 2007-05-02 22:03 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <1178116438.13233.65.camel@johannes.berg>

On Wed, 2007-05-02 at 16:33 +0200, Johannes Berg wrote:
> On Wed, 2007-05-02 at 20:55 +1000, Paul Mackerras wrote:
> 
> > Ultimately we want to put the disabled cpus in sleep mode, but that
> > will require a suitable cache flush routine.
> 
> I don't have any docs for the particular processors the G5s have, do
> they have a sleep mode?

They have, but the cache flush is not trivial to do (and might imply
access to non documented bits). So let's put that on the to-do list and
stick to NAP for now while I dig something.

Ben.

^ permalink raw reply

* RE: PTE entries
From: Paul Mackerras @ 2007-05-02 22:03 UTC (permalink / raw)
  To: Siva Prasad; +Cc: linuxppc-embedded, linuxppc-dev
In-Reply-To: <D83235F0F3C86D4D889D8B9A0DA8C6D762D0F8@corpexc01.corp.networkrobots.com>

Siva Prasad writes:

> Are there any other places where we have self modifying code in Linux
> kernel, other than in arch/powerpc/mm/ppc_mmu_32.c:MMU_init_hw()
> (basically modified create_hpte and flush_hash_page)

Yes, the cpu feature stuff writes nops over various bits of code
depending on what cpu you're running on.  See do_feature_fixups() in
arch/powerpc/kernel/cputable.c.

> Instead of using addis, why can't we move it from SDR1 register and mask
> the second half. SDR1 has the required value. Right?
> May be I am missing something here.

mtspr is slow on most processors, certainly slower than addis.

Paul.

^ permalink raw reply

* [PATCH] powerpc: check cache coherency of kernel vs firmware
From: Dale Farnsworth @ 2007-05-02 21:59 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: Linuxppc-dev

This function verifies that the cache coherency setting of the kernel
(CONFIG_NOT_COHERENT_CACHE) matches that left by the firmware, as
indicated by coherency-off device tree property.

It's only needed on platforms where cache-coherency can be enabled or
disabled by firmware, e.g. mv64x60-based platforms.

Signed-of-by: Dale Farnsworth <dale@farnsworth.org>

---
 arch/powerpc/Kconfig                       |    3 +
 arch/powerpc/kernel/setup-common.c         |   41 +++++++++++++++++++
 arch/powerpc/platforms/embedded6xx/Kconfig |    1 
 3 files changed, 45 insertions(+)

Index: linux-2.6-powerpc-df/arch/powerpc/kernel/setup-common.c
===================================================================
--- linux-2.6-powerpc-df.orig/arch/powerpc/kernel/setup-common.c
+++ linux-2.6-powerpc-df/arch/powerpc/kernel/setup-common.c
@@ -530,3 +530,44 @@ void __init setup_panic(void)
 {
 	atomic_notifier_chain_register(&panic_notifier_list, &ppc_panic_block);
 }
+
+#ifdef CONFIG_CHECK_CACHE_COHERENCY
+/*
+ * For platforms that have configurable cache-coherency.  This function
+ * checks that the cache coherency setting of the kernel matches the setting
+ * left by the firmware, as indicated in the device tree.  Since a mismatch
+ * will eventually result in DMA failures, we print * and error and call
+ * BUG() in that case.
+ */
+
+#ifdef CONFIG_NOT_COHERENT_CACHE
+#define KERNEL_COHERENCY	0
+#else
+#define KERNEL_COHERENCY	1
+#endif
+
+static int __init check_cache_coherency(void)
+{
+	struct device_node *np;
+	const void *prop;
+	int devtree_coherency;
+
+	np = of_find_node_by_path("/");
+	prop = of_get_property(np, "coherency-off", NULL);
+	of_node_put(np);
+
+	devtree_coherency = prop ? 0 : 1;
+
+	if (devtree_coherency != KERNEL_COHERENCY) {
+		printk(KERN_ERR
+			"kernel coherency:%s != device tree_coherency:%s\n",
+			KERNEL_COHERENCY ? "on" : "off",
+			devtree_coherency ? "on" : "off");
+		BUG();
+	}
+
+	return 0;
+}
+
+late_initcall(check_cache_coherency);
+#endif /* CONFIG_CHECK_CACHE_COHERENCY */
Index: linux-2.6-powerpc-df/arch/powerpc/Kconfig
===================================================================
--- linux-2.6-powerpc-df.orig/arch/powerpc/Kconfig
+++ linux-2.6-powerpc-df/arch/powerpc/Kconfig
@@ -373,6 +373,9 @@ config NOT_COHERENT_CACHE
 	bool
 	depends on 4xx || 8xx || E200
 	default y
+
+config CHECK_COHERENT_CACHE
+	bool
 endmenu
 
 source "init/Kconfig"
Index: linux-2.6-powerpc-df/arch/powerpc/platforms/embedded6xx/Kconfig
===================================================================
--- linux-2.6-powerpc-df.orig/arch/powerpc/platforms/embedded6xx/Kconfig
+++ linux-2.6-powerpc-df/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -41,6 +41,7 @@ config MPC10X_BRIDGE
 config MV64X60
 	bool
 	select PPC_INDIRECT_PCI
+	select CHECK_COHERENT_CACHE
 
 config MPC10X_OPENPIC
 	bool

^ permalink raw reply

* Re: Using Cypress EZ-Host on ML403/5
From: Peter Korsgaard @ 2007-05-02 21:39 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-embedded
In-Reply-To: <528646bc0705021408o1e1f25d7pa81905081d06ed8e@mail.gmail.com>

>>>>> "Grant" == Grant Likely <grant.likely@secretlab.ca> writes:

Hi,

 >> > Did you have a chance to try it out yet?

 Grant> Hey Peter,

 Grant> I've got it running on my board now after figuring out how to wire up
 Grant> external interrupts in EDK.  :-)

 Grant> Good success with keyboards and mice.  Events come through no problem.

Great!

 Grant> Some block devices seem to be giving me grief.  I have no problem with
 Grant> my SanDisk ImageMate CF reader.  However, I've got a SanDisk Curzer
 Grant> Micro that gets reset during transfers.  Is this something you've seen
 Grant> before?  Log output is below.

Yeah, I've also had quite varied success with USB sticks - Some work
just fine, others not at all. I'm still trying to figure out what goes
wrong..

 Grant> I've also got a QuickCam Messinger that I'm going to test isochronos
 Grant> transfers with as well.

Ok. I've had a webcam and USB audio devices working OK. Isochronos
transfers are the most tricky ones to implement though, so don't
expect wonders (E.G. I get audio stutter if I do a lot of bulk
tranfers at the same time).

Thanks for the feedback!

-- 
Bye, Peter Korsgaard

^ permalink raw reply

* [PATCH] 86xx: Enable the AC97 interface on 8641D board.
From: Jon Loeliger @ 2007-05-02 21:53 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org

From: Jason Jin <jason.jin@freescale.com>

HD interface and AC97 interface share some pins and they are enabled at
the same time, In order to use AC97 interface, we need to disable the HD
interface first.

Signed-off-by:Jason Jin<jason.jin@freescale.com>
Acked-by: Jon Loeliger <jdl@freescale.com>
---
 arch/powerpc/platforms/86xx/mpc86xx_hpcn.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index 3d3d98f..13a14dd 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -168,7 +168,7 @@ static void __devinit quirk_uli1575(struct pci_dev *dev)
 {
 	unsigned short temp;
 	struct pci_controller *hose = pci_bus_to_host(dev->bus);
-	unsigned char irq2pin[16];
+	unsigned char irq2pin[16], c;
 	unsigned long pirq_map_word = 0;
 	u32 irq;
 	int i;
@@ -288,6 +288,11 @@ static void __devinit quirk_uli1575(struct pci_dev *dev)
 	outb(0x1e, 0x4d1);
 
 #undef ULI1575_SET_DEV_IRQ
+
+	/* Disable the HD interface and enable the AC97 interface. */
+	pci_read_config_byte(dev, 0xb8, &c);
+	c &= 0x7f;
+	pci_write_config_byte(dev, 0xb8, c);
 }
 
 static void __devinit quirk_uli5288(struct pci_dev *dev)
-- 
1.5.0.3

^ permalink raw reply related

* Re: Using Cypress EZ-Host on ML403/5
From: Grant Likely @ 2007-05-02 21:48 UTC (permalink / raw)
  To: Peter Korsgaard; +Cc: linuxppc-embedded
In-Reply-To: <87wszqucpr.fsf@p4.be.48ers.dk>

On 5/2/07, Peter Korsgaard <jacmet@sunsite.dk> wrote:
> Thanks for the feedback!

No problem.  I'll keep hacking on it here and keep you up-to-date on
my progress.

Cheers,
g.

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

^ permalink raw reply

* [PATCH 10/13] powerpc: Add arch/powerpc mv64x60 PCI setup
From: Dale Farnsworth @ 2007-05-02 21:46 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <20070426000107.GL4046@mag.az.mvista.com>


Signed-off-by: Dale Farnsworth <dale@farnsworth.org>

---
I took Arnd Bergmann's advice and put the mv64x60 PCI setup code
in its own file.

 arch/powerpc/platforms/embedded6xx/Kconfig |    1 
 arch/powerpc/sysdev/Makefile               |    4 
 arch/powerpc/sysdev/mv64x60.h              |    2 
 arch/powerpc/sysdev/mv64x60_pci.c          |  190 +++++++++++++++++++
 4 files changed, 197 insertions(+)

Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/Makefile
===================================================================
--- linux-2.6-powerpc-df.orig/arch/powerpc/sysdev/Makefile
+++ linux-2.6-powerpc-df/arch/powerpc/sysdev/Makefile
@@ -16,6 +16,10 @@ obj-$(CONFIG_TSI108_BRIDGE)	+= tsi108_pc
 obj-$(CONFIG_QUICC_ENGINE)	+= qe_lib/
 obj-$(CONFIG_MV64X60)		+= mv64x60_pic.o mv64x60_dev.o
 
+ifeq ($(CONFIG_PCI),y)
+obj-$(CONFIG_MV64X60)		+= mv64x60_pci.o
+endif
+
 # contains only the suspend handler for time
 obj-$(CONFIG_PM)		+= timer.o
 
Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.h
===================================================================
--- linux-2.6-powerpc-df.orig/arch/powerpc/sysdev/mv64x60.h
+++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.h
@@ -16,4 +16,6 @@ extern int __init mv64x60_device_probe(s
 extern void __init mv64x60_init_irq(void);
 extern unsigned int mv64x60_get_irq(void);
 
+extern void __init mv64x60_pci_init(void);
+
 #endif /* __MV64X60_H__ */
Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60_pci.c
===================================================================
--- /dev/null
+++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60_pci.c
@@ -0,0 +1,190 @@
+/*
+ * PCI bus setup for Marvell mv64360/mv64460 host bridges (Discovery)
+ *
+ * Author: Dale Farnsworth <dale@farnsworth.org>
+ *
+ * 2007 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+
+static int mv64x60_pci_exclude_bridge = 1;
+static struct pci_controller *mv64x60_primary_hose;
+static int mv64x60_pci2_busno;
+
+#ifdef CONFIG_SYSFS
+/* 32-bit hex or dec stringified number + '\n' */
+#define MV64X60_VAL_LEN_MAX		11
+#define MV64X60_PCICFG_CPCI_HOTSWAP	0x68
+
+DECLARE_MUTEX(mv64x60_hs_lock);
+
+static ssize_t mv64x60_hs_reg_read(struct kobject *kobj, char *buf, loff_t off,
+				   size_t count)
+{
+	u32 v;
+	int save_exclude;
+
+	if (off > 0)
+		return 0;
+	if (count < MV64X60_VAL_LEN_MAX)
+		return -EINVAL;
+
+	if (down_interruptible(&mv64x60_hs_lock))
+		return -ERESTARTSYS;
+	save_exclude = mv64x60_pci_exclude_bridge;
+	mv64x60_pci_exclude_bridge = 0;
+	early_read_config_dword(mv64x60_primary_hose, 0, PCI_DEVFN(0, 0),
+				MV64X60_PCICFG_CPCI_HOTSWAP, &v);
+	mv64x60_pci_exclude_bridge = save_exclude;
+	up(&mv64x60_hs_lock);
+
+	return sprintf(buf, "0x%08x\n", v);
+}
+
+static ssize_t mv64x60_hs_reg_write(struct kobject *kobj, char *buf,
+				    loff_t off, size_t count)
+{
+	u32 v;
+	int save_exclude;
+
+	if (off > 0)
+		return 0;
+	if (count <= 0)
+		return -EINVAL;
+
+	if (sscanf(buf, "%i", &v) == 1) {
+		if (down_interruptible(&mv64x60_hs_lock))
+			return -ERESTARTSYS;
+		save_exclude = mv64x60_pci_exclude_bridge;
+		mv64x60_pci_exclude_bridge = 0;
+		early_write_config_dword(mv64x60_primary_hose, 0,
+					 PCI_DEVFN(0, 0),
+					 MV64X60_PCICFG_CPCI_HOTSWAP, v);
+		mv64x60_pci_exclude_bridge = save_exclude;
+		up(&mv64x60_hs_lock);
+	}
+	else
+		count = -EINVAL;
+
+	return count;
+}
+
+static struct bin_attribute mv64x60_hs_reg_attr = { /* Hotswap register */
+	.attr = {
+		.name = "hs_reg",
+		.mode = S_IRUGO | S_IWUSR,
+		.owner = THIS_MODULE,
+	},
+	.size  = MV64X60_VAL_LEN_MAX,
+	.read  = mv64x60_hs_reg_read,
+	.write = mv64x60_hs_reg_write,
+};
+
+static int __init mv64x60_sysfs_init(void)
+{
+	struct device_node *np;
+	struct platform_device *pdev;
+	const unsigned int *prop;
+
+	np = of_find_compatible_node(NULL, NULL, "mv64x60");
+	if (!np)
+		return 0;
+
+	pdev = platform_device_register_simple("mv64x60", 0, NULL, 0);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	prop = of_get_property(np, "hs_reg_valid", NULL);
+	of_node_put(np);
+	if (!prop)
+		return 0;
+
+	return sysfs_create_bin_file(&pdev->dev.kobj, &mv64x60_hs_reg_attr);
+}
+
+subsys_initcall(mv64x60_sysfs_init);
+
+#endif /* CONFIG_SYSFS */
+
+static int mv64x60_exclude_device(u_char bus, u_char devfn)
+{
+	if ((bus == 0 || bus == mv64x60_pci2_busno) &&
+	    PCI_SLOT(devfn) == 0 && mv64x60_pci_exclude_bridge)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int __init mv64x60_add_bridge(struct device_node *dev)
+{
+	int len;
+	struct pci_controller *hose;
+	struct resource rsrc;
+	const int *bus_range;
+	int primary;
+
+	memset(&rsrc, 0, sizeof(rsrc));
+
+	/* Fetch host bridge registers address */
+	if (of_address_to_resource(dev, 0, &rsrc)) {
+		printk(KERN_ERR "No PCI reg property in device tree\n");
+		return -ENODEV;
+	}
+
+	/* Get bus range if any */
+	bus_range = of_get_property(dev, "bus-range", &len);
+	if (bus_range == NULL || len < 2 * sizeof(int))
+		printk(KERN_WARNING "Can't get bus-range for %s, assume"
+		       " bus 0\n", dev->full_name);
+
+	hose = pcibios_alloc_controller();
+	if (!hose)
+		return -ENOMEM;
+
+	hose->arch_data = dev;
+	hose->set_cfg_type = 1;
+
+	hose->first_busno = bus_range ? bus_range[0] : 0;
+	hose->last_busno = bus_range ? bus_range[1] : 0xff;
+	primary = hose->first_busno == 0;
+
+	setup_indirect_pci(hose, rsrc.start, rsrc.start + 4);
+
+	if (primary)
+		mv64x60_primary_hose = hose;
+	else {
+		hose->bus_offset = hose->first_busno;
+		mv64x60_pci2_busno = hose->first_busno;
+	}
+
+	printk(KERN_INFO "Found MV64x60 PCI host bridge at 0x%016llx. "
+	       "Firmware bus number: %d->%d\n",
+	       (unsigned long long)rsrc.start, hose->first_busno,
+	       hose->last_busno);
+
+	/* Interpret the "ranges" property */
+	/* This also maps the I/O region and sets isa_io/mem_base */
+	pci_process_bridge_OF_ranges(hose, dev, primary);
+
+	return 0;
+}
+
+void __init mv64x60_pci_init(void)
+{
+	struct device_node *np = NULL;
+
+	ppc_md.pci_exclude_device = mv64x60_exclude_device;
+
+	while ((np = of_find_compatible_node(np, "pci", "mv64x60-pci")))
+		mv64x60_add_bridge(np);
+}
Index: linux-2.6-powerpc-df/arch/powerpc/platforms/embedded6xx/Kconfig
===================================================================
--- linux-2.6-powerpc-df.orig/arch/powerpc/platforms/embedded6xx/Kconfig
+++ linux-2.6-powerpc-df/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -40,6 +40,7 @@ config MPC10X_BRIDGE
 
 config MV64X60
 	bool
+	select PPC_INDIRECT_PCI
 
 config MPC10X_OPENPIC
 	bool

^ permalink raw reply

* [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
From: Dale Farnsworth @ 2007-05-02 21:44 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <20070426000043.GK4046@mag.az.mvista.com>


Signed-off-by: Dale Farnsworth <dale@farnsworth.org>

---
 arch/powerpc/sysdev/mv64x60_dev.c |   63 ++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60_dev.c
===================================================================
--- linux-2.6-powerpc-df.orig/arch/powerpc/sysdev/mv64x60_dev.c
+++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60_dev.c
@@ -299,6 +299,65 @@ unreg:
 	return err;
 }
 
+/*
+ * Create mv64x60_i2c platform devices
+ */
+static int __init mv64x60_i2c_device_setup(struct device_node *np)
+{
+	struct resource r[2];
+	struct platform_device *pdev;
+	struct mv64xxx_i2c_pdata pdata;
+	const unsigned int *prop;
+	int err;
+	static int called_count;
+	int instance = called_count++;
+
+	memset(&r[1], 0, sizeof(r[1]));
+
+	err = of_address_to_resource(np, 0, &r[0]);
+	if (err)
+		return err;
+
+	of_irq_to_resource(np, 0, &r[1]);
+
+	memset(&pdata, 0, sizeof(pdata));
+
+	prop = of_get_property(np, "freq_m", NULL);
+	if (!prop)
+		return -ENODEV;
+	pdata.freq_m = *prop;
+
+	prop = of_get_property(np, "freq_n", NULL);
+	if (!prop)
+		return -ENODEV;
+	pdata.freq_n = *prop;
+
+	prop = of_get_property(np, "timeout", NULL);
+	if (prop)
+		pdata.timeout = *prop;
+	else
+		pdata.timeout = 1000;	/* 1 second */
+
+	prop = of_get_property(np, "retries", NULL);
+	if (prop)
+		pdata.retries = *prop;
+	else
+		pdata.retries = 1;
+
+	pdev = platform_device_register_simple(MV64XXX_I2C_CTLR_NAME,
+					       instance, r, 2);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+	if (err) {
+		platform_device_unregister(pdev);
+		return err;
+	}
+
+	return 0;
+}
+
 static int __init mv64x60_device_setup(void)
 {
 	struct device_node *np = NULL;
@@ -312,6 +371,10 @@ static int __init mv64x60_device_setup(v
 		if ((err = mv64x60_eth_device_setup(np)))
 			goto err_ret;
 
+	while ((np = of_find_compatible_node(np, "i2c", "mv64x60-i2c")))
+		if ((err = mv64x60_i2c_device_setup(np)))
+			goto err_ret;
+
 	return 0;
 
 err_ret:

^ permalink raw reply

* [PATCH 8/13] powerpc: Add arch/powerpc mv64x60_eth platform data setup
From: Dale Farnsworth @ 2007-05-02 21:43 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <20070426000009.GJ4046@mag.az.mvista.com>


Signed-off-by: Dale Farnsworth <dale@farnsworth.org>
---
I rearranged some of the property setting code.

 arch/powerpc/sysdev/mv64x60_dev.c |  123 +++++++++++++++++++++++++++-
 drivers/net/Kconfig               |    2 
 2 files changed, 123 insertions(+), 2 deletions(-)

Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60_dev.c
===================================================================
--- linux-2.6-powerpc-df.orig/arch/powerpc/sysdev/mv64x60_dev.c
+++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60_dev.c
@@ -182,6 +182,123 @@ unreg:
 	return err;
 }
 
+/*
+ * Create mv64x60_eth platform devices
+ */
+static int __init eth_register_shared_pdev(struct device_node *np)
+{
+	struct platform_device *pdev;
+	struct resource res;
+	int err;
+
+	np = of_get_parent(np);
+	if (!np)
+		return -ENODEV;
+
+	err = of_address_to_resource(np, 0, &res);
+	of_node_put(np);
+	if (err)
+		return err;
+
+	pdev = platform_device_register_simple(MV643XX_ETH_SHARED_NAME, 0,
+					       &res, 1);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	return 0;
+}
+
+static int __init mv64x60_eth_device_setup(struct device_node *np)
+{
+	struct resource res;
+	struct mv643xx_eth_platform_data pdata;
+	struct platform_device *pdev;
+	struct device_node *phy;
+	const u8 *mac_addr;
+	const void *prop;
+	const phandle *ph;
+	int err;
+	static int called_count;
+
+	memset(&res, 0, sizeof(res));
+	of_irq_to_resource(np, 0, &res);
+
+	memset(&pdata, 0, sizeof(pdata));
+
+	prop = of_get_property(np, "block-index", NULL);
+	if (!prop)
+		return -ENODEV;
+	pdata.port_number = *(int *)prop;
+
+	mac_addr = of_get_mac_address(np);
+	if (mac_addr)
+		memcpy(pdata.mac_addr, mac_addr, 6);
+
+	prop = of_get_property(np, "speed", NULL);
+	if (prop)
+		pdata.speed = *(int *)prop;
+
+	prop = of_get_property(np, "tx_queue_size", NULL);
+	if (prop)
+		pdata.tx_queue_size = *(int *)prop;
+
+	prop = of_get_property(np, "rx_queue_size", NULL);
+	if (prop)
+		pdata.rx_queue_size = *(int *)prop;
+
+	prop = of_get_property(np, "tx_sram_addr", NULL);
+	if (prop)
+		pdata.tx_sram_addr = *(int *)prop;
+
+	prop = of_get_property(np, "tx_sram_size", NULL);
+	if (prop)
+		pdata.tx_sram_size = *(int *)prop;
+
+	prop = of_get_property(np, "rx_sram_addr", NULL);
+	if (prop)
+		pdata.rx_sram_addr = *(int *)prop;
+
+	prop = of_get_property(np, "rx_sram_size", NULL);
+	if (prop)
+		pdata.rx_sram_size = *(int *)prop;
+
+	ph = of_get_property(np, "phy", NULL);
+	if (!ph)
+		return -ENODEV;
+
+	phy = of_find_node_by_phandle(*ph);
+	if (phy == NULL)
+		return -ENODEV;
+
+	prop = of_get_property(phy, "reg", NULL);
+	if (prop) {
+		pdata.force_phy_addr = 1;
+		pdata.phy_addr = *(int *)prop;
+	}
+
+	of_node_put(phy);
+
+	pdev = platform_device_register_simple(MV643XX_ETH_NAME,
+					       pdata.port_number, &res, 1);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+	if (err)
+		goto unreg;
+
+	/* only register the shared platform device the first time through */
+	if (called_count++ == 0)
+		if ((err = eth_register_shared_pdev(np)))
+			goto unreg;
+
+	return 0;
+
+unreg:
+	platform_device_unregister(pdev);
+	return err;
+}
+
 static int __init mv64x60_device_setup(void)
 {
 	struct device_node *np = NULL;
@@ -191,6 +308,10 @@ static int __init mv64x60_device_setup(v
 		if ((err = mv64x60_mpsc_device_setup(np)))
 			goto err_ret;
 
+	while ((np = of_find_compatible_node(np, "network", "mv64x60-eth")))
+		if ((err = mv64x60_eth_device_setup(np)))
+			goto err_ret;
+
 	return 0;
 
 err_ret:
Index: linux-2.6-powerpc-df/drivers/net/Kconfig
===================================================================
--- linux-2.6-powerpc-df.orig/drivers/net/Kconfig
+++ linux-2.6-powerpc-df/drivers/net/Kconfig
@@ -2302,7 +2302,7 @@ config UGETH_HAS_GIGA
 
 config MV643XX_ETH
 	tristate "MV-643XX Ethernet support"
-	depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MV64360 || MOMENCO_OCELOT_3 || (PPC_MULTIPLATFORM && PPC32)
+	depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MV64360 || MV64X60 || MOMENCO_OCELOT_3 || (PPC_MULTIPLATFORM && PPC32)
 	select MII
 	help
 	  This driver supports the gigabit Ethernet on the Marvell MV643XX

^ permalink raw reply

* [PATCH 7/13] powerpc: Add arch/powerpc mv64x60 MPSC platform data setup
From: Dale Farnsworth @ 2007-05-02 21:41 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <20070425235939.GI4046@mag.az.mvista.com>

Signed-off-by: Dale Farnsworth <dale@farnsworth.org>

---

I added a comment describing using platform_device rather than
of_platform_device.  I also rearranged some of the property
setting code.

 arch/powerpc/platforms/embedded6xx/Kconfig |    3 
 arch/powerpc/sysdev/Makefile               |    2 
 arch/powerpc/sysdev/mv64x60_dev.c          |  201 +++++++++++++++++++
 3 files changed, 205 insertions(+), 1 deletion(-)

Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60_dev.c
===================================================================
--- /dev/null
+++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60_dev.c
@@ -0,0 +1,201 @@
+/*
+ * Platform device setup for Marvell mv64360/mv64460 host bridges (Discovery)
+ *
+ * Author: Dale Farnsworth <dale@farnsworth.org>
+ *
+ * 2007 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mv643xx.h>
+#include <linux/platform_device.h>
+
+#include <asm/prom.h>
+
+/*
+ * These functions provide the necessary setup for the mv64x60 drivers.
+ * These drivers are unusual in that they work on both the MIPS and PowerPC
+ * architectures.  Because of that, the drivers do not support the normal
+ * PowerPC of_platform_bus_type.  They support platform_bus_type instead.
+ */
+
+/*
+ * Create MPSC platform device
+ */
+static int __init mv64x60_mpsc_register_shared_pdev(struct device_node *np)
+{
+	struct platform_device *pdev;
+	struct resource r[2];
+	struct mpsc_shared_pdata pdata;
+	const phandle *ph;
+	struct device_node *mpscrouting, *mpscintr;
+	int err;
+
+	ph = of_get_property(np, "mpscrouting", NULL);
+	mpscrouting = of_find_node_by_phandle(*ph);
+	if (!mpscrouting)
+		return -ENODEV;
+
+	err = of_address_to_resource(mpscrouting, 0, &r[0]);
+	of_node_put(mpscrouting);
+	if (err)
+		return err;
+
+	ph = of_get_property(np, "mpscintr", NULL);
+	mpscintr = of_find_node_by_phandle(*ph);
+	if (!mpscintr)
+		return -ENODEV;
+
+	err = of_address_to_resource(mpscintr, 0, &r[1]);
+	of_node_put(mpscintr);
+	if (err)
+		return err;
+
+	pdev = platform_device_register_simple(MPSC_SHARED_NAME, 0, r, 2);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	memset(&pdata, 0, sizeof(pdata));
+
+	err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+	if (err)
+		platform_device_unregister(pdev);
+
+	return 0;
+}
+
+static int __init mv64x60_mpsc_device_setup(struct device_node *np)
+{
+	struct resource r[5];
+	struct mpsc_pdata pdata;
+	struct platform_device *pdev;
+	const unsigned int *prop;
+	const phandle *ph;
+	struct device_node *sdma, *brg;
+	int err;
+	int port_number;
+	static int called_count;
+
+	memset(&r, 0, sizeof(r));
+
+	err = of_address_to_resource(np, 0, &r[0]);
+	if (err)
+		return err;
+
+	of_irq_to_resource(np, 0, &r[4]);
+
+	ph = of_get_property(np, "sdma", NULL);
+	sdma = of_find_node_by_phandle(*ph);
+	if (!sdma)
+		return -ENODEV;
+
+	of_irq_to_resource(sdma, 0, &r[3]);
+	err = of_address_to_resource(sdma, 0, &r[1]);
+	of_node_put(sdma);
+	if (err)
+		return err;
+
+	ph = of_get_property(np, "brg", NULL);
+	brg = of_find_node_by_phandle(*ph);
+	if (!brg)
+		return -ENODEV;
+
+	err = of_address_to_resource(brg, 0, &r[2]);
+	of_node_put(brg);
+	if (err)
+		return err;
+
+	memset(&pdata, 0, sizeof(pdata));
+
+	pdata.cache_mgmt = 1; /* All current revs need this set */
+
+	prop = of_get_property(np, "block-index", NULL);
+	if (!prop)
+		return -ENODEV;
+	port_number = *(int *)prop;
+
+	prop = of_get_property(np, "max_idle", NULL);
+	if (prop)
+		pdata.max_idle = *prop;
+
+	prop = of_get_property(brg, "current-speed", NULL);
+	if (prop)
+		pdata.default_baud = *prop;
+
+	/* Default is 8 bits, no parity, no flow control */
+	pdata.default_bits = 8;
+	pdata.default_parity = 'n';
+	pdata.default_flow = 'n';
+
+	prop = of_get_property(np, "chr_1", NULL);
+	if (prop)
+		pdata.chr_1_val = *prop;
+
+	prop = of_get_property(np, "chr_2", NULL);
+	if (prop)
+		pdata.chr_2_val = *prop;
+
+	prop = of_get_property(np, "chr_10", NULL);
+	if (prop)
+		pdata.chr_10_val = *prop;
+
+	prop = of_get_property(np, "mpcr", NULL);
+	if (prop)
+		pdata.mpcr_val = *prop;
+
+	prop = of_get_property(brg, "bcr", NULL);
+	if (prop)
+		pdata.bcr_val = *prop;
+
+	pdata.brg_can_tune = 1; /* All current revs need this set */
+
+	prop = of_get_property(brg, "clock-src", NULL);
+	if (prop)
+		pdata.brg_clk_src = *prop;
+
+	prop = of_get_property(brg, "clock-frequency", NULL);
+	if (prop)
+		pdata.brg_clk_freq = *prop;
+
+	pdev = platform_device_register_simple(MPSC_CTLR_NAME,
+					       port_number, r, 5);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+	if (err)
+		goto unreg;
+
+	/* only register the shared platform device the first time through */
+	if (called_count++ == 0)
+		if ((err = mv64x60_mpsc_register_shared_pdev(np)))
+			goto unreg;
+
+	return 0;
+
+unreg:
+	platform_device_unregister(pdev);
+	return err;
+}
+
+static int __init mv64x60_device_setup(void)
+{
+	struct device_node *np = NULL;
+	int err;
+
+	while ((np = of_find_compatible_node(np, "serial", "mpsc")))
+		if ((err = mv64x60_mpsc_device_setup(np)))
+			goto err_ret;
+
+	return 0;
+
+err_ret:
+	of_node_put(np);
+	return err;
+}
+arch_initcall(mv64x60_device_setup);
Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/Makefile
===================================================================
--- linux-2.6-powerpc-df.orig/arch/powerpc/sysdev/Makefile
+++ linux-2.6-powerpc-df/arch/powerpc/sysdev/Makefile
@@ -14,7 +14,7 @@ obj-$(CONFIG_FSL_SOC)		+= fsl_soc.o
 obj-$(CONFIG_FSL_PCIE)		+= fsl_pcie.o
 obj-$(CONFIG_TSI108_BRIDGE)	+= tsi108_pci.o tsi108_dev.o
 obj-$(CONFIG_QUICC_ENGINE)	+= qe_lib/
-obj-$(CONFIG_MV64X60)		+= mv64x60_pic.o
+obj-$(CONFIG_MV64X60)		+= mv64x60_pic.o mv64x60_dev.o
 
 # contains only the suspend handler for time
 obj-$(CONFIG_PM)		+= timer.o
Index: linux-2.6-powerpc-df/arch/powerpc/platforms/embedded6xx/Kconfig
===================================================================
--- linux-2.6-powerpc-df.orig/arch/powerpc/platforms/embedded6xx/Kconfig
+++ linux-2.6-powerpc-df/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -38,6 +38,9 @@ config MPC10X_BRIDGE
 	select PPC_INDIRECT_PCI
 	default y
 
+config MV64X60
+	bool
+
 config MPC10X_OPENPIC
 	bool
 	depends on LINKSTATION

^ permalink raw reply

* [PATCH 6/13] powerpc: Add arch/powerpc interrupt handler for mv64x60
From: Dale Farnsworth @ 2007-05-02 21:38 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <20070425235858.GH4046@mag.az.mvista.com>


Signed-off-by: Dale Farnsworth <dale@farnsworth.org>

---
I took Arnd Bergmann's advice and created a separate file for
the Marvell mv64x60 interrupt handler code.

 arch/powerpc/sysdev/Makefile      |    1 
 arch/powerpc/sysdev/mv64x60.h     |    9 
 arch/powerpc/sysdev/mv64x60_pic.c |  305 ++++++++++++++++++++++++++++
 3 files changed, 315 insertions(+)

Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60_pic.c
===================================================================
--- /dev/null
+++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60_pic.c
@@ -0,0 +1,305 @@
+/*
+ * Interrupt handling for Marvell mv64360/mv64460 host bridges (Discovery)
+ *
+ * Author: Dale Farnsworth <dale@farnsworth.org>
+ *
+ * 2007 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/irq.h>
+
+#include "mv64x60.h"
+
+/* Interrupt Controller Interface Registers */
+#define MV64X60_IC_MAIN_CAUSE_LO	0x0004
+#define MV64X60_IC_MAIN_CAUSE_HI	0x000c
+#define MV64X60_IC_CPU0_INTR_MASK_LO	0x0014
+#define MV64X60_IC_CPU0_INTR_MASK_HI	0x001c
+#define MV64X60_IC_CPU0_SELECT_CAUSE	0x0024
+
+#define MV64X60_HIGH_GPP_GROUPS		0x0f000000
+#define MV64X60_SELECT_CAUSE_HIGH	0x40000000
+
+/* General Purpose Pins Controller Interface Registers */
+#define MV64x60_GPP_INTR_CAUSE		0x0008
+#define MV64x60_GPP_INTR_MASK		0x000c
+
+#define MV64x60_LEVEL1_LOW		0
+#define MV64x60_LEVEL1_HIGH		1
+#define MV64x60_LEVEL1_GPP		2
+
+#define MV64x60_LEVEL1_MASK		0x00000060
+#define MV64x60_LEVEL1_OFFSET		5
+
+#define MV64x60_LEVEL2_MASK		0x0000001f
+
+#define MV64x60_NUM_IRQS		96
+
+DEFINE_SPINLOCK(mv64x60_lock);
+
+static void __iomem *mv64x60_irq_reg_base;
+static void __iomem *mv64x60_gpp_reg_base;
+
+/*
+ * Interrupt Controller Handling
+ *
+ * The interrupt controller handles three groups of interrupts:
+ *   main low:	IRQ0-IRQ31
+ *   main high:	IRQ32-IRQ63
+ *   gpp:	IRQ64-IRQ95
+ *
+ * This code handles interrupts in two levels.  Level 1 selects the
+ * interrupt group, and level 2 selects an IRQ within that group.
+ * Each group has its own irq_chip structure.
+ */
+
+static u32 mv64x60_cached_low_mask  = 0;
+static u32 mv64x60_cached_high_mask = MV64X60_HIGH_GPP_GROUPS;
+static u32 mv64x60_cached_gpp_mask  = 0;
+
+static struct irq_host *mv64x60_irq_host;
+
+/*
+ * mv64x60_chip_low functions
+ */
+
+static void mv64x60_mask_low(unsigned int virq)
+{
+	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mv64x60_lock, flags);
+	mv64x60_cached_low_mask &= ~(1 << level2);
+	out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO,
+		 mv64x60_cached_low_mask);
+	spin_unlock_irqrestore(&mv64x60_lock, flags);
+	(void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO);
+}
+
+static void mv64x60_unmask_low(unsigned int virq)
+{
+	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mv64x60_lock, flags);
+	mv64x60_cached_low_mask |= 1 << level2;
+	out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO,
+		 mv64x60_cached_low_mask);
+	spin_unlock_irqrestore(&mv64x60_lock, flags);
+	(void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO);
+}
+
+static struct irq_chip mv64x60_chip_low = {
+	.name		= "mv64x60_low",
+	.mask		= mv64x60_mask_low,
+	.mask_ack	= mv64x60_mask_low,
+	.unmask		= mv64x60_unmask_low,
+};
+
+/*
+ * mv64x60_chip_high functions
+ */
+
+static void mv64x60_mask_high(unsigned int virq)
+{
+	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mv64x60_lock, flags);
+	mv64x60_cached_high_mask &= ~(1 << level2);
+	out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI,
+		 mv64x60_cached_high_mask);
+	spin_unlock_irqrestore(&mv64x60_lock, flags);
+	(void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI);
+}
+
+static void mv64x60_unmask_high(unsigned int virq)
+{
+	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mv64x60_lock, flags);
+	mv64x60_cached_high_mask |= 1 << level2;
+	out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI,
+		 mv64x60_cached_high_mask);
+	spin_unlock_irqrestore(&mv64x60_lock, flags);
+	(void)in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI);
+}
+
+static struct irq_chip mv64x60_chip_high = {
+	.name		= "mv64x60_high",
+	.mask		= mv64x60_mask_high,
+	.mask_ack	= mv64x60_mask_high,
+	.unmask		= mv64x60_unmask_high,
+};
+
+/*
+ * mv64x60_chip_gpp functions
+ */
+
+static void mv64x60_mask_gpp(unsigned int virq)
+{
+	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mv64x60_lock, flags);
+	mv64x60_cached_gpp_mask &= ~(1 << level2);
+	out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
+		 mv64x60_cached_gpp_mask);
+	spin_unlock_irqrestore(&mv64x60_lock, flags);
+	(void)in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK);
+}
+
+static void mv64x60_mask_ack_gpp(unsigned int virq)
+{
+	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mv64x60_lock, flags);
+	mv64x60_cached_gpp_mask &= ~(1 << level2);
+	out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
+		 mv64x60_cached_gpp_mask);
+	out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_CAUSE,
+		 ~(1 << level2));
+	spin_unlock_irqrestore(&mv64x60_lock, flags);
+	(void)in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_CAUSE);
+}
+
+static void mv64x60_unmask_gpp(unsigned int virq)
+{
+	int level2 = irq_map[virq].hwirq & MV64x60_LEVEL2_MASK;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mv64x60_lock, flags);
+	mv64x60_cached_gpp_mask |= 1 << level2;
+	out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
+		 mv64x60_cached_gpp_mask);
+	spin_unlock_irqrestore(&mv64x60_lock, flags);
+	(void)in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK);
+}
+
+static struct irq_chip mv64x60_chip_gpp = {
+	.name		= "mv64x60_gpp",
+	.mask		= mv64x60_mask_gpp,
+	.mask_ack	= mv64x60_mask_ack_gpp,
+	.unmask		= mv64x60_unmask_gpp,
+};
+
+/*
+ * mv64x60_host_ops functions
+ */
+
+static int mv64x60_host_match(struct irq_host *h, struct device_node *np)
+{
+	return mv64x60_irq_host->host_data == np;
+}
+
+static struct irq_chip *mv64x60_chips[] = {
+	[MV64x60_LEVEL1_LOW]  = &mv64x60_chip_low,
+	[MV64x60_LEVEL1_HIGH] = &mv64x60_chip_high,
+	[MV64x60_LEVEL1_GPP]  = &mv64x60_chip_gpp,
+};
+
+static int mv64x60_host_map(struct irq_host *h, unsigned int virq,
+			  irq_hw_number_t hwirq)
+{
+	int level1;
+
+	get_irq_desc(virq)->status |= IRQ_LEVEL;
+
+	level1 = (hwirq & MV64x60_LEVEL1_MASK) >> MV64x60_LEVEL1_OFFSET;
+	BUG_ON(level1 > MV64x60_LEVEL1_GPP);
+	set_irq_chip_and_handler(virq, mv64x60_chips[level1], handle_level_irq);
+
+	return 0;
+}
+
+static struct irq_host_ops mv64x60_host_ops = {
+	.match = mv64x60_host_match,
+	.map   = mv64x60_host_map,
+};
+
+/*
+ * Global functions
+ */
+
+void __init mv64x60_init_irq(void)
+{
+	struct device_node *np;
+	phys_addr_t paddr;
+	unsigned int size;
+	const unsigned int *reg;
+	unsigned long flags;
+
+	np = of_find_compatible_node(NULL, "mv64x60-gpp", "mv64x60-gpp");
+	reg = of_get_property(np, "reg", &size);
+	paddr = of_translate_address(np, reg);
+	mv64x60_gpp_reg_base = ioremap(paddr, reg[1]);
+	of_node_put(np);
+
+	np = of_find_compatible_node(NULL, "mv64x60-pic", "mv64x60-pic");
+	reg = of_get_property(np, "reg", &size);
+	paddr = of_translate_address(np, reg);
+	of_node_put(np);
+	mv64x60_irq_reg_base = ioremap(paddr, reg[1]);
+
+	mv64x60_irq_host = irq_alloc_host(IRQ_HOST_MAP_LINEAR, MV64x60_NUM_IRQS,
+					  &mv64x60_host_ops, MV64x60_NUM_IRQS);
+
+	mv64x60_irq_host->host_data = np;
+
+	spin_lock_irqsave(&mv64x60_lock, flags);
+	out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
+		 mv64x60_cached_gpp_mask);
+	out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_LO,
+		 mv64x60_cached_low_mask);
+	out_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_INTR_MASK_HI,
+		 mv64x60_cached_high_mask);
+
+	out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_CAUSE, 0);
+	out_le32(mv64x60_irq_reg_base + MV64X60_IC_MAIN_CAUSE_LO, 0);
+	out_le32(mv64x60_irq_reg_base + MV64X60_IC_MAIN_CAUSE_HI, 0);
+	spin_unlock_irqrestore(&mv64x60_lock, flags);
+}
+
+unsigned int mv64x60_get_irq(void)
+{
+	u32 cause;
+	int level1;
+	irq_hw_number_t hwirq;
+	int virq = NO_IRQ;
+
+	cause = in_le32(mv64x60_irq_reg_base + MV64X60_IC_CPU0_SELECT_CAUSE);
+	if (cause & MV64X60_SELECT_CAUSE_HIGH) {
+		cause &= mv64x60_cached_high_mask;
+		level1 = MV64x60_LEVEL1_HIGH;
+		if (cause & MV64X60_HIGH_GPP_GROUPS) {
+			cause = in_le32(mv64x60_gpp_reg_base +
+					MV64x60_GPP_INTR_CAUSE);
+			cause &= mv64x60_cached_gpp_mask;
+			level1 = MV64x60_LEVEL1_GPP;
+		}
+	} else {
+		cause &= mv64x60_cached_low_mask;
+		level1 = MV64x60_LEVEL1_LOW;
+	}
+	if (cause) {
+		hwirq = (level1 << MV64x60_LEVEL1_OFFSET) | __ilog2(cause);
+		virq = irq_linear_revmap(mv64x60_irq_host, hwirq);
+	}
+
+	return virq;
+}
Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.h
===================================================================
--- /dev/null
+++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.h
@@ -0,0 +1,9 @@
+#ifndef __MV64X60_H__
+#define __MV64X60_H__
+
+#include <linux/init.h>
+
+extern void __init mv64x60_init_irq(void);
+extern unsigned int mv64x60_get_irq(void);
+
+#endif /* __MV64X60_H__ */
Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/Makefile
===================================================================
--- linux-2.6-powerpc-df.orig/arch/powerpc/sysdev/Makefile
+++ linux-2.6-powerpc-df/arch/powerpc/sysdev/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_FSL_SOC)		+= fsl_soc.o
 obj-$(CONFIG_FSL_PCIE)		+= fsl_pcie.o
 obj-$(CONFIG_TSI108_BRIDGE)	+= tsi108_pci.o tsi108_dev.o
 obj-$(CONFIG_QUICC_ENGINE)	+= qe_lib/
+obj-$(CONFIG_MV64X60)		+= mv64x60_pic.o
 
 # contains only the suspend handler for time
 obj-$(CONFIG_PM)		+= timer.o

^ permalink raw reply

* [PATCH] Remove CPU_FTR_NEED_COHERENT for 7448.
From: Jon Loeliger @ 2007-05-02 21:34 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org

From: James.Yang <James.Yang@freescale.com>

Remove CPU_FTR_NEED_COHERENT for MPC7448 (and single-core MPC86xx).
This prevents needlessly setting M=1 when not SMP.

Signed-off-by: James.Yang <James.Yang@freescale.com>
Acked-by: Jon Loeliger <jdl@freescale.com>
---
 arch/powerpc/kernel/cputable.c |    2 +-
 include/asm-powerpc/cputable.h |    6 ++++++
 2 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 9cb24d2..6ef87fb 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -836,7 +836,7 @@ static struct cpu_spec cpu_specs[] = {
 		.pvr_mask		= 0xffff0000,
 		.pvr_value		= 0x80040000,
 		.cpu_name		= "7448",
-		.cpu_features		= CPU_FTRS_7447A,
+		.cpu_features		= CPU_FTRS_7448,
 		.cpu_user_features	= COMMON_USER |
 			PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
 		.icache_bsize		= 32,
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h
index 4345249..82d595a 100644
--- a/include/asm-powerpc/cputable.h
+++ b/include/asm-powerpc/cputable.h
@@ -302,6 +302,12 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
 	    CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
 	    CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \
 	    CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE)
+#define CPU_FTRS_7448	(CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
+	    CPU_FTR_USE_TB | \
+	    CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
+	    CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
+	    CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \
+	    CPU_FTR_PPC_LE)
 #define CPU_FTRS_82XX	(CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
 	    CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB)
 #define CPU_FTRS_G2_LE	(CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | \
-- 
1.5.0.3

^ permalink raw reply related

* Re: [PATCH v2] gianfar: Add I/O barriers when touching buffer descriptor ownership.
From: Scott Wood @ 2007-05-02 21:30 UTC (permalink / raw)
  To: Kumar Gala; +Cc: netdev, jgarzik, linuxppc-dev
In-Reply-To: <41B347BE-06AA-4346-BEFB-19DFB52AC533@kernel.crashing.org>

Kumar Gala wrote:
> Why doesn't marking the bdp pointer volatile resolve the issue in  
> gfar_clean_rx_ring() to ensure load ordering?

Because that only addresses compiler reordering (and does so in a rather 
clumsy way -- not all accesses need to be strongly ordered), not 
hardware reordering.

-Scott

^ permalink raw reply

* Re: [PATCH v2] gianfar: Add I/O barriers when touching buffer descriptor ownership.
From: Kumar Gala @ 2007-05-02 21:23 UTC (permalink / raw)
  To: Scott Wood; +Cc: netdev, jgarzik, linuxppc-dev
In-Reply-To: <4638F734.2040809@freescale.com>


On May 2, 2007, at 3:40 PM, Scott Wood wrote:

> Kumar Gala wrote:
>> On May 2, 2007, at 3:12 PM, Scott Wood wrote:
>>> wmb() is a sync, smp_wmb() is an eieio.  Andy told me he would  
>>> not  accept a sync in those spots.
>> Sorry, was looking at the iobarrier code.
>>> And the driver is already ppc-specific; it uses in/out_be32.
>> True, but its hidden behind the gfar_read/write accessors.
>> Your change is a bit more blatant.
>
> Well, Segher doesn't want me to use iobarrier (because it's not I/ 
> O). Andy doesn't want me to use wmb() (because it's sync).  I don't  
> think something like gfar_wmb() would be appropriate.  So the  
> remaining options are either eieio(), or a new non-arch-specific,  
> non-driver-specific mem_wmb() (or whatever).
>
> While I like the latter option, I don't think this bugfix should  
> have to wait for it.

Ok, I've resigned to the eieio's.  If we end up respinning the patch  
again for any reason I'd like to see something in the commit comment  
to the fact that we are adding ppc specific sync operations.

Why doesn't marking the bdp pointer volatile resolve the issue in  
gfar_clean_rx_ring() to ensure load ordering?

- k

^ permalink raw reply

* Re: Using Cypress EZ-Host on ML403/5
From: Grant Likely @ 2007-05-02 21:08 UTC (permalink / raw)
  To: Peter Korsgaard, linuxppc-embedded
In-Reply-To: <528646bc0704301223q2024505ah5308147ba6eead0a@mail.gmail.com>

On 4/30/07, Grant Likely <grant.likely@secretlab.ca> wrote:
> On 4/27/07, Peter Korsgaard <jacmet@sunsite.dk> wrote:
> > On 4/24/07, Grant Likely <grant.likely@secretlab.ca> wrote:
> >
> > > > Anyway, here it is. It is structured as a base driver with
> > > > configurable host/peripheral support on top. The host part works
> > > > pretty ok, but the scheduling code can still be improved. Please
> > > > ignore the peripheral part for now.
> > >
> > > Awesome, thank you!  I'll try it out ASAP.
> >
> > Did you have a chance to try it out yet?

Hey Peter,

I've got it running on my board now after figuring out how to wire up
external interrupts in EDK.  :-)

Good success with keyboards and mice.  Events come through no problem.

Some block devices seem to be giving me grief.  I have no problem with
my SanDisk ImageMate CF reader.  However, I've got a SanDisk Curzer
Micro that gets reset during transfers.  Is this something you've seen
before?  Log output is below.

I've also got a QuickCam Messinger that I'm going to test isochronos
transfers with as well.

Cheers,
g.

/mnt #
/mnt # [ 2358.173508] usb 1-1.1: new full speed USB device using
c67x00 and address 15
[ 2358.309263] usb 1-1.1: configuration #1 chosen from 1 choice
[ 2358.318978] scsi4 : SCSI emulation for USB Mass Storage devices
[ 2358.328546] usb-storage: device found at 15
[ 2358.332860] usb-storage: waiting for device to settle before scanning
[ 2363.348145] scsi 4:0:0:0: Direct-Access     SanDisk  U3 Cruzer
Micro  2.18 PQ: 0 ANSI: 2
[ 2363.367956] SCSI device sda: 990865 512-byte hdwr sectors (507 MB)
[ 2363.379943] sda: Write Protect is off
[ 2363.383721] sda: Mode Sense: 03 00 00 00
[ 2363.387701] sda: assuming drive cache: write through
[ 2363.416940] SCSI device sda: 990865 512-byte hdwr sectors (507 MB)
[ 2363.428944] sda: Write Protect is off
[ 2363.432709] sda: Mode Sense: 03 00 00 00
[ 2363.436691] sda: assuming drive cache: write through
[ 2363.441730]  sda: sda1
[ 2363.465064] sd 4:0:0:0: Attached scsi removable disk sda
[ 2363.475029] usb-storage: device scan complete

/mnt #
/mnt # dd if=/dev/sda of=/dev/null bs=512 count=2048
[ 2390.851453] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2391.091406] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2391.331377] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2391.571349] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2391.811317] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2392.051286] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2392.173340] sd 4:0:0:0: SCSI error: return code = 0x00070000
[ 2392.179076] end_request: I/O error, dev sda, sector 0
[ 2392.184169] Buffer I/O error on device sda, logical block 0
[ 2392.189797] Buffer I/O error on device sda, logical block 1
[ 2392.195419] Buffer I/O error on device sda, logical block 2
[ 2392.201046] Buffer I/O error on device sda, logical block 3
[ 2392.206667] Buffer I/O error on device sda, logical block 4
[ 2392.212290] Buffer I/O error on device sda, logical block 5
[ 2392.217917] Buffer I/O error on device sda, logical block 6
[ 2392.223537] Buffer I/O error on device sda, logical block 7
[ 2392.229179] Buffer I/O error on device sda, logical block 8
[ 2392.234804] Buffer I/O error on device sda, logical block 9
[ 2392.331253] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2392.543226] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2392.755200] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2392.967174] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2393.179147] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2393.391121] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2393.513110] sd 4:0:0:0: SCSI error: return code = 0x00070000
[ 2393.518840] end_request: I/O error, dev sda, sector 0
dd: /dev/sda: Input/output error
/mnt # time dd if=/dev/sda of=/dev/null bs=512 count=2048
[ 2442.613020] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2442.852988] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2443.092959] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2443.332929] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2443.572902] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2443.812869] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2443.934899] sd 4:0:0:0: SCSI error: return code = 0x00070000
[ 2443.940624] end_request: I/O error, dev sda, sector 0
[ 2443.945717] printk: 30 messages suppressed.
[ 2443.949940] Buffer I/O error on device sda, logical block 0
[ 2443.955565] Buffer I/O error on device sda, logical block 1
[ 2443.961190] Buffer I/O error on device sda, logical block 2
[ 2443.966817] Buffer I/O error on device sda, logical block 3
[ 2443.972437] Buffer I/O error on device sda, logical block 4
[ 2443.978061] Buffer I/O error on device sda, logical block 5
[ 2443.983688] Buffer I/O error on device sda, logical block 6
[ 2443.989309] Buffer I/O error on device sda, logical block 7
[ 2443.994952] Buffer I/O error on device sda, logical block 8
[ 2444.000576] Buffer I/O error on device sda, logical block 9
[ 2444.096835] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2444.308808] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2444.520781] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2444.732771] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2444.944730] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2445.156704] usb 1-1.1: reset full speed USB device using c67x00 and
address 15
[ 2445.278663] sd 4:0:0:0: SCSI error: return code = 0x00070000
[ 2445.284390] end_request: I/O error, dev sda, sector 0
dd: /dev/sda: Input/output error
Command exited with non-zero status 1
real    0m 2.81s
user    0m 0.00s
sys     0m 0.02s
/mnt #

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

^ permalink raw reply

* Re: [PATCH v2] gianfar: Add I/O barriers when touching buffer descriptor ownership.
From: Scott Wood @ 2007-05-02 20:40 UTC (permalink / raw)
  To: Kumar Gala; +Cc: netdev, jgarzik, linuxppc-dev
In-Reply-To: <FA9554A4-5A7D-4E03-BE28-C4B6B80D9DB9@kernel.crashing.org>

Kumar Gala wrote:
> On May 2, 2007, at 3:12 PM, Scott Wood wrote:
>> wmb() is a sync, smp_wmb() is an eieio.  Andy told me he would not  
>> accept a sync in those spots.
> 
> 
> Sorry, was looking at the iobarrier code.
> 
>> And the driver is already ppc-specific; it uses in/out_be32.
> 
> 
> True, but its hidden behind the gfar_read/write accessors.
> 
> Your change is a bit more blatant.

Well, Segher doesn't want me to use iobarrier (because it's not I/O). 
Andy doesn't want me to use wmb() (because it's sync).  I don't think 
something like gfar_wmb() would be appropriate.  So the remaining 
options are either eieio(), or a new non-arch-specific, 
non-driver-specific mem_wmb() (or whatever).

While I like the latter option, I don't think this bugfix should have to 
wait for it.

-Scott

^ permalink raw reply

* Re: [PATCH v2] gianfar: Add I/O barriers when touching buffer descriptor ownership.
From: Kumar Gala @ 2007-05-02 20:20 UTC (permalink / raw)
  To: Scott Wood; +Cc: netdev, jgarzik, linuxppc-dev
In-Reply-To: <4638F0C4.2000406@freescale.com>


On May 2, 2007, at 3:12 PM, Scott Wood wrote:

> Kumar Gala wrote:
>> I'd rather see a wmb() instead of eieio() to keep this code non- 
>> ppc  specific.  (also, we implement wmb as eieio, so I don't keep  
>> the  comment about it being too heavy, unless you mean generically).
>
> wmb() is a sync, smp_wmb() is an eieio.  Andy told me he would not  
> accept a sync in those spots.

Sorry, was looking at the iobarrier code.

> And the driver is already ppc-specific; it uses in/out_be32.

True, but its hidden behind the gfar_read/write accessors.

Your change is a bit more blatant.

- k

^ permalink raw reply

* Re: mpc5200 and spi bus
From: John Rigby @ 2007-05-02 20:19 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: Txema Lopez, linuxppc-embedded
In-Reply-To: <20070502173629.GA5797@pengutronix.de>

This will take you to a page where the download attachment link will
actually work:

http://sourceforge.net/mailarchive/attachment.php?list_name=spi-devel-general&message_id=45DEDC70.7010301@toptica.com&counter=1

On 5/2/07, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> Hi,
>
> On Wed, May 02, 2007 at 10:02:44AM +0200, Asier Llano Palacios wrote:
> > >
> >
> > I'll have a look. If don't see anything the code from 2.4.x is good
> > starting point to port it.
>
> There was a patch for the PSC in SPI mode for 2.6 posted here:
>
> http://sourceforge.net/mailarchive/forum.php?thread_name=45DD9ABF.9010009%40toptica.com&forum_name=spi-devel-general
>
> I can forward you the patch if you like, because the sourceforge server
> only replies with "Insufficient parameters" when I click on the patch
> link :(
>
> I myself wrote a driver for the dedicated SPI port which I can post on
> spi-devel-general tomorrow (after I looked over it again).
>
> Best regards,
>   Sascha
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>

^ permalink raw reply

* Re: [PATCH v2] gianfar: Add I/O barriers when touching buffer descriptor ownership.
From: Scott Wood @ 2007-05-02 20:12 UTC (permalink / raw)
  To: Kumar Gala; +Cc: netdev, jgarzik, linuxppc-dev
In-Reply-To: <F1B250DD-A472-470F-B3D0-EBB2F042E454@kernel.crashing.org>

Kumar Gala wrote:
> I'd rather see a wmb() instead of eieio() to keep this code non-ppc  
> specific.  (also, we implement wmb as eieio, so I don't keep the  
> comment about it being too heavy, unless you mean generically).

wmb() is a sync, smp_wmb() is an eieio.  Andy told me he would not 
accept a sync in those spots.

And the driver is already ppc-specific; it uses in/out_be32.

-Scott

^ permalink raw reply

* Re: [PATCH v2] gianfar: Add I/O barriers when touching buffer descriptor ownership.
From: Kumar Gala @ 2007-05-02 20:09 UTC (permalink / raw)
  To: Scott Wood; +Cc: netdev, jgarzik, linuxppc-dev
In-Reply-To: <20070502195712.GA16541@ld0162-tx32.am.freescale.net>


On May 2, 2007, at 2:57 PM, Scott Wood wrote:

> The hardware must not see that is given ownership of a buffer until  
> it is
> completely written, and when the driver receives ownership of a  
> buffer,
> it must ensure that any other reads to the buffer reflect its final
> state.  Thus, I/O barriers are added where required.
>
> Without this patch, I have observed GCC reordering the setting of
> bdp->length and bdp->status in gfar_new_skb.
>
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> ---
> This is version 2 of this patch.  I was told that eieio doesn't order
> loads from main memory, so a sync is used instead.  Also, due to
> objectons that iobarrier_* shouldn't be used for main memory, I used
> eieio() instead (a wmb() would be unnecessarily heavy).

I'd rather see a wmb() instead of eieio() to keep this code non-ppc  
specific.  (also, we implement wmb as eieio, so I don't keep the  
comment about it being too heavy, unless you mean generically).

- k

>
>  drivers/net/gianfar.c |    3 +++
>  1 files changed, 3 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
> index b666a0c..b014d27 100644
> --- a/drivers/net/gianfar.c
> +++ b/drivers/net/gianfar.c
> @@ -1025,6 +1025,7 @@ static int gfar_start_xmit(struct sk_buff  
> *skb, struct net_device *dev)
>
>  	dev->trans_start = jiffies;
>
> +	eieio();
>  	txbdp->status = status;
>
>  	/* If this was the last BD in the ring, the next one */
> @@ -1301,6 +1302,7 @@ struct sk_buff * gfar_new_skb(struct  
> net_device *dev, struct rxbd8 *bdp)
>  	bdp->length = 0;
>
>  	/* Mark the buffer empty */
> +	eieio();
>  	bdp->status |= (RXBD_EMPTY | RXBD_INTERRUPT);
>
>  	return skb;
> @@ -1484,6 +1486,7 @@ int gfar_clean_rx_ring(struct net_device  
> *dev, int rx_work_limit)
>  	bdp = priv->cur_rx;
>
>  	while (!((bdp->status & RXBD_EMPTY) || (--rx_work_limit < 0))) {
> +		rmb();
>  		skb = priv->rx_skbuff[priv->skb_currx];
>
>  		if (!(bdp->status &
> -- 
> 1.5.0.3
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* RE: PTE entries
From: Siva Prasad @ 2007-05-02 19:58 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, linuxppc-embedded
In-Reply-To: <1177473008.14873.181.camel@localhost.localdomain>

Hi Ben,

First,=20
Are there any other places where we have self modifying code in Linux
kernel, other than in arch/powerpc/mm/ppc_mmu_32.c:MMU_init_hw()
(basically modified create_hpte and flush_hash_page)

Second,
Instead of using addis, why can't we move it from SDR1 register and mask
the second half. SDR1 has the required value. Right?
May be I am missing something here.

Thanks
- Siva


-----Original Message-----
From: Benjamin Herrenschmidt [mailto:benh@kernel.crashing.org]=20
Sent: Tuesday, April 24, 2007 8:50 PM
To: Siva Prasad
Cc: linuxppc-dev@ozlabs.org; linuxppc-embedded@ozlabs.org
Subject: RE: PTE entries

On Tue, 2007-04-24 at 20:34 -0700, Siva Prasad wrote:
> Thanks Ben.
>=20
> I managed to fix this. I am working on how best we can rewrite the
self
> modifying code we have for create_hpte routine. I would prefer to read
> from SDR1, than to hardcode (or self modify the code) the way it is
done
> now.
>=20
> Feel free to let me know what you think.

Self-modifying allows better performances in that very critical code
path...

Why would you need to change that code anyway ?

Ben.

^ permalink raw reply

* [PATCH v2] gianfar: Add I/O barriers when touching buffer descriptor ownership.
From: Scott Wood @ 2007-05-02 19:57 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev

The hardware must not see that is given ownership of a buffer until it is
completely written, and when the driver receives ownership of a buffer,
it must ensure that any other reads to the buffer reflect its final
state.  Thus, I/O barriers are added where required.

Without this patch, I have observed GCC reordering the setting of
bdp->length and bdp->status in gfar_new_skb.

Signed-off-by: Scott Wood <scottwood@freescale.com>
---
This is version 2 of this patch.  I was told that eieio doesn't order
loads from main memory, so a sync is used instead.  Also, due to
objectons that iobarrier_* shouldn't be used for main memory, I used
eieio() instead (a wmb() would be unnecessarily heavy).

 drivers/net/gianfar.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index b666a0c..b014d27 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -1025,6 +1025,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	dev->trans_start = jiffies;
 
+	eieio();
 	txbdp->status = status;
 
 	/* If this was the last BD in the ring, the next one */
@@ -1301,6 +1302,7 @@ struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp)
 	bdp->length = 0;
 
 	/* Mark the buffer empty */
+	eieio();
 	bdp->status |= (RXBD_EMPTY | RXBD_INTERRUPT);
 
 	return skb;
@@ -1484,6 +1486,7 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
 	bdp = priv->cur_rx;
 
 	while (!((bdp->status & RXBD_EMPTY) || (--rx_work_limit < 0))) {
+		rmb();
 		skb = priv->rx_skbuff[priv->skb_currx];
 
 		if (!(bdp->status &
-- 
1.5.0.3

^ permalink raw reply related

* [PATCH] ucc_geth: eliminate max-speed, change interface-type to phy-connection-type
From: Kim Phillips @ 2007-05-02 19:21 UTC (permalink / raw)
  To: jeff; +Cc: netdev, linuxppc-dev

It was agreed that phy-connection-type was a better name for
the interface-type property, so this patch renames it.

Also, the max-speed property name was determined too generic,
and is therefore eliminated in favour of phy-connection-type
derivation logic.

includes corrections to copyright text.

Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
---
Jeff, this patch depends on Stephen Rothwell's 
  "[PATCH 2/2] Rename get_property to of_get_property: drivers"
patch dated Tue, 1 May 2007 13:54:02 +1000

 drivers/net/ucc_geth.c     |   40 ++++++++++++++++------------------------
 drivers/net/ucc_geth_mii.c |    9 +++++----
 drivers/net/ucc_geth_mii.h |   10 +++++-----
 3 files changed, 26 insertions(+), 33 deletions(-)

diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index d7aff81..361eca0 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
+ * Copyright (C) 2006-2007 Freescale Semicondutor, Inc. All rights reserved.
  *
  * Author: Shlomi Gridish <gridish@freescale.com>
  *	   Li Yang <leoli@freescale.com>
@@ -3737,21 +3737,21 @@ static int ucc_geth_close(struct net_device *dev)
 
 const struct ethtool_ops ucc_geth_ethtool_ops = { };
 
-static phy_interface_t to_phy_interface(const char *interface_type)
+static phy_interface_t to_phy_interface(const char *phy_connection_type)
 {
-	if (strcasecmp(interface_type, "mii") == 0)
+	if (strcasecmp(phy_connection_type, "mii") == 0)
 		return PHY_INTERFACE_MODE_MII;
-	if (strcasecmp(interface_type, "gmii") == 0)
+	if (strcasecmp(phy_connection_type, "gmii") == 0)
 		return PHY_INTERFACE_MODE_GMII;
-	if (strcasecmp(interface_type, "tbi") == 0)
+	if (strcasecmp(phy_connection_type, "tbi") == 0)
 		return PHY_INTERFACE_MODE_TBI;
-	if (strcasecmp(interface_type, "rmii") == 0)
+	if (strcasecmp(phy_connection_type, "rmii") == 0)
 		return PHY_INTERFACE_MODE_RMII;
-	if (strcasecmp(interface_type, "rgmii") == 0)
+	if (strcasecmp(phy_connection_type, "rgmii") == 0)
 		return PHY_INTERFACE_MODE_RGMII;
-	if (strcasecmp(interface_type, "rgmii-id") == 0)
+	if (strcasecmp(phy_connection_type, "rgmii-id") == 0)
 		return PHY_INTERFACE_MODE_RGMII_ID;
-	if (strcasecmp(interface_type, "rtbi") == 0)
+	if (strcasecmp(phy_connection_type, "rtbi") == 0)
 		return PHY_INTERFACE_MODE_RTBI;
 
 	return PHY_INTERFACE_MODE_MII;
@@ -3819,29 +3819,21 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
 	ug_info->phy_address = *prop;
 
 	/* get the phy interface type, or default to MII */
-	prop = of_get_property(np, "interface-type", NULL);
+	prop = of_get_property(np, "phy-connection-type", NULL);
 	if (!prop) {
 		/* handle interface property present in old trees */
 		prop = of_get_property(phy, "interface", NULL);
-		if (prop != NULL)
+		if (prop != NULL) {
 			phy_interface = enet_to_phy_interface[*prop];
-		else
+			max_speed = enet_to_speed[*prop];
+		} else
 			phy_interface = PHY_INTERFACE_MODE_MII;
 	} else {
 		phy_interface = to_phy_interface((const char *)prop);
 	}
 
-	/* get speed, or derive from interface */
-	prop = of_get_property(np, "max-speed", NULL);
-	if (!prop) {
-		/* handle interface property present in old trees */
-		prop = of_get_property(phy, "interface", NULL);
-		if (prop != NULL)
-			max_speed = enet_to_speed[*prop];
-	} else {
-		max_speed = *prop;
-	}
-	if (!max_speed) {
+	/* get speed, or derive from PHY interface */
+	if (max_speed == 0)
 		switch (phy_interface) {
 		case PHY_INTERFACE_MODE_GMII:
 		case PHY_INTERFACE_MODE_RGMII:
@@ -3854,9 +3846,9 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
 			max_speed = SPEED_100;
 			break;
 		}
-	}
 
 	if (max_speed == SPEED_1000) {
+		/* configure muram FIFOs for gigabit operation */
 		ug_info->uf_info.urfs = UCC_GETH_URFS_GIGA_INIT;
 		ug_info->uf_info.urfet = UCC_GETH_URFET_GIGA_INIT;
 		ug_info->uf_info.urfset = UCC_GETH_URFSET_GIGA_INIT;
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c
index 27a1ef3..f96966d 100644
--- a/drivers/net/ucc_geth_mii.c
+++ b/drivers/net/ucc_geth_mii.c
@@ -1,12 +1,13 @@
 /*
  * drivers/net/ucc_geth_mii.c
  *
- * Gianfar Ethernet Driver -- MIIM bus implementation
- * Provides Bus interface for MIIM regs
+ * QE UCC Gigabit Ethernet Driver -- MII Management Bus Implementation
+ * Provides Bus interface for MII Management regs in the UCC register space
  *
- * Author: Li Yang
+ * Copyright (C) 2007 Freescale Semiconductor, Inc.
  *
- * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
+ * Authors: Li Yang <leoli@freescale.com>
+ *	    Kim Phillips <kim.phillips@freescale.com>
  *
  * 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
diff --git a/drivers/net/ucc_geth_mii.h b/drivers/net/ucc_geth_mii.h
index 98430fe..d834370 100644
--- a/drivers/net/ucc_geth_mii.h
+++ b/drivers/net/ucc_geth_mii.h
@@ -1,13 +1,13 @@
 /*
  * drivers/net/ucc_geth_mii.h
  *
- * Gianfar Ethernet Driver -- MII Management Bus Implementation
- * Driver for the MDIO bus controller in the Gianfar register space
+ * QE UCC Gigabit Ethernet Driver -- MII Management Bus Implementation
+ * Provides Bus interface for MII Management regs in the UCC register space
  *
- * Author: Andy Fleming
- * Maintainer: Kumar Gala
+ * Copyright (C) 2007 Freescale Semiconductor, Inc.
  *
- * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
+ * Authors: Li Yang <leoli@freescale.com>
+ *	    Kim Phillips <kim.phillips@freescale.com>
  *
  * 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
-- 
1.5.0.3

^ permalink raw reply related


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