Merge branch 'merge'
authorPaul Mackerras <paulus@samba.org>
Mon, 12 Jun 2006 07:53:34 +0000 (17:53 +1000)
committerPaul Mackerras <paulus@samba.org>
Mon, 12 Jun 2006 07:53:34 +0000 (17:53 +1000)
122 files changed:
arch/powerpc/Kconfig
arch/powerpc/Kconfig.debug
arch/powerpc/configs/mpc85xx_cds_defconfig [new file with mode: 0644]
arch/powerpc/kernel/align.c
arch/powerpc/kernel/cpu_setup_power4.S
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/crash.c
arch/powerpc/kernel/crash_dump.c
arch/powerpc/kernel/iomap.c
arch/powerpc/kernel/iommu.c
arch/powerpc/kernel/lparcfg.c
arch/powerpc/kernel/machine_kexec_64.c
arch/powerpc/kernel/misc_32.S
arch/powerpc/kernel/misc_64.S
arch/powerpc/kernel/nvram_64.c
arch/powerpc/kernel/pci_64.c
arch/powerpc/kernel/pci_dn.c
arch/powerpc/kernel/pci_iommu.c
arch/powerpc/kernel/proc_ppc64.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/prom_init.c
arch/powerpc/kernel/prom_parse.c
arch/powerpc/kernel/ptrace.c
arch/powerpc/kernel/rtas-rtc.c
arch/powerpc/kernel/rtas.c
arch/powerpc/kernel/rtas_flash.c
arch/powerpc/kernel/setup-common.c
arch/powerpc/kernel/setup.h
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/signal_32.c
arch/powerpc/kernel/signal_64.c
arch/powerpc/kernel/time.c
arch/powerpc/kernel/traps.c
arch/powerpc/kernel/udbg.c
arch/powerpc/kernel/vdso.c
arch/powerpc/kernel/vio.c
arch/powerpc/kernel/vmlinux.lds.S
arch/powerpc/lib/Makefile
arch/powerpc/lib/bitops.c [deleted file]
arch/powerpc/mm/hash_low_64.S
arch/powerpc/mm/hash_native_64.c
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/mm/lmb.c
arch/powerpc/mm/mem.c
arch/powerpc/mm/mmu_context_32.c
arch/powerpc/mm/numa.c
arch/powerpc/mm/ppc_mmu_32.c
arch/powerpc/mm/tlb_32.c
arch/powerpc/oprofile/common.c
arch/powerpc/oprofile/op_model_power4.c
arch/powerpc/platforms/85xx/Kconfig
arch/powerpc/platforms/85xx/Makefile
arch/powerpc/platforms/85xx/mpc85xx_cds.c [new file with mode: 0644]
arch/powerpc/platforms/85xx/mpc85xx_cds.h [new file with mode: 0644]
arch/powerpc/platforms/cell/spufs/context.c
arch/powerpc/platforms/iseries/Makefile
arch/powerpc/platforms/iseries/call_pci.h
arch/powerpc/platforms/iseries/dt.c [new file with mode: 0644]
arch/powerpc/platforms/iseries/iommu.c
arch/powerpc/platforms/iseries/iommu.h [deleted file]
arch/powerpc/platforms/iseries/irq.c
arch/powerpc/platforms/iseries/irq.h
arch/powerpc/platforms/iseries/mf.c
arch/powerpc/platforms/iseries/pci.c
arch/powerpc/platforms/iseries/setup.c
arch/powerpc/platforms/iseries/setup.h
arch/powerpc/platforms/iseries/vio.c [deleted file]
arch/powerpc/platforms/maple/pci.c
arch/powerpc/platforms/maple/setup.c
arch/powerpc/platforms/powermac/cpufreq_32.c
arch/powerpc/platforms/powermac/feature.c
arch/powerpc/platforms/powermac/pci.c
arch/powerpc/platforms/powermac/setup.c
arch/powerpc/platforms/pseries/Makefile
arch/powerpc/platforms/pseries/eeh_driver.c
arch/powerpc/platforms/pseries/eeh_event.c
arch/powerpc/platforms/pseries/iommu.c
arch/powerpc/platforms/pseries/rtasd.c
arch/powerpc/platforms/pseries/setup.c
arch/powerpc/platforms/pseries/vio.c [deleted file]
arch/powerpc/platforms/pseries/xics.c
arch/ppc/Kconfig
arch/ppc/mm/mmu_context.c
drivers/block/viodasd.c
drivers/cdrom/viocd.c
drivers/char/hvc_console.c
drivers/char/hvc_rtas.c
drivers/char/hvsi.c
drivers/char/viotape.c
drivers/macintosh/via-pmu.c
drivers/net/ibmveth.c
drivers/net/iseries_veth.c
include/asm-powerpc/bitops.h
include/asm-powerpc/cputable.h
include/asm-powerpc/eeh.h
include/asm-powerpc/eeh_event.h
include/asm-powerpc/elf.h
include/asm-powerpc/io.h
include/asm-powerpc/iommu.h
include/asm-powerpc/iseries/iommu.h [new file with mode: 0644]
include/asm-powerpc/kdump.h
include/asm-powerpc/kexec.h
include/asm-powerpc/mmu.h
include/asm-powerpc/page.h
include/asm-powerpc/pci-bridge.h
include/asm-powerpc/processor.h
include/asm-powerpc/prom.h
include/asm-powerpc/ptrace.h
include/asm-powerpc/reg.h
include/asm-powerpc/rtas.h
include/asm-powerpc/tce.h
include/asm-powerpc/topology.h
include/asm-powerpc/udbg.h
include/asm-powerpc/vio.h
include/asm-ppc/mmu.h
include/asm-ppc/mmu_context.h
include/asm-ppc/mpc85xx.h
include/asm-ppc/pgtable.h
include/linux/prctl.h
kernel/sys.c

index 6729c98b66f969fb16566bcc949039c776370a24..7eb0ef2b0036cec0a438f424ab0552c1e26b3eef 100644 (file)
@@ -45,6 +45,10 @@ config GENERIC_CALIBRATE_DELAY
        bool
        default y
 
+config GENERIC_FIND_NEXT_BIT
+       bool
+       default y
+
 config PPC
        bool
        default y
@@ -336,7 +340,7 @@ endchoice
 
 config PPC_PSERIES
        depends on PPC_MULTIPLATFORM && PPC64
-       bool "  IBM pSeries & new (POWER5-based) iSeries"
+       bool "IBM pSeries & new (POWER5-based) iSeries"
        select PPC_I8259
        select PPC_RTAS
        select RTAS_ERROR_LOGGING
@@ -344,7 +348,7 @@ config PPC_PSERIES
        default y
 
 config PPC_CHRP
-       bool "  Common Hardware Reference Platform (CHRP) based machines"
+       bool "Common Hardware Reference Platform (CHRP) based machines"
        depends on PPC_MULTIPLATFORM && PPC32
        select PPC_I8259
        select PPC_INDIRECT_PCI
@@ -354,7 +358,7 @@ config PPC_CHRP
        default y
 
 config PPC_PMAC
-       bool "  Apple PowerMac based machines"
+       bool "Apple PowerMac based machines"
        depends on PPC_MULTIPLATFORM
        select PPC_INDIRECT_PCI if PPC32
        select PPC_MPC106 if PPC32
@@ -370,7 +374,7 @@ config PPC_PMAC64
        default y
 
 config PPC_PREP
-       bool "  PowerPC Reference Platform (PReP) based machines"
+       bool "PowerPC Reference Platform (PReP) based machines"
        depends on PPC_MULTIPLATFORM && PPC32 && BROKEN
        select PPC_I8259
        select PPC_INDIRECT_PCI
@@ -379,7 +383,7 @@ config PPC_PREP
 
 config PPC_MAPLE
        depends on PPC_MULTIPLATFORM && PPC64
-       bool "  Maple 970FX Evaluation Board"
+       bool "Maple 970FX Evaluation Board"
        select U3_DART
        select MPIC_BROKEN_U3
        select GENERIC_TBSYNC
@@ -391,7 +395,7 @@ config PPC_MAPLE
          For more informations, refer to <http://www.970eval.com>
 
 config PPC_CELL
-       bool "  Cell Broadband Processor Architecture"
+       bool "Cell Broadband Processor Architecture"
        depends on PPC_MULTIPLATFORM && PPC64
        select PPC_RTAS
        select MMIO_NVRAM
@@ -827,12 +831,12 @@ config PCI_8260
        default y
 
 config 8260_PCI9
-       bool "  Enable workaround for MPC826x erratum PCI 9"
+       bool "Enable workaround for MPC826x erratum PCI 9"
        depends on PCI_8260 && !ADS8272
        default y
 
 choice
-       prompt "  IDMA channel for PCI 9 workaround"
+       prompt "IDMA channel for PCI 9 workaround"
        depends on 8260_PCI9
 
 config 8260_PCI9_IDMA1
index 8d48e9e7162ad2aaacc454689f6c7d29da6871d1..c69006ae8246abc6bbc756752779473bf5c4467c 100644 (file)
@@ -110,13 +110,16 @@ config SERIAL_TEXT_DEBUG
        depends on 4xx || LOPEC || MV64X60 || PPLUS || PRPMC800 || \
                PPC_GEN550 || PPC_MPC52xx
 
+config PPC_EARLY_DEBUG
+       bool "Early debugging (dangerous)"
+
 choice
-       prompt "Early debugging (dangerous)"
-       bool
-       optional
+       prompt "Early debugging console"
+       depends on PPC_EARLY_DEBUG
        help
-         Enable early debugging. Careful, if you enable debugging for the
-         wrong type of machine your kernel _will not boot_.
+         Use the selected console for early debugging. Careful, if you
+         enable debugging for the wrong type of machine your kernel
+         _will not boot_.
 
 config PPC_EARLY_DEBUG_LPAR
        bool "LPAR HV Console"
diff --git a/arch/powerpc/configs/mpc85xx_cds_defconfig b/arch/powerpc/configs/mpc85xx_cds_defconfig
new file mode 100644 (file)
index 0000000..9bb022a
--- /dev/null
@@ -0,0 +1,846 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.16
+# Sun Apr  2 11:23:42 2006
+#
+# CONFIG_PPC64 is not set
+CONFIG_PPC32=y
+CONFIG_PPC_MERGE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+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_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+# CONFIG_DEFAULT_UIMAGE is not set
+
+#
+# Processor support
+#
+# CONFIG_CLASSIC32 is not set
+# CONFIG_PPC_52xx is not set
+# CONFIG_PPC_82xx is not set
+# CONFIG_PPC_83xx is not set
+CONFIG_PPC_85xx=y
+# CONFIG_40x is not set
+# CONFIG_44x is not set
+# CONFIG_8xx is not set
+# CONFIG_E200 is not set
+CONFIG_85xx=y
+CONFIG_E500=y
+CONFIG_BOOKE=y
+CONFIG_FSL_BOOKE=y
+# CONFIG_PHYS_64BIT is not set
+CONFIG_SPE=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF 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_MPIC=y
+# CONFIG_WANT_EARLY_SERIAL is not set
+
+#
+# Platform support
+#
+# CONFIG_MPC8540_ADS is not set
+CONFIG_MPC85xx_CDS=y
+CONFIG_MPC8540=y
+CONFIG_PPC_INDIRECT_PCI_BE=y
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+CONFIG_MATH_EMULATION=y
+CONFIG_ARCH_FLATMEM_ENABLE=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_SPLIT_PTLOCK_CPUS=4
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_PM is not set
+# CONFIG_SOFTWARE_SUSPEND is not set
+# CONFIG_SECCOMP is not set
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_PPC_I8259=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_PCI_DEBUG is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_HIGHMEM_START=0xfe000000
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_TASK_SIZE=0x80000000
+CONFIG_BOOT_LOAD=0x00800000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# 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_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# 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_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# 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_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# 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=y
+# CONFIG_BLK_DEV_CRYPTOLOOP 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=32768
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+# CONFIG_BLK_DEV_IDEDISK is not set
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+# CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# Macintosh device drivers
+#
+# CONFIG_WINDFARM is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# PHY device support
+#
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+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
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+CONFIG_E1000=y
+CONFIG_E1000_NAPI=y
+# CONFIG_E1000_DISABLE_PACKET_SPLIT 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_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+CONFIG_GIANFAR=y
+CONFIG_GFAR_NAPI=y
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_CHELSIO_T1 is not set
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# 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_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC 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_SERIAL_NONSTANDARD 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 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS 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=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# 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_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# 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_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# 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_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=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
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+
+#
+# Instrumentation Support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_UNWIND_INFO is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_DEBUGGER is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
+# CONFIG_PPC_EARLY_DEBUG_G5 is not set
+# CONFIG_PPC_EARLY_DEBUG_RTAS is not set
+# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
+# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
index faaec9c6f78f1aaf5f7f572e5cbd8035c4c063e9..4734b5de599dd516fc612a72d9a1b3258edb544d 100644 (file)
@@ -35,17 +35,19 @@ struct aligninfo {
 
 #define INVALID        { 0, 0 }
 
-#define LD     1       /* load */
-#define ST     2       /* store */
-#define        SE      4       /* sign-extend value */
-#define F      8       /* to/from fp regs */
-#define U      0x10    /* update index register */
-#define M      0x20    /* multiple load/store */
-#define SW     0x40    /* byte swap int or ... */
-#define S      0x40    /* ... single-precision fp */
-#define SX     0x40    /* byte count in XER */
+/* Bits in the flags field */
+#define LD     0       /* load */
+#define ST     1       /* store */
+#define        SE      2       /* sign-extend value */
+#define F      4       /* to/from fp regs */
+#define U      8       /* update index register */
+#define M      0x10    /* multiple load/store */
+#define SW     0x20    /* byte swap */
+#define S      0x40    /* single-precision fp or... */
+#define SX     0x40    /* ... byte count in XER */
 #define HARD   0x80    /* string, stwcx. */
 
+/* DSISR bits reported for a DCBZ instruction: */
 #define DCBZ   0x5f    /* 8xx/82xx dcbz faults when cache not enabled */
 
 #define SWAP(a, b)     (t = (a), (a) = (b), (b) = t)
@@ -256,12 +258,16 @@ static int emulate_dcbz(struct pt_regs *regs, unsigned char __user *addr)
 #define REG_BYTE(rp, i)                *((u8 *)(rp) + (i))
 #endif
 
+#define SWIZ_PTR(p)            ((unsigned char __user *)((p) ^ swiz))
+
 static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr,
                            unsigned int reg, unsigned int nb,
-                           unsigned int flags, unsigned int instr)
+                           unsigned int flags, unsigned int instr,
+                           unsigned long swiz)
 {
        unsigned long *rptr;
-       unsigned int nb0, i;
+       unsigned int nb0, i, bswiz;
+       unsigned long p;
 
        /*
         * We do not try to emulate 8 bytes multiple as they aren't really
@@ -280,9 +286,12 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr,
                        if (nb == 0)
                                return 1;
                } else {
-                       if (__get_user(instr,
-                                      (unsigned int __user *)regs->nip))
+                       unsigned long pc = regs->nip ^ (swiz & 4);
+
+                       if (__get_user(instr, (unsigned int __user *)pc))
                                return -EFAULT;
+                       if (swiz == 0 && (flags & SW))
+                               instr = cpu_to_le32(instr);
                        nb = (instr >> 11) & 0x1f;
                        if (nb == 0)
                                nb = 32;
@@ -300,7 +309,10 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr,
                return -EFAULT; /* bad address */
 
        rptr = &regs->gpr[reg];
-       if (flags & LD) {
+       p = (unsigned long) addr;
+       bswiz = (flags & SW)? 3: 0;
+
+       if (!(flags & ST)) {
                /*
                 * This zeroes the top 4 bytes of the affected registers
                 * in 64-bit mode, and also zeroes out any remaining
@@ -311,26 +323,28 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr,
                        memset(&regs->gpr[0], 0,
                               ((nb0 + 3) / 4) * sizeof(unsigned long));
 
-               for (i = 0; i < nb; ++i)
-                       if (__get_user(REG_BYTE(rptr, i), addr + i))
+               for (i = 0; i < nb; ++i, ++p)
+                       if (__get_user(REG_BYTE(rptr, i ^ bswiz), SWIZ_PTR(p)))
                                return -EFAULT;
                if (nb0 > 0) {
                        rptr = &regs->gpr[0];
                        addr += nb;
-                       for (i = 0; i < nb0; ++i)
-                               if (__get_user(REG_BYTE(rptr, i), addr + i))
+                       for (i = 0; i < nb0; ++i, ++p)
+                               if (__get_user(REG_BYTE(rptr, i ^ bswiz),
+                                              SWIZ_PTR(p)))
                                        return -EFAULT;
                }
 
        } else {
-               for (i = 0; i < nb; ++i)
-                       if (__put_user(REG_BYTE(rptr, i), addr + i))
+               for (i = 0; i < nb; ++i, ++p)
+                       if (__put_user(REG_BYTE(rptr, i ^ bswiz), SWIZ_PTR(p)))
                                return -EFAULT;
                if (nb0 > 0) {
                        rptr = &regs->gpr[0];
                        addr += nb;
-                       for (i = 0; i < nb0; ++i)
-                               if (__put_user(REG_BYTE(rptr, i), addr + i))
+                       for (i = 0; i < nb0; ++i, ++p)
+                               if (__put_user(REG_BYTE(rptr, i ^ bswiz),
+                                              SWIZ_PTR(p)))
                                        return -EFAULT;
                }
        }
@@ -352,7 +366,7 @@ int fix_alignment(struct pt_regs *regs)
        unsigned int reg, areg;
        unsigned int dsisr;
        unsigned char __user *addr;
-       unsigned char __user *p;
+       unsigned long p, swiz;
        int ret, t;
        union {
                u64 ll;
@@ -380,11 +394,15 @@ int fix_alignment(struct pt_regs *regs)
         * let's make one up from the instruction
         */
        if (cpu_has_feature(CPU_FTR_NODSISRALIGN)) {
-               unsigned int real_instr;
-               if (unlikely(__get_user(real_instr,
-                                       (unsigned int __user *)regs->nip)))
+               unsigned long pc = regs->nip;
+
+               if (cpu_has_feature(CPU_FTR_PPC_LE) && (regs->msr & MSR_LE))
+                       pc ^= 4;
+               if (unlikely(__get_user(instr, (unsigned int __user *)pc)))
                        return -EFAULT;
-               dsisr = make_dsisr(real_instr);
+               if (cpu_has_feature(CPU_FTR_REAL_LE) && (regs->msr & MSR_LE))
+                       instr = cpu_to_le32(instr);
+               dsisr = make_dsisr(instr);
        }
 
        /* extract the operation and registers from the dsisr */
@@ -397,6 +415,24 @@ int fix_alignment(struct pt_regs *regs)
        nb = aligninfo[instr].len;
        flags = aligninfo[instr].flags;
 
+       /* Byteswap little endian loads and stores */
+       swiz = 0;
+       if (regs->msr & MSR_LE) {
+               flags ^= SW;
+               /*
+                * So-called "PowerPC little endian" mode works by
+                * swizzling addresses rather than by actually doing
+                * any byte-swapping.  To emulate this, we XOR each
+                * byte address with 7.  We also byte-swap, because
+                * the processor's address swizzling depends on the
+                * operand size (it xors the address with 7 for bytes,
+                * 6 for halfwords, 4 for words, 0 for doublewords) but
+                * we will xor with 7 and load/store each byte separately.
+                */
+               if (cpu_has_feature(CPU_FTR_PPC_LE))
+                       swiz = 7;
+       }
+
        /* DAR has the operand effective address */
        addr = (unsigned char __user *)regs->dar;
 
@@ -412,7 +448,8 @@ int fix_alignment(struct pt_regs *regs)
         * function
         */
        if (flags & M)
-               return emulate_multiple(regs, addr, reg, nb, flags, instr);
+               return emulate_multiple(regs, addr, reg, nb,
+                                       flags, instr, swiz);
 
        /* Verify the address of the operand */
        if (unlikely(user_mode(regs) &&
@@ -431,51 +468,71 @@ int fix_alignment(struct pt_regs *regs)
        /* If we are loading, get the data from user space, else
         * get it from register values
         */
-       if (flags & LD) {
+       if (!(flags & ST)) {
                data.ll = 0;
                ret = 0;
-               p = addr;
+               p = (unsigned long) addr;
                switch (nb) {
                case 8:
-                       ret |= __get_user(data.v[0], p++);
-                       ret |= __get_user(data.v[1], p++);
-                       ret |= __get_user(data.v[2], p++);
-                       ret |= __get_user(data.v[3], p++);
+                       ret |= __get_user(data.v[0], SWIZ_PTR(p++));
+                       ret |= __get_user(data.v[1], SWIZ_PTR(p++));
+                       ret |= __get_user(data.v[2], SWIZ_PTR(p++));
+                       ret |= __get_user(data.v[3], SWIZ_PTR(p++));
                case 4:
-                       ret |= __get_user(data.v[4], p++);
-                       ret |= __get_user(data.v[5], p++);
+                       ret |= __get_user(data.v[4], SWIZ_PTR(p++));
+                       ret |= __get_user(data.v[5], SWIZ_PTR(p++));
                case 2:
-                       ret |= __get_user(data.v[6], p++);
-                       ret |= __get_user(data.v[7], p++);
+                       ret |= __get_user(data.v[6], SWIZ_PTR(p++));
+                       ret |= __get_user(data.v[7], SWIZ_PTR(p++));
                        if (unlikely(ret))
                                return -EFAULT;
                }
-       } else if (flags & F)
+       } else if (flags & F) {
                data.dd = current->thread.fpr[reg];
-       else
+               if (flags & S) {
+                       /* Single-precision FP store requires conversion... */
+#ifdef CONFIG_PPC_FPU
+                       preempt_disable();
+                       enable_kernel_fp();
+                       cvt_df(&data.dd, (float *)&data.v[4], &current->thread);
+                       preempt_enable();
+#else
+                       return 0;
+#endif
+               }
+       } else
                data.ll = regs->gpr[reg];
 
-       /* Perform other misc operations like sign extension, byteswap,
+       if (flags & SW) {
+               switch (nb) {
+               case 8:
+                       SWAP(data.v[0], data.v[7]);
+                       SWAP(data.v[1], data.v[6]);
+                       SWAP(data.v[2], data.v[5]);
+                       SWAP(data.v[3], data.v[4]);
+                       break;
+               case 4:
+                       SWAP(data.v[4], data.v[7]);
+                       SWAP(data.v[5], data.v[6]);
+                       break;
+               case 2:
+                       SWAP(data.v[6], data.v[7]);
+                       break;
+               }
+       }
+
+       /* Perform other misc operations like sign extension
         * or floating point single precision conversion
         */
-       switch (flags & ~U) {
+       switch (flags & ~(U|SW)) {
        case LD+SE:     /* sign extend */
                if ( nb == 2 )
                        data.ll = data.x16.low16;
                else    /* nb must be 4 */
                        data.ll = data.x32.low32;
                break;
-       case LD+S:      /* byte-swap */
-       case ST+S:
-               if (nb == 2) {
-                       SWAP(data.v[6], data.v[7]);
-               } else {
-                       SWAP(data.v[4], data.v[7]);
-                       SWAP(data.v[5], data.v[6]);
-               }
-               break;
 
-       /* Single-precision FP load and store require conversions... */
+       /* Single-precision FP load requires conversion... */
        case LD+F+S:
 #ifdef CONFIG_PPC_FPU
                preempt_disable();
@@ -484,16 +541,6 @@ int fix_alignment(struct pt_regs *regs)
                preempt_enable();
 #else
                return 0;
-#endif
-               break;
-       case ST+F+S:
-#ifdef CONFIG_PPC_FPU
-               preempt_disable();
-               enable_kernel_fp();
-               cvt_df(&data.dd, (float *)&data.v[4], &current->thread);
-               preempt_enable();
-#else
-               return 0;
 #endif
                break;
        }
@@ -501,19 +548,19 @@ int fix_alignment(struct pt_regs *regs)
        /* Store result to memory or update registers */
        if (flags & ST) {
                ret = 0;
-               p = addr;
+               p = (unsigned long) addr;
                switch (nb) {
                case 8:
-                       ret |= __put_user(data.v[0], p++);
-                       ret |= __put_user(data.v[1], p++);
-                       ret |= __put_user(data.v[2], p++);
-                       ret |= __put_user(data.v[3], p++);
+                       ret |= __put_user(data.v[0], SWIZ_PTR(p++));
+                       ret |= __put_user(data.v[1], SWIZ_PTR(p++));
+                       ret |= __put_user(data.v[2], SWIZ_PTR(p++));
+                       ret |= __put_user(data.v[3], SWIZ_PTR(p++));
                case 4:
-                       ret |= __put_user(data.v[4], p++);
-                       ret |= __put_user(data.v[5], p++);
+                       ret |= __put_user(data.v[4], SWIZ_PTR(p++));
+                       ret |= __put_user(data.v[5], SWIZ_PTR(p++));
                case 2:
-                       ret |= __put_user(data.v[6], p++);
-                       ret |= __put_user(data.v[7], p++);
+                       ret |= __put_user(data.v[6], SWIZ_PTR(p++));
+                       ret |= __put_user(data.v[7], SWIZ_PTR(p++));
                }
                if (unlikely(ret))
                        return -EFAULT;
index b61d86e7ceb6059c7e838927dc66c25244441f1e..271418308d536de53601ae69a0c070ac24a11490 100644 (file)
@@ -73,23 +73,6 @@ _GLOBAL(__970_cpu_preinit)
        isync
        blr
 
-_GLOBAL(__setup_cpu_power4)
-       blr
-
-_GLOBAL(__setup_cpu_be)
-        /* Set large page sizes LP=0: 16MB, LP=1: 64KB */
-        addi    r3, 0,  0
-        ori     r3, r3, HID6_LB
-        sldi    r3, r3, 32
-        nor     r3, r3, r3
-        mfspr   r4, SPRN_HID6
-        and     r4, r4, r3
-        addi    r3, 0, 0x02000
-        sldi    r3, r3, 32
-        or      r4, r4, r3
-        mtspr   SPRN_HID6, r4
-       blr
-
 _GLOBAL(__setup_cpu_ppc970)
        mfspr   r0,SPRN_HID0
        li      r11,5                   /* clear DOZE and SLEEP */
index 3f7182db9ed50cbafcc2992c0bb64fbb66a836e1..dfe2fcfb20a095c2a93b6d9e275f34ace6739ade 100644 (file)
@@ -30,11 +30,7 @@ EXPORT_SYMBOL(cur_cpu_spec);
  * part of the cputable though. That has to be fixed for both ppc32
  * and ppc64
  */
-#ifdef CONFIG_PPC64
-extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec);
-extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec);
-extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec);
-#else
+#ifdef CONFIG_PPC32
 extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec);
@@ -58,7 +54,8 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
 #define COMMON_USER_POWER5_PLUS        (COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS|\
                                 PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP)
 #define COMMON_USER_POWER6     (COMMON_USER_PPC64 | PPC_FEATURE_ARCH_2_05 |\
-                                PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP)
+                                PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP | \
+                                PPC_FEATURE_TRUE_LE)
 #define COMMON_USER_BOOKE      (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
                                 PPC_FEATURE_BOOKE)
 
@@ -78,11 +75,10 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x00400000,
                .cpu_name               = "POWER3 (630)",
                .cpu_features           = CPU_FTRS_POWER3,
-               .cpu_user_features      = COMMON_USER_PPC64,
+               .cpu_user_features      = COMMON_USER_PPC64|PPC_FEATURE_PPC_LE,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .num_pmcs               = 8,
-               .cpu_setup              = __setup_cpu_power3,
                .oprofile_cpu_type      = "ppc64/power3",
                .oprofile_type          = PPC_OPROFILE_RS64,
                .platform               = "power3",
@@ -92,11 +88,10 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x00410000,
                .cpu_name               = "POWER3 (630+)",
                .cpu_features           = CPU_FTRS_POWER3,
-               .cpu_user_features      = COMMON_USER_PPC64,
+               .cpu_user_features      = COMMON_USER_PPC64|PPC_FEATURE_PPC_LE,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .num_pmcs               = 8,
-               .cpu_setup              = __setup_cpu_power3,
                .oprofile_cpu_type      = "ppc64/power3",
                .oprofile_type          = PPC_OPROFILE_RS64,
                .platform               = "power3",
@@ -110,7 +105,6 @@ struct cpu_spec     cpu_specs[] = {
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .num_pmcs               = 8,
-               .cpu_setup              = __setup_cpu_power3,
                .oprofile_cpu_type      = "ppc64/rs64",
                .oprofile_type          = PPC_OPROFILE_RS64,
                .platform               = "rs64",
@@ -124,7 +118,6 @@ struct cpu_spec     cpu_specs[] = {
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .num_pmcs               = 8,
-               .cpu_setup              = __setup_cpu_power3,
                .oprofile_cpu_type      = "ppc64/rs64",
                .oprofile_type          = PPC_OPROFILE_RS64,
                .platform               = "rs64",
@@ -138,7 +131,6 @@ struct cpu_spec     cpu_specs[] = {
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .num_pmcs               = 8,
-               .cpu_setup              = __setup_cpu_power3,
                .oprofile_cpu_type      = "ppc64/rs64",
                .oprofile_type          = PPC_OPROFILE_RS64,
                .platform               = "rs64",
@@ -152,7 +144,6 @@ struct cpu_spec     cpu_specs[] = {
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .num_pmcs               = 8,
-               .cpu_setup              = __setup_cpu_power3,
                .oprofile_cpu_type      = "ppc64/rs64",
                .oprofile_type          = PPC_OPROFILE_RS64,
                .platform               = "rs64",
@@ -166,7 +157,6 @@ struct cpu_spec     cpu_specs[] = {
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .num_pmcs               = 8,
-               .cpu_setup              = __setup_cpu_power4,
                .oprofile_cpu_type      = "ppc64/power4",
                .oprofile_type          = PPC_OPROFILE_POWER4,
                .platform               = "power4",
@@ -180,7 +170,6 @@ struct cpu_spec     cpu_specs[] = {
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .num_pmcs               = 8,
-               .cpu_setup              = __setup_cpu_power4,
                .oprofile_cpu_type      = "ppc64/power4",
                .oprofile_type          = PPC_OPROFILE_POWER4,
                .platform               = "power4",
@@ -232,6 +221,7 @@ struct cpu_spec     cpu_specs[] = {
                        PPC_FEATURE_HAS_ALTIVEC_COMP,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
+               .num_pmcs               = 8,
                .cpu_setup              = __setup_cpu_ppc970,
                .oprofile_cpu_type      = "ppc64/970",
                .oprofile_type          = PPC_OPROFILE_POWER4,
@@ -246,9 +236,13 @@ struct cpu_spec    cpu_specs[] = {
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .num_pmcs               = 6,
-               .cpu_setup              = __setup_cpu_power4,
                .oprofile_cpu_type      = "ppc64/power5",
                .oprofile_type          = PPC_OPROFILE_POWER4,
+               /* SIHV / SIPR bits are implemented on POWER4+ (GQ)
+                * and above but only works on POWER5 and above
+                */
+               .oprofile_mmcra_sihv    = MMCRA_SIHV,
+               .oprofile_mmcra_sipr    = MMCRA_SIPR,
                .platform               = "power5",
        },
        {       /* Power5 GS */
@@ -260,9 +254,10 @@ struct cpu_spec    cpu_specs[] = {
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .num_pmcs               = 6,
-               .cpu_setup              = __setup_cpu_power4,
                .oprofile_cpu_type      = "ppc64/power5+",
                .oprofile_type          = PPC_OPROFILE_POWER4,
+               .oprofile_mmcra_sihv    = MMCRA_SIHV,
+               .oprofile_mmcra_sipr    = MMCRA_SIPR,
                .platform               = "power5+",
        },
        {       /* Power6 */
@@ -273,10 +268,13 @@ struct cpu_spec   cpu_specs[] = {
                .cpu_user_features      = COMMON_USER_POWER6,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
-               .num_pmcs               = 6,
-               .cpu_setup              = __setup_cpu_power4,
+               .num_pmcs               = 8,
                .oprofile_cpu_type      = "ppc64/power6",
                .oprofile_type          = PPC_OPROFILE_POWER4,
+               .oprofile_mmcra_sihv    = POWER6_MMCRA_SIHV,
+               .oprofile_mmcra_sipr    = POWER6_MMCRA_SIPR,
+               .oprofile_mmcra_clear   = POWER6_MMCRA_THRM |
+                       POWER6_MMCRA_OTHER,
                .platform               = "power6",
        },
        {       /* Cell Broadband Engine */
@@ -289,7 +287,6 @@ struct cpu_spec     cpu_specs[] = {
                        PPC_FEATURE_SMT,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
-               .cpu_setup              = __setup_cpu_be,
                .platform               = "ppc-cell-be",
        },
        {       /* default match */
@@ -301,7 +298,6 @@ struct cpu_spec     cpu_specs[] = {
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .num_pmcs               = 6,
-               .cpu_setup              = __setup_cpu_power4,
                .platform               = "power4",
        }
 #endif /* CONFIG_PPC64 */
@@ -323,7 +319,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x00030000,
                .cpu_name               = "603",
                .cpu_features           = CPU_FTRS_603,
-               .cpu_user_features      = COMMON_USER,
+               .cpu_user_features      = COMMON_USER | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .cpu_setup              = __setup_cpu_603,
@@ -334,7 +330,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x00060000,
                .cpu_name               = "603e",
                .cpu_features           = CPU_FTRS_603,
-               .cpu_user_features      = COMMON_USER,
+               .cpu_user_features      = COMMON_USER | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .cpu_setup              = __setup_cpu_603,
@@ -345,7 +341,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x00070000,
                .cpu_name               = "603ev",
                .cpu_features           = CPU_FTRS_603,
-               .cpu_user_features      = COMMON_USER,
+               .cpu_user_features      = COMMON_USER | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .cpu_setup              = __setup_cpu_603,
@@ -356,7 +352,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x00040000,
                .cpu_name               = "604",
                .cpu_features           = CPU_FTRS_604,
-               .cpu_user_features      = COMMON_USER,
+               .cpu_user_features      = COMMON_USER | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 2,
@@ -368,7 +364,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x00090000,
                .cpu_name               = "604e",
                .cpu_features           = CPU_FTRS_604,
-               .cpu_user_features      = COMMON_USER,
+               .cpu_user_features      = COMMON_USER | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
@@ -380,7 +376,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x00090000,
                .cpu_name               = "604r",
                .cpu_features           = CPU_FTRS_604,
-               .cpu_user_features      = COMMON_USER,
+               .cpu_user_features      = COMMON_USER | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
@@ -392,7 +388,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x000a0000,
                .cpu_name               = "604ev",
                .cpu_features           = CPU_FTRS_604,
-               .cpu_user_features      = COMMON_USER,
+               .cpu_user_features      = COMMON_USER | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
@@ -404,7 +400,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x00084202,
                .cpu_name               = "740/750",
                .cpu_features           = CPU_FTRS_740_NOTAU,
-               .cpu_user_features      = COMMON_USER,
+               .cpu_user_features      = COMMON_USER | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
@@ -416,7 +412,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x00080100,
                .cpu_name               = "750CX",
                .cpu_features           = CPU_FTRS_750,
-               .cpu_user_features      = COMMON_USER,
+               .cpu_user_features      = COMMON_USER | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
@@ -428,7 +424,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x00082200,
                .cpu_name               = "750CX",
                .cpu_features           = CPU_FTRS_750,
-               .cpu_user_features      = COMMON_USER,
+               .cpu_user_features      = COMMON_USER | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
@@ -440,7 +436,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x00082210,
                .cpu_name               = "750CXe",
                .cpu_features           = CPU_FTRS_750,
-               .cpu_user_features      = COMMON_USER,
+               .cpu_user_features      = COMMON_USER | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
@@ -452,7 +448,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x00083214,
                .cpu_name               = "750CXe",
                .cpu_features           = CPU_FTRS_750,
-               .cpu_user_features      = COMMON_USER,
+               .cpu_user_features      = COMMON_USER | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
@@ -464,7 +460,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x00083000,
                .cpu_name               = "745/755",
                .cpu_features           = CPU_FTRS_750,
-               .cpu_user_features      = COMMON_USER,
+               .cpu_user_features      = COMMON_USER | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
@@ -476,7 +472,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x70000100,
                .cpu_name               = "750FX",
                .cpu_features           = CPU_FTRS_750FX1,
-               .cpu_user_features      = COMMON_USER,
+               .cpu_user_features      = COMMON_USER | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
@@ -488,7 +484,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x70000200,
                .cpu_name               = "750FX",
                .cpu_features           = CPU_FTRS_750FX2,
-               .cpu_user_features      = COMMON_USER,
+               .cpu_user_features      = COMMON_USER | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
@@ -500,7 +496,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x70000000,
                .cpu_name               = "750FX",
                .cpu_features           = CPU_FTRS_750FX,
-               .cpu_user_features      = COMMON_USER,
+               .cpu_user_features      = COMMON_USER | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
@@ -512,7 +508,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x70020000,
                .cpu_name               = "750GX",
                .cpu_features           = CPU_FTRS_750GX,
-               .cpu_user_features      = COMMON_USER,
+               .cpu_user_features      = COMMON_USER | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
@@ -524,7 +520,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x00080000,
                .cpu_name               = "740/750",
                .cpu_features           = CPU_FTRS_740,
-               .cpu_user_features      = COMMON_USER,
+               .cpu_user_features      = COMMON_USER | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
@@ -536,7 +532,8 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x000c1101,
                .cpu_name               = "7400 (1.1)",
                .cpu_features           = CPU_FTRS_7400_NOTAU,
-               .cpu_user_features      = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
+               .cpu_user_features      = COMMON_USER |
+                       PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
@@ -548,7 +545,8 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x000c0000,
                .cpu_name               = "7400",
                .cpu_features           = CPU_FTRS_7400,
-               .cpu_user_features      = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
+               .cpu_user_features      = COMMON_USER |
+                       PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
@@ -560,7 +558,8 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x800c0000,
                .cpu_name               = "7410",
                .cpu_features           = CPU_FTRS_7400,
-               .cpu_user_features      = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
+               .cpu_user_features      = COMMON_USER |
+                       PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 4,
@@ -572,7 +571,8 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x80000200,
                .cpu_name               = "7450",
                .cpu_features           = CPU_FTRS_7450_20,
-               .cpu_user_features      = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
+               .cpu_user_features      = COMMON_USER |
+                       PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
@@ -586,7 +586,8 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x80000201,
                .cpu_name               = "7450",
                .cpu_features           = CPU_FTRS_7450_21,
-               .cpu_user_features      = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
+               .cpu_user_features      = COMMON_USER |
+                       PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
@@ -600,7 +601,8 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x80000000,
                .cpu_name               = "7450",
                .cpu_features           = CPU_FTRS_7450_23,
-               .cpu_user_features      = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
+               .cpu_user_features      = COMMON_USER |
+                       PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
@@ -614,7 +616,8 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x80010100,
                .cpu_name               = "7455",
                .cpu_features           = CPU_FTRS_7455_1,
-               .cpu_user_features      = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
+               .cpu_user_features      = COMMON_USER |
+                       PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
@@ -628,7 +631,8 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x80010200,
                .cpu_name               = "7455",
                .cpu_features           = CPU_FTRS_7455_20,
-               .cpu_user_features      = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
+               .cpu_user_features      = COMMON_USER |
+                       PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
@@ -642,7 +646,8 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x80010000,
                .cpu_name               = "7455",
                .cpu_features           = CPU_FTRS_7455,
-               .cpu_user_features      = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
+               .cpu_user_features      = COMMON_USER |
+                       PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
@@ -656,7 +661,8 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x80020100,
                .cpu_name               = "7447/7457",
                .cpu_features           = CPU_FTRS_7447_10,
-               .cpu_user_features      = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
+               .cpu_user_features      = COMMON_USER |
+                       PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
@@ -670,7 +676,8 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x80020101,
                .cpu_name               = "7447/7457",
                .cpu_features           = CPU_FTRS_7447_10,
-               .cpu_user_features      = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
+               .cpu_user_features      = COMMON_USER |
+                       PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
@@ -684,7 +691,7 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x80020000,
                .cpu_name               = "7447/7457",
                .cpu_features           = CPU_FTRS_7447,
-               .cpu_user_features      = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
+               .cpu_user_features      = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
@@ -698,7 +705,8 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x80030000,
                .cpu_name               = "7447A",
                .cpu_features           = CPU_FTRS_7447A,
-               .cpu_user_features      = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
+               .cpu_user_features      = COMMON_USER |
+                       PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
@@ -712,7 +720,8 @@ struct cpu_spec     cpu_specs[] = {
                .pvr_value              = 0x80040000,
                .cpu_name               = "7448",
                .cpu_features           = CPU_FTRS_7447A,
-               .cpu_user_features      = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
+               .cpu_user_features      = COMMON_USER |
+                       PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE,
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
                .num_pmcs               = 6,
index 778f22fd85d2e96eab7e3e84ed19ac0f25fb3765..dbcb85994f461883e4047178c4e853a9ef9e1aea 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/elf.h>
 #include <linux/elfcore.h>
 #include <linux/init.h>
+#include <linux/irq.h>
 #include <linux/types.h>
 
 #include <asm/processor.h>
@@ -174,6 +175,8 @@ static void crash_kexec_prepare_cpus(void)
 
 void default_machine_crash_shutdown(struct pt_regs *regs)
 {
+       unsigned int irq;
+
        /*
         * This function is only called after the system
         * has paniced or is otherwise in a critical state.
@@ -186,6 +189,16 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
         */
        local_irq_disable();
 
+       for_each_irq(irq) {
+               struct irq_desc *desc = irq_descp(irq);
+
+               if (desc->status & IRQ_INPROGRESS)
+                       desc->handler->end(irq);
+
+               if (!(desc->status & IRQ_DISABLED))
+                       desc->handler->disable(irq);
+       }
+
        if (ppc_md.kexec_cpu_down)
                ppc_md.kexec_cpu_down(1, 0);
 
index 764d073297165cc4792e83c1d3a1191ac34d09c0..371973be8d7117fad31cd342d18a679c091c89a1 100644 (file)
 #define DBG(fmt...)
 #endif
 
+void reserve_kdump_trampoline(void)
+{
+       lmb_reserve(0, KDUMP_RESERVE_LIMIT);
+}
+
 static void __init create_trampoline(unsigned long addr)
 {
        /* The maximum range of a single instruction branch, is the current
@@ -39,11 +44,11 @@ static void __init create_trampoline(unsigned long addr)
        create_branch(addr + 4, addr + PHYSICAL_START, 0);
 }
 
-void __init kdump_setup(void)
+void __init setup_kdump_trampoline(void)
 {
        unsigned long i;
 
-       DBG(" -> kdump_setup()\n");
+       DBG(" -> setup_kdump_trampoline()\n");
 
        for (i = KDUMP_TRAMPOLINE_START; i < KDUMP_TRAMPOLINE_END; i += 8) {
                create_trampoline(i);
@@ -52,7 +57,7 @@ void __init kdump_setup(void)
        create_trampoline(__pa(system_reset_fwnmi) - PHYSICAL_START);
        create_trampoline(__pa(machine_check_fwnmi) - PHYSICAL_START);
 
-       DBG(" <- kdump_setup()\n");
+       DBG(" <- setup_kdump_trampoline()\n");
 }
 
 #ifdef CONFIG_PROC_VMCORE
index fd8214caedeedcdcfc4b44a660669ee2a9cda543..a13a93dfc65539e7a70ef75baab047bcb250e277 100644 (file)
@@ -106,8 +106,6 @@ EXPORT_SYMBOL(iowrite32_rep);
 
 void __iomem *ioport_map(unsigned long port, unsigned int len)
 {
-       if (!_IO_IS_VALID(port))
-               return NULL;
        return (void __iomem *) (port+pci_io_base);
 }
 
index 4eba60a328907d753cbcb0ab5ab2736552e3a8e1..cef8cba8329b1fb2f8eb691a34e3539b06bc226b 100644 (file)
@@ -536,11 +536,12 @@ void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
  * to the dma address (mapping) of the first page.
  */
 void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
-               dma_addr_t *dma_handle, unsigned long mask, gfp_t flag)
+               dma_addr_t *dma_handle, unsigned long mask, gfp_t flag, int node)
 {
        void *ret = NULL;
        dma_addr_t mapping;
        unsigned int npages, order;
+       struct page *page;
 
        size = PAGE_ALIGN(size);
        npages = size >> PAGE_SHIFT;
@@ -560,9 +561,10 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
                return NULL;
 
        /* Alloc enough pages (and possibly more) */
-       ret = (void *)__get_free_pages(flag, order);
-       if (!ret)
+       page = alloc_pages_node(node, flag, order);
+       if (!page)
                return NULL;
+       ret = page_address(page);
        memset(ret, 0, size);
 
        /* Set up tces to cover the allocated range */
@@ -570,9 +572,9 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
                              mask >> PAGE_SHIFT, order);
        if (mapping == DMA_ERROR_CODE) {
                free_pages((unsigned long)ret, order);
-               ret = NULL;
-       } else
-               *dma_handle = mapping;
+               return NULL;
+       }
+       *dma_handle = mapping;
        return ret;
 }
 
index 2cbde865d4f57b5cc0e1d871d26933e36d927eec..c02deaab26c78d241f15b6c805a38309fdfe52b7 100644 (file)
@@ -521,10 +521,10 @@ static ssize_t lparcfg_write(struct file *file, const char __user * buf,
 
        current_weight = (resource >> 5 * 8) & 0xFF;
 
-       pr_debug("%s: current_entitled = %lu, current_weight = %lu\n",
+       pr_debug("%s: current_entitled = %lu, current_weight = %u\n",
                 __FUNCTION__, current_entitled, current_weight);
 
-       pr_debug("%s: new_entitled = %lu, new_weight = %lu\n",
+       pr_debug("%s: new_entitled = %lu, new_weight = %u\n",
                 __FUNCTION__, *new_entitled_ptr, *new_weight_ptr);
 
        retval = plpar_hcall_norets(H_SET_PPP, *new_entitled_ptr,
index ee166c586642c7a61a0a727be0632d9e08b34412..a8fa04ef27cd79597a65842f8e9b380d8eb3d828 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/machdep.h>
 #include <asm/cacheflush.h>
 #include <asm/paca.h>
+#include <asm/lmb.h>
 #include <asm/mmu.h>
 #include <asm/sections.h>      /* _end */
 #include <asm/prom.h>
@@ -335,7 +336,105 @@ static void __init export_htab_values(void)
        of_node_put(node);
 }
 
+static struct property crashk_base_prop = {
+       .name = "linux,crashkernel-base",
+       .length = sizeof(unsigned long),
+       .value = (unsigned char *)&crashk_res.start,
+};
+
+static unsigned long crashk_size;
+
+static struct property crashk_size_prop = {
+       .name = "linux,crashkernel-size",
+       .length = sizeof(unsigned long),
+       .value = (unsigned char *)&crashk_size,
+};
+
+static void __init export_crashk_values(void)
+{
+       struct device_node *node;
+       struct property *prop;
+
+       node = of_find_node_by_path("/chosen");
+       if (!node)
+               return;
+
+       /* There might be existing crash kernel properties, but we can't
+        * be sure what's in them, so remove them. */
+       prop = of_find_property(node, "linux,crashkernel-base", NULL);
+       if (prop)
+               prom_remove_property(node, prop);
+
+       prop = of_find_property(node, "linux,crashkernel-size", NULL);
+       if (prop)
+               prom_remove_property(node, prop);
+
+       if (crashk_res.start != 0) {
+               prom_add_property(node, &crashk_base_prop);
+               crashk_size = crashk_res.end - crashk_res.start + 1;
+               prom_add_property(node, &crashk_size_prop);
+       }
+
+       of_node_put(node);
+}
+
 void __init kexec_setup(void)
 {
        export_htab_values();
+       export_crashk_values();
+}
+
+static int __init early_parse_crashk(char *p)
+{
+       unsigned long size;
+
+       if (!p)
+               return 1;
+
+       size = memparse(p, &p);
+
+       if (*p == '@')
+               crashk_res.start = memparse(p + 1, &p);
+       else
+               crashk_res.start = KDUMP_KERNELBASE;
+
+       crashk_res.end = crashk_res.start + size - 1;
+
+       return 0;
+}
+early_param("crashkernel", early_parse_crashk);
+
+void __init reserve_crashkernel(void)
+{
+       unsigned long size;
+
+       if (crashk_res.start == 0)
+               return;
+
+       /* We might have got these values via the command line or the
+        * device tree, either way sanitise them now. */
+
+       size = crashk_res.end - crashk_res.start + 1;
+
+       if (crashk_res.start != KDUMP_KERNELBASE)
+               printk("Crash kernel location must be 0x%x\n",
+                               KDUMP_KERNELBASE);
+
+       crashk_res.start = KDUMP_KERNELBASE;
+       size = PAGE_ALIGN(size);
+       crashk_res.end = crashk_res.start + size - 1;
+
+       /* Crash kernel trumps memory limit */
+       if (memory_limit && memory_limit <= crashk_res.end) {
+               memory_limit = crashk_res.end + 1;
+               printk("Adjusted memory limit for crashkernel, now 0x%lx\n",
+                               memory_limit);
+       }
+
+       lmb_reserve(crashk_res.start, size);
+}
+
+int overlaps_crashkernel(unsigned long start, unsigned long size)
+{
+       return (start + size) > crashk_res.start && start <= crashk_res.end;
 }
index be982023409ec2179833ebceefd4a6ff02aa32c7..01d3916c4cb13f6dc01b431328f3f2a1a49e4007 100644 (file)
@@ -216,7 +216,7 @@ _GLOBAL(call_setup_cpu)
        lwz     r4,0(r4)
        add     r4,r4,r3
        lwz     r5,CPU_SPEC_SETUP(r4)
-       cmp   0,r5,0
+       cmpwi   0,r5,0
        add     r5,r5,r3
        beqlr
        mtctr   r5
index 2778cce058e2af29ff7d66152dfd59d4d7d62fe4..e8883d42c43c16c2d237d9cf81ea3a34a8105bd8 100644 (file)
@@ -482,7 +482,9 @@ _GLOBAL(identify_cpu)
        sub     r0,r3,r5
        std     r0,0(r4)
        ld      r4,CPU_SPEC_SETUP(r3)
+       cmpdi   0,r4,0
        add     r4,r4,r5
+       beqlr
        ld      r4,0(r4)
        add     r4,r4,r5
        mtctr   r4
@@ -768,9 +770,6 @@ _GLOBAL(giveup_altivec)
 
 #endif /* CONFIG_ALTIVEC */
 
-_GLOBAL(__setup_cpu_power3)
-       blr
-
 _GLOBAL(execve)
        li      r0,__NR_execve
        sc
index ada50aa5b6000dd57148f19696c49397badcc5e2..6960f090991ed2fcabc318bd1743a04c6d9550d4 100644 (file)
@@ -204,7 +204,7 @@ static void nvram_print_partitions(char * label)
        printk(KERN_WARNING "indx\t\tsig\tchks\tlen\tname\n");
        list_for_each(p, &nvram_part->partition) {
                tmp_part = list_entry(p, struct nvram_partition, partition);
-               printk(KERN_WARNING "%d    \t%02x\t%02x\t%d\t%s\n",
+               printk(KERN_WARNING "%4d    \t%02x\t%02x\t%d\t%s\n",
                       tmp_part->index, tmp_part->header.signature,
                       tmp_part->header.checksum, tmp_part->header.length,
                       tmp_part->header.name);
index 4c4449be81ce4395ca253acda7e66cbac3993550..30a4e6a1368ac855753cc0f65b910155038ddc87 100644 (file)
 unsigned long pci_probe_only = 1;
 int pci_assign_all_buses = 0;
 
-/*
- * legal IO pages under MAX_ISA_PORT.  This is to ensure we don't touch
- * devices we don't have access to.
- */
-unsigned long io_page_mask;
-
-EXPORT_SYMBOL(io_page_mask);
-
 #ifdef CONFIG_PPC_MULTIPLATFORM
 static void fixup_resource(struct resource *res, struct pci_dev *dev);
 static void do_bus_setup(struct pci_bus *bus);
@@ -605,7 +597,7 @@ static int __init pcibios_init(void)
        iSeries_pcibios_init(); 
 #endif
 
-       printk("PCI: Probing PCI hardware\n");
+       printk(KERN_DEBUG "PCI: Probing PCI hardware\n");
 
        /* Scan all of the recorded PCI controllers.  */
        list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
@@ -630,14 +622,14 @@ static int __init pcibios_init(void)
        /* Cache the location of the ISA bridge (if we have one) */
        ppc64_isabridge_dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
        if (ppc64_isabridge_dev != NULL)
-               printk("ISA bridge at %s\n", pci_name(ppc64_isabridge_dev));
+               printk(KERN_DEBUG "ISA bridge at %s\n", pci_name(ppc64_isabridge_dev));
 
 #ifdef CONFIG_PPC_MULTIPLATFORM
        /* map in PCI I/O space */
        phbs_remap_io();
 #endif
 
-       printk("PCI: Probing PCI hardware done\n");
+       printk(KERN_DEBUG "PCI: Probing PCI hardware done\n");
 
        return 0;
 }
@@ -804,7 +796,7 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
        else
                prot |= _PAGE_GUARDED;
 
-       printk("PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start,
+       printk(KERN_DEBUG "PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start,
               prot);
 
        return __pgprot(prot);
@@ -894,8 +886,8 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
        return ret;
 }
 
-#ifdef CONFIG_PPC_MULTIPLATFORM
-static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t pci_show_devspec(struct device *dev,
+               struct device_attribute *attr, char *buf)
 {
        struct pci_dev *pdev;
        struct device_node *np;
@@ -907,13 +899,10 @@ static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *att
        return sprintf(buf, "%s", np->full_name);
 }
 static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
-#endif /* CONFIG_PPC_MULTIPLATFORM */
 
 void pcibios_add_platform_entries(struct pci_dev *pdev)
 {
-#ifdef CONFIG_PPC_MULTIPLATFORM
        device_create_file(&pdev->dev, &dev_attr_devspec);
-#endif /* CONFIG_PPC_MULTIPLATFORM */
 }
 
 #ifdef CONFIG_PPC_MULTIPLATFORM
@@ -1104,8 +1093,6 @@ void __init pci_setup_phb_io(struct pci_controller *hose, int primary)
                        pci_process_ISA_OF_ranges(isa_dn, hose->io_base_phys,
                                                hose->io_base_virt);
                        of_node_put(isa_dn);
-                       /* Allow all IO */
-                       io_page_mask = -1;
                }
        }
 
@@ -1212,7 +1199,7 @@ int remap_bus_range(struct pci_bus *bus)
                return 1;
        if (start_phys == 0)
                return 1;
-       printk("mapping IO %lx -> %lx, size: %lx\n", start_phys, start_virt, size);
+       printk(KERN_DEBUG "mapping IO %lx -> %lx, size: %lx\n", start_phys, start_virt, size);
        if (__ioremap_explicit(start_phys, start_virt, size,
                               _PAGE_NO_CACHE | _PAGE_GUARDED))
                return 1;
@@ -1232,27 +1219,13 @@ static void phbs_remap_io(void)
 static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
 {
        struct pci_controller *hose = pci_bus_to_host(dev->bus);
-       unsigned long start, end, mask, offset;
+       unsigned long offset;
 
        if (res->flags & IORESOURCE_IO) {
                offset = (unsigned long)hose->io_base_virt - pci_io_base;
 
-               start = res->start += offset;
-               end = res->end += offset;
-
-               /* Need to allow IO access to pages that are in the
-                  ISA range */
-               if (start < MAX_ISA_PORT) {
-                       if (end > MAX_ISA_PORT)
-                               end = MAX_ISA_PORT;
-
-                       start >>= PAGE_SHIFT;
-                       end >>= PAGE_SHIFT;
-
-                       /* get the range of pages for the map */
-                       mask = ((1 << (end+1)) - 1) ^ ((1 << start) - 1);
-                       io_page_mask |= mask;
-               }
+               res->start += offset;
+               res->end += offset;
        } else if (res->flags & IORESOURCE_MEM) {
                res->start += hose->pci_mem_offset;
                res->end += hose->pci_mem_offset;
index 12c4c9e9bbc7bc3bb9165d3d8b055d1538cff5e6..1c18953514c3d0a15aea5efce1eaf0092c40c8c1 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/pci-bridge.h>
 #include <asm/pSeries_reconfig.h>
 #include <asm/ppc-pci.h>
+#include <asm/firmware.h>
 
 /*
  * Traverse_func that inits the PCI fields of the device node.
@@ -59,6 +60,11 @@ static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
                pdn->busno = (regs[0] >> 16) & 0xff;
                pdn->devfn = (regs[0] >> 8) & 0xff;
        }
+       if (firmware_has_feature(FW_FEATURE_ISERIES)) {
+               u32 *busp = (u32 *)get_property(dn, "linux,subbus", NULL);
+               if (busp)
+                       pdn->bussubno = *busp;
+       }
 
        pdn->pci_ext_config_space = (type && *type == 1);
        return NULL;
index c1d95e14bbed21e8f979367baa5ee1a2b71c9a69..7fb4cca021be57e3e311cda66935e12f1237ce50 100644 (file)
  */
 #define PCI_GET_DN(dev) ((struct device_node *)((dev)->sysdata))
 
-static inline struct iommu_table *devnode_table(struct device *dev)
+static inline struct iommu_table *device_to_table(struct device *hwdev)
 {
        struct pci_dev *pdev;
 
-       if (!dev) {
+       if (!hwdev) {
                pdev = ppc64_isabridge_dev;
                if (!pdev)
                        return NULL;
        } else
-               pdev = to_pci_dev(dev);
+               pdev = to_pci_dev(hwdev);
 
        return PCI_DN(PCI_GET_DN(pdev))->iommu_table;
 }
@@ -85,14 +85,15 @@ static inline unsigned long device_to_mask(struct device *hwdev)
 static void *pci_iommu_alloc_coherent(struct device *hwdev, size_t size,
                           dma_addr_t *dma_handle, gfp_t flag)
 {
-       return iommu_alloc_coherent(devnode_table(hwdev), size, dma_handle,
-                       device_to_mask(hwdev), flag);
+       return iommu_alloc_coherent(device_to_table(hwdev), size, dma_handle,
+                       device_to_mask(hwdev), flag,
+                       pcibus_to_node(to_pci_dev(hwdev)->bus));
 }
 
 static void pci_iommu_free_coherent(struct device *hwdev, size_t size,
                         void *vaddr, dma_addr_t dma_handle)
 {
-       iommu_free_coherent(devnode_table(hwdev), size, vaddr, dma_handle);
+       iommu_free_coherent(device_to_table(hwdev), size, vaddr, dma_handle);
 }
 
 /* Creates TCEs for a user provided buffer.  The user buffer must be 
@@ -104,7 +105,7 @@ static void pci_iommu_free_coherent(struct device *hwdev, size_t size,
 static dma_addr_t pci_iommu_map_single(struct device *hwdev, void *vaddr,
                size_t size, enum dma_data_direction direction)
 {
-       return iommu_map_single(devnode_table(hwdev), vaddr, size,
+       return iommu_map_single(device_to_table(hwdev), vaddr, size,
                                device_to_mask(hwdev), direction);
 }
 
@@ -112,27 +113,27 @@ static dma_addr_t pci_iommu_map_single(struct device *hwdev, void *vaddr,
 static void pci_iommu_unmap_single(struct device *hwdev, dma_addr_t dma_handle,
                size_t size, enum dma_data_direction direction)
 {
-       iommu_unmap_single(devnode_table(hwdev), dma_handle, size, direction);
+       iommu_unmap_single(device_to_table(hwdev), dma_handle, size, direction);
 }
 
 
 static int pci_iommu_map_sg(struct device *pdev, struct scatterlist *sglist,
                int nelems, enum dma_data_direction direction)
 {
-       return iommu_map_sg(pdev, devnode_table(pdev), sglist,
+       return iommu_map_sg(pdev, device_to_table(pdev), sglist,
                        nelems, device_to_mask(pdev), direction);
 }
 
 static void pci_iommu_unmap_sg(struct device *pdev, struct scatterlist *sglist,
                int nelems, enum dma_data_direction direction)
 {
-       iommu_unmap_sg(devnode_table(pdev), sglist, nelems, direction);
+       iommu_unmap_sg(device_to_table(pdev), sglist, nelems, direction);
 }
 
 /* We support DMA to/from any memory page via the iommu */
 static int pci_iommu_dma_supported(struct device *dev, u64 mask)
 {
-       struct iommu_table *tbl = devnode_table(dev);
+       struct iommu_table *tbl = device_to_table(dev);
 
        if (!tbl || tbl->it_offset > mask) {
                printk(KERN_INFO "Warning: IOMMU table offset too big for device mask\n");
index 3c2cf661f6d997bf589c6f1c95cd617be599b622..2b87f82df13516cd623e5e42f7f7e673431513c0 100644 (file)
@@ -52,7 +52,7 @@ static int __init proc_ppc64_create(void)
        if (!root)
                return 1;
 
-       if (!machine_is(pseries) && !machine_is(cell))
+       if (!of_find_node_by_path("/rtas"))
                return 0;
 
        if (!proc_mkdir("rtas", root))
index 2dd47d2dd9980ee604829fc3d4a8d42bfd3155b7..e4732459c48571c6508631b81c6ed46917dae082 100644 (file)
@@ -708,6 +708,61 @@ int get_fpexc_mode(struct task_struct *tsk, unsigned long adr)
        return put_user(val, (unsigned int __user *) adr);
 }
 
+int set_endian(struct task_struct *tsk, unsigned int val)
+{
+       struct pt_regs *regs = tsk->thread.regs;
+
+       if ((val == PR_ENDIAN_LITTLE && !cpu_has_feature(CPU_FTR_REAL_LE)) ||
+           (val == PR_ENDIAN_PPC_LITTLE && !cpu_has_feature(CPU_FTR_PPC_LE)))
+               return -EINVAL;
+
+       if (regs == NULL)
+               return -EINVAL;
+
+       if (val == PR_ENDIAN_BIG)
+               regs->msr &= ~MSR_LE;
+       else if (val == PR_ENDIAN_LITTLE || val == PR_ENDIAN_PPC_LITTLE)
+               regs->msr |= MSR_LE;
+       else
+               return -EINVAL;
+
+       return 0;
+}
+
+int get_endian(struct task_struct *tsk, unsigned long adr)
+{
+       struct pt_regs *regs = tsk->thread.regs;
+       unsigned int val;
+
+       if (!cpu_has_feature(CPU_FTR_PPC_LE) &&
+           !cpu_has_feature(CPU_FTR_REAL_LE))
+               return -EINVAL;
+
+       if (regs == NULL)
+               return -EINVAL;
+
+       if (regs->msr & MSR_LE) {
+               if (cpu_has_feature(CPU_FTR_REAL_LE))
+                       val = PR_ENDIAN_LITTLE;
+               else
+                       val = PR_ENDIAN_PPC_LITTLE;
+       } else
+               val = PR_ENDIAN_BIG;
+
+       return put_user(val, (unsigned int __user *)adr);
+}
+
+int set_unalign_ctl(struct task_struct *tsk, unsigned int val)
+{
+       tsk->thread.align_ctl = val;
+       return 0;
+}
+
+int get_unalign_ctl(struct task_struct *tsk, unsigned long adr)
+{
+       return put_user(tsk->thread.align_ctl, (unsigned int __user *)adr);
+}
+
 #define TRUNC_PTR(x)   ((typeof(x))(((unsigned long)(x)) & 0xffffffff))
 
 int sys_clone(unsigned long clone_flags, unsigned long usp,
index 9a07f97f0712d78ce271b6ec35190cf92032be26..969f4abcc0be64bc625685facacf0edeb55f7b5f 100644 (file)
@@ -50,6 +50,7 @@
 #include <asm/machdep.h>
 #include <asm/pSeries_reconfig.h>
 #include <asm/pci-bridge.h>
+#include <asm/kexec.h>
 
 #ifdef DEBUG
 #define DBG(fmt...) printk(KERN_ERR fmt)
@@ -836,6 +837,42 @@ static unsigned long __init unflatten_dt_node(unsigned long mem,
        return mem;
 }
 
+static int __init early_parse_mem(char *p)
+{
+       if (!p)
+               return 1;
+
+       memory_limit = PAGE_ALIGN(memparse(p, &p));
+       DBG("memory limit = 0x%lx\n", memory_limit);
+
+       return 0;
+}
+early_param("mem", early_parse_mem);
+
+/*
+ * The device tree may be allocated below our memory limit, or inside the
+ * crash kernel region for kdump. If so, move it out now.
+ */
+static void move_device_tree(void)
+{
+       unsigned long start, size;
+       void *p;
+
+       DBG("-> move_device_tree\n");
+
+       start = __pa(initial_boot_params);
+       size = initial_boot_params->totalsize;
+
+       if ((memory_limit && (start + size) > memory_limit) ||
+                       overlaps_crashkernel(start, size)) {
+               p = __va(lmb_alloc_base(size, PAGE_SIZE, lmb.rmo_size));
+               memcpy(p, initial_boot_params, size);
+               initial_boot_params = (struct boot_param_header *)p;
+               DBG("Moved device tree to 0x%p\n", p);
+       }
+
+       DBG("<- move_device_tree\n");
+}
 
 /**
  * unflattens the device-tree passed by the firmware, creating the
@@ -1070,6 +1107,7 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
                iommu_force_on = 1;
 #endif
 
+       /* mem=x on the command line is the preferred mechanism */
        lprop = of_get_flat_dt_prop(node, "linux,memory-limit", NULL);
        if (lprop)
                memory_limit = *lprop;
@@ -1123,17 +1161,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
 
        DBG("Command line is: %s\n", cmd_line);
 
-       if (strstr(cmd_line, "mem=")) {
-               char *p, *q;
-
-               for (q = cmd_line; (p = strstr(q, "mem=")) != 0; ) {
-                       q = p + 4;
-                       if (p > cmd_line && p[-1] != ' ')
-                               continue;
-                       memory_limit = memparse(q, &q);
-               }
-       }
-
        /* break now */
        return 1;
 }
@@ -1240,6 +1267,11 @@ static void __init early_reserve_mem(void)
 
        reserve_map = (u64 *)(((unsigned long)initial_boot_params) +
                                        initial_boot_params->off_mem_rsvmap);
+
+       /* before we do anything, lets reserve the dt blob */
+       lmb_reserve(__pa((unsigned long)initial_boot_params),
+                   initial_boot_params->totalsize);
+
 #ifdef CONFIG_PPC32
        /* 
         * Handle the case where we might be booting from an old kexec
@@ -1292,18 +1324,26 @@ void __init early_init_devtree(void *params)
        lmb_init();
        of_scan_flat_dt(early_init_dt_scan_root, NULL);
        of_scan_flat_dt(early_init_dt_scan_memory, NULL);
-       lmb_enforce_memory_limit(memory_limit);
-       lmb_analyze();
 
-       DBG("Phys. mem: %lx\n", lmb_phys_mem_size());
+       /* Save command line for /proc/cmdline and then parse parameters */
+       strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
+       parse_early_param();
 
        /* Reserve LMB regions used by kernel, initrd, dt, etc... */
        lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START);
-#ifdef CONFIG_CRASH_DUMP
-       lmb_reserve(0, KDUMP_RESERVE_LIMIT);
-#endif
+       reserve_kdump_trampoline();
+       reserve_crashkernel();
        early_reserve_mem();
 
+       lmb_enforce_memory_limit(memory_limit);
+       lmb_analyze();
+
+       DBG("Phys. mem: %lx\n", lmb_phys_mem_size());
+
+       /* We may need to relocate the flat tree, do it now.
+        * FIXME .. and the initrd too? */
+       move_device_tree();
+
        DBG("Scanning CPUs ...\n");
 
        /* Retreive CPU related informations from the flat tree
@@ -2053,29 +2093,3 @@ int prom_update_property(struct device_node *np,
        return 0;
 }
 
-#ifdef CONFIG_KEXEC
-/* We may have allocated the flat device tree inside the crash kernel region
- * in prom_init. If so we need to move it out into regular memory. */
-void kdump_move_device_tree(void)
-{
-       unsigned long start, end;
-       struct boot_param_header *new;
-
-       start = __pa((unsigned long)initial_boot_params);
-       end = start + initial_boot_params->totalsize;
-
-       if (end < crashk_res.start || start > crashk_res.end)
-               return;
-
-       new = (struct boot_param_header*)
-               __va(lmb_alloc(initial_boot_params->totalsize, PAGE_SIZE));
-
-       memcpy(new, initial_boot_params, initial_boot_params->totalsize);
-
-       initial_boot_params = new;
-
-       DBG("Flat device tree blob moved to %p\n", initial_boot_params);
-
-       /* XXX should we unreserve the old DT? */
-}
-#endif /* CONFIG_KEXEC */
index f70bd090dacda51fb52b716fb7c8e92e8c27fc1a..57d8a16438a02324186cce165d768e637eaba63b 100644 (file)
@@ -194,19 +194,12 @@ static int __initdata of_platform;
 
 static char __initdata prom_cmd_line[COMMAND_LINE_SIZE];
 
-static unsigned long __initdata prom_memory_limit;
-
 static unsigned long __initdata alloc_top;
 static unsigned long __initdata alloc_top_high;
 static unsigned long __initdata alloc_bottom;
 static unsigned long __initdata rmo_top;
 static unsigned long __initdata ram_top;
 
-#ifdef CONFIG_KEXEC
-static unsigned long __initdata prom_crashk_base;
-static unsigned long __initdata prom_crashk_size;
-#endif
-
 static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE];
 static int __initdata mem_reserve_cnt;
 
@@ -593,45 +586,6 @@ static void __init early_cmdline_parse(void)
                        RELOC(iommu_force_on) = 1;
        }
 #endif
-
-       opt = strstr(RELOC(prom_cmd_line), RELOC("mem="));
-       if (opt) {
-               opt += 4;
-               RELOC(prom_memory_limit) = prom_memparse(opt, (const char **)&opt);
-#ifdef CONFIG_PPC64
-               /* Align to 16 MB == size of ppc64 large page */
-               RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000);
-#endif
-       }
-
-#ifdef CONFIG_KEXEC
-       /*
-        * crashkernel=size@addr specifies the location to reserve for
-        * crash kernel.
-        */
-       opt = strstr(RELOC(prom_cmd_line), RELOC("crashkernel="));
-       if (opt) {
-               opt += 12;
-               RELOC(prom_crashk_size) = 
-                       prom_memparse(opt, (const char **)&opt);
-
-               if (ALIGN(RELOC(prom_crashk_size), 0x1000000) !=
-                       RELOC(prom_crashk_size)) {
-                       prom_printf("Warning: crashkernel size is not "
-                                       "aligned to 16MB\n");
-               }
-
-               /*
-                * At present, the crash kernel always run at 32MB.
-                * Just ignore whatever user passed.
-                */
-               RELOC(prom_crashk_base) = 0x2000000;
-               if (*opt == '@') {
-                       prom_printf("Warning: PPC64 kdump kernel always runs "
-                                       "at 32 MB\n");
-               }
-       }
-#endif
 }
 
 #ifdef CONFIG_PPC_PSERIES
@@ -1115,29 +1069,6 @@ static void __init prom_init_mem(void)
                        RELOC(alloc_bottom) = PAGE_ALIGN(RELOC(prom_initrd_end));
        }
 
-       /*
-        * If prom_memory_limit is set we reduce the upper limits *except* for
-        * alloc_top_high. This must be the real top of RAM so we can put
-        * TCE's up there.
-        */
-
-       RELOC(alloc_top_high) = RELOC(ram_top);
-
-       if (RELOC(prom_memory_limit)) {
-               if (RELOC(prom_memory_limit) <= RELOC(alloc_bottom)) {
-                       prom_printf("Ignoring mem=%x <= alloc_bottom.\n",
-                               RELOC(prom_memory_limit));
-                       RELOC(prom_memory_limit) = 0;
-               } else if (RELOC(prom_memory_limit) >= RELOC(ram_top)) {
-                       prom_printf("Ignoring mem=%x >= ram_top.\n",
-                               RELOC(prom_memory_limit));
-                       RELOC(prom_memory_limit) = 0;
-               } else {
-                       RELOC(ram_top) = RELOC(prom_memory_limit);
-                       RELOC(rmo_top) = min(RELOC(rmo_top), RELOC(prom_memory_limit));
-               }
-       }
-
        /*
         * Setup our top alloc point, that is top of RMO or top of
         * segment 0 when running non-LPAR.
@@ -1150,20 +1081,14 @@ static void __init prom_init_mem(void)
                RELOC(rmo_top) = RELOC(ram_top);
        RELOC(rmo_top) = min(0x30000000ul, RELOC(rmo_top));
        RELOC(alloc_top) = RELOC(rmo_top);
+       RELOC(alloc_top_high) = RELOC(ram_top);
 
        prom_printf("memory layout at init:\n");
-       prom_printf("  memory_limit : %x (16 MB aligned)\n", RELOC(prom_memory_limit));
        prom_printf("  alloc_bottom : %x\n", RELOC(alloc_bottom));
        prom_printf("  alloc_top    : %x\n", RELOC(alloc_top));
        prom_printf("  alloc_top_hi : %x\n", RELOC(alloc_top_high));
        prom_printf("  rmo_top      : %x\n", RELOC(rmo_top));
        prom_printf("  ram_top      : %x\n", RELOC(ram_top));
-#ifdef CONFIG_KEXEC
-       if (RELOC(prom_crashk_base)) {
-               prom_printf("  crashk_base  : %x\n",  RELOC(prom_crashk_base));
-               prom_printf("  crashk_size  : %x\n", RELOC(prom_crashk_size));
-       }
-#endif
 }
 
 
@@ -1349,16 +1274,10 @@ static void __init prom_initialize_tce_table(void)
 
        reserve_mem(local_alloc_bottom, local_alloc_top - local_alloc_bottom);
 
-       if (RELOC(prom_memory_limit)) {
-               /*
-                * We align the start to a 16MB boundary so we can map
-                * the TCE area using large pages if possible.
-                * The end should be the top of RAM so no need to align it.
-                */
-               RELOC(prom_tce_alloc_start) = _ALIGN_DOWN(local_alloc_bottom,
-                                                         0x1000000);
-               RELOC(prom_tce_alloc_end) = local_alloc_top;
-       }
+       /* These are only really needed if there is a memory limit in
+        * effect, but we don't know so export them always. */
+       RELOC(prom_tce_alloc_start) = local_alloc_bottom;
+       RELOC(prom_tce_alloc_end) = local_alloc_top;
 
        /* Flag the first invalid entry */
        prom_debug("ending prom_initialize_tce_table\n");
@@ -2041,11 +1960,7 @@ static void __init flatten_device_tree(void)
        /* Version 16 is not backward compatible */
        hdr->last_comp_version = 0x10;
 
-       /* Reserve the whole thing and copy the reserve map in, we
-        * also bump mem_reserve_cnt to cause further reservations to
-        * fail since it's too late.
-        */
-       reserve_mem(RELOC(dt_header_start), hdr->totalsize);
+       /* Copy the reserve map in */
        memcpy(rsvmap, RELOC(mem_reserve_map), sizeof(mem_reserve_map));
 
 #ifdef DEBUG_PROM
@@ -2058,6 +1973,9 @@ static void __init flatten_device_tree(void)
                                    RELOC(mem_reserve_map)[i].size);
        }
 #endif
+       /* Bump mem_reserve_cnt to cause further reservations to fail
+        * since it's too late.
+        */
        RELOC(mem_reserve_cnt) = MEM_RESERVE_MAP_SIZE;
 
        prom_printf("Device tree strings 0x%x -> 0x%x\n",
@@ -2280,10 +2198,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
         */
        prom_init_mem();
 
-#ifdef CONFIG_KEXEC
-       if (RELOC(prom_crashk_base))
-               reserve_mem(RELOC(prom_crashk_base), RELOC(prom_crashk_size));
-#endif
        /*
         * Determine which cpu is actually running right _now_
         */
@@ -2317,10 +2231,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
        /*
         * Fill in some infos for use by the kernel later on
         */
-       if (RELOC(prom_memory_limit))
-               prom_setprop(_prom->chosen, "/chosen", "linux,memory-limit",
-                            &RELOC(prom_memory_limit),
-                            sizeof(prom_memory_limit));
 #ifdef CONFIG_PPC64
        if (RELOC(ppc64_iommu_off))
                prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off",
@@ -2340,16 +2250,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
        }
 #endif
 
-#ifdef CONFIG_KEXEC
-       if (RELOC(prom_crashk_base)) {
-               prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-base",
-                       PTRRELOC(&prom_crashk_base),
-                       sizeof(RELOC(prom_crashk_base)));
-               prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-size",
-                       PTRRELOC(&prom_crashk_size),
-                       sizeof(RELOC(prom_crashk_size)));
-       }
-#endif
        /*
         * Fixup any known bugs in the device-tree
         */
index 3934c227549b07a1f08ba59c86ac497ce6c0a45f..45df420383cc6d7d8f0a0ef81807b475a2e5c89f 100644 (file)
@@ -548,3 +548,28 @@ int of_pci_address_to_resource(struct device_node *dev, int bar,
        return __of_address_to_resource(dev, addrp, size, flags, r);
 }
 EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
+
+void of_parse_dma_window(struct device_node *dn, unsigned char *dma_window_prop,
+               unsigned long *busno, unsigned long *phys, unsigned long *size)
+{
+       u32 *dma_window, cells;
+       unsigned char *prop;
+
+       dma_window = (u32 *)dma_window_prop;
+
+       /* busno is always one cell */
+       *busno = *(dma_window++);
+
+       prop = get_property(dn, "ibm,#dma-address-cells", NULL);
+       if (!prop)
+               prop = get_property(dn, "#address-cells", NULL);
+
+       cells = prop ? *(u32 *)prop : prom_n_addr_cells(dn);
+       *phys = of_read_addr(dma_window, cells);
+
+       dma_window += cells;
+
+       prop = get_property(dn, "ibm,#dma-size-cells", NULL);
+       cells = prop ? *(u32 *)prop : prom_n_size_cells(dn);
+       *size = of_read_addr(dma_window, cells);
+}
index 4a677d1bd4ef717baa0d748b4652f757ed12a321..5563e2e7d89c8ca934d51ce11599579c7d0baad5 100644 (file)
@@ -404,7 +404,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                ret = ptrace_detach(child, data);
                break;
 
-#ifdef CONFIG_PPC64
        case PPC_PTRACE_GETREGS: { /* Get GPRs 0 - 31. */
                int i;
                unsigned long *reg = &((unsigned long *)child->thread.regs)[0];
@@ -468,7 +467,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                }
                break;
        }
-#endif /* CONFIG_PPC64 */
 
 #ifdef CONFIG_ALTIVEC
        case PTRACE_GETVRREGS:
index 34d073fb60911aff9f672971275bbe8c44e09386..77578c093ddafc6b57936f9e9715d725ec740829 100644 (file)
 unsigned long __init rtas_get_boot_time(void)
 {
        int ret[8];
-       int error, wait_time;
+       int error;
+       unsigned int wait_time;
        u64 max_wait_tb;
 
        max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
        do {
                error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
-               if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
-                       wait_time = rtas_extended_busy_delay_time(error);
+
+               wait_time = rtas_busy_delay_time(error);
+               if (wait_time) {
                        /* This is boot time so we spin. */
                        udelay(wait_time*1000);
-                       error = RTAS_CLOCK_BUSY;
                }
-       } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb));
+       } while (wait_time && (get_tb() < max_wait_tb));
 
        if (error != 0 && printk_ratelimit()) {
                printk(KERN_WARNING "error: reading the clock failed (%d)\n",
@@ -44,24 +45,25 @@ unsigned long __init rtas_get_boot_time(void)
 void rtas_get_rtc_time(struct rtc_time *rtc_tm)
 {
         int ret[8];
-       int error, wait_time;
+       int error;
+       unsigned int wait_time;
        u64 max_wait_tb;
 
        max_wait_tb = get_tb() + tb_ticks_per_usec * 1000 * MAX_RTC_WAIT;
        do {
                error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret);
-               if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
+
+               wait_time = rtas_busy_delay_time(error);
+               if (wait_time) {
                        if (in_interrupt() && printk_ratelimit()) {
                                memset(rtc_tm, 0, sizeof(struct rtc_time));
                                printk(KERN_WARNING "error: reading clock"
                                       " would delay interrupt\n");
                                return; /* delay not allowed */
                        }
-                       wait_time = rtas_extended_busy_delay_time(error);
                        msleep(wait_time);
-                       error = RTAS_CLOCK_BUSY;
                }
-       } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb));
+       } while (wait_time && (get_tb() < max_wait_tb));
 
         if (error != 0 && printk_ratelimit()) {
                 printk(KERN_WARNING "error: reading the clock failed (%d)\n",
@@ -88,14 +90,14 @@ int rtas_set_rtc_time(struct rtc_time *tm)
                                  tm->tm_year + 1900, tm->tm_mon + 1,
                                  tm->tm_mday, tm->tm_hour, tm->tm_min,
                                  tm->tm_sec, 0);
-               if (error == RTAS_CLOCK_BUSY || rtas_is_extended_busy(error)) {
+
+               wait_time = rtas_busy_delay_time(error);
+               if (wait_time) {
                        if (in_interrupt())
                                return 1;       /* probably decrementer */
-                       wait_time = rtas_extended_busy_delay_time(error);
                        msleep(wait_time);
-                       error = RTAS_CLOCK_BUSY;
                }
-       } while (error == RTAS_CLOCK_BUSY && (get_tb() < max_wait_tb));
+       } while (wait_time && (get_tb() < max_wait_tb));
 
         if (error != 0 && printk_ratelimit())
                 printk(KERN_WARNING "error: setting the clock failed (%d)\n",
index 0112318213ab5aada8c00e5ec6877c801501ccd3..13496f3198554fbe1bb6c339fd1f71cefa8b8d25 100644 (file)
@@ -370,24 +370,36 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
        return ret;
 }
 
-/* Given an RTAS status code of 990n compute the hinted delay of 10^n
- * (last digit) milliseconds.  For now we bound at n=5 (100 sec).
+/* For RTAS_BUSY (-2), delay for 1 millisecond.  For an extended busy status
+ * code of 990n, perform the hinted delay of 10^n (last digit) milliseconds.
  */
-unsigned int rtas_extended_busy_delay_time(int status)
+unsigned int rtas_busy_delay_time(int status)
 {
-       int order = status - 9900;
-       unsigned long ms;
+       int order;
+       unsigned int ms = 0;
+
+       if (status == RTAS_BUSY) {
+               ms = 1;
+       } else if (status >= 9900 && status <= 9905) {
+               order = status - 9900;
+               for (ms = 1; order > 0; order--)
+                       ms *= 10;
+       }
 
-       if (order < 0)
-               order = 0;      /* RTC depends on this for -2 clock busy */
-       else if (order > 5)
-               order = 5;      /* bound */
+       return ms;
+}
 
-       /* Use microseconds for reasonable accuracy */
-       for (ms = 1; order > 0; order--)
-               ms *= 10;
+/* For an RTAS busy status code, perform the hinted delay. */
+unsigned int rtas_busy_delay(int status)
+{
+       unsigned int ms;
 
-       return ms; 
+       might_sleep();
+       ms = rtas_busy_delay_time(status);
+       if (ms)
+               msleep(ms);
+
+       return ms;
 }
 
 int rtas_error_rc(int rtas_rc)
@@ -438,22 +450,14 @@ int rtas_get_power_level(int powerdomain, int *level)
 int rtas_set_power_level(int powerdomain, int level, int *setlevel)
 {
        int token = rtas_token("set-power-level");
-       unsigned int wait_time;
        int rc;
 
        if (token == RTAS_UNKNOWN_SERVICE)
                return -ENOENT;
 
-       while (1) {
+       do {
                rc = rtas_call(token, 2, 2, setlevel, powerdomain, level);
-               if (rc == RTAS_BUSY)
-                       udelay(1);
-               else if (rtas_is_extended_busy(rc)) {
-                       wait_time = rtas_extended_busy_delay_time(rc);
-                       udelay(wait_time * 1000);
-               } else
-                       break;
-       }
+       } while (rtas_busy_delay(rc));
 
        if (rc < 0)
                return rtas_error_rc(rc);
@@ -463,22 +467,14 @@ int rtas_set_power_level(int powerdomain, int level, int *setlevel)
 int rtas_get_sensor(int sensor, int index, int *state)
 {
        int token = rtas_token("get-sensor-state");
-       unsigned int wait_time;
        int rc;
 
        if (token == RTAS_UNKNOWN_SERVICE)
                return -ENOENT;
 
-       while (1) {
+       do {
                rc = rtas_call(token, 2, 2, state, sensor, index);
-               if (rc == RTAS_BUSY)
-                       udelay(1);
-               else if (rtas_is_extended_busy(rc)) {
-                       wait_time = rtas_extended_busy_delay_time(rc);
-                       udelay(wait_time * 1000);
-               } else
-                       break;
-       }
+       } while (rtas_busy_delay(rc));
 
        if (rc < 0)
                return rtas_error_rc(rc);
@@ -488,23 +484,14 @@ int rtas_get_sensor(int sensor, int index, int *state)
 int rtas_set_indicator(int indicator, int index, int new_value)
 {
        int token = rtas_token("set-indicator");
-       unsigned int wait_time;
        int rc;
 
        if (token == RTAS_UNKNOWN_SERVICE)
                return -ENOENT;
 
-       while (1) {
+       do {
                rc = rtas_call(token, 3, 1, NULL, indicator, index, new_value);
-               if (rc == RTAS_BUSY)
-                       udelay(1);
-               else if (rtas_is_extended_busy(rc)) {
-                       wait_time = rtas_extended_busy_delay_time(rc);
-                       udelay(wait_time * 1000);
-               }
-               else
-                       break;
-       }
+       } while (rtas_busy_delay(rc));
 
        if (rc < 0)
                return rtas_error_rc(rc);
@@ -555,13 +542,11 @@ void rtas_os_term(char *str)
        do {
                status = rtas_call(rtas_token("ibm,os-term"), 1, 1, NULL,
                                   __pa(rtas_os_term_buf));
+       } while (rtas_busy_delay(status));
 
-               if (status == RTAS_BUSY)
-                       udelay(1);
-               else if (status != 0)
-                       printk(KERN_EMERG "ibm,os-term call failed %d\n",
+       if (status != 0)
+               printk(KERN_EMERG "ibm,os-term call failed %d\n",
                               status);
-       } while (status == RTAS_BUSY);
 }
 
 static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE;
@@ -789,7 +774,7 @@ EXPORT_SYMBOL(rtas_token);
 EXPORT_SYMBOL(rtas_call);
 EXPORT_SYMBOL(rtas_data_buf);
 EXPORT_SYMBOL(rtas_data_buf_lock);
-EXPORT_SYMBOL(rtas_extended_busy_delay_time);
+EXPORT_SYMBOL(rtas_busy_delay_time);
 EXPORT_SYMBOL(rtas_get_sensor);
 EXPORT_SYMBOL(rtas_get_power_level);
 EXPORT_SYMBOL(rtas_set_power_level);
index aaf384c3f04a62eca2bbe497bdfd0b80e905b265..1442b63a75daa1998f5d8c4bc22a6b8d758f46e7 100644 (file)
@@ -365,20 +365,12 @@ static int rtas_excl_release(struct inode *inode, struct file *file)
 
 static void manage_flash(struct rtas_manage_flash_t *args_buf)
 {
-       unsigned int wait_time;
        s32 rc;
 
-       while (1) {
+       do {
                rc = rtas_call(rtas_token("ibm,manage-flash-image"), 1, 
                               1, NULL, args_buf->op);
-               if (rc == RTAS_RC_BUSY)
-                       udelay(1);
-               else if (rtas_is_extended_busy(rc)) {
-                       wait_time = rtas_extended_busy_delay_time(rc);
-                       udelay(wait_time * 1000);
-               } else
-                       break;
-       }
+       } while (rtas_busy_delay(rc));
 
        args_buf->status = rc;
 }
@@ -451,27 +443,18 @@ static ssize_t manage_flash_write(struct file *file, const char __user *buf,
 static void validate_flash(struct rtas_validate_flash_t *args_buf)
 {
        int token = rtas_token("ibm,validate-flash-image");
-       unsigned int wait_time;
        int update_results;
        s32 rc; 
 
        rc = 0;
-       while(1) {
+       do {
                spin_lock(&rtas_data_buf_lock);
                memcpy(rtas_data_buf, args_buf->buf, VALIDATE_BUF_SIZE);
                rc = rtas_call(token, 2, 2, &update_results, 
                               (u32) __pa(rtas_data_buf), args_buf->buf_size);
                memcpy(args_buf->buf, rtas_data_buf, VALIDATE_BUF_SIZE);
                spin_unlock(&rtas_data_buf_lock);
-                       
-               if (rc == RTAS_RC_BUSY)
-                       udelay(1);
-               else if (rtas_is_extended_busy(rc)) {
-                       wait_time = rtas_extended_busy_delay_time(rc);
-                       udelay(wait_time * 1000);
-               } else
-                       break;
-       }
+       } while (rtas_busy_delay(rc));
 
        args_buf->status = rc;
        args_buf->update_results = update_results;
index 684ab1d49c65366d62930c22346cb3581e588e71..bd328123af7550ab032a0fe1f48d11cce0262624 100644 (file)
@@ -443,6 +443,7 @@ void __init smp_setup_cpu_maps(void)
 }
 #endif /* CONFIG_SMP */
 
+int __initdata do_early_xmon;
 #ifdef CONFIG_XMON
 static int __init early_xmon(char *p)
 {
@@ -456,7 +457,7 @@ static int __init early_xmon(char *p)
                        return 0;
        }
        xmon_init(1);
-       debugger(NULL);
+       do_early_xmon = 1;
 
        return 0;
 }
@@ -524,3 +525,20 @@ int check_legacy_ioport(unsigned long base_port)
        return ppc_md.check_legacy_ioport(base_port);
 }
 EXPORT_SYMBOL(check_legacy_ioport);
+
+static int ppc_panic_event(struct notifier_block *this,
+                             unsigned long event, void *ptr)
+{
+       ppc_md.panic(ptr);  /* May not return */
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block ppc_panic_block = {
+       .notifier_call = ppc_panic_event,
+       .priority = INT_MIN /* may not return; must be done last */
+};
+
+void __init setup_panic(void)
+{
+       atomic_notifier_chain_register(&panic_notifier_list, &ppc_panic_block);
+}
index 2ebba755272e145db5039304105f4b969e220d66..4c67ad7fae085d2cc170c13d24f6cac27448705f 100644 (file)
@@ -2,5 +2,8 @@
 #define _POWERPC_KERNEL_SETUP_H
 
 void check_for_initrd(void);
+void do_init_bootmem(void);
+void setup_panic(void);
+extern int do_early_xmon;
 
 #endif /* _POWERPC_KERNEL_SETUP_H */
index 69ac2570134425dd108d372fe030fcb9d271483e..e5a44812441ac121b980e3d296f19e09651df045 100644 (file)
@@ -131,12 +131,6 @@ void __init machine_init(unsigned long dt_ptr, unsigned long phys)
        /* Do some early initialization based on the flat device tree */
        early_init_devtree(__va(dt_ptr));
 
-       /* Check default command line */
-#ifdef CONFIG_CMDLINE
-       if (cmd_line[0] == 0)
-               strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line));
-#endif /* CONFIG_CMDLINE */
-
        probe_machine();
 
 #ifdef CONFIG_6xx
@@ -235,7 +229,7 @@ arch_initcall(ppc_init);
 /* Warning, IO base is not yet inited */
 void __init setup_arch(char **cmdline_p)
 {
-       extern void do_init_bootmem(void);
+       *cmdline_p = cmd_line;
 
        /* so udelay does something sensible, assume <= 1000 bogomips */
        loops_per_jiffy = 500000000 / HZ;
@@ -285,16 +279,16 @@ void __init setup_arch(char **cmdline_p)
        /* reboot on panic */
        panic_timeout = 180;
 
+       if (ppc_md.panic)
+               setup_panic();
+
        init_mm.start_code = PAGE_OFFSET;
        init_mm.end_code = (unsigned long) _etext;
        init_mm.end_data = (unsigned long) _edata;
        init_mm.brk = klimit;
 
-       /* Save unparsed command line copy for /proc/cmdline */
-       strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
-       *cmdline_p = cmd_line;
-
-       parse_early_param();
+       if (do_early_xmon)
+               debugger(NULL);
 
        /* set up the bootmem stuff with available memory */
        do_init_bootmem();
index 4467c49903b64011884337a47445eb1ee9044d0f..78f3a5fd43f635b37a1186d056d11c78fb0897c2 100644 (file)
@@ -100,12 +100,6 @@ unsigned long SYSRQ_KEY;
 #endif /* CONFIG_MAGIC_SYSRQ */
 
 
-static int ppc64_panic_event(struct notifier_block *, unsigned long, void *);
-static struct notifier_block ppc64_panic_block = {
-       .notifier_call = ppc64_panic_event,
-       .priority = INT_MIN /* may not return; must be done last */
-};
-
 #ifdef CONFIG_SMP
 
 static int smt_enabled_cmdline;
@@ -199,9 +193,7 @@ void __init early_setup(unsigned long dt_ptr)
        /* Probe the machine type */
        probe_machine();
 
-#ifdef CONFIG_CRASH_DUMP
-       kdump_setup();
-#endif
+       setup_kdump_trampoline();
 
        DBG("Found, Initializing memory management...\n");
 
@@ -353,9 +345,6 @@ void __init setup_system(void)
 {
        DBG(" -> setup_system()\n");
 
-#ifdef CONFIG_KEXEC
-       kdump_move_device_tree();
-#endif
        /*
         * Unflatten the device-tree passed by prom_init or kexec
         */
@@ -420,10 +409,8 @@ void __init setup_system(void)
         */
        register_early_udbg_console();
 
-       /* Save unparsed command line copy for /proc/cmdline */
-       strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
-
-       parse_early_param();
+       if (do_early_xmon)
+               debugger(NULL);
 
        check_smt_enabled();
        smp_setup_cpu_maps();
@@ -456,13 +443,6 @@ void __init setup_system(void)
        DBG(" <- setup_system()\n");
 }
 
-static int ppc64_panic_event(struct notifier_block *this,
-                             unsigned long event, void *ptr)
-{
-       ppc_md.panic((char *)ptr);  /* May not return */
-       return NOTIFY_DONE;
-}
-
 #ifdef CONFIG_IRQSTACKS
 static void __init irqstack_early_init(void)
 {
@@ -517,8 +497,6 @@ static void __init emergency_stack_init(void)
  */
 void __init setup_arch(char **cmdline_p)
 {
-       extern void do_init_bootmem(void);
-
        ppc64_boot_msg(0x12, "Setup Arch");
 
        *cmdline_p = cmd_line;
@@ -535,8 +513,7 @@ void __init setup_arch(char **cmdline_p)
        panic_timeout = 180;
 
        if (ppc_md.panic)
-               atomic_notifier_chain_register(&panic_notifier_list,
-                               &ppc64_panic_block);
+               setup_panic();
 
        init_mm.start_code = PAGE_OFFSET;
        init_mm.end_code = (unsigned long) _etext;
index 8fdeca2d4597c35295271ff9ea844a91ea856a4d..d73b25e22fca892fd7b2f2dce8db2d94ddc0efda 100644 (file)
@@ -419,9 +419,7 @@ static long restore_user_regs(struct pt_regs *regs,
 {
        long err;
        unsigned int save_r2 = 0;
-#if defined(CONFIG_ALTIVEC) || defined(CONFIG_SPE)
        unsigned long msr;
-#endif
 
        /*
         * restore general registers but not including MSR or SOFTE. Also
@@ -430,11 +428,16 @@ static long restore_user_regs(struct pt_regs *regs,
        if (!sig)
                save_r2 = (unsigned int)regs->gpr[2];
        err = restore_general_regs(regs, sr);
+       err |= __get_user(msr, &sr->mc_gregs[PT_MSR]);
        if (!sig)
                regs->gpr[2] = (unsigned long) save_r2;
        if (err)
                return 1;
 
+       /* if doing signal return, restore the previous little-endian mode */
+       if (sig)
+               regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);
+
        /*
         * Do this before updating the thread state in
         * current->thread.fpr/vr/evr.  That way, if we get preempted
@@ -455,7 +458,7 @@ static long restore_user_regs(struct pt_regs *regs,
        /* force the process to reload the altivec registers from
           current->thread when it next does altivec instructions */
        regs->msr &= ~MSR_VEC;
-       if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_VEC) != 0) {
+       if (msr & MSR_VEC) {
                /* restore altivec registers from the stack */
                if (__copy_from_user(current->thread.vr, &sr->mc_vregs,
                                     sizeof(sr->mc_vregs)))
@@ -472,7 +475,7 @@ static long restore_user_regs(struct pt_regs *regs,
        /* force the process to reload the spe registers from
           current->thread when it next does spe instructions */
        regs->msr &= ~MSR_SPE;
-       if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_SPE) != 0) {
+       if (msr & MSR_SPE) {
                /* restore spe registers from the stack */
                if (__copy_from_user(current->thread.evr, &sr->mc_vregs,
                                     ELF_NEVRREG * sizeof(u32)))
@@ -757,10 +760,10 @@ static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
 
        /* Save user registers on the stack */
        frame = &rt_sf->uc.uc_mcontext;
-       if (vdso32_rt_sigtramp && current->thread.vdso_base) {
+       if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
                if (save_user_regs(regs, frame, 0))
                        goto badframe;
-               regs->link = current->thread.vdso_base + vdso32_rt_sigtramp;
+               regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
        } else {
                if (save_user_regs(regs, frame, __NR_rt_sigreturn))
                        goto badframe;
@@ -777,6 +780,8 @@ static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
        regs->gpr[5] = (unsigned long) &rt_sf->uc;
        regs->gpr[6] = (unsigned long) rt_sf;
        regs->nip = (unsigned long) ka->sa.sa_handler;
+       /* enter the signal handler in big-endian mode */
+       regs->msr &= ~MSR_LE;
        regs->trap = 0;
        return 1;
 
@@ -1038,10 +1043,10 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
            || __put_user(sig, &sc->signal))
                goto badframe;
 
-       if (vdso32_sigtramp && current->thread.vdso_base) {
+       if (vdso32_sigtramp && current->mm->context.vdso_base) {
                if (save_user_regs(regs, &frame->mctx, 0))
                        goto badframe;
-               regs->link = current->thread.vdso_base + vdso32_sigtramp;
+               regs->link = current->mm->context.vdso_base + vdso32_sigtramp;
        } else {
                if (save_user_regs(regs, &frame->mctx, __NR_sigreturn))
                        goto badframe;
@@ -1056,6 +1061,8 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
        regs->gpr[3] = sig;
        regs->gpr[4] = (unsigned long) sc;
        regs->nip = (unsigned long) ka->sa.sa_handler;
+       /* enter the signal handler in big-endian mode */
+       regs->msr &= ~MSR_LE;
        regs->trap = 0;
 
        return 1;
index c2db642f4cdd44c32695432b9622406204fdd866..6e75d7ab6d4d4757271c9bde664f4ead13724716 100644 (file)
@@ -141,9 +141,7 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
        unsigned long err = 0;
        unsigned long save_r13 = 0;
        elf_greg_t *gregs = (elf_greg_t *)regs;
-#ifdef CONFIG_ALTIVEC
        unsigned long msr;
-#endif
        int i;
 
        /* If this is not a signal return, we preserve the TLS in r13 */
@@ -154,7 +152,12 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
        err |= __copy_from_user(regs, &sc->gp_regs,
                                PT_MSR*sizeof(unsigned long));
 
-       /* skip MSR and SOFTE */
+       /* get MSR separately, transfer the LE bit if doing signal return */
+       err |= __get_user(msr, &sc->gp_regs[PT_MSR]);
+       if (sig)
+               regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);
+
+       /* skip SOFTE */
        for (i = PT_MSR+1; i <= PT_RESULT; i++) {
                if (i == PT_SOFTE)
                        continue;
@@ -179,7 +182,6 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
 
 #ifdef CONFIG_ALTIVEC
        err |= __get_user(v_regs, &sc->v_regs);
-       err |= __get_user(msr, &sc->gp_regs[PT_MSR]);
        if (err)
                return err;
        if (v_regs && !access_ok(VERIFY_READ, v_regs, 34 * sizeof(vector128)))
@@ -396,8 +398,8 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
        current->thread.fpscr.val = 0;
 
        /* Set up to return from userspace. */
-       if (vdso64_rt_sigtramp && current->thread.vdso_base) {
-               regs->link = current->thread.vdso_base + vdso64_rt_sigtramp;
+       if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
+               regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
        } else {
                err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
                if (err)
@@ -412,6 +414,8 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
 
        /* Set up "regs" so we "return" to the signal handler. */
        err |= get_user(regs->nip, &funct_desc_ptr->entry);
+       /* enter the signal handler in big-endian mode */
+       regs->msr &= ~MSR_LE;
        regs->gpr[1] = newsp;
        err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
        regs->gpr[3] = signr;
index 24e3ad756de02ce124bb2ff05ea4eb9b04c9a033..528e7f84cb67703a5516a4083ca4af4ca5bbb19b 100644 (file)
@@ -76,7 +76,6 @@
 
 /* keep track of when we need to update the rtc */
 time_t last_rtc_update;
-extern int piranha_simulator;
 #ifdef CONFIG_PPC_ISERIES
 unsigned long iSeries_recal_titan = 0;
 unsigned long iSeries_recal_tb = 0; 
@@ -945,9 +944,9 @@ void __init time_init(void)
        } else {
                /* Normal PowerPC with timebase register */
                ppc_md.calibrate_decr();
-               printk(KERN_INFO "time_init: decrementer frequency = %lu.%.6lu MHz\n",
+               printk(KERN_DEBUG "time_init: decrementer frequency = %lu.%.6lu MHz\n",
                       ppc_tb_freq / 1000000, ppc_tb_freq % 1000000);
-               printk(KERN_INFO "time_init: processor frequency   = %lu.%.6lu MHz\n",
+               printk(KERN_DEBUG "time_init: processor frequency   = %lu.%.6lu MHz\n",
                       ppc_proc_freq / 1000000, ppc_proc_freq % 1000000);
                tb_last_stamp = tb_last_jiffy = get_tb();
        }
@@ -1010,10 +1009,7 @@ void __init time_init(void)
        tb_to_ns_scale = scale;
        tb_to_ns_shift = shift;
 
-#ifdef CONFIG_PPC_ISERIES
-       if (!piranha_simulator)
-#endif
-               tm = get_boot_time();
+       tm = get_boot_time();
 
        write_seqlock_irqsave(&xtime_lock, flags);
 
index 064a525646922cf165177a8b9b8bc8c54df00800..91a6e04d9741fb197f4fb91ec039a1a154b2eabd 100644 (file)
@@ -658,7 +658,7 @@ static int emulate_instruction(struct pt_regs *regs)
        u32 instword;
        u32 rd;
 
-       if (!user_mode(regs))
+       if (!user_mode(regs) || (regs->msr & MSR_LE))
                return -EINVAL;
        CHECK_FULL_REGS(regs);
 
@@ -805,9 +805,11 @@ void __kprobes program_check_exception(struct pt_regs *regs)
 
 void alignment_exception(struct pt_regs *regs)
 {
-       int fixed;
+       int fixed = 0;
 
-       fixed = fix_alignment(regs);
+       /* we don't implement logging of alignment exceptions */
+       if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS))
+               fixed = fix_alignment(regs);
 
        if (fixed == 1) {
                regs->nip += 4; /* skip over emulated instruction */
index 3774e80094f5393bc86395fbd0632420a1992917..67d9fd9ae2b53092cc2bf7727f29060f4331f921 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/console.h>
+#include <linux/init.h>
 #include <asm/processor.h>
 #include <asm/udbg.h>
 
@@ -141,12 +142,14 @@ static int early_console_initialized;
 
 void __init disable_early_printk(void)
 {
-#if 1
        if (!early_console_initialized)
                return;
+       if (strstr(saved_command_line, "udbg-immortal")) {
+               printk(KERN_INFO "early console immortal !\n");
+               return;
+       }
        unregister_console(&udbg_console);
        early_console_initialized = 0;
-#endif
 }
 
 /* called by setup_system */
index 573afb68d69e7d1ba39d2e364fdf0c35c6db6196..bc3e15be308759c4026379dde0a16551c75630e6 100644 (file)
@@ -223,6 +223,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
        struct vm_area_struct *vma;
        unsigned long vdso_pages;
        unsigned long vdso_base;
+       int rc;
 
 #ifdef CONFIG_PPC64
        if (test_thread_flag(TIF_32BIT)) {
@@ -237,20 +238,13 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
        vdso_base = VDSO32_MBASE;
 #endif
 
-       current->thread.vdso_base = 0;
+       current->mm->context.vdso_base = 0;
 
        /* vDSO has a problem and was disabled, just don't "enable" it for the
         * process
         */
        if (vdso_pages == 0)
                return 0;
-
-       vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
-       if (vma == NULL)
-               return -ENOMEM;
-
-       memset(vma, 0, sizeof(*vma));
-
        /* Add a page to the vdso size for the data page */
        vdso_pages ++;
 
@@ -259,17 +253,23 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
         * at vdso_base which is the "natural" base for it, but we might fail
         * and end up putting it elsewhere.
         */
+       down_write(&mm->mmap_sem);
        vdso_base = get_unmapped_area(NULL, vdso_base,
                                      vdso_pages << PAGE_SHIFT, 0, 0);
-       if (vdso_base & ~PAGE_MASK) {
-               kmem_cache_free(vm_area_cachep, vma);
-               return (int)vdso_base;
+       if (IS_ERR_VALUE(vdso_base)) {
+               rc = vdso_base;
+               goto fail_mmapsem;
        }
 
-       current->thread.vdso_base = vdso_base;
 
+       /* Allocate a VMA structure and fill it up */
+       vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL);
+       if (vma == NULL) {
+               rc = -ENOMEM;
+               goto fail_mmapsem;
+       }
        vma->vm_mm = mm;
-       vma->vm_start = current->thread.vdso_base;
+       vma->vm_start = vdso_base;
        vma->vm_end = vma->vm_start + (vdso_pages << PAGE_SHIFT);
 
        /*
@@ -282,23 +282,38 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
         * It's fine to use that for setting breakpoints in the vDSO code
         * pages though
         */
-       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
+       vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC;
        vma->vm_flags |= mm->def_flags;
        vma->vm_page_prot = protection_map[vma->vm_flags & 0x7];
        vma->vm_ops = &vdso_vmops;
 
-       down_write(&mm->mmap_sem);
-       if (insert_vm_struct(mm, vma)) {
-               up_write(&mm->mmap_sem);
-               kmem_cache_free(vm_area_cachep, vma);
-               return -ENOMEM;
-       }
+       /* Insert new VMA */
+       rc = insert_vm_struct(mm, vma);
+       if (rc)
+               goto fail_vma;
+
+       /* Put vDSO base into mm struct and account for memory usage */
+       current->mm->context.vdso_base = vdso_base;
        mm->total_vm += (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
        up_write(&mm->mmap_sem);
-
        return 0;
+
+ fail_vma:
+       kmem_cache_free(vm_area_cachep, vma);
+ fail_mmapsem:
+       up_write(&mm->mmap_sem);
+       return rc;
+}
+
+const char *arch_vma_name(struct vm_area_struct *vma)
+{
+       if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso_base)
+               return "[vdso]";
+       return NULL;
 }
 
+
+
 static void * __init find_section32(Elf32_Ehdr *ehdr, const char *secname,
                                  unsigned long *size)
 {
index 971020cf3f7d24f90bd6d33edaf454e166fa7df7..e746686d48b8eb34f673654fa5bb82ece331ed59 100644 (file)
  *      2 of the License, or (at your option) any later version.
  */
 
+#include <linux/types.h>
+#include <linux/device.h>
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/dma-mapping.h>
+#include <linux/kobject.h>
+
 #include <asm/iommu.h>
 #include <asm/dma.h>
 #include <asm/vio.h>
 #include <asm/prom.h>
-
-static const struct vio_device_id *vio_match_device(
-               const struct vio_device_id *, const struct vio_dev *);
-
-struct vio_dev vio_bus_device  = { /* fake "parent" device */
+#include <asm/firmware.h>
+#include <asm/tce.h>
+#include <asm/abs_addr.h>
+#include <asm/page.h>
+#include <asm/hvcall.h>
+#include <asm/iseries/vio.h>
+#include <asm/iseries/hv_types.h>
+#include <asm/iseries/hv_lp_config.h>
+#include <asm/iseries/hv_call_xm.h>
+#include <asm/iseries/iommu.h>
+
+extern struct subsystem devices_subsys; /* needed for vio_find_name() */
+
+static struct vio_dev vio_bus_device  = { /* fake "parent" device */
        .name = vio_bus_device.dev.bus_id,
        .type = "",
        .dev.bus_id = "vio",
        .dev.bus = &vio_bus_type,
 };
 
-static struct vio_bus_ops vio_bus_ops;
+#ifdef CONFIG_PPC_ISERIES
+struct device *iSeries_vio_dev = &vio_bus_device.dev;
+EXPORT_SYMBOL(iSeries_vio_dev);
+
+static struct iommu_table veth_iommu_table;
+static struct iommu_table vio_iommu_table;
+
+static void __init iommu_vio_init(void)
+{
+       iommu_table_getparms_iSeries(255, 0, 0xff, &veth_iommu_table);
+       veth_iommu_table.it_size /= 2;
+       vio_iommu_table = veth_iommu_table;
+       vio_iommu_table.it_offset += veth_iommu_table.it_size;
+
+       if (!iommu_init_table(&veth_iommu_table))
+               printk("Virtual Bus VETH TCE table failed.\n");
+       if (!iommu_init_table(&vio_iommu_table))
+               printk("Virtual Bus VIO TCE table failed.\n");
+}
+#endif
+
+static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
+{
+#ifdef CONFIG_PPC_ISERIES
+       if (firmware_has_feature(FW_FEATURE_ISERIES)) {
+               if (strcmp(dev->type, "network") == 0)
+                       return &veth_iommu_table;
+               return &vio_iommu_table;
+       } else
+#endif
+       {
+               unsigned char *dma_window;
+               struct iommu_table *tbl;
+               unsigned long offset, size;
+
+               dma_window = get_property(dev->dev.platform_data,
+                               "ibm,my-dma-window", NULL);
+               if (!dma_window)
+                       return NULL;
+
+               tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
+
+               of_parse_dma_window(dev->dev.platform_data, dma_window,
+                               &tbl->it_index, &offset, &size);
+
+               /* TCE table size - measured in tce entries */
+               tbl->it_size = size >> PAGE_SHIFT;
+               /* offset for VIO should always be 0 */
+               tbl->it_offset = offset >> PAGE_SHIFT;
+               tbl->it_busno = 0;
+               tbl->it_type = TCE_VB;
+
+               return iommu_init_table(tbl);
+       }
+}
+
+/**
+ * vio_match_device: - Tell if a VIO device has a matching
+ *                     VIO device id structure.
+ * @ids:       array of VIO device id structures to search in
+ * @dev:       the VIO device structure to match against
+ *
+ * Used by a driver to check whether a VIO device present in the
+ * system is in its list of supported devices. Returns the matching
+ * vio_device_id structure or NULL if there is no match.
+ */
+static const struct vio_device_id *vio_match_device(
+               const struct vio_device_id *ids, const struct vio_dev *dev)
+{
+       while (ids->type[0] != '\0') {
+               if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) &&
+                   device_is_compatible(dev->dev.platform_data, ids->compat))
+                       return ids;
+               ids++;
+       }
+       return NULL;
+}
 
 /*
  * Convert from struct device to struct vio_dev and pass to driver.
@@ -106,35 +195,110 @@ void vio_unregister_driver(struct vio_driver *viodrv)
 }
 EXPORT_SYMBOL(vio_unregister_driver);
 
+/* vio_dev refcount hit 0 */
+static void __devinit vio_dev_release(struct device *dev)
+{
+       if (dev->platform_data) {
+               /* XXX free TCE table */
+               of_node_put(dev->platform_data);
+       }
+       kfree(to_vio_dev(dev));
+}
+
 /**
- * vio_match_device: - Tell if a VIO device has a matching
- *                     VIO device id structure.
- * @ids:       array of VIO device id structures to search in
- * @dev:       the VIO device structure to match against
+ * vio_register_device_node: - Register a new vio device.
+ * @of_node:   The OF node for this device.
  *
- * Used by a driver to check whether a VIO device present in the
- * system is in its list of supported devices. Returns the matching
- * vio_device_id structure or NULL if there is no match.
+ * Creates and initializes a vio_dev structure from the data in
+ * of_node (dev.platform_data) and adds it to the list of virtual devices.
+ * Returns a pointer to the created vio_dev or NULL if node has
+ * NULL device_type or compatible fields.
  */
-static const struct vio_device_id *vio_match_device(
-               const struct vio_device_id *ids, const struct vio_dev *dev)
+struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
 {
-       while (ids->type[0] != '\0') {
-               if (vio_bus_ops.match(ids, dev))
-                       return ids;
-               ids++;
+       struct vio_dev *viodev;
+       unsigned int *unit_address;
+       unsigned int *irq_p;
+
+       /* we need the 'device_type' property, in order to match with drivers */
+       if (of_node->type == NULL) {
+               printk(KERN_WARNING "%s: node %s missing 'device_type'\n",
+                               __FUNCTION__,
+                               of_node->name ? of_node->name : "<unknown>");
+               return NULL;
        }
-       return NULL;
+
+       unit_address = (unsigned int *)get_property(of_node, "reg", NULL);
+       if (unit_address == NULL) {
+               printk(KERN_WARNING "%s: node %s missing 'reg'\n",
+                               __FUNCTION__,
+                               of_node->name ? of_node->name : "<unknown>");
+               return NULL;
+       }
+
+       /* allocate a vio_dev for this node */
+       viodev = kzalloc(sizeof(struct vio_dev), GFP_KERNEL);
+       if (viodev == NULL)
+               return NULL;
+
+       viodev->dev.platform_data = of_node_get(of_node);
+
+       viodev->irq = NO_IRQ;
+       irq_p = (unsigned int *)get_property(of_node, "interrupts", NULL);
+       if (irq_p) {
+               int virq = virt_irq_create_mapping(*irq_p);
+               if (virq == NO_IRQ) {
+                       printk(KERN_ERR "Unable to allocate interrupt "
+                              "number for %s\n", of_node->full_name);
+               } else
+                       viodev->irq = irq_offset_up(virq);
+       }
+
+       snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address);
+       viodev->name = of_node->name;
+       viodev->type = of_node->type;
+       viodev->unit_address = *unit_address;
+       if (firmware_has_feature(FW_FEATURE_ISERIES)) {
+               unit_address = (unsigned int *)get_property(of_node,
+                               "linux,unit_address", NULL);
+               if (unit_address != NULL)
+                       viodev->unit_address = *unit_address;
+       }
+       viodev->iommu_table = vio_build_iommu_table(viodev);
+
+       /* init generic 'struct device' fields: */
+       viodev->dev.parent = &vio_bus_device.dev;
+       viodev->dev.bus = &vio_bus_type;
+       viodev->dev.release = vio_dev_release;
+
+       /* register with generic device framework */
+       if (device_register(&viodev->dev)) {
+               printk(KERN_ERR "%s: failed to register device %s\n",
+                               __FUNCTION__, viodev->dev.bus_id);
+               /* XXX free TCE table */
+               kfree(viodev);
+               return NULL;
+       }
+
+       return viodev;
 }
+EXPORT_SYMBOL(vio_register_device_node);
 
 /**
  * vio_bus_init: - Initialize the virtual IO bus
  */
-int __init vio_bus_init(struct vio_bus_ops *ops)
+static int __init vio_bus_init(void)
 {
        int err;
+       struct device_node *node_vroot;
 
-       vio_bus_ops = *ops;
+#ifdef CONFIG_PPC_ISERIES
+       if (firmware_has_feature(FW_FEATURE_ISERIES)) {
+               iommu_vio_init();
+               vio_bus_device.iommu_table = &vio_iommu_table;
+               iSeries_vio_dev = &vio_bus_device.dev;
+       }
+#endif
 
        err = bus_register(&vio_bus_type);
        if (err) {
@@ -153,47 +317,48 @@ int __init vio_bus_init(struct vio_bus_ops *ops)
                return err;
        }
 
-       return 0;
-}
+       node_vroot = find_devices("vdevice");
+       if (node_vroot) {
+               struct device_node *of_node;
+
+               /*
+                * Create struct vio_devices for each virtual device in
+                * the device tree. Drivers will associate with them later.
+                */
+               for (of_node = node_vroot->child; of_node != NULL;
+                               of_node = of_node->sibling) {
+                       printk(KERN_DEBUG "%s: processing %p\n",
+                                       __FUNCTION__, of_node);
+                       vio_register_device_node(of_node);
+               }
+       }
 
-/* vio_dev refcount hit 0 */
-static void __devinit vio_dev_release(struct device *dev)
-{
-       if (vio_bus_ops.release_device)
-               vio_bus_ops.release_device(dev);
-       kfree(to_vio_dev(dev));
+       return 0;
 }
+__initcall(vio_bus_init);
 
-static ssize_t viodev_show_name(struct device *dev,
+static ssize_t name_show(struct device *dev,
                struct device_attribute *attr, char *buf)
 {
        return sprintf(buf, "%s\n", to_vio_dev(dev)->name);
 }
-DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_name, NULL);
 
-struct vio_dev * __devinit vio_register_device(struct vio_dev *viodev)
+static ssize_t devspec_show(struct device *dev,
+               struct device_attribute *attr, char *buf)
 {
-       /* init generic 'struct device' fields: */
-       viodev->dev.parent = &vio_bus_device.dev;
-       viodev->dev.bus = &vio_bus_type;
-       viodev->dev.release = vio_dev_release;
-
-       /* register with generic device framework */
-       if (device_register(&viodev->dev)) {
-               printk(KERN_ERR "%s: failed to register device %s\n",
-                               __FUNCTION__, viodev->dev.bus_id);
-               return NULL;
-       }
-       device_create_file(&viodev->dev, &dev_attr_name);
+       struct device_node *of_node = dev->platform_data;
 
-       return viodev;
+       return sprintf(buf, "%s\n", of_node ? of_node->full_name : "none");
 }
 
+static struct device_attribute vio_dev_attrs[] = {
+       __ATTR_RO(name),
+       __ATTR_RO(devspec),
+       __ATTR_NULL
+};
+
 void __devinit vio_unregister_device(struct vio_dev *viodev)
 {
-       if (vio_bus_ops.unregister_device)
-               vio_bus_ops.unregister_device(viodev);
-       device_remove_file(&viodev->dev, &dev_attr_name);
        device_unregister(&viodev->dev);
 }
 EXPORT_SYMBOL(vio_unregister_device);
@@ -229,7 +394,7 @@ static void *vio_alloc_coherent(struct device *dev, size_t size,
                           dma_addr_t *dma_handle, gfp_t flag)
 {
        return iommu_alloc_coherent(to_vio_dev(dev)->iommu_table, size,
-                       dma_handle, ~0ul, flag);
+                       dma_handle, ~0ul, flag, -1);
 }
 
 static void vio_free_coherent(struct device *dev, size_t size,
@@ -267,22 +432,23 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp,
                        char *buffer, int buffer_size)
 {
        const struct vio_dev *vio_dev = to_vio_dev(dev);
+       struct device_node *dn = dev->platform_data;
        char *cp;
        int length;
 
        if (!num_envp)
                return -ENOMEM;
 
-       if (!vio_dev->dev.platform_data)
+       if (!dn)
                return -ENODEV;
-       cp = (char *)get_property(vio_dev->dev.platform_data, "compatible", &length);
+       cp = (char *)get_property(dn, "compatible", &length);
        if (!cp)
                return -ENODEV;
 
        envp[0] = buffer;
        length = scnprintf(buffer, buffer_size, "MODALIAS=vio:T%sS%s",
                                vio_dev->type, cp);
-       if (buffer_size - length <= 0)
+       if ((buffer_size - length) <= 0)
                return -ENOMEM;
        envp[1] = NULL;
        return 0;
@@ -290,9 +456,81 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp,
 
 struct bus_type vio_bus_type = {
        .name = "vio",
+       .dev_attrs = vio_dev_attrs,
        .uevent = vio_hotplug,
        .match = vio_bus_match,
        .probe = vio_bus_probe,
        .remove = vio_bus_remove,
        .shutdown = vio_bus_shutdown,
 };
+
+/**
+ * vio_get_attribute: - get attribute for virtual device
+ * @vdev:      The vio device to get property.
+ * @which:     The property/attribute to be extracted.
+ * @length:    Pointer to length of returned data size (unused if NULL).
+ *
+ * Calls prom.c's get_property() to return the value of the
+ * attribute specified by @which
+*/
+const void *vio_get_attribute(struct vio_dev *vdev, char *which, int *length)
+{
+       return get_property(vdev->dev.platform_data, which, length);
+}
+EXPORT_SYMBOL(vio_get_attribute);
+
+#ifdef CONFIG_PPC_PSERIES
+/* vio_find_name() - internal because only vio.c knows how we formatted the
+ * kobject name
+ * XXX once vio_bus_type.devices is actually used as a kset in
+ * drivers/base/bus.c, this function should be removed in favor of
+ * "device_find(kobj_name, &vio_bus_type)"
+ */
+static struct vio_dev *vio_find_name(const char *kobj_name)
+{
+       struct kobject *found;
+
+       found = kset_find_obj(&devices_subsys.kset, kobj_name);
+       if (!found)
+               return NULL;
+
+       return to_vio_dev(container_of(found, struct device, kobj));
+}
+
+/**
+ * vio_find_node - find an already-registered vio_dev
+ * @vnode: device_node of the virtual device we're looking for
+ */
+struct vio_dev *vio_find_node(struct device_node *vnode)
+{
+       uint32_t *unit_address;
+       char kobj_name[BUS_ID_SIZE];
+
+       /* construct the kobject name from the device node */
+       unit_address = (uint32_t *)get_property(vnode, "reg", NULL);
+       if (!unit_address)
+               return NULL;
+       snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address);
+
+       return vio_find_name(kobj_name);
+}
+EXPORT_SYMBOL(vio_find_node);
+
+int vio_enable_interrupts(struct vio_dev *dev)
+{
+       int rc = h_vio_signal(dev->unit_address, VIO_IRQ_ENABLE);
+       if (rc != H_SUCCESS)
+               printk(KERN_ERR "vio: Error 0x%x enabling interrupts\n", rc);
+       return rc;
+}
+EXPORT_SYMBOL(vio_enable_interrupts);
+
+int vio_disable_interrupts(struct vio_dev *dev)
+{
+       int rc = h_vio_signal(dev->unit_address, VIO_IRQ_DISABLE);
+       if (rc != H_SUCCESS)
+               printk(KERN_ERR "vio: Error 0x%x disabling interrupts\n", rc);
+       return rc;
+}
+EXPORT_SYMBOL(vio_disable_interrupts);
+#endif /* CONFIG_PPC_PSERIES */
index fe79c2584cb0057db73212f5885a7fbc59e62af7..8b25953dc4f02022d8c939579ca7bb3bdef66777 100644 (file)
@@ -93,6 +93,11 @@ SECTIONS
                __ptov_table_begin = .;
                *(.ptov_fixup);
                __ptov_table_end = .;
+#ifdef CONFIG_PPC_ISERIES
+               __dt_strings_start = .;
+               *(.dt_strings);
+               __dt_strings_end = .;
+#endif
        }
 
        . = ALIGN(16);
index 34f5c2e074c987ea3346ad1933c03e745328bb10..ae354d65b82ccfb66311c4a652905d8ef11012e3 100644 (file)
@@ -7,7 +7,6 @@ obj-y                   := string.o strcase.o
 obj-$(CONFIG_PPC32)    += div64.o copy_32.o checksum_32.o
 endif
 
-obj-y                  += bitops.o
 obj-$(CONFIG_PPC64)    += checksum_64.o copypage_64.o copyuser_64.o \
                           memcpy_64.o usercopy_64.o mem_64.o string.o \
                           strcase.o
diff --git a/arch/powerpc/lib/bitops.c b/arch/powerpc/lib/bitops.c
deleted file mode 100644 (file)
index f68ad71..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-#include <linux/types.h>
-#include <linux/module.h>
-#include <asm/byteorder.h>
-#include <asm/bitops.h>
-
-/**
- * find_next_bit - find the next set bit in a memory region
- * @addr: The address to base the search on
- * @offset: The bitnumber to start searching at
- * @size: The maximum size to search
- */
-unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
-                           unsigned long offset)
-{
-       const unsigned long *p = addr + BITOP_WORD(offset);
-       unsigned long result = offset & ~(BITS_PER_LONG-1);
-       unsigned long tmp;
-
-       if (offset >= size)
-               return size;
-       size -= result;
-       offset %= BITS_PER_LONG;
-       if (offset) {
-               tmp = *(p++);
-               tmp &= (~0UL << offset);
-               if (size < BITS_PER_LONG)
-                       goto found_first;
-               if (tmp)
-                       goto found_middle;
-               size -= BITS_PER_LONG;
-               result += BITS_PER_LONG;
-       }
-       while (size & ~(BITS_PER_LONG-1)) {
-               if ((tmp = *(p++)))
-                       goto found_middle;
-               result += BITS_PER_LONG;
-               size -= BITS_PER_LONG;
-       }
-       if (!size)
-               return result;
-       tmp = *p;
-
-found_first:
-       tmp &= (~0UL >> (BITS_PER_LONG - size));
-       if (tmp == 0UL)         /* Are any bits set? */
-               return result + size;   /* Nope. */
-found_middle:
-       return result + __ffs(tmp);
-}
-EXPORT_SYMBOL(find_next_bit);
-
-/*
- * This implementation of find_{first,next}_zero_bit was stolen from
- * Linus' asm-alpha/bitops.h.
- */
-unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
-                                unsigned long offset)
-{
-       const unsigned long *p = addr + BITOP_WORD(offset);
-       unsigned long result = offset & ~(BITS_PER_LONG-1);
-       unsigned long tmp;
-
-       if (offset >= size)
-               return size;
-       size -= result;
-       offset %= BITS_PER_LONG;
-       if (offset) {
-               tmp = *(p++);
-               tmp |= ~0UL >> (BITS_PER_LONG - offset);
-               if (size < BITS_PER_LONG)
-                       goto found_first;
-               if (~tmp)
-                       goto found_middle;
-               size -= BITS_PER_LONG;
-               result += BITS_PER_LONG;
-       }
-       while (size & ~(BITS_PER_LONG-1)) {
-               if (~(tmp = *(p++)))
-                       goto found_middle;
-               result += BITS_PER_LONG;
-               size -= BITS_PER_LONG;
-       }
-       if (!size)
-               return result;
-       tmp = *p;
-
-found_first:
-       tmp |= ~0UL << size;
-       if (tmp == ~0UL)        /* Are any bits zero? */
-               return result + size;   /* Nope. */
-found_middle:
-       return result + ffz(tmp);
-}
-EXPORT_SYMBOL(find_next_zero_bit);
-
-static inline unsigned int ext2_ilog2(unsigned int x)
-{
-       int lz;
-
-       asm("cntlzw %0,%1": "=r"(lz):"r"(x));
-       return 31 - lz;
-}
-
-static inline unsigned int ext2_ffz(unsigned int x)
-{
-       u32 rc;
-       if ((x = ~x) == 0)
-               return 32;
-       rc = ext2_ilog2(x & -x);
-       return rc;
-}
-
-unsigned long find_next_zero_le_bit(const unsigned long *addr,
-                                   unsigned long size, unsigned long offset)
-{
-       const unsigned int *p = ((const unsigned int *)addr) + (offset >> 5);
-       unsigned int result = offset & ~31;
-       unsigned int tmp;
-
-       if (offset >= size)
-               return size;
-       size -= result;
-       offset &= 31;
-       if (offset) {
-               tmp = cpu_to_le32p(p++);
-               tmp |= ~0U >> (32 - offset);    /* bug or feature ? */
-               if (size < 32)
-                       goto found_first;
-               if (tmp != ~0)
-                       goto found_middle;
-               size -= 32;
-               result += 32;
-       }
-       while (size >= 32) {
-               if ((tmp = cpu_to_le32p(p++)) != ~0)
-                       goto found_middle;
-               result += 32;
-               size -= 32;
-       }
-       if (!size)
-               return result;
-       tmp = cpu_to_le32p(p);
-found_first:
-       tmp |= ~0 << size;
-       if (tmp == ~0)          /* Are any bits zero? */
-               return result + size;   /* Nope. */
-found_middle:
-       return result + ext2_ffz(tmp);
-}
-EXPORT_SYMBOL(find_next_zero_le_bit);
index e0d02c4a2615f8787abc1b13737f7b78e67bc5a5..106fba391987376ce8c3599e610aa86cfe484674 100644 (file)
@@ -136,6 +136,7 @@ _GLOBAL(__hash_page_4K)
        and     r0,r0,r4                /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/
        andc    r0,r30,r0               /* r0 = pte & ~r0 */
        rlwimi  r3,r0,32-1,31,31        /* Insert result into PP lsb */
+       ori     r3,r3,HPTE_R_C          /* Always add "C" bit for perf. */
 
        /* We eventually do the icache sync here (maybe inline that
         * code rather than call a C function...) 
@@ -400,6 +401,7 @@ _GLOBAL(__hash_page_4K)
        and     r0,r0,r4                /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/
        andc    r0,r30,r0               /* r0 = pte & ~r0 */
        rlwimi  r3,r0,32-1,31,31        /* Insert result into PP lsb */
+       ori     r3,r3,HPTE_R_C          /* Always add "C" bit for perf. */
 
        /* We eventually do the icache sync here (maybe inline that
         * code rather than call a C function...)
@@ -671,6 +673,7 @@ _GLOBAL(__hash_page_64K)
        and     r0,r0,r4                /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/
        andc    r0,r30,r0               /* r0 = pte & ~r0 */
        rlwimi  r3,r0,32-1,31,31        /* Insert result into PP lsb */
+       ori     r3,r3,HPTE_R_C          /* Always add "C" bit for perf. */
 
        /* We eventually do the icache sync here (maybe inline that
         * code rather than call a C function...)
index 33654d1b1b43b596ac70e98cf834a1185157f355..3b8205033f15379c9e2a0cfb8f3c98056004d67e 100644 (file)
@@ -238,7 +238,7 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
                DBG_LOW(" -> hit\n");
                /* Update the HPTE */
                hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) |
-                       (newpp & (HPTE_R_PP | HPTE_R_N));
+                       (newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_C));
                native_unlock_hpte(hptep);
        }
 
index c006d9039633dc75f020a71da32ce254c619c937..b43ed92ef471fc69a7e0160eccd8e77f521a7ae4 100644 (file)
@@ -319,7 +319,7 @@ static void __init htab_init_page_sizes(void)
                mmu_virtual_psize = MMU_PAGE_64K;
 #endif
 
-       printk(KERN_INFO "Page orders: linear mapping = %d, others = %d\n",
+       printk(KERN_DEBUG "Page orders: linear mapping = %d, others = %d\n",
               mmu_psize_defs[mmu_linear_psize].shift,
               mmu_psize_defs[mmu_virtual_psize].shift);
 
index 417d58518558bd0ab31975df7e7d864d6aea3a05..8b6f522655a62c56542629c2b7da3455ebd4b867 100644 (file)
@@ -89,20 +89,25 @@ static long __init lmb_regions_adjacent(struct lmb_region *rgn,
        return lmb_addrs_adjacent(base1, size1, base2, size2);
 }
 
-/* Assumption: base addr of region 1 < base addr of region 2 */
-static void __init lmb_coalesce_regions(struct lmb_region *rgn,
-               unsigned long r1, unsigned long r2)
+static void __init lmb_remove_region(struct lmb_region *rgn, unsigned long r)
 {
        unsigned long i;
 
-       rgn->region[r1].size += rgn->region[r2].size;
-       for (i=r2; i < rgn->cnt-1; i++) {
-               rgn->region[i].base = rgn->region[i+1].base;
-               rgn->region[i].size = rgn->region[i+1].size;
+       for (i = r; i < rgn->cnt - 1; i++) {
+               rgn->region[i].base = rgn->region[i + 1].base;
+               rgn->region[i].size = rgn->region[i + 1].size;
        }
        rgn->cnt--;
 }
 
+/* Assumption: base addr of region 1 < base addr of region 2 */
+static void __init lmb_coalesce_regions(struct lmb_region *rgn,
+               unsigned long r1, unsigned long r2)
+{
+       rgn->region[r1].size += rgn->region[r2].size;
+       lmb_remove_region(rgn, r2);
+}
+
 /* This routine called with relocation disabled. */
 void __init lmb_init(void)
 {
@@ -294,17 +299,16 @@ unsigned long __init lmb_end_of_DRAM(void)
        return (lmb.memory.region[idx].base + lmb.memory.region[idx].size);
 }
 
-/*
- * Truncate the lmb list to memory_limit if it's set
- * You must call lmb_analyze() after this.
- */
+/* You must call lmb_analyze() after this. */
 void __init lmb_enforce_memory_limit(unsigned long memory_limit)
 {
        unsigned long i, limit;
+       struct lmb_property *p;
 
        if (! memory_limit)
                return;
 
+       /* Truncate the lmb regions to satisfy the memory limit. */
        limit = memory_limit;
        for (i = 0; i < lmb.memory.cnt; i++) {
                if (limit > lmb.memory.region[i].size) {
@@ -316,4 +320,21 @@ void __init lmb_enforce_memory_limit(unsigned long memory_limit)
                lmb.memory.cnt = i + 1;
                break;
        }
+
+       lmb.rmo_size = lmb.memory.region[0].size;
+
+       /* And truncate any reserves above the limit also. */
+       for (i = 0; i < lmb.reserved.cnt; i++) {
+               p = &lmb.reserved.region[i];
+
+               if (p->base > memory_limit)
+                       p->size = 0;
+               else if ((p->base + p->size) > memory_limit)
+                       p->size = memory_limit - p->base;
+
+               if (p->size == 0) {
+                       lmb_remove_region(&lmb.reserved, i);
+                       i--;
+               }
+       }
 }
index 741dd8802d495d99f1e8e31bd55d14dc00613366..69f3b9a20beb768a093735b800628e18f3d1645f 100644 (file)
@@ -299,9 +299,9 @@ void __init paging_init(void)
        kmap_prot = PAGE_KERNEL;
 #endif /* CONFIG_HIGHMEM */
 
-       printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
+       printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
               top_of_ram, total_ram);
-       printk(KERN_INFO "Memory hole size: %ldMB\n",
+       printk(KERN_DEBUG "Memory hole size: %ldMB\n",
               (top_of_ram - total_ram) >> 20);
        /*
         * All pages are DMA-able so we put them all in the DMA zone.
@@ -380,7 +380,7 @@ void __init mem_init(void)
                        totalhigh_pages++;
                }
                totalram_pages += totalhigh_pages;
-               printk(KERN_INFO "High memory: %luk\n",
+               printk(KERN_DEBUG "High memory: %luk\n",
                       totalhigh_pages << (PAGE_SHIFT-10));
        }
 #endif /* CONFIG_HIGHMEM */
index a8816e0f6a86dd4eb28f15cd3a9813dfeef0a5a1..e326e4249e1a24eb393d7c3628af9a046e43bf16 100644 (file)
@@ -30,7 +30,7 @@
 #include <asm/mmu_context.h>
 #include <asm/tlbflush.h>
 
-mm_context_t next_mmu_context;
+unsigned long next_mmu_context;
 unsigned long context_map[LAST_CONTEXT / BITS_PER_LONG + 1];
 #ifdef FEW_CONTEXTS
 atomic_t nr_free_contexts;
index 092355f373996798075e5aa2f49074fa689e676a..aa98cb3b59d82a3c9ff49f35089ba0244eca60d6 100644 (file)
@@ -487,9 +487,9 @@ static void __init setup_nonnuma(void)
        unsigned long total_ram = lmb_phys_mem_size();
        unsigned int i;
 
-       printk(KERN_INFO "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
+       printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
               top_of_ram, total_ram);
-       printk(KERN_INFO "Memory hole size: %ldMB\n",
+       printk(KERN_DEBUG "Memory hole size: %ldMB\n",
               (top_of_ram - total_ram) >> 20);
 
        for (i = 0; i < lmb.memory.cnt; ++i)
@@ -507,7 +507,7 @@ void __init dump_numa_cpu_topology(void)
                return;
 
        for_each_online_node(node) {
-               printk(KERN_INFO "Node %d CPUs:", node);
+               printk(KERN_DEBUG "Node %d CPUs:", node);
 
                count = 0;
                /*
@@ -543,7 +543,7 @@ static void __init dump_numa_memory_topology(void)
        for_each_online_node(node) {
                unsigned long i;
 
-               printk(KERN_INFO "Node %d Memory:", node);
+               printk(KERN_DEBUG "Node %d Memory:", node);
 
                count = 0;
 
index ed7fcfe5fd370882d2264bd3e86ed04b9cbc74aa..1df731e42b50522639636334130f3e849e4939ad 100644 (file)
@@ -190,7 +190,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
                return;
        pmd = pmd_offset(pgd_offset(mm, ea), ea);
        if (!pmd_none(*pmd))
-               add_hash_page(mm->context, ea, pmd_val(*pmd));
+               add_hash_page(mm->context.id, ea, pmd_val(*pmd));
 }
 
 /*
index ad580f3742e5cf187bfe65cf6f7c1f948d3ff558..02eb23e036d593eb9589313de023cdaafe31b4ef 100644 (file)
@@ -42,7 +42,7 @@ void flush_hash_entry(struct mm_struct *mm, pte_t *ptep, unsigned long addr)
 
        if (Hash != 0) {
                ptephys = __pa(ptep) & PAGE_MASK;
-               flush_hash_pages(mm->context, addr, ptephys, 1);
+               flush_hash_pages(mm->context.id, addr, ptephys, 1);
        }
 }
 
@@ -102,7 +102,7 @@ static void flush_range(struct mm_struct *mm, unsigned long start,
        pmd_t *pmd;
        unsigned long pmd_end;
        int count;
-       unsigned int ctx = mm->context;
+       unsigned int ctx = mm->context.id;
 
        if (Hash == 0) {
                _tlbia();
@@ -172,7 +172,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
        mm = (vmaddr < TASK_SIZE)? vma->vm_mm: &init_mm;
        pmd = pmd_offset(pgd_offset(mm, vmaddr), vmaddr);
        if (!pmd_none(*pmd))
-               flush_hash_pages(mm->context, vmaddr, pmd_val(*pmd), 1);
+               flush_hash_pages(mm->context.id, vmaddr, pmd_val(*pmd), 1);
        FINISH_FLUSH;
 }
 
index 5b1de7e8041edc68f0e1abee231fe501beed6afd..38a2f9c171878a7a6f6d790e2e58e6a6f6b91249 100644 (file)
@@ -162,7 +162,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
        ops->stop = op_powerpc_stop;
        ops->backtrace = op_powerpc_backtrace;
 
-       printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
+       printk(KERN_DEBUG "oprofile: using %s performance monitoring.\n",
               ops->cpu_type);
 
        return 0;
index 4c2beab1fdc199dd14e562cde95ea5d05a809e45..506f6b79f893225df5fcc093f146d3d9656f3e7f 100644 (file)
 static unsigned long reset_value[OP_MAX_COUNTER];
 
 static int oprofile_running;
-static int mmcra_has_sihv;
-/* Unfortunately these bits vary between CPUs */
-static unsigned long mmcra_sihv = MMCRA_SIHV;
-static unsigned long mmcra_sipr = MMCRA_SIPR;
 
 /* mmcr values are set in power4_reg_setup, used in power4_cpu_setup */
 static u32 mmcr0_val;
@@ -40,16 +36,6 @@ static void power4_reg_setup(struct op_counter_config *ctr,
 {
        int i;
 
-       /*
-        * SIHV / SIPR bits are only implemented on POWER4+ (GQ) and above.
-        * However we disable it on all POWER4 until we verify it works
-        * (I was seeing some strange behaviour last time I tried).
-        *
-        * It has been verified to work on POWER5 so we enable it there.
-        */
-       if (cpu_has_feature(CPU_FTR_MMCRA_SIHV))
-               mmcra_has_sihv = 1;
-
        /*
         * The performance counter event settings are given in the mmcr0,
         * mmcr1 and mmcra values passed from the user in the
@@ -202,18 +188,19 @@ static unsigned long get_pc(struct pt_regs *regs)
        unsigned long mmcra;
 
        /* Cant do much about it */
-       if (!mmcra_has_sihv)
+       if (!cur_cpu_spec->oprofile_mmcra_sihv)
                return pc;
 
        mmcra = mfspr(SPRN_MMCRA);
 
        /* Were we in the hypervisor? */
-       if (firmware_has_feature(FW_FEATURE_LPAR) && (mmcra & mmcra_sihv))
+       if (firmware_has_feature(FW_FEATURE_LPAR) &&
+           (mmcra & cur_cpu_spec->oprofile_mmcra_sihv))
                /* function descriptor madness */
                return *((unsigned long *)hypervisor_bucket);
 
        /* We were in userspace, nothing to do */
-       if (mmcra & mmcra_sipr)
+       if (mmcra & cur_cpu_spec->oprofile_mmcra_sipr)
                return pc;
 
 #ifdef CONFIG_PPC_RTAS
@@ -235,15 +222,14 @@ static unsigned long get_pc(struct pt_regs *regs)
        return pc;
 }
 
-static int get_kernel(unsigned long pc)
+static int get_kernel(unsigned long pc, unsigned long mmcra)
 {
        int is_kernel;
 
-       if (!mmcra_has_sihv) {
+       if (!cur_cpu_spec->oprofile_mmcra_sihv) {
                is_kernel = is_kernel_addr(pc);
        } else {
-               unsigned long mmcra = mfspr(SPRN_MMCRA);
-               is_kernel = ((mmcra & mmcra_sipr) == 0);
+               is_kernel = ((mmcra & cur_cpu_spec->oprofile_mmcra_sipr) == 0);
        }
 
        return is_kernel;
@@ -257,9 +243,12 @@ static void power4_handle_interrupt(struct pt_regs *regs,
        int val;
        int i;
        unsigned int mmcr0;
+       unsigned long mmcra;
+
+       mmcra = mfspr(SPRN_MMCRA);
 
        pc = get_pc(regs);
-       is_kernel = get_kernel(pc);
+       is_kernel = get_kernel(pc, mmcra);
 
        /* set the PMM bit (see comment below) */
        mtmsrd(mfmsr() | MSR_PMM);
@@ -287,6 +276,10 @@ static void power4_handle_interrupt(struct pt_regs *regs,
         */
        mmcr0 &= ~MMCR0_PMAO;
 
+       /* Clear the appropriate bits in the MMCRA */
+       mmcra &= ~cur_cpu_spec->oprofile_mmcra_clear;
+       mtspr(SPRN_MMCRA, mmcra);
+
        /*
         * now clear the freeze bit, counting will not start until we
         * rfid from this exception, because only at that point will
index 06e371282f574ff9c4b2250ee644e9d9ac064d89..454fc53289ab5d4a8ea1d5ca635cf810000f68e6 100644 (file)
@@ -11,13 +11,20 @@ config MPC8540_ADS
        help
          This option enables support for the MPC 8540 ADS board
 
+config MPC85xx_CDS
+       bool "Freescale MPC85xx CDS"
+       select DEFAULT_UIMAGE
+       select PPC_I8259 if PCI
+       help
+         This option enables support for the MPC85xx CDS board
+
 endchoice
 
 config MPC8540
        bool
        select PPC_UDBG_16550
        select PPC_INDIRECT_PCI
-       default y if MPC8540_ADS
+       default y if MPC8540_ADS || MPC85xx_CDS
 
 config PPC_INDIRECT_PCI_BE
        bool
index ffc4139cb214378984636b6cf0ea60eb82e07aca..7615aa59c78bacf6d911f2ea7e194e927f4e1b79 100644 (file)
@@ -3,3 +3,4 @@
 #
 obj-$(CONFIG_PPC_85xx) += misc.o pci.o
 obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o
+obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
new file mode 100644 (file)
index 0000000..18e6e11
--- /dev/null
@@ -0,0 +1,359 @@
+/*
+ * MPC85xx setup and early boot code plus other random bits.
+ *
+ * Maintained by Kumar Gala (see MAINTAINERS for contact information)
+ *
+ * Copyright 2005 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/initrd.h>
+#include <linux/module.h>
+#include <linux/fsl_devices.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/atomic.h>
+#include <asm/time.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/ipic.h>
+#include <asm/bootinfo.h>
+#include <asm/pci-bridge.h>
+#include <asm/mpc85xx.h>
+#include <asm/irq.h>
+#include <mm/mmu_decl.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/mpic.h>
+#include <asm/i8259.h>
+
+#include <sysdev/fsl_soc.h>
+#include "mpc85xx.h"
+
+#ifndef CONFIG_PCI
+unsigned long isa_io_base = 0;
+unsigned long isa_mem_base = 0;
+#endif
+
+static int cds_pci_slot = 2;
+static volatile u8 *cadmus;
+
+/*
+ * Internal interrupts are all Level Sensitive, and Positive Polarity
+ *
+ * Note:  Likely, this table and the following function should be
+ *        obtained and derived from the OF Device Tree.
+ */
+static u_char mpc85xx_cds_openpic_initsenses[] __initdata = {
+       MPC85XX_INTERNAL_IRQ_SENSES,
+#if defined(CONFIG_PCI)
+       (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE),      /* Ext 0: PCI slot 0 */
+       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* Ext 1: PCI slot 1 */
+       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* Ext 2: PCI slot 2 */
+       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* Ext 3: PCI slot 3 */
+#else
+       0x0,                            /* External  0: */
+       0x0,                            /* External  1: */
+       0x0,                            /* External  2: */
+       0x0,                            /* External  3: */
+#endif
+       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),      /* External 5: PHY */
+       0x0,                            /* External  6: */
+       0x0,                            /* External  7: */
+       0x0,                            /* External  8: */
+       0x0,                            /* External  9: */
+       0x0,                            /* External 10: */
+#ifdef CONFIG_PCI
+       (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE),    /* Ext 11: PCI2 slot 0 */
+#else
+       0x0,                            /* External 11: */
+#endif
+};
+
+
+#ifdef CONFIG_PCI
+/*
+ * interrupt routing
+ */
+int
+mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+       struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
+
+       if (!hose->index)
+       {
+               /* Handle PCI1 interrupts */
+               char pci_irq_table[][4] =
+                       /*
+                        *      PCI IDSEL/INTPIN->INTLINE
+                        *        A      B      C      D
+                        */
+
+                       /* Note IRQ assignment for slots is based on which slot the elysium is
+                        * in -- in this setup elysium is in slot #2 (this PIRQA as first
+                        * interrupt on slot */
+               {
+                       { 0, 1, 2, 3 }, /* 16 - PMC */
+                       { 0, 1, 2, 3 }, /* 17 P2P (Tsi320) */
+                       { 0, 1, 2, 3 }, /* 18 - Slot 1 */
+                       { 1, 2, 3, 0 }, /* 19 - Slot 2 */
+                       { 2, 3, 0, 1 }, /* 20 - Slot 3 */
+                       { 3, 0, 1, 2 }, /* 21 - Slot 4 */
+               };
+
+               const long min_idsel = 16, max_idsel = 21, irqs_per_slot = 4;
+               int i, j;
+
+               for (i = 0; i < 6; i++)
+                       for (j = 0; j < 4; j++)
+                               pci_irq_table[i][j] =
+                                       ((pci_irq_table[i][j] + 5 -
+                                         cds_pci_slot) & 0x3) + PIRQ0A;
+
+               return PCI_IRQ_TABLE_LOOKUP;
+       } else {
+               /* Handle PCI2 interrupts (if we have one) */
+               char pci_irq_table[][4] =
+               {
+                       /*
+                        * We only have one slot and one interrupt
+                        * going to PIRQA - PIRQD */
+                       { PIRQ1A, PIRQ1A, PIRQ1A, PIRQ1A }, /* 21 - slot 0 */
+               };
+
+               const long min_idsel = 21, max_idsel = 21, irqs_per_slot = 4;
+
+               return PCI_IRQ_TABLE_LOOKUP;
+       }
+}
+
+#define ARCADIA_HOST_BRIDGE_IDSEL      17
+#define ARCADIA_2ND_BRIDGE_IDSEL       3
+
+extern int mpc85xx_pci2_busno;
+
+int
+mpc85xx_exclude_device(u_char bus, u_char devfn)
+{
+       if (bus == 0 && PCI_SLOT(devfn) == 0)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+       if (mpc85xx_pci2_busno)
+               if (bus == (mpc85xx_pci2_busno) && PCI_SLOT(devfn) == 0)
+                       return PCIBIOS_DEVICE_NOT_FOUND;
+       /* We explicitly do not go past the Tundra 320 Bridge */
+       if ((bus == 1) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+       if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
+               return PCIBIOS_DEVICE_NOT_FOUND;
+       else
+               return PCIBIOS_SUCCESSFUL;
+}
+
+void __init
+mpc85xx_cds_pcibios_fixup(void)
+{
+       struct pci_dev *dev;
+       u_char          c;
+
+       if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
+                                       PCI_DEVICE_ID_VIA_82C586_1, NULL))) {
+               /*
+                * U-Boot does not set the enable bits
+                * for the IDE device. Force them on here.
+                */
+               pci_read_config_byte(dev, 0x40, &c);
+               c |= 0x03; /* IDE: Chip Enable Bits */
+               pci_write_config_byte(dev, 0x40, c);
+
+               /*
+                * Since only primary interface works, force the
+                * IDE function to standard primary IDE interrupt
+                * w/ 8259 offset
+                */
+               dev->irq = 14;
+               pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+               pci_dev_put(dev);
+       }
+
+       /*
+        * Force legacy USB interrupt routing
+        */
+       if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
+                                       PCI_DEVICE_ID_VIA_82C586_2, NULL))) {
+               dev->irq = 10;
+               pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10);
+               pci_dev_put(dev);
+       }
+
+       if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
+                                       PCI_DEVICE_ID_VIA_82C586_2, dev))) {
+               dev->irq = 11;
+               pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11);
+               pci_dev_put(dev);
+       }
+}
+#endif /* CONFIG_PCI */
+
+void __init mpc85xx_cds_pic_init(void)
+{
+       struct mpic *mpic1;
+       phys_addr_t OpenPIC_PAddr;
+
+       /* Determine the Physical Address of the OpenPIC regs */
+       OpenPIC_PAddr = get_immrbase() + MPC85xx_OPENPIC_OFFSET;
+
+       mpic1 = mpic_alloc(OpenPIC_PAddr,
+                       MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN,
+                       4, MPC85xx_OPENPIC_IRQ_OFFSET, 0, 250,
+                       mpc85xx_cds_openpic_initsenses,
+                       sizeof(mpc85xx_cds_openpic_initsenses), " OpenPIC  ");
+       BUG_ON(mpic1 == NULL);
+       mpic_assign_isu(mpic1, 0, OpenPIC_PAddr + 0x10200);
+       mpic_assign_isu(mpic1, 1, OpenPIC_PAddr + 0x10280);
+       mpic_assign_isu(mpic1, 2, OpenPIC_PAddr + 0x10300);
+       mpic_assign_isu(mpic1, 3, OpenPIC_PAddr + 0x10380);
+       mpic_assign_isu(mpic1, 4, OpenPIC_PAddr + 0x10400);
+       mpic_assign_isu(mpic1, 5, OpenPIC_PAddr + 0x10480);
+       mpic_assign_isu(mpic1, 6, OpenPIC_PAddr + 0x10500);
+       mpic_assign_isu(mpic1, 7, OpenPIC_PAddr + 0x10580);
+
+       /* dummy mappings to get to 48 */
+       mpic_assign_isu(mpic1, 8, OpenPIC_PAddr + 0x10600);
+       mpic_assign_isu(mpic1, 9, OpenPIC_PAddr + 0x10680);
+       mpic_assign_isu(mpic1, 10, OpenPIC_PAddr + 0x10700);
+       mpic_assign_isu(mpic1, 11, OpenPIC_PAddr + 0x10780);
+
+       /* External ints */
+       mpic_assign_isu(mpic1, 12, OpenPIC_PAddr + 0x10000);
+       mpic_assign_isu(mpic1, 13, OpenPIC_PAddr + 0x10080);
+       mpic_assign_isu(mpic1, 14, OpenPIC_PAddr + 0x10100);
+
+       mpic_init(mpic1);
+
+#ifdef CONFIG_PCI
+       mpic_setup_cascade(PIRQ0A, i8259_irq_cascade, NULL);
+
+       i8259_init(0,0);
+#endif
+}
+
+
+/*
+ * Setup the architecture
+ */
+static void __init
+mpc85xx_cds_setup_arch(void)
+{
+       struct device_node *cpu;
+#ifdef CONFIG_PCI
+       struct device_node *np;
+#endif
+
+       if (ppc_md.progress)
+               ppc_md.progress("mpc85xx_cds_setup_arch()", 0);
+
+       cpu = of_find_node_by_type(NULL, "cpu");
+       if (cpu != 0) {
+               unsigned int *fp;
+
+               fp = (int *)get_property(cpu, "clock-frequency", NULL);
+               if (fp != 0)
+                       loops_per_jiffy = *fp / HZ;
+               else
+                       loops_per_jiffy = 500000000 / HZ;
+               of_node_put(cpu);
+       }
+
+       cadmus = ioremap(CADMUS_BASE, CADMUS_SIZE);
+       cds_pci_slot = ((cadmus[CM_CSR] >> 6) & 0x3) + 1;
+
+       if (ppc_md.progress) {
+               char buf[40];
+               snprintf(buf, 40, "CDS Version = 0x%x in slot %d\n",
+                               cadmus[CM_VER], cds_pci_slot);
+               ppc_md.progress(buf, 0);
+       }
+
+#ifdef CONFIG_PCI
+       for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
+               add_bridge(np);
+
+       ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup;
+       ppc_md.pci_swizzle = common_swizzle;
+       ppc_md.pci_map_irq = mpc85xx_map_irq;
+       ppc_md.pci_exclude_device = mpc85xx_exclude_device;
+#endif
+
+#ifdef  CONFIG_ROOT_NFS
+       ROOT_DEV = Root_NFS;
+#else
+       ROOT_DEV = Root_HDA1;
+#endif
+}
+
+
+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);
+
+       seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
+       seq_printf(m, "Machine\t\t: MPC85xx CDS (0x%x)\n", cadmus[CM_VER]);
+       seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
+       seq_printf(m, "SVR\t\t: 0x%x\n", svid);
+
+       /* 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));
+}
+
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init mpc85xx_cds_probe(void)
+{
+       /* We always match for now, eventually we should look at
+        * the flat dev tree to ensure this is the board we are
+        * supposed to run on
+        */
+       return 1;
+}
+
+define_machine(mpc85xx_cds) {
+       .name           = "MPC85xx CDS",
+       .probe          = mpc85xx_cds_probe,
+       .setup_arch     = mpc85xx_cds_setup_arch,
+       .init_IRQ       = mpc85xx_cds_pic_init,
+       .show_cpuinfo   = mpc85xx_cds_show_cpuinfo,
+       .get_irq        = mpic_get_irq,
+       .restart        = mpc85xx_restart,
+       .calibrate_decr = generic_calibrate_decr,
+       .progress       = udbg_progress,
+};
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.h b/arch/powerpc/platforms/85xx/mpc85xx_cds.h
new file mode 100644 (file)
index 0000000..671f54f
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * arch/ppc/platforms/85xx/mpc85xx_cds_common.h
+ *
+ * MPC85xx CDS board definitions
+ *
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
+ *
+ * Copyright 2004 Freescale Semiconductor, Inc
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef __MACH_MPC85XX_CDS_H__
+#define __MACH_MPC85XX_CDS_H__
+
+/* CADMUS info */
+#define CADMUS_BASE (0xf8004000)
+#define CADMUS_SIZE (256)
+#define CM_VER (0)
+#define CM_CSR (1)
+#define CM_RST (2)
+
+/* CDS NVRAM/RTC */
+#define CDS_RTC_ADDR   (0xf8000000)
+#define CDS_RTC_SIZE   (8 * 1024)
+
+/* PCI interrupt controller */
+#define PIRQ0A                 MPC85xx_IRQ_EXT0
+#define PIRQ0B                 MPC85xx_IRQ_EXT1
+#define PIRQ0C                 MPC85xx_IRQ_EXT2
+#define PIRQ0D                 MPC85xx_IRQ_EXT3
+#define PIRQ1A                 MPC85xx_IRQ_EXT11
+
+#define NR_8259_INTS           16
+#define CPM_IRQ_OFFSET         NR_8259_INTS
+
+#define MPC85xx_OPENPIC_IRQ_OFFSET     80
+
+#endif /* __MACH_MPC85XX_CDS_H__ */
index 8bb33abfad175b721e86b948f2ab1bdb57ccea5d..36439c5e9f2d80ba0c27415cae29dbb1d0af34ee 100644 (file)
@@ -30,7 +30,7 @@
 struct spu_context *alloc_spu_context(void)
 {
        struct spu_context *ctx;
-       ctx = kmalloc(sizeof *ctx, GFP_KERNEL);
+       ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
        if (!ctx)
                goto out;
        /* Binding to physical processor deferred
@@ -48,17 +48,7 @@ struct spu_context *alloc_spu_context(void)
        init_waitqueue_head(&ctx->wbox_wq);
        init_waitqueue_head(&ctx->stop_wq);
        init_waitqueue_head(&ctx->mfc_wq);
-       ctx->ibox_fasync = NULL;
-       ctx->wbox_fasync = NULL;
-       ctx->mfc_fasync = NULL;
-       ctx->mfc = NULL;
-       ctx->tagwait = 0;
        ctx->state = SPU_STATE_SAVED;
-       ctx->local_store = NULL;
-       ctx->cntl = NULL;
-       ctx->signal1 = NULL;
-       ctx->signal2 = NULL;
-       ctx->spu = NULL;
        ctx->ops = &spu_backing_ops;
        ctx->owner = get_task_mm(current);
        goto out;
index ce8c0b943fa0ffee6c81be950fc619f1cd4ced26..dee4eb4d8bec05082e30510f813c956e1d6ff9a3 100644 (file)
@@ -1,9 +1,11 @@
 EXTRA_CFLAGS   += -mno-minimal-toc
 
-obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \
+obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt_mod.o mf.o lpevents.o \
        hvcall.o proc.o htab.o iommu.o misc.o irq.o
 obj-$(CONFIG_PCI) += pci.o vpdinfo.o
-obj-$(CONFIG_IBMVIO) += vio.o
 obj-$(CONFIG_SMP) += smp.o
 obj-$(CONFIG_VIOPATH) += viopath.o
 obj-$(CONFIG_MODULES) += ksyms.o
+
+$(obj)/dt_mod.o:       $(obj)/dt.o
+       @$(OBJCOPY) --rename-section .rodata.str1.8=.dt_strings $(obj)/dt.o $(obj)/dt_mod.o
index 59d4e0ad5cf324796e5ea7e7dd081feef071f476..dbdf69850ed9a0ab2aece186db0ab077f4c8b509 100644 (file)
@@ -145,6 +145,25 @@ static inline u64 HvCallPci_configLoad16(u16 busNumber, u8 subBusNumber,
        return retVal.rc;
 }
 
+static inline u64 HvCallPci_configLoad32(u16 busNumber, u8 subBusNumber,
+               u8 deviceId, u32 offset, u32 *value)
+{
+       struct HvCallPci_DsaAddr dsa;
+       struct HvCallPci_LoadReturn retVal;
+
+       *((u64*)&dsa) = 0;
+
+       dsa.busNumber = busNumber;
+       dsa.subBusNumber = subBusNumber;
+       dsa.deviceId = deviceId;
+
+       HvCall3Ret16(HvCallPciConfigLoad32, &retVal, *(u64 *)&dsa, offset, 0);
+
+       *value = retVal.value;
+
+       return retVal.rc;
+}
+
 static inline u64 HvCallPci_configStore8(u16 busNumber, u8 subBusNumber,
                u8 deviceId, u32 offset, u8 value)
 {
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
new file mode 100644 (file)
index 0000000..d3444aa
--- /dev/null
@@ -0,0 +1,615 @@
+/*
+ *    Copyright (c) 2005-2006 Michael Ellerman, IBM Corporation
+ *
+ *    Description:
+ *      This file contains all the routines to build a flattened device
+ *      tree for a legacy iSeries machine.
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#undef DEBUG
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/pci_regs.h>
+#include <linux/pci_ids.h>
+#include <linux/threads.h>
+#include <linux/bitops.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/if_ether.h>    /* ETH_ALEN */
+
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/lppaca.h>
+#include <asm/cputable.h>
+#include <asm/abs_addr.h>
+#include <asm/system.h>
+#include <asm/iseries/hv_types.h>
+#include <asm/iseries/hv_lp_config.h>
+#include <asm/iseries/hv_call_xm.h>
+#include <asm/iseries/it_exp_vpd_panel.h>
+#include <asm/udbg.h>
+
+#include "processor_vpd.h"
+#include "call_hpt.h"
+#include "call_pci.h"
+#include "pci.h"
+
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+/*
+ * These are created by the linker script at the start and end
+ * of the section containing all the strings from this file.
+ */
+extern char __dt_strings_start[];
+extern char __dt_strings_end[];
+
+struct iseries_flat_dt {
+       struct boot_param_header header;
+       u64 reserve_map[2];
+};
+
+static void * __initdata dt_data;
+
+/*
+ * Putting these strings here keeps them out of the section
+ * that we rename to .dt_strings using objcopy and capture
+ * for the strings blob of the flattened device tree.
+ */
+static char __initdata device_type_cpu[] = "cpu";
+static char __initdata device_type_memory[] = "memory";
+static char __initdata device_type_serial[] = "serial";
+static char __initdata device_type_network[] = "network";
+static char __initdata device_type_block[] = "block";
+static char __initdata device_type_byte[] = "byte";
+static char __initdata device_type_pci[] = "pci";
+static char __initdata device_type_vdevice[] = "vdevice";
+static char __initdata device_type_vscsi[] = "vscsi";
+
+static struct iseries_flat_dt * __init dt_init(void)
+{
+       struct iseries_flat_dt *dt;
+       unsigned long str_len;
+
+       str_len = __dt_strings_end - __dt_strings_start;
+       dt = (struct iseries_flat_dt *)ALIGN(klimit, 8);
+       dt->header.off_mem_rsvmap =
+               offsetof(struct iseries_flat_dt, reserve_map);
+       dt->header.off_dt_strings = ALIGN(sizeof(*dt), 8);
+       dt->header.off_dt_struct = dt->header.off_dt_strings
+               + ALIGN(str_len, 8);
+       dt_data = (void *)((unsigned long)dt + dt->header.off_dt_struct);
+       dt->header.dt_strings_size = str_len;
+
+       /* There is no notion of hardware cpu id on iSeries */
+       dt->header.boot_cpuid_phys = smp_processor_id();
+
+       memcpy((char *)dt + dt->header.off_dt_strings, __dt_strings_start,
+                       str_len);
+
+       dt->header.magic = OF_DT_HEADER;
+       dt->header.version = 0x10;
+       dt->header.last_comp_version = 0x10;
+
+       dt->reserve_map[0] = 0;
+       dt->reserve_map[1] = 0;
+
+       return dt;
+}
+
+static void __init dt_push_u32(struct iseries_flat_dt *dt, u32 value)
+{
+       *((u32 *)dt_data) = value;
+       dt_data += sizeof(u32);
+}
+
+#ifdef notyet
+static void __init dt_push_u64(struct iseries_flat_dt *dt, u64 value)
+{
+       *((u64 *)dt_data) = value;
+       dt_data += sizeof(u64);
+}
+#endif
+
+static void __init dt_push_bytes(struct iseries_flat_dt *dt, const char *data,
+               int len)
+{
+       memcpy(dt_data, data, len);
+       dt_data += ALIGN(len, 4);
+}
+
+static void __init dt_start_node(struct iseries_flat_dt *dt, const char *name)
+{
+       dt_push_u32(dt, OF_DT_BEGIN_NODE);
+       dt_push_bytes(dt, name, strlen(name) + 1);
+}
+
+#define dt_end_node(dt) dt_push_u32(dt, OF_DT_END_NODE)
+
+static void __init dt_prop(struct iseries_flat_dt *dt, const char *name,
+               const void *data, int len)
+{
+       unsigned long offset;
+
+       dt_push_u32(dt, OF_DT_PROP);
+
+       /* Length of the data */
+       dt_push_u32(dt, len);
+
+       offset = name - __dt_strings_start;
+
+       /* The offset of the properties name in the string blob. */
+       dt_push_u32(dt, (u32)offset);
+
+       /* The actual data. */
+       dt_push_bytes(dt, data, len);
+}
+
+static void __init dt_prop_str(struct iseries_flat_dt *dt, const char *name,
+               const char *data)
+{
+       dt_prop(dt, name, data, strlen(data) + 1); /* + 1 for NULL */
+}
+
+static void __init dt_prop_u32(struct iseries_flat_dt *dt, const char *name,
+               u32 data)
+{
+       dt_prop(dt, name, &data, sizeof(u32));
+}
+
+#ifdef notyet
+static void __init dt_prop_u64(struct iseries_flat_dt *dt, const char *name,
+               u64 data)
+{
+       dt_prop(dt, name, &data, sizeof(u64));
+}
+#endif
+
+static void __init dt_prop_u64_list(struct iseries_flat_dt *dt,
+               const char *name, u64 *data, int n)
+{
+       dt_prop(dt, name, data, sizeof(u64) * n);
+}
+
+static void __init dt_prop_u32_list(struct iseries_flat_dt *dt,
+               const char *name, u32 *data, int n)
+{
+       dt_prop(dt, name, data, sizeof(u32) * n);
+}
+
+#ifdef notyet
+static void __init dt_prop_empty(struct iseries_flat_dt *dt, const char *name)
+{
+       dt_prop(dt, name, NULL, 0);
+}
+#endif
+
+static void __init dt_cpus(struct iseries_flat_dt *dt)
+{
+       unsigned char buf[32];
+       unsigned char *p;
+       unsigned int i, index;
+       struct IoHriProcessorVpd *d;
+       u32 pft_size[2];
+
+       /* yuck */
+       snprintf(buf, 32, "PowerPC,%s", cur_cpu_spec->cpu_name);
+       p = strchr(buf, ' ');
+       if (!p) p = buf + strlen(buf);
+
+       dt_start_node(dt, "cpus");
+       dt_prop_u32(dt, "#address-cells", 1);
+       dt_prop_u32(dt, "#size-cells", 0);
+
+       pft_size[0] = 0; /* NUMA CEC cookie, 0 for non NUMA  */
+       pft_size[1] = __ilog2(HvCallHpt_getHptPages() * HW_PAGE_SIZE);
+
+       for (i = 0; i < NR_CPUS; i++) {
+               if (lppaca[i].dyn_proc_status >= 2)
+                       continue;
+
+               snprintf(p, 32 - (p - buf), "@%d", i);
+               dt_start_node(dt, buf);
+
+               dt_prop_str(dt, "device_type", device_type_cpu);
+
+               index = lppaca[i].dyn_hv_phys_proc_index;
+               d = &xIoHriProcessorVpd[index];
+
+               dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024);
+               dt_prop_u32(dt, "i-cache-line-size", d->xInstCacheOperandSize);
+
+               dt_prop_u32(dt, "d-cache-size", d->xDataL1CacheSizeKB * 1024);
+               dt_prop_u32(dt, "d-cache-line-size", d->xDataCacheOperandSize);
+
+               /* magic conversions to Hz copied from old code */
+               dt_prop_u32(dt, "clock-frequency",
+                       ((1UL << 34) * 1000000) / d->xProcFreq);
+               dt_prop_u32(dt, "timebase-frequency",
+                       ((1UL << 32) * 1000000) / d->xTimeBaseFreq);
+
+               dt_prop_u32(dt, "reg", i);
+
+               dt_prop_u32_list(dt, "ibm,pft-size", pft_size, 2);
+
+               dt_end_node(dt);
+       }
+
+       dt_end_node(dt);
+}
+
+static void __init dt_model(struct iseries_flat_dt *dt)
+{
+       char buf[16] = "IBM,";
+
+       /* "IBM," + mfgId[2:3] + systemSerial[1:5] */
+       strne2a(buf + 4, xItExtVpdPanel.mfgID + 2, 2);
+       strne2a(buf + 6, xItExtVpdPanel.systemSerial + 1, 5);
+       buf[11] = '\0';
+       dt_prop_str(dt, "system-id", buf);
+
+       /* "IBM," + machineType[0:4] */
+       strne2a(buf + 4, xItExtVpdPanel.machineType, 4);
+       buf[8] = '\0';
+       dt_prop_str(dt, "model", buf);
+
+       dt_prop_str(dt, "compatible", "IBM,iSeries");
+}
+
+static void __init dt_do_vdevice(struct iseries_flat_dt *dt,
+               const char *name, u32 reg, int unit,
+               const char *type, const char *compat, int end)
+{
+       char buf[32];
+
+       snprintf(buf, 32, "%s@%08x", name, reg + ((unit >= 0) ? unit : 0));
+       dt_start_node(dt, buf);
+       dt_prop_str(dt, "device_type", type);
+       if (compat)
+               dt_prop_str(dt, "compatible", compat);
+       dt_prop_u32(dt, "reg", reg + ((unit >= 0) ? unit : 0));
+       if (unit >= 0)
+               dt_prop_u32(dt, "linux,unit_address", unit);
+       if (end)
+               dt_end_node(dt);
+}
+
+static void __init dt_vdevices(struct iseries_flat_dt *dt)
+{
+       u32 reg = 0;
+       HvLpIndexMap vlan_map;
+       int i;
+
+       dt_start_node(dt, "vdevice");
+       dt_prop_str(dt, "device_type", device_type_vdevice);
+       dt_prop_str(dt, "compatible", "IBM,iSeries-vdevice");
+       dt_prop_u32(dt, "#address-cells", 1);
+       dt_prop_u32(dt, "#size-cells", 0);
+
+       dt_do_vdevice(dt, "vty", reg, -1, device_type_serial, NULL, 1);
+       reg++;
+
+       dt_do_vdevice(dt, "v-scsi", reg, -1, device_type_vscsi,
+                       "IBM,v-scsi", 1);
+       reg++;
+
+       vlan_map = HvLpConfig_getVirtualLanIndexMap();
+       for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) {
+               unsigned char mac_addr[ETH_ALEN];
+
+               if ((vlan_map & (0x8000 >> i)) == 0)
+                       continue;
+               dt_do_vdevice(dt, "l-lan", reg, i, device_type_network,
+                               "IBM,iSeries-l-lan", 0);
+               mac_addr[0] = 0x02;
+               mac_addr[1] = 0x01;
+               mac_addr[2] = 0xff;
+               mac_addr[3] = i;
+               mac_addr[4] = 0xff;
+               mac_addr[5] = HvLpConfig_getLpIndex_outline();
+               dt_prop(dt, "local-mac-address", (char *)mac_addr, ETH_ALEN);
+               dt_prop(dt, "mac-address", (char *)mac_addr, ETH_ALEN);
+               dt_prop_u32(dt, "max-frame-size", 9000);
+               dt_prop_u32(dt, "address-bits", 48);
+
+               dt_end_node(dt);
+       }
+       reg += HVMAXARCHITECTEDVIRTUALLANS;
+
+       for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++)
+               dt_do_vdevice(dt, "viodasd", reg, i, device_type_block,
+                               "IBM,iSeries-viodasd", 1);
+       reg += HVMAXARCHITECTEDVIRTUALDISKS;
+
+       for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++)
+               dt_do_vdevice(dt, "viocd", reg, i, device_type_block,
+                               "IBM,iSeries-viocd", 1);
+       reg += HVMAXARCHITECTEDVIRTUALCDROMS;
+
+       for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++)
+               dt_do_vdevice(dt, "viotape", reg, i, device_type_byte,
+                               "IBM,iSeries-viotape", 1);
+
+       dt_end_node(dt);
+}
+
+struct pci_class_name {
+       u16 code;
+       const char *name;
+       const char *type;
+};
+
+static struct pci_class_name __initdata pci_class_name[] = {
+       { PCI_CLASS_NETWORK_ETHERNET, "ethernet", device_type_network },
+};
+
+static struct pci_class_name * __init dt_find_pci_class_name(u16 class_code)
+{
+       struct pci_class_name *cp;
+
+       for (cp = pci_class_name;
+                       cp < &pci_class_name[ARRAY_SIZE(pci_class_name)]; cp++)
+               if (cp->code == class_code)
+                       return cp;
+       return NULL;
+}
+
+/*
+ * This assumes that the node slot is always on the primary bus!
+ */
+static void __init scan_bridge_slot(struct iseries_flat_dt *dt,
+               HvBusNumber bus, struct HvCallPci_BridgeInfo *bridge_info)
+{
+       HvSubBusNumber sub_bus = bridge_info->subBusNumber;
+       u16 vendor_id;
+       u16 device_id;
+       u32 class_id;
+       int err;
+       char buf[32];
+       u32 reg[5];
+       int id_sel = ISERIES_GET_DEVICE_FROM_SUBBUS(sub_bus);
+       int function = ISERIES_GET_FUNCTION_FROM_SUBBUS(sub_bus);
+       HvAgentId eads_id_sel = ISERIES_PCI_AGENTID(id_sel, function);
+       u8 devfn;
+       struct pci_class_name *cp;
+
+       /*
+        * Connect all functions of any device found.
+        */
+       for (id_sel = 1; id_sel <= bridge_info->maxAgents; id_sel++) {
+               for (function = 0; function < 8; function++) {
+                       HvAgentId agent_id = ISERIES_PCI_AGENTID(id_sel,
+                                       function);
+                       err = HvCallXm_connectBusUnit(bus, sub_bus,
+                                       agent_id, 0);
+                       if (err) {
+                               if (err != 0x302)
+                                       DBG("connectBusUnit(%x, %x, %x) %x\n",
+                                               bus, sub_bus, agent_id, err);
+                               continue;
+                       }
+
+                       err = HvCallPci_configLoad16(bus, sub_bus, agent_id,
+                                       PCI_VENDOR_ID, &vendor_id);
+                       if (err) {
+                               DBG("ReadVendor(%x, %x, %x) %x\n",
+                                       bus, sub_bus, agent_id, err);
+                               continue;
+                       }
+                       err = HvCallPci_configLoad16(bus, sub_bus, agent_id,
+                                       PCI_DEVICE_ID, &device_id);
+                       if (err) {
+                               DBG("ReadDevice(%x, %x, %x) %x\n",
+                                       bus, sub_bus, agent_id, err);
+                               continue;
+                       }
+                       err = HvCallPci_configLoad32(bus, sub_bus, agent_id,
+                                       PCI_CLASS_REVISION , &class_id);
+                       if (err) {
+                               DBG("ReadClass(%x, %x, %x) %x\n",
+                                       bus, sub_bus, agent_id, err);
+                               continue;
+                       }
+
+                       devfn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(eads_id_sel),
+                                       function);
+                       cp = dt_find_pci_class_name(class_id >> 16);
+                       if (cp && cp->name)
+                               strncpy(buf, cp->name, sizeof(buf) - 1);
+                       else
+                               snprintf(buf, sizeof(buf), "pci%x,%x",
+                                               vendor_id, device_id);
+                       buf[sizeof(buf) - 1] = '\0';
+                       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+                                       "@%x", PCI_SLOT(devfn));
+                       buf[sizeof(buf) - 1] = '\0';
+                       if (function != 0)
+                               snprintf(buf + strlen(buf),
+                                       sizeof(buf) - strlen(buf),
+                                       ",%x", function);
+                       dt_start_node(dt, buf);
+                       reg[0] = (bus << 16) | (devfn << 8);
+                       reg[1] = 0;
+                       reg[2] = 0;
+                       reg[3] = 0;
+                       reg[4] = 0;
+                       dt_prop_u32_list(dt, "reg", reg, 5);
+                       if (cp && (cp->type || cp->name))
+                               dt_prop_str(dt, "device_type",
+                                       cp->type ? cp->type : cp->name);
+                       dt_prop_u32(dt, "vendor-id", vendor_id);
+                       dt_prop_u32(dt, "device-id", device_id);
+                       dt_prop_u32(dt, "class-code", class_id >> 8);
+                       dt_prop_u32(dt, "revision-id", class_id & 0xff);
+                       dt_prop_u32(dt, "linux,subbus", sub_bus);
+                       dt_prop_u32(dt, "linux,agent-id", agent_id);
+                       dt_prop_u32(dt, "linux,logical-slot-number",
+                                       bridge_info->logicalSlotNumber);
+                       dt_end_node(dt);
+
+               }
+       }
+}
+
+static void __init scan_bridge(struct iseries_flat_dt *dt, HvBusNumber bus,
+               HvSubBusNumber sub_bus, int id_sel)
+{
+       struct HvCallPci_BridgeInfo bridge_info;
+       HvAgentId agent_id;
+       int function;
+       int ret;
+
+       /* Note: hvSubBus and irq is always be 0 at this level! */
+       for (function = 0; function < 8; ++function) {
+               agent_id = ISERIES_PCI_AGENTID(id_sel, function);
+               ret = HvCallXm_connectBusUnit(bus, sub_bus, agent_id, 0);
+               if (ret != 0) {
+                       if (ret != 0xb)
+                               DBG("connectBusUnit(%x, %x, %x) %x\n",
+                                               bus, sub_bus, agent_id, ret);
+                       continue;
+               }
+               DBG("found device at bus %d idsel %d func %d (AgentId %x)\n",
+                               bus, id_sel, function, agent_id);
+               ret = HvCallPci_getBusUnitInfo(bus, sub_bus, agent_id,
+                               iseries_hv_addr(&bridge_info),
+                               sizeof(struct HvCallPci_BridgeInfo));
+               if (ret != 0)
+                       continue;
+               DBG("bridge info: type %x subbus %x "
+                       "maxAgents %x maxsubbus %x logslot %x\n",
+                       bridge_info.busUnitInfo.deviceType,
+                       bridge_info.subBusNumber,
+                       bridge_info.maxAgents,
+                       bridge_info.maxSubBusNumber,
+                       bridge_info.logicalSlotNumber);
+               if (bridge_info.busUnitInfo.deviceType ==
+                               HvCallPci_BridgeDevice)
+                       scan_bridge_slot(dt, bus, &bridge_info);
+               else
+                       DBG("PCI: Invalid Bridge Configuration(0x%02X)",
+                               bridge_info.busUnitInfo.deviceType);
+       }
+}
+
+static void __init scan_phb(struct iseries_flat_dt *dt, HvBusNumber bus)
+{
+       struct HvCallPci_DeviceInfo dev_info;
+       const HvSubBusNumber sub_bus = 0;       /* EADs is always 0. */
+       int err;
+       int id_sel;
+       const int max_agents = 8;
+
+       /*
+        * Probe for EADs Bridges
+        */
+       for (id_sel = 1; id_sel < max_agents; ++id_sel) {
+               err = HvCallPci_getDeviceInfo(bus, sub_bus, id_sel,
+                               iseries_hv_addr(&dev_info),
+                               sizeof(struct HvCallPci_DeviceInfo));
+               if (err) {
+                       if (err != 0x302)
+                               DBG("getDeviceInfo(%x, %x, %x) %x\n",
+                                               bus, sub_bus, id_sel, err);
+                       continue;
+               }
+               if (dev_info.deviceType != HvCallPci_NodeDevice) {
+                       DBG("PCI: Invalid System Configuration"
+                                       "(0x%02X) for bus 0x%02x id 0x%02x.\n",
+                                       dev_info.deviceType, bus, id_sel);
+                       continue;
+               }
+               scan_bridge(dt, bus, sub_bus, id_sel);
+       }
+}
+
+static void __init dt_pci_devices(struct iseries_flat_dt *dt)
+{
+       HvBusNumber bus;
+       char buf[32];
+       u32 buses[2];
+       int phb_num = 0;
+
+       /* Check all possible buses. */
+       for (bus = 0; bus < 256; bus++) {
+               int err = HvCallXm_testBus(bus);
+
+               if (err) {
+                       /*
+                        * Check for Unexpected Return code, a clue that
+                        * something has gone wrong.
+                        */
+                       if (err != 0x0301)
+                               DBG("Unexpected Return on Probe(0x%02X) "
+                                               "0x%04X\n", bus, err);
+                       continue;
+               }
+               DBG("bus %d appears to exist\n", bus);
+               snprintf(buf, 32, "pci@%d", phb_num);
+               dt_start_node(dt, buf);
+               dt_prop_str(dt, "device_type", device_type_pci);
+               dt_prop_str(dt, "compatible", "IBM,iSeries-Logical-PHB");
+               dt_prop_u32(dt, "#address-cells", 3);
+               dt_prop_u32(dt, "#size-cells", 2);
+               buses[0] = buses[1] = bus;
+               dt_prop_u32_list(dt, "bus-range", buses, 2);
+               scan_phb(dt, bus);
+               dt_end_node(dt);
+               phb_num++;
+       }
+}
+
+static void dt_finish(struct iseries_flat_dt *dt)
+{
+       dt_push_u32(dt, OF_DT_END);
+       dt->header.totalsize = (unsigned long)dt_data - (unsigned long)dt;
+       klimit = ALIGN((unsigned long)dt_data, 8);
+}
+
+void * __init build_flat_dt(unsigned long phys_mem_size)
+{
+       struct iseries_flat_dt *iseries_dt;
+       u64 tmp[2];
+
+       iseries_dt = dt_init();
+
+       dt_start_node(iseries_dt, "");
+
+       dt_prop_u32(iseries_dt, "#address-cells", 2);
+       dt_prop_u32(iseries_dt, "#size-cells", 2);
+       dt_model(iseries_dt);
+
+       /* /memory */
+       dt_start_node(iseries_dt, "memory@0");
+       dt_prop_str(iseries_dt, "device_type", device_type_memory);
+       tmp[0] = 0;
+       tmp[1] = phys_mem_size;
+       dt_prop_u64_list(iseries_dt, "reg", tmp, 2);
+       dt_end_node(iseries_dt);
+
+       /* /chosen */
+       dt_start_node(iseries_dt, "chosen");
+       dt_prop_str(iseries_dt, "bootargs", cmd_line);
+       dt_end_node(iseries_dt);
+
+       dt_cpus(iseries_dt);
+
+       dt_vdevices(iseries_dt);
+       dt_pci_devices(iseries_dt);
+
+       dt_end_node(iseries_dt);
+
+       dt_finish(iseries_dt);
+
+       return iseries_dt;
+}
index bea0b703f4095c216c1b290119199ac15bdac047..a992f6af249fe081af06753b145f6b68bf1a8bd9 100644 (file)
@@ -4,6 +4,7 @@
  * Rewrite, cleanup:
  *
  * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation
