* Re: "Now booting the kernel"
From: Nathael PAJANI @ 2005-11-10 10:40 UTC (permalink / raw)
To: linuxppc-embedded
(Sorry, I first replyed with the wrong mail address)
>Linux/PPC load: console=ttyS0,9600 root=/dev/xsysace/disc0/part2 rw
>Uncompressing Linux...done.
>Now booting the kernel
Hi!
At this state the bootloader stops executing and the Linux Kernel
starts. The problem is that the Linux kernel does not know yet how to
use the serial.
You won't have any message before it is set up (in early-console if my
memory is allright)
So what you can do to check what's going on, is put "breakpoints" in the
boot sequence. This means in the file arch/ppc/kernel/head*.S used for
your board you should try to comment the line with the "tlbwe"
instruction in the section "/* 2. Invalidate all entries except the
entry we're executing in */"
This will allow you to keep access to your board registers.
Then you go step by step, putting some code which will reboot the board
when executed, so you know you're going up to that point, and then move
the "breakpoint" further.
This code does the reboot (for the booke I can reboot the board by
writting '4' at address 0xfa001001):
ASM:
lis r4,0xfa00
li r5,4
stb r5,0x1001(r4)
msync
C:
*((volatile unsigned char*)0xfa001001 = 4;
This way, instead of hanging up, the board reboots and you know where
you are.
If you're going up to this:
bl machine_init /* arch/ppc/kernel/setup.c */
bl MMU_init /* arch/ppc/mm/init.c */
It's quite good, these are C functions, but they are processor specific,
once again, check that the ones used (compiled) are those you need.
And next you've got the "start_kernel" call, which leads you to C code
definitely. It's in init/main.c.
I hope I did not tell anything wrong, and that this will help.
Have fun.
Nathael.
^ permalink raw reply
* Re: "Now booting the kernel"
From: Nathael PAJANI @ 2005-11-10 8:46 UTC (permalink / raw)
To: linuxppc-embedded
>Linux/PPC load: console=ttyS0,9600 root=/dev/xsysace/disc0/part2 rw
>Uncompressing Linux...done.
>Now booting the kernel
Hi!
At this state the bootloader stops executing and the Linux Kernel
starts. The problem is that the Linux kernel does not know yet how to
use the serial.
You won't have any message before it is set up (in early-console if my
memory is allright)
So what you can do to check what's going on, is put "breakpoints" in the
boot sequence. This means in the file arch/ppc/kernel/head*.S used for
your board you should try to comment the line with the "tlbwe"
instruction in the section "/* 2. Invalidate all entries except the
entry we're executing in */"
This will allow you to keep access to your board registers.
Then you go step by step, putting some code which will reboot the board
when executed, so you know you're going up to that point, and then move
the "breakpoint" further.
This code does the reboot (for the booke I can reboot the board by
writting '4' at address 0xfa001001):
ASM:
lis r4,0xfa00
li r5,4
stb r5,0x1001(r4)
msync
C:
*((volatile unsigned char*)0xfa001001 = 4;
This way, instead of hanging up, the board reboots and you know where
you are.
If you're going up to this:
bl machine_init /* arch/ppc/kernel/setup.c */
bl MMU_init /* arch/ppc/mm/init.c */
It's quite good, these are C functions, but they are processor specific,
once again, check that the ones used (compiled) are those you need.
And next you've got the "start_kernel" call, which leads you to C code
definitely. It's in init/main.c.
I hope I did not tell anything wrong, and that this will help.
Have fun.
Nathael.
^ permalink raw reply
* PowerPC reservations
From: Kalle Pokki @ 2005-11-10 8:20 UTC (permalink / raw)
To: linuxppc-embedded
Hi,
Can someone please help me understand how the memory reservations in
PowerPC actually work. Let's just assume uniprocessor with a pre-emptive
scheduler, and take a text-book example of an atomic increment case,
which is also frequently used in e.g. the Linux kernel. With two atomic
operations, everything seems to be just fine. But how about with three
concurrent threads of execution?
From the following code, assume r3 contains the same address for each
incrementing operation. If the first atomic increment is pre-empted in
the middle, execution then jumps to the second increment (by the
scheduler). The second increment runs through and succeeds, and
continues straight to the third increment. Then it is again pre-empted
in the middle, execution returning to the first increment. Now the
processor has the reservation with the correct address, and the first
increment succeeds when still holding the original input value. The
first and the second increment thus write the same value in memory.
After the first increment, the scheduler again continues the third
increment, which doesn't succeed a first, but the second round succeeds.
However, the value in the address pointed by r3 was not increased by
three, but by two.
Am I just not getting how this is really supposed to work? Are there
still some other constructs in use to prevent this, e.g. extra stwcx.
instructions when changing the thread of execution?
I'm also wondering why the architecture specifically defines the stwcx.
instruction to have, well, undefined behavior in case the reservation
address differs from the address of the previous lwarx...
1: lwarx r6, r0, r3
addi r6, r6, 1
stwcx. r6, r0, r3
bne- 1b
.....
2: lwarx r7, r0, r3
addi r7, r7, 1
stwcx. r7, r0, r3
bne- 2b
3: lwarx r8, r0, r3
addi r8, r8, 1
stwcx. r8, r0, r3
bne- 3b
^ permalink raw reply
* Re: [PATCH 2.6.14] mm: 8xx MM fix for
From: David Jander @ 2005-11-10 8:18 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <200511100848.46263.david.jander@protonic.nl>
On Thursday 10 November 2005 08:48, David Jander wrote:
>[...]
> Hmmm. This is a lot in the line of the tests I did with (the more generic
> benchmark) nbench. After looking at those results (see my other post in
> this thread) I already suspected something like this.
Sorry, I obviously did not mean this thread, but the following post on another
thread:
http://ozlabs.org/pipermail/linuxppc-embedded/2005-November/020775.html
Regards,
--
David Jander
^ permalink raw reply
* [PATCH] 2.6: PRTPPC board-support was: Re: about MPC 8XX SPI Driver
From: David Jander @ 2005-11-10 8:02 UTC (permalink / raw)
To: linuxppc-embedded; +Cc: 徐小威的EMAIL
In-Reply-To: <1131605445.4691.4.camel@banana>
[-- Attachment #1: Type: text/plain, Size: 589 bytes --]
On Thursday 10 November 2005 07:50, 徐小威的EMAIL wrote:
> Anybody know where can found 'CPM SPI Driver' for MPC852T.I found a
> cpm_spi.c at /arch/ppc/8260_io directory in Linux 2.4.25.But I don't
> know how to program application to
> handle this driver.
Do you want it for 2.4 or 2.6? (I have both running on a mpc852T).
Here's a patch for 2.6.14 (denx-git tree).
Sorry to send you the complete patch for prtppc board support, but the spi
driver makes up most part of it, so it wouldn't be much smaller anyway ;-)
Regards,
--
David Jander
Protonic Holland.
[-- Attachment #2: linux-2.6.14-20051107-prt.patch --]
[-- Type: text/x-diff, Size: 33276 bytes --]
diff --git a/arch/ppc/8xx_io/Kconfig b/arch/ppc/8xx_io/Kconfig
--- a/arch/ppc/8xx_io/Kconfig
+++ b/arch/ppc/8xx_io/Kconfig
@@ -77,6 +77,14 @@ config ENET_BIG_BUFFERS
config HTDMSOUND
bool "Embedded Planet HIOX Audio"
depends on SOUND=y
+
+config CPM_SPI
+ bool "Simple CPM SPI driver"
+
+config CPM_SPI_BDSIZE
+ int "Size of Rx/Tx Buffer for SPI"
+ depends on CPM_SPI
+ default "16"
# This doesn't really belong here, but it is convenient to ask
# 8xx specific questions.
diff --git a/arch/ppc/8xx_io/Makefile b/arch/ppc/8xx_io/Makefile
--- a/arch/ppc/8xx_io/Makefile
+++ b/arch/ppc/8xx_io/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_FEC_ENET) += fec.o
obj-$(CONFIG_SCC_ENET) += enet.o
obj-$(CONFIG_UCODE_PATCH) += micropatch.o
obj-$(CONFIG_HTDMSOUND) += cs4218_tdm.o
+obj-$(CONFIG_CPM_SPI) += cpm_spi.o
diff --git a/arch/ppc/8xx_io/cpm_spi.c b/arch/ppc/8xx_io/cpm_spi.c
new file mode 100644
--- /dev/null
+++ b/arch/ppc/8xx_io/cpm_spi.c
@@ -0,0 +1,448 @@
+/*
+ * Simple CPM SPI interface for the MPC 8xx.
+ *
+ * Copyright (c) 2002 Wolfgang Grandegger (wg@denx.de)
+ *
+ * This interface is partially derived from code copyrighted
+ * by Navin Boppuri (nboppuri@trinetcommunication.co) and
+ * Prashant Patel (pmpatel@trinetcommunication.com).
+ *
+ * This driver implements the function "cpm_spi_io()" to be
+ * used by other drivers and a simple read/write interface
+ * for user-land applications. The latter is mainly useful
+ * for debugging purposes. Some further remarks:
+ *
+ * - Board specific definitions and code should go into
+ * the file "cpm_spi.h".
+ *
+ * - For the moment, no interrupts are used. This be useful
+ * for (very) long transfers.
+ *
+ * Ported back from 2.4.25/mpc82xx to 2.6.14/mpc8xx by
+ * David Jander (david@protonic.nl)
+ *
+ */
+
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB /* need this one 'cause we export symbols */
+#endif
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/proc_fs.h>
+#include <linux/device.h>
+#include <asm/page.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#include <asm/8xx_immap.h>
+#include <asm/mpc8xx.h>
+
+#include <asm/commproc.h>
+#include <asm/cpm_spi.h>
+
+#define DRIVER_NAME "cmp_spi"
+
+MODULE_AUTHOR("Wolfgang Grandegger (wg@denx.de)");
+MODULE_DESCRIPTION("Simple Driver for the CPM SPI");
+
+#undef DEBUG
+#ifdef DEBUG
+# define debugk(fmt,args...) printk(fmt ,##args)
+#else
+# define debugk(fmt,args...)
+#endif
+
+#if defined(CONFIG_SCC2_ENET) && !defined(CONFIG_UCODE_PATCH)
+#error "I2C/SPI Microcode Patch is needed, please enable it!"
+#endif
+
+#define CPM_SPI_MAJOR 65 /* "borrowed" from "plink" driver */
+
+extern void invalidate_dcache_range(unsigned long start, unsigned long end);
+
+static volatile immap_t *immap = (immap_t *)IMAP_ADDR;
+
+static unsigned int dp_addr;
+static ushort r_tbase, r_rbase;
+static cbd_t *tx_bdf, *rx_bdf;
+static u_char *tx_buf, *rx_buf;
+
+#if CPM_SPI_SWAP_BYTES
+static void swap_bytes(u_char *buf, int len)
+{
+ u_short *sbuf = (u_short *)buf;
+ while (len > 0) {
+ *sbuf = cpu_to_le16(*sbuf);
+ sbuf++;
+ len -= 2;
+ }
+}
+#else
+#define swap_bytes(buf, len)
+#endif
+
+/*
+ * CPM SPI Kernel API function(s)
+ */
+ssize_t cpm_spi_io (int chip_id, int serial,
+ u_char *tx_buffer, int tx_size,
+ u_char *rx_buffer, int rx_size)
+{
+ unsigned long flags;
+ int i;
+
+ /*
+ * Serialize access to the SPI. We have to disable interrupts
+ * because we may need to call it from interrupt handlers.
+ */
+ local_irq_save(flags); local_irq_disable();
+
+ rx_bdf->cbd_datlen = 0;
+ if (serial)
+ tx_bdf->cbd_datlen = tx_size + rx_size;
+ else
+ tx_bdf->cbd_datlen = tx_size > rx_size ? tx_size : rx_size;
+ if (tx_bdf->cbd_datlen > CONFIG_CPM_SPI_BDSIZE) {
+ printk("cpm_spi_io: Invalid size\n");
+ local_irq_restore(flags);
+ return -EINVAL;
+ }
+ if (tx_size > 0) {
+ memcpy(tx_buf, tx_buffer, tx_size);
+#ifdef DEBUG
+ printk("Tx:");
+ for (i = 0; i < tx_size; i++)
+ printk(" %02x", tx_buf[i]);
+ printk("\n");
+#endif
+ swap_bytes(tx_buf, tx_size);
+ }
+
+ flush_dcache_range((unsigned long) tx_buf,
+ (unsigned long) (tx_buf+CONFIG_CPM_SPI_BDSIZE-1));
+ flush_dcache_range((unsigned long) rx_buf,
+ (unsigned long) (rx_buf+CONFIG_CPM_SPI_BDSIZE-1));
+ invalidate_dcache_range((unsigned long) rx_buf,
+ (unsigned long) (rx_buf+
+ CONFIG_CPM_SPI_BDSIZE-1));
+
+ /* Setting Rx and Tx BD status and data length */
+ tx_bdf->cbd_sc = BD_SC_READY | BD_SC_LAST | BD_SC_WRAP;
+ rx_bdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
+
+ /* Chip select for device */
+ cpm_spi_set_cs(immap, chip_id, 1);
+
+ /* Start SPI Tx/Rx transfer */
+ cpmp->cp_spcom |= 0x80;
+
+ /*
+ * Wait until the Tx/Rx transfer is done.
+ */
+ for (i = 0; i < CPM_SPI_POLL_RETRIES; i++) {
+ udelay(1);
+ if ((tx_bdf->cbd_sc & BD_SC_EMPTY) == 0 &&
+ (rx_bdf->cbd_sc & BD_SC_EMPTY) == 0)
+ break;
+ }
+
+ /* De-select device */
+ cpm_spi_set_cs(immap, chip_id, 0);
+
+ /* Check for timeout */
+ if (i == CPM_SPI_POLL_RETRIES) {
+ printk("cpm_spi_io: Tx/Rx transfer timeout\n");
+ local_irq_restore(flags);
+ return -EIO;
+ }
+
+#ifdef DEBUG
+ printk("Transfer time approx. %d us\n", i);
+ if (rx_bdf->cbd_datlen > 0) {
+ printk("Rx:");
+ for (i = 0; i < rx_bdf->cbd_datlen; i++)
+ printk(" %02x", rx_buf[i]);
+ printk("\n");
+ }
+#endif
+
+ /* Copy receive data if appropriate */
+ i = rx_bdf->cbd_datlen;
+#ifdef DEBUG
+ if (i != tx_bdf->cbd_datlen)
+ {
+ printk("i=%d tx_size=%d rx_size=%d\n", i, tx_size, rx_size);
+ }
+#endif
+ if (i > tx_bdf->cbd_datlen)
+ {
+ local_irq_restore(flags);
+ return -EIO;
+ }
+ swap_bytes(rx_buf, i);
+ if (rx_size > 0) {
+ if (serial) {
+ i -= tx_size;
+ memcpy(rx_buffer, rx_buf + tx_size, i);
+ } else {
+ memcpy(rx_buffer, rx_buf, i);
+ }
+ }
+
+ local_irq_restore(flags);
+
+ return i;
+}
+
+EXPORT_SYMBOL(cpm_spi_io);
+
+/*
+ * Prototypes for driver entry functions.
+ */
+static int
+cpm_spi_open(struct inode *inode, struct file *filp);
+static int
+cpm_spi_release(struct inode *inode, struct file *filp);
+static ssize_t
+cpm_spi_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);
+static ssize_t
+cpm_spi_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos);
+static int
+cpm_spi_init(void);
+static void
+cpm_spi_cleanup(void);
+
+/*
+ * File operations supported by this driver.
+ */
+struct file_operations cpm_spi_fops = {
+ owner: THIS_MODULE,
+ open: cpm_spi_open,
+ release: cpm_spi_release,
+ read: cpm_spi_read,
+ write: cpm_spi_write,
+};
+
+
+static int
+cpm_spi_open (struct inode *inode, struct file *filp)
+{
+ int minor = MINOR(inode->i_rdev);
+
+ if (minor >= CPM_SPI_MAX_CHIPS)
+ return -ENODEV;
+
+ filp->private_data = (void *)minor;
+ // MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static int
+cpm_spi_release(struct inode *inode, struct file *filp)
+{
+ // MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+static ssize_t
+cpm_spi_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
+{
+ u_char tx_kbuf[CONFIG_CPM_SPI_BDSIZE];
+ u_char rx_kbuf[CONFIG_CPM_SPI_BDSIZE];
+ int chip_id = (int)filp->private_data;
+ ssize_t size;
+
+ debugk("cpm_spi_read: count=%d, chip_id=%d\n", count, chip_id);
+
+ if (count > CONFIG_CPM_SPI_BDSIZE)
+ return -ENXIO;
+
+ if (copy_from_user(tx_kbuf, buf, count))
+ return -EFAULT;
+
+ size = cpm_spi_io(chip_id, 0, tx_kbuf, count, rx_kbuf, count);
+ if (size < 0)
+ return size;
+
+ if (copy_to_user(buf, rx_kbuf, size))
+ return -EFAULT;
+
+ return size;
+}
+
+static ssize_t
+cpm_spi_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
+{
+ int chip_id = (int)filp->private_data;
+ u_char tx_kbuf[CONFIG_CPM_SPI_BDSIZE];
+
+ if (count > CONFIG_CPM_SPI_BDSIZE)
+ return -ENXIO;
+
+ if (copy_from_user(tx_kbuf, buf, count))
+ return -EFAULT;
+
+ return cpm_spi_io(chip_id, 0, tx_kbuf, count, NULL, 0);
+}
+
+/* Tx and Rx buffers are so small, we don't need to worry about
+ * consistent alloc. Just make them static here (ugly, but simple).
+ */
+static unsigned char txbufspace[CONFIG_CPM_SPI_BDSIZE];
+static unsigned char rxbufspace[CONFIG_CPM_SPI_BDSIZE];
+
+static int
+cpm_spi_init(void)
+{
+ int err = 0;
+ volatile spi_t *spi;
+
+
+ printk (KERN_INFO "CPM SPI Driver: $Revision: 1.1 $ wg@denx.de\n");
+
+ /* Global pointer to internal registers */
+ immap = (immap_t *)IMAP_ADDR;
+
+ spi = (spi_t *)&cpmp->cp_dparam[PROFF_SPI];
+
+#ifdef USE_IIC_PATCH
+ /* Check for and use a microcode relocation patch. */
+ if (spi->spi_rpbase)
+ spi = (spi_t *)&cpmp->cp_dpmem[spi->spi_rpbase];
+ printk("cpm_spi: using microcode patch (spi_rpbase=0x%p)\n", spi);
+#endif
+
+ /*
+ * Initialize the parameter RAM. We need to make sure
+ * many things are initialized to zero, especially in
+ * the case of a microcode patch.
+ */
+ spi->spi_rdp = 0;
+ spi->spi_rbptr = 0;
+ spi->spi_rbc = 0;
+ spi->spi_rxtmp = 0;
+ spi->spi_tstate = 0;
+ spi->spi_tdp = 0;
+ spi->spi_tbptr = 0;
+ spi->spi_tbc = 0;
+ spi->spi_txtmp = 0;
+
+ /*
+ * Allocate space for one transmit and one receive buffer
+ * descriptor in the DP RAM.
+ */
+ dp_addr = cpm_dpalloc(sizeof(cbd_t) * 2,0);
+ if (dp_addr == CPM_DP_NOSPACE) {
+ printk("cpm_spi: m8xx_cpm_dpalloc() failed\n");
+ return -ENOMEM;
+ }
+
+ /*
+ * Set up the IIC parameters in the parameter RAM.
+ */
+ spi->spi_rbase = r_rbase = dp_addr;
+ spi->spi_tbase = r_tbase = dp_addr + sizeof(cbd_t);
+
+ /*
+ * Setting transmit and receive buffer descriptor pointers
+ * intially to rbase and rbase.
+ */
+ spi->spi_rbptr = spi->spi_rbase;
+ spi->spi_tbptr = spi->spi_tbase;
+
+ /* Setting CPCR */
+ while(cpmp->cp_cpcr & CPM_CR_FLG) ;
+ cpmp->cp_cpcr |=
+ mk_cr_cmd(CPM_CR_CH_SPI, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+ udelay(1);
+ while(cpmp->cp_cpcr & CPM_CR_FLG) ;
+
+ /* Sets the SDMA configuration register. */
+ immap->im_siu_conf.sc_sdcr = 0x0001;
+
+ /* Set to big endian. */
+ spi->spi_tfcr = SMC_EB;
+ spi->spi_rfcr = SMC_EB;
+
+ /* Set maximum receive size. */
+ spi->spi_mrblr = CONFIG_CPM_SPI_BDSIZE;
+
+ /*
+ * Clear all pending SPI events and mask all possible SPI
+ * interrupts. For the moment we don't use interrupts.
+ */
+ cpmp->cp_spie = 0xff;
+ cpmp->cp_spim = 0x00;
+
+ /*
+ * Set SPI Mode register.
+ * Note: the board-specific definitions are in cpm_spi.h.
+ */
+ cpmp->cp_spmode = CPM_SPI_SPMODE | SPMODE_EN;
+
+ /*
+ * Initiliaze port pins for SPI
+ * par dir odr
+ * PB28 -> SPIMISO: 1 1 0
+ * PB29 -> SPIMOSI: 1 1 0
+ * PB30 -> SPICLK : 1 1 0
+ */
+ cpmp->cp_pbpar |= 0x000e;
+ cpmp->cp_pbdir |= 0x000e;
+ cpmp->cp_pbodr &= ~(0x000e);
+
+ /*
+ * Initialize board-specific port for chip select etc.
+ * Note: the board-specific definitions are in cpm_spi.h.
+ */
+ cpm_spi_init_ports(immap);
+
+ /* Tx and Rx buffer descriptors. */
+ tx_bdf = (cbd_t *)&cpmp->cp_dpmem[r_tbase];
+ rx_bdf = (cbd_t *)&cpmp->cp_dpmem[r_rbase];
+
+ /* Initialize Tx and Tx BD's */
+ rx_bdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
+ tx_bdf->cbd_sc = BD_SC_LAST | BD_SC_WRAP;
+
+ /* Allocate memory for Rx and Tx buffers */
+ tx_buf = (u_char *)txbufspace;
+ rx_buf = (u_char *)rxbufspace;
+ debugk("rxbuf = 0x%p tx_buf = 0x%p\n", rx_buf, tx_buf);
+
+ /* Set the bd's rx and tx buffer address pointers */
+ tx_bdf->cbd_bufaddr = virt_to_bus(tx_buf);
+ rx_bdf->cbd_bufaddr = virt_to_bus(rx_buf);
+ debugk("pa:rxbuf = 0x%p pa:tx_buf = 0x%p\n", rx_bdf->cbd_bufaddr, tx_bdf->cbd_bufaddr);
+
+ /*
+ * Finally register the driver.
+ */
+ err = register_chrdev(CPM_SPI_MAJOR, DRIVER_NAME, &cpm_spi_fops);
+ if (err < 0) {
+ printk("cpm_spi: Couldn't register driver (major=%d)\n",
+ CPM_SPI_MAJOR);
+ return err;
+ }
+
+ return 0;
+}
+
+static void
+cpm_spi_cleanup(void)
+{
+ unregister_chrdev(CPM_SPI_MAJOR, DRIVER_NAME);
+ cpm_dpfree(dp_addr);
+}
+
+module_init(cpm_spi_init);
+module_exit(cpm_spi_cleanup);
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -504,6 +504,13 @@ config WINCEPT
MPC821 PowerPC, introduced in 1998 and designed to be used in
thin-client machines. Say Y to support it directly.
+config PRTPPC
+ bool "PRTPPC"
+ help
+ PRTPPC is a single-board computer module based on a Freescale MPC852T
+ embedded processor. It is used in different products designed and
+ manufactured by Protonic Holland.
+
endchoice
choice
@@ -954,6 +961,16 @@ config NR_CPUS
config HIGHMEM
bool "High memory support"
+config PRT_IOADDR
+ hex "PRTPPC IO-address space start"
+ depends on PRTPPC
+ default "0xf8100000"
+
+config PRT_IOSIZE
+ hex "PRTPPC IO-address space size"
+ depends on PRTPPC
+ default "0x00040000"
+
source kernel/Kconfig.hz
source kernel/Kconfig.preempt
source "mm/Kconfig"
diff --git a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile
--- a/arch/ppc/platforms/Makefile
+++ b/arch/ppc/platforms/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_SBC82xx) += sbc82xx.o
obj-$(CONFIG_SPRUCE) += spruce.o
obj-$(CONFIG_LITE5200) += lite5200.o
obj-$(CONFIG_EV64360) += ev64360.o
+obj-$(CONFIG_PRTPPC) += prtppc_setup.o
ifeq ($(CONFIG_SMP),y)
obj-$(CONFIG_PPC_PMAC) += pmac_smp.o
diff --git a/arch/ppc/platforms/prtppc.h b/arch/ppc/platforms/prtppc.h
new file mode 100644
--- /dev/null
+++ b/arch/ppc/platforms/prtppc.h
@@ -0,0 +1,40 @@
+/*
+ * PRTPPC board definitions, loosely based on:
+ * TQM8xx(L/M) board specific definitions
+ *
+ * Author: David Jander <david@protonic.nl>
+ *
+ * Copyright (c) 2005 Protonic Holland b.v.
+ *
+ * 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.
+ */
+
+#ifndef __PRTPPC_H__
+#define __PRTPPC_H__
+
+#include <linux/config.h>
+
+#include <asm/ppcboot.h>
+
+#define BOARD_CHIP_NAME "MPC86X"
+
+#define PRTPPC_IMMR_BASE 0xF8000000 /* phys. addr of IMMR */
+#define PRTPPC_IMAP_SIZE (64 * 1024) /* size of mapped area */
+
+#define IMAP_ADDR PRTPPC_IMMR_BASE /* physical base address of IMMR area */
+#define IMAP_SIZE PRTPPC_IMAP_SIZE /* mapped size of IMMR area */
+
+/* define IO_BASE for External bus devices */
+#define _IO_BASE CONFIG_PRT_IOADDR
+#define _IO_BASE_SIZE CONFIG_PRT_IOSIZE
+
+#define FEC_INTERRUPT 9 /* = SIU_LEVEL4 */
+
+/* We don't use the 8259.
+*/
+#define NR_8259_INTS 0
+
+#endif /* __PRTPPC_H__ */
diff --git a/arch/ppc/platforms/prtppc_serial.h b/arch/ppc/platforms/prtppc_serial.h
new file mode 100644
--- /dev/null
+++ b/arch/ppc/platforms/prtppc_serial.h
@@ -0,0 +1,100 @@
+/*
+ * include/asm-ppc/prtppc_serial.h
+ *
+ * Definitions for Protonic PRTPPC board multi-uart interface
+ * Usable for PRTACM and MSAMPS doughterboards.
+ *
+ * Author: David Jander <david@protonic.nl>
+ *
+ * Copyright (c) 2005 Protonic Holland b.v.
+ *
+ * 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.
+ */
+
+#ifndef __PRTPPC_SERIAL_H
+#define __PRTPPC_SERIAL_H
+
+#include <linux/config.h>
+
+/* Make room for 3 mpc8xx SCM devices at minor 64,65 and 66 */
+// #define SERIAL_DEV_OFFSET 3
+
+#if !defined(CONFIG_PRT_UARTADDR)
+#define CONFIG_PRT_UARTADDR _IO_BASE
+#endif
+
+/* Define the UART base addresses and IRQs */
+#define PRTPPC_UART0_BASE (CONFIG_PRT_UARTADDR)
+#define PRTPPC_UART1_BASE (CONFIG_PRT_UARTADDR + 8)
+#define PRTPPC_UART2_BASE (CONFIG_PRT_UARTADDR + 16)
+#define PRTPPC_UART3_BASE (CONFIG_PRT_UARTADDR + 24)
+#define PRTPPC_UART4_BASE (CONFIG_PRT_UARTADDR + 32)
+#define PRTPPC_UART5_BASE (CONFIG_PRT_UARTADDR + 40)
+#define PRTPPC_UART6_BASE (CONFIG_PRT_UARTADDR + 48)
+#define PRTPPC_UART7_BASE (CONFIG_PRT_UARTADDR + 56)
+
+/* On PRTACM there are 2 16C554 quad uart chips, with INTx outputs
+ * Negted and OR'd together 4 on 1.
+ * Chip one goes to IRQ1, Chip two to IRQ2
+ */
+#define PRTPPC_UART0_IRQ SIU_IRQ1
+#define PRTPPC_UART1_IRQ SIU_IRQ1
+#define PRTPPC_UART2_IRQ SIU_IRQ1
+#define PRTPPC_UART3_IRQ SIU_IRQ1
+#define PRTPPC_UART4_IRQ SIU_IRQ2
+#define PRTPPC_UART5_IRQ SIU_IRQ2
+#define PRTPPC_UART6_IRQ SIU_IRQ2
+#define PRTPPC_UART7_IRQ SIU_IRQ2
+
+
+#ifdef CONFIG_SERIAL_MANY_PORTS
+#define RS_TABLE_SIZE 16
+#else
+#define RS_TABLE_SIZE 8
+#endif
+
+/* Rate for the 1.8432 Mhz clock for the onboard serial chip */
+#define BASE_BAUD ( 1843200 / 16 )
+
+/* AUTO_IRQ is scary, but maybe it even works :-) */
+#ifdef CONFIG_SERIAL_DETECT_IRQ
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ)
+#else
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST)
+#endif
+
+/* Define a prototype UART entry.... */
+#define STD_SERIAL_PORT_ITEM(num) \
+ { 0, BASE_BAUD, PRTPPC_UART##num##_BASE, \
+ PRTPPC_UART##num##_IRQ, \
+ STD_COM_FLAGS, \
+ iomem_base: (u8 *)PRTPPC_UART##num##_BASE, \
+ iomem_reg_shift: 0, \
+ io_type: SERIAL_IO_MEM }
+
+/* Make a table from it */
+#if (CONFIG_SERIAL_8250_NR_UARTS > 4)
+#define STD_SERIAL_PORT_DFNS \
+ STD_SERIAL_PORT_ITEM(0), \
+ STD_SERIAL_PORT_ITEM(1), \
+ STD_SERIAL_PORT_ITEM(2), \
+ STD_SERIAL_PORT_ITEM(3), \
+ STD_SERIAL_PORT_ITEM(4), \
+ STD_SERIAL_PORT_ITEM(5), \
+ STD_SERIAL_PORT_ITEM(6), \
+ STD_SERIAL_PORT_ITEM(7)
+#else
+#define STD_SERIAL_PORT_DFNS \
+ STD_SERIAL_PORT_ITEM(0), \
+ STD_SERIAL_PORT_ITEM(1), \
+ STD_SERIAL_PORT_ITEM(2), \
+ STD_SERIAL_PORT_ITEM(3)
+#endif /* CONFIG_SERIAL_8250_NR_UARTS */
+
+#define SERIAL_PORT_DFNS \
+ STD_SERIAL_PORT_DFNS
+
+#endif /* __PRTPPC_SERIAL_H */
diff --git a/arch/ppc/platforms/prtppc_setup.c b/arch/ppc/platforms/prtppc_setup.c
new file mode 100644
--- /dev/null
+++ b/arch/ppc/platforms/prtppc_setup.c
@@ -0,0 +1,88 @@
+/*
+ * arch/ppc/platforms/prtppc_setup.c
+ *
+ * PRTPPC platform support
+ *
+ * Author: David Jander <david@protonic.nl>
+ *
+ * Copyright (c) 2005 Protonic Holland b.v.
+ *
+ * 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/init.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/usb_isp116x.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+
+#include <asm/mpc8xx.h>
+#include <asm/8xx_immap.h>
+#include <asm/machdep.h>
+#include <asm/irq.h>
+#include <asm/delay.h>
+
+struct resource prt_isp1160_resource[] =
+{
+ {
+ .name = "isp1160_data",
+ .flags = IORESOURCE_MEM,
+ .start = 0xf8100040,
+ .end = 0xf8100041,
+ },
+ {
+ .name = "isp1160_addr",
+ .flags = IORESOURCE_MEM,
+ .start = 0xf8100042,
+ .end = 0xf8100043,
+ },
+ {
+ .name = "isp1160_irq",
+ .flags = IORESOURCE_IRQ,
+ .start = SIU_IRQ6,
+ .end = SIU_IRQ6,
+ }
+};
+
+
+void platform_delay(struct device * dev, int delay)
+{
+ ndelay(delay);
+}
+
+struct isp116x_platform_data isp1160_config =
+{
+ .sel15Kres = 1,
+ .oc_enable = 1,
+ .int_act_high = 0,
+ .int_edge_triggered = 1,
+ .remote_wakeup_enable = 0,
+ .delay = platform_delay,
+};
+
+void __init prtppc_platform_init(void)
+{
+ struct platform_device *pdev;
+ static volatile immap_t *immap = (immap_t *)IMAP_ADDR;
+
+ printk("prtppc_platform_init()\n");
+
+ pdev = platform_device_register_simple("isp116x-hcd",0,prt_isp1160_resource,3);
+ pdev->dev.platform_data = &isp1160_config;
+
+ /* Configure SIU_IRQ6 as edge triggered */
+ immap->im_siu_conf.sc_siel |= 0x00080000;
+ irq_desc[SIU_IRQ6].status &= ~IRQ_LEVEL;
+}
+
+/* Anything special for this platform */
+void __init board_init(void)
+{
+ /* Register a platform_init function */
+ ppc_md.init=prtppc_platform_init;
+}
diff --git a/arch/ppc/syslib/m8xx_setup.c b/arch/ppc/syslib/m8xx_setup.c
--- a/arch/ppc/syslib/m8xx_setup.c
+++ b/arch/ppc/syslib/m8xx_setup.c
@@ -367,7 +367,7 @@ m8xx_map_io(void)
#ifdef CONFIG_PCI
io_block_mapping(PCI_CSR_ADDR, PCI_CSR_ADDR, PCI_CSR_SIZE, _PAGE_IO);
#endif
-#if defined(CONFIG_NETTA)
+#if defined(CONFIG_NETTA) || defined (CONFIG_PRTPPC)
io_block_mapping(_IO_BASE,_IO_BASE,_IO_BASE_SIZE, _PAGE_IO);
#endif
}
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -10,7 +10,8 @@ menu "USB support"
config USB_ARCH_HAS_HCD
boolean
default y if USB_ARCH_HAS_OHCI
- default y if ARM # SL-811
+ default y if ARM # SL-811
+ default y if PRTPPC
default PCI
# many non-PCI SOC chips embed OHCI
diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h
--- a/drivers/usb/host/isp116x.h
+++ b/drivers/usb/host/isp116x.h
@@ -365,6 +365,33 @@ struct isp116x_ep {
#define IRQ_TEST() do{}while(0)
#endif
+#if defined(CONFIG_PRTPPC)
+/* On the PRTPPC the ISP1160 is connected through an 8-bit bus via a CPLD
+ * which translates the 8-bit data to 16-bit back and forth.
+ * The UPM splits the 16-bit bus-cycles up into two 8-bit cycles.
+ * The only caveat is that on writing, we have to write to the higher address first
+ * and then to the lower address, while on reading it has to be done the other way around,
+ * that is first the lower address and then the higher address.
+ * So for reading we can use normal 16-bit read functions, while for writing,
+ * we just redefine (temporarily) writew() and __raw_writew() to these below.
+ */
+static void inline writew_hcd(unsigned int port,u16 data)
+{
+ out_8((volatile unsigned char __iomem *)(port | 0x00000001), (data>>8) & 0x00ff);
+ out_8((volatile unsigned char __iomem *)(port & 0xfffffffe), data & 0x00ff);
+}
+
+static void inline raw_writew_hcd(unsigned int port,u16 data)
+{
+ __raw_writeb(data & 0x00ff, (volatile unsigned char __iomem *)(port | 0x00000001));
+ __raw_writeb((data>>8) & 0x00ff, (volatile unsigned char __iomem *)(port & 0xfffffffe));
+}
+
+#define writew(b,a) writew_hcd((unsigned int)(a),b)
+#define __raw_writew(b,a) raw_writew_hcd((unsigned int)(a),b)
+
+#endif /* CONFIG_PRTPPC */
+
static inline void isp116x_write_addr(struct isp116x *isp116x, unsigned reg)
{
IRQ_TEST();
@@ -421,6 +448,11 @@ static inline u32 isp116x_read_data32(st
return val;
}
+#if defined(CONFIG_PRTPPC)
+#undef writew
+#undef __raw_writew
+#endif /* CONFIG_PRTPPC */
+
/* Let's keep register access functions out of line. Hint:
we wait at least 150 ns at every access.
*/
diff --git a/include/asm-ppc/cpm_spi.h b/include/asm-ppc/cpm_spi.h
new file mode 100644
--- /dev/null
+++ b/include/asm-ppc/cpm_spi.h
@@ -0,0 +1,340 @@
+/*
+ * Simple CPM SPI interface for the MPC 8260 and MPC 8xx.
+ *
+ * Copyright (c) 2002 Wolfgang Grandegger (wg@denx.de)
+ *
+ * This interface is partly derived from code copyrighted
+ * by Navin Boppuri (nboppuri@trinetcommunication.co) and
+ * Prashant Patel (pmpatel@trinetcommunication.com).
+ */
+
+#ifndef __CPM_SPI_H
+#define __CPM_SPI_H
+
+#define SPMODE_LEN(x) (((x) - 1) << 4)
+
+#define CPM_SPI_POLL_RETRIES 1000 /* in micro-seconds */
+
+/*
+ * Board specific setting and functions:
+ *
+ * CPM_SPI_MAX_CHIPS: Maximum number of chips on the SPI.
+ *
+ * CPM_SPI_CLOCK: the bitwise or of the DIV16 and PM bits,
+ * see 16.12.4.1 in the MPC823e User's Manual.
+ *
+ * CPM_SPI_MODE : SPI mode setting,
+ * see 16.12.4.1 in the MPC823e User's Manual.
+ *
+ */
+
+#ifdef CONFIG_R360MPI
+/* There are two MPC2510 connected to the SPI */
+
+#define CPM_SPI_MAX_CHIPS 2
+#if 1
+#define CPM_SPI_BITS_PER_CHAR 8
+#define CPM_SPI_SWAP_BYTES 0
+#else
+#define CPM_SPI_BITS_PER_CHAR 16
+#define CPM_SPI_SWAP_BYTES 1
+#endif
+
+/* There are read timeouts with a clock value of 2 */
+#define CPM_SPI_CLOCK 3
+
+#define CPM_SPI_SPMODE (SPMODE_REV | SPMODE_MSTR | \
+ SPMODE_LEN(CPM_SPI_BITS_PER_CHAR) |\
+ CPM_SPI_CLOCK)
+
+static inline void
+cpm_spi_init_ports (volatile immap_t *immap)
+{
+ volatile iop8xx_t *iop = &immap->im_ioport;
+ /* we use PC14 and PC15 for chip select */
+ iop->iop_pcpar &= ~(0x0003);
+ iop->iop_pcdir |= 0x0003;
+ iop->iop_pcso &= ~(0x0003);
+ iop->iop_pcdat |= 0x0003 ; /* de-select */
+}
+
+static inline void
+cpm_spi_set_cs (volatile immap_t *immap, int id, int select)
+{
+ volatile iop8xx_t *iop = &immap->im_ioport;
+ /* we use PC14/PC15 for chip 0/1 select */
+ if (select)
+ iop->iop_pcdat &= ~(2 >> id);
+ else
+ iop->iop_pcdat |= (2 >> id);
+}
+
+#elif defined(CONFIG_HMI10)
+
+#define CPM_SPI_MAX_CHIPS 1
+#define CPM_SPI_BITS_PER_CHAR 8
+#define CPM_SPI_SWAP_BYTES 0
+
+#define CPM_SPI_CLOCK 15
+
+#define CPM_SPI_SPMODE (SPMODE_CP | SPMODE_REV | SPMODE_MSTR | \
+ SPMODE_LEN(CPM_SPI_BITS_PER_CHAR) |\
+ CPM_SPI_CLOCK)
+
+static inline void
+cpm_spi_init_ports (volatile immap_t *immap)
+{
+ volatile iop8xx_t *iop = &immap->im_ioport;
+ /* we use PA6 for chip select */
+ iop->iop_papar &= ~(0x0200);
+ iop->iop_padir |= 0x0200;
+ iop->iop_padat |= 0x0200 ; /* de-select */
+}
+
+static inline void
+cpm_spi_set_cs (volatile immap_t *immap, int id, int select)
+{
+ volatile iop8xx_t *iop = &immap->im_ioport;
+ /* we use PA6 for chip select */
+ if (select)
+ iop->iop_padat &= ~(0x0200);
+ else
+ iop->iop_padat |= (0x0200);
+}
+
+#elif defined (CONFIG_PM826)
+/* There are two MPC2510 connected to the SPI */
+
+#define CPM_SPI_MAX_CHIPS 32
+#if 0
+#define CPM_SPI_BITS_PER_CHAR 8
+#define CPM_SPI_SWAP_BYTES 0
+#else
+#define CPM_SPI_BITS_PER_CHAR 16
+#define CPM_SPI_SWAP_BYTES 1
+#endif
+
+/* There are read timeouts with a clock value of 2 */
+#define CPM_SPI_CLOCK 0
+
+#define CPM_SPI_SPMODE (SPMODE_REV | SPMODE_MSTR | \
+ SPMODE_LEN(CPM_SPI_BITS_PER_CHAR) |\
+ CPM_SPI_CLOCK)
+
+/*
+ * Pin configuration:
+ *
+ * SEL:
+ * PD19
+ *
+ * CS:
+ * PA9 PA8 PB17 PB16 PB13 PB12
+ * High Low
+ *
+ * IRQ:
+ * PC7 PC6 PC5 PC4 PC3 PC2 PC1
+ * High Low
+ */
+
+static inline void
+cpm_spi_init_ports (volatile immap_t *immap)
+{
+ volatile iop8260_t *iop = &immap->im_ioport;
+
+ /* Configure CS pins */
+ iop->iop_ppara &= ~0x00c00000;
+ iop->iop_pdira |= 0x00c00000;
+ iop->iop_podra &= ~0x00c00000;
+ iop->iop_pdata &= ~0x00c00000;
+
+ iop->iop_pparb &= ~0x000cc000;
+ iop->iop_pdirb |= 0x000cc000;
+ iop->iop_podrb &= ~0x000cc000;
+ iop->iop_pdatb &= ~0x000cc000;
+
+ iop->iop_ppard &= ~0x00001000;
+ iop->iop_pdird |= 0x00001000;
+ iop->iop_podrd &= ~0x00001000;
+ iop->iop_podrd |= 0x00001000;
+
+ /* Configure IRQ pins */
+ iop->iop_pparc &= ~0x7f000000;
+ iop->iop_pdirc &= ~0x7f000000;
+ iop->iop_podrc |= 0x7f000000;
+}
+
+static inline void
+cpm_spi_set_cs (volatile immap_t *immap, int id, int select)
+{
+ volatile iop8260_t *iop = &immap->im_ioport;
+ unsigned long portb, porta;
+
+ if (select) {
+ iop->iop_pdatd |= 0x00001000;
+
+ porta = portb = 0;
+ if (id & 0x01) portb |= 0x00080000;
+ if (id & 0x02) portb |= 0x00040000;
+ if (id & 0x04) portb |= 0x00008000;
+ if (id & 0x08) portb |= 0x00004000;
+ if (id & 0x10) porta |= 0x00800000;
+ if (id & 0x20) porta |= 0x00400000;
+
+ iop->iop_pdata = (iop->iop_pdata & ~0x00c00000) | porta;
+ iop->iop_pdatb = (iop->iop_pdatb & ~0x000cc000) | portb;
+ iop->iop_pdatd &= ~0x00001000;
+
+ } else {
+#if 0 /* SEL line won't work correctly */
+ iop->iop_pdatd |= 0x00001000;
+#else
+ iop->iop_pdata &= ~0x00c00000;
+ iop->iop_pdatb &= ~0x000cc000;
+#endif
+ }
+}
+
+static inline int
+cpm_spi_get_irq_cs (void)
+{
+ volatile immap_t *immap = (immap_t *)IMAP_ADDR;
+ volatile iop8260_t *iop = &immap->im_ioport;
+ unsigned long portc;
+ int irq;
+
+ portc = iop->iop_pdatc;
+
+ irq = 0;
+ if (portc & 0x01000000) irq += 64;
+ if (portc & 0x02000000) irq += 32;
+ if (portc & 0x04000000) irq += 16;
+ if (portc & 0x08000000) irq += 8;
+ if (portc & 0x10000000) irq += 4;
+ if (portc & 0x20000000) irq += 2;
+ if (portc & 0x40000000) irq += 1;
+
+ return irq;
+}
+
+#elif defined (CONFIG_ATC)
+
+#define CPM_SPI_MAX_CHIPS 32
+#define CPM_SPI_SWAP_BYTES 0
+
+static inline void
+cpm_spi_init_ports (volatile immap_t *immap)
+{
+
+ immap->im_ioport.iop_ppard &= ~0x00080000;
+ immap->im_ioport.iop_pdird |= 0x00080000;
+ immap->im_ioport.iop_podrd &= ~0x00080000;
+ immap->im_ioport.iop_pdatd |= 0x00080000;
+}
+
+static inline void
+cpm_spi_set_cs (volatile immap_t *immap, int id, int select)
+{
+
+ if (select) {
+ immap->im_ioport.iop_pdatd &= ~0x00080000;
+ } else {
+ immap->im_ioport.iop_pdatd |= 0x00080000;
+ }
+}
+
+#elif defined (CONFIG_PRTPPC)
+
+#define NUM_SPI_CHIPSELS 4
+
+#define PB_SPI_CS0 0x00010000 /* PB 15 is Chip Select for the RTC */
+#define PB_SPI_CS1 0x00000001 /* PB 31 is Chip select for the MMC */
+#define PA_SPI_CS2 0x2000 /* PA 2 (PA has 16-bit registers !!) */
+#define PA_SPI_CS3 0x1000 /* PA 3 (PA has 16-bit registers !!) */
+
+#define CPM_SPI_MAX_CHIPS NUM_SPI_CHIPSELS
+#define CPM_SPI_SWAP_BYTES 0
+
+#define CPM_SPI_SPMODE (/* SPMODE_DIV16 | */\
+ SPMODE_CP | \
+ SPMODE_REV | \
+ SPMODE_MSTR | \
+ SPMODE_LEN(8) | \
+ 0x0f )
+
+static inline void
+cpm_spi_init_ports (volatile immap_t *immap)
+{
+ printk("CPM_SPI: Config chipsels\n");
+ /* Set Port-B pin assignment for SPI pins */
+ immap->im_cpm.cp_pbpar |= 0x0000000e; /* Route PB30,29,28 to second function */
+ immap->im_cpm.cp_pbdir |= 0x0000000e; /* Select SPI block for second function */
+
+ /* Set Port-B and Port-A pin assignments for SPI_CS0...CS3 pins */
+ immap->im_cpm.cp_pbpar &= ~(PB_SPI_CS0 | PB_SPI_CS1); /* Route PB15,PB31 to GPIO */
+ immap->im_ioport.iop_papar &= ~(PA_SPI_CS2 | PA_SPI_CS3); /* Route PB15,PB31 to GPIO */
+
+ immap->im_cpm.cp_pbdir |= (PB_SPI_CS0 | PB_SPI_CS1); /* Set PB15,PB31 as outputs */
+ immap->im_ioport.iop_padir |= (PA_SPI_CS2 | PA_SPI_CS3); /* Set PA2,PA3 as outputs */
+
+ immap->im_cpm.cp_pbdat |= (PB_SPI_CS0 | PB_SPI_CS1); /* Clear Chip Selects (active low) */
+ immap->im_ioport.iop_padat |= (PA_SPI_CS2 | PA_SPI_CS3); /* Clear Chip Selects (active low) */
+}
+
+static inline void
+cpm_spi_set_cs (volatile immap_t *immap, int id, int select)
+{
+ /* printk("CPM_SPI: CS%d = %d\n",id,select); */
+ if(select) {
+ switch(id)
+ {
+ case 0:
+ immap->im_cpm.cp_pbdat |= PB_SPI_CS0; /* SET */
+ /* Clear all others */
+ immap->im_cpm.cp_pbdat |= PB_SPI_CS1;
+ immap->im_ioport.iop_padat |= PA_SPI_CS2 | PA_SPI_CS3;
+ break;
+ case 1:
+ immap->im_cpm.cp_pbdat &= ~PB_SPI_CS1; /* SET */
+ /* Clear all others */
+ immap->im_cpm.cp_pbdat &= ~PB_SPI_CS0;
+ immap->im_ioport.iop_padat |= PA_SPI_CS2 | PA_SPI_CS3;
+ break;
+ case 2:
+ immap->im_ioport.iop_padat &= ~PA_SPI_CS2; /* SET */
+ /* Clear all others */
+ immap->im_cpm.cp_pbdat &= ~PB_SPI_CS0;
+ immap->im_cpm.cp_pbdat |= PB_SPI_CS1;
+ immap->im_ioport.iop_padat |= PA_SPI_CS3;
+ break;
+ case 3:
+ immap->im_ioport.iop_padat &= ~PA_SPI_CS3; /* SET */
+ /* Clear all others */
+ immap->im_cpm.cp_pbdat &= ~PB_SPI_CS0;
+ immap->im_cpm.cp_pbdat |= PB_SPI_CS1;
+ immap->im_ioport.iop_padat |= PA_SPI_CS2;
+ break;
+ default:
+ break;
+ }
+ }
+ else {
+ /* Just clear all CS's */
+ /* FIXME: This _can_ go wrong when doing this:
+ Select1
+ Do something on SPI 1
+ Select2
+ Unselect 1
+ Do something on SPI 2 will fail
+ Unselect 2
+ */
+ immap->im_cpm.cp_pbdat &= ~PB_SPI_CS0;
+ immap->im_cpm.cp_pbdat |= PB_SPI_CS1;
+ immap->im_ioport.iop_padat |= PA_SPI_CS2 | PA_SPI_CS3;
+ }
+}
+
+#else
+#error "CPM SPI support is not implemented for your board"
+#endif
+
+#endif
diff --git a/include/asm-ppc/mpc8xx.h b/include/asm-ppc/mpc8xx.h
--- a/include/asm-ppc/mpc8xx.h
+++ b/include/asm-ppc/mpc8xx.h
@@ -68,6 +68,10 @@
#include <platforms/mpc885ads.h>
#endif
+#if defined(CONFIG_PRTPPC)
+#include <platforms/prtppc.h>
+#endif
+
/* Currently, all 8xx boards that support a processor to PCI/ISA bridge
* use the same memory map.
*/
diff --git a/include/asm-ppc/serial.h b/include/asm-ppc/serial.h
--- a/include/asm-ppc/serial.h
+++ b/include/asm-ppc/serial.h
@@ -38,6 +38,8 @@
#include <asm/mpc85xx.h>
#elif defined(CONFIG_RADSTONE_PPC7D)
#include <platforms/radstone_ppc7d.h>
+#elif defined(CONFIG_PRTPPC)
+#include <platforms/prtppc_serial.h>
#else
/*
^ permalink raw reply
* Re: [PATCH 2.6.14] mm: 8xx MM fix for
From: David Jander @ 2005-11-10 7:48 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <20051109120450.GB8588@logos.cnet>
On Wednesday 09 November 2005 13:04, Marcelo Tosatti wrote:
>[...]
>
> ** 2.6.14 DataTLBHandler jump direct ("two exceptions"):
>
> first batch:
> avg: 287ms
> avg: 287ms
> avg: 287ms
> avg: 287ms
> avg: 287ms
>
> second batch:
> avg: 287ms
> avg: 287ms
> avg: 287ms
> avg: 287ms
> avg: 287ms
>
> ** 2.6.14 vanilla ("three exceptions"):
>
> first batch:
> avg: 288ms
> avg: 285ms
> avg: 287ms
> avg: 287ms
> avg: 288ms
>
> second batch:
> avg: 288ms
> avg: 288ms
> avg: 287ms
> avg: 287ms
> avg: 287ms
>
> ** 2.4.17 (root on RAMDISK):
>
> avg: 309ms
> avg: 313ms
> avg: 312ms
> avg: 311ms
> avg: 310ms
Hmmm. This is a lot in the line of the tests I did with (the more generic
benchmark) nbench. After looking at those results (see my other post in this
thread) I already suspected something like this.
> The v2.6.14's kernel jump-direct is more consistent at 287ms,
> while vanilla 2.6.14 oscillates between 285 and 288ms, but
> no significant difference between the two.
>
> v2.6's fault handling is clearly faster than 2.4's (note that the compiler
> is also different, 2.4 uses gcc 2.95 and 2.6 gcc 3.3).
I don't think the compiler does much difference here though. In my test the
exact same compiler was used for both kernels, and the same rootfs and binary
of nbench. gcc-3.3.3. I did also use oprofile to get an idea of where the
code spent its most cpu time during nbench, and AFAIR flush_dcache_icache()
took quite a chunk of it, so I assume page fault latency is of importance
there too, and might account for the huge difference between 2.4 and 2.6.
Greetings,
--
David Jander
^ permalink raw reply
* about MPC 8XX SPI Driver
From: 徐小威的EMAIL @ 2005-11-10 6:50 UTC (permalink / raw)
To: linuxppc-embedded
Hi All:
Anybody know where can found 'CPM SPI Driver' for MPC852T.I found a
cpm_spi.c at /arch/ppc/8260_io directory in Linux 2.4.25.But I don't
know how to program application to
handle this driver.
Best Regards,
Rober Hsu
^ permalink raw reply
* Re: [PATCH] ppc: add support for new powerbooks
From: Andrew Morton @ 2005-11-10 6:29 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <17266.58346.798470.79283@cargo.ozlabs.ibm.com>
Paul Mackerras <paulus@samba.org> wrote:
>
> > And, given the amount of shared infrastructure, I suspect it would have to
> > be a single git tree for both architectures.
> >
> > I'd still sweep up random ppc patches, but those will go into mainline via the
> > originator->mm->git-powerpc->linus route.
> >
> > Possible?
>
> Yes. Good idea, in fact. I'll create a powerpc.git tree once the
> current merge window closes.
OK.
> Do I need to grep the -mm releases for ppc patches or will you mail
> them to me?
If I see a ppc patch I will:
- merge it into -mm, add you guys to the cc on the mm-commits email.
- stage the patch after git-powerpc.patch in the -mm lineup.
- if I see the patch appear in git-powerpc.patch, I just drop it. I sync
with the git trees maybe twice per day.
- time passes
- if it still hasn't been merged into git-powerpc, I start spamming you
with the patch.
So no, you don't need to grep -mm and I won't bypass the git-powerpc tree
and the patch won't get lost. All you need to do is to either merge or
nack the patch at some stage.
Easy as pie ;)
^ permalink raw reply
* Re: [PATCH] ppc: add support for new powerbooks
From: Paul Mackerras @ 2005-11-10 6:08 UTC (permalink / raw)
To: Andrew Morton; +Cc: linuxppc-dev
In-Reply-To: <20051109213837.47c8dce7.akpm@osdl.org>
Andrew Morton writes:
> I don't think I'm adding much value handling ppc/ppc64 patches, really.
> I'd prefer to get out of that business.
>
> It would be better to have an arch maintainer who runs a git tree, same as
> ia64, arm, etc.
My powerpc-merge.git tree is sort-of de-facto that at the moment.
> And, given the amount of shared infrastructure, I suspect it would have to
> be a single git tree for both architectures.
>
> I'd still sweep up random ppc patches, but those will go into mainline via the
> originator->mm->git-powerpc->linus route.
>
> Possible?
Yes. Good idea, in fact. I'll create a powerpc.git tree once the
current merge window closes.
Do I need to grep the -mm releases for ppc patches or will you mail
them to me?
Regards,
Paul.
^ permalink raw reply
* Re: [PATCH] ppc: add support for new powerbooks
From: Benjamin Herrenschmidt @ 2005-11-10 6:06 UTC (permalink / raw)
To: Andrew Morton; +Cc: linuxppc-dev
In-Reply-To: <20051109220022.264437f8.akpm@osdl.org>
> Well yes, that's a generic problem with subsystem trees. I suppose one
> could enforce processes which prevent it from happening.
I think the right process is to go through the linuxppc[64]-dev list(s)
first, maybe CC lkml when it's not strictly arch gore, and then hop from
there to -git. We also have a nice patch tracking system scanning those
lists, I suppose I need to fix my own habits of bypassing all of that
stuff :)
> OK, well please think about it. It's not a ton of work at this end at
> present, but a) you lazy bums don't ack most of the things I cc you on, so
> it's rather open-loop and I don't know whether I'm merging wrong patches
> and b) there's now increasing potential for patches in -mm to clash with
> patches in Paul's git tree.
>
> The latter can be solved easily enough: I add Paul's git tree to the -mm
> lineup.
I think going through the -git tree always makes sense and I've doing
doing that for my own production, I'll route patches that I'm acking
that way too from now on.
I'm keeping the liberty of bombing you & linus directly when I think
it's an important bug fix late in the rc cycle though :)
Ben.
^ permalink raw reply
* Re: [PATCH] ppc: add support for new powerbooks
From: Andrew Morton @ 2005-11-10 6:00 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1131601224.24637.155.camel@gaston>
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
>
>
> > I don't think I'm adding much value handling ppc/ppc64 patches, really.
> > I'd prefer to get out of that business.
> >
> > It would be better to have an arch maintainer who runs a git tree, same as
> > ia64, arm, etc.
> >
> > And, given the amount of shared infrastructure, I suspect it would have to
> > be a single git tree for both architectures.
> >
> > I'd still sweep up random ppc patches, but those will go into mainline via the
> > originator->mm->git-powerpc->linus route.
> >
> > Possible?
>
> Well, I'm personally no fan of the git route as it causes us to have
> less review on the list imho
Well yes, that's a generic problem with subsystem trees. I suppose one
could enforce processes which prevent it from happening.
> (too easy also for me to just bounce a
> patch to paulus to shove in his git tree :) though that's what I've been
> doing for the last few days at least. But if you prefer that way, yes,
> it's certainly possible.
OK, well please think about it. It's not a ton of work at this end at
present, but a) you lazy bums don't ack most of the things I cc you on, so
it's rather open-loop and I don't know whether I'm merging wrong patches
and b) there's now increasing potential for patches in -mm to clash with
patches in Paul's git tree.
The latter can be solved easily enough: I add Paul's git tree to the -mm
lineup. Gimme.
^ permalink raw reply
* Re: [PATCH] ppc: add support for new powerbooks
From: Benjamin Herrenschmidt @ 2005-11-10 5:40 UTC (permalink / raw)
To: Andrew Morton; +Cc: linuxppc-dev
In-Reply-To: <20051109213837.47c8dce7.akpm@osdl.org>
> I don't think I'm adding much value handling ppc/ppc64 patches, really.
> I'd prefer to get out of that business.
>
> It would be better to have an arch maintainer who runs a git tree, same as
> ia64, arm, etc.
>
> And, given the amount of shared infrastructure, I suspect it would have to
> be a single git tree for both architectures.
>
> I'd still sweep up random ppc patches, but those will go into mainline via the
> originator->mm->git-powerpc->linus route.
>
> Possible?
Well, I'm personally no fan of the git route as it causes us to have
less review on the list imho (too easy also for me to just bounce a
patch to paulus to shove in his git tree :) though that's what I've been
doing for the last few days at least. But if you prefer that way, yes,
it's certainly possible.
Ben.
^ permalink raw reply
* Re: [PATCH] ppc: add support for new powerbooks
From: Andrew Morton @ 2005-11-10 5:38 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1131526855.24637.67.camel@gaston>
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
>
> Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
I don't think I'm adding much value handling ppc/ppc64 patches, really.
I'd prefer to get out of that business.
It would be better to have an arch maintainer who runs a git tree, same as
ia64, arm, etc.
And, given the amount of shared infrastructure, I suspect it would have to
be a single git tree for both architectures.
I'd still sweep up random ppc patches, but those will go into mainline via the
originator->mm->git-powerpc->linus route.
Possible?
^ permalink raw reply
* "Now booting the kernel"
From: Nitesh Guinde @ 2005-11-10 4:57 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 1154 bytes --]
Hello all,
I am loading a linux kernel onto ML310 board .I want networking support and
hence I have a pci enabled design.
I am using linux 2.4 powerpc devel kernel. I have also tried the montavista
previewkit
But I end up with the same problem. I have enabled the option " support for
early boot texts: in the kernel debugging.
Now once run the kernel program in powerpc I get the following essages in
the serial minicom terminal
Enter Desired System ACE CF Configuration <0-7>.
0: ACE-loader.
1: Linux w/PCI.
2: VxWorks w/PCI.
3: QNX Demo.
4: Linux EDK Base Build.
5: VxWorks EDK Base Build.
6: User Configuration A.
7: User Configuration B.
Select:
loaded at: 00400000 008CB1E0
board data at: 008C8138 008C8150
relocated to: 00405308 00405320
zimage at: 00405813 004DE42A
initrd at: 004DF000 008C7382
avail ram: 008CC000 10000000
Linux/PPC load: console=ttyS0,9600 root=/dev/xsysace/disc0/part2 rw
Uncompressing Linux...done.
Now booting the kernel
The prompt goes dead at this point.The board details is available at
www.xilinx.com/ml310 <http://www.xilinx.com/ml310>
Any workarounds?
Thanks,
Nitesh
[-- Attachment #2: Type: text/html, Size: 1518 bytes --]
^ permalink raw reply
* Re: 2.6.14 USB vs. sleep issues
From: Benjamin Herrenschmidt @ 2005-11-10 1:51 UTC (permalink / raw)
To: Eddy Petrişor; +Cc: linuxppc-dev list, debian-powerpc@lists.debian.org
In-Reply-To: <60381eeb0511091712u115979f2jf92717a3641f7952@mail.gmail.com>
On Thu, 2005-11-10 at 03:12 +0200, Eddy Petrişor wrote:
> On 11/7/05, Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> >
> > > i've applied your patch and it seems that when i put my powerbook to
> > > sleep ( by closing the lid ) the kernel just crashes since everytime i
> > > come back, the machine is turned off. I had a look at the logs and i see
> > > that i'm having a reboot almost immediateley after the lid is closed.
> > > However i've got no trace of a kernel panic .....
> > > my conf:
> >
> > What about this patch ?
>
> I tried to apply this patch and the previous one over 2.6.14, but they failed.
> I also tied to apply the second patch over the first, also the third
> over the first, but I had the same result.
>
> Over which version should these pacthes be applied?
2.6.14 :) (But not some git checkout from after 2.6.14 release)
Ben.
^ permalink raw reply
* Re: 2.6.14 USB vs. sleep issues
From: Eddy Petrişor @ 2005-11-10 1:12 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list, debian-powerpc@lists.debian.org
In-Reply-To: <1131397208.4652.41.camel@gaston>
On 11/7/05, Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
>
> > i've applied your patch and it seems that when i put my powerbook to
> > sleep ( by closing the lid ) the kernel just crashes since everytime i
> > come back, the machine is turned off. I had a look at the logs and i se=
e
> > that i'm having a reboot almost immediateley after the lid is closed.
> > However i've got no trace of a kernel panic .....
> > my conf:
>
> What about this patch ?
I tried to apply this patch and the previous one over 2.6.14, but they fail=
ed.
I also tied to apply the second patch over the first, also the third
over the first, but I had the same result.
Over which version should these pacthes be applied?
--
Regards,
EddyP
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
"Imagination is more important than knowledge" A.Einstein
^ permalink raw reply
* Re: u-boot + kernel (help required)
From: Wolfgang Denk @ 2005-11-09 22:58 UTC (permalink / raw)
To: srideep.devireddy; +Cc: linuxppc-embedded
In-Reply-To: <6AD9F6A5F6E096408F0B703773355A075BB210@CHN-SNR-MBX01.wipro.com>
In message <6AD9F6A5F6E096408F0B703773355A075BB210@CHN-SNR-MBX01.wipro.com> you wrote:
>
> we were able to get the u-boot up on MPC8272ADS board . We are just
...
Arghh... Why are you posting the same message 3 times?????
Wolfgang Denk
--
Software Engineering: Embedded and Realtime Systems, Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
"There's only one kind of woman ..." "Or man, for that matter. You
either believe in yourself or you don't."
-- Kirk and Harry Mudd, "Mudd's Women", stardate 1330.1
^ permalink raw reply
* Re: FW: U-boot linux kernel
From: Wolfgang Denk @ 2005-11-09 22:57 UTC (permalink / raw)
To: srideep.devireddy; +Cc: linuxppc-embedded
In-Reply-To: <6AD9F6A5F6E096408F0B703773355A075BB03B@CHN-SNR-MBX01.wipro.com>
In message <6AD9F6A5F6E096408F0B703773355A075BB03B@CHN-SNR-MBX01.wipro.com> you wrote:
>
> I am right now working on MPC 8272 Ads board to bring up the u-boot
> and the linux kernel on it . As I am success full in bringing up the
> u-boot . but I am finding it difficult in getting the linux up . As I
> downloaded the vmlinux image from montavista linux site for 8272Ads
Are you sure this image is configured for use with U-Boot?
> board and they tried to tftp to 100000 at u-boot prompt I am not able
And did you read the FAQ, for example
http://www.denx.de/wiki/view/DULG/LinuxUncompressingError ???
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
Alliance: In international politics, the union of two thieves who
have their hands so deeply inserted in each other's pocket that they
cannot separately plunder a third. - Ambrose Bierce
^ permalink raw reply
* Re: [patch 2.6.14 (take #2)] fec_8xx: make CONFIG_FEC_8XX depend on CONFIG_8xx
From: John W. Linville @ 2005-11-09 21:52 UTC (permalink / raw)
To: Pantelis Antoniou, linuxppc-embedded, netdev, linux-kernel
In-Reply-To: <20051107182459.GD13797@tuxdriver.com>
On Mon, Nov 07, 2005 at 01:24:59PM -0500, John W. Linville wrote:
> Change CONFIG_FEC_8XX to depend on CONFIG_8xx instead of CONFIG_FEC.
> CONFIG_FEC depends on ColdFire CPUs, which does not apply for the
> PPC 8xx processors.
FWIW, I have this patch available on the linville-fec_8xx branch of
netdev-jwl as described below.
Thanks,
John
---
The following changes since commit 330d57fb98a916fa8e1363846540dd420e99499a:
Al Viro:
Fix sysctl unregistration oops (CVE-2005-2709)
are found in the git repository at:
git://git.tuxdriver.com/git/netdev-jwl.git linville-fec_8xx
John W. Linville:
fec_8xx: make CONFIG_FEC_8XX depend on CONFIG_8xx
drivers/net/fec_8xx/Kconfig | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/fec_8xx/Kconfig b/drivers/net/fec_8xx/Kconfig
index 94e7a9a..a84c232 100644
--- a/drivers/net/fec_8xx/Kconfig
+++ b/drivers/net/fec_8xx/Kconfig
@@ -1,6 +1,6 @@
config FEC_8XX
tristate "Motorola 8xx FEC driver"
- depends on NET_ETHERNET && FEC
+ depends on NET_ETHERNET && 8xx
select MII
config FEC_8XX_GENERIC_PHY
--
John W. Linville
linville@tuxdriver.com
^ permalink raw reply related
* Need test: 2.6.14: Fix IRQ race in USB sleep/wakeup code]
From: Benjamin Herrenschmidt @ 2005-11-09 21:50 UTC (permalink / raw)
To: Linux Kernel list; +Cc: linuxppc-dev list
Here's a patch that fixes a race in the USB code with sleep/wakeup.
It's against 2.6.14 and I'd like to see it in the stable series as
powerbook sleep crashes without it, but it needs a little bit of
field testing first. So I would appreciate if ppl could give it a
go and let me know if it doesn't seem to cause any regression (or
if it does of course ;)
Ben.
Index: 2.6.14-ben/drivers/usb/core/hcd-pci.c
===================================================================
--- 2.6.14-ben.orig/drivers/usb/core/hcd-pci.c
+++ 2.6.14-ben/drivers/usb/core/hcd-pci.c
@@ -32,6 +32,13 @@
#include <linux/usb.h>
#include "hcd.h"
+#ifdef CONFIG_PPC_PMAC
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
+#include <asm/pci-bridge.h>
+#include <asm/prom.h>
+#endif
+
/* PCI-based HCs are common, but plenty of non-PCI HCs are used too */
@@ -278,6 +285,18 @@ int usb_hcd_pci_suspend (struct pci_dev
break;
}
+#ifdef CONFIG_PPC_PMAC
+ if (retval == 0 && _machine == _MACH_Pmac) {
+ struct device_node *of_node;
+
+ /* Disable USB PAD & cell clock */
+ of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.
+ controller));
+ if (of_node)
+ pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
+ }
+#endif /* CONFIG_PPC_PMAC */
+
/* update power_state **ONLY** to make sysfs happier */
if (retval == 0)
dev->dev.power.power_state = message;
@@ -303,6 +322,18 @@ int usb_hcd_pci_resume (struct pci_dev *
return 0;
}
+#ifdef CONFIG_PPC_PMAC
+ if (_machine == _MACH_Pmac) {
+ struct device_node *of_node;
+
+ /* Re-enable USB PAD & cell clock */
+ of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.
+ controller));
+ if (of_node)
+ pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 1);
+ }
+#endif /* CONFIG_PPC_PMAC */
+
/* NOTE: chip docs cover clean "real suspend" cases (what Linux
* calls "standby", "suspend to RAM", and so on). There are also
* dirty cases when swsusp fakes a suspend in "shutdown" mode.
Index: 2.6.14-ben/drivers/usb/core/hcd.c
===================================================================
--- 2.6.14-ben.orig/drivers/usb/core/hcd.c
+++ 2.6.14-ben/drivers/usb/core/hcd.c
@@ -1600,7 +1600,8 @@ irqreturn_t usb_hcd_irq (int irq, void *
struct usb_hcd *hcd = __hcd;
int start = hcd->state;
- if (start == HC_STATE_HALT)
+ if (start == HC_STATE_HALT ||
+ !test_bit(HC_FLAG_IRQ_ON, &hcd->bitflags))
return IRQ_NONE;
if (hcd->driver->irq (hcd, r) == IRQ_NONE)
return IRQ_NONE;
@@ -1736,6 +1737,9 @@ int usb_add_hcd(struct usb_hcd *hcd,
if (hcd->driver->irq) {
char buf[8], *bufp = buf;
+ set_bit(HC_FLAG_IRQ_ON, &hcd->bitflags);
+ mb();
+
#ifdef __sparc__
bufp = __irq_itoa(irqnum);
#else
Index: 2.6.14-ben/drivers/usb/core/hcd.h
===================================================================
--- 2.6.14-ben.orig/drivers/usb/core/hcd.h
+++ 2.6.14-ben/drivers/usb/core/hcd.h
@@ -71,6 +71,9 @@ struct usb_hcd { /* usb_bus.hcpriv point
/*
* hardware info/state
*/
+ unsigned long bitflags; /* various single-bit flags */
+#define HC_FLAG_IRQ_ON 0
+
const struct hc_driver *driver; /* hw-specific hooks */
unsigned saw_irq : 1;
unsigned can_wakeup:1; /* hw supports wakeup? */
Index: 2.6.14-ben/drivers/usb/host/ehci-hcd.c
===================================================================
--- 2.6.14-ben.orig/drivers/usb/host/ehci-hcd.c
+++ 2.6.14-ben/drivers/usb/host/ehci-hcd.c
@@ -750,6 +750,12 @@ static int ehci_suspend (struct usb_hcd
if (time_before (jiffies, ehci->next_statechange))
msleep (100);
+ /* Disable emission of interrupts during suspend */
+ writel(0, &ehci->regs->intr_enable);
+ mb();
+ clear_bit(HC_FLAG_IRQ_ON, &hcd->bitflags);
+ synchronize_irq(to_pci_dev(hcd->self.controller)->irq);
+
#ifdef CONFIG_USB_SUSPEND
(void) usb_suspend_device (hcd->self.root_hub, message);
#else
@@ -776,6 +782,8 @@ static int ehci_resume (struct usb_hcd *
if (time_before (jiffies, ehci->next_statechange))
msleep (100);
+ set_bit(HC_FLAG_IRQ_ON, &hcd->bitflags);
+
/* If any port is suspended (or owned by the companion),
* we know we can/must resume the HC (and mustn't reset it).
*/
Index: 2.6.14-ben/drivers/usb/host/ehci-q.c
===================================================================
--- 2.6.14-ben.orig/drivers/usb/host/ehci-q.c
+++ 2.6.14-ben/drivers/usb/host/ehci-q.c
@@ -926,6 +926,11 @@ submit_async (
#endif
spin_lock_irqsave (&ehci->lock, flags);
+ if (HC_IS_SUSPENDED(ehci_to_hcd(ehci)->state)) {
+ spin_unlock_irqrestore (&ehci->lock, flags);
+ return -ESHUTDOWN;
+ }
+
qh = qh_append_tds (ehci, urb, qtd_list, epnum, &ep->hcpriv);
/* Control/bulk operations through TTs don't need scheduling,
Index: 2.6.14-ben/drivers/usb/host/ehci-sched.c
===================================================================
--- 2.6.14-ben.orig/drivers/usb/host/ehci-sched.c
+++ 2.6.14-ben/drivers/usb/host/ehci-sched.c
@@ -602,6 +602,11 @@ static int intr_submit (
spin_lock_irqsave (&ehci->lock, flags);
+ if (HC_IS_SUSPENDED(ehci_to_hcd(ehci)->state)) {
+ spin_unlock_irqrestore (&ehci->lock, flags);
+ return -ESHUTDOWN;
+ }
+
/* get qh and force any scheduling errors */
INIT_LIST_HEAD (&empty);
qh = qh_append_tds (ehci, urb, &empty, epnum, &ep->hcpriv);
@@ -1456,6 +1461,11 @@ static int itd_submit (struct ehci_hcd *
/* schedule ... need to lock */
spin_lock_irqsave (&ehci->lock, flags);
+ if (HC_IS_SUSPENDED(ehci_to_hcd(ehci)->state)) {
+ spin_unlock_irqrestore (&ehci->lock, flags);
+ status = -ESHUTDOWN;
+ goto done;
+ }
status = iso_stream_schedule (ehci, urb, stream);
if (likely (status == 0))
itd_link_urb (ehci, urb, ehci->periodic_size << 3, stream);
@@ -1815,6 +1825,11 @@ static int sitd_submit (struct ehci_hcd
/* schedule ... need to lock */
spin_lock_irqsave (&ehci->lock, flags);
+ if (HC_IS_SUSPENDED(ehci_to_hcd(ehci)->state)) {
+ spin_unlock_irqrestore (&ehci->lock, flags);
+ status = -ESHUTDOWN;
+ goto done;
+ }
status = iso_stream_schedule (ehci, urb, stream);
if (status == 0)
sitd_link_urb (ehci, urb, ehci->periodic_size << 3, stream);
Index: 2.6.14-ben/drivers/usb/host/ohci-hcd.c
===================================================================
--- 2.6.14-ben.orig/drivers/usb/host/ohci-hcd.c
+++ 2.6.14-ben/drivers/usb/host/ohci-hcd.c
@@ -252,6 +252,10 @@ static int ohci_urb_enqueue (
spin_lock_irqsave (&ohci->lock, flags);
+ if (HC_IS_SUSPENDED(hcd->state)) {
+ retval = -ESHUTDOWN;
+ goto fail;
+ }
/* don't submit to a dead HC */
if (!HC_IS_RUNNING(hcd->state)) {
retval = -ENODEV;
Index: 2.6.14-ben/drivers/usb/host/ohci-hub.c
===================================================================
--- 2.6.14-ben.orig/drivers/usb/host/ohci-hub.c
+++ 2.6.14-ben/drivers/usb/host/ohci-hub.c
@@ -219,13 +219,6 @@ static int ohci_hub_resume (struct usb_h
/* Sometimes PCI D3 suspend trashes frame timings ... */
periodic_reinit (ohci);
- /* interrupts might have been disabled */
- ohci_writel (ohci, OHCI_INTR_INIT, &ohci->regs->intrenable);
- if (ohci->ed_rm_list)
- ohci_writel (ohci, OHCI_INTR_SF, &ohci->regs->intrenable);
- ohci_writel (ohci, ohci_readl (ohci, &ohci->regs->intrstatus),
- &ohci->regs->intrstatus);
-
/* Then re-enable operations */
ohci_writel (ohci, OHCI_USB_OPER, &ohci->regs->control);
(void) ohci_readl (ohci, &ohci->regs->control);
@@ -241,6 +234,13 @@ static int ohci_hub_resume (struct usb_h
/* TRSMRCY */
msleep (10);
+ /* interrupts might have been disabled */
+ ohci_writel (ohci, OHCI_INTR_INIT, &ohci->regs->intrenable);
+ if (ohci->ed_rm_list)
+ ohci_writel (ohci, OHCI_INTR_SF, &ohci->regs->intrenable);
+ ohci_writel (ohci, ohci_readl (ohci, &ohci->regs->intrstatus),
+ &ohci->regs->intrstatus);
+
/* keep it alive for ~5x suspend + resume costs */
ohci->next_statechange = jiffies + msecs_to_jiffies (250);
Index: 2.6.14-ben/drivers/usb/host/ohci-pci.c
===================================================================
--- 2.6.14-ben.orig/drivers/usb/host/ohci-pci.c
+++ 2.6.14-ben/drivers/usb/host/ohci-pci.c
@@ -14,13 +14,6 @@
* This file is licenced under the GPL.
*/
-#ifdef CONFIG_PPC_PMAC
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <asm/pci-bridge.h>
-#include <asm/prom.h>
-#endif
-
#ifndef CONFIG_PCI
#error "This file is PCI bus glue. CONFIG_PCI must be defined."
#endif
@@ -118,6 +111,12 @@ static int ohci_pci_suspend (struct usb_
if (time_before (jiffies, ohci->next_statechange))
msleep (100);
+ /* Disable emission of interrupts during suspend */
+ ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
+ mb();
+ clear_bit(HC_FLAG_IRQ_ON, &hcd->bitflags);
+ synchronize_irq(to_pci_dev(hcd->self.controller)->irq);
+
#ifdef CONFIG_USB_SUSPEND
(void) usb_suspend_device (hcd->self.root_hub, message);
#else
@@ -129,16 +128,6 @@ static int ohci_pci_suspend (struct usb_
/* let things settle down a bit */
msleep (100);
-#ifdef CONFIG_PPC_PMAC
- if (_machine == _MACH_Pmac) {
- struct device_node *of_node;
-
- /* Disable USB PAD & cell clock */
- of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.controller));
- if (of_node)
- pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
- }
-#endif /* CONFIG_PPC_PMAC */
return 0;
}
@@ -148,20 +137,11 @@ static int ohci_pci_resume (struct usb_h
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int retval = 0;
-#ifdef CONFIG_PPC_PMAC
- if (_machine == _MACH_Pmac) {
- struct device_node *of_node;
-
- /* Re-enable USB PAD & cell clock */
- of_node = pci_device_to_OF_node (to_pci_dev(hcd->self.controller));
- if (of_node)
- pmac_call_feature (PMAC_FTR_USB_ENABLE, of_node, 0, 1);
- }
-#endif /* CONFIG_PPC_PMAC */
-
/* resume root hub */
if (time_before (jiffies, ohci->next_statechange))
msleep (100);
+ set_bit(HC_FLAG_IRQ_ON, &hcd->bitflags);
+
#ifdef CONFIG_USB_SUSPEND
/* get extra cleanup even if remote wakeup isn't in use */
retval = usb_resume_device (hcd->self.root_hub);
Index: 2.6.14-ben/drivers/usb/host/uhci-hcd.c
===================================================================
--- 2.6.14-ben.orig/drivers/usb/host/uhci-hcd.c
+++ 2.6.14-ben/drivers/usb/host/uhci-hcd.c
@@ -797,6 +797,11 @@ static int uhci_suspend(struct usb_hcd *
done:
spin_unlock_irq(&uhci->lock);
+ if (rc == 0) {
+ mb();
+ clear_bit(HC_FLAG_IRQ_ON, &hcd->bitflags);
+ synchronize_irq(hcd->irq);
+ }
return rc;
}
@@ -818,6 +823,8 @@ static int uhci_resume(struct usb_hcd *h
* system wakeup. Check it and reconfigure to avoid problems.
*/
check_and_reset_hc(uhci);
+ set_bit(HC_FLAG_IRQ_ON, &hcd->bitflags);
+ mb();
configure_hc(uhci);
#ifndef CONFIG_USB_SUSPEND
^ permalink raw reply
* [PATCH] ppc32: Add support for handling PCI interrupts on MPC834x PCI expansion card
From: Kumar Gala @ 2005-11-09 20:33 UTC (permalink / raw)
To: Andrew Morton; +Cc: linuxppc-embedded
The MPC8349 PIBs system has a expansion board with 6 PCI slots. We needed
to update the IDSEL interrupt mapping for it to work properly. However,
only PCI1 is supported as the first revision of this expansion board doesn't
function properly for PCI2. For the time being we have zero'd out the entries
for the IDSELs related to PCI2. When a functioning expansion board exists
we can fix the table.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
commit b23f8a20b85440d4bebf1a2ddea5830ca85ff655
tree c60902116ecca2880d12d15350fed1e5d780bc79
parent 35003e02e33939b7359635f3cf7b424723ffd4b0
author Kumar Gala <galak@kernel.crashing.org> Wed, 09 Nov 2005 14:33:30 -0600
committer Kumar Gala <galak@kernel.crashing.org> Wed, 09 Nov 2005 14:33:30 -0600
arch/ppc/platforms/83xx/mpc834x_sys.c | 15 +++++++++++----
1 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c
index 98edc75..763777c 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.c
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
@@ -73,12 +73,19 @@ mpc83xx_map_irq(struct pci_dev *dev, uns
* A B C D
*/
{
- {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x11 */
- {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x12 */
- {PIRQD, PIRQA, PIRQB, PIRQC} /* idsel 0x13 */
+ {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x11 */
+ {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x12 */
+ {PIRQD, PIRQA, PIRQB, PIRQC}, /* idsel 0x13 */
+ {0, 0, 0, 0},
+ {PIRQA, PIRQB, PIRQC, PIRQD}, /* idsel 0x15 */
+ {PIRQD, PIRQA, PIRQB, PIRQC}, /* idsel 0x16 */
+ {PIRQC, PIRQD, PIRQA, PIRQB}, /* idsel 0x17 */
+ {PIRQB, PIRQC, PIRQD, PIRQA}, /* idsel 0x18 */
+ {0, 0, 0, 0}, /* idsel 0x19 */
+ {0, 0, 0, 0}, /* idsel 0x20 */
};
- const long min_idsel = 0x11, max_idsel = 0x13, irqs_per_slot = 4;
+ const long min_idsel = 0x11, max_idsel = 0x20, irqs_per_slot = 4;
return PCI_IRQ_TABLE_LOOKUP;
}
^ permalink raw reply related
* [PATCH] gianfar mii needs to zero out the mii_bus structure
From: Kumar Gala @ 2005-11-09 18:13 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linuxppc-embedded
To ensure that phy_mask and any future elements of the mii_bus
structure are initialized use kzalloc() instead of kmalloc().
This fixes an issue in which phy_mask was not being initialized
and we would skip random phy addresses when scanning.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
commit 35003e02e33939b7359635f3cf7b424723ffd4b0
tree 386160e32c51e8f1e662811738e79571c7218fdb
parent d0876a2748ddc33ca9ed1ea26cf958726c50c7b9
author Kumar Gala <galak@kernel.crashing.org> Wed, 09 Nov 2005 12:11:40 -0600
committer Kumar Gala <galak@kernel.crashing.org> Wed, 09 Nov 2005 12:11:40 -0600
drivers/net/gianfar_mii.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
index 5a74d3d..ee1a77a 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/gianfar_mii.c
@@ -134,7 +134,7 @@ int gfar_mdio_probe(struct device *dev)
if (NULL == dev)
return -EINVAL;
- new_bus = kmalloc(sizeof(struct mii_bus), GFP_KERNEL);
+ new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
if (NULL == new_bus)
return -ENOMEM;
^ permalink raw reply related
* Re: [PATCH 2.6.14] mm: 8xx MM fix for
From: Marcelo Tosatti @ 2005-11-09 12:04 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-embedded, Dan Malek
In-Reply-To: <1131396000.4652.24.camel@gaston>
On Tue, Nov 08, 2005 at 07:39:59AM +1100, Benjamin Herrenschmidt wrote:
<snip>
> I think the current code, even with your fix, is sub-optimal. But of
> course, the only way to be sure is to do real measurements
Hi folks,
I've written a simple app to estimate pagefault latency using gettimeofday().
Can be found at http://hera.kernel.org/~marcelo/measurefault/
/* This simple program attemps to estimate how long a pagefault takes.
* It does that by mmaping() /tmp/latency-test, and touching a page.
* Time measurement is done with gettimeofday() before and after the
* data touch.
*
* In the hope to have a more precise measurement two values are subtracted
* from the pagefault time delta:
*
* - Estimated time between two subsequent gettimeofday() calls, average
* of 100 runs (this average is around 8ms on 48Mhz PPC 8xx,
* 0ms on 1Ghz Pegasos G4)
*
* - Time taken to touch the data after its TLB cached, aka second run.
* This takes 1 and 2ms on 8xx (it varies) and 0ms on 1Ghz Pegasos.
*/
And results with 48Mhz 855T, comparing internal v2.4.17, vanilla v2.6.14
and v2.6.14-jump-direct (jumping directly to handle_page_fault if the
pte is zeroed).
Each "avg:" entry is an average of 100 "measure-fault-latency.c" runs.
2.6's root is mounted on NFS.
** 2.6.14 DataTLBHandler jump direct ("two exceptions"):
first batch:
avg: 287ms
avg: 287ms
avg: 287ms
avg: 287ms
avg: 287ms
second batch:
avg: 287ms
avg: 287ms
avg: 287ms
avg: 287ms
avg: 287ms
** 2.6.14 vanilla ("three exceptions"):
first batch:
avg: 288ms
avg: 285ms
avg: 287ms
avg: 287ms
avg: 288ms
second batch:
avg: 288ms
avg: 288ms
avg: 287ms
avg: 287ms
avg: 287ms
** 2.4.17 (root on RAMDISK):
avg: 309ms
avg: 313ms
avg: 312ms
avg: 311ms
avg: 310ms
The v2.6.14's kernel jump-direct is more consistent at 287ms,
while vanilla 2.6.14 oscillates between 285 and 288ms, but
no significant difference between the two.
v2.6's fault handling is clearly faster than 2.4's (note that the compiler
is also different, 2.4 uses gcc 2.95 and 2.6 gcc 3.3).
^ permalink raw reply
* Re: fix swapping on 8xx?
From: Marcelo Tosatti @ 2005-11-09 11:21 UTC (permalink / raw)
To: Tom Rini; +Cc: David Jander, linuxppc-embedded
In-Reply-To: <20051108175658.GO3839@smtp.west.cox.net>
On Tue, Nov 08, 2005 at 10:56:58AM -0700, Tom Rini wrote:
> On Tue, Nov 08, 2005 at 01:59:26PM +0200, David Jander wrote:
> > On Tuesday 08 November 2005 01:55, Dan Malek wrote:
> > > On Nov 7, 2005, at 10:10 AM, Marcelo Tosatti wrote:
> > > > The following is an attempt to fix swapping on 8xx by not touching
> > > > _PAGE_ACCESSED bit if the page is not present.
> > >
> > > Ugh .... I suppose. I hate assembler code macros .......
> > > Somehow, "swapping" and "8xx" just don't belong together.
> >
> > Well, at least it sounds ugly together, but it is also at least conceiveable.
> > There seem to be people who use PCMCIA for an IDE interface, so swapping may
> > become desireable in some cases.
>
> I think Dan might be in the camp that says a properly designed embedded
> system won't need to swap. And when I hear about how people do try and
> swap on systems like this, I really start agreeing. Maybe we could make
> 8xx just select SWAP=n? :)
TimeSys shipped their kernel with swapping fix as far as I know (Jason
plyed with it recently).
We'd better not assume what people try to do with their old 8xx's :)
> > > I'm tempted to add a configuration option that is the complete
> > > opposite of this and assumes are really embedded system.
> > > Mark pages as always accessed, data pages as always dirty,
> > > and you can eliminate lots of TLB faults in systems that are
> > > fairly static.
> >
> > It sounds tempting indeed, but should you really notice a performance increase
> > out of this?
>
> Compared to 8xx in 2.6 today? Absolutely.
>
> --
> Tom Rini
> http://gate.crashing.org/~trini/
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
^ permalink raw reply
* Re: 440EP FPU support missing
From: Josh Boyer @ 2005-11-09 16:50 UTC (permalink / raw)
To: Matt Porter; +Cc: linuxppc-dev, Stefan Roese, linuxppc64-dev
In-Reply-To: <20051108160200.I27232@cox.net>
On Tue, 2005-11-08 at 16:02 -0700, Matt Porter wrote:
> On Tue, Nov 08, 2005 at 04:32:54PM -0600, Josh Boyer wrote:
> > On Tue, 2005-11-08 at 15:30 -0700, Matt Porter wrote:
> > > On Tue, Nov 08, 2005 at 06:38:11PM +0100, Stefan Roese wrote:
> > > > In the current linux version, Bamboo (440EP) won't compile anymore, because of
> > > > missing fpu support:
> > > >
> > > > make uImage
> > > > ...
> > > > LD init/built-in.o
> > > > LD .tmp_vmlinux1
> > > > arch/ppc/kernel/head_44x.o(.text+0x868): In function `_start':
> > > > : undefined reference to `KernelFP'
> > > > make: *** [.tmp_vmlinux1] Error 1
> > > >
> > > > Somehow arch/ppc/kernel/fpu.S has disappeared. :-( I assume, this happened in
> > > > the ppc/ppc64 -> powerpc merge. Any thoughts, why this file disappeared and
> > > > how to solve this problem (just restore the original file)?
> > >
> > > arch/powerpc/kernel/fpu.S is being used now which doesn't have KernelFP.
> > > I don't know why the 44x fpu support wasn't using
> > > kernel_fp_unavailable_exception() before but I must have missed that
> > > reviewing it.
> > >
> > > Try this patch.
> >
> > Doesn't this render the 440EP's FPU useless?
>
> Does what render the 440EP's FPU useless? The supplied patch? I
> don't think so, the path should be the same as classic PPC.
>
> The patch simply replaces the KernelFP routine that used to be in
> arch/ppc/kernel/fpu.S (and was removed inadvertently in the arch/powerpc/
> merge) with a kernel_fp_unavailable_exception() call which does the
> equivalent and is shared by others.
>
> The exception still loads up the fpu is coming from userspace and
> only goes down this path when getting an FP unavailable exception from
> kernel space.
Yes, you're obviously right. I blame my idiocy on lack of coffee.
Sorry for the noise.
josh
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox