Re: [PATCH v3 06/11] dma: Add MPC512x DMA driver
Anatolij Gustschin wrote: Hi Dan, any chance this patch could be merged for 2.6.34 ? Looks good to me, I'll include it in the dmaengine pull request. -- Dan ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: something gets odd when I set the mtd.dev.parent
Problem solved. The NULL oops is due to the mtd->dev.class->p is NULL, which makes the spin_lock in "get_device_parent" function uses a false spin_lock_t struct. the line is "spin_lock(&dev->class->p->class_dirs.list_lock);" That is mainly because in function add_mtd_device function uses the static struct mtd_class to fill into mtd->dev.class. The static struct is not initialized because I drop the driver in our custom dirctory, which is in /arch/powerpc/platforms/..., not in the /drivers/mtd/nand directory, after I put the file there and modifies the Makefile, everything works fine. 2010/3/2 Peter Pan : > > We use Address A20 and A21 connect to ALE and CLE, the data bus is > connected through a buffer. > The RE is OE AND with CS. the WE is PBS0 AND with CS. CE pin is > connect to ground. It works > fine in VxWorks. And also in our previous Linux version 2.6.22. > > Now, I get a odd problem. My GPCM Nand flash driver is mostly copied > from fsl_upm.c. In the fun_probe > function, I have printed out the of_device pointer status as follows: > ofdev= 0xcf851ca0 > ofdev->dev= 0xcf851cb0 > ofdev->dev.class= 0xcf851d50 > > Then I set the &ofdev->dev to mtd.dev.parent using > fun->mtd.dev.parent = &ofdev->dev; > > Then I print out the values: > fun->mtd.dev.parent= 0xcf851cb0 > fun->mtd.dev.parent->class= 0x0 > > The parent pointer is identical, but the class member is NULL, which > makes the access of NULL pointer oops > later. > > I'm wondering why this could happen. The pointer points at the same > address, shouldn't all the members be the > same? > ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
something gets odd when I set the mtd.dev.parent
2010/2/27 Peter Pan : > 2010/2/27 Scott Wood : >> On Fri, Feb 26, 2010 at 10:08:09AM +0800, Peter Pan wrote: >> There isn't one. I was not under the impression that such a configuration >> was even possible (how do you control ALE/CLE, for example?). There is a >> NAND driver that uses UPM, though -- perhaps you could use that? >> >> How specifically is NAND connected to the SoC on your board? What about it >> suggests GPCM? >> >> -Scott >> We use Address A20 and A21 connect to ALE and CLE, the data bus is connected through a buffer. The RE is OE AND with CS. the WE is PBS0 AND with CS. CE pin is connect to ground. It works fine in VxWorks. And also in our previous Linux version 2.6.22. Now, I get a odd problem. My GPCM Nand flash driver is mostly copied from fsl_upm.c. In the fun_probe function, I have printed out the of_device pointer status as follows: ofdev= 0xcf851ca0 ofdev->dev= 0xcf851cb0 ofdev->dev.class= 0xcf851d50 Then I set the &ofdev->dev to mtd.dev.parent using fun->mtd.dev.parent = &ofdev->dev; Then I print out the values: fun->mtd.dev.parent= 0xcf851cb0 fun->mtd.dev.parent->class= 0x0 The parent pointer is identical, but the class member is NULL, which makes the access of NULL pointer oops later. I'm wondering why this could happen. The pointer points at the same address, shouldn't all the members be the same? ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC: PATCH 03/13] powerpc/47x: Base ppc476 support
On Mon, Mar 01, 2010 at 05:11:29PM -0600, Dave Kleikamp wrote: >On Mon, 2010-03-01 at 15:19 -0500, Josh Boyer wrote: >> Overall I'm just going to trust you that things aren't broken on 47x :) >> >> A few minor comments below. Also, if Torez and Benh contributed to this >> code, >> then their S-o-b lines should be included as well (same goes for any other >> patch). > >Right, wanted to make sure they approved of the current state of the >patches. They'll go through Ben anyway. Oh. I guess it doesn't matter much but I would like to test my tree with them applied first. (That's not a distrust that you haven't. It's me attempting to be a decent maintainer for 4xx.) josh ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [Patch] mpc5200b: improve baud rate calculation (reach high baud rates, better accuracy)
Hi Albrecht, On Mon, Mar 01, 2010 at 07:11:54PM +0100, Albrecht Dreß wrote: > On the MPC5200B, select the baud rate prescaler as /4 by default to make very > high baud rates (e.g. 3 MBaud) accessible and to achieve a higher precision > for high baud rates in general. For baud rates below ~500 Baud, the code will > automatically fall back to the /32 prescaler. The original MPC5200 does only > have a /32 prescaler which is detected only once and stored in a global. A > new chip-dependent method is used to set the divisor. > > Tested on a custom 5200B based board, with up to 3 MBaud. > > Signed-off-by: Albrecht Dreß > > --- > > --- linux-2.6.33/drivers/serial/mpc52xx_uart.c.orig 2010-02-24 > 19:52:17.0 +0100 > +++ linux-2.6.33/drivers/serial/mpc52xx_uart.c2010-02-26 > 21:12:51.0 +0100 > @@ -144,9 +144,17 @@ struct psc_ops { > unsigned char (*read_char)(struct uart_port *port); > void(*cw_disable_ints)(struct uart_port *port); > void(*cw_restore_ints)(struct uart_port *port); > + void(*set_divisor)(struct uart_port *port, > +unsigned int divisor); > unsigned long (*getuartclk)(void *p); > }; > > +/* We need to distinguish between the MPC5200 which has only a /32 prescaler, > + * and the MPC5200B which has a /32 and a /4 prescaler. The global is fine, > + * as the chip can be only either a 5200B or not. */ > +static int is_mpc5200b = -1; > + > + One empty line too much. Maybe we can also get rid of the static later in the process, but first things first. > #ifdef CONFIG_PPC_MPC52xx > #define FIFO_52xx(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1)) > static void mpc52xx_psc_fifo_init(struct uart_port *port) > @@ -154,9 +162,6 @@ static void mpc52xx_psc_fifo_init(struct > struct mpc52xx_psc __iomem *psc = PSC(port); > struct mpc52xx_psc_fifo __iomem *fifo = FIFO_52xx(port); > > - /* /32 prescaler */ > - out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); > - > out_8(&fifo->rfcntl, 0x00); > out_be16(&fifo->rfalarm, 0x1ff); > out_8(&fifo->tfcntl, 0x07); > @@ -245,15 +250,40 @@ static void mpc52xx_psc_cw_restore_ints( > out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); > } > > +static void mpc52xx_psc_set_divisor(struct uart_port *port, > + unsigned int divisor) > +{ > + struct mpc52xx_psc __iomem *psc = PSC(port); > + > + /* prescaler */ > + if (is_mpc5200b != 1) > + out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /32 */ > + else if (divisor > 0x) { > + out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /32 */ > + divisor = (divisor + 4) / 8; > + } else > + out_be16(&psc->mpc52xx_psc_clock_select, 0xff00); /* /4 */ > + > + /* ctr */ > + divisor &= 0x; > + out_8(&psc->ctur, divisor >> 8); > + out_8(&psc->ctlr, divisor & 0xff); > +} > + > /* Search for bus-frequency property in this node or a parent */ > static unsigned long mpc52xx_getuartclk(void *p) > { > /* > - * 5200 UARTs have a / 32 prescaler > - * but the generic serial code assumes 16 > - * so return ipb freq / 2 > + * The 5200 has only /32 prescalers. > + * 5200B UARTs have a /4 or a /32 prescaler. For higher accuracy, we > + * do all calculations using the /4 prescaler for this chip. > + * The generic serial code assumes /16 so return ipb freq / 2 (5200) > + * or ipb freq * 4 (5200B). >*/ > - return mpc5xxx_get_bus_frequency(p) / 2; > + if (is_mpc5200b == 1) > + return mpc5xxx_get_bus_frequency(p) * 4; > + else > + return mpc5xxx_get_bus_frequency(p) / 2; Isn't this wrong? You can also have /32 on the 5200B (the fallback). > } > > static struct psc_ops mpc52xx_psc_ops = { > @@ -272,6 +302,7 @@ static struct psc_ops mpc52xx_psc_ops = > .read_char = mpc52xx_psc_read_char, > .cw_disable_ints = mpc52xx_psc_cw_disable_ints, > .cw_restore_ints = mpc52xx_psc_cw_restore_ints, > + .set_divisor = mpc52xx_psc_set_divisor, > .getuartclk = mpc52xx_getuartclk, > }; > > @@ -388,6 +419,16 @@ static void mpc512x_psc_cw_restore_ints( > out_be32(&FIFO_512x(port)->rximr, port->read_status_mask & 0x7f); > } > > +static void mpc512x_psc_set_divisor(struct uart_port *port, > + unsigned int divisor) > +{ > + struct mpc52xx_psc __iomem *psc = PSC(port); > + > + divisor &= 0x; > + out_8(&psc->ctur, divisor >> 8); > + out_8(&psc->ctlr, divisor & 0xff); > +} > + > static unsigned long mpc512x_getuartclk(void *p) > { > return mpc5xxx_get_bus_frequency(p); > @@ -409,6 +450,7 @@ static struct psc_ops mpc512x_psc_ops = > .read_char = mpc512x_psc_read_char, > .cw_disable_ints = mpc512x_psc_cw_disable_ints, > .cw_restore_ints = mp
Re: [RFC: PATCH 08/13] powerpc/476: define specific cpu table entry for DD1 and DD1.1 cores
On Mon, 2010-03-01 at 15:24 -0500, Josh Boyer wrote: > On Mon, Mar 01, 2010 at 02:13:52PM -0500, Dave Kleikamp wrote: > >powerpc/476: define specific cpu table entry for DD1 and DD1.1 cores > > > >From: Benjamin Herrenschmidt > > > >There are still some unstable bits on the DD1 and DD1.1 cores. Don't use > >the FPU or the tlbivax operation. Define CPU_FTR_476_DD1 and > >CPU_FTR_476_DD1_1 for additional workarounds in later patches. > > > >The DD1 core requires workarounds triggered by both CPU_FTR_476_DD1 > >and CPU_FTR_476_DD1_1. the DD1.1 core only needs CPU_FTR_476_DD1_1 > >defined. > > DD1, DD1.1, and all others have the same PVR value? How do you tell which > core version you have? I seemed to have lost the change to the DD1.1 PVR value. I originally coded it this way while I was waiting to find out what it was. DD1.1 is 0x11A52040. I don't know a value for the future versions, so that will have to be filled in later. Actually, I should probably use 0x11A52000, since that's what's defined in reg.h. Thanks, Shaggy -- David Kleikamp IBM Linux Technology Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC: PATCH 06/13] powerpc/4xx: Simple platform for the ISS 4xx simulator
On Mon, 2010-03-01 at 15:29 -0500, Josh Boyer wrote: > On Mon, Mar 01, 2010 at 12:16:00PM -0700, Dave Kleikamp wrote: > >diff --git a/arch/powerpc/platforms/44x/Kconfig > >b/arch/powerpc/platforms/44x/Kconfig > >index 1dfc1c1..915c295 100644 > >--- a/arch/powerpc/platforms/44x/Kconfig > >+++ b/arch/powerpc/platforms/44x/Kconfig > >@@ -162,6 +162,17 @@ config YOSEMITE > > help > > This option enables support for the AMCC PPC440EP evaluation board. > > > >+config ISS4xx > >+bool "ISS 4xx Simulator" > >+depends on (44x || 40x) > >+default n > >+select 405GP if 40x > >+select 440GP if 44x > > Won't that now build a 44x_46x kernel due to the 'select 440GP' there? If so, > doesn't that cause issues for 476? Confused... I hadn't really noticed this because it's been working. When both 44GP and PPC_47x are defined, it doesn't cause any problems for the 476. It's not right though. Thanks, Shaggy -- David Kleikamp IBM Linux Technology Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC: PATCH 04/13] powerpc/476: add machine check handler for 47x core
On Mon, 2010-03-01 at 15:08 -0600, Olof Johansson wrote: > On Mon, Mar 01, 2010 at 05:13:23AM -0700, Dave Kleikamp wrote: > > powerpc/476: add machine check handler for 47x core > > > > From: Dave Kleikamp > > > > The 47x core's MCSR varies from 44x, so it needs it's own machine check > > handler. > > > > --- a/arch/powerpc/kernel/traps.c > > +++ b/arch/powerpc/kernel/traps.c > > @@ -376,6 +376,44 @@ int machine_check_440A(struct pt_regs *regs) > > } > > return 0; > > } > > + > > +int machine_check_47x(struct pt_regs *regs) > > +{ > > + unsigned long reason = get_mc_reason(regs); > > + > > + printk("Machine check in kernel mode.\n"); > > It's quite possible that the other machine check handlers don't have > printk KERN_-levels on them but it would be a good idea to use them here. Right. As it's new code, it should be as correct as possible. > > + if (reason & ESR_IMCP){ > > + printk("Instruction Synchronous Machine Check exception\n"); > > + mtspr(SPRN_ESR, reason & ~ESR_IMCP); > > + } > > + else { > > } else { > > Or, rather, add an early return above and you can just remove one level of > indentation below. agreed. Thanks, Shaggy -- David Kleikamp IBM Linux Technology Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC: PATCH 03/13] powerpc/47x: Base ppc476 support
On Mon, 2010-03-01 at 15:19 -0500, Josh Boyer wrote: > Overall I'm just going to trust you that things aren't broken on 47x :) > > A few minor comments below. Also, if Torez and Benh contributed to this code, > then their S-o-b lines should be included as well (same goes for any other > patch). Right, wanted to make sure they approved of the current state of the patches. They'll go through Ben anyway. > On Mon, Mar 01, 2010 at 12:13:15PM -0700, Dave Kleikamp wrote: > >diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h > >index bc8dd53..4af1c28 100644 > >--- a/arch/powerpc/include/asm/reg.h > >+++ b/arch/powerpc/include/asm/reg.h > >@@ -813,6 +813,7 @@ > > #define PVR_403GC 0x00200200 > > #define PVR_403GCX 0x00201400 > > #define PVR_405GP 0x4011 > >+#define PVR_476 0x11a52000 > > Is that really needed? None of the 44x CPUs have a PVR value here. init_cpu_state() checks the PVR against the high-order word of PVR_476 to determine whether the cpu is 44x or 47x, as we eventually want the same kernel to run on either platform. It's either defined here, or hardcoded there. > > #define PVR_STB03XXX0x4031 > > #define PVR_NP405H 0x4141 > > #define PVR_NP405L 0x4161 > > > > >diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c > >index 2fc82ba..338ac47 100644 > >--- a/arch/powerpc/kernel/cputable.c > >+++ b/arch/powerpc/kernel/cputable.c > >@@ -1701,6 +1701,19 @@ static struct cpu_spec __initdata cpu_specs[] = { > > .machine_check = machine_check_440A, > > .platform = "ppc440", > > }, > >+{ /* 476 core */ > >+.pvr_mask = 0x, > >+.pvr_value = 0x11a5, > > Could we use PVR_476 here (if it's going to stay). I guess it could, but it would be inconsistent with the rest of the cpu table. Also, I'm adding new values for DD1 and DD1.1 (and maybe someday DD2) that differ in the low-order word, but the logic in init_cpu_state only uses the high-order bits in PVR_476, so I don't intend to add new values for those > >+.cpu_name = "476", > >+.cpu_features = CPU_FTRS_47X, > >+.cpu_user_features = COMMON_USER_BOOKE | > >+PPC_FEATURE_HAS_FPU, > >+.mmu_features = MMU_FTR_TYPE_47x | > >+MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL, > >+.icache_bsize = 32, > >+.dcache_bsize = 128, > >+.platform = "ppc470", > >+}, > > > > >diff --git a/arch/powerpc/platforms/44x/Kconfig > >b/arch/powerpc/platforms/44x/Kconfig > >index 7486bff..1dfc1c1 100644 > >--- a/arch/powerpc/platforms/44x/Kconfig > >+++ b/arch/powerpc/platforms/44x/Kconfig > >@@ -1,6 +1,17 @@ > >+config PPC_44x_46x > >+bool "Support for 44x and 46x variants" > >+depends on 44x > >+default n > > Why do this? All it seems to do is add a bunch of churn to the Kconfig here. > If the intention was to try and prevent selecting both 44x and 47x kernel > options, then maybe I could see that. However nothing prevents both from > being > enabled. I'm not really sure about this. If Ben doesn't convince me there's a reason for it, I think I'll remove it. > Maybe PPC_47x should: > > depends on !PPC_44x_46x && 44x Eventually, we want to resolve compiler-time differences in these platforms and have a binary kernel that could run on both 44x and 47x, so we'd just have to rip this out later. I'm not convinced we want this at all. We may want something for the time being to keep from breaking 47x from being accidentally selected, but I'm not sure this is the best thing. > josh -- David Kleikamp IBM Linux Technology Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm
sounds very much like this issue: http://linux.derkeiler.com/Mailing-Lists/Kernel/2010-02/msg09470.html (interrupt storm on the second port which is hit with breaks). It's not the uart driver problem per se, the below fixes it: *** linux/drivers/serial/serial_core.c#1Wed Feb 24 17:46:22 2010 --- linux/drivers/serial/serial_core.c#2Mon Mar 1 15:00:29 2010 *** *** 622,632 struct uart_port *port = state->port; if (I_IXOFF(tty)) { if (port->x_char) port->x_char = 0; ! else uart_send_xchar(tty, START_CHAR(tty)); } if (tty->termios->c_cflag & CRTSCTS) uart_set_mctrl(port, TIOCM_RTS); --- 622,632 struct uart_port *port = state->port; if (I_IXOFF(tty)) { if (port->x_char) port->x_char = 0; ! else if (!(tty->flags & (1 << TTY_IO_ERROR))) uart_send_xchar(tty, START_CHAR(tty)); } if (tty->termios->c_cflag & CRTSCTS) uart_set_mctrl(port, TIOCM_RTS); ^^ I did not get to trying to submit it, but it sure gets rid o the storm. cheers, /vb On Fri, Feb 26, 2010 at 11:25 AM, Paul Gortmaker wrote: > Sending a break on the SOC UARTs found in some MPC83xx/85xx/86xx > chips seems to cause a short lived IRQ storm (/proc/interrupts > typically shows somewhere between 300 and 1500 events). Unfortunately > this renders SysRQ over the serial console completely inoperable. > Testing with obvious things like ACKing the event doesn't seem to > change anything vs. a completely dumb approach of just ignoring > it and waiting for it to stop, so that is what is implemented here. > > Signed-off-by: Paul Gortmaker > --- > > This is a refresh of a patch I'd done earlier -- I've tried to make > the bug support as generic as possible to minimize having board > specific ifdef crap in 8250.c -- any suggestions on how to further > improve it are welcome. > > drivers/serial/8250.c | 6 ++ > drivers/serial/8250.h | 20 > drivers/serial/Kconfig | 14 ++ > include/linux/serial_reg.h | 2 ++ > 4 files changed, 42 insertions(+), 0 deletions(-) > > diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c > index e9b15c3..850b0e9 100644 > --- a/drivers/serial/8250.c > +++ b/drivers/serial/8250.c > @@ -1531,6 +1531,11 @@ static void serial8250_handle_port(struct > uart_8250_port *up) > > status = serial_inp(up, UART_LSR); > > + if ((up->bugs & UART_BUG_PPC) && (status == UART_LSR_RFE_ERROR_BITS)) > { > + spin_unlock_irqrestore(&up->port.lock, flags); > + return; > + } > + > DEBUG_INTR("status = %x...", status); > > if (status & (UART_LSR_DR | UART_LSR_BI)) > @@ -1948,6 +1953,7 @@ static int serial8250_startup(struct uart_port *port) > > up->capabilities = uart_config[up->port.type].flags; > up->mcr = 0; > + up->bugs |= UART_KNOWN_BUGS; > > if (up->port.iotype != up->cur_iotype) > set_io_from_upio(port); > diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h > index 6e19ea3..2074ce1 100644 > --- a/drivers/serial/8250.h > +++ b/drivers/serial/8250.h > @@ -49,6 +49,7 @@ struct serial8250_config { > #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ > #define UART_BUG_NOMSR (1 << 2) /* UART has buggy MSR status bits > (Au1x00) */ > #define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */ > +#define UART_BUG_PPC (1 << 4) /* UART has buggy PPC break IRQ storm > */ > > #define PROBE_RSA (1 << 0) > #define PROBE_ANY (~0) > @@ -78,3 +79,22 @@ struct serial8250_config { > #else > #define ALPHA_KLUDGE_MCR 0 > #endif > + > +/* > + * The following UART bugs are currently dynamically detected and not > + * required to be contingent on any particular compile time options. > + */ > +#define HAS_BUG_QUOT 0 /* assign UART_BUG_QUOT to enable */ > +#define HAS_BUG_TXEN 0 /* assign UART_BUG_TXEN to enable */ > +#define HAS_BUG_NOMSR 0 /* assign UART_BUG_NOMSR to enable */ > +#define HAS_BUG_THRE 0 /* assign UART_BUG_THRE to enable */ > + > +#ifdef CONFIG_SERIAL_8250_PPC_BUG > +#define HAS_BUG_PPC UART_BUG_PPC > +#else > +#define HAS_BUG_PPC 0 > +#endif > + > +#define UART_KNOWN_BUGS (HAS_BUG_QUOT | HAS_BUG_TXEN | HAS_BUG_NOMSR | \ > + HAS_BUG_THRE | HAS_BUG_PPC) > + > diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig > index 9ff47db..e01a411 100644 > --- a/drivers/serial/Kconfig > +++ b/drivers/serial/Kconfig > @@ -70,6 +70,20 @@ config SERIAL_8250_CONSOLE > > If unsure, say N. > > +config SERIAL_8250_PPC_BUG > + bool "Fix 8250/16550 to handle IRQ storm a
Re: [RFC PATCH v2 8/9] USB: add HCD_NO_COHERENT_MEM host controller driver flag
Alan Stern wrote: > On Mon, 1 Mar 2010, Albert Herranz wrote: > Am I on the right path? >>> More or less. I would do it somewhat differently: >>> >>> If URB_NO_TRANSFER_DMA_MAP is set then no map is needed. >>> Otherwise if num_sgs > 0 then no map is needed. >>> Otherwise if HCD_NO_COHERENT_MEM is set then use >>> hcd_alloc_coherent(). >>> Otherwise if transfer_buffer_length > 0 then use >>> dma_map_single(). >>> >> I think that logic is not quite right. >> Remember that the final goal is to avoid allocating USB buffers from >> coherent memory (because the USB drivers access USB buffers without access >> restrictions but the platform I'm working on can't write to coherent memory >> unless it is done in 32-bit chunks). > > Actually the final goal is to make the mapping/unmapping algorithms > clear and correct. One of the subgoals involves avoiding coherent USB > buffers, but there are others as well (if you look back the through the > linux-usb mailing list for the last few weeks you'll see a discussion > about a controller which has to use PIO for control transfers but can > use DMA for other types). > Well, I was talking about our particular case here. I did not imply that we should forget about the other cases. >> And we want to avoid bouncing at the USB layer too (that's what v1 did). >> >> The strategy so far is: >> - we have modified the USB buffer allocation routines >> hcd_buffer_alloc()/hcd_buffer_free() to always return normal kernel memory >> when HCD_NO_COHERENT_MEM is set on the host controller. >> - during map_urb_for_dma()/unmap_urb_for_dma() we need to make sure that >> those USB buffers are sync'ed, even if we are told >> USB_NO_{SETUP,TRANSFER}_DMA_MAP >> >> So the logic would be: >> >> If URB_NO_TRANSFER_DMA_MAP is _cleared_ then do the mapping > > No, that's wrong because it ignores the HCD_LOCAL_MEM flag. > When I said "do the mapping" there I meant to do a dma_map_single() if self.uses_dma, else if HCD_LOCAL_MEM is set then do a hcd_alloc_coherent(). I should have been more clear on that. >> - this case covers normal kernel memory used as a buffer and not >> already DMA mapped by a USB driver >> >> Otherwise if HCD_NO_COHERENT_MEM is set _and_ num_sgs == 0 _and_ >> transfer_buffer_length > 0 then do the mapping too >> - this case covers USB buffers allocated via usb_buffer_alloc() and >> marked URB_NO_TRANSFER_DMA_MAP by a USB driver, which are allocated from >> normal kernel memory when HCD_NO_COHERENT_MEM is set (we avoid bouncing >> buffers here too, at least if they sit already within MEM2 in the Wii, but >> anyway that's part of the platform DMA mapping code) >> >> s-g urbs do not need a mapping as they have already been mapped, marked >> URB_NO_TRANSFER_DMA_MAP and have num_sgs > 0 > > Actually the test for transfer_buffer_length == 0 should be done first, > since obviously no mapping is needed if there's no data. (And in fact > the current code does do this; I was wrong earlier when I said it > doesn't.) > > So let's make things a little easier by first testing the conditions > under which no mapping is needed: > > If transfer_buffer_length is 0 then do nothing. > Otherwise if num_sgs > 0 then do nothing. > Otherwise if URB_NO_TRANSFER_DMA_MAP and transfer_dma > are both set (this avoids your HCD_NO_COHERENT_MEM > case) then do nothing. > I see. This case would include the PIO case too (for which dma_handle is set to all 1s). So this assumes that transfer_dma should be set initially to 0 when allocating USB buffers for HCD_NO_COHERENT_MEM. > The remaining cases all need mapping and/or bounce buffers: > > Otherwise if HCD_LOCAL_MEM is set then call hcd_alloc_coherent. > Otherwise call dma_map_single. > > Finally, the unmapping tests can be simplified greatly if the kind of > mapping is recorded in the URB flags. > Good point. > Alan Stern > Thanks for your comments, Albert ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm
[Re: [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm] On 26/02/2010 (Fri 14:23) Scott Wood wrote: > On Fri, Feb 26, 2010 at 01:42:39PM -0600, Kumar Gala wrote: > > > > On Feb 26, 2010, at 1:25 PM, Paul Gortmaker wrote: > > > > > Sending a break on the SOC UARTs found in some MPC83xx/85xx/86xx > > > chips seems to cause a short lived IRQ storm (/proc/interrupts > > > typically shows somewhere between 300 and 1500 events). Unfortunately > > > this renders SysRQ over the serial console completely inoperable. > > > Testing with obvious things like ACKing the event doesn't seem to > > > change anything vs. a completely dumb approach of just ignoring > > > it and waiting for it to stop, so that is what is implemented here. > > > > > > Signed-off-by: Paul Gortmaker > > > --- > > > > > > This is a refresh of a patch I'd done earlier -- I've tried to make > > > the bug support as generic as possible to minimize having board > > > specific ifdef crap in 8250.c -- any suggestions on how to further > > > improve it are welcome. > > > > > > drivers/serial/8250.c |6 ++ > > > drivers/serial/8250.h | 20 > > > drivers/serial/Kconfig | 14 ++ > > > include/linux/serial_reg.h |2 ++ > > > 4 files changed, 42 insertions(+), 0 deletions(-) > > > > > > diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c > > > index e9b15c3..850b0e9 100644 > > > --- a/drivers/serial/8250.c > > > +++ b/drivers/serial/8250.c > > > @@ -1531,6 +1531,11 @@ static void serial8250_handle_port(struct > > > uart_8250_port *up) > > > > > > status = serial_inp(up, UART_LSR); > > > > > > + if ((up->bugs & UART_BUG_PPC) && (status == UART_LSR_RFE_ERROR_BITS)) { > > > + spin_unlock_irqrestore(&up->port.lock, flags); > > > + return; > > > + } > > Will LSR always be 0xf1 when this problem hits? At least the transmit bits > shouldn't be relevant. It was, based only on the emperical data I collected. I agree that the Tx data shouldn't really matter. But it is a moot point now that I know about the errata workaround... > > This has been listed as an erratum in some of the newer chips (e.g. > mpc8568). > > The suggested as workaround is to, upon seeing a break condition: > - read RBR > - delay at least one character period > - read RBR again > > If I'm interpreting this correctly, it could be implemented by doing the > normal break handling on the first interrupt, plus setting a flag so that the > next interrupt simply reads RBR, clears the flag, and returns, without ever > reading LSR. Thanks for the info -- that makes for a better fix (in that the storm gets averted completely) so your interpretation is on the money. The only question that remains is whether we: (a) deploy it everywhere, or (b) leave it as a config option and update Kconfig with select on the boards of interest, or (c) implement dynamic enablement based on something like adding a detect_arch_bugs() to 8250.c and then for powerpc, we iterate over of_flat_dt_is_compatible(root, blacklist[i]) looking for a match. Paul. From c77b1600975b5fc596b2baebf43e28b66969181f Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Fri, 26 Feb 2010 10:29:46 -0500 Subject: [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm Sending a break on the SOC UARTs found in some MPC83xx/85xx/86xx chips seems to cause a short lived IRQ storm (/proc/interrupts typically shows somewhere between 300 and 1500 events). Unfortunately this renders SysRQ over the serial console completely inoperable. The suggested workaround in the errata is to read the Rx register, wait one character period, and then read the Rx register again. We achieve this by tracking the old LSR value, and on the subsequent interrupt event after a break, we don't read LSR, instead we just read the RBR again and return immediately. Signed-off-by: Paul Gortmaker --- drivers/serial/8250.c | 11 ++- drivers/serial/8250.h | 20 drivers/serial/Kconfig | 14 ++ 3 files changed, 44 insertions(+), 1 deletions(-) diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index e9b15c3..645cf9b 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -143,6 +143,7 @@ struct uart_8250_port { unsigned char mcr_mask; /* mask of user bits */ unsigned char mcr_force; /* mask of forced bits */ unsigned char cur_iotype; /* Running I/O type */ + unsigned char lsr_last; /* LSR of last IRQ event */ /* * Some bits in registers are cleared on a read, so they must @@ -1529,7 +1530,14 @@ static void serial8250_handle_port(struct uart_8250_port *up) spin_lock_irqsave(&up->port.lock, flags); - status = serial_inp(up, UART_LSR); + if (unlikely(up->lsr_last & UART_LSR_BI && up->bugs & UART_BUG_PPC)) { + up->lsr_last &= ~UART_LSR
Re: [RFC: PATCH 04/13] powerpc/476: add machine check handler for 47x core
On Mon, Mar 01, 2010 at 05:13:23AM -0700, Dave Kleikamp wrote: > powerpc/476: add machine check handler for 47x core > > From: Dave Kleikamp > > The 47x core's MCSR varies from 44x, so it needs it's own machine check > handler. > --- a/arch/powerpc/kernel/traps.c > +++ b/arch/powerpc/kernel/traps.c > @@ -376,6 +376,44 @@ int machine_check_440A(struct pt_regs *regs) > } > return 0; > } > + > +int machine_check_47x(struct pt_regs *regs) > +{ > + unsigned long reason = get_mc_reason(regs); > + > + printk("Machine check in kernel mode.\n"); It's quite possible that the other machine check handlers don't have printk KERN_-levels on them but it would be a good idea to use them here. > + if (reason & ESR_IMCP){ > + printk("Instruction Synchronous Machine Check exception\n"); > + mtspr(SPRN_ESR, reason & ~ESR_IMCP); > + } > + else { } else { Or, rather, add an early return above and you can just remove one level of indentation below. > + u32 mcsr = mfspr(SPRN_MCSR); > + if (mcsr & MCSR_IB) > + printk("Instruction Read PLB Error\n"); > + if (mcsr & MCSR_DRB) > + printk("Data Read PLB Error\n"); > + if (mcsr & MCSR_DWB) > + printk("Data Write PLB Error\n"); > + if (mcsr & MCSR_TLBP) > + printk("TLB Parity Error\n"); > + if (mcsr & MCSR_ICP){ > + flush_instruction_cache(); > + printk("I-Cache Parity Error\n"); > + } > + if (mcsr & MCSR_DCSP) > + printk("D-Cache Search Parity Error\n"); > + if (mcsr & PPC47x_MCSR_GPR) > + printk("GPR Parity Error\n"); > + if (mcsr & PPC47x_MCSR_FPR) > + printk("FPR Parity Error\n"); > + if (mcsr & PPC47x_MCSR_IMP) > + printk("Machine Check exception is imprecise\n"); > + > + /* Clear MCSR */ > + mtspr(SPRN_MCSR, mcsr); > + } > + return 0; > +} ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC PATCH v2 8/9] USB: add HCD_NO_COHERENT_MEM host controller driver flag
On Mon, 1 Mar 2010, Albert Herranz wrote: > >> Am I on the right path? > > > > More or less. I would do it somewhat differently: > > > > If URB_NO_TRANSFER_DMA_MAP is set then no map is needed. > > Otherwise if num_sgs > 0 then no map is needed. > > Otherwise if HCD_NO_COHERENT_MEM is set then use > > hcd_alloc_coherent(). > > Otherwise if transfer_buffer_length > 0 then use > > dma_map_single(). > > > > I think that logic is not quite right. > Remember that the final goal is to avoid allocating USB buffers from coherent > memory (because the USB drivers access USB buffers without access > restrictions but the platform I'm working on can't write to coherent memory > unless it is done in 32-bit chunks). Actually the final goal is to make the mapping/unmapping algorithms clear and correct. One of the subgoals involves avoiding coherent USB buffers, but there are others as well (if you look back the through the linux-usb mailing list for the last few weeks you'll see a discussion about a controller which has to use PIO for control transfers but can use DMA for other types). > And we want to avoid bouncing at the USB layer too (that's what v1 did). > > The strategy so far is: > - we have modified the USB buffer allocation routines > hcd_buffer_alloc()/hcd_buffer_free() to always return normal kernel memory > when HCD_NO_COHERENT_MEM is set on the host controller. > - during map_urb_for_dma()/unmap_urb_for_dma() we need to make sure that > those USB buffers are sync'ed, even if we are told > USB_NO_{SETUP,TRANSFER}_DMA_MAP > > So the logic would be: > > If URB_NO_TRANSFER_DMA_MAP is _cleared_ then do the mapping No, that's wrong because it ignores the HCD_LOCAL_MEM flag. > - this case covers normal kernel memory used as a buffer and not > already DMA mapped by a USB driver > > Otherwise if HCD_NO_COHERENT_MEM is set _and_ num_sgs == 0 _and_ > transfer_buffer_length > 0 then do the mapping too > - this case covers USB buffers allocated via usb_buffer_alloc() and > marked URB_NO_TRANSFER_DMA_MAP by a USB driver, which are allocated from > normal kernel memory when HCD_NO_COHERENT_MEM is set (we avoid bouncing > buffers here too, at least if they sit already within MEM2 in the Wii, but > anyway that's part of the platform DMA mapping code) > > s-g urbs do not need a mapping as they have already been mapped, marked > URB_NO_TRANSFER_DMA_MAP and have num_sgs > 0 Actually the test for transfer_buffer_length == 0 should be done first, since obviously no mapping is needed if there's no data. (And in fact the current code does do this; I was wrong earlier when I said it doesn't.) So let's make things a little easier by first testing the conditions under which no mapping is needed: If transfer_buffer_length is 0 then do nothing. Otherwise if num_sgs > 0 then do nothing. Otherwise if URB_NO_TRANSFER_DMA_MAP and transfer_dma are both set (this avoids your HCD_NO_COHERENT_MEM case) then do nothing. The remaining cases all need mapping and/or bounce buffers: Otherwise if HCD_LOCAL_MEM is set then call hcd_alloc_coherent. Otherwise call dma_map_single. Finally, the unmapping tests can be simplified greatly if the kind of mapping is recorded in the URB flags. Alan Stern ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC: PATCH 06/13] powerpc/4xx: Simple platform for the ISS 4xx simulator
On Mon, Mar 01, 2010 at 12:16:00PM -0700, Dave Kleikamp wrote: >diff --git a/arch/powerpc/platforms/44x/Kconfig >b/arch/powerpc/platforms/44x/Kconfig >index 1dfc1c1..915c295 100644 >--- a/arch/powerpc/platforms/44x/Kconfig >+++ b/arch/powerpc/platforms/44x/Kconfig >@@ -162,6 +162,17 @@ config YOSEMITE > help > This option enables support for the AMCC PPC440EP evaluation board. > >+config ISS4xx >+ bool "ISS 4xx Simulator" >+ depends on (44x || 40x) >+ default n >+ select 405GP if 40x >+ select 440GP if 44x Won't that now build a 44x_46x kernel due to the 'select 440GP' there? If so, doesn't that cause issues for 476? Confused... josh ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC: PATCH 08/13] powerpc/476: define specific cpu table entry for DD1 and DD1.1 cores
On Mon, Mar 01, 2010 at 02:13:52PM -0500, Dave Kleikamp wrote: >powerpc/476: define specific cpu table entry for DD1 and DD1.1 cores > >From: Benjamin Herrenschmidt > >There are still some unstable bits on the DD1 and DD1.1 cores. Don't use >the FPU or the tlbivax operation. Define CPU_FTR_476_DD1 and >CPU_FTR_476_DD1_1 for additional workarounds in later patches. > >The DD1 core requires workarounds triggered by both CPU_FTR_476_DD1 >and CPU_FTR_476_DD1_1. the DD1.1 core only needs CPU_FTR_476_DD1_1 >defined. DD1, DD1.1, and all others have the same PVR value? How do you tell which core version you have? josh ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC: PATCH 03/13] powerpc/47x: Base ppc476 support
Overall I'm just going to trust you that things aren't broken on 47x :) A few minor comments below. Also, if Torez and Benh contributed to this code, then their S-o-b lines should be included as well (same goes for any other patch). On Mon, Mar 01, 2010 at 12:13:15PM -0700, Dave Kleikamp wrote: >diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h >index bc8dd53..4af1c28 100644 >--- a/arch/powerpc/include/asm/reg.h >+++ b/arch/powerpc/include/asm/reg.h >@@ -813,6 +813,7 @@ > #define PVR_403GC 0x00200200 > #define PVR_403GCX0x00201400 > #define PVR_405GP 0x4011 >+#define PVR_476 0x11a52000 Is that really needed? None of the 44x CPUs have a PVR value here. > #define PVR_STB03XXX 0x4031 > #define PVR_NP405H0x4141 > #define PVR_NP405L0x4161 >diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c >index 2fc82ba..338ac47 100644 >--- a/arch/powerpc/kernel/cputable.c >+++ b/arch/powerpc/kernel/cputable.c >@@ -1701,6 +1701,19 @@ static struct cpu_spec __initdata cpu_specs[] = { > .machine_check = machine_check_440A, > .platform = "ppc440", > }, >+ { /* 476 core */ >+ .pvr_mask = 0x, >+ .pvr_value = 0x11a5, Could we use PVR_476 here (if it's going to stay). >+ .cpu_name = "476", >+ .cpu_features = CPU_FTRS_47X, >+ .cpu_user_features = COMMON_USER_BOOKE | >+ PPC_FEATURE_HAS_FPU, >+ .mmu_features = MMU_FTR_TYPE_47x | >+ MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL, >+ .icache_bsize = 32, >+ .dcache_bsize = 128, >+ .platform = "ppc470", >+ }, >diff --git a/arch/powerpc/platforms/44x/Kconfig >b/arch/powerpc/platforms/44x/Kconfig >index 7486bff..1dfc1c1 100644 >--- a/arch/powerpc/platforms/44x/Kconfig >+++ b/arch/powerpc/platforms/44x/Kconfig >@@ -1,6 +1,17 @@ >+config PPC_44x_46x >+ bool "Support for 44x and 46x variants" >+ depends on 44x >+ default n Why do this? All it seems to do is add a bunch of churn to the Kconfig here. If the intention was to try and prevent selecting both 44x and 47x kernel options, then maybe I could see that. However nothing prevents both from being enabled. Maybe PPC_47x should: depends on !PPC_44x_46x && 44x josh ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] pata_mpc52xx: optimizing code size by change of ATA timing data types
On 02/16/2010 02:41 PM, Grant Likely wrote: [cc'd linux-kernel, linux-ide and Jeff Garzik] Hi Roman. you should use ./scripts/get_maintainer.pl to make sure you're cc'ing the right people when posting patches. You should repost so that Jeff has a copy of the patch to pick up (and add my acked-by when you do). On Wed, Dec 16, 2009 at 6:29 AM, Roman Fietze wrote: Hello Everybody, A totally simple patch that reduces the text size as of the ppc_6xx-size command of pata_mpc52xx by more than 10%, by reducing the rodata size from 0x4a4 to 0x17e bytes. This is simply done by changing the data types of the ATA timing constants. Acked-by: Grant Likely I have the ACK, but never saw the requested repost... req that, please? ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC PATCH v2 8/9] USB: add HCD_NO_COHERENT_MEM host controller driver flag
Alan Stern wrote: > If urb->num_sgs > 0 then urb has been s-g mapped. Although we don't > currently check for it, quite a few URBs have transfer_buffer_length == > 0 (a number of control requests are like this, for example) so they > don't need a mapping either. > Ok, I'll use urb->num_sgs > 0 to check for s-g mapped requests. >> The final logic would be something like: >> - map if URB_NO_TRANSFER_DMA_MAP is cleared >> - otherwise (URB_TRANSFER_NO_DMA_MAP is set so) map if >> HCD_NO_COHERENT_MEM is set _and_ it's not a scatter/gather request >> (as that should have been mapped already by usb_buffer_map_sg()) >> >> Am I on the right path? > > More or less. I would do it somewhat differently: > > If URB_NO_TRANSFER_DMA_MAP is set then no map is needed. > Otherwise if num_sgs > 0 then no map is needed. > Otherwise if HCD_NO_COHERENT_MEM is set then use > hcd_alloc_coherent(). > Otherwise if transfer_buffer_length > 0 then use > dma_map_single(). > I think that logic is not quite right. Remember that the final goal is to avoid allocating USB buffers from coherent memory (because the USB drivers access USB buffers without access restrictions but the platform I'm working on can't write to coherent memory unless it is done in 32-bit chunks). And we want to avoid bouncing at the USB layer too (that's what v1 did). The strategy so far is: - we have modified the USB buffer allocation routines hcd_buffer_alloc()/hcd_buffer_free() to always return normal kernel memory when HCD_NO_COHERENT_MEM is set on the host controller. - during map_urb_for_dma()/unmap_urb_for_dma() we need to make sure that those USB buffers are sync'ed, even if we are told USB_NO_{SETUP,TRANSFER}_DMA_MAP So the logic would be: If URB_NO_TRANSFER_DMA_MAP is _cleared_ then do the mapping - this case covers normal kernel memory used as a buffer and not already DMA mapped by a USB driver Otherwise if HCD_NO_COHERENT_MEM is set _and_ num_sgs == 0 _and_ transfer_buffer_length > 0 then do the mapping too - this case covers USB buffers allocated via usb_buffer_alloc() and marked URB_NO_TRANSFER_DMA_MAP by a USB driver, which are allocated from normal kernel memory when HCD_NO_COHERENT_MEM is set (we avoid bouncing buffers here too, at least if they sit already within MEM2 in the Wii, but anyway that's part of the platform DMA mapping code) s-g urbs do not need a mapping as they have already been mapped, marked URB_NO_TRANSFER_DMA_MAP and have num_sgs > 0 > Similar logic is needed for the setup buffer mapping, but you can > assume that control URBs never use scatter-gather so there's no need to > check num_sgs (and there's no need to check the transfer length, since > setup packets are always 8 bytes long). > > In fact, I think URB_NO_SETUP_DMA_MAP doesn't really offer any > worthwhile advantages. (About the only place where multiple control > requests are used in rapid succession is during firmware transfers, and > those aren't time-constrained.) It is currently used in a few > drivers, but we ought to be able to remove it without too much effort. > That might make a good project. > I'll leave that projects to others or, in any case, address it later :) > Alan Stern > Thanks, Albert ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC PATCH v2 8/9] USB: add HCD_NO_COHERENT_MEM host controller driver flag
On Mon, 1 Mar 2010, Albert Herranz wrote: > > Also, I can't help thinking that the corresponding *_map() and > > *_unmap() routines are so similar, it ought to be possible to combine > > them. The only difference is a check for a NULL DMA address, and it's > > not clear to me why it is present. It's also not clear why the test > > for a DMA address of all ones is present. Maybe they both can be > > removed. > > > > I think too that I can simplify that logic. > I added those checks in a defensive way seeking robustness while I > familiarize with the USB stack innards. So far, those cases are just > avoiding mappings when > urb_needs_transfer_dma_map()/urb_needs_transfer_dma_unmap() are > called with urb->transfer_buffer == 0 and urb->transfer_dma == 0. > > I guess that those cases are related to scatterlist-based urb requests. > What should be the correct way to check if a urb has already been > scatter/gather-mapped? If urb->num_sgs > 0 then urb has been s-g mapped. Although we don't currently check for it, quite a few URBs have transfer_buffer_length == 0 (a number of control requests are like this, for example) so they don't need a mapping either. > The final logic would be something like: > - map if URB_NO_TRANSFER_DMA_MAP is cleared > - otherwise (URB_TRANSFER_NO_DMA_MAP is set so) map if > HCD_NO_COHERENT_MEM is set _and_ it's not a scatter/gather request > (as that should have been mapped already by usb_buffer_map_sg()) > > Am I on the right path? More or less. I would do it somewhat differently: If URB_NO_TRANSFER_DMA_MAP is set then no map is needed. Otherwise if num_sgs > 0 then no map is needed. Otherwise if HCD_NO_COHERENT_MEM is set then use hcd_alloc_coherent(). Otherwise if transfer_buffer_length > 0 then use dma_map_single(). Similar logic is needed for the setup buffer mapping, but you can assume that control URBs never use scatter-gather so there's no need to check num_sgs (and there's no need to check the transfer length, since setup packets are always 8 bytes long). In fact, I think URB_NO_SETUP_DMA_MAP doesn't really offer any worthwhile advantages. (About the only place where multiple control requests are used in rapid succession is during firmware transfers, and those aren't time-constrained.) It is currently used in a few drivers, but we ought to be able to remove it without too much effort. That might make a good project. Alan Stern ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[RFC: PATCH 13/13] powerpc/476: Add dci instruction to async interrupt handlers on DD1 core
powerpc/476: Add dci instruction to async interrupt handlers on DD1 core From: Dave Kleikamp Signed-off-by: Dave Kleikamp --- arch/powerpc/include/asm/asm-compat.h |5 + arch/powerpc/kernel/head_booke.h |3 +++ 2 files changed, 8 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h index fd16e3a..43e9d1b 100644 --- a/arch/powerpc/include/asm/asm-compat.h +++ b/arch/powerpc/include/asm/asm-compat.h @@ -71,6 +71,10 @@ lwsync; \ END_FTR_SECTION_IFSET(CPU_FTR_476_DD1_1) #define PPC476_ERR_MTPID PPC476_ERR_DCBx +#define PPC476_ERR_DCI() \ + BEGIN_FTR_SECTION; \ + dci;\ + END_FTR_SECTION_IFSET(CPU_FTR_476_DD1) #define PPC476_ERR_ISYNC() \ BEGIN_FTR_SECTION; \ isync; \ @@ -78,6 +82,7 @@ #else /* ! CONFIG_PPC_47x */ #define PPC476_ERR_DCBx() #define PPC476_ERR_MTPID() +#define PPC476_ERR_DCI() #define PPC476_ERR_ISYNC() #endif /* CONFIG_PPC_47x */ diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h index 6b1ad61..d247c1c 100644 --- a/arch/powerpc/kernel/head_booke.h +++ b/arch/powerpc/kernel/head_booke.h @@ -175,12 +175,14 @@ label: \ #define EXCEPTION(n, label, hdlr, xfer)\ START_EXCEPTION(label); \ + PPC476_ERR_DCI(); \ NORMAL_EXCEPTION_PROLOG;\ addir3,r1,STACK_FRAME_OVERHEAD; \ xfer(n, hdlr) #define CRITICAL_EXCEPTION(n, label, hdlr) \ START_EXCEPTION(label); \ + PPC476_ERR_DCI(); \ CRITICAL_EXCEPTION_PROLOG; \ addir3,r1,STACK_FRAME_OVERHEAD; \ EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ @@ -380,6 +382,7 @@ label: \ #define DECREMENTER_EXCEPTION\ START_EXCEPTION(Decrementer) \ + PPC476_ERR_DCI(); \ NORMAL_EXCEPTION_PROLOG; \ lis r0,tsr_...@h; /* Setup the DEC interrupt mask */\ mtspr SPRN_TSR,r0;/* Clear the DEC interrupt */ \ -- Dave Kleikamp IBM Linux Technology Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[RFC: PATCH 11/13] powerpc/476: Software workaround to fix dcr read/write sequencing.
powerpc/476: Software workaround to fix dcr read/write sequencing. From: Dave Kleikamp Copy the register containing the dcr address to a spr before mfdcrx or mtdcrx instruction. SPRN_SPRG_WSCRATCH_CRIT seems safe enough to use as a dummy register, as it is only otherwise used by critical interrupts, and we don't care if what we write is overwritten. Ideally, would only do this when CPU_FTR_476_DD1_1 is set, but I'm not getting the feature macros working in inlined assembler. The dummy store is pretty cheap though, so I'm doing it unconditionally for 47x. Signed-off-by: Dave Kleikamp --- arch/powerpc/include/asm/dcr-native.h | 24 ++-- 1 files changed, 22 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/dcr-native.h b/arch/powerpc/include/asm/dcr-native.h index 7d2e623..768ce50 100644 --- a/arch/powerpc/include/asm/dcr-native.h +++ b/arch/powerpc/include/asm/dcr-native.h @@ -50,14 +50,34 @@ extern unsigned int __mfdcr(unsigned int reg); static inline unsigned int mfdcrx(unsigned int reg) { unsigned int ret; - asm volatile(".long 0x7c000206 | (%0 << 21) | (%1 << 16)" + asm volatile( +#ifdef CONFIG_PPC_47x + /* +* Workaround: move reg to an spr prior to mfdcrx instruction +*/ +/* __stringify(BEGIN_FTR_SECTION) */ +"mtspr "__stringify(SPRN_SPRG_WSCRATCH_CRIT)",%1;" +/* __stringify(END_FTR_SECTION_IFSET(CPU_FTR_476_DD1_1)) */ +#endif +".long 0x7c000206 | (%0 << 21) | (%1 << 16)" : "=r" (ret) : "r" (reg)); return ret; } static inline void mtdcrx(unsigned int reg, unsigned int val) { - asm volatile(".long 0x7c000306 | (%0 << 21) | (%1 << 16)" + asm volatile( +#ifdef CONFIG_PPC_47x + /* +* Workaround: move reg to an spr prior to mtdcrx instruction. +* (Would love to get the FTR_SECTION macros working for +* inlined assembler -- shaggy) +*/ +/* __stringify(BEGIN_FTR_SECTION) */ +"mtspr "__stringify(SPRN_SPRG_WSCRATCH_CRIT)",%1;" +/* __stringify(END_FTR_SECTION_IFSET(CPU_FTR_476_DD1_1)) */ +#endif +".long 0x7c000306 | (%0 << 21) | (%1 << 16)" : : "r" (val), "r" (reg)); } -- Dave Kleikamp IBM Linux Technology Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[RFC: PATCH 12/13] powerpc/476: Workaround for DD1.1: Issue lwsync after mtpid
powerpc/476: Workaround for DD1.1: Issue lwsync after mtpid From: Dave Kleikamp Signed-off-by: Dave Kleikamp --- arch/powerpc/include/asm/asm-compat.h |2 ++ arch/powerpc/kernel/head_44x.S|1 + 2 files changed, 3 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h index 1890fbf..fd16e3a 100644 --- a/arch/powerpc/include/asm/asm-compat.h +++ b/arch/powerpc/include/asm/asm-compat.h @@ -70,12 +70,14 @@ BEGIN_FTR_SECTION; \ lwsync; \ END_FTR_SECTION_IFSET(CPU_FTR_476_DD1_1) +#define PPC476_ERR_MTPID PPC476_ERR_DCBx #define PPC476_ERR_ISYNC() \ BEGIN_FTR_SECTION; \ isync; \ END_FTR_SECTION_IFSET(CPU_FTR_476_DD1_1) #else /* ! CONFIG_PPC_47x */ #define PPC476_ERR_DCBx() +#define PPC476_ERR_MTPID() #define PPC476_ERR_ISYNC() #endif /* CONFIG_PPC_47x */ diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index a96796d..c27b0cd 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S @@ -705,6 +705,7 @@ _GLOBAL(set_context) stw r4, 0x4(r5) #endif mtspr SPRN_PID,r3 + PPC476_ERR_MTPID() isync /* Force context change */ blr -- Dave Kleikamp IBM Linux Technology Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[RFC: PATCH 09/13] powerpc/476: Workaround for dcbf/dcbz workaround on DD1
powerpc/476: Workaround for dcbf/dcbz workaround on DD1 From: Benjamin Herrenschmidt On the DD1.1 core, the dcbf and dcbz instructions need to be preceded and followed by an lwsync. We must trap user-space to ensure that this occurs there too. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Dave Kleikamp --- arch/powerpc/include/asm/asm-compat.h | 10 +++ arch/powerpc/include/asm/ppc-opcode.h |4 +++ arch/powerpc/include/asm/reg_booke.h |9 +++ arch/powerpc/kernel/entry_32.S| 35 +++--- arch/powerpc/kernel/head_44x.S|9 +++ arch/powerpc/kernel/misc_32.S | 32 ++- arch/powerpc/kernel/traps.c | 45 + arch/powerpc/lib/copy_32.S|7 - 8 files changed, 145 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h index 8f0fe79..bee05ec 100644 --- a/arch/powerpc/include/asm/asm-compat.h +++ b/arch/powerpc/include/asm/asm-compat.h @@ -64,6 +64,16 @@ #define PPC405_ERR77(ra,rb) #define PPC405_ERR77_SYNC #endif + +#ifdef CONFIG_PPC_47x +#define PPC476_ERR_DCBx() \ + BEGIN_FTR_SECTION; \ + lwsync; \ + END_FTR_SECTION_IFSET(CPU_FTR_476_DD1_1) +#else +#define PPC476_ERR_DCBx() +#endif /* CONFIG_PPC_47x */ + #endif #endif /* _ASM_POWERPC_ASM_COMPAT_H */ diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index ef9aa84..629b1fe 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -19,6 +19,10 @@ #define PPC_INST_DCBA 0x7c0005ec #define PPC_INST_DCBA_MASK 0xfc0007fe #define PPC_INST_DCBAL 0x7c2005ec +#define PPC_INST_DCBF 0x7cac +#define PPC_INST_DCBF_MASK 0xfc0007fe +#define PPC_INST_DCBZ 0x7c0007ec +#define PPC_INST_DCBZ_MASK 0xfc0007fe #define PPC_INST_DCBZL 0x7c2007ec #define PPC_INST_ISEL 0x7c1e #define PPC_INST_ISEL_MASK 0xfc3e diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h index a9245b9..bca3fba 100644 --- a/arch/powerpc/include/asm/reg_booke.h +++ b/arch/powerpc/include/asm/reg_booke.h @@ -276,6 +276,8 @@ #define ESR_IMCN 0x4000 /* Instr. Machine Check - Non-config */ #define ESR_IMCB 0x2000 /* Instr. Machine Check - Bus error */ #define ESR_IMCT 0x1000 /* Instr. Machine Check - Timeout */ +#define ESR_POT1 0x2000 /* 476 - IOCR1 trap */ +#define ESR_POT2 0x1000 /* 476 - IOCR2 trap */ #define ESR_PIL0x0800 /* Program Exception - Illegal */ #define ESR_PPR0x0400 /* Program Exception - Privileged */ #define ESR_PTR0x0200 /* Program Exception - Trap */ @@ -535,6 +537,13 @@ #define MMUBE1_VBE30x0004 #define MMUBE1_VBE40x0002 #define MMUBE1_VBE50x0001 +#define SPRN_IOCCR 860 +#defineIOCCR_IOCR1EN 0x8000 +#defineIOCCR_IOCR1M0x4000 +#defineIOCCR_IOCR2EN 0x2000 +#defineIOCCR_IOCR2M0x1000 +#define SPRN_IOCR1 861 +#define SPRN_IOCR2 862 #endif /* __ASM_POWERPC_REG_BOOKE_H__ */ #endif /* __KERNEL__ */ diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index ed4aeb9..57b7893 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -142,6 +142,12 @@ transfer_to_handler: addir2,r12,-THREAD tovirt(r2,r2) /* set r2 to current */ beq 2f /* if from user, fix up THREAD.regs */ +#ifdef CONFIG_PPC_47x +BEGIN_FTR_SECTION + li r11,0 + mtspr SPRN_IOCCR,r11 +END_FTR_SECTION_IFSET(CPU_FTR_476_DD1_1) +#endif /* CONFIG_PPC_47x */ addir11,r1,STACK_FRAME_OVERHEAD stw r11,PT_REGS(r12) #if defined(CONFIG_40x) || defined(CONFIG_BOOKE) @@ -280,6 +286,12 @@ stack_ovf: 0: _GLOBAL(DoSyscall) +#ifdef CONFIG_PPC_47x +BEGIN_FTR_SECTION + li r11,0 + mtspr SPRN_IOCCR,r11 +END_FTR_SECTION_IFSET(CPU_FTR_476_DD1_1) +#endif /* CONFIG_PPC_47x */ stw r3,ORIG_GPR3(r1) li r12,0 stw r12,RESULT(r1) @@ -381,6 +393,16 @@ BEGIN_MMU_FTR_SECTION 1: END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_47x) #endif /* CONFIG_44x */ +#ifdef CONFIG_PPC_47x +BEGIN_FTR_SECTION + lwz r7,_MSR(r1) + andi. r5,r7,MSR_PR + beq 11f + lis r4,(IOCCR_IOCR1EN|IOCCR_IOCR2EN)@h + mtspr SPRN_IOCCR,r4 +11: +END_FTR_SECTION_IFSET(CPU_FTR_476_DD1_1) +#endif /* CONFIG_PPC_47x
[RFC: PATCH 10/13] powerpc/476: Add isync to the top of all exception handlers for DD1.1 core
powerpc/476: Add isync to the top of all exception handlers for DD1.1 core From: Dave Kleikamp Signed-off-by: Dave Kleikamp --- arch/powerpc/include/asm/asm-compat.h |7 ++- arch/powerpc/kernel/head_booke.h |3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h index bee05ec..1890fbf 100644 --- a/arch/powerpc/include/asm/asm-compat.h +++ b/arch/powerpc/include/asm/asm-compat.h @@ -70,8 +70,13 @@ BEGIN_FTR_SECTION; \ lwsync; \ END_FTR_SECTION_IFSET(CPU_FTR_476_DD1_1) -#else +#define PPC476_ERR_ISYNC() \ + BEGIN_FTR_SECTION; \ + isync; \ + END_FTR_SECTION_IFSET(CPU_FTR_476_DD1_1) +#else /* ! CONFIG_PPC_47x */ #define PPC476_ERR_DCBx() +#define PPC476_ERR_ISYNC() #endif /* CONFIG_PPC_47x */ #endif diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h index 80d47f4..6b1ad61 100644 --- a/arch/powerpc/kernel/head_booke.h +++ b/arch/powerpc/kernel/head_booke.h @@ -165,7 +165,8 @@ */ #defineSTART_EXCEPTION(label) \ .align 5; \ -label: +label: \ + PPC476_ERR_ISYNC() #define FINISH_EXCEPTION(func) \ bl transfer_to_handler_full; \ -- Dave Kleikamp IBM Linux Technology Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[RFC: PATCH 08/13] powerpc/476: define specific cpu table entry for DD1 and DD1.1 cores
powerpc/476: define specific cpu table entry for DD1 and DD1.1 cores From: Benjamin Herrenschmidt There are still some unstable bits on the DD1 and DD1.1 cores. Don't use the FPU or the tlbivax operation. Define CPU_FTR_476_DD1 and CPU_FTR_476_DD1_1 for additional workarounds in later patches. The DD1 core requires workarounds triggered by both CPU_FTR_476_DD1 and CPU_FTR_476_DD1_1. the DD1.1 core only needs CPU_FTR_476_DD1_1 defined. Signed-off-by: Dave Kleikamp --- arch/powerpc/include/asm/cputable.h |2 ++ arch/powerpc/kernel/cputable.c | 38 ++- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 9fff628..d28eaf7 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -153,8 +153,10 @@ extern const char *powerpc_base_platform; #define CPU_FTR_NAP_DISABLE_L2_PR ASM_CONST(0x2000) #define CPU_FTR_DUAL_PLL_750FX ASM_CONST(0x4000) #define CPU_FTR_NO_DPM ASM_CONST(0x8000) +#define CPU_FTR_476_DD1ASM_CONST(0x0001) #define CPU_FTR_NEED_COHERENT ASM_CONST(0x0002) #define CPU_FTR_NO_BTICASM_CONST(0x0004) +#define CPU_FTR_476_DD1_1 ASM_CONST(0x0008) #define CPU_FTR_NODSISRALIGN ASM_CONST(0x0010) #define CPU_FTR_PPC_LE ASM_CONST(0x0020) #define CPU_FTR_REAL_LEASM_CONST(0x0040) diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index a06e6d3..0ea9134 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -1701,15 +1701,29 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_440A, .platform = "ppc440", }, - { /* 476 core */ + { /* 476 DD1 core - needs DD1.1 feature as well */ .pvr_mask = 0x, .pvr_value = 0x11a5, .cpu_name = "476", - .cpu_features = CPU_FTRS_47X, - .cpu_user_features = COMMON_USER_BOOKE | - PPC_FEATURE_HAS_FPU, + .cpu_features = CPU_FTRS_47X | CPU_FTR_476_DD1 | + CPU_FTR_476_DD1_1 | CPU_FTR_FPU_UNAVAILABLE, + .cpu_user_features = COMMON_USER_BOOKE, .mmu_features = MMU_FTR_TYPE_47x | - MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL, + MMU_FTR_LOCK_BCAST_INVAL, + .icache_bsize = 32, + .dcache_bsize = 128, + .machine_check = machine_check_47x, + .platform = "ppc470", + }, + { /* 476 DD1.1 core */ + .pvr_mask = 0x, + .pvr_value = 0x11a5, + .cpu_name = "476", + .cpu_features = CPU_FTRS_47X | CPU_FTR_476_DD1_1 | + CPU_FTR_FPU_UNAVAILABLE, + .cpu_user_features = COMMON_USER_BOOKE, + .mmu_features = MMU_FTR_TYPE_47x | + MMU_FTR_LOCK_BCAST_INVAL, .icache_bsize = 32, .dcache_bsize = 128, .machine_check = machine_check_47x, @@ -1724,6 +1738,20 @@ static struct cpu_spec __initdata cpu_specs[] = { PPC_FEATURE_HAS_FPU, .cpu_user_features = COMMON_USER_BOOKE, .mmu_features = MMU_FTR_TYPE_47x | + MMU_FTR_LOCK_BCAST_INVAL, + .icache_bsize = 32, + .dcache_bsize = 128, + .machine_check = machine_check_47x, + .platform = "ppc470", + }, + { /* 476 others */ + .pvr_mask = 0x, + .pvr_value = 0x11a5, + .cpu_name = "476", + .cpu_features = CPU_FTRS_47X, + .cpu_user_features = COMMON_USER_BOOKE | + PPC_FEATURE_HAS_FPU, + .mmu_features = MMU_FTR_TYPE_47x | MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL, .icache_bsize = 32, .dcache_bsize = 128, -- Dave Kleikamp IBM Linux Technology Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[RFC: PATCH 07/13] powerpc/47x: defconfig for 476 on the iss 4xx simulator
powerpc/47x: defconfig for 476 on the iss 4xx simulator From: Dave Kleikamp Signed-off-by: Dave Kleikamp --- arch/powerpc/configs/44x/iss476-smp_defconfig | 1023 + 1 files changed, 1023 insertions(+), 0 deletions(-) create mode 100644 arch/powerpc/configs/44x/iss476-smp_defconfig diff --git a/arch/powerpc/configs/44x/iss476-smp_defconfig b/arch/powerpc/configs/44x/iss476-smp_defconfig new file mode 100644 index 000..681c0d7 --- /dev/null +++ b/arch/powerpc/configs/44x/iss476-smp_defconfig @@ -0,0 +1,1023 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.33-rc7 +# Tue Feb 9 16:40:35 2010 +# +# CONFIG_PPC64 is not set + +# +# Processor support +# +# CONFIG_PPC_BOOK3S_32 is not set +# CONFIG_PPC_85xx is not set +# CONFIG_PPC_8xx is not set +# CONFIG_40x is not set +CONFIG_44x=y +# CONFIG_E200 is not set +CONFIG_PPC_FPU=y +CONFIG_4xx=y +CONFIG_BOOKE=y +CONFIG_PTE_64BIT=y +CONFIG_PHYS_64BIT=y +CONFIG_PPC_MMU_NOHASH=y +CONFIG_PPC_MMU_NOHASH_32=y +# CONFIG_PPC_MM_SLICES is not set +CONFIG_SMP=y +CONFIG_NR_CPUS=4 +# CONFIG_NOT_COHERENT_CACHE is not set +CONFIG_PPC32=y +CONFIG_WORD_SIZE=32 +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y +CONFIG_MMU=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set +# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set +CONFIG_IRQ_PER_CPU=y +CONFIG_NR_IRQS=512 +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_ARCH_HAS_ILOG2_U32=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +# CONFIG_ARCH_NO_VIRT_TO_BUS is not set +CONFIG_PPC=y +CONFIG_EARLY_PRINTK=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_PPC_OF=y +CONFIG_OF=y +CONFIG_PPC_UDBG_16550=y +CONFIG_GENERIC_TBSYNC=y +CONFIG_AUDIT_ARCH=y +CONFIG_GENERIC_BUG=y +CONFIG_DTC=y +# CONFIG_DEFAULT_UIMAGE is not set +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_PPC_DCR_NATIVE=y +# CONFIG_PPC_DCR_MMIO is not set +CONFIG_PPC_DCR=y +CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y +CONFIG_PPC_ADV_DEBUG_REGS=y +CONFIG_PPC_ADV_DEBUG_IACS=4 +CONFIG_PPC_ADV_DEBUG_DACS=2 +CONFIG_PPC_ADV_DEBUG_DVCS=2 +CONFIG_PPC_ADV_DEBUG_DAC_RANGE=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_CONSTRUCTORS=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_TREE_RCU=y +# CONFIG_TREE_PREEMPT_RCU is not set +# CONFIG_TINY_RCU is not set +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_GROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUPS is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_RELAY is not set +# CONFIG_NAMESPACES is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_LZO is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_AIO=y +CONFIG_HAVE_PERF_EVENTS=y + +# +# Kernel Performance Events And Counters +# +CONFIG_PERF_EVENTS=y +CONFIG_EVENT_PROFILE=y +# CONFIG_PERF_COUNTERS is not set +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +CONFIG_COMPAT_BRK=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_PROFILING=y +CONFIG_TRACEPOINTS=y +CONFIG_OPROFILE=y +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_HAVE_DMA_API_DEBUG=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +# CONFIG_SLOW_WORK is not set +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFI
[RFC: PATCH 05/13] powerpc/476: Add isync after loading mmu and debug spr's
powerpc/476: Add isync after loading mmu and debug spr's From: Dave Kleikamp 476 requires an isync after loading MMU and debug related SPR's. Some of these are in performance-critical paths and may need to be optimized, but initially, we're playing it safe. Signed-off-by: Dave Kleikamp --- arch/powerpc/kernel/head_44x.S |8 arch/powerpc/kernel/kprobes.c|3 +++ arch/powerpc/kernel/process.c|3 +++ arch/powerpc/kernel/traps.c |6 ++ arch/powerpc/mm/44x_mmu.c|1 + arch/powerpc/mm/tlb_nohash_low.S |3 +++ 6 files changed, 24 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index 1acd175..992e9d5 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S @@ -464,6 +464,9 @@ finish_tlb_load_44x: lwz r11,PGDIR(r11) mfspr r12,SPRN_PID/* Get PID */ 4: mtspr SPRN_MMUCR,r12 /* Set MMUCR */ +#ifdef CONFIG_PPC_47x + isync +#endif /* Mask of required permission bits. Note that while we * do copy ESR:ST to _PAGE_RW position as trying to write @@ -561,6 +564,9 @@ finish_tlb_load_44x: lwz r11,PGDIR(r11) mfspr r12,SPRN_PID/* Get PID */ 4: mtspr SPRN_MMUCR,r12 /* Set MMUCR */ +#ifdef CONFIG_PPC_47x + isync +#endif /* Make up the required permissions */ li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC @@ -1031,6 +1037,7 @@ clear_utlb_entry: mtspr SPRN_USPCR,r3 LOAD_REG_IMMEDIATE(r3, 0x12345670) mtspr SPRN_ISPCR,r3 + isync /* 476 needs this */ /* Force context change */ mfmsr r0 @@ -1116,6 +1123,7 @@ head_start_common: /* Establish the interrupt vector base */ lis r4,interrupt_b...@h /* IVPR only uses the high 16-bits */ mtspr SPRN_IVPR,r4 + isync /* 476 needs this */ addis r22,r22,kernelb...@h mtlrr22 diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index c932978..7fec5db 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -113,6 +113,9 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) #ifdef CONFIG_BOOKE regs->msr &= ~MSR_CE; mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM); +#ifdef CONFIG_PPC_47x + isync(); +#endif #endif /* diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 7b816da..15ee756 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -286,6 +286,9 @@ int set_dabr(unsigned long dabr) /* XXX should we have a CPU_FTR_HAS_DABR ? */ #if defined(CONFIG_BOOKE) mtspr(SPRN_DAC1, dabr); +#ifdef CONFIG_PPC_47x + isync(); +#endif #elif defined(CONFIG_PPC_BOOK3S) mtspr(SPRN_DABR, dabr); #endif diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 66617b6..47169f6 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -1078,6 +1078,9 @@ void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status) mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~DBCR0_BT); /* Clear the BT event */ mtspr(SPRN_DBSR, DBSR_BT); +#ifdef CONFIG_PPC_47x + isync(); +#endif /* Do the single step trick only when coming from userspace */ if (user_mode(regs)) { @@ -1100,6 +1103,9 @@ void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status) mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~DBCR0_IC); /* Clear the instruction completion event */ mtspr(SPRN_DBSR, DBSR_IC); +#ifdef CONFIG_PPC_47x + isync(); +#endif if (notify_die(DIE_SSTEP, "single_step", regs, 5, 5, SIGTRAP) == NOTIFY_STOP) { diff --git a/arch/powerpc/mm/44x_mmu.c b/arch/powerpc/mm/44x_mmu.c index d8c6efb..a5f082a 100644 --- a/arch/powerpc/mm/44x_mmu.c +++ b/arch/powerpc/mm/44x_mmu.c @@ -156,6 +156,7 @@ static void __cpuinit ppc47x_pin_tlb(unsigned int virt, unsigned int phys) virt, phys, bolted); mtspr(SPRN_MMUCR, 0); + isync(); __asm__ __volatile__( "tlbwe %2,%3,0\n" diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S index e925cb5..7c890f7 100644 --- a/arch/powerpc/mm/tlb_nohash_low.S +++ b/arch/powerpc/mm/tlb_nohash_low.S @@ -92,6 +92,9 @@ _GLOBAL(__tlbil_va) */ wrteei 0 mtspr SPRN_MMUCR,r5 +#ifdef CONFIG_PPC_47x + isync +#endif tlbsx. r6,0,r3 bne 10f sync -- Dave Kleikamp IBM Linux Technology Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.o
[RFC: PATCH 06/13] powerpc/4xx: Simple platform for the ISS 4xx simulator
powerpc/4xx: Simple platform for the ISS 4xx simulator From: Torez Smith This is a trivial 4xx plaform that uses the new simple bsp from Josh and is handy to use in simulators such as ISS or even Mambo who don't properly implement most of the actual devices in the SoC but really only the core. Signed-off-by: Dave Kleikamp --- arch/powerpc/boot/Makefile|5 + arch/powerpc/boot/dts/iss4xx-mpic.dts | 155 +++ arch/powerpc/boot/dts/iss4xx.dts | 116 +++ arch/powerpc/boot/treeboot-iss4xx.c | 56 +++ arch/powerpc/boot/wrapper |3 + arch/powerpc/include/asm/reg.h|3 + arch/powerpc/kernel/cputable.c| 15 +++ arch/powerpc/kernel/head_44x.S|2 arch/powerpc/platforms/44x/Kconfig| 11 ++ arch/powerpc/platforms/44x/Makefile |1 arch/powerpc/platforms/44x/iss4xx.c | 165 + 11 files changed, 531 insertions(+), 1 deletions(-) create mode 100644 arch/powerpc/boot/dts/iss4xx-mpic.dts create mode 100644 arch/powerpc/boot/dts/iss4xx.dts create mode 100644 arch/powerpc/boot/treeboot-iss4xx.c create mode 100644 arch/powerpc/platforms/44x/iss4xx.c diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index bb2465b..997196e 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -44,6 +44,7 @@ $(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=405 $(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=405 $(obj)/cuboot-acadia.o: BOOTCFLAGS += -mcpu=405 $(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405 +$(obj)/treeboot-iss4xx.o: BOOTCFLAGS += -mcpu=405 $(obj)/virtex405-head.o: BOOTAFLAGS += -mcpu=405 @@ -77,7 +78,7 @@ src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c cuboot-warp.c cuboot-85xx-cpm2.c cuboot-yosemite.c simpleboot.c \ virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c \ cuboot-acadia.c cuboot-amigaone.c cuboot-kilauea.c \ - gamecube-head.S gamecube.c wii-head.S wii.c + gamecube-head.S gamecube.c wii-head.S wii.c treeboot-iss4xx.c src-boot := $(src-wlib) $(src-plat) empty.c src-boot := $(addprefix $(obj)/, $(src-boot)) @@ -206,6 +207,8 @@ image-$(CONFIG_TAISHAN) += cuImage.taishan image-$(CONFIG_KATMAI) += cuImage.katmai image-$(CONFIG_WARP) += cuImage.warp image-$(CONFIG_YOSEMITE) += cuImage.yosemite +image-$(CONFIG_ISS4xx) += treeImage.iss4xx \ + treeImage.iss4xx-mpic # Board ports in arch/powerpc/platform/8xx/Kconfig image-$(CONFIG_MPC86XADS) += cuImage.mpc866ads diff --git a/arch/powerpc/boot/dts/iss4xx-mpic.dts b/arch/powerpc/boot/dts/iss4xx-mpic.dts new file mode 100644 index 000..23e9d9b --- /dev/null +++ b/arch/powerpc/boot/dts/iss4xx-mpic.dts @@ -0,0 +1,155 @@ +/* + * Device Tree Source for IBM Embedded PPC 476 Platform + * + * Copyright 2010 Torez Smith, IBM Corporation. + * + * Based on earlier code: + * Copyright (c) 2006, 2007 IBM Corp. + * Josh Boyer , David Gibson + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without + * any warranty of any kind, whether express or implied. + */ + +/dts-v1/; + +/memreserve/ 0x01f0 0x0010; + +/ { + #address-cells = <2>; + #size-cells = <1>; + model = "ibm,iss-4xx"; + compatible = "ibm,iss-4xx"; + dcr-parent = <&{/cpus/c...@0}>; + + aliases { + serial0 = &UART0; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + c...@0 { + device_type = "cpu"; + model = "PowerPC,4xx"; // real CPU changed in sim + reg = <0>; + clock-frequency = <1>; // 100Mhz :-) + timebase-frequency = <1>; + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; + d-cache-size = <32768>; + dcr-controller; + dcr-access-method = "native"; + status = "ok"; + }; + c...@1 { + device_type = "cpu"; + model = "PowerPC,4xx"; // real CPU changed in sim + reg = <1>; + clock-frequency = <1>; // 100Mhz :-) + timebase-frequency = <1>; + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <32768>; + d-cache-size = <32768>; + dcr-controller; +
[RFC: PATCH 04/13] powerpc/476: add machine check handler for 47x core
powerpc/476: add machine check handler for 47x core From: Dave Kleikamp The 47x core's MCSR varies from 44x, so it needs it's own machine check handler. Signed-off-by: Dave Kleikamp --- arch/powerpc/include/asm/cputable.h |1 + arch/powerpc/include/asm/reg_booke.h |2 +- arch/powerpc/kernel/cputable.c |1 + arch/powerpc/kernel/traps.c | 38 ++ 4 files changed, 41 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 75b774e..9fff628 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -72,6 +72,7 @@ extern int machine_check_4xx(struct pt_regs *regs); extern int machine_check_440A(struct pt_regs *regs); extern int machine_check_e500(struct pt_regs *regs); extern int machine_check_e200(struct pt_regs *regs); +extern int machine_check_47x(struct pt_regs *regs); /* NOTE WELL: Update identify_cpu() if fields are added or removed! */ struct cpu_spec { diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h index ee61a9d..a9245b9 100644 --- a/arch/powerpc/include/asm/reg_booke.h +++ b/arch/powerpc/include/asm/reg_booke.h @@ -194,7 +194,7 @@ #ifdef CONFIG_PPC_47x #define PPC47x_MCSR_GPR0x0100 /* GPR parity error */ #define PPC47x_MCSR_FPR0x0080 /* FPR parity error */ -#define PPC47x_MCSR_IPR0x0040 /* Imprecise Machine Check Exception */ +#define PPC47x_MCSR_IMP0x0040 /* Imprecise Machine Check Exception */ #endif #ifdef CONFIG_E500 diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 338ac47..7b2a67c 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -1712,6 +1712,7 @@ static struct cpu_spec __initdata cpu_specs[] = { MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL, .icache_bsize = 32, .dcache_bsize = 128, + .machine_check = machine_check_47x, .platform = "ppc470", }, { /* default match */ diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index d069ff8..66617b6 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -376,6 +376,44 @@ int machine_check_440A(struct pt_regs *regs) } return 0; } + +int machine_check_47x(struct pt_regs *regs) +{ + unsigned long reason = get_mc_reason(regs); + + printk("Machine check in kernel mode.\n"); + if (reason & ESR_IMCP){ + printk("Instruction Synchronous Machine Check exception\n"); + mtspr(SPRN_ESR, reason & ~ESR_IMCP); + } + else { + u32 mcsr = mfspr(SPRN_MCSR); + if (mcsr & MCSR_IB) + printk("Instruction Read PLB Error\n"); + if (mcsr & MCSR_DRB) + printk("Data Read PLB Error\n"); + if (mcsr & MCSR_DWB) + printk("Data Write PLB Error\n"); + if (mcsr & MCSR_TLBP) + printk("TLB Parity Error\n"); + if (mcsr & MCSR_ICP){ + flush_instruction_cache(); + printk("I-Cache Parity Error\n"); + } + if (mcsr & MCSR_DCSP) + printk("D-Cache Search Parity Error\n"); + if (mcsr & PPC47x_MCSR_GPR) + printk("GPR Parity Error\n"); + if (mcsr & PPC47x_MCSR_FPR) + printk("FPR Parity Error\n"); + if (mcsr & PPC47x_MCSR_IMP) + printk("Machine Check exception is imprecise\n"); + + /* Clear MCSR */ + mtspr(SPRN_MCSR, mcsr); + } + return 0; +} #elif defined(CONFIG_E500) int machine_check_e500(struct pt_regs *regs) { -- Dave Kleikamp IBM Linux Technology Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[RFC: PATCH 03/13] powerpc/47x: Base ppc476 support
powerpc/47x: Base ppc476 support From: Dave Kleikamp This patch adds the base support for the 476 processor. The code was primarily written by Ben Herrenschmidt and Torez Smith, but I've been maintaining it for a while. The goal is to have a single binary that will run on 44x and 47x, but we still have some details to work out. The biggest is that the L1 cache line size differs on the two platforms, but it's currently a compile-time option. Signed-off-by: Dave Kleikamp --- arch/powerpc/include/asm/cache.h |6 arch/powerpc/include/asm/cputable.h|4 arch/powerpc/include/asm/mmu-44x.h | 51 +++ arch/powerpc/include/asm/mmu.h |1 arch/powerpc/include/asm/reg.h |1 arch/powerpc/include/asm/reg_booke.h | 26 ++ arch/powerpc/kernel/cputable.c | 13 + arch/powerpc/kernel/entry_32.S |5 arch/powerpc/kernel/head_44x.S | 502 +++- arch/powerpc/kernel/misc_32.S |9 - arch/powerpc/kernel/smp.c |8 + arch/powerpc/mm/44x_mmu.c | 144 + arch/powerpc/mm/mmu_context_nohash.c |8 + arch/powerpc/mm/mmu_decl.h |7 arch/powerpc/mm/tlb_nohash_low.S | 118 +++- arch/powerpc/platforms/44x/Kconfig | 37 ++ arch/powerpc/platforms/Kconfig.cputype |5 17 files changed, 888 insertions(+), 57 deletions(-) diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h index 81de6eb..725634f 100644 --- a/arch/powerpc/include/asm/cache.h +++ b/arch/powerpc/include/asm/cache.h @@ -12,8 +12,12 @@ #define L1_CACHE_SHIFT 6 #define MAX_COPY_PREFETCH 4 #elif defined(CONFIG_PPC32) -#define L1_CACHE_SHIFT 5 #define MAX_COPY_PREFETCH 4 +#if defined(CONFIG_PPC_47x) +#define L1_CACHE_SHIFT 7 +#else +#define L1_CACHE_SHIFT 5 +#endif #else /* CONFIG_PPC64 */ #define L1_CACHE_SHIFT 7 #endif diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 80f315e..75b774e 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -365,6 +365,7 @@ extern const char *powerpc_base_platform; #define CPU_FTRS_44X (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE) #define CPU_FTRS_440x6 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE | \ CPU_FTR_INDEXED_DCR) +#define CPU_FTRS_47X (CPU_FTRS_440x6) #define CPU_FTRS_E200 (CPU_FTR_USE_TB | CPU_FTR_SPE_COMP | \ CPU_FTR_NODSISRALIGN | CPU_FTR_COHERENT_ICACHE | \ CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_NOEXECUTE) @@ -453,6 +454,9 @@ enum { #ifdef CONFIG_44x CPU_FTRS_44X | CPU_FTRS_440x6 | #endif +#ifdef CONFIG_PPC_47x + CPU_FTRS_47X | +#endif #ifdef CONFIG_E200 CPU_FTRS_E200 | #endif diff --git a/arch/powerpc/include/asm/mmu-44x.h b/arch/powerpc/include/asm/mmu-44x.h index 0372669..bf52d70 100644 --- a/arch/powerpc/include/asm/mmu-44x.h +++ b/arch/powerpc/include/asm/mmu-44x.h @@ -40,7 +40,7 @@ #define PPC44x_TLB_I 0x0400 /* Caching is inhibited */ #define PPC44x_TLB_M 0x0200 /* Memory is coherent */ #define PPC44x_TLB_G 0x0100 /* Memory is guarded */ -#define PPC44x_TLB_E 0x0080 /* Memory is guarded */ +#define PPC44x_TLB_E 0x0080 /* Memory is little endian */ #define PPC44x_TLB_PERM_MASK 0x003f #define PPC44x_TLB_UX 0x0020 /* User execution */ @@ -53,6 +53,52 @@ /* Number of TLB entries */ #define PPC44x_TLB_SIZE64 +/* 47x bits */ +#define PPC47x_MMUCR_TID 0x +#define PPC47x_MMUCR_STS 0x0001 + +/* Page identification fields */ +#define PPC47x_TLB0_EPN_MASK 0xf000 /* Effective Page Number */ +#define PPC47x_TLB0_VALID 0x0800 /* Valid flag */ +#define PPC47x_TLB0_TS 0x0400 /* Translation address space */ +#define PPC47x_TLB0_4K 0x +#define PPC47x_TLB0_16K0x0010 +#define PPC47x_TLB0_64K0x0030 +#define PPC47x_TLB0_1M 0x0070 +#define PPC47x_TLB0_16M0x00f0 +#define PPC47x_TLB0_256M 0x01f0 +#define PPC47x_TLB0_1G 0x03f0 +#define PPC47x_TLB0_BOLTED_R 0x0008 /* tlbre only */ + +/* Translation fields */ +#define PPC47x_TLB1_RPN_MASK 0xf000 /* Real Page Number */ +#define PPC47x_TLB1_ERPN_MASK 0x03ff + +/* Storage attribute and access control fields */ +#define PPC47x_TLB2_ATTR_MASK 0x0003ff80 +#define PPC47x_TLB2_IL1I 0x0002 /* Memory is guarded */ +#define PPC47x_TLB2_IL1D 0x0001 /* Memory is guarded */ +#define PPC47x_TLB2_U0 0x8000 /* User 0 */ +#define PPC47x_TLB2_U1 0x4000 /* User 1 */ +#define PPC47x_TLB2_U2 0x2000 /* User 2 */ +#define PPC4
[RFC: PATCH 01/13] powerpc/booke: Add Stack Marking support to Booke Exception Prolog
powerpc/booke: Add Stack Marking support to Booke Exception Prolog From: Torez Smith Signed-off-by: Torez Smith Signed-off-by: Dave Kleikamp --- arch/powerpc/kernel/head_booke.h |5 + 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h index 50504ae..80d47f4 100644 --- a/arch/powerpc/kernel/head_booke.h +++ b/arch/powerpc/kernel/head_booke.h @@ -1,6 +1,8 @@ #ifndef __HEAD_BOOKE_H__ #define __HEAD_BOOKE_H__ +#define STACK_FRAME_REGS_MARKERASM_CONST(0x72656773) + /* * Macros used for common Book-e exception handling */ @@ -48,6 +50,9 @@ stw r10,0(r11); \ rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\ stw r0,GPR0(r11);\ + lis r10, stack_frame_regs_mar...@ha;/* exception frame marker */ \ + addir10, r10, stack_frame_regs_mar...@l; \ + stw r10, 8(r11); \ SAVE_4GPRS(3, r11); \ SAVE_2GPRS(7, r11) -- Dave Kleikamp IBM Linux Technology Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[RFC: PATCH 02/13] powerpc/44x: break out cpu init code into stand-alone function
powerpc/44x: break out cpu init code into stand-alone function From: Dave Kleikamp The 47x platform supports multiple cores and shares code with 44x. Break out code that is common for initializing the primary and secondary cpus into a function which can be called for both. Signed-off-by: Dave Kleikamp --- arch/powerpc/kernel/head_44x.S | 330 +--- 1 files changed, 171 insertions(+), 159 deletions(-) diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index 711368b..39be049 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S @@ -69,165 +69,7 @@ _ENTRY(_start); mr r27,r7 li r24,0 /* CPU number */ -/* - * In case the firmware didn't do it, we apply some workarounds - * that are good for all 440 core variants here - */ - mfspr r3,SPRN_CCR0 - rlwinm r3,r3,0,0,27/* disable icache prefetch */ - isync - mtspr SPRN_CCR0,r3 - isync - sync - -/* - * Set up the initial MMU state - * - * We are still executing code at the virtual address - * mappings set by the firmware for the base of RAM. - * - * We first invalidate all TLB entries but the one - * we are running from. We then load the KERNELBASE - * mappings so we can begin to use kernel addresses - * natively and so the interrupt vector locations are - * permanently pinned (necessary since Book E - * implementations always have translation enabled). - * - * TODO: Use the known TLB entry we are running from to - * determine which physical region we are located - * in. This can be used to determine where in RAM - * (on a shared CPU system) or PCI memory space - * (on a DRAMless system) we are located. - * For now, we assume a perfect world which means - * we are located at the base of DRAM (physical 0). - */ - -/* - * Search TLB for entry that we are currently using. - * Invalidate all entries but the one we are using. - */ - /* Load our current PID->MMUCR TID and MSR IS->MMUCR STS */ - mfspr r3,SPRN_PID /* Get PID */ - mfmsr r4 /* Get MSR */ - andi. r4,r4,msr...@l /* TS=1? */ - beq wmmucr /* If not, leave STS=0 */ - orisr3,r3,ppc44x_mmucr_...@h/* Set STS=1 */ -wmmucr:mtspr SPRN_MMUCR,r3 /* Put MMUCR */ - sync - - bl invstr /* Find our address */ -invstr:mflrr5 /* Make it accessible */ - tlbsx r23,0,r5/* Find entry we are in */ - li r4,0/* Start at TLB entry 0 */ - li r3,0/* Set PAGEID inval value */ -1: cmpwr23,r4 /* Is this our entry? */ - beq skpinv /* If so, skip the inval */ - tlbwe r3,r4,PPC44x_TLB_PAGEID /* If not, inval the entry */ -skpinv:addir4,r4,1 /* Increment */ - cmpwi r4,64 /* Are we done? */ - bne 1b /* If not, repeat */ - isync /* If so, context change */ - -/* - * Configure and load pinned entry into TLB slot 63. - */ - - lis r3,page_off...@h - ori r3,r3,page_off...@l - - /* Kernel is at the base of RAM */ - li r4, 0/* Load the kernel physical address */ - - /* Load the kernel PID = 0 */ - li r0,0 - mtspr SPRN_PID,r0 - sync - - /* Initialize MMUCR */ - li r5,0 - mtspr SPRN_MMUCR,r5 - sync - - /* pageid fields */ - clrrwi r3,r3,10/* Mask off the effective page number */ - ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_256M - - /* xlat fields */ - clrrwi r4,r4,10/* Mask off the real page number */ - /* ERPN is 0 for first 4GB page */ - - /* attrib fields */ - /* Added guarded bit to protect against speculative loads/stores */ - li r5,0 - ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G) - -li r0,63/* TLB slot 63 */ - - tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ - tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */ - tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */ - - /* Force context change */ - mfmsr r0 - mtspr SPRN_SRR1, r0 - lis r0,3...@h - ori r0,r0,3...@l - mtspr SPRN_SRR0,r0 - sync - rfi - - /* If necessary, invalidate original entry we used */ -3: cmpwi r23,63 - beq 4f - li r6,0
[RFC: PATCH 00/13] powerpc/47x: Support for 476 core
These patches add support for the 476 core. The goal is to have a single binary that will run on both 44x and 47x, but we still have some details to work out. The biggest is that the L1 cache line size differs on the two platforms, but it's currently a compile-time option. The code was originally written by Ben Herrenschmidt and Torez Smith, but I've been maintaining it. I'll take responsibility for the content, but I can't take all the credit. The first patch is a generic bookE feature. Patches 2-5 add base 47x support. Patches 6 & 7 add a platform to support the ISS simulator, and patches 8-13 add workarounds for DD1 and DD1.1 hardware bugs. -- Dave Kleikamp IBM Linux Technology Center ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
JFFS2 warnings
I'm getting a bunch of these after I 'reboot' or 'poweroff' several times. Empty flash at 0x0056205c ends at 0x00562800 Empty flash at 0x00565334 ends at 0x00565800 Empty flash at 0x00576104 ends at 0x00576800 JFFS2 notice: (848) check_node_data: wrong data CRC in data node at 0x00577034: read 0xe6adad18, calculated 0x202a305c. JFFS2 notice: (848) check_node_data: wrong data CRC in data node at 0x00575768: read 0xe6adad18, calculated 0xfc64f8a3. I'm not too sure why I'm getting these, but recently they seem to have caused a few problems with parts of my filesystem (i.e. programs not running correctly). Can someone tell me what these are or what could be causing them? I'm using 2.6.33rc1 and this is on an mpc8313 based board. Not sure what other info would be useful. Thanks, Ron ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC PATCH v2 8/9] USB: add HCD_NO_COHERENT_MEM host controller driver flag
Alan Stern wrote: >> --- a/drivers/usb/core/hcd.c >> +++ b/drivers/usb/core/hcd.c >> @@ -1260,6 +1260,34 @@ static void hcd_free_coherent(struct usb_bus *bus, >> dma_addr_t *dma_handle, >> *dma_handle = 0; >> } >> >> +static int urb_needs_setup_dma_map(struct usb_hcd *hcd, struct urb *urb) >> +{ >> +return !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP) || >> + ((hcd->driver->flags & HCD_NO_COHERENT_MEM) && >> +urb->setup_dma == ~(dma_addr_t)0); >> +} >> + >> +static int urb_needs_setup_dma_unmap(struct usb_hcd *hcd, struct urb *urb) >> +{ >> +return !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP) || >> + ((hcd->driver->flags & HCD_NO_COHERENT_MEM) && >> +urb->setup_dma && urb->setup_dma != ~(dma_addr_t)0); >> +} >> + >> +static int urb_needs_transfer_dma_map(struct usb_hcd *hcd, struct urb *urb) >> +{ >> +return !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) || >> + ((hcd->driver->flags & HCD_NO_COHERENT_MEM) && >> +urb->transfer_dma == ~(dma_addr_t)0); >> +} >> + >> +static int urb_needs_transfer_dma_unmap(struct usb_hcd *hcd, struct urb >> *urb) >> +{ >> +return !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) || >> + ((hcd->driver->flags & HCD_NO_COHERENT_MEM) && >> +urb->transfer_dma && urb->transfer_dma != ~(dma_addr_t)0); >> +} >> + > > These functions would be a lot easier to understand if they were > expanded into multiple test and return statements, rather than > squeezing all the Boolean manipulations into single expressions. (Not > to mention the fact that other developement is going to make them even > more complicated than they are now...) > Yes, agreed. I'll enhance that, thanks. > Also, I can't help thinking that the corresponding *_map() and > *_unmap() routines are so similar, it ought to be possible to combine > them. The only difference is a check for a NULL DMA address, and it's > not clear to me why it is present. It's also not clear why the test > for a DMA address of all ones is present. Maybe they both can be > removed. > I think too that I can simplify that logic. I added those checks in a defensive way seeking robustness while I familiarize with the USB stack innards. So far, those cases are just avoiding mappings when urb_needs_transfer_dma_map()/urb_needs_transfer_dma_unmap() are called with urb->transfer_buffer == 0 and urb->transfer_dma == 0. I guess that those cases are related to scatterlist-based urb requests. What should be the correct way to check if a urb has already been scatter/gather-mapped? The final logic would be something like: - map if URB_NO_TRANSFER_DMA_MAP is cleared - otherwise (URB_TRANSFER_NO_DMA_MAP is set so) map if HCD_NO_COHERENT_MEM is set _and_ it's not a scatter/gather request (as that should have been mapped already by usb_buffer_map_sg()) Am I on the right path? > Alan Stern > Thanks, Albert ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[Patch] mpc5200b: improve baud rate calculation (reach high baud rates, better accuracy)
On the MPC5200B, select the baud rate prescaler as /4 by default to make very high baud rates (e.g. 3 MBaud) accessible and to achieve a higher precision for high baud rates in general. For baud rates below ~500 Baud, the code will automatically fall back to the /32 prescaler. The original MPC5200 does only have a /32 prescaler which is detected only once and stored in a global. A new chip-dependent method is used to set the divisor. Tested on a custom 5200B based board, with up to 3 MBaud. Signed-off-by: Albrecht Dreß --- --- linux-2.6.33/drivers/serial/mpc52xx_uart.c.orig 2010-02-24 19:52:17.0 +0100 +++ linux-2.6.33/drivers/serial/mpc52xx_uart.c 2010-02-26 21:12:51.0 +0100 @@ -144,9 +144,17 @@ struct psc_ops { unsigned char (*read_char)(struct uart_port *port); void(*cw_disable_ints)(struct uart_port *port); void(*cw_restore_ints)(struct uart_port *port); + void(*set_divisor)(struct uart_port *port, + unsigned int divisor); unsigned long (*getuartclk)(void *p); }; +/* We need to distinguish between the MPC5200 which has only a /32 prescaler, + * and the MPC5200B which has a /32 and a /4 prescaler. The global is fine, + * as the chip can be only either a 5200B or not. */ +static int is_mpc5200b = -1; + + #ifdef CONFIG_PPC_MPC52xx #define FIFO_52xx(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1)) static void mpc52xx_psc_fifo_init(struct uart_port *port) @@ -154,9 +162,6 @@ static void mpc52xx_psc_fifo_init(struct struct mpc52xx_psc __iomem *psc = PSC(port); struct mpc52xx_psc_fifo __iomem *fifo = FIFO_52xx(port); - /* /32 prescaler */ - out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); - out_8(&fifo->rfcntl, 0x00); out_be16(&fifo->rfalarm, 0x1ff); out_8(&fifo->tfcntl, 0x07); @@ -245,15 +250,40 @@ static void mpc52xx_psc_cw_restore_ints( out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); } +static void mpc52xx_psc_set_divisor(struct uart_port *port, + unsigned int divisor) +{ + struct mpc52xx_psc __iomem *psc = PSC(port); + + /* prescaler */ + if (is_mpc5200b != 1) + out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /32 */ + else if (divisor > 0x) { + out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /32 */ + divisor = (divisor + 4) / 8; + } else + out_be16(&psc->mpc52xx_psc_clock_select, 0xff00); /* /4 */ + + /* ctr */ + divisor &= 0x; + out_8(&psc->ctur, divisor >> 8); + out_8(&psc->ctlr, divisor & 0xff); +} + /* Search for bus-frequency property in this node or a parent */ static unsigned long mpc52xx_getuartclk(void *p) { /* -* 5200 UARTs have a / 32 prescaler -* but the generic serial code assumes 16 -* so return ipb freq / 2 +* The 5200 has only /32 prescalers. +* 5200B UARTs have a /4 or a /32 prescaler. For higher accuracy, we +* do all calculations using the /4 prescaler for this chip. +* The generic serial code assumes /16 so return ipb freq / 2 (5200) +* or ipb freq * 4 (5200B). */ - return mpc5xxx_get_bus_frequency(p) / 2; + if (is_mpc5200b == 1) + return mpc5xxx_get_bus_frequency(p) * 4; + else + return mpc5xxx_get_bus_frequency(p) / 2; } static struct psc_ops mpc52xx_psc_ops = { @@ -272,6 +302,7 @@ static struct psc_ops mpc52xx_psc_ops = .read_char = mpc52xx_psc_read_char, .cw_disable_ints = mpc52xx_psc_cw_disable_ints, .cw_restore_ints = mpc52xx_psc_cw_restore_ints, + .set_divisor = mpc52xx_psc_set_divisor, .getuartclk = mpc52xx_getuartclk, }; @@ -388,6 +419,16 @@ static void mpc512x_psc_cw_restore_ints( out_be32(&FIFO_512x(port)->rximr, port->read_status_mask & 0x7f); } +static void mpc512x_psc_set_divisor(struct uart_port *port, + unsigned int divisor) +{ + struct mpc52xx_psc __iomem *psc = PSC(port); + + divisor &= 0x; + out_8(&psc->ctur, divisor >> 8); + out_8(&psc->ctlr, divisor & 0xff); +} + static unsigned long mpc512x_getuartclk(void *p) { return mpc5xxx_get_bus_frequency(p); @@ -409,6 +450,7 @@ static struct psc_ops mpc512x_psc_ops = .read_char = mpc512x_psc_read_char, .cw_disable_ints = mpc512x_psc_cw_disable_ints, .cw_restore_ints = mpc512x_psc_cw_restore_ints, + .set_divisor = mpc512x_psc_set_divisor, .getuartclk = mpc512x_getuartclk, }; #endif @@ -564,7 +606,6 @@ mpc52xx_uart_set_termios(struct uart_por struct mpc52xx_psc __iomem *psc = PSC(port); unsigned long flags; unsigned char mr1, mr2; - unsigned short ctr; unsigned int j, baud, quot; /* Prepar
Re: [PATCH] powerpc: Set a smaller value for RECLAIM_DISTANCE to enable zone reclaim
On Mon, 1 Mar 2010, Mel Gorman wrote: > Christoph, how feasible would it be to allow parallel reclaimers in > __zone_reclaim() that back off at a rate depending on the number of > reclaimers? Not too hard. Zone locking is there but there may be a lot of bouncing cachelines if you run it concurrently. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/booke: Fix breakpoint/watchpoint one-shot behavior
Another fix for the extended ptrace patches in the -next tree. The handling of breakpoints and watchpoints is inconsistent. When a breakpoint or watchpoint is hit, the interrupt handler is clearing the proper bits in the dbcr* registers, but leaving the dac* and iac* registers alone. The ptrace code to delete the break/watchpoints checks the dac* and iac* registers for zero to determine if they are enabled. Instead, they should check the dbcr* bits. Signed-off-by: Dave Kleikamp --- arch/powerpc/kernel/ptrace.c | 12 ++-- 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 0efa2e3..ed2cfe1 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -940,7 +940,7 @@ static int del_instruction_bp(struct task_struct *child, int slot) { switch (slot) { case 1: - if (child->thread.iac1 == 0) + if ((child->thread.dbcr0 & DBCR0_IAC1) == 0) return -ENOENT; if (dbcr_iac_range(child) & DBCR_IAC12MODE) { @@ -952,7 +952,7 @@ static int del_instruction_bp(struct task_struct *child, int slot) child->thread.dbcr0 &= ~DBCR0_IAC1; break; case 2: - if (child->thread.iac2 == 0) + if ((child->thread.dbcr0 & DBCR0_IAC2) == 0) return -ENOENT; if (dbcr_iac_range(child) & DBCR_IAC12MODE) @@ -963,7 +963,7 @@ static int del_instruction_bp(struct task_struct *child, int slot) break; #if CONFIG_PPC_ADV_DEBUG_IACS > 2 case 3: - if (child->thread.iac3 == 0) + if ((child->thread.dbcr0 & DBCR0_IAC3) == 0) return -ENOENT; if (dbcr_iac_range(child) & DBCR_IAC34MODE) { @@ -975,7 +975,7 @@ static int del_instruction_bp(struct task_struct *child, int slot) child->thread.dbcr0 &= ~DBCR0_IAC3; break; case 4: - if (child->thread.iac4 == 0) + if ((child->thread.dbcr0 & DBCR0_IAC4) == 0) return -ENOENT; if (dbcr_iac_range(child) & DBCR_IAC34MODE) @@ -1054,7 +1054,7 @@ static int set_dac(struct task_struct *child, struct ppc_hw_breakpoint *bp_info) static int del_dac(struct task_struct *child, int slot) { if (slot == 1) { - if (child->thread.dac1 == 0) + if ((dbcr_dac(child) & (DBCR_DAC1R | DBCR_DAC1W)) == 0) return -ENOENT; child->thread.dac1 = 0; @@ -1070,7 +1070,7 @@ static int del_dac(struct task_struct *child, int slot) child->thread.dvc1 = 0; #endif } else if (slot == 2) { - if (child->thread.dac2 == 0) + if ((dbcr_dac(child) & (DBCR_DAC2R | DBCR_DAC2W)) == 0) return -ENOENT; #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC PATCH v2 8/9] USB: add HCD_NO_COHERENT_MEM host controller driver flag
On Sun, 28 Feb 2010, Albert Herranz wrote: > The HCD_NO_COHERENT_MEM USB host controller driver flag can be enabled > to instruct the USB stack to avoid allocating coherent memory for USB > buffers. > > This flag is useful to overcome some esoteric memory access restrictions > found in some platforms. > For example, the Nintendo Wii video game console is a NOT_COHERENT_CACHE > platform that is unable to safely perform non-32 bit uncached writes > to RAM because the byte enables are not connected to the bus. > Thus, in that platform, "coherent" DMA buffers cannot be directly used > by the kernel code unless it guarantees that all write accesses > to said buffers are done in 32 bit chunks (which is not the case in the > USB subsystem). > > To avoid this unwanted behaviour HCD_NO_COHERENT_MEM can be enabled at > the HCD controller, causing USB buffer allocations to be satisfied from > normal kernel memory. In this case, the USB stack will make sure that > the buffers get properly mapped/unmapped for DMA transfers using the DMA > streaming mapping API. > > Note that other parts of the USB stack may also use coherent memory, > like for example the hardware descriptors used in the EHCI controllers. > This needs to be checked and addressed separately. In the EHCI example, > hardware descriptors are accessed in 32-bit (or 64-bit) chunks, causing > no problems in the described scenario. > --- a/drivers/usb/core/hcd.c > +++ b/drivers/usb/core/hcd.c > @@ -1260,6 +1260,34 @@ static void hcd_free_coherent(struct usb_bus *bus, > dma_addr_t *dma_handle, > *dma_handle = 0; > } > > +static int urb_needs_setup_dma_map(struct usb_hcd *hcd, struct urb *urb) > +{ > + return !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP) || > +((hcd->driver->flags & HCD_NO_COHERENT_MEM) && > + urb->setup_dma == ~(dma_addr_t)0); > +} > + > +static int urb_needs_setup_dma_unmap(struct usb_hcd *hcd, struct urb *urb) > +{ > + return !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP) || > +((hcd->driver->flags & HCD_NO_COHERENT_MEM) && > + urb->setup_dma && urb->setup_dma != ~(dma_addr_t)0); > +} > + > +static int urb_needs_transfer_dma_map(struct usb_hcd *hcd, struct urb *urb) > +{ > + return !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) || > +((hcd->driver->flags & HCD_NO_COHERENT_MEM) && > + urb->transfer_dma == ~(dma_addr_t)0); > +} > + > +static int urb_needs_transfer_dma_unmap(struct usb_hcd *hcd, struct urb *urb) > +{ > + return !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) || > +((hcd->driver->flags & HCD_NO_COHERENT_MEM) && > + urb->transfer_dma && urb->transfer_dma != ~(dma_addr_t)0); > +} > + These functions would be a lot easier to understand if they were expanded into multiple test and return statements, rather than squeezing all the Boolean manipulations into single expressions. (Not to mention the fact that other developement is going to make them even more complicated than they are now...) Also, I can't help thinking that the corresponding *_map() and *_unmap() routines are so similar, it ought to be possible to combine them. The only difference is a check for a NULL DMA address, and it's not clear to me why it is present. It's also not clear why the test for a DMA address of all ones is present. Maybe they both can be removed. Alan Stern ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc: Renaming following split of GE Fanuc joint venture
This patch renames GE Fanuc boards following the split-up of the GE Fanuc joint venture. These boards are now made by GE Intelligent platorms. Signed-off-by: Martyn Welch --- arch/powerpc/boot/dts/gef_ppc9a.dts |4 ++-- arch/powerpc/boot/dts/gef_sbc310.dts |4 ++-- arch/powerpc/boot/dts/gef_sbc610.dts |4 ++-- arch/powerpc/platforms/86xx/Kconfig | 12 ++-- arch/powerpc/platforms/86xx/gef_gpio.c | 10 +- arch/powerpc/platforms/86xx/gef_pic.c|6 +++--- arch/powerpc/platforms/86xx/gef_ppc9a.c | 12 ++-- arch/powerpc/platforms/86xx/gef_sbc310.c | 12 ++-- arch/powerpc/platforms/86xx/gef_sbc610.c | 12 ++-- 9 files changed, 38 insertions(+), 38 deletions(-) diff --git a/arch/powerpc/boot/dts/gef_ppc9a.dts b/arch/powerpc/boot/dts/gef_ppc9a.dts index 977f260..83f4b79 100644 --- a/arch/powerpc/boot/dts/gef_ppc9a.dts +++ b/arch/powerpc/boot/dts/gef_ppc9a.dts @@ -1,7 +1,7 @@ /* - * GE Fanuc PPC9A Device Tree Source + * GE PPC9A Device Tree Source * - * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. + * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/powerpc/boot/dts/gef_sbc310.dts b/arch/powerpc/boot/dts/gef_sbc310.dts index 8e4efff..fc3a331 100644 --- a/arch/powerpc/boot/dts/gef_sbc310.dts +++ b/arch/powerpc/boot/dts/gef_sbc310.dts @@ -1,7 +1,7 @@ /* - * GE Fanuc SBC310 Device Tree Source + * GE SBC310 Device Tree Source * - * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. + * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/powerpc/boot/dts/gef_sbc610.dts b/arch/powerpc/boot/dts/gef_sbc610.dts index bb70600..c0671cc 100644 --- a/arch/powerpc/boot/dts/gef_sbc610.dts +++ b/arch/powerpc/boot/dts/gef_sbc610.dts @@ -1,7 +1,7 @@ /* - * GE Fanuc SBC610 Device Tree Source + * GE SBC610 Device Tree Source * - * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc. + * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig index 2bbfd53..fbe9f36 100644 --- a/arch/powerpc/platforms/86xx/Kconfig +++ b/arch/powerpc/platforms/86xx/Kconfig @@ -33,32 +33,32 @@ config MPC8610_HPCD This option enables support for the MPC8610 HPCD board. config GEF_PPC9A - bool "GE Fanuc PPC9A" + bool "GE PPC9A" select DEFAULT_UIMAGE select MMIO_NVRAM select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB help - This option enables support for GE Fanuc's PPC9A. + This option enables support for the GE PPC9A. config GEF_SBC310 - bool "GE Fanuc SBC310" + bool "GE SBC310" select DEFAULT_UIMAGE select MMIO_NVRAM select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB help - This option enables support for GE Fanuc's SBC310. + This option enables support for the GE SBC310. config GEF_SBC610 - bool "GE Fanuc SBC610" + bool "GE SBC610" select DEFAULT_UIMAGE select MMIO_NVRAM select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB select HAS_RAPIDIO help - This option enables support for GE Fanuc's SBC610. + This option enables support for the GE SBC610. endif diff --git a/arch/powerpc/platforms/86xx/gef_gpio.c b/arch/powerpc/platforms/86xx/gef_gpio.c index b2ea887..11f7b2b 100644 --- a/arch/powerpc/platforms/86xx/gef_gpio.c +++ b/arch/powerpc/platforms/86xx/gef_gpio.c @@ -1,9 +1,9 @@ /* - * Driver for GE Fanuc's FPGA based GPIO pins + * Driver for GE FPGA based GPIO * - * Author: Martyn Welch + * Author: Martyn Welch * - * 2008 (c) GE Fanuc Intelligent Platforms Embedded Systems, Inc. + * 2008 (c) GE Intelligent Platforms Embedded Systems, Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any @@ -164,6 +164,6 @@ static int __init gef_gpio_init(void) }; arch_initcall(gef_gpio_init); -MODULE_DESCRIPTION("GE Fanuc I/O FPGA GPIO driver"); -MODULE_AUTHOR("Martyn Welch + * Author: Martyn Welch * - * 2008 (c) GE Fanuc Intelligent Platforms Embedded Systems, Inc. + * 2008 (c) GE Intelligent Platforms Embedded Systems, Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as
Re: [PATCH v3 06/11] dma: Add MPC512x DMA driver
Hi Dan, any chance this patch could be merged for 2.6.34 ? Thanks, Anatolij On Fri, 5 Feb 2010 14:42:52 +0100 Anatolij Gustschin wrote: > From: Piotr Ziecik > > Adds initial version of MPC512x DMA driver. > Only memory to memory transfers are currenly supported. > > Signed-off-by: Piotr Ziecik > Signed-off-by: Wolfgang Denk > Signed-off-by: Anatolij Gustschin > Cc: Dan Williams > Cc: Grant Likely > Cc: John Rigby > --- > No changes since v2 > > Changes since v1: > - move content of the mpc512x.h into the drivers .c file as >it is only used by this DMA driver > - use __devinit/__devexit/__devexit_p as requested > - add unregistration of the dma device > - remove meaningless comment > > Changes since patch version submitted in May 2009: > - don't use wildcards in compatible property, use "fsl,mpc5121-dma" > - don't add "fsl,mpc5121-dma" compatible to of_bus_ids[] as the >dma device is part of IMMR > > drivers/dma/Kconfig |7 + > drivers/dma/Makefile |1 + > drivers/dma/mpc512x_dma.c | 800 > + > 3 files changed, 808 insertions(+), 0 deletions(-) > create mode 100644 drivers/dma/mpc512x_dma.c ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: Gianfar driver failing on MPC8641D based board
Anton Vorontsov wrote: > diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c > index 8bd3c9f..cccb409 100644 > --- a/drivers/net/gianfar.c > +++ b/drivers/net/gianfar.c > @@ -2021,7 +2021,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct > net_device *dev) > } > > /* setup the TxBD length and buffer pointer for the first BD */ > - tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb; > txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data, > skb_headlen(skb), DMA_TO_DEVICE); > > @@ -2053,6 +2052,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct > net_device *dev) > > txbdp_start->lstatus = lstatus; > > + eieio(); /* force lstatus write before tx_skbuff */ > + > + tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb; > + > /* Update the current skb pointer to the next entry we will use >* (wrapping if necessary) */ > tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) & > I can confirm 10/10 successful boots on p2020ds and mpc8641_hpcn. Martyn -- Martyn Welch (Principal Software Engineer) | Registered in England and GE Intelligent Platforms | Wales (3828642) at 100 T +44(0)127322748| Barbirolli Square, Manchester, E martyn.we...@ge.com| M2 3AB VAT:GB 927559189 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 3/3] powerpc: reduce printk from pseries_mach_cpu_die()
Remove debug printks in pseries_mach_cpu_die(). These are noisy at runtime. Traceevents can be added to instrument this section of code. The following KERN_INFO printks are removed: cpu 62 (hwid 62) returned from cede. Decrementer value = b2802fff Timebase value = 2fa8f95035f4a cpu 62 (hwid 62) got prodded to go online cpu 58 (hwid 58) ceding for offline with hint 2 Signed-off-by: Vaidyanathan Srinivasan Cc: Gautham R Shenoy --- arch/powerpc/platforms/pseries/hotplug-cpu.c | 11 --- 1 files changed, 0 insertions(+), 11 deletions(-) diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 39ecb40..b842378 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -122,21 +122,10 @@ static void pseries_mach_cpu_die(void) if (!get_lppaca()->shared_proc) get_lppaca()->donate_dedicated_cpu = 1; - printk(KERN_INFO - "cpu %u (hwid %u) ceding for offline with hint %d\n", - cpu, hwcpu, cede_latency_hint); while (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) { extended_cede_processor(cede_latency_hint); - printk(KERN_INFO "cpu %u (hwid %u) returned from cede.\n", - cpu, hwcpu); - printk(KERN_INFO - "Decrementer value = %x Timebase value = %llx\n", - get_dec(), get_tb()); } - printk(KERN_INFO "cpu %u (hwid %u) got prodded to go online\n", - cpu, hwcpu); - if (!get_lppaca()->shared_proc) get_lppaca()->donate_dedicated_cpu = 0; get_lppaca()->idle = 0; ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 2/3] powerpc: move checks in pseries_mach_cpu_die()
Rearrange condition checks for better code readability and prevention of possible race conditions when preferred_offline_state can potentially change during the execution of pseries_mach_cpu_die(). The patch will make pseries_mach_cpu_die() put cpu in one of the consistent states and not hit the run over BUG() Signed-off-by: Vaidyanathan Srinivasan Cc: Gautham R Shenoy --- arch/powerpc/platforms/pseries/hotplug-cpu.c | 30 +- 1 files changed, 15 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 9be7af4..39ecb40 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -140,25 +140,25 @@ static void pseries_mach_cpu_die(void) if (!get_lppaca()->shared_proc) get_lppaca()->donate_dedicated_cpu = 0; get_lppaca()->idle = 0; - } - if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) { - unregister_slb_shadow(hwcpu, __pa(get_slb_shadow())); + if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) { + unregister_slb_shadow(hwcpu, __pa(get_slb_shadow())); - /* -* Call to start_secondary_resume() will not return. -* Kernel stack will be reset and start_secondary() -* will be called to continue the online operation. -*/ - start_secondary_resume(); + /* +* Call to start_secondary_resume() will not return. +* Kernel stack will be reset and start_secondary() +* will be called to continue the online operation. +*/ + start_secondary_resume(); + } + } - } else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) { + /* Requested state is CPU_STATE_OFFLINE at this point */ + WARN_ON(get_preferred_offline_state(cpu) != CPU_STATE_OFFLINE); - set_cpu_current_state(cpu, CPU_STATE_OFFLINE); - unregister_slb_shadow(hard_smp_processor_id(), - __pa(get_slb_shadow())); - rtas_stop_self(); - } + set_cpu_current_state(cpu, CPU_STATE_OFFLINE); + unregister_slb_shadow(hwcpu, __pa(get_slb_shadow())); + rtas_stop_self(); /* Should never get here... */ BUG(); ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 1/3] powerpc: reset kernel stack on cpu online from cede state
Cpu hotplug (offline) without dlpar operation will place cpu in cede state and the extended_cede_processor() function will return when resumed. Kernel stack pointer needs to be reset before start_secondary() is called to continue the online operation. Added new function start_secondary_resume() to do the above steps. Signed-off-by: Vaidyanathan Srinivasan Cc: Gautham R Shenoy --- arch/powerpc/kernel/head_64.S | 11 +++ arch/powerpc/platforms/pseries/hotplug-cpu.c|9 - arch/powerpc/platforms/pseries/offline_states.h |2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 9258074..567cd57 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -615,6 +615,17 @@ _GLOBAL(start_secondary_prolog) std r3,0(r1)/* Zero the stack frame pointer */ bl .start_secondary b . +/* + * Reset stack pointer and call start_secondary + * to continue with online operation when woken up + * from cede in cpu offline. + */ +_GLOBAL(start_secondary_resume) + ld r1,PACAKSAVE(r13) /* Reload kernel stack pointer */ + li r3,0 + std r3,0(r1)/* Zero the stack frame pointer */ + bl .start_secondary + b . #endif /* diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 6ea4698..9be7af4 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -146,12 +146,11 @@ static void pseries_mach_cpu_die(void) unregister_slb_shadow(hwcpu, __pa(get_slb_shadow())); /* -* NOTE: Calling start_secondary() here for now to -* start new context. -* However, need to do it cleanly by resetting the -* stack pointer. +* Call to start_secondary_resume() will not return. +* Kernel stack will be reset and start_secondary() +* will be called to continue the online operation. */ - start_secondary(); + start_secondary_resume(); } else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) { diff --git a/arch/powerpc/platforms/pseries/offline_states.h b/arch/powerpc/platforms/pseries/offline_states.h index 22574e0..da07256 100644 --- a/arch/powerpc/platforms/pseries/offline_states.h +++ b/arch/powerpc/platforms/pseries/offline_states.h @@ -14,5 +14,5 @@ extern void set_cpu_current_state(int cpu, enum cpu_state_vals state); extern enum cpu_state_vals get_preferred_offline_state(int cpu); extern void set_preferred_offline_state(int cpu, enum cpu_state_vals state); extern void set_default_offline_state(int cpu); -extern int start_secondary(void); +extern void start_secondary_resume(void); #endif ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 0/3] powerpc: bug fixes in pseries_mach_cpu_die()
Hi Ben, The following set of patches fixes kernel stack reset issue and also potential race conditions. This fix should be applied in 2.6.33 stable tree onwards. Problem description: (1) Repeated offline/online operation on pseries with extended cede processor feature will run over the kernel stack and crash since the stack was not reset on resume from cede processor. (2) The 'if' conditions and code has been slightly rearranged to avoid any possible race conditions where preferred_offline_state can change while the cpu is still executing the condition checks in pseries_mach_cpu_die(). The new code has the CPU_STATE_OFFLINE as default and also improved readability. Thanks to Anton Blanchard for pointing this out. (3) There were too many noisy KERN_INFO printks on offline/online operation. Removed the printk's for now. Other debug methods or traceevents can be introduced at a later point. The patch has been tested on large POWER machine with both cede_offline=off case and the default cede_offline=on case. Please apply in powerpc.git tree and push upstream. Previous version of the patch can be found at: [PATCH] powerpc: reset kernel stack on cpu online from cede state http://lists.ozlabs.org/pipermail/linuxppc-dev/2010-February/080515.html Thanks, Vaidy --- Vaidyanathan Srinivasan (3): powerpc: reset kernel stack on cpu online from cede state powerpc: move checks in pseries_mach_cpu_die() powerpc: reduce printk from pseries_mach_cpu_die() arch/powerpc/kernel/head_64.S | 11 ++ arch/powerpc/platforms/pseries/hotplug-cpu.c| 42 --- arch/powerpc/platforms/pseries/offline_states.h |2 + 3 files changed, 27 insertions(+), 28 deletions(-) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc: Set a smaller value for RECLAIM_DISTANCE to enable zone reclaim
On Tue, Feb 23, 2010 at 12:55:51PM +1100, Anton Blanchard wrote: > > Hi Mel, > I'm back but a bit vague. Am on painkillers for the bashing I gave myself down the hills. > > You're pretty much on the button here. Only one thread at a time enters > > zone_reclaim. The others back off and try the next zone in the zonelist > > instead. I'm not sure what the original intention was but most likely it > > was to prevent too many parallel reclaimers in the same zone potentially > > dumping out way more data than necessary. > > > > > I'm not sure if there is an easy way to fix this without penalising other > > > workloads though. > > > > > > > You could experiment with waiting on the bit if the GFP flags allowi it? The > > expectation would be that the reclaim operation does not take long. Wait > > on the bit, if you are making the forward progress, recheck the > > watermarks before continueing. > > Thanks to you and Christoph for some suggestions to try. Attached is a > chart showing the results of the following tests: > > > baseline.txt > The current ppc64 default of zone_reclaim_mode = 0. As expected we see > no change in remote node memory usage even after 10 iterations. > > zone_reclaim_mode.txt > Now we set zone_reclaim_mode = 1. On each iteration we continue to improve, > but even after 10 runs of stream we have > 10% remote node memory usage. > Ok, so how reasonable would it be to expect that the rate of "improvement" to be related to the ratio between "available free node memory at start - how many pages the benchmark requires" and the number of pages zone_reclaim reclaims on the local node? The exact rate of improvement is complicated by multiple threads so it won't be exact. > reclaim_4096_pages.txt > Instead of reclaiming 32 pages at a time, we try for a much larger batch > of 4096. The slope is much steeper but it still takes around 6 iterations > to get almost all local node memory. > > wait_on_busy_flag.txt > Here we busy wait if the ZONE_RECLAIM_LOCKED flag is set. As you suggest > we would need to check the GFP flags etc, but so far it looks the most > promising. We only get a few percent of remote node memory on the first > iteration and get all local node by the second. > If the above expectation is reasonable, a better alternative may be to adapt the number of pages reclaimed to the number of callers to __zone_reclaim() and allow parallel reclaimers. e.g. 1 thread 128 2 threads 64 3 threads 32 4 threads 16 etc The exact starting batch count needs more careful thinking than what I'm giving it currently and maybe the decay ratio too to work out what the worst-case scenario for dumping node-local memory is but you get the idea. The downside is that this requires a per-zone counter to count the number of parallel reclaimers. > > Perhaps a combination of larger batch size and waiting on the busy > flag is the way to go? > I think a static increase on the batch size runs three risks. The first of parallel reclaimers dumping too much of local memory although it could be mitigated by checking the watermarks after waiting on the bit lock. The second is that the thread doing the reclaiming is penalised with higher reclaim costs while other CPUs remain idle. The third is that there could be latency snags with a thread spinning that would previously have gone off-node. Not sure what the impact of the third risk but it might be noticeable on latency-sensitive machines where the off-node cost is not significant enough to justify a delay. Christoph, how feasible would it be to allow parallel reclaimers in __zone_reclaim() that back off at a rate depending on the number of reclaimers? > --- mm/vmscan.c~ 2010-02-21 23:47:14.0 -0600 > +++ mm/vmscan.c 2010-02-22 03:22:01.0 -0600 > @@ -2534,7 +2534,7 @@ > .may_unmap = !!(zone_reclaim_mode & RECLAIM_SWAP), > .may_swap = 1, > .nr_to_reclaim = max_t(unsigned long, nr_pages, > -SWAP_CLUSTER_MAX), > +4096), > .gfp_mask = gfp_mask, > .swappiness = vm_swappiness, > .order = order, > --- mm/vmscan.c~ 2010-02-21 23:47:14.0 -0600 > +++ mm/vmscan.c 2010-02-21 23:47:31.0 -0600 > @@ -2634,8 +2634,8 @@ > if (node_state(node_id, N_CPU) && node_id != numa_node_id()) > return ZONE_RECLAIM_NOSCAN; > > - if (zone_test_and_set_flag(zone, ZONE_RECLAIM_LOCKED)) > - return ZONE_RECLAIM_NOSCAN; > + while (zone_test_and_set_flag(zone, ZONE_RECLAIM_LOCKED)) > + cpu_relax(); > > ret = __zone_reclaim(zone, gfp_mask, order); > zone_clear_flag(zone, ZONE_RECLAIM_LOCKED); -- Mel Gorman Part-time Phd Student Linux Technology Center University of Limerick IBM Dublin Software Lab _