+ * Copyright (C) 2006 Olof Johansson <olof@lixom.net>
  *
  * Dynamic DMA mapping support, iSeries-specific parts.
  *
 #include <asm/tce.h>
 #include <asm/machdep.h>
 #include <asm/abs_addr.h>
+#include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #include <asm/iseries/hv_call_xm.h>
-
-#include "iommu.h"
-
-extern struct list_head iSeries_Global_Device_List;
-
+#include <asm/iseries/iommu.h>
 
 static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,
                unsigned long uaddr, enum dma_data_direction direction)
 {
        u64 rc;
-       union tce_entry tce;
+       u64 tce, rpn;
 
        index <<= TCE_PAGE_FACTOR;
        npages <<= TCE_PAGE_FACTOR;
 
        while (npages--) {
-               tce.te_word = 0;
-               tce.te_bits.tb_rpn = virt_to_abs(uaddr) >> TCE_SHIFT;
+               rpn = virt_to_abs(uaddr) >> TCE_SHIFT;
+               tce = (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
 
                if (tbl->it_type == TCE_VB) {
                        /* Virtual Bus */
-                       tce.te_bits.tb_valid = 1;
-                       tce.te_bits.tb_allio = 1;
+                       tce |= TCE_VALID|TCE_ALLIO;
                        if (direction != DMA_TO_DEVICE)
-                               tce.te_bits.tb_rdwr = 1;
+                               tce |= TCE_VB_WRITE;
                } else {
                        /* PCI Bus */
-                       tce.te_bits.tb_rdwr = 1; /* Read allowed */
+                       tce |= TCE_PCI_READ; /* Read allowed */
                        if (direction != DMA_TO_DEVICE)
-                               tce.te_bits.tb_pciwr = 1;
+                               tce |= TCE_PCI_WRITE;
                }
 
-               rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index,
-                               tce.te_word);
+               rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, tce);
                if (rc)
                        panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n",
                                        rc);
@@ -124,7 +120,7 @@ void iommu_table_getparms_iSeries(unsigned long busno,
 
        /* itc_size is in pages worth of table, it_size is in # of entries */
        tbl->it_size = ((parms->itc_size * TCE_PAGE_SIZE) /
-                       sizeof(union tce_entry)) >> TCE_PAGE_FACTOR;
+                       TCE_ENTRY_SIZE) >> TCE_PAGE_FACTOR;
        tbl->it_busno = parms->itc_busno;
        tbl->it_offset = parms->itc_offset >> TCE_PAGE_FACTOR;
        tbl->it_index = parms->itc_index;
@@ -142,10 +138,15 @@ void iommu_table_getparms_iSeries(unsigned long busno,
  */
 static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
 {
-       struct pci_dn *pdn;
+       struct device_node *node;
 
-       list_for_each_entry(pdn, &iSeries_Global_Device_List, Device_List) {
-               struct iommu_table *it = pdn->iommu_table;
+       for (node = NULL; (node = of_find_all_nodes(node)); ) {
+               struct pci_dn *pdn = PCI_DN(node);
+               struct iommu_table *it;
+
+               if (pdn == NULL)
+                       continue;
+               it = pdn->iommu_table;
                if ((it != NULL) &&
                    (it->it_type == TCE_PCI) &&
                    (it->it_offset == tbl->it_offset) &&
@@ -161,10 +162,13 @@ void iommu_devnode_init_iSeries(struct device_node *dn)
 {
        struct iommu_table *tbl;
        struct pci_dn *pdn = PCI_DN(dn);
+       u32 *lsn = (u32 *)get_property(dn, "linux,logical-slot-number", NULL);
+
+       BUG_ON(lsn == NULL);
 
        tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
 
-       iommu_table_getparms_iSeries(pdn->busno, pdn->LogicalSlot, 0, tbl);
+       iommu_table_getparms_iSeries(pdn->busno, *lsn, 0, tbl);
 
        /* Look for existing tce table */
        pdn->iommu_table = iommu_table_find(tbl);
diff --git a/arch/powerpc/platforms/iseries/iommu.h b/arch/powerpc/platforms/iseries/iommu.h
deleted file mode 100644 (file)
index cb5658f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef _PLATFORMS_ISERIES_IOMMU_H
-#define _PLATFORMS_ISERIES_IOMMU_H
-
-/*
- * Copyright (C) 2005  Stephen Rothwell, 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; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the:
- * Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330,
- * Boston, MA  02111-1307  USA
- */
-
-struct device_node;
-struct iommu_table;
-
-/* Creates table for an individual device node */
-extern void iommu_devnode_init_iSeries(struct device_node *dn);
-
-/* Get table parameters from HV */
-extern void iommu_table_getparms_iSeries(unsigned long busno,
-               unsigned char slotno, unsigned char virtbus,
-               struct iommu_table *tbl);
-
-#endif /* _PLATFORMS_ISERIES_IOMMU_H */
index be3fbfc24e6cc2b1ecf947df77fd38f9c4f2b050..62bbbcf5ded3e27d19f5c2ed0f1d2e402171b87f 100644 (file)
@@ -42,6 +42,7 @@
 #include <asm/iseries/it_lp_queue.h>
 
 #include "irq.h"
+#include "pci.h"
 #include "call_pci.h"
 
 #if defined(CONFIG_SMP)
@@ -312,12 +313,12 @@ static hw_irq_controller iSeries_IRQ_handler = {
  * Note that sub_bus is always 0 (at the moment at least).
  */
 int __init iSeries_allocate_IRQ(HvBusNumber bus,
-               HvSubBusNumber sub_bus, HvAgentId dev_id)
+               HvSubBusNumber sub_bus, u32 bsubbus)
 {
        int virtirq;
        unsigned int realirq;
-       u8 idsel = (dev_id >> 4);
-       u8 function = dev_id & 7;
+       u8 idsel = ISERIES_GET_DEVICE_FROM_SUBBUS(bsubbus);
+       u8 function = ISERIES_GET_FUNCTION_FROM_SUBBUS(bsubbus);
 
        realirq = (((((sub_bus << 8) + (bus - 1)) << 3) + (idsel - 1)) << 3)
                + function;
index b9c801ba5a476d103a35d454ffd89c783d901b3c..188aa808abd7c8941c2712f365bbf1240a96b4b2 100644 (file)
@@ -2,7 +2,7 @@
 #define        _ISERIES_IRQ_H
 
 extern void iSeries_init_IRQ(void);
-extern int  iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId);
+extern int  iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, u32);
 extern void iSeries_activate_IRQs(void);
 extern int iSeries_get_irq(struct pt_regs *);
 
index d771b8ee857d59462af2a5dde6c870dfa6e52b13..1a2c2a50f9221c912e3c5a465f97a495d03fac9c 100644 (file)
@@ -45,7 +45,6 @@
 
 #include "setup.h"
 
-extern int piranha_simulator;
 static int mf_initialized;
 
 /*
@@ -658,7 +657,7 @@ static void mf_clear_src(void)
 
 void __init mf_display_progress(u16 value)
 {
-       if (piranha_simulator || !mf_initialized)
+       if (!mf_initialized)
                return;
 
        if (0xFFFF == value)
@@ -1295,9 +1294,6 @@ __initcall(mf_proc_init);
  */
 void iSeries_get_rtc_time(struct rtc_time *rtc_tm)
 {
-       if (piranha_simulator)
-               return;
-
        mf_get_rtc(rtc_tm);
        rtc_tm->tm_mon--;
 }
@@ -1316,9 +1312,6 @@ unsigned long iSeries_get_boot_time(void)
 {
        struct rtc_time tm;
 
-       if (piranha_simulator)
-               return 0;
-
        mf_get_boot_rtc(&tm);
        return mktime(tm.tm_year + 1900, tm.tm_mon, tm.tm_mday,
                      tm.tm_hour, tm.tm_min, tm.tm_sec);
index a19833b880e4096273c5e5360d01af7638ddf9e2..35bcc98111f5b7077faa9a1f612861cfa678b983 100644 (file)
 
 #include <asm/iseries/hv_call_xm.h>
 #include <asm/iseries/mf.h>
+#include <asm/iseries/iommu.h>
 
 #include <asm/ppc-pci.h>
 
 #include "irq.h"
 #include "pci.h"
 #include "call_pci.h"
-#include "iommu.h"
-
-extern unsigned long io_page_mask;
 
 /*
  * Forward declares of prototypes.
  */
 static struct device_node *find_Device_Node(int bus, int devfn);
-static void scan_PHB_slots(struct pci_controller *Phb);
-static void scan_EADS_bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel);
-static int scan_bridge_slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo *Info);
-
-LIST_HEAD(iSeries_Global_Device_List);
-
-static int DeviceCount;
-
-/* Counters and control flags. */
-static long Pci_Io_Read_Count;
-static long Pci_Io_Write_Count;
-#if 0
-static long Pci_Cfg_Read_Count;
-static long Pci_Cfg_Write_Count;
-#endif
-static long Pci_Error_Count;
 
 static int Pci_Retry_Max = 3;  /* Only retry 3 times  */
 static int Pci_Error_Flag = 1; /* Set Retry Error on. */
@@ -81,40 +63,18 @@ static struct pci_ops iSeries_pci_ops;
 #define IOMM_TABLE_ENTRY_SIZE  0x0000000000400000UL
 #define BASE_IO_MEMORY         0xE000000000000000UL
 
-static unsigned long max_io_memory = 0xE000000000000000UL;
+static unsigned long max_io_memory = BASE_IO_MEMORY;
 static long current_iomm_table_entry;
 
 /*
  * Lookup Tables.
  */
-static struct device_node **iomm_table;
-static u8 *iobar_table;
+static struct device_node *iomm_table[IOMM_TABLE_MAX_ENTRIES];
+static u8 iobar_table[IOMM_TABLE_MAX_ENTRIES];
 
-/*
- * Static and Global variables
- */
-static char *pci_io_text = "iSeries PCI I/O";
+static const char pci_io_text[] = "iSeries PCI I/O";
 static DEFINE_SPINLOCK(iomm_table_lock);
 
-/*
- * iomm_table_initialize
- *
- * Allocates and initalizes the Address Translation Table and Bar
- * Tables to get them ready for use.  Must be called before any
- * I/O space is handed out to the device BARs.
- */
-static void iomm_table_initialize(void)
-{
-       spin_lock(&iomm_table_lock);
-       iomm_table = kmalloc(sizeof(*iomm_table) * IOMM_TABLE_MAX_ENTRIES,
-                       GFP_KERNEL);
-       iobar_table = kmalloc(sizeof(*iobar_table) * IOMM_TABLE_MAX_ENTRIES,
-                       GFP_KERNEL);
-       spin_unlock(&iomm_table_lock);
-       if ((iomm_table == NULL) || (iobar_table == NULL))
-               panic("PCI: I/O tables allocation failed.\n");
-}
-
 /*
  * iomm_table_allocate_entry
  *
@@ -142,9 +102,8 @@ static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
         */
        spin_lock(&iomm_table_lock);
        bar_res->name = pci_io_text;
-       bar_res->start =
+       bar_res->start = BASE_IO_MEMORY +
                IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry;
-       bar_res->start += BASE_IO_MEMORY;
        bar_res->end = bar_res->start + bar_size - 1;
        /*
         * Allocate the number of table entries needed for BAR.
@@ -156,7 +115,7 @@ static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
                ++current_iomm_table_entry;
        }
        max_io_memory = BASE_IO_MEMORY +
-               (IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry);
+               IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry;
        spin_unlock(&iomm_table_lock);
 }
 
@@ -173,13 +132,10 @@ static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
  */
 static void allocate_device_bars(struct pci_dev *dev)
 {
-       struct resource *bar_res;
        int bar_num;
 
-       for (bar_num = 0; bar_num <= PCI_ROM_RESOURCE; ++bar_num) {
-               bar_res = &dev->resource[bar_num];
+       for (bar_num = 0; bar_num <= PCI_ROM_RESOURCE; ++bar_num)
                iomm_table_allocate_entry(dev, bar_num);
-       }
 }
 
 /*
@@ -199,34 +155,7 @@ static void pci_Log_Error(char *Error_Text, int Bus, int SubBus,
 }
 
 /*
- * build_device_node(u16 Bus, int SubBus, u8 DevFn)
- */
-static struct device_node *build_device_node(HvBusNumber Bus,
-               HvSubBusNumber SubBus, int AgentId, int Function)
-{
-       struct device_node *node;
-       struct pci_dn *pdn;
-
-       node = kmalloc(sizeof(struct device_node), GFP_KERNEL);
-       if (node == NULL)
-               return NULL;
-       memset(node, 0, sizeof(struct device_node));
-       pdn = kzalloc(sizeof(*pdn), GFP_KERNEL);
-       if (pdn == NULL) {
-               kfree(node);
-               return NULL;
-       }
-       node->data = pdn;
-       pdn->node = node;
-       list_add_tail(&pdn->Device_List, &iSeries_Global_Device_List);
-       pdn->busno = Bus;
-       pdn->bussubno = SubBus;
-       pdn->devfn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function);
-       return node;
-}
-
-/*
- * unsigned long __init find_and_init_phbs(void)
+ * iSeries_pcibios_init
  *
  * Description:
  *   This function checks for all possible system PCI host bridges that connect
@@ -234,50 +163,42 @@ static struct device_node *build_device_node(HvBusNumber Bus,
  *   ownership status.  A pci_controller is built for any bus which is partially
  *   owned or fully owned by this guest partition.
  */
-unsigned long __init find_and_init_phbs(void)
+void iSeries_pcibios_init(void)
 {
        struct pci_controller *phb;
-       HvBusNumber bus;
-
-       /* Check all possible buses. */
-       for (bus = 0; bus < 256; bus++) {
-               int ret = HvCallXm_testBus(bus);
-               if (ret == 0) {
-                       printk("bus %d appears to exist\n", bus);
+       struct device_node *root = of_find_node_by_path("/");
+       struct device_node *node = NULL;
 
-                       phb = pcibios_alloc_controller(NULL);
-                       if (phb == NULL)
-                               return -ENOMEM;
-
-                       phb->pci_mem_offset = phb->local_number = bus;
-                       phb->first_busno = bus;
-                       phb->last_busno = bus;
-                       phb->ops = &iSeries_pci_ops;
-
-                       /* Find and connect the devices. */
-                       scan_PHB_slots(phb);
-               }
-               /*
-                * Check for Unexpected Return code, a clue that something
-                * has gone wrong.
-                */
-               else if (ret != 0x0301)
-                       printk(KERN_ERR "Unexpected Return on Probe(0x%04X): 0x%04X",
-                              bus, ret);
+       if (root == NULL) {
+               printk(KERN_CRIT "iSeries_pcibios_init: can't find root "
+                               "of device tree\n");
+               return;
+       }
+       while ((node = of_get_next_child(root, node)) != NULL) {
+               HvBusNumber bus;
+               u32 *busp;
+
+               if ((node->type == NULL) || (strcmp(node->type, "pci") != 0))
+                       continue;
+
+               busp = (u32 *)get_property(node, "bus-range", NULL);
+               if (busp == NULL)
+                       continue;
+               bus = *busp;
+               printk("bus %d appears to exist\n", bus);
+               phb = pcibios_alloc_controller(node);
+               if (phb == NULL)
+                       continue;
+
+               phb->pci_mem_offset = phb->local_number = bus;
+               phb->first_busno = bus;
+               phb->last_busno = bus;
+               phb->ops = &iSeries_pci_ops;
        }
-       return 0;
-}
 
-/*
- * iSeries_pcibios_init
- *
- * Chance to initialize and structures or variable before PCI Bus walk.
- */
-void iSeries_pcibios_init(void)
-{
-       iomm_table_initialize();
-       find_and_init_phbs();
-       io_page_mask = -1;
+       of_node_put(root);
+
+       pci_devs_phb_init();
 }
 
 /*
@@ -299,6 +220,34 @@ void __init iSeries_pci_final_fixup(void)
                       pdev->bus->number, pdev->devfn, node);
 
                if (node != NULL) {
+                       struct pci_dn *pdn = PCI_DN(node);
+                       u32 *agent;
+
+                       agent = (u32 *)get_property(node, "linux,agent-id",
+                                       NULL);
+                       if ((pdn != NULL) && (agent != NULL)) {
+                               u8 irq = iSeries_allocate_IRQ(pdn->busno, 0,
+                                               pdn->bussubno);
+                               int err;
+
+                               err = HvCallXm_connectBusUnit(pdn->busno, pdn->bussubno,
+                                               *agent, irq);
+                               if (err)
+                                       pci_Log_Error("Connect Bus Unit",
+                                               pdn->busno, pdn->bussubno, *agent, err);
+                               else {
+                                       err = HvCallPci_configStore8(pdn->busno, pdn->bussubno,
+                                                       *agent,
+                                                       PCI_INTERRUPT_LINE,
+                                                       irq);
+                                       if (err)
+                                               pci_Log_Error("PciCfgStore Irq Failed!",
+                                                       pdn->busno, pdn->bussubno, *agent, err);
+                               }
+                               if (!err)
+                                       pdev->irq = irq;
+                       }
+
                        ++DeviceCount;
                        pdev->sysdata = (void *)node;
                        PCI_DN(node)->pcidev = pdev;
@@ -308,7 +257,6 @@ void __init iSeries_pci_final_fixup(void)
                } else
                        printk("PCI: Device Tree not found for 0x%016lX\n",
                                        (unsigned long)pdev);
-               pdev->irq = PCI_DN(node)->Irq;
        }
        iSeries_activate_IRQs();
        mf_display_src(0xC9000200);
@@ -322,148 +270,6 @@ void pcibios_fixup_resources(struct pci_dev *pdev)
 {
 }
 
-/*
- * Loop through each node function to find usable EADs bridges.
- */
-static void scan_PHB_slots(struct pci_controller *Phb)
-{
-       struct HvCallPci_DeviceInfo *DevInfo;
-       HvBusNumber bus = Phb->local_number;    /* System Bus */
-       const HvSubBusNumber SubBus = 0;        /* EADs is always 0. */
-       int HvRc = 0;
-       int IdSel;
-       const int MaxAgents = 8;
-
-       DevInfo = (struct HvCallPci_DeviceInfo*)
-               kmalloc(sizeof(struct HvCallPci_DeviceInfo), GFP_KERNEL);
-       if (DevInfo == NULL)
-               return;
-
-       /*
-        * Probe for EADs Bridges
-        */
-       for (IdSel = 1; IdSel < MaxAgents; ++IdSel) {
-               HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel,
-                               iseries_hv_addr(DevInfo),
-                               sizeof(struct HvCallPci_DeviceInfo));
-               if (HvRc == 0) {
-                       if (DevInfo->deviceType == HvCallPci_NodeDevice)
-                               scan_EADS_bridge(bus, SubBus, IdSel);
-                       else
-                               printk("PCI: Invalid System Configuration(0x%02X)"
-                                      " for bus 0x%02x id 0x%02x.\n",
-                                      DevInfo->deviceType, bus, IdSel);
-               }
-               else
-                       pci_Log_Error("getDeviceInfo", bus, SubBus, IdSel, HvRc);
-       }
-       kfree(DevInfo);
-}
-
-static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus,
-               int IdSel)
-{
-       struct HvCallPci_BridgeInfo *BridgeInfo;
-       HvAgentId AgentId;
-       int Function;
-       int HvRc;
-
-       BridgeInfo = (struct HvCallPci_BridgeInfo *)
-               kmalloc(sizeof(struct HvCallPci_BridgeInfo), GFP_KERNEL);
-       if (BridgeInfo == NULL)
-               return;
-
-       /* Note: hvSubBus and irq is always be 0 at this level! */
-       for (Function = 0; Function < 8; ++Function) {
-               AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
-               HvRc = HvCallXm_connectBusUnit(bus, SubBus, AgentId, 0);
-               if (HvRc == 0) {
-                       printk("found device at bus %d idsel %d func %d (AgentId %x)\n",
-                              bus, IdSel, Function, AgentId);
-                       /*  Connect EADs: 0x18.00.12 = 0x00 */
-                       HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId,
-                                       iseries_hv_addr(BridgeInfo),
-                                       sizeof(struct HvCallPci_BridgeInfo));
-                       if (HvRc == 0) {
-                               printk("bridge info: type %x subbus %x maxAgents %x maxsubbus %x logslot %x\n",
-                                       BridgeInfo->busUnitInfo.deviceType,
-                                       BridgeInfo->subBusNumber,
-                                       BridgeInfo->maxAgents,
-                                       BridgeInfo->maxSubBusNumber,
-                                       BridgeInfo->logicalSlotNumber);
-                               if (BridgeInfo->busUnitInfo.deviceType ==
-                                               HvCallPci_BridgeDevice)  {
-                                       /* Scan_Bridge_Slot...: 0x18.00.12 */
-                                       scan_bridge_slot(bus, BridgeInfo);
-                               } else
-                                       printk("PCI: Invalid Bridge Configuration(0x%02X)",
-                                               BridgeInfo->busUnitInfo.deviceType);
-                       }
-               } else if (HvRc != 0x000B)
-                       pci_Log_Error("EADs Connect",
-                                       bus, SubBus, AgentId, HvRc);
-       }
-       kfree(BridgeInfo);
-}
-
-/*
- * This assumes that the node slot is always on the primary bus!
- */
-static int scan_bridge_slot(HvBusNumber Bus,
-               struct HvCallPci_BridgeInfo *BridgeInfo)
-{
-       struct device_node *node;
-       HvSubBusNumber SubBus = BridgeInfo->subBusNumber;
-       u16 VendorId = 0;
-       int HvRc = 0;
-       u8 Irq = 0;
-       int IdSel = ISERIES_GET_DEVICE_FROM_SUBBUS(SubBus);
-       int Function = ISERIES_GET_FUNCTION_FROM_SUBBUS(SubBus);
-       HvAgentId EADsIdSel = ISERIES_PCI_AGENTID(IdSel, Function);
-
-       /* iSeries_allocate_IRQ.: 0x18.00.12(0xA3) */
-       Irq = iSeries_allocate_IRQ(Bus, 0, EADsIdSel);
-
-       /*
-        * Connect all functions of any device found.
-        */
-       for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) {
-               for (Function = 0; Function < 8; ++Function) {
-                       HvAgentId AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
-                       HvRc = HvCallXm_connectBusUnit(Bus, SubBus,
-                                       AgentId, Irq);
-                       if (HvRc != 0) {
-                               pci_Log_Error("Connect Bus Unit",
-                                             Bus, SubBus, AgentId, HvRc);
-                               continue;
-                       }
-
-                       HvRc = HvCallPci_configLoad16(Bus, SubBus, AgentId,
-                                                     PCI_VENDOR_ID, &VendorId);
-                       if (HvRc != 0) {
-                               pci_Log_Error("Read Vendor",
-                                             Bus, SubBus, AgentId, HvRc);
-                               continue;
-                       }
-                       printk("read vendor ID: %x\n", VendorId);
-
-                       /* FoundDevice: 0x18.28.10 = 0x12AE */
-                       HvRc = HvCallPci_configStore8(Bus, SubBus, AgentId,
-                                                     PCI_INTERRUPT_LINE, Irq);
-                       if (HvRc != 0)
-                               pci_Log_Error("PciCfgStore Irq Failed!",
-                                             Bus, SubBus, AgentId, HvRc);
-
-                       ++DeviceCount;
-                       node = build_device_node(Bus, SubBus, EADsIdSel, Function);
-                       PCI_DN(node)->Irq = Irq;
-                       PCI_DN(node)->LogicalSlot = BridgeInfo->logicalSlotNumber;
-
-               } /* for (Function = 0; Function < 8; ++Function) */
-       } /* for (IdSel = 1; IdSel <= MaxAgents; ++IdSel) */
-       return HvRc;
-}
-
 /*
  * I/0 Memory copy MUST use mmio commands on iSeries
  * To do; For performance, include the hv call directly
@@ -509,11 +315,13 @@ EXPORT_SYMBOL(iSeries_memcpy_fromio);
  */
 static struct device_node *find_Device_Node(int bus, int devfn)
 {
-       struct pci_dn *pdn;
+       struct device_node *node;
+
+       for (node = NULL; (node = of_find_all_nodes(node)); ) {
+               struct pci_dn *pdn = PCI_DN(node);
 
-       list_for_each_entry(pdn, &iSeries_Global_Device_List, Device_List) {
-               if ((bus == pdn->busno) && (devfn == pdn->devfn))
-                       return pdn->node;
+               if (pdn && (bus == pdn->busno) && (devfn == pdn->devfn))
+                       return node;
        }
        return NULL;
 }
@@ -625,7 +433,6 @@ static int CheckReturnCode(char *TextHdr, struct device_node *DevNode,
        if (ret != 0)  {
                struct pci_dn *pdn = PCI_DN(DevNode);
 
-               ++Pci_Error_Count;
                (*retry)++;
                printk("PCI: %s: Device 0x%04X:%02X  I/O Error(%2d): 0x%04X\n",
                                TextHdr, pdn->busno, pdn->devfn,
@@ -707,7 +514,6 @@ u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
                return 0xff;
        }
        do {
-               ++Pci_Io_Read_Count;
                HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0);
        } while (CheckReturnCode("RDB", DevNode, &retry, ret.rc) != 0);
 
@@ -737,7 +543,6 @@ u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
                return 0xffff;
        }
        do {
-               ++Pci_Io_Read_Count;
                HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa,
                                BarOffset, 0);
        } while (CheckReturnCode("RDW", DevNode, &retry, ret.rc) != 0);
@@ -768,7 +573,6 @@ u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
                return 0xffffffff;
        }
        do {
-               ++Pci_Io_Read_Count;
                HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa,
                                BarOffset, 0);
        } while (CheckReturnCode("RDL", DevNode, &retry, ret.rc) != 0);
@@ -806,7 +610,6 @@ void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
                return;
        }
        do {
-               ++Pci_Io_Write_Count;
                rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0);
        } while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0);
 }
@@ -834,7 +637,6 @@ void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
                return;
        }
        do {
-               ++Pci_Io_Write_Count;
                rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0);
        } while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0);
 }
@@ -862,7 +664,6 @@ void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
                return;
        }
        do {
-               ++Pci_Io_Write_Count;
                rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0);
        } while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0);
 }
index a6fd9bedb0741b533fc207650a128ef1c35070ec..617c724c4590841df47f43e1512743db0d155f62 100644 (file)
@@ -50,7 +50,6 @@
 #include <asm/iseries/hv_call_xm.h>
 #include <asm/iseries/it_lp_queue.h>
 #include <asm/iseries/mf.h>
-#include <asm/iseries/it_exp_vpd_panel.h>
 #include <asm/iseries/hv_lp_event.h>
 #include <asm/iseries/lpar_map.h>
 #include <asm/udbg.h>
@@ -81,9 +80,6 @@ extern void iSeries_pci_final_fixup(void);
 static void iSeries_pci_final_fixup(void) { }
 #endif
 
-/* Global Variables */
-int piranha_simulator;
-
 extern int rd_size;            /* Defined in drivers/block/rd.c */
 extern unsigned long embedded_sysmap_start;
 extern unsigned long embedded_sysmap_end;
@@ -91,8 +87,6 @@ extern unsigned long embedded_sysmap_end;
 extern unsigned long iSeries_recal_tb;
 extern unsigned long iSeries_recal_titan;
 
-static unsigned long cmd_mem_limit;
-
 struct MemoryBlock {
        unsigned long absStart;
        unsigned long absEnd;
@@ -340,8 +334,6 @@ static void __init iSeries_init_early(void)
 #ifdef CONFIG_SMP
        smp_init_iSeries();
 #endif
-       if (itLpNaca.xPirEnvironMode == 0)
-               piranha_simulator = 1;
 
        /* Associate Lp Event Queue 0 with processor 0 */
        HvCallEvent_setLpEventQueueInterruptProc(0, 0);
@@ -536,10 +528,10 @@ static void __init iSeries_setup_arch(void)
 {
        if (get_lppaca()->shared_proc) {
                ppc_md.idle_loop = iseries_shared_idle;
-               printk(KERN_INFO "Using shared processor idle loop\n");
+               printk(KERN_DEBUG "Using shared processor idle loop\n");
        } else {
                ppc_md.idle_loop = iseries_dedicated_idle;
-               printk(KERN_INFO "Using dedicated idle loop\n");
+               printk(KERN_DEBUG "Using dedicated idle loop\n");
        }
 
        /* Setup the Lp Event Queue */
@@ -714,243 +706,6 @@ define_machine(iseries) {
        /* XXX Implement enable_pmcs for iSeries */
 };
 
-struct blob {
-       unsigned char data[PAGE_SIZE];
-       unsigned long next;
-};
-
-struct iseries_flat_dt {
-       struct boot_param_header header;
-       u64 reserve_map[2];
-       struct blob dt;
-       struct blob strings;
-};
-
-struct iseries_flat_dt iseries_dt;
-
-void dt_init(struct iseries_flat_dt *dt)
-{
-       dt->header.off_mem_rsvmap =
-               offsetof(struct iseries_flat_dt, reserve_map);
-       dt->header.off_dt_struct = offsetof(struct iseries_flat_dt, dt);
-       dt->header.off_dt_strings = offsetof(struct iseries_flat_dt, strings);
-       dt->header.totalsize = sizeof(struct iseries_flat_dt);
-       dt->header.dt_strings_size = sizeof(struct blob);
-
-       /* There is no notion of hardware cpu id on iSeries */
-       dt->header.boot_cpuid_phys = smp_processor_id();
-
-       dt->dt.next = (unsigned long)&dt->dt.data;
-       dt->strings.next = (unsigned long)&dt->strings.data;
-
-       dt->header.magic = OF_DT_HEADER;
-       dt->header.version = 0x10;
-       dt->header.last_comp_version = 0x10;
-
-       dt->reserve_map[0] = 0;
-       dt->reserve_map[1] = 0;
-}
-
-void dt_check_blob(struct blob *b)
-{
-       if (b->next >= (unsigned long)&b->next) {
-               DBG("Ran out of space in flat device tree blob!\n");
-               BUG();
-       }
-}
-
-void dt_push_u32(struct iseries_flat_dt *dt, u32 value)
-{
-       *((u32*)dt->dt.next) = value;
-       dt->dt.next += sizeof(u32);
-
-       dt_check_blob(&dt->dt);
-}
-
-void dt_push_u64(struct iseries_flat_dt *dt, u64 value)
-{
-       *((u64*)dt->dt.next) = value;
-       dt->dt.next += sizeof(u64);
-
-       dt_check_blob(&dt->dt);
-}
-
-unsigned long dt_push_bytes(struct blob *blob, char *data, int len)
-{
-       unsigned long start = blob->next - (unsigned long)blob->data;
-
-       memcpy((char *)blob->next, data, len);
-       blob->next = _ALIGN(blob->next + len, 4);
-
-       dt_check_blob(blob);
-
-       return start;
-}
-
-void dt_start_node(struct iseries_flat_dt *dt, char *name)
-{
-       dt_push_u32(dt, OF_DT_BEGIN_NODE);
-       dt_push_bytes(&dt->dt, name, strlen(name) + 1);
-}
-
-#define dt_end_node(dt) dt_push_u32(dt, OF_DT_END_NODE)
-
-void dt_prop(struct iseries_flat_dt *dt, char *name, char *data, int len)
-{
-       unsigned long offset;
-
-       dt_push_u32(dt, OF_DT_PROP);
-
-       /* Length of the data */
-       dt_push_u32(dt, len);
-
-       /* Put the property name in the string blob. */
-       offset = dt_push_bytes(&dt->strings, name, strlen(name) + 1);
-
-       /* The offset of the properties name in the string blob. */
-       dt_push_u32(dt, (u32)offset);
-
-       /* The actual data. */
-       dt_push_bytes(&dt->dt, data, len);
-}
-
-void dt_prop_str(struct iseries_flat_dt *dt, char *name, char *data)
-{
-       dt_prop(dt, name, data, strlen(data) + 1); /* + 1 for NULL */
-}
-
-void dt_prop_u32(struct iseries_flat_dt *dt, char *name, u32 data)
-{
-       dt_prop(dt, name, (char *)&data, sizeof(u32));
-}
-
-void dt_prop_u64(struct iseries_flat_dt *dt, char *name, u64 data)
-{
-       dt_prop(dt, name, (char *)&data, sizeof(u64));
-}
-
-void dt_prop_u64_list(struct iseries_flat_dt *dt, char *name, u64 *data, int n)
-{
-       dt_prop(dt, name, (char *)data, sizeof(u64) * n);
-}
-
-void dt_prop_u32_list(struct iseries_flat_dt *dt, char *name, u32 *data, int n)
-{
-       dt_prop(dt, name, (char *)data, sizeof(u32) * n);
-}
-
-void dt_prop_empty(struct iseries_flat_dt *dt, char *name)
-{
-       dt_prop(dt, name, NULL, 0);
-}
-
-void dt_cpus(struct iseries_flat_dt *dt)
-{
-       unsigned char buf[32];
-       unsigned char *p;
-       unsigned int i, index;
-       struct IoHriProcessorVpd *d;
-       u32 pft_size[2];
-
-       /* yuck */
-       snprintf(buf, 32, "PowerPC,%s", cur_cpu_spec->cpu_name);
-       p = strchr(buf, ' ');
-       if (!p) p = buf + strlen(buf);
-
-       dt_start_node(dt, "cpus");
-       dt_prop_u32(dt, "#address-cells", 1);
-       dt_prop_u32(dt, "#size-cells", 0);
-
-       pft_size[0] = 0; /* NUMA CEC cookie, 0 for non NUMA  */
-       pft_size[1] = __ilog2(HvCallHpt_getHptPages() * HW_PAGE_SIZE);
-
-       for (i = 0; i < NR_CPUS; i++) {
-               if (lppaca[i].dyn_proc_status >= 2)
-                       continue;
-
-               snprintf(p, 32 - (p - buf), "@%d", i);
-               dt_start_node(dt, buf);
-
-               dt_prop_str(dt, "device_type", "cpu");
-
-               index = lppaca[i].dyn_hv_phys_proc_index;
-               d = &xIoHriProcessorVpd[index];
-
-               dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024);
-               dt_prop_u32(dt, "i-cache-line-size", d->xInstCacheOperandSize);
-
-               dt_prop_u32(dt, "d-cache-size", d->xDataL1CacheSizeKB * 1024);
-               dt_prop_u32(dt, "d-cache-line-size", d->xDataCacheOperandSize);
-
-               /* magic conversions to Hz copied from old code */
-               dt_prop_u32(dt, "clock-frequency",
-                       ((1UL << 34) * 1000000) / d->xProcFreq);
-               dt_prop_u32(dt, "timebase-frequency",
-                       ((1UL << 32) * 1000000) / d->xTimeBaseFreq);
-
-               dt_prop_u32(dt, "reg", i);
-
-               dt_prop_u32_list(dt, "ibm,pft-size", pft_size, 2);
-
-               dt_end_node(dt);
-       }
-
-       dt_end_node(dt);
-}
-
-void dt_model(struct iseries_flat_dt *dt)
-{
-       char buf[16] = "IBM,";
-
-       /* "IBM," + mfgId[2:3] + systemSerial[1:5] */
-       strne2a(buf + 4, xItExtVpdPanel.mfgID + 2, 2);
-       strne2a(buf + 6, xItExtVpdPanel.systemSerial + 1, 5);
-       buf[11] = '\0';
-       dt_prop_str(dt, "system-id", buf);
-
-       /* "IBM," + machineType[0:4] */
-       strne2a(buf + 4, xItExtVpdPanel.machineType, 4);
-       buf[8] = '\0';
-       dt_prop_str(dt, "model", buf);
-
-       dt_prop_str(dt, "compatible", "IBM,iSeries");
-}
-
-void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size)
-{
-       u64 tmp[2];
-
-       dt_init(dt);
-
-       dt_start_node(dt, "");
-
-       dt_prop_u32(dt, "#address-cells", 2);
-       dt_prop_u32(dt, "#size-cells", 2);
-       dt_model(dt);
-
-       /* /memory */
-       dt_start_node(dt, "memory@0");
-       dt_prop_str(dt, "name", "memory");
-       dt_prop_str(dt, "device_type", "memory");
-       tmp[0] = 0;
-       tmp[1] = phys_mem_size;
-       dt_prop_u64_list(dt, "reg", tmp, 2);
-       dt_end_node(dt);
-
-       /* /chosen */
-       dt_start_node(dt, "chosen");
-       dt_prop_str(dt, "bootargs", cmd_line);
-       if (cmd_mem_limit)
-               dt_prop_u64(dt, "linux,memory-limit", cmd_mem_limit);
-       dt_end_node(dt);
-
-       dt_cpus(dt);
-
-       dt_end_node(dt);
-
-       dt_push_u32(dt, OF_DT_END);
-}
-
 void * __init iSeries_early_setup(void)
 {
        unsigned long phys_mem_size;
@@ -965,28 +720,8 @@ void * __init iSeries_early_setup(void)
 
        iSeries_get_cmdline();
 
-       /* Save unparsed command line copy for /proc/cmdline */
-       strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
-
-       /* Parse early parameters, in particular mem=x */
-       parse_early_param();
-
-       build_flat_dt(&iseries_dt, phys_mem_size);
-
-       return (void *) __pa(&iseries_dt);
-}
-
-/*
- * On iSeries we just parse the mem=X option from the command line.
- * On pSeries it's a bit more complicated, see prom_init_mem()
- */
-static int __init early_parsemem(char *p)
-{
-       if (p)
-               cmd_mem_limit = ALIGN(memparse(p, &p), PAGE_SIZE);
-       return 0;
+       return (void *) __pa(build_flat_dt(phys_mem_size));
 }
-early_param("mem", early_parsemem);
 
 static void hvputc(char c)
 {
index 5213044ec4117b3dcf76f16547076b4a1ea9a71b..0a47ac53c95970a0fbf958410829c0a2cc97d9e3 100644 (file)
@@ -21,4 +21,6 @@ extern unsigned long iSeries_get_boot_time(void);
 extern int iSeries_set_rtc_time(struct rtc_time *tm);
 extern void iSeries_get_rtc_time(struct rtc_time *tm);
 
+extern void *build_flat_dt(unsigned long phys_mem_size);
+
 #endif /* __ISERIES_SETUP_H__ */
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
deleted file mode 100644 (file)
index ad36ab0..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * IBM PowerPC iSeries Virtual I/O Infrastructure Support.
- *
- *    Copyright (c) 2005 Stephen Rothwell, IBM Corp.
- *
- *      This program is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU General Public License
- *      as published by the Free Software Foundation; either version
- *      2 of the License, or (at your option) any later version.
- */
-#include <linux/types.h>
-#include <linux/device.h>
-#include <linux/init.h>
-
-#include <asm/vio.h>
-#include <asm/iommu.h>
-#include <asm/tce.h>
-#include <asm/abs_addr.h>
-#include <asm/page.h>
-#include <asm/iseries/vio.h>
-#include <asm/iseries/hv_types.h>
-#include <asm/iseries/hv_lp_config.h>
-#include <asm/iseries/hv_call_xm.h>
-
-#include "iommu.h"
-
-struct device *iSeries_vio_dev = &vio_bus_device.dev;
-EXPORT_SYMBOL(iSeries_vio_dev);
-
-static struct iommu_table veth_iommu_table;
-static struct iommu_table vio_iommu_table;
-
-static void __init iommu_vio_init(void)
-{
-       iommu_table_getparms_iSeries(255, 0, 0xff, &veth_iommu_table);
-       veth_iommu_table.it_size /= 2;
-       vio_iommu_table = veth_iommu_table;
-       vio_iommu_table.it_offset += veth_iommu_table.it_size;
-
-       if (!iommu_init_table(&veth_iommu_table))
-               printk("Virtual Bus VETH TCE table failed.\n");
-       if (!iommu_init_table(&vio_iommu_table))
-               printk("Virtual Bus VIO TCE table failed.\n");
-}
-
-/**
- * vio_register_device_iseries: - Register a new iSeries vio device.
- * @voidev:    The device to register.
- */
-static struct vio_dev *__init vio_register_device_iseries(char *type,
-               uint32_t unit_num)
-{
-       struct vio_dev *viodev;
-
-       /* allocate a vio_dev for this device */
-       viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL);
-       if (!viodev)
-               return NULL;
-       memset(viodev, 0, sizeof(struct vio_dev));
-
-       snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%s%d", type, unit_num);
-
-       viodev->name = viodev->dev.bus_id;
-       viodev->type = type;
-       viodev->unit_address = unit_num;
-       viodev->iommu_table = &vio_iommu_table;
-       if (vio_register_device(viodev) == NULL) {
-               kfree(viodev);
-               return NULL;
-       }
-       return viodev;
-}
-
-void __init probe_bus_iseries(void)
-{
-       HvLpIndexMap vlan_map;
-       struct vio_dev *viodev;
-       int i;
-
-       /* there is only one of each of these */
-       vio_register_device_iseries("viocons", 0);
-       vio_register_device_iseries("vscsi", 0);
-
-       vlan_map = HvLpConfig_getVirtualLanIndexMap();
-       for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) {
-               if ((vlan_map & (0x8000 >> i)) == 0)
-                       continue;
-               viodev = vio_register_device_iseries("vlan", i);
-               /* veth is special and has it own iommu_table */
-               viodev->iommu_table = &veth_iommu_table;
-       }
-       for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++)
-               vio_register_device_iseries("viodasd", i);
-       for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++)
-               vio_register_device_iseries("viocd", i);
-       for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++)
-               vio_register_device_iseries("viotape", i);
-}
-
-/**
- * vio_match_device_iseries: - Tell if a iSeries VIO device matches a
- *     vio_device_id
- */
-static int vio_match_device_iseries(const struct vio_device_id *id,
-               const struct vio_dev *dev)
-{
-       return strncmp(dev->type, id->type, strlen(id->type)) == 0;
-}
-
-static struct vio_bus_ops vio_bus_ops_iseries = {
-       .match = vio_match_device_iseries,
-};
-
-/**
- * vio_bus_init_iseries: - Initialize the iSeries virtual IO bus
- */
-static int __init vio_bus_init_iseries(void)
-{
-       int err;
-
-       err = vio_bus_init(&vio_bus_ops_iseries);
-       if (err == 0) {
-               iommu_vio_init();
-               vio_bus_device.iommu_table = &vio_iommu_table;
-               iSeries_vio_dev = &vio_bus_device.dev;
-               probe_bus_iseries();
-       }
-       return err;
-}
-
-__initcall(vio_bus_init_iseries);
index 85d6c93659cc1d8e8ca2ca2cd7a224b2a9a1e3cc..9a4efc0c3b2932f025275287f9c42f4f94f30ad9 100644 (file)
@@ -437,9 +437,6 @@ void __init maple_pci_init(void)
 
        /* Tell pci.c to not change any resource allocations.  */
        pci_probe_only = 1;
-       
-       /* Allow all IO */
-       io_page_mask = -1;
 }
 
 int maple_pci_get_legacy_ide_irq(struct pci_dev *pdev, int channel)
index 24c0aef4ea39b8497e6a5377f85f911085e67524..a0505ea48a86ca75343206829d06fb0e361920c6 100644 (file)
@@ -189,7 +189,7 @@ void __init maple_setup_arch(void)
        conswitchp = &dummy_con;
 #endif
 
-       printk(KERN_INFO "Using native/NAP idle loop\n");
+       printk(KERN_DEBUG "Using native/NAP idle loop\n");
 }
 
 /* 
index cfd6527a0d7e0799ec140bb5688481b2322112f7..af2a8f9f122214328d7733ddbe6ef80179a645ef 100644 (file)
@@ -314,7 +314,7 @@ static int pmu_set_cpu_speed(int low_speed)
                _set_L3CR(save_l3cr);
 
        /* Restore userland MMU context */
-       set_context(current->active_mm->context, current->active_mm->pgd);
+       set_context(current->active_mm->context.id, current->active_mm->pgd);
 
 #ifdef DEBUG_FREQ
        printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));
index a5063cd675c58623244528006d96d30717a07afb..85e00cb0006ea47c400b28141dcc33b37625e529 100644 (file)
@@ -2510,7 +2510,7 @@ found:
                if (get_property(np, "flush-on-lock", NULL))
                        break;
                powersave_nap = 1;
-               printk(KERN_INFO "Processor NAP mode on idle enabled.\n");
+               printk(KERN_DEBUG "Processor NAP mode on idle enabled.\n");
                break;
        }
 
index ea179afea632724811e081f0d423c287c2f0e494..80035853467b000fa1517920762b8bc1bfdfef8b 100644 (file)
@@ -1068,9 +1068,6 @@ void __init pmac_pci_init(void)
        /* Tell pci.c to not use the common resource allocation mechanism */
        pci_probe_only = 1;
 
-       /* Allow all IO */
-       io_page_mask = -1;
-
 #else /* CONFIG_PPC64 */
        init_p2pbridge();
        fixup_nec_usb2();
index b9200fb078157f3498e16f4be98e92a5b8d8194d..9cc7db7a8bdc443a1da0af1cb4adf34ad7b462af 100644 (file)
@@ -458,7 +458,7 @@ static int pmac_pm_finish(suspend_state_t state)
        printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
 
        /* Restore userland MMU context */
-       set_context(current->active_mm->context, current->active_mm->pgd);
+       set_context(current->active_mm->context.id, current->active_mm->pgd);
 
        return 0;
 }
index 930898635c9ffa2c25d6d8afb04221768f36ce43..b46ce3b9bb3c4f7cd2cbe9caf77ab74b96518f3a 100644 (file)
@@ -2,7 +2,6 @@ obj-y                   := pci.o lpar.o hvCall.o nvram.o reconfig.o \
                           setup.o iommu.o ras.o rtasd.o pci_dlpar.o \
                           firmware.o
 obj-$(CONFIG_SMP)      += smp.o
-obj-$(CONFIG_IBMVIO)   += vio.o
 obj-$(CONFIG_XICS)     += xics.o
 obj-$(CONFIG_SCANLOG)  += scanlog.o
 obj-$(CONFIG_EEH)      += eeh.o eeh_cache.o eeh_driver.o eeh_event.o
index 1fba695e32e82d113cbfcab42e18cfc69ae0da62..4d45347afabc74a782c10037dee8308a92faf3ca 100644 (file)
@@ -23,9 +23,8 @@
  *
  */
 #include <linux/delay.h>
-#include <linux/irq.h>
 #include <linux/interrupt.h>
-#include <linux/notifier.h>
+#include <linux/irq.h>
 #include <linux/pci.h>
 #include <asm/eeh.h>
 #include <asm/eeh_event.h>
@@ -202,7 +201,11 @@ static void eeh_report_failure(struct pci_dev *dev, void *userdata)
 
 static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)
 {
-       int rc;
+       int cnt, rc;
+
+       /* pcibios will clear the counter; save the value */
+       cnt = pe_dn->eeh_freeze_count;
+
        if (bus)
                pcibios_remove_pci_devices(bus);
 
@@ -241,6 +244,7 @@ static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)
                ssleep (5);
                pcibios_add_pci_devices(bus);
        }
+       pe_dn->eeh_freeze_count = cnt;
 
        return 0;
 }
@@ -250,7 +254,7 @@ static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)
  */
 #define MAX_WAIT_FOR_RECOVERY 15
 
-void handle_eeh_events (struct eeh_event *event)
+struct pci_dn * handle_eeh_events (struct eeh_event *event)
 {
        struct device_node *frozen_dn;
        struct pci_dn *frozen_pdn;
@@ -265,7 +269,7 @@ void handle_eeh_events (struct eeh_event *event)
        if (!frozen_dn) {
                printk(KERN_ERR "EEH: Error: Cannot find partition endpoint for %s\n",
                        pci_name(event->dev));
-               return;
+               return NULL;
        }
 
        /* There are two different styles for coming up with the PE.
@@ -280,7 +284,7 @@ void handle_eeh_events (struct eeh_event *event)
        if (!frozen_bus) {
                printk(KERN_ERR "EEH: Cannot find PCI bus for %s\n",
                        frozen_dn->full_name);
-               return;
+               return NULL;
        }
 
 #if 0
@@ -355,7 +359,7 @@ void handle_eeh_events (struct eeh_event *event)
        /* Tell all device drivers that they can resume operations */
        pci_walk_bus(frozen_bus, eeh_report_resume, NULL);
 
-       return;
+       return frozen_pdn;
        
 excess_failures:
        /*
@@ -384,6 +388,8 @@ perm_error:
 
        /* Shut down the device drivers for good. */
        pcibios_remove_pci_devices(frozen_bus);
+
+       return NULL;
 }
 
 /* ---------- end of file ---------- */
index 40020c65c89e4da0e2365fac47316593ee712c12..8f2d12935b99fe47de2a273ad4b12338fbcb5f4f 100644 (file)
@@ -18,6 +18,7 @@
  * Copyright (c) 2005 Linas Vepstas <linas@linas.org>
  */
 
+#include <linux/delay.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
 #include <linux/pci.h>
@@ -56,38 +57,43 @@ static int eeh_event_handler(void * dummy)
 {
        unsigned long flags;
        struct eeh_event        *event;
+       struct pci_dn *pdn;
 
        daemonize ("eehd");
+       set_current_state(TASK_INTERRUPTIBLE);
 
-       while (1) {
-               set_current_state(TASK_INTERRUPTIBLE);
+       spin_lock_irqsave(&eeh_eventlist_lock, flags);
+       event = NULL;
 
-               spin_lock_irqsave(&eeh_eventlist_lock, flags);
-               event = NULL;
+       /* Unqueue the event, get ready to process. */
+       if (!list_empty(&eeh_eventlist)) {
+               event = list_entry(eeh_eventlist.next, struct eeh_event, list);
+               list_del(&event->list);
+       }
+       spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
 
-               /* Unqueue the event, get ready to process. */
-               if (!list_empty(&eeh_eventlist)) {
-                       event = list_entry(eeh_eventlist.next, struct eeh_event, list);
-                       list_del(&event->list);
-               }
-               spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
+       if (event == NULL)
+               return 0;
 
-               if (event == NULL)
-                       break;
+       /* Serialize processing of EEH events */
+       mutex_lock(&eeh_event_mutex);
+       eeh_mark_slot(event->dn, EEH_MODE_RECOVERING);
 
-               /* Serialize processing of EEH events */
-               mutex_lock(&eeh_event_mutex);
-               eeh_mark_slot(event->dn, EEH_MODE_RECOVERING);
+       printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n",
+              pci_name(event->dev));
 
-               printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n",
-                      pci_name(event->dev));
+       pdn = handle_eeh_events(event);
 
-               handle_eeh_events(event);
+       eeh_clear_slot(event->dn, EEH_MODE_RECOVERING);
+       pci_dev_put(event->dev);
+       kfree(event);
+       mutex_unlock(&eeh_event_mutex);
 
-               eeh_clear_slot(event->dn, EEH_MODE_RECOVERING);
-               pci_dev_put(event->dev);
-               kfree(event);
-               mutex_unlock(&eeh_event_mutex);
+       /* If there are no new errors after an hour, clear the counter. */
+       if (pdn && pdn->eeh_freeze_count>0) {
+               msleep_interruptible (3600*1000);
+               if (pdn->eeh_freeze_count>0)
+                       pdn->eeh_freeze_count--;
        }
 
        return 0;
index 2643078433f0123f8997c7f98823934e7b1feadb..44a507e6fb342dc1e616923450ec2778a960a849 100644 (file)
@@ -1,23 +1,24 @@
 /*
  * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
  *
- * Rewrite, cleanup: 
+ * Rewrite, cleanup:
  *
  * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation
+ * Copyright (C) 2006 Olof Johansson <olof@lixom.net>
  *
  * Dynamic DMA mapping support, pSeries-specific parts, both SMP and LPAR.
  *
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 
 #define DBG(fmt...)
 
-static void tce_build_pSeries(struct iommu_table *tbl, long index, 
-                             long npages, unsigned long uaddr, 
+static void tce_build_pSeries(struct iommu_table *tbl, long index,
+                             long npages, unsigned long uaddr,
                              enum dma_data_direction direction)
 {
-       union tce_entry t;
-       union tce_entry *tp;
+       u64 proto_tce;
+       u64 *tcep;
+       u64 rpn;
 
        index <<= TCE_PAGE_FACTOR;
        npages <<= TCE_PAGE_FACTOR;
 
-       t.te_word = 0;
-       t.te_rdwr = 1; // Read allowed 
+       proto_tce = TCE_PCI_READ; // Read allowed
 
        if (direction != DMA_TO_DEVICE)
-               t.te_pciwr = 1;
+               proto_tce |= TCE_PCI_WRITE;
 
-       tp = ((union tce_entry *)tbl->it_base) + index;
+       tcep = ((u64 *)tbl->it_base) + index;
 
        while (npages--) {
                /* can't move this out since we might cross LMB boundary */
-               t.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
-       
-               tp->te_word = t.te_word;
+               rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
+               *tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
 
                uaddr += TCE_PAGE_SIZE;
-               tp++;
+               tcep++;
        }
 }
 
 
 static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages)
 {
-       union tce_entry t;
-       union tce_entry *tp;
+       u64 *tcep;
 
        npages <<= TCE_PAGE_FACTOR;
        index <<= TCE_PAGE_FACTOR;
 
-       t.te_word = 0;
-       tp  = ((union tce_entry *)tbl->it_base) + index;
-               
-       while (npages--) {
-               tp->te_word = t.te_word;
-               
-               tp++;
-       }
+       tcep = ((u64 *)tbl->it_base) + index;
+
+       while (npages--)
+               *(tcep++) = 0;
 }
 
 
@@ -103,43 +98,44 @@ static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
                                enum dma_data_direction direction)
 {
        u64 rc;
-       union tce_entry tce;
+       u64 proto_tce, tce;
+       u64 rpn;
 
        tcenum <<= TCE_PAGE_FACTOR;
        npages <<= TCE_PAGE_FACTOR;
 
-       tce.te_word = 0;
-       tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
-       tce.te_rdwr = 1;
+       rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
+       proto_tce = TCE_PCI_READ;
        if (direction != DMA_TO_DEVICE)
-               tce.te_pciwr = 1;
+               proto_tce |= TCE_PCI_WRITE;
 
        while (npages--) {
-               rc = plpar_tce_put((u64)tbl->it_index, 
-                                  (u64)tcenum << 12, 
-                                  tce.te_word );
-               
+               tce = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
+               rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, tce);
+
                if (rc && printk_ratelimit()) {
                        printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc);
                        printk("\tindex   = 0x%lx\n", (u64)tbl->it_index);
                        printk("\ttcenum  = 0x%lx\n", (u64)tcenum);
-                       printk("\ttce val = 0x%lx\n", tce.te_word );
+                       printk("\ttce val = 0x%lx\n", tce );
                        show_stack(current, (unsigned long *)__get_SP());
                }
-                       
+
                tcenum++;
-               tce.te_rpn++;
+               rpn++;
        }
 }
 
-static DEFINE_PER_CPU(void *, tce_page) = NULL;
+static DEFINE_PER_CPU(u64 *, tce_page) = NULL;
 
 static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
                                     long npages, unsigned long uaddr,
                                     enum dma_data_direction direction)
 {
        u64 rc;
-       union tce_entry tce, *tcep;
+       u64 proto_tce;
+       u64 *tcep;
+       u64 rpn;
        long l, limit;
 
        if (TCE_PAGE_FACTOR == 0 && npages == 1)
@@ -152,7 +148,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
         * from iommu_alloc{,_sg}()
         */
        if (!tcep) {
-               tcep = (void *)__get_free_page(GFP_ATOMIC);
+               tcep = (u64 *)__get_free_page(GFP_ATOMIC);
                /* If allocation fails, fall back to the loop implementation */
                if (!tcep)
                        return tce_build_pSeriesLP(tbl, tcenum, npages,
@@ -163,11 +159,10 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
        tcenum <<= TCE_PAGE_FACTOR;
        npages <<= TCE_PAGE_FACTOR;
 
-       tce.te_word = 0;
-       tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
-       tce.te_rdwr = 1;
+       rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
+       proto_tce = TCE_PCI_READ;
        if (direction != DMA_TO_DEVICE)
-               tce.te_pciwr = 1;
+               proto_tce |= TCE_PCI_WRITE;
 
        /* We can map max one pageful of TCEs at a time */
        do {
@@ -175,11 +170,11 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
                 * Set up the page with TCE data, looping through and setting
                 * the values.
                 */
-               limit = min_t(long, npages, 4096/sizeof(union tce_entry));
+               limit = min_t(long, npages, 4096/TCE_ENTRY_SIZE);
 
                for (l = 0; l < limit; l++) {
-                       tcep[l] = tce;
-                       tce.te_rpn++;
+                       tcep[l] = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
+                       rpn++;
                }
 
                rc = plpar_tce_put_indirect((u64)tbl->it_index,
@@ -195,7 +190,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
                printk("tce_buildmulti_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc);
                printk("\tindex   = 0x%lx\n", (u64)tbl->it_index);
                printk("\tnpages  = 0x%lx\n", (u64)npages);
-               printk("\ttce[0] val = 0x%lx\n", tcep[0].te_word);
+               printk("\ttce[0] val = 0x%lx\n", tcep[0]);
                show_stack(current, (unsigned long *)__get_SP());
        }
 }
@@ -203,23 +198,17 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
 static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages)
 {
        u64 rc;
-       union tce_entry tce;
 
        tcenum <<= TCE_PAGE_FACTOR;
        npages <<= TCE_PAGE_FACTOR;
 
-       tce.te_word = 0;
-
        while (npages--) {
-               rc = plpar_tce_put((u64)tbl->it_index,
-                                  (u64)tcenum << 12,
-                                  tce.te_word);
+               rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0);
 
                if (rc && printk_ratelimit()) {
                        printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc);
                        printk("\tindex   = 0x%lx\n", (u64)tbl->it_index);
                        printk("\ttcenum  = 0x%lx\n", (u64)tcenum);
-                       printk("\ttce val = 0x%lx\n", tce.te_word );
                        show_stack(current, (unsigned long *)__get_SP());
                }
 
@@ -231,31 +220,24 @@ static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages
 static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages)
 {
        u64 rc;
-       union tce_entry tce;
 
        tcenum <<= TCE_PAGE_FACTOR;
        npages <<= TCE_PAGE_FACTOR;
 
-       tce.te_word = 0;
-
-       rc = plpar_tce_stuff((u64)tbl->it_index,
-                          (u64)tcenum << 12,
-                          tce.te_word,
-                          npages);
+       rc = plpar_tce_stuff((u64)tbl->it_index, (u64)tcenum << 12, 0, npages);
 
        if (rc && printk_ratelimit()) {
                printk("tce_freemulti_pSeriesLP: plpar_tce_stuff failed\n");
                printk("\trc      = %ld\n", rc);
                printk("\tindex   = 0x%lx\n", (u64)tbl->it_index);
                printk("\tnpages  = 0x%lx\n", (u64)npages);
-               printk("\ttce val = 0x%lx\n", tce.te_word );
                show_stack(current, (unsigned long *)__get_SP());
        }
 }
 
 static void iommu_table_setparms(struct pci_controller *phb,
                                 struct device_node *dn,
-                                struct iommu_table *tbl) 
+                                struct iommu_table *tbl)
 {
        struct device_node *node;
        unsigned long *basep;
@@ -275,16 +257,16 @@ static void iommu_table_setparms(struct pci_controller *phb,
        memset((void *)tbl->it_base, 0, *sizep);
 
        tbl->it_busno = phb->bus->number;
-       
+
        /* Units of tce entries */
        tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT;
-       
+
        /* Test if we are going over 2GB of DMA space */
        if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) {
                udbg_printf("PCI_DMA: Unexpected number of IOAs under this PHB.\n");
-               panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); 
+               panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n");
        }
-       
+
        phb->dma_window_base_cur += phb->dma_window_size;
 
        /* Set the tce table size - measured in entries */
@@ -299,30 +281,22 @@ static void iommu_table_setparms(struct pci_controller *phb,
  * iommu_table_setparms_lpar
  *
  * Function: On pSeries LPAR systems, return TCE table info, given a pci bus.
- *
- * ToDo: properly interpret the ibm,dma-window property.  The definition is:
- *     logical-bus-number      (1 word)
- *     phys-address            (#address-cells words)
- *     size                    (#cell-size words)
- *
- * Currently we hard code these sizes (more or less).
  */
 static void iommu_table_setparms_lpar(struct pci_controller *phb,
                                      struct device_node *dn,
                                      struct iommu_table *tbl,
-                                     unsigned int *dma_window)
+                                     unsigned char *dma_window)
 {
+       unsigned long offset, size;
+
        tbl->it_busno  = PCI_DN(dn)->bussubno;
+       of_parse_dma_window(dn, dma_window, &tbl->it_index, &offset, &size);
 
-       /* TODO: Parse field size properties properly. */
-       tbl->it_size   = (((unsigned long)dma_window[4] << 32) |
-                          (unsigned long)dma_window[5]) >> PAGE_SHIFT;
-       tbl->it_offset = (((unsigned long)dma_window[2] << 32) |
-                          (unsigned long)dma_window[3]) >> PAGE_SHIFT;
        tbl->it_base   = 0;
-       tbl->it_index  = dma_window[0];
        tbl->it_blocksize  = 16;
        tbl->it_type = TCE_PCI;
+       tbl->it_offset = offset >> PAGE_SHIFT;
+       tbl->it_size = size >> PAGE_SHIFT;
 }
 
 static void iommu_bus_setup_pSeries(struct pci_bus *bus)
@@ -414,7 +388,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
        struct iommu_table *tbl;
        struct device_node *dn, *pdn;
        struct pci_dn *ppci;
-       unsigned int *dma_window = NULL;
+       unsigned char *dma_window = NULL;
 
        DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self);
 
@@ -422,7 +396,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
 
        /* Find nearest ibm,dma-window, walking up the device tree */
        for (pdn = dn; pdn != NULL; pdn = pdn->parent) {
-               dma_window = (unsigned int *)get_property(pdn, "ibm,dma-window", NULL);
+               dma_window = get_property(pdn, "ibm,dma-window", NULL);
                if (dma_window != NULL)
                        break;
        }
@@ -442,7 +416,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
 
                tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table),
                                                    GFP_KERNEL);
-       
+
                iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window);
 
                ppci->iommu_table = iommu_init_table(tbl);
@@ -516,7 +490,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
 {
        struct device_node *pdn, *dn;
        struct iommu_table *tbl;
-       int *dma_window = NULL;
+       unsigned char *dma_window = NULL;
        struct pci_dn *pci;
 
        DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev));
@@ -531,8 +505,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
 
        for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table;
             pdn = pdn->parent) {
-               dma_window = (unsigned int *)
-                       get_property(pdn, "ibm,dma-window", NULL);
+               dma_window = get_property(pdn, "ibm,dma-window", NULL);
                if (dma_window)
                        break;
        }
index e0000ce769e51831db5df3fe82f25d57384c1e16..2e4e04042d85705f9700de82ba8aabe001e8239c 100644 (file)
@@ -348,7 +348,7 @@ static int enable_surveillance(int timeout)
                return 0;
 
        if (error == -EINVAL) {
-               printk(KERN_INFO "rtasd: surveillance not supported\n");
+               printk(KERN_DEBUG "rtasd: surveillance not supported\n");
                return 0;
        }
 
@@ -440,7 +440,7 @@ static int rtasd(void *unused)
                goto error;
        }
 
-       printk(KERN_INFO "RTAS daemon started\n");
+       printk(KERN_DEBUG "RTAS daemon started\n");
 
        DEBUG("will sleep for %d milliseconds\n", (30000/rtas_event_scan_rate));
 
@@ -487,7 +487,7 @@ static int __init rtas_init(void)
 
        /* No RTAS */
        if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) {
-               printk(KERN_INFO "rtasd: no event-scan on system\n");
+               printk(KERN_DEBUG "rtasd: no event-scan on system\n");
                return -ENODEV;
        }
 
index 3ba87835757e2cfd5319d54e6992dd2d313488e7..1e28518c6121f7431526b75501ff15aa3d9e0ef4 100644 (file)
@@ -235,14 +235,14 @@ static void __init pSeries_setup_arch(void)
        if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
                vpa_init(boot_cpuid);
                if (get_lppaca()->shared_proc) {
-                       printk(KERN_INFO "Using shared processor idle loop\n");
+                       printk(KERN_DEBUG "Using shared processor idle loop\n");
                        ppc_md.power_save = pseries_shared_idle_sleep;
                } else {
-                       printk(KERN_INFO "Using dedicated idle loop\n");
+                       printk(KERN_DEBUG "Using dedicated idle loop\n");
                        ppc_md.power_save = pseries_dedicated_idle_sleep;
                }
        } else {
-               printk(KERN_INFO "Using default idle loop\n");
+               printk(KERN_DEBUG "Using default idle loop\n");
        }
 
        if (firmware_has_feature(FW_FEATURE_LPAR))
diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c
deleted file mode 100644 (file)
index 8e53e04..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * IBM PowerPC pSeries Virtual I/O Infrastructure Support.
- *
- *    Copyright (c) 2003-2005 IBM Corp.
- *     Dave Engebretsen engebret@us.ibm.com
- *     Santiago Leon santil@us.ibm.com
- *     Hollis Blanchard <hollisb@us.ibm.com>
- *     Stephen Rothwell
- *
- *      This program is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU General Public License
- *      as published by the Free Software Foundation; either version
- *      2 of the License, or (at your option) any later version.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/kobject.h>
-#include <asm/iommu.h>
-#include <asm/dma.h>
-#include <asm/prom.h>
-#include <asm/vio.h>
-#include <asm/hvcall.h>
-#include <asm/tce.h>
-
-extern struct subsystem devices_subsys; /* needed for vio_find_name() */
-
-static void probe_bus_pseries(void)
-{
-       struct device_node *node_vroot, *of_node;
-
-       node_vroot = find_devices("vdevice");
-       if ((node_vroot == NULL) || (node_vroot->child == NULL))
-               /* this machine doesn't do virtual IO, and that's ok */
-               return;
-
-       /*
-        * Create struct vio_devices for each virtual device in the device tree.
-        * Drivers will associate with them later.
-        */
-       for (of_node = node_vroot->child; of_node != NULL;
-                       of_node = of_node->sibling) {
-               printk(KERN_DEBUG "%s: processing %p\n", __FUNCTION__, of_node);
-               vio_register_device_node(of_node);
-       }
-}
-
-/**
- * vio_match_device_pseries: - Tell if a pSeries VIO device matches a
- *     vio_device_id
- */
-static int vio_match_device_pseries(const struct vio_device_id *id,
-               const struct vio_dev *dev)
-{
-       return (strncmp(dev->type, id->type, strlen(id->type)) == 0) &&
-                       device_is_compatible(dev->dev.platform_data, id->compat);
-}
-
-static void vio_release_device_pseries(struct device *dev)
-{
-       /* XXX free TCE table */
-       of_node_put(dev->platform_data);
-}
-
-static ssize_t viodev_show_devspec(struct device *dev,
-               struct device_attribute *attr, char *buf)
-{
-       struct device_node *of_node = dev->platform_data;
-
-       return sprintf(buf, "%s\n", of_node->full_name);
-}
-DEVICE_ATTR(devspec, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_devspec, NULL);
-
-static void vio_unregister_device_pseries(struct vio_dev *viodev)
-{
-       device_remove_file(&viodev->dev, &dev_attr_devspec);
-}
-
-static struct vio_bus_ops vio_bus_ops_pseries = {
-       .match = vio_match_device_pseries,
-       .unregister_device = vio_unregister_device_pseries,
-       .release_device = vio_release_device_pseries,
-};
-
-/**
- * vio_bus_init_pseries: - Initialize the pSeries virtual IO bus
- */
-static int __init vio_bus_init_pseries(void)
-{
-       int err;
-
-       err = vio_bus_init(&vio_bus_ops_pseries);
-       if (err == 0)
-               probe_bus_pseries();
-       return err;
-}
-
-__initcall(vio_bus_init_pseries);
-
-/**
- * vio_build_iommu_table: - gets the dma information from OF and
- *     builds the TCE tree.
- * @dev: the virtual device.
- *
- * Returns a pointer to the built tce tree, or NULL if it can't
- * find property.
-*/
-static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
-{
-       unsigned int *dma_window;
-       struct iommu_table *newTceTable;
-       unsigned long offset;
-       int dma_window_property_size;
-
-       dma_window = (unsigned int *) get_property(dev->dev.platform_data, "ibm,my-dma-window", &dma_window_property_size);
-       if(!dma_window) {
-               return NULL;
-       }
-
-       newTceTable = (struct iommu_table *) kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
-
-       /*  There should be some code to extract the phys-encoded offset
-               using prom_n_addr_cells(). However, according to a comment
-               on earlier versions, it's always zero, so we don't bother */
-       offset = dma_window[1] >>  PAGE_SHIFT;
-
-       /* TCE table size - measured in tce entries */
-       newTceTable->it_size            = dma_window[4] >> PAGE_SHIFT;
-       /* offset for VIO should always be 0 */
-       newTceTable->it_offset          = offset;
-       newTceTable->it_busno           = 0;
-       newTceTable->it_index           = (unsigned long)dma_window[0];
-       newTceTable->it_type            = TCE_VB;
-
-       return iommu_init_table(newTceTable);
-}
-
-/**
- * vio_register_device_node: - Register a new vio device.
- * @of_node:   The OF node for this device.
- *
- * Creates and initializes a vio_dev structure from the data in
- * of_node (dev.platform_data) and adds it to the list of virtual devices.
- * Returns a pointer to the created vio_dev or NULL if node has
- * NULL device_type or compatible fields.
- */
-struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
-{
-       struct vio_dev *viodev;
-       unsigned int *unit_address;
-       unsigned int *irq_p;
-
-       /* we need the 'device_type' property, in order to match with drivers */
-       if ((NULL == of_node->type)) {
-               printk(KERN_WARNING
-                       "%s: node %s missing 'device_type'\n", __FUNCTION__,
-                       of_node->name ? of_node->name : "<unknown>");
-               return NULL;
-       }
-
-       unit_address = (unsigned int *)get_property(of_node, "reg", NULL);
-       if (!unit_address) {
-               printk(KERN_WARNING "%s: node %s missing 'reg'\n", __FUNCTION__,
-                       of_node->name ? of_node->name : "<unknown>");
-               return NULL;
-       }
-
-       /* allocate a vio_dev for this node */
-       viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL);
-       if (!viodev) {
-               return NULL;
-       }
-       memset(viodev, 0, sizeof(struct vio_dev));
-
-       viodev->dev.platform_data = of_node_get(of_node);
-
-       viodev->irq = NO_IRQ;
-       irq_p = (unsigned int *)get_property(of_node, "interrupts", NULL);
-       if (irq_p) {
-               int virq = virt_irq_create_mapping(*irq_p);
-               if (virq == NO_IRQ) {
-                       printk(KERN_ERR "Unable to allocate interrupt "
-                              "number for %s\n", of_node->full_name);
-               } else
-                       viodev->irq = irq_offset_up(virq);
-       }
-
-       snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address);
-       viodev->name = of_node->name;
-       viodev->type = of_node->type;
-       viodev->unit_address = *unit_address;
-       viodev->iommu_table = vio_build_iommu_table(viodev);
-
-       /* register with generic device framework */
-       if (vio_register_device(viodev) == NULL) {
-               /* XXX free TCE table */
-               kfree(viodev);
-               return NULL;
-       }
-       device_create_file(&viodev->dev, &dev_attr_devspec);
-
-       return viodev;
-}
-EXPORT_SYMBOL(vio_register_device_node);
-
-/**
- * vio_get_attribute: - get attribute for virtual device
- * @vdev:      The vio device to get property.
- * @which:     The property/attribute to be extracted.
- * @length:    Pointer to length of returned data size (unused if NULL).
- *
- * Calls prom.c's get_property() to return the value of the
- * attribute specified by the preprocessor constant @which
-*/
-const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length)
-{
-       return get_property(vdev->dev.platform_data, (char*)which, length);
-}
-EXPORT_SYMBOL(vio_get_attribute);
-
-/* vio_find_name() - internal because only vio.c knows how we formatted the
- * kobject name
- * XXX once vio_bus_type.devices is actually used as a kset in
- * drivers/base/bus.c, this function should be removed in favor of
- * "device_find(kobj_name, &vio_bus_type)"
- */
-static struct vio_dev *vio_find_name(const char *kobj_name)
-{
-       struct kobject *found;
-
-       found = kset_find_obj(&devices_subsys.kset, kobj_name);
-       if (!found)
-               return NULL;
-
-       return to_vio_dev(container_of(found, struct device, kobj));
-}
-
-/**
- * vio_find_node - find an already-registered vio_dev
- * @vnode: device_node of the virtual device we're looking for
- */
-struct vio_dev *vio_find_node(struct device_node *vnode)
-{
-       uint32_t *unit_address;
-       char kobj_name[BUS_ID_SIZE];
-
-       /* construct the kobject name from the device node */
-       unit_address = (uint32_t *)get_property(vnode, "reg", NULL);
-       if (!unit_address)
-               return NULL;
-       snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address);
-
-       return vio_find_name(kobj_name);
-}
-EXPORT_SYMBOL(vio_find_node);
-
-int vio_enable_interrupts(struct vio_dev *dev)
-{
-       int rc = h_vio_signal(dev->unit_address, VIO_IRQ_ENABLE);
-       if (rc != H_SUCCESS)
-               printk(KERN_ERR "vio: Error 0x%x enabling interrupts\n", rc);
-       return rc;
-}
-EXPORT_SYMBOL(vio_enable_interrupts);
-
-int vio_disable_interrupts(struct vio_dev *dev)
-{
-       int rc = h_vio_signal(dev->unit_address, VIO_IRQ_DISABLE);
-       if (rc != H_SUCCESS)
-               printk(KERN_ERR "vio: Error 0x%x disabling interrupts\n", rc);
-       return rc;
-}
-EXPORT_SYMBOL(vio_disable_interrupts);
index 2d60ea30fed6a00d24efa99085070fbfe2492c16..b14f9b5c114edebf110120973e8fe43b4fa1168e 100644 (file)
@@ -522,7 +522,7 @@ nextnode:
 
        np = of_find_node_by_type(NULL, "interrupt-controller");
        if (!np) {
-               printk(KERN_WARNING "xics: no ISA interrupt controller\n");
+               printk(KERN_DEBUG "xics: no ISA interrupt controller\n");
                xics_irq_8259_cascade_real = -1;
                xics_irq_8259_cascade = -1;
        } else {
@@ -641,23 +641,26 @@ void xics_teardown_cpu(int secondary)
        ops->cppr_info(cpu, 0x00);
        iosync();
 
+       /* Clear IPI */
+       ops->qirr_info(cpu, 0xff);
+
+       /*
+        * we need to EOI the IPI if we got here from kexec down IPI
+        *
+        * probably need to check all the other interrupts too
+        * should we be flagging idle loop instead?
+        * or creating some task to be scheduled?
+        */
+       ops->xirr_info_set(cpu, XICS_IPI);
+
        /*
         * Some machines need to have at least one cpu in the GIQ,
         * so leave the master cpu in the group.
         */
-       if (secondary) {
-               /*
-                * we need to EOI the IPI if we got here from kexec down IPI
-                *
-                * probably need to check all the other interrupts too
-                * should we be flagging idle loop instead?
-                * or creating some task to be scheduled?
-                */
-               ops->xirr_info_set(cpu, XICS_IPI);
+       if (secondary)
                rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
                        (1UL << interrupt_server_size) - 1 -
                        default_distrib_server, 0);
-       }
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
index e9a8f5d1dfcdf9f4e8b7c8ac157e5d8e6d9abaf3..b55de4f42aec1a8b4db42d2379c43cbf7f89b4c5 100644 (file)
@@ -40,6 +40,10 @@ config GENERIC_NVRAM
        bool
        default y
 
+config GENERIC_FIND_NEXT_BIT
+       bool
+       default y
+
 config SCHED_NO_NO_OMIT_FRAME_POINTER
        bool
        default y
index b4a4b3f02a1cac61fbb31a9407075a0cd99347da..8784f3715032d8008c2f37cafd1ceb3005fb8bae 100644 (file)
@@ -30,7 +30,7 @@
 #include <asm/mmu_context.h>
 #include <asm/tlbflush.h>
 
-mm_context_t next_mmu_context;
+unsigned long next_mmu_context;
 unsigned long context_map[LAST_CONTEXT / BITS_PER_LONG + 1];
 #ifdef FEW_CONTEXTS
 atomic_t nr_free_contexts;
index f63e07bd9f9c4e3b23f20c626c95e260451f1639..b0df4f5ab97afff4d490e9781fae37bd9984a210 100644 (file)
@@ -747,7 +747,7 @@ static int viodasd_remove(struct vio_dev *vdev)
  * support.
  */
 static struct vio_device_id viodasd_device_table[] __devinitdata = {
-       { "viodasd", "" },
+       { "block", "IBM,iSeries-viodasd" },
        { "", "" }
 };
 MODULE_DEVICE_TABLE(vio, viodasd_device_table);
index c0f817ba7adba0a1b5defc5083b99bd8ff123d25..af6b3bfd169ba1ccb7dc8f77c44bafad408f7dd0 100644 (file)
@@ -731,7 +731,7 @@ static int viocd_remove(struct vio_dev *vdev)
  * support.
  */
 static struct vio_device_id viocd_device_table[] __devinitdata = {
-       { "viocd", "" },
+       { "block", "IBM,iSeries-viocd" },
        { "", "" }
 };
 MODULE_DEVICE_TABLE(vio, viocd_device_table);
index 2b6a56b2bf35c78b53153d87b032c720b5b0b004..a5c6a9d7ff0805319d42ee5ceb03020058821c59 100644 (file)
@@ -553,7 +553,6 @@ static int hvc_chars_in_buffer(struct tty_struct *tty)
 
 #define HVC_POLL_READ  0x00000001
 #define HVC_POLL_WRITE 0x00000002
-#define HVC_POLL_QUICK 0x00000004
 
 static int hvc_poll(struct hvc_struct *hp)
 {
@@ -568,6 +567,7 @@ static int hvc_poll(struct hvc_struct *hp)
        /* Push pending writes */
        if (hp->n_outbuf > 0)
                hvc_push(hp);
+
        /* Reschedule us if still some write pending */
        if (hp->n_outbuf > 0)
                poll_mask |= HVC_POLL_WRITE;
@@ -680,7 +680,7 @@ int khvcd(void *unused)
                        poll_mask |= HVC_POLL_READ;
                if (hvc_kicked)
                        continue;
-               if (poll_mask & HVC_POLL_QUICK) {
+               if (poll_mask & HVC_POLL_WRITE) {
                        yield();
                        continue;
                }
index 83364ea63cba7b23c71b9cc44bfdd922e47c7eff..57106e02fd2e4ac8686758ceea8e062cd4abb4c4 100644 (file)
 #define hvc_rtas_cookie 0x67781e15
 struct hvc_struct *hvc_rtas_dev;
 
-#define RTASCONS_PUT_ATTEMPTS  16
-
 static int rtascons_put_char_token = RTAS_UNKNOWN_SERVICE;
 static int rtascons_get_char_token = RTAS_UNKNOWN_SERVICE;
-static int rtascons_put_delay = 100;
-module_param_named(put_delay, rtascons_put_delay, int, 0644);
 
-static inline int hvc_rtas_write_console(uint32_t vtermno, const char *buf, int count)
+static inline int hvc_rtas_write_console(uint32_t vtermno, const char *buf,
+               int count)
 {
-       int done;
+       int i;
 
-       /* if there is more than one character to be displayed, wait a bit */
-       for (done = 0; done < count; done++) {
-               int result;
-               result = rtas_call(rtascons_put_char_token, 1, 1, NULL, buf[done]);
-               if (result)
+       for (i = 0; i < count; i++) {
+               if (rtas_call(rtascons_put_char_token, 1, 1, NULL, buf[i]))
                        break;
        }
-       /* the calling routine expects to receive the number of bytes sent */
-       return done;
+
+       return i;
 }
 
 static int hvc_rtas_read_console(uint32_t vtermno, char *buf, int count)
 {
-       int i;
+       int i, c;
 
        for (i = 0; i < count; i++) {
-               int c, err;
-
-               err = rtas_call(rtascons_get_char_token, 0, 2, &c);
-               if (err)
+               if (rtas_call(rtascons_get_char_token, 0, 2, &c))
                        break;
 
                buf[i] = c;
@@ -106,7 +97,9 @@ static int hvc_rtas_init(void)
        hp = hvc_alloc(hvc_rtas_cookie, NO_IRQ, &hvc_rtas_get_put_ops);
        if (IS_ERR(hp))
                return PTR_ERR(hp);
+
        hvc_rtas_dev = hp;
+
        return 0;
 }
 module_init(hvc_rtas_init);
@@ -114,8 +107,8 @@ module_init(hvc_rtas_init);
 /* This will tear down the tty portion of the driver */
 static void __exit hvc_rtas_exit(void)
 {
-       /* Really the fun isn't over until the worker thread breaks down and the
-        * tty cleans up */
+       /* Really the fun isn't over until the worker thread breaks down and
+        * the tty cleans up */
        if (hvc_rtas_dev)
                hvc_remove(hvc_rtas_dev);
 }
@@ -127,12 +120,14 @@ static int hvc_rtas_console_init(void)
        rtascons_put_char_token = rtas_token("put-term-char");
        if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE)
                return -EIO;
+
        rtascons_get_char_token = rtas_token("get-term-char");
        if (rtascons_get_char_token == RTAS_UNKNOWN_SERVICE)
                return -EIO;
 
-       hvc_instantiate(hvc_rtas_cookie, 0, &hvc_rtas_get_put_ops );
+       hvc_instantiate(hvc_rtas_cookie, 0, &hvc_rtas_get_put_ops);
        add_preferred_console("hvc", 0, NULL);
+
        return 0;
 }
 console_initcall(hvc_rtas_console_init);
index a9522189fc9efeaa82dab6d3b479df11d89a8412..a0370ed752ce01725b4458fb00335adb5ccb905f 100644 (file)
@@ -1179,7 +1179,7 @@ static int __init hvsi_init(void)
        if (tty_register_driver(hvsi_driver))
                panic("Couldn't register hvsi console driver\n");
 
-       printk(KERN_INFO "HVSI: registered %i devices\n", hvsi_count);
+       printk(KERN_DEBUG "HVSI: registered %i devices\n", hvsi_count);
 
        return 0;
 }
index 60aabdb4a046975ead521046aa1353216d3cfbf2..11c7e9de595862a9747b6b19b18d0499e357da6b 100644 (file)
@@ -989,7 +989,7 @@ static int viotape_remove(struct vio_dev *vdev)
  * support.
  */
 static struct vio_device_id viotape_device_table[] __devinitdata = {
-       { "viotape", "" },
+       { "byte", "IBM,iSeries-viotape" },
        { "", "" }
 };
 MODULE_DEVICE_TABLE(vio, viotape_device_table);
index 0b5ff553e39a01046c4afeaf480eceb8020208a3..c63d4e7984be6e1884388f3c2875df6ce621a164 100644 (file)
@@ -2268,7 +2268,7 @@ static int powerbook_sleep_grackle(void)
                _set_L2CR(save_l2cr);
        
        /* Restore userland MMU context */
-       set_context(current->active_mm->context, current->active_mm->pgd);
+       set_context(current->active_mm->context.id, current->active_mm->pgd);
 
        /* Power things up */
        pmu_unlock();
@@ -2366,7 +2366,7 @@ powerbook_sleep_Core99(void)
                _set_L3CR(save_l3cr);
        
        /* Restore userland MMU context */
-       set_context(current->active_mm->context, current->active_mm->pgd);
+       set_context(current->active_mm->context.id, current->active_mm->pgd);
 
        /* Tell PMU we are ready */
        pmu_unlock();
index 52d01027d9e7c236d472af4f25b2f84e993a22bf..37965dc78eece19bfd5cb150deb0895194d20beb 100644 (file)
@@ -61,7 +61,7 @@
 #undef DEBUG
 
 #define ibmveth_printk(fmt, args...) \
-  printk(KERN_INFO "%s: " fmt, __FILE__, ## args)
+  printk(KERN_DEBUG "%s: " fmt, __FILE__, ## args)
 
 #define ibmveth_error_printk(fmt, args...) \
   printk(KERN_ERR "(%s:%3.3d ua:%x) ERROR: " fmt, __FILE__, __LINE__ , adapter->vdev->unit_address, ## args)
index f0f04be989d62bf5003838fbea839ee097f88883..93394d76587ab749bdd1adb7b22b03fb3e9aaec0 100644 (file)
@@ -69,6 +69,7 @@
 #include <linux/delay.h>
 #include <linux/mm.h>
 #include <linux/ethtool.h>
+#include <linux/if_ether.h>
 
 #include <asm/abs_addr.h>
 #include <asm/iseries/mf.h>
@@ -1035,11 +1036,22 @@ static struct ethtool_ops ops = {
        .get_link = veth_get_link,
 };
 
-static struct net_device * __init veth_probe_one(int vlan, struct device *vdev)
+static struct net_device * __init veth_probe_one(int vlan,
+               struct vio_dev *vio_dev)
 {
        struct net_device *dev;
        struct veth_port *port;
+       struct device *vdev = &vio_dev->dev;
        int i, rc;
+       const unsigned char *mac_addr;
+
+       mac_addr = vio_get_attribute(vio_dev, "local-mac-address", NULL);
+       if (mac_addr == NULL)
+               mac_addr = vio_get_attribute(vio_dev, "mac-address", NULL);
+       if (mac_addr == NULL) {
+               veth_error("Unable to fetch MAC address from device tree.\n");
+               return NULL;
+       }
 
        dev = alloc_etherdev(sizeof (struct veth_port));
        if (! dev) {
@@ -1064,16 +1076,11 @@ static struct net_device * __init veth_probe_one(int vlan, struct device *vdev)
        }
        port->dev = vdev;
 
-       dev->dev_addr[0] = 0x02;
-       dev->dev_addr[1] = 0x01;
-       dev->dev_addr[2] = 0xff;
-       dev->dev_addr[3] = vlan;
-       dev->dev_addr[4] = 0xff;
-       dev->dev_addr[5] = this_lp;
+       memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
 
        dev->mtu = VETH_MAX_MTU;
 
-       memcpy(&port->mac_addr, dev->dev_addr, 6);
+       memcpy(&port->mac_addr, mac_addr, ETH_ALEN);
 
        dev->open = veth_open;
        dev->hard_start_xmit = veth_start_xmit;
@@ -1608,7 +1615,7 @@ static int veth_probe(struct vio_dev *vdev, const struct vio_device_id *id)
        struct net_device *dev;
        struct veth_port *port;
 
-       dev = veth_probe_one(i, &vdev->dev);
+       dev = veth_probe_one(i, vdev);
        if (dev == NULL) {
                veth_remove(vdev);
                return 1;
@@ -1641,7 +1648,7 @@ static int veth_probe(struct vio_dev *vdev, const struct vio_device_id *id)
  * support.
  */
 static struct vio_device_id veth_device_table[] __devinitdata = {
-       { "vlan", "" },
+       { "network", "IBM,iSeries-l-lan" },
        { "", "" }
 };
 MODULE_DEVICE_TABLE(vio, veth_device_table);
index d1c2a4405660dbecbcaa859c4abbc7b0fea2bba3..76e2f08c3c83016915a7831e3402a6baa638284d 100644 (file)
@@ -288,8 +288,8 @@ static __inline__ int test_le_bit(unsigned long nr,
 #define __test_and_clear_le_bit(nr, addr) \
        __test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
 
-#define find_first_zero_le_bit(addr, size) find_next_zero_le_bit((addr), (size), 0)
-unsigned long find_next_zero_le_bit(const unsigned long *addr,
+#define find_first_zero_le_bit(addr, size) generic_find_next_zero_le_bit((addr), (size), 0)
+unsigned long generic_find_next_zero_le_bit(const unsigned long *addr,
                                    unsigned long size, unsigned long offset);
 
 /* Bitmap functions for the ext2 filesystem */
@@ -309,7 +309,7 @@ unsigned long find_next_zero_le_bit(const unsigned long *addr,
 #define ext2_find_first_zero_bit(addr, size) \
        find_first_zero_le_bit((unsigned long*)addr, size)
 #define ext2_find_next_zero_bit(addr, size, off) \
-       find_next_zero_le_bit((unsigned long*)addr, size, off)
+       generic_find_next_zero_le_bit((unsigned long*)addr, size, off)
 
 /* Bitmap functions for the minix filesystem.  */
 
index 9fcf0162d859e3e5ec7ae95649850c305785ee04..69f2c242797ff16d3c85867f817e0c1fbf9c3727 100644 (file)
@@ -24,6 +24,9 @@
 #define PPC_FEATURE_ICACHE_SNOOP       0x00002000
 #define PPC_FEATURE_ARCH_2_05          0x00001000
 
+#define PPC_FEATURE_TRUE_LE            0x00000002
+#define PPC_FEATURE_PPC_LE             0x00000001
+
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
 
@@ -69,6 +72,13 @@ struct cpu_spec {
        /* Processor specific oprofile operations */
        enum powerpc_oprofile_type oprofile_type;
 
+       /* Bit locations inside the mmcra change */
+       unsigned long   oprofile_mmcra_sihv;
+       unsigned long   oprofile_mmcra_sipr;
+
+       /* Bits to clear during an oprofile exception */
+       unsigned long   oprofile_mmcra_clear;
+
        /* Name of processor class, for the ELF AT_PLATFORM entry */
        char            *platform;
 };
@@ -104,6 +114,8 @@ extern void do_cpu_ftr_fixups(unsigned long offset);
 #define CPU_FTR_NO_BTIC                        ASM_CONST(0x0000000000040000)
 #define CPU_FTR_BIG_PHYS               ASM_CONST(0x0000000000080000)
 #define CPU_FTR_NODSISRALIGN           ASM_CONST(0x0000000000100000)
+#define CPU_FTR_PPC_LE                 ASM_CONST(0x0000000000200000)
+#define CPU_FTR_REAL_LE                        ASM_CONST(0x0000000000400000)
 
 #ifdef __powerpc64__
 /* Add the 64b processor unique features in the top half of the word */
@@ -117,7 +129,6 @@ extern void do_cpu_ftr_fixups(unsigned long offset);
 #define CPU_FTR_SMT                    ASM_CONST(0x0000010000000000)
 #define CPU_FTR_COHERENT_ICACHE                ASM_CONST(0x0000020000000000)
 #define CPU_FTR_LOCKLESS_TLBIE         ASM_CONST(0x0000040000000000)
-#define CPU_FTR_MMCRA_SIHV             ASM_CONST(0x0000080000000000)
 #define CPU_FTR_CI_LARGE_PAGE          ASM_CONST(0x0000100000000000)
 #define CPU_FTR_PAUSE_ZERO             ASM_CONST(0x0000200000000000)
 #define CPU_FTR_PURR                   ASM_CONST(0x0000400000000000)
@@ -134,7 +145,6 @@ extern void do_cpu_ftr_fixups(unsigned long offset);
 #define CPU_FTR_SMT                    ASM_CONST(0x0)
 #define CPU_FTR_COHERENT_ICACHE                ASM_CONST(0x0)
 #define CPU_FTR_LOCKLESS_TLBIE         ASM_CONST(0x0)
-#define CPU_FTR_MMCRA_SIHV             ASM_CONST(0x0)
 #define CPU_FTR_CI_LARGE_PAGE          ASM_CONST(0x0)
 #define CPU_FTR_PURR                   ASM_CONST(0x0)
 #endif
@@ -192,92 +202,95 @@ extern void do_cpu_ftr_fixups(unsigned long offset);
 #define CPU_FTRS_PPC601        (CPU_FTR_COMMON | CPU_FTR_601 | CPU_FTR_HPTE_TABLE)
 #define CPU_FTRS_603   (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
            CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | \
-           CPU_FTR_MAYBE_CAN_NAP)
+           CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE)
 #define CPU_FTRS_604   (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
-           CPU_FTR_USE_TB | CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE)
+           CPU_FTR_USE_TB | CPU_FTR_604_PERF_MON | CPU_FTR_HPTE_TABLE | \
+           CPU_FTR_PPC_LE)
 #define CPU_FTRS_740_NOTAU     (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
            CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
-           CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP)
+           CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE)
 #define CPU_FTRS_740   (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
            CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
-           CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP)
+           CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | \
+           CPU_FTR_PPC_LE)
 #define CPU_FTRS_750   (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
            CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
-           CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP)
+           CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | \
+           CPU_FTR_PPC_LE)
 #define CPU_FTRS_750FX1        (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
            CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
            CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | \
-           CPU_FTR_DUAL_PLL_750FX | CPU_FTR_NO_DPM)
+           CPU_FTR_DUAL_PLL_750FX | CPU_FTR_NO_DPM | CPU_FTR_PPC_LE)
 #define CPU_FTRS_750FX2        (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
            CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
            CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | \
-           CPU_FTR_NO_DPM)
+           CPU_FTR_NO_DPM | CPU_FTR_PPC_LE)
 #define CPU_FTRS_750FX (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
            CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
            CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | \
-           CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS)
+           CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS | CPU_FTR_PPC_LE)
 #define CPU_FTRS_750GX (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | \
            CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU | \
            CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP | \
-           CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS)
+           CPU_FTR_DUAL_PLL_750FX | CPU_FTR_HAS_HIGH_BATS | CPU_FTR_PPC_LE)
 #define CPU_FTRS_7400_NOTAU    (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
            CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
            CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | \
-           CPU_FTR_MAYBE_CAN_NAP)
+           CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE)
 #define CPU_FTRS_7400  (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
            CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB | CPU_FTR_L2CR | \
            CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE | \
-           CPU_FTR_MAYBE_CAN_NAP)
+           CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_PPC_LE)
 #define CPU_FTRS_7450_20       (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
            CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
            CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
-           CPU_FTR_NEED_COHERENT)
+           CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE)
 #define CPU_FTRS_7450_21       (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
            CPU_FTR_USE_TB | \
            CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
            CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
            CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP | \
-           CPU_FTR_NEED_COHERENT)
+           CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE)
 #define CPU_FTRS_7450_23       (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
            CPU_FTR_USE_TB | \
            CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
            CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
-           CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_NEED_COHERENT)
+           CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE)
 #define CPU_FTRS_7455_1        (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
            CPU_FTR_USE_TB | \
            CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR | \
            CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_HAS_HIGH_BATS | \
-           CPU_FTR_NEED_COHERENT)
+           CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE)
 #define CPU_FTRS_7455_20       (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
            CPU_FTR_USE_TB | \
            CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
            CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
            CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_L3_DISABLE_NAP | \
-           CPU_FTR_NEED_COHERENT | CPU_FTR_HAS_HIGH_BATS)
+           CPU_FTR_NEED_COHERENT | CPU_FTR_HAS_HIGH_BATS | CPU_FTR_PPC_LE)
 #define CPU_FTRS_7455  (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
            CPU_FTR_USE_TB | \
            CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
            CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
            CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \
-           CPU_FTR_NEED_COHERENT)
+           CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE)
 #define CPU_FTRS_7447_10       (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
            CPU_FTR_USE_TB | \
            CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
            CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
            CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \
-           CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC)
+           CPU_FTR_NEED_COHERENT | CPU_FTR_NO_BTIC | CPU_FTR_PPC_LE)
 #define CPU_FTRS_7447  (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
            CPU_FTR_USE_TB | \
            CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
            CPU_FTR_L3CR | CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
            CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \
-           CPU_FTR_NEED_COHERENT)
+           CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE)
 #define CPU_FTRS_7447A (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
            CPU_FTR_USE_TB | \
            CPU_FTR_MAYBE_CAN_NAP | CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | \
            CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | \
            CPU_FTR_NAP_DISABLE_L2_PR | CPU_FTR_HAS_HIGH_BATS | \
-           CPU_FTR_NEED_COHERENT)
+           CPU_FTR_NEED_COHERENT | CPU_FTR_PPC_LE)
 #define CPU_FTRS_82XX  (CPU_FTR_COMMON | CPU_FTR_SPLIT_ID_CACHE | \
            CPU_FTR_MAYBE_CAN_DOZE | CPU_FTR_USE_TB)
 #define CPU_FTRS_G2_LE (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE | \
@@ -307,7 +320,7 @@ extern void do_cpu_ftr_fixups(unsigned long offset);
 #define CPU_FTRS_GENERIC_32    (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
 #ifdef __powerpc64__
 #define CPU_FTRS_POWER3        (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
-           CPU_FTR_HPTE_TABLE | CPU_FTR_IABR)
+           CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | CPU_FTR_PPC_LE)
 #define CPU_FTRS_RS64  (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
            CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | \
            CPU_FTR_MMCRA | CPU_FTR_CTRL)
@@ -320,12 +333,12 @@ extern void do_cpu_ftr_fixups(unsigned long offset);
            CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
            CPU_FTR_MMCRA | CPU_FTR_SMT | \
            CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
-           CPU_FTR_MMCRA_SIHV | CPU_FTR_PURR)
+           CPU_FTR_PURR)
 #define CPU_FTRS_POWER6 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
            CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
            CPU_FTR_MMCRA | CPU_FTR_SMT | \
            CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
-           CPU_FTR_PURR | CPU_FTR_CI_LARGE_PAGE)
+           CPU_FTR_PURR | CPU_FTR_CI_LARGE_PAGE | CPU_FTR_REAL_LE)
 #define CPU_FTRS_CELL  (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
            CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
            CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
index 868c7139dbfff8db6d6730db3900e0ccce6add4d..2c3dc4a2b12a6dc24c6d41c8d47aceb301ca8b64 100644 (file)
@@ -293,8 +293,6 @@ static inline void eeh_memcpy_toio(volatile void __iomem *dest, const void *src,
 static inline u8 eeh_inb(unsigned long port)
 {
        u8 val;
-       if (!_IO_IS_VALID(port))
-               return ~0;
        val = in_8((u8 __iomem *)(port+pci_io_base));
        if (EEH_POSSIBLE_ERROR(val, u8))
                return eeh_check_failure((void __iomem *)(port), val);
@@ -303,15 +301,12 @@ static inline u8 eeh_inb(unsigned long port)
 
 static inline void eeh_outb(u8 val, unsigned long port)
 {
-       if (_IO_IS_VALID(port))
-               out_8((u8 __iomem *)(port+pci_io_base), val);
+       out_8((u8 __iomem *)(port+pci_io_base), val);
 }
 
 static inline u16 eeh_inw(unsigned long port)
 {
        u16 val;
-       if (!_IO_IS_VALID(port))
-               return ~0;
        val = in_le16((u16 __iomem *)(port+pci_io_base));
        if (EEH_POSSIBLE_ERROR(val, u16))
                return eeh_check_failure((void __iomem *)(port), val);
@@ -320,15 +315,12 @@ static inline u16 eeh_inw(unsigned long port)
 
 static inline void eeh_outw(u16 val, unsigned long port)
 {
-       if (_IO_IS_VALID(port))
-               out_le16((u16 __iomem *)(port+pci_io_base), val);
+       out_le16((u16 __iomem *)(port+pci_io_base), val);
 }
 
 static inline u32 eeh_inl(unsigned long port)
 {
        u32 val;
-       if (!_IO_IS_VALID(port))
-               return ~0;
        val = in_le32((u32 __iomem *)(port+pci_io_base));
        if (EEH_POSSIBLE_ERROR(val, u32))
                return eeh_check_failure((void __iomem *)(port), val);
@@ -337,8 +329,7 @@ static inline u32 eeh_inl(unsigned long port)
 
 static inline void eeh_outl(u32 val, unsigned long port)
 {
-       if (_IO_IS_VALID(port))
-               out_le32((u32 __iomem *)(port+pci_io_base), val);
+       out_le32((u32 __iomem *)(port+pci_io_base), val);
 }
 
 /* in-string eeh macros */
index 93d55a2bebfdc9e4acc660679d9a4391d7905f73..dc6bf0ffb796afb25fe707c85c9147169742665f 100644 (file)
@@ -18,8 +18,8 @@
  * Copyright (c) 2005 Linas Vepstas <linas@linas.org>
  */
 
-#ifndef ASM_PPC64_EEH_EVENT_H
-#define ASM_PPC64_EEH_EVENT_H
+#ifndef ASM_POWERPC_EEH_EVENT_H
+#define ASM_POWERPC_EEH_EVENT_H
 #ifdef __KERNEL__
 
 /** EEH event -- structure holding pci controller data that describes
@@ -39,7 +39,7 @@ struct eeh_event {
  * @dev pci device
  *
  * This routine builds a PCI error event which will be delivered
- * to all listeners on the peh_notifier_chain.
+ * to all listeners on the eeh_notifier_chain.
  *
  * This routine can be called within an interrupt context;
  * the actual event will be delivered in a normal context
@@ -51,7 +51,7 @@ int eeh_send_failure_event (struct device_node *dn,
                             int time_unavail);
 
 /* Main recovery function */
-void handle_eeh_events (struct eeh_event *);
+struct pci_dn * handle_eeh_events (struct eeh_event *);
 
 #endif /* __KERNEL__ */
-#endif /* ASM_PPC64_EEH_EVENT_H */
+#endif /* ASM_POWERPC_EEH_EVENT_H */
index 94d228f9c6ac0a799e2b431f6464b5e124c1258e..319655ce66c0bed289df84904464b7933856e7b1 100644 (file)
@@ -294,7 +294,7 @@ do {                                                                        \
        NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize);                      \
        NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize);                      \
        NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize);                      \
-       VDSO_AUX_ENT(AT_SYSINFO_EHDR, current->thread.vdso_base)        \
+       VDSO_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso_base)   \
 } while (0)
 
 /* PowerPC64 relocations defined by the ABIs */
index f1c2469b8844793996310ca4f4151942ec7f54d5..a9496f34b048b81a22ccf37c1e8beeb73e180374 100644 (file)
@@ -40,12 +40,6 @@ extern int check_legacy_ioport(unsigned long base_port);
 
 extern unsigned long isa_io_base;
 extern unsigned long pci_io_base;
-extern unsigned long io_page_mask;
-
-#define MAX_ISA_PORT 0x10000
-
-#define _IO_IS_VALID(port) ((port) >= MAX_ISA_PORT || (1 << (port>>PAGE_SHIFT)) \
-                           & io_page_mask)
 
 #ifdef CONFIG_PPC_ISERIES
 /* __raw_* accessors aren't supported on iSeries */
index 18ca29e9105a5d92f1e302d49f411f1f83229159..9065f6c972a43d38c200cf90e326217eb0e137a5 100644 (file)
@@ -76,7 +76,8 @@ extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
                int nelems, enum dma_data_direction direction);
 
 extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
-               dma_addr_t *dma_handle, unsigned long mask, gfp_t flag);
+               dma_addr_t *dma_handle, unsigned long mask,
+               gfp_t flag, int node);
 extern void iommu_free_coherent(struct iommu_table *tbl, size_t size,
                void *vaddr, dma_addr_t dma_handle);
 extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
diff --git a/include/asm-powerpc/iseries/iommu.h b/include/asm-powerpc/iseries/iommu.h
new file mode 100644 (file)
index 0000000..0edbfe1
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef _ASM_POWERPC_ISERIES_IOMMU_H
+#define _ASM_POWERPC_ISERIES_IOMMU_H
+
+/*
+ * Copyright (C) 2005  Stephen Rothwell, 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the:
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330,
+ * Boston, MA  02111-1307  USA
+ */
+
+struct device_node;
+struct iommu_table;
+
+/* Creates table for an individual device node */
+extern void iommu_devnode_init_iSeries(struct device_node *dn);
+
+/* Get table parameters from HV */
+extern void iommu_table_getparms_iSeries(unsigned long busno,
+               unsigned char slotno, unsigned char virtbus,
+               struct iommu_table *tbl);
+
+#endif /* _ASM_POWERPC_ISERIES_IOMMU_H */
index a87aed00d61fbccd8a6ce2a9a10a7e17109e2f74..5a5c3b5ab1e0236686975c0abb9d94bb9a0ef9fd 100644 (file)
@@ -1,13 +1,38 @@
 #ifndef _PPC64_KDUMP_H
 #define _PPC64_KDUMP_H
 
+/* Kdump kernel runs at 32 MB, change at your peril. */
+#define KDUMP_KERNELBASE       0x2000000
+
 /* How many bytes to reserve at zero for kdump. The reserve limit should
- * be greater or equal to the trampoline's end address. */
+ * be greater or equal to the trampoline's end address.
+ * Reserve to the end of the FWNMI area, see head_64.S */
 #define KDUMP_RESERVE_LIMIT    0x8000
 
+#ifdef CONFIG_CRASH_DUMP
+
+#define PHYSICAL_START KDUMP_KERNELBASE
 #define KDUMP_TRAMPOLINE_START 0x0100
 #define KDUMP_TRAMPOLINE_END   0x3000
 
-extern void kdump_setup(void);
+#else /* !CONFIG_CRASH_DUMP */
+
+#define PHYSICAL_START 0x0
+
+#endif /* CONFIG_CRASH_DUMP */
+
+#ifndef __ASSEMBLY__
+#ifdef CONFIG_CRASH_DUMP
+
+extern void reserve_kdump_trampoline(void);
+extern void setup_kdump_trampoline(void);
+
+#else /* !CONFIG_CRASH_DUMP */
+
+static inline void reserve_kdump_trampoline(void) { ; }
+static inline void setup_kdump_trampoline(void) { ; }
+
+#endif /* CONFIG_CRASH_DUMP */
+#endif /* __ASSEMBLY__ */
 
 #endif /* __PPC64_KDUMP_H */
index 6a2af2f6853b368ad8765de253814e1a1f0f090e..efe8872ec58382f78ba3807944d601e7409c80b4 100644 (file)
 #define KEXEC_ARCH KEXEC_ARCH_PPC
 #endif
 
+#ifndef __ASSEMBLY__
+
 #ifdef CONFIG_KEXEC
 
-#ifndef __ASSEMBLY__
 #ifdef __powerpc64__
 /*
  * This function is responsible for capturing register states if coming
@@ -123,8 +124,19 @@ extern int default_machine_kexec_prepare(struct kimage *image);
 extern void default_machine_crash_shutdown(struct pt_regs *regs);
 
 extern void machine_kexec_simple(struct kimage *image);
+extern int overlaps_crashkernel(unsigned long start, unsigned long size);
+extern void reserve_crashkernel(void);
+
+#else /* !CONFIG_KEXEC */
+
+static inline int overlaps_crashkernel(unsigned long start, unsigned long size)
+{
+       return 0;
+}
+
+static inline void reserve_crashkernel(void) { ; }
 
-#endif /* ! __ASSEMBLY__ */
 #endif /* CONFIG_KEXEC */
+#endif /* ! __ASSEMBLY__ */
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_KEXEC_H */
index 31f721994bd894265d73f398560e6028ad84640e..8853974201046cc2a1535b3127fcb3344887bea8 100644 (file)
@@ -96,6 +96,8 @@ extern char initial_stab[];
 #define HPTE_R_FLAGS           ASM_CONST(0x00000000000003ff)
 #define HPTE_R_PP              ASM_CONST(0x0000000000000003)
 #define HPTE_R_N               ASM_CONST(0x0000000000000004)
+#define HPTE_R_C               ASM_CONST(0x0000000000000080)
+#define HPTE_R_R               ASM_CONST(0x0000000000000100)
 
 /* Values for PP (assumes Ks=0, Kp=1) */
 /* pp0 will always be 0 for linux     */
@@ -360,6 +362,7 @@ typedef struct {
 #ifdef CONFIG_HUGETLB_PAGE
        u16 low_htlb_areas, high_htlb_areas;
 #endif
+       unsigned long vdso_base;
 } mm_context_t;
 
 
index 2fbecebe1c92a4c6e8785cf889dc0da7e40fcb53..a315d0c0d96a964d22c81e4946bdedd565c42d4d 100644 (file)
@@ -13,6 +13,7 @@
 #ifdef __KERNEL__
 #include <linux/config.h>
 #include <asm/asm-compat.h>
+#include <asm/kdump.h>
 
 /*
  * On PPC32 page size is 4K. For PPC64 we support either 4K or 64K software
  * If you want to test if something's a kernel address, use is_kernel_addr().
  */
 
-#ifdef CONFIG_CRASH_DUMP
-/* Kdump kernel runs at 32 MB, change at your peril. */
-#define PHYSICAL_START 0x2000000
-#else
-#define PHYSICAL_START 0x0
-#endif
-
 #define PAGE_OFFSET     ASM_CONST(CONFIG_KERNEL_START)
 #define KERNELBASE      (PAGE_OFFSET + PHYSICAL_START)
 
@@ -198,6 +192,9 @@ extern void copy_user_page(void *to, void *from, unsigned long vaddr,
                struct page *p);
 extern int page_is_ram(unsigned long pfn);
 
+struct vm_area_struct;
+extern const char *arch_vma_name(struct vm_area_struct *vma);
+
 #include <asm-generic/memory_model.h>
 #endif /* __ASSEMBLY__ */
 
index 38de92d41a148a2cdfd1083af2bbe35f41dba3d0..84a3075db5244bba324b3e2ba4ea926e3b8ebf4b 100644 (file)
@@ -78,12 +78,6 @@ struct pci_dn {
        struct  iommu_table *iommu_table;       /* for phb's or bridges */
        struct  pci_dev *pcidev;        /* back-pointer to the pci device */
        struct  device_node *node;      /* back-pointer to the device_node */
-#ifdef CONFIG_PPC_ISERIES
-       struct  list_head Device_List;
-       int     Irq;                    /* Assigned IRQ */
-       int     Flags;                  /* Possible flags(disable/bist)*/
-       u8      LogicalSlot;            /* Hv Slot Index for Tces */
-#endif
        u32     config_space[16];       /* saved PCI config space */
 };
 
index 93f83efeb310ebdac9c7fd3db1daae507bd94663..d2c2c95f913b46af94874b9965841e8e7f3cb041 100644 (file)
@@ -149,11 +149,11 @@ struct thread_struct {
                unsigned int val;       /* Floating point status */
        } fpscr;
        int             fpexc_mode;     /* floating-point exception mode */
+       unsigned int    align_ctl;      /* alignment handling control */
 #ifdef CONFIG_PPC64
        unsigned long   start_tb;       /* Start purr when proc switched in */
        unsigned long   accum_tb;       /* Total accumilated purr for process */
 #endif
-       unsigned long   vdso_base;      /* base of the vDSO library */
        unsigned long   dabr;           /* Data address breakpoint register */
 #ifdef CONFIG_ALTIVEC
        /* Complete AltiVec register set */
@@ -212,6 +212,18 @@ unsigned long get_wchan(struct task_struct *p);
 extern int get_fpexc_mode(struct task_struct *tsk, unsigned long adr);
 extern int set_fpexc_mode(struct task_struct *tsk, unsigned int val);
 
+#define GET_ENDIAN(tsk, adr) get_endian((tsk), (adr))
+#define SET_ENDIAN(tsk, val) set_endian((tsk), (val))
+
+extern int get_endian(struct task_struct *tsk, unsigned long adr);
+extern int set_endian(struct task_struct *tsk, unsigned int val);
+
+#define GET_UNALIGN_CTL(tsk, adr)      get_unalign_ctl((tsk), (adr))
+#define SET_UNALIGN_CTL(tsk, val)      set_unalign_ctl((tsk), (val))
+
+extern int get_unalign_ctl(struct task_struct *tsk, unsigned long adr);
+extern int set_unalign_ctl(struct task_struct *tsk, unsigned int val);
+
 static inline unsigned int __unpack_fe01(unsigned long msr_bits)
 {
        return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8);
index 97ef1cd71a4da2ed226b58e9fd121d7970f52a19..c79d58ab7441898e6b68ee8a5504b66754cd8222 100644 (file)
@@ -230,6 +230,12 @@ extern int of_address_to_resource(struct device_node *dev, int index,
 extern int of_pci_address_to_resource(struct device_node *dev, int bar,
                                      struct resource *r);
 
+/* Parse the ibm,dma-window property of an OF node into the busno, phys and
+ * size parameters.
+ */
+void of_parse_dma_window(struct device_node *dn, unsigned char *dma_window_prop,
+               unsigned long *busno, unsigned long *phys, unsigned long *size);
+
 extern void kdump_move_device_tree(void);
 
 #endif /* __KERNEL__ */
index 9c550b3148231418b99f63403f0631c2ef2402fa..dc4cb9cc73a1b43394b8f12b903e91cdb359764d 100644 (file)
@@ -229,13 +229,13 @@ do {                                                                            \
 #define PTRACE_GET_DEBUGREG    25
 #define PTRACE_SET_DEBUGREG    26
 
-#ifdef __powerpc64__
 /* Additional PTRACE requests implemented on PowerPC. */
 #define PPC_PTRACE_GETREGS     0x99    /* Get GPRs 0 - 31 */
 #define PPC_PTRACE_SETREGS     0x98    /* Set GPRs 0 - 31 */
 #define PPC_PTRACE_GETFPREGS   0x97    /* Get FPRs 0 - 31 */
 #define PPC_PTRACE_SETFPREGS   0x96    /* Set FPRs 0 - 31 */
 
+#ifdef __powerpc64__
 /* Calls to trace a 64bit program from a 32bit program */
 #define PPC_PTRACE_PEEKTEXT_3264 0x95
 #define PPC_PTRACE_PEEKDATA_3264 0x94
index bd467bf5cf5a7157465e39f7c461f306efb39aa8..3779b21a7c71750561dff3bb3905596149f1d7b8 100644 (file)
 #define SPRN_DABR      0x3F5   /* Data Address Breakpoint Register */
 #define   DABR_TRANSLATION     (1UL << 2)
 #define SPRN_DAR       0x013   /* Data Address Register */
-#define        SPRN_DSISR      0x012   /* Data Storage Interrupt Status Register */
+#define SPRN_DSISR     0x012   /* Data Storage Interrupt Status Register */
 #define   DSISR_NOHPTE         0x40000000      /* no translation found */
 #define   DSISR_PROTFAULT      0x08000000      /* protection fault */
 #define   DSISR_ISSTORE                0x02000000      /* access was a store */
 #define SPRN_IABR      0x3F2   /* Instruction Address Breakpoint Register */
 #define SPRN_HID4      0x3F4           /* 970 HID4 */
 #define SPRN_HID5      0x3F6           /* 970 HID5 */
-#define        SPRN_HID6       0x3F9   /* BE HID 6 */
-#define          HID6_LB       (0x0F<<12) /* Concurrent Large Page Modes */
-#define          HID6_DLP      (1<<20) /* Disable all large page modes (4K only) */
-#define        SPRN_TSC_CELL   0x399   /* Thread switch control on Cell */
-#define          TSC_CELL_DEC_ENABLE_0 0x400000 /* Decrementer Interrupt */
-#define          TSC_CELL_DEC_ENABLE_1 0x200000 /* Decrementer Interrupt */
-#define          TSC_CELL_EE_ENABLE    0x100000 /* External Interrupt */
-#define          TSC_CELL_EE_BOOST     0x080000 /* External Interrupt Boost */
-#define        SPRN_TSC        0x3FD   /* Thread switch control on others */
-#define        SPRN_TST        0x3FC   /* Thread switch timeout on others */
+#define SPRN_HID6      0x3F9   /* BE HID 6 */
+#define   HID6_LB      (0x0F<<12) /* Concurrent Large Page Modes */
+#define   HID6_DLP     (1<<20) /* Disable all large page modes (4K only) */
+#define SPRN_TSC_CELL  0x399   /* Thread switch control on Cell */
+#define   TSC_CELL_DEC_ENABLE_0        0x400000 /* Decrementer Interrupt */
+#define   TSC_CELL_DEC_ENABLE_1        0x200000 /* Decrementer Interrupt */
+#define   TSC_CELL_EE_ENABLE   0x100000 /* External Interrupt */
+#define   TSC_CELL_EE_BOOST    0x080000 /* External Interrupt Boost */
+#define SPRN_TSC       0x3FD   /* Thread switch control on others */
+#define SPRN_TST       0x3FC   /* Thread switch timeout on others */
 #if !defined(SPRN_IAC1) && !defined(SPRN_IAC2)
 #define SPRN_IAC1      0x3F4           /* Instruction Address Compare 1 */
 #define SPRN_IAC2      0x3F5           /* Instruction Address Compare 2 */
 #endif
 #define SPRN_PTEHI     0x3D5   /* 981 7450 PTE HI word (S/W TLB load) */
 #define SPRN_PTELO     0x3D6   /* 982 7450 PTE LO word (S/W TLB load) */
-#define        SPRN_PURR       0x135   /* Processor Utilization of Resources Reg */
+#define SPRN_PURR      0x135   /* Processor Utilization of Resources Reg */
 #define SPRN_PVR       0x11F   /* Processor Version Register */
 #define SPRN_RPA       0x3D6   /* Required Physical Address Register */
 #define SPRN_SDA       0x3BF   /* Sampled Data Address Register */
 #define   MMCRA_SIHV   0x10000000UL /* state of MSR HV when SIAR set */
 #define   MMCRA_SIPR   0x08000000UL /* state of MSR PR when SIAR set */
 #define   MMCRA_SAMPLE_ENABLE 0x00000001UL /* enable sampling */
+#define   POWER6_MMCRA_SIHV   0x0000040000000000ULL
+#define   POWER6_MMCRA_SIPR   0x0000020000000000ULL
+#define   POWER6_MMCRA_THRM    0x00000020UL
+#define   POWER6_MMCRA_OTHER   0x0000000EUL
 #define SPRN_PMC1      787
 #define SPRN_PMC2      788
 #define SPRN_PMC3      789
 
 /* 64-bit processors */
 /* XXX the prefix should be PVR_, we'll do a global sweep to fix it one day */
-#define        PV_NORTHSTAR    0x0033
-#define        PV_PULSAR       0x0034
-#define        PV_POWER4       0x0035
-#define        PV_ICESTAR      0x0036
-#define        PV_SSTAR        0x0037
-#define        PV_POWER4p      0x0038
+#define PV_NORTHSTAR   0x0033
+#define PV_PULSAR      0x0034
+#define PV_POWER4      0x0035
+#define PV_ICESTAR     0x0036
+#define PV_SSTAR       0x0037
+#define PV_POWER4p     0x0038
 #define PV_970         0x0039
-#define        PV_POWER5       0x003A
+#define PV_POWER5      0x003A
 #define PV_POWER5p     0x003B
 #define PV_970FX       0x003C
-#define        PV_630          0x0040
-#define        PV_630p 0x0041
-#define        PV_970MP        0x0044
-#define        PV_BE           0x0070
+#define PV_630         0x0040
+#define PV_630p        0x0041
+#define PV_970MP       0x0044
+#define PV_BE          0x0070
 
 /*
  * Number of entries in the SLB. If this ever changes we should handle
index f43c6835e62a1911c5a18205c0a86a0599e33297..a3b4e55569c7b203321c49eaa9c9546318bc399e 100644 (file)
@@ -177,12 +177,8 @@ extern unsigned long rtas_get_boot_time(void);
 extern void rtas_get_rtc_time(struct rtc_time *rtc_time);
 extern int rtas_set_rtc_time(struct rtc_time *rtc_time);
 
-/* Given an RTAS status code of 9900..9905 compute the hinted delay */
-unsigned int rtas_extended_busy_delay_time(int status);
-static inline int rtas_is_extended_busy(int status)
-{
-       return status >= 9900 && status <= 9909;
-}
+extern unsigned int rtas_busy_delay_time(int status);
+extern unsigned int rtas_busy_delay(int status);
 
 extern void pSeries_log_error(char *buf, unsigned int err_type, int fatal);
 
index 6fa200ad7a7f29813ae15d484b2dacaa1f7aa3ce..c9483adbf59994edc016a90b4f8dfac29449e72f 100644 (file)
 #define TCE_PAGE_SIZE  (1 << TCE_SHIFT)
 #define TCE_PAGE_FACTOR        (PAGE_SHIFT - TCE_SHIFT)
 
-
-/* tce_entry
- * Used by pSeries (SMP) and iSeries/pSeries LPAR, but there it's
- * abstracted so layout is irrelevant.
- */
-union tce_entry {
-       unsigned long te_word;
-       struct {
-               unsigned int  tb_cacheBits :6;  /* Cache hash bits - not used */
-               unsigned int  tb_rsvd      :6;
-               unsigned long tb_rpn       :40; /* Real page number */
-               unsigned int  tb_valid     :1;  /* Tce is valid (vb only) */
-               unsigned int  tb_allio     :1;  /* Tce is valid for all lps (vb only) */
-               unsigned int  tb_lpindex   :8;  /* LpIndex for user of TCE (vb only) */
-               unsigned int  tb_pciwr     :1;  /* Write allowed (pci only) */
-               unsigned int  tb_rdwr      :1;  /* Read allowed  (pci), Write allowed (vb) */
-       } te_bits;
-#define te_cacheBits te_bits.tb_cacheBits
-#define te_rpn       te_bits.tb_rpn
-#define te_valid     te_bits.tb_valid
-#define te_allio     te_bits.tb_allio
-#define te_lpindex   te_bits.tb_lpindex
-#define te_pciwr     te_bits.tb_pciwr
-#define te_rdwr      te_bits.tb_rdwr
-};
-
+#define TCE_ENTRY_SIZE         8               /* each TCE is 64 bits */
+
+#define TCE_RPN_MASK           0xfffffffffful  /* 40-bit RPN (4K pages) */
+#define TCE_RPN_SHIFT          12
+#define TCE_VALID              0x800           /* TCE valid */
+#define TCE_ALLIO              0x400           /* TCE valid for all lpars */
+#define TCE_PCI_WRITE          0x2             /* write from PCI allowed */
+#define TCE_PCI_READ           0x1             /* read from PCI allowed */
+#define TCE_VB_WRITE           0x1             /* write from VB allowed */
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_TCE_H */
index 87362a05542b6ba5036d8631b5f20aa481651980..b7abd423c570f804cb06641e918eab5e3cff420b 100644 (file)
@@ -32,8 +32,13 @@ static inline int node_to_first_cpu(int node)
 
 int of_node_to_nid(struct device_node *device);
 
+#ifdef CONFIG_PPC64
+#define pcibus_to_node(bus)    (of_node_to_nid(bus->sysdata))
+#define pcibus_to_cpumask(bus) (node_to_cpumask(of_node_to_nid(bus->sysdata)))
+#else
 #define pcibus_to_node(node)    (-1)
 #define pcibus_to_cpumask(bus) (cpu_online_map)
+#endif
 
 /* sched_domains SD_NODE_INIT for PPC64 machines */
 #define SD_NODE_INIT (struct sched_domain) {           \
index 5c4236c342bb162f1f5e8b46c8e657e9281b0a17..19a1517ac43b7266f1fad7034863dd0fb8594bf9 100644 (file)
@@ -23,7 +23,8 @@ extern int udbg_write(const char *s, int n);
 extern int udbg_read(char *buf, int buflen);
 
 extern void register_early_udbg_console(void);
-extern void udbg_printf(const char *fmt, ...);
+extern void udbg_printf(const char *fmt, ...)
+       __attribute__ ((format (printf, 1, 2)));
 extern void udbg_progress(char *s, unsigned short hex);
 
 extern void udbg_init_uart(void __iomem *comport, unsigned int speed,
index 0544ece51761f9236ff3b24cfaa46c0e653d23e9..10da7f3af9387d8e1301eacbf3b5f8d090515606 100644 (file)
@@ -64,32 +64,22 @@ struct vio_driver {
        struct device_driver driver;
 };
 
-struct vio_bus_ops {
-       int (*match)(const struct vio_device_id *id, const struct vio_dev *dev);
-       void (*unregister_device)(struct vio_dev *);
-       void (*release_device)(struct device *);
-};
-
 extern struct dma_mapping_ops vio_dma_ops;
 extern struct bus_type vio_bus_type;
-extern struct vio_dev vio_bus_device;
 
 extern int vio_register_driver(struct vio_driver *drv);
 extern void vio_unregister_driver(struct vio_driver *drv);
 
-extern struct vio_dev * __devinit vio_register_device(struct vio_dev *viodev);
 extern void __devinit vio_unregister_device(struct vio_dev *dev);
 
-extern int vio_bus_init(struct vio_bus_ops *);
-
-#ifdef CONFIG_PPC_PSERIES
 struct device_node;
 
 extern struct vio_dev * __devinit vio_register_device_node(
                struct device_node *node_vdev);
-extern struct vio_dev *vio_find_node(struct device_node *vnode);
-extern const void *vio_get_attribute(struct vio_dev *vdev, void *which,
+extern const void *vio_get_attribute(struct vio_dev *vdev, char *which,
                int *length);
+#ifdef CONFIG_PPC_PSERIES
+extern struct vio_dev *vio_find_node(struct device_node *vnode);
 extern int vio_enable_interrupts(struct vio_dev *dev);
 extern int vio_disable_interrupts(struct vio_dev *dev);
 #endif
index 9205db404c7a27fb9d8b7be620a083323a928588..80ae60481fb7b7a732739df193304a87fd83a89e 100644 (file)
@@ -24,8 +24,10 @@ extern phys_addr_t fixup_bigphys_addr(phys_addr_t, phys_addr_t);
 #define PHYS_FMT       "%16Lx"
 #endif
 
-/* Default "unsigned long" context */
-typedef unsigned long mm_context_t;
+typedef struct {
+       unsigned long id;
+       unsigned long vdso_base;
+} mm_context_t;
 
 /* Hardware Page Table Entry */
 typedef struct _PTE {
index 4f152cca13c1985a02fc0c73d4a02808a2ea228d..4454ecf1aed5e9d52c941c2337609f7683dd543f 100644 (file)
@@ -71,7 +71,7 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
 #else
 
 /* PPC 6xx, 7xx CPUs */
-#define NO_CONTEXT             ((mm_context_t) -1)
+#define NO_CONTEXT             ((unsigned long) -1)
 #define LAST_CONTEXT           32767
 #define FIRST_CONTEXT          1
 #endif
@@ -86,7 +86,7 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
  * can be used for debugging on all processors (if you happen to have
  * an Abatron).
  */
-extern void set_context(mm_context_t context, pgd_t *pgd);
+extern void set_context(unsigned long contextid, pgd_t *pgd);
 
 /*
  * Bitmap of contexts in use.
@@ -99,7 +99,7 @@ extern unsigned long context_map[];
  * Its use is an optimization only, we can't rely on this context
  * number to be free, but it usually will be.
  */
-extern mm_context_t next_mmu_context;
+extern unsigned long next_mmu_context;
 
 /*
  * If we don't have sufficient contexts to give one to every task
@@ -118,9 +118,9 @@ extern void steal_context(void);
  */
 static inline void get_mmu_context(struct mm_struct *mm)
 {
-       mm_context_t ctx;
+       unsigned long ctx;
 
-       if (mm->context != NO_CONTEXT)
+       if (mm->context.id != NO_CONTEXT)
                return;
 #ifdef FEW_CONTEXTS
        while (atomic_dec_if_positive(&nr_free_contexts) < 0)
@@ -133,7 +133,7 @@ static inline void get_mmu_context(struct mm_struct *mm)
                        ctx = 0;
        }
        next_mmu_context = (ctx + 1) & LAST_CONTEXT;
-       mm->context = ctx;
+       mm->context.id = ctx;
 #ifdef FEW_CONTEXTS
        context_mm[ctx] = mm;
 #endif
@@ -142,7 +142,12 @@ static inline void get_mmu_context(struct mm_struct *mm)
 /*
  * Set up the context for a new address space.
  */
-#define init_new_context(tsk,mm)       (((mm)->context = NO_CONTEXT), 0)
+static inline int init_new_context(struct task_struct *t, struct mm_struct *mm)
+{
+       mm->context.id = NO_CONTEXT;
+       mm->context.vdso_base = 0;
+       return 0;
+}
 
 /*
  * We're finished using the context for an address space.
@@ -150,9 +155,9 @@ static inline void get_mmu_context(struct mm_struct *mm)
 static inline void destroy_context(struct mm_struct *mm)
 {
        preempt_disable();
-       if (mm->context != NO_CONTEXT) {
-               clear_bit(mm->context, context_map);
-               mm->context = NO_CONTEXT;
+       if (mm->context.id != NO_CONTEXT) {
+               clear_bit(mm->context.id, context_map);
+               mm->context.id = NO_CONTEXT;
 #ifdef FEW_CONTEXTS
                atomic_inc(&nr_free_contexts);
 #endif
@@ -180,7 +185,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
 
        /* Setup new userspace context */
        get_mmu_context(next);
-       set_context(next->context, next->pgd);
+       set_context(next->context.id, next->pgd);
 }
 
 #define deactivate_mm(tsk,mm)  do { } while (0)
index f47002a60edf59dd293906233df56fc386c67679..4f844ebe7669ef760a57be715cde6783d4f27389 100644 (file)
@@ -28,6 +28,9 @@
 #if defined(CONFIG_MPC8555_CDS) || defined(CONFIG_MPC8548_CDS)
 #include <platforms/85xx/mpc8555_cds.h>
 #endif
+#ifdef CONFIG_MPC85xx_CDS
+#include <platforms/85xx/mpc85xx_cds.h>
+#endif
 #ifdef CONFIG_MPC8560_ADS
 #include <platforms/85xx/mpc8560_ads.h>
 #endif
index 570b355162fae0bba5247e84c01407fe55e4ab88..f886066bd15c33a6c2f5fc301b3830a92af88c9c 100644 (file)
@@ -663,7 +663,7 @@ static inline int __ptep_test_and_clear_young(unsigned int context, unsigned lon
        return (old & _PAGE_ACCESSED) != 0;
 }
 #define ptep_test_and_clear_young(__vma, __addr, __ptep) \
-       __ptep_test_and_clear_young((__vma)->vm_mm->context, __addr, __ptep)
+       __ptep_test_and_clear_young((__vma)->vm_mm->context.id, __addr, __ptep)
 
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
 static inline int ptep_test_and_clear_dirty(struct vm_area_struct *vma,
index bf022c43a18ecee1733dc52690a9186736f194a8..52a9be41250deae36aa604664b296563ce0fcf7f 100644 (file)
 #define PR_SET_NAME    15              /* Set process name */
 #define PR_GET_NAME    16              /* Get process name */
 
+/* Get/set process endian */
+#define PR_GET_ENDIAN  19
+#define PR_SET_ENDIAN  20
+# define PR_ENDIAN_BIG         0
+# define PR_ENDIAN_LITTLE      1       /* True little endian mode */
+# define PR_ENDIAN_PPC_LITTLE  2       /* "PowerPC" pseudo little endian */
+
 #endif /* _LINUX_PRCTL_H */
index 0b6ec0e7936f02ebb92477dd12951169a2bc7218..12d2d753dc3bb08bb9ef9062692189c14e98a7b1 100644 (file)
 #ifndef GET_FPEXC_CTL
 # define GET_FPEXC_CTL(a,b)    (-EINVAL)
 #endif
+#ifndef GET_ENDIAN
+# define GET_ENDIAN(a,b)       (-EINVAL)
+#endif
+#ifndef SET_ENDIAN
+# define SET_ENDIAN(a,b)       (-EINVAL)
+#endif
 
 /*
  * this is where the system-wide overflow UID and GID are defined, for
@@ -2057,6 +2063,13 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
                                return -EFAULT;
                        return 0;
                }
+               case PR_GET_ENDIAN:
+                       error = GET_ENDIAN(current, arg2);
+                       break;
+               case PR_SET_ENDIAN:
+                       error = SET_ENDIAN(current, arg2);
+                       break;
+
                default:
                        error = -EINVAL;
                        break;
This page took 0.160671 seconds and 5 git commands to generate.