* Re: Platform device model drawback
From: Grant Likely @ 2005-11-17 23:46 UTC (permalink / raw)
To: Greg KH, Vitaly Bordug; +Cc: Kumar Gala, linuxppc-embedded list
In-Reply-To: <20051115224056.GA14357@kroah.com>
On 11/15/05, Greg KH <greg@kroah.com> wrote:
> On Tue, Nov 15, 2005 at 01:34:47PM -0600, Kumar Gala wrote:
> > This is where the confusion is. We have two instances of device A. We
> > want instance 1 of device A bound to driver "enet" and instance 2 of
> > device A bound to "serial".
>
> That's different from what was described earlier :)
>
> In this case, you need two different struct devices.
Which is what we have.
>
> > Today both instances are called "deviceA". However we can't register t=
wo
> > different drivers as "deviceA".
>
> Nor would you want to.
>
> > Not sure if that clarifies the issue any.
>
> A bit. I think it still sounds messy...
Does this help? (We also discussed this a bit at the PPC BoF at OLS this y=
ear)
For example on the mpc52xx (see arch/ppc/syslib/mpc52xx_devices.c);
- 6 PSC devices on chip;
- (struct platform_device) for each device has: .name=3D'mpc52xx-psc';
- However, SCC1 may be driven by the Ethernet driver but PSC2 and
PSC6 may be serial
- problem then is: How do you get only PSC1 bound to the
psc-ethernet driver and only PSC2 & PSC6 bound to the serial driver?
Possible solution; Modify the naming scheme slightly from what is
currently used.
1. Make the Ethernet driver register the name "mpc52xx-psc:eth"
2. Make the serial driver register the name "mpc52xx-psc:uart"
3. In the board-specific platform code, modify the .name field in
struct platform_device *before* the device is registered with the
platform device. (possibly by extending ppc_sys_device_fixup callback)
- The board specific code would set PSC1 to "mpc52xx-psc:eth",
PSC2&6 to "mpc52xx-psc:uart". PSC3-5 would stick with "mpc52xx-psc"
and so would not get bound to anything.
Q: Can the .name field be modified *after* platform_device is
registered w/ the platform bus?
g.
^ permalink raw reply
* Problems with fcc_enet driver for MPC8248 (2.6.12)
From: Carlos Munoz @ 2005-11-17 23:39 UTC (permalink / raw)
To: linuxppc-embedded
I'm working on an embedded board that is currently running kernel 2.4.28
without any problems. However, I am trying to upgrade from kernel 2.4.28
to kernel 2.6.12 and I'm unable to get the fcc_enet driver to work
properly.
The fcc ports are connected to ethernet phy devices. The receive and
transmitted data out of the ethernet phy devices is all 0xff.
I tried using the fcc_enet driver from the 2.4.28 kernel on the 2.6.12
kernel but get the same results. This leads me to believe that the core
initialization of the MPC8248 has changed on kernel 2.6.12.
Has anyone got the fcc ports to work properly on the 2.6.12 kernel ? If
yes, how ? Did the MPC8248 core initialization change ?
Thanks,
Carlos Munoz
^ permalink raw reply
* Re: [PATCH] Fix 8250 probe on ppc32
From: Paul Mackerras @ 2005-11-18 1:12 UTC (permalink / raw)
To: David Woodhouse; +Cc: Tom Rini, linuxppc-dev
In-Reply-To: <1132136755.21643.40.camel@hades.cambridge.redhat.com>
David Woodhouse writes:
> I'll try it on Pegasos some time tonight or tomorrow. AFAICT I'm going
> to need the patch which started this thread, if I want any serial ports
> on my Pegasos. The newly-created asm-powerpc/serial.h file is devoid of
> serial port definitions.
This intersects with some more ambitious reworking Ben H is doing, so
I won't put this one in.
Paul.
^ permalink raw reply
* Help ! 2.6.14 kernel can't bring up
From: zjznliang @ 2005-11-18 2:02 UTC (permalink / raw)
To: linuxppc-embedded
SGkgbGludXhwcGMtZW1iZWRkZWSjoQ0KDQoJSGkgLCBIb3cgdG8gY29uZmlnIHRoZSAiZWFybHkg
cHJpbnRrIiBpbiAyLjYuMTQgbGludXggY29uZmlncmF0aW9uPz8/DQoNCg0KIAkJCQkNCg0KoaGh
oXpqem5saWFuZw0KoaGhoaGhoaF6anpubGlhbmdfcG9wb0AxNjMuY29tDQqhoaGhoaGhoaGhoaEy
MDA1LTExLTE4DQo=
^ permalink raw reply
* Re: [PATCH] Fix 8250 probe on ppc32
From: Kumar Gala @ 2005-11-18 3:26 UTC (permalink / raw)
To: Paul Mackerras, Benjamin Herrenschmidt
Cc: Tom Rini, David Woodhouse, linuxppc-dev list
In-Reply-To: <17277.10875.334722.856865@cargo.ozlabs.ibm.com>
Paul or BenH,
Would you like to enlighten us on this ambitious rework?
- kumar
On Nov 17, 2005, at 7:12 PM, Paul Mackerras wrote:
> David Woodhouse writes:
>
>> I'll try it on Pegasos some time tonight or tomorrow. AFAICT I'm
>> going
>> to need the patch which started this thread, if I want any serial
>> ports
>> on my Pegasos. The newly-created asm-powerpc/serial.h file is
>> devoid of
>> serial port definitions.
>
> This intersects with some more ambitious reworking Ben H is doing, so
> I won't put this one in.
>
> Paul.
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
^ permalink raw reply
* Re: [PATCH] Fix 8250 probe on ppc32
From: Benjamin Herrenschmidt @ 2005-11-18 3:50 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev list, David Woodhouse, Tom Rini
In-Reply-To: <3F990F6D-7A3F-47CA-938F-968593678895@kernel.crashing.org>
On Thu, 2005-11-17 at 21:26 -0600, Kumar Gala wrote:
> Paul or BenH,
>
> Would you like to enlighten us on this ambitious rework?
First, some better & more generic routines for translating addresses
from the device-tree, and some more generic code for looking for
standard serial port using the above routines, among others ... also,
set_preferred_console gets modified to use the previous list so it can
detect the ports more reliably, etc ....
Ben.
^ permalink raw reply
* [PATCH] generate COFF zImage in arch/powerpc/boot
From: Paul Mackerras @ 2005-11-18 6:06 UTC (permalink / raw)
To: linuxppc-dev
This patch makes ARCH=powerpc on 32-bit machines generate an
arch/powerpc/boot/zImage.coff suitable for booting on old-world
powermacs. I took the opportunity to reorganize prom.c and prom.h a
bit. The *printf routines have been moved to their own file, stdio.c,
and prom.c now contains a version of claim() that knows what to do on
older machines. The link address of the zImage has been moved up from
4MB to 5MB, since OF on oldworld machines occupies the 4M - 5M region.
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
diff -urN powerpc-merge/arch/powerpc/Makefile merge-hack/arch/powerpc/Makefile
--- powerpc-merge/arch/powerpc/Makefile 2005-11-18 16:11:26.000000000 +1100
+++ merge-hack/arch/powerpc/Makefile 2005-11-18 16:54:42.000000000 +1100
@@ -138,7 +138,7 @@
drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
-defaultimage-$(CONFIG_PPC32) := zImage
+defaultimage-$(CONFIG_PPC32) := zImage zImage.coff
defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux
defaultimage-$(CONFIG_PPC_PSERIES) := zImage
KBUILD_IMAGE := $(defaultimage-y)
@@ -149,7 +149,8 @@
# All the instructions talk about "make bzImage".
bzImage: zImage
-BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm
+BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm \
+ zImage.vmode zImage.initrd.vmode zImage.coff zImage.initrd.coff
.PHONY: $(BOOT_TARGETS)
diff -urN powerpc-merge/arch/powerpc/boot/Makefile merge-hack/arch/powerpc/boot/Makefile
--- powerpc-merge/arch/powerpc/boot/Makefile 2005-11-16 13:52:19.000000000 +1100
+++ merge-hack/arch/powerpc/boot/Makefile 2005-11-17 14:53:27.000000000 +1100
@@ -27,6 +27,7 @@
BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc
BOOTLFLAGS := -T $(srctree)/$(src)/zImage.lds
OBJCOPYFLAGS := contents,alloc,load,readonly,data
+OBJCOPY_COFF_ARGS := -O aixcoff-rs6000 --set-start 0x500000
zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c
zlibheader := infblock.h infcodes.h inffast.h inftrees.h infutil.h
@@ -35,7 +36,7 @@
$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
#$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h)
-src-boot := string.S prom.c main.c div64.S crt0.S
+src-boot := crt0.S string.S prom.c stdio.c main.c div64.S
src-boot += $(zlib)
src-boot := $(addprefix $(obj)/, $(src-boot))
obj-boot := $(addsuffix .o, $(basename $(src-boot)))
@@ -87,12 +88,13 @@
src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section)))
gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section)))
-hostprogs-y := addnote addRamDisk
-targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd \
- $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
- $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
- $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \
- vmlinux.initrd
+hostprogs-y := addnote addRamDisk hack-coff
+
+targets += zImage.vmode zImage.initrd.vmode zImage zImage.initrd \
+ $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \
+ $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \
+ $(patsubst $(obj)/%,%, $(call gz-sec, $(required) $(initrd))) \
+ vmlinux.initrd
extra-y := initrd.o
quiet_cmd_ramdisk = RAMDISK $@
@@ -114,6 +116,10 @@
quiet_cmd_addnote = ADDNOTE $@
cmd_addnote = $(obj)/addnote $@
+quiet_cmd_gencoff = COFF $@
+ cmd_gencoff = $(OBJCOPY) $(OBJCOPY_COFF_ARGS) $< $@ && \
+ $(obj)/hack-coff $@
+
$(call gz-sec, $(required)): $(obj)/kernel-%.gz: %
$(call if_changed,gzip)
@@ -143,6 +149,12 @@
@cp -f $< $@
$(call if_changed,addnote)
+$(obj)/zImage.coff: $(obj)/zImage.vmode $(obj)/hack-coff
+ $(call cmd,gencoff)
+
+$(obj)/zImage.initrd.coff: $(obj)/zImage.initrd.vmode $(obj)/hack-coff
+ $(call cmd,gencoff)
+
install: $(CONFIGURE) $(BOOTIMAGE)
sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)"
diff -urN powerpc-merge/arch/powerpc/boot/crt0.S merge-hack/arch/powerpc/boot/crt0.S
--- powerpc-merge/arch/powerpc/boot/crt0.S 2005-11-18 13:18:16.000000000 +1100
+++ merge-hack/arch/powerpc/boot/crt0.S 2005-11-18 14:00:00.000000000 +1100
@@ -12,17 +12,22 @@
#include "ppc_asm.h"
.text
+ /* a procedure descriptor used when booting this as a COFF file */
+ .long _zimage_start, 0, 0, 0
+
.globl _zimage_start
_zimage_start:
+ /* Work out the offset between the address we were linked at
+ and the address where we're running. */
bl 1f
-
-1:
- mflr r0
+1: mflr r0
lis r9,1b@ha
addi r9,r9,1b@l
subf. r0,r9,r0
- beq 3f
+ beq 3f /* if running at same address as linked */
+ /* The .got2 section contains a list of addresses, so add
+ the address offset onto each entry. */
lis r9,__got2_start@ha
addi r9,r9,__got2_start@l
lis r8,__got2_end@ha
@@ -32,15 +37,14 @@
srwi. r8,r8,2
mtctr r8
add r9,r0,r9
-2:
- lwz r8,0(r9)
+2: lwz r8,0(r9)
add r8,r8,r0
stw r8,0(r9)
addi r9,r9,4
bdnz 2b
-3:
- lis r9,_start@h
+ /* Do a cache flush for our text, in case OF didn't */
+3: lis r9,_start@h
add r9,r0,r9
lis r8,_etext@ha
addi r8,r8,_etext@l
diff -urN powerpc-merge/arch/powerpc/boot/hack-coff.c merge-hack/arch/powerpc/boot/hack-coff.c
--- /dev/null 2005-04-02 20:23:56.000000000 +1000
+++ merge-hack/arch/powerpc/boot/hack-coff.c 2005-11-17 14:57:08.000000000 +1100
@@ -0,0 +1,84 @@
+/*
+ * hack-coff.c - hack the header of an xcoff file to fill in
+ * a few fields needed by the Open Firmware xcoff loader on
+ * Power Macs but not initialized by objcopy.
+ *
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include "rs6000.h"
+
+#define AOUT_MAGIC 0x010b
+
+#define get_16be(x) ((((unsigned char *)(x))[0] << 8) \
+ + ((unsigned char *)(x))[1])
+#define put_16be(x, v) (((unsigned char *)(x))[0] = (v) >> 8, \
+ ((unsigned char *)(x))[1] = (v) & 0xff)
+#define get_32be(x) ((((unsigned char *)(x))[0] << 24) \
+ + (((unsigned char *)(x))[1] << 16) \
+ + (((unsigned char *)(x))[2] << 8) \
+ + ((unsigned char *)(x))[3])
+
+int
+main(int ac, char **av)
+{
+ int fd;
+ int i, nsect;
+ int aoutsz;
+ struct external_filehdr fhdr;
+ AOUTHDR aout;
+ struct external_scnhdr shdr;
+
+ if (ac != 2) {
+ fprintf(stderr, "Usage: hack-coff coff-file\n");
+ exit(1);
+ }
+ if ((fd = open(av[1], 2)) == -1) {
+ perror(av[2]);
+ exit(1);
+ }
+ if (read(fd, &fhdr, sizeof(fhdr)) != sizeof(fhdr))
+ goto readerr;
+ i = get_16be(fhdr.f_magic);
+ if (i != U802TOCMAGIC && i != U802WRMAGIC && i != U802ROMAGIC) {
+ fprintf(stderr, "%s: not an xcoff file\n", av[1]);
+ exit(1);
+ }
+ aoutsz = get_16be(fhdr.f_opthdr);
+ if (read(fd, &aout, aoutsz) != aoutsz)
+ goto readerr;
+ nsect = get_16be(fhdr.f_nscns);
+ for (i = 0; i < nsect; ++i) {
+ if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr))
+ goto readerr;
+ if (strcmp(shdr.s_name, ".text") == 0) {
+ put_16be(aout.o_snentry, i+1);
+ put_16be(aout.o_sntext, i+1);
+ } else if (strcmp(shdr.s_name, ".data") == 0) {
+ put_16be(aout.o_sndata, i+1);
+ } else if (strcmp(shdr.s_name, ".bss") == 0) {
+ put_16be(aout.o_snbss, i+1);
+ }
+ }
+ put_16be(aout.magic, AOUT_MAGIC);
+ if (lseek(fd, (long) sizeof(struct external_filehdr), 0) == -1
+ || write(fd, &aout, aoutsz) != aoutsz) {
+ fprintf(stderr, "%s: write error\n", av[1]);
+ exit(1);
+ }
+ close(fd);
+ exit(0);
+
+readerr:
+ fprintf(stderr, "%s: read error or file too short\n", av[1]);
+ exit(1);
+}
diff -urN powerpc-merge/arch/powerpc/boot/main.c merge-hack/arch/powerpc/boot/main.c
--- powerpc-merge/arch/powerpc/boot/main.c 2005-11-16 13:52:19.000000000 +1100
+++ merge-hack/arch/powerpc/boot/main.c 2005-11-17 14:41:13.000000000 +1100
@@ -21,8 +21,8 @@
/* Value picked to match that used by yaboot */
-#define PROG_START 0x01400000
-#define RAM_END (512<<20) // Fixme: use OF */
+#define PROG_START 0x01400000 /* only used on 64-bit systems */
+#define RAM_END (512<<20) /* Fixme: use OF */
#define ONE_MB 0x100000
extern char _start[];
@@ -160,6 +160,17 @@
elfoffset = (unsigned long)elf64ph->p_offset;
vmlinux.size = (unsigned long)elf64ph->p_filesz + elfoffset;
vmlinux.memsize = (unsigned long)elf64ph->p_memsz + elfoffset;
+
+#if defined(PROG_START)
+ /*
+ * Maintain a "magic" minimum address. This keeps some older
+ * firmware platforms running.
+ */
+
+ if (claim_base < PROG_START)
+ claim_base = PROG_START;
+#endif
+
return 1;
}
@@ -206,12 +217,18 @@
exit();
if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
exit();
- stderr = stdout;
- if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
- exit();
printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp);
+ /*
+ * The first available claim_base must be above the end of the
+ * the loaded kernel wrapper file (_start to _end includes the
+ * initrd image if it is present) and rounded up to a nice
+ * 1 MB boundary for good measure.
+ */
+
+ claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
+
vmlinuz.addr = (unsigned long)_vmlinux_start;
vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
@@ -228,25 +245,6 @@
exit();
}
- /*
- * The first available claim_base must be above the end of the
- * the loaded kernel wrapper file (_start to _end includes the
- * initrd image if it is present) and rounded up to a nice
- * 1 MB boundary for good measure.
- */
-
- claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
-
-#if defined(PROG_START)
- /*
- * Maintain a "magic" minimum address. This keeps some older
- * firmware platforms running.
- */
-
- if (claim_base < PROG_START)
- claim_base = PROG_START;
-#endif
-
/* We need to claim the memsize plus the file offset since gzip
* will expand the header (file offset), then the kernel, then
* possible rubbish we don't care about. But the kernel bss must
diff -urN powerpc-merge/arch/powerpc/boot/prom.c merge-hack/arch/powerpc/boot/prom.c
--- powerpc-merge/arch/powerpc/boot/prom.c 2005-11-16 13:52:19.000000000 +1100
+++ merge-hack/arch/powerpc/boot/prom.c 2005-11-17 14:37:12.000000000 +1100
@@ -13,487 +13,153 @@
#include "prom.h"
int (*prom)(void *);
+phandle chosen_handle;
+ihandle stdout;
-void *chosen_handle;
-
-void *stdin;
-void *stdout;
-void *stderr;
-
-
-int
-write(void *handle, void *ptr, int nb)
-{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- void *ihandle;
- void *addr;
- int len;
- int actual;
- } args;
-
- args.service = "write";
- args.nargs = 3;
- args.nret = 1;
- args.ihandle = handle;
- args.addr = ptr;
- args.len = nb;
- args.actual = -1;
- (*prom)(&args);
- return args.actual;
-}
-
-int
-read(void *handle, void *ptr, int nb)
+int call_prom(const char *service, int nargs, int nret, ...)
{
+ int i;
struct prom_args {
- char *service;
+ const char *service;
int nargs;
int nret;
- void *ihandle;
- void *addr;
- int len;
- int actual;
+ unsigned int args[12];
} args;
+ va_list list;
- args.service = "read";
- args.nargs = 3;
- args.nret = 1;
- args.ihandle = handle;
- args.addr = ptr;
- args.len = nb;
- args.actual = -1;
- (*prom)(&args);
- return args.actual;
-}
+ args.service = service;
+ args.nargs = nargs;
+ args.nret = nret;
-void
-exit()
-{
- struct prom_args {
- char *service;
- } args;
+ va_start(list, nret);
+ for (i = 0; i < nargs; i++)
+ args.args[i] = va_arg(list, unsigned int);
+ va_end(list);
- for (;;) {
- args.service = "exit";
- (*prom)(&args);
- }
-}
+ for (i = 0; i < nret; i++)
+ args.args[nargs+i] = 0;
-void
-pause(void)
-{
- struct prom_args {
- char *service;
- } args;
-
- args.service = "enter";
- (*prom)(&args);
-}
-
-void *
-finddevice(const char *name)
-{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- const char *devspec;
- void *phandle;
- } args;
-
- args.service = "finddevice";
- args.nargs = 1;
- args.nret = 1;
- args.devspec = name;
- args.phandle = (void *) -1;
- (*prom)(&args);
- return args.phandle;
-}
-
-void *
-claim(unsigned long virt, unsigned long size, unsigned long align)
-{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- unsigned int virt;
- unsigned int size;
- unsigned int align;
- void *ret;
- } args;
+ if (prom(&args) < 0)
+ return -1;
- args.service = "claim";
- args.nargs = 3;
- args.nret = 1;
- args.virt = virt;
- args.size = size;
- args.align = align;
- (*prom)(&args);
- return args.ret;
+ return (nret > 0)? args.args[nargs]: 0;
}
-int
-getprop(void *phandle, const char *name, void *buf, int buflen)
+int call_prom_ret(const char *service, int nargs, int nret,
+ unsigned int *rets, ...)
{
+ int i;
struct prom_args {
- char *service;
+ const char *service;
int nargs;
int nret;
- void *phandle;
- const char *name;
- void *buf;
- int buflen;
- int size;
+ unsigned int args[12];
} args;
+ va_list list;
- args.service = "getprop";
- args.nargs = 4;
- args.nret = 1;
- args.phandle = phandle;
- args.name = name;
- args.buf = buf;
- args.buflen = buflen;
- args.size = -1;
- (*prom)(&args);
- return args.size;
-}
+ args.service = service;
+ args.nargs = nargs;
+ args.nret = nret;
-int
-putc(int c, void *f)
-{
- char ch = c;
+ va_start(list, rets);
+ for (i = 0; i < nargs; i++)
+ args.args[i] = va_arg(list, unsigned int);
+ va_end(list);
- if (c == '\n')
- putc('\r', f);
- return write(f, &ch, 1) == 1? c: -1;
-}
+ for (i = 0; i < nret; i++)
+ args.args[nargs+i] = 0;
-int
-putchar(int c)
-{
- return putc(c, stdout);
-}
+ if (prom(&args) < 0)
+ return -1;
-int
-fputs(char *str, void *f)
-{
- int n = strlen(str);
+ if (rets != (void *) 0)
+ for (i = 1; i < nret; ++i)
+ rets[i-1] = args.args[nargs+i];
- return write(f, str, n) == n? 0: -1;
+ return (nret > 0)? args.args[nargs]: 0;
}
-size_t strnlen(const char * s, size_t count)
+int write(void *handle, void *ptr, int nb)
{
- const char *sc;
-
- for (sc = s; count-- && *sc != '\0'; ++sc)
- /* nothing */;
- return sc - s;
+ return call_prom("write", 3, 1, handle, ptr, nb);
}
-extern unsigned int __div64_32(unsigned long long *dividend,
- unsigned int divisor);
-
-/* The unnecessary pointer compare is there
- * to check for type safety (n must be 64bit)
+/*
+ * Older OF's require that when claiming a specific range of addresses,
+ * we claim the physical space in the /memory node and the virtual
+ * space in the chosen mmu node, and then do a map operation to
+ * map virtual to physical.
*/
-# define do_div(n,base) ({ \
- unsigned int __base = (base); \
- unsigned int __rem; \
- (void)(((typeof((n)) *)0) == ((unsigned long long *)0)); \
- if (((n) >> 32) == 0) { \
- __rem = (unsigned int)(n) % __base; \
- (n) = (unsigned int)(n) / __base; \
- } else \
- __rem = __div64_32(&(n), __base); \
- __rem; \
- })
+static int need_map = -1;
+static ihandle chosen_mmu;
+static phandle memory;
-static int skip_atoi(const char **s)
+/* returns true if s2 is a prefix of s1 */
+static int string_match(const char *s1, const char *s2)
{
- int i, c;
-
- for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s)
- i = i*10 + c - '0';
- return i;
+ for (; *s2; ++s2)
+ if (*s1++ != *s2)
+ return 0;
+ return 1;
}
-#define ZEROPAD 1 /* pad with zero */
-#define SIGN 2 /* unsigned/signed long */
-#define PLUS 4 /* show plus */
-#define SPACE 8 /* space if plus */
-#define LEFT 16 /* left justified */
-#define SPECIAL 32 /* 0x */
-#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
-
-static char * number(char * str, unsigned long long num, int base, int size, int precision, int type)
+static int check_of_version(void)
{
- char c,sign,tmp[66];
- const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
- int i;
+ phandle oprom, chosen;
+ char version[64];
- if (type & LARGE)
- digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- if (type & LEFT)
- type &= ~ZEROPAD;
- if (base < 2 || base > 36)
+ oprom = finddevice("/openprom");
+ if (oprom == (phandle) -1)
+ return 0;
+ if (getprop(oprom, "model", version, sizeof(version)) <= 0)
return 0;
- c = (type & ZEROPAD) ? '0' : ' ';
- sign = 0;
- if (type & SIGN) {
- if ((signed long long)num < 0) {
- sign = '-';
- num = - (signed long long)num;
- size--;
- } else if (type & PLUS) {
- sign = '+';
- size--;
- } else if (type & SPACE) {
- sign = ' ';
- size--;
+ version[sizeof(version)-1] = 0;
+ printf("OF version = '%s'\r\n", version);
+ if (!string_match(version, "Open Firmware, 1.")
+ && !string_match(version, "FirmWorks,3."))
+ return 0;
+ chosen = finddevice("/chosen");
+ if (chosen == (phandle) -1) {
+ chosen = finddevice("/chosen@0");
+ if (chosen == (phandle) -1) {
+ printf("no chosen\n");
+ return 0;
}
}
- if (type & SPECIAL) {
- if (base == 16)
- size -= 2;
- else if (base == 8)
- size--;
- }
- i = 0;
- if (num == 0)
- tmp[i++]='0';
- else while (num != 0) {
- tmp[i++] = digits[do_div(num, base)];
+ if (getprop(chosen, "mmu", &chosen_mmu, sizeof(chosen_mmu)) <= 0) {
+ printf("no mmu\n");
+ return 0;
}
- if (i > precision)
- precision = i;
- size -= precision;
- if (!(type&(ZEROPAD+LEFT)))
- while(size-->0)
- *str++ = ' ';
- if (sign)
- *str++ = sign;
- if (type & SPECIAL) {
- if (base==8)
- *str++ = '0';
- else if (base==16) {
- *str++ = '0';
- *str++ = digits[33];
+ memory = (ihandle) call_prom("open", 1, 1, "/memory");
+ if (memory == (ihandle) -1) {
+ memory = (ihandle) call_prom("open", 1, 1, "/memory@0");
+ if (memory == (ihandle) -1) {
+ printf("no memory node\n");
+ return 0;
}
}
- if (!(type & LEFT))
- while (size-- > 0)
- *str++ = c;
- while (i < precision--)
- *str++ = '0';
- while (i-- > 0)
- *str++ = tmp[i];
- while (size-- > 0)
- *str++ = ' ';
- return str;
+ printf("old OF detected\r\n");
+ return 1;
}
-int vsprintf(char *buf, const char *fmt, va_list args)
+void *claim(unsigned long virt, unsigned long size, unsigned long align)
{
- int len;
- unsigned long long num;
- int i, base;
- char * str;
- const char *s;
-
- int flags; /* flags to number() */
-
- int field_width; /* width of output field */
- int precision; /* min. # of digits for integers; max
- number of chars for from string */
- int qualifier; /* 'h', 'l', or 'L' for integer fields */
- /* 'z' support added 23/7/1999 S.H. */
- /* 'z' changed to 'Z' --davidm 1/25/99 */
+ int ret;
+ unsigned int result;
+ if (need_map < 0)
+ need_map = check_of_version();
+ if (align || !need_map)
+ return (void *) call_prom("claim", 3, 1, virt, size, align);
- for (str=buf ; *fmt ; ++fmt) {
- if (*fmt != '%') {
- *str++ = *fmt;
- continue;
- }
-
- /* process flags */
- flags = 0;
- repeat:
- ++fmt; /* this also skips first '%' */
- switch (*fmt) {
- case '-': flags |= LEFT; goto repeat;
- case '+': flags |= PLUS; goto repeat;
- case ' ': flags |= SPACE; goto repeat;
- case '#': flags |= SPECIAL; goto repeat;
- case '0': flags |= ZEROPAD; goto repeat;
- }
-
- /* get field width */
- field_width = -1;
- if ('0' <= *fmt && *fmt <= '9')
- field_width = skip_atoi(&fmt);
- else if (*fmt == '*') {
- ++fmt;
- /* it's the next argument */
- field_width = va_arg(args, int);
- if (field_width < 0) {
- field_width = -field_width;
- flags |= LEFT;
- }
- }
-
- /* get the precision */
- precision = -1;
- if (*fmt == '.') {
- ++fmt;
- if ('0' <= *fmt && *fmt <= '9')
- precision = skip_atoi(&fmt);
- else if (*fmt == '*') {
- ++fmt;
- /* it's the next argument */
- precision = va_arg(args, int);
- }
- if (precision < 0)
- precision = 0;
- }
-
- /* get the conversion qualifier */
- qualifier = -1;
- if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
- qualifier = *fmt;
- ++fmt;
- }
-
- /* default base */
- base = 10;
-
- switch (*fmt) {
- case 'c':
- if (!(flags & LEFT))
- while (--field_width > 0)
- *str++ = ' ';
- *str++ = (unsigned char) va_arg(args, int);
- while (--field_width > 0)
- *str++ = ' ';
- continue;
-
- case 's':
- s = va_arg(args, char *);
- if (!s)
- s = "<NULL>";
-
- len = strnlen(s, precision);
-
- if (!(flags & LEFT))
- while (len < field_width--)
- *str++ = ' ';
- for (i = 0; i < len; ++i)
- *str++ = *s++;
- while (len < field_width--)
- *str++ = ' ';
- continue;
-
- case 'p':
- if (field_width == -1) {
- field_width = 2*sizeof(void *);
- flags |= ZEROPAD;
- }
- str = number(str,
- (unsigned long) va_arg(args, void *), 16,
- field_width, precision, flags);
- continue;
-
-
- case 'n':
- if (qualifier == 'l') {
- long * ip = va_arg(args, long *);
- *ip = (str - buf);
- } else if (qualifier == 'Z') {
- size_t * ip = va_arg(args, size_t *);
- *ip = (str - buf);
- } else {
- int * ip = va_arg(args, int *);
- *ip = (str - buf);
- }
- continue;
-
- case '%':
- *str++ = '%';
- continue;
-
- /* integer number formats - set up the flags and "break" */
- case 'o':
- base = 8;
- break;
-
- case 'X':
- flags |= LARGE;
- case 'x':
- base = 16;
- break;
-
- case 'd':
- case 'i':
- flags |= SIGN;
- case 'u':
- break;
-
- default:
- *str++ = '%';
- if (*fmt)
- *str++ = *fmt;
- else
- --fmt;
- continue;
- }
- if (qualifier == 'l') {
- num = va_arg(args, unsigned long);
- if (flags & SIGN)
- num = (signed long) num;
- } else if (qualifier == 'Z') {
- num = va_arg(args, size_t);
- } else if (qualifier == 'h') {
- num = (unsigned short) va_arg(args, int);
- if (flags & SIGN)
- num = (signed short) num;
- } else {
- num = va_arg(args, unsigned int);
- if (flags & SIGN)
- num = (signed int) num;
- }
- str = number(str, num, base, field_width, precision, flags);
- }
- *str = '\0';
- return str-buf;
-}
-
-int sprintf(char * buf, const char *fmt, ...)
-{
- va_list args;
- int i;
-
- va_start(args, fmt);
- i=vsprintf(buf,fmt,args);
- va_end(args);
- return i;
-}
-
-static char sprint_buf[1024];
-
-int
-printf(const char *fmt, ...)
-{
- va_list args;
- int n;
-
- va_start(args, fmt);
- n = vsprintf(sprint_buf, fmt, args);
- va_end(args);
- write(stdout, sprint_buf, n);
- return n;
+ ret = call_prom_ret("call-method", 5, 2, &result, "claim", memory,
+ align, size, virt);
+ if (ret != 0 || result == -1)
+ return (void *) -1;
+ ret = call_prom_ret("call-method", 5, 2, &result, "claim", chosen_mmu,
+ align, size, virt);
+ /* 0x12 == coherent + read/write */
+ ret = call_prom("call-method", 6, 1, "map", chosen_mmu,
+ 0x12, size, virt, virt);
+ return (void *) virt;
}
diff -urN powerpc-merge/arch/powerpc/boot/prom.h merge-hack/arch/powerpc/boot/prom.h
--- powerpc-merge/arch/powerpc/boot/prom.h 2005-11-16 13:52:19.000000000 +1100
+++ merge-hack/arch/powerpc/boot/prom.h 2005-11-17 11:11:47.000000000 +1100
@@ -1,18 +1,34 @@
#ifndef _PPC_BOOT_PROM_H_
#define _PPC_BOOT_PROM_H_
+typedef void *phandle;
+typedef void *ihandle;
+
extern int (*prom) (void *);
-extern void *chosen_handle;
+extern phandle chosen_handle;
+extern ihandle stdout;
-extern void *stdin;
-extern void *stdout;
-extern void *stderr;
+int call_prom(const char *service, int nargs, int nret, ...);
+int call_prom_ret(const char *service, int nargs, int nret,
+ unsigned int *rets, ...);
extern int write(void *handle, void *ptr, int nb);
-extern int read(void *handle, void *ptr, int nb);
-extern void exit(void);
-extern void pause(void);
-extern void *finddevice(const char *);
-extern void *claim(unsigned long virt, unsigned long size, unsigned long align);
-extern int getprop(void *phandle, const char *name, void *buf, int buflen);
+extern void *claim(unsigned long virt, unsigned long size, unsigned long aln);
+
+static inline void exit(void)
+{
+ call_prom("exit", 0, 0);
+}
+
+static inline phandle finddevice(const char *name)
+{
+ return (phandle) call_prom("finddevice", 1, 1, name);
+}
+
+static inline int getprop(void *phandle, const char *name,
+ void *buf, int buflen)
+{
+ return call_prom("getprop", 4, 1, phandle, name, buf, buflen);
+}
+
#endif /* _PPC_BOOT_PROM_H_ */
diff -urN powerpc-merge/arch/powerpc/boot/rs6000.h merge-hack/arch/powerpc/boot/rs6000.h
--- /dev/null 2005-04-02 20:23:56.000000000 +1000
+++ merge-hack/arch/powerpc/boot/rs6000.h 2005-11-17 14:57:47.000000000 +1100
@@ -0,0 +1,243 @@
+/* IBM RS/6000 "XCOFF" file definitions for BFD.
+ Copyright (C) 1990, 1991 Free Software Foundation, Inc.
+ FIXME: Can someone provide a transliteration of this name into ASCII?
+ Using the following chars caused a compiler warning on HIUX (so I replaced
+ them with octal escapes), and isn't useful without an understanding of what
+ character set it is.
+ Written by Mimi Ph\373\364ng-Th\345o V\365 of IBM
+ and John Gilmore of Cygnus Support. */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+ char f_magic[2]; /* magic number */
+ char f_nscns[2]; /* number of sections */
+ char f_timdat[4]; /* time & date stamp */
+ char f_symptr[4]; /* file pointer to symtab */
+ char f_nsyms[4]; /* number of symtab entries */
+ char f_opthdr[2]; /* sizeof(optional hdr) */
+ char f_flags[2]; /* flags */
+};
+
+ /* IBM RS/6000 */
+#define U802WRMAGIC 0730 /* writeable text segments **chh** */
+#define U802ROMAGIC 0735 /* readonly sharable text segments */
+#define U802TOCMAGIC 0737 /* readonly text segments and TOC */
+
+#define BADMAG(x) \
+ ((x).f_magic != U802ROMAGIC && (x).f_magic != U802WRMAGIC && \
+ (x).f_magic != U802TOCMAGIC)
+
+#define FILHDR struct external_filehdr
+#define FILHSZ 20
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct
+{
+ unsigned char magic[2]; /* type of file */
+ unsigned char vstamp[2]; /* version stamp */
+ unsigned char tsize[4]; /* text size in bytes, padded to FW bdry */
+ unsigned char dsize[4]; /* initialized data " " */
+ unsigned char bsize[4]; /* uninitialized data " " */
+ unsigned char entry[4]; /* entry pt. */
+ unsigned char text_start[4]; /* base of text used for this file */
+ unsigned char data_start[4]; /* base of data used for this file */
+ unsigned char o_toc[4]; /* address of TOC */
+ unsigned char o_snentry[2]; /* section number of entry point */
+ unsigned char o_sntext[2]; /* section number of .text section */
+ unsigned char o_sndata[2]; /* section number of .data section */
+ unsigned char o_sntoc[2]; /* section number of TOC */
+ unsigned char o_snloader[2]; /* section number of .loader section */
+ unsigned char o_snbss[2]; /* section number of .bss section */
+ unsigned char o_algntext[2]; /* .text alignment */
+ unsigned char o_algndata[2]; /* .data alignment */
+ unsigned char o_modtype[2]; /* module type (??) */
+ unsigned char o_cputype[2]; /* cpu type */
+ unsigned char o_maxstack[4]; /* max stack size (??) */
+ unsigned char o_maxdata[4]; /* max data size (??) */
+ unsigned char o_resv2[12]; /* reserved */
+}
+AOUTHDR;
+
+#define AOUTSZ 72
+#define SMALL_AOUTSZ (28)
+#define AOUTHDRSZ 72
+
+#define RS6K_AOUTHDR_OMAGIC 0x0107 /* old: text & data writeable */
+#define RS6K_AOUTHDR_NMAGIC 0x0108 /* new: text r/o, data r/w */
+#define RS6K_AOUTHDR_ZMAGIC 0x010B /* paged: text r/o, both page-aligned */
+
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+ char s_name[8]; /* section name */
+ char s_paddr[4]; /* physical address, aliased s_nlib */
+ char s_vaddr[4]; /* virtual address */
+ char s_size[4]; /* section size */
+ char s_scnptr[4]; /* file ptr to raw data for section */
+ char s_relptr[4]; /* file ptr to relocation */
+ char s_lnnoptr[4]; /* file ptr to line numbers */
+ char s_nreloc[2]; /* number of relocation entries */
+ char s_nlnno[2]; /* number of line number entries*/
+ char s_flags[4]; /* flags */
+};
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT ".text"
+#define _DATA ".data"
+#define _BSS ".bss"
+#define _PAD ".pad"
+#define _LOADER ".loader"
+
+#define SCNHDR struct external_scnhdr
+#define SCNHSZ 40
+
+/* XCOFF uses a special .loader section with type STYP_LOADER. */
+#define STYP_LOADER 0x1000
+
+/* XCOFF uses a special .debug section with type STYP_DEBUG. */
+#define STYP_DEBUG 0x2000
+
+/* XCOFF handles line number or relocation overflow by creating
+ another section header with STYP_OVRFLO set. */
+#define STYP_OVRFLO 0x8000
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+ union {
+ char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/
+ char l_paddr[4]; /* (physical) address of line number */
+ } l_addr;
+ char l_lnno[2]; /* line number */
+};
+
+
+#define LINENO struct external_lineno
+#define LINESZ 6
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN 8 /* # characters in a symbol name */
+#define E_FILNMLEN 14 /* # characters in a file name */
+#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+ union {
+ char e_name[E_SYMNMLEN];
+ struct {
+ char e_zeroes[4];
+ char e_offset[4];
+ } e;
+ } e;
+ char e_value[4];
+ char e_scnum[2];
+ char e_type[2];
+ char e_sclass[1];
+ char e_numaux[1];
+};
+
+
+
+#define N_BTMASK (017)
+#define N_TMASK (060)
+#define N_BTSHFT (4)
+#define N_TSHIFT (2)
+
+
+union external_auxent {
+ struct {
+ char x_tagndx[4]; /* str, un, or enum tag indx */
+ union {
+ struct {
+ char x_lnno[2]; /* declaration line number */
+ char x_size[2]; /* str/union/array size */
+ } x_lnsz;
+ char x_fsize[4]; /* size of function */
+ } x_misc;
+ union {
+ struct { /* if ISFCN, tag, or .bb */
+ char x_lnnoptr[4]; /* ptr to fcn line # */
+ char x_endndx[4]; /* entry ndx past block end */
+ } x_fcn;
+ struct { /* if ISARY, up to 4 dimen. */
+ char x_dimen[E_DIMNUM][2];
+ } x_ary;
+ } x_fcnary;
+ char x_tvndx[2]; /* tv index */
+ } x_sym;
+
+ union {
+ char x_fname[E_FILNMLEN];
+ struct {
+ char x_zeroes[4];
+ char x_offset[4];
+ } x_n;
+ } x_file;
+
+ struct {
+ char x_scnlen[4]; /* section length */
+ char x_nreloc[2]; /* # relocation entries */
+ char x_nlinno[2]; /* # line numbers */
+ } x_scn;
+
+ struct {
+ char x_tvfill[4]; /* tv fill value */
+ char x_tvlen[2]; /* length of .tv */
+ char x_tvran[2][2]; /* tv range */
+ } x_tv; /* info about .tv section (in auxent of symbol .tv)) */
+
+ struct {
+ unsigned char x_scnlen[4];
+ unsigned char x_parmhash[4];
+ unsigned char x_snhash[2];
+ unsigned char x_smtyp[1];
+ unsigned char x_smclas[1];
+ unsigned char x_stab[4];
+ unsigned char x_snstab[2];
+ } x_csect;
+
+};
+
+#define SYMENT struct external_syment
+#define SYMESZ 18
+#define AUXENT union external_auxent
+#define AUXESZ 18
+#define DBXMASK 0x80 /* for dbx storage mask */
+#define SYMNAME_IN_DEBUG(symptr) ((symptr)->n_sclass & DBXMASK)
+
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+
+struct external_reloc {
+ char r_vaddr[4];
+ char r_symndx[4];
+ char r_size[1];
+ char r_type[1];
+};
+
+
+#define RELOC struct external_reloc
+#define RELSZ 10
+
+#define DEFAULT_DATA_SECTION_ALIGNMENT 4
+#define DEFAULT_BSS_SECTION_ALIGNMENT 4
+#define DEFAULT_TEXT_SECTION_ALIGNMENT 4
+/* For new sections we havn't heard of before */
+#define DEFAULT_SECTION_ALIGNMENT 4
diff -urN powerpc-merge/arch/powerpc/boot/stdio.c merge-hack/arch/powerpc/boot/stdio.c
--- /dev/null 2005-04-02 20:23:56.000000000 +1000
+++ merge-hack/arch/powerpc/boot/stdio.c 2005-11-17 14:36:52.000000000 +1100
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <stdarg.h>
+#include <stddef.h>
+#include "string.h"
+#include "stdio.h"
+#include "prom.h"
+
+size_t strnlen(const char * s, size_t count)
+{
+ const char *sc;
+
+ for (sc = s; count-- && *sc != '\0'; ++sc)
+ /* nothing */;
+ return sc - s;
+}
+
+extern unsigned int __div64_32(unsigned long long *dividend,
+ unsigned int divisor);
+
+/* The unnecessary pointer compare is there
+ * to check for type safety (n must be 64bit)
+ */
+# define do_div(n,base) ({ \
+ unsigned int __base = (base); \
+ unsigned int __rem; \
+ (void)(((typeof((n)) *)0) == ((unsigned long long *)0)); \
+ if (((n) >> 32) == 0) { \
+ __rem = (unsigned int)(n) % __base; \
+ (n) = (unsigned int)(n) / __base; \
+ } else \
+ __rem = __div64_32(&(n), __base); \
+ __rem; \
+ })
+
+static int skip_atoi(const char **s)
+{
+ int i, c;
+
+ for (i = 0; '0' <= (c = **s) && c <= '9'; ++*s)
+ i = i*10 + c - '0';
+ return i;
+}
+
+#define ZEROPAD 1 /* pad with zero */
+#define SIGN 2 /* unsigned/signed long */
+#define PLUS 4 /* show plus */
+#define SPACE 8 /* space if plus */
+#define LEFT 16 /* left justified */
+#define SPECIAL 32 /* 0x */
+#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
+
+static char * number(char * str, unsigned long long num, int base, int size, int precision, int type)
+{
+ char c,sign,tmp[66];
+ const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
+ int i;
+
+ if (type & LARGE)
+ digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ if (type & LEFT)
+ type &= ~ZEROPAD;
+ if (base < 2 || base > 36)
+ return 0;
+ c = (type & ZEROPAD) ? '0' : ' ';
+ sign = 0;
+ if (type & SIGN) {
+ if ((signed long long)num < 0) {
+ sign = '-';
+ num = - (signed long long)num;
+ size--;
+ } else if (type & PLUS) {
+ sign = '+';
+ size--;
+ } else if (type & SPACE) {
+ sign = ' ';
+ size--;
+ }
+ }
+ if (type & SPECIAL) {
+ if (base == 16)
+ size -= 2;
+ else if (base == 8)
+ size--;
+ }
+ i = 0;
+ if (num == 0)
+ tmp[i++]='0';
+ else while (num != 0) {
+ tmp[i++] = digits[do_div(num, base)];
+ }
+ if (i > precision)
+ precision = i;
+ size -= precision;
+ if (!(type&(ZEROPAD+LEFT)))
+ while(size-->0)
+ *str++ = ' ';
+ if (sign)
+ *str++ = sign;
+ if (type & SPECIAL) {
+ if (base==8)
+ *str++ = '0';
+ else if (base==16) {
+ *str++ = '0';
+ *str++ = digits[33];
+ }
+ }
+ if (!(type & LEFT))
+ while (size-- > 0)
+ *str++ = c;
+ while (i < precision--)
+ *str++ = '0';
+ while (i-- > 0)
+ *str++ = tmp[i];
+ while (size-- > 0)
+ *str++ = ' ';
+ return str;
+}
+
+int vsprintf(char *buf, const char *fmt, va_list args)
+{
+ int len;
+ unsigned long long num;
+ int i, base;
+ char * str;
+ const char *s;
+
+ int flags; /* flags to number() */
+
+ int field_width; /* width of output field */
+ int precision; /* min. # of digits for integers; max
+ number of chars for from string */
+ int qualifier; /* 'h', 'l', or 'L' for integer fields */
+ /* 'z' support added 23/7/1999 S.H. */
+ /* 'z' changed to 'Z' --davidm 1/25/99 */
+
+
+ for (str=buf ; *fmt ; ++fmt) {
+ if (*fmt != '%') {
+ *str++ = *fmt;
+ continue;
+ }
+
+ /* process flags */
+ flags = 0;
+ repeat:
+ ++fmt; /* this also skips first '%' */
+ switch (*fmt) {
+ case '-': flags |= LEFT; goto repeat;
+ case '+': flags |= PLUS; goto repeat;
+ case ' ': flags |= SPACE; goto repeat;
+ case '#': flags |= SPECIAL; goto repeat;
+ case '0': flags |= ZEROPAD; goto repeat;
+ }
+
+ /* get field width */
+ field_width = -1;
+ if ('0' <= *fmt && *fmt <= '9')
+ field_width = skip_atoi(&fmt);
+ else if (*fmt == '*') {
+ ++fmt;
+ /* it's the next argument */
+ field_width = va_arg(args, int);
+ if (field_width < 0) {
+ field_width = -field_width;
+ flags |= LEFT;
+ }
+ }
+
+ /* get the precision */
+ precision = -1;
+ if (*fmt == '.') {
+ ++fmt;
+ if ('0' <= *fmt && *fmt <= '9')
+ precision = skip_atoi(&fmt);
+ else if (*fmt == '*') {
+ ++fmt;
+ /* it's the next argument */
+ precision = va_arg(args, int);
+ }
+ if (precision < 0)
+ precision = 0;
+ }
+
+ /* get the conversion qualifier */
+ qualifier = -1;
+ if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
+ qualifier = *fmt;
+ ++fmt;
+ }
+
+ /* default base */
+ base = 10;
+
+ switch (*fmt) {
+ case 'c':
+ if (!(flags & LEFT))
+ while (--field_width > 0)
+ *str++ = ' ';
+ *str++ = (unsigned char) va_arg(args, int);
+ while (--field_width > 0)
+ *str++ = ' ';
+ continue;
+
+ case 's':
+ s = va_arg(args, char *);
+ if (!s)
+ s = "<NULL>";
+
+ len = strnlen(s, precision);
+
+ if (!(flags & LEFT))
+ while (len < field_width--)
+ *str++ = ' ';
+ for (i = 0; i < len; ++i)
+ *str++ = *s++;
+ while (len < field_width--)
+ *str++ = ' ';
+ continue;
+
+ case 'p':
+ if (field_width == -1) {
+ field_width = 2*sizeof(void *);
+ flags |= ZEROPAD;
+ }
+ str = number(str,
+ (unsigned long) va_arg(args, void *), 16,
+ field_width, precision, flags);
+ continue;
+
+
+ case 'n':
+ if (qualifier == 'l') {
+ long * ip = va_arg(args, long *);
+ *ip = (str - buf);
+ } else if (qualifier == 'Z') {
+ size_t * ip = va_arg(args, size_t *);
+ *ip = (str - buf);
+ } else {
+ int * ip = va_arg(args, int *);
+ *ip = (str - buf);
+ }
+ continue;
+
+ case '%':
+ *str++ = '%';
+ continue;
+
+ /* integer number formats - set up the flags and "break" */
+ case 'o':
+ base = 8;
+ break;
+
+ case 'X':
+ flags |= LARGE;
+ case 'x':
+ base = 16;
+ break;
+
+ case 'd':
+ case 'i':
+ flags |= SIGN;
+ case 'u':
+ break;
+
+ default:
+ *str++ = '%';
+ if (*fmt)
+ *str++ = *fmt;
+ else
+ --fmt;
+ continue;
+ }
+ if (qualifier == 'l') {
+ num = va_arg(args, unsigned long);
+ if (flags & SIGN)
+ num = (signed long) num;
+ } else if (qualifier == 'Z') {
+ num = va_arg(args, size_t);
+ } else if (qualifier == 'h') {
+ num = (unsigned short) va_arg(args, int);
+ if (flags & SIGN)
+ num = (signed short) num;
+ } else {
+ num = va_arg(args, unsigned int);
+ if (flags & SIGN)
+ num = (signed int) num;
+ }
+ str = number(str, num, base, field_width, precision, flags);
+ }
+ *str = '\0';
+ return str-buf;
+}
+
+int sprintf(char * buf, const char *fmt, ...)
+{
+ va_list args;
+ int i;
+
+ va_start(args, fmt);
+ i=vsprintf(buf,fmt,args);
+ va_end(args);
+ return i;
+}
+
+static char sprint_buf[1024];
+
+int
+printf(const char *fmt, ...)
+{
+ va_list args;
+ int n;
+
+ va_start(args, fmt);
+ n = vsprintf(sprint_buf, fmt, args);
+ va_end(args);
+ write(stdout, sprint_buf, n);
+ return n;
+}
diff -urN powerpc-merge/arch/powerpc/boot/stdio.h merge-hack/arch/powerpc/boot/stdio.h
--- powerpc-merge/arch/powerpc/boot/stdio.h 2005-11-16 13:52:19.000000000 +1100
+++ merge-hack/arch/powerpc/boot/stdio.h 2005-11-17 11:07:34.000000000 +1100
@@ -7,10 +7,4 @@
extern int vsprintf(char *buf, const char *fmt, va_list args);
-extern int putc(int c, void *f);
-extern int putchar(int c);
-extern int getchar(void);
-
-extern int fputs(char *str, void *f);
-
#endif /* _PPC_BOOT_STDIO_H_ */
diff -urN powerpc-merge/arch/powerpc/boot/zImage.lds merge-hack/arch/powerpc/boot/zImage.lds
--- powerpc-merge/arch/powerpc/boot/zImage.lds 2005-11-16 13:52:19.000000000 +1100
+++ merge-hack/arch/powerpc/boot/zImage.lds 2005-11-16 23:16:48.000000000 +1100
@@ -2,7 +2,7 @@
ENTRY(_zimage_start)
SECTIONS
{
- . = (4*1024*1024);
+ . = (5*1024*1024);
_start = .;
.text :
{
@@ -19,22 +19,18 @@
__got2_start = .;
*(.got2)
__got2_end = .;
- }
- . = ALIGN(4096);
- _vmlinux_start = .;
- .kernel:vmlinux.strip : { *(.kernel:vmlinux.strip) }
- _vmlinux_end = .;
+ _vmlinux_start = .;
+ *(.kernel:vmlinux.strip)
+ _vmlinux_end = .;
- . = ALIGN(4096);
- _initrd_start = .;
- .kernel:initrd : { *(.kernel:initrd) }
- _initrd_end = .;
+ _initrd_start = .;
+ *(.kernel:initrd)
+ _initrd_end = .;
+ }
. = ALIGN(4096);
_edata = .;
-
- . = ALIGN(4096);
__bss_start = .;
.bss :
{
^ permalink raw reply
* [PATCH] powerpc: Fix setting MPIC priority
From: Benjamin Herrenschmidt @ 2005-11-18 6:18 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev list
Trying to set the priority would just disable the interrupt due to an
incorrect mask used. We rarely use that call, in fact, I think only in
the powermac code for the cmd-power key combo that triggers xmon. So it
got unnoticed for a while.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Index: linux-work/arch/powerpc/sysdev/mpic.c
===================================================================
--- linux-work.orig/arch/powerpc/sysdev/mpic.c 2005-11-17 17:06:04.000000000 +1100
+++ linux-work/arch/powerpc/sysdev/mpic.c 2005-11-17 17:07:40.000000000 +1100
@@ -361,7 +361,8 @@
DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
- mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & ~MPIC_VECPRI_MASK);
+ mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
+ ~MPIC_VECPRI_MASK);
/* make sure mask gets to controller before we return to user */
do {
@@ -381,7 +382,8 @@
DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
- mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) | MPIC_VECPRI_MASK);
+ mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
+ MPIC_VECPRI_MASK);
/* make sure mask gets to controller before we return to user */
do {
@@ -735,12 +737,13 @@
spin_lock_irqsave(&mpic_lock, flags);
if (is_ipi) {
- reg = mpic_ipi_read(irq - mpic->ipi_offset) & MPIC_VECPRI_PRIORITY_MASK;
+ reg = mpic_ipi_read(irq - mpic->ipi_offset) &
+ ~MPIC_VECPRI_PRIORITY_MASK;
mpic_ipi_write(irq - mpic->ipi_offset,
reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
} else {
- reg = mpic_irq_read(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI)
- & MPIC_VECPRI_PRIORITY_MASK;
+ reg = mpic_irq_read(irq - mpic->irq_offset,MPIC_IRQ_VECTOR_PRI)
+ & ~MPIC_VECPRI_PRIORITY_MASK;
mpic_irq_write(irq - mpic->irq_offset, MPIC_IRQ_VECTOR_PRI,
reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
}
^ permalink raw reply
* Insmod mod.ko: ERROR: Module mod does not exist in /proc/modules
From: KS Soumya-ask067 @ 2005-11-18 7:06 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 1170 bytes --]
Hi,
I am using Linux 2.6.10 for an MPC8540 board.
"insmod" seemed to have a problem which said
[insmod: QM_MODULES: Function not implemented] .
After googling, I downloaded the module-init-tools 3.1, cross compiled
it with 85xx tool chain, installed it on the target filesystem.
Now after doing that, I get an error,
ERROR: Module mod does not exist in /proc/modules
I have enabled the Module loading/unloading option in the kernel. Am I
missing out on anything else?
Can anyone please help me with a lead. A snapshot of the error is
attached.
Thanks a lot,
Soumya
10 login: root
Last login: Wed Dec 31 19:00:49 on console
bash-2.05b#
bash-2.05b#
bash-2.05b# insmod mod.ko
ERROR: Module mod does not exist in /proc/modules
bash-2.05b#
bash-2.05b#
bash-2.05b# insmod -f mod.ko
ERROR: Removing 'mod': No such file or directory
bash-2.05b#
bash-2.05b#
bash-2.05b# modprobe mod.ko
ERROR: Module mod does not exist in /proc/modules
bash-2.05b#
bash-2.05b# lsmod mod
ERROR: Module mod does not exist in /proc/modules
bash-2.05b#
bash-2.05b#
bash-2.05b# insmod -V
module-init-tools version 3.1
bash-2.05b#
[-- Attachment #2: Type: text/html, Size: 3305 bytes --]
^ permalink raw reply
* Re: [PATCH] ppc boot: replace string labels with numbers
From: Olaf Hering @ 2005-11-18 7:42 UTC (permalink / raw)
To: Jerry Van Baren; +Cc: linuxppc-dev
In-Reply-To: <437D0A21.4090803@smiths-aerospace.com>
On Thu, Nov 17, Jerry Van Baren wrote:
> While I'm being dumb, I gotta ask, how big is zImage and why does 117
> bytes make a difference?
Because we can.
> My 2c: if you are going to use inscrutable labels (1,2,3,4), please put
> comments in. At least the previous labels gave hints as to what was
> happening.
The code should be obvious.
--
short story of a lazy sysadmin:
alias appserv=wotan
^ permalink raw reply
* Re: [PATCH] generate COFF zImage in arch/powerpc/boot
From: Olaf Hering @ 2005-11-18 7:51 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <17277.28534.614112.962810@cargo.ozlabs.ibm.com>
On Fri, Nov 18, Paul Mackeras wrote:
> +++ merge-hack/arch/powerpc/boot/zImage.lds 2005-11-16 23:16:48.000000000 +1100
This change makes arch/powerpc/boot/README obsolete.
Last time I looked, the COFF loader liked only .text, .data and .bss.
But maybe hack-coff needs some tweaking to modify also other sections.
I was about to do the same changes. There are some comments about the
COFF layout, and PReP, in arch/powerpc/kernel/head_32.S. Some of it can
go.
--
short story of a lazy sysadmin:
alias appserv=wotan
^ permalink raw reply
* Re: [PATCH] Fix 8250 probe on ppc32
From: Christoph Hellwig @ 2005-11-18 8:23 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list, David Woodhouse, Tom Rini
In-Reply-To: <1132285818.20016.79.camel@gaston>
On Fri, Nov 18, 2005 at 02:50:17PM +1100, Benjamin Herrenschmidt wrote:
> On Thu, 2005-11-17 at 21:26 -0600, Kumar Gala wrote:
> > Paul or BenH,
> >
> > Would you like to enlighten us on this ambitious rework?
>
> First, some better & more generic routines for translating addresses
> from the device-tree, and some more generic code for looking for
> standard serial port using the above routines, among others ... also,
> set_preferred_console gets modified to use the previous list so it can
> detect the ports more reliably, etc ....
so as a start can we move the code to a place in arch/powerpc/ where
it can bee used by ppc32 _now_ because it fixes a real problem? You
can add your encehancements whenever you get time to actually do it.
^ permalink raw reply
* Re: [PATCH] Fix 8250 probe on ppc32
From: Benjamin Herrenschmidt @ 2005-11-18 10:51 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linuxppc-dev list, David Woodhouse, Tom Rini
In-Reply-To: <20051118082358.GA2309@lst.de>
On Fri, 2005-11-18 at 09:23 +0100, Christoph Hellwig wrote:
> On Fri, Nov 18, 2005 at 02:50:17PM +1100, Benjamin Herrenschmidt wrote:
> > On Thu, 2005-11-17 at 21:26 -0600, Kumar Gala wrote:
> > > Paul or BenH,
> > >
> > > Would you like to enlighten us on this ambitious rework?
> >
> > First, some better & more generic routines for translating addresses
> > from the device-tree, and some more generic code for looking for
> > standard serial port using the above routines, among others ... also,
> > set_preferred_console gets modified to use the previous list so it can
> > detect the ports more reliably, etc ....
>
> so as a start can we move the code to a place in arch/powerpc/ where
> it can bee used by ppc32 _now_ because it fixes a real problem? You
> can add your encehancements whenever you get time to actually do it.
My patch makes it ppc32 too :) udbg gets build on ppc32 along with early
console etc... all with the same code path as ppc64. I still need to
test it on more hw and fix a few problems and hopefully will post it
before the week-end is over.
Ben
^ permalink raw reply
* Porting Linux 2.4 on MPC8266
From: Manisha Jagadhane @ 2005-11-18 11:46 UTC (permalink / raw)
To: Linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 327 bytes --]
Hi all,
we have a MPC8266 custom board . At present we ported u-boot(1.1.1) on the
board and its working properly.
Now we want to port linux on that board. we have PowerTap Pro Emulator and
CodeWarrior (IDE) from Metroworks, can we use this for porting & debugging
Linux on the custom board?
thanking u all
Manisha.
[-- Attachment #2: Type: text/html, Size: 430 bytes --]
^ permalink raw reply
* Re: [PATCH] ppc32: 8xx board-specific platform stuff for fs_enet
From: Vitaly Bordug @ 2005-11-18 14:09 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: linuxppc-embedded list
In-Reply-To: <20051117135810.GB9753@logos.cnet>
Marcelo,
Thanks for review, will fix.
Guess the proper place for setbits/clrbits should be asm-ppc/io.h?
--
Sincerely,
Vitaly
^ permalink raw reply
* Re: [PATCH] ppc32: 8xx board-specific platform stuff for fs_enet
From: Vitaly Bordug @ 2005-11-18 14:11 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: linuxppc-embedded list
In-Reply-To: <20051117140715.GC9753@logos.cnet>
Marcelo Tosatti wrote:
> On Wed, Nov 16, 2005 at 03:04:33PM +0300, Vitaly Bordug wrote:
>> This adds board-specific files needed to utilize fs_enet Ethernet driver
>> for MPC885ADS and MPC866ADS.
>>
>> Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
>>
>
> Vitaly,
>
> It also sounds to me that mpc885_nonplatform_device_init()
> initialization suits board_init() time, instead of post-start_kernel()
> do_initcalls(). No?
>
>
>
Well, maybe, but it actually works and since this approach prevents messing up the
m8xx_setup.c with #ifdef hell, I prefer the additional initialization to be there.
If this is odd, I'll proceed with the right way of course.
--
Sincerely,
Vitaly
^ permalink raw reply
* Re: [PATCH] ppc32: 8xx board-specific platform stuff for fs_enet
From: Marcelo Tosatti @ 2005-11-18 9:05 UTC (permalink / raw)
To: Vitaly Bordug; +Cc: linuxppc-embedded list
In-Reply-To: <437DE127.50507@ru.mvista.com>
On Fri, Nov 18, 2005 at 05:11:51PM +0300, Vitaly Bordug wrote:
> Marcelo Tosatti wrote:
> >On Wed, Nov 16, 2005 at 03:04:33PM +0300, Vitaly Bordug wrote:
> >>This adds board-specific files needed to utilize fs_enet Ethernet driver
> >>for MPC885ADS and MPC866ADS.
> >>
> >>Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
> >>
> >
> >Vitaly,
> >
> >It also sounds to me that mpc885_nonplatform_device_init()
> >initialization suits board_init() time, instead of post-start_kernel()
> >do_initcalls(). No?
> >
> >
> >
> Well, maybe, but it actually works and since this approach prevents messing
> up the m8xx_setup.c with #ifdef hell, I prefer the additional
> initialization to be there.
>
> If this is odd, I'll proceed with the right way of course.
No need to mess with m8xx_setup.c, just define your own board_init()
function:
+void __init
+board_init(void)
+{
+ ppc_md.time_init = cyc_rtc_init;
+ ppc_md.set_rtc_time = cyc_set_rtc_time;
+ ppc_md.get_rtc_time = cyc_get_rtc_time;
+ ppc_md.restart = cyc_8xx_restart;
+}
^ permalink raw reply
* Re: [PATCH] ppc32: 8xx board-specific platform stuff for fs_enet
From: Marcelo Tosatti @ 2005-11-18 9:08 UTC (permalink / raw)
To: Vitaly Bordug, Paul Mackerras; +Cc: linuxppc-embedded list
In-Reply-To: <437DE07E.6080005@ru.mvista.com>
On Fri, Nov 18, 2005 at 05:09:02PM +0300, Vitaly Bordug wrote:
> Marcelo,
> Thanks for review, will fix.
>
> Guess the proper place for setbits/clrbits should be asm-ppc/io.h?
Yes, think so.
Paul, you're OK with the following definitions on asm-ppc/io.h?
+/* access ports */
+#define setbits32(_addr, _v) out_be32(&(_addr), in_be32(&(_addr)) | (_v))
+#define clrbits32(_addr, _v) out_be32(&(_addr), in_be32(&(_addr)) & ~(_v))
+
+#define setbits16(_addr, _v) out_be16(&(_addr), in_be16(&(_addr)) | (_v))
+#define clrbits16(_addr, _v) out_be16(&(_addr), in_be16(&(_addr)) & ~(_v))
^ permalink raw reply
* Re: [PATCH] Fix 8250 probe on ppc32
From: Kumar Gala @ 2005-11-18 14:46 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list, David Woodhouse, Tom Rini
In-Reply-To: <1132311088.20016.88.camel@gaston>
On Nov 18, 2005, at 4:51 AM, Benjamin Herrenschmidt wrote:
> On Fri, 2005-11-18 at 09:23 +0100, Christoph Hellwig wrote:
>> On Fri, Nov 18, 2005 at 02:50:17PM +1100, Benjamin Herrenschmidt
>> wrote:
>>> On Thu, 2005-11-17 at 21:26 -0600, Kumar Gala wrote:
>>>> Paul or BenH,
>>>>
>>>> Would you like to enlighten us on this ambitious rework?
>>>
>>> First, some better & more generic routines for translating addresses
>>> from the device-tree, and some more generic code for looking for
>>> standard serial port using the above routines, among others ...
>>> also,
>>> set_preferred_console gets modified to use the previous list so
>>> it can
>>> detect the ports more reliably, etc ....
>>
>> so as a start can we move the code to a place in arch/powerpc/ where
>> it can bee used by ppc32 _now_ because it fixes a real problem? You
>> can add your encehancements whenever you get time to actually do it.
>
> My patch makes it ppc32 too :) udbg gets build on ppc32 along with
> early
> console etc... all with the same code path as ppc64. I still need to
> test it on more hw and fix a few problems and hopefully will post it
> before the week-end is over.
How early on can we use udbg? I'd be interested to see how this is
going to work out for 4xx/83xx/85xx w/built-in 8250's.
- kumar
^ permalink raw reply
* Re: [PATCH] ppc boot: replace string labels with numbers
From: Hollis Blanchard @ 2005-11-18 15:30 UTC (permalink / raw)
To: Olaf Hering; +Cc: linuxppc-dev
In-Reply-To: <20051118074237.GA14865@suse.de>
On Nov 18, 2005, at 1:42 AM, Olaf Hering wrote:
> On Thu, Nov 17, Jerry Van Baren wrote:
>
>> While I'm being dumb, I gotta ask, how big is zImage and why does 117
>> bytes make a difference?
>
> Because we can.
>
>> My 2c: if you are going to use inscrutable labels (1,2,3,4), please
>> put
>> comments in. At least the previous labels gave hints as to what was
>> happening.
>
> The code should be obvious.
I hope the above was a joke, Olaf.
I too am wondering where the savings come from. Regardless, IMHO 117
bytes is not a worthwhile tradeoff for less maintainable assembly.
BTW, Jerry, the size of the instructions themselves will not change. I
suspect the savings is from things like the symbol table, but I can't
replicate it with a simple "hello world" testcase.
-Hollis
^ permalink raw reply
* [PATCH] ppc32: 8xx board-specific platform stuff for fs_enet
From: Vitaly Bordug @ 2005-11-18 16:19 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: linuxppc-embedded list
This adds board-specific files needed to utilize fs_enet Ethernet driver
for MPC885ADS and MPC866ADS.
Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
---
arch/ppc/Kconfig | 47 ++++
arch/ppc/platforms/Makefile | 2
arch/ppc/platforms/fads.h | 2
arch/ppc/platforms/mpc866ads_setup.c | 283 ++++++++++++++++++++++++
arch/ppc/platforms/mpc885ads_setup.c | 400 ++++++++++++++++++++++++++++++++++
include/asm-ppc/io.h | 7 +
6 files changed, 740 insertions(+), 1 deletions(-)
create mode 100644 arch/ppc/platforms/mpc866ads_setup.c
create mode 100644 arch/ppc/platforms/mpc885ads_setup.c
applies-to: d2cd86c706af9e6ad47e2dda6b24df0d93f6f98f
fa40f206175e866edd27507148c61a90b665c8db
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 8fa51b0..8e6fcb2 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -506,6 +506,53 @@ config WINCEPT
endchoice
+menu "Freescale Ethernet driver platform-specific options"
+ depends on FS_ENET
+
+ config MPC8xx_SECOND_ETH
+ bool "Second Ethernet channel"
+ depends on (MPC885ADS || MPC86XADS)
+ default y
+ help
+ This enables support for second Ethernet on MPC885ADS and MPC86xADS boards.
+ The latter will use SCC1, for 885ADS you can select it below.
+
+ choice
+ prompt "Second Ethernet channel"
+ depends on MPC8xx_SECOND_ETH
+ default MPC8xx_SECOND_ETH_FEC2
+
+ config MPC8xx_SECOND_ETH_FEC2
+ bool "FEC2"
+ depends on MPC885ADS
+ help
+ Enable FEC2 to serve as 2-nd Ethernet channel. Note that SMC2
+ (often 2-nd UART) will not work if this is enabled.
+
+ config MPC8xx_SECOND_ETH_SCC1
+ bool "SCC1"
+ depends on MPC86XADS
+ select MPC8xx_SCC_ENET_FIXED
+ help
+ Enable SCC1 to serve as 2-nd Ethernet channel. Note that SMC1
+ (often 1-nd UART) will not work if this is enabled.
+
+ config MPC8xx_SECOND_ETH_SCC3
+ bool "SCC3"
+ depends on MPC885ADS
+ help
+ Enable SCC3 to serve as 2-nd Ethernet channel. Note that SMC1
+ (often 1-nd UART) will not work if this is enabled.
+
+ endchoice
+
+ config MPC8xx_SCC_ENET_FIXED
+ depends on MPC8xx_SECOND_ETH_SCC
+ default n
+ bool "Use fixed MII-less mode for SCC Ethernet"
+
+endmenu
+
choice
prompt "Machine Type"
depends on 6xx || POWER3 || POWER4
diff --git a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile
index 7c5cdab..cce6487 100644
--- a/arch/ppc/platforms/Makefile
+++ b/arch/ppc/platforms/Makefile
@@ -45,6 +45,8 @@ obj-$(CONFIG_SBC82xx) += sbc82xx.o
obj-$(CONFIG_SPRUCE) += spruce.o
obj-$(CONFIG_LITE5200) += lite5200.o
obj-$(CONFIG_EV64360) += ev64360.o
+obj-$(CONFIG_MPC86XADS) += mpc866ads_setup.o
+obj-$(CONFIG_MPC885ADS) += mpc885ads_setup.o
ifeq ($(CONFIG_SMP),y)
obj-$(CONFIG_PPC_PMAC) += pmac_smp.o
diff --git a/arch/ppc/platforms/fads.h b/arch/ppc/platforms/fads.h
index a48fb8d..e1c0b1b 100644
--- a/arch/ppc/platforms/fads.h
+++ b/arch/ppc/platforms/fads.h
@@ -112,7 +112,7 @@
/* CPM Ethernet through SCC1 or SCC2 */
-#ifdef CONFIG_SCC1_ENET /* Probably 860 variant */
+#if defined(CONFIG_SCC1_ENET) || defined(CONFIG_MPC8xx_SECOND_ETH_SCC1) /* Probably 860
variant */
/* Bits in parallel I/O port registers that have to be set/cleared
* to configure the pins for SCC1 use.
* TCLK - CLK1, RCLK - CLK2.
diff --git a/arch/ppc/platforms/mpc866ads_setup.c b/arch/ppc/platforms/mpc866ads_setup.c
new file mode 100644
index 0000000..0809cf3
--- /dev/null
+++ b/arch/ppc/platforms/mpc866ads_setup.c
@@ -0,0 +1,283 @@
+/*arch/ppc/platforms/mpc885ads-setup.c
+ *
+ * Platform setup for the Freescale mpc885ads board
+ *
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * Copyright 2005 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/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+
+#include <linux/fs_enet_pd.h>
+#include <linux/mii.h>
+
+#include <asm/delay.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/ppcboot.h>
+#include <asm/8xx_immap.h>
+#include <asm/commproc.h>
+#include <asm/ppc_sys.h>
+#include <asm/mpc8xx.h>
+
+extern unsigned char __res[];
+
+static struct fs_mii_bus_info fec_mii_bus_info = {
+ .method = fsmii_fec,
+ .id = 0,
+};
+
+static struct fs_mii_bus_info scc_mii_bus_info = {
+ .method = fsmii_fixed,
+ .id = 0,
+ .i.fixed.speed = 10,
+ .i.fixed.duplex = 0,
+};
+
+static struct fs_platform_info mpc8xx_fec_pdata[] = {
+ {
+ .rx_ring = 128,
+ .tx_ring = 16,
+ .rx_copybreak = 240,
+
+ .use_napi = 1,
+ .napi_weight = 17,
+
+ .phy_addr = 15,
+ .phy_irq = -1,
+
+ .use_rmii = 0,
+
+ .bus_info = &fec_mii_bus_info,
+ }
+};
+
+static struct fs_platform_info mpc8xx_scc_pdata = {
+ .rx_ring = 64,
+ .tx_ring = 8,
+ .rx_copybreak = 240,
+
+ .use_napi = 1,
+ .napi_weight = 17,
+
+ .phy_addr = -1,
+ .phy_irq = -1,
+
+ .bus_info = &scc_mii_bus_info,
+};
+
+void __init board_init(void)
+{
+ volatile cpm8xx_t *cp = cpmp;
+ unsigned *bcsr_io;
+
+ bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+
+ if (bcsr_io == NULL) {
+ printk(KERN_CRIT "Could not remap BCSR1\n");
+ return;
+ }
+#ifdef CONFIG_SERIAL_CPM_SMC1
+ cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */
+ clrbits32(bcsr_io,(0x80000000 >> 7));
+#else
+ setbits32(bcsr_io,(0x80000000 >> 7));
+
+ cp->cp_pbpar &= ~(0x000000c0);
+ cp->cp_pbdir |= 0x000000c0;
+ cp->cp_smc[0].smc_smcmr = 0;
+ cp->cp_smc[0].smc_smce = 0;
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SMC2
+ cp->cp_simode &= ~(0xe0000000 >> 1);
+ cp->cp_simode |= (0x20000000 >> 1); /* brg2 */
+ clrbits32(bcsr_io,(0x80000000 >> 13));
+#else
+ clrbits32(bcsr_io,(0x80000000 >> 13));
+ cp->cp_pbpar &= ~(0x00000c00);
+ cp->cp_pbdir |= 0x00000c00;
+ cp->cp_smc[1].smc_smcmr = 0;
+ cp->cp_smc[1].smc_smce = 0;
+#endif
+ iounmap(bcsr_io);
+}
+
+static void setup_fec1_ioports(void)
+{
+ immap_t *immap = (immap_t *) IMAP_ADDR;
+
+ setbits16(&immap->im_ioport.iop_pdpar, 0x1fff);
+ setbits16(&immap->im_ioport.iop_pddir, 0x1fff);
+}
+
+static void setup_scc1_ioports(void)
+{
+ immap_t *immap = (immap_t *) IMAP_ADDR;
+ unsigned *bcsr_io;
+
+ bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+
+ if (bcsr_io == NULL) {
+ printk(KERN_CRIT "Could not remap BCSR1\n");
+ return;
+ }
+
+ /* Enable the PHY.
+ */
+ clrbits32(bcsr_io,BCSR1_ETHEN);
+
+ /* Configure port A pins for Txd and Rxd.
+ */
+ /* Disable receive and transmit in case EPPC-Bug started it.
+ */
+ setbits16(&immap->im_ioport.iop_papar, PA_ENET_RXD | PA_ENET_TXD);
+ clrbits16(&immap->im_ioport.iop_padir, PA_ENET_RXD | PA_ENET_TXD);
+ clrbits16(&immap->im_ioport.iop_paodr, PA_ENET_TXD);
+
+ /* Configure port C pins to enable CLSN and RENA.
+ */
+ clrbits16(&immap->im_ioport.iop_pcpar, PC_ENET_CLSN | PC_ENET_RENA);
+ clrbits16(&immap->im_ioport.iop_pcdir, PC_ENET_CLSN | PC_ENET_RENA);
+ setbits16(&immap->im_ioport.iop_pcso, PC_ENET_CLSN | PC_ENET_RENA);
+ /* Configure port A for TCLK and RCLK.
+ */
+ setbits16(&immap->im_ioport.iop_papar, PA_ENET_TCLK | PA_ENET_RCLK);
+ clrbits16(&immap->im_ioport.iop_padir, PA_ENET_TCLK | PA_ENET_RCLK);
+ clrbits32(&immap->im_cpm.cp_pbpar, PB_ENET_TENA);
+ clrbits32(&immap->im_cpm.cp_pbdir, PB_ENET_TENA);
+
+ /* Configure Serial Interface clock routing.
+ * First, clear all SCC bits to zero, then set the ones we want.
+ */
+ clrbits32(&immap->im_cpm.cp_sicr, SICR_ENET_MASK);
+ setbits32(&immap->im_cpm.cp_sicr, SICR_ENET_CLKRT);
+
+ /* In the original SCC enet driver the following code is placed at
+ the end of the initialization */
+ setbits32(&immap->im_cpm.cp_pbpar, PB_ENET_TENA);
+ setbits32(&immap->im_cpm.cp_pbdir, PB_ENET_TENA);
+
+}
+
+static void mpc866ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no)
+{
+ struct fs_platform_info *fpi = pdev->dev.platform_data;
+
+ volatile cpm8xx_t *cp;
+ bd_t *bd = (bd_t *) __res;
+ char *e;
+ int i;
+
+ /* Get pointer to Communication Processor */
+ cp = cpmp;
+ switch (fs_no) {
+ case fsid_fec1:
+ fpi = &mpc8xx_fec_pdata[0];
+ fpi->init_ioports = &setup_fec1_ioports;
+
+ break;
+ case fsid_scc1:
+ fpi = &mpc8xx_scc_pdata;
+ fpi->init_ioports = &setup_scc1_ioports;
+
+ break;
+ default:
+ break;
+ }
+
+ pdev->dev.platform_data = fpi;
+ fpi->fs_no = fs_no;
+
+ e = (unsigned char *)&bd->bi_enetaddr;
+ for (i = 0; i < 6; i++)
+ fpi->macaddr[i] = *e++;
+
+ fpi->macaddr[5 - pdev->id]++;
+
+}
+
+static void mpc866ads_fixup_fec_enet_pdata(struct platform_device *pdev,
+ int idx)
+{
+ /* This is for FEC devices only */
+ if (strcmp(pdev->name, "fsl-cpm-fec"))
+ return;
+ mpc866ads_fixup_enet_pdata(pdev, fsid_fec1 + pdev->id - 1);
+}
+
+static void mpc866ads_fixup_scc_enet_pdata(struct platform_device *pdev,
+ int idx)
+{
+ /* This is for SCC devices only */
+ if (strcmp(pdev->name, "fsl-cpm-scc"))
+ return;
+
+ mpc866ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
+}
+
+static int mpc866ads_platform_notify(struct device *dev)
+{
+ static struct {
+ const char *bus_id;
+ void (*rtn) (struct platform_device * pdev, int idx);
+ } dev_map[] = {
+ {
+ "fsl-cpm-fec", mpc866ads_fixup_fec_enet_pdata}, {
+ "fsl-cpm-scc", mpc866ads_fixup_scc_enet_pdata},};
+ struct platform_device *pdev;
+ int i, j, idx;
+ const char *s;
+ if (dev && dev->bus_id)
+ for (i = 0; i < ARRAY_SIZE(dev_map); i++) {
+ idx = -1;
+
+ if ((s = strrchr(dev->bus_id, '.')) != NULL)
+ idx = (int)simple_strtol(s + 1, NULL, 10);
+ else
+ s = dev->bus_id;
+ j = s - dev->bus_id;
+ if (!strncmp(dev->bus_id, dev_map[i].bus_id, j)) {
+ pdev =
+ container_of(dev, struct platform_device,
+ dev);
+ dev_map[i].rtn(pdev, idx);
+ }
+ }
+ return 0;
+}
+
+int __init mpc866ads_init(void)
+{
+ printk(KERN_NOTICE "mpc866ads: Init\n");
+
+ platform_notify = mpc866ads_platform_notify;
+
+ identify_ppc_sys_by_name(BOARD_CHIP_NAME);
+
+ ppc_sys_device_remove(MPC8xx_CPM_FEC2);
+ ppc_sys_device_remove(MPC8xx_CPM_SCC3);
+ ppc_sys_device_remove(MPC8xx_CPM_SCC2);
+ ppc_sys_device_remove(MPC8xx_CPM_SCC4);
+ ppc_sys_device_remove(MPC8xx_CPM_SMC1);
+ ppc_sys_device_remove(MPC8xx_CPM_SMC2);
+
+ return 0;
+}
+
+arch_initcall(mpc866ads_init);
diff --git a/arch/ppc/platforms/mpc885ads_setup.c b/arch/ppc/platforms/mpc885ads_setup.c
new file mode 100644
index 0000000..5e72f64
--- /dev/null
+++ b/arch/ppc/platforms/mpc885ads_setup.c
@@ -0,0 +1,400 @@
+/*arch/ppc/platforms/mpc885ads-setup.c
+ *
+ * Platform setup for the Freescale mpc885ads board
+ *
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * Copyright 2005 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/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+
+#include <linux/fs_enet_pd.h>
+#include <linux/mii.h>
+
+#include <asm/delay.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/ppcboot.h>
+#include <asm/8xx_immap.h>
+#include <asm/commproc.h>
+#include <asm/ppc_sys.h>
+
+extern unsigned char __res[];
+
+static void __init mpc885ads_scc_phy_init(char);
+
+static struct fs_mii_bus_info fec_mii_bus_info = {
+ .method = fsmii_fec,
+ .id = 0,
+};
+
+static struct fs_mii_bus_info scc_mii_bus_info = {
+#ifdef CONFIG_SCC_ENET_8xx_FIXED
+ .method = fsmii_fixed,
+#else
+ .method = fsmii_fec,
+#endif
+
+ .id = 0,
+};
+
+static struct fs_platform_info mpc8xx_fec_pdata[] = {
+ {
+ .rx_ring = 128,
+ .tx_ring = 16,
+ .rx_copybreak = 240,
+
+ .use_napi = 1,
+ .napi_weight = 17,
+
+ .phy_addr = 0,
+ .phy_irq = SIU_IRQ7,
+
+ .bus_info = &fec_mii_bus_info,
+ }, {
+ .rx_ring = 128,
+ .tx_ring = 16,
+ .rx_copybreak = 240,
+
+ .use_napi = 1,
+ .napi_weight = 17,
+
+ .phy_addr = 1,
+ .phy_irq = SIU_IRQ7,
+
+ .bus_info = &fec_mii_bus_info,
+ }
+};
+
+static struct fs_platform_info mpc8xx_scc_pdata = {
+ .rx_ring = 64,
+ .tx_ring = 8,
+ .rx_copybreak = 240,
+
+ .use_napi = 1,
+ .napi_weight = 17,
+
+ .phy_addr = 2,
+#ifdef CONFIG_MPC8xx_SCC_ENET_FIXED
+ .phy_irq = -1,
+#else
+ .phy_irq = SIU_IRQ7,
+#endif
+
+ .bus_info = &scc_mii_bus_info,
+};
+
+void __init board_init(void)
+{
+ volatile cpm8xx_t *cp = cpmp;
+ unsigned int *bcsr_io;
+
+#ifdef CONFIG_FS_ENET
+ immap_t *immap = (immap_t *) IMAP_ADDR;
+#endif
+ bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+
+ if (bcsr_io == NULL) {
+ printk(KERN_CRIT "Could not remap BCSR\n");
+ return;
+ }
+#ifdef CONFIG_SERIAL_CPM_SMC1
+ cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */
+ clrbits32(bcsr_io, BCSR1_RS232EN_1);
+#else
+ setbits32(bcsr_io,BCSR1_RS232EN_1);
+ cp->cp_smc[0].smc_smcmr = 0;
+ cp->cp_smc[0].smc_smce = 0;
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SMC2
+ cp->cp_simode &= ~(0xe0000000 >> 1);
+ cp->cp_simode |= (0x20000000 >> 1); /* brg2 */
+ clrbits32(bcsr_io,BCSR1_RS232EN_2);
+#else
+ setbits32(bcsr_io,BCSR1_RS232EN_2);
+ cp->cp_smc[1].smc_smcmr = 0;
+ cp->cp_smc[1].smc_smce = 0;
+#endif
+ iounmap(bcsr_io);
+
+#ifdef CONFIG_FS_ENET
+ /* use MDC for MII (common) */
+ setbits16(&immap->im_ioport.iop_pdpar, 0x0080);
+ clrbits16(&immap->im_ioport.iop_pddir, 0x0080);
+#endif
+}
+
+static void setup_fec1_ioports(void)
+{
+ immap_t *immap = (immap_t *) IMAP_ADDR;
+
+ /* configure FEC1 pins */
+ setbits16(&immap->im_ioport.iop_papar, 0xf830);
+ setbits16(&immap->im_ioport.iop_padir, 0x0830);
+ clrbits16(&immap->im_ioport.iop_padir, 0xf000);
+ setbits32(&immap->im_cpm.cp_pbpar, 0x00001001);
+
+ clrbits32(&immap->im_cpm.cp_pbdir, 0x00001001);
+ setbits16(&immap->im_ioport.iop_pcpar, 0x000c);
+ clrbits16(&immap->im_ioport.iop_pcdir, 0x000c);
+ setbits32(&immap->im_cpm.cp_pepar, 0x00000003);
+
+ setbits32(&immap->im_cpm.cp_pedir, 0x00000003);
+ clrbits32(&immap->im_cpm.cp_peso, 0x00000003);
+ clrbits32(&immap->im_cpm.cp_cptr, 0x00000100);
+}
+
+static void setup_fec2_ioports(void)
+{
+ immap_t *immap = (immap_t *) IMAP_ADDR;
+
+ /* configure FEC2 pins */
+ setbits32(&immap->im_cpm.cp_pepar, 0x0003fffc);
+ setbits32(&immap->im_cpm.cp_pedir, 0x0003fffc);
+ setbits32(&immap->im_cpm.cp_peso, 0x00037800);
+ clrbits32(&immap->im_cpm.cp_peso, 0x000087fc);
+ clrbits32(&immap->im_cpm.cp_cptr, 0x00000080);
+}
+
+static void setup_scc3_ioports(void)
+{
+ immap_t *immap = (immap_t *) IMAP_ADDR;
+ unsigned *bcsr_io;
+
+ bcsr_io = ioremap(BCSR_ADDR, BCSR_SIZE);
+
+ if (bcsr_io == NULL) {
+ printk(KERN_CRIT "Could not remap BCSR\n");
+ return;
+ }
+
+ /* Enable the PHY.
+ */
+ setbits32(bcsr_io+4, BCSR4_ETH10_RST);
+ /* Configure port A pins for Txd and Rxd.
+ */
+ setbits16(&immap->im_ioport.iop_papar, PA_ENET_RXD | PA_ENET_TXD);
+ clrbits16(&immap->im_ioport.iop_padir, PA_ENET_RXD | PA_ENET_TXD);
+
+ /* Configure port C pins to enable CLSN and RENA.
+ */
+ clrbits16(&immap->im_ioport.iop_pcpar, PC_ENET_CLSN | PC_ENET_RENA);
+ clrbits16(&immap->im_ioport.iop_pcdir, PC_ENET_CLSN | PC_ENET_RENA);
+ setbits16(&immap->im_ioport.iop_pcso, PC_ENET_CLSN | PC_ENET_RENA);
+
+ /* Configure port E for TCLK and RCLK.
+ */
+ setbits32(&immap->im_cpm.cp_pepar, PE_ENET_TCLK | PE_ENET_RCLK);
+ clrbits32(&immap->im_cpm.cp_pepar, PE_ENET_TENA);
+ clrbits32(&immap->im_cpm.cp_pedir,
+ PE_ENET_TCLK | PE_ENET_RCLK | PE_ENET_TENA);
+ clrbits32(&immap->im_cpm.cp_peso, PE_ENET_TCLK | PE_ENET_RCLK);
+ setbits32(&immap->im_cpm.cp_peso, PE_ENET_TENA);
+
+ /* Configure Serial Interface clock routing.
+ * First, clear all SCC bits to zero, then set the ones we want.
+ */
+ clrbits32(&immap->im_cpm.cp_sicr, SICR_ENET_MASK);
+ setbits32(&immap->im_cpm.cp_sicr, SICR_ENET_CLKRT);
+
+ /* Disable Rx and Tx. SMC1 sshould be stopped if SCC3 eternet are used.
+ */
+ immap->im_cpm.cp_smc[0].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
+ /* On the MPC885ADS SCC ethernet PHY is initialized in the full duplex mode
+ * by H/W setting after reset. SCC ethernet controller support only half duplex.
+ * This discrepancy of modes causes a lot of carrier lost errors.
+ */
+
+ /* In the original SCC enet driver the following code is placed at
+ the end of the initialization */
+ setbits32(&immap->im_cpm.cp_pepar, PE_ENET_TENA);
+ clrbits32(&immap->im_cpm.cp_pedir, PE_ENET_TENA);
+ setbits32(&immap->im_cpm.cp_peso, PE_ENET_TENA);
+
+ setbits32(bcsr_io+1, BCSR1_ETHEN);
+ iounmap(bcsr_io);
+}
+
+static void mpc885ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no)
+{
+ struct fs_platform_info *fpi = pdev->dev.platform_data;
+
+ volatile cpm8xx_t *cp;
+ bd_t *bd = (bd_t *) __res;
+ char *e;
+ int i;
+
+ /* Get pointer to Communication Processor */
+ cp = cpmp;
+ switch (fs_no) {
+ case fsid_fec1:
+ fpi = &mpc8xx_fec_pdata[0];
+ fpi->init_ioports = &setup_fec1_ioports;
+ break;
+ case fsid_fec2:
+ fpi = &mpc8xx_fec_pdata[1];
+ fpi->init_ioports = &setup_fec2_ioports;
+ break;
+ case fsid_scc3:
+ fpi = &mpc8xx_scc_pdata;
+ fpi->init_ioports = &setup_scc3_ioports;
+ mpc885ads_scc_phy_init(fpi->phy_addr);
+ break;
+ default:
+ break;
+ }
+
+ pdev->dev.platform_data = fpi;
+ fpi->fs_no = fs_no;
+
+ e = (unsigned char *)&bd->bi_enetaddr;
+ for (i = 0; i < 6; i++)
+ fpi->macaddr[i] = *e++;
+
+ fpi->macaddr[5 - pdev->id]++;
+
+}
+
+static void mpc885ads_fixup_fec_enet_pdata(struct platform_device *pdev,
+ int idx)
+{
+ /* This is for FEC devices only */
+ if (!strstr(pdev->name, "fsl-cpm-fec"))
+ return;
+ mpc885ads_fixup_enet_pdata(pdev, fsid_fec1 + pdev->id - 1);
+}
+
+static void __init mpc885ads_fixup_scc_enet_pdata(struct platform_device *pdev,
+ int idx)
+{
+ /* This is for SCC devices only */
+ if (!strstr(pdev->name, "fsl-cpm-scc"))
+ return;
+
+ mpc885ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
+}
+
+/* SCC ethernet controller does not have MII management channel. FEC1 MII
+ * channel is used to communicate with the 10Mbit PHY.
+ */
+
+#define MII_ECNTRL_PINMUX 0x4
+#define FEC_ECNTRL_PINMUX 0x00000004
+#define FEC_RCNTRL_MII_MODE 0x00000004
+
+/* Make MII read/write commands.
+ */
+#define mk_mii_write(REG, VAL, PHY_ADDR) (0x50020000 | (((REG) & 0x1f) << 18) | \
+ ((VAL) & 0xffff) | ((PHY_ADDR) << 23))
+
+static void mpc885ads_scc_phy_init(char phy_addr)
+{
+ volatile immap_t *immap;
+ volatile fec_t *fecp;
+ bd_t *bd;
+
+ bd = (bd_t *) __res;
+ immap = (immap_t *) IMAP_ADDR; /* pointer to internal registers */
+ fecp = &(immap->im_cpm.cp_fec);
+
+ /* Enable MII pins of the FEC1
+ */
+ setbits16(&immap->im_ioport.iop_pdpar, 0x0080);
+ clrbits16(&immap->im_ioport.iop_pddir, 0x0080);
+ /* Set MII speed to 2.5 MHz
+ */
+ out_be32(&fecp->fec_mii_speed,
+ ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1);
+
+ /* Enable FEC pin MUX
+ */
+ setbits32(&fecp->fec_ecntrl, MII_ECNTRL_PINMUX);
+ setbits32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE);
+
+ out_be32(&fecp->fec_mii_data,
+ mk_mii_write(MII_BMCR, BMCR_ISOLATE, phy_addr));
+ udelay(100);
+ out_be32(&fecp->fec_mii_data,
+ mk_mii_write(MII_ADVERTISE,
+ ADVERTISE_10HALF | ADVERTISE_CSMA, phy_addr));
+ udelay(100);
+
+ /* Disable FEC MII settings
+ */
+ clrbits32(&fecp->fec_ecntrl, MII_ECNTRL_PINMUX);
+ clrbits32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE);
+ out_be32(&fecp->fec_mii_speed, 0);
+}
+
+static int mpc885ads_platform_notify(struct device *dev)
+{
+ static struct {
+ const char *bus_id;
+ void (*rtn) (struct platform_device * pdev, int idx);
+ } dev_map[] = {
+ {
+ "fsl-cpm-fec", mpc885ads_fixup_fec_enet_pdata}, {
+ "fsl-cpm-scc", mpc885ads_fixup_scc_enet_pdata},};
+ struct platform_device *pdev;
+ int i, j, idx;
+ const char *s;
+ if (dev && dev->bus_id)
+ for (i = 0; i < ARRAY_SIZE(dev_map); i++) {
+ idx = -1;
+
+ if ((s = strrchr(dev->bus_id, '.')) != NULL)
+ idx = (int)simple_strtol(s + 1, NULL, 10);
+ else
+ s = dev->bus_id;
+ j = s - dev->bus_id;
+ if (!strncmp(dev->bus_id, dev_map[i].bus_id, j)) {
+ pdev =
+ container_of(dev, struct platform_device,
+ dev);
+ dev_map[i].rtn(pdev, idx);
+ }
+ }
+ return 0;
+}
+
+int __init mpc885ads_init(void)
+{
+ printk(KERN_NOTICE "mpc885ads: Init\n");
+
+ platform_notify = mpc885ads_platform_notify;
+
+ identify_ppc_sys_by_name(BOARD_CHIP_NAME);
+
+#ifdef CONFIG_MPC8xx_SECOND_ETH_SCC3
+ ppc_sys_device_remove(MPC8xx_CPM_FEC2);
+#endif
+#ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
+ ppc_sys_device_remove(MPC8xx_CPM_SCC3);
+#endif
+
+ ppc_sys_device_remove(MPC8xx_CPM_SCC1);
+ ppc_sys_device_remove(MPC8xx_CPM_SCC2);
+ ppc_sys_device_remove(MPC8xx_CPM_SCC4);
+ ppc_sys_device_remove(MPC8xx_CPM_SMC1);
+ ppc_sys_device_remove(MPC8xx_CPM_SMC2);
+
+ return 0;
+}
+
+arch_initcall(mpc885ads_init);
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
index 2bfdf9c..0ff4395 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -556,4 +556,11 @@ extern void pci_iounmap(struct pci_dev *
*/
#define xlate_dev_kmem_ptr(p) p
+/* access ports */
+#define setbits32(_addr, _v) out_be32((_addr), in_be32(_addr) | (_v))
+#define clrbits32(_addr, _v) out_be32((_addr), in_be32(_addr) & ~(_v))
+
+#define setbits16(_addr, _v) out_be16((_addr), in_be16(_addr) | (_v))
+#define clrbits16(_addr, _v) out_be16((_addr), in_be16(_addr) & ~(_v))
+
#endif /* __KERNEL__ */
---
Sincerely,
Vitaly
^ permalink raw reply related
* [PATCH] 8xx PCMCIA: support for MPC885ADS and MPC866ADS
From: Vitaly Bordug @ 2005-11-18 16:42 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: linuxppc-embedded list
[-- Attachment #1: Type: text/plain, Size: 302 bytes --]
This adds adds PCMCIA supported for both MPC885ADS and MPC866ADS.
This is established not together with FADS, because 885 does not have
io_block_mapping() for BCSR area.
Also, some cleanups done both for 885ADS and MBX.
Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
--
Sincerely,
Vitaly
[-- Attachment #2: mpc8xx_pcmcia_885ads1.patch --]
[-- Type: text/x-patch, Size: 3553 bytes --]
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index 6d9f71c..5b7a04f 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -9,6 +9,9 @@
* <oliver.kurth@cyclades.de>
* Further fixes, v2.6 kernel port
* <marcelo.tosatti@cyclades.com>
+ *
+ * Some fixes, additions (C) 2005 Montavista Software, Inc.
+ * <vbordug@ru.mvista.com>
*
* "The ExCA standard specifies that socket controllers should provide
* two IO and five memory windows per socket, which can be independently
@@ -97,6 +100,11 @@ MODULE_LICENSE("Dual MPL/GPL");
#endif
#endif
+#if defined(CONFIG_MPC885ADS)
+#define CONFIG_PCMCIA_SLOT_A
+#define PCMCIA_GLITCHY_CD
+#endif
+
/* Cyclades ACS uses both slots */
#ifdef CONFIG_PRxK
#define CONFIG_PCMCIA_SLOT_A
@@ -374,11 +382,80 @@ static int voltage_set(int slot, int vcc
}
/* first, turn off all power */
- out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK));
+ out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK));
+
+ /* enable new powersettings */
+ out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) | reg);
+
+ return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
+
+static void hardware_enable(int slot)
+{
+ out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) & ~BCSR1_PCCEN);
+}
+
+static void hardware_disable(int slot)
+{
+ out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) | BCSR1_PCCEN);
+}
+
+#endif
+
+/* MPC885ADS Boards */
+
+#if defined(CONFIG_MPC885ADS)
+
+#define PCMCIA_BOARD_MSG "MPC885ADS"
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+ u32 reg = 0;
+ unsigned *bcsr_io;
+
+ bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+
+ switch(vcc) {
+ case 0:
+ break;
+ case 33:
+ reg |= BCSR1_PCCVCC0;
+ break;
+ case 50:
+ reg |= BCSR1_PCCVCC1;
+ break;
+ default:
+ return 1;
+ }
+
+ switch(vpp) {
+ case 0:
+ break;
+ case 33:
+ case 50:
+ if(vcc == vpp)
+ reg |= BCSR1_PCCVPP1;
+ else
+ return 1;
+ break;
+ case 120:
+ if ((vcc == 33) || (vcc == 50))
+ reg |= BCSR1_PCCVPP0;
+ else
+ return 1;
+ default:
+ return 1;
+ }
+
+ /* first, turn off all power */
+ out_be32(bcsr_io, in_be32(bcsr_io) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK));
/* enable new powersettings */
- out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) | reg);
+ out_be32(bcsr_io, in_be32(bcsr_io) | reg);
+ iounmap(bcsr_io);
return 0;
}
@@ -386,12 +463,20 @@ static int voltage_set(int slot, int vcc
static void hardware_enable(int slot)
{
- out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) & ~BCSR1_PCCEN);
+ unsigned *bcsr_io;
+
+ bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+ out_be32(bcsr_io, in_be32(bcsr_io) & ~BCSR1_PCCEN);
+ iounmap(bcsr_io);
}
static void hardware_disable(int slot)
{
- out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) | BCSR1_PCCEN);
+ unsigned *bcsr_io;
+
+ bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+ out_be32(bcsr_io, in_be32(bcsr_io) | BCSR1_PCCEN);
+ iounmap(bcsr_io);
}
#endif
@@ -440,10 +525,10 @@ static int voltage_set(int slot, int vcc
}
/* first, turn off all power */
- out_8(&((u8 *)MBX_CSR2_ADDR), in_8(&((u8 *)MBX_CSR2_ADDR)) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK));
+ out_8((u8 *)MBX_CSR2_ADDR, in_8((u8 *)MBX_CSR2_ADDR) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK));
/* enable new powersettings */
- out_8(&((u8 *)MBX_CSR2_ADDR), in_8(&((u8 *)MBX_CSR2_ADDR)) | reg);
+ out_8((u8 *)MBX_CSR2_ADDR, in_8((u8 *)MBX_CSR2_ADDR) | reg);
return 0;
}
^ permalink raw reply related
* Re: Help ! 2.6.14 kernel can't bring up
From: Clemens Koller @ 2005-11-18 18:44 UTC (permalink / raw)
To: zjznliang; +Cc: linuxppc-embedded
In-Reply-To: <20051118024803.E2988687A1@ozlabs.org>
Hello, zjznliang!
zjznliang wrote:
> Hi linuxppc-embedded!
>
> Hi , How to config the "early printk" in 2.6.14 linux configration???
Well... check the .config or the kernel sources for
CONFIG_EARLY_PRINTK
or
CONFIG_WANT_EARLY_SERIAL
Have a look at the bootup code of your board, where it's used.
I would call the printk as soon as the serial ports are initialized.
If that's too late, try to toggle some pin as early as possible.
If that doesn't work, and if you have no more ideas of what to do,
you might think about getting some hardware debugging tools.
Best greets,
--
Clemens Koller
_______________________________
R&D Imaging Devices
Anagramm GmbH
Rupert-Mayer-Str. 45/1
81379 Muenchen
Germany
http://www.anagramm.de
Phone: +49-89-741518-50
Fax: +49-89-741518-19
^ permalink raw reply
* Re: [PATCH] m8xx_wdt: software watchdog reset/interrupt select
From: Marcelo Tosatti @ 2005-11-18 15:36 UTC (permalink / raw)
To: Florian Schirmer, Dan Malek; +Cc: obi, carjay, linux-ppc-embedded
In-Reply-To: <437C499C.6090002@tuxbox.org>
On Thu, Nov 17, 2005 at 10:13:00AM +0100, Florian Schirmer wrote:
> Hi,
>
> okay here is what the current driver does:
>
> During startup it installs a timer irq (PIT) handler and sets the
> frequency to half of the watchdog timeout. As soon as this timer irq
> triggers we reset the watchdog inside the irq handler.
>
> If a userspace handler takes over the watchdog we deinstall the timer
> irq handler and let the userspace daemon handle the watchdog resets.
>
> Please not that we're talking about the timer irq, not the watchdog
> interrupt.
>
> I don't see why it should make a difference wether the watchdog
> generates a IRQ0/HRESET or a system reset directly since it should never
> trigger anyway.
>
> All the patch does is to use a kernel timer instead of the hardware
> timer. So i'm little confused.
Florian,
After your message I decided to check if the PIT is working, guess what: it isnt.
Our board uses an external RTC (the internal RTC/PIT HW seem to be
nonexistant/nonfunctional).
I've changed the m8xx_wdt code to deal with that situation by checking
the RTC enable bit of RTCSC as follows:
m8xx_has_internal_rtc = in_be16(&imap->im_sit.sit_rtcsc) & RTCSC_RTE;
Problem with it is that the kernel sets the RTCSC_RTE bit
unconditionally in m8xx_calibrate_decr(), so you can't really know its
original value. The following patch changes m8xx_calibrate_decr()'s
RTC initialization to a weak function which can be overriden by board
specific code.
Dan, can you think of any nicer to avoid m8xx_calibrate_decr() from
overwriting RTCSC?
diff --git a/arch/ppc/syslib/m8xx_setup.c b/arch/ppc/syslib/m8xx_setup.c
index 1cc3abe..688616d 100644
--- a/arch/ppc/syslib/m8xx_setup.c
+++ b/arch/ppc/syslib/m8xx_setup.c
@@ -135,6 +135,16 @@ static struct irqaction tbint_irqaction
.name = "tbint",
};
+/* per-board overridable init_internal_rtc() function. */
+void __init __attribute__ ((weak))
+init_internal_rtc(void)
+{
+ /* Disable the RTC one second and alarm interrupts. */
+ out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) & ~(RTCSC_SIE | RTCSC_ALE));
+ /* Enable the RTC */
+ out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) | (RTCSC_RTF | RTCSC_RTE));
+}
+
/* The decrementer counts at the system (internal) clock frequency divided by
* sixteen, or external oscillator divided by four. We force the processor
* to use system clock divided by sixteen.
@@ -183,10 +193,7 @@ void __init m8xx_calibrate_decr(void)
out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck, KAPWR_KEY);
out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk, KAPWR_KEY);
- /* Disable the RTC one second and alarm interrupts. */
- out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) & ~(RTCSC_SIE | RTCSC_ALE));
- /* Enable the RTC */
- out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) | (RTCSC_RTF | RTCSC_RTE));
+ init_internal_rtc();
/* Enabling the decrementer also enables the timebase interrupts
* (or from the other point of view, to get decrementer interrupts
diff --git a/arch/ppc/syslib/m8xx_wdt.c b/arch/ppc/syslib/m8xx_wdt.c
index a21632d..df6c955 100644
--- a/arch/ppc/syslib/m8xx_wdt.c
+++ b/arch/ppc/syslib/m8xx_wdt.c
@@ -19,6 +19,7 @@
#include <syslib/m8xx_wdt.h>
static int wdt_timeout;
+int m8xx_has_internal_rtc = 0;
static irqreturn_t m8xx_wdt_interrupt(int, void *, struct pt_regs *);
static struct irqaction m8xx_wdt_irqaction = {
@@ -45,35 +46,15 @@ static irqreturn_t m8xx_wdt_interrupt(in
return IRQ_HANDLED;
}
-void __init m8xx_wdt_handler_install(bd_t * binfo)
+#define SYPCR_SWP 0x1
+#define SYPCR_SWE 0x4
+
+
+void __init m8xx_wdt_install_irq(volatile immap_t *imap, bd_t *binfo)
{
- volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
u32 pitc;
- u32 sypcr;
u32 pitrtclk;
- sypcr = in_be32(&imap->im_siu_conf.sc_sypcr);
-
- if (!(sypcr & 0x04)) {
- printk(KERN_NOTICE "m8xx_wdt: wdt disabled (SYPCR: 0x%08X)\n",
- sypcr);
- return;
- }
-
- m8xx_wdt_reset();
-
- printk(KERN_NOTICE
- "m8xx_wdt: active wdt found (SWTC: 0x%04X, SWP: 0x%01X)\n",
- (sypcr >> 16), sypcr & 0x01);
-
- wdt_timeout = (sypcr >> 16) & 0xFFFF;
-
- if (!wdt_timeout)
- wdt_timeout = 0xFFFF;
-
- if (sypcr & 0x01)
- wdt_timeout *= 2048;
-
/*
* Fire trigger if half of the wdt ticked down
*/
@@ -98,6 +79,67 @@ void __init m8xx_wdt_handler_install(bd_
printk(KERN_NOTICE
"m8xx_wdt: keep-alive trigger installed (PITC: 0x%04X)\n", pitc);
+}
+
+static void m8xx_wdt_timer_func(unsigned long data);
+
+static struct timer_list m8xx_wdt_timer =
+ TIMER_INITIALIZER(m8xx_wdt_timer_func, 0, 0);
+
+void m8xx_wdt_stop_timer(void)
+{
+ del_timer(&m8xx_wdt_timer);
+}
+
+void m8xx_wdt_install_timer(void)
+{
+ m8xx_wdt_timer.expires = jiffies + (HZ/2);
+ add_timer(&m8xx_wdt_timer);
+}
+
+static void m8xx_wdt_timer_func(unsigned long data)
+{
+ m8xx_wdt_reset();
+ m8xx_wdt_install_timer();
+}
+
+void __init m8xx_wdt_handler_install(bd_t * binfo)
+{
+ volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
+ u32 sypcr;
+
+ sypcr = in_be32(&imap->im_siu_conf.sc_sypcr);
+
+ if (!(sypcr & SYPCR_SWE)) {
+ printk(KERN_NOTICE "m8xx_wdt: wdt disabled (SYPCR: 0x%08X)\n",
+ sypcr);
+ return;
+ }
+
+ m8xx_wdt_reset();
+
+ printk(KERN_NOTICE
+ "m8xx_wdt: active wdt found (SWTC: 0x%04X, SWP: 0x%01X)\n",
+ (sypcr >> 16), sypcr & SYPCR_SWP);
+
+ wdt_timeout = (sypcr >> 16) & 0xFFFF;
+
+ if (!wdt_timeout)
+ wdt_timeout = 0xFFFF;
+
+ if (sypcr & SYPCR_SWP)
+ wdt_timeout *= 2048;
+
+ m8xx_has_internal_rtc = in_be16(&imap->im_sit.sit_rtcsc) & RTCSC_RTE;
+
+ /* if the internal RTC is off use a kernel timer */
+ if (!m8xx_has_internal_rtc) {
+ if (wdt_timeout < (binfo->bi_intfreq/HZ))
+ printk(KERN_ERR "m8xx_wdt: timeout too short for ktimer!\n");
+ m8xx_wdt_install_timer();
+ } else
+ m8xx_wdt_install_irq(imap, binfo);
+
wdt_timeout /= binfo->bi_intfreq;
}
diff --git a/arch/ppc/syslib/m8xx_wdt.h b/arch/ppc/syslib/m8xx_wdt.h
index 0d81a9f..e75835f 100644
--- a/arch/ppc/syslib/m8xx_wdt.h
+++ b/arch/ppc/syslib/m8xx_wdt.h
@@ -9,8 +9,12 @@
#ifndef _PPC_SYSLIB_M8XX_WDT_H
#define _PPC_SYSLIB_M8XX_WDT_H
+extern int m8xx_has_internal_rtc;
+
extern void m8xx_wdt_handler_install(bd_t * binfo);
extern int m8xx_wdt_get_timeout(void);
extern void m8xx_wdt_reset(void);
+extern void m8xx_wdt_install_timer(void);
+extern void m8xx_wdt_stop_timer(void);
#endif /* _PPC_SYSLIB_M8XX_WDT_H */
diff --git a/drivers/char/watchdog/mpc8xx_wdt.c b/drivers/char/watchdog/mpc8xx_wdt.c
index 56d62ba..ac6fbac 100644
--- a/drivers/char/watchdog/mpc8xx_wdt.c
+++ b/drivers/char/watchdog/mpc8xx_wdt.c
@@ -27,7 +27,10 @@ static void mpc8xx_wdt_handler_disable(v
{
volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
- imap->im_sit.sit_piscr &= ~(PISCR_PIE | PISCR_PTE);
+ if (!m8xx_has_internal_rtc)
+ m8xx_wdt_stop_timer();
+ else
+ out_be32(imap->im_sit.sit_piscr, in_be32(&imap->im_sit.sit_piscr) & ~(PISCR_PIE | PISCR_PTE));
printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler deactivated\n");
}
@@ -36,7 +39,10 @@ static void mpc8xx_wdt_handler_enable(vo
{
volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR;
- imap->im_sit.sit_piscr |= PISCR_PIE | PISCR_PTE;
+ if (!m8xx_has_internal_rtc)
+ m8xx_wdt_install_timer();
+ else
+ out_be32(&imap->im_sit.sit_piscr, in_be32(&imap->im_sit.sit_piscr) | PISCR_PIE | PISCR_PTE);
printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler activated\n");
}
@@ -68,9 +74,6 @@ static int mpc8xx_wdt_release(struct ino
static ssize_t mpc8xx_wdt_write(struct file *file, const char *data, size_t len,
loff_t * ppos)
{
- if (ppos != &file->f_pos)
- return -ESPIPE;
-
if (len)
m8xx_wdt_reset();
^ permalink raw reply related
* Re: [PATCH] Fix 8250 probe on ppc32
From: Benjamin Herrenschmidt @ 2005-11-18 21:36 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev list, David Woodhouse, Tom Rini
In-Reply-To: <5534EC32-EE72-4019-A5D9-305F8348E4D9@kernel.crashing.org>
> How early on can we use udbg? I'd be interested to see how this is
> going to work out for 4xx/83xx/85xx w/built-in 8250's.
As soon as you can get something mapped I suppose... On ppc32 with
BootX, I setup a BAT in head.S, thus udbg is available in
machine_init(). On ppc64 with hypervisor console, we can enable hacks
that initialize udbg in real mode.
Ben.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox