summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt11
-rw-r--r--Documentation/power/swsusp.txt51
-rw-r--r--Documentation/power/userland-swsusp.txt149
-rw-r--r--Documentation/power/video.txt74
-rw-r--r--Documentation/powerpc/booting-without-of.txt72
-rw-r--r--Documentation/powerpc/eeh-pci-error-recovery.txt15
-rw-r--r--Documentation/powerpc/hvcs.txt4
-rw-r--r--MAINTAINERS4
-rw-r--r--arch/cris/kernel/irq.c10
-rw-r--r--arch/frv/kernel/irq.c10
-rw-r--r--arch/i386/Kconfig24
-rw-r--r--arch/i386/Kconfig.debug9
-rw-r--r--arch/i386/kernel/Makefile2
-rw-r--r--arch/i386/kernel/alternative.c321
-rw-r--r--arch/i386/kernel/apic.c1
-rw-r--r--arch/i386/kernel/cpu/centaur.c1
-rw-r--r--arch/i386/kernel/cpu/common.c47
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k8.c4
-rw-r--r--arch/i386/kernel/cpu/intel.c12
-rw-r--r--arch/i386/kernel/cpu/intel_cacheinfo.c4
-rw-r--r--arch/i386/kernel/cpu/proc.c2
-rw-r--r--arch/i386/kernel/crash.c2
-rw-r--r--arch/i386/kernel/entry.S4
-rw-r--r--arch/i386/kernel/head.S5
-rw-r--r--arch/i386/kernel/io_apic.c25
-rw-r--r--arch/i386/kernel/kprobes.c4
-rw-r--r--arch/i386/kernel/module.c32
-rw-r--r--arch/i386/kernel/mpparse.c7
-rw-r--r--arch/i386/kernel/nmi.c6
-rw-r--r--arch/i386/kernel/process.c2
-rw-r--r--arch/i386/kernel/ptrace.c4
-rw-r--r--arch/i386/kernel/semaphore.c8
-rw-r--r--arch/i386/kernel/setup.c118
-rw-r--r--arch/i386/kernel/signal.c7
-rw-r--r--arch/i386/kernel/smpboot.c3
-rw-r--r--arch/i386/kernel/topology.c9
-rw-r--r--arch/i386/kernel/traps.c57
-rw-r--r--arch/i386/kernel/vmlinux.lds.S20
-rw-r--r--arch/i386/kernel/vsyscall-sysenter.S3
-rw-r--r--arch/i386/mach-es7000/es7000.h5
-rw-r--r--arch/i386/mach-es7000/es7000plat.c6
-rw-r--r--arch/i386/mm/fault.c210
-rw-r--r--arch/i386/mm/init.c45
-rw-r--r--arch/i386/oprofile/nmi_int.c7
-rw-r--r--arch/ia64/hp/sim/simserial.c7
-rw-r--r--arch/m32r/kernel/irq.c10
-rw-r--r--arch/m68k/bvme6000/rtc.c4
-rw-r--r--arch/mips/kernel/irq.c10
-rw-r--r--arch/mips/kernel/smp.c4
-rw-r--r--arch/mips/sgi-ip27/ip27-irq.c5
-rw-r--r--arch/parisc/kernel/smp.c25
-rw-r--r--arch/powerpc/Kconfig38
-rw-r--r--arch/powerpc/Makefile2
-rw-r--r--arch/powerpc/boot/install.sh2
-rw-r--r--arch/powerpc/boot/main.c4
-rw-r--r--arch/powerpc/configs/mpc8540_ads_defconfig721
-rw-r--r--arch/powerpc/kernel/asm-offsets.c3
-rw-r--r--arch/powerpc/kernel/cputable.c12
-rw-r--r--arch/powerpc/kernel/entry_64.S11
-rw-r--r--arch/powerpc/kernel/firmware.c25
-rw-r--r--arch/powerpc/kernel/head_44x.S2
-rw-r--r--arch/powerpc/kernel/head_64.S11
-rw-r--r--arch/powerpc/kernel/head_8xx.S2
-rw-r--r--arch/powerpc/kernel/head_booke.h363
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S6
-rw-r--r--arch/powerpc/kernel/iomap.c2
-rw-r--r--arch/powerpc/kernel/iommu.c1
-rw-r--r--arch/powerpc/kernel/irq.c37
-rw-r--r--arch/powerpc/kernel/kprobes.c5
-rw-r--r--arch/powerpc/kernel/of_device.c5
-rw-r--r--arch/powerpc/kernel/pci_iommu.c1
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c1
-rw-r--r--arch/powerpc/kernel/process.c9
-rw-r--r--arch/powerpc/kernel/prom.c4
-rw-r--r--arch/powerpc/kernel/ptrace-common.h2
-rw-r--r--arch/powerpc/kernel/rtas-proc.c1
-rw-r--r--arch/powerpc/kernel/rtas_pci.c2
-rw-r--r--arch/powerpc/kernel/setup-common.c5
-rw-r--r--arch/powerpc/kernel/setup_32.c5
-rw-r--r--arch/powerpc/kernel/setup_64.c2
-rw-r--r--arch/powerpc/kernel/signal_64.c2
-rw-r--r--arch/powerpc/kernel/smp.c4
-rw-r--r--arch/powerpc/kernel/time.c241
-rw-r--r--arch/powerpc/kernel/vdso.c2
-rw-r--r--arch/powerpc/lib/copypage_64.S2
-rw-r--r--arch/powerpc/lib/copyuser_64.S2
-rw-r--r--arch/powerpc/lib/e2a.c14
-rw-r--r--arch/powerpc/lib/memcpy_64.S2
-rw-r--r--arch/powerpc/lib/rheap.c2
-rw-r--r--arch/powerpc/mm/fault.c2
-rw-r--r--arch/powerpc/mm/hash_low_32.S2
-rw-r--r--arch/powerpc/mm/hash_utils_64.c32
-rw-r--r--arch/powerpc/mm/init_64.c48
-rw-r--r--arch/powerpc/mm/lmb.c16
-rw-r--r--arch/powerpc/mm/mem.c3
-rw-r--r--arch/powerpc/mm/mmap.c2
-rw-r--r--arch/powerpc/mm/numa.c160
-rw-r--r--arch/powerpc/mm/slb_low.S2
-rw-r--r--arch/powerpc/mm/stab.c4
-rw-r--r--arch/powerpc/mm/tlb_64.c2
-rw-r--r--arch/powerpc/oprofile/op_model_power4.c3
-rw-r--r--arch/powerpc/platforms/83xx/Makefile4
-rw-r--r--arch/powerpc/platforms/83xx/misc.c55
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_sys.c89
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_sys.h2
-rw-r--r--arch/powerpc/platforms/83xx/mpc83xx.h5
-rw-r--r--arch/powerpc/platforms/83xx/pci.c21
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig74
-rw-r--r--arch/powerpc/platforms/85xx/Makefile6
-rw-r--r--arch/powerpc/platforms/85xx/misc.c31
-rw-r--r--arch/powerpc/platforms/85xx/mpc8540_ads.h36
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx.h18
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ads.c244
-rw-r--r--arch/powerpc/platforms/85xx/pci.c96
-rw-r--r--arch/powerpc/platforms/Makefile2
-rw-r--r--arch/powerpc/platforms/chrp/pegasos_eth.c2
-rw-r--r--arch/powerpc/platforms/chrp/setup.c2
-rw-r--r--arch/powerpc/platforms/chrp/time.c2
-rw-r--r--arch/powerpc/platforms/iseries/mf.c112
-rw-r--r--arch/powerpc/platforms/iseries/setup.c72
-rw-r--r--arch/powerpc/platforms/maple/time.c2
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_32.c2
-rw-r--r--arch/powerpc/platforms/powermac/feature.c2
-rw-r--r--arch/powerpc/platforms/powermac/nvram.c2
-rw-r--r--arch/powerpc/platforms/powermac/setup.c8
-rw-r--r--arch/powerpc/platforms/powermac/smp.c4
-rw-r--r--arch/powerpc/platforms/pseries/Makefile3
-rw-r--r--arch/powerpc/platforms/pseries/firmware.c103
-rw-r--r--arch/powerpc/platforms/pseries/firmware.h17
-rw-r--r--arch/powerpc/platforms/pseries/hvCall.S2
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c4
-rw-r--r--arch/powerpc/platforms/pseries/pci.c2
-rw-r--r--arch/powerpc/platforms/pseries/setup.c67
-rw-r--r--arch/powerpc/platforms/pseries/smp.c2
-rw-r--r--arch/powerpc/platforms/pseries/xics.c3
-rw-r--r--arch/powerpc/sysdev/dart_iommu.c2
-rw-r--r--arch/powerpc/sysdev/dcr.S2
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c292
-rw-r--r--arch/powerpc/sysdev/ipic.h2
-rw-r--r--arch/powerpc/xmon/xmon.c30
-rw-r--r--arch/ppc/4xx_io/serial_sicc.c5
-rw-r--r--arch/ppc/8xx_io/commproc.c6
-rw-r--r--arch/ppc/Kconfig47
-rw-r--r--arch/ppc/Kconfig.debug2
-rw-r--r--arch/ppc/amiga/amiints.c2
-rw-r--r--arch/ppc/amiga/bootinfo.c2
-rw-r--r--arch/ppc/amiga/cia.c2
-rw-r--r--arch/ppc/amiga/config.c2
-rw-r--r--arch/ppc/amiga/ints.c2
-rw-r--r--arch/ppc/boot/Makefile3
-rw-r--r--arch/ppc/boot/common/Makefile3
-rw-r--r--arch/ppc/boot/common/bootinfo.c2
-rw-r--r--arch/ppc/boot/common/misc-common.c2
-rw-r--r--arch/ppc/boot/common/ns16550.c3
-rw-r--r--arch/ppc/boot/common/serial_stub.c2
-rw-r--r--arch/ppc/boot/common/util.S2
-rw-r--r--arch/ppc/boot/include/mpc10x.h2
-rw-r--r--arch/ppc/boot/simple/Makefile1
-rw-r--r--arch/ppc/boot/simple/cpc700_memory.c2
-rw-r--r--arch/ppc/boot/simple/embed_config.c7
-rw-r--r--arch/ppc/boot/simple/head.S9
-rw-r--r--arch/ppc/boot/simple/misc-chestnut.c2
-rw-r--r--arch/ppc/boot/simple/misc-cpci690.c2
-rw-r--r--arch/ppc/boot/simple/misc-ev64260.c2
-rw-r--r--arch/ppc/boot/simple/misc-ev64360.c1
-rw-r--r--arch/ppc/boot/simple/misc-katana.c2
-rw-r--r--arch/ppc/boot/simple/misc-mv64x60.c2
-rw-r--r--arch/ppc/boot/simple/misc-prep.c2
-rw-r--r--arch/ppc/boot/simple/misc-radstone_ppc7d.c2
-rw-r--r--arch/ppc/boot/simple/misc-spruce.c2
-rw-r--r--arch/ppc/boot/simple/misc.c2
-rw-r--r--arch/ppc/boot/simple/mpc10x_memory.c2
-rw-r--r--arch/ppc/boot/simple/mpc52xx_tty.c2
-rw-r--r--arch/ppc/boot/simple/mv64x60_tty.c2
-rw-r--r--arch/ppc/boot/simple/openbios.c2
-rw-r--r--arch/ppc/boot/simple/relocate.S2
-rw-r--r--arch/ppc/boot/utils/mkbugboot.c2
-rw-r--r--arch/ppc/configs/ml300_defconfig739
-rw-r--r--arch/ppc/configs/ml403_defconfig740
-rw-r--r--arch/ppc/kernel/head_44x.S2
-rw-r--r--arch/ppc/kernel/head_8xx.S2
-rw-r--r--arch/ppc/kernel/head_fsl_booke.S6
-rw-r--r--arch/ppc/kernel/setup.c10
-rw-r--r--arch/ppc/kernel/smp-tbsync.c3
-rw-r--r--arch/ppc/kernel/traps.c2
-rw-r--r--arch/ppc/lib/rheap.c2
-rw-r--r--arch/ppc/math-emu/math.c2
-rw-r--r--arch/ppc/mm/44x_mmu.c4
-rw-r--r--arch/ppc/mm/fault.c2
-rw-r--r--arch/ppc/mm/hashtable.S2
-rw-r--r--arch/ppc/platforms/4xx/Kconfig23
-rw-r--r--arch/ppc/platforms/4xx/Makefile4
-rw-r--r--arch/ppc/platforms/4xx/bamboo.c2
-rw-r--r--arch/ppc/platforms/4xx/bamboo.h2
-rw-r--r--arch/ppc/platforms/4xx/bubinga.h2
-rw-r--r--arch/ppc/platforms/4xx/cpci405.c2
-rw-r--r--arch/ppc/platforms/4xx/ebony.c2
-rw-r--r--arch/ppc/platforms/4xx/ebony.h2
-rw-r--r--arch/ppc/platforms/4xx/ep405.c2
-rw-r--r--arch/ppc/platforms/4xx/ep405.h2
-rw-r--r--arch/ppc/platforms/4xx/ibm405ep.c2
-rw-r--r--arch/ppc/platforms/4xx/ibm405ep.h2
-rw-r--r--arch/ppc/platforms/4xx/ibm405gp.h2
-rw-r--r--arch/ppc/platforms/4xx/ibm405gpr.c2
-rw-r--r--arch/ppc/platforms/4xx/ibm405gpr.h2
-rw-r--r--arch/ppc/platforms/4xx/ibm440ep.c2
-rw-r--r--arch/ppc/platforms/4xx/ibm440ep.h2
-rw-r--r--arch/ppc/platforms/4xx/ibm440gp.c2
-rw-r--r--arch/ppc/platforms/4xx/ibm440gp.h2
-rw-r--r--arch/ppc/platforms/4xx/ibm440gx.c2
-rw-r--r--arch/ppc/platforms/4xx/ibm440gx.h2
-rw-r--r--arch/ppc/platforms/4xx/ibm440sp.c2
-rw-r--r--arch/ppc/platforms/4xx/ibm440sp.h2
-rw-r--r--arch/ppc/platforms/4xx/ibmnp405h.c2
-rw-r--r--arch/ppc/platforms/4xx/ibmnp405h.h2
-rw-r--r--arch/ppc/platforms/4xx/ibmstb4.c2
-rw-r--r--arch/ppc/platforms/4xx/ibmstb4.h2
-rw-r--r--arch/ppc/platforms/4xx/ibmstbx25.c2
-rw-r--r--arch/ppc/platforms/4xx/ibmstbx25.h2
-rw-r--r--arch/ppc/platforms/4xx/luan.c2
-rw-r--r--arch/ppc/platforms/4xx/luan.h2
-rw-r--r--arch/ppc/platforms/4xx/ocotea.c2
-rw-r--r--arch/ppc/platforms/4xx/ocotea.h2
-rw-r--r--arch/ppc/platforms/4xx/ppc440spe.c2
-rw-r--r--arch/ppc/platforms/4xx/ppc440spe.h2
-rw-r--r--arch/ppc/platforms/4xx/redwood5.c2
-rw-r--r--arch/ppc/platforms/4xx/redwood5.h2
-rw-r--r--arch/ppc/platforms/4xx/redwood6.c2
-rw-r--r--arch/ppc/platforms/4xx/redwood6.h2
-rw-r--r--arch/ppc/platforms/4xx/sycamore.c2
-rw-r--r--arch/ppc/platforms/4xx/sycamore.h2
-rw-r--r--arch/ppc/platforms/4xx/virtex-ii_pro.c60
-rw-r--r--arch/ppc/platforms/4xx/virtex-ii_pro.h99
-rw-r--r--arch/ppc/platforms/4xx/virtex.c56
-rw-r--r--arch/ppc/platforms/4xx/virtex.h35
-rw-r--r--arch/ppc/platforms/4xx/walnut.c2
-rw-r--r--arch/ppc/platforms/4xx/walnut.h2
-rw-r--r--arch/ppc/platforms/4xx/xilinx_ml300.c76
-rw-r--r--arch/ppc/platforms/4xx/xilinx_ml300.h6
-rw-r--r--arch/ppc/platforms/4xx/xilinx_ml403.c177
-rw-r--r--arch/ppc/platforms/4xx/xilinx_ml403.h49
-rw-r--r--arch/ppc/platforms/4xx/xparameters/xparameters.h37
-rw-r--r--arch/ppc/platforms/4xx/xparameters/xparameters_ml403.h243
-rw-r--r--arch/ppc/platforms/4xx/yucca.c2
-rw-r--r--arch/ppc/platforms/4xx/yucca.h2
-rw-r--r--arch/ppc/platforms/83xx/mpc834x_sys.c2
-rw-r--r--arch/ppc/platforms/83xx/mpc834x_sys.h4
-rw-r--r--arch/ppc/platforms/85xx/mpc8540_ads.c2
-rw-r--r--arch/ppc/platforms/85xx/mpc8540_ads.h2
-rw-r--r--arch/ppc/platforms/85xx/mpc8555_cds.h2
-rw-r--r--arch/ppc/platforms/85xx/mpc8560_ads.c2
-rw-r--r--arch/ppc/platforms/85xx/mpc8560_ads.h2
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_ads_common.c2
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_ads_common.h2
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_cds_common.c2
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_cds_common.h2
-rw-r--r--arch/ppc/platforms/85xx/sbc8560.c2
-rw-r--r--arch/ppc/platforms/85xx/sbc8560.h2
-rw-r--r--arch/ppc/platforms/85xx/sbc85xx.c2
-rw-r--r--arch/ppc/platforms/85xx/sbc85xx.h2
-rw-r--r--arch/ppc/platforms/85xx/stx_gp3.c2
-rw-r--r--arch/ppc/platforms/85xx/stx_gp3.h2
-rw-r--r--arch/ppc/platforms/85xx/tqm85xx.c2
-rw-r--r--arch/ppc/platforms/85xx/tqm85xx.h2
-rw-r--r--arch/ppc/platforms/Makefile3
-rw-r--r--arch/ppc/platforms/apus_setup.c2
-rw-r--r--arch/ppc/platforms/chestnut.c2
-rw-r--r--arch/ppc/platforms/chestnut.h2
-rw-r--r--arch/ppc/platforms/chrp_pegasos_eth.c2
-rw-r--r--arch/ppc/platforms/chrp_setup.c2
-rw-r--r--arch/ppc/platforms/chrp_time.c2
-rw-r--r--arch/ppc/platforms/cpci690.c4
-rw-r--r--arch/ppc/platforms/cpci690.h2
-rw-r--r--arch/ppc/platforms/ev64260.c4
-rw-r--r--arch/ppc/platforms/ev64260.h2
-rw-r--r--arch/ppc/platforms/ev64360.c4
-rw-r--r--arch/ppc/platforms/ev64360.h2
-rw-r--r--arch/ppc/platforms/fads.h2
-rw-r--r--arch/ppc/platforms/gemini.h3
-rw-r--r--arch/ppc/platforms/gemini_prom.S2
-rw-r--r--arch/ppc/platforms/gemini_setup.c2
-rw-r--r--arch/ppc/platforms/hdpu.c5
-rw-r--r--arch/ppc/platforms/hdpu.h2
-rw-r--r--arch/ppc/platforms/katana.c7
-rw-r--r--arch/ppc/platforms/katana.h2
-rw-r--r--arch/ppc/platforms/lite5200.c2
-rw-r--r--arch/ppc/platforms/lite5200.h2
-rw-r--r--arch/ppc/platforms/lopec.c2
-rw-r--r--arch/ppc/platforms/mpc8272ads_setup.c236
-rw-r--r--arch/ppc/platforms/mpc866ads_setup.c273
-rw-r--r--arch/ppc/platforms/mpc885ads_setup.c389
-rw-r--r--arch/ppc/platforms/mvme5100.c2
-rw-r--r--arch/ppc/platforms/pal4.h2
-rw-r--r--arch/ppc/platforms/pal4_pci.c2
-rw-r--r--arch/ppc/platforms/pal4_serial.h2
-rw-r--r--arch/ppc/platforms/pal4_setup.c2
-rw-r--r--arch/ppc/platforms/powerpmc250.c2
-rw-r--r--arch/ppc/platforms/pplus.c2
-rw-r--r--arch/ppc/platforms/pplus.h2
-rw-r--r--arch/ppc/platforms/pq2ads.c2
-rw-r--r--arch/ppc/platforms/pq2ads.h4
-rw-r--r--arch/ppc/platforms/pq2ads_pd.h114
-rw-r--r--arch/ppc/platforms/prep_setup.c2
-rw-r--r--arch/ppc/platforms/prpmc750.c2
-rw-r--r--arch/ppc/platforms/prpmc800.c2
-rw-r--r--arch/ppc/platforms/radstone_ppc7d.c7
-rw-r--r--arch/ppc/platforms/radstone_ppc7d.h2
-rw-r--r--arch/ppc/platforms/sandpoint.c2
-rw-r--r--arch/ppc/platforms/sandpoint.h2
-rw-r--r--arch/ppc/platforms/sbc82xx.c2
-rw-r--r--arch/ppc/platforms/spruce.c2
-rw-r--r--arch/ppc/platforms/tqm8260_setup.c2
-rw-r--r--arch/ppc/syslib/Makefile4
-rw-r--r--arch/ppc/syslib/cpc700.h2
-rw-r--r--arch/ppc/syslib/cpc700_pic.c2
-rw-r--r--arch/ppc/syslib/cpc710.h2
-rw-r--r--arch/ppc/syslib/gen550.h2
-rw-r--r--arch/ppc/syslib/gen550_dbg.c2
-rw-r--r--arch/ppc/syslib/gen550_kgdb.c2
-rw-r--r--arch/ppc/syslib/gt64260_pic.c2
-rw-r--r--arch/ppc/syslib/harrier.c2
-rw-r--r--arch/ppc/syslib/hawk_common.c2
-rw-r--r--arch/ppc/syslib/ibm440gp_common.c2
-rw-r--r--arch/ppc/syslib/ibm440gp_common.h2
-rw-r--r--arch/ppc/syslib/ibm440gx_common.c2
-rw-r--r--arch/ppc/syslib/ibm440gx_common.h2
-rw-r--r--arch/ppc/syslib/ibm440sp_common.c2
-rw-r--r--arch/ppc/syslib/ibm440sp_common.h2
-rw-r--r--arch/ppc/syslib/ibm44x_common.c2
-rw-r--r--arch/ppc/syslib/ibm44x_common.h2
-rw-r--r--arch/ppc/syslib/m8260_pci_erratum9.c2
-rw-r--r--arch/ppc/syslib/m8260_setup.c2
-rw-r--r--arch/ppc/syslib/m8xx_setup.c65
-rw-r--r--arch/ppc/syslib/m8xx_wdt.c3
-rw-r--r--arch/ppc/syslib/mpc10x_common.c2
-rw-r--r--arch/ppc/syslib/mpc52xx_devices.c2
-rw-r--r--arch/ppc/syslib/mpc52xx_pci.c2
-rw-r--r--arch/ppc/syslib/mpc52xx_pci.h2
-rw-r--r--arch/ppc/syslib/mpc52xx_pic.c2
-rw-r--r--arch/ppc/syslib/mpc52xx_setup.c2
-rw-r--r--arch/ppc/syslib/mpc52xx_sys.c2
-rw-r--r--arch/ppc/syslib/mpc83xx_devices.c2
-rw-r--r--arch/ppc/syslib/mpc83xx_sys.c2
-rw-r--r--arch/ppc/syslib/mpc85xx_devices.c2
-rw-r--r--arch/ppc/syslib/mpc85xx_sys.c2
-rw-r--r--arch/ppc/syslib/mpc8xx_devices.c2
-rw-r--r--arch/ppc/syslib/mpc8xx_sys.c2
-rw-r--r--arch/ppc/syslib/mv64360_pic.c2
-rw-r--r--arch/ppc/syslib/mv64x60.c2
-rw-r--r--arch/ppc/syslib/mv64x60_dbg.c2
-rw-r--r--arch/ppc/syslib/mv64x60_win.c2
-rw-r--r--arch/ppc/syslib/ocp.c3
-rw-r--r--arch/ppc/syslib/open_pic.c2
-rw-r--r--arch/ppc/syslib/open_pic2.c2
-rw-r--r--arch/ppc/syslib/open_pic_defs.h2
-rw-r--r--arch/ppc/syslib/pci_auto.c2
-rw-r--r--arch/ppc/syslib/ppc4xx_dma.c2
-rw-r--r--arch/ppc/syslib/ppc4xx_pic.c2
-rw-r--r--arch/ppc/syslib/ppc4xx_pm.c47
-rw-r--r--arch/ppc/syslib/ppc4xx_sgdma.c2
-rw-r--r--arch/ppc/syslib/ppc83xx_setup.c2
-rw-r--r--arch/ppc/syslib/ppc83xx_setup.h2
-rw-r--r--arch/ppc/syslib/ppc85xx_common.c2
-rw-r--r--arch/ppc/syslib/ppc85xx_common.h2
-rw-r--r--arch/ppc/syslib/ppc85xx_setup.c2
-rw-r--r--arch/ppc/syslib/ppc85xx_setup.h2
-rw-r--r--arch/ppc/syslib/ppc_sys.c179
-rw-r--r--arch/ppc/syslib/pq2_devices.c2
-rw-r--r--arch/ppc/syslib/pq2_sys.c2
-rw-r--r--arch/ppc/syslib/prep_nvram.c2
-rw-r--r--arch/ppc/syslib/todc_time.c2
-rw-r--r--arch/ppc/syslib/xilinx_pic.c4
-rw-r--r--arch/s390/kernel/smp.c4
-rw-r--r--arch/sh/kernel/irq.c5
-rw-r--r--arch/sh/kernel/setup.c5
-rw-r--r--arch/sh64/kernel/irq.c5
-rw-r--r--arch/sparc/kernel/irq.c5
-rw-r--r--arch/sparc/kernel/smp.c24
-rw-r--r--arch/sparc/kernel/sun4d_irq.c8
-rw-r--r--arch/sparc/kernel/sun4d_smp.c8
-rw-r--r--arch/sparc/kernel/sun4m_smp.c6
-rw-r--r--arch/sparc64/kernel/irq.c4
-rw-r--r--arch/sparc64/kernel/smp.c30
-rw-r--r--arch/sparc64/mm/init.c4
-rw-r--r--arch/um/kernel/um_arch.c12
-rw-r--r--arch/x86_64/kernel/early_printk.c26
-rw-r--r--arch/x86_64/kernel/irq.c21
-rw-r--r--arch/x86_64/kernel/kprobes.c4
-rw-r--r--arch/x86_64/kernel/nmi.c4
-rw-r--r--arch/x86_64/kernel/signal.c4
-rw-r--r--arch/xtensa/kernel/irq.c15
-rw-r--r--arch/xtensa/platform-iss/console.c4
-rw-r--r--block/ioctl.c22
-rw-r--r--drivers/base/power/suspend.c5
-rw-r--r--drivers/block/cciss.c2
-rw-r--r--drivers/block/floppy.c17
-rw-r--r--drivers/block/loop.c18
-rw-r--r--drivers/block/nbd.c16
-rw-r--r--drivers/block/pktcdvd.c27
-rw-r--r--drivers/block/rd.c4
-rw-r--r--drivers/cdrom/cdrom.c874
-rw-r--r--drivers/cdrom/cdu31a.c8
-rw-r--r--drivers/cdrom/cm206.c44
-rw-r--r--drivers/cdrom/sbpcd.c710
-rw-r--r--drivers/cdrom/viocd.c2
-rw-r--r--drivers/char/Kconfig2
-rw-r--r--drivers/char/amiserial.c18
-rw-r--r--drivers/char/generic_serial.c14
-rw-r--r--drivers/char/hvcs.c9
-rw-r--r--drivers/char/istallion.c1
-rw-r--r--drivers/char/n_tty.c10
-rw-r--r--drivers/char/nwflash.c11
-rw-r--r--drivers/char/raw.c23
-rw-r--r--drivers/char/ser_a2232.c4
-rw-r--r--drivers/char/snsc.c8
-rw-r--r--drivers/char/snsc_event.c5
-rw-r--r--drivers/char/stallion.c1
-rw-r--r--drivers/char/sx.c2
-rw-r--r--drivers/char/tty_io.c50
-rw-r--r--drivers/char/vme_scc.c2
-rw-r--r--drivers/char/vt.c22
-rw-r--r--drivers/char/watchdog/pcwd_usb.c7
-rw-r--r--drivers/connector/connector.c15
-rw-r--r--drivers/firmware/dcdbas.c23
-rw-r--r--drivers/ide/ide-cd.c110
-rw-r--r--drivers/ide/ide-disk.c11
-rw-r--r--drivers/ide/ide-floppy.c11
-rw-r--r--drivers/ide/ide-tape.c19
-rw-r--r--drivers/isdn/capi/kcapi.c17
-rw-r--r--drivers/isdn/hisax/config.c1
-rw-r--r--drivers/isdn/hisax/elsa.c1
-rw-r--r--drivers/macintosh/macio_asic.c5
-rw-r--r--drivers/macintosh/smu.c4
-rw-r--r--drivers/macintosh/therm_pm72.c2
-rw-r--r--drivers/macintosh/via-pmu.c5
-rw-r--r--drivers/macintosh/windfarm_lm75_sensor.c1
-rw-r--r--drivers/macintosh/windfarm_max6690_sensor.c1
-rw-r--r--drivers/macintosh/windfarm_smu_sat.c1
-rw-r--r--drivers/net/Kconfig1
-rw-r--r--drivers/net/loopback.c4
-rw-r--r--drivers/net/ppp_generic.c25
-rw-r--r--drivers/oprofile/cpu_buffer.c3
-rw-r--r--drivers/pnp/pnpbios/rsparser.c6
-rw-r--r--drivers/s390/block/dasd_ioctl.c8
-rw-r--r--drivers/scsi/ide-scsi.c11
-rw-r--r--drivers/scsi/sr.c37
-rw-r--r--drivers/scsi/sr.h1
-rw-r--r--drivers/scsi/sr_ioctl.c19
-rw-r--r--drivers/serial/68328serial.c9
-rw-r--r--drivers/serial/au1x00_uart.c11
-rw-r--r--drivers/serial/crisv10.c68
-rw-r--r--drivers/serial/m32r_sio.c15
-rw-r--r--drivers/serial/sunsu.c13
-rw-r--r--drivers/tc/zs.c9
-rw-r--r--fs/9p/mux.c11
-rw-r--r--fs/adfs/file.c4
-rw-r--r--fs/autofs4/autofs_i.h3
-rw-r--r--fs/autofs4/inode.c2
-rw-r--r--fs/autofs4/waitq.c16
-rw-r--r--fs/bio.c8
-rw-r--r--fs/block_dev.c28
-rw-r--r--fs/buffer.c6
-rw-r--r--fs/cifs/dir.c8
-rw-r--r--fs/cifs/fcntl.c4
-rw-r--r--fs/cifs/file.c4
-rw-r--r--fs/cifs/inode.c16
-rw-r--r--fs/cifs/link.c16
-rw-r--r--fs/cifs/readdir.c4
-rw-r--r--fs/cifs/xattr.c16
-rw-r--r--fs/devpts/inode.c76
-rw-r--r--fs/dquot.c167
-rw-r--r--fs/eventpoll.c32
-rw-r--r--fs/ext2/namei.c54
-rw-r--r--fs/ext3/dir.c52
-rw-r--r--fs/ext3/file.c4
-rw-r--r--fs/ext3/inode.c16
-rw-r--r--fs/ext3/ioctl.c4
-rw-r--r--fs/ext3/super.c6
-rw-r--r--fs/fat/fatent.c6
-rw-r--r--fs/fcntl.c9
-rw-r--r--fs/file.c34
-rw-r--r--fs/file_table.c10
-rw-r--r--fs/hpfs/hpfs_fn.h5
-rw-r--r--fs/hpfs/inode.c10
-rw-r--r--fs/hpfs/namei.c60
-rw-r--r--fs/hpfs/super.c4
-rw-r--r--fs/inode.c18
-rw-r--r--fs/inotify.c116
-rw-r--r--fs/jbd/checkpoint.c4
-rw-r--r--fs/jbd/journal.c4
-rw-r--r--fs/jbd/transaction.c4
-rw-r--r--fs/jffs/inode-v23.c86
-rw-r--r--fs/jffs/intrep.c6
-rw-r--r--fs/jffs/jffs_fm.c2
-rw-r--r--fs/jffs/jffs_fm.h5
-rw-r--r--fs/libfs.c14
-rw-r--r--fs/minix/namei.c48
-rw-r--r--fs/namei.c12
-rw-r--r--fs/ncpfs/file.c4
-rw-r--r--fs/ncpfs/inode.c6
-rw-r--r--fs/ncpfs/ncplib_kernel.c4
-rw-r--r--fs/ncpfs/sock.c34
-rw-r--r--fs/open.c8
-rw-r--r--fs/proc/proc_misc.c2
-rw-r--r--fs/qnx4/file.c3
-rw-r--r--fs/quota.c6
-rw-r--r--fs/quota_v2.c2
-rw-r--r--fs/ramfs/file-mmu.c11
-rw-r--r--fs/seq_file.c10
-rw-r--r--fs/super.c10
-rw-r--r--fs/sysv/namei.c48
-rw-r--r--fs/udf/balloc.c36
-rw-r--r--fs/udf/ialloc.c8
-rw-r--r--fs/udf/super.c2
-rw-r--r--fs/ufs/file.c10
-rw-r--r--fs/ufs/namei.c48
-rw-r--r--fs/xfs/linux-2.6/xfs_stats.c7
-rw-r--r--fs/xfs/linux-2.6/xfs_sysctl.c3
-rw-r--r--include/asm-alpha/mmu_context.h5
-rw-r--r--include/asm-alpha/topology.h4
-rw-r--r--include/asm-generic/bug.h4
-rw-r--r--include/asm-generic/percpu.h7
-rw-r--r--include/asm-i386/alternative.h129
-rw-r--r--include/asm-i386/arch_hooks.h3
-rw-r--r--include/asm-i386/atomic.h36
-rw-r--r--include/asm-i386/bitops.h7
-rw-r--r--include/asm-i386/cache.h2
-rw-r--r--include/asm-i386/cpufeature.h1
-rw-r--r--include/asm-i386/mach-default/do_timer.h2
-rw-r--r--include/asm-i386/mach-es7000/mach_mpparse.h10
-rw-r--r--include/asm-i386/mach-visws/do_timer.h2
-rw-r--r--include/asm-i386/mach-voyager/do_timer.h2
-rw-r--r--include/asm-i386/mpspec.h1
-rw-r--r--include/asm-i386/mtrr.h1
-rw-r--r--include/asm-i386/mutex.h6
-rw-r--r--include/asm-i386/pgtable-2level.h2
-rw-r--r--include/asm-i386/pgtable-3level.h2
-rw-r--r--include/asm-i386/rwlock.h56
-rw-r--r--include/asm-i386/semaphore.h8
-rw-r--r--include/asm-i386/spinlock.h34
-rw-r--r--include/asm-i386/system.h62
-rw-r--r--include/asm-i386/uaccess.h12
-rw-r--r--include/asm-i386/unistd.h36
-rw-r--r--include/asm-ia64/atomic.h8
-rw-r--r--include/asm-ia64/cache.h2
-rw-r--r--include/asm-m68k/atomic.h8
-rw-r--r--include/asm-parisc/cache.h2
-rw-r--r--include/asm-powerpc/atomic.h38
-rw-r--r--include/asm-powerpc/cputable.h38
-rw-r--r--include/asm-powerpc/cputime.h202
-rw-r--r--include/asm-powerpc/firmware.h16
-rw-r--r--include/asm-powerpc/irq.h6
-rw-r--r--include/asm-powerpc/iseries/mf.h7
-rw-r--r--include/asm-powerpc/lmb.h19
-rw-r--r--include/asm-powerpc/mmu.h1
-rw-r--r--include/asm-powerpc/paca.h7
-rw-r--r--include/asm-powerpc/percpu.h7
-rw-r--r--include/asm-powerpc/pgtable-4k.h11
-rw-r--r--include/asm-powerpc/pgtable.h9
-rw-r--r--include/asm-powerpc/ppc_asm.h42
-rw-r--r--include/asm-powerpc/processor.h1
-rw-r--r--include/asm-powerpc/prom.h6
-rw-r--r--include/asm-powerpc/rwsem.h2
-rw-r--r--include/asm-powerpc/synch.h2
-rw-r--r--include/asm-powerpc/system.h6
-rw-r--r--include/asm-powerpc/time.h15
-rw-r--r--include/asm-ppc/harrier.h2
-rw-r--r--include/asm-ppc/ibm44x.h2
-rw-r--r--include/asm-ppc/ibm4xx.h4
-rw-r--r--include/asm-ppc/io.h7
-rw-r--r--include/asm-ppc/mpc10x.h3
-rw-r--r--include/asm-ppc/mpc52xx.h1
-rw-r--r--include/asm-ppc/mpc8260.h1
-rw-r--r--include/asm-ppc/mpc83xx.h1
-rw-r--r--include/asm-ppc/mpc85xx.h1
-rw-r--r--include/asm-ppc/mpc8xx.h3
-rw-r--r--include/asm-ppc/pgtable.h6
-rw-r--r--include/asm-ppc/ppc_sys.h34
-rw-r--r--include/asm-ppc/time.h5
-rw-r--r--include/asm-ppc/todc.h2
-rw-r--r--include/asm-ppc/xparameters.h18
-rw-r--r--include/asm-s390/atomic.h18
-rw-r--r--include/asm-s390/percpu.h7
-rw-r--r--include/asm-sparc64/atomic.h10
-rw-r--r--include/asm-sparc64/cache.h2
-rw-r--r--include/asm-sparc64/percpu.h7
-rw-r--r--include/asm-um/alternative.h6
-rw-r--r--include/asm-x86_64/atomic.h8
-rw-r--r--include/asm-x86_64/cache.h2
-rw-r--r--include/asm-x86_64/percpu.h7
-rw-r--r--include/linux/cache.h4
-rw-r--r--include/linux/cdrom.h5
-rw-r--r--include/linux/eventpoll.h8
-rw-r--r--include/linux/ext3_fs.h9
-rw-r--r--include/linux/ext3_fs_i.h7
-rw-r--r--include/linux/file.h28
-rw-r--r--include/linux/fs.h22
-rw-r--r--include/linux/generic_serial.h4
-rw-r--r--include/linux/genhd.h14
-rw-r--r--include/linux/init_task.h10
-rw-r--r--include/linux/jbd.h7
-rw-r--r--include/linux/kernel.h3
-rw-r--r--include/linux/kprobes.h3
-rw-r--r--include/linux/loop.h3
-rw-r--r--include/linux/msdos_fs.h3
-rw-r--r--include/linux/nbd.h3
-rw-r--r--include/linux/ncp_fs_i.h2
-rw-r--r--include/linux/ncp_fs_sb.h5
-rw-r--r--include/linux/pm.h3
-rw-r--r--include/linux/profile.h2
-rw-r--r--include/linux/quota.h7
-rw-r--r--include/linux/raid/raid1.h2
-rw-r--r--include/linux/rcupdate.h2
-rw-r--r--include/linux/seq_file.h4
-rw-r--r--include/linux/swap.h5
-rw-r--r--include/linux/tty.h8
-rw-r--r--include/linux/tty_flip.h12
-rw-r--r--include/linux/udf_fs_sb.h4
-rw-r--r--include/linux/vt_kern.h5
-rw-r--r--init/do_mounts_initrd.c1
-rw-r--r--init/main.c26
-rw-r--r--kernel/auditsc.c2
-rw-r--r--kernel/cpuset.c212
-rw-r--r--kernel/exit.c4
-rw-r--r--kernel/fork.c8
-rw-r--r--kernel/kprobes.c14
-rw-r--r--kernel/kthread.c7
-rw-r--r--kernel/module.c53
-rw-r--r--kernel/panic.c97
-rw-r--r--kernel/posix-timers.c1
-rw-r--r--kernel/power/Makefile2
-rw-r--r--kernel/power/disk.c20
-rw-r--r--kernel/power/main.c2
-rw-r--r--kernel/power/pm.c21
-rw-r--r--kernel/power/power.h75
-rw-r--r--kernel/power/process.c61
-rw-r--r--kernel/power/snapshot.c335
-rw-r--r--kernel/power/swap.c544
-rw-r--r--kernel/power/swsusp.c887
-rw-r--r--kernel/power/user.c333
-rw-r--r--kernel/profile.c11
-rw-r--r--kernel/rcupdate.c14
-rw-r--r--kernel/sched.c13
-rw-r--r--kernel/signal.c11
-rw-r--r--kernel/spinlock.c9
-rw-r--r--kernel/sys.c46
-rw-r--r--lib/extable.c1
-rw-r--r--lib/reed_solomon/reed_solomon.c11
-rw-r--r--mm/readahead.c1
-rw-r--r--mm/swapfile.c57
-rw-r--r--security/seclvl.c210
-rw-r--r--sound/oss/ac97_codec.c24
-rw-r--r--sound/oss/aci.c11
-rw-r--r--sound/oss/ad1889.c7
-rw-r--r--sound/oss/ad1889.h2
-rw-r--r--sound/oss/ali5455.c8
-rw-r--r--sound/oss/au1000.c44
-rw-r--r--sound/oss/au1550_ac97.c44
-rw-r--r--sound/oss/btaudio.c36
-rw-r--r--sound/oss/cmpci.c20
-rw-r--r--sound/oss/cs4281/cs4281m.c54
-rw-r--r--sound/oss/cs46xx.c75
-rw-r--r--sound/oss/dmasound/dmasound_awacs.c10
-rw-r--r--sound/oss/emu10k1/hwaccess.h2
-rw-r--r--sound/oss/emu10k1/main.c2
-rw-r--r--sound/oss/emu10k1/midi.c14
-rw-r--r--sound/oss/es1370.c71
-rw-r--r--sound/oss/es1371.c71
-rw-r--r--sound/oss/esssolo1.c50
-rw-r--r--sound/oss/forte.c11
-rw-r--r--sound/oss/hal2.c22
-rw-r--r--sound/oss/i810_audio.c8
-rw-r--r--sound/oss/ite8172.c20
-rw-r--r--sound/oss/maestro.c26
-rw-r--r--sound/oss/maestro3.c20
-rw-r--r--sound/oss/nec_vrc5477.c20
-rw-r--r--sound/oss/rme96xx.c17
-rw-r--r--sound/oss/sonicvibes.c48
-rw-r--r--sound/oss/swarm_cs4297a.c39
-rw-r--r--sound/oss/trident.c62
-rw-r--r--sound/oss/via82cxxx_audio.c49
-rw-r--r--sound/oss/vwsnd.c61
-rw-r--r--sound/oss/ymfpci.c14
-rw-r--r--sound/oss/ymfpci.h3
684 files changed, 12361 insertions, 5728 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index fc99075e0af4..7b7382d0f758 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1008,7 +1008,9 @@ running once the system is up.
noexec=on: enable non-executable mappings (default)
noexec=off: disable nn-executable mappings
- nofxsr [BUGS=IA-32]
+ nofxsr [BUGS=IA-32] Disables x86 floating point extended
+ register save and restore. The kernel will only save
+ legacy floating-point registers on task switch.
nohlt [BUGS=ARM]
@@ -1053,6 +1055,8 @@ running once the system is up.
nosbagart [IA-64]
+ nosep [BUGS=IA-32] Disables x86 SYSENTER/SYSEXIT support.
+
nosmp [SMP] Tells an SMP kernel to act as a UP kernel.
nosync [HW,M68K] Disables sync negotiation for all devices.
@@ -1122,6 +1126,11 @@ running once the system is up.
pas16= [HW,SCSI]
See header of drivers/scsi/pas16.c.
+ pause_on_oops=
+ Halt all CPUs after the first oops has been printed for
+ the specified number of seconds. This is to be used if
+ your oopses keep scrolling off the screen.
+
pcbit= [HW,ISDN]
pcd. [PARIDE]
diff --git a/Documentation/power/swsusp.txt b/Documentation/power/swsusp.txt
index b28b7f04abb8..d7814a113ee1 100644
--- a/Documentation/power/swsusp.txt
+++ b/Documentation/power/swsusp.txt
@@ -17,6 +17,11 @@ Some warnings, first.
* but it will probably only crash.
*
* (*) suspend/resume support is needed to make it safe.
+ *
+ * If you have any filesystems on USB devices mounted before suspend,
+ * they won't be accessible after resume and you may lose data, as though
+ * you have unplugged the USB devices with mounted filesystems on them
+ * (see the FAQ below for details).
You need to append resume=/dev/your_swap_partition to kernel command
line. Then you suspend by
@@ -27,19 +32,18 @@ echo shutdown > /sys/power/disk; echo disk > /sys/power/state
echo platform > /sys/power/disk; echo disk > /sys/power/state
+. If you have SATA disks, you'll need recent kernels with SATA suspend
+support. For suspend and resume to work, make sure your disk drivers
+are built into kernel -- not modules. [There's way to make
+suspend/resume with modular disk drivers, see FAQ, but you probably
+should not do that.]
+
If you want to limit the suspend image size to N bytes, do
echo N > /sys/power/image_size
before suspend (it is limited to 500 MB by default).
-Encrypted suspend image:
-------------------------
-If you want to store your suspend image encrypted with a temporary
-key to prevent data gathering after resume you must compile
-crypto and the aes algorithm into the kernel - modules won't work
-as they cannot be loaded at resume time.
-
Article about goals and implementation of Software Suspend for Linux
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -333,4 +337,37 @@ init=/bin/bash, then swapon and starting suspend sequence manually
usually does the trick. Then it is good idea to try with latest
vanilla kernel.
+Q: How can distributions ship a swsusp-supporting kernel with modular
+disk drivers (especially SATA)?
+
+A: Well, it can be done, load the drivers, then do echo into
+/sys/power/disk/resume file from initrd. Be sure not to mount
+anything, not even read-only mount, or you are going to lose your
+data.
+
+Q: How do I make suspend more verbose?
+
+A: If you want to see any non-error kernel messages on the virtual
+terminal the kernel switches to during suspend, you have to set the
+kernel console loglevel to at least 5, for example by doing
+
+ echo 5 > /proc/sys/kernel/printk
+
+Q: Is this true that if I have a mounted filesystem on a USB device and
+I suspend to disk, I can lose data unless the filesystem has been mounted
+with "sync"?
+
+A: That's right. It depends on your hardware, and it could be true even for
+suspend-to-RAM. In fact, even with "-o sync" you can lose data if your
+programs have information in buffers they haven't written out to disk.
+
+If you're lucky, your hardware will support low-power modes for USB
+controllers while the system is asleep. Lots of hardware doesn't,
+however. Shutting off the power to a USB controller is equivalent to
+unplugging all the attached devices.
+
+Remember that it's always a bad idea to unplug a disk drive containing a
+mounted filesystem. With USB that's true even when your system is asleep!
+The safest thing is to unmount all USB-based filesystems before suspending
+and remount them after resuming.
diff --git a/Documentation/power/userland-swsusp.txt b/Documentation/power/userland-swsusp.txt
new file mode 100644
index 000000000000..94058220aaf0
--- /dev/null
+++ b/Documentation/power/userland-swsusp.txt
@@ -0,0 +1,149 @@
+Documentation for userland software suspend interface
+ (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
+
+First, the warnings at the beginning of swsusp.txt still apply.
+
+Second, you should read the FAQ in swsusp.txt _now_ if you have not
+done it already.
+
+Now, to use the userland interface for software suspend you need special
+utilities that will read/write the system memory snapshot from/to the
+kernel. Such utilities are available, for example, from
+<http://www.sisk.pl/kernel/utilities/suspend>. You may want to have
+a look at them if you are going to develop your own suspend/resume
+utilities.
+
+The interface consists of a character device providing the open(),
+release(), read(), and write() operations as well as several ioctl()
+commands defined in kernel/power/power.h. The major and minor
+numbers of the device are, respectively, 10 and 231, and they can
+be read from /sys/class/misc/snapshot/dev.
+
+The device can be open either for reading or for writing. If open for
+reading, it is considered to be in the suspend mode. Otherwise it is
+assumed to be in the resume mode. The device cannot be open for reading
+and writing. It is also impossible to have the device open more than once
+at a time.
+
+The ioctl() commands recognized by the device are:
+
+SNAPSHOT_FREEZE - freeze user space processes (the current process is
+ not frozen); this is required for SNAPSHOT_ATOMIC_SNAPSHOT
+ and SNAPSHOT_ATOMIC_RESTORE to succeed
+
+SNAPSHOT_UNFREEZE - thaw user space processes frozen by SNAPSHOT_FREEZE
+
+SNAPSHOT_ATOMIC_SNAPSHOT - create a snapshot of the system memory; the
+ last argument of ioctl() should be a pointer to an int variable,
+ the value of which will indicate whether the call returned after
+ creating the snapshot (1) or after restoring the system memory state
+ from it (0) (after resume the system finds itself finishing the
+ SNAPSHOT_ATOMIC_SNAPSHOT ioctl() again); after the snapshot
+ has been created the read() operation can be used to transfer
+ it out of the kernel
+
+SNAPSHOT_ATOMIC_RESTORE - restore the system memory state from the
+ uploaded snapshot image; before calling it you should transfer
+ the system memory snapshot back to the kernel using the write()
+ operation; this call will not succeed if the snapshot
+ image is not available to the kernel
+
+SNAPSHOT_FREE - free memory allocated for the snapshot image
+
+SNAPSHOT_SET_IMAGE_SIZE - set the preferred maximum size of the image
+ (the kernel will do its best to ensure the image size will not exceed
+ this number, but if it turns out to be impossible, the kernel will
+ create the smallest image possible)
+
+SNAPSHOT_AVAIL_SWAP - return the amount of available swap in bytes (the last
+ argument should be a pointer to an unsigned int variable that will
+ contain the result if the call is successful).
+
+SNAPSHOT_GET_SWAP_PAGE - allocate a swap page from the resume partition
+ (the last argument should be a pointer to a loff_t variable that
+ will contain the swap page offset if the call is successful)
+
+SNAPSHOT_FREE_SWAP_PAGES - free all swap pages allocated with
+ SNAPSHOT_GET_SWAP_PAGE
+
+SNAPSHOT_SET_SWAP_FILE - set the resume partition (the last ioctl() argument
+ should specify the device's major and minor numbers in the old
+ two-byte format, as returned by the stat() function in the .st_rdev
+ member of the stat structure); it is recommended to always use this
+ call, because the code to set the resume partition could be removed from
+ future kernels
+
+The device's read() operation can be used to transfer the snapshot image from
+the kernel. It has the following limitations:
+- you cannot read() more than one virtual memory page at a time
+- read()s accross page boundaries are impossible (ie. if ypu read() 1/2 of
+ a page in the previous call, you will only be able to read()
+ _at_ _most_ 1/2 of the page in the next call)
+
+The device's write() operation is used for uploading the system memory snapshot
+into the kernel. It has the same limitations as the read() operation.
+
+The release() operation frees all memory allocated for the snapshot image
+and all swap pages allocated with SNAPSHOT_GET_SWAP_PAGE (if any).
+Thus it is not necessary to use either SNAPSHOT_FREE or
+SNAPSHOT_FREE_SWAP_PAGES before closing the device (in fact it will also
+unfreeze user space processes frozen by SNAPSHOT_UNFREEZE if they are
+still frozen when the device is being closed).
+
+Currently it is assumed that the userland utilities reading/writing the
+snapshot image from/to the kernel will use a swap parition, called the resume
+partition, as storage space. However, this is not really required, as they
+can use, for example, a special (blank) suspend partition or a file on a partition
+that is unmounted before SNAPSHOT_ATOMIC_SNAPSHOT and mounted afterwards.
+
+These utilities SHOULD NOT make any assumptions regarding the ordering of
+data within the snapshot image, except for the image header that MAY be
+assumed to start with an swsusp_info structure, as specified in
+kernel/power/power.h. This structure MAY be used by the userland utilities
+to obtain some information about the snapshot image, such as the size
+of the snapshot image, including the metadata and the header itself,
+contained in the .size member of swsusp_info.
+
+The snapshot image MUST be written to the kernel unaltered (ie. all of the image
+data, metadata and header MUST be written in _exactly_ the same amount, form
+and order in which they have been read). Otherwise, the behavior of the
+resumed system may be totally unpredictable.
+
+While executing SNAPSHOT_ATOMIC_RESTORE the kernel checks if the
+structure of the snapshot image is consistent with the information stored
+in the image header. If any inconsistencies are detected,
+SNAPSHOT_ATOMIC_RESTORE will not succeed. Still, this is not a fool-proof
+mechanism and the userland utilities using the interface SHOULD use additional
+means, such as checksums, to ensure the integrity of the snapshot image.
+
+The suspending and resuming utilities MUST lock themselves in memory,
+preferrably using mlockall(), before calling SNAPSHOT_FREEZE.
+
+The suspending utility MUST check the value stored by SNAPSHOT_ATOMIC_SNAPSHOT
+in the memory location pointed to by the last argument of ioctl() and proceed
+in accordance with it:
+1. If the value is 1 (ie. the system memory snapshot has just been
+ created and the system is ready for saving it):
+ (a) The suspending utility MUST NOT close the snapshot device
+ _unless_ the whole suspend procedure is to be cancelled, in
+ which case, if the snapshot image has already been saved, the
+ suspending utility SHOULD destroy it, preferrably by zapping
+ its header. If the suspend is not to be cancelled, the
+ system MUST be powered off or rebooted after the snapshot
+ image has been saved.
+ (b) The suspending utility SHOULD NOT attempt to perform any
+ file system operations (including reads) on the file systems
+ that were mounted before SNAPSHOT_ATOMIC_SNAPSHOT has been
+ called. However, it MAY mount a file system that was not
+ mounted at that time and perform some operations on it (eg.
+ use it for saving the image).
+2. If the value is 0 (ie. the system state has just been restored from
+ the snapshot image), the suspending utility MUST close the snapshot
+ device. Afterwards it will be treated as a regular userland process,
+ so it need not exit.
+
+The resuming utility SHOULD NOT attempt to mount any file systems that could
+be mounted before suspend and SHOULD NOT attempt to perform any operations
+involving such file systems.
+
+For details, please refer to the source code.
diff --git a/Documentation/power/video.txt b/Documentation/power/video.txt
index 912bed87c758..d18a57d1a531 100644
--- a/Documentation/power/video.txt
+++ b/Documentation/power/video.txt
@@ -1,7 +1,7 @@
Video issues with S3 resume
~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 2003-2005, Pavel Machek
+ 2003-2006, Pavel Machek
During S3 resume, hardware needs to be reinitialized. For most
devices, this is easy, and kernel driver knows how to do
@@ -15,6 +15,27 @@ run normally so video card is normally initialized. It should not be
problem for S1 standby, because hardware should retain its state over
that.
+We either have to run video BIOS during early resume, or interpret it
+using vbetool later, or maybe nothing is neccessary on particular
+system because video state is preserved. Unfortunately different
+methods work on different systems, and no known method suits all of
+them.
+
+Userland application called s2ram has been developed; it contains long
+whitelist of systems, and automatically selects working method for a
+given system. It can be downloaded from CVS at
+www.sf.net/projects/suspend . If you get a system that is not in the
+whitelist, please try to find a working solution, and submit whitelist
+entry so that work does not need to be repeated.
+
+Currently, VBE_SAVE method (6 below) works on most
+systems. Unfortunately, vbetool only runs after userland is resumed,
+so it makes debugging of early resume problems
+hard/impossible. Methods that do not rely on userland are preferable.
+
+Details
+~~~~~~~
+
There are a few types of systems where video works after S3 resume:
(1) systems where video state is preserved over S3.
@@ -104,6 +125,7 @@ HP NX7000 ??? (*)
HP Pavilion ZD7000 vbetool post needed, need open-source nv driver for X
HP Omnibook XE3 athlon version none (1)
HP Omnibook XE3GC none (1), video is S3 Savage/IX-MV
+HP Omnibook 5150 none (1), (S1 also works OK)
IBM TP T20, model 2647-44G none (1), video is S3 Inc. 86C270-294 Savage/IX-MV, vesafb gets "interesting" but X work.
IBM TP A31 / Type 2652-M5G s3_mode (3) [works ok with BIOS 1.04 2002-08-23, but not at all with BIOS 1.11 2004-11-05 :-(]
IBM TP R32 / Type 2658-MMG none (1)
@@ -120,18 +142,24 @@ IBM ThinkPad T42p (2373-GTG) s3_bios (2)
IBM TP X20 ??? (*)
IBM TP X30 s3_bios (2)
IBM TP X31 / Type 2672-XXH none (1), use radeontool (http://fdd.com/software/radeon/) to turn off backlight.
-IBM TP X32 none (1), but backlight is on and video is trashed after long suspend
+IBM TP X32 none (1), but backlight is on and video is trashed after long suspend. s3_bios,s3_mode (4) works too. Perhaps that gets better results?
IBM Thinkpad X40 Type 2371-7JG s3_bios,s3_mode (4)
+IBM TP 600e none(1), but a switch to console and back to X is needed
Medion MD4220 ??? (*)
Samsung P35 vbetool needed (6)
-Sharp PC-AR10 (ATI rage) none (1)
+Sharp PC-AR10 (ATI rage) none (1), backlight does not switch off
Sony Vaio PCG-C1VRX/K s3_bios (2)
Sony Vaio PCG-F403 ??? (*)
+Sony Vaio PCG-GRT995MP none (1), works with 'nv' X driver
+Sony Vaio PCG-GR7/K none (1), but needs radeonfb, use radeontool (http://fdd.com/software/radeon/) to turn off backlight.
Sony Vaio PCG-N505SN ??? (*)
Sony Vaio vgn-s260 X or boot-radeon can init it (5)
+Sony Vaio vgn-S580BH vga=normal, but suspend from X. Console will be blank unless you return to X.
+Sony Vaio vgn-FS115B s3_bios (2),s3_mode (4)
Toshiba Libretto L5 none (1)
-Toshiba Satellite 4030CDT s3_mode (3)
-Toshiba Satellite 4080XCDT s3_mode (3)
+Toshiba Portege 3020CT s3_mode (3)
+Toshiba Satellite 4030CDT s3_mode (3) (S1 also works OK)
+Toshiba Satellite 4080XCDT s3_mode (3) (S1 also works OK)
Toshiba Satellite 4090XCDT ??? (*)
Toshiba Satellite P10-554 s3_bios,s3_mode (4)(****)
Toshiba M30 (2) xor X with nvidia driver using internal AGP
@@ -151,39 +179,3 @@ Asus A7V8X nVidia RIVA TNT2 model 64 s3_bios,s3_mode (4)
(***) To be tested with a newer kernel.
(****) Not with SMP kernel, UP only.
-
-VBEtool details
-~~~~~~~~~~~~~~~
-(with thanks to Carl-Daniel Hailfinger)
-
-First, boot into X and run the following script ONCE:
-#!/bin/bash
-statedir=/root/s3/state
-mkdir -p $statedir
-chvt 2
-sleep 1
-vbetool vbestate save >$statedir/vbe
-
-
-To suspend and resume properly, call the following script as root:
-#!/bin/bash
-statedir=/root/s3/state
-curcons=`fgconsole`
-fuser /dev/tty$curcons 2>/dev/null|xargs ps -o comm= -p|grep -q X && chvt 2
-cat /dev/vcsa >$statedir/vcsa
-sync
-echo 3 >/proc/acpi/sleep
-sync
-vbetool post
-vbetool vbestate restore <$statedir/vbe
-cat $statedir/vcsa >/dev/vcsa
-rckbd restart
-chvt $[curcons%6+1]
-chvt $curcons
-
-
-Unless you change your graphics card or other hardware configuration,
-the state once saved will be OK for every resume afterwards.
-NOTE: The "rckbd restart" command may be different for your
-distribution. Simply replace it with the command you would use to
-set the fonts on screen.
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index d02c64953dcd..ee551c6ea235 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -1365,6 +1365,78 @@ platforms are moved over to use the flattened-device-tree model.
};
+ g) Freescale SOC SEC Security Engines
+
+ Required properties:
+
+ - device_type : Should be "crypto"
+ - model : Model of the device. Should be "SEC1" or "SEC2"
+ - compatible : Should be "talitos"
+ - reg : Offset and length of the register set for the device
+ - interrupts : <a b> where a is the interrupt number and b is a
+ field that represents an encoding of the sense and level
+ information for the interrupt. This should be encoded based on
+ the information in section 2) depending on the type of interrupt
+ controller you have.
+ - interrupt-parent : the phandle for the interrupt controller that
+ services interrupts for this device.
+ - num-channels : An integer representing the number of channels
+ available.
+ - channel-fifo-len : An integer representing the number of
+ descriptor pointers each channel fetch fifo can hold.
+ - exec-units-mask : The bitmask representing what execution units
+ (EUs) are available. It's a single 32 bit cell. EU information
+ should be encoded following the SEC's Descriptor Header Dword
+ EU_SEL0 field documentation, i.e. as follows:
+
+ bit 0 = reserved - should be 0
+ bit 1 = set if SEC has the ARC4 EU (AFEU)
+ bit 2 = set if SEC has the DES/3DES EU (DEU)
+ bit 3 = set if SEC has the message digest EU (MDEU)
+ bit 4 = set if SEC has the random number generator EU (RNG)
+ bit 5 = set if SEC has the public key EU (PKEU)
+ bit 6 = set if SEC has the AES EU (AESU)
+ bit 7 = set if SEC has the Kasumi EU (KEU)
+
+ bits 8 through 31 are reserved for future SEC EUs.
+
+ - descriptor-types-mask : The bitmask representing what descriptors
+ are available. It's a single 32 bit cell. Descriptor type
+ information should be encoded following the SEC's Descriptor
+ Header Dword DESC_TYPE field documentation, i.e. as follows:
+
+ bit 0 = set if SEC supports the aesu_ctr_nonsnoop desc. type
+ bit 1 = set if SEC supports the ipsec_esp descriptor type
+ bit 2 = set if SEC supports the common_nonsnoop desc. type
+ bit 3 = set if SEC supports the 802.11i AES ccmp desc. type
+ bit 4 = set if SEC supports the hmac_snoop_no_afeu desc. type
+ bit 5 = set if SEC supports the srtp descriptor type
+ bit 6 = set if SEC supports the non_hmac_snoop_no_afeu desc.type
+ bit 7 = set if SEC supports the pkeu_assemble descriptor type
+ bit 8 = set if SEC supports the aesu_key_expand_output desc.type
+ bit 9 = set if SEC supports the pkeu_ptmul descriptor type
+ bit 10 = set if SEC supports the common_nonsnoop_afeu desc. type
+ bit 11 = set if SEC supports the pkeu_ptadd_dbl descriptor type
+
+ ..and so on and so forth.
+
+ Example:
+
+ /* MPC8548E */
+ crypto@30000 {
+ device_type = "crypto";
+ model = "SEC2";
+ compatible = "talitos";
+ reg = <30000 10000>;
+ interrupts = <1d 3>;
+ interrupt-parent = <40000>;
+ num-channels = <4>;
+ channel-fifo-len = <24>;
+ exec-units-mask = <000000fe>;
+ descriptor-types-mask = <073f1127>;
+ };
+
+
More devices will be defined as this spec matures.
diff --git a/Documentation/powerpc/eeh-pci-error-recovery.txt b/Documentation/powerpc/eeh-pci-error-recovery.txt
index 67a11a36270c..3764dd4b12cb 100644
--- a/Documentation/powerpc/eeh-pci-error-recovery.txt
+++ b/Documentation/powerpc/eeh-pci-error-recovery.txt
@@ -121,7 +121,7 @@ accomplished.
EEH must be enabled in the PHB's very early during the boot process,
and if a PCI slot is hot-plugged. The former is performed by
-eeh_init() in arch/ppc64/kernel/eeh.c, and the later by
+eeh_init() in arch/powerpc/platforms/pseries/eeh.c, and the later by
drivers/pci/hotplug/pSeries_pci.c calling in to the eeh.c code.
EEH must be enabled before a PCI scan of the device can proceed.
Current Power5 hardware will not work unless EEH is enabled;
@@ -133,7 +133,7 @@ error. Given an arbitrary address, the routine
pci_get_device_by_addr() will find the pci device associated
with that address (if any).
-The default include/asm-ppc64/io.h macros readb(), inb(), insb(),
+The default include/asm-powerpc/io.h macros readb(), inb(), insb(),
etc. include a check to see if the i/o read returned all-0xff's.
If so, these make a call to eeh_dn_check_failure(), which in turn
asks the firmware if the all-ff's value is the sign of a true EEH
@@ -143,11 +143,12 @@ seen in /proc/ppc64/eeh (subject to change). Normally, almost
all of these occur during boot, when the PCI bus is scanned, where
a large number of 0xff reads are part of the bus scan procedure.
-If a frozen slot is detected, code in arch/ppc64/kernel/eeh.c will
-print a stack trace to syslog (/var/log/messages). This stack trace
-has proven to be very useful to device-driver authors for finding
-out at what point the EEH error was detected, as the error itself
-usually occurs slightly beforehand.
+If a frozen slot is detected, code in
+arch/powerpc/platforms/pseries/eeh.c will print a stack trace to
+syslog (/var/log/messages). This stack trace has proven to be very
+useful to device-driver authors for finding out at what point the EEH
+error was detected, as the error itself usually occurs slightly
+beforehand.
Next, it uses the Linux kernel notifier chain/work queue mechanism to
allow any interested parties to find out about the failure. Device
diff --git a/Documentation/powerpc/hvcs.txt b/Documentation/powerpc/hvcs.txt
index dca75cbda6f8..1e38166f4e54 100644
--- a/Documentation/powerpc/hvcs.txt
+++ b/Documentation/powerpc/hvcs.txt
@@ -558,9 +558,9 @@ partitions.
The proper channel for reporting bugs is either through the Linux OS
distribution company that provided your OS or by posting issues to the
-ppc64 development mailing list at:
+PowerPC development mailing list at:
-linuxppc64-dev@lists.linuxppc.org
+linuxppc-dev@ozlabs.org
This request is to provide a documented and searchable public exchange
of the problems and solutions surrounding this driver for the benefit of
diff --git a/MAINTAINERS b/MAINTAINERS
index dd1351dc32b8..bfd7fbfe90ab 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -534,7 +534,7 @@ S: Supported
BROADBAND PROCESSOR ARCHITECTURE
P: Arnd Bergmann
M: arnd@arndb.de
-L: linuxppc64-dev@ozlabs.org
+L: linuxppc-dev@ozlabs.org
W: http://linuxppc64.org
S: Supported
@@ -1624,7 +1624,7 @@ P: Anton Blanchard
M: anton@samba.org
M: anton@au.ibm.com
W: http://linuxppc64.org
-L: linuxppc64-dev@ozlabs.org
+L: linuxppc-dev@ozlabs.org
S: Supported
LINUX SECURITY MODULE (LSM) FRAMEWORK
diff --git a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c
index 30deaf1b728a..b504def3e346 100644
--- a/arch/cris/kernel/irq.c
+++ b/arch/cris/kernel/irq.c
@@ -52,9 +52,8 @@ int show_interrupts(struct seq_file *p, void *v)
if (i == 0) {
seq_printf(p, " ");
- for (j=0; j<NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "CPU%d ",j);
+ for_each_online_cpu(j)
+ seq_printf(p, "CPU%d ",j);
seq_putc(p, '\n');
}
@@ -67,9 +66,8 @@ int show_interrupts(struct seq_file *p, void *v)
#ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i));
#else
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
#endif
seq_printf(p, " %14s", irq_desc[i].handler->typename);
seq_printf(p, " %s", action->name);
diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c
index 27ab4c30aac6..11fa326a8f62 100644
--- a/arch/frv/kernel/irq.c
+++ b/arch/frv/kernel/irq.c
@@ -75,9 +75,8 @@ int show_interrupts(struct seq_file *p, void *v)
switch (i) {
case 0:
seq_printf(p, " ");
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "CPU%d ",j);
+ for_each_online_cpu(j)
+ seq_printf(p, "CPU%d ",j);
seq_putc(p, '\n');
break;
@@ -100,9 +99,8 @@ int show_interrupts(struct seq_file *p, void *v)
#ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i));
#else
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i - 1]);
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", kstat_cpu(j).irqs[i - 1]);
#endif
level = group->sources[ix]->level - frv_irq_levels;
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 5b1a7d46d1d9..bfea1bedcbf2 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -80,6 +80,7 @@ config X86_VOYAGER
config X86_NUMAQ
bool "NUMAQ (IBM/Sequent)"
+ select SMP
select NUMA
help
This option is used for getting Linux to run on a (IBM/Sequent) NUMA
@@ -400,6 +401,7 @@ choice
config NOHIGHMEM
bool "off"
+ depends on !X86_NUMAQ
---help---
Linux can use up to 64 Gigabytes of physical memory on x86 systems.
However, the address space of 32-bit x86 processors is only 4
@@ -436,6 +438,7 @@ config NOHIGHMEM
config HIGHMEM4G
bool "4GB"
+ depends on !X86_NUMAQ
help
Select this if you have a 32-bit processor and between 1 and 4
gigabytes of physical RAM.
@@ -503,10 +506,6 @@ config NUMA
default n if X86_PC
default y if (X86_NUMAQ || X86_SUMMIT)
-# Need comments to help the hapless user trying to turn on NUMA support
-comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support"
- depends on X86_NUMAQ && (!HIGHMEM64G || !SMP)
-
comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI"
depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI)
@@ -660,13 +659,18 @@ config BOOT_IOREMAP
default y
config REGPARM
- bool "Use register arguments (EXPERIMENTAL)"
- depends on EXPERIMENTAL
- default n
+ bool "Use register arguments"
+ default y
help
- Compile the kernel with -mregparm=3. This uses a different ABI
- and passes the first three arguments of a function call in registers.
- This will probably break binary only modules.
+ Compile the kernel with -mregparm=3. This instructs gcc to use
+ a more efficient function call ABI which passes the first three
+ arguments of a function call via registers, which results in denser
+ and faster code.
+
+ If this option is disabled, then the default ABI of passing
+ arguments via the stack is used.
+
+ If unsure, say Y.
config SECCOMP
bool "Enable seccomp to safely compute untrusted bytecode"
diff --git a/arch/i386/Kconfig.debug b/arch/i386/Kconfig.debug
index bf32ecc9ad04..00108ba9a78d 100644
--- a/arch/i386/Kconfig.debug
+++ b/arch/i386/Kconfig.debug
@@ -31,6 +31,15 @@ config DEBUG_STACK_USAGE
This option will slow down process creation somewhat.
+config STACK_BACKTRACE_COLS
+ int "Stack backtraces per line" if DEBUG_KERNEL
+ range 1 3
+ default 2
+ help
+ Selects how many stack backtrace entries per line to display.
+
+ This can save screen space when displaying traces.
+
comment "Page alloc debug is incompatible with Software Suspend on i386"
depends on DEBUG_KERNEL && SOFTWARE_SUSPEND
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index 65656c033d70..5b9ed21216cf 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -7,7 +7,7 @@ extra-y := head.o init_task.o vmlinux.lds
obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \
ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \
pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \
- quirks.o i8237.o topology.o
+ quirks.o i8237.o topology.o alternative.o
obj-y += cpu/
obj-y += timers/
diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c
new file mode 100644
index 000000000000..5cbd6f99fb2a
--- /dev/null
+++ b/arch/i386/kernel/alternative.c
@@ -0,0 +1,321 @@
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <asm/alternative.h>
+#include <asm/sections.h>
+
+#define DEBUG 0
+#if DEBUG
+# define DPRINTK(fmt, args...) printk(fmt, args)
+#else
+# define DPRINTK(fmt, args...)
+#endif
+
+/* Use inline assembly to define this because the nops are defined
+ as inline assembly strings in the include files and we cannot
+ get them easily into strings. */
+asm("\t.data\nintelnops: "
+ GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6
+ GENERIC_NOP7 GENERIC_NOP8);
+asm("\t.data\nk8nops: "
+ K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6
+ K8_NOP7 K8_NOP8);
+asm("\t.data\nk7nops: "
+ K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6
+ K7_NOP7 K7_NOP8);
+
+extern unsigned char intelnops[], k8nops[], k7nops[];
+static unsigned char *intel_nops[ASM_NOP_MAX+1] = {
+ NULL,
+ intelnops,
+ intelnops + 1,
+ intelnops + 1 + 2,
+ intelnops + 1 + 2 + 3,
+ intelnops + 1 + 2 + 3 + 4,
+ intelnops + 1 + 2 + 3 + 4 + 5,
+ intelnops + 1 + 2 + 3 + 4 + 5 + 6,
+ intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
+};
+static unsigned char *k8_nops[ASM_NOP_MAX+1] = {
+ NULL,
+ k8nops,
+ k8nops + 1,
+ k8nops + 1 + 2,
+ k8nops + 1 + 2 + 3,
+ k8nops + 1 + 2 + 3 + 4,
+ k8nops + 1 + 2 + 3 + 4 + 5,
+ k8nops + 1 + 2 + 3 + 4 + 5 + 6,
+ k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
+};
+static unsigned char *k7_nops[ASM_NOP_MAX+1] = {
+ NULL,
+ k7nops,
+ k7nops + 1,
+ k7nops + 1 + 2,
+ k7nops + 1 + 2 + 3,
+ k7nops + 1 + 2 + 3 + 4,
+ k7nops + 1 + 2 + 3 + 4 + 5,
+ k7nops + 1 + 2 + 3 + 4 + 5 + 6,
+ k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
+};
+static struct nop {
+ int cpuid;
+ unsigned char **noptable;
+} noptypes[] = {
+ { X86_FEATURE_K8, k8_nops },
+ { X86_FEATURE_K7, k7_nops },
+ { -1, NULL }
+};
+
+
+extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
+extern struct alt_instr __smp_alt_instructions[], __smp_alt_instructions_end[];
+extern u8 *__smp_locks[], *__smp_locks_end[];
+
+extern u8 __smp_alt_begin[], __smp_alt_end[];
+
+
+static unsigned char** find_nop_table(void)
+{
+ unsigned char **noptable = intel_nops;
+ int i;
+
+ for (i = 0; noptypes[i].cpuid >= 0; i++) {
+ if (boot_cpu_has(noptypes[i].cpuid)) {
+ noptable = noptypes[i].noptable;
+ break;
+ }
+ }
+ return noptable;
+}
+
+/* Replace instructions with better alternatives for this CPU type.
+ This runs before SMP is initialized to avoid SMP problems with
+ self modifying code. This implies that assymetric systems where
+ APs have less capabilities than the boot processor are not handled.
+ Tough. Make sure you disable such features by hand. */
+
+void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
+{
+ unsigned char **noptable = find_nop_table();
+ struct alt_instr *a;
+ int diff, i, k;
+
+ DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end);
+ for (a = start; a < end; a++) {
+ BUG_ON(a->replacementlen > a->instrlen);
+ if (!boot_cpu_has(a->cpuid))
+ continue;
+ memcpy(a->instr, a->replacement, a->replacementlen);
+ diff = a->instrlen - a->replacementlen;
+ /* Pad the rest with nops */
+ for (i = a->replacementlen; diff > 0; diff -= k, i += k) {
+ k = diff;
+ if (k > ASM_NOP_MAX)
+ k = ASM_NOP_MAX;
+ memcpy(a->instr + i, noptable[k], k);
+ }
+ }
+}
+
+static void alternatives_smp_save(struct alt_instr *start, struct alt_instr *end)
+{
+ struct alt_instr *a;
+
+ DPRINTK("%s: alt table %p-%p\n", __FUNCTION__, start, end);
+ for (a = start; a < end; a++) {
+ memcpy(a->replacement + a->replacementlen,
+ a->instr,
+ a->instrlen);
+ }
+}
+
+static void alternatives_smp_apply(struct alt_instr *start, struct alt_instr *end)
+{
+ struct alt_instr *a;
+
+ for (a = start; a < end; a++) {
+ memcpy(a->instr,
+ a->replacement + a->replacementlen,
+ a->instrlen);
+ }
+}
+
+static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end)
+{
+ u8 **ptr;
+
+ for (ptr = start; ptr < end; ptr++) {
+ if (*ptr < text)
+ continue;
+ if (*ptr > text_end)
+ continue;
+ **ptr = 0xf0; /* lock prefix */
+ };
+}
+
+static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end)
+{
+ unsigned char **noptable = find_nop_table();
+ u8 **ptr;
+
+ for (ptr = start; ptr < end; ptr++) {
+ if (*ptr < text)
+ continue;
+ if (*ptr > text_end)
+ continue;
+ **ptr = noptable[1][0];
+ };
+}
+
+struct smp_alt_module {
+ /* what is this ??? */
+ struct module *mod;
+ char *name;
+
+ /* ptrs to lock prefixes */
+ u8 **locks;
+ u8 **locks_end;
+
+ /* .text segment, needed to avoid patching init code ;) */
+ u8 *text;
+ u8 *text_end;
+
+ struct list_head next;
+};
+static LIST_HEAD(smp_alt_modules);
+static DEFINE_SPINLOCK(smp_alt);
+
+static int smp_alt_once = 0;
+static int __init bootonly(char *str)
+{
+ smp_alt_once = 1;
+ return 1;
+}
+__setup("smp-alt-boot", bootonly);
+
+void alternatives_smp_module_add(struct module *mod, char *name,
+ void *locks, void *locks_end,
+ void *text, void *text_end)
+{
+ struct smp_alt_module *smp;
+ unsigned long flags;
+
+ if (smp_alt_once) {
+ if (boot_cpu_has(X86_FEATURE_UP))
+ alternatives_smp_unlock(locks, locks_end,
+ text, text_end);
+ return;
+ }
+
+ smp = kzalloc(sizeof(*smp), GFP_KERNEL);
+ if (NULL == smp)
+ return; /* we'll run the (safe but slow) SMP code then ... */
+
+ smp->mod = mod;
+ smp->name = name;
+ smp->locks = locks;
+ smp->locks_end = locks_end;
+ smp->text = text;
+ smp->text_end = text_end;
+ DPRINTK("%s: locks %p -> %p, text %p -> %p, name %s\n",
+ __FUNCTION__, smp->locks, smp->locks_end,
+ smp->text, smp->text_end, smp->name);
+
+ spin_lock_irqsave(&smp_alt, flags);
+ list_add_tail(&smp->next, &smp_alt_modules);
+ if (boot_cpu_has(X86_FEATURE_UP))
+ alternatives_smp_unlock(smp->locks, smp->locks_end,
+ smp->text, smp->text_end);
+ spin_unlock_irqrestore(&smp_alt, flags);
+}
+
+void alternatives_smp_module_del(struct module *mod)
+{
+ struct smp_alt_module *item;
+ unsigned long flags;
+
+ if (smp_alt_once)
+ return;
+
+ spin_lock_irqsave(&smp_alt, flags);
+ list_for_each_entry(item, &smp_alt_modules, next) {
+ if (mod != item->mod)
+ continue;
+ list_del(&item->next);
+ spin_unlock_irqrestore(&smp_alt, flags);
+ DPRINTK("%s: %s\n", __FUNCTION__, item->name);
+ kfree(item);
+ return;
+ }
+ spin_unlock_irqrestore(&smp_alt, flags);
+}
+
+void alternatives_smp_switch(int smp)
+{
+ struct smp_alt_module *mod;
+ unsigned long flags;
+
+ if (smp_alt_once)
+ return;
+ BUG_ON(!smp && (num_online_cpus() > 1));
+
+ spin_lock_irqsave(&smp_alt, flags);
+ if (smp) {
+ printk(KERN_INFO "SMP alternatives: switching to SMP code\n");
+ clear_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
+ clear_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
+ alternatives_smp_apply(__smp_alt_instructions,
+ __smp_alt_instructions_end);
+ list_for_each_entry(mod, &smp_alt_modules, next)
+ alternatives_smp_lock(mod->locks, mod->locks_end,
+ mod->text, mod->text_end);
+ } else {
+ printk(KERN_INFO "SMP alternatives: switching to UP code\n");
+ set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
+ set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
+ apply_alternatives(__smp_alt_instructions,
+ __smp_alt_instructions_end);
+ list_for_each_entry(mod, &smp_alt_modules, next)
+ alternatives_smp_unlock(mod->locks, mod->locks_end,
+ mod->text, mod->text_end);
+ }
+ spin_unlock_irqrestore(&smp_alt, flags);
+}
+
+void __init alternative_instructions(void)
+{
+ apply_alternatives(__alt_instructions, __alt_instructions_end);
+
+ /* switch to patch-once-at-boottime-only mode and free the
+ * tables in case we know the number of CPUs will never ever
+ * change */
+#ifdef CONFIG_HOTPLUG_CPU
+ if (num_possible_cpus() < 2)
+ smp_alt_once = 1;
+#else
+ smp_alt_once = 1;
+#endif
+
+ if (smp_alt_once) {
+ if (1 == num_possible_cpus()) {
+ printk(KERN_INFO "SMP alternatives: switching to UP code\n");
+ set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
+ set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
+ apply_alternatives(__smp_alt_instructions,
+ __smp_alt_instructions_end);
+ alternatives_smp_unlock(__smp_locks, __smp_locks_end,
+ _text, _etext);
+ }
+ free_init_pages("SMP alternatives",
+ (unsigned long)__smp_alt_begin,
+ (unsigned long)__smp_alt_end);
+ } else {
+ alternatives_smp_save(__smp_alt_instructions,
+ __smp_alt_instructions_end);
+ alternatives_smp_module_add(NULL, "core kernel",
+ __smp_locks, __smp_locks_end,
+ _text, _etext);
+ alternatives_smp_switch(0);
+ }
+}
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 776c90989e06..eb5279d23b7f 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -38,6 +38,7 @@
#include <asm/i8253.h>
#include <mach_apic.h>
+#include <mach_apicdef.h>
#include <mach_ipi.h>
#include "io_ports.h"
diff --git a/arch/i386/kernel/cpu/centaur.c b/arch/i386/kernel/cpu/centaur.c
index f52669ecb93f..bd75629dd262 100644
--- a/arch/i386/kernel/cpu/centaur.c
+++ b/arch/i386/kernel/cpu/centaur.c
@@ -4,6 +4,7 @@
#include <asm/processor.h>
#include <asm/msr.h>
#include <asm/e820.h>
+#include <asm/mtrr.h>
#include "cpu.h"
#ifdef CONFIG_X86_OOSTORE
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index e6bd095ae108..7e3d6b6a4e96 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -25,9 +25,10 @@ EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr);
DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
-static int cachesize_override __devinitdata = -1;
-static int disable_x86_fxsr __devinitdata = 0;
-static int disable_x86_serial_nr __devinitdata = 1;
+static int cachesize_override __cpuinitdata = -1;
+static int disable_x86_fxsr __cpuinitdata;
+static int disable_x86_serial_nr __cpuinitdata = 1;
+static int disable_x86_sep __cpuinitdata;
struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
@@ -59,7 +60,7 @@ static int __init cachesize_setup(char *str)
}
__setup("cachesize=", cachesize_setup);
-int __devinit get_model_name(struct cpuinfo_x86 *c)
+int __cpuinit get_model_name(struct cpuinfo_x86 *c)
{
unsigned int *v;
char *p, *q;
@@ -89,7 +90,7 @@ int __devinit get_model_name(struct cpuinfo_x86 *c)
}
-void __devinit display_cacheinfo(struct cpuinfo_x86 *c)
+void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c)
{
unsigned int n, dummy, ecx, edx, l2size;
@@ -130,7 +131,7 @@ void __devinit display_cacheinfo(struct cpuinfo_x86 *c)
/* in particular, if CPUID levels 0x80000002..4 are supported, this isn't used */
/* Look up CPU names by table lookup. */
-static char __devinit *table_lookup_model(struct cpuinfo_x86 *c)
+static char __cpuinit *table_lookup_model(struct cpuinfo_x86 *c)
{
struct cpu_model_info *info;
@@ -151,7 +152,7 @@ static char __devinit *table_lookup_model(struct cpuinfo_x86 *c)
}
-static void __devinit get_cpu_vendor(struct cpuinfo_x86 *c, int early)
+static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c, int early)
{
char *v = c->x86_vendor_id;
int i;
@@ -187,6 +188,14 @@ static int __init x86_fxsr_setup(char * s)
__setup("nofxsr", x86_fxsr_setup);
+static int __init x86_sep_setup(char * s)
+{
+ disable_x86_sep = 1;
+ return 1;
+}
+__setup("nosep", x86_sep_setup);
+
+
/* Standard macro to see if a specific flag is changeable */
static inline int flag_is_changeable_p(u32 flag)
{
@@ -210,7 +219,7 @@ static inline int flag_is_changeable_p(u32 flag)
/* Probe for the CPUID instruction */
-static int __devinit have_cpuid_p(void)
+static int __cpuinit have_cpuid_p(void)
{
return flag_is_changeable_p(X86_EFLAGS_ID);
}
@@ -254,7 +263,7 @@ static void __init early_cpu_detect(void)
}
}
-void __devinit generic_identify(struct cpuinfo_x86 * c)
+void __cpuinit generic_identify(struct cpuinfo_x86 * c)
{
u32 tfms, xlvl;
int junk;
@@ -307,7 +316,7 @@ void __devinit generic_identify(struct cpuinfo_x86 * c)
#endif
}
-static void __devinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
+static void __cpuinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
{
if (cpu_has(c, X86_FEATURE_PN) && disable_x86_serial_nr ) {
/* Disable processor serial number */
@@ -335,7 +344,7 @@ __setup("serialnumber", x86_serial_nr_setup);
/*
* This does the hard work of actually picking apart the CPU stuff...
*/
-void __devinit identify_cpu(struct cpuinfo_x86 *c)
+void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
{
int i;
@@ -405,6 +414,10 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c)
clear_bit(X86_FEATURE_XMM, c->x86_capability);
}
+ /* SEP disabled? */
+ if (disable_x86_sep)
+ clear_bit(X86_FEATURE_SEP, c->x86_capability);
+
if (disable_pse)
clear_bit(X86_FEATURE_PSE, c->x86_capability);
@@ -417,7 +430,7 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c)
else
/* Last resort... */
sprintf(c->x86_model_id, "%02x/%02x",
- c->x86_vendor, c->x86_model);
+ c->x86, c->x86_model);
}
/* Now the feature flags better reflect actual CPU features! */
@@ -453,7 +466,7 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c)
}
#ifdef CONFIG_X86_HT
-void __devinit detect_ht(struct cpuinfo_x86 *c)
+void __cpuinit detect_ht(struct cpuinfo_x86 *c)
{
u32 eax, ebx, ecx, edx;
int index_msb, core_bits;
@@ -500,7 +513,7 @@ void __devinit detect_ht(struct cpuinfo_x86 *c)
}
#endif
-void __devinit print_cpu_info(struct cpuinfo_x86 *c)
+void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
{
char *vendor = NULL;
@@ -523,7 +536,7 @@ void __devinit print_cpu_info(struct cpuinfo_x86 *c)
printk("\n");
}
-cpumask_t cpu_initialized __devinitdata = CPU_MASK_NONE;
+cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
/* This is hacky. :)
* We're emulating future behavior.
@@ -570,7 +583,7 @@ void __init early_cpu_init(void)
* and IDT. We reload them nevertheless, this function acts as a
* 'CPU state barrier', nothing should get across.
*/
-void __devinit cpu_init(void)
+void __cpuinit cpu_init(void)
{
int cpu = smp_processor_id();
struct tss_struct * t = &per_cpu(init_tss, cpu);
@@ -670,7 +683,7 @@ void __devinit cpu_init(void)
}
#ifdef CONFIG_HOTPLUG_CPU
-void __devinit cpu_uninit(void)
+void __cpuinit cpu_uninit(void)
{
int cpu = raw_smp_processor_id();
cpu_clear(cpu, cpu_initialized);
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
index e11a09207ec8..3d5110b65cc3 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
@@ -1145,9 +1145,7 @@ static int __cpuinit powernowk8_init(void)
{
unsigned int i, supported_cpus = 0;
- for (i=0; i<NR_CPUS; i++) {
- if (!cpu_online(i))
- continue;
+ for_each_cpu(i) {
if (check_supported_cpu(i))
supported_cpus++;
}
diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c
index 8c0120186b9f..5386b29bb5a5 100644
--- a/arch/i386/kernel/cpu/intel.c
+++ b/arch/i386/kernel/cpu/intel.c
@@ -29,7 +29,7 @@ extern int trap_init_f00f_bug(void);
struct movsl_mask movsl_mask __read_mostly;
#endif
-void __devinit early_intel_workaround(struct cpuinfo_x86 *c)
+void __cpuinit early_intel_workaround(struct cpuinfo_x86 *c)
{
if (c->x86_vendor != X86_VENDOR_INTEL)
return;
@@ -44,7 +44,7 @@ void __devinit early_intel_workaround(struct cpuinfo_x86 *c)
* This is called before we do cpu ident work
*/
-int __devinit ppro_with_ram_bug(void)
+int __cpuinit ppro_with_ram_bug(void)
{
/* Uses data from early_cpu_detect now */
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
@@ -62,7 +62,7 @@ int __devinit ppro_with_ram_bug(void)
* P4 Xeon errata 037 workaround.
* Hardware prefetcher may cause stale data to be loaded into the cache.
*/
-static void __devinit Intel_errata_workarounds(struct cpuinfo_x86 *c)
+static void __cpuinit Intel_errata_workarounds(struct cpuinfo_x86 *c)
{
unsigned long lo, hi;
@@ -81,7 +81,7 @@ static void __devinit Intel_errata_workarounds(struct cpuinfo_x86 *c)
/*
* find out the number of processor cores on the die
*/
-static int __devinit num_cpu_cores(struct cpuinfo_x86 *c)
+static int __cpuinit num_cpu_cores(struct cpuinfo_x86 *c)
{
unsigned int eax, ebx, ecx, edx;
@@ -96,7 +96,7 @@ static int __devinit num_cpu_cores(struct cpuinfo_x86 *c)
return 1;
}
-static void __devinit init_intel(struct cpuinfo_x86 *c)
+static void __cpuinit init_intel(struct cpuinfo_x86 *c)
{
unsigned int l2 = 0;
char *p = NULL;
@@ -205,7 +205,7 @@ static unsigned int intel_size_cache(struct cpuinfo_x86 * c, unsigned int size)
return size;
}
-static struct cpu_dev intel_cpu_dev __devinitdata = {
+static struct cpu_dev intel_cpu_dev __cpuinitdata = {
.c_vendor = "Intel",
.c_ident = { "GenuineIntel" },
.c_models = {
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c
index ffe58cee0c48..ce61921369e5 100644
--- a/arch/i386/kernel/cpu/intel_cacheinfo.c
+++ b/arch/i386/kernel/cpu/intel_cacheinfo.c
@@ -174,7 +174,7 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
- if (c->cpuid_level > 4) {
+ if (c->cpuid_level > 3) {
static int is_initialized;
if (is_initialized == 0) {
@@ -330,7 +330,7 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
}
}
}
-static void __devinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
+static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
{
struct _cpuid4_info *this_leaf, *sibling_leaf;
int sibling;
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
index 89a85af33d28..5cfbd8011698 100644
--- a/arch/i386/kernel/cpu/proc.c
+++ b/arch/i386/kernel/cpu/proc.c
@@ -40,7 +40,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
/* Other (Linux-defined) */
"cxmmx", "k6_mtrr", "cyrix_arr", "centaur_mcr",
NULL, NULL, NULL, NULL,
- "constant_tsc", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ "constant_tsc", "up", NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
index d49dbe8dc96b..e3c5fca0aa8a 100644
--- a/arch/i386/kernel/crash.c
+++ b/arch/i386/kernel/crash.c
@@ -105,7 +105,7 @@ static int crash_nmi_callback(struct pt_regs *regs, int cpu)
return 1;
local_irq_disable();
- if (!user_mode(regs)) {
+ if (!user_mode_vm(regs)) {
crash_fixup_ss_esp(&fixed_regs, regs);
regs = &fixed_regs;
}
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 4d704724b2f5..cfc683f153b9 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -226,6 +226,10 @@ ENTRY(system_call)
pushl %eax # save orig_eax
SAVE_ALL
GET_THREAD_INFO(%ebp)
+ testl $TF_MASK,EFLAGS(%esp)
+ jz no_singlestep
+ orl $_TIF_SINGLESTEP,TI_flags(%ebp)
+no_singlestep:
# system call tracing in operation / emulation
/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index e0b7c632efbc..3debc2e26542 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -450,7 +450,6 @@ int_msg:
.globl boot_gdt_descr
.globl idt_descr
-.globl cpu_gdt_descr
ALIGN
# early boot GDT descriptor (must use 1:1 address mapping)
@@ -470,8 +469,6 @@ cpu_gdt_descr:
.word GDT_ENTRIES*8-1
.long cpu_gdt_table
- .fill NR_CPUS-1,8,0 # space for the other GDT descriptors
-
/*
* The boot_gdt_table must mirror the equivalent in setup.S and is
* used only for booting.
@@ -485,7 +482,7 @@ ENTRY(boot_gdt_table)
/*
* The Global Descriptor Table contains 28 quadwords, per-CPU.
*/
- .align PAGE_SIZE_asm
+ .align L1_CACHE_BYTES
ENTRY(cpu_gdt_table)
.quad 0x0000000000000000 /* NULL descriptor */
.quad 0x0000000000000000 /* 0x0b reserved */
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 39d9a5fa907e..311b4e7266f1 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -351,8 +351,8 @@ static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold)
{
int i, j;
Dprintk("Rotating IRQs among CPUs.\n");
- for (i = 0; i < NR_CPUS; i++) {
- for (j = 0; cpu_online(i) && (j < NR_IRQS); j++) {
+ for_each_online_cpu(i) {
+ for (j = 0; j < NR_IRQS; j++) {
if (!irq_desc[j].action)
continue;
/* Is it a significant load ? */
@@ -381,7 +381,7 @@ static void do_irq_balance(void)
unsigned long imbalance = 0;
cpumask_t allowed_mask, target_cpu_mask, tmp;
- for (i = 0; i < NR_CPUS; i++) {
+ for_each_cpu(i) {
int package_index;
CPU_IRQ(i) = 0;
if (!cpu_online(i))
@@ -422,9 +422,7 @@ static void do_irq_balance(void)
}
}
/* Find the least loaded processor package */
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_online(i))
- continue;
+ for_each_online_cpu(i) {
if (i != CPU_TO_PACKAGEINDEX(i))
continue;
if (min_cpu_irq > CPU_IRQ(i)) {
@@ -441,9 +439,7 @@ tryanothercpu:
*/
tmp_cpu_irq = 0;
tmp_loaded = -1;
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_online(i))
- continue;
+ for_each_online_cpu(i) {
if (i != CPU_TO_PACKAGEINDEX(i))
continue;
if (max_cpu_irq <= CPU_IRQ(i))
@@ -619,9 +615,7 @@ static int __init balanced_irq_init(void)
if (smp_num_siblings > 1 && !cpus_empty(tmp))
physical_balance = 1;
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_online(i))
- continue;
+ for_each_online_cpu(i) {
irq_cpu_data[i].irq_delta = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL);
irq_cpu_data[i].last_irq = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL);
if (irq_cpu_data[i].irq_delta == NULL || irq_cpu_data[i].last_irq == NULL) {
@@ -638,9 +632,11 @@ static int __init balanced_irq_init(void)
else
printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq");
failed:
- for (i = 0; i < NR_CPUS; i++) {
+ for_each_cpu(i) {
kfree(irq_cpu_data[i].irq_delta);
+ irq_cpu_data[i].irq_delta = NULL;
kfree(irq_cpu_data[i].last_irq);
+ irq_cpu_data[i].last_irq = NULL;
}
return 0;
}
@@ -1761,7 +1757,8 @@ static void __init setup_ioapic_ids_from_mpc(void)
* Don't check I/O APIC IDs for xAPIC systems. They have
* no meaning without the serial APIC bus.
*/
- if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && boot_cpu_data.x86 < 15))
+ if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
+ || APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
return;
/*
* This is broken; anything with a real cpu count has to
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index 694a13997637..7a59050242a7 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -84,9 +84,9 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)
void __kprobes arch_remove_kprobe(struct kprobe *p)
{
- down(&kprobe_mutex);
+ mutex_lock(&kprobe_mutex);
free_insn_slot(p->ainsn.insn);
- up(&kprobe_mutex);
+ mutex_unlock(&kprobe_mutex);
}
static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
diff --git a/arch/i386/kernel/module.c b/arch/i386/kernel/module.c
index 5149c8a621f0..470cf97e7cd3 100644
--- a/arch/i386/kernel/module.c
+++ b/arch/i386/kernel/module.c
@@ -104,26 +104,38 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
return -ENOEXEC;
}
-extern void apply_alternatives(void *start, void *end);
-
int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
struct module *me)
{
- const Elf_Shdr *s;
+ const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL;
char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
- /* look for .altinstructions to patch */
for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
- void *seg;
- if (strcmp(".altinstructions", secstrings + s->sh_name))
- continue;
- seg = (void *)s->sh_addr;
- apply_alternatives(seg, seg + s->sh_size);
- }
+ if (!strcmp(".text", secstrings + s->sh_name))
+ text = s;
+ if (!strcmp(".altinstructions", secstrings + s->sh_name))
+ alt = s;
+ if (!strcmp(".smp_locks", secstrings + s->sh_name))
+ locks= s;
+ }
+
+ if (alt) {
+ /* patch .altinstructions */
+ void *aseg = (void *)alt->sh_addr;
+ apply_alternatives(aseg, aseg + alt->sh_size);
+ }
+ if (locks && text) {
+ void *lseg = (void *)locks->sh_addr;
+ void *tseg = (void *)text->sh_addr;
+ alternatives_smp_module_add(me, me->name,
+ lseg, lseg + locks->sh_size,
+ tseg, tseg + text->sh_size);
+ }
return 0;
}
void module_arch_cleanup(struct module *mod)
{
+ alternatives_smp_module_del(mod);
}
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index e6e2f43db85e..8d8aa9d1796d 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -828,6 +828,8 @@ void __init find_smp_config (void)
smp_scan_config(address, 0x400);
}
+int es7000_plat;
+
/* --------------------------------------------------------------------------
ACPI-based MP Configuration
-------------------------------------------------------------------------- */
@@ -935,7 +937,8 @@ void __init mp_register_ioapic (
mp_ioapics[idx].mpc_apicaddr = address;
set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
- if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 < 15))
+ if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
+ && !APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
tmpid = io_apic_get_unique_id(idx, id);
else
tmpid = id;
@@ -1011,8 +1014,6 @@ void __init mp_override_legacy_irq (
return;
}
-int es7000_plat;
-
void __init mp_config_acpi_legacy_irqs (void)
{
struct mpc_config_intsrc intsrc;
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index be87c5e2ee95..9074818b9473 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -143,7 +143,7 @@ static int __init check_nmi_watchdog(void)
local_irq_enable();
mdelay((10*1000)/nmi_hz); // wait 10 ticks
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
+ for_each_cpu(cpu) {
#ifdef CONFIG_SMP
/* Check cpu_callin_map here because that is set
after the timer is started. */
@@ -510,7 +510,7 @@ void touch_nmi_watchdog (void)
* Just reset the alert counters, (other CPUs might be
* spinning on locks we hold):
*/
- for (i = 0; i < NR_CPUS; i++)
+ for_each_cpu(i)
alert_counter[i] = 0;
/*
@@ -543,7 +543,7 @@ void nmi_watchdog_tick (struct pt_regs * regs)
/*
* die_nmi will return ONLY if NOTIFY_STOP happens..
*/
- die_nmi(regs, "NMI Watchdog detected LOCKUP");
+ die_nmi(regs, "BUG: NMI Watchdog detected LOCKUP");
} else {
last_irq_sums[cpu] = sum;
alert_counter[cpu] = 0;
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 0480454ebffa..299e61674084 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -295,7 +295,7 @@ void show_regs(struct pt_regs * regs)
printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
print_symbol("EIP is at %s\n", regs->eip);
- if (user_mode(regs))
+ if (user_mode_vm(regs))
printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
printk(" EFLAGS: %08lx %s (%s %.*s)\n",
regs->eflags, print_tainted(), system_utsname.release,
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index 5c1fb6aada5b..506462ef36a0 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -34,10 +34,10 @@
/*
* Determines which flags the user has access to [1 = access, 0 = no access].
- * Prohibits changing ID(21), VIP(20), VIF(19), VM(17), IOPL(12-13), IF(9).
+ * Prohibits changing ID(21), VIP(20), VIF(19), VM(17), NT(14), IOPL(12-13), IF(9).
* Also masks reserved bits (31-22, 15, 5, 3, 1).
*/
-#define FLAG_MASK 0x00054dd5
+#define FLAG_MASK 0x00050dd5
/* set's the trap flag. */
#define TRAP_FLAG 0x100
diff --git a/arch/i386/kernel/semaphore.c b/arch/i386/kernel/semaphore.c
index 7455ab643943..967dc74df9ee 100644
--- a/arch/i386/kernel/semaphore.c
+++ b/arch/i386/kernel/semaphore.c
@@ -110,11 +110,11 @@ asm(
".align 4\n"
".globl __write_lock_failed\n"
"__write_lock_failed:\n\t"
- LOCK "addl $" RW_LOCK_BIAS_STR ",(%eax)\n"
+ LOCK_PREFIX "addl $" RW_LOCK_BIAS_STR ",(%eax)\n"
"1: rep; nop\n\t"
"cmpl $" RW_LOCK_BIAS_STR ",(%eax)\n\t"
"jne 1b\n\t"
- LOCK "subl $" RW_LOCK_BIAS_STR ",(%eax)\n\t"
+ LOCK_PREFIX "subl $" RW_LOCK_BIAS_STR ",(%eax)\n\t"
"jnz __write_lock_failed\n\t"
"ret"
);
@@ -124,11 +124,11 @@ asm(
".align 4\n"
".globl __read_lock_failed\n"
"__read_lock_failed:\n\t"
- LOCK "incl (%eax)\n"
+ LOCK_PREFIX "incl (%eax)\n"
"1: rep; nop\n\t"
"cmpl $1,(%eax)\n\t"
"js 1b\n\t"
- LOCK "decl (%eax)\n\t"
+ LOCK_PREFIX "decl (%eax)\n\t"
"js __read_lock_failed\n\t"
"ret"
);
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index ab62a9f4701e..2d8782960f41 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -1377,101 +1377,6 @@ static void __init register_memory(void)
pci_mem_start, gapstart, gapsize);
}
-/* Use inline assembly to define this because the nops are defined
- as inline assembly strings in the include files and we cannot
- get them easily into strings. */
-asm("\t.data\nintelnops: "
- GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6
- GENERIC_NOP7 GENERIC_NOP8);
-asm("\t.data\nk8nops: "
- K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6
- K8_NOP7 K8_NOP8);
-asm("\t.data\nk7nops: "
- K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6
- K7_NOP7 K7_NOP8);
-
-extern unsigned char intelnops[], k8nops[], k7nops[];
-static unsigned char *intel_nops[ASM_NOP_MAX+1] = {
- NULL,
- intelnops,
- intelnops + 1,
- intelnops + 1 + 2,
- intelnops + 1 + 2 + 3,
- intelnops + 1 + 2 + 3 + 4,
- intelnops + 1 + 2 + 3 + 4 + 5,
- intelnops + 1 + 2 + 3 + 4 + 5 + 6,
- intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
-};
-static unsigned char *k8_nops[ASM_NOP_MAX+1] = {
- NULL,
- k8nops,
- k8nops + 1,
- k8nops + 1 + 2,
- k8nops + 1 + 2 + 3,
- k8nops + 1 + 2 + 3 + 4,
- k8nops + 1 + 2 + 3 + 4 + 5,
- k8nops + 1 + 2 + 3 + 4 + 5 + 6,
- k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
-};
-static unsigned char *k7_nops[ASM_NOP_MAX+1] = {
- NULL,
- k7nops,
- k7nops + 1,
- k7nops + 1 + 2,
- k7nops + 1 + 2 + 3,
- k7nops + 1 + 2 + 3 + 4,
- k7nops + 1 + 2 + 3 + 4 + 5,
- k7nops + 1 + 2 + 3 + 4 + 5 + 6,
- k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
-};
-static struct nop {
- int cpuid;
- unsigned char **noptable;
-} noptypes[] = {
- { X86_FEATURE_K8, k8_nops },
- { X86_FEATURE_K7, k7_nops },
- { -1, NULL }
-};
-
-/* Replace instructions with better alternatives for this CPU type.
-
- This runs before SMP is initialized to avoid SMP problems with
- self modifying code. This implies that assymetric systems where
- APs have less capabilities than the boot processor are not handled.
- Tough. Make sure you disable such features by hand. */
-void apply_alternatives(void *start, void *end)
-{
- struct alt_instr *a;
- int diff, i, k;
- unsigned char **noptable = intel_nops;
- for (i = 0; noptypes[i].cpuid >= 0; i++) {
- if (boot_cpu_has(noptypes[i].cpuid)) {
- noptable = noptypes[i].noptable;
- break;
- }
- }
- for (a = start; (void *)a < end; a++) {
- if (!boot_cpu_has(a->cpuid))
- continue;
- BUG_ON(a->replacementlen > a->instrlen);
- memcpy(a->instr, a->replacement, a->replacementlen);
- diff = a->instrlen - a->replacementlen;
- /* Pad the rest with nops */
- for (i = a->replacementlen; diff > 0; diff -= k, i += k) {
- k = diff;
- if (k > ASM_NOP_MAX)
- k = ASM_NOP_MAX;
- memcpy(a->instr + i, noptable[k], k);
- }
- }
-}
-
-void __init alternative_instructions(void)
-{
- extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
- apply_alternatives(__alt_instructions, __alt_instructions_end);
-}
-
static char * __init machine_specific_memory_setup(void);
#ifdef CONFIG_MCA
@@ -1554,6 +1459,16 @@ void __init setup_arch(char **cmdline_p)
parse_cmdline_early(cmdline_p);
+#ifdef CONFIG_EARLY_PRINTK
+ {
+ char *s = strstr(*cmdline_p, "earlyprintk=");
+ if (s) {
+ setup_early_printk(strchr(s, '=') + 1);
+ printk("early console enabled\n");
+ }
+ }
+#endif
+
max_low_pfn = setup_memory();
/*
@@ -1578,19 +1493,6 @@ void __init setup_arch(char **cmdline_p)
* NOTE: at this point the bootmem allocator is fully available.
*/
-#ifdef CONFIG_EARLY_PRINTK
- {
- char *s = strstr(*cmdline_p, "earlyprintk=");
- if (s) {
- extern void setup_early_printk(char *);
-
- setup_early_printk(strchr(s, '=') + 1);
- printk("early console enabled\n");
- }
- }
-#endif
-
-
dmi_scan_machine();
#ifdef CONFIG_X86_GENERICARCH
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
index 963616d364ec..5c352c3a9e7f 100644
--- a/arch/i386/kernel/signal.c
+++ b/arch/i386/kernel/signal.c
@@ -123,7 +123,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *peax
err |= __get_user(tmp, &sc->seg); \
loadsegment(seg,tmp); }
-#define FIX_EFLAGS (X86_EFLAGS_AC | X86_EFLAGS_OF | X86_EFLAGS_DF | \
+#define FIX_EFLAGS (X86_EFLAGS_AC | X86_EFLAGS_RF | \
+ X86_EFLAGS_OF | X86_EFLAGS_DF | \
X86_EFLAGS_TF | X86_EFLAGS_SF | X86_EFLAGS_ZF | \
X86_EFLAGS_AF | X86_EFLAGS_PF | X86_EFLAGS_CF)
@@ -582,9 +583,6 @@ static void fastcall do_signal(struct pt_regs *regs)
if (!user_mode(regs))
return;
- if (try_to_freeze())
- goto no_signal;
-
if (test_thread_flag(TIF_RESTORE_SIGMASK))
oldset = &current->saved_sigmask;
else
@@ -613,7 +611,6 @@ static void fastcall do_signal(struct pt_regs *regs)
return;
}
-no_signal:
/* Did we come from a system call? */
if (regs->orig_eax >= 0) {
/* Restart the system call - no handlers present */
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 7007e1783797..4c470e99a742 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -899,6 +899,7 @@ static int __devinit do_boot_cpu(int apicid, int cpu)
unsigned short nmi_high = 0, nmi_low = 0;
++cpucount;
+ alternatives_smp_switch(1);
/*
* We can't use kernel_thread since we must avoid to
@@ -1368,6 +1369,8 @@ void __cpu_die(unsigned int cpu)
/* They ack this in play_dead by setting CPU_DEAD */
if (per_cpu(cpu_state, cpu) == CPU_DEAD) {
printk ("CPU %d is now offline\n", cpu);
+ if (1 == num_online_cpus())
+ alternatives_smp_switch(0);
return;
}
msleep(100);
diff --git a/arch/i386/kernel/topology.c b/arch/i386/kernel/topology.c
index 67a0e1baa28b..296355292c7c 100644
--- a/arch/i386/kernel/topology.c
+++ b/arch/i386/kernel/topology.c
@@ -41,6 +41,15 @@ int arch_register_cpu(int num){
parent = &node_devices[node].node;
#endif /* CONFIG_NUMA */
+ /*
+ * CPU0 cannot be offlined due to several
+ * restrictions and assumptions in kernel. This basically
+ * doesnt add a control file, one cannot attempt to offline
+ * BSP.
+ */
+ if (!num)
+ cpu_devices[num].cpu.no_control = 1;
+
return register_cpu(&cpu_devices[num].cpu, num, parent);
}
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index b814dbdcc91e..de5386b01d38 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -99,6 +99,8 @@ int register_die_notifier(struct notifier_block *nb)
{
int err = 0;
unsigned long flags;
+
+ vmalloc_sync_all();
spin_lock_irqsave(&die_notifier_lock, flags);
err = notifier_chain_register(&i386die_chain, nb);
spin_unlock_irqrestore(&die_notifier_lock, flags);
@@ -112,12 +114,30 @@ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
p < (void *)tinfo + THREAD_SIZE - 3;
}
-static void print_addr_and_symbol(unsigned long addr, char *log_lvl)
+/*
+ * Print CONFIG_STACK_BACKTRACE_COLS address/symbol entries per line.
+ */
+static inline int print_addr_and_symbol(unsigned long addr, char *log_lvl,
+ int printed)
{
- printk(log_lvl);
+ if (!printed)
+ printk(log_lvl);
+
+#if CONFIG_STACK_BACKTRACE_COLS == 1
printk(" [<%08lx>] ", addr);
+#else
+ printk(" <%08lx> ", addr);
+#endif
print_symbol("%s", addr);
- printk("\n");
+
+ printed = (printed + 1) % CONFIG_STACK_BACKTRACE_COLS;
+
+ if (printed)
+ printk(" ");
+ else
+ printk("\n");
+
+ return printed;
}
static inline unsigned long print_context_stack(struct thread_info *tinfo,
@@ -125,20 +145,24 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo,
char *log_lvl)
{
unsigned long addr;
+ int printed = 0; /* nr of entries already printed on current line */
#ifdef CONFIG_FRAME_POINTER
while (valid_stack_ptr(tinfo, (void *)ebp)) {
addr = *(unsigned long *)(ebp + 4);
- print_addr_and_symbol(addr, log_lvl);
+ printed = print_addr_and_symbol(addr, log_lvl, printed);
ebp = *(unsigned long *)ebp;
}
#else
while (valid_stack_ptr(tinfo, stack)) {
addr = *stack++;
if (__kernel_text_address(addr))
- print_addr_and_symbol(addr, log_lvl);
+ printed = print_addr_and_symbol(addr, log_lvl, printed);
}
#endif
+ if (printed)
+ printk("\n");
+
return ebp;
}
@@ -166,8 +190,7 @@ static void show_trace_log_lvl(struct task_struct *task,
stack = (unsigned long*)context->previous_esp;
if (!stack)
break;
- printk(log_lvl);
- printk(" =======================\n");
+ printk("%s =======================\n", log_lvl);
}
}
@@ -194,21 +217,17 @@ static void show_stack_log_lvl(struct task_struct *task, unsigned long *esp,
for(i = 0; i < kstack_depth_to_print; i++) {
if (kstack_end(stack))
break;
- if (i && ((i % 8) == 0)) {
- printk("\n");
- printk(log_lvl);
- printk(" ");
- }
+ if (i && ((i % 8) == 0))
+ printk("\n%s ", log_lvl);
printk("%08lx ", *stack++);
}
- printk("\n");
- printk(log_lvl);
- printk("Call Trace:\n");
+ printk("\n%sCall Trace:\n", log_lvl);
show_trace_log_lvl(task, esp, log_lvl);
}
void show_stack(struct task_struct *task, unsigned long *esp)
{
+ printk(" ");
show_stack_log_lvl(task, esp, "");
}
@@ -233,7 +252,7 @@ void show_registers(struct pt_regs *regs)
esp = (unsigned long) (&regs->esp);
savesegment(ss, ss);
- if (user_mode(regs)) {
+ if (user_mode_vm(regs)) {
in_kernel = 0;
esp = regs->esp;
ss = regs->xss & 0xffff;
@@ -333,6 +352,8 @@ void die(const char * str, struct pt_regs * regs, long err)
static int die_counter;
unsigned long flags;
+ oops_enter();
+
if (die.lock_owner != raw_smp_processor_id()) {
console_verbose();
spin_lock_irqsave(&die.lock, flags);
@@ -385,6 +406,7 @@ void die(const char * str, struct pt_regs * regs, long err)
ssleep(5);
panic("Fatal exception");
}
+ oops_exit();
do_exit(SIGSEGV);
}
@@ -623,7 +645,7 @@ void die_nmi (struct pt_regs *regs, const char *msg)
/* If we are in kernel we are probably nested up pretty bad
* and might aswell get out now while we still can.
*/
- if (!user_mode(regs)) {
+ if (!user_mode_vm(regs)) {
current->thread.trap_no = 2;
crash_kexec(regs);
}
@@ -694,6 +716,7 @@ fastcall void do_nmi(struct pt_regs * regs, long error_code)
void set_nmi_callback(nmi_callback_t callback)
{
+ vmalloc_sync_all();
rcu_assign_pointer(nmi_callback, callback);
}
EXPORT_SYMBOL_GPL(set_nmi_callback);
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S
index 4710195b6b74..3f21c6f6466d 100644
--- a/arch/i386/kernel/vmlinux.lds.S
+++ b/arch/i386/kernel/vmlinux.lds.S
@@ -68,6 +68,26 @@ SECTIONS
*(.data.init_task)
}
+ /* might get freed after init */
+ . = ALIGN(4096);
+ __smp_alt_begin = .;
+ __smp_alt_instructions = .;
+ .smp_altinstructions : AT(ADDR(.smp_altinstructions) - LOAD_OFFSET) {
+ *(.smp_altinstructions)
+ }
+ __smp_alt_instructions_end = .;
+ . = ALIGN(4);
+ __smp_locks = .;
+ .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
+ *(.smp_locks)
+ }
+ __smp_locks_end = .;
+ .smp_altinstr_replacement : AT(ADDR(.smp_altinstr_replacement) - LOAD_OFFSET) {
+ *(.smp_altinstr_replacement)
+ }
+ . = ALIGN(4096);
+ __smp_alt_end = .;
+
/* will be freed after init */
. = ALIGN(4096); /* Init code and data */
__init_begin = .;
diff --git a/arch/i386/kernel/vsyscall-sysenter.S b/arch/i386/kernel/vsyscall-sysenter.S
index 76b728159403..3b62baa6a371 100644
--- a/arch/i386/kernel/vsyscall-sysenter.S
+++ b/arch/i386/kernel/vsyscall-sysenter.S
@@ -21,6 +21,9 @@
* instruction clobbers %esp, the user's %esp won't even survive entry
* into the kernel. We store %esp in %ebp. Code in entry.S must fetch
* arg6 from the stack.
+ *
+ * You can not use this vsyscall for the clone() syscall because the
+ * three dwords on the parent stack do not get copied to the child.
*/
.text
.globl __kernel_vsyscall
diff --git a/arch/i386/mach-es7000/es7000.h b/arch/i386/mach-es7000/es7000.h
index f1e3204f5dec..80566ca4a80a 100644
--- a/arch/i386/mach-es7000/es7000.h
+++ b/arch/i386/mach-es7000/es7000.h
@@ -83,6 +83,7 @@ struct es7000_oem_table {
struct psai psai;
};
+#ifdef CONFIG_ACPI
struct acpi_table_sdt {
unsigned long pa;
unsigned long count;
@@ -99,6 +100,9 @@ struct oem_table {
u32 OEMTableSize;
};
+extern int find_unisys_acpi_oem_table(unsigned long *oem_addr);
+#endif
+
struct mip_reg {
unsigned long long off_0;
unsigned long long off_8;
@@ -114,7 +118,6 @@ struct mip_reg {
#define MIP_FUNC(VALUE) (VALUE & 0xff)
extern int parse_unisys_oem (char *oemptr);
-extern int find_unisys_acpi_oem_table(unsigned long *oem_addr);
extern void setup_unisys(void);
extern int es7000_start_cpu(int cpu, unsigned long eip);
extern void es7000_sw_apic(void);
diff --git a/arch/i386/mach-es7000/es7000plat.c b/arch/i386/mach-es7000/es7000plat.c
index a9ab0644f403..3d0fc853516d 100644
--- a/arch/i386/mach-es7000/es7000plat.c
+++ b/arch/i386/mach-es7000/es7000plat.c
@@ -51,8 +51,6 @@ struct mip_reg *host_reg;
int mip_port;
unsigned long mip_addr, host_addr;
-#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_ACPI)
-
/*
* GSI override for ES7000 platforms.
*/
@@ -76,8 +74,6 @@ es7000_rename_gsi(int ioapic, int gsi)
return gsi;
}
-#endif /* (CONFIG_X86_IO_APIC) && (CONFIG_ACPI) */
-
void __init
setup_unisys(void)
{
@@ -160,6 +156,7 @@ parse_unisys_oem (char *oemptr)
return es7000_plat;
}
+#ifdef CONFIG_ACPI
int __init
find_unisys_acpi_oem_table(unsigned long *oem_addr)
{
@@ -212,6 +209,7 @@ find_unisys_acpi_oem_table(unsigned long *oem_addr)
}
return -1;
}
+#endif
static void
es7000_spin(int n)
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
index cf572d9a3b6e..7f0fcf219a26 100644
--- a/arch/i386/mm/fault.c
+++ b/arch/i386/mm/fault.c
@@ -214,6 +214,68 @@ static noinline void force_sig_info_fault(int si_signo, int si_code,
fastcall void do_invalid_op(struct pt_regs *, unsigned long);
+static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
+{
+ unsigned index = pgd_index(address);
+ pgd_t *pgd_k;
+ pud_t *pud, *pud_k;
+ pmd_t *pmd, *pmd_k;
+
+ pgd += index;
+ pgd_k = init_mm.pgd + index;
+
+ if (!pgd_present(*pgd_k))
+ return NULL;
+
+ /*
+ * set_pgd(pgd, *pgd_k); here would be useless on PAE
+ * and redundant with the set_pmd() on non-PAE. As would
+ * set_pud.
+ */
+
+ pud = pud_offset(pgd, address);
+ pud_k = pud_offset(pgd_k, address);
+ if (!pud_present(*pud_k))
+ return NULL;
+
+ pmd = pmd_offset(pud, address);
+ pmd_k = pmd_offset(pud_k, address);
+ if (!pmd_present(*pmd_k))
+ return NULL;
+ if (!pmd_present(*pmd))
+ set_pmd(pmd, *pmd_k);
+ else
+ BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
+ return pmd_k;
+}
+
+/*
+ * Handle a fault on the vmalloc or module mapping area
+ *
+ * This assumes no large pages in there.
+ */
+static inline int vmalloc_fault(unsigned long address)
+{
+ unsigned long pgd_paddr;
+ pmd_t *pmd_k;
+ pte_t *pte_k;
+ /*
+ * Synchronize this task's top level page-table
+ * with the 'reference' page table.
+ *
+ * Do _not_ use "current" here. We might be inside
+ * an interrupt in the middle of a task switch..
+ */
+ pgd_paddr = read_cr3();
+ pmd_k = vmalloc_sync_one(__va(pgd_paddr), address);
+ if (!pmd_k)
+ return -1;
+ pte_k = pte_offset_kernel(pmd_k, address);
+ if (!pte_present(*pte_k))
+ return -1;
+ return 0;
+}
+
/*
* This routine handles page faults. It determines the address,
* and the problem, and then passes it off to one of the appropriate
@@ -223,6 +285,8 @@ fastcall void do_invalid_op(struct pt_regs *, unsigned long);
* bit 0 == 0 means no page found, 1 means protection fault
* bit 1 == 0 means read, 1 means write
* bit 2 == 0 means kernel, 1 means user-mode
+ * bit 3 == 1 means use of reserved bit detected
+ * bit 4 == 1 means fault was an instruction fetch
*/
fastcall void __kprobes do_page_fault(struct pt_regs *regs,
unsigned long error_code)
@@ -237,13 +301,6 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
/* get the address */
address = read_cr2();
- if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
- SIGSEGV) == NOTIFY_STOP)
- return;
- /* It's safe to allow irq's after cr2 has been saved */
- if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
- local_irq_enable();
-
tsk = current;
si_code = SEGV_MAPERR;
@@ -259,17 +316,29 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
*
* This verifies that the fault happens in kernel space
* (error_code & 4) == 0, and that the fault was not a
- * protection error (error_code & 1) == 0.
+ * protection error (error_code & 9) == 0.
*/
- if (unlikely(address >= TASK_SIZE)) {
- if (!(error_code & 5))
- goto vmalloc_fault;
- /*
+ if (unlikely(address >= TASK_SIZE)) {
+ if (!(error_code & 0x0000000d) && vmalloc_fault(address) >= 0)
+ return;
+ if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
+ SIGSEGV) == NOTIFY_STOP)
+ return;
+ /*
* Don't take the mm semaphore here. If we fixup a prefetch
* fault we could otherwise deadlock.
*/
goto bad_area_nosemaphore;
- }
+ }
+
+ if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
+ SIGSEGV) == NOTIFY_STOP)
+ return;
+
+ /* It's safe to allow irq's after cr2 has been saved and the vmalloc
+ fault has been handled. */
+ if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
+ local_irq_enable();
mm = tsk->mm;
@@ -440,24 +509,31 @@ no_context:
bust_spinlocks(1);
-#ifdef CONFIG_X86_PAE
- if (error_code & 16) {
- pte_t *pte = lookup_address(address);
+ if (oops_may_print()) {
+ #ifdef CONFIG_X86_PAE
+ if (error_code & 16) {
+ pte_t *pte = lookup_address(address);
- if (pte && pte_present(*pte) && !pte_exec_kernel(*pte))
- printk(KERN_CRIT "kernel tried to execute NX-protected page - exploit attempt? (uid: %d)\n", current->uid);
+ if (pte && pte_present(*pte) && !pte_exec_kernel(*pte))
+ printk(KERN_CRIT "kernel tried to execute "
+ "NX-protected page - exploit attempt? "
+ "(uid: %d)\n", current->uid);
+ }
+ #endif
+ if (address < PAGE_SIZE)
+ printk(KERN_ALERT "BUG: unable to handle kernel NULL "
+ "pointer dereference");
+ else
+ printk(KERN_ALERT "BUG: unable to handle kernel paging"
+ " request");
+ printk(" at virtual address %08lx\n",address);
+ printk(KERN_ALERT " printing eip:\n");
+ printk("%08lx\n", regs->eip);
}
-#endif
- if (address < PAGE_SIZE)
- printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
- else
- printk(KERN_ALERT "Unable to handle kernel paging request");
- printk(" at virtual address %08lx\n",address);
- printk(KERN_ALERT " printing eip:\n");
- printk("%08lx\n", regs->eip);
page = read_cr3();
page = ((unsigned long *) __va(page))[address >> 22];
- printk(KERN_ALERT "*pde = %08lx\n", page);
+ if (oops_may_print())
+ printk(KERN_ALERT "*pde = %08lx\n", page);
/*
* We must not directly access the pte in the highpte
* case, the page table might be allocated in highmem.
@@ -465,7 +541,7 @@ no_context:
* it's allocated already.
*/
#ifndef CONFIG_HIGHPTE
- if (page & 1) {
+ if ((page & 1) && oops_may_print()) {
page &= PAGE_MASK;
address &= 0x003ff000;
page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
@@ -510,51 +586,41 @@ do_sigbus:
tsk->thread.error_code = error_code;
tsk->thread.trap_no = 14;
force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk);
- return;
-
-vmalloc_fault:
- {
- /*
- * Synchronize this task's top level page-table
- * with the 'reference' page table.
- *
- * Do _not_ use "tsk" here. We might be inside
- * an interrupt in the middle of a task switch..
- */
- int index = pgd_index(address);
- unsigned long pgd_paddr;
- pgd_t *pgd, *pgd_k;
- pud_t *pud, *pud_k;
- pmd_t *pmd, *pmd_k;
- pte_t *pte_k;
-
- pgd_paddr = read_cr3();
- pgd = index + (pgd_t *)__va(pgd_paddr);
- pgd_k = init_mm.pgd + index;
-
- if (!pgd_present(*pgd_k))
- goto no_context;
-
- /*
- * set_pgd(pgd, *pgd_k); here would be useless on PAE
- * and redundant with the set_pmd() on non-PAE. As would
- * set_pud.
- */
+}
- pud = pud_offset(pgd, address);
- pud_k = pud_offset(pgd_k, address);
- if (!pud_present(*pud_k))
- goto no_context;
-
- pmd = pmd_offset(pud, address);
- pmd_k = pmd_offset(pud_k, address);
- if (!pmd_present(*pmd_k))
- goto no_context;
- set_pmd(pmd, *pmd_k);
+#ifndef CONFIG_X86_PAE
+void vmalloc_sync_all(void)
+{
+ /*
+ * Note that races in the updates of insync and start aren't
+ * problematic: insync can only get set bits added, and updates to
+ * start are only improving performance (without affecting correctness
+ * if undone).
+ */
+ static DECLARE_BITMAP(insync, PTRS_PER_PGD);
+ static unsigned long start = TASK_SIZE;
+ unsigned long address;
- pte_k = pte_offset_kernel(pmd_k, address);
- if (!pte_present(*pte_k))
- goto no_context;
- return;
+ BUILD_BUG_ON(TASK_SIZE & ~PGDIR_MASK);
+ for (address = start; address >= TASK_SIZE; address += PGDIR_SIZE) {
+ if (!test_bit(pgd_index(address), insync)) {
+ unsigned long flags;
+ struct page *page;
+
+ spin_lock_irqsave(&pgd_lock, flags);
+ for (page = pgd_list; page; page =
+ (struct page *)page->index)
+ if (!vmalloc_sync_one(page_address(page),
+ address)) {
+ BUG_ON(page != pgd_list);
+ break;
+ }
+ spin_unlock_irqrestore(&pgd_lock, flags);
+ if (!page)
+ set_bit(pgd_index(address), insync);
+ }
+ if (address == start && test_bit(pgd_index(address), insync))
+ start = address + PGDIR_SIZE;
}
}
+#endif
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 7ba55a6e2dbc..9f66ac582a8b 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -720,21 +720,6 @@ static int noinline do_test_wp_bit(void)
return flag;
}
-void free_initmem(void)
-{
- unsigned long addr;
-
- addr = (unsigned long)(&__init_begin);
- for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
- ClearPageReserved(virt_to_page(addr));
- init_page_count(virt_to_page(addr));
- memset((void *)addr, 0xcc, PAGE_SIZE);
- free_page(addr);
- totalram_pages++;
- }
- printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (__init_end - __init_begin) >> 10);
-}
-
#ifdef CONFIG_DEBUG_RODATA
extern char __start_rodata, __end_rodata;
@@ -758,17 +743,31 @@ void mark_rodata_ro(void)
}
#endif
+void free_init_pages(char *what, unsigned long begin, unsigned long end)
+{
+ unsigned long addr;
+
+ for (addr = begin; addr < end; addr += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(addr));
+ init_page_count(virt_to_page(addr));
+ memset((void *)addr, 0xcc, PAGE_SIZE);
+ free_page(addr);
+ totalram_pages++;
+ }
+ printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
+}
+
+void free_initmem(void)
+{
+ free_init_pages("unused kernel memory",
+ (unsigned long)(&__init_begin),
+ (unsigned long)(&__init_end));
+}
#ifdef CONFIG_BLK_DEV_INITRD
void free_initrd_mem(unsigned long start, unsigned long end)
{
- if (start < end)
- printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
- for (; start < end; start += PAGE_SIZE) {
- ClearPageReserved(virt_to_page(start));
- init_page_count(virt_to_page(start));
- free_page(start);
- totalram_pages++;
- }
+ free_init_pages("initrd memory", start, end);
}
#endif
+
diff --git a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
index 0493e8b8ec49..1accce50c2c7 100644
--- a/arch/i386/oprofile/nmi_int.c
+++ b/arch/i386/oprofile/nmi_int.c
@@ -122,7 +122,7 @@ static void nmi_save_registers(void * dummy)
static void free_msrs(void)
{
int i;
- for (i = 0; i < NR_CPUS; ++i) {
+ for_each_cpu(i) {
kfree(cpu_msrs[i].counters);
cpu_msrs[i].counters = NULL;
kfree(cpu_msrs[i].controls);
@@ -138,10 +138,7 @@ static int allocate_msrs(void)
size_t counters_size = sizeof(struct op_msr) * model->num_counters;
int i;
- for (i = 0; i < NR_CPUS; ++i) {
- if (!cpu_online(i))
- continue;
-
+ for_each_online_cpu(i) {
cpu_msrs[i].counters = kmalloc(counters_size, GFP_KERNEL);
if (!cpu_msrs[i].counters) {
success = 0;
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
index 626cdc83668b..0e5c6ae50228 100644
--- a/arch/ia64/hp/sim/simserial.c
+++ b/arch/ia64/hp/sim/simserial.c
@@ -46,11 +46,6 @@
#define KEYBOARD_INTR 3 /* must match with simulator! */
#define NR_PORTS 1 /* only one port for now */
-#define SERIAL_INLINE 1
-
-#ifdef SERIAL_INLINE
-#define _INLINE_ inline
-#endif
#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT)
@@ -237,7 +232,7 @@ static void rs_put_char(struct tty_struct *tty, unsigned char ch)
local_irq_restore(flags);
}
-static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
+static void transmit_chars(struct async_struct *info, int *intr_done)
{
int count;
unsigned long flags;
diff --git a/arch/m32r/kernel/irq.c b/arch/m32r/kernel/irq.c
index 1ce63926a3c0..a4634b06f675 100644
--- a/arch/m32r/kernel/irq.c
+++ b/arch/m32r/kernel/irq.c
@@ -37,9 +37,8 @@ int show_interrupts(struct seq_file *p, void *v)
if (i == 0) {
seq_printf(p, " ");
- for (j=0; j<NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "CPU%d ",j);
+ for_each_online_cpu(j)
+ seq_printf(p, "CPU%d ",j);
seq_putc(p, '\n');
}
@@ -52,9 +51,8 @@ int show_interrupts(struct seq_file *p, void *v)
#ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i));
#else
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
#endif
seq_printf(p, " %14s", irq_desc[i].handler->typename);
seq_printf(p, " %s", action->name);
diff --git a/arch/m68k/bvme6000/rtc.c b/arch/m68k/bvme6000/rtc.c
index 703cbc6dc9cc..15c16b62dff5 100644
--- a/arch/m68k/bvme6000/rtc.c
+++ b/arch/m68k/bvme6000/rtc.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/mc146818rtc.h> /* For struct rtc_time and ioctls, etc */
#include <linux/smp_lock.h>
+#include <linux/bcd.h>
#include <asm/bvme6000hw.h>
#include <asm/io.h>
@@ -32,9 +33,6 @@
* ioctls.
*/
-#define BCD2BIN(val) (((val)&15) + ((val)>>4)*10)
-#define BIN2BCD(val) ((((val)/10)<<4) + (val)%10)
-
static unsigned char days_in_mo[] =
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index 7d93992e462c..3dd76b3d2967 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -68,9 +68,8 @@ int show_interrupts(struct seq_file *p, void *v)
if (i == 0) {
seq_printf(p, " ");
- for (j=0; j<NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "CPU%d ",j);
+ for_each_online_cpu(j)
+ seq_printf(p, "CPU%d ",j);
seq_putc(p, '\n');
}
@@ -83,9 +82,8 @@ int show_interrupts(struct seq_file *p, void *v)
#ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i));
#else
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
#endif
seq_printf(p, " %14s", irq_desc[i].handler->typename);
seq_printf(p, " %s", action->name);
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 06ed90752424..78d171bfa331 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -167,8 +167,8 @@ int smp_call_function (void (*func) (void *info), void *info, int retry,
mb();
/* Send a message to all other CPUs and wait for them to respond */
- for (i = 0; i < NR_CPUS; i++)
- if (cpu_online(i) && i != cpu)
+ for_each_online_cpu(i)
+ if (i != cpu)
core_send_ipi(i, SMP_CALL_FUNCTION);
/* Wait for response */
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index 73e5e52781d8..2854ac4c9be1 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -88,12 +88,9 @@ static inline int find_level(cpuid_t *cpunum, int irq)
{
int cpu, i;
- for (cpu = 0; cpu <= NR_CPUS; cpu++) {
+ for_each_online_cpu(cpu) {
struct slice_data *si = cpu_data[cpu].data;
- if (!cpu_online(cpu))
- continue;
-
for (i = BASE_PCI_IRQ; i < LEVELS_PER_SLICE; i++)
if (si->level_to_irq[i] == irq) {
*cpunum = cpu;
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 25564b7ca6bb..d6ac1c60a471 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -298,8 +298,8 @@ send_IPI_allbutself(enum ipi_message_type op)
{
int i;
- for (i = 0; i < NR_CPUS; i++) {
- if (cpu_online(i) && i != smp_processor_id())
+ for_each_online_cpu(i) {
+ if (i != smp_processor_id())
send_IPI_single(i, op);
}
}
@@ -643,14 +643,13 @@ int sys_cpus(int argc, char **argv)
if ( argc == 1 ){
#ifdef DUMP_MORE_STATE
- for(i=0; i<NR_CPUS; i++) {
+ for_each_online_cpu(i) {
int cpus_per_line = 4;
- if(cpu_online(i)) {
- if (j++ % cpus_per_line)
- printk(" %3d",i);
- else
- printk("\n %3d",i);
- }
+
+ if (j++ % cpus_per_line)
+ printk(" %3d",i);
+ else
+ printk("\n %3d",i);
}
printk("\n");
#else
@@ -659,9 +658,7 @@ int sys_cpus(int argc, char **argv)
} else if((argc==2) && !(strcmp(argv[1],"-l"))) {
printk("\nCPUSTATE TASK CPUNUM CPUID HARDCPU(HPA)\n");
#ifdef DUMP_MORE_STATE
- for(i=0;i<NR_CPUS;i++) {
- if (!cpu_online(i))
- continue;
+ for_each_online_cpu(i) {
if (cpu_data[i].cpuid != NO_PROC_ID) {
switch(cpu_data[i].state) {
case STATE_RENDEZVOUS:
@@ -695,9 +692,7 @@ int sys_cpus(int argc, char **argv)
} else if ((argc==2) && !(strcmp(argv[1],"-s"))) {
#ifdef DUMP_MORE_STATE
printk("\nCPUSTATE CPUID\n");
- for (i=0;i<NR_CPUS;i++) {
- if (!cpu_online(i))
- continue;
+ for_each_online_cpu(i) {
if (cpu_data[i].cpuid != NO_PROC_ID) {
switch(cpu_data[i].state) {
case STATE_RENDEZVOUS:
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index dfba81719dec..fae42da7468d 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -127,6 +127,12 @@ config PPC_83xx
select 83xx
select PPC_FPU
+config PPC_85xx
+ bool "Freescale 85xx"
+ select E500
+ select FSL_SOC
+ select 85xx
+
config 40x
bool "AMCC 40x"
@@ -139,8 +145,6 @@ config 8xx
config E200
bool "Freescale e200"
-config E500
- bool "Freescale e500"
endchoice
config POWER4_ONLY
@@ -168,6 +172,13 @@ config 6xx
config 83xx
bool
+# this is temp to handle compat with arch=ppc
+config 85xx
+ bool
+
+config E500
+ bool
+
config PPC_FPU
bool
default y if PPC64
@@ -217,6 +228,7 @@ config ALTIVEC
config SPE
bool "SPE Support"
depends on E200 || E500
+ default y
---help---
This option enables kernel support for the Signal Processing
Extensions (SPE) to the PowerPC processor. The kernel currently
@@ -238,6 +250,21 @@ config PPC_STD_MMU_32
def_bool y
depends on PPC_STD_MMU && PPC32
+config VIRT_CPU_ACCOUNTING
+ bool "Deterministic task and CPU time accounting"
+ depends on PPC64
+ default y
+ help
+ Select this option to enable more accurate task and CPU time
+ accounting. This is done by reading a CPU counter on each
+ kernel entry and exit and on transitions within the kernel
+ between system, softirq and hardirq state, so there is a
+ small performance impact. This also enables accounting of
+ stolen time on logically-partitioned systems running on
+ IBM POWER5-based machines.
+
+ If in doubt, say Y here.
+
config SMP
depends on PPC_STD_MMU
bool "Symmetric multi-processing support"
@@ -734,13 +761,12 @@ config GENERIC_ISA_DMA
config PPC_I8259
bool
- default y if 85xx
default n
config PPC_INDIRECT_PCI
bool
depends on PCI
- default y if 40x || 44x || 85xx
+ default y if 40x || 44x
default n
config EISA
@@ -757,8 +783,8 @@ config MCA
bool
config PCI
- bool "PCI support" if 40x || CPM2 || PPC_83xx || 85xx || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES)
- default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx && !85xx
+ bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES)
+ default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx && !PPC_85xx
default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS
default PCI_QSPAN if !4xx && !CPM2 && 8xx
help
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 5500ab55d042..a3fc7a23158f 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -148,7 +148,7 @@ all: $(KBUILD_IMAGE)
CPPFLAGS_vmlinux.lds := -Upowerpc
-BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm uImage
+BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm uImage vmlinux.bin
.PHONY: $(BOOT_TARGETS)
diff --git a/arch/powerpc/boot/install.sh b/arch/powerpc/boot/install.sh
index eacce9590816..b002bfd56786 100644
--- a/arch/powerpc/boot/install.sh
+++ b/arch/powerpc/boot/install.sh
@@ -1,7 +1,5 @@
#!/bin/sh
#
-# arch/ppc64/boot/install.sh
-#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c
index 55ec59867250..816446f0e497 100644
--- a/arch/powerpc/boot/main.c
+++ b/arch/powerpc/boot/main.c
@@ -152,7 +152,7 @@ static int is_elf64(void *hdr)
elf64ph = (Elf64_Phdr *)((unsigned long)elf64 +
(unsigned long)elf64->e_phoff);
for (i = 0; i < (unsigned int)elf64->e_phnum; i++, elf64ph++)
- if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0)
+ if (elf64ph->p_type == PT_LOAD)
break;
if (i >= (unsigned int)elf64->e_phnum)
return 0;
@@ -193,7 +193,7 @@ static int is_elf32(void *hdr)
elf32 = (Elf32_Ehdr *)elfheader;
elf32ph = (Elf32_Phdr *) ((unsigned long)elf32 + elf32->e_phoff);
for (i = 0; i < elf32->e_phnum; i++, elf32ph++)
- if (elf32ph->p_type == PT_LOAD && elf32ph->p_offset != 0)
+ if (elf32ph->p_type == PT_LOAD)
break;
if (i >= elf32->e_phnum)
return 0;
diff --git a/arch/powerpc/configs/mpc8540_ads_defconfig b/arch/powerpc/configs/mpc8540_ads_defconfig
new file mode 100644
index 000000000000..2a8290ee15c6
--- /dev/null
+++ b/arch/powerpc/configs/mpc8540_ads_defconfig
@@ -0,0 +1,721 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version:
+# Sat Jan 14 15:57:54 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_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
+
+#
+# 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_CLEAN_COMPILE=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_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_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+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
+
+#
+# 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=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 is not set
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_FSL_SOC=y
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# PCI Hotplug Support
+#
+
+#
+# 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_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_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_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC 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_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_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 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
+#
+
+#
+# I2O device support
+#
+
+#
+# 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
+
+#
+# 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
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_GIANFAR=y
+CONFIG_GFAR_NAPI=y
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN 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_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_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
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP 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
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# 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 is not set
+# CONFIG_USB_ARCH_HAS_OHCI 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
+
+#
+# InfiniBand support
+#
+
+#
+# SN Devices
+#
+
+#
+# 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_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_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_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_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
+#
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index c9a660e4c2db..882889b15926 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -136,6 +136,9 @@ int main(void)
DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
DEFINE(PACALPPACAPTR, offsetof(struct paca_struct, lppaca_ptr));
DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
+ DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
+ DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
+ DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index e4e81374cb9a..39e348a3ade2 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -894,7 +894,7 @@ struct cpu_spec cpu_specs[] = {
.platform = "ppc405",
},
{ /* Xilinx Virtex-II Pro */
- .pvr_mask = 0xffff0000,
+ .pvr_mask = 0xfffff000,
.pvr_value = 0x20010000,
.cpu_name = "Virtex-II Pro",
.cpu_features = CPU_FTRS_40X,
@@ -904,6 +904,16 @@ struct cpu_spec cpu_specs[] = {
.dcache_bsize = 32,
.platform = "ppc405",
},
+ { /* Xilinx Virtex-4 FX */
+ .pvr_mask = 0xfffff000,
+ .pvr_value = 0x20011000,
+ .cpu_name = "Virtex-4 FX",
+ .cpu_features = CPU_FTRS_40X,
+ .cpu_user_features = PPC_FEATURE_32 |
+ PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ .icache_bsize = 32,
+ .dcache_bsize = 32,
+ },
{ /* 405EP */
.pvr_mask = 0xffff0000,
.pvr_value = 0x51210000,
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 24be0cf86d7f..1060155d84c3 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -1,6 +1,4 @@
/*
- * arch/ppc64/kernel/entry.S
- *
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
* Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
@@ -63,6 +61,7 @@ system_call_common:
std r12,_MSR(r1)
std r0,GPR0(r1)
std r10,GPR1(r1)
+ ACCOUNT_CPU_USER_ENTRY(r10, r11)
std r2,GPR2(r1)
std r3,GPR3(r1)
std r4,GPR4(r1)
@@ -170,8 +169,9 @@ syscall_error_cont:
stdcx. r0,0,r1 /* to clear the reservation */
andi. r6,r8,MSR_PR
ld r4,_LINK(r1)
- beq- 1f /* only restore r13 if */
- ld r13,GPR13(r1) /* returning to usermode */
+ beq- 1f
+ ACCOUNT_CPU_USER_EXIT(r11, r12)
+ ld r13,GPR13(r1) /* only restore r13 if returning to usermode */
1: ld r2,GPR2(r1)
li r12,MSR_RI
andc r11,r10,r12
@@ -322,7 +322,7 @@ _GLOBAL(ret_from_fork)
* the fork code also.
*
* The code which creates the new task context is in 'copy_thread'
- * in arch/ppc64/kernel/process.c
+ * in arch/powerpc/kernel/process.c
*/
.align 7
_GLOBAL(_switch)
@@ -486,6 +486,7 @@ restore:
* userspace
*/
beq 1f
+ ACCOUNT_CPU_USER_EXIT(r3, r4)
REST_GPR(13, r1)
1:
ld r3,_CTR(r1)
diff --git a/arch/powerpc/kernel/firmware.c b/arch/powerpc/kernel/firmware.c
index 65eae752a527..4d37a3cb80f6 100644
--- a/arch/powerpc/kernel/firmware.c
+++ b/arch/powerpc/kernel/firmware.c
@@ -18,28 +18,3 @@
#include <asm/firmware.h>
unsigned long ppc64_firmware_features;
-
-#ifdef CONFIG_PPC_PSERIES
-firmware_feature_t firmware_features_table[FIRMWARE_MAX_FEATURES] = {
- {FW_FEATURE_PFT, "hcall-pft"},
- {FW_FEATURE_TCE, "hcall-tce"},
- {FW_FEATURE_SPRG0, "hcall-sprg0"},
- {FW_FEATURE_DABR, "hcall-dabr"},
- {FW_FEATURE_COPY, "hcall-copy"},
- {FW_FEATURE_ASR, "hcall-asr"},
- {FW_FEATURE_DEBUG, "hcall-debug"},
- {FW_FEATURE_PERF, "hcall-perf"},
- {FW_FEATURE_DUMP, "hcall-dump"},
- {FW_FEATURE_INTERRUPT, "hcall-interrupt"},
- {FW_FEATURE_MIGRATE, "hcall-migrate"},
- {FW_FEATURE_PERFMON, "hcall-perfmon"},
- {FW_FEATURE_CRQ, "hcall-crq"},
- {FW_FEATURE_VIO, "hcall-vio"},
- {FW_FEATURE_RDMA, "hcall-rdma"},
- {FW_FEATURE_LLAN, "hcall-lLAN"},
- {FW_FEATURE_BULK, "hcall-bulk"},
- {FW_FEATURE_XDABR, "hcall-xdabr"},
- {FW_FEATURE_MULTITCE, "hcall-multi-tce"},
- {FW_FEATURE_SPLPAR, "hcall-splpar"},
-};
-#endif
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index 8b49679fad54..47c7fa148c9a 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/head_44x.S
- *
* Kernel execution entry point code.
*
* Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 9b65029dd2a3..35084f3a841b 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -1,6 +1,4 @@
/*
- * arch/ppc64/kernel/head.S
- *
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
@@ -279,6 +277,7 @@ exception_marker:
std r10,0(r1); /* make stack chain pointer */ \
std r0,GPR0(r1); /* save r0 in stackframe */ \
std r10,GPR1(r1); /* save r1 in stackframe */ \
+ ACCOUNT_CPU_USER_ENTRY(r9, r10); \
std r2,GPR2(r1); /* save r2 in stackframe */ \
SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \
SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \
@@ -846,6 +845,14 @@ fast_exception_return:
ld r11,_NIP(r1)
andi. r3,r12,MSR_RI /* check if RI is set */
beq- unrecov_fer
+
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ andi. r3,r12,MSR_PR
+ beq 2f
+ ACCOUNT_CPU_USER_EXIT(r3, r4)
+2:
+#endif
+
ld r3,_CCR(r1)
ld r4,_LINK(r1)
ld r5,_CTR(r1)
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index bc6d1ac55235..28941f5ce673 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/except_8xx.S
- *
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
* Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
new file mode 100644
index 000000000000..8536e7676160
--- /dev/null
+++ b/arch/powerpc/kernel/head_booke.h
@@ -0,0 +1,363 @@
+#ifndef __HEAD_BOOKE_H__
+#define __HEAD_BOOKE_H__
+
+/*
+ * Macros used for common Book-e exception handling
+ */
+
+#define SET_IVOR(vector_number, vector_label) \
+ li r26,vector_label@l; \
+ mtspr SPRN_IVOR##vector_number,r26; \
+ sync
+
+#define NORMAL_EXCEPTION_PROLOG \
+ mtspr SPRN_SPRG0,r10; /* save two registers to work with */\
+ mtspr SPRN_SPRG1,r11; \
+ mtspr SPRN_SPRG4W,r1; \
+ mfcr r10; /* save CR in r10 for now */\
+ mfspr r11,SPRN_SRR1; /* check whether user or kernel */\
+ andi. r11,r11,MSR_PR; \
+ beq 1f; \
+ mfspr r1,SPRN_SPRG3; /* if from user, start at top of */\
+ lwz r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack */\
+ addi r1,r1,THREAD_SIZE; \
+1: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\
+ mr r11,r1; \
+ stw r10,_CCR(r11); /* save various registers */\
+ stw r12,GPR12(r11); \
+ stw r9,GPR9(r11); \
+ mfspr r10,SPRN_SPRG0; \
+ stw r10,GPR10(r11); \
+ mfspr r12,SPRN_SPRG1; \
+ stw r12,GPR11(r11); \
+ mflr r10; \
+ stw r10,_LINK(r11); \
+ mfspr r10,SPRN_SPRG4R; \
+ mfspr r12,SPRN_SRR0; \
+ stw r10,GPR1(r11); \
+ mfspr r9,SPRN_SRR1; \
+ stw r10,0(r11); \
+ rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
+ stw r0,GPR0(r11); \
+ SAVE_4GPRS(3, r11); \
+ SAVE_2GPRS(7, r11)
+
+/* To handle the additional exception priority levels on 40x and Book-E
+ * processors we allocate a 4k stack per additional priority level. The various
+ * head_xxx.S files allocate space (exception_stack_top) for each priority's
+ * stack times the number of CPUs
+ *
+ * On 40x critical is the only additional level
+ * On 44x/e500 we have critical and machine check
+ * On e200 we have critical and debug (machine check occurs via critical)
+ *
+ * Additionally we reserve a SPRG for each priority level so we can free up a
+ * GPR to use as the base for indirect access to the exception stacks. This
+ * is necessary since the MMU is always on, for Book-E parts, and the stacks
+ * are offset from KERNELBASE.
+ *
+ */
+#define BOOKE_EXCEPTION_STACK_SIZE (8192)
+
+/* CRIT_SPRG only used in critical exception handling */
+#define CRIT_SPRG SPRN_SPRG2
+/* MCHECK_SPRG only used in machine check exception handling */
+#define MCHECK_SPRG SPRN_SPRG6W
+
+#define MCHECK_STACK_TOP (exception_stack_top - 4096)
+#define CRIT_STACK_TOP (exception_stack_top)
+
+/* only on e200 for now */
+#define DEBUG_STACK_TOP (exception_stack_top - 4096)
+#define DEBUG_SPRG SPRN_SPRG6W
+
+#ifdef CONFIG_SMP
+#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
+ mfspr r8,SPRN_PIR; \
+ mulli r8,r8,BOOKE_EXCEPTION_STACK_SIZE; \
+ neg r8,r8; \
+ addis r8,r8,level##_STACK_TOP@ha; \
+ addi r8,r8,level##_STACK_TOP@l
+#else
+#define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
+ lis r8,level##_STACK_TOP@h; \
+ ori r8,r8,level##_STACK_TOP@l
+#endif
+
+/*
+ * Exception prolog for critical/machine check exceptions. This is a
+ * little different from the normal exception prolog above since a
+ * critical/machine check exception can potentially occur at any point
+ * during normal exception processing. Thus we cannot use the same SPRG
+ * registers as the normal prolog above. Instead we use a portion of the
+ * critical/machine check exception stack at low physical addresses.
+ */
+#define EXC_LEVEL_EXCEPTION_PROLOG(exc_level, exc_level_srr0, exc_level_srr1) \
+ mtspr exc_level##_SPRG,r8; \
+ BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);/* r8 points to the exc_level stack*/ \
+ stw r10,GPR10-INT_FRAME_SIZE(r8); \
+ stw r11,GPR11-INT_FRAME_SIZE(r8); \
+ mfcr r10; /* save CR in r10 for now */\
+ mfspr r11,exc_level_srr1; /* check whether user or kernel */\
+ andi. r11,r11,MSR_PR; \
+ mr r11,r8; \
+ mfspr r8,exc_level##_SPRG; \
+ beq 1f; \
+ /* COMING FROM USER MODE */ \
+ mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
+ lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
+ addi r11,r11,THREAD_SIZE; \
+1: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\
+ stw r10,_CCR(r11); /* save various registers */\
+ stw r12,GPR12(r11); \
+ stw r9,GPR9(r11); \
+ mflr r10; \
+ stw r10,_LINK(r11); \
+ mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\
+ stw r12,_DEAR(r11); /* since they may have had stuff */\
+ mfspr r9,SPRN_ESR; /* in them at the point where the */\
+ stw r9,_ESR(r11); /* exception was taken */\
+ mfspr r12,exc_level_srr0; \
+ stw r1,GPR1(r11); \
+ mfspr r9,exc_level_srr1; \
+ stw r1,0(r11); \
+ mr r1,r11; \
+ rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
+ stw r0,GPR0(r11); \
+ SAVE_4GPRS(3, r11); \
+ SAVE_2GPRS(7, r11)
+
+#define CRITICAL_EXCEPTION_PROLOG \
+ EXC_LEVEL_EXCEPTION_PROLOG(CRIT, SPRN_CSRR0, SPRN_CSRR1)
+#define DEBUG_EXCEPTION_PROLOG \
+ EXC_LEVEL_EXCEPTION_PROLOG(DEBUG, SPRN_DSRR0, SPRN_DSRR1)
+#define MCHECK_EXCEPTION_PROLOG \
+ EXC_LEVEL_EXCEPTION_PROLOG(MCHECK, SPRN_MCSRR0, SPRN_MCSRR1)
+
+/*
+ * Exception vectors.
+ */
+#define START_EXCEPTION(label) \
+ .align 5; \
+label:
+
+#define FINISH_EXCEPTION(func) \
+ bl transfer_to_handler_full; \
+ .long func; \
+ .long ret_from_except_full
+
+#define EXCEPTION(n, label, hdlr, xfer) \
+ START_EXCEPTION(label); \
+ NORMAL_EXCEPTION_PROLOG; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ xfer(n, hdlr)
+
+#define CRITICAL_EXCEPTION(n, label, hdlr) \
+ START_EXCEPTION(label); \
+ CRITICAL_EXCEPTION_PROLOG; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
+ NOCOPY, crit_transfer_to_handler, \
+ ret_from_crit_exc)
+
+#define MCHECK_EXCEPTION(n, label, hdlr) \
+ START_EXCEPTION(label); \
+ MCHECK_EXCEPTION_PROLOG; \
+ mfspr r5,SPRN_ESR; \
+ stw r5,_ESR(r11); \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
+ NOCOPY, mcheck_transfer_to_handler, \
+ ret_from_mcheck_exc)
+
+#define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret) \
+ li r10,trap; \
+ stw r10,_TRAP(r11); \
+ lis r10,msr@h; \
+ ori r10,r10,msr@l; \
+ copyee(r10, r9); \
+ bl tfer; \
+ .long hdlr; \
+ .long ret
+
+#define COPY_EE(d, s) rlwimi d,s,0,16,16
+#define NOCOPY(d, s)
+
+#define EXC_XFER_STD(n, hdlr) \
+ EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, NOCOPY, transfer_to_handler_full, \
+ ret_from_except_full)
+
+#define EXC_XFER_LITE(n, hdlr) \
+ EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \
+ ret_from_except)
+
+#define EXC_XFER_EE(n, hdlr) \
+ EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, COPY_EE, transfer_to_handler_full, \
+ ret_from_except_full)
+
+#define EXC_XFER_EE_LITE(n, hdlr) \
+ EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \
+ ret_from_except)
+
+/* Check for a single step debug exception while in an exception
+ * handler before state has been saved. This is to catch the case
+ * where an instruction that we are trying to single step causes
+ * an exception (eg ITLB/DTLB miss) and thus the first instruction of
+ * the exception handler generates a single step debug exception.
+ *
+ * If we get a debug trap on the first instruction of an exception handler,
+ * we reset the MSR_DE in the _exception handler's_ MSR (the debug trap is
+ * a critical exception, so we are using SPRN_CSRR1 to manipulate the MSR).
+ * The exception handler was handling a non-critical interrupt, so it will
+ * save (and later restore) the MSR via SPRN_CSRR1, which will still have
+ * the MSR_DE bit set.
+ */
+#ifdef CONFIG_E200
+#define DEBUG_EXCEPTION \
+ START_EXCEPTION(Debug); \
+ DEBUG_EXCEPTION_PROLOG; \
+ \
+ /* \
+ * If there is a single step or branch-taken exception in an \
+ * exception entry sequence, it was probably meant to apply to \
+ * the code where the exception occurred (since exception entry \
+ * doesn't turn off DE automatically). We simulate the effect \
+ * of turning off DE on entry to an exception handler by turning \
+ * off DE in the CSRR1 value and clearing the debug status. \
+ */ \
+ mfspr r10,SPRN_DBSR; /* check single-step/branch taken */ \
+ andis. r10,r10,DBSR_IC@h; \
+ beq+ 2f; \
+ \
+ lis r10,KERNELBASE@h; /* check if exception in vectors */ \
+ ori r10,r10,KERNELBASE@l; \
+ cmplw r12,r10; \
+ blt+ 2f; /* addr below exception vectors */ \
+ \
+ lis r10,Debug@h; \
+ ori r10,r10,Debug@l; \
+ cmplw r12,r10; \
+ bgt+ 2f; /* addr above exception vectors */ \
+ \
+ /* here it looks like we got an inappropriate debug exception. */ \
+1: rlwinm r9,r9,0,~MSR_DE; /* clear DE in the CDRR1 value */ \
+ lis r10,DBSR_IC@h; /* clear the IC event */ \
+ mtspr SPRN_DBSR,r10; \
+ /* restore state and get out */ \
+ lwz r10,_CCR(r11); \
+ lwz r0,GPR0(r11); \
+ lwz r1,GPR1(r11); \
+ mtcrf 0x80,r10; \
+ mtspr SPRN_DSRR0,r12; \
+ mtspr SPRN_DSRR1,r9; \
+ lwz r9,GPR9(r11); \
+ lwz r12,GPR12(r11); \
+ mtspr DEBUG_SPRG,r8; \
+ BOOKE_LOAD_EXC_LEVEL_STACK(DEBUG); /* r8 points to the debug stack */ \
+ lwz r10,GPR10-INT_FRAME_SIZE(r8); \
+ lwz r11,GPR11-INT_FRAME_SIZE(r8); \
+ mfspr r8,DEBUG_SPRG; \
+ \
+ RFDI; \
+ b .; \
+ \
+ /* continue normal handling for a critical exception... */ \
+2: mfspr r4,SPRN_DBSR; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, debug_transfer_to_handler, ret_from_debug_exc)
+#else
+#define DEBUG_EXCEPTION \
+ START_EXCEPTION(Debug); \
+ CRITICAL_EXCEPTION_PROLOG; \
+ \
+ /* \
+ * If there is a single step or branch-taken exception in an \
+ * exception entry sequence, it was probably meant to apply to \
+ * the code where the exception occurred (since exception entry \
+ * doesn't turn off DE automatically). We simulate the effect \
+ * of turning off DE on entry to an exception handler by turning \
+ * off DE in the CSRR1 value and clearing the debug status. \
+ */ \
+ mfspr r10,SPRN_DBSR; /* check single-step/branch taken */ \
+ andis. r10,r10,DBSR_IC@h; \
+ beq+ 2f; \
+ \
+ lis r10,KERNELBASE@h; /* check if exception in vectors */ \
+ ori r10,r10,KERNELBASE@l; \
+ cmplw r12,r10; \
+ blt+ 2f; /* addr below exception vectors */ \
+ \
+ lis r10,Debug@h; \
+ ori r10,r10,Debug@l; \
+ cmplw r12,r10; \
+ bgt+ 2f; /* addr above exception vectors */ \
+ \
+ /* here it looks like we got an inappropriate debug exception. */ \
+1: rlwinm r9,r9,0,~MSR_DE; /* clear DE in the CSRR1 value */ \
+ lis r10,DBSR_IC@h; /* clear the IC event */ \
+ mtspr SPRN_DBSR,r10; \
+ /* restore state and get out */ \
+ lwz r10,_CCR(r11); \
+ lwz r0,GPR0(r11); \
+ lwz r1,GPR1(r11); \
+ mtcrf 0x80,r10; \
+ mtspr SPRN_CSRR0,r12; \
+ mtspr SPRN_CSRR1,r9; \
+ lwz r9,GPR9(r11); \
+ lwz r12,GPR12(r11); \
+ mtspr CRIT_SPRG,r8; \
+ BOOKE_LOAD_EXC_LEVEL_STACK(CRIT); /* r8 points to the debug stack */ \
+ lwz r10,GPR10-INT_FRAME_SIZE(r8); \
+ lwz r11,GPR11-INT_FRAME_SIZE(r8); \
+ mfspr r8,CRIT_SPRG; \
+ \
+ rfci; \
+ b .; \
+ \
+ /* continue normal handling for a critical exception... */ \
+2: mfspr r4,SPRN_DBSR; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ EXC_XFER_TEMPLATE(DebugException, 0x2002, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), NOCOPY, crit_transfer_to_handler, ret_from_crit_exc)
+#endif
+
+#define INSTRUCTION_STORAGE_EXCEPTION \
+ START_EXCEPTION(InstructionStorage) \
+ NORMAL_EXCEPTION_PROLOG; \
+ mfspr r5,SPRN_ESR; /* Grab the ESR and save it */ \
+ stw r5,_ESR(r11); \
+ mr r4,r12; /* Pass SRR0 as arg2 */ \
+ li r5,0; /* Pass zero as arg3 */ \
+ EXC_XFER_EE_LITE(0x0400, handle_page_fault)
+
+#define ALIGNMENT_EXCEPTION \
+ START_EXCEPTION(Alignment) \
+ NORMAL_EXCEPTION_PROLOG; \
+ mfspr r4,SPRN_DEAR; /* Grab the DEAR and save it */ \
+ stw r4,_DEAR(r11); \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ EXC_XFER_EE(0x0600, alignment_exception)
+
+#define PROGRAM_EXCEPTION \
+ START_EXCEPTION(Program) \
+ NORMAL_EXCEPTION_PROLOG; \
+ mfspr r4,SPRN_ESR; /* Grab the ESR and save it */ \
+ stw r4,_ESR(r11); \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ EXC_XFER_STD(0x0700, program_check_exception)
+
+#define DECREMENTER_EXCEPTION \
+ START_EXCEPTION(Decrementer) \
+ NORMAL_EXCEPTION_PROLOG; \
+ lis r0,TSR_DIS@h; /* Setup the DEC interrupt mask */ \
+ mtspr SPRN_TSR,r0; /* Clear the DEC interrupt */ \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ EXC_XFER_LITE(0x0900, timer_interrupt)
+
+#define FP_UNAVAILABLE_EXCEPTION \
+ START_EXCEPTION(FloatingPointUnavailable) \
+ NORMAL_EXCEPTION_PROLOG; \
+ bne load_up_fpu; /* if from user, just load it up */ \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ EXC_XFER_EE_LITE(0x800, kernel_fp_unavailable_exception)
+
+#endif /* __HEAD_BOOKE_H__ */
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index 8d60fa99fc4b..dd86bbed7627 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/head_fsl_booke.S
- *
* Kernel execution entry point code.
*
* Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
@@ -316,6 +314,7 @@ skpinv: addi r6,r6,1 /* Increment */
*/
lis r2,DBCR0_IDM@h
mtspr SPRN_DBCR0,r2
+ isync
/* clear any residual debug events */
li r2,-1
mtspr SPRN_DBSR,r2
@@ -1002,12 +1001,15 @@ _GLOBAL(giveup_fpu)
_GLOBAL(abort)
li r13,0
mtspr SPRN_DBCR0,r13 /* disable all debug events */
+ isync
mfmsr r13
ori r13,r13,MSR_DE@l /* Enable Debug Events */
mtmsr r13
+ isync
mfspr r13,SPRN_DBCR0
lis r13,(DBCR0_IDM|DBCR0_RST_CHIP)@h
mtspr SPRN_DBCR0,r13
+ isync
_GLOBAL(set_context)
diff --git a/arch/powerpc/kernel/iomap.c b/arch/powerpc/kernel/iomap.c
index 6160c8dbb7c5..fd8214caedee 100644
--- a/arch/powerpc/kernel/iomap.c
+++ b/arch/powerpc/kernel/iomap.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc64/kernel/iomap.c
- *
* ppc64 "iomap" interface implementation.
*
* (C) Copyright 2004 Linus Torvalds
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 946f3219fd29..d9a7fdef59b9 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -1,5 +1,4 @@
/*
- * arch/ppc64/kernel/iommu.c
* Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
*
* Rewrite, cleanup, new allocation schemes, virtual merging:
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index d1fffce86df9..771a59cbd213 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/irq.c
- *
* Derived from arch/i386/kernel/irq.c
* Copyright (C) 1992 Linus Torvalds
* Adapted from arch/i386 by Gary Thomas
@@ -137,9 +135,8 @@ skip:
#ifdef CONFIG_TAU_INT
if (tau_initialized){
seq_puts(p, "TAU: ");
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "%10u ", tau_interrupts(j));
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", tau_interrupts(j));
seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n");
}
#endif
@@ -371,6 +368,7 @@ unsigned int real_irq_to_virt_slowpath(unsigned int real_irq)
return NO_IRQ;
}
+#endif /* CONFIG_PPC64 */
#ifdef CONFIG_IRQSTACKS
struct thread_info *softirq_ctx[NR_CPUS];
@@ -394,10 +392,24 @@ void irq_ctx_init(void)
}
}
+static inline void do_softirq_onstack(void)
+{
+ struct thread_info *curtp, *irqtp;
+
+ curtp = current_thread_info();
+ irqtp = softirq_ctx[smp_processor_id()];
+ irqtp->task = curtp->task;
+ call_do_softirq(irqtp);
+ irqtp->task = NULL;
+}
+
+#else
+#define do_softirq_onstack() __do_softirq()
+#endif /* CONFIG_IRQSTACKS */
+
void do_softirq(void)
{
unsigned long flags;
- struct thread_info *curtp, *irqtp;
if (in_interrupt())
return;
@@ -405,19 +417,18 @@ void do_softirq(void)
local_irq_save(flags);
if (local_softirq_pending()) {
- curtp = current_thread_info();
- irqtp = softirq_ctx[smp_processor_id()];
- irqtp->task = curtp->task;
- call_do_softirq(irqtp);
- irqtp->task = NULL;
+ account_system_vtime(current);
+ local_bh_disable();
+ do_softirq_onstack();
+ account_system_vtime(current);
+ __local_bh_enable();
}
local_irq_restore(flags);
}
EXPORT_SYMBOL(do_softirq);
-#endif /* CONFIG_IRQSTACKS */
-
+#ifdef CONFIG_PPC64
static int __init setup_noirqdistrib(char *str)
{
distribute_irqs = 0;
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index cfab48566db1..cb1fe5878e8b 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -1,6 +1,5 @@
/*
* Kernel Probes (KProbes)
- * arch/ppc64/kernel/kprobes.c
*
* 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
@@ -82,9 +81,9 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)
void __kprobes arch_remove_kprobe(struct kprobe *p)
{
- down(&kprobe_mutex);
+ mutex_lock(&kprobe_mutex);
free_insn_slot(p->ainsn.insn);
- up(&kprobe_mutex);
+ mutex_unlock(&kprobe_mutex);
}
static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
index 22d83d4d1af5..9feeeef5a875 100644
--- a/arch/powerpc/kernel/of_device.c
+++ b/arch/powerpc/kernel/of_device.c
@@ -147,15 +147,12 @@ postcore_initcall(of_bus_driver_init);
int of_register_driver(struct of_platform_driver *drv)
{
- int count = 0;
-
/* initialize common driver fields */
drv->driver.name = drv->name;
drv->driver.bus = &of_platform_bus_type;
/* register with core */
- count = driver_register(&drv->driver);
- return count ? count : 1;
+ return driver_register(&drv->driver);
}
void of_unregister_driver(struct of_platform_driver *drv)
diff --git a/arch/powerpc/kernel/pci_iommu.c b/arch/powerpc/kernel/pci_iommu.c
index bdf15dbbf4f0..c336f3e31cff 100644
--- a/arch/powerpc/kernel/pci_iommu.c
+++ b/arch/powerpc/kernel/pci_iommu.c
@@ -1,5 +1,4 @@
/*
- * arch/ppc64/kernel/pci_iommu.c
* Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
*
* Rewrite, cleanup, new allocation schemes:
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 63ecbec05202..dfa5398ab3c8 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -57,7 +57,6 @@ extern void machine_check_exception(struct pt_regs *regs);
extern void alignment_exception(struct pt_regs *regs);
extern void program_check_exception(struct pt_regs *regs);
extern void single_step_exception(struct pt_regs *regs);
-extern int pmac_newworld;
extern int sys_sigreturn(struct pt_regs *regs);
EXPORT_SYMBOL(clear_pages);
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index c225cf154bfe..1770a066c217 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/process.c
- *
* Derived from "arch/i386/kernel/process.c"
* Copyright (C) 1995 Linus Torvalds
*
@@ -47,9 +45,9 @@
#include <asm/mmu.h>
#include <asm/prom.h>
#include <asm/machdep.h>
+#include <asm/time.h>
#ifdef CONFIG_PPC64
#include <asm/firmware.h>
-#include <asm/time.h>
#endif
extern unsigned long _get_SP(void);
@@ -330,6 +328,11 @@ struct task_struct *__switch_to(struct task_struct *prev,
#endif
local_irq_save(flags);
+
+ account_system_vtime(current);
+ account_process_vtime(current);
+ calculate_steal_time();
+
last = _switch(old_thread, new_thread);
local_irq_restore(flags);
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 6dbd21726770..d63cd562d9d5 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -829,10 +829,6 @@ void __init unflatten_device_tree(void)
/* Allocate memory for the expanded device tree */
mem = lmb_alloc(size + 4, __alignof__(struct device_node));
- if (!mem) {
- DBG("Couldn't allocate memory with lmb_alloc()!\n");
- panic("Couldn't allocate memory with lmb_alloc()!\n");
- }
mem = (unsigned long) __va(mem);
((u32 *)mem)[size / 4] = 0xdeadbeef;
diff --git a/arch/powerpc/kernel/ptrace-common.h b/arch/powerpc/kernel/ptrace-common.h
index 5ccbdbe0d5c9..c42a860c8d25 100644
--- a/arch/powerpc/kernel/ptrace-common.h
+++ b/arch/powerpc/kernel/ptrace-common.h
@@ -1,6 +1,4 @@
/*
- * linux/arch/ppc64/kernel/ptrace-common.h
- *
* Copyright (c) 2002 Stephen Rothwell, IBM Coproration
* Extracted from ptrace.c and ptrace32.c
*
diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c
index 7a95b8a28354..1f03fb28cc0a 100644
--- a/arch/powerpc/kernel/rtas-proc.c
+++ b/arch/powerpc/kernel/rtas-proc.c
@@ -1,5 +1,4 @@
/*
- * arch/ppc64/kernel/rtas-proc.c
* Copyright (C) 2000 Tilmann Bitterberg
* (tilmann@bitterberg.de)
*
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index 7442775ef2a1..57b539a03fa9 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc64/kernel/rtas_pci.c
- *
* Copyright (C) 2001 Dave Engebretsen, IBM Corporation
* Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
*
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index be12041c0fc5..c1d62bf11f29 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -162,9 +162,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
#if defined(CONFIG_SMP) && defined(CONFIG_PPC32)
unsigned long bogosum = 0;
int i;
- for (i = 0; i < NR_CPUS; ++i)
- if (cpu_online(i))
- bogosum += loops_per_jiffy;
+ for_each_online_cpu(i)
+ bogosum += loops_per_jiffy;
seq_printf(m, "total bogomips\t: %lu.%02lu\n",
bogosum/(500000/HZ), bogosum/(5000/HZ) % 100);
#endif /* CONFIG_SMP && CONFIG_PPC32 */
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index db72a92943bf..dc2770df25b3 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -272,9 +272,8 @@ int __init ppc_init(void)
if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff);
/* register CPU devices */
- for (i = 0; i < NR_CPUS; i++)
- if (cpu_possible(i))
- register_cpu(&cpu_devices[i], i, NULL);
+ for_each_cpu(i)
+ register_cpu(&cpu_devices[i], i, NULL);
/* call platform init */
if (ppc_md.init != NULL) {
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index f96c49b03ba0..2f3fdad35594 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -497,8 +497,6 @@ void __init setup_system(void)
#endif
printk("-----------------------------------------------------\n");
- mm_init_ppc64();
-
DBG(" <- setup_system()\n");
}
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 4324f8a8ba24..47f910380a6a 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -1,6 +1,4 @@
/*
- * linux/arch/ppc64/kernel/signal.c
- *
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 13595a64f013..805eaedbc308 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -541,7 +541,7 @@ int __devinit start_secondary(void *unused)
smp_ops->take_timebase();
if (system_state > SYSTEM_BOOTING)
- per_cpu(last_jiffy, cpu) = get_tb();
+ snapshot_timebase();
spin_lock(&call_lock);
cpu_set(cpu, cpu_online_map);
@@ -573,6 +573,8 @@ void __init smp_cpus_done(unsigned int max_cpus)
set_cpus_allowed(current, old_mask);
+ snapshot_timebases();
+
dump_numa_cpu_topology();
}
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 86f7e3d154d8..4a27218a086c 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -51,6 +51,7 @@
#include <linux/percpu.h>
#include <linux/rtc.h>
#include <linux/jiffies.h>
+#include <linux/posix-timers.h>
#include <asm/io.h>
#include <asm/processor.h>
@@ -98,6 +99,7 @@ unsigned long tb_ticks_per_jiffy;
unsigned long tb_ticks_per_usec = 100; /* sane default */
EXPORT_SYMBOL(tb_ticks_per_usec);
unsigned long tb_ticks_per_sec;
+EXPORT_SYMBOL(tb_ticks_per_sec); /* for cputime_t conversions */
u64 tb_to_xs;
unsigned tb_to_us;
@@ -135,6 +137,224 @@ unsigned long tb_last_stamp;
*/
DEFINE_PER_CPU(unsigned long, last_jiffy);
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+/*
+ * Factors for converting from cputime_t (timebase ticks) to
+ * jiffies, milliseconds, seconds, and clock_t (1/USER_HZ seconds).
+ * These are all stored as 0.64 fixed-point binary fractions.
+ */
+u64 __cputime_jiffies_factor;
+EXPORT_SYMBOL(__cputime_jiffies_factor);
+u64 __cputime_msec_factor;
+EXPORT_SYMBOL(__cputime_msec_factor);
+u64 __cputime_sec_factor;
+EXPORT_SYMBOL(__cputime_sec_factor);
+u64 __cputime_clockt_factor;
+EXPORT_SYMBOL(__cputime_clockt_factor);
+
+static void calc_cputime_factors(void)
+{
+ struct div_result res;
+
+ div128_by_32(HZ, 0, tb_ticks_per_sec, &res);
+ __cputime_jiffies_factor = res.result_low;
+ div128_by_32(1000, 0, tb_ticks_per_sec, &res);
+ __cputime_msec_factor = res.result_low;
+ div128_by_32(1, 0, tb_ticks_per_sec, &res);
+ __cputime_sec_factor = res.result_low;
+ div128_by_32(USER_HZ, 0, tb_ticks_per_sec, &res);
+ __cputime_clockt_factor = res.result_low;
+}
+
+/*
+ * Read the PURR on systems that have it, otherwise the timebase.
+ */
+static u64 read_purr(void)
+{
+ if (cpu_has_feature(CPU_FTR_PURR))
+ return mfspr(SPRN_PURR);
+ return mftb();
+}
+
+/*
+ * Account time for a transition between system, hard irq
+ * or soft irq state.
+ */
+void account_system_vtime(struct task_struct *tsk)
+{
+ u64 now, delta;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ now = read_purr();
+ delta = now - get_paca()->startpurr;
+ get_paca()->startpurr = now;
+ if (!in_interrupt()) {
+ delta += get_paca()->system_time;
+ get_paca()->system_time = 0;
+ }
+ account_system_time(tsk, 0, delta);
+ local_irq_restore(flags);
+}
+
+/*
+ * Transfer the user and system times accumulated in the paca
+ * by the exception entry and exit code to the generic process
+ * user and system time records.
+ * Must be called with interrupts disabled.
+ */
+void account_process_vtime(struct task_struct *tsk)
+{
+ cputime_t utime;
+
+ utime = get_paca()->user_time;
+ get_paca()->user_time = 0;
+ account_user_time(tsk, utime);
+}
+
+static void account_process_time(struct pt_regs *regs)
+{
+ int cpu = smp_processor_id();
+
+ account_process_vtime(current);
+ run_local_timers();
+ if (rcu_pending(cpu))
+ rcu_check_callbacks(cpu, user_mode(regs));
+ scheduler_tick();
+ run_posix_cpu_timers(current);
+}
+
+#ifdef CONFIG_PPC_SPLPAR
+/*
+ * Stuff for accounting stolen time.
+ */
+struct cpu_purr_data {
+ int initialized; /* thread is running */
+ u64 tb0; /* timebase at origin time */
+ u64 purr0; /* PURR at origin time */
+ u64 tb; /* last TB value read */
+ u64 purr; /* last PURR value read */
+ u64 stolen; /* stolen time so far */
+ spinlock_t lock;
+};
+
+static DEFINE_PER_CPU(struct cpu_purr_data, cpu_purr_data);
+
+static void snapshot_tb_and_purr(void *data)
+{
+ struct cpu_purr_data *p = &__get_cpu_var(cpu_purr_data);
+
+ p->tb0 = mftb();
+ p->purr0 = mfspr(SPRN_PURR);
+ p->tb = p->tb0;
+ p->purr = 0;
+ wmb();
+ p->initialized = 1;
+}
+
+/*
+ * Called during boot when all cpus have come up.
+ */
+void snapshot_timebases(void)
+{
+ int cpu;
+
+ if (!cpu_has_feature(CPU_FTR_PURR))
+ return;
+ for_each_cpu(cpu)
+ spin_lock_init(&per_cpu(cpu_purr_data, cpu).lock);
+ on_each_cpu(snapshot_tb_and_purr, NULL, 0, 1);
+}
+
+void calculate_steal_time(void)
+{
+ u64 tb, purr, t0;
+ s64 stolen;
+ struct cpu_purr_data *p0, *pme, *phim;
+ int cpu;
+
+ if (!cpu_has_feature(CPU_FTR_PURR))
+ return;
+ cpu = smp_processor_id();
+ pme = &per_cpu(cpu_purr_data, cpu);
+ if (!pme->initialized)
+ return; /* this can happen in early boot */
+ p0 = &per_cpu(cpu_purr_data, cpu & ~1);
+ phim = &per_cpu(cpu_purr_data, cpu ^ 1);
+ spin_lock(&p0->lock);
+ tb = mftb();
+ purr = mfspr(SPRN_PURR) - pme->purr0;
+ if (!phim->initialized || !cpu_online(cpu ^ 1)) {
+ stolen = (tb - pme->tb) - (purr - pme->purr);
+ } else {
+ t0 = pme->tb0;
+ if (phim->tb0 < t0)
+ t0 = phim->tb0;
+ stolen = phim->tb - t0 - phim->purr - purr - p0->stolen;
+ }
+ if (stolen > 0) {
+ account_steal_time(current, stolen);
+ p0->stolen += stolen;
+ }
+ pme->tb = tb;
+ pme->purr = purr;
+ spin_unlock(&p0->lock);
+}
+
+/*
+ * Must be called before the cpu is added to the online map when
+ * a cpu is being brought up at runtime.
+ */
+static void snapshot_purr(void)
+{
+ int cpu;
+ u64 purr;
+ struct cpu_purr_data *p0, *pme, *phim;
+ unsigned long flags;
+
+ if (!cpu_has_feature(CPU_FTR_PURR))
+ return;
+ cpu = smp_processor_id();
+ pme = &per_cpu(cpu_purr_data, cpu);
+ p0 = &per_cpu(cpu_purr_data, cpu & ~1);
+ phim = &per_cpu(cpu_purr_data, cpu ^ 1);
+ spin_lock_irqsave(&p0->lock, flags);
+ pme->tb = pme->tb0 = mftb();
+ purr = mfspr(SPRN_PURR);
+ if (!phim->initialized) {
+ pme->purr = 0;
+ pme->purr0 = purr;
+ } else {
+ /* set p->purr and p->purr0 for no change in p0->stolen */
+ pme->purr = phim->tb - phim->tb0 - phim->purr - p0->stolen;
+ pme->purr0 = purr - pme->purr;
+ }
+ pme->initialized = 1;
+ spin_unlock_irqrestore(&p0->lock, flags);
+}
+
+#endif /* CONFIG_PPC_SPLPAR */
+
+#else /* ! CONFIG_VIRT_CPU_ACCOUNTING */
+#define calc_cputime_factors()
+#define account_process_time(regs) update_process_times(user_mode(regs))
+#define calculate_steal_time() do { } while (0)
+#endif
+
+#if !(defined(CONFIG_VIRT_CPU_ACCOUNTING) && defined(CONFIG_PPC_SPLPAR))
+#define snapshot_purr() do { } while (0)
+#endif
+
+/*
+ * Called when a cpu comes up after the system has finished booting,
+ * i.e. as a result of a hotplug cpu action.
+ */
+void snapshot_timebase(void)
+{
+ __get_cpu_var(last_jiffy) = get_tb();
+ snapshot_purr();
+}
+
void __delay(unsigned long loops)
{
unsigned long start;
@@ -392,6 +612,7 @@ static void iSeries_tb_recal(void)
new_tb_ticks_per_jiffy, sign, tick_diff );
tb_ticks_per_jiffy = new_tb_ticks_per_jiffy;
tb_ticks_per_sec = new_tb_ticks_per_sec;
+ calc_cputime_factors();
div128_by_32( XSEC_PER_SEC, 0, tb_ticks_per_sec, &divres );
do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
tb_to_xs = divres.result_low;
@@ -440,6 +661,7 @@ void timer_interrupt(struct pt_regs * regs)
irq_enter();
profile_tick(CPU_PROFILING, regs);
+ calculate_steal_time();
#ifdef CONFIG_PPC_ISERIES
get_lppaca()->int_dword.fields.decr_int = 0;
@@ -461,7 +683,7 @@ void timer_interrupt(struct pt_regs * regs)
* is the case.
*/
if (!cpu_is_offline(cpu))
- update_process_times(user_mode(regs));
+ account_process_time(regs);
/*
* No need to check whether cpu is offline here; boot_cpuid
@@ -518,13 +740,27 @@ void wakeup_decrementer(void)
void __init smp_space_timers(unsigned int max_cpus)
{
int i;
+ unsigned long half = tb_ticks_per_jiffy / 2;
unsigned long offset = tb_ticks_per_jiffy / max_cpus;
unsigned long previous_tb = per_cpu(last_jiffy, boot_cpuid);
/* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */
previous_tb -= tb_ticks_per_jiffy;
+ /*
+ * The stolen time calculation for POWER5 shared-processor LPAR
+ * systems works better if the two threads' timebase interrupts
+ * are staggered by half a jiffy with respect to each other.
+ */
for_each_cpu(i) {
- if (i != boot_cpuid) {
+ if (i == boot_cpuid)
+ continue;
+ if (i == (boot_cpuid ^ 1))
+ per_cpu(last_jiffy, i) =
+ per_cpu(last_jiffy, boot_cpuid) - half;
+ else if (i & 1)
+ per_cpu(last_jiffy, i) =
+ per_cpu(last_jiffy, i ^ 1) + half;
+ else {
previous_tb += offset;
per_cpu(last_jiffy, i) = previous_tb;
}
@@ -720,6 +956,7 @@ void __init time_init(void)
tb_ticks_per_sec = ppc_tb_freq;
tb_ticks_per_usec = ppc_tb_freq / 1000000;
tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
+ calc_cputime_factors();
/*
* Calculate the length of each tick in ns. It will not be
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 04f7df39ffbb..ec8370368423 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -1,6 +1,4 @@
/*
- * linux/arch/ppc64/kernel/vdso.c
- *
* Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
* <benh@kernel.crashing.org>
*
diff --git a/arch/powerpc/lib/copypage_64.S b/arch/powerpc/lib/copypage_64.S
index 40523b140109..f9837f44ac0b 100644
--- a/arch/powerpc/lib/copypage_64.S
+++ b/arch/powerpc/lib/copypage_64.S
@@ -1,6 +1,4 @@
/*
- * arch/ppc64/lib/copypage.S
- *
* Copyright (C) 2002 Paul Mackerras, IBM Corp.
*
* This program is free software; you can redistribute it and/or
diff --git a/arch/powerpc/lib/copyuser_64.S b/arch/powerpc/lib/copyuser_64.S
index 6d69ef39b7df..a6b54cb97c49 100644
--- a/arch/powerpc/lib/copyuser_64.S
+++ b/arch/powerpc/lib/copyuser_64.S
@@ -1,6 +1,4 @@
/*
- * arch/ppc64/lib/copyuser.S
- *
* Copyright (C) 2002 Paul Mackerras, IBM Corp.
*
* This program is free software; you can redistribute it and/or
diff --git a/arch/powerpc/lib/e2a.c b/arch/powerpc/lib/e2a.c
index d2b834887920..4b72ed8fd50e 100644
--- a/arch/powerpc/lib/e2a.c
+++ b/arch/powerpc/lib/e2a.c
@@ -1,9 +1,7 @@
/*
- * arch/ppc64/lib/e2a.c
- *
* EBCDIC to ASCII conversion
*
- * This function moved here from arch/ppc64/kernel/viopath.c
+ * This function moved here from arch/powerpc/platforms/iseries/viopath.c
*
* (C) Copyright 2000-2004 IBM Corporation
*
@@ -105,4 +103,14 @@ unsigned char e2a(unsigned char x)
}
EXPORT_SYMBOL(e2a);
+unsigned char* strne2a(unsigned char *dest, const unsigned char *src, size_t n)
+{
+ int i;
+
+ n = strnlen(src, n);
+ for (i = 0; i < n; i++)
+ dest[i] = e2a(src[i]);
+
+ return dest;
+}
diff --git a/arch/powerpc/lib/memcpy_64.S b/arch/powerpc/lib/memcpy_64.S
index 9ccacdf5bcb9..fd66acfd3e3e 100644
--- a/arch/powerpc/lib/memcpy_64.S
+++ b/arch/powerpc/lib/memcpy_64.S
@@ -1,6 +1,4 @@
/*
- * arch/ppc64/lib/memcpy.S
- *
* Copyright (C) 2002 Paul Mackerras, IBM Corp.
*
* This program is free software; you can redistribute it and/or
diff --git a/arch/powerpc/lib/rheap.c b/arch/powerpc/lib/rheap.c
index 42c5de2c898f..31e511856dc5 100644
--- a/arch/powerpc/lib/rheap.c
+++ b/arch/powerpc/lib/rheap.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/rheap.c
- *
* A Remote Heap. Remote means that we don't touch the memory that the
* heap points to. Normal heap implementations use the memory they manage
* to place their list. We cannot do that because the memory we manage may
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index a4815d316722..ec4adcb4bc28 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/mm/fault.c
- *
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
diff --git a/arch/powerpc/mm/hash_low_32.S b/arch/powerpc/mm/hash_low_32.S
index 12ccd7155bac..ea469eefa146 100644
--- a/arch/powerpc/mm/hash_low_32.S
+++ b/arch/powerpc/mm/hash_low_32.S
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/hashtable.S
- *
* $Id: hashtable.S,v 1.6 1999/10/08 01:56:15 paulus Exp $
*
* PowerPC version
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index e9d589eefc14..89b35c181314 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -169,7 +169,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
#ifdef CONFIG_PPC_ISERIES
if (_machine == PLATFORM_ISERIES_LPAR)
ret = iSeries_hpte_insert(hpteg, va,
- __pa(vaddr),
+ paddr,
tmp_mode,
HPTE_V_BOLTED,
psize);
@@ -178,7 +178,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
#ifdef CONFIG_PPC_PSERIES
if (_machine & PLATFORM_LPAR)
ret = pSeries_lpar_hpte_insert(hpteg, va,
- virt_to_abs(paddr),
+ paddr,
tmp_mode,
HPTE_V_BOLTED,
psize);
@@ -186,7 +186,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
#endif
#ifdef CONFIG_PPC_MULTIPLATFORM
ret = native_hpte_insert(hpteg, va,
- virt_to_abs(paddr),
+ paddr,
tmp_mode, HPTE_V_BOLTED,
psize);
#endif
@@ -392,7 +392,7 @@ static unsigned long __init htab_get_table_size(void)
#ifdef CONFIG_MEMORY_HOTPLUG
void create_section_mapping(unsigned long start, unsigned long end)
{
- BUG_ON(htab_bolt_mapping(start, end, start,
+ BUG_ON(htab_bolt_mapping(start, end, __pa(start),
_PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX,
mmu_linear_psize));
}
@@ -422,7 +422,7 @@ void __init htab_initialize(void)
htab_hash_mask = pteg_count - 1;
- if (platform_is_lpar()) {
+ if (firmware_has_feature(FW_FEATURE_LPAR)) {
/* Using a hypervisor which owns the htab */
htab_address = NULL;
_SDR1 = 0;
@@ -431,7 +431,6 @@ void __init htab_initialize(void)
* the absolute address space.
*/
table = lmb_alloc(htab_size_bytes, htab_size_bytes);
- BUG_ON(table == 0);
DBG("Hash table allocated at %lx, size: %lx\n", table,
htab_size_bytes);
@@ -474,21 +473,22 @@ void __init htab_initialize(void)
if (dart_tablebase != 0 && dart_tablebase >= base
&& dart_tablebase < (base + size)) {
+ unsigned long dart_table_end = dart_tablebase + 16 * MB;
if (base != dart_tablebase)
BUG_ON(htab_bolt_mapping(base, dart_tablebase,
- base, mode_rw,
- mmu_linear_psize));
- if ((base + size) > (dart_tablebase + 16*MB))
+ __pa(base), mode_rw,
+ mmu_linear_psize));
+ if ((base + size) > dart_table_end)
BUG_ON(htab_bolt_mapping(dart_tablebase+16*MB,
- base + size,
- dart_tablebase+16*MB,
+ base + size,
+ __pa(dart_table_end),
mode_rw,
mmu_linear_psize));
continue;
}
#endif /* CONFIG_U3_DART */
- BUG_ON(htab_bolt_mapping(base, base + size, base,
- mode_rw, mmu_linear_psize));
+ BUG_ON(htab_bolt_mapping(base, base + size, __pa(base),
+ mode_rw, mmu_linear_psize));
}
/*
@@ -505,8 +505,8 @@ void __init htab_initialize(void)
if (base + size >= tce_alloc_start)
tce_alloc_start = base + size + 1;
- BUG_ON(htab_bolt_mapping(tce_alloc_start, tce_alloc_end,
- tce_alloc_start, mode_rw,
+ BUG_ON(htab_bolt_mapping(tce_alloc_start, tce_alloc_end,
+ __pa(tce_alloc_start), mode_rw,
mmu_linear_psize));
}
@@ -517,7 +517,7 @@ void __init htab_initialize(void)
void htab_initialize_secondary(void)
{
- if (!platform_is_lpar())
+ if (!firmware_has_feature(FW_FEATURE_LPAR))
mtspr(SPRN_SDR1, _SDR1);
}
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index bacb71c89811..babebd15bdc4 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -84,54 +84,6 @@
/* max amount of RAM to use */
unsigned long __max_memory;
-/* info on what we think the IO hole is */
-unsigned long io_hole_start;
-unsigned long io_hole_size;
-
-/*
- * Do very early mm setup.
- */
-void __init mm_init_ppc64(void)
-{
-#ifndef CONFIG_PPC_ISERIES
- unsigned long i;
-#endif
-
- ppc64_boot_msg(0x100, "MM Init");
-
- /* This is the story of the IO hole... please, keep seated,
- * unfortunately, we are out of oxygen masks at the moment.
- * So we need some rough way to tell where your big IO hole
- * is. On pmac, it's between 2G and 4G, on POWER3, it's around
- * that area as well, on POWER4 we don't have one, etc...
- * We need that as a "hint" when sizing the TCE table on POWER3
- * So far, the simplest way that seem work well enough for us it
- * to just assume that the first discontinuity in our physical
- * RAM layout is the IO hole. That may not be correct in the future
- * (and isn't on iSeries but then we don't care ;)
- */
-
-#ifndef CONFIG_PPC_ISERIES
- for (i = 1; i < lmb.memory.cnt; i++) {
- unsigned long base, prevbase, prevsize;
-
- prevbase = lmb.memory.region[i-1].base;
- prevsize = lmb.memory.region[i-1].size;
- base = lmb.memory.region[i].base;
- if (base > (prevbase + prevsize)) {
- io_hole_start = prevbase + prevsize;
- io_hole_size = base - (prevbase + prevsize);
- break;
- }
- }
-#endif /* CONFIG_PPC_ISERIES */
- if (io_hole_start)
- printk("IO Hole assumed to be %lx -> %lx\n",
- io_hole_start, io_hole_start + io_hole_size - 1);
-
- ppc64_boot_msg(0x100, "MM Init Done");
-}
-
void free_initmem(void)
{
unsigned long addr;
diff --git a/arch/powerpc/mm/lmb.c b/arch/powerpc/mm/lmb.c
index bbe3eac918e8..417d58518558 100644
--- a/arch/powerpc/mm/lmb.c
+++ b/arch/powerpc/mm/lmb.c
@@ -31,6 +31,8 @@
#define DBG(fmt...)
#endif
+#define LMB_ALLOC_ANYWHERE 0
+
struct lmb lmb;
void lmb_dump_all(void)
@@ -226,6 +228,20 @@ unsigned long __init lmb_alloc(unsigned long size, unsigned long align)
unsigned long __init lmb_alloc_base(unsigned long size, unsigned long align,
unsigned long max_addr)
{
+ unsigned long alloc;
+
+ alloc = __lmb_alloc_base(size, align, max_addr);
+
+ if (alloc == 0)
+ panic("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n",
+ size, max_addr);
+
+ return alloc;
+}
+
+unsigned long __init __lmb_alloc_base(unsigned long size, unsigned long align,
+ unsigned long max_addr)
+{
long i, j;
unsigned long base = 0;
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 454cac01d8cc..badac10d700c 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -125,7 +125,7 @@ int __devinit add_memory(u64 start, u64 size)
nid = hot_add_scn_to_nid(start);
pgdata = NODE_DATA(nid);
- start = __va(start);
+ start = (unsigned long)__va(start);
create_section_mapping(start, start + size);
/* this should work for most non-highmem platforms */
@@ -249,7 +249,6 @@ void __init do_init_bootmem(void)
bootmap_pages = bootmem_bootmap_pages(total_pages);
start = lmb_alloc(bootmap_pages << PAGE_SHIFT, PAGE_SIZE);
- BUG_ON(!start);
boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages);
diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
index fe65f522aff3..972a8e884b9a 100644
--- a/arch/powerpc/mm/mmap.c
+++ b/arch/powerpc/mm/mmap.c
@@ -1,6 +1,4 @@
/*
- * linux/arch/ppc64/mm/mmap.c
- *
* flexible mmap layout support
*
* Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 2863a912bcd0..e89b22aa539e 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -129,10 +129,12 @@ void __init get_region(unsigned int nid, unsigned long *start_pfn,
*start_pfn = 0;
}
-static inline void map_cpu_to_node(int cpu, int node)
+static void __cpuinit map_cpu_to_node(int cpu, int node)
{
numa_cpu_lookup_table[cpu] = node;
+ dbg("adding cpu %d to node %d\n", cpu, node);
+
if (!(cpu_isset(cpu, numa_cpumask_lookup_table[node])))
cpu_set(cpu, numa_cpumask_lookup_table[node]);
}
@@ -153,7 +155,7 @@ static void unmap_cpu_from_node(unsigned long cpu)
}
#endif /* CONFIG_HOTPLUG_CPU */
-static struct device_node *find_cpu_node(unsigned int cpu)
+static struct device_node * __cpuinit find_cpu_node(unsigned int cpu)
{
unsigned int hw_cpuid = get_hard_smp_processor_id(cpu);
struct device_node *cpu_node = NULL;
@@ -189,23 +191,29 @@ static int *of_get_associativity(struct device_node *dev)
return (unsigned int *)get_property(dev, "ibm,associativity", NULL);
}
-static int of_node_numa_domain(struct device_node *device)
+/* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa
+ * info is found.
+ */
+static int of_node_to_nid(struct device_node *device)
{
- int numa_domain;
+ int nid = -1;
unsigned int *tmp;
if (min_common_depth == -1)
- return 0;
+ goto out;
tmp = of_get_associativity(device);
- if (tmp && (tmp[0] >= min_common_depth)) {
- numa_domain = tmp[min_common_depth];
- } else {
- dbg("WARNING: no NUMA information for %s\n",
- device->full_name);
- numa_domain = 0;
- }
- return numa_domain;
+ if (!tmp)
+ goto out;
+
+ if (tmp[0] >= min_common_depth)
+ nid = tmp[min_common_depth];
+
+ /* POWER4 LPAR uses 0xffff as invalid node */
+ if (nid == 0xffff || nid >= MAX_NUMNODES)
+ nid = -1;
+out:
+ return nid;
}
/*
@@ -246,8 +254,7 @@ static int __init find_min_common_depth(void)
if ((len >= 1) && ref_points) {
depth = ref_points[1];
} else {
- dbg("WARNING: could not find NUMA "
- "associativity reference point\n");
+ dbg("NUMA: ibm,associativity-reference-points not found.\n");
depth = -1;
}
of_node_put(rtas_root);
@@ -283,9 +290,9 @@ static unsigned long __devinit read_n_cells(int n, unsigned int **buf)
* Figure out to which domain a cpu belongs and stick it there.
* Return the id of the domain used.
*/
-static int numa_setup_cpu(unsigned long lcpu)
+static int __cpuinit numa_setup_cpu(unsigned long lcpu)
{
- int numa_domain = 0;
+ int nid = 0;
struct device_node *cpu = find_cpu_node(lcpu);
if (!cpu) {
@@ -293,27 +300,16 @@ static int numa_setup_cpu(unsigned long lcpu)
goto out;
}
- numa_domain = of_node_numa_domain(cpu);
+ nid = of_node_to_nid(cpu);
- if (numa_domain >= num_online_nodes()) {
- /*
- * POWER4 LPAR uses 0xffff as invalid node,
- * dont warn in this case.
- */
- if (numa_domain != 0xffff)
- printk(KERN_ERR "WARNING: cpu %ld "
- "maps to invalid NUMA node %d\n",
- lcpu, numa_domain);
- numa_domain = 0;
- }
+ if (nid < 0 || !node_online(nid))
+ nid = any_online_node(NODE_MASK_ALL);
out:
- node_set_online(numa_domain);
-
- map_cpu_to_node(lcpu, numa_domain);
+ map_cpu_to_node(lcpu, nid);
of_node_put(cpu);
- return numa_domain;
+ return nid;
}
static int cpu_numa_callback(struct notifier_block *nfb,
@@ -325,10 +321,7 @@ static int cpu_numa_callback(struct notifier_block *nfb,
switch (action) {
case CPU_UP_PREPARE:
- if (min_common_depth == -1 || !numa_enabled)
- map_cpu_to_node(lcpu, 0);
- else
- numa_setup_cpu(lcpu);
+ numa_setup_cpu(lcpu);
ret = NOTIFY_OK;
break;
#ifdef CONFIG_HOTPLUG_CPU
@@ -375,7 +368,7 @@ static int __init parse_numa_properties(void)
{
struct device_node *cpu = NULL;
struct device_node *memory = NULL;
- int max_domain;
+ int default_nid = 0;
unsigned long i;
if (numa_enabled == 0) {
@@ -385,32 +378,32 @@ static int __init parse_numa_properties(void)
min_common_depth = find_min_common_depth();
- dbg("NUMA associativity depth for CPU/Memory: %d\n", min_common_depth);
if (min_common_depth < 0)
return min_common_depth;
- max_domain = numa_setup_cpu(boot_cpuid);
+ dbg("NUMA associativity depth for CPU/Memory: %d\n", min_common_depth);
/*
- * Even though we connect cpus to numa domains later in SMP init,
- * we need to know the maximum node id now. This is because each
- * node id must have NODE_DATA etc backing it.
- * As a result of hotplug we could still have cpus appear later on
- * with larger node ids. In that case we force the cpu into node 0.
+ * Even though we connect cpus to numa domains later in SMP
+ * init, we need to know the node ids now. This is because
+ * each node to be onlined must have NODE_DATA etc backing it.
*/
- for_each_cpu(i) {
- int numa_domain;
+ for_each_present_cpu(i) {
+ int nid;
cpu = find_cpu_node(i);
+ BUG_ON(!cpu);
+ nid = of_node_to_nid(cpu);
+ of_node_put(cpu);
- if (cpu) {
- numa_domain = of_node_numa_domain(cpu);
- of_node_put(cpu);
-
- if (numa_domain < MAX_NUMNODES &&
- max_domain < numa_domain)
- max_domain = numa_domain;
- }
+ /*
+ * Don't fall back to default_nid yet -- we will plug
+ * cpus into nodes once the memory scan has discovered
+ * the topology.
+ */
+ if (nid < 0)
+ continue;
+ node_set_online(nid);
}
get_n_mem_cells(&n_mem_addr_cells, &n_mem_size_cells);
@@ -418,7 +411,7 @@ static int __init parse_numa_properties(void)
while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
unsigned long start;
unsigned long size;
- int numa_domain;
+ int nid;
int ranges;
unsigned int *memcell_buf;
unsigned int len;
@@ -439,18 +432,15 @@ new_range:
start = read_n_cells(n_mem_addr_cells, &memcell_buf);
size = read_n_cells(n_mem_size_cells, &memcell_buf);
- numa_domain = of_node_numa_domain(memory);
-
- if (numa_domain >= MAX_NUMNODES) {
- if (numa_domain != 0xffff)
- printk(KERN_ERR "WARNING: memory at %lx maps "
- "to invalid NUMA node %d\n", start,
- numa_domain);
- numa_domain = 0;
- }
-
- if (max_domain < numa_domain)
- max_domain = numa_domain;
+ /*
+ * Assumption: either all memory nodes or none will
+ * have associativity properties. If none, then
+ * everything goes to default_nid.
+ */
+ nid = of_node_to_nid(memory);
+ if (nid < 0)
+ nid = default_nid;
+ node_set_online(nid);
if (!(size = numa_enforce_memory_limit(start, size))) {
if (--ranges)
@@ -459,16 +449,13 @@ new_range:
continue;
}
- add_region(numa_domain, start >> PAGE_SHIFT,
+ add_region(nid, start >> PAGE_SHIFT,
size >> PAGE_SHIFT);
if (--ranges)
goto new_range;
}
- for (i = 0; i <= max_domain; i++)
- node_set_online(i);
-
return 0;
}
@@ -483,7 +470,6 @@ static void __init setup_nonnuma(void)
printk(KERN_INFO "Memory hole size: %ldMB\n",
(top_of_ram - total_ram) >> 20);
- map_cpu_to_node(boot_cpuid, 0);
for (i = 0; i < lmb.memory.cnt; ++i)
add_region(0, lmb.memory.region[i].base >> PAGE_SHIFT,
lmb_size_pages(&lmb.memory, i));
@@ -570,11 +556,11 @@ static void __init *careful_allocation(int nid, unsigned long size,
unsigned long end_pfn)
{
int new_nid;
- unsigned long ret = lmb_alloc_base(size, align, end_pfn << PAGE_SHIFT);
+ unsigned long ret = __lmb_alloc_base(size, align, end_pfn << PAGE_SHIFT);
/* retry over all memory */
if (!ret)
- ret = lmb_alloc_base(size, align, lmb_end_of_DRAM());
+ ret = __lmb_alloc_base(size, align, lmb_end_of_DRAM());
if (!ret)
panic("numa.c: cannot allocate %lu bytes on node %d",
@@ -620,6 +606,8 @@ void __init do_init_bootmem(void)
dump_numa_memory_topology();
register_cpu_notifier(&ppc64_numa_nb);
+ cpu_numa_callback(&ppc64_numa_nb, CPU_UP_PREPARE,
+ (void *)(unsigned long)boot_cpuid);
for_each_online_node(nid) {
unsigned long start_pfn, end_pfn, pages_present;
@@ -767,10 +755,10 @@ int hot_add_scn_to_nid(unsigned long scn_addr)
{
struct device_node *memory = NULL;
nodemask_t nodes;
- int numa_domain = 0;
+ int default_nid = any_online_node(NODE_MASK_ALL);
if (!numa_enabled || (min_common_depth < 0))
- return numa_domain;
+ return default_nid;
while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
unsigned long start, size;
@@ -787,15 +775,15 @@ int hot_add_scn_to_nid(unsigned long scn_addr)
ha_new_range:
start = read_n_cells(n_mem_addr_cells, &memcell_buf);
size = read_n_cells(n_mem_size_cells, &memcell_buf);
- numa_domain = of_node_numa_domain(memory);
+ nid = of_node_to_nid(memory);
/* Domains not present at boot default to 0 */
- if (!node_online(numa_domain))
- numa_domain = any_online_node(NODE_MASK_ALL);
+ if (nid < 0 || !node_online(nid))
+ nid = default_nid;
if ((scn_addr >= start) && (scn_addr < (start + size))) {
of_node_put(memory);
- goto got_numa_domain;
+ goto got_nid;
}
if (--ranges) /* process all ranges in cell */
@@ -804,12 +792,12 @@ ha_new_range:
BUG(); /* section address should be found above */
/* Temporary code to ensure that returned node is not empty */
-got_numa_domain:
+got_nid:
nodes_setall(nodes);
- while (NODE_DATA(numa_domain)->node_spanned_pages == 0) {
- node_clear(numa_domain, nodes);
- numa_domain = any_online_node(nodes);
+ while (NODE_DATA(nid)->node_spanned_pages == 0) {
+ node_clear(nid, nodes);
+ nid = any_online_node(nodes);
}
- return numa_domain;
+ return nid;
}
#endif /* CONFIG_MEMORY_HOTPLUG */
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index d1acee38f163..abfaabf667bf 100644
--- a/arch/powerpc/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
@@ -1,6 +1,4 @@
/*
- * arch/ppc64/mm/slb_low.S
- *
* Low-level SLB routines
*
* Copyright (C) 2004 David Gibson <dwg@au.ibm.com>, IBM
diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c
index 82e4951826bc..91d25fb27f89 100644
--- a/arch/powerpc/mm/stab.c
+++ b/arch/powerpc/mm/stab.c
@@ -247,10 +247,6 @@ void stabs_alloc(void)
newstab = lmb_alloc_base(HW_PAGE_SIZE, HW_PAGE_SIZE,
1<<SID_SHIFT);
- if (! newstab)
- panic("Unable to allocate segment table for CPU %d.\n",
- cpu);
-
newstab = (unsigned long)__va(newstab);
memset((void *)newstab, 0, HW_PAGE_SIZE);
diff --git a/arch/powerpc/mm/tlb_64.c b/arch/powerpc/mm/tlb_64.c
index bb3afb6e6317..f734b11566c2 100644
--- a/arch/powerpc/mm/tlb_64.c
+++ b/arch/powerpc/mm/tlb_64.c
@@ -36,7 +36,7 @@
DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
/* This is declared as we are using the more or less generic
- * include/asm-ppc64/tlb.h file -- tgall
+ * include/asm-powerpc/tlb.h file -- tgall
*/
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur);
diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c
index 659a021da0c7..4b06e53eb9b4 100644
--- a/arch/powerpc/oprofile/op_model_power4.c
+++ b/arch/powerpc/oprofile/op_model_power4.c
@@ -10,6 +10,7 @@
#include <linux/oprofile.h>
#include <linux/init.h>
#include <linux/smp.h>
+#include <asm/firmware.h>
#include <asm/ptrace.h>
#include <asm/system.h>
#include <asm/processor.h>
@@ -232,7 +233,7 @@ static unsigned long get_pc(struct pt_regs *regs)
mmcra = mfspr(SPRN_MMCRA);
/* Were we in the hypervisor? */
- if (platform_is_lpar() && (mmcra & MMCRA_SIHV))
+ if (firmware_has_feature(FW_FEATURE_LPAR) && (mmcra & MMCRA_SIHV))
/* function descriptor madness */
return *((unsigned long *)hypervisor_bucket);
diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile
index 9d8b28ef3343..5c72367441a8 100644
--- a/arch/powerpc/platforms/83xx/Makefile
+++ b/arch/powerpc/platforms/83xx/Makefile
@@ -1,4 +1,6 @@
#
# Makefile for the PowerPC 83xx linux kernel.
#
-obj-$(CONFIG_MPC834x_SYS) += mpc834x_sys.o pci.o
+obj-y := misc.o
+obj-$(CONFIG_PCI) += pci.o
+obj-$(CONFIG_MPC834x_SYS) += mpc834x_sys.o
diff --git a/arch/powerpc/platforms/83xx/misc.c b/arch/powerpc/platforms/83xx/misc.c
new file mode 100644
index 000000000000..1455bcef4892
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/misc.c
@@ -0,0 +1,55 @@
+/*
+ * misc setup functions for MPC83xx
+ *
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+
+#include <asm/io.h>
+#include <asm/hw_irq.h>
+#include <sysdev/fsl_soc.h>
+
+#include "mpc83xx.h"
+
+void mpc83xx_restart(char *cmd)
+{
+#define RST_OFFSET 0x00000900
+#define RST_PROT_REG 0x00000018
+#define RST_CTRL_REG 0x0000001c
+ __be32 __iomem *reg;
+
+ /* map reset register space */
+ reg = ioremap(get_immrbase() + 0x900, 0xff);
+
+ local_irq_disable();
+
+ /* enable software reset "RSTE" */
+ out_be32(reg + (RST_PROT_REG >> 2), 0x52535445);
+
+ /* set software hard reset */
+ out_be32(reg + (RST_CTRL_REG >> 2), 0x2);
+ for (;;) ;
+}
+
+long __init mpc83xx_time_init(void)
+{
+#define SPCR_OFFSET 0x00000110
+#define SPCR_TBEN 0x00400000
+ __be32 __iomem *spcr = ioremap(get_immrbase() + SPCR_OFFSET, 4);
+ __be32 tmp;
+
+ tmp = in_be32(spcr);
+ out_be32(spcr, tmp | SPCR_TBEN);
+
+ iounmap(spcr);
+
+ return 0;
+}
diff --git a/arch/powerpc/platforms/83xx/mpc834x_sys.c b/arch/powerpc/platforms/83xx/mpc834x_sys.c
index 2098dd05a773..7c18b4cd5db4 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_sys.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_sys.c
@@ -24,22 +24,15 @@
#include <linux/delay.h>
#include <linux/seq_file.h>
#include <linux/root_dev.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/mpc83xx.h>
#include <asm/irq.h>
-#include <mm/mmu_decl.h>
#include <asm/prom.h>
#include <asm/udbg.h>
#include <sysdev/fsl_soc.h>
@@ -52,8 +45,6 @@ unsigned long isa_mem_base = 0;
#endif
#ifdef CONFIG_PCI
-extern int mpc83xx_pci2_busno;
-
static int
mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
{
@@ -78,26 +69,14 @@ mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
const long min_idsel = 0x11, max_idsel = 0x20, irqs_per_slot = 4;
return PCI_IRQ_TABLE_LOOKUP;
}
-
-static int
-mpc83xx_exclude_device(u_char bus, u_char devfn)
-{
- if (bus == 0 && PCI_SLOT(devfn) == 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if (mpc83xx_pci2_busno)
- if (bus == (mpc83xx_pci2_busno) && PCI_SLOT(devfn) == 0)
- return PCIBIOS_DEVICE_NOT_FOUND;
- return PCIBIOS_SUCCESSFUL;
-}
-#endif /* CONFIG_PCI */
+#endif /* CONFIG_PCI */
/* ************************************************************************
*
* Setup the architecture
*
*/
-static void __init
-mpc834x_sys_setup_arch(void)
+static void __init mpc834x_sys_setup_arch(void)
{
struct device_node *np;
@@ -106,14 +85,14 @@ mpc834x_sys_setup_arch(void)
np = of_find_node_by_type(NULL, "cpu");
if (np != 0) {
- unsigned int *fp = (int *) get_property(np, "clock-frequency", NULL);
+ unsigned int *fp =
+ (int *)get_property(np, "clock-frequency", NULL);
if (fp != 0)
loops_per_jiffy = *fp / HZ;
else
loops_per_jiffy = 50000000 / HZ;
of_node_put(np);
}
-
#ifdef CONFIG_PCI
for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
add_bridge(np);
@@ -124,14 +103,13 @@ mpc834x_sys_setup_arch(void)
#endif
#ifdef CONFIG_ROOT_NFS
- ROOT_DEV = Root_NFS;
+ ROOT_DEV = Root_NFS;
#else
- ROOT_DEV = Root_HDA1;
+ ROOT_DEV = Root_HDA1;
#endif
}
-void __init
-mpc834x_sys_init_IRQ(void)
+void __init mpc834x_sys_init_IRQ(void)
{
u8 senses[8] = {
0, /* EXT 0 */
@@ -160,64 +138,27 @@ mpc834x_sys_init_IRQ(void)
}
#if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
-extern ulong ds1374_get_rtc_time(void);
-extern int ds1374_set_rtc_time(ulong);
+extern ulong ds1374_get_rtc_time(void);
+extern int ds1374_set_rtc_time(ulong);
-static int __init
-mpc834x_rtc_hookup(void)
+static int __init mpc834x_rtc_hookup(void)
{
- struct timespec tv;
+ struct timespec tv;
ppc_md.get_rtc_time = ds1374_get_rtc_time;
ppc_md.set_rtc_time = ds1374_set_rtc_time;
tv.tv_nsec = 0;
- tv.tv_sec = (ppc_md.get_rtc_time)();
+ tv.tv_sec = (ppc_md.get_rtc_time) ();
do_settimeofday(&tv);
return 0;
}
+
late_initcall(mpc834x_rtc_hookup);
#endif
-static void
-mpc83xx_restart(char *cmd)
-{
-#define RST_OFFSET 0x00000900
-#define RST_PROT_REG 0x00000018
-#define RST_CTRL_REG 0x0000001c
- __be32 __iomem *reg;
-
- // map reset register space
- reg = ioremap(get_immrbase() + 0x900, 0xff);
-
- local_irq_disable();
-
- /* enable software reset "RSTE" */
- out_be32(reg + (RST_PROT_REG >> 2), 0x52535445);
-
- /* set software hard reset */
- out_be32(reg + (RST_CTRL_REG >> 2), 0x52535445);
- for(;;);
-}
-
-static long __init
-mpc83xx_time_init(void)
-{
-#define SPCR_OFFSET 0x00000110
-#define SPCR_TBEN 0x00400000
- __be32 __iomem *spcr = ioremap(get_immrbase() + SPCR_OFFSET, 4);
- __be32 tmp;
-
- tmp = in_be32(spcr);
- out_be32(spcr, tmp|SPCR_TBEN);
-
- iounmap(spcr);
-
- return 0;
-}
-void __init
-platform_init(void)
+void __init platform_init(void)
{
/* setup the PowerPC module struct */
ppc_md.setup_arch = mpc834x_sys_setup_arch;
@@ -239,5 +180,3 @@ platform_init(void)
return;
}
-
-
diff --git a/arch/powerpc/platforms/83xx/mpc834x_sys.h b/arch/powerpc/platforms/83xx/mpc834x_sys.h
index e4ca39f6a862..fedecb73f7ff 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_sys.h
+++ b/arch/powerpc/platforms/83xx/mpc834x_sys.h
@@ -20,4 +20,4 @@
#define PIRQC MPC83xx_IRQ_EXT6
#define PIRQD MPC83xx_IRQ_EXT7
-#endif /* __MACH_MPC83XX_SYS_H__ */
+#endif /* __MACH_MPC83XX_SYS_H__ */
diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h
index ce9e66abef24..01cae106912b 100644
--- a/arch/powerpc/platforms/83xx/mpc83xx.h
+++ b/arch/powerpc/platforms/83xx/mpc83xx.h
@@ -10,5 +10,8 @@
*/
extern int add_bridge(struct device_node *dev);
+extern int mpc83xx_exclude_device(u_char bus, u_char devfn);
+extern void mpc83xx_restart(char *cmd);
+extern long mpc83xx_time_init(void);
-#endif /* __MPC83XX_H__ */
+#endif /* __MPC83XX_H__ */
diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/platforms/83xx/pci.c
index 469cdacc5bd4..16f7d3b30e1d 100644
--- a/arch/powerpc/platforms/83xx/pci.c
+++ b/arch/powerpc/platforms/83xx/pci.c
@@ -36,7 +36,16 @@
int mpc83xx_pci2_busno;
-#ifdef CONFIG_PCI
+int mpc83xx_exclude_device(u_char bus, u_char devfn)
+{
+ if (bus == 0 && PCI_SLOT(devfn) == 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ if (mpc83xx_pci2_busno)
+ if (bus == (mpc83xx_pci2_busno) && PCI_SLOT(devfn) == 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ return PCIBIOS_SUCCESSFUL;
+}
+
int __init add_bridge(struct device_node *dev)
{
int len;
@@ -52,7 +61,7 @@ int __init add_bridge(struct device_node *dev)
has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
/* Get bus range if any */
- bus_range = (int *) get_property(dev, "bus-range", &len);
+ bus_range = (int *)get_property(dev, "bus-range", &len);
if (bus_range == NULL || len < 2 * sizeof(int)) {
printk(KERN_WARNING "Can't get bus-range for %s, assume"
" bus 0\n", dev->full_name);
@@ -74,7 +83,7 @@ int __init add_bridge(struct device_node *dev)
if ((rsrc.start & 0xfffff) == 0x8500) {
setup_indirect_pci(hose, immr + 0x8300, immr + 0x8304);
}
- /* PCI 2*/
+ /* PCI 2 */
if ((rsrc.start & 0xfffff) == 0x8600) {
setup_indirect_pci(hose, immr + 0x8380, immr + 0x8384);
primary = 0;
@@ -84,10 +93,10 @@ int __init add_bridge(struct device_node *dev)
printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%08lx. "
"Firmware bus number: %d->%d\n",
- rsrc.start, hose->first_busno, hose->last_busno);
+ rsrc.start, hose->first_busno, hose->last_busno);
DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
- hose, hose->cfg_addr, hose->cfg_data);
+ hose, hose->cfg_addr, hose->cfg_data);
/* Interpret the "ranges" property */
/* This also maps the I/O region and sets isa_io/mem_base */
@@ -95,5 +104,3 @@ int __init add_bridge(struct device_node *dev)
return 0;
}
-
-#endif
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index c5bc2821d991..d3d0ff745e84 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -1,86 +1,30 @@
-config 85xx
- bool
- depends on E500
- default y
-
-config PPC_INDIRECT_PCI_BE
- bool
- depends on 85xx
- default y
-
-menu "Freescale 85xx options"
- depends on E500
+menu "Platform support"
+ depends on PPC_85xx
choice
prompt "Machine Type"
- depends on 85xx
default MPC8540_ADS
config MPC8540_ADS
bool "Freescale MPC8540 ADS"
help
- This option enables support for the MPC 8540 ADS evaluation board.
-
-config MPC8548_CDS
- bool "Freescale MPC8548 CDS"
- help
- This option enablese support for the MPC8548 CDS evaluation board.
-
-config MPC8555_CDS
- bool "Freescale MPC8555 CDS"
- help
- This option enablese support for the MPC8555 CDS evaluation board.
-
-config MPC8560_ADS
- bool "Freescale MPC8560 ADS"
- help
- This option enables support for the MPC 8560 ADS evaluation board.
-
-config SBC8560
- bool "WindRiver PowerQUICC III SBC8560"
- help
- This option enables support for the WindRiver PowerQUICC III
- SBC8560 board.
-
-config STX_GP3
- bool "Silicon Turnkey Express GP3"
- help
- This option enables support for the Silicon Turnkey Express GP3
- board.
+ This option enables support for the MPC 8540 ADS board
endchoice
-# It's often necessary to know the specific 85xx processor type.
-# Fortunately, it is implied (so far) from the board type, so we
-# don't need to ask more redundant questions.
config MPC8540
bool
- depends on MPC8540_ADS
- default y
-
-config MPC8548
- bool
- depends on MPC8548_CDS
- default y
+ select PPC_UDBG_16550
+ select PPC_INDIRECT_PCI
+ default y if MPC8540_ADS
-config MPC8555
- bool
- depends on MPC8555_CDS
- default y
-
-config MPC8560
+config PPC_INDIRECT_PCI_BE
bool
- depends on SBC8560 || MPC8560_ADS || STX_GP3
- default y
-
-config 85xx_PCI2
- bool "Supprt for 2nd PCI host controller"
- depends on MPC8555_CDS
+ depends on PPC_85xx
default y
-config PPC_GEN550
+config MPIC
bool
- depends on MPC8540 || SBC8560 || MPC8555
default y
endmenu
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index 6407197ffd89..ffc4139cb214 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -1 +1,5 @@
-# empty makefile so make clean works
+#
+# Makefile for the PowerPC 85xx linux kernel.
+#
+obj-$(CONFIG_PPC_85xx) += misc.o pci.o
+obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o
diff --git a/arch/powerpc/platforms/85xx/misc.c b/arch/powerpc/platforms/85xx/misc.c
new file mode 100644
index 000000000000..26c5e822c7c8
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/misc.c
@@ -0,0 +1,31 @@
+/*
+ * MPC85xx generic code.
+ *
+ * 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/irq.h>
+#include <linux/module.h>
+#include <asm/irq.h>
+
+extern void abort(void);
+
+void mpc85xx_restart(char *cmd)
+{
+ local_irq_disable();
+ abort();
+}
+
+/* For now this is a pass through */
+phys_addr_t fixup_bigphys_addr(phys_addr_t addr, phys_addr_t size)
+{
+ return addr;
+};
+
+EXPORT_SYMBOL(fixup_bigphys_addr);
diff --git a/arch/powerpc/platforms/85xx/mpc8540_ads.h b/arch/powerpc/platforms/85xx/mpc8540_ads.h
new file mode 100644
index 000000000000..f770cadb2080
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/mpc8540_ads.h
@@ -0,0 +1,36 @@
+/*
+ * arch/ppc/platforms/85xx/mpc8540_ads.h
+ *
+ * MPC8540ADS board definitions
+ *
+ * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ *
+ * 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_MPC8540ADS_H__
+#define __MACH_MPC8540ADS_H__
+
+#include <linux/config.h>
+#include <linux/initrd.h>
+
+#define BOARD_CCSRBAR ((uint)0xe0000000)
+#define BCSR_ADDR ((uint)0xf8000000)
+#define BCSR_SIZE ((uint)(32 * 1024))
+
+/* PCI interrupt controller */
+#define PIRQA MPC85xx_IRQ_EXT1
+#define PIRQB MPC85xx_IRQ_EXT2
+#define PIRQC MPC85xx_IRQ_EXT3
+#define PIRQD MPC85xx_IRQ_EXT4
+
+/* Offset of CPM register space */
+#define CPM_MAP_ADDR (CCSRBAR + MPC85xx_CPM_OFFSET)
+
+#endif /* __MACH_MPC8540ADS_H__ */
diff --git a/arch/powerpc/platforms/85xx/mpc85xx.h b/arch/powerpc/platforms/85xx/mpc85xx.h
new file mode 100644
index 000000000000..b44db6268f3d
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/mpc85xx.h
@@ -0,0 +1,18 @@
+/*
+ * arch/ppc/platforms/85xx/mpc85xx.h
+ *
+ * MPC85xx soc definitions/function decls
+ *
+ * Maintainer: Kumar Gala <kumar.gala@freescale.com>
+ *
+ * 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.
+ *
+ */
+
+extern void mpc85xx_restart(char *);
+extern int add_bridge(struct device_node *dev);
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
new file mode 100644
index 000000000000..b7821dbae00d
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -0,0 +1,244 @@
+/*
+ * 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/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/delay.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/mpc85xx.h>
+#include <asm/prom.h>
+#include <asm/mpic.h>
+#include <mm/mmu_decl.h>
+#include <asm/udbg.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
+
+/*
+ * 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_ads_openpic_initsenses[] __initdata = {
+ MPC85XX_INTERNAL_IRQ_SENSES,
+ 0x0, /* External 0: */
+#if defined(CONFIG_PCI)
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 1: PCI slot 0 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 2: PCI slot 1 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 3: PCI slot 2 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 4: PCI slot 3 */
+#else
+ 0x0, /* External 1: */
+ 0x0, /* External 2: */
+ 0x0, /* External 3: */
+ 0x0, /* External 4: */
+#endif
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 5: PHY */
+ 0x0, /* External 6: */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 7: PHY */
+ 0x0, /* External 8: */
+ 0x0, /* External 9: */
+ 0x0, /* External 10: */
+ 0x0, /* External 11: */
+};
+
+#ifdef CONFIG_PCI
+/*
+ * interrupt routing
+ */
+
+int
+mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+ static char pci_irq_table[][4] =
+ /*
+ * This is little evil, but works around the fact
+ * that revA boards have IDSEL starting at 18
+ * and others boards (older) start at 12
+ *
+ * PCI IDSEL/INTPIN->INTLINE
+ * A B C D
+ */
+ {
+ {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 2 */
+ {PIRQD, PIRQA, PIRQB, PIRQC},
+ {PIRQC, PIRQD, PIRQA, PIRQB},
+ {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 5 */
+ {0, 0, 0, 0}, /* -- */
+ {0, 0, 0, 0}, /* -- */
+ {0, 0, 0, 0}, /* -- */
+ {0, 0, 0, 0}, /* -- */
+ {0, 0, 0, 0}, /* -- */
+ {0, 0, 0, 0}, /* -- */
+ {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 12 */
+ {PIRQD, PIRQA, PIRQB, PIRQC},
+ {PIRQC, PIRQD, PIRQA, PIRQB},
+ {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 15 */
+ {0, 0, 0, 0}, /* -- */
+ {0, 0, 0, 0}, /* -- */
+ {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 18 */
+ {PIRQD, PIRQA, PIRQB, PIRQC},
+ {PIRQC, PIRQD, PIRQA, PIRQB},
+ {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 21 */
+ };
+
+ const long min_idsel = 2, max_idsel = 21, irqs_per_slot = 4;
+ return PCI_IRQ_TABLE_LOOKUP;
+}
+
+int
+mpc85xx_exclude_device(u_char bus, u_char devfn)
+{
+ if (bus == 0 && PCI_SLOT(devfn) == 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ else
+ return PCIBIOS_SUCCESSFUL;
+}
+
+#endif /* CONFIG_PCI */
+
+
+void __init mpc85xx_ads_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_ads_openpic_initsenses,
+ sizeof(mpc85xx_ads_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);
+}
+
+/*
+ * Setup the architecture
+ */
+static void __init mpc85xx_ads_setup_arch(void)
+{
+ struct device_node *cpu;
+ struct device_node *np;
+
+ if (ppc_md.progress)
+ ppc_md.progress("mpc85xx_ads_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 = 50000000 / HZ;
+ of_node_put(cpu);
+ }
+
+#ifdef CONFIG_PCI
+ for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
+ add_bridge(np);
+
+ 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_ads_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\n");
+ 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));
+}
+
+void __init platform_init(void)
+{
+ ppc_md.setup_arch = mpc85xx_ads_setup_arch;
+ ppc_md.show_cpuinfo = mpc85xx_ads_show_cpuinfo;
+
+ ppc_md.init_IRQ = mpc85xx_ads_pic_init;
+ ppc_md.get_irq = mpic_get_irq;
+
+ ppc_md.restart = mpc85xx_restart;
+ ppc_md.power_off = NULL;
+ ppc_md.halt = NULL;
+
+ ppc_md.time_init = NULL;
+ ppc_md.set_rtc_time = NULL;
+ ppc_md.get_rtc_time = NULL;
+ ppc_md.calibrate_decr = generic_calibrate_decr;
+
+ ppc_md.progress = udbg_progress;
+
+ if (ppc_md.progress)
+ ppc_md.progress("mpc85xx_ads platform_init(): exit", 0);
+}
diff --git a/arch/powerpc/platforms/85xx/pci.c b/arch/powerpc/platforms/85xx/pci.c
new file mode 100644
index 000000000000..bad290110ed1
--- /dev/null
+++ b/arch/powerpc/platforms/85xx/pci.c
@@ -0,0 +1,96 @@
+/*
+ * FSL SoC setup code
+ *
+ * Maintained by Kumar Gala (see MAINTAINERS for contact information)
+ *
+ * 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/pci.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <asm/io.h>
+#include <asm/pci-bridge.h>
+#include <asm/prom.h>
+#include <sysdev/fsl_soc.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+int mpc85xx_pci2_busno = 0;
+
+#ifdef CONFIG_PCI
+int __init add_bridge(struct device_node *dev)
+{
+ int len;
+ struct pci_controller *hose;
+ struct resource rsrc;
+ int *bus_range;
+ int primary = 1, has_address = 0;
+ phys_addr_t immr = get_immrbase();
+
+ DBG("Adding PCI host bridge %s\n", dev->full_name);
+
+ /* Fetch host bridge registers address */
+ has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
+
+ /* Get bus range if any */
+ bus_range = (int *) get_property(dev, "bus-range", &len);
+ if (bus_range == NULL || len < 2 * sizeof(int)) {
+ printk(KERN_WARNING "Can't get bus-range for %s, assume"
+ " bus 0\n", dev->full_name);
+ }
+
+ hose = pcibios_alloc_controller();
+ if (!hose)
+ return -ENOMEM;
+ hose->arch_data = dev;
+ hose->set_cfg_type = 1;
+
+ hose->first_busno = bus_range ? bus_range[0] : 0;
+ hose->last_busno = bus_range ? bus_range[1] : 0xff;
+
+ /* PCI 1 */
+ if ((rsrc.start & 0xfffff) == 0x8000) {
+ setup_indirect_pci(hose, immr + 0x8000, immr + 0x8004);
+ }
+ /* PCI 2 */
+ if ((rsrc.start & 0xfffff) == 0x9000) {
+ setup_indirect_pci(hose, immr + 0x9000, immr + 0x9004);
+ primary = 0;
+ hose->bus_offset = hose->first_busno;
+ mpc85xx_pci2_busno = hose->first_busno;
+ }
+
+ printk(KERN_INFO "Found MPC85xx PCI host bridge at 0x%08lx. "
+ "Firmware bus number: %d->%d\n",
+ rsrc.start, hose->first_busno, hose->last_busno);
+
+ DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
+ hose, hose->cfg_addr, hose->cfg_data);
+
+ /* Interpret the "ranges" property */
+ /* This also maps the I/O region and sets isa_io/mem_base */
+ pci_process_bridge_OF_ranges(hose, dev, primary);
+
+ return 0;
+}
+
+#endif
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index 04073fd987ec..c4f6b0d2d140 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -8,7 +8,7 @@ endif
obj-$(CONFIG_PPC_CHRP) += chrp/
obj-$(CONFIG_4xx) += 4xx/
obj-$(CONFIG_PPC_83xx) += 83xx/
-obj-$(CONFIG_85xx) += 85xx/
+obj-$(CONFIG_PPC_85xx) += 85xx/
obj-$(CONFIG_PPC_PSERIES) += pseries/
obj-$(CONFIG_PPC_ISERIES) += iseries/
obj-$(CONFIG_PPC_MAPLE) += maple/
diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c
index 29c86781c493..6ad4b1a72c96 100644
--- a/arch/powerpc/platforms/chrp/pegasos_eth.c
+++ b/arch/powerpc/platforms/chrp/pegasos_eth.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/chrp_pegasos_eth.c
- *
* Copyright (C) 2005 Sven Luther <sl@bplan-gmbh.de>
* Thanks to :
* Dale Farnsworth <dale@farnsworth.org>
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index e1fadbf49150..8bf4307e323d 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/setup.c
- *
* Copyright (C) 1995 Linus Torvalds
* Adapted from 'alpha' version by Gary Thomas
* Modified by Cort Dougan (cort@cs.nmt.edu)
diff --git a/arch/powerpc/platforms/chrp/time.c b/arch/powerpc/platforms/chrp/time.c
index 78df2e7ca88a..12c6f689b1aa 100644
--- a/arch/powerpc/platforms/chrp/time.c
+++ b/arch/powerpc/platforms/chrp/time.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/chrp_time.c
- *
* Copyright (C) 1991, 1992, 1995 Linus Torvalds
*
* Adapted for PowerPC (PReP) by Gary Thomas
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c
index a41d8b78c0cd..d771b8ee857d 100644
--- a/arch/powerpc/platforms/iseries/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -46,6 +46,7 @@
#include "setup.h"
extern int piranha_simulator;
+static int mf_initialized;
/*
* This is the structure layout for the Machine Facilites LPAR event
@@ -143,7 +144,8 @@ static spinlock_t pending_event_spinlock;
static struct pending_event *pending_event_head;
static struct pending_event *pending_event_tail;
static struct pending_event *pending_event_avail;
-static struct pending_event pending_event_prealloc[16];
+#define PENDING_EVENT_PREALLOC_LEN 16
+static struct pending_event pending_event_prealloc[PENDING_EVENT_PREALLOC_LEN];
/*
* Put a pending event onto the available queue, so it can get reused.
@@ -597,7 +599,7 @@ void mf_power_off(void)
* Global kernel interface to tell the VSP object in the primary
* partition to reboot this partition.
*/
-void mf_reboot(void)
+void mf_reboot(char *cmd)
{
printk(KERN_INFO "mf.c: Preparing to bounce...\n");
signal_ce_msg_simple(0x4e, NULL);
@@ -625,7 +627,7 @@ void mf_display_src(u32 word)
/*
* Display a single word SRC of the form "PROGXXXX" on the VSP control panel.
*/
-void mf_display_progress(u16 value)
+static __init void mf_display_progress_src(u16 value)
{
u8 ce[12];
u8 src[72];
@@ -649,30 +651,42 @@ void mf_display_progress(u16 value)
* Clear the VSP control panel. Used to "erase" an SRC that was
* previously displayed.
*/
-void mf_clear_src(void)
+static void mf_clear_src(void)
{
signal_ce_msg_simple(0x4b, NULL);
}
+void __init mf_display_progress(u16 value)
+{
+ if (piranha_simulator || !mf_initialized)
+ return;
+
+ if (0xFFFF == value)
+ mf_clear_src();
+ else
+ mf_display_progress_src(value);
+}
+
/*
* Initialization code here.
*/
-void mf_init(void)
+void __init mf_init(void)
{
int i;
- /* initialize */
spin_lock_init(&pending_event_spinlock);
- for (i = 0;
- i < sizeof(pending_event_prealloc) / sizeof(*pending_event_prealloc);
- ++i)
+
+ for (i = 0; i < PENDING_EVENT_PREALLOC_LEN; i++)
free_pending_event(&pending_event_prealloc[i]);
+
HvLpEvent_registerHandler(HvLpEvent_Type_MachineFac, &hv_handler);
/* virtual continue ack */
signal_ce_msg_simple(0x57, NULL);
- /* initialization complete */
+ mf_initialized = 1;
+ mb();
+
printk(KERN_NOTICE "mf.c: iSeries Linux LPAR Machine Facilities "
"initialized\n");
}
@@ -692,6 +706,43 @@ static void get_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
complete(&rtc->com);
}
+static int mf_set_rtc(struct rtc_time *tm)
+{
+ char ce_time[12];
+ u8 day, mon, hour, min, sec, y1, y2;
+ unsigned year;
+
+ year = 1900 + tm->tm_year;
+ y1 = year / 100;
+ y2 = year % 100;
+
+ sec = tm->tm_sec;
+ min = tm->tm_min;
+ hour = tm->tm_hour;
+ day = tm->tm_mday;
+ mon = tm->tm_mon + 1;
+
+ BIN_TO_BCD(sec);
+ BIN_TO_BCD(min);
+ BIN_TO_BCD(hour);
+ BIN_TO_BCD(mon);
+ BIN_TO_BCD(day);
+ BIN_TO_BCD(y1);
+ BIN_TO_BCD(y2);
+
+ memset(ce_time, 0, sizeof(ce_time));
+ ce_time[3] = 0x41;
+ ce_time[4] = y1;
+ ce_time[5] = y2;
+ ce_time[6] = sec;
+ ce_time[7] = min;
+ ce_time[8] = hour;
+ ce_time[10] = day;
+ ce_time[11] = mon;
+
+ return signal_ce_msg(ce_time, NULL);
+}
+
static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm)
{
tm->tm_wday = 0;
@@ -747,7 +798,7 @@ static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm)
return 0;
}
-int mf_get_rtc(struct rtc_time *tm)
+static int mf_get_rtc(struct rtc_time *tm)
{
struct ce_msg_comp_data ce_complete;
struct rtc_time_data rtc_data;
@@ -780,7 +831,7 @@ static void get_boot_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
rtc->busy = 0;
}
-int mf_get_boot_rtc(struct rtc_time *tm)
+static int mf_get_boot_rtc(struct rtc_time *tm)
{
struct ce_msg_comp_data ce_complete;
struct boot_rtc_time_data rtc_data;
@@ -802,43 +853,6 @@ int mf_get_boot_rtc(struct rtc_time *tm)
return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
}
-int mf_set_rtc(struct rtc_time *tm)
-{
- char ce_time[12];
- u8 day, mon, hour, min, sec, y1, y2;
- unsigned year;
-
- year = 1900 + tm->tm_year;
- y1 = year / 100;
- y2 = year % 100;
-
- sec = tm->tm_sec;
- min = tm->tm_min;
- hour = tm->tm_hour;
- day = tm->tm_mday;
- mon = tm->tm_mon + 1;
-
- BIN_TO_BCD(sec);
- BIN_TO_BCD(min);
- BIN_TO_BCD(hour);
- BIN_TO_BCD(mon);
- BIN_TO_BCD(day);
- BIN_TO_BCD(y1);
- BIN_TO_BCD(y2);
-
- memset(ce_time, 0, sizeof(ce_time));
- ce_time[3] = 0x41;
- ce_time[4] = y1;
- ce_time[5] = y2;
- ce_time[6] = sec;
- ce_time[7] = min;
- ce_time[8] = hour;
- ce_time[10] = day;
- ce_time[11] = mon;
-
- return signal_ce_msg(ce_time, NULL);
-}
-
#ifdef CONFIG_PROC_FS
static int proc_mf_dump_cmdline(char *page, char **start, off_t off,
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 3ecc4a652d82..fa4550611c11 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -50,6 +50,7 @@
#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>
@@ -89,8 +90,6 @@ extern unsigned long embedded_sysmap_end;
extern unsigned long iSeries_recal_tb;
extern unsigned long iSeries_recal_titan;
-static int mf_initialized;
-
static unsigned long cmd_mem_limit;
struct MemoryBlock {
@@ -303,8 +302,6 @@ static void __init iSeries_init_early(void)
{
DBG(" -> iSeries_init_early()\n");
- ppc64_firmware_features = FW_FEATURE_ISERIES;
-
ppc64_interrupt_controller = IC_ISERIES;
#if defined(CONFIG_BLK_DEV_INITRD)
@@ -349,8 +346,6 @@ static void __init iSeries_init_early(void)
HvCallEvent_setLpEventQueueInterruptProc(0, 0);
mf_init();
- mf_initialized = 1;
- mb();
/* If we were passed an initrd, set the ROOT_DEV properly if the values
* look sensible. If not, clear initrd reference.
@@ -560,39 +555,10 @@ static void iSeries_show_cpuinfo(struct seq_file *m)
seq_printf(m, "machine\t\t: 64-bit iSeries Logical Partition\n");
}
-/*
- * Document me.
- */
-static void iSeries_restart(char *cmd)
-{
- mf_reboot();
-}
-
-/*
- * Document me.
- */
-static void iSeries_power_off(void)
-{
- mf_power_off();
-}
-
-/*
- * Document me.
- */
-static void iSeries_halt(void)
-{
- mf_power_off();
-}
-
static void __init iSeries_progress(char * st, unsigned short code)
{
printk("Progress: [%04x] - %s\n", (unsigned)code, st);
- if (!piranha_simulator && mf_initialized) {
- if (code != 0xffff)
- mf_display_progress(code);
- else
- mf_clear_src();
- }
+ mf_display_progress(code);
}
static void __init iSeries_fixup_klimit(void)
@@ -711,7 +677,13 @@ void __init iSeries_init_IRQ(void) { }
static int __init iseries_probe(int platform)
{
- return PLATFORM_ISERIES_LPAR == platform;
+ if (PLATFORM_ISERIES_LPAR != platform)
+ return 0;
+
+ ppc64_firmware_features |= FW_FEATURE_ISERIES;
+ ppc64_firmware_features |= FW_FEATURE_LPAR;
+
+ return 1;
}
struct machdep_calls __initdata iseries_md = {
@@ -721,9 +693,9 @@ struct machdep_calls __initdata iseries_md = {
.get_irq = iSeries_get_irq,
.init_early = iSeries_init_early,
.pcibios_fixup = iSeries_pci_final_fixup,
- .restart = iSeries_restart,
- .power_off = iSeries_power_off,
- .halt = iSeries_halt,
+ .restart = mf_reboot,
+ .power_off = mf_power_off,
+ .halt = mf_power_off,
.get_boot_time = iSeries_get_boot_time,
.set_rtc_time = iSeries_set_rtc_time,
.get_rtc_time = iSeries_get_rtc_time,
@@ -917,6 +889,24 @@ void dt_cpus(struct iseries_flat_dt *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];
@@ -927,6 +917,7 @@ void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size)
dt_prop_u32(dt, "#address-cells", 2);
dt_prop_u32(dt, "#size-cells", 2);
+ dt_model(dt);
/* /memory */
dt_start_node(dt, "memory@0");
@@ -940,6 +931,7 @@ void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size)
/* /chosen */
dt_start_node(dt, "chosen");
dt_prop_u32(dt, "linux,platform", PLATFORM_ISERIES_LPAR);
+ 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);
diff --git a/arch/powerpc/platforms/maple/time.c b/arch/powerpc/platforms/maple/time.c
index 50bc4eb85353..5e6981d17379 100644
--- a/arch/powerpc/platforms/maple/time.c
+++ b/arch/powerpc/platforms/maple/time.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc64/kernel/maple_time.c
- *
* (c) Copyright 2004 Benjamin Herrenschmidt (benh@kernel.crashing.org),
* IBM Corp.
*
diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c
index 56fd4e05fede..cfd6527a0d7e 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_32.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_32.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/pmac_cpufreq.c
- *
* Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
* Copyright (C) 2004 John Steele Scott <toojays@toojays.net>
*
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index bbe794891a20..e49eddd5042d 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/pmac_feature.c
- *
* Copyright (C) 1996-2001 Paul Mackerras (paulus@cs.anu.edu.au)
* Ben. Herrenschmidt (benh@kernel.crashing.org)
*
diff --git a/arch/powerpc/platforms/powermac/nvram.c b/arch/powerpc/platforms/powermac/nvram.c
index 3ebd045a3350..5fd28995c74c 100644
--- a/arch/powerpc/platforms/powermac/nvram.c
+++ b/arch/powerpc/platforms/powermac/nvram.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/pmac_nvram.c
- *
* Copyright (C) 2002 Benjamin Herrenschmidt (benh@kernel.crashing.org)
*
* This program is free software; you can redistribute it and/or
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 29c2946f1c77..385aab90c4d2 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -86,11 +86,10 @@ int ppc_override_l2cr = 0;
int ppc_override_l2cr_value;
int has_l2cache = 0;
-int pmac_newworld = 1;
+int pmac_newworld;
static int current_root_goodness = -1;
-extern int pmac_newworld;
extern struct machdep_calls pmac_md;
#define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */
@@ -308,9 +307,10 @@ static void __init pmac_setup_arch(void)
for (ic = NULL; (ic = of_find_all_nodes(ic)) != NULL; )
if (get_property(ic, "interrupt-controller", NULL))
break;
- pmac_newworld = (ic != NULL);
- if (ic)
+ if (ic) {
+ pmac_newworld = 1;
of_node_put(ic);
+ }
/* Lookup PCI hosts */
pmac_pci_init();
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 6d64a9bf3474..1065d87fc279 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -191,9 +191,7 @@ static void smp_psurge_message_pass(int target, int msg)
if (num_online_cpus() < 2)
return;
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_online(i))
- continue;
+ for_each_online_cpu(i) {
if (target == MSG_ALL
|| (target == MSG_ALL_BUT_SELF && i != smp_processor_id())
|| target == i) {
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 61616d144072..930898635c9f 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -1,5 +1,6 @@
obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \
- setup.o iommu.o ras.o rtasd.o pci_dlpar.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
diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
new file mode 100644
index 000000000000..989f4bc136cb
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -0,0 +1,103 @@
+/*
+ * pSeries firmware setup code.
+ *
+ * Portions from arch/powerpc/platforms/pseries/setup.c:
+ * Copyright (C) 1995 Linus Torvalds
+ * Adapted from 'alpha' version by Gary Thomas
+ * Modified by Cort Dougan (cort@cs.nmt.edu)
+ * Modified by PPC64 Team, IBM Corp
+ *
+ * Portions from arch/powerpc/kernel/firmware.c
+ * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
+ * Modifications for ppc64:
+ * Copyright (C) 2003 Dave Engebretsen <engebret@us.ibm.com>
+ * Copyright (C) 2005 Stephen Rothwell, IBM Corporation
+ *
+ * Copyright 2006 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.
+ */
+
+#undef DEBUG
+
+#include <asm/firmware.h>
+#include <asm/prom.h>
+
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+typedef struct {
+ unsigned long val;
+ char * name;
+} firmware_feature_t;
+
+static __initdata firmware_feature_t
+firmware_features_table[FIRMWARE_MAX_FEATURES] = {
+ {FW_FEATURE_PFT, "hcall-pft"},
+ {FW_FEATURE_TCE, "hcall-tce"},
+ {FW_FEATURE_SPRG0, "hcall-sprg0"},
+ {FW_FEATURE_DABR, "hcall-dabr"},
+ {FW_FEATURE_COPY, "hcall-copy"},
+ {FW_FEATURE_ASR, "hcall-asr"},
+ {FW_FEATURE_DEBUG, "hcall-debug"},
+ {FW_FEATURE_PERF, "hcall-perf"},
+ {FW_FEATURE_DUMP, "hcall-dump"},
+ {FW_FEATURE_INTERRUPT, "hcall-interrupt"},
+ {FW_FEATURE_MIGRATE, "hcall-migrate"},
+ {FW_FEATURE_PERFMON, "hcall-perfmon"},
+ {FW_FEATURE_CRQ, "hcall-crq"},
+ {FW_FEATURE_VIO, "hcall-vio"},
+ {FW_FEATURE_RDMA, "hcall-rdma"},
+ {FW_FEATURE_LLAN, "hcall-lLAN"},
+ {FW_FEATURE_BULK, "hcall-bulk"},
+ {FW_FEATURE_XDABR, "hcall-xdabr"},
+ {FW_FEATURE_MULTITCE, "hcall-multi-tce"},
+ {FW_FEATURE_SPLPAR, "hcall-splpar"},
+};
+
+/* Build up the firmware features bitmask using the contents of
+ * device-tree/ibm,hypertas-functions. Ultimately this functionality may
+ * be moved into prom.c prom_init().
+ */
+void __init fw_feature_init(void)
+{
+ struct device_node *dn;
+ char *hypertas, *s;
+ int len, i;
+
+ DBG(" -> fw_feature_init()\n");
+
+ dn = of_find_node_by_path("/rtas");
+ if (dn == NULL) {
+ printk(KERN_ERR "WARNING! Cannot find RTAS in device-tree!\n");
+ goto out;
+ }
+
+ hypertas = get_property(dn, "ibm,hypertas-functions", &len);
+ if (hypertas == NULL)
+ goto out;
+
+ for (s = hypertas; s < hypertas + len; s += strlen(s) + 1) {
+ for (i = 0; i < FIRMWARE_MAX_FEATURES; i++) {
+ /* check value against table of strings */
+ if (!firmware_features_table[i].name ||
+ strcmp(firmware_features_table[i].name, s))
+ continue;
+
+ /* we have a match */
+ ppc64_firmware_features |=
+ firmware_features_table[i].val;
+ break;
+ }
+ }
+
+out:
+ of_node_put(dn);
+ DBG(" <- fw_feature_init()\n");
+}
diff --git a/arch/powerpc/platforms/pseries/firmware.h b/arch/powerpc/platforms/pseries/firmware.h
new file mode 100644
index 000000000000..714f56f55362
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/firmware.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2006 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.
+ */
+
+#ifndef _PSERIES_FIRMWARE_H
+#define _PSERIES_FIRMWARE_H
+
+#include <asm/firmware.h>
+
+extern void __init fw_feature_init(void);
+
+#endif /* _PSERIES_FIRMWARE_H */
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S
index 176e8da76466..db7c19fe9297 100644
--- a/arch/powerpc/platforms/pseries/hvCall.S
+++ b/arch/powerpc/platforms/pseries/hvCall.S
@@ -1,6 +1,4 @@
/*
- * arch/ppc64/kernel/pSeries_hvCall.S
- *
* This file contains the generic code to perform a call to the
* pSeries LPAR hypervisor.
* NOTE: this file will go away when we move to inline this work.
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 48cfbfc43f99..2643078433f0 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc64/kernel/pSeries_iommu.c
- *
* Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
*
* Rewrite, cleanup:
@@ -582,7 +580,7 @@ void iommu_init_early_pSeries(void)
return;
}
- if (platform_is_lpar()) {
+ if (firmware_has_feature(FW_FEATURE_LPAR)) {
if (firmware_has_feature(FW_FEATURE_MULTITCE)) {
ppc_md.tce_build = tce_buildmulti_pSeriesLP;
ppc_md.tce_free = tce_freemulti_pSeriesLP;
diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c
index 999a9620b5ce..946ad59e3352 100644
--- a/arch/powerpc/platforms/pseries/pci.c
+++ b/arch/powerpc/platforms/pseries/pci.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc64/kernel/pSeries_pci.c
- *
* Copyright (C) 2001 Dave Engebretsen, IBM Corporation
* Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
*
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 9edeca83f434..44d5c7fdcd97 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -60,7 +60,6 @@
#include <asm/time.h>
#include <asm/nvram.h>
#include "xics.h"
-#include <asm/firmware.h>
#include <asm/pmc.h>
#include <asm/mpic.h>
#include <asm/ppc-pci.h>
@@ -70,6 +69,7 @@
#include "plpar_wrappers.h"
#include "ras.h"
+#include "firmware.h"
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -246,7 +246,7 @@ static void __init pSeries_setup_arch(void)
ppc_md.idle_loop = default_idle;
}
- if (platform_is_lpar())
+ if (firmware_has_feature(FW_FEATURE_LPAR))
ppc_md.enable_pmcs = pseries_lpar_enable_pmcs;
else
ppc_md.enable_pmcs = power4_enable_pmcs;
@@ -262,53 +262,6 @@ static int __init pSeries_init_panel(void)
}
arch_initcall(pSeries_init_panel);
-
-/* Build up the ppc64_firmware_features bitmask field
- * using contents of device-tree/ibm,hypertas-functions.
- * Ultimately this functionality may be moved into prom.c prom_init().
- */
-static void __init fw_feature_init(void)
-{
- struct device_node * dn;
- char * hypertas;
- unsigned int len;
-
- DBG(" -> fw_feature_init()\n");
-
- ppc64_firmware_features = 0;
- dn = of_find_node_by_path("/rtas");
- if (dn == NULL) {
- printk(KERN_ERR "WARNING ! Cannot find RTAS in device-tree !\n");
- goto no_rtas;
- }
-
- hypertas = get_property(dn, "ibm,hypertas-functions", &len);
- if (hypertas) {
- while (len > 0){
- int i, hypertas_len;
- /* check value against table of strings */
- for(i=0; i < FIRMWARE_MAX_FEATURES ;i++) {
- if ((firmware_features_table[i].name) &&
- (strcmp(firmware_features_table[i].name,hypertas))==0) {
- /* we have a match */
- ppc64_firmware_features |=
- (firmware_features_table[i].val);
- break;
- }
- }
- hypertas_len = strlen(hypertas);
- len -= hypertas_len +1;
- hypertas+= hypertas_len +1;
- }
- }
-
- of_node_put(dn);
-no_rtas:
-
- DBG(" <- fw_feature_init()\n");
-}
-
-
static void __init pSeries_discover_pic(void)
{
struct device_node *np;
@@ -367,21 +320,16 @@ static int pseries_set_xdabr(unsigned long dabr)
*/
static void __init pSeries_init_early(void)
{
- int iommu_off = 0;
-
DBG(" -> pSeries_init_early()\n");
fw_feature_init();
- if (platform_is_lpar())
+ if (firmware_has_feature(FW_FEATURE_LPAR))
hpte_init_lpar();
- else {
+ else
hpte_init_native();
- iommu_off = (of_chosen &&
- get_property(of_chosen, "linux,iommu-off", NULL));
- }
- if (platform_is_lpar())
+ if (firmware_has_feature(FW_FEATURE_LPAR))
find_udbg_vterm();
if (firmware_has_feature(FW_FEATURE_DABR))
@@ -437,6 +385,9 @@ static int __init pSeries_probe(int platform)
* it here ...
*/
+ if (platform == PLATFORM_PSERIES_LPAR)
+ ppc64_firmware_features |= FW_FEATURE_LPAR;
+
return 1;
}
@@ -576,7 +527,7 @@ static void pseries_shared_idle(void)
static int pSeries_pci_probe_mode(struct pci_bus *bus)
{
- if (platform_is_lpar())
+ if (firmware_has_feature(FW_FEATURE_LPAR))
return PCI_PROBE_DEVTREE;
return PCI_PROBE_NORMAL;
}
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index 8d710af50756..3cf78a6cd27c 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -443,7 +443,7 @@ void __init smp_init_pSeries(void)
smp_ops->cpu_die = pSeries_cpu_die;
/* Processors can be added/removed only on LPAR */
- if (platform_is_lpar())
+ if (firmware_has_feature(FW_FEATURE_LPAR))
pSeries_reconfig_notifier_register(&pSeries_smp_nb);
#endif
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index fd823c7c9ac8..eb86cdb9b802 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -20,6 +20,7 @@
#include <linux/gfp.h>
#include <linux/radix-tree.h>
#include <linux/cpu.h>
+#include <asm/firmware.h>
#include <asm/prom.h>
#include <asm/io.h>
#include <asm/pgtable.h>
@@ -536,7 +537,7 @@ nextnode:
of_node_put(np);
}
- if (platform_is_lpar())
+ if (firmware_has_feature(FW_FEATURE_LPAR))
ops = &pSeriesLP_ops;
else {
#ifdef CONFIG_SMP
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 6298264efe36..61d317428610 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -194,8 +194,6 @@ static int dart_init(struct device_node *dart_node)
* prefetching into invalid pages and corrupting data
*/
tmp = lmb_alloc(DART_PAGE_SIZE, DART_PAGE_SIZE);
- if (!tmp)
- panic("DART: Cannot allocate spare page!");
dart_emptyval = DARTMAP_VALID | ((tmp >> DART_PAGE_SHIFT) &
DARTMAP_RPNMASK);
diff --git a/arch/powerpc/sysdev/dcr.S b/arch/powerpc/sysdev/dcr.S
index 895f10243a43..2078f39e2f17 100644
--- a/arch/powerpc/sysdev/dcr.S
+++ b/arch/powerpc/sysdev/dcr.S
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/dcr.S
- *
* "Indirect" DCR access
*
* Copyright (c) 2004 Eugene Surovegin <ebs@ebshome.net>
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 064c9de47732..ceb584682fa3 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -40,7 +40,7 @@ phys_addr_t get_immrbase(void)
return immrbase;
soc = of_find_node_by_type(NULL, "soc");
- if (soc != 0) {
+ if (soc) {
unsigned int size;
void *prop = get_property(soc, "reg", &size);
immrbase = of_translate_address(soc, prop);
@@ -49,21 +49,20 @@ phys_addr_t get_immrbase(void)
return immrbase;
}
-EXPORT_SYMBOL(get_immrbase);
-static const char * gfar_tx_intr = "tx";
-static const char * gfar_rx_intr = "rx";
-static const char * gfar_err_intr = "error";
+EXPORT_SYMBOL(get_immrbase);
-static int __init gfar_of_init(void)
+static int __init gfar_mdio_of_init(void)
{
struct device_node *np;
unsigned int i;
- struct platform_device *mdio_dev, *gfar_dev;
+ struct platform_device *mdio_dev;
struct resource res;
int ret;
- for (np = NULL, i = 0; (np = of_find_compatible_node(np, "mdio", "gianfar")) != NULL; i++) {
+ for (np = NULL, i = 0;
+ (np = of_find_compatible_node(np, "mdio", "gianfar")) != NULL;
+ i++) {
int k;
struct device_node *child = NULL;
struct gianfar_mdio_data mdio_data;
@@ -73,12 +72,14 @@ static int __init gfar_of_init(void)
ret = of_address_to_resource(np, 0, &res);
if (ret)
- goto mdio_err;
+ goto err;
- mdio_dev = platform_device_register_simple("fsl-gianfar_mdio", res.start, &res, 1);
+ mdio_dev =
+ platform_device_register_simple("fsl-gianfar_mdio",
+ res.start, &res, 1);
if (IS_ERR(mdio_dev)) {
ret = PTR_ERR(mdio_dev);
- goto mdio_err;
+ goto err;
}
for (k = 0; k < 32; k++)
@@ -86,17 +87,44 @@ static int __init gfar_of_init(void)
while ((child = of_get_next_child(np, child)) != NULL) {
if (child->n_intrs) {
- u32 *id = (u32 *) get_property(child, "reg", NULL);
+ u32 *id =
+ (u32 *) get_property(child, "reg", NULL);
mdio_data.irq[*id] = child->intrs[0].line;
}
}
- ret = platform_device_add_data(mdio_dev, &mdio_data, sizeof(struct gianfar_mdio_data));
+ ret =
+ platform_device_add_data(mdio_dev, &mdio_data,
+ sizeof(struct gianfar_mdio_data));
if (ret)
- goto mdio_unreg;
+ goto unreg;
}
- for (np = NULL, i = 0; (np = of_find_compatible_node(np, "network", "gianfar")) != NULL; i++) {
+ return 0;
+
+unreg:
+ platform_device_unregister(mdio_dev);
+err:
+ return ret;
+}
+
+arch_initcall(gfar_mdio_of_init);
+
+static const char *gfar_tx_intr = "tx";
+static const char *gfar_rx_intr = "rx";
+static const char *gfar_err_intr = "error";
+
+static int __init gfar_of_init(void)
+{
+ struct device_node *np;
+ unsigned int i;
+ struct platform_device *gfar_dev;
+ struct resource res;
+ int ret;
+
+ for (np = NULL, i = 0;
+ (np = of_find_compatible_node(np, "network", "gianfar")) != NULL;
+ i++) {
struct resource r[4];
struct device_node *phy, *mdio;
struct gianfar_platform_data gfar_data;
@@ -110,7 +138,7 @@ static int __init gfar_of_init(void)
ret = of_address_to_resource(np, 0, &r[0]);
if (ret)
- goto gfar_err;
+ goto err;
r[1].start = np->intrs[0].line;
r[1].end = np->intrs[0].line;
@@ -133,11 +161,13 @@ static int __init gfar_of_init(void)
r[3].flags = IORESOURCE_IRQ;
}
- gfar_dev = platform_device_register_simple("fsl-gianfar", i, &r[0], np->n_intrs + 1);
+ gfar_dev =
+ platform_device_register_simple("fsl-gianfar", i, &r[0],
+ np->n_intrs + 1);
if (IS_ERR(gfar_dev)) {
ret = PTR_ERR(gfar_dev);
- goto gfar_err;
+ goto err;
}
mac_addr = get_property(np, "address", NULL);
@@ -145,26 +175,26 @@ static int __init gfar_of_init(void)
if (model && !strcasecmp(model, "TSEC"))
gfar_data.device_flags =
- FSL_GIANFAR_DEV_HAS_GIGABIT |
- FSL_GIANFAR_DEV_HAS_COALESCE |
- FSL_GIANFAR_DEV_HAS_RMON |
- FSL_GIANFAR_DEV_HAS_MULTI_INTR;
+ FSL_GIANFAR_DEV_HAS_GIGABIT |
+ FSL_GIANFAR_DEV_HAS_COALESCE |
+ FSL_GIANFAR_DEV_HAS_RMON |
+ FSL_GIANFAR_DEV_HAS_MULTI_INTR;
if (model && !strcasecmp(model, "eTSEC"))
gfar_data.device_flags =
- FSL_GIANFAR_DEV_HAS_GIGABIT |
- FSL_GIANFAR_DEV_HAS_COALESCE |
- FSL_GIANFAR_DEV_HAS_RMON |
- FSL_GIANFAR_DEV_HAS_MULTI_INTR |
- FSL_GIANFAR_DEV_HAS_CSUM |
- FSL_GIANFAR_DEV_HAS_VLAN |
- FSL_GIANFAR_DEV_HAS_EXTENDED_HASH;
+ FSL_GIANFAR_DEV_HAS_GIGABIT |
+ FSL_GIANFAR_DEV_HAS_COALESCE |
+ FSL_GIANFAR_DEV_HAS_RMON |
+ FSL_GIANFAR_DEV_HAS_MULTI_INTR |
+ FSL_GIANFAR_DEV_HAS_CSUM |
+ FSL_GIANFAR_DEV_HAS_VLAN |
+ FSL_GIANFAR_DEV_HAS_EXTENDED_HASH;
ph = (phandle *) get_property(np, "phy-handle", NULL);
phy = of_find_node_by_phandle(*ph);
if (phy == NULL) {
ret = -ENODEV;
- goto gfar_unreg;
+ goto unreg;
}
mdio = of_get_parent(phy);
@@ -174,7 +204,7 @@ static int __init gfar_of_init(void)
if (ret) {
of_node_put(phy);
of_node_put(mdio);
- goto gfar_unreg;
+ goto unreg;
}
gfar_data.phy_id = *id;
@@ -183,23 +213,22 @@ static int __init gfar_of_init(void)
of_node_put(phy);
of_node_put(mdio);
- ret = platform_device_add_data(gfar_dev, &gfar_data, sizeof(struct gianfar_platform_data));
+ ret =
+ platform_device_add_data(gfar_dev, &gfar_data,
+ sizeof(struct
+ gianfar_platform_data));
if (ret)
- goto gfar_unreg;
+ goto unreg;
}
return 0;
-mdio_unreg:
- platform_device_unregister(mdio_dev);
-mdio_err:
- return ret;
-
-gfar_unreg:
+unreg:
platform_device_unregister(gfar_dev);
-gfar_err:
+err:
return ret;
}
+
arch_initcall(gfar_of_init);
static int __init fsl_i2c_of_init(void)
@@ -209,17 +238,19 @@ static int __init fsl_i2c_of_init(void)
struct platform_device *i2c_dev;
int ret;
- for (np = NULL, i = 0; (np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL; i++) {
+ for (np = NULL, i = 0;
+ (np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL;
+ i++) {
struct resource r[2];
struct fsl_i2c_platform_data i2c_data;
- unsigned char * flags = NULL;
+ unsigned char *flags = NULL;
memset(&r, 0, sizeof(r));
memset(&i2c_data, 0, sizeof(i2c_data));
ret = of_address_to_resource(np, 0, &r[0]);
if (ret)
- goto i2c_err;
+ goto err;
r[1].start = np->intrs[0].line;
r[1].end = np->intrs[0].line;
@@ -228,7 +259,7 @@ static int __init fsl_i2c_of_init(void)
i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2);
if (IS_ERR(i2c_dev)) {
ret = PTR_ERR(i2c_dev);
- goto i2c_err;
+ goto err;
}
i2c_data.device_flags = 0;
@@ -240,18 +271,22 @@ static int __init fsl_i2c_of_init(void)
if (flags)
i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200;
- ret = platform_device_add_data(i2c_dev, &i2c_data, sizeof(struct fsl_i2c_platform_data));
+ ret =
+ platform_device_add_data(i2c_dev, &i2c_data,
+ sizeof(struct
+ fsl_i2c_platform_data));
if (ret)
- goto i2c_unreg;
+ goto unreg;
}
return 0;
-i2c_unreg:
+unreg:
platform_device_unregister(i2c_dev);
-i2c_err:
+err:
return ret;
}
+
arch_initcall(fsl_i2c_of_init);
#ifdef CONFIG_PPC_83xx
@@ -267,51 +302,192 @@ static int __init mpc83xx_wdt_init(void)
if (!np) {
ret = -ENODEV;
- goto mpc83xx_wdt_nodev;
+ goto nodev;
}
soc = of_find_node_by_type(NULL, "soc");
if (!soc) {
ret = -ENODEV;
- goto mpc83xx_wdt_nosoc;
+ goto nosoc;
}
freq = (unsigned int *)get_property(soc, "bus-frequency", NULL);
if (!freq) {
ret = -ENODEV;
- goto mpc83xx_wdt_err;
+ goto err;
}
memset(&r, 0, sizeof(r));
ret = of_address_to_resource(np, 0, &r);
if (ret)
- goto mpc83xx_wdt_err;
+ goto err;
dev = platform_device_register_simple("mpc83xx_wdt", 0, &r, 1);
if (IS_ERR(dev)) {
ret = PTR_ERR(dev);
- goto mpc83xx_wdt_err;
+ goto err;
}
ret = platform_device_add_data(dev, freq, sizeof(int));
if (ret)
- goto mpc83xx_wdt_unreg;
+ goto unreg;
of_node_put(soc);
of_node_put(np);
return 0;
-mpc83xx_wdt_unreg:
+unreg:
platform_device_unregister(dev);
-mpc83xx_wdt_err:
+err:
of_node_put(soc);
-mpc83xx_wdt_nosoc:
+nosoc:
of_node_put(np);
-mpc83xx_wdt_nodev:
+nodev:
return ret;
}
+
arch_initcall(mpc83xx_wdt_init);
#endif
+
+static enum fsl_usb2_phy_modes determine_usb_phy(char * phy_type)
+{
+ if (!phy_type)
+ return FSL_USB2_PHY_NONE;
+ if (!strcasecmp(phy_type, "ulpi"))
+ return FSL_USB2_PHY_ULPI;
+ if (!strcasecmp(phy_type, "utmi"))
+ return FSL_USB2_PHY_UTMI;
+ if (!strcasecmp(phy_type, "utmi_wide"))
+ return FSL_USB2_PHY_UTMI_WIDE;
+ if (!strcasecmp(phy_type, "serial"))
+ return FSL_USB2_PHY_SERIAL;
+
+ return FSL_USB2_PHY_NONE;
+}
+
+static int __init fsl_usb_of_init(void)
+{
+ struct device_node *np;
+ unsigned int i;
+ struct platform_device *usb_dev;
+ int ret;
+
+ for (np = NULL, i = 0;
+ (np = of_find_compatible_node(np, "usb", "fsl-usb2-mph")) != NULL;
+ i++) {
+ struct resource r[2];
+ struct fsl_usb2_platform_data usb_data;
+ unsigned char *prop = NULL;
+
+ memset(&r, 0, sizeof(r));
+ memset(&usb_data, 0, sizeof(usb_data));
+
+ ret = of_address_to_resource(np, 0, &r[0]);
+ if (ret)
+ goto err;
+
+ r[1].start = np->intrs[0].line;
+ r[1].end = np->intrs[0].line;
+ r[1].flags = IORESOURCE_IRQ;
+
+ usb_dev =
+ platform_device_register_simple("fsl-usb2-mph", i, r, 2);
+ if (IS_ERR(usb_dev)) {
+ ret = PTR_ERR(usb_dev);
+ goto err;
+ }
+
+ usb_dev->dev.coherent_dma_mask = 0xffffffffUL;
+ usb_dev->dev.dma_mask = &usb_dev->dev.coherent_dma_mask;
+
+ usb_data.operating_mode = FSL_USB2_MPH_HOST;
+
+ prop = get_property(np, "port0", NULL);
+ if (prop)
+ usb_data.port_enables |= FSL_USB2_PORT0_ENABLED;
+
+ prop = get_property(np, "port1", NULL);
+ if (prop)
+ usb_data.port_enables |= FSL_USB2_PORT1_ENABLED;
+
+ prop = get_property(np, "phy_type", NULL);
+ usb_data.phy_mode = determine_usb_phy(prop);
+
+ ret =
+ platform_device_add_data(usb_dev, &usb_data,
+ sizeof(struct
+ fsl_usb2_platform_data));
+ if (ret)
+ goto unreg;
+ }
+
+ return 0;
+
+unreg:
+ platform_device_unregister(usb_dev);
+err:
+ return ret;
+}
+
+arch_initcall(fsl_usb_of_init);
+
+static int __init fsl_usb_dr_of_init(void)
+{
+ struct device_node *np;
+ unsigned int i;
+ struct platform_device *usb_dev;
+ int ret;
+
+ for (np = NULL, i = 0;
+ (np = of_find_compatible_node(np, "usb", "fsl-usb2-dr")) != NULL;
+ i++) {
+ struct resource r[2];
+ struct fsl_usb2_platform_data usb_data;
+ unsigned char *prop = NULL;
+
+ memset(&r, 0, sizeof(r));
+ memset(&usb_data, 0, sizeof(usb_data));
+
+ ret = of_address_to_resource(np, 0, &r[0]);
+ if (ret)
+ goto err;
+
+ r[1].start = np->intrs[0].line;
+ r[1].end = np->intrs[0].line;
+ r[1].flags = IORESOURCE_IRQ;
+
+ usb_dev =
+ platform_device_register_simple("fsl-usb2-dr", i, r, 2);
+ if (IS_ERR(usb_dev)) {
+ ret = PTR_ERR(usb_dev);
+ goto err;
+ }
+
+ usb_dev->dev.coherent_dma_mask = 0xffffffffUL;
+ usb_dev->dev.dma_mask = &usb_dev->dev.coherent_dma_mask;
+
+ usb_data.operating_mode = FSL_USB2_DR_HOST;
+
+ prop = get_property(np, "phy_type", NULL);
+ usb_data.phy_mode = determine_usb_phy(prop);
+
+ ret =
+ platform_device_add_data(usb_dev, &usb_data,
+ sizeof(struct
+ fsl_usb2_platform_data));
+ if (ret)
+ goto unreg;
+ }
+
+ return 0;
+
+unreg:
+ platform_device_unregister(usb_dev);
+err:
+ return ret;
+}
+
+arch_initcall(fsl_usb_dr_of_init);
diff --git a/arch/powerpc/sysdev/ipic.h b/arch/powerpc/sysdev/ipic.h
index a7ce7da8785c..a60c9d18bb7f 100644
--- a/arch/powerpc/sysdev/ipic.h
+++ b/arch/powerpc/sysdev/ipic.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/ipic.h
- *
* IPIC private definitions and structure.
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 7d02fa2a8990..4735b41c113c 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -191,6 +191,7 @@ Commands:\n\
di dump instructions\n\
df dump float values\n\
dd dump double values\n\
+ dr dump stream of raw bytes\n\
e print exception information\n\
f flush cache\n\
la lookup symbol+offset of specified address\n\
@@ -1938,6 +1939,28 @@ bsesc(void)
return c;
}
+static void xmon_rawdump (unsigned long adrs, long ndump)
+{
+ long n, m, r, nr;
+ unsigned char temp[16];
+
+ for (n = ndump; n > 0;) {
+ r = n < 16? n: 16;
+ nr = mread(adrs, temp, r);
+ adrs += nr;
+ for (m = 0; m < r; ++m) {
+ if (m < nr)
+ printf("%.2x", temp[m]);
+ else
+ printf("%s", fault_chars[fault_type]);
+ }
+ n -= r;
+ if (nr < r)
+ break;
+ }
+ printf("\n");
+}
+
#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
|| ('a' <= (c) && (c) <= 'f') \
|| ('A' <= (c) && (c) <= 'F'))
@@ -1960,6 +1983,13 @@ dump(void)
nidump = MAX_DUMP;
adrs += ppc_inst_dump(adrs, nidump, 1);
last_cmd = "di\n";
+ } else if (c == 'r') {
+ scanhex(&ndump);
+ if (ndump == 0)
+ ndump = 64;
+ xmon_rawdump(adrs, ndump);
+ adrs += ndump;
+ last_cmd = "dr\n";
} else {
scanhex(&ndump);
if (ndump == 0)
diff --git a/arch/ppc/4xx_io/serial_sicc.c b/arch/ppc/4xx_io/serial_sicc.c
index 8ace2a1f3b48..98b25fa0049a 100644
--- a/arch/ppc/4xx_io/serial_sicc.c
+++ b/arch/ppc/4xx_io/serial_sicc.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/4xx_io/serial_sicc.c
- *
* Driver for IBM STB3xxx SICC serial port
*
* Based on drivers/char/serial_amba.c, by ARM Ltd.
@@ -1639,9 +1637,8 @@ static struct SICC_info *siccuart_get(int line)
state->count++;
if (state->info)
return state->info;
- info = kmalloc(sizeof(struct SICC_info), GFP_KERNEL);
+ info = kzalloc(sizeof(struct SICC_info), GFP_KERNEL);
if (info) {
- memset(info, 0, sizeof(struct SICC_info));
init_waitqueue_head(&info->open_wait);
init_waitqueue_head(&info->close_wait);
init_waitqueue_head(&info->delta_msr_wait);
diff --git a/arch/ppc/8xx_io/commproc.c b/arch/ppc/8xx_io/commproc.c
index 579cd40258b9..12b84ca51327 100644
--- a/arch/ppc/8xx_io/commproc.c
+++ b/arch/ppc/8xx_io/commproc.c
@@ -73,7 +73,7 @@ cpm_mask_irq(unsigned int irq)
{
int cpm_vec = irq - CPM_IRQ_OFFSET;
- out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr, in_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr) & ~(1 << cpm_vec));
+ clrbits32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr, (1 << cpm_vec));
}
static void
@@ -81,7 +81,7 @@ cpm_unmask_irq(unsigned int irq)
{
int cpm_vec = irq - CPM_IRQ_OFFSET;
- out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr, in_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr) | (1 << cpm_vec));
+ setbits32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr, (1 << cpm_vec));
}
static void
@@ -198,7 +198,7 @@ cpm_interrupt_init(void)
if (setup_irq(CPM_IRQ_OFFSET + CPMVEC_ERROR, &cpm_error_irqaction))
panic("Could not allocate CPM error IRQ!");
- out_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr, in_be32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr) | CICR_IEN);
+ setbits32(&((immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr, CICR_IEN);
}
/*
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 11899f06bf06..54a0a9bb12dd 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -481,6 +481,53 @@ config WINCEPT
endchoice
+menu "Freescale Ethernet driver platform-specific options"
+ depends on FS_ENET
+
+ config MPC8xx_SECOND_ETH
+ bool "Second Ethernet channel"
+ depends on (MPC885ADS || MPC86XADS)
+ default y
+ help
+ This enables support for second Ethernet on MPC885ADS and MPC86xADS boards.
+ The latter will use SCC1, for 885ADS you can select it below.
+
+ choice
+ prompt "Second Ethernet channel"
+ depends on MPC8xx_SECOND_ETH
+ default MPC8xx_SECOND_ETH_FEC2
+
+ config MPC8xx_SECOND_ETH_FEC2
+ bool "FEC2"
+ depends on MPC885ADS
+ help
+ Enable FEC2 to serve as 2-nd Ethernet channel. Note that SMC2
+ (often 2-nd UART) will not work if this is enabled.
+
+ config MPC8xx_SECOND_ETH_SCC1
+ bool "SCC1"
+ depends on MPC86XADS
+ select MPC8xx_SCC_ENET_FIXED
+ help
+ Enable SCC1 to serve as 2-nd Ethernet channel. Note that SMC1
+ (often 1-nd UART) will not work if this is enabled.
+
+ config MPC8xx_SECOND_ETH_SCC3
+ bool "SCC3"
+ depends on MPC885ADS
+ help
+ Enable SCC3 to serve as 2-nd Ethernet channel. Note that SMC1
+ (often 1-nd UART) will not work if this is enabled.
+
+ endchoice
+
+ config MPC8xx_SCC_ENET_FIXED
+ depends on MPC8xx_SECOND_ETH_SCC
+ default n
+ bool "Use fixed MII-less mode for SCC Ethernet"
+
+endmenu
+
choice
prompt "Machine Type"
depends on 6xx || POWER3
diff --git a/arch/ppc/Kconfig.debug b/arch/ppc/Kconfig.debug
index 61653cb60c4e..8cc75abf3d83 100644
--- a/arch/ppc/Kconfig.debug
+++ b/arch/ppc/Kconfig.debug
@@ -67,7 +67,7 @@ config SERIAL_TEXT_DEBUG
config PPC_OCP
bool
- depends on IBM_OCP || XILINX_OCP
+ depends on IBM_OCP
default y
endmenu
diff --git a/arch/ppc/amiga/amiints.c b/arch/ppc/amiga/amiints.c
index 5f35cf3986f7..b2bba052ab93 100644
--- a/arch/ppc/amiga/amiints.c
+++ b/arch/ppc/amiga/amiints.c
@@ -1,5 +1,5 @@
/*
- * arch/ppc/amiga/amiints.c -- Amiga Linux interrupt handling code
+ * Amiga Linux interrupt handling code
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
diff --git a/arch/ppc/amiga/bootinfo.c b/arch/ppc/amiga/bootinfo.c
index e2e965661d03..efd869a3ed9b 100644
--- a/arch/ppc/amiga/bootinfo.c
+++ b/arch/ppc/amiga/bootinfo.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/amiga/bootinfo.c
- *
* Extracted from arch/m68k/kernel/setup.c.
* Should be properly generalized and put somewhere else.
* Jesper
diff --git a/arch/ppc/amiga/cia.c b/arch/ppc/amiga/cia.c
index 4431c58f611a..9558f2f40e64 100644
--- a/arch/ppc/amiga/cia.c
+++ b/arch/ppc/amiga/cia.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/amiga/cia.c - CIA support
- *
* Copyright (C) 1996 Roman Zippel
*
* The concept of some functions bases on the original Amiga OS function
diff --git a/arch/ppc/amiga/config.c b/arch/ppc/amiga/config.c
index 60e2da1c92c0..bbe47c9bd707 100644
--- a/arch/ppc/amiga/config.c
+++ b/arch/ppc/amiga/config.c
@@ -1,8 +1,6 @@
#define m68k_debug_device debug_device
/*
- * arch/ppc/amiga/config.c
- *
* Copyright (C) 1993 Hamish Macdonald
*
* This file is subject to the terms and conditions of the GNU General Public
diff --git a/arch/ppc/amiga/ints.c b/arch/ppc/amiga/ints.c
index 5d318e498f06..083a17462190 100644
--- a/arch/ppc/amiga/ints.c
+++ b/arch/ppc/amiga/ints.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/amiga/ints.c
- *
* Linux/m68k general interrupt handling code from arch/m68k/kernel/ints.c
* Needed to drive the m68k emulating IRQ hardware on the PowerUp boards.
*/
diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile
index efd8ce515d5f..f565699a9fe0 100644
--- a/arch/ppc/boot/Makefile
+++ b/arch/ppc/boot/Makefile
@@ -1,6 +1,3 @@
-#
-# arch/ppc/boot/Makefile
-#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
diff --git a/arch/ppc/boot/common/Makefile b/arch/ppc/boot/common/Makefile
index f88d647d5dd4..a2e85e3beb88 100644
--- a/arch/ppc/boot/common/Makefile
+++ b/arch/ppc/boot/common/Makefile
@@ -1,6 +1,3 @@
-#
-# arch/ppc/boot/common/Makefile
-#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
diff --git a/arch/ppc/boot/common/bootinfo.c b/arch/ppc/boot/common/bootinfo.c
index 9c6e528940e9..f4dc9b9fab9c 100644
--- a/arch/ppc/boot/common/bootinfo.c
+++ b/arch/ppc/boot/common/bootinfo.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/common/bootinfo.c
- *
* General bootinfo record utilities
* Author: Randy Vinson <rvinson@mvista.com>
*
diff --git a/arch/ppc/boot/common/misc-common.c b/arch/ppc/boot/common/misc-common.c
index e79e6b3f276e..073830a8559a 100644
--- a/arch/ppc/boot/common/misc-common.c
+++ b/arch/ppc/boot/common/misc-common.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/boot/common/misc-common.c
- *
* Misc. bootloader code (almost) all platforms can use
*
* Author: Johnnie Peters <jpeters@mvista.com>
diff --git a/arch/ppc/boot/common/ns16550.c b/arch/ppc/boot/common/ns16550.c
index 26818bbb6cff..4f00c93ac870 100644
--- a/arch/ppc/boot/common/ns16550.c
+++ b/arch/ppc/boot/common/ns16550.c
@@ -8,6 +8,9 @@
#include <linux/serial_reg.h>
#include <asm/serial.h>
+#if defined(CONFIG_XILINX_VIRTEX)
+#include <platforms/4xx/xparameters/xparameters.h>
+#endif
#include "nonstdio.h"
#include "serial.h"
diff --git a/arch/ppc/boot/common/serial_stub.c b/arch/ppc/boot/common/serial_stub.c
index 03dfaa01fa63..5cc9ae66a8ba 100644
--- a/arch/ppc/boot/common/serial_stub.c
+++ b/arch/ppc/boot/common/serial_stub.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/boot/common/serial_stub.c
- *
* This is a few stub routines to make the boot code cleaner looking when
* there is no serial port support doesn't need to be closed, for example.
*
diff --git a/arch/ppc/boot/common/util.S b/arch/ppc/boot/common/util.S
index 368ec035e6cd..0c5e43c4ae06 100644
--- a/arch/ppc/boot/common/util.S
+++ b/arch/ppc/boot/common/util.S
@@ -1,6 +1,4 @@
/*
- * arch/ppc/boot/common/util.S
- *
* Useful bootup functions, which are more easily done in asm than C.
*
* NOTE: Be very very careful about the registers you use here.
diff --git a/arch/ppc/boot/include/mpc10x.h b/arch/ppc/boot/include/mpc10x.h
index 6cd40ecabc74..6e5d540d8d3e 100644
--- a/arch/ppc/boot/include/mpc10x.h
+++ b/arch/ppc/boot/include/mpc10x.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/boot/include/mpc10.h
- *
* Common defines for the Motorola SPS MPC106/8240/107 Host bridge/Mem
* ctrl/EPIC/etc.
*
diff --git a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile
index 9533f8de238f..28be01b99c44 100644
--- a/arch/ppc/boot/simple/Makefile
+++ b/arch/ppc/boot/simple/Makefile
@@ -192,6 +192,7 @@ boot-$(CONFIG_8xx) += embed_config.o
boot-$(CONFIG_8260) += embed_config.o
boot-$(CONFIG_EP405) += embed_config.o
boot-$(CONFIG_XILINX_ML300) += embed_config.o
+boot-$(CONFIG_XILINX_ML403) += embed_config.o
boot-$(CONFIG_BSEIP) += iic.o
boot-$(CONFIG_MBX) += iic.o pci.o qspan_pci.o
boot-$(CONFIG_MV64X60) += misc-mv64x60.o
diff --git a/arch/ppc/boot/simple/cpc700_memory.c b/arch/ppc/boot/simple/cpc700_memory.c
index 8c75cf6c2383..d75420a45a59 100644
--- a/arch/ppc/boot/simple/cpc700_memory.c
+++ b/arch/ppc/boot/simple/cpc700_memory.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/boot/common/cpc700_memory.c
- *
* Find memory based upon settings in the CPC700 bridge
*
* Author: Dan Cox
diff --git a/arch/ppc/boot/simple/embed_config.c b/arch/ppc/boot/simple/embed_config.c
index 491a691d10cc..3a51b1062940 100644
--- a/arch/ppc/boot/simple/embed_config.c
+++ b/arch/ppc/boot/simple/embed_config.c
@@ -21,6 +21,9 @@
#ifdef CONFIG_40x
#include <asm/io.h>
#endif
+#ifdef CONFIG_XILINX_VIRTEX
+#include <platforms/4xx/xparameters/xparameters.h>
+#endif
extern unsigned long timebase_period_ns;
/* For those boards that don't provide one.
@@ -742,7 +745,7 @@ embed_config(bd_t **bdp)
}
#endif /* WILLOW */
-#ifdef CONFIG_XILINX_ML300
+#if defined(CONFIG_XILINX_ML300) || defined(CONFIG_XILINX_ML403)
void
embed_config(bd_t ** bdp)
{
@@ -779,7 +782,7 @@ embed_config(bd_t ** bdp)
timebase_period_ns = 1000000000 / bd->bi_tbfreq;
/* see bi_tbfreq definition in arch/ppc/platforms/4xx/xilinx_ml300.h */
}
-#endif /* CONFIG_XILINX_ML300 */
+#endif /* CONFIG_XILINX_ML300 || CONFIG_XILINX_ML403 */
#ifdef CONFIG_IBM_OPENBIOS
/* This could possibly work for all treeboot roms.
diff --git a/arch/ppc/boot/simple/head.S b/arch/ppc/boot/simple/head.S
index 5e4adc298bf9..160da1006ff8 100644
--- a/arch/ppc/boot/simple/head.S
+++ b/arch/ppc/boot/simple/head.S
@@ -1,6 +1,4 @@
/*
- * arch/ppc/boot/simple/head.S
- *
* Initial board bringup code for many different boards.
*
* Author: Tom Rini
@@ -65,6 +63,13 @@ start_:
*/
#endif
+#if defined(CONFIG_XILINX_VIRTEX_4_FX)
+ /* PPC errata 213: only for Virtex-4 FX */
+ mfccr0 0
+ oris 0,0,0x50000000@h
+ mtccr0 0
+#endif
+
mflr r3 /* Save our actual starting address. */
/* The following functions we call must not modify r3 or r4.....
diff --git a/arch/ppc/boot/simple/misc-chestnut.c b/arch/ppc/boot/simple/misc-chestnut.c
index 0dce7f3557e4..b94e142ad892 100644
--- a/arch/ppc/boot/simple/misc-chestnut.c
+++ b/arch/ppc/boot/simple/misc-chestnut.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/boot/simple/misc-chestnut.c
- *
* Setup for the IBM Chestnut (ibm-750fxgx_eval)
*
* Author: Mark A. Greer <mgreer@mvista.com>
diff --git a/arch/ppc/boot/simple/misc-cpci690.c b/arch/ppc/boot/simple/misc-cpci690.c
index 26860300fa09..8a8614d11a32 100644
--- a/arch/ppc/boot/simple/misc-cpci690.c
+++ b/arch/ppc/boot/simple/misc-cpci690.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/boot/simple/misc-cpci690.c
- *
* Add birec data for Force CPCI690 board.
*
* Author: Mark A. Greer <source@mvista.com>
diff --git a/arch/ppc/boot/simple/misc-ev64260.c b/arch/ppc/boot/simple/misc-ev64260.c
index 52ece6937a7a..2678c224af22 100644
--- a/arch/ppc/boot/simple/misc-ev64260.c
+++ b/arch/ppc/boot/simple/misc-ev64260.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/boot/simple/misc-ev64260.c
- *
* Host bridge init code for the Marvell/Galileo EV-64260-BP evaluation board
* with a GT64260 onboard.
*
diff --git a/arch/ppc/boot/simple/misc-ev64360.c b/arch/ppc/boot/simple/misc-ev64360.c
index cd1ccf2a1582..a212b5b988cb 100644
--- a/arch/ppc/boot/simple/misc-ev64360.c
+++ b/arch/ppc/boot/simple/misc-ev64360.c
@@ -1,5 +1,4 @@
/*
- * arch/ppc/boot/simple/misc-ev64360.c
* Copyright (C) 2005 Lee Nicks <allinux@gmail.com>
*
* Based on arch/ppc/boot/simple/misc-katana.c from:
diff --git a/arch/ppc/boot/simple/misc-katana.c b/arch/ppc/boot/simple/misc-katana.c
index ec94a11bacac..d97f2ee6f04e 100644
--- a/arch/ppc/boot/simple/misc-katana.c
+++ b/arch/ppc/boot/simple/misc-katana.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/boot/simple/misc-katana.c
- *
* Set up MPSC values to bootwrapper can prompt user.
*
* Author: Mark A. Greer <source@mvista.com>
diff --git a/arch/ppc/boot/simple/misc-mv64x60.c b/arch/ppc/boot/simple/misc-mv64x60.c
index 258d4599fadc..71ff20fd494a 100644
--- a/arch/ppc/boot/simple/misc-mv64x60.c
+++ b/arch/ppc/boot/simple/misc-mv64x60.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/boot/simple/misc-mv64x60.c
- *
* Relocate bridge's register base and call board specific routine.
*
* Author: Mark A. Greer <source@mvista.com>
diff --git a/arch/ppc/boot/simple/misc-prep.c b/arch/ppc/boot/simple/misc-prep.c
index 75380ac41669..63def9d13d70 100644
--- a/arch/ppc/boot/simple/misc-prep.c
+++ b/arch/ppc/boot/simple/misc-prep.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/boot/simple/misc-prep.c
- *
* Maintainer: Tom Rini <trini@kernel.crashing.org>
*
* In the past: Gary Thomas, Cort Dougan <cort@cs.nmt.edu>
diff --git a/arch/ppc/boot/simple/misc-radstone_ppc7d.c b/arch/ppc/boot/simple/misc-radstone_ppc7d.c
index 569e0d4feeaf..0f302ea9c3d1 100644
--- a/arch/ppc/boot/simple/misc-radstone_ppc7d.c
+++ b/arch/ppc/boot/simple/misc-radstone_ppc7d.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/boot/simple/misc-radstone_ppc7d.c
- *
* Misc data for Radstone PPC7D board.
*
* Author: James Chapman <jchapman@katalix.com>
diff --git a/arch/ppc/boot/simple/misc-spruce.c b/arch/ppc/boot/simple/misc-spruce.c
index d012c39278fd..0cad2f557a1e 100644
--- a/arch/ppc/boot/simple/misc-spruce.c
+++ b/arch/ppc/boot/simple/misc-spruce.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/boot/spruce/misc.c
- *
* Misc. bootloader code for IBM Spruce reference platform
*
* Authors: Johnnie Peters <jpeters@mvista.com>
diff --git a/arch/ppc/boot/simple/misc.c b/arch/ppc/boot/simple/misc.c
index f415d6c62362..3d78571ad945 100644
--- a/arch/ppc/boot/simple/misc.c
+++ b/arch/ppc/boot/simple/misc.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/simple/misc.c
- *
* Misc. bootloader code for many machines. This assumes you have are using
* a 6xx/7xx/74xx CPU in your machine. This assumes the chunk of memory
* below 8MB is free. Finally, it assumes you have a NS16550-style uart for
diff --git a/arch/ppc/boot/simple/mpc10x_memory.c b/arch/ppc/boot/simple/mpc10x_memory.c
index 20d92a34ceb8..c24290823f7f 100644
--- a/arch/ppc/boot/simple/mpc10x_memory.c
+++ b/arch/ppc/boot/simple/mpc10x_memory.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/boot/common/mpc10x_common.c
- *
* A routine to find out how much memory the machine has.
*
* Based on:
diff --git a/arch/ppc/boot/simple/mpc52xx_tty.c b/arch/ppc/boot/simple/mpc52xx_tty.c
index 3acc6b7c0727..1964493cf3bd 100644
--- a/arch/ppc/boot/simple/mpc52xx_tty.c
+++ b/arch/ppc/boot/simple/mpc52xx_tty.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/boot/simple/mpc52xx_tty.c
- *
* Minimal serial functions needed to send messages out a MPC52xx
* Programmable Serial Controller (PSC).
*
diff --git a/arch/ppc/boot/simple/mv64x60_tty.c b/arch/ppc/boot/simple/mv64x60_tty.c
index b9c24d4c738b..0c52f5c784a2 100644
--- a/arch/ppc/boot/simple/mv64x60_tty.c
+++ b/arch/ppc/boot/simple/mv64x60_tty.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/boot/simple/mv64x60_tty.c
- *
* Bootloader version of the embedded MPSC/UART driver for the Marvell 64x60.
* Note: Due to a GT64260A erratum, DMA will be used for UART input (via SDMA).
*
diff --git a/arch/ppc/boot/simple/openbios.c b/arch/ppc/boot/simple/openbios.c
index 81f11d8b30a7..3f2ed53f793a 100644
--- a/arch/ppc/boot/simple/openbios.c
+++ b/arch/ppc/boot/simple/openbios.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/boot/simple/openbios.c
- *
* Copyright (c) 2005 DENX Software Engineering
* Stefan Roese <sr@denx.de>
*
diff --git a/arch/ppc/boot/simple/relocate.S b/arch/ppc/boot/simple/relocate.S
index 555a216ccc49..7efddc507564 100644
--- a/arch/ppc/boot/simple/relocate.S
+++ b/arch/ppc/boot/simple/relocate.S
@@ -1,6 +1,4 @@
/*
- * arch/ppc/boot/simple/relocate.S
- *
* This is the common part of the loader relocation and initialization
* process. All of the board/processor specific initialization is
* done before we get here.
diff --git a/arch/ppc/boot/utils/mkbugboot.c b/arch/ppc/boot/utils/mkbugboot.c
index 886122283f39..29115e01f60a 100644
--- a/arch/ppc/boot/utils/mkbugboot.c
+++ b/arch/ppc/boot/utils/mkbugboot.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/boot/utils/mkbugboot.c
- *
* Makes a Motorola PPCBUG ROM bootable image which can be flashed
* into one of the FLASH banks on a Motorola PowerPlus board.
*
diff --git a/arch/ppc/configs/ml300_defconfig b/arch/ppc/configs/ml300_defconfig
new file mode 100644
index 000000000000..4a33aca948cc
--- /dev/null
+++ b/arch/ppc/configs/ml300_defconfig
@@ -0,0 +1,739 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.16-rc1
+# Wed Jan 18 00:49:20 2006
+#
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_PPC=y
+CONFIG_PPC32=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+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_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+
+#
+# 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"
+
+#
+# Processor
+#
+# CONFIG_6xx is not set
+CONFIG_40x=y
+# CONFIG_44x is not set
+# CONFIG_POWER3 is not set
+# CONFIG_8xx is not set
+# CONFIG_E200 is not set
+# CONFIG_E500 is not set
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CPU_FREQ is not set
+CONFIG_4xx=y
+# CONFIG_WANT_EARLY_SERIAL is not set
+
+#
+# IBM 4xx options
+#
+# CONFIG_BUBINGA is not set
+# CONFIG_CPCI405 is not set
+# CONFIG_EP405 is not set
+# CONFIG_REDWOOD_5 is not set
+# CONFIG_REDWOOD_6 is not set
+# CONFIG_SYCAMORE is not set
+# CONFIG_WALNUT is not set
+CONFIG_XILINX_ML300=y
+CONFIG_IBM405_ERR77=y
+CONFIG_IBM405_ERR51=y
+CONFIG_XILINX_VIRTEX=y
+CONFIG_EMBEDDEDBOOT=y
+# CONFIG_PPC4xx_DMA is not set
+CONFIG_PPC_GEN550=y
+CONFIG_UART0_TTYS0=y
+# CONFIG_UART0_TTYS1 is not set
+CONFIG_NOT_COHERENT_CACHE=y
+
+#
+# Platform options
+#
+# CONFIG_PC_KEYBOARD is not set
+# 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_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_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,9600"
+# CONFIG_PM is not set
+# CONFIG_SOFTWARE_SUSPEND is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD 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_CONSISTENT_START=0xff100000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_BOOT_LOAD=0x00400000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_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_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC 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_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=65536
+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 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
+#
+
+#
+# I2O device support
+#
+
+#
+# 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=y
+
+#
+# PHY device support
+#
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+# CONFIG_IBM_EMAC is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN 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=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=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_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP 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 is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI 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
+
+#
+# InfiniBand support
+#
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_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_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# 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_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_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 is not set
+# CONFIG_NFSD 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 is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+
+#
+# IBM 40x options
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_MAGIC_SYSRQ=y
+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=y
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_KGDB is not set
+CONFIG_XMON=y
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_SERIAL_TEXT_DEBUG 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
+#
diff --git a/arch/ppc/configs/ml403_defconfig b/arch/ppc/configs/ml403_defconfig
new file mode 100644
index 000000000000..fafd2516fa51
--- /dev/null
+++ b/arch/ppc/configs/ml403_defconfig
@@ -0,0 +1,740 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.16-rc1
+# Wed Jan 18 01:11:41 2006
+#
+CONFIG_MMU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_PPC=y
+CONFIG_PPC32=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_EMBEDDED is not set
+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_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_SLAB=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_LBD=y
+
+#
+# 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"
+
+#
+# Processor
+#
+# CONFIG_6xx is not set
+CONFIG_40x=y
+# CONFIG_44x is not set
+# CONFIG_POWER3 is not set
+# CONFIG_8xx is not set
+# CONFIG_E200 is not set
+# CONFIG_E500 is not set
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CPU_FREQ is not set
+CONFIG_4xx=y
+# CONFIG_WANT_EARLY_SERIAL is not set
+
+#
+# IBM 4xx options
+#
+# CONFIG_BUBINGA is not set
+# CONFIG_CPCI405 is not set
+# CONFIG_EP405 is not set
+# CONFIG_REDWOOD_5 is not set
+# CONFIG_REDWOOD_6 is not set
+# CONFIG_SYCAMORE is not set
+# CONFIG_WALNUT is not set
+# CONFIG_XILINX_ML300 is not set
+CONFIG_XILINX_ML403=y
+CONFIG_IBM405_ERR77=y
+CONFIG_IBM405_ERR51=y
+CONFIG_XILINX_VIRTEX=y
+CONFIG_EMBEDDEDBOOT=y
+# CONFIG_PPC4xx_DMA is not set
+CONFIG_PPC_GEN550=y
+CONFIG_UART0_TTYS0=y
+# CONFIG_UART0_TTYS1 is not set
+CONFIG_NOT_COHERENT_CACHE=y
+
+#
+# Platform options
+#
+# CONFIG_PC_KEYBOARD is not set
+# 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_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_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=ttyS0,9600"
+# CONFIG_PM is not set
+# CONFIG_SOFTWARE_SUSPEND is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD 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_CONSISTENT_START=0xff100000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_BOOT_LOAD=0x00400000
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_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_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP 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
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC 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_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=65536
+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 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
+#
+
+#
+# I2O device support
+#
+
+#
+# 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=y
+
+#
+# PHY device support
+#
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+# CONFIG_IBM_EMAC is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN 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=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# 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=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=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_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_AGP 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 is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI 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
+
+#
+# InfiniBand support
+#
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_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_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# 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_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_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 is not set
+# CONFIG_NFSD 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 is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+
+#
+# IBM 40x options
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_MAGIC_SYSRQ=y
+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=y
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_KGDB is not set
+CONFIG_XMON=y
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_SERIAL_TEXT_DEBUG 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
+#
diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S
index 677c571aa276..0d8b88219d38 100644
--- a/arch/ppc/kernel/head_44x.S
+++ b/arch/ppc/kernel/head_44x.S
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/head_44x.S
- *
* Kernel execution entry point code.
*
* Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S
index c1e89ad0684d..ec53c7d65f2b 100644
--- a/arch/ppc/kernel/head_8xx.S
+++ b/arch/ppc/kernel/head_8xx.S
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/except_8xx.S
- *
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
* Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
diff --git a/arch/ppc/kernel/head_fsl_booke.S b/arch/ppc/kernel/head_fsl_booke.S
index 8d60fa99fc4b..dd86bbed7627 100644
--- a/arch/ppc/kernel/head_fsl_booke.S
+++ b/arch/ppc/kernel/head_fsl_booke.S
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/head_fsl_booke.S
- *
* Kernel execution entry point code.
*
* Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
@@ -316,6 +314,7 @@ skpinv: addi r6,r6,1 /* Increment */
*/
lis r2,DBCR0_IDM@h
mtspr SPRN_DBCR0,r2
+ isync
/* clear any residual debug events */
li r2,-1
mtspr SPRN_DBSR,r2
@@ -1002,12 +1001,15 @@ _GLOBAL(giveup_fpu)
_GLOBAL(abort)
li r13,0
mtspr SPRN_DBCR0,r13 /* disable all debug events */
+ isync
mfmsr r13
ori r13,r13,MSR_DE@l /* Enable Debug Events */
mtmsr r13
+ isync
mfspr r13,SPRN_DBCR0
lis r13,(DBCR0_IDM|DBCR0_RST_CHIP)@h
mtspr SPRN_DBCR0,r13
+ isync
_GLOBAL(set_context)
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index c08ab432e958..53e9deacee82 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -168,9 +168,8 @@ int show_cpuinfo(struct seq_file *m, void *v)
/* Show summary information */
#ifdef CONFIG_SMP
unsigned long bogosum = 0;
- for (i = 0; i < NR_CPUS; ++i)
- if (cpu_online(i))
- bogosum += cpu_data[i].loops_per_jiffy;
+ for_each_online_cpu(i)
+ bogosum += cpu_data[i].loops_per_jiffy;
seq_printf(m, "total bogomips\t: %lu.%02lu\n",
bogosum/(500000/HZ), bogosum/(5000/HZ) % 100);
#endif /* CONFIG_SMP */
@@ -712,9 +711,8 @@ int __init ppc_init(void)
if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff);
/* register CPU devices */
- for (i = 0; i < NR_CPUS; i++)
- if (cpu_possible(i))
- register_cpu(&cpu_devices[i], i, NULL);
+ for_each_cpu(i)
+ register_cpu(&cpu_devices[i], i, NULL);
/* call platform init */
if (ppc_md.init != NULL) {
diff --git a/arch/ppc/kernel/smp-tbsync.c b/arch/ppc/kernel/smp-tbsync.c
index 2c9cd95bcea6..6a5694fcc711 100644
--- a/arch/ppc/kernel/smp-tbsync.c
+++ b/arch/ppc/kernel/smp-tbsync.c
@@ -126,8 +126,7 @@ smp_generic_give_timebase( void )
printk("Synchronizing timebase\n");
/* if this fails then this kernel won't work anyway... */
- tbsync = kmalloc( sizeof(*tbsync), GFP_KERNEL );
- memset( tbsync, 0, sizeof(*tbsync) );
+ tbsync = kzalloc( sizeof(*tbsync), GFP_KERNEL );
mb();
running = 1;
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index 6d0a1838d94c..1c0d68026abd 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/traps.c
- *
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
* This program is free software; you can redistribute it and/or
diff --git a/arch/ppc/lib/rheap.c b/arch/ppc/lib/rheap.c
index 42c5de2c898f..31e511856dc5 100644
--- a/arch/ppc/lib/rheap.c
+++ b/arch/ppc/lib/rheap.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/rheap.c
- *
* A Remote Heap. Remote means that we don't touch the memory that the
* heap points to. Normal heap implementations use the memory they manage
* to place their list. We cannot do that because the memory we manage may
diff --git a/arch/ppc/math-emu/math.c b/arch/ppc/math-emu/math.c
index b7dff53a7103..589153472761 100644
--- a/arch/ppc/math-emu/math.c
+++ b/arch/ppc/math-emu/math.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/math-emu/math.c
- *
* Copyright (C) 1999 Eddie C. Dost (ecd@atecom.com)
*/
diff --git a/arch/ppc/mm/44x_mmu.c b/arch/ppc/mm/44x_mmu.c
index 3d79ce281b67..e0152a9b26e6 100644
--- a/arch/ppc/mm/44x_mmu.c
+++ b/arch/ppc/mm/44x_mmu.c
@@ -104,7 +104,7 @@ unsigned long __init mmu_mapin_ram(void)
/* Determine number of entries necessary to cover lowmem */
pinned_tlbs = (unsigned int)
- (_ALIGN(total_lowmem, PPC44x_PIN_SIZE) >> PPC44x_PIN_SHIFT);
+ (_ALIGN(total_lowmem, PPC_PIN_SIZE) >> PPC44x_PIN_SHIFT);
/* Write upper watermark to save location */
tlb_44x_hwater = PPC44x_LOW_SLOT - pinned_tlbs;
@@ -112,7 +112,7 @@ unsigned long __init mmu_mapin_ram(void)
/* If necessary, set additional pinned TLBs */
if (pinned_tlbs > 1)
for (i = (PPC44x_LOW_SLOT-(pinned_tlbs-1)); i < PPC44x_LOW_SLOT; i++) {
- unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC44x_PIN_SIZE;
+ unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC_PIN_SIZE;
ppc44x_pin_tlb(i, phys_addr+PAGE_OFFSET, phys_addr);
}
diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
index ee5e9f25baf9..0217188ef465 100644
--- a/arch/ppc/mm/fault.c
+++ b/arch/ppc/mm/fault.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/mm/fault.c
- *
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
diff --git a/arch/ppc/mm/hashtable.S b/arch/ppc/mm/hashtable.S
index 3ec87c91343e..f09fa88db35a 100644
--- a/arch/ppc/mm/hashtable.S
+++ b/arch/ppc/mm/hashtable.S
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/hashtable.S
- *
* $Id: hashtable.S,v 1.6 1999/10/08 01:56:15 paulus Exp $
*
* PowerPC version
diff --git a/arch/ppc/platforms/4xx/Kconfig b/arch/ppc/platforms/4xx/Kconfig
index d8837911bbc6..174ddbc9758b 100644
--- a/arch/ppc/platforms/4xx/Kconfig
+++ b/arch/ppc/platforms/4xx/Kconfig
@@ -57,6 +57,10 @@ config XILINX_ML300
help
This option enables support for the Xilinx ML300 evaluation board.
+config XILINX_ML403
+ bool "Xilinx-ML403"
+ help
+ This option enables support for the Xilinx ML403 evaluation board.
endchoice
choice
@@ -172,11 +176,6 @@ config IBM_OCP
depends on ASH || BAMBOO || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || YUCCA || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
default y
-config XILINX_OCP
- bool
- depends on XILINX_ML300
- default y
-
config IBM_EMAC4
bool
depends on 440GX || 440SP || 440SPE
@@ -208,11 +207,21 @@ config 405GPR
depends on SYCAMORE
default y
-config VIRTEX_II_PRO
+config XILINX_VIRTEX_II_PRO
bool
depends on XILINX_ML300
default y
+config XILINX_VIRTEX_4_FX
+ bool
+ depends on XILINX_ML403
+ default y
+
+config XILINX_VIRTEX
+ bool
+ depends on XILINX_VIRTEX_II_PRO || XILINX_VIRTEX_4_FX
+ default y
+
config STB03xxx
bool
depends on REDWOOD_5 || REDWOOD_6
@@ -220,7 +229,7 @@ config STB03xxx
config EMBEDDEDBOOT
bool
- depends on EP405 || XILINX_ML300
+ depends on EP405 || XILINX_ML300 || XILINX_ML403
default y
config IBM_OPENBIOS
diff --git a/arch/ppc/platforms/4xx/Makefile b/arch/ppc/platforms/4xx/Makefile
index c9bb61170954..a04a0d0a0f5c 100644
--- a/arch/ppc/platforms/4xx/Makefile
+++ b/arch/ppc/platforms/4xx/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_REDWOOD_6) += redwood6.o
obj-$(CONFIG_SYCAMORE) += sycamore.o
obj-$(CONFIG_WALNUT) += walnut.o
obj-$(CONFIG_XILINX_ML300) += xilinx_ml300.o
+obj-$(CONFIG_XILINX_ML403) += xilinx_ml403.o
obj-$(CONFIG_405GP) += ibm405gp.o
obj-$(CONFIG_REDWOOD_5) += ibmstb4.o
@@ -26,4 +27,5 @@ obj-$(CONFIG_440SP) += ibm440sp.o
obj-$(CONFIG_440SPE) += ppc440spe.o
obj-$(CONFIG_405EP) += ibm405ep.o
obj-$(CONFIG_405GPR) += ibm405gpr.o
-obj-$(CONFIG_VIRTEX_II_PRO) += virtex-ii_pro.o
+obj-$(CONFIG_XILINX_VIRTEX) += virtex.o
+
diff --git a/arch/ppc/platforms/4xx/bamboo.c b/arch/ppc/platforms/4xx/bamboo.c
index 0ec53f049338..b940cfd646c2 100644
--- a/arch/ppc/platforms/4xx/bamboo.c
+++ b/arch/ppc/platforms/4xx/bamboo.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/bamboo.c
- *
* Bamboo board specific routines
*
* Wade Farnsworth <wfarnsworth@mvista.com>
diff --git a/arch/ppc/platforms/4xx/bamboo.h b/arch/ppc/platforms/4xx/bamboo.h
index 5c0192826494..31c0dd6a26cb 100644
--- a/arch/ppc/platforms/4xx/bamboo.h
+++ b/arch/ppc/platforms/4xx/bamboo.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/bamboo.h
- *
* Bamboo board definitions
*
* Wade Farnsworth <wfarnsworth@mvista.com>
diff --git a/arch/ppc/platforms/4xx/bubinga.h b/arch/ppc/platforms/4xx/bubinga.h
index b5380cfaf5c0..606aa9fa5caa 100644
--- a/arch/ppc/platforms/4xx/bubinga.h
+++ b/arch/ppc/platforms/4xx/bubinga.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/bubinga.h
- *
* Bubinga board definitions
*
* Copyright (c) 2005 DENX Software Engineering
diff --git a/arch/ppc/platforms/4xx/cpci405.c b/arch/ppc/platforms/4xx/cpci405.c
index ff966773a0bf..6571e39fbe48 100644
--- a/arch/ppc/platforms/4xx/cpci405.c
+++ b/arch/ppc/platforms/4xx/cpci405.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/cpci405.c
- *
* Board setup routines for the esd CPCI-405 cPCI Board.
*
* Author: Stefan Roese
diff --git a/arch/ppc/platforms/4xx/ebony.c b/arch/ppc/platforms/4xx/ebony.c
index 9a828b623417..b4ecb9c79854 100644
--- a/arch/ppc/platforms/4xx/ebony.c
+++ b/arch/ppc/platforms/4xx/ebony.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ebony.c
- *
* Ebony board specific routines
*
* Matt Porter <mporter@kernel.crashing.org>
diff --git a/arch/ppc/platforms/4xx/ebony.h b/arch/ppc/platforms/4xx/ebony.h
index b91ad4272dfe..27b2e77c7c83 100644
--- a/arch/ppc/platforms/4xx/ebony.h
+++ b/arch/ppc/platforms/4xx/ebony.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/ebony.h
- *
* Ebony board definitions
*
* Matt Porter <mporter@mvista.com>
diff --git a/arch/ppc/platforms/4xx/ep405.c b/arch/ppc/platforms/4xx/ep405.c
index 26a07cdb30ec..6efa91ff9c07 100644
--- a/arch/ppc/platforms/4xx/ep405.c
+++ b/arch/ppc/platforms/4xx/ep405.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ep405.c
- *
* Embedded Planet 405GP board
* http://www.embeddedplanet.com
*
diff --git a/arch/ppc/platforms/4xx/ep405.h b/arch/ppc/platforms/4xx/ep405.h
index ea3eb21338fb..9814fc431725 100644
--- a/arch/ppc/platforms/4xx/ep405.h
+++ b/arch/ppc/platforms/4xx/ep405.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ep405.h
- *
* Embedded Planet 405GP board
* http://www.embeddedplanet.com
*
diff --git a/arch/ppc/platforms/4xx/ibm405ep.c b/arch/ppc/platforms/4xx/ibm405ep.c
index 093b28d27a41..55af769a6e70 100644
--- a/arch/ppc/platforms/4xx/ibm405ep.c
+++ b/arch/ppc/platforms/4xx/ibm405ep.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/ibm405ep.c
- *
* Support for IBM PPC 405EP processors.
*
* Author: SAW (IBM), derived from ibmnp405l.c.
diff --git a/arch/ppc/platforms/4xx/ibm405ep.h b/arch/ppc/platforms/4xx/ibm405ep.h
index e051e3fe8c63..fe46640de152 100644
--- a/arch/ppc/platforms/4xx/ibm405ep.h
+++ b/arch/ppc/platforms/4xx/ibm405ep.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ibm405ep.h
- *
* IBM PPC 405EP processor defines.
*
* Author: SAW (IBM), derived from ibm405gp.h.
diff --git a/arch/ppc/platforms/4xx/ibm405gp.h b/arch/ppc/platforms/4xx/ibm405gp.h
index b2b642e81af7..eaf0ef57028d 100644
--- a/arch/ppc/platforms/4xx/ibm405gp.h
+++ b/arch/ppc/platforms/4xx/ibm405gp.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ibm405gp.h
- *
* Author: Armin Kuster akuster@mvista.com
*
* 2001 (c) MontaVista, Software, Inc. This file is licensed under
diff --git a/arch/ppc/platforms/4xx/ibm405gpr.c b/arch/ppc/platforms/4xx/ibm405gpr.c
index cd0d00d8e8ee..49da61f6854a 100644
--- a/arch/ppc/platforms/4xx/ibm405gpr.c
+++ b/arch/ppc/platforms/4xx/ibm405gpr.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ibm405gpr.c
- *
* Author: Armin Kuster <akuster@mvista.com>
*
* 2002 (c) MontaVista, Software, Inc. This file is licensed under
diff --git a/arch/ppc/platforms/4xx/ibm405gpr.h b/arch/ppc/platforms/4xx/ibm405gpr.h
index 45412fb4368f..e90c5dde01d3 100644
--- a/arch/ppc/platforms/4xx/ibm405gpr.h
+++ b/arch/ppc/platforms/4xx/ibm405gpr.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ibm405gpr.h
- *
* Author: Armin Kuster <akuster@mvista.com>
*
* 2002 (c) MontaVista, Software, Inc. This file is licensed under
diff --git a/arch/ppc/platforms/4xx/ibm440ep.c b/arch/ppc/platforms/4xx/ibm440ep.c
index 65ac0b9c2d05..1fed6638c81f 100644
--- a/arch/ppc/platforms/4xx/ibm440ep.c
+++ b/arch/ppc/platforms/4xx/ibm440ep.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ibm440ep.c
- *
* PPC440EP I/O descriptions
*
* Wade Farnsworth <wfarnsworth@mvista.com>
diff --git a/arch/ppc/platforms/4xx/ibm440ep.h b/arch/ppc/platforms/4xx/ibm440ep.h
index 97c80b8e3e10..61717e8a799e 100644
--- a/arch/ppc/platforms/4xx/ibm440ep.h
+++ b/arch/ppc/platforms/4xx/ibm440ep.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ibm440ep.h
- *
* PPC440EP definitions
*
* Wade Farnsworth <wfarnsworth@mvista.com>
diff --git a/arch/ppc/platforms/4xx/ibm440gp.c b/arch/ppc/platforms/4xx/ibm440gp.c
index d926245e8b3e..b67a72e5c6fe 100644
--- a/arch/ppc/platforms/4xx/ibm440gp.c
+++ b/arch/ppc/platforms/4xx/ibm440gp.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ibm440gp.c
- *
* PPC440GP I/O descriptions
*
* Matt Porter <mporter@mvista.com>
diff --git a/arch/ppc/platforms/4xx/ibm440gp.h b/arch/ppc/platforms/4xx/ibm440gp.h
index ae1efc03b295..7b2763b6024f 100644
--- a/arch/ppc/platforms/4xx/ibm440gp.h
+++ b/arch/ppc/platforms/4xx/ibm440gp.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ibm440gp.h
- *
* PPC440GP definitions
*
* Roland Dreier <roland@digitalvampire.org>
diff --git a/arch/ppc/platforms/4xx/ibm440gx.c b/arch/ppc/platforms/4xx/ibm440gx.c
index d24c09ee7b18..685abffcb6ce 100644
--- a/arch/ppc/platforms/4xx/ibm440gx.c
+++ b/arch/ppc/platforms/4xx/ibm440gx.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ibm440gx.c
- *
* PPC440GX I/O descriptions
*
* Matt Porter <mporter@mvista.com>
diff --git a/arch/ppc/platforms/4xx/ibm440gx.h b/arch/ppc/platforms/4xx/ibm440gx.h
index 0b59d8dcd03c..070a34efe1c7 100644
--- a/arch/ppc/platforms/4xx/ibm440gx.h
+++ b/arch/ppc/platforms/4xx/ibm440gx.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/ibm440gx.h
- *
* PPC440GX definitions
*
* Matt Porter <mporter@mvista.com>
diff --git a/arch/ppc/platforms/4xx/ibm440sp.c b/arch/ppc/platforms/4xx/ibm440sp.c
index 71a0117d3597..de8f7ac5623c 100644
--- a/arch/ppc/platforms/4xx/ibm440sp.c
+++ b/arch/ppc/platforms/4xx/ibm440sp.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ibm440sp.c
- *
* PPC440SP I/O descriptions
*
* Matt Porter <mporter@kernel.crashing.org>
diff --git a/arch/ppc/platforms/4xx/ibm440sp.h b/arch/ppc/platforms/4xx/ibm440sp.h
index c71e46a18b9e..77e8bb22c527 100644
--- a/arch/ppc/platforms/4xx/ibm440sp.h
+++ b/arch/ppc/platforms/4xx/ibm440sp.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ibm440sp.h
- *
* PPC440SP definitions
*
* Matt Porter <mporter@kernel.crashing.org>
diff --git a/arch/ppc/platforms/4xx/ibmnp405h.c b/arch/ppc/platforms/4xx/ibmnp405h.c
index a477a78f4902..f1dcb0ac15b7 100644
--- a/arch/ppc/platforms/4xx/ibmnp405h.c
+++ b/arch/ppc/platforms/4xx/ibmnp405h.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ibmnp405h.c
- *
* Author: Armin Kuster <akuster@mvista.com>
*
* 2000-2002 (c) MontaVista, Software, Inc. This file is licensed under
diff --git a/arch/ppc/platforms/4xx/ibmnp405h.h b/arch/ppc/platforms/4xx/ibmnp405h.h
index e2c2b06128c8..2c683f6aaa66 100644
--- a/arch/ppc/platforms/4xx/ibmnp405h.h
+++ b/arch/ppc/platforms/4xx/ibmnp405h.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ibmnp405h.h
- *
* Author: Armin Kuster <akuster@mvista.com>
*
* 2002 (c) MontaVista, Software, Inc. This file is licensed under
diff --git a/arch/ppc/platforms/4xx/ibmstb4.c b/arch/ppc/platforms/4xx/ibmstb4.c
index 7e33bb635443..799a2eccccc3 100644
--- a/arch/ppc/platforms/4xx/ibmstb4.c
+++ b/arch/ppc/platforms/4xx/ibmstb4.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ibmstb4.c
- *
* Author: Armin Kuster <akuster@mvista.com>
*
* 2000-2001 (c) MontaVista, Software, Inc. This file is licensed under
diff --git a/arch/ppc/platforms/4xx/ibmstb4.h b/arch/ppc/platforms/4xx/ibmstb4.h
index 9f21d4c88a3d..9de426597351 100644
--- a/arch/ppc/platforms/4xx/ibmstb4.h
+++ b/arch/ppc/platforms/4xx/ibmstb4.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ibmstb4.h
- *
* Author: Armin Kuster <akuster@mvista.com>
*
* 2001 (c) MontaVista, Software, Inc. This file is licensed under
diff --git a/arch/ppc/platforms/4xx/ibmstbx25.c b/arch/ppc/platforms/4xx/ibmstbx25.c
index b895b9cca57d..090ddcbecc5e 100644
--- a/arch/ppc/platforms/4xx/ibmstbx25.c
+++ b/arch/ppc/platforms/4xx/ibmstbx25.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ibmstbx25.c
- *
* Author: Armin Kuster <akuster@mvista.com>
*
* 2000-2002 (c) MontaVista, Software, Inc. This file is licensed under
diff --git a/arch/ppc/platforms/4xx/ibmstbx25.h b/arch/ppc/platforms/4xx/ibmstbx25.h
index 9a2efc366e9c..6884a49d3482 100644
--- a/arch/ppc/platforms/4xx/ibmstbx25.h
+++ b/arch/ppc/platforms/4xx/ibmstbx25.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ibmstbx25.h
- *
* Author: Armin Kuster <akuster@mvista.com>
*
* 2002 (c) MontaVista, Software, Inc. This file is licensed under
diff --git a/arch/ppc/platforms/4xx/luan.c b/arch/ppc/platforms/4xx/luan.c
index 21d29132aebd..5c37de28e135 100644
--- a/arch/ppc/platforms/4xx/luan.c
+++ b/arch/ppc/platforms/4xx/luan.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/luan.c
- *
* Luan board specific routines
*
* Matt Porter <mporter@kernel.crashing.org>
diff --git a/arch/ppc/platforms/4xx/luan.h b/arch/ppc/platforms/4xx/luan.h
index bbe7d0766db8..e0db6a810feb 100644
--- a/arch/ppc/platforms/4xx/luan.h
+++ b/arch/ppc/platforms/4xx/luan.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/luan.h
- *
* Luan board definitions
*
* Matt Porter <mporter@kernel.crashing.org>
diff --git a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c
index 4f355b6acab2..f841972f1fa9 100644
--- a/arch/ppc/platforms/4xx/ocotea.c
+++ b/arch/ppc/platforms/4xx/ocotea.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ocotea.c
- *
* Ocotea board specific routines
*
* Matt Porter <mporter@kernel.crashing.org>
diff --git a/arch/ppc/platforms/4xx/ocotea.h b/arch/ppc/platforms/4xx/ocotea.h
index 33251153ac5f..7c799a9ff82b 100644
--- a/arch/ppc/platforms/4xx/ocotea.h
+++ b/arch/ppc/platforms/4xx/ocotea.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/ocotea.h
- *
* Ocotea board definitions
*
* Matt Porter <mporter@kernel.crashing.org>
diff --git a/arch/ppc/platforms/4xx/ppc440spe.c b/arch/ppc/platforms/4xx/ppc440spe.c
index 6139a0b3393e..1be5d1c8e266 100644
--- a/arch/ppc/platforms/4xx/ppc440spe.c
+++ b/arch/ppc/platforms/4xx/ppc440spe.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ppc440spe.c
- *
* PPC440SPe I/O descriptions
*
* Roland Dreier <rolandd@cisco.com>
diff --git a/arch/ppc/platforms/4xx/ppc440spe.h b/arch/ppc/platforms/4xx/ppc440spe.h
index 2216846973b8..d3a620ddcdee 100644
--- a/arch/ppc/platforms/4xx/ppc440spe.h
+++ b/arch/ppc/platforms/4xx/ppc440spe.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/ibm440spe.h
- *
* PPC440SPe definitions
*
* Roland Dreier <rolandd@cisco.com>
diff --git a/arch/ppc/platforms/4xx/redwood5.c b/arch/ppc/platforms/4xx/redwood5.c
index 611ac861804d..53da2b4f7c24 100644
--- a/arch/ppc/platforms/4xx/redwood5.c
+++ b/arch/ppc/platforms/4xx/redwood5.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/redwood5.c
- *
* Support for the IBM redwood5 eval board file
*
* Author: Armin Kuster <akuster@mvista.com>
diff --git a/arch/ppc/platforms/4xx/redwood5.h b/arch/ppc/platforms/4xx/redwood5.h
index 264e34fb3fbd..49edd4818970 100644
--- a/arch/ppc/platforms/4xx/redwood5.h
+++ b/arch/ppc/platforms/4xx/redwood5.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/redwood5.h
- *
* Macros, definitions, and data structures specific to the IBM PowerPC
* STB03xxx "Redwood" evaluation board.
*
diff --git a/arch/ppc/platforms/4xx/redwood6.c b/arch/ppc/platforms/4xx/redwood6.c
index b13116691289..41b27d106fa3 100644
--- a/arch/ppc/platforms/4xx/redwood6.c
+++ b/arch/ppc/platforms/4xx/redwood6.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/redwood6.c
- *
* Author: Armin Kuster <akuster@mvista.com>
*
* 2002 (c) MontaVista, Software, Inc. This file is licensed under
diff --git a/arch/ppc/platforms/4xx/redwood6.h b/arch/ppc/platforms/4xx/redwood6.h
index 1814b9f5fc3a..1edcbe5c51c7 100644
--- a/arch/ppc/platforms/4xx/redwood6.h
+++ b/arch/ppc/platforms/4xx/redwood6.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/redwood6.h
- *
* Macros, definitions, and data structures specific to the IBM PowerPC
* STBx25xx "Redwood6" evaluation board.
*
diff --git a/arch/ppc/platforms/4xx/sycamore.c b/arch/ppc/platforms/4xx/sycamore.c
index 281b4a2ffb96..bab31eb30687 100644
--- a/arch/ppc/platforms/4xx/sycamore.c
+++ b/arch/ppc/platforms/4xx/sycamore.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/sycamore.c
- *
* Architecture- / platform-specific boot-time initialization code for
* IBM PowerPC 4xx based boards.
*
diff --git a/arch/ppc/platforms/4xx/sycamore.h b/arch/ppc/platforms/4xx/sycamore.h
index 1cd6c824fd62..dae01620227d 100644
--- a/arch/ppc/platforms/4xx/sycamore.h
+++ b/arch/ppc/platforms/4xx/sycamore.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/sycamore.h
- *
* Sycamore board definitions
*
* Copyright (c) 2005 DENX Software Engineering
diff --git a/arch/ppc/platforms/4xx/virtex-ii_pro.c b/arch/ppc/platforms/4xx/virtex-ii_pro.c
deleted file mode 100644
index 097cc9d5aca0..000000000000
--- a/arch/ppc/platforms/4xx/virtex-ii_pro.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * arch/ppc/platforms/4xx/virtex-ii_pro.c
- *
- * Author: MontaVista Software, Inc.
- * source@mvista.com
- *
- * 2002-2004 (c) MontaVista Software, Inc. This file is licensed under the
- * terms of the GNU General Public License version 2. This program is licensed
- * "as is" without any warranty of any kind, whether express or implied.
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <asm/ocp.h>
-#include "virtex-ii_pro.h"
-
-/* Have OCP take care of the serial ports. */
-struct ocp_def core_ocp[] = {
-#ifdef XPAR_UARTNS550_0_BASEADDR
- { .vendor = OCP_VENDOR_XILINX,
- .function = OCP_FUNC_16550,
- .index = 0,
- .paddr = XPAR_UARTNS550_0_BASEADDR,
- .irq = XPAR_INTC_0_UARTNS550_0_VEC_ID,
- .pm = OCP_CPM_NA
- },
-#ifdef XPAR_UARTNS550_1_BASEADDR
- { .vendor = OCP_VENDOR_XILINX,
- .function = OCP_FUNC_16550,
- .index = 1,
- .paddr = XPAR_UARTNS550_1_BASEADDR,
- .irq = XPAR_INTC_0_UARTNS550_1_VEC_ID,
- .pm = OCP_CPM_NA
- },
-#ifdef XPAR_UARTNS550_2_BASEADDR
- { .vendor = OCP_VENDOR_XILINX,
- .function = OCP_FUNC_16550,
- .index = 2,
- .paddr = XPAR_UARTNS550_2_BASEADDR,
- .irq = XPAR_INTC_0_UARTNS550_2_VEC_ID,
- .pm = OCP_CPM_NA
- },
-#ifdef XPAR_UARTNS550_3_BASEADDR
- { .vendor = OCP_VENDOR_XILINX,
- .function = OCP_FUNC_16550,
- .index = 3,
- .paddr = XPAR_UARTNS550_3_BASEADDR,
- .irq = XPAR_INTC_0_UARTNS550_3_VEC_ID,
- .pm = OCP_CPM_NA
- },
-#ifdef XPAR_UARTNS550_4_BASEADDR
-#error Edit this file to add more devices.
-#endif /* 4 */
-#endif /* 3 */
-#endif /* 2 */
-#endif /* 1 */
-#endif /* 0 */
- { .vendor = OCP_VENDOR_INVALID
- }
-};
diff --git a/arch/ppc/platforms/4xx/virtex-ii_pro.h b/arch/ppc/platforms/4xx/virtex-ii_pro.h
deleted file mode 100644
index 9014c4887339..000000000000
--- a/arch/ppc/platforms/4xx/virtex-ii_pro.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * arch/ppc/platforms/4xx/virtex-ii_pro.h
- *
- * Include file that defines the Xilinx Virtex-II Pro processor
- *
- * Author: MontaVista Software, Inc.
- * source@mvista.com
- *
- * 2002-2004 (c) MontaVista Software, Inc. This file is licensed under the
- * terms of the GNU General Public License version 2. This program is licensed
- * "as is" without any warranty of any kind, whether express or implied.
- */
-
-#ifdef __KERNEL__
-#ifndef __ASM_VIRTEXIIPRO_H__
-#define __ASM_VIRTEXIIPRO_H__
-
-#include <linux/config.h>
-#include <asm/xparameters.h>
-
-/* serial defines */
-
-#define RS_TABLE_SIZE 4 /* change this and add more devices below
- if you have more then 4 16x50 UARTs */
-
-#define BASE_BAUD (XPAR_UARTNS550_0_CLOCK_FREQ_HZ/16)
-
-/* The serial ports in the Virtex-II Pro have each I/O byte in the
- * LSByte of a word. This means that iomem_reg_shift needs to be 2 to
- * change the byte offsets into word offsets. In addition the base
- * addresses need to have 3 added to them to get to the LSByte.
- */
-#define STD_UART_OP(num) \
- { 0, BASE_BAUD, 0, XPAR_INTC_0_UARTNS550_##num##_VEC_ID, \
- ASYNC_BOOT_AUTOCONF, \
- .iomem_base = (u8 *)XPAR_UARTNS550_##num##_BASEADDR + 3, \
- .iomem_reg_shift = 2, \
- .io_type = SERIAL_IO_MEM},
-
-#if defined(XPAR_INTC_0_UARTNS550_0_VEC_ID)
-#define ML300_UART0 STD_UART_OP(0)
-#else
-#define ML300_UART0
-#endif
-
-#if defined(XPAR_INTC_0_UARTNS550_1_VEC_ID)
-#define ML300_UART1 STD_UART_OP(1)
-#else
-#define ML300_UART1
-#endif
-
-#if defined(XPAR_INTC_0_UARTNS550_2_VEC_ID)
-#define ML300_UART2 STD_UART_OP(2)
-#else
-#define ML300_UART2
-#endif
-
-#if defined(XPAR_INTC_0_UARTNS550_3_VEC_ID)
-#define ML300_UART3 STD_UART_OP(3)
-#else
-#define ML300_UART3
-#endif
-
-#if defined(XPAR_INTC_0_UARTNS550_4_VEC_ID)
-#error Edit this file to add more devices.
-#elif defined(XPAR_INTC_0_UARTNS550_3_VEC_ID)
-#define NR_SER_PORTS 4
-#elif defined(XPAR_INTC_0_UARTNS550_2_VEC_ID)
-#define NR_SER_PORTS 3
-#elif defined(XPAR_INTC_0_UARTNS550_1_VEC_ID)
-#define NR_SER_PORTS 2
-#elif defined(XPAR_INTC_0_UARTNS550_0_VEC_ID)
-#define NR_SER_PORTS 1
-#else
-#define NR_SER_PORTS 0
-#endif
-
-#if defined(CONFIG_UART0_TTYS0)
-#define SERIAL_PORT_DFNS \
- ML300_UART0 \
- ML300_UART1 \
- ML300_UART2 \
- ML300_UART3
-#endif
-
-#if defined(CONFIG_UART0_TTYS1)
-#define SERIAL_PORT_DFNS \
- ML300_UART1 \
- ML300_UART0 \
- ML300_UART2 \
- ML300_UART3
-#endif
-
-#define DCRN_CPMFR_BASE 0
-
-#include <asm/ibm405.h>
-
-#endif /* __ASM_VIRTEXIIPRO_H__ */
-#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/virtex.c b/arch/ppc/platforms/4xx/virtex.c
new file mode 100644
index 000000000000..133a83147199
--- /dev/null
+++ b/arch/ppc/platforms/4xx/virtex.c
@@ -0,0 +1,56 @@
+/*
+ * Virtex-II Pro & Virtex-4 FX common infrastructure
+ *
+ * Maintainer: Grant Likely <grant.likely@secretlab.ca>
+ *
+ * Copyright 2005 Secret Lab Technologies Ltd.
+ * Copyright 2005 General Dynamics Canada Ltd.
+ * 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/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/serial_8250.h>
+#include <asm/ppc_sys.h>
+#include <platforms/4xx/virtex.h>
+#include <platforms/4xx/xparameters/xparameters.h>
+
+#define XPAR_UART(num) { \
+ .mapbase = XPAR_UARTNS550_##num##_BASEADDR + 3, \
+ .irq = XPAR_INTC_0_UARTNS550_##num##_VEC_ID, \
+ .iotype = UPIO_MEM, \
+ .uartclk = XPAR_UARTNS550_##num##_CLOCK_FREQ_HZ, \
+ .flags = UPF_BOOT_AUTOCONF, \
+ .regshift = 2, \
+ }
+
+struct plat_serial8250_port serial_platform_data[] = {
+#ifdef XPAR_UARTNS550_0_BASEADDR
+ XPAR_UART(0),
+#endif
+#ifdef XPAR_UARTNS550_1_BASEADDR
+ XPAR_UART(1),
+#endif
+#ifdef XPAR_UARTNS550_2_BASEADDR
+ XPAR_UART(2),
+#endif
+#ifdef XPAR_UARTNS550_3_BASEADDR
+ XPAR_UART(3),
+#endif
+ { }, /* terminated by empty record */
+};
+
+struct platform_device ppc_sys_platform_devices[] = {
+ [VIRTEX_UART] = {
+ .name = "serial8250",
+ .id = 0,
+ .dev.platform_data = serial_platform_data,
+ },
+};
+
diff --git a/arch/ppc/platforms/4xx/virtex.h b/arch/ppc/platforms/4xx/virtex.h
new file mode 100644
index 000000000000..c14325dfd7b1
--- /dev/null
+++ b/arch/ppc/platforms/4xx/virtex.h
@@ -0,0 +1,35 @@
+/*
+ * arch/ppc/platforms/4xx/virtex.h
+ *
+ * Include file that defines the Xilinx Virtex-II Pro processor
+ *
+ * Author: MontaVista Software, Inc.
+ * source@mvista.com
+ *
+ * 2002-2004 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is licensed
+ * "as is" without any warranty of any kind, whether express or implied.
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_VIRTEX_H__
+#define __ASM_VIRTEX_H__
+
+/* serial defines */
+
+#include <asm/ibm405.h>
+
+/* Ugly, ugly, ugly! BASE_BAUD defined here to keep 8250.c happy. */
+#if !defined(BASE_BAUD)
+ #define BASE_BAUD (0) /* dummy value; not used */
+#endif
+
+/* Device type enumeration for platform bus definitions */
+#ifndef __ASSEMBLY__
+enum ppc_sys_devices {
+ VIRTEX_UART, NUM_PPC_SYS_DEVS,
+};
+#endif
+
+#endif /* __ASM_VIRTEX_H__ */
+#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/walnut.c b/arch/ppc/platforms/4xx/walnut.c
index 74cb33182d9f..6bd77902b9a4 100644
--- a/arch/ppc/platforms/4xx/walnut.c
+++ b/arch/ppc/platforms/4xx/walnut.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/walnut.c
- *
* Architecture- / platform-specific boot-time initialization code for
* IBM PowerPC 4xx based boards. Adapted from original
* code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek
diff --git a/arch/ppc/platforms/4xx/walnut.h b/arch/ppc/platforms/4xx/walnut.h
index dcf2691698c0..f13a577f0a41 100644
--- a/arch/ppc/platforms/4xx/walnut.h
+++ b/arch/ppc/platforms/4xx/walnut.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/walnut.h
- *
* Walnut board definitions
*
* Copyright (c) 2005 DENX Software Engineering
diff --git a/arch/ppc/platforms/4xx/xilinx_ml300.c b/arch/ppc/platforms/4xx/xilinx_ml300.c
index e90d97f64f76..d97a7f269f97 100644
--- a/arch/ppc/platforms/4xx/xilinx_ml300.c
+++ b/arch/ppc/platforms/4xx/xilinx_ml300.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/xilinx_ml300.c
- *
* Xilinx ML300 evaluation board initialization
*
* Author: MontaVista Software, Inc.
@@ -17,12 +15,14 @@
#include <linux/tty.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
#include <linux/serialP.h>
#include <asm/io.h>
#include <asm/machdep.h>
-#include <asm/ocp.h>
+#include <asm/ppc_sys.h>
-#include <platforms/4xx/virtex-ii_pro.h> /* for NR_SER_PORTS */
+#include <syslib/gen550.h>
+#include <platforms/4xx/xparameters/xparameters.h>
/*
* As an overview of how the following functions (platform_init,
@@ -54,6 +54,22 @@
* ppc4xx_pic_init arch/ppc/syslib/xilinx_pic.c
*/
+/* Board specifications structures */
+struct ppc_sys_spec *cur_ppc_sys_spec;
+struct ppc_sys_spec ppc_sys_specs[] = {
+ {
+ /* Only one entry, always assume the same design */
+ .ppc_sys_name = "Xilinx ML300 Reference Design",
+ .mask = 0x00000000,
+ .value = 0x00000000,
+ .num_devices = 1,
+ .device_list = (enum ppc_sys_devices[])
+ {
+ VIRTEX_UART,
+ },
+ },
+};
+
#if defined(XPAR_POWER_0_POWERDOWN_BASEADDR)
static volatile unsigned *powerdown_base =
@@ -80,28 +96,39 @@ ml300_map_io(void)
#endif
}
+/* Early serial support functions */
static void __init
+ml300_early_serial_init(int num, struct plat_serial8250_port *pdata)
+{
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+ struct uart_port serial_req;
+
+ memset(&serial_req, 0, sizeof(serial_req));
+ serial_req.mapbase = pdata->mapbase;
+ serial_req.membase = pdata->membase;
+ serial_req.irq = pdata->irq;
+ serial_req.uartclk = pdata->uartclk;
+ serial_req.regshift = pdata->regshift;
+ serial_req.iotype = pdata->iotype;
+ serial_req.flags = pdata->flags;
+ gen550_init(num, &serial_req);
+#endif
+}
+
+void __init
ml300_early_serial_map(void)
{
#ifdef CONFIG_SERIAL_8250
- struct serial_state old_ports[] = { SERIAL_PORT_DFNS };
- struct uart_port port;
- int i;
-
- /* Setup ioremapped serial port access */
- for (i = 0; i < ARRAY_SIZE(old_ports); i++ ) {
- memset(&port, 0, sizeof(port));
- port.membase = ioremap((phys_addr_t)(old_ports[i].iomem_base), 16);
- port.irq = old_ports[i].irq;
- port.uartclk = old_ports[i].baud_base * 16;
- port.regshift = old_ports[i].iomem_reg_shift;
- port.iotype = UPIO_MEM;
- port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
- port.line = i;
-
- if (early_serial_setup(&port) != 0) {
- printk("Early serial init of port %d failed\n", i);
- }
+ struct plat_serial8250_port *pdata;
+ int i = 0;
+
+ pdata = (struct plat_serial8250_port *) ppc_sys_get_pdata(VIRTEX_UART);
+ while(pdata && pdata->flags)
+ {
+ pdata->membase = ioremap(pdata->mapbase, 0x100);
+ ml300_early_serial_init(i, pdata);
+ pdata++;
+ i++;
}
#endif /* CONFIG_SERIAL_8250 */
}
@@ -109,9 +136,8 @@ ml300_early_serial_map(void)
void __init
ml300_setup_arch(void)
{
- ppc4xx_setup_arch(); /* calls ppc4xx_find_bridges() */
-
ml300_early_serial_map();
+ ppc4xx_setup_arch(); /* calls ppc4xx_find_bridges() */
/* Identify the system */
printk(KERN_INFO "Xilinx Virtex-II Pro port\n");
@@ -131,6 +157,8 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
{
ppc4xx_init(r3, r4, r5, r6, r7);
+ identify_ppc_sys_by_id(mfspr(SPRN_PVR));
+
ppc_md.setup_arch = ml300_setup_arch;
ppc_md.setup_io_mappings = ml300_map_io;
ppc_md.init_IRQ = ml300_init_irq;
diff --git a/arch/ppc/platforms/4xx/xilinx_ml300.h b/arch/ppc/platforms/4xx/xilinx_ml300.h
index f8c588412336..3d57332ba820 100644
--- a/arch/ppc/platforms/4xx/xilinx_ml300.h
+++ b/arch/ppc/platforms/4xx/xilinx_ml300.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/xilinx_ml300.h
- *
* Include file that defines the Xilinx ML300 evaluation board
*
* Author: MontaVista Software, Inc.
@@ -16,7 +14,7 @@
#define __ASM_XILINX_ML300_H__
/* ML300 has a Xilinx Virtex-II Pro processor */
-#include <platforms/4xx/virtex-ii_pro.h>
+#include <platforms/4xx/virtex.h>
#ifndef __ASSEMBLY__
@@ -41,7 +39,7 @@ typedef struct board_info {
#define PPC4xx_ONB_IO_VADDR 0u
#define PPC4xx_ONB_IO_SIZE 0u
-#define PPC4xx_MACHINE_NAME "Xilinx ML300"
+#define PPC4xx_MACHINE_NAME "Xilinx ML300 Reference System"
#endif /* __ASM_XILINX_ML300_H__ */
#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/xilinx_ml403.c b/arch/ppc/platforms/4xx/xilinx_ml403.c
new file mode 100644
index 000000000000..4c0c7e4c1114
--- /dev/null
+++ b/arch/ppc/platforms/4xx/xilinx_ml403.c
@@ -0,0 +1,177 @@
+/*
+ * arch/ppc/platforms/4xx/xilinx_ml403.c
+ *
+ * Xilinx ML403 evaluation board initialization
+ *
+ * Author: Grant Likely <grant.likely@secretlab.ca>
+ *
+ * 2005 (c) Secret Lab Technologies Ltd.
+ * 2002-2004 (c) MontaVista Software, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/serialP.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/ppc_sys.h>
+
+#include <syslib/gen550.h>
+#include <platforms/4xx/xparameters/xparameters.h>
+
+/*
+ * As an overview of how the following functions (platform_init,
+ * ml403_map_io, ml403_setup_arch and ml403_init_IRQ) fit into the
+ * kernel startup procedure, here's a call tree:
+ *
+ * start_here arch/ppc/kernel/head_4xx.S
+ * early_init arch/ppc/kernel/setup.c
+ * machine_init arch/ppc/kernel/setup.c
+ * platform_init this file
+ * ppc4xx_init arch/ppc/syslib/ppc4xx_setup.c
+ * parse_bootinfo
+ * find_bootinfo
+ * "setup some default ppc_md pointers"
+ * MMU_init arch/ppc/mm/init.c
+ * *ppc_md.setup_io_mappings == ml403_map_io this file
+ * ppc4xx_map_io arch/ppc/syslib/ppc4xx_setup.c
+ * start_kernel init/main.c
+ * setup_arch arch/ppc/kernel/setup.c
+ * #if defined(CONFIG_KGDB)
+ * *ppc_md.kgdb_map_scc() == gen550_kgdb_map_scc
+ * #endif
+ * *ppc_md.setup_arch == ml403_setup_arch this file
+ * ppc4xx_setup_arch arch/ppc/syslib/ppc4xx_setup.c
+ * ppc4xx_find_bridges arch/ppc/syslib/ppc405_pci.c
+ * init_IRQ arch/ppc/kernel/irq.c
+ * *ppc_md.init_IRQ == ml403_init_IRQ this file
+ * ppc4xx_init_IRQ arch/ppc/syslib/ppc4xx_setup.c
+ * ppc4xx_pic_init arch/ppc/syslib/xilinx_pic.c
+ */
+
+/* Board specifications structures */
+struct ppc_sys_spec *cur_ppc_sys_spec;
+struct ppc_sys_spec ppc_sys_specs[] = {
+ {
+ /* Only one entry, always assume the same design */
+ .ppc_sys_name = "Xilinx ML403 Reference Design",
+ .mask = 0x00000000,
+ .value = 0x00000000,
+ .num_devices = 1,
+ .device_list = (enum ppc_sys_devices[])
+ {
+ VIRTEX_UART,
+ },
+ },
+};
+
+#if defined(XPAR_POWER_0_POWERDOWN_BASEADDR)
+
+static volatile unsigned *powerdown_base =
+ (volatile unsigned *) XPAR_POWER_0_POWERDOWN_BASEADDR;
+
+static void
+xilinx_power_off(void)
+{
+ local_irq_disable();
+ out_be32(powerdown_base, XPAR_POWER_0_POWERDOWN_VALUE);
+ while (1) ;
+}
+#endif
+
+void __init
+ml403_map_io(void)
+{
+ ppc4xx_map_io();
+
+#if defined(XPAR_POWER_0_POWERDOWN_BASEADDR)
+ powerdown_base = ioremap((unsigned long) powerdown_base,
+ XPAR_POWER_0_POWERDOWN_HIGHADDR -
+ XPAR_POWER_0_POWERDOWN_BASEADDR + 1);
+#endif
+}
+
+/* Early serial support functions */
+static void __init
+ml403_early_serial_init(int num, struct plat_serial8250_port *pdata)
+{
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+ struct uart_port serial_req;
+
+ memset(&serial_req, 0, sizeof(serial_req));
+ serial_req.mapbase = pdata->mapbase;
+ serial_req.membase = pdata->membase;
+ serial_req.irq = pdata->irq;
+ serial_req.uartclk = pdata->uartclk;
+ serial_req.regshift = pdata->regshift;
+ serial_req.iotype = pdata->iotype;
+ serial_req.flags = pdata->flags;
+ gen550_init(num, &serial_req);
+#endif
+}
+
+void __init
+ml403_early_serial_map(void)
+{
+#ifdef CONFIG_SERIAL_8250
+ struct plat_serial8250_port *pdata;
+ int i = 0;
+
+ pdata = (struct plat_serial8250_port *) ppc_sys_get_pdata(VIRTEX_UART);
+ while(pdata && pdata->flags)
+ {
+ pdata->membase = ioremap(pdata->mapbase, 0x100);
+ ml403_early_serial_init(i, pdata);
+ pdata++;
+ i++;
+ }
+#endif /* CONFIG_SERIAL_8250 */
+}
+
+void __init
+ml403_setup_arch(void)
+{
+ ml403_early_serial_map();
+ ppc4xx_setup_arch(); /* calls ppc4xx_find_bridges() */
+
+ /* Identify the system */
+ printk(KERN_INFO "Xilinx ML403 Reference System (Virtex-4 FX)\n");
+}
+
+/* Called after board_setup_irq from ppc4xx_init_IRQ(). */
+void __init
+ml403_init_irq(void)
+{
+ ppc4xx_init_IRQ();
+}
+
+void __init
+platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7)
+{
+ ppc4xx_init(r3, r4, r5, r6, r7);
+
+ identify_ppc_sys_by_id(mfspr(SPRN_PVR));
+
+ ppc_md.setup_arch = ml403_setup_arch;
+ ppc_md.setup_io_mappings = ml403_map_io;
+ ppc_md.init_IRQ = ml403_init_irq;
+
+#if defined(XPAR_POWER_0_POWERDOWN_BASEADDR)
+ ppc_md.power_off = xilinx_power_off;
+#endif
+
+#ifdef CONFIG_KGDB
+ ppc_md.early_serial_map = ml403_early_serial_map;
+#endif
+}
+
diff --git a/arch/ppc/platforms/4xx/xilinx_ml403.h b/arch/ppc/platforms/4xx/xilinx_ml403.h
new file mode 100644
index 000000000000..473596959902
--- /dev/null
+++ b/arch/ppc/platforms/4xx/xilinx_ml403.h
@@ -0,0 +1,49 @@
+/*
+ * arch/ppc/platforms/4xx/xilinx_ml403.h
+ *
+ * Include file that defines the Xilinx ML403 reference design
+ *
+ * Author: Grant Likely <grant.likely@secretlab.ca>
+ *
+ * 2005 (c) Secret Lab Technologies Ltd.
+ * 2002-2004 (c) MontaVista Software, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_XILINX_ML403_H__
+#define __ASM_XILINX_ML403_H__
+
+/* ML403 has a Xilinx Virtex-4 FPGA with a PPC405 hard core */
+#include <platforms/4xx/virtex.h>
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
+typedef struct board_info {
+ unsigned int bi_memsize; /* DRAM installed, in bytes */
+ unsigned char bi_enetaddr[6]; /* Local Ethernet MAC address */
+ unsigned int bi_intfreq; /* Processor speed, in Hz */
+ unsigned int bi_busfreq; /* PLB Bus speed, in Hz */
+ unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */
+} bd_t;
+
+/* Some 4xx parts use a different timebase frequency from the internal clock.
+*/
+#define bi_tbfreq bi_intfreq
+
+#endif /* !__ASSEMBLY__ */
+
+/* We don't need anything mapped. Size of zero will accomplish that. */
+#define PPC4xx_ONB_IO_PADDR 0u
+#define PPC4xx_ONB_IO_VADDR 0u
+#define PPC4xx_ONB_IO_SIZE 0u
+
+#define PPC4xx_MACHINE_NAME "Xilinx ML403 Reference Design"
+
+#endif /* __ASM_XILINX_ML403_H__ */
+#endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/xparameters/xparameters.h b/arch/ppc/platforms/4xx/xparameters/xparameters.h
new file mode 100644
index 000000000000..4cf21f256356
--- /dev/null
+++ b/arch/ppc/platforms/4xx/xparameters/xparameters.h
@@ -0,0 +1,37 @@
+/*
+ * include/asm-ppc/xparameters.h
+ *
+ * This file includes the correct xparameters.h for the CONFIG'ed board plus
+ * fixups to translate board specific XPAR values to a common set of names
+ *
+ * Author: MontaVista Software, Inc.
+ * source@mvista.com
+ *
+ * 2004 (c) MontaVista Software, Inc. This file is licensed under the terms
+ * of the GNU General Public License version 2. This program is licensed
+ * "as is" without any warranty of any kind, whether express or implied.
+ */
+
+#include <linux/config.h>
+
+#if defined(CONFIG_XILINX_ML300)
+ #include "xparameters_ml300.h"
+#elif defined(CONFIG_XILINX_ML403)
+ #include "xparameters_ml403.h"
+#else
+ /* Add other board xparameter includes here before the #else */
+ #error No xparameters_*.h file included
+#endif
+
+#ifndef SERIAL_PORT_DFNS
+ /* zImage serial port definitions */
+ #define RS_TABLE_SIZE 1
+ #define SERIAL_PORT_DFNS { \
+ .baud_base = XPAR_UARTNS550_0_CLOCK_FREQ_HZ/16, \
+ .irq = XPAR_INTC_0_UARTNS550_0_VEC_ID, \
+ .flags = ASYNC_BOOT_AUTOCONF, \
+ .iomem_base = (u8 *)XPAR_UARTNS550_0_BASEADDR + 3, \
+ .iomem_reg_shift = 2, \
+ .io_type = SERIAL_IO_MEM, \
+ },
+#endif
diff --git a/arch/ppc/platforms/4xx/xparameters/xparameters_ml403.h b/arch/ppc/platforms/4xx/xparameters/xparameters_ml403.h
new file mode 100644
index 000000000000..5cacdcb3964d
--- /dev/null
+++ b/arch/ppc/platforms/4xx/xparameters/xparameters_ml403.h
@@ -0,0 +1,243 @@
+
+/*******************************************************************
+*
+* CAUTION: This file is automatically generated by libgen.
+* Version: Xilinx EDK 7.1.2 EDK_H.12.5.1
+* DO NOT EDIT.
+*
+* Copyright (c) 2005 Xilinx, Inc. All rights reserved.
+*
+* Description: Driver parameters
+*
+*******************************************************************/
+
+#define XPAR_PLB_BRAM_IF_CNTLR_0_BASEADDR 0xFFFF0000
+#define XPAR_PLB_BRAM_IF_CNTLR_0_HIGHADDR 0xFFFFFFFF
+
+/******************************************************************/
+
+#define XPAR_OPB_EMC_0_MEM0_BASEADDR 0x20000000
+#define XPAR_OPB_EMC_0_MEM0_HIGHADDR 0x200FFFFF
+#define XPAR_OPB_EMC_0_MEM1_BASEADDR 0x28000000
+#define XPAR_OPB_EMC_0_MEM1_HIGHADDR 0x287FFFFF
+#define XPAR_OPB_AC97_CONTROLLER_REF_0_BASEADDR 0xA6000000
+#define XPAR_OPB_AC97_CONTROLLER_REF_0_HIGHADDR 0xA60000FF
+#define XPAR_OPB_EMC_USB_0_MEM0_BASEADDR 0xA5000000
+#define XPAR_OPB_EMC_USB_0_MEM0_HIGHADDR 0xA50000FF
+#define XPAR_PLB_DDR_0_MEM0_BASEADDR 0x00000000
+#define XPAR_PLB_DDR_0_MEM0_HIGHADDR 0x0FFFFFFF
+
+/******************************************************************/
+
+#define XPAR_XEMAC_NUM_INSTANCES 1
+#define XPAR_OPB_ETHERNET_0_BASEADDR 0x60000000
+#define XPAR_OPB_ETHERNET_0_HIGHADDR 0x60003FFF
+#define XPAR_OPB_ETHERNET_0_DEVICE_ID 0
+#define XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST 1
+#define XPAR_OPB_ETHERNET_0_DMA_PRESENT 1
+#define XPAR_OPB_ETHERNET_0_MII_EXIST 1
+
+/******************************************************************/
+
+#define XPAR_XUARTNS550_NUM_INSTANCES 1
+#define XPAR_XUARTNS550_CLOCK_HZ 100000000
+#define XPAR_OPB_UART16550_0_BASEADDR 0xA0000000
+#define XPAR_OPB_UART16550_0_HIGHADDR 0xA0001FFF
+#define XPAR_OPB_UART16550_0_DEVICE_ID 0
+
+/******************************************************************/
+
+#define XPAR_XGPIO_NUM_INSTANCES 3
+#define XPAR_OPB_GPIO_0_BASEADDR 0x90000000
+#define XPAR_OPB_GPIO_0_HIGHADDR 0x900001FF
+#define XPAR_OPB_GPIO_0_DEVICE_ID 0
+#define XPAR_OPB_GPIO_0_INTERRUPT_PRESENT 0
+#define XPAR_OPB_GPIO_0_IS_DUAL 1
+#define XPAR_OPB_GPIO_EXP_HDR_0_BASEADDR 0x90001000
+#define XPAR_OPB_GPIO_EXP_HDR_0_HIGHADDR 0x900011FF
+#define XPAR_OPB_GPIO_EXP_HDR_0_DEVICE_ID 1
+#define XPAR_OPB_GPIO_EXP_HDR_0_INTERRUPT_PRESENT 0
+#define XPAR_OPB_GPIO_EXP_HDR_0_IS_DUAL 1
+#define XPAR_OPB_GPIO_CHAR_LCD_0_BASEADDR 0x90002000
+#define XPAR_OPB_GPIO_CHAR_LCD_0_HIGHADDR 0x900021FF
+#define XPAR_OPB_GPIO_CHAR_LCD_0_DEVICE_ID 2
+#define XPAR_OPB_GPIO_CHAR_LCD_0_INTERRUPT_PRESENT 0
+#define XPAR_OPB_GPIO_CHAR_LCD_0_IS_DUAL 0
+
+/******************************************************************/
+
+#define XPAR_XPS2_NUM_INSTANCES 2
+#define XPAR_OPB_PS2_DUAL_REF_0_DEVICE_ID_0 0
+#define XPAR_OPB_PS2_DUAL_REF_0_BASEADDR_0 0xA9000000
+#define XPAR_OPB_PS2_DUAL_REF_0_HIGHADDR_0 (0xA9000000+0x3F)
+#define XPAR_OPB_PS2_DUAL_REF_0_DEVICE_ID_1 1
+#define XPAR_OPB_PS2_DUAL_REF_0_BASEADDR_1 (0xA9000000+0x1000)
+#define XPAR_OPB_PS2_DUAL_REF_0_HIGHADDR_1 (0xA9000000+0x103F)
+
+/******************************************************************/
+
+#define XPAR_XIIC_NUM_INSTANCES 1
+#define XPAR_OPB_IIC_0_BASEADDR 0xA8000000
+#define XPAR_OPB_IIC_0_HIGHADDR 0xA80001FF
+#define XPAR_OPB_IIC_0_DEVICE_ID 0
+#define XPAR_OPB_IIC_0_TEN_BIT_ADR 0
+#define XPAR_OPB_IIC_0_GPO_WIDTH 1
+
+/******************************************************************/
+
+#define XPAR_INTC_MAX_NUM_INTR_INPUTS 10
+#define XPAR_XINTC_HAS_IPR 1
+#define XPAR_XINTC_USE_DCR 0
+#define XPAR_XINTC_NUM_INSTANCES 1
+#define XPAR_OPB_INTC_0_BASEADDR 0xD1000FC0
+#define XPAR_OPB_INTC_0_HIGHADDR 0xD1000FDF
+#define XPAR_OPB_INTC_0_DEVICE_ID 0
+#define XPAR_OPB_INTC_0_KIND_OF_INTR 0x00000000
+
+/******************************************************************/
+
+#define XPAR_INTC_SINGLE_BASEADDR 0xD1000FC0
+#define XPAR_INTC_SINGLE_HIGHADDR 0xD1000FDF
+#define XPAR_INTC_SINGLE_DEVICE_ID XPAR_OPB_INTC_0_DEVICE_ID
+#define XPAR_OPB_ETHERNET_0_IP2INTC_IRPT_MASK 0X000001
+#define XPAR_OPB_INTC_0_OPB_ETHERNET_0_IP2INTC_IRPT_INTR 0
+#define XPAR_SYSTEM_USB_HPI_INT_MASK 0X000002
+#define XPAR_OPB_INTC_0_SYSTEM_USB_HPI_INT_INTR 1
+#define XPAR_MISC_LOGIC_0_PHY_MII_INT_MASK 0X000004
+#define XPAR_OPB_INTC_0_MISC_LOGIC_0_PHY_MII_INT_INTR 2
+#define XPAR_OPB_SYSACE_0_SYSACE_IRQ_MASK 0X000008
+#define XPAR_OPB_INTC_0_OPB_SYSACE_0_SYSACE_IRQ_INTR 3
+#define XPAR_OPB_AC97_CONTROLLER_REF_0_RECORD_INTERRUPT_MASK 0X000010
+#define XPAR_OPB_INTC_0_OPB_AC97_CONTROLLER_REF_0_RECORD_INTERRUPT_INTR 4
+#define XPAR_OPB_AC97_CONTROLLER_REF_0_PLAYBACK_INTERRUPT_MASK 0X000020
+#define XPAR_OPB_INTC_0_OPB_AC97_CONTROLLER_REF_0_PLAYBACK_INTERRUPT_INTR 5
+#define XPAR_OPB_IIC_0_IP2INTC_IRPT_MASK 0X000040
+#define XPAR_OPB_INTC_0_OPB_IIC_0_IP2INTC_IRPT_INTR 6
+#define XPAR_OPB_PS2_DUAL_REF_0_SYS_INTR2_MASK 0X000080
+#define XPAR_OPB_INTC_0_OPB_PS2_DUAL_REF_0_SYS_INTR2_INTR 7
+#define XPAR_OPB_PS2_DUAL_REF_0_SYS_INTR1_MASK 0X000100
+#define XPAR_OPB_INTC_0_OPB_PS2_DUAL_REF_0_SYS_INTR1_INTR 8
+#define XPAR_OPB_UART16550_0_IP2INTC_IRPT_MASK 0X000200
+#define XPAR_OPB_INTC_0_OPB_UART16550_0_IP2INTC_IRPT_INTR 9
+
+/******************************************************************/
+
+#define XPAR_XTFT_NUM_INSTANCES 1
+#define XPAR_PLB_TFT_CNTLR_REF_0_DCR_BASEADDR 0xD0000200
+#define XPAR_PLB_TFT_CNTLR_REF_0_DCR_HIGHADDR 0xD0000207
+#define XPAR_PLB_TFT_CNTLR_REF_0_DEVICE_ID 0
+
+/******************************************************************/
+
+#define XPAR_XSYSACE_MEM_WIDTH 16
+#define XPAR_XSYSACE_NUM_INSTANCES 1
+#define XPAR_OPB_SYSACE_0_BASEADDR 0xCF000000
+#define XPAR_OPB_SYSACE_0_HIGHADDR 0xCF0001FF
+#define XPAR_OPB_SYSACE_0_DEVICE_ID 0
+#define XPAR_OPB_SYSACE_0_MEM_WIDTH 16
+
+/******************************************************************/
+
+#define XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ 300000000
+
+/******************************************************************/
+
+
+/******************************************************************/
+
+/* Linux Redefines */
+
+/******************************************************************/
+
+#define XPAR_UARTNS550_0_BASEADDR (XPAR_OPB_UART16550_0_BASEADDR+0x1000)
+#define XPAR_UARTNS550_0_HIGHADDR XPAR_OPB_UART16550_0_HIGHADDR
+#define XPAR_UARTNS550_0_CLOCK_FREQ_HZ XPAR_XUARTNS550_CLOCK_HZ
+#define XPAR_UARTNS550_0_DEVICE_ID XPAR_OPB_UART16550_0_DEVICE_ID
+
+/******************************************************************/
+
+#define XPAR_INTC_0_BASEADDR XPAR_OPB_INTC_0_BASEADDR
+#define XPAR_INTC_0_HIGHADDR XPAR_OPB_INTC_0_HIGHADDR
+#define XPAR_INTC_0_KIND_OF_INTR XPAR_OPB_INTC_0_KIND_OF_INTR
+#define XPAR_INTC_0_DEVICE_ID XPAR_OPB_INTC_0_DEVICE_ID
+
+/******************************************************************/
+
+#define XPAR_INTC_0_EMAC_0_VEC_ID XPAR_OPB_INTC_0_OPB_ETHERNET_0_IP2INTC_IRPT_INTR
+#define XPAR_INTC_0_SYSACE_0_VEC_ID XPAR_OPB_INTC_0_OPB_SYSACE_0_SYSACE_IRQ_INTR
+#define XPAR_INTC_0_IIC_0_VEC_ID XPAR_OPB_INTC_0_OPB_IIC_0_IP2INTC_IRPT_INTR
+#define XPAR_INTC_0_PS2_1_VEC_ID XPAR_OPB_INTC_0_OPB_PS2_DUAL_REF_0_SYS_INTR2_INTR
+#define XPAR_INTC_0_PS2_0_VEC_ID XPAR_OPB_INTC_0_OPB_PS2_DUAL_REF_0_SYS_INTR1_INTR
+#define XPAR_INTC_0_UARTNS550_0_VEC_ID XPAR_OPB_INTC_0_OPB_UART16550_0_IP2INTC_IRPT_INTR
+
+/******************************************************************/
+
+#define XPAR_TFT_0_BASEADDR XPAR_PLB_TFT_CNTLR_REF_0_DCR_BASEADDR
+
+/******************************************************************/
+
+#define XPAR_EMAC_0_BASEADDR XPAR_OPB_ETHERNET_0_BASEADDR
+#define XPAR_EMAC_0_HIGHADDR XPAR_OPB_ETHERNET_0_HIGHADDR
+#define XPAR_EMAC_0_DMA_PRESENT XPAR_OPB_ETHERNET_0_DMA_PRESENT
+#define XPAR_EMAC_0_MII_EXIST XPAR_OPB_ETHERNET_0_MII_EXIST
+#define XPAR_EMAC_0_ERR_COUNT_EXIST XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST
+#define XPAR_EMAC_0_DEVICE_ID XPAR_OPB_ETHERNET_0_DEVICE_ID
+
+/******************************************************************/
+
+#define XPAR_GPIO_0_BASEADDR XPAR_OPB_GPIO_0_BASEADDR_0
+#define XPAR_GPIO_0_HIGHADDR XPAR_OPB_GPIO_0_HIGHADDR_0
+#define XPAR_GPIO_0_DEVICE_ID XPAR_OPB_GPIO_0_DEVICE_ID_0
+#define XPAR_GPIO_1_BASEADDR XPAR_OPB_GPIO_0_BASEADDR_1
+#define XPAR_GPIO_1_HIGHADDR XPAR_OPB_GPIO_0_HIGHADDR_1
+#define XPAR_GPIO_1_DEVICE_ID XPAR_OPB_GPIO_0_DEVICE_ID_1
+#define XPAR_GPIO_2_BASEADDR XPAR_OPB_GPIO_EXP_HDR_0_BASEADDR_0
+#define XPAR_GPIO_2_HIGHADDR XPAR_OPB_GPIO_EXP_HDR_0_HIGHADDR_0
+#define XPAR_GPIO_2_DEVICE_ID XPAR_OPB_GPIO_EXP_HDR_0_DEVICE_ID_0
+#define XPAR_GPIO_3_BASEADDR XPAR_OPB_GPIO_EXP_HDR_0_BASEADDR_1
+#define XPAR_GPIO_3_HIGHADDR XPAR_OPB_GPIO_EXP_HDR_0_HIGHADDR_1
+#define XPAR_GPIO_3_DEVICE_ID XPAR_OPB_GPIO_EXP_HDR_0_DEVICE_ID_1
+#define XPAR_GPIO_4_BASEADDR XPAR_OPB_GPIO_CHAR_LCD_0_BASEADDR
+#define XPAR_GPIO_4_HIGHADDR XPAR_OPB_GPIO_CHAR_LCD_0_HIGHADDR
+#define XPAR_GPIO_4_DEVICE_ID XPAR_OPB_GPIO_CHAR_LCD_0_DEVICE_ID
+
+/******************************************************************/
+
+#define XPAR_PS2_0_BASEADDR XPAR_OPB_PS2_DUAL_REF_0_BASEADDR_0
+#define XPAR_PS2_0_HIGHADDR XPAR_OPB_PS2_DUAL_REF_0_HIGHADDR_0
+#define XPAR_PS2_0_DEVICE_ID XPAR_OPB_PS2_DUAL_REF_0_DEVICE_ID_0
+#define XPAR_PS2_1_BASEADDR XPAR_OPB_PS2_DUAL_REF_0_BASEADDR_1
+#define XPAR_PS2_1_HIGHADDR XPAR_OPB_PS2_DUAL_REF_0_HIGHADDR_1
+#define XPAR_PS2_1_DEVICE_ID XPAR_OPB_PS2_DUAL_REF_0_DEVICE_ID_1
+
+/******************************************************************/
+
+#define XPAR_SYSACE_0_BASEADDR XPAR_OPB_SYSACE_0_BASEADDR
+#define XPAR_SYSACE_0_HIGHADDR XPAR_OPB_SYSACE_0_HIGHADDR
+#define XPAR_SYSACE_0_DEVICE_ID XPAR_OPB_SYSACE_0_DEVICE_ID
+
+/******************************************************************/
+
+#define XPAR_IIC_0_BASEADDR XPAR_OPB_IIC_0_BASEADDR
+#define XPAR_IIC_0_HIGHADDR XPAR_OPB_IIC_0_HIGHADDR
+#define XPAR_IIC_0_TEN_BIT_ADR XPAR_OPB_IIC_0_TEN_BIT_ADR
+#define XPAR_IIC_0_DEVICE_ID XPAR_OPB_IIC_0_DEVICE_ID
+
+/******************************************************************/
+
+#define XPAR_PLB_CLOCK_FREQ_HZ 100000000
+#define XPAR_CORE_CLOCK_FREQ_HZ XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ
+#define XPAR_DDR_0_SIZE 0x4000000
+
+/******************************************************************/
+
+#define XPAR_PERSISTENT_0_IIC_0_BASEADDR 0x00000400
+#define XPAR_PERSISTENT_0_IIC_0_HIGHADDR 0x000007FF
+#define XPAR_PERSISTENT_0_IIC_0_EEPROMADDR 0xA0
+
+/******************************************************************/
+
+#define XPAR_PCI_0_CLOCK_FREQ_HZ 0
+
+/******************************************************************/
+
diff --git a/arch/ppc/platforms/4xx/yucca.c b/arch/ppc/platforms/4xx/yucca.c
index b065b8babcd3..f287dcdbffce 100644
--- a/arch/ppc/platforms/4xx/yucca.c
+++ b/arch/ppc/platforms/4xx/yucca.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/yucca.c
- *
* Yucca board specific routines
*
* Roland Dreier <rolandd@cisco.com> (based on luan.c by Matt Porter)
diff --git a/arch/ppc/platforms/4xx/yucca.h b/arch/ppc/platforms/4xx/yucca.h
index 01a4afea1514..7ae23012237a 100644
--- a/arch/ppc/platforms/4xx/yucca.h
+++ b/arch/ppc/platforms/4xx/yucca.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/4xx/yucca.h
- *
* Yucca board definitions
*
* Roland Dreier <rolandd@cisco.com> (based on luan.h by Matt Porter)
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c
index 1a659bbc1860..11626dd9090f 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.c
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/83xx/mpc834x_sys.c
- *
* MPC834x SYS board specific routines
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.h b/arch/ppc/platforms/83xx/mpc834x_sys.h
index 2e514d316fb8..6727bbdc36ec 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.h
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/83xx/mpc834x_sys.h
- *
* MPC834X SYS common board definitions
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
@@ -25,7 +23,7 @@
#define VIRT_IMMRBAR ((uint)0xfe000000)
#define BCSR_PHYS_ADDR ((uint)0xf8000000)
-#define BCSR_SIZE ((uint)(128 * 1024))
+#define BCSR_SIZE ((uint)(32 * 1024))
#define BCSR_MISC_REG2_OFF 0x07
#define BCSR_MISC_REG2_PORESET 0x01
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c
index 408d64f18e1a..9b014df516b9 100644
--- a/arch/ppc/platforms/85xx/mpc8540_ads.c
+++ b/arch/ppc/platforms/85xx/mpc8540_ads.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/85xx/mpc8540_ads.c
- *
* MPC8540ADS board specific routines
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.h b/arch/ppc/platforms/85xx/mpc8540_ads.h
index e48ca3a97397..0b5e7ff856f5 100644
--- a/arch/ppc/platforms/85xx/mpc8540_ads.h
+++ b/arch/ppc/platforms/85xx/mpc8540_ads.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/85xx/mpc8540_ads.h
- *
* MPC8540ADS board definitions
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/platforms/85xx/mpc8555_cds.h b/arch/ppc/platforms/85xx/mpc8555_cds.h
index 1a8e6c67355d..9754dbd5d18c 100644
--- a/arch/ppc/platforms/85xx/mpc8555_cds.h
+++ b/arch/ppc/platforms/85xx/mpc8555_cds.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/mpc8555_cds.h
- *
* MPC8555CDS board definitions
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.c b/arch/ppc/platforms/85xx/mpc8560_ads.c
index 442c7ff195d3..0cb2e86470e2 100644
--- a/arch/ppc/platforms/85xx/mpc8560_ads.c
+++ b/arch/ppc/platforms/85xx/mpc8560_ads.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/85xx/mpc8560_ads.c
- *
* MPC8560ADS board specific routines
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.h b/arch/ppc/platforms/85xx/mpc8560_ads.h
index 143ae7eefa7c..c2247c21fc53 100644
--- a/arch/ppc/platforms/85xx/mpc8560_ads.h
+++ b/arch/ppc/platforms/85xx/mpc8560_ads.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/mpc8560_ads.h
- *
* MPC8540ADS board definitions
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
index 17ce48fe3503..8fd9d763f58d 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/85xx/mpc85xx_ads_common.c
- *
* MPC85xx ADS board common routines
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/platforms/85xx/mpc85xx_ads_common.h b/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
index 198a6a02cde8..de8d41aafe11 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
+++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/85xx/mpc85xx_ads_common.h
- *
* MPC85XX ADS common board definitions
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
index 1801ab392e22..c9e0aeeca3d8 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platform/85xx/mpc85xx_cds_common.c
- *
* MPC85xx CDS board specific routines
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.h b/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
index 5b588cfd0e41..62df54f61ae3 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/85xx/mpc85xx_cds_common.h
- *
* MPC85xx CDS board definitions
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c
index 8a72221f816c..b73778ecf827 100644
--- a/arch/ppc/platforms/85xx/sbc8560.c
+++ b/arch/ppc/platforms/85xx/sbc8560.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/85xx/sbc8560.c
- *
* Wind River SBC8560 board specific routines
*
* Maintainer: Kumar Gala
diff --git a/arch/ppc/platforms/85xx/sbc8560.h b/arch/ppc/platforms/85xx/sbc8560.h
index 5e1b00c77da5..44ffaa2d2c87 100644
--- a/arch/ppc/platforms/85xx/sbc8560.h
+++ b/arch/ppc/platforms/85xx/sbc8560.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/85xx/sbc8560.h
- *
* Wind River SBC8560 board definitions
*
* Copyright 2003 Motorola Inc.
diff --git a/arch/ppc/platforms/85xx/sbc85xx.c b/arch/ppc/platforms/85xx/sbc85xx.c
index c02f110219f5..d3ff280510ff 100644
--- a/arch/ppc/platforms/85xx/sbc85xx.c
+++ b/arch/ppc/platforms/85xx/sbc85xx.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platform/85xx/sbc85xx.c
- *
* WindRiver PowerQUICC III SBC85xx board common routines
*
* Copyright 2002, 2003 Motorola Inc.
diff --git a/arch/ppc/platforms/85xx/sbc85xx.h b/arch/ppc/platforms/85xx/sbc85xx.h
index 7af93c691a6b..5dd8b6a98c9b 100644
--- a/arch/ppc/platforms/85xx/sbc85xx.h
+++ b/arch/ppc/platforms/85xx/sbc85xx.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/85xx/sbc85xx.h
- *
* WindRiver PowerQUICC III SBC85xx common board definitions
*
* Copyright 2003 Motorola Inc.
diff --git a/arch/ppc/platforms/85xx/stx_gp3.c b/arch/ppc/platforms/85xx/stx_gp3.c
index 061bb7cf2d9a..8d7baa9a397a 100644
--- a/arch/ppc/platforms/85xx/stx_gp3.c
+++ b/arch/ppc/platforms/85xx/stx_gp3.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/85xx/stx_gp3.c
- *
* STx GP3 board specific routines
*
* Dan Malek <dan@embeddededge.com>
diff --git a/arch/ppc/platforms/85xx/stx_gp3.h b/arch/ppc/platforms/85xx/stx_gp3.h
index 2f25b5195152..3f71f8f59370 100644
--- a/arch/ppc/platforms/85xx/stx_gp3.h
+++ b/arch/ppc/platforms/85xx/stx_gp3.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/stx8560_gp3.h
- *
* STx GP3 board definitions
*
* Dan Malek (dan@embeddededge.com)
diff --git a/arch/ppc/platforms/85xx/tqm85xx.c b/arch/ppc/platforms/85xx/tqm85xx.c
index a5e38ba62732..00af132262b3 100644
--- a/arch/ppc/platforms/85xx/tqm85xx.c
+++ b/arch/ppc/platforms/85xx/tqm85xx.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/85xx/tqm85xx.c
- *
* TQM85xx (40/41/55/60) board specific routines
*
* Copyright (c) 2005 DENX Software Engineering
diff --git a/arch/ppc/platforms/85xx/tqm85xx.h b/arch/ppc/platforms/85xx/tqm85xx.h
index 3775eb363fde..612d80504f9b 100644
--- a/arch/ppc/platforms/85xx/tqm85xx.h
+++ b/arch/ppc/platforms/85xx/tqm85xx.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/85xx/tqm85xx.h
- *
* TQM85xx (40/41/55/60) board definitions
*
* Copyright (c) 2005 DENX Software Engineering
diff --git a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile
index 51430e294b32..e8b91a33ce91 100644
--- a/arch/ppc/platforms/Makefile
+++ b/arch/ppc/platforms/Makefile
@@ -37,6 +37,9 @@ obj-$(CONFIG_SBC82xx) += sbc82xx.o
obj-$(CONFIG_SPRUCE) += spruce.o
obj-$(CONFIG_LITE5200) += lite5200.o
obj-$(CONFIG_EV64360) += ev64360.o
+obj-$(CONFIG_MPC86XADS) += mpc866ads_setup.o
+obj-$(CONFIG_MPC885ADS) += mpc885ads_setup.o
+obj-$(CONFIG_ADS8272) += mpc8272ads_setup.o
ifeq ($(CONFIG_SMP),y)
obj-$(CONFIG_PPC_CHRP) += chrp_smp.o
diff --git a/arch/ppc/platforms/apus_setup.c b/arch/ppc/platforms/apus_setup.c
index c42c50073da5..fe0cdc04d436 100644
--- a/arch/ppc/platforms/apus_setup.c
+++ b/arch/ppc/platforms/apus_setup.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/apus_setup.c
- *
* Copyright (C) 1998, 1999 Jesper Skov
*
* Basically what is needed to replace functionality found in
diff --git a/arch/ppc/platforms/chestnut.c b/arch/ppc/platforms/chestnut.c
index aefcc0e7be57..f324f757cae1 100644
--- a/arch/ppc/platforms/chestnut.c
+++ b/arch/ppc/platforms/chestnut.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/chestnut.c
- *
* Board setup routines for IBM Chestnut
*
* Author: <source@mvista.com>
diff --git a/arch/ppc/platforms/chestnut.h b/arch/ppc/platforms/chestnut.h
index 0400b2be40ab..e00fd9f8bbd0 100644
--- a/arch/ppc/platforms/chestnut.h
+++ b/arch/ppc/platforms/chestnut.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/chestnut.h
- *
* Definitions for IBM 750FXGX Eval (Chestnut)
*
* Author: <source@mvista.com>
diff --git a/arch/ppc/platforms/chrp_pegasos_eth.c b/arch/ppc/platforms/chrp_pegasos_eth.c
index 108a6e265185..9305c8aa1373 100644
--- a/arch/ppc/platforms/chrp_pegasos_eth.c
+++ b/arch/ppc/platforms/chrp_pegasos_eth.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/chrp_pegasos_eth.c
- *
* Copyright (C) 2005 Sven Luther <sl@bplan-gmbh.de>
* Thanks to :
* Dale Farnsworth <dale@farnsworth.org>
diff --git a/arch/ppc/platforms/chrp_setup.c b/arch/ppc/platforms/chrp_setup.c
index 48996b787378..f9fd3f4f8e2e 100644
--- a/arch/ppc/platforms/chrp_setup.c
+++ b/arch/ppc/platforms/chrp_setup.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/setup.c
- *
* Copyright (C) 1995 Linus Torvalds
* Adapted from 'alpha' version by Gary Thomas
* Modified by Cort Dougan (cort@cs.nmt.edu)
diff --git a/arch/ppc/platforms/chrp_time.c b/arch/ppc/platforms/chrp_time.c
index 57753a55b580..c8627770af13 100644
--- a/arch/ppc/platforms/chrp_time.c
+++ b/arch/ppc/platforms/chrp_time.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/chrp_time.c
- *
* Copyright (C) 1991, 1992, 1995 Linus Torvalds
*
* Adapted for PowerPC (PReP) by Gary Thomas
diff --git a/arch/ppc/platforms/cpci690.c b/arch/ppc/platforms/cpci690.c
index 6ca7bcac9474..790475c22fd7 100644
--- a/arch/ppc/platforms/cpci690.c
+++ b/arch/ppc/platforms/cpci690.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/cpci690.c
- *
* Board setup routines for the Force CPCI690 board.
*
* Author: Mark A. Greer <mgreer@mvista.com>
@@ -290,7 +288,7 @@ cpci690_fixup_mpsc_pdata(struct platform_device *pdev)
pdata->brg_clk_freq = cpci690_get_bus_freq();
}
-static int __init
+static int
cpci690_platform_notify(struct device *dev)
{
static struct {
diff --git a/arch/ppc/platforms/cpci690.h b/arch/ppc/platforms/cpci690.h
index 49584c9cedf3..0fa5a4c31b67 100644
--- a/arch/ppc/platforms/cpci690.h
+++ b/arch/ppc/platforms/cpci690.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/cpci690.h
- *
* Definitions for Force CPCI690
*
* Author: Mark A. Greer <mgreer@mvista.com>
diff --git a/arch/ppc/platforms/ev64260.c b/arch/ppc/platforms/ev64260.c
index ffde8f6f6302..31e8e21e1d5c 100644
--- a/arch/ppc/platforms/ev64260.c
+++ b/arch/ppc/platforms/ev64260.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/ev64260.c
- *
* Board setup routines for the Marvell/Galileo EV-64260-BP Evaluation Board.
*
* Author: Mark A. Greer <mgreer@mvista.com>
@@ -416,7 +414,7 @@ ev64260_fixup_mpsc_pdata(struct platform_device *pdev)
return;
}
-static int __init
+static int
ev64260_platform_notify(struct device *dev)
{
static struct {
diff --git a/arch/ppc/platforms/ev64260.h b/arch/ppc/platforms/ev64260.h
index bedffced3a02..44d90d56745a 100644
--- a/arch/ppc/platforms/ev64260.h
+++ b/arch/ppc/platforms/ev64260.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/ev64260.h
- *
* Definitions for Marvell/Galileo EV-64260-BP Evaluation Board.
*
* Author: Mark A. Greer <mgreer@mvista.com>
diff --git a/arch/ppc/platforms/ev64360.c b/arch/ppc/platforms/ev64360.c
index b9d844f88c2b..104ac9b16e8b 100644
--- a/arch/ppc/platforms/ev64360.c
+++ b/arch/ppc/platforms/ev64360.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/ev64360.c
- *
* Board setup routines for the Marvell EV-64360-BP Evaluation Board.
*
* Author: Lee Nicks <allinux@gmail.com>
@@ -300,7 +298,7 @@ ev64360_fixup_eth_pdata(struct platform_device *pdev)
}
#endif
-static int __init
+static int
ev64360_platform_notify(struct device *dev)
{
static struct {
diff --git a/arch/ppc/platforms/ev64360.h b/arch/ppc/platforms/ev64360.h
index 68eabe490397..b30f4722690a 100644
--- a/arch/ppc/platforms/ev64360.h
+++ b/arch/ppc/platforms/ev64360.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/ev64360.h
- *
* Definitions for Marvell EV-64360-BP Evaluation Board.
*
* Author: Lee Nicks <allinux@gmail.com>
diff --git a/arch/ppc/platforms/fads.h b/arch/ppc/platforms/fads.h
index a48fb8d723e4..e1c0b1b6dcb3 100644
--- a/arch/ppc/platforms/fads.h
+++ b/arch/ppc/platforms/fads.h
@@ -112,7 +112,7 @@
/* CPM Ethernet through SCC1 or SCC2 */
-#ifdef CONFIG_SCC1_ENET /* Probably 860 variant */
+#if defined(CONFIG_SCC1_ENET) || defined(CONFIG_MPC8xx_SECOND_ETH_SCC1) /* Probably 860 variant */
/* Bits in parallel I/O port registers that have to be set/cleared
* to configure the pins for SCC1 use.
* TCLK - CLK1, RCLK - CLK2.
diff --git a/arch/ppc/platforms/gemini.h b/arch/ppc/platforms/gemini.h
index 06de59248918..5528fd0a1216 100644
--- a/arch/ppc/platforms/gemini.h
+++ b/arch/ppc/platforms/gemini.h
@@ -1,7 +1,4 @@
/*
- * arch/ppc/platforms/gemini.h
- *
- *
* Onboard registers and descriptions for Synergy Microsystems'
* "Gemini" boards.
*
diff --git a/arch/ppc/platforms/gemini_prom.S b/arch/ppc/platforms/gemini_prom.S
index 8c5065d56505..b181f2108001 100644
--- a/arch/ppc/platforms/gemini_prom.S
+++ b/arch/ppc/platforms/gemini_prom.S
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/gemini_prom.S
- *
* Not really prom support code (yet), but sort of anti-prom code. The current
* bootloader does a number of things it shouldn't and doesn't do things that it
* should. The stuff in here is mainly a hodge-podge collection of setup code
diff --git a/arch/ppc/platforms/gemini_setup.c b/arch/ppc/platforms/gemini_setup.c
index 729897c59033..0090ff154608 100644
--- a/arch/ppc/platforms/gemini_setup.c
+++ b/arch/ppc/platforms/gemini_setup.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/gemini_setup.c
- *
* Copyright (C) 1995 Linus Torvalds
* Adapted from 'alpha' version by Gary Thomas
* Modified by Cort Dougan (cort@cs.nmt.edu)
diff --git a/arch/ppc/platforms/hdpu.c b/arch/ppc/platforms/hdpu.c
index f945416960e9..75dc2ee87d2f 100644
--- a/arch/ppc/platforms/hdpu.c
+++ b/arch/ppc/platforms/hdpu.c
@@ -1,7 +1,4 @@
-
/*
- * arch/ppc/platforms/hdpu_setup.c
- *
* Board setup routines for the Sky Computers HDPU Compute Blade.
*
* Written by Brian Waite <waite@skycomputers.com>
@@ -353,7 +350,7 @@ static void __init hdpu_fixup_cpustate_pdata(struct platform_device *pd)
}
#endif
-static int __init hdpu_platform_notify(struct device *dev)
+static int hdpu_platform_notify(struct device *dev)
{
static struct {
char *bus_id;
diff --git a/arch/ppc/platforms/hdpu.h b/arch/ppc/platforms/hdpu.h
index 07c3cffb5c7b..f9e020b6970c 100644
--- a/arch/ppc/platforms/hdpu.h
+++ b/arch/ppc/platforms/hdpu.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/hdpu.h
- *
* Definitions for Sky Computers HDPU board.
*
* Brian Waite <waite@skycomputers.com>
diff --git a/arch/ppc/platforms/katana.c b/arch/ppc/platforms/katana.c
index 6e58e30ceed1..ad21280e8920 100644
--- a/arch/ppc/platforms/katana.c
+++ b/arch/ppc/platforms/katana.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/katana.c
- *
* Board setup routines for the Artesyn Katana cPCI boards.
*
* Author: Tim Montgomery <timm@artesyncp.com>
@@ -598,7 +596,7 @@ katana_fixup_mv64xxx_pdata(struct platform_device *pdev)
}
#endif
-static int __init
+static int
katana_platform_notify(struct device *dev)
{
static struct {
@@ -664,12 +662,11 @@ katana_setup_mtd(void)
ptbl_entries = (size >= (64*MB)) ? 6 : 4;
- if ((ptbl = kmalloc(ptbl_entries * sizeof(struct mtd_partition),
+ if ((ptbl = kcalloc(ptbl_entries, sizeof(struct mtd_partition),
GFP_KERNEL)) == NULL) {
printk(KERN_WARNING "Can't alloc MTD partition table\n");
return -ENOMEM;
}
- memset(ptbl, 0, ptbl_entries * sizeof(struct mtd_partition));
ptbl[0].name = "Monitor";
ptbl[0].size = KATANA_MTD_MONITOR_SIZE;
diff --git a/arch/ppc/platforms/katana.h b/arch/ppc/platforms/katana.h
index 597257eff2ec..0a9b036526b1 100644
--- a/arch/ppc/platforms/katana.h
+++ b/arch/ppc/platforms/katana.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/katana.h
- *
* Definitions for Artesyn Katana750i/3750 board.
*
* Author: Tim Montgomery <timm@artesyncp.com>
diff --git a/arch/ppc/platforms/lite5200.c b/arch/ppc/platforms/lite5200.c
index 7ed52dc340c9..5171b53bccb5 100644
--- a/arch/ppc/platforms/lite5200.c
+++ b/arch/ppc/platforms/lite5200.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/lite5200.c
- *
* Platform support file for the Freescale LITE5200 based on MPC52xx.
* A maximum of this file should be moved to syslib/mpc52xx_?????
* so that new platform based on MPC52xx need a minimal platform file
diff --git a/arch/ppc/platforms/lite5200.h b/arch/ppc/platforms/lite5200.h
index c1de2aa47175..852a18e24d0b 100644
--- a/arch/ppc/platforms/lite5200.h
+++ b/arch/ppc/platforms/lite5200.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/lite5200.h
- *
* Definitions for Freescale LITE5200 : MPC52xx Standard Development
* Platform board support
*
diff --git a/arch/ppc/platforms/lopec.c b/arch/ppc/platforms/lopec.c
index 06d247c23b82..c6445a727ca3 100644
--- a/arch/ppc/platforms/lopec.c
+++ b/arch/ppc/platforms/lopec.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/lopec.c
- *
* Setup routines for the Motorola LoPEC.
*
* Author: Dan Cox
diff --git a/arch/ppc/platforms/mpc8272ads_setup.c b/arch/ppc/platforms/mpc8272ads_setup.c
new file mode 100644
index 000000000000..bc9b94f77e39
--- /dev/null
+++ b/arch/ppc/platforms/mpc8272ads_setup.c
@@ -0,0 +1,236 @@
+/*
+ * arch/ppc/platforms/82xx/pq2ads_pd.c
+ *
+ * MPC82xx Board-specific PlatformDevice descriptions
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/ioport.h>
+#include <linux/fs_enet_pd.h>
+#include <linux/platform_device.h>
+
+#include <asm/io.h>
+#include <asm/mpc8260.h>
+#include <asm/cpm2.h>
+#include <asm/immap_cpm2.h>
+#include <asm/irq.h>
+#include <asm/ppc_sys.h>
+#include <asm/ppcboot.h>
+
+#include "pq2ads_pd.h"
+
+static void init_fcc1_ioports(void);
+static void init_fcc2_ioports(void);
+
+static struct fs_mii_bus_info mii_bus_info = {
+ .method = fsmii_bitbang,
+ .id = 0,
+ .i.bitbang = {
+ .mdio_port = fsiop_portc,
+ .mdio_bit = 18,
+ .mdc_port = fsiop_portc,
+ .mdc_bit = 19,
+ .delay = 1,
+ },
+};
+
+static struct fs_platform_info mpc82xx_fcc1_pdata = {
+ .fs_no = fsid_fcc1,
+ .cp_page = CPM_CR_FCC1_PAGE,
+ .cp_block = CPM_CR_FCC1_SBLOCK,
+ .clk_trx = (PC_F1RXCLK | PC_F1TXCLK),
+ .clk_route = CMX1_CLK_ROUTE,
+ .clk_mask = CMX1_CLK_MASK,
+ .init_ioports = init_fcc1_ioports,
+
+ .phy_addr = 0,
+#ifdef PHY_INTERRUPT
+ .phy_irq = PHY_INTERRUPT,
+#else
+ .phy_irq = -1;
+#endif
+ .mem_offset = FCC1_MEM_OFFSET,
+ .bus_info = &mii_bus_info,
+ .rx_ring = 32,
+ .tx_ring = 32,
+ .rx_copybreak = 240,
+ .use_napi = 0,
+ .napi_weight = 17,
+};
+
+static struct fs_platform_info mpc82xx_fcc2_pdata = {
+ .fs_no = fsid_fcc2,
+ .cp_page = CPM_CR_FCC2_PAGE,
+ .cp_block = CPM_CR_FCC2_SBLOCK,
+ .clk_trx = (PC_F2RXCLK | PC_F2TXCLK),
+ .clk_route = CMX2_CLK_ROUTE,
+ .clk_mask = CMX2_CLK_MASK,
+ .init_ioports = init_fcc2_ioports,
+
+ .phy_addr = 3,
+#ifdef PHY_INTERRUPT
+ .phy_irq = PHY_INTERRUPT,
+#else
+ .phy_irq = -1;
+#endif
+ .mem_offset = FCC2_MEM_OFFSET,
+ .bus_info = &mii_bus_info,
+ .rx_ring = 32,
+ .tx_ring = 32,
+ .rx_copybreak = 240,
+ .use_napi = 0,
+ .napi_weight = 17,
+};
+
+static void init_fcc1_ioports(void)
+{
+ struct io_port *io;
+ u32 tempval;
+ cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
+ u32 *bcsr = ioremap(BCSR_ADDR+4, sizeof(u32));
+
+ io = &immap->im_ioport;
+
+ /* Enable the PHY */
+ clrbits32(bcsr, BCSR1_FETHIEN);
+ setbits32(bcsr, BCSR1_FETH_RST);
+
+ /* FCC1 pins are on port A/C. */
+ /* Configure port A and C pins for FCC1 Ethernet. */
+
+ tempval = in_be32(&io->iop_pdira);
+ tempval &= ~PA1_DIRA0;
+ tempval |= PA1_DIRA1;
+ out_be32(&io->iop_pdira, tempval);
+
+ tempval = in_be32(&io->iop_psora);
+ tempval &= ~PA1_PSORA0;
+ tempval |= PA1_PSORA1;
+ out_be32(&io->iop_psora, tempval);
+
+ setbits32(&io->iop_ppara,PA1_DIRA0 | PA1_DIRA1);
+
+ /* Alter clocks */
+ tempval = PC_F1TXCLK|PC_F1RXCLK;
+
+ clrbits32(&io->iop_psorc, tempval);
+ clrbits32(&io->iop_pdirc, tempval);
+ setbits32(&io->iop_pparc, tempval);
+
+ clrbits32(&immap->im_cpmux.cmx_fcr, CMX1_CLK_MASK);
+ setbits32(&immap->im_cpmux.cmx_fcr, CMX1_CLK_ROUTE);
+ iounmap(bcsr);
+ iounmap(immap);
+}
+
+static void init_fcc2_ioports(void)
+{
+ cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
+ u32 *bcsr = ioremap(BCSR_ADDR+12, sizeof(u32));
+
+ struct io_port *io;
+ u32 tempval;
+
+ immap = cpm2_immr;
+
+ io = &immap->im_ioport;
+
+ /* Enable the PHY */
+ clrbits32(bcsr, BCSR3_FETHIEN2);
+ setbits32(bcsr, BCSR3_FETH2_RST);
+
+ /* FCC2 are port B/C. */
+ /* Configure port A and C pins for FCC2 Ethernet. */
+
+ tempval = in_be32(&io->iop_pdirb);
+ tempval &= ~PB2_DIRB0;
+ tempval |= PB2_DIRB1;
+ out_be32(&io->iop_pdirb, tempval);
+
+ tempval = in_be32(&io->iop_psorb);
+ tempval &= ~PB2_PSORB0;
+ tempval |= PB2_PSORB1;
+ out_be32(&io->iop_psorb, tempval);
+
+ setbits32(&io->iop_pparb,PB2_DIRB0 | PB2_DIRB1);
+
+ tempval = PC_F2RXCLK|PC_F2TXCLK;
+
+ /* Alter clocks */
+ clrbits32(&io->iop_psorc,tempval);
+ clrbits32(&io->iop_pdirc,tempval);
+ setbits32(&io->iop_pparc,tempval);
+
+ clrbits32(&immap->im_cpmux.cmx_fcr, CMX2_CLK_MASK);
+ setbits32(&immap->im_cpmux.cmx_fcr, CMX2_CLK_ROUTE);
+
+ iounmap(bcsr);
+ iounmap(immap);
+}
+
+
+static void __init mpc8272ads_fixup_enet_pdata(struct platform_device *pdev,
+ int idx)
+{
+ bd_t* bi = (void*)__res;
+ int fs_no = fsid_fcc1+pdev->id-1;
+
+ mpc82xx_fcc1_pdata.dpram_offset = mpc82xx_fcc2_pdata.dpram_offset = (u32)cpm2_immr->im_dprambase;
+ mpc82xx_fcc1_pdata.fcc_regs_c = mpc82xx_fcc2_pdata.fcc_regs_c = (u32)cpm2_immr->im_fcc_c;
+
+ switch(fs_no) {
+ case fsid_fcc1:
+ memcpy(&mpc82xx_fcc1_pdata.macaddr,bi->bi_enetaddr,6);
+ pdev->dev.platform_data = &mpc82xx_fcc1_pdata;
+ break;
+ case fsid_fcc2:
+ memcpy(&mpc82xx_fcc2_pdata.macaddr,bi->bi_enetaddr,6);
+ mpc82xx_fcc2_pdata.macaddr[5] ^= 1;
+ pdev->dev.platform_data = &mpc82xx_fcc2_pdata;
+ break;
+ }
+}
+
+static int mpc8272ads_platform_notify(struct device *dev)
+{
+ static const struct platform_notify_dev_map dev_map[] = {
+ {
+ .bus_id = "fsl-cpm-fcc",
+ .rtn = mpc8272ads_fixup_enet_pdata
+ },
+ {
+ .bus_id = NULL
+ }
+ };
+ platform_notify_map(dev_map,dev);
+
+ return 0;
+
+}
+
+int __init mpc8272ads_init(void)
+{
+ printk(KERN_NOTICE "mpc8272ads: Init\n");
+
+ platform_notify = mpc8272ads_platform_notify;
+
+ ppc_sys_device_initfunc();
+
+ ppc_sys_device_disable_all();
+ ppc_sys_device_enable(MPC82xx_CPM_FCC1);
+ ppc_sys_device_enable(MPC82xx_CPM_FCC2);
+
+ return 0;
+}
+
+arch_initcall(mpc8272ads_init);
diff --git a/arch/ppc/platforms/mpc866ads_setup.c b/arch/ppc/platforms/mpc866ads_setup.c
new file mode 100644
index 000000000000..ac8fcc68afeb
--- /dev/null
+++ b/arch/ppc/platforms/mpc866ads_setup.c
@@ -0,0 +1,273 @@
+/*arch/ppc/platforms/mpc885ads-setup.c
+ *
+ * Platform setup for the Freescale mpc885ads board
+ *
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * Copyright 2005 MontaVista Software Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+
+#include <linux/fs_enet_pd.h>
+#include <linux/mii.h>
+
+#include <asm/delay.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/ppcboot.h>
+#include <asm/8xx_immap.h>
+#include <asm/commproc.h>
+#include <asm/ppc_sys.h>
+#include <asm/mpc8xx.h>
+
+extern unsigned char __res[];
+
+static struct fs_mii_bus_info fec_mii_bus_info = {
+ .method = fsmii_fec,
+ .id = 0,
+};
+
+static struct fs_mii_bus_info scc_mii_bus_info = {
+ .method = fsmii_fixed,
+ .id = 0,
+ .i.fixed.speed = 10,
+ .i.fixed.duplex = 0,
+};
+
+static struct fs_platform_info mpc8xx_fec_pdata[] = {
+ {
+ .rx_ring = 128,
+ .tx_ring = 16,
+ .rx_copybreak = 240,
+
+ .use_napi = 1,
+ .napi_weight = 17,
+
+ .phy_addr = 15,
+ .phy_irq = -1,
+
+ .use_rmii = 0,
+
+ .bus_info = &fec_mii_bus_info,
+ }
+};
+
+static struct fs_platform_info mpc8xx_scc_pdata = {
+ .rx_ring = 64,
+ .tx_ring = 8,
+ .rx_copybreak = 240,
+
+ .use_napi = 1,
+ .napi_weight = 17,
+
+ .phy_addr = -1,
+ .phy_irq = -1,
+
+ .bus_info = &scc_mii_bus_info,
+};
+
+void __init board_init(void)
+{
+ volatile cpm8xx_t *cp = cpmp;
+ unsigned *bcsr_io;
+
+ bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+
+ if (bcsr_io == NULL) {
+ printk(KERN_CRIT "Could not remap BCSR1\n");
+ return;
+ }
+#ifdef CONFIG_SERIAL_CPM_SMC1
+ cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */
+ clrbits32(bcsr_io,(0x80000000 >> 7));
+#else
+ setbits32(bcsr_io,(0x80000000 >> 7));
+
+ cp->cp_pbpar &= ~(0x000000c0);
+ cp->cp_pbdir |= 0x000000c0;
+ cp->cp_smc[0].smc_smcmr = 0;
+ cp->cp_smc[0].smc_smce = 0;
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SMC2
+ cp->cp_simode &= ~(0xe0000000 >> 1);
+ cp->cp_simode |= (0x20000000 >> 1); /* brg2 */
+ clrbits32(bcsr_io,(0x80000000 >> 13));
+#else
+ clrbits32(bcsr_io,(0x80000000 >> 13));
+ cp->cp_pbpar &= ~(0x00000c00);
+ cp->cp_pbdir |= 0x00000c00;
+ cp->cp_smc[1].smc_smcmr = 0;
+ cp->cp_smc[1].smc_smce = 0;
+#endif
+ iounmap(bcsr_io);
+}
+
+static void setup_fec1_ioports(void)
+{
+ immap_t *immap = (immap_t *) IMAP_ADDR;
+
+ setbits16(&immap->im_ioport.iop_pdpar, 0x1fff);
+ setbits16(&immap->im_ioport.iop_pddir, 0x1fff);
+}
+
+static void setup_scc1_ioports(void)
+{
+ immap_t *immap = (immap_t *) IMAP_ADDR;
+ unsigned *bcsr_io;
+
+ bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+
+ if (bcsr_io == NULL) {
+ printk(KERN_CRIT "Could not remap BCSR1\n");
+ return;
+ }
+
+ /* Enable the PHY.
+ */
+ clrbits32(bcsr_io,BCSR1_ETHEN);
+
+ /* Configure port A pins for Txd and Rxd.
+ */
+ /* Disable receive and transmit in case EPPC-Bug started it.
+ */
+ setbits16(&immap->im_ioport.iop_papar, PA_ENET_RXD | PA_ENET_TXD);
+ clrbits16(&immap->im_ioport.iop_padir, PA_ENET_RXD | PA_ENET_TXD);
+ clrbits16(&immap->im_ioport.iop_paodr, PA_ENET_TXD);
+
+ /* Configure port C pins to enable CLSN and RENA.
+ */
+ clrbits16(&immap->im_ioport.iop_pcpar, PC_ENET_CLSN | PC_ENET_RENA);
+ clrbits16(&immap->im_ioport.iop_pcdir, PC_ENET_CLSN | PC_ENET_RENA);
+ setbits16(&immap->im_ioport.iop_pcso, PC_ENET_CLSN | PC_ENET_RENA);
+ /* Configure port A for TCLK and RCLK.
+ */
+ setbits16(&immap->im_ioport.iop_papar, PA_ENET_TCLK | PA_ENET_RCLK);
+ clrbits16(&immap->im_ioport.iop_padir, PA_ENET_TCLK | PA_ENET_RCLK);
+ clrbits32(&immap->im_cpm.cp_pbpar, PB_ENET_TENA);
+ clrbits32(&immap->im_cpm.cp_pbdir, PB_ENET_TENA);
+
+ /* Configure Serial Interface clock routing.
+ * First, clear all SCC bits to zero, then set the ones we want.
+ */
+ clrbits32(&immap->im_cpm.cp_sicr, SICR_ENET_MASK);
+ setbits32(&immap->im_cpm.cp_sicr, SICR_ENET_CLKRT);
+
+ /* In the original SCC enet driver the following code is placed at
+ the end of the initialization */
+ setbits32(&immap->im_cpm.cp_pbpar, PB_ENET_TENA);
+ setbits32(&immap->im_cpm.cp_pbdir, PB_ENET_TENA);
+
+}
+
+static void mpc866ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no)
+{
+ struct fs_platform_info *fpi = pdev->dev.platform_data;
+
+ volatile cpm8xx_t *cp;
+ bd_t *bd = (bd_t *) __res;
+ char *e;
+ int i;
+
+ /* Get pointer to Communication Processor */
+ cp = cpmp;
+ switch (fs_no) {
+ case fsid_fec1:
+ fpi = &mpc8xx_fec_pdata[0];
+ fpi->init_ioports = &setup_fec1_ioports;
+
+ break;
+ case fsid_scc1:
+ fpi = &mpc8xx_scc_pdata;
+ fpi->init_ioports = &setup_scc1_ioports;
+
+ break;
+ default:
+ printk(KERN_WARNING"Device %s is not supported!\n", pdev->name);
+ return;
+ }
+
+ pdev->dev.platform_data = fpi;
+ fpi->fs_no = fs_no;
+
+ e = (unsigned char *)&bd->bi_enetaddr;
+ for (i = 0; i < 6; i++)
+ fpi->macaddr[i] = *e++;
+
+ fpi->macaddr[5 - pdev->id]++;
+
+}
+
+static void mpc866ads_fixup_fec_enet_pdata(struct platform_device *pdev,
+ int idx)
+{
+ /* This is for FEC devices only */
+ if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-fec")))
+ return;
+ mpc866ads_fixup_enet_pdata(pdev, fsid_fec1 + pdev->id - 1);
+}
+
+static void mpc866ads_fixup_scc_enet_pdata(struct platform_device *pdev,
+ int idx)
+{
+ /* This is for SCC devices only */
+ if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-scc")))
+ return;
+
+ mpc866ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
+}
+
+static int mpc866ads_platform_notify(struct device *dev)
+{
+ static const struct platform_notify_dev_map dev_map[] = {
+ {
+ .bus_id = "fsl-cpm-fec",
+ .rtn = mpc866ads_fixup_fec_enet_pdata,
+ },
+ {
+ .bus_id = "fsl-cpm-scc",
+ .rtn = mpc866ads_fixup_scc_enet_pdata,
+ },
+ {
+ .bus_id = NULL
+ }
+ };
+
+ platform_notify_map(dev_map,dev);
+
+ return 0;
+}
+
+int __init mpc866ads_init(void)
+{
+ printk(KERN_NOTICE "mpc866ads: Init\n");
+
+ platform_notify = mpc866ads_platform_notify;
+
+ ppc_sys_device_initfunc();
+ ppc_sys_device_disable_all();
+
+#ifdef MPC8xx_SECOND_ETH_SCC1
+ ppc_sys_device_enable(MPC8xx_CPM_SCC1);
+#endif
+ ppc_sys_device_enable(MPC8xx_CPM_FEC1);
+
+ return 0;
+}
+
+arch_initcall(mpc866ads_init);
diff --git a/arch/ppc/platforms/mpc885ads_setup.c b/arch/ppc/platforms/mpc885ads_setup.c
new file mode 100644
index 000000000000..50a99e5f7c68
--- /dev/null
+++ b/arch/ppc/platforms/mpc885ads_setup.c
@@ -0,0 +1,389 @@
+/*arch/ppc/platforms/mpc885ads-setup.c
+ *
+ * Platform setup for the Freescale mpc885ads board
+ *
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * Copyright 2005 MontaVista Software Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+
+#include <linux/fs_enet_pd.h>
+#include <linux/mii.h>
+
+#include <asm/delay.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/ppcboot.h>
+#include <asm/8xx_immap.h>
+#include <asm/commproc.h>
+#include <asm/ppc_sys.h>
+
+extern unsigned char __res[];
+
+static void __init mpc885ads_scc_phy_init(char);
+
+static struct fs_mii_bus_info fec_mii_bus_info = {
+ .method = fsmii_fec,
+ .id = 0,
+};
+
+static struct fs_mii_bus_info scc_mii_bus_info = {
+#ifdef CONFIG_SCC_ENET_8xx_FIXED
+ .method = fsmii_fixed,
+#else
+ .method = fsmii_fec,
+#endif
+
+ .id = 0,
+};
+
+static struct fs_platform_info mpc8xx_fec_pdata[] = {
+ {
+ .rx_ring = 128,
+ .tx_ring = 16,
+ .rx_copybreak = 240,
+
+ .use_napi = 1,
+ .napi_weight = 17,
+
+ .phy_addr = 0,
+ .phy_irq = SIU_IRQ7,
+
+ .bus_info = &fec_mii_bus_info,
+ }, {
+ .rx_ring = 128,
+ .tx_ring = 16,
+ .rx_copybreak = 240,
+
+ .use_napi = 1,
+ .napi_weight = 17,
+
+ .phy_addr = 1,
+ .phy_irq = SIU_IRQ7,
+
+ .bus_info = &fec_mii_bus_info,
+ }
+};
+
+static struct fs_platform_info mpc8xx_scc_pdata = {
+ .rx_ring = 64,
+ .tx_ring = 8,
+ .rx_copybreak = 240,
+
+ .use_napi = 1,
+ .napi_weight = 17,
+
+ .phy_addr = 2,
+#ifdef CONFIG_MPC8xx_SCC_ENET_FIXED
+ .phy_irq = -1,
+#else
+ .phy_irq = SIU_IRQ7,
+#endif
+
+ .bus_info = &scc_mii_bus_info,
+};
+
+void __init board_init(void)
+{
+ volatile cpm8xx_t *cp = cpmp;
+ unsigned int *bcsr_io;
+
+#ifdef CONFIG_FS_ENET
+ immap_t *immap = (immap_t *) IMAP_ADDR;
+#endif
+ bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+
+ if (bcsr_io == NULL) {
+ printk(KERN_CRIT "Could not remap BCSR\n");
+ return;
+ }
+#ifdef CONFIG_SERIAL_CPM_SMC1
+ cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */
+ clrbits32(bcsr_io, BCSR1_RS232EN_1);
+#else
+ setbits32(bcsr_io,BCSR1_RS232EN_1);
+ cp->cp_smc[0].smc_smcmr = 0;
+ cp->cp_smc[0].smc_smce = 0;
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SMC2
+ cp->cp_simode &= ~(0xe0000000 >> 1);
+ cp->cp_simode |= (0x20000000 >> 1); /* brg2 */
+ clrbits32(bcsr_io,BCSR1_RS232EN_2);
+#else
+ setbits32(bcsr_io,BCSR1_RS232EN_2);
+ cp->cp_smc[1].smc_smcmr = 0;
+ cp->cp_smc[1].smc_smce = 0;
+#endif
+ iounmap(bcsr_io);
+
+#ifdef CONFIG_FS_ENET
+ /* use MDC for MII (common) */
+ setbits16(&immap->im_ioport.iop_pdpar, 0x0080);
+ clrbits16(&immap->im_ioport.iop_pddir, 0x0080);
+#endif
+}
+
+static void setup_fec1_ioports(void)
+{
+ immap_t *immap = (immap_t *) IMAP_ADDR;
+
+ /* configure FEC1 pins */
+ setbits16(&immap->im_ioport.iop_papar, 0xf830);
+ setbits16(&immap->im_ioport.iop_padir, 0x0830);
+ clrbits16(&immap->im_ioport.iop_padir, 0xf000);
+ setbits32(&immap->im_cpm.cp_pbpar, 0x00001001);
+
+ clrbits32(&immap->im_cpm.cp_pbdir, 0x00001001);
+ setbits16(&immap->im_ioport.iop_pcpar, 0x000c);
+ clrbits16(&immap->im_ioport.iop_pcdir, 0x000c);
+ setbits32(&immap->im_cpm.cp_pepar, 0x00000003);
+
+ setbits32(&immap->im_cpm.cp_pedir, 0x00000003);
+ clrbits32(&immap->im_cpm.cp_peso, 0x00000003);
+ clrbits32(&immap->im_cpm.cp_cptr, 0x00000100);
+}
+
+static void setup_fec2_ioports(void)
+{
+ immap_t *immap = (immap_t *) IMAP_ADDR;
+
+ /* configure FEC2 pins */
+ setbits32(&immap->im_cpm.cp_pepar, 0x0003fffc);
+ setbits32(&immap->im_cpm.cp_pedir, 0x0003fffc);
+ setbits32(&immap->im_cpm.cp_peso, 0x00037800);
+ clrbits32(&immap->im_cpm.cp_peso, 0x000087fc);
+ clrbits32(&immap->im_cpm.cp_cptr, 0x00000080);
+}
+
+static void setup_scc3_ioports(void)
+{
+ immap_t *immap = (immap_t *) IMAP_ADDR;
+ unsigned *bcsr_io;
+
+ bcsr_io = ioremap(BCSR_ADDR, BCSR_SIZE);
+
+ if (bcsr_io == NULL) {
+ printk(KERN_CRIT "Could not remap BCSR\n");
+ return;
+ }
+
+ /* Enable the PHY.
+ */
+ setbits32(bcsr_io+4, BCSR4_ETH10_RST);
+ /* Configure port A pins for Txd and Rxd.
+ */
+ setbits16(&immap->im_ioport.iop_papar, PA_ENET_RXD | PA_ENET_TXD);
+ clrbits16(&immap->im_ioport.iop_padir, PA_ENET_RXD | PA_ENET_TXD);
+
+ /* Configure port C pins to enable CLSN and RENA.
+ */
+ clrbits16(&immap->im_ioport.iop_pcpar, PC_ENET_CLSN | PC_ENET_RENA);
+ clrbits16(&immap->im_ioport.iop_pcdir, PC_ENET_CLSN | PC_ENET_RENA);
+ setbits16(&immap->im_ioport.iop_pcso, PC_ENET_CLSN | PC_ENET_RENA);
+
+ /* Configure port E for TCLK and RCLK.
+ */
+ setbits32(&immap->im_cpm.cp_pepar, PE_ENET_TCLK | PE_ENET_RCLK);
+ clrbits32(&immap->im_cpm.cp_pepar, PE_ENET_TENA);
+ clrbits32(&immap->im_cpm.cp_pedir,
+ PE_ENET_TCLK | PE_ENET_RCLK | PE_ENET_TENA);
+ clrbits32(&immap->im_cpm.cp_peso, PE_ENET_TCLK | PE_ENET_RCLK);
+ setbits32(&immap->im_cpm.cp_peso, PE_ENET_TENA);
+
+ /* Configure Serial Interface clock routing.
+ * First, clear all SCC bits to zero, then set the ones we want.
+ */
+ clrbits32(&immap->im_cpm.cp_sicr, SICR_ENET_MASK);
+ setbits32(&immap->im_cpm.cp_sicr, SICR_ENET_CLKRT);
+
+ /* Disable Rx and Tx. SMC1 sshould be stopped if SCC3 eternet are used.
+ */
+ immap->im_cpm.cp_smc[0].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
+ /* On the MPC885ADS SCC ethernet PHY is initialized in the full duplex mode
+ * by H/W setting after reset. SCC ethernet controller support only half duplex.
+ * This discrepancy of modes causes a lot of carrier lost errors.
+ */
+
+ /* In the original SCC enet driver the following code is placed at
+ the end of the initialization */
+ setbits32(&immap->im_cpm.cp_pepar, PE_ENET_TENA);
+ clrbits32(&immap->im_cpm.cp_pedir, PE_ENET_TENA);
+ setbits32(&immap->im_cpm.cp_peso, PE_ENET_TENA);
+
+ setbits32(bcsr_io+1, BCSR1_ETHEN);
+ iounmap(bcsr_io);
+}
+
+static void mpc885ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no)
+{
+ struct fs_platform_info *fpi = pdev->dev.platform_data;
+
+ volatile cpm8xx_t *cp;
+ bd_t *bd = (bd_t *) __res;
+ char *e;
+ int i;
+
+ /* Get pointer to Communication Processor */
+ cp = cpmp;
+ switch (fs_no) {
+ case fsid_fec1:
+ fpi = &mpc8xx_fec_pdata[0];
+ fpi->init_ioports = &setup_fec1_ioports;
+ break;
+ case fsid_fec2:
+ fpi = &mpc8xx_fec_pdata[1];
+ fpi->init_ioports = &setup_fec2_ioports;
+ break;
+ case fsid_scc3:
+ fpi = &mpc8xx_scc_pdata;
+ fpi->init_ioports = &setup_scc3_ioports;
+ mpc885ads_scc_phy_init(fpi->phy_addr);
+ break;
+ default:
+ printk(KERN_WARNING"Device %s is not supported!\n", pdev->name);
+ return;
+ }
+
+ pdev->dev.platform_data = fpi;
+ fpi->fs_no = fs_no;
+
+ e = (unsigned char *)&bd->bi_enetaddr;
+ for (i = 0; i < 6; i++)
+ fpi->macaddr[i] = *e++;
+
+ fpi->macaddr[5 - pdev->id]++;
+
+}
+
+static void mpc885ads_fixup_fec_enet_pdata(struct platform_device *pdev,
+ int idx)
+{
+ /* This is for FEC devices only */
+ if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-fec")))
+ return;
+ mpc885ads_fixup_enet_pdata(pdev, fsid_fec1 + pdev->id - 1);
+}
+
+static void __init mpc885ads_fixup_scc_enet_pdata(struct platform_device *pdev,
+ int idx)
+{
+ /* This is for SCC devices only */
+ if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-scc")))
+ return;
+
+ mpc885ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
+}
+
+/* SCC ethernet controller does not have MII management channel. FEC1 MII
+ * channel is used to communicate with the 10Mbit PHY.
+ */
+
+#define MII_ECNTRL_PINMUX 0x4
+#define FEC_ECNTRL_PINMUX 0x00000004
+#define FEC_RCNTRL_MII_MODE 0x00000004
+
+/* Make MII read/write commands.
+ */
+#define mk_mii_write(REG, VAL, PHY_ADDR) (0x50020000 | (((REG) & 0x1f) << 18) | \
+ ((VAL) & 0xffff) | ((PHY_ADDR) << 23))
+
+static void mpc885ads_scc_phy_init(char phy_addr)
+{
+ volatile immap_t *immap;
+ volatile fec_t *fecp;
+ bd_t *bd;
+
+ bd = (bd_t *) __res;
+ immap = (immap_t *) IMAP_ADDR; /* pointer to internal registers */
+ fecp = &(immap->im_cpm.cp_fec);
+
+ /* Enable MII pins of the FEC1
+ */
+ setbits16(&immap->im_ioport.iop_pdpar, 0x0080);
+ clrbits16(&immap->im_ioport.iop_pddir, 0x0080);
+ /* Set MII speed to 2.5 MHz
+ */
+ out_be32(&fecp->fec_mii_speed,
+ ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1);
+
+ /* Enable FEC pin MUX
+ */
+ setbits32(&fecp->fec_ecntrl, MII_ECNTRL_PINMUX);
+ setbits32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE);
+
+ out_be32(&fecp->fec_mii_data,
+ mk_mii_write(MII_BMCR, BMCR_ISOLATE, phy_addr));
+ udelay(100);
+ out_be32(&fecp->fec_mii_data,
+ mk_mii_write(MII_ADVERTISE,
+ ADVERTISE_10HALF | ADVERTISE_CSMA, phy_addr));
+ udelay(100);
+
+ /* Disable FEC MII settings
+ */
+ clrbits32(&fecp->fec_ecntrl, MII_ECNTRL_PINMUX);
+ clrbits32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE);
+ out_be32(&fecp->fec_mii_speed, 0);
+}
+
+static int mpc885ads_platform_notify(struct device *dev)
+{
+
+ static const struct platform_notify_dev_map dev_map[] = {
+ {
+ .bus_id = "fsl-cpm-fec",
+ .rtn = mpc885ads_fixup_fec_enet_pdata,
+ },
+ {
+ .bus_id = "fsl-cpm-scc",
+ .rtn = mpc885ads_fixup_scc_enet_pdata,
+ },
+ {
+ .bus_id = NULL
+ }
+ };
+
+ platform_notify_map(dev_map,dev);
+
+}
+
+int __init mpc885ads_init(void)
+{
+ printk(KERN_NOTICE "mpc885ads: Init\n");
+
+ platform_notify = mpc885ads_platform_notify;
+
+ ppc_sys_device_initfunc();
+ ppc_sys_device_disable_all();
+
+ ppc_sys_device_enable(MPC8xx_CPM_FEC1);
+
+#ifdef CONFIG_MPC8xx_SECOND_ETH_SCC3
+ ppc_sys_device_enable(MPC8xx_CPM_SCC1);
+
+#endif
+#ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
+ ppc_sys_device_enable(MPC8xx_CPM_FEC2);
+#endif
+
+ return 0;
+}
+
+arch_initcall(mpc885ads_init);
diff --git a/arch/ppc/platforms/mvme5100.c b/arch/ppc/platforms/mvme5100.c
index 108eb182dddc..c717cd92c028 100644
--- a/arch/ppc/platforms/mvme5100.c
+++ b/arch/ppc/platforms/mvme5100.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/mvme5100.c
- *
* Board setup routines for the Motorola MVME5100.
*
* Author: Matt Porter <mporter@mvista.com>
diff --git a/arch/ppc/platforms/pal4.h b/arch/ppc/platforms/pal4.h
index 641a11a31657..8569c423d887 100644
--- a/arch/ppc/platforms/pal4.h
+++ b/arch/ppc/platforms/pal4.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/pal4.h
- *
* Definitions for SBS Palomar IV board
*
* Author: Dan Cox
diff --git a/arch/ppc/platforms/pal4_pci.c b/arch/ppc/platforms/pal4_pci.c
index c3b1b757a48b..d81ae1c7e1cf 100644
--- a/arch/ppc/platforms/pal4_pci.c
+++ b/arch/ppc/platforms/pal4_pci.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/pal4_pci.c
- *
* PCI support for SBS Palomar IV
*
* Author: Dan Cox
diff --git a/arch/ppc/platforms/pal4_serial.h b/arch/ppc/platforms/pal4_serial.h
index a715c66e1adf..a75343224cfd 100644
--- a/arch/ppc/platforms/pal4_serial.h
+++ b/arch/ppc/platforms/pal4_serial.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/pal4_serial.h
- *
* Definitions for SBS PalomarIV serial support
*
* Author: Dan Cox
diff --git a/arch/ppc/platforms/pal4_setup.c b/arch/ppc/platforms/pal4_setup.c
index f93a3f871932..3c3d881df00d 100644
--- a/arch/ppc/platforms/pal4_setup.c
+++ b/arch/ppc/platforms/pal4_setup.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/pal4_setup.c
- *
* Board setup routines for the SBS PalomarIV.
*
* Author: Dan Cox
diff --git a/arch/ppc/platforms/powerpmc250.c b/arch/ppc/platforms/powerpmc250.c
index e6b520e6e13f..c3a86be11fb7 100644
--- a/arch/ppc/platforms/powerpmc250.c
+++ b/arch/ppc/platforms/powerpmc250.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/powerpmc250.c
- *
* Board setup routines for Force PowerPMC-250 Processor PMC
*
* Author: Troy Benjegerdes <tbenjegerdes@mvista.com>
diff --git a/arch/ppc/platforms/pplus.c b/arch/ppc/platforms/pplus.c
index 22bd40cfb092..de2761ebe0d9 100644
--- a/arch/ppc/platforms/pplus.c
+++ b/arch/ppc/platforms/pplus.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/pplus.c
- *
* Board and PCI setup routines for MCG PowerPlus
*
* Author: Randy Vinson <rvinson@mvista.com>
diff --git a/arch/ppc/platforms/pplus.h b/arch/ppc/platforms/pplus.h
index 90f0cb2d409f..a07cbbdd72c6 100644
--- a/arch/ppc/platforms/pplus.h
+++ b/arch/ppc/platforms/pplus.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/pplus.h
- *
* Definitions for Motorola MCG Falcon/Raven & HAWK North Bridge & Memory ctlr.
*
* Author: Mark A. Greerinclude/asm-ppc/hawk.h
diff --git a/arch/ppc/platforms/pq2ads.c b/arch/ppc/platforms/pq2ads.c
index 71c9fca1fe9b..3365fd788a7a 100644
--- a/arch/ppc/platforms/pq2ads.c
+++ b/arch/ppc/platforms/pq2ads.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/pq2ads.c
- *
* PQ2ADS platform support
*
* Author: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/platforms/pq2ads.h b/arch/ppc/platforms/pq2ads.h
index 067d9a5aebc1..6b26dd36c640 100644
--- a/arch/ppc/platforms/pq2ads.h
+++ b/arch/ppc/platforms/pq2ads.h
@@ -13,6 +13,10 @@
#include <asm/ppcboot.h>
+#if defined(CONFIG_ADS8272)
+#define BOARD_CHIP_NAME "8272"
+#endif
+
/* Memory map is configured by the PROM startup.
* We just map a few things we need. The CSR is actually 4 byte-wide
* registers that can be accessed as 8-, 16-, or 32-bit values.
diff --git a/arch/ppc/platforms/pq2ads_pd.h b/arch/ppc/platforms/pq2ads_pd.h
new file mode 100644
index 000000000000..8f14a43eafec
--- /dev/null
+++ b/arch/ppc/platforms/pq2ads_pd.h
@@ -0,0 +1,114 @@
+#ifndef __PQ2ADS_PD_H
+#define __PQ2ADS_PD_H
+/*
+ * arch/ppc/platforms/82xx/pq2ads_pd.h
+ *
+ * Some defines for MPC82xx board-specific PlatformDevice descriptions
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/* FCC1 Clock Source Configuration. These can be redefined in the board specific file.
+ Can only choose from CLK9-12 */
+
+#define F1_RXCLK 11
+#define F1_TXCLK 10
+
+/* FCC2 Clock Source Configuration. These can be redefined in the board specific file.
+ Can only choose from CLK13-16 */
+#define F2_RXCLK 15
+#define F2_TXCLK 16
+
+/* FCC3 Clock Source Configuration. These can be redefined in the board specific file.
+ Can only choose from CLK13-16 */
+#define F3_RXCLK 13
+#define F3_TXCLK 14
+
+/* Automatically generates register configurations */
+#define PC_CLK(x) ((uint)(1<<(x-1))) /* FCC CLK I/O ports */
+
+#define CMXFCR_RF1CS(x) ((uint)((x-5)<<27)) /* FCC1 Receive Clock Source */
+#define CMXFCR_TF1CS(x) ((uint)((x-5)<<24)) /* FCC1 Transmit Clock Source */
+#define CMXFCR_RF2CS(x) ((uint)((x-9)<<19)) /* FCC2 Receive Clock Source */
+#define CMXFCR_TF2CS(x) ((uint)((x-9)<<16)) /* FCC2 Transmit Clock Source */
+#define CMXFCR_RF3CS(x) ((uint)((x-9)<<11)) /* FCC3 Receive Clock Source */
+#define CMXFCR_TF3CS(x) ((uint)((x-9)<<8)) /* FCC3 Transmit Clock Source */
+
+#define PC_F1RXCLK PC_CLK(F1_RXCLK)
+#define PC_F1TXCLK PC_CLK(F1_TXCLK)
+#define CMX1_CLK_ROUTE (CMXFCR_RF1CS(F1_RXCLK) | CMXFCR_TF1CS(F1_TXCLK))
+#define CMX1_CLK_MASK ((uint)0xff000000)
+
+#define PC_F2RXCLK PC_CLK(F2_RXCLK)
+#define PC_F2TXCLK PC_CLK(F2_TXCLK)
+#define CMX2_CLK_ROUTE (CMXFCR_RF2CS(F2_RXCLK) | CMXFCR_TF2CS(F2_TXCLK))
+#define CMX2_CLK_MASK ((uint)0x00ff0000)
+
+#define PC_F3RXCLK PC_CLK(F3_RXCLK)
+#define PC_F3TXCLK PC_CLK(F3_TXCLK)
+#define CMX3_CLK_ROUTE (CMXFCR_RF3CS(F3_RXCLK) | CMXFCR_TF3CS(F3_TXCLK))
+#define CMX3_CLK_MASK ((uint)0x0000ff00)
+
+/* I/O Pin assignment for FCC1. I don't yet know the best way to do this,
+ * but there is little variation among the choices.
+ */
+#define PA1_COL 0x00000001U
+#define PA1_CRS 0x00000002U
+#define PA1_TXER 0x00000004U
+#define PA1_TXEN 0x00000008U
+#define PA1_RXDV 0x00000010U
+#define PA1_RXER 0x00000020U
+#define PA1_TXDAT 0x00003c00U
+#define PA1_RXDAT 0x0003c000U
+#define PA1_PSORA0 (PA1_RXDAT | PA1_TXDAT)
+#define PA1_PSORA1 (PA1_COL | PA1_CRS | PA1_TXER | PA1_TXEN | \
+ PA1_RXDV | PA1_RXER)
+#define PA1_DIRA0 (PA1_RXDAT | PA1_CRS | PA1_COL | PA1_RXER | PA1_RXDV)
+#define PA1_DIRA1 (PA1_TXDAT | PA1_TXEN | PA1_TXER)
+
+
+/* I/O Pin assignment for FCC2. I don't yet know the best way to do this,
+ * but there is little variation among the choices.
+ */
+#define PB2_TXER 0x00000001U
+#define PB2_RXDV 0x00000002U
+#define PB2_TXEN 0x00000004U
+#define PB2_RXER 0x00000008U
+#define PB2_COL 0x00000010U
+#define PB2_CRS 0x00000020U
+#define PB2_TXDAT 0x000003c0U
+#define PB2_RXDAT 0x00003c00U
+#define PB2_PSORB0 (PB2_RXDAT | PB2_TXDAT | PB2_CRS | PB2_COL | \
+ PB2_RXER | PB2_RXDV | PB2_TXER)
+#define PB2_PSORB1 (PB2_TXEN)
+#define PB2_DIRB0 (PB2_RXDAT | PB2_CRS | PB2_COL | PB2_RXER | PB2_RXDV)
+#define PB2_DIRB1 (PB2_TXDAT | PB2_TXEN | PB2_TXER)
+
+
+/* I/O Pin assignment for FCC3. I don't yet know the best way to do this,
+ * but there is little variation among the choices.
+ */
+#define PB3_RXDV 0x00004000U
+#define PB3_RXER 0x00008000U
+#define PB3_TXER 0x00010000U
+#define PB3_TXEN 0x00020000U
+#define PB3_COL 0x00040000U
+#define PB3_CRS 0x00080000U
+#define PB3_TXDAT 0x0f000000U
+#define PB3_RXDAT 0x00f00000U
+#define PB3_PSORB0 (PB3_RXDAT | PB3_TXDAT | PB3_CRS | PB3_COL | \
+ PB3_RXER | PB3_RXDV | PB3_TXER | PB3_TXEN)
+#define PB3_PSORB1 0
+#define PB3_DIRB0 (PB3_RXDAT | PB3_CRS | PB3_COL | PB3_RXER | PB3_RXDV)
+#define PB3_DIRB1 (PB3_TXDAT | PB3_TXEN | PB3_TXER)
+
+#define FCC_MEM_OFFSET(x) (CPM_FCC_SPECIAL_BASE + (x*128))
+#define FCC1_MEM_OFFSET FCC_MEM_OFFSET(0)
+#define FCC2_MEM_OFFSET FCC_MEM_OFFSET(1)
+
+#endif
diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
index d06535802003..a0fc628ffb1e 100644
--- a/arch/ppc/platforms/prep_setup.c
+++ b/arch/ppc/platforms/prep_setup.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/setup.c
- *
* Copyright (C) 1995 Linus Torvalds
* Adapted from 'alpha' version by Gary Thomas
* Modified by Cort Dougan (cort@cs.nmt.edu)
diff --git a/arch/ppc/platforms/prpmc750.c b/arch/ppc/platforms/prpmc750.c
index 0bb14a5e824c..cdd9cfb13ee9 100644
--- a/arch/ppc/platforms/prpmc750.c
+++ b/arch/ppc/platforms/prpmc750.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/prpmc750_setup.c
- *
* Board setup routines for Motorola PrPMC750
*
* Author: Matt Porter <mporter@mvista.com>
diff --git a/arch/ppc/platforms/prpmc800.c b/arch/ppc/platforms/prpmc800.c
index de7baefacd3a..e459a199fb1d 100644
--- a/arch/ppc/platforms/prpmc800.c
+++ b/arch/ppc/platforms/prpmc800.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/prpmc800.c
- *
* Author: Dale Farnsworth <dale.farnsworth@mvista.com>
*
* 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
diff --git a/arch/ppc/platforms/radstone_ppc7d.c b/arch/ppc/platforms/radstone_ppc7d.c
index 872c0a3ba3c7..bc26b6d71c1d 100644
--- a/arch/ppc/platforms/radstone_ppc7d.c
+++ b/arch/ppc/platforms/radstone_ppc7d.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/radstone_ppc7d.c
- *
* Board setup routines for the Radstone PPC7D boards.
*
* Author: James Chapman <jchapman@katalix.com>
@@ -685,11 +683,10 @@ ppc7d_fixup_i2c_pdata(struct platform_device *pdev)
pdata = pdev->dev.platform_data;
if (pdata == NULL) {
- pdata = kmalloc(sizeof(*pdata), GFP_KERNEL);
+ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
if (pdata == NULL)
return;
- memset(pdata, 0, sizeof(*pdata));
pdev->dev.platform_data = pdata;
}
@@ -712,7 +709,7 @@ ppc7d_fixup_i2c_pdata(struct platform_device *pdev)
}
#endif
-static int __init ppc7d_platform_notify(struct device *dev)
+static int ppc7d_platform_notify(struct device *dev)
{
static struct {
char *bus_id;
diff --git a/arch/ppc/platforms/radstone_ppc7d.h b/arch/ppc/platforms/radstone_ppc7d.h
index 938375510be4..2bb093a0c03e 100644
--- a/arch/ppc/platforms/radstone_ppc7d.h
+++ b/arch/ppc/platforms/radstone_ppc7d.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/radstone_ppc7d.h
- *
* Board definitions for the Radstone PPC7D boards.
*
* Author: James Chapman <jchapman@katalix.com>
diff --git a/arch/ppc/platforms/sandpoint.c b/arch/ppc/platforms/sandpoint.c
index 9eeed3572309..6dc459decb2d 100644
--- a/arch/ppc/platforms/sandpoint.c
+++ b/arch/ppc/platforms/sandpoint.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/sandpoint_setup.c
- *
* Board setup routines for the Motorola SPS Sandpoint Test Platform.
*
* Author: Mark A. Greer
diff --git a/arch/ppc/platforms/sandpoint.h b/arch/ppc/platforms/sandpoint.h
index f4e982cb69df..3b64e6418489 100644
--- a/arch/ppc/platforms/sandpoint.h
+++ b/arch/ppc/platforms/sandpoint.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/sandpoint.h
- *
* Definitions for Motorola SPS Sandpoint Test Platform
*
* Author: Mark A. Greer
diff --git a/arch/ppc/platforms/sbc82xx.c b/arch/ppc/platforms/sbc82xx.c
index 74c9ff72c3dd..866807b4ad0b 100644
--- a/arch/ppc/platforms/sbc82xx.c
+++ b/arch/ppc/platforms/sbc82xx.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/sbc82xx.c
- *
* SBC82XX platform support
*
* Author: Guy Streeter <streeter@redhat.com>
diff --git a/arch/ppc/platforms/spruce.c b/arch/ppc/platforms/spruce.c
index 69e1de7971f2..3783deccd9b2 100644
--- a/arch/ppc/platforms/spruce.c
+++ b/arch/ppc/platforms/spruce.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/spruce.c
- *
* Board and PCI setup routines for IBM Spruce
*
* Author: MontaVista Software <source@mvista.com>
diff --git a/arch/ppc/platforms/tqm8260_setup.c b/arch/ppc/platforms/tqm8260_setup.c
index 3409139330b1..b766339f44ac 100644
--- a/arch/ppc/platforms/tqm8260_setup.c
+++ b/arch/ppc/platforms/tqm8260_setup.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/tqm8260_setup.c
- *
* TQM8260 platform support
*
* Author: Allen Curtis <acurtis@onz.com>
diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile
index 159dcd92a6d1..5cb62c6a51c8 100644
--- a/arch/ppc/syslib/Makefile
+++ b/arch/ppc/syslib/Makefile
@@ -17,8 +17,8 @@ obj-$(CONFIG_440GX) += ibm440gx_common.o
obj-$(CONFIG_440SP) += ibm440gx_common.o ibm440sp_common.o
obj-$(CONFIG_440SPE) += ibm440gx_common.o ibm440sp_common.o ppc440spe_pcie.o
ifeq ($(CONFIG_4xx),y)
-ifeq ($(CONFIG_VIRTEX_II_PRO),y)
-obj-$(CONFIG_40x) += xilinx_pic.o
+ifeq ($(CONFIG_XILINX_VIRTEX),y)
+obj-$(CONFIG_40x) += xilinx_pic.o ppc_sys.o
else
ifeq ($(CONFIG_403),y)
obj-$(CONFIG_40x) += ppc403_pic.o
diff --git a/arch/ppc/syslib/cpc700.h b/arch/ppc/syslib/cpc700.h
index f2c002531019..0a8a5d84390f 100644
--- a/arch/ppc/syslib/cpc700.h
+++ b/arch/ppc/syslib/cpc700.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/cpc700.h
- *
* Header file for IBM CPC700 Host Bridge, et. al.
*
* Author: Mark A. Greer
diff --git a/arch/ppc/syslib/cpc700_pic.c b/arch/ppc/syslib/cpc700_pic.c
index 75fe8eb10693..5add0a919ef6 100644
--- a/arch/ppc/syslib/cpc700_pic.c
+++ b/arch/ppc/syslib/cpc700_pic.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/cpc700_pic.c
- *
* Interrupt controller support for IBM Spruce
*
* Authors: Mark Greer, Matt Porter, and Johnnie Peters
diff --git a/arch/ppc/syslib/cpc710.h b/arch/ppc/syslib/cpc710.h
index cc0afd804029..5299bf8b5d01 100644
--- a/arch/ppc/syslib/cpc710.h
+++ b/arch/ppc/syslib/cpc710.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/cpc710.h
- *
* Definitions for the IBM CPC710 PCI Host Bridge
*
* Author: Matt Porter <mporter@mvista.com>
diff --git a/arch/ppc/syslib/gen550.h b/arch/ppc/syslib/gen550.h
index 039d249e19a8..5254d3cdbca6 100644
--- a/arch/ppc/syslib/gen550.h
+++ b/arch/ppc/syslib/gen550.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/gen550.h
- *
* gen550 prototypes
*
* Matt Porter <mporter@kernel.crashing.org>
diff --git a/arch/ppc/syslib/gen550_dbg.c b/arch/ppc/syslib/gen550_dbg.c
index 9ef0113c83d1..9fcff74bfdd0 100644
--- a/arch/ppc/syslib/gen550_dbg.c
+++ b/arch/ppc/syslib/gen550_dbg.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/gen550_dbg.c
- *
* A library of polled 16550 serial routines. These are intended to
* be used to support progress messages, xmon, kgdb, etc. on a
* variety of platforms.
diff --git a/arch/ppc/syslib/gen550_kgdb.c b/arch/ppc/syslib/gen550_kgdb.c
index 7239d5d7ddcd..874078a7664d 100644
--- a/arch/ppc/syslib/gen550_kgdb.c
+++ b/arch/ppc/syslib/gen550_kgdb.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/gen550_kgdb.c
- *
* Generic 16550 kgdb support intended to be useful on a variety
* of platforms. To enable this support, it is necessary to set
* the CONFIG_GEN550 option. Any virtual mapping of the serial
diff --git a/arch/ppc/syslib/gt64260_pic.c b/arch/ppc/syslib/gt64260_pic.c
index f97b3a9abd1e..dc3bd9ecbbf6 100644
--- a/arch/ppc/syslib/gt64260_pic.c
+++ b/arch/ppc/syslib/gt64260_pic.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/gt64260_pic.c
- *
* Interrupt controller support for Galileo's GT64260.
*
* Author: Chris Zankel <source@mvista.com>
diff --git a/arch/ppc/syslib/harrier.c b/arch/ppc/syslib/harrier.c
index a6b3f8645793..c1583f488325 100644
--- a/arch/ppc/syslib/harrier.c
+++ b/arch/ppc/syslib/harrier.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/harrier.c
- *
* Motorola MCG Harrier northbridge/memory controller support
*
* Author: Dale Farnsworth
diff --git a/arch/ppc/syslib/hawk_common.c b/arch/ppc/syslib/hawk_common.c
index a9911dc3a82f..c5bf16b0d6a1 100644
--- a/arch/ppc/syslib/hawk_common.c
+++ b/arch/ppc/syslib/hawk_common.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/hawk_common.c
- *
* Common Motorola PowerPlus Platform--really Falcon/Raven or HAWK.
*
* Author: Mark A. Greer
diff --git a/arch/ppc/syslib/ibm440gp_common.c b/arch/ppc/syslib/ibm440gp_common.c
index 0d6be2d6dd67..fbaae5f6d834 100644
--- a/arch/ppc/syslib/ibm440gp_common.c
+++ b/arch/ppc/syslib/ibm440gp_common.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/ibm440gp_common.c
- *
* PPC440GP system library
*
* Matt Porter <mporter@mvista.com>
diff --git a/arch/ppc/syslib/ibm440gp_common.h b/arch/ppc/syslib/ibm440gp_common.h
index a054d83cb1ac..f48529f3c23d 100644
--- a/arch/ppc/syslib/ibm440gp_common.h
+++ b/arch/ppc/syslib/ibm440gp_common.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/ibm440gp_common.h
- *
* PPC440GP system library
*
* Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
diff --git a/arch/ppc/syslib/ibm440gx_common.c b/arch/ppc/syslib/ibm440gx_common.c
index c36db279b43d..a7dd55f1c63e 100644
--- a/arch/ppc/syslib/ibm440gx_common.c
+++ b/arch/ppc/syslib/ibm440gx_common.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/ibm440gx_common.c
- *
* PPC440GX system library
*
* Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
diff --git a/arch/ppc/syslib/ibm440gx_common.h b/arch/ppc/syslib/ibm440gx_common.h
index e73aa0411d35..a2ab9fab8e34 100644
--- a/arch/ppc/syslib/ibm440gx_common.h
+++ b/arch/ppc/syslib/ibm440gx_common.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/ibm440gx_common.h
- *
* PPC440GX system library
*
* Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
diff --git a/arch/ppc/syslib/ibm440sp_common.c b/arch/ppc/syslib/ibm440sp_common.c
index cdafda127d81..293e4138d172 100644
--- a/arch/ppc/syslib/ibm440sp_common.c
+++ b/arch/ppc/syslib/ibm440sp_common.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/ibm440sp_common.c
- *
* PPC440SP/PPC440SPe system library
*
* Matt Porter <mporter@kernel.crashing.org>
diff --git a/arch/ppc/syslib/ibm440sp_common.h b/arch/ppc/syslib/ibm440sp_common.h
index a21a9906dcc9..8077bf8ed118 100644
--- a/arch/ppc/syslib/ibm440sp_common.h
+++ b/arch/ppc/syslib/ibm440sp_common.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/ibm440sp_common.h
- *
* PPC440SP system library
*
* Matt Porter <mporter@kernel.crashing.org>
diff --git a/arch/ppc/syslib/ibm44x_common.c b/arch/ppc/syslib/ibm44x_common.c
index 71db11d22158..14a981a5cea7 100644
--- a/arch/ppc/syslib/ibm44x_common.c
+++ b/arch/ppc/syslib/ibm44x_common.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/ibm44x_common.c
- *
* PPC44x system library
*
* Matt Porter <mporter@kernel.crashing.org>
diff --git a/arch/ppc/syslib/ibm44x_common.h b/arch/ppc/syslib/ibm44x_common.h
index b25a8995e4e9..f179db8634e0 100644
--- a/arch/ppc/syslib/ibm44x_common.h
+++ b/arch/ppc/syslib/ibm44x_common.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/ibm44x_common.h
- *
* PPC44x system library
*
* Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
diff --git a/arch/ppc/syslib/m8260_pci_erratum9.c b/arch/ppc/syslib/m8260_pci_erratum9.c
index 1dc7e4e1d491..99e4bc0e42af 100644
--- a/arch/ppc/syslib/m8260_pci_erratum9.c
+++ b/arch/ppc/syslib/m8260_pci_erratum9.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/mpc8260_pci9.c
- *
* Workaround for device erratum PCI 9.
* See Motorola's "XPC826xA Family Device Errata Reference."
* The erratum applies to all 8260 family Hip4 processors. It is scheduled
diff --git a/arch/ppc/syslib/m8260_setup.c b/arch/ppc/syslib/m8260_setup.c
index 76a2aa4ce65e..b7a6cb2d8d52 100644
--- a/arch/ppc/syslib/m8260_setup.c
+++ b/arch/ppc/syslib/m8260_setup.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/m8260_setup.c
- *
* Copyright (C) 1995 Linus Torvalds
* Adapted from 'alpha' version by Gary Thomas
* Modified by Cort Dougan (cort@cs.nmt.edu)
diff --git a/arch/ppc/syslib/m8xx_setup.c b/arch/ppc/syslib/m8xx_setup.c
index 688616de3cde..dae9af78bde1 100644
--- a/arch/ppc/syslib/m8xx_setup.c
+++ b/arch/ppc/syslib/m8xx_setup.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/setup.c
- *
* Copyright (C) 1995 Linus Torvalds
* Adapted from 'alpha' version by Gary Thomas
* Modified by Cort Dougan (cort@cs.nmt.edu)
@@ -34,6 +32,13 @@
#include <linux/seq_file.h>
#include <linux/root_dev.h>
+#if defined(CONFIG_MTD) && defined(CONFIG_MTD_PHYSMAP)
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#endif
+
#include <asm/mmu.h>
#include <asm/reg.h>
#include <asm/residual.h>
@@ -49,6 +54,34 @@
#include "ppc8xx_pic.h"
+#ifdef CONFIG_MTD_PHYSMAP
+#define MPC8xxADS_BANK_WIDTH 4
+#endif
+
+#define MPC8xxADS_U_BOOT_SIZE 0x80000
+#define MPC8xxADS_FREE_AREA_OFFSET MPC8xxADS_U_BOOT_SIZE
+
+#if defined(CONFIG_MTD_PARTITIONS)
+ /*
+ NOTE: bank width and interleave relative to the installed flash
+ should have been chosen within MTD_CFI_GEOMETRY options.
+ */
+static struct mtd_partition mpc8xxads_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = MPC8xxADS_U_BOOT_SIZE,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "User FS",
+ .offset = MPC8xxADS_FREE_AREA_OFFSET
+ }
+};
+
+#define mpc8xxads_part_num (sizeof (mpc8xxads_partitions) / sizeof (mpc8xxads_partitions[0]))
+
+#endif
+
static int m8xx_set_rtc_time(unsigned long time);
static unsigned long m8xx_get_rtc_time(void);
void m8xx_calibrate_decr(void);
@@ -71,6 +104,10 @@ board_init(void)
void __init
m8xx_setup_arch(void)
{
+#if defined(CONFIG_MTD) && defined(CONFIG_MTD_PHYSMAP)
+ bd_t *binfo = (bd_t *)__res;
+#endif
+
/* Reset the Communication Processor Module.
*/
m8xx_cpm_reset();
@@ -106,6 +143,17 @@ m8xx_setup_arch(void)
}
#endif
#endif
+
+#if defined (CONFIG_MPC86XADS) || defined (CONFIG_MPC885ADS)
+#if defined(CONFIG_MTD_PHYSMAP)
+ physmap_configure(binfo->bi_flashstart, binfo->bi_flashsize,
+ MPC8xxADS_BANK_WIDTH, NULL);
+#ifdef CONFIG_MTD_PARTITIONS
+ physmap_set_partitions(mpc8xxads_partitions, mpc8xxads_part_num);
+#endif /* CONFIG_MTD_PARTITIONS */
+#endif /* CONFIG_MTD_PHYSMAP */
+#endif
+
board_init();
}
@@ -140,9 +188,11 @@ void __init __attribute__ ((weak))
init_internal_rtc(void)
{
/* Disable the RTC one second and alarm interrupts. */
- out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) & ~(RTCSC_SIE | RTCSC_ALE));
+ clrbits16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, (RTCSC_SIE | RTCSC_ALE));
+
/* Enable the RTC */
- out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) | (RTCSC_RTF | RTCSC_RTE));
+ setbits16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, (RTCSC_RTF | RTCSC_RTE));
+
}
/* The decrementer counts at the system (internal) clock frequency divided by
@@ -159,8 +209,7 @@ void __init m8xx_calibrate_decr(void)
out_be32(&((immap_t *)IMAP_ADDR)->im_clkrstk.cark_sccrk, KAPWR_KEY);
/* Force all 8xx processors to use divide by 16 processor clock. */
- out_be32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_sccr,
- in_be32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_sccr)|0x02000000);
+ setbits32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_sccr, 0x02000000);
/* Processor frequency is MHz.
* The value 'fp' is the number of decrementer ticks per second.
*/
@@ -239,8 +288,8 @@ m8xx_restart(char *cmd)
__volatile__ unsigned char dummy;
local_irq_disable();
- out_be32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr, in_be32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr) | 0x00000080);
+ setbits32(&((immap_t *)IMAP_ADDR)->im_clkrst.car_plprcr, 0x00000080);
/* Clear the ME bit in MSR to cause checkstop on machine check
*/
mtmsr(mfmsr() & ~0x1000);
@@ -310,8 +359,8 @@ m8xx_init_IRQ(void)
i8259_init(0);
/* The i8259 cascade interrupt must be level sensitive. */
- out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel, in_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel & ~(0x80000000 >> ISA_BRIDGE_INT)));
+ clrbits32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel, (0x80000000 >> ISA_BRIDGE_INT));
if (setup_irq(ISA_BRIDGE_INT, &mbx_i8259_irqaction))
enable_irq(ISA_BRIDGE_INT);
#endif /* CONFIG_PCI */
diff --git a/arch/ppc/syslib/m8xx_wdt.c b/arch/ppc/syslib/m8xx_wdt.c
index df6c9557b86a..ac11d7bab443 100644
--- a/arch/ppc/syslib/m8xx_wdt.c
+++ b/arch/ppc/syslib/m8xx_wdt.c
@@ -41,8 +41,7 @@ static irqreturn_t m8xx_wdt_interrupt(int irq, void *dev, struct pt_regs *regs)
m8xx_wdt_reset();
- out_be16(&imap->im_sit.sit_piscr, in_be16(&imap->im_sit.sit_piscr) | PISCR_PS); /* clear irq */
-
+ setbits16(&imap->im_sit.sit_piscr, PISCR_PS);
return IRQ_HANDLED;
}
diff --git a/arch/ppc/syslib/mpc10x_common.c b/arch/ppc/syslib/mpc10x_common.c
index 3e039706bdbc..2fc7c4150a18 100644
--- a/arch/ppc/syslib/mpc10x_common.c
+++ b/arch/ppc/syslib/mpc10x_common.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/mpc10x_common.c
- *
* Common routines for the Motorola SPS MPC106, MPC107 and MPC8240 Host bridge,
* Mem ctlr, EPIC, etc.
*
diff --git a/arch/ppc/syslib/mpc52xx_devices.c b/arch/ppc/syslib/mpc52xx_devices.c
index da3c74bfdc92..7487539a4e92 100644
--- a/arch/ppc/syslib/mpc52xx_devices.c
+++ b/arch/ppc/syslib/mpc52xx_devices.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/mpc52xx_devices.c
- *
* Freescale MPC52xx device descriptions
*
*
diff --git a/arch/ppc/syslib/mpc52xx_pci.c b/arch/ppc/syslib/mpc52xx_pci.c
index 313c96ec7eb1..9ec525f9fe98 100644
--- a/arch/ppc/syslib/mpc52xx_pci.c
+++ b/arch/ppc/syslib/mpc52xx_pci.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/mpc52xx_pci.c
- *
* PCI code for the Freescale MPC52xx embedded CPU.
*
*
diff --git a/arch/ppc/syslib/mpc52xx_pci.h b/arch/ppc/syslib/mpc52xx_pci.h
index 04b509a02530..77d47dbba85e 100644
--- a/arch/ppc/syslib/mpc52xx_pci.h
+++ b/arch/ppc/syslib/mpc52xx_pci.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/mpc52xx_pci.h
- *
* PCI Include file the Freescale MPC52xx embedded cpu chips
*
*
diff --git a/arch/ppc/syslib/mpc52xx_pic.c b/arch/ppc/syslib/mpc52xx_pic.c
index 4c4497e62517..c4406f9dc6a3 100644
--- a/arch/ppc/syslib/mpc52xx_pic.c
+++ b/arch/ppc/syslib/mpc52xx_pic.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/mpc52xx_pic.c
- *
* Programmable Interrupt Controller functions for the Freescale MPC52xx
* embedded CPU.
*
diff --git a/arch/ppc/syslib/mpc52xx_setup.c b/arch/ppc/syslib/mpc52xx_setup.c
index a4a4b02227df..2ee48ce0a517 100644
--- a/arch/ppc/syslib/mpc52xx_setup.c
+++ b/arch/ppc/syslib/mpc52xx_setup.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/mpc52xx_setup.c
- *
* Common code for the boards based on Freescale MPC52xx embedded CPU.
*
*
diff --git a/arch/ppc/syslib/mpc52xx_sys.c b/arch/ppc/syslib/mpc52xx_sys.c
index 9a0f90aa8aac..b4e6f978f057 100644
--- a/arch/ppc/syslib/mpc52xx_sys.c
+++ b/arch/ppc/syslib/mpc52xx_sys.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/mpc52xx_sys.c
- *
* Freescale MPC52xx system descriptions
*
*
diff --git a/arch/ppc/syslib/mpc83xx_devices.c b/arch/ppc/syslib/mpc83xx_devices.c
index f9b95de70e23..1af2c000fcfa 100644
--- a/arch/ppc/syslib/mpc83xx_devices.c
+++ b/arch/ppc/syslib/mpc83xx_devices.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/83xx/mpc83xx_devices.c
- *
* MPC83xx Device descriptions
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/syslib/mpc83xx_sys.c b/arch/ppc/syslib/mpc83xx_sys.c
index 82cf3ab77f4a..0498ae7e01e3 100644
--- a/arch/ppc/syslib/mpc83xx_sys.c
+++ b/arch/ppc/syslib/mpc83xx_sys.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/83xx/mpc83xx_sys.c
- *
* MPC83xx System descriptions
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/syslib/mpc85xx_devices.c b/arch/ppc/syslib/mpc85xx_devices.c
index 00e9b6ff2f6e..7735336f5b8f 100644
--- a/arch/ppc/syslib/mpc85xx_devices.c
+++ b/arch/ppc/syslib/mpc85xx_devices.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/85xx/mpc85xx_devices.c
- *
* MPC85xx Device descriptions
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/syslib/mpc85xx_sys.c b/arch/ppc/syslib/mpc85xx_sys.c
index 397cfbcce5ea..d96a93dbcb5a 100644
--- a/arch/ppc/syslib/mpc85xx_sys.c
+++ b/arch/ppc/syslib/mpc85xx_sys.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/85xx/mpc85xx_sys.c
- *
* MPC85xx System descriptions
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/syslib/mpc8xx_devices.c b/arch/ppc/syslib/mpc8xx_devices.c
index 92dc98b36bde..bd41ed83beb3 100644
--- a/arch/ppc/syslib/mpc8xx_devices.c
+++ b/arch/ppc/syslib/mpc8xx_devices.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/mpc8xx_devices.c
- *
* MPC8xx Device descriptions
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/syslib/mpc8xx_sys.c b/arch/ppc/syslib/mpc8xx_sys.c
index d3c617521603..eee213284855 100644
--- a/arch/ppc/syslib/mpc8xx_sys.c
+++ b/arch/ppc/syslib/mpc8xx_sys.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/platforms/mpc8xx_sys.c
- *
* MPC8xx System descriptions
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/syslib/mv64360_pic.c b/arch/ppc/syslib/mv64360_pic.c
index 58b0aa813e85..5a19697060f0 100644
--- a/arch/ppc/syslib/mv64360_pic.c
+++ b/arch/ppc/syslib/mv64360_pic.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/mv64360_pic.c
- *
* Interrupt controller support for Marvell's MV64360.
*
* Author: Rabeeh Khoury <rabeeh@galileo.co.il>
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c
index 1f01b7e2376b..3b039c30a439 100644
--- a/arch/ppc/syslib/mv64x60.c
+++ b/arch/ppc/syslib/mv64x60.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/mv64x60.c
- *
* Common routines for the Marvell/Galileo Discovery line of host bridges
* (gt64260, mv64360, mv64460, ...).
*
diff --git a/arch/ppc/syslib/mv64x60_dbg.c b/arch/ppc/syslib/mv64x60_dbg.c
index fa5b2e45e0ca..9cf18764a1a1 100644
--- a/arch/ppc/syslib/mv64x60_dbg.c
+++ b/arch/ppc/syslib/mv64x60_dbg.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/mv64x60_dbg.c
- *
* KGDB and progress routines for the Marvell/Galileo MV64x60 (Discovery).
*
* Author: Mark A. Greer <mgreer@mvista.com>
diff --git a/arch/ppc/syslib/mv64x60_win.c b/arch/ppc/syslib/mv64x60_win.c
index 5b827e2bbe22..4bf1ad17bf1a 100644
--- a/arch/ppc/syslib/mv64x60_win.c
+++ b/arch/ppc/syslib/mv64x60_win.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/mv64x60_win.c
- *
* Tables with info on how to manipulate the 32 & 64 bit windows on the
* various types of Marvell bridge chips.
*
diff --git a/arch/ppc/syslib/ocp.c b/arch/ppc/syslib/ocp.c
index 2fe28ded2c60..a4ecc2ee579f 100644
--- a/arch/ppc/syslib/ocp.c
+++ b/arch/ppc/syslib/ocp.c
@@ -451,10 +451,9 @@ ocp_driver_init(void)
DBG(("ocp: ocp_driver_init()...\n"));
/* Allocate/register primary OCP bus */
- ocp_bus = kmalloc(sizeof(struct device), GFP_KERNEL);
+ ocp_bus = kzalloc(sizeof(struct device), GFP_KERNEL);
if (ocp_bus == NULL)
return 1;
- memset(ocp_bus, 0, sizeof(struct device));
strcpy(ocp_bus->bus_id, "ocp");
bus_register(&ocp_bus_type);
diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c
index 894779712b46..38e5b93fbe41 100644
--- a/arch/ppc/syslib/open_pic.c
+++ b/arch/ppc/syslib/open_pic.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/open_pic.c -- OpenPIC Interrupt Handling
- *
* Copyright (C) 1997 Geert Uytterhoeven
*
* This file is subject to the terms and conditions of the GNU General Public
diff --git a/arch/ppc/syslib/open_pic2.c b/arch/ppc/syslib/open_pic2.c
index 1c40049b9a45..bcbe40de26fe 100644
--- a/arch/ppc/syslib/open_pic2.c
+++ b/arch/ppc/syslib/open_pic2.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/open_pic.c -- OpenPIC Interrupt Handling
- *
* Copyright (C) 1997 Geert Uytterhoeven
*
* This file is subject to the terms and conditions of the GNU General Public
diff --git a/arch/ppc/syslib/open_pic_defs.h b/arch/ppc/syslib/open_pic_defs.h
index 6c94e7131463..3a25de7cb572 100644
--- a/arch/ppc/syslib/open_pic_defs.h
+++ b/arch/ppc/syslib/open_pic_defs.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/open_pic_defs.h -- OpenPIC definitions
- *
* Copyright (C) 1997 Geert Uytterhoeven
*
* This file is based on the following documentation:
diff --git a/arch/ppc/syslib/pci_auto.c b/arch/ppc/syslib/pci_auto.c
index d64207c2a972..ee20a86fcc4b 100644
--- a/arch/ppc/syslib/pci_auto.c
+++ b/arch/ppc/syslib/pci_auto.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/pci_auto.c
- *
* PCI autoconfiguration library
*
* Author: Matt Porter <mporter@mvista.com>
diff --git a/arch/ppc/syslib/ppc4xx_dma.c b/arch/ppc/syslib/ppc4xx_dma.c
index 05ccd598dd4e..b40b96a8c609 100644
--- a/arch/ppc/syslib/ppc4xx_dma.c
+++ b/arch/ppc/syslib/ppc4xx_dma.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/ppc4xx_dma.c
- *
* IBM PPC4xx DMA engine core library
*
* Copyright 2000-2004 MontaVista Software Inc.
diff --git a/arch/ppc/syslib/ppc4xx_pic.c b/arch/ppc/syslib/ppc4xx_pic.c
index aa4165144ec2..fd9af0fc0e9f 100644
--- a/arch/ppc/syslib/ppc4xx_pic.c
+++ b/arch/ppc/syslib/ppc4xx_pic.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/ppc4xx_pic.c
- *
* Interrupt controller driver for PowerPC 4xx-based processors.
*
* Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
diff --git a/arch/ppc/syslib/ppc4xx_pm.c b/arch/ppc/syslib/ppc4xx_pm.c
deleted file mode 100644
index 60a479204885..000000000000
--- a/arch/ppc/syslib/ppc4xx_pm.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Author: Armin Kuster <akuster@mvista.com>
- *
- * 2002 (c) MontaVista, Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- *
- * This an attempt to get Power Management going for the IBM 4xx processor.
- * This was derived from the ppc4xx._setup.c file
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-
-#include <asm/ibm4xx.h>
-
-void __init
-ppc4xx_pm_init(void)
-{
-
- unsigned int value = 0;
-
- /* turn off unused hardware to save power */
-#ifdef CONFIG_405GP
- value |= CPM_DCP; /* CodePack */
-#endif
-
-#if !defined(CONFIG_IBM_OCP_GPIO)
- value |= CPM_GPIO0;
-#endif
-
-#if !defined(CONFIG_PPC405_I2C_ADAP)
- value |= CPM_IIC0;
-#ifdef CONFIG_STB03xxx
- value |= CPM_IIC1;
-#endif
-#endif
-
-
-#if !defined(CONFIG_405_DMA)
- value |= CPM_DMA;
-#endif
-
- mtdcr(DCRN_CPMFR, value);
-
-}
diff --git a/arch/ppc/syslib/ppc4xx_sgdma.c b/arch/ppc/syslib/ppc4xx_sgdma.c
index 9f76e8ee39ed..280ea010a9c8 100644
--- a/arch/ppc/syslib/ppc4xx_sgdma.c
+++ b/arch/ppc/syslib/ppc4xx_sgdma.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/ppc4xx_sgdma.c
- *
* IBM PPC4xx DMA engine scatter/gather library
*
* Copyright 2002-2003 MontaVista Software Inc.
diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ppc83xx_setup.c
index 7bada82527a8..26afd637dc81 100644
--- a/arch/ppc/syslib/ppc83xx_setup.c
+++ b/arch/ppc/syslib/ppc83xx_setup.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/ppc83xx_setup.c
- *
* MPC83XX common board code
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/syslib/ppc83xx_setup.h b/arch/ppc/syslib/ppc83xx_setup.h
index a122a7322e5e..478b011cd963 100644
--- a/arch/ppc/syslib/ppc83xx_setup.h
+++ b/arch/ppc/syslib/ppc83xx_setup.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/ppc83xx_setup.h
- *
* MPC83XX common board definitions
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/syslib/ppc85xx_common.c b/arch/ppc/syslib/ppc85xx_common.c
index 19ad537225e4..0145c968f9ad 100644
--- a/arch/ppc/syslib/ppc85xx_common.c
+++ b/arch/ppc/syslib/ppc85xx_common.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/ppc85xx_common.c
- *
* MPC85xx support routines
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/syslib/ppc85xx_common.h b/arch/ppc/syslib/ppc85xx_common.h
index 94edf32151dd..182744a1321c 100644
--- a/arch/ppc/syslib/ppc85xx_common.h
+++ b/arch/ppc/syslib/ppc85xx_common.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/ppc85xx_common.h
- *
* MPC85xx support routines
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c
index e4dda43fdaa7..e70b34ee6275 100644
--- a/arch/ppc/syslib/ppc85xx_setup.c
+++ b/arch/ppc/syslib/ppc85xx_setup.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/ppc85xx_setup.c
- *
* MPC85XX common board code
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/syslib/ppc85xx_setup.h b/arch/ppc/syslib/ppc85xx_setup.h
index e340b0545fb5..f55b8032d3d9 100644
--- a/arch/ppc/syslib/ppc85xx_setup.h
+++ b/arch/ppc/syslib/ppc85xx_setup.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/ppc85xx_setup.h
- *
* MPC85XX common board definitions
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
index c0b93c4191ee..60c724e11584 100644
--- a/arch/ppc/syslib/ppc_sys.c
+++ b/arch/ppc/syslib/ppc_sys.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/ppc_sys.c
- *
* PPC System library functions
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
@@ -15,11 +13,22 @@
*/
#include <linux/string.h>
+#include <linux/bootmem.h>
#include <asm/ppc_sys.h>
int (*ppc_sys_device_fixup) (struct platform_device * pdev);
static int ppc_sys_inited;
+static int ppc_sys_func_inited;
+
+static const char *ppc_sys_func_names[] = {
+ [PPC_SYS_FUNC_DUMMY] = "dummy",
+ [PPC_SYS_FUNC_ETH] = "eth",
+ [PPC_SYS_FUNC_UART] = "uart",
+ [PPC_SYS_FUNC_HLDC] = "hldc",
+ [PPC_SYS_FUNC_USB] = "usb",
+ [PPC_SYS_FUNC_IRDA] = "irda",
+};
void __init identify_ppc_sys_by_id(u32 id)
{
@@ -38,13 +47,13 @@ void __init identify_ppc_sys_by_id(u32 id)
void __init identify_ppc_sys_by_name(char *name)
{
unsigned int i = 0;
- while (ppc_sys_specs[i].ppc_sys_name[0])
- {
+ while (ppc_sys_specs[i].ppc_sys_name[0]) {
if (!strcmp(ppc_sys_specs[i].ppc_sys_name, name))
break;
i++;
}
cur_ppc_sys_spec = &ppc_sys_specs[i];
+
return;
}
@@ -128,6 +137,165 @@ void ppc_sys_device_remove(enum ppc_sys_devices dev)
}
}
+/* Platform-notify mapping
+ * Helper function for BSP code to assign board-specific platfom-divice bits
+ */
+
+void platform_notify_map(const struct platform_notify_dev_map *map,
+ struct device *dev)
+{
+ struct platform_device *pdev;
+ int len, idx;
+ const char *s;
+
+ /* do nothing if no device or no bus_id */
+ if (!dev || !dev->bus_id)
+ return;
+
+ /* call per device map */
+ while (map->bus_id != NULL) {
+ idx = -1;
+ s = strrchr(dev->bus_id, '.');
+ if (s != NULL)
+ idx = (int)simple_strtol(s + 1, NULL, 10);
+ else
+ s = dev->bus_id;
+
+ len = s - dev->bus_id;
+
+ if (!strncmp(dev->bus_id, map->bus_id, len)) {
+ pdev = container_of(dev, struct platform_device, dev);
+ map->rtn(pdev, idx);
+ }
+ map++;
+ }
+}
+
+/*
+ Function assignment stuff.
+ Intended to work as follows:
+ the device name defined in foo_devices.c will be concatenated with :"func",
+ where func is string map of respective function from platfom_device_func enum
+
+ The PPC_SYS_FUNC_DUMMY function is intended to remove all assignments, making the device to appear
+ in platform bus with unmodified name.
+ */
+
+/*
+ Here we'll replace .name pointers with fixed-lenght strings
+ Hereby, this should be called *before* any func stuff triggeded.
+ */
+void ppc_sys_device_initfunc(void)
+{
+ int i;
+ const char *name;
+ static char new_names[NUM_PPC_SYS_DEVS][BUS_ID_SIZE];
+ enum ppc_sys_devices cur_dev;
+
+ /* If inited yet, do nothing */
+ if (ppc_sys_func_inited)
+ return;
+
+ for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
+ if ((cur_dev = cur_ppc_sys_spec->device_list[i]) < 0)
+ continue;
+
+ if (ppc_sys_platform_devices[cur_dev].name) {
+ /*backup name */
+ name = ppc_sys_platform_devices[cur_dev].name;
+ strlcpy(new_names[i], name, BUS_ID_SIZE);
+ ppc_sys_platform_devices[cur_dev].name = new_names[i];
+ }
+ }
+
+ ppc_sys_func_inited = 1;
+}
+
+/*The "engine" of the func stuff. Here we either concat specified function string description
+ to the name, or remove it if PPC_SYS_FUNC_DUMMY parameter is passed here*/
+void ppc_sys_device_setfunc(enum ppc_sys_devices dev,
+ enum platform_device_func func)
+{
+ char *s;
+ char *name = (char *)ppc_sys_platform_devices[dev].name;
+ char tmp[BUS_ID_SIZE];
+
+ if (!ppc_sys_func_inited) {
+ printk(KERN_ERR "Unable to alter function - not inited!\n");
+ return;
+ }
+
+ if (ppc_sys_inited) {
+ platform_device_unregister(&ppc_sys_platform_devices[dev]);
+ }
+
+ if ((s = (char *)strchr(name, ':')) != NULL) { /* reassign */
+ /* Either change the name after ':' or remove func modifications */
+ if (func != PPC_SYS_FUNC_DUMMY)
+ strlcpy(s + 1, ppc_sys_func_names[func], BUS_ID_SIZE);
+ else
+ *s = 0;
+ } else if (func != PPC_SYS_FUNC_DUMMY) {
+ /* do assignment if it is not just "clear" request */
+ sprintf(tmp, "%s:%s", name, ppc_sys_func_names[func]);
+ strlcpy(name, tmp, BUS_ID_SIZE);
+ }
+
+ if (ppc_sys_inited) {
+ platform_device_register(&ppc_sys_platform_devices[dev]);
+ }
+}
+
+void ppc_sys_device_disable(enum ppc_sys_devices dev)
+{
+ BUG_ON(cur_ppc_sys_spec == NULL);
+
+ /*Check if it is enabled*/
+ if(!(cur_ppc_sys_spec->config[dev] & PPC_SYS_CONFIG_DISABLED)) {
+ if (ppc_sys_inited) {
+ platform_device_unregister(&ppc_sys_platform_devices[dev]);
+ }
+ cur_ppc_sys_spec->config[dev] |= PPC_SYS_CONFIG_DISABLED;
+ }
+}
+
+void ppc_sys_device_enable(enum ppc_sys_devices dev)
+{
+ BUG_ON(cur_ppc_sys_spec == NULL);
+
+ /*Check if it is disabled*/
+ if(cur_ppc_sys_spec->config[dev] & PPC_SYS_CONFIG_DISABLED) {
+ if (ppc_sys_inited) {
+ platform_device_register(&ppc_sys_platform_devices[dev]);
+ }
+ cur_ppc_sys_spec->config[dev] &= ~PPC_SYS_CONFIG_DISABLED;
+ }
+
+}
+
+void ppc_sys_device_enable_all(void)
+{
+ enum ppc_sys_devices cur_dev;
+ int i;
+
+ for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
+ cur_dev = cur_ppc_sys_spec->device_list[i];
+ ppc_sys_device_enable(cur_dev);
+ }
+}
+
+void ppc_sys_device_disable_all(void)
+{
+ enum ppc_sys_devices cur_dev;
+ int i;
+
+ for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
+ cur_dev = cur_ppc_sys_spec->device_list[i];
+ ppc_sys_device_disable(cur_dev);
+ }
+}
+
+
static int __init ppc_sys_init(void)
{
unsigned int i, dev_id, ret = 0;
@@ -136,7 +304,8 @@ static int __init ppc_sys_init(void)
for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
dev_id = cur_ppc_sys_spec->device_list[i];
- if (dev_id != -1) {
+ if ((dev_id != -1) &&
+ !(cur_ppc_sys_spec->config[dev_id] & PPC_SYS_CONFIG_DISABLED)) {
if (ppc_sys_device_fixup != NULL)
ppc_sys_device_fixup(&ppc_sys_platform_devices
[dev_id]);
diff --git a/arch/ppc/syslib/pq2_devices.c b/arch/ppc/syslib/pq2_devices.c
index 6ff3aab82fc3..0636aed7b827 100644
--- a/arch/ppc/syslib/pq2_devices.c
+++ b/arch/ppc/syslib/pq2_devices.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/pq2_devices.c
- *
* PQ2 Device descriptions
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/syslib/pq2_sys.c b/arch/ppc/syslib/pq2_sys.c
index 36d6e2179940..75e64f1c144d 100644
--- a/arch/ppc/syslib/pq2_sys.c
+++ b/arch/ppc/syslib/pq2_sys.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/pq2_devices.c
- *
* PQ2 System descriptions
*
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
diff --git a/arch/ppc/syslib/prep_nvram.c b/arch/ppc/syslib/prep_nvram.c
index 2c6364d9641f..474dccbc4a8a 100644
--- a/arch/ppc/syslib/prep_nvram.c
+++ b/arch/ppc/syslib/prep_nvram.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/prep_nvram.c
- *
* Copyright (C) 1998 Corey Minyard
*
* This reads the NvRAM on PReP compliant machines (generally from IBM or
diff --git a/arch/ppc/syslib/todc_time.c b/arch/ppc/syslib/todc_time.c
index 1323c641c19d..a8168b8e5683 100644
--- a/arch/ppc/syslib/todc_time.c
+++ b/arch/ppc/syslib/todc_time.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/todc_time.c
- *
* Time of Day Clock support for the M48T35, M48T37, M48T59, and MC146818
* Real Time Clocks/Timekeepers.
*
diff --git a/arch/ppc/syslib/xilinx_pic.c b/arch/ppc/syslib/xilinx_pic.c
index 47f04c71fe9c..e672b600f315 100644
--- a/arch/ppc/syslib/xilinx_pic.c
+++ b/arch/ppc/syslib/xilinx_pic.c
@@ -1,6 +1,4 @@
/*
- * arch/ppc/syslib/xilinx_pic.c
- *
* Interrupt controller driver for Xilinx Virtex-II Pro.
*
* Author: MontaVista Software, Inc.
@@ -15,7 +13,7 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/io.h>
-#include <asm/xparameters.h>
+#include <platforms/4xx/xparameters/xparameters.h>
#include <asm/ibm4xx.h>
#include <asm/machdep.h>
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 7dbe00c76c6b..d52d6d211d9f 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -799,9 +799,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
*/
print_cpu_info(&S390_lowcore.cpu_data);
- for(i = 0; i < NR_CPUS; i++) {
- if (!cpu_possible(i))
- continue;
+ for_each_cpu(i) {
lowcore_ptr[i] = (struct _lowcore *)
__get_free_pages(GFP_KERNEL|GFP_DMA,
sizeof(void*) == 8 ? 1 : 0);
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index 6883c00728cb..b56e79632f24 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -35,9 +35,8 @@ int show_interrupts(struct seq_file *p, void *v)
if (i == 0) {
seq_puts(p, " ");
- for (j=0; j<NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "CPU%d ",j);
+ for_each_online_cpu(j)
+ seq_printf(p, "CPU%d ",j);
seq_putc(p, '\n');
}
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index a067a34e0b64..c0e79843f580 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -404,9 +404,8 @@ static int __init topology_init(void)
{
int cpu_id;
- for (cpu_id = 0; cpu_id < NR_CPUS; cpu_id++)
- if (cpu_possible(cpu_id))
- register_cpu(&cpu[cpu_id], cpu_id, NULL);
+ for_each_cpu(cpu_id)
+ register_cpu(&cpu[cpu_id], cpu_id, NULL);
return 0;
}
diff --git a/arch/sh64/kernel/irq.c b/arch/sh64/kernel/irq.c
index 9fc2b71dbd84..d69879c0e063 100644
--- a/arch/sh64/kernel/irq.c
+++ b/arch/sh64/kernel/irq.c
@@ -53,9 +53,8 @@ int show_interrupts(struct seq_file *p, void *v)
if (i == 0) {
seq_puts(p, " ");
- for (j=0; j<NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "CPU%d ",j);
+ for_each_online_cpu(j)
+ seq_printf(p, "CPU%d ",j);
seq_putc(p, '\n');
}
diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
index 410b9a72aba9..4c60a6ef54a9 100644
--- a/arch/sparc/kernel/irq.c
+++ b/arch/sparc/kernel/irq.c
@@ -184,9 +184,8 @@ int show_interrupts(struct seq_file *p, void *v)
#ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i));
#else
- for (j = 0; j < NR_CPUS; j++) {
- if (cpu_online(j))
- seq_printf(p, "%10u ",
+ for_each_online_cpu(j) {
+ seq_printf(p, "%10u ",
kstat_cpu(cpu_logical_map(j)).irqs[i]);
}
#endif
diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c
index c6e721d8f477..ea5682ce7031 100644
--- a/arch/sparc/kernel/smp.c
+++ b/arch/sparc/kernel/smp.c
@@ -243,9 +243,8 @@ int setup_profiling_timer(unsigned int multiplier)
return -EINVAL;
spin_lock_irqsave(&prof_setup_lock, flags);
- for(i = 0; i < NR_CPUS; i++) {
- if (cpu_possible(i))
- load_profile_irq(i, lvl14_resolution / multiplier);
+ for_each_cpu(i) {
+ load_profile_irq(i, lvl14_resolution / multiplier);
prof_multiplier(i) = multiplier;
}
spin_unlock_irqrestore(&prof_setup_lock, flags);
@@ -273,13 +272,12 @@ void smp_bogo(struct seq_file *m)
{
int i;
- for (i = 0; i < NR_CPUS; i++) {
- if (cpu_online(i))
- seq_printf(m,
- "Cpu%dBogo\t: %lu.%02lu\n",
- i,
- cpu_data(i).udelay_val/(500000/HZ),
- (cpu_data(i).udelay_val/(5000/HZ))%100);
+ for_each_online_cpu(i) {
+ seq_printf(m,
+ "Cpu%dBogo\t: %lu.%02lu\n",
+ i,
+ cpu_data(i).udelay_val/(500000/HZ),
+ (cpu_data(i).udelay_val/(5000/HZ))%100);
}
}
@@ -288,8 +286,6 @@ void smp_info(struct seq_file *m)
int i;
seq_printf(m, "State:\n");
- for (i = 0; i < NR_CPUS; i++) {
- if (cpu_online(i))
- seq_printf(m, "CPU%d\t\t: online\n", i);
- }
+ for_each_online_cpu(i)
+ seq_printf(m, "CPU%d\t\t: online\n", i);
}
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
index 52621348a56c..cea7fc6fc6e5 100644
--- a/arch/sparc/kernel/sun4d_irq.c
+++ b/arch/sparc/kernel/sun4d_irq.c
@@ -103,11 +103,9 @@ found_it: seq_printf(p, "%3d: ", i);
#ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i));
#else
- for (x = 0; x < NR_CPUS; x++) {
- if (cpu_online(x))
- seq_printf(p, "%10u ",
- kstat_cpu(cpu_logical_map(x)).irqs[i]);
- }
+ for_each_online_cpu(x)
+ seq_printf(p, "%10u ",
+ kstat_cpu(cpu_logical_map(x)).irqs[i]);
#endif
seq_printf(p, "%c %s",
(action->flags & SA_INTERRUPT) ? '+' : ' ',
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
index 4219dd2ce3a2..41bb9596be48 100644
--- a/arch/sparc/kernel/sun4d_smp.c
+++ b/arch/sparc/kernel/sun4d_smp.c
@@ -249,11 +249,9 @@ void __init smp4d_boot_cpus(void)
} else {
unsigned long bogosum = 0;
- for(i = 0; i < NR_CPUS; i++) {
- if (cpu_isset(i, cpu_present_map)) {
- bogosum += cpu_data(i).udelay_val;
- smp_highest_cpu = i;
- }
+ for_each_present_cpu(i) {
+ bogosum += cpu_data(i).udelay_val;
+ smp_highest_cpu = i;
}
SMP_PRINTK(("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n", cpucount + 1, bogosum/(500000/HZ), (bogosum/(5000/HZ))%100));
printk("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n",
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
index fbbd8a474c4c..1dde312eebda 100644
--- a/arch/sparc/kernel/sun4m_smp.c
+++ b/arch/sparc/kernel/sun4m_smp.c
@@ -218,10 +218,8 @@ void __init smp4m_boot_cpus(void)
cpu_present_map = cpumask_of_cpu(smp_processor_id());
} else {
unsigned long bogosum = 0;
- for(i = 0; i < NR_CPUS; i++) {
- if (cpu_isset(i, cpu_present_map))
- bogosum += cpu_data(i).udelay_val;
- }
+ for_each_present_cpu(i)
+ bogosum += cpu_data(i).udelay_val;
printk("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n",
cpucount + 1,
bogosum/(500000/HZ),
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index 8c93ba655b33..e505a4125e35 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -117,9 +117,7 @@ int show_interrupts(struct seq_file *p, void *v)
#ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i));
#else
- for (j = 0; j < NR_CPUS; j++) {
- if (!cpu_online(j))
- continue;
+ for_each_online_cpu(j) {
seq_printf(p, "%10u ",
kstat_cpu(j).irqs[i]);
}
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 373a701c90a5..1b6e2ade1008 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -57,25 +57,21 @@ void smp_info(struct seq_file *m)
int i;
seq_printf(m, "State:\n");
- for (i = 0; i < NR_CPUS; i++) {
- if (cpu_online(i))
- seq_printf(m,
- "CPU%d:\t\tonline\n", i);
- }
+ for_each_online_cpu(i)
+ seq_printf(m, "CPU%d:\t\tonline\n", i);
}
void smp_bogo(struct seq_file *m)
{
int i;
- for (i = 0; i < NR_CPUS; i++)
- if (cpu_online(i))
- seq_printf(m,
- "Cpu%dBogo\t: %lu.%02lu\n"
- "Cpu%dClkTck\t: %016lx\n",
- i, cpu_data(i).udelay_val / (500000/HZ),
- (cpu_data(i).udelay_val / (5000/HZ)) % 100,
- i, cpu_data(i).clock_tick);
+ for_each_online_cpu(i)
+ seq_printf(m,
+ "Cpu%dBogo\t: %lu.%02lu\n"
+ "Cpu%dClkTck\t: %016lx\n",
+ i, cpu_data(i).udelay_val / (500000/HZ),
+ (cpu_data(i).udelay_val / (5000/HZ)) % 100,
+ i, cpu_data(i).clock_tick);
}
void __init smp_store_cpu_info(int id)
@@ -1282,7 +1278,7 @@ int setup_profiling_timer(unsigned int multiplier)
return -EINVAL;
spin_lock_irqsave(&prof_setup_lock, flags);
- for (i = 0; i < NR_CPUS; i++)
+ for_each_cpu(i)
prof_multiplier(i) = multiplier;
current_tick_offset = (timer_tick_offset / multiplier);
spin_unlock_irqrestore(&prof_setup_lock, flags);
@@ -1384,10 +1380,8 @@ void __init smp_cpus_done(unsigned int max_cpus)
unsigned long bogosum = 0;
int i;
- for (i = 0; i < NR_CPUS; i++) {
- if (cpu_online(i))
- bogosum += cpu_data(i).udelay_val;
- }
+ for_each_online_cpu(i)
+ bogosum += cpu_data(i).udelay_val;
printk("Total of %ld processors activated "
"(%lu.%02lu BogoMIPS).\n",
(long) num_online_cpus(),
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index ded63ee9c4fd..1539a8362b6f 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -1828,8 +1828,8 @@ void __flush_tlb_all(void)
void online_page(struct page *page)
{
ClearPageReserved(page);
- set_page_count(page, 0);
- free_cold_page(page);
+ init_page_count(page);
+ __free_page(page);
totalram_pages++;
num_physpages++;
}
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 27cdf9164422..80c9c18aae94 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -491,6 +491,16 @@ void __init check_bugs(void)
check_devanon();
}
-void apply_alternatives(void *start, void *end)
+void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
+{
+}
+
+void alternatives_smp_module_add(struct module *mod, char *name,
+ void *locks, void *locks_end,
+ void *text, void *text_end)
+{
+}
+
+void alternatives_smp_module_del(struct module *mod)
{
}
diff --git a/arch/x86_64/kernel/early_printk.c b/arch/x86_64/kernel/early_printk.c
index 6dffb498ccd7..a8a6aa70d695 100644
--- a/arch/x86_64/kernel/early_printk.c
+++ b/arch/x86_64/kernel/early_printk.c
@@ -17,11 +17,8 @@
#define VGABASE ((void __iomem *)0xffffffff800b8000UL)
#endif
-#define MAX_YPOS max_ypos
-#define MAX_XPOS max_xpos
-
static int max_ypos = 25, max_xpos = 80;
-static int current_ypos = 1, current_xpos = 0;
+static int current_ypos = 25, current_xpos = 0;
static void early_vga_write(struct console *con, const char *str, unsigned n)
{
@@ -29,26 +26,26 @@ static void early_vga_write(struct console *con, const char *str, unsigned n)
int i, k, j;
while ((c = *str++) != '\0' && n-- > 0) {
- if (current_ypos >= MAX_YPOS) {
+ if (current_ypos >= max_ypos) {
/* scroll 1 line up */
- for (k = 1, j = 0; k < MAX_YPOS; k++, j++) {
- for (i = 0; i < MAX_XPOS; i++) {
- writew(readw(VGABASE + 2*(MAX_XPOS*k + i)),
- VGABASE + 2*(MAX_XPOS*j + i));
+ for (k = 1, j = 0; k < max_ypos; k++, j++) {
+ for (i = 0; i < max_xpos; i++) {
+ writew(readw(VGABASE+2*(max_xpos*k+i)),
+ VGABASE + 2*(max_xpos*j + i));
}
}
- for (i = 0; i < MAX_XPOS; i++)
- writew(0x720, VGABASE + 2*(MAX_XPOS*j + i));
- current_ypos = MAX_YPOS-1;
+ for (i = 0; i < max_xpos; i++)
+ writew(0x720, VGABASE + 2*(max_xpos*j + i));
+ current_ypos = max_ypos-1;
}
if (c == '\n') {
current_xpos = 0;
current_ypos++;
} else if (c != '\r') {
writew(((0x7 << 8) | (unsigned short) c),
- VGABASE + 2*(MAX_XPOS*current_ypos +
+ VGABASE + 2*(max_xpos*current_ypos +
current_xpos++));
- if (current_xpos >= MAX_XPOS) {
+ if (current_xpos >= max_xpos) {
current_xpos = 0;
current_ypos++;
}
@@ -244,6 +241,7 @@ int __init setup_early_printk(char *opt)
&& SCREEN_INFO.orig_video_isVGA == 1) {
max_xpos = SCREEN_INFO.orig_video_cols;
max_ypos = SCREEN_INFO.orig_video_lines;
+ current_ypos = SCREEN_INFO.orig_y;
early_console = &early_vga_console;
} else if (!strncmp(buf, "simnow", 6)) {
simnow_init(buf + 6);
diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c
index 30d2a1e545fe..d8bd0b345b1e 100644
--- a/arch/x86_64/kernel/irq.c
+++ b/arch/x86_64/kernel/irq.c
@@ -38,9 +38,8 @@ int show_interrupts(struct seq_file *p, void *v)
if (i == 0) {
seq_printf(p, " ");
- for (j=0; j<NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "CPU%d ",j);
+ for_each_online_cpu(j)
+ seq_printf(p, "CPU%d ",j);
seq_putc(p, '\n');
}
@@ -53,10 +52,8 @@ int show_interrupts(struct seq_file *p, void *v)
#ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i));
#else
- for (j=0; j<NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "%10u ",
- kstat_cpu(j).irqs[i]);
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
#endif
seq_printf(p, " %14s", irq_desc[i].handler->typename);
@@ -68,15 +65,13 @@ skip:
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
} else if (i == NR_IRQS) {
seq_printf(p, "NMI: ");
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "%10u ", cpu_pda(j)->__nmi_count);
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", cpu_pda(j)->__nmi_count);
seq_putc(p, '\n');
#ifdef CONFIG_X86_LOCAL_APIC
seq_printf(p, "LOC: ");
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "%10u ", cpu_pda(j)->apic_timer_irqs);
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", cpu_pda(j)->apic_timer_irqs);
seq_putc(p, '\n');
#endif
seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
index 8b866a8572cf..14f0ced613b6 100644
--- a/arch/x86_64/kernel/kprobes.c
+++ b/arch/x86_64/kernel/kprobes.c
@@ -222,9 +222,9 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)
void __kprobes arch_remove_kprobe(struct kprobe *p)
{
- down(&kprobe_mutex);
+ mutex_lock(&kprobe_mutex);
free_insn_slot(p->ainsn.insn);
- up(&kprobe_mutex);
+ mutex_unlock(&kprobe_mutex);
}
static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index 5bf17e41cd2d..66c009e10bac 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -162,9 +162,7 @@ int __init check_nmi_watchdog (void)
local_irq_enable();
mdelay((10*1000)/nmi_hz); // wait 10 ticks
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
- if (!cpu_online(cpu))
- continue;
+ for_each_online_cpu(cpu) {
if (cpu_pda(cpu)->__nmi_count - counts[cpu] <= 5) {
endflag = 1;
printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n",
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
index 5876df116c92..e5f5ce7909a3 100644
--- a/arch/x86_64/kernel/signal.c
+++ b/arch/x86_64/kernel/signal.c
@@ -443,9 +443,6 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
if (!user_mode(regs))
return 1;
- if (try_to_freeze())
- goto no_signal;
-
if (!oldset)
oldset = &current->blocked;
@@ -463,7 +460,6 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
return handle_signal(signr, &info, &ka, oldset, regs);
}
- no_signal:
/* Did we come from a system call? */
if ((long)regs->orig_rax >= 0) {
/* Restart the system call - no handlers present */
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c
index 4cbf6d91571f..51f9bed455fa 100644
--- a/arch/xtensa/kernel/irq.c
+++ b/arch/xtensa/kernel/irq.c
@@ -83,9 +83,8 @@ int show_interrupts(struct seq_file *p, void *v)
if (i == 0) {
seq_printf(p, " ");
- for (j=0; j<NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "CPU%d ",j);
+ for_each_online_cpu(j)
+ seq_printf(p, "CPU%d ",j);
seq_putc(p, '\n');
}
@@ -98,9 +97,8 @@ int show_interrupts(struct seq_file *p, void *v)
#ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i));
#else
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
#endif
seq_printf(p, " %14s", irq_desc[i].handler->typename);
seq_printf(p, " %s", action->name);
@@ -113,9 +111,8 @@ skip:
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
} else if (i == NR_IRQS) {
seq_printf(p, "NMI: ");
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "%10u ", nmi_count(j));
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", nmi_count(j));
seq_putc(p, '\n');
seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
}
diff --git a/arch/xtensa/platform-iss/console.c b/arch/xtensa/platform-iss/console.c
index 94fdfe474ac1..2a580efb58ec 100644
--- a/arch/xtensa/platform-iss/console.c
+++ b/arch/xtensa/platform-iss/console.c
@@ -31,10 +31,6 @@
#include <linux/tty.h>
#include <linux/tty_flip.h>
-#ifdef SERIAL_INLINE
-#define _INLINE_ inline
-#endif
-
#define SERIAL_MAX_NUM_LINES 1
#define SERIAL_TIMER_VALUE (20 * HZ)
diff --git a/block/ioctl.c b/block/ioctl.c
index e1109491c234..35fdb7dc6512 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -42,9 +42,9 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
return -EINVAL;
}
/* partition number in use? */
- down(&bdev->bd_sem);
+ mutex_lock(&bdev->bd_mutex);
if (disk->part[part - 1]) {
- up(&bdev->bd_sem);
+ mutex_unlock(&bdev->bd_mutex);
return -EBUSY;
}
/* overlap? */
@@ -55,13 +55,13 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
continue;
if (!(start+length <= s->start_sect ||
start >= s->start_sect + s->nr_sects)) {
- up(&bdev->bd_sem);
+ mutex_unlock(&bdev->bd_mutex);
return -EBUSY;
}
}
/* all seems OK */
add_partition(disk, part, start, length);
- up(&bdev->bd_sem);
+ mutex_unlock(&bdev->bd_mutex);
return 0;
case BLKPG_DEL_PARTITION:
if (!disk->part[part-1])
@@ -71,9 +71,9 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
bdevp = bdget_disk(disk, part);
if (!bdevp)
return -ENOMEM;
- down(&bdevp->bd_sem);
+ mutex_lock(&bdevp->bd_mutex);
if (bdevp->bd_openers) {
- up(&bdevp->bd_sem);
+ mutex_unlock(&bdevp->bd_mutex);
bdput(bdevp);
return -EBUSY;
}
@@ -81,10 +81,10 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user
fsync_bdev(bdevp);
invalidate_bdev(bdevp, 0);
- down(&bdev->bd_sem);
+ mutex_lock(&bdev->bd_mutex);
delete_partition(disk, part);
- up(&bdev->bd_sem);
- up(&bdevp->bd_sem);
+ mutex_unlock(&bdev->bd_mutex);
+ mutex_unlock(&bdevp->bd_mutex);
bdput(bdevp);
return 0;
@@ -102,10 +102,10 @@ static int blkdev_reread_part(struct block_device *bdev)
return -EINVAL;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- if (down_trylock(&bdev->bd_sem))
+ if (!mutex_trylock(&bdev->bd_mutex))
return -EBUSY;
res = rescan_partitions(disk, bdev);
- up(&bdev->bd_sem);
+ mutex_unlock(&bdev->bd_mutex);
return res;
}
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
index 8660779fb288..bdb60663f2ef 100644
--- a/drivers/base/power/suspend.c
+++ b/drivers/base/power/suspend.c
@@ -8,6 +8,7 @@
*
*/
+#include <linux/vt_kern.h>
#include <linux/device.h>
#include "../base.h"
#include "power.h"
@@ -62,7 +63,6 @@ int suspend_device(struct device * dev, pm_message_t state)
return error;
}
-
/**
* device_suspend - Save state and stop all devices in system.
* @state: Power state to put each device in.
@@ -82,6 +82,9 @@ int device_suspend(pm_message_t state)
{
int error = 0;
+ if (!is_console_suspend_safe())
+ return -EINVAL;
+
down(&dpm_sem);
down(&dpm_list_sem);
while (!list_empty(&dpm_active) && error == 0) {
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index cf39cf9aac25..e29b8926f80e 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -3268,8 +3268,8 @@ clean2:
unregister_blkdev(hba[i]->major, hba[i]->devname);
clean1:
release_io_mem(hba[i]);
- free_hba(i);
hba[i]->busy_initializing = 0;
+ free_hba(i);
return(-1);
}
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index d23b54332d7e..fb2d0be7cdeb 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -179,6 +179,7 @@ static int print_unex = 1;
#include <linux/devfs_fs_kernel.h>
#include <linux/platform_device.h>
#include <linux/buffer_head.h> /* for invalidate_buffers() */
+#include <linux/mutex.h>
/*
* PS/2 floppies have much slower step rates than regular floppies.
@@ -413,7 +414,7 @@ static struct floppy_write_errors write_errors[N_DRIVE];
static struct timer_list motor_off_timer[N_DRIVE];
static struct gendisk *disks[N_DRIVE];
static struct block_device *opened_bdev[N_DRIVE];
-static DECLARE_MUTEX(open_lock);
+static DEFINE_MUTEX(open_lock);
static struct floppy_raw_cmd *raw_cmd, default_raw_cmd;
/*
@@ -3333,7 +3334,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
if (type) {
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- down(&open_lock);
+ mutex_lock(&open_lock);
LOCK_FDC(drive, 1);
floppy_type[type] = *g;
floppy_type[type].name = "user format";
@@ -3347,7 +3348,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
continue;
__invalidate_device(bdev);
}
- up(&open_lock);
+ mutex_unlock(&open_lock);
} else {
int oldStretch;
LOCK_FDC(drive, 1);
@@ -3674,7 +3675,7 @@ static int floppy_release(struct inode *inode, struct file *filp)
{
int drive = (long)inode->i_bdev->bd_disk->private_data;
- down(&open_lock);
+ mutex_lock(&open_lock);
if (UDRS->fd_ref < 0)
UDRS->fd_ref = 0;
else if (!UDRS->fd_ref--) {
@@ -3684,7 +3685,7 @@ static int floppy_release(struct inode *inode, struct file *filp)
if (!UDRS->fd_ref)
opened_bdev[drive] = NULL;
floppy_release_irq_and_dma();
- up(&open_lock);
+ mutex_unlock(&open_lock);
return 0;
}
@@ -3702,7 +3703,7 @@ static int floppy_open(struct inode *inode, struct file *filp)
char *tmp;
filp->private_data = (void *)0;
- down(&open_lock);
+ mutex_lock(&open_lock);
old_dev = UDRS->fd_device;
if (opened_bdev[drive] && opened_bdev[drive] != inode->i_bdev)
goto out2;
@@ -3785,7 +3786,7 @@ static int floppy_open(struct inode *inode, struct file *filp)
if ((filp->f_mode & 2) && !(UTESTF(FD_DISK_WRITABLE)))
goto out;
}
- up(&open_lock);
+ mutex_unlock(&open_lock);
return 0;
out:
if (UDRS->fd_ref < 0)
@@ -3796,7 +3797,7 @@ out:
opened_bdev[drive] = NULL;
floppy_release_irq_and_dma();
out2:
- up(&open_lock);
+ mutex_unlock(&open_lock);
return res;
}
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 0010704739e3..74bf0255e98f 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1144,7 +1144,7 @@ static int lo_ioctl(struct inode * inode, struct file * file,
struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
int err;
- down(&lo->lo_ctl_mutex);
+ mutex_lock(&lo->lo_ctl_mutex);
switch (cmd) {
case LOOP_SET_FD:
err = loop_set_fd(lo, file, inode->i_bdev, arg);
@@ -1170,7 +1170,7 @@ static int lo_ioctl(struct inode * inode, struct file * file,
default:
err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
}
- up(&lo->lo_ctl_mutex);
+ mutex_unlock(&lo->lo_ctl_mutex);
return err;
}
@@ -1178,9 +1178,9 @@ static int lo_open(struct inode *inode, struct file *file)
{
struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
- down(&lo->lo_ctl_mutex);
+ mutex_lock(&lo->lo_ctl_mutex);
lo->lo_refcnt++;
- up(&lo->lo_ctl_mutex);
+ mutex_unlock(&lo->lo_ctl_mutex);
return 0;
}
@@ -1189,9 +1189,9 @@ static int lo_release(struct inode *inode, struct file *file)
{
struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
- down(&lo->lo_ctl_mutex);
+ mutex_lock(&lo->lo_ctl_mutex);
--lo->lo_refcnt;
- up(&lo->lo_ctl_mutex);
+ mutex_unlock(&lo->lo_ctl_mutex);
return 0;
}
@@ -1233,12 +1233,12 @@ int loop_unregister_transfer(int number)
xfer_funcs[n] = NULL;
for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) {
- down(&lo->lo_ctl_mutex);
+ mutex_lock(&lo->lo_ctl_mutex);
if (lo->lo_encryption == xfer)
loop_release_xfer(lo);
- up(&lo->lo_ctl_mutex);
+ mutex_unlock(&lo->lo_ctl_mutex);
}
return 0;
@@ -1285,7 +1285,7 @@ static int __init loop_init(void)
lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
if (!lo->lo_queue)
goto out_mem4;
- init_MUTEX(&lo->lo_ctl_mutex);
+ mutex_init(&lo->lo_ctl_mutex);
init_completion(&lo->lo_done);
init_completion(&lo->lo_bh_done);
lo->lo_number = i;
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 6997d8e6bfb5..a9bde30dadad 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -459,9 +459,9 @@ static void do_nbd_request(request_queue_t * q)
req->errors = 0;
spin_unlock_irq(q->queue_lock);
- down(&lo->tx_lock);
+ mutex_lock(&lo->tx_lock);
if (unlikely(!lo->sock)) {
- up(&lo->tx_lock);
+ mutex_unlock(&lo->tx_lock);
printk(KERN_ERR "%s: Attempted send on closed socket\n",
lo->disk->disk_name);
req->errors++;
@@ -484,7 +484,7 @@ static void do_nbd_request(request_queue_t * q)
}
lo->active_req = NULL;
- up(&lo->tx_lock);
+ mutex_unlock(&lo->tx_lock);
wake_up_all(&lo->active_wq);
spin_lock_irq(q->queue_lock);
@@ -534,9 +534,9 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
case NBD_CLEAR_SOCK:
error = 0;
- down(&lo->tx_lock);
+ mutex_lock(&lo->tx_lock);
lo->sock = NULL;
- up(&lo->tx_lock);
+ mutex_unlock(&lo->tx_lock);
file = lo->file;
lo->file = NULL;
nbd_clear_que(lo);
@@ -590,7 +590,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
* FIXME: This code is duplicated from sys_shutdown, but
* there should be a more generic interface rather than
* calling socket ops directly here */
- down(&lo->tx_lock);
+ mutex_lock(&lo->tx_lock);
if (lo->sock) {
printk(KERN_WARNING "%s: shutting down socket\n",
lo->disk->disk_name);
@@ -598,7 +598,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
SEND_SHUTDOWN|RCV_SHUTDOWN);
lo->sock = NULL;
}
- up(&lo->tx_lock);
+ mutex_unlock(&lo->tx_lock);
file = lo->file;
lo->file = NULL;
nbd_clear_que(lo);
@@ -683,7 +683,7 @@ static int __init nbd_init(void)
nbd_dev[i].flags = 0;
spin_lock_init(&nbd_dev[i].queue_lock);
INIT_LIST_HEAD(&nbd_dev[i].queue_head);
- init_MUTEX(&nbd_dev[i].tx_lock);
+ mutex_init(&nbd_dev[i].tx_lock);
init_waitqueue_head(&nbd_dev[i].active_wq);
nbd_dev[i].blksize = 1024;
nbd_dev[i].bytesize = 0x7ffffc00ULL << 10; /* 2TB */
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 476a5b553f34..1d261f985f31 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -56,6 +56,7 @@
#include <linux/seq_file.h>
#include <linux/miscdevice.h>
#include <linux/suspend.h>
+#include <linux/mutex.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_ioctl.h>
#include <scsi/scsi.h>
@@ -81,7 +82,7 @@
static struct pktcdvd_device *pkt_devs[MAX_WRITERS];
static struct proc_dir_entry *pkt_proc;
static int pkt_major;
-static struct semaphore ctl_mutex; /* Serialize open/close/setup/teardown */
+static struct mutex ctl_mutex; /* Serialize open/close/setup/teardown */
static mempool_t *psd_pool;
@@ -2018,7 +2019,7 @@ static int pkt_open(struct inode *inode, struct file *file)
VPRINTK("pktcdvd: entering open\n");
- down(&ctl_mutex);
+ mutex_lock(&ctl_mutex);
pd = pkt_find_dev_from_minor(iminor(inode));
if (!pd) {
ret = -ENODEV;
@@ -2044,14 +2045,14 @@ static int pkt_open(struct inode *inode, struct file *file)
set_blocksize(inode->i_bdev, CD_FRAMESIZE);
}
- up(&ctl_mutex);
+ mutex_unlock(&ctl_mutex);
return 0;
out_dec:
pd->refcnt--;
out:
VPRINTK("pktcdvd: failed open (%d)\n", ret);
- up(&ctl_mutex);
+ mutex_unlock(&ctl_mutex);
return ret;
}
@@ -2060,14 +2061,14 @@ static int pkt_close(struct inode *inode, struct file *file)
struct pktcdvd_device *pd = inode->i_bdev->bd_disk->private_data;
int ret = 0;
- down(&ctl_mutex);
+ mutex_lock(&ctl_mutex);
pd->refcnt--;
BUG_ON(pd->refcnt < 0);
if (pd->refcnt == 0) {
int flush = test_bit(PACKET_WRITABLE, &pd->flags);
pkt_release_dev(pd, flush);
}
- up(&ctl_mutex);
+ mutex_unlock(&ctl_mutex);
return ret;
}
@@ -2596,21 +2597,21 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm
case PKT_CTRL_CMD_SETUP:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- down(&ctl_mutex);
+ mutex_lock(&ctl_mutex);
ret = pkt_setup_dev(&ctrl_cmd);
- up(&ctl_mutex);
+ mutex_unlock(&ctl_mutex);
break;
case PKT_CTRL_CMD_TEARDOWN:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- down(&ctl_mutex);
+ mutex_lock(&ctl_mutex);
ret = pkt_remove_dev(&ctrl_cmd);
- up(&ctl_mutex);
+ mutex_unlock(&ctl_mutex);
break;
case PKT_CTRL_CMD_STATUS:
- down(&ctl_mutex);
+ mutex_lock(&ctl_mutex);
pkt_get_status(&ctrl_cmd);
- up(&ctl_mutex);
+ mutex_unlock(&ctl_mutex);
break;
default:
return -ENOTTY;
@@ -2656,7 +2657,7 @@ static int __init pkt_init(void)
goto out;
}
- init_MUTEX(&ctl_mutex);
+ mutex_init(&ctl_mutex);
pkt_proc = proc_mkdir("pktcdvd", proc_root_driver);
diff --git a/drivers/block/rd.c b/drivers/block/rd.c
index ffd6abd6d5a0..1c54f46d3f70 100644
--- a/drivers/block/rd.c
+++ b/drivers/block/rd.c
@@ -310,12 +310,12 @@ static int rd_ioctl(struct inode *inode, struct file *file,
* cache
*/
error = -EBUSY;
- down(&bdev->bd_sem);
+ mutex_lock(&bdev->bd_mutex);
if (bdev->bd_openers <= 2) {
truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
error = 0;
}
- up(&bdev->bd_sem);
+ mutex_unlock(&bdev->bd_mutex);
return error;
}
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 879bbc26ce96..a59876a0bfa1 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -407,7 +407,6 @@ int register_cdrom(struct cdrom_device_info *cdi)
ENSURE(get_mcn, CDC_MCN);
ENSURE(reset, CDC_RESET);
ENSURE(audio_ioctl, CDC_PLAY_AUDIO);
- ENSURE(dev_ioctl, CDC_IOCTLS);
ENSURE(generic_packet, CDC_GENERIC_PACKET);
cdi->mc_flags = 0;
cdo->n_minors = 0;
@@ -2196,395 +2195,586 @@ retry:
return cdrom_read_cdda_old(cdi, ubuf, lba, nframes);
}
-/* Just about every imaginable ioctl is supported in the Uniform layer
- * these days. ATAPI / SCSI specific code now mainly resides in
- * mmc_ioct().
- */
-int cdrom_ioctl(struct file * file, struct cdrom_device_info *cdi,
- struct inode *ip, unsigned int cmd, unsigned long arg)
+static int cdrom_ioctl_multisession(struct cdrom_device_info *cdi,
+ void __user *argp)
{
- struct cdrom_device_ops *cdo = cdi->ops;
+ struct cdrom_multisession ms_info;
+ u8 requested_format;
int ret;
- /* Try the generic SCSI command ioctl's first.. */
- ret = scsi_cmd_ioctl(file, ip->i_bdev->bd_disk, cmd, (void __user *)arg);
- if (ret != -ENOTTY)
+ cdinfo(CD_DO_IOCTL, "entering CDROMMULTISESSION\n");
+
+ if (!(cdi->ops->capability & CDC_MULTI_SESSION))
+ return -ENOSYS;
+
+ if (copy_from_user(&ms_info, argp, sizeof(ms_info)))
+ return -EFAULT;
+
+ requested_format = ms_info.addr_format;
+ if (requested_format != CDROM_MSF && requested_format != CDROM_LBA)
+ return -EINVAL;
+ ms_info.addr_format = CDROM_LBA;
+
+ ret = cdi->ops->get_last_session(cdi, &ms_info);
+ if (ret)
return ret;
- /* the first few commands do not deal with audio drive_info, but
- only with routines in cdrom device operations. */
- switch (cmd) {
- case CDROMMULTISESSION: {
- struct cdrom_multisession ms_info;
- u_char requested_format;
- cdinfo(CD_DO_IOCTL, "entering CDROMMULTISESSION\n");
- if (!(cdo->capability & CDC_MULTI_SESSION))
- return -ENOSYS;
- IOCTL_IN(arg, struct cdrom_multisession, ms_info);
- requested_format = ms_info.addr_format;
- if (!((requested_format == CDROM_MSF) ||
- (requested_format == CDROM_LBA)))
- return -EINVAL;
- ms_info.addr_format = CDROM_LBA;
- if ((ret=cdo->get_last_session(cdi, &ms_info)))
+ sanitize_format(&ms_info.addr, &ms_info.addr_format, requested_format);
+
+ if (copy_to_user(argp, &ms_info, sizeof(ms_info)))
+ return -EFAULT;
+
+ cdinfo(CD_DO_IOCTL, "CDROMMULTISESSION successful\n");
+ return 0;
+}
+
+static int cdrom_ioctl_eject(struct cdrom_device_info *cdi)
+{
+ cdinfo(CD_DO_IOCTL, "entering CDROMEJECT\n");
+
+ if (!CDROM_CAN(CDC_OPEN_TRAY))
+ return -ENOSYS;
+ if (cdi->use_count != 1 || keeplocked)
+ return -EBUSY;
+ if (CDROM_CAN(CDC_LOCK)) {
+ int ret = cdi->ops->lock_door(cdi, 0);
+ if (ret)
return ret;
- sanitize_format(&ms_info.addr, &ms_info.addr_format,
- requested_format);
- IOCTL_OUT(arg, struct cdrom_multisession, ms_info);
- cdinfo(CD_DO_IOCTL, "CDROMMULTISESSION successful\n");
- return 0;
- }
+ }
- case CDROMEJECT: {
- cdinfo(CD_DO_IOCTL, "entering CDROMEJECT\n");
- if (!CDROM_CAN(CDC_OPEN_TRAY))
- return -ENOSYS;
- if (cdi->use_count != 1 || keeplocked)
- return -EBUSY;
- if (CDROM_CAN(CDC_LOCK))
- if ((ret=cdo->lock_door(cdi, 0)))
- return ret;
+ return cdi->ops->tray_move(cdi, 1);
+}
- return cdo->tray_move(cdi, 1);
- }
+static int cdrom_ioctl_closetray(struct cdrom_device_info *cdi)
+{
+ cdinfo(CD_DO_IOCTL, "entering CDROMCLOSETRAY\n");
- case CDROMCLOSETRAY: {
- cdinfo(CD_DO_IOCTL, "entering CDROMCLOSETRAY\n");
- if (!CDROM_CAN(CDC_CLOSE_TRAY))
- return -ENOSYS;
- return cdo->tray_move(cdi, 0);
- }
+ if (!CDROM_CAN(CDC_CLOSE_TRAY))
+ return -ENOSYS;
+ return cdi->ops->tray_move(cdi, 0);
+}
- case CDROMEJECT_SW: {
- cdinfo(CD_DO_IOCTL, "entering CDROMEJECT_SW\n");
- if (!CDROM_CAN(CDC_OPEN_TRAY))
- return -ENOSYS;
- if (keeplocked)
- return -EBUSY;
- cdi->options &= ~(CDO_AUTO_CLOSE | CDO_AUTO_EJECT);
- if (arg)
- cdi->options |= CDO_AUTO_CLOSE | CDO_AUTO_EJECT;
- return 0;
- }
+static int cdrom_ioctl_eject_sw(struct cdrom_device_info *cdi,
+ unsigned long arg)
+{
+ cdinfo(CD_DO_IOCTL, "entering CDROMEJECT_SW\n");
- case CDROM_MEDIA_CHANGED: {
- struct cdrom_changer_info *info;
- int changed;
+ if (!CDROM_CAN(CDC_OPEN_TRAY))
+ return -ENOSYS;
+ if (keeplocked)
+ return -EBUSY;
- cdinfo(CD_DO_IOCTL, "entering CDROM_MEDIA_CHANGED\n");
- if (!CDROM_CAN(CDC_MEDIA_CHANGED))
- return -ENOSYS;
+ cdi->options &= ~(CDO_AUTO_CLOSE | CDO_AUTO_EJECT);
+ if (arg)
+ cdi->options |= CDO_AUTO_CLOSE | CDO_AUTO_EJECT;
+ return 0;
+}
- /* cannot select disc or select current disc */
- if (!CDROM_CAN(CDC_SELECT_DISC) || arg == CDSL_CURRENT)
- return media_changed(cdi, 1);
+static int cdrom_ioctl_media_changed(struct cdrom_device_info *cdi,
+ unsigned long arg)
+{
+ struct cdrom_changer_info *info;
+ int ret;
- if ((unsigned int)arg >= cdi->capacity)
- return -EINVAL;
+ cdinfo(CD_DO_IOCTL, "entering CDROM_MEDIA_CHANGED\n");
- info = kmalloc(sizeof(*info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
+ if (!CDROM_CAN(CDC_MEDIA_CHANGED))
+ return -ENOSYS;
- if ((ret = cdrom_read_mech_status(cdi, info))) {
- kfree(info);
- return ret;
- }
+ /* cannot select disc or select current disc */
+ if (!CDROM_CAN(CDC_SELECT_DISC) || arg == CDSL_CURRENT)
+ return media_changed(cdi, 1);
- changed = info->slots[arg].change;
- kfree(info);
- return changed;
- }
+ if ((unsigned int)arg >= cdi->capacity)
+ return -EINVAL;
- case CDROM_SET_OPTIONS: {
- cdinfo(CD_DO_IOCTL, "entering CDROM_SET_OPTIONS\n");
- /* options need to be in sync with capability. too late for
- that, so we have to check each one separately... */
- switch (arg) {
- case CDO_USE_FFLAGS:
- case CDO_CHECK_TYPE:
- break;
- case CDO_LOCK:
- if (!CDROM_CAN(CDC_LOCK))
- return -ENOSYS;
- break;
- case 0:
- return cdi->options;
- /* default is basically CDO_[AUTO_CLOSE|AUTO_EJECT] */
- default:
- if (!CDROM_CAN(arg))
- return -ENOSYS;
- }
- cdi->options |= (int) arg;
- return cdi->options;
- }
+ info = kmalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
- case CDROM_CLEAR_OPTIONS: {
- cdinfo(CD_DO_IOCTL, "entering CDROM_CLEAR_OPTIONS\n");
- cdi->options &= ~(int) arg;
- return cdi->options;
- }
+ ret = cdrom_read_mech_status(cdi, info);
+ if (!ret)
+ ret = info->slots[arg].change;
+ kfree(info);
+ return ret;
+}
- case CDROM_SELECT_SPEED: {
- cdinfo(CD_DO_IOCTL, "entering CDROM_SELECT_SPEED\n");
- if (!CDROM_CAN(CDC_SELECT_SPEED))
- return -ENOSYS;
- return cdo->select_speed(cdi, arg);
- }
+static int cdrom_ioctl_set_options(struct cdrom_device_info *cdi,
+ unsigned long arg)
+{
+ cdinfo(CD_DO_IOCTL, "entering CDROM_SET_OPTIONS\n");
- case CDROM_SELECT_DISC: {
- cdinfo(CD_DO_IOCTL, "entering CDROM_SELECT_DISC\n");
- if (!CDROM_CAN(CDC_SELECT_DISC))
+ /*
+ * Options need to be in sync with capability.
+ * Too late for that, so we have to check each one separately.
+ */
+ switch (arg) {
+ case CDO_USE_FFLAGS:
+ case CDO_CHECK_TYPE:
+ break;
+ case CDO_LOCK:
+ if (!CDROM_CAN(CDC_LOCK))
+ return -ENOSYS;
+ break;
+ case 0:
+ return cdi->options;
+ /* default is basically CDO_[AUTO_CLOSE|AUTO_EJECT] */
+ default:
+ if (!CDROM_CAN(arg))
return -ENOSYS;
+ }
+ cdi->options |= (int) arg;
+ return cdi->options;
+}
- if ((arg != CDSL_CURRENT) && (arg != CDSL_NONE))
- if ((int)arg >= cdi->capacity)
- return -EINVAL;
-
- /* cdo->select_disc is a hook to allow a driver-specific
- * way of seleting disc. However, since there is no
- * equiv hook for cdrom_slot_status this may not
- * actually be useful...
- */
- if (cdo->select_disc != NULL)
- return cdo->select_disc(cdi, arg);
-
- /* no driver specific select_disc(), call our own */
- cdinfo(CD_CHANGER, "Using generic cdrom_select_disc()\n");
- return cdrom_select_disc(cdi, arg);
- }
+static int cdrom_ioctl_clear_options(struct cdrom_device_info *cdi,
+ unsigned long arg)
+{
+ cdinfo(CD_DO_IOCTL, "entering CDROM_CLEAR_OPTIONS\n");
- case CDROMRESET: {
- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;
- cdinfo(CD_DO_IOCTL, "entering CDROM_RESET\n");
- if (!CDROM_CAN(CDC_RESET))
- return -ENOSYS;
- invalidate_bdev(ip->i_bdev, 0);
- return cdo->reset(cdi);
- }
+ cdi->options &= ~(int) arg;
+ return cdi->options;
+}
- case CDROM_LOCKDOOR: {
- cdinfo(CD_DO_IOCTL, "%socking door.\n", arg ? "L" : "Unl");
- if (!CDROM_CAN(CDC_LOCK))
- return -EDRIVE_CANT_DO_THIS;
- keeplocked = arg ? 1 : 0;
- /* don't unlock the door on multiple opens,but allow root
- * to do so */
- if ((cdi->use_count != 1) && !arg && !capable(CAP_SYS_ADMIN))
- return -EBUSY;
- return cdo->lock_door(cdi, arg);
- }
+static int cdrom_ioctl_select_speed(struct cdrom_device_info *cdi,
+ unsigned long arg)
+{
+ cdinfo(CD_DO_IOCTL, "entering CDROM_SELECT_SPEED\n");
- case CDROM_DEBUG: {
- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;
- cdinfo(CD_DO_IOCTL, "%sabling debug.\n", arg ? "En" : "Dis");
- debug = arg ? 1 : 0;
- return debug;
- }
+ if (!CDROM_CAN(CDC_SELECT_SPEED))
+ return -ENOSYS;
+ return cdi->ops->select_speed(cdi, arg);
+}
- case CDROM_GET_CAPABILITY: {
- cdinfo(CD_DO_IOCTL, "entering CDROM_GET_CAPABILITY\n");
- return (cdo->capability & ~cdi->mask);
- }
+static int cdrom_ioctl_select_disc(struct cdrom_device_info *cdi,
+ unsigned long arg)
+{
+ cdinfo(CD_DO_IOCTL, "entering CDROM_SELECT_DISC\n");
+
+ if (!CDROM_CAN(CDC_SELECT_DISC))
+ return -ENOSYS;
+
+ if (arg != CDSL_CURRENT && arg != CDSL_NONE) {
+ if ((int)arg >= cdi->capacity)
+ return -EINVAL;
+ }
+
+ /*
+ * ->select_disc is a hook to allow a driver-specific way of
+ * seleting disc. However, since there is no equivalent hook for
+ * cdrom_slot_status this may not actually be useful...
+ */
+ if (cdi->ops->select_disc)
+ return cdi->ops->select_disc(cdi, arg);
+
+ cdinfo(CD_CHANGER, "Using generic cdrom_select_disc()\n");
+ return cdrom_select_disc(cdi, arg);
+}
+
+static int cdrom_ioctl_reset(struct cdrom_device_info *cdi,
+ struct block_device *bdev)
+{
+ cdinfo(CD_DO_IOCTL, "entering CDROM_RESET\n");
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+ if (!CDROM_CAN(CDC_RESET))
+ return -ENOSYS;
+ invalidate_bdev(bdev, 0);
+ return cdi->ops->reset(cdi);
+}
+
+static int cdrom_ioctl_lock_door(struct cdrom_device_info *cdi,
+ unsigned long arg)
+{
+ cdinfo(CD_DO_IOCTL, "%socking door.\n", arg ? "L" : "Unl");
+
+ if (!CDROM_CAN(CDC_LOCK))
+ return -EDRIVE_CANT_DO_THIS;
+
+ keeplocked = arg ? 1 : 0;
+
+ /*
+ * Don't unlock the door on multiple opens by default, but allow
+ * root to do so.
+ */
+ if (cdi->use_count != 1 && !arg && !capable(CAP_SYS_ADMIN))
+ return -EBUSY;
+ return cdi->ops->lock_door(cdi, arg);
+}
+
+static int cdrom_ioctl_debug(struct cdrom_device_info *cdi,
+ unsigned long arg)
+{
+ cdinfo(CD_DO_IOCTL, "%sabling debug.\n", arg ? "En" : "Dis");
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+ debug = arg ? 1 : 0;
+ return debug;
+}
-/* The following function is implemented, although very few audio
+static int cdrom_ioctl_get_capability(struct cdrom_device_info *cdi)
+{
+ cdinfo(CD_DO_IOCTL, "entering CDROM_GET_CAPABILITY\n");
+ return (cdi->ops->capability & ~cdi->mask);
+}
+
+/*
+ * The following function is implemented, although very few audio
* discs give Universal Product Code information, which should just be
* the Medium Catalog Number on the box. Note, that the way the code
* is written on the CD is /not/ uniform across all discs!
*/
- case CDROM_GET_MCN: {
- struct cdrom_mcn mcn;
- cdinfo(CD_DO_IOCTL, "entering CDROM_GET_MCN\n");
- if (!(cdo->capability & CDC_MCN))
- return -ENOSYS;
- if ((ret=cdo->get_mcn(cdi, &mcn)))
- return ret;
- IOCTL_OUT(arg, struct cdrom_mcn, mcn);
- cdinfo(CD_DO_IOCTL, "CDROM_GET_MCN successful\n");
- return 0;
- }
+static int cdrom_ioctl_get_mcn(struct cdrom_device_info *cdi,
+ void __user *argp)
+{
+ struct cdrom_mcn mcn;
+ int ret;
- case CDROM_DRIVE_STATUS: {
- cdinfo(CD_DO_IOCTL, "entering CDROM_DRIVE_STATUS\n");
- if (!(cdo->capability & CDC_DRIVE_STATUS))
- return -ENOSYS;
- if (!CDROM_CAN(CDC_SELECT_DISC))
- return cdo->drive_status(cdi, CDSL_CURRENT);
- if ((arg == CDSL_CURRENT) || (arg == CDSL_NONE))
- return cdo->drive_status(cdi, CDSL_CURRENT);
- if (((int)arg >= cdi->capacity))
- return -EINVAL;
- return cdrom_slot_status(cdi, arg);
- }
+ cdinfo(CD_DO_IOCTL, "entering CDROM_GET_MCN\n");
- /* Ok, this is where problems start. The current interface for the
- CDROM_DISC_STATUS ioctl is flawed. It makes the false assumption
- that CDs are all CDS_DATA_1 or all CDS_AUDIO, etc. Unfortunatly,
- while this is often the case, it is also very common for CDs to
- have some tracks with data, and some tracks with audio. Just
- because I feel like it, I declare the following to be the best
- way to cope. If the CD has ANY data tracks on it, it will be
- returned as a data CD. If it has any XA tracks, I will return
- it as that. Now I could simplify this interface by combining these
- returns with the above, but this more clearly demonstrates
- the problem with the current interface. Too bad this wasn't
- designed to use bitmasks... -Erik
-
- Well, now we have the option CDS_MIXED: a mixed-type CD.
- User level programmers might feel the ioctl is not very useful.
- ---david
- */
- case CDROM_DISC_STATUS: {
- tracktype tracks;
- cdinfo(CD_DO_IOCTL, "entering CDROM_DISC_STATUS\n");
- cdrom_count_tracks(cdi, &tracks);
- if (tracks.error)
- return(tracks.error);
-
- /* Policy mode on */
- if (tracks.audio > 0) {
- if (tracks.data==0 && tracks.cdi==0 && tracks.xa==0)
- return CDS_AUDIO;
- else
- return CDS_MIXED;
- }
- if (tracks.cdi > 0) return CDS_XA_2_2;
- if (tracks.xa > 0) return CDS_XA_2_1;
- if (tracks.data > 0) return CDS_DATA_1;
- /* Policy mode off */
+ if (!(cdi->ops->capability & CDC_MCN))
+ return -ENOSYS;
+ ret = cdi->ops->get_mcn(cdi, &mcn);
+ if (ret)
+ return ret;
- cdinfo(CD_WARNING,"This disc doesn't have any tracks I recognize!\n");
- return CDS_NO_INFO;
- }
+ if (copy_to_user(argp, &mcn, sizeof(mcn)))
+ return -EFAULT;
+ cdinfo(CD_DO_IOCTL, "CDROM_GET_MCN successful\n");
+ return 0;
+}
- case CDROM_CHANGER_NSLOTS: {
- cdinfo(CD_DO_IOCTL, "entering CDROM_CHANGER_NSLOTS\n");
- return cdi->capacity;
- }
+static int cdrom_ioctl_drive_status(struct cdrom_device_info *cdi,
+ unsigned long arg)
+{
+ cdinfo(CD_DO_IOCTL, "entering CDROM_DRIVE_STATUS\n");
+
+ if (!(cdi->ops->capability & CDC_DRIVE_STATUS))
+ return -ENOSYS;
+ if (!CDROM_CAN(CDC_SELECT_DISC) ||
+ (arg == CDSL_CURRENT || arg == CDSL_NONE))
+ return cdi->ops->drive_status(cdi, CDSL_CURRENT);
+ if (((int)arg >= cdi->capacity))
+ return -EINVAL;
+ return cdrom_slot_status(cdi, arg);
+}
+
+/*
+ * Ok, this is where problems start. The current interface for the
+ * CDROM_DISC_STATUS ioctl is flawed. It makes the false assumption that
+ * CDs are all CDS_DATA_1 or all CDS_AUDIO, etc. Unfortunatly, while this
+ * is often the case, it is also very common for CDs to have some tracks
+ * with data, and some tracks with audio. Just because I feel like it,
+ * I declare the following to be the best way to cope. If the CD has ANY
+ * data tracks on it, it will be returned as a data CD. If it has any XA
+ * tracks, I will return it as that. Now I could simplify this interface
+ * by combining these returns with the above, but this more clearly
+ * demonstrates the problem with the current interface. Too bad this
+ * wasn't designed to use bitmasks... -Erik
+ *
+ * Well, now we have the option CDS_MIXED: a mixed-type CD.
+ * User level programmers might feel the ioctl is not very useful.
+ * ---david
+ */
+static int cdrom_ioctl_disc_status(struct cdrom_device_info *cdi)
+{
+ tracktype tracks;
+
+ cdinfo(CD_DO_IOCTL, "entering CDROM_DISC_STATUS\n");
+
+ cdrom_count_tracks(cdi, &tracks);
+ if (tracks.error)
+ return tracks.error;
+
+ /* Policy mode on */
+ if (tracks.audio > 0) {
+ if (!tracks.data && !tracks.cdi && !tracks.xa)
+ return CDS_AUDIO;
+ else
+ return CDS_MIXED;
}
- /* use the ioctls that are implemented through the generic_packet()
- interface. this may look at bit funny, but if -ENOTTY is
- returned that particular ioctl is not implemented and we
- let it go through the device specific ones. */
+ if (tracks.cdi > 0)
+ return CDS_XA_2_2;
+ if (tracks.xa > 0)
+ return CDS_XA_2_1;
+ if (tracks.data > 0)
+ return CDS_DATA_1;
+ /* Policy mode off */
+
+ cdinfo(CD_WARNING,"This disc doesn't have any tracks I recognize!\n");
+ return CDS_NO_INFO;
+}
+
+static int cdrom_ioctl_changer_nslots(struct cdrom_device_info *cdi)
+{
+ cdinfo(CD_DO_IOCTL, "entering CDROM_CHANGER_NSLOTS\n");
+ return cdi->capacity;
+}
+
+static int cdrom_ioctl_get_subchnl(struct cdrom_device_info *cdi,
+ void __user *argp)
+{
+ struct cdrom_subchnl q;
+ u8 requested, back;
+ int ret;
+
+ /* cdinfo(CD_DO_IOCTL,"entering CDROMSUBCHNL\n");*/
+
+ if (!CDROM_CAN(CDC_PLAY_AUDIO))
+ return -ENOSYS;
+ if (copy_from_user(&q, argp, sizeof(q)))
+ return -EFAULT;
+
+ requested = q.cdsc_format;
+ if (requested != CDROM_MSF && requested != CDROM_LBA)
+ return -EINVAL;
+ q.cdsc_format = CDROM_MSF;
+
+ ret = cdi->ops->audio_ioctl(cdi, CDROMSUBCHNL, &q);
+ if (ret)
+ return ret;
+
+ back = q.cdsc_format; /* local copy */
+ sanitize_format(&q.cdsc_absaddr, &back, requested);
+ sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested);
+
+ if (copy_to_user(argp, &q, sizeof(q)))
+ return -EFAULT;
+ /* cdinfo(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */
+ return 0;
+}
+
+static int cdrom_ioctl_read_tochdr(struct cdrom_device_info *cdi,
+ void __user *argp)
+{
+ struct cdrom_tochdr header;
+ int ret;
+
+ /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCHDR\n"); */
+
+ if (!CDROM_CAN(CDC_PLAY_AUDIO))
+ return -ENOSYS;
+ if (copy_from_user(&header, argp, sizeof(header)))
+ return -EFAULT;
+
+ ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCHDR, &header);
+ if (ret)
+ return ret;
+
+ if (copy_to_user(argp, &header, sizeof(header)))
+ return -EFAULT;
+ /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCHDR successful\n"); */
+ return 0;
+}
+
+static int cdrom_ioctl_read_tocentry(struct cdrom_device_info *cdi,
+ void __user *argp)
+{
+ struct cdrom_tocentry entry;
+ u8 requested_format;
+ int ret;
+
+ /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCENTRY\n"); */
+
+ if (!CDROM_CAN(CDC_PLAY_AUDIO))
+ return -ENOSYS;
+ if (copy_from_user(&entry, argp, sizeof(entry)))
+ return -EFAULT;
+
+ requested_format = entry.cdte_format;
+ if (requested_format != CDROM_MSF && requested_format != CDROM_LBA)
+ return -EINVAL;
+ /* make interface to low-level uniform */
+ entry.cdte_format = CDROM_MSF;
+ ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry);
+ if (ret)
+ return ret;
+ sanitize_format(&entry.cdte_addr, &entry.cdte_format, requested_format);
+
+ if (copy_to_user(argp, &entry, sizeof(entry)))
+ return -EFAULT;
+ /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCENTRY successful\n"); */
+ return 0;
+}
+
+static int cdrom_ioctl_play_msf(struct cdrom_device_info *cdi,
+ void __user *argp)
+{
+ struct cdrom_msf msf;
+
+ cdinfo(CD_DO_IOCTL, "entering CDROMPLAYMSF\n");
+
+ if (!CDROM_CAN(CDC_PLAY_AUDIO))
+ return -ENOSYS;
+ if (copy_from_user(&msf, argp, sizeof(msf)))
+ return -EFAULT;
+ return cdi->ops->audio_ioctl(cdi, CDROMPLAYMSF, &msf);
+}
+
+static int cdrom_ioctl_play_trkind(struct cdrom_device_info *cdi,
+ void __user *argp)
+{
+ struct cdrom_ti ti;
+ int ret;
+
+ cdinfo(CD_DO_IOCTL, "entering CDROMPLAYTRKIND\n");
+
+ if (!CDROM_CAN(CDC_PLAY_AUDIO))
+ return -ENOSYS;
+ if (copy_from_user(&ti, argp, sizeof(ti)))
+ return -EFAULT;
+
+ ret = check_for_audio_disc(cdi, cdi->ops);
+ if (ret)
+ return ret;
+ return cdi->ops->audio_ioctl(cdi, CDROMPLAYTRKIND, &ti);
+}
+static int cdrom_ioctl_volctrl(struct cdrom_device_info *cdi,
+ void __user *argp)
+{
+ struct cdrom_volctrl volume;
+
+ cdinfo(CD_DO_IOCTL, "entering CDROMVOLCTRL\n");
+
+ if (!CDROM_CAN(CDC_PLAY_AUDIO))
+ return -ENOSYS;
+ if (copy_from_user(&volume, argp, sizeof(volume)))
+ return -EFAULT;
+ return cdi->ops->audio_ioctl(cdi, CDROMVOLCTRL, &volume);
+}
+
+static int cdrom_ioctl_volread(struct cdrom_device_info *cdi,
+ void __user *argp)
+{
+ struct cdrom_volctrl volume;
+ int ret;
+
+ cdinfo(CD_DO_IOCTL, "entering CDROMVOLREAD\n");
+
+ if (!CDROM_CAN(CDC_PLAY_AUDIO))
+ return -ENOSYS;
+
+ ret = cdi->ops->audio_ioctl(cdi, CDROMVOLREAD, &volume);
+ if (ret)
+ return ret;
+
+ if (copy_to_user(argp, &volume, sizeof(volume)))
+ return -EFAULT;
+ return 0;
+}
+
+static int cdrom_ioctl_audioctl(struct cdrom_device_info *cdi,
+ unsigned int cmd)
+{
+ int ret;
+
+ cdinfo(CD_DO_IOCTL, "doing audio ioctl (start/stop/pause/resume)\n");
+
+ if (!CDROM_CAN(CDC_PLAY_AUDIO))
+ return -ENOSYS;
+ ret = check_for_audio_disc(cdi, cdi->ops);
+ if (ret)
+ return ret;
+ return cdi->ops->audio_ioctl(cdi, cmd, NULL);
+}
+
+/*
+ * Just about every imaginable ioctl is supported in the Uniform layer
+ * these days.
+ * ATAPI / SCSI specific code now mainly resides in mmc_ioctl().
+ */
+int cdrom_ioctl(struct file * file, struct cdrom_device_info *cdi,
+ struct inode *ip, unsigned int cmd, unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ int ret;
+
+ /*
+ * Try the generic SCSI command ioctl's first.
+ */
+ ret = scsi_cmd_ioctl(file, ip->i_bdev->bd_disk, cmd, argp);
+ if (ret != -ENOTTY)
+ return ret;
+
+ switch (cmd) {
+ case CDROMMULTISESSION:
+ return cdrom_ioctl_multisession(cdi, argp);
+ case CDROMEJECT:
+ return cdrom_ioctl_eject(cdi);
+ case CDROMCLOSETRAY:
+ return cdrom_ioctl_closetray(cdi);
+ case CDROMEJECT_SW:
+ return cdrom_ioctl_eject_sw(cdi, arg);
+ case CDROM_MEDIA_CHANGED:
+ return cdrom_ioctl_media_changed(cdi, arg);
+ case CDROM_SET_OPTIONS:
+ return cdrom_ioctl_set_options(cdi, arg);
+ case CDROM_CLEAR_OPTIONS:
+ return cdrom_ioctl_clear_options(cdi, arg);
+ case CDROM_SELECT_SPEED:
+ return cdrom_ioctl_select_speed(cdi, arg);
+ case CDROM_SELECT_DISC:
+ return cdrom_ioctl_select_disc(cdi, arg);
+ case CDROMRESET:
+ return cdrom_ioctl_reset(cdi, ip->i_bdev);
+ case CDROM_LOCKDOOR:
+ return cdrom_ioctl_lock_door(cdi, arg);
+ case CDROM_DEBUG:
+ return cdrom_ioctl_debug(cdi, arg);
+ case CDROM_GET_CAPABILITY:
+ return cdrom_ioctl_get_capability(cdi);
+ case CDROM_GET_MCN:
+ return cdrom_ioctl_get_mcn(cdi, argp);
+ case CDROM_DRIVE_STATUS:
+ return cdrom_ioctl_drive_status(cdi, arg);
+ case CDROM_DISC_STATUS:
+ return cdrom_ioctl_disc_status(cdi);
+ case CDROM_CHANGER_NSLOTS:
+ return cdrom_ioctl_changer_nslots(cdi);
+ }
+
+ /*
+ * Use the ioctls that are implemented through the generic_packet()
+ * interface. this may look at bit funny, but if -ENOTTY is
+ * returned that particular ioctl is not implemented and we
+ * let it go through the device specific ones.
+ */
if (CDROM_CAN(CDC_GENERIC_PACKET)) {
ret = mmc_ioctl(cdi, cmd, arg);
- if (ret != -ENOTTY) {
+ if (ret != -ENOTTY)
return ret;
- }
}
- /* note: most of the cdinfo() calls are commented out here,
- because they fill up the sys log when CD players poll
- the drive. */
+ /*
+ * Note: most of the cdinfo() calls are commented out here,
+ * because they fill up the sys log when CD players poll
+ * the drive.
+ */
switch (cmd) {
- case CDROMSUBCHNL: {
- struct cdrom_subchnl q;
- u_char requested, back;
- if (!CDROM_CAN(CDC_PLAY_AUDIO))
- return -ENOSYS;
- /* cdinfo(CD_DO_IOCTL,"entering CDROMSUBCHNL\n");*/
- IOCTL_IN(arg, struct cdrom_subchnl, q);
- requested = q.cdsc_format;
- if (!((requested == CDROM_MSF) ||
- (requested == CDROM_LBA)))
- return -EINVAL;
- q.cdsc_format = CDROM_MSF;
- if ((ret=cdo->audio_ioctl(cdi, cmd, &q)))
- return ret;
- back = q.cdsc_format; /* local copy */
- sanitize_format(&q.cdsc_absaddr, &back, requested);
- sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested);
- IOCTL_OUT(arg, struct cdrom_subchnl, q);
- /* cdinfo(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */
- return 0;
- }
- case CDROMREADTOCHDR: {
- struct cdrom_tochdr header;
- if (!CDROM_CAN(CDC_PLAY_AUDIO))
- return -ENOSYS;
- /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCHDR\n"); */
- IOCTL_IN(arg, struct cdrom_tochdr, header);
- if ((ret=cdo->audio_ioctl(cdi, cmd, &header)))
- return ret;
- IOCTL_OUT(arg, struct cdrom_tochdr, header);
- /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCHDR successful\n"); */
- return 0;
- }
- case CDROMREADTOCENTRY: {
- struct cdrom_tocentry entry;
- u_char requested_format;
- if (!CDROM_CAN(CDC_PLAY_AUDIO))
- return -ENOSYS;
- /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCENTRY\n"); */
- IOCTL_IN(arg, struct cdrom_tocentry, entry);
- requested_format = entry.cdte_format;
- if (!((requested_format == CDROM_MSF) ||
- (requested_format == CDROM_LBA)))
- return -EINVAL;
- /* make interface to low-level uniform */
- entry.cdte_format = CDROM_MSF;
- if ((ret=cdo->audio_ioctl(cdi, cmd, &entry)))
- return ret;
- sanitize_format(&entry.cdte_addr,
- &entry.cdte_format, requested_format);
- IOCTL_OUT(arg, struct cdrom_tocentry, entry);
- /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCENTRY successful\n"); */
- return 0;
- }
- case CDROMPLAYMSF: {
- struct cdrom_msf msf;
- if (!CDROM_CAN(CDC_PLAY_AUDIO))
- return -ENOSYS;
- cdinfo(CD_DO_IOCTL, "entering CDROMPLAYMSF\n");
- IOCTL_IN(arg, struct cdrom_msf, msf);
- return cdo->audio_ioctl(cdi, cmd, &msf);
- }
- case CDROMPLAYTRKIND: {
- struct cdrom_ti ti;
- if (!CDROM_CAN(CDC_PLAY_AUDIO))
- return -ENOSYS;
- cdinfo(CD_DO_IOCTL, "entering CDROMPLAYTRKIND\n");
- IOCTL_IN(arg, struct cdrom_ti, ti);
- CHECKAUDIO;
- return cdo->audio_ioctl(cdi, cmd, &ti);
- }
- case CDROMVOLCTRL: {
- struct cdrom_volctrl volume;
- if (!CDROM_CAN(CDC_PLAY_AUDIO))
- return -ENOSYS;
- cdinfo(CD_DO_IOCTL, "entering CDROMVOLCTRL\n");
- IOCTL_IN(arg, struct cdrom_volctrl, volume);
- return cdo->audio_ioctl(cdi, cmd, &volume);
- }
- case CDROMVOLREAD: {
- struct cdrom_volctrl volume;
- if (!CDROM_CAN(CDC_PLAY_AUDIO))
- return -ENOSYS;
- cdinfo(CD_DO_IOCTL, "entering CDROMVOLREAD\n");
- if ((ret=cdo->audio_ioctl(cdi, cmd, &volume)))
- return ret;
- IOCTL_OUT(arg, struct cdrom_volctrl, volume);
- return 0;
- }
+ case CDROMSUBCHNL:
+ return cdrom_ioctl_get_subchnl(cdi, argp);
+ case CDROMREADTOCHDR:
+ return cdrom_ioctl_read_tochdr(cdi, argp);
+ case CDROMREADTOCENTRY:
+ return cdrom_ioctl_read_tocentry(cdi, argp);
+ case CDROMPLAYMSF:
+ return cdrom_ioctl_play_msf(cdi, argp);
+ case CDROMPLAYTRKIND:
+ return cdrom_ioctl_play_trkind(cdi, argp);
+ case CDROMVOLCTRL:
+ return cdrom_ioctl_volctrl(cdi, argp);
+ case CDROMVOLREAD:
+ return cdrom_ioctl_volread(cdi, argp);
case CDROMSTART:
case CDROMSTOP:
case CDROMPAUSE:
- case CDROMRESUME: {
- if (!CDROM_CAN(CDC_PLAY_AUDIO))
- return -ENOSYS;
- cdinfo(CD_DO_IOCTL, "doing audio ioctl (start/stop/pause/resume)\n");
- CHECKAUDIO;
- return cdo->audio_ioctl(cdi, cmd, NULL);
- }
- } /* switch */
+ case CDROMRESUME:
+ return cdrom_ioctl_audioctl(cdi, cmd);
+ }
- /* do the device specific ioctls */
- if (CDROM_CAN(CDC_IOCTLS))
- return cdo->dev_ioctl(cdi, cmd, arg);
-
return -ENOSYS;
}
diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c
index 378e88d20757..72ffd64e8b1e 100644
--- a/drivers/cdrom/cdu31a.c
+++ b/drivers/cdrom/cdu31a.c
@@ -2668,7 +2668,7 @@ static int scd_audio_ioctl(struct cdrom_device_info *cdi,
return retval;
}
-static int scd_dev_ioctl(struct cdrom_device_info *cdi,
+static int scd_read_audio(struct cdrom_device_info *cdi,
unsigned int cmd, unsigned long arg)
{
void __user *argp = (void __user *)arg;
@@ -2894,11 +2894,10 @@ static struct cdrom_device_ops scd_dops = {
.get_mcn = scd_get_mcn,
.reset = scd_reset,
.audio_ioctl = scd_audio_ioctl,
- .dev_ioctl = scd_dev_ioctl,
.capability = CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK |
CDC_SELECT_SPEED | CDC_MULTI_SESSION |
CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO |
- CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS,
+ CDC_RESET | CDC_DRIVE_STATUS,
.n_minors = 1,
};
@@ -2936,6 +2935,9 @@ static int scd_block_ioctl(struct inode *inode, struct file *file,
case CDROMCLOSETRAY:
retval = scd_tray_move(&scd_info, 0);
break;
+ case CDROMREADAUDIO:
+ retval = scd_read_audio(&scd_info, CDROMREADAUDIO, arg);
+ break;
default:
retval = cdrom_ioctl(file, &scd_info, inode, cmd, arg);
}
diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c
index ce127f7ec0f6..fad27a87ce35 100644
--- a/drivers/cdrom/cm206.c
+++ b/drivers/cdrom/cm206.c
@@ -1157,32 +1157,6 @@ static int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
}
}
-/* Ioctl. These ioctls are specific to the cm206 driver. I have made
- some driver statistics accessible through ioctl calls.
- */
-
-static int cm206_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
- unsigned long arg)
-{
- switch (cmd) {
-#ifdef STATISTICS
- case CM206CTL_GET_STAT:
- if (arg >= NR_STATS)
- return -EINVAL;
- else
- return cd->stats[arg];
- case CM206CTL_GET_LAST_STAT:
- if (arg >= NR_STATS)
- return -EINVAL;
- else
- return cd->last_stat[arg];
-#endif
- default:
- debug(("Unknown ioctl call 0x%x\n", cmd));
- return -EINVAL;
- }
-}
-
static int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
{
if (cd != NULL) {
@@ -1321,11 +1295,10 @@ static struct cdrom_device_ops cm206_dops = {
.get_mcn = cm206_get_upc,
.reset = cm206_reset,
.audio_ioctl = cm206_audio_ioctl,
- .dev_ioctl = cm206_ioctl,
.capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
- CDC_IOCTLS | CDC_DRIVE_STATUS,
+ CDC_DRIVE_STATUS,
.n_minors = 1,
};
@@ -1350,6 +1323,21 @@ static int cm206_block_release(struct inode *inode, struct file *file)
static int cm206_block_ioctl(struct inode *inode, struct file *file,
unsigned cmd, unsigned long arg)
{
+ switch (cmd) {
+#ifdef STATISTICS
+ case CM206CTL_GET_STAT:
+ if (arg >= NR_STATS)
+ return -EINVAL;
+ return cd->stats[arg];
+ case CM206CTL_GET_LAST_STAT:
+ if (arg >= NR_STATS)
+ return -EINVAL;
+ return cd->last_stat[arg];
+#endif
+ default:
+ break;
+ }
+
return cdrom_ioctl(file, &cm206_info, inode, cmd, arg);
}
diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c
index 466e9c2974bd..4760f515f591 100644
--- a/drivers/cdrom/sbpcd.c
+++ b/drivers/cdrom/sbpcd.c
@@ -4160,332 +4160,6 @@ static int sbpcd_get_last_session(struct cdrom_device_info *cdi, struct cdrom_mu
return 0;
}
-/*==========================================================================*/
-/*==========================================================================*/
-/*
- * ioctl support
- */
-static int sbpcd_dev_ioctl(struct cdrom_device_info *cdi, u_int cmd,
- u_long arg)
-{
- struct sbpcd_drive *p = cdi->handle;
- int i;
-
- msg(DBG_IO2,"ioctl(%s, 0x%08lX, 0x%08lX)\n", cdi->name, cmd, arg);
- if (p->drv_id==-1) {
- msg(DBG_INF, "ioctl: bad device: %s\n", cdi->name);
- return (-ENXIO); /* no such drive */
- }
- down(&ioctl_read_sem);
- if (p != current_drive)
- switch_drive(p);
-
- msg(DBG_IO2,"ioctl: device %s, request %04X\n",cdi->name,cmd);
- switch (cmd) /* Sun-compatible */
- {
- case DDIOCSDBG: /* DDI Debug */
- if (!capable(CAP_SYS_ADMIN)) RETURN_UP(-EPERM);
- i=sbpcd_dbg_ioctl(arg,1);
- RETURN_UP(i);
- case CDROMRESET: /* hard reset the drive */
- msg(DBG_IOC,"ioctl: CDROMRESET entered.\n");
- i=DriveReset();
- current_drive->audio_state=0;
- RETURN_UP(i);
-
- case CDROMREADMODE1:
- msg(DBG_IOC,"ioctl: CDROMREADMODE1 requested.\n");
-#ifdef SAFE_MIXED
- if (current_drive->has_data>1) RETURN_UP(-EBUSY);
-#endif /* SAFE_MIXED */
- cc_ModeSelect(CD_FRAMESIZE);
- cc_ModeSense();
- current_drive->mode=READ_M1;
- RETURN_UP(0);
-
- case CDROMREADMODE2: /* not usable at the moment */
- msg(DBG_IOC,"ioctl: CDROMREADMODE2 requested.\n");
-#ifdef SAFE_MIXED
- if (current_drive->has_data>1) RETURN_UP(-EBUSY);
-#endif /* SAFE_MIXED */
- cc_ModeSelect(CD_FRAMESIZE_RAW1);
- cc_ModeSense();
- current_drive->mode=READ_M2;
- RETURN_UP(0);
-
- case CDROMAUDIOBUFSIZ: /* configure the audio buffer size */
- msg(DBG_IOC,"ioctl: CDROMAUDIOBUFSIZ entered.\n");
- if (current_drive->sbp_audsiz>0)
- vfree(current_drive->aud_buf);
- current_drive->aud_buf=NULL;
- current_drive->sbp_audsiz=arg;
-
- if (current_drive->sbp_audsiz>16)
- {
- current_drive->sbp_audsiz = 0;
- RETURN_UP(current_drive->sbp_audsiz);
- }
-
- if (current_drive->sbp_audsiz>0)
- {
- current_drive->aud_buf=(u_char *) vmalloc(current_drive->sbp_audsiz*CD_FRAMESIZE_RAW);
- if (current_drive->aud_buf==NULL)
- {
- msg(DBG_INF,"audio buffer (%d frames) not available.\n",current_drive->sbp_audsiz);
- current_drive->sbp_audsiz=0;
- }
- else msg(DBG_INF,"audio buffer size: %d frames.\n",current_drive->sbp_audsiz);
- }
- RETURN_UP(current_drive->sbp_audsiz);
-
- case CDROMREADAUDIO:
- { /* start of CDROMREADAUDIO */
- int i=0, j=0, frame, block=0;
- u_int try=0;
- u_long timeout;
- u_char *p;
- u_int data_tries = 0;
- u_int data_waits = 0;
- u_int data_retrying = 0;
- int status_tries;
- int error_flag;
-
- msg(DBG_IOC,"ioctl: CDROMREADAUDIO entered.\n");
- if (fam0_drive) RETURN_UP(-EINVAL);
- if (famL_drive) RETURN_UP(-EINVAL);
- if (famV_drive) RETURN_UP(-EINVAL);
- if (famT_drive) RETURN_UP(-EINVAL);
-#ifdef SAFE_MIXED
- if (current_drive->has_data>1) RETURN_UP(-EBUSY);
-#endif /* SAFE_MIXED */
- if (current_drive->aud_buf==NULL) RETURN_UP(-EINVAL);
- if (copy_from_user(&read_audio, (void __user *)arg,
- sizeof(struct cdrom_read_audio)))
- RETURN_UP(-EFAULT);
- if (read_audio.nframes < 0 || read_audio.nframes>current_drive->sbp_audsiz) RETURN_UP(-EINVAL);
- if (!access_ok(VERIFY_WRITE, read_audio.buf,
- read_audio.nframes*CD_FRAMESIZE_RAW))
- RETURN_UP(-EFAULT);
-
- if (read_audio.addr_format==CDROM_MSF) /* MSF-bin specification of where to start */
- block=msf2lba(&read_audio.addr.msf.minute);
- else if (read_audio.addr_format==CDROM_LBA) /* lba specification of where to start */
- block=read_audio.addr.lba;
- else RETURN_UP(-EINVAL);
-#if 000
- i=cc_SetSpeed(speed_150,0,0);
- if (i) msg(DBG_AUD,"read_audio: SetSpeed error %d\n", i);
-#endif
- msg(DBG_AUD,"read_audio: lba: %d, msf: %06X\n",
- block, blk2msf(block));
- msg(DBG_AUD,"read_audio: before cc_ReadStatus.\n");
-#if OLD_BUSY
- while (busy_data) sbp_sleep(HZ/10); /* wait a bit */
- busy_audio=1;
-#endif /* OLD_BUSY */
- error_flag=0;
- for (data_tries=5; data_tries>0; data_tries--)
- {
- msg(DBG_AUD,"data_tries=%d ...\n", data_tries);
- current_drive->mode=READ_AU;
- cc_ModeSelect(CD_FRAMESIZE_RAW);
- cc_ModeSense();
- for (status_tries=3; status_tries > 0; status_tries--)
- {
- flags_cmd_out |= f_respo3;
- cc_ReadStatus();
- if (sbp_status() != 0) break;
- if (st_check) cc_ReadError();
- sbp_sleep(1); /* wait a bit, try again */
- }
- if (status_tries == 0)
- {
- msg(DBG_AUD,"read_audio: sbp_status: failed after 3 tries in line %d.\n", __LINE__);
- continue;
- }
- msg(DBG_AUD,"read_audio: sbp_status: ok.\n");
-
- flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check;
- if (fam0L_drive)
- {
- flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
- cmd_type=READ_M2;
- drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */
- drvcmd[1]=(block>>16)&0x000000ff;
- drvcmd[2]=(block>>8)&0x000000ff;
- drvcmd[3]=block&0x000000ff;
- drvcmd[4]=0;
- drvcmd[5]=read_audio.nframes; /* # of frames */
- drvcmd[6]=0;
- }
- else if (fam1_drive)
- {
- drvcmd[0]=CMD1_READ; /* "read frames", new drives */
- lba2msf(block,&drvcmd[1]); /* msf-bin format required */
- drvcmd[4]=0;
- drvcmd[5]=0;
- drvcmd[6]=read_audio.nframes; /* # of frames */
- }
- else if (fam2_drive)
- {
- drvcmd[0]=CMD2_READ_XA2;
- lba2msf(block,&drvcmd[1]); /* msf-bin format required */
- drvcmd[4]=0;
- drvcmd[5]=read_audio.nframes; /* # of frames */
- drvcmd[6]=0x11; /* raw mode */
- }
- else if (famT_drive) /* CD-55A: not tested yet */
- {
- }
- msg(DBG_AUD,"read_audio: before giving \"read\" command.\n");
- flags_cmd_out=f_putcmd;
- response_count=0;
- i=cmd_out();
- if (i<0) msg(DBG_INF,"error giving READ AUDIO command: %0d\n", i);
- sbp_sleep(0);
- msg(DBG_AUD,"read_audio: after giving \"read\" command.\n");
- for (frame=1;frame<2 && !error_flag; frame++)
- {
- try=maxtim_data;
- for (timeout=jiffies+9*HZ; ; )
- {
- for ( ; try!=0;try--)
- {
- j=inb(CDi_status);
- if (!(j&s_not_data_ready)) break;
- if (!(j&s_not_result_ready)) break;
- if (fam0L_drive) if (j&s_attention) break;
- }
- if (try != 0 || time_after_eq(jiffies, timeout)) break;
- if (data_retrying == 0) data_waits++;
- data_retrying = 1;
- sbp_sleep(1);
- try = 1;
- }
- if (try==0)
- {
- msg(DBG_INF,"read_audio: sbp_data: CDi_status timeout.\n");
- error_flag++;
- break;
- }
- msg(DBG_AUD,"read_audio: sbp_data: CDi_status ok.\n");
- if (j&s_not_data_ready)
- {
- msg(DBG_INF, "read_audio: sbp_data: DATA_READY timeout.\n");
- error_flag++;
- break;
- }
- msg(DBG_AUD,"read_audio: before reading data.\n");
- error_flag=0;
- p = current_drive->aud_buf;
- if (sbpro_type==1) OUT(CDo_sel_i_d,1);
- if (do_16bit)
- {
- u_short *p2 = (u_short *) p;
-
- for (; (u_char *) p2 < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
- {
- if ((inb_p(CDi_status)&s_not_data_ready)) continue;
-
- /* get one sample */
- *p2++ = inw_p(CDi_data);
- *p2++ = inw_p(CDi_data);
- }
- } else {
- for (; p < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
- {
- if ((inb_p(CDi_status)&s_not_data_ready)) continue;
-
- /* get one sample */
- *p++ = inb_p(CDi_data);
- *p++ = inb_p(CDi_data);
- *p++ = inb_p(CDi_data);
- *p++ = inb_p(CDi_data);
- }
- }
- if (sbpro_type==1) OUT(CDo_sel_i_d,0);
- data_retrying = 0;
- }
- msg(DBG_AUD,"read_audio: after reading data.\n");
- if (error_flag) /* must have been spurious D_RDY or (ATTN&&!D_RDY) */
- {
- msg(DBG_AUD,"read_audio: read aborted by drive\n");
-#if 0000
- i=cc_DriveReset(); /* ugly fix to prevent a hang */
-#else
- i=cc_ReadError();
-#endif
- continue;
- }
- if (fam0L_drive)
- {
- i=maxtim_data;
- for (timeout=jiffies+9*HZ; time_before(jiffies, timeout); timeout--)
- {
- for ( ;i!=0;i--)
- {
- j=inb(CDi_status);
- if (!(j&s_not_data_ready)) break;
- if (!(j&s_not_result_ready)) break;
- if (j&s_attention) break;
- }
- if (i != 0 || time_after_eq(jiffies, timeout)) break;
- sbp_sleep(0);
- i = 1;
- }
- if (i==0) msg(DBG_AUD,"read_audio: STATUS TIMEOUT AFTER READ");
- if (!(j&s_attention))
- {
- msg(DBG_AUD,"read_audio: sbp_data: timeout waiting DRV_ATTN - retrying\n");
- i=cc_DriveReset(); /* ugly fix to prevent a hang */
- continue;
- }
- }
- do
- {
- if (fam0L_drive) cc_ReadStatus();
- i=ResponseStatus(); /* builds status_bits, returns orig. status (old) or faked p_success (new) */
- if (i<0) { msg(DBG_AUD,
- "read_audio: cc_ReadStatus error after read: %02X\n",
- current_drive->status_bits);
- continue; /* FIXME */
- }
- }
- while ((fam0L_drive)&&(!st_check)&&(!(i&p_success)));
- if (st_check)
- {
- i=cc_ReadError();
- msg(DBG_AUD,"read_audio: cc_ReadError was necessary after read: %02X\n",i);
- continue;
- }
- if (copy_to_user(read_audio.buf,
- current_drive->aud_buf,
- read_audio.nframes * CD_FRAMESIZE_RAW))
- RETURN_UP(-EFAULT);
- msg(DBG_AUD,"read_audio: copy_to_user done.\n");
- break;
- }
- cc_ModeSelect(CD_FRAMESIZE);
- cc_ModeSense();
- current_drive->mode=READ_M1;
-#if OLD_BUSY
- busy_audio=0;
-#endif /* OLD_BUSY */
- if (data_tries == 0)
- {
- msg(DBG_AUD,"read_audio: failed after 5 tries in line %d.\n", __LINE__);
- RETURN_UP(-EIO);
- }
- msg(DBG_AUD,"read_audio: successful return.\n");
- RETURN_UP(0);
- } /* end of CDROMREADAUDIO */
-
- default:
- msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd);
- RETURN_UP(-EINVAL);
- } /* end switch(cmd) */
-}
-
static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
void * arg)
{
@@ -4530,7 +4204,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
default:
RETURN_UP(-EINVAL);
}
-
+
case CDROMRESUME: /* resume paused audio play */
msg(DBG_IOC,"ioctl: CDROMRESUME entered.\n");
/* resume playing audio tracks when a previous PLAY AUDIO call has */
@@ -4544,12 +4218,12 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
if (i<0) RETURN_UP(-EIO);
current_drive->audio_state=audio_playing;
RETURN_UP(0);
-
+
case CDROMPLAYMSF:
msg(DBG_IOC,"ioctl: CDROMPLAYMSF entered.\n");
#ifdef SAFE_MIXED
if (current_drive->has_data>1) RETURN_UP(-EBUSY);
-#endif /* SAFE_MIXED */
+#endif /* SAFE_MIXED */
if (current_drive->audio_state==audio_playing)
{
i=cc_Pause_Resume(1);
@@ -4584,7 +4258,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
msg(DBG_IOC,"ioctl: CDROMPLAYTRKIND entered.\n");
#ifdef SAFE_MIXED
if (current_drive->has_data>1) RETURN_UP(-EBUSY);
-#endif /* SAFE_MIXED */
+#endif /* SAFE_MIXED */
if (current_drive->audio_state==audio_playing)
{
msg(DBG_IOX,"CDROMPLAYTRKIND: already audio_playing.\n");
@@ -4654,13 +4328,13 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
cc_DriveReset();
#endif
RETURN_UP(i);
-
+
case CDROMSTART: /* Spin up the drive */
msg(DBG_IOC,"ioctl: CDROMSTART entered.\n");
cc_SpinUp();
current_drive->audio_state=0;
RETURN_UP(0);
-
+
case CDROMVOLCTRL: /* Volume control */
msg(DBG_IOC,"ioctl: CDROMVOLCTRL entered.\n");
memcpy(&volctrl,(char *) arg,sizeof(volctrl));
@@ -4670,7 +4344,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
current_drive->vol_ctrl1=volctrl.channel1;
i=cc_SetVolume();
RETURN_UP(0);
-
+
case CDROMVOLREAD: /* read Volume settings from drive */
msg(DBG_IOC,"ioctl: CDROMVOLREAD entered.\n");
st=cc_GetVolume();
@@ -4694,7 +4368,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
if (i<0) {
j=cc_ReadError(); /* clear out error status from drive */
current_drive->audio_state=CDROM_AUDIO_NO_STATUS;
- /* get and set the disk state here,
+ /* get and set the disk state here,
probably not the right place, but who cares!
It makes it work properly! --AJK */
if (current_drive->CD_changed==0xFF) {
@@ -4715,8 +4389,8 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
}
}
memcpy(&SC, (void *) arg, sizeof(struct cdrom_subchnl));
- /*
- This virtual crap is very bogus!
+ /*
+ This virtual crap is very bogus!
It doesn't detect when the cd is done playing audio!
Lets do this right with proper hardware register reading!
*/
@@ -4775,7 +4449,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
SC.cdsc_trk,SC.cdsc_ind,
SC.cdsc_absaddr,SC.cdsc_reladdr);
RETURN_UP(0);
-
+
default:
msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd);
RETURN_UP(-EINVAL);
@@ -4788,7 +4462,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd,
static void sbp_transfer(struct request *req)
{
long offs;
-
+
while ( (req->nr_sectors > 0) &&
(req->sector/4 >= current_drive->sbp_first_frame) &&
(req->sector/4 <= current_drive->sbp_last_frame) )
@@ -4807,11 +4481,11 @@ static void sbp_transfer(struct request *req)
*
* This is a kludge so we don't need to modify end_request.
* We put the req we take out after INIT_REQUEST in the requests list,
- * so that end_request will discard it.
+ * so that end_request will discard it.
*
* The bug could be present in other block devices, perhaps we
* should modify INIT_REQUEST and end_request instead, and
- * change every block device..
+ * change every block device..
*
* Could be a race here?? Could e.g. a timer interrupt schedule() us?
* If so, we should copy end_request here, and do it right.. (or
@@ -4883,19 +4557,19 @@ static void do_sbpcd_request(request_queue_t * q)
while (busy_audio) sbp_sleep(HZ); /* wait a bit */
busy_data=1;
#endif /* OLD_BUSY */
-
+
if (p->audio_state==audio_playing) goto err_done;
if (p != current_drive)
switch_drive(p);
block = req->sector; /* always numbered as 512-byte-pieces */
nsect = req->nr_sectors; /* always counted as 512-byte-pieces */
-
+
msg(DBG_BSZ,"read sector %d (%d sectors)\n", block, nsect);
#if 0
msg(DBG_MUL,"read LBA %d\n", block/4);
#endif
-
+
sbp_transfer(req);
/* if we satisfied the request from the buffer, we're done. */
if (req->nr_sectors == 0)
@@ -4914,10 +4588,10 @@ static void do_sbpcd_request(request_queue_t * q)
i=prepare(0,0); /* at moment not really a hassle check, but ... */
if (i!=0)
msg(DBG_INF,"\"prepare\" tells error %d -- ignored\n", i);
-#endif /* FUTURE */
-
+#endif /* FUTURE */
+
if (!st_spinning) cc_SpinUp();
-
+
for (data_tries=n_retries; data_tries > 0; data_tries--)
{
for (status_tries=3; status_tries > 0; status_tries--)
@@ -4940,7 +4614,7 @@ static void do_sbpcd_request(request_queue_t * q)
{
#ifdef SAFE_MIXED
current_drive->has_data=2; /* is really a data disk */
-#endif /* SAFE_MIXED */
+#endif /* SAFE_MIXED */
#ifdef DEBUG_GTL
printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 3, Time:%li\n",
xnr, req, req->sector, req->nr_sectors, jiffies);
@@ -4951,7 +4625,7 @@ static void do_sbpcd_request(request_queue_t * q)
goto request_loop;
}
}
-
+
err_done:
#if OLD_BUSY
busy_data=0;
@@ -4976,7 +4650,7 @@ static void sbp_read_cmd(struct request *req)
int i;
int block;
-
+
current_drive->sbp_first_frame=current_drive->sbp_last_frame=-1; /* purge buffer */
current_drive->sbp_current = 0;
block=req->sector/4;
@@ -4993,7 +4667,7 @@ static void sbp_read_cmd(struct request *req)
current_drive->sbp_read_frames=1;
}
}
-
+
flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check;
clr_cmdbuf();
if (famV_drive)
@@ -5092,7 +4766,7 @@ static int sbp_data(struct request *req)
int success;
int wait;
int duration;
-
+
error_flag=0;
success=0;
#if LONG_TIMING
@@ -5105,12 +4779,12 @@ static int sbp_data(struct request *req)
for (frame=0;frame<current_drive->sbp_read_frames&&!error_flag; frame++)
{
SBPCD_CLI;
-
+
del_timer(&data_timer);
data_timer.expires=jiffies+max_latency;
timed_out_data=0;
add_timer(&data_timer);
- while (!timed_out_data)
+ while (!timed_out_data)
{
if (current_drive->f_multisession) try=maxtim_data*4;
else try=maxtim_data;
@@ -5207,9 +4881,9 @@ static int sbp_data(struct request *req)
else
{
sbp_sleep(1);
- OUT(CDo_sel_i_d,0);
+ OUT(CDo_sel_i_d,0);
i=inb(CDi_status);
- }
+ }
if (!(i&s_not_data_ready))
{
OUT(CDo_sel_i_d,1);
@@ -5311,7 +4985,7 @@ static int sbp_data(struct request *req)
}
SBPCD_STI;
}
-
+
#if 0
if (!success)
#endif
@@ -5370,7 +5044,326 @@ static int sbpcd_block_ioctl(struct inode *inode, struct file *file,
unsigned cmd, unsigned long arg)
{
struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data;
- return cdrom_ioctl(file, p->sbpcd_infop, inode, cmd, arg);
+ struct cdrom_device_info *cdi = p->sbpcd_infop;
+ int ret, i;
+
+ ret = cdrom_ioctl(file, p->sbpcd_infop, inode, cmd, arg);
+ if (ret != -ENOSYS)
+ return ret;
+
+ msg(DBG_IO2,"ioctl(%s, 0x%08lX, 0x%08lX)\n", cdi->name, cmd, arg);
+ if (p->drv_id==-1) {
+ msg(DBG_INF, "ioctl: bad device: %s\n", cdi->name);
+ return (-ENXIO); /* no such drive */
+ }
+ down(&ioctl_read_sem);
+ if (p != current_drive)
+ switch_drive(p);
+
+ msg(DBG_IO2,"ioctl: device %s, request %04X\n",cdi->name,cmd);
+ switch (cmd) /* Sun-compatible */
+ {
+ case DDIOCSDBG: /* DDI Debug */
+ if (!capable(CAP_SYS_ADMIN)) RETURN_UP(-EPERM);
+ i=sbpcd_dbg_ioctl(arg,1);
+ RETURN_UP(i);
+ case CDROMRESET: /* hard reset the drive */
+ msg(DBG_IOC,"ioctl: CDROMRESET entered.\n");
+ i=DriveReset();
+ current_drive->audio_state=0;
+ RETURN_UP(i);
+
+ case CDROMREADMODE1:
+ msg(DBG_IOC,"ioctl: CDROMREADMODE1 requested.\n");
+#ifdef SAFE_MIXED
+ if (current_drive->has_data>1) RETURN_UP(-EBUSY);
+#endif /* SAFE_MIXED */
+ cc_ModeSelect(CD_FRAMESIZE);
+ cc_ModeSense();
+ current_drive->mode=READ_M1;
+ RETURN_UP(0);
+
+ case CDROMREADMODE2: /* not usable at the moment */
+ msg(DBG_IOC,"ioctl: CDROMREADMODE2 requested.\n");
+#ifdef SAFE_MIXED
+ if (current_drive->has_data>1) RETURN_UP(-EBUSY);
+#endif /* SAFE_MIXED */
+ cc_ModeSelect(CD_FRAMESIZE_RAW1);
+ cc_ModeSense();
+ current_drive->mode=READ_M2;
+ RETURN_UP(0);
+
+ case CDROMAUDIOBUFSIZ: /* configure the audio buffer size */
+ msg(DBG_IOC,"ioctl: CDROMAUDIOBUFSIZ entered.\n");
+ if (current_drive->sbp_audsiz>0)
+ vfree(current_drive->aud_buf);
+ current_drive->aud_buf=NULL;
+ current_drive->sbp_audsiz=arg;
+
+ if (current_drive->sbp_audsiz>16)
+ {
+ current_drive->sbp_audsiz = 0;
+ RETURN_UP(current_drive->sbp_audsiz);
+ }
+
+ if (current_drive->sbp_audsiz>0)
+ {
+ current_drive->aud_buf=(u_char *) vmalloc(current_drive->sbp_audsiz*CD_FRAMESIZE_RAW);
+ if (current_drive->aud_buf==NULL)
+ {
+ msg(DBG_INF,"audio buffer (%d frames) not available.\n",current_drive->sbp_audsiz);
+ current_drive->sbp_audsiz=0;
+ }
+ else msg(DBG_INF,"audio buffer size: %d frames.\n",current_drive->sbp_audsiz);
+ }
+ RETURN_UP(current_drive->sbp_audsiz);
+
+ case CDROMREADAUDIO:
+ { /* start of CDROMREADAUDIO */
+ int i=0, j=0, frame, block=0;
+ u_int try=0;
+ u_long timeout;
+ u_char *p;
+ u_int data_tries = 0;
+ u_int data_waits = 0;
+ u_int data_retrying = 0;
+ int status_tries;
+ int error_flag;
+
+ msg(DBG_IOC,"ioctl: CDROMREADAUDIO entered.\n");
+ if (fam0_drive) RETURN_UP(-EINVAL);
+ if (famL_drive) RETURN_UP(-EINVAL);
+ if (famV_drive) RETURN_UP(-EINVAL);
+ if (famT_drive) RETURN_UP(-EINVAL);
+#ifdef SAFE_MIXED
+ if (current_drive->has_data>1) RETURN_UP(-EBUSY);
+#endif /* SAFE_MIXED */
+ if (current_drive->aud_buf==NULL) RETURN_UP(-EINVAL);
+ if (copy_from_user(&read_audio, (void __user *)arg,
+ sizeof(struct cdrom_read_audio)))
+ RETURN_UP(-EFAULT);
+ if (read_audio.nframes < 0 || read_audio.nframes>current_drive->sbp_audsiz) RETURN_UP(-EINVAL);
+ if (!access_ok(VERIFY_WRITE, read_audio.buf,
+ read_audio.nframes*CD_FRAMESIZE_RAW))
+ RETURN_UP(-EFAULT);
+
+ if (read_audio.addr_format==CDROM_MSF) /* MSF-bin specification of where to start */
+ block=msf2lba(&read_audio.addr.msf.minute);
+ else if (read_audio.addr_format==CDROM_LBA) /* lba specification of where to start */
+ block=read_audio.addr.lba;
+ else RETURN_UP(-EINVAL);
+#if 000
+ i=cc_SetSpeed(speed_150,0,0);
+ if (i) msg(DBG_AUD,"read_audio: SetSpeed error %d\n", i);
+#endif
+ msg(DBG_AUD,"read_audio: lba: %d, msf: %06X\n",
+ block, blk2msf(block));
+ msg(DBG_AUD,"read_audio: before cc_ReadStatus.\n");
+#if OLD_BUSY
+ while (busy_data) sbp_sleep(HZ/10); /* wait a bit */
+ busy_audio=1;
+#endif /* OLD_BUSY */
+ error_flag=0;
+ for (data_tries=5; data_tries>0; data_tries--)
+ {
+ msg(DBG_AUD,"data_tries=%d ...\n", data_tries);
+ current_drive->mode=READ_AU;
+ cc_ModeSelect(CD_FRAMESIZE_RAW);
+ cc_ModeSense();
+ for (status_tries=3; status_tries > 0; status_tries--)
+ {
+ flags_cmd_out |= f_respo3;
+ cc_ReadStatus();
+ if (sbp_status() != 0) break;
+ if (st_check) cc_ReadError();
+ sbp_sleep(1); /* wait a bit, try again */
+ }
+ if (status_tries == 0)
+ {
+ msg(DBG_AUD,"read_audio: sbp_status: failed after 3 tries in line %d.\n", __LINE__);
+ continue;
+ }
+ msg(DBG_AUD,"read_audio: sbp_status: ok.\n");
+
+ flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check;
+ if (fam0L_drive)
+ {
+ flags_cmd_out |= f_lopsta | f_getsta | f_bit1;
+ cmd_type=READ_M2;
+ drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */
+ drvcmd[1]=(block>>16)&0x000000ff;
+ drvcmd[2]=(block>>8)&0x000000ff;
+ drvcmd[3]=block&0x000000ff;
+ drvcmd[4]=0;
+ drvcmd[5]=read_audio.nframes; /* # of frames */
+ drvcmd[6]=0;
+ }
+ else if (fam1_drive)
+ {
+ drvcmd[0]=CMD1_READ; /* "read frames", new drives */
+ lba2msf(block,&drvcmd[1]); /* msf-bin format required */
+ drvcmd[4]=0;
+ drvcmd[5]=0;
+ drvcmd[6]=read_audio.nframes; /* # of frames */
+ }
+ else if (fam2_drive)
+ {
+ drvcmd[0]=CMD2_READ_XA2;
+ lba2msf(block,&drvcmd[1]); /* msf-bin format required */
+ drvcmd[4]=0;
+ drvcmd[5]=read_audio.nframes; /* # of frames */
+ drvcmd[6]=0x11; /* raw mode */
+ }
+ else if (famT_drive) /* CD-55A: not tested yet */
+ {
+ }
+ msg(DBG_AUD,"read_audio: before giving \"read\" command.\n");
+ flags_cmd_out=f_putcmd;
+ response_count=0;
+ i=cmd_out();
+ if (i<0) msg(DBG_INF,"error giving READ AUDIO command: %0d\n", i);
+ sbp_sleep(0);
+ msg(DBG_AUD,"read_audio: after giving \"read\" command.\n");
+ for (frame=1;frame<2 && !error_flag; frame++)
+ {
+ try=maxtim_data;
+ for (timeout=jiffies+9*HZ; ; )
+ {
+ for ( ; try!=0;try--)
+ {
+ j=inb(CDi_status);
+ if (!(j&s_not_data_ready)) break;
+ if (!(j&s_not_result_ready)) break;
+ if (fam0L_drive) if (j&s_attention) break;
+ }
+ if (try != 0 || time_after_eq(jiffies, timeout)) break;
+ if (data_retrying == 0) data_waits++;
+ data_retrying = 1;
+ sbp_sleep(1);
+ try = 1;
+ }
+ if (try==0)
+ {
+ msg(DBG_INF,"read_audio: sbp_data: CDi_status timeout.\n");
+ error_flag++;
+ break;
+ }
+ msg(DBG_AUD,"read_audio: sbp_data: CDi_status ok.\n");
+ if (j&s_not_data_ready)
+ {
+ msg(DBG_INF, "read_audio: sbp_data: DATA_READY timeout.\n");
+ error_flag++;
+ break;
+ }
+ msg(DBG_AUD,"read_audio: before reading data.\n");
+ error_flag=0;
+ p = current_drive->aud_buf;
+ if (sbpro_type==1) OUT(CDo_sel_i_d,1);
+ if (do_16bit)
+ {
+ u_short *p2 = (u_short *) p;
+
+ for (; (u_char *) p2 < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
+ {
+ if ((inb_p(CDi_status)&s_not_data_ready)) continue;
+
+ /* get one sample */
+ *p2++ = inw_p(CDi_data);
+ *p2++ = inw_p(CDi_data);
+ }
+ } else {
+ for (; p < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;)
+ {
+ if ((inb_p(CDi_status)&s_not_data_ready)) continue;
+
+ /* get one sample */
+ *p++ = inb_p(CDi_data);
+ *p++ = inb_p(CDi_data);
+ *p++ = inb_p(CDi_data);
+ *p++ = inb_p(CDi_data);
+ }
+ }
+ if (sbpro_type==1) OUT(CDo_sel_i_d,0);
+ data_retrying = 0;
+ }
+ msg(DBG_AUD,"read_audio: after reading data.\n");
+ if (error_flag) /* must have been spurious D_RDY or (ATTN&&!D_RDY) */
+ {
+ msg(DBG_AUD,"read_audio: read aborted by drive\n");
+#if 0000
+ i=cc_DriveReset(); /* ugly fix to prevent a hang */
+#else
+ i=cc_ReadError();
+#endif
+ continue;
+ }
+ if (fam0L_drive)
+ {
+ i=maxtim_data;
+ for (timeout=jiffies+9*HZ; time_before(jiffies, timeout); timeout--)
+ {
+ for ( ;i!=0;i--)
+ {
+ j=inb(CDi_status);
+ if (!(j&s_not_data_ready)) break;
+ if (!(j&s_not_result_ready)) break;
+ if (j&s_attention) break;
+ }
+ if (i != 0 || time_after_eq(jiffies, timeout)) break;
+ sbp_sleep(0);
+ i = 1;
+ }
+ if (i==0) msg(DBG_AUD,"read_audio: STATUS TIMEOUT AFTER READ");
+ if (!(j&s_attention))
+ {
+ msg(DBG_AUD,"read_audio: sbp_data: timeout waiting DRV_ATTN - retrying\n");
+ i=cc_DriveReset(); /* ugly fix to prevent a hang */
+ continue;
+ }
+ }
+ do
+ {
+ if (fam0L_drive) cc_ReadStatus();
+ i=ResponseStatus(); /* builds status_bits, returns orig. status (old) or faked p_success (new) */
+ if (i<0) { msg(DBG_AUD,
+ "read_audio: cc_ReadStatus error after read: %02X\n",
+ current_drive->status_bits);
+ continue; /* FIXME */
+ }
+ }
+ while ((fam0L_drive)&&(!st_check)&&(!(i&p_success)));
+ if (st_check)
+ {
+ i=cc_ReadError();
+ msg(DBG_AUD,"read_audio: cc_ReadError was necessary after read: %02X\n",i);
+ continue;
+ }
+ if (copy_to_user(read_audio.buf,
+ current_drive->aud_buf,
+ read_audio.nframes * CD_FRAMESIZE_RAW))
+ RETURN_UP(-EFAULT);
+ msg(DBG_AUD,"read_audio: copy_to_user done.\n");
+ break;
+ }
+ cc_ModeSelect(CD_FRAMESIZE);
+ cc_ModeSense();
+ current_drive->mode=READ_M1;
+#if OLD_BUSY
+ busy_audio=0;
+#endif /* OLD_BUSY */
+ if (data_tries == 0)
+ {
+ msg(DBG_AUD,"read_audio: failed after 5 tries in line %d.\n", __LINE__);
+ RETURN_UP(-EIO);
+ }
+ msg(DBG_AUD,"read_audio: successful return.\n");
+ RETURN_UP(0);
+ } /* end of CDROMREADAUDIO */
+
+ default:
+ msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd);
+ RETURN_UP(-EINVAL);
+ } /* end switch(cmd) */
}
static int sbpcd_block_media_changed(struct gendisk *disk)
@@ -5478,10 +5471,9 @@ static struct cdrom_device_ops sbpcd_dops = {
.get_mcn = sbpcd_get_mcn,
.reset = sbpcd_reset,
.audio_ioctl = sbpcd_audio_ioctl,
- .dev_ioctl = sbpcd_dev_ioctl,
.capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
- CDC_MCN | CDC_PLAY_AUDIO | CDC_IOCTLS,
+ CDC_MCN | CDC_PLAY_AUDIO,
.n_minors = 1,
};
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index e27617259552..c0f817ba7adb 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -627,7 +627,7 @@ static struct cdrom_device_ops viocd_dops = {
.media_changed = viocd_media_changed,
.lock_door = viocd_lock_door,
.generic_packet = viocd_packet,
- .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS | CDC_GENERIC_PACKET | CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_RAM
+ .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | CDC_DRIVE_STATUS | CDC_GENERIC_PACKET | CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_RAM
};
static int __init find_capability(const char *type)
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 05ba410682a3..b524f5ba78a9 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -695,7 +695,7 @@ config NVRAM
config RTC
tristate "Enhanced Real Time Clock Support"
- depends on !PPC32 && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV
+ depends on !PPC && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV
---help---
If you say Y here and create a character special file /dev/rtc with
major number 10 and minor number 135 using mknod ("man mknod"), you
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 7ac365b5d9ec..6602b3156df5 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -46,8 +46,6 @@
/* Sanity checks */
-#define SERIAL_INLINE
-
#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
tty->name, (info->flags), serial_driver->refcount,info->count,tty->count,s)
@@ -95,10 +93,6 @@ static char *serial_version = "4.30";
#include <asm/amigahw.h>
#include <asm/amigaints.h>
-#ifdef SERIAL_INLINE
-#define _INLINE_ inline
-#endif
-
#define custom amiga_custom
static char *serial_name = "Amiga-builtin serial driver";
@@ -253,14 +247,14 @@ static void rs_start(struct tty_struct *tty)
* This routine is used by the interrupt handler to schedule
* processing in the software interrupt portion of the driver.
*/
-static _INLINE_ void rs_sched_event(struct async_struct *info,
- int event)
+static void rs_sched_event(struct async_struct *info,
+ int event)
{
info->event |= 1 << event;
tasklet_schedule(&info->tlet);
}
-static _INLINE_ void receive_chars(struct async_struct *info)
+static void receive_chars(struct async_struct *info)
{
int status;
int serdatr;
@@ -349,7 +343,7 @@ out:
return;
}
-static _INLINE_ void transmit_chars(struct async_struct *info)
+static void transmit_chars(struct async_struct *info)
{
custom.intreq = IF_TBE;
mb();
@@ -389,7 +383,7 @@ static _INLINE_ void transmit_chars(struct async_struct *info)
}
}
-static _INLINE_ void check_modem_status(struct async_struct *info)
+static void check_modem_status(struct async_struct *info)
{
unsigned char status = ciab.pra & (SER_DCD | SER_CTS | SER_DSR);
unsigned char dstatus;
@@ -1959,7 +1953,7 @@ done:
* number, and identifies which options were configured into this
* driver.
*/
-static _INLINE_ void show_serial_version(void)
+static void show_serial_version(void)
{
printk(KERN_INFO "%s version %s\n", serial_name, serial_version);
}
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index e38a5f0e07bb..5e59c0b42731 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -48,8 +48,8 @@ static int gs_debug;
#define NEW_WRITE_LOCKING 1
#if NEW_WRITE_LOCKING
#define DECL /* Nothing */
-#define LOCKIT down (& port->port_write_sem);
-#define RELEASEIT up (&port->port_write_sem);
+#define LOCKIT mutex_lock(& port->port_write_mutex);
+#define RELEASEIT mutex_unlock(&port->port_write_mutex);
#else
#define DECL unsigned long flags;
#define LOCKIT save_flags (flags);cli ()
@@ -124,14 +124,14 @@ int gs_write(struct tty_struct * tty,
/* get exclusive "write" access to this port (problem 3) */
/* This is not a spinlock because we can have a disk access (page
fault) in copy_from_user */
- down (& port->port_write_sem);
+ mutex_lock(& port->port_write_mutex);
while (1) {
c = count;
/* This is safe because we "OWN" the "head". Noone else can
- change the "head": we own the port_write_sem. */
+ change the "head": we own the port_write_mutex. */
/* Don't overrun the end of the buffer */
t = SERIAL_XMIT_SIZE - port->xmit_head;
if (t < c) c = t;
@@ -153,7 +153,7 @@ int gs_write(struct tty_struct * tty,
count -= c;
total += c;
}
- up (& port->port_write_sem);
+ mutex_unlock(& port->port_write_mutex);
gs_dprintk (GS_DEBUG_WRITE, "write: interrupts are %s\n",
(port->flags & GS_TX_INTEN)?"enabled": "disabled");
@@ -214,7 +214,7 @@ int gs_write(struct tty_struct * tty,
c = count;
/* This is safe because we "OWN" the "head". Noone else can
- change the "head": we own the port_write_sem. */
+ change the "head": we own the port_write_mutex. */
/* Don't overrun the end of the buffer */
t = SERIAL_XMIT_SIZE - port->xmit_head;
if (t < c) c = t;
@@ -888,7 +888,7 @@ int gs_init_port(struct gs_port *port)
spin_lock_irqsave (&port->driver_lock, flags);
if (port->tty)
clear_bit(TTY_IO_ERROR, &port->tty->flags);
- init_MUTEX(&port->port_write_sem);
+ mutex_init(&port->port_write_mutex);
port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
spin_unlock_irqrestore(&port->driver_lock, flags);
gs_set_termios(port->tty, NULL);
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c
index 831eb4e8d9d3..f7ac31856572 100644
--- a/drivers/char/hvcs.c
+++ b/drivers/char/hvcs.c
@@ -118,7 +118,7 @@
* the hvcs_final_close() function in order to get it out of the spinlock.
* Rearranged hvcs_close(). Cleaned up some printks and did some housekeeping
* on the changelog. Removed local CLC_LENGTH and used HVCS_CLC_LENGTH from
- * arch/ppc64/hvcserver.h.
+ * include/asm-powerpc/hvcserver.h
*
* 1.3.2 -> 1.3.3 Replaced yield() in hvcs_close() with tty_wait_until_sent() to
* prevent possible lockup with realtime scheduling as similarily pointed out by
@@ -168,9 +168,10 @@ MODULE_VERSION(HVCS_DRIVER_VERSION);
/*
* The hcall interface involves putting 8 chars into each of two registers.
- * We load up those 2 registers (in arch/ppc64/hvconsole.c) by casting char[16]
- * to long[2]. It would work without __ALIGNED__, but a little (tiny) bit
- * slower because an unaligned load is slower than aligned load.
+ * We load up those 2 registers (in arch/powerpc/platforms/pseries/hvconsole.c)
+ * by casting char[16] to long[2]. It would work without __ALIGNED__, but a
+ * little (tiny) bit slower because an unaligned load is slower than aligned
+ * load.
*/
#define __ALIGNED__ __attribute__((__aligned__(8)))
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 28c5a3193b81..ede128356af2 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -181,7 +181,6 @@ static struct tty_driver *stli_serial;
* is already swapping a shared buffer won't make things any worse.
*/
static char *stli_tmpwritebuf;
-static DECLARE_MUTEX(stli_tmpwritesem);
#define STLI_TXBUFSIZE 4096
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index ccad7ae94541..ede365d05387 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -132,7 +132,7 @@ static void put_tty_queue(unsigned char c, struct tty_struct *tty)
* We test the TTY_THROTTLED bit first so that it always
* indicates the current state. The decision about whether
* it is worth allowing more input has been taken by the caller.
- * Can sleep, may be called under the atomic_read semaphore but
+ * Can sleep, may be called under the atomic_read_lock mutex but
* this is not guaranteed.
*/
@@ -1132,7 +1132,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt)
* buffer, and once to drain the space from the (physical) beginning of
* the buffer to head pointer.
*
- * Called under the tty->atomic_read sem and with TTY_DONT_FLIP set
+ * Called under the tty->atomic_read_lock sem and with TTY_DONT_FLIP set
*
*/
@@ -1262,11 +1262,11 @@ do_it_again:
* Internal serialization of reads.
*/
if (file->f_flags & O_NONBLOCK) {
- if (down_trylock(&tty->atomic_read))
+ if (!mutex_trylock(&tty->atomic_read_lock))
return -EAGAIN;
}
else {
- if (down_interruptible(&tty->atomic_read))
+ if (mutex_lock_interruptible(&tty->atomic_read_lock))
return -ERESTARTSYS;
}
@@ -1393,7 +1393,7 @@ do_it_again:
timeout = time;
}
clear_bit(TTY_DONT_FLIP, &tty->flags);
- up(&tty->atomic_read);
+ mutex_unlock(&tty->atomic_read_lock);
remove_wait_queue(&tty->read_wait, &wait);
if (!waitqueue_active(&tty->read_wait))
diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c
index ca41d62b1d9d..8865387d3448 100644
--- a/drivers/char/nwflash.c
+++ b/drivers/char/nwflash.c
@@ -27,6 +27,7 @@
#include <linux/rwsem.h>
#include <linux/init.h>
#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <asm/hardware/dec21285.h>
#include <asm/io.h>
@@ -56,7 +57,7 @@ static int gbWriteEnable;
static int gbWriteBase64Enable;
static volatile unsigned char *FLASH_BASE;
static int gbFlashSize = KFLASH_SIZE;
-static DECLARE_MUTEX(nwflash_sem);
+static DEFINE_MUTEX(nwflash_mutex);
extern spinlock_t gpio_lock;
@@ -140,7 +141,7 @@ static ssize_t flash_read(struct file *file, char __user *buf, size_t size,
/*
* We now lock against reads and writes. --rmk
*/
- if (down_interruptible(&nwflash_sem))
+ if (mutex_lock_interruptible(&nwflash_mutex))
return -ERESTARTSYS;
ret = copy_to_user(buf, (void *)(FLASH_BASE + p), count);
@@ -149,7 +150,7 @@ static ssize_t flash_read(struct file *file, char __user *buf, size_t size,
*ppos += count;
} else
ret = -EFAULT;
- up(&nwflash_sem);
+ mutex_unlock(&nwflash_mutex);
}
return ret;
}
@@ -188,7 +189,7 @@ static ssize_t flash_write(struct file *file, const char __user *buf,
/*
* We now lock against reads and writes. --rmk
*/
- if (down_interruptible(&nwflash_sem))
+ if (mutex_lock_interruptible(&nwflash_mutex))
return -ERESTARTSYS;
written = 0;
@@ -277,7 +278,7 @@ static ssize_t flash_write(struct file *file, const char __user *buf,
*/
leds_event(led_release);
- up(&nwflash_sem);
+ mutex_unlock(&nwflash_mutex);
return written;
}
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 30e4cbe16bb0..15a7b4086524 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -19,6 +19,7 @@
#include <linux/uio.h>
#include <linux/cdev.h>
#include <linux/device.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
@@ -29,7 +30,7 @@ struct raw_device_data {
static struct class *raw_class;
static struct raw_device_data raw_devices[MAX_RAW_MINORS];
-static DECLARE_MUTEX(raw_mutex);
+static DEFINE_MUTEX(raw_mutex);
static struct file_operations raw_ctl_fops; /* forward declaration */
/*
@@ -53,7 +54,7 @@ static int raw_open(struct inode *inode, struct file *filp)
return 0;
}
- down(&raw_mutex);
+ mutex_lock(&raw_mutex);
/*
* All we need to do on open is check that the device is bound.
@@ -78,7 +79,7 @@ static int raw_open(struct inode *inode, struct file *filp)
filp->f_dentry->d_inode->i_mapping =
bdev->bd_inode->i_mapping;
filp->private_data = bdev;
- up(&raw_mutex);
+ mutex_unlock(&raw_mutex);
return 0;
out2:
@@ -86,7 +87,7 @@ out2:
out1:
blkdev_put(bdev);
out:
- up(&raw_mutex);
+ mutex_unlock(&raw_mutex);
return err;
}
@@ -99,14 +100,14 @@ static int raw_release(struct inode *inode, struct file *filp)
const int minor= iminor(inode);
struct block_device *bdev;
- down(&raw_mutex);
+ mutex_lock(&raw_mutex);
bdev = raw_devices[minor].binding;
if (--raw_devices[minor].inuse == 0) {
/* Here inode->i_mapping == bdev->bd_inode->i_mapping */
inode->i_mapping = &inode->i_data;
inode->i_mapping->backing_dev_info = &default_backing_dev_info;
}
- up(&raw_mutex);
+ mutex_unlock(&raw_mutex);
bd_release(bdev);
blkdev_put(bdev);
@@ -187,9 +188,9 @@ static int raw_ctl_ioctl(struct inode *inode, struct file *filp,
goto out;
}
- down(&raw_mutex);
+ mutex_lock(&raw_mutex);
if (rawdev->inuse) {
- up(&raw_mutex);
+ mutex_unlock(&raw_mutex);
err = -EBUSY;
goto out;
}
@@ -211,11 +212,11 @@ static int raw_ctl_ioctl(struct inode *inode, struct file *filp,
bind_device(&rq);
}
}
- up(&raw_mutex);
+ mutex_unlock(&raw_mutex);
} else {
struct block_device *bdev;
- down(&raw_mutex);
+ mutex_lock(&raw_mutex);
bdev = rawdev->binding;
if (bdev) {
rq.block_major = MAJOR(bdev->bd_dev);
@@ -223,7 +224,7 @@ static int raw_ctl_ioctl(struct inode *inode, struct file *filp,
} else {
rq.block_major = rq.block_minor = 0;
}
- up(&raw_mutex);
+ mutex_unlock(&raw_mutex);
if (copy_to_user((void __user *)arg, &rq, sizeof(rq))) {
err = -EFAULT;
goto out;
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c
index fee68cc895f8..510bd3e0e88b 100644
--- a/drivers/char/ser_a2232.c
+++ b/drivers/char/ser_a2232.c
@@ -97,7 +97,7 @@
#include <asm/amigahw.h>
#include <linux/zorro.h>
#include <asm/irq.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
#include <linux/delay.h>
@@ -654,7 +654,7 @@ static void a2232_init_portstructs(void)
port->gs.closing_wait = 30 * HZ;
port->gs.rd = &a2232_real_driver;
#ifdef NEW_WRITE_LOCKING
- init_MUTEX(&(port->gs.port_write_sem));
+ init_MUTEX(&(port->gs.port_write_mutex));
#endif
init_waitqueue_head(&port->gs.open_wait);
init_waitqueue_head(&port->gs.close_wait);
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
index 0e7d216e7eb0..b543821d8cb4 100644
--- a/drivers/char/snsc.c
+++ b/drivers/char/snsc.c
@@ -5,7 +5,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2004 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2004, 2006 Silicon Graphics, Inc. All rights reserved.
*/
/*
@@ -77,7 +77,7 @@ scdrv_open(struct inode *inode, struct file *file)
scd = container_of(inode->i_cdev, struct sysctl_data_s, scd_cdev);
/* allocate memory for subchannel data */
- sd = kmalloc(sizeof (struct subch_data_s), GFP_KERNEL);
+ sd = kzalloc(sizeof (struct subch_data_s), GFP_KERNEL);
if (sd == NULL) {
printk("%s: couldn't allocate subchannel data\n",
__FUNCTION__);
@@ -85,7 +85,6 @@ scdrv_open(struct inode *inode, struct file *file)
}
/* initialize subch_data_s fields */
- memset(sd, 0, sizeof (struct subch_data_s));
sd->sd_nasid = scd->scd_nasid;
sd->sd_subch = ia64_sn_irtr_open(scd->scd_nasid);
@@ -394,7 +393,7 @@ scdrv_init(void)
sprintf(devnamep, "#%d", geo_slab(geoid));
/* allocate sysctl device data */
- scd = kmalloc(sizeof (struct sysctl_data_s),
+ scd = kzalloc(sizeof (struct sysctl_data_s),
GFP_KERNEL);
if (!scd) {
printk("%s: failed to allocate device info"
@@ -402,7 +401,6 @@ scdrv_init(void)
SYSCTL_BASENAME, devname);
continue;
}
- memset(scd, 0, sizeof (struct sysctl_data_s));
/* initialize sysctl device data fields */
scd->scd_nasid = cnodeid_to_nasid(cnode);
diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c
index a4fa507eed9e..e234d50e142a 100644
--- a/drivers/char/snsc_event.c
+++ b/drivers/char/snsc_event.c
@@ -287,7 +287,7 @@ scdrv_event_init(struct sysctl_data_s *scd)
{
int rv;
- event_sd = kmalloc(sizeof (struct subch_data_s), GFP_KERNEL);
+ event_sd = kzalloc(sizeof (struct subch_data_s), GFP_KERNEL);
if (event_sd == NULL) {
printk(KERN_WARNING "%s: couldn't allocate subchannel info"
" for event monitoring\n", __FUNCTION__);
@@ -295,7 +295,6 @@ scdrv_event_init(struct sysctl_data_s *scd)
}
/* initialize subch_data_s fields */
- memset(event_sd, 0, sizeof (struct subch_data_s));
event_sd->sd_nasid = scd->scd_nasid;
spin_lock_init(&event_sd->sd_rlock);
@@ -321,5 +320,3 @@ scdrv_event_init(struct sysctl_data_s *scd)
return;
}
}
-
-
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index bdaab6992109..3f5d6077f39c 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -148,7 +148,6 @@ static struct tty_driver *stl_serial;
* is already swapping a shared buffer won't make things any worse.
*/
static char *stl_tmpwritebuf;
-static DECLARE_MUTEX(stl_tmpwritesem);
/*
* Define a local default termios struct. All ports will be created
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index a6b4f02bdceb..3b4747230270 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -2318,7 +2318,7 @@ static int sx_init_portstructs (int nboards, int nports)
port->board = board;
port->gs.rd = &sx_real_driver;
#ifdef NEW_WRITE_LOCKING
- port->gs.port_write_sem = MUTEX;
+ port->gs.port_write_mutex = MUTEX;
#endif
port->gs.driver_lock = SPIN_LOCK_UNLOCKED;
/*
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 53d3d066554e..76592ee1fb38 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -130,7 +130,7 @@ LIST_HEAD(tty_drivers); /* linked list of tty drivers */
/* Semaphore to protect creating and releasing a tty. This is shared with
vt.c for deeply disgusting hack reasons */
-DECLARE_MUTEX(tty_sem);
+DEFINE_MUTEX(tty_mutex);
#ifdef CONFIG_UNIX98_PTYS
extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */
@@ -1188,11 +1188,11 @@ void disassociate_ctty(int on_exit)
lock_kernel();
- down(&tty_sem);
+ mutex_lock(&tty_mutex);
tty = current->signal->tty;
if (tty) {
tty_pgrp = tty->pgrp;
- up(&tty_sem);
+ mutex_unlock(&tty_mutex);
if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
tty_vhangup(tty);
} else {
@@ -1200,7 +1200,7 @@ void disassociate_ctty(int on_exit)
kill_pg(current->signal->tty_old_pgrp, SIGHUP, on_exit);
kill_pg(current->signal->tty_old_pgrp, SIGCONT, on_exit);
}
- up(&tty_sem);
+ mutex_unlock(&tty_mutex);
unlock_kernel();
return;
}
@@ -1211,7 +1211,7 @@ void disassociate_ctty(int on_exit)
}
/* Must lock changes to tty_old_pgrp */
- down(&tty_sem);
+ mutex_lock(&tty_mutex);
current->signal->tty_old_pgrp = 0;
tty->session = 0;
tty->pgrp = -1;
@@ -1222,7 +1222,7 @@ void disassociate_ctty(int on_exit)
p->signal->tty = NULL;
} while_each_task_pid(current->signal->session, PIDTYPE_SID, p);
read_unlock(&tasklist_lock);
- up(&tty_sem);
+ mutex_unlock(&tty_mutex);
unlock_kernel();
}
@@ -1306,7 +1306,7 @@ static inline ssize_t do_tty_write(
ssize_t ret = 0, written = 0;
unsigned int chunk;
- if (down_interruptible(&tty->atomic_write)) {
+ if (mutex_lock_interruptible(&tty->atomic_write_lock)) {
return -ERESTARTSYS;
}
@@ -1329,7 +1329,7 @@ static inline ssize_t do_tty_write(
if (count < chunk)
chunk = count;
- /* write_buf/write_cnt is protected by the atomic_write semaphore */
+ /* write_buf/write_cnt is protected by the atomic_write_lock mutex */
if (tty->write_cnt < chunk) {
unsigned char *buf;
@@ -1338,7 +1338,7 @@ static inline ssize_t do_tty_write(
buf = kmalloc(chunk, GFP_KERNEL);
if (!buf) {
- up(&tty->atomic_write);
+ mutex_unlock(&tty->atomic_write_lock);
return -ENOMEM;
}
kfree(tty->write_buf);
@@ -1374,7 +1374,7 @@ static inline ssize_t do_tty_write(
inode->i_mtime = current_fs_time(inode->i_sb);
ret = written;
}
- up(&tty->atomic_write);
+ mutex_unlock(&tty->atomic_write_lock);
return ret;
}
@@ -1442,8 +1442,8 @@ static inline void tty_line_name(struct tty_driver *driver, int index, char *p)
/*
* WSH 06/09/97: Rewritten to remove races and properly clean up after a
- * failed open. The new code protects the open with a semaphore, so it's
- * really quite straightforward. The semaphore locking can probably be
+ * failed open. The new code protects the open with a mutex, so it's
+ * really quite straightforward. The mutex locking can probably be
* relaxed for the (most common) case of reopening a tty.
*/
static int init_dev(struct tty_driver *driver, int idx,
@@ -1640,7 +1640,7 @@ fast_track:
success:
*ret_tty = tty;
- /* All paths come through here to release the semaphore */
+ /* All paths come through here to release the mutex */
end_init:
return retval;
@@ -1837,7 +1837,7 @@ static void release_dev(struct file * filp)
/* Guard against races with tty->count changes elsewhere and
opens on /dev/tty */
- down(&tty_sem);
+ mutex_lock(&tty_mutex);
tty_closing = tty->count <= 1;
o_tty_closing = o_tty &&
(o_tty->count <= (pty_master ? 1 : 0));
@@ -1868,7 +1868,7 @@ static void release_dev(struct file * filp)
printk(KERN_WARNING "release_dev: %s: read/write wait queue "
"active!\n", tty_name(tty, buf));
- up(&tty_sem);
+ mutex_unlock(&tty_mutex);
schedule();
}
@@ -1934,7 +1934,7 @@ static void release_dev(struct file * filp)
read_unlock(&tasklist_lock);
}
- up(&tty_sem);
+ mutex_unlock(&tty_mutex);
/* check whether both sides are closing ... */
if (!tty_closing || (o_tty && !o_tty_closing))
@@ -2040,11 +2040,11 @@ retry_open:
index = -1;
retval = 0;
- down(&tty_sem);
+ mutex_lock(&tty_mutex);
if (device == MKDEV(TTYAUX_MAJOR,0)) {
if (!current->signal->tty) {
- up(&tty_sem);
+ mutex_unlock(&tty_mutex);
return -ENXIO;
}
driver = current->signal->tty->driver;
@@ -2070,18 +2070,18 @@ retry_open:
noctty = 1;
goto got_driver;
}
- up(&tty_sem);
+ mutex_unlock(&tty_mutex);
return -ENODEV;
}
driver = get_tty_driver(device, &index);
if (!driver) {
- up(&tty_sem);
+ mutex_unlock(&tty_mutex);
return -ENODEV;
}
got_driver:
retval = init_dev(driver, index, &tty);
- up(&tty_sem);
+ mutex_unlock(&tty_mutex);
if (retval)
return retval;
@@ -2167,9 +2167,9 @@ static int ptmx_open(struct inode * inode, struct file * filp)
}
up(&allocated_ptys_lock);
- down(&tty_sem);
+ mutex_lock(&tty_mutex);
retval = init_dev(ptm_driver, index, &tty);
- up(&tty_sem);
+ mutex_unlock(&tty_mutex);
if (retval)
goto out;
@@ -2915,8 +2915,8 @@ static void initialize_tty_struct(struct tty_struct *tty)
init_waitqueue_head(&tty->write_wait);
init_waitqueue_head(&tty->read_wait);
INIT_WORK(&tty->hangup_work, do_tty_hangup, tty);
- sema_init(&tty->atomic_read, 1);
- sema_init(&tty->atomic_write, 1);
+ mutex_init(&tty->atomic_read_lock);
+ mutex_init(&tty->atomic_write_lock);
spin_lock_init(&tty->read_lock);
INIT_LIST_HEAD(&tty->tty_files);
INIT_WORK(&tty->SAK_work, NULL, NULL);
diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c
index d9325281e482..fd00822ac145 100644
--- a/drivers/char/vme_scc.c
+++ b/drivers/char/vme_scc.c
@@ -184,7 +184,7 @@ static void scc_init_portstructs(void)
port->gs.closing_wait = 30 * HZ;
port->gs.rd = &scc_real_driver;
#ifdef NEW_WRITE_LOCKING
- port->gs.port_write_sem = MUTEX;
+ port->gs.port_write_mutex = MUTEX;
#endif
init_waitqueue_head(&port->gs.open_wait);
init_waitqueue_head(&port->gs.close_wait);
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 0900d1dbee59..ca4844c527da 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -2489,7 +2489,7 @@ static int con_open(struct tty_struct *tty, struct file *filp)
}
/*
- * We take tty_sem in here to prevent another thread from coming in via init_dev
+ * We take tty_mutex in here to prevent another thread from coming in via init_dev
* and taking a ref against the tty while we're in the process of forgetting
* about it and cleaning things up.
*
@@ -2497,7 +2497,7 @@ static int con_open(struct tty_struct *tty, struct file *filp)
*/
static void con_close(struct tty_struct *tty, struct file *filp)
{
- down(&tty_sem);
+ mutex_lock(&tty_mutex);
acquire_console_sem();
if (tty && tty->count == 1) {
struct vc_data *vc = tty->driver_data;
@@ -2507,15 +2507,15 @@ static void con_close(struct tty_struct *tty, struct file *filp)
tty->driver_data = NULL;
release_console_sem();
vcs_remove_devfs(tty);
- up(&tty_sem);
+ mutex_unlock(&tty_mutex);
/*
- * tty_sem is released, but we still hold BKL, so there is
+ * tty_mutex is released, but we still hold BKL, so there is
* still exclusion against init_dev()
*/
return;
}
release_console_sem();
- up(&tty_sem);
+ mutex_unlock(&tty_mutex);
}
static void vc_init(struct vc_data *vc, unsigned int rows,
@@ -2869,9 +2869,9 @@ void unblank_screen(void)
}
/*
- * We defer the timer blanking to work queue so it can take the console semaphore
+ * We defer the timer blanking to work queue so it can take the console mutex
* (console operations can still happen at irq time, but only from printk which
- * has the console semaphore. Not perfect yet, but better than no locking
+ * has the console mutex. Not perfect yet, but better than no locking
*/
static void blank_screen_t(unsigned long dummy)
{
@@ -3234,6 +3234,14 @@ void vcs_scr_writew(struct vc_data *vc, u16 val, u16 *org)
}
}
+int is_console_suspend_safe(void)
+{
+ /* It is unsafe to suspend devices while X has control of the
+ * hardware. Make sure we are running on a kernel-controlled console.
+ */
+ return vc_cons[fg_console].d->vc_mode == KD_TEXT;
+}
+
/*
* Visible symbols for modules
*/
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c
index 1533f56baa42..2700c5c45b8a 100644
--- a/drivers/char/watchdog/pcwd_usb.c
+++ b/drivers/char/watchdog/pcwd_usb.c
@@ -42,6 +42,7 @@
#include <linux/completion.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
+#include <linux/mutex.h>
#ifdef CONFIG_USB_DEBUG
@@ -143,7 +144,7 @@ struct usb_pcwd_private {
static struct usb_pcwd_private *usb_pcwd_device;
/* prevent races between open() and disconnect() */
-static DECLARE_MUTEX (disconnect_sem);
+static DEFINE_MUTEX(disconnect_mutex);
/* local function prototypes */
static int usb_pcwd_probe (struct usb_interface *interface, const struct usb_device_id *id);
@@ -723,7 +724,7 @@ static void usb_pcwd_disconnect(struct usb_interface *interface)
struct usb_pcwd_private *usb_pcwd;
/* prevent races with open() */
- down (&disconnect_sem);
+ mutex_lock(&disconnect_mutex);
usb_pcwd = usb_get_intfdata (interface);
usb_set_intfdata (interface, NULL);
@@ -749,7 +750,7 @@ static void usb_pcwd_disconnect(struct usb_interface *interface)
cards_found--;
- up (&disconnect_sem);
+ mutex_unlock(&disconnect_mutex);
printk(KERN_INFO PFX "USB PC Watchdog disconnected\n");
}
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index d7125f4d9113..35897079a78d 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -26,6 +26,7 @@
#include <linux/netlink.h>
#include <linux/moduleparam.h>
#include <linux/connector.h>
+#include <linux/mutex.h>
#include <net/sock.h>
@@ -41,7 +42,7 @@ module_param(cn_val, uint, 0);
MODULE_PARM_DESC(cn_idx, "Connector's main device idx.");
MODULE_PARM_DESC(cn_val, "Connector's main device val.");
-static DECLARE_MUTEX(notify_lock);
+static DEFINE_MUTEX(notify_lock);
static LIST_HEAD(notify_list);
static struct cn_dev cdev;
@@ -260,7 +261,7 @@ static void cn_notify(struct cb_id *id, u32 notify_event)
{
struct cn_ctl_entry *ent;
- down(&notify_lock);
+ mutex_lock(&notify_lock);
list_for_each_entry(ent, &notify_list, notify_entry) {
int i;
struct cn_notify_req *req;
@@ -293,7 +294,7 @@ static void cn_notify(struct cb_id *id, u32 notify_event)
cn_netlink_send(&m, ctl->group, GFP_KERNEL);
}
}
- up(&notify_lock);
+ mutex_unlock(&notify_lock);
}
/*
@@ -407,14 +408,14 @@ static void cn_callback(void *data)
if (ctl->group == 0) {
struct cn_ctl_entry *n;
- down(&notify_lock);
+ mutex_lock(&notify_lock);
list_for_each_entry_safe(ent, n, &notify_list, notify_entry) {
if (cn_ctl_msg_equals(ent->msg, ctl)) {
list_del(&ent->notify_entry);
kfree(ent);
}
}
- up(&notify_lock);
+ mutex_unlock(&notify_lock);
return;
}
@@ -429,9 +430,9 @@ static void cn_callback(void *data)
memcpy(ent->msg, ctl, size - sizeof(*ent));
- down(&notify_lock);
+ mutex_lock(&notify_lock);
list_add(&ent->notify_entry, &notify_list);
- up(&notify_lock);
+ mutex_unlock(&notify_lock);
}
static int __init cn_init(void)
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
index 3a4e5c5b4e1f..d6543fc4a923 100644
--- a/drivers/firmware/dcdbas.c
+++ b/drivers/firmware/dcdbas.c
@@ -33,6 +33,7 @@
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/types.h>
+#include <linux/mutex.h>
#include <asm/io.h>
#include <asm/semaphore.h>
@@ -48,7 +49,7 @@ static u8 *smi_data_buf;
static dma_addr_t smi_data_buf_handle;
static unsigned long smi_data_buf_size;
static u32 smi_data_buf_phys_addr;
-static DECLARE_MUTEX(smi_data_lock);
+static DEFINE_MUTEX(smi_data_lock);
static unsigned int host_control_action;
static unsigned int host_control_smi_type;
@@ -139,9 +140,9 @@ static ssize_t smi_data_buf_size_store(struct device *dev,
buf_size = simple_strtoul(buf, NULL, 10);
/* make sure SMI data buffer is at least buf_size */
- down(&smi_data_lock);
+ mutex_lock(&smi_data_lock);
ret = smi_data_buf_realloc(buf_size);
- up(&smi_data_lock);
+ mutex_unlock(&smi_data_lock);
if (ret)
return ret;
@@ -154,7 +155,7 @@ static ssize_t smi_data_read(struct kobject *kobj, char *buf, loff_t pos,
size_t max_read;
ssize_t ret;
- down(&smi_data_lock);
+ mutex_lock(&smi_data_lock);
if (pos >= smi_data_buf_size) {
ret = 0;
@@ -165,7 +166,7 @@ static ssize_t smi_data_read(struct kobject *kobj, char *buf, loff_t pos,
ret = min(max_read, count);
memcpy(buf, smi_data_buf + pos, ret);
out:
- up(&smi_data_lock);
+ mutex_unlock(&smi_data_lock);
return ret;
}
@@ -174,7 +175,7 @@ static ssize_t smi_data_write(struct kobject *kobj, char *buf, loff_t pos,
{
ssize_t ret;
- down(&smi_data_lock);
+ mutex_lock(&smi_data_lock);
ret = smi_data_buf_realloc(pos + count);
if (ret)
@@ -183,7 +184,7 @@ static ssize_t smi_data_write(struct kobject *kobj, char *buf, loff_t pos,
memcpy(smi_data_buf + pos, buf, count);
ret = count;
out:
- up(&smi_data_lock);
+ mutex_unlock(&smi_data_lock);
return ret;
}
@@ -201,9 +202,9 @@ static ssize_t host_control_action_store(struct device *dev,
ssize_t ret;
/* make sure buffer is available for host control command */
- down(&smi_data_lock);
+ mutex_lock(&smi_data_lock);
ret = smi_data_buf_realloc(sizeof(struct apm_cmd));
- up(&smi_data_lock);
+ mutex_unlock(&smi_data_lock);
if (ret)
return ret;
@@ -302,7 +303,7 @@ static ssize_t smi_request_store(struct device *dev,
unsigned long val = simple_strtoul(buf, NULL, 10);
ssize_t ret;
- down(&smi_data_lock);
+ mutex_lock(&smi_data_lock);
if (smi_data_buf_size < sizeof(struct smi_cmd)) {
ret = -ENODEV;
@@ -334,7 +335,7 @@ static ssize_t smi_request_store(struct device *dev,
}
out:
- up(&smi_data_lock);
+ mutex_unlock(&smi_data_lock);
return ret;
}
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 3325660f7248..c7671e188017 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -313,6 +313,7 @@
#include <linux/cdrom.h>
#include <linux/ide.h>
#include <linux/completion.h>
+#include <linux/mutex.h>
#include <scsi/scsi.h> /* For SCSI -> ATAPI command conversion */
@@ -324,7 +325,7 @@
#include "ide-cd.h"
-static DECLARE_MUTEX(idecd_ref_sem);
+static DEFINE_MUTEX(idecd_ref_mutex);
#define to_ide_cd(obj) container_of(obj, struct cdrom_info, kref)
@@ -335,11 +336,11 @@ static struct cdrom_info *ide_cd_get(struct gendisk *disk)
{
struct cdrom_info *cd = NULL;
- down(&idecd_ref_sem);
+ mutex_lock(&idecd_ref_mutex);
cd = ide_cd_g(disk);
if (cd)
kref_get(&cd->kref);
- up(&idecd_ref_sem);
+ mutex_unlock(&idecd_ref_mutex);
return cd;
}
@@ -347,9 +348,9 @@ static void ide_cd_release(struct kref *);
static void ide_cd_put(struct cdrom_info *cd)
{
- down(&idecd_ref_sem);
+ mutex_lock(&idecd_ref_mutex);
kref_put(&cd->kref, ide_cd_release);
- up(&idecd_ref_sem);
+ mutex_unlock(&idecd_ref_mutex);
}
/****************************************************************************
@@ -2471,52 +2472,6 @@ static int ide_cdrom_packet(struct cdrom_device_info *cdi,
}
static
-int ide_cdrom_dev_ioctl (struct cdrom_device_info *cdi,
- unsigned int cmd, unsigned long arg)
-{
- struct packet_command cgc;
- char buffer[16];
- int stat;
-
- init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
-
- /* These will be moved into the Uniform layer shortly... */
- switch (cmd) {
- case CDROMSETSPINDOWN: {
- char spindown;
-
- if (copy_from_user(&spindown, (void __user *) arg, sizeof(char)))
- return -EFAULT;
-
- if ((stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0)))
- return stat;
-
- buffer[11] = (buffer[11] & 0xf0) | (spindown & 0x0f);
-
- return cdrom_mode_select(cdi, &cgc);
- }
-
- case CDROMGETSPINDOWN: {
- char spindown;
-
- if ((stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0)))
- return stat;
-
- spindown = buffer[11] & 0x0f;
-
- if (copy_to_user((void __user *) arg, &spindown, sizeof (char)))
- return -EFAULT;
-
- return 0;
- }
-
- default:
- return -EINVAL;
- }
-
-}
-
-static
int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
unsigned int cmd, void *arg)
@@ -2852,12 +2807,11 @@ static struct cdrom_device_ops ide_cdrom_dops = {
.get_mcn = ide_cdrom_get_mcn,
.reset = ide_cdrom_reset,
.audio_ioctl = ide_cdrom_audio_ioctl,
- .dev_ioctl = ide_cdrom_dev_ioctl,
.capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
CDC_SELECT_SPEED | CDC_SELECT_DISC |
CDC_MULTI_SESSION | CDC_MCN |
CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET |
- CDC_IOCTLS | CDC_DRIVE_STATUS | CDC_CD_R |
+ CDC_DRIVE_STATUS | CDC_CD_R |
CDC_CD_RW | CDC_DVD | CDC_DVD_R| CDC_DVD_RAM |
CDC_GENERIC_PACKET | CDC_MO_DRIVE | CDC_MRW |
CDC_MRW_W | CDC_RAM,
@@ -3367,6 +3321,45 @@ static int idecd_release(struct inode * inode, struct file * file)
return 0;
}
+static int idecd_set_spindown(struct cdrom_device_info *cdi, unsigned long arg)
+{
+ struct packet_command cgc;
+ char buffer[16];
+ int stat;
+ char spindown;
+
+ if (copy_from_user(&spindown, (void __user *)arg, sizeof(char)))
+ return -EFAULT;
+
+ init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
+
+ stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0);
+ if (stat)
+ return stat;
+
+ buffer[11] = (buffer[11] & 0xf0) | (spindown & 0x0f);
+ return cdrom_mode_select(cdi, &cgc);
+}
+
+static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg)
+{
+ struct packet_command cgc;
+ char buffer[16];
+ int stat;
+ char spindown;
+
+ init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
+
+ stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0);
+ if (stat)
+ return stat;
+
+ spindown = buffer[11] & 0x0f;
+ if (copy_to_user((void __user *)arg, &spindown, sizeof (char)))
+ return -EFAULT;
+ return 0;
+}
+
static int idecd_ioctl (struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
@@ -3374,7 +3367,16 @@ static int idecd_ioctl (struct inode *inode, struct file *file,
struct cdrom_info *info = ide_cd_g(bdev->bd_disk);
int err;
- err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg);
+ switch (cmd) {
+ case CDROMSETSPINDOWN:
+ return idecd_set_spindown(&info->devinfo, arg);
+ case CDROMGETSPINDOWN:
+ return idecd_get_spindown(&info->devinfo, arg);
+ default:
+ break;
+ }
+
+ err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg);
if (err == -EINVAL)
err = cdrom_ioctl(file, &info->devinfo, inode, cmd, arg);
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 09086b8b6486..e238b7da824b 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -60,6 +60,7 @@
#include <linux/genhd.h>
#include <linux/slab.h>
#include <linux/delay.h>
+#include <linux/mutex.h>
#define _IDE_DISK
@@ -78,7 +79,7 @@ struct ide_disk_obj {
struct kref kref;
};
-static DECLARE_MUTEX(idedisk_ref_sem);
+static DEFINE_MUTEX(idedisk_ref_mutex);
#define to_ide_disk(obj) container_of(obj, struct ide_disk_obj, kref)
@@ -89,11 +90,11 @@ static struct ide_disk_obj *ide_disk_get(struct gendisk *disk)
{
struct ide_disk_obj *idkp = NULL;
- down(&idedisk_ref_sem);
+ mutex_lock(&idedisk_ref_mutex);
idkp = ide_disk_g(disk);
if (idkp)
kref_get(&idkp->kref);
- up(&idedisk_ref_sem);
+ mutex_unlock(&idedisk_ref_mutex);
return idkp;
}
@@ -101,9 +102,9 @@ static void ide_disk_release(struct kref *);
static void ide_disk_put(struct ide_disk_obj *idkp)
{
- down(&idedisk_ref_sem);
+ mutex_lock(&idedisk_ref_mutex);
kref_put(&idkp->kref, ide_disk_release);
- up(&idedisk_ref_sem);
+ mutex_unlock(&idedisk_ref_mutex);
}
/*
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 1f8db9ac05d1..a53e3ce4a142 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -98,6 +98,7 @@
#include <linux/cdrom.h>
#include <linux/ide.h>
#include <linux/bitops.h>
+#include <linux/mutex.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
@@ -517,7 +518,7 @@ typedef struct {
u8 reserved[4];
} idefloppy_mode_parameter_header_t;
-static DECLARE_MUTEX(idefloppy_ref_sem);
+static DEFINE_MUTEX(idefloppy_ref_mutex);
#define to_ide_floppy(obj) container_of(obj, struct ide_floppy_obj, kref)
@@ -528,11 +529,11 @@ static struct ide_floppy_obj *ide_floppy_get(struct gendisk *disk)
{
struct ide_floppy_obj *floppy = NULL;
- down(&idefloppy_ref_sem);
+ mutex_lock(&idefloppy_ref_mutex);
floppy = ide_floppy_g(disk);
if (floppy)
kref_get(&floppy->kref);
- up(&idefloppy_ref_sem);
+ mutex_unlock(&idefloppy_ref_mutex);
return floppy;
}
@@ -540,9 +541,9 @@ static void ide_floppy_release(struct kref *);
static void ide_floppy_put(struct ide_floppy_obj *floppy)
{
- down(&idefloppy_ref_sem);
+ mutex_lock(&idefloppy_ref_mutex);
kref_put(&floppy->kref, ide_floppy_release);
- up(&idefloppy_ref_sem);
+ mutex_unlock(&idefloppy_ref_mutex);
}
/*
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 0101d0def7c5..ebc59064b475 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -443,6 +443,7 @@
#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <linux/bitops.h>
+#include <linux/mutex.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
@@ -1011,7 +1012,7 @@ typedef struct ide_tape_obj {
int debug_level;
} idetape_tape_t;
-static DECLARE_MUTEX(idetape_ref_sem);
+static DEFINE_MUTEX(idetape_ref_mutex);
static struct class *idetape_sysfs_class;
@@ -1024,11 +1025,11 @@ static struct ide_tape_obj *ide_tape_get(struct gendisk *disk)
{
struct ide_tape_obj *tape = NULL;
- down(&idetape_ref_sem);
+ mutex_lock(&idetape_ref_mutex);
tape = ide_tape_g(disk);
if (tape)
kref_get(&tape->kref);
- up(&idetape_ref_sem);
+ mutex_unlock(&idetape_ref_mutex);
return tape;
}
@@ -1036,9 +1037,9 @@ static void ide_tape_release(struct kref *);
static void ide_tape_put(struct ide_tape_obj *tape)
{
- down(&idetape_ref_sem);
+ mutex_lock(&idetape_ref_mutex);
kref_put(&tape->kref, ide_tape_release);
- up(&idetape_ref_sem);
+ mutex_unlock(&idetape_ref_mutex);
}
/*
@@ -1290,11 +1291,11 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i)
{
struct ide_tape_obj *tape = NULL;
- down(&idetape_ref_sem);
+ mutex_lock(&idetape_ref_mutex);
tape = idetape_devs[i];
if (tape)
kref_get(&tape->kref);
- up(&idetape_ref_sem);
+ mutex_unlock(&idetape_ref_mutex);
return tape;
}
@@ -4870,11 +4871,11 @@ static int ide_tape_probe(ide_drive_t *drive)
drive->driver_data = tape;
- down(&idetape_ref_sem);
+ mutex_lock(&idetape_ref_mutex);
for (minor = 0; idetape_devs[minor]; minor++)
;
idetape_devs[minor] = tape;
- up(&idetape_ref_sem);
+ mutex_unlock(&idetape_ref_mutex);
idetape_setup(drive, tape, minor);
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
index feec40cf5900..8c4fcb9027b3 100644
--- a/drivers/isdn/capi/kcapi.c
+++ b/drivers/isdn/capi/kcapi.c
@@ -32,6 +32,7 @@
#ifdef CONFIG_AVMB1_COMPAT
#include <linux/b1lli.h>
#endif
+#include <linux/mutex.h>
static char *revision = "$Revision: 1.1.2.8 $";
@@ -66,7 +67,7 @@ LIST_HEAD(capi_drivers);
DEFINE_RWLOCK(capi_drivers_list_lock);
static DEFINE_RWLOCK(application_lock);
-static DECLARE_MUTEX(controller_sem);
+static DEFINE_MUTEX(controller_mutex);
struct capi20_appl *capi_applications[CAPI_MAXAPPL];
struct capi_ctr *capi_cards[CAPI_MAXCONTR];
@@ -395,20 +396,20 @@ attach_capi_ctr(struct capi_ctr *card)
{
int i;
- down(&controller_sem);
+ mutex_lock(&controller_mutex);
for (i = 0; i < CAPI_MAXCONTR; i++) {
if (capi_cards[i] == NULL)
break;
}
if (i == CAPI_MAXCONTR) {
- up(&controller_sem);
+ mutex_unlock(&controller_mutex);
printk(KERN_ERR "kcapi: out of controller slots\n");
return -EBUSY;
}
capi_cards[i] = card;
- up(&controller_sem);
+ mutex_unlock(&controller_mutex);
card->nrecvctlpkt = 0;
card->nrecvdatapkt = 0;
@@ -531,13 +532,13 @@ u16 capi20_register(struct capi20_appl *ap)
write_unlock_irqrestore(&application_lock, flags);
- down(&controller_sem);
+ mutex_lock(&controller_mutex);
for (i = 0; i < CAPI_MAXCONTR; i++) {
if (!capi_cards[i] || capi_cards[i]->cardstate != CARD_RUNNING)
continue;
register_appl(capi_cards[i], applid, &ap->rparam);
}
- up(&controller_sem);
+ mutex_unlock(&controller_mutex);
if (showcapimsgs & 1) {
printk(KERN_DEBUG "kcapi: appl %d up\n", applid);
@@ -560,13 +561,13 @@ u16 capi20_release(struct capi20_appl *ap)
capi_applications[ap->applid - 1] = NULL;
write_unlock_irqrestore(&application_lock, flags);
- down(&controller_sem);
+ mutex_lock(&controller_mutex);
for (i = 0; i < CAPI_MAXCONTR; i++) {
if (!capi_cards[i] || capi_cards[i]->cardstate != CARD_RUNNING)
continue;
release_appl(capi_cards[i], ap->applid);
}
- up(&controller_sem);
+ mutex_unlock(&controller_mutex);
flush_scheduled_work();
skb_queue_purge(&ap->recv_queue);
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index df9d65201819..27332506f9f7 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -25,7 +25,6 @@
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#define HISAX_STATUS_BUFSIZE 4096
-#define INCLUDE_INLINE_FUNCS
/*
* This structure array contains one entry per card. An entry looks
diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c
index 110e9fd669c5..f8ca4b323331 100644
--- a/drivers/isdn/hisax/elsa.c
+++ b/drivers/isdn/hisax/elsa.c
@@ -108,7 +108,6 @@ static const char *ITACVer[] =
#define ELSA_ASSIGN 4
#define RS_ISR_PASS_LIMIT 256
-#define _INLINE_ inline
#define FLG_MODEM_ACTIVE 1
/* IPAC AUX */
#define ELSA_IPAC_LINE_LED 0x40 /* Bit 6 Gelbe LED */
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index 69596f6438e9..431bd37225a1 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -550,15 +550,12 @@ static void macio_pci_add_devices(struct macio_chip *chip)
*/
int macio_register_driver(struct macio_driver *drv)
{
- int count = 0;
-
/* initialize common driver fields */
drv->driver.name = drv->name;
drv->driver.bus = &macio_bus_type;
/* register with core */
- count = driver_register(&drv->driver);
- return count ? count : 1;
+ return driver_register(&drv->driver);
}
/**
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index db2ae71d07ef..4eb05d7143d8 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -629,8 +629,6 @@ static struct of_platform_driver smu_of_platform_driver =
static int __init smu_init_sysfs(void)
{
- int rc;
-
/*
* Due to sysfs bogosity, a sysdev is not a real device, so
* we should in fact create both if we want sysdev semantics
@@ -639,7 +637,7 @@ static int __init smu_init_sysfs(void)
* I'm a bit too far from figuring out how that works with those
* new chipsets, but that will come back and bite us
*/
- rc = of_register_driver(&smu_of_platform_driver);
+ of_register_driver(&smu_of_platform_driver);
return 0;
}
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index 4f50ee5767a2..231146f439dd 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -104,7 +104,6 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/sched.h>
-#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/spinlock.h>
@@ -113,7 +112,6 @@
#include <linux/reboot.h>
#include <linux/kmod.h>
#include <linux/i2c.h>
-#include <linux/i2c-dev.h>
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/io.h>
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 4a478eb0e27d..4f5f3abc9cb3 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -161,7 +161,9 @@ static int drop_interrupts;
#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
static int option_lid_wakeup = 1;
#endif /* CONFIG_PM && CONFIG_PPC32 */
+#if (defined(CONFIG_PM)&&defined(CONFIG_PPC32))||defined(CONFIG_PMAC_BACKLIGHT)
static int sleep_in_progress;
+#endif
static unsigned long async_req_locks;
static unsigned int pmu_irq_stats[11];
@@ -2201,8 +2203,7 @@ pmac_wakeup_devices(void)
#define GRACKLE_NAP (1<<4)
#define GRACKLE_SLEEP (1<<3)
-int
-powerbook_sleep_grackle(void)
+static int powerbook_sleep_grackle(void)
{
unsigned long save_l2cr;
unsigned short pmcr1;
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c
index 423bfa2432c0..3f7967feaf5b 100644
--- a/drivers/macintosh/windfarm_lm75_sensor.c
+++ b/drivers/macintosh/windfarm_lm75_sensor.c
@@ -15,7 +15,6 @@
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/i2c.h>
-#include <linux/i2c-dev.h>
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/io.h>
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c
index 8e99d408fddd..eae1189d6c41 100644
--- a/drivers/macintosh/windfarm_max6690_sensor.c
+++ b/drivers/macintosh/windfarm_max6690_sensor.c
@@ -11,7 +11,6 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
-#include <linux/i2c-dev.h>
#include <asm/prom.h>
#include <asm/pmac_low_i2c.h>
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c
index 24e51d5e97fc..e295a07a1ebc 100644
--- a/drivers/macintosh/windfarm_smu_sat.c
+++ b/drivers/macintosh/windfarm_smu_sat.c
@@ -13,7 +13,6 @@
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/i2c.h>
-#include <linux/i2c-dev.h>
#include <asm/semaphore.h>
#include <asm/prom.h>
#include <asm/smu.h>
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 00993e8ba589..e20b849a22e8 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2172,6 +2172,7 @@ config BNX2
config SPIDER_NET
tristate "Spider Gigabit Ethernet driver"
depends on PCI && PPC_CELL
+ select FW_LOADER
help
This driver supports the Gigabit Ethernet chips present on the
Cell Processor-Based Blades from IBM.
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index 690a1aae0b34..0c13795dca38 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -172,11 +172,9 @@ static struct net_device_stats *get_stats(struct net_device *dev)
memset(stats, 0, sizeof(struct net_device_stats));
- for (i=0; i < NR_CPUS; i++) {
+ for_each_cpu(i) {
struct net_device_stats *lb_stats;
- if (!cpu_possible(i))
- continue;
lb_stats = &per_cpu(loopback_stats, i);
stats->rx_bytes += lb_stats->rx_bytes;
stats->tx_bytes += lb_stats->tx_bytes;
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index f608c12e3e8b..b2073fce8216 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -46,6 +46,7 @@
#include <linux/rwsem.h>
#include <linux/stddef.h>
#include <linux/device.h>
+#include <linux/mutex.h>
#include <net/slhc_vj.h>
#include <asm/atomic.h>
@@ -198,11 +199,11 @@ static unsigned int cardmap_find_first_free(struct cardmap *map);
static void cardmap_destroy(struct cardmap **map);
/*
- * all_ppp_sem protects the all_ppp_units mapping.
+ * all_ppp_mutex protects the all_ppp_units mapping.
* It also ensures that finding a ppp unit in the all_ppp_units map
* and updating its file.refcnt field is atomic.
*/
-static DECLARE_MUTEX(all_ppp_sem);
+static DEFINE_MUTEX(all_ppp_mutex);
static struct cardmap *all_ppp_units;
static atomic_t ppp_unit_count = ATOMIC_INIT(0);
@@ -804,7 +805,7 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
/* Attach to an existing ppp unit */
if (get_user(unit, p))
break;
- down(&all_ppp_sem);
+ mutex_lock(&all_ppp_mutex);
err = -ENXIO;
ppp = ppp_find_unit(unit);
if (ppp != 0) {
@@ -812,7 +813,7 @@ static int ppp_unattached_ioctl(struct ppp_file *pf, struct file *file,
file->private_data = &ppp->file;
err = 0;
}
- up(&all_ppp_sem);
+ mutex_unlock(&all_ppp_mutex);
break;
case PPPIOCATTCHAN:
@@ -2446,7 +2447,7 @@ ppp_create_interface(int unit, int *retp)
dev->do_ioctl = ppp_net_ioctl;
ret = -EEXIST;
- down(&all_ppp_sem);
+ mutex_lock(&all_ppp_mutex);
if (unit < 0)
unit = cardmap_find_first_free(all_ppp_units);
else if (cardmap_get(all_ppp_units, unit) != NULL)
@@ -2465,12 +2466,12 @@ ppp_create_interface(int unit, int *retp)
atomic_inc(&ppp_unit_count);
cardmap_set(&all_ppp_units, unit, ppp);
- up(&all_ppp_sem);
+ mutex_unlock(&all_ppp_mutex);
*retp = 0;
return ppp;
out2:
- up(&all_ppp_sem);
+ mutex_unlock(&all_ppp_mutex);
free_netdev(dev);
out1:
kfree(ppp);
@@ -2500,7 +2501,7 @@ static void ppp_shutdown_interface(struct ppp *ppp)
{
struct net_device *dev;
- down(&all_ppp_sem);
+ mutex_lock(&all_ppp_mutex);
ppp_lock(ppp);
dev = ppp->dev;
ppp->dev = NULL;
@@ -2514,7 +2515,7 @@ static void ppp_shutdown_interface(struct ppp *ppp)
ppp->file.dead = 1;
ppp->owner = NULL;
wake_up_interruptible(&ppp->file.rwait);
- up(&all_ppp_sem);
+ mutex_unlock(&all_ppp_mutex);
}
/*
@@ -2556,7 +2557,7 @@ static void ppp_destroy_interface(struct ppp *ppp)
/*
* Locate an existing ppp unit.
- * The caller should have locked the all_ppp_sem.
+ * The caller should have locked the all_ppp_mutex.
*/
static struct ppp *
ppp_find_unit(int unit)
@@ -2601,7 +2602,7 @@ ppp_connect_channel(struct channel *pch, int unit)
int ret = -ENXIO;
int hdrlen;
- down(&all_ppp_sem);
+ mutex_lock(&all_ppp_mutex);
ppp = ppp_find_unit(unit);
if (ppp == 0)
goto out;
@@ -2626,7 +2627,7 @@ ppp_connect_channel(struct channel *pch, int unit)
outl:
write_unlock_bh(&pch->upl);
out:
- up(&all_ppp_sem);
+ mutex_unlock(&all_ppp_mutex);
return ret;
}
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
index 78193e4bbdb5..330d3869b41e 100644
--- a/drivers/oprofile/cpu_buffer.c
+++ b/drivers/oprofile/cpu_buffer.c
@@ -38,9 +38,8 @@ void free_cpu_buffers(void)
{
int i;
- for_each_online_cpu(i) {
+ for_each_online_cpu(i)
vfree(cpu_buffer[i].buffer);
- }
}
int alloc_cpu_buffers(void)
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c
index 5e38cd7335f7..c89c98a2cca8 100644
--- a/drivers/pnp/pnpbios/rsparser.c
+++ b/drivers/pnp/pnpbios/rsparser.c
@@ -448,11 +448,7 @@ pnpbios_parse_resource_option_data(unsigned char * p, unsigned char * end, struc
break;
case SMALL_TAG_END:
- if (option_independent != option)
- printk(KERN_WARNING "PnPBIOS: Missing SMALL_TAG_ENDDEP tag\n");
- p = p + 2;
- return (unsigned char *)p;
- break;
+ return p + 2;
default: /* an unkown tag */
len_err:
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index fafeeae52675..f9930552ab54 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -151,9 +151,9 @@ dasd_ioctl_enable(struct block_device *bdev, int no, long args)
return -ENODEV;
dasd_enable_device(device);
/* Formatting the dasd device can change the capacity. */
- down(&bdev->bd_sem);
+ mutex_lock(&bdev->bd_mutex);
i_size_write(bdev->bd_inode, (loff_t)get_capacity(device->gdp) << 9);
- up(&bdev->bd_sem);
+ mutex_unlock(&bdev->bd_mutex);
return 0;
}
@@ -184,9 +184,9 @@ dasd_ioctl_disable(struct block_device *bdev, int no, long args)
* Set i_size to zero, since read, write, etc. check against this
* value.
*/
- down(&bdev->bd_sem);
+ mutex_lock(&bdev->bd_mutex);
i_size_write(bdev->bd_inode, 0);
- up(&bdev->bd_sem);
+ mutex_unlock(&bdev->bd_mutex);
return 0;
}
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 0cf0e4c7ac0c..39b760a24241 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -47,6 +47,7 @@
#include <linux/ide.h>
#include <linux/scatterlist.h>
#include <linux/delay.h>
+#include <linux/mutex.h>
#include <asm/io.h>
#include <asm/bitops.h>
@@ -109,7 +110,7 @@ typedef struct ide_scsi_obj {
unsigned long log; /* log flags */
} idescsi_scsi_t;
-static DECLARE_MUTEX(idescsi_ref_sem);
+static DEFINE_MUTEX(idescsi_ref_mutex);
#define ide_scsi_g(disk) \
container_of((disk)->private_data, struct ide_scsi_obj, driver)
@@ -118,19 +119,19 @@ static struct ide_scsi_obj *ide_scsi_get(struct gendisk *disk)
{
struct ide_scsi_obj *scsi = NULL;
- down(&idescsi_ref_sem);
+ mutex_lock(&idescsi_ref_mutex);
scsi = ide_scsi_g(disk);
if (scsi)
scsi_host_get(scsi->host);
- up(&idescsi_ref_sem);
+ mutex_unlock(&idescsi_ref_mutex);
return scsi;
}
static void ide_scsi_put(struct ide_scsi_obj *scsi)
{
- down(&idescsi_ref_sem);
+ mutex_lock(&idescsi_ref_mutex);
scsi_host_put(scsi->host);
- up(&idescsi_ref_sem);
+ mutex_unlock(&idescsi_ref_mutex);
}
static inline idescsi_scsi_t *scsihost_to_idescsi(struct Scsi_Host *host)
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index f9c1192dc15e..7c80711e18ed 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -71,7 +71,7 @@ MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_CDROM_MAJOR);
#define SR_CAPABILITIES \
(CDC_CLOSE_TRAY|CDC_OPEN_TRAY|CDC_LOCK|CDC_SELECT_SPEED| \
CDC_SELECT_DISC|CDC_MULTI_SESSION|CDC_MCN|CDC_MEDIA_CHANGED| \
- CDC_PLAY_AUDIO|CDC_RESET|CDC_IOCTLS|CDC_DRIVE_STATUS| \
+ CDC_PLAY_AUDIO|CDC_RESET|CDC_DRIVE_STATUS| \
CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_DVD_RAM|CDC_GENERIC_PACKET| \
CDC_MRW|CDC_MRW_W|CDC_RAM)
@@ -118,7 +118,6 @@ static struct cdrom_device_ops sr_dops = {
.get_mcn = sr_get_mcn,
.reset = sr_reset,
.audio_ioctl = sr_audio_ioctl,
- .dev_ioctl = sr_dev_ioctl,
.capability = SR_CAPABILITIES,
.generic_packet = sr_packet,
};
@@ -456,17 +455,33 @@ static int sr_block_ioctl(struct inode *inode, struct file *file, unsigned cmd,
{
struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk);
struct scsi_device *sdev = cd->device;
+ void __user *argp = (void __user *)arg;
+ int ret;
- /*
- * Send SCSI addressing ioctls directly to mid level, send other
- * ioctls to cdrom/block level.
- */
- switch (cmd) {
- case SCSI_IOCTL_GET_IDLUN:
- case SCSI_IOCTL_GET_BUS_NUMBER:
- return scsi_ioctl(sdev, cmd, (void __user *)arg);
+ /*
+ * Send SCSI addressing ioctls directly to mid level, send other
+ * ioctls to cdrom/block level.
+ */
+ switch (cmd) {
+ case SCSI_IOCTL_GET_IDLUN:
+ case SCSI_IOCTL_GET_BUS_NUMBER:
+ return scsi_ioctl(sdev, cmd, argp);
}
- return cdrom_ioctl(file, &cd->cdi, inode, cmd, arg);
+
+ ret = cdrom_ioctl(file, &cd->cdi, inode, cmd, arg);
+ if (ret != ENOSYS)
+ return ret;
+
+ /*
+ * ENODEV means that we didn't recognise the ioctl, or that we
+ * cannot execute it in the current device state. In either
+ * case fall through to scsi_ioctl, which will return ENDOEV again
+ * if it doesn't recognise the ioctl
+ */
+ ret = scsi_nonblockable_ioctl(sdev, cmd, argp, NULL);
+ if (ret != -ENODEV)
+ return ret;
+ return scsi_ioctl(sdev, cmd, argp);
}
static int sr_block_media_changed(struct gendisk *disk)
diff --git a/drivers/scsi/sr.h b/drivers/scsi/sr.h
index d2bcd99c272f..d65de9621b27 100644
--- a/drivers/scsi/sr.h
+++ b/drivers/scsi/sr.h
@@ -55,7 +55,6 @@ int sr_get_mcn(struct cdrom_device_info *, struct cdrom_mcn *);
int sr_reset(struct cdrom_device_info *);
int sr_select_speed(struct cdrom_device_info *cdi, int speed);
int sr_audio_ioctl(struct cdrom_device_info *, unsigned int, void *);
-int sr_dev_ioctl(struct cdrom_device_info *, unsigned int, unsigned long);
int sr_is_xa(Scsi_CD *);
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c
index b65462f76484..d1268cb46837 100644
--- a/drivers/scsi/sr_ioctl.c
+++ b/drivers/scsi/sr_ioctl.c
@@ -562,22 +562,3 @@ int sr_is_xa(Scsi_CD *cd)
#endif
return is_xa;
}
-
-int sr_dev_ioctl(struct cdrom_device_info *cdi,
- unsigned int cmd, unsigned long arg)
-{
- Scsi_CD *cd = cdi->handle;
- int ret;
-
- ret = scsi_nonblockable_ioctl(cd->device, cmd,
- (void __user *)arg, NULL);
- /*
- * ENODEV means that we didn't recognise the ioctl, or that we
- * cannot execute it in the current device state. In either
- * case fall through to scsi_ioctl, which will return ENDOEV again
- * if it doesn't recognise the ioctl
- */
- if (ret != -ENODEV)
- return ret;
- return scsi_ioctl(cd->device, cmd, (void __user *)arg);
-}
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index 7f0f35a05dca..b88a7c1158af 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -101,8 +101,6 @@ struct tty_driver *serial_driver;
#define RS_ISR_PASS_LIMIT 256
-#define _INLINE_ inline
-
static void change_speed(struct m68k_serial *info);
/*
@@ -262,7 +260,7 @@ static void batten_down_hatches(void)
/* Drop into the debugger */
}
-static _INLINE_ void status_handle(struct m68k_serial *info, unsigned short status)
+static void status_handle(struct m68k_serial *info, unsigned short status)
{
#if 0
if(status & DCD) {
@@ -289,7 +287,8 @@ static _INLINE_ void status_handle(struct m68k_serial *info, unsigned short stat
return;
}
-static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *regs, unsigned short rx)
+static void receive_chars(struct m68k_serial *info, struct pt_regs *regs,
+ unsigned short rx)
{
struct tty_struct *tty = info->tty;
m68328_uart *uart = &uart_addr[info->line];
@@ -359,7 +358,7 @@ clear_and_exit:
return;
}
-static _INLINE_ void transmit_chars(struct m68k_serial *info)
+static void transmit_chars(struct m68k_serial *info)
{
m68328_uart *uart = &uart_addr[info->line];
diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c
index 29f94bbb79be..948880ac5878 100644
--- a/drivers/serial/au1x00_uart.c
+++ b/drivers/serial/au1x00_uart.c
@@ -133,13 +133,12 @@ static const struct serial_uart_config uart_config[PORT_MAX_8250+1] = {
{ "AU1X00_UART",16, UART_CLEAR_FIFO | UART_USE_FIFO },
};
-static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset)
+static unsigned int serial_in(struct uart_8250_port *up, int offset)
{
return au_readl((unsigned long)up->port.membase + offset);
}
-static _INLINE_ void
-serial_out(struct uart_8250_port *up, int offset, int value)
+static void serial_out(struct uart_8250_port *up, int offset, int value)
{
au_writel(value, (unsigned long)up->port.membase + offset);
}
@@ -237,7 +236,7 @@ static void serial8250_enable_ms(struct uart_port *port)
serial_out(up, UART_IER, up->ier);
}
-static _INLINE_ void
+static void
receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs)
{
struct tty_struct *tty = up->port.info->tty;
@@ -312,7 +311,7 @@ receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs)
spin_lock(&up->port.lock);
}
-static _INLINE_ void transmit_chars(struct uart_8250_port *up)
+static void transmit_chars(struct uart_8250_port *up)
{
struct circ_buf *xmit = &up->port.info->xmit;
int count;
@@ -346,7 +345,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up)
serial8250_stop_tx(&up->port);
}
-static _INLINE_ void check_modem_status(struct uart_8250_port *up)
+static void check_modem_status(struct uart_8250_port *up)
{
int status;
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index be12623d8544..89700141f87e 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -481,8 +481,6 @@ static char *serial_version = "$Revision: 1.25 $";
#include "serial_compat.h"
#endif
-#define _INLINE_ inline
-
struct tty_driver *serial_driver;
/* serial subtype definitions */
@@ -591,8 +589,6 @@ static void rs_throttle(struct tty_struct * tty);
static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
static int rs_write(struct tty_struct * tty, int from_user,
const unsigned char *buf, int count);
-extern _INLINE_ int rs_raw_write(struct tty_struct * tty, int from_user,
- const unsigned char *buf, int count);
#ifdef CONFIG_ETRAX_RS485
static int e100_write_rs485(struct tty_struct * tty, int from_user,
const unsigned char *buf, int count);
@@ -1538,8 +1534,7 @@ e100_enable_rxdma_irq(struct e100_serial *info)
/* the tx DMA uses only dma_descr interrupt */
-static _INLINE_ void
-e100_disable_txdma_irq(struct e100_serial *info)
+static void e100_disable_txdma_irq(struct e100_serial *info)
{
#ifdef SERIAL_DEBUG_INTR
printk("txdma_irq(%d): 0\n",info->line);
@@ -1548,8 +1543,7 @@ e100_disable_txdma_irq(struct e100_serial *info)
*R_IRQ_MASK2_CLR = info->irq;
}
-static _INLINE_ void
-e100_enable_txdma_irq(struct e100_serial *info)
+static void e100_enable_txdma_irq(struct e100_serial *info)
{
#ifdef SERIAL_DEBUG_INTR
printk("txdma_irq(%d): 1\n",info->line);
@@ -1558,8 +1552,7 @@ e100_enable_txdma_irq(struct e100_serial *info)
*R_IRQ_MASK2_SET = info->irq;
}
-static _INLINE_ void
-e100_disable_txdma_channel(struct e100_serial *info)
+static void e100_disable_txdma_channel(struct e100_serial *info)
{
unsigned long flags;
@@ -1599,8 +1592,7 @@ e100_disable_txdma_channel(struct e100_serial *info)
}
-static _INLINE_ void
-e100_enable_txdma_channel(struct e100_serial *info)
+static void e100_enable_txdma_channel(struct e100_serial *info)
{
unsigned long flags;
@@ -1625,8 +1617,7 @@ e100_enable_txdma_channel(struct e100_serial *info)
restore_flags(flags);
}
-static _INLINE_ void
-e100_disable_rxdma_channel(struct e100_serial *info)
+static void e100_disable_rxdma_channel(struct e100_serial *info)
{
unsigned long flags;
@@ -1665,8 +1656,7 @@ e100_disable_rxdma_channel(struct e100_serial *info)
}
-static _INLINE_ void
-e100_enable_rxdma_channel(struct e100_serial *info)
+static void e100_enable_rxdma_channel(struct e100_serial *info)
{
unsigned long flags;
@@ -1913,9 +1903,7 @@ rs_start(struct tty_struct *tty)
* This routine is used by the interrupt handler to schedule
* processing in the software interrupt portion of the driver.
*/
-static _INLINE_ void
-rs_sched_event(struct e100_serial *info,
- int event)
+static void rs_sched_event(struct e100_serial *info, int event)
{
if (info->event & (1 << event))
return;
@@ -2155,8 +2143,9 @@ add_char_and_flag(struct e100_serial *info, unsigned char data, unsigned char fl
return 1;
}
-extern _INLINE_ unsigned int
-handle_descr_data(struct e100_serial *info, struct etrax_dma_descr *descr, unsigned int recvl)
+static unsigned int handle_descr_data(struct e100_serial *info,
+ struct etrax_dma_descr *descr,
+ unsigned int recvl)
{
struct etrax_recv_buffer *buffer = phys_to_virt(descr->buf) - sizeof *buffer;
@@ -2182,8 +2171,7 @@ handle_descr_data(struct e100_serial *info, struct etrax_dma_descr *descr, unsig
return recvl;
}
-static _INLINE_ unsigned int
-handle_all_descr_data(struct e100_serial *info)
+static unsigned int handle_all_descr_data(struct e100_serial *info)
{
struct etrax_dma_descr *descr;
unsigned int recvl;
@@ -2230,8 +2218,7 @@ handle_all_descr_data(struct e100_serial *info)
return ret;
}
-static _INLINE_ void
-receive_chars_dma(struct e100_serial *info)
+static void receive_chars_dma(struct e100_serial *info)
{
struct tty_struct *tty;
unsigned char rstat;
@@ -2292,8 +2279,7 @@ receive_chars_dma(struct e100_serial *info)
*info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, restart);
}
-static _INLINE_ int
-start_recv_dma(struct e100_serial *info)
+static int start_recv_dma(struct e100_serial *info)
{
struct etrax_dma_descr *descr = info->rec_descr;
struct etrax_recv_buffer *buffer;
@@ -2348,11 +2334,6 @@ start_receive(struct e100_serial *info)
}
-static _INLINE_ void
-status_handle(struct e100_serial *info, unsigned short status)
-{
-}
-
/* the bits in the MASK2 register are laid out like this:
DMAI_EOP DMAI_DESCR DMAO_EOP DMAO_DESCR
where I is the input channel and O is the output channel for the port.
@@ -2454,8 +2435,7 @@ rec_interrupt(int irq, void *dev_id, struct pt_regs * regs)
return IRQ_RETVAL(handled);
} /* rec_interrupt */
-static _INLINE_ int
-force_eop_if_needed(struct e100_serial *info)
+static int force_eop_if_needed(struct e100_serial *info)
{
/* We check data_avail bit to determine if data has
* arrived since last time
@@ -2499,8 +2479,7 @@ force_eop_if_needed(struct e100_serial *info)
return 1;
}
-extern _INLINE_ void
-flush_to_flip_buffer(struct e100_serial *info)
+static void flush_to_flip_buffer(struct e100_serial *info)
{
struct tty_struct *tty;
struct etrax_recv_buffer *buffer;
@@ -2611,8 +2590,7 @@ flush_to_flip_buffer(struct e100_serial *info)
tty_flip_buffer_push(tty);
}
-static _INLINE_ void
-check_flush_timeout(struct e100_serial *info)
+static void check_flush_timeout(struct e100_serial *info)
{
/* Flip what we've got (if we can) */
flush_to_flip_buffer(info);
@@ -2741,7 +2719,7 @@ TODO: The break will be delayed until an F or V character is received.
*/
-extern _INLINE_
+static
struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info)
{
unsigned long data_read;
@@ -2875,8 +2853,7 @@ more_data:
return info;
}
-extern _INLINE_
-struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info)
+static struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info)
{
unsigned char rstat;
@@ -2995,7 +2972,7 @@ struct e100_serial* handle_ser_rx_interrupt(struct e100_serial *info)
return info;
} /* handle_ser_rx_interrupt */
-extern _INLINE_ void handle_ser_tx_interrupt(struct e100_serial *info)
+static void handle_ser_tx_interrupt(struct e100_serial *info)
{
unsigned long flags;
@@ -3621,9 +3598,8 @@ rs_flush_chars(struct tty_struct *tty)
restore_flags(flags);
}
-extern _INLINE_ int
-rs_raw_write(struct tty_struct * tty, int from_user,
- const unsigned char *buf, int count)
+static int rs_raw_write(struct tty_struct * tty, int from_user,
+ const unsigned char *buf, int count)
{
int c, ret = 0;
struct e100_serial *info = (struct e100_serial *)tty->driver_data;
@@ -4710,7 +4686,7 @@ rs_open(struct tty_struct *tty, struct file * filp)
* /proc fs routines....
*/
-extern _INLINE_ int line_info(char *buf, struct e100_serial *info)
+static int line_info(char *buf, struct e100_serial *info)
{
char stat_buf[30];
int ret;
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c
index 876bc5e027bb..e9c10c0a30fc 100644
--- a/drivers/serial/m32r_sio.c
+++ b/drivers/serial/m32r_sio.c
@@ -248,17 +248,17 @@ static void sio_error(int *status)
#endif /* CONFIG_SERIAL_M32R_PLDSIO */
-static _INLINE_ unsigned int sio_in(struct uart_sio_port *up, int offset)
+static unsigned int sio_in(struct uart_sio_port *up, int offset)
{
return __sio_in(up->port.iobase + offset);
}
-static _INLINE_ void sio_out(struct uart_sio_port *up, int offset, int value)
+static void sio_out(struct uart_sio_port *up, int offset, int value)
{
__sio_out(value, up->port.iobase + offset);
}
-static _INLINE_ unsigned int serial_in(struct uart_sio_port *up, int offset)
+static unsigned int serial_in(struct uart_sio_port *up, int offset)
{
if (!offset)
return 0;
@@ -266,8 +266,7 @@ static _INLINE_ unsigned int serial_in(struct uart_sio_port *up, int offset)
return __sio_in(offset);
}
-static _INLINE_ void
-serial_out(struct uart_sio_port *up, int offset, int value)
+static void serial_out(struct uart_sio_port *up, int offset, int value)
{
if (!offset)
return;
@@ -326,8 +325,8 @@ static void m32r_sio_enable_ms(struct uart_port *port)
serial_out(up, UART_IER, up->ier);
}
-static _INLINE_ void receive_chars(struct uart_sio_port *up, int *status,
- struct pt_regs *regs)
+static void receive_chars(struct uart_sio_port *up, int *status,
+ struct pt_regs *regs)
{
struct tty_struct *tty = up->port.info->tty;
unsigned char ch;
@@ -400,7 +399,7 @@ static _INLINE_ void receive_chars(struct uart_sio_port *up, int *status,
tty_flip_buffer_push(tty);
}
-static _INLINE_ void transmit_chars(struct uart_sio_port *up)
+static void transmit_chars(struct uart_sio_port *up)
{
struct circ_buf *xmit = &up->port.info->xmit;
int count;
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 7fc3d3b41d18..9fe2283d91e5 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -102,9 +102,7 @@ struct uart_sunsu_port {
#endif
};
-#define _INLINE_
-
-static _INLINE_ unsigned int serial_in(struct uart_sunsu_port *up, int offset)
+static unsigned int serial_in(struct uart_sunsu_port *up, int offset)
{
offset <<= up->port.regshift;
@@ -121,8 +119,7 @@ static _INLINE_ unsigned int serial_in(struct uart_sunsu_port *up, int offset)
}
}
-static _INLINE_ void
-serial_out(struct uart_sunsu_port *up, int offset, int value)
+static void serial_out(struct uart_sunsu_port *up, int offset, int value)
{
#ifndef CONFIG_SPARC64
/*
@@ -316,7 +313,7 @@ static void sunsu_enable_ms(struct uart_port *port)
spin_unlock_irqrestore(&up->port.lock, flags);
}
-static _INLINE_ struct tty_struct *
+static struct tty_struct *
receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs *regs)
{
struct tty_struct *tty = up->port.info->tty;
@@ -395,7 +392,7 @@ receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs
return tty;
}
-static _INLINE_ void transmit_chars(struct uart_sunsu_port *up)
+static void transmit_chars(struct uart_sunsu_port *up)
{
struct circ_buf *xmit = &up->port.info->xmit;
int count;
@@ -431,7 +428,7 @@ static _INLINE_ void transmit_chars(struct uart_sunsu_port *up)
__stop_tx(up);
}
-static _INLINE_ void check_modem_status(struct uart_sunsu_port *up)
+static void check_modem_status(struct uart_sunsu_port *up)
{
int status;
diff --git a/drivers/tc/zs.c b/drivers/tc/zs.c
index 6756d0fab6fe..2dffa8e303b2 100644
--- a/drivers/tc/zs.c
+++ b/drivers/tc/zs.c
@@ -186,8 +186,6 @@ static struct tty_driver *serial_driver;
#define RS_STROBE_TIME 10
#define RS_ISR_PASS_LIMIT 256
-#define _INLINE_ inline
-
static void probe_sccs(void);
static void change_speed(struct dec_serial *info);
static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
@@ -344,14 +342,13 @@ static inline void rs_recv_clear(struct dec_zschannel *zsc)
* This routine is used by the interrupt handler to schedule
* processing in the software interrupt portion of the driver.
*/
-static _INLINE_ void rs_sched_event(struct dec_serial *info, int event)
+static void rs_sched_event(struct dec_serial *info, int event)
{
info->event |= 1 << event;
tasklet_schedule(&info->tlet);
}
-static _INLINE_ void receive_chars(struct dec_serial *info,
- struct pt_regs *regs)
+static void receive_chars(struct dec_serial *info, struct pt_regs *regs)
{
struct tty_struct *tty = info->tty;
unsigned char ch, stat, flag;
@@ -441,7 +438,7 @@ static void transmit_chars(struct dec_serial *info)
rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
}
-static _INLINE_ void status_handle(struct dec_serial *info)
+static void status_handle(struct dec_serial *info)
{
unsigned char stat;
diff --git a/fs/9p/mux.c b/fs/9p/mux.c
index ea1134eb47c8..8e8356c1c229 100644
--- a/fs/9p/mux.c
+++ b/fs/9p/mux.c
@@ -31,6 +31,7 @@
#include <linux/poll.h>
#include <linux/kthread.h>
#include <linux/idr.h>
+#include <linux/mutex.h>
#include "debug.h"
#include "v9fs.h"
@@ -110,7 +111,7 @@ static void v9fs_pollwait(struct file *filp, wait_queue_head_t * wait_address,
static u16 v9fs_mux_get_tag(struct v9fs_mux_data *);
static void v9fs_mux_put_tag(struct v9fs_mux_data *, u16);
-static DECLARE_MUTEX(v9fs_mux_task_lock);
+static DEFINE_MUTEX(v9fs_mux_task_lock);
static struct workqueue_struct *v9fs_mux_wq;
static int v9fs_mux_num;
@@ -166,7 +167,7 @@ static int v9fs_mux_poll_start(struct v9fs_mux_data *m)
dprintk(DEBUG_MUX, "mux %p muxnum %d procnum %d\n", m, v9fs_mux_num,
v9fs_mux_poll_task_num);
- up(&v9fs_mux_task_lock);
+ mutex_lock(&v9fs_mux_task_lock);
n = v9fs_mux_calc_poll_procs(v9fs_mux_num + 1);
if (n > v9fs_mux_poll_task_num) {
@@ -225,7 +226,7 @@ static int v9fs_mux_poll_start(struct v9fs_mux_data *m)
}
v9fs_mux_num++;
- down(&v9fs_mux_task_lock);
+ mutex_unlock(&v9fs_mux_task_lock);
return 0;
}
@@ -235,7 +236,7 @@ static void v9fs_mux_poll_stop(struct v9fs_mux_data *m)
int i;
struct v9fs_mux_poll_task *vpt;
- up(&v9fs_mux_task_lock);
+ mutex_lock(&v9fs_mux_task_lock);
vpt = m->poll_task;
list_del(&m->mux_list);
for(i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) {
@@ -252,7 +253,7 @@ static void v9fs_mux_poll_stop(struct v9fs_mux_data *m)
v9fs_mux_poll_task_num--;
}
v9fs_mux_num--;
- down(&v9fs_mux_task_lock);
+ mutex_unlock(&v9fs_mux_task_lock);
}
/**
diff --git a/fs/adfs/file.c b/fs/adfs/file.c
index afebbfde6968..6af10885f9d6 100644
--- a/fs/adfs/file.c
+++ b/fs/adfs/file.c
@@ -19,11 +19,7 @@
*
* adfs regular file handling primitives
*/
-#include <linux/errno.h>
#include <linux/fs.h>
-#include <linux/fcntl.h>
-#include <linux/time.h>
-#include <linux/stat.h>
#include <linux/buffer_head.h> /* for file_fsync() */
#include <linux/adfs_fs.h>
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index 385bed09b0d8..f54c5b21f876 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -13,6 +13,7 @@
/* Internal header file for autofs */
#include <linux/auto_fs4.h>
+#include <linux/mutex.h>
#include <linux/list.h>
/* This is the range of ioctl() numbers we claim as ours */
@@ -102,7 +103,7 @@ struct autofs_sb_info {
int reghost_enabled;
int needs_reghost;
struct super_block *sb;
- struct semaphore wq_sem;
+ struct mutex wq_mutex;
spinlock_t fs_lock;
struct autofs_wait_queue *queues; /* Wait queue pointer */
};
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 2d3082854a29..1ad98d48e550 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -269,7 +269,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
sbi->sb = s;
sbi->version = 0;
sbi->sub_version = 0;
- init_MUTEX(&sbi->wq_sem);
+ mutex_init(&sbi->wq_mutex);
spin_lock_init(&sbi->fs_lock);
sbi->queues = NULL;
s->s_blocksize = 1024;
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index 394ff36ef8f1..be78e9378c03 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -178,7 +178,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
return -ENOENT;
}
- if (down_interruptible(&sbi->wq_sem)) {
+ if (mutex_lock_interruptible(&sbi->wq_mutex)) {
kfree(name);
return -EINTR;
}
@@ -194,7 +194,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
/* Can't wait for an expire if there's no mount */
if (notify == NFY_NONE && !d_mountpoint(dentry)) {
kfree(name);
- up(&sbi->wq_sem);
+ mutex_unlock(&sbi->wq_mutex);
return -ENOENT;
}
@@ -202,7 +202,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL);
if ( !wq ) {
kfree(name);
- up(&sbi->wq_sem);
+ mutex_unlock(&sbi->wq_mutex);
return -ENOMEM;
}
@@ -218,10 +218,10 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
wq->status = -EINTR; /* Status return if interrupted */
atomic_set(&wq->wait_ctr, 2);
atomic_set(&wq->notified, 1);
- up(&sbi->wq_sem);
+ mutex_unlock(&sbi->wq_mutex);
} else {
atomic_inc(&wq->wait_ctr);
- up(&sbi->wq_sem);
+ mutex_unlock(&sbi->wq_mutex);
kfree(name);
DPRINTK("existing wait id = 0x%08lx, name = %.*s, nfy=%d",
(unsigned long) wq->wait_queue_token, wq->len, wq->name, notify);
@@ -282,19 +282,19 @@ int autofs4_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_tok
{
struct autofs_wait_queue *wq, **wql;
- down(&sbi->wq_sem);
+ mutex_lock(&sbi->wq_mutex);
for ( wql = &sbi->queues ; (wq = *wql) != 0 ; wql = &wq->next ) {
if ( wq->wait_queue_token == wait_queue_token )
break;
}
if ( !wq ) {
- up(&sbi->wq_sem);
+ mutex_unlock(&sbi->wq_mutex);
return -EINVAL;
}
*wql = wq->next; /* Unlink from chain */
- up(&sbi->wq_sem);
+ mutex_unlock(&sbi->wq_mutex);
kfree(wq->name);
wq->name = NULL; /* Do not wait on this queue */
diff --git a/fs/bio.c b/fs/bio.c
index 1f3bb501c262..8f1d2e815c96 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -1243,11 +1243,11 @@ static int __init init_bio(void)
scale = 4;
/*
- * scale number of entries
+ * Limit number of entries reserved -- mempools are only used when
+ * the system is completely unable to allocate memory, so we only
+ * need enough to make progress.
*/
- bvec_pool_entries = megabytes * 2;
- if (bvec_pool_entries > 256)
- bvec_pool_entries = 256;
+ bvec_pool_entries = 1 + scale;
fs_bio_set = bioset_create(BIO_POOL_SIZE, bvec_pool_entries, scale);
if (!fs_bio_set)
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 6e50346fb1ee..44d05e6e34db 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -265,8 +265,8 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
SLAB_CTOR_CONSTRUCTOR)
{
memset(bdev, 0, sizeof(*bdev));
- sema_init(&bdev->bd_sem, 1);
- sema_init(&bdev->bd_mount_sem, 1);
+ mutex_init(&bdev->bd_mutex);
+ mutex_init(&bdev->bd_mount_mutex);
INIT_LIST_HEAD(&bdev->bd_inodes);
INIT_LIST_HEAD(&bdev->bd_list);
inode_init_once(&ei->vfs_inode);
@@ -574,7 +574,7 @@ static int do_open(struct block_device *bdev, struct file *file)
}
owner = disk->fops->owner;
- down(&bdev->bd_sem);
+ mutex_lock(&bdev->bd_mutex);
if (!bdev->bd_openers) {
bdev->bd_disk = disk;
bdev->bd_contains = bdev;
@@ -605,21 +605,21 @@ static int do_open(struct block_device *bdev, struct file *file)
if (ret)
goto out_first;
bdev->bd_contains = whole;
- down(&whole->bd_sem);
+ mutex_lock(&whole->bd_mutex);
whole->bd_part_count++;
p = disk->part[part - 1];
bdev->bd_inode->i_data.backing_dev_info =
whole->bd_inode->i_data.backing_dev_info;
if (!(disk->flags & GENHD_FL_UP) || !p || !p->nr_sects) {
whole->bd_part_count--;
- up(&whole->bd_sem);
+ mutex_unlock(&whole->bd_mutex);
ret = -ENXIO;
goto out_first;
}
kobject_get(&p->kobj);
bdev->bd_part = p;
bd_set_size(bdev, (loff_t) p->nr_sects << 9);
- up(&whole->bd_sem);
+ mutex_unlock(&whole->bd_mutex);
}
} else {
put_disk(disk);
@@ -633,13 +633,13 @@ static int do_open(struct block_device *bdev, struct file *file)
if (bdev->bd_invalidated)
rescan_partitions(bdev->bd_disk, bdev);
} else {
- down(&bdev->bd_contains->bd_sem);
+ mutex_lock(&bdev->bd_contains->bd_mutex);
bdev->bd_contains->bd_part_count++;
- up(&bdev->bd_contains->bd_sem);
+ mutex_unlock(&bdev->bd_contains->bd_mutex);
}
}
bdev->bd_openers++;
- up(&bdev->bd_sem);
+ mutex_unlock(&bdev->bd_mutex);
unlock_kernel();
return 0;
@@ -652,7 +652,7 @@ out_first:
put_disk(disk);
module_put(owner);
out:
- up(&bdev->bd_sem);
+ mutex_unlock(&bdev->bd_mutex);
unlock_kernel();
if (ret)
bdput(bdev);
@@ -714,7 +714,7 @@ int blkdev_put(struct block_device *bdev)
struct inode *bd_inode = bdev->bd_inode;
struct gendisk *disk = bdev->bd_disk;
- down(&bdev->bd_sem);
+ mutex_lock(&bdev->bd_mutex);
lock_kernel();
if (!--bdev->bd_openers) {
sync_blockdev(bdev);
@@ -724,9 +724,9 @@ int blkdev_put(struct block_device *bdev)
if (disk->fops->release)
ret = disk->fops->release(bd_inode, NULL);
} else {
- down(&bdev->bd_contains->bd_sem);
+ mutex_lock(&bdev->bd_contains->bd_mutex);
bdev->bd_contains->bd_part_count--;
- up(&bdev->bd_contains->bd_sem);
+ mutex_unlock(&bdev->bd_contains->bd_mutex);
}
if (!bdev->bd_openers) {
struct module *owner = disk->fops->owner;
@@ -746,7 +746,7 @@ int blkdev_put(struct block_device *bdev)
bdev->bd_contains = NULL;
}
unlock_kernel();
- up(&bdev->bd_sem);
+ mutex_unlock(&bdev->bd_mutex);
bdput(bdev);
return ret;
}
diff --git a/fs/buffer.c b/fs/buffer.c
index 1d3683d496f8..0d6ca7bac6c8 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -201,7 +201,7 @@ int fsync_bdev(struct block_device *bdev)
* freeze_bdev -- lock a filesystem and force it into a consistent state
* @bdev: blockdevice to lock
*
- * This takes the block device bd_mount_sem to make sure no new mounts
+ * This takes the block device bd_mount_mutex to make sure no new mounts
* happen on bdev until thaw_bdev() is called.
* If a superblock is found on this device, we take the s_umount semaphore
* on it to make sure nobody unmounts until the snapshot creation is done.
@@ -210,7 +210,7 @@ struct super_block *freeze_bdev(struct block_device *bdev)
{
struct super_block *sb;
- down(&bdev->bd_mount_sem);
+ mutex_lock(&bdev->bd_mount_mutex);
sb = get_super(bdev);
if (sb && !(sb->s_flags & MS_RDONLY)) {
sb->s_frozen = SB_FREEZE_WRITE;
@@ -264,7 +264,7 @@ void thaw_bdev(struct block_device *bdev, struct super_block *sb)
drop_super(sb);
}
- up(&bdev->bd_mount_sem);
+ mutex_unlock(&bdev->bd_mount_mutex);
}
EXPORT_SYMBOL(thaw_bdev);
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index fed55e3c53df..632561dd9c50 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -138,9 +138,9 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
cifs_sb = CIFS_SB(inode->i_sb);
pTcon = cifs_sb->tcon;
- down(&direntry->d_sb->s_vfs_rename_sem);
+ mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);
full_path = build_path_from_dentry(direntry);
- up(&direntry->d_sb->s_vfs_rename_sem);
+ mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);
if(full_path == NULL) {
FreeXid(xid);
return -ENOMEM;
@@ -317,9 +317,9 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
cifs_sb = CIFS_SB(inode->i_sb);
pTcon = cifs_sb->tcon;
- down(&direntry->d_sb->s_vfs_rename_sem);
+ mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);
full_path = build_path_from_dentry(direntry);
- up(&direntry->d_sb->s_vfs_rename_sem);
+ mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);
if(full_path == NULL)
rc = -ENOMEM;
else if (pTcon->ses->capabilities & CAP_UNIX) {
diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c
index a7a47bb36bf3..ec4dfe9bf5ef 100644
--- a/fs/cifs/fcntl.c
+++ b/fs/cifs/fcntl.c
@@ -86,9 +86,9 @@ int cifs_dir_notify(struct file * file, unsigned long arg)
cifs_sb = CIFS_SB(file->f_dentry->d_sb);
pTcon = cifs_sb->tcon;
- down(&file->f_dentry->d_sb->s_vfs_rename_sem);
+ mutex_lock(&file->f_dentry->d_sb->s_vfs_rename_mutex);
full_path = build_path_from_dentry(file->f_dentry);
- up(&file->f_dentry->d_sb->s_vfs_rename_sem);
+ mutex_unlock(&file->f_dentry->d_sb->s_vfs_rename_mutex);
if(full_path == NULL) {
rc = -ENOMEM;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 675bd2568297..165d67426381 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -203,9 +203,9 @@ int cifs_open(struct inode *inode, struct file *file)
}
}
- down(&inode->i_sb->s_vfs_rename_sem);
+ mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
full_path = build_path_from_dentry(file->f_dentry);
- up(&inode->i_sb->s_vfs_rename_sem);
+ mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
if (full_path == NULL) {
FreeXid(xid);
return -ENOMEM;
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 59359911f481..ff93a9f81d1c 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -574,9 +574,9 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
/* Unlink can be called from rename so we can not grab the sem here
since we deadlock otherwise */
-/* down(&direntry->d_sb->s_vfs_rename_sem);*/
+/* mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);*/
full_path = build_path_from_dentry(direntry);
-/* up(&direntry->d_sb->s_vfs_rename_sem);*/
+/* mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);*/
if (full_path == NULL) {
FreeXid(xid);
return -ENOMEM;
@@ -718,9 +718,9 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
cifs_sb = CIFS_SB(inode->i_sb);
pTcon = cifs_sb->tcon;
- down(&inode->i_sb->s_vfs_rename_sem);
+ mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
full_path = build_path_from_dentry(direntry);
- up(&inode->i_sb->s_vfs_rename_sem);
+ mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
if (full_path == NULL) {
FreeXid(xid);
return -ENOMEM;
@@ -803,9 +803,9 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
cifs_sb = CIFS_SB(inode->i_sb);
pTcon = cifs_sb->tcon;
- down(&inode->i_sb->s_vfs_rename_sem);
+ mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
full_path = build_path_from_dentry(direntry);
- up(&inode->i_sb->s_vfs_rename_sem);
+ mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
if (full_path == NULL) {
FreeXid(xid);
return -ENOMEM;
@@ -1137,9 +1137,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
rc = 0;
}
- down(&direntry->d_sb->s_vfs_rename_sem);
+ mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);
full_path = build_path_from_dentry(direntry);
- up(&direntry->d_sb->s_vfs_rename_sem);
+ mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);
if (full_path == NULL) {
FreeXid(xid);
return -ENOMEM;
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 0f99aae33162..8d0da7c87c7b 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -48,10 +48,10 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
/* No need to check for cross device links since server will do that
BB note DFS case in future though (when we may have to check) */
- down(&inode->i_sb->s_vfs_rename_sem);
+ mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
fromName = build_path_from_dentry(old_file);
toName = build_path_from_dentry(direntry);
- up(&inode->i_sb->s_vfs_rename_sem);
+ mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
if((fromName == NULL) || (toName == NULL)) {
rc = -ENOMEM;
goto cifs_hl_exit;
@@ -103,9 +103,9 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
xid = GetXid();
- down(&direntry->d_sb->s_vfs_rename_sem);
+ mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);
full_path = build_path_from_dentry(direntry);
- up(&direntry->d_sb->s_vfs_rename_sem);
+ mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);
if (!full_path)
goto out_no_free;
@@ -164,9 +164,9 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
cifs_sb = CIFS_SB(inode->i_sb);
pTcon = cifs_sb->tcon;
- down(&inode->i_sb->s_vfs_rename_sem);
+ mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
full_path = build_path_from_dentry(direntry);
- up(&inode->i_sb->s_vfs_rename_sem);
+ mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
if(full_path == NULL) {
FreeXid(xid);
@@ -232,9 +232,9 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
/* BB would it be safe against deadlock to grab this sem
even though rename itself grabs the sem and calls lookup? */
-/* down(&inode->i_sb->s_vfs_rename_sem);*/
+/* mutex_lock(&inode->i_sb->s_vfs_rename_mutex);*/
full_path = build_path_from_dentry(direntry);
-/* up(&inode->i_sb->s_vfs_rename_sem);*/
+/* mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);*/
if(full_path == NULL) {
FreeXid(xid);
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 288cc048d37f..edb3b6eb34bc 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -404,9 +404,9 @@ static int initiate_cifs_search(const int xid, struct file *file)
if(pTcon == NULL)
return -EINVAL;
- down(&file->f_dentry->d_sb->s_vfs_rename_sem);
+ mutex_lock(&file->f_dentry->d_sb->s_vfs_rename_mutex);
full_path = build_path_from_dentry(file->f_dentry);
- up(&file->f_dentry->d_sb->s_vfs_rename_sem);
+ mutex_unlock(&file->f_dentry->d_sb->s_vfs_rename_mutex);
if(full_path == NULL) {
return -ENOMEM;
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index 777e3363c2a4..3938444d87b2 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -62,9 +62,9 @@ int cifs_removexattr(struct dentry * direntry, const char * ea_name)
cifs_sb = CIFS_SB(sb);
pTcon = cifs_sb->tcon;
- down(&sb->s_vfs_rename_sem);
+ mutex_lock(&sb->s_vfs_rename_mutex);
full_path = build_path_from_dentry(direntry);
- up(&sb->s_vfs_rename_sem);
+ mutex_unlock(&sb->s_vfs_rename_mutex);
if(full_path == NULL) {
FreeXid(xid);
return -ENOMEM;
@@ -116,9 +116,9 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name,
cifs_sb = CIFS_SB(sb);
pTcon = cifs_sb->tcon;
- down(&sb->s_vfs_rename_sem);
+ mutex_lock(&sb->s_vfs_rename_mutex);
full_path = build_path_from_dentry(direntry);
- up(&sb->s_vfs_rename_sem);
+ mutex_unlock(&sb->s_vfs_rename_mutex);
if(full_path == NULL) {
FreeXid(xid);
return -ENOMEM;
@@ -223,9 +223,9 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
cifs_sb = CIFS_SB(sb);
pTcon = cifs_sb->tcon;
- down(&sb->s_vfs_rename_sem);
+ mutex_lock(&sb->s_vfs_rename_mutex);
full_path = build_path_from_dentry(direntry);
- up(&sb->s_vfs_rename_sem);
+ mutex_unlock(&sb->s_vfs_rename_mutex);
if(full_path == NULL) {
FreeXid(xid);
return -ENOMEM;
@@ -341,9 +341,9 @@ ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size)
cifs_sb = CIFS_SB(sb);
pTcon = cifs_sb->tcon;
- down(&sb->s_vfs_rename_sem);
+ mutex_lock(&sb->s_vfs_rename_mutex);
full_path = build_path_from_dentry(direntry);
- up(&sb->s_vfs_rename_sem);
+ mutex_unlock(&sb->s_vfs_rename_mutex);
if(full_path == NULL) {
FreeXid(xid);
return -ENOMEM;
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index bfb8a230bac9..14c5620b5cab 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -18,6 +18,7 @@
#include <linux/mount.h>
#include <linux/tty.h>
#include <linux/devpts_fs.h>
+#include <linux/parser.h>
#define DEVPTS_SUPER_MAGIC 0x1cd1
@@ -32,39 +33,60 @@ static struct {
umode_t mode;
} config = {.mode = 0600};
+enum {
+ Opt_uid, Opt_gid, Opt_mode,
+ Opt_err
+};
+
+static match_table_t tokens = {
+ {Opt_uid, "uid=%u"},
+ {Opt_gid, "gid=%u"},
+ {Opt_mode, "mode=%o"},
+ {Opt_err, NULL}
+};
+
static int devpts_remount(struct super_block *sb, int *flags, char *data)
{
- int setuid = 0;
- int setgid = 0;
- uid_t uid = 0;
- gid_t gid = 0;
- umode_t mode = 0600;
- char *this_char;
-
- this_char = NULL;
- while ((this_char = strsep(&data, ",")) != NULL) {
- int n;
- char dummy;
- if (!*this_char)
+ char *p;
+
+ config.setuid = 0;
+ config.setgid = 0;
+ config.uid = 0;
+ config.gid = 0;
+ config.mode = 0600;
+
+ while ((p = strsep(&data, ",")) != NULL) {
+ substring_t args[MAX_OPT_ARGS];
+ int token;
+ int option;
+
+ if (!*p)
continue;
- if (sscanf(this_char, "uid=%i%c", &n, &dummy) == 1) {
- setuid = 1;
- uid = n;
- } else if (sscanf(this_char, "gid=%i%c", &n, &dummy) == 1) {
- setgid = 1;
- gid = n;
- } else if (sscanf(this_char, "mode=%o%c", &n, &dummy) == 1)
- mode = n & ~S_IFMT;
- else {
- printk("devpts: called with bogus options\n");
+
+ token = match_token(p, tokens, args);
+ switch (token) {
+ case Opt_uid:
+ if (match_int(&args[0], &option))
+ return -EINVAL;
+ config.uid = option;
+ config.setuid = 1;
+ break;
+ case Opt_gid:
+ if (match_int(&args[0], &option))
+ return -EINVAL;
+ config.gid = option;
+ config.setgid = 1;
+ break;
+ case Opt_mode:
+ if (match_octal(&args[0], &option))
+ return -EINVAL;
+ config.mode = option & ~S_IFMT;
+ break;
+ default:
+ printk(KERN_ERR "devpts: called with bogus options\n");
return -EINVAL;
}
}
- config.setuid = setuid;
- config.setgid = setgid;
- config.uid = uid;
- config.gid = gid;
- config.mode = mode;
return 0;
}
diff --git a/fs/dquot.c b/fs/dquot.c
index 1966c890b48d..acf07e581f8c 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -103,12 +103,12 @@
* (these locking rules also apply for S_NOQUOTA flag in the inode - note that
* for altering the flag i_mutex is also needed). If operation is holding
* reference to dquot in other way (e.g. quotactl ops) it must be guarded by
- * dqonoff_sem.
+ * dqonoff_mutex.
* This locking assures that:
* a) update/access to dquot pointers in inode is serialized
* b) everyone is guarded against invalidate_dquots()
*
- * Each dquot has its dq_lock semaphore. Locked dquots might not be referenced
+ * Each dquot has its dq_lock mutex. Locked dquots might not be referenced
* from inodes (dquot_alloc_space() and such don't check the dq_lock).
* Currently dquot is locked only when it is being read to memory (or space for
* it is being allocated) on the first dqget() and when it is being released on
@@ -118,9 +118,9 @@
* spinlock to internal buffers before writing.
*
* Lock ordering (including related VFS locks) is the following:
- * i_mutex > dqonoff_sem > iprune_sem > journal_lock > dqptr_sem >
- * > dquot->dq_lock > dqio_sem
- * i_mutex on quota files is special (it's below dqio_sem)
+ * i_mutex > dqonoff_sem > journal_lock > dqptr_sem > dquot->dq_lock >
+ * dqio_mutex
+ * i_mutex on quota files is special (it's below dqio_mutex)
*/
static DEFINE_SPINLOCK(dq_list_lock);
@@ -281,8 +281,8 @@ static inline void remove_inuse(struct dquot *dquot)
static void wait_on_dquot(struct dquot *dquot)
{
- down(&dquot->dq_lock);
- up(&dquot->dq_lock);
+ mutex_lock(&dquot->dq_lock);
+ mutex_unlock(&dquot->dq_lock);
}
#define mark_dquot_dirty(dquot) ((dquot)->dq_sb->dq_op->mark_dirty(dquot))
@@ -321,8 +321,8 @@ int dquot_acquire(struct dquot *dquot)
int ret = 0, ret2 = 0;
struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
- down(&dquot->dq_lock);
- down(&dqopt->dqio_sem);
+ mutex_lock(&dquot->dq_lock);
+ mutex_lock(&dqopt->dqio_mutex);
if (!test_bit(DQ_READ_B, &dquot->dq_flags))
ret = dqopt->ops[dquot->dq_type]->read_dqblk(dquot);
if (ret < 0)
@@ -343,8 +343,8 @@ int dquot_acquire(struct dquot *dquot)
}
set_bit(DQ_ACTIVE_B, &dquot->dq_flags);
out_iolock:
- up(&dqopt->dqio_sem);
- up(&dquot->dq_lock);
+ mutex_unlock(&dqopt->dqio_mutex);
+ mutex_unlock(&dquot->dq_lock);
return ret;
}
@@ -356,7 +356,7 @@ int dquot_commit(struct dquot *dquot)
int ret = 0, ret2 = 0;
struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
- down(&dqopt->dqio_sem);
+ mutex_lock(&dqopt->dqio_mutex);
spin_lock(&dq_list_lock);
if (!clear_dquot_dirty(dquot)) {
spin_unlock(&dq_list_lock);
@@ -373,7 +373,7 @@ int dquot_commit(struct dquot *dquot)
ret = ret2;
}
out_sem:
- up(&dqopt->dqio_sem);
+ mutex_unlock(&dqopt->dqio_mutex);
return ret;
}
@@ -385,11 +385,11 @@ int dquot_release(struct dquot *dquot)
int ret = 0, ret2 = 0;
struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
- down(&dquot->dq_lock);
+ mutex_lock(&dquot->dq_lock);
/* Check whether we are not racing with some other dqget() */
if (atomic_read(&dquot->dq_count) > 1)
goto out_dqlock;
- down(&dqopt->dqio_sem);
+ mutex_lock(&dqopt->dqio_mutex);
if (dqopt->ops[dquot->dq_type]->release_dqblk) {
ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot);
/* Write the info */
@@ -399,31 +399,57 @@ int dquot_release(struct dquot *dquot)
ret = ret2;
}
clear_bit(DQ_ACTIVE_B, &dquot->dq_flags);
- up(&dqopt->dqio_sem);
+ mutex_unlock(&dqopt->dqio_mutex);
out_dqlock:
- up(&dquot->dq_lock);
+ mutex_unlock(&dquot->dq_lock);
return ret;
}
/* Invalidate all dquots on the list. Note that this function is called after
* quota is disabled and pointers from inodes removed so there cannot be new
- * quota users. Also because we hold dqonoff_sem there can be no quota users
- * for this sb+type at all. */
+ * quota users. There can still be some users of quotas due to inodes being
+ * just deleted or pruned by prune_icache() (those are not attached to any
+ * list). We have to wait for such users.
+ */
static void invalidate_dquots(struct super_block *sb, int type)
{
struct dquot *dquot, *tmp;
+restart:
spin_lock(&dq_list_lock);
list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) {
if (dquot->dq_sb != sb)
continue;
if (dquot->dq_type != type)
continue;
-#ifdef __DQUOT_PARANOIA
- if (atomic_read(&dquot->dq_count))
- BUG();
-#endif
- /* Quota now has no users and it has been written on last dqput() */
+ /* Wait for dquot users */
+ if (atomic_read(&dquot->dq_count)) {
+ DEFINE_WAIT(wait);
+
+ atomic_inc(&dquot->dq_count);
+ prepare_to_wait(&dquot->dq_wait_unused, &wait,
+ TASK_UNINTERRUPTIBLE);
+ spin_unlock(&dq_list_lock);
+ /* Once dqput() wakes us up, we know it's time to free
+ * the dquot.
+ * IMPORTANT: we rely on the fact that there is always
+ * at most one process waiting for dquot to free.
+ * Otherwise dq_count would be > 1 and we would never
+ * wake up.
+ */
+ if (atomic_read(&dquot->dq_count) > 1)
+ schedule();
+ finish_wait(&dquot->dq_wait_unused, &wait);
+ dqput(dquot);
+ /* At this moment dquot() need not exist (it could be
+ * reclaimed by prune_dqcache(). Hence we must
+ * restart. */
+ goto restart;
+ }
+ /*
+ * Quota now has no users and it has been written on last
+ * dqput()
+ */
remove_dquot_hash(dquot);
remove_free_dquot(dquot);
remove_inuse(dquot);
@@ -439,7 +465,7 @@ int vfs_quota_sync(struct super_block *sb, int type)
struct quota_info *dqopt = sb_dqopt(sb);
int cnt;
- down(&dqopt->dqonoff_sem);
+ mutex_lock(&dqopt->dqonoff_mutex);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (type != -1 && cnt != type)
continue;
@@ -474,7 +500,7 @@ int vfs_quota_sync(struct super_block *sb, int type)
spin_lock(&dq_list_lock);
dqstats.syncs++;
spin_unlock(&dq_list_lock);
- up(&dqopt->dqonoff_sem);
+ mutex_unlock(&dqopt->dqonoff_mutex);
return 0;
}
@@ -515,7 +541,7 @@ static int shrink_dqcache_memory(int nr, gfp_t gfp_mask)
/*
* Put reference to dquot
* NOTE: If you change this function please check whether dqput_blocks() works right...
- * MUST be called with either dqptr_sem or dqonoff_sem held
+ * MUST be called with either dqptr_sem or dqonoff_mutex held
*/
static void dqput(struct dquot *dquot)
{
@@ -540,6 +566,10 @@ we_slept:
if (atomic_read(&dquot->dq_count) > 1) {
/* We have more than one user... nothing to do */
atomic_dec(&dquot->dq_count);
+ /* Releasing dquot during quotaoff phase? */
+ if (!sb_has_quota_enabled(dquot->dq_sb, dquot->dq_type) &&
+ atomic_read(&dquot->dq_count) == 1)
+ wake_up(&dquot->dq_wait_unused);
spin_unlock(&dq_list_lock);
return;
}
@@ -576,11 +606,12 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type)
return NODQUOT;
memset((caddr_t)dquot, 0, sizeof(struct dquot));
- sema_init(&dquot->dq_lock, 1);
+ mutex_init(&dquot->dq_lock);
INIT_LIST_HEAD(&dquot->dq_free);
INIT_LIST_HEAD(&dquot->dq_inuse);
INIT_HLIST_NODE(&dquot->dq_hash);
INIT_LIST_HEAD(&dquot->dq_dirty);
+ init_waitqueue_head(&dquot->dq_wait_unused);
dquot->dq_sb = sb;
dquot->dq_type = type;
atomic_set(&dquot->dq_count, 1);
@@ -590,7 +621,7 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type)
/*
* Get reference to dquot
- * MUST be called with either dqptr_sem or dqonoff_sem held
+ * MUST be called with either dqptr_sem or dqonoff_mutex held
*/
static struct dquot *dqget(struct super_block *sb, unsigned int id, int type)
{
@@ -656,7 +687,7 @@ static int dqinit_needed(struct inode *inode, int type)
return 0;
}
-/* This routine is guarded by dqonoff_sem semaphore */
+/* This routine is guarded by dqonoff_mutex mutex */
static void add_dquot_ref(struct super_block *sb, int type)
{
struct list_head *p;
@@ -732,13 +763,9 @@ static void drop_dquot_ref(struct super_block *sb, int type)
{
LIST_HEAD(tofree_head);
- /* We need to be guarded against prune_icache to reach all the
- * inodes - otherwise some can be on the local list of prune_icache */
- down(&iprune_sem);
down_write(&sb_dqopt(sb)->dqptr_sem);
remove_dquot_ref(sb, type, &tofree_head);
up_write(&sb_dqopt(sb)->dqptr_sem);
- up(&iprune_sem);
put_dquot_list(&tofree_head);
}
@@ -938,8 +965,8 @@ int dquot_initialize(struct inode *inode, int type)
unsigned int id = 0;
int cnt, ret = 0;
- /* First test before acquiring semaphore - solves deadlocks when we
- * re-enter the quota code and are already holding the semaphore */
+ /* First test before acquiring mutex - solves deadlocks when we
+ * re-enter the quota code and are already holding the mutex */
if (IS_NOQUOTA(inode))
return 0;
down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
@@ -1002,8 +1029,8 @@ int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
int cnt, ret = NO_QUOTA;
char warntype[MAXQUOTAS];
- /* First test before acquiring semaphore - solves deadlocks when we
- * re-enter the quota code and are already holding the semaphore */
+ /* First test before acquiring mutex - solves deadlocks when we
+ * re-enter the quota code and are already holding the mutex */
if (IS_NOQUOTA(inode)) {
out_add:
inode_add_bytes(inode, number);
@@ -1051,8 +1078,8 @@ int dquot_alloc_inode(const struct inode *inode, unsigned long number)
int cnt, ret = NO_QUOTA;
char warntype[MAXQUOTAS];
- /* First test before acquiring semaphore - solves deadlocks when we
- * re-enter the quota code and are already holding the semaphore */
+ /* First test before acquiring mutex - solves deadlocks when we
+ * re-enter the quota code and are already holding the mutex */
if (IS_NOQUOTA(inode))
return QUOTA_OK;
for (cnt = 0; cnt < MAXQUOTAS; cnt++)
@@ -1095,8 +1122,8 @@ int dquot_free_space(struct inode *inode, qsize_t number)
{
unsigned int cnt;
- /* First test before acquiring semaphore - solves deadlocks when we
- * re-enter the quota code and are already holding the semaphore */
+ /* First test before acquiring mutex - solves deadlocks when we
+ * re-enter the quota code and are already holding the mutex */
if (IS_NOQUOTA(inode)) {
out_sub:
inode_sub_bytes(inode, number);
@@ -1131,8 +1158,8 @@ int dquot_free_inode(const struct inode *inode, unsigned long number)
{
unsigned int cnt;
- /* First test before acquiring semaphore - solves deadlocks when we
- * re-enter the quota code and are already holding the semaphore */
+ /* First test before acquiring mutex - solves deadlocks when we
+ * re-enter the quota code and are already holding the mutex */
if (IS_NOQUOTA(inode))
return QUOTA_OK;
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
@@ -1171,8 +1198,8 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
chgid = (iattr->ia_valid & ATTR_GID) && inode->i_gid != iattr->ia_gid;
char warntype[MAXQUOTAS];
- /* First test before acquiring semaphore - solves deadlocks when we
- * re-enter the quota code and are already holding the semaphore */
+ /* First test before acquiring mutex - solves deadlocks when we
+ * re-enter the quota code and are already holding the mutex */
if (IS_NOQUOTA(inode))
return QUOTA_OK;
/* Clear the arrays */
@@ -1266,9 +1293,9 @@ int dquot_commit_info(struct super_block *sb, int type)
int ret;
struct quota_info *dqopt = sb_dqopt(sb);
- down(&dqopt->dqio_sem);
+ mutex_lock(&dqopt->dqio_mutex);
ret = dqopt->ops[type]->write_file_info(sb, type);
- up(&dqopt->dqio_sem);
+ mutex_unlock(&dqopt->dqio_mutex);
return ret;
}
@@ -1324,7 +1351,7 @@ int vfs_quota_off(struct super_block *sb, int type)
struct inode *toputinode[MAXQUOTAS];
/* We need to serialize quota_off() for device */
- down(&dqopt->dqonoff_sem);
+ mutex_lock(&dqopt->dqonoff_mutex);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
toputinode[cnt] = NULL;
if (type != -1 && cnt != type)
@@ -1353,7 +1380,7 @@ int vfs_quota_off(struct super_block *sb, int type)
dqopt->info[cnt].dqi_bgrace = 0;
dqopt->ops[cnt] = NULL;
}
- up(&dqopt->dqonoff_sem);
+ mutex_unlock(&dqopt->dqonoff_mutex);
/* Sync the superblock so that buffers with quota data are written to
* disk (and so userspace sees correct data afterwards). */
if (sb->s_op->sync_fs)
@@ -1366,7 +1393,7 @@ int vfs_quota_off(struct super_block *sb, int type)
* changes done by userspace on the next quotaon() */
for (cnt = 0; cnt < MAXQUOTAS; cnt++)
if (toputinode[cnt]) {
- down(&dqopt->dqonoff_sem);
+ mutex_lock(&dqopt->dqonoff_mutex);
/* If quota was reenabled in the meantime, we have
* nothing to do */
if (!sb_has_quota_enabled(sb, cnt)) {
@@ -1378,7 +1405,7 @@ int vfs_quota_off(struct super_block *sb, int type)
mark_inode_dirty(toputinode[cnt]);
iput(toputinode[cnt]);
}
- up(&dqopt->dqonoff_sem);
+ mutex_unlock(&dqopt->dqonoff_mutex);
}
if (sb->s_bdev)
invalidate_bdev(sb->s_bdev, 0);
@@ -1419,7 +1446,7 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id)
/* And now flush the block cache so that kernel sees the changes */
invalidate_bdev(sb->s_bdev, 0);
mutex_lock(&inode->i_mutex);
- down(&dqopt->dqonoff_sem);
+ mutex_lock(&dqopt->dqonoff_mutex);
if (sb_has_quota_enabled(sb, type)) {
error = -EBUSY;
goto out_lock;
@@ -1444,17 +1471,17 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id)
dqopt->ops[type] = fmt->qf_ops;
dqopt->info[type].dqi_format = fmt;
INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list);
- down(&dqopt->dqio_sem);
+ mutex_lock(&dqopt->dqio_mutex);
if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0) {
- up(&dqopt->dqio_sem);
+ mutex_unlock(&dqopt->dqio_mutex);
goto out_file_init;
}
- up(&dqopt->dqio_sem);
+ mutex_unlock(&dqopt->dqio_mutex);
mutex_unlock(&inode->i_mutex);
set_enable_flags(dqopt, type);
add_dquot_ref(sb, type);
- up(&dqopt->dqonoff_sem);
+ mutex_unlock(&dqopt->dqonoff_mutex);
return 0;
@@ -1462,7 +1489,7 @@ out_file_init:
dqopt->files[type] = NULL;
iput(inode);
out_lock:
- up(&dqopt->dqonoff_sem);
+ mutex_unlock(&dqopt->dqonoff_mutex);
if (oldflags != -1) {
down_write(&dqopt->dqptr_sem);
/* Set the flags back (in the case of accidental quotaon()
@@ -1550,14 +1577,14 @@ int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d
{
struct dquot *dquot;
- down(&sb_dqopt(sb)->dqonoff_sem);
+ mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
if (!(dquot = dqget(sb, id, type))) {
- up(&sb_dqopt(sb)->dqonoff_sem);
+ mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
return -ESRCH;
}
do_get_dqblk(dquot, di);
dqput(dquot);
- up(&sb_dqopt(sb)->dqonoff_sem);
+ mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
return 0;
}
@@ -1619,14 +1646,14 @@ int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d
{
struct dquot *dquot;
- down(&sb_dqopt(sb)->dqonoff_sem);
+ mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
if (!(dquot = dqget(sb, id, type))) {
- up(&sb_dqopt(sb)->dqonoff_sem);
+ mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
return -ESRCH;
}
do_set_dqblk(dquot, di);
dqput(dquot);
- up(&sb_dqopt(sb)->dqonoff_sem);
+ mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
return 0;
}
@@ -1635,9 +1662,9 @@ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
{
struct mem_dqinfo *mi;
- down(&sb_dqopt(sb)->dqonoff_sem);
+ mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
if (!sb_has_quota_enabled(sb, type)) {
- up(&sb_dqopt(sb)->dqonoff_sem);
+ mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
return -ESRCH;
}
mi = sb_dqopt(sb)->info + type;
@@ -1647,7 +1674,7 @@ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
ii->dqi_flags = mi->dqi_flags & DQF_MASK;
ii->dqi_valid = IIF_ALL;
spin_unlock(&dq_data_lock);
- up(&sb_dqopt(sb)->dqonoff_sem);
+ mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
return 0;
}
@@ -1656,9 +1683,9 @@ int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
{
struct mem_dqinfo *mi;
- down(&sb_dqopt(sb)->dqonoff_sem);
+ mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
if (!sb_has_quota_enabled(sb, type)) {
- up(&sb_dqopt(sb)->dqonoff_sem);
+ mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
return -ESRCH;
}
mi = sb_dqopt(sb)->info + type;
@@ -1673,7 +1700,7 @@ int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
mark_info_dirty(sb, type);
/* Force write to disk */
sb->dq_op->write_info(sb, type);
- up(&sb_dqopt(sb)->dqonoff_sem);
+ mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
return 0;
}
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 4284cd31eba6..1c2b16fda13a 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -34,6 +34,7 @@
#include <linux/eventpoll.h>
#include <linux/mount.h>
#include <linux/bitops.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -46,7 +47,7 @@
* LOCKING:
* There are three level of locking required by epoll :
*
- * 1) epsem (semaphore)
+ * 1) epmutex (mutex)
* 2) ep->sem (rw_semaphore)
* 3) ep->lock (rw_lock)
*
@@ -67,9 +68,9 @@
* if a file has been pushed inside an epoll set and it is then
* close()d without a previous call toepoll_ctl(EPOLL_CTL_DEL).
* It is possible to drop the "ep->sem" and to use the global
- * semaphore "epsem" (together with "ep->lock") to have it working,
+ * semaphore "epmutex" (together with "ep->lock") to have it working,
* but having "ep->sem" will make the interface more scalable.
- * Events that require holding "epsem" are very rare, while for
+ * Events that require holding "epmutex" are very rare, while for
* normal operations the epoll private "ep->sem" will guarantee
* a greater scalability.
*/
@@ -274,7 +275,7 @@ static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type,
/*
* This semaphore is used to serialize ep_free() and eventpoll_release_file().
*/
-static struct semaphore epsem;
+static struct mutex epmutex;
/* Safe wake up implementation */
static struct poll_safewake psw;
@@ -451,15 +452,6 @@ static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq)
}
-/* Used to initialize the epoll bits inside the "struct file" */
-void eventpoll_init_file(struct file *file)
-{
-
- INIT_LIST_HEAD(&file->f_ep_links);
- spin_lock_init(&file->f_ep_lock);
-}
-
-
/*
* This is called from eventpoll_release() to unlink files from the eventpoll
* interface. We need to have this facility to cleanup correctly files that are
@@ -477,10 +469,10 @@ void eventpoll_release_file(struct file *file)
* cleanup path, and this means that noone is using this file anymore.
* The only hit might come from ep_free() but by holding the semaphore
* will correctly serialize the operation. We do need to acquire
- * "ep->sem" after "epsem" because ep_remove() requires it when called
+ * "ep->sem" after "epmutex" because ep_remove() requires it when called
* from anywhere but ep_free().
*/
- down(&epsem);
+ mutex_lock(&epmutex);
while (!list_empty(lsthead)) {
epi = list_entry(lsthead->next, struct epitem, fllink);
@@ -492,7 +484,7 @@ void eventpoll_release_file(struct file *file)
up_write(&ep->sem);
}
- up(&epsem);
+ mutex_unlock(&epmutex);
}
@@ -819,9 +811,9 @@ static void ep_free(struct eventpoll *ep)
* We do not need to hold "ep->sem" here because the epoll file
* is on the way to be removed and no one has references to it
* anymore. The only hit might come from eventpoll_release_file() but
- * holding "epsem" is sufficent here.
+ * holding "epmutex" is sufficent here.
*/
- down(&epsem);
+ mutex_lock(&epmutex);
/*
* Walks through the whole tree by unregistering poll callbacks.
@@ -843,7 +835,7 @@ static void ep_free(struct eventpoll *ep)
ep_remove(ep, epi);
}
- up(&epsem);
+ mutex_unlock(&epmutex);
}
@@ -1615,7 +1607,7 @@ static int __init eventpoll_init(void)
{
int error;
- init_MUTEX(&epsem);
+ mutex_init(&epmutex);
/* Initialize the structure used to perform safe poll wait head wake ups */
ep_poll_safewake_init(&psw);
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index ad1432a2a62e..4ca824985321 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -36,22 +36,6 @@
#include "acl.h"
#include "xip.h"
-/*
- * Couple of helper functions - make the code slightly cleaner.
- */
-
-static inline void ext2_inc_count(struct inode *inode)
-{
- inode->i_nlink++;
- mark_inode_dirty(inode);
-}
-
-static inline void ext2_dec_count(struct inode *inode)
-{
- inode->i_nlink--;
- mark_inode_dirty(inode);
-}
-
static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode)
{
int err = ext2_add_link(dentry, inode);
@@ -59,7 +43,7 @@ static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode)
d_instantiate(dentry, inode);
return 0;
}
- ext2_dec_count(inode);
+ inode_dec_link_count(inode);
iput(inode);
return err;
}
@@ -201,7 +185,7 @@ out:
return err;
out_fail:
- ext2_dec_count(inode);
+ inode_dec_link_count(inode);
iput (inode);
goto out;
}
@@ -215,7 +199,7 @@ static int ext2_link (struct dentry * old_dentry, struct inode * dir,
return -EMLINK;
inode->i_ctime = CURRENT_TIME_SEC;
- ext2_inc_count(inode);
+ inode_inc_link_count(inode);
atomic_inc(&inode->i_count);
return ext2_add_nondir(dentry, inode);
@@ -229,7 +213,7 @@ static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
if (dir->i_nlink >= EXT2_LINK_MAX)
goto out;
- ext2_inc_count(dir);
+ inode_inc_link_count(dir);
inode = ext2_new_inode (dir, S_IFDIR | mode);
err = PTR_ERR(inode);
@@ -243,7 +227,7 @@ static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
else
inode->i_mapping->a_ops = &ext2_aops;
- ext2_inc_count(inode);
+ inode_inc_link_count(inode);
err = ext2_make_empty(inode, dir);
if (err)
@@ -258,11 +242,11 @@ out:
return err;
out_fail:
- ext2_dec_count(inode);
- ext2_dec_count(inode);
+ inode_dec_link_count(inode);
+ inode_dec_link_count(inode);
iput(inode);
out_dir:
- ext2_dec_count(dir);
+ inode_dec_link_count(dir);
goto out;
}
@@ -282,7 +266,7 @@ static int ext2_unlink(struct inode * dir, struct dentry *dentry)
goto out;
inode->i_ctime = dir->i_ctime;
- ext2_dec_count(inode);
+ inode_dec_link_count(inode);
err = 0;
out:
return err;
@@ -297,8 +281,8 @@ static int ext2_rmdir (struct inode * dir, struct dentry *dentry)
err = ext2_unlink(dir, dentry);
if (!err) {
inode->i_size = 0;
- ext2_dec_count(inode);
- ext2_dec_count(dir);
+ inode_dec_link_count(inode);
+ inode_dec_link_count(dir);
}
}
return err;
@@ -338,41 +322,41 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
new_de = ext2_find_entry (new_dir, new_dentry, &new_page);
if (!new_de)
goto out_dir;
- ext2_inc_count(old_inode);
+ inode_inc_link_count(old_inode);
ext2_set_link(new_dir, new_de, new_page, old_inode);
new_inode->i_ctime = CURRENT_TIME_SEC;
if (dir_de)
new_inode->i_nlink--;
- ext2_dec_count(new_inode);
+ inode_dec_link_count(new_inode);
} else {
if (dir_de) {
err = -EMLINK;
if (new_dir->i_nlink >= EXT2_LINK_MAX)
goto out_dir;
}
- ext2_inc_count(old_inode);
+ inode_inc_link_count(old_inode);
err = ext2_add_link(new_dentry, old_inode);
if (err) {
- ext2_dec_count(old_inode);
+ inode_dec_link_count(old_inode);
goto out_dir;
}
if (dir_de)
- ext2_inc_count(new_dir);
+ inode_inc_link_count(new_dir);
}
/*
* Like most other Unix systems, set the ctime for inodes on a
* rename.
- * ext2_dec_count() will mark the inode dirty.
+ * inode_dec_link_count() will mark the inode dirty.
*/
old_inode->i_ctime = CURRENT_TIME_SEC;
ext2_delete_entry (old_de, old_page);
- ext2_dec_count(old_inode);
+ inode_dec_link_count(old_inode);
if (dir_de) {
ext2_set_link(old_inode, dir_de, dir_page, new_dir);
- ext2_dec_count(old_dir);
+ inode_dec_link_count(old_dir);
}
return 0;
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
index 832867aef3dc..773459164bb2 100644
--- a/fs/ext3/dir.c
+++ b/fs/ext3/dir.c
@@ -95,11 +95,10 @@ static int ext3_readdir(struct file * filp,
void * dirent, filldir_t filldir)
{
int error = 0;
- unsigned long offset, blk;
- int i, num, stored;
- struct buffer_head * bh, * tmp, * bha[16];
- struct ext3_dir_entry_2 * de;
- struct super_block * sb;
+ unsigned long offset;
+ int i, stored;
+ struct ext3_dir_entry_2 *de;
+ struct super_block *sb;
int err;
struct inode *inode = filp->f_dentry->d_inode;
int ret = 0;
@@ -124,12 +123,29 @@ static int ext3_readdir(struct file * filp,
}
#endif
stored = 0;
- bh = NULL;
offset = filp->f_pos & (sb->s_blocksize - 1);
while (!error && !stored && filp->f_pos < inode->i_size) {
- blk = (filp->f_pos) >> EXT3_BLOCK_SIZE_BITS(sb);
- bh = ext3_bread(NULL, inode, blk, 0, &err);
+ unsigned long blk = filp->f_pos >> EXT3_BLOCK_SIZE_BITS(sb);
+ struct buffer_head map_bh;
+ struct buffer_head *bh = NULL;
+
+ map_bh.b_state = 0;
+ err = ext3_get_block_handle(NULL, inode, blk, &map_bh, 0, 0);
+ if (!err) {
+ page_cache_readahead(sb->s_bdev->bd_inode->i_mapping,
+ &filp->f_ra,
+ filp,
+ map_bh.b_blocknr >>
+ (PAGE_CACHE_SHIFT - inode->i_blkbits),
+ 1);
+ bh = ext3_bread(NULL, inode, blk, 0, &err);
+ }
+
+ /*
+ * We ignore I/O errors on directories so users have a chance
+ * of recovering data when there's a bad sector
+ */
if (!bh) {
ext3_error (sb, "ext3_readdir",
"directory #%lu contains a hole at offset %lu",
@@ -138,26 +154,6 @@ static int ext3_readdir(struct file * filp,
continue;
}
- /*
- * Do the readahead
- */
- if (!offset) {
- for (i = 16 >> (EXT3_BLOCK_SIZE_BITS(sb) - 9), num = 0;
- i > 0; i--) {
- tmp = ext3_getblk (NULL, inode, ++blk, 0, &err);
- if (tmp && !buffer_uptodate(tmp) &&
- !buffer_locked(tmp))
- bha[num++] = tmp;
- else
- brelse (tmp);
- }
- if (num) {
- ll_rw_block (READA, num, bha);
- for (i = 0; i < num; i++)
- brelse (bha[i]);
- }
- }
-
revalidate:
/* If the dir block has changed since the last call to
* readdir(2), then we might be pointing to an invalid
diff --git a/fs/ext3/file.c b/fs/ext3/file.c
index 98e78345ead9..59098ea56711 100644
--- a/fs/ext3/file.c
+++ b/fs/ext3/file.c
@@ -37,9 +37,9 @@ static int ext3_release_file (struct inode * inode, struct file * filp)
if ((filp->f_mode & FMODE_WRITE) &&
(atomic_read(&inode->i_writecount) == 1))
{
- down(&EXT3_I(inode)->truncate_sem);
+ mutex_lock(&EXT3_I(inode)->truncate_mutex);
ext3_discard_reservation(inode);
- up(&EXT3_I(inode)->truncate_sem);
+ mutex_unlock(&EXT3_I(inode)->truncate_mutex);
}
if (is_dx(inode) && filp->private_data)
ext3_htree_free_dir_info(filp->private_data);
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 0384e539b88f..2c361377e0a5 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -671,7 +671,7 @@ err_out:
* The BKL may not be held on entry here. Be sure to take it early.
*/
-static int
+int
ext3_get_block_handle(handle_t *handle, struct inode *inode, sector_t iblock,
struct buffer_head *bh_result, int create, int extend_disksize)
{
@@ -702,7 +702,7 @@ ext3_get_block_handle(handle_t *handle, struct inode *inode, sector_t iblock,
if (!create || err == -EIO)
goto cleanup;
- down(&ei->truncate_sem);
+ mutex_lock(&ei->truncate_mutex);
/*
* If the indirect block is missing while we are reading
@@ -723,7 +723,7 @@ ext3_get_block_handle(handle_t *handle, struct inode *inode, sector_t iblock,
}
partial = ext3_get_branch(inode, depth, offsets, chain, &err);
if (!partial) {
- up(&ei->truncate_sem);
+ mutex_unlock(&ei->truncate_mutex);
if (err)
goto cleanup;
clear_buffer_new(bh_result);
@@ -759,13 +759,13 @@ ext3_get_block_handle(handle_t *handle, struct inode *inode, sector_t iblock,
err = ext3_splice_branch(handle, inode, iblock, chain,
partial, left);
/*
- * i_disksize growing is protected by truncate_sem. Don't forget to
+ * i_disksize growing is protected by truncate_mutex. Don't forget to
* protect it if you're about to implement concurrent
* ext3_get_block() -bzzz
*/
if (!err && extend_disksize && inode->i_size > ei->i_disksize)
ei->i_disksize = inode->i_size;
- up(&ei->truncate_sem);
+ mutex_unlock(&ei->truncate_mutex);
if (err)
goto cleanup;
@@ -1227,7 +1227,7 @@ static int journal_dirty_data_fn(handle_t *handle, struct buffer_head *bh)
* ext3_file_write() -> generic_file_write() -> __alloc_pages() -> ...
*
* Same applies to ext3_get_block(). We will deadlock on various things like
- * lock_journal and i_truncate_sem.
+ * lock_journal and i_truncate_mutex.
*
* Setting PF_MEMALLOC here doesn't work - too many internal memory
* allocations fail.
@@ -2161,7 +2161,7 @@ void ext3_truncate(struct inode * inode)
* From here we block out all ext3_get_block() callers who want to
* modify the block allocation tree.
*/
- down(&ei->truncate_sem);
+ mutex_lock(&ei->truncate_mutex);
if (n == 1) { /* direct blocks */
ext3_free_data(handle, inode, NULL, i_data+offsets[0],
@@ -2228,7 +2228,7 @@ do_indirects:
ext3_discard_reservation(inode);
- up(&ei->truncate_sem);
+ mutex_unlock(&ei->truncate_mutex);
inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
ext3_mark_inode_dirty(handle, inode);
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c
index 556cd5510078..aaf1da17b6d4 100644
--- a/fs/ext3/ioctl.c
+++ b/fs/ext3/ioctl.c
@@ -182,7 +182,7 @@ flags_err:
* need to allocate reservation structure for this inode
* before set the window size
*/
- down(&ei->truncate_sem);
+ mutex_lock(&ei->truncate_mutex);
if (!ei->i_block_alloc_info)
ext3_init_block_alloc_info(inode);
@@ -190,7 +190,7 @@ flags_err:
struct ext3_reserve_window_node *rsv = &ei->i_block_alloc_info->rsv_window_node;
rsv->rsv_goal_size = rsv_window_size;
}
- up(&ei->truncate_sem);
+ mutex_unlock(&ei->truncate_mutex);
return 0;
}
case EXT3_IOC_GROUP_EXTEND: {
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 56bf76586019..efe5b20d7a5a 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -472,7 +472,7 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
#ifdef CONFIG_EXT3_FS_XATTR
init_rwsem(&ei->xattr_sem);
#endif
- init_MUTEX(&ei->truncate_sem);
+ mutex_init(&ei->truncate_mutex);
inode_init_once(&ei->vfs_inode);
}
}
@@ -2382,8 +2382,8 @@ static int ext3_statfs (struct super_block * sb, struct kstatfs * buf)
* Process 1 Process 2
* ext3_create() quota_sync()
* journal_start() write_dquot()
- * DQUOT_INIT() down(dqio_sem)
- * down(dqio_sem) journal_start()
+ * DQUOT_INIT() down(dqio_mutex)
+ * down(dqio_mutex) journal_start()
*
*/
diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c
index a1a9e0451217..ab171ea8e869 100644
--- a/fs/fat/fatent.c
+++ b/fs/fat/fatent.c
@@ -267,19 +267,19 @@ static struct fatent_operations fat32_ops = {
static inline void lock_fat(struct msdos_sb_info *sbi)
{
- down(&sbi->fat_lock);
+ mutex_lock(&sbi->fat_lock);
}
static inline void unlock_fat(struct msdos_sb_info *sbi)
{
- up(&sbi->fat_lock);
+ mutex_unlock(&sbi->fat_lock);
}
void fat_ent_access_init(struct super_block *sb)
{
struct msdos_sb_info *sbi = MSDOS_SB(sb);
- init_MUTEX(&sbi->fat_lock);
+ mutex_init(&sbi->fat_lock);
switch (sbi->fat_bits) {
case 32:
diff --git a/fs/fcntl.c b/fs/fcntl.c
index dc4a7007f4e7..03c789560fb8 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -73,8 +73,8 @@ repeat:
* orig_start..fdt->next_fd
*/
start = orig_start;
- if (start < fdt->next_fd)
- start = fdt->next_fd;
+ if (start < files->next_fd)
+ start = files->next_fd;
newfd = start;
if (start < fdt->max_fdset) {
@@ -102,9 +102,8 @@ repeat:
* we reacquire the fdtable pointer and use it while holding
* the lock, no one can free it during that time.
*/
- fdt = files_fdtable(files);
- if (start <= fdt->next_fd)
- fdt->next_fd = newfd + 1;
+ if (start <= files->next_fd)
+ files->next_fd = newfd + 1;
error = newfd;
diff --git a/fs/file.c b/fs/file.c
index cea7cbea11d0..bbc743314730 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -125,7 +125,8 @@ static void free_fdtable_rcu(struct rcu_head *rcu)
kmem_cache_free(files_cachep, fdt->free_files);
return;
}
- if (fdt->max_fdset <= __FD_SETSIZE && fdt->max_fds <= NR_OPEN_DEFAULT) {
+ if (fdt->max_fdset <= EMBEDDED_FD_SET_SIZE &&
+ fdt->max_fds <= NR_OPEN_DEFAULT) {
/*
* The fdtable was embedded
*/
@@ -155,8 +156,9 @@ static void free_fdtable_rcu(struct rcu_head *rcu)
void free_fdtable(struct fdtable *fdt)
{
- if (fdt->free_files || fdt->max_fdset > __FD_SETSIZE ||
- fdt->max_fds > NR_OPEN_DEFAULT)
+ if (fdt->free_files ||
+ fdt->max_fdset > EMBEDDED_FD_SET_SIZE ||
+ fdt->max_fds > NR_OPEN_DEFAULT)
call_rcu(&fdt->rcu, free_fdtable_rcu);
}
@@ -199,7 +201,6 @@ static void copy_fdtable(struct fdtable *nfdt, struct fdtable *fdt)
(nfdt->max_fds - fdt->max_fds) *
sizeof(struct file *));
}
- nfdt->next_fd = fdt->next_fd;
}
/*
@@ -220,11 +221,9 @@ fd_set * alloc_fdset(int num)
void free_fdset(fd_set *array, int num)
{
- int size = num / 8;
-
- if (num <= __FD_SETSIZE) /* Don't free an embedded fdset */
+ if (num <= EMBEDDED_FD_SET_SIZE) /* Don't free an embedded fdset */
return;
- else if (size <= PAGE_SIZE)
+ else if (num <= 8 * PAGE_SIZE)
kfree(array);
else
vfree(array);
@@ -237,22 +236,17 @@ static struct fdtable *alloc_fdtable(int nr)
fd_set *new_openset = NULL, *new_execset = NULL;
struct file **new_fds;
- fdt = kmalloc(sizeof(*fdt), GFP_KERNEL);
+ fdt = kzalloc(sizeof(*fdt), GFP_KERNEL);
if (!fdt)
goto out;
- memset(fdt, 0, sizeof(*fdt));
- nfds = __FD_SETSIZE;
+ nfds = 8 * L1_CACHE_BYTES;
/* Expand to the max in easy steps */
- do {
- if (nfds < (PAGE_SIZE * 8))
- nfds = PAGE_SIZE * 8;
- else {
- nfds = nfds * 2;
- if (nfds > NR_OPEN)
- nfds = NR_OPEN;
- }
- } while (nfds <= nr);
+ while (nfds <= nr) {
+ nfds = nfds * 2;
+ if (nfds > NR_OPEN)
+ nfds = NR_OPEN;
+ }
new_openset = alloc_fdset(nfds);
new_execset = alloc_fdset(nfds);
diff --git a/fs/file_table.c b/fs/file_table.c
index 44fabeaa9415..bcea1998b4de 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -88,6 +88,7 @@ int proc_nr_files(ctl_table *table, int write, struct file *filp,
*/
struct file *get_empty_filp(void)
{
+ struct task_struct *tsk;
static int old_max;
struct file * f;
@@ -112,13 +113,14 @@ struct file *get_empty_filp(void)
if (security_file_alloc(f))
goto fail_sec;
- eventpoll_init_file(f);
+ tsk = current;
+ INIT_LIST_HEAD(&f->f_u.fu_list);
atomic_set(&f->f_count, 1);
- f->f_uid = current->fsuid;
- f->f_gid = current->fsgid;
rwlock_init(&f->f_owner.lock);
+ f->f_uid = tsk->fsuid;
+ f->f_gid = tsk->fsgid;
+ eventpoll_init_file(f);
/* f->f_version: 0 */
- INIT_LIST_HEAD(&f->f_u.fu_list);
return f;
over:
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h
index 6628c3b352cb..4c6473ab3b34 100644
--- a/fs/hpfs/hpfs_fn.h
+++ b/fs/hpfs/hpfs_fn.h
@@ -9,6 +9,7 @@
//#define DBG
//#define DEBUG_LOCKS
+#include <linux/mutex.h>
#include <linux/pagemap.h>
#include <linux/buffer_head.h>
#include <linux/hpfs_fs.h>
@@ -57,8 +58,8 @@ struct hpfs_inode_info {
unsigned i_ea_uid : 1; /* file's uid is stored in ea */
unsigned i_ea_gid : 1; /* file's gid is stored in ea */
unsigned i_dirty : 1;
- struct semaphore i_sem;
- struct semaphore i_parent;
+ struct mutex i_mutex;
+ struct mutex i_parent_mutex;
loff_t **i_rddir_off;
struct inode vfs_inode;
};
diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c
index e3d17e9ea6c1..56f2c338c4d9 100644
--- a/fs/hpfs/inode.c
+++ b/fs/hpfs/inode.c
@@ -186,9 +186,9 @@ void hpfs_write_inode(struct inode *i)
kfree(hpfs_inode->i_rddir_off);
hpfs_inode->i_rddir_off = NULL;
}
- down(&hpfs_inode->i_parent);
+ mutex_lock(&hpfs_inode->i_parent_mutex);
if (!i->i_nlink) {
- up(&hpfs_inode->i_parent);
+ mutex_unlock(&hpfs_inode->i_parent_mutex);
return;
}
parent = iget_locked(i->i_sb, hpfs_inode->i_parent_dir);
@@ -199,14 +199,14 @@ void hpfs_write_inode(struct inode *i)
hpfs_read_inode(parent);
unlock_new_inode(parent);
}
- down(&hpfs_inode->i_sem);
+ mutex_lock(&hpfs_inode->i_mutex);
hpfs_write_inode_nolock(i);
- up(&hpfs_inode->i_sem);
+ mutex_unlock(&hpfs_inode->i_mutex);
iput(parent);
} else {
mark_inode_dirty(i);
}
- up(&hpfs_inode->i_parent);
+ mutex_unlock(&hpfs_inode->i_parent_mutex);
}
void hpfs_write_inode_nolock(struct inode *i)
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c
index 8ff8fc433fc1..a03abb12c610 100644
--- a/fs/hpfs/namei.c
+++ b/fs/hpfs/namei.c
@@ -60,7 +60,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
if (dee.read_only)
result->i_mode &= ~0222;
- down(&hpfs_i(dir)->i_sem);
+ mutex_lock(&hpfs_i(dir)->i_mutex);
r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
if (r == 1)
goto bail3;
@@ -101,11 +101,11 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
hpfs_write_inode_nolock(result);
}
d_instantiate(dentry, result);
- up(&hpfs_i(dir)->i_sem);
+ mutex_unlock(&hpfs_i(dir)->i_mutex);
unlock_kernel();
return 0;
bail3:
- up(&hpfs_i(dir)->i_sem);
+ mutex_unlock(&hpfs_i(dir)->i_mutex);
iput(result);
bail2:
hpfs_brelse4(&qbh0);
@@ -168,7 +168,7 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struc
result->i_data.a_ops = &hpfs_aops;
hpfs_i(result)->mmu_private = 0;
- down(&hpfs_i(dir)->i_sem);
+ mutex_lock(&hpfs_i(dir)->i_mutex);
r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
if (r == 1)
goto bail2;
@@ -193,12 +193,12 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struc
hpfs_write_inode_nolock(result);
}
d_instantiate(dentry, result);
- up(&hpfs_i(dir)->i_sem);
+ mutex_unlock(&hpfs_i(dir)->i_mutex);
unlock_kernel();
return 0;
bail2:
- up(&hpfs_i(dir)->i_sem);
+ mutex_unlock(&hpfs_i(dir)->i_mutex);
iput(result);
bail1:
brelse(bh);
@@ -254,7 +254,7 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t
result->i_blocks = 1;
init_special_inode(result, mode, rdev);
- down(&hpfs_i(dir)->i_sem);
+ mutex_lock(&hpfs_i(dir)->i_mutex);
r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
if (r == 1)
goto bail2;
@@ -271,12 +271,12 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t
hpfs_write_inode_nolock(result);
d_instantiate(dentry, result);
- up(&hpfs_i(dir)->i_sem);
+ mutex_unlock(&hpfs_i(dir)->i_mutex);
brelse(bh);
unlock_kernel();
return 0;
bail2:
- up(&hpfs_i(dir)->i_sem);
+ mutex_unlock(&hpfs_i(dir)->i_mutex);
iput(result);
bail1:
brelse(bh);
@@ -333,7 +333,7 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy
result->i_op = &page_symlink_inode_operations;
result->i_data.a_ops = &hpfs_symlink_aops;
- down(&hpfs_i(dir)->i_sem);
+ mutex_lock(&hpfs_i(dir)->i_mutex);
r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
if (r == 1)
goto bail2;
@@ -352,11 +352,11 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy
hpfs_write_inode_nolock(result);
d_instantiate(dentry, result);
- up(&hpfs_i(dir)->i_sem);
+ mutex_unlock(&hpfs_i(dir)->i_mutex);
unlock_kernel();
return 0;
bail2:
- up(&hpfs_i(dir)->i_sem);
+ mutex_unlock(&hpfs_i(dir)->i_mutex);
iput(result);
bail1:
brelse(bh);
@@ -382,8 +382,8 @@ static int hpfs_unlink(struct inode *dir, struct dentry *dentry)
lock_kernel();
hpfs_adjust_length((char *)name, &len);
again:
- down(&hpfs_i(inode)->i_parent);
- down(&hpfs_i(dir)->i_sem);
+ mutex_lock(&hpfs_i(inode)->i_parent_mutex);
+ mutex_lock(&hpfs_i(dir)->i_mutex);
err = -ENOENT;
de = map_dirent(dir, hpfs_i(dir)->i_dno, (char *)name, len, &dno, &qbh);
if (!de)
@@ -410,8 +410,8 @@ again:
if (rep++)
break;
- up(&hpfs_i(dir)->i_sem);
- up(&hpfs_i(inode)->i_parent);
+ mutex_unlock(&hpfs_i(dir)->i_mutex);
+ mutex_unlock(&hpfs_i(inode)->i_parent_mutex);
d_drop(dentry);
spin_lock(&dentry->d_lock);
if (atomic_read(&dentry->d_count) > 1 ||
@@ -442,8 +442,8 @@ again:
out1:
hpfs_brelse4(&qbh);
out:
- up(&hpfs_i(dir)->i_sem);
- up(&hpfs_i(inode)->i_parent);
+ mutex_unlock(&hpfs_i(dir)->i_mutex);
+ mutex_unlock(&hpfs_i(inode)->i_parent_mutex);
unlock_kernel();
return err;
}
@@ -463,8 +463,8 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
hpfs_adjust_length((char *)name, &len);
lock_kernel();
- down(&hpfs_i(inode)->i_parent);
- down(&hpfs_i(dir)->i_sem);
+ mutex_lock(&hpfs_i(inode)->i_parent_mutex);
+ mutex_lock(&hpfs_i(dir)->i_mutex);
err = -ENOENT;
de = map_dirent(dir, hpfs_i(dir)->i_dno, (char *)name, len, &dno, &qbh);
if (!de)
@@ -502,8 +502,8 @@ static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
out1:
hpfs_brelse4(&qbh);
out:
- up(&hpfs_i(dir)->i_sem);
- up(&hpfs_i(inode)->i_parent);
+ mutex_unlock(&hpfs_i(dir)->i_mutex);
+ mutex_unlock(&hpfs_i(inode)->i_parent_mutex);
unlock_kernel();
return err;
}
@@ -565,12 +565,12 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
lock_kernel();
/* order doesn't matter, due to VFS exclusion */
- down(&hpfs_i(i)->i_parent);
+ mutex_lock(&hpfs_i(i)->i_parent_mutex);
if (new_inode)
- down(&hpfs_i(new_inode)->i_parent);
- down(&hpfs_i(old_dir)->i_sem);
+ mutex_lock(&hpfs_i(new_inode)->i_parent_mutex);
+ mutex_lock(&hpfs_i(old_dir)->i_mutex);
if (new_dir != old_dir)
- down(&hpfs_i(new_dir)->i_sem);
+ mutex_lock(&hpfs_i(new_dir)->i_mutex);
/* Erm? Moving over the empty non-busy directory is perfectly legal */
if (new_inode && S_ISDIR(new_inode->i_mode)) {
@@ -650,11 +650,11 @@ static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
hpfs_decide_conv(i, (char *)new_name, new_len);
end1:
if (old_dir != new_dir)
- up(&hpfs_i(new_dir)->i_sem);
- up(&hpfs_i(old_dir)->i_sem);
- up(&hpfs_i(i)->i_parent);
+ mutex_unlock(&hpfs_i(new_dir)->i_mutex);
+ mutex_unlock(&hpfs_i(old_dir)->i_mutex);
+ mutex_unlock(&hpfs_i(i)->i_parent_mutex);
if (new_inode)
- up(&hpfs_i(new_inode)->i_parent);
+ mutex_unlock(&hpfs_i(new_inode)->i_parent_mutex);
unlock_kernel();
return err;
}
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index 63e88d7e2c3b..9488a794076e 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -181,8 +181,8 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
SLAB_CTOR_CONSTRUCTOR) {
- init_MUTEX(&ei->i_sem);
- init_MUTEX(&ei->i_parent);
+ mutex_init(&ei->i_mutex);
+ mutex_init(&ei->i_parent_mutex);
inode_init_once(&ei->vfs_inode);
}
}
diff --git a/fs/inode.c b/fs/inode.c
index d0be6159eb7f..25967b67903d 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -84,14 +84,14 @@ static struct hlist_head *inode_hashtable;
DEFINE_SPINLOCK(inode_lock);
/*
- * iprune_sem provides exclusion between the kswapd or try_to_free_pages
+ * iprune_mutex provides exclusion between the kswapd or try_to_free_pages
* icache shrinking path, and the umount path. Without this exclusion,
* by the time prune_icache calls iput for the inode whose pages it has
* been invalidating, or by the time it calls clear_inode & destroy_inode
* from its final dispose_list, the struct super_block they refer to
* (for inode->i_sb->s_op) may already have been freed and reused.
*/
-DECLARE_MUTEX(iprune_sem);
+DEFINE_MUTEX(iprune_mutex);
/*
* Statistics gathering..
@@ -206,7 +206,7 @@ void inode_init_once(struct inode *inode)
i_size_ordered_init(inode);
#ifdef CONFIG_INOTIFY
INIT_LIST_HEAD(&inode->inotify_watches);
- sema_init(&inode->inotify_sem, 1);
+ mutex_init(&inode->inotify_mutex);
#endif
}
@@ -319,7 +319,7 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose)
/*
* We can reschedule here without worrying about the list's
* consistency because the per-sb list of inodes must not
- * change during umount anymore, and because iprune_sem keeps
+ * change during umount anymore, and because iprune_mutex keeps
* shrink_icache_memory() away.
*/
cond_resched_lock(&inode_lock);
@@ -355,14 +355,14 @@ int invalidate_inodes(struct super_block * sb)
int busy;
LIST_HEAD(throw_away);
- down(&iprune_sem);
+ mutex_lock(&iprune_mutex);
spin_lock(&inode_lock);
inotify_unmount_inodes(&sb->s_inodes);
busy = invalidate_list(&sb->s_inodes, &throw_away);
spin_unlock(&inode_lock);
dispose_list(&throw_away);
- up(&iprune_sem);
+ mutex_unlock(&iprune_mutex);
return busy;
}
@@ -377,7 +377,7 @@ int __invalidate_device(struct block_device *bdev)
if (sb) {
/*
* no need to lock the super, get_super holds the
- * read semaphore so the filesystem cannot go away
+ * read mutex so the filesystem cannot go away
* under us (->put_super runs with the write lock
* hold).
*/
@@ -423,7 +423,7 @@ static void prune_icache(int nr_to_scan)
int nr_scanned;
unsigned long reap = 0;
- down(&iprune_sem);
+ mutex_lock(&iprune_mutex);
spin_lock(&inode_lock);
for (nr_scanned = 0; nr_scanned < nr_to_scan; nr_scanned++) {
struct inode *inode;
@@ -459,7 +459,7 @@ static void prune_icache(int nr_to_scan)
spin_unlock(&inode_lock);
dispose_list(&freeable);
- up(&iprune_sem);
+ mutex_unlock(&iprune_mutex);
if (current_is_kswapd())
mod_page_state(kswapd_inodesteal, reap);
diff --git a/fs/inotify.c b/fs/inotify.c
index 3041503bde02..0ee39ef591c6 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -54,10 +54,10 @@ int inotify_max_queued_events;
* Lock ordering:
*
* dentry->d_lock (used to keep d_move() away from dentry->d_parent)
- * iprune_sem (synchronize shrink_icache_memory())
+ * iprune_mutex (synchronize shrink_icache_memory())
* inode_lock (protects the super_block->s_inodes list)
- * inode->inotify_sem (protects inode->inotify_watches and watches->i_list)
- * inotify_dev->sem (protects inotify_device and watches->d_list)
+ * inode->inotify_mutex (protects inode->inotify_watches and watches->i_list)
+ * inotify_dev->mutex (protects inotify_device and watches->d_list)
*/
/*
@@ -79,12 +79,12 @@ int inotify_max_queued_events;
/*
* struct inotify_device - represents an inotify instance
*
- * This structure is protected by the semaphore 'sem'.
+ * This structure is protected by the mutex 'mutex'.
*/
struct inotify_device {
wait_queue_head_t wq; /* wait queue for i/o */
struct idr idr; /* idr mapping wd -> watch */
- struct semaphore sem; /* protects this bad boy */
+ struct mutex mutex; /* protects this bad boy */
struct list_head events; /* list of queued events */
struct list_head watches; /* list of watches */
atomic_t count; /* reference count */
@@ -101,7 +101,7 @@ struct inotify_device {
* device. In read(), this list is walked and all events that can fit in the
* buffer are returned.
*
- * Protected by dev->sem of the device in which we are queued.
+ * Protected by dev->mutex of the device in which we are queued.
*/
struct inotify_kernel_event {
struct inotify_event event; /* the user-space event */
@@ -112,8 +112,8 @@ struct inotify_kernel_event {
/*
* struct inotify_watch - represents a watch request on a specific inode
*
- * d_list is protected by dev->sem of the associated watch->dev.
- * i_list and mask are protected by inode->inotify_sem of the associated inode.
+ * d_list is protected by dev->mutex of the associated watch->dev.
+ * i_list and mask are protected by inode->inotify_mutex of the associated inode.
* dev, inode, and wd are never written to once the watch is created.
*/
struct inotify_watch {
@@ -261,7 +261,7 @@ static struct inotify_kernel_event * kernel_event(s32 wd, u32 mask, u32 cookie,
/*
* inotify_dev_get_event - return the next event in the given dev's queue
*
- * Caller must hold dev->sem.
+ * Caller must hold dev->mutex.
*/
static inline struct inotify_kernel_event *
inotify_dev_get_event(struct inotify_device *dev)
@@ -272,7 +272,7 @@ inotify_dev_get_event(struct inotify_device *dev)
/*
* inotify_dev_queue_event - add a new event to the given device
*
- * Caller must hold dev->sem. Can sleep (calls kernel_event()).
+ * Caller must hold dev->mutex. Can sleep (calls kernel_event()).
*/
static void inotify_dev_queue_event(struct inotify_device *dev,
struct inotify_watch *watch, u32 mask,
@@ -315,7 +315,7 @@ static void inotify_dev_queue_event(struct inotify_device *dev,
/*
* remove_kevent - cleans up and ultimately frees the given kevent
*
- * Caller must hold dev->sem.
+ * Caller must hold dev->mutex.
*/
static void remove_kevent(struct inotify_device *dev,
struct inotify_kernel_event *kevent)
@@ -332,7 +332,7 @@ static void remove_kevent(struct inotify_device *dev,
/*
* inotify_dev_event_dequeue - destroy an event on the given device
*
- * Caller must hold dev->sem.
+ * Caller must hold dev->mutex.
*/
static void inotify_dev_event_dequeue(struct inotify_device *dev)
{
@@ -346,7 +346,7 @@ static void inotify_dev_event_dequeue(struct inotify_device *dev)
/*
* inotify_dev_get_wd - returns the next WD for use by the given dev
*
- * Callers must hold dev->sem. This function can sleep.
+ * Callers must hold dev->mutex. This function can sleep.
*/
static int inotify_dev_get_wd(struct inotify_device *dev,
struct inotify_watch *watch)
@@ -383,7 +383,7 @@ static int find_inode(const char __user *dirname, struct nameidata *nd,
/*
* create_watch - creates a watch on the given device.
*
- * Callers must hold dev->sem. Calls inotify_dev_get_wd() so may sleep.
+ * Callers must hold dev->mutex. Calls inotify_dev_get_wd() so may sleep.
* Both 'dev' and 'inode' (by way of nameidata) need to be pinned.
*/
static struct inotify_watch *create_watch(struct inotify_device *dev,
@@ -434,7 +434,7 @@ static struct inotify_watch *create_watch(struct inotify_device *dev,
/*
* inotify_find_dev - find the watch associated with the given inode and dev
*
- * Callers must hold inode->inotify_sem.
+ * Callers must hold inode->inotify_mutex.
*/
static struct inotify_watch *inode_find_dev(struct inode *inode,
struct inotify_device *dev)
@@ -469,7 +469,7 @@ static void remove_watch_no_event(struct inotify_watch *watch,
* the IN_IGNORED event to the given device signifying that the inode is no
* longer watched.
*
- * Callers must hold both inode->inotify_sem and dev->sem. We drop a
+ * Callers must hold both inode->inotify_mutex and dev->mutex. We drop a
* reference to the inode before returning.
*
* The inode is not iput() so as to remain atomic. If the inode needs to be
@@ -507,21 +507,21 @@ void inotify_inode_queue_event(struct inode *inode, u32 mask, u32 cookie,
if (!inotify_inode_watched(inode))
return;
- down(&inode->inotify_sem);
+ mutex_lock(&inode->inotify_mutex);
list_for_each_entry_safe(watch, next, &inode->inotify_watches, i_list) {
u32 watch_mask = watch->mask;
if (watch_mask & mask) {
struct inotify_device *dev = watch->dev;
get_inotify_watch(watch);
- down(&dev->sem);
+ mutex_lock(&dev->mutex);
inotify_dev_queue_event(dev, watch, mask, cookie, name);
if (watch_mask & IN_ONESHOT)
remove_watch_no_event(watch, dev);
- up(&dev->sem);
+ mutex_unlock(&dev->mutex);
put_inotify_watch(watch);
}
}
- up(&inode->inotify_sem);
+ mutex_unlock(&inode->inotify_mutex);
}
EXPORT_SYMBOL_GPL(inotify_inode_queue_event);
@@ -569,7 +569,7 @@ EXPORT_SYMBOL_GPL(inotify_get_cookie);
* @list: list of inodes being unmounted (sb->s_inodes)
*
* Called with inode_lock held, protecting the unmounting super block's list
- * of inodes, and with iprune_sem held, keeping shrink_icache_memory() at bay.
+ * of inodes, and with iprune_mutex held, keeping shrink_icache_memory() at bay.
* We temporarily drop inode_lock, however, and CAN block.
*/
void inotify_unmount_inodes(struct list_head *list)
@@ -618,7 +618,7 @@ void inotify_unmount_inodes(struct list_head *list)
* We can safely drop inode_lock here because we hold
* references on both inode and next_i. Also no new inodes
* will be added since the umount has begun. Finally,
- * iprune_sem keeps shrink_icache_memory() away.
+ * iprune_mutex keeps shrink_icache_memory() away.
*/
spin_unlock(&inode_lock);
@@ -626,16 +626,16 @@ void inotify_unmount_inodes(struct list_head *list)
iput(need_iput_tmp);
/* for each watch, send IN_UNMOUNT and then remove it */
- down(&inode->inotify_sem);
+ mutex_lock(&inode->inotify_mutex);
watches = &inode->inotify_watches;
list_for_each_entry_safe(watch, next_w, watches, i_list) {
struct inotify_device *dev = watch->dev;
- down(&dev->sem);
+ mutex_lock(&dev->mutex);
inotify_dev_queue_event(dev, watch, IN_UNMOUNT,0,NULL);
remove_watch(watch, dev);
- up(&dev->sem);
+ mutex_unlock(&dev->mutex);
}
- up(&inode->inotify_sem);
+ mutex_unlock(&inode->inotify_mutex);
iput(inode);
spin_lock(&inode_lock);
@@ -651,14 +651,14 @@ void inotify_inode_is_dead(struct inode *inode)
{
struct inotify_watch *watch, *next;
- down(&inode->inotify_sem);
+ mutex_lock(&inode->inotify_mutex);
list_for_each_entry_safe(watch, next, &inode->inotify_watches, i_list) {
struct inotify_device *dev = watch->dev;
- down(&dev->sem);
+ mutex_lock(&dev->mutex);
remove_watch(watch, dev);
- up(&dev->sem);
+ mutex_unlock(&dev->mutex);
}
- up(&inode->inotify_sem);
+ mutex_unlock(&inode->inotify_mutex);
}
EXPORT_SYMBOL_GPL(inotify_inode_is_dead);
@@ -670,10 +670,10 @@ static unsigned int inotify_poll(struct file *file, poll_table *wait)
int ret = 0;
poll_wait(file, &dev->wq, wait);
- down(&dev->sem);
+ mutex_lock(&dev->mutex);
if (!list_empty(&dev->events))
ret = POLLIN | POLLRDNORM;
- up(&dev->sem);
+ mutex_unlock(&dev->mutex);
return ret;
}
@@ -695,9 +695,9 @@ static ssize_t inotify_read(struct file *file, char __user *buf,
prepare_to_wait(&dev->wq, &wait, TASK_INTERRUPTIBLE);
- down(&dev->sem);
+ mutex_lock(&dev->mutex);
events = !list_empty(&dev->events);
- up(&dev->sem);
+ mutex_unlock(&dev->mutex);
if (events) {
ret = 0;
break;
@@ -720,7 +720,7 @@ static ssize_t inotify_read(struct file *file, char __user *buf,
if (ret)
return ret;
- down(&dev->sem);
+ mutex_lock(&dev->mutex);
while (1) {
struct inotify_kernel_event *kevent;
@@ -750,7 +750,7 @@ static ssize_t inotify_read(struct file *file, char __user *buf,
remove_kevent(dev, kevent);
}
- up(&dev->sem);
+ mutex_unlock(&dev->mutex);
return ret;
}
@@ -763,37 +763,37 @@ static int inotify_release(struct inode *ignored, struct file *file)
* Destroy all of the watches on this device. Unfortunately, not very
* pretty. We cannot do a simple iteration over the list, because we
* do not know the inode until we iterate to the watch. But we need to
- * hold inode->inotify_sem before dev->sem. The following works.
+ * hold inode->inotify_mutex before dev->mutex. The following works.
*/
while (1) {
struct inotify_watch *watch;
struct list_head *watches;
struct inode *inode;
- down(&dev->sem);
+ mutex_lock(&dev->mutex);
watches = &dev->watches;
if (list_empty(watches)) {
- up(&dev->sem);
+ mutex_unlock(&dev->mutex);
break;
}
watch = list_entry(watches->next, struct inotify_watch, d_list);
get_inotify_watch(watch);
- up(&dev->sem);
+ mutex_unlock(&dev->mutex);
inode = watch->inode;
- down(&inode->inotify_sem);
- down(&dev->sem);
+ mutex_lock(&inode->inotify_mutex);
+ mutex_lock(&dev->mutex);
remove_watch_no_event(watch, dev);
- up(&dev->sem);
- up(&inode->inotify_sem);
+ mutex_unlock(&dev->mutex);
+ mutex_unlock(&inode->inotify_mutex);
put_inotify_watch(watch);
}
/* destroy all of the events on this device */
- down(&dev->sem);
+ mutex_lock(&dev->mutex);
while (!list_empty(&dev->events))
inotify_dev_event_dequeue(dev);
- up(&dev->sem);
+ mutex_unlock(&dev->mutex);
/* free this device: the put matching the get in inotify_init() */
put_inotify_dev(dev);
@@ -811,26 +811,26 @@ static int inotify_ignore(struct inotify_device *dev, s32 wd)
struct inotify_watch *watch;
struct inode *inode;
- down(&dev->sem);
+ mutex_lock(&dev->mutex);
watch = idr_find(&dev->idr, wd);
if (unlikely(!watch)) {
- up(&dev->sem);
+ mutex_unlock(&dev->mutex);
return -EINVAL;
}
get_inotify_watch(watch);
inode = watch->inode;
- up(&dev->sem);
+ mutex_unlock(&dev->mutex);
- down(&inode->inotify_sem);
- down(&dev->sem);
+ mutex_lock(&inode->inotify_mutex);
+ mutex_lock(&dev->mutex);
/* make sure that we did not race */
watch = idr_find(&dev->idr, wd);
if (likely(watch))
remove_watch(watch, dev);
- up(&dev->sem);
- up(&inode->inotify_sem);
+ mutex_unlock(&dev->mutex);
+ mutex_unlock(&inode->inotify_mutex);
put_inotify_watch(watch);
return 0;
@@ -905,7 +905,7 @@ asmlinkage long sys_inotify_init(void)
INIT_LIST_HEAD(&dev->events);
INIT_LIST_HEAD(&dev->watches);
init_waitqueue_head(&dev->wq);
- sema_init(&dev->sem, 1);
+ mutex_init(&dev->mutex);
dev->event_count = 0;
dev->queue_size = 0;
dev->max_events = inotify_max_queued_events;
@@ -960,8 +960,8 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
inode = nd.dentry->d_inode;
dev = filp->private_data;
- down(&inode->inotify_sem);
- down(&dev->sem);
+ mutex_lock(&inode->inotify_mutex);
+ mutex_lock(&dev->mutex);
if (mask & IN_MASK_ADD)
mask_add = 1;
@@ -998,8 +998,8 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
list_add(&watch->i_list, &inode->inotify_watches);
ret = watch->wd;
out:
- up(&dev->sem);
- up(&inode->inotify_sem);
+ mutex_unlock(&dev->mutex);
+ mutex_unlock(&inode->inotify_mutex);
path_release(&nd);
fput_and_out:
fput_light(filp, fput_needed);
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
index 543ed543d1e5..3f5102b069db 100644
--- a/fs/jbd/checkpoint.c
+++ b/fs/jbd/checkpoint.c
@@ -85,7 +85,7 @@ void __log_wait_for_space(journal_t *journal)
if (journal->j_flags & JFS_ABORT)
return;
spin_unlock(&journal->j_state_lock);
- down(&journal->j_checkpoint_sem);
+ mutex_lock(&journal->j_checkpoint_mutex);
/*
* Test again, another process may have checkpointed while we
@@ -98,7 +98,7 @@ void __log_wait_for_space(journal_t *journal)
log_do_checkpoint(journal);
spin_lock(&journal->j_state_lock);
}
- up(&journal->j_checkpoint_sem);
+ mutex_unlock(&journal->j_checkpoint_mutex);
}
}
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index e4b516ac4989..95a628d8cac8 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -659,8 +659,8 @@ static journal_t * journal_init_common (void)
init_waitqueue_head(&journal->j_wait_checkpoint);
init_waitqueue_head(&journal->j_wait_commit);
init_waitqueue_head(&journal->j_wait_updates);
- init_MUTEX(&journal->j_barrier);
- init_MUTEX(&journal->j_checkpoint_sem);
+ mutex_init(&journal->j_barrier);
+ mutex_init(&journal->j_checkpoint_mutex);
spin_lock_init(&journal->j_revoke_lock);
spin_lock_init(&journal->j_list_lock);
spin_lock_init(&journal->j_state_lock);
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index ca917973c2c0..5fc40888f4cf 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -455,7 +455,7 @@ void journal_lock_updates(journal_t *journal)
* to make sure that we serialise special journal-locked operations
* too.
*/
- down(&journal->j_barrier);
+ mutex_lock(&journal->j_barrier);
}
/**
@@ -470,7 +470,7 @@ void journal_unlock_updates (journal_t *journal)
{
J_ASSERT(journal->j_barrier_count != 0);
- up(&journal->j_barrier);
+ mutex_unlock(&journal->j_barrier);
spin_lock(&journal->j_state_lock);
--journal->j_barrier_count;
spin_unlock(&journal->j_state_lock);
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index fc3855a1aef3..890d7ff7456d 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -42,7 +42,7 @@
#include <linux/quotaops.h>
#include <linux/highmem.h>
#include <linux/vfs.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
#include <asm/byteorder.h>
#include <asm/uaccess.h>
@@ -203,7 +203,7 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr)
fmc = c->fmc;
D3(printk (KERN_NOTICE "notify_change(): down biglock\n"));
- down(&fmc->biglock);
+ mutex_lock(&fmc->biglock);
f = jffs_find_file(c, inode->i_ino);
@@ -211,7 +211,7 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr)
printk("jffs_setattr(): Invalid inode number: %lu\n",
inode->i_ino);
D3(printk (KERN_NOTICE "notify_change(): up biglock\n"));
- up(&fmc->biglock);
+ mutex_unlock(&fmc->biglock);
res = -EINVAL;
goto out;
});
@@ -232,7 +232,7 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr)
if (!(new_node = jffs_alloc_node())) {
D(printk("jffs_setattr(): Allocation failed!\n"));
D3(printk (KERN_NOTICE "notify_change(): up biglock\n"));
- up(&fmc->biglock);
+ mutex_unlock(&fmc->biglock);
res = -ENOMEM;
goto out;
}
@@ -319,7 +319,7 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr)
D(printk("jffs_notify_change(): The write failed!\n"));
jffs_free_node(new_node);
D3(printk (KERN_NOTICE "n_c(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
goto out;
}
@@ -327,7 +327,7 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr)
mark_inode_dirty(inode);
D3(printk (KERN_NOTICE "n_c(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
out:
unlock_kernel();
return res;
@@ -461,7 +461,7 @@ jffs_rename(struct inode *old_dir, struct dentry *old_dentry,
goto jffs_rename_end;
}
D3(printk (KERN_NOTICE "rename(): down biglock\n"));
- down(&c->fmc->biglock);
+ mutex_lock(&c->fmc->biglock);
/* Create a node and initialize as much as needed. */
result = -ENOMEM;
if (!(node = jffs_alloc_node())) {
@@ -555,7 +555,7 @@ jffs_rename(struct inode *old_dir, struct dentry *old_dentry,
jffs_rename_end:
D3(printk (KERN_NOTICE "rename(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
unlock_kernel();
return result;
} /* jffs_rename() */
@@ -574,14 +574,14 @@ jffs_readdir(struct file *filp, void *dirent, filldir_t filldir)
int ddino;
lock_kernel();
D3(printk (KERN_NOTICE "readdir(): down biglock\n"));
- down(&c->fmc->biglock);
+ mutex_lock(&c->fmc->biglock);
D2(printk("jffs_readdir(): inode: 0x%p, filp: 0x%p\n", inode, filp));
if (filp->f_pos == 0) {
D3(printk("jffs_readdir(): \".\" %lu\n", inode->i_ino));
if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino, DT_DIR) < 0) {
D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
unlock_kernel();
return 0;
}
@@ -598,7 +598,7 @@ jffs_readdir(struct file *filp, void *dirent, filldir_t filldir)
D3(printk("jffs_readdir(): \"..\" %u\n", ddino));
if (filldir(dirent, "..", 2, filp->f_pos, ddino, DT_DIR) < 0) {
D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
unlock_kernel();
return 0;
}
@@ -617,7 +617,7 @@ jffs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (filldir(dirent, f->name, f->nsize,
filp->f_pos , f->ino, DT_UNKNOWN) < 0) {
D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
unlock_kernel();
return 0;
}
@@ -627,7 +627,7 @@ jffs_readdir(struct file *filp, void *dirent, filldir_t filldir)
} while(f && f->deleted);
}
D3(printk (KERN_NOTICE "readdir(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
unlock_kernel();
return filp->f_pos;
} /* jffs_readdir() */
@@ -660,7 +660,7 @@ jffs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
});
D3(printk (KERN_NOTICE "lookup(): down biglock\n"));
- down(&c->fmc->biglock);
+ mutex_lock(&c->fmc->biglock);
r = -ENAMETOOLONG;
if (len > JFFS_MAX_NAME_LEN) {
@@ -683,31 +683,31 @@ jffs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
if ((len == 1) && (name[0] == '.')) {
D3(printk (KERN_NOTICE "lookup(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
if (!(inode = iget(dir->i_sb, d->ino))) {
D(printk("jffs_lookup(): . iget() ==> NULL\n"));
goto jffs_lookup_end_no_biglock;
}
D3(printk (KERN_NOTICE "lookup(): down biglock\n"));
- down(&c->fmc->biglock);
+ mutex_lock(&c->fmc->biglock);
} else if ((len == 2) && (name[0] == '.') && (name[1] == '.')) {
D3(printk (KERN_NOTICE "lookup(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
if (!(inode = iget(dir->i_sb, d->pino))) {
D(printk("jffs_lookup(): .. iget() ==> NULL\n"));
goto jffs_lookup_end_no_biglock;
}
D3(printk (KERN_NOTICE "lookup(): down biglock\n"));
- down(&c->fmc->biglock);
+ mutex_lock(&c->fmc->biglock);
} else if ((f = jffs_find_child(d, name, len))) {
D3(printk (KERN_NOTICE "lookup(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
if (!(inode = iget(dir->i_sb, f->ino))) {
D(printk("jffs_lookup(): iget() ==> NULL\n"));
goto jffs_lookup_end_no_biglock;
}
D3(printk (KERN_NOTICE "lookup(): down biglock\n"));
- down(&c->fmc->biglock);
+ mutex_lock(&c->fmc->biglock);
} else {
D3(printk("jffs_lookup(): Couldn't find the file. "
"f = 0x%p, name = \"%s\", d = 0x%p, d->ino = %u\n",
@@ -717,13 +717,13 @@ jffs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
d_add(dentry, inode);
D3(printk (KERN_NOTICE "lookup(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
unlock_kernel();
return NULL;
jffs_lookup_end:
D3(printk (KERN_NOTICE "lookup(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
jffs_lookup_end_no_biglock:
unlock_kernel();
@@ -753,7 +753,7 @@ jffs_do_readpage_nolock(struct file *file, struct page *page)
ClearPageError(page);
D3(printk (KERN_NOTICE "readpage(): down biglock\n"));
- down(&c->fmc->biglock);
+ mutex_lock(&c->fmc->biglock);
read_len = 0;
result = 0;
@@ -782,7 +782,7 @@ jffs_do_readpage_nolock(struct file *file, struct page *page)
kunmap(page);
D3(printk (KERN_NOTICE "readpage(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
if (result) {
SetPageError(page);
@@ -839,7 +839,7 @@ jffs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
c = dir_f->c;
D3(printk (KERN_NOTICE "mkdir(): down biglock\n"));
- down(&c->fmc->biglock);
+ mutex_lock(&c->fmc->biglock);
dir_mode = S_IFDIR | (mode & (S_IRWXUGO|S_ISVTX)
& ~current->fs->umask);
@@ -906,7 +906,7 @@ jffs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
result = 0;
jffs_mkdir_end:
D3(printk (KERN_NOTICE "mkdir(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
unlock_kernel();
return result;
} /* jffs_mkdir() */
@@ -921,10 +921,10 @@ jffs_rmdir(struct inode *dir, struct dentry *dentry)
D3(printk("***jffs_rmdir()\n"));
D3(printk (KERN_NOTICE "rmdir(): down biglock\n"));
lock_kernel();
- down(&c->fmc->biglock);
+ mutex_lock(&c->fmc->biglock);
ret = jffs_remove(dir, dentry, S_IFDIR);
D3(printk (KERN_NOTICE "rmdir(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
unlock_kernel();
return ret;
}
@@ -940,10 +940,10 @@ jffs_unlink(struct inode *dir, struct dentry *dentry)
lock_kernel();
D3(printk("***jffs_unlink()\n"));
D3(printk (KERN_NOTICE "unlink(): down biglock\n"));
- down(&c->fmc->biglock);
+ mutex_lock(&c->fmc->biglock);
ret = jffs_remove(dir, dentry, 0);
D3(printk (KERN_NOTICE "unlink(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
unlock_kernel();
return ret;
}
@@ -1086,7 +1086,7 @@ jffs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
c = dir_f->c;
D3(printk (KERN_NOTICE "mknod(): down biglock\n"));
- down(&c->fmc->biglock);
+ mutex_lock(&c->fmc->biglock);
/* Create and initialize a new node. */
if (!(node = jffs_alloc_node())) {
@@ -1152,7 +1152,7 @@ jffs_mknod_err:
jffs_mknod_end:
D3(printk (KERN_NOTICE "mknod(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
unlock_kernel();
return result;
} /* jffs_mknod() */
@@ -1203,7 +1203,7 @@ jffs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
return -ENOMEM;
}
D3(printk (KERN_NOTICE "symlink(): down biglock\n"));
- down(&c->fmc->biglock);
+ mutex_lock(&c->fmc->biglock);
node->data_offset = 0;
node->removed_size = 0;
@@ -1253,7 +1253,7 @@ jffs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
d_instantiate(dentry, inode);
jffs_symlink_end:
D3(printk (KERN_NOTICE "symlink(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
unlock_kernel();
return err;
} /* jffs_symlink() */
@@ -1306,7 +1306,7 @@ jffs_create(struct inode *dir, struct dentry *dentry, int mode,
return -ENOMEM;
}
D3(printk (KERN_NOTICE "create(): down biglock\n"));
- down(&c->fmc->biglock);
+ mutex_lock(&c->fmc->biglock);
node->data_offset = 0;
node->removed_size = 0;
@@ -1359,7 +1359,7 @@ jffs_create(struct inode *dir, struct dentry *dentry, int mode,
d_instantiate(dentry, inode);
jffs_create_end:
D3(printk (KERN_NOTICE "create(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
unlock_kernel();
return err;
} /* jffs_create() */
@@ -1423,7 +1423,7 @@ jffs_file_write(struct file *filp, const char *buf, size_t count,
thiscount = min(c->fmc->max_chunk_size - sizeof(struct jffs_raw_inode), count);
D3(printk (KERN_NOTICE "file_write(): down biglock\n"));
- down(&c->fmc->biglock);
+ mutex_lock(&c->fmc->biglock);
/* Urgh. POSIX says we can do short writes if we feel like it.
* In practice, we can't. Nothing will cope. So we loop until
@@ -1511,7 +1511,7 @@ jffs_file_write(struct file *filp, const char *buf, size_t count,
}
out:
D3(printk (KERN_NOTICE "file_write(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
/* Fix things in the real inode. */
if (pos > inode->i_size) {
@@ -1567,7 +1567,7 @@ jffs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
return -EIO;
}
D3(printk (KERN_NOTICE "ioctl(): down biglock\n"));
- down(&c->fmc->biglock);
+ mutex_lock(&c->fmc->biglock);
switch (cmd) {
case JFFS_PRINT_HASH:
@@ -1609,7 +1609,7 @@ jffs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
ret = -ENOTTY;
}
D3(printk (KERN_NOTICE "ioctl(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
return ret;
} /* jffs_ioctl() */
@@ -1685,12 +1685,12 @@ jffs_read_inode(struct inode *inode)
}
c = (struct jffs_control *)inode->i_sb->s_fs_info;
D3(printk (KERN_NOTICE "read_inode(): down biglock\n"));
- down(&c->fmc->biglock);
+ mutex_lock(&c->fmc->biglock);
if (!(f = jffs_find_file(c, inode->i_ino))) {
D(printk("jffs_read_inode(): No such inode (%lu).\n",
inode->i_ino));
D3(printk (KERN_NOTICE "read_inode(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
return;
}
inode->u.generic_ip = (void *)f;
@@ -1732,7 +1732,7 @@ jffs_read_inode(struct inode *inode)
}
D3(printk (KERN_NOTICE "read_inode(): up biglock\n"));
- up(&c->fmc->biglock);
+ mutex_unlock(&c->fmc->biglock);
}
diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c
index ce7b54b0b2b7..0ef207dfaf6f 100644
--- a/fs/jffs/intrep.c
+++ b/fs/jffs/intrep.c
@@ -62,7 +62,7 @@
#include <linux/fs.h>
#include <linux/stat.h>
#include <linux/pagemap.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
#include <asm/byteorder.h>
#include <linux/smp_lock.h>
#include <linux/time.h>
@@ -3416,7 +3416,7 @@ jffs_garbage_collect_thread(void *ptr)
D1(printk (KERN_NOTICE "jffs_garbage_collect_thread(): collecting.\n"));
D3(printk (KERN_NOTICE "g_c_thread(): down biglock\n"));
- down(&fmc->biglock);
+ mutex_lock(&fmc->biglock);
D1(printk("***jffs_garbage_collect_thread(): round #%u, "
"fmc->dirty_size = %u\n", i++, fmc->dirty_size));
@@ -3447,6 +3447,6 @@ jffs_garbage_collect_thread(void *ptr)
gc_end:
D3(printk (KERN_NOTICE "g_c_thread(): up biglock\n"));
- up(&fmc->biglock);
+ mutex_unlock(&fmc->biglock);
} /* for (;;) */
} /* jffs_garbage_collect_thread() */
diff --git a/fs/jffs/jffs_fm.c b/fs/jffs/jffs_fm.c
index 6da13b309bd1..7d8ca1aeace2 100644
--- a/fs/jffs/jffs_fm.c
+++ b/fs/jffs/jffs_fm.c
@@ -139,7 +139,7 @@ jffs_build_begin(struct jffs_control *c, int unit)
fmc->tail = NULL;
fmc->head_extra = NULL;
fmc->tail_extra = NULL;
- init_MUTEX(&fmc->biglock);
+ mutex_init(&fmc->biglock);
return fmc;
}
diff --git a/fs/jffs/jffs_fm.h b/fs/jffs/jffs_fm.h
index f64151e74122..c794d923df2a 100644
--- a/fs/jffs/jffs_fm.h
+++ b/fs/jffs/jffs_fm.h
@@ -20,10 +20,11 @@
#ifndef __LINUX_JFFS_FM_H__
#define __LINUX_JFFS_FM_H__
+#include <linux/config.h>
#include <linux/types.h>
#include <linux/jffs.h>
#include <linux/mtd/mtd.h>
-#include <linux/config.h>
+#include <linux/mutex.h>
/* The alignment between two nodes in the flash memory. */
#define JFFS_ALIGN_SIZE 4
@@ -97,7 +98,7 @@ struct jffs_fmcontrol
struct jffs_fm *tail;
struct jffs_fm *head_extra;
struct jffs_fm *tail_extra;
- struct semaphore biglock;
+ struct mutex biglock;
};
/* Notice the two members head_extra and tail_extra in the jffs_control
diff --git a/fs/libfs.c b/fs/libfs.c
index 71fd08fa4103..4fdeaceb892c 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -7,6 +7,8 @@
#include <linux/pagemap.h>
#include <linux/mount.h>
#include <linux/vfs.h>
+#include <linux/mutex.h>
+
#include <asm/uaccess.h>
int simple_getattr(struct vfsmount *mnt, struct dentry *dentry,
@@ -530,7 +532,7 @@ struct simple_attr {
char set_buf[24];
void *data;
const char *fmt; /* format for read operation */
- struct semaphore sem; /* protects access to these buffers */
+ struct mutex mutex; /* protects access to these buffers */
};
/* simple_attr_open is called by an actual attribute open file operation
@@ -549,7 +551,7 @@ int simple_attr_open(struct inode *inode, struct file *file,
attr->set = set;
attr->data = inode->u.generic_ip;
attr->fmt = fmt;
- init_MUTEX(&attr->sem);
+ mutex_init(&attr->mutex);
file->private_data = attr;
@@ -575,7 +577,7 @@ ssize_t simple_attr_read(struct file *file, char __user *buf,
if (!attr->get)
return -EACCES;
- down(&attr->sem);
+ mutex_lock(&attr->mutex);
if (*ppos) /* continued read */
size = strlen(attr->get_buf);
else /* first read */
@@ -584,7 +586,7 @@ ssize_t simple_attr_read(struct file *file, char __user *buf,
(unsigned long long)attr->get(attr->data));
ret = simple_read_from_buffer(buf, len, ppos, attr->get_buf, size);
- up(&attr->sem);
+ mutex_unlock(&attr->mutex);
return ret;
}
@@ -602,7 +604,7 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf,
if (!attr->set)
return -EACCES;
- down(&attr->sem);
+ mutex_lock(&attr->mutex);
ret = -EFAULT;
size = min(sizeof(attr->set_buf) - 1, len);
if (copy_from_user(attr->set_buf, buf, size))
@@ -613,7 +615,7 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf,
val = simple_strtol(attr->set_buf, NULL, 0);
attr->set(attr->data, val);
out:
- up(&attr->sem);
+ mutex_unlock(&attr->mutex);
return ret;
}
diff --git a/fs/minix/namei.c b/fs/minix/namei.c
index b25bca5bdb57..5b6a4540a05b 100644
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -6,18 +6,6 @@
#include "minix.h"
-static inline void inc_count(struct inode *inode)
-{
- inode->i_nlink++;
- mark_inode_dirty(inode);
-}
-
-static inline void dec_count(struct inode *inode)
-{
- inode->i_nlink--;
- mark_inode_dirty(inode);
-}
-
static int add_nondir(struct dentry *dentry, struct inode *inode)
{
int err = minix_add_link(dentry, inode);
@@ -25,7 +13,7 @@ static int add_nondir(struct dentry *dentry, struct inode *inode)
d_instantiate(dentry, inode);
return 0;
}
- dec_count(inode);
+ inode_dec_link_count(inode);
iput(inode);
return err;
}
@@ -125,7 +113,7 @@ out:
return err;
out_fail:
- dec_count(inode);
+ inode_dec_link_count(inode);
iput(inode);
goto out;
}
@@ -139,7 +127,7 @@ static int minix_link(struct dentry * old_dentry, struct inode * dir,
return -EMLINK;
inode->i_ctime = CURRENT_TIME_SEC;
- inc_count(inode);
+ inode_inc_link_count(inode);
atomic_inc(&inode->i_count);
return add_nondir(dentry, inode);
}
@@ -152,7 +140,7 @@ static int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
if (dir->i_nlink >= minix_sb(dir->i_sb)->s_link_max)
goto out;
- inc_count(dir);
+ inode_inc_link_count(dir);
inode = minix_new_inode(dir, &err);
if (!inode)
@@ -163,7 +151,7 @@ static int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
inode->i_mode |= S_ISGID;
minix_set_inode(inode, 0);
- inc_count(inode);
+ inode_inc_link_count(inode);
err = minix_make_empty(inode, dir);
if (err)
@@ -178,11 +166,11 @@ out:
return err;
out_fail:
- dec_count(inode);
- dec_count(inode);
+ inode_dec_link_count(inode);
+ inode_dec_link_count(inode);
iput(inode);
out_dir:
- dec_count(dir);
+ inode_dec_link_count(dir);
goto out;
}
@@ -202,7 +190,7 @@ static int minix_unlink(struct inode * dir, struct dentry *dentry)
goto end_unlink;
inode->i_ctime = dir->i_ctime;
- dec_count(inode);
+ inode_dec_link_count(inode);
end_unlink:
return err;
}
@@ -215,8 +203,8 @@ static int minix_rmdir(struct inode * dir, struct dentry *dentry)
if (minix_empty_dir(inode)) {
err = minix_unlink(dir, dentry);
if (!err) {
- dec_count(dir);
- dec_count(inode);
+ inode_dec_link_count(dir);
+ inode_dec_link_count(inode);
}
}
return err;
@@ -257,34 +245,34 @@ static int minix_rename(struct inode * old_dir, struct dentry *old_dentry,
new_de = minix_find_entry(new_dentry, &new_page);
if (!new_de)
goto out_dir;
- inc_count(old_inode);
+ inode_inc_link_count(old_inode);
minix_set_link(new_de, new_page, old_inode);
new_inode->i_ctime = CURRENT_TIME_SEC;
if (dir_de)
new_inode->i_nlink--;
- dec_count(new_inode);
+ inode_dec_link_count(new_inode);
} else {
if (dir_de) {
err = -EMLINK;
if (new_dir->i_nlink >= info->s_link_max)
goto out_dir;
}
- inc_count(old_inode);
+ inode_inc_link_count(old_inode);
err = minix_add_link(new_dentry, old_inode);
if (err) {
- dec_count(old_inode);
+ inode_dec_link_count(old_inode);
goto out_dir;
}
if (dir_de)
- inc_count(new_dir);
+ inode_inc_link_count(new_dir);
}
minix_delete_entry(old_de, old_page);
- dec_count(old_inode);
+ inode_dec_link_count(old_inode);
if (dir_de) {
minix_set_link(dir_de, dir_page, new_dir);
- dec_count(old_dir);
+ inode_dec_link_count(old_dir);
}
return 0;
diff --git a/fs/namei.c b/fs/namei.c
index 8dc2b038d5d9..c72b940797fc 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -104,7 +104,7 @@
*/
/*
* [Sep 2001 AV] Single-semaphore locking scheme (kudos to David Holland)
- * implemented. Let's see if raised priority of ->s_vfs_rename_sem gives
+ * implemented. Let's see if raised priority of ->s_vfs_rename_mutex gives
* any extra contention...
*/
@@ -1422,7 +1422,7 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
return NULL;
}
- down(&p1->d_inode->i_sb->s_vfs_rename_sem);
+ mutex_lock(&p1->d_inode->i_sb->s_vfs_rename_mutex);
for (p = p1; p->d_parent != p; p = p->d_parent) {
if (p->d_parent == p2) {
@@ -1450,7 +1450,7 @@ void unlock_rename(struct dentry *p1, struct dentry *p2)
mutex_unlock(&p1->d_inode->i_mutex);
if (p1 != p2) {
mutex_unlock(&p2->d_inode->i_mutex);
- up(&p1->d_inode->i_sb->s_vfs_rename_sem);
+ mutex_unlock(&p1->d_inode->i_sb->s_vfs_rename_mutex);
}
}
@@ -2277,17 +2277,17 @@ asmlinkage long sys_link(const char __user *oldname, const char __user *newname)
* a) we can get into loop creation. Check is done in is_subdir().
* b) race potential - two innocent renames can create a loop together.
* That's where 4.4 screws up. Current fix: serialization on
- * sb->s_vfs_rename_sem. We might be more accurate, but that's another
+ * sb->s_vfs_rename_mutex. We might be more accurate, but that's another
* story.
* c) we have to lock _three_ objects - parents and victim (if it exists).
* And that - after we got ->i_mutex on parents (until then we don't know
* whether the target exists). Solution: try to be smart with locking
* order for inodes. We rely on the fact that tree topology may change
- * only under ->s_vfs_rename_sem _and_ that parent of the object we
+ * only under ->s_vfs_rename_mutex _and_ that parent of the object we
* move will be locked. Thus we can rank directories by the tree
* (ancestors first) and rank all non-directories after them.
* That works since everybody except rename does "lock parent, lookup,
- * lock child" and rename is under ->s_vfs_rename_sem.
+ * lock child" and rename is under ->s_vfs_rename_mutex.
* HOWEVER, it relies on the assumption that any object with ->lookup()
* has no more than 1 dentry. If "hybrid" objects will ever appear,
* we'd better make sure that there's no link(2) for them.
diff --git a/fs/ncpfs/file.c b/fs/ncpfs/file.c
index 973b444d6914..ebdad8f6398f 100644
--- a/fs/ncpfs/file.c
+++ b/fs/ncpfs/file.c
@@ -46,7 +46,7 @@ int ncp_make_open(struct inode *inode, int right)
NCP_FINFO(inode)->volNumber,
NCP_FINFO(inode)->dirEntNum);
error = -EACCES;
- down(&NCP_FINFO(inode)->open_sem);
+ mutex_lock(&NCP_FINFO(inode)->open_mutex);
if (!atomic_read(&NCP_FINFO(inode)->opened)) {
struct ncp_entry_info finfo;
int result;
@@ -93,7 +93,7 @@ int ncp_make_open(struct inode *inode, int right)
}
out_unlock:
- up(&NCP_FINFO(inode)->open_sem);
+ mutex_unlock(&NCP_FINFO(inode)->open_mutex);
out:
return error;
}
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index d277a58bd128..0b521d3d97ce 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -63,7 +63,7 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
SLAB_CTOR_CONSTRUCTOR) {
- init_MUTEX(&ei->open_sem);
+ mutex_init(&ei->open_mutex);
inode_init_once(&ei->vfs_inode);
}
}
@@ -520,7 +520,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
}
/* server->lock = 0; */
- init_MUTEX(&server->sem);
+ mutex_init(&server->mutex);
server->packet = NULL;
/* server->buffer_size = 0; */
/* server->conn_status = 0; */
@@ -557,7 +557,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
server->dentry_ttl = 0; /* no caching */
INIT_LIST_HEAD(&server->tx.requests);
- init_MUTEX(&server->rcv.creq_sem);
+ mutex_init(&server->rcv.creq_mutex);
server->tx.creq = NULL;
server->rcv.creq = NULL;
server->data_ready = sock->sk->sk_data_ready;
diff --git a/fs/ncpfs/ncplib_kernel.c b/fs/ncpfs/ncplib_kernel.c
index c755e1848a42..d9ebf6439f59 100644
--- a/fs/ncpfs/ncplib_kernel.c
+++ b/fs/ncpfs/ncplib_kernel.c
@@ -291,7 +291,7 @@ ncp_make_closed(struct inode *inode)
int err;
err = 0;
- down(&NCP_FINFO(inode)->open_sem);
+ mutex_lock(&NCP_FINFO(inode)->open_mutex);
if (atomic_read(&NCP_FINFO(inode)->opened) == 1) {
atomic_set(&NCP_FINFO(inode)->opened, 0);
err = ncp_close_file(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle);
@@ -301,7 +301,7 @@ ncp_make_closed(struct inode *inode)
NCP_FINFO(inode)->volNumber,
NCP_FINFO(inode)->dirEntNum, err);
}
- up(&NCP_FINFO(inode)->open_sem);
+ mutex_unlock(&NCP_FINFO(inode)->open_mutex);
return err;
}
diff --git a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c
index 6593a5ca88ba..8783eb7ec641 100644
--- a/fs/ncpfs/sock.c
+++ b/fs/ncpfs/sock.c
@@ -171,9 +171,9 @@ static inline void __ncp_abort_request(struct ncp_server *server, struct ncp_req
static inline void ncp_abort_request(struct ncp_server *server, struct ncp_request_reply *req, int err)
{
- down(&server->rcv.creq_sem);
+ mutex_lock(&server->rcv.creq_mutex);
__ncp_abort_request(server, req, err);
- up(&server->rcv.creq_sem);
+ mutex_unlock(&server->rcv.creq_mutex);
}
static inline void __ncptcp_abort(struct ncp_server *server)
@@ -303,20 +303,20 @@ static inline void __ncp_start_request(struct ncp_server *server, struct ncp_req
static int ncp_add_request(struct ncp_server *server, struct ncp_request_reply *req)
{
- down(&server->rcv.creq_sem);
+ mutex_lock(&server->rcv.creq_mutex);
if (!ncp_conn_valid(server)) {
- up(&server->rcv.creq_sem);
+ mutex_unlock(&server->rcv.creq_mutex);
printk(KERN_ERR "ncpfs: tcp: Server died\n");
return -EIO;
}
if (server->tx.creq || server->rcv.creq) {
req->status = RQ_QUEUED;
list_add_tail(&req->req, &server->tx.requests);
- up(&server->rcv.creq_sem);
+ mutex_unlock(&server->rcv.creq_mutex);
return 0;
}
__ncp_start_request(server, req);
- up(&server->rcv.creq_sem);
+ mutex_unlock(&server->rcv.creq_mutex);
return 0;
}
@@ -400,7 +400,7 @@ void ncpdgram_rcv_proc(void *s)
info_server(server, 0, server->unexpected_packet.data, result);
continue;
}
- down(&server->rcv.creq_sem);
+ mutex_lock(&server->rcv.creq_mutex);
req = server->rcv.creq;
if (req && (req->tx_type == NCP_ALLOC_SLOT_REQUEST || (server->sequence == reply.sequence &&
server->connection == get_conn_number(&reply)))) {
@@ -430,11 +430,11 @@ void ncpdgram_rcv_proc(void *s)
server->rcv.creq = NULL;
ncp_finish_request(req, result);
__ncp_next_request(server);
- up(&server->rcv.creq_sem);
+ mutex_unlock(&server->rcv.creq_mutex);
continue;
}
}
- up(&server->rcv.creq_sem);
+ mutex_unlock(&server->rcv.creq_mutex);
}
drop:;
_recv(sock, &reply, sizeof(reply), MSG_DONTWAIT);
@@ -472,9 +472,9 @@ static void __ncpdgram_timeout_proc(struct ncp_server *server)
void ncpdgram_timeout_proc(void *s)
{
struct ncp_server *server = s;
- down(&server->rcv.creq_sem);
+ mutex_lock(&server->rcv.creq_mutex);
__ncpdgram_timeout_proc(server);
- up(&server->rcv.creq_sem);
+ mutex_unlock(&server->rcv.creq_mutex);
}
static inline void ncp_init_req(struct ncp_request_reply* req)
@@ -657,18 +657,18 @@ void ncp_tcp_rcv_proc(void *s)
{
struct ncp_server *server = s;
- down(&server->rcv.creq_sem);
+ mutex_lock(&server->rcv.creq_mutex);
__ncptcp_rcv_proc(server);
- up(&server->rcv.creq_sem);
+ mutex_unlock(&server->rcv.creq_mutex);
}
void ncp_tcp_tx_proc(void *s)
{
struct ncp_server *server = s;
- down(&server->rcv.creq_sem);
+ mutex_lock(&server->rcv.creq_mutex);
__ncptcp_try_send(server);
- up(&server->rcv.creq_sem);
+ mutex_unlock(&server->rcv.creq_mutex);
}
static int do_ncp_rpc_call(struct ncp_server *server, int size,
@@ -833,7 +833,7 @@ int ncp_disconnect(struct ncp_server *server)
void ncp_lock_server(struct ncp_server *server)
{
- down(&server->sem);
+ mutex_lock(&server->mutex);
if (server->lock)
printk(KERN_WARNING "ncp_lock_server: was locked!\n");
server->lock = 1;
@@ -846,5 +846,5 @@ void ncp_unlock_server(struct ncp_server *server)
return;
}
server->lock = 0;
- up(&server->sem);
+ mutex_unlock(&server->mutex);
}
diff --git a/fs/open.c b/fs/open.c
index 70e0230d8e77..1091dadd6c38 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -973,7 +973,7 @@ repeat:
fdt = files_fdtable(files);
fd = find_next_zero_bit(fdt->open_fds->fds_bits,
fdt->max_fdset,
- fdt->next_fd);
+ files->next_fd);
/*
* N.B. For clone tasks sharing a files structure, this test
@@ -998,7 +998,7 @@ repeat:
FD_SET(fd, fdt->open_fds);
FD_CLR(fd, fdt->close_on_exec);
- fdt->next_fd = fd + 1;
+ files->next_fd = fd + 1;
#if 1
/* Sanity check */
if (fdt->fd[fd] != NULL) {
@@ -1019,8 +1019,8 @@ static void __put_unused_fd(struct files_struct *files, unsigned int fd)
{
struct fdtable *fdt = files_fdtable(files);
__FD_CLR(fd, fdt->open_fds);
- if (fd < fdt->next_fd)
- fdt->next_fd = fd;
+ if (fd < files->next_fd)
+ files->next_fd = fd;
}
void fastcall put_unused_fd(unsigned int fd)
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 1d24fead51a6..826c131994c3 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -312,7 +312,7 @@ static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
case BLK_HDR:
info->state = BLK_LIST;
(*pos)++;
- break;
+ /*fallthrough*/
case BLK_LIST:
if (get_blkdev_info(info->blkdev,&idummy,&ndummy)) {
/*
diff --git a/fs/qnx4/file.c b/fs/qnx4/file.c
index b471315e24ef..c33963fded9e 100644
--- a/fs/qnx4/file.c
+++ b/fs/qnx4/file.c
@@ -12,10 +12,7 @@
* 27-06-1998 by Frank Denis : file overwriting.
*/
-#include <linux/config.h>
-#include <linux/types.h>
#include <linux/fs.h>
-#include <linux/time.h>
#include <linux/qnx4_fs.h>
/*
diff --git a/fs/quota.c b/fs/quota.c
index ba9e0bf32f67..d6a2be826e29 100644
--- a/fs/quota.c
+++ b/fs/quota.c
@@ -170,10 +170,10 @@ static void quota_sync_sb(struct super_block *sb, int type)
/* Now when everything is written we can discard the pagecache so
* that userspace sees the changes. We need i_mutex and so we could
- * not do it inside dqonoff_sem. Moreover we need to be carefull
+ * not do it inside dqonoff_mutex. Moreover we need to be carefull
* about races with quotaoff() (that is the reason why we have own
* reference to inode). */
- down(&sb_dqopt(sb)->dqonoff_sem);
+ mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
discard[cnt] = NULL;
if (type != -1 && cnt != type)
@@ -182,7 +182,7 @@ static void quota_sync_sb(struct super_block *sb, int type)
continue;
discard[cnt] = igrab(sb_dqopt(sb)->files[cnt]);
}
- up(&sb_dqopt(sb)->dqonoff_sem);
+ mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (discard[cnt]) {
mutex_lock(&discard[cnt]->i_mutex);
diff --git a/fs/quota_v2.c b/fs/quota_v2.c
index b4199ec3ece4..c519a583e681 100644
--- a/fs/quota_v2.c
+++ b/fs/quota_v2.c
@@ -394,7 +394,7 @@ static int v2_write_dquot(struct dquot *dquot)
ssize_t ret;
struct v2_disk_dqblk ddquot, empty;
- /* dq_off is guarded by dqio_sem */
+ /* dq_off is guarded by dqio_mutex */
if (!dquot->dq_off)
if ((ret = dq_insert_tree(dquot)) < 0) {
printk(KERN_ERR "VFS: Error %zd occurred while creating quota.\n", ret);
diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c
index 2115383dcc8d..6ada2095b9ac 100644
--- a/fs/ramfs/file-mmu.c
+++ b/fs/ramfs/file-mmu.c
@@ -24,18 +24,7 @@
* caches is sufficient.
*/
-#include <linux/module.h>
#include <linux/fs.h>
-#include <linux/pagemap.h>
-#include <linux/highmem.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/smp_lock.h>
-#include <linux/backing-dev.h>
-#include <linux/ramfs.h>
-
-#include <asm/uaccess.h>
-#include "internal.h"
struct address_space_operations ramfs_aops = {
.readpage = simple_readpage,
diff --git a/fs/seq_file.c b/fs/seq_file.c
index 7c40570b71dc..555b9ac04c25 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -37,7 +37,7 @@ int seq_open(struct file *file, struct seq_operations *op)
file->private_data = p;
}
memset(p, 0, sizeof(*p));
- sema_init(&p->sem, 1);
+ mutex_init(&p->lock);
p->op = op;
/*
@@ -71,7 +71,7 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
void *p;
int err = 0;
- down(&m->sem);
+ mutex_lock(&m->lock);
/*
* seq_file->op->..m_start/m_stop/m_next may do special actions
* or optimisations based on the file->f_version, so we want to
@@ -164,7 +164,7 @@ Done:
else
*ppos += copied;
file->f_version = m->version;
- up(&m->sem);
+ mutex_unlock(&m->lock);
return copied;
Enomem:
err = -ENOMEM;
@@ -237,7 +237,7 @@ loff_t seq_lseek(struct file *file, loff_t offset, int origin)
struct seq_file *m = (struct seq_file *)file->private_data;
long long retval = -EINVAL;
- down(&m->sem);
+ mutex_lock(&m->lock);
m->version = file->f_version;
switch (origin) {
case 1:
@@ -260,7 +260,7 @@ loff_t seq_lseek(struct file *file, loff_t offset, int origin)
}
}
}
- up(&m->sem);
+ mutex_unlock(&m->lock);
file->f_version = m->version;
return retval;
}
diff --git a/fs/super.c b/fs/super.c
index e20b5580afd5..425861cb1caa 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -76,9 +76,9 @@ static struct super_block *alloc_super(void)
down_write(&s->s_umount);
s->s_count = S_BIAS;
atomic_set(&s->s_active, 1);
- sema_init(&s->s_vfs_rename_sem,1);
- sema_init(&s->s_dquot.dqio_sem, 1);
- sema_init(&s->s_dquot.dqonoff_sem, 1);
+ mutex_init(&s->s_vfs_rename_mutex);
+ mutex_init(&s->s_dquot.dqio_mutex);
+ mutex_init(&s->s_dquot.dqonoff_mutex);
init_rwsem(&s->s_dquot.dqptr_sem);
init_waitqueue_head(&s->s_wait_unfrozen);
s->s_maxbytes = MAX_NON_LFS;
@@ -693,9 +693,9 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type,
* will protect the lockfs code from trying to start a snapshot
* while we are mounting
*/
- down(&bdev->bd_mount_sem);
+ mutex_lock(&bdev->bd_mount_mutex);
s = sget(fs_type, test_bdev_super, set_bdev_super, bdev);
- up(&bdev->bd_mount_sem);
+ mutex_unlock(&bdev->bd_mount_mutex);
if (IS_ERR(s))
goto out;
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c
index 7f0e4b53085e..b8a73f716fbe 100644
--- a/fs/sysv/namei.c
+++ b/fs/sysv/namei.c
@@ -16,18 +16,6 @@
#include <linux/smp_lock.h>
#include "sysv.h"
-static inline void inc_count(struct inode *inode)
-{
- inode->i_nlink++;
- mark_inode_dirty(inode);
-}
-
-static inline void dec_count(struct inode *inode)
-{
- inode->i_nlink--;
- mark_inode_dirty(inode);
-}
-
static int add_nondir(struct dentry *dentry, struct inode *inode)
{
int err = sysv_add_link(dentry, inode);
@@ -35,7 +23,7 @@ static int add_nondir(struct dentry *dentry, struct inode *inode)
d_instantiate(dentry, inode);
return 0;
}
- dec_count(inode);
+ inode_dec_link_count(inode);
iput(inode);
return err;
}
@@ -124,7 +112,7 @@ out:
return err;
out_fail:
- dec_count(inode);
+ inode_dec_link_count(inode);
iput(inode);
goto out;
}
@@ -138,7 +126,7 @@ static int sysv_link(struct dentry * old_dentry, struct inode * dir,
return -EMLINK;
inode->i_ctime = CURRENT_TIME_SEC;
- inc_count(inode);
+ inode_inc_link_count(inode);
atomic_inc(&inode->i_count);
return add_nondir(dentry, inode);
@@ -151,7 +139,7 @@ static int sysv_mkdir(struct inode * dir, struct dentry *dentry, int mode)
if (dir->i_nlink >= SYSV_SB(dir->i_sb)->s_link_max)
goto out;
- inc_count(dir);
+ inode_inc_link_count(dir);
inode = sysv_new_inode(dir, S_IFDIR|mode);
err = PTR_ERR(inode);
@@ -160,7 +148,7 @@ static int sysv_mkdir(struct inode * dir, struct dentry *dentry, int mode)
sysv_set_inode(inode, 0);
- inc_count(inode);
+ inode_inc_link_count(inode);
err = sysv_make_empty(inode, dir);
if (err)
@@ -175,11 +163,11 @@ out:
return err;
out_fail:
- dec_count(inode);
- dec_count(inode);
+ inode_dec_link_count(inode);
+ inode_dec_link_count(inode);
iput(inode);
out_dir:
- dec_count(dir);
+ inode_dec_link_count(dir);
goto out;
}
@@ -199,7 +187,7 @@ static int sysv_unlink(struct inode * dir, struct dentry * dentry)
goto out;
inode->i_ctime = dir->i_ctime;
- dec_count(inode);
+ inode_dec_link_count(inode);
out:
return err;
}
@@ -213,8 +201,8 @@ static int sysv_rmdir(struct inode * dir, struct dentry * dentry)
err = sysv_unlink(dir, dentry);
if (!err) {
inode->i_size = 0;
- dec_count(inode);
- dec_count(dir);
+ inode_dec_link_count(inode);
+ inode_dec_link_count(dir);
}
}
return err;
@@ -258,34 +246,34 @@ static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry,
new_de = sysv_find_entry(new_dentry, &new_page);
if (!new_de)
goto out_dir;
- inc_count(old_inode);
+ inode_inc_link_count(old_inode);
sysv_set_link(new_de, new_page, old_inode);
new_inode->i_ctime = CURRENT_TIME_SEC;
if (dir_de)
new_inode->i_nlink--;
- dec_count(new_inode);
+ inode_dec_link_count(new_inode);
} else {
if (dir_de) {
err = -EMLINK;
if (new_dir->i_nlink >= SYSV_SB(new_dir->i_sb)->s_link_max)
goto out_dir;
}
- inc_count(old_inode);
+ inode_inc_link_count(old_inode);
err = sysv_add_link(new_dentry, old_inode);
if (err) {
- dec_count(old_inode);
+ inode_dec_link_count(old_inode);
goto out_dir;
}
if (dir_de)
- inc_count(new_dir);
+ inode_inc_link_count(new_dir);
}
sysv_delete_entry(old_de, old_page);
- dec_count(old_inode);
+ inode_dec_link_count(old_inode);
if (dir_de) {
sysv_set_link(dir_de, dir_page, new_dir);
- dec_count(old_dir);
+ inode_dec_link_count(old_dir);
}
return 0;
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c
index 201049ac8a96..ea521f846d97 100644
--- a/fs/udf/balloc.c
+++ b/fs/udf/balloc.c
@@ -152,7 +152,7 @@ static void udf_bitmap_free_blocks(struct super_block * sb,
int bitmap_nr;
unsigned long overflow;
- down(&sbi->s_alloc_sem);
+ mutex_lock(&sbi->s_alloc_mutex);
if (bloc.logicalBlockNum < 0 ||
(bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
{
@@ -211,7 +211,7 @@ error_return:
sb->s_dirt = 1;
if (UDF_SB_LVIDBH(sb))
mark_buffer_dirty(UDF_SB_LVIDBH(sb));
- up(&sbi->s_alloc_sem);
+ mutex_unlock(&sbi->s_alloc_mutex);
return;
}
@@ -226,7 +226,7 @@ static int udf_bitmap_prealloc_blocks(struct super_block * sb,
int nr_groups, bitmap_nr;
struct buffer_head *bh;
- down(&sbi->s_alloc_sem);
+ mutex_lock(&sbi->s_alloc_mutex);
if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
goto out;
@@ -275,7 +275,7 @@ out:
mark_buffer_dirty(UDF_SB_LVIDBH(sb));
}
sb->s_dirt = 1;
- up(&sbi->s_alloc_sem);
+ mutex_unlock(&sbi->s_alloc_mutex);
return alloc_count;
}
@@ -291,7 +291,7 @@ static int udf_bitmap_new_block(struct super_block * sb,
int newblock = 0;
*err = -ENOSPC;
- down(&sbi->s_alloc_sem);
+ mutex_lock(&sbi->s_alloc_mutex);
repeat:
if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
@@ -364,7 +364,7 @@ repeat:
}
if (i >= (nr_groups*2))
{
- up(&sbi->s_alloc_sem);
+ mutex_unlock(&sbi->s_alloc_mutex);
return newblock;
}
if (bit < sb->s_blocksize << 3)
@@ -373,7 +373,7 @@ repeat:
bit = udf_find_next_one_bit(bh->b_data, sb->s_blocksize << 3, group_start << 3);
if (bit >= sb->s_blocksize << 3)
{
- up(&sbi->s_alloc_sem);
+ mutex_unlock(&sbi->s_alloc_mutex);
return 0;
}
@@ -387,7 +387,7 @@ got_block:
*/
if (inode && DQUOT_ALLOC_BLOCK(inode, 1))
{
- up(&sbi->s_alloc_sem);
+ mutex_unlock(&sbi->s_alloc_mutex);
*err = -EDQUOT;
return 0;
}
@@ -410,13 +410,13 @@ got_block:
mark_buffer_dirty(UDF_SB_LVIDBH(sb));
}
sb->s_dirt = 1;
- up(&sbi->s_alloc_sem);
+ mutex_unlock(&sbi->s_alloc_mutex);
*err = 0;
return newblock;
error_return:
*err = -EIO;
- up(&sbi->s_alloc_sem);
+ mutex_unlock(&sbi->s_alloc_mutex);
return 0;
}
@@ -433,7 +433,7 @@ static void udf_table_free_blocks(struct super_block * sb,
int8_t etype;
int i;
- down(&sbi->s_alloc_sem);
+ mutex_lock(&sbi->s_alloc_mutex);
if (bloc.logicalBlockNum < 0 ||
(bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
{
@@ -666,7 +666,7 @@ static void udf_table_free_blocks(struct super_block * sb,
error_return:
sb->s_dirt = 1;
- up(&sbi->s_alloc_sem);
+ mutex_unlock(&sbi->s_alloc_mutex);
return;
}
@@ -692,7 +692,7 @@ static int udf_table_prealloc_blocks(struct super_block * sb,
else
return 0;
- down(&sbi->s_alloc_sem);
+ mutex_lock(&sbi->s_alloc_mutex);
extoffset = sizeof(struct unallocSpaceEntry);
bloc = UDF_I_LOCATION(table);
@@ -736,7 +736,7 @@ static int udf_table_prealloc_blocks(struct super_block * sb,
mark_buffer_dirty(UDF_SB_LVIDBH(sb));
sb->s_dirt = 1;
}
- up(&sbi->s_alloc_sem);
+ mutex_unlock(&sbi->s_alloc_mutex);
return alloc_count;
}
@@ -761,7 +761,7 @@ static int udf_table_new_block(struct super_block * sb,
else
return newblock;
- down(&sbi->s_alloc_sem);
+ mutex_lock(&sbi->s_alloc_mutex);
if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
goal = 0;
@@ -811,7 +811,7 @@ static int udf_table_new_block(struct super_block * sb,
if (spread == 0xFFFFFFFF)
{
udf_release_data(goal_bh);
- up(&sbi->s_alloc_sem);
+ mutex_unlock(&sbi->s_alloc_mutex);
return 0;
}
@@ -827,7 +827,7 @@ static int udf_table_new_block(struct super_block * sb,
if (inode && DQUOT_ALLOC_BLOCK(inode, 1))
{
udf_release_data(goal_bh);
- up(&sbi->s_alloc_sem);
+ mutex_unlock(&sbi->s_alloc_mutex);
*err = -EDQUOT;
return 0;
}
@@ -846,7 +846,7 @@ static int udf_table_new_block(struct super_block * sb,
}
sb->s_dirt = 1;
- up(&sbi->s_alloc_sem);
+ mutex_unlock(&sbi->s_alloc_mutex);
*err = 0;
return newblock;
}
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c
index c9b707b470ca..3873c672cb4c 100644
--- a/fs/udf/ialloc.c
+++ b/fs/udf/ialloc.c
@@ -42,7 +42,7 @@ void udf_free_inode(struct inode * inode)
clear_inode(inode);
- down(&sbi->s_alloc_sem);
+ mutex_lock(&sbi->s_alloc_mutex);
if (sbi->s_lvidbh) {
if (S_ISDIR(inode->i_mode))
UDF_SB_LVIDIU(sb)->numDirs =
@@ -53,7 +53,7 @@ void udf_free_inode(struct inode * inode)
mark_buffer_dirty(sbi->s_lvidbh);
}
- up(&sbi->s_alloc_sem);
+ mutex_unlock(&sbi->s_alloc_mutex);
udf_free_blocks(sb, NULL, UDF_I_LOCATION(inode), 0, 1);
}
@@ -83,7 +83,7 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
return NULL;
}
- down(&sbi->s_alloc_sem);
+ mutex_lock(&sbi->s_alloc_mutex);
UDF_I_UNIQUE(inode) = 0;
UDF_I_LENEXTENTS(inode) = 0;
UDF_I_NEXT_ALLOC_BLOCK(inode) = 0;
@@ -148,7 +148,7 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err)
UDF_I_CRTIME(inode) = current_fs_time(inode->i_sb);
insert_inode_hash(inode);
mark_inode_dirty(inode);
- up(&sbi->s_alloc_sem);
+ mutex_unlock(&sbi->s_alloc_mutex);
if (DQUOT_ALLOC_INODE(inode))
{
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 368d8f81fe54..9303c50c5d55 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -1515,7 +1515,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
sb->s_fs_info = sbi;
memset(UDF_SB(sb), 0x00, sizeof(struct udf_sb_info));
- init_MUTEX(&sbi->s_alloc_sem);
+ mutex_init(&sbi->s_alloc_mutex);
if (!udf_parse_options((char *)options, &uopt))
goto error_out;
diff --git a/fs/ufs/file.c b/fs/ufs/file.c
index ed69d7fe1b5d..62ad481810ef 100644
--- a/fs/ufs/file.c
+++ b/fs/ufs/file.c
@@ -23,18 +23,8 @@
* ext2 fs regular file handling primitives
*/
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
-#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/ufs_fs.h>
-#include <linux/fcntl.h>
-#include <linux/time.h>
-#include <linux/stat.h>
-#include <linux/mm.h>
-#include <linux/pagemap.h>
-#include <linux/smp_lock.h>
/*
* We have mostly NULL's here: the current defaults are ok for
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c
index 2958cde7d3d6..8d5f98a01c74 100644
--- a/fs/ufs/namei.c
+++ b/fs/ufs/namei.c
@@ -43,18 +43,6 @@
#define UFSD(x)
#endif
-static inline void ufs_inc_count(struct inode *inode)
-{
- inode->i_nlink++;
- mark_inode_dirty(inode);
-}
-
-static inline void ufs_dec_count(struct inode *inode)
-{
- inode->i_nlink--;
- mark_inode_dirty(inode);
-}
-
static inline int ufs_add_nondir(struct dentry *dentry, struct inode *inode)
{
int err = ufs_add_link(dentry, inode);
@@ -62,7 +50,7 @@ static inline int ufs_add_nondir(struct dentry *dentry, struct inode *inode)
d_instantiate(dentry, inode);
return 0;
}
- ufs_dec_count(inode);
+ inode_dec_link_count(inode);
iput(inode);
return err;
}
@@ -173,7 +161,7 @@ out:
return err;
out_fail:
- ufs_dec_count(inode);
+ inode_dec_link_count(inode);
iput(inode);
goto out;
}
@@ -191,7 +179,7 @@ static int ufs_link (struct dentry * old_dentry, struct inode * dir,
}
inode->i_ctime = CURRENT_TIME_SEC;
- ufs_inc_count(inode);
+ inode_inc_link_count(inode);
atomic_inc(&inode->i_count);
error = ufs_add_nondir(dentry, inode);
@@ -208,7 +196,7 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
goto out;
lock_kernel();
- ufs_inc_count(dir);
+ inode_inc_link_count(dir);
inode = ufs_new_inode(dir, S_IFDIR|mode);
err = PTR_ERR(inode);
@@ -218,7 +206,7 @@ static int ufs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
inode->i_op = &ufs_dir_inode_operations;
inode->i_fop = &ufs_dir_operations;
- ufs_inc_count(inode);
+ inode_inc_link_count(inode);
err = ufs_make_empty(inode, dir);
if (err)
@@ -234,11 +222,11 @@ out:
return err;
out_fail:
- ufs_dec_count(inode);
- ufs_dec_count(inode);
+ inode_dec_link_count(inode);
+ inode_dec_link_count(inode);
iput (inode);
out_dir:
- ufs_dec_count(dir);
+ inode_dec_link_count(dir);
unlock_kernel();
goto out;
}
@@ -260,7 +248,7 @@ static int ufs_unlink(struct inode * dir, struct dentry *dentry)
goto out;
inode->i_ctime = dir->i_ctime;
- ufs_dec_count(inode);
+ inode_dec_link_count(inode);
err = 0;
out:
unlock_kernel();
@@ -277,8 +265,8 @@ static int ufs_rmdir (struct inode * dir, struct dentry *dentry)
err = ufs_unlink(dir, dentry);
if (!err) {
inode->i_size = 0;
- ufs_dec_count(inode);
- ufs_dec_count(dir);
+ inode_dec_link_count(inode);
+ inode_dec_link_count(dir);
}
}
unlock_kernel();
@@ -319,35 +307,35 @@ static int ufs_rename (struct inode * old_dir, struct dentry * old_dentry,
new_de = ufs_find_entry (new_dentry, &new_bh);
if (!new_de)
goto out_dir;
- ufs_inc_count(old_inode);
+ inode_inc_link_count(old_inode);
ufs_set_link(new_dir, new_de, new_bh, old_inode);
new_inode->i_ctime = CURRENT_TIME_SEC;
if (dir_de)
new_inode->i_nlink--;
- ufs_dec_count(new_inode);
+ inode_dec_link_count(new_inode);
} else {
if (dir_de) {
err = -EMLINK;
if (new_dir->i_nlink >= UFS_LINK_MAX)
goto out_dir;
}
- ufs_inc_count(old_inode);
+ inode_inc_link_count(old_inode);
err = ufs_add_link(new_dentry, old_inode);
if (err) {
- ufs_dec_count(old_inode);
+ inode_dec_link_count(old_inode);
goto out_dir;
}
if (dir_de)
- ufs_inc_count(new_dir);
+ inode_inc_link_count(new_dir);
}
ufs_delete_entry (old_dir, old_de, old_bh);
- ufs_dec_count(old_inode);
+ inode_dec_link_count(old_inode);
if (dir_de) {
ufs_set_link(old_inode, dir_de, dir_bh, new_dir);
- ufs_dec_count(old_dir);
+ inode_dec_link_count(old_dir);
}
unlock_kernel();
return 0;
diff --git a/fs/xfs/linux-2.6/xfs_stats.c b/fs/xfs/linux-2.6/xfs_stats.c
index 8955720a2c6b..713e6a7505d0 100644
--- a/fs/xfs/linux-2.6/xfs_stats.c
+++ b/fs/xfs/linux-2.6/xfs_stats.c
@@ -62,18 +62,15 @@ xfs_read_xfsstats(
while (j < xstats[i].endpoint) {
val = 0;
/* sum over all cpus */
- for (c = 0; c < NR_CPUS; c++) {
- if (!cpu_possible(c)) continue;
+ for_each_cpu(c)
val += *(((__u32*)&per_cpu(xfsstats, c) + j));
- }
len += sprintf(buffer + len, " %u", val);
j++;
}
buffer[len++] = '\n';
}
/* extra precision counters */
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_possible(i)) continue;
+ for_each_cpu(i) {
xs_xstrat_bytes += per_cpu(xfsstats, i).xs_xstrat_bytes;
xs_write_bytes += per_cpu(xfsstats, i).xs_write_bytes;
xs_read_bytes += per_cpu(xfsstats, i).xs_read_bytes;
diff --git a/fs/xfs/linux-2.6/xfs_sysctl.c b/fs/xfs/linux-2.6/xfs_sysctl.c
index a02564972420..7079cc837210 100644
--- a/fs/xfs/linux-2.6/xfs_sysctl.c
+++ b/fs/xfs/linux-2.6/xfs_sysctl.c
@@ -38,8 +38,7 @@ xfs_stats_clear_proc_handler(
if (!ret && write && *valp) {
printk("XFS Clearing xfsstats\n");
- for (c = 0; c < NR_CPUS; c++) {
- if (!cpu_possible(c)) continue;
+ for_each_cpu(c) {
preempt_disable();
/* save vn_active, it's a universal truth! */
vn_active = per_cpu(xfsstats, c).vn_active;
diff --git a/include/asm-alpha/mmu_context.h b/include/asm-alpha/mmu_context.h
index 6f92482cc96c..0c017fc181c1 100644
--- a/include/asm-alpha/mmu_context.h
+++ b/include/asm-alpha/mmu_context.h
@@ -231,9 +231,8 @@ init_new_context(struct task_struct *tsk, struct mm_struct *mm)
{
int i;
- for (i = 0; i < NR_CPUS; i++)
- if (cpu_online(i))
- mm->context[i] = 0;
+ for_each_online_cpu(i)
+ mm->context[i] = 0;
if (tsk != current)
task_thread_info(tsk)->pcb.ptbr
= ((unsigned long)mm->pgd - IDENT_ADDR) >> PAGE_SHIFT;
diff --git a/include/asm-alpha/topology.h b/include/asm-alpha/topology.h
index eb740e280d9c..420ccde6b916 100644
--- a/include/asm-alpha/topology.h
+++ b/include/asm-alpha/topology.h
@@ -27,8 +27,8 @@ static inline cpumask_t node_to_cpumask(int node)
cpumask_t node_cpu_mask = CPU_MASK_NONE;
int cpu;
- for(cpu = 0; cpu < NR_CPUS; cpu++) {
- if (cpu_online(cpu) && (cpu_to_node(cpu) == node))
+ for_each_online_cpu(cpu) {
+ if (cpu_to_node(cpu) == node)
cpu_set(cpu, node_cpu_mask);
}
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index 400c2b41896e..1a565a9d2fa7 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -7,7 +7,7 @@
#ifdef CONFIG_BUG
#ifndef HAVE_ARCH_BUG
#define BUG() do { \
- printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+ printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \
panic("BUG!"); \
} while (0)
#endif
@@ -19,7 +19,7 @@
#ifndef HAVE_ARCH_WARN_ON
#define WARN_ON(condition) do { \
if (unlikely((condition)!=0)) { \
- printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \
+ printk("BUG: warning at %s:%d/%s()\n", __FILE__, __LINE__, __FUNCTION__); \
dump_stack(); \
} \
} while (0)
diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h
index 9044aeb37828..78cf45547e31 100644
--- a/include/asm-generic/percpu.h
+++ b/include/asm-generic/percpu.h
@@ -19,10 +19,9 @@ extern unsigned long __per_cpu_offset[NR_CPUS];
#define percpu_modcopy(pcpudst, src, size) \
do { \
unsigned int __i; \
- for (__i = 0; __i < NR_CPUS; __i++) \
- if (cpu_possible(__i)) \
- memcpy((pcpudst)+__per_cpu_offset[__i], \
- (src), (size)); \
+ for_each_cpu(__i) \
+ memcpy((pcpudst)+__per_cpu_offset[__i], \
+ (src), (size)); \
} while (0)
#else /* ! SMP */
diff --git a/include/asm-i386/alternative.h b/include/asm-i386/alternative.h
new file mode 100644
index 000000000000..e201decea0c9
--- /dev/null
+++ b/include/asm-i386/alternative.h
@@ -0,0 +1,129 @@
+#ifndef _I386_ALTERNATIVE_H
+#define _I386_ALTERNATIVE_H
+
+#ifdef __KERNEL__
+
+struct alt_instr {
+ u8 *instr; /* original instruction */
+ u8 *replacement;
+ u8 cpuid; /* cpuid bit set for replacement */
+ u8 instrlen; /* length of original instruction */
+ u8 replacementlen; /* length of new instruction, <= instrlen */
+ u8 pad;
+};
+
+extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
+
+struct module;
+extern void alternatives_smp_module_add(struct module *mod, char *name,
+ void *locks, void *locks_end,
+ void *text, void *text_end);
+extern void alternatives_smp_module_del(struct module *mod);
+extern void alternatives_smp_switch(int smp);
+
+#endif
+
+/*
+ * Alternative instructions for different CPU types or capabilities.
+ *
+ * This allows to use optimized instructions even on generic binary
+ * kernels.
+ *
+ * length of oldinstr must be longer or equal the length of newinstr
+ * It can be padded with nops as needed.
+ *
+ * For non barrier like inlines please define new variants
+ * without volatile and memory clobber.
+ */
+#define alternative(oldinstr, newinstr, feature) \
+ asm volatile ("661:\n\t" oldinstr "\n662:\n" \
+ ".section .altinstructions,\"a\"\n" \
+ " .align 4\n" \
+ " .long 661b\n" /* label */ \
+ " .long 663f\n" /* new instruction */ \
+ " .byte %c0\n" /* feature bit */ \
+ " .byte 662b-661b\n" /* sourcelen */ \
+ " .byte 664f-663f\n" /* replacementlen */ \
+ ".previous\n" \
+ ".section .altinstr_replacement,\"ax\"\n" \
+ "663:\n\t" newinstr "\n664:\n" /* replacement */\
+ ".previous" :: "i" (feature) : "memory")
+
+/*
+ * Alternative inline assembly with input.
+ *
+ * Pecularities:
+ * No memory clobber here.
+ * Argument numbers start with 1.
+ * Best is to use constraints that are fixed size (like (%1) ... "r")
+ * If you use variable sized constraints like "m" or "g" in the
+ * replacement maake sure to pad to the worst case length.
+ */
+#define alternative_input(oldinstr, newinstr, feature, input...) \
+ asm volatile ("661:\n\t" oldinstr "\n662:\n" \
+ ".section .altinstructions,\"a\"\n" \
+ " .align 4\n" \
+ " .long 661b\n" /* label */ \
+ " .long 663f\n" /* new instruction */ \
+ " .byte %c0\n" /* feature bit */ \
+ " .byte 662b-661b\n" /* sourcelen */ \
+ " .byte 664f-663f\n" /* replacementlen */ \
+ ".previous\n" \
+ ".section .altinstr_replacement,\"ax\"\n" \
+ "663:\n\t" newinstr "\n664:\n" /* replacement */\
+ ".previous" :: "i" (feature), ##input)
+
+/*
+ * Alternative inline assembly for SMP.
+ *
+ * alternative_smp() takes two versions (SMP first, UP second) and is
+ * for more complex stuff such as spinlocks.
+ *
+ * The LOCK_PREFIX macro defined here replaces the LOCK and
+ * LOCK_PREFIX macros used everywhere in the source tree.
+ *
+ * SMP alternatives use the same data structures as the other
+ * alternatives and the X86_FEATURE_UP flag to indicate the case of a
+ * UP system running a SMP kernel. The existing apply_alternatives()
+ * works fine for patching a SMP kernel for UP.
+ *
+ * The SMP alternative tables can be kept after boot and contain both
+ * UP and SMP versions of the instructions to allow switching back to
+ * SMP at runtime, when hotplugging in a new CPU, which is especially
+ * useful in virtualized environments.
+ *
+ * The very common lock prefix is handled as special case in a
+ * separate table which is a pure address list without replacement ptr
+ * and size information. That keeps the table sizes small.
+ */
+
+#ifdef CONFIG_SMP
+#define alternative_smp(smpinstr, upinstr, args...) \
+ asm volatile ("661:\n\t" smpinstr "\n662:\n" \
+ ".section .smp_altinstructions,\"a\"\n" \
+ " .align 4\n" \
+ " .long 661b\n" /* label */ \
+ " .long 663f\n" /* new instruction */ \
+ " .byte 0x68\n" /* X86_FEATURE_UP */ \
+ " .byte 662b-661b\n" /* sourcelen */ \
+ " .byte 664f-663f\n" /* replacementlen */ \
+ ".previous\n" \
+ ".section .smp_altinstr_replacement,\"awx\"\n" \
+ "663:\n\t" upinstr "\n" /* replacement */ \
+ "664:\n\t.fill 662b-661b,1,0x42\n" /* space for original */ \
+ ".previous" : args)
+
+#define LOCK_PREFIX \
+ ".section .smp_locks,\"a\"\n" \
+ " .align 4\n" \
+ " .long 661f\n" /* address */ \
+ ".previous\n" \
+ "661:\n\tlock; "
+
+#else /* ! CONFIG_SMP */
+#define alternative_smp(smpinstr, upinstr, args...) \
+ asm volatile (upinstr : args)
+#define LOCK_PREFIX ""
+#endif
+
+#endif /* _I386_ALTERNATIVE_H */
diff --git a/include/asm-i386/arch_hooks.h b/include/asm-i386/arch_hooks.h
index 28b96a6fb9fa..238cf4275b96 100644
--- a/include/asm-i386/arch_hooks.h
+++ b/include/asm-i386/arch_hooks.h
@@ -24,4 +24,7 @@ extern void trap_init_hook(void);
extern void time_init_hook(void);
extern void mca_nmi_hook(void);
+extern int setup_early_printk(char *);
+extern void early_printk(const char *fmt, ...) __attribute__((format(printf,1,2)));
+
#endif
diff --git a/include/asm-i386/atomic.h b/include/asm-i386/atomic.h
index de649d3aa2d4..22d80ece95cb 100644
--- a/include/asm-i386/atomic.h
+++ b/include/asm-i386/atomic.h
@@ -10,12 +10,6 @@
* resource counting etc..
*/
-#ifdef CONFIG_SMP
-#define LOCK "lock ; "
-#else
-#define LOCK ""
-#endif
-
/*
* Make sure gcc doesn't try to be clever and move things around
* on us. We need to use _exactly_ the address the user gave us,
@@ -52,7 +46,7 @@ typedef struct { volatile int counter; } atomic_t;
static __inline__ void atomic_add(int i, atomic_t *v)
{
__asm__ __volatile__(
- LOCK "addl %1,%0"
+ LOCK_PREFIX "addl %1,%0"
:"=m" (v->counter)
:"ir" (i), "m" (v->counter));
}
@@ -67,7 +61,7 @@ static __inline__ void atomic_add(int i, atomic_t *v)
static __inline__ void atomic_sub(int i, atomic_t *v)
{
__asm__ __volatile__(
- LOCK "subl %1,%0"
+ LOCK_PREFIX "subl %1,%0"
:"=m" (v->counter)
:"ir" (i), "m" (v->counter));
}
@@ -86,7 +80,7 @@ static __inline__ int atomic_sub_and_test(int i, atomic_t *v)
unsigned char c;
__asm__ __volatile__(
- LOCK "subl %2,%0; sete %1"
+ LOCK_PREFIX "subl %2,%0; sete %1"
:"=m" (v->counter), "=qm" (c)
:"ir" (i), "m" (v->counter) : "memory");
return c;
@@ -101,7 +95,7 @@ static __inline__ int atomic_sub_and_test(int i, atomic_t *v)
static __inline__ void atomic_inc(atomic_t *v)
{
__asm__ __volatile__(
- LOCK "incl %0"
+ LOCK_PREFIX "incl %0"
:"=m" (v->counter)
:"m" (v->counter));
}
@@ -115,7 +109,7 @@ static __inline__ void atomic_inc(atomic_t *v)
static __inline__ void atomic_dec(atomic_t *v)
{
__asm__ __volatile__(
- LOCK "decl %0"
+ LOCK_PREFIX "decl %0"
:"=m" (v->counter)
:"m" (v->counter));
}
@@ -133,7 +127,7 @@ static __inline__ int atomic_dec_and_test(atomic_t *v)
unsigned char c;
__asm__ __volatile__(
- LOCK "decl %0; sete %1"
+ LOCK_PREFIX "decl %0; sete %1"
:"=m" (v->counter), "=qm" (c)
:"m" (v->counter) : "memory");
return c != 0;
@@ -152,7 +146,7 @@ static __inline__ int atomic_inc_and_test(atomic_t *v)
unsigned char c;
__asm__ __volatile__(
- LOCK "incl %0; sete %1"
+ LOCK_PREFIX "incl %0; sete %1"
:"=m" (v->counter), "=qm" (c)
:"m" (v->counter) : "memory");
return c != 0;
@@ -172,7 +166,7 @@ static __inline__ int atomic_add_negative(int i, atomic_t *v)
unsigned char c;
__asm__ __volatile__(
- LOCK "addl %2,%0; sets %1"
+ LOCK_PREFIX "addl %2,%0; sets %1"
:"=m" (v->counter), "=qm" (c)
:"ir" (i), "m" (v->counter) : "memory");
return c;
@@ -195,7 +189,7 @@ static __inline__ int atomic_add_return(int i, atomic_t *v)
/* Modern 486+ processor */
__i = i;
__asm__ __volatile__(
- LOCK "xaddl %0, %1;"
+ LOCK_PREFIX "xaddl %0, %1;"
:"=r"(i)
:"m"(v->counter), "0"(i));
return i + __i;
@@ -231,8 +225,14 @@ static __inline__ int atomic_sub_return(int i, atomic_t *v)
({ \
int c, old; \
c = atomic_read(v); \
- while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+ for (;;) { \
+ if (unlikely(c == (u))) \
+ break; \
+ old = atomic_cmpxchg((v), c, c + (a)); \
+ if (likely(old == c)) \
+ break; \
c = old; \
+ } \
c != (u); \
})
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
@@ -242,11 +242,11 @@ static __inline__ int atomic_sub_return(int i, atomic_t *v)
/* These are x86-specific, used by some header files */
#define atomic_clear_mask(mask, addr) \
-__asm__ __volatile__(LOCK "andl %0,%1" \
+__asm__ __volatile__(LOCK_PREFIX "andl %0,%1" \
: : "r" (~(mask)),"m" (*addr) : "memory")
#define atomic_set_mask(mask, addr) \
-__asm__ __volatile__(LOCK "orl %0,%1" \
+__asm__ __volatile__(LOCK_PREFIX "orl %0,%1" \
: : "r" (mask),"m" (*(addr)) : "memory")
/* Atomic operations are already serializing on x86 */
diff --git a/include/asm-i386/bitops.h b/include/asm-i386/bitops.h
index 88e6ca248cd7..7d20b95edb3b 100644
--- a/include/asm-i386/bitops.h
+++ b/include/asm-i386/bitops.h
@@ -7,6 +7,7 @@
#include <linux/config.h>
#include <linux/compiler.h>
+#include <asm/alternative.h>
/*
* These have to be done with inline assembly: that way the bit-setting
@@ -16,12 +17,6 @@
* bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
*/
-#ifdef CONFIG_SMP
-#define LOCK_PREFIX "lock ; "
-#else
-#define LOCK_PREFIX ""
-#endif
-
#define ADDR (*(volatile long *) addr)
/**
diff --git a/include/asm-i386/cache.h b/include/asm-i386/cache.h
index 615911e5bd24..ca15c9c665cf 100644
--- a/include/asm-i386/cache.h
+++ b/include/asm-i386/cache.h
@@ -10,4 +10,6 @@
#define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+
#endif
diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h
index c4ec2a4d8fdf..5c0b5876b931 100644
--- a/include/asm-i386/cpufeature.h
+++ b/include/asm-i386/cpufeature.h
@@ -70,6 +70,7 @@
#define X86_FEATURE_P3 (3*32+ 6) /* P3 */
#define X86_FEATURE_P4 (3*32+ 7) /* P4 */
#define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */
+#define X86_FEATURE_UP (3*32+ 9) /* smp kernel running on up */
/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
#define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */
diff --git a/include/asm-i386/mach-default/do_timer.h b/include/asm-i386/mach-default/do_timer.h
index 56211414fc95..6312c3e79814 100644
--- a/include/asm-i386/mach-default/do_timer.h
+++ b/include/asm-i386/mach-default/do_timer.h
@@ -18,7 +18,7 @@ static inline void do_timer_interrupt_hook(struct pt_regs *regs)
{
do_timer(regs);
#ifndef CONFIG_SMP
- update_process_times(user_mode(regs));
+ update_process_times(user_mode_vm(regs));
#endif
/*
* In the SMP case we use the local APIC timer interrupt to do the
diff --git a/include/asm-i386/mach-es7000/mach_mpparse.h b/include/asm-i386/mach-es7000/mach_mpparse.h
index 4a0637a3e208..99f66be240be 100644
--- a/include/asm-i386/mach-es7000/mach_mpparse.h
+++ b/include/asm-i386/mach-es7000/mach_mpparse.h
@@ -30,7 +30,8 @@ static inline int mps_oem_check(struct mp_config_table *mpc, char *oem,
return 0;
}
-static inline int es7000_check_dsdt()
+#ifdef CONFIG_ACPI
+static inline int es7000_check_dsdt(void)
{
struct acpi_table_header *header = NULL;
if(!acpi_get_table_header_early(ACPI_DSDT, &header))
@@ -54,6 +55,11 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id)
}
return 0;
}
-
+#else
+static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+ return 0;
+}
+#endif
#endif /* __ASM_MACH_MPPARSE_H */
diff --git a/include/asm-i386/mach-visws/do_timer.h b/include/asm-i386/mach-visws/do_timer.h
index 92d638fc8b11..95568e6ca91c 100644
--- a/include/asm-i386/mach-visws/do_timer.h
+++ b/include/asm-i386/mach-visws/do_timer.h
@@ -11,7 +11,7 @@ static inline void do_timer_interrupt_hook(struct pt_regs *regs)
do_timer(regs);
#ifndef CONFIG_SMP
- update_process_times(user_mode(regs));
+ update_process_times(user_mode_vm(regs));
#endif
/*
* In the SMP case we use the local APIC timer interrupt to do the
diff --git a/include/asm-i386/mach-voyager/do_timer.h b/include/asm-i386/mach-voyager/do_timer.h
index ae510e5d0d78..eaf518098981 100644
--- a/include/asm-i386/mach-voyager/do_timer.h
+++ b/include/asm-i386/mach-voyager/do_timer.h
@@ -5,7 +5,7 @@ static inline void do_timer_interrupt_hook(struct pt_regs *regs)
{
do_timer(regs);
#ifndef CONFIG_SMP
- update_process_times(user_mode(regs));
+ update_process_times(user_mode_vm(regs));
#endif
voyager_timer_interrupt(regs);
diff --git a/include/asm-i386/mpspec.h b/include/asm-i386/mpspec.h
index 64a0b8e6afeb..62113d3bfdc2 100644
--- a/include/asm-i386/mpspec.h
+++ b/include/asm-i386/mpspec.h
@@ -22,7 +22,6 @@ extern int mp_bus_id_to_type [MAX_MP_BUSSES];
extern int mp_irq_entries;
extern struct mpc_config_intsrc mp_irqs [MAX_IRQ_SOURCES];
extern int mpc_default_type;
-extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
extern unsigned long mp_lapic_addr;
extern int pic_mode;
extern int using_apic_timer;
diff --git a/include/asm-i386/mtrr.h b/include/asm-i386/mtrr.h
index 5b6ceda68c5f..64cf937c7e33 100644
--- a/include/asm-i386/mtrr.h
+++ b/include/asm-i386/mtrr.h
@@ -25,6 +25,7 @@
#include <linux/config.h>
#include <linux/ioctl.h>
+#include <linux/errno.h>
#define MTRR_IOCTL_BASE 'M'
diff --git a/include/asm-i386/mutex.h b/include/asm-i386/mutex.h
index 9b2199e829f3..05a538531229 100644
--- a/include/asm-i386/mutex.h
+++ b/include/asm-i386/mutex.h
@@ -9,6 +9,8 @@
#ifndef _ASM_MUTEX_H
#define _ASM_MUTEX_H
+#include "asm/alternative.h"
+
/**
* __mutex_fastpath_lock - try to take the lock by moving the count
* from 1 to a 0 value
@@ -27,7 +29,7 @@ do { \
typecheck_fn(fastcall void (*)(atomic_t *), fail_fn); \
\
__asm__ __volatile__( \
- LOCK " decl (%%eax) \n" \
+ LOCK_PREFIX " decl (%%eax) \n" \
" js 2f \n" \
"1: \n" \
\
@@ -83,7 +85,7 @@ do { \
typecheck_fn(fastcall void (*)(atomic_t *), fail_fn); \
\
__asm__ __volatile__( \
- LOCK " incl (%%eax) \n" \
+ LOCK_PREFIX " incl (%%eax) \n" \
" jle 2f \n" \
"1: \n" \
\
diff --git a/include/asm-i386/pgtable-2level.h b/include/asm-i386/pgtable-2level.h
index 74ef721b534d..27bde973abc7 100644
--- a/include/asm-i386/pgtable-2level.h
+++ b/include/asm-i386/pgtable-2level.h
@@ -61,4 +61,6 @@ static inline int pte_exec_kernel(pte_t pte)
#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_low })
#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
+void vmalloc_sync_all(void);
+
#endif /* _I386_PGTABLE_2LEVEL_H */
diff --git a/include/asm-i386/pgtable-3level.h b/include/asm-i386/pgtable-3level.h
index f1a8b454920a..36a5aa63cbbf 100644
--- a/include/asm-i386/pgtable-3level.h
+++ b/include/asm-i386/pgtable-3level.h
@@ -152,4 +152,6 @@ static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
#define __pmd_free_tlb(tlb, x) do { } while (0)
+#define vmalloc_sync_all() ((void)0)
+
#endif /* _I386_PGTABLE_3LEVEL_H */
diff --git a/include/asm-i386/rwlock.h b/include/asm-i386/rwlock.h
index b57cc7afdf7e..94f00195d543 100644
--- a/include/asm-i386/rwlock.h
+++ b/include/asm-i386/rwlock.h
@@ -21,21 +21,23 @@
#define RW_LOCK_BIAS_STR "0x01000000"
#define __build_read_lock_ptr(rw, helper) \
- asm volatile(LOCK "subl $1,(%0)\n\t" \
- "jns 1f\n" \
- "call " helper "\n\t" \
- "1:\n" \
- ::"a" (rw) : "memory")
+ alternative_smp("lock; subl $1,(%0)\n\t" \
+ "jns 1f\n" \
+ "call " helper "\n\t" \
+ "1:\n", \
+ "subl $1,(%0)\n\t", \
+ :"a" (rw) : "memory")
#define __build_read_lock_const(rw, helper) \
- asm volatile(LOCK "subl $1,%0\n\t" \
- "jns 1f\n" \
- "pushl %%eax\n\t" \
- "leal %0,%%eax\n\t" \
- "call " helper "\n\t" \
- "popl %%eax\n\t" \
- "1:\n" \
- :"=m" (*(volatile int *)rw) : : "memory")
+ alternative_smp("lock; subl $1,%0\n\t" \
+ "jns 1f\n" \
+ "pushl %%eax\n\t" \
+ "leal %0,%%eax\n\t" \
+ "call " helper "\n\t" \
+ "popl %%eax\n\t" \
+ "1:\n", \
+ "subl $1,%0\n\t", \
+ "=m" (*(volatile int *)rw) : : "memory")
#define __build_read_lock(rw, helper) do { \
if (__builtin_constant_p(rw)) \
@@ -45,21 +47,23 @@
} while (0)
#define __build_write_lock_ptr(rw, helper) \
- asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
- "jz 1f\n" \
- "call " helper "\n\t" \
- "1:\n" \
- ::"a" (rw) : "memory")
+ alternative_smp("lock; subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
+ "jz 1f\n" \
+ "call " helper "\n\t" \
+ "1:\n", \
+ "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t", \
+ :"a" (rw) : "memory")
#define __build_write_lock_const(rw, helper) \
- asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",%0\n\t" \
- "jz 1f\n" \
- "pushl %%eax\n\t" \
- "leal %0,%%eax\n\t" \
- "call " helper "\n\t" \
- "popl %%eax\n\t" \
- "1:\n" \
- :"=m" (*(volatile int *)rw) : : "memory")
+ alternative_smp("lock; subl $" RW_LOCK_BIAS_STR ",%0\n\t" \
+ "jz 1f\n" \
+ "pushl %%eax\n\t" \
+ "leal %0,%%eax\n\t" \
+ "call " helper "\n\t" \
+ "popl %%eax\n\t" \
+ "1:\n", \
+ "subl $" RW_LOCK_BIAS_STR ",%0\n\t", \
+ "=m" (*(volatile int *)rw) : : "memory")
#define __build_write_lock(rw, helper) do { \
if (__builtin_constant_p(rw)) \
diff --git a/include/asm-i386/semaphore.h b/include/asm-i386/semaphore.h
index 6a42b2142fd6..f7a0f310c524 100644
--- a/include/asm-i386/semaphore.h
+++ b/include/asm-i386/semaphore.h
@@ -99,7 +99,7 @@ static inline void down(struct semaphore * sem)
might_sleep();
__asm__ __volatile__(
"# atomic down operation\n\t"
- LOCK "decl %0\n\t" /* --sem->count */
+ LOCK_PREFIX "decl %0\n\t" /* --sem->count */
"js 2f\n"
"1:\n"
LOCK_SECTION_START("")
@@ -123,7 +123,7 @@ static inline int down_interruptible(struct semaphore * sem)
might_sleep();
__asm__ __volatile__(
"# atomic interruptible down operation\n\t"
- LOCK "decl %1\n\t" /* --sem->count */
+ LOCK_PREFIX "decl %1\n\t" /* --sem->count */
"js 2f\n\t"
"xorl %0,%0\n"
"1:\n"
@@ -148,7 +148,7 @@ static inline int down_trylock(struct semaphore * sem)
__asm__ __volatile__(
"# atomic interruptible down operation\n\t"
- LOCK "decl %1\n\t" /* --sem->count */
+ LOCK_PREFIX "decl %1\n\t" /* --sem->count */
"js 2f\n\t"
"xorl %0,%0\n"
"1:\n"
@@ -173,7 +173,7 @@ static inline void up(struct semaphore * sem)
{
__asm__ __volatile__(
"# atomic up operation\n\t"
- LOCK "incl %0\n\t" /* ++sem->count */
+ LOCK_PREFIX "incl %0\n\t" /* ++sem->count */
"jle 2f\n"
"1:\n"
LOCK_SECTION_START("")
diff --git a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h
index 23604350cdf4..d76b7693cf1d 100644
--- a/include/asm-i386/spinlock.h
+++ b/include/asm-i386/spinlock.h
@@ -35,31 +35,41 @@
#define __raw_spin_lock_string_flags \
"\n1:\t" \
"lock ; decb %0\n\t" \
- "jns 4f\n\t" \
+ "jns 5f\n" \
"2:\t" \
"testl $0x200, %1\n\t" \
- "jz 3f\n\t" \
- "sti\n\t" \
+ "jz 4f\n\t" \
+ "sti\n" \
"3:\t" \
"rep;nop\n\t" \
"cmpb $0, %0\n\t" \
"jle 3b\n\t" \
"cli\n\t" \
"jmp 1b\n" \
- "4:\n\t"
+ "4:\t" \
+ "rep;nop\n\t" \
+ "cmpb $0, %0\n\t" \
+ "jg 1b\n\t" \
+ "jmp 4b\n" \
+ "5:\n\t"
+
+#define __raw_spin_lock_string_up \
+ "\n\tdecb %0"
static inline void __raw_spin_lock(raw_spinlock_t *lock)
{
- __asm__ __volatile__(
- __raw_spin_lock_string
- :"=m" (lock->slock) : : "memory");
+ alternative_smp(
+ __raw_spin_lock_string,
+ __raw_spin_lock_string_up,
+ "=m" (lock->slock) : : "memory");
}
static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags)
{
- __asm__ __volatile__(
- __raw_spin_lock_string_flags
- :"=m" (lock->slock) : "r" (flags) : "memory");
+ alternative_smp(
+ __raw_spin_lock_string_flags,
+ __raw_spin_lock_string_up,
+ "=m" (lock->slock) : "r" (flags) : "memory");
}
static inline int __raw_spin_trylock(raw_spinlock_t *lock)
@@ -178,12 +188,12 @@ static inline int __raw_write_trylock(raw_rwlock_t *lock)
static inline void __raw_read_unlock(raw_rwlock_t *rw)
{
- asm volatile("lock ; incl %0" :"=m" (rw->lock) : : "memory");
+ asm volatile(LOCK_PREFIX "incl %0" :"=m" (rw->lock) : : "memory");
}
static inline void __raw_write_unlock(raw_rwlock_t *rw)
{
- asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ", %0"
+ asm volatile(LOCK_PREFIX "addl $" RW_LOCK_BIAS_STR ", %0"
: "=m" (rw->lock) : : "memory");
}
diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h
index 399145a247f2..d0d8d7448d88 100644
--- a/include/asm-i386/system.h
+++ b/include/asm-i386/system.h
@@ -352,67 +352,6 @@ static inline unsigned long long __cmpxchg64(volatile void *ptr, unsigned long l
#endif
-#ifdef __KERNEL__
-struct alt_instr {
- __u8 *instr; /* original instruction */
- __u8 *replacement;
- __u8 cpuid; /* cpuid bit set for replacement */
- __u8 instrlen; /* length of original instruction */
- __u8 replacementlen; /* length of new instruction, <= instrlen */
- __u8 pad;
-};
-#endif
-
-/*
- * Alternative instructions for different CPU types or capabilities.
- *
- * This allows to use optimized instructions even on generic binary
- * kernels.
- *
- * length of oldinstr must be longer or equal the length of newinstr
- * It can be padded with nops as needed.
- *
- * For non barrier like inlines please define new variants
- * without volatile and memory clobber.
- */
-#define alternative(oldinstr, newinstr, feature) \
- asm volatile ("661:\n\t" oldinstr "\n662:\n" \
- ".section .altinstructions,\"a\"\n" \
- " .align 4\n" \
- " .long 661b\n" /* label */ \
- " .long 663f\n" /* new instruction */ \
- " .byte %c0\n" /* feature bit */ \
- " .byte 662b-661b\n" /* sourcelen */ \
- " .byte 664f-663f\n" /* replacementlen */ \
- ".previous\n" \
- ".section .altinstr_replacement,\"ax\"\n" \
- "663:\n\t" newinstr "\n664:\n" /* replacement */ \
- ".previous" :: "i" (feature) : "memory")
-
-/*
- * Alternative inline assembly with input.
- *
- * Pecularities:
- * No memory clobber here.
- * Argument numbers start with 1.
- * Best is to use constraints that are fixed size (like (%1) ... "r")
- * If you use variable sized constraints like "m" or "g" in the
- * replacement maake sure to pad to the worst case length.
- */
-#define alternative_input(oldinstr, newinstr, feature, input...) \
- asm volatile ("661:\n\t" oldinstr "\n662:\n" \
- ".section .altinstructions,\"a\"\n" \
- " .align 4\n" \
- " .long 661b\n" /* label */ \
- " .long 663f\n" /* new instruction */ \
- " .byte %c0\n" /* feature bit */ \
- " .byte 662b-661b\n" /* sourcelen */ \
- " .byte 664f-663f\n" /* replacementlen */ \
- ".previous\n" \
- ".section .altinstr_replacement,\"ax\"\n" \
- "663:\n\t" newinstr "\n664:\n" /* replacement */ \
- ".previous" :: "i" (feature), ##input)
-
/*
* Force strict CPU ordering.
* And yes, this is required on UP too when we're talking
@@ -558,5 +497,6 @@ static inline void sched_cacheflush(void)
}
extern unsigned long arch_align_stack(unsigned long sp);
+extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
#endif
diff --git a/include/asm-i386/uaccess.h b/include/asm-i386/uaccess.h
index 3f1337c34208..371457b1ceb6 100644
--- a/include/asm-i386/uaccess.h
+++ b/include/asm-i386/uaccess.h
@@ -197,13 +197,15 @@ extern void __put_user_8(void);
#define put_user(x,ptr) \
({ int __ret_pu; \
+ __typeof__(*(ptr)) __pu_val; \
__chk_user_ptr(ptr); \
+ __pu_val = x; \
switch(sizeof(*(ptr))) { \
- case 1: __put_user_1(x, ptr); break; \
- case 2: __put_user_2(x, ptr); break; \
- case 4: __put_user_4(x, ptr); break; \
- case 8: __put_user_8(x, ptr); break; \
- default:__put_user_X(x, ptr); break; \
+ case 1: __put_user_1(__pu_val, ptr); break; \
+ case 2: __put_user_2(__pu_val, ptr); break; \
+ case 4: __put_user_4(__pu_val, ptr); break; \
+ case 8: __put_user_8(__pu_val, ptr); break; \
+ default:__put_user_X(__pu_val, ptr); break; \
} \
__ret_pu; \
})
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index dc81a55dd94d..d8afd0e3b81a 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -347,9 +347,9 @@ __syscall_return(type,__res); \
type name(type1 arg1) \
{ \
long __res; \
-__asm__ volatile ("int $0x80" \
+__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \
: "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1)) : "memory"); \
+ : "0" (__NR_##name),"ri" ((long)(arg1)) : "memory"); \
__syscall_return(type,__res); \
}
@@ -357,9 +357,10 @@ __syscall_return(type,__res); \
type name(type1 arg1,type2 arg2) \
{ \
long __res; \
-__asm__ volatile ("int $0x80" \
+__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \
: "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)) : "memory"); \
+ : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)) \
+ : "memory"); \
__syscall_return(type,__res); \
}
@@ -367,9 +368,9 @@ __syscall_return(type,__res); \
type name(type1 arg1,type2 arg2,type3 arg3) \
{ \
long __res; \
-__asm__ volatile ("int $0x80" \
+__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \
: "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+ : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \
"d" ((long)(arg3)) : "memory"); \
__syscall_return(type,__res); \
}
@@ -378,9 +379,9 @@ __syscall_return(type,__res); \
type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
{ \
long __res; \
-__asm__ volatile ("int $0x80" \
+__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \
: "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+ : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \
"d" ((long)(arg3)),"S" ((long)(arg4)) : "memory"); \
__syscall_return(type,__res); \
}
@@ -390,10 +391,12 @@ __syscall_return(type,__res); \
type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
{ \
long __res; \
-__asm__ volatile ("int $0x80" \
+__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; movl %1,%%eax ; " \
+ "int $0x80 ; pop %%ebx" \
: "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
- "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)) : "memory"); \
+ : "i" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \
+ "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)) \
+ : "memory"); \
__syscall_return(type,__res); \
}
@@ -402,11 +405,14 @@ __syscall_return(type,__res); \
type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \
{ \
long __res; \
-__asm__ volatile ("push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; int $0x80 ; pop %%ebp" \
+ struct { long __a1; long __a6; } __s = { (long)arg1, (long)arg6 }; \
+__asm__ volatile ("push %%ebp ; push %%ebx ; movl 4(%2),%%ebp ; " \
+ "movl 0(%2),%%ebx ; movl %1,%%eax ; int $0x80 ; " \
+ "pop %%ebx ; pop %%ebp" \
: "=a" (__res) \
- : "i" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
- "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)), \
- "0" ((long)(arg6)) : "memory"); \
+ : "i" (__NR_##name),"0" ((long)(&__s)),"c" ((long)(arg2)), \
+ "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)) \
+ : "memory"); \
__syscall_return(type,__res); \
}
diff --git a/include/asm-ia64/atomic.h b/include/asm-ia64/atomic.h
index d3e0dfa99e1f..569ec7574baf 100644
--- a/include/asm-ia64/atomic.h
+++ b/include/asm-ia64/atomic.h
@@ -95,8 +95,14 @@ ia64_atomic64_sub (__s64 i, atomic64_t *v)
({ \
int c, old; \
c = atomic_read(v); \
- while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+ for (;;) { \
+ if (unlikely(c == (u))) \
+ break; \
+ old = atomic_cmpxchg((v), c, c + (a)); \
+ if (likely(old == c)) \
+ break; \
c = old; \
+ } \
c != (u); \
})
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
diff --git a/include/asm-ia64/cache.h b/include/asm-ia64/cache.h
index 40dd25195d65..f0a104db8f20 100644
--- a/include/asm-ia64/cache.h
+++ b/include/asm-ia64/cache.h
@@ -25,4 +25,6 @@
# define SMP_CACHE_BYTES (1 << 3)
#endif
+#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+
#endif /* _ASM_IA64_CACHE_H */
diff --git a/include/asm-m68k/atomic.h b/include/asm-m68k/atomic.h
index 862e497c2645..732d696d31a6 100644
--- a/include/asm-m68k/atomic.h
+++ b/include/asm-m68k/atomic.h
@@ -175,8 +175,14 @@ static inline void atomic_set_mask(unsigned long mask, unsigned long *v)
({ \
int c, old; \
c = atomic_read(v); \
- while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+ for (;;) { \
+ if (unlikely(c == (u))) \
+ break; \
+ old = atomic_cmpxchg((v), c, c + (a)); \
+ if (likely(old == c)) \
+ break; \
c = old; \
+ } \
c != (u); \
})
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
diff --git a/include/asm-parisc/cache.h b/include/asm-parisc/cache.h
index 93f179f13ce8..ae50f8e12eed 100644
--- a/include/asm-parisc/cache.h
+++ b/include/asm-parisc/cache.h
@@ -29,6 +29,8 @@
#define SMP_CACHE_BYTES L1_CACHE_BYTES
+#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+
extern void flush_data_cache_local(void *); /* flushes local data-cache only */
extern void flush_instruction_cache_local(void *); /* flushes local code-cache only */
#ifdef CONFIG_SMP
diff --git a/include/asm-powerpc/atomic.h b/include/asm-powerpc/atomic.h
index 147a38dcc766..bb3c0ab7e667 100644
--- a/include/asm-powerpc/atomic.h
+++ b/include/asm-powerpc/atomic.h
@@ -8,6 +8,7 @@
typedef struct { volatile int counter; } atomic_t;
#ifdef __KERNEL__
+#include <linux/compiler.h>
#include <asm/synch.h>
#include <asm/asm-compat.h>
@@ -176,20 +177,29 @@ static __inline__ int atomic_dec_return(atomic_t *v)
* Atomically adds @a to @v, so long as it was not @u.
* Returns non-zero if @v was not @u, and zero otherwise.
*/
-#define atomic_add_unless(v, a, u) \
-({ \
- int c, old; \
- c = atomic_read(v); \
- for (;;) { \
- if (unlikely(c == (u))) \
- break; \
- old = atomic_cmpxchg((v), c, c + (a)); \
- if (likely(old == c)) \
- break; \
- c = old; \
- } \
- c != (u); \
-})
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ int t;
+
+ __asm__ __volatile__ (
+ LWSYNC_ON_SMP
+"1: lwarx %0,0,%1 # atomic_add_unless\n\
+ cmpw 0,%0,%3 \n\
+ beq- 2f \n\
+ add %0,%2,%0 \n"
+ PPC405_ERR77(0,%2)
+" stwcx. %0,0,%1 \n\
+ bne- 1b \n"
+ ISYNC_ON_SMP
+" subf %0,%2,%0 \n\
+2:"
+ : "=&r" (t)
+ : "r" (&v->counter), "r" (a), "r" (u)
+ : "cc", "memory");
+
+ return t != u;
+}
+
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
#define atomic_sub_and_test(a, v) (atomic_sub_return((a), (v)) == 0)
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h
index 5638518968c3..fe45f6f3a4be 100644
--- a/include/asm-powerpc/cputable.h
+++ b/include/asm-powerpc/cputable.h
@@ -102,38 +102,40 @@ extern void do_cpu_ftr_fixups(unsigned long offset);
#define CPU_FTR_NEED_COHERENT ASM_CONST(0x0000000000020000)
#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_NODSISRALIGN ASM_CONST(0x0000000000100000)
#ifdef __powerpc64__
/* Add the 64b processor unique features in the top half of the word */
-#define CPU_FTR_SLB ASM_CONST(0x0000000100000000)
-#define CPU_FTR_16M_PAGE ASM_CONST(0x0000000200000000)
-#define CPU_FTR_TLBIEL ASM_CONST(0x0000000400000000)
-#define CPU_FTR_NOEXECUTE ASM_CONST(0x0000000800000000)
-#define CPU_FTR_IABR ASM_CONST(0x0000002000000000)
-#define CPU_FTR_MMCRA ASM_CONST(0x0000004000000000)
+#define CPU_FTR_SLB ASM_CONST(0x0000000100000000)
+#define CPU_FTR_16M_PAGE ASM_CONST(0x0000000200000000)
+#define CPU_FTR_TLBIEL ASM_CONST(0x0000000400000000)
+#define CPU_FTR_NOEXECUTE ASM_CONST(0x0000000800000000)
+#define CPU_FTR_IABR ASM_CONST(0x0000002000000000)
+#define CPU_FTR_MMCRA ASM_CONST(0x0000004000000000)
#define CPU_FTR_CTRL ASM_CONST(0x0000008000000000)
-#define CPU_FTR_SMT ASM_CONST(0x0000010000000000)
-#define CPU_FTR_COHERENT_ICACHE ASM_CONST(0x0000020000000000)
+#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)
#else
/* ensure on 32b processors the flags are available for compiling but
* don't do anything */
-#define CPU_FTR_SLB ASM_CONST(0x0)
-#define CPU_FTR_16M_PAGE ASM_CONST(0x0)
-#define CPU_FTR_TLBIEL ASM_CONST(0x0)
-#define CPU_FTR_NOEXECUTE ASM_CONST(0x0)
-#define CPU_FTR_IABR ASM_CONST(0x0)
-#define CPU_FTR_MMCRA ASM_CONST(0x0)
+#define CPU_FTR_SLB ASM_CONST(0x0)
+#define CPU_FTR_16M_PAGE ASM_CONST(0x0)
+#define CPU_FTR_TLBIEL ASM_CONST(0x0)
+#define CPU_FTR_NOEXECUTE ASM_CONST(0x0)
+#define CPU_FTR_IABR ASM_CONST(0x0)
+#define CPU_FTR_MMCRA ASM_CONST(0x0)
#define CPU_FTR_CTRL ASM_CONST(0x0)
-#define CPU_FTR_SMT ASM_CONST(0x0)
-#define CPU_FTR_COHERENT_ICACHE ASM_CONST(0x0)
+#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
#ifndef __ASSEMBLY__
@@ -318,7 +320,7 @@ enum {
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_MMCRA_SIHV | CPU_FTR_PURR,
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 |
diff --git a/include/asm-powerpc/cputime.h b/include/asm-powerpc/cputime.h
index 6d68ad7e0ea3..a21185d47883 100644
--- a/include/asm-powerpc/cputime.h
+++ b/include/asm-powerpc/cputime.h
@@ -1 +1,203 @@
+/*
+ * Definitions for measuring cputime on powerpc machines.
+ *
+ * Copyright (C) 2006 Paul Mackerras, 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.
+ *
+ * If we have CONFIG_VIRT_CPU_ACCOUNTING, we measure cpu time in
+ * the same units as the timebase. Otherwise we measure cpu time
+ * in jiffies using the generic definitions.
+ */
+
+#ifndef __POWERPC_CPUTIME_H
+#define __POWERPC_CPUTIME_H
+
+#ifndef CONFIG_VIRT_CPU_ACCOUNTING
#include <asm-generic/cputime.h>
+#else
+
+#include <linux/types.h>
+#include <linux/time.h>
+#include <asm/div64.h>
+#include <asm/time.h>
+#include <asm/param.h>
+
+typedef u64 cputime_t;
+typedef u64 cputime64_t;
+
+#define cputime_zero ((cputime_t)0)
+#define cputime_max ((~((cputime_t)0) >> 1) - 1)
+#define cputime_add(__a, __b) ((__a) + (__b))
+#define cputime_sub(__a, __b) ((__a) - (__b))
+#define cputime_div(__a, __n) ((__a) / (__n))
+#define cputime_halve(__a) ((__a) >> 1)
+#define cputime_eq(__a, __b) ((__a) == (__b))
+#define cputime_gt(__a, __b) ((__a) > (__b))
+#define cputime_ge(__a, __b) ((__a) >= (__b))
+#define cputime_lt(__a, __b) ((__a) < (__b))
+#define cputime_le(__a, __b) ((__a) <= (__b))
+
+#define cputime64_zero ((cputime64_t)0)
+#define cputime64_add(__a, __b) ((__a) + (__b))
+#define cputime_to_cputime64(__ct) (__ct)
+
+#ifdef __KERNEL__
+
+/*
+ * Convert cputime <-> jiffies
+ */
+extern u64 __cputime_jiffies_factor;
+
+static inline unsigned long cputime_to_jiffies(const cputime_t ct)
+{
+ return mulhdu(ct, __cputime_jiffies_factor);
+}
+
+static inline cputime_t jiffies_to_cputime(const unsigned long jif)
+{
+ cputime_t ct;
+ unsigned long sec;
+
+ /* have to be a little careful about overflow */
+ ct = jif % HZ;
+ sec = jif / HZ;
+ if (ct) {
+ ct *= tb_ticks_per_sec;
+ do_div(ct, HZ);
+ }
+ if (sec)
+ ct += (cputime_t) sec * tb_ticks_per_sec;
+ return ct;
+}
+
+static inline u64 cputime64_to_jiffies64(const cputime_t ct)
+{
+ return mulhdu(ct, __cputime_jiffies_factor);
+}
+
+/*
+ * Convert cputime <-> milliseconds
+ */
+extern u64 __cputime_msec_factor;
+
+static inline unsigned long cputime_to_msecs(const cputime_t ct)
+{
+ return mulhdu(ct, __cputime_msec_factor);
+}
+
+static inline cputime_t msecs_to_cputime(const unsigned long ms)
+{
+ cputime_t ct;
+ unsigned long sec;
+
+ /* have to be a little careful about overflow */
+ ct = ms % 1000;
+ sec = ms / 1000;
+ if (ct) {
+ ct *= tb_ticks_per_sec;
+ do_div(ct, 1000);
+ }
+ if (sec)
+ ct += (cputime_t) sec * tb_ticks_per_sec;
+ return ct;
+}
+
+/*
+ * Convert cputime <-> seconds
+ */
+extern u64 __cputime_sec_factor;
+
+static inline unsigned long cputime_to_secs(const cputime_t ct)
+{
+ return mulhdu(ct, __cputime_sec_factor);
+}
+
+static inline cputime_t secs_to_cputime(const unsigned long sec)
+{
+ return (cputime_t) sec * tb_ticks_per_sec;
+}
+
+/*
+ * Convert cputime <-> timespec
+ */
+static inline void cputime_to_timespec(const cputime_t ct, struct timespec *p)
+{
+ u64 x = ct;
+ unsigned int frac;
+
+ frac = do_div(x, tb_ticks_per_sec);
+ p->tv_sec = x;
+ x = (u64) frac * 1000000000;
+ do_div(x, tb_ticks_per_sec);
+ p->tv_nsec = x;
+}
+
+static inline cputime_t timespec_to_cputime(const struct timespec *p)
+{
+ cputime_t ct;
+
+ ct = (u64) p->tv_nsec * tb_ticks_per_sec;
+ do_div(ct, 1000000000);
+ return ct + (u64) p->tv_sec * tb_ticks_per_sec;
+}
+
+/*
+ * Convert cputime <-> timeval
+ */
+static inline void cputime_to_timeval(const cputime_t ct, struct timeval *p)
+{
+ u64 x = ct;
+ unsigned int frac;
+
+ frac = do_div(x, tb_ticks_per_sec);
+ p->tv_sec = x;
+ x = (u64) frac * 1000000;
+ do_div(x, tb_ticks_per_sec);
+ p->tv_usec = x;
+}
+
+static inline cputime_t timeval_to_cputime(const struct timeval *p)
+{
+ cputime_t ct;
+
+ ct = (u64) p->tv_usec * tb_ticks_per_sec;
+ do_div(ct, 1000000);
+ return ct + (u64) p->tv_sec * tb_ticks_per_sec;
+}
+
+/*
+ * Convert cputime <-> clock_t (units of 1/USER_HZ seconds)
+ */
+extern u64 __cputime_clockt_factor;
+
+static inline unsigned long cputime_to_clock_t(const cputime_t ct)
+{
+ return mulhdu(ct, __cputime_clockt_factor);
+}
+
+static inline cputime_t clock_t_to_cputime(const unsigned long clk)
+{
+ cputime_t ct;
+ unsigned long sec;
+
+ /* have to be a little careful about overflow */
+ ct = clk % USER_HZ;
+ sec = clk / USER_HZ;
+ if (ct) {
+ ct *= tb_ticks_per_sec;
+ do_div(ct, USER_HZ);
+ }
+ if (sec)
+ ct += (cputime_t) sec * tb_ticks_per_sec;
+ return ct;
+}
+
+#define cputime64_to_clock_t(ct) cputime_to_clock_t((cputime_t)(ct))
+
+#endif /* __KERNEL__ */
+#endif /* CONFIG_VIRT_CPU_ACCOUNTING */
+#endif /* __POWERPC_CPUTIME_H */
diff --git a/include/asm-powerpc/firmware.h b/include/asm-powerpc/firmware.h
index f804b34cf06a..ce3788224ed0 100644
--- a/include/asm-powerpc/firmware.h
+++ b/include/asm-powerpc/firmware.h
@@ -41,6 +41,7 @@
#define FW_FEATURE_MULTITCE (1UL<<19)
#define FW_FEATURE_SPLPAR (1UL<<20)
#define FW_FEATURE_ISERIES (1UL<<21)
+#define FW_FEATURE_LPAR (1UL<<22)
enum {
#ifdef CONFIG_PPC64
@@ -51,10 +52,10 @@ enum {
FW_FEATURE_MIGRATE | FW_FEATURE_PERFMON | FW_FEATURE_CRQ |
FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN |
FW_FEATURE_BULK | FW_FEATURE_XDABR | FW_FEATURE_MULTITCE |
- FW_FEATURE_SPLPAR,
+ FW_FEATURE_SPLPAR | FW_FEATURE_LPAR,
FW_FEATURE_PSERIES_ALWAYS = 0,
- FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES,
- FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES,
+ FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
+ FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
FW_FEATURE_POSSIBLE =
#ifdef CONFIG_PPC_PSERIES
FW_FEATURE_PSERIES_POSSIBLE |
@@ -89,15 +90,6 @@ static inline unsigned long firmware_has_feature(unsigned long feature)
(FW_FEATURE_POSSIBLE & ppc64_firmware_features & feature);
}
-#ifdef CONFIG_PPC_PSERIES
-typedef struct {
- unsigned long val;
- char * name;
-} firmware_feature_t;
-
-extern firmware_feature_t firmware_features_table[];
-#endif
-
extern void system_reset_fwnmi(void);
extern void machine_check_fwnmi(void);
diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h
index 8eb7e857ec4c..51f87d9993b6 100644
--- a/include/asm-powerpc/irq.h
+++ b/include/asm-powerpc/irq.h
@@ -479,6 +479,10 @@ extern int distribute_irqs;
struct irqaction;
struct pt_regs;
+#define __ARCH_HAS_DO_SOFTIRQ
+
+extern void __do_softirq(void);
+
#ifdef CONFIG_IRQSTACKS
/*
* Per-cpu stacks for handling hard and soft interrupts.
@@ -491,8 +495,6 @@ extern void call_do_softirq(struct thread_info *tp);
extern int call___do_IRQ(int irq, struct pt_regs *regs,
struct thread_info *tp);
-#define __ARCH_HAS_DO_SOFTIRQ
-
#else
#define irq_ctx_init()
diff --git a/include/asm-powerpc/iseries/mf.h b/include/asm-powerpc/iseries/mf.h
index 857e5202fc78..eb851a9c9e5c 100644
--- a/include/asm-powerpc/iseries/mf.h
+++ b/include/asm-powerpc/iseries/mf.h
@@ -41,16 +41,11 @@ extern void mf_deallocate_lp_events(HvLpIndex targetLp, HvLpEvent_Type type,
unsigned count, MFCompleteHandler hdlr, void *userToken);
extern void mf_power_off(void);
-extern void mf_reboot(void);
+extern void mf_reboot(char *cmd);
extern void mf_display_src(u32 word);
extern void mf_display_progress(u16 value);
-extern void mf_clear_src(void);
extern void mf_init(void);
-extern int mf_get_rtc(struct rtc_time *tm);
-extern int mf_get_boot_rtc(struct rtc_time *tm);
-extern int mf_set_rtc(struct rtc_time *tm);
-
#endif /* _ASM_POWERPC_ISERIES_MF_H */
diff --git a/include/asm-powerpc/lmb.h b/include/asm-powerpc/lmb.h
index d3546c4c9f46..0c5880f70225 100644
--- a/include/asm-powerpc/lmb.h
+++ b/include/asm-powerpc/lmb.h
@@ -19,8 +19,6 @@
#define MAX_LMB_REGIONS 128
-#define LMB_ALLOC_ANYWHERE 0
-
struct lmb_property {
unsigned long base;
unsigned long size;
@@ -43,20 +41,19 @@ extern struct lmb lmb;
extern void __init lmb_init(void);
extern void __init lmb_analyze(void);
-extern long __init lmb_add(unsigned long, unsigned long);
-extern long __init lmb_reserve(unsigned long, unsigned long);
-extern unsigned long __init lmb_alloc(unsigned long, unsigned long);
-extern unsigned long __init lmb_alloc_base(unsigned long, unsigned long,
- unsigned long);
+extern long __init lmb_add(unsigned long base, unsigned long size);
+extern long __init lmb_reserve(unsigned long base, unsigned long size);
+extern unsigned long __init lmb_alloc(unsigned long size, unsigned long align);
+extern unsigned long __init lmb_alloc_base(unsigned long size,
+ unsigned long align, unsigned long max_addr);
+extern unsigned long __init __lmb_alloc_base(unsigned long size,
+ unsigned long align, unsigned long max_addr);
extern unsigned long __init lmb_phys_mem_size(void);
extern unsigned long __init lmb_end_of_DRAM(void);
-extern unsigned long __init lmb_abs_to_phys(unsigned long);
-extern void __init lmb_enforce_memory_limit(unsigned long);
+extern void __init lmb_enforce_memory_limit(unsigned long memory_limit);
extern void lmb_dump_all(void);
-extern unsigned long io_hole_start;
-
static inline unsigned long
lmb_size_bytes(struct lmb_region *type, unsigned long region_nr)
{
diff --git a/include/asm-powerpc/mmu.h b/include/asm-powerpc/mmu.h
index b0b9a3f8cdc2..31f721994bd8 100644
--- a/include/asm-powerpc/mmu.h
+++ b/include/asm-powerpc/mmu.h
@@ -236,7 +236,6 @@ extern void htab_initialize_secondary(void);
extern void hpte_init_native(void);
extern void hpte_init_lpar(void);
extern void hpte_init_iSeries(void);
-extern void mm_init_ppc64(void);
extern long pSeries_lpar_hpte_insert(unsigned long hpte_group,
unsigned long va, unsigned long prpn,
diff --git a/include/asm-powerpc/paca.h b/include/asm-powerpc/paca.h
index c9add8f1ad94..4465b95ebef0 100644
--- a/include/asm-powerpc/paca.h
+++ b/include/asm-powerpc/paca.h
@@ -54,7 +54,7 @@ struct paca_struct {
#endif /* CONFIG_PPC_ISERIES */
/*
- * MAGIC: the spinlock functions in arch/ppc64/lib/locks.c
+ * MAGIC: the spinlock functions in arch/powerpc/lib/locks.c
* load lock_token and paca_index with a single lwz
* instruction. They must travel together and be properly
* aligned.
@@ -96,6 +96,11 @@ struct paca_struct {
u64 saved_r1; /* r1 save for RTAS calls */
u64 saved_msr; /* MSR saved here by enter_rtas */
u8 proc_enabled; /* irq soft-enable flag */
+
+ /* Stuff for accurate time accounting */
+ u64 user_time; /* accumulated usermode TB ticks */
+ u64 system_time; /* accumulated system TB ticks */
+ u64 startpurr; /* PURR/TB value snapshot */
};
extern struct paca_struct paca[];
diff --git a/include/asm-powerpc/percpu.h b/include/asm-powerpc/percpu.h
index e31922c50e53..464301cd0d03 100644
--- a/include/asm-powerpc/percpu.h
+++ b/include/asm-powerpc/percpu.h
@@ -27,10 +27,9 @@
#define percpu_modcopy(pcpudst, src, size) \
do { \
unsigned int __i; \
- for (__i = 0; __i < NR_CPUS; __i++) \
- if (cpu_possible(__i)) \
- memcpy((pcpudst)+__per_cpu_offset(__i), \
- (src), (size)); \
+ for_each_cpu(__i) \
+ memcpy((pcpudst)+__per_cpu_offset(__i), \
+ (src), (size)); \
} while (0)
extern void setup_per_cpu_areas(void);
diff --git a/include/asm-powerpc/pgtable-4k.h b/include/asm-powerpc/pgtable-4k.h
index 80a7832d2721..b2e18629932a 100644
--- a/include/asm-powerpc/pgtable-4k.h
+++ b/include/asm-powerpc/pgtable-4k.h
@@ -62,9 +62,14 @@
/* shift to put page number into pte */
#define PTE_RPN_SHIFT (17)
-#define __real_pte(e,p) ((real_pte_t)(e))
-#define __rpte_to_pte(r) (r)
-#define __rpte_to_hidx(r,index) (pte_val((r)) >> 12)
+#ifdef STRICT_MM_TYPECHECKS
+#define __real_pte(e,p) ((real_pte_t){(e)})
+#define __rpte_to_pte(r) ((r).pte)
+#else
+#define __real_pte(e,p) (e)
+#define __rpte_to_pte(r) (__pte(r))
+#endif
+#define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >> 12)
#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \
do { \
diff --git a/include/asm-powerpc/pgtable.h b/include/asm-powerpc/pgtable.h
index 185ee15963a1..e9f1f4627e6b 100644
--- a/include/asm-powerpc/pgtable.h
+++ b/include/asm-powerpc/pgtable.h
@@ -188,9 +188,13 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
#define pte_pfn(x) ((unsigned long)((pte_val(x)>>PTE_RPN_SHIFT)))
#define pte_page(x) pfn_to_page(pte_pfn(x))
+#define PMD_BAD_BITS (PTE_TABLE_SIZE-1)
+#define PUD_BAD_BITS (PMD_TABLE_SIZE-1)
+
#define pmd_set(pmdp, pmdval) (pmd_val(*(pmdp)) = (pmdval))
#define pmd_none(pmd) (!pmd_val(pmd))
-#define pmd_bad(pmd) (pmd_val(pmd) == 0)
+#define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \
+ || (pmd_val(pmd) & PMD_BAD_BITS))
#define pmd_present(pmd) (pmd_val(pmd) != 0)
#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0)
#define pmd_page_kernel(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS)
@@ -198,7 +202,8 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
#define pud_set(pudp, pudval) (pud_val(*(pudp)) = (pudval))
#define pud_none(pud) (!pud_val(pud))
-#define pud_bad(pud) ((pud_val(pud)) == 0)
+#define pud_bad(pud) (!is_kernel_addr(pud_val(pud)) \
+ || (pud_val(pud) & PUD_BAD_BITS))
#define pud_present(pud) (pud_val(pud) != 0)
#define pud_clear(pudp) (pud_val(*(pudp)) = 0)
#define pud_page(pud) (pud_val(pud) & ~PUD_MASKED_BITS)
diff --git a/include/asm-powerpc/ppc_asm.h b/include/asm-powerpc/ppc_asm.h
index ab8688d39024..dd1c0a913d5f 100644
--- a/include/asm-powerpc/ppc_asm.h
+++ b/include/asm-powerpc/ppc_asm.h
@@ -15,6 +15,48 @@
#define SZL (BITS_PER_LONG/8)
/*
+ * Stuff for accurate CPU time accounting.
+ * These macros handle transitions between user and system state
+ * in exception entry and exit and accumulate time to the
+ * user_time and system_time fields in the paca.
+ */
+
+#ifndef CONFIG_VIRT_CPU_ACCOUNTING
+#define ACCOUNT_CPU_USER_ENTRY(ra, rb)
+#define ACCOUNT_CPU_USER_EXIT(ra, rb)
+#else
+#define ACCOUNT_CPU_USER_ENTRY(ra, rb) \
+ beq 2f; /* if from kernel mode */ \
+BEGIN_FTR_SECTION; \
+ mfspr ra,SPRN_PURR; /* get processor util. reg */ \
+END_FTR_SECTION_IFSET(CPU_FTR_PURR); \
+BEGIN_FTR_SECTION; \
+ mftb ra; /* or get TB if no PURR */ \
+END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \
+ ld rb,PACA_STARTPURR(r13); \
+ std ra,PACA_STARTPURR(r13); \
+ subf rb,rb,ra; /* subtract start value */ \
+ ld ra,PACA_USER_TIME(r13); \
+ add ra,ra,rb; /* add on to user time */ \
+ std ra,PACA_USER_TIME(r13); \
+2:
+
+#define ACCOUNT_CPU_USER_EXIT(ra, rb) \
+BEGIN_FTR_SECTION; \
+ mfspr ra,SPRN_PURR; /* get processor util. reg */ \
+END_FTR_SECTION_IFSET(CPU_FTR_PURR); \
+BEGIN_FTR_SECTION; \
+ mftb ra; /* or get TB if no PURR */ \
+END_FTR_SECTION_IFCLR(CPU_FTR_PURR); \
+ ld rb,PACA_STARTPURR(r13); \
+ std ra,PACA_STARTPURR(r13); \
+ subf rb,rb,ra; /* subtract start value */ \
+ ld ra,PACA_SYSTEM_TIME(r13); \
+ add ra,ra,rb; /* add on to user time */ \
+ std ra,PACA_SYSTEM_TIME(r13);
+#endif
+
+/*
* Macros for storing registers into and loading registers from
* exception frames.
*/
diff --git a/include/asm-powerpc/processor.h b/include/asm-powerpc/processor.h
index 415fa393b00c..1c64a211cf19 100644
--- a/include/asm-powerpc/processor.h
+++ b/include/asm-powerpc/processor.h
@@ -52,7 +52,6 @@
#ifdef __KERNEL__
#define platform_is_pseries() (_machine == PLATFORM_PSERIES || \
_machine == PLATFORM_PSERIES_LPAR)
-#define platform_is_lpar() (!!(_machine & PLATFORM_LPAR))
#if defined(CONFIG_PPC_MULTIPLATFORM)
extern int _machine;
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index cbd297f44cce..782e13a070a1 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -126,8 +126,14 @@ extern struct device_node *find_all_nodes(void);
/* New style node lookup */
extern struct device_node *of_find_node_by_name(struct device_node *from,
const char *name);
+#define for_each_node_by_name(dn, name) \
+ for (dn = of_find_node_by_name(NULL, name); dn; \
+ dn = of_find_node_by_name(dn, name))
extern struct device_node *of_find_node_by_type(struct device_node *from,
const char *type);
+#define for_each_node_by_type(dn, type) \
+ for (dn = of_find_node_by_type(NULL, type); dn; \
+ dn = of_find_node_by_type(dn, type))
extern struct device_node *of_find_compatible_node(struct device_node *from,
const char *type, const char *compat);
extern struct device_node *of_find_node_by_path(const char *path);
diff --git a/include/asm-powerpc/rwsem.h b/include/asm-powerpc/rwsem.h
index 79bae4933b73..2c2fe9647595 100644
--- a/include/asm-powerpc/rwsem.h
+++ b/include/asm-powerpc/rwsem.h
@@ -4,7 +4,7 @@
#ifdef __KERNEL__
/*
- * include/asm-ppc64/rwsem.h: R/W semaphores for PPC using the stuff
+ * include/asm-powerpc/rwsem.h: R/W semaphores for PPC using the stuff
* in lib/rwsem.c. Adapted largely from include/asm-i386/rwsem.h
* by Paul Mackerras <paulus@samba.org>.
*/
diff --git a/include/asm-powerpc/synch.h b/include/asm-powerpc/synch.h
index c90d9d9aae72..2cda3c38a9fa 100644
--- a/include/asm-powerpc/synch.h
+++ b/include/asm-powerpc/synch.h
@@ -15,7 +15,7 @@
#endif
#ifdef CONFIG_SMP
-#define ISYNC_ON_SMP "\n\tisync"
+#define ISYNC_ON_SMP "\n\tisync\n"
#define LWSYNC_ON_SMP __stringify(LWSYNC) "\n"
#else
#define ISYNC_ON_SMP
diff --git a/include/asm-powerpc/system.h b/include/asm-powerpc/system.h
index d9bf53653b10..65f5a7b2646b 100644
--- a/include/asm-powerpc/system.h
+++ b/include/asm-powerpc/system.h
@@ -171,6 +171,8 @@ extern u32 booke_wdt_period;
/* EBCDIC -> ASCII conversion for [0-9A-Z] on iSeries */
extern unsigned char e2a(unsigned char);
+extern unsigned char* strne2a(unsigned char *dest,
+ const unsigned char *src, size_t n);
struct device_node;
extern void note_scsi_host(struct device_node *, void *);
@@ -424,5 +426,9 @@ static inline void create_function_call(unsigned long addr, void * func)
create_branch(addr, func_addr, BRANCH_SET_LINK);
}
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+extern void account_system_vtime(struct task_struct *);
+#endif
+
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_SYSTEM_H */
diff --git a/include/asm-powerpc/time.h b/include/asm-powerpc/time.h
index baddc9ab57ad..912118db13ae 100644
--- a/include/asm-powerpc/time.h
+++ b/include/asm-powerpc/time.h
@@ -41,6 +41,7 @@ extern time_t last_rtc_update;
extern void generic_calibrate_decr(void);
extern void wakeup_decrementer(void);
+extern void snapshot_timebase(void);
/* Some sane defaults: 125 MHz timebase, 1GHz processor */
extern unsigned long ppc_proc_freq;
@@ -221,5 +222,19 @@ struct cpu_usage {
DECLARE_PER_CPU(struct cpu_usage, cpu_usage_array);
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+extern void account_process_vtime(struct task_struct *tsk);
+#else
+#define account_process_vtime(tsk) do { } while (0)
+#endif
+
+#if defined(CONFIG_VIRT_CPU_ACCOUNTING) && defined(CONFIG_PPC_SPLPAR)
+extern void calculate_steal_time(void);
+extern void snapshot_timebases(void);
+#else
+#define calculate_steal_time() do { } while (0)
+#define snapshot_timebases() do { } while (0)
+#endif
+
#endif /* __KERNEL__ */
#endif /* __PPC64_TIME_H */
diff --git a/include/asm-ppc/harrier.h b/include/asm-ppc/harrier.h
index 36c73ab7e43e..7acd7fc126ec 100644
--- a/include/asm-ppc/harrier.h
+++ b/include/asm-ppc/harrier.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/harrier.h
- *
* Definitions for Motorola MCG Harrier North Bridge & Memory controller
*
* Author: Dale Farnsworth
diff --git a/include/asm-ppc/ibm44x.h b/include/asm-ppc/ibm44x.h
index f835066fb3ca..3acc382cc83f 100644
--- a/include/asm-ppc/ibm44x.h
+++ b/include/asm-ppc/ibm44x.h
@@ -29,7 +29,7 @@
/* TLB entry offset/size used for pinning kernel lowmem */
#define PPC44x_PIN_SHIFT 28
-#define PPC44x_PIN_SIZE (1 << PPC44x_PIN_SHIFT)
+#define PPC_PIN_SIZE (1 << PPC44x_PIN_SHIFT)
/* Lowest TLB slot consumed by the default pinned TLBs */
#define PPC44x_LOW_SLOT 63
diff --git a/include/asm-ppc/ibm4xx.h b/include/asm-ppc/ibm4xx.h
index 6c28ae7807f4..38f99710752b 100644
--- a/include/asm-ppc/ibm4xx.h
+++ b/include/asm-ppc/ibm4xx.h
@@ -51,6 +51,10 @@
#include <platforms/4xx/xilinx_ml300.h>
#endif
+#if defined(CONFIG_XILINX_ML403)
+#include <platforms/4xx/xilinx_ml403.h>
+#endif
+
#ifndef __ASSEMBLY__
#ifdef CONFIG_40x
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
index df9cf6ed189d..b919d8fb7d98 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -575,4 +575,11 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
*/
#define xlate_dev_kmem_ptr(p) p
+/* access ports */
+#define setbits32(_addr, _v) out_be32((_addr), in_be32(_addr) | (_v))
+#define clrbits32(_addr, _v) out_be32((_addr), in_be32(_addr) & ~(_v))
+
+#define setbits16(_addr, _v) out_be16((_addr), in_be16(_addr) | (_v))
+#define clrbits16(_addr, _v) out_be16((_addr), in_be16(_addr) & ~(_v))
+
#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/mpc10x.h b/include/asm-ppc/mpc10x.h
index 77b1e092c206..b30a6a3b5bd2 100644
--- a/include/asm-ppc/mpc10x.h
+++ b/include/asm-ppc/mpc10x.h
@@ -1,6 +1,4 @@
/*
- * arch/ppc/kernel/mpc10x.h
- *
* Common routines for the Motorola SPS MPC106/8240/107 Host bridge/Mem
* ctlr/EPIC/etc.
*
@@ -165,6 +163,7 @@ enum ppc_sys_devices {
MPC10X_DMA1,
MPC10X_UART0,
MPC10X_UART1,
+ NUM_PPC_SYS_DEVS,
};
int mpc10x_bridge_init(struct pci_controller *hose,
diff --git a/include/asm-ppc/mpc52xx.h b/include/asm-ppc/mpc52xx.h
index a055e0756b9d..6167f74635f7 100644
--- a/include/asm-ppc/mpc52xx.h
+++ b/include/asm-ppc/mpc52xx.h
@@ -60,6 +60,7 @@ enum ppc_sys_devices {
MPC52xx_ATA,
MPC52xx_I2C1,
MPC52xx_I2C2,
+ NUM_PPC_SYS_DEVS,
};
diff --git a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h
index 321452695039..6ba69a86b9dd 100644
--- a/include/asm-ppc/mpc8260.h
+++ b/include/asm-ppc/mpc8260.h
@@ -83,6 +83,7 @@ enum ppc_sys_devices {
MPC82xx_CPM_SMC2,
MPC82xx_CPM_USB,
MPC82xx_SEC1,
+ NUM_PPC_SYS_DEVS,
};
#ifndef __ASSEMBLY__
diff --git a/include/asm-ppc/mpc83xx.h b/include/asm-ppc/mpc83xx.h
index 7cdf60fa69b6..3c23fc43bfbc 100644
--- a/include/asm-ppc/mpc83xx.h
+++ b/include/asm-ppc/mpc83xx.h
@@ -108,6 +108,7 @@ enum ppc_sys_devices {
MPC83xx_USB2_DR,
MPC83xx_USB2_MPH,
MPC83xx_MDIO,
+ NUM_PPC_SYS_DEVS,
};
#endif /* CONFIG_83xx */
diff --git a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h
index c8a96aa44fb7..f47002a60edf 100644
--- a/include/asm-ppc/mpc85xx.h
+++ b/include/asm-ppc/mpc85xx.h
@@ -139,6 +139,7 @@ enum ppc_sys_devices {
MPC85xx_eTSEC4,
MPC85xx_IIC2,
MPC85xx_MDIO,
+ NUM_PPC_SYS_DEVS,
};
/* Internal interrupts are all Level Sensitive, and Positive Polarity */
diff --git a/include/asm-ppc/mpc8xx.h b/include/asm-ppc/mpc8xx.h
index 46f159cf589e..3515a7fa6c89 100644
--- a/include/asm-ppc/mpc8xx.h
+++ b/include/asm-ppc/mpc8xx.h
@@ -111,8 +111,11 @@ enum ppc_sys_devices {
MPC8xx_CPM_SMC1,
MPC8xx_CPM_SMC2,
MPC8xx_CPM_USB,
+ NUM_PPC_SYS_DEVS,
};
+#define PPC_PIN_SIZE (24 * 1024 * 1024) /* 24Mbytes of data pinned */
+
#ifndef BOARD_CHIP_NAME
#define BOARD_CHIP_NAME ""
#endif
diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h
index 6d1c39e8a6af..e1c62da12e74 100644
--- a/include/asm-ppc/pgtable.h
+++ b/include/asm-ppc/pgtable.h
@@ -12,6 +12,7 @@
#include <asm/processor.h> /* For TASK_SIZE */
#include <asm/mmu.h>
#include <asm/page.h>
+#include <asm/io.h> /* For sub-arch specific PPC_PIN_SIZE */
struct mm_struct;
extern unsigned long va_to_phys(unsigned long address);
@@ -127,9 +128,8 @@ extern unsigned long ioremap_bot, ioremap_base;
* of RAM. -- Cort
*/
#define VMALLOC_OFFSET (0x1000000) /* 16M */
-#ifdef CONFIG_44x
-#include <asm/ibm44x.h>
-#define VMALLOC_START (((_ALIGN((long)high_memory, PPC44x_PIN_SIZE) + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
+#ifdef PPC_PIN_SIZE
+#define VMALLOC_START (((_ALIGN((long)high_memory, PPC_PIN_SIZE) + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
#else
#define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
#endif
diff --git a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h
index 83d8c77c124d..4b94f7059ebe 100644
--- a/include/asm-ppc/ppc_sys.h
+++ b/include/asm-ppc/ppc_sys.h
@@ -33,6 +33,8 @@
#include <asm/mpc52xx.h>
#elif defined(CONFIG_MPC10X_BRIDGE)
#include <asm/mpc10x.h>
+#elif defined(CONFIG_XILINX_VIRTEX)
+#include <platforms/4xx/virtex.h>
#else
#error "need definition of ppc_sys_devices"
#endif
@@ -44,9 +46,26 @@ struct ppc_sys_spec {
u32 value;
u32 num_devices;
char *ppc_sys_name;
+ u8 config[NUM_PPC_SYS_DEVS];
enum ppc_sys_devices *device_list;
};
+struct platform_notify_dev_map {
+ const char *bus_id;
+ void (*rtn)(struct platform_device * pdev, int idx);
+};
+
+enum platform_device_func {
+ PPC_SYS_FUNC_DUMMY = 0,
+ PPC_SYS_FUNC_ETH = 1,
+ PPC_SYS_FUNC_UART = 2,
+ PPC_SYS_FUNC_HLDC = 3,
+ PPC_SYS_FUNC_USB = 4,
+ PPC_SYS_FUNC_IRDA = 5,
+};
+
+#define PPC_SYS_CONFIG_DISABLED 1
+
/* describes all specific chips and which devices they have on them */
extern struct ppc_sys_spec ppc_sys_specs[];
extern struct ppc_sys_spec *cur_ppc_sys_spec;
@@ -72,5 +91,20 @@ extern void *ppc_sys_get_pdata(enum ppc_sys_devices dev) __init;
/* remove a device from the system */
extern void ppc_sys_device_remove(enum ppc_sys_devices dev);
+/* Function assignment stuff */
+void ppc_sys_device_initfunc(void);
+void ppc_sys_device_setfunc(enum ppc_sys_devices dev,
+ enum platform_device_func func);
+void ppc_sys_device_set_func_all(enum platform_device_func func);
+
+void platform_notify_map(const struct platform_notify_dev_map *map,
+ struct device *dev);
+
+/* Enable / disable stuff */
+void ppc_sys_device_disable(enum ppc_sys_devices dev);
+void ppc_sys_device_enable(enum ppc_sys_devices dev);
+void ppc_sys_device_enable_all(void);
+void ppc_sys_device_disable_all(void);
+
#endif /* __ASM_PPC_SYS_H */
#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/time.h b/include/asm-ppc/time.h
index 321fb75b5f22..c86112323c9f 100644
--- a/include/asm-ppc/time.h
+++ b/include/asm-ppc/time.h
@@ -153,5 +153,10 @@ extern __inline__ unsigned binary_tbl(void) {
({unsigned z; asm ("mulhwu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
unsigned mulhwu_scale_factor(unsigned, unsigned);
+
+#define account_process_vtime(tsk) do { } while (0)
+#define calculate_steal_time() do { } while (0)
+#define snapshot_timebases() do { } while (0)
+
#endif /* __ASM_TIME_H__ */
#endif /* __KERNEL__ */
diff --git a/include/asm-ppc/todc.h b/include/asm-ppc/todc.h
index 84bae7d76814..937c7dbe6e5c 100644
--- a/include/asm-ppc/todc.h
+++ b/include/asm-ppc/todc.h
@@ -1,6 +1,4 @@
/*
- * include/asm-ppc/todc.h
- *
* Definitions for the M48Txx and mc146818 series of Time of day/Real Time
* Clock chips.
*
diff --git a/include/asm-ppc/xparameters.h b/include/asm-ppc/xparameters.h
deleted file mode 100644
index fe4eac629139..000000000000
--- a/include/asm-ppc/xparameters.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * include/asm-ppc/xparameters.h
- *
- * This file includes the correct xparameters.h for the CONFIG'ed board
- *
- * Author: MontaVista Software, Inc.
- * source@mvista.com
- *
- * 2004 (c) MontaVista Software, Inc. This file is licensed under the terms
- * of the GNU General Public License version 2. This program is licensed
- * "as is" without any warranty of any kind, whether express or implied.
- */
-
-#include <linux/config.h>
-
-#if defined(CONFIG_XILINX_ML300)
-#include <platforms/4xx/xparameters/xparameters_ml300.h>
-#endif
diff --git a/include/asm-s390/atomic.h b/include/asm-s390/atomic.h
index be6fefe223d6..de1d9926aa60 100644
--- a/include/asm-s390/atomic.h
+++ b/include/asm-s390/atomic.h
@@ -89,10 +89,15 @@ static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new)
static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
{
int c, old;
-
c = atomic_read(v);
- while (c != u && (old = atomic_cmpxchg(v, c, c + a)) != c)
+ for (;;) {
+ if (unlikely(c == u))
+ break;
+ old = atomic_cmpxchg(v, c, c + a);
+ if (likely(old == c))
+ break;
c = old;
+ }
return c != u;
}
@@ -167,10 +172,15 @@ static __inline__ int atomic64_add_unless(atomic64_t *v,
long long a, long long u)
{
long long c, old;
-
c = atomic64_read(v);
- while (c != u && (old = atomic64_cmpxchg(v, c, c + a)) != c)
+ for (;;) {
+ if (unlikely(c == u))
+ break;
+ old = atomic64_cmpxchg(v, c, c + a);
+ if (likely(old == c))
+ break;
c = old;
+ }
return c != u;
}
diff --git a/include/asm-s390/percpu.h b/include/asm-s390/percpu.h
index 123fcaca295e..e10ed87094f0 100644
--- a/include/asm-s390/percpu.h
+++ b/include/asm-s390/percpu.h
@@ -46,10 +46,9 @@ extern unsigned long __per_cpu_offset[NR_CPUS];
#define percpu_modcopy(pcpudst, src, size) \
do { \
unsigned int __i; \
- for (__i = 0; __i < NR_CPUS; __i++) \
- if (cpu_possible(__i)) \
- memcpy((pcpudst)+__per_cpu_offset[__i], \
- (src), (size)); \
+ for_each_cpu(__i) \
+ memcpy((pcpudst)+__per_cpu_offset[__i], \
+ (src), (size)); \
} while (0)
#else /* ! SMP */
diff --git a/include/asm-sparc64/atomic.h b/include/asm-sparc64/atomic.h
index 25256bdc8aae..468eb48d8142 100644
--- a/include/asm-sparc64/atomic.h
+++ b/include/asm-sparc64/atomic.h
@@ -78,9 +78,15 @@ extern int atomic64_sub_ret(int, atomic64_t *);
({ \
int c, old; \
c = atomic_read(v); \
- while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+ for (;;) { \
+ if (unlikely(c == (u))) \
+ break; \
+ old = atomic_cmpxchg((v), c, c + (a)); \
+ if (likely(old == c)) \
+ break; \
c = old; \
- c != (u); \
+ } \
+ likely(c != (u)); \
})
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
diff --git a/include/asm-sparc64/cache.h b/include/asm-sparc64/cache.h
index f7d35a2ae9b8..e9df17acedde 100644
--- a/include/asm-sparc64/cache.h
+++ b/include/asm-sparc64/cache.h
@@ -13,4 +13,6 @@
#define SMP_CACHE_BYTES_SHIFT 6
#define SMP_CACHE_BYTES (1 << SMP_CACHE_BYTES_SHIFT) /* L2 cache line size. */
+#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+
#endif
diff --git a/include/asm-sparc64/percpu.h b/include/asm-sparc64/percpu.h
index aea4e51e7cd1..82032e159a76 100644
--- a/include/asm-sparc64/percpu.h
+++ b/include/asm-sparc64/percpu.h
@@ -26,10 +26,9 @@ register unsigned long __local_per_cpu_offset asm("g5");
#define percpu_modcopy(pcpudst, src, size) \
do { \
unsigned int __i; \
- for (__i = 0; __i < NR_CPUS; __i++) \
- if (cpu_possible(__i)) \
- memcpy((pcpudst)+__per_cpu_offset(__i), \
- (src), (size)); \
+ for_each_cpu(__i) \
+ memcpy((pcpudst)+__per_cpu_offset(__i), \
+ (src), (size)); \
} while (0)
#else /* ! SMP */
diff --git a/include/asm-um/alternative.h b/include/asm-um/alternative.h
new file mode 100644
index 000000000000..b6434396bd42
--- /dev/null
+++ b/include/asm-um/alternative.h
@@ -0,0 +1,6 @@
+#ifndef __UM_ALTERNATIVE_H
+#define __UM_ALTERNATIVE_H
+
+#include "asm/arch/alternative.h"
+
+#endif
diff --git a/include/asm-x86_64/atomic.h b/include/asm-x86_64/atomic.h
index 4b5cd553e772..cecbf7baa6aa 100644
--- a/include/asm-x86_64/atomic.h
+++ b/include/asm-x86_64/atomic.h
@@ -405,8 +405,14 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t *v)
({ \
int c, old; \
c = atomic_read(v); \
- while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+ for (;;) { \
+ if (unlikely(c == (u))) \
+ break; \
+ old = atomic_cmpxchg((v), c, c + (a)); \
+ if (likely(old == c)) \
+ break; \
c = old; \
+ } \
c != (u); \
})
#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
diff --git a/include/asm-x86_64/cache.h b/include/asm-x86_64/cache.h
index 263f0a211ed7..c8043a16152e 100644
--- a/include/asm-x86_64/cache.h
+++ b/include/asm-x86_64/cache.h
@@ -20,6 +20,8 @@
__attribute__((__section__(".data.page_aligned")))
#endif
+#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+
#endif
#endif
diff --git a/include/asm-x86_64/percpu.h b/include/asm-x86_64/percpu.h
index 29a6b0408f75..4405b4adeaba 100644
--- a/include/asm-x86_64/percpu.h
+++ b/include/asm-x86_64/percpu.h
@@ -26,10 +26,9 @@
#define percpu_modcopy(pcpudst, src, size) \
do { \
unsigned int __i; \
- for (__i = 0; __i < NR_CPUS; __i++) \
- if (cpu_possible(__i)) \
- memcpy((pcpudst)+__per_cpu_offset(__i), \
- (src), (size)); \
+ for_each_cpu(__i) \
+ memcpy((pcpudst)+__per_cpu_offset(__i), \
+ (src), (size)); \
} while (0)
extern void setup_per_cpu_areas(void);
diff --git a/include/linux/cache.h b/include/linux/cache.h
index d22e632f41fb..cc4b3aafad9a 100644
--- a/include/linux/cache.h
+++ b/include/linux/cache.h
@@ -13,9 +13,7 @@
#define SMP_CACHE_BYTES L1_CACHE_BYTES
#endif
-#if defined(CONFIG_X86) || defined(CONFIG_SPARC64) || defined(CONFIG_IA64) || defined(CONFIG_PARISC)
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
-#else
+#ifndef __read_mostly
#define __read_mostly
#endif
diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h
index b68fdf1f3156..3c9b0bc05123 100644
--- a/include/linux/cdrom.h
+++ b/include/linux/cdrom.h
@@ -378,7 +378,6 @@ struct cdrom_generic_command
#define CDC_MEDIA_CHANGED 0x80 /* media changed */
#define CDC_PLAY_AUDIO 0x100 /* audio functions */
#define CDC_RESET 0x200 /* hard reset device */
-#define CDC_IOCTLS 0x400 /* driver has non-standard ioctls */
#define CDC_DRIVE_STATUS 0x800 /* driver implements drive status */
#define CDC_GENERIC_PACKET 0x1000 /* driver implements generic packets */
#define CDC_CD_R 0x2000 /* drive is a CD-R */
@@ -974,9 +973,7 @@ struct cdrom_device_ops {
int (*reset) (struct cdrom_device_info *);
/* play stuff */
int (*audio_ioctl) (struct cdrom_device_info *,unsigned int, void *);
- /* dev-specific */
- int (*dev_ioctl) (struct cdrom_device_info *,
- unsigned int, unsigned long);
+
/* driver specifications */
const int capability; /* capability flags */
int n_minors; /* number of active minor devices */
diff --git a/include/linux/eventpoll.h b/include/linux/eventpoll.h
index 1289f0ec4c00..1e4bdfcf83a2 100644
--- a/include/linux/eventpoll.h
+++ b/include/linux/eventpoll.h
@@ -52,7 +52,12 @@ struct file;
#ifdef CONFIG_EPOLL
/* Used to initialize the epoll bits inside the "struct file" */
-void eventpoll_init_file(struct file *file);
+static inline void eventpoll_init_file(struct file *file)
+{
+ INIT_LIST_HEAD(&file->f_ep_links);
+ spin_lock_init(&file->f_ep_lock);
+}
+
/* Used to release the epoll bits inside the "struct file" */
void eventpoll_release_file(struct file *file);
@@ -85,7 +90,6 @@ static inline void eventpoll_release(struct file *file)
eventpoll_release_file(file);
}
-
#else
static inline void eventpoll_init_file(struct file *file) {}
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index c0272d73ab20..e7239f2f97a1 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -772,9 +772,12 @@ extern unsigned long ext3_count_free (struct buffer_head *, unsigned);
/* inode.c */
-extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int);
-extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
-extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
+int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int);
+struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *);
+struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *);
+int ext3_get_block_handle(handle_t *handle, struct inode *inode,
+ sector_t iblock, struct buffer_head *bh_result, int create,
+ int extend_disksize);
extern void ext3_read_inode (struct inode *);
extern int ext3_write_inode (struct inode *, int);
diff --git a/include/linux/ext3_fs_i.h b/include/linux/ext3_fs_i.h
index e71dd98dbcae..7abf90147180 100644
--- a/include/linux/ext3_fs_i.h
+++ b/include/linux/ext3_fs_i.h
@@ -19,6 +19,7 @@
#include <linux/rwsem.h>
#include <linux/rbtree.h>
#include <linux/seqlock.h>
+#include <linux/mutex.h>
struct ext3_reserve_window {
__u32 _rsv_start; /* First byte reserved */
@@ -122,16 +123,16 @@ struct ext3_inode_info {
__u16 i_extra_isize;
/*
- * truncate_sem is for serialising ext3_truncate() against
+ * truncate_mutex is for serialising ext3_truncate() against
* ext3_getblock(). In the 2.4 ext2 design, great chunks of inode's
* data tree are chopped off during truncate. We can't do that in
* ext3 because whenever we perform intermediate commits during
* truncate, the inode and all the metadata blocks *must* be in a
* consistent state which allows truncation of the orphans to restart
* during recovery. Hence we must fix the get_block-vs-truncate race
- * by other means, so we have truncate_sem.
+ * by other means, so we have truncate_mutex.
*/
- struct semaphore truncate_sem;
+ struct mutex truncate_mutex;
struct inode vfs_inode;
};
diff --git a/include/linux/file.h b/include/linux/file.h
index 9901b850f2e4..9f7c2513866f 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -10,6 +10,7 @@
#include <linux/compiler.h>
#include <linux/spinlock.h>
#include <linux/rcupdate.h>
+#include <linux/types.h>
/*
* The default fd array needs to be at least BITS_PER_LONG,
@@ -17,10 +18,22 @@
*/
#define NR_OPEN_DEFAULT BITS_PER_LONG
+/*
+ * The embedded_fd_set is a small fd_set,
+ * suitable for most tasks (which open <= BITS_PER_LONG files)
+ */
+struct embedded_fd_set {
+ unsigned long fds_bits[1];
+};
+
+/*
+ * More than this number of fds: we use a separately allocated fd_set
+ */
+#define EMBEDDED_FD_SET_SIZE (BITS_PER_BYTE * sizeof(struct embedded_fd_set))
+
struct fdtable {
unsigned int max_fds;
int max_fdset;
- int next_fd;
struct file ** fd; /* current fd array */
fd_set *close_on_exec;
fd_set *open_fds;
@@ -33,13 +46,20 @@ struct fdtable {
* Open file table structure
*/
struct files_struct {
+ /*
+ * read mostly part
+ */
atomic_t count;
struct fdtable *fdt;
struct fdtable fdtab;
- fd_set close_on_exec_init;
- fd_set open_fds_init;
+ /*
+ * written part on a separate cache line in SMP
+ */
+ spinlock_t file_lock ____cacheline_aligned_in_smp;
+ int next_fd;
+ struct embedded_fd_set close_on_exec_init;
+ struct embedded_fd_set open_fds_init;
struct file * fd_array[NR_OPEN_DEFAULT];
- spinlock_t file_lock; /* Protects concurrent writers. Nests inside tsk->alloc_lock */
};
#define files_fdtable(files) (rcu_dereference((files)->fdt))
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 128d0082522c..f9c9dea636d0 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -397,8 +397,8 @@ struct block_device {
dev_t bd_dev; /* not a kdev_t - it's a search key */
struct inode * bd_inode; /* will die */
int bd_openers;
- struct semaphore bd_sem; /* open/close mutex */
- struct semaphore bd_mount_sem; /* mount mutex */
+ struct mutex bd_mutex; /* open/close mutex */
+ struct mutex bd_mount_mutex; /* mount mutex */
struct list_head bd_inodes;
void * bd_holder;
int bd_holders;
@@ -509,7 +509,7 @@ struct inode {
#ifdef CONFIG_INOTIFY
struct list_head inotify_watches; /* watches on this inode */
- struct semaphore inotify_sem; /* protects the watches list */
+ struct mutex inotify_mutex; /* protects the watches list */
#endif
unsigned long i_state;
@@ -847,7 +847,7 @@ struct super_block {
* The next field is for VFS *only*. No filesystems have any business
* even looking at it. You had been warned.
*/
- struct semaphore s_vfs_rename_sem; /* Kludge */
+ struct mutex s_vfs_rename_mutex; /* Kludge */
/* Granuality of c/m/atime in ns.
Cannot be worse than a second */
@@ -1115,6 +1115,18 @@ static inline void mark_inode_dirty_sync(struct inode *inode)
__mark_inode_dirty(inode, I_DIRTY_SYNC);
}
+static inline void inode_inc_link_count(struct inode *inode)
+{
+ inode->i_nlink++;
+ mark_inode_dirty(inode);
+}
+
+static inline void inode_dec_link_count(struct inode *inode)
+{
+ inode->i_nlink--;
+ mark_inode_dirty(inode);
+}
+
extern void touch_atime(struct vfsmount *mnt, struct dentry *dentry);
static inline void file_accessed(struct file *file)
{
@@ -1534,7 +1546,7 @@ extern void destroy_inode(struct inode *);
extern struct inode *new_inode(struct super_block *);
extern int remove_suid(struct dentry *);
extern void remove_dquot_ref(struct super_block *, int, struct list_head *);
-extern struct semaphore iprune_sem;
+extern struct mutex iprune_mutex;
extern void __insert_inode_hash(struct inode *, unsigned long hashval);
extern void remove_inode_hash(struct inode *);
diff --git a/include/linux/generic_serial.h b/include/linux/generic_serial.h
index 0abe9d9a0069..652611a4bdcd 100644
--- a/include/linux/generic_serial.h
+++ b/include/linux/generic_serial.h
@@ -12,6 +12,8 @@
#ifndef GENERIC_SERIAL_H
#define GENERIC_SERIAL_H
+#include <linux/mutex.h>
+
struct real_driver {
void (*disable_tx_interrupts) (void *);
void (*enable_tx_interrupts) (void *);
@@ -34,7 +36,7 @@ struct gs_port {
int xmit_head;
int xmit_tail;
int xmit_cnt;
- struct semaphore port_write_sem;
+ struct mutex port_write_mutex;
int flags;
wait_queue_head_t open_wait;
wait_queue_head_t close_wait;
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index eef5ccdcd731..fd647fde5ec1 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -149,22 +149,16 @@ struct disk_attribute {
({ \
typeof(gendiskp->dkstats->field) res = 0; \
int i; \
- for (i=0; i < NR_CPUS; i++) { \
- if (!cpu_possible(i)) \
- continue; \
+ for_each_cpu(i) \
res += per_cpu_ptr(gendiskp->dkstats, i)->field; \
- } \
res; \
})
static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) {
int i;
- for (i=0; i < NR_CPUS; i++) {
- if (cpu_possible(i)) {
- memset(per_cpu_ptr(gendiskp->dkstats, i), value,
- sizeof (struct disk_stats));
- }
- }
+ for_each_cpu(i)
+ memset(per_cpu_ptr(gendiskp->dkstats, i), value,
+ sizeof (struct disk_stats));
}
#else
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index dcfd2ecccb5d..92146f3b7423 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -7,11 +7,10 @@
#define INIT_FDTABLE \
{ \
.max_fds = NR_OPEN_DEFAULT, \
- .max_fdset = __FD_SETSIZE, \
- .next_fd = 0, \
+ .max_fdset = EMBEDDED_FD_SET_SIZE, \
.fd = &init_files.fd_array[0], \
- .close_on_exec = &init_files.close_on_exec_init, \
- .open_fds = &init_files.open_fds_init, \
+ .close_on_exec = (fd_set *)&init_files.close_on_exec_init, \
+ .open_fds = (fd_set *)&init_files.open_fds_init, \
.rcu = RCU_HEAD_INIT, \
.free_files = NULL, \
.next = NULL, \
@@ -20,9 +19,10 @@
#define INIT_FILES \
{ \
.count = ATOMIC_INIT(1), \
- .file_lock = SPIN_LOCK_UNLOCKED, \
.fdt = &init_files.fdtab, \
.fdtab = INIT_FDTABLE, \
+ .file_lock = SPIN_LOCK_UNLOCKED, \
+ .next_fd = 0, \
.close_on_exec_init = { { 0, } }, \
.open_fds_init = { { 0, } }, \
.fd_array = { NULL, } \
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index 41ee79962bb2..2ccbfb6340ba 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -28,6 +28,7 @@
#include <linux/journal-head.h>
#include <linux/stddef.h>
#include <linux/bit_spinlock.h>
+#include <linux/mutex.h>
#include <asm/semaphore.h>
#endif
@@ -575,7 +576,7 @@ struct transaction_s
* @j_wait_checkpoint: Wait queue to trigger checkpointing
* @j_wait_commit: Wait queue to trigger commit
* @j_wait_updates: Wait queue to wait for updates to complete
- * @j_checkpoint_sem: Semaphore for locking against concurrent checkpoints
+ * @j_checkpoint_mutex: Mutex for locking against concurrent checkpoints
* @j_head: Journal head - identifies the first unused block in the journal
* @j_tail: Journal tail - identifies the oldest still-used block in the
* journal.
@@ -645,7 +646,7 @@ struct journal_s
int j_barrier_count;
/* The barrier lock itself */
- struct semaphore j_barrier;
+ struct mutex j_barrier;
/*
* Transactions: The current running transaction...
@@ -687,7 +688,7 @@ struct journal_s
wait_queue_head_t j_wait_updates;
/* Semaphore for locking against concurrent checkpoints */
- struct semaphore j_checkpoint_sem;
+ struct mutex j_checkpoint_mutex;
/*
* Journal head: identifies the first unused block in the journal.
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 3b507bf05d09..bb6e7ddee2fd 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -91,6 +91,9 @@ extern struct notifier_block *panic_notifier_list;
extern long (*panic_blink)(long time);
NORET_TYPE void panic(const char * fmt, ...)
__attribute__ ((NORET_AND format (printf, 1, 2)));
+extern void oops_enter(void);
+extern void oops_exit(void);
+extern int oops_may_print(void);
fastcall NORET_TYPE void do_exit(long error_code)
ATTRIB_NORET;
NORET_TYPE void complete_and_exit(struct completion *, long)
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index 669756bc20a2..778adc0fa640 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -36,6 +36,7 @@
#include <linux/percpu.h>
#include <linux/spinlock.h>
#include <linux/rcupdate.h>
+#include <linux/mutex.h>
#ifdef CONFIG_KPROBES
#include <asm/kprobes.h>
@@ -152,7 +153,7 @@ struct kretprobe_instance {
};
extern spinlock_t kretprobe_lock;
-extern struct semaphore kprobe_mutex;
+extern struct mutex kprobe_mutex;
extern int arch_prepare_kprobe(struct kprobe *p);
extern void arch_arm_kprobe(struct kprobe *p);
extern void arch_disarm_kprobe(struct kprobe *p);
diff --git a/include/linux/loop.h b/include/linux/loop.h
index f96506782ebe..e76c7611d6cc 100644
--- a/include/linux/loop.h
+++ b/include/linux/loop.h
@@ -17,6 +17,7 @@
#include <linux/bio.h>
#include <linux/blkdev.h>
#include <linux/spinlock.h>
+#include <linux/mutex.h>
/* Possible states of device */
enum {
@@ -60,7 +61,7 @@ struct loop_device {
int lo_state;
struct completion lo_done;
struct completion lo_bh_done;
- struct semaphore lo_ctl_mutex;
+ struct mutex lo_ctl_mutex;
int lo_pending;
request_queue_t *lo_queue;
diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
index 8bcd9450d926..779e6a5744c7 100644
--- a/include/linux/msdos_fs.h
+++ b/include/linux/msdos_fs.h
@@ -184,6 +184,7 @@ struct fat_slot_info {
#include <linux/string.h>
#include <linux/nls.h>
#include <linux/fs.h>
+#include <linux/mutex.h>
struct fat_mount_options {
uid_t fs_uid;
@@ -226,7 +227,7 @@ struct msdos_sb_info {
unsigned long max_cluster; /* maximum cluster number */
unsigned long root_cluster; /* first cluster of the root directory */
unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */
- struct semaphore fat_lock;
+ struct mutex fat_lock;
unsigned int prev_free; /* previously allocated cluster number */
unsigned int free_clusters; /* -1 if undefined */
struct fat_mount_options options;
diff --git a/include/linux/nbd.h b/include/linux/nbd.h
index f95d51fae733..a6ce409ec6fc 100644
--- a/include/linux/nbd.h
+++ b/include/linux/nbd.h
@@ -38,6 +38,7 @@ enum {
#ifdef __KERNEL__
#include <linux/wait.h>
+#include <linux/mutex.h>
/* values for flags field */
#define NBD_READ_ONLY 0x0001
@@ -57,7 +58,7 @@ struct nbd_device {
struct request *active_req;
wait_queue_head_t active_wq;
- struct semaphore tx_lock;
+ struct mutex tx_lock;
struct gendisk *disk;
int blksize;
u64 bytesize;
diff --git a/include/linux/ncp_fs_i.h b/include/linux/ncp_fs_i.h
index 415be1ec6f98..bdb4c8ae6924 100644
--- a/include/linux/ncp_fs_i.h
+++ b/include/linux/ncp_fs_i.h
@@ -19,7 +19,7 @@ struct ncp_inode_info {
__le32 DosDirNum;
__u8 volNumber;
__le32 nwattr;
- struct semaphore open_sem;
+ struct mutex open_mutex;
atomic_t opened;
int access;
int flags;
diff --git a/include/linux/ncp_fs_sb.h b/include/linux/ncp_fs_sb.h
index cf858eb80f0b..b089d9506283 100644
--- a/include/linux/ncp_fs_sb.h
+++ b/include/linux/ncp_fs_sb.h
@@ -11,6 +11,7 @@
#include <linux/types.h>
#include <linux/ncp_mount.h>
#include <linux/net.h>
+#include <linux/mutex.h>
#ifdef __KERNEL__
@@ -51,7 +52,7 @@ struct ncp_server {
receive replies */
int lock; /* To prevent mismatch in protocols. */
- struct semaphore sem;
+ struct mutex mutex;
int current_size; /* for packet preparation */
int has_subfunction;
@@ -96,7 +97,7 @@ struct ncp_server {
struct {
struct work_struct tq; /* STREAM/DGRAM: data/error ready */
struct ncp_request_reply* creq; /* STREAM/DGRAM: awaiting reply from this request */
- struct semaphore creq_sem; /* DGRAM only: lock accesses to rcv.creq */
+ struct mutex creq_mutex; /* DGRAM only: lock accesses to rcv.creq */
unsigned int state; /* STREAM only: receiver state */
struct {
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 5be87ba3b7ac..6df2585c0169 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -188,6 +188,8 @@ extern void device_power_up(void);
extern void device_resume(void);
#ifdef CONFIG_PM
+extern suspend_disk_method_t pm_disk_mode;
+
extern int device_suspend(pm_message_t state);
#define device_set_wakeup_enable(dev,val) \
@@ -215,7 +217,6 @@ static inline int dpm_runtime_suspend(struct device * dev, pm_message_t state)
static inline void dpm_runtime_resume(struct device * dev)
{
-
}
#endif
diff --git a/include/linux/profile.h b/include/linux/profile.h
index 026969a5595c..1f2fea6640a4 100644
--- a/include/linux/profile.h
+++ b/include/linux/profile.h
@@ -14,6 +14,7 @@
struct proc_dir_entry;
struct pt_regs;
+struct notifier_block;
/* init basic kernel profiler */
void __init profile_init(void);
@@ -32,7 +33,6 @@ enum profile_type {
#ifdef CONFIG_PROFILING
-struct notifier_block;
struct task_struct;
struct mm_struct;
diff --git a/include/linux/quota.h b/include/linux/quota.h
index f33aeb22c26a..8dc2d04a103f 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -38,6 +38,7 @@
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/spinlock.h>
+#include <linux/mutex.h>
#define __DQUOT_VERSION__ "dquot_6.5.1"
#define __DQUOT_NUM_VERSION__ 6*10000+5*100+1
@@ -215,7 +216,7 @@ struct dquot {
struct list_head dq_inuse; /* List of all quotas */
struct list_head dq_free; /* Free list element */
struct list_head dq_dirty; /* List of dirty dquots */
- struct semaphore dq_lock; /* dquot IO lock */
+ struct mutex dq_lock; /* dquot IO lock */
atomic_t dq_count; /* Use count */
wait_queue_head_t dq_wait_unused; /* Wait queue for dquot to become unused */
struct super_block *dq_sb; /* superblock this applies to */
@@ -285,8 +286,8 @@ struct quota_format_type {
struct quota_info {
unsigned int flags; /* Flags for diskquotas on this device */
- struct semaphore dqio_sem; /* lock device while I/O in progress */
- struct semaphore dqonoff_sem; /* Serialize quotaon & quotaoff */
+ struct mutex dqio_mutex; /* lock device while I/O in progress */
+ struct mutex dqonoff_mutex; /* Serialize quotaon & quotaoff */
struct rw_semaphore dqptr_sem; /* serialize ops using quota_info struct, pointers from inode to dquots */
struct inode *files[MAXQUOTAS]; /* inodes of quotafiles */
struct mem_dqinfo info[MAXQUOTAS]; /* Information for each quota type */
diff --git a/include/linux/raid/raid1.h b/include/linux/raid/raid1.h
index 9d5494aaac0f..3009c813d83d 100644
--- a/include/linux/raid/raid1.h
+++ b/include/linux/raid/raid1.h
@@ -130,6 +130,6 @@ struct r1bio_s {
* with failure when last write completes (and all failed).
* Record that bi_end_io was called with this flag...
*/
-#define R1BIO_Returned 4
+#define R1BIO_Returned 6
#endif
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index c2ec6c77874e..5673008b61e1 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -113,8 +113,6 @@ struct rcu_data {
DECLARE_PER_CPU(struct rcu_data, rcu_data);
DECLARE_PER_CPU(struct rcu_data, rcu_bh_data);
-extern struct rcu_ctrlblk rcu_ctrlblk;
-extern struct rcu_ctrlblk rcu_bh_ctrlblk;
/*
* Increment the quiescent state counter.
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index 850a974ee505..b95f6eb7254c 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -4,7 +4,7 @@
#include <linux/types.h>
#include <linux/string.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
struct seq_operations;
struct file;
@@ -19,7 +19,7 @@ struct seq_file {
size_t count;
loff_t index;
loff_t version;
- struct semaphore sem;
+ struct mutex lock;
struct seq_operations *op;
void *private;
};
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 12415dd94451..54eac8a39a4c 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -234,14 +234,15 @@ extern struct page * read_swap_cache_async(swp_entry_t, struct vm_area_struct *v
/* linux/mm/swapfile.c */
extern long total_swap_pages;
extern unsigned int nr_swapfiles;
-extern struct swap_info_struct swap_info[];
extern void si_swapinfo(struct sysinfo *);
extern swp_entry_t get_swap_page(void);
-extern swp_entry_t get_swap_page_of_type(int type);
+extern swp_entry_t get_swap_page_of_type(int);
extern int swap_duplicate(swp_entry_t);
extern int valid_swaphandles(swp_entry_t, unsigned long *);
extern void swap_free(swp_entry_t);
extern void free_swap_and_cache(swp_entry_t);
+extern int swap_type_of(dev_t);
+extern unsigned int count_swap_pages(int, int);
extern sector_t map_swap_page(struct swap_info_struct *, pgoff_t);
extern struct swap_info_struct *get_swap_info_struct(unsigned);
extern int can_share_swap_page(struct page *);
diff --git a/include/linux/tty.h b/include/linux/tty.h
index f45cd74e6f24..f13f49afe198 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -24,6 +24,7 @@
#include <linux/tty_driver.h>
#include <linux/tty_ldisc.h>
#include <linux/screen_info.h>
+#include <linux/mutex.h>
#include <asm/system.h>
@@ -231,8 +232,8 @@ struct tty_struct {
int canon_data;
unsigned long canon_head;
unsigned int canon_column;
- struct semaphore atomic_read;
- struct semaphore atomic_write;
+ struct mutex atomic_read_lock;
+ struct mutex atomic_write_lock;
unsigned char *write_buf;
int write_cnt;
spinlock_t read_lock;
@@ -319,8 +320,7 @@ extern void tty_ldisc_put(int);
extern void tty_wakeup(struct tty_struct *tty);
extern void tty_ldisc_flush(struct tty_struct *tty);
-struct semaphore;
-extern struct semaphore tty_sem;
+extern struct mutex tty_mutex;
/* n_tty.c */
extern struct tty_ldisc tty_ldisc_N_TTY;
diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h
index 222faf97d5f9..0c6169fff366 100644
--- a/include/linux/tty_flip.h
+++ b/include/linux/tty_flip.h
@@ -7,14 +7,8 @@ extern int tty_insert_flip_string_flags(struct tty_struct *tty, unsigned char *c
extern int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size);
extern int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size);
-#ifdef INCLUDE_INLINE_FUNCS
-#define _INLINE_ extern
-#else
-#define _INLINE_ static __inline__
-#endif
-
-_INLINE_ int tty_insert_flip_char(struct tty_struct *tty,
- unsigned char ch, char flag)
+static inline int tty_insert_flip_char(struct tty_struct *tty,
+ unsigned char ch, char flag)
{
struct tty_buffer *tb = tty->buf.tail;
if (tb && tb->active && tb->used < tb->size) {
@@ -25,7 +19,7 @@ _INLINE_ int tty_insert_flip_char(struct tty_struct *tty,
return tty_insert_flip_string_flags(tty, &ch, &flag, 1);
}
-_INLINE_ void tty_schedule_flip(struct tty_struct *tty)
+static inline void tty_schedule_flip(struct tty_struct *tty)
{
unsigned long flags;
spin_lock_irqsave(&tty->buf.lock, flags);
diff --git a/include/linux/udf_fs_sb.h b/include/linux/udf_fs_sb.h
index b15ff2e99c91..80ae9ef940dc 100644
--- a/include/linux/udf_fs_sb.h
+++ b/include/linux/udf_fs_sb.h
@@ -13,7 +13,7 @@
#ifndef _UDF_FS_SB_H
#define _UDF_FS_SB_H 1
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
#pragma pack(1)
@@ -111,7 +111,7 @@ struct udf_sb_info
/* VAT inode */
struct inode *s_vat;
- struct semaphore s_alloc_sem;
+ struct mutex s_alloc_mutex;
};
#endif /* _UDF_FS_SB_H */
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index fab5aed8ca31..530ae3f4248c 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -73,6 +73,11 @@ int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc);
int vt_waitactive(int vt);
void change_console(struct vc_data *new_vc);
void reset_vc(struct vc_data *vc);
+#ifdef CONFIG_VT
+int is_console_suspend_safe(void);
+#else
+static inline int is_console_suspend_safe(void) { return 1; }
+#endif
/*
* vc_screen.c shares this temporary buffer with the console write code so that
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index a05cabd0fd10..405f9031af87 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -56,6 +56,7 @@ static void __init handle_initrd(void)
sys_chroot(".");
mount_devfs_fs ();
+ current->flags |= PF_NOFREEZE;
pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
if (pid > 0) {
while (pid != sys_wait4(-1, NULL, 0, NULL))
diff --git a/init/main.c b/init/main.c
index 4c194c47395f..2714e0e7cfec 100644
--- a/init/main.c
+++ b/init/main.c
@@ -325,7 +325,7 @@ static inline void smp_prepare_cpus(unsigned int maxcpus) { }
#else
#ifdef __GENERIC_PER_CPU
-unsigned long __per_cpu_offset[NR_CPUS];
+unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
EXPORT_SYMBOL(__per_cpu_offset);
@@ -333,6 +333,7 @@ static void __init setup_per_cpu_areas(void)
{
unsigned long size, i;
char *ptr;
+ unsigned long nr_possible_cpus = num_possible_cpus();
/* Copy section for each CPU (we discard the original) */
size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES);
@@ -340,12 +341,12 @@ static void __init setup_per_cpu_areas(void)
if (size < PERCPU_ENOUGH_ROOM)
size = PERCPU_ENOUGH_ROOM;
#endif
+ ptr = alloc_bootmem(size * nr_possible_cpus);
- ptr = alloc_bootmem(size * NR_CPUS);
-
- for (i = 0; i < NR_CPUS; i++, ptr += size) {
+ for_each_cpu(i) {
__per_cpu_offset[i] = ptr - __per_cpu_start;
memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
+ ptr += size;
}
}
#endif /* !__GENERIC_PER_CPU */
@@ -438,6 +439,15 @@ void __init parse_early_param(void)
* Activate the first processor.
*/
+static void __init boot_cpu_init(void)
+{
+ int cpu = smp_processor_id();
+ /* Mark the boot cpu "present", "online" etc for SMP and UP case */
+ cpu_set(cpu, cpu_online_map);
+ cpu_set(cpu, cpu_present_map);
+ cpu_set(cpu, cpu_possible_map);
+}
+
asmlinkage void __init start_kernel(void)
{
char * command_line;
@@ -447,17 +457,13 @@ asmlinkage void __init start_kernel(void)
* enable them
*/
lock_kernel();
+ boot_cpu_init();
page_address_init();
printk(KERN_NOTICE);
printk(linux_banner);
setup_arch(&command_line);
setup_per_cpu_areas();
-
- /*
- * Mark the boot cpu "online" so that it can call console drivers in
- * printk() and can access its per-cpu storage.
- */
- smp_prepare_boot_cpu();
+ smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
/*
* Set up the scheduler prior starting any interrupts (such as the
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index d7e7e637b92a..c4394abcd5e6 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -958,7 +958,7 @@ void audit_syscall_entry(struct task_struct *tsk, int arch, int major,
*
* i386 no
* x86_64 no
- * ppc64 yes (see arch/ppc64/kernel/misc.S)
+ * ppc64 yes (see arch/powerpc/platforms/iseries/misc.S)
*
* This also happens with vm86 emulation in a non-nested manner
* (entries without exits), so this case must be caught.
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 12815d3f1a05..c86ee051b734 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -53,7 +53,7 @@
#include <asm/uaccess.h>
#include <asm/atomic.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
#define CPUSET_SUPER_MAGIC 0x27e0eb
@@ -168,63 +168,57 @@ static struct vfsmount *cpuset_mount;
static struct super_block *cpuset_sb;
/*
- * We have two global cpuset semaphores below. They can nest.
- * It is ok to first take manage_sem, then nest callback_sem. We also
+ * We have two global cpuset mutexes below. They can nest.
+ * It is ok to first take manage_mutex, then nest callback_mutex. We also
* require taking task_lock() when dereferencing a tasks cpuset pointer.
* See "The task_lock() exception", at the end of this comment.
*
- * A task must hold both semaphores to modify cpusets. If a task
- * holds manage_sem, then it blocks others wanting that semaphore,
- * ensuring that it is the only task able to also acquire callback_sem
+ * A task must hold both mutexes to modify cpusets. If a task
+ * holds manage_mutex, then it blocks others wanting that mutex,
+ * ensuring that it is the only task able to also acquire callback_mutex
* and be able to modify cpusets. It can perform various checks on
* the cpuset structure first, knowing nothing will change. It can
- * also allocate memory while just holding manage_sem. While it is
+ * also allocate memory while just holding manage_mutex. While it is
* performing these checks, various callback routines can briefly
- * acquire callback_sem to query cpusets. Once it is ready to make
- * the changes, it takes callback_sem, blocking everyone else.
+ * acquire callback_mutex to query cpusets. Once it is ready to make
+ * the changes, it takes callback_mutex, blocking everyone else.
*
* Calls to the kernel memory allocator can not be made while holding
- * callback_sem, as that would risk double tripping on callback_sem
+ * callback_mutex, as that would risk double tripping on callback_mutex
* from one of the callbacks into the cpuset code from within
* __alloc_pages().
*
- * If a task is only holding callback_sem, then it has read-only
+ * If a task is only holding callback_mutex, then it has read-only
* access to cpusets.
*
* The task_struct fields mems_allowed and mems_generation may only
* be accessed in the context of that task, so require no locks.
*
* Any task can increment and decrement the count field without lock.
- * So in general, code holding manage_sem or callback_sem can't rely
+ * So in general, code holding manage_mutex or callback_mutex can't rely
* on the count field not changing. However, if the count goes to
- * zero, then only attach_task(), which holds both semaphores, can
+ * zero, then only attach_task(), which holds both mutexes, can
* increment it again. Because a count of zero means that no tasks
* are currently attached, therefore there is no way a task attached
* to that cpuset can fork (the other way to increment the count).
- * So code holding manage_sem or callback_sem can safely assume that
+ * So code holding manage_mutex or callback_mutex can safely assume that
* if the count is zero, it will stay zero. Similarly, if a task
- * holds manage_sem or callback_sem on a cpuset with zero count, it
+ * holds manage_mutex or callback_mutex on a cpuset with zero count, it
* knows that the cpuset won't be removed, as cpuset_rmdir() needs
- * both of those semaphores.
- *
- * A possible optimization to improve parallelism would be to make
- * callback_sem a R/W semaphore (rwsem), allowing the callback routines
- * to proceed in parallel, with read access, until the holder of
- * manage_sem needed to take this rwsem for exclusive write access
- * and modify some cpusets.
+ * both of those mutexes.
*
* The cpuset_common_file_write handler for operations that modify
- * the cpuset hierarchy holds manage_sem across the entire operation,
+ * the cpuset hierarchy holds manage_mutex across the entire operation,
* single threading all such cpuset modifications across the system.
*
- * The cpuset_common_file_read() handlers only hold callback_sem across
+ * The cpuset_common_file_read() handlers only hold callback_mutex across
* small pieces of code, such as when reading out possibly multi-word
* cpumasks and nodemasks.
*
* The fork and exit callbacks cpuset_fork() and cpuset_exit(), don't
- * (usually) take either semaphore. These are the two most performance
+ * (usually) take either mutex. These are the two most performance
* critical pieces of code here. The exception occurs on cpuset_exit(),
- * when a task in a notify_on_release cpuset exits. Then manage_sem
+ * when a task in a notify_on_release cpuset exits. Then manage_mutex
* is taken, and if the cpuset count is zero, a usermode call made
* to /sbin/cpuset_release_agent with the name of the cpuset (path
* relative to the root of cpuset file system) as the argument.
@@ -242,9 +236,9 @@ static struct super_block *cpuset_sb;
*
* The need for this exception arises from the action of attach_task(),
* which overwrites one tasks cpuset pointer with another. It does
- * so using both semaphores, however there are several performance
+ * so using both mutexes, however there are several performance
* critical places that need to reference task->cpuset without the
- * expense of grabbing a system global semaphore. Therefore except as
+ * expense of grabbing a system global mutex. Therefore except as
* noted below, when dereferencing or, as in attach_task(), modifying
* a tasks cpuset pointer we use task_lock(), which acts on a spinlock
* (task->alloc_lock) already in the task_struct routinely used for
@@ -256,8 +250,8 @@ static struct super_block *cpuset_sb;
* the routine cpuset_update_task_memory_state().
*/
-static DECLARE_MUTEX(manage_sem);
-static DECLARE_MUTEX(callback_sem);
+static DEFINE_MUTEX(manage_mutex);
+static DEFINE_MUTEX(callback_mutex);
/*
* A couple of forward declarations required, due to cyclic reference loop:
@@ -432,7 +426,7 @@ static inline struct cftype *__d_cft(struct dentry *dentry)
}
/*
- * Call with manage_sem held. Writes path of cpuset into buf.
+ * Call with manage_mutex held. Writes path of cpuset into buf.
* Returns 0 on success, -errno on error.
*/
@@ -484,11 +478,11 @@ static int cpuset_path(const struct cpuset *cs, char *buf, int buflen)
* status of the /sbin/cpuset_release_agent task, so no sense holding
* our caller up for that.
*
- * When we had only one cpuset semaphore, we had to call this
+ * When we had only one cpuset mutex, we had to call this
* without holding it, to avoid deadlock when call_usermodehelper()
* allocated memory. With two locks, we could now call this while
- * holding manage_sem, but we still don't, so as to minimize
- * the time manage_sem is held.
+ * holding manage_mutex, but we still don't, so as to minimize
+ * the time manage_mutex is held.
*/
static void cpuset_release_agent(const char *pathbuf)
@@ -520,15 +514,15 @@ static void cpuset_release_agent(const char *pathbuf)
* cs is notify_on_release() and now both the user count is zero and
* the list of children is empty, prepare cpuset path in a kmalloc'd
* buffer, to be returned via ppathbuf, so that the caller can invoke
- * cpuset_release_agent() with it later on, once manage_sem is dropped.
- * Call here with manage_sem held.
+ * cpuset_release_agent() with it later on, once manage_mutex is dropped.
+ * Call here with manage_mutex held.
*
* This check_for_release() routine is responsible for kmalloc'ing
* pathbuf. The above cpuset_release_agent() is responsible for
* kfree'ing pathbuf. The caller of these routines is responsible
* for providing a pathbuf pointer, initialized to NULL, then
- * calling check_for_release() with manage_sem held and the address
- * of the pathbuf pointer, then dropping manage_sem, then calling
+ * calling check_for_release() with manage_mutex held and the address
+ * of the pathbuf pointer, then dropping manage_mutex, then calling
* cpuset_release_agent() with pathbuf, as set by check_for_release().
*/
@@ -559,7 +553,7 @@ static void check_for_release(struct cpuset *cs, char **ppathbuf)
* One way or another, we guarantee to return some non-empty subset
* of cpu_online_map.
*
- * Call with callback_sem held.
+ * Call with callback_mutex held.
*/
static void guarantee_online_cpus(const struct cpuset *cs, cpumask_t *pmask)
@@ -583,7 +577,7 @@ static void guarantee_online_cpus(const struct cpuset *cs, cpumask_t *pmask)
* One way or another, we guarantee to return some non-empty subset
* of node_online_map.
*
- * Call with callback_sem held.
+ * Call with callback_mutex held.
*/
static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask)
@@ -608,12 +602,12 @@ static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask)
* current->cpuset if a task has its memory placement changed.
* Do not call this routine if in_interrupt().
*
- * Call without callback_sem or task_lock() held. May be called
- * with or without manage_sem held. Doesn't need task_lock to guard
+ * Call without callback_mutex or task_lock() held. May be called
+ * with or without manage_mutex held. Doesn't need task_lock to guard
* against another task changing a non-NULL cpuset pointer to NULL,
* as that is only done by a task on itself, and if the current task
* is here, it is not simultaneously in the exit code NULL'ing its
- * cpuset pointer. This routine also might acquire callback_sem and
+ * cpuset pointer. This routine also might acquire callback_mutex and
* current->mm->mmap_sem during call.
*
* Reading current->cpuset->mems_generation doesn't need task_lock
@@ -658,13 +652,13 @@ void cpuset_update_task_memory_state(void)
}
if (my_cpusets_mem_gen != tsk->cpuset_mems_generation) {
- down(&callback_sem);
+ mutex_lock(&callback_mutex);
task_lock(tsk);
cs = tsk->cpuset; /* Maybe changed when task not locked */
guarantee_online_mems(cs, &tsk->mems_allowed);
tsk->cpuset_mems_generation = cs->mems_generation;
task_unlock(tsk);
- up(&callback_sem);
+ mutex_unlock(&callback_mutex);
mpol_rebind_task(tsk, &tsk->mems_allowed);
}
}
@@ -674,7 +668,7 @@ void cpuset_update_task_memory_state(void)
*
* One cpuset is a subset of another if all its allowed CPUs and
* Memory Nodes are a subset of the other, and its exclusive flags
- * are only set if the other's are set. Call holding manage_sem.
+ * are only set if the other's are set. Call holding manage_mutex.
*/
static int is_cpuset_subset(const struct cpuset *p, const struct cpuset *q)
@@ -692,7 +686,7 @@ static int is_cpuset_subset(const struct cpuset *p, const struct cpuset *q)
* If we replaced the flag and mask values of the current cpuset
* (cur) with those values in the trial cpuset (trial), would
* our various subset and exclusive rules still be valid? Presumes
- * manage_sem held.
+ * manage_mutex held.
*
* 'cur' is the address of an actual, in-use cpuset. Operations
* such as list traversal that depend on the actual address of the
@@ -746,7 +740,7 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial)
* exclusive child cpusets
* Build these two partitions by calling partition_sched_domains
*
- * Call with manage_sem held. May nest a call to the
+ * Call with manage_mutex held. May nest a call to the
* lock_cpu_hotplug()/unlock_cpu_hotplug() pair.
*/
@@ -792,7 +786,7 @@ static void update_cpu_domains(struct cpuset *cur)
}
/*
- * Call with manage_sem held. May take callback_sem during call.
+ * Call with manage_mutex held. May take callback_mutex during call.
*/
static int update_cpumask(struct cpuset *cs, char *buf)
@@ -811,9 +805,9 @@ static int update_cpumask(struct cpuset *cs, char *buf)
if (retval < 0)
return retval;
cpus_unchanged = cpus_equal(cs->cpus_allowed, trialcs.cpus_allowed);
- down(&callback_sem);
+ mutex_lock(&callback_mutex);
cs->cpus_allowed = trialcs.cpus_allowed;
- up(&callback_sem);
+ mutex_unlock(&callback_mutex);
if (is_cpu_exclusive(cs) && !cpus_unchanged)
update_cpu_domains(cs);
return 0;
@@ -827,7 +821,7 @@ static int update_cpumask(struct cpuset *cs, char *buf)
* the cpuset is marked 'memory_migrate', migrate the tasks
* pages to the new memory.
*
- * Call with manage_sem held. May take callback_sem during call.
+ * Call with manage_mutex held. May take callback_mutex during call.
* Will take tasklist_lock, scan tasklist for tasks in cpuset cs,
* lock each such tasks mm->mmap_sem, scan its vma's and rebind
* their mempolicies to the cpusets new mems_allowed.
@@ -862,11 +856,11 @@ static int update_nodemask(struct cpuset *cs, char *buf)
if (retval < 0)
goto done;
- down(&callback_sem);
+ mutex_lock(&callback_mutex);
cs->mems_allowed = trialcs.mems_allowed;
atomic_inc(&cpuset_mems_generation);
cs->mems_generation = atomic_read(&cpuset_mems_generation);
- up(&callback_sem);
+ mutex_unlock(&callback_mutex);
set_cpuset_being_rebound(cs); /* causes mpol_copy() rebind */
@@ -922,7 +916,7 @@ static int update_nodemask(struct cpuset *cs, char *buf)
* tasklist_lock. Forks can happen again now - the mpol_copy()
* cpuset_being_rebound check will catch such forks, and rebind
* their vma mempolicies too. Because we still hold the global
- * cpuset manage_sem, we know that no other rebind effort will
+ * cpuset manage_mutex, we know that no other rebind effort will
* be contending for the global variable cpuset_being_rebound.
* It's ok if we rebind the same mm twice; mpol_rebind_mm()
* is idempotent. Also migrate pages in each mm to new nodes.
@@ -948,7 +942,7 @@ done:
}
/*
- * Call with manage_sem held.
+ * Call with manage_mutex held.
*/
static int update_memory_pressure_enabled(struct cpuset *cs, char *buf)
@@ -967,7 +961,7 @@ static int update_memory_pressure_enabled(struct cpuset *cs, char *buf)
* cs: the cpuset to update
* buf: the buffer where we read the 0 or 1
*
- * Call with manage_sem held.
+ * Call with manage_mutex held.
*/
static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
@@ -989,12 +983,12 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
return err;
cpu_exclusive_changed =
(is_cpu_exclusive(cs) != is_cpu_exclusive(&trialcs));
- down(&callback_sem);
+ mutex_lock(&callback_mutex);
if (turning_on)
set_bit(bit, &cs->flags);
else
clear_bit(bit, &cs->flags);
- up(&callback_sem);
+ mutex_unlock(&callback_mutex);
if (cpu_exclusive_changed)
update_cpu_domains(cs);
@@ -1104,7 +1098,7 @@ static int fmeter_getrate(struct fmeter *fmp)
* writing the path of the old cpuset in 'ppathbuf' if it needs to be
* notified on release.
*
- * Call holding manage_sem. May take callback_sem and task_lock of
+ * Call holding manage_mutex. May take callback_mutex and task_lock of
* the task 'pid' during call.
*/
@@ -1144,13 +1138,13 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
get_task_struct(tsk);
}
- down(&callback_sem);
+ mutex_lock(&callback_mutex);
task_lock(tsk);
oldcs = tsk->cpuset;
if (!oldcs) {
task_unlock(tsk);
- up(&callback_sem);
+ mutex_unlock(&callback_mutex);
put_task_struct(tsk);
return -ESRCH;
}
@@ -1164,7 +1158,7 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
from = oldcs->mems_allowed;
to = cs->mems_allowed;
- up(&callback_sem);
+ mutex_unlock(&callback_mutex);
mm = get_task_mm(tsk);
if (mm) {
@@ -1221,7 +1215,7 @@ static ssize_t cpuset_common_file_write(struct file *file, const char __user *us
}
buffer[nbytes] = 0; /* nul-terminate */
- down(&manage_sem);
+ mutex_lock(&manage_mutex);
if (is_removed(cs)) {
retval = -ENODEV;
@@ -1264,7 +1258,7 @@ static ssize_t cpuset_common_file_write(struct file *file, const char __user *us
if (retval == 0)
retval = nbytes;
out2:
- up(&manage_sem);
+ mutex_unlock(&manage_mutex);
cpuset_release_agent(pathbuf);
out1:
kfree(buffer);
@@ -1304,9 +1298,9 @@ static int cpuset_sprintf_cpulist(char *page, struct cpuset *cs)
{
cpumask_t mask;
- down(&callback_sem);
+ mutex_lock(&callback_mutex);
mask = cs->cpus_allowed;
- up(&callback_sem);
+ mutex_unlock(&callback_mutex);
return cpulist_scnprintf(page, PAGE_SIZE, mask);
}
@@ -1315,9 +1309,9 @@ static int cpuset_sprintf_memlist(char *page, struct cpuset *cs)
{
nodemask_t mask;
- down(&callback_sem);
+ mutex_lock(&callback_mutex);
mask = cs->mems_allowed;
- up(&callback_sem);
+ mutex_unlock(&callback_mutex);
return nodelist_scnprintf(page, PAGE_SIZE, mask);
}
@@ -1598,7 +1592,7 @@ static int pid_array_to_buf(char *buf, int sz, pid_t *a, int npids)
* Handle an open on 'tasks' file. Prepare a buffer listing the
* process id's of tasks currently attached to the cpuset being opened.
*
- * Does not require any specific cpuset semaphores, and does not take any.
+ * Does not require any specific cpuset mutexes, and does not take any.
*/
static int cpuset_tasks_open(struct inode *unused, struct file *file)
{
@@ -1754,7 +1748,7 @@ static int cpuset_populate_dir(struct dentry *cs_dentry)
* name: name of the new cpuset. Will be strcpy'ed.
* mode: mode to set on new inode
*
- * Must be called with the semaphore on the parent inode held
+ * Must be called with the mutex on the parent inode held
*/
static long cpuset_create(struct cpuset *parent, const char *name, int mode)
@@ -1766,7 +1760,7 @@ static long cpuset_create(struct cpuset *parent, const char *name, int mode)
if (!cs)
return -ENOMEM;
- down(&manage_sem);
+ mutex_lock(&manage_mutex);
cpuset_update_task_memory_state();
cs->flags = 0;
if (notify_on_release(parent))
@@ -1782,28 +1776,28 @@ static long cpuset_create(struct cpuset *parent, const char *name, int mode)
cs->parent = parent;
- down(&callback_sem);
+ mutex_lock(&callback_mutex);
list_add(&cs->sibling, &cs->parent->children);
number_of_cpusets++;
- up(&callback_sem);
+ mutex_unlock(&callback_mutex);
err = cpuset_create_dir(cs, name, mode);
if (err < 0)
goto err;
/*
- * Release manage_sem before cpuset_populate_dir() because it
+ * Release manage_mutex before cpuset_populate_dir() because it
* will down() this new directory's i_mutex and if we race with
* another mkdir, we might deadlock.
*/
- up(&manage_sem);
+ mutex_unlock(&manage_mutex);
err = cpuset_populate_dir(cs->dentry);
/* If err < 0, we have a half-filled directory - oh well ;) */
return 0;
err:
list_del(&cs->sibling);
- up(&manage_sem);
+ mutex_unlock(&manage_mutex);
kfree(cs);
return err;
}
@@ -1825,18 +1819,18 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
/* the vfs holds both inode->i_mutex already */
- down(&manage_sem);
+ mutex_lock(&manage_mutex);
cpuset_update_task_memory_state();
if (atomic_read(&cs->count) > 0) {
- up(&manage_sem);
+ mutex_unlock(&manage_mutex);
return -EBUSY;
}
if (!list_empty(&cs->children)) {
- up(&manage_sem);
+ mutex_unlock(&manage_mutex);
return -EBUSY;
}
parent = cs->parent;
- down(&callback_sem);
+ mutex_lock(&callback_mutex);
set_bit(CS_REMOVED, &cs->flags);
if (is_cpu_exclusive(cs))
update_cpu_domains(cs);
@@ -1848,10 +1842,10 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
cpuset_d_remove_dir(d);
dput(d);
number_of_cpusets--;
- up(&callback_sem);
+ mutex_unlock(&callback_mutex);
if (list_empty(&parent->children))
check_for_release(parent, &pathbuf);
- up(&manage_sem);
+ mutex_unlock(&manage_mutex);
cpuset_release_agent(pathbuf);
return 0;
}
@@ -1960,19 +1954,19 @@ void cpuset_fork(struct task_struct *child)
* Description: Detach cpuset from @tsk and release it.
*
* Note that cpusets marked notify_on_release force every task in
- * them to take the global manage_sem semaphore when exiting.
+ * them to take the global manage_mutex mutex when exiting.
* This could impact scaling on very large systems. Be reluctant to
* use notify_on_release cpusets where very high task exit scaling
* is required on large systems.
*
* Don't even think about derefencing 'cs' after the cpuset use count
- * goes to zero, except inside a critical section guarded by manage_sem
- * or callback_sem. Otherwise a zero cpuset use count is a license to
+ * goes to zero, except inside a critical section guarded by manage_mutex
+ * or callback_mutex. Otherwise a zero cpuset use count is a license to
* any other task to nuke the cpuset immediately, via cpuset_rmdir().
*
- * This routine has to take manage_sem, not callback_sem, because
- * it is holding that semaphore while calling check_for_release(),
- * which calls kmalloc(), so can't be called holding callback__sem().
+ * This routine has to take manage_mutex, not callback_mutex, because
+ * it is holding that mutex while calling check_for_release(),
+ * which calls kmalloc(), so can't be called holding callback_mutex().
*
* We don't need to task_lock() this reference to tsk->cpuset,
* because tsk is already marked PF_EXITING, so attach_task() won't
@@ -2022,10 +2016,10 @@ void cpuset_exit(struct task_struct *tsk)
if (notify_on_release(cs)) {
char *pathbuf = NULL;
- down(&manage_sem);
+ mutex_lock(&manage_mutex);
if (atomic_dec_and_test(&cs->count))
check_for_release(cs, &pathbuf);
- up(&manage_sem);
+ mutex_unlock(&manage_mutex);
cpuset_release_agent(pathbuf);
} else {
atomic_dec(&cs->count);
@@ -2046,11 +2040,11 @@ cpumask_t cpuset_cpus_allowed(struct task_struct *tsk)
{
cpumask_t mask;
- down(&callback_sem);
+ mutex_lock(&callback_mutex);
task_lock(tsk);
guarantee_online_cpus(tsk->cpuset, &mask);
task_unlock(tsk);
- up(&callback_sem);
+ mutex_unlock(&callback_mutex);
return mask;
}
@@ -2074,11 +2068,11 @@ nodemask_t cpuset_mems_allowed(struct task_struct *tsk)
{
nodemask_t mask;
- down(&callback_sem);
+ mutex_lock(&callback_mutex);
task_lock(tsk);
guarantee_online_mems(tsk->cpuset, &mask);
task_unlock(tsk);
- up(&callback_sem);
+ mutex_unlock(&callback_mutex);
return mask;
}
@@ -2104,7 +2098,7 @@ int cpuset_zonelist_valid_mems_allowed(struct zonelist *zl)
/*
* nearest_exclusive_ancestor() - Returns the nearest mem_exclusive
- * ancestor to the specified cpuset. Call holding callback_sem.
+ * ancestor to the specified cpuset. Call holding callback_mutex.
* If no ancestor is mem_exclusive (an unusual configuration), then
* returns the root cpuset.
*/
@@ -2131,12 +2125,12 @@ static const struct cpuset *nearest_exclusive_ancestor(const struct cpuset *cs)
* GFP_KERNEL allocations are not so marked, so can escape to the
* nearest mem_exclusive ancestor cpuset.
*
- * Scanning up parent cpusets requires callback_sem. The __alloc_pages()
+ * Scanning up parent cpusets requires callback_mutex. The __alloc_pages()
* routine only calls here with __GFP_HARDWALL bit _not_ set if
* it's a GFP_KERNEL allocation, and all nodes in the current tasks
* mems_allowed came up empty on the first pass over the zonelist.
* So only GFP_KERNEL allocations, if all nodes in the cpuset are
- * short of memory, might require taking the callback_sem semaphore.
+ * short of memory, might require taking the callback_mutex mutex.
*
* The first loop over the zonelist in mm/page_alloc.c:__alloc_pages()
* calls here with __GFP_HARDWALL always set in gfp_mask, enforcing
@@ -2171,31 +2165,31 @@ int __cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
return 1;
/* Not hardwall and node outside mems_allowed: scan up cpusets */
- down(&callback_sem);
+ mutex_lock(&callback_mutex);
task_lock(current);
cs = nearest_exclusive_ancestor(current->cpuset);
task_unlock(current);
allowed = node_isset(node, cs->mems_allowed);
- up(&callback_sem);
+ mutex_unlock(&callback_mutex);
return allowed;
}
/**
* cpuset_lock - lock out any changes to cpuset structures
*
- * The out of memory (oom) code needs to lock down cpusets
+ * The out of memory (oom) code needs to mutex_lock cpusets
* from being changed while it scans the tasklist looking for a
- * task in an overlapping cpuset. Expose callback_sem via this
+ * task in an overlapping cpuset. Expose callback_mutex via this
* cpuset_lock() routine, so the oom code can lock it, before
* locking the task list. The tasklist_lock is a spinlock, so
- * must be taken inside callback_sem.
+ * must be taken inside callback_mutex.
*/
void cpuset_lock(void)
{
- down(&callback_sem);
+ mutex_lock(&callback_mutex);
}
/**
@@ -2206,7 +2200,7 @@ void cpuset_lock(void)
void cpuset_unlock(void)
{
- up(&callback_sem);
+ mutex_unlock(&callback_mutex);
}
/**
@@ -2218,7 +2212,7 @@ void cpuset_unlock(void)
* determine if task @p's memory usage might impact the memory
* available to the current task.
*
- * Call while holding callback_sem.
+ * Call while holding callback_mutex.
**/
int cpuset_excl_nodes_overlap(const struct task_struct *p)
@@ -2289,7 +2283,7 @@ void __cpuset_memory_pressure_bump(void)
* - Used for /proc/<pid>/cpuset.
* - No need to task_lock(tsk) on this tsk->cpuset reference, as it
* doesn't really matter if tsk->cpuset changes after we read it,
- * and we take manage_sem, keeping attach_task() from changing it
+ * and we take manage_mutex, keeping attach_task() from changing it
* anyway.
*/
@@ -2305,7 +2299,7 @@ static int proc_cpuset_show(struct seq_file *m, void *v)
return -ENOMEM;
tsk = m->private;
- down(&manage_sem);
+ mutex_lock(&manage_mutex);
cs = tsk->cpuset;
if (!cs) {
retval = -EINVAL;
@@ -2318,7 +2312,7 @@ static int proc_cpuset_show(struct seq_file *m, void *v)
seq_puts(m, buf);
seq_putc(m, '\n');
out:
- up(&manage_sem);
+ mutex_unlock(&manage_mutex);
kfree(buf);
return retval;
}
diff --git a/kernel/exit.c b/kernel/exit.c
index d1e8d500a7e1..8037405e136e 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -345,9 +345,9 @@ void daemonize(const char *name, ...)
exit_mm(current);
set_special_pids(1, 1);
- down(&tty_sem);
+ mutex_lock(&tty_mutex);
current->signal->tty = NULL;
- up(&tty_sem);
+ mutex_unlock(&tty_mutex);
/* Block and flush all signals */
sigfillset(&blocked);
diff --git a/kernel/fork.c b/kernel/fork.c
index 9bd7b65ee418..c79ae0b19a49 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -607,12 +607,12 @@ static struct files_struct *alloc_files(void)
atomic_set(&newf->count, 1);
spin_lock_init(&newf->file_lock);
+ newf->next_fd = 0;
fdt = &newf->fdtab;
- fdt->next_fd = 0;
fdt->max_fds = NR_OPEN_DEFAULT;
- fdt->max_fdset = __FD_SETSIZE;
- fdt->close_on_exec = &newf->close_on_exec_init;
- fdt->open_fds = &newf->open_fds_init;
+ fdt->max_fdset = EMBEDDED_FD_SET_SIZE;
+ fdt->close_on_exec = (fd_set *)&newf->close_on_exec_init;
+ fdt->open_fds = (fd_set *)&newf->open_fds_init;
fdt->fd = &newf->fd_array[0];
INIT_RCU_HEAD(&fdt->rcu);
fdt->free_files = NULL;
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index fef1af8a73ce..1fb9f753ef60 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -48,7 +48,7 @@
static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
-DECLARE_MUTEX(kprobe_mutex); /* Protects kprobe_table */
+DEFINE_MUTEX(kprobe_mutex); /* Protects kprobe_table */
DEFINE_SPINLOCK(kretprobe_lock); /* Protects kretprobe_inst_table */
static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL;
@@ -460,7 +460,7 @@ static int __kprobes __register_kprobe(struct kprobe *p,
}
p->nmissed = 0;
- down(&kprobe_mutex);
+ mutex_lock(&kprobe_mutex);
old_p = get_kprobe(p->addr);
if (old_p) {
ret = register_aggr_kprobe(old_p, p);
@@ -477,7 +477,7 @@ static int __kprobes __register_kprobe(struct kprobe *p,
arch_arm_kprobe(p);
out:
- up(&kprobe_mutex);
+ mutex_unlock(&kprobe_mutex);
if (ret && probed_mod)
module_put(probed_mod);
@@ -496,10 +496,10 @@ void __kprobes unregister_kprobe(struct kprobe *p)
struct kprobe *old_p, *list_p;
int cleanup_p;
- down(&kprobe_mutex);
+ mutex_lock(&kprobe_mutex);
old_p = get_kprobe(p->addr);
if (unlikely(!old_p)) {
- up(&kprobe_mutex);
+ mutex_unlock(&kprobe_mutex);
return;
}
if (p != old_p) {
@@ -507,7 +507,7 @@ void __kprobes unregister_kprobe(struct kprobe *p)
if (list_p == p)
/* kprobe p is a valid probe */
goto valid_p;
- up(&kprobe_mutex);
+ mutex_unlock(&kprobe_mutex);
return;
}
valid_p:
@@ -523,7 +523,7 @@ valid_p:
cleanup_p = 0;
}
- up(&kprobe_mutex);
+ mutex_unlock(&kprobe_mutex);
synchronize_sched();
if (p->mod_refcounted &&
diff --git a/kernel/kthread.c b/kernel/kthread.c
index e75950a1092c..6a5373868a98 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -12,6 +12,7 @@
#include <linux/unistd.h>
#include <linux/file.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <asm/semaphore.h>
/*
@@ -41,7 +42,7 @@ struct kthread_stop_info
/* Thread stopping is done by setthing this var: lock serializes
* multiple kthread_stop calls. */
-static DECLARE_MUTEX(kthread_stop_lock);
+static DEFINE_MUTEX(kthread_stop_lock);
static struct kthread_stop_info kthread_stop_info;
int kthread_should_stop(void)
@@ -173,7 +174,7 @@ int kthread_stop_sem(struct task_struct *k, struct semaphore *s)
{
int ret;
- down(&kthread_stop_lock);
+ mutex_lock(&kthread_stop_lock);
/* It could exit after stop_info.k set, but before wake_up_process. */
get_task_struct(k);
@@ -194,7 +195,7 @@ int kthread_stop_sem(struct task_struct *k, struct semaphore *s)
wait_for_completion(&kthread_stop_info.done);
kthread_stop_info.k = NULL;
ret = kthread_stop_info.err;
- up(&kthread_stop_lock);
+ mutex_unlock(&kthread_stop_lock);
return ret;
}
diff --git a/kernel/module.c b/kernel/module.c
index 77764f22f021..fb404299082e 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -39,6 +39,7 @@
#include <linux/device.h>
#include <linux/string.h>
#include <linux/sched.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>
#include <asm/cacheflush.h>
@@ -60,18 +61,18 @@
static DEFINE_SPINLOCK(modlist_lock);
/* List of modules, protected by module_mutex AND modlist_lock */
-static DECLARE_MUTEX(module_mutex);
+static DEFINE_MUTEX(module_mutex);
static LIST_HEAD(modules);
-static DECLARE_MUTEX(notify_mutex);
+static DEFINE_MUTEX(notify_mutex);
static struct notifier_block * module_notify_list;
int register_module_notifier(struct notifier_block * nb)
{
int err;
- down(&notify_mutex);
+ mutex_lock(&notify_mutex);
err = notifier_chain_register(&module_notify_list, nb);
- up(&notify_mutex);
+ mutex_unlock(&notify_mutex);
return err;
}
EXPORT_SYMBOL(register_module_notifier);
@@ -79,9 +80,9 @@ EXPORT_SYMBOL(register_module_notifier);
int unregister_module_notifier(struct notifier_block * nb)
{
int err;
- down(&notify_mutex);
+ mutex_lock(&notify_mutex);
err = notifier_chain_unregister(&module_notify_list, nb);
- up(&notify_mutex);
+ mutex_unlock(&notify_mutex);
return err;
}
EXPORT_SYMBOL(unregister_module_notifier);
@@ -601,7 +602,7 @@ static void free_module(struct module *mod);
static void wait_for_zero_refcount(struct module *mod)
{
/* Since we might sleep for some time, drop the semaphore first */
- up(&module_mutex);
+ mutex_unlock(&module_mutex);
for (;;) {
DEBUGP("Looking at refcount...\n");
set_current_state(TASK_UNINTERRUPTIBLE);
@@ -610,7 +611,7 @@ static void wait_for_zero_refcount(struct module *mod)
schedule();
}
current->state = TASK_RUNNING;
- down(&module_mutex);
+ mutex_lock(&module_mutex);
}
asmlinkage long
@@ -627,7 +628,7 @@ sys_delete_module(const char __user *name_user, unsigned int flags)
return -EFAULT;
name[MODULE_NAME_LEN-1] = '\0';
- if (down_interruptible(&module_mutex) != 0)
+ if (mutex_lock_interruptible(&module_mutex) != 0)
return -EINTR;
mod = find_module(name);
@@ -676,14 +677,14 @@ sys_delete_module(const char __user *name_user, unsigned int flags)
/* Final destruction now noone is using it. */
if (mod->exit != NULL) {
- up(&module_mutex);
+ mutex_unlock(&module_mutex);
mod->exit();
- down(&module_mutex);
+ mutex_lock(&module_mutex);
}
free_module(mod);
out:
- up(&module_mutex);
+ mutex_unlock(&module_mutex);
return ret;
}
@@ -1972,13 +1973,13 @@ sys_init_module(void __user *umod,
return -EPERM;
/* Only one module load at a time, please */
- if (down_interruptible(&module_mutex) != 0)
+ if (mutex_lock_interruptible(&module_mutex) != 0)
return -EINTR;
/* Do all the hard work */
mod = load_module(umod, len, uargs);
if (IS_ERR(mod)) {
- up(&module_mutex);
+ mutex_unlock(&module_mutex);
return PTR_ERR(mod);
}
@@ -1987,11 +1988,11 @@ sys_init_module(void __user *umod,
stop_machine_run(__link_module, mod, NR_CPUS);
/* Drop lock so they can recurse */
- up(&module_mutex);
+ mutex_unlock(&module_mutex);
- down(&notify_mutex);
+ mutex_lock(&notify_mutex);
notifier_call_chain(&module_notify_list, MODULE_STATE_COMING, mod);
- up(&notify_mutex);
+ mutex_unlock(&notify_mutex);
/* Start the module */
if (mod->init != NULL)
@@ -2006,15 +2007,15 @@ sys_init_module(void __user *umod,
mod->name);
else {
module_put(mod);
- down(&module_mutex);
+ mutex_lock(&module_mutex);
free_module(mod);
- up(&module_mutex);
+ mutex_unlock(&module_mutex);
}
return ret;
}
/* Now it's a first class citizen! */
- down(&module_mutex);
+ mutex_lock(&module_mutex);
mod->state = MODULE_STATE_LIVE;
/* Drop initial reference. */
module_put(mod);
@@ -2022,7 +2023,7 @@ sys_init_module(void __user *umod,
mod->module_init = NULL;
mod->init_size = 0;
mod->init_text_size = 0;
- up(&module_mutex);
+ mutex_unlock(&module_mutex);
return 0;
}
@@ -2112,7 +2113,7 @@ struct module *module_get_kallsym(unsigned int symnum,
{
struct module *mod;
- down(&module_mutex);
+ mutex_lock(&module_mutex);
list_for_each_entry(mod, &modules, list) {
if (symnum < mod->num_symtab) {
*value = mod->symtab[symnum].st_value;
@@ -2120,12 +2121,12 @@ struct module *module_get_kallsym(unsigned int symnum,
strncpy(namebuf,
mod->strtab + mod->symtab[symnum].st_name,
127);
- up(&module_mutex);
+ mutex_unlock(&module_mutex);
return mod;
}
symnum -= mod->num_symtab;
}
- up(&module_mutex);
+ mutex_unlock(&module_mutex);
return NULL;
}
@@ -2168,7 +2169,7 @@ static void *m_start(struct seq_file *m, loff_t *pos)
struct list_head *i;
loff_t n = 0;
- down(&module_mutex);
+ mutex_lock(&module_mutex);
list_for_each(i, &modules) {
if (n++ == *pos)
break;
@@ -2189,7 +2190,7 @@ static void *m_next(struct seq_file *m, void *p, loff_t *pos)
static void m_stop(struct seq_file *m, void *p)
{
- up(&module_mutex);
+ mutex_unlock(&module_mutex);
}
static int m_show(struct seq_file *m, void *p)
diff --git a/kernel/panic.c b/kernel/panic.c
index 126dc43f1c74..acd95adddb93 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -20,10 +20,13 @@
#include <linux/nmi.h>
#include <linux/kexec.h>
-int panic_timeout;
int panic_on_oops;
int tainted;
+static int pause_on_oops;
+static int pause_on_oops_flag;
+static DEFINE_SPINLOCK(pause_on_oops_lock);
+int panic_timeout;
EXPORT_SYMBOL(panic_timeout);
struct notifier_block *panic_notifier_list;
@@ -174,3 +177,95 @@ void add_taint(unsigned flag)
tainted |= flag;
}
EXPORT_SYMBOL(add_taint);
+
+static int __init pause_on_oops_setup(char *str)
+{
+ pause_on_oops = simple_strtoul(str, NULL, 0);
+ return 1;
+}
+__setup("pause_on_oops=", pause_on_oops_setup);
+
+static void spin_msec(int msecs)
+{
+ int i;
+
+ for (i = 0; i < msecs; i++) {
+ touch_nmi_watchdog();
+ mdelay(1);
+ }
+}
+
+/*
+ * It just happens that oops_enter() and oops_exit() are identically
+ * implemented...
+ */
+static void do_oops_enter_exit(void)
+{
+ unsigned long flags;
+ static int spin_counter;
+
+ if (!pause_on_oops)
+ return;
+
+ spin_lock_irqsave(&pause_on_oops_lock, flags);
+ if (pause_on_oops_flag == 0) {
+ /* This CPU may now print the oops message */
+ pause_on_oops_flag = 1;
+ } else {
+ /* We need to stall this CPU */
+ if (!spin_counter) {
+ /* This CPU gets to do the counting */
+ spin_counter = pause_on_oops;
+ do {
+ spin_unlock(&pause_on_oops_lock);
+ spin_msec(MSEC_PER_SEC);
+ spin_lock(&pause_on_oops_lock);
+ } while (--spin_counter);
+ pause_on_oops_flag = 0;
+ } else {
+ /* This CPU waits for a different one */
+ while (spin_counter) {
+ spin_unlock(&pause_on_oops_lock);
+ spin_msec(1);
+ spin_lock(&pause_on_oops_lock);
+ }
+ }
+ }
+ spin_unlock_irqrestore(&pause_on_oops_lock, flags);
+}
+
+/*
+ * Return true if the calling CPU is allowed to print oops-related info. This
+ * is a bit racy..
+ */
+int oops_may_print(void)
+{
+ return pause_on_oops_flag == 0;
+}
+
+/*
+ * Called when the architecture enters its oops handler, before it prints
+ * anything. If this is the first CPU to oops, and it's oopsing the first time
+ * then let it proceed.
+ *
+ * This is all enabled by the pause_on_oops kernel boot option. We do all this
+ * to ensure that oopses don't scroll off the screen. It has the side-effect
+ * of preventing later-oopsing CPUs from mucking up the display, too.
+ *
+ * It turns out that the CPU which is allowed to print ends up pausing for the
+ * right duration, whereas all the other CPUs pause for twice as long: once in
+ * oops_enter(), once in oops_exit().
+ */
+void oops_enter(void)
+{
+ do_oops_enter_exit();
+}
+
+/*
+ * Called when the architecture exits its oops handler, after printing
+ * everything.
+ */
+void oops_exit(void)
+{
+ do_oops_enter_exit();
+}
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index fa895fc2ecf5..9944379360b5 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -35,6 +35,7 @@
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/time.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>
diff --git a/kernel/power/Makefile b/kernel/power/Makefile
index 04be7d0d96a7..8d0af3d37a4b 100644
--- a/kernel/power/Makefile
+++ b/kernel/power/Makefile
@@ -5,7 +5,7 @@ endif
obj-y := main.o process.o console.o
obj-$(CONFIG_PM_LEGACY) += pm.o
-obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o disk.o snapshot.o
+obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o disk.o snapshot.o swap.o user.o
obj-$(CONFIG_SUSPEND_SMP) += smp.o
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 0b43847dc980..81d4d982f3f0 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -22,17 +22,6 @@
#include "power.h"
-extern suspend_disk_method_t pm_disk_mode;
-
-extern int swsusp_shrink_memory(void);
-extern int swsusp_suspend(void);
-extern int swsusp_write(struct pbe *pblist, unsigned int nr_pages);
-extern int swsusp_check(void);
-extern int swsusp_read(struct pbe **pblist_ptr);
-extern void swsusp_close(void);
-extern int swsusp_resume(void);
-
-
static int noresume = 0;
char resume_file[256] = CONFIG_PM_STD_PARTITION;
dev_t swsusp_resume_device;
@@ -70,10 +59,6 @@ static void power_down(suspend_disk_method_t mode)
while(1);
}
-
-static int in_suspend __nosavedata = 0;
-
-
static inline void platform_finish(void)
{
if (pm_disk_mode == PM_DISK_PLATFORM) {
@@ -87,7 +72,6 @@ static int prepare_processes(void)
int error;
pm_prepare_console();
- sys_sync();
disable_nonboot_cpus();
if (freeze_processes()) {
@@ -145,7 +129,7 @@ int pm_suspend_disk(void)
if (in_suspend) {
device_resume();
pr_debug("PM: writing image.\n");
- error = swsusp_write(pagedir_nosave, nr_copy_pages);
+ error = swsusp_write();
if (!error)
power_down(pm_disk_mode);
else {
@@ -216,7 +200,7 @@ static int software_resume(void)
pr_debug("PM: Reading swsusp image.\n");
- if ((error = swsusp_read(&pagedir_nosave))) {
+ if ((error = swsusp_read())) {
swsusp_free();
goto Thaw;
}
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 9cb235cba4a9..ee371f50ccaa 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -103,7 +103,7 @@ static int suspend_prepare(suspend_state_t state)
}
-static int suspend_enter(suspend_state_t state)
+int suspend_enter(suspend_state_t state)
{
int error = 0;
unsigned long flags;
diff --git a/kernel/power/pm.c b/kernel/power/pm.c
index 33c508e857dd..0f6908cce1dd 100644
--- a/kernel/power/pm.c
+++ b/kernel/power/pm.c
@@ -25,6 +25,7 @@
#include <linux/pm.h>
#include <linux/pm_legacy.h>
#include <linux/interrupt.h>
+#include <linux/mutex.h>
int pm_active;
@@ -40,7 +41,7 @@ int pm_active;
* until a resume but that will be fine.
*/
-static DECLARE_MUTEX(pm_devs_lock);
+static DEFINE_MUTEX(pm_devs_lock);
static LIST_HEAD(pm_devs);
/**
@@ -67,9 +68,9 @@ struct pm_dev *pm_register(pm_dev_t type,
dev->id = id;
dev->callback = callback;
- down(&pm_devs_lock);
+ mutex_lock(&pm_devs_lock);
list_add(&dev->entry, &pm_devs);
- up(&pm_devs_lock);
+ mutex_unlock(&pm_devs_lock);
}
return dev;
}
@@ -85,9 +86,9 @@ struct pm_dev *pm_register(pm_dev_t type,
void pm_unregister(struct pm_dev *dev)
{
if (dev) {
- down(&pm_devs_lock);
+ mutex_lock(&pm_devs_lock);
list_del(&dev->entry);
- up(&pm_devs_lock);
+ mutex_unlock(&pm_devs_lock);
kfree(dev);
}
@@ -118,7 +119,7 @@ void pm_unregister_all(pm_callback callback)
if (!callback)
return;
- down(&pm_devs_lock);
+ mutex_lock(&pm_devs_lock);
entry = pm_devs.next;
while (entry != &pm_devs) {
struct pm_dev *dev = list_entry(entry, struct pm_dev, entry);
@@ -126,7 +127,7 @@ void pm_unregister_all(pm_callback callback)
if (dev->callback == callback)
__pm_unregister(dev);
}
- up(&pm_devs_lock);
+ mutex_unlock(&pm_devs_lock);
}
/**
@@ -234,7 +235,7 @@ int pm_send_all(pm_request_t rqst, void *data)
{
struct list_head *entry;
- down(&pm_devs_lock);
+ mutex_lock(&pm_devs_lock);
entry = pm_devs.next;
while (entry != &pm_devs) {
struct pm_dev *dev = list_entry(entry, struct pm_dev, entry);
@@ -246,13 +247,13 @@ int pm_send_all(pm_request_t rqst, void *data)
*/
if (rqst == PM_SUSPEND)
pm_undo_all(dev);
- up(&pm_devs_lock);
+ mutex_unlock(&pm_devs_lock);
return status;
}
}
entry = entry->next;
}
- up(&pm_devs_lock);
+ mutex_unlock(&pm_devs_lock);
return 0;
}
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 388dba680841..f06f12f21767 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -8,6 +8,7 @@ struct swsusp_info {
int cpus;
unsigned long image_pages;
unsigned long pages;
+ unsigned long size;
} __attribute__((aligned(PAGE_SIZE)));
@@ -37,21 +38,79 @@ extern struct subsystem power_subsys;
/* References to section boundaries */
extern const void __nosave_begin, __nosave_end;
-extern unsigned int nr_copy_pages;
extern struct pbe *pagedir_nosave;
/* Preferred image size in bytes (default 500 MB) */
extern unsigned long image_size;
+extern int in_suspend;
+extern dev_t swsusp_resume_device;
extern asmlinkage int swsusp_arch_suspend(void);
extern asmlinkage int swsusp_arch_resume(void);
extern unsigned int count_data_pages(void);
-extern void free_pagedir(struct pbe *pblist);
-extern void release_eaten_pages(void);
-extern struct pbe *alloc_pagedir(unsigned nr_pages, gfp_t gfp_mask, int safe_needed);
+
+struct snapshot_handle {
+ loff_t offset;
+ unsigned int page;
+ unsigned int page_offset;
+ unsigned int prev;
+ struct pbe *pbe;
+ void *buffer;
+ unsigned int buf_offset;
+};
+
+#define data_of(handle) ((handle).buffer + (handle).buf_offset)
+
+extern int snapshot_read_next(struct snapshot_handle *handle, size_t count);
+extern int snapshot_write_next(struct snapshot_handle *handle, size_t count);
+int snapshot_image_loaded(struct snapshot_handle *handle);
+
+#define SNAPSHOT_IOC_MAGIC '3'
+#define SNAPSHOT_FREEZE _IO(SNAPSHOT_IOC_MAGIC, 1)
+#define SNAPSHOT_UNFREEZE _IO(SNAPSHOT_IOC_MAGIC, 2)
+#define SNAPSHOT_ATOMIC_SNAPSHOT _IOW(SNAPSHOT_IOC_MAGIC, 3, void *)
+#define SNAPSHOT_ATOMIC_RESTORE _IO(SNAPSHOT_IOC_MAGIC, 4)
+#define SNAPSHOT_FREE _IO(SNAPSHOT_IOC_MAGIC, 5)
+#define SNAPSHOT_SET_IMAGE_SIZE _IOW(SNAPSHOT_IOC_MAGIC, 6, unsigned long)
+#define SNAPSHOT_AVAIL_SWAP _IOR(SNAPSHOT_IOC_MAGIC, 7, void *)
+#define SNAPSHOT_GET_SWAP_PAGE _IOR(SNAPSHOT_IOC_MAGIC, 8, void *)
+#define SNAPSHOT_FREE_SWAP_PAGES _IO(SNAPSHOT_IOC_MAGIC, 9)
+#define SNAPSHOT_SET_SWAP_FILE _IOW(SNAPSHOT_IOC_MAGIC, 10, unsigned int)
+#define SNAPSHOT_S2RAM _IO(SNAPSHOT_IOC_MAGIC, 11)
+#define SNAPSHOT_IOC_MAXNR 11
+
+/**
+ * The bitmap is used for tracing allocated swap pages
+ *
+ * The entire bitmap consists of a number of bitmap_page
+ * structures linked with the help of the .next member.
+ * Thus each page can be allocated individually, so we only
+ * need to make 0-order memory allocations to create
+ * the bitmap.
+ */
+
+#define BITMAP_PAGE_SIZE (PAGE_SIZE - sizeof(void *))
+#define BITMAP_PAGE_CHUNKS (BITMAP_PAGE_SIZE / sizeof(long))
+#define BITS_PER_CHUNK (sizeof(long) * 8)
+#define BITMAP_PAGE_BITS (BITMAP_PAGE_CHUNKS * BITS_PER_CHUNK)
+
+struct bitmap_page {
+ unsigned long chunks[BITMAP_PAGE_CHUNKS];
+ struct bitmap_page *next;
+};
+
+extern void free_bitmap(struct bitmap_page *bitmap);
+extern struct bitmap_page *alloc_bitmap(unsigned int nr_bits);
+extern unsigned long alloc_swap_page(int swap, struct bitmap_page *bitmap);
+extern void free_all_swap_pages(int swap, struct bitmap_page *bitmap);
+
+extern int swsusp_check(void);
+extern int swsusp_shrink_memory(void);
extern void swsusp_free(void);
-extern int alloc_data_pages(struct pbe *pblist, gfp_t gfp_mask, int safe_needed);
-extern unsigned int snapshot_nr_pages(void);
-extern struct pbe *snapshot_pblist(void);
-extern void snapshot_pblist_set(struct pbe *pblist);
+extern int swsusp_suspend(void);
+extern int swsusp_resume(void);
+extern int swsusp_read(void);
+extern int swsusp_write(void);
+extern void swsusp_close(void);
+extern int suspend_enter(suspend_state_t state);
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 28de118f7a0b..8ac7c35fad77 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -12,11 +12,12 @@
#include <linux/interrupt.h>
#include <linux/suspend.h>
#include <linux/module.h>
+#include <linux/syscalls.h>
/*
* Timeout for stopping processes
*/
-#define TIMEOUT (6 * HZ)
+#define TIMEOUT (20 * HZ)
static inline int freezeable(struct task_struct * p)
@@ -54,38 +55,62 @@ void refrigerator(void)
current->state = save;
}
+static inline void freeze_process(struct task_struct *p)
+{
+ unsigned long flags;
+
+ if (!freezing(p)) {
+ freeze(p);
+ spin_lock_irqsave(&p->sighand->siglock, flags);
+ signal_wake_up(p, 0);
+ spin_unlock_irqrestore(&p->sighand->siglock, flags);
+ }
+}
+
/* 0 = success, else # of processes that we failed to stop */
int freeze_processes(void)
{
- int todo;
+ int todo, nr_user, user_frozen;
unsigned long start_time;
struct task_struct *g, *p;
unsigned long flags;
printk( "Stopping tasks: " );
start_time = jiffies;
+ user_frozen = 0;
do {
- todo = 0;
+ nr_user = todo = 0;
read_lock(&tasklist_lock);
do_each_thread(g, p) {
if (!freezeable(p))
continue;
if (frozen(p))
continue;
-
- freeze(p);
- spin_lock_irqsave(&p->sighand->siglock, flags);
- signal_wake_up(p, 0);
- spin_unlock_irqrestore(&p->sighand->siglock, flags);
- todo++;
+ if (p->mm && !(p->flags & PF_BORROWED_MM)) {
+ /* The task is a user-space one.
+ * Freeze it unless there's a vfork completion
+ * pending
+ */
+ if (!p->vfork_done)
+ freeze_process(p);
+ nr_user++;
+ } else {
+ /* Freeze only if the user space is frozen */
+ if (user_frozen)
+ freeze_process(p);
+ todo++;
+ }
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
+ todo += nr_user;
+ if (!user_frozen && !nr_user) {
+ sys_sync();
+ start_time = jiffies;
+ }
+ user_frozen = !nr_user;
yield(); /* Yield is okay here */
- if (todo && time_after(jiffies, start_time + TIMEOUT)) {
- printk( "\n" );
- printk(KERN_ERR " stopping tasks failed (%d tasks remaining)\n", todo );
+ if (todo && time_after(jiffies, start_time + TIMEOUT))
break;
- }
} while(todo);
/* This does not unfreeze processes that are already frozen
@@ -94,8 +119,14 @@ int freeze_processes(void)
* but it cleans up leftover PF_FREEZE requests.
*/
if (todo) {
+ printk( "\n" );
+ printk(KERN_ERR " stopping tasks timed out "
+ "after %d seconds (%d tasks remaining):\n",
+ TIMEOUT / HZ, todo);
read_lock(&tasklist_lock);
- do_each_thread(g, p)
+ do_each_thread(g, p) {
+ if (freezeable(p) && !frozen(p))
+ printk(KERN_ERR " %s\n", p->comm);
if (freezing(p)) {
pr_debug(" clean up: %s\n", p->comm);
p->flags &= ~PF_FREEZE;
@@ -103,7 +134,7 @@ int freeze_processes(void)
recalc_sigpending_tsk(p);
spin_unlock_irqrestore(&p->sighand->siglock, flags);
}
- while_each_thread(g, p);
+ } while_each_thread(g, p);
read_unlock(&tasklist_lock);
return todo;
}
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 8d5a5986d621..c5863d02c89e 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -10,6 +10,7 @@
*/
+#include <linux/version.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/suspend.h>
@@ -34,7 +35,9 @@
#include "power.h"
struct pbe *pagedir_nosave;
-unsigned int nr_copy_pages;
+static unsigned int nr_copy_pages;
+static unsigned int nr_meta_pages;
+static unsigned long *buffer;
#ifdef CONFIG_HIGHMEM
unsigned int count_highmem_pages(void)
@@ -80,7 +83,7 @@ static int save_highmem_zone(struct zone *zone)
void *kaddr;
unsigned long pfn = zone_pfn + zone->zone_start_pfn;
- if (!(pfn%1000))
+ if (!(pfn%10000))
printk(".");
if (!pfn_valid(pfn))
continue;
@@ -119,13 +122,15 @@ int save_highmem(void)
struct zone *zone;
int res = 0;
- pr_debug("swsusp: Saving Highmem\n");
+ pr_debug("swsusp: Saving Highmem");
+ drain_local_pages();
for_each_zone (zone) {
if (is_highmem(zone))
res = save_highmem_zone(zone);
if (res)
return res;
}
+ printk("\n");
return 0;
}
@@ -235,7 +240,7 @@ static void copy_data_pages(struct pbe *pblist)
* free_pagedir - free pages allocated with alloc_pagedir()
*/
-void free_pagedir(struct pbe *pblist)
+static void free_pagedir(struct pbe *pblist)
{
struct pbe *pbe;
@@ -301,7 +306,7 @@ struct eaten_page {
static struct eaten_page *eaten_pages = NULL;
-void release_eaten_pages(void)
+static void release_eaten_pages(void)
{
struct eaten_page *p, *q;
@@ -376,7 +381,6 @@ struct pbe *alloc_pagedir(unsigned int nr_pages, gfp_t gfp_mask, int safe_needed
if (!nr_pages)
return NULL;
- pr_debug("alloc_pagedir(): nr_pages = %d\n", nr_pages);
pblist = alloc_image_page(gfp_mask, safe_needed);
/* FIXME: rewrite this ugly loop */
for (pbe = pblist, num = PBES_PER_PAGE; pbe && num < nr_pages;
@@ -388,7 +392,7 @@ struct pbe *alloc_pagedir(unsigned int nr_pages, gfp_t gfp_mask, int safe_needed
free_pagedir(pblist);
pblist = NULL;
} else
- create_pbe_list(pblist, nr_pages);
+ create_pbe_list(pblist, nr_pages);
return pblist;
}
@@ -414,6 +418,10 @@ void swsusp_free(void)
}
}
}
+ nr_copy_pages = 0;
+ nr_meta_pages = 0;
+ pagedir_nosave = NULL;
+ buffer = NULL;
}
@@ -437,7 +445,7 @@ static int enough_free_mem(unsigned int nr_pages)
(nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
}
-int alloc_data_pages(struct pbe *pblist, gfp_t gfp_mask, int safe_needed)
+static int alloc_data_pages(struct pbe *pblist, gfp_t gfp_mask, int safe_needed)
{
struct pbe *p;
@@ -504,7 +512,318 @@ asmlinkage int swsusp_save(void)
*/
nr_copy_pages = nr_pages;
+ nr_meta_pages = (nr_pages * sizeof(long) + PAGE_SIZE - 1) >> PAGE_SHIFT;
printk("swsusp: critical section/: done (%d pages copied)\n", nr_pages);
return 0;
}
+
+static void init_header(struct swsusp_info *info)
+{
+ memset(info, 0, sizeof(struct swsusp_info));
+ info->version_code = LINUX_VERSION_CODE;
+ info->num_physpages = num_physpages;
+ memcpy(&info->uts, &system_utsname, sizeof(system_utsname));
+ info->cpus = num_online_cpus();
+ info->image_pages = nr_copy_pages;
+ info->pages = nr_copy_pages + nr_meta_pages + 1;
+ info->size = info->pages;
+ info->size <<= PAGE_SHIFT;
+}
+
+/**
+ * pack_orig_addresses - the .orig_address fields of the PBEs from the
+ * list starting at @pbe are stored in the array @buf[] (1 page)
+ */
+
+static inline struct pbe *pack_orig_addresses(unsigned long *buf, struct pbe *pbe)
+{
+ int j;
+
+ for (j = 0; j < PAGE_SIZE / sizeof(long) && pbe; j++) {
+ buf[j] = pbe->orig_address;
+ pbe = pbe->next;
+ }
+ if (!pbe)
+ for (; j < PAGE_SIZE / sizeof(long); j++)
+ buf[j] = 0;
+ return pbe;
+}
+
+/**
+ * snapshot_read_next - used for reading the system memory snapshot.
+ *
+ * On the first call to it @handle should point to a zeroed
+ * snapshot_handle structure. The structure gets updated and a pointer
+ * to it should be passed to this function every next time.
+ *
+ * The @count parameter should contain the number of bytes the caller
+ * wants to read from the snapshot. It must not be zero.
+ *
+ * On success the function returns a positive number. Then, the caller
+ * is allowed to read up to the returned number of bytes from the memory
+ * location computed by the data_of() macro. The number returned
+ * may be smaller than @count, but this only happens if the read would
+ * cross a page boundary otherwise.
+ *
+ * The function returns 0 to indicate the end of data stream condition,
+ * and a negative number is returned on error. In such cases the
+ * structure pointed to by @handle is not updated and should not be used
+ * any more.
+ */
+
+int snapshot_read_next(struct snapshot_handle *handle, size_t count)
+{
+ if (handle->page > nr_meta_pages + nr_copy_pages)
+ return 0;
+ if (!buffer) {
+ /* This makes the buffer be freed by swsusp_free() */
+ buffer = alloc_image_page(GFP_ATOMIC, 0);
+ if (!buffer)
+ return -ENOMEM;
+ }
+ if (!handle->offset) {
+ init_header((struct swsusp_info *)buffer);
+ handle->buffer = buffer;
+ handle->pbe = pagedir_nosave;
+ }
+ if (handle->prev < handle->page) {
+ if (handle->page <= nr_meta_pages) {
+ handle->pbe = pack_orig_addresses(buffer, handle->pbe);
+ if (!handle->pbe)
+ handle->pbe = pagedir_nosave;
+ } else {
+ handle->buffer = (void *)handle->pbe->address;
+ handle->pbe = handle->pbe->next;
+ }
+ handle->prev = handle->page;
+ }
+ handle->buf_offset = handle->page_offset;
+ if (handle->page_offset + count >= PAGE_SIZE) {
+ count = PAGE_SIZE - handle->page_offset;
+ handle->page_offset = 0;
+ handle->page++;
+ } else {
+ handle->page_offset += count;
+ }
+ handle->offset += count;
+ return count;
+}
+
+/**
+ * mark_unsafe_pages - mark the pages that cannot be used for storing
+ * the image during resume, because they conflict with the pages that
+ * had been used before suspend
+ */
+
+static int mark_unsafe_pages(struct pbe *pblist)
+{
+ struct zone *zone;
+ unsigned long zone_pfn;
+ struct pbe *p;
+
+ if (!pblist) /* a sanity check */
+ return -EINVAL;
+
+ /* Clear page flags */
+ for_each_zone (zone) {
+ for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
+ if (pfn_valid(zone_pfn + zone->zone_start_pfn))
+ ClearPageNosaveFree(pfn_to_page(zone_pfn +
+ zone->zone_start_pfn));
+ }
+
+ /* Mark orig addresses */
+ for_each_pbe (p, pblist) {
+ if (virt_addr_valid(p->orig_address))
+ SetPageNosaveFree(virt_to_page(p->orig_address));
+ else
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static void copy_page_backup_list(struct pbe *dst, struct pbe *src)
+{
+ /* We assume both lists contain the same number of elements */
+ while (src) {
+ dst->orig_address = src->orig_address;
+ dst = dst->next;
+ src = src->next;
+ }
+}
+
+static int check_header(struct swsusp_info *info)
+{
+ char *reason = NULL;
+
+ if (info->version_code != LINUX_VERSION_CODE)
+ reason = "kernel version";
+ if (info->num_physpages != num_physpages)
+ reason = "memory size";
+ if (strcmp(info->uts.sysname,system_utsname.sysname))
+ reason = "system type";
+ if (strcmp(info->uts.release,system_utsname.release))
+ reason = "kernel release";
+ if (strcmp(info->uts.version,system_utsname.version))
+ reason = "version";
+ if (strcmp(info->uts.machine,system_utsname.machine))
+ reason = "machine";
+ if (reason) {
+ printk(KERN_ERR "swsusp: Resume mismatch: %s\n", reason);
+ return -EPERM;
+ }
+ return 0;
+}
+
+/**
+ * load header - check the image header and copy data from it
+ */
+
+static int load_header(struct snapshot_handle *handle,
+ struct swsusp_info *info)
+{
+ int error;
+ struct pbe *pblist;
+
+ error = check_header(info);
+ if (!error) {
+ pblist = alloc_pagedir(info->image_pages, GFP_ATOMIC, 0);
+ if (!pblist)
+ return -ENOMEM;
+ pagedir_nosave = pblist;
+ handle->pbe = pblist;
+ nr_copy_pages = info->image_pages;
+ nr_meta_pages = info->pages - info->image_pages - 1;
+ }
+ return error;
+}
+
+/**
+ * unpack_orig_addresses - copy the elements of @buf[] (1 page) to
+ * the PBEs in the list starting at @pbe
+ */
+
+static inline struct pbe *unpack_orig_addresses(unsigned long *buf,
+ struct pbe *pbe)
+{
+ int j;
+
+ for (j = 0; j < PAGE_SIZE / sizeof(long) && pbe; j++) {
+ pbe->orig_address = buf[j];
+ pbe = pbe->next;
+ }
+ return pbe;
+}
+
+/**
+ * create_image - use metadata contained in the PBE list
+ * pointed to by pagedir_nosave to mark the pages that will
+ * be overwritten in the process of restoring the system
+ * memory state from the image and allocate memory for
+ * the image avoiding these pages
+ */
+
+static int create_image(struct snapshot_handle *handle)
+{
+ int error = 0;
+ struct pbe *p, *pblist;
+
+ p = pagedir_nosave;
+ error = mark_unsafe_pages(p);
+ if (!error) {
+ pblist = alloc_pagedir(nr_copy_pages, GFP_ATOMIC, 1);
+ if (pblist)
+ copy_page_backup_list(pblist, p);
+ free_pagedir(p);
+ if (!pblist)
+ error = -ENOMEM;
+ }
+ if (!error)
+ error = alloc_data_pages(pblist, GFP_ATOMIC, 1);
+ if (!error) {
+ release_eaten_pages();
+ pagedir_nosave = pblist;
+ } else {
+ pagedir_nosave = NULL;
+ handle->pbe = NULL;
+ nr_copy_pages = 0;
+ nr_meta_pages = 0;
+ }
+ return error;
+}
+
+/**
+ * snapshot_write_next - used for writing the system memory snapshot.
+ *
+ * On the first call to it @handle should point to a zeroed
+ * snapshot_handle structure. The structure gets updated and a pointer
+ * to it should be passed to this function every next time.
+ *
+ * The @count parameter should contain the number of bytes the caller
+ * wants to write to the image. It must not be zero.
+ *
+ * On success the function returns a positive number. Then, the caller
+ * is allowed to write up to the returned number of bytes to the memory
+ * location computed by the data_of() macro. The number returned
+ * may be smaller than @count, but this only happens if the write would
+ * cross a page boundary otherwise.
+ *
+ * The function returns 0 to indicate the "end of file" condition,
+ * and a negative number is returned on error. In such cases the
+ * structure pointed to by @handle is not updated and should not be used
+ * any more.
+ */
+
+int snapshot_write_next(struct snapshot_handle *handle, size_t count)
+{
+ int error = 0;
+
+ if (handle->prev && handle->page > nr_meta_pages + nr_copy_pages)
+ return 0;
+ if (!buffer) {
+ /* This makes the buffer be freed by swsusp_free() */
+ buffer = alloc_image_page(GFP_ATOMIC, 0);
+ if (!buffer)
+ return -ENOMEM;
+ }
+ if (!handle->offset)
+ handle->buffer = buffer;
+ if (handle->prev < handle->page) {
+ if (!handle->prev) {
+ error = load_header(handle, (struct swsusp_info *)buffer);
+ if (error)
+ return error;
+ } else if (handle->prev <= nr_meta_pages) {
+ handle->pbe = unpack_orig_addresses(buffer, handle->pbe);
+ if (!handle->pbe) {
+ error = create_image(handle);
+ if (error)
+ return error;
+ handle->pbe = pagedir_nosave;
+ handle->buffer = (void *)handle->pbe->address;
+ }
+ } else {
+ handle->pbe = handle->pbe->next;
+ handle->buffer = (void *)handle->pbe->address;
+ }
+ handle->prev = handle->page;
+ }
+ handle->buf_offset = handle->page_offset;
+ if (handle->page_offset + count >= PAGE_SIZE) {
+ count = PAGE_SIZE - handle->page_offset;
+ handle->page_offset = 0;
+ handle->page++;
+ } else {
+ handle->page_offset += count;
+ }
+ handle->offset += count;
+ return count;
+}
+
+int snapshot_image_loaded(struct snapshot_handle *handle)
+{
+ return !(!handle->pbe || handle->pbe->next || !nr_copy_pages ||
+ handle->page <= nr_meta_pages + nr_copy_pages);
+}
diff --git a/kernel/power/swap.c b/kernel/power/swap.c
new file mode 100644
index 000000000000..9177f3f73a6c
--- /dev/null
+++ b/kernel/power/swap.c
@@ -0,0 +1,544 @@
+/*
+ * linux/kernel/power/swap.c
+ *
+ * This file provides functions for reading the suspend image from
+ * and writing it to a swap partition.
+ *
+ * Copyright (C) 1998,2001-2005 Pavel Machek <pavel@suse.cz>
+ * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
+ *
+ * This file is released under the GPLv2.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/smp_lock.h>
+#include <linux/file.h>
+#include <linux/utsname.h>
+#include <linux/version.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+#include <linux/genhd.h>
+#include <linux/device.h>
+#include <linux/buffer_head.h>
+#include <linux/bio.h>
+#include <linux/swap.h>
+#include <linux/swapops.h>
+#include <linux/pm.h>
+
+#include "power.h"
+
+extern char resume_file[];
+
+#define SWSUSP_SIG "S1SUSPEND"
+
+static struct swsusp_header {
+ char reserved[PAGE_SIZE - 20 - sizeof(swp_entry_t)];
+ swp_entry_t image;
+ char orig_sig[10];
+ char sig[10];
+} __attribute__((packed, aligned(PAGE_SIZE))) swsusp_header;
+
+/*
+ * Saving part...
+ */
+
+static unsigned short root_swap = 0xffff;
+
+static int mark_swapfiles(swp_entry_t start)
+{
+ int error;
+
+ rw_swap_page_sync(READ,
+ swp_entry(root_swap, 0),
+ virt_to_page((unsigned long)&swsusp_header));
+ if (!memcmp("SWAP-SPACE",swsusp_header.sig, 10) ||
+ !memcmp("SWAPSPACE2",swsusp_header.sig, 10)) {
+ memcpy(swsusp_header.orig_sig,swsusp_header.sig, 10);
+ memcpy(swsusp_header.sig,SWSUSP_SIG, 10);
+ swsusp_header.image = start;
+ error = rw_swap_page_sync(WRITE,
+ swp_entry(root_swap, 0),
+ virt_to_page((unsigned long)
+ &swsusp_header));
+ } else {
+ pr_debug("swsusp: Partition is not swap space.\n");
+ error = -ENODEV;
+ }
+ return error;
+}
+
+/**
+ * swsusp_swap_check - check if the resume device is a swap device
+ * and get its index (if so)
+ */
+
+static int swsusp_swap_check(void) /* This is called before saving image */
+{
+ int res = swap_type_of(swsusp_resume_device);
+
+ if (res >= 0) {
+ root_swap = res;
+ return 0;
+ }
+ return res;
+}
+
+/**
+ * write_page - Write one page to given swap location.
+ * @buf: Address we're writing.
+ * @offset: Offset of the swap page we're writing to.
+ */
+
+static int write_page(void *buf, unsigned long offset)
+{
+ swp_entry_t entry;
+ int error = -ENOSPC;
+
+ if (offset) {
+ entry = swp_entry(root_swap, offset);
+ error = rw_swap_page_sync(WRITE, entry, virt_to_page(buf));
+ }
+ return error;
+}
+
+/*
+ * The swap map is a data structure used for keeping track of each page
+ * written to a swap partition. It consists of many swap_map_page
+ * structures that contain each an array of MAP_PAGE_SIZE swap entries.
+ * These structures are stored on the swap and linked together with the
+ * help of the .next_swap member.
+ *
+ * The swap map is created during suspend. The swap map pages are
+ * allocated and populated one at a time, so we only need one memory
+ * page to set up the entire structure.
+ *
+ * During resume we also only need to use one swap_map_page structure
+ * at a time.
+ */
+
+#define MAP_PAGE_ENTRIES (PAGE_SIZE / sizeof(long) - 1)
+
+struct swap_map_page {
+ unsigned long entries[MAP_PAGE_ENTRIES];
+ unsigned long next_swap;
+};
+
+/**
+ * The swap_map_handle structure is used for handling swap in
+ * a file-alike way
+ */
+
+struct swap_map_handle {
+ struct swap_map_page *cur;
+ unsigned long cur_swap;
+ struct bitmap_page *bitmap;
+ unsigned int k;
+};
+
+static void release_swap_writer(struct swap_map_handle *handle)
+{
+ if (handle->cur)
+ free_page((unsigned long)handle->cur);
+ handle->cur = NULL;
+ if (handle->bitmap)
+ free_bitmap(handle->bitmap);
+ handle->bitmap = NULL;
+}
+
+static int get_swap_writer(struct swap_map_handle *handle)
+{
+ handle->cur = (struct swap_map_page *)get_zeroed_page(GFP_KERNEL);
+ if (!handle->cur)
+ return -ENOMEM;
+ handle->bitmap = alloc_bitmap(count_swap_pages(root_swap, 0));
+ if (!handle->bitmap) {
+ release_swap_writer(handle);
+ return -ENOMEM;
+ }
+ handle->cur_swap = alloc_swap_page(root_swap, handle->bitmap);
+ if (!handle->cur_swap) {
+ release_swap_writer(handle);
+ return -ENOSPC;
+ }
+ handle->k = 0;
+ return 0;
+}
+
+static int swap_write_page(struct swap_map_handle *handle, void *buf)
+{
+ int error;
+ unsigned long offset;
+
+ if (!handle->cur)
+ return -EINVAL;
+ offset = alloc_swap_page(root_swap, handle->bitmap);
+ error = write_page(buf, offset);
+ if (error)
+ return error;
+ handle->cur->entries[handle->k++] = offset;
+ if (handle->k >= MAP_PAGE_ENTRIES) {
+ offset = alloc_swap_page(root_swap, handle->bitmap);
+ if (!offset)
+ return -ENOSPC;
+ handle->cur->next_swap = offset;
+ error = write_page(handle->cur, handle->cur_swap);
+ if (error)
+ return error;
+ memset(handle->cur, 0, PAGE_SIZE);
+ handle->cur_swap = offset;
+ handle->k = 0;
+ }
+ return 0;
+}
+
+static int flush_swap_writer(struct swap_map_handle *handle)
+{
+ if (handle->cur && handle->cur_swap)
+ return write_page(handle->cur, handle->cur_swap);
+ else
+ return -EINVAL;
+}
+
+/**
+ * save_image - save the suspend image data
+ */
+
+static int save_image(struct swap_map_handle *handle,
+ struct snapshot_handle *snapshot,
+ unsigned int nr_pages)
+{
+ unsigned int m;
+ int ret;
+ int error = 0;
+
+ printk("Saving image data pages (%u pages) ... ", nr_pages);
+ m = nr_pages / 100;
+ if (!m)
+ m = 1;
+ nr_pages = 0;
+ do {
+ ret = snapshot_read_next(snapshot, PAGE_SIZE);
+ if (ret > 0) {
+ error = swap_write_page(handle, data_of(*snapshot));
+ if (error)
+ break;
+ if (!(nr_pages % m))
+ printk("\b\b\b\b%3d%%", nr_pages / m);
+ nr_pages++;
+ }
+ } while (ret > 0);
+ if (!error)
+ printk("\b\b\b\bdone\n");
+ return error;
+}
+
+/**
+ * enough_swap - Make sure we have enough swap to save the image.
+ *
+ * Returns TRUE or FALSE after checking the total amount of swap
+ * space avaiable from the resume partition.
+ */
+
+static int enough_swap(unsigned int nr_pages)
+{
+ unsigned int free_swap = count_swap_pages(root_swap, 1);
+
+ pr_debug("swsusp: free swap pages: %u\n", free_swap);
+ return free_swap > (nr_pages + PAGES_FOR_IO +
+ (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
+}
+
+/**
+ * swsusp_write - Write entire image and metadata.
+ *
+ * It is important _NOT_ to umount filesystems at this point. We want
+ * them synced (in case something goes wrong) but we DO not want to mark
+ * filesystem clean: it is not. (And it does not matter, if we resume
+ * correctly, we'll mark system clean, anyway.)
+ */
+
+int swsusp_write(void)
+{
+ struct swap_map_handle handle;
+ struct snapshot_handle snapshot;
+ struct swsusp_info *header;
+ unsigned long start;
+ int error;
+
+ if ((error = swsusp_swap_check())) {
+ printk(KERN_ERR "swsusp: Cannot find swap device, try swapon -a.\n");
+ return error;
+ }
+ memset(&snapshot, 0, sizeof(struct snapshot_handle));
+ error = snapshot_read_next(&snapshot, PAGE_SIZE);
+ if (error < PAGE_SIZE)
+ return error < 0 ? error : -EFAULT;
+ header = (struct swsusp_info *)data_of(snapshot);
+ if (!enough_swap(header->pages)) {
+ printk(KERN_ERR "swsusp: Not enough free swap\n");
+ return -ENOSPC;
+ }
+ error = get_swap_writer(&handle);
+ if (!error) {
+ start = handle.cur_swap;
+ error = swap_write_page(&handle, header);
+ }
+ if (!error)
+ error = save_image(&handle, &snapshot, header->pages - 1);
+ if (!error) {
+ flush_swap_writer(&handle);
+ printk("S");
+ error = mark_swapfiles(swp_entry(root_swap, start));
+ printk("|\n");
+ }
+ if (error)
+ free_all_swap_pages(root_swap, handle.bitmap);
+ release_swap_writer(&handle);
+ return error;
+}
+
+/*
+ * Using bio to read from swap.
+ * This code requires a bit more work than just using buffer heads
+ * but, it is the recommended way for 2.5/2.6.
+ * The following are to signal the beginning and end of I/O. Bios
+ * finish asynchronously, while we want them to happen synchronously.
+ * A simple atomic_t, and a wait loop take care of this problem.
+ */
+
+static atomic_t io_done = ATOMIC_INIT(0);
+
+static int end_io(struct bio *bio, unsigned int num, int err)
+{
+ if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
+ panic("I/O error reading memory image");
+ atomic_set(&io_done, 0);
+ return 0;
+}
+
+static struct block_device *resume_bdev;
+
+/**
+ * submit - submit BIO request.
+ * @rw: READ or WRITE.
+ * @off physical offset of page.
+ * @page: page we're reading or writing.
+ *
+ * Straight from the textbook - allocate and initialize the bio.
+ * If we're writing, make sure the page is marked as dirty.
+ * Then submit it and wait.
+ */
+
+static int submit(int rw, pgoff_t page_off, void *page)
+{
+ int error = 0;
+ struct bio *bio;
+
+ bio = bio_alloc(GFP_ATOMIC, 1);
+ if (!bio)
+ return -ENOMEM;
+ bio->bi_sector = page_off * (PAGE_SIZE >> 9);
+ bio->bi_bdev = resume_bdev;
+ bio->bi_end_io = end_io;
+
+ if (bio_add_page(bio, virt_to_page(page), PAGE_SIZE, 0) < PAGE_SIZE) {
+ printk("swsusp: ERROR: adding page to bio at %ld\n",page_off);
+ error = -EFAULT;
+ goto Done;
+ }
+
+ atomic_set(&io_done, 1);
+ submit_bio(rw | (1 << BIO_RW_SYNC), bio);
+ while (atomic_read(&io_done))
+ yield();
+ if (rw == READ)
+ bio_set_pages_dirty(bio);
+ Done:
+ bio_put(bio);
+ return error;
+}
+
+static int bio_read_page(pgoff_t page_off, void *page)
+{
+ return submit(READ, page_off, page);
+}
+
+static int bio_write_page(pgoff_t page_off, void *page)
+{
+ return submit(WRITE, page_off, page);
+}
+
+/**
+ * The following functions allow us to read data using a swap map
+ * in a file-alike way
+ */
+
+static void release_swap_reader(struct swap_map_handle *handle)
+{
+ if (handle->cur)
+ free_page((unsigned long)handle->cur);
+ handle->cur = NULL;
+}
+
+static int get_swap_reader(struct swap_map_handle *handle,
+ swp_entry_t start)
+{
+ int error;
+
+ if (!swp_offset(start))
+ return -EINVAL;
+ handle->cur = (struct swap_map_page *)get_zeroed_page(GFP_ATOMIC);
+ if (!handle->cur)
+ return -ENOMEM;
+ error = bio_read_page(swp_offset(start), handle->cur);
+ if (error) {
+ release_swap_reader(handle);
+ return error;
+ }
+ handle->k = 0;
+ return 0;
+}
+
+static int swap_read_page(struct swap_map_handle *handle, void *buf)
+{
+ unsigned long offset;
+ int error;
+
+ if (!handle->cur)
+ return -EINVAL;
+ offset = handle->cur->entries[handle->k];
+ if (!offset)
+ return -EFAULT;
+ error = bio_read_page(offset, buf);
+ if (error)
+ return error;
+ if (++handle->k >= MAP_PAGE_ENTRIES) {
+ handle->k = 0;
+ offset = handle->cur->next_swap;
+ if (!offset)
+ release_swap_reader(handle);
+ else
+ error = bio_read_page(offset, handle->cur);
+ }
+ return error;
+}
+
+/**
+ * load_image - load the image using the swap map handle
+ * @handle and the snapshot handle @snapshot
+ * (assume there are @nr_pages pages to load)
+ */
+
+static int load_image(struct swap_map_handle *handle,
+ struct snapshot_handle *snapshot,
+ unsigned int nr_pages)
+{
+ unsigned int m;
+ int ret;
+ int error = 0;
+
+ printk("Loading image data pages (%u pages) ... ", nr_pages);
+ m = nr_pages / 100;
+ if (!m)
+ m = 1;
+ nr_pages = 0;
+ do {
+ ret = snapshot_write_next(snapshot, PAGE_SIZE);
+ if (ret > 0) {
+ error = swap_read_page(handle, data_of(*snapshot));
+ if (error)
+ break;
+ if (!(nr_pages % m))
+ printk("\b\b\b\b%3d%%", nr_pages / m);
+ nr_pages++;
+ }
+ } while (ret > 0);
+ if (!error)
+ printk("\b\b\b\bdone\n");
+ if (!snapshot_image_loaded(snapshot))
+ error = -ENODATA;
+ return error;
+}
+
+int swsusp_read(void)
+{
+ int error;
+ struct swap_map_handle handle;
+ struct snapshot_handle snapshot;
+ struct swsusp_info *header;
+
+ if (IS_ERR(resume_bdev)) {
+ pr_debug("swsusp: block device not initialised\n");
+ return PTR_ERR(resume_bdev);
+ }
+
+ memset(&snapshot, 0, sizeof(struct snapshot_handle));
+ error = snapshot_write_next(&snapshot, PAGE_SIZE);
+ if (error < PAGE_SIZE)
+ return error < 0 ? error : -EFAULT;
+ header = (struct swsusp_info *)data_of(snapshot);
+ error = get_swap_reader(&handle, swsusp_header.image);
+ if (!error)
+ error = swap_read_page(&handle, header);
+ if (!error)
+ error = load_image(&handle, &snapshot, header->pages - 1);
+ release_swap_reader(&handle);
+
+ blkdev_put(resume_bdev);
+
+ if (!error)
+ pr_debug("swsusp: Reading resume file was successful\n");
+ else
+ pr_debug("swsusp: Error %d resuming\n", error);
+ return error;
+}
+
+/**
+ * swsusp_check - Check for swsusp signature in the resume device
+ */
+
+int swsusp_check(void)
+{
+ int error;
+
+ resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ);
+ if (!IS_ERR(resume_bdev)) {
+ set_blocksize(resume_bdev, PAGE_SIZE);
+ memset(&swsusp_header, 0, sizeof(swsusp_header));
+ if ((error = bio_read_page(0, &swsusp_header)))
+ return error;
+ if (!memcmp(SWSUSP_SIG, swsusp_header.sig, 10)) {
+ memcpy(swsusp_header.sig, swsusp_header.orig_sig, 10);
+ /* Reset swap signature now */
+ error = bio_write_page(0, &swsusp_header);
+ } else {
+ return -EINVAL;
+ }
+ if (error)
+ blkdev_put(resume_bdev);
+ else
+ pr_debug("swsusp: Signature found, resuming\n");
+ } else {
+ error = PTR_ERR(resume_bdev);
+ }
+
+ if (error)
+ pr_debug("swsusp: Error %d check for resume file\n", error);
+
+ return error;
+}
+
+/**
+ * swsusp_close - close swap device.
+ */
+
+void swsusp_close(void)
+{
+ if (IS_ERR(resume_bdev)) {
+ pr_debug("swsusp: block device not initialised\n");
+ return;
+ }
+
+ blkdev_put(resume_bdev);
+}
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index 2d9d08f72f76..c4016cbbd3e0 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -31,41 +31,24 @@
* Fixed runaway init
*
* Rafael J. Wysocki <rjw@sisk.pl>
- * Added the swap map data structure and reworked the handling of swap
+ * Reworked the freeing of memory and the handling of swap
*
* More state savers are welcome. Especially for the scsi layer...
*
* For TODOs,FIXMEs also look in Documentation/power/swsusp.txt
*/
-#include <linux/module.h>
#include <linux/mm.h>
#include <linux/suspend.h>
-#include <linux/smp_lock.h>
-#include <linux/file.h>
-#include <linux/utsname.h>
-#include <linux/version.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
#include <linux/spinlock.h>
-#include <linux/genhd.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/swap.h>
#include <linux/pm.h>
-#include <linux/device.h>
-#include <linux/buffer_head.h>
#include <linux/swapops.h>
#include <linux/bootmem.h>
#include <linux/syscalls.h>
#include <linux/highmem.h>
-#include <linux/bio.h>
-
-#include <asm/uaccess.h>
-#include <asm/mmu_context.h>
-#include <asm/pgtable.h>
-#include <asm/tlbflush.h>
-#include <asm/io.h>
#include "power.h"
@@ -77,6 +60,8 @@
*/
unsigned long image_size = 500 * 1024 * 1024;
+int in_suspend __nosavedata = 0;
+
#ifdef CONFIG_HIGHMEM
unsigned int count_highmem_pages(void);
int save_highmem(void);
@@ -87,471 +72,97 @@ static int restore_highmem(void) { return 0; }
static unsigned int count_highmem_pages(void) { return 0; }
#endif
-extern char resume_file[];
-
-#define SWSUSP_SIG "S1SUSPEND"
-
-static struct swsusp_header {
- char reserved[PAGE_SIZE - 20 - sizeof(swp_entry_t)];
- swp_entry_t image;
- char orig_sig[10];
- char sig[10];
-} __attribute__((packed, aligned(PAGE_SIZE))) swsusp_header;
-
-static struct swsusp_info swsusp_info;
-
-/*
- * Saving part...
- */
-
-static unsigned short root_swap = 0xffff;
-
-static int mark_swapfiles(swp_entry_t start)
-{
- int error;
-
- rw_swap_page_sync(READ,
- swp_entry(root_swap, 0),
- virt_to_page((unsigned long)&swsusp_header));
- if (!memcmp("SWAP-SPACE",swsusp_header.sig, 10) ||
- !memcmp("SWAPSPACE2",swsusp_header.sig, 10)) {
- memcpy(swsusp_header.orig_sig,swsusp_header.sig, 10);
- memcpy(swsusp_header.sig,SWSUSP_SIG, 10);
- swsusp_header.image = start;
- error = rw_swap_page_sync(WRITE,
- swp_entry(root_swap, 0),
- virt_to_page((unsigned long)
- &swsusp_header));
- } else {
- pr_debug("swsusp: Partition is not swap space.\n");
- error = -ENODEV;
- }
- return error;
-}
-
-/*
- * Check whether the swap device is the specified resume
- * device, irrespective of whether they are specified by
- * identical names.
- *
- * (Thus, device inode aliasing is allowed. You can say /dev/hda4
- * instead of /dev/ide/host0/bus0/target0/lun0/part4 [if using devfs]
- * and they'll be considered the same device. This is *necessary* for
- * devfs, since the resume code can only recognize the form /dev/hda4,
- * but the suspend code would see the long name.)
- */
-static inline int is_resume_device(const struct swap_info_struct *swap_info)
-{
- struct file *file = swap_info->swap_file;
- struct inode *inode = file->f_dentry->d_inode;
-
- return S_ISBLK(inode->i_mode) &&
- swsusp_resume_device == MKDEV(imajor(inode), iminor(inode));
-}
-
-static int swsusp_swap_check(void) /* This is called before saving image */
-{
- int i;
-
- spin_lock(&swap_lock);
- for (i = 0; i < MAX_SWAPFILES; i++) {
- if (!(swap_info[i].flags & SWP_WRITEOK))
- continue;
- if (!swsusp_resume_device || is_resume_device(swap_info + i)) {
- spin_unlock(&swap_lock);
- root_swap = i;
- return 0;
- }
- }
- spin_unlock(&swap_lock);
- return -ENODEV;
-}
-
-/**
- * write_page - Write one page to a fresh swap location.
- * @addr: Address we're writing.
- * @loc: Place to store the entry we used.
- *
- * Allocate a new swap entry and 'sync' it. Note we discard -EIO
- * errors. That is an artifact left over from swsusp. It did not
- * check the return of rw_swap_page_sync() at all, since most pages
- * written back to swap would return -EIO.
- * This is a partial improvement, since we will at least return other
- * errors, though we need to eventually fix the damn code.
- */
-static int write_page(unsigned long addr, swp_entry_t *loc)
-{
- swp_entry_t entry;
- int error = -ENOSPC;
-
- entry = get_swap_page_of_type(root_swap);
- if (swp_offset(entry)) {
- error = rw_swap_page_sync(WRITE, entry, virt_to_page(addr));
- if (!error || error == -EIO)
- *loc = entry;
- }
- return error;
-}
-
/**
- * Swap map-handling functions
- *
- * The swap map is a data structure used for keeping track of each page
- * written to the swap. It consists of many swap_map_page structures
- * that contain each an array of MAP_PAGE_SIZE swap entries.
- * These structures are linked together with the help of either the
- * .next (in memory) or the .next_swap (in swap) member.
+ * The following functions are used for tracing the allocated
+ * swap pages, so that they can be freed in case of an error.
*
- * The swap map is created during suspend. At that time we need to keep
- * it in memory, because we have to free all of the allocated swap
- * entries if an error occurs. The memory needed is preallocated
- * so that we know in advance if there's enough of it.
- *
- * The first swap_map_page structure is filled with the swap entries that
- * correspond to the first MAP_PAGE_SIZE data pages written to swap and
- * so on. After the all of the data pages have been written, the order
- * of the swap_map_page structures in the map is reversed so that they
- * can be read from swap in the original order. This causes the data
- * pages to be loaded in exactly the same order in which they have been
- * saved.
- *
- * During resume we only need to use one swap_map_page structure
- * at a time, which means that we only need to use two memory pages for
- * reading the image - one for reading the swap_map_page structures
- * and the second for reading the data pages from swap.
+ * The functions operate on a linked bitmap structure defined
+ * in power.h
*/
-#define MAP_PAGE_SIZE ((PAGE_SIZE - sizeof(swp_entry_t) - sizeof(void *)) \
- / sizeof(swp_entry_t))
-
-struct swap_map_page {
- swp_entry_t entries[MAP_PAGE_SIZE];
- swp_entry_t next_swap;
- struct swap_map_page *next;
-};
-
-static inline void free_swap_map(struct swap_map_page *swap_map)
+void free_bitmap(struct bitmap_page *bitmap)
{
- struct swap_map_page *swp;
+ struct bitmap_page *bp;
- while (swap_map) {
- swp = swap_map->next;
- free_page((unsigned long)swap_map);
- swap_map = swp;
+ while (bitmap) {
+ bp = bitmap->next;
+ free_page((unsigned long)bitmap);
+ bitmap = bp;
}
}
-static struct swap_map_page *alloc_swap_map(unsigned int nr_pages)
+struct bitmap_page *alloc_bitmap(unsigned int nr_bits)
{
- struct swap_map_page *swap_map, *swp;
- unsigned n = 0;
+ struct bitmap_page *bitmap, *bp;
+ unsigned int n;
- if (!nr_pages)
+ if (!nr_bits)
return NULL;
- pr_debug("alloc_swap_map(): nr_pages = %d\n", nr_pages);
- swap_map = (struct swap_map_page *)get_zeroed_page(GFP_ATOMIC);
- swp = swap_map;
- for (n = MAP_PAGE_SIZE; n < nr_pages; n += MAP_PAGE_SIZE) {
- swp->next = (struct swap_map_page *)get_zeroed_page(GFP_ATOMIC);
- swp = swp->next;
- if (!swp) {
- free_swap_map(swap_map);
+ bitmap = (struct bitmap_page *)get_zeroed_page(GFP_KERNEL);
+ bp = bitmap;
+ for (n = BITMAP_PAGE_BITS; n < nr_bits; n += BITMAP_PAGE_BITS) {
+ bp->next = (struct bitmap_page *)get_zeroed_page(GFP_KERNEL);
+ bp = bp->next;
+ if (!bp) {
+ free_bitmap(bitmap);
return NULL;
}
}
- return swap_map;
+ return bitmap;
}
-/**
- * reverse_swap_map - reverse the order of pages in the swap map
- * @swap_map
- */
-
-static inline struct swap_map_page *reverse_swap_map(struct swap_map_page *swap_map)
-{
- struct swap_map_page *prev, *next;
-
- prev = NULL;
- while (swap_map) {
- next = swap_map->next;
- swap_map->next = prev;
- prev = swap_map;
- swap_map = next;
- }
- return prev;
-}
-
-/**
- * free_swap_map_entries - free the swap entries allocated to store
- * the swap map @swap_map (this is only called in case of an error)
- */
-static inline void free_swap_map_entries(struct swap_map_page *swap_map)
-{
- while (swap_map) {
- if (swap_map->next_swap.val)
- swap_free(swap_map->next_swap);
- swap_map = swap_map->next;
- }
-}
-
-/**
- * save_swap_map - save the swap map used for tracing the data pages
- * stored in the swap
- */
-
-static int save_swap_map(struct swap_map_page *swap_map, swp_entry_t *start)
-{
- swp_entry_t entry = (swp_entry_t){0};
- int error;
-
- while (swap_map) {
- swap_map->next_swap = entry;
- if ((error = write_page((unsigned long)swap_map, &entry)))
- return error;
- swap_map = swap_map->next;
- }
- *start = entry;
- return 0;
-}
-
-/**
- * free_image_entries - free the swap entries allocated to store
- * the image data pages (this is only called in case of an error)
- */
-
-static inline void free_image_entries(struct swap_map_page *swp)
+static int bitmap_set(struct bitmap_page *bitmap, unsigned long bit)
{
- unsigned k;
+ unsigned int n;
- while (swp) {
- for (k = 0; k < MAP_PAGE_SIZE; k++)
- if (swp->entries[k].val)
- swap_free(swp->entries[k]);
- swp = swp->next;
+ n = BITMAP_PAGE_BITS;
+ while (bitmap && n <= bit) {
+ n += BITMAP_PAGE_BITS;
+ bitmap = bitmap->next;
}
-}
-
-/**
- * The swap_map_handle structure is used for handling the swap map in
- * a file-alike way
- */
-
-struct swap_map_handle {
- struct swap_map_page *cur;
- unsigned int k;
-};
-
-static inline void init_swap_map_handle(struct swap_map_handle *handle,
- struct swap_map_page *map)
-{
- handle->cur = map;
- handle->k = 0;
-}
-
-static inline int swap_map_write_page(struct swap_map_handle *handle,
- unsigned long addr)
-{
- int error;
-
- error = write_page(addr, handle->cur->entries + handle->k);
- if (error)
- return error;
- if (++handle->k >= MAP_PAGE_SIZE) {
- handle->cur = handle->cur->next;
- handle->k = 0;
+ if (!bitmap)
+ return -EINVAL;
+ n -= BITMAP_PAGE_BITS;
+ bit -= n;
+ n = 0;
+ while (bit >= BITS_PER_CHUNK) {
+ bit -= BITS_PER_CHUNK;
+ n++;
}
+ bitmap->chunks[n] |= (1UL << bit);
return 0;
}
-/**
- * save_image_data - save the data pages pointed to by the PBEs
- * from the list @pblist using the swap map handle @handle
- * (assume there are @nr_pages data pages to save)
- */
-
-static int save_image_data(struct pbe *pblist,
- struct swap_map_handle *handle,
- unsigned int nr_pages)
-{
- unsigned int m;
- struct pbe *p;
- int error = 0;
-
- printk("Saving image data pages (%u pages) ... ", nr_pages);
- m = nr_pages / 100;
- if (!m)
- m = 1;
- nr_pages = 0;
- for_each_pbe (p, pblist) {
- error = swap_map_write_page(handle, p->address);
- if (error)
- break;
- if (!(nr_pages % m))
- printk("\b\b\b\b%3d%%", nr_pages / m);
- nr_pages++;
- }
- if (!error)
- printk("\b\b\b\bdone\n");
- return error;
-}
-
-static void dump_info(void)
-{
- pr_debug(" swsusp: Version: %u\n",swsusp_info.version_code);
- pr_debug(" swsusp: Num Pages: %ld\n",swsusp_info.num_physpages);
- pr_debug(" swsusp: UTS Sys: %s\n",swsusp_info.uts.sysname);
- pr_debug(" swsusp: UTS Node: %s\n",swsusp_info.uts.nodename);
- pr_debug(" swsusp: UTS Release: %s\n",swsusp_info.uts.release);
- pr_debug(" swsusp: UTS Version: %s\n",swsusp_info.uts.version);
- pr_debug(" swsusp: UTS Machine: %s\n",swsusp_info.uts.machine);
- pr_debug(" swsusp: UTS Domain: %s\n",swsusp_info.uts.domainname);
- pr_debug(" swsusp: CPUs: %d\n",swsusp_info.cpus);
- pr_debug(" swsusp: Image: %ld Pages\n",swsusp_info.image_pages);
- pr_debug(" swsusp: Total: %ld Pages\n", swsusp_info.pages);
-}
-
-static void init_header(unsigned int nr_pages)
-{
- memset(&swsusp_info, 0, sizeof(swsusp_info));
- swsusp_info.version_code = LINUX_VERSION_CODE;
- swsusp_info.num_physpages = num_physpages;
- memcpy(&swsusp_info.uts, &system_utsname, sizeof(system_utsname));
-
- swsusp_info.cpus = num_online_cpus();
- swsusp_info.image_pages = nr_pages;
- swsusp_info.pages = nr_pages +
- ((nr_pages * sizeof(long) + PAGE_SIZE - 1) >> PAGE_SHIFT) + 1;
-}
-
-/**
- * pack_orig_addresses - the .orig_address fields of the PBEs from the
- * list starting at @pbe are stored in the array @buf[] (1 page)
- */
-
-static inline struct pbe *pack_orig_addresses(unsigned long *buf,
- struct pbe *pbe)
-{
- int j;
-
- for (j = 0; j < PAGE_SIZE / sizeof(long) && pbe; j++) {
- buf[j] = pbe->orig_address;
- pbe = pbe->next;
- }
- if (!pbe)
- for (; j < PAGE_SIZE / sizeof(long); j++)
- buf[j] = 0;
- return pbe;
-}
-
-/**
- * save_image_metadata - save the .orig_address fields of the PBEs
- * from the list @pblist using the swap map handle @handle
- */
-
-static int save_image_metadata(struct pbe *pblist,
- struct swap_map_handle *handle)
+unsigned long alloc_swap_page(int swap, struct bitmap_page *bitmap)
{
- unsigned long *buf;
- unsigned int n = 0;
- struct pbe *p;
- int error = 0;
+ unsigned long offset;
- printk("Saving image metadata ... ");
- buf = (unsigned long *)get_zeroed_page(GFP_ATOMIC);
- if (!buf)
- return -ENOMEM;
- p = pblist;
- while (p) {
- p = pack_orig_addresses(buf, p);
- error = swap_map_write_page(handle, (unsigned long)buf);
- if (error)
- break;
- n++;
+ offset = swp_offset(get_swap_page_of_type(swap));
+ if (offset) {
+ if (bitmap_set(bitmap, offset)) {
+ swap_free(swp_entry(swap, offset));
+ offset = 0;
+ }
}
- free_page((unsigned long)buf);
- if (!error)
- printk("done (%u pages saved)\n", n);
- return error;
+ return offset;
}
-/**
- * enough_swap - Make sure we have enough swap to save the image.
- *
- * Returns TRUE or FALSE after checking the total amount of swap
- * space avaiable from the resume partition.
- */
-
-static int enough_swap(unsigned int nr_pages)
+void free_all_swap_pages(int swap, struct bitmap_page *bitmap)
{
- unsigned int free_swap = swap_info[root_swap].pages -
- swap_info[root_swap].inuse_pages;
-
- pr_debug("swsusp: free swap pages: %u\n", free_swap);
- return free_swap > (nr_pages + PAGES_FOR_IO +
- (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
-}
+ unsigned int bit, n;
+ unsigned long test;
-/**
- * swsusp_write - Write entire image and metadata.
- *
- * It is important _NOT_ to umount filesystems at this point. We want
- * them synced (in case something goes wrong) but we DO not want to mark
- * filesystem clean: it is not. (And it does not matter, if we resume
- * correctly, we'll mark system clean, anyway.)
- */
-
-int swsusp_write(struct pbe *pblist, unsigned int nr_pages)
-{
- struct swap_map_page *swap_map;
- struct swap_map_handle handle;
- swp_entry_t start;
- int error;
-
- if ((error = swsusp_swap_check())) {
- printk(KERN_ERR "swsusp: Cannot find swap device, try swapon -a.\n");
- return error;
- }
- if (!enough_swap(nr_pages)) {
- printk(KERN_ERR "swsusp: Not enough free swap\n");
- return -ENOSPC;
+ bit = 0;
+ while (bitmap) {
+ for (n = 0; n < BITMAP_PAGE_CHUNKS; n++)
+ for (test = 1UL; test; test <<= 1) {
+ if (bitmap->chunks[n] & test)
+ swap_free(swp_entry(swap, bit));
+ bit++;
+ }
+ bitmap = bitmap->next;
}
-
- init_header(nr_pages);
- swap_map = alloc_swap_map(swsusp_info.pages);
- if (!swap_map)
- return -ENOMEM;
- init_swap_map_handle(&handle, swap_map);
-
- error = swap_map_write_page(&handle, (unsigned long)&swsusp_info);
- if (!error)
- error = save_image_metadata(pblist, &handle);
- if (!error)
- error = save_image_data(pblist, &handle, nr_pages);
- if (error)
- goto Free_image_entries;
-
- swap_map = reverse_swap_map(swap_map);
- error = save_swap_map(swap_map, &start);
- if (error)
- goto Free_map_entries;
-
- dump_info();
- printk( "S" );
- error = mark_swapfiles(start);
- printk( "|\n" );
- if (error)
- goto Free_map_entries;
-
-Free_swap_map:
- free_swap_map(swap_map);
- return error;
-
-Free_map_entries:
- free_swap_map_entries(swap_map);
-Free_image_entries:
- free_image_entries(swap_map);
- goto Free_swap_map;
}
/**
@@ -660,379 +271,3 @@ int swsusp_resume(void)
local_irq_enable();
return error;
}
-
-/**
- * mark_unsafe_pages - mark the pages that cannot be used for storing
- * the image during resume, because they conflict with the pages that
- * had been used before suspend
- */
-
-static void mark_unsafe_pages(struct pbe *pblist)
-{
- struct zone *zone;
- unsigned long zone_pfn;
- struct pbe *p;
-
- if (!pblist) /* a sanity check */
- return;
-
- /* Clear page flags */
- for_each_zone (zone) {
- for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
- if (pfn_valid(zone_pfn + zone->zone_start_pfn))
- ClearPageNosaveFree(pfn_to_page(zone_pfn +
- zone->zone_start_pfn));
- }
-
- /* Mark orig addresses */
- for_each_pbe (p, pblist)
- SetPageNosaveFree(virt_to_page(p->orig_address));
-
-}
-
-static void copy_page_backup_list(struct pbe *dst, struct pbe *src)
-{
- /* We assume both lists contain the same number of elements */
- while (src) {
- dst->orig_address = src->orig_address;
- dst = dst->next;
- src = src->next;
- }
-}
-
-/*
- * Using bio to read from swap.
- * This code requires a bit more work than just using buffer heads
- * but, it is the recommended way for 2.5/2.6.
- * The following are to signal the beginning and end of I/O. Bios
- * finish asynchronously, while we want them to happen synchronously.
- * A simple atomic_t, and a wait loop take care of this problem.
- */
-
-static atomic_t io_done = ATOMIC_INIT(0);
-
-static int end_io(struct bio *bio, unsigned int num, int err)
-{
- if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
- panic("I/O error reading memory image");
- atomic_set(&io_done, 0);
- return 0;
-}
-
-static struct block_device *resume_bdev;
-
-/**
- * submit - submit BIO request.
- * @rw: READ or WRITE.
- * @off physical offset of page.
- * @page: page we're reading or writing.
- *
- * Straight from the textbook - allocate and initialize the bio.
- * If we're writing, make sure the page is marked as dirty.
- * Then submit it and wait.
- */
-
-static int submit(int rw, pgoff_t page_off, void *page)
-{
- int error = 0;
- struct bio *bio;
-
- bio = bio_alloc(GFP_ATOMIC, 1);
- if (!bio)
- return -ENOMEM;
- bio->bi_sector = page_off * (PAGE_SIZE >> 9);
- bio->bi_bdev = resume_bdev;
- bio->bi_end_io = end_io;
-
- if (bio_add_page(bio, virt_to_page(page), PAGE_SIZE, 0) < PAGE_SIZE) {
- printk("swsusp: ERROR: adding page to bio at %ld\n",page_off);
- error = -EFAULT;
- goto Done;
- }
-
-
- atomic_set(&io_done, 1);
- submit_bio(rw | (1 << BIO_RW_SYNC), bio);
- while (atomic_read(&io_done))
- yield();
- if (rw == READ)
- bio_set_pages_dirty(bio);
- Done:
- bio_put(bio);
- return error;
-}
-
-static int bio_read_page(pgoff_t page_off, void *page)
-{
- return submit(READ, page_off, page);
-}
-
-static int bio_write_page(pgoff_t page_off, void *page)
-{
- return submit(WRITE, page_off, page);
-}
-
-/**
- * The following functions allow us to read data using a swap map
- * in a file-alike way
- */
-
-static inline void release_swap_map_reader(struct swap_map_handle *handle)
-{
- if (handle->cur)
- free_page((unsigned long)handle->cur);
- handle->cur = NULL;
-}
-
-static inline int get_swap_map_reader(struct swap_map_handle *handle,
- swp_entry_t start)
-{
- int error;
-
- if (!swp_offset(start))
- return -EINVAL;
- handle->cur = (struct swap_map_page *)get_zeroed_page(GFP_ATOMIC);
- if (!handle->cur)
- return -ENOMEM;
- error = bio_read_page(swp_offset(start), handle->cur);
- if (error) {
- release_swap_map_reader(handle);
- return error;
- }
- handle->k = 0;
- return 0;
-}
-
-static inline int swap_map_read_page(struct swap_map_handle *handle, void *buf)
-{
- unsigned long offset;
- int error;
-
- if (!handle->cur)
- return -EINVAL;
- offset = swp_offset(handle->cur->entries[handle->k]);
- if (!offset)
- return -EINVAL;
- error = bio_read_page(offset, buf);
- if (error)
- return error;
- if (++handle->k >= MAP_PAGE_SIZE) {
- handle->k = 0;
- offset = swp_offset(handle->cur->next_swap);
- if (!offset)
- release_swap_map_reader(handle);
- else
- error = bio_read_page(offset, handle->cur);
- }
- return error;
-}
-
-static int check_header(void)
-{
- char *reason = NULL;
-
- dump_info();
- if (swsusp_info.version_code != LINUX_VERSION_CODE)
- reason = "kernel version";
- if (swsusp_info.num_physpages != num_physpages)
- reason = "memory size";
- if (strcmp(swsusp_info.uts.sysname,system_utsname.sysname))
- reason = "system type";
- if (strcmp(swsusp_info.uts.release,system_utsname.release))
- reason = "kernel release";
- if (strcmp(swsusp_info.uts.version,system_utsname.version))
- reason = "version";
- if (strcmp(swsusp_info.uts.machine,system_utsname.machine))
- reason = "machine";
- if (reason) {
- printk(KERN_ERR "swsusp: Resume mismatch: %s\n", reason);
- return -EPERM;
- }
- return 0;
-}
-
-/**
- * load_image_data - load the image data using the swap map handle
- * @handle and store them using the page backup list @pblist
- * (assume there are @nr_pages pages to load)
- */
-
-static int load_image_data(struct pbe *pblist,
- struct swap_map_handle *handle,
- unsigned int nr_pages)
-{
- int error;
- unsigned int m;
- struct pbe *p;
-
- if (!pblist)
- return -EINVAL;
- printk("Loading image data pages (%u pages) ... ", nr_pages);
- m = nr_pages / 100;
- if (!m)
- m = 1;
- nr_pages = 0;
- p = pblist;
- while (p) {
- error = swap_map_read_page(handle, (void *)p->address);
- if (error)
- break;
- p = p->next;
- if (!(nr_pages % m))
- printk("\b\b\b\b%3d%%", nr_pages / m);
- nr_pages++;
- }
- if (!error)
- printk("\b\b\b\bdone\n");
- return error;
-}
-
-/**
- * unpack_orig_addresses - copy the elements of @buf[] (1 page) to
- * the PBEs in the list starting at @pbe
- */
-
-static inline struct pbe *unpack_orig_addresses(unsigned long *buf,
- struct pbe *pbe)
-{
- int j;
-
- for (j = 0; j < PAGE_SIZE / sizeof(long) && pbe; j++) {
- pbe->orig_address = buf[j];
- pbe = pbe->next;
- }
- return pbe;
-}
-
-/**
- * load_image_metadata - load the image metadata using the swap map
- * handle @handle and put them into the PBEs in the list @pblist
- */
-
-static int load_image_metadata(struct pbe *pblist, struct swap_map_handle *handle)
-{
- struct pbe *p;
- unsigned long *buf;
- unsigned int n = 0;
- int error = 0;
-
- printk("Loading image metadata ... ");
- buf = (unsigned long *)get_zeroed_page(GFP_ATOMIC);
- if (!buf)
- return -ENOMEM;
- p = pblist;
- while (p) {
- error = swap_map_read_page(handle, buf);
- if (error)
- break;
- p = unpack_orig_addresses(buf, p);
- n++;
- }
- free_page((unsigned long)buf);
- if (!error)
- printk("done (%u pages loaded)\n", n);
- return error;
-}
-
-int swsusp_read(struct pbe **pblist_ptr)
-{
- int error;
- struct pbe *p, *pblist;
- struct swap_map_handle handle;
- unsigned int nr_pages;
-
- if (IS_ERR(resume_bdev)) {
- pr_debug("swsusp: block device not initialised\n");
- return PTR_ERR(resume_bdev);
- }
-
- error = get_swap_map_reader(&handle, swsusp_header.image);
- if (!error)
- error = swap_map_read_page(&handle, &swsusp_info);
- if (!error)
- error = check_header();
- if (error)
- return error;
- nr_pages = swsusp_info.image_pages;
- p = alloc_pagedir(nr_pages, GFP_ATOMIC, 0);
- if (!p)
- return -ENOMEM;
- error = load_image_metadata(p, &handle);
- if (!error) {
- mark_unsafe_pages(p);
- pblist = alloc_pagedir(nr_pages, GFP_ATOMIC, 1);
- if (pblist)
- copy_page_backup_list(pblist, p);
- free_pagedir(p);
- if (!pblist)
- error = -ENOMEM;
-
- /* Allocate memory for the image and read the data from swap */
- if (!error)
- error = alloc_data_pages(pblist, GFP_ATOMIC, 1);
- if (!error) {
- release_eaten_pages();
- error = load_image_data(pblist, &handle, nr_pages);
- }
- if (!error)
- *pblist_ptr = pblist;
- }
- release_swap_map_reader(&handle);
-
- blkdev_put(resume_bdev);
-
- if (!error)
- pr_debug("swsusp: Reading resume file was successful\n");
- else
- pr_debug("swsusp: Error %d resuming\n", error);
- return error;
-}
-
-/**
- * swsusp_check - Check for swsusp signature in the resume device
- */
-
-int swsusp_check(void)
-{
- int error;
-
- resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ);
- if (!IS_ERR(resume_bdev)) {
- set_blocksize(resume_bdev, PAGE_SIZE);
- memset(&swsusp_header, 0, sizeof(swsusp_header));
- if ((error = bio_read_page(0, &swsusp_header)))
- return error;
- if (!memcmp(SWSUSP_SIG, swsusp_header.sig, 10)) {
- memcpy(swsusp_header.sig, swsusp_header.orig_sig, 10);
- /* Reset swap signature now */
- error = bio_write_page(0, &swsusp_header);
- } else {
- return -EINVAL;
- }
- if (error)
- blkdev_put(resume_bdev);
- else
- pr_debug("swsusp: Signature found, resuming\n");
- } else {
- error = PTR_ERR(resume_bdev);
- }
-
- if (error)
- pr_debug("swsusp: Error %d check for resume file\n", error);
-
- return error;
-}
-
-/**
- * swsusp_close - close swap device.
- */
-
-void swsusp_close(void)
-{
- if (IS_ERR(resume_bdev)) {
- pr_debug("swsusp: block device not initialised\n");
- return;
- }
-
- blkdev_put(resume_bdev);
-}
diff --git a/kernel/power/user.c b/kernel/power/user.c
new file mode 100644
index 000000000000..3f1539fbe48a
--- /dev/null
+++ b/kernel/power/user.c
@@ -0,0 +1,333 @@
+/*
+ * linux/kernel/power/user.c
+ *
+ * This file provides the user space interface for software suspend/resume.
+ *
+ * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl>
+ *
+ * This file is released under the GPLv2.
+ *
+ */
+
+#include <linux/suspend.h>
+#include <linux/syscalls.h>
+#include <linux/string.h>
+#include <linux/device.h>
+#include <linux/miscdevice.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/swapops.h>
+#include <linux/pm.h>
+#include <linux/fs.h>
+
+#include <asm/uaccess.h>
+
+#include "power.h"
+
+#define SNAPSHOT_MINOR 231
+
+static struct snapshot_data {
+ struct snapshot_handle handle;
+ int swap;
+ struct bitmap_page *bitmap;
+ int mode;
+ char frozen;
+ char ready;
+} snapshot_state;
+
+static atomic_t device_available = ATOMIC_INIT(1);
+
+static int snapshot_open(struct inode *inode, struct file *filp)
+{
+ struct snapshot_data *data;
+
+ if (!atomic_add_unless(&device_available, -1, 0))
+ return -EBUSY;
+
+ if ((filp->f_flags & O_ACCMODE) == O_RDWR)
+ return -ENOSYS;
+
+ nonseekable_open(inode, filp);
+ data = &snapshot_state;
+ filp->private_data = data;
+ memset(&data->handle, 0, sizeof(struct snapshot_handle));
+ if ((filp->f_flags & O_ACCMODE) == O_RDONLY) {
+ data->swap = swsusp_resume_device ? swap_type_of(swsusp_resume_device) : -1;
+ data->mode = O_RDONLY;
+ } else {
+ data->swap = -1;
+ data->mode = O_WRONLY;
+ }
+ data->bitmap = NULL;
+ data->frozen = 0;
+ data->ready = 0;
+
+ return 0;
+}
+
+static int snapshot_release(struct inode *inode, struct file *filp)
+{
+ struct snapshot_data *data;
+
+ swsusp_free();
+ data = filp->private_data;
+ free_all_swap_pages(data->swap, data->bitmap);
+ free_bitmap(data->bitmap);
+ if (data->frozen) {
+ down(&pm_sem);
+ thaw_processes();
+ enable_nonboot_cpus();
+ up(&pm_sem);
+ }
+ atomic_inc(&device_available);
+ return 0;
+}
+
+static ssize_t snapshot_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *offp)
+{
+ struct snapshot_data *data;
+ ssize_t res;
+
+ data = filp->private_data;
+ res = snapshot_read_next(&data->handle, count);
+ if (res > 0) {
+ if (copy_to_user(buf, data_of(data->handle), res))
+ res = -EFAULT;
+ else
+ *offp = data->handle.offset;
+ }
+ return res;
+}
+
+static ssize_t snapshot_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *offp)
+{
+ struct snapshot_data *data;
+ ssize_t res;
+
+ data = filp->private_data;
+ res = snapshot_write_next(&data->handle, count);
+ if (res > 0) {
+ if (copy_from_user(data_of(data->handle), buf, res))
+ res = -EFAULT;
+ else
+ *offp = data->handle.offset;
+ }
+ return res;
+}
+
+static int snapshot_ioctl(struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ int error = 0;
+ struct snapshot_data *data;
+ loff_t offset, avail;
+
+ if (_IOC_TYPE(cmd) != SNAPSHOT_IOC_MAGIC)
+ return -ENOTTY;
+ if (_IOC_NR(cmd) > SNAPSHOT_IOC_MAXNR)
+ return -ENOTTY;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ data = filp->private_data;
+
+ switch (cmd) {
+
+ case SNAPSHOT_FREEZE:
+ if (data->frozen)
+ break;
+ down(&pm_sem);
+ disable_nonboot_cpus();
+ if (freeze_processes()) {
+ thaw_processes();
+ enable_nonboot_cpus();
+ error = -EBUSY;
+ }
+ up(&pm_sem);
+ if (!error)
+ data->frozen = 1;
+ break;
+
+ case SNAPSHOT_UNFREEZE:
+ if (!data->frozen)
+ break;
+ down(&pm_sem);
+ thaw_processes();
+ enable_nonboot_cpus();
+ up(&pm_sem);
+ data->frozen = 0;
+ break;
+
+ case SNAPSHOT_ATOMIC_SNAPSHOT:
+ if (data->mode != O_RDONLY || !data->frozen || data->ready) {
+ error = -EPERM;
+ break;
+ }
+ down(&pm_sem);
+ /* Free memory before shutting down devices. */
+ error = swsusp_shrink_memory();
+ if (!error) {
+ error = device_suspend(PMSG_FREEZE);
+ if (!error) {
+ in_suspend = 1;
+ error = swsusp_suspend();
+ device_resume();
+ }
+ }
+ up(&pm_sem);
+ if (!error)
+ error = put_user(in_suspend, (unsigned int __user *)arg);
+ if (!error)
+ data->ready = 1;
+ break;
+
+ case SNAPSHOT_ATOMIC_RESTORE:
+ if (data->mode != O_WRONLY || !data->frozen ||
+ !snapshot_image_loaded(&data->handle)) {
+ error = -EPERM;
+ break;
+ }
+ down(&pm_sem);
+ pm_prepare_console();
+ error = device_suspend(PMSG_FREEZE);
+ if (!error) {
+ error = swsusp_resume();
+ device_resume();
+ }
+ pm_restore_console();
+ up(&pm_sem);
+ break;
+
+ case SNAPSHOT_FREE:
+ swsusp_free();
+ memset(&data->handle, 0, sizeof(struct snapshot_handle));
+ data->ready = 0;
+ break;
+
+ case SNAPSHOT_SET_IMAGE_SIZE:
+ image_size = arg;
+ break;
+
+ case SNAPSHOT_AVAIL_SWAP:
+ avail = count_swap_pages(data->swap, 1);
+ avail <<= PAGE_SHIFT;
+ error = put_user(avail, (loff_t __user *)arg);
+ break;
+
+ case SNAPSHOT_GET_SWAP_PAGE:
+ if (data->swap < 0 || data->swap >= MAX_SWAPFILES) {
+ error = -ENODEV;
+ break;
+ }
+ if (!data->bitmap) {
+ data->bitmap = alloc_bitmap(count_swap_pages(data->swap, 0));
+ if (!data->bitmap) {
+ error = -ENOMEM;
+ break;
+ }
+ }
+ offset = alloc_swap_page(data->swap, data->bitmap);
+ if (offset) {
+ offset <<= PAGE_SHIFT;
+ error = put_user(offset, (loff_t __user *)arg);
+ } else {
+ error = -ENOSPC;
+ }
+ break;
+
+ case SNAPSHOT_FREE_SWAP_PAGES:
+ if (data->swap < 0 || data->swap >= MAX_SWAPFILES) {
+ error = -ENODEV;
+ break;
+ }
+ free_all_swap_pages(data->swap, data->bitmap);
+ free_bitmap(data->bitmap);
+ data->bitmap = NULL;
+ break;
+
+ case SNAPSHOT_SET_SWAP_FILE:
+ if (!data->bitmap) {
+ /*
+ * User space encodes device types as two-byte values,
+ * so we need to recode them
+ */
+ if (old_decode_dev(arg)) {
+ data->swap = swap_type_of(old_decode_dev(arg));
+ if (data->swap < 0)
+ error = -ENODEV;
+ } else {
+ data->swap = -1;
+ error = -EINVAL;
+ }
+ } else {
+ error = -EPERM;
+ }
+ break;
+
+ case SNAPSHOT_S2RAM:
+ if (!data->frozen) {
+ error = -EPERM;
+ break;
+ }
+
+ if (down_trylock(&pm_sem)) {
+ error = -EBUSY;
+ break;
+ }
+
+ if (pm_ops->prepare) {
+ error = pm_ops->prepare(PM_SUSPEND_MEM);
+ if (error)
+ goto OutS3;
+ }
+
+ /* Put devices to sleep */
+ error = device_suspend(PMSG_SUSPEND);
+ if (error) {
+ printk(KERN_ERR "Failed to suspend some devices.\n");
+ } else {
+ /* Enter S3, system is already frozen */
+ suspend_enter(PM_SUSPEND_MEM);
+
+ /* Wake up devices */
+ device_resume();
+ }
+
+ if (pm_ops->finish)
+ pm_ops->finish(PM_SUSPEND_MEM);
+
+OutS3:
+ up(&pm_sem);
+ break;
+
+ default:
+ error = -ENOTTY;
+
+ }
+
+ return error;
+}
+
+static struct file_operations snapshot_fops = {
+ .open = snapshot_open,
+ .release = snapshot_release,
+ .read = snapshot_read,
+ .write = snapshot_write,
+ .llseek = no_llseek,
+ .ioctl = snapshot_ioctl,
+};
+
+static struct miscdevice snapshot_device = {
+ .minor = SNAPSHOT_MINOR,
+ .name = "snapshot",
+ .fops = &snapshot_fops,
+};
+
+static int __init snapshot_device_init(void)
+{
+ return misc_register(&snapshot_device);
+};
+
+device_initcall(snapshot_device_init);
diff --git a/kernel/profile.c b/kernel/profile.c
index f89248e6d704..ad81f799a9b4 100644
--- a/kernel/profile.c
+++ b/kernel/profile.c
@@ -23,6 +23,7 @@
#include <linux/cpu.h>
#include <linux/profile.h>
#include <linux/highmem.h>
+#include <linux/mutex.h>
#include <asm/sections.h>
#include <asm/semaphore.h>
@@ -44,7 +45,7 @@ static cpumask_t prof_cpu_mask = CPU_MASK_ALL;
#ifdef CONFIG_SMP
static DEFINE_PER_CPU(struct profile_hit *[2], cpu_profile_hits);
static DEFINE_PER_CPU(int, cpu_profile_flip);
-static DECLARE_MUTEX(profile_flip_mutex);
+static DEFINE_MUTEX(profile_flip_mutex);
#endif /* CONFIG_SMP */
static int __init profile_setup(char * str)
@@ -243,7 +244,7 @@ static void profile_flip_buffers(void)
{
int i, j, cpu;
- down(&profile_flip_mutex);
+ mutex_lock(&profile_flip_mutex);
j = per_cpu(cpu_profile_flip, get_cpu());
put_cpu();
on_each_cpu(__profile_flip_buffers, NULL, 0, 1);
@@ -259,14 +260,14 @@ static void profile_flip_buffers(void)
hits[i].hits = hits[i].pc = 0;
}
}
- up(&profile_flip_mutex);
+ mutex_unlock(&profile_flip_mutex);
}
static void profile_discard_flip_buffers(void)
{
int i, cpu;
- down(&profile_flip_mutex);
+ mutex_lock(&profile_flip_mutex);
i = per_cpu(cpu_profile_flip, get_cpu());
put_cpu();
on_each_cpu(__profile_flip_buffers, NULL, 0, 1);
@@ -274,7 +275,7 @@ static void profile_discard_flip_buffers(void)
struct profile_hit *hits = per_cpu(cpu_profile_hits, cpu)[i];
memset(hits, 0, NR_PROFILE_HIT*sizeof(struct profile_hit));
}
- up(&profile_flip_mutex);
+ mutex_unlock(&profile_flip_mutex);
}
void profile_hit(int type, void *__pc)
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index fedf5e369755..6df1559b1c02 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -47,15 +47,16 @@
#include <linux/notifier.h>
#include <linux/rcupdate.h>
#include <linux/cpu.h>
+#include <linux/mutex.h>
/* Definition for rcupdate control block. */
-struct rcu_ctrlblk rcu_ctrlblk = {
+static struct rcu_ctrlblk rcu_ctrlblk = {
.cur = -300,
.completed = -300,
.lock = SPIN_LOCK_UNLOCKED,
.cpumask = CPU_MASK_NONE,
};
-struct rcu_ctrlblk rcu_bh_ctrlblk = {
+static struct rcu_ctrlblk rcu_bh_ctrlblk = {
.cur = -300,
.completed = -300,
.lock = SPIN_LOCK_UNLOCKED,
@@ -75,7 +76,7 @@ static int rsinterval = 1000;
#endif
static atomic_t rcu_barrier_cpu_count;
-static struct semaphore rcu_barrier_sema;
+static DEFINE_MUTEX(rcu_barrier_mutex);
static struct completion rcu_barrier_completion;
#ifdef CONFIG_SMP
@@ -207,13 +208,13 @@ static void rcu_barrier_func(void *notused)
void rcu_barrier(void)
{
BUG_ON(in_interrupt());
- /* Take cpucontrol semaphore to protect against CPU hotplug */
- down(&rcu_barrier_sema);
+ /* Take cpucontrol mutex to protect against CPU hotplug */
+ mutex_lock(&rcu_barrier_mutex);
init_completion(&rcu_barrier_completion);
atomic_set(&rcu_barrier_cpu_count, 0);
on_each_cpu(rcu_barrier_func, NULL, 0, 1);
wait_for_completion(&rcu_barrier_completion);
- up(&rcu_barrier_sema);
+ mutex_unlock(&rcu_barrier_mutex);
}
EXPORT_SYMBOL_GPL(rcu_barrier);
@@ -549,7 +550,6 @@ static struct notifier_block __devinitdata rcu_nb = {
*/
void __init rcu_init(void)
{
- sema_init(&rcu_barrier_sema, 1);
rcu_cpu_notify(&rcu_nb, CPU_UP_PREPARE,
(void *)(long)smp_processor_id());
/* Register notifier for non-boot CPUs */
diff --git a/kernel/sched.c b/kernel/sched.c
index 6b6e0d70eb30..7ffaabd64f89 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -237,6 +237,7 @@ struct runqueue {
task_t *migration_thread;
struct list_head migration_queue;
+ int cpu;
#endif
#ifdef CONFIG_SCHEDSTATS
@@ -1654,6 +1655,9 @@ unsigned long nr_iowait(void)
/*
* double_rq_lock - safely lock two runqueues
*
+ * We must take them in cpu order to match code in
+ * dependent_sleeper and wake_dependent_sleeper.
+ *
* Note this does not disable interrupts like task_rq_lock,
* you need to do so manually before calling.
*/
@@ -1665,7 +1669,7 @@ static void double_rq_lock(runqueue_t *rq1, runqueue_t *rq2)
spin_lock(&rq1->lock);
__acquire(rq2->lock); /* Fake it out ;) */
} else {
- if (rq1 < rq2) {
+ if (rq1->cpu < rq2->cpu) {
spin_lock(&rq1->lock);
spin_lock(&rq2->lock);
} else {
@@ -1701,7 +1705,7 @@ static void double_lock_balance(runqueue_t *this_rq, runqueue_t *busiest)
__acquires(this_rq->lock)
{
if (unlikely(!spin_trylock(&busiest->lock))) {
- if (busiest < this_rq) {
+ if (busiest->cpu < this_rq->cpu) {
spin_unlock(&this_rq->lock);
spin_lock(&busiest->lock);
spin_lock(&this_rq->lock);
@@ -2869,7 +2873,7 @@ asmlinkage void __sched schedule(void)
*/
if (likely(!current->exit_state)) {
if (unlikely(in_atomic())) {
- printk(KERN_ERR "scheduling while atomic: "
+ printk(KERN_ERR "BUG: scheduling while atomic: "
"%s/0x%08x/%d\n",
current->comm, preempt_count(), current->pid);
dump_stack();
@@ -6029,6 +6033,7 @@ void __init sched_init(void)
rq->push_cpu = 0;
rq->migration_thread = NULL;
INIT_LIST_HEAD(&rq->migration_queue);
+ rq->cpu = i;
#endif
atomic_set(&rq->nr_iowait, 0);
@@ -6069,7 +6074,7 @@ void __might_sleep(char *file, int line)
if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
return;
prev_jiffy = jiffies;
- printk(KERN_ERR "Debug: sleeping function called from invalid"
+ printk(KERN_ERR "BUG: sleeping function called from invalid"
" context at %s:%d\n", file, line);
printk("in_atomic():%d, irqs_disabled():%d\n",
in_atomic(), irqs_disabled());
diff --git a/kernel/signal.c b/kernel/signal.c
index ea154104a00b..75f7341b0c39 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1922,6 +1922,8 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
sigset_t *mask = &current->blocked;
int signr = 0;
+ try_to_freeze();
+
relock:
spin_lock_irq(&current->sighand->siglock);
for (;;) {
@@ -2099,10 +2101,11 @@ long do_no_restart_syscall(struct restart_block *param)
int sigprocmask(int how, sigset_t *set, sigset_t *oldset)
{
int error;
- sigset_t old_block;
spin_lock_irq(&current->sighand->siglock);
- old_block = current->blocked;
+ if (oldset)
+ *oldset = current->blocked;
+
error = 0;
switch (how) {
case SIG_BLOCK:
@@ -2119,8 +2122,7 @@ int sigprocmask(int how, sigset_t *set, sigset_t *oldset)
}
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);
- if (oldset)
- *oldset = old_block;
+
return error;
}
@@ -2307,7 +2309,6 @@ sys_rt_sigtimedwait(const sigset_t __user *uthese,
timeout = schedule_timeout_interruptible(timeout);
- try_to_freeze();
spin_lock_irq(&current->sighand->siglock);
sig = dequeue_signal(current, &these, &info);
current->blocked = current->real_blocked;
diff --git a/kernel/spinlock.c b/kernel/spinlock.c
index 0375fcd5921d..d1b810782bc4 100644
--- a/kernel/spinlock.c
+++ b/kernel/spinlock.c
@@ -179,16 +179,16 @@ EXPORT_SYMBOL(_write_lock);
#define BUILD_LOCK_OPS(op, locktype) \
void __lockfunc _##op##_lock(locktype##_t *lock) \
{ \
- preempt_disable(); \
for (;;) { \
+ preempt_disable(); \
if (likely(_raw_##op##_trylock(lock))) \
break; \
preempt_enable(); \
+ \
if (!(lock)->break_lock) \
(lock)->break_lock = 1; \
while (!op##_can_lock(lock) && (lock)->break_lock) \
cpu_relax(); \
- preempt_disable(); \
} \
(lock)->break_lock = 0; \
} \
@@ -199,19 +199,18 @@ unsigned long __lockfunc _##op##_lock_irqsave(locktype##_t *lock) \
{ \
unsigned long flags; \
\
- preempt_disable(); \
for (;;) { \
+ preempt_disable(); \
local_irq_save(flags); \
if (likely(_raw_##op##_trylock(lock))) \
break; \
local_irq_restore(flags); \
- \
preempt_enable(); \
+ \
if (!(lock)->break_lock) \
(lock)->break_lock = 1; \
while (!op##_can_lock(lock) && (lock)->break_lock) \
cpu_relax(); \
- preempt_disable(); \
} \
(lock)->break_lock = 0; \
return flags; \
diff --git a/kernel/sys.c b/kernel/sys.c
index f91218a5463e..c0fcad9f826c 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1227,7 +1227,7 @@ asmlinkage long sys_setsid(void)
struct pid *pid;
int err = -EPERM;
- down(&tty_sem);
+ mutex_lock(&tty_mutex);
write_lock_irq(&tasklist_lock);
pid = find_pid(PIDTYPE_PGID, group_leader->pid);
@@ -1241,7 +1241,7 @@ asmlinkage long sys_setsid(void)
err = process_group(group_leader);
out:
write_unlock_irq(&tasklist_lock);
- up(&tty_sem);
+ mutex_unlock(&tty_mutex);
return err;
}
@@ -1677,9 +1677,6 @@ asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim)
* a lot simpler! (Which we're not doing right now because we're not
* measuring them yet).
*
- * This expects to be called with tasklist_lock read-locked or better,
- * and the siglock not locked. It may momentarily take the siglock.
- *
* When sampling multiple threads for RUSAGE_SELF, under SMP we might have
* races with threads incrementing their own counters. But since word
* reads are atomic, we either get new values or old values and we don't
@@ -1687,6 +1684,25 @@ asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim)
* the c* fields from p->signal from races with exit.c updating those
* fields when reaping, so a sample either gets all the additions of a
* given child after it's reaped, or none so this sample is before reaping.
+ *
+ * tasklist_lock locking optimisation:
+ * If we are current and single threaded, we do not need to take the tasklist
+ * lock or the siglock. No one else can take our signal_struct away,
+ * no one else can reap the children to update signal->c* counters, and
+ * no one else can race with the signal-> fields.
+ * If we do not take the tasklist_lock, the signal-> fields could be read
+ * out of order while another thread was just exiting. So we place a
+ * read memory barrier when we avoid the lock. On the writer side,
+ * write memory barrier is implied in __exit_signal as __exit_signal releases
+ * the siglock spinlock after updating the signal-> fields.
+ *
+ * We don't really need the siglock when we access the non c* fields
+ * of the signal_struct (for RUSAGE_SELF) even in multithreaded
+ * case, since we take the tasklist lock for read and the non c* signal->
+ * fields are updated only in __exit_signal, which is called with
+ * tasklist_lock taken for write, hence these two threads cannot execute
+ * concurrently.
+ *
*/
static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
@@ -1694,13 +1710,23 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
struct task_struct *t;
unsigned long flags;
cputime_t utime, stime;
+ int need_lock = 0;
memset((char *) r, 0, sizeof *r);
+ utime = stime = cputime_zero;
- if (unlikely(!p->signal))
- return;
+ if (p != current || !thread_group_empty(p))
+ need_lock = 1;
- utime = stime = cputime_zero;
+ if (need_lock) {
+ read_lock(&tasklist_lock);
+ if (unlikely(!p->signal)) {
+ read_unlock(&tasklist_lock);
+ return;
+ }
+ } else
+ /* See locking comments above */
+ smp_rmb();
switch (who) {
case RUSAGE_BOTH:
@@ -1740,6 +1766,8 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
BUG();
}
+ if (need_lock)
+ read_unlock(&tasklist_lock);
cputime_to_timeval(utime, &r->ru_utime);
cputime_to_timeval(stime, &r->ru_stime);
}
@@ -1747,9 +1775,7 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
int getrusage(struct task_struct *p, int who, struct rusage __user *ru)
{
struct rusage r;
- read_lock(&tasklist_lock);
k_getrusage(p, who, &r);
- read_unlock(&tasklist_lock);
return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0;
}
diff --git a/lib/extable.c b/lib/extable.c
index 18df57c029df..01c08b5836f5 100644
--- a/lib/extable.c
+++ b/lib/extable.c
@@ -1,5 +1,4 @@
/*
- * lib/extable.c
* Derived from arch/ppc/mm/extable.c and arch/i386/mm/extable.c.
*
* Copyright (C) 2004 Paul Mackerras, IBM Corp.
diff --git a/lib/reed_solomon/reed_solomon.c b/lib/reed_solomon/reed_solomon.c
index f5fef948a415..f8ac9fa95de1 100644
--- a/lib/reed_solomon/reed_solomon.c
+++ b/lib/reed_solomon/reed_solomon.c
@@ -44,12 +44,13 @@
#include <linux/module.h>
#include <linux/rslib.h>
#include <linux/slab.h>
+#include <linux/mutex.h>
#include <asm/semaphore.h>
/* This list holds all currently allocated rs control structures */
static LIST_HEAD (rslist);
/* Protection for the list */
-static DECLARE_MUTEX(rslistlock);
+static DEFINE_MUTEX(rslistlock);
/**
* rs_init - Initialize a Reed-Solomon codec
@@ -161,7 +162,7 @@ errrs:
*/
void free_rs(struct rs_control *rs)
{
- down(&rslistlock);
+ mutex_lock(&rslistlock);
rs->users--;
if(!rs->users) {
list_del(&rs->list);
@@ -170,7 +171,7 @@ void free_rs(struct rs_control *rs)
kfree(rs->genpoly);
kfree(rs);
}
- up(&rslistlock);
+ mutex_unlock(&rslistlock);
}
/**
@@ -201,7 +202,7 @@ struct rs_control *init_rs(int symsize, int gfpoly, int fcr, int prim,
if (nroots < 0 || nroots >= (1<<symsize))
return NULL;
- down(&rslistlock);
+ mutex_lock(&rslistlock);
/* Walk through the list and look for a matching entry */
list_for_each(tmp, &rslist) {
@@ -228,7 +229,7 @@ struct rs_control *init_rs(int symsize, int gfpoly, int fcr, int prim,
list_add(&rs->list, &rslist);
}
out:
- up(&rslistlock);
+ mutex_unlock(&rslistlock);
return rs;
}
diff --git a/mm/readahead.c b/mm/readahead.c
index 301b36c4a0ce..0f142a40984b 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -555,6 +555,7 @@ recheck:
out:
return ra->prev_page + 1;
}
+EXPORT_SYMBOL_GPL(page_cache_readahead);
/*
* handle_ra_miss() is called when it is known that a page which should have
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 365ed6ff182d..39aa9d129612 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -45,7 +45,7 @@ static const char Unused_offset[] = "Unused swap offset entry ";
struct swap_list_t swap_list = {-1, -1};
-struct swap_info_struct swap_info[MAX_SWAPFILES];
+static struct swap_info_struct swap_info[MAX_SWAPFILES];
static DEFINE_MUTEX(swapon_mutex);
@@ -417,6 +417,61 @@ void free_swap_and_cache(swp_entry_t entry)
}
}
+#ifdef CONFIG_SOFTWARE_SUSPEND
+/*
+ * Find the swap type that corresponds to given device (if any)
+ *
+ * This is needed for software suspend and is done in such a way that inode
+ * aliasing is allowed.
+ */
+int swap_type_of(dev_t device)
+{
+ int i;
+
+ spin_lock(&swap_lock);
+ for (i = 0; i < nr_swapfiles; i++) {
+ struct inode *inode;
+
+ if (!(swap_info[i].flags & SWP_WRITEOK))
+ continue;
+ if (!device) {
+ spin_unlock(&swap_lock);
+ return i;
+ }
+ inode = swap_info->swap_file->f_dentry->d_inode;
+ if (S_ISBLK(inode->i_mode) &&
+ device == MKDEV(imajor(inode), iminor(inode))) {
+ spin_unlock(&swap_lock);
+ return i;
+ }
+ }
+ spin_unlock(&swap_lock);
+ return -ENODEV;
+}
+
+/*
+ * Return either the total number of swap pages of given type, or the number
+ * of free pages of that type (depending on @free)
+ *
+ * This is needed for software suspend
+ */
+unsigned int count_swap_pages(int type, int free)
+{
+ unsigned int n = 0;
+
+ if (type < nr_swapfiles) {
+ spin_lock(&swap_lock);
+ if (swap_info[type].flags & SWP_WRITEOK) {
+ n = swap_info[type].pages;
+ if (free)
+ n -= swap_info[type].inuse_pages;
+ }
+ spin_unlock(&swap_lock);
+ }
+ return n;
+}
+#endif
+
/*
* No need to decide whether this PTE shares the swap entry with others,
* just let do_wp_page work it out if a write is requested later - to
diff --git a/security/seclvl.c b/security/seclvl.c
index 8529ea6f7aa8..441beaf1bbc1 100644
--- a/security/seclvl.c
+++ b/security/seclvl.c
@@ -8,6 +8,7 @@
* Copyright (c) 2001 WireX Communications, Inc <chris@wirex.com>
* Copyright (c) 2001 Greg Kroah-Hartman <greg@kroah.com>
* Copyright (c) 2002 International Business Machines <robb@austin.ibm.com>
+ * Copyright (c) 2006 Davi E. M. Arnaut <davi.arnaut@gmail.com>
*
* 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
@@ -31,6 +32,7 @@
#include <linux/kobject.h>
#include <linux/crypto.h>
#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
#include <linux/gfp.h>
#include <linux/sysfs.h>
@@ -194,35 +196,27 @@ static unsigned char hashedPassword[SHA1_DIGEST_SIZE];
* people...
*/
static int
-plaintext_to_sha1(unsigned char *hash, const char *plaintext, int len)
+plaintext_to_sha1(unsigned char *hash, const char *plaintext, unsigned int len)
{
- char *pgVirtAddr;
struct crypto_tfm *tfm;
- struct scatterlist sg[1];
+ struct scatterlist sg;
if (len > PAGE_SIZE) {
seclvl_printk(0, KERN_ERR, "Plaintext password too large (%d "
"characters). Largest possible is %lu "
"bytes.\n", len, PAGE_SIZE);
- return -ENOMEM;
+ return -EINVAL;
}
tfm = crypto_alloc_tfm("sha1", CRYPTO_TFM_REQ_MAY_SLEEP);
if (tfm == NULL) {
seclvl_printk(0, KERN_ERR,
"Failed to load transform for SHA1\n");
- return -ENOSYS;
+ return -EINVAL;
}
- // Just get a new page; don't play around with page boundaries
- // and scatterlists.
- pgVirtAddr = (char *)__get_free_page(GFP_KERNEL);
- sg[0].page = virt_to_page(pgVirtAddr);
- sg[0].offset = 0;
- sg[0].length = len;
- strncpy(pgVirtAddr, plaintext, len);
+ sg_init_one(&sg, (u8 *)plaintext, len);
crypto_digest_init(tfm);
- crypto_digest_update(tfm, sg, 1);
+ crypto_digest_update(tfm, &sg, 1);
crypto_digest_final(tfm, hash);
crypto_free_tfm(tfm);
- free_page((unsigned long)pgVirtAddr);
return 0;
}
@@ -234,11 +228,9 @@ static ssize_t
passwd_write_file(struct file * file, const char __user * buf,
size_t count, loff_t *ppos)
{
- int i;
- unsigned char tmp[SHA1_DIGEST_SIZE];
- char *page;
- int rc;
+ char *p;
int len;
+ unsigned char tmp[SHA1_DIGEST_SIZE];
if (!*passwd && !*sha1_passwd) {
seclvl_printk(0, KERN_ERR, "Attempt to password-unlock the "
@@ -251,38 +243,39 @@ passwd_write_file(struct file * file, const char __user * buf,
return -EINVAL;
}
- if (count < 0 || count >= PAGE_SIZE)
+ if (count >= PAGE_SIZE)
return -EINVAL;
if (*ppos != 0)
return -EINVAL;
- page = (char *)get_zeroed_page(GFP_KERNEL);
- if (!page)
+ p = kmalloc(count, GFP_KERNEL);
+ if (!p)
return -ENOMEM;
len = -EFAULT;
- if (copy_from_user(page, buf, count))
+ if (copy_from_user(p, buf, count))
goto out;
- len = strlen(page);
+ len = count;
/* ``echo "secret" > seclvl/passwd'' includes a newline */
- if (page[len - 1] == '\n')
+ if (p[len - 1] == '\n')
len--;
/* Hash the password, then compare the hashed values */
- if ((rc = plaintext_to_sha1(tmp, page, len))) {
+ if ((len = plaintext_to_sha1(tmp, p, len))) {
seclvl_printk(0, KERN_ERR, "Error hashing password: rc = "
- "[%d]\n", rc);
- return rc;
- }
- for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
- if (hashedPassword[i] != tmp[i])
- return -EPERM;
+ "[%d]\n", len);
+ goto out;
}
+
+ len = -EPERM;
+ if (memcmp(hashedPassword, tmp, SHA1_DIGEST_SIZE))
+ goto out;
+
seclvl_printk(0, KERN_INFO,
"Password accepted; seclvl reduced to 0.\n");
seclvl = 0;
len = count;
out:
- free_page((unsigned long)page);
+ kfree (p);
return len;
}
@@ -295,13 +288,11 @@ static struct file_operations passwd_file_ops = {
*/
static int seclvl_ptrace(struct task_struct *parent, struct task_struct *child)
{
- if (seclvl >= 0) {
- if (child->pid == 1) {
- seclvl_printk(1, KERN_WARNING, "Attempt to ptrace "
- "the init process dissallowed in "
- "secure level %d\n", seclvl);
- return -EPERM;
- }
+ if (seclvl >= 0 && child->pid == 1) {
+ seclvl_printk(1, KERN_WARNING, "Attempt to ptrace "
+ "the init process dissallowed in "
+ "secure level %d\n", seclvl);
+ return -EPERM;
}
return 0;
}
@@ -312,55 +303,54 @@ static int seclvl_ptrace(struct task_struct *parent, struct task_struct *child)
*/
static int seclvl_capable(struct task_struct *tsk, int cap)
{
+ int rc = 0;
+
/* init can do anything it wants */
if (tsk->pid == 1)
return 0;
- switch (seclvl) {
- case 2:
- /* fall through */
- case 1:
- if (cap == CAP_LINUX_IMMUTABLE) {
+ if (seclvl > 0) {
+ rc = -EPERM;
+
+ if (cap == CAP_LINUX_IMMUTABLE)
seclvl_printk(1, KERN_WARNING, "Attempt to modify "
"the IMMUTABLE and/or APPEND extended "
"attribute on a file with the IMMUTABLE "
"and/or APPEND extended attribute set "
"denied in seclvl [%d]\n", seclvl);
- return -EPERM;
- } else if (cap == CAP_SYS_RAWIO) { // Somewhat broad...
+ else if (cap == CAP_SYS_RAWIO)
seclvl_printk(1, KERN_WARNING, "Attempt to perform "
"raw I/O while in secure level [%d] "
"denied\n", seclvl);
- return -EPERM;
- } else if (cap == CAP_NET_ADMIN) {
+ else if (cap == CAP_NET_ADMIN)
seclvl_printk(1, KERN_WARNING, "Attempt to perform "
"network administrative task while "
"in secure level [%d] denied\n", seclvl);
- return -EPERM;
- } else if (cap == CAP_SETUID) {
+ else if (cap == CAP_SETUID)
seclvl_printk(1, KERN_WARNING, "Attempt to setuid "
"while in secure level [%d] denied\n",
seclvl);
- return -EPERM;
- } else if (cap == CAP_SETGID) {
+ else if (cap == CAP_SETGID)
seclvl_printk(1, KERN_WARNING, "Attempt to setgid "
"while in secure level [%d] denied\n",
seclvl);
- } else if (cap == CAP_SYS_MODULE) {
+ else if (cap == CAP_SYS_MODULE)
seclvl_printk(1, KERN_WARNING, "Attempt to perform "
"a module operation while in secure "
"level [%d] denied\n", seclvl);
- return -EPERM;
- }
- break;
- default:
- break;
+ else
+ rc = 0;
}
- /* from dummy.c */
- if (cap_is_fs_cap(cap) ? tsk->fsuid == 0 : tsk->euid == 0)
- return 0; /* capability granted */
- seclvl_printk(1, KERN_WARNING, "Capability denied\n");
- return -EPERM; /* capability denied */
+
+ if (!rc) {
+ if (!(cap_is_fs_cap(cap) ? tsk->fsuid == 0 : tsk->euid == 0))
+ rc = -EPERM;
+ }
+
+ if (rc)
+ seclvl_printk(1, KERN_WARNING, "Capability denied\n");
+
+ return rc;
}
/**
@@ -466,12 +456,9 @@ static int seclvl_inode_setattr(struct dentry *dentry, struct iattr *iattr)
static void seclvl_file_free_security(struct file *filp)
{
struct dentry *dentry = filp->f_dentry;
- struct inode *inode = NULL;
- if (dentry) {
- inode = dentry->d_inode;
- seclvl_bd_release(inode);
- }
+ if (dentry)
+ seclvl_bd_release(dentry->d_inode);
}
/**
@@ -479,9 +466,7 @@ static void seclvl_file_free_security(struct file *filp)
*/
static int seclvl_umount(struct vfsmount *mnt, int flags)
{
- if (current->pid == 1)
- return 0;
- if (seclvl == 2) {
+ if (current->pid != 1 && seclvl == 2) {
seclvl_printk(1, KERN_WARNING, "Attempt to unmount in secure "
"level %d\n", seclvl);
return -EPERM;
@@ -505,8 +490,9 @@ static struct security_operations seclvl_ops = {
static int processPassword(void)
{
int rc = 0;
- hashedPassword[0] = '\0';
if (*passwd) {
+ char *p;
+
if (*sha1_passwd) {
seclvl_printk(0, KERN_ERR, "Error: Both "
"passwd and sha1_passwd "
@@ -514,12 +500,16 @@ static int processPassword(void)
"exclusive.\n");
return -EINVAL;
}
- if ((rc = plaintext_to_sha1(hashedPassword, passwd,
- strlen(passwd)))) {
+
+ p = kstrdup(passwd, GFP_KERNEL);
+ if (p == NULL)
+ return -ENOMEM;
+
+ if ((rc = plaintext_to_sha1(hashedPassword, p, strlen(p))))
seclvl_printk(0, KERN_ERR, "Error: SHA1 support not "
"in kernel\n");
- return rc;
- }
+
+ kfree (p);
/* All static data goes to the BSS, which zero's the
* plaintext password out for us. */
} else if (*sha1_passwd) { // Base 16
@@ -542,7 +532,7 @@ static int processPassword(void)
sha1_passwd[i + 2] = tmp;
}
}
- return 0;
+ return rc;
}
/**
@@ -552,28 +542,46 @@ struct dentry *dir_ino, *seclvl_ino, *passwd_ino;
static int seclvlfs_register(void)
{
+ int rc = 0;
+
dir_ino = securityfs_create_dir("seclvl", NULL);
- if (!dir_ino)
- return -EFAULT;
+
+ if (IS_ERR(dir_ino))
+ return PTR_ERR(dir_ino);
seclvl_ino = securityfs_create_file("seclvl", S_IRUGO | S_IWUSR,
dir_ino, &seclvl, &seclvl_file_ops);
- if (!seclvl_ino)
+ if (IS_ERR(seclvl_ino)) {
+ rc = PTR_ERR(seclvl_ino);
goto out_deldir;
+ }
if (*passwd || *sha1_passwd) {
passwd_ino = securityfs_create_file("passwd", S_IRUGO | S_IWUSR,
dir_ino, NULL, &passwd_file_ops);
- if (!passwd_ino)
+ if (IS_ERR(passwd_ino)) {
+ rc = PTR_ERR(passwd_ino);
goto out_delf;
+ }
}
- return 0;
+ return rc;
+
+out_delf:
+ securityfs_remove(seclvl_ino);
out_deldir:
securityfs_remove(dir_ino);
-out_delf:
+
+ return rc;
+}
+
+static void seclvlfs_unregister(void)
+{
securityfs_remove(seclvl_ino);
- return -EFAULT;
+ if (*passwd || *sha1_passwd)
+ securityfs_remove(passwd_ino);
+
+ securityfs_remove(dir_ino);
}
/**
@@ -582,6 +590,8 @@ out_delf:
static int __init seclvl_init(void)
{
int rc = 0;
+ static char once;
+
if (verbosity < 0 || verbosity > 1) {
printk(KERN_ERR "Error: bad verbosity [%d]; only 0 or 1 "
"are valid values\n", verbosity);
@@ -600,6 +610,11 @@ static int __init seclvl_init(void)
"module parameter(s): rc = [%d]\n", rc);
goto exit;
}
+
+ if ((rc = seclvlfs_register())) {
+ seclvl_printk(0, KERN_ERR, "Error registering with sysfs\n");
+ goto exit;
+ }
/* register ourselves with the security framework */
if (register_security(&seclvl_ops)) {
seclvl_printk(0, KERN_ERR,
@@ -611,20 +626,24 @@ static int __init seclvl_init(void)
seclvl_printk(0, KERN_ERR, "seclvl: Failure "
"registering with primary security "
"module.\n");
+ seclvlfs_unregister();
goto exit;
} /* if primary module registered */
secondary = 1;
} /* if we registered ourselves with the security framework */
- if ((rc = seclvlfs_register())) {
- seclvl_printk(0, KERN_ERR, "Error registering with sysfs\n");
- goto exit;
- }
+
seclvl_printk(0, KERN_INFO, "seclvl: Successfully initialized.\n");
+
+ if (once) {
+ once = 1;
+ seclvl_printk(0, KERN_INFO, "seclvl is going away. It has been "
+ "buggy for ages. Also, be warned that "
+ "Securelevels are useless.");
+ }
exit:
- if (rc) {
+ if (rc)
printk(KERN_ERR "seclvl: Error during initialization: rc = "
"[%d]\n", rc);
- }
return rc;
}
@@ -633,17 +652,14 @@ static int __init seclvl_init(void)
*/
static void __exit seclvl_exit(void)
{
- securityfs_remove(seclvl_ino);
- if (*passwd || *sha1_passwd)
- securityfs_remove(passwd_ino);
- securityfs_remove(dir_ino);
- if (secondary == 1) {
+ seclvlfs_unregister();
+
+ if (secondary)
mod_unreg_security(MY_NAME, &seclvl_ops);
- } else if (unregister_security(&seclvl_ops)) {
+ else if (unregister_security(&seclvl_ops))
seclvl_printk(0, KERN_INFO,
"seclvl: Failure unregistering with the "
"kernel\n");
- }
}
module_init(seclvl_init);
diff --git a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c
index fd25aca25120..972327c97644 100644
--- a/sound/oss/ac97_codec.c
+++ b/sound/oss/ac97_codec.c
@@ -55,7 +55,7 @@
#include <linux/pci.h>
#include <linux/ac97_codec.h>
#include <asm/uaccess.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
#define CODEC_ID_BUFSZ 14
@@ -304,7 +304,7 @@ static const unsigned int ac97_oss_rm[] = {
static LIST_HEAD(codecs);
static LIST_HEAD(codec_drivers);
-static DECLARE_MUTEX(codec_sem);
+static DEFINE_MUTEX(codec_mutex);
/* reads the given OSS mixer from the ac97 the caller must have insured that the ac97 knows
about that given mixer, and should be holding a spinlock for the card */
@@ -769,9 +769,9 @@ void ac97_release_codec(struct ac97_codec *codec)
{
/* Remove from the list first, we don't want to be
"rediscovered" */
- down(&codec_sem);
+ mutex_lock(&codec_mutex);
list_del(&codec->list);
- up(&codec_sem);
+ mutex_unlock(&codec_mutex);
/*
* The driver needs to deal with internal
* locking to avoid accidents here.
@@ -889,7 +889,7 @@ int ac97_probe_codec(struct ac97_codec *codec)
* callbacks.
*/
- down(&codec_sem);
+ mutex_lock(&codec_mutex);
list_add(&codec->list, &codecs);
list_for_each(l, &codec_drivers) {
@@ -903,7 +903,7 @@ int ac97_probe_codec(struct ac97_codec *codec)
}
}
- up(&codec_sem);
+ mutex_unlock(&codec_mutex);
return 1;
}
@@ -1439,7 +1439,7 @@ int ac97_register_driver(struct ac97_driver *driver)
struct list_head *l;
struct ac97_codec *c;
- down(&codec_sem);
+ mutex_lock(&codec_mutex);
INIT_LIST_HEAD(&driver->list);
list_add(&driver->list, &codec_drivers);
@@ -1452,7 +1452,7 @@ int ac97_register_driver(struct ac97_driver *driver)
continue;
c->driver = driver;
}
- up(&codec_sem);
+ mutex_unlock(&codec_mutex);
return 0;
}
@@ -1471,7 +1471,7 @@ void ac97_unregister_driver(struct ac97_driver *driver)
struct list_head *l;
struct ac97_codec *c;
- down(&codec_sem);
+ mutex_lock(&codec_mutex);
list_del_init(&driver->list);
list_for_each(l, &codecs)
@@ -1483,7 +1483,7 @@ void ac97_unregister_driver(struct ac97_driver *driver)
}
}
- up(&codec_sem);
+ mutex_unlock(&codec_mutex);
}
EXPORT_SYMBOL_GPL(ac97_unregister_driver);
@@ -1494,14 +1494,14 @@ static int swap_headphone(int remove_master)
struct ac97_codec *c;
if (remove_master) {
- down(&codec_sem);
+ mutex_lock(&codec_mutex);
list_for_each(l, &codecs)
{
c = list_entry(l, struct ac97_codec, list);
if (supported_mixer(c, SOUND_MIXER_PHONEOUT))
c->supported_mixers &= ~SOUND_MASK_PHONEOUT;
}
- up(&codec_sem);
+ mutex_unlock(&codec_mutex);
} else
ac97_hw[SOUND_MIXER_PHONEOUT].offset = AC97_MASTER_VOL_STEREO;
diff --git a/sound/oss/aci.c b/sound/oss/aci.c
index 3928c2802cc4..3bfac375dbdb 100644
--- a/sound/oss/aci.c
+++ b/sound/oss/aci.c
@@ -56,7 +56,8 @@
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/slab.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
+
#include <asm/io.h>
#include <asm/uaccess.h>
#include "sound_config.h"
@@ -79,7 +80,7 @@ static int aci_micpreamp=3; /* microphone preamp-level that can't be *
* checked with ACI versions prior to 0xb0 */
static int mixer_device;
-static struct semaphore aci_sem;
+static struct mutex aci_mutex;
#ifdef MODULE
static int reset;
@@ -212,7 +213,7 @@ int aci_rw_cmd(int write1, int write2, int write3)
int write[] = {write1, write2, write3};
int read = -EINTR, i;
- if (down_interruptible(&aci_sem))
+ if (mutex_lock_interruptible(&aci_mutex))
goto out;
for (i=0; i<3; i++) {
@@ -227,7 +228,7 @@ int aci_rw_cmd(int write1, int write2, int write3)
}
read = aci_rawread();
-out_up: up(&aci_sem);
+out_up: mutex_unlock(&aci_mutex);
out: return read;
}
@@ -603,7 +604,7 @@ static int __init attach_aci(void)
char *boardname;
int i, rc = -EBUSY;
- init_MUTEX(&aci_sem);
+ mutex_init(&aci_mutex);
outb(0xE3, 0xf8f); /* Write MAD16 password */
aci_port = (inb(0xf90) & 0x10) ?
diff --git a/sound/oss/ad1889.c b/sound/oss/ad1889.c
index a0d73f343100..54dabf862802 100644
--- a/sound/oss/ad1889.c
+++ b/sound/oss/ad1889.c
@@ -38,6 +38,7 @@
#include <linux/ac97_codec.h>
#include <linux/sound.h>
#include <linux/interrupt.h>
+#include <linux/mutex.h>
#include <asm/delay.h>
#include <asm/io.h>
@@ -238,7 +239,7 @@ static ad1889_dev_t *ad1889_alloc_dev(struct pci_dev *pci)
for (i = 0; i < AD_MAX_STATES; i++) {
dev->state[i].card = dev;
- init_MUTEX(&dev->state[i].sem);
+ mutex_init(&dev->state[i].mutex);
init_waitqueue_head(&dev->state[i].dmabuf.wait);
}
@@ -461,7 +462,7 @@ static ssize_t ad1889_write(struct file *file, const char __user *buffer, size_t
ssize_t ret = 0;
DECLARE_WAITQUEUE(wait, current);
- down(&state->sem);
+ mutex_lock(&state->mutex);
#if 0
if (dmabuf->mapped) {
ret = -ENXIO;
@@ -546,7 +547,7 @@ static ssize_t ad1889_write(struct file *file, const char __user *buffer, size_t
err2:
remove_wait_queue(&state->dmabuf.wait, &wait);
err1:
- up(&state->sem);
+ mutex_unlock(&state->mutex);
return ret;
}
diff --git a/sound/oss/ad1889.h b/sound/oss/ad1889.h
index e04affce1dd1..861b3213f30b 100644
--- a/sound/oss/ad1889.h
+++ b/sound/oss/ad1889.h
@@ -100,7 +100,7 @@ typedef struct ad1889_state {
unsigned int subdivision;
} dmabuf;
- struct semaphore sem;
+ struct mutex mutex;
} ad1889_state_t;
typedef struct ad1889_dev {
diff --git a/sound/oss/ali5455.c b/sound/oss/ali5455.c
index 9c9e6c0410f2..62bb936b1f3d 100644
--- a/sound/oss/ali5455.c
+++ b/sound/oss/ali5455.c
@@ -64,6 +64,8 @@
#include <linux/smp_lock.h>
#include <linux/ac97_codec.h>
#include <linux/interrupt.h>
+#include <linux/mutex.h>
+
#include <asm/uaccess.h>
#ifndef PCI_DEVICE_ID_ALI_5455
@@ -234,7 +236,7 @@ struct ali_state {
struct ali_card *card; /* Card info */
/* single open lock mechanism, only used for recording */
- struct semaphore open_sem;
+ struct mutex open_mutex;
wait_queue_head_t open_wait;
/* file mode */
@@ -2807,7 +2809,7 @@ found_virt:
state->card = card;
state->magic = ALI5455_STATE_MAGIC;
init_waitqueue_head(&dmabuf->wait);
- init_MUTEX(&state->open_sem);
+ mutex_init(&state->open_mutex);
file->private_data = state;
dmabuf->trigger = 0;
/* allocate hardware channels */
@@ -3359,7 +3361,7 @@ static void __devinit ali_configure_clocking(void)
state->card = card;
state->magic = ALI5455_STATE_MAGIC;
init_waitqueue_head(&dmabuf->wait);
- init_MUTEX(&state->open_sem);
+ mutex_init(&state->open_mutex);
dmabuf->fmt = ALI5455_FMT_STEREO | ALI5455_FMT_16BIT;
dmabuf->trigger = PCM_ENABLE_OUTPUT;
ali_set_dac_rate(state, 48000);
diff --git a/sound/oss/au1000.c b/sound/oss/au1000.c
index c407de86cbb6..fe54de25aafc 100644
--- a/sound/oss/au1000.c
+++ b/sound/oss/au1000.c
@@ -68,6 +68,8 @@
#include <linux/smp_lock.h>
#include <linux/ac97_codec.h>
#include <linux/interrupt.h>
+#include <linux/mutex.h>
+
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/mach-au1x00/au1000.h>
@@ -120,8 +122,8 @@ struct au1000_state {
int no_vra; // do not use VRA
spinlock_t lock;
- struct semaphore open_sem;
- struct semaphore sem;
+ struct mutex open_mutex;
+ struct mutex sem;
mode_t open_mode;
wait_queue_head_t open_wait;
@@ -1106,7 +1108,7 @@ static ssize_t au1000_read(struct file *file, char *buffer,
count *= db->cnt_factor;
- down(&s->sem);
+ mutex_lock(&s->sem);
add_wait_queue(&db->wait, &wait);
while (count > 0) {
@@ -1125,14 +1127,14 @@ static ssize_t au1000_read(struct file *file, char *buffer,
ret = -EAGAIN;
goto out;
}
- up(&s->sem);
+ mutex_unlock(&s->sem);
schedule();
if (signal_pending(current)) {
if (!ret)
ret = -ERESTARTSYS;
goto out2;
}
- down(&s->sem);
+ mutex_lock(&s->sem);
}
} while (avail <= 0);
@@ -1159,7 +1161,7 @@ static ssize_t au1000_read(struct file *file, char *buffer,
} // while (count > 0)
out:
- up(&s->sem);
+ mutex_unlock(&s->sem);
out2:
remove_wait_queue(&db->wait, &wait);
set_current_state(TASK_RUNNING);
@@ -1187,7 +1189,7 @@ static ssize_t au1000_write(struct file *file, const char *buffer,
count *= db->cnt_factor;
- down(&s->sem);
+ mutex_lock(&s->sem);
add_wait_queue(&db->wait, &wait);
while (count > 0) {
@@ -1204,14 +1206,14 @@ static ssize_t au1000_write(struct file *file, const char *buffer,
ret = -EAGAIN;
goto out;
}
- up(&s->sem);
+ mutex_unlock(&s->sem);
schedule();
if (signal_pending(current)) {
if (!ret)
ret = -ERESTARTSYS;
goto out2;
}
- down(&s->sem);
+ mutex_lock(&s->sem);
}
} while (avail <= 0);
@@ -1240,7 +1242,7 @@ static ssize_t au1000_write(struct file *file, const char *buffer,
} // while (count > 0)
out:
- up(&s->sem);
+ mutex_unlock(&s->sem);
out2:
remove_wait_queue(&db->wait, &wait);
set_current_state(TASK_RUNNING);
@@ -1298,7 +1300,7 @@ static int au1000_mmap(struct file *file, struct vm_area_struct *vma)
dbg("%s", __FUNCTION__);
lock_kernel();
- down(&s->sem);
+ mutex_lock(&s->sem);
if (vma->vm_flags & VM_WRITE)
db = &s->dma_dac;
else if (vma->vm_flags & VM_READ)
@@ -1324,7 +1326,7 @@ static int au1000_mmap(struct file *file, struct vm_area_struct *vma)
vma->vm_flags &= ~VM_IO;
db->mapped = 1;
out:
- up(&s->sem);
+ mutex_unlock(&s->sem);
unlock_kernel();
return ret;
}
@@ -1829,21 +1831,21 @@ static int au1000_open(struct inode *inode, struct file *file)
file->private_data = s;
/* wait for device to become free */
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
while (s->open_mode & file->f_mode) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return -EBUSY;
}
add_wait_queue(&s->open_wait, &wait);
__set_current_state(TASK_INTERRUPTIBLE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
schedule();
remove_wait_queue(&s->open_wait, &wait);
set_current_state(TASK_RUNNING);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
}
stop_dac(s);
@@ -1879,8 +1881,8 @@ static int au1000_open(struct inode *inode, struct file *file)
}
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
- up(&s->open_sem);
- init_MUTEX(&s->sem);
+ mutex_unlock(&s->open_mutex);
+ mutex_init(&s->sem);
return nonseekable_open(inode, file);
}
@@ -1896,7 +1898,7 @@ static int au1000_release(struct inode *inode, struct file *file)
lock_kernel();
}
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
if (file->f_mode & FMODE_WRITE) {
stop_dac(s);
dealloc_dmabuf(s, &s->dma_dac);
@@ -1906,7 +1908,7 @@ static int au1000_release(struct inode *inode, struct file *file)
dealloc_dmabuf(s, &s->dma_adc);
}
s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE));
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
wake_up(&s->open_wait);
unlock_kernel();
return 0;
@@ -1996,7 +1998,7 @@ static int __devinit au1000_probe(void)
init_waitqueue_head(&s->dma_adc.wait);
init_waitqueue_head(&s->dma_dac.wait);
init_waitqueue_head(&s->open_wait);
- init_MUTEX(&s->open_sem);
+ mutex_init(&s->open_mutex);
spin_lock_init(&s->lock);
s->codec.private_data = s;
s->codec.id = 0;
diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c
index bdee0502f3e2..6a4956b8025d 100644
--- a/sound/oss/au1550_ac97.c
+++ b/sound/oss/au1550_ac97.c
@@ -52,6 +52,8 @@
#include <linux/spinlock.h>
#include <linux/smp_lock.h>
#include <linux/ac97_codec.h>
+#include <linux/mutex.h>
+
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/hardirq.h>
@@ -90,8 +92,8 @@ static struct au1550_state {
int no_vra; /* do not use VRA */
spinlock_t lock;
- struct semaphore open_sem;
- struct semaphore sem;
+ struct mutex open_mutex;
+ struct mutex sem;
mode_t open_mode;
wait_queue_head_t open_wait;
@@ -1044,7 +1046,7 @@ au1550_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
count *= db->cnt_factor;
- down(&s->sem);
+ mutex_lock(&s->sem);
add_wait_queue(&db->wait, &wait);
while (count > 0) {
@@ -1064,14 +1066,14 @@ au1550_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
ret = -EAGAIN;
goto out;
}
- up(&s->sem);
+ mutex_unlock(&s->sem);
schedule();
if (signal_pending(current)) {
if (!ret)
ret = -ERESTARTSYS;
goto out2;
}
- down(&s->sem);
+ mutex_lock(&s->sem);
}
} while (avail <= 0);
@@ -1099,7 +1101,7 @@ au1550_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
} /* while (count > 0) */
out:
- up(&s->sem);
+ mutex_unlock(&s->sem);
out2:
remove_wait_queue(&db->wait, &wait);
set_current_state(TASK_RUNNING);
@@ -1125,7 +1127,7 @@ au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
count *= db->cnt_factor;
- down(&s->sem);
+ mutex_lock(&s->sem);
add_wait_queue(&db->wait, &wait);
while (count > 0) {
@@ -1143,14 +1145,14 @@ au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
ret = -EAGAIN;
goto out;
}
- up(&s->sem);
+ mutex_unlock(&s->sem);
schedule();
if (signal_pending(current)) {
if (!ret)
ret = -ERESTARTSYS;
goto out2;
}
- down(&s->sem);
+ mutex_lock(&s->sem);
}
} while (avail <= 0);
@@ -1196,7 +1198,7 @@ au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
} /* while (count > 0) */
out:
- up(&s->sem);
+ mutex_unlock(&s->sem);
out2:
remove_wait_queue(&db->wait, &wait);
set_current_state(TASK_RUNNING);
@@ -1253,7 +1255,7 @@ au1550_mmap(struct file *file, struct vm_area_struct *vma)
int ret = 0;
lock_kernel();
- down(&s->sem);
+ mutex_lock(&s->sem);
if (vma->vm_flags & VM_WRITE)
db = &s->dma_dac;
else if (vma->vm_flags & VM_READ)
@@ -1279,7 +1281,7 @@ au1550_mmap(struct file *file, struct vm_area_struct *vma)
vma->vm_flags &= ~VM_IO;
db->mapped = 1;
out:
- up(&s->sem);
+ mutex_unlock(&s->sem);
unlock_kernel();
return ret;
}
@@ -1790,21 +1792,21 @@ au1550_open(struct inode *inode, struct file *file)
file->private_data = s;
/* wait for device to become free */
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
while (s->open_mode & file->f_mode) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return -EBUSY;
}
add_wait_queue(&s->open_wait, &wait);
__set_current_state(TASK_INTERRUPTIBLE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
schedule();
remove_wait_queue(&s->open_wait, &wait);
set_current_state(TASK_RUNNING);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
}
stop_dac(s);
@@ -1840,8 +1842,8 @@ au1550_open(struct inode *inode, struct file *file)
}
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
- up(&s->open_sem);
- init_MUTEX(&s->sem);
+ mutex_unlock(&s->open_mutex);
+ mutex_init(&s->sem);
return 0;
}
@@ -1858,7 +1860,7 @@ au1550_release(struct inode *inode, struct file *file)
lock_kernel();
}
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
if (file->f_mode & FMODE_WRITE) {
stop_dac(s);
kfree(s->dma_dac.rawbuf);
@@ -1870,7 +1872,7 @@ au1550_release(struct inode *inode, struct file *file)
s->dma_adc.rawbuf = NULL;
}
s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE));
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
wake_up(&s->open_wait);
unlock_kernel();
return 0;
@@ -1902,7 +1904,7 @@ au1550_probe(void)
init_waitqueue_head(&s->dma_adc.wait);
init_waitqueue_head(&s->dma_dac.wait);
init_waitqueue_head(&s->open_wait);
- init_MUTEX(&s->open_sem);
+ mutex_init(&s->open_mutex);
spin_lock_init(&s->lock);
s->codec = ac97_alloc_codec();
diff --git a/sound/oss/btaudio.c b/sound/oss/btaudio.c
index 4007a5680acb..bfe3b534ef30 100644
--- a/sound/oss/btaudio.c
+++ b/sound/oss/btaudio.c
@@ -32,6 +32,8 @@
#include <linux/soundcard.h>
#include <linux/slab.h>
#include <linux/kdev_t.h>
+#include <linux/mutex.h>
+
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -108,7 +110,7 @@ struct btaudio {
/* locking */
int users;
- struct semaphore lock;
+ struct mutex lock;
/* risc instructions */
unsigned int risc_size;
@@ -440,7 +442,7 @@ static struct file_operations btaudio_mixer_fops = {
static int btaudio_dsp_open(struct inode *inode, struct file *file,
struct btaudio *bta, int analog)
{
- down(&bta->lock);
+ mutex_lock(&bta->lock);
if (bta->users)
goto busy;
bta->users++;
@@ -452,11 +454,11 @@ static int btaudio_dsp_open(struct inode *inode, struct file *file,
bta->read_count = 0;
bta->sampleshift = 0;
- up(&bta->lock);
+ mutex_unlock(&bta->lock);
return 0;
busy:
- up(&bta->lock);
+ mutex_unlock(&bta->lock);
return -EBUSY;
}
@@ -496,11 +498,11 @@ static int btaudio_dsp_release(struct inode *inode, struct file *file)
{
struct btaudio *bta = file->private_data;
- down(&bta->lock);
+ mutex_lock(&bta->lock);
if (bta->recording)
stop_recording(bta);
bta->users--;
- up(&bta->lock);
+ mutex_unlock(&bta->lock);
return 0;
}
@@ -513,7 +515,7 @@ static ssize_t btaudio_dsp_read(struct file *file, char __user *buffer,
DECLARE_WAITQUEUE(wait, current);
add_wait_queue(&bta->readq, &wait);
- down(&bta->lock);
+ mutex_lock(&bta->lock);
while (swcount > 0) {
if (0 == bta->read_count) {
if (!bta->recording) {
@@ -528,10 +530,10 @@ static ssize_t btaudio_dsp_read(struct file *file, char __user *buffer,
ret = -EAGAIN;
break;
}
- up(&bta->lock);
+ mutex_unlock(&bta->lock);
current->state = TASK_INTERRUPTIBLE;
schedule();
- down(&bta->lock);
+ mutex_lock(&bta->lock);
if(signal_pending(current)) {
if (0 == ret)
ret = -EINTR;
@@ -604,7 +606,7 @@ static ssize_t btaudio_dsp_read(struct file *file, char __user *buffer,
if (bta->read_offset == bta->buf_size)
bta->read_offset = 0;
}
- up(&bta->lock);
+ mutex_unlock(&bta->lock);
remove_wait_queue(&bta->readq, &wait);
current->state = TASK_RUNNING;
return ret;
@@ -651,10 +653,10 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
bta->decimation = 0;
}
if (bta->recording) {
- down(&bta->lock);
+ mutex_lock(&bta->lock);
stop_recording(bta);
start_recording(bta);
- up(&bta->lock);
+ mutex_unlock(&bta->lock);
}
/* fall through */
case SOUND_PCM_READ_RATE:
@@ -716,10 +718,10 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
else
bta->bits = 16;
if (bta->recording) {
- down(&bta->lock);
+ mutex_lock(&bta->lock);
stop_recording(bta);
start_recording(bta);
- up(&bta->lock);
+ mutex_unlock(&bta->lock);
}
}
if (debug)
@@ -736,9 +738,9 @@ static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
case SNDCTL_DSP_RESET:
if (bta->recording) {
- down(&bta->lock);
+ mutex_lock(&bta->lock);
stop_recording(bta);
- up(&bta->lock);
+ mutex_unlock(&bta->lock);
}
return 0;
case SNDCTL_DSP_GETBLKSIZE:
@@ -941,7 +943,7 @@ static int __devinit btaudio_probe(struct pci_dev *pci_dev,
if (rate)
bta->rate = rate;
- init_MUTEX(&bta->lock);
+ mutex_init(&bta->lock);
init_waitqueue_head(&bta->readq);
if (-1 != latency) {
diff --git a/sound/oss/cmpci.c b/sound/oss/cmpci.c
index 7cfbb08db537..1fbd5137f6d7 100644
--- a/sound/oss/cmpci.c
+++ b/sound/oss/cmpci.c
@@ -138,6 +138,8 @@
#endif
#ifdef CONFIG_SOUND_CMPCI_JOYSTICK
#include <linux/gameport.h>
+#include <linux/mutex.h>
+
#endif
/* --------------------------------------------------------------------- */
@@ -392,7 +394,7 @@ struct cm_state {
unsigned char fmt, enable;
spinlock_t lock;
- struct semaphore open_sem;
+ struct mutex open_mutex;
mode_t open_mode;
wait_queue_head_t open_wait;
@@ -2825,21 +2827,21 @@ static int cm_open(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
file->private_data = s;
/* wait for device to become free */
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
while (s->open_mode & file->f_mode) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return -EBUSY;
}
add_wait_queue(&s->open_wait, &wait);
__set_current_state(TASK_INTERRUPTIBLE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
schedule();
remove_wait_queue(&s->open_wait, &wait);
set_current_state(TASK_RUNNING);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
}
if (file->f_mode & FMODE_READ) {
s->status &= ~DO_BIGENDIAN_R;
@@ -2867,7 +2869,7 @@ static int cm_open(struct inode *inode, struct file *file)
}
set_fmt(s, fmtm, fmts);
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return nonseekable_open(inode, file);
}
@@ -2879,7 +2881,7 @@ static int cm_release(struct inode *inode, struct file *file)
lock_kernel();
if (file->f_mode & FMODE_WRITE)
drain_dac(s, file->f_flags & O_NONBLOCK);
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
if (file->f_mode & FMODE_WRITE) {
stop_dac(s);
@@ -2903,7 +2905,7 @@ static int cm_release(struct inode *inode, struct file *file)
s->status &= ~DO_BIGENDIAN_R;
}
s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE));
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
wake_up(&s->open_wait);
unlock_kernel();
return 0;
@@ -3080,7 +3082,7 @@ static int __devinit cm_probe(struct pci_dev *pcidev, const struct pci_device_id
init_waitqueue_head(&s->dma_adc.wait);
init_waitqueue_head(&s->dma_dac.wait);
init_waitqueue_head(&s->open_wait);
- init_MUTEX(&s->open_sem);
+ mutex_init(&s->open_mutex);
spin_lock_init(&s->lock);
s->magic = CM_MAGIC;
s->dev = pcidev;
diff --git a/sound/oss/cs4281/cs4281m.c b/sound/oss/cs4281/cs4281m.c
index 0720365f6438..0004442f9b7e 100644
--- a/sound/oss/cs4281/cs4281m.c
+++ b/sound/oss/cs4281/cs4281m.c
@@ -245,9 +245,9 @@ struct cs4281_state {
void *tmpbuff; // tmp buffer for sample conversions
unsigned ena;
spinlock_t lock;
- struct semaphore open_sem;
- struct semaphore open_sem_adc;
- struct semaphore open_sem_dac;
+ struct mutex open_sem;
+ struct mutex open_sem_adc;
+ struct mutex open_sem_dac;
mode_t open_mode;
wait_queue_head_t open_wait;
wait_queue_head_t open_wait_adc;
@@ -3598,20 +3598,20 @@ static int cs4281_release(struct inode *inode, struct file *file)
if (file->f_mode & FMODE_WRITE) {
drain_dac(s, file->f_flags & O_NONBLOCK);
- down(&s->open_sem_dac);
+ mutex_lock(&s->open_sem_dac);
stop_dac(s);
dealloc_dmabuf(s, &s->dma_dac);
s->open_mode &= ~FMODE_WRITE;
- up(&s->open_sem_dac);
+ mutex_unlock(&s->open_sem_dac);
wake_up(&s->open_wait_dac);
}
if (file->f_mode & FMODE_READ) {
drain_adc(s, file->f_flags & O_NONBLOCK);
- down(&s->open_sem_adc);
+ mutex_lock(&s->open_sem_adc);
stop_adc(s);
dealloc_dmabuf(s, &s->dma_adc);
s->open_mode &= ~FMODE_READ;
- up(&s->open_sem_adc);
+ mutex_unlock(&s->open_sem_adc);
wake_up(&s->open_wait_adc);
}
return 0;
@@ -3651,33 +3651,33 @@ static int cs4281_open(struct inode *inode, struct file *file)
return -ENODEV;
}
if (file->f_mode & FMODE_WRITE) {
- down(&s->open_sem_dac);
+ mutex_lock(&s->open_sem_dac);
while (s->open_mode & FMODE_WRITE) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem_dac);
+ mutex_unlock(&s->open_sem_dac);
return -EBUSY;
}
- up(&s->open_sem_dac);
+ mutex_unlock(&s->open_sem_dac);
interruptible_sleep_on(&s->open_wait_dac);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem_dac);
+ mutex_lock(&s->open_sem_dac);
}
}
if (file->f_mode & FMODE_READ) {
- down(&s->open_sem_adc);
+ mutex_lock(&s->open_sem_adc);
while (s->open_mode & FMODE_READ) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem_adc);
+ mutex_unlock(&s->open_sem_adc);
return -EBUSY;
}
- up(&s->open_sem_adc);
+ mutex_unlock(&s->open_sem_adc);
interruptible_sleep_on(&s->open_wait_adc);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem_adc);
+ mutex_lock(&s->open_sem_adc);
}
}
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
@@ -3691,7 +3691,7 @@ static int cs4281_open(struct inode *inode, struct file *file)
s->ena &= ~FMODE_READ;
s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
s->dma_adc.subdivision = 0;
- up(&s->open_sem_adc);
+ mutex_unlock(&s->open_sem_adc);
if (prog_dmabuf_adc(s)) {
CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR
@@ -3711,7 +3711,7 @@ static int cs4281_open(struct inode *inode, struct file *file)
s->ena &= ~FMODE_WRITE;
s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
s->dma_dac.subdivision = 0;
- up(&s->open_sem_dac);
+ mutex_unlock(&s->open_sem_dac);
if (prog_dmabuf_dac(s)) {
CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR
@@ -3978,17 +3978,17 @@ static int cs4281_midi_open(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
file->private_data = s;
// wait for device to become free
- down(&s->open_sem);
+ mutex_lock(&s->open_sem);
while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_sem);
return -EBUSY;
}
- up(&s->open_sem);
+ mutex_unlock(&s->open_sem);
interruptible_sleep_on(&s->open_wait);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem);
+ mutex_lock(&s->open_sem);
}
spin_lock_irqsave(&s->lock, flags);
if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
@@ -4018,7 +4018,7 @@ static int cs4281_midi_open(struct inode *inode, struct file *file)
(file->
f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ |
FMODE_MIDI_WRITE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_sem);
return nonseekable_open(inode, file);
}
@@ -4057,7 +4057,7 @@ static int cs4281_midi_release(struct inode *inode, struct file *file)
remove_wait_queue(&s->midi.owait, &wait);
current->state = TASK_RUNNING;
}
- down(&s->open_sem);
+ mutex_lock(&s->open_sem);
s->open_mode &=
(~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ |
FMODE_MIDI_WRITE);
@@ -4067,7 +4067,7 @@ static int cs4281_midi_release(struct inode *inode, struct file *file)
del_timer(&s->midi.timer);
}
spin_unlock_irqrestore(&s->lock, flags);
- up(&s->open_sem);
+ mutex_unlock(&s->open_sem);
wake_up(&s->open_wait);
return 0;
}
@@ -4300,9 +4300,9 @@ static int __devinit cs4281_probe(struct pci_dev *pcidev,
init_waitqueue_head(&s->open_wait_dac);
init_waitqueue_head(&s->midi.iwait);
init_waitqueue_head(&s->midi.owait);
- init_MUTEX(&s->open_sem);
- init_MUTEX(&s->open_sem_adc);
- init_MUTEX(&s->open_sem_dac);
+ mutex_init(&s->open_sem);
+ mutex_init(&s->open_sem_adc);
+ mutex_init(&s->open_sem_dac);
spin_lock_init(&s->lock);
s->pBA0phys = pci_resource_start(pcidev, 0);
s->pBA1phys = pci_resource_start(pcidev, 1);
diff --git a/sound/oss/cs46xx.c b/sound/oss/cs46xx.c
index 58e25c82eaf2..53881bc91bba 100644
--- a/sound/oss/cs46xx.c
+++ b/sound/oss/cs46xx.c
@@ -90,6 +90,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/ac97_codec.h>
+#include <linux/mutex.h>
#include <asm/io.h>
#include <asm/dma.h>
@@ -238,7 +239,7 @@ struct cs_state {
struct cs_card *card; /* Card info */
/* single open lock mechanism, only used for recording */
- struct semaphore open_sem;
+ struct mutex open_mutex;
wait_queue_head_t open_wait;
/* file mode */
@@ -297,7 +298,7 @@ struct cs_state {
unsigned subdivision;
} dmabuf;
/* Guard against mmap/write/read races */
- struct semaphore sem;
+ struct mutex sem;
};
struct cs_card {
@@ -375,7 +376,7 @@ struct cs_card {
unsigned char ibuf[CS_MIDIINBUF];
unsigned char obuf[CS_MIDIOUTBUF];
mode_t open_mode;
- struct semaphore open_sem;
+ struct mutex open_mutex;
} midi;
struct cs46xx_pm pm;
};
@@ -1428,9 +1429,9 @@ static int prog_dmabuf(struct cs_state *state)
{
int ret;
- down(&state->sem);
+ mutex_lock(&state->sem);
ret = __prog_dmabuf(state);
- up(&state->sem);
+ mutex_unlock(&state->sem);
return ret;
}
@@ -1831,17 +1832,17 @@ static int cs_midi_open(struct inode *inode, struct file *file)
file->private_data = card;
/* wait for device to become free */
- down(&card->midi.open_sem);
+ mutex_lock(&card->midi.open_mutex);
while (card->midi.open_mode & file->f_mode) {
if (file->f_flags & O_NONBLOCK) {
- up(&card->midi.open_sem);
+ mutex_unlock(&card->midi.open_mutex);
return -EBUSY;
}
- up(&card->midi.open_sem);
+ mutex_unlock(&card->midi.open_mutex);
interruptible_sleep_on(&card->midi.open_wait);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&card->midi.open_sem);
+ mutex_lock(&card->midi.open_mutex);
}
spin_lock_irqsave(&card->midi.lock, flags);
if (!(card->midi.open_mode & (FMODE_READ | FMODE_WRITE))) {
@@ -1859,7 +1860,7 @@ static int cs_midi_open(struct inode *inode, struct file *file)
}
spin_unlock_irqrestore(&card->midi.lock, flags);
card->midi.open_mode |= (file->f_mode & (FMODE_READ | FMODE_WRITE));
- up(&card->midi.open_sem);
+ mutex_unlock(&card->midi.open_mutex);
return 0;
}
@@ -1891,9 +1892,9 @@ static int cs_midi_release(struct inode *inode, struct file *file)
remove_wait_queue(&card->midi.owait, &wait);
current->state = TASK_RUNNING;
}
- down(&card->midi.open_sem);
+ mutex_lock(&card->midi.open_mutex);
card->midi.open_mode &= (~(file->f_mode & (FMODE_READ | FMODE_WRITE)));
- up(&card->midi.open_sem);
+ mutex_unlock(&card->midi.open_mutex);
wake_up(&card->midi.open_wait);
return 0;
}
@@ -2081,7 +2082,7 @@ static ssize_t cs_read(struct file *file, char __user *buffer, size_t count, lof
if (!access_ok(VERIFY_WRITE, buffer, count))
return -EFAULT;
- down(&state->sem);
+ mutex_lock(&state->sem);
if (!dmabuf->ready && (ret = __prog_dmabuf(state)))
goto out2;
@@ -2114,13 +2115,13 @@ static ssize_t cs_read(struct file *file, char __user *buffer, size_t count, lof
if (!ret) ret = -EAGAIN;
goto out;
}
- up(&state->sem);
+ mutex_unlock(&state->sem);
schedule();
if (signal_pending(current)) {
if(!ret) ret = -ERESTARTSYS;
goto out;
}
- down(&state->sem);
+ mutex_lock(&state->sem);
if (dmabuf->mapped)
{
if(!ret)
@@ -2155,7 +2156,7 @@ static ssize_t cs_read(struct file *file, char __user *buffer, size_t count, lof
out:
remove_wait_queue(&state->dmabuf.wait, &wait);
out2:
- up(&state->sem);
+ mutex_unlock(&state->sem);
set_current_state(TASK_RUNNING);
CS_DBGOUT(CS_WAVE_READ | CS_FUNCTION, 4,
printk("cs46xx: cs_read()- %zd\n",ret) );
@@ -2184,7 +2185,7 @@ static ssize_t cs_write(struct file *file, const char __user *buffer, size_t cou
return -EFAULT;
dmabuf = &state->dmabuf;
- down(&state->sem);
+ mutex_lock(&state->sem);
if (dmabuf->mapped)
{
ret = -ENXIO;
@@ -2240,13 +2241,13 @@ static ssize_t cs_write(struct file *file, const char __user *buffer, size_t cou
if (!ret) ret = -EAGAIN;
goto out;
}
- up(&state->sem);
+ mutex_unlock(&state->sem);
schedule();
if (signal_pending(current)) {
if(!ret) ret = -ERESTARTSYS;
goto out;
}
- down(&state->sem);
+ mutex_lock(&state->sem);
if (dmabuf->mapped)
{
if(!ret)
@@ -2278,7 +2279,7 @@ static ssize_t cs_write(struct file *file, const char __user *buffer, size_t cou
start_dac(state);
}
out:
- up(&state->sem);
+ mutex_unlock(&state->sem);
remove_wait_queue(&state->dmabuf.wait, &wait);
set_current_state(TASK_RUNNING);
@@ -2411,7 +2412,7 @@ static int cs_mmap(struct file *file, struct vm_area_struct *vma)
goto out;
}
- down(&state->sem);
+ mutex_lock(&state->sem);
dmabuf = &state->dmabuf;
if (cs4x_pgoff(vma) != 0)
{
@@ -2438,7 +2439,7 @@ static int cs_mmap(struct file *file, struct vm_area_struct *vma)
CS_DBGOUT(CS_FUNCTION, 2, printk("cs46xx: cs_mmap()-\n") );
out:
- up(&state->sem);
+ mutex_unlock(&state->sem);
return ret;
}
@@ -3200,7 +3201,7 @@ static int cs_open(struct inode *inode, struct file *file)
if (state == NULL)
return -ENOMEM;
memset(state, 0, sizeof(struct cs_state));
- init_MUTEX(&state->sem);
+ mutex_init(&state->sem);
dmabuf = &state->dmabuf;
dmabuf->pbuf = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
if(dmabuf->pbuf==NULL)
@@ -3241,10 +3242,10 @@ static int cs_open(struct inode *inode, struct file *file)
state->virt = 0;
state->magic = CS_STATE_MAGIC;
init_waitqueue_head(&dmabuf->wait);
- init_MUTEX(&state->open_sem);
+ mutex_init(&state->open_mutex);
file->private_data = card;
- down(&state->open_sem);
+ mutex_lock(&state->open_mutex);
/* set default sample format. According to OSS Programmer's Guide /dev/dsp
should be default to unsigned 8-bits, mono, with sample rate 8kHz and
@@ -3260,7 +3261,7 @@ static int cs_open(struct inode *inode, struct file *file)
cs_set_divisor(dmabuf);
state->open_mode |= FMODE_READ;
- up(&state->open_sem);
+ mutex_unlock(&state->open_mutex);
}
if(file->f_mode & FMODE_WRITE)
{
@@ -3271,7 +3272,7 @@ static int cs_open(struct inode *inode, struct file *file)
if (state == NULL)
return -ENOMEM;
memset(state, 0, sizeof(struct cs_state));
- init_MUTEX(&state->sem);
+ mutex_init(&state->sem);
dmabuf = &state->dmabuf;
dmabuf->pbuf = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
if(dmabuf->pbuf==NULL)
@@ -3312,10 +3313,10 @@ static int cs_open(struct inode *inode, struct file *file)
state->virt = 1;
state->magic = CS_STATE_MAGIC;
init_waitqueue_head(&dmabuf->wait);
- init_MUTEX(&state->open_sem);
+ mutex_init(&state->open_mutex);
file->private_data = card;
- down(&state->open_sem);
+ mutex_lock(&state->open_mutex);
/* set default sample format. According to OSS Programmer's Guide /dev/dsp
should be default to unsigned 8-bits, mono, with sample rate 8kHz and
@@ -3331,7 +3332,7 @@ static int cs_open(struct inode *inode, struct file *file)
cs_set_divisor(dmabuf);
state->open_mode |= FMODE_WRITE;
- up(&state->open_sem);
+ mutex_unlock(&state->open_mutex);
if((ret = prog_dmabuf(state)))
return ret;
}
@@ -3363,14 +3364,14 @@ static int cs_release(struct inode *inode, struct file *file)
cs_clear_tail(state);
drain_dac(state, file->f_flags & O_NONBLOCK);
/* stop DMA state machine and free DMA buffers/channels */
- down(&state->open_sem);
+ mutex_lock(&state->open_mutex);
stop_dac(state);
dealloc_dmabuf(state);
state->card->free_pcm_channel(state->card, dmabuf->channel->num);
free_page((unsigned long)state->dmabuf.pbuf);
- /* we're covered by the open_sem */
- up(&state->open_sem);
+ /* we're covered by the open_mutex */
+ mutex_unlock(&state->open_mutex);
state->card->states[state->virt] = NULL;
state->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
@@ -3395,14 +3396,14 @@ static int cs_release(struct inode *inode, struct file *file)
{
CS_DBGOUT(CS_RELEASE, 2, printk("cs46xx: cs_release() FMODE_READ\n") );
dmabuf = &state->dmabuf;
- down(&state->open_sem);
+ mutex_lock(&state->open_mutex);
stop_adc(state);
dealloc_dmabuf(state);
state->card->free_pcm_channel(state->card, dmabuf->channel->num);
free_page((unsigned long)state->dmabuf.pbuf);
- /* we're covered by the open_sem */
- up(&state->open_sem);
+ /* we're covered by the open_mutex */
+ mutex_unlock(&state->open_mutex);
state->card->states[state->virt] = NULL;
state->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
@@ -5507,7 +5508,7 @@ static int __devinit cs46xx_probe(struct pci_dev *pci_dev,
}
init_waitqueue_head(&card->midi.open_wait);
- init_MUTEX(&card->midi.open_sem);
+ mutex_init(&card->midi.open_mutex);
init_waitqueue_head(&card->midi.iwait);
init_waitqueue_head(&card->midi.owait);
cs461x_pokeBA0(card, BA0_MIDCR, MIDCR_MRST);
diff --git a/sound/oss/dmasound/dmasound_awacs.c b/sound/oss/dmasound/dmasound_awacs.c
index 74f975676ccb..a17375141c3a 100644
--- a/sound/oss/dmasound/dmasound_awacs.c
+++ b/sound/oss/dmasound/dmasound_awacs.c
@@ -80,7 +80,7 @@
#include <linux/kmod.h>
#include <linux/interrupt.h>
#include <linux/input.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
#ifdef CONFIG_ADB_CUDA
#include <linux/cuda.h>
#endif
@@ -130,7 +130,7 @@ static struct resource awacs_rsrc[3];
static char awacs_name[64];
static int awacs_revision;
static int awacs_sleeping;
-static DECLARE_MUTEX(dmasound_sem);
+static DEFINE_MUTEX(dmasound_mutex);
static int sound_device_id; /* exists after iMac revA */
static int hw_can_byteswap = 1 ; /* most pmac sound h/w can */
@@ -312,11 +312,11 @@ extern int daca_enter_sleep(void);
extern int daca_leave_sleep(void);
#define TRY_LOCK() \
- if ((rc = down_interruptible(&dmasound_sem)) != 0) \
+ if ((rc = mutex_lock_interruptible(&dmasound_mutex)) != 0) \
return rc;
-#define LOCK() down(&dmasound_sem);
+#define LOCK() mutex_lock(&dmasound_mutex);
-#define UNLOCK() up(&dmasound_sem);
+#define UNLOCK() mutex_unlock(&dmasound_mutex);
/* We use different versions that the ones provided in dmasound.h
*
diff --git a/sound/oss/emu10k1/hwaccess.h b/sound/oss/emu10k1/hwaccess.h
index 104223a192aa..85e27bda694b 100644
--- a/sound/oss/emu10k1/hwaccess.h
+++ b/sound/oss/emu10k1/hwaccess.h
@@ -181,7 +181,7 @@ struct emu10k1_card
struct emu10k1_mpuout *mpuout;
struct emu10k1_mpuin *mpuin;
- struct semaphore open_sem;
+ struct mutex open_sem;
mode_t open_mode;
wait_queue_head_t open_wait;
diff --git a/sound/oss/emu10k1/main.c b/sound/oss/emu10k1/main.c
index 23241cbdd90f..0cd44a6f7ac0 100644
--- a/sound/oss/emu10k1/main.c
+++ b/sound/oss/emu10k1/main.c
@@ -1320,7 +1320,7 @@ static int __devinit emu10k1_probe(struct pci_dev *pci_dev, const struct pci_dev
card->is_aps = (subsysvid == EMU_APS_SUBID);
spin_lock_init(&card->lock);
- init_MUTEX(&card->open_sem);
+ mutex_init(&card->open_sem);
card->open_mode = 0;
init_waitqueue_head(&card->open_wait);
diff --git a/sound/oss/emu10k1/midi.c b/sound/oss/emu10k1/midi.c
index b40b5f97aace..959a96794dba 100644
--- a/sound/oss/emu10k1/midi.c
+++ b/sound/oss/emu10k1/midi.c
@@ -110,21 +110,21 @@ match:
#endif
/* Wait for device to become free */
- down(&card->open_sem);
+ mutex_lock(&card->open_sem);
while (card->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
if (file->f_flags & O_NONBLOCK) {
- up(&card->open_sem);
+ mutex_unlock(&card->open_sem);
return -EBUSY;
}
- up(&card->open_sem);
+ mutex_unlock(&card->open_sem);
interruptible_sleep_on(&card->open_wait);
if (signal_pending(current)) {
return -ERESTARTSYS;
}
- down(&card->open_sem);
+ mutex_lock(&card->open_sem);
}
if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
@@ -183,7 +183,7 @@ match:
card->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
- up(&card->open_sem);
+ mutex_unlock(&card->open_sem);
return nonseekable_open(inode, file);
}
@@ -234,9 +234,9 @@ static int emu10k1_midi_release(struct inode *inode, struct file *file)
kfree(midi_dev);
- down(&card->open_sem);
+ mutex_lock(&card->open_sem);
card->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE));
- up(&card->open_sem);
+ mutex_unlock(&card->open_sem);
wake_up_interruptible(&card->open_wait);
unlock_kernel();
diff --git a/sound/oss/es1370.c b/sound/oss/es1370.c
index ae55c536613a..094f569cc6e0 100644
--- a/sound/oss/es1370.c
+++ b/sound/oss/es1370.c
@@ -157,6 +157,7 @@
#include <linux/gameport.h>
#include <linux/wait.h>
#include <linux/dma-mapping.h>
+#include <linux/mutex.h>
#include <asm/io.h>
#include <asm/page.h>
@@ -346,7 +347,7 @@ struct es1370_state {
unsigned sctrl;
spinlock_t lock;
- struct semaphore open_sem;
+ struct mutex open_mutex;
mode_t open_mode;
wait_queue_head_t open_wait;
@@ -393,7 +394,7 @@ struct es1370_state {
struct gameport *gameport;
#endif
- struct semaphore sem;
+ struct mutex mutex;
};
/* --------------------------------------------------------------------- */
@@ -1159,7 +1160,7 @@ static ssize_t es1370_read(struct file *file, char __user *buffer, size_t count,
return -ENXIO;
if (!access_ok(VERIFY_WRITE, buffer, count))
return -EFAULT;
- down(&s->sem);
+ mutex_lock(&s->mutex);
if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
goto out;
@@ -1183,14 +1184,14 @@ static ssize_t es1370_read(struct file *file, char __user *buffer, size_t count,
ret = -EAGAIN;
goto out;
}
- up(&s->sem);
+ mutex_unlock(&s->mutex);
schedule();
if (signal_pending(current)) {
if (!ret)
ret = -ERESTARTSYS;
goto out;
}
- down(&s->sem);
+ mutex_lock(&s->mutex);
if (s->dma_adc.mapped)
{
ret = -ENXIO;
@@ -1215,7 +1216,7 @@ static ssize_t es1370_read(struct file *file, char __user *buffer, size_t count,
start_adc(s);
}
out:
- up(&s->sem);
+ mutex_unlock(&s->mutex);
remove_wait_queue(&s->dma_adc.wait, &wait);
set_current_state(TASK_RUNNING);
return ret;
@@ -1235,7 +1236,7 @@ static ssize_t es1370_write(struct file *file, const char __user *buffer, size_t
return -ENXIO;
if (!access_ok(VERIFY_READ, buffer, count))
return -EFAULT;
- down(&s->sem);
+ mutex_lock(&s->mutex);
if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
goto out;
ret = 0;
@@ -1263,14 +1264,14 @@ static ssize_t es1370_write(struct file *file, const char __user *buffer, size_t
ret = -EAGAIN;
goto out;
}
- up(&s->sem);
+ mutex_unlock(&s->mutex);
schedule();
if (signal_pending(current)) {
if (!ret)
ret = -ERESTARTSYS;
goto out;
}
- down(&s->sem);
+ mutex_lock(&s->mutex);
if (s->dma_dac2.mapped)
{
ret = -ENXIO;
@@ -1296,7 +1297,7 @@ static ssize_t es1370_write(struct file *file, const char __user *buffer, size_t
start_dac2(s);
}
out:
- up(&s->sem);
+ mutex_unlock(&s->mutex);
remove_wait_queue(&s->dma_dac2.wait, &wait);
set_current_state(TASK_RUNNING);
return ret;
@@ -1348,7 +1349,7 @@ static int es1370_mmap(struct file *file, struct vm_area_struct *vma)
VALIDATE_STATE(s);
lock_kernel();
- down(&s->sem);
+ mutex_lock(&s->mutex);
if (vma->vm_flags & VM_WRITE) {
if ((ret = prog_dmabuf_dac2(s)) != 0) {
goto out;
@@ -1380,7 +1381,7 @@ static int es1370_mmap(struct file *file, struct vm_area_struct *vma)
}
db->mapped = 1;
out:
- up(&s->sem);
+ mutex_unlock(&s->mutex);
unlock_kernel();
return ret;
}
@@ -1752,21 +1753,21 @@ static int es1370_open(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
file->private_data = s;
/* wait for device to become free */
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
while (s->open_mode & file->f_mode) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return -EBUSY;
}
add_wait_queue(&s->open_wait, &wait);
__set_current_state(TASK_INTERRUPTIBLE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
schedule();
remove_wait_queue(&s->open_wait, &wait);
set_current_state(TASK_RUNNING);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
}
spin_lock_irqsave(&s->lock, flags);
if (!(s->open_mode & (FMODE_READ|FMODE_WRITE)))
@@ -1793,8 +1794,8 @@ static int es1370_open(struct inode *inode, struct file *file)
outl(s->ctrl, s->io+ES1370_REG_CONTROL);
spin_unlock_irqrestore(&s->lock, flags);
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
- up(&s->open_sem);
- init_MUTEX(&s->sem);
+ mutex_unlock(&s->open_mutex);
+ mutex_init(&s->mutex);
return nonseekable_open(inode, file);
}
@@ -1806,7 +1807,7 @@ static int es1370_release(struct inode *inode, struct file *file)
lock_kernel();
if (file->f_mode & FMODE_WRITE)
drain_dac2(s, file->f_flags & O_NONBLOCK);
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
if (file->f_mode & FMODE_WRITE) {
stop_dac2(s);
synchronize_irq(s->irq);
@@ -1818,7 +1819,7 @@ static int es1370_release(struct inode *inode, struct file *file)
}
s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE));
wake_up(&s->open_wait);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
unlock_kernel();
return 0;
}
@@ -2198,21 +2199,21 @@ static int es1370_open_dac(struct inode *inode, struct file *file)
return -EINVAL;
file->private_data = s;
/* wait for device to become free */
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
while (s->open_mode & FMODE_DAC) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return -EBUSY;
}
add_wait_queue(&s->open_wait, &wait);
__set_current_state(TASK_INTERRUPTIBLE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
schedule();
remove_wait_queue(&s->open_wait, &wait);
set_current_state(TASK_RUNNING);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
}
s->dma_dac1.ossfragshift = s->dma_dac1.ossmaxfrags = s->dma_dac1.subdivision = 0;
s->dma_dac1.enabled = 1;
@@ -2227,7 +2228,7 @@ static int es1370_open_dac(struct inode *inode, struct file *file)
outl(s->ctrl, s->io+ES1370_REG_CONTROL);
spin_unlock_irqrestore(&s->lock, flags);
s->open_mode |= FMODE_DAC;
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return nonseekable_open(inode, file);
}
@@ -2238,12 +2239,12 @@ static int es1370_release_dac(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
lock_kernel();
drain_dac1(s, file->f_flags & O_NONBLOCK);
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
stop_dac1(s);
dealloc_dmabuf(s, &s->dma_dac1);
s->open_mode &= ~FMODE_DAC;
wake_up(&s->open_wait);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
unlock_kernel();
return 0;
}
@@ -2430,21 +2431,21 @@ static int es1370_midi_open(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
file->private_data = s;
/* wait for device to become free */
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return -EBUSY;
}
add_wait_queue(&s->open_wait, &wait);
__set_current_state(TASK_INTERRUPTIBLE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
schedule();
remove_wait_queue(&s->open_wait, &wait);
set_current_state(TASK_RUNNING);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
}
spin_lock_irqsave(&s->lock, flags);
if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
@@ -2465,7 +2466,7 @@ static int es1370_midi_open(struct inode *inode, struct file *file)
es1370_handle_midi(s);
spin_unlock_irqrestore(&s->lock, flags);
s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return nonseekable_open(inode, file);
}
@@ -2499,7 +2500,7 @@ static int es1370_midi_release(struct inode *inode, struct file *file)
remove_wait_queue(&s->midi.owait, &wait);
set_current_state(TASK_RUNNING);
}
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE));
spin_lock_irqsave(&s->lock, flags);
if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
@@ -2508,7 +2509,7 @@ static int es1370_midi_release(struct inode *inode, struct file *file)
}
spin_unlock_irqrestore(&s->lock, flags);
wake_up(&s->open_wait);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
unlock_kernel();
return 0;
}
@@ -2638,7 +2639,7 @@ static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_devic
init_waitqueue_head(&s->open_wait);
init_waitqueue_head(&s->midi.iwait);
init_waitqueue_head(&s->midi.owait);
- init_MUTEX(&s->open_sem);
+ mutex_init(&s->open_mutex);
spin_lock_init(&s->lock);
s->magic = ES1370_MAGIC;
s->dev = pcidev;
diff --git a/sound/oss/es1371.c b/sound/oss/es1371.c
index 5c697f162579..4400c8538686 100644
--- a/sound/oss/es1371.c
+++ b/sound/oss/es1371.c
@@ -129,6 +129,7 @@
#include <linux/gameport.h>
#include <linux/wait.h>
#include <linux/dma-mapping.h>
+#include <linux/mutex.h>
#include <asm/io.h>
#include <asm/page.h>
@@ -419,7 +420,7 @@ struct es1371_state {
unsigned dac1rate, dac2rate, adcrate;
spinlock_t lock;
- struct semaphore open_sem;
+ struct mutex open_mutex;
mode_t open_mode;
wait_queue_head_t open_wait;
@@ -462,7 +463,7 @@ struct es1371_state {
struct gameport *gameport;
#endif
- struct semaphore sem;
+ struct mutex sem;
};
/* --------------------------------------------------------------------- */
@@ -1346,7 +1347,7 @@ static ssize_t es1371_read(struct file *file, char __user *buffer, size_t count,
return -ENXIO;
if (!access_ok(VERIFY_WRITE, buffer, count))
return -EFAULT;
- down(&s->sem);
+ mutex_lock(&s->sem);
if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
goto out2;
@@ -1370,14 +1371,14 @@ static ssize_t es1371_read(struct file *file, char __user *buffer, size_t count,
ret = -EAGAIN;
goto out;
}
- up(&s->sem);
+ mutex_unlock(&s->sem);
schedule();
if (signal_pending(current)) {
if (!ret)
ret = -ERESTARTSYS;
goto out2;
}
- down(&s->sem);
+ mutex_lock(&s->sem);
if (s->dma_adc.mapped)
{
ret = -ENXIO;
@@ -1402,7 +1403,7 @@ static ssize_t es1371_read(struct file *file, char __user *buffer, size_t count,
start_adc(s);
}
out:
- up(&s->sem);
+ mutex_unlock(&s->sem);
out2:
remove_wait_queue(&s->dma_adc.wait, &wait);
set_current_state(TASK_RUNNING);
@@ -1423,7 +1424,7 @@ static ssize_t es1371_write(struct file *file, const char __user *buffer, size_t
return -ENXIO;
if (!access_ok(VERIFY_READ, buffer, count))
return -EFAULT;
- down(&s->sem);
+ mutex_lock(&s->sem);
if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s)))
goto out3;
ret = 0;
@@ -1451,14 +1452,14 @@ static ssize_t es1371_write(struct file *file, const char __user *buffer, size_t
ret = -EAGAIN;
goto out;
}
- up(&s->sem);
+ mutex_unlock(&s->sem);
schedule();
if (signal_pending(current)) {
if (!ret)
ret = -ERESTARTSYS;
goto out2;
}
- down(&s->sem);
+ mutex_lock(&s->sem);
if (s->dma_dac2.mapped)
{
ret = -ENXIO;
@@ -1484,7 +1485,7 @@ static ssize_t es1371_write(struct file *file, const char __user *buffer, size_t
start_dac2(s);
}
out:
- up(&s->sem);
+ mutex_unlock(&s->sem);
out2:
remove_wait_queue(&s->dma_dac2.wait, &wait);
out3:
@@ -1538,7 +1539,7 @@ static int es1371_mmap(struct file *file, struct vm_area_struct *vma)
VALIDATE_STATE(s);
lock_kernel();
- down(&s->sem);
+ mutex_lock(&s->sem);
if (vma->vm_flags & VM_WRITE) {
if ((ret = prog_dmabuf_dac2(s)) != 0) {
@@ -1571,7 +1572,7 @@ static int es1371_mmap(struct file *file, struct vm_area_struct *vma)
}
db->mapped = 1;
out:
- up(&s->sem);
+ mutex_unlock(&s->sem);
unlock_kernel();
return ret;
}
@@ -1938,21 +1939,21 @@ static int es1371_open(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
file->private_data = s;
/* wait for device to become free */
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
while (s->open_mode & file->f_mode) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return -EBUSY;
}
add_wait_queue(&s->open_wait, &wait);
__set_current_state(TASK_INTERRUPTIBLE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
schedule();
remove_wait_queue(&s->open_wait, &wait);
set_current_state(TASK_RUNNING);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
}
if (file->f_mode & FMODE_READ) {
s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
@@ -1982,8 +1983,8 @@ static int es1371_open(struct inode *inode, struct file *file)
outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
spin_unlock_irqrestore(&s->lock, flags);
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
- up(&s->open_sem);
- init_MUTEX(&s->sem);
+ mutex_unlock(&s->open_mutex);
+ mutex_init(&s->sem);
return nonseekable_open(inode, file);
}
@@ -1995,7 +1996,7 @@ static int es1371_release(struct inode *inode, struct file *file)
lock_kernel();
if (file->f_mode & FMODE_WRITE)
drain_dac2(s, file->f_flags & O_NONBLOCK);
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
if (file->f_mode & FMODE_WRITE) {
stop_dac2(s);
dealloc_dmabuf(s, &s->dma_dac2);
@@ -2005,7 +2006,7 @@ static int es1371_release(struct inode *inode, struct file *file)
dealloc_dmabuf(s, &s->dma_adc);
}
s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE));
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
wake_up(&s->open_wait);
unlock_kernel();
return 0;
@@ -2377,21 +2378,21 @@ static int es1371_open_dac(struct inode *inode, struct file *file)
return -EINVAL;
file->private_data = s;
/* wait for device to become free */
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
while (s->open_mode & FMODE_DAC) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return -EBUSY;
}
add_wait_queue(&s->open_wait, &wait);
__set_current_state(TASK_INTERRUPTIBLE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
schedule();
remove_wait_queue(&s->open_wait, &wait);
set_current_state(TASK_RUNNING);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
}
s->dma_dac1.ossfragshift = s->dma_dac1.ossmaxfrags = s->dma_dac1.subdivision = 0;
s->dma_dac1.enabled = 1;
@@ -2405,7 +2406,7 @@ static int es1371_open_dac(struct inode *inode, struct file *file)
outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
spin_unlock_irqrestore(&s->lock, flags);
s->open_mode |= FMODE_DAC;
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return nonseekable_open(inode, file);
}
@@ -2416,11 +2417,11 @@ static int es1371_release_dac(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
lock_kernel();
drain_dac1(s, file->f_flags & O_NONBLOCK);
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
stop_dac1(s);
dealloc_dmabuf(s, &s->dma_dac1);
s->open_mode &= ~FMODE_DAC;
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
wake_up(&s->open_wait);
unlock_kernel();
return 0;
@@ -2608,21 +2609,21 @@ static int es1371_midi_open(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
file->private_data = s;
/* wait for device to become free */
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return -EBUSY;
}
add_wait_queue(&s->open_wait, &wait);
__set_current_state(TASK_INTERRUPTIBLE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
schedule();
remove_wait_queue(&s->open_wait, &wait);
set_current_state(TASK_RUNNING);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
}
spin_lock_irqsave(&s->lock, flags);
if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
@@ -2643,7 +2644,7 @@ static int es1371_midi_open(struct inode *inode, struct file *file)
es1371_handle_midi(s);
spin_unlock_irqrestore(&s->lock, flags);
s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return nonseekable_open(inode, file);
}
@@ -2676,7 +2677,7 @@ static int es1371_midi_release(struct inode *inode, struct file *file)
remove_wait_queue(&s->midi.owait, &wait);
set_current_state(TASK_RUNNING);
}
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE));
spin_lock_irqsave(&s->lock, flags);
if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
@@ -2684,7 +2685,7 @@ static int es1371_midi_release(struct inode *inode, struct file *file)
outl(s->ctrl, s->io+ES1371_REG_CONTROL);
}
spin_unlock_irqrestore(&s->lock, flags);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
wake_up(&s->open_wait);
unlock_kernel();
return 0;
@@ -2884,7 +2885,7 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic
init_waitqueue_head(&s->open_wait);
init_waitqueue_head(&s->midi.iwait);
init_waitqueue_head(&s->midi.owait);
- init_MUTEX(&s->open_sem);
+ mutex_init(&s->open_mutex);
spin_lock_init(&s->lock);
s->magic = ES1371_MAGIC;
s->dev = pcidev;
diff --git a/sound/oss/esssolo1.c b/sound/oss/esssolo1.c
index 849b59f67ef5..78d3e29ce968 100644
--- a/sound/oss/esssolo1.c
+++ b/sound/oss/esssolo1.c
@@ -105,6 +105,8 @@
#include <linux/gameport.h>
#include <linux/wait.h>
#include <linux/dma-mapping.h>
+#include <linux/mutex.h>
+
#include <asm/io.h>
#include <asm/page.h>
@@ -191,7 +193,7 @@ struct solo1_state {
unsigned ena;
spinlock_t lock;
- struct semaphore open_sem;
+ struct mutex open_mutex;
mode_t open_mode;
wait_queue_head_t open_wait;
@@ -1581,7 +1583,7 @@ static int solo1_release(struct inode *inode, struct file *file)
lock_kernel();
if (file->f_mode & FMODE_WRITE)
drain_dac(s, file->f_flags & O_NONBLOCK);
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
if (file->f_mode & FMODE_WRITE) {
stop_dac(s);
outb(0, s->iobase+6); /* disable DMA */
@@ -1595,7 +1597,7 @@ static int solo1_release(struct inode *inode, struct file *file)
}
s->open_mode &= ~(FMODE_READ | FMODE_WRITE);
wake_up(&s->open_wait);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
unlock_kernel();
return 0;
}
@@ -1624,21 +1626,21 @@ static int solo1_open(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
file->private_data = s;
/* wait for device to become free */
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
while (s->open_mode & (FMODE_READ | FMODE_WRITE)) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return -EBUSY;
}
add_wait_queue(&s->open_wait, &wait);
__set_current_state(TASK_INTERRUPTIBLE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
schedule();
remove_wait_queue(&s->open_wait, &wait);
set_current_state(TASK_RUNNING);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
}
s->fmt = AFMT_U8;
s->channels = 1;
@@ -1650,7 +1652,7 @@ static int solo1_open(struct inode *inode, struct file *file)
s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
s->dma_dac.enabled = 1;
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
prog_codec(s);
return nonseekable_open(inode, file);
}
@@ -1911,21 +1913,21 @@ static int solo1_midi_open(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
file->private_data = s;
/* wait for device to become free */
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return -EBUSY;
}
add_wait_queue(&s->open_wait, &wait);
__set_current_state(TASK_INTERRUPTIBLE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
schedule();
remove_wait_queue(&s->open_wait, &wait);
set_current_state(TASK_RUNNING);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
}
spin_lock_irqsave(&s->lock, flags);
if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
@@ -1951,7 +1953,7 @@ static int solo1_midi_open(struct inode *inode, struct file *file)
}
spin_unlock_irqrestore(&s->lock, flags);
s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return nonseekable_open(inode, file);
}
@@ -1985,7 +1987,7 @@ static int solo1_midi_release(struct inode *inode, struct file *file)
remove_wait_queue(&s->midi.owait, &wait);
set_current_state(TASK_RUNNING);
}
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE));
spin_lock_irqsave(&s->lock, flags);
if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
@@ -1994,7 +1996,7 @@ static int solo1_midi_release(struct inode *inode, struct file *file)
}
spin_unlock_irqrestore(&s->lock, flags);
wake_up(&s->open_wait);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
unlock_kernel();
return 0;
}
@@ -2132,24 +2134,24 @@ static int solo1_dmfm_open(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
file->private_data = s;
/* wait for device to become free */
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
while (s->open_mode & FMODE_DMFM) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return -EBUSY;
}
add_wait_queue(&s->open_wait, &wait);
__set_current_state(TASK_INTERRUPTIBLE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
schedule();
remove_wait_queue(&s->open_wait, &wait);
set_current_state(TASK_RUNNING);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
}
if (!request_region(s->sbbase, FMSYNTH_EXTENT, "ESS Solo1")) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
printk(KERN_ERR "solo1: FM synth io ports in use, opl3 loaded?\n");
return -EBUSY;
}
@@ -2161,7 +2163,7 @@ static int solo1_dmfm_open(struct inode *inode, struct file *file)
outb(5, s->sbbase+2);
outb(1, s->sbbase+3); /* enable OPL3 */
s->open_mode |= FMODE_DMFM;
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return nonseekable_open(inode, file);
}
@@ -2172,7 +2174,7 @@ static int solo1_dmfm_release(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
lock_kernel();
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
s->open_mode &= ~FMODE_DMFM;
for (regb = 0xb0; regb < 0xb9; regb++) {
outb(regb, s->sbbase);
@@ -2182,7 +2184,7 @@ static int solo1_dmfm_release(struct inode *inode, struct file *file)
}
release_region(s->sbbase, FMSYNTH_EXTENT);
wake_up(&s->open_wait);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
unlock_kernel();
return 0;
}
@@ -2362,7 +2364,7 @@ static int __devinit solo1_probe(struct pci_dev *pcidev, const struct pci_device
init_waitqueue_head(&s->open_wait);
init_waitqueue_head(&s->midi.iwait);
init_waitqueue_head(&s->midi.owait);
- init_MUTEX(&s->open_sem);
+ mutex_init(&s->open_mutex);
spin_lock_init(&s->lock);
s->magic = SOLO1_MAGIC;
s->dev = pcidev;
diff --git a/sound/oss/forte.c b/sound/oss/forte.c
index 8406bc90c4ff..0294eec8ad90 100644
--- a/sound/oss/forte.c
+++ b/sound/oss/forte.c
@@ -43,6 +43,7 @@
#include <linux/interrupt.h>
#include <linux/proc_fs.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -185,7 +186,7 @@ struct forte_chip {
unsigned long iobase;
int irq;
- struct semaphore open_sem; /* Device access */
+ struct mutex open_mutex; /* Device access */
spinlock_t lock; /* State */
spinlock_t ac97_lock;
@@ -1242,13 +1243,13 @@ forte_dsp_open (struct inode *inode, struct file *file)
struct forte_chip *chip = forte; /* FIXME: HACK FROM HELL! */
if (file->f_flags & O_NONBLOCK) {
- if (down_trylock (&chip->open_sem)) {
+ if (!mutex_trylock(&chip->open_mutex)) {
DPRINTK ("%s: returning -EAGAIN\n", __FUNCTION__);
return -EAGAIN;
}
}
else {
- if (down_interruptible (&chip->open_sem)) {
+ if (mutex_lock_interruptible(&chip->open_mutex)) {
DPRINTK ("%s: returning -ERESTARTSYS\n", __FUNCTION__);
return -ERESTARTSYS;
}
@@ -1302,7 +1303,7 @@ forte_dsp_release (struct inode *inode, struct file *file)
spin_unlock_irq (&chip->lock);
}
- up (&chip->open_sem);
+ mutex_unlock(&chip->open_mutex);
return ret;
}
@@ -2011,7 +2012,7 @@ forte_probe (struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
memset (chip, 0, sizeof (struct forte_chip));
chip->pci_dev = pci_dev;
- init_MUTEX(&chip->open_sem);
+ mutex_init(&chip->open_mutex);
spin_lock_init (&chip->lock);
spin_lock_init (&chip->ac97_lock);
diff --git a/sound/oss/hal2.c b/sound/oss/hal2.c
index afe97c4ce069..dd4f59d30a3a 100644
--- a/sound/oss/hal2.c
+++ b/sound/oss/hal2.c
@@ -32,6 +32,8 @@
#include <linux/dma-mapping.h>
#include <linux/sound.h>
#include <linux/soundcard.h>
+#include <linux/mutex.h>
+
#include <asm/io.h>
#include <asm/sgi/hpc3.h>
@@ -92,7 +94,7 @@ struct hal2_codec {
wait_queue_head_t dma_wait;
spinlock_t lock;
- struct semaphore sem;
+ struct mutex sem;
int usecount; /* recording and playback are
* independent */
@@ -1178,7 +1180,7 @@ static ssize_t hal2_read(struct file *file, char *buffer,
if (!count)
return 0;
- if (down_interruptible(&adc->sem))
+ if (mutex_lock_interruptible(&adc->sem))
return -EINTR;
if (file->f_flags & O_NONBLOCK) {
err = hal2_get_buffer(hal2, buffer, count);
@@ -1217,7 +1219,7 @@ static ssize_t hal2_read(struct file *file, char *buffer,
}
} while (count > 0 && err >= 0);
}
- up(&adc->sem);
+ mutex_unlock(&adc->sem);
return err;
}
@@ -1232,7 +1234,7 @@ static ssize_t hal2_write(struct file *file, const char *buffer,
if (!count)
return 0;
- if (down_interruptible(&dac->sem))
+ if (mutex_lock_interruptible(&dac->sem))
return -EINTR;
if (file->f_flags & O_NONBLOCK) {
err = hal2_add_buffer(hal2, buf, count);
@@ -1271,7 +1273,7 @@ static ssize_t hal2_write(struct file *file, const char *buffer,
}
} while (count > 0 && err >= 0);
}
- up(&dac->sem);
+ mutex_unlock(&dac->sem);
return err;
}
@@ -1356,20 +1358,20 @@ static int hal2_release(struct inode *inode, struct file *file)
if (file->f_mode & FMODE_READ) {
struct hal2_codec *adc = &hal2->adc;
- down(&adc->sem);
+ mutex_lock(&adc->sem);
hal2_stop_adc(hal2);
hal2_free_adc_dmabuf(adc);
adc->usecount--;
- up(&adc->sem);
+ mutex_unlock(&adc->sem);
}
if (file->f_mode & FMODE_WRITE) {
struct hal2_codec *dac = &hal2->dac;
- down(&dac->sem);
+ mutex_lock(&dac->sem);
hal2_sync_dac(hal2);
hal2_free_dac_dmabuf(dac);
dac->usecount--;
- up(&dac->sem);
+ mutex_unlock(&dac->sem);
}
return 0;
@@ -1400,7 +1402,7 @@ static void hal2_init_codec(struct hal2_codec *codec, struct hpc3_regs *hpc3,
codec->pbus.pbusnr = index;
codec->pbus.pbus = &hpc3->pbdma[index];
init_waitqueue_head(&codec->dma_wait);
- init_MUTEX(&codec->sem);
+ mutex_init(&codec->sem);
spin_lock_init(&codec->lock);
}
diff --git a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c
index abc242abd5b1..dd2b871cdac5 100644
--- a/sound/oss/i810_audio.c
+++ b/sound/oss/i810_audio.c
@@ -100,6 +100,8 @@
#include <linux/smp_lock.h>
#include <linux/ac97_codec.h>
#include <linux/bitops.h>
+#include <linux/mutex.h>
+
#include <asm/uaccess.h>
#define DRIVER_VERSION "1.01"
@@ -331,7 +333,7 @@ struct i810_state {
struct i810_card *card; /* Card info */
/* single open lock mechanism, only used for recording */
- struct semaphore open_sem;
+ struct mutex open_mutex;
wait_queue_head_t open_wait;
/* file mode */
@@ -2597,7 +2599,7 @@ found_virt:
state->card = card;
state->magic = I810_STATE_MAGIC;
init_waitqueue_head(&dmabuf->wait);
- init_MUTEX(&state->open_sem);
+ mutex_init(&state->open_mutex);
file->private_data = state;
dmabuf->trigger = 0;
@@ -3213,7 +3215,7 @@ static void __devinit i810_configure_clocking (void)
state->card = card;
state->magic = I810_STATE_MAGIC;
init_waitqueue_head(&dmabuf->wait);
- init_MUTEX(&state->open_sem);
+ mutex_init(&state->open_mutex);
dmabuf->fmt = I810_FMT_STEREO | I810_FMT_16BIT;
dmabuf->trigger = PCM_ENABLE_OUTPUT;
i810_set_spdif_output(state, -1, 0);
diff --git a/sound/oss/ite8172.c b/sound/oss/ite8172.c
index 8fd2f9a9e668..ffcb910f5c3e 100644
--- a/sound/oss/ite8172.c
+++ b/sound/oss/ite8172.c
@@ -71,6 +71,8 @@
#include <linux/smp_lock.h>
#include <linux/ac97_codec.h>
#include <linux/interrupt.h>
+#include <linux/mutex.h>
+
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/uaccess.h>
@@ -304,7 +306,7 @@ struct it8172_state {
unsigned dacrate, adcrate;
spinlock_t lock;
- struct semaphore open_sem;
+ struct mutex open_mutex;
mode_t open_mode;
wait_queue_head_t open_wait;
@@ -1801,21 +1803,21 @@ static int it8172_open(struct inode *inode, struct file *file)
}
file->private_data = s;
/* wait for device to become free */
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
while (s->open_mode & file->f_mode) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return -EBUSY;
}
add_wait_queue(&s->open_wait, &wait);
__set_current_state(TASK_INTERRUPTIBLE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
schedule();
remove_wait_queue(&s->open_wait, &wait);
set_current_state(TASK_RUNNING);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
}
spin_lock_irqsave(&s->lock, flags);
@@ -1850,7 +1852,7 @@ static int it8172_open(struct inode *inode, struct file *file)
spin_unlock_irqrestore(&s->lock, flags);
s->open_mode |= (file->f_mode & (FMODE_READ | FMODE_WRITE));
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return nonseekable_open(inode, file);
}
@@ -1864,7 +1866,7 @@ static int it8172_release(struct inode *inode, struct file *file)
lock_kernel();
if (file->f_mode & FMODE_WRITE)
drain_dac(s, file->f_flags & O_NONBLOCK);
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
if (file->f_mode & FMODE_WRITE) {
stop_dac(s);
dealloc_dmabuf(s, &s->dma_dac);
@@ -1874,7 +1876,7 @@ static int it8172_release(struct inode *inode, struct file *file)
dealloc_dmabuf(s, &s->dma_adc);
}
s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE));
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
wake_up(&s->open_wait);
unlock_kernel();
return 0;
@@ -1997,7 +1999,7 @@ static int __devinit it8172_probe(struct pci_dev *pcidev,
init_waitqueue_head(&s->dma_adc.wait);
init_waitqueue_head(&s->dma_dac.wait);
init_waitqueue_head(&s->open_wait);
- init_MUTEX(&s->open_sem);
+ mutex_init(&s->open_mutex);
spin_lock_init(&s->lock);
s->dev = pcidev;
s->io = pci_resource_start(pcidev, 0);
diff --git a/sound/oss/maestro.c b/sound/oss/maestro.c
index d4b569acf764..e647f2f86279 100644
--- a/sound/oss/maestro.c
+++ b/sound/oss/maestro.c
@@ -223,6 +223,8 @@
#include <linux/reboot.h>
#include <linux/bitops.h>
#include <linux/wait.h>
+#include <linux/mutex.h>
+
#include <asm/current.h>
#include <asm/dma.h>
@@ -397,7 +399,7 @@ struct ess_state {
/* this locks around the oss state in the driver */
spinlock_t lock;
/* only let 1 be opening at a time */
- struct semaphore open_sem;
+ struct mutex open_mutex;
wait_queue_head_t open_wait;
mode_t open_mode;
@@ -3020,26 +3022,26 @@ ess_open(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
file->private_data = s;
/* wait for device to become free */
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
while (s->open_mode & file->f_mode) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return -EWOULDBLOCK;
}
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
interruptible_sleep_on(&s->open_wait);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
}
/* under semaphore.. */
if ((s->card->dmapages==NULL) && allocate_buffers(s)) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return -ENOMEM;
}
- /* we're covered by the open_sem */
+ /* we're covered by the open_mutex */
if( ! s->card->dsps_open ) {
maestro_power(s->card,ACPI_D0);
start_bob(s);
@@ -3076,7 +3078,7 @@ ess_open(struct inode *inode, struct file *file)
set_fmt(s, fmtm, fmts);
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return nonseekable_open(inode, file);
}
@@ -3089,7 +3091,7 @@ ess_release(struct inode *inode, struct file *file)
lock_kernel();
if (file->f_mode & FMODE_WRITE)
drain_dac(s, file->f_flags & O_NONBLOCK);
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
if (file->f_mode & FMODE_WRITE) {
stop_dac(s);
}
@@ -3098,7 +3100,7 @@ ess_release(struct inode *inode, struct file *file)
}
s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
- /* we're covered by the open_sem */
+ /* we're covered by the open_mutex */
M_printk("maestro: %d dsps now alive\n",s->card->dsps_open-1);
if( --s->card->dsps_open <= 0) {
s->card->dsps_open = 0;
@@ -3106,7 +3108,7 @@ ess_release(struct inode *inode, struct file *file)
free_buffers(s);
maestro_power(s->card,ACPI_D2);
}
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
wake_up(&s->open_wait);
unlock_kernel();
return 0;
@@ -3466,7 +3468,7 @@ maestro_probe(struct pci_dev *pcidev,const struct pci_device_id *pdid)
init_waitqueue_head(&s->dma_dac.wait);
init_waitqueue_head(&s->open_wait);
spin_lock_init(&s->lock);
- init_MUTEX(&s->open_sem);
+ mutex_init(&s->open_mutex);
s->magic = ESS_STATE_MAGIC;
s->apu[0] = 6*i;
diff --git a/sound/oss/maestro3.c b/sound/oss/maestro3.c
index f3dec70fcb9b..66044aff2586 100644
--- a/sound/oss/maestro3.c
+++ b/sound/oss/maestro3.c
@@ -144,6 +144,8 @@
#include <linux/spinlock.h>
#include <linux/ac97_codec.h>
#include <linux/wait.h>
+#include <linux/mutex.h>
+
#include <asm/io.h>
#include <asm/dma.h>
@@ -205,7 +207,7 @@ struct m3_state {
when irqhandler uses s->lock
and m3_assp_read uses card->lock ?
*/
- struct semaphore open_sem;
+ struct mutex open_mutex;
wait_queue_head_t open_wait;
mode_t open_mode;
@@ -2013,17 +2015,17 @@ static int m3_open(struct inode *inode, struct file *file)
file->private_data = s;
/* wait for device to become free */
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
while (s->open_mode & file->f_mode) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return -EWOULDBLOCK;
}
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
interruptible_sleep_on(&s->open_wait);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
}
spin_lock_irqsave(&c->lock, flags);
@@ -2047,7 +2049,7 @@ static int m3_open(struct inode *inode, struct file *file)
set_fmt(s, fmtm, fmts);
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
spin_unlock_irqrestore(&c->lock, flags);
return nonseekable_open(inode, file);
}
@@ -2062,7 +2064,7 @@ static int m3_release(struct inode *inode, struct file *file)
if (file->f_mode & FMODE_WRITE)
drain_dac(s, file->f_flags & O_NONBLOCK);
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
spin_lock_irqsave(&card->lock, flags);
if (file->f_mode & FMODE_WRITE) {
@@ -2083,7 +2085,7 @@ static int m3_release(struct inode *inode, struct file *file)
s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
spin_unlock_irqrestore(&card->lock, flags);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
wake_up(&s->open_wait);
return 0;
@@ -2679,7 +2681,7 @@ static int __devinit m3_probe(struct pci_dev *pci_dev, const struct pci_device_i
init_waitqueue_head(&s->dma_adc.wait);
init_waitqueue_head(&s->dma_dac.wait);
init_waitqueue_head(&s->open_wait);
- init_MUTEX(&(s->open_sem));
+ mutex_init(&(s->open_mutex));
s->magic = M3_STATE_MAGIC;
m3_assp_client_init(s);
diff --git a/sound/oss/nec_vrc5477.c b/sound/oss/nec_vrc5477.c
index fbb9170e8e0a..21c1954d9108 100644
--- a/sound/oss/nec_vrc5477.c
+++ b/sound/oss/nec_vrc5477.c
@@ -78,6 +78,8 @@
#include <linux/spinlock.h>
#include <linux/smp_lock.h>
#include <linux/ac97_codec.h>
+#include <linux/mutex.h>
+
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/uaccess.h>
@@ -198,7 +200,7 @@ struct vrc5477_ac97_state {
unsigned short extended_status;
spinlock_t lock;
- struct semaphore open_sem;
+ struct mutex open_mutex;
mode_t open_mode;
wait_queue_head_t open_wait;
@@ -1617,22 +1619,22 @@ static int vrc5477_ac97_open(struct inode *inode, struct file *file)
file->private_data = s;
/* wait for device to become free */
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
while (s->open_mode & file->f_mode) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return -EBUSY;
}
add_wait_queue(&s->open_wait, &wait);
__set_current_state(TASK_INTERRUPTIBLE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
schedule();
remove_wait_queue(&s->open_wait, &wait);
set_current_state(TASK_RUNNING);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
}
spin_lock_irqsave(&s->lock, flags);
@@ -1659,7 +1661,7 @@ static int vrc5477_ac97_open(struct inode *inode, struct file *file)
bailout:
spin_unlock_irqrestore(&s->lock, flags);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return ret;
}
@@ -1671,7 +1673,7 @@ static int vrc5477_ac97_release(struct inode *inode, struct file *file)
lock_kernel();
if (file->f_mode & FMODE_WRITE)
drain_dac(s, file->f_flags & O_NONBLOCK);
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
if (file->f_mode & FMODE_WRITE) {
stop_dac(s);
dealloc_dmabuf(s, &s->dma_dac);
@@ -1681,7 +1683,7 @@ static int vrc5477_ac97_release(struct inode *inode, struct file *file)
dealloc_dmabuf(s, &s->dma_adc);
}
s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
wake_up(&s->open_wait);
unlock_kernel();
return 0;
@@ -1867,7 +1869,7 @@ static int __devinit vrc5477_ac97_probe(struct pci_dev *pcidev,
init_waitqueue_head(&s->dma_adc.wait);
init_waitqueue_head(&s->dma_dac.wait);
init_waitqueue_head(&s->open_wait);
- init_MUTEX(&s->open_sem);
+ mutex_init(&s->open_mutex);
spin_lock_init(&s->lock);
s->dev = pcidev;
diff --git a/sound/oss/rme96xx.c b/sound/oss/rme96xx.c
index faa0b7919b65..a1ec9d131ab3 100644
--- a/sound/oss/rme96xx.c
+++ b/sound/oss/rme96xx.c
@@ -58,6 +58,7 @@ TODO:
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/wait.h>
+#include <linux/mutex.h>
#include <asm/dma.h>
#include <asm/page.h>
@@ -326,7 +327,7 @@ typedef struct _rme96xx_info {
/* waiting and locking */
wait_queue_head_t wait;
- struct semaphore open_sem;
+ struct mutex open_mutex;
wait_queue_head_t open_wait;
} dma[RME96xx_MAX_DEVS];
@@ -842,7 +843,7 @@ static void busmaster_free(void* ptr,int size) {
static int rme96xx_dmabuf_init(rme96xx_info * s,struct dmabuf* dma,int ioffset,int ooffset) {
- init_MUTEX(&dma->open_sem);
+ mutex_init(&dma->open_mutex);
init_waitqueue_head(&dma->open_wait);
init_waitqueue_head(&dma->wait);
dma->s = s;
@@ -1469,21 +1470,21 @@ static int rme96xx_open(struct inode *in, struct file *f)
dma = &s->dma[devnum];
f->private_data = dma;
/* wait for device to become free */
- down(&dma->open_sem);
+ mutex_lock(&dma->open_mutex);
while (dma->open_mode & f->f_mode) {
if (f->f_flags & O_NONBLOCK) {
- up(&dma->open_sem);
+ mutex_unlock(&dma->open_mutex);
return -EBUSY;
}
add_wait_queue(&dma->open_wait, &wait);
__set_current_state(TASK_INTERRUPTIBLE);
- up(&dma->open_sem);
+ mutex_unlock(&dma->open_mutex);
schedule();
remove_wait_queue(&dma->open_wait, &wait);
set_current_state(TASK_RUNNING);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&dma->open_sem);
+ mutex_lock(&dma->open_mutex);
}
COMM ("hardware open")
@@ -1492,7 +1493,7 @@ static int rme96xx_open(struct inode *in, struct file *f)
dma->open_mode |= (f->f_mode & (FMODE_READ | FMODE_WRITE));
dma->opened = 1;
- up(&dma->open_sem);
+ mutex_unlock(&dma->open_mutex);
DBG(printk("device num %d open finished\n",devnum));
return 0;
@@ -1524,7 +1525,7 @@ static int rme96xx_release(struct inode *in, struct file *file)
}
wake_up(&dma->open_wait);
- up(&dma->open_sem);
+ mutex_unlock(&dma->open_mutex);
return 0;
}
diff --git a/sound/oss/sonicvibes.c b/sound/oss/sonicvibes.c
index 71b05e2f6977..69a4b8778b51 100644
--- a/sound/oss/sonicvibes.c
+++ b/sound/oss/sonicvibes.c
@@ -116,6 +116,8 @@
#include <linux/spinlock.h>
#include <linux/smp_lock.h>
#include <linux/gameport.h>
+#include <linux/mutex.h>
+
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -328,7 +330,7 @@ struct sv_state {
unsigned char fmt, enable;
spinlock_t lock;
- struct semaphore open_sem;
+ struct mutex open_mutex;
mode_t open_mode;
wait_queue_head_t open_wait;
@@ -1922,21 +1924,21 @@ static int sv_open(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
file->private_data = s;
/* wait for device to become free */
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
while (s->open_mode & file->f_mode) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return -EBUSY;
}
add_wait_queue(&s->open_wait, &wait);
__set_current_state(TASK_INTERRUPTIBLE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
schedule();
remove_wait_queue(&s->open_wait, &wait);
set_current_state(TASK_RUNNING);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
}
if (file->f_mode & FMODE_READ) {
fmtm &= ~((SV_CFMT_STEREO | SV_CFMT_16BIT) << SV_CFMT_CSHIFT);
@@ -1956,7 +1958,7 @@ static int sv_open(struct inode *inode, struct file *file)
}
set_fmt(s, fmtm, fmts);
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return nonseekable_open(inode, file);
}
@@ -1968,7 +1970,7 @@ static int sv_release(struct inode *inode, struct file *file)
lock_kernel();
if (file->f_mode & FMODE_WRITE)
drain_dac(s, file->f_flags & O_NONBLOCK);
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
if (file->f_mode & FMODE_WRITE) {
stop_dac(s);
dealloc_dmabuf(s, &s->dma_dac);
@@ -1979,7 +1981,7 @@ static int sv_release(struct inode *inode, struct file *file)
}
s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE));
wake_up(&s->open_wait);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
unlock_kernel();
return 0;
}
@@ -2167,21 +2169,21 @@ static int sv_midi_open(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
file->private_data = s;
/* wait for device to become free */
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return -EBUSY;
}
add_wait_queue(&s->open_wait, &wait);
__set_current_state(TASK_INTERRUPTIBLE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
schedule();
remove_wait_queue(&s->open_wait, &wait);
set_current_state(TASK_RUNNING);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
}
spin_lock_irqsave(&s->lock, flags);
if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
@@ -2210,7 +2212,7 @@ static int sv_midi_open(struct inode *inode, struct file *file)
}
spin_unlock_irqrestore(&s->lock, flags);
s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return nonseekable_open(inode, file);
}
@@ -2248,7 +2250,7 @@ static int sv_midi_release(struct inode *inode, struct file *file)
remove_wait_queue(&s->midi.owait, &wait);
set_current_state(TASK_RUNNING);
}
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE));
spin_lock_irqsave(&s->lock, flags);
if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
@@ -2257,7 +2259,7 @@ static int sv_midi_release(struct inode *inode, struct file *file)
}
spin_unlock_irqrestore(&s->lock, flags);
wake_up(&s->open_wait);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
unlock_kernel();
return 0;
}
@@ -2388,21 +2390,21 @@ static int sv_dmfm_open(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
file->private_data = s;
/* wait for device to become free */
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
while (s->open_mode & FMODE_DMFM) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return -EBUSY;
}
add_wait_queue(&s->open_wait, &wait);
__set_current_state(TASK_INTERRUPTIBLE);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
schedule();
remove_wait_queue(&s->open_wait, &wait);
set_current_state(TASK_RUNNING);
if (signal_pending(current))
return -ERESTARTSYS;
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
}
/* init the stuff */
outb(1, s->iosynth);
@@ -2412,7 +2414,7 @@ static int sv_dmfm_open(struct inode *inode, struct file *file)
outb(5, s->iosynth+2);
outb(1, s->iosynth+3); /* enable OPL3 */
s->open_mode |= FMODE_DMFM;
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
return nonseekable_open(inode, file);
}
@@ -2423,7 +2425,7 @@ static int sv_dmfm_release(struct inode *inode, struct file *file)
VALIDATE_STATE(s);
lock_kernel();
- down(&s->open_sem);
+ mutex_lock(&s->open_mutex);
s->open_mode &= ~FMODE_DMFM;
for (regb = 0xb0; regb < 0xb9; regb++) {
outb(regb, s->iosynth);
@@ -2432,7 +2434,7 @@ static int sv_dmfm_release(struct inode *inode, struct file *file)
outb(0, s->iosynth+3);
}
wake_up(&s->open_wait);
- up(&s->open_sem);
+ mutex_unlock(&s->open_mutex);
unlock_kernel();
return 0;
}
@@ -2582,7 +2584,7 @@ static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id
init_waitqueue_head(&s->open_wait);
init_waitqueue_head(&s->midi.iwait);
init_waitqueue_head(&s->midi.owait);
- init_MUTEX(&s->open_sem);
+ mutex_init(&s->open_mutex);
spin_lock_init(&s->lock);
s->magic = SV_MAGIC;
s->dev = pcidev;
diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c
index df4d3771fa84..dce9016cbcfd 100644
--- a/sound/oss/swarm_cs4297a.c
+++ b/sound/oss/swarm_cs4297a.c
@@ -76,6 +76,7 @@
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <asm/byteorder.h>
#include <asm/dma.h>
@@ -291,9 +292,9 @@ struct cs4297a_state {
unsigned conversion:1; // conversion from 16 to 8 bit in progress
unsigned ena;
spinlock_t lock;
- struct semaphore open_sem;
- struct semaphore open_sem_adc;
- struct semaphore open_sem_dac;
+ struct mutex open_mutex;
+ struct mutex open_sem_adc;
+ struct mutex open_sem_dac;
mode_t open_mode;
wait_queue_head_t open_wait;
wait_queue_head_t open_wait_adc;
@@ -2352,20 +2353,20 @@ static int cs4297a_release(struct inode *inode, struct file *file)
if (file->f_mode & FMODE_WRITE) {
drain_dac(s, file->f_flags & O_NONBLOCK);
- down(&s->open_sem_dac);
+ mutex_lock(&s->open_sem_dac);
stop_dac(s);
dealloc_dmabuf(s, &s->dma_dac);
s->open_mode &= ~FMODE_WRITE;
- up(&s->open_sem_dac);
+ mutex_unlock(&s->open_sem_dac);
wake_up(&s->open_wait_dac);
}
if (file->f_mode & FMODE_READ) {
drain_adc(s, file->f_flags & O_NONBLOCK);
- down(&s->open_sem_adc);
+ mutex_lock(&s->open_sem_adc);
stop_adc(s);
dealloc_dmabuf(s, &s->dma_adc);
s->open_mode &= ~FMODE_READ;
- up(&s->open_sem_adc);
+ mutex_unlock(&s->open_sem_adc);
wake_up(&s->open_wait_adc);
}
return 0;
@@ -2413,37 +2414,37 @@ static int cs4297a_open(struct inode *inode, struct file *file)
;
}
- down(&s->open_sem_dac);
+ mutex_lock(&s->open_sem_dac);
while (s->open_mode & FMODE_WRITE) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem_dac);
+ mutex_unlock(&s->open_sem_dac);
return -EBUSY;
}
- up(&s->open_sem_dac);
+ mutex_unlock(&s->open_sem_dac);
interruptible_sleep_on(&s->open_wait_dac);
if (signal_pending(current)) {
printk("open - sig pending\n");
return -ERESTARTSYS;
}
- down(&s->open_sem_dac);
+ mutex_lock(&s->open_sem_dac);
}
}
if (file->f_mode & FMODE_READ) {
- down(&s->open_sem_adc);
+ mutex_lock(&s->open_sem_adc);
while (s->open_mode & FMODE_READ) {
if (file->f_flags & O_NONBLOCK) {
- up(&s->open_sem_adc);
+ mutex_unlock(&s->open_sem_adc);
return -EBUSY;
}
- up(&s->open_sem_adc);
+ mutex_unlock(&s->open_sem_adc);
interruptible_sleep_on(&s->open_wait_adc);
if (signal_pending(current)) {
printk("open - sig pending\n");
return -ERESTARTSYS;
}
- down(&s->open_sem_adc);
+ mutex_lock(&s->open_sem_adc);
}
}
s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
@@ -2456,7 +2457,7 @@ static int cs4297a_open(struct inode *inode, struct file *file)
s->ena &= ~FMODE_READ;
s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
s->dma_adc.subdivision = 0;
- up(&s->open_sem_adc);
+ mutex_unlock(&s->open_sem_adc);
if (prog_dmabuf_adc(s)) {
CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR
@@ -2474,7 +2475,7 @@ static int cs4297a_open(struct inode *inode, struct file *file)
s->ena &= ~FMODE_WRITE;
s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
s->dma_dac.subdivision = 0;
- up(&s->open_sem_dac);
+ mutex_unlock(&s->open_sem_dac);
if (prog_dmabuf_dac(s)) {
CS_DBGOUT(CS_OPEN | CS_ERROR, 2, printk(KERN_ERR
@@ -2631,8 +2632,8 @@ static int __init cs4297a_init(void)
init_waitqueue_head(&s->open_wait);
init_waitqueue_head(&s->open_wait_adc);
init_waitqueue_head(&s->open_wait_dac);
- init_MUTEX(&s->open_sem_adc);
- init_MUTEX(&s->open_sem_dac);
+ mutex_init(&s->open_sem_adc);
+ mutex_init(&s->open_sem_dac);
spin_lock_init(&s->lock);
s->irq = K_INT_SER_1;
diff --git a/sound/oss/trident.c b/sound/oss/trident.c
index a21c663e7e12..e61a454a8150 100644
--- a/sound/oss/trident.c
+++ b/sound/oss/trident.c
@@ -190,7 +190,7 @@
*
* Lock order (high->low)
* lock - hardware lock
- * open_sem - guard opens
+ * open_mutex - guard opens
* sem - guard dmabuf, write re-entry etc
*/
@@ -216,6 +216,8 @@
#include <linux/pm.h>
#include <linux/gameport.h>
#include <linux/kernel.h>
+#include <linux/mutex.h>
+
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/dma.h>
@@ -349,7 +351,7 @@ struct trident_state {
unsigned chans_num;
unsigned long fmt_flag;
/* Guard against mmap/write/read races */
- struct semaphore sem;
+ struct mutex sem;
};
@@ -402,7 +404,7 @@ struct trident_card {
struct trident_card *next;
/* single open lock mechanism, only used for recording */
- struct semaphore open_sem;
+ struct mutex open_mutex;
/* The trident has a certain amount of cross channel interaction
so we use a single per card lock */
@@ -1881,7 +1883,7 @@ trident_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos
if (!access_ok(VERIFY_WRITE, buffer, count))
return -EFAULT;
- down(&state->sem);
+ mutex_lock(&state->sem);
if (!dmabuf->ready && (ret = prog_dmabuf_record(state)))
goto out;
@@ -1913,7 +1915,7 @@ trident_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos
goto out;
}
- up(&state->sem);
+ mutex_unlock(&state->sem);
/* No matter how much space left in the buffer, */
/* we have to wait until CSO == ESO/2 or CSO == ESO */
/* when address engine interrupts */
@@ -1940,7 +1942,7 @@ trident_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos
ret = -ERESTARTSYS;
goto out;
}
- down(&state->sem);
+ mutex_lock(&state->sem);
if (dmabuf->mapped) {
if (!ret)
ret = -ENXIO;
@@ -1968,7 +1970,7 @@ trident_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos
start_adc(state);
}
out:
- up(&state->sem);
+ mutex_unlock(&state->sem);
return ret;
}
@@ -1996,7 +1998,7 @@ trident_write(struct file *file, const char __user *buffer, size_t count, loff_t
* Guard against an mmap or ioctl while writing
*/
- down(&state->sem);
+ mutex_lock(&state->sem);
if (dmabuf->mapped) {
ret = -ENXIO;
@@ -2045,7 +2047,7 @@ trident_write(struct file *file, const char __user *buffer, size_t count, loff_t
tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 2);
tmo >>= sample_shift[dmabuf->fmt];
unlock_set_fmt(state);
- up(&state->sem);
+ mutex_unlock(&state->sem);
/* There are two situations when sleep_on_timeout */
/* returns, one is when the interrupt is serviced */
@@ -2073,7 +2075,7 @@ trident_write(struct file *file, const char __user *buffer, size_t count, loff_t
ret = -ERESTARTSYS;
goto out_nolock;
}
- down(&state->sem);
+ mutex_lock(&state->sem);
if (dmabuf->mapped) {
if (!ret)
ret = -ENXIO;
@@ -2131,7 +2133,7 @@ trident_write(struct file *file, const char __user *buffer, size_t count, loff_t
start_dac(state);
}
out:
- up(&state->sem);
+ mutex_unlock(&state->sem);
out_nolock:
return ret;
}
@@ -2152,24 +2154,24 @@ trident_poll(struct file *file, struct poll_table_struct *wait)
* prog_dmabuf events
*/
- down(&state->sem);
+ mutex_lock(&state->sem);
if (file->f_mode & FMODE_WRITE) {
if (!dmabuf->ready && prog_dmabuf_playback(state)) {
- up(&state->sem);
+ mutex_unlock(&state->sem);
return 0;
}
poll_wait(file, &dmabuf->wait, wait);
}
if (file->f_mode & FMODE_READ) {
if (!dmabuf->ready && prog_dmabuf_record(state)) {
- up(&state->sem);
+ mutex_unlock(&state->sem);
return 0;
}
poll_wait(file, &dmabuf->wait, wait);
}
- up(&state->sem);
+ mutex_unlock(&state->sem);
spin_lock_irqsave(&state->card->lock, flags);
trident_update_ptr(state);
@@ -2207,7 +2209,7 @@ trident_mmap(struct file *file, struct vm_area_struct *vma)
* a read or write against an mmap.
*/
- down(&state->sem);
+ mutex_lock(&state->sem);
if (vma->vm_flags & VM_WRITE) {
if ((ret = prog_dmabuf_playback(state)) != 0)
@@ -2232,7 +2234,7 @@ trident_mmap(struct file *file, struct vm_area_struct *vma)
dmabuf->mapped = 1;
ret = 0;
out:
- up(&state->sem);
+ mutex_unlock(&state->sem);
return ret;
}
@@ -2429,15 +2431,15 @@ trident_ioctl(struct inode *inode, struct file *file,
unlock_set_fmt(state);
break;
}
- down(&state->card->open_sem);
+ mutex_lock(&state->card->open_mutex);
ret = ali_allocate_other_states_resources(state, 6);
if (ret < 0) {
- up(&state->card->open_sem);
+ mutex_unlock(&state->card->open_mutex);
unlock_set_fmt(state);
break;
}
state->card->multi_channel_use_count++;
- up(&state->card->open_sem);
+ mutex_unlock(&state->card->open_mutex);
} else
val = 2; /*yield to 2-channels */
} else
@@ -2727,11 +2729,11 @@ trident_open(struct inode *inode, struct file *file)
/* find an available virtual channel (instance of /dev/dsp) */
while (card != NULL) {
- down(&card->open_sem);
+ mutex_lock(&card->open_mutex);
if (file->f_mode & FMODE_READ) {
/* Skip opens on cards that are in 6 channel mode */
if (card->multi_channel_use_count > 0) {
- up(&card->open_sem);
+ mutex_unlock(&card->open_mutex);
card = card->next;
continue;
}
@@ -2740,16 +2742,16 @@ trident_open(struct inode *inode, struct file *file)
if (card->states[i] == NULL) {
state = card->states[i] = kmalloc(sizeof(*state), GFP_KERNEL);
if (state == NULL) {
- up(&card->open_sem);
+ mutex_unlock(&card->open_mutex);
return -ENOMEM;
}
memset(state, 0, sizeof(*state));
- init_MUTEX(&state->sem);
+ mutex_init(&state->sem);
dmabuf = &state->dmabuf;
goto found_virt;
}
}
- up(&card->open_sem);
+ mutex_unlock(&card->open_mutex);
card = card->next;
}
/* no more virtual channel avaiable */
@@ -2816,7 +2818,7 @@ trident_open(struct inode *inode, struct file *file)
}
state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
- up(&card->open_sem);
+ mutex_unlock(&card->open_mutex);
pr_debug("trident: open virtual channel %d, hard channel %d\n",
state->virt, dmabuf->channel->num);
@@ -2845,7 +2847,7 @@ trident_release(struct inode *inode, struct file *file)
state->virt, dmabuf->channel->num);
/* stop DMA state machine and free DMA buffers/channels */
- down(&card->open_sem);
+ mutex_lock(&card->open_mutex);
if (file->f_mode & FMODE_WRITE) {
stop_dac(state);
@@ -2878,8 +2880,8 @@ trident_release(struct inode *inode, struct file *file)
card->states[state->virt] = NULL;
kfree(state);
- /* we're covered by the open_sem */
- up(&card->open_sem);
+ /* we're covered by the open_mutex */
+ mutex_unlock(&card->open_mutex);
return 0;
}
@@ -4405,7 +4407,7 @@ trident_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
card->banks[BANK_B].addresses = &bank_b_addrs;
card->banks[BANK_B].bitmap = 0UL;
- init_MUTEX(&card->open_sem);
+ mutex_init(&card->open_mutex);
spin_lock_init(&card->lock);
init_timer(&card->timer);
diff --git a/sound/oss/via82cxxx_audio.c b/sound/oss/via82cxxx_audio.c
index 83edda93f0b4..1a921ee71aba 100644
--- a/sound/oss/via82cxxx_audio.c
+++ b/sound/oss/via82cxxx_audio.c
@@ -38,7 +38,8 @@
#include <linux/dma-mapping.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
+
#include "sound_config.h"
#include "dev_table.h"
#include "mpu401.h"
@@ -311,8 +312,8 @@ struct via_info {
int mixer_vol; /* 8233/35 volume - not yet implemented */
- struct semaphore syscall_sem;
- struct semaphore open_sem;
+ struct mutex syscall_mutex;
+ struct mutex open_mutex;
/* The 8233/8235 have 4 DX audio channels, two record and
one six channel out. We bind ch_in to DX 1, ch_out to multichannel
@@ -505,10 +506,10 @@ static inline int via_syscall_down (struct via_info *card, int nonblock)
nonblock = 0;
if (nonblock) {
- if (down_trylock (&card->syscall_sem))
+ if (!mutex_trylock(&card->syscall_mutex))
return -EAGAIN;
} else {
- if (down_interruptible (&card->syscall_sem))
+ if (mutex_lock_interruptible(&card->syscall_mutex))
return -ERESTARTSYS;
}
@@ -1609,7 +1610,7 @@ static int via_mixer_ioctl (struct inode *inode, struct file *file, unsigned int
#endif
rc = codec->mixer_ioctl(codec, cmd, arg);
- up (&card->syscall_sem);
+ mutex_unlock(&card->syscall_mutex);
out:
DPRINTK ("EXIT, returning %d\n", rc);
@@ -2228,7 +2229,7 @@ static int via_dsp_mmap(struct file *file, struct vm_area_struct *vma)
if (wr)
card->ch_out.is_mapped = 1;
- up (&card->syscall_sem);
+ mutex_unlock(&card->syscall_mutex);
rc = 0;
out:
@@ -2256,7 +2257,7 @@ handle_one_block:
/* Thomas Sailer:
* But also to ourselves, release semaphore if we do so */
if (need_resched()) {
- up(&card->syscall_sem);
+ mutex_unlock(&card->syscall_mutex);
schedule ();
ret = via_syscall_down (card, nonblock);
if (ret)
@@ -2286,7 +2287,7 @@ handle_one_block:
break;
}
- up(&card->syscall_sem);
+ mutex_unlock(&card->syscall_mutex);
DPRINTK ("Sleeping on block %d\n", n);
schedule();
@@ -2402,7 +2403,7 @@ static ssize_t via_dsp_read(struct file *file, char __user *buffer, size_t count
rc = via_dsp_do_read (card, buffer, count, nonblock);
out_up:
- up (&card->syscall_sem);
+ mutex_unlock(&card->syscall_mutex);
out:
DPRINTK ("EXIT, returning %ld\n",(long) rc);
return rc;
@@ -2426,7 +2427,7 @@ handle_one_block:
/* Thomas Sailer:
* But also to ourselves, release semaphore if we do so */
if (need_resched()) {
- up(&card->syscall_sem);
+ mutex_unlock(&card->syscall_mutex);
schedule ();
ret = via_syscall_down (card, nonblock);
if (ret)
@@ -2456,7 +2457,7 @@ handle_one_block:
break;
}
- up(&card->syscall_sem);
+ mutex_unlock(&card->syscall_mutex);
DPRINTK ("Sleeping on page %d, tmp==%d, ir==%d\n", n, tmp, chan->is_record);
schedule();
@@ -2585,7 +2586,7 @@ static ssize_t via_dsp_write(struct file *file, const char __user *buffer, size_
rc = via_dsp_do_write (card, buffer, count, nonblock);
out_up:
- up (&card->syscall_sem);
+ mutex_unlock(&card->syscall_mutex);
out:
DPRINTK ("EXIT, returning %ld\n",(long) rc);
return rc;
@@ -2634,7 +2635,7 @@ static unsigned int via_dsp_poll(struct file *file, struct poll_table_struct *wa
* Sleeps until all playback has been flushed to the audio
* hardware.
*
- * Locking: inside card->syscall_sem
+ * Locking: inside card->syscall_mutex
*/
static int via_dsp_drain_playback (struct via_info *card,
@@ -2692,7 +2693,7 @@ static int via_dsp_drain_playback (struct via_info *card,
printk (KERN_ERR "sleeping but not active\n");
#endif
- up(&card->syscall_sem);
+ mutex_unlock(&card->syscall_mutex);
DPRINTK ("sleeping, nbufs=%d\n", atomic_read (&chan->n_frags));
schedule();
@@ -2748,7 +2749,7 @@ out:
*
* Handles SNDCTL_DSP_GETISPACE and SNDCTL_DSP_GETOSPACE.
*
- * Locking: inside card->syscall_sem
+ * Locking: inside card->syscall_mutex
*/
static int via_dsp_ioctl_space (struct via_info *card,
@@ -2793,7 +2794,7 @@ static int via_dsp_ioctl_space (struct via_info *card,
*
* Handles SNDCTL_DSP_GETIPTR and SNDCTL_DSP_GETOPTR.
*
- * Locking: inside card->syscall_sem
+ * Locking: inside card->syscall_mutex
*/
static int via_dsp_ioctl_ptr (struct via_info *card,
@@ -3221,7 +3222,7 @@ static int via_dsp_ioctl (struct inode *inode, struct file *file,
break;
}
- up (&card->syscall_sem);
+ mutex_unlock(&card->syscall_mutex);
DPRINTK ("EXIT, returning %d\n", rc);
return rc;
}
@@ -3264,12 +3265,12 @@ static int via_dsp_open (struct inode *inode, struct file *file)
match:
if (nonblock) {
- if (down_trylock (&card->open_sem)) {
+ if (!mutex_trylock(&card->open_mutex)) {
DPRINTK ("EXIT, returning -EAGAIN\n");
return -EAGAIN;
}
} else {
- if (down_interruptible (&card->open_sem)) {
+ if (mutex_lock_interruptible(&card->open_mutex)) {
DPRINTK ("EXIT, returning -ERESTARTSYS\n");
return -ERESTARTSYS;
}
@@ -3355,8 +3356,8 @@ static int via_dsp_release(struct inode *inode, struct file *file)
via_chan_buffer_free (card, &card->ch_in);
}
- up (&card->syscall_sem);
- up (&card->open_sem);
+ mutex_unlock(&card->syscall_mutex);
+ mutex_unlock(&card->open_mutex);
DPRINTK ("EXIT, returning 0\n");
return 0;
@@ -3414,8 +3415,8 @@ static int __devinit via_init_one (struct pci_dev *pdev, const struct pci_device
card->card_num = via_num_cards++;
spin_lock_init (&card->lock);
spin_lock_init (&card->ac97_lock);
- init_MUTEX (&card->syscall_sem);
- init_MUTEX (&card->open_sem);
+ mutex_init(&card->syscall_mutex);
+ mutex_init(&card->open_mutex);
/* we must init these now, in case the intr handler needs them */
via_chan_init_defaults (card, &card->ch_out);
diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c
index 265423054caf..b372e88e857f 100644
--- a/sound/oss/vwsnd.c
+++ b/sound/oss/vwsnd.c
@@ -94,7 +94,7 @@
* Open will block until the previous client has closed the
* device, unless O_NONBLOCK is specified.
*
- * The semaphore devc->io_sema serializes PCM I/O syscalls. This
+ * The semaphore devc->io_mutex serializes PCM I/O syscalls. This
* is unnecessary in Linux 2.2, because the kernel lock
* serializes read, write, and ioctl globally, but it's there,
* ready for the brave, new post-kernel-lock world.
@@ -105,7 +105,7 @@
* area it owns and update its pointers. See pcm_output() and
* pcm_input() for most of the gory stuff.
*
- * devc->mix_sema serializes all mixer ioctls. This is also
+ * devc->mix_mutex serializes all mixer ioctls. This is also
* redundant because of the kernel lock.
*
* The lowest level lock is lith->lithium_lock. It is a
@@ -148,7 +148,8 @@
#include <linux/smp_lock.h>
#include <linux/wait.h>
#include <linux/interrupt.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
+
#include <asm/mach-visws/cobalt.h>
#include "sound_config.h"
@@ -1447,11 +1448,11 @@ typedef enum vwsnd_port_flags {
*
* port->lock protects: hwstate, flags, swb_[iu]_avail.
*
- * devc->io_sema protects: swstate, sw_*, swb_[iu]_idx.
+ * devc->io_mutex protects: swstate, sw_*, swb_[iu]_idx.
*
* everything else is only written by open/release or
* pcm_{setup,shutdown}(), which are serialized by a
- * combination of devc->open_sema and devc->io_sema.
+ * combination of devc->open_mutex and devc->io_mutex.
*/
typedef struct vwsnd_port {
@@ -1507,9 +1508,9 @@ typedef struct vwsnd_dev {
int audio_minor; /* minor number of audio device */
int mixer_minor; /* minor number of mixer device */
- struct semaphore open_sema;
- struct semaphore io_sema;
- struct semaphore mix_sema;
+ struct mutex open_mutex;
+ struct mutex io_mutex;
+ struct mutex mix_mutex;
mode_t open_mode;
wait_queue_head_t open_wait;
@@ -1633,7 +1634,7 @@ static __inline__ unsigned int swb_inc_i(vwsnd_port_t *port, int inc)
* mode-setting ioctls have been done, but before the first I/O is
* done.
*
- * Locking: called with devc->io_sema held.
+ * Locking: called with devc->io_mutex held.
*
* Returns 0 on success, -errno on failure.
*/
@@ -2319,9 +2320,9 @@ static ssize_t vwsnd_audio_read(struct file *file,
vwsnd_dev_t *devc = file->private_data;
ssize_t ret;
- down(&devc->io_sema);
+ mutex_lock(&devc->io_mutex);
ret = vwsnd_audio_do_read(file, buffer, count, ppos);
- up(&devc->io_sema);
+ mutex_unlock(&devc->io_mutex);
return ret;
}
@@ -2394,9 +2395,9 @@ static ssize_t vwsnd_audio_write(struct file *file,
vwsnd_dev_t *devc = file->private_data;
ssize_t ret;
- down(&devc->io_sema);
+ mutex_lock(&devc->io_mutex);
ret = vwsnd_audio_do_write(file, buffer, count, ppos);
- up(&devc->io_sema);
+ mutex_unlock(&devc->io_mutex);
return ret;
}
@@ -2891,9 +2892,9 @@ static int vwsnd_audio_ioctl(struct inode *inode,
vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data;
int ret;
- down(&devc->io_sema);
+ mutex_lock(&devc->io_mutex);
ret = vwsnd_audio_do_ioctl(inode, file, cmd, arg);
- up(&devc->io_sema);
+ mutex_unlock(&devc->io_mutex);
return ret;
}
@@ -2929,9 +2930,9 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
return -ENODEV;
}
- down(&devc->open_sema);
+ mutex_lock(&devc->open_mutex);
while (devc->open_mode & file->f_mode) {
- up(&devc->open_sema);
+ mutex_unlock(&devc->open_mutex);
if (file->f_flags & O_NONBLOCK) {
DEC_USE_COUNT;
return -EBUSY;
@@ -2941,10 +2942,10 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
DEC_USE_COUNT;
return -ERESTARTSYS;
}
- down(&devc->open_sema);
+ mutex_lock(&devc->open_mutex);
}
devc->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
- up(&devc->open_sema);
+ mutex_unlock(&devc->open_mutex);
/* get default sample format from minor number. */
@@ -2960,7 +2961,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
/* Initialize vwsnd_ports. */
- down(&devc->io_sema);
+ mutex_lock(&devc->io_mutex);
{
if (file->f_mode & FMODE_READ) {
devc->rport.swstate = SW_INITIAL;
@@ -2987,7 +2988,7 @@ static int vwsnd_audio_open(struct inode *inode, struct file *file)
devc->wport.frag_count = 0;
}
}
- up(&devc->io_sema);
+ mutex_unlock(&devc->io_mutex);
file->private_data = devc;
DBGRV();
@@ -3005,7 +3006,7 @@ static int vwsnd_audio_release(struct inode *inode, struct file *file)
int err = 0;
lock_kernel();
- down(&devc->io_sema);
+ mutex_lock(&devc->io_mutex);
{
DBGEV("(inode=0x%p, file=0x%p)\n", inode, file);
@@ -3022,13 +3023,13 @@ static int vwsnd_audio_release(struct inode *inode, struct file *file)
if (wport)
wport->swstate = SW_OFF;
}
- up(&devc->io_sema);
+ mutex_unlock(&devc->io_mutex);
- down(&devc->open_sema);
+ mutex_lock(&devc->open_mutex);
{
devc->open_mode &= ~file->f_mode;
}
- up(&devc->open_sema);
+ mutex_unlock(&devc->open_mutex);
wake_up(&devc->open_wait);
DEC_USE_COUNT;
DBGR();
@@ -3213,7 +3214,7 @@ static int vwsnd_mixer_ioctl(struct inode *ioctl,
DBGEV("(devc=0x%p, cmd=0x%x, arg=0x%lx)\n", devc, cmd, arg);
- down(&devc->mix_sema);
+ mutex_lock(&devc->mix_mutex);
{
if ((cmd & ~nrmask) == MIXER_READ(0))
retval = mixer_read_ioctl(devc, nr, (void __user *) arg);
@@ -3222,7 +3223,7 @@ static int vwsnd_mixer_ioctl(struct inode *ioctl,
else
retval = -EINVAL;
}
- up(&devc->mix_sema);
+ mutex_unlock(&devc->mix_mutex);
return retval;
}
@@ -3376,9 +3377,9 @@ static int __init attach_vwsnd(struct address_info *hw_config)
/* Initialize as much of *devc as possible */
- init_MUTEX(&devc->open_sema);
- init_MUTEX(&devc->io_sema);
- init_MUTEX(&devc->mix_sema);
+ mutex_init(&devc->open_mutex);
+ mutex_init(&devc->io_mutex);
+ mutex_init(&devc->mix_mutex);
devc->open_mode = 0;
spin_lock_init(&devc->rport.lock);
init_waitqueue_head(&devc->rport.queue);
diff --git a/sound/oss/ymfpci.c b/sound/oss/ymfpci.c
index f8bd72e46f57..bf90c124a7e6 100644
--- a/sound/oss/ymfpci.c
+++ b/sound/oss/ymfpci.c
@@ -1918,10 +1918,10 @@ static int ymf_open(struct inode *inode, struct file *file)
if (unit == NULL)
return -ENODEV;
- down(&unit->open_sem);
+ mutex_lock(&unit->open_mutex);
if ((state = ymf_state_alloc(unit)) == NULL) {
- up(&unit->open_sem);
+ mutex_unlock(&unit->open_mutex);
return -ENOMEM;
}
list_add_tail(&state->chain, &unit->states);
@@ -1956,7 +1956,7 @@ static int ymf_open(struct inode *inode, struct file *file)
ymfpci_writeb(unit, YDSXGR_TIMERCTRL,
(YDSXGR_TIMERCTRL_TEN|YDSXGR_TIMERCTRL_TIEN));
#endif
- up(&unit->open_sem);
+ mutex_unlock(&unit->open_mutex);
return nonseekable_open(inode, file);
@@ -1974,7 +1974,7 @@ out_nodma:
list_del(&state->chain);
kfree(state);
- up(&unit->open_sem);
+ mutex_unlock(&unit->open_mutex);
return err;
}
@@ -1987,7 +1987,7 @@ static int ymf_release(struct inode *inode, struct file *file)
ymfpci_writeb(unit, YDSXGR_TIMERCTRL, 0);
#endif
- down(&unit->open_sem);
+ mutex_lock(&unit->open_mutex);
/*
* XXX Solve the case of O_NONBLOCK close - don't deallocate here.
@@ -2004,7 +2004,7 @@ static int ymf_release(struct inode *inode, struct file *file)
file->private_data = NULL; /* Can you tell I programmed Solaris */
kfree(state);
- up(&unit->open_sem);
+ mutex_unlock(&unit->open_mutex);
return 0;
}
@@ -2532,7 +2532,7 @@ static int __devinit ymf_probe_one(struct pci_dev *pcidev, const struct pci_devi
spin_lock_init(&codec->reg_lock);
spin_lock_init(&codec->voice_lock);
spin_lock_init(&codec->ac97_lock);
- init_MUTEX(&codec->open_sem);
+ mutex_init(&codec->open_mutex);
INIT_LIST_HEAD(&codec->states);
codec->pci = pcidev;
diff --git a/sound/oss/ymfpci.h b/sound/oss/ymfpci.h
index f810a100c641..ac1785f2b7e7 100644
--- a/sound/oss/ymfpci.h
+++ b/sound/oss/ymfpci.h
@@ -22,6 +22,7 @@
*
*/
#include <linux/config.h>
+#include <linux/mutex.h>
/*
* Direct registers
@@ -279,7 +280,7 @@ struct ymf_unit {
/* soundcore stuff */
int dev_audio;
- struct semaphore open_sem;
+ struct mutex open_mutex;
struct list_head ymf_devs;
struct list_head states; /* List of states for this unit */