* MPC5200 (Board: PM520) I2C Problem
From: RPo @ 2006-10-19 15:05 UTC (permalink / raw)
To: 'linuxppc-embedded@ozlabs.org'
Hi,
I'm currently using the MPC5200 based board "PM520" and
want to access the I2C bus. To do so, I attached a PCF8574P
to the bus. But I was not successful in setting the outputs
of this IC.
Here is the code with which I tried to access the bus:
8<==================================================
int i2c = 0, i = 0xfffffff;
i2c = open("/dev/i2c-0",O_RDWR);
if(i2c > 0)
RT_TRACE(printf("I2C opened successfully.\n"));
else
RT_TRACE(printf("Error: I2C could not be opened.\n"));
ioctl(i2c, I2C_SLAVE, 0x46);
write(i2c, &i, 1);
8<==================================================
The open() and ioctl() calls are successful (checked with
strace) but the write() call always returns -1 and an
EREMOTEIO error. The device nodes have been created this way:
8<==================================================
mknod /dev/i2c-0 c 89 0
mknod /dev/i2c-1 c 89 1
chmod 666 /dev/i2c-*
8<==================================================
So here is my configuration:
Linux 2.4.25 (ELDK 3.1.1-2005-06-07)
The I2C modules were compiled after I had made some changes
to the i2c-pm520.c file in the kernel-tree:
8<================== ORIGINAL ======================
/* #define MPC5xxx_I2C1_ENABLE 0 */ /* Disabled */
8<================== ORIGINAL ======================
8<================== MODIFIED ======================
#define MPC5xxx_I2C1_ENABLE 1 /* Enabled */
8<================== MODIFIED ======================
I was unsure about the bus my code uses and so I decided to
enable both busses. These are the printks I get, when I load
the modules:
8<==================================================
# /ftp/sbin/insmod ./i2c-core.o
i2c-core.o: i2c core module version 2.6.1 (20010830)
# /ftp/sbin/insmod ./i2c-proc.o
i2c-proc.o version 2.6.1 (20010830)
# /ftp/sbin/insmod ./i2c-dev.o
i2c-dev.o: i2c /dev entries driver module version 2.6.1 (20010830)
# /ftp/sbin/insmod ./i2c-algo-mpc5xxx.o speed=85
# /ftp/sbin/insmod ./i2c-pm520.o
i2c-algo-5xxx.o: scanning bus PM520 I2C module #1 interface...
............................................................................
....
................................................
i2c-pm520.o: I2C module #1 installed
i2c-algo-5xxx.o: scanning bus PM520 I2C module #2 interface...
............................................................................
....
.(0x51)......(0x58)(0x59)(0x5a)(0x5b)(0x5c)(0x5d)(0x5e)(0x5f)...............
....
............(0x7f)
i2c-pm520.o: I2C module #2 installed
8<==================================================
So, what are these identifiers on I2C module #2 interface?
I can neither find them in the documentation of the EEPROM
nor the one of the realtime clock. write() calls to these
IDs are succesful, but it seems like nothing happens. The
same is for the other bus (module #1 interface).
Has anyone an idea or experience with I2C bus on the MPC5200?
Best regards and thanks for reading,
Rainer
^ permalink raw reply
* Re: status of mpc52xx with arch=powerpc?
From: Grant Likely @ 2006-10-19 14:46 UTC (permalink / raw)
To: Roman Fietze; +Cc: linuxppc-embedded
In-Reply-To: <200610191149.10873.roman.fietze@telemotive.de>
On 10/19/06, Roman Fietze <roman.fietze@telemotive.de> wrote:
> Could you both double check e.g. with Sylvain Munaut at
If Sylvain is around and has available bandwidth, I'm sure he is
monitoring this list.
> There are many drivers (git heads) available already, including IDE,
> FEC, and so on. There's also new BestComm/FEC/IDE code from Dale
> Farnsworth and John Rigby (Freescale) somewhere on the net.
Yes, I'm using those patches; but they don't help with getting the
mpc52xx moved over to arch/powerpc
--
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
^ permalink raw reply
* Re: [PATCH] powerpc: Support for MPIC on native cell
From: Arnd Bergmann @ 2006-10-19 14:38 UTC (permalink / raw)
To: linuxppc-dev; +Cc: cbe-oss-dev@ozlabs.org
In-Reply-To: <1160984707.22522.64.camel@localhost.localdomain>
On Monday 16 October 2006 09:45, Benjamin Herrenschmidt wrote:
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0/* The MPIC driver will get=
everything it needs from the
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 * device-tree, just pass 0=
to all arguments
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 */
> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0mpic =3D mpic_alloc(dn, 0, =
0, 0, 0, " MPIC =A0 =A0 ");
Do you expect future users to do the same and just pass zeroes?
If so, maybe we should add a small wrapper like
static inline struct mpic *mpic_probe(struct device_node *dn)
{
return mpic_alloc(dn, 0, 0, 0, 0, " MPIC ");
}
in <asm/mpic.h>
Arnd <><
^ permalink raw reply
* Re: status of mpc52xx with arch=powerpc?
From: Sascha Hauer @ 2006-10-19 14:17 UTC (permalink / raw)
To: Roman Fietze; +Cc: linuxppc-embedded
In-Reply-To: <200610191149.10873.roman.fietze@telemotive.de>
On Thu, Oct 19, 2006 at 11:49:07AM +0200, Roman Fietze wrote:
> Hello,
>
> On Thursday 19 October 2006 10:13, Sascha Hauer wrote:
>
> > Could you post your .dts?
> > I'm too working on it, so maybe we should stay synchronized. At the
> > moment I have nothing but a minimal dts and some .progress() messages.
>
> Could you both double check e.g. with Sylvain Munaut at
>
> http://246tnt.com/mpc52xx/
I have his tree here and and it does not seem to contain bits for
mpc52xx with arch=powerpc (unless there are some git-secrets I'm not
aware of)
>
> There are many drivers (git heads) available already, including IDE,
> FEC, and so on. There's also new BestComm/FEC/IDE code from Dale
> Farnsworth and John Rigby (Freescale) somewhere on the net.
>
We have these drivers running already with arch=ppc. I have not looked
into it deeper, but I think (well, hope) they only need minor changes
like a transition from platform_device to of_device.
I just received a patch from nicolas det with a port from ppc to
powerpc, I'll have a look at it. He posted it on linuxppc-dev
Sascha
--
Dipl.-Ing. Sascha Hauer | http://www.pengutronix.de
Pengutronix - Linux Solutions for Science and Industry
Handelsregister: Amtsgericht Hildesheim, HRA 2686
Hannoversche Str. 2, 31134 Hildesheim, Germany
Phone: +49-5121-206917-0 | Fax: +49-5121-206917-9
^ permalink raw reply
* Re: [PATCH/RFC] Add cmd_wrap_dts rules to arch/powerpc/boot/Makefile
From: Jon Loeliger @ 2006-10-19 14:03 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <20061019002635.GA2356@mag.az.mvista.com>
So, like, the other day "Mark A. Greer" mumbled:
>
> This would be used by the sandpoint, say, by adding the following rules
> to the Makefile in the appropriate places:
>
> $(obj)/zImage.sandpoint: vmlinux $(wrapperbits)
> $(call cmd,wrap_dts,sandpoint)
>
> $(obj)/zImage.initrd.sandpoint: vmlinux $(wrapperbits)
> $(call cmd,wrap_dts_initrd,sandpoint)
>
> and:
>
> image-$(CONFIG_SANDPOINT) += zImage.sandpoint
>
> Comments?
Isn't there a way to do this without hardcoding the
platform name in the makefiles directly? I fear for
the one-per-platform effect that is yet to come with
the conversion of many of the legacy boards.
> +++ b/arch/powerpc/boot/Makefile
> @@ -117,6 +117,13 @@ quiet_cmd_wrap = WRAP $@
> quiet_cmd_wrap_initrd = WRAP $@
> cmd_wrap_initrd =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \
> -i $(obj)/ramdisk.image.gz vmlinux
> +quiet_cmd_wrap_dts = WRAP_DTS $@
> + cmd_wrap_dts =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \
> + -s $(obj)/dts/$2.dts vmlinux
> +quiet_cmd_wrap_dts_initrd = WRAP_DTS $@
> + cmd_wrap_dts_initrd =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 \
> + $(CROSSWRAP) -s $(obj)/dts/$2.dts \
> + -i $(obj)/ramdisk.image.gz vmlinux
>
> $(obj)/zImage.chrp: vmlinux $(wrapperbits)
> $(call cmd,wrap,chrp)
Which I guess means this patch is OK, but the zImage.chrp use
around it is suspect.... :-)
jdl
^ permalink raw reply
* [PATCH] CPM_UART: Fix non-console transmit
From: kalle.pokki @ 2006-10-19 12:25 UTC (permalink / raw)
To: linuxppc-embedded, galak, panto, vbordug
The SMC and SCC hardware transmitter is enabled at the wrong
place. Simply writing twice to the non-console port, like
$ echo asdf > /dev/ttyCPM1
$ echo asdf > /dev/ttyCPM1
puts the shell into endless uninterruptible sleep, since the
transmitter is stopped after the first write, and is not enabled
before the shutdown function of the second write. Thus the transmit
buffers are never emptied.
Signed-off-by: Kalle Pokki <kalle.pokki@iki.fi>
---
drivers/serial/cpm_uart/cpm_uart_core.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 90ff96e..8f3b3e5 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -194,10 +194,8 @@ static void cpm_uart_start_tx(struct uar
if (cpm_uart_tx_pump(port) != 0) {
if (IS_SMC(pinfo)) {
smcp->smc_smcm |= SMCM_TX;
- smcp->smc_smcmr |= SMCMR_TEN;
} else {
sccp->scc_sccm |= UART_SCCM_TX;
- pinfo->sccp->scc_gsmrl |= SCC_GSMRL_ENT;
}
}
}
@@ -420,9 +418,10 @@ static int cpm_uart_startup(struct uart_
/* Startup rx-int */
if (IS_SMC(pinfo)) {
pinfo->smcp->smc_smcm |= SMCM_RX;
- pinfo->smcp->smc_smcmr |= SMCMR_REN;
+ pinfo->smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN);
} else {
pinfo->sccp->scc_sccm |= UART_SCCM_RX;
+ pinfo->sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
}
if (!(pinfo->flags & FLAG_CONSOLE))
--
1.4.1.1
^ permalink raw reply related
* Re: Badness in irq_create_mapping at arch/powerpc/kernel/irq.c:527
From: Nicolas DET @ 2006-10-19 13:34 UTC (permalink / raw)
To: Olaf Hering; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20061019122802.GA26637@aepfle.de>
[-- Attachment #1: Type: text/plain, Size: 522 bytes --]
Olaf Hering wrote:
> I get irq warnings with current Linus tree on Pegasos.
> The EDID handling for radeonfb appears to be broken as well,
> but thats a different story:
>
This patch enables chrp_pcibios_fixup() for bPlan's machine. however,
this function should NOT be called as thoses platforms.
http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=26c5032eaa64090b2a01973b0c6ea9e7f6a80fa7
An upcomming patch will "ppc_md.pcibios_fixup = NULL;" for every bPlan's
platforms.
Regards,
[-- Attachment #2: nd.vcf --]
[-- Type: text/x-vcard, Size: 249 bytes --]
begin:vcard
fn:Nicolas DET ( bplan GmbH )
n:DET;Nicolas
org:bplan GmbH
adr:;;;;;;Germany
email;internet:nd@bplan-gmbh.de
title:Software Entwicklung
tel;work:+49 6171 9187 - 31
x-mozilla-html:FALSE
url:http://www.bplan-gmbh.de
version:2.1
end:vcard
^ permalink raw reply
* [RFC] Porting AmigaOne platform code from ppc to powerpc
From: Gerhard Pircher @ 2006-10-19 13:24 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <20060630182144.27980@gmx.net>
Hi!
I'm working on the AmigaOne Linux kernel port. The AmigaOne is a G3/G4 desktop system and makes use of U-boot v1.1.0 as firmware. I intend to port the current code base of this platform to the powerpc architecture, but I'm not sure how to address this.
The "problem" is the device tree required by the powerpc architecture. The AmigaOne's U-boot version doesn't support the flattened device tree yet and also requires a special flash rom programmer tool (I guess it adds some sort of dongle code to the flash rom content). Otherwise users won't be able to boot AmigaOS4. Thus using a newer U-boot version is not really an option and AFAIK the OS4 developers are not going to update their U-boot version.
Well, some time ago I read about a CUIMAGE target that can be used to get powerpc-arch kernels working on old U-boot versions by using a precompiled/static device tree. I don't think that this approch makes sense for a desktop platform, which uses different CPUs (750FX, 750GX, 7410, 7450, 7455, etc..), PCI/AGP cards, etc.
Any advice for me in this case?
Regards,
Gerhard
--
GMX DSL-Flatrate 0,- Euro* - Überall, wo DSL verfügbar ist!
NEU: Jetzt bis zu 16.000 kBit/s! http://www.gmx.net/de/go/dsl
^ permalink raw reply
* [PATCH] CPM_UART: Fix non-console transmit
From: Kalle Pokki @ 2006-10-19 12:52 UTC (permalink / raw)
To: linuxppc-embedded
The SMC and SCC hardware transmitter is enabled at the wrong
place. Simply writing twice to the non-console port, like
$ echo asdf > /dev/ttyCPM1
$ echo asdf > /dev/ttyCPM1
puts the shell into endless uninterruptible sleep, since the
transmitter is stopped after the first write, and is not enabled
before the shutdown function of the second write. Thus the transmit
buffers are never emptied.
Signed-off-by: Kalle Pokki <kalle.pokki@iki.fi>
---
drivers/serial/cpm_uart/cpm_uart_core.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 90ff96e..8f3b3e5 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -194,10 +194,8 @@ static void cpm_uart_start_tx(struct uar
if (cpm_uart_tx_pump(port) != 0) {
if (IS_SMC(pinfo)) {
smcp->smc_smcm |= SMCM_TX;
- smcp->smc_smcmr |= SMCMR_TEN;
} else {
sccp->scc_sccm |= UART_SCCM_TX;
- pinfo->sccp->scc_gsmrl |= SCC_GSMRL_ENT;
}
}
}
@@ -420,9 +418,10 @@ static int cpm_uart_startup(struct uart_
/* Startup rx-int */
if (IS_SMC(pinfo)) {
pinfo->smcp->smc_smcm |= SMCM_RX;
- pinfo->smcp->smc_smcmr |= SMCMR_REN;
+ pinfo->smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN);
} else {
pinfo->sccp->scc_sccm |= UART_SCCM_RX;
+ pinfo->sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
}
if (!(pinfo->flags & FLAG_CONSOLE))
--
1.4.1.1
^ permalink raw reply related
* [PATCH] General CHRP/MPC5K2 Platform and drivers support - to comment
From: Nicolas DET @ 2006-10-19 12:39 UTC (permalink / raw)
To: linuxppc-dev, sl, benh, tnt
[-- Attachment #1: Type: text/plain, Size: 538 bytes --]
This 'big' patch adds support for CHRP/MPC52xx based platform. Here,
this is the bPlan's Efika computer
(http://www.bplan-gmbh.de/efika_spec_en.html)
We know this patch is not totaly compliant with Documentation/CodingStyle/.
We would like people to comment and review it. This way we would provide
a new patch with the changes required (if any) for an upcomming merge in
the kernel.
This patch has been applied on the kernel 2.6.18.1.
Signed-off-by: Nicolas DET <nd@bplan-gmbh.de>
Signed-off-by: Sven Luther <sl@bplan-gmbh.de>
[-- Attachment #2: chrpmpc52x_bigone.patch.bz2 --]
[-- Type: application/x-bzip, Size: 24315 bytes --]
[-- Attachment #3: nd.vcf --]
[-- Type: text/x-vcard, Size: 249 bytes --]
begin:vcard
fn:Nicolas DET ( bplan GmbH )
n:DET;Nicolas
org:bplan GmbH
adr:;;;;;;Germany
email;internet:nd@bplan-gmbh.de
title:Software Entwicklung
tel;work:+49 6171 9187 - 31
x-mozilla-html:FALSE
url:http://www.bplan-gmbh.de
version:2.1
end:vcard
^ permalink raw reply
* [PATCH] CPM_UART: Fix non-console initialisation
From: kalle.pokki @ 2006-10-19 12:31 UTC (permalink / raw)
To: linuxppc-embedded, galak, panto, vbordug
If there is a frame buffer console, the cpm_uart_init_portdesc()
function is never called in the compat mode. Also, the set_lineif()
method is not called in the compat mode.
Signed-off-by: Kalle Pokki <kalle.pokki@iki.fi>
---
drivers/serial/cpm_uart/cpm_uart.h | 2 +-
drivers/serial/cpm_uart/cpm_uart_core.c | 9 ++++-----
drivers/serial/cpm_uart/cpm_uart_cpm1.c | 6 +++++-
drivers/serial/cpm_uart/cpm_uart_cpm2.c | 6 +++++-
4 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h
index 3b35cb7..19a6ffe 100644
--- a/drivers/serial/cpm_uart/cpm_uart.h
+++ b/drivers/serial/cpm_uart/cpm_uart.h
@@ -89,7 +89,7 @@ extern struct uart_cpm_port cpm_uart_por
/* these are located in their respective files */
void cpm_line_cr_cmd(int line, int cmd);
-int cpm_uart_init_portdesc(void);
+int __init cpm_uart_init_portdesc(void);
int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con);
void cpm_uart_freebuf(struct uart_cpm_port *pinfo);
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 8f3b3e5..895f2f1 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -1349,11 +1349,8 @@ static int cpm_uart_init(void) {
pr_info("cpm_uart: WARNING: no UART devices found on platform bus!\n");
pr_info(
"cpm_uart: the driver will guess configuration, but this mode is no longer supported.\n");
-#ifndef CONFIG_SERIAL_CPM_CONSOLE
- ret = cpm_uart_init_portdesc();
- if (ret)
- return ret;
-#endif
+
+ cpm_uart_init_portdesc();
cpm_reg.nr = cpm_uart_nr;
ret = uart_register_driver(&cpm_reg);
@@ -1365,6 +1362,8 @@ #endif
int con = cpm_uart_port_map[i];
cpm_uart_ports[con].port.line = i;
cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF;
+ if (cpm_uart_ports[con].set_lineif)
+ cpm_uart_ports[con].set_lineif(&cpm_uart_ports[con]);
uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port);
}
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
index 95afc37..6f04a9f 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -184,10 +184,14 @@ void cpm_uart_freebuf(struct uart_cpm_po
}
/* Setup any dynamic params in the uart desc */
-int cpm_uart_init_portdesc(void)
+int __init cpm_uart_init_portdesc(void)
{
pr_debug("CPM uart[-]:init portdesc\n");
+ /* Don't run this again, if the console driver did it already */
+ if (cpm_uart_nr > 0)
+ return 0;
+
cpm_uart_nr = 0;
#ifdef CONFIG_SERIAL_CPM_SMC1
cpm_uart_ports[UART_SMC1].smcp = &cpmp->cp_smc[0];
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index ef3bb47..0f21543 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -252,10 +252,14 @@ void cpm_uart_freebuf(struct uart_cpm_po
}
/* Setup any dynamic params in the uart desc */
-int cpm_uart_init_portdesc(void)
+int __init cpm_uart_init_portdesc(void)
{
pr_debug("CPM uart[-]:init portdesc\n");
+ /* Don't run this again, if the console driver did it already */
+ if (cpm_uart_nr > 0)
+ return 0;
+
cpm_uart_nr = 0;
#ifdef CONFIG_SERIAL_CPM_SMC1
cpm_uart_ports[UART_SMC1].smcp = (smc_t *) & cpm2_immr->im_smc[0];
--
1.4.1.1
^ permalink raw reply related
* Badness in irq_create_mapping at arch/powerpc/kernel/irq.c:527
From: Olaf Hering @ 2006-10-19 12:28 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel
I get irq warnings with current Linus tree on Pegasos.
The EDID handling for radeonfb appears to be broken as well,
but thats a different story:
Using CHRP machine description
Total memory = 256MB; using 512kB for hash table (at cff80000)
Linux version 2.6.19-rc2-git3-default (olaf@pomegranate) (gcc version 4.1.0 (SUSE Linux)) #1 Thu Oct 19 14:19:35 CEST 2006
Found legacy serial port 0 for /pci@80000000/isa@C/serial@i2F8
port=2f8, taddr=fe0002f8, irq=0, clk=1843200, speed=0
Entering add_active_range(0, 0, 65536) 0 entries of 256 used
chrp type = 6 [Genesi Pegasos]
Pegasos l2cr : L2 cache was not active, activating
PCI bus 0 controlled by /pci@80000000 at 80000000
PCI bus 0 controlled by /pci@C0000000 at c0000000
Top of RAM: 0x10000000, Total RAM: 0x10000000
Memory hole size: 0MB
Zone PFN ranges:
DMA 0 -> 65536
Normal 65536 -> 65536
HighMem 65536 -> 65536
early_node_map[1] active PFN ranges
0: 0 -> 65536
On node 0 totalpages: 65536
DMA zone: 512 pages used for memmap
DMA zone: 0 pages reserved
DMA zone: 65024 pages, LIFO batch:15
Normal zone: 0 pages used for memmap
HighMem zone: 0 pages used for memmap
Built 1 zonelists. Total pages: 65024
Kernel command line: root=/dev/hda7 quiet console=ttyS0,115200
i8259 legacy interrupt controller initialized
PID hash table entries: 1024 (order: 10, 4096 bytes)
time_init: decrementer frequency = 33.333333 MHz
time_init: processor frequency = 999.999990 MHz
Console: colour dummy device 80x25
Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
High memory: 0k
Memory: 254012k/262144k available (3768k kernel code, 7780k reserved, 540k data, 439k bss, 204k init)
Calibrating delay loop... 66.56 BogoMIPS (lpj=133120)
Security Framework v1.0.0 initialized
Mount-cache hash table entries: 512
device-tree: Duplicate name in /pci@80000000/usb@C,2/device@1, renamed to "data@1#1"
device-tree: Duplicate name in /pci@80000000/usb@C,2/device@1, renamed to "data@1#2"
NET: Registered protocol family 16
PCI: Probing PCI hardware
Boot video device is 0001:01:08.0
irq_create_mapping called for NULL host, hwirq=0
Badness in irq_create_mapping at /home/olaf/kernel/olh/pegasos/linux-2.6.19-rc2/arch/powerpc/kernel/irq.c:527
Call Trace:
[C06EDDF0] [C0008728] show_stack+0x50/0x184 (unreliable)
[C06EDE10] [C001126C] program_check_exception+0x194/0x54c
[C06EDE60] [C0012C10] ret_from_except_full+0x0/0x4c
--- Exception: 700 at irq_create_mapping+0x38/0x11c
LR = irq_create_mapping+0x38/0x11c
[C06EDF40] [C0015AFC] pci_read_irq_line+0x78/0xdc
[C06EDF70] [C038F828] chrp_pcibios_fixup+0x1c/0x48
[C06EDF80] [C03883A0] pcibios_init+0x100/0x224
[C06EDFA0] [C0003DB0] init+0x9c/0x268
[C06EDFF0] [C0013604] kernel_thread+0x44/0x60
irq_create_mapping called for NULL host, hwirq=9
Badness in irq_create_mapping at /home/olaf/kernel/olh/pegasos/linux-2.6.19-rc2/arch/powerpc/kernel/irq.c:527
Call Trace:
[C06EDDF0] [C0008728] show_stack+0x50/0x184 (unreliable)
[C06EDE10] [C001126C] program_check_exception+0x194/0x54c
[C06EDE60] [C0012C10] ret_from_except_full+0x0/0x4c
--- Exception: 700 at irq_create_mapping+0x38/0x11c
LR = irq_create_mapping+0x38/0x11c
[C06EDF40] [C0015AFC] pci_read_irq_line+0x78/0xdc
[C06EDF70] [C038F828] chrp_pcibios_fixup+0x1c/0x48
[C06EDF80] [C03883A0] pcibios_init+0x100/0x224
[C06EDFA0] [C0003DB0] init+0x9c/0x268
[C06EDFF0] [C0013604] kernel_thread+0x44/0x60
irq_create_mapping called for NULL host, hwirq=9
Badness in irq_create_mapping at /home/olaf/kernel/olh/pegasos/linux-2.6.19-rc2/arch/powerpc/kernel/irq.c:527
Call Trace:
[C06EDDF0] [C0008728] show_stack+0x50/0x184 (unreliable)
[C06EDE10] [C001126C] program_check_exception+0x194/0x54c
[C06EDE60] [C0012C10] ret_from_except_full+0x0/0x4c
--- Exception: 700 at irq_create_mapping+0x38/0x11c
LR = irq_create_mapping+0x38/0x11c
[C06EDF40] [C0015AFC] pci_read_irq_line+0x78/0xdc
[C06EDF70] [C038F828] chrp_pcibios_fixup+0x1c/0x48
[C06EDF80] [C03883A0] pcibios_init+0x100/0x224
[C06EDFA0] [C0003DB0] init+0x9c/0x268
[C06EDFF0] [C0013604] kernel_thread+0x44/0x60
irq_create_mapping called for NULL host, hwirq=e
Badness in irq_create_mapping at /home/olaf/kernel/olh/pegasos/linux-2.6.19-rc2/arch/powerpc/kernel/irq.c:527
Call Trace:
[C06EDDF0] [C0008728] show_stack+0x50/0x184 (unreliable)
[C06EDE10] [C001126C] program_check_exception+0x194/0x54c
[C06EDE60] [C0012C10] ret_from_except_full+0x0/0x4c
--- Exception: 700 at irq_create_mapping+0x38/0x11c
LR = irq_create_mapping+0x38/0x11c
[C06EDF40] [C0015AFC] pci_read_irq_line+0x78/0xdc
[C06EDF70] [C038F828] chrp_pcibios_fixup+0x1c/0x48
[C06EDF80] [C03883A0] pcibios_init+0x100/0x224
[C06EDFA0] [C0003DB0] init+0x9c/0x268
[C06EDFF0] [C0013604] kernel_thread+0x44/0x60
irq_create_mapping called for NULL host, hwirq=9
Badness in irq_create_mapping at /home/olaf/kernel/olh/pegasos/linux-2.6.19-rc2/arch/powerpc/kernel/irq.c:527
Call Trace:
[C06EDDF0] [C0008728] show_stack+0x50/0x184 (unreliable)
[C06EDE10] [C001126C] program_check_exception+0x194/0x54c
[C06EDE60] [C0012C10] ret_from_except_full+0x0/0x4c
--- Exception: 700 at irq_create_mapping+0x38/0x11c
LR = irq_create_mapping+0x38/0x11c
[C06EDF40] [C0015AFC] pci_read_irq_line+0x78/0xdc
[C06EDF70] [C038F828] chrp_pcibios_fixup+0x1c/0x48
[C06EDF80] [C03883A0] pcibios_init+0x100/0x224
[C06EDFA0] [C0003DB0] init+0x9c/0x268
[C06EDFF0] [C0013604] kernel_thread+0x44/0x60
irq_create_mapping called for NULL host, hwirq=9
Badness in irq_create_mapping at /home/olaf/kernel/olh/pegasos/linux-2.6.19-rc2/arch/powerpc/kernel/irq.c:527
Call Trace:
[C06EDDF0] [C0008728] show_stack+0x50/0x184 (unreliable)
[C06EDE10] [C001126C] program_check_exception+0x194/0x54c
[C06EDE60] [C0012C10] ret_from_except_full+0x0/0x4c
--- Exception: 700 at irq_create_mapping+0x38/0x11c
LR = irq_create_mapping+0x38/0x11c
[C06EDF40] [C0015AFC] pci_read_irq_line+0x78/0xdc
[C06EDF70] [C038F828] chrp_pcibios_fixup+0x1c/0x48
[C06EDF80] [C03883A0] pcibios_init+0x100/0x224
[C06EDFA0] [C0003DB0] init+0x9c/0x268
[C06EDFF0] [C0013604] kernel_thread+0x44/0x60
irq_create_mapping called for NULL host, hwirq=9
Badness in irq_create_mapping at /home/olaf/kernel/olh/pegasos/linux-2.6.19-rc2/arch/powerpc/kernel/irq.c:527
Call Trace:
[C06EDDF0] [C0008728] show_stack+0x50/0x184 (unreliable)
[C06EDE10] [C001126C] program_check_exception+0x194/0x54c
[C06EDE60] [C0012C10] ret_from_except_full+0x0/0x4c
--- Exception: 700 at irq_create_mapping+0x38/0x11c
LR = irq_create_mapping+0x38/0x11c
[C06EDF40] [C0015AFC] pci_read_irq_line+0x78/0xdc
[C06EDF70] [C038F828] chrp_pcibios_fixup+0x1c/0x48
[C06EDF80] [C03883A0] pcibios_init+0x100/0x224
[C06EDFA0] [C0003DB0] init+0x9c/0x268
[C06EDFF0] [C0013604] kernel_thread+0x44/0x60
irq_create_mapping called for NULL host, hwirq=9
Badness in irq_create_mapping at /home/olaf/kernel/olh/pegasos/linux-2.6.19-rc2/arch/powerpc/kernel/irq.c:527
Call Trace:
[C06EDDF0] [C0008728] show_stack+0x50/0x184 (unreliable)
[C06EDE10] [C001126C] program_check_exception+0x194/0x54c
[C06EDE60] [C0012C10] ret_from_except_full+0x0/0x4c
--- Exception: 700 at irq_create_mapping+0x38/0x11c
LR = irq_create_mapping+0x38/0x11c
[C06EDF40] [C0015AFC] pci_read_irq_line+0x78/0xdc
[C06EDF70] [C038F828] chrp_pcibios_fixup+0x1c/0x48
[C06EDF80] [C03883A0] pcibios_init+0x100/0x224
[C06EDFA0] [C0003DB0] init+0x9c/0x268
[C06EDFF0] [C0013604] kernel_thread+0x44/0x60
irq_create_mapping called for NULL host, hwirq=9
Badness in irq_create_mapping at /home/olaf/kernel/olh/pegasos/linux-2.6.19-rc2/arch/powerpc/kernel/irq.c:527
Call Trace:
[C06EDDF0] [C0008728] show_stack+0x50/0x184 (unreliable)
[C06EDE10] [C001126C] program_check_exception+0x194/0x54c
[C06EDE60] [C0012C10] ret_from_except_full+0x0/0x4c
--- Exception: 700 at irq_create_mapping+0x38/0x11c
LR = irq_create_mapping+0x38/0x11c
[C06EDF40] [C0015AFC] pci_read_irq_line+0x78/0xdc
[C06EDF70] [C038F828] chrp_pcibios_fixup+0x1c/0x48
[C06EDF80] [C03883A0] pcibios_init+0x100/0x224
[C06EDFA0] [C0003DB0] init+0x9c/0x268
[C06EDFF0] [C0013604] kernel_thread+0x44/0x60
irq_create_mapping called for NULL host, hwirq=0
Badness in irq_create_mapping at /home/olaf/kernel/olh/pegasos/linux-2.6.19-rc2/arch/powerpc/kernel/irq.c:527
Call Trace:
[C06EDDF0] [C0008728] show_stack+0x50/0x184 (unreliable)
[C06EDE10] [C001126C] program_check_exception+0x194/0x54c
[C06EDE60] [C0012C10] ret_from_except_full+0x0/0x4c
--- Exception: 700 at irq_create_mapping+0x38/0x11c
LR = irq_create_mapping+0x38/0x11c
[C06EDF40] [C0015AFC] pci_read_irq_line+0x78/0xdc
[C06EDF70] [C038F828] chrp_pcibios_fixup+0x1c/0x48
[C06EDF80] [C03883A0] pcibios_init+0x100/0x224
[C06EDFA0] [C0003DB0] init+0x9c/0x268
[C06EDFF0] [C0013604] kernel_thread+0x44/0x60
irq_create_mapping called for NULL host, hwirq=9
Badness in irq_create_mapping at /home/olaf/kernel/olh/pegasos/linux-2.6.19-rc2/arch/powerpc/kernel/irq.c:527
Call Trace:
[C06EDDF0] [C0008728] show_stack+0x50/0x184 (unreliable)
[C06EDE10] [C001126C] program_check_exception+0x194/0x54c
[C06EDE60] [C0012C10] ret_from_except_full+0x0/0x4c
--- Exception: 700 at irq_create_mapping+0x38/0x11c
LR = irq_create_mapping+0x38/0x11c
[C06EDF40] [C0015AFC] pci_read_irq_line+0x78/0xdc
[C06EDF70] [C038F828] chrp_pcibios_fixup+0x1c/0x48
[C06EDF80] [C03883A0] pcibios_init+0x100/0x224
[C06EDFA0] [C0003DB0] init+0x9c/0x268
[C06EDFF0] [C0013604] kernel_thread+0x44/0x60
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
NET: Registered protocol family 2
IP route cache hash table entries: 2048 (order: 1, 8192 bytes)
TCP established hash table entries: 8192 (order: 3, 32768 bytes)
TCP bind hash table entries: 4096 (order: 2, 16384 bytes)
TCP: Hash tables configured (established 8192 bind 4096)
TCP reno registered
Thermal assist unit not available
audit: initializing netlink socket (disabled)
audit(1161260512.148:1): initialized
VFS: Disk quotas dquot_6.5.1
Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered (default)
__ioremap(): phys addr 000c0000 is RAM lr c016d7bc
radeonfb (0001:01:08.0): ROM failed to map
radeonfb: No ATY,RefCLK property !
xtal calculation failed: 22967
radeonfb: Used default PLL infos
radeonfb: Reference=27.00 MHz (RefDiv=12) Memory=166.00 Mhz, System=166.00 MHz
radeonfb: PLL min 12000 max 35000
i2c_adapter i2c-1: unable to read EDID block.
i2c_adapter i2c-1: unable to read EDID block.
i2c_adapter i2c-1: unable to read EDID block.
i2c_adapter i2c-3: unable to read EDID block.
i2c_adapter i2c-3: unable to read EDID block.
i2c_adapter i2c-3: unable to read EDID block.
i2c_adapter i2c-2: unable to read EDID block.
i2c_adapter i2c-2: unable to read EDID block.
i2c_adapter i2c-2: unable to read EDID block.
i2c_adapter i2c-3: unable to read EDID block.
i2c_adapter i2c-3: unable to read EDID block.
i2c_adapter i2c-3: unable to read EDID block.
radeonfb: Monitor 1 type CRT found
radeonfb: Monitor 2 type no found
Console: switching to colour frame buffer device 80x30
radeonfb (0001:01:08.0): ATI Radeon Yd
can't get 2 addresses for control
Generic RTC Driver v1.07
Macintosh non-volatile memory driver v1.1
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing disabled
serial8250.0: ttyS0 at I/O 0x2f8 (irq = 0) is a 16550A
pmac_zilog: 0.6 (Benjamin Herrenschmidt <benh@kernel.crashing.org>)
parport_pc: VIA 686A/8231 detected
parport_pc: probing current configuration
parport_pc: Current parallel port base: 0x3BC
parport0: PC-style at 0x3bc, irq 7 [PCSPP]
parport_pc: VIA parallel port: io=0x3BC, irq=7
RAMDISK driver initialized: 16 RAM disks of 123456K size 1024 blocksize
loop: loaded (max 8 devices)
MV-643xx 10/100/1000 Ethernet Driver
eth0: port 1 with MAC address 00:2b:2f:de:ad:01
eth0: Scatter Gather Enabled
eth0: TX TCP/IP Checksumming Supported
eth0: RX TCP/UDP Checksum Offload ON
eth0: RX NAPI Enabled
eth0: Using SRAM
input: Macintosh mouse button emulation as /class/input/input0
apm_emu: Requires a machine with a PMU.
Warning: no ADB interface detected
Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2
ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx
VP_IDE: IDE controller at PCI slot 0000:00:0c.1
VP_IDE: chipset revision 6
VP_IDE: VIA vt8231 (rev 10) IDE UDMA100 controller on pci0000:00:0c.1
VP_IDE: 100% native mode on irq 14
ide0: BM-DMA at 0x1020-0x1027, BIOS settings: hda:pio, hdb:pio
ide1: BM-DMA at 0x1028-0x102f, BIOS settings: hdc:pio, hdd:pio
Probing IDE interface ide0...
hda: ST340014A, ATA DISK drive
ide0 at 0x1000-0x1007,0x100e on irq 14
Probing IDE interface ide1...
hdc: SAMSUNG CDRW/DVD SM-352N, ATAPI CD/DVD-ROM drive
ide1 at 0x1010-0x1017,0x101e on irq 15
hda: max request size: 512KiB
hda: 78165360 sectors (40020 MB) w/2048KiB Cache, CHS=16383/255/63, UDMA(100)
hda: cache flushes supported
hda: RDSK (512) hda1 (DOS^A)(res 2 spb 1) hda2 (DOS^E)(res 2 spb 2) hda3 (DOS^E)(res 2 spb 2) hda4 (LNX^@)(res 2 spb 1) hda5 (LNX^@)(res 2 spb 1) hda6 (SWP^@)(res 2 spb 1) hda7 (LNX^@)(res 2 spb 1) hda8 (LNX^@)(res 2 spb 1)
hdc: ATAPI 52X DVD-ROM CD-R/RW drive, 2048kB Cache, UDMA(33)
Uniform CD-ROM driver Revision: 3.20
ohci_hcd: 2006 August 04 USB 1.1 'Open' Host Controller (OHCI) Driver (PCI)
usbcore: registered new interface driver hiddev
usbcore: registered new interface driver usbhid
/home/olaf/kernel/olh/pegasos/linux-2.6.19-rc2/drivers/usb/input/hid-core.c: v2.6:USB HID core driver
usbcore: registered new interface driver appletouch
serio: i8042 KBD port at 0x60,0x64 irq 1
serio: i8042 AUX port at 0x60,0x64 irq 12
mice: PS/2 mouse device common for all mice
atkbd.c: keyboard reset failed on isa0060/serio0
atkbd.c: keyboard reset failed on isa0060/serio1
NET: Registered protocol family 1
NET: Registered protocol family 17
md: Autodetecting RAID arrays.
md: autorun ...
md: ... autorun DONE.
kjournald starting. Commit interval 5 seconds
EXT3-fs: mounted filesystem with ordered data mode.
VFS: Mounted root (ext3 filesystem) readonly.
Freeing unused kernel memory: 204k init
warning: process `showconsole' used the removed sysctl system call
warning: process `showconsole' used the removed sysctl system call
EXT3 FS on hda7, internal journal
warning: process `ls' used the removed sysctl system call
warning: process `ls' used the removed sysctl system call
warning: process `showconsole' used the removed sysctl system call
Adding 976744k swap on /dev/hda6. Priority:-1 extents:1 across:976744k
audit(1161260543.595:2): audit_pid=2357 old=0 by auid=4294967295
^ permalink raw reply
* Re: status of mpc52xx with arch=powerpc?
From: Roman Fietze @ 2006-10-19 9:49 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <20061019081337.GF6202@localhost.localdomain>
[-- Attachment #1: Type: text/plain, Size: 1489 bytes --]
Hello,
On Thursday 19 October 2006 10:13, Sascha Hauer wrote:
> Could you post your .dts?
> I'm too working on it, so maybe we should stay synchronized. At the
> moment I have nothing but a minimal dts and some .progress() messages.
Could you both double check e.g. with Sylvain Munaut at
http://246tnt.com/mpc52xx/
There are many drivers (git heads) available already, including IDE,
FEC, and so on. There's also new BestComm/FEC/IDE code from Dale
Farnsworth and John Rigby (Freescale) somewhere on the net.
I've already opened my own branch using DENX 2.6 and several patches
from Sylvain, Dale and John and got a first working 2.6 for the
MPC5200 including DMA driven FEC and IDE. Sylvain promised to get in
touch with the 2.6 maintainers to incorporate his changes into vanilla
2.6. I don't know if he still works on that since his server crashed a
few months ago, that's why I didn't do anything about it.
Here's a part of a mail I got from John in 2006-05:
"Sylvain Munaut is working on a different bestcomm patch. It's much
cleaner and is based on bestcomm code written by Dale Farnsworth.
You can search the mailing list for a pointer to Sylvain's git tree."
I assume that's what I have here, spinning around with 15k for a few
months now.
Roman
--
Roman Fietze Telemotive AG Büro Mühlhausen
Breitwiesen 73347 Mühlhausen
Tel.: +49(0)7335/18493-45 http://www.telemotive.de
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: status of mpc52xx with arch=powerpc?
From: Sascha Hauer @ 2006-10-19 8:13 UTC (permalink / raw)
To: Grant Likely; +Cc: linuxppc-embedded
In-Reply-To: <528646bc0610180652u2ee8e8b4xe25d555a59a27c85@mail.gmail.com>
On Wed, Oct 18, 2006 at 07:52:02AM -0600, Grant Likely wrote:
> On 10/18/06, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> >Is someone working on this already?
> >
> >There are some Kconfig entries, but there seems to be no code, at least
> >not in vanilla.
>
> I'm slowly working on it. I've got a .dts written and I've got u-boot
> w/ the fdt patches running on the board. I need to port the 52xx PIC
> driver into arch/powerpc before I attempt to boot.
Could you post your .dts?
I'm too working on it, so maybe we should stay synchronized. At the
moment I have nothing but a minimal dts and some .progress() messages.
Sascha
--
Dipl.-Ing. Sascha Hauer | http://www.pengutronix.de
Pengutronix - Linux Solutions for Science and Industry
Handelsregister: Amtsgericht Hildesheim, HRA 2686
Hannoversche Str. 2, 31134 Hildesheim, Germany
Phone: +49-5121-206917-0 | Fax: +49-5121-206917-9
^ permalink raw reply
* [PATCH/RFC] Refactor powerpc DMA ops (#2)
From: Benjamin Herrenschmidt @ 2006-10-19 8:06 UTC (permalink / raw)
To: linuxppc-dev list
In-Reply-To: <1161158225.23947.22.camel@localhost.localdomain>
This patch completely refactors DMA operations for 64 bits powerpc. 32 bits
is untouched for now.
The basic idea is to define an auxilliary structure (struct device_ext) that
can be attached to any struct device in the system. We use the "firmware_data"
pointer to reference it for now, though I kept that very isolated so I can
change it in the future, especially if I get my way with Greg KH and add a
sysdata pointer to struct device instead or even better, embed it inside
struct device to limit the number of pointer indirections.
This structure holds the optional OF device node pointer, the DMA ops and
associated void *data (to be used by the ops, typically, the iommu table
pointer for machines with more than one), and a numa node id (if useful)
to constraint consistent memory allocs. In the future, I might also merge
the current pci_dn into it for PCI.
The old vio, pci-iommu and pci-direct DMA ops are gone. They are now replaced
by a set of generic iommu and direct DMA ops (non PCI specific) that can be
used by bus types. The toplevel implementation is now inline.
In the case of busses we control completely, like vio, the bus layer will
create and fill this structure and all is easy (see the changes to vio.c
or ebus).
In the case of "foreign" busses like PCI, what I've done is that I create
the data structure in the PCI fixup code (which is run after discovery but
before the struct device is actually registered with the core, as PCI keeps
those two steps separate) and use the old ppc_md. callbacks that I renamed
for consistency, to setup the iommu table pointer if necessary. By default
the dma_ops are set to the content of a global pci_dma_ops that your platform
can set. So if you have no iommu, you can just set that dma_direct_ops and
not implement any of the callbacks.
I do have plans to move away from that model for PCI, and consolidate this
with pci_dn, while make everybody use the platform notifiers provided by
the device core upon device registration but this goes beyond the goal of
this patch.
This version is more finished than yesterday's (though it still need more
testing). I'm also pondering splitting the addition of the device extension
(without dma ops fields in it) from the actual DMA operations refactoring,
though that would be a painful patch splitting work.
Oh, and :
23 files changed, 561 insertions(+), 580 deletions(-)
Despite my tendency to add verbose comments :)
Comments much welcome,
Ben.
Index: linux-cell/include/asm-powerpc/device_ext.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-cell/include/asm-powerpc/device_ext.h 2006-10-19 17:37:59.000000000 +1000
@@ -0,0 +1,43 @@
+#ifndef _POWERPC_DEVICE_EXT_H
+#define _POWERPC_DEVICE_EXT_H
+#ifdef __KERNEL__
+
+struct dma_mapping_ops;
+struct device_node;
+
+/*
+ * Auxilliary data structure that can be attached to any struct device
+ * in the system. (Currently using firmware_data, though I'd like to
+ * see a system_data in there instead).
+ *
+ * The structure can be wrapped within a bus-type specific data structure.
+ *
+ * There are no strict lifetime rules for this structure, it's entirely up
+ * to the bus to manage it's lifetime.
+ */
+struct device_ext {
+ /* Optional pointer to an OF device node */
+ struct device_node *of_node;
+
+ /* DMA operations on that device */
+ struct dma_mapping_ops *dma_ops;
+ void *dma_data;
+
+ /* NUMA node if applicable */
+ int numa_node;
+};
+
+/* Provide accessors in case we move it to some other field */
+static inline struct device_ext *device_get_ext(const struct device *dev)
+{
+ return dev->firmware_data;
+}
+
+static inline void device_set_ext(struct device *dev, struct device_ext *ext)
+{
+ dev->firmware_data = ext;
+}
+
+
+#endif /* __KERNEL__ */
+#endif /* _POWERPC_DEVICE_EXT_H */
Index: linux-cell/arch/powerpc/kernel/dma_64.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/dma_64.c 2006-10-19 17:37:56.000000000 +1000
+++ linux-cell/arch/powerpc/kernel/dma_64.c 2006-10-19 17:37:59.000000000 +1000
@@ -1,151 +1,204 @@
/*
- * Copyright (C) 2004 IBM Corporation
+ * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corporation
*
- * Implements the generic device dma API for ppc64. Handles
- * the pci and vio busses
+ * Provide default implementations of the DMA mapping callbacks for
+ * directly mapped busses and busses using the iommu infrastructure
*/
#include <linux/device.h>
#include <linux/dma-mapping.h>
-/* Include the busses we support */
-#include <linux/pci.h>
-#include <asm/vio.h>
-#include <asm/ibmebus.h>
-#include <asm/scatterlist.h>
#include <asm/bug.h>
+#include <asm/iommu.h>
+#include <asm/abs_addr.h>
-static struct dma_mapping_ops *get_dma_ops(struct device *dev)
+/*
+ * Generic iommu implementation
+ */
+
+static inline unsigned long device_to_mask(struct device *dev)
{
-#ifdef CONFIG_PCI
- if (dev->bus == &pci_bus_type)
- return &pci_dma_ops;
-#endif
-#ifdef CONFIG_IBMVIO
- if (dev->bus == &vio_bus_type)
- return &vio_dma_ops;
-#endif
-#ifdef CONFIG_IBMEBUS
- if (dev->bus == &ibmebus_bus_type)
- return &ibmebus_dma_ops;
-#endif
- return NULL;
+ if (dev->dma_mask && *dev->dma_mask)
+ return *dev->dma_mask;
+ /* Assume devices without mask can take 32 bit addresses */
+ return 0xfffffffful;
}
-int dma_supported(struct device *dev, u64 mask)
-{
- struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
- BUG_ON(!dma_ops);
+/* Allocates a contiguous real buffer and creates mappings over it.
+ * Returns the virtual address of the buffer and sets dma_handle
+ * to the dma address (mapping) of the first page.
+ */
+static void *dma_iommu_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag)
+{
+ struct device_ext *dext = device_get_ext(dev);
- return dma_ops->dma_supported(dev, mask);
+ if (unlikely(dext == NULL))
+ return NULL;
+ return iommu_alloc_coherent(dext->dma_data, size, dma_handle,
+ device_to_mask(dev), flag,
+ dext->numa_node);
}
-EXPORT_SYMBOL(dma_supported);
-int dma_set_mask(struct device *dev, u64 dma_mask)
+static void dma_iommu_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
{
-#ifdef CONFIG_PCI
- if (dev->bus == &pci_bus_type)
- return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
-#endif
-#ifdef CONFIG_IBMVIO
- if (dev->bus == &vio_bus_type)
- return -EIO;
-#endif /* CONFIG_IBMVIO */
-#ifdef CONFIG_IBMEBUS
- if (dev->bus == &ibmebus_bus_type)
- return -EIO;
-#endif
- BUG();
- return 0;
+ struct device_ext *dext = device_get_ext(dev);
+
+ if (unlikely(dext == NULL))
+ return;
+ iommu_free_coherent(dext->dma_data, size, vaddr, dma_handle);
}
-EXPORT_SYMBOL(dma_set_mask);
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag)
+/* Creates TCEs for a user provided buffer. The user buffer must be
+ * contiguous real kernel storage (not vmalloc). The address of the buffer
+ * passed here is the kernel (virtual) address of the buffer. The buffer
+ * need not be page aligned, the dma_addr_t returned will point to the same
+ * byte within the page as vaddr.
+ */
+static dma_addr_t dma_iommu_map_single(struct device *dev, void *vaddr,
+ size_t size,
+ enum dma_data_direction direction)
{
- struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+ struct device_ext *dext = device_get_ext(dev);
- BUG_ON(!dma_ops);
-
- return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
+ if (unlikely(dext == NULL))
+ return DMA_ERROR_CODE;
+ return iommu_map_single(dext->dma_data, vaddr, size,
+ device_to_mask(dev), direction);
}
-EXPORT_SYMBOL(dma_alloc_coherent);
-void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
- dma_addr_t dma_handle)
-{
- struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
- BUG_ON(!dma_ops);
+static void dma_iommu_unmap_single(struct device *dev, dma_addr_t dma_handle,
+ size_t size,
+ enum dma_data_direction direction)
+{
+ struct device_ext *dext = device_get_ext(dev);
- dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
+ if (unlikely(dext == NULL))
+ return;
+ iommu_unmap_single(dext->dma_data, dma_handle, size, direction);
}
-EXPORT_SYMBOL(dma_free_coherent);
-dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size,
- enum dma_data_direction direction)
-{
- struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
- BUG_ON(!dma_ops);
+static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
+ int nelems, enum dma_data_direction direction)
+{
+ struct device_ext *dext = device_get_ext(dev);
- return dma_ops->map_single(dev, cpu_addr, size, direction);
+ if (unlikely(dext == NULL))
+ return -ENXIO;
+ return iommu_map_sg(dext->dma_data, sglist, nelems,
+ device_to_mask(dev), direction);
}
-EXPORT_SYMBOL(dma_map_single);
-void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
- enum dma_data_direction direction)
+static void dma_iommu_unmap_sg(struct device *dev, struct scatterlist *sglist,
+ int nelems, enum dma_data_direction direction)
{
- struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
- BUG_ON(!dma_ops);
+ struct device_ext *dext = device_get_ext(dev);
- dma_ops->unmap_single(dev, dma_addr, size, direction);
+ if (unlikely(dext == NULL))
+ return;
+ iommu_unmap_sg(dext->dma_data, sglist, nelems, direction);
}
-EXPORT_SYMBOL(dma_unmap_single);
-dma_addr_t dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
- enum dma_data_direction direction)
+/* We support DMA to/from any memory page via the iommu */
+static int dma_iommu_dma_supported(struct device *dev, u64 mask)
{
- struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+ struct device_ext *dext = device_get_ext(dev);
+ struct iommu_table *tbl = dext->dma_data;
- BUG_ON(!dma_ops);
+ if (!tbl || tbl->it_offset > mask) {
+ printk(KERN_INFO "Warning: IOMMU table offset too big for device mask\n");
+ if (tbl)
+ printk(KERN_INFO "mask: 0x%08lx, table offset: 0x%08lx\n",
+ mask, tbl->it_offset);
+ else
+ printk(KERN_INFO "mask: 0x%08lx, table unavailable\n",
+ mask);
+ return 0;
+ } else
+ return 1;
+}
- return dma_ops->map_single(dev, page_address(page) + offset, size,
- direction);
+struct dma_mapping_ops dma_iommu_ops = {
+ .alloc_coherent = dma_iommu_alloc_coherent,
+ .free_coherent = dma_iommu_free_coherent,
+ .map_single = dma_iommu_map_single,
+ .unmap_single = dma_iommu_unmap_single,
+ .map_sg = dma_iommu_map_sg,
+ .unmap_sg = dma_iommu_unmap_sg,
+ .dma_supported = dma_iommu_dma_supported,
+};
+EXPORT_SYMBOL(dma_iommu_ops);
+
+/*
+ * Generic direct DMA implementation
+ */
+
+static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag)
+{
+ void *ret;
+
+ /* TODO: Maybe use the numa node here too ? */
+ ret = (void *)__get_free_pages(flag, get_order(size));
+ if (ret != NULL) {
+ memset(ret, 0, size);
+ *dma_handle = virt_to_abs(ret);
+ }
+ return ret;
}
-EXPORT_SYMBOL(dma_map_page);
-void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
- enum dma_data_direction direction)
+static void dma_direct_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
{
- struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+ free_pages((unsigned long)vaddr, get_order(size));
+}
- BUG_ON(!dma_ops);
+static dma_addr_t dma_direct_map_single(struct device *dev, void *ptr,
+ size_t size,
+ enum dma_data_direction direction)
+{
+ return virt_to_abs(ptr);
+}
- dma_ops->unmap_single(dev, dma_address, size, direction);
+static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr,
+ size_t size,
+ enum dma_data_direction direction)
+{
}
-EXPORT_SYMBOL(dma_unmap_page);
-int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction direction)
+static int dma_direct_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction)
{
- struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+ int i;
- BUG_ON(!dma_ops);
+ for (i = 0; i < nents; i++, sg++) {
+ sg->dma_address = page_to_phys(sg->page) + sg->offset;
+ sg->dma_length = sg->length;
+ }
- return dma_ops->map_sg(dev, sg, nents, direction);
+ return nents;
}
-EXPORT_SYMBOL(dma_map_sg);
-void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
- enum dma_data_direction direction)
+static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction)
{
- struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
-
- BUG_ON(!dma_ops);
+}
- dma_ops->unmap_sg(dev, sg, nhwentries, direction);
+static int dma_direct_dma_supported(struct device *dev, u64 mask)
+{
+ return mask < 0x100000000ull;
}
-EXPORT_SYMBOL(dma_unmap_sg);
+
+struct dma_mapping_ops dma_direct_ops = {
+ .alloc_coherent = dma_direct_alloc_coherent,
+ .free_coherent = dma_direct_free_coherent,
+ .map_single = dma_direct_map_single,
+ .unmap_single = dma_direct_unmap_single,
+ .map_sg = dma_direct_map_sg,
+ .unmap_sg = dma_direct_unmap_sg,
+ .dma_supported = dma_direct_dma_supported,
+};
+EXPORT_SYMBOL(dma_direct_ops);
Index: linux-cell/arch/powerpc/kernel/iommu.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/iommu.c 2006-10-19 17:37:56.000000000 +1000
+++ linux-cell/arch/powerpc/kernel/iommu.c 2006-10-19 17:37:59.000000000 +1000
@@ -247,9 +247,9 @@ static void iommu_free(struct iommu_tabl
spin_unlock_irqrestore(&(tbl->it_lock), flags);
}
-int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
- struct scatterlist *sglist, int nelems,
- unsigned long mask, enum dma_data_direction direction)
+int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
+ int nelems, unsigned long mask,
+ enum dma_data_direction direction)
{
dma_addr_t dma_next = 0, dma_addr;
unsigned long flags;
Index: linux-cell/arch/powerpc/kernel/pci_direct_iommu.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/pci_direct_iommu.c 2006-10-19 17:37:56.000000000 +1000
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,98 +0,0 @@
-/*
- * Support for DMA from PCI devices to main memory on
- * machines without an iommu or with directly addressable
- * RAM (typically a pmac with 2Gb of RAM or less)
- *
- * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org)
- *
- * 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 <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/bootmem.h>
-#include <linux/mm.h>
-#include <linux/dma-mapping.h>
-
-#include <asm/sections.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/pci-bridge.h>
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <asm/abs_addr.h>
-#include <asm/ppc-pci.h>
-
-static void *pci_direct_alloc_coherent(struct device *hwdev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag)
-{
- void *ret;
-
- ret = (void *)__get_free_pages(flag, get_order(size));
- if (ret != NULL) {
- memset(ret, 0, size);
- *dma_handle = virt_to_abs(ret);
- }
- return ret;
-}
-
-static void pci_direct_free_coherent(struct device *hwdev, size_t size,
- void *vaddr, dma_addr_t dma_handle)
-{
- free_pages((unsigned long)vaddr, get_order(size));
-}
-
-static dma_addr_t pci_direct_map_single(struct device *hwdev, void *ptr,
- size_t size, enum dma_data_direction direction)
-{
- return virt_to_abs(ptr);
-}
-
-static void pci_direct_unmap_single(struct device *hwdev, dma_addr_t dma_addr,
- size_t size, enum dma_data_direction direction)
-{
-}
-
-static int pci_direct_map_sg(struct device *hwdev, struct scatterlist *sg,
- int nents, enum dma_data_direction direction)
-{
- int i;
-
- for (i = 0; i < nents; i++, sg++) {
- sg->dma_address = page_to_phys(sg->page) + sg->offset;
- sg->dma_length = sg->length;
- }
-
- return nents;
-}
-
-static void pci_direct_unmap_sg(struct device *hwdev, struct scatterlist *sg,
- int nents, enum dma_data_direction direction)
-{
-}
-
-static int pci_direct_dma_supported(struct device *dev, u64 mask)
-{
- return mask < 0x100000000ull;
-}
-
-static struct dma_mapping_ops pci_direct_ops = {
- .alloc_coherent = pci_direct_alloc_coherent,
- .free_coherent = pci_direct_free_coherent,
- .map_single = pci_direct_map_single,
- .unmap_single = pci_direct_unmap_single,
- .map_sg = pci_direct_map_sg,
- .unmap_sg = pci_direct_unmap_sg,
- .dma_supported = pci_direct_dma_supported,
-};
-
-void __init pci_direct_iommu_init(void)
-{
- pci_dma_ops = pci_direct_ops;
-}
Index: linux-cell/arch/powerpc/kernel/pci_iommu.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/pci_iommu.c 2006-10-19 17:37:56.000000000 +1000
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
- *
- * Rewrite, cleanup, new allocation schemes:
- * Copyright (C) 2004 Olof Johansson, IBM Corporation
- *
- * Dynamic DMA mapping support, platform-independent parts.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/spinlock.h>
-#include <linux/string.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/iommu.h>
-#include <asm/pci-bridge.h>
-#include <asm/machdep.h>
-#include <asm/ppc-pci.h>
-
-/*
- * We can use ->sysdata directly and avoid the extra work in
- * pci_device_to_OF_node since ->sysdata will have been initialised
- * in the iommu init code for all devices.
- */
-#define PCI_GET_DN(dev) ((struct device_node *)((dev)->sysdata))
-
-static inline struct iommu_table *device_to_table(struct device *hwdev)
-{
- struct pci_dev *pdev;
-
- if (!hwdev) {
- pdev = ppc64_isabridge_dev;
- if (!pdev)
- return NULL;
- } else
- pdev = to_pci_dev(hwdev);
-
- return PCI_DN(PCI_GET_DN(pdev))->iommu_table;
-}
-
-
-static inline unsigned long device_to_mask(struct device *hwdev)
-{
- struct pci_dev *pdev;
-
- if (!hwdev) {
- pdev = ppc64_isabridge_dev;
- if (!pdev) /* This is the best guess we can do */
- return 0xfffffffful;
- } else
- pdev = to_pci_dev(hwdev);
-
- if (pdev->dma_mask)
- return pdev->dma_mask;
-
- /* Assume devices without mask can take 32 bit addresses */
- return 0xfffffffful;
-}
-
-
-/* Allocates a contiguous real buffer and creates mappings over it.
- * Returns the virtual address of the buffer and sets dma_handle
- * to the dma address (mapping) of the first page.
- */
-static void *pci_iommu_alloc_coherent(struct device *hwdev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag)
-{
- return iommu_alloc_coherent(device_to_table(hwdev), size, dma_handle,
- device_to_mask(hwdev), flag,
- pcibus_to_node(to_pci_dev(hwdev)->bus));
-}
-
-static void pci_iommu_free_coherent(struct device *hwdev, size_t size,
- void *vaddr, dma_addr_t dma_handle)
-{
- iommu_free_coherent(device_to_table(hwdev), size, vaddr, dma_handle);
-}
-
-/* Creates TCEs for a user provided buffer. The user buffer must be
- * contiguous real kernel storage (not vmalloc). The address of the buffer
- * passed here is the kernel (virtual) address of the buffer. The buffer
- * need not be page aligned, the dma_addr_t returned will point to the same
- * byte within the page as vaddr.
- */
-static dma_addr_t pci_iommu_map_single(struct device *hwdev, void *vaddr,
- size_t size, enum dma_data_direction direction)
-{
- return iommu_map_single(device_to_table(hwdev), vaddr, size,
- device_to_mask(hwdev), direction);
-}
-
-
-static void pci_iommu_unmap_single(struct device *hwdev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction direction)
-{
- iommu_unmap_single(device_to_table(hwdev), dma_handle, size, direction);
-}
-
-
-static int pci_iommu_map_sg(struct device *pdev, struct scatterlist *sglist,
- int nelems, enum dma_data_direction direction)
-{
- return iommu_map_sg(pdev, device_to_table(pdev), sglist,
- nelems, device_to_mask(pdev), direction);
-}
-
-static void pci_iommu_unmap_sg(struct device *pdev, struct scatterlist *sglist,
- int nelems, enum dma_data_direction direction)
-{
- iommu_unmap_sg(device_to_table(pdev), sglist, nelems, direction);
-}
-
-/* We support DMA to/from any memory page via the iommu */
-static int pci_iommu_dma_supported(struct device *dev, u64 mask)
-{
- struct iommu_table *tbl = device_to_table(dev);
-
- if (!tbl || tbl->it_offset > mask) {
- printk(KERN_INFO "Warning: IOMMU table offset too big for device mask\n");
- if (tbl)
- printk(KERN_INFO "mask: 0x%08lx, table offset: 0x%08lx\n",
- mask, tbl->it_offset);
- else
- printk(KERN_INFO "mask: 0x%08lx, table unavailable\n",
- mask);
- return 0;
- } else
- return 1;
-}
-
-struct dma_mapping_ops pci_iommu_ops = {
- .alloc_coherent = pci_iommu_alloc_coherent,
- .free_coherent = pci_iommu_free_coherent,
- .map_single = pci_iommu_map_single,
- .unmap_single = pci_iommu_unmap_single,
- .map_sg = pci_iommu_map_sg,
- .unmap_sg = pci_iommu_unmap_sg,
- .dma_supported = pci_iommu_dma_supported,
-};
-
-void pci_iommu_init(void)
-{
- pci_dma_ops = pci_iommu_ops;
-}
Index: linux-cell/include/asm-powerpc/dma-mapping.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/dma-mapping.h 2006-10-19 17:37:56.000000000 +1000
+++ linux-cell/include/asm-powerpc/dma-mapping.h 2006-10-19 17:37:59.000000000 +1000
@@ -14,6 +14,7 @@
#include <linux/mm.h>
#include <asm/scatterlist.h>
#include <asm/io.h>
+#include <asm/device_ext.h>
#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
@@ -44,26 +45,152 @@ extern void __dma_sync_page(struct page
#endif /* ! CONFIG_NOT_COHERENT_CACHE */
#ifdef CONFIG_PPC64
+/*
+ * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO
+ */
+struct dma_mapping_ops {
+ void * (*alloc_coherent)(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag);
+ void (*free_coherent)(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle);
+ dma_addr_t (*map_single)(struct device *dev, void *ptr,
+ size_t size, enum dma_data_direction direction);
+ void (*unmap_single)(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction direction);
+ int (*map_sg)(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction);
+ void (*unmap_sg)(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction);
+ int (*dma_supported)(struct device *dev, u64 mask);
+ int (*dac_dma_supported)(struct device *dev, u64 mask);
+ int (*set_dma_mask)(struct device *dev, u64 dma_mask);
+};
+
+static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
+{
+ struct device_ext *dext;
+
+ /* We don't handle the NULL dev case for ISA for now. We could
+ * do it via an out of line call but it is not needed for now
+ */
+ if (dev == NULL)
+ return NULL;
+
+ dext = device_get_ext(dev);
+ if (unlikely(dext == NULL))
+ return NULL;
+ return dext->dma_ops;
+}
+
+static inline int dma_supported(struct device *dev, u64 mask)
+{
+ struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+ if (unlikely(dma_ops == NULL))
+ return 0;
+ if (dma_ops->dma_supported == NULL)
+ return 1;
+ return dma_ops->dma_supported(dev, mask);
+}
+
+static inline int dma_set_mask(struct device *dev, u64 dma_mask)
+{
+ struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+ if (unlikely(dma_ops == NULL))
+ return -EIO;
+ if (dma_ops->set_dma_mask != NULL)
+ return dma_ops->set_dma_mask(dev, dma_mask);
+ if (!dev->dma_mask || !dma_supported(dev, *dev->dma_mask))
+ return -EIO;
+ *dev->dma_mask = dma_mask;
+ return 0;
+}
+
+static inline void *dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag)
+{
+ struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+ BUG_ON(!dma_ops);
+ return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
+}
+
+static inline void dma_free_coherent(struct device *dev, size_t size,
+ void *cpu_addr, dma_addr_t dma_handle)
+{
+ struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+ BUG_ON(!dma_ops);
+ dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
+}
+
+static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
+ size_t size,
+ enum dma_data_direction direction)
+{
+ struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+ BUG_ON(!dma_ops);
+ return dma_ops->map_single(dev, cpu_addr, size, direction);
+}
+
+static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
+ size_t size,
+ enum dma_data_direction direction)
+{
+ struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+ BUG_ON(!dma_ops);
+ dma_ops->unmap_single(dev, dma_addr, size, direction);
+}
+
+static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction)
+{
+ struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+ BUG_ON(!dma_ops);
+ return dma_ops->map_single(dev, page_address(page) + offset, size,
+ direction);
+}
+
+static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
+ size_t size,
+ enum dma_data_direction direction)
+{
+ struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+ BUG_ON(!dma_ops);
+ dma_ops->unmap_single(dev, dma_address, size, direction);
+}
+
+static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction)
+{
+ struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+ BUG_ON(!dma_ops);
+ return dma_ops->map_sg(dev, sg, nents, direction);
+}
+
+static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nhwentries,
+ enum dma_data_direction direction)
+{
+ struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
+
+ BUG_ON(!dma_ops);
+ dma_ops->unmap_sg(dev, sg, nhwentries, direction);
+}
-extern int dma_supported(struct device *dev, u64 mask);
-extern int dma_set_mask(struct device *dev, u64 dma_mask);
-extern void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag);
-extern void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
- dma_addr_t dma_handle);
-extern dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
- size_t size, enum dma_data_direction direction);
-extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
- size_t size, enum dma_data_direction direction);
-extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
- enum dma_data_direction direction);
-extern void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
- size_t size, enum dma_data_direction direction);
-extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction direction);
-extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
- int nhwentries, enum dma_data_direction direction);
+
+/*
+ * Available generic sets of operations
+ */
+extern struct dma_mapping_ops dma_iommu_ops;
+extern struct dma_mapping_ops dma_direct_ops;
#else /* CONFIG_PPC64 */
@@ -261,25 +388,5 @@ static inline void dma_cache_sync(void *
__dma_sync(vaddr, size, (int)direction);
}
-/*
- * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO
- */
-struct dma_mapping_ops {
- void * (*alloc_coherent)(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag);
- void (*free_coherent)(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle);
- dma_addr_t (*map_single)(struct device *dev, void *ptr,
- size_t size, enum dma_data_direction direction);
- void (*unmap_single)(struct device *dev, dma_addr_t dma_addr,
- size_t size, enum dma_data_direction direction);
- int (*map_sg)(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction direction);
- void (*unmap_sg)(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction direction);
- int (*dma_supported)(struct device *dev, u64 mask);
- int (*dac_dma_supported)(struct device *dev, u64 mask);
-};
-
#endif /* __KERNEL__ */
#endif /* _ASM_DMA_MAPPING_H */
Index: linux-cell/include/asm-powerpc/iommu.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/iommu.h 2006-10-19 17:37:56.000000000 +1000
+++ linux-cell/include/asm-powerpc/iommu.h 2006-10-19 17:37:59.000000000 +1000
@@ -69,22 +69,22 @@ extern void iommu_free_table(struct devi
extern struct iommu_table *iommu_init_table(struct iommu_table * tbl,
int nid);
-extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
- struct scatterlist *sglist, int nelems, unsigned long mask,
- enum dma_data_direction direction);
+extern int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
+ int nelems, unsigned long mask,
+ enum dma_data_direction direction);
extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
- int nelems, enum dma_data_direction direction);
+ int nelems, enum dma_data_direction direction);
extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
- dma_addr_t *dma_handle, unsigned long mask,
- gfp_t flag, int node);
+ dma_addr_t *dma_handle, unsigned long mask,
+ gfp_t flag, int node);
extern void iommu_free_coherent(struct iommu_table *tbl, size_t size,
- void *vaddr, dma_addr_t dma_handle);
+ void *vaddr, dma_addr_t dma_handle);
extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
- size_t size, unsigned long mask,
- enum dma_data_direction direction);
+ size_t size, unsigned long mask,
+ enum dma_data_direction direction);
extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction direction);
+ size_t size, enum dma_data_direction direction);
extern void iommu_init_early_pSeries(void);
extern void iommu_init_early_iSeries(void);
Index: linux-cell/arch/powerpc/kernel/vio.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/vio.c 2006-10-19 17:37:56.000000000 +1000
+++ linux-cell/arch/powerpc/kernel/vio.c 2006-10-19 17:37:59.000000000 +1000
@@ -81,15 +81,15 @@ static struct iommu_table *vio_build_iom
struct iommu_table *tbl;
unsigned long offset, size;
- dma_window = get_property(dev->dev.platform_data,
- "ibm,my-dma-window", NULL);
+ dma_window = get_property(dev->dext.of_node,
+ "ibm,my-dma-window", NULL);
if (!dma_window)
return NULL;
tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
- of_parse_dma_window(dev->dev.platform_data, dma_window,
- &tbl->it_index, &offset, &size);
+ of_parse_dma_window(dev->dext.of_node, dma_window,
+ &tbl->it_index, &offset, &size);
/* TCE table size - measured in tce entries */
tbl->it_size = size >> PAGE_SHIFT;
@@ -115,9 +115,11 @@ static struct iommu_table *vio_build_iom
static const struct vio_device_id *vio_match_device(
const struct vio_device_id *ids, const struct vio_dev *dev)
{
+ struct device_ext *dext = device_get_ext(&dev->dev);
+
while (ids->type[0] != '\0') {
if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) &&
- device_is_compatible(dev->dev.platform_data, ids->compat))
+ device_is_compatible(dext->of_node, ids->compat))
return ids;
ids++;
}
@@ -198,9 +200,11 @@ EXPORT_SYMBOL(vio_unregister_driver);
/* vio_dev refcount hit 0 */
static void __devinit vio_dev_release(struct device *dev)
{
- if (dev->platform_data) {
+ struct device_ext *dext = device_get_ext(dev);
+
+ if (dext && dext->of_node) {
/* XXX free TCE table */
- of_node_put(dev->platform_data);
+ of_node_put(dext->of_node);
}
kfree(to_vio_dev(dev));
}
@@ -210,7 +214,7 @@ static void __devinit vio_dev_release(st
* @of_node: The OF node for this device.
*
* Creates and initializes a vio_dev structure from the data in
- * of_node (dev.platform_data) and adds it to the list of virtual devices.
+ * of_node and adds it to the list of virtual devices.
* Returns a pointer to the created vio_dev or NULL if node has
* NULL device_type or compatible fields.
*/
@@ -240,8 +244,6 @@ struct vio_dev * __devinit vio_register_
if (viodev == NULL)
return NULL;
- viodev->dev.platform_data = of_node_get(of_node);
-
viodev->irq = irq_of_parse_and_map(of_node, 0);
snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address);
@@ -254,7 +256,10 @@ struct vio_dev * __devinit vio_register_
if (unit_address != NULL)
viodev->unit_address = *unit_address;
}
- viodev->iommu_table = vio_build_iommu_table(viodev);
+ device_set_ext(&viodev->dev, &viodev->dext);
+ viodev->dext.of_node = of_node_get(of_node);
+ viodev->dext.dma_ops = &dma_iommu_ops;
+ viodev->dext.dma_data = vio_build_iommu_table(viodev);
/* init generic 'struct device' fields: */
viodev->dev.parent = &vio_bus_device.dev;
@@ -282,13 +287,16 @@ static int __init vio_bus_init(void)
int err;
struct device_node *node_vroot;
+ device_set_ext(&vio_bus_device.dev, &vio_bus_device.dext);
+
#ifdef CONFIG_PPC_ISERIES
if (firmware_has_feature(FW_FEATURE_ISERIES)) {
iommu_vio_init();
- vio_bus_device.iommu_table = &vio_iommu_table;
+ vio_bus_device.dext.dma_ops = &dma_iommu_ops;
+ vio_bus_device.dext.dma_data = &vio_iommu_table;
iSeries_vio_dev = &vio_bus_device.dev;
}
-#endif
+#endif /* CONFIG_PPC_ISERIES */
err = bus_register(&vio_bus_type);
if (err) {
@@ -336,7 +344,8 @@ static ssize_t name_show(struct device *
static ssize_t devspec_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct device_node *of_node = dev->platform_data;
+ struct device_ext *dext = device_get_ext(dev);
+ struct device_node *of_node = dext->of_node;
return sprintf(buf, "%s\n", of_node ? of_node->full_name : "none");
}
@@ -353,62 +362,6 @@ void __devinit vio_unregister_device(str
}
EXPORT_SYMBOL(vio_unregister_device);
-static dma_addr_t vio_map_single(struct device *dev, void *vaddr,
- size_t size, enum dma_data_direction direction)
-{
- return iommu_map_single(to_vio_dev(dev)->iommu_table, vaddr, size,
- ~0ul, direction);
-}
-
-static void vio_unmap_single(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction direction)
-{
- iommu_unmap_single(to_vio_dev(dev)->iommu_table, dma_handle, size,
- direction);
-}
-
-static int vio_map_sg(struct device *dev, struct scatterlist *sglist,
- int nelems, enum dma_data_direction direction)
-{
- return iommu_map_sg(dev, to_vio_dev(dev)->iommu_table, sglist,
- nelems, ~0ul, direction);
-}
-
-static void vio_unmap_sg(struct device *dev, struct scatterlist *sglist,
- int nelems, enum dma_data_direction direction)
-{
- iommu_unmap_sg(to_vio_dev(dev)->iommu_table, sglist, nelems, direction);
-}
-
-static void *vio_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t flag)
-{
- return iommu_alloc_coherent(to_vio_dev(dev)->iommu_table, size,
- dma_handle, ~0ul, flag, -1);
-}
-
-static void vio_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle)
-{
- iommu_free_coherent(to_vio_dev(dev)->iommu_table, size, vaddr,
- dma_handle);
-}
-
-static int vio_dma_supported(struct device *dev, u64 mask)
-{
- return 1;
-}
-
-struct dma_mapping_ops vio_dma_ops = {
- .alloc_coherent = vio_alloc_coherent,
- .free_coherent = vio_free_coherent,
- .map_single = vio_map_single,
- .unmap_single = vio_unmap_single,
- .map_sg = vio_map_sg,
- .unmap_sg = vio_unmap_sg,
- .dma_supported = vio_dma_supported,
-};
-
static int vio_bus_match(struct device *dev, struct device_driver *drv)
{
const struct vio_dev *vio_dev = to_vio_dev(dev);
@@ -422,13 +375,17 @@ static int vio_hotplug(struct device *de
char *buffer, int buffer_size)
{
const struct vio_dev *vio_dev = to_vio_dev(dev);
- struct device_node *dn = dev->platform_data;
+ struct device_ext *dext = device_get_ext(dev);
+ struct device_node *dn;
const char *cp;
int length;
if (!num_envp)
return -ENOMEM;
+ if (!dext)
+ return -ENODEV;
+ dn = dext->of_node;
if (!dn)
return -ENODEV;
cp = get_property(dn, "compatible", &length);
@@ -465,7 +422,9 @@ struct bus_type vio_bus_type = {
*/
const void *vio_get_attribute(struct vio_dev *vdev, char *which, int *length)
{
- return get_property(vdev->dev.platform_data, which, length);
+ struct device_ext *dext = device_get_ext(&vdev->dev);
+
+ return get_property(dext->of_node, which, length);
}
EXPORT_SYMBOL(vio_get_attribute);
Index: linux-cell/include/asm-powerpc/vio.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/vio.h 2006-10-19 17:37:56.000000000 +1000
+++ linux-cell/include/asm-powerpc/vio.h 2006-10-19 17:37:59.000000000 +1000
@@ -23,6 +23,7 @@
#include <asm/hvcall.h>
#include <asm/scatterlist.h>
+#include <asm/device_ext.h>
/*
* Architecture-specific constants for drivers to
@@ -45,12 +46,12 @@ struct iommu_table;
* The vio_dev structure is used to describe virtual I/O devices.
*/
struct vio_dev {
- struct iommu_table *iommu_table; /* vio_map_* uses this */
const char *name;
const char *type;
uint32_t unit_address;
unsigned int irq;
struct device dev;
+ struct device_ext dext;
};
struct vio_driver {
Index: linux-cell/arch/powerpc/kernel/pci_64.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/pci_64.c 2006-10-19 17:37:56.000000000 +1000
+++ linux-cell/arch/powerpc/kernel/pci_64.c 2006-10-19 17:38:57.000000000 +1000
@@ -31,6 +31,7 @@
#include <asm/machdep.h>
#include <asm/ppc-pci.h>
#include <asm/firmware.h>
+#include <asm/device_ext.h>
#ifdef DEBUG
#include <asm/udbg.h>
@@ -63,7 +64,7 @@ void iSeries_pcibios_init(void);
LIST_HEAD(hose_list);
-struct dma_mapping_ops pci_dma_ops;
+struct dma_mapping_ops *pci_dma_ops;
EXPORT_SYMBOL(pci_dma_ops);
int global_phb_number; /* Global phb counter */
@@ -1207,15 +1208,42 @@ void __devinit pcibios_fixup_device_reso
}
EXPORT_SYMBOL(pcibios_fixup_device_resources);
+void __devinit pcibios_setup_new_device(struct pci_dev *dev)
+{
+ struct device_ext *dext;
+
+ if (device_get_ext(&dev->dev) != NULL)
+ return;
+
+ dext = kzalloc(sizeof(struct device_ext), GFP_KERNEL);
+ if (dext == NULL) {
+ printk(KERN_ERR "Failed to allocate device extension"
+ " for PCI device %s\n", pci_name(dev));
+ return;
+ }
+ device_set_ext(&dev->dev, dext);
+ dext->of_node = pci_device_to_OF_node(dev);
+ DBG("PCI device %s OF node: %s\n", pci_name(dev),
+ dext->of_node ? dext->of_node->full_name : "<none>");
+ dext->dma_ops = pci_dma_ops;
+
+#ifdef CONFIG_NUMA
+ dext->numa_node = pcibus_to_node(dev->bus);
+#endif
+ if (ppc_md.pci_dma_dev_setup)
+ ppc_md.pci_dma_dev_setup(dev);
+}
+EXPORT_SYMBOL(pcibios_setup_new_device);
static void __devinit do_bus_setup(struct pci_bus *bus)
{
struct pci_dev *dev;
- ppc_md.iommu_bus_setup(bus);
+ if (ppc_md.pci_dma_bus_setup)
+ ppc_md.pci_dma_bus_setup(bus);
list_for_each_entry(dev, &bus->devices, bus_list)
- ppc_md.iommu_dev_setup(dev);
+ pcibios_setup_new_device(dev);
if (ppc_md.irq_bus_setup)
ppc_md.irq_bus_setup(bus);
@@ -1419,3 +1447,25 @@ int pcibus_to_node(struct pci_bus *bus)
}
EXPORT_SYMBOL(pcibus_to_node);
#endif
+
+int pci_platform_notify(struct device * dev)
+{
+ return 0;
+}
+
+int pci_platform_notify_remove(struct device * dev)
+{
+ struct device_ext *dext = device_get_ext(dev);
+
+ DBG("%s:%s platform notify remove !\n",
+ dev_driver_string(dev), dev->bus_id);
+
+ if (dev->bus != &pci_bus_type)
+ return 0;
+
+ device_set_ext(dev, NULL);
+ mb();
+ kfree(dext);
+
+ return 0;
+}
Index: linux-cell/arch/powerpc/kernel/setup_64.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/setup_64.c 2006-10-19 17:37:56.000000000 +1000
+++ linux-cell/arch/powerpc/kernel/setup_64.c 2006-10-19 17:38:57.000000000 +1000
@@ -33,6 +33,7 @@
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <linux/bootmem.h>
+#include <linux/pci.h>
#include <asm/io.h>
#include <asm/kdump.h>
#include <asm/prom.h>
@@ -533,6 +534,10 @@ void __init setup_arch(char **cmdline_p)
conswitchp = &dummy_con;
#endif
+#ifdef CONFIG_PCI
+ platform_notify = pci_platform_notify;
+ platform_notify_remove = pci_platform_notify_remove;
+#endif
ppc_md.setup_arch();
paging_init();
Index: linux-cell/arch/powerpc/platforms/pseries/iommu.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/pseries/iommu.c 2006-10-19 17:37:56.000000000 +1000
+++ linux-cell/arch/powerpc/platforms/pseries/iommu.c 2006-10-19 17:37:59.000000000 +1000
@@ -44,6 +44,7 @@
#include <asm/tce.h>
#include <asm/ppc-pci.h>
#include <asm/udbg.h>
+#include <asm/device_ext.h>
#include "plpar_wrappers.h"
@@ -329,7 +330,7 @@ static void iommu_table_setparms_lpar(st
tbl->it_size = size >> PAGE_SHIFT;
}
-static void iommu_bus_setup_pSeries(struct pci_bus *bus)
+static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
{
struct device_node *dn;
struct iommu_table *tbl;
@@ -338,10 +339,9 @@ static void iommu_bus_setup_pSeries(stru
struct pci_dn *pci;
int children;
- DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self);
-
dn = pci_bus_to_OF_node(bus);
- pci = PCI_DN(dn);
+
+ DBG("pci_dma_bus_setup_pSeries: setting up bus %s\n", dn->full_name);
if (bus->self) {
/* This is not a root bus, any setup will be done for the
@@ -349,6 +349,7 @@ static void iommu_bus_setup_pSeries(stru
*/
return;
}
+ pci = PCI_DN(dn);
/* Check if the ISA bus on the system is under
* this PHB.
@@ -410,17 +411,17 @@ static void iommu_bus_setup_pSeries(stru
}
-static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
+static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
{
struct iommu_table *tbl;
struct device_node *dn, *pdn;
struct pci_dn *ppci;
const void *dma_window = NULL;
- DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self);
-
dn = pci_bus_to_OF_node(bus);
+ DBG("pci_dma_bus_setup_pSeriesLP: setting up bus %s\n", dn->full_name);
+
/* Find nearest ibm,dma-window, walking up the device tree */
for (pdn = dn; pdn != NULL; pdn = pdn->parent) {
dma_window = get_property(pdn, "ibm,dma-window", NULL);
@@ -429,11 +430,15 @@ static void iommu_bus_setup_pSeriesLP(st
}
if (dma_window == NULL) {
- DBG("iommu_bus_setup_pSeriesLP: bus %s seems to have no ibm,dma-window property\n", dn->full_name);
+ DBG(" no ibm,dma-window property !\n");
return;
}
ppci = PCI_DN(pdn);
+
+ DBG(" parent is %s, iommu_table: 0x%p\n",
+ pdn->full_name, ppci->iommu_table);
+
if (!ppci->iommu_table) {
/* Bussubno hasn't been copied yet.
* Do it now because iommu_table_setparms_lpar needs it.
@@ -447,6 +452,7 @@ static void iommu_bus_setup_pSeriesLP(st
iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window);
ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node);
+ DBG(" created table: %p\n", ppci->iommu_table);
}
if (pdn != dn)
@@ -454,27 +460,34 @@ static void iommu_bus_setup_pSeriesLP(st
}
-static void iommu_dev_setup_pSeries(struct pci_dev *dev)
+static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
{
- struct device_node *dn, *mydn;
+ struct device_ext *dext = device_get_ext(&dev->dev);
+ struct device_node *dn;
struct iommu_table *tbl;
- DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, pci_name(dev));
+ DBG("pci_dma_dev_setup_pSeries: %s\n", pci_name(dev));
+
+ if (dext == NULL) {
+ printk(KERN_ERR "iommu: Attempt to setup PCI dev %s "
+ "with no device extension !", pci_name(dev));
+ return;
+ }
- mydn = dn = pci_device_to_OF_node(dev);
+ dn = dext->of_node;
/* If we're the direct child of a root bus, then we need to allocate
* an iommu table ourselves. The bus setup code should have setup
* the window sizes already.
*/
if (!dev->bus->self) {
+ struct pci_controller *phb = PCI_DN(dn)->phb;
+
DBG(" --> first child, no bridge. Allocating iommu table.\n");
tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
- PCI_DN(dn)->phb->node);
- iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl);
- PCI_DN(dn)->iommu_table = iommu_init_table(tbl,
- PCI_DN(dn)->phb->node);
-
+ phb->node);
+ iommu_table_setparms(phb, dn, tbl);
+ dext->dma_data = iommu_init_table(tbl, phb->node);
return;
}
@@ -485,11 +498,11 @@ static void iommu_dev_setup_pSeries(stru
while (dn && PCI_DN(dn) && PCI_DN(dn)->iommu_table == NULL)
dn = dn->parent;
- if (dn && PCI_DN(dn)) {
- PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table;
- } else {
- DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, pci_name(dev));
- }
+ if (dn && PCI_DN(dn))
+ dext->dma_data = PCI_DN(dn)->iommu_table;
+ else
+ printk(KERN_WARNING "iommu: Device %s has no iommu table\n",
+ pci_name(dev));
}
static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
@@ -515,14 +528,21 @@ static struct notifier_block iommu_recon
.notifier_call = iommu_reconfig_notifier,
};
-static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
+static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
{
+ struct device_ext *dext = device_get_ext(&dev->dev);
struct device_node *pdn, *dn;
struct iommu_table *tbl;
const void *dma_window = NULL;
struct pci_dn *pci;
- DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev));
+ DBG("pci_dma_dev_setup_pSeriesLP: %s\n", pci_name(dev));
+
+ if (dext == NULL) {
+ printk(KERN_ERR "iommu: Attempt to setup PCI dev %s "
+ "with no device extension !", pci_name(dev));
+ return;
+ }
/* dev setup for LPAR is a little tricky, since the device tree might
* contain the dma-window properties per-device and not neccesarily
@@ -531,6 +551,7 @@ static void iommu_dev_setup_pSeriesLP(st
* already allocated.
*/
dn = pci_device_to_OF_node(dev);
+ DBG(" node is %s\n", dn->full_name);
for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table;
pdn = pdn->parent) {
@@ -539,16 +560,17 @@ static void iommu_dev_setup_pSeriesLP(st
break;
}
+ DBG(" parent is %s\n", pdn->full_name);
+
/* Check for parent == NULL so we don't try to setup the empty EADS
* slots on POWER4 machines.
*/
if (dma_window == NULL || pdn->parent == NULL) {
- DBG("No dma window for device, linking to parent\n");
- PCI_DN(dn)->iommu_table = PCI_DN(pdn)->iommu_table;
+ DBG(" no dma window for device, linking to parent\n");
+ dext->dma_data = PCI_DN(pdn)->iommu_table;
return;
- } else {
- DBG("Found DMA window, allocating table\n");
}
+ DBG(" found DMA window, table: %p\n", pci->iommu_table);
pci = PCI_DN(pdn);
if (!pci->iommu_table) {
@@ -561,24 +583,20 @@ static void iommu_dev_setup_pSeriesLP(st
iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window);
pci->iommu_table = iommu_init_table(tbl, pci->phb->node);
+ DBG(" created table: %p\n", pci->iommu_table);
}
- if (pdn != dn)
- PCI_DN(dn)->iommu_table = pci->iommu_table;
+ dext->dma_data = pci->iommu_table;
}
-static void iommu_bus_setup_null(struct pci_bus *b) { }
-static void iommu_dev_setup_null(struct pci_dev *d) { }
-
/* These are called very early. */
void iommu_init_early_pSeries(void)
{
if (of_chosen && get_property(of_chosen, "linux,iommu-off", NULL)) {
/* Direct I/O, IOMMU off */
- ppc_md.iommu_dev_setup = iommu_dev_setup_null;
- ppc_md.iommu_bus_setup = iommu_bus_setup_null;
- pci_direct_iommu_init();
-
+ ppc_md.pci_dma_dev_setup = NULL;
+ ppc_md.pci_dma_bus_setup = NULL;
+ pci_dma_ops = &dma_direct_ops;
return;
}
@@ -591,19 +609,19 @@ void iommu_init_early_pSeries(void)
ppc_md.tce_free = tce_free_pSeriesLP;
}
ppc_md.tce_get = tce_get_pSeriesLP;
- ppc_md.iommu_bus_setup = iommu_bus_setup_pSeriesLP;
- ppc_md.iommu_dev_setup = iommu_dev_setup_pSeriesLP;
+ ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeriesLP;
+ ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeriesLP;
} else {
ppc_md.tce_build = tce_build_pSeries;
ppc_md.tce_free = tce_free_pSeries;
ppc_md.tce_get = tce_get_pseries;
- ppc_md.iommu_bus_setup = iommu_bus_setup_pSeries;
- ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries;
+ ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeries;
+ ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeries;
}
pSeries_reconfig_notifier_register(&iommu_reconfig_nb);
- pci_iommu_init();
+ pci_dma_ops = &dma_iommu_ops;
}
Index: linux-cell/arch/powerpc/platforms/pseries/pci_dlpar.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/pseries/pci_dlpar.c 2006-10-19 17:37:56.000000000 +1000
+++ linux-cell/arch/powerpc/platforms/pseries/pci_dlpar.c 2006-10-19 17:37:59.000000000 +1000
@@ -93,8 +93,8 @@ pcibios_fixup_new_pci_devices(struct pci
if (list_empty(&dev->global_list)) {
int i;
- /* Need to setup IOMMU tables */
- ppc_md.iommu_dev_setup(dev);
+ /* Create device extension and setup iommu table */
+ pcibios_setup_new_device(dev);
if(fix_bus)
pcibios_fixup_device_resources(dev, bus);
Index: linux-cell/arch/powerpc/sysdev/dart_iommu.c
===================================================================
--- linux-cell.orig/arch/powerpc/sysdev/dart_iommu.c 2006-10-19 17:37:56.000000000 +1000
+++ linux-cell/arch/powerpc/sysdev/dart_iommu.c 2006-10-19 17:37:59.000000000 +1000
@@ -45,6 +45,7 @@
#include <asm/cacheflush.h>
#include <asm/lmb.h>
#include <asm/ppc-pci.h>
+#include <asm/device_ext.h>
#include "dart.h"
@@ -295,24 +296,23 @@ static void iommu_table_dart_setup(void)
set_bit(iommu_table_dart.it_size - 1, iommu_table_dart.it_map);
}
-static void iommu_dev_setup_dart(struct pci_dev *dev)
+static void pci_dma_dev_setup_dart(struct pci_dev *dev)
{
- struct device_node *dn;
+ struct device_ext *dext = device_get_ext(&dev->dev);
+
+ if (dext == NULL) {
+ printk(KERN_ERR "dart: Attempt to setup PCI dev %s "
+ "with no device extension !", pci_name(dev));
+ return;
+ }
/* We only have one iommu table on the mac for now, which makes
* things simple. Setup all PCI devices to point to this table
- *
- * We must use pci_device_to_OF_node() to make sure that
- * we get the real "final" pointer to the device in the
- * pci_dev sysdata and not the temporary PHB one
*/
- dn = pci_device_to_OF_node(dev);
-
- if (dn)
- PCI_DN(dn)->iommu_table = &iommu_table_dart;
+ dext->dma_data = &iommu_table_dart;
}
-static void iommu_bus_setup_dart(struct pci_bus *bus)
+static void pci_dma_bus_setup_dart(struct pci_bus *bus)
{
struct device_node *dn;
@@ -327,9 +327,6 @@ static void iommu_bus_setup_dart(struct
PCI_DN(dn)->iommu_table = &iommu_table_dart;
}
-static void iommu_dev_setup_null(struct pci_dev *dev) { }
-static void iommu_bus_setup_null(struct pci_bus *bus) { }
-
void iommu_init_early_dart(void)
{
struct device_node *dn;
@@ -350,22 +347,21 @@ void iommu_init_early_dart(void)
/* Initialize the DART HW */
if (dart_init(dn) == 0) {
- ppc_md.iommu_dev_setup = iommu_dev_setup_dart;
- ppc_md.iommu_bus_setup = iommu_bus_setup_dart;
+ ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_dart;
+ ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_dart;
/* Setup pci_dma ops */
- pci_iommu_init();
-
+ pci_dma_ops = &dma_iommu_ops;
return;
}
bail:
/* If init failed, use direct iommu and null setup functions */
- ppc_md.iommu_dev_setup = iommu_dev_setup_null;
- ppc_md.iommu_bus_setup = iommu_bus_setup_null;
+ ppc_md.pci_dma_dev_setup = NULL;
+ ppc_md.pci_dma_bus_setup = NULL;
/* Setup pci_dma ops */
- pci_direct_iommu_init();
+ pci_dma_ops = &dma_direct_ops;
}
Index: linux-cell/include/asm-powerpc/machdep.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/machdep.h 2006-10-19 17:37:56.000000000 +1000
+++ linux-cell/include/asm-powerpc/machdep.h 2006-10-19 17:37:59.000000000 +1000
@@ -84,8 +84,8 @@ struct machdep_calls {
unsigned long (*tce_get)(struct iommu_table *tbl,
long index);
void (*tce_flush)(struct iommu_table *tbl);
- void (*iommu_dev_setup)(struct pci_dev *dev);
- void (*iommu_bus_setup)(struct pci_bus *bus);
+ void (*pci_dma_dev_setup)(struct pci_dev *dev);
+ void (*pci_dma_bus_setup)(struct pci_bus *bus);
void (*irq_bus_setup)(struct pci_bus *bus);
#endif /* CONFIG_PPC64 */
Index: linux-cell/include/asm-powerpc/pci-bridge.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/pci-bridge.h 2006-10-19 17:37:56.000000000 +1000
+++ linux-cell/include/asm-powerpc/pci-bridge.h 2006-10-19 17:37:59.000000000 +1000
@@ -161,6 +161,9 @@ static inline unsigned long pci_address_
}
#endif
+extern int pci_platform_notify(struct device * dev);
+extern int pci_platform_notify_remove(struct device * dev);
+
/* Return values for ppc_md.pci_probe_mode function */
#define PCI_PROBE_NONE -1 /* Don't look at this bus at all */
#define PCI_PROBE_NORMAL 0 /* Do normal PCI probing */
Index: linux-cell/include/asm-powerpc/pci.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/pci.h 2006-10-19 17:37:56.000000000 +1000
+++ linux-cell/include/asm-powerpc/pci.h 2006-10-19 17:37:59.000000000 +1000
@@ -76,15 +76,15 @@ static inline int pcibios_prep_mwi(struc
return 0;
}
-extern struct dma_mapping_ops pci_dma_ops;
+extern struct dma_mapping_ops *pci_dma_ops;
/* For DAC DMA, we currently don't support it by default, but
* we let 64-bit platforms override this.
*/
static inline int pci_dac_dma_supported(struct pci_dev *hwdev,u64 mask)
{
- if (pci_dma_ops.dac_dma_supported)
- return pci_dma_ops.dac_dma_supported(&hwdev->dev, mask);
+ if (pci_dma_ops && pci_dma_ops->dac_dma_supported)
+ return pci_dma_ops->dac_dma_supported(&hwdev->dev, mask);
return 0;
}
@@ -216,6 +216,8 @@ extern int remap_bus_range(struct pci_bu
extern void pcibios_fixup_device_resources(struct pci_dev *dev,
struct pci_bus *bus);
+extern void pcibios_setup_new_device(struct pci_dev *dev);
+
extern void pcibios_claim_one_bus(struct pci_bus *b);
extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
Index: linux-cell/arch/powerpc/kernel/Makefile
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/Makefile 2006-10-19 17:37:56.000000000 +1000
+++ linux-cell/arch/powerpc/kernel/Makefile 2006-10-19 17:37:59.000000000 +1000
@@ -64,8 +64,7 @@ obj-$(CONFIG_PPC_UDBG_16550) += legacy_s
module-$(CONFIG_PPC64) += module_64.o
obj-$(CONFIG_MODULES) += $(module-y)
-pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci_iommu.o \
- pci_direct_iommu.o iomap.o
+pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o iomap.o
pci32-$(CONFIG_PPC32) := pci_32.o
obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y)
kexec-$(CONFIG_PPC64) := machine_kexec_64.o
Index: linux-cell/arch/powerpc/kernel/ibmebus.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/ibmebus.c 2006-10-19 17:37:56.000000000 +1000
+++ linux-cell/arch/powerpc/kernel/ibmebus.c 2006-10-19 17:37:59.000000000 +1000
@@ -112,7 +112,7 @@ static int ibmebus_dma_supported(struct
return 1;
}
-struct dma_mapping_ops ibmebus_dma_ops = {
+static struct dma_mapping_ops ibmebus_dma_ops = {
.alloc_coherent = ibmebus_alloc_coherent,
.free_coherent = ibmebus_free_coherent,
.map_single = ibmebus_map_single,
@@ -176,6 +176,10 @@ static struct ibmebus_dev* __devinit ibm
dev->ofdev.dev.bus = &ibmebus_bus_type;
dev->ofdev.dev.release = ibmebus_dev_release;
+ device_set_ext(&dev->ofdev.dev, &dev->dext);
+ dev->dext.of_node = dev->ofdev.node;
+ dev->dext.dma_ops = &ibmebus_dma_ops;
+
/* An ibmebusdev is based on a of_device. We have to change the
* bus type to use our own DMA mapping operations.
*/
Index: linux-cell/arch/powerpc/platforms/cell/iommu.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/cell/iommu.c 2006-10-19 17:37:56.000000000 +1000
+++ linux-cell/arch/powerpc/platforms/cell/iommu.c 2006-10-19 17:37:59.000000000 +1000
@@ -255,9 +255,6 @@ static void enable_mapping(void __iomem
set_iost_origin(mmio_base);
}
-static void iommu_dev_setup_null(struct pci_dev *d) { }
-static void iommu_bus_setup_null(struct pci_bus *b) { }
-
struct cell_iommu {
unsigned long base;
unsigned long mmio_base;
@@ -306,12 +303,15 @@ static void cell_do_map_iommu(struct cel
}
}
-static void iommu_devnode_setup(struct device_node *d)
+static void pci_dma_cell_bus_setup(struct pci_bus *b)
{
const unsigned int *ioid;
unsigned long map_start, map_size, token;
const unsigned long *dma_window;
struct cell_iommu *iommu;
+ struct device_node *d;
+
+ d = pci_bus_to_OF_node(b);
ioid = get_property(d, "ioid", NULL);
if (!ioid)
@@ -330,12 +330,6 @@ static void iommu_devnode_setup(struct d
cell_do_map_iommu(iommu, *ioid, map_start, map_size);
}
-static void iommu_bus_setup(struct pci_bus *b)
-{
- struct device_node *d = (struct device_node *)b->sysdata;
- iommu_devnode_setup(d);
-}
-
static int cell_map_iommu_hardcoded(int num_nodes)
{
@@ -499,16 +493,13 @@ void cell_init_iommu(void)
if (setup_bus) {
pr_debug("%s: IOMMU mapping activated\n", __FUNCTION__);
- ppc_md.iommu_dev_setup = iommu_dev_setup_null;
- ppc_md.iommu_bus_setup = iommu_bus_setup;
+ ppc_md.pci_dma_bus_setup = pci_dma_cell_bus_setup;
} else {
pr_debug("%s: IOMMU mapping activated, "
"no device action necessary\n", __FUNCTION__);
/* Direct I/O, IOMMU off */
- ppc_md.iommu_dev_setup = iommu_dev_setup_null;
- ppc_md.iommu_bus_setup = iommu_bus_setup_null;
}
}
- pci_dma_ops = cell_iommu_ops;
+ pci_dma_ops = &cell_iommu_ops;
}
Index: linux-cell/include/asm-powerpc/ibmebus.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/ibmebus.h 2006-10-19 17:37:56.000000000 +1000
+++ linux-cell/include/asm-powerpc/ibmebus.h 2006-10-19 17:37:59.000000000 +1000
@@ -43,12 +43,13 @@
#include <linux/interrupt.h>
#include <linux/mod_devicetable.h>
#include <asm/of_device.h>
+#include <asm/device_ext.h>
-extern struct dma_mapping_ops ibmebus_dma_ops;
extern struct bus_type ibmebus_bus_type;
struct ibmebus_dev {
const char *name;
+ struct device_ext dext;
struct of_device ofdev;
};
Index: linux-cell/include/asm-powerpc/of_device.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/of_device.h 2006-10-19 17:37:56.000000000 +1000
+++ linux-cell/include/asm-powerpc/of_device.h 2006-10-19 17:37:59.000000000 +1000
@@ -5,6 +5,7 @@
#include <linux/device.h>
#include <linux/mod_devicetable.h>
#include <asm/prom.h>
+#include <asm/device_ext.h>
/*
@@ -14,8 +15,9 @@
*/
struct of_device
{
- struct device_node *node; /* OF device node */
+ struct device_node *node; /* to be obsoleted */
u64 dma_mask; /* DMA mask */
+ struct device_ext dext;
struct device dev; /* Generic device interface */
};
#define to_of_device(d) container_of(d, struct of_device, dev)
Index: linux-cell/arch/powerpc/kernel/of_platform.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/of_platform.c 2006-10-19 17:37:56.000000000 +1000
+++ linux-cell/arch/powerpc/kernel/of_platform.c 2006-10-19 17:42:28.000000000 +1000
@@ -22,7 +22,7 @@
#include <asm/dcr.h>
#include <asm/of_device.h>
#include <asm/of_platform.h>
-
+#include <asm/topology.h>
/*
* The list of OF IDs below is used for matching bus types in the
@@ -220,6 +220,15 @@ struct of_device* of_platform_device_cre
dev->dev.parent = parent;
dev->dev.bus = &of_platform_bus_type;
dev->dev.release = of_release_dev;
+ device_set_ext(&dev->dev, &dev->dext);
+ dev->dext.of_node = np;
+#ifdef CONFIG_NUMA
+ dev->dext.numa_node = of_node_to_nid(np);
+#endif
+ /* We do not fill the DMA ops for platform devices by default.
+ * This is currently the responsibility of the platform code
+ * to do such, possibly using a device notifier
+ */
if (bus_id)
strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
^ permalink raw reply
* Re: [PATCH] enable RTAS /proc for PowerPC/CHRP platform
From: Olaf Hering @ 2006-10-19 7:03 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: akpm, tilmann, Sven Luther, linuxppc-dev
In-Reply-To: <1161211083.10524.13.camel@localhost.localdomain>
On Thu, Oct 19, Benjamin Herrenschmidt wrote:
> On Wed, 2006-10-18 at 09:38 +0200, Olaf Hering wrote:
> > On Wed, Oct 18, Michael Ellerman wrote:
> >
> > > But it's called '/proc/ppc64' right now on lots of machines, so you
> > > can't go changing it.
> >
> > if test -d /proc/ppc64 .. is a quick way to check wether the system is
> > 64bit or not. Similar to if test -d /proc/iSeries ..
>
> That's really ugly ! You really do that ? Gack...
What way should I use?
^ permalink raw reply
* Re: [PATCH/RFC] Add cmd_wrap_dts rules to arch/powerpc/boot/Makefile
From: Matthew McClintock @ 2006-10-19 5:58 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <1161237001.4992.5.camel@localhost>
On Thu, 2006-10-19 at 00:50 -0500, Matthew McClintock wrote:
> $(obj)/$(CONFIG_SANDPOINT): vmlinux $(wrapperbits)
> $(call cmd,wrap_dts,`echo $CONFIG_SANDPOINT | awk
> '{print substr($1, 8)}'`)
The $(CONFIG_SANDPOINT) bits should ideally be renamed to
$(CONFIG_TARGET) or something....
-Matthew
^ permalink raw reply
* Re: [PATCH/RFC] Add cmd_wrap_dts rules to arch/powerpc/boot/Makefile
From: Matthew McClintock @ 2006-10-19 5:50 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <20061019002635.GA2356@mag.az.mvista.com>
On Wed, 2006-10-18 at 17:26 -0700, Mark A. Greer wrote:
>
> $(obj)/zImage.sandpoint: vmlinux $(wrapperbits)
> $(call cmd,wrap_dts,sandpoint)
>
> $(obj)/zImage.initrd.sandpoint: vmlinux $(wrapperbits)
> $(call cmd,wrap_dts_initrd,sandpoint)
Can you do something like this to make it even more automatic:
$(obj)/$(CONFIG_SANDPOINT): vmlinux $(wrapperbits)
$(call cmd,wrap_dts,`echo $CONFIG_SANDPOINT | awk '{print substr($1, 8)}'`)
I'm not sure if this will work exactly as is. But, I do think adding an
entry in the Makefile for every possible bootwrapper target is needed. I
say this because I intend to add targets for all variants of Freescale
boards at some point in the future.
Let me clarify my needs here some more, I want to be able to type 'make
cuImage' and have the scripts build the wrapper target and attached the
correct dtb for all variants of Freescale boards. Of course, the dtb
will hopefully be specified in the defconfig. Does this make sense?
-Matthew
^ permalink raw reply
* Re: kernel BUG in __cache_alloc_node at linux-2.6.git/mm/slab.c:3177!
From: Paul Mackerras @ 2006-10-19 5:03 UTC (permalink / raw)
To: Christoph Lameter; +Cc: akpm, linuxppc-dev, linux-kernel
In-Reply-To: <Pine.LNX.4.64.0610181448250.30710@schroedinger.engr.sgi.com>
Christoph Lameter writes:
> Here is patch to add some printk to try to figure out what is going on.
> Run with this and send me the console output leading up to the failure.
Here... Thanks for your help on this. I'll poke a bit further.
Linux version 2.6.19-rc2-test (paulus@drongo) (gcc version 4.1.2 20060928 (prerelease) (Debian 4.1.1-15)) #37 SMP Thu Oct 19 14:05:18 EST 2006
[boot]0012 Setup Arch
No ramdisk, default root is /dev/sda2
EEH: PCI Enhanced I/O Error Handling Enabled
PPC64 nvram contains 7168 bytes
Zone PFN ranges:
DMA 0 -> 524288
Normal 524288 -> 524288
early_node_map[3] active PFN ranges
1: 0 -> 32768
0: 32768 -> 278528
1: 278528 -> 524288
[boot]0015 Setup Done
Built 2 zonelists. Total pages: 513760
Kernel command line: root=/dev/sdc3
[boot]0020 XICS Init
[boot]0021 XICS Done
PID hash table entries: 4096 (order: 12, 32768 bytes)
Console: colour dummy device 80x25
Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes)
Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes)
freeing bootmem node 0
freeing bootmem node 1
Memory: 2046852k/2097152k available (5512k kernel code, 65056k reserved, 2204k data, 554k bss, 256k init)
Get cache descritor
__cache_alloc
__cache_alloc_node 0
fallback_alloc
__cache_alloc_node 0
__cache_alloc_node 1
kernel BUG in __cache_alloc_node at /home/paulus/kernel/powerpc/mm/slab.c:3185!
^ permalink raw reply
* [POWERPC] Add the thread topolgy to sysfs
From: Stephen Rothwell @ 2006-10-19 4:33 UTC (permalink / raw)
To: paulus; +Cc: ppc-dev
This adds the /sys/devices/system/cpu/*/topology/thread_siblings
files.
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
include/asm-powerpc/topology.h | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
diff --git a/include/asm-powerpc/topology.h b/include/asm-powerpc/topology.h
index 8f7ee16..9fe7894 100644
--- a/include/asm-powerpc/topology.h
+++ b/include/asm-powerpc/topology.h
@@ -96,7 +96,13 @@ #endif /* CONFIG_NUMA */
#ifdef CONFIG_SMP
#include <asm/cputable.h>
-#define smt_capable() (cpu_has_feature(CPU_FTR_SMT))
+#define smt_capable() (cpu_has_feature(CPU_FTR_SMT))
+
+#ifdef CONFIG_PPC64
+#include <asm/smp.h>
+
+#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu])
+#endif
#endif
#endif /* __KERNEL__ */
--
1.4.2.3
^ permalink raw reply related
* Re: Linuxppc-embedded Digest, Vol 26, Issue 36
From: Kumar Gala @ 2006-10-19 1:54 UTC (permalink / raw)
To: Wang Matthew-R59995; +Cc: linuxppc-embedded
In-Reply-To: <54A124D27BDE0F449E2032F42ED617583197CD@zch01exm21.fsl.freescale.net>
On Oct 18, 2006, at 8:10 PM, Wang Matthew-R59995 wrote:
> Hi Kumar,
>
> Actually I do many trials about it. Vxwerks Bootrom is smaller than
> U-Boot. The key difference between Bootrom and U-boot is that some
> source code of Bootrom is invisible to the users.
>
> Actually the rfi instruction which I point out is the first rfi
> instruction of Linux PowerPC bringup.
>
> Before that, it's TLB entry invalidation and temp TLB entry mapping.
>
> I check MMU setting carefully before coming Linux Kernel.
>
> I just want to know if other guys met similar scenario like me. I
> don't
> need the precise answer, just overall suggestion about it because I
> understand that not everyone has the same bootloader of mine, that
> bootloader is actually a customized bootloader.
I understand that, thus I was asking what exact problem you were
seeing to try and help.
> Anyway thank you.
>
> R9 point to LR register, mask the high 20 bit of r9 and send to r7,
> and
> then add 24, which means stride 6 instructions for rfi instruction
> execution.
>
> Of course, rfi can switch the TLB entry, both the previous TLB
> entry and
> the temp TLB entry point to the same physical address.
>
> I've checked it.
I know what the code does, I wrote it :)
- kumar
^ permalink raw reply
* Not know how to build image and user application from ELDK 3.1.1
From: tran vanle @ 2006-10-19 1:25 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 2145 bytes --]
hanks Wolfgang Denk
I'm reinstall ELDK 3.1.1 and it ok
I rebuild openssl like that
- Download openssl-0.9.7f-7.10_1.src.rpm in <project>/usr/src/denx/SRPMS
- Go to <project>/usr/src/denx/SRPMS and run
ppc_8xx-rpm -iv openssl-0.9.7f-7.10_1.src.rpm
- Go to <project>/usr/src/denx/SPECS and run
ppc_8xx-rpmbuild openssl.spec
Then I receive in <project>/usr/src/denx/openssl-0.9.7f/ libssl.so.0.9.7 and openssl in <project>/usr/src/denx/openssl-0.9.7f/apps
That's OK
But I don't know Was command openssl added in image in <project>/ppc_8xx/images? If no how i can do it ?
I also want to rebuild kernel but i only receive vmlinux in <project>/ppc_8xx/usr/src/linux/ Was vmlinux added in image in <project>/ppc_8xx/images? If no how i can do it ?
If I want to build an application but not in ftp://ftp.sunet.se/pub/Linux/distributions/eldk/3.1.1/ppc-linux-x86/sources/target/SRPMS/
how can I do?
Thanks
Wolfgang Denk <wd@denx.de> wrote: In message <20061016142137.34580.qmail@web33007.mail.mud.yahoo.com> you wrote:
>
> I have just installed ELDK 4.0 for TQM 8xxL and read it README but I don't know how to build my custom image or adding user application.Such as I want to build ssh and openssh but I don't know where to start and how to do it step by step.
> Every one who HAD did it please guide me step by step to do it
I strongly recommend to read the extensive documentation that is
available at http://www.denx.de/wiki/view/DULG/Manual?stickboard=tqm8xxl
Also, I would like to point out that you should use ELDK 3.1.1 for
MPC8xx based systems like the TQM8xxL (that's the reason why the
TQM8xxL ships with ELDK 3.1.1 included on CDROM).
Best regards,
Wolfgang Denk
--
Software Engineering: Embedded and Realtime Systems, Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
A Perl script is correct if it's halfway readable and gets the job
done before your boss fires you.
- L. Wall & R. L. Schwartz, _Programming Perl_
---------------------------------
On Yahoo!7
Photos: Unlimited free storage keep all your photos in one place!
[-- Attachment #2: Type: text/html, Size: 2662 bytes --]
^ permalink raw reply
* RE: Linuxppc-embedded Digest, Vol 26, Issue 36
From: Wang Matthew-R59995 @ 2006-10-19 1:10 UTC (permalink / raw)
To: galak; +Cc: linuxppc-embedded
In-Reply-To: <mailman.354.1161187327.32299.linuxppc-embedded@ozlabs.org>
Hi Kumar,
Actually I do many trials about it. Vxwerks Bootrom is smaller than
U-Boot. The key difference between Bootrom and U-boot is that some
source code of Bootrom is invisible to the users.
Actually the rfi instruction which I point out is the first rfi
instruction of Linux PowerPC bringup.
Before that, it's TLB entry invalidation and temp TLB entry mapping.
I check MMU setting carefully before coming Linux Kernel.
I just want to know if other guys met similar scenario like me. I don't
need the precise answer, just overall suggestion about it because I
understand that not everyone has the same bootloader of mine, that
bootloader is actually a customized bootloader.
Anyway thank you.
R9 point to LR register, mask the high 20 bit of r9 and send to r7, and
then add 24, which means stride 6 instructions for rfi instruction
execution.
Of course, rfi can switch the TLB entry, both the previous TLB entry and
the temp TLB entry point to the same physical address.
I've checked it.
B.R
Wang Qi.
Date: Wed, 18 Oct 2006 08:39:23 -0500
From: Kumar Gala <galak@kernel.crashing.org>
Subject: Re: About the RFI instruction on Linux Powerpc
To: Wang Matthew-R59995 <Qi.W@freescale.com>
Cc: linuxppc-embedded@ozlabs.org
Message-ID: <0EE06CE5-98CB-49BB-A398-DF0E3277125D@kernel.crashing.org>
Content-Type: text/plain; charset=3DUS-ASCII; delsp=3Dyes; =
format=3Dflowed
On Oct 18, 2006, at 7:49 AM, Wang Matthew-R59995 wrote:
> Hi folks,
>
> Currently I meet an issue about rfi instruction. Please see the =20
> following source code. This source code is contained at the =20
> head_fsl_booke.h of ./arch/powerpc/kernel directory.
>
> xori r6,r4,1
> slwi r6,r6,5 /* setup new context with other address space */
> bl 1f /* Find our address */
> 1: mflr r9
> rlwimi r7,r9,0,20,31
> addi r7,r7,24
> mtspr SPRN_SRR0,r7
> mtspr SPRN_SRR1,r6
> rfi
> I found that rfi instruction can't jump to the address of SRR0. I =20
> take the MPC8555CDS board to do those test. And I don't take U-Boot =20
> as bootloader, while the Vxwerks Bootrom.
>
> I just want to try if Bootrom can bring up the Linux Powerpc kernel.
>
> Any suggestion for that?
What does happen after the rfi instruction? Do you have a JTAG =20
debugger or something you can use to single step through this code? =20
Do you know the value of r9?
There are some expectations as to what's setup by the bootloader when =20
you jump into the kernel. They are pretty minimal but I dont know if =20
the VxWorks Bootrom does the same thing as u-boot.
- kumar
^ permalink raw reply
* Re: [PATCH/RFC] Add cmd_wrap_dts rules to arch/powerpc/boot/Makefile
From: Josh Boyer @ 2006-10-19 0:34 UTC (permalink / raw)
To: Mark A. Greer; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <20061019002635.GA2356@mag.az.mvista.com>
On Wed, 2006-10-18 at 17:26 -0700, Mark A. Greer wrote:
> Paul, et. al.,
>
> Currently, platforms that don't have a dt-aware firmware need to
> manually run the wrapper script to wrap a dtb into the zImage that
> was just built. This is a PITA and is guaranteed to mess up people
> who just want to build a zImage and have it work.
>
> To address this, I added a couple new rules to arch/powerpc/boot/Makefile
> so that the dtb is automatically wrapped for "reference" platforms.
> "reference" meaning a platform that has its dts in
> arch/powerpc/boot/dts/<platform>.dts. It won't work for non-reference
> platforms.
>
> The patch is attached below with a header in case it is acceptable, as
> is.
>
> This would be used by the sandpoint, say, by adding the following rules
> to the Makefile in the appropriate places:
>
> $(obj)/zImage.sandpoint: vmlinux $(wrapperbits)
> $(call cmd,wrap_dts,sandpoint)
>
> $(obj)/zImage.initrd.sandpoint: vmlinux $(wrapperbits)
> $(call cmd,wrap_dts_initrd,sandpoint)
>
> and:
>
> image-$(CONFIG_SANDPOINT) += zImage.sandpoint
>
> Comments?
I've been using a patch much like this while I work on getting my
platform up and running with the new bootwrapper patches. It's very
useful.
josh
^ permalink raw reply
* [PATCH/RFC] Add cmd_wrap_dts rules to arch/powerpc/boot/Makefile
From: Mark A. Greer @ 2006-10-19 0:26 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
Paul, et. al.,
Currently, platforms that don't have a dt-aware firmware need to
manually run the wrapper script to wrap a dtb into the zImage that
was just built. This is a PITA and is guaranteed to mess up people
who just want to build a zImage and have it work.
To address this, I added a couple new rules to arch/powerpc/boot/Makefile
so that the dtb is automatically wrapped for "reference" platforms.
"reference" meaning a platform that has its dts in
arch/powerpc/boot/dts/<platform>.dts. It won't work for non-reference
platforms.
The patch is attached below with a header in case it is acceptable, as
is.
This would be used by the sandpoint, say, by adding the following rules
to the Makefile in the appropriate places:
$(obj)/zImage.sandpoint: vmlinux $(wrapperbits)
$(call cmd,wrap_dts,sandpoint)
$(obj)/zImage.initrd.sandpoint: vmlinux $(wrapperbits)
$(call cmd,wrap_dts_initrd,sandpoint)
and:
image-$(CONFIG_SANDPOINT) += zImage.sandpoint
Comments?
Mark
---
[PATCH] Add cmd_wrap_dts rules to arch/powerpc/boot/Makefile
Add cmd_wrap_dts rules to bootwrapper Makefile so "make zImage" and
"make zImage.initrd" will wrap the platform's dtb in the zImage.
This eliminates the need to manually run the wrapper script a
second time just to add the dtb to the zImage.
This only works for reference platforms that have their dts files
in arch/powerpc/boot/dts/<platform>.dts.
Depends-on: http://ozlabs.org/pipermail/linuxppc-dev/2006-October/027003.html
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
---
Makefile | 7 +++++++
1 files changed, 7 insertions(+)
---
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 4b2be61..3dc4e55 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -117,6 +117,13 @@ quiet_cmd_wrap = WRAP $@
quiet_cmd_wrap_initrd = WRAP $@
cmd_wrap_initrd =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \
-i $(obj)/ramdisk.image.gz vmlinux
+quiet_cmd_wrap_dts = WRAP_DTS $@
+ cmd_wrap_dts =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \
+ -s $(obj)/dts/$2.dts vmlinux
+quiet_cmd_wrap_dts_initrd = WRAP_DTS $@
+ cmd_wrap_dts_initrd =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 \
+ $(CROSSWRAP) -s $(obj)/dts/$2.dts \
+ -i $(obj)/ramdisk.image.gz vmlinux
$(obj)/zImage.chrp: vmlinux $(wrapperbits)
$(call cmd,wrap,chrp)
^ permalink raw reply related
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