From 40847993d881050cbfa7184db33603165ba84fa1 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 15 Oct 2008 11:09:59 -0600 Subject: [PATCH 01/53] powerpc/52xx: Make cuImage more robust in locating immr node. Current device trees do not have the device_type = soc property set anymore. Fix up the cuImage bootwrapper fragment to still find the IMMR nodes. Signed-off-by: Grant Likely --- arch/powerpc/boot/cuboot-52xx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/powerpc/boot/cuboot-52xx.c b/arch/powerpc/boot/cuboot-52xx.c index a8611546a656..4c42ec8687be 100644 --- a/arch/powerpc/boot/cuboot-52xx.c +++ b/arch/powerpc/boot/cuboot-52xx.c @@ -37,6 +37,10 @@ static void platform_fixups(void) * this can do a simple path lookup. */ soc = find_node_by_devtype(NULL, "soc"); + if (!soc) + soc = find_node_by_compatible(NULL, "fsl,mpc5200-immr"); + if (!soc) + soc = find_node_by_compatible(NULL, "fsl,mpc5200b-immr"); if (soc) { setprop(soc, "bus-frequency", &bd.bi_ipbfreq, sizeof(bd.bi_ipbfreq)); From 9629095761b64636356c132f0228ed780ebb97e8 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 15 Oct 2008 11:09:59 -0600 Subject: [PATCH 02/53] powerpc/mpc5200: Don't touch pipelining for MPC5200B MPC5200 needs to have pipelining disabled for ATA to work. MPC5200B does not. So, for the latter, don't touch the original setting from the bootloader. Signed-off-by: Wolfram Sang Signed-off-by: Grant Likely --- arch/powerpc/platforms/52xx/mpc52xx_common.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c index 044b4e6e8743..ae7c34f37e1c 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_common.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c @@ -99,11 +99,14 @@ mpc5200_setup_xlb_arbiter(void) out_be32(&xlb->master_pri_enable, 0xff); out_be32(&xlb->master_priority, 0x11111111); - /* Disable XLB pipelining + /* + * Disable XLB pipelining * (cfr errate 292. We could do this only just before ATA PIO * transaction and re-enable it afterwards ...) + * Not needed on MPC5200B. */ - out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS); + if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR) + out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS); iounmap(xlb); } From 51d9861e9e09c5c0066e5e5d9bb0009be1957899 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 15 Oct 2008 11:10:00 -0600 Subject: [PATCH 03/53] powerpc/mpc5200: Refactor FEC mdio read/write routines Read & write functions now call a generic transfer function, so identical code in both routines could be eliminated. The result is easier to maintain and smaller in source and binary code. Also, fix some checkpatch warnings. Signed-off-by: Wolfram Sang Signed-off-by: Grant Likely --- drivers/net/fec_mpc52xx_phy.c | 57 ++++++++++++++--------------------- 1 file changed, 23 insertions(+), 34 deletions(-) diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c index 08e18bcb970f..45dd9bdc5d62 100644 --- a/drivers/net/fec_mpc52xx_phy.c +++ b/drivers/net/fec_mpc52xx_phy.c @@ -2,6 +2,7 @@ * Driver for the MPC5200 Fast Ethernet Controller - MDIO bus driver * * Copyright (C) 2007 Domen Puncer, Telargo, Inc. + * Copyright (C) 2008 Wolfram Sang, Pengutronix * * 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 @@ -21,58 +22,45 @@ struct mpc52xx_fec_mdio_priv { struct mpc52xx_fec __iomem *regs; }; -static int mpc52xx_fec_mdio_read(struct mii_bus *bus, int phy_id, int reg) +static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id, + int reg, u32 value) { struct mpc52xx_fec_mdio_priv *priv = bus->priv; struct mpc52xx_fec __iomem *fec; int tries = 100; - u32 request = FEC_MII_READ_FRAME; + + value |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK; + value |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK; fec = priv->regs; out_be32(&fec->ievent, FEC_IEVENT_MII); - - request |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK; - request |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK; - - out_be32(&priv->regs->mii_data, request); + out_be32(&priv->regs->mii_data, value); /* wait for it to finish, this takes about 23 us on lite5200b */ while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries) udelay(5); - if (tries == 0) + if (!tries) return -ETIMEDOUT; - return in_be32(&priv->regs->mii_data) & FEC_MII_DATA_DATAMSK; + return value & FEC_MII_DATA_OP_RD ? + in_be32(&priv->regs->mii_data) & FEC_MII_DATA_DATAMSK : 0; } -static int mpc52xx_fec_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 data) +static int mpc52xx_fec_mdio_read(struct mii_bus *bus, int phy_id, int reg) { - struct mpc52xx_fec_mdio_priv *priv = bus->priv; - struct mpc52xx_fec __iomem *fec; - u32 value = data; - int tries = 100; - - fec = priv->regs; - out_be32(&fec->ievent, FEC_IEVENT_MII); - - value |= FEC_MII_WRITE_FRAME; - value |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK; - value |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK; - - out_be32(&priv->regs->mii_data, value); - - /* wait for request to finish */ - while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries) - udelay(5); - - if (tries == 0) - return -ETIMEDOUT; - - return 0; + return mpc52xx_fec_mdio_transfer(bus, phy_id, reg, FEC_MII_READ_FRAME); } -static int mpc52xx_fec_mdio_probe(struct of_device *of, const struct of_device_id *match) +static int mpc52xx_fec_mdio_write(struct mii_bus *bus, int phy_id, int reg, + u16 data) +{ + return mpc52xx_fec_mdio_transfer(bus, phy_id, reg, + data | FEC_MII_WRITE_FRAME); +} + +static int mpc52xx_fec_mdio_probe(struct of_device *of, + const struct of_device_id *match) { struct device *dev = &of->dev; struct device_node *np = of->node; @@ -131,7 +119,8 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of, const struct of_device_i dev_set_drvdata(dev, bus); /* set MII speed */ - out_be32(&priv->regs->mii_speed, ((mpc52xx_find_ipb_freq(of->node) >> 20) / 5) << 1); + out_be32(&priv->regs->mii_speed, + ((mpc52xx_find_ipb_freq(of->node) >> 20) / 5) << 1); /* enable MII interrupt */ out_be32(&priv->regs->imask, in_be32(&priv->regs->imask) | FEC_IMASK_MII); From 00f3ca740a9c2692a58e629d92a1c8666e394c26 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Wed, 3 Sep 2008 20:47:25 -0400 Subject: [PATCH 04/53] powerpc/40x: AMCC PowerPC 405EZ Acadia DTS Add the base DTS for the AMCC PowerPC 405EZ Acadia evalution board. In addition to some of the normal PPC 40x peripherals, the Acadia board has: - 64 MiB PSRAM - NOR and NAND flash - Two USB 1.1 host ports - Two CAN 2.0 ports - ADC and DAC connectors - LCD display This adds the basic platform support to build from. Signed-off-by: Josh Boyer --- arch/powerpc/boot/dts/acadia.dts | 224 +++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 arch/powerpc/boot/dts/acadia.dts diff --git a/arch/powerpc/boot/dts/acadia.dts b/arch/powerpc/boot/dts/acadia.dts new file mode 100644 index 000000000000..57291f61ffe7 --- /dev/null +++ b/arch/powerpc/boot/dts/acadia.dts @@ -0,0 +1,224 @@ +/* + * Device Tree Source for AMCC Acadia (405EZ) + * + * Copyright IBM Corp. 2008 + * + * 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/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "amcc,acadia"; + compatible = "amcc,acadia"; + dcr-parent = <&{/cpus/cpu@0}>; + + aliases { + ethernet0 = &EMAC0; + serial0 = &UART0; + serial1 = &UART1; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + model = "PowerPC,405EZ"; + reg = <0x0>; + clock-frequency = <0>; /* Filled in by wrapper */ + timebase-frequency = <0>; /* Filled in by wrapper */ + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <16384>; + d-cache-size = <16384>; + dcr-controller; + dcr-access-method = "native"; + }; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x0>; /* Filled in by wrapper */ + }; + + UIC0: interrupt-controller { + compatible = "ibm,uic-405ez", "ibm,uic"; + interrupt-controller; + dcr-reg = <0x0c0 0x009>; + cell-index = <0>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + }; + + plb { + compatible = "ibm,plb-405ez", "ibm,plb3"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + clock-frequency = <0>; /* Filled in by wrapper */ + + MAL0: mcmal { + compatible = "ibm,mcmal-405ez", "ibm,mcmal"; + dcr-reg = <0x380 0x62>; + num-tx-chans = <1>; + num-rx-chans = <1>; + interrupt-parent = <&UIC0>; + /* 405EZ has only 3 interrupts to the UIC, as + * SERR, TXDE, and RXDE are or'd together into + * one UIC bit + */ + interrupts = < + 0x13 0x4 /* TXEOB */ + 0x15 0x4 /* RXEOB */ + 0x12 0x4 /* SERR, TXDE, RXDE */>; + }; + + POB0: opb { + compatible = "ibm,opb-405ez", "ibm,opb"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + dcr-reg = <0x0a 0x05>; + clock-frequency = <0>; /* Filled in by wrapper */ + + UART0: serial@ef600300 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0xef600300 0x8>; + virtual-reg = <0xef600300>; + clock-frequency = <0>; /* Filled in by wrapper */ + current-speed = <115200>; + interrupt-parent = <&UIC0>; + interrupts = <0x5 0x4>; + }; + + UART1: serial@ef600400 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0xef600400 0x8>; + clock-frequency = <0>; /* Filled in by wrapper */ + current-speed = <115200>; + interrupt-parent = <&UIC0>; + interrupts = <0x6 0x4>; + }; + + IIC: i2c@ef600500 { + compatible = "ibm,iic-405ez", "ibm,iic"; + reg = <0xef600500 0x11>; + interrupt-parent = <&UIC0>; + interrupts = <0xa 0x4>; + }; + + GPIO0: gpio@ef600700 { + compatible = "ibm,gpio-405ez"; + reg = <0xef600700 0x20>; + }; + + GPIO1: gpio@ef600800 { + compatible = "ibm,gpio-405ez"; + reg = <0xef600800 0x20>; + }; + + EMAC0: ethernet@ef600900 { + device_type = "network"; + compatible = "ibm,emac-405ez", "ibm,emac"; + interrupt-parent = <&UIC0>; + interrupts = < + 0x10 0x4 /* Ethernet */ + 0x11 0x4 /* Ethernet Wake up */>; + local-mac-address = [000000000000]; /* Filled in by wrapper */ + reg = <0xef600900 0x70>; + mal-device = <&MAL0>; + mal-tx-channel = <0>; + mal-rx-channel = <0>; + cell-index = <0>; + max-frame-size = <1500>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; + phy-mode = "mii"; + phy-map = <0x0>; + }; + + CAN0: can@ef601000 { + compatible = "amcc,can-405ez"; + reg = <0xef601000 0x620>; + interrupt-parent = <&UIC0>; + interrupts = <0x7 0x4>; + }; + + CAN1: can@ef601800 { + compatible = "amcc,can-405ez"; + reg = <0xef601800 0x620>; + interrupt-parent = <&UIC0>; + interrupts = <0x8 0x4>; + }; + + cameleon@ef602000 { + compatible = "amcc,cameleon-405ez"; + reg = <0xef602000 0x800>; + interrupt-parent = <&UIC0>; + interrupts = <0xb 0x4 0xc 0x4>; + }; + + ieee1588@ef602800 { + compatible = "amcc,ieee1588-405ez"; + reg = <0xef602800 0x60>; + interrupt-parent = <&UIC0>; + interrupts = <0x4 0x4>; + /* This thing is a bit weird. It has it's own UIC + * that it uses to generate snapshot triggers. We + * don't really support this device yet, and it needs + * work to figure this out. + */ + dcr-reg = <0xe0 0x9>; + }; + + usb@ef603000 { + compatible = "ohci-be"; + reg = <0xef603000 0x80>; + interrupts-parent = <&UIC0>; + interrupts = <0xd 0x4 0xe 0x4>; + }; + + dac@ef603300 { + compatible = "amcc,dac-405ez"; + reg = <0xef603300 0x40>; + interrupt-parent = <&UIC0>; + interrupts = <0x18 0x4>; + }; + + adc@ef603400 { + compatible = "amcc,adc-405ez"; + reg = <0xef603400 0x40>; + interrupt-parent = <&UIC0>; + interrupts = <0x17 0x4>; + }; + + spi@ef603500 { + compatible = "amcc,spi-405ez"; + reg = <0xef603500 0x100>; + interrupt-parent = <&UIC0>; + interrupts = <0x9 0x4>; + }; + }; + + EBC0: ebc { + compatible = "ibm,ebc-405ez", "ibm,ebc"; + dcr-reg = <0x12 0x2>; + #address-cells = <2>; + #size-cells = <1>; + clock-frequency = <0>; /* Filled in by wrapper */ + }; + }; + + chosen { + linux,stdout-path = "/plb/opb/serial@ef600300"; + }; +}; From df8f71faa8e9b8b8df8b22b57889630fece25696 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Thu, 9 Oct 2008 08:56:38 -0400 Subject: [PATCH 05/53] powerpc/40x: Add AMCC PowerPC 405EZ to cputable This adds the AMCC PowerPC 405EZ chip to the cputable Signed-off-by: Josh Boyer --- arch/powerpc/kernel/cputable.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index e70d0483fb4e..b1eb834bc0fc 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -1277,6 +1277,19 @@ static struct cpu_spec __initdata cpu_specs[] = { .machine_check = machine_check_4xx, .platform = "ppc405", }, + { + /* 405EZ */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x41510000, + .cpu_name = "405EZ", + .cpu_features = CPU_FTRS_40X, + .cpu_user_features = PPC_FEATURE_32 | + PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, + .icache_bsize = 32, + .dcache_bsize = 32, + .machine_check = machine_check_4xx, + .platform = "ppc405", + }, { /* default match */ .pvr_mask = 0x00000000, .pvr_value = 0x00000000, From 8105fa88593c87f8aba0e7e829d7dc0ee94fe2cf Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Wed, 3 Sep 2008 20:58:22 -0400 Subject: [PATCH 06/53] powerpc/40x: Add PowerPC 40x simple platform support This adds a common board file for almost all of the "simple" PowerPC 40x boards that exist today. This is intended to be a single place to add support for boards that do not differ in platform support from most of the evaluation boards that are used as reference platforms. Boards that have specific requirements or custom hardware setup should still have their own board.c file. The first board ported to this is the AMCC PowerPC 405EZ Acadia board. Signed-off-by: Josh Boyer --- arch/powerpc/platforms/40x/Kconfig | 22 ++++++ arch/powerpc/platforms/40x/Makefile | 1 + arch/powerpc/platforms/40x/ppc40x_simple.c | 80 ++++++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 arch/powerpc/platforms/40x/ppc40x_simple.c diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig index a9260e21451e..72ba3a7289fe 100644 --- a/arch/powerpc/platforms/40x/Kconfig +++ b/arch/powerpc/platforms/40x/Kconfig @@ -14,6 +14,15 @@ # help # This option enables support for the CPCI405 board. +config ACADIA + bool "Acadia" + depends on 40x + default n + select PPC40x_SIMPLE + select 405EZ + help + This option enables support for the AMCC 405EZ Acadia evaluation board. + config EP405 bool "EP405/EP405PC" depends on 40x @@ -93,6 +102,13 @@ config XILINX_VIRTEX_GENERIC_BOARD Most Virtex designs should use this unless it needs to do some special configuration at board probe time. +config PPC40x_SIMPLE + bool "Simple PowerPC 40x board support" + depends on 40x + default n + help + This option enables the simple PowerPC 40x platform support. + # 40x specific CPU modules, selected based on the board above. config NP405H bool @@ -118,6 +134,12 @@ config 405EX select IBM_NEW_EMAC_EMAC4 select IBM_NEW_EMAC_RGMII +config 405EZ + bool + select IBM_NEW_EMAC_NO_FLOW_CTRL + select IBM_NEW_EMAC_MAL_CLR_ICINTSTAT + select IBM_NEW_EMAC_MAL_COMMON_ERR + config 405GPR bool diff --git a/arch/powerpc/platforms/40x/Makefile b/arch/powerpc/platforms/40x/Makefile index 5533a5c8ce4e..1d93273a1db1 100644 --- a/arch/powerpc/platforms/40x/Makefile +++ b/arch/powerpc/platforms/40x/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_MAKALU) += makalu.o obj-$(CONFIG_WALNUT) += walnut.o obj-$(CONFIG_XILINX_VIRTEX_GENERIC_BOARD) += virtex.o obj-$(CONFIG_EP405) += ep405.o +obj-$(CONFIG_PPC40x_SIMPLE) += ppc40x_simple.o diff --git a/arch/powerpc/platforms/40x/ppc40x_simple.c b/arch/powerpc/platforms/40x/ppc40x_simple.c new file mode 100644 index 000000000000..4498a86b46c3 --- /dev/null +++ b/arch/powerpc/platforms/40x/ppc40x_simple.c @@ -0,0 +1,80 @@ +/* + * Generic PowerPC 40x platform support + * + * Copyright 2008 IBM Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; version 2 of the License. + * + * This implements simple platform support for PowerPC 44x chips. This is + * mostly used for eval boards or other simple and "generic" 44x boards. If + * your board has custom functions or hardware, then you will likely want to + * implement your own board.c file to accommodate it. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static __initdata struct of_device_id ppc40x_of_bus[] = { + { .compatible = "ibm,plb3", }, + { .compatible = "ibm,plb4", }, + { .compatible = "ibm,opb", }, + { .compatible = "ibm,ebc", }, + { .compatible = "simple-bus", }, + {}, +}; + +static int __init ppc40x_device_probe(void) +{ + of_platform_bus_probe(NULL, ppc40x_of_bus, NULL); + + return 0; +} +machine_device_initcall(ppc40x_simple, ppc40x_device_probe); + +/* This is the list of boards that can be supported by this simple + * platform code. This does _not_ mean the boards are compatible, + * as they most certainly are not from a device tree perspective. + * However, their differences are handled by the device tree and the + * drivers and therefore they don't need custom board support files. + * + * Again, if your board needs to do things differently then create a + * board.c file for it rather than adding it to this list. + */ +static char *board[] __initdata = { + "amcc,acadia" +}; + +static int __init ppc40x_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + int i = 0; + + for (i = 0; i < ARRAY_SIZE(board); i++) { + if (of_flat_dt_is_compatible(root, board[i])) { + ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; + return 1; + } + } + + return 0; +} + +define_machine(ppc40x_simple) { + .name = "PowerPC 40x Platform", + .probe = ppc40x_probe, + .progress = udbg_progress, + .init_IRQ = uic_init_tree, + .get_irq = uic_get_irq, + .restart = ppc4xx_reset_system, + .calibrate_decr = generic_calibrate_decr, +}; From 94c73a8f97907116e294aa27a58151cc4500e6fa Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Wed, 3 Sep 2008 21:01:39 -0400 Subject: [PATCH 07/53] powerpc/40x: Add cuboot wrapper for Acadia board This adds a cuboot wrapper for the AMCC PowerPC 405EZ Acadia board. The clocking code is derived from U-Boot, originally written by Stefan Roese. Signed-off-by: Josh Boyer --- arch/powerpc/boot/Makefile | 4 +- arch/powerpc/boot/cuboot-acadia.c | 174 ++++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/boot/cuboot-acadia.c diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index aac1406ccba5..47603652e7f1 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -68,7 +68,8 @@ src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c fixed-head.S ep88xc.c ep405.c cuboot-c2k.c \ cuboot-katmai.c cuboot-rainier.c redboot-8xx.c ep8248e.c \ cuboot-warp.c cuboot-85xx-cpm2.c cuboot-yosemite.c simpleboot.c \ - virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c + virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c \ + cuboot-acadia.c src-boot := $(src-wlib) $(src-plat) empty.c src-boot := $(addprefix $(obj)/, $(src-boot)) @@ -211,6 +212,7 @@ image-$(CONFIG_DEFAULT_UIMAGE) += uImage # Board ports in arch/powerpc/platform/40x/Kconfig image-$(CONFIG_EP405) += dtbImage.ep405 image-$(CONFIG_WALNUT) += treeImage.walnut +image-$(CONFIG_ACADIA) += cuImage.acadia # Board ports in arch/powerpc/platform/44x/Kconfig image-$(CONFIG_EBONY) += treeImage.ebony cuImage.ebony diff --git a/arch/powerpc/boot/cuboot-acadia.c b/arch/powerpc/boot/cuboot-acadia.c new file mode 100644 index 000000000000..0634aba6348a --- /dev/null +++ b/arch/powerpc/boot/cuboot-acadia.c @@ -0,0 +1,174 @@ +/* + * Old U-boot compatibility for Acadia + * + * Author: Josh Boyer + * + * Copyright 2008 IBM Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include "ops.h" +#include "io.h" +#include "dcr.h" +#include "stdio.h" +#include "4xx.h" +#include "44x.h" +#include "cuboot.h" + +#define TARGET_4xx +#include "ppcboot.h" + +static bd_t bd; + +#define CPR_PERD0_SPIDV_MASK 0x000F0000 /* SPI Clock Divider */ + +#define PLLC_SRC_MASK 0x20000000 /* PLL feedback source */ + +#define PLLD_FBDV_MASK 0x1F000000 /* PLL feedback divider value */ +#define PLLD_FWDVA_MASK 0x000F0000 /* PLL forward divider A value */ +#define PLLD_FWDVB_MASK 0x00000700 /* PLL forward divider B value */ + +#define PRIMAD_CPUDV_MASK 0x0F000000 /* CPU Clock Divisor Mask */ +#define PRIMAD_PLBDV_MASK 0x000F0000 /* PLB Clock Divisor Mask */ +#define PRIMAD_OPBDV_MASK 0x00000F00 /* OPB Clock Divisor Mask */ +#define PRIMAD_EBCDV_MASK 0x0000000F /* EBC Clock Divisor Mask */ + +#define PERD0_PWMDV_MASK 0xFF000000 /* PWM Divider Mask */ +#define PERD0_SPIDV_MASK 0x000F0000 /* SPI Divider Mask */ +#define PERD0_U0DV_MASK 0x0000FF00 /* UART 0 Divider Mask */ +#define PERD0_U1DV_MASK 0x000000FF /* UART 1 Divider Mask */ + +static void get_clocks(void) +{ + unsigned long sysclk, cpr_plld, cpr_pllc, cpr_primad, plloutb, i; + unsigned long pllFwdDiv, pllFwdDivB, pllFbkDiv, pllPlbDiv, pllExtBusDiv; + unsigned long pllOpbDiv, freqEBC, freqUART, freqOPB; + unsigned long div; /* total divisor udiv * bdiv */ + unsigned long umin; /* minimum udiv */ + unsigned short diff; /* smallest diff */ + unsigned long udiv; /* best udiv */ + unsigned short idiff; /* current diff */ + unsigned short ibdiv; /* current bdiv */ + unsigned long est; /* current estimate */ + unsigned long baud; + void *np; + + /* read the sysclk value from the CPLD */ + sysclk = (in_8((unsigned char *)0x80000000) == 0xc) ? 66666666 : 33333000; + + /* + * Read PLL Mode registers + */ + cpr_plld = CPR0_READ(DCRN_CPR0_PLLD); + cpr_pllc = CPR0_READ(DCRN_CPR0_PLLC); + + /* + * Determine forward divider A + */ + pllFwdDiv = ((cpr_plld & PLLD_FWDVA_MASK) >> 16); + + /* + * Determine forward divider B + */ + pllFwdDivB = ((cpr_plld & PLLD_FWDVB_MASK) >> 8); + if (pllFwdDivB == 0) + pllFwdDivB = 8; + + /* + * Determine FBK_DIV. + */ + pllFbkDiv = ((cpr_plld & PLLD_FBDV_MASK) >> 24); + if (pllFbkDiv == 0) + pllFbkDiv = 256; + + /* + * Read CPR_PRIMAD register + */ + cpr_primad = CPR0_READ(DCRN_CPR0_PRIMAD); + + /* + * Determine PLB_DIV. + */ + pllPlbDiv = ((cpr_primad & PRIMAD_PLBDV_MASK) >> 16); + if (pllPlbDiv == 0) + pllPlbDiv = 16; + + /* + * Determine EXTBUS_DIV. + */ + pllExtBusDiv = (cpr_primad & PRIMAD_EBCDV_MASK); + if (pllExtBusDiv == 0) + pllExtBusDiv = 16; + + /* + * Determine OPB_DIV. + */ + pllOpbDiv = ((cpr_primad & PRIMAD_OPBDV_MASK) >> 8); + if (pllOpbDiv == 0) + pllOpbDiv = 16; + + /* There is a bug in U-Boot that prevents us from using + * bd.bi_opbfreq because U-Boot doesn't populate it for + * 405EZ. We get to calculate it, yay! + */ + freqOPB = (sysclk *pllFbkDiv) /pllOpbDiv; + + freqEBC = (sysclk * pllFbkDiv) / pllExtBusDiv; + + plloutb = ((sysclk * ((cpr_pllc & PLLC_SRC_MASK) ? + pllFwdDivB : pllFwdDiv) * + pllFbkDiv) / pllFwdDivB); + + np = find_node_by_alias("serial0"); + if (getprop(np, "current-speed", &baud, sizeof(baud)) != sizeof(baud)) + fatal("no current-speed property\n\r"); + + udiv = 256; /* Assume lowest possible serial clk */ + div = plloutb / (16 * baud); /* total divisor */ + umin = (plloutb / freqOPB) << 1; /* 2 x OPB divisor */ + diff = 256; /* highest possible */ + + /* i is the test udiv value -- start with the largest + * possible (256) to minimize serial clock and constrain + * search to umin. + */ + for (i = 256; i > umin; i--) { + ibdiv = div / i; + est = i * ibdiv; + idiff = (est > div) ? (est-div) : (div-est); + if (idiff == 0) { + udiv = i; + break; /* can't do better */ + } else if (idiff < diff) { + udiv = i; /* best so far */ + diff = idiff; /* update lowest diff*/ + } + } + freqUART = plloutb / udiv; + + dt_fixup_cpu_clocks(bd.bi_procfreq, bd.bi_intfreq, bd.bi_plb_busfreq); + dt_fixup_clock("/plb/ebc", freqEBC); + dt_fixup_clock("/plb/opb", freqOPB); + dt_fixup_clock("/plb/opb/serial@ef600300", freqUART); + dt_fixup_clock("/plb/opb/serial@ef600400", freqUART); +} + +static void acadia_fixups(void) +{ + dt_fixup_memory(bd.bi_memstart, bd.bi_memsize); + get_clocks(); + dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr); +} + +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + CUBOOT_INIT(); + platform_ops.fixups = acadia_fixups; + platform_ops.exit = ibm40x_dbcr_reset; + fdt_init(_dtb_start); + serial_console_init(); +} From 4cbfc467cc08976e74a6f203c404e728d4dbd902 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Wed, 3 Sep 2008 21:02:47 -0400 Subject: [PATCH 08/53] powerpc/40x: Add PowerPC 405EZ Acadia defconfig Add simple defconfig for the AMCC PowerPC 405EZ Acadia evaluation board Signed-off-by: Josh Boyer --- arch/powerpc/configs/40x/acadia_defconfig | 921 ++++++++++++++++++++++ 1 file changed, 921 insertions(+) create mode 100644 arch/powerpc/configs/40x/acadia_defconfig diff --git a/arch/powerpc/configs/40x/acadia_defconfig b/arch/powerpc/configs/40x/acadia_defconfig new file mode 100644 index 000000000000..39bd9eb453f0 --- /dev/null +++ b/arch/powerpc/configs/40x/acadia_defconfig @@ -0,0 +1,921 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.27-rc5 +# Mon Oct 13 13:47:16 2008 +# +# CONFIG_PPC64 is not set + +# +# Processor support +# +# CONFIG_6xx is not set +# CONFIG_PPC_85xx is not set +# CONFIG_PPC_8xx is not set +CONFIG_40x=y +# CONFIG_44x is not set +# CONFIG_E200 is not set +CONFIG_4xx=y +# CONFIG_PPC_MM_SLICES is not set +CONFIG_NOT_COHERENT_CACHE=y +CONFIG_PPC32=y +CONFIG_WORD_SIZE=32 +CONFIG_PPC_MERGE=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_HAVE_SETUP_PER_CPU_AREA is not set +CONFIG_IRQ_PER_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_ARCH_HAS_ILOG2_U32=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +# CONFIG_ARCH_NO_VIRT_TO_BUS is not set +CONFIG_PPC=y +CONFIG_EARLY_PRINTK=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_PPC_OF=y +CONFIG_OF=y +CONFIG_PPC_UDBG_16550=y +# CONFIG_GENERIC_TBSYNC is not set +CONFIG_AUDIT_ARCH=y +CONFIG_GENERIC_BUG=y +# CONFIG_DEFAULT_UIMAGE is not set +CONFIG_PPC_DCR_NATIVE=y +# CONFIG_PPC_DCR_MMIO is not set +CONFIG_PPC_DCR=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=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_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +CONFIG_GROUP_SCHED=y +# CONFIG_FAIR_GROUP_SCHED is not set +# CONFIG_RT_GROUP_SCHED is not set +CONFIG_USER_SCHED=y +# CONFIG_CGROUP_SCHED 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_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=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_COMPAT_BRK=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +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 is not set +# CONFIG_USE_GENERIC_SMP_HELPERS is not set +# CONFIG_HAVE_CLK is not set +CONFIG_PROC_PAGE_MONITOR=y +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_BLOCK=y +CONFIG_LBD=y +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y +# CONFIG_PPC4xx_PCI_EXPRESS is not set + +# +# Platform support +# +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set +CONFIG_ACADIA=y +# CONFIG_EP405 is not set +# CONFIG_KILAUEA is not set +# CONFIG_MAKALU is not set +# CONFIG_WALNUT is not set +# CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set +CONFIG_PPC40x_SIMPLE=y +CONFIG_405EZ=y +# CONFIG_IPIC is not set +# CONFIG_MPIC is not set +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_FSL_ULI1575 is not set + +# +# Kernel options +# +# CONFIG_HIGHMEM is not set +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_MATH_EMULATION is not set +# CONFIG_IOMMU_HELPER is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_MIGRATION=y +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_PROC_DEVICETREE=y +# CONFIG_CMDLINE_BOOL is not set +CONFIG_EXTRA_TARGETS="" +# CONFIG_PM is not set +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_ZONE_DMA=y +CONFIG_PPC_INDIRECT_PCI=y +CONFIG_4xx_SOC=y +CONFIG_PPC_PCI_CHOICE=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_SYSCALL=y +# CONFIG_PCIEPORTBUS is not set +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_PCI_MSI is not set +CONFIG_PCI_LEGACY=y +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCCARD is not set +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HAS_RAPIDIO is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_PAGE_OFFSET=0xc0000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_PHYSICAL_START=0x00000000 +CONFIG_TASK_SIZE=0xc0000000 +CONFIG_CONSISTENT_START=0xff100000 +CONFIG_CONSISTENT_SIZE=0x00200000 +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_PHYSMAP_OF=y +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +CONFIG_OF_DEVICE=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=35000 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_XILINX_SYSACE is not set +# CONFIG_BLK_DEV_HD is not set +# CONFIG_MISC_DEVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# Enable only one of the two stacks, unless you know what you are doing +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set +# CONFIG_MACINTOSH_DRIVERS is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_ARCNET is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_IBM_NEW_EMAC=y +CONFIG_IBM_NEW_EMAC_RXB=256 +CONFIG_IBM_NEW_EMAC_TXB=256 +CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32 +CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256 +CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0 +CONFIG_IBM_NEW_EMAC_DEBUG=y +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL=y +CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT=y +CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR=y +# CONFIG_NET_PCI is not set +# CONFIG_B44 is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +# CONFIG_GEN_RTC is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +# CONFIG_I2C is not set +# CONFIG_SPI is not set +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y +# CONFIG_GPIOLIB is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +CONFIG_THERMAL=y +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_MFD_TMIO is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_SOUND is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +# CONFIG_EDAC is not set +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_NLS is not set +# CONFIG_DLM is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_HAVE_LMB=y + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_HAVE_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +# CONFIG_FTRACE is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_CODE_PATCHING_SELFTEST is not set +# CONFIG_FTR_FIXUP_SELFTEST is not set +# CONFIG_MSI_BITMAP_SELFTEST is not set +# CONFIG_XMON is not set +# CONFIG_IRQSTACKS is not set +# CONFIG_VIRQ_DEBUG is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_PPC_EARLY_DEBUG is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=y +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_PPC_CLOCK is not set +# CONFIG_VIRTUALIZATION is not set From 9fa126da4a9addec77db4663933ed592188a0741 Mon Sep 17 00:00:00 2001 From: Niklaus Giger Date: Wed, 1 Oct 2008 19:23:23 +0000 Subject: [PATCH 09/53] powerpc/40x: Add support for Netstal HCU4 board Adds support for a HCU4 PPC405GPr based board from Netstal Maschinen AG. Signed-off-by: Niklaus Giger Signed-off-by: Josh Boyer --- arch/powerpc/boot/dts/hcu4.dts | 168 +++++ arch/powerpc/configs/40x/hcu4_defconfig | 929 ++++++++++++++++++++++++ arch/powerpc/platforms/40x/Kconfig | 8 + arch/powerpc/platforms/40x/Makefile | 1 + arch/powerpc/platforms/40x/hcu4.c | 61 ++ 5 files changed, 1167 insertions(+) create mode 100644 arch/powerpc/boot/dts/hcu4.dts create mode 100644 arch/powerpc/configs/40x/hcu4_defconfig create mode 100644 arch/powerpc/platforms/40x/hcu4.c diff --git a/arch/powerpc/boot/dts/hcu4.dts b/arch/powerpc/boot/dts/hcu4.dts new file mode 100644 index 000000000000..7988598da4c9 --- /dev/null +++ b/arch/powerpc/boot/dts/hcu4.dts @@ -0,0 +1,168 @@ +/* +* Device Tree Source for Netstal Maschinen HCU4 +* based on the IBM Walnut +* +* Copyright 2008 +* Niklaus Giger +* +* Copyright 2007 IBM Corp. +* Josh Boyer +* +* 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/; + +/ { + #address-cells = <0x1>; + #size-cells = <0x1>; + model = "netstal,hcu4"; + compatible = "netstal,hcu4"; + dcr-parent = <0x1>; + + aliases { + ethernet0 = "/plb/opb/ethernet@ef600800"; + serial0 = "/plb/opb/serial@ef600300"; + }; + + cpus { + #address-cells = <0x1>; + #size-cells = <0x0>; + + cpu@0 { + device_type = "cpu"; + model = "PowerPC,405GPr"; + reg = <0x0>; + clock-frequency = <0>; /* Filled in by U-Boot */ + timebase-frequency = <0x0>; /* Filled in by U-Boot */ + i-cache-line-size = <0x20>; + d-cache-line-size = <0x20>; + i-cache-size = <0x4000>; + d-cache-size = <0x4000>; + dcr-controller; + dcr-access-method = "native"; + linux,phandle = <0x1>; + }; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x0>; /* Filled in by U-Boot */ + }; + + UIC0: interrupt-controller { + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <0x0>; + dcr-reg = <0xc0 0x9>; + #address-cells = <0x0>; + #size-cells = <0x0>; + #interrupt-cells = <0x2>; + linux,phandle = <0x2>; + }; + + plb { + compatible = "ibm,plb3"; + #address-cells = <0x1>; + #size-cells = <0x1>; + ranges; + clock-frequency = <0x0>; /* Filled in by U-Boot */ + + SDRAM0: memory-controller { + compatible = "ibm,sdram-405gp"; + dcr-reg = <0x10 0x2>; + }; + + MAL: mcmal { + compatible = "ibm,mcmal-405gp", "ibm,mcmal"; + dcr-reg = <0x180 0x62>; + num-tx-chans = <0x1>; + num-rx-chans = <0x1>; + interrupt-parent = <0x2>; + interrupts = <0xb 0x4 0xc 0x4 0xa 0x4 0xd 0x4 0xe 0x4>; + linux,phandle = <0x3>; + }; + + POB0: opb { + compatible = "ibm,opb-405gp", "ibm,opb"; + #address-cells = <0x1>; + #size-cells = <0x1>; + ranges = <0xef600000 0xef600000 0xa00000>; + dcr-reg = <0xa0 0x5>; + clock-frequency = <0x0>; /* Filled in by U-Boot */ + + UART0: serial@ef600300 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0xef600300 0x8>; + virtual-reg = <0xef600300>; + clock-frequency = <0x0>;/* Filled in by U-Boot */ + current-speed = <0>; /* Filled in by U-Boot */ + interrupt-parent = <0x2>; + interrupts = <0x0 0x4>; + }; + + IIC: i2c@ef600500 { + compatible = "ibm,iic-405gp", "ibm,iic"; + reg = <0xef600500 0x11>; + interrupt-parent = <0x2>; + interrupts = <0x2 0x4>; + }; + + GPIO: gpio@ef600700 { + compatible = "ibm,gpio-405gp"; + reg = <0xef600700 0x20>; + }; + + EMAC: ethernet@ef600800 { + device_type = "network"; + compatible = "ibm,emac-405gp", "ibm,emac"; + interrupt-parent = <0x2>; + interrupts = <0xf 0x4 0x9 0x4>; + local-mac-address = [00 00 00 00 00 00]; + reg = <0xef600800 0x70>; + mal-device = <0x3>; + mal-tx-channel = <0x0>; + mal-rx-channel = <0x0>; + cell-index = <0x0>; + max-frame-size = <0x5dc>; + rx-fifo-size = <0x1000>; + tx-fifo-size = <0x800>; + phy-mode = "rmii"; + phy-map = <0x1>; + }; + }; + + EBC0: ebc { + compatible = "ibm,ebc-405gp", "ibm,ebc"; + dcr-reg = <0x12 0x2>; + #address-cells = <0x2>; + #size-cells = <0x1>; + clock-frequency = <0x0>; /* Filled in by U-Boot */ + + sram@0,0 { + reg = <0x0 0x0 0x80000>; + }; + + flash@0,80000 { + compatible = "jedec-flash"; + bank-width = <0x1>; + reg = <0x0 0x80000 0x80000>; + #address-cells = <0x1>; + #size-cells = <0x1>; + + partition@0 { + label = "OpenBIOS"; + reg = <0x0 0x80000>; + read-only; + }; + }; + }; + }; + + chosen { + linux,stdout-path = "/plb/opb/serial@ef600300"; + }; +}; diff --git a/arch/powerpc/configs/40x/hcu4_defconfig b/arch/powerpc/configs/40x/hcu4_defconfig new file mode 100644 index 000000000000..682fce02c73a --- /dev/null +++ b/arch/powerpc/configs/40x/hcu4_defconfig @@ -0,0 +1,929 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.26.5 +# Tue Sep 16 00:44:33 2008 +# +# CONFIG_PPC64 is not set + +# +# Processor support +# +# CONFIG_6xx is not set +# CONFIG_PPC_85xx is not set +# CONFIG_PPC_8xx is not set +CONFIG_40x=y +# CONFIG_44x is not set +# CONFIG_E200 is not set +CONFIG_4xx=y +# CONFIG_PPC_MM_SLICES is not set +CONFIG_NOT_COHERENT_CACHE=y +CONFIG_PPC32=y +CONFIG_WORD_SIZE=32 +CONFIG_PPC_MERGE=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_HAVE_SETUP_PER_CPU_AREA is not set +CONFIG_IRQ_PER_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_ARCH_HAS_ILOG2_U32=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +# CONFIG_ARCH_NO_VIRT_TO_BUS is not set +CONFIG_PPC=y +CONFIG_EARLY_PRINTK=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_PPC_OF=y +CONFIG_OF=y +CONFIG_PPC_UDBG_16550=y +# CONFIG_GENERIC_TBSYNC is not set +CONFIG_AUDIT_ARCH=y +CONFIG_GENERIC_BUG=y +# CONFIG_DEFAULT_UIMAGE is not set +CONFIG_PPC_DCR_NATIVE=y +# CONFIG_PPC_DCR_MMIO is not set +CONFIG_PPC_DCR=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=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_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_CGROUPS is not set +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_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_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +# CONFIG_LOGBUFFER is not set +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_COMPAT_BRK=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +# CONFIG_MARKERS is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +# CONFIG_HAVE_DMA_ATTRS is not set +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SLABINFO=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_BLOCK=y +CONFIG_LBD=y +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_CLASSIC_RCU=y +# CONFIG_PPC4xx_PCI_EXPRESS is not set + +# +# Platform support +# +# CONFIG_PPC_MPC512x is not set +# CONFIG_PPC_MPC5121 is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PQ2ADS is not set +# CONFIG_EP405 is not set +CONFIG_HCU4=y +# CONFIG_KILAUEA is not set +# CONFIG_MAKALU is not set +# CONFIG_WALNUT is not set +# CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set +# CONFIG_IPIC is not set +# CONFIG_MPIC is not set +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_FSL_ULI1575 is not set + +# +# Kernel options +# +# CONFIG_HIGHMEM is not set +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +# CONFIG_SCHED_HRTICK is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_MATH_EMULATION is not set +# CONFIG_IOMMU_HELPER is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_WALK_MEMORY=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_RESOURCES_64BIT=y +CONFIG_ZONE_DMA_FLAG=1 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +CONFIG_FORCE_MAX_ZONEORDER=11 +CONFIG_PROC_DEVICETREE=y +# CONFIG_CMDLINE_BOOL is not set +# CONFIG_PM is not set +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_ZONE_DMA=y +CONFIG_PPC_INDIRECT_PCI=y +CONFIG_4xx_SOC=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_SYSCALL=y +# CONFIG_PCIEPORTBUS is not set +CONFIG_ARCH_SUPPORTS_MSI=y +# CONFIG_PCI_MSI is not set +# CONFIG_PCI_LEGACY is not set +# CONFIG_PCI_DEBUG is not set +# CONFIG_PCCARD is not set +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HAS_RAPIDIO is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_PAGE_OFFSET=0xc0000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_PHYSICAL_START=0x00000000 +CONFIG_TASK_SIZE=0xc0000000 +CONFIG_CONSISTENT_START=0xff100000 +CONFIG_CONSISTENT_SIZE=0x00200000 + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_CONNECTOR=y +CONFIG_PROC_EVENTS=y +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=m +CONFIG_MTD_BLOCK=m +# CONFIG_MTD_BLOCK_RO is not set +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set +# CONFIG_MTD_OOPS is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_PHYSMAP_OF=y +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +CONFIG_OF_DEVICE=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=35000 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_XILINX_SYSACE is not set +CONFIG_MISC_DEVICES=y +# CONFIG_PHANTOM is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_ENCLOSURE_SERVICES is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# Enable only one of the two stacks, unless you know what you are doing +# +# CONFIG_FIREWIRE is not set +# CONFIG_IEEE1394 is not set +# CONFIG_I2O is not set +# CONFIG_MACINTOSH_DRIVERS is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_VETH is not set +# CONFIG_ARCNET is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_IBM_NEW_EMAC=y +CONFIG_IBM_NEW_EMAC_RXB=128 +CONFIG_IBM_NEW_EMAC_TXB=64 +CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32 +CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256 +CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0 +# CONFIG_IBM_NEW_EMAC_DEBUG is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_NET_PCI is not set +# CONFIG_B44 is not set +CONFIG_NETDEV_1000=y +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_E1000E_ENABLED is not set +# CONFIG_IP1000 is not set +# CONFIG_IGB is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set +CONFIG_NETDEV_10000=y +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_NIU is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_TEHUTI is not set +# CONFIG_BNX2X is not set +# CONFIG_SFC is not set +# CONFIG_TR is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_IWLWIFI_LEDS is not set +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_DEVKMEM=y +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_NOZOMI is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +# CONFIG_GEN_RTC is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +# CONFIG_I2C is not set +# CONFIG_SPI is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +# CONFIG_WATCHDOG is not set + +# +# Sonics Silicon Backplane +# +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSB is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set +# CONFIG_HTC_PASIC3 is not set + +# +# Multimedia devices +# + +# +# Multimedia core support +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +# CONFIG_VIDEO_MEDIA is not set + +# +# Multimedia drivers +# +# CONFIG_DAB is not set + +# +# Graphics support +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=m +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +# CONFIG_EDAC is not set +# CONFIG_RTC_CLASS is not set +# CONFIG_DMADEVICES is not set +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +CONFIG_DNOTIFY=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_YAFFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_BIND34 is not set +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_NLS is not set +# CONFIG_DLM is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +# CONFIG_GENERIC_FIND_FIRST_BIT is not set +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y +CONFIG_HAVE_LMB=y + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_SAMPLES is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUGGER is not set +# CONFIG_IRQSTACKS is not set +# CONFIG_VIRQ_DEBUG is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_PPC_EARLY_DEBUG is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_GF128MUL is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_SEQIV is not set + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +CONFIG_CRYPTO_PCBC=y +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_XCBC is not set + +# +# Digest +# +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +# CONFIG_PPC_CLOCK is not set +# CONFIG_VIRTUALIZATION is not set diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig index 72ba3a7289fe..9bd152553050 100644 --- a/arch/powerpc/platforms/40x/Kconfig +++ b/arch/powerpc/platforms/40x/Kconfig @@ -32,6 +32,14 @@ config EP405 help This option enables support for the EP405/EP405PC boards. +config HCU4 + bool "Hcu4" + depends on 40x + default y + select 405GPR + help + This option enables support for the Nestal Maschinen HCU4 board. + config KILAUEA bool "Kilauea" depends on 40x diff --git a/arch/powerpc/platforms/40x/Makefile b/arch/powerpc/platforms/40x/Makefile index 1d93273a1db1..9bab76a652a6 100644 --- a/arch/powerpc/platforms/40x/Makefile +++ b/arch/powerpc/platforms/40x/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_KILAUEA) += kilauea.o +obj-$(CONFIG_HCU4) += hcu4.o obj-$(CONFIG_MAKALU) += makalu.o obj-$(CONFIG_WALNUT) += walnut.o obj-$(CONFIG_XILINX_VIRTEX_GENERIC_BOARD) += virtex.o diff --git a/arch/powerpc/platforms/40x/hcu4.c b/arch/powerpc/platforms/40x/hcu4.c new file mode 100644 index 000000000000..60b2afecab75 --- /dev/null +++ b/arch/powerpc/platforms/40x/hcu4.c @@ -0,0 +1,61 @@ +/* + * Architecture- / platform-specific boot-time initialization code for + * IBM PowerPC 4xx based boards. Adapted from original + * code by Gary Thomas, Cort Dougan , and Dan Malek + * . + * + * Copyright(c) 1999-2000 Grant Erickson + * + * Rewritten and ported to the merged powerpc tree: + * Copyright 2007 IBM Corporation + * Josh Boyer + * + * 2002 (c) MontaVista, Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +static __initdata struct of_device_id hcu4_of_bus[] = { + { .compatible = "ibm,plb3", }, + { .compatible = "ibm,opb", }, + { .compatible = "ibm,ebc", }, + {}, +}; + +static int __init hcu4_device_probe(void) +{ + of_platform_bus_probe(NULL, hcu4_of_bus, NULL); + return 0; +} +machine_device_initcall(hcu4, hcu4_device_probe); + +static int __init hcu4_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + if (!of_flat_dt_is_compatible(root, "netstal,hcu4")) + return 0; + + return 1; +} + +define_machine(hcu4) { + .name = "HCU4", + .probe = hcu4_probe, + .progress = udbg_progress, + .init_IRQ = uic_init_tree, + .get_irq = uic_get_irq, + .restart = ppc4xx_reset_system, + .calibrate_decr = generic_calibrate_decr, +}; From 878e7556bfe7b10178ea58862bf9708f35afe001 Mon Sep 17 00:00:00 2001 From: "Steven A. Falco" Date: Mon, 13 Oct 2008 06:04:09 +0000 Subject: [PATCH 10/53] powerpc/4xx: Add PowerPC 4xx GPIO driver This patch adds support for the GPIO functions of PPC40x and PPC44x SOCs. Signed-off-by: Steve Falco Acked-by: Stefan Roese Acked-by: Sean MacLennan Signed-off-by: Josh Boyer --- arch/powerpc/platforms/40x/Kconfig | 8 ++ arch/powerpc/platforms/44x/Kconfig | 8 ++ arch/powerpc/sysdev/Makefile | 1 + arch/powerpc/sysdev/ppc4xx_gpio.c | 217 +++++++++++++++++++++++++++++ 4 files changed, 234 insertions(+) create mode 100644 arch/powerpc/sysdev/ppc4xx_gpio.c diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig index 9bd152553050..65730275e012 100644 --- a/arch/powerpc/platforms/40x/Kconfig +++ b/arch/powerpc/platforms/40x/Kconfig @@ -169,6 +169,14 @@ config STB03xxx select IBM405_ERR77 select IBM405_ERR51 +config PPC4xx_GPIO + bool "PPC4xx GPIO support" + depends on 40x + select ARCH_REQUIRE_GPIOLIB + select GENERIC_GPIO + help + Enable gpiolib support for ppc40x based boards + # 40x errata/workaround config symbols, selected by the CPU models above # All 405-based cores up until the 405GPR and 405EP have this errata. diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index 79c1154f88d4..3496bc05058e 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig @@ -167,6 +167,14 @@ config PPC44x_SIMPLE help This option enables the simple PowerPC 44x platform support. +config PPC4xx_GPIO + bool "PPC4xx GPIO support" + depends on 44x + select ARCH_REQUIRE_GPIOLIB + select GENERIC_GPIO + help + Enable gpiolib support for ppc440 based boards + # 44x specific CPU modules, selected based on the board above. config 440EP bool diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index a44709a94f97..5afce115ab1f 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_OF_RTC) += of_rtc.o ifeq ($(CONFIG_PCI),y) obj-$(CONFIG_4xx) += ppc4xx_pci.o endif +obj-$(CONFIG_PPC4xx_GPIO) += ppc4xx_gpio.o obj-$(CONFIG_CPM) += cpm_common.o obj-$(CONFIG_CPM2) += cpm2.o cpm2_pic.o diff --git a/arch/powerpc/sysdev/ppc4xx_gpio.c b/arch/powerpc/sysdev/ppc4xx_gpio.c new file mode 100644 index 000000000000..110efe2a54fc --- /dev/null +++ b/arch/powerpc/sysdev/ppc4xx_gpio.c @@ -0,0 +1,217 @@ +/* + * PPC4xx gpio driver + * + * Copyright (c) 2008 Harris Corporation + * Copyright (c) 2008 Sascha Hauer , Pengutronix + * Copyright (c) MontaVista Software, Inc. 2008. + * + * Author: Steve Falco + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define GPIO_MASK(gpio) (0x80000000 >> (gpio)) +#define GPIO_MASK2(gpio) (0xc0000000 >> ((gpio) * 2)) + +/* Physical GPIO register layout */ +struct ppc4xx_gpio { + __be32 or; + __be32 tcr; + __be32 osrl; + __be32 osrh; + __be32 tsrl; + __be32 tsrh; + __be32 odr; + __be32 ir; + __be32 rr1; + __be32 rr2; + __be32 rr3; + __be32 reserved1; + __be32 isr1l; + __be32 isr1h; + __be32 isr2l; + __be32 isr2h; + __be32 isr3l; + __be32 isr3h; +}; + +struct ppc4xx_gpio_chip { + struct of_mm_gpio_chip mm_gc; + spinlock_t lock; +}; + +/* + * GPIO LIB API implementation for GPIOs + * + * There are a maximum of 32 gpios in each gpio controller. + */ + +static inline struct ppc4xx_gpio_chip * +to_ppc4xx_gpiochip(struct of_mm_gpio_chip *mm_gc) +{ + return container_of(mm_gc, struct ppc4xx_gpio_chip, mm_gc); +} + +static int ppc4xx_gpio_get(struct gpio_chip *gc, unsigned int gpio) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct ppc4xx_gpio __iomem *regs = mm_gc->regs; + + return in_be32(®s->ir) & GPIO_MASK(gpio); +} + +static inline void +__ppc4xx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct ppc4xx_gpio __iomem *regs = mm_gc->regs; + + if (val) + setbits32(®s->or, GPIO_MASK(gpio)); + else + clrbits32(®s->or, GPIO_MASK(gpio)); +} + +static void +ppc4xx_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct ppc4xx_gpio_chip *chip = to_ppc4xx_gpiochip(mm_gc); + unsigned long flags; + + spin_lock_irqsave(&chip->lock, flags); + + __ppc4xx_gpio_set(gc, gpio, val); + + spin_unlock_irqrestore(&chip->lock, flags); + + pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); +} + +static int ppc4xx_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct ppc4xx_gpio_chip *chip = to_ppc4xx_gpiochip(mm_gc); + struct ppc4xx_gpio __iomem *regs = mm_gc->regs; + unsigned long flags; + + spin_lock_irqsave(&chip->lock, flags); + + /* Disable open-drain function */ + clrbits32(®s->odr, GPIO_MASK(gpio)); + + /* Float the pin */ + clrbits32(®s->tcr, GPIO_MASK(gpio)); + + /* Bits 0-15 use TSRL/OSRL, bits 16-31 use TSRH/OSRH */ + if (gpio < 16) { + clrbits32(®s->osrl, GPIO_MASK2(gpio)); + clrbits32(®s->tsrl, GPIO_MASK2(gpio)); + } else { + clrbits32(®s->osrh, GPIO_MASK2(gpio)); + clrbits32(®s->tsrh, GPIO_MASK2(gpio)); + } + + spin_unlock_irqrestore(&chip->lock, flags); + + return 0; +} + +static int +ppc4xx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct ppc4xx_gpio_chip *chip = to_ppc4xx_gpiochip(mm_gc); + struct ppc4xx_gpio __iomem *regs = mm_gc->regs; + unsigned long flags; + + spin_lock_irqsave(&chip->lock, flags); + + /* First set initial value */ + __ppc4xx_gpio_set(gc, gpio, val); + + /* Disable open-drain function */ + clrbits32(®s->odr, GPIO_MASK(gpio)); + + /* Drive the pin */ + setbits32(®s->tcr, GPIO_MASK(gpio)); + + /* Bits 0-15 use TSRL, bits 16-31 use TSRH */ + if (gpio < 16) { + clrbits32(®s->osrl, GPIO_MASK2(gpio)); + clrbits32(®s->tsrl, GPIO_MASK2(gpio)); + } else { + clrbits32(®s->osrh, GPIO_MASK2(gpio)); + clrbits32(®s->tsrh, GPIO_MASK2(gpio)); + } + + spin_unlock_irqrestore(&chip->lock, flags); + + pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val); + + return 0; +} + +static int __init ppc4xx_add_gpiochips(void) +{ + struct device_node *np; + + for_each_compatible_node(np, NULL, "ibm,ppc4xx-gpio") { + int ret; + struct ppc4xx_gpio_chip *ppc4xx_gc; + struct of_mm_gpio_chip *mm_gc; + struct of_gpio_chip *of_gc; + struct gpio_chip *gc; + + ppc4xx_gc = kzalloc(sizeof(*ppc4xx_gc), GFP_KERNEL); + if (!ppc4xx_gc) { + ret = -ENOMEM; + goto err; + } + + spin_lock_init(&ppc4xx_gc->lock); + + mm_gc = &ppc4xx_gc->mm_gc; + of_gc = &mm_gc->of_gc; + gc = &of_gc->gc; + + of_gc->gpio_cells = 2; + gc->ngpio = 32; + gc->direction_input = ppc4xx_gpio_dir_in; + gc->direction_output = ppc4xx_gpio_dir_out; + gc->get = ppc4xx_gpio_get; + gc->set = ppc4xx_gpio_set; + + ret = of_mm_gpiochip_add(np, mm_gc); + if (ret) + goto err; + continue; +err: + pr_err("%s: registration failed with status %d\n", + np->full_name, ret); + kfree(ppc4xx_gc); + /* try others anyway */ + } + return 0; +} +arch_initcall(ppc4xx_add_gpiochips); From 1ff0fcfcb1a6d0a4c4d065ed230be7beae087b83 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Thu, 16 Oct 2008 04:38:40 +0000 Subject: [PATCH 11/53] ibm_newemac: Fix new MAL feature handling Support for new features needed by the PPC 405EZ boards introduced some errors in the MAL and EMAC feature handling. This broke 'allmodconfig' builds as CONFIG_PPC_DCR_NATIVE is not set for those. This patch fixes these errors by wrapping the code in the appropriate #ifdefs. Acked-by: Benjamin Herrenschmidt Signed-off-by: Josh Boyer --- drivers/net/ibm_newemac/core.c | 10 +++++++++- drivers/net/ibm_newemac/mal.c | 15 ++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index efcf21c9f5c7..2ee2622258f5 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -2604,8 +2604,16 @@ static int __devinit emac_init_config(struct emac_instance *dev) if (of_device_is_compatible(np, "ibm,emac-440ep") || of_device_is_compatible(np, "ibm,emac-440gr")) dev->features |= EMAC_FTR_440EP_PHY_CLK_FIX; - if (of_device_is_compatible(np, "ibm,emac-405ez")) + if (of_device_is_compatible(np, "ibm,emac-405ez")) { +#ifdef CONFIG_IBM_NEW_EMAC_NO_FLOW_CONTROL dev->features |= EMAC_FTR_NO_FLOW_CONTROL_40x; +#else + printk(KERN_ERR "%s: Flow control not disabled!\n", + np->full_name); + return -ENXIO; +#endif + } + } /* Fixup some feature bits based on the device tree */ diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c index 1839d3f154a3..ecf9798987fa 100644 --- a/drivers/net/ibm_newemac/mal.c +++ b/drivers/net/ibm_newemac/mal.c @@ -280,9 +280,11 @@ static irqreturn_t mal_txeob(int irq, void *dev_instance) mal_schedule_poll(mal); set_mal_dcrn(mal, MAL_TXEOBISR, r); +#ifdef CONFIG_PPC_DCR_NATIVE if (mal_has_feature(mal, MAL_FTR_CLEAR_ICINTSTAT)) mtdcri(SDR0, DCRN_SDR_ICINTSTAT, (mfdcri(SDR0, DCRN_SDR_ICINTSTAT) | ICINTSTAT_ICTX)); +#endif return IRQ_HANDLED; } @@ -298,9 +300,11 @@ static irqreturn_t mal_rxeob(int irq, void *dev_instance) mal_schedule_poll(mal); set_mal_dcrn(mal, MAL_RXEOBISR, r); +#ifdef CONFIG_PPC_DCR_NATIVE if (mal_has_feature(mal, MAL_FTR_CLEAR_ICINTSTAT)) mtdcri(SDR0, DCRN_SDR_ICINTSTAT, (mfdcri(SDR0, DCRN_SDR_ICINTSTAT) | ICINTSTAT_ICRX)); +#endif return IRQ_HANDLED; } @@ -572,9 +576,18 @@ static int __devinit mal_probe(struct of_device *ofdev, goto fail; } - if (of_device_is_compatible(ofdev->node, "ibm,mcmal-405ez")) + if (of_device_is_compatible(ofdev->node, "ibm,mcmal-405ez")) { +#if defined(CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT) && \ + defined(CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR) mal->features |= (MAL_FTR_CLEAR_ICINTSTAT | MAL_FTR_COMMON_ERR_INT); +#else + printk(KERN_ERR "%s: Support for 405EZ not enabled!\n", + ofdev->node->full_name); + err = -ENODEV; + goto fail; +#endif + } mal->txeob_irq = irq_of_parse_and_map(ofdev->node, 0); mal->rxeob_irq = irq_of_parse_and_map(ofdev->node, 1); From baf399273f2ea38e2fcbd4d0b6cc7ba7f7db43eb Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Wed, 15 Oct 2008 13:16:18 +1100 Subject: [PATCH 12/53] powerpc/spufs: sputrace: Only enable logging on open(), prevent multiple openers Currently, sputrace will start logging to the event buffer before the log buffer has been open()ed. This results in a heap of "lost samples" warnings if the sputrace file hasn't yet been opened. Since the buffer is reset on open() anyway, there's no need to enable logging when no-one has opened the log. Because open clears the log, make it return EBUSY for mutliple open calls. Signed-off-by: Jeremy Kerr --- arch/powerpc/platforms/cell/spufs/sputrace.c | 34 +++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/platforms/cell/spufs/sputrace.c b/arch/powerpc/platforms/cell/spufs/sputrace.c index 92d20e993ede..50cae0cf0988 100644 --- a/arch/powerpc/platforms/cell/spufs/sputrace.c +++ b/arch/powerpc/platforms/cell/spufs/sputrace.c @@ -40,6 +40,7 @@ static DECLARE_WAIT_QUEUE_HEAD(sputrace_wait); static ktime_t sputrace_start; static unsigned long sputrace_head, sputrace_tail; static struct sputrace *sputrace_log; +static int sputrace_logging; static int sputrace_used(void) { @@ -109,24 +110,49 @@ static ssize_t sputrace_read(struct file *file, char __user *buf, static int sputrace_open(struct inode *inode, struct file *file) { + int rc; + spin_lock(&sputrace_lock); + if (sputrace_logging) { + rc = -EBUSY; + goto out; + } + + sputrace_logging = 1; sputrace_head = sputrace_tail = 0; sputrace_start = ktime_get(); - spin_unlock(&sputrace_lock); + rc = 0; +out: + spin_unlock(&sputrace_lock); + return rc; +} + +static int sputrace_release(struct inode *inode, struct file *file) +{ + spin_lock(&sputrace_lock); + sputrace_logging = 0; + spin_unlock(&sputrace_lock); return 0; } static const struct file_operations sputrace_fops = { - .owner = THIS_MODULE, - .open = sputrace_open, - .read = sputrace_read, + .owner = THIS_MODULE, + .open = sputrace_open, + .read = sputrace_read, + .release = sputrace_release, }; static void sputrace_log_item(const char *name, struct spu_context *ctx, struct spu *spu) { spin_lock(&sputrace_lock); + + if (!sputrace_logging) { + spin_unlock(&sputrace_lock); + return; + } + if (sputrace_avail() > 1) { struct sputrace *t = sputrace_log + sputrace_head; From e869446bb6db209e6092f7cba6cdfc2a5e637177 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Wed, 15 Oct 2008 13:20:42 +1100 Subject: [PATCH 13/53] powerpc/spufs: sputrace: Don't block until the read buffer is full Currently, read() on the sputrace buffer will only return data when the user buffer is exhausted. This may mean that we never see the end of the event log, unless we read() with exactly the right-sized buffer. This change makes sputrace_read not block if we have data ready to return. Signed-off-by: Jeremy Kerr --- arch/powerpc/platforms/cell/spufs/sputrace.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/powerpc/platforms/cell/spufs/sputrace.c b/arch/powerpc/platforms/cell/spufs/sputrace.c index 50cae0cf0988..a2460e2e1928 100644 --- a/arch/powerpc/platforms/cell/spufs/sputrace.c +++ b/arch/powerpc/platforms/cell/spufs/sputrace.c @@ -80,6 +80,11 @@ static ssize_t sputrace_read(struct file *file, char __user *buf, char tbuf[128]; int width; + /* If we have data ready to return, don't block waiting + * for more */ + if (cnt > 0 && sputrace_used() == 0) + break; + error = wait_event_interruptible(sputrace_wait, sputrace_used() > 0); if (error) From f5ed0eb6fe131e8f3847323b4aa569a6f7b36f56 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Thu, 16 Oct 2008 10:03:46 +1100 Subject: [PATCH 14/53] powerpc/spufs: Use state_mutex for switch_log locking, and prevent multiple openers Currently, we use ctx->mapping_lock and ctx->switch_log->lock for the context switch log. The mapping lock only prevents concurrent open()s, so we require the switch_lock->lock for reads. Since writes to the switch log buffer occur on context switches, we're better off synchronising with the state_mutex, which is held during a switch. Since we're serialised througout the buffer reads and writes, we can use the state mutex to protect open and release too, and can now kfree() the log buffer on release. This allows us to perform the switch log notify without taking any extra locks. Because the buffer is only present while the file is open, we can use it to prevent multiple simultaneous openers. Signed-off-by: Jeremy Kerr --- arch/powerpc/platforms/cell/spufs/file.c | 137 +++++++++++++--------- arch/powerpc/platforms/cell/spufs/run.c | 3 +- arch/powerpc/platforms/cell/spufs/spufs.h | 1 - 3 files changed, 83 insertions(+), 58 deletions(-) diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 010a51f59796..adb5abb9af5d 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -2426,38 +2426,48 @@ static inline int spufs_switch_log_avail(struct spu_context *ctx) static int spufs_switch_log_open(struct inode *inode, struct file *file) { struct spu_context *ctx = SPUFS_I(inode)->i_ctx; + int rc; + + rc = spu_acquire(ctx); + if (rc) + return rc; - /* - * We (ab-)use the mapping_lock here because it serves the similar - * purpose for synchronizing open/close elsewhere. Maybe it should - * be renamed eventually. - */ - mutex_lock(&ctx->mapping_lock); if (ctx->switch_log) { - spin_lock(&ctx->switch_log->lock); - ctx->switch_log->head = 0; - ctx->switch_log->tail = 0; - spin_unlock(&ctx->switch_log->lock); - } else { - /* - * We allocate the switch log data structures on first open. - * They will never be free because we assume a context will - * be traced until it goes away. - */ - ctx->switch_log = kzalloc(sizeof(struct switch_log) + - SWITCH_LOG_BUFSIZE * sizeof(struct switch_log_entry), - GFP_KERNEL); - if (!ctx->switch_log) - goto out; - spin_lock_init(&ctx->switch_log->lock); - init_waitqueue_head(&ctx->switch_log->wait); + rc = -EBUSY; + goto out; } - mutex_unlock(&ctx->mapping_lock); + + ctx->switch_log = kzalloc(sizeof(struct switch_log) + + SWITCH_LOG_BUFSIZE * sizeof(struct switch_log_entry), + GFP_KERNEL); + + if (!ctx->switch_log) { + rc = -ENOMEM; + goto out; + } + + init_waitqueue_head(&ctx->switch_log->wait); + rc = 0; + +out: + spu_release(ctx); + return rc; +} + +static int spufs_switch_log_release(struct inode *inode, struct file *file) +{ + struct spu_context *ctx = SPUFS_I(inode)->i_ctx; + int rc; + + rc = spu_acquire(ctx); + if (rc) + return rc; + + kfree(ctx->switch_log); + ctx->switch_log = NULL; + spu_release(ctx); return 0; - out: - mutex_unlock(&ctx->mapping_lock); - return -ENOMEM; } static int switch_log_sprint(struct spu_context *ctx, char *tbuf, int n) @@ -2485,42 +2495,46 @@ static ssize_t spufs_switch_log_read(struct file *file, char __user *buf, if (!buf || len < 0) return -EINVAL; + error = spu_acquire(ctx); + if (error) + return error; + while (cnt < len) { char tbuf[128]; int width; if (file->f_flags & O_NONBLOCK) { - if (spufs_switch_log_used(ctx) <= 0) - return cnt ? cnt : -EAGAIN; - } else { - /* Wait for data in buffer */ - error = wait_event_interruptible(ctx->switch_log->wait, - spufs_switch_log_used(ctx) > 0); - if (error) + if (spufs_switch_log_used(ctx) == 0) { + error = -EAGAIN; break; + } + } else { + /* spufs_wait will drop the mutex and re-acquire, + * but since we're in read(), the file cannot be + * _released (and so ctx->switch_log is stable). + */ + error = spufs_wait(ctx->switch_log->wait, + spufs_switch_log_used(ctx) > 0); + + /* On error, spufs_wait returns without the + * state mutex held */ + if (error) + return error; } - spin_lock(&ctx->switch_log->lock); - if (ctx->switch_log->head == ctx->switch_log->tail) { - /* multiple readers race? */ - spin_unlock(&ctx->switch_log->lock); + /* We may have had entries read from underneath us while we + * dropped the mutex in spufs_wait, so re-check */ + if (ctx->switch_log->head == ctx->switch_log->tail) continue; - } width = switch_log_sprint(ctx, tbuf, sizeof(tbuf)); - if (width < len) { + if (width < len) ctx->switch_log->tail = (ctx->switch_log->tail + 1) % SWITCH_LOG_BUFSIZE; - } - - spin_unlock(&ctx->switch_log->lock); - - /* - * If the record is greater than space available return - * partial buffer (so far) - */ - if (width >= len) + else + /* If the record is greater than space available return + * partial buffer (so far) */ break; error = copy_to_user(buf + cnt, tbuf, width); @@ -2529,6 +2543,8 @@ static ssize_t spufs_switch_log_read(struct file *file, char __user *buf, cnt += width; } + spu_release(ctx); + return cnt == 0 ? error : cnt; } @@ -2537,29 +2553,41 @@ static unsigned int spufs_switch_log_poll(struct file *file, poll_table *wait) struct inode *inode = file->f_path.dentry->d_inode; struct spu_context *ctx = SPUFS_I(inode)->i_ctx; unsigned int mask = 0; + int rc; poll_wait(file, &ctx->switch_log->wait, wait); + rc = spu_acquire(ctx); + if (rc) + return rc; + if (spufs_switch_log_used(ctx) > 0) mask |= POLLIN; + spu_release(ctx); + return mask; } static const struct file_operations spufs_switch_log_fops = { - .owner = THIS_MODULE, - .open = spufs_switch_log_open, - .read = spufs_switch_log_read, - .poll = spufs_switch_log_poll, + .owner = THIS_MODULE, + .open = spufs_switch_log_open, + .read = spufs_switch_log_read, + .poll = spufs_switch_log_poll, + .release = spufs_switch_log_release, }; +/** + * Log a context switch event to a switch log reader. + * + * Must be called with ctx->state_mutex held. + */ void spu_switch_log_notify(struct spu *spu, struct spu_context *ctx, u32 type, u32 val) { if (!ctx->switch_log) return; - spin_lock(&ctx->switch_log->lock); if (spufs_switch_log_avail(ctx) > 1) { struct switch_log_entry *p; @@ -2573,7 +2601,6 @@ void spu_switch_log_notify(struct spu *spu, struct spu_context *ctx, ctx->switch_log->head = (ctx->switch_log->head + 1) % SWITCH_LOG_BUFSIZE; } - spin_unlock(&ctx->switch_log->lock); wake_up(&ctx->switch_log->wait); } diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index c9bb7cfd3dca..c58bd36b0c5b 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -249,6 +249,7 @@ static int spu_run_fini(struct spu_context *ctx, u32 *npc, spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED); clear_bit(SPU_SCHED_SPU_RUN, &ctx->sched_flags); + spu_switch_log_notify(NULL, ctx, SWITCH_LOG_EXIT, *status); spu_release(ctx); if (signal_pending(current)) @@ -417,8 +418,6 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event) ret = spu_run_fini(ctx, npc, &status); spu_yield(ctx); - spu_switch_log_notify(NULL, ctx, SWITCH_LOG_EXIT, status); - if ((status & SPU_STATUS_STOPPED_BY_STOP) && (((status >> SPU_STOP_STATUS_SHIFT) & 0x3f00) == 0x2100)) ctx->stats.libassist++; diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index 8ae8ef9dfc22..15c62d3ca129 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -65,7 +65,6 @@ enum { }; struct switch_log { - spinlock_t lock; wait_queue_head_t wait; unsigned long head; unsigned long tail; From 14f693eeb5b16bc47ffa38d8b8838a654aedd53f Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Thu, 16 Oct 2008 10:51:46 +1100 Subject: [PATCH 15/53] powerpc/spufs: Don't require full buffer in switch_log read Currently, read() on the sputrace log will block until the read buffer is full. This makes it difficult to retrieve the end of the buffer, as the user will need to read with the right-sized buffer. In a similar method as 91553a1b5e0df006a3573a88d98ee7cd48a3818a, this change makes the switch_log return if there has already been data read. Signed-off-by: Jeremy Kerr --- arch/powerpc/platforms/cell/spufs/file.c | 46 ++++++++++++++---------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index adb5abb9af5d..f139cd8b594d 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -2503,30 +2503,38 @@ static ssize_t spufs_switch_log_read(struct file *file, char __user *buf, char tbuf[128]; int width; - if (file->f_flags & O_NONBLOCK) { - if (spufs_switch_log_used(ctx) == 0) { + if (spufs_switch_log_used(ctx) == 0) { + if (cnt > 0) { + /* If there's data ready to go, we can + * just return straight away */ + break; + + } else if (file->f_flags & O_NONBLOCK) { error = -EAGAIN; break; + + } else { + /* spufs_wait will drop the mutex and + * re-acquire, but since we're in read(), the + * file cannot be _released (and so + * ctx->switch_log is stable). + */ + error = spufs_wait(ctx->switch_log->wait, + spufs_switch_log_used(ctx) > 0); + + /* On error, spufs_wait returns without the + * state mutex held */ + if (error) + return error; + + /* We may have had entries read from underneath + * us while we dropped the mutex in spufs_wait, + * so re-check */ + if (spufs_switch_log_used(ctx) == 0) + continue; } - } else { - /* spufs_wait will drop the mutex and re-acquire, - * but since we're in read(), the file cannot be - * _released (and so ctx->switch_log is stable). - */ - error = spufs_wait(ctx->switch_log->wait, - spufs_switch_log_used(ctx) > 0); - - /* On error, spufs_wait returns without the - * state mutex held */ - if (error) - return error; } - /* We may have had entries read from underneath us while we - * dropped the mutex in spufs_wait, so re-check */ - if (ctx->switch_log->head == ctx->switch_log->tail) - continue; - width = switch_log_sprint(ctx, tbuf, sizeof(tbuf)); if (width < len) ctx->switch_log->tail = From f027faa231f38c02e949352735eac76f29090809 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Thu, 16 Oct 2008 11:11:12 +1100 Subject: [PATCH 16/53] powerpc/spufs: Don't spu_acquire_saved unnecessarily in regs read With most file readers (eg cat, dd), reading a context's regs file will result in two reads: the first to read the data, and the second to return EOF. Because each read performs a spu_acquire_saved, we end up descheduling and re-scheduling the context twice. This change does a simple check to see if we'd return EOF before calling spu_acquire_saved(), saving the extra schedule operation. Signed-off-by: Jeremy Kerr --- arch/powerpc/platforms/cell/spufs/file.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index f139cd8b594d..b6f7b917b56c 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -548,6 +548,11 @@ spufs_regs_read(struct file *file, char __user *buffer, int ret; struct spu_context *ctx = file->private_data; + /* pre-check for file position: if we'd return EOF, there's no point + * causing a deschedule */ + if (*pos >= sizeof(ctx->csa.lscsa->gprs)) + return 0; + ret = spu_acquire_saved(ctx); if (ret) return ret; From 837ef884b702edd1c4514eaed1dbecd48721bd22 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Fri, 17 Oct 2008 12:02:31 +1100 Subject: [PATCH 17/53] powerpc/spufs: Use kmalloc rather than kzalloc for switch log buffer No need to zero the entire buffer, just the head and tail indices. Signed-off-by: Jeremy Kerr --- arch/powerpc/platforms/cell/spufs/file.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index b6f7b917b56c..b73c369cc6f1 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -2442,7 +2442,7 @@ static int spufs_switch_log_open(struct inode *inode, struct file *file) goto out; } - ctx->switch_log = kzalloc(sizeof(struct switch_log) + + ctx->switch_log = kmalloc(sizeof(struct switch_log) + SWITCH_LOG_BUFSIZE * sizeof(struct switch_log_entry), GFP_KERNEL); @@ -2451,6 +2451,7 @@ static int spufs_switch_log_open(struct inode *inode, struct file *file) goto out; } + ctx->switch_log->head = ctx->switch_log->tail = 0; init_waitqueue_head(&ctx->switch_log->wait); rc = 0; From 10baa26c8ccba6f100397c9ba6534be175762e8d Mon Sep 17 00:00:00 2001 From: Andre Detsch Date: Tue, 21 Oct 2008 11:15:23 +1100 Subject: [PATCH 18/53] powerpc/spufs: Improve search of node for contexts with SPU affinity This patch improves redability of the code responsible for trying to find a node with enough SPUs not committed to other affinity gangs. An additional check is also added, to avoid taking into account gangs that have no SPU affinity. Signed-off-by: Andre Detsch Signed-off-by: Jeremy Kerr --- arch/powerpc/platforms/cell/spufs/sched.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 67595bc380dc..6253df5a436e 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -312,6 +312,15 @@ static struct spu *aff_ref_location(struct spu_context *ctx, int mem_aff, */ node = cpu_to_node(raw_smp_processor_id()); for (n = 0; n < MAX_NUMNODES; n++, node++) { + /* + * "available_spus" counts how many spus are not potentially + * going to be used by other affinity gangs whose reference + * context is already in place. Although this code seeks to + * avoid having affinity gangs with a summed amount of + * contexts bigger than the amount of spus in the node, + * this may happen sporadically. In this case, available_spus + * becomes negative, which is harmless. + */ int available_spus; node = (node < MAX_NUMNODES) ? node : 0; @@ -321,12 +330,10 @@ static struct spu *aff_ref_location(struct spu_context *ctx, int mem_aff, available_spus = 0; mutex_lock(&cbe_spu_info[node].list_mutex); list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) { - if (spu->ctx && spu->ctx->gang - && spu->ctx->aff_offset == 0) - available_spus -= - (spu->ctx->gang->contexts - 1); - else - available_spus++; + if (spu->ctx && spu->ctx->gang && !spu->ctx->aff_offset + && spu->ctx->gang->aff_ref_spu) + available_spus -= spu->ctx->gang->contexts; + available_spus++; } if (available_spus < ctx->gang->contexts) { mutex_unlock(&cbe_spu_info[node].list_mutex); From 34318c253b861f82bd4a2956e6c8ae8ee2c3aae7 Mon Sep 17 00:00:00 2001 From: Andre Detsch Date: Tue, 21 Oct 2008 11:16:09 +1100 Subject: [PATCH 19/53] powerpc/spufs: Explain conditional decrement of aff_sched_count This patch adds a comment to clarify why atomic_dec_if_positive is being used to decrement gang's aff_sched_count on SPU context unbind. Signed-off-by: Andre Detsch Signed-off-by: Jeremy Kerr --- arch/powerpc/platforms/cell/spufs/sched.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 6253df5a436e..2ad914c47493 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -444,6 +444,11 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx) atomic_dec(&cbe_spu_info[spu->node].reserved_spus); if (ctx->gang) + /* + * If ctx->gang->aff_sched_count is positive, SPU affinity is + * being considered in this gang. Using atomic_dec_if_positive + * allow us to skip an explicit check for affinity in this gang + */ atomic_dec_if_positive(&ctx->gang->aff_sched_count); spu_switch_notify(spu, NULL); From c10c178a92b032ea3dd7259dcbbd1b9331c05c41 Mon Sep 17 00:00:00 2001 From: Sebastian Siewior Date: Sun, 12 Oct 2008 23:15:26 +0000 Subject: [PATCH 20/53] powerpc/boot: Compare _start against ei.loadsize instead ei.memsize If the vmlinux binary in memory is larger than 4 MiB than it collides with the initial boot code which is linked at 4 MiB in case of cuBoot. If the the uncompressed image size (on disk size) is less than 4 MiB then it would fit. The difference between those two sizes is the bss section. In cuBoot we have the dtb embedded right after the data section so it is very likely that the reset of the bss section (in kernel's start up code) will overwrite the dtb blob. Therefore we reallocate the dtb. Something similar is allready done to the initrd. Signed-off-by: Sebastian Andrzej Siewior Acked-by: David Gibson Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/boot/libfdt-wrapper.c | 16 ++++++++-------- arch/powerpc/boot/main.c | 14 ++++++++++++-- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/boot/libfdt-wrapper.c b/arch/powerpc/boot/libfdt-wrapper.c index c541fd8a95d4..1daa73f08ba8 100644 --- a/arch/powerpc/boot/libfdt-wrapper.c +++ b/arch/powerpc/boot/libfdt-wrapper.c @@ -165,6 +165,7 @@ static unsigned long fdt_wrapper_finalize(void) void fdt_init(void *blob) { int err; + int bufsize; dt_ops.finddevice = fdt_wrapper_finddevice; dt_ops.getprop = fdt_wrapper_getprop; @@ -178,16 +179,15 @@ void fdt_init(void *blob) /* Make sure the dt blob is the right version and so forth */ fdt = blob; - err = fdt_open_into(fdt, fdt, fdt_totalsize(blob)); - if (err == -FDT_ERR_NOSPACE) { - int bufsize = fdt_totalsize(fdt) + 4; - buf = malloc(bufsize); - err = fdt_open_into(fdt, buf, bufsize); - } + bufsize = fdt_totalsize(fdt) + 4; + buf = malloc(bufsize); + if(!buf) + fatal("malloc failed. can't relocate the device tree\n\r"); + + err = fdt_open_into(fdt, buf, bufsize); if (err != 0) fatal("fdt_init(): %s\n\r", fdt_strerror(err)); - if (buf) - fdt = buf; + fdt = buf; } diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c index 9e7f3ddd9913..ae32801ebd69 100644 --- a/arch/powerpc/boot/main.c +++ b/arch/powerpc/boot/main.c @@ -56,9 +56,19 @@ static struct addr_range prep_kernel(void) if (platform_ops.vmlinux_alloc) { addr = platform_ops.vmlinux_alloc(ei.memsize); } else { - if ((unsigned long)_start < ei.memsize) + /* + * Check if the kernel image (without bss) would overwrite the + * bootwrapper. The device tree has been moved in fdt_init() + * to an area allocated with malloc() (somewhere past _end). + */ + if ((unsigned long)_start < ei.loadsize) fatal("Insufficient memory for kernel at address 0!" - " (_start=%p)\n\r", _start); + " (_start=%p, uncomressed size=%08x)\n\r", + _start, ei.loadsize); + + if ((unsigned long)_end < ei.memsize) + fatal("The final kernel image would overwrite the " + "device tree\n\r"); } /* Finally, gunzip the kernel */ From 04badfd2936333a23e0fc233f31a760d0dc9424f Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Mon, 13 Oct 2008 08:42:00 +0000 Subject: [PATCH 21/53] powerpc/pseries: Validate PFN in pseries_remove_lmb() The pfn of the memory to be removed should be validated prior to attempting to remove the memory. In cases where the probe of a memory section fails during hotplug add, the pfn for the lmb may not be valid. Signed-off-by: Badari Pulavarty Signed-off-by: Nathan Fontenot Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/hotplug-memory.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 140d02a5232a..a623ad256e9e 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -22,6 +22,12 @@ static int pseries_remove_lmb(unsigned long base, unsigned int lmb_size) int ret; start_pfn = base >> PAGE_SHIFT; + + if (!pfn_valid(start_pfn)) { + lmb_remove(base, lmb_size); + return 0; + } + zone = page_zone(pfn_to_page(start_pfn)); /* From bb5e6491cae4c5d6ddfa3e173e22efb35f595949 Mon Sep 17 00:00:00 2001 From: roel kluin Date: Tue, 14 Oct 2008 14:36:31 +0000 Subject: [PATCH 22/53] powerpc: Unsigned speed cannot be negative in udbg_16559.c "unsigned int" speed cannot be negative, it's thus pointless to test if it is. Signed-off-by: Roel Kluin Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/udbg_16550.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c index cb01ebc59387..7b7da8cfd5e8 100644 --- a/arch/powerpc/kernel/udbg_16550.c +++ b/arch/powerpc/kernel/udbg_16550.c @@ -142,7 +142,7 @@ unsigned int udbg_probe_uart_speed(void __iomem *comport, unsigned int clock) speed = (clock / prescaler) / (divisor * 16); /* sanity check */ - if (speed < 0 || speed > (clock / 16)) + if (speed > (clock / 16)) speed = 9600; return speed; From a5598ca0d49821912a5053c05f07fd650671eb6d Mon Sep 17 00:00:00 2001 From: Carl Love Date: Tue, 14 Oct 2008 23:37:01 +0000 Subject: [PATCH 23/53] powerpc/oprofile: Fix mutex locking for cell spu-oprofile The issue is the SPU code is not holding the kernel mutex lock while adding samples to the kernel buffer. This patch creates per SPU buffers to hold the data. Data is added to the buffers from in interrupt context. The data is periodically pushed to the kernel buffer via a new Oprofile function oprofile_put_buff(). The oprofile_put_buff() function is called via a work queue enabling the funtion to acquire the mutex lock. The existing user controls for adjusting the per CPU buffer size is used to control the size of the per SPU buffers. Similarly, overflows of the SPU buffers are reported by incrementing the per CPU buffer stats. This eliminates the need to have architecture specific controls for the per SPU buffers which is not acceptable to the OProfile user tool maintainer. The export of the oprofile add_event_entry() is removed as it is no longer needed given this patch. Note, this patch has not addressed the issue of indexing arrays by the spu number. This still needs to be fixed as the spu numbering is not guarenteed to be 0 to max_num_spus-1. Signed-off-by: Carl Love Signed-off-by: Maynard Johnson Signed-off-by: Arnd Bergmann Acked-by: Acked-by: Robert Richter Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/oprofile/cell/pr_util.h | 13 ++ arch/powerpc/oprofile/cell/spu_profiler.c | 4 +- arch/powerpc/oprofile/cell/spu_task_sync.c | 236 ++++++++++++++++++--- drivers/oprofile/buffer_sync.c | 24 +++ drivers/oprofile/cpu_buffer.c | 15 +- drivers/oprofile/event_buffer.h | 7 + include/linux/oprofile.h | 16 +- 7 files changed, 279 insertions(+), 36 deletions(-) diff --git a/arch/powerpc/oprofile/cell/pr_util.h b/arch/powerpc/oprofile/cell/pr_util.h index 22e4e8d4eb2c..628009c01958 100644 --- a/arch/powerpc/oprofile/cell/pr_util.h +++ b/arch/powerpc/oprofile/cell/pr_util.h @@ -24,6 +24,11 @@ #define SKIP_GENERIC_SYNC 0 #define SYNC_START_ERROR -1 #define DO_GENERIC_SYNC 1 +#define SPUS_PER_NODE 8 +#define DEFAULT_TIMER_EXPIRE (HZ / 10) + +extern struct delayed_work spu_work; +extern int spu_prof_running; struct spu_overlay_info { /* map of sections within an SPU overlay */ unsigned int vma; /* SPU virtual memory address from elf */ @@ -62,6 +67,14 @@ struct vma_to_fileoffset_map { /* map of sections within an SPU program */ }; +struct spu_buffer { + int last_guard_val; + int ctx_sw_seen; + unsigned long *buff; + unsigned int head, tail; +}; + + /* The three functions below are for maintaining and accessing * the vma-to-fileoffset map. */ diff --git a/arch/powerpc/oprofile/cell/spu_profiler.c b/arch/powerpc/oprofile/cell/spu_profiler.c index 380d7e217531..6edaebd5099a 100644 --- a/arch/powerpc/oprofile/cell/spu_profiler.c +++ b/arch/powerpc/oprofile/cell/spu_profiler.c @@ -23,12 +23,11 @@ static u32 *samples; -static int spu_prof_running; +int spu_prof_running; static unsigned int profiling_interval; #define NUM_SPU_BITS_TRBUF 16 #define SPUS_PER_TB_ENTRY 4 -#define SPUS_PER_NODE 8 #define SPU_PC_MASK 0xFFFF @@ -208,6 +207,7 @@ int start_spu_profiling(unsigned int cycles_reset) spu_prof_running = 1; hrtimer_start(&timer, kt, HRTIMER_MODE_REL); + schedule_delayed_work(&spu_work, DEFAULT_TIMER_EXPIRE); return 0; } diff --git a/arch/powerpc/oprofile/cell/spu_task_sync.c b/arch/powerpc/oprofile/cell/spu_task_sync.c index 2a9b4a049329..2949126d28d1 100644 --- a/arch/powerpc/oprofile/cell/spu_task_sync.c +++ b/arch/powerpc/oprofile/cell/spu_task_sync.c @@ -35,7 +35,102 @@ static DEFINE_SPINLOCK(buffer_lock); static DEFINE_SPINLOCK(cache_lock); static int num_spu_nodes; int spu_prof_num_nodes; -int last_guard_val[MAX_NUMNODES * 8]; + +struct spu_buffer spu_buff[MAX_NUMNODES * SPUS_PER_NODE]; +struct delayed_work spu_work; +static unsigned max_spu_buff; + +static void spu_buff_add(unsigned long int value, int spu) +{ + /* spu buff is a circular buffer. Add entries to the + * head. Head is the index to store the next value. + * The buffer is full when there is one available entry + * in the queue, i.e. head and tail can't be equal. + * That way we can tell the difference between the + * buffer being full versus empty. + * + * ASSUPTION: the buffer_lock is held when this function + * is called to lock the buffer, head and tail. + */ + int full = 1; + + if (spu_buff[spu].head >= spu_buff[spu].tail) { + if ((spu_buff[spu].head - spu_buff[spu].tail) + < (max_spu_buff - 1)) + full = 0; + + } else if (spu_buff[spu].tail > spu_buff[spu].head) { + if ((spu_buff[spu].tail - spu_buff[spu].head) + > 1) + full = 0; + } + + if (!full) { + spu_buff[spu].buff[spu_buff[spu].head] = value; + spu_buff[spu].head++; + + if (spu_buff[spu].head >= max_spu_buff) + spu_buff[spu].head = 0; + } else { + /* From the user's perspective make the SPU buffer + * size management/overflow look like we are using + * per cpu buffers. The user uses the same + * per cpu parameter to adjust the SPU buffer size. + * Increment the sample_lost_overflow to inform + * the user the buffer size needs to be increased. + */ + oprofile_cpu_buffer_inc_smpl_lost(); + } +} + +/* This function copies the per SPU buffers to the + * OProfile kernel buffer. + */ +void sync_spu_buff(void) +{ + int spu; + unsigned long flags; + int curr_head; + + for (spu = 0; spu < num_spu_nodes; spu++) { + /* In case there was an issue and the buffer didn't + * get created skip it. + */ + if (spu_buff[spu].buff == NULL) + continue; + + /* Hold the lock to make sure the head/tail + * doesn't change while spu_buff_add() is + * deciding if the buffer is full or not. + * Being a little paranoid. + */ + spin_lock_irqsave(&buffer_lock, flags); + curr_head = spu_buff[spu].head; + spin_unlock_irqrestore(&buffer_lock, flags); + + /* Transfer the current contents to the kernel buffer. + * data can still be added to the head of the buffer. + */ + oprofile_put_buff(spu_buff[spu].buff, + spu_buff[spu].tail, + curr_head, max_spu_buff); + + spin_lock_irqsave(&buffer_lock, flags); + spu_buff[spu].tail = curr_head; + spin_unlock_irqrestore(&buffer_lock, flags); + } + +} + +static void wq_sync_spu_buff(struct work_struct *work) +{ + /* move data from spu buffers to kernel buffer */ + sync_spu_buff(); + + /* only reschedule if profiling is not done */ + if (spu_prof_running) + schedule_delayed_work(&spu_work, DEFAULT_TIMER_EXPIRE); +} /* Container for caching information about an active SPU task. */ struct cached_info { @@ -305,14 +400,21 @@ static int process_context_switch(struct spu *spu, unsigned long objectId) /* Record context info in event buffer */ spin_lock_irqsave(&buffer_lock, flags); - add_event_entry(ESCAPE_CODE); - add_event_entry(SPU_CTX_SWITCH_CODE); - add_event_entry(spu->number); - add_event_entry(spu->pid); - add_event_entry(spu->tgid); - add_event_entry(app_dcookie); - add_event_entry(spu_cookie); - add_event_entry(offset); + spu_buff_add(ESCAPE_CODE, spu->number); + spu_buff_add(SPU_CTX_SWITCH_CODE, spu->number); + spu_buff_add(spu->number, spu->number); + spu_buff_add(spu->pid, spu->number); + spu_buff_add(spu->tgid, spu->number); + spu_buff_add(app_dcookie, spu->number); + spu_buff_add(spu_cookie, spu->number); + spu_buff_add(offset, spu->number); + + /* Set flag to indicate SPU PC data can now be written out. If + * the SPU program counter data is seen before an SPU context + * record is seen, the postprocessing will fail. + */ + spu_buff[spu->number].ctx_sw_seen = 1; + spin_unlock_irqrestore(&buffer_lock, flags); smp_wmb(); /* insure spu event buffer updates are written */ /* don't want entries intermingled... */ @@ -360,6 +462,47 @@ static int number_of_online_nodes(void) return nodes; } +static int oprofile_spu_buff_create(void) +{ + int spu; + + max_spu_buff = oprofile_get_cpu_buffer_size(); + + for (spu = 0; spu < num_spu_nodes; spu++) { + /* create circular buffers to store the data in. + * use locks to manage accessing the buffers + */ + spu_buff[spu].head = 0; + spu_buff[spu].tail = 0; + + /* + * Create a buffer for each SPU. Can't reliably + * create a single buffer for all spus due to not + * enough contiguous kernel memory. + */ + + spu_buff[spu].buff = kzalloc((max_spu_buff + * sizeof(unsigned long)), + GFP_KERNEL); + + if (!spu_buff[spu].buff) { + printk(KERN_ERR "SPU_PROF: " + "%s, line %d: oprofile_spu_buff_create " + "failed to allocate spu buffer %d.\n", + __func__, __LINE__, spu); + + /* release the spu buffers that have been allocated */ + while (spu >= 0) { + kfree(spu_buff[spu].buff); + spu_buff[spu].buff = 0; + spu--; + } + return -ENOMEM; + } + } + return 0; +} + /* The main purpose of this function is to synchronize * OProfile with SPUFS by registering to be notified of * SPU task switches. @@ -372,20 +515,35 @@ static int number_of_online_nodes(void) */ int spu_sync_start(void) { - int k; + int spu; int ret = SKIP_GENERIC_SYNC; int register_ret; unsigned long flags = 0; spu_prof_num_nodes = number_of_online_nodes(); num_spu_nodes = spu_prof_num_nodes * 8; + INIT_DELAYED_WORK(&spu_work, wq_sync_spu_buff); + + /* create buffer for storing the SPU data to put in + * the kernel buffer. + */ + ret = oprofile_spu_buff_create(); + if (ret) + goto out; spin_lock_irqsave(&buffer_lock, flags); - add_event_entry(ESCAPE_CODE); - add_event_entry(SPU_PROFILING_CODE); - add_event_entry(num_spu_nodes); + for (spu = 0; spu < num_spu_nodes; spu++) { + spu_buff_add(ESCAPE_CODE, spu); + spu_buff_add(SPU_PROFILING_CODE, spu); + spu_buff_add(num_spu_nodes, spu); + } spin_unlock_irqrestore(&buffer_lock, flags); + for (spu = 0; spu < num_spu_nodes; spu++) { + spu_buff[spu].ctx_sw_seen = 0; + spu_buff[spu].last_guard_val = 0; + } + /* Register for SPU events */ register_ret = spu_switch_event_register(&spu_active); if (register_ret) { @@ -393,8 +551,6 @@ int spu_sync_start(void) goto out; } - for (k = 0; k < (MAX_NUMNODES * 8); k++) - last_guard_val[k] = 0; pr_debug("spu_sync_start -- running.\n"); out: return ret; @@ -446,13 +602,20 @@ void spu_sync_buffer(int spu_num, unsigned int *samples, * use. We need to discard samples taken during the time * period which an overlay occurs (i.e., guard value changes). */ - if (grd_val && grd_val != last_guard_val[spu_num]) { - last_guard_val[spu_num] = grd_val; + if (grd_val && grd_val != spu_buff[spu_num].last_guard_val) { + spu_buff[spu_num].last_guard_val = grd_val; /* Drop the rest of the samples. */ break; } - add_event_entry(file_offset | spu_num_shifted); + /* We must ensure that the SPU context switch has been written + * out before samples for the SPU. Otherwise, the SPU context + * information is not available and the postprocessing of the + * SPU PC will fail with no available anonymous map information. + */ + if (spu_buff[spu_num].ctx_sw_seen) + spu_buff_add((file_offset | spu_num_shifted), + spu_num); } spin_unlock(&buffer_lock); out: @@ -463,20 +626,41 @@ out: int spu_sync_stop(void) { unsigned long flags = 0; - int ret = spu_switch_event_unregister(&spu_active); - if (ret) { + int ret; + int k; + + ret = spu_switch_event_unregister(&spu_active); + + if (ret) printk(KERN_ERR "SPU_PROF: " - "%s, line %d: spu_switch_event_unregister returned %d\n", - __func__, __LINE__, ret); - goto out; - } + "%s, line %d: spu_switch_event_unregister " \ + "returned %d\n", + __func__, __LINE__, ret); + + /* flush any remaining data in the per SPU buffers */ + sync_spu_buff(); spin_lock_irqsave(&cache_lock, flags); ret = release_cached_info(RELEASE_ALL); spin_unlock_irqrestore(&cache_lock, flags); -out: + + /* remove scheduled work queue item rather then waiting + * for every queued entry to execute. Then flush pending + * system wide buffer to event buffer. + */ + cancel_delayed_work(&spu_work); + + for (k = 0; k < num_spu_nodes; k++) { + spu_buff[k].ctx_sw_seen = 0; + + /* + * spu_sys_buff will be null if there was a problem + * allocating the buffer. Only delete if it exists. + */ + kfree(spu_buff[k].buff); + spu_buff[k].buff = 0; + } pr_debug("spu_sync_stop -- done.\n"); return ret; } - diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c index ed982273fb8b..37681700b61a 100644 --- a/drivers/oprofile/buffer_sync.c +++ b/drivers/oprofile/buffer_sync.c @@ -628,3 +628,27 @@ void sync_buffer(int cpu) mutex_unlock(&buffer_mutex); } + +/* The function can be used to add a buffer worth of data directly to + * the kernel buffer. The buffer is assumed to be a circular buffer. + * Take the entries from index start and end at index end, wrapping + * at max_entries. + */ +void oprofile_put_buff(unsigned long *buf, unsigned int start, + unsigned int stop, unsigned int max) +{ + int i; + + i = start; + + mutex_lock(&buffer_mutex); + while (i != stop) { + add_event_entry(buf[i++]); + + if (i >= max) + i = 0; + } + + mutex_unlock(&buffer_mutex); +} + diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c index e1bd5a937f6c..7ba39fe20a8a 100644 --- a/drivers/oprofile/cpu_buffer.c +++ b/drivers/oprofile/cpu_buffer.c @@ -38,13 +38,26 @@ static int work_enabled; void free_cpu_buffers(void) { int i; - + for_each_online_cpu(i) { vfree(per_cpu(cpu_buffer, i).buffer); per_cpu(cpu_buffer, i).buffer = NULL; } } +unsigned long oprofile_get_cpu_buffer_size(void) +{ + return fs_cpu_buffer_size; +} + +void oprofile_cpu_buffer_inc_smpl_lost(void) +{ + struct oprofile_cpu_buffer *cpu_buf + = &__get_cpu_var(cpu_buffer); + + cpu_buf->sample_lost_overflow++; +} + int alloc_cpu_buffers(void) { int i; diff --git a/drivers/oprofile/event_buffer.h b/drivers/oprofile/event_buffer.h index 5076ed1ebd8f..84bf324c5771 100644 --- a/drivers/oprofile/event_buffer.h +++ b/drivers/oprofile/event_buffer.h @@ -17,6 +17,13 @@ int alloc_event_buffer(void); void free_event_buffer(void); +/** + * Add data to the event buffer. + * The data passed is free-form, but typically consists of + * file offsets, dcookies, context information, and ESCAPE codes. + */ +void add_event_entry(unsigned long data); + /* wake up the process sleeping on the event file */ void wake_up_buffer_waiter(void); diff --git a/include/linux/oprofile.h b/include/linux/oprofile.h index bcb8f725427c..5231861f357d 100644 --- a/include/linux/oprofile.h +++ b/include/linux/oprofile.h @@ -85,13 +85,6 @@ int oprofile_arch_init(struct oprofile_operations * ops); */ void oprofile_arch_exit(void); -/** - * Add data to the event buffer. - * The data passed is free-form, but typically consists of - * file offsets, dcookies, context information, and ESCAPE codes. - */ -void add_event_entry(unsigned long data); - /** * Add a sample. This may be called from any context. Pass * smp_processor_id() as cpu. @@ -162,5 +155,14 @@ int oprofilefs_ulong_from_user(unsigned long * val, char const __user * buf, siz /** lock for read/write safety */ extern spinlock_t oprofilefs_lock; + +/** + * Add the contents of a circular buffer to the event buffer. + */ +void oprofile_put_buff(unsigned long *buf, unsigned int start, + unsigned int stop, unsigned int max); + +unsigned long oprofile_get_cpu_buffer_size(void); +void oprofile_cpu_buffer_inc_smpl_lost(void); #endif /* OPROFILE_H */ From e81703724a966120ace6504c993bda9e084cbf3e Mon Sep 17 00:00:00 2001 From: Jon Tollefson Date: Thu, 16 Oct 2008 18:59:43 +0000 Subject: [PATCH 24/53] powerpc/numa: Make memory reserve code more robust Adjust amount to reserve based on previous nodes for reserves spanning multiple nodes. Check if the node active range is empty before attempting to pass the reserve to bootmem. In practice the range shouldn't be empty, but to be sure we check. Signed-off-by: Jon Tollefson Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/numa.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 6cf5c71c431f..195bfcd08959 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -116,6 +116,7 @@ static int __init get_active_region_work_fn(unsigned long start_pfn, /* * get_node_active_region - Return active region containing start_pfn + * Active range returned is empty if none found. * @start_pfn: The page to return the region for. * @node_ar: Returned set to the active region containing start_pfn */ @@ -126,6 +127,7 @@ static void __init get_node_active_region(unsigned long start_pfn, node_ar->nid = nid; node_ar->start_pfn = start_pfn; + node_ar->end_pfn = start_pfn; work_with_active_regions(nid, get_active_region_work_fn, node_ar); } @@ -933,18 +935,20 @@ void __init do_init_bootmem(void) struct node_active_region node_ar; get_node_active_region(start_pfn, &node_ar); - while (start_pfn < end_pfn) { + while (start_pfn < end_pfn && + node_ar.start_pfn < node_ar.end_pfn) { + unsigned long reserve_size = size; /* * if reserved region extends past active region * then trim size to active region */ if (end_pfn > node_ar.end_pfn) - size = (node_ar.end_pfn << PAGE_SHIFT) + reserve_size = (node_ar.end_pfn << PAGE_SHIFT) - (start_pfn << PAGE_SHIFT); - dbg("reserve_bootmem %lx %lx nid=%d\n", physbase, size, - node_ar.nid); + dbg("reserve_bootmem %lx %lx nid=%d\n", physbase, + reserve_size, node_ar.nid); reserve_bootmem_node(NODE_DATA(node_ar.nid), physbase, - size, BOOTMEM_DEFAULT); + reserve_size, BOOTMEM_DEFAULT); /* * if reserved region is contained in the active region * then done. @@ -959,6 +963,7 @@ void __init do_init_bootmem(void) */ start_pfn = node_ar.end_pfn; physbase = start_pfn << PAGE_SHIFT; + size = size - reserve_size; get_node_active_region(start_pfn, &node_ar); } From 59fd6b8cc0975b88e35f6ca2318b8cee77d3a508 Mon Sep 17 00:00:00 2001 From: Mike Ditto Date: Fri, 17 Oct 2008 09:27:51 +0000 Subject: [PATCH 25/53] powerpc: Fix boot wrapper memcmp() called with zero length argument I noticed, when trying to use, e.g., node = find_node_by_prop_value(prev, "booleanprop", "", 0)) to search for all nodes with a certain boolean property, that memcmp() returns garbage when comparing zero bytes. It should return zero. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/boot/string.S | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/boot/string.S b/arch/powerpc/boot/string.S index 643e4cb2f11d..acc9428f2789 100644 --- a/arch/powerpc/boot/string.S +++ b/arch/powerpc/boot/string.S @@ -235,7 +235,7 @@ memchr: .globl memcmp memcmp: cmpwi 0,r5,0 - blelr + ble 2f mtctr r5 addi r6,r3,-1 addi r4,r4,-1 @@ -244,6 +244,8 @@ memcmp: subf. r3,r0,r3 bdnzt 2,1b blr +2: li r3,0 + blr /* From a4292d7ae6fabcdbc41c3e0f0eb790a1429b985f Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 17 Oct 2008 19:12:07 +0000 Subject: [PATCH 26/53] powerpc: Add missing cuImage.initrd.% target This target is needed to build cuImages with an embedded ramdisk image. Signed-off-by: Grant Likely Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/boot/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 47603652e7f1..8fc6d72849ae 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -321,6 +321,9 @@ $(obj)/zImage.iseries: vmlinux $(obj)/uImage: vmlinux $(wrapperbits) $(call if_changed,wrap,uboot) +$(obj)/cuImage.initrd.%: vmlinux $(obj)/%.dtb $(wrapperbits) + $(call if_changed,wrap,cuboot-$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz) + $(obj)/cuImage.%: vmlinux $(obj)/%.dtb $(wrapperbits) $(call if_changed,wrap,cuboot-$*,,$(obj)/$*.dtb) From 0721357d4d04563b6e5c7ffd6b5685df275d5ff9 Mon Sep 17 00:00:00 2001 From: Jon Smirl Date: Mon, 20 Oct 2008 02:13:15 +0000 Subject: [PATCH 27/53] of: Format string bug in drivers/of/of_i2c.c Format string bug. Not exploitable, as this is only writable by root, but worth fixing all the same. See 326f6a5c9c9e1a62aec37bdc0c3f8d53adabe77b Signed-off-by: Benjamin Herrenschmidt --- drivers/of/of_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index 6a98dc8aa30b..24bbef777c19 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c @@ -41,7 +41,7 @@ void of_register_i2c_devices(struct i2c_adapter *adap, info.addr = *addr; - request_module(info.type); + request_module("%s", info.type); result = i2c_new_device(adap, &info); if (result == NULL) { From a3ba68f969b2407b6809a840f6ff45ab0eb06f84 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 20 Oct 2008 03:16:55 +0000 Subject: [PATCH 28/53] powerpc: Fix build issue with CONFIG_RELOCATABLE=y There are two issues when we enable CONFIG_RELOCATABLE. The first is due to the fact that phys_addr_t is now defined in linux/types.h. The second is due to the fact that the DMA code changes expose memstart_addr to prom_init.c Signed-off-by: Kumar Gala Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/page.h | 5 ++++- arch/powerpc/kernel/prom_init_check.sh | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h index 64e144505f65..120f4d494257 100644 --- a/arch/powerpc/include/asm/page.h +++ b/arch/powerpc/include/asm/page.h @@ -12,7 +12,9 @@ #include #include -#include +#ifndef __ASSEMBLY__ +#include +#endif /* * On PPC32 page size is 4K. For PPC64 we support either 4K or 64K software @@ -73,6 +75,7 @@ #if defined(CONFIG_RELOCATABLE) #ifndef __ASSEMBLY__ + extern phys_addr_t memstart_addr; extern phys_addr_t kernstart_addr; #endif diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh index 2c7e8e87f770..ea3a2ec03ffa 100644 --- a/arch/powerpc/kernel/prom_init_check.sh +++ b/arch/powerpc/kernel/prom_init_check.sh @@ -20,7 +20,7 @@ WHITELIST="add_reloc_offset __bss_start __bss_stop copy_and_flush _end enter_prom memcpy memset reloc_offset __secondary_hold __secondary_hold_acknowledge __secondary_hold_spinloop __start strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224 -reloc_got2 kernstart_addr" +reloc_got2 kernstart_addr memstart_addr" NM="$1" OBJ="$2" From dbc1c5c250cbedccf3571597d156e581e34b2944 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 20 Oct 2008 08:03:46 +0000 Subject: [PATCH 29/53] powerpc: Remove Kconfig support for PPC_MERGE There are no users of PPC_MERGE in tree so we can get rid of it. It was a hold over from the arch/ppc days. Signed-off-by: Kumar Gala Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/Kconfig | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index c171f5bcf258..bbe149c26518 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -19,9 +19,6 @@ config WORD_SIZE default 64 if PPC64 default 32 if !PPC64 -config PPC_MERGE - def_bool y - config MMU bool default y From ed7b2144bcc87b2b097553f15a2f96e18ede21b0 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Mon, 20 Oct 2008 15:37:03 +0000 Subject: [PATCH 30/53] powerpc: Find and destroy possible stale kernel added properties 64 bit powerpc requires the kexec user space tools avoid overwriting the static kernel image and translation hash table when choosing where to put memory image data because it copies the data into place using the kernels virtual memory system. Kexec userspace determines these and other areas blocked by reading properties the kernel adds, but does not filter these properties when creating the device tree for the next kernel. When the second kernel tries to add its values for these properties, the export via /proc/device-tree is hidden by the pre-existing but stale values from the flat tree. Kexec userspace reads the old property, allocates the new kernel at the old kernel's end, and gets rejected by the overlap check. Search and remove these stale properties before adding the new values. Signed-off-by: Milton Miller Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/machine_kexec_64.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index a168514d8609..4bd8b4f5e70d 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c @@ -312,11 +312,24 @@ static struct property kernel_end_prop = { static void __init export_htab_values(void) { struct device_node *node; + struct property *prop; node = of_find_node_by_path("/chosen"); if (!node) return; + /* remove any stale propertys so ours can be found */ + prop = of_find_property(node, kernel_end_prop.name, NULL); + if (prop) + prom_remove_property(node, prop); + prop = of_find_property(node, htab_base_prop.name, NULL); + if (prop) + prom_remove_property(node, prop); + prop = of_find_property(node, htab_size_prop.name, NULL); + if (prop) + prom_remove_property(node, prop); + + /* information needed by userspace when using default_machine_kexec */ kernel_end = __pa(_end); prom_add_property(node, &kernel_end_prop); From 6a75a6b8e85e92cc774d42a4e113c76c30b5a539 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Mon, 20 Oct 2008 15:37:03 +0000 Subject: [PATCH 31/53] powerpc: Use cpu_thread_in_core in smp_init for of_spin_map We used to assume that even numbered threads were the primary threads, ie those that would be listed and started as a cpu from open firmware. Replace a left over is even (% 2) check with a check for it being a primary thread and update the comments. Tested with a debug print on pseries, identical code found for cell. Signed-off-by: Milton Miller Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/cell/smp.c | 10 +++------- arch/powerpc/platforms/pseries/smp.c | 13 ++++--------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c index efb3964457b1..c0d86e1f56ea 100644 --- a/arch/powerpc/platforms/cell/smp.c +++ b/arch/powerpc/platforms/cell/smp.c @@ -54,8 +54,8 @@ #endif /* - * The primary thread of each non-boot processor is recorded here before - * smp init. + * The Primary thread of each non-boot processor was started from the OF client + * interface by prom_hold_cpus and is spinning on secondary_hold_spinloop. */ static cpumask_t of_spin_map; @@ -208,11 +208,7 @@ void __init smp_init_cell(void) /* Mark threads which are still spinning in hold loops. */ if (cpu_has_feature(CPU_FTR_SMT)) { for_each_present_cpu(i) { - if (i % 2 == 0) - /* - * Even-numbered logical cpus correspond to - * primary threads. - */ + if (cpu_thread_in_core(i) == 0) cpu_set(i, of_spin_map); } } else { diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index e00f96baa381..1a231c389ba0 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -52,8 +52,8 @@ /* - * The primary thread of each non-boot processor is recorded here before - * smp init. + * The Primary thread of each non-boot processor was started from the OF client + * interface by prom_hold_cpus and is spinning on secondary_hold_spinloop. */ static cpumask_t of_spin_map; @@ -161,8 +161,7 @@ static void __devinit smp_pSeries_kick_cpu(int nr) static int smp_pSeries_cpu_bootable(unsigned int nr) { /* Special case - we inhibit secondary thread startup - * during boot if the user requests it. Odd-numbered - * cpus are assumed to be secondary threads. + * during boot if the user requests it. */ if (system_state < SYSTEM_RUNNING && cpu_has_feature(CPU_FTR_SMT) && @@ -199,11 +198,7 @@ static void __init smp_init_pseries(void) /* Mark threads which are still spinning in hold loops. */ if (cpu_has_feature(CPU_FTR_SMT)) { for_each_present_cpu(i) { - if (i % 2 == 0) - /* - * Even-numbered logical cpus correspond to - * primary threads. - */ + if (cpu_thread_in_core(i) == 0) cpu_set(i, of_spin_map); } } else { From fe55249d17f7979cf9bbc58e38e9ceaf1918b415 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Mon, 20 Oct 2008 15:37:04 +0000 Subject: [PATCH 32/53] powerpc: Always trim numa memory to lmb_end_of_DRAM() numa_enforce_memory_limit tried to be smart and only call lmb_end_of_DRAM when a memory limit was set via mem= on the command line. However, the early boot code will also limit memory added to the lmb system when iommu=off is specified. When this happens, the page allocator is given pages not in the linear mapping and this results in a fatal data reference to the unmapped page. Signed-off-by: Milton Miller Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/numa.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 195bfcd08959..eb505ad34a85 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -528,12 +528,10 @@ static unsigned long __init numa_enforce_memory_limit(unsigned long start, /* * We use lmb_end_of_DRAM() in here instead of memory_limit because * we've already adjusted it for the limit and it takes care of - * having memory holes below the limit. + * having memory holes below the limit. Also, in the case of + * iommu_is_off, memory_limit is not set but is implicitly enforced. */ - if (! memory_limit) - return size; - if (start + size <= lmb_end_of_DRAM()) return size; From 0dcd440120ef12879ff34fc78d7e4abf171c79e4 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 20 Oct 2008 17:42:42 +0000 Subject: [PATCH 33/53] powerpc: Revert CHRP boot wrapper to real-base = 12MB on 32-bit Commit 9b09c6d909dfd8de96b99b9b9c808b94b0a71614 ("powerpc: Change the default link address for pSeries zImage kernels") changed the real-base value in the CHRP note added by addnote to the zImage from 12MB to 32MB. It turns out that this causes unnecessary extra reboots on old 32-bit CHRP machines. This therefore adds a -r flag to addnote to allow us to specify what real-base value it should put in the CHRP note, and adjusts the wrapper script to pass -r c00000 to addnote when making a zImage for a CHRP machine. Also, CHRP machines ignore the RPA note, so we don't need to arrange for it to be the same as the kernel's. Signed-off-by: Paul Mackerras Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/boot/addnote.c | 39 ++++++++++++++++++++++++------------- arch/powerpc/boot/wrapper | 5 ++++- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/boot/addnote.c b/arch/powerpc/boot/addnote.c index dcc9ab2ca823..3091d1d21aef 100644 --- a/arch/powerpc/boot/addnote.c +++ b/arch/powerpc/boot/addnote.c @@ -11,7 +11,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * Usage: addnote zImage [note.elf] + * Usage: addnote [-r realbase] zImage [note.elf] * * If note.elf is supplied, it is the name of an ELF file that contains * an RPA note to use instead of the built-in one. Alternatively, the @@ -153,18 +153,31 @@ unsigned char *read_rpanote(const char *fname, int *nnp) int main(int ac, char **av) { - int fd, n, i; + int fd, n, i, ai; int ph, ps, np; int nnote, nnote2, ns; unsigned char *rpap; + char *p, *endp; - if (ac != 2 && ac != 3) { - fprintf(stderr, "Usage: %s elf-file [rpanote.elf]\n", av[0]); + ai = 1; + if (ac >= ai + 2 && strcmp(av[ai], "-r") == 0) { + /* process -r realbase */ + p = av[ai + 1]; + descr[1] = strtol(p, &endp, 16); + if (endp == p || *endp != 0) { + fprintf(stderr, "Can't parse -r argument '%s' as hex\n", + p); + exit(1); + } + ai += 2; + } + if (ac != ai + 1 && ac != ai + 2) { + fprintf(stderr, "Usage: %s [-r realbase] elf-file [rpanote.elf]\n", av[0]); exit(1); } - fd = open(av[1], O_RDWR); + fd = open(av[ai], O_RDWR); if (fd < 0) { - perror(av[1]); + perror(av[ai]); exit(1); } @@ -184,12 +197,12 @@ main(int ac, char **av) if (buf[E_IDENT+EI_CLASS] != ELFCLASS32 || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) { fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n", - av[1]); + av[ai]); exit(1); } - if (ac == 3) - rpap = read_rpanote(av[2], &nnote2); + if (ac == ai + 2) + rpap = read_rpanote(av[ai + 1], &nnote2); ph = GET_32BE(buf, E_PHOFF); ps = GET_16BE(buf, E_PHENTSIZE); @@ -202,7 +215,7 @@ main(int ac, char **av) for (i = 0; i < np; ++i) { if (GET_32BE(buf, ph + PH_TYPE) == PT_NOTE) { fprintf(stderr, "%s already has a note entry\n", - av[1]); + av[ai]); exit(0); } ph += ps; @@ -260,18 +273,18 @@ main(int ac, char **av) exit(1); } if (i < n) { - fprintf(stderr, "%s: write truncated\n", av[1]); + fprintf(stderr, "%s: write truncated\n", av[ai]); exit(1); } exit(0); notelf: - fprintf(stderr, "%s does not appear to be an ELF file\n", av[1]); + fprintf(stderr, "%s does not appear to be an ELF file\n", av[ai]); exit(1); nospace: fprintf(stderr, "sorry, I can't find space in %s to put the note\n", - av[1]); + av[ai]); exit(1); } diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index ee0dc41d7c56..f39073511a49 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -306,11 +306,14 @@ fi # post-processing needed for some platforms case "$platform" in -pseries|chrp) +pseries) ${CROSS}objcopy -O binary -j .fakeelf "$kernel" "$ofile".rpanote $objbin/addnote "$ofile" "$ofile".rpanote rm -r "$ofile".rpanote ;; +chrp) + $objbin/addnote -r c00000 "$ofile" + ;; coff) ${CROSS}objcopy -O aixcoff-rs6000 --set-start "$entry" "$ofile" $objbin/hack-coff "$ofile" From 34d81f858a3bdec568bf08c4feb997ccd3d40b94 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Mon, 20 Oct 2008 18:03:18 +0000 Subject: [PATCH 34/53] powerpc: Delete unused prom_strtoul and prom_memparse These functions should have been static, and inspection shows they are no longer used. (We used to parse mem= but we now defer that to early_param). Signed-off-by: Milton Miller Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/prom_init.c | 61 --------------------------------- 1 file changed, 61 deletions(-) diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 2fdbc18ae94a..23e0db203329 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -487,67 +487,6 @@ static int __init prom_setprop(phandle node, const char *nodename, return call_prom("interpret", 1, 1, (u32)(unsigned long) cmd); } -/* We can't use the standard versions because of RELOC headaches. */ -#define isxdigit(c) (('0' <= (c) && (c) <= '9') \ - || ('a' <= (c) && (c) <= 'f') \ - || ('A' <= (c) && (c) <= 'F')) - -#define isdigit(c) ('0' <= (c) && (c) <= '9') -#define islower(c) ('a' <= (c) && (c) <= 'z') -#define toupper(c) (islower(c) ? ((c) - 'a' + 'A') : (c)) - -unsigned long prom_strtoul(const char *cp, const char **endp) -{ - unsigned long result = 0, base = 10, value; - - if (*cp == '0') { - base = 8; - cp++; - if (toupper(*cp) == 'X') { - cp++; - base = 16; - } - } - - while (isxdigit(*cp) && - (value = isdigit(*cp) ? *cp - '0' : toupper(*cp) - 'A' + 10) < base) { - result = result * base + value; - cp++; - } - - if (endp) - *endp = cp; - - return result; -} - -unsigned long prom_memparse(const char *ptr, const char **retptr) -{ - unsigned long ret = prom_strtoul(ptr, retptr); - int shift = 0; - - /* - * We can't use a switch here because GCC *may* generate a - * jump table which won't work, because we're not running at - * the address we're linked at. - */ - if ('G' == **retptr || 'g' == **retptr) - shift = 30; - - if ('M' == **retptr || 'm' == **retptr) - shift = 20; - - if ('K' == **retptr || 'k' == **retptr) - shift = 10; - - if (shift) { - ret <<= shift; - (*retptr)++; - } - - return ret; -} - /* * Early parsing of the command line passed to the kernel, used for * "mem=x" and the options that affect the iommu From ba556ed23c73796efd58ac348cc33773935bb3b9 Mon Sep 17 00:00:00 2001 From: Jason Jin Date: Thu, 16 Oct 2008 17:31:32 +0800 Subject: [PATCH 35/53] powerpc/85xx: Enable enhanced functions for 8536 TSEC Signed-off-by: Jason Jin Signed-off-by: Kumar Gala --- arch/powerpc/boot/dts/mpc8536ds.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/boot/dts/mpc8536ds.dts b/arch/powerpc/boot/dts/mpc8536ds.dts index 93fdd99901b6..dce2f65bf92a 100644 --- a/arch/powerpc/boot/dts/mpc8536ds.dts +++ b/arch/powerpc/boot/dts/mpc8536ds.dts @@ -180,7 +180,7 @@ enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; - model = "TSEC"; + model = "eTSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; @@ -193,7 +193,7 @@ enet1: ethernet@26000 { cell-index = <1>; device_type = "network"; - model = "TSEC"; + model = "eTSEC"; compatible = "gianfar"; reg = <0x26000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; From 13690332a315128ba8936297137d33aff5b2ad7b Mon Sep 17 00:00:00 2001 From: Ed Swarthout Date: Fri, 17 Oct 2008 00:41:32 -0500 Subject: [PATCH 36/53] powerpc/85xx: Fix mpc8536ds dma interrupt numbers Signed-off-by: Ed Swarthout Signed-off-by: Kumar Gala --- arch/powerpc/boot/dts/mpc8536ds.dts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/boot/dts/mpc8536ds.dts b/arch/powerpc/boot/dts/mpc8536ds.dts index dce2f65bf92a..35db1e5440c7 100644 --- a/arch/powerpc/boot/dts/mpc8536ds.dts +++ b/arch/powerpc/boot/dts/mpc8536ds.dts @@ -109,7 +109,7 @@ reg = <0x0 0x80>; cell-index = <0>; interrupt-parent = <&mpic>; - interrupts = <14 0x2>; + interrupts = <20 2>; }; dma-channel@80 { compatible = "fsl,mpc8536-dma-channel", @@ -117,7 +117,7 @@ reg = <0x80 0x80>; cell-index = <1>; interrupt-parent = <&mpic>; - interrupts = <15 0x2>; + interrupts = <21 2>; }; dma-channel@100 { compatible = "fsl,mpc8536-dma-channel", @@ -125,7 +125,7 @@ reg = <0x100 0x80>; cell-index = <2>; interrupt-parent = <&mpic>; - interrupts = <16 0x2>; + interrupts = <22 2>; }; dma-channel@180 { compatible = "fsl,mpc8536-dma-channel", @@ -133,7 +133,7 @@ reg = <0x180 0x80>; cell-index = <3>; interrupt-parent = <&mpic>; - interrupts = <17 0x2>; + interrupts = <23 2>; }; }; From 0a346dacee18ff69f6162d9860d723a058f47321 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 16 Oct 2008 21:12:00 +0200 Subject: [PATCH 37/53] i2c-cpm: Suppress autoprobing for devices Similar to commit 618b26d52843c0f85b8eb143cf2695d7f6fd072d, also remove automatic probing for this i2c controller. Might need updates to dts files using it. Signed-off-by: Wolfram Sang Acked-by: Jochen Friedrich Acked-by: Jean Delvare Signed-off-by: Kumar Gala --- drivers/i2c/busses/i2c-cpm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index 8164de1f4d72..228f75723063 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -423,7 +423,6 @@ static const struct i2c_adapter cpm_ops = { .owner = THIS_MODULE, .name = "i2c-cpm", .algo = &cpm_i2c_algo, - .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, }; static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm) From fd657efc67dbd70f422285101a50c2e84d03463d Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Sat, 18 Oct 2008 04:23:52 +0400 Subject: [PATCH 38/53] powerpc: Remove device_type = "board_control" properties in .dts files We don't want to encourage the bogus device_type usage. The device type isn't used in the code, so we can simply remove it from the documentation and dts files. Boards should specify proper compatible entries instead. Signed-off-by: Anton Vorontsov Acked-by: David Gibson Signed-off-by: Kumar Gala --- Documentation/powerpc/dts-bindings/fsl/board.txt | 4 ++-- arch/powerpc/boot/dts/mpc832x_mds.dts | 2 +- arch/powerpc/boot/dts/mpc834x_mds.dts | 2 +- arch/powerpc/boot/dts/mpc836x_mds.dts | 2 +- arch/powerpc/boot/dts/mpc8568mds.dts | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Documentation/powerpc/dts-bindings/fsl/board.txt b/Documentation/powerpc/dts-bindings/fsl/board.txt index 74ae6f1cd2d6..81a917ef96e9 100644 --- a/Documentation/powerpc/dts-bindings/fsl/board.txt +++ b/Documentation/powerpc/dts-bindings/fsl/board.txt @@ -2,13 +2,13 @@ Required properties: - - device_type : Should be "board-control" + - compatible : Should be "fsl,-bcsr" - reg : Offset and length of the register set for the device Example: bcsr@f8000000 { - device_type = "board-control"; + compatible = "fsl,mpc8360mds-bcsr"; reg = ; }; diff --git a/arch/powerpc/boot/dts/mpc832x_mds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts index e4cc1768f241..57c595bf1071 100644 --- a/arch/powerpc/boot/dts/mpc832x_mds.dts +++ b/arch/powerpc/boot/dts/mpc832x_mds.dts @@ -60,7 +60,7 @@ }; bcsr@f8000000 { - device_type = "board-control"; + compatible = "fsl,mpc8323mds-bcsr"; reg = <0xf8000000 0x8000>; }; diff --git a/arch/powerpc/boot/dts/mpc834x_mds.dts b/arch/powerpc/boot/dts/mpc834x_mds.dts index 04bfde3ea605..c986c541e9bb 100644 --- a/arch/powerpc/boot/dts/mpc834x_mds.dts +++ b/arch/powerpc/boot/dts/mpc834x_mds.dts @@ -49,7 +49,7 @@ }; bcsr@e2400000 { - device_type = "board-control"; + compatible = "fsl,mpc8349mds-bcsr"; reg = <0xe2400000 0x8000>; }; diff --git a/arch/powerpc/boot/dts/mpc836x_mds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts index 66a12d2631fb..14534d04e4db 100644 --- a/arch/powerpc/boot/dts/mpc836x_mds.dts +++ b/arch/powerpc/boot/dts/mpc836x_mds.dts @@ -69,7 +69,7 @@ }; bcsr@1,0 { - device_type = "board-control"; + compatible = "fsl,mpc8360mds-bcsr"; reg = <1 0 0x8000>; }; }; diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts index a15f10343f53..c80158f7741d 100644 --- a/arch/powerpc/boot/dts/mpc8568mds.dts +++ b/arch/powerpc/boot/dts/mpc8568mds.dts @@ -52,7 +52,7 @@ }; bcsr@f8000000 { - device_type = "board-control"; + compatible = "fsl,mpc8568mds-bcsr"; reg = <0xf8000000 0x8000>; }; From f618ebfcbf9616a0fa9a78f5ecb69762f0fa3c59 Mon Sep 17 00:00:00 2001 From: Wolfgang Ocker Date: Wed, 15 Oct 2008 15:00:47 +0200 Subject: [PATCH 39/53] of/spi: Support specifying chip select as active high via device tree The patch allows to specify that an SPI device needs an active high chip select. Signed-off-by: Wolfgang Ocker Signed-off-by: Kumar Gala --- Documentation/powerpc/booting-without-of.txt | 2 ++ drivers/of/of_spi.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt index de4063cb4fdc..02ea9a971b8e 100644 --- a/Documentation/powerpc/booting-without-of.txt +++ b/Documentation/powerpc/booting-without-of.txt @@ -1917,6 +1917,8 @@ platforms are moved over to use the flattened-device-tree model. inverse clock polarity (CPOL) mode - spi-cpha - (optional) Empty property indicating device requires shifted clock phase (CPHA) mode + - spi-cs-high - (optional) Empty property indicating device requires + chip select active high SPI example for an MPC5200 SPI bus: spi@f00 { diff --git a/drivers/of/of_spi.c b/drivers/of/of_spi.c index b01eec026f68..bed0ed6dcdc1 100644 --- a/drivers/of/of_spi.c +++ b/drivers/of/of_spi.c @@ -61,6 +61,8 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np) spi->mode |= SPI_CPHA; if (of_find_property(nc, "spi-cpol", NULL)) spi->mode |= SPI_CPOL; + if (of_find_property(nc, "spi-cs-high", NULL)) + spi->mode |= SPI_CS_HIGH; /* Device speed */ prop = of_get_property(nc, "spi-max-frequency", &len); From 66eb988406df0f675c3133aedaf2773ba68866ff Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 20 Oct 2008 23:02:26 -0500 Subject: [PATCH 40/53] powerpc/85xx: Move mpc8572ds.dts to address-cells/size-cells = <2> Change the top-level #address-cells and #size-cells to <2> so the mpc8572ds.dts is easier to deal with both a true 32-bit physical or 36-bit physical address space. Signed-off-by: Kumar Gala --- arch/powerpc/boot/dts/mpc8572ds.dts | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/boot/dts/mpc8572ds.dts b/arch/powerpc/boot/dts/mpc8572ds.dts index e124dd18fb5a..cadd4652a695 100644 --- a/arch/powerpc/boot/dts/mpc8572ds.dts +++ b/arch/powerpc/boot/dts/mpc8572ds.dts @@ -13,8 +13,8 @@ / { model = "fsl,MPC8572DS"; compatible = "fsl,MPC8572DS"; - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; aliases { ethernet0 = &enet0; @@ -61,7 +61,6 @@ memory { device_type = "memory"; - reg = <0x0 0x0>; // Filled by U-Boot }; soc8572@ffe00000 { @@ -69,8 +68,8 @@ #size-cells = <1>; device_type = "soc"; compatible = "simple-bus"; - ranges = <0x0 0xffe00000 0x100000>; - reg = <0xffe00000 0x1000>; // CCSRBAR & soc regs, remove once parse code for immrbase fixed + ranges = <0x0 0 0xffe00000 0x100000>; + reg = <0 0xffe00000 0 0x1000>; // CCSRBAR & soc regs, remove once parse code for immrbase fixed bus-frequency = <0>; // Filled out by uboot. memory-controller@2000 { @@ -351,10 +350,10 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xffe08000 0x1000>; + reg = <0 0xffe08000 0 0x1000>; bus-range = <0 255>; - ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x20000000 - 0x1000000 0x0 0x0 0xffc00000 0x0 0x10000>; + ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000 + 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x00010000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; interrupts = <24 2>; @@ -561,10 +560,10 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xffe09000 0x1000>; + reg = <0 0xffe09000 0 0x1000>; bus-range = <0 255>; - ranges = <0x2000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000 - 0x1000000 0x0 0x0 0xffc10000 0x0 0x10000>; + ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000 + 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x00010000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; interrupts = <26 2>; @@ -598,10 +597,10 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xffe0a000 0x1000>; + reg = <0 0xffe0a000 0 0x1000>; bus-range = <0 255>; - ranges = <0x2000000 0x0 0xc0000000 0xc0000000 0x0 0x20000000 - 0x1000000 0x0 0x0 0xffc20000 0x0 0x10000>; + ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000 + 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x00010000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; interrupts = <27 2>; From 442746989d92afc125040e0f29b33602ad94da99 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 17 Oct 2008 22:57:09 +0400 Subject: [PATCH 41/53] powerpc/83xx: Add support for MCU microcontroller in .dts files MCU is an external Freescale MC9S08QG8 microcontroller, mainly used to provide soft power-off function, but also exports two GPIOs (wired to the LEDs and also available from the external headers). Added the MCU on mpc8349emitx, mpc837xrdb and mpc8315erdb boards. Signed-off-by: Anton Vorontsov Signed-off-by: Kumar Gala --- arch/powerpc/boot/dts/mpc8315erdb.dts | 8 ++++++++ arch/powerpc/boot/dts/mpc8349emitx.dts | 8 ++++++++ arch/powerpc/boot/dts/mpc8377_rdb.dts | 8 ++++++++ arch/powerpc/boot/dts/mpc8378_rdb.dts | 8 ++++++++ arch/powerpc/boot/dts/mpc8379_rdb.dts | 8 ++++++++ 5 files changed, 40 insertions(+) diff --git a/arch/powerpc/boot/dts/mpc8315erdb.dts b/arch/powerpc/boot/dts/mpc8315erdb.dts index 7449e54c1a90..6b850670de1d 100644 --- a/arch/powerpc/boot/dts/mpc8315erdb.dts +++ b/arch/powerpc/boot/dts/mpc8315erdb.dts @@ -121,6 +121,14 @@ compatible = "dallas,ds1339"; reg = <0x68>; }; + + mcu_pio: mcu@a { + #gpio-cells = <2>; + compatible = "fsl,mc9s08qg8-mpc8315erdb", + "fsl,mcu-mpc8349emitx"; + reg = <0x0a>; + gpio-controller; + }; }; spi@7000 { diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts index 5cedf373a1d8..87cd8b7b5a2c 100644 --- a/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/arch/powerpc/boot/dts/mpc8349emitx.dts @@ -131,6 +131,14 @@ interrupt-parent = <&ipic>; interrupts = <71 8>; }; + + mcu_pio: mcu@a { + #gpio-cells = <2>; + compatible = "fsl,mc9s08qg8-mpc8349emitx", + "fsl,mcu-mpc8349emitx"; + reg = <0x0a>; + gpio-controller; + }; }; usb@22000 { diff --git a/arch/powerpc/boot/dts/mpc8377_rdb.dts b/arch/powerpc/boot/dts/mpc8377_rdb.dts index 53191ba67aaa..435ef3dd022d 100644 --- a/arch/powerpc/boot/dts/mpc8377_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8377_rdb.dts @@ -121,6 +121,14 @@ compatible = "dallas,ds1339"; reg = <0x68>; }; + + mcu_pio: mcu@a { + #gpio-cells = <2>; + compatible = "fsl,mc9s08qg8-mpc8377erdb", + "fsl,mcu-mpc8349emitx"; + reg = <0x0a>; + gpio-controller; + }; }; i2c@3100 { diff --git a/arch/powerpc/boot/dts/mpc8378_rdb.dts b/arch/powerpc/boot/dts/mpc8378_rdb.dts index 4a09153d160c..b11e68f56a06 100644 --- a/arch/powerpc/boot/dts/mpc8378_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8378_rdb.dts @@ -121,6 +121,14 @@ compatible = "dallas,ds1339"; reg = <0x68>; }; + + mcu_pio: mcu@a { + #gpio-cells = <2>; + compatible = "fsl,mc9s08qg8-mpc8378erdb", + "fsl,mcu-mpc8349emitx"; + reg = <0x0a>; + gpio-controller; + }; }; i2c@3100 { diff --git a/arch/powerpc/boot/dts/mpc8379_rdb.dts b/arch/powerpc/boot/dts/mpc8379_rdb.dts index bbd884ac9dc0..337af6ea26d3 100644 --- a/arch/powerpc/boot/dts/mpc8379_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8379_rdb.dts @@ -121,6 +121,14 @@ compatible = "dallas,ds1339"; reg = <0x68>; }; + + mcu_pio: mcu@a { + #gpio-cells = <2>; + compatible = "fsl,mc9s08qg8-mpc8379erdb", + "fsl,mcu-mpc8349emitx"; + reg = <0x0a>; + gpio-controller; + }; }; i2c@3100 { From 672e806ee103c1709bcdcafabe65ba9c8ab5a63d Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 17 Oct 2008 22:56:59 +0400 Subject: [PATCH 42/53] powerpc/83xx: Add DS1339 RTC support for MPC8349E-mITX boards .dts The RTC is sitting on the I2C2 bus at address 0x68. RTC interrupt signal is connected to the IPIC's EXT2 interrupt line, the line is shared with Vitesse 8201 Ethernet PHY. Signed-off-by: Anton Vorontsov Signed-off-by: Kumar Gala --- arch/powerpc/boot/dts/mpc8349emitx.dts | 8 ++++++++ arch/powerpc/boot/dts/mpc8349emitxgp.dts | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts index 87cd8b7b5a2c..2c9d54a35bc3 100644 --- a/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/arch/powerpc/boot/dts/mpc8349emitx.dts @@ -83,6 +83,14 @@ interrupts = <15 0x8>; interrupt-parent = <&ipic>; dfsrr; + + rtc@68 { + device_type = "rtc"; + compatible = "dallas,ds1339"; + reg = <0x68>; + interrupts = <18 0x8>; + interrupt-parent = <&ipic>; + }; }; spi@7000 { diff --git a/arch/powerpc/boot/dts/mpc8349emitxgp.dts b/arch/powerpc/boot/dts/mpc8349emitxgp.dts index 81ae1d3e9440..fa40647ee62e 100644 --- a/arch/powerpc/boot/dts/mpc8349emitxgp.dts +++ b/arch/powerpc/boot/dts/mpc8349emitxgp.dts @@ -81,6 +81,14 @@ interrupts = <15 0x8>; interrupt-parent = <&ipic>; dfsrr; + + rtc@68 { + device_type = "rtc"; + compatible = "dallas,ds1339"; + reg = <0x68>; + interrupts = <18 0x8>; + interrupt-parent = <&ipic>; + }; }; spi@7000 { From fc362e2e0efd8b652ebfb409a4e43e6189c04f6f Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Mon, 13 Oct 2008 23:12:48 +0000 Subject: [PATCH 43/53] hvc_console: Add a hangup notifier for backends I have added a hangup notifier that can be used by hvc console backends to handle a tty hangup. The default irq hangup notifier calls the notifier_del_irq() for compatibility. Acked-by: Christian Borntraeger Signed-off-by: Hendrik Brueckner Signed-off-by: Benjamin Herrenschmidt --- drivers/char/hvc_console.c | 4 ++-- drivers/char/hvc_console.h | 4 +++- drivers/char/hvc_irq.c | 5 +++++ drivers/char/hvc_iseries.c | 1 + drivers/char/hvc_vio.c | 1 + drivers/char/hvc_xen.c | 1 + drivers/char/virtio_console.c | 1 + 7 files changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index bf70450a49cc..5c9750ed0bc2 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -418,8 +418,8 @@ static void hvc_hangup(struct tty_struct *tty) spin_unlock_irqrestore(&hp->lock, flags); - if (hp->ops->notifier_del) - hp->ops->notifier_del(hp, hp->data); + if (hp->ops->notifier_hangup) + hp->ops->notifier_hangup(hp, hp->data); while(temp_open_count) { --temp_open_count; diff --git a/drivers/char/hvc_console.h b/drivers/char/hvc_console.h index 9790201718ae..ec0e9bb0e5e6 100644 --- a/drivers/char/hvc_console.h +++ b/drivers/char/hvc_console.h @@ -65,9 +65,10 @@ struct hv_ops { int (*get_chars)(uint32_t vtermno, char *buf, int count); int (*put_chars)(uint32_t vtermno, const char *buf, int count); - /* Callbacks for notification. Called in open and close */ + /* Callbacks for notification. Called in open, close and hangup */ int (*notifier_add)(struct hvc_struct *hp, int irq); void (*notifier_del)(struct hvc_struct *hp, int irq); + void (*notifier_hangup)(struct hvc_struct *hp, int irq); }; /* Register a vterm and a slot index for use as a console (console_init) */ @@ -86,6 +87,7 @@ void hvc_kick(void); /* default notifier for irq based notification */ extern int notifier_add_irq(struct hvc_struct *hp, int data); extern void notifier_del_irq(struct hvc_struct *hp, int data); +extern void notifier_hangup_irq(struct hvc_struct *hp, int data); #if defined(CONFIG_XMON) && defined(CONFIG_SMP) diff --git a/drivers/char/hvc_irq.c b/drivers/char/hvc_irq.c index 73a59cdb8947..d09e5688d449 100644 --- a/drivers/char/hvc_irq.c +++ b/drivers/char/hvc_irq.c @@ -42,3 +42,8 @@ void notifier_del_irq(struct hvc_struct *hp, int irq) free_irq(irq, hp); hp->irq_requested = 0; } + +void notifier_hangup_irq(struct hvc_struct *hp, int irq) +{ + notifier_del_irq(hp, irq); +} diff --git a/drivers/char/hvc_iseries.c b/drivers/char/hvc_iseries.c index b71c610fe5ae..b74a2f8ab908 100644 --- a/drivers/char/hvc_iseries.c +++ b/drivers/char/hvc_iseries.c @@ -202,6 +202,7 @@ static struct hv_ops hvc_get_put_ops = { .put_chars = put_chars, .notifier_add = notifier_add_irq, .notifier_del = notifier_del_irq, + .notifier_hangup = notifier_hangup_irq, }; static int __devinit hvc_vio_probe(struct vio_dev *vdev, diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c index 93f3840c1682..019e0b58593d 100644 --- a/drivers/char/hvc_vio.c +++ b/drivers/char/hvc_vio.c @@ -82,6 +82,7 @@ static struct hv_ops hvc_get_put_ops = { .put_chars = hvc_put_chars, .notifier_add = notifier_add_irq, .notifier_del = notifier_del_irq, + .notifier_hangup = notifier_hangup_irq, }; static int __devinit hvc_vio_probe(struct vio_dev *vdev, diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c index 538ceea5e7df..eba999f8598d 100644 --- a/drivers/char/hvc_xen.c +++ b/drivers/char/hvc_xen.c @@ -102,6 +102,7 @@ static struct hv_ops hvc_ops = { .put_chars = write_console, .notifier_add = notifier_add_irq, .notifier_del = notifier_del_irq, + .notifier_hangup = notifier_hangup_irq, }; static int __init xen_init(void) diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index d0f4eb6fdb7f..3fb0d2c88ba5 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -198,6 +198,7 @@ static int __devinit virtcons_probe(struct virtio_device *dev) virtio_cons.put_chars = put_chars; virtio_cons.notifier_add = notifier_add_vio; virtio_cons.notifier_del = notifier_del_vio; + virtio_cons.notifier_hangup = notifier_del_vio; /* The first argument of hvc_alloc() is the virtual console number, so * we use zero. The second argument is the parameter for the From 56ce9e2b2463b3b257098aa966586701d9967f1e Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Mon, 13 Oct 2008 23:12:49 +0000 Subject: [PATCH 44/53] hvc_console: Add tty driver flag TTY_DRIVER_RESET_TERMIOS After a tty hangup() or close() operation, processes might not reset the termio settings to a sane state. In order to reset the termios to its default settings the tty driver flag TTY_DRIVER_RESET_TERMIOS has been added. TTY driver flag description from include/linux/tty_driver.h: TTY_DRIVER_RESET_TERMIOS --- requests the tty layer to reset the termios setting when the last process has closed the device. Used for PTY's, in particular. Acked-by: Christian Borntraeger Signed-off-by: Hendrik Brueckner Signed-off-by: Benjamin Herrenschmidt --- drivers/char/hvc_console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 5c9750ed0bc2..c9d16665c960 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -796,7 +796,7 @@ static int hvc_init(void) drv->minor_start = HVC_MINOR; drv->type = TTY_DRIVER_TYPE_SYSTEM; drv->init_termios = tty_std_termios; - drv->flags = TTY_DRIVER_REAL_RAW; + drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS; tty_set_operations(drv, &hvc_ops); /* Always start the kthread because there can be hotplug vty adapters From 3feebbb5492e9e463467cefb633e23a3dfcec132 Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Mon, 13 Oct 2008 23:12:50 +0000 Subject: [PATCH 45/53] hvc_console: Fix loop if put_char() returns 0 If put_char() routine of a hvc console backend returns 0, then the hvc console starts looping in the following scenarios: 1. hvc_console_print() If put_char() returns 0 then the while loop may loop forever. I have added the missing check for 0 to throw away console messages. 2. khvcd may loop: The thread calls hvc_poll() --> hvc_push()... if there are still buffered data then the HVC_POLL_WRITE bit is set and causes the khvcd thread to loop (if yield() returns immediately). However, instead of looping, the khvcd thread could sleep for MIN_TIMEOUT (doing the same as for get_chars()). The MIN_TIMEOUT is set if hvc_push() was not able to write data to the backend. If data has been written, the timeout is set to 0 to immediately re-schedule hvc_poll(). Reviewed-by: Christian Borntraeger Tested-by: Christian Borntraeger (virtio_console) Signed-off-by: Hendrik Brueckner Signed-off-by: Benjamin Herrenschmidt --- drivers/char/hvc_console.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index c9d16665c960..3650c904401e 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -161,7 +161,7 @@ static void hvc_console_print(struct console *co, const char *b, } } else { r = cons_ops[index]->put_chars(vtermnos[index], c, i); - if (r < 0) { + if (r <= 0) { /* throw away chars on error */ i = 0; } else if (r > 0) { @@ -431,7 +431,7 @@ static void hvc_hangup(struct tty_struct *tty) * Push buffered characters whether they were just recently buffered or waiting * on a blocked hypervisor. Call this function with hp->lock held. */ -static void hvc_push(struct hvc_struct *hp) +static int hvc_push(struct hvc_struct *hp) { int n; @@ -439,7 +439,7 @@ static void hvc_push(struct hvc_struct *hp) if (n <= 0) { if (n == 0) { hp->do_wakeup = 1; - return; + return 0; } /* throw away output on error; this happens when there is no session connected to the vterm. */ @@ -450,6 +450,8 @@ static void hvc_push(struct hvc_struct *hp) memmove(hp->outbuf, hp->outbuf + n, hp->n_outbuf); else hp->do_wakeup = 1; + + return n; } static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count) @@ -538,16 +540,20 @@ int hvc_poll(struct hvc_struct *hp) char buf[N_INBUF] __ALIGNED__; unsigned long flags; int read_total = 0; + int written_total = 0; spin_lock_irqsave(&hp->lock, flags); /* Push pending writes */ if (hp->n_outbuf > 0) - hvc_push(hp); + written_total = hvc_push(hp); /* Reschedule us if still some write pending */ - if (hp->n_outbuf > 0) + if (hp->n_outbuf > 0) { poll_mask |= HVC_POLL_WRITE; + /* If hvc_push() was not able to write, sleep a few msecs */ + timeout = (written_total) ? 0 : MIN_TIMEOUT; + } /* No tty attached, just skip */ tty = hp->tty; @@ -659,10 +665,6 @@ static int khvcd(void *unused) poll_mask |= HVC_POLL_READ; if (hvc_kicked) continue; - if (poll_mask & HVC_POLL_WRITE) { - yield(); - continue; - } set_current_state(TASK_INTERRUPTIBLE); if (!hvc_kicked) { if (poll_mask == 0) From febde3711992a64ea83a47a719f68a90c4b0927a Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Tue, 14 Oct 2008 05:02:09 +0000 Subject: [PATCH 46/53] hvc_console: Add support for tty window resizing The patch provides the hvc_resize() function to update the terminal window dimensions (struct winsize) for a specified hvc console. The function stores the new window size and schedules a function that finally updates the tty winsize and signals the change to user space (SIGWINCH). Because the winsize update must acquire a mutex and might sleep, the function is scheduled instead of being called from hvc_poll() or khvcd. This patch uses the tty_do_resize() routine from the tty layer. A pending resize work is canceled in hvc_close() and hvc_hangup(). Signed-off-by: Hendrik Brueckner Signed-off-by: Benjamin Herrenschmidt --- drivers/char/hvc_console.c | 58 ++++++++++++++++++++++++++++++++++++++ drivers/char/hvc_console.h | 6 ++++ 2 files changed, 64 insertions(+) diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 3650c904401e..2d256dc80529 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -374,6 +374,9 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) if (hp->ops->notifier_del) hp->ops->notifier_del(hp, hp->data); + /* cancel pending tty resize work */ + cancel_work_sync(&hp->tty_resize); + /* * Chain calls chars_in_buffer() and returns immediately if * there is no buffered data otherwise sleeps on a wait queue @@ -399,6 +402,9 @@ static void hvc_hangup(struct tty_struct *tty) if (!hp) return; + /* cancel pending tty resize work */ + cancel_work_sync(&hp->tty_resize); + spin_lock_irqsave(&hp->lock, flags); /* @@ -494,6 +500,39 @@ static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count return written; } +/** + * hvc_set_winsz() - Resize the hvc tty terminal window. + * @work: work structure. + * + * The routine shall not be called within an atomic context because it + * might sleep. + * + * Locking: hp->lock + */ +static void hvc_set_winsz(struct work_struct *work) +{ + struct hvc_struct *hp; + unsigned long hvc_flags; + struct tty_struct *tty; + struct winsize ws; + + hp = container_of(work, struct hvc_struct, tty_resize); + if (!hp) + return; + + spin_lock_irqsave(&hp->lock, hvc_flags); + if (!hp->tty) { + spin_unlock_irqrestore(&hp->lock, hvc_flags); + return; + } + ws = hp->ws; + tty = tty_kref_get(hp->tty); + spin_unlock_irqrestore(&hp->lock, hvc_flags); + + tty_do_resize(tty, tty, &ws); + tty_kref_put(tty); +} + /* * This is actually a contract between the driver and the tty layer outlining * how much write room the driver can guarantee will be sent OR BUFFERED. This @@ -638,6 +677,24 @@ int hvc_poll(struct hvc_struct *hp) } EXPORT_SYMBOL_GPL(hvc_poll); +/** + * hvc_resize() - Update terminal window size information. + * @hp: HVC console pointer + * @ws: Terminal window size structure + * + * Stores the specified window size information in the hvc structure of @hp. + * The function schedule the tty resize update. + * + * Locking: Locking free; the function MUST be called holding hp->lock + */ +void hvc_resize(struct hvc_struct *hp, struct winsize ws) +{ + if ((hp->ws.ws_row != ws.ws_row) || (hp->ws.ws_col != ws.ws_col)) { + hp->ws = ws; + schedule_work(&hp->tty_resize); + } +} + /* * This kthread is either polling or interrupt driven. This is determined by * calling hvc_poll() who determines whether a console adapter support @@ -720,6 +777,7 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int data, kref_init(&hp->kref); + INIT_WORK(&hp->tty_resize, hvc_set_winsz); spin_lock_init(&hp->lock); spin_lock(&hvc_structs_lock); diff --git a/drivers/char/hvc_console.h b/drivers/char/hvc_console.h index ec0e9bb0e5e6..e3359f3c9b2a 100644 --- a/drivers/char/hvc_console.h +++ b/drivers/char/hvc_console.h @@ -27,6 +27,7 @@ #ifndef HVC_CONSOLE_H #define HVC_CONSOLE_H #include +#include /* * This is the max number of console adapters that can/will be found as @@ -56,6 +57,8 @@ struct hvc_struct { struct hv_ops *ops; int irq_requested; int data; + struct winsize ws; + struct work_struct tty_resize; struct list_head next; struct kref kref; /* ref count & hvc_struct lifetime */ }; @@ -84,6 +87,9 @@ extern int __devexit hvc_remove(struct hvc_struct *hp); int hvc_poll(struct hvc_struct *hp); void hvc_kick(void); +/* Resize hvc tty terminal window */ +extern void hvc_resize(struct hvc_struct *hp, struct winsize ws); + /* default notifier for irq based notification */ extern int notifier_add_irq(struct hvc_struct *hp, int data); extern void notifier_del_irq(struct hvc_struct *hp, int data); From 934752d8a4aaae4bee7a1b46944f30a55178ec91 Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Mon, 13 Oct 2008 23:12:52 +0000 Subject: [PATCH 47/53] hvc_console: Remove __devexit annotation of hvc_remove() Removed __devexit annotation of hvc_remove() to avoid a section mismatch if the backend initialization fails and hvc_remove() must be used to clean up allocated hvc structs (called in section __init or __devinit). Acked-by: Christian Borntraeger Signed-off-by: Hendrik Brueckner Signed-off-by: Benjamin Herrenschmidt --- drivers/char/hvc_console.c | 2 +- drivers/char/hvc_console.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 2d256dc80529..5b819b12675a 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -803,7 +803,7 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int data, } EXPORT_SYMBOL_GPL(hvc_alloc); -int __devexit hvc_remove(struct hvc_struct *hp) +int hvc_remove(struct hvc_struct *hp) { unsigned long flags; struct tty_struct *tty; diff --git a/drivers/char/hvc_console.h b/drivers/char/hvc_console.h index e3359f3c9b2a..8297dbc2e6ec 100644 --- a/drivers/char/hvc_console.h +++ b/drivers/char/hvc_console.h @@ -81,7 +81,7 @@ extern int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops); extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int data, struct hv_ops *ops, int outbuf_size); /* remove a vterm from hvc tty operation (module_exit or hotplug remove) */ -extern int __devexit hvc_remove(struct hvc_struct *hp); +extern int hvc_remove(struct hvc_struct *hp); /* data available */ int hvc_poll(struct hvc_struct *hp); From f465df81a80df92dbde0029b277f31b5e787b5df Mon Sep 17 00:00:00 2001 From: Becky Bruce Date: Wed, 15 Oct 2008 08:25:28 +0000 Subject: [PATCH 48/53] powerpc: Move memory size print into common show_cpuinfo for 32-bit Most of the platforms were printing the size of the memory in their show_cpuinfo implementations. This moves that to the common show_cpuinfo, so that all 32-bit platforms will now print the size of memory. I also update the code to deal with the fact that total_memory is now a phys_addr_t. Signed-off-by: Becky Bruce Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/setup-common.c | 7 +++++++ arch/powerpc/platforms/85xx/ksi8560.c | 4 ---- arch/powerpc/platforms/85xx/mpc85xx_ads.c | 4 ---- arch/powerpc/platforms/85xx/mpc85xx_cds.c | 4 ---- arch/powerpc/platforms/85xx/sbc8548.c | 4 ---- arch/powerpc/platforms/85xx/sbc8560.c | 4 ---- arch/powerpc/platforms/85xx/stx_gp3.c | 4 ---- arch/powerpc/platforms/85xx/tqm85xx.c | 4 ---- arch/powerpc/platforms/86xx/gef_sbc610.c | 2 -- arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | 2 -- arch/powerpc/platforms/86xx/sbc8641d.c | 2 -- arch/powerpc/platforms/embedded6xx/c2k.c | 3 --- arch/powerpc/platforms/embedded6xx/prpmc2800.c | 3 --- 13 files changed, 7 insertions(+), 40 deletions(-) diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 5ec56ff03e86..705fc4bf3800 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -59,6 +59,7 @@ #include #include #include +#include #include "setup.h" @@ -190,6 +191,12 @@ static int show_cpuinfo(struct seq_file *m, void *v) if (ppc_md.show_cpuinfo != NULL) ppc_md.show_cpuinfo(m); +#ifdef CONFIG_PPC32 + /* Display the amount of memory */ + seq_printf(m, "Memory\t\t: %d MB\n", + (unsigned int)(total_memory / (1024 * 1024))); +#endif + return 0; } diff --git a/arch/powerpc/platforms/85xx/ksi8560.c b/arch/powerpc/platforms/85xx/ksi8560.c index 8a3b117b6ce2..81cee7bbf2d2 100644 --- a/arch/powerpc/platforms/85xx/ksi8560.c +++ b/arch/powerpc/platforms/85xx/ksi8560.c @@ -193,7 +193,6 @@ static void __init ksi8560_setup_arch(void) static void ksi8560_show_cpuinfo(struct seq_file *m) { uint pvid, svid, phid1; - uint memsize = total_memory; pvid = mfspr(SPRN_PVR); svid = mfspr(SPRN_SVR); @@ -215,9 +214,6 @@ static void ksi8560_show_cpuinfo(struct seq_file *m) /* Display cpu Pll setting */ phid1 = mfspr(SPRN_HID1); seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); - - /* Display the amount of memory */ - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } static struct of_device_id __initdata of_bus_ids[] = { diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c index 0293e3d3580f..21f009023e26 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c @@ -207,7 +207,6 @@ static void __init mpc85xx_ads_setup_arch(void) static void mpc85xx_ads_show_cpuinfo(struct seq_file *m) { uint pvid, svid, phid1; - uint memsize = total_memory; pvid = mfspr(SPRN_PVR); svid = mfspr(SPRN_SVR); @@ -219,9 +218,6 @@ static void mpc85xx_ads_show_cpuinfo(struct seq_file *m) /* Display cpu Pll setting */ phid1 = mfspr(SPRN_HID1); seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); - - /* Display the amount of memory */ - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } static struct of_device_id __initdata of_bus_ids[] = { diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c index 50d7ea8f922b..aeb6a5bc5522 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c @@ -307,7 +307,6 @@ static void __init mpc85xx_cds_setup_arch(void) static void mpc85xx_cds_show_cpuinfo(struct seq_file *m) { uint pvid, svid, phid1; - uint memsize = total_memory; pvid = mfspr(SPRN_PVR); svid = mfspr(SPRN_SVR); @@ -320,9 +319,6 @@ static void mpc85xx_cds_show_cpuinfo(struct seq_file *m) /* Display cpu Pll setting */ phid1 = mfspr(SPRN_HID1); seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); - - /* Display the amount of memory */ - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } diff --git a/arch/powerpc/platforms/85xx/sbc8548.c b/arch/powerpc/platforms/85xx/sbc8548.c index b9246ea0928a..7ec77ce12dad 100644 --- a/arch/powerpc/platforms/85xx/sbc8548.c +++ b/arch/powerpc/platforms/85xx/sbc8548.c @@ -136,7 +136,6 @@ static void __init sbc8548_setup_arch(void) static void sbc8548_show_cpuinfo(struct seq_file *m) { uint pvid, svid, phid1; - uint memsize = total_memory; pvid = mfspr(SPRN_PVR); svid = mfspr(SPRN_SVR); @@ -149,9 +148,6 @@ static void sbc8548_show_cpuinfo(struct seq_file *m) /* Display cpu Pll setting */ phid1 = mfspr(SPRN_HID1); seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); - - /* Display the amount of memory */ - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } static struct of_device_id __initdata of_bus_ids[] = { diff --git a/arch/powerpc/platforms/85xx/sbc8560.c b/arch/powerpc/platforms/85xx/sbc8560.c index 0c9a856f66b6..472f254a19d2 100644 --- a/arch/powerpc/platforms/85xx/sbc8560.c +++ b/arch/powerpc/platforms/85xx/sbc8560.c @@ -194,7 +194,6 @@ static void __init sbc8560_setup_arch(void) static void sbc8560_show_cpuinfo(struct seq_file *m) { uint pvid, svid, phid1; - uint memsize = total_memory; pvid = mfspr(SPRN_PVR); svid = mfspr(SPRN_SVR); @@ -206,9 +205,6 @@ static void sbc8560_show_cpuinfo(struct seq_file *m) /* Display cpu Pll setting */ phid1 = mfspr(SPRN_HID1); seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); - - /* Display the amount of memory */ - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } static struct of_device_id __initdata of_bus_ids[] = { diff --git a/arch/powerpc/platforms/85xx/stx_gp3.c b/arch/powerpc/platforms/85xx/stx_gp3.c index 18499d7c9d9e..0cca8f5cb272 100644 --- a/arch/powerpc/platforms/85xx/stx_gp3.c +++ b/arch/powerpc/platforms/85xx/stx_gp3.c @@ -130,7 +130,6 @@ static void __init stx_gp3_setup_arch(void) static void stx_gp3_show_cpuinfo(struct seq_file *m) { uint pvid, svid, phid1; - uint memsize = total_memory; pvid = mfspr(SPRN_PVR); svid = mfspr(SPRN_SVR); @@ -142,9 +141,6 @@ static void stx_gp3_show_cpuinfo(struct seq_file *m) /* Display cpu Pll setting */ phid1 = mfspr(SPRN_HID1); seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); - - /* Display the amount of memory */ - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } static struct of_device_id __initdata of_bus_ids[] = { diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c index d850880d6964..2933a8e827d9 100644 --- a/arch/powerpc/platforms/85xx/tqm85xx.c +++ b/arch/powerpc/platforms/85xx/tqm85xx.c @@ -138,7 +138,6 @@ static void __init tqm85xx_setup_arch(void) static void tqm85xx_show_cpuinfo(struct seq_file *m) { uint pvid, svid, phid1; - uint memsize = total_memory; pvid = mfspr(SPRN_PVR); svid = mfspr(SPRN_SVR); @@ -150,9 +149,6 @@ static void tqm85xx_show_cpuinfo(struct seq_file *m) /* Display cpu Pll setting */ phid1 = mfspr(SPRN_HID1); seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); - - /* Display the amount of memory */ - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } static struct of_device_id __initdata of_bus_ids[] = { diff --git a/arch/powerpc/platforms/86xx/gef_sbc610.c b/arch/powerpc/platforms/86xx/gef_sbc610.c index 821c45fac18b..fb371f5ce132 100644 --- a/arch/powerpc/platforms/86xx/gef_sbc610.c +++ b/arch/powerpc/platforms/86xx/gef_sbc610.c @@ -127,7 +127,6 @@ static unsigned int gef_sbc610_get_fpga_rev(void) static void gef_sbc610_show_cpuinfo(struct seq_file *m) { - uint memsize = total_memory; uint svid = mfspr(SPRN_SVR); seq_printf(m, "Vendor\t\t: GE Fanuc Intelligent Platforms\n"); @@ -137,7 +136,6 @@ static void gef_sbc610_show_cpuinfo(struct seq_file *m) seq_printf(m, "FPGA Revision\t: %u\n", gef_sbc610_get_fpga_rev()); seq_printf(m, "SVR\t\t: 0x%x\n", svid); - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } static void __init gef_sbc610_nec_fixup(struct pci_dev *pdev) diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index 2672829a71dc..27e0e682d8e1 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -101,13 +101,11 @@ mpc86xx_hpcn_setup_arch(void) static void mpc86xx_hpcn_show_cpuinfo(struct seq_file *m) { - uint memsize = total_memory; uint svid = mfspr(SPRN_SVR); seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); seq_printf(m, "SVR\t\t: 0x%x\n", svid); - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } diff --git a/arch/powerpc/platforms/86xx/sbc8641d.c b/arch/powerpc/platforms/86xx/sbc8641d.c index da677a74e2d1..5fd7ed40986f 100644 --- a/arch/powerpc/platforms/86xx/sbc8641d.c +++ b/arch/powerpc/platforms/86xx/sbc8641d.c @@ -63,13 +63,11 @@ sbc8641_setup_arch(void) static void sbc8641_show_cpuinfo(struct seq_file *m) { - uint memsize = total_memory; uint svid = mfspr(SPRN_SVR); seq_printf(m, "Vendor\t\t: Wind River Systems\n"); seq_printf(m, "SVR\t\t: 0x%x\n", svid); - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); } diff --git a/arch/powerpc/platforms/embedded6xx/c2k.c b/arch/powerpc/platforms/embedded6xx/c2k.c index d0b25b8c39d1..32ba0fa0ad03 100644 --- a/arch/powerpc/platforms/embedded6xx/c2k.c +++ b/arch/powerpc/platforms/embedded6xx/c2k.c @@ -116,10 +116,7 @@ static void c2k_restart(char *cmd) void c2k_show_cpuinfo(struct seq_file *m) { - uint memsize = total_memory; - seq_printf(m, "Vendor\t\t: GEFanuc\n"); - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); seq_printf(m, "coherency\t: %s\n", COHERENCY_SETTING); } diff --git a/arch/powerpc/platforms/embedded6xx/prpmc2800.c b/arch/powerpc/platforms/embedded6xx/prpmc2800.c index 5a19b9a1457c..4c485e984236 100644 --- a/arch/powerpc/platforms/embedded6xx/prpmc2800.c +++ b/arch/powerpc/platforms/embedded6xx/prpmc2800.c @@ -119,10 +119,7 @@ static void prpmc2800_restart(char *cmd) void prpmc2800_show_cpuinfo(struct seq_file *m) { - uint memsize = total_memory; - seq_printf(m, "Vendor\t\t: Motorola\n"); - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); seq_printf(m, "coherency\t: %s\n", PPRPM2800_COHERENCY_SETTING); } From 8873d93b4bf0bd270c3fc7e178211633e7a1d5e8 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Wed, 15 Oct 2008 18:21:07 +0000 Subject: [PATCH 49/53] powerpc: Remove empty #else from signal_64.c Remove empty/bogus #else from signal_64.c Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/signal_64.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 65ad925c3a8f..c6a8f2326b6f 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -235,8 +235,6 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, else for (i = 0; i < 32 ; i++) current->thread.fpr[i][TS_VSRLOWOFFSET] = 0; - -#else #endif return err; } From 201bdc868d9e3122bbe4491aa6b5fc4dee4cdb96 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Mon, 20 Oct 2008 17:55:29 +0000 Subject: [PATCH 50/53] powerpc: Further compile fixup for STRICT_MM_TYPECHECKS A patch of mine was recently committed to fix up STRICT_MM_TYPECHECKS behaviour on powerpc (f5ea64dcbad89875d130596df14c9b25d994a737). However, something which breaks it again seems to have slipped in afterwards. So, here's another small fix. Signed-off-by: David Gibson Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/pci-common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 3815d84a1ef4..1ec73938a00f 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -610,7 +610,8 @@ int pci_mmap_legacy_page_range(struct pci_bus *bus, pr_debug(" -> mapping phys %llx\n", (unsigned long long)offset); vma->vm_pgoff = offset >> PAGE_SHIFT; - vma->vm_page_prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; + vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) + | _PAGE_NO_CACHE | _PAGE_GUARDED); return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vma->vm_end - vma->vm_start, vma->vm_page_prot); From 71773f0337bee8a3701aaaec22581c18a5f44679 Mon Sep 17 00:00:00 2001 From: Mike Ditto Date: Tue, 21 Oct 2008 11:32:29 +0000 Subject: [PATCH 51/53] powerpc: Add del_node() for early boot code to prune inapplicable devices. Some platforms have variants that can share most of a flat device tree but need a few devices selectively pruned at boot time. This adds del_node() to ops.h to allow access to the existing fdt_del_node(). Signed-off-by: Mike Ditto Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/boot/libfdt-wrapper.c | 6 ++++++ arch/powerpc/boot/ops.h | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/arch/powerpc/boot/libfdt-wrapper.c b/arch/powerpc/boot/libfdt-wrapper.c index 1daa73f08ba8..9276327bc2bb 100644 --- a/arch/powerpc/boot/libfdt-wrapper.c +++ b/arch/powerpc/boot/libfdt-wrapper.c @@ -105,6 +105,11 @@ static int fdt_wrapper_setprop(const void *devp, const char *name, return check_err(rc); } +static int fdt_wrapper_del_node(const void *devp) +{ + return fdt_del_node(fdt, devp_offset(devp)); +} + static void *fdt_wrapper_get_parent(const void *devp) { return offset_devp(fdt_parent_offset(fdt, devp_offset(devp))); @@ -174,6 +179,7 @@ void fdt_init(void *blob) dt_ops.create_node = fdt_wrapper_create_node; dt_ops.find_node_by_prop_value = fdt_wrapper_find_node_by_prop_value; dt_ops.find_node_by_compatible = fdt_wrapper_find_node_by_compatible; + dt_ops.del_node = fdt_wrapper_del_node; dt_ops.get_path = fdt_wrapper_get_path; dt_ops.finalize = fdt_wrapper_finalize; diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h index 321e2f5afe71..b3218ce451bb 100644 --- a/arch/powerpc/boot/ops.h +++ b/arch/powerpc/boot/ops.h @@ -40,6 +40,7 @@ struct dt_ops { const int buflen); int (*setprop)(const void *phandle, const char *name, const void *buf, const int buflen); + int (*del_node)(const void *phandle); void *(*get_parent)(const void *phandle); /* The node must not already exist. */ void *(*create_node)(const void *parent, const char *name); @@ -126,6 +127,11 @@ static inline int setprop_str(void *devp, const char *name, const char *buf) return -1; } +static inline int del_node(const void *devp) +{ + return dt_ops.del_node ? dt_ops.del_node(devp) : -1; +} + static inline void *get_parent(const char *devp) { return dt_ops.get_parent ? dt_ops.get_parent(devp) : NULL; From 4792adbac9eb41cea77a45ab76258ea10d411173 Mon Sep 17 00:00:00 2001 From: Jon Tollefson Date: Tue, 21 Oct 2008 15:27:36 +0000 Subject: [PATCH 52/53] powerpc: Don't use a 16G page if beyond mem= limits If mem= is used on the boot command line to limit memory then the memory block where a 16G page resides may not be available. Thanks to Michael Ellerman for finding the problem. Signed-off-by: Jon Tollefson Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/hash_utils_64.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 5c64af174752..8d5b4758c13a 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -382,8 +382,10 @@ static int __init htab_dt_scan_hugepage_blocks(unsigned long node, printk(KERN_INFO "Huge page(16GB) memory: " "addr = 0x%lX size = 0x%lX pages = %d\n", phys_addr, block_size, expected_pages); - lmb_reserve(phys_addr, block_size * expected_pages); - add_gpage(phys_addr, block_size, expected_pages); + if (phys_addr + (16 * GB) <= lmb_end_of_DRAM()) { + lmb_reserve(phys_addr, block_size * expected_pages); + add_gpage(phys_addr, block_size, expected_pages); + } return 0; } #endif /* CONFIG_HUGETLB_PAGE */ From 54622f10a6aabb8bb2bdacf3dd070046f03dc246 Mon Sep 17 00:00:00 2001 From: Mohan Kumar M Date: Tue, 21 Oct 2008 17:38:10 +0000 Subject: [PATCH 53/53] powerpc: Support for relocatable kdump kernel This adds relocatable kernel support for kdump. With this one can use the same regular kernel to capture the kdump. A signature (0xfeed1234) is passed in r6 from panic code to the next kernel through kexec_sequence and purgatory code. The signature is used to differentiate between kdump kernel and non-kdump kernels. The purgatory code compares the signature and sets the __kdump_flag in head_64.S. During the boot up, kernel code checks __kdump_flag and if it is set, the kernel will behave as relocatable kdump kernel. This kernel will boot at the address where it was loaded by kexec-tools ie. at the address reserved through crashkernel boot parameter. CONFIG_CRASH_DUMP depends on CONFIG_RELOCATABLE option to build kdump kernel as relocatable. So the same kernel can be used as production and kdump kernel. This patch incorporates the changes suggested by Paul Mackerras to avoid GOT use and to avoid two copies of the code. Signed-off-by: Paul Mackerras Signed-off-by: Mohan Kumar M Signed-off-by: Michael Ellerman Signed-off-by: Benjamin Herrenschmidt --- Documentation/kdump/kdump.txt | 14 ++++-- arch/powerpc/Kconfig | 10 ++-- arch/powerpc/include/asm/kdump.h | 17 +++++-- arch/powerpc/kernel/crash_dump.c | 2 + arch/powerpc/kernel/head_64.S | 39 ++++++++++++--- arch/powerpc/kernel/iommu.c | 69 ++++++++++++++------------ arch/powerpc/kernel/machine_kexec.c | 2 + arch/powerpc/kernel/machine_kexec_64.c | 13 +++-- arch/powerpc/kernel/misc_64.S | 9 ++-- arch/powerpc/platforms/cell/ras.c | 6 +-- arch/powerpc/platforms/pseries/iommu.c | 6 +-- 11 files changed, 121 insertions(+), 66 deletions(-) diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt index 0705040531a5..3f4bc840da8b 100644 --- a/Documentation/kdump/kdump.txt +++ b/Documentation/kdump/kdump.txt @@ -109,7 +109,8 @@ There are two possible methods of using Kdump. 2) Or use the system kernel binary itself as dump-capture kernel and there is no need to build a separate dump-capture kernel. This is possible only with the architecutres which support a relocatable kernel. As - of today, i386, x86_64 and ia64 architectures support relocatable kernel. + of today, i386, x86_64, ppc64 and ia64 architectures support relocatable + kernel. Building a relocatable kernel is advantageous from the point of view that one does not have to build a second kernel for capturing the dump. But @@ -207,8 +208,15 @@ Dump-capture kernel config options (Arch Dependent, i386 and x86_64) Dump-capture kernel config options (Arch Dependent, ppc64) ---------------------------------------------------------- -* Make and install the kernel and its modules. DO NOT add this kernel - to the boot loader configuration files. +1) Enable "Build a kdump crash kernel" support under "Kernel" options: + + CONFIG_CRASH_DUMP=y + +2) Enable "Build a relocatable kernel" support + + CONFIG_RELOCATABLE=y + + Make and install the kernel and its modules. Dump-capture kernel config options (Arch Dependent, ia64) ---------------------------------------------------------- diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 369d93e7377c..5b1527883fcb 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -323,13 +323,11 @@ config KEXEC config CRASH_DUMP bool "Build a kdump crash kernel" - depends on PPC_MULTIPLATFORM && PPC64 + depends on PPC_MULTIPLATFORM && PPC64 && RELOCATABLE help Build a kernel suitable for use as a kdump capture kernel. - The kernel will be linked at a different address than normal, and - so can only be used for Kdump. - - Don't change this unless you know what you are doing. + The same kernel binary can be used as production kernel and dump + capture kernel. config PHYP_DUMP bool "Hypervisor-assisted dump (EXPERIMENTAL)" @@ -829,11 +827,9 @@ config PAGE_OFFSET default "0xc000000000000000" config KERNEL_START hex - default "0xc000000002000000" if CRASH_DUMP default "0xc000000000000000" config PHYSICAL_START hex - default "0x02000000" if CRASH_DUMP default "0x00000000" endif diff --git a/arch/powerpc/include/asm/kdump.h b/arch/powerpc/include/asm/kdump.h index f6c93c716898..a503da9d56f3 100644 --- a/arch/powerpc/include/asm/kdump.h +++ b/arch/powerpc/include/asm/kdump.h @@ -9,6 +9,12 @@ * Reserve to the end of the FWNMI area, see head_64.S */ #define KDUMP_RESERVE_LIMIT 0x10000 /* 64K */ +/* + * Used to differentiate between relocatable kdump kernel and other + * kernels + */ +#define KDUMP_SIGNATURE 0xfeed1234 + #ifdef CONFIG_CRASH_DUMP #define KDUMP_TRAMPOLINE_START 0x0100 @@ -19,17 +25,18 @@ #endif /* CONFIG_CRASH_DUMP */ #ifndef __ASSEMBLY__ -#ifdef CONFIG_CRASH_DUMP +extern unsigned long __kdump_flag; + +#if defined(CONFIG_CRASH_DUMP) && !defined(CONFIG_RELOCATABLE) extern void reserve_kdump_trampoline(void); extern void setup_kdump_trampoline(void); - -#else /* !CONFIG_CRASH_DUMP */ - +#else +/* !CRASH_DUMP || RELOCATABLE */ static inline void reserve_kdump_trampoline(void) { ; } static inline void setup_kdump_trampoline(void) { ; } +#endif -#endif /* CONFIG_CRASH_DUMP */ #endif /* __ASSEMBLY__ */ #endif /* __PPC64_KDUMP_H */ diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c index 97e056379728..19671aca6591 100644 --- a/arch/powerpc/kernel/crash_dump.c +++ b/arch/powerpc/kernel/crash_dump.c @@ -30,6 +30,7 @@ /* Stores the physical address of elf header of crash image. */ unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX; +#ifndef CONFIG_RELOCATABLE void __init reserve_kdump_trampoline(void) { lmb_reserve(0, KDUMP_RESERVE_LIMIT); @@ -68,6 +69,7 @@ void __init setup_kdump_trampoline(void) DBG(" <- setup_kdump_trampoline()\n"); } +#endif /* CONFIG_RELOCATABLE */ /* * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 84856bee33a5..69489bd3210c 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -97,6 +97,12 @@ __secondary_hold_spinloop: __secondary_hold_acknowledge: .llong 0x0 + /* This flag is set by purgatory if we should be a kdump kernel. */ + /* Do not move this variable as purgatory knows about it. */ + .globl __kdump_flag +__kdump_flag: + .llong 0x0 + #ifdef CONFIG_PPC_ISERIES /* * At offset 0x20, there is a pointer to iSeries LPAR data. @@ -1384,7 +1390,13 @@ _STATIC(__after_prom_start) /* process relocations for the final address of the kernel */ lis r25,PAGE_OFFSET@highest /* compute virtual base of kernel */ sldi r25,r25,32 - mr r3,r25 +#ifdef CONFIG_CRASH_DUMP + ld r7,__kdump_flag-_stext(r26) + cmpldi cr0,r7,1 /* kdump kernel ? - stay where we are */ + bne 1f + add r25,r25,r26 +#endif +1: mr r3,r25 bl .relocate #endif @@ -1398,11 +1410,26 @@ _STATIC(__after_prom_start) li r3,0 /* target addr */ mr. r4,r26 /* In some cases the loader may */ beq 9f /* have already put us at zero */ - lis r5,(copy_to_here - _stext)@ha - addi r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */ li r6,0x100 /* Start offset, the first 0x100 */ /* bytes were copied earlier. */ +#ifdef CONFIG_CRASH_DUMP +/* + * Check if the kernel has to be running as relocatable kernel based on the + * variable __kdump_flag, if it is set the kernel is treated as relocatable + * kernel, otherwise it will be moved to PHYSICAL_START + */ + ld r7,__kdump_flag-_stext(r26) + cmpldi cr0,r7,1 + bne 3f + + li r5,__end_interrupts - _stext /* just copy interrupts */ + b 5f +3: +#endif + lis r5,(copy_to_here - _stext)@ha + addi r5,r5,(copy_to_here - _stext)@l /* # bytes of memory to copy */ + bl .copy_and_flush /* copy the first n bytes */ /* this includes the code being */ /* executed here. */ @@ -1411,15 +1438,15 @@ _STATIC(__after_prom_start) mtctr r8 bctr +p_end: .llong _end - _stext + 4: /* Now copy the rest of the kernel up to _end */ addis r5,r26,(p_end - _stext)@ha ld r5,(p_end - _stext)@l(r5) /* get _end */ - bl .copy_and_flush /* copy the rest */ +5: bl .copy_and_flush /* copy the rest */ 9: b .start_here_multiplatform -p_end: .llong _end - _stext - /* * Copy routine used to copy the kernel to start at physical address 0 * and flush and invalidate the caches as needed. diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index ea1ba89f9c90..3857d7e2af0c 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -458,6 +458,42 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, spin_unlock_irqrestore(&(tbl->it_lock), flags); } +static void iommu_table_clear(struct iommu_table *tbl) +{ + if (!__kdump_flag) { + /* Clear the table in case firmware left allocations in it */ + ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); + return; + } + +#ifdef CONFIG_CRASH_DUMP + if (ppc_md.tce_get) { + unsigned long index, tceval, tcecount = 0; + + /* Reserve the existing mappings left by the first kernel. */ + for (index = 0; index < tbl->it_size; index++) { + tceval = ppc_md.tce_get(tbl, index + tbl->it_offset); + /* + * Freed TCE entry contains 0x7fffffffffffffff on JS20 + */ + if (tceval && (tceval != 0x7fffffffffffffffUL)) { + __set_bit(index, tbl->it_map); + tcecount++; + } + } + + if ((tbl->it_size - tcecount) < KDUMP_MIN_TCE_ENTRIES) { + printk(KERN_WARNING "TCE table is full; freeing "); + printk(KERN_WARNING "%d entries for the kdump boot\n", + KDUMP_MIN_TCE_ENTRIES); + for (index = tbl->it_size - KDUMP_MIN_TCE_ENTRIES; + index < tbl->it_size; index++) + __clear_bit(index, tbl->it_map); + } + } +#endif +} + /* * Build a iommu_table structure. This contains a bit map which * is used to manage allocation of the tce space. @@ -484,38 +520,7 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) tbl->it_largehint = tbl->it_halfpoint; spin_lock_init(&tbl->it_lock); -#ifdef CONFIG_CRASH_DUMP - if (ppc_md.tce_get) { - unsigned long index; - unsigned long tceval; - unsigned long tcecount = 0; - - /* - * Reserve the existing mappings left by the first kernel. - */ - for (index = 0; index < tbl->it_size; index++) { - tceval = ppc_md.tce_get(tbl, index + tbl->it_offset); - /* - * Freed TCE entry contains 0x7fffffffffffffff on JS20 - */ - if (tceval && (tceval != 0x7fffffffffffffffUL)) { - __set_bit(index, tbl->it_map); - tcecount++; - } - } - if ((tbl->it_size - tcecount) < KDUMP_MIN_TCE_ENTRIES) { - printk(KERN_WARNING "TCE table is full; "); - printk(KERN_WARNING "freeing %d entries for the kdump boot\n", - KDUMP_MIN_TCE_ENTRIES); - for (index = tbl->it_size - KDUMP_MIN_TCE_ENTRIES; - index < tbl->it_size; index++) - __clear_bit(index, tbl->it_map); - } - } -#else - /* Clear the hardware table in case firmware left allocations in it */ - ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); -#endif + iommu_table_clear(tbl); if (!welcomed) { printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index aab76887a842..ac2a21f45c75 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -88,11 +88,13 @@ void __init reserve_crashkernel(void) crash_size = crashk_res.end - crashk_res.start + 1; +#ifndef CONFIG_RELOCATABLE if (crashk_res.start != KDUMP_KERNELBASE) printk("Crash kernel location must be 0x%x\n", KDUMP_KERNELBASE); crashk_res.start = KDUMP_KERNELBASE; +#endif crash_size = PAGE_ALIGN(crash_size); crashk_res.end = crashk_res.start + crash_size - 1; diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index 4bd8b4f5e70d..e6efec788c4d 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c @@ -255,11 +255,14 @@ static union thread_union kexec_stack /* Our assembly helper, in kexec_stub.S */ extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start, void *image, void *control, - void (*clear_all)(void)) ATTRIB_NORET; + void (*clear_all)(void), + unsigned long kdump_flag) ATTRIB_NORET; /* too late to fail here */ void default_machine_kexec(struct kimage *image) { + unsigned long kdump_flag = 0; + /* prepare control code if any */ /* @@ -270,8 +273,10 @@ void default_machine_kexec(struct kimage *image) * using debugger IPI. */ - if (crashing_cpu == -1) - kexec_prepare_cpus(); + if (crashing_cpu == -1) + kexec_prepare_cpus(); + else + kdump_flag = KDUMP_SIGNATURE; /* switch to a staticly allocated stack. Based on irq stack code. * XXX: the task struct will likely be invalid once we do the copy! @@ -284,7 +289,7 @@ void default_machine_kexec(struct kimage *image) */ kexec_sequence(&kexec_stack, image->start, image, page_address(image->control_code_page), - ppc_md.hpte_clear_all); + ppc_md.hpte_clear_all, kdump_flag); /* NOTREACHED */ } diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index 3053fe5c62f2..a243fd072a77 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -611,10 +611,12 @@ real_mode: /* assume normal blr return */ /* - * kexec_sequence(newstack, start, image, control, clear_all()) + * kexec_sequence(newstack, start, image, control, clear_all(), kdump_flag) * * does the grungy work with stack switching and real mode switches * also does simple calls to other code + * + * kdump_flag says whether the next kernel should be a kdump kernel. */ _GLOBAL(kexec_sequence) @@ -647,7 +649,7 @@ _GLOBAL(kexec_sequence) mr r29,r5 /* image (virt) */ mr r28,r6 /* control, unused */ mr r27,r7 /* clear_all() fn desc */ - mr r26,r8 /* spare */ + mr r26,r8 /* kdump flag */ lhz r25,PACAHWCPUID(r13) /* get our phys cpu from paca */ /* disable interrupts, we are overwriting kernel data next */ @@ -709,5 +711,6 @@ _GLOBAL(kexec_sequence) mr r4,r30 # start, aka phys mem offset mtlr 4 li r5,0 - blr /* image->start(physid, image->start, 0); */ + mr r6,r26 /* kdump_flag */ + blr /* image->start(physid, image->start, 0, kdump_flag); */ #endif /* CONFIG_KEXEC */ diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c index 2a14b052abcd..665af1c4195b 100644 --- a/arch/powerpc/platforms/cell/ras.c +++ b/arch/powerpc/platforms/cell/ras.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "ras.h" @@ -111,9 +112,8 @@ static int __init cbe_ptcal_enable_on_node(int nid, int order) int ret = -ENOMEM; unsigned long addr; -#ifdef CONFIG_CRASH_DUMP - rtas_call(ptcal_stop_tok, 1, 1, NULL, nid); -#endif + if (__kdump_flag) + rtas_call(ptcal_stop_tok, 1, 1, NULL, nid); area = kmalloc(sizeof(*area), GFP_KERNEL); if (!area) diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index a8c446697f9e..d56491d182d3 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -44,6 +44,7 @@ #include #include #include +#include #include "plpar_wrappers.h" @@ -291,9 +292,8 @@ static void iommu_table_setparms(struct pci_controller *phb, tbl->it_base = (unsigned long)__va(*basep); -#ifndef CONFIG_CRASH_DUMP - memset((void *)tbl->it_base, 0, *sizep); -#endif + if (!__kdump_flag) + memset((void *)tbl->it_base, 0, *sizep); tbl->it_busno = phb->bus->number;