* [PATCH 1/13] powerpc: Add Makefile rule to wrap dts file in zImage
2007-04-25 23:46 [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800 Mark A. Greer
@ 2007-04-25 23:55 ` Mark A. Greer
2007-04-30 6:06 ` David Gibson
2007-04-25 23:55 ` [PATCH 2/13] powerpc: Add dt_xlate_addr() to bootwrapper Mark A. Greer
` (12 subsequent siblings)
13 siblings, 1 reply; 87+ messages in thread
From: Mark A. Greer @ 2007-04-25 23:55 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
Add 'zImage.dts' and 'zImage.dts_initrd' build rules that automatically
compile and wrap a dts file into the zImage file. The rules are similar
to the initrd rules.
The dts file is expected to be arch/powerpc/boot/dts/$(CONFIG_DEVICE_TREE)
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
---
Makefile | 2 +-
boot/Makefile | 24 +++++++++++++++++++++++-
2 files changed, 24 insertions(+), 2 deletions(-)
Index: powerpc/arch/powerpc/boot/Makefile
===================================================================
--- powerpc.orig/arch/powerpc/boot/Makefile
+++ powerpc/arch/powerpc/boot/Makefile
@@ -144,9 +144,27 @@ targets += $(image-y) $(initrd-y)
$(addprefix $(obj)/, $(initrd-y)): $(obj)/ramdisk.image.gz
+dts- := $(patsubst zImage%, zImage.dts%, $(image-n) $(image-))
+dts-y := $(patsubst zImage%, zImage.dts%, $(image-y))
+dts-y := $(filter-out $(image-y), $(dts-y))
+targets += $(image-y) $(dts-y)
+
+dts_initrd- := $(patsubst zImage%, zImage.dts_initrd%, $(image-n) $(image-))
+dts_initrd-y := $(patsubst zImage%, zImage.dts_initrd%, $(image-y))
+dts_initrd-y := $(filter-out $(image-y), $(dts_initrd-y))
+targets += $(image-y) $(dts_initrd-y)
+
+$(addprefix $(obj)/, $(dts_initrd-y)): $(obj)/ramdisk.image.gz
+
# Don't put the ramdisk on the pattern rule; when its missing make will try
# the pattern rule with less dependencies that also matches (even with the
# hard dependency listed).
+$(obj)/zImage.dts_initrd.%: vmlinux $(wrapperbits)
+ $(call if_changed,wrap,$*,$(dts),,$(obj)/ramdisk.image.gz)
+
+$(obj)/zImage.dts.%: vmlinux $(wrapperbits)
+ $(call if_changed,wrap,$*,$(dts))
+
$(obj)/zImage.initrd.%: vmlinux $(wrapperbits)
$(call if_changed,wrap,$*,,,$(obj)/ramdisk.image.gz)
@@ -175,13 +193,17 @@ $(obj)/zImage: $(addprefix $(obj)/, $(i
@rm -f $@; ln $< $@
$(obj)/zImage.initrd: $(addprefix $(obj)/, $(initrd-y))
@rm -f $@; ln $< $@
+$(obj)/zImage.dts: $(addprefix $(obj)/, $(dts-y))
+ @rm -f $@; ln $< $@
+$(obj)/zImage.dts_initrd: $(addprefix $(obj)/, $(dts_initrd-y))
+ @rm -f $@; ln $< $@
install: $(CONFIGURE) $(image-y)
sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $<
# anything not in $(targets)
clean-files += $(image-) $(initrd-) zImage zImage.initrd \
- cuImage.elf cuImage.bin.gz
+ cuImage.elf cuImage.bin.gz zImage.dts zImage.dts_initrd
# clean up files cached by wrapper
clean-kernel := vmlinux.strip vmlinux.bin
Index: powerpc/arch/powerpc/Makefile
===================================================================
--- powerpc.orig/arch/powerpc/Makefile
+++ powerpc/arch/powerpc/Makefile
@@ -148,7 +148,7 @@ all: $(KBUILD_IMAGE)
CPPFLAGS_vmlinux.lds := -Upowerpc
-BOOT_TARGETS = zImage zImage.initrd uImage cuImage
+BOOT_TARGETS = zImage zImage.initrd zImage.dts zImage.dts_initrd uImage cuImage
PHONY += $(BOOT_TARGETS)
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 1/13] powerpc: Add Makefile rule to wrap dts file in zImage
2007-04-25 23:55 ` [PATCH 1/13] powerpc: Add Makefile rule to wrap dts file in zImage Mark A. Greer
@ 2007-04-30 6:06 ` David Gibson
0 siblings, 0 replies; 87+ messages in thread
From: David Gibson @ 2007-04-30 6:06 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev, Paul Mackerras
On Wed, Apr 25, 2007 at 04:55:04PM -0700, Mark A. Greer wrote:
> Add 'zImage.dts' and 'zImage.dts_initrd' build rules that automatically
> compile and wrap a dts file into the zImage file. The rules are similar
> to the initrd rules.
>
> The dts file is expected to be arch/powerpc/boot/dts/$(CONFIG_DEVICE_TREE)
Hrm. It would make more sense to extend the existing zImage.% rule to
pass in the dts (making sure it still works with no dts, obviously).
We shouldn't need this two-level indirection of make targets, either
through dts-y, see my recent patch of cuboot cleanups to see how I
removed that for Scott Wood's cuboot stuff.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply [flat|nested] 87+ messages in thread
* [PATCH 2/13] powerpc: Add dt_xlate_addr() to bootwrapper
2007-04-25 23:46 [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800 Mark A. Greer
2007-04-25 23:55 ` [PATCH 1/13] powerpc: Add Makefile rule to wrap dts file in zImage Mark A. Greer
@ 2007-04-25 23:55 ` Mark A. Greer
2007-04-26 16:44 ` Scott Wood
2007-04-27 5:55 ` Paul Mackerras
2007-04-25 23:56 ` [PATCH 3/13] powerpc: Add bootwrapper support for Marvell/mv64x60 hostbridge Mark A. Greer
` (11 subsequent siblings)
13 siblings, 2 replies; 87+ messages in thread
From: Mark A. Greer @ 2007-04-25 23:55 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
dt_xlate_reg() looks up the 'reg' property in the specified node
to get the address and size to translate. Add dt_xlate_addr()
which is passed in the address and size to translate.
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
---
devtree.c | 45 ++++++++++++++++++++++++++++++++-------------
ops.h | 4 ++--
2 files changed, 34 insertions(+), 15 deletions(-)
Index: powerpc/arch/powerpc/boot/devtree.c
===================================================================
--- powerpc.orig/arch/powerpc/boot/devtree.c
+++ powerpc/arch/powerpc/boot/devtree.c
@@ -205,12 +205,13 @@ static int find_range(u32 *reg, u32 *ran
* In particular, PCI is not supported. Also, only the beginning of the
* reg block is tracked; size is ignored except in ranges.
*/
-int dt_xlate_reg(void *node, int res, unsigned long *addr,
- unsigned long *size)
+static u32 dt_xlate_buf[MAX_ADDR_CELLS * MAX_RANGES * 3];
+
+static int dt_xlate(void *node, int res, int reglen, unsigned long *addr,
+ unsigned long *size)
{
u32 last_addr[MAX_ADDR_CELLS];
u32 this_addr[MAX_ADDR_CELLS];
- u32 buf[MAX_ADDR_CELLS * MAX_RANGES * 3];
void *parent;
u64 ret_addr, ret_size;
u32 naddr, nsize, prev_naddr;
@@ -225,18 +226,17 @@ int dt_xlate_reg(void *node, int res, un
if (nsize > 2)
return 0;
- buflen = getprop(node, "reg", buf, sizeof(buf)) / 4;
offset = (naddr + nsize) * res;
- if (buflen < offset + naddr + nsize)
+ if (reglen < offset + naddr + nsize)
return 0;
- copy_val(last_addr, buf + offset, naddr);
+ copy_val(last_addr, dt_xlate_buf + offset, naddr);
- ret_size = buf[offset + naddr];
+ ret_size = dt_xlate_buf[offset + naddr];
if (nsize == 2) {
ret_size <<= 32;
- ret_size |= buf[offset + naddr + 1];
+ ret_size |= dt_xlate_buf[offset + naddr + 1];
}
while ((node = get_parent(node))) {
@@ -244,24 +244,25 @@ int dt_xlate_reg(void *node, int res, un
get_reg_format(node, &naddr, &nsize);
- buflen = getprop(node, "ranges", buf, sizeof(buf));
+ buflen = getprop(node, "ranges", dt_xlate_buf,
+ sizeof(dt_xlate_buf));
if (buflen < 0)
continue;
- if (buflen > sizeof(buf))
+ if (buflen > sizeof(dt_xlate_buf))
return 0;
- offset = find_range(last_addr, buf, prev_naddr,
+ offset = find_range(last_addr, dt_xlate_buf, prev_naddr,
naddr, nsize, buflen / 4);
if (offset < 0)
return 0;
- copy_val(this_addr, buf + offset, prev_naddr);
+ copy_val(this_addr, dt_xlate_buf + offset, prev_naddr);
if (!sub_reg(last_addr, this_addr))
return 0;
- copy_val(this_addr, buf + offset + prev_naddr, naddr);
+ copy_val(this_addr, dt_xlate_buf + offset + prev_naddr, naddr);
if (!add_reg(last_addr, this_addr))
return 0;
@@ -287,3 +288,21 @@ int dt_xlate_reg(void *node, int res, un
return 1;
}
+
+int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size)
+{
+ int reglen;
+
+ reglen = getprop(node, "reg", dt_xlate_buf, sizeof(dt_xlate_buf)) / 4;
+ return dt_xlate(node, res, reglen, addr, size);
+}
+
+int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr)
+{
+
+ if (buflen > sizeof(dt_xlate_buf))
+ return 0;
+
+ memcpy(dt_xlate_buf, buf, buflen);
+ return dt_xlate(node, 0, buflen / 4, xlated_addr, NULL);
+}
Index: powerpc/arch/powerpc/boot/ops.h
===================================================================
--- powerpc.orig/arch/powerpc/boot/ops.h
+++ powerpc/arch/powerpc/boot/ops.h
@@ -82,8 +82,8 @@ int ns16550_console_init(void *devp, str
void *simple_alloc_init(char *base, unsigned long heap_size,
unsigned long granularity, unsigned long max_allocs);
extern void flush_cache(void *, unsigned long);
-int dt_xlate_reg(void *node, int res, unsigned long *addr,
- unsigned long *size);
+int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size);
+int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr);
static inline void *finddevice(const char *name)
{
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 2/13] powerpc: Add dt_xlate_addr() to bootwrapper
2007-04-25 23:55 ` [PATCH 2/13] powerpc: Add dt_xlate_addr() to bootwrapper Mark A. Greer
@ 2007-04-26 16:44 ` Scott Wood
2007-04-27 5:55 ` Paul Mackerras
1 sibling, 0 replies; 87+ messages in thread
From: Scott Wood @ 2007-04-26 16:44 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev, Paul Mackerras
On Wed, Apr 25, 2007 at 04:55:43PM -0700, Mark A. Greer wrote:
> dt_xlate_reg() looks up the 'reg' property in the specified node
> to get the address and size to translate. Add dt_xlate_addr()
> which is passed in the address and size to translate.
There's an extra blank line in dt_xlate_addr, but otherwise:
Acked-by: Scott Wood <scottwood@freescale.com>
-Scott
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 2/13] powerpc: Add dt_xlate_addr() to bootwrapper
2007-04-25 23:55 ` [PATCH 2/13] powerpc: Add dt_xlate_addr() to bootwrapper Mark A. Greer
2007-04-26 16:44 ` Scott Wood
@ 2007-04-27 5:55 ` Paul Mackerras
2007-04-27 20:48 ` Mark A. Greer
1 sibling, 1 reply; 87+ messages in thread
From: Paul Mackerras @ 2007-04-27 5:55 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev
Mark A. Greer writes:
> dt_xlate_reg() looks up the 'reg' property in the specified node
> to get the address and size to translate. Add dt_xlate_addr()
> which is passed in the address and size to translate.
Could you rebase on top of Scott Wood's patch fixing bugs in
dt_xlate_reg please?
Paul.
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 2/13] powerpc: Add dt_xlate_addr() to bootwrapper
2007-04-27 5:55 ` Paul Mackerras
@ 2007-04-27 20:48 ` Mark A. Greer
0 siblings, 0 replies; 87+ messages in thread
From: Mark A. Greer @ 2007-04-27 20:48 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
dt_xlate_reg() looks up the 'reg' property in the specified node
to get the address and size to translate. Add dt_xlate_addr()
which is passed in the address and size to translate.
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
---
Paul, this should apply on top of Scott's patch.
devtree.c | 47 +++++++++++++++++++++++++++++++++--------------
ops.h | 4 ++--
2 files changed, 35 insertions(+), 16 deletions(-)
Index: powerpc/arch/powerpc/boot/devtree.c
===================================================================
--- powerpc.orig/arch/powerpc/boot/devtree.c
+++ powerpc/arch/powerpc/boot/devtree.c
@@ -207,12 +207,13 @@ static int find_range(u32 *reg, u32 *ran
* In particular, PCI is not supported. Also, only the beginning of the
* reg block is tracked; size is ignored except in ranges.
*/
-int dt_xlate_reg(void *node, int res, unsigned long *addr,
- unsigned long *size)
+static u32 dt_xlate_buf[MAX_ADDR_CELLS * MAX_RANGES * 3];
+
+static int dt_xlate(void *node, int res, int reglen, unsigned long *addr,
+ unsigned long *size)
{
u32 last_addr[MAX_ADDR_CELLS];
u32 this_addr[MAX_ADDR_CELLS];
- u32 buf[MAX_ADDR_CELLS * MAX_RANGES * 3];
void *parent;
u64 ret_addr, ret_size;
u32 naddr, nsize, prev_naddr;
@@ -227,19 +228,18 @@ int dt_xlate_reg(void *node, int res, un
if (nsize > 2)
return 0;
- buflen = getprop(node, "reg", buf, sizeof(buf)) / 4;
offset = (naddr + nsize) * res;
- if (buflen < offset + naddr + nsize ||
- sizeof(buf) < offset + naddr + nsize)
+ if (reglen < offset + naddr + nsize ||
+ sizeof(dt_xlate_buf) < offset + naddr + nsize)
return 0;
- copy_val(last_addr, buf + offset, naddr);
+ copy_val(last_addr, dt_xlate_buf + offset, naddr);
- ret_size = buf[offset + naddr];
+ ret_size = dt_xlate_buf[offset + naddr];
if (nsize == 2) {
ret_size <<= 32;
- ret_size |= buf[offset + naddr + 1];
+ ret_size |= dt_xlate_buf[offset + naddr + 1];
}
while ((node = get_parent(node))) {
@@ -247,24 +247,25 @@ int dt_xlate_reg(void *node, int res, un
get_reg_format(node, &naddr, &nsize);
- buflen = getprop(node, "ranges", buf, sizeof(buf));
+ buflen = getprop(node, "ranges", dt_xlate_buf,
+ sizeof(dt_xlate_buf));
if (buflen < 0)
continue;
- if (buflen > sizeof(buf))
+ if (buflen > sizeof(dt_xlate_buf))
return 0;
- offset = find_range(last_addr, buf, prev_naddr,
+ offset = find_range(last_addr, dt_xlate_buf, prev_naddr,
naddr, nsize, buflen / 4);
if (offset < 0)
return 0;
- copy_val(this_addr, buf + offset, prev_naddr);
+ copy_val(this_addr, dt_xlate_buf + offset, prev_naddr);
if (!sub_reg(last_addr, this_addr))
return 0;
- copy_val(this_addr, buf + offset + prev_naddr, naddr);
+ copy_val(this_addr, dt_xlate_buf + offset + prev_naddr, naddr);
if (!add_reg(last_addr, this_addr, naddr))
return 0;
@@ -286,3 +287,21 @@ int dt_xlate_reg(void *node, int res, un
return 1;
}
+
+int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size)
+{
+ int reglen;
+
+ reglen = getprop(node, "reg", dt_xlate_buf, sizeof(dt_xlate_buf)) / 4;
+ return dt_xlate(node, res, reglen, addr, size);
+}
+
+int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr)
+{
+
+ if (buflen > sizeof(dt_xlate_buf))
+ return 0;
+
+ memcpy(dt_xlate_buf, buf, buflen);
+ return dt_xlate(node, 0, buflen / 4, xlated_addr, NULL);
+}
Index: powerpc/arch/powerpc/boot/ops.h
===================================================================
--- powerpc.orig/arch/powerpc/boot/ops.h
+++ powerpc/arch/powerpc/boot/ops.h
@@ -82,8 +82,8 @@ int ns16550_console_init(void *devp, str
void *simple_alloc_init(char *base, unsigned long heap_size,
unsigned long granularity, unsigned long max_allocs);
extern void flush_cache(void *, unsigned long);
-int dt_xlate_reg(void *node, int res, unsigned long *addr,
- unsigned long *size);
+int dt_xlate_reg(void *node, int res, unsigned long *addr, unsigned long *size);
+int dt_xlate_addr(void *node, u32 *buf, int buflen, unsigned long *xlated_addr);
static inline void *finddevice(const char *name)
{
^ permalink raw reply [flat|nested] 87+ messages in thread
* [PATCH 3/13] powerpc: Add bootwrapper support for Marvell/mv64x60 hostbridge
2007-04-25 23:46 [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800 Mark A. Greer
2007-04-25 23:55 ` [PATCH 1/13] powerpc: Add Makefile rule to wrap dts file in zImage Mark A. Greer
2007-04-25 23:55 ` [PATCH 2/13] powerpc: Add dt_xlate_addr() to bootwrapper Mark A. Greer
@ 2007-04-25 23:56 ` Mark A. Greer
2007-04-27 6:01 ` Paul Mackerras
2007-04-25 23:57 ` [PATCH 4/13] powerpc: Add bootwrapper support for Marvell MPSC Mark A. Greer
` (10 subsequent siblings)
13 siblings, 1 reply; 87+ messages in thread
From: Mark A. Greer @ 2007-04-25 23:56 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
---
Makefile | 2
mv64x60.c | 581 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
mv64x60.h | 70 +++++++
3 files changed, 652 insertions(+), 1 deletion(-)
Index: powerpc/arch/powerpc/boot/mv64x60.c
===================================================================
--- /dev/null
+++ powerpc/arch/powerpc/boot/mv64x60.c
@@ -0,0 +1,581 @@
+/*
+ * Marvell hostbridge routines
+ *
+ * Author: Mark A. Greer <source@mvista.com>
+ *
+ * 2004, 2005, 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 <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "elf.h"
+#include "page.h"
+#include "string.h"
+#include "stdio.h"
+#include "io.h"
+#include "ops.h"
+#include "mv64x60.h"
+
+#define PCI_DEVFN(slot,func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
+
+#define MV64x60_CPU2MEM_WINDOWS 4
+#define MV64x60_CPU2MEM_0_BASE 0x0008
+#define MV64x60_CPU2MEM_0_SIZE 0x0010
+#define MV64x60_CPU2MEM_1_BASE 0x0208
+#define MV64x60_CPU2MEM_1_SIZE 0x0210
+#define MV64x60_CPU2MEM_2_BASE 0x0018
+#define MV64x60_CPU2MEM_2_SIZE 0x0020
+#define MV64x60_CPU2MEM_3_BASE 0x0218
+#define MV64x60_CPU2MEM_3_SIZE 0x0220
+
+#define MV64x60_ENET2MEM_BAR_ENABLE 0x2290
+#define MV64x60_ENET2MEM_0_BASE 0x2200
+#define MV64x60_ENET2MEM_0_SIZE 0x2204
+#define MV64x60_ENET2MEM_1_BASE 0x2208
+#define MV64x60_ENET2MEM_1_SIZE 0x220c
+#define MV64x60_ENET2MEM_2_BASE 0x2210
+#define MV64x60_ENET2MEM_2_SIZE 0x2214
+#define MV64x60_ENET2MEM_3_BASE 0x2218
+#define MV64x60_ENET2MEM_3_SIZE 0x221c
+#define MV64x60_ENET2MEM_4_BASE 0x2220
+#define MV64x60_ENET2MEM_4_SIZE 0x2224
+#define MV64x60_ENET2MEM_5_BASE 0x2228
+#define MV64x60_ENET2MEM_5_SIZE 0x222c
+#define MV64x60_ENET2MEM_ACC_PROT_0 0x2294
+#define MV64x60_ENET2MEM_ACC_PROT_1 0x2298
+#define MV64x60_ENET2MEM_ACC_PROT_2 0x229c
+
+#define MV64x60_MPSC2MEM_BAR_ENABLE 0xf250
+#define MV64x60_MPSC2MEM_0_BASE 0xf200
+#define MV64x60_MPSC2MEM_0_SIZE 0xf204
+#define MV64x60_MPSC2MEM_1_BASE 0xf208
+#define MV64x60_MPSC2MEM_1_SIZE 0xf20c
+#define MV64x60_MPSC2MEM_2_BASE 0xf210
+#define MV64x60_MPSC2MEM_2_SIZE 0xf214
+#define MV64x60_MPSC2MEM_3_BASE 0xf218
+#define MV64x60_MPSC2MEM_3_SIZE 0xf21c
+#define MV64x60_MPSC_0_REMAP 0xf240
+#define MV64x60_MPSC_1_REMAP 0xf244
+#define MV64x60_MPSC2MEM_ACC_PROT_0 0xf254
+#define MV64x60_MPSC2MEM_ACC_PROT_1 0xf258
+#define MV64x60_MPSC2REGS_BASE 0xf25c
+
+#define MV64x60_IDMA2MEM_BAR_ENABLE 0x0a80
+#define MV64x60_IDMA2MEM_0_BASE 0x0a00
+#define MV64x60_IDMA2MEM_0_SIZE 0x0a04
+#define MV64x60_IDMA2MEM_1_BASE 0x0a08
+#define MV64x60_IDMA2MEM_1_SIZE 0x0a0c
+#define MV64x60_IDMA2MEM_2_BASE 0x0a10
+#define MV64x60_IDMA2MEM_2_SIZE 0x0a14
+#define MV64x60_IDMA2MEM_3_BASE 0x0a18
+#define MV64x60_IDMA2MEM_3_SIZE 0x0a1c
+#define MV64x60_IDMA2MEM_4_BASE 0x0a20
+#define MV64x60_IDMA2MEM_4_SIZE 0x0a24
+#define MV64x60_IDMA2MEM_5_BASE 0x0a28
+#define MV64x60_IDMA2MEM_5_SIZE 0x0a2c
+#define MV64x60_IDMA2MEM_6_BASE 0x0a30
+#define MV64x60_IDMA2MEM_6_SIZE 0x0a34
+#define MV64x60_IDMA2MEM_7_BASE 0x0a38
+#define MV64x60_IDMA2MEM_7_SIZE 0x0a3c
+#define MV64x60_IDMA2MEM_ACC_PROT_0 0x0a70
+#define MV64x60_IDMA2MEM_ACC_PROT_1 0x0a74
+#define MV64x60_IDMA2MEM_ACC_PROT_2 0x0a78
+#define MV64x60_IDMA2MEM_ACC_PROT_3 0x0a7c
+
+#define MV64x60_PCI_ACC_CNTL_WINDOWS 6
+#define MV64x60_PCI0_PCI_DECODE_CNTL 0x0d3c
+#define MV64x60_PCI1_PCI_DECODE_CNTL 0x0dbc
+
+#define MV64x60_PCI0_BAR_ENABLE 0x0c3c
+#define MV64x60_PCI02MEM_0_SIZE 0x0c08
+#define MV64x60_PCI0_ACC_CNTL_0_BASE_LO 0x1e00
+#define MV64x60_PCI0_ACC_CNTL_0_BASE_HI 0x1e04
+#define MV64x60_PCI0_ACC_CNTL_0_SIZE 0x1e08
+#define MV64x60_PCI0_ACC_CNTL_1_BASE_LO 0x1e10
+#define MV64x60_PCI0_ACC_CNTL_1_BASE_HI 0x1e14
+#define MV64x60_PCI0_ACC_CNTL_1_SIZE 0x1e18
+#define MV64x60_PCI0_ACC_CNTL_2_BASE_LO 0x1e20
+#define MV64x60_PCI0_ACC_CNTL_2_BASE_HI 0x1e24
+#define MV64x60_PCI0_ACC_CNTL_2_SIZE 0x1e28
+#define MV64x60_PCI0_ACC_CNTL_3_BASE_LO 0x1e30
+#define MV64x60_PCI0_ACC_CNTL_3_BASE_HI 0x1e34
+#define MV64x60_PCI0_ACC_CNTL_3_SIZE 0x1e38
+#define MV64x60_PCI0_ACC_CNTL_4_BASE_LO 0x1e40
+#define MV64x60_PCI0_ACC_CNTL_4_BASE_HI 0x1e44
+#define MV64x60_PCI0_ACC_CNTL_4_SIZE 0x1e48
+#define MV64x60_PCI0_ACC_CNTL_5_BASE_LO 0x1e50
+#define MV64x60_PCI0_ACC_CNTL_5_BASE_HI 0x1e54
+#define MV64x60_PCI0_ACC_CNTL_5_SIZE 0x1e58
+
+#define MV64x60_PCI1_BAR_ENABLE 0x0cbc
+#define MV64x60_PCI12MEM_0_SIZE 0x0c88
+#define MV64x60_PCI1_ACC_CNTL_0_BASE_LO 0x1e80
+#define MV64x60_PCI1_ACC_CNTL_0_BASE_HI 0x1e84
+#define MV64x60_PCI1_ACC_CNTL_0_SIZE 0x1e88
+#define MV64x60_PCI1_ACC_CNTL_1_BASE_LO 0x1e90
+#define MV64x60_PCI1_ACC_CNTL_1_BASE_HI 0x1e94
+#define MV64x60_PCI1_ACC_CNTL_1_SIZE 0x1e98
+#define MV64x60_PCI1_ACC_CNTL_2_BASE_LO 0x1ea0
+#define MV64x60_PCI1_ACC_CNTL_2_BASE_HI 0x1ea4
+#define MV64x60_PCI1_ACC_CNTL_2_SIZE 0x1ea8
+#define MV64x60_PCI1_ACC_CNTL_3_BASE_LO 0x1eb0
+#define MV64x60_PCI1_ACC_CNTL_3_BASE_HI 0x1eb4
+#define MV64x60_PCI1_ACC_CNTL_3_SIZE 0x1eb8
+#define MV64x60_PCI1_ACC_CNTL_4_BASE_LO 0x1ec0
+#define MV64x60_PCI1_ACC_CNTL_4_BASE_HI 0x1ec4
+#define MV64x60_PCI1_ACC_CNTL_4_SIZE 0x1ec8
+#define MV64x60_PCI1_ACC_CNTL_5_BASE_LO 0x1ed0
+#define MV64x60_PCI1_ACC_CNTL_5_BASE_HI 0x1ed4
+#define MV64x60_PCI1_ACC_CNTL_5_SIZE 0x1ed8
+
+#define MV64x60_CPU2PCI_SWAP_NONE 0x01000000
+
+#define MV64x60_CPU2PCI0_IO_BASE 0x0048
+#define MV64x60_CPU2PCI0_IO_SIZE 0x0050
+#define MV64x60_CPU2PCI0_IO_REMAP 0x00f0
+#define MV64x60_CPU2PCI0_MEM_0_BASE 0x0058
+#define MV64x60_CPU2PCI0_MEM_0_SIZE 0x0060
+#define MV64x60_CPU2PCI0_MEM_0_REMAP_LO 0x00f8
+#define MV64x60_CPU2PCI0_MEM_0_REMAP_HI 0x0320
+
+#define MV64x60_CPU2PCI1_IO_BASE 0x0090
+#define MV64x60_CPU2PCI1_IO_SIZE 0x0098
+#define MV64x60_CPU2PCI1_IO_REMAP 0x0108
+#define MV64x60_CPU2PCI1_MEM_0_BASE 0x00a0
+#define MV64x60_CPU2PCI1_MEM_0_SIZE 0x00a8
+#define MV64x60_CPU2PCI1_MEM_0_REMAP_LO 0x0110
+#define MV64x60_CPU2PCI1_MEM_0_REMAP_HI 0x0340
+
+struct mv64x60_mem_win {
+ u32 hi;
+ u32 lo;
+ u32 size;
+};
+
+struct mv64x60_pci_win {
+ u32 fcn;
+ u32 hi;
+ u32 lo;
+ u32 size;
+};
+
+/* PCI config access routines */
+struct {
+ u32 addr;
+ u32 data;
+} static mv64x60_pci_cfgio[2] = {
+ { /* hose 0 */
+ .addr = 0xcf8,
+ .data = 0xcfc,
+ },
+ { /* hose 1 */
+ .addr = 0xc78,
+ .data = 0xc7c,
+ }
+};
+
+u32 mv64x60_cfg_read(u8 *bridge_base, u8 hose, u8 bus, u8 devfn, u8 offset)
+{
+ out_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].addr),
+ (1 << 31) | (bus << 16) | (devfn << 8) | offset);
+ return in_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].data));
+}
+
+void mv64x60_cfg_write(u8 *bridge_base, u8 hose, u8 bus, u8 devfn, u8 offset,
+ u32 val)
+{
+ out_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].addr),
+ (1 << 31) | (bus << 16) | (devfn << 8) | offset);
+ out_le32((u32 *)(bridge_base + mv64x60_pci_cfgio[hose].data), val);
+}
+
+/* I/O ctlr -> system memory setup */
+static struct mv64x60_mem_win mv64x60_cpu2mem[MV64x60_CPU2MEM_WINDOWS] = {
+ {
+ .lo = MV64x60_CPU2MEM_0_BASE,
+ .size = MV64x60_CPU2MEM_0_SIZE,
+ },
+ {
+ .lo = MV64x60_CPU2MEM_1_BASE,
+ .size = MV64x60_CPU2MEM_1_SIZE,
+ },
+ {
+ .lo = MV64x60_CPU2MEM_2_BASE,
+ .size = MV64x60_CPU2MEM_2_SIZE,
+ },
+ {
+ .lo = MV64x60_CPU2MEM_3_BASE,
+ .size = MV64x60_CPU2MEM_3_SIZE,
+ },
+};
+
+static struct mv64x60_mem_win mv64x60_enet2mem[MV64x60_CPU2MEM_WINDOWS] = {
+ {
+ .lo = MV64x60_ENET2MEM_0_BASE,
+ .size = MV64x60_ENET2MEM_0_SIZE,
+ },
+ {
+ .lo = MV64x60_ENET2MEM_1_BASE,
+ .size = MV64x60_ENET2MEM_1_SIZE,
+ },
+ {
+ .lo = MV64x60_ENET2MEM_2_BASE,
+ .size = MV64x60_ENET2MEM_2_SIZE,
+ },
+ {
+ .lo = MV64x60_ENET2MEM_3_BASE,
+ .size = MV64x60_ENET2MEM_3_SIZE,
+ },
+};
+
+static struct mv64x60_mem_win mv64x60_mpsc2mem[MV64x60_CPU2MEM_WINDOWS] = {
+ {
+ .lo = MV64x60_MPSC2MEM_0_BASE,
+ .size = MV64x60_MPSC2MEM_0_SIZE,
+ },
+ {
+ .lo = MV64x60_MPSC2MEM_1_BASE,
+ .size = MV64x60_MPSC2MEM_1_SIZE,
+ },
+ {
+ .lo = MV64x60_MPSC2MEM_2_BASE,
+ .size = MV64x60_MPSC2MEM_2_SIZE,
+ },
+ {
+ .lo = MV64x60_MPSC2MEM_3_BASE,
+ .size = MV64x60_MPSC2MEM_3_SIZE,
+ },
+};
+
+static struct mv64x60_mem_win mv64x60_idma2mem[MV64x60_CPU2MEM_WINDOWS] = {
+ {
+ .lo = MV64x60_IDMA2MEM_0_BASE,
+ .size = MV64x60_IDMA2MEM_0_SIZE,
+ },
+ {
+ .lo = MV64x60_IDMA2MEM_1_BASE,
+ .size = MV64x60_IDMA2MEM_1_SIZE,
+ },
+ {
+ .lo = MV64x60_IDMA2MEM_2_BASE,
+ .size = MV64x60_IDMA2MEM_2_SIZE,
+ },
+ {
+ .lo = MV64x60_IDMA2MEM_3_BASE,
+ .size = MV64x60_IDMA2MEM_3_SIZE,
+ },
+};
+
+static u32 mv64x60_dram_selects[MV64x60_CPU2MEM_WINDOWS] = {0xe,0xd,0xb,0x7};
+
+/*
+ * ENET, MPSC, and IDMA ctlrs on the MV64x60 have separate windows that
+ * must be set up so that the respective ctlr can access system memory.
+ * Configure them to be same as cpu->memory windows.
+ */
+void mv64x60_config_ctlr_windows(u8 *bridge_base, u8 *bridge_pbase,
+ u8 is_coherent)
+{
+ u32 i, base, size, enables, prot = 0, snoop_bits = 0;
+
+ /* Disable ctlr->mem windows */
+ out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_BAR_ENABLE), 0x3f);
+ out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_BAR_ENABLE), 0xf);
+ out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_BAR_ENABLE), 0xff);
+
+ if (is_coherent)
+ snoop_bits = 0x2 << 12; /* Writeback */
+
+ enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE)) & 0xf;
+
+ for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) {
+ if (enables & (1 << i)) /* Set means disabled */
+ continue;
+
+ base = in_le32((u32 *)(bridge_base + mv64x60_cpu2mem[i].lo))
+ << 16;
+ base |= snoop_bits | (mv64x60_dram_selects[i] << 8);
+ size = in_le32((u32 *)(bridge_base + mv64x60_cpu2mem[i].size))
+ << 16;
+ prot |= (0x3 << (i << 1)); /* RW access */
+
+ out_le32((u32 *)(bridge_base + mv64x60_enet2mem[i].lo), base);
+ out_le32((u32 *)(bridge_base + mv64x60_enet2mem[i].size), size);
+ out_le32((u32 *)(bridge_base + mv64x60_mpsc2mem[i].lo), base);
+ out_le32((u32 *)(bridge_base + mv64x60_mpsc2mem[i].size), size);
+ out_le32((u32 *)(bridge_base + mv64x60_idma2mem[i].lo), base);
+ out_le32((u32 *)(bridge_base + mv64x60_idma2mem[i].size), size);
+ }
+
+ out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_ACC_PROT_0), prot);
+ out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_ACC_PROT_1), prot);
+ out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_ACC_PROT_2), prot);
+ out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_ACC_PROT_0), prot);
+ out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_ACC_PROT_1), prot);
+ out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_0), prot);
+ out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_1), prot);
+ out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_2), prot);
+ out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_ACC_PROT_3), prot);
+
+ /* Set mpsc->bridge's reg window to the bridge's internal registers. */
+ out_le32((u32 *)(bridge_base + MV64x60_MPSC2REGS_BASE),
+ (u32)bridge_pbase);
+
+ out_le32((u32 *)(bridge_base + MV64x60_ENET2MEM_BAR_ENABLE), enables);
+ out_le32((u32 *)(bridge_base + MV64x60_MPSC2MEM_BAR_ENABLE), enables);
+ out_le32((u32 *)(bridge_base + MV64x60_IDMA2MEM_BAR_ENABLE), enables);
+}
+
+/* PCI MEM -> system memory, et. al. setup */
+static struct mv64x60_pci_win mv64x60_pci2mem[2] = {
+ { /* hose 0 */
+ .fcn = 0,
+ .hi = 0x14,
+ .lo = 0x10,
+ .size = MV64x60_PCI02MEM_0_SIZE,
+ },
+ { /* hose 1 */
+ .fcn = 0,
+ .hi = 0x94,
+ .lo = 0x90,
+ .size = MV64x60_PCI12MEM_0_SIZE,
+ },
+};
+
+static struct
+mv64x60_mem_win mv64x60_pci_acc[2][MV64x60_PCI_ACC_CNTL_WINDOWS] = {
+ { /* hose 0 */
+ {
+ .hi = MV64x60_PCI0_ACC_CNTL_0_BASE_HI,
+ .lo = MV64x60_PCI0_ACC_CNTL_0_BASE_LO,
+ .size = MV64x60_PCI0_ACC_CNTL_0_SIZE,
+ },
+ {
+ .hi = MV64x60_PCI0_ACC_CNTL_1_BASE_HI,
+ .lo = MV64x60_PCI0_ACC_CNTL_1_BASE_LO,
+ .size = MV64x60_PCI0_ACC_CNTL_1_SIZE,
+ },
+ {
+ .hi = MV64x60_PCI0_ACC_CNTL_2_BASE_HI,
+ .lo = MV64x60_PCI0_ACC_CNTL_2_BASE_LO,
+ .size = MV64x60_PCI0_ACC_CNTL_2_SIZE,
+ },
+ {
+ .hi = MV64x60_PCI0_ACC_CNTL_3_BASE_HI,
+ .lo = MV64x60_PCI0_ACC_CNTL_3_BASE_LO,
+ .size = MV64x60_PCI0_ACC_CNTL_3_SIZE,
+ },
+ },
+ { /* hose 1 */
+ {
+ .hi = MV64x60_PCI1_ACC_CNTL_0_BASE_HI,
+ .lo = MV64x60_PCI1_ACC_CNTL_0_BASE_LO,
+ .size = MV64x60_PCI1_ACC_CNTL_0_SIZE,
+ },
+ {
+ .hi = MV64x60_PCI1_ACC_CNTL_1_BASE_HI,
+ .lo = MV64x60_PCI1_ACC_CNTL_1_BASE_LO,
+ .size = MV64x60_PCI1_ACC_CNTL_1_SIZE,
+ },
+ {
+ .hi = MV64x60_PCI1_ACC_CNTL_2_BASE_HI,
+ .lo = MV64x60_PCI1_ACC_CNTL_2_BASE_LO,
+ .size = MV64x60_PCI1_ACC_CNTL_2_SIZE,
+ },
+ {
+ .hi = MV64x60_PCI1_ACC_CNTL_3_BASE_HI,
+ .lo = MV64x60_PCI1_ACC_CNTL_3_BASE_LO,
+ .size = MV64x60_PCI1_ACC_CNTL_3_SIZE,
+ },
+ },
+};
+
+static struct mv64x60_mem_win mv64x60_pci2reg[2] = {
+ {
+ .hi = 0x24,
+ .lo = 0x20,
+ .size = 0,
+ },
+ {
+ .hi = 0xa4,
+ .lo = 0xa0,
+ .size = 0,
+ },
+};
+
+/* Only need to use 1 window (per hose) to get access to all of system memory */
+void mv64x60_config_pci_windows(u8 *bridge_base, u8 *bridge_pbase, u8 hose,
+ u8 bus, u32 mem_size, u32 acc_bits)
+{
+ u32 i, offset, bar_enable, enables;
+
+ /* Disable all windows but PCI MEM -> Bridge's regs window */
+ enables = ~(1 << 9);
+ bar_enable = hose ? MV64x60_PCI1_BAR_ENABLE : MV64x60_PCI0_BAR_ENABLE;
+ out_le32((u32 *)(bridge_base + bar_enable), enables);
+
+ for (i=0; i<MV64x60_PCI_ACC_CNTL_WINDOWS; i++)
+ out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][i].lo), 0);
+
+ /* If mem_size is 0, leave windows disabled */
+ if (mem_size == 0)
+ return;
+
+ /* Cause automatic updates of PCI remap regs */
+ offset = hose ?
+ MV64x60_PCI1_PCI_DECODE_CNTL : MV64x60_PCI0_PCI_DECODE_CNTL;
+ i = in_le32((u32 *)(bridge_base + offset));
+ out_le32((u32 *)(bridge_base + offset), i & ~0x1);
+
+ mem_size = (mem_size - 1) & 0xfffff000;
+
+ /* Map PCI MEM addr 0 -> System Mem addr 0 */
+ mv64x60_cfg_write(bridge_base, hose, bus,
+ PCI_DEVFN(0, mv64x60_pci2mem[hose].fcn),
+ mv64x60_pci2mem[hose].hi, 0);
+ mv64x60_cfg_write(bridge_base, hose, bus,
+ PCI_DEVFN(0, mv64x60_pci2mem[hose].fcn),
+ mv64x60_pci2mem[hose].lo, 0);
+ out_le32((u32 *)(bridge_base + mv64x60_pci2mem[hose].size),mem_size);
+
+ acc_bits |= MV64x60_PCI_ACC_CNTL_ENABLE;
+ out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][0].hi), 0);
+ out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][0].lo), acc_bits);
+ out_le32((u32 *)(bridge_base + mv64x60_pci_acc[hose][0].size),mem_size);
+
+ /* Set PCI MEM->bridge's reg window to where they are in CPU mem map */
+ i = (u32)bridge_base;
+ i &= 0xffff0000;
+ i |= (0x2 << 1);
+ mv64x60_cfg_write(bridge_base, hose, bus, PCI_DEVFN(0,0),
+ mv64x60_pci2reg[hose].hi, 0);
+ mv64x60_cfg_write(bridge_base, hose, bus, PCI_DEVFN(0,0),
+ mv64x60_pci2reg[hose].lo, i);
+
+ enables &= ~0x1; /* Enable PCI MEM -> System Mem window 0 */
+ out_le32((u32 *)(bridge_base + bar_enable), enables);
+}
+
+/* CPU -> PCI I/O & MEM setup */
+struct mv64x60_cpu2pci_win mv64x60_cpu2pci_io[2] = {
+ { /* hose 0 */
+ .lo = MV64x60_CPU2PCI0_IO_BASE,
+ .size = MV64x60_CPU2PCI0_IO_SIZE,
+ .remap_hi = 0,
+ .remap_lo = MV64x60_CPU2PCI0_IO_REMAP,
+ },
+ { /* hose 1 */
+ .lo = MV64x60_CPU2PCI1_IO_BASE,
+ .size = MV64x60_CPU2PCI1_IO_SIZE,
+ .remap_hi = 0,
+ .remap_lo = MV64x60_CPU2PCI1_IO_REMAP,
+ },
+};
+
+struct mv64x60_cpu2pci_win mv64x60_cpu2pci_mem[2] = {
+ { /* hose 0 */
+ .lo = MV64x60_CPU2PCI0_MEM_0_BASE,
+ .size = MV64x60_CPU2PCI0_MEM_0_SIZE,
+ .remap_hi = MV64x60_CPU2PCI0_MEM_0_REMAP_HI,
+ .remap_lo = MV64x60_CPU2PCI0_MEM_0_REMAP_LO,
+ },
+ { /* hose 1 */
+ .lo = MV64x60_CPU2PCI1_MEM_0_BASE,
+ .size = MV64x60_CPU2PCI1_MEM_0_SIZE,
+ .remap_hi = MV64x60_CPU2PCI1_MEM_0_REMAP_HI,
+ .remap_lo = MV64x60_CPU2PCI1_MEM_0_REMAP_LO,
+ },
+};
+
+/* Only need to set up 1 window to pci mem space */
+void mv64x60_config_cpu2pci_window(u8 *bridge_base, u8 hose, u32 pci_base_hi,
+ u32 pci_base_lo, u32 cpu_base, u32 size,
+ struct mv64x60_cpu2pci_win *offset_tbl)
+{
+ cpu_base >>= 16;
+ cpu_base |= MV64x60_CPU2PCI_SWAP_NONE;
+ out_le32((u32 *)(bridge_base + offset_tbl[hose].lo), cpu_base);
+
+ if (offset_tbl[hose].remap_hi != 0)
+ out_le32((u32 *)(bridge_base + offset_tbl[hose].remap_hi),
+ pci_base_hi);
+ out_le32((u32 *)(bridge_base + offset_tbl[hose].remap_lo),
+ pci_base_lo >> 16);
+
+ size = (size - 1) >> 16;
+ out_le32((u32 *)(bridge_base + offset_tbl[hose].size), size);
+}
+
+/* Read mem ctlr to get the amount of mem in system */
+u32 mv64x60_get_mem_size(u8 *bridge_base)
+{
+ u32 enables, i, v;
+ u32 mem = 0;
+
+ enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE)) & 0xf;
+
+ for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++)
+ if (!(enables & (1<<i))) {
+ v = in_le32((u32*)(bridge_base
+ + mv64x60_cpu2mem[i].size));
+ v = ((v & 0xffff) + 1) << 16;
+ mem += v;
+ }
+
+ return mem;
+}
+
+/* Get physical address of bridge's registers */
+u8 *mv64x60_get_bridge_pbase(void)
+{
+ u32 v[2];
+ void *devp;
+
+ devp = finddevice("/mv64x60");
+ if (devp == NULL)
+ goto err_out;
+ if (getprop(devp, "reg", v, sizeof(v)) != sizeof(v))
+ goto err_out;
+
+ return (u8 *)v[0];
+
+err_out:
+ return 0;
+}
+
+/* Get virtual address of bridge's registers */
+u8 *mv64x60_get_bridge_base(void)
+{
+ u32 v;
+ void *devp;
+
+ devp = finddevice("/mv64x60");
+ if (devp == NULL)
+ goto err_out;
+ if (getprop(devp, "virtual-reg", &v, sizeof(v)) != sizeof(v))
+ goto err_out;
+
+ return (u8 *)v;
+
+err_out:
+ return 0;
+}
+
+u8 mv64x60_is_coherent(void)
+{
+ u32 v;
+ void *devp;
+
+ devp = finddevice("/");
+ if (devp == NULL)
+ return 1; /* Assume coherency on */
+
+ if (getprop(devp, "coherency-off", &v, sizeof(v)) < 0)
+ return 1; /* Coherency on */
+ else
+ return 0;
+}
Index: powerpc/arch/powerpc/boot/mv64x60.h
===================================================================
--- /dev/null
+++ powerpc/arch/powerpc/boot/mv64x60.h
@@ -0,0 +1,70 @@
+/*
+ * Author: Mark A. Greer <source@mvista.com>
+ *
+ * 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.
+ */
+
+#ifndef _PPC_BOOT_MV64x60_H_
+#define _PPC_BOOT_MV64x60_H_
+
+#define MV64x60_CPU_BAR_ENABLE 0x0278
+
+#define MV64x60_PCI_ACC_CNTL_ENABLE (1<<0)
+#define MV64x60_PCI_ACC_CNTL_REQ64 (1<<1)
+#define MV64x60_PCI_ACC_CNTL_SNOOP_NONE 0x00000000
+#define MV64x60_PCI_ACC_CNTL_SNOOP_WT 0x00000004
+#define MV64x60_PCI_ACC_CNTL_SNOOP_WB 0x00000008
+#define MV64x60_PCI_ACC_CNTL_SNOOP_MASK 0x0000000c
+#define MV64x60_PCI_ACC_CNTL_ACCPROT (1<<4)
+#define MV64x60_PCI_ACC_CNTL_WRPROT (1<<5)
+#define MV64x60_PCI_ACC_CNTL_SWAP_BYTE 0x00000000
+#define MV64x60_PCI_ACC_CNTL_SWAP_NONE 0x00000040
+#define MV64x60_PCI_ACC_CNTL_SWAP_BYTE_WORD 0x00000080
+#define MV64x60_PCI_ACC_CNTL_SWAP_WORD 0x000000c0
+#define MV64x60_PCI_ACC_CNTL_SWAP_MASK 0x000000c0
+#define MV64x60_PCI_ACC_CNTL_MBURST_32_BYTES 0x00000000
+#define MV64x60_PCI_ACC_CNTL_MBURST_64_BYTES 0x00000100
+#define MV64x60_PCI_ACC_CNTL_MBURST_128_BYTES 0x00000200
+#define MV64x60_PCI_ACC_CNTL_MBURST_MASK 0x00000300
+#define MV64x60_PCI_ACC_CNTL_RDSIZE_32_BYTES 0x00000000
+#define MV64x60_PCI_ACC_CNTL_RDSIZE_64_BYTES 0x00000400
+#define MV64x60_PCI_ACC_CNTL_RDSIZE_128_BYTES 0x00000800
+#define MV64x60_PCI_ACC_CNTL_RDSIZE_256_BYTES 0x00000c00
+#define MV64x60_PCI_ACC_CNTL_RDSIZE_MASK 0x00000c00
+
+struct mv64x60_cpu2pci_win {
+ u32 lo;
+ u32 size;
+ u32 remap_hi;
+ u32 remap_lo;
+};
+
+extern struct mv64x60_cpu2pci_win mv64x60_cpu2pci_io[2];
+extern struct mv64x60_cpu2pci_win mv64x60_cpu2pci_mem[2];
+
+u32 mv64x60_cfg_read(u8 *bridge_base, u8 hose, u8 bus, u8 devfn,
+ u8 offset);
+void mv64x60_cfg_write(u8 *bridge_base, u8 hose, u8 bus, u8 devfn,
+ u8 offset, u32 val);
+
+void mv64x60_config_ctlr_windows(u8 *bridge_base, u8 *bridge_pbase,
+ u8 is_coherent);
+void mv64x60_config_pci_windows(u8 *bridge_base, u8 *bridge_pbase, u8 hose,
+ u8 bus, u32 mem_size, u32 acc_bits);
+void mv64x60_config_cpu2pci_window(u8 *bridge_base, u8 hose, u32 pci_base_hi,
+ u32 pci_base_lo, u32 cpu_base, u32 size,
+ struct mv64x60_cpu2pci_win *offset_tbl);
+u32 mv64x60_get_mem_size(u8 *bridge_base);
+u8 *mv64x60_get_bridge_pbase(void);
+u8 *mv64x60_get_bridge_base(void);
+u8 mv64x60_is_coherent(void);
+
+int mv64x60_i2c_open(void);
+int mv64x60_i2c_read(u32 devaddr, u8 *buf, u32 offset, u32 offset_size,
+ u32 count);
+void mv64x60_i2c_close(void);
+
+#endif /* _PPC_BOOT_MV64x60_H_ */
Index: powerpc/arch/powerpc/boot/Makefile
===================================================================
--- powerpc.orig/arch/powerpc/boot/Makefile
+++ powerpc/arch/powerpc/boot/Makefile
@@ -42,7 +42,7 @@ $(addprefix $(obj)/,$(zlib) main.o): $(a
src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
ns16550.c serial.c simple_alloc.c div64.S util.S \
- gunzip_util.c elf_util.c $(zlib) devtree.c
+ gunzip_util.c elf_util.c devtree.c mv64x60.c $(zlib)
src-plat := of.c cuboot-83xx.c
src-boot := $(src-wlib) $(src-plat) empty.c
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 3/13] powerpc: Add bootwrapper support for Marvell/mv64x60 hostbridge
2007-04-25 23:56 ` [PATCH 3/13] powerpc: Add bootwrapper support for Marvell/mv64x60 hostbridge Mark A. Greer
@ 2007-04-27 6:01 ` Paul Mackerras
2007-04-27 22:02 ` Mark A. Greer
0 siblings, 1 reply; 87+ messages in thread
From: Paul Mackerras @ 2007-04-27 6:01 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev
Mark A. Greer writes:
> Makefile | 2
> mv64x60.c | 581 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> mv64x60.h | 70 +++++++
> 3 files changed, 652 insertions(+), 1 deletion(-)
650 lines just to set up a hostbridge - that seems like rather a lot.
Why do we have to do this here? Isn't there some firmware that should
do this for us?
Paul.
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 3/13] powerpc: Add bootwrapper support for Marvell/mv64x60 hostbridge
2007-04-27 6:01 ` Paul Mackerras
@ 2007-04-27 22:02 ` Mark A. Greer
2007-05-03 5:25 ` Paul Mackerras
0 siblings, 1 reply; 87+ messages in thread
From: Mark A. Greer @ 2007-04-27 22:02 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
On Fri, Apr 27, 2007 at 04:01:55PM +1000, Paul Mackerras wrote:
> Mark A. Greer writes:
>
> > Makefile | 2
> > mv64x60.c | 581 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > mv64x60.h | 70 +++++++
> > 3 files changed, 652 insertions(+), 1 deletion(-)
>
> 650 lines just to set up a hostbridge - that seems like rather a lot.
Yes, it is. This probably won't make you feel any better but most of
the lines are #define's or table init lines. There's only a couple
hundred or so that are actual code.
> Why do we have to do this here? Isn't there some firmware that should
> do this for us?
Well, the firmware just doesn't do all the init that's required. And,
some of the init that it does do is wrong. For example, the window for
the MPSC (serial ctlr) to access main memory isn't set up so the kernel
mpsc driver can't dma. There are several other examles.
All of this init should be in the firmware but its Motorola/ECC's
firmware and I/we have no control over it. Given that, I/we have to do
the init somewhere. Either in the kernel or the bootwrapper.
I vote for the bootwrapper but then your vote is the only one that actually
counts. :)
Mark
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 3/13] powerpc: Add bootwrapper support for Marvell/mv64x60 hostbridge
2007-04-27 22:02 ` Mark A. Greer
@ 2007-05-03 5:25 ` Paul Mackerras
2007-05-03 18:44 ` Mark A. Greer
0 siblings, 1 reply; 87+ messages in thread
From: Paul Mackerras @ 2007-05-03 5:25 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev
Mark A. Greer writes:
> Well, the firmware just doesn't do all the init that's required. And,
> some of the init that it does do is wrong. For example, the window for
> the MPSC (serial ctlr) to access main memory isn't set up so the kernel
> mpsc driver can't dma. There are several other examles.
>
> All of this init should be in the firmware but its Motorola/ECC's
> firmware and I/we have no control over it. Given that, I/we have to do
> the init somewhere. Either in the kernel or the bootwrapper.
> I vote for the bootwrapper but then your vote is the only one that actually
> counts. :)
How much of the setup is actually necessary for the bootwrapper to
run, and how much could be deferred to setup_arch() time in the
kernel? If nothing else, doing it in the kernel means that the code
and data for it exist in compressed form in the zImage rather than
uncompressed form. :)
Also, how many lines of code (including definitions) would we avoid
having in the kernel by having this stuff in the bootwrapper?
Another question - is this setup something that will need to be done
differently for different boards using the mv64x60, or is the same
setup needed for all applications of the mv64x60?
Paul.
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 3/13] powerpc: Add bootwrapper support for Marvell/mv64x60 hostbridge
2007-05-03 5:25 ` Paul Mackerras
@ 2007-05-03 18:44 ` Mark A. Greer
2007-05-03 19:00 ` Mark A. Greer
2007-05-05 23:27 ` Paul Mackerras
0 siblings, 2 replies; 87+ messages in thread
From: Mark A. Greer @ 2007-05-03 18:44 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
On Thu, May 03, 2007 at 03:25:06PM +1000, Paul Mackerras wrote:
> Mark A. Greer writes:
>
> > Well, the firmware just doesn't do all the init that's required. And,
> > some of the init that it does do is wrong. For example, the window for
> > the MPSC (serial ctlr) to access main memory isn't set up so the kernel
> > mpsc driver can't dma. There are several other examles.
> >
> > All of this init should be in the firmware but its Motorola/ECC's
> > firmware and I/we have no control over it. Given that, I/we have to do
> > the init somewhere. Either in the kernel or the bootwrapper.
> > I vote for the bootwrapper but then your vote is the only one that actually
> > counts. :)
>
> How much of the setup is actually necessary for the bootwrapper to
> run, and how much could be deferred to setup_arch() time in the
> kernel?
Actually, none of the config code should be needed by the bootwrapper
itself because the bootwrapper mpsc and i2c drivers use PIO (so accessing
memory isn't an issue). The "get info" type routines are still needed.
> If nothing else, doing it in the kernel means that the code
> and data for it exist in compressed form in the zImage rather than
> uncompressed form. :)
mv64x60.o is 4804 bytes, .text is 2188 bytes, .data 64 bytes, .bss 0
bytes. So we're probably only saving ~1-2KB by compressing.
> Also, how many lines of code (including definitions) would we avoid
> having in the kernel by having this stuff in the bootwrapper?
Its pretty much 1:1. Whatever is in the bootwrapper (including
#define's) isn't needed in the kernel.
> Another question - is this setup something that will need to be done
> differently for different boards using the mv64x60, or is the same
> setup needed for all applications of the mv64x60?
I expect that the setup will be done the same for all of the boards
that need it. Not all of the boards will need it, though. It depends
on their firmware. The config code is filling the gap between what the
firmware should have done and what the kernel drivers require (i.e.,
allowing the ctlrs to access system memory and pci mem/io space).
Paul, I'm a little perplexed by you wanting this code pushed back into
the kernel. A while back there was a definite desire to push stuff like
this out of the kernel (mainly by Ben). I tend to agree with Ben on
this. Either way, it would good to have everyone pushing in the same
direction. :)
Mark
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 3/13] powerpc: Add bootwrapper support for Marvell/mv64x60 hostbridge
2007-05-03 18:44 ` Mark A. Greer
@ 2007-05-03 19:00 ` Mark A. Greer
2007-05-05 23:27 ` Paul Mackerras
1 sibling, 0 replies; 87+ messages in thread
From: Mark A. Greer @ 2007-05-03 19:00 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev, Paul Mackerras
On Thu, May 03, 2007 at 11:44:02AM -0700, Mark A. Greer wrote:
> On Thu, May 03, 2007 at 03:25:06PM +1000, Paul Mackerras wrote:
> > Mark A. Greer writes:
> > Another question - is this setup something that will need to be done
> > differently for different boards using the mv64x60, or is the same
> > setup needed for all applications of the mv64x60?
>
> I expect that the setup will be done the same for all of the boards
> that need it. Not all of the boards will need it, though. It depends
> on their firmware. The config code is filling the gap between what the
> firmware should have done and what the kernel drivers require (i.e.,
> allowing the ctlrs to access system memory and pci mem/io space).
I'll clarify the last line: "allowing ctlrs on the bridge to access
system memory, allowing the cpu to access pci mem/io space, and allowing
pci devices to access system memory via pci mem reference."
Mark
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 3/13] powerpc: Add bootwrapper support for Marvell/mv64x60 hostbridge
2007-05-03 18:44 ` Mark A. Greer
2007-05-03 19:00 ` Mark A. Greer
@ 2007-05-05 23:27 ` Paul Mackerras
2007-05-07 18:15 ` Mark A. Greer
1 sibling, 1 reply; 87+ messages in thread
From: Paul Mackerras @ 2007-05-05 23:27 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev
Mark A. Greer writes:
> Actually, none of the config code should be needed by the bootwrapper
> itself because the bootwrapper mpsc and i2c drivers use PIO (so accessing
> memory isn't an issue). The "get info" type routines are still needed.
Talking of i2c, why does the bootwrapper need an i2c driver at all?
You don't tell me in the patch description for your patch 5/13...
> Its pretty much 1:1. Whatever is in the bootwrapper (including
> #define's) isn't needed in the kernel.
OK, good.
> I expect that the setup will be done the same for all of the boards
> that need it. Not all of the boards will need it, though. It depends
> on their firmware. The config code is filling the gap between what the
> firmware should have done and what the kernel drivers require (i.e.,
> allowing the ctlrs to access system memory and pci mem/io space).
Is it possible that different kernels will want things set up
differently? Or is there really only one sensible setup?
> Paul, I'm a little perplexed by you wanting this code pushed back into
> the kernel. A while back there was a definite desire to push stuff like
> this out of the kernel (mainly by Ben). I tend to agree with Ben on
> this. Either way, it would good to have everyone pushing in the same
> direction. :)
One of these days you guys will write me nice informative patch
descriptions that explain the rationale and design decisions behind
the changes you're proposing, without me nagging. :) I'm not so much
pushing back as trying to get you to tell me why the code is here and
not somewhere else, and what the obvious alternatives might be and why
we aren't doing them. Or better still, put that information into a
new set of patch descriptions for me...
BTW, the descriptions on your string of 13 were completely empty for
many of them, and for the remainder they just said what had been
changed. Please be more informative. Yes, it does require thinking
about things from the point of view of someone who doesn't have all
the context in their head, as you do, which can take a bit of mental
effort. But in 2 or 3 years time it might be you that doesn't have
the context in mind any more and will really appreciate a more verbose
description. :)
Paul.
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 3/13] powerpc: Add bootwrapper support for Marvell/mv64x60 hostbridge
2007-05-05 23:27 ` Paul Mackerras
@ 2007-05-07 18:15 ` Mark A. Greer
0 siblings, 0 replies; 87+ messages in thread
From: Mark A. Greer @ 2007-05-07 18:15 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
On Sun, May 06, 2007 at 09:27:39AM +1000, Paul Mackerras wrote:
> Mark A. Greer writes:
>
> > Actually, none of the config code should be needed by the bootwrapper
> > itself because the bootwrapper mpsc and i2c drivers use PIO (so accessing
> > memory isn't an issue). The "get info" type routines are still needed.
>
> Talking of i2c, why does the bootwrapper need an i2c driver at all?
The prpmc2800 needs it to get at some VPD that store in an i2c eeprom.
The VPD provide that type of board, amount of memory, etc. so the DT can
be updated.
> You don't tell me in the patch description for your patch 5/13...
Yes, I haven't provided much for descriptions :)
> > Its pretty much 1:1. Whatever is in the bootwrapper (including
> > #define's) isn't needed in the kernel.
>
> OK, good.
>
> > I expect that the setup will be done the same for all of the boards
> > that need it. Not all of the boards will need it, though. It depends
> > on their firmware. The config code is filling the gap between what the
> > firmware should have done and what the kernel drivers require (i.e.,
> > allowing the ctlrs to access system memory and pci mem/io space).
>
> Is it possible that different kernels will want things set up
> differently? Or is there really only one sensible setup?
Most of the boot/mv64x60 config code is "configurable" in that the
important info is passed in from platform-specific code so each platform
can configure the windows how it wants.
However, mv64x60_config_ctlr_windows() does assume that the cpu->mem
windows are set correctly and uses that info to configure the
enet/mpsc/idma->mem windows. I can't think of any scenario where someone
would want to do it differently but if/when there is one, we can make
the necessary changes then.
There is another assumption where only one window each is used to configure
the cpu->pci mem, cpu->pci i/o, pci mem->system mem windows. One window
can cover the entire address space, so I don't see why that would ever
ben an issue.
> > Paul, I'm a little perplexed by you wanting this code pushed back into
> > the kernel. A while back there was a definite desire to push stuff like
> > this out of the kernel (mainly by Ben). I tend to agree with Ben on
> > this. Either way, it would good to have everyone pushing in the same
> > direction. :)
>
> One of these days you guys will write me nice informative patch
> descriptions that explain the rationale and design decisions behind
> the changes you're proposing, without me nagging. :) I'm not so much
> pushing back as trying to get you to tell me why the code is here and
> not somewhere else, and what the obvious alternatives might be and why
> we aren't doing them. Or better still, put that information into a
> new set of patch descriptions for me...
>
> BTW, the descriptions on your string of 13 were completely empty for
> many of them, and for the remainder they just said what had been
> changed. Please be more informative. Yes, it does require thinking
> about things from the point of view of someone who doesn't have all
> the context in their head, as you do, which can take a bit of mental
> effort. But in 2 or 3 years time it might be you that doesn't have
> the context in mind any more and will really appreciate a more verbose
> description. :)
Okay, point well taken. The subject said enough for me but I wasn't
thinking of others or 2-3 years down the road. I'll add some
descriptions and resubmit. Sorry for the frustration.
Mark
^ permalink raw reply [flat|nested] 87+ messages in thread
* [PATCH 4/13] powerpc: Add bootwrapper support for Marvell MPSC
2007-04-25 23:46 [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800 Mark A. Greer
` (2 preceding siblings ...)
2007-04-25 23:56 ` [PATCH 3/13] powerpc: Add bootwrapper support for Marvell/mv64x60 hostbridge Mark A. Greer
@ 2007-04-25 23:57 ` Mark A. Greer
2007-04-25 23:57 ` [PATCH 5/13] powerpc: Add bootwrapper support for Marvell/mv64x60 I2C Mark A. Greer
` (9 subsequent siblings)
13 siblings, 0 replies; 87+ messages in thread
From: Mark A. Greer @ 2007-04-25 23:57 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
---
Makefile | 2
mpsc.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ops.h | 1
serial.c | 2
4 files changed, 174 insertions(+), 1 deletion(-)
Index: powerpc/arch/powerpc/boot/mpsc.c
===================================================================
--- /dev/null
+++ powerpc/arch/powerpc/boot/mpsc.c
@@ -0,0 +1,170 @@
+/*
+ * MPSC/UART driver for the Marvell mv64360, mv64460, ...
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 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 <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "string.h"
+#include "stdio.h"
+#include "io.h"
+#include "ops.h"
+
+extern void udelay(long delay);
+
+#define MPSC_CHR_1 0x000c
+
+#define MPSC_CHR_2 0x0010
+#define MPSC_CHR_2_TA (1<<7)
+#define MPSC_CHR_2_TCS (1<<9)
+#define MPSC_CHR_2_RA (1<<23)
+#define MPSC_CHR_2_CRD (1<<25)
+#define MPSC_CHR_2_EH (1<<31)
+
+#define MPSC_CHR_4 0x0018
+#define MPSC_CHR_4_Z (1<<29)
+
+#define MPSC_CHR_5 0x001c
+#define MPSC_CHR_5_CTL1_INTR (1<<12)
+#define MPSC_CHR_5_CTL1_VALID (1<<15)
+
+#define MPSC_CHR_10 0x0030
+
+#define MPSC_INTR_CAUSE 0x0000
+#define MPSC_INTR_CAUSE_RCC (1<<6)
+#define MPSC_INTR_MASK 0x0080
+
+#define SDMA_SDCM 0x0008
+#define SDMA_SDCM_AR (1<<15)
+#define SDMA_SDCM_AT (1<<31)
+
+static volatile char *mpsc_base;
+static volatile char *mpscintr_base;
+static u32 chr1, chr2;
+
+static int mpsc_open(void)
+{
+ chr1 = in_le32((u32 *)(mpsc_base + MPSC_CHR_1)) & 0x00ff0000;
+ chr2 = in_le32((u32 *)(mpsc_base + MPSC_CHR_2)) & ~(MPSC_CHR_2_TA
+ | MPSC_CHR_2_TCS | MPSC_CHR_2_RA | MPSC_CHR_2_CRD
+ | MPSC_CHR_2_EH);
+ out_le32((u32 *)(mpsc_base + MPSC_CHR_4), MPSC_CHR_4_Z);
+ out_le32((u32 *)(mpsc_base + MPSC_CHR_5),
+ MPSC_CHR_5_CTL1_INTR | MPSC_CHR_5_CTL1_VALID);
+ out_le32((u32 *)(mpsc_base + MPSC_CHR_2), chr2 | MPSC_CHR_2_EH);
+ return 0;
+}
+
+static void mpsc_putc(unsigned char c)
+{
+ while (in_le32((u32 *)(mpsc_base + MPSC_CHR_2)) & MPSC_CHR_2_TCS);
+
+ out_le32((u32 *)(mpsc_base + MPSC_CHR_1), chr1 | c);
+ out_le32((u32 *)(mpsc_base + MPSC_CHR_2), chr2 | MPSC_CHR_2_TCS);
+}
+
+static unsigned char mpsc_getc(void)
+{
+ u32 cause = 0;
+ unsigned char c;
+
+ while (!(cause & MPSC_INTR_CAUSE_RCC))
+ cause = in_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE));
+
+ c = in_8((u8 *)(mpsc_base + MPSC_CHR_10 + 2));
+ out_8((u8 *)(mpsc_base + MPSC_CHR_10 + 2), c);
+ out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE),
+ cause & ~MPSC_INTR_CAUSE_RCC);
+
+ return c;
+}
+
+static u8 mpsc_tstc(void)
+{
+ return (u8)((in_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE))
+ & MPSC_INTR_CAUSE_RCC) != 0);
+}
+
+static void mpsc_stop_dma(volatile char *sdma_base)
+{
+ out_le32((u32 *)(mpsc_base + MPSC_CHR_2),MPSC_CHR_2_TA | MPSC_CHR_2_RA);
+ out_le32((u32 *)(sdma_base + SDMA_SDCM), SDMA_SDCM_AR | SDMA_SDCM_AT);
+
+ while ((in_le32((u32 *)(sdma_base + SDMA_SDCM))
+ & (SDMA_SDCM_AR | SDMA_SDCM_AT)) != 0)
+ udelay(100);
+}
+
+static volatile char *mpsc_get_virtreg_of_phandle(void *devp, char *prop)
+{
+ void *v;
+ int n;
+
+ n = getprop(devp, prop, &v, sizeof(v));
+ if (n != sizeof(v))
+ goto err_out;
+
+ devp = find_node_by_linuxphandle((u32)v);
+ if (devp == NULL)
+ goto err_out;
+
+ n = getprop(devp, "virtual-reg", &v, sizeof(v));
+ if (n == sizeof(v))
+ return v;
+
+err_out:
+ return NULL;
+}
+
+int mpsc_console_init(void *devp, struct serial_console_data *scdp)
+{
+ void *v;
+ int n, reg_set;
+ volatile char *sdma_base;
+
+ n = getprop(devp, "virtual-reg", &v, sizeof(v));
+ if (n != sizeof(v))
+ goto err_out;
+ mpsc_base = v;
+
+ sdma_base = mpsc_get_virtreg_of_phandle(devp, "sdma");
+ if (sdma_base == NULL)
+ goto err_out;
+
+ mpscintr_base = mpsc_get_virtreg_of_phandle(devp, "mpscintr");
+ if (mpscintr_base == NULL)
+ goto err_out;
+
+ n = getprop(devp, "block-index", &v, sizeof(v));
+ if (n != sizeof(v))
+ goto err_out;
+ reg_set = (int)v;
+
+ mpscintr_base += (reg_set == 0) ? 0x4 : 0xc;
+
+ /* Make sure the mpsc ctlrs are shutdown */
+ out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE), 0);
+ out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE), 0);
+ out_le32((u32 *)(mpscintr_base + MPSC_INTR_MASK), 0);
+ out_le32((u32 *)(mpscintr_base + MPSC_INTR_MASK), 0);
+
+ mpsc_stop_dma(sdma_base);
+
+ scdp->open = mpsc_open;
+ scdp->putc = mpsc_putc;
+ scdp->getc = mpsc_getc;
+ scdp->tstc = mpsc_tstc;
+ scdp->close = NULL;
+
+ return 0;
+
+err_out:
+ return -1;
+}
Index: powerpc/arch/powerpc/boot/serial.c
===================================================================
--- powerpc.orig/arch/powerpc/boot/serial.c
+++ powerpc/arch/powerpc/boot/serial.c
@@ -125,6 +125,8 @@ int serial_console_init(void)
if (!strcmp(compat, "ns16550"))
rc = ns16550_console_init(devp, &serial_cd);
+ else if (!strcmp(compat, "mpsc"))
+ rc = mpsc_console_init(devp, &serial_cd);
/* Add other serial console driver calls here */
Index: powerpc/arch/powerpc/boot/Makefile
===================================================================
--- powerpc.orig/arch/powerpc/boot/Makefile
+++ powerpc/arch/powerpc/boot/Makefile
@@ -42,7 +42,7 @@ $(addprefix $(obj)/,$(zlib) main.o): $(a
src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
ns16550.c serial.c simple_alloc.c div64.S util.S \
- gunzip_util.c elf_util.c devtree.c mv64x60.c $(zlib)
+ gunzip_util.c elf_util.c devtree.c mv64x60.c mpsc.c $(zlib)
src-plat := of.c cuboot-83xx.c
src-boot := $(src-wlib) $(src-plat) empty.c
Index: powerpc/arch/powerpc/boot/ops.h
===================================================================
--- powerpc.orig/arch/powerpc/boot/ops.h
+++ powerpc/arch/powerpc/boot/ops.h
@@ -79,6 +79,7 @@ void start(void);
int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device);
int serial_console_init(void);
int ns16550_console_init(void *devp, struct serial_console_data *scdp);
+int mpsc_console_init(void *devp, struct serial_console_data *scdp);
void *simple_alloc_init(char *base, unsigned long heap_size,
unsigned long granularity, unsigned long max_allocs);
extern void flush_cache(void *, unsigned long);
^ permalink raw reply [flat|nested] 87+ messages in thread
* [PATCH 5/13] powerpc: Add bootwrapper support for Marvell/mv64x60 I2C
2007-04-25 23:46 [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800 Mark A. Greer
` (3 preceding siblings ...)
2007-04-25 23:57 ` [PATCH 4/13] powerpc: Add bootwrapper support for Marvell MPSC Mark A. Greer
@ 2007-04-25 23:57 ` Mark A. Greer
2007-04-25 23:58 ` [PATCH 6/13] powerpc: Add arch/powerpc support for Marvell/mv64x60 hostbridge Mark A. Greer
` (8 subsequent siblings)
13 siblings, 0 replies; 87+ messages in thread
From: Mark A. Greer @ 2007-04-25 23:57 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
---
Makefile | 3
mv64x60_i2c.c | 206 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 208 insertions(+), 1 deletion(-)
Index: powerpc/arch/powerpc/boot/mv64x60_i2c.c
===================================================================
--- /dev/null
+++ powerpc/arch/powerpc/boot/mv64x60_i2c.c
@@ -0,0 +1,206 @@
+/*
+ * Bootloader version of the i2c driver for the MV64x60.
+ *
+ * Author: Dale Farnsworth <dfarnsworth@mvista.com>
+ * Maintained by: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2003, 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 <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "elf.h"
+#include "page.h"
+#include "string.h"
+#include "stdio.h"
+#include "io.h"
+#include "ops.h"
+#include "mv64x60.h"
+
+extern void udelay(long);
+
+/* Register defines */
+#define MV64x60_I2C_REG_SLAVE_ADDR 0x00
+#define MV64x60_I2C_REG_DATA 0x04
+#define MV64x60_I2C_REG_CONTROL 0x08
+#define MV64x60_I2C_REG_STATUS 0x0c
+#define MV64x60_I2C_REG_BAUD 0x0c
+#define MV64x60_I2C_REG_EXT_SLAVE_ADDR 0x10
+#define MV64x60_I2C_REG_SOFT_RESET 0x1c
+
+#define MV64x60_I2C_CONTROL_ACK 0x04
+#define MV64x60_I2C_CONTROL_IFLG 0x08
+#define MV64x60_I2C_CONTROL_STOP 0x10
+#define MV64x60_I2C_CONTROL_START 0x20
+#define MV64x60_I2C_CONTROL_TWSIEN 0x40
+#define MV64x60_I2C_CONTROL_INTEN 0x80
+
+#define MV64x60_I2C_STATUS_BUS_ERR 0x00
+#define MV64x60_I2C_STATUS_MAST_START 0x08
+#define MV64x60_I2C_STATUS_MAST_REPEAT_START 0x10
+#define MV64x60_I2C_STATUS_MAST_WR_ADDR_ACK 0x18
+#define MV64x60_I2C_STATUS_MAST_WR_ADDR_NO_ACK 0x20
+#define MV64x60_I2C_STATUS_MAST_WR_ACK 0x28
+#define MV64x60_I2C_STATUS_MAST_WR_NO_ACK 0x30
+#define MV64x60_I2C_STATUS_MAST_LOST_ARB 0x38
+#define MV64x60_I2C_STATUS_MAST_RD_ADDR_ACK 0x40
+#define MV64x60_I2C_STATUS_MAST_RD_ADDR_NO_ACK 0x48
+#define MV64x60_I2C_STATUS_MAST_RD_DATA_ACK 0x50
+#define MV64x60_I2C_STATUS_MAST_RD_DATA_NO_ACK 0x58
+#define MV64x60_I2C_STATUS_MAST_WR_ADDR_2_ACK 0xd0
+#define MV64x60_I2C_STATUS_MAST_WR_ADDR_2_NO_ACK 0xd8
+#define MV64x60_I2C_STATUS_MAST_RD_ADDR_2_ACK 0xe0
+#define MV64x60_I2C_STATUS_MAST_RD_ADDR_2_NO_ACK 0xe8
+#define MV64x60_I2C_STATUS_NO_STATUS 0xf8
+
+static u8 *ctlr_base;
+
+static int mv64x60_i2c_wait_for_status(int wanted)
+{
+ int i;
+ int status;
+
+ for (i=0; i<1000; i++) {
+ udelay(10);
+ status = in_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_STATUS))
+ & 0xff;
+ if (status == wanted)
+ return status;
+ }
+ return -status;
+}
+
+static int mv64x60_i2c_control(int control, int status)
+{
+ out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_CONTROL), control & 0xff);
+ return mv64x60_i2c_wait_for_status(status);
+}
+
+static int mv64x60_i2c_read_byte(int control, int status)
+{
+ out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_CONTROL), control & 0xff);
+ if (mv64x60_i2c_wait_for_status(status) < 0)
+ return -1;
+ return in_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_DATA)) & 0xff;
+}
+
+static int mv64x60_i2c_write_byte(int data, int control, int status)
+{
+ out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_DATA), data & 0xff);
+ out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_CONTROL), control & 0xff);
+ return mv64x60_i2c_wait_for_status(status);
+}
+
+int mv64x60_i2c_read(u32 devaddr, u8 *buf, u32 offset, u32 offset_size,
+ u32 count)
+{
+ int i;
+ int data;
+ int control;
+ int status;
+
+ if (ctlr_base == NULL)
+ return -1;
+
+ /* send reset */
+ out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_SOFT_RESET), 0);
+ out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_SLAVE_ADDR), 0);
+ out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_EXT_SLAVE_ADDR), 0);
+ out_le32((u32 *)(ctlr_base + MV64x60_I2C_REG_BAUD), (4 << 3) | 0x4);
+
+ if (mv64x60_i2c_control(MV64x60_I2C_CONTROL_TWSIEN,
+ MV64x60_I2C_STATUS_NO_STATUS) < 0)
+ return -1;
+
+ /* send start */
+ control = MV64x60_I2C_CONTROL_START | MV64x60_I2C_CONTROL_TWSIEN;
+ status = MV64x60_I2C_STATUS_MAST_START;
+ if (mv64x60_i2c_control(control, status) < 0)
+ return -1;
+
+ /* select device for writing */
+ data = devaddr & ~0x1;
+ control = MV64x60_I2C_CONTROL_TWSIEN;
+ status = MV64x60_I2C_STATUS_MAST_WR_ADDR_ACK;
+ if (mv64x60_i2c_write_byte(data, control, status) < 0)
+ return -1;
+
+ /* send offset of data */
+ control = MV64x60_I2C_CONTROL_TWSIEN;
+ status = MV64x60_I2C_STATUS_MAST_WR_ACK;
+ if (offset_size > 1) {
+ if (mv64x60_i2c_write_byte(offset >> 8, control, status) < 0)
+ return -1;
+ }
+ if (mv64x60_i2c_write_byte(offset, control, status) < 0)
+ return -1;
+
+ /* resend start */
+ control = MV64x60_I2C_CONTROL_START | MV64x60_I2C_CONTROL_TWSIEN;
+ status = MV64x60_I2C_STATUS_MAST_REPEAT_START;
+ if (mv64x60_i2c_control(control, status) < 0)
+ return -1;
+
+ /* select device for reading */
+ data = devaddr | 0x1;
+ control = MV64x60_I2C_CONTROL_TWSIEN;
+ status = MV64x60_I2C_STATUS_MAST_RD_ADDR_ACK;
+ if (mv64x60_i2c_write_byte(data, control, status) < 0)
+ return -1;
+
+ /* read all but last byte of data */
+ control = MV64x60_I2C_CONTROL_ACK | MV64x60_I2C_CONTROL_TWSIEN;
+ status = MV64x60_I2C_STATUS_MAST_RD_DATA_ACK;
+
+ for (i=1; i<count; i++) {
+ data = mv64x60_i2c_read_byte(control, status);
+ if (data < 0) {
+ printf("errors on iteration %d\n", i);
+ return -1;
+ }
+ *buf++ = data;
+ }
+
+ /* read last byte of data */
+ control = MV64x60_I2C_CONTROL_TWSIEN;
+ status = MV64x60_I2C_STATUS_MAST_RD_DATA_NO_ACK;
+ data = mv64x60_i2c_read_byte(control, status);
+ if (data < 0)
+ return -1;
+ *buf++ = data;
+
+ /* send stop */
+ control = MV64x60_I2C_CONTROL_STOP | MV64x60_I2C_CONTROL_TWSIEN;
+ status = MV64x60_I2C_STATUS_NO_STATUS;
+ if (mv64x60_i2c_control(control, status) < 0)
+ return -1;
+
+ return count;
+}
+
+int mv64x60_i2c_open(void)
+{
+ u32 v;
+ void *devp;
+
+ devp = finddevice("/mv64x60/i2c");
+ if (devp == NULL)
+ goto err_out;
+ if (getprop(devp, "virtual-reg", &v, sizeof(v)) != sizeof(v))
+ goto err_out;
+
+ ctlr_base = (u8 *)v;
+ return 0;
+
+err_out:
+ return -1;
+}
+
+void mv64x60_i2c_close(void)
+{
+ ctlr_base = NULL;
+}
Index: powerpc/arch/powerpc/boot/Makefile
===================================================================
--- powerpc.orig/arch/powerpc/boot/Makefile
+++ powerpc/arch/powerpc/boot/Makefile
@@ -42,7 +42,8 @@ $(addprefix $(obj)/,$(zlib) main.o): $(a
src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
ns16550.c serial.c simple_alloc.c div64.S util.S \
- gunzip_util.c elf_util.c devtree.c mv64x60.c mpsc.c $(zlib)
+ gunzip_util.c elf_util.c devtree.c mv64x60.c mpsc.c \
+ mv64x60_i2c.c $(zlib)
src-plat := of.c cuboot-83xx.c
src-boot := $(src-wlib) $(src-plat) empty.c
^ permalink raw reply [flat|nested] 87+ messages in thread
* [PATCH 6/13] powerpc: Add arch/powerpc support for Marvell/mv64x60 hostbridge
2007-04-25 23:46 [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800 Mark A. Greer
` (4 preceding siblings ...)
2007-04-25 23:57 ` [PATCH 5/13] powerpc: Add bootwrapper support for Marvell/mv64x60 I2C Mark A. Greer
@ 2007-04-25 23:58 ` Mark A. Greer
2007-04-26 0:42 ` Arnd Bergmann
2007-05-02 21:38 ` [PATCH 6/13] powerpc: Add arch/powerpc interrupt handler for mv64x60 Dale Farnsworth
2007-04-25 23:59 ` [PATCH 7/13] powerpc: Add arch/powerpc mv64x60 MPSC platform data setup Mark A. Greer
` (7 subsequent siblings)
13 siblings, 2 replies; 87+ messages in thread
From: Mark A. Greer @ 2007-04-25 23:58 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
From: Dale Farnsworth <dale@farnsworth.org>
Signed-off-by: Dale Farnsworth <dale@farnsworth.org>
---
platforms/embedded6xx/Kconfig | 4
sysdev/Makefile | 1
sysdev/mv64x60.c | 343 ++++++++++++++++++++++++++++++++++++++++++
sysdev/mv64x60.h | 9 +
4 files changed, 357 insertions(+)
Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c 2007-04-17 12:48:22.000000000 -0700
@@ -0,0 +1,343 @@
+/*
+ * Common routines for the 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 <asm/machdep.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;
+}
+
+/*
+ * The bootwrapper sets the coherency of the DMA windows according to
+ * the setting in the device tree. For the kernel, coherency is a
+ * compile-time configuration option. Fail if there is a mismatch.
+ */
+
+#ifdef CONFIG_NOT_COHERENT_CACHE
+#define KERNEL_COHERENCY 0
+#else
+#define KERNEL_COHERENCY 1
+#endif
+
+int __init mv64x60_verify_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(mv64x60_verify_cache_coherency);
Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.h 2007-04-17 12:47:28.000000000 -0700
@@ -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/platforms/embedded6xx/Kconfig
===================================================================
--- linux-2.6-powerpc-df.orig/arch/powerpc/platforms/embedded6xx/Kconfig 2007-04-17 11:35:26.000000000 -0700
+++ linux-2.6-powerpc-df/arch/powerpc/platforms/embedded6xx/Kconfig 2007-04-17 12:47:27.000000000 -0700
@@ -38,6 +38,10 @@
select PPC_INDIRECT_PCI
default y
+config MV64X60
+ bool
+ select PPC_INDIRECT_PCI
+
config MPC10X_OPENPIC
bool
depends on LINKSTATION
Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/Makefile
===================================================================
--- linux-2.6-powerpc-df.orig/arch/powerpc/sysdev/Makefile 2007-04-17 11:35:26.000000000 -0700
+++ linux-2.6-powerpc-df/arch/powerpc/sysdev/Makefile 2007-04-17 12:46:39.000000000 -0700
@@ -14,6 +14,7 @@
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.o
# contains only the suspend handler for time
obj-$(CONFIG_PM) += timer.o
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 6/13] powerpc: Add arch/powerpc support for Marvell/mv64x60 hostbridge
2007-04-25 23:58 ` [PATCH 6/13] powerpc: Add arch/powerpc support for Marvell/mv64x60 hostbridge Mark A. Greer
@ 2007-04-26 0:42 ` Arnd Bergmann
2007-04-26 5:49 ` Dale Farnsworth
2007-05-02 21:38 ` [PATCH 6/13] powerpc: Add arch/powerpc interrupt handler for mv64x60 Dale Farnsworth
1 sibling, 1 reply; 87+ messages in thread
From: Arnd Bergmann @ 2007-04-26 0:42 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras
> Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c 2007-04-17 12:48:22.000000000 -0700
> @@ -0,0 +1,343 @@
> +/*
> + * Common routines for the Marvell mv64360/mv64460 host bridges (Discovery)
> + *
> +/* Interrupt Controller Interface Registers */
I'd make this a file that _only_ deals with the interrupt controller
code, and has a respective name, e.g. mv64x60_irq.c
> +/*
> + * The bootwrapper sets the coherency of the DMA windows according to
> + * the setting in the device tree. For the kernel, coherency is a
> + * compile-time configuration option. Fail if there is a mismatch.
> + */
> +
> +#ifdef CONFIG_NOT_COHERENT_CACHE
> +#define KERNEL_COHERENCY 0
> +#else
> +#define KERNEL_COHERENCY 1
> +#endif
> +
> +int __init mv64x60_verify_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(mv64x60_verify_cache_coherency);
Not sure where to best put this function, but probably not in the same file as
your interrupt handling code.
Note that the way your function is written, there is nothing specific to
mv64x60 in it, and it will actually get called on other machines when the
file is built-in.
Maybe just rename it to verify_cache_coherency() and put it into
arch/powerpc/kernel/setup-common.c.
Arnd <><
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 6/13] powerpc: Add arch/powerpc support for Marvell/mv64x60 hostbridge
2007-04-26 0:42 ` Arnd Bergmann
@ 2007-04-26 5:49 ` Dale Farnsworth
0 siblings, 0 replies; 87+ messages in thread
From: Dale Farnsworth @ 2007-04-26 5:49 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
On Thu, Apr 26, 2007 at 12:42:39AM +0000, Arnd Bergmann wrote:
> > Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
> > ===================================================================
> > --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> > +++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c 2007-04-17 12:48:22.000000000 -0700
> > @@ -0,0 +1,343 @@
> > +/*
> > + * Common routines for the Marvell mv64360/mv64460 host bridges (Discovery)
> > + *
> > +/* Interrupt Controller Interface Registers */
>
> I'd make this a file that _only_ deals with the interrupt controller
> code, and has a respective name, e.g. mv64x60_irq.c
Does anyone else feel strongly about this? I can go either way.
On the one hand, separating out the irq handling might make it
marginally easier to understand. On the other hand, it's nice
to keep all of the mv64x60 support together. I see examples
doing it both ways currently in arch/powerpc/sysdev.
> > +/*
> > + * The bootwrapper sets the coherency of the DMA windows according to
> > + * the setting in the device tree. For the kernel, coherency is a
> > + * compile-time configuration option. Fail if there is a mismatch.
> > + */
> > +
> > +#ifdef CONFIG_NOT_COHERENT_CACHE
> > +#define KERNEL_COHERENCY 0
> > +#else
> > +#define KERNEL_COHERENCY 1
> > +#endif
> > +
> > +int __init mv64x60_verify_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(mv64x60_verify_cache_coherency);
>
> Not sure where to best put this function, but probably not in the same file as
> your interrupt handling code.
>
> Note that the way your function is written, there is nothing specific to
> mv64x60 in it, and it will actually get called on other machines when the
> file is built-in.
>
> Maybe just rename it to verify_cache_coherency() and put it into
> arch/powerpc/kernel/setup-common.c.
Good point. I'll break it out and submit it separately.
Thanks,
-Dale
^ permalink raw reply [flat|nested] 87+ messages in thread
* [PATCH 6/13] powerpc: Add arch/powerpc interrupt handler for mv64x60
2007-04-25 23:58 ` [PATCH 6/13] powerpc: Add arch/powerpc support for Marvell/mv64x60 hostbridge Mark A. Greer
2007-04-26 0:42 ` Arnd Bergmann
@ 2007-05-02 21:38 ` Dale Farnsworth
2007-05-03 1:47 ` Stephen Rothwell
1 sibling, 1 reply; 87+ messages in thread
From: Dale Farnsworth @ 2007-05-02 21:38 UTC (permalink / raw)
To: linuxppc-dev
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 [flat|nested] 87+ messages in thread
* Re: [PATCH 6/13] powerpc: Add arch/powerpc interrupt handler for mv64x60
2007-05-02 21:38 ` [PATCH 6/13] powerpc: Add arch/powerpc interrupt handler for mv64x60 Dale Farnsworth
@ 2007-05-03 1:47 ` Stephen Rothwell
2007-05-03 2:55 ` Dale Farnsworth
0 siblings, 1 reply; 87+ messages in thread
From: Stephen Rothwell @ 2007-05-03 1:47 UTC (permalink / raw)
To: Dale Farnsworth; +Cc: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 601 bytes --]
On Wed, 2 May 2007 14:38:30 -0700 "Dale Farnsworth" <dale@farnsworth.org> wrote:
>
> +DEFINE_SPINLOCK(mv64x60_lock);
Does this need to be global (it is not declared in the header file)?
> +static u32 mv64x60_cached_low_mask = 0;
> +static u32 mv64x60_cached_high_mask = MV64X60_HIGH_GPP_GROUPS;
> +static u32 mv64x60_cached_gpp_mask = 0;
Don't initialise things to zero, please. If you feel it is necessary,
put the "= 0" in a comment. But generally we know that globals are
initially zero.
--
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 [flat|nested] 87+ messages in thread
* Re: [PATCH 6/13] powerpc: Add arch/powerpc interrupt handler for mv64x60
2007-05-03 1:47 ` Stephen Rothwell
@ 2007-05-03 2:55 ` Dale Farnsworth
0 siblings, 0 replies; 87+ messages in thread
From: Dale Farnsworth @ 2007-05-03 2:55 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: linuxppc-dev
On Thu, May 03, 2007 at 11:47:05AM +1000, Stephen Rothwell wrote:
> On Wed, 2 May 2007 14:38:30 -0700 "Dale Farnsworth" <dale@farnsworth.org> wrote:
> >
> > +DEFINE_SPINLOCK(mv64x60_lock);
>
> Does this need to be global (it is not declared in the header file)?
No, it doesn't. I made it static.
> > +static u32 mv64x60_cached_low_mask = 0;
> > +static u32 mv64x60_cached_high_mask = MV64X60_HIGH_GPP_GROUPS;
> > +static u32 mv64x60_cached_gpp_mask = 0;
>
> Don't initialise things to zero, please. If you feel it is necessary,
> put the "= 0" in a comment. But generally we know that globals are
> initially zero.
OK. Thanks.
-Dale
^ permalink raw reply [flat|nested] 87+ messages in thread
* [PATCH 7/13] powerpc: Add arch/powerpc mv64x60 MPSC platform data setup
2007-04-25 23:46 [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800 Mark A. Greer
` (5 preceding siblings ...)
2007-04-25 23:58 ` [PATCH 6/13] powerpc: Add arch/powerpc support for Marvell/mv64x60 hostbridge Mark A. Greer
@ 2007-04-25 23:59 ` Mark A. Greer
2007-04-26 0:14 ` Arnd Bergmann
2007-05-02 21:41 ` Dale Farnsworth
2007-04-26 0:00 ` [PATCH 8/13] powerpc: Add arch/powerpc mv64x60_eth platform data setup Mark A. Greer
` (6 subsequent siblings)
13 siblings, 2 replies; 87+ messages in thread
From: Mark A. Greer @ 2007-04-25 23:59 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
From: Dale Farnsworth <dale@farnsworth.org>
Signed-off-by: Dale Farnsworth <dale@farnsworth.org>
---
mv64x60.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 170 insertions(+)
Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
===================================================================
--- linux-2.6-powerpc-df.orig/arch/powerpc/sysdev/mv64x60.c
+++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
@@ -15,6 +15,9 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/mv643xx.h>
+#include <linux/platform_device.h>
#include <asm/byteorder.h>
#include <asm/io.h>
@@ -341,3 +344,170 @@ int __init mv64x60_verify_cache_coherenc
}
late_initcall(mv64x60_verify_cache_coherency);
+
+/*
+ * 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_platform_device_init(void)
+{
+ struct device_node *np = NULL;
+ unsigned int i;
+ struct platform_device *pdev;
+ int err;
+
+ for (i = 0; (np = of_find_compatible_node(np, "serial", "mpsc")); i++) {
+ struct resource r[5];
+ struct mpsc_pdata pdata;
+ const unsigned int *prop;
+ const phandle *ph;
+ struct device_node *sdma, *brg;
+
+ memset(&r, 0, sizeof(r));
+
+ if (i == 0) {
+ err = mv64x60_mpsc_register_shared_pdev(np);
+ if (err)
+ goto ret_node_put;
+ }
+
+ err = of_address_to_resource(np, 0, &r[0]);
+ if (err)
+ goto ret_node_put;
+
+ of_irq_to_resource(np, 0, &r[4]);
+
+ ph = of_get_property(np, "sdma", NULL);
+ sdma = of_find_node_by_phandle(*ph);
+ if (!sdma) {
+ err = -ENODEV;
+ goto ret_node_put;
+ }
+ of_irq_to_resource(sdma, 0, &r[3]);
+ err = of_address_to_resource(sdma, 0, &r[1]);
+ of_node_put(sdma);
+ if (err)
+ goto ret_node_put;
+
+ ph = of_get_property(np, "brg", NULL);
+ brg = of_find_node_by_phandle(*ph);
+ if (!brg) {
+ err = -ENODEV;
+ goto ret_node_put;
+ }
+
+ err = of_address_to_resource(brg, 0, &r[2]);
+ of_node_put(brg);
+ if (err)
+ goto ret_node_put;
+
+ pdev = platform_device_register_simple(MPSC_CTLR_NAME, i, r, 5);
+ if (IS_ERR(pdev)) {
+ err = PTR_ERR(pdev);
+ goto ret_node_put;
+ }
+
+ memset(&pdata, 0, sizeof(pdata));
+
+ pdata.cache_mgmt = 1; /* All current revs need this set */
+
+ 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;
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto ret_unreg;
+ of_node_put(np);
+ }
+
+ return 0;
+
+ret_unreg:
+ platform_device_unregister(pdev);
+ret_node_put:
+ of_node_put(np);
+ return err;
+}
+
+arch_initcall(mv64x60_mpsc_platform_device_init);
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 7/13] powerpc: Add arch/powerpc mv64x60 MPSC platform data setup
2007-04-25 23:59 ` [PATCH 7/13] powerpc: Add arch/powerpc mv64x60 MPSC platform data setup Mark A. Greer
@ 2007-04-26 0:14 ` Arnd Bergmann
2007-04-26 5:57 ` Dale Farnsworth
2007-05-02 21:41 ` Dale Farnsworth
1 sibling, 1 reply; 87+ messages in thread
From: Arnd Bergmann @ 2007-04-26 0:14 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras
On Thursday 26 April 2007, Mark A. Greer wrote:
> +static int __init mv64x60_mpsc_platform_device_init(void)
> +{
> +=A0=A0=A0=A0=A0=A0=A0struct device_node *np =3D NULL;
> +=A0=A0=A0=A0=A0=A0=A0unsigned int i;
> +=A0=A0=A0=A0=A0=A0=A0struct platform_device *pdev;
> +=A0=A0=A0=A0=A0=A0=A0int err;
> +
> +=A0=A0=A0=A0=A0=A0=A0for (i =3D 0; (np =3D of_find_compatible_node(np, "=
serial", "mpsc")); i++) {
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0struct resource r[5];
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0struct mpsc_pdata pdata;
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0const unsigned int *prop;
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0const phandle *ph;
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0struct device_node *sdma, *=
brg;
This looks wrong to me. See drivers/serial/of_serial.c to find how we do it=
for
8250 compatible serial ports. You should probably just add your serial port
stuff in there as well, instead of doing your own scanning of the device tr=
ee.
> + pdev =3D platform_device_register_simple(MPSC_CTLR_NAME, =
i, r, 5);
> + if (IS_ERR(pdev)) {
> + err =3D PTR_ERR(pdev);
> + goto ret_node_put;
> + }
Now this really needs some explanation.
Why the heck do you have a platform device that gets its resources from
nonstandard properties of a serial port?
Arnd <><
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 7/13] powerpc: Add arch/powerpc mv64x60 MPSC platform data setup
2007-04-26 0:14 ` Arnd Bergmann
@ 2007-04-26 5:57 ` Dale Farnsworth
2007-04-26 11:24 ` Arnd Bergmann
0 siblings, 1 reply; 87+ messages in thread
From: Dale Farnsworth @ 2007-04-26 5:57 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
On Thu, Apr 26, 2007 at 12:14:07AM +0000, Arnd Bergmann wrote:
> On Thursday 26 April 2007, Mark A. Greer wrote:
> > +static int __init mv64x60_mpsc_platform_device_init(void)
> > +{
> > + struct device_node *np = NULL;
> > + unsigned int i;
> > + struct platform_device *pdev;
> > + int err;
> > +
> > + for (i = 0; (np = of_find_compatible_node(np, "serial", "mpsc")); i++) {
> > + struct resource r[5];
> > + struct mpsc_pdata pdata;
> > + const unsigned int *prop;
> > + const phandle *ph;
> > + struct device_node *sdma, *brg;
>
> This looks wrong to me. See drivers/serial/of_serial.c to find how we do it for
> 8250 compatible serial ports. You should probably just add your serial port
> stuff in there as well, instead of doing your own scanning of the device tree.
Unfortunately, this hardware is very much non-8250 compatible.
> > + pdev = platform_device_register_simple(MPSC_CTLR_NAME, i, r, 5);
> > + if (IS_ERR(pdev)) {
> > + err = PTR_ERR(pdev);
> > + goto ret_node_put;
> > + }
>
> Now this really needs some explanation.
>
> Why the heck do you have a platform device that gets its resources from
> nonstandard properties of a serial port?
There is an existing mpsc driver usable on both MIPS and powerpc platforms
that requires these non-standard properties.
-Dale
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 7/13] powerpc: Add arch/powerpc mv64x60 MPSC platform data setup
2007-04-26 5:57 ` Dale Farnsworth
@ 2007-04-26 11:24 ` Arnd Bergmann
2007-04-26 14:30 ` Dale Farnsworth
0 siblings, 1 reply; 87+ messages in thread
From: Arnd Bergmann @ 2007-04-26 11:24 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras
On Thursday 26 April 2007, Dale Farnsworth wrote:
> > This looks wrong to me. See drivers/serial/of_serial.c to find how we d=
o it for
> > 8250 compatible serial ports. You should probably just add your serial =
port
> > stuff in there as well, instead of doing your own scanning of the devic=
e tree.
>=20
> Unfortunately, this hardware is very much non-8250 compatible.
That shouldn't matter much. The driver is not 8250 specific by itself, it's=
just
that right now it doesn't know about any other chips.
If you find that there is more code that needs to be added than what is alr=
eady
in there, you could also create a new one based on of_serial for your port.
I can understand why you want to keep using the platform_device here, and i=
n the
other places, but if you do then please use platform_device_register from an
of_platform_driver probe function instead of platform_device_register_simple
so you can set the parent to the of_device.
> > > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0pdev =3D platform_device_register_s=
imple(MPSC_CTLR_NAME, i, r, 5);
> > > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0if (IS_ERR(pdev)) {
> > > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0err =3D PTR=
_ERR(pdev);
> > > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0goto ret_no=
de_put;
> > > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0}
> >=20
> > Now this really needs some explanation.
> >=20
> > Why the heck do you have a platform device that gets its resources from
> > nonstandard properties of a serial port?
>=20
> There is an existing mpsc driver usable on both MIPS and powerpc platforms
> that requires these non-standard properties.
Ok, I see where some of the limitations come from. However, instead of
introducing the new "sdma" and "brg" properties, why not just add the
register ranges to the "reg" property, like other drivers do?
Arnd <><
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 7/13] powerpc: Add arch/powerpc mv64x60 MPSC platform data setup
2007-04-26 11:24 ` Arnd Bergmann
@ 2007-04-26 14:30 ` Dale Farnsworth
2007-04-26 15:14 ` Arnd Bergmann
0 siblings, 1 reply; 87+ messages in thread
From: Dale Farnsworth @ 2007-04-26 14:30 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
On Thu, Apr 26, 2007 at 01:24:19PM +0200, Arnd Bergmann wrote:
> On Thursday 26 April 2007, Dale Farnsworth wrote:
> > > This looks wrong to me. See drivers/serial/of_serial.c to find how we do it for
> > > 8250 compatible serial ports. You should probably just add your serial port
> > > stuff in there as well, instead of doing your own scanning of the device tree.
> >
> > Unfortunately, this hardware is very much non-8250 compatible.
>
> That shouldn't matter much. The driver is not 8250 specific by itself,
> it's just that right now it doesn't know about any other chips.
Hmm, I wouldn't call that a driver, I'd call it OF interface
glue used to register the driver. I guess I could put the
platform_device_register call for the mpsc driver in that file.
But I think that will increase, rather than reduce complexity.
>
> If you find that there is more code that needs to be added than what is already
> in there, you could also create a new one based on of_serial for your port.
>
> I can understand why you want to keep using the platform_device here, and in the
> other places, but if you do then please use platform_device_register from an
> of_platform_driver probe function instead of platform_device_register_simple
> so you can set the parent to the of_device.
>
> > > > +???????????pdev = platform_device_register_simple(MPSC_CTLR_NAME, i, r, 5);
> > > > +???????????if (IS_ERR(pdev)) {
> > > > +???????????????????err = PTR_ERR(pdev);
> > > > +???????????????????goto ret_node_put;
> > > > +???????????}
Can you coerce your mailer to stop munging tabs?
> > > Now this really needs some explanation.
> > >
> > > Why the heck do you have a platform device that gets its resources from
> > > nonstandard properties of a serial port?
> >
> > There is an existing mpsc driver usable on both MIPS and powerpc platforms
> > that requires these non-standard properties.
>
> Ok, I see where some of the limitations come from. However, instead of
> introducing the new "sdma" and "brg" properties, why not just add the
> register ranges to the "reg" property, like other drivers do?
The sdma and brg are not simply properties of the serial device, these
nodes represent hardware modules that may be shared by multiple drivers.
-Dale
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 7/13] powerpc: Add arch/powerpc mv64x60 MPSC platform data setup
2007-04-26 14:30 ` Dale Farnsworth
@ 2007-04-26 15:14 ` Arnd Bergmann
0 siblings, 0 replies; 87+ messages in thread
From: Arnd Bergmann @ 2007-04-26 15:14 UTC (permalink / raw)
To: Dale Farnsworth; +Cc: linuxppc-dev, Paul Mackerras
On Thursday 26 April 2007, Dale Farnsworth wrote:
> On Thu, Apr 26, 2007 at 01:24:19PM +0200, Arnd Bergmann wrote:
> > On Thursday 26 April 2007, Dale Farnsworth wrote:
> > > > This looks wrong to me. See drivers/serial/of_serial.c to find how we do it for
> > > > 8250 compatible serial ports. You should probably just add your serial port
> > > > stuff in there as well, instead of doing your own scanning of the device tree.
> > >
> > > Unfortunately, this hardware is very much non-8250 compatible.
> >
> > That shouldn't matter much. The driver is not 8250 specific by itself,
> > it's just that right now it doesn't know about any other chips.
>
> Hmm, I wouldn't call that a driver, I'd call it OF interface
> glue used to register the driver.
I mean driver in the sense that it registers a struct device_driver, not
that it does anything particularly interesting with the hardware
> I guess I could put the
> platform_device_register call for the mpsc driver in that file.
> But I think that will increase, rather than reduce complexity.
Right, I wasn't thinking of that. Instead I meant you should call the
mpsc_drv_probe() function (or some variation of that) directly from
of_platform_serial_probe(), the way that I call serial8250_register_port.
> > > > > +???????????pdev = platform_device_register_simple(MPSC_CTLR_NAME, i, r, 5);
> > > > > +???????????if (IS_ERR(pdev)) {
> > > > > +???????????????????err = PTR_ERR(pdev);
> > > > > +???????????????????goto ret_node_put;
> > > > > +???????????}
>
> Can you coerce your mailer to stop munging tabs?
sorry about that, it always happens when I copy something over from my vim.
> > Ok, I see where some of the limitations come from. However, instead of
> > introducing the new "sdma" and "brg" properties, why not just add the
> > register ranges to the "reg" property, like other drivers do?
>
> The sdma and brg are not simply properties of the serial device, these
> nodes represent hardware modules that may be shared by multiple drivers.
Ok, this looks like a mess that is rather hard to clean up and now might
not be the time to start working on that. If these are shared by multiple
high-level drivers, it sounds like there ought to be a driver for each of
them that also does the necessary locking to serialize register accesses.
Arnd <><
^ permalink raw reply [flat|nested] 87+ messages in thread
* [PATCH 7/13] powerpc: Add arch/powerpc mv64x60 MPSC platform data setup
2007-04-25 23:59 ` [PATCH 7/13] powerpc: Add arch/powerpc mv64x60 MPSC platform data setup Mark A. Greer
2007-04-26 0:14 ` Arnd Bergmann
@ 2007-05-02 21:41 ` Dale Farnsworth
2007-05-03 6:40 ` Arnd Bergmann
2007-05-04 21:03 ` [PATCH 7/13] powerpc: Create Marvell mv64x60 MPSC (serial) platform_data Dale Farnsworth
1 sibling, 2 replies; 87+ messages in thread
From: Dale Farnsworth @ 2007-05-02 21:41 UTC (permalink / raw)
To: linuxppc-dev
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 [flat|nested] 87+ messages in thread
* Re: [PATCH 7/13] powerpc: Add arch/powerpc mv64x60 MPSC platform data setup
2007-05-02 21:41 ` Dale Farnsworth
@ 2007-05-03 6:40 ` Arnd Bergmann
2007-05-04 21:03 ` [PATCH 7/13] powerpc: Create Marvell mv64x60 MPSC (serial) platform_data Dale Farnsworth
1 sibling, 0 replies; 87+ messages in thread
From: Arnd Bergmann @ 2007-05-03 6:40 UTC (permalink / raw)
To: linuxppc-dev
On Wednesday 02 May 2007, Dale Farnsworth wrote:
> Signed-off-by: Dale Farnsworth <dale@farnsworth.org>
A patch comment about what functionality exactly gets added
would be good, I forgot to mention that when first looking at
the patch. Otherwise looks good.
Acked-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply [flat|nested] 87+ messages in thread
* [PATCH 7/13] powerpc: Create Marvell mv64x60 MPSC (serial) platform_data
2007-05-02 21:41 ` Dale Farnsworth
2007-05-03 6:40 ` Arnd Bergmann
@ 2007-05-04 21:03 ` Dale Farnsworth
2007-05-05 12:26 ` Arnd Bergmann
1 sibling, 1 reply; 87+ messages in thread
From: Dale Farnsworth @ 2007-05-04 21:03 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Stephen Rothwell, Paul Mackerras, Arnd Bergmann
This patch creates platform_device entries for the Marvell mv64x60
MPSC (multi-protocol serial controller) ports, based on information
contained in the device tree.
Signed-off-by: Dale Farnsworth <dale@farnsworth.org>
---
Latest rev. I believe I have address all the issues raised by
Stephen Rothwell and Arnd Bergmann.
arch/powerpc/platforms/embedded6xx/Kconfig | 3
arch/powerpc/sysdev/Makefile | 2
arch/powerpc/sysdev/mv64x60_dev.c | 221 +++++++++++++++++++
3 files changed, 225 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,221 @@
+/*
+ * 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;
+
+ memset(&pdata, 0, sizeof(pdata));
+
+ pdev = platform_device_alloc(MPSC_SHARED_NAME, 0);
+ if (!pdev)
+ return -ENOMEM;
+
+ err = platform_device_add_resources(pdev, r, 2);
+ if (err)
+ goto error;
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto error;
+
+ err = platform_device_add(pdev);
+ if (err)
+ goto error;
+
+ return 0;
+
+error:
+ platform_device_put(pdev);
+ return err;
+}
+
+
+static int __init mv64x60_mpsc_device_setup(struct device_node *np, int id)
+{
+ 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;
+
+ /* only register the shared platform device the first time through */
+ if (id == 0 && (err = mv64x60_mpsc_register_shared_pdev(np)))
+ return err;
+
+ 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;
+
+ prop = of_get_property(np, "block-index", NULL);
+ if (!prop)
+ return -ENODEV;
+ port_number = *(int *)prop;
+
+ memset(&pdata, 0, sizeof(pdata));
+
+ pdata.cache_mgmt = 1; /* All current revs need this set */
+
+ 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_alloc(MPSC_CTLR_NAME, port_number);
+ if (!pdev)
+ return -ENOMEM;
+
+ err = platform_device_add_resources(pdev, r, 5);
+ if (err)
+ goto error;
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto error;
+
+ err = platform_device_add(pdev);
+ if (err)
+ goto error;
+
+ return 0;
+
+error:
+ platform_device_put(pdev);
+ return err;
+}
+
+static int __init mv64x60_device_setup(void)
+{
+ struct device_node *np = NULL;
+ int id;
+ int err;
+
+ for (id = 0;
+ (np = of_find_compatible_node(np, "serial", "mpsc")); id++)
+ if ((err = mv64x60_mpsc_device_setup(np, id)))
+ goto error;
+
+ return 0;
+
+error:
+ 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 [flat|nested] 87+ messages in thread
* [PATCH 8/13] powerpc: Add arch/powerpc mv64x60_eth platform data setup
2007-04-25 23:46 [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800 Mark A. Greer
` (6 preceding siblings ...)
2007-04-25 23:59 ` [PATCH 7/13] powerpc: Add arch/powerpc mv64x60 MPSC platform data setup Mark A. Greer
@ 2007-04-26 0:00 ` Mark A. Greer
2007-04-26 0:18 ` Arnd Bergmann
2007-05-02 21:43 ` Dale Farnsworth
2007-04-26 0:00 ` [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup Mark A. Greer
` (5 subsequent siblings)
13 siblings, 2 replies; 87+ messages in thread
From: Mark A. Greer @ 2007-04-26 0:00 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
From: Dale Farnsworth <dale@farnsworth.org>
Signed-off-by: Dale Farnsworth <dale@farnsworth.org>
---
arch/powerpc/sysdev/mv64x60.c | 135 ++++++++++++++++++++++++++++++++++++++++++
drivers/net/Kconfig | 2
2 files changed, 136 insertions(+), 1 deletion(-)
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
@@ -2301,7 +2301,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
Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
===================================================================
--- linux-2.6-powerpc-df.orig/arch/powerpc/sysdev/mv64x60.c
+++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
@@ -511,3 +511,138 @@ ret_node_put:
}
arch_initcall(mv64x60_mpsc_platform_device_init);
+
+/*
+ * Create mv64x60_eth platform device
+ */
+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_platform_device_init(void)
+{
+ struct device_node *np = NULL;
+ unsigned int i;
+ struct platform_device *pdev;
+ int err;
+
+ for (i = 0;
+ (np = of_find_compatible_node(np, "network", "mv64x60-eth"));
+ i++) {
+ struct device_node *phy;
+ struct mv643xx_eth_platform_data pdata;
+ const u8 *mac_addr;
+ const void *prop;
+ const phandle *ph;
+ struct resource res;
+
+ if (i == 0) {
+ err = eth_register_shared_pdev(np);
+ if (err)
+ goto ret_node_put;
+ }
+
+ memset(&res, 0, sizeof(res));
+ of_irq_to_resource(np, 0, &res);
+
+ pdev = platform_device_register_simple(MV643XX_ETH_NAME,
+ i, &res, 1);
+ if (IS_ERR(pdev)) {
+ err = PTR_ERR(pdev);
+ goto ret_node_put;
+ }
+
+ memset(&pdata, 0, sizeof(pdata));
+
+ prop = of_get_property(np, "block-index", NULL);
+ if (prop)
+ pdata.port_number = *(int *)prop;
+ else
+ pdata.port_number = i;
+
+ 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) {
+ err = -ENODEV;
+ goto ret_unreg;
+ }
+
+ phy = of_find_node_by_phandle(*ph);
+ if (phy == NULL) {
+ err = -ENODEV;
+ goto ret_unreg;
+ }
+
+ prop = of_get_property(phy, "reg", NULL);
+ if (prop) {
+ pdata.force_phy_addr = 1;
+ pdata.phy_addr = *(int *)prop;
+ }
+
+ of_node_put(phy);
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto ret_unreg;
+ }
+
+ return 0;
+
+ret_unreg:
+ platform_device_unregister(pdev);
+ret_node_put:
+ of_node_put(np);
+ return err;
+}
+
+arch_initcall(mv64x60_eth_platform_device_init);
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 8/13] powerpc: Add arch/powerpc mv64x60_eth platform data setup
2007-04-26 0:00 ` [PATCH 8/13] powerpc: Add arch/powerpc mv64x60_eth platform data setup Mark A. Greer
@ 2007-04-26 0:18 ` Arnd Bergmann
2007-04-26 6:00 ` Dale Farnsworth
2007-05-02 21:43 ` Dale Farnsworth
1 sibling, 1 reply; 87+ messages in thread
From: Arnd Bergmann @ 2007-04-26 0:18 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras
On Thursday 26 April 2007, Mark A. Greer wrote:
> Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> --- linux-2.6-powerpc-df.orig/arch/powerpc/sysdev/mv64x60.c
> +++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
> @@ -511,3 +511,138 @@ ret_node_put:
> =A0}
> =A0
> =A0arch_initcall(mv64x60_mpsc_platform_device_init);
> +
> +/*
> + * Create mv64x60_eth platform device
> + */
> +static int __init eth_register_shared_pdev(struct device_node *np)
> +{
> +=A0=A0=A0=A0=A0=A0=A0struct platform_device *pdev;
No need to put this into architecture specific code, just register
the of_platform_driver from mv643xx_init_module and use the device
you get passed in there.
Once arch/ppc is dead, you can remove the platform_driver from mv643xx
entirely.
Arnd <><
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 8/13] powerpc: Add arch/powerpc mv64x60_eth platform data setup
2007-04-26 0:18 ` Arnd Bergmann
@ 2007-04-26 6:00 ` Dale Farnsworth
0 siblings, 0 replies; 87+ messages in thread
From: Dale Farnsworth @ 2007-04-26 6:00 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
On Thu, Apr 26, 2007 at 12:18:45AM +0000, Arnd Bergmann wrote:
> On Thursday 26 April 2007, Mark A. Greer wrote:
> > Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
> > --- linux-2.6-powerpc-df.orig/arch/powerpc/sysdev/mv64x60.c
> > +++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
> > @@ -511,3 +511,138 @@ ret_node_put:
> > }
> >
> >arch_initcall(mv64x60_mpsc_platform_device_init);
> > +
> > +/*
> > + * Create mv64x60_eth platform device
> > + */
> > +static int __init eth_register_shared_pdev(struct device_node *np)
> > +{
> > + struct platform_device *pdev;
>
> No need to put this into architecture specific code, just register
> the of_platform_driver from mv643xx_init_module and use the device
> you get passed in there.
>
> Once arch/ppc is dead, you can remove the platform_driver from mv643xx
> entirely.
Like with the mpsc driver, there is an existing platform-driver-based
ethernet driver used by MIPS and powerpc platforms. OF isn't universal yet.
-Dale
^ permalink raw reply [flat|nested] 87+ messages in thread
* [PATCH 8/13] powerpc: Add arch/powerpc mv64x60_eth platform data setup
2007-04-26 0:00 ` [PATCH 8/13] powerpc: Add arch/powerpc mv64x60_eth platform data setup Mark A. Greer
2007-04-26 0:18 ` Arnd Bergmann
@ 2007-05-02 21:43 ` Dale Farnsworth
2007-05-03 2:03 ` Stephen Rothwell
` (2 more replies)
1 sibling, 3 replies; 87+ messages in thread
From: Dale Farnsworth @ 2007-05-02 21:43 UTC (permalink / raw)
To: linuxppc-dev
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 [flat|nested] 87+ messages in thread
* Re: [PATCH 8/13] powerpc: Add arch/powerpc mv64x60_eth platform data setup
2007-05-02 21:43 ` Dale Farnsworth
@ 2007-05-03 2:03 ` Stephen Rothwell
2007-05-03 6:43 ` Arnd Bergmann
2007-05-04 21:06 ` [PATCH 8/13] powerpc: Create Marvell mv64x60 ethernet platform_data Dale Farnsworth
2 siblings, 0 replies; 87+ messages in thread
From: Stephen Rothwell @ 2007-05-03 2:03 UTC (permalink / raw)
To: Dale Farnsworth; +Cc: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 333 bytes --]
On Wed, 2 May 2007 14:43:12 -0700 "Dale Farnsworth" <dale@farnsworth.org> wrote:
>
> + const void *prop;
Since all uses of this are being cast to "int *" before being
dereferenced, maybe you should declare it as a "const int *".
--
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 [flat|nested] 87+ messages in thread
* Re: [PATCH 8/13] powerpc: Add arch/powerpc mv64x60_eth platform data setup
2007-05-02 21:43 ` Dale Farnsworth
2007-05-03 2:03 ` Stephen Rothwell
@ 2007-05-03 6:43 ` Arnd Bergmann
2007-05-04 21:06 ` [PATCH 8/13] powerpc: Create Marvell mv64x60 ethernet platform_data Dale Farnsworth
2 siblings, 0 replies; 87+ messages in thread
From: Arnd Bergmann @ 2007-05-03 6:43 UTC (permalink / raw)
To: linuxppc-dev
On Wednesday 02 May 2007, Dale Farnsworth wrote:
> Signed-off-by: Dale Farnsworth <dale@farnsworth.org>
Acked-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply [flat|nested] 87+ messages in thread
* [PATCH 8/13] powerpc: Create Marvell mv64x60 ethernet platform_data
2007-05-02 21:43 ` Dale Farnsworth
2007-05-03 2:03 ` Stephen Rothwell
2007-05-03 6:43 ` Arnd Bergmann
@ 2007-05-04 21:06 ` Dale Farnsworth
2007-05-05 12:28 ` Arnd Bergmann
2 siblings, 1 reply; 87+ messages in thread
From: Dale Farnsworth @ 2007-05-04 21:06 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Stephen Rothwell, Paul Mackerras, Arnd Bergmann
This patch creates platform_device entries for the Marvell mv64x60
ethernet controller ports, based on information contained in the
device tree.
Signed-off-by: Dale Farnsworth <dale@farnsworth.org>
---
Latest rev. I think I've addressed all of Stephen Rothwell's and
Arnd Bergmann's comments. Thanks.
arch/powerpc/sysdev/mv64x60_dev.c | 129 +++++++++++++++++++++++++++-
drivers/net/Kconfig | 2
2 files changed, 129 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
@@ -201,6 +201,128 @@ error:
return err;
}
+/*
+ * Create mv64x60_eth platform devices
+ */
+static int __init eth_register_shared_pdev(struct device_node *np)
+{
+ struct platform_device *pdev;
+ struct resource r[1];
+ int err;
+
+ np = of_get_parent(np);
+ if (!np)
+ return -ENODEV;
+
+ err = of_address_to_resource(np, 0, &r[0]);
+ of_node_put(np);
+ if (err)
+ return err;
+
+ pdev = platform_device_register_simple(MV643XX_ETH_SHARED_NAME, 0,
+ r, 1);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return 0;
+}
+
+static int __init mv64x60_eth_device_setup(struct device_node *np, int id)
+{
+ struct resource r[1];
+ struct mv643xx_eth_platform_data pdata;
+ struct platform_device *pdev;
+ struct device_node *phy;
+ const u8 *mac_addr;
+ const int *prop;
+ const phandle *ph;
+ int err;
+
+ /* only register the shared platform device the first time through */
+ if (id == 0 && (err = eth_register_shared_pdev(np)))
+ return err;;
+
+ memset(r, 0, sizeof(r));
+ of_irq_to_resource(np, 0, &r[0]);
+
+ memset(&pdata, 0, sizeof(pdata));
+
+ prop = of_get_property(np, "block-index", NULL);
+ if (!prop)
+ return -ENODEV;
+ pdata.port_number = *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 = *prop;
+
+ prop = of_get_property(np, "tx_queue_size", NULL);
+ if (prop)
+ pdata.tx_queue_size = *prop;
+
+ prop = of_get_property(np, "rx_queue_size", NULL);
+ if (prop)
+ pdata.rx_queue_size = *prop;
+
+ prop = of_get_property(np, "tx_sram_addr", NULL);
+ if (prop)
+ pdata.tx_sram_addr = *prop;
+
+ prop = of_get_property(np, "tx_sram_size", NULL);
+ if (prop)
+ pdata.tx_sram_size = *prop;
+
+ prop = of_get_property(np, "rx_sram_addr", NULL);
+ if (prop)
+ pdata.rx_sram_addr = *prop;
+
+ prop = of_get_property(np, "rx_sram_size", NULL);
+ if (prop)
+ pdata.rx_sram_size = *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 = *prop;
+ }
+
+ of_node_put(phy);
+
+ pdev = platform_device_alloc(MV643XX_ETH_NAME, pdata.port_number);
+ if (!pdev)
+ return -ENOMEM;
+
+ err = platform_device_add_resources(pdev, r, 1);
+ if (err)
+ goto error;
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto error;
+
+ err = platform_device_add(pdev);
+ if (err)
+ goto error;
+
+ return 0;
+
+error:
+ platform_device_put(pdev);
+ return err;
+}
+
static int __init mv64x60_device_setup(void)
{
struct device_node *np = NULL;
@@ -212,6 +334,11 @@ static int __init mv64x60_device_setup(v
if ((err = mv64x60_mpsc_device_setup(np, id)))
goto error;
+ for (id = 0;
+ (np = of_find_compatible_node(np, "network", "mv64x60-eth")); id++)
+ if ((err = mv64x60_eth_device_setup(np, id)))
+ goto error;
+
return 0;
error:
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
@@ -2299,7 +2299,7 @@ config UGETH_TX_ON_DEMAND
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 [flat|nested] 87+ messages in thread
* [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
2007-04-25 23:46 [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800 Mark A. Greer
` (7 preceding siblings ...)
2007-04-26 0:00 ` [PATCH 8/13] powerpc: Add arch/powerpc mv64x60_eth platform data setup Mark A. Greer
@ 2007-04-26 0:00 ` Mark A. Greer
2007-04-26 0:21 ` Arnd Bergmann
2007-05-02 21:44 ` Dale Farnsworth
2007-04-26 0:01 ` [PATCH 10/13] powerpc: Add arch/powerpc mv64x60 PCI setup Mark A. Greer
` (4 subsequent siblings)
13 siblings, 2 replies; 87+ messages in thread
From: Mark A. Greer @ 2007-04-26 0:00 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
From: Dale Farnsworth <dale@farnsworth.org>
Signed-off-by: Dale Farnsworth <dale@farnsworth.org>
---
mv64x60.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
===================================================================
--- linux-2.6-powerpc-df.orig/arch/powerpc/sysdev/mv64x60.c
+++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
@@ -646,3 +646,78 @@ ret_node_put:
}
arch_initcall(mv64x60_eth_platform_device_init);
+
+/*
+ * Create mv64x60_i2c platform device
+ */
+static int __init mv64x60_i2c_platform_device_init(void)
+{
+ struct device_node *np = NULL;
+ int i;
+ struct platform_device *pdev;
+ int err;
+
+ for (i = 0;
+ (np = of_find_compatible_node(np, "i2c", "mv64x60-i2c"));
+ i++) {
+ struct resource r[2];
+ struct mv64xxx_i2c_pdata pdata;
+ const unsigned int *prop;
+
+ err = of_address_to_resource(np, 0, &r[0]);
+ if (err)
+ goto ret_node_put;
+
+ memset(&r[1], 0, sizeof(r[1]));
+ of_irq_to_resource(np, 0, &r[1]);
+
+ pdev = platform_device_register_simple(MV64XXX_I2C_CTLR_NAME,
+ 0, r, 2);
+ if (IS_ERR(pdev)) {
+ err = PTR_ERR(pdev);
+ goto ret_node_put;
+ }
+
+ memset(&pdata, 0, sizeof(pdata));
+
+ prop = of_get_property(np, "freq_m", NULL);
+ if (!prop) {
+ err = -ENODEV;
+ goto ret_unreg;
+ }
+ pdata.freq_m = *prop;
+
+ prop = of_get_property(np, "freq_n", NULL);
+ if (!prop) {
+ err = -ENODEV;
+ goto ret_unreg;
+ }
+ 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;
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto ret_unreg;
+ }
+
+ return 0;
+
+ret_unreg:
+ platform_device_unregister(pdev);
+ret_node_put:
+ of_node_put(np);
+ return err;
+}
+
+arch_initcall(mv64x60_i2c_platform_device_init);
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
2007-04-26 0:00 ` [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup Mark A. Greer
@ 2007-04-26 0:21 ` Arnd Bergmann
2007-04-26 0:43 ` Mark A. Greer
2007-05-02 21:44 ` Dale Farnsworth
1 sibling, 1 reply; 87+ messages in thread
From: Arnd Bergmann @ 2007-04-26 0:21 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras
On Thursday 26 April 2007, Mark A. Greer wrote:
> +static int __init mv64x60_i2c_platform_device_init(void)
> +{
> +=A0=A0=A0=A0=A0=A0=A0struct device_node *np =3D NULL;
> +=A0=A0=A0=A0=A0=A0=A0int i;
> +=A0=A0=A0=A0=A0=A0=A0struct platform_device *pdev;
> +=A0=A0=A0=A0=A0=A0=A0int err;
> +
> +=A0=A0=A0=A0=A0=A0=A0for (i =3D 0;
> +=A0=A0=A0=A0=A0=A0=A0 =A0 =A0 (np =3D of_find_compatible_node(np, "i2c",=
"mv64x60-i2c"));
Same comment as about the ethernet driver: You should register an
of_platform_driver from drivers/i2c/busses/i2c-mv64xxx.c.
Repeat after me:=20
I will not call of_find_compatible_node() from device drivers.
I will not call of_find_compatible_node() from device drivers.
I will not call of_find_compatible_node() from device drivers.
Arnd <><
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
2007-04-26 0:21 ` Arnd Bergmann
@ 2007-04-26 0:43 ` Mark A. Greer
2007-04-26 0:55 ` Arnd Bergmann
0 siblings, 1 reply; 87+ messages in thread
From: Mark A. Greer @ 2007-04-26 0:43 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
On Thu, Apr 26, 2007 at 02:21:19AM +0200, Arnd Bergmann wrote:
> On Thursday 26 April 2007, Mark A. Greer wrote:
> > +static int __init mv64x60_i2c_platform_device_init(void)
> > +{
> > + struct device_node *np = NULL;
> > + int i;
> > + struct platform_device *pdev;
> > + int err;
> > +
> > + for (i = 0;
> > + (np = of_find_compatible_node(np, "i2c", "mv64x60-i2c"));
>
> Same comment as about the ethernet driver: You should register an
> of_platform_driver from drivers/i2c/busses/i2c-mv64xxx.c.
>
> Repeat after me:
>
> I will not call of_find_compatible_node() from device drivers.
> I will not call of_find_compatible_node() from device drivers.
> I will not call of_find_compatible_node() from device drivers.
Well, your comments are for Dale's patches so I'll leave it to him to
answer your questions in detail but...
of_find_compatible_node() is not being called from a driver, its being
called from platform code. Its extracting info from the device tree and
setting up the platform_data required by the driver.
Mark
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
2007-04-26 0:43 ` Mark A. Greer
@ 2007-04-26 0:55 ` Arnd Bergmann
2007-04-26 1:13 ` Mark A. Greer
0 siblings, 1 reply; 87+ messages in thread
From: Arnd Bergmann @ 2007-04-26 0:55 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev, Paul Mackerras
On Thursday 26 April 2007, Mark A. Greer wrote:
> of_find_compatible_node() is not being called from a driver, its being
> called from platform code. =A0Its extracting info from the device tree and
> setting up the platform_data required by the driver.
Well, the idea of putting the device driver code into a platform specific
location is the smaller part of the problem. Even if it was the right
thing to scan the tree and then create platform_data instead of using
the of_device, that code would still belong into the device driver.
Note that the interrupt controller code in patch 6 is different, because
it is not possible to probe interrupt controllers using the Linux
driver model -- any device driver that gets initialized must assume
that the interrupt controller code and some other infrastructure is
already running.
Arnd <><
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
2007-04-26 0:55 ` Arnd Bergmann
@ 2007-04-26 1:13 ` Mark A. Greer
2007-04-26 2:02 ` Arnd Bergmann
0 siblings, 1 reply; 87+ messages in thread
From: Mark A. Greer @ 2007-04-26 1:13 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
On Thu, Apr 26, 2007 at 02:55:03AM +0200, Arnd Bergmann wrote:
> On Thursday 26 April 2007, Mark A. Greer wrote:
> > of_find_compatible_node() is not being called from a driver, its being
> > called from platform code. Its extracting info from the device tree and
> > setting up the platform_data required by the driver.
>
> Well, the idea of putting the device driver code into a platform specific
It isn't device driver code. It providing the driver with some info
that it needs but doesn't have the ability to get, in general.
> location is the smaller part of the problem. Even if it was the right
> thing to scan the tree and then create platform_data instead of using
> the of_device, that code would still belong into the device driver.
I don't think of_device is going to work very well on MIPS.
Mark
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
2007-04-26 1:13 ` Mark A. Greer
@ 2007-04-26 2:02 ` Arnd Bergmann
2007-04-26 6:08 ` Dale Farnsworth
2007-04-26 6:48 ` Mark A. Greer
0 siblings, 2 replies; 87+ messages in thread
From: Arnd Bergmann @ 2007-04-26 2:02 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev, Paul Mackerras
On Thursday 26 April 2007, Mark A. Greer wrote:
> > location is the smaller part of the problem. Even if it was the right
> > thing to scan the tree and then create platform_data instead of using
> > the of_device, that code would still belong into the device driver.
>
> I don't think of_device is going to work very well on MIPS.
Ok, I see your point there. But after looking at the i2c and net drivers,
I believe that they can easily be split into an architecture dependent
part that is either an of_platform_driver or a platform_driver, and
a common part that does not know about either of these.
With the example of the i2c driver, you can have something like:
i2c-mv64xxx.c:
=============
int __devinit mv64xxx_i2c_probe(struct device *dev, struct mv64xxx_i2c_pdata *data,
struct resource *regs, int irq)
{
...
}
EXPORT_SYMBOL_GPL(mv64xxx_i2c_probe);
int __devexit mv64xxx_i2c_remove(struct device *dev)
{
...
}
EXPORT_SYMBOL_GPL(mv64xxx_i2c_remove);
i2c-mv64xxx-pdev.c:
========================
static int __devinit mv64xxx_i2c_probe_pdev(struct platform_device *pd)
{
return mv64xxx_i2c_probe(&pd->dev, &pd->dev.platform_data,
platform_get_resource(pd, IORESOURCE_MEM, 0)),
platform_get_irq(pd, 0));
}
static int __devexit mv64xxx_i2c_remove_pdev(struct platform_device *pd)
{
return mv64xxx_i2c_remove(&pd->dev);
}
static struct platform_driver mv64xxx_i2c_driver = {
.probe = mv64xxx_i2c_probe_pdev,
.remove = mv64xxx_i2c_remove_pdev,
.driver = {
.owner = THIS_MODULE,
.name = MV64XXX_I2C_CTLR_NAME,
},
};
static int __init
mv64xxx_i2c_init_pdev(void)
{
return platform_driver_register(&mv64xxx_i2c_driver);
}
static void __exit
mv64xxx_i2c_exit_pdev(void)
{
platform_driver_unregister(&mv64xxx_i2c_driver);
}
module_init(mv64xxx_i2c_init_pdev);
module_exit(mv64xxx_i2c_exit_pdev);
i2c-mv64xxx-of.c:
========================
static int __devinit mv64xxx_i2c_probe_of(struct of_device *dev)
{
struct mv64xxx_i2c_pdata pdata;
struct resource resource;
int irq;
of_address_to_resource(&dev->node, 0, &resource);
of_map_irq(&dev->node, 0, &irq);
return mv64xxx_i2c_probe(&dev->dev, &pdata, &resource, irq);
}
static int __devexit mv64xxx_i2c_remove_pdev(struct of_device *dev)
{
return mv64xxx_i2c_remove(&dev->dev);
}
static struct of_device_id mv64xxx_i2c_device_ids = {
{ .type = "i2c", .compatible = "mv64x60-i2c" },
{ },
};
static struct of_platform_driver mv64xxx_i2c_of_driver = {
.probe = mv64xxx_i2c_probe_of,
.remove = mv64xxx_i2c_remove_of,
.ids = &mv64xxx_i2c_device_ids,
.driver = {
.owner = THIS_MODULE,
.name = MV64XXX_I2C_CTLR_NAME,
},
};
static int __init
mv64xxx_i2c_init_of(void)
{
return of_platform_driver_register(&mv64xxx_i2c_of_driver);
}
static void __exit
mv64xxx_i2c_exit_of(void)
{
of_platform_driver_unregister(&mv64xxx_i2c_driver);
}
module_init(mv64xxx_i2c_init_of);
module_exit(mv64xxx_i2c_exit_of);
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
2007-04-26 2:02 ` Arnd Bergmann
@ 2007-04-26 6:08 ` Dale Farnsworth
2007-04-26 9:00 ` Arnd Bergmann
2007-04-26 6:48 ` Mark A. Greer
1 sibling, 1 reply; 87+ messages in thread
From: Dale Farnsworth @ 2007-04-26 6:08 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
On Thu, Apr 26, 2007 at 02:02:16AM +0000, Arnd Bergmann wrote:
> On Thursday 26 April 2007, Mark A. Greer wrote:
> > > location is the smaller part of the problem. Even if it was the right
> > > thing to scan the tree and then create platform_data instead of using
> > > the of_device, that code would still belong into the device driver.
> >
> > I don't think of_device is going to work very well on MIPS.
>
> Ok, I see your point there. But after looking at the i2c and net drivers,
> I believe that they can easily be split into an architecture dependent
> part that is either an of_platform_driver or a platform_driver, and
> a common part that does not know about either of these.
Oh, it's certainly possible, but it doesn't seem desirable to me. Why
should the drivers carry the burden of supporting both platform_driver
and of_platform_driver interfaces?
-Dale
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
2007-04-26 6:08 ` Dale Farnsworth
@ 2007-04-26 9:00 ` Arnd Bergmann
2007-04-26 14:19 ` Dale Farnsworth
0 siblings, 1 reply; 87+ messages in thread
From: Arnd Bergmann @ 2007-04-26 9:00 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras
On Thursday 26 April 2007, Dale Farnsworth wrote:
>
> > Ok, I see your point there. But after looking at the i2c and net drivers,
> > I believe that they can easily be split into an architecture dependent
> > part that is either an of_platform_driver or a platform_driver, and
> > a common part that does not know about either of these.
>
> Oh, it's certainly possible, but it doesn't seem desirable to me. Why
> should the drivers carry the burden of supporting both platform_driver
> and of_platform_driver interfaces?
The reason is that platform_devices are for stuff that fundamentally cannot
be probed but has to be hardcoded in some place.
The point about the of device tree is that it allows you to probe this
kind of device. This means you get automatic module loading based on the
device tree, and that the devices show up in sane locations in /sys.
Arnd <><
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
2007-04-26 9:00 ` Arnd Bergmann
@ 2007-04-26 14:19 ` Dale Farnsworth
2007-04-26 15:04 ` Arnd Bergmann
0 siblings, 1 reply; 87+ messages in thread
From: Dale Farnsworth @ 2007-04-26 14:19 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
On Thu, Apr 26, 2007 at 11:00:25AM +0200, Arnd Bergmann wrote:
> On Thursday 26 April 2007, Dale Farnsworth wrote:
> >
> > > Ok, I see your point there. But after looking at the i2c and net drivers,
> > > I believe that they can easily be split into an architecture dependent
> > > part that is either an of_platform_driver or a platform_driver, and
> > > a common part that does not know about either of these.
> >
> > Oh, it's certainly possible, but it doesn't seem desirable to me. Why
> > should the drivers carry the burden of supporting both platform_driver
> > and of_platform_driver interfaces?
>
> The reason is that platform_devices are for stuff that fundamentally cannot
> be probed but has to be hardcoded in some place.
>
> The point about the of device tree is that it allows you to probe this
> kind of device. This means you get automatic module loading based on the
> device tree, and that the devices show up in sane locations in /sys.
I understand the benefits of the DT; that's not the issue.
Here we have platform devices common to MIPS and PowerPC platforms.
The drivers must continue to support the platform_driver interface
for MIPS platforms. The question is, where should we put the glue
that transforms the DT info into the platform_driver format?
You seem to suggest putting the ethernet-related glue into
drivers/net/mv643xx_eth.c. That's bogus, IMHO. The base driver
shouldn't have to accommodate every arch-specific interface.
(I know OF isn't strictly arch-specific, but it's far from universal.)
I put this glue into arch/powerpc/sysdev/mv64x60.c. I still don't see
the benefit of moving it into the drivers.
-Dale
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
2007-04-26 14:19 ` Dale Farnsworth
@ 2007-04-26 15:04 ` Arnd Bergmann
2007-04-27 23:50 ` Dale Farnsworth
2007-05-01 4:45 ` Paul Mackerras
0 siblings, 2 replies; 87+ messages in thread
From: Arnd Bergmann @ 2007-04-26 15:04 UTC (permalink / raw)
To: Dale Farnsworth; +Cc: linuxppc-dev, Paul Mackerras
On Thursday 26 April 2007, Dale Farnsworth wrote:
>=20
> > The point about the of device tree is that it allows you to probe this
> > kind of device. This means you get automatic module loading based on the
> > device tree, and that the devices show up in sane locations in /sys.
>=20
> I understand the benefits of the DT; that's not the issue.
>
> Here we have platform devices common to MIPS and PowerPC platforms.
> The drivers must continue to support the platform_driver interface
> for MIPS platforms. =A0The question is, where should we put the glue
> that transforms the DT info into the platform_driver format?
>=20
> You seem to suggest putting the ethernet-related glue into
> drivers/net/mv643xx_eth.c. =A0That's bogus, IMHO. The base driver
> shouldn't have to accommodate every arch-specific interface.
> (I know OF isn't strictly arch-specific, but it's far from universal.)
> I put this glue into arch/powerpc/sysdev/mv64x60.c. I still don't see
> the benefit of moving it into the drivers.
Maybe you still haven't understood the difference of an of_platform_driver
compared to the platform_driver glue which you are adding here.
I don't want you to move the glue code into the device driver -- I really
think the glue code should not be there in the first place.
As you probably understand, the Linux driver model represents every piece
of hardware as a 'struct device' which can be embedded in things like
of_device, pci_device or platform_device. Then there are 'struct
device_driver's than handle all devices of a given bus_type/device_id
combination.
With the of device tree, you automatically get an of_device for everything
that is connected to an internal (soc, plb, ssb, ...) bus on the chip
or on the board. According to the driver model, they should be driven
by an of_platform_driver.
What your glue code does is to find a backdoor into the device tree
(through of_find_compatible_node) and create a second struct device
for the same hardware, in an unrelated location in the linux device tree.
This is very confusing if you look at sysfs, e.g. trying to find out
which driver is attached to a given of_device.
It also makes you lose the ability to autoload the driver module,
because autoloading is not supported for a platform_driver (there
is no MODULE_DEVICE_TABLE()).
As you made clear, we will need the platform_driver for the forseeable
future, but I really think that we also need an of_platform_driver
to drive them on powerpc instead of adding another pile of junk like
fsl_soc.c.
I can see multiple ways for you to get there:
1. have a driver that binds to all of_devices supported by mv64x60
and then creates the platform_device for them the way you do in your
glue, but without adding code that manually iterates through
the device tree. Make the platform_device a child of the of_device.
This approach is the closest to what you have right now and would
at least get the sysfs representation right, but not allow module
autoloading and it still duplicates all the devices.
2. remove the dependencies on platform_device data structures from
the current driver code, and add them to a separate file, so you
can link the module either with the platform_driver or with the
of_platform_driver, as I suggested in a previous mail.
I think this would be the best solution.
3. Have a small of_device_driver part that gets added to each
of the device drivers, and that adds the platform_device internally.
This would be like 1., but also allow autoloading.
Arnd <><
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
2007-04-26 15:04 ` Arnd Bergmann
@ 2007-04-27 23:50 ` Dale Farnsworth
2007-04-28 1:05 ` Arnd Bergmann
2007-05-01 4:45 ` Paul Mackerras
1 sibling, 1 reply; 87+ messages in thread
From: Dale Farnsworth @ 2007-04-27 23:50 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: Paul Mackerras, linuxppc-dev
On Thu, Apr 26, 2007 at 05:04:06PM +0200, Arnd Bergmann wrote:
> Maybe you still haven't understood the difference of an of_platform_driver
> compared to the platform_driver glue which you are adding here.
>
> I don't want you to move the glue code into the device driver -- I really
> think the glue code should not be there in the first place.
>
> As you probably understand, the Linux driver model represents every piece
> of hardware as a 'struct device' which can be embedded in things like
> of_device, pci_device or platform_device. Then there are 'struct
> device_driver's than handle all devices of a given bus_type/device_id
> combination.
>
> With the of device tree, you automatically get an of_device for everything
> that is connected to an internal (soc, plb, ssb, ...) bus on the chip
> or on the board. According to the driver model, they should be driven
> by an of_platform_driver.
Well, since our platform hasn't called of_platform_bus_probe() with
a device id for the mv64x60 device node, we don't create an of_device
for each of its sub-devices. Instead, we scan separately and create
platform_devices that the existing drivers require, and for the
benefit of those who join this discussion late, which we must
maintain for use by MIPS platforms.
> What your glue code does is to find a backdoor into the device tree
> (through of_find_compatible_node) and create a second struct device
> for the same hardware, in an unrelated location in the linux device tree.
> This is very confusing if you look at sysfs, e.g. trying to find out
> which driver is attached to a given of_device.
No, we don't create the first struct device you mentioned, so we avoid
the duplication and the confusion.
> It also makes you lose the ability to autoload the driver module,
> because autoloading is not supported for a platform_driver (there
> is no MODULE_DEVICE_TABLE()).
>
> As you made clear, we will need the platform_driver for the forseeable
> future, but I really think that we also need an of_platform_driver
> to drive them on powerpc instead of adding another pile of junk like
> fsl_soc.c.
Heh, I was going to ask if you made these points when fsl_soc.c went in. :)
> I can see multiple ways for you to get there:
I find each of these methods lacking.
> 1. have a driver that binds to all of_devices supported by mv64x60
> and then creates the platform_device for them the way you do in your
> glue, but without adding code that manually iterates through
> the device tree. Make the platform_device a child of the of_device.
> This approach is the closest to what you have right now and would
> at least get the sysfs representation right, but not allow module
> autoloading and it still duplicates all the devices.
Like you, I dislike the resulting dev duplication. Also, having
the platform_device be a child of a superfluous of_device seems weird.
> 2. remove the dependencies on platform_device data structures from
> the current driver code, and add them to a separate file, so you
> can link the module either with the platform_driver or with the
> of_platform_driver, as I suggested in a previous mail.
> I think this would be the best solution.
This is a very OF-centric proposal. IMHO it's a mistake for drivers
to call of_get_property(). There should be a firmware-independent
way of passing parameters to drivers. I'm not a big fan of the
details of platform_device, but at least it's firmware independent.
I think it's a layering violation even when ppc-only drivers
query for parameters via of_get_property().
> 3. Have a small of_device_driver part that gets added to each
> of the device drivers, and that adds the platform_device internally.
> This would be like 1., but also allow autoloading.
Again, I'd like to keep arch-specific code out of drivers, as much
as possible.
Since you now recognize our need for platform_devices, I'd like to
understand your primary objection to our not creating of_devices.
Is it because it violates the assumption that of_devices be created
for all devices on the platform? Is that a hard requirement?
BTW Arnd, thank you for taking the time to comment on this code.
-Dale
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
2007-04-27 23:50 ` Dale Farnsworth
@ 2007-04-28 1:05 ` Arnd Bergmann
2007-04-28 2:40 ` Dale Farnsworth
2007-05-01 4:58 ` Paul Mackerras
0 siblings, 2 replies; 87+ messages in thread
From: Arnd Bergmann @ 2007-04-28 1:05 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras
On Saturday 28 April 2007, Dale Farnsworth wrote:
> On Thu, Apr 26, 2007 at 05:04:06PM +0200, Arnd Bergmann wrote:
> > With the of device tree, you automatically get an of_device for everything
> > that is connected to an internal (soc, plb, ssb, ...) bus on the chip
> > or on the board. According to the driver model, they should be driven
> > by an of_platform_driver.
>
> Well, since our platform hasn't called of_platform_bus_probe() with
> a device id for the mv64x60 device node, we don't create an of_device
> for each of its sub-devices. Instead, we scan separately and create
> platform_devices that the existing drivers require, and for the
> benefit of those who join this discussion late, which we must
> maintain for use by MIPS platforms.
We've had discussions about of_platform_bus_probe() on the mailing
lists and on IRC before. My idea of the long-term goal is that we
should not call it from the platform specific code, but instead
globally and add all the devices we find, with exceptions for
stuff that works differently, like PCI.
I think it would be bad to have to add another exception for
mv64x60 just because the drivers work different from the others.
> > 2. remove the dependencies on platform_device data structures from
> > the current driver code, and add them to a separate file, so you
> > can link the module either with the platform_driver or with the
> > of_platform_driver, as I suggested in a previous mail.
> > I think this would be the best solution.
>
> This is a very OF-centric proposal. IMHO it's a mistake for drivers
> to call of_get_property(). There should be a firmware-independent
> way of passing parameters to drivers. I'm not a big fan of the
> details of platform_device, but at least it's firmware independent.
> I think it's a layering violation even when ppc-only drivers
> query for parameters via of_get_property().
Calling of_* functions is the natural thing to do for an
of_platform_driver, just like a PCI driver calls pci_* functions.
Note that what I'm suggestiong here is that you have one file
that encapsulates all the calls to OF functions (of_iomap,
irq_of_parse_and_map, ...) and passes the raw information down
to the main low-level driver.
I think the main difference between your view and mine is that
you see the OF model as an _architecture_ property, while in my
view it is a _bus_type_ that devices are attached to.
It's like the OHCI driver, which has low-level driver for the
a common register interface, but comes with a number of bus
interfaces that it can attach to (PCI, PS3, OF, ...).
[ don't look at the OHCI implementation, the way they did
the code is not a good example, but it can be done properly. ]
> Since you now recognize our need for platform_devices, I'd like to
> understand your primary objection to our not creating of_devices.
> Is it because it violates the assumption that of_devices be created
> for all devices on the platform?
That, and the missing ability to do module autoloading.
> Is that a hard requirement?
Not yet, but I'd like to get there, as I mention above.
Arnd <><
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
2007-04-28 1:05 ` Arnd Bergmann
@ 2007-04-28 2:40 ` Dale Farnsworth
2007-05-01 4:58 ` Paul Mackerras
1 sibling, 0 replies; 87+ messages in thread
From: Dale Farnsworth @ 2007-04-28 2:40 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
On Sat, Apr 28, 2007 at 03:05:25AM +0200, Arnd Bergmann wrote:
> > This is a very OF-centric proposal. IMHO it's a mistake for drivers
> > to call of_get_property(). There should be a firmware-independent
> > way of passing parameters to drivers. I'm not a big fan of the
> > details of platform_device, but at least it's firmware independent.
> > I think it's a layering violation even when ppc-only drivers
> > query for parameters via of_get_property().
>
> Calling of_* functions is the natural thing to do for an
> of_platform_driver, just like a PCI driver calls pci_* functions.
It may be customary, and seem natural to you, but to me it includes
an unnaturally close coupling between the driver and the firmware.
Of course, I see many drivers have adopted it. I also like the
interface better than platform_device. However, I would like
it better if it were more decoupled from Open Firmware.
> Note that what I'm suggestiong here is that you have one file
> that encapsulates all the calls to OF functions (of_iomap,
> irq_of_parse_and_map, ...) and passes the raw information down
> to the main low-level driver.
I thought that's what I submitted. The main difference is that
what you suggest requires me to also allocate a superfluous
of_device for each platform device, or to rewrite the driver
interface to handle an of_device and to do its own calls to
retrieve data from the device tree.
In the short term, since the of_ routines don't support the
platform_device interface, there's going to be ugliness. We're
just discussing where to put that ugliness. Do we keep the of_
functions clean and push the ugliness into the drivers, or
do we keep the driver interfaces clean and create platform_devices
rather than of_devices from the device tree info? You want to
keep the of_ functions clean; I don't want to uglify the drivers
and am concerned about getting those ugly bits accepted into
the kernel.
> I think the main difference between your view and mine is that
> you see the OF model as an _architecture_ property, while in my
> view it is a _bus_type_ that devices are attached to.
Heh. I see it as a firmware-specific bus type. Of course, now
it's actually device-tree-specific, since we don't require OF
anymore, just some of its interfaces.
> It's like the OHCI driver, which has low-level driver for the
> a common register interface, but comes with a number of bus
> interfaces that it can attach to (PCI, PS3, OF, ...).
> [ don't look at the OHCI implementation, the way they did
> the code is not a good example, but it can be done properly. ]
>
> > Since you now recognize our need for platform_devices, I'd like to
> > understand your primary objection to our not creating of_devices.
> > Is it because it violates the assumption that of_devices be created
> > for all devices on the platform?
>
> That, and the missing ability to do module autoloading.
>
> > Is that a hard requirement?
>
> Not yet, but I'd like to get there, as I mention above.
Understood. I still think it's an OF-centric view. That wouldn't
be a problem if all architectures replaced platform_device with
of_device, a place that I think you'd also like to get to, which
I wouldn't mind at all. We're just not going to get there any
time soon.
-Dale
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
2007-04-28 1:05 ` Arnd Bergmann
2007-04-28 2:40 ` Dale Farnsworth
@ 2007-05-01 4:58 ` Paul Mackerras
1 sibling, 0 replies; 87+ messages in thread
From: Paul Mackerras @ 2007-05-01 4:58 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev
Arnd Bergmann writes:
> We've had discussions about of_platform_bus_probe() on the mailing
> lists and on IRC before. My idea of the long-term goal is that we
> should not call it from the platform specific code, but instead
> globally and add all the devices we find, with exceptions for
> stuff that works differently, like PCI.
I really don't think that is a good idea.
> I think it would be bad to have to add another exception for
> mv64x60 just because the drivers work different from the others.
I don't think it's fair to require extra work now for the sake of
something that will probably never happen. Creating a platform_device
seems reasonable to me given that the driver is shared between mips
and powerpc.
More generally, the fact that we require a device tree shouldn't be
taken to imply that every device driver should be an
of_platform_driver.
Paul.
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
2007-04-26 15:04 ` Arnd Bergmann
2007-04-27 23:50 ` Dale Farnsworth
@ 2007-05-01 4:45 ` Paul Mackerras
1 sibling, 0 replies; 87+ messages in thread
From: Paul Mackerras @ 2007-05-01 4:45 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev
Arnd Bergmann writes:
> What your glue code does is to find a backdoor into the device tree
> (through of_find_compatible_node) and create a second struct device
> for the same hardware, in an unrelated location in the linux device tree.
I disagree that of_find_compatible_node is a "backdoor".
He won't have an of_device already unless he has arranged for the
mv64x60 node to be scanned by of_platform_bus_probe. Which he hasn't
AFAICS.
> This is very confusing if you look at sysfs, e.g. trying to find out
> which driver is attached to a given of_device.
> It also makes you lose the ability to autoload the driver module,
> because autoloading is not supported for a platform_driver (there
> is no MODULE_DEVICE_TABLE()).
There's nothing preventing autoloading of modules for platform
devices, if desired.
Paul.
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
2007-04-26 2:02 ` Arnd Bergmann
2007-04-26 6:08 ` Dale Farnsworth
@ 2007-04-26 6:48 ` Mark A. Greer
1 sibling, 0 replies; 87+ messages in thread
From: Mark A. Greer @ 2007-04-26 6:48 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
On Thu, Apr 26, 2007 at 04:02:16AM +0200, Arnd Bergmann wrote:
> On Thursday 26 April 2007, Mark A. Greer wrote:
> > > location is the smaller part of the problem. Even if it was the right
> > > thing to scan the tree and then create platform_data instead of using
> > > the of_device, that code would still belong into the device driver.
> >
> > I don't think of_device is going to work very well on MIPS.
>
> Ok, I see your point there. But after looking at the i2c and net drivers,
> I believe that they can easily be split into an architecture dependent
> part that is either an of_platform_driver or a platform_driver, and
> a common part that does not know about either of these.
Back when I originally did the mpsc driver I did something similar.
The lkml folks told me pretty clearly to get rid of the arch-specific
code and use platform data. All-in-all, I think that's the best solution
(until all arch's move to a device tree model). So, I think we'll have
to agree to disagree on this.
There does seem to be a lot of duplicate code, though, so we should try
to clean that up (if possible).
Mark
^ permalink raw reply [flat|nested] 87+ messages in thread
* [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
2007-04-26 0:00 ` [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup Mark A. Greer
2007-04-26 0:21 ` Arnd Bergmann
@ 2007-05-02 21:44 ` Dale Farnsworth
2007-05-03 6:53 ` Arnd Bergmann
2007-05-04 21:08 ` [PATCH 9/13] powerpc: Create Marvell mv64x60 I2C platform_data Dale Farnsworth
1 sibling, 2 replies; 87+ messages in thread
From: Dale Farnsworth @ 2007-05-02 21:44 UTC (permalink / raw)
To: linuxppc-dev
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 [flat|nested] 87+ messages in thread
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
2007-05-02 21:44 ` Dale Farnsworth
@ 2007-05-03 6:53 ` Arnd Bergmann
2007-05-03 13:06 `
2007-05-04 21:08 ` [PATCH 9/13] powerpc: Create Marvell mv64x60 I2C platform_data Dale Farnsworth
1 sibling, 1 reply; 87+ messages in thread
From: Arnd Bergmann @ 2007-05-03 6:53 UTC (permalink / raw)
To: linuxppc-dev
On Wednesday 02 May 2007, Dale Farnsworth wrote:
> +=A0=A0=A0=A0=A0=A0=A0static int called_count;
> +=A0=A0=A0=A0=A0=A0=A0int instance =3D called_count++;
I would think it's simpler to count the instances in the outer loop
when looking for the devices than having a static counter here.
> + pdev =3D platform_device_register_simple(MV64XXX_I2C_CTLR_NAME,
> + instance, r, 2);
> + if (IS_ERR(pdev))
> + return PTR_ERR(pdev);
> +
> + err =3D platform_device_add_data(pdev, &pdata, sizeof(pdata));
> + if (err) {
> + platform_device_unregister(pdev);
> + return err;
Doing the initialization in this order means that you have to add the
devices before the driver is loaded. I haven't checked if you do
the same thing in the oder places as well, but I think it would be
better to do it open coded like
pdev =3D platform_device_alloc(MV64XXX_I2C_CTLR_NAME, instance);
if (!pdev)
return -ENOMEM;
err =3D platform_device_add_resources(pdev, r, 2);
if (err)
goto error;
err =3D platform_device_add_data(pdev, &pdata, sizeof(pdata));
if (err)
goto error;
err =3D platform_device_add(pdev);
if (err)
goto error;
return pdev;
error:
platform_device_put(pdev);
return ERR_PTR(err);
Arnd <><
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup
2007-05-03 6:53 ` Arnd Bergmann
@ 2007-05-03 13:06 `
0 siblings, 0 replies; 87+ messages in thread
From: @ 2007-05-03 13:06 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
On Thu, May 03, 2007 at 08:53:17AM +0200, Arnd Bergmann wrote:
> On Wednesday 02 May 2007, Dale Farnsworth wrote:
> > +???????static int called_count;
> > +???????int instance = called_count++;
>
> I would think it's simpler to count the instances in the outer loop
> when looking for the devices than having a static counter here.
Maybe. I did it with passing an outer counter in a previous
incarnation. I'll look at it again.
> > + 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;
>
> Doing the initialization in this order means that you have to add the
> devices before the driver is loaded. I haven't checked if you do
> the same thing in the oder places as well, but I think it would be
> better to do it open coded like
>
> pdev = platform_device_alloc(MV64XXX_I2C_CTLR_NAME, instance);
> if (!pdev)
> return -ENOMEM;
> err = platform_device_add_resources(pdev, r, 2);
> if (err)
> goto error;
> err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
> if (err)
> goto error;
> err = platform_device_add(pdev);
> if (err)
> goto error;
> return pdev;
> error:
> platform_device_put(pdev);
> return ERR_PTR(err);
Makes sense to me. I'll change it (in all three places).
Thanks.
-Dale
^ permalink raw reply [flat|nested] 87+ messages in thread
* [PATCH 9/13] powerpc: Create Marvell mv64x60 I2C platform_data
2007-05-02 21:44 ` Dale Farnsworth
2007-05-03 6:53 ` Arnd Bergmann
@ 2007-05-04 21:08 ` Dale Farnsworth
2007-05-05 12:29 ` Arnd Bergmann
1 sibling, 1 reply; 87+ messages in thread
From: Dale Farnsworth @ 2007-05-04 21:08 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Stephen Rothwell, Paul Mackerras, Arnd Bergmann
This patch creates platform_device entries for the Marvell mv64x60
I2C ports, based on information contained in device tree.
Signed-off-by: Dale Farnsworth <dale@farnsworth.org>
---
Latest rev. I think I've addressed all of Stephen's and Arnd's issues.
arch/powerpc/sysdev/mv64x60_dev.c | 74 +++++++++++++++++++++++++++-
1 file changed, 72 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
@@ -323,14 +323,79 @@ error:
return err;
}
+/*
+ * Create mv64x60_i2c platform devices
+ */
+static int __init mv64x60_i2c_device_setup(struct device_node *np, int id)
+{
+ struct resource r[2];
+ struct platform_device *pdev;
+ struct mv64xxx_i2c_pdata pdata;
+ const unsigned int *prop;
+ int err;
+
+ 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[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_alloc(MV64XXX_I2C_CTLR_NAME, id);
+ if (!pdev)
+ return -ENOMEM;
+
+ err = platform_device_add_resources(pdev, r, 2);
+ if (err)
+ goto error;
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto error;
+
+ err = platform_device_add(pdev);
+ if (err)
+ goto error;
+
+ return 0;
+
+error:
+ platform_device_put(pdev);
+ return err;
+}
+
static int __init mv64x60_device_setup(void)
{
struct device_node *np = NULL;
int id;
int err;
- for (id = 0;
- (np = of_find_compatible_node(np, "serial", "mpsc")); id++)
+ for (id = 0; (np = of_find_compatible_node(np, "serial", "mpsc")); id++)
if ((err = mv64x60_mpsc_device_setup(np, id)))
goto error;
@@ -339,6 +404,11 @@ static int __init mv64x60_device_setup(v
if ((err = mv64x60_eth_device_setup(np, id)))
goto error;
+ for (id = 0;
+ (np = of_find_compatible_node(np, "i2c", "mv64x60-i2c")); id++)
+ if ((err = mv64x60_i2c_device_setup(np, id)))
+ goto error;
+
return 0;
error:
^ permalink raw reply [flat|nested] 87+ messages in thread
* [PATCH 10/13] powerpc: Add arch/powerpc mv64x60 PCI setup
2007-04-25 23:46 [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800 Mark A. Greer
` (8 preceding siblings ...)
2007-04-26 0:00 ` [PATCH 9/13] powerpc: Add arch/powerpc mv64x60 I2C platform data setup Mark A. Greer
@ 2007-04-26 0:01 ` Mark A. Greer
2007-04-26 0:25 ` Arnd Bergmann
2007-05-02 21:46 ` Dale Farnsworth
2007-04-26 0:01 ` [PATCH 11/13] powerpc: Add DTS file for the Motorola PrPMC2800 platform Mark A. Greer
` (3 subsequent siblings)
13 siblings, 2 replies; 87+ messages in thread
From: Mark A. Greer @ 2007-04-26 0:01 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
From: Dale Farnsworth <dale@farnsworth.org>
Signed-off-by: Dale Farnsworth <dale@farnsworth.org>
---
mv64x60.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
mv64x60.h | 2
2 files changed, 178 insertions(+)
Index: linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
===================================================================
--- linux-2.6-powerpc-df.orig/arch/powerpc/sysdev/mv64x60.c
+++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.c
@@ -18,12 +18,14 @@
#include <linux/string.h>
#include <linux/mv643xx.h>
#include <linux/platform_device.h>
+#include <linux/pci.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/irq.h>
#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
#include "mv64x60.h"
@@ -721,3 +723,177 @@ ret_node_put:
}
arch_initcall(mv64x60_i2c_platform_device_init);
+
+#ifdef CONFIG_PCI
+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);
+}
+#endif /* CONFIG_PCI */
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
@@ -6,4 +6,6 @@
extern void __init mv64x60_init_irq(void);
extern unsigned int mv64x60_get_irq(void);
+extern void __init mv64x60_pci_init(void);
+
#endif /* __MV64X60_H__ */
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 10/13] powerpc: Add arch/powerpc mv64x60 PCI setup
2007-04-26 0:01 ` [PATCH 10/13] powerpc: Add arch/powerpc mv64x60 PCI setup Mark A. Greer
@ 2007-04-26 0:25 ` Arnd Bergmann
2007-04-26 6:33 ` Dale Farnsworth
2007-05-02 21:46 ` Dale Farnsworth
1 sibling, 1 reply; 87+ messages in thread
From: Arnd Bergmann @ 2007-04-26 0:25 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Paul Mackerras
On Thursday 26 April 2007, Mark A. Greer wrote:
> +void __init mv64x60_pci_init(void)
> +{
> +=A0=A0=A0=A0=A0=A0=A0struct device_node *np =3D NULL;
> +
> +=A0=A0=A0=A0=A0=A0=A0ppc_md.pci_exclude_device =3D mv64x60_exclude_devic=
e;
> +
> +=A0=A0=A0=A0=A0=A0=A0while ((np =3D of_find_compatible_node(np, "pci", "=
mv64x60-pci")))
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0mv64x60_add_bridge(np);
> +}
This is a similar mistake to the previous two, but somewhat different:
You actually duplicate code that is already present in of_platform.c.
AFAICS, all you should need to do is implement the ppc_md.pci_setup_phb()
function instead of your own handmade device tree scanning.
Arnd <><
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 10/13] powerpc: Add arch/powerpc mv64x60 PCI setup
2007-04-26 0:25 ` Arnd Bergmann
@ 2007-04-26 6:33 ` Dale Farnsworth
2007-04-26 11:39 ` Arnd Bergmann
0 siblings, 1 reply; 87+ messages in thread
From: Dale Farnsworth @ 2007-04-26 6:33 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev, Paul Mackerras
On Thu, Apr 26, 2007 at 12:25:27AM +0000, Arnd Bergmann wrote:
> On Thursday 26 April 2007, Mark A. Greer wrote:
> > +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);
> > +}
>
> This is a similar mistake to the previous two, but somewhat different:
>
> You actually duplicate code that is already present in of_platform.c.
> AFAICS, all you should need to do is implement the ppc_md.pci_setup_phb()
> function instead of your own handmade device tree scanning.
I find this comment in of_platform.c troubling:
> /* The probing of PCI controllers from of_platform is currently
> * 64 bits only, mostly due to gratuitous differences between
> * the 32 and 64 bits PCI code on PowerPC and the 32 bits one
> * lacking some bits needed here.
> */
Is this comment incorrect?
I agree that this is more code duplication than I like, and we could
benefit from some refactoring. However, I find 15 other places in
arch/powerpc that largely duplicate this pci initialization code.
That doesn't make a 16th right, but at least I'm in good company. :)
-Dale
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 10/13] powerpc: Add arch/powerpc mv64x60 PCI setup
2007-04-26 6:33 ` Dale Farnsworth
@ 2007-04-26 11:39 ` Arnd Bergmann
2007-04-26 14:42 ` Dale Farnsworth
0 siblings, 1 reply; 87+ messages in thread
From: Arnd Bergmann @ 2007-04-26 11:39 UTC (permalink / raw)
To: Dale Farnsworth; +Cc: linuxppc-dev, Paul Mackerras
On Thursday 26 April 2007, Dale Farnsworth wrote:
> > /* The probing of PCI controllers from of_platform is currently
> > =A0* 64 bits only, mostly due to gratuitous differences between
> > =A0* the 32 and 64 bits PCI code on PowerPC and the 32 bits one
> > =A0* lacking some bits needed here.
> > =A0*/
>=20
> Is this comment incorrect?
>=20
> I agree that this is more code duplication than I like, and we could
> benefit from some refactoring. =A0However, I find 15 other places in
> arch/powerpc that largely duplicate this pci initialization code.
> That doesn't make a 16th right, but at least I'm in good company.=20
Yes, you're right. I was assuming that the code had been ported to
32 bit already, which was incorrect.
While I would very much like you (or someone else) to make it work,
it should not be a prerequisite to get your code merged in 2.6.22.
The one remaining comment I have about this one is that IMHO it
should be a separate file, mv64x60-pci.c instead of being
in the same file as the interrupt controller and other code.
Arnd <><
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 10/13] powerpc: Add arch/powerpc mv64x60 PCI setup
2007-04-26 11:39 ` Arnd Bergmann
@ 2007-04-26 14:42 ` Dale Farnsworth
0 siblings, 0 replies; 87+ messages in thread
From: Dale Farnsworth @ 2007-04-26 14:42 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: Paul Mackerras, linuxppc-dev
On Thu, Apr 26, 2007 at 01:39:18PM +0200, Arnd Bergmann wrote:
> On Thursday 26 April 2007, Dale Farnsworth wrote:
> > > /* The probing of PCI controllers from of_platform is currently
> > > ?* 64 bits only, mostly due to gratuitous differences between
> > > ?* the 32 and 64 bits PCI code on PowerPC and the 32 bits one
> > > ?* lacking some bits needed here.
> > > ?*/
> >
> > Is this comment incorrect?
> >
> > I agree that this is more code duplication than I like, and we could
> > benefit from some refactoring. ?However, I find 15 other places in
> > arch/powerpc that largely duplicate this pci initialization code.
> > That doesn't make a 16th right, but at least I'm in good company.
>
> Yes, you're right. I was assuming that the code had been ported to
> 32 bit already, which was incorrect.
>
> While I would very much like you (or someone else) to make it work,
> it should not be a prerequisite to get your code merged in 2.6.22.
>
> The one remaining comment I have about this one is that IMHO it
> should be a separate file, mv64x60-pci.c instead of being
> in the same file as the interrupt controller and other code.
Ah, the debate continues. I remember 4 or 5 years ago there was
campaign to consolidate the xxxx-pci.c files into the core support
files. I have no strong preference. More opinions are welcome.
Thanks,
-Dale
^ permalink raw reply [flat|nested] 87+ messages in thread
* [PATCH 10/13] powerpc: Add arch/powerpc mv64x60 PCI setup
2007-04-26 0:01 ` [PATCH 10/13] powerpc: Add arch/powerpc mv64x60 PCI setup Mark A. Greer
2007-04-26 0:25 ` Arnd Bergmann
@ 2007-05-02 21:46 ` Dale Farnsworth
2007-05-03 2:13 ` Stephen Rothwell
` (2 more replies)
1 sibling, 3 replies; 87+ messages in thread
From: Dale Farnsworth @ 2007-05-02 21:46 UTC (permalink / raw)
To: linuxppc-dev
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 [flat|nested] 87+ messages in thread
* Re: [PATCH 10/13] powerpc: Add arch/powerpc mv64x60 PCI setup
2007-05-02 21:46 ` Dale Farnsworth
@ 2007-05-03 2:13 ` Stephen Rothwell
2007-05-03 2:57 ` Dale Farnsworth
2007-05-03 7:17 ` Arnd Bergmann
2007-05-04 21:10 ` [PATCH 10/13] powerpc: Add Marvell mv64x60 PCI bridge support Dale Farnsworth
2 siblings, 1 reply; 87+ messages in thread
From: Stephen Rothwell @ 2007-05-03 2:13 UTC (permalink / raw)
To: Dale Farnsworth; +Cc: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 538 bytes --]
On Wed, 2 May 2007 14:46:09 -0700 "Dale Farnsworth" <dale@farnsworth.org> wrote:
>
> +DECLARE_MUTEX(mv64x60_hs_lock);
Does this need to be global (it is not declared in a header file)?
> + 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);
This error leaks a reference count on np.
--
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 [flat|nested] 87+ messages in thread
* Re: [PATCH 10/13] powerpc: Add arch/powerpc mv64x60 PCI setup
2007-05-03 2:13 ` Stephen Rothwell
@ 2007-05-03 2:57 ` Dale Farnsworth
0 siblings, 0 replies; 87+ messages in thread
From: Dale Farnsworth @ 2007-05-03 2:57 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: linuxppc-dev
On Thu, May 03, 2007 at 12:13:58PM +1000, Stephen Rothwell wrote:
> On Wed, 2 May 2007 14:46:09 -0700 "Dale Farnsworth" <dale@farnsworth.org> wrote:
> >
> > +DECLARE_MUTEX(mv64x60_hs_lock);
>
> Does this need to be global (it is not declared in a header file)?
Nope. Fixed.
> > + 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);
>
> This error leaks a reference count on np.
Good find. Fixed.
Stephen, thanks for taking the time to review and comment.
I'll wait to see what other comments I get before reposting.
-Dale
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 10/13] powerpc: Add arch/powerpc mv64x60 PCI setup
2007-05-02 21:46 ` Dale Farnsworth
2007-05-03 2:13 ` Stephen Rothwell
@ 2007-05-03 7:17 ` Arnd Bergmann
2007-05-03 13:45 ` Dale Farnsworth
2007-05-04 21:10 ` [PATCH 10/13] powerpc: Add Marvell mv64x60 PCI bridge support Dale Farnsworth
2 siblings, 1 reply; 87+ messages in thread
From: Arnd Bergmann @ 2007-05-03 7:17 UTC (permalink / raw)
To: linuxppc-dev
On Wednesday 02 May 2007, Dale Farnsworth wrote:
> 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
> +
I'd write this as
mv64x60-$(CONFIG_INDIRECT_PCI) += mv64x60_pci.o
obj-$(CONFIG_MV64X60) += mv64x60-y
though that doesn't make much difference any more
> +#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);
Please avoid using struct semephores in new code, we now have struct mutex
for this, which gets defined as
static DEFINE_MUTEX(mv64x60_hs_mutex);
> +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);
Why do you use early_read_config_dword, not pci_read_config_dword()?
> + mv64x60_pci_exclude_bridge = save_exclude;
> + up(&mv64x60_hs_lock);
> +
> + return sprintf(buf, "0x%08x\n", v);
> +}
<snip>
> +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;
> +}
The locking here looks wrong. If you call mv64x60_exclude_device() from one thread
thread while another one is calling mv64x60_hs_reg_read(), the bridge will
not be excluded.
Arnd <><
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 10/13] powerpc: Add arch/powerpc mv64x60 PCI setup
2007-05-03 7:17 ` Arnd Bergmann
@ 2007-05-03 13:45 ` Dale Farnsworth
0 siblings, 0 replies; 87+ messages in thread
From: Dale Farnsworth @ 2007-05-03 13:45 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: linuxppc-dev
On Thu, May 03, 2007 at 09:17:46AM +0200, Arnd Bergmann wrote:
> On Wednesday 02 May 2007, Dale Farnsworth wrote:
>
> > 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
> > +
>
> I'd write this as
>
> mv64x60-$(CONFIG_INDIRECT_PCI) += mv64x60_pci.o
> obj-$(CONFIG_MV64X60) += mv64x60-y
>
> though that doesn't make much difference any more
>
> > +#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);
>
> Please avoid using struct semephores in new code, we now have struct mutex
> for this, which gets defined as
>
> static DEFINE_MUTEX(mv64x60_hs_mutex);
This is existing code being moved over from arch/ppc. I'll make the change.
> > +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);
>
> Why do you use early_read_config_dword, not pci_read_config_dword()?
As above, this is existing code being moved over from arch/ppc.
I'll make the change.
> > + mv64x60_pci_exclude_bridge = save_exclude;
> > + up(&mv64x60_hs_lock);
> > +
> > + return sprintf(buf, "0x%08x\n", v);
> > +}
>
> <snip>
>
> > +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;
> > +}
>
> The locking here looks wrong. If you call mv64x60_exclude_device() from one thread
> thread while another one is calling mv64x60_hs_reg_read(), the bridge will
> not be excluded.
Good catch. Again, it's existing code, but clearly there's a race here.
I'm guessing that the mutex above was just to prevent nesting of setting
mv64x60_pci_exclude_bridge. A fix for the race doesn't look easy.
I'll look into it.
Thanks,
-Dale
^ permalink raw reply [flat|nested] 87+ messages in thread
* [PATCH 10/13] powerpc: Add Marvell mv64x60 PCI bridge support
2007-05-02 21:46 ` Dale Farnsworth
2007-05-03 2:13 ` Stephen Rothwell
2007-05-03 7:17 ` Arnd Bergmann
@ 2007-05-04 21:10 ` Dale Farnsworth
2007-05-05 12:30 ` Arnd Bergmann
2 siblings, 1 reply; 87+ messages in thread
From: Dale Farnsworth @ 2007-05-04 21:10 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Stephen Rothwell, Paul Mackerras, Arnd Bergmann
This patch adds PCI bridge support for the Marvell mv64x60 chip.
Signed-off-by: Dale Farnsworth <dale@farnsworth.org>
---
I think I have addressed all of the issues raised by Arnd and Stephen.
arch/powerpc/platforms/embedded6xx/Kconfig | 1
arch/powerpc/sysdev/Makefile | 3
arch/powerpc/sysdev/mv64x60.h | 2
arch/powerpc/sysdev/mv64x60_pci.c | 172 +++++++++++++++++++
4 files changed, 177 insertions(+), 1 deletion(-)
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,8 @@ 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 mv64x60_dev.o
+mv64x60-$(CONFIG_PCI) += mv64x60_pci.o
+obj-$(CONFIG_MV64X60) += $(mv64x60-y) 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/sysdev/mv64x60.h
===================================================================
--- linux-2.6-powerpc-df.orig/arch/powerpc/sysdev/mv64x60.h
+++ linux-2.6-powerpc-df/arch/powerpc/sysdev/mv64x60.h
@@ -6,4 +6,6 @@
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,172 @@
+/*
+ * 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>
+
+#define PCI_HEADER_TYPE_INVALID 0x7f /* Invalid PCI header type */
+
+#ifdef CONFIG_SYSFS
+/* 32-bit hex or dec stringified number + '\n' */
+#define MV64X60_VAL_LEN_MAX 11
+#define MV64X60_PCICFG_CPCI_HOTSWAP 0x68
+
+static ssize_t mv64x60_hs_reg_read(struct kobject *kobj, char *buf, loff_t off,
+ size_t count)
+{
+ struct pci_dev *phb;
+ u32 v;
+
+ if (off > 0)
+ return 0;
+ if (count < MV64X60_VAL_LEN_MAX)
+ return -EINVAL;
+
+ phb = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
+ if (!phb)
+ return -ENODEV;
+ pci_read_config_dword(phb, MV64X60_PCICFG_CPCI_HOTSWAP, &v);
+ pci_dev_put(phb);
+
+ 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)
+{
+ struct pci_dev *phb;
+ u32 v;
+
+ if (off > 0)
+ return 0;
+ if (count <= 0)
+ return -EINVAL;
+
+ if (sscanf(buf, "%i", &v) != 1)
+ return -EINVAL;
+
+ phb = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
+ if (!phb)
+ return -ENODEV;
+ pci_write_config_dword(phb, MV64X60_PCICFG_CPCI_HOTSWAP, v);
+ pci_dev_put(phb);
+
+ 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;
+
+ prop = of_get_property(np, "hs_reg_valid", NULL);
+ of_node_put(np);
+
+ pdev = platform_device_register_simple("mv64x60", 0, NULL, 0);
+ if (IS_ERR(pdev))
+ return PTR_ERR(pdev);
+
+ return sysfs_create_bin_file(&pdev->dev.kobj, &mv64x60_hs_reg_attr);
+}
+
+subsys_initcall(mv64x60_sysfs_init);
+
+#endif /* CONFIG_SYSFS */
+
+static void __init mv64x60_pci_fixup_early(struct pci_dev *dev)
+{
+ /*
+ * Set the host bridge hdr_type to an invalid value so that
+ * pci_setup_device() will ignore the host bridge.
+ */
+ dev->hdr_type = PCI_HEADER_TYPE_INVALID;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64360,
+ mv64x60_pci_fixup_early);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64460,
+ mv64x60_pci_fixup_early);
+
+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;
+
+ setup_indirect_pci(hose, rsrc.start, rsrc.start + 4);
+ hose->bus_offset = 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 */
+ primary = (hose->first_busno == 0);
+ pci_process_bridge_OF_ranges(hose, dev, primary);
+
+ return 0;
+}
+
+void __init mv64x60_pci_init(void)
+{
+ struct device_node *np = NULL;
+
+ 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 [flat|nested] 87+ messages in thread
* [PATCH 11/13] powerpc: Add DTS file for the Motorola PrPMC2800 platform
2007-04-25 23:46 [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800 Mark A. Greer
` (9 preceding siblings ...)
2007-04-26 0:01 ` [PATCH 10/13] powerpc: Add arch/powerpc mv64x60 PCI setup Mark A. Greer
@ 2007-04-26 0:01 ` Mark A. Greer
2007-04-26 16:42 ` Scott Wood
2007-04-27 20:41 ` Mark A. Greer
2007-04-26 0:02 ` [PATCH 12/13] powerpc: Add bootwrapper support for " Mark A. Greer
` (2 subsequent siblings)
13 siblings, 2 replies; 87+ messages in thread
From: Mark A. Greer @ 2007-04-26 0:01 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
---
prpmc2800.dts | 322 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 322 insertions(+)
Index: powerpc/arch/powerpc/boot/dts/prpmc2800.dts
===================================================================
--- /dev/null
+++ powerpc/arch/powerpc/boot/dts/prpmc2800.dts
@@ -0,0 +1,322 @@
+/* Device Tree Source for Motorola PrPMC2800
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 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.
+ *
+ * To build:
+ * dtc -I dts -O asm -o prpmc2800.S -V 16 -b 0 prpmc2800.dts
+ * dtc -I dts -O dtb -o prpmc2800.dtb -V 16 -b 0 prpmc2800.dts
+ */
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "PrPMC280/PrPMC2800"; /* Updated by bootwrapper */
+ compatible = "PrPMC2800";
+ coherency-off;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,7447 {
+ device_type = "cpu";
+ reg = <0>;
+ clock-frequency = <0>; /* Set by bootwrapper */
+ bus-frequency = <7f28155>; /* 133.333333 MHz */
+ timebase-frequency = <1fca055>; /* 33.333333 MHz */
+ /* Following required by dtc but not used */
+ i-cache-line-size = <0>;
+ d-cache-line-size = <0>;
+ i-cache-size = <0>;
+ d-cache-size = <0>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <00000000 00000000>; /* Set by bootwrapper */
+ };
+
+ mv64x60@f1000000 { /* Marvell Discovery */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <1>;
+ device_type = "mv64360";
+ compatible = "mv64x60";
+ clock-frequency = <7f28155>; /* 133.333333 Mhz */
+ reg = <f1000000 00010000>;
+ virtual-reg = <f1000000>;
+ ranges = <88000000 88000000 01000000 /* PCI 0 I/O Space */
+ 80000000 80000000 08000000 /* PCI 0 MEM Space */
+ a0000000 a0000000 04000000 /* User FLASH */
+ 00000000 f1000000 00010000 /* Bridge's regs */
+ f2000000 f2000000 00040000>; /* Integrated SRAM */
+
+ flash@a0000000 {
+ device_type = "rom";
+ compatible = "direct-mapped";
+ reg = <a0000000 0>; /* Size set by bootwrapper */
+ probe-type = "CFI";
+ bank-width = <4>;
+ partitions = <00000000 00100000 /* RO */
+ 00100000 00040001 /* RW */
+ 00140000 00400000 /* RO */
+ 00540000 039c0000 /* RO */
+ 03f00000 00100000>; /* RO */
+ partition-names = "FW Image A\0FW Config Data\0Kernel Image\0Filesystem\0FW Image B";
+ };
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "mdio";
+ compatible = "mv64x60-mdio";
+ ethernet-phy@1 {
+ device_type = "ethernet-phy";
+ compatible = "bcm5421";
+ interrupts = <4c>; /* GPP 12 */
+ interrupt-parent = <&/mv64x60/pic>;
+ reg = <1>;
+ };
+ ethernet-phy@3 {
+ device_type = "ethernet-phy";
+ compatible = "bcm5421";
+ interrupts = <4c>; /* GPP 12 */
+ interrupt-parent = <&/mv64x60/pic>;
+ reg = <3>;
+ };
+ };
+
+ ethernet@2000 { /* mac-address set by bootwrapper */
+ reg = <2000 2000>;
+ eth0 {
+ device_type = "network";
+ compatible = "mv64x60-eth";
+ block-index = <0>;
+ interrupts = <20>;
+ interrupt-parent = <&/mv64x60/pic>;
+ phy = <&/mv64x60/mdio/ethernet-phy@1>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ eth1 {
+ device_type = "network";
+ compatible = "mv64x60-eth";
+ block-index = <1>;
+ interrupts = <21>;
+ interrupt-parent = <&/mv64x60/pic>;
+ phy = <&/mv64x60/mdio/ethernet-phy@3>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ };
+
+ sdma@4000 {
+ device_type = "dma";
+ compatible = "mv64x60-sdma";
+ reg = <4000 c18>;
+ virtual-reg = <f1004000>;
+ interrupt-base = <0>;
+ interrupts = <24>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ sdma@6000 {
+ device_type = "dma";
+ compatible = "mv64x60-sdma";
+ reg = <6000 c18>;
+ virtual-reg = <f1006000>;
+ interrupt-base = <0>;
+ interrupts = <26>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ brg@b200 {
+ device_type = "brg";
+ compatible = "mv64x60-brg";
+ reg = <b200 8>;
+ clock-src = <8>;
+ clock-frequency = <7ed6b40>;
+ current-speed = <2580>;
+ bcr = <0>;
+ };
+
+ brg@b208 {
+ device_type = "brg";
+ compatible = "mv64x60-brg";
+ reg = <b208 8>;
+ clock-src = <8>;
+ clock-frequency = <7ed6b40>;
+ current-speed = <2580>;
+ bcr = <0>;
+ };
+
+ cunit@f200 {
+ device_type = "mv64x60-cunit";
+ reg = <f200 200>;
+ };
+
+ mpscrouting@b400 {
+ device_type = "mpscrouting";
+ reg = <b400 c>;
+ };
+
+ mpscintr@b800 {
+ device_type = "mpscintr";
+ reg = <b800 100>;
+ virtual-reg = <f100b800>;
+ };
+
+ mpsc@8000 {
+ device_type = "serial";
+ compatible = "mpsc";
+ reg = <8000 38>;
+ virtual-reg = <f1008000>;
+ sdma = <&/mv64x60/sdma@4000>;
+ brg = <&/mv64x60/brg@b200>;
+ cunit = <&/mv64x60/cunit@f200>;
+ mpscrouting = <&/mv64x60/mpscrouting@b400>;
+ mpscintr = <&/mv64x60/mpscintr@b800>;
+ block-index = <0>;
+ max_idle = <28>;
+ chr_1 = <0>;
+ chr_2 = <0>;
+ chr_10 = <3>;
+ mpcr = <0>;
+ interrupts = <28>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ mpsc@9000 {
+ device_type = "serial";
+ compatible = "mpsc";
+ reg = <9000 38>;
+ virtual-reg = <f1009000>;
+ sdma = <&/mv64x60/sdma@6000>;
+ brg = <&/mv64x60/brg@b208>;
+ cunit = <&/mv64x60/cunit@f200>;
+ mpscrouting = <&/mv64x60/mpscrouting@b400>;
+ mpscintr = <&/mv64x60/mpscintr@b800>;
+ block-index = <1>;
+ max_idle = <28>;
+ chr_1 = <0>;
+ chr_2 = <0>;
+ chr_10 = <3>;
+ mpcr = <0>;
+ interrupts = <2a>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ i2c@c000 {
+ device_type = "i2c";
+ compatible = "mv64x60-i2c";
+ reg = <c000 20>;
+ virtual-reg = <f100c000>;
+ freq_m = <8>;
+ freq_n = <3>;
+ timeout = <3e8>; /* 1000 = 1 second */
+ retries = <1>;
+ interrupts = <25>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ pic {
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ device_type = "mv64x60-pic";
+ compatible = "mv64x60-pic";
+ reg = <0000 88>;
+ interrupt-controller;
+ };
+
+ mpp@f000 {
+ device_type = "mv64x60-mpp";
+ compatible = "mv64x60-mpp";
+ reg = <f000 10>;
+ };
+
+ gpp@f100 {
+ device_type = "mv64x60-gpp";
+ compatible = "mv64x60-gpp";
+ reg = <f100 20>;
+ };
+
+ pci@80000000 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ compatible = "mv64x60-pci";
+ reg = <0cf8 8>;
+ ranges = <01000000 0 0 88000000 0 01000000
+ 02000000 0 80000000 80000000 0 08000000>;
+ bus-range = <0 ff>;
+ clock-frequency = <3EF1480>;
+ interrupt-pci-iack = <0c34>;
+ interrupt-parent = <&/mv64x60/pic>;
+ interrupt-map-mask = <f800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0a */
+ 5000 0 0 1 &/mv64x60/pic 50
+ 5000 0 0 2 &/mv64x60/pic 51
+ 5000 0 0 3 &/mv64x60/pic 5b
+ 5000 0 0 4 &/mv64x60/pic 5d
+
+ /* IDSEL 0x0b */
+ 5800 0 0 1 &/mv64x60/pic 5b
+ 5800 0 0 2 &/mv64x60/pic 5d
+ 5800 0 0 3 &/mv64x60/pic 50
+ 5800 0 0 4 &/mv64x60/pic 51
+
+ /* IDSEL 0x0c */
+ 6000 0 0 1 &/mv64x60/pic 5b
+ 6000 0 0 2 &/mv64x60/pic 5d
+ 6000 0 0 3 &/mv64x60/pic 50
+ 6000 0 0 4 &/mv64x60/pic 51
+
+ /* IDSEL 0x0d */
+ 6800 0 0 1 &/mv64x60/pic 5d
+ 6800 0 0 2 &/mv64x60/pic 50
+ 6800 0 0 3 &/mv64x60/pic 51
+ 6800 0 0 4 &/mv64x60/pic 5b
+ >;
+ };
+
+ cpu-error@0070 {
+ device_type = "mv64x60-cpu-error";
+ reg = <0070 10 0128 28>;
+ interrupts = <03>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ sram-error@0380 {
+ device_type = "mv64x60-sram-error";
+ reg = <0380 80>;
+ interrupts = <0d>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ pci-error@1dc0 {
+ device_type = "mv64x60-pci-error";
+ reg = <1d40 40 0c28 4>;
+ interrupts = <0c>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ memctrl@1400 {
+ device_type = "mv64x60-memctrl";
+ reg = <1400 60>;
+ interrupts = <11>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+ };
+
+ chosen {
+ linux,platform = <1>;
+ bootargs = "ip=on console=ttyMM0";
+ linux,stdout-path = "/mv64x60/mpsc@8000";
+ };
+};
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 11/13] powerpc: Add DTS file for the Motorola PrPMC2800 platform
2007-04-26 0:01 ` [PATCH 11/13] powerpc: Add DTS file for the Motorola PrPMC2800 platform Mark A. Greer
@ 2007-04-26 16:42 ` Scott Wood
2007-04-26 23:34 ` Mark A. Greer
2007-04-26 23:37 ` David Gibson
2007-04-27 20:41 ` Mark A. Greer
1 sibling, 2 replies; 87+ messages in thread
From: Scott Wood @ 2007-04-26 16:42 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev, Paul Mackerras
On Wed, Apr 25, 2007 at 05:01:51PM -0700, Mark A. Greer wrote:
> + chosen {
> + linux,platform = <1>;
> + bootargs = "ip=on console=ttyMM0";
> + linux,stdout-path = "/mv64x60/mpsc@8000";
> + };
Isn't linux,platform obsolete?
-Scott
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 11/13] powerpc: Add DTS file for the Motorola PrPMC2800 platform
2007-04-26 16:42 ` Scott Wood
@ 2007-04-26 23:34 ` Mark A. Greer
2007-04-26 23:37 ` David Gibson
1 sibling, 0 replies; 87+ messages in thread
From: Mark A. Greer @ 2007-04-26 23:34 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev, Paul Mackerras
On Thu, Apr 26, 2007 at 11:42:26AM -0500, Scott Wood wrote:
> On Wed, Apr 25, 2007 at 05:01:51PM -0700, Mark A. Greer wrote:
> > + chosen {
> > + linux,platform = <1>;
> > + bootargs = "ip=on console=ttyMM0";
> > + linux,stdout-path = "/mv64x60/mpsc@8000";
> > + };
>
> Isn't linux,platform obsolete?
Hmm, yeah, think so. Good catch. Will remove.
Mark
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 11/13] powerpc: Add DTS file for the Motorola PrPMC2800 platform
2007-04-26 16:42 ` Scott Wood
2007-04-26 23:34 ` Mark A. Greer
@ 2007-04-26 23:37 ` David Gibson
1 sibling, 0 replies; 87+ messages in thread
From: David Gibson @ 2007-04-26 23:37 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev, Paul Mackerras
On Thu, Apr 26, 2007 at 11:42:26AM -0500, Scott Wood wrote:
> On Wed, Apr 25, 2007 at 05:01:51PM -0700, Mark A. Greer wrote:
> > + chosen {
> > + linux,platform = <1>;
> > + bootargs = "ip=on console=ttyMM0";
> > + linux,stdout-path = "/mv64x60/mpsc@8000";
> > + };
>
> Isn't linux,platform obsolete?
Well and truly. Please get rid of it.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 11/13] powerpc: Add DTS file for the Motorola PrPMC2800 platform
2007-04-26 0:01 ` [PATCH 11/13] powerpc: Add DTS file for the Motorola PrPMC2800 platform Mark A. Greer
2007-04-26 16:42 ` Scott Wood
@ 2007-04-27 20:41 ` Mark A. Greer
2007-04-30 16:45 ` Jon Loeliger
1 sibling, 1 reply; 87+ messages in thread
From: Mark A. Greer @ 2007-04-27 20:41 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
[PATCH 11/13] powerpc: Add DTS file for the Motorola PrPMC2800 platform
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
---
prpmc2800.dts | 321 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 321 insertions(+)
Index: powerpc/arch/powerpc/boot/dts/prpmc2800.dts
===================================================================
--- /dev/null
+++ powerpc/arch/powerpc/boot/dts/prpmc2800.dts
@@ -0,0 +1,321 @@
+/* Device Tree Source for Motorola PrPMC2800
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 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.
+ *
+ * To build:
+ * dtc -I dts -O asm -o prpmc2800.S -V 16 -b 0 prpmc2800.dts
+ * dtc -I dts -O dtb -o prpmc2800.dtb -V 16 -b 0 prpmc2800.dts
+ */
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "PrPMC280/PrPMC2800"; /* Updated by bootwrapper */
+ compatible = "PrPMC2800";
+ coherency-off;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,7447 {
+ device_type = "cpu";
+ reg = <0>;
+ clock-frequency = <0>; /* Set by bootwrapper */
+ bus-frequency = <7f28155>; /* 133.333333 MHz */
+ timebase-frequency = <1fca055>; /* 33.333333 MHz */
+ /* Following required by dtc but not used */
+ i-cache-line-size = <0>;
+ d-cache-line-size = <0>;
+ i-cache-size = <0>;
+ d-cache-size = <0>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <00000000 00000000>; /* Set by bootwrapper */
+ };
+
+ mv64x60@f1000000 { /* Marvell Discovery */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <1>;
+ device_type = "mv64360";
+ compatible = "mv64x60";
+ clock-frequency = <7f28155>; /* 133.333333 Mhz */
+ reg = <f1000000 00010000>;
+ virtual-reg = <f1000000>;
+ ranges = <88000000 88000000 01000000 /* PCI 0 I/O Space */
+ 80000000 80000000 08000000 /* PCI 0 MEM Space */
+ a0000000 a0000000 04000000 /* User FLASH */
+ 00000000 f1000000 00010000 /* Bridge's regs */
+ f2000000 f2000000 00040000>; /* Integrated SRAM */
+
+ flash@a0000000 {
+ device_type = "rom";
+ compatible = "direct-mapped";
+ reg = <a0000000 0>; /* Size set by bootwrapper */
+ probe-type = "CFI";
+ bank-width = <4>;
+ partitions = <00000000 00100000 /* RO */
+ 00100000 00040001 /* RW */
+ 00140000 00400000 /* RO */
+ 00540000 039c0000 /* RO */
+ 03f00000 00100000>; /* RO */
+ partition-names = "FW Image A\0FW Config Data\0Kernel Image\0Filesystem\0FW Image B";
+ };
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "mdio";
+ compatible = "mv64x60-mdio";
+ ethernet-phy@1 {
+ device_type = "ethernet-phy";
+ compatible = "bcm5421";
+ interrupts = <4c>; /* GPP 12 */
+ interrupt-parent = <&/mv64x60/pic>;
+ reg = <1>;
+ };
+ ethernet-phy@3 {
+ device_type = "ethernet-phy";
+ compatible = "bcm5421";
+ interrupts = <4c>; /* GPP 12 */
+ interrupt-parent = <&/mv64x60/pic>;
+ reg = <3>;
+ };
+ };
+
+ ethernet@2000 { /* mac-address set by bootwrapper */
+ reg = <2000 2000>;
+ eth0 {
+ device_type = "network";
+ compatible = "mv64x60-eth";
+ block-index = <0>;
+ interrupts = <20>;
+ interrupt-parent = <&/mv64x60/pic>;
+ phy = <&/mv64x60/mdio/ethernet-phy@1>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ eth1 {
+ device_type = "network";
+ compatible = "mv64x60-eth";
+ block-index = <1>;
+ interrupts = <21>;
+ interrupt-parent = <&/mv64x60/pic>;
+ phy = <&/mv64x60/mdio/ethernet-phy@3>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ };
+
+ sdma@4000 {
+ device_type = "dma";
+ compatible = "mv64x60-sdma";
+ reg = <4000 c18>;
+ virtual-reg = <f1004000>;
+ interrupt-base = <0>;
+ interrupts = <24>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ sdma@6000 {
+ device_type = "dma";
+ compatible = "mv64x60-sdma";
+ reg = <6000 c18>;
+ virtual-reg = <f1006000>;
+ interrupt-base = <0>;
+ interrupts = <26>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ brg@b200 {
+ device_type = "brg";
+ compatible = "mv64x60-brg";
+ reg = <b200 8>;
+ clock-src = <8>;
+ clock-frequency = <7ed6b40>;
+ current-speed = <2580>;
+ bcr = <0>;
+ };
+
+ brg@b208 {
+ device_type = "brg";
+ compatible = "mv64x60-brg";
+ reg = <b208 8>;
+ clock-src = <8>;
+ clock-frequency = <7ed6b40>;
+ current-speed = <2580>;
+ bcr = <0>;
+ };
+
+ cunit@f200 {
+ device_type = "mv64x60-cunit";
+ reg = <f200 200>;
+ };
+
+ mpscrouting@b400 {
+ device_type = "mpscrouting";
+ reg = <b400 c>;
+ };
+
+ mpscintr@b800 {
+ device_type = "mpscintr";
+ reg = <b800 100>;
+ virtual-reg = <f100b800>;
+ };
+
+ mpsc@8000 {
+ device_type = "serial";
+ compatible = "mpsc";
+ reg = <8000 38>;
+ virtual-reg = <f1008000>;
+ sdma = <&/mv64x60/sdma@4000>;
+ brg = <&/mv64x60/brg@b200>;
+ cunit = <&/mv64x60/cunit@f200>;
+ mpscrouting = <&/mv64x60/mpscrouting@b400>;
+ mpscintr = <&/mv64x60/mpscintr@b800>;
+ block-index = <0>;
+ max_idle = <28>;
+ chr_1 = <0>;
+ chr_2 = <0>;
+ chr_10 = <3>;
+ mpcr = <0>;
+ interrupts = <28>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ mpsc@9000 {
+ device_type = "serial";
+ compatible = "mpsc";
+ reg = <9000 38>;
+ virtual-reg = <f1009000>;
+ sdma = <&/mv64x60/sdma@6000>;
+ brg = <&/mv64x60/brg@b208>;
+ cunit = <&/mv64x60/cunit@f200>;
+ mpscrouting = <&/mv64x60/mpscrouting@b400>;
+ mpscintr = <&/mv64x60/mpscintr@b800>;
+ block-index = <1>;
+ max_idle = <28>;
+ chr_1 = <0>;
+ chr_2 = <0>;
+ chr_10 = <3>;
+ mpcr = <0>;
+ interrupts = <2a>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ i2c@c000 {
+ device_type = "i2c";
+ compatible = "mv64x60-i2c";
+ reg = <c000 20>;
+ virtual-reg = <f100c000>;
+ freq_m = <8>;
+ freq_n = <3>;
+ timeout = <3e8>; /* 1000 = 1 second */
+ retries = <1>;
+ interrupts = <25>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ pic {
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ device_type = "mv64x60-pic";
+ compatible = "mv64x60-pic";
+ reg = <0000 88>;
+ interrupt-controller;
+ };
+
+ mpp@f000 {
+ device_type = "mv64x60-mpp";
+ compatible = "mv64x60-mpp";
+ reg = <f000 10>;
+ };
+
+ gpp@f100 {
+ device_type = "mv64x60-gpp";
+ compatible = "mv64x60-gpp";
+ reg = <f100 20>;
+ };
+
+ pci@80000000 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ compatible = "mv64x60-pci";
+ reg = <0cf8 8>;
+ ranges = <01000000 0 0 88000000 0 01000000
+ 02000000 0 80000000 80000000 0 08000000>;
+ bus-range = <0 ff>;
+ clock-frequency = <3EF1480>;
+ interrupt-pci-iack = <0c34>;
+ interrupt-parent = <&/mv64x60/pic>;
+ interrupt-map-mask = <f800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0a */
+ 5000 0 0 1 &/mv64x60/pic 50
+ 5000 0 0 2 &/mv64x60/pic 51
+ 5000 0 0 3 &/mv64x60/pic 5b
+ 5000 0 0 4 &/mv64x60/pic 5d
+
+ /* IDSEL 0x0b */
+ 5800 0 0 1 &/mv64x60/pic 5b
+ 5800 0 0 2 &/mv64x60/pic 5d
+ 5800 0 0 3 &/mv64x60/pic 50
+ 5800 0 0 4 &/mv64x60/pic 51
+
+ /* IDSEL 0x0c */
+ 6000 0 0 1 &/mv64x60/pic 5b
+ 6000 0 0 2 &/mv64x60/pic 5d
+ 6000 0 0 3 &/mv64x60/pic 50
+ 6000 0 0 4 &/mv64x60/pic 51
+
+ /* IDSEL 0x0d */
+ 6800 0 0 1 &/mv64x60/pic 5d
+ 6800 0 0 2 &/mv64x60/pic 50
+ 6800 0 0 3 &/mv64x60/pic 51
+ 6800 0 0 4 &/mv64x60/pic 5b
+ >;
+ };
+
+ cpu-error@0070 {
+ device_type = "mv64x60-cpu-error";
+ reg = <0070 10 0128 28>;
+ interrupts = <03>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ sram-error@0380 {
+ device_type = "mv64x60-sram-error";
+ reg = <0380 80>;
+ interrupts = <0d>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ pci-error@1dc0 {
+ device_type = "mv64x60-pci-error";
+ reg = <1d40 40 0c28 4>;
+ interrupts = <0c>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ memctrl@1400 {
+ device_type = "mv64x60-memctrl";
+ reg = <1400 60>;
+ interrupts = <11>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+ };
+
+ chosen {
+ bootargs = "ip=on console=ttyMM0";
+ linux,stdout-path = "/mv64x60/mpsc@8000";
+ };
+};
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 11/13] powerpc: Add DTS file for the Motorola PrPMC2800 platform
2007-04-27 20:41 ` Mark A. Greer
@ 2007-04-30 16:45 ` Jon Loeliger
2007-04-30 18:08 ` Mark A. Greer
2007-04-30 22:29 ` Mark A. Greer
0 siblings, 2 replies; 87+ messages in thread
From: Jon Loeliger @ 2007-04-30 16:45 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev, Paul Mackerras
On Fri, 2007-04-27 at 15:41, Mark A. Greer wrote:
> [PATCH 11/13] powerpc: Add DTS file for the Motorola PrPMC2800 platform
>
> Signed-off-by: Mark A. Greer <mgreer@mvista.com>
> ---
>
> prpmc2800.dts | 321 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 321 insertions(+)
>
> Index: powerpc/arch/powerpc/boot/dts/prpmc2800.dts
> ===================================================================
> --- /dev/null
> +++ powerpc/arch/powerpc/boot/dts/prpmc2800.dts
> @@ -0,0 +1,321 @@
> +/* Device Tree Source for Motorola PrPMC2800
> + *
> + * Author: Mark A. Greer <mgreer@mvista.com>
> + *
> + * 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.
> + *
> + * To build:
> + * dtc -I dts -O asm -o prpmc2800.S -V 16 -b 0 prpmc2800.dts
> + * dtc -I dts -O dtb -o prpmc2800.dtb -V 16 -b 0 prpmc2800.dts
Any real reason to keep the -V 16 in there?
If not, please remove this advice!
Thanks,
jdl
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 11/13] powerpc: Add DTS file for the Motorola PrPMC2800 platform
2007-04-30 16:45 ` Jon Loeliger
@ 2007-04-30 18:08 ` Mark A. Greer
2007-04-30 22:29 ` Mark A. Greer
1 sibling, 0 replies; 87+ messages in thread
From: Mark A. Greer @ 2007-04-30 18:08 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev, Paul Mackerras
On Mon, Apr 30, 2007 at 11:45:41AM -0500, Jon Loeliger wrote:
> On Fri, 2007-04-27 at 15:41, Mark A. Greer wrote:
> > [PATCH 11/13] powerpc: Add DTS file for the Motorola PrPMC2800 platform
> >
> > Signed-off-by: Mark A. Greer <mgreer@mvista.com>
> > ---
> >
> > prpmc2800.dts | 321 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 321 insertions(+)
> >
> > Index: powerpc/arch/powerpc/boot/dts/prpmc2800.dts
> > ===================================================================
> > --- /dev/null
> > +++ powerpc/arch/powerpc/boot/dts/prpmc2800.dts
> > @@ -0,0 +1,321 @@
> > +/* Device Tree Source for Motorola PrPMC2800
> > + *
> > + * Author: Mark A. Greer <mgreer@mvista.com>
> > + *
> > + * 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.
> > + *
> > + * To build:
> > + * dtc -I dts -O asm -o prpmc2800.S -V 16 -b 0 prpmc2800.dts
> > + * dtc -I dts -O dtb -o prpmc2800.dtb -V 16 -b 0 prpmc2800.dts
>
> Any real reason to keep the -V 16 in there?
> If not, please remove this advice!
Nope. It just got copied along...
Mark
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 11/13] powerpc: Add DTS file for the Motorola PrPMC2800 platform
2007-04-30 16:45 ` Jon Loeliger
2007-04-30 18:08 ` Mark A. Greer
@ 2007-04-30 22:29 ` Mark A. Greer
1 sibling, 0 replies; 87+ messages in thread
From: Mark A. Greer @ 2007-04-30 22:29 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev, Paul Mackerras
[PATCH 11/13] powerpc: Add DTS file for the Motorola PrPMC2800 platform
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
---
prpmc2800.dts | 321 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 321 insertions(+)
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
Index: powerpc/arch/powerpc/boot/dts/prpmc2800.dts
===================================================================
--- /dev/null
+++ powerpc/arch/powerpc/boot/dts/prpmc2800.dts
@@ -0,0 +1,321 @@
+/* Device Tree Source for Motorola PrPMC2800
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 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.
+ *
+ * To build:
+ * dtc -I dts -O asm -o prpmc2800.S -b 0 prpmc2800.dts
+ * dtc -I dts -O dtb -o prpmc2800.dtb -b 0 prpmc2800.dts
+ */
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "PrPMC280/PrPMC2800"; /* Updated by bootwrapper */
+ compatible = "PrPMC2800";
+ coherency-off;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ PowerPC,7447 {
+ device_type = "cpu";
+ reg = <0>;
+ clock-frequency = <0>; /* Set by bootwrapper */
+ bus-frequency = <7f28155>; /* 133.333333 MHz */
+ timebase-frequency = <1fca055>; /* 33.333333 MHz */
+ /* Following required by dtc but not used */
+ i-cache-line-size = <0>;
+ d-cache-line-size = <0>;
+ i-cache-size = <0>;
+ d-cache-size = <0>;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <00000000 00000000>; /* Set by bootwrapper */
+ };
+
+ mv64x60@f1000000 { /* Marvell Discovery */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <1>;
+ device_type = "mv64360";
+ compatible = "mv64x60";
+ clock-frequency = <7f28155>; /* 133.333333 Mhz */
+ reg = <f1000000 00010000>;
+ virtual-reg = <f1000000>;
+ ranges = <88000000 88000000 01000000 /* PCI 0 I/O Space */
+ 80000000 80000000 08000000 /* PCI 0 MEM Space */
+ a0000000 a0000000 04000000 /* User FLASH */
+ 00000000 f1000000 00010000 /* Bridge's regs */
+ f2000000 f2000000 00040000>; /* Integrated SRAM */
+
+ flash@a0000000 {
+ device_type = "rom";
+ compatible = "direct-mapped";
+ reg = <a0000000 0>; /* Size set by bootwrapper */
+ probe-type = "CFI";
+ bank-width = <4>;
+ partitions = <00000000 00100000 /* RO */
+ 00100000 00040001 /* RW */
+ 00140000 00400000 /* RO */
+ 00540000 039c0000 /* RO */
+ 03f00000 00100000>; /* RO */
+ partition-names = "FW Image A\0FW Config Data\0Kernel Image\0Filesystem\0FW Image B";
+ };
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "mdio";
+ compatible = "mv64x60-mdio";
+ ethernet-phy@1 {
+ device_type = "ethernet-phy";
+ compatible = "bcm5421";
+ interrupts = <4c>; /* GPP 12 */
+ interrupt-parent = <&/mv64x60/pic>;
+ reg = <1>;
+ };
+ ethernet-phy@3 {
+ device_type = "ethernet-phy";
+ compatible = "bcm5421";
+ interrupts = <4c>; /* GPP 12 */
+ interrupt-parent = <&/mv64x60/pic>;
+ reg = <3>;
+ };
+ };
+
+ ethernet@2000 { /* mac-address set by bootwrapper */
+ reg = <2000 2000>;
+ eth0 {
+ device_type = "network";
+ compatible = "mv64x60-eth";
+ block-index = <0>;
+ interrupts = <20>;
+ interrupt-parent = <&/mv64x60/pic>;
+ phy = <&/mv64x60/mdio/ethernet-phy@1>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ eth1 {
+ device_type = "network";
+ compatible = "mv64x60-eth";
+ block-index = <1>;
+ interrupts = <21>;
+ interrupt-parent = <&/mv64x60/pic>;
+ phy = <&/mv64x60/mdio/ethernet-phy@3>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ };
+
+ sdma@4000 {
+ device_type = "dma";
+ compatible = "mv64x60-sdma";
+ reg = <4000 c18>;
+ virtual-reg = <f1004000>;
+ interrupt-base = <0>;
+ interrupts = <24>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ sdma@6000 {
+ device_type = "dma";
+ compatible = "mv64x60-sdma";
+ reg = <6000 c18>;
+ virtual-reg = <f1006000>;
+ interrupt-base = <0>;
+ interrupts = <26>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ brg@b200 {
+ device_type = "brg";
+ compatible = "mv64x60-brg";
+ reg = <b200 8>;
+ clock-src = <8>;
+ clock-frequency = <7ed6b40>;
+ current-speed = <2580>;
+ bcr = <0>;
+ };
+
+ brg@b208 {
+ device_type = "brg";
+ compatible = "mv64x60-brg";
+ reg = <b208 8>;
+ clock-src = <8>;
+ clock-frequency = <7ed6b40>;
+ current-speed = <2580>;
+ bcr = <0>;
+ };
+
+ cunit@f200 {
+ device_type = "mv64x60-cunit";
+ reg = <f200 200>;
+ };
+
+ mpscrouting@b400 {
+ device_type = "mpscrouting";
+ reg = <b400 c>;
+ };
+
+ mpscintr@b800 {
+ device_type = "mpscintr";
+ reg = <b800 100>;
+ virtual-reg = <f100b800>;
+ };
+
+ mpsc@8000 {
+ device_type = "serial";
+ compatible = "mpsc";
+ reg = <8000 38>;
+ virtual-reg = <f1008000>;
+ sdma = <&/mv64x60/sdma@4000>;
+ brg = <&/mv64x60/brg@b200>;
+ cunit = <&/mv64x60/cunit@f200>;
+ mpscrouting = <&/mv64x60/mpscrouting@b400>;
+ mpscintr = <&/mv64x60/mpscintr@b800>;
+ block-index = <0>;
+ max_idle = <28>;
+ chr_1 = <0>;
+ chr_2 = <0>;
+ chr_10 = <3>;
+ mpcr = <0>;
+ interrupts = <28>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ mpsc@9000 {
+ device_type = "serial";
+ compatible = "mpsc";
+ reg = <9000 38>;
+ virtual-reg = <f1009000>;
+ sdma = <&/mv64x60/sdma@6000>;
+ brg = <&/mv64x60/brg@b208>;
+ cunit = <&/mv64x60/cunit@f200>;
+ mpscrouting = <&/mv64x60/mpscrouting@b400>;
+ mpscintr = <&/mv64x60/mpscintr@b800>;
+ block-index = <1>;
+ max_idle = <28>;
+ chr_1 = <0>;
+ chr_2 = <0>;
+ chr_10 = <3>;
+ mpcr = <0>;
+ interrupts = <2a>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ i2c@c000 {
+ device_type = "i2c";
+ compatible = "mv64x60-i2c";
+ reg = <c000 20>;
+ virtual-reg = <f100c000>;
+ freq_m = <8>;
+ freq_n = <3>;
+ timeout = <3e8>; /* 1000 = 1 second */
+ retries = <1>;
+ interrupts = <25>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ pic {
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ device_type = "mv64x60-pic";
+ compatible = "mv64x60-pic";
+ reg = <0000 88>;
+ interrupt-controller;
+ };
+
+ mpp@f000 {
+ device_type = "mv64x60-mpp";
+ compatible = "mv64x60-mpp";
+ reg = <f000 10>;
+ };
+
+ gpp@f100 {
+ device_type = "mv64x60-gpp";
+ compatible = "mv64x60-gpp";
+ reg = <f100 20>;
+ };
+
+ pci@80000000 {
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+ device_type = "pci";
+ compatible = "mv64x60-pci";
+ reg = <0cf8 8>;
+ ranges = <01000000 0 0 88000000 0 01000000
+ 02000000 0 80000000 80000000 0 08000000>;
+ bus-range = <0 ff>;
+ clock-frequency = <3EF1480>;
+ interrupt-pci-iack = <0c34>;
+ interrupt-parent = <&/mv64x60/pic>;
+ interrupt-map-mask = <f800 0 0 7>;
+ interrupt-map = <
+ /* IDSEL 0x0a */
+ 5000 0 0 1 &/mv64x60/pic 50
+ 5000 0 0 2 &/mv64x60/pic 51
+ 5000 0 0 3 &/mv64x60/pic 5b
+ 5000 0 0 4 &/mv64x60/pic 5d
+
+ /* IDSEL 0x0b */
+ 5800 0 0 1 &/mv64x60/pic 5b
+ 5800 0 0 2 &/mv64x60/pic 5d
+ 5800 0 0 3 &/mv64x60/pic 50
+ 5800 0 0 4 &/mv64x60/pic 51
+
+ /* IDSEL 0x0c */
+ 6000 0 0 1 &/mv64x60/pic 5b
+ 6000 0 0 2 &/mv64x60/pic 5d
+ 6000 0 0 3 &/mv64x60/pic 50
+ 6000 0 0 4 &/mv64x60/pic 51
+
+ /* IDSEL 0x0d */
+ 6800 0 0 1 &/mv64x60/pic 5d
+ 6800 0 0 2 &/mv64x60/pic 50
+ 6800 0 0 3 &/mv64x60/pic 51
+ 6800 0 0 4 &/mv64x60/pic 5b
+ >;
+ };
+
+ cpu-error@0070 {
+ device_type = "mv64x60-cpu-error";
+ reg = <0070 10 0128 28>;
+ interrupts = <03>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ sram-error@0380 {
+ device_type = "mv64x60-sram-error";
+ reg = <0380 80>;
+ interrupts = <0d>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ pci-error@1dc0 {
+ device_type = "mv64x60-pci-error";
+ reg = <1d40 40 0c28 4>;
+ interrupts = <0c>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+
+ memctrl@1400 {
+ device_type = "mv64x60-memctrl";
+ reg = <1400 60>;
+ interrupts = <11>;
+ interrupt-parent = <&/mv64x60/pic>;
+ };
+ };
+
+ chosen {
+ bootargs = "ip=on console=ttyMM0";
+ linux,stdout-path = "/mv64x60/mpsc@8000";
+ };
+};
^ permalink raw reply [flat|nested] 87+ messages in thread
* [PATCH 12/13] powerpc: Add bootwrapper support for Motorola PrPMC2800 platform
2007-04-25 23:46 [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800 Mark A. Greer
` (10 preceding siblings ...)
2007-04-26 0:01 ` [PATCH 11/13] powerpc: Add DTS file for the Motorola PrPMC2800 platform Mark A. Greer
@ 2007-04-26 0:02 ` Mark A. Greer
2007-04-26 0:02 ` [PATCH 13/13] powerpc: Add arch/powerpc support for the " Mark A. Greer
2007-04-26 0:45 ` [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800 David Gibson
13 siblings, 0 replies; 87+ messages in thread
From: Mark A. Greer @ 2007-04-26 0:02 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
Add support for Motorola ECC PrPMC280/PrPMC2800 Platform.
The PrPMC280 sits on an F101 baseboard and the PrPMC2800 sits on a
F101e baseboard. Logic has been added to determine which board
(and variant thereof) the code is being run on.
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
---
Makefile | 3
prpmc2800.c | 566 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 568 insertions(+), 1 deletion(-)
Index: powerpc/arch/powerpc/boot/prpmc2800.c
===================================================================
--- /dev/null
+++ powerpc/arch/powerpc/boot/prpmc2800.c
@@ -0,0 +1,566 @@
+/*
+ * Motorola ECC prpmc280/f101 & prpmc2800/f101e platform code.
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 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 <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "elf.h"
+#include "page.h"
+#include "string.h"
+#include "stdio.h"
+#include "io.h"
+#include "ops.h"
+#include "gunzip_util.h"
+#include "mv64x60.h"
+
+extern char _end[];
+extern char _vmlinux_start[], _vmlinux_end[];
+extern char _dtb_start[], _dtb_end[];
+
+#define KB 1024U
+#define MB (KB*KB)
+#define GB (KB*MB)
+#define MHz (1000U*1000U)
+#define GHz (1000U*MHz)
+
+#define BOARD_MODEL "PrPMC2800"
+#define BOARD_MODEL_MAX 32 /* max strlen(BOARD_MODEL) + 1 */
+
+#define EEPROM2_ADDR 0xa4
+#define EEPROM3_ADDR 0xa8
+
+BSS_STACK(16*KB);
+
+static u8 *bridge_base;
+
+typedef enum {
+ BOARD_MODEL_PRPMC280,
+ BOARD_MODEL_PRPMC2800,
+} prpmc2800_board_model;
+
+typedef enum {
+ BRIDGE_TYPE_MV64360,
+ BRIDGE_TYPE_MV64362,
+} prpmc2800_bridge_type;
+
+struct prpmc2800_board_info {
+ prpmc2800_board_model model;
+ char variant;
+ prpmc2800_bridge_type bridge_type;
+ u8 subsys0;
+ u8 subsys1;
+ u8 vpd4;
+ u8 vpd4_mask;
+ u32 core_speed;
+ u32 mem_size;
+ u32 boot_flash;
+ u32 user_flash;
+};
+
+static struct prpmc2800_board_info prpmc2800_board_info[] = {
+ {
+ .model = BOARD_MODEL_PRPMC280,
+ .variant = 'a',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xff,
+ .subsys1 = 0xff,
+ .vpd4 = 0x00,
+ .vpd4_mask = 0x0f,
+ .core_speed = 1*GHz,
+ .mem_size = 512*MB,
+ .boot_flash = 1*MB,
+ .user_flash = 64*MB,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC280,
+ .variant = 'b',
+ .bridge_type = BRIDGE_TYPE_MV64362,
+ .subsys0 = 0xff,
+ .subsys1 = 0xff,
+ .vpd4 = 0x01,
+ .vpd4_mask = 0x0f,
+ .core_speed = 1*GHz,
+ .mem_size = 512*MB,
+ .boot_flash = 0,
+ .user_flash = 0,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC280,
+ .variant = 'c',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xff,
+ .subsys1 = 0xff,
+ .vpd4 = 0x02,
+ .vpd4_mask = 0x0f,
+ .core_speed = 733*MHz,
+ .mem_size = 512*MB,
+ .boot_flash = 1*MB,
+ .user_flash = 64*MB,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC280,
+ .variant = 'd',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xff,
+ .subsys1 = 0xff,
+ .vpd4 = 0x03,
+ .vpd4_mask = 0x0f,
+ .core_speed = 1*GHz,
+ .mem_size = 1*GB,
+ .boot_flash = 1*MB,
+ .user_flash = 64*MB,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC280,
+ .variant = 'e',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xff,
+ .subsys1 = 0xff,
+ .vpd4 = 0x04,
+ .vpd4_mask = 0x0f,
+ .core_speed = 1*GHz,
+ .mem_size = 512*MB,
+ .boot_flash = 1*MB,
+ .user_flash = 64*MB,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC280,
+ .variant = 'f',
+ .bridge_type = BRIDGE_TYPE_MV64362,
+ .subsys0 = 0xff,
+ .subsys1 = 0xff,
+ .vpd4 = 0x05,
+ .vpd4_mask = 0x0f,
+ .core_speed = 733*MHz,
+ .mem_size = 128*MB,
+ .boot_flash = 1*MB,
+ .user_flash = 0,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC280,
+ .variant = 'g',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xff,
+ .subsys1 = 0xff,
+ .vpd4 = 0x06,
+ .vpd4_mask = 0x0f,
+ .core_speed = 1*GHz,
+ .mem_size = 256*MB,
+ .boot_flash = 1*MB,
+ .user_flash = 0,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC280,
+ .variant = 'h',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xff,
+ .subsys1 = 0xff,
+ .vpd4 = 0x07,
+ .vpd4_mask = 0x0f,
+ .core_speed = 1*GHz,
+ .mem_size = 1*GB,
+ .boot_flash = 1*MB,
+ .user_flash = 64*MB,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC2800,
+ .variant = 'a',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xb2,
+ .subsys1 = 0x8c,
+ .vpd4 = 0x00,
+ .vpd4_mask = 0x00,
+ .core_speed = 1*GHz,
+ .mem_size = 512*MB,
+ .boot_flash = 2*MB,
+ .user_flash = 64*MB,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC2800,
+ .variant = 'b',
+ .bridge_type = BRIDGE_TYPE_MV64362,
+ .subsys0 = 0xb2,
+ .subsys1 = 0x8d,
+ .vpd4 = 0x00,
+ .vpd4_mask = 0x00,
+ .core_speed = 1*GHz,
+ .mem_size = 512*MB,
+ .boot_flash = 0,
+ .user_flash = 0,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC2800,
+ .variant = 'c',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xb2,
+ .subsys1 = 0x8e,
+ .vpd4 = 0x00,
+ .vpd4_mask = 0x00,
+ .core_speed = 733*MHz,
+ .mem_size = 512*MB,
+ .boot_flash = 2*MB,
+ .user_flash = 64*MB,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC2800,
+ .variant = 'd',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xb2,
+ .subsys1 = 0x8f,
+ .vpd4 = 0x00,
+ .vpd4_mask = 0x00,
+ .core_speed = 1*GHz,
+ .mem_size = 1*GB,
+ .boot_flash = 2*MB,
+ .user_flash = 64*MB,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC2800,
+ .variant = 'e',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xa2,
+ .subsys1 = 0x8a,
+ .vpd4 = 0x00,
+ .vpd4_mask = 0x00,
+ .core_speed = 1*GHz,
+ .mem_size = 512*MB,
+ .boot_flash = 2*MB,
+ .user_flash = 64*MB,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC2800,
+ .variant = 'f',
+ .bridge_type = BRIDGE_TYPE_MV64362,
+ .subsys0 = 0xa2,
+ .subsys1 = 0x8b,
+ .vpd4 = 0x00,
+ .vpd4_mask = 0x00,
+ .core_speed = 733*MHz,
+ .mem_size = 128*MB,
+ .boot_flash = 2*MB,
+ .user_flash = 0,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC2800,
+ .variant = 'g',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xa2,
+ .subsys1 = 0x8c,
+ .vpd4 = 0x00,
+ .vpd4_mask = 0x00,
+ .core_speed = 1*GHz,
+ .mem_size = 2*GB,
+ .boot_flash = 2*MB,
+ .user_flash = 64*MB,
+ },
+ {
+ .model = BOARD_MODEL_PRPMC2800,
+ .variant = 'h',
+ .bridge_type = BRIDGE_TYPE_MV64360,
+ .subsys0 = 0xa2,
+ .subsys1 = 0x8d,
+ .vpd4 = 0x00,
+ .vpd4_mask = 0x00,
+ .core_speed = 733*MHz,
+ .mem_size = 1*GB,
+ .boot_flash = 2*MB,
+ .user_flash = 64*MB,
+ },
+};
+
+static struct prpmc2800_board_info *prpmc2800_get_board_info(u8 *vpd)
+{
+ struct prpmc2800_board_info *bip;
+ int i;
+
+ for (i=0,bip=prpmc2800_board_info; i<ARRAY_SIZE(prpmc2800_board_info);
+ i++,bip++)
+ if ((vpd[0] == bip->subsys0) && (vpd[1] == bip->subsys1)
+ && ((vpd[4] & bip->vpd4_mask) == bip->vpd4))
+ return bip;
+
+ return NULL;
+}
+
+/* Get VPD from i2c eeprom 2, then match it to a board info entry */
+static struct prpmc2800_board_info *prpmc2800_get_bip(void)
+{
+ struct prpmc2800_board_info *bip;
+ u8 vpd[5];
+ int rc;
+
+ if (mv64x60_i2c_open())
+ fatal("Error: Can't open i2c device\n\r");
+
+ /* Get VPD from i2c eeprom-2 */
+ memset(vpd, 0, sizeof(vpd));
+ rc = mv64x60_i2c_read(EEPROM2_ADDR, vpd, 0x1fde, 2, sizeof(vpd));
+ if (rc < 0)
+ fatal("Error: Couldn't read eeprom2\n\r");
+ mv64x60_i2c_close();
+
+ /* Get board type & related info */
+ bip = prpmc2800_get_board_info(vpd);
+ if (bip == NULL) {
+ printf("Error: Unsupported board or corrupted VPD:\n\r");
+ fatal(" 0x%x 0x%x 0x%x 0x%x 0x%x\n\r",
+ vpd[0], vpd[1], vpd[2], vpd[3], vpd[4]);
+ }
+
+ return bip;
+}
+
+static void prpmc2800_bridge_setup(struct prpmc2800_board_info *bip)
+{
+ u32 i, v[12], enables, acc_bits;
+ u32 pci_base_hi, pci_base_lo, size, buf[2];
+ unsigned long cpu_base;
+ int rc;
+ void *devp;
+ u8 *bridge_pbase, is_coherent;
+ struct mv64x60_cpu2pci_win *tbl;
+
+ bridge_pbase = mv64x60_get_bridge_pbase();
+ is_coherent = mv64x60_is_coherent();
+
+ if (is_coherent)
+ acc_bits = MV64x60_PCI_ACC_CNTL_SNOOP_WB
+ | MV64x60_PCI_ACC_CNTL_SWAP_NONE
+ | MV64x60_PCI_ACC_CNTL_MBURST_32_BYTES
+ | MV64x60_PCI_ACC_CNTL_RDSIZE_32_BYTES;
+ else
+ acc_bits = MV64x60_PCI_ACC_CNTL_SNOOP_NONE
+ | MV64x60_PCI_ACC_CNTL_SWAP_NONE
+ | MV64x60_PCI_ACC_CNTL_MBURST_128_BYTES
+ | MV64x60_PCI_ACC_CNTL_RDSIZE_256_BYTES;
+
+ mv64x60_config_ctlr_windows(bridge_base, bridge_pbase, is_coherent);
+ mv64x60_config_pci_windows(bridge_base, bridge_pbase, 0, 0,
+ bip->mem_size, acc_bits);
+
+ /* Get the cpu -> pci i/o & mem mappings from the device tree */
+ devp = finddevice("/mv64x60/pci@80000000");
+ if (devp == NULL)
+ fatal("Error: Missing /mv64x60/pci@80000000"
+ " device tree node\n\r");
+
+ rc = getprop(devp, "ranges", v, sizeof(v));
+ if (rc != sizeof(v))
+ fatal("Error: Can't find /mv64x60/pci@80000000/ranges"
+ " property\n\r");
+
+ /* Get the cpu -> pci i/o & mem mappings from the device tree */
+ devp = finddevice("/mv64x60");
+ if (devp == NULL)
+ fatal("Error: Missing /mv64x60 device tree node\n\r");
+
+ enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE));
+ enables |= 0x0007fe00; /* Disable all cpu->pci windows */
+ out_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE), enables);
+
+ for (i=0; i<12; i+=6) {
+ switch (v[i] & 0xff000000) {
+ case 0x01000000: /* PCI I/O Space */
+ tbl = mv64x60_cpu2pci_io;
+ break;
+ case 0x02000000: /* PCI MEM Space */
+ tbl = mv64x60_cpu2pci_mem;
+ break;
+ default:
+ continue;
+ }
+
+ pci_base_hi = v[i+1];
+ pci_base_lo = v[i+2];
+ cpu_base = v[i+3];
+ size = v[i+5];
+
+ buf[0] = cpu_base;
+ buf[1] = size;
+
+ if (!dt_xlate_addr(devp, buf, sizeof(buf), &cpu_base))
+ fatal("Error: Can't translate PCI address 0x%x\n\r",
+ (u32)cpu_base);
+
+ mv64x60_config_cpu2pci_window(bridge_base, 0, pci_base_hi,
+ pci_base_lo, cpu_base, size, tbl);
+ }
+
+ enables &= ~0x00000600; /* Enable cpu->pci0 i/o, cpu->pci0 mem0 */
+ out_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE), enables);
+}
+
+/* XXX turn off WDT, DMA engines, timers */
+
+static void prpmc2800_fixups(void)
+{
+ u32 v[2], l;
+ int rc;
+ void *devp;
+ char model[BOARD_MODEL_MAX];
+ struct prpmc2800_board_info *bip;
+
+ bip = prpmc2800_get_bip(); /* Get board info based on VPD */
+ prpmc2800_bridge_setup(bip); /* Do necessary bridge setup */
+
+ /* Now fixup device tree properties */
+ /* Set /model appropriately */
+ devp = finddevice("/");
+ if (devp == NULL)
+ fatal("Error: Missing '/' device tree node\n\r");
+ memset(model, 0, BOARD_MODEL_MAX);
+ strncpy(model, BOARD_MODEL, BOARD_MODEL_MAX - 2);
+ l = strlen(model);
+ if (bip->model == BOARD_MODEL_PRPMC280)
+ l--;
+ model[l++] = bip->variant;
+ model[l++] = '\0';
+ setprop(devp, "model", model, l);
+
+ /* Set /cpus/PowerPC,7447/clock-frequency */
+ devp = finddevice("/cpus/PowerPC,7447");
+ if (devp == NULL)
+ fatal("Error: Missing proper /cpus device tree node\n\r");
+ v[0] = bip->core_speed;
+ setprop(devp, "clock-frequency", &v[0], sizeof(v[0]));
+
+ /* Set /memory/reg size */
+ devp = finddevice("/memory");
+ if (devp == NULL)
+ fatal("Error: Missing /memory device tree node\n\r");
+ v[0] = 0;
+ v[1] = bip->mem_size;
+ setprop(devp, "reg", v, sizeof(v));
+
+ /* Update /mv64x60/device_type, if this is a mv64362 */
+ if (bip->bridge_type == BRIDGE_TYPE_MV64362) {
+ devp = finddevice("/mv64x60");
+ if (devp == NULL)
+ fatal("Error: Missing /mv64x60 device tree node\n\r");
+ setprop(devp, "device_type", "mv64362", strlen("mv64362") + 1);
+ }
+
+ /* Set User FLASH size */
+ devp = finddevice("/mv64x60/flash@a0000000");
+ if (devp == NULL)
+ fatal("Error: Missing User FLASH device tree node\n\r");
+ rc = getprop(devp, "reg", v, sizeof(v));
+ if (rc != sizeof(v))
+ fatal("Error: Can't find User FLASH reg property\n\r");
+ v[1] = bip->user_flash;
+ setprop(devp, "reg", v, sizeof(v));
+}
+
+#define MV64x60_MPP_CNTL_0 0xf000
+#define MV64x60_MPP_CNTL_2 0xf008
+#define MV64x60_GPP_IO_CNTL 0xf100
+#define MV64x60_GPP_LEVEL_CNTL 0xf110
+#define MV64x60_GPP_VALUE_SET 0xf118
+
+static void prpmc2800_reset(void)
+{
+ u32 temp;
+
+ if (bridge_base != 0) {
+ temp = in_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_0));
+ temp &= 0xFFFF0FFF;
+ out_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_0), temp);
+
+ temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL));
+ temp |= 0x00000004;
+ out_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL), temp);
+
+ temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL));
+ temp |= 0x00000004;
+ out_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL), temp);
+
+ temp = in_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_2));
+ temp &= 0xFFFF0FFF;
+ out_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_2), temp);
+
+ temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL));
+ temp |= 0x00080000;
+ out_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL), temp);
+
+ temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL));
+ temp |= 0x00080000;
+ out_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL), temp);
+
+ out_le32((u32 *)(bridge_base + MV64x60_GPP_VALUE_SET),
+ 0x00080004);
+ }
+
+ for (;;);
+}
+
+#define HEAP_SIZE (16*MB)
+static struct gunzip_state gzstate;
+
+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7)
+{
+ struct elf_info ei;
+ char *heap_start, *dtb;
+ int dt_size = _dtb_end - _dtb_start;
+ void *vmlinuz_addr = _vmlinux_start;
+ unsigned long vmlinuz_size = _vmlinux_end - _vmlinux_start;
+ char elfheader[256];
+
+ if (dt_size <= 0) /* No fdt */
+ exit();
+
+ /*
+ * Start heap after end of the kernel (after decompressed to
+ * address 0) or the end of the zImage, whichever is higher.
+ * That's so things allocated by simple_alloc won't overwrite
+ * any part of the zImage and the kernel won't overwrite the dtb
+ * when decompressed & relocated.
+ */
+ gunzip_start(&gzstate, vmlinuz_addr, vmlinuz_size);
+ gunzip_exactly(&gzstate, elfheader, sizeof(elfheader));
+
+ if (!parse_elf32(elfheader, &ei))
+ exit();
+
+ heap_start = (char *)(ei.memsize + ei.elfoffset); /* end of kernel*/
+ heap_start = max(heap_start, (char *)_end); /* end of zImage */
+
+ if ((unsigned)simple_alloc_init(heap_start, HEAP_SIZE, 2*KB, 16)
+ > (128*MB))
+ exit();
+
+ /* Relocate dtb to safe area past end of zImage & kernel */
+ dtb = malloc(dt_size);
+ if (!dtb)
+ exit();
+ memmove(dtb, _dtb_start, dt_size);
+ if (ft_init(dtb, dt_size, 16))
+ exit();
+
+ bridge_base = mv64x60_get_bridge_base();
+
+ platform_ops.fixups = prpmc2800_fixups;
+ platform_ops.exit = prpmc2800_reset;
+
+ if (serial_console_init() < 0)
+ exit();
+}
+
+/* Following code is put at very beginning of zImage (64KB into ELF file) */
+asm (" .globl _zimage_start\n\
+ _zimage_start:\n\
+ mfmsr 10\n\
+ rlwinm 10,10,0,~(1<<15) /* Clear MSR_EE */\n\
+ sync\n\
+ mtmsr 10\n\
+ isync\n\
+ b _zimage_start_lib\n\
+");
Index: powerpc/arch/powerpc/boot/Makefile
===================================================================
--- powerpc.orig/arch/powerpc/boot/Makefile
+++ powerpc/arch/powerpc/boot/Makefile
@@ -44,7 +44,7 @@ src-wlib := string.S crt0.S stdio.c main
ns16550.c serial.c simple_alloc.c div64.S util.S \
gunzip_util.c elf_util.c devtree.c mv64x60.c mpsc.c \
mv64x60_i2c.c $(zlib)
-src-plat := of.c cuboot-83xx.c
+src-plat := of.c cuboot-83xx.c prpmc2800.c
src-boot := $(src-wlib) $(src-plat) empty.c
src-boot := $(addprefix $(obj)/, $(src-boot))
@@ -130,6 +130,7 @@ image-$(CONFIG_PPC_CELLEB) += zImage.ps
image-$(CONFIG_PPC_CHRP) += zImage.chrp
image-$(CONFIG_PPC_EFIKA) += zImage.chrp
image-$(CONFIG_PPC_PMAC) += zImage.pmac
+image-$(CONFIG_PPC_PRPMC2800) += zImage.prpmc2800
image-$(CONFIG_DEFAULT_UIMAGE) += uImage cuImage
# For 32-bit powermacs, build the COFF and miboot images
^ permalink raw reply [flat|nested] 87+ messages in thread
* [PATCH 13/13] powerpc: Add arch/powerpc support for the Motorola PrPMC2800 platform
2007-04-25 23:46 [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800 Mark A. Greer
` (11 preceding siblings ...)
2007-04-26 0:02 ` [PATCH 12/13] powerpc: Add bootwrapper support for " Mark A. Greer
@ 2007-04-26 0:02 ` Mark A. Greer
2007-04-26 0:45 ` [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800 David Gibson
13 siblings, 0 replies; 87+ messages in thread
From: Mark A. Greer @ 2007-04-26 0:02 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
From: Dale Farnsworth <dale@farnsworth.org>
Signed-off-by: Dale Farnsworth <dale@farnsworth.org>
---
Kconfig | 2
configs/prpmc2800_defconfig | 1437 ++++++++++++++++++++++++++++++++++++++
platforms/embedded6xx/Kconfig | 9
platforms/embedded6xx/Makefile | 1
platforms/embedded6xx/prpmc2800.c | 169 ++++
5 files changed, 1617 insertions(+), 1 deletion(-)
Index: powerpc/arch/powerpc/platforms/embedded6xx/Kconfig
===================================================================
--- powerpc.orig/arch/powerpc/platforms/embedded6xx/Kconfig
+++ powerpc/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -25,6 +25,15 @@ config MPC7448HPC2
help
Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga)
platform
+
+config PPC_PRPMC2800
+ bool "Motorola-PrPMC2800"
+ select MV64X60
+ select NOT_COHERENT_CACHE
+ select WANT_DEVICE_TREE
+ help
+ This option enables support for the Motorola PrPMC2800 board
+
endchoice
config TSI108_BRIDGE
Index: powerpc/arch/powerpc/platforms/embedded6xx/Makefile
===================================================================
--- powerpc.orig/arch/powerpc/platforms/embedded6xx/Makefile
+++ powerpc/arch/powerpc/platforms/embedded6xx/Makefile
@@ -3,3 +3,4 @@
#
obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o
obj-$(CONFIG_LINKSTATION) += linkstation.o ls_uart.o
+obj-$(CONFIG_PPC_PRPMC2800) += prpmc2800.o
Index: powerpc/arch/powerpc/platforms/embedded6xx/prpmc2800.c
===================================================================
--- /dev/null
+++ powerpc/arch/powerpc/platforms/embedded6xx/prpmc2800.c
@@ -0,0 +1,169 @@
+/*
+ * Board setup routines for the Motorola PrPMC2800
+ *
+ * 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/delay.h>
+#include <linux/interrupt.h>
+#include <linux/seq_file.h>
+
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/kexec.h>
+
+#include <mm/mmu_decl.h>
+
+#include <sysdev/mv64x60.h>
+
+#define MV64x60_MPP_CNTL_0 0x0000
+#define MV64x60_MPP_CNTL_2 0x0008
+
+#define MV64x60_GPP_IO_CNTL 0x0000
+#define MV64x60_GPP_LEVEL_CNTL 0x0010
+#define MV64x60_GPP_VALUE_SET 0x0018
+
+#define PLATFORM_NAME_MAX 32
+
+static char prpmc2800_platform_name[PLATFORM_NAME_MAX];
+
+static void __iomem *mv64x60_mpp_reg_base;
+static void __iomem *mv64x60_gpp_reg_base;
+
+static void __init prpmc2800_setup_arch(void)
+{
+ struct device_node *np;
+ phys_addr_t paddr;
+ const unsigned int *reg;
+ const unsigned int *prop;
+
+ /*
+ * ioremap mpp and gpp registers in case they are later
+ * needed by prpmc2800_reset_board().
+ */
+ np = of_find_compatible_node(NULL, NULL, "mv64x60-mpp");
+ reg = of_get_property(np, "reg", NULL);
+ paddr = of_translate_address(np, reg);
+ of_node_put(np);
+ mv64x60_mpp_reg_base = ioremap(paddr, reg[1]);
+
+ np = of_find_compatible_node(NULL, NULL, "mv64x60-gpp");
+ reg = of_get_property(np, "reg", NULL);
+ paddr = of_translate_address(np, reg);
+ of_node_put(np);
+ mv64x60_gpp_reg_base = ioremap(paddr, reg[1]);
+
+ np = of_find_node_by_type(NULL, "cpu");
+ prop = of_get_property(np, "clock-frequency", NULL);
+ if (prop)
+ loops_per_jiffy = *prop / HZ;
+ of_node_put(np);
+
+ mv64x60_pci_init();
+
+ printk("Motorola %s\n", prpmc2800_platform_name);
+}
+
+static void prpmc2800_reset_board(void)
+{
+ u32 temp;
+
+ local_irq_disable();
+
+ temp = in_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_0);
+ temp &= 0xFFFF0FFF;
+ out_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_0, temp);
+
+ temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL);
+ temp |= 0x00000004;
+ out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL, temp);
+
+ temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL);
+ temp |= 0x00000004;
+ out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL, temp);
+
+ temp = in_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_2);
+ temp &= 0xFFFF0FFF;
+ out_le32(mv64x60_mpp_reg_base + MV64x60_MPP_CNTL_2, temp);
+
+ temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL);
+ temp |= 0x00080000;
+ out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_LEVEL_CNTL, temp);
+
+ temp = in_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL);
+ temp |= 0x00080000;
+ out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_IO_CNTL, temp);
+
+ out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_VALUE_SET, 0x00080004);
+}
+
+static void prpmc2800_restart(char *cmd)
+{
+ volatile ulong i = 10000000;
+
+ prpmc2800_reset_board();
+
+ while (i-- > 0);
+ panic("restart failed\n");
+}
+
+#ifdef CONFIG_NOT_COHERENT_CACHE
+#define PPRPM2800_COHERENCY_SETTING "off"
+#else
+#define PPRPM2800_COHERENCY_SETTING "on"
+#endif
+
+void prpmc2800_show_cpuinfo(struct seq_file *m)
+{
+ uint memsize = total_memory;
+
+ seq_printf(m, "Vendor\t\t: Motorola\n");
+ seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024));
+ seq_printf(m, "coherency\t: %s\n", PPRPM2800_COHERENCY_SETTING);
+}
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init prpmc2800_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+ unsigned long len = PLATFORM_NAME_MAX;
+ void *m;
+
+ if (!of_flat_dt_is_compatible(root, "PrPMC2800"))
+ return 0;
+
+ /* Update ppc_md.name with name from dt */
+ m = of_get_flat_dt_prop(root, "model", &len);
+ if (m)
+ strncpy(prpmc2800_platform_name, m,
+ min((int)len, PLATFORM_NAME_MAX - 1));
+
+ return 1;
+}
+
+define_machine(prpmc2800){
+ .name = prpmc2800_platform_name,
+ .probe = prpmc2800_probe,
+ .setup_arch = prpmc2800_setup_arch,
+ .show_cpuinfo = prpmc2800_show_cpuinfo,
+ .init_IRQ = mv64x60_init_irq,
+ .get_irq = mv64x60_get_irq,
+ .restart = prpmc2800_restart,
+ .calibrate_decr = generic_calibrate_decr,
+#ifdef CONFIG_KEXEC
+ .machine_kexec = default_machine_kexec,
+ .machine_kexec_prepare = default_machine_kexec_prepare,
+ .machine_crash_shutdown = default_machine_crash_shutdown,
+#endif
+};
Index: powerpc/arch/powerpc/configs/prpmc2800_defconfig
===================================================================
--- /dev/null
+++ powerpc/arch/powerpc/configs/prpmc2800_defconfig
@@ -0,0 +1,1437 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21-rc7
+# Wed Apr 25 12:55:17 2007
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+# CONFIG_PPC_UDBG_16550 is not set
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+# CONFIG_DEFAULT_UIMAGE is not set
+
+#
+# Processor support
+#
+CONFIG_CLASSIC32=y
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_86xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_6xx=y
+CONFIG_PPC_FPU=y
+# CONFIG_PPC_DCR_NATIVE is not set
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_ALTIVEC=y
+CONFIG_PPC_STD_MMU=y
+CONFIG_PPC_STD_MMU_32=y
+# CONFIG_SMP is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
+# Platform support
+#
+# CONFIG_PPC_MULTIPLATFORM is not set
+CONFIG_EMBEDDED6xx=y
+# CONFIG_APUS is not set
+# CONFIG_PPC_MPC52xx is not set
+# CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_LINKSTATION is not set
+# CONFIG_MPC7448HPC2 is not set
+CONFIG_PPC_PRPMC2800=y
+CONFIG_MV64X60=y
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+
+#
+# CPU Frequency support
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_TAU is not set
+# CONFIG_CPM2 is not set
+
+#
+# Kernel options
+#
+CONFIG_HIGHMEM=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+# CONFIG_KEXEC is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+# CONFIG_SECCOMP is not set
+CONFIG_WANT_DEVICE_TREE=y
+CONFIG_DEVICE_TREE="prpmc2800.dts"
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+# CONFIG_PPC_INDIRECT_PCI_BE is not set
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCIEPORTBUS is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_CONSISTENT_START=0xff100000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_ONLYDISK is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8213 is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=y
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_SRP is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+CONFIG_SATA_MV=y
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIL24 is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_SPI is not set
+# CONFIG_FUSION_FC is not set
+# CONFIG_FUSION_SAS is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+# CONFIG_MAC_EMUMOUSEBTN is not set
+# CONFIG_WINDFARM is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
+# CONFIG_FORCEDETH is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=y
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_8139CP is not set
+CONFIG_8139TOO=y
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+# CONFIG_E1000_NAPI is not set
+# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+CONFIG_MV643XX_ETH=y
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_MPSC=y
+CONFIG_SERIAL_MPSC_CONSOLE=y
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_MPC is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+CONFIG_I2C_MV64XXX=y
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_M41T00 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
+# CONFIG_FB_IBM_GXT4500 is not set
+
+#
+# Console display driver support
+#
+CONFIG_VGA_CONSOLE=y
+# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
+# CONFIG_USB_ISP116X_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_HCD_PPC_OF is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_ACECAD is not set
+# CONFIG_USB_KBTAB is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_TOUCHSCREEN is not set
+# CONFIG_USB_YEALINK is not set
+# CONFIG_USB_XPAD is not set
+# CONFIG_USB_ATI_REMOTE is not set
+# CONFIG_USB_ATI_REMOTE2 is not set
+# CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
+# CONFIG_USB_GTCO is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_USB_MON=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+
+#
+# USB DSL modem support
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_TEST is not set
+CONFIG_RTC_DRV_MAX6900=y
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+# CONFIG_UCC_SLOW is not set
+# CONFIG_UCC_FAST is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
Index: powerpc/arch/powerpc/Kconfig
===================================================================
--- powerpc.orig/arch/powerpc/Kconfig
+++ powerpc/arch/powerpc/Kconfig
@@ -431,7 +431,7 @@ config ARCH_ENABLE_MEMORY_HOTPLUG
config KEXEC
bool "kexec system call (EXPERIMENTAL)"
- depends on PPC_MULTIPLATFORM && EXPERIMENTAL
+ depends on (PPC_PRPMC2800 || PPC_MULTIPLATFORM) && EXPERIMENTAL
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800
2007-04-25 23:46 [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800 Mark A. Greer
` (12 preceding siblings ...)
2007-04-26 0:02 ` [PATCH 13/13] powerpc: Add arch/powerpc support for the " Mark A. Greer
@ 2007-04-26 0:45 ` David Gibson
2007-04-26 0:58 ` Mark A. Greer
13 siblings, 1 reply; 87+ messages in thread
From: David Gibson @ 2007-04-26 0:45 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev, Paul Mackerras
On Wed, Apr 25, 2007 at 04:46:30PM -0700, Mark A. Greer wrote:
> The following set of patches add support for the Motorola prpmc2800/f101e platform.
> To support that platform, several other patches are required that can be grouped as
> follows:
>
> - 1 patch to add Makefile rules that automatically compile & wrap a dts into
> a zImage
> - 1 patch to add a new interface to the dt_xlate code.
> - 3 mv64x60 bootwrapper patches
> - 5 mv64x60 kernel patches
> - 3 prpmc2800 patches
Hrm. This series adds an awful lot of code to the bootwrapper. Is
there really no reasonable way to trim it, perhaps moving some of the
initialization to the kernel driver proper? I can see that memory
controller setup and serial might need to be in the wrapper, but PCI
and I2C initialization?
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800
2007-04-26 0:45 ` [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800 David Gibson
@ 2007-04-26 0:58 ` Mark A. Greer
2007-04-26 1:15 ` Mark A. Greer
0 siblings, 1 reply; 87+ messages in thread
From: Mark A. Greer @ 2007-04-26 0:58 UTC (permalink / raw)
To: Mark A. Greer, Paul Mackerras, linuxppc-dev
On Thu, Apr 26, 2007 at 10:45:14AM +1000, David Gibson wrote:
> On Wed, Apr 25, 2007 at 04:46:30PM -0700, Mark A. Greer wrote:
> > The following set of patches add support for the Motorola prpmc2800/f101e platform.
> > To support that platform, several other patches are required that can be grouped as
> > follows:
> >
> > - 1 patch to add Makefile rules that automatically compile & wrap a dts into
> > a zImage
> > - 1 patch to add a new interface to the dt_xlate code.
> > - 3 mv64x60 bootwrapper patches
> > - 5 mv64x60 kernel patches
> > - 3 prpmc2800 patches
>
> Hrm. This series adds an awful lot of code to the bootwrapper. Is
> there really no reasonable way to trim it, perhaps moving some of the
> initialization to the kernel driver proper? I can see that memory
> controller setup and serial might need to be in the wrapper, but PCI
> and I2C initialization?
Well, its not really the ctlr init. That is done in the kernel
driver(s). What's being set up are the windows that allow the ctlrs to
access system memory. This should really be done the the firmware but
isn't so I think the bootwrapper is the proper place to do it.
AFA PCI, its setting up the window from cpu phys->PCI MEM & I/O,
and PCI MEM->system mem. I think its better to not have that in the
kernel--bloats the kernel and mv64x60 with better fw (which is most of
them hopefully) don't need it.
Another thing to remember is that the marvell bridges are used on MIPS
platforms and therefore the drivers can potentially be used there too.
That makes it doubly important to not dump setup that should be done by
the fw into kernel drivers.
Mark
^ permalink raw reply [flat|nested] 87+ messages in thread
* Re: [PATCH 0/13] powerpc: Add support for Marvell/mv64x60 and prpmc2800
2007-04-26 0:58 ` Mark A. Greer
@ 2007-04-26 1:15 ` Mark A. Greer
0 siblings, 0 replies; 87+ messages in thread
From: Mark A. Greer @ 2007-04-26 1:15 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev, Paul Mackerras
On Wed, Apr 25, 2007 at 05:58:53PM -0700, Mark A. Greer wrote:
> Well, its not really the ctlr init. That is done in the kernel
> driver(s). What's being set up are the windows that allow the ctlrs to
> access system memory. This should really be done the the firmware but
^^^ "by"
> isn't so I think the bootwrapper is the proper place to do it.
>
> AFA PCI, its setting up the window from cpu phys->PCI MEM & I/O,
> and PCI MEM->system mem. I think its better to not have that in the
> kernel--bloats the kernel and mv64x60 with better fw (which is most of
^ "platforms"
Mark
^ permalink raw reply [flat|nested] 87+ messages in thread