aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/Kconfig5
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c1
-rw-r--r--arch/alpha/kernel/setup.c17
-rw-r--r--arch/alpha/kernel/smp.c8
-rw-r--r--arch/arm/Kconfig6
-rw-r--r--arch/arm/boot/compressed/vmlinux.lds.in1
-rw-r--r--arch/arm/common/scoop.c12
-rw-r--r--arch/arm/configs/ep93xx_defconfig79
-rw-r--r--arch/arm/configs/ixp2000_defconfig59
-rw-r--r--arch/arm/configs/ixp23xx_defconfig58
-rw-r--r--arch/arm/kernel/armksyms.c1
-rw-r--r--arch/arm/kernel/setup.c14
-rw-r--r--arch/arm/mach-at91rm9200/devices.c12
-rw-r--r--arch/arm/mach-ixp4xx/common.c2
-rw-r--r--arch/arm/mach-omap1/devices.c11
-rw-r--r--arch/arm/mach-omap2/devices.c10
-rw-r--r--arch/arm/mach-pxa/corgi_ssp.c9
-rw-r--r--arch/arm/mach-s3c2410/clock.c4
-rw-r--r--arch/arm/mach-s3c2410/common-smdk.c3
-rw-r--r--arch/arm/mach-s3c2410/s3c2440-clock.c2
-rw-r--r--arch/arm/mm/cache-v4wb.S26
-rw-r--r--arch/arm/mm/init.c7
-rw-r--r--arch/arm/mm/proc-sa110.S25
-rw-r--r--arch/arm/mm/proc-sa1100.S37
-rw-r--r--arch/arm/plat-omap/clock.c3
-rw-r--r--arch/arm/plat-omap/devices.c22
-rw-r--r--arch/arm/vfp/vfpdouble.c29
-rw-r--r--arch/arm/vfp/vfphw.S6
-rw-r--r--arch/arm/vfp/vfpsingle.c9
-rw-r--r--arch/arm26/kernel/armksyms.c1
-rw-r--r--arch/cris/kernel/crisksyms.c1
-rw-r--r--arch/frv/kernel/entry.S26
-rw-r--r--arch/frv/kernel/frv_ksyms.c1
-rw-r--r--arch/h8300/kernel/h8300_ksyms.c1
-rw-r--r--arch/i386/Kconfig73
-rw-r--r--arch/i386/Kconfig.cpu2
-rw-r--r--arch/i386/Kconfig.debug9
-rw-r--r--arch/i386/boot/video.S5
-rw-r--r--arch/i386/kernel/Makefile2
-rw-r--r--arch/i386/kernel/acpi/boot.c11
-rw-r--r--arch/i386/kernel/apic.c23
-rw-r--r--arch/i386/kernel/apm.c2
-rw-r--r--arch/i386/kernel/cpu/amd.c4
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k8.c22
-rw-r--r--arch/i386/kernel/cpuid.c2
-rw-r--r--arch/i386/kernel/dmi_scan.c358
-rw-r--r--arch/i386/kernel/i386_ksyms.c1
-rw-r--r--arch/i386/kernel/kprobes.c18
-rw-r--r--arch/i386/kernel/mpparse.c43
-rw-r--r--arch/i386/kernel/msr.c2
-rw-r--r--arch/i386/kernel/reboot_fixups.c2
-rw-r--r--arch/i386/kernel/setup.c36
-rw-r--r--arch/i386/kernel/syscall_table.S1
-rw-r--r--arch/i386/kernel/traps.c16
-rw-r--r--arch/i386/mach-voyager/voyager_cat.c11
-rw-r--r--arch/i386/mm/init.c2
-rw-r--r--arch/i386/pci/direct.c13
-rw-r--r--arch/i386/pci/irq.c3
-rw-r--r--arch/i386/pci/mmconfig.c67
-rw-r--r--arch/ia64/Kconfig19
-rw-r--r--arch/ia64/kernel/Makefile3
-rw-r--r--arch/ia64/kernel/acpi-ext.c143
-rw-r--r--arch/ia64/kernel/entry.S4
-rw-r--r--arch/ia64/kernel/kprobes.c10
-rw-r--r--arch/ia64/kernel/mca.c43
-rw-r--r--arch/ia64/kernel/mca_asm.S10
-rw-r--r--arch/ia64/kernel/module.c2
-rw-r--r--arch/ia64/mm/discontig.c66
-rw-r--r--arch/ia64/mm/fault.c3
-rw-r--r--arch/ia64/sn/kernel/xpc_channel.c2
-rw-r--r--arch/m32r/Kconfig5
-rw-r--r--arch/m32r/kernel/entry.S55
-rw-r--r--arch/m32r/kernel/m32r_ksyms.c29
-rw-r--r--arch/m32r/kernel/process.c4
-rw-r--r--arch/m32r/kernel/setup.c12
-rw-r--r--arch/m32r/kernel/signal.c4
-rw-r--r--arch/m32r/kernel/smpboot.c19
-rw-r--r--arch/m32r/lib/Makefile4
-rw-r--r--arch/m32r/lib/getuser.S88
-rw-r--r--arch/m32r/lib/putuser.S84
-rw-r--r--arch/m68k/kernel/m68k_ksyms.c1
-rw-r--r--arch/m68knommu/kernel/m68k_ksyms.c1
-rw-r--r--arch/mips/Kconfig30
-rw-r--r--arch/mips/Makefile12
-rw-r--r--arch/mips/au1000/common/Makefile2
-rw-r--r--arch/mips/au1000/common/int-handler.S68
-rw-r--r--arch/mips/au1000/common/irq.c20
-rw-r--r--arch/mips/cobalt/Makefile2
-rw-r--r--arch/mips/cobalt/int-handler.S25
-rw-r--r--arch/mips/cobalt/irq.c6
-rw-r--r--arch/mips/configs/tb0287_defconfig1096
-rw-r--r--arch/mips/ddb5xxx/ddb5074/Makefile2
-rw-r--r--arch/mips/ddb5xxx/ddb5074/int-handler.S120
-rw-r--r--arch/mips/ddb5xxx/ddb5074/irq.c26
-rw-r--r--arch/mips/ddb5xxx/ddb5476/Makefile2
-rw-r--r--arch/mips/ddb5xxx/ddb5476/int-handler.S112
-rw-r--r--arch/mips/ddb5xxx/ddb5476/irq.c30
-rw-r--r--arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c6
-rw-r--r--arch/mips/ddb5xxx/ddb5477/Makefile2
-rw-r--r--arch/mips/ddb5xxx/ddb5477/int-handler.S75
-rw-r--r--arch/mips/ddb5xxx/ddb5477/irq.c24
-rw-r--r--arch/mips/dec/boot/decstation.c3
-rw-r--r--arch/mips/dec/int-handler.S14
-rw-r--r--arch/mips/dec/setup.c3
-rw-r--r--arch/mips/galileo-boards/ev96100/Makefile2
-rw-r--r--arch/mips/galileo-boards/ev96100/int-handler.S33
-rw-r--r--arch/mips/galileo-boards/ev96100/irq.c19
-rw-r--r--arch/mips/gt64120/ev64120/Makefile2
-rw-r--r--arch/mips/gt64120/ev64120/int-handler.S113
-rw-r--r--arch/mips/gt64120/ev64120/irq.c27
-rw-r--r--arch/mips/gt64120/momenco_ocelot/Makefile2
-rw-r--r--arch/mips/gt64120/momenco_ocelot/int-handler.S131
-rw-r--r--arch/mips/gt64120/momenco_ocelot/irq.c36
-rw-r--r--arch/mips/ite-boards/generic/Makefile2
-rw-r--r--arch/mips/ite-boards/generic/int-handler.S63
-rw-r--r--arch/mips/ite-boards/generic/irq.c18
-rw-r--r--arch/mips/ite-boards/generic/time.c1
-rw-r--r--arch/mips/ite-boards/ivr/init.c2
-rw-r--r--arch/mips/ite-boards/qed-4n-s01b/init.c2
-rw-r--r--arch/mips/jazz/Makefile2
-rw-r--r--arch/mips/jazz/int-handler.S282
-rw-r--r--arch/mips/jazz/irq.c78
-rw-r--r--arch/mips/jmr3927/common/rtc_ds1742.c60
-rw-r--r--arch/mips/jmr3927/rbhma3100/Makefile2
-rw-r--r--arch/mips/jmr3927/rbhma3100/int-handler.S74
-rw-r--r--arch/mips/jmr3927/rbhma3100/irq.c6
-rw-r--r--arch/mips/kernel/Makefile5
-rw-r--r--arch/mips/kernel/asm-offsets.c3
-rw-r--r--arch/mips/kernel/entry.S69
-rw-r--r--arch/mips/kernel/gdb-low.S24
-rw-r--r--arch/mips/kernel/gdb-stub.c61
-rw-r--r--arch/mips/kernel/genex.S43
-rw-r--r--arch/mips/kernel/head.S57
-rw-r--r--arch/mips/kernel/i8259.c4
-rw-r--r--arch/mips/kernel/irq-msc01.c9
-rw-r--r--arch/mips/kernel/irq.c18
-rw-r--r--arch/mips/kernel/kspd.c398
-rw-r--r--arch/mips/kernel/linux32.c10
-rw-r--r--arch/mips/kernel/mips-mt.c449
-rw-r--r--arch/mips/kernel/mips_ksyms.c16
-rw-r--r--arch/mips/kernel/process.c21
-rw-r--r--arch/mips/kernel/ptrace.c14
-rw-r--r--arch/mips/kernel/ptrace32.c14
-rw-r--r--arch/mips/kernel/r4k_switch.S34
-rw-r--r--arch/mips/kernel/rtlx.c517
-rw-r--r--arch/mips/kernel/scall32-o32.S13
-rw-r--r--arch/mips/kernel/scall64-64.S2
-rw-r--r--arch/mips/kernel/scall64-n32.S2
-rw-r--r--arch/mips/kernel/scall64-o32.S2
-rw-r--r--arch/mips/kernel/setup.c5
-rw-r--r--arch/mips/kernel/smp-mt.c (renamed from arch/mips/kernel/smp_mt.c)44
-rw-r--r--arch/mips/kernel/smp.c12
-rw-r--r--arch/mips/kernel/smtc-asm.S130
-rw-r--r--arch/mips/kernel/smtc-proc.c93
-rw-r--r--arch/mips/kernel/smtc.c1322
-rw-r--r--arch/mips/kernel/time.c3
-rw-r--r--arch/mips/kernel/traps.c212
-rw-r--r--arch/mips/kernel/vmlinux.lds.S2
-rw-r--r--arch/mips/kernel/vpe.c659
-rw-r--r--arch/mips/lasat/Makefile2
-rw-r--r--arch/mips/lasat/interrupt.c14
-rw-r--r--arch/mips/lasat/lasatIRQ.S69
-rw-r--r--arch/mips/mips-boards/atlas/atlas_int.c92
-rw-r--r--arch/mips/mips-boards/generic/Makefile4
-rw-r--r--arch/mips/mips-boards/generic/gdb_hook.c2
-rw-r--r--arch/mips/mips-boards/generic/init.c1
-rw-r--r--arch/mips/mips-boards/generic/memory.c9
-rw-r--r--arch/mips/mips-boards/generic/mipsIRQ.S155
-rw-r--r--arch/mips/mips-boards/generic/time.c68
-rw-r--r--arch/mips/mips-boards/malta/Makefile1
-rw-r--r--arch/mips/mips-boards/malta/malta_int.c102
-rw-r--r--arch/mips/mips-boards/malta/malta_smp.c128
-rw-r--r--arch/mips/mips-boards/sead/sead_int.c86
-rw-r--r--arch/mips/mips-boards/sim/cmdline.c59
-rw-r--r--arch/mips/mips-boards/sim/sim_cmdline.c6
-rw-r--r--arch/mips/mips-boards/sim/sim_int.c64
-rw-r--r--arch/mips/mips-boards/sim/sim_irq.S4
-rw-r--r--arch/mips/mips-boards/sim/sim_mem.c9
-rw-r--r--arch/mips/mips-boards/sim/sim_smp.c14
-rw-r--r--arch/mips/mm/c-r3k.c5
-rw-r--r--arch/mips/mm/c-r4k.c20
-rw-r--r--arch/mips/mm/c-sb1.c1
-rw-r--r--arch/mips/mm/c-tx39.c7
-rw-r--r--arch/mips/mm/cache.c1
-rw-r--r--arch/mips/mm/fault.c13
-rw-r--r--arch/mips/mm/highmem.c2
-rw-r--r--arch/mips/mm/init.c48
-rw-r--r--arch/mips/mm/sc-rm7k.c2
-rw-r--r--arch/mips/mm/tlb-r4k.c85
-rw-r--r--arch/mips/mm/tlbex.c87
-rw-r--r--arch/mips/momentum/jaguar_atx/Makefile2
-rw-r--r--arch/mips/momentum/jaguar_atx/int-handler.S128
-rw-r--r--arch/mips/momentum/jaguar_atx/irq.c35
-rw-r--r--arch/mips/momentum/jaguar_atx/setup.c36
-rw-r--r--arch/mips/momentum/ocelot_3/Makefile2
-rw-r--r--arch/mips/momentum/ocelot_3/int-handler.S137
-rw-r--r--arch/mips/momentum/ocelot_3/irq.c38
-rw-r--r--arch/mips/momentum/ocelot_3/setup.c24
-rw-r--r--arch/mips/momentum/ocelot_c/Makefile2
-rw-r--r--arch/mips/momentum/ocelot_c/int-handler.S102
-rw-r--r--arch/mips/momentum/ocelot_c/irq.c30
-rw-r--r--arch/mips/momentum/ocelot_g/Makefile2
-rw-r--r--arch/mips/momentum/ocelot_g/int-handler.S131
-rw-r--r--arch/mips/momentum/ocelot_g/irq.c38
-rw-r--r--arch/mips/philips/pnx8550/common/Makefile2
-rw-r--r--arch/mips/philips/pnx8550/common/int.c23
-rw-r--r--arch/mips/philips/pnx8550/common/mipsIRQ.S76
-rw-r--r--arch/mips/philips/pnx8550/common/platform.c1
-rw-r--r--arch/mips/pmc-sierra/yosemite/Makefile2
-rw-r--r--arch/mips/pmc-sierra/yosemite/irq-handler.S93
-rw-r--r--arch/mips/pmc-sierra/yosemite/irq.c33
-rw-r--r--arch/mips/qemu/Makefile2
-rw-r--r--arch/mips/qemu/q-int.S17
-rw-r--r--arch/mips/qemu/q-irq.c3
-rw-r--r--arch/mips/sgi-ip22/Makefile2
-rw-r--r--arch/mips/sgi-ip22/ip22-int.c59
-rw-r--r--arch/mips/sgi-ip22/ip22-irq.S118
-rw-r--r--arch/mips/sgi-ip27/Makefile2
-rw-r--r--arch/mips/sgi-ip27/TODO4
-rw-r--r--arch/mips/sgi-ip27/ip27-irq-glue.S45
-rw-r--r--arch/mips/sgi-ip27/ip27-irq.c27
-rw-r--r--arch/mips/sgi-ip32/Makefile2
-rw-r--r--arch/mips/sgi-ip32/ip32-irq-glue.S86
-rw-r--r--arch/mips/sgi-ip32/ip32-irq.c33
-rw-r--r--arch/mips/sibyte/bcm1480/Makefile2
-rw-r--r--arch/mips/sibyte/bcm1480/irq.c77
-rw-r--r--arch/mips/sibyte/bcm1480/irq_handler.S165
-rw-r--r--arch/mips/sibyte/sb1250/Makefile2
-rw-r--r--arch/mips/sibyte/sb1250/irq.c78
-rw-r--r--arch/mips/sibyte/sb1250/irq_handler.S147
-rw-r--r--arch/mips/sni/Makefile2
-rw-r--r--arch/mips/sni/int-handler.S106
-rw-r--r--arch/mips/sni/irq.c37
-rw-r--r--arch/mips/tx4927/common/Makefile2
-rw-r--r--arch/mips/tx4927/common/tx4927_irq.c30
-rw-r--r--arch/mips/tx4927/common/tx4927_irq_handler.S103
-rw-r--r--arch/mips/tx4938/common/Makefile2
-rw-r--r--arch/mips/tx4938/common/irq.c21
-rw-r--r--arch/mips/tx4938/common/irq_handler.S84
-rw-r--r--arch/mips/vr41xx/Kconfig13
-rw-r--r--arch/mips/vr41xx/common/Makefile2
-rw-r--r--arch/mips/vr41xx/common/int-handler.S114
-rw-r--r--arch/mips/vr41xx/common/irq.c29
-rw-r--r--arch/parisc/Kconfig5
-rw-r--r--arch/parisc/kernel/parisc_ksyms.c1
-rw-r--r--arch/powerpc/Kconfig11
-rw-r--r--arch/powerpc/Makefile4
-rw-r--r--arch/powerpc/kernel/Makefile2
-rw-r--r--arch/powerpc/kernel/asm-offsets.c1
-rw-r--r--arch/powerpc/kernel/entry_32.S35
-rw-r--r--arch/powerpc/kernel/head_64.S49
-rw-r--r--arch/powerpc/kernel/idle.c4
-rw-r--r--arch/powerpc/kernel/idle_6xx.S63
-rw-r--r--arch/powerpc/kernel/idle_power4.S10
-rw-r--r--arch/powerpc/kernel/irq.c36
-rw-r--r--arch/powerpc/kernel/kprobes.c14
-rw-r--r--arch/powerpc/kernel/prom_init.c5
-rw-r--r--arch/powerpc/kernel/rtas-proc.c4
-rw-r--r--arch/powerpc/kernel/systbl.S1
-rw-r--r--arch/powerpc/platforms/cell/spufs/switch.c2
-rw-r--r--arch/powerpc/platforms/chrp/chrp.h1
-rw-r--r--arch/powerpc/platforms/chrp/pci.c6
-rw-r--r--arch/powerpc/platforms/chrp/setup.c44
-rw-r--r--arch/powerpc/platforms/iseries/setup.c7
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c6
-rw-r--r--arch/powerpc/platforms/pseries/rtasd.c2
-rw-r--r--arch/ppc/boot/lib/Makefile2
-rw-r--r--arch/ppc/syslib/ppc_sys.c9
-rw-r--r--arch/s390/Makefile1
-rw-r--r--arch/s390/defconfig48
-rw-r--r--arch/sh/Kconfig5
-rw-r--r--arch/sh/kernel/sh_ksyms.c1
-rw-r--r--arch/sh64/kernel/sh_ksyms.c1
-rw-r--r--arch/sparc/kernel/smp.c2
-rw-r--r--arch/sparc/kernel/sparc_ksyms.c1
-rw-r--r--arch/sparc/kernel/systbls.S2
-rw-r--r--arch/sparc/math-emu/Makefile2
-rw-r--r--arch/sparc64/Kconfig5
-rw-r--r--arch/sparc64/defconfig10
-rw-r--r--arch/sparc64/kernel/kprobes.c12
-rw-r--r--arch/sparc64/kernel/pci.c1
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c2
-rw-r--r--arch/sparc64/kernel/ptrace.c23
-rw-r--r--arch/sparc64/kernel/setup.c2
-rw-r--r--arch/sparc64/kernel/smp.c41
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c1
-rw-r--r--arch/sparc64/kernel/sys32.S1
-rw-r--r--arch/sparc64/kernel/systbls.S4
-rw-r--r--arch/sparc64/kernel/traps.c4
-rw-r--r--arch/um/Makefile3
-rw-r--r--arch/um/drivers/cow.h2
-rw-r--r--arch/um/drivers/cow_sys.h2
-rw-r--r--arch/um/drivers/cow_user.c96
-rw-r--r--arch/um/drivers/mconsole_kern.c8
-rw-r--r--arch/um/drivers/net_user.c4
-rw-r--r--arch/um/drivers/slirp_user.c2
-rw-r--r--arch/um/include/kern_util.h4
-rw-r--r--arch/um/include/longjmp.h4
-rw-r--r--arch/um/include/sysdep-i386/kernel-offsets.h2
-rw-r--r--arch/um/include/sysdep-x86_64/kernel-offsets.h2
-rw-r--r--arch/um/include/tt/tt.h3
-rw-r--r--arch/um/include/user.h6
-rw-r--r--arch/um/include/user_util.h3
-rw-r--r--arch/um/kernel/ksyms.c5
-rw-r--r--arch/um/os-Linux/drivers/ethertap_user.c2
-rw-r--r--arch/um/os-Linux/helper.c10
-rw-r--r--arch/um/os-Linux/mem.c141
-rw-r--r--arch/um/os-Linux/process.c8
-rw-r--r--arch/um/os-Linux/sigio.c2
-rw-r--r--arch/um/os-Linux/skas/mem.c4
-rw-r--r--arch/um/os-Linux/skas/process.c40
-rw-r--r--arch/um/os-Linux/start_up.c24
-rw-r--r--arch/um/os-Linux/sys-i386/tls.c1
-rw-r--r--arch/um/os-Linux/trap.c4
-rw-r--r--arch/um/os-Linux/uaccess.c4
-rw-r--r--arch/um/os-Linux/umid.c15
-rw-r--r--arch/um/os-Linux/user_syms.c9
-rw-r--r--arch/um/os-Linux/util.c2
-rw-r--r--arch/um/scripts/Makefile.rules6
-rw-r--r--arch/um/sys-i386/ksyms.c4
-rw-r--r--arch/um/sys-i386/ptrace_user.c2
-rw-r--r--arch/um/sys-i386/signal.c8
-rw-r--r--arch/um/sys-i386/stub_segv.c4
-rw-r--r--arch/um/sys-i386/tls.c2
-rw-r--r--arch/um/sys-x86_64/signal.c2
-rw-r--r--arch/um/sys-x86_64/stub_segv.c10
-rw-r--r--arch/v850/kernel/v850_ksyms.c1
-rw-r--r--arch/x86_64/Kconfig10
-rw-r--r--arch/x86_64/Makefile24
-rw-r--r--arch/x86_64/boot/video.S5
-rw-r--r--arch/x86_64/defconfig57
-rw-r--r--arch/x86_64/ia32/ia32entry.S24
-rw-r--r--arch/x86_64/kernel/Makefile4
-rw-r--r--arch/x86_64/kernel/aperture.c2
-rw-r--r--arch/x86_64/kernel/e820.c36
-rw-r--r--arch/x86_64/kernel/entry.S28
-rw-r--r--arch/x86_64/kernel/kprobes.c10
-rw-r--r--arch/x86_64/kernel/mce.c8
-rw-r--r--arch/x86_64/kernel/nmi.c7
-rw-r--r--arch/x86_64/kernel/pci-dma.c2
-rw-r--r--arch/x86_64/kernel/process.c14
-rw-r--r--arch/x86_64/kernel/ptrace.c5
-rw-r--r--arch/x86_64/kernel/setup.c8
-rw-r--r--arch/x86_64/kernel/time.c4
-rw-r--r--arch/x86_64/kernel/traps.c5
-rw-r--r--arch/x86_64/kernel/vmlinux.lds.S2
-rw-r--r--arch/x86_64/kernel/x8664_ksyms.c3
-rw-r--r--arch/x86_64/mm/init.c37
-rw-r--r--arch/x86_64/mm/numa.c46
-rw-r--r--arch/x86_64/mm/srat.c170
-rw-r--r--arch/x86_64/pci/mmconfig.c53
-rw-r--r--arch/xtensa/kernel/xtensa_ksyms.c1
352 files changed, 8307 insertions, 5466 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 9bef61b30367..8290b69da202 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -549,6 +549,11 @@ config NUMA
549 Access). This option is for configuring high-end multiprocessor 549 Access). This option is for configuring high-end multiprocessor
550 server machines. If in doubt, say N. 550 server machines. If in doubt, say N.
551 551
552config NODES_SHIFT
553 int
554 default "7"
555 depends on NEED_MULTIPLE_NODES
556
552# LARGE_VMALLOC is racy, if you *really* need it then fix it first 557# LARGE_VMALLOC is racy, if you *really* need it then fix it first
553config ALPHA_LARGE_VMALLOC 558config ALPHA_LARGE_VMALLOC
554 bool 559 bool
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index 9d6186d50245..c645c5e14786 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -76,7 +76,6 @@ EXPORT_SYMBOL(strncpy);
76EXPORT_SYMBOL(strnlen); 76EXPORT_SYMBOL(strnlen);
77EXPORT_SYMBOL(strncat); 77EXPORT_SYMBOL(strncat);
78EXPORT_SYMBOL(strstr); 78EXPORT_SYMBOL(strstr);
79EXPORT_SYMBOL(strpbrk);
80EXPORT_SYMBOL(strchr); 79EXPORT_SYMBOL(strchr);
81EXPORT_SYMBOL(strrchr); 80EXPORT_SYMBOL(strrchr);
82EXPORT_SYMBOL(memcmp); 81EXPORT_SYMBOL(memcmp);
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index a15e18a00258..558b83368559 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -24,6 +24,7 @@
24#include <linux/config.h> /* CONFIG_ALPHA_LCA etc */ 24#include <linux/config.h> /* CONFIG_ALPHA_LCA etc */
25#include <linux/mc146818rtc.h> 25#include <linux/mc146818rtc.h>
26#include <linux/console.h> 26#include <linux/console.h>
27#include <linux/cpu.h>
27#include <linux/errno.h> 28#include <linux/errno.h>
28#include <linux/init.h> 29#include <linux/init.h>
29#include <linux/string.h> 30#include <linux/string.h>
@@ -471,6 +472,22 @@ page_is_ram(unsigned long pfn)
471 return 0; 472 return 0;
472} 473}
473 474
475static int __init
476register_cpus(void)
477{
478 int i;
479
480 for_each_possible_cpu(i) {
481 struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL);
482 if (!p)
483 return -ENOMEM;
484 register_cpu(p, i, NULL);
485 }
486 return 0;
487}
488
489arch_initcall(register_cpus);
490
474void __init 491void __init
475setup_arch(char **cmdline_p) 492setup_arch(char **cmdline_p)
476{ 493{
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index 02c2db08114a..185255416e85 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -439,7 +439,7 @@ setup_smp(void)
439 if ((cpu->flags & 0x1cc) == 0x1cc) { 439 if ((cpu->flags & 0x1cc) == 0x1cc) {
440 smp_num_probed++; 440 smp_num_probed++;
441 /* Assume here that "whami" == index */ 441 /* Assume here that "whami" == index */
442 cpu_set(i, cpu_possible_map); 442 cpu_set(i, cpu_present_mask);
443 cpu->pal_revision = boot_cpu_palrev; 443 cpu->pal_revision = boot_cpu_palrev;
444 } 444 }
445 445
@@ -450,9 +450,8 @@ setup_smp(void)
450 } 450 }
451 } else { 451 } else {
452 smp_num_probed = 1; 452 smp_num_probed = 1;
453 cpu_set(boot_cpuid, cpu_possible_map); 453 cpu_set(boot_cpuid, cpu_present_mask);
454 } 454 }
455 cpu_present_mask = cpumask_of_cpu(boot_cpuid);
456 455
457 printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", 456 printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n",
458 smp_num_probed, cpu_possible_map.bits[0]); 457 smp_num_probed, cpu_possible_map.bits[0]);
@@ -488,9 +487,8 @@ void __devinit
488smp_prepare_boot_cpu(void) 487smp_prepare_boot_cpu(void)
489{ 488{
490 /* 489 /*
491 * Mark the boot cpu (current cpu) as both present and online 490 * Mark the boot cpu (current cpu) as online
492 */ 491 */
493 cpu_set(smp_processor_id(), cpu_present_mask);
494 cpu_set(smp_processor_id(), cpu_online_map); 492 cpu_set(smp_processor_id(), cpu_online_map);
495} 493}
496 494
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index dc5a9332c915..1dbf6ddb300d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -512,6 +512,12 @@ config ARCH_DISCONTIGMEM_ENABLE
512 or have huge holes in the physical address space for other reasons. 512 or have huge holes in the physical address space for other reasons.
513 See <file:Documentation/vm/numa> for more. 513 See <file:Documentation/vm/numa> for more.
514 514
515config NODES_SHIFT
516 int
517 default "4" if ARCH_LH7A40X
518 default "2"
519 depends on NEED_MULTIPLE_NODES
520
515source "mm/Kconfig" 521source "mm/Kconfig"
516 522
517config LEDS 523config LEDS
diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in
index eed616113e47..153a07e7222b 100644
--- a/arch/arm/boot/compressed/vmlinux.lds.in
+++ b/arch/arm/boot/compressed/vmlinux.lds.in
@@ -18,6 +18,7 @@ SECTIONS
18 _start = .; 18 _start = .;
19 *(.start) 19 *(.start)
20 *(.text) 20 *(.text)
21 *(.text.*)
21 *(.fixup) 22 *(.fixup)
22 *(.gnu.warning) 23 *(.gnu.warning)
23 *(.rodata) 24 *(.rodata)
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index 5e830f444c6c..314ebd3a1d71 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -18,6 +18,18 @@
18#include <asm/io.h> 18#include <asm/io.h>
19#include <asm/hardware/scoop.h> 19#include <asm/hardware/scoop.h>
20 20
21/* PCMCIA to Scoop linkage
22
23 There is no easy way to link multiple scoop devices into one
24 single entity for the pxa2xx_pcmcia device so this structure
25 is used which is setup by the platform code.
26
27 This file is never modular so this symbol is always
28 accessile to the board support files.
29*/
30struct scoop_pcmcia_config *platform_scoop_config;
31EXPORT_SYMBOL(platform_scoop_config);
32
21#define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr))) 33#define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr)))
22 34
23struct scoop_dev { 35struct scoop_dev {
diff --git a/arch/arm/configs/ep93xx_defconfig b/arch/arm/configs/ep93xx_defconfig
index 8dcc8e8ec813..b69e88bbc909 100644
--- a/arch/arm/configs/ep93xx_defconfig
+++ b/arch/arm/configs/ep93xx_defconfig
@@ -1,12 +1,14 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.16 3# Linux kernel version: 2.6.17-rc2
4# Mon Mar 20 14:54:51 2006 4# Wed Apr 19 21:21:01 2006
5# 5#
6CONFIG_ARM=y 6CONFIG_ARM=y
7CONFIG_MMU=y 7CONFIG_MMU=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y 8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HWEIGHT=y
9CONFIG_GENERIC_CALIBRATE_DELAY=y 10CONFIG_GENERIC_CALIBRATE_DELAY=y
11CONFIG_VECTORS_BASE=0xffff0000
10 12
11# 13#
12# Code maturity level options 14# Code maturity level options
@@ -28,6 +30,7 @@ CONFIG_SYSCTL=y
28# CONFIG_AUDIT is not set 30# CONFIG_AUDIT is not set
29CONFIG_IKCONFIG=y 31CONFIG_IKCONFIG=y
30CONFIG_IKCONFIG_PROC=y 32CONFIG_IKCONFIG_PROC=y
33# CONFIG_RELAY is not set
31CONFIG_INITRAMFS_SOURCE="" 34CONFIG_INITRAMFS_SOURCE=""
32CONFIG_UID16=y 35CONFIG_UID16=y
33CONFIG_CC_OPTIMIZE_FOR_SIZE=y 36CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -43,10 +46,6 @@ CONFIG_BASE_FULL=y
43CONFIG_FUTEX=y 46CONFIG_FUTEX=y
44CONFIG_EPOLL=y 47CONFIG_EPOLL=y
45CONFIG_SHMEM=y 48CONFIG_SHMEM=y
46CONFIG_CC_ALIGN_FUNCTIONS=0
47CONFIG_CC_ALIGN_LABELS=0
48CONFIG_CC_ALIGN_LOOPS=0
49CONFIG_CC_ALIGN_JUMPS=0
50CONFIG_SLAB=y 49CONFIG_SLAB=y
51# CONFIG_TINY_SHMEM is not set 50# CONFIG_TINY_SHMEM is not set
52CONFIG_BASE_SMALL=0 51CONFIG_BASE_SMALL=0
@@ -59,7 +58,6 @@ CONFIG_OBSOLETE_INTERMODULE=y
59CONFIG_MODULES=y 58CONFIG_MODULES=y
60CONFIG_MODULE_UNLOAD=y 59CONFIG_MODULE_UNLOAD=y
61CONFIG_MODULE_FORCE_UNLOAD=y 60CONFIG_MODULE_FORCE_UNLOAD=y
62CONFIG_OBSOLETE_MODPARM=y
63# CONFIG_MODVERSIONS is not set 61# CONFIG_MODVERSIONS is not set
64# CONFIG_MODULE_SRCVERSION_ALL is not set 62# CONFIG_MODULE_SRCVERSION_ALL is not set
65CONFIG_KMOD=y 63CONFIG_KMOD=y
@@ -67,6 +65,7 @@ CONFIG_KMOD=y
67# 65#
68# Block layer 66# Block layer
69# 67#
68# CONFIG_BLK_DEV_IO_TRACE is not set
70 69
71# 70#
72# IO Schedulers 71# IO Schedulers
@@ -94,6 +93,7 @@ CONFIG_ARCH_EP93XX=y
94# CONFIG_ARCH_IOP3XX is not set 93# CONFIG_ARCH_IOP3XX is not set
95# CONFIG_ARCH_IXP4XX is not set 94# CONFIG_ARCH_IXP4XX is not set
96# CONFIG_ARCH_IXP2000 is not set 95# CONFIG_ARCH_IXP2000 is not set
96# CONFIG_ARCH_IXP23XX is not set
97# CONFIG_ARCH_L7200 is not set 97# CONFIG_ARCH_L7200 is not set
98# CONFIG_ARCH_PXA is not set 98# CONFIG_ARCH_PXA is not set
99# CONFIG_ARCH_RPC is not set 99# CONFIG_ARCH_RPC is not set
@@ -112,7 +112,6 @@ CONFIG_ARCH_EP93XX=y
112# 112#
113# Cirrus EP93xx Implementation Options 113# Cirrus EP93xx Implementation Options
114# 114#
115CONFIG_CRUNCH=y
116 115
117# 116#
118# EP93xx Platforms 117# EP93xx Platforms
@@ -232,12 +231,15 @@ CONFIG_SYN_COOKIES=y
232# CONFIG_INET_AH is not set 231# CONFIG_INET_AH is not set
233# CONFIG_INET_ESP is not set 232# CONFIG_INET_ESP is not set
234# CONFIG_INET_IPCOMP is not set 233# CONFIG_INET_IPCOMP is not set
234# CONFIG_INET_XFRM_TUNNEL is not set
235# CONFIG_INET_TUNNEL is not set 235# CONFIG_INET_TUNNEL is not set
236CONFIG_INET_DIAG=y 236CONFIG_INET_DIAG=y
237CONFIG_INET_TCP_DIAG=y 237CONFIG_INET_TCP_DIAG=y
238# CONFIG_TCP_CONG_ADVANCED is not set 238# CONFIG_TCP_CONG_ADVANCED is not set
239CONFIG_TCP_CONG_BIC=y 239CONFIG_TCP_CONG_BIC=y
240# CONFIG_IPV6 is not set 240# CONFIG_IPV6 is not set
241# CONFIG_INET6_XFRM_TUNNEL is not set
242# CONFIG_INET6_TUNNEL is not set
241# CONFIG_NETFILTER is not set 243# CONFIG_NETFILTER is not set
242 244
243# 245#
@@ -346,7 +348,6 @@ CONFIG_MTD_CFI_I2=y
346# CONFIG_MTD_OTP is not set 348# CONFIG_MTD_OTP is not set
347CONFIG_MTD_CFI_INTELEXT=y 349CONFIG_MTD_CFI_INTELEXT=y
348CONFIG_MTD_CFI_AMDSTD=y 350CONFIG_MTD_CFI_AMDSTD=y
349CONFIG_MTD_CFI_AMDSTD_RETRY=0
350CONFIG_MTD_CFI_STAA=y 351CONFIG_MTD_CFI_STAA=y
351CONFIG_MTD_CFI_UTIL=y 352CONFIG_MTD_CFI_UTIL=y
352# CONFIG_MTD_RAM is not set 353# CONFIG_MTD_RAM is not set
@@ -371,7 +372,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1
371# CONFIG_MTD_SLRAM is not set 372# CONFIG_MTD_SLRAM is not set
372# CONFIG_MTD_PHRAM is not set 373# CONFIG_MTD_PHRAM is not set
373# CONFIG_MTD_MTDRAM is not set 374# CONFIG_MTD_MTDRAM is not set
374# CONFIG_MTD_BLKMTD is not set
375# CONFIG_MTD_BLOCK2MTD is not set 375# CONFIG_MTD_BLOCK2MTD is not set
376 376
377# 377#
@@ -412,7 +412,7 @@ CONFIG_MTD_NAND_IDS=y
412# CONFIG_BLK_DEV_NBD is not set 412# CONFIG_BLK_DEV_NBD is not set
413# CONFIG_BLK_DEV_UB is not set 413# CONFIG_BLK_DEV_UB is not set
414# CONFIG_BLK_DEV_RAM is not set 414# CONFIG_BLK_DEV_RAM is not set
415CONFIG_BLK_DEV_RAM_COUNT=16 415# CONFIG_BLK_DEV_INITRD is not set
416# CONFIG_CDROM_PKTCDVD is not set 416# CONFIG_CDROM_PKTCDVD is not set
417# CONFIG_ATA_OVER_ETH is not set 417# CONFIG_ATA_OVER_ETH is not set
418 418
@@ -576,13 +576,13 @@ CONFIG_WATCHDOG=y
576# Watchdog Device Drivers 576# Watchdog Device Drivers
577# 577#
578# CONFIG_SOFT_WATCHDOG is not set 578# CONFIG_SOFT_WATCHDOG is not set
579CONFIG_EP93XX_WATCHDOG=y
579 580
580# 581#
581# USB-based Watchdog Cards 582# USB-based Watchdog Cards
582# 583#
583# CONFIG_USBPCWATCHDOG is not set 584# CONFIG_USBPCWATCHDOG is not set
584# CONFIG_NVRAM is not set 585# CONFIG_NVRAM is not set
585# CONFIG_RTC is not set
586# CONFIG_DTLK is not set 586# CONFIG_DTLK is not set
587# CONFIG_R3964 is not set 587# CONFIG_R3964 is not set
588 588
@@ -626,9 +626,7 @@ CONFIG_I2C_ALGOBIT=y
626# CONFIG_SENSORS_PCF8574 is not set 626# CONFIG_SENSORS_PCF8574 is not set
627# CONFIG_SENSORS_PCA9539 is not set 627# CONFIG_SENSORS_PCA9539 is not set
628# CONFIG_SENSORS_PCF8591 is not set 628# CONFIG_SENSORS_PCF8591 is not set
629# CONFIG_SENSORS_RTC8564 is not set
630# CONFIG_SENSORS_MAX6875 is not set 629# CONFIG_SENSORS_MAX6875 is not set
631# CONFIG_RTC_X1205_I2C is not set
632CONFIG_I2C_DEBUG_CORE=y 630CONFIG_I2C_DEBUG_CORE=y
633CONFIG_I2C_DEBUG_ALGO=y 631CONFIG_I2C_DEBUG_ALGO=y
634CONFIG_I2C_DEBUG_BUS=y 632CONFIG_I2C_DEBUG_BUS=y
@@ -690,7 +688,16 @@ CONFIG_HWMON=y
690# 688#
691 689
692# 690#
693# Multimedia Capabilities Port drivers 691# LED devices
692#
693# CONFIG_NEW_LEDS is not set
694
695#
696# LED drivers
697#
698
699#
700# LED Triggers
694# 701#
695 702
696# 703#
@@ -702,6 +709,7 @@ CONFIG_HWMON=y
702# Digital Video Broadcasting Devices 709# Digital Video Broadcasting Devices
703# 710#
704# CONFIG_DVB is not set 711# CONFIG_DVB is not set
712# CONFIG_USB_DABUSB is not set
705 713
706# 714#
707# Graphics support 715# Graphics support
@@ -718,6 +726,7 @@ CONFIG_HWMON=y
718# 726#
719CONFIG_USB_ARCH_HAS_HCD=y 727CONFIG_USB_ARCH_HAS_HCD=y
720# CONFIG_USB_ARCH_HAS_OHCI is not set 728# CONFIG_USB_ARCH_HAS_OHCI is not set
729# CONFIG_USB_ARCH_HAS_EHCI is not set
721CONFIG_USB=y 730CONFIG_USB=y
722CONFIG_USB_DEBUG=y 731CONFIG_USB_DEBUG=y
723 732
@@ -776,15 +785,6 @@ CONFIG_USB_STORAGE=y
776# CONFIG_USB_MICROTEK is not set 785# CONFIG_USB_MICROTEK is not set
777 786
778# 787#
779# USB Multimedia devices
780#
781# CONFIG_USB_DABUSB is not set
782
783#
784# Video4Linux support is needed for USB Multimedia device support
785#
786
787#
788# USB Network Adapters 788# USB Network Adapters
789# 789#
790# CONFIG_USB_CATC is not set 790# CONFIG_USB_CATC is not set
@@ -813,6 +813,7 @@ CONFIG_USB_SERIAL_CONSOLE=y
813# CONFIG_USB_SERIAL_CYPRESS_M8 is not set 813# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
814# CONFIG_USB_SERIAL_EMPEG is not set 814# CONFIG_USB_SERIAL_EMPEG is not set
815# CONFIG_USB_SERIAL_FTDI_SIO is not set 815# CONFIG_USB_SERIAL_FTDI_SIO is not set
816# CONFIG_USB_SERIAL_FUNSOFT is not set
816# CONFIG_USB_SERIAL_VISOR is not set 817# CONFIG_USB_SERIAL_VISOR is not set
817# CONFIG_USB_SERIAL_IPAQ is not set 818# CONFIG_USB_SERIAL_IPAQ is not set
818# CONFIG_USB_SERIAL_IR is not set 819# CONFIG_USB_SERIAL_IR is not set
@@ -825,6 +826,7 @@ CONFIG_USB_SERIAL_CONSOLE=y
825# CONFIG_USB_SERIAL_KLSI is not set 826# CONFIG_USB_SERIAL_KLSI is not set
826# CONFIG_USB_SERIAL_KOBIL_SCT is not set 827# CONFIG_USB_SERIAL_KOBIL_SCT is not set
827# CONFIG_USB_SERIAL_MCT_U232 is not set 828# CONFIG_USB_SERIAL_MCT_U232 is not set
829# CONFIG_USB_SERIAL_NAVMAN is not set
828CONFIG_USB_SERIAL_PL2303=y 830CONFIG_USB_SERIAL_PL2303=y
829# CONFIG_USB_SERIAL_HP4X is not set 831# CONFIG_USB_SERIAL_HP4X is not set
830# CONFIG_USB_SERIAL_SAFE is not set 832# CONFIG_USB_SERIAL_SAFE is not set
@@ -865,6 +867,32 @@ CONFIG_USB_SERIAL_PL2303=y
865# CONFIG_MMC is not set 867# CONFIG_MMC is not set
866 868
867# 869#
870# Real Time Clock
871#
872CONFIG_RTC_LIB=y
873CONFIG_RTC_CLASS=y
874CONFIG_RTC_HCTOSYS=y
875CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
876
877#
878# RTC interfaces
879#
880CONFIG_RTC_INTF_SYSFS=y
881CONFIG_RTC_INTF_PROC=y
882CONFIG_RTC_INTF_DEV=y
883
884#
885# RTC drivers
886#
887# CONFIG_RTC_DRV_X1205 is not set
888# CONFIG_RTC_DRV_DS1672 is not set
889# CONFIG_RTC_DRV_PCF8563 is not set
890# CONFIG_RTC_DRV_RS5C372 is not set
891CONFIG_RTC_DRV_M48T86=y
892CONFIG_RTC_DRV_EP93XX=y
893# CONFIG_RTC_DRV_TEST is not set
894
895#
868# File systems 896# File systems
869# 897#
870CONFIG_EXT2_FS=y 898CONFIG_EXT2_FS=y
@@ -912,7 +940,6 @@ CONFIG_SYSFS=y
912CONFIG_TMPFS=y 940CONFIG_TMPFS=y
913# CONFIG_HUGETLB_PAGE is not set 941# CONFIG_HUGETLB_PAGE is not set
914CONFIG_RAMFS=y 942CONFIG_RAMFS=y
915# CONFIG_RELAYFS_FS is not set
916# CONFIG_CONFIGFS_FS is not set 943# CONFIG_CONFIGFS_FS is not set
917 944
918# 945#
@@ -1044,6 +1071,7 @@ CONFIG_LOG_BUF_SHIFT=14
1044CONFIG_DETECT_SOFTLOCKUP=y 1071CONFIG_DETECT_SOFTLOCKUP=y
1045# CONFIG_SCHEDSTATS is not set 1072# CONFIG_SCHEDSTATS is not set
1046CONFIG_DEBUG_SLAB=y 1073CONFIG_DEBUG_SLAB=y
1074# CONFIG_DEBUG_SLAB_LEAK is not set
1047CONFIG_DEBUG_MUTEXES=y 1075CONFIG_DEBUG_MUTEXES=y
1048CONFIG_DEBUG_SPINLOCK=y 1076CONFIG_DEBUG_SPINLOCK=y
1049# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 1077# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
@@ -1053,6 +1081,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
1053# CONFIG_DEBUG_FS is not set 1081# CONFIG_DEBUG_FS is not set
1054# CONFIG_DEBUG_VM is not set 1082# CONFIG_DEBUG_VM is not set
1055CONFIG_FRAME_POINTER=y 1083CONFIG_FRAME_POINTER=y
1084# CONFIG_UNWIND_INFO is not set
1056CONFIG_FORCED_INLINING=y 1085CONFIG_FORCED_INLINING=y
1057# CONFIG_RCU_TORTURE_TEST is not set 1086# CONFIG_RCU_TORTURE_TEST is not set
1058CONFIG_DEBUG_USER=y 1087CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/ixp2000_defconfig b/arch/arm/configs/ixp2000_defconfig
index 7b02ca04c3ee..e6f3e4873d6c 100644
--- a/arch/arm/configs/ixp2000_defconfig
+++ b/arch/arm/configs/ixp2000_defconfig
@@ -1,18 +1,19 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.16-rc2 3# Linux kernel version: 2.6.17-rc2
4# Wed Feb 8 04:49:11 2006 4# Wed Apr 19 21:12:49 2006
5# 5#
6CONFIG_ARM=y 6CONFIG_ARM=y
7CONFIG_MMU=y 7CONFIG_MMU=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y 8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HWEIGHT=y
9CONFIG_GENERIC_CALIBRATE_DELAY=y 10CONFIG_GENERIC_CALIBRATE_DELAY=y
11CONFIG_VECTORS_BASE=0xffff0000
10 12
11# 13#
12# Code maturity level options 14# Code maturity level options
13# 15#
14CONFIG_EXPERIMENTAL=y 16CONFIG_EXPERIMENTAL=y
15CONFIG_CLEAN_COMPILE=y
16CONFIG_BROKEN_ON_SMP=y 17CONFIG_BROKEN_ON_SMP=y
17CONFIG_INIT_ENV_ARG_LIMIT=32 18CONFIG_INIT_ENV_ARG_LIMIT=32
18 19
@@ -29,6 +30,7 @@ CONFIG_BSD_PROCESS_ACCT=y
29CONFIG_SYSCTL=y 30CONFIG_SYSCTL=y
30# CONFIG_AUDIT is not set 31# CONFIG_AUDIT is not set
31# CONFIG_IKCONFIG is not set 32# CONFIG_IKCONFIG is not set
33# CONFIG_RELAY is not set
32CONFIG_INITRAMFS_SOURCE="" 34CONFIG_INITRAMFS_SOURCE=""
33CONFIG_UID16=y 35CONFIG_UID16=y
34CONFIG_CC_OPTIMIZE_FOR_SIZE=y 36CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -44,10 +46,6 @@ CONFIG_BASE_FULL=y
44CONFIG_FUTEX=y 46CONFIG_FUTEX=y
45CONFIG_EPOLL=y 47CONFIG_EPOLL=y
46CONFIG_SHMEM=y 48CONFIG_SHMEM=y
47CONFIG_CC_ALIGN_FUNCTIONS=0
48CONFIG_CC_ALIGN_LABELS=0
49CONFIG_CC_ALIGN_LOOPS=0
50CONFIG_CC_ALIGN_JUMPS=0
51CONFIG_SLAB=y 49CONFIG_SLAB=y
52# CONFIG_TINY_SHMEM is not set 50# CONFIG_TINY_SHMEM is not set
53CONFIG_BASE_SMALL=0 51CONFIG_BASE_SMALL=0
@@ -60,7 +58,6 @@ CONFIG_OBSOLETE_INTERMODULE=y
60CONFIG_MODULES=y 58CONFIG_MODULES=y
61CONFIG_MODULE_UNLOAD=y 59CONFIG_MODULE_UNLOAD=y
62# CONFIG_MODULE_FORCE_UNLOAD is not set 60# CONFIG_MODULE_FORCE_UNLOAD is not set
63CONFIG_OBSOLETE_MODPARM=y
64# CONFIG_MODVERSIONS is not set 61# CONFIG_MODVERSIONS is not set
65# CONFIG_MODULE_SRCVERSION_ALL is not set 62# CONFIG_MODULE_SRCVERSION_ALL is not set
66CONFIG_KMOD=y 63CONFIG_KMOD=y
@@ -68,6 +65,7 @@ CONFIG_KMOD=y
68# 65#
69# Block layer 66# Block layer
70# 67#
68# CONFIG_BLK_DEV_IO_TRACE is not set
71 69
72# 70#
73# IO Schedulers 71# IO Schedulers
@@ -89,11 +87,13 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
89# CONFIG_ARCH_CLPS711X is not set 87# CONFIG_ARCH_CLPS711X is not set
90# CONFIG_ARCH_CO285 is not set 88# CONFIG_ARCH_CO285 is not set
91# CONFIG_ARCH_EBSA110 is not set 89# CONFIG_ARCH_EBSA110 is not set
90# CONFIG_ARCH_EP93XX is not set
92# CONFIG_ARCH_FOOTBRIDGE is not set 91# CONFIG_ARCH_FOOTBRIDGE is not set
93# CONFIG_ARCH_INTEGRATOR is not set 92# CONFIG_ARCH_INTEGRATOR is not set
94# CONFIG_ARCH_IOP3XX is not set 93# CONFIG_ARCH_IOP3XX is not set
95# CONFIG_ARCH_IXP4XX is not set 94# CONFIG_ARCH_IXP4XX is not set
96CONFIG_ARCH_IXP2000=y 95CONFIG_ARCH_IXP2000=y
96# CONFIG_ARCH_IXP23XX is not set
97# CONFIG_ARCH_L7200 is not set 97# CONFIG_ARCH_L7200 is not set
98# CONFIG_ARCH_PXA is not set 98# CONFIG_ARCH_PXA is not set
99# CONFIG_ARCH_RPC is not set 99# CONFIG_ARCH_RPC is not set
@@ -123,6 +123,7 @@ CONFIG_ARCH_IXDP2800=y
123CONFIG_ARCH_IXDP2X00=y 123CONFIG_ARCH_IXDP2X00=y
124CONFIG_ARCH_IXDP2401=y 124CONFIG_ARCH_IXDP2401=y
125CONFIG_ARCH_IXDP2801=y 125CONFIG_ARCH_IXDP2801=y
126CONFIG_MACH_IXDP28X5=y
126CONFIG_ARCH_IXDP2X01=y 127CONFIG_ARCH_IXDP2X01=y
127# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set 128# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set
128 129
@@ -147,7 +148,6 @@ CONFIG_XSCALE_PMU=y
147# Bus support 148# Bus support
148# 149#
149CONFIG_PCI=y 150CONFIG_PCI=y
150CONFIG_PCI_LEGACY_PROC=y
151# CONFIG_PCI_DEBUG is not set 151# CONFIG_PCI_DEBUG is not set
152 152
153# 153#
@@ -160,6 +160,7 @@ CONFIG_PCI_LEGACY_PROC=y
160# 160#
161# CONFIG_PREEMPT is not set 161# CONFIG_PREEMPT is not set
162# CONFIG_NO_IDLE_HZ is not set 162# CONFIG_NO_IDLE_HZ is not set
163CONFIG_HZ=100
163# CONFIG_AEABI is not set 164# CONFIG_AEABI is not set
164# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set 165# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
165CONFIG_SELECT_MEMORY_MODEL=y 166CONFIG_SELECT_MEMORY_MODEL=y
@@ -213,6 +214,7 @@ CONFIG_NET=y
213# 214#
214# Networking options 215# Networking options
215# 216#
217# CONFIG_NETDEBUG is not set
216CONFIG_PACKET=y 218CONFIG_PACKET=y
217CONFIG_PACKET_MMAP=y 219CONFIG_PACKET_MMAP=y
218CONFIG_UNIX=y 220CONFIG_UNIX=y
@@ -232,12 +234,15 @@ CONFIG_SYN_COOKIES=y
232# CONFIG_INET_AH is not set 234# CONFIG_INET_AH is not set
233# CONFIG_INET_ESP is not set 235# CONFIG_INET_ESP is not set
234# CONFIG_INET_IPCOMP is not set 236# CONFIG_INET_IPCOMP is not set
237# CONFIG_INET_XFRM_TUNNEL is not set
235# CONFIG_INET_TUNNEL is not set 238# CONFIG_INET_TUNNEL is not set
236CONFIG_INET_DIAG=y 239CONFIG_INET_DIAG=y
237CONFIG_INET_TCP_DIAG=y 240CONFIG_INET_TCP_DIAG=y
238# CONFIG_TCP_CONG_ADVANCED is not set 241# CONFIG_TCP_CONG_ADVANCED is not set
239CONFIG_TCP_CONG_BIC=y 242CONFIG_TCP_CONG_BIC=y
240# CONFIG_IPV6 is not set 243# CONFIG_IPV6 is not set
244# CONFIG_INET6_XFRM_TUNNEL is not set
245# CONFIG_INET6_TUNNEL is not set
241# CONFIG_NETFILTER is not set 246# CONFIG_NETFILTER is not set
242 247
243# 248#
@@ -347,7 +352,6 @@ CONFIG_MTD_CFI_UTIL=y
347# CONFIG_MTD_ROM is not set 352# CONFIG_MTD_ROM is not set
348# CONFIG_MTD_ABSENT is not set 353# CONFIG_MTD_ABSENT is not set
349# CONFIG_MTD_OBSOLETE_CHIPS is not set 354# CONFIG_MTD_OBSOLETE_CHIPS is not set
350# CONFIG_MTD_XIP is not set
351 355
352# 356#
353# Mapping drivers for chip access 357# Mapping drivers for chip access
@@ -366,7 +370,6 @@ CONFIG_MTD_IXP2000=y
366# CONFIG_MTD_SLRAM is not set 370# CONFIG_MTD_SLRAM is not set
367# CONFIG_MTD_PHRAM is not set 371# CONFIG_MTD_PHRAM is not set
368# CONFIG_MTD_MTDRAM is not set 372# CONFIG_MTD_MTDRAM is not set
369# CONFIG_MTD_BLKMTD is not set
370# CONFIG_MTD_BLOCK2MTD is not set 373# CONFIG_MTD_BLOCK2MTD is not set
371 374
372# 375#
@@ -614,8 +617,9 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
614# 617#
615CONFIG_SERIAL_8250=y 618CONFIG_SERIAL_8250=y
616CONFIG_SERIAL_8250_CONSOLE=y 619CONFIG_SERIAL_8250_CONSOLE=y
620CONFIG_SERIAL_8250_PCI=y
617CONFIG_SERIAL_8250_NR_UARTS=3 621CONFIG_SERIAL_8250_NR_UARTS=3
618CONFIG_SERIAL_8250_RUNTIME_UARTS=4 622CONFIG_SERIAL_8250_RUNTIME_UARTS=3
619# CONFIG_SERIAL_8250_EXTENDED is not set 623# CONFIG_SERIAL_8250_EXTENDED is not set
620 624
621# 625#
@@ -623,6 +627,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
623# 627#
624CONFIG_SERIAL_CORE=y 628CONFIG_SERIAL_CORE=y
625CONFIG_SERIAL_CORE_CONSOLE=y 629CONFIG_SERIAL_CORE_CONSOLE=y
630# CONFIG_SERIAL_JSM is not set
626CONFIG_UNIX98_PTYS=y 631CONFIG_UNIX98_PTYS=y
627CONFIG_LEGACY_PTYS=y 632CONFIG_LEGACY_PTYS=y
628CONFIG_LEGACY_PTY_COUNT=256 633CONFIG_LEGACY_PTY_COUNT=256
@@ -650,7 +655,6 @@ CONFIG_IXP2000_WATCHDOG=y
650# CONFIG_PCIPCWATCHDOG is not set 655# CONFIG_PCIPCWATCHDOG is not set
651# CONFIG_WDTPCI is not set 656# CONFIG_WDTPCI is not set
652# CONFIG_NVRAM is not set 657# CONFIG_NVRAM is not set
653# CONFIG_RTC is not set
654# CONFIG_DTLK is not set 658# CONFIG_DTLK is not set
655# CONFIG_R3964 is not set 659# CONFIG_R3964 is not set
656# CONFIG_APPLICOM is not set 660# CONFIG_APPLICOM is not set
@@ -696,7 +700,6 @@ CONFIG_I2C_IXP2000=y
696# CONFIG_I2C_PARPORT_LIGHT is not set 700# CONFIG_I2C_PARPORT_LIGHT is not set
697# CONFIG_I2C_PROSAVAGE is not set 701# CONFIG_I2C_PROSAVAGE is not set
698# CONFIG_I2C_SAVAGE4 is not set 702# CONFIG_I2C_SAVAGE4 is not set
699# CONFIG_SCx200_ACB is not set
700# CONFIG_I2C_SIS5595 is not set 703# CONFIG_I2C_SIS5595 is not set
701# CONFIG_I2C_SIS630 is not set 704# CONFIG_I2C_SIS630 is not set
702# CONFIG_I2C_SIS96X is not set 705# CONFIG_I2C_SIS96X is not set
@@ -715,9 +718,7 @@ CONFIG_SENSORS_EEPROM=y
715# CONFIG_SENSORS_PCF8574 is not set 718# CONFIG_SENSORS_PCF8574 is not set
716# CONFIG_SENSORS_PCA9539 is not set 719# CONFIG_SENSORS_PCA9539 is not set
717# CONFIG_SENSORS_PCF8591 is not set 720# CONFIG_SENSORS_PCF8591 is not set
718# CONFIG_SENSORS_RTC8564 is not set
719# CONFIG_SENSORS_MAX6875 is not set 721# CONFIG_SENSORS_MAX6875 is not set
720# CONFIG_RTC_X1205_I2C is not set
721# CONFIG_I2C_DEBUG_CORE is not set 722# CONFIG_I2C_DEBUG_CORE is not set
722# CONFIG_I2C_DEBUG_ALGO is not set 723# CONFIG_I2C_DEBUG_ALGO is not set
723# CONFIG_I2C_DEBUG_BUS is not set 724# CONFIG_I2C_DEBUG_BUS is not set
@@ -730,6 +731,11 @@ CONFIG_SENSORS_EEPROM=y
730# CONFIG_SPI_MASTER is not set 731# CONFIG_SPI_MASTER is not set
731 732
732# 733#
734# Dallas's 1-wire bus
735#
736# CONFIG_W1 is not set
737
738#
733# Hardware Monitoring support 739# Hardware Monitoring support
734# 740#
735CONFIG_HWMON=y 741CONFIG_HWMON=y
@@ -742,6 +748,7 @@ CONFIG_HWMON=y
742# CONFIG_SENSORS_ASB100 is not set 748# CONFIG_SENSORS_ASB100 is not set
743# CONFIG_SENSORS_ATXP1 is not set 749# CONFIG_SENSORS_ATXP1 is not set
744# CONFIG_SENSORS_DS1621 is not set 750# CONFIG_SENSORS_DS1621 is not set
751# CONFIG_SENSORS_F71805F is not set
745# CONFIG_SENSORS_FSCHER is not set 752# CONFIG_SENSORS_FSCHER is not set
746# CONFIG_SENSORS_FSCPOS is not set 753# CONFIG_SENSORS_FSCPOS is not set
747# CONFIG_SENSORS_GL518SM is not set 754# CONFIG_SENSORS_GL518SM is not set
@@ -776,7 +783,16 @@ CONFIG_HWMON=y
776# 783#
777 784
778# 785#
779# Multimedia Capabilities Port drivers 786# LED devices
787#
788# CONFIG_NEW_LEDS is not set
789
790#
791# LED drivers
792#
793
794#
795# LED Triggers
780# 796#
781 797
782# 798#
@@ -804,6 +820,7 @@ CONFIG_HWMON=y
804# 820#
805CONFIG_USB_ARCH_HAS_HCD=y 821CONFIG_USB_ARCH_HAS_HCD=y
806CONFIG_USB_ARCH_HAS_OHCI=y 822CONFIG_USB_ARCH_HAS_OHCI=y
823CONFIG_USB_ARCH_HAS_EHCI=y
807# CONFIG_USB is not set 824# CONFIG_USB is not set
808 825
809# 826#
@@ -821,6 +838,12 @@ CONFIG_USB_ARCH_HAS_OHCI=y
821# CONFIG_MMC is not set 838# CONFIG_MMC is not set
822 839
823# 840#
841# Real Time Clock
842#
843CONFIG_RTC_LIB=y
844# CONFIG_RTC_CLASS is not set
845
846#
824# File systems 847# File systems
825# 848#
826CONFIG_EXT2_FS=y 849CONFIG_EXT2_FS=y
@@ -870,7 +893,6 @@ CONFIG_SYSFS=y
870CONFIG_TMPFS=y 893CONFIG_TMPFS=y
871# CONFIG_HUGETLB_PAGE is not set 894# CONFIG_HUGETLB_PAGE is not set
872CONFIG_RAMFS=y 895CONFIG_RAMFS=y
873# CONFIG_RELAYFS_FS is not set
874# CONFIG_CONFIGFS_FS is not set 896# CONFIG_CONFIGFS_FS is not set
875 897
876# 898#
@@ -972,6 +994,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
972# CONFIG_DEBUG_FS is not set 994# CONFIG_DEBUG_FS is not set
973# CONFIG_DEBUG_VM is not set 995# CONFIG_DEBUG_VM is not set
974CONFIG_FRAME_POINTER=y 996CONFIG_FRAME_POINTER=y
997# CONFIG_UNWIND_INFO is not set
975CONFIG_FORCED_INLINING=y 998CONFIG_FORCED_INLINING=y
976# CONFIG_RCU_TORTURE_TEST is not set 999# CONFIG_RCU_TORTURE_TEST is not set
977CONFIG_DEBUG_USER=y 1000CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/ixp23xx_defconfig b/arch/arm/configs/ixp23xx_defconfig
index 1a2751e9ab05..9ce898a6cf87 100644
--- a/arch/arm/configs/ixp23xx_defconfig
+++ b/arch/arm/configs/ixp23xx_defconfig
@@ -1,12 +1,14 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.16 3# Linux kernel version: 2.6.17-rc2
4# Tue Mar 21 03:27:20 2006 4# Wed Apr 19 21:13:50 2006
5# 5#
6CONFIG_ARM=y 6CONFIG_ARM=y
7CONFIG_MMU=y 7CONFIG_MMU=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y 8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HWEIGHT=y
9CONFIG_GENERIC_CALIBRATE_DELAY=y 10CONFIG_GENERIC_CALIBRATE_DELAY=y
11CONFIG_VECTORS_BASE=0xffff0000
10 12
11# 13#
12# Code maturity level options 14# Code maturity level options
@@ -28,6 +30,7 @@ CONFIG_BSD_PROCESS_ACCT=y
28CONFIG_SYSCTL=y 30CONFIG_SYSCTL=y
29# CONFIG_AUDIT is not set 31# CONFIG_AUDIT is not set
30# CONFIG_IKCONFIG is not set 32# CONFIG_IKCONFIG is not set
33# CONFIG_RELAY is not set
31CONFIG_INITRAMFS_SOURCE="" 34CONFIG_INITRAMFS_SOURCE=""
32CONFIG_UID16=y 35CONFIG_UID16=y
33CONFIG_CC_OPTIMIZE_FOR_SIZE=y 36CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -43,10 +46,6 @@ CONFIG_BASE_FULL=y
43CONFIG_FUTEX=y 46CONFIG_FUTEX=y
44CONFIG_EPOLL=y 47CONFIG_EPOLL=y
45CONFIG_SHMEM=y 48CONFIG_SHMEM=y
46CONFIG_CC_ALIGN_FUNCTIONS=0
47CONFIG_CC_ALIGN_LABELS=0
48CONFIG_CC_ALIGN_LOOPS=0
49CONFIG_CC_ALIGN_JUMPS=0
50CONFIG_SLAB=y 49CONFIG_SLAB=y
51# CONFIG_TINY_SHMEM is not set 50# CONFIG_TINY_SHMEM is not set
52CONFIG_BASE_SMALL=0 51CONFIG_BASE_SMALL=0
@@ -59,7 +58,6 @@ CONFIG_OBSOLETE_INTERMODULE=y
59CONFIG_MODULES=y 58CONFIG_MODULES=y
60CONFIG_MODULE_UNLOAD=y 59CONFIG_MODULE_UNLOAD=y
61# CONFIG_MODULE_FORCE_UNLOAD is not set 60# CONFIG_MODULE_FORCE_UNLOAD is not set
62CONFIG_OBSOLETE_MODPARM=y
63# CONFIG_MODVERSIONS is not set 61# CONFIG_MODVERSIONS is not set
64# CONFIG_MODULE_SRCVERSION_ALL is not set 62# CONFIG_MODULE_SRCVERSION_ALL is not set
65CONFIG_KMOD=y 63CONFIG_KMOD=y
@@ -67,6 +65,7 @@ CONFIG_KMOD=y
67# 65#
68# Block layer 66# Block layer
69# 67#
68# CONFIG_BLK_DEV_IO_TRACE is not set
70 69
71# 70#
72# IO Schedulers 71# IO Schedulers
@@ -143,7 +142,6 @@ CONFIG_CPU_BIG_ENDIAN=y
143# Bus support 142# Bus support
144# 143#
145CONFIG_PCI=y 144CONFIG_PCI=y
146CONFIG_PCI_LEGACY_PROC=y
147# CONFIG_PCI_DEBUG is not set 145# CONFIG_PCI_DEBUG is not set
148 146
149# 147#
@@ -230,12 +228,15 @@ CONFIG_SYN_COOKIES=y
230# CONFIG_INET_AH is not set 228# CONFIG_INET_AH is not set
231# CONFIG_INET_ESP is not set 229# CONFIG_INET_ESP is not set
232# CONFIG_INET_IPCOMP is not set 230# CONFIG_INET_IPCOMP is not set
231# CONFIG_INET_XFRM_TUNNEL is not set
233# CONFIG_INET_TUNNEL is not set 232# CONFIG_INET_TUNNEL is not set
234CONFIG_INET_DIAG=y 233CONFIG_INET_DIAG=y
235CONFIG_INET_TCP_DIAG=y 234CONFIG_INET_TCP_DIAG=y
236# CONFIG_TCP_CONG_ADVANCED is not set 235# CONFIG_TCP_CONG_ADVANCED is not set
237CONFIG_TCP_CONG_BIC=y 236CONFIG_TCP_CONG_BIC=y
238# CONFIG_IPV6 is not set 237# CONFIG_IPV6 is not set
238# CONFIG_INET6_XFRM_TUNNEL is not set
239# CONFIG_INET6_TUNNEL is not set
239# CONFIG_NETFILTER is not set 240# CONFIG_NETFILTER is not set
240 241
241# 242#
@@ -365,7 +366,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1
365# CONFIG_MTD_SLRAM is not set 366# CONFIG_MTD_SLRAM is not set
366# CONFIG_MTD_PHRAM is not set 367# CONFIG_MTD_PHRAM is not set
367# CONFIG_MTD_MTDRAM is not set 368# CONFIG_MTD_MTDRAM is not set
368# CONFIG_MTD_BLKMTD is not set
369# CONFIG_MTD_BLOCK2MTD is not set 369# CONFIG_MTD_BLOCK2MTD is not set
370 370
371# 371#
@@ -527,7 +527,6 @@ CONFIG_BLK_DEV_SD=y
527# CONFIG_SCSI_INIA100 is not set 527# CONFIG_SCSI_INIA100 is not set
528# CONFIG_SCSI_SYM53C8XX_2 is not set 528# CONFIG_SCSI_SYM53C8XX_2 is not set
529# CONFIG_SCSI_IPR is not set 529# CONFIG_SCSI_IPR is not set
530# CONFIG_SCSI_QLOGIC_FC is not set
531# CONFIG_SCSI_QLOGIC_1280 is not set 530# CONFIG_SCSI_QLOGIC_1280 is not set
532# CONFIG_SCSI_QLA_FC is not set 531# CONFIG_SCSI_QLA_FC is not set
533# CONFIG_SCSI_LPFC is not set 532# CONFIG_SCSI_LPFC is not set
@@ -735,6 +734,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
735# 734#
736CONFIG_SERIAL_8250=y 735CONFIG_SERIAL_8250=y
737CONFIG_SERIAL_8250_CONSOLE=y 736CONFIG_SERIAL_8250_CONSOLE=y
737CONFIG_SERIAL_8250_PCI=y
738CONFIG_SERIAL_8250_NR_UARTS=4 738CONFIG_SERIAL_8250_NR_UARTS=4
739CONFIG_SERIAL_8250_RUNTIME_UARTS=4 739CONFIG_SERIAL_8250_RUNTIME_UARTS=4
740# CONFIG_SERIAL_8250_EXTENDED is not set 740# CONFIG_SERIAL_8250_EXTENDED is not set
@@ -776,7 +776,6 @@ CONFIG_WATCHDOG=y
776# 776#
777# CONFIG_USBPCWATCHDOG is not set 777# CONFIG_USBPCWATCHDOG is not set
778# CONFIG_NVRAM is not set 778# CONFIG_NVRAM is not set
779# CONFIG_RTC is not set
780# CONFIG_DTLK is not set 779# CONFIG_DTLK is not set
781# CONFIG_R3964 is not set 780# CONFIG_R3964 is not set
782# CONFIG_APPLICOM is not set 781# CONFIG_APPLICOM is not set
@@ -821,7 +820,6 @@ CONFIG_I2C_ALGOBIT=y
821# CONFIG_I2C_PARPORT_LIGHT is not set 820# CONFIG_I2C_PARPORT_LIGHT is not set
822# CONFIG_I2C_PROSAVAGE is not set 821# CONFIG_I2C_PROSAVAGE is not set
823# CONFIG_I2C_SAVAGE4 is not set 822# CONFIG_I2C_SAVAGE4 is not set
824# CONFIG_SCx200_ACB is not set
825# CONFIG_I2C_SIS5595 is not set 823# CONFIG_I2C_SIS5595 is not set
826# CONFIG_I2C_SIS630 is not set 824# CONFIG_I2C_SIS630 is not set
827# CONFIG_I2C_SIS96X is not set 825# CONFIG_I2C_SIS96X is not set
@@ -840,9 +838,7 @@ CONFIG_SENSORS_EEPROM=y
840# CONFIG_SENSORS_PCF8574 is not set 838# CONFIG_SENSORS_PCF8574 is not set
841# CONFIG_SENSORS_PCA9539 is not set 839# CONFIG_SENSORS_PCA9539 is not set
842# CONFIG_SENSORS_PCF8591 is not set 840# CONFIG_SENSORS_PCF8591 is not set
843# CONFIG_SENSORS_RTC8564 is not set
844# CONFIG_SENSORS_MAX6875 is not set 841# CONFIG_SENSORS_MAX6875 is not set
845# CONFIG_RTC_X1205_I2C is not set
846# CONFIG_I2C_DEBUG_CORE is not set 842# CONFIG_I2C_DEBUG_CORE is not set
847# CONFIG_I2C_DEBUG_ALGO is not set 843# CONFIG_I2C_DEBUG_ALGO is not set
848# CONFIG_I2C_DEBUG_BUS is not set 844# CONFIG_I2C_DEBUG_BUS is not set
@@ -907,7 +903,16 @@ CONFIG_HWMON=y
907# 903#
908 904
909# 905#
910# Multimedia Capabilities Port drivers 906# LED devices
907#
908# CONFIG_NEW_LEDS is not set
909
910#
911# LED drivers
912#
913
914#
915# LED Triggers
911# 916#
912 917
913# 918#
@@ -919,6 +924,7 @@ CONFIG_HWMON=y
919# Digital Video Broadcasting Devices 924# Digital Video Broadcasting Devices
920# 925#
921# CONFIG_DVB is not set 926# CONFIG_DVB is not set
927# CONFIG_USB_DABUSB is not set
922 928
923# 929#
924# Graphics support 930# Graphics support
@@ -935,6 +941,7 @@ CONFIG_HWMON=y
935# 941#
936CONFIG_USB_ARCH_HAS_HCD=y 942CONFIG_USB_ARCH_HAS_HCD=y
937CONFIG_USB_ARCH_HAS_OHCI=y 943CONFIG_USB_ARCH_HAS_OHCI=y
944CONFIG_USB_ARCH_HAS_EHCI=y
938CONFIG_USB=y 945CONFIG_USB=y
939# CONFIG_USB_DEBUG is not set 946# CONFIG_USB_DEBUG is not set
940 947
@@ -1000,9 +1007,7 @@ CONFIG_USB_STORAGE=y
1000# CONFIG_USB_ACECAD is not set 1007# CONFIG_USB_ACECAD is not set
1001# CONFIG_USB_KBTAB is not set 1008# CONFIG_USB_KBTAB is not set
1002# CONFIG_USB_POWERMATE is not set 1009# CONFIG_USB_POWERMATE is not set
1003# CONFIG_USB_MTOUCH is not set 1010# CONFIG_USB_TOUCHSCREEN is not set
1004# CONFIG_USB_ITMTOUCH is not set
1005# CONFIG_USB_EGALAX is not set
1006# CONFIG_USB_YEALINK is not set 1011# CONFIG_USB_YEALINK is not set
1007# CONFIG_USB_XPAD is not set 1012# CONFIG_USB_XPAD is not set
1008# CONFIG_USB_ATI_REMOTE is not set 1013# CONFIG_USB_ATI_REMOTE is not set
@@ -1017,15 +1022,6 @@ CONFIG_USB_STORAGE=y
1017# CONFIG_USB_MICROTEK is not set 1022# CONFIG_USB_MICROTEK is not set
1018 1023
1019# 1024#
1020# USB Multimedia devices
1021#
1022# CONFIG_USB_DABUSB is not set
1023
1024#
1025# Video4Linux support is needed for USB Multimedia device support
1026#
1027
1028#
1029# USB Network Adapters 1025# USB Network Adapters
1030# 1026#
1031# CONFIG_USB_CATC is not set 1027# CONFIG_USB_CATC is not set
@@ -1076,6 +1072,12 @@ CONFIG_USB_MON=y
1076# CONFIG_MMC is not set 1072# CONFIG_MMC is not set
1077 1073
1078# 1074#
1075# Real Time Clock
1076#
1077CONFIG_RTC_LIB=y
1078# CONFIG_RTC_CLASS is not set
1079
1080#
1079# File systems 1081# File systems
1080# 1082#
1081CONFIG_EXT2_FS=y 1083CONFIG_EXT2_FS=y
@@ -1127,7 +1129,6 @@ CONFIG_SYSFS=y
1127CONFIG_TMPFS=y 1129CONFIG_TMPFS=y
1128# CONFIG_HUGETLB_PAGE is not set 1130# CONFIG_HUGETLB_PAGE is not set
1129CONFIG_RAMFS=y 1131CONFIG_RAMFS=y
1130# CONFIG_RELAYFS_FS is not set
1131# CONFIG_CONFIGFS_FS is not set 1132# CONFIG_CONFIGFS_FS is not set
1132 1133
1133# 1134#
@@ -1268,6 +1269,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
1268# CONFIG_DEBUG_FS is not set 1269# CONFIG_DEBUG_FS is not set
1269# CONFIG_DEBUG_VM is not set 1270# CONFIG_DEBUG_VM is not set
1270CONFIG_FRAME_POINTER=y 1271CONFIG_FRAME_POINTER=y
1272# CONFIG_UNWIND_INFO is not set
1271CONFIG_FORCED_INLINING=y 1273CONFIG_FORCED_INLINING=y
1272# CONFIG_RCU_TORTURE_TEST is not set 1274# CONFIG_RCU_TORTURE_TEST is not set
1273CONFIG_DEBUG_USER=y 1275CONFIG_DEBUG_USER=y
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index ee083b3f0522..c49b5d4d7fca 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -101,7 +101,6 @@ EXPORT_SYMBOL(__raw_writesl);
101 101
102 /* string / mem functions */ 102 /* string / mem functions */
103EXPORT_SYMBOL(strchr); 103EXPORT_SYMBOL(strchr);
104EXPORT_SYMBOL(strpbrk);
105EXPORT_SYMBOL(strrchr); 104EXPORT_SYMBOL(strrchr);
106EXPORT_SYMBOL(memset); 105EXPORT_SYMBOL(memset);
107EXPORT_SYMBOL(memcpy); 106EXPORT_SYMBOL(memcpy);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 437528403959..9fc9af88c60c 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -322,6 +322,12 @@ static void __init setup_processor(void)
322 sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS); 322 sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
323 sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); 323 sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
324 elf_hwcap = list->elf_hwcap; 324 elf_hwcap = list->elf_hwcap;
325#ifndef CONFIG_ARM_THUMB
326 elf_hwcap &= ~HWCAP_THUMB;
327#endif
328#ifndef CONFIG_VFP
329 elf_hwcap &= ~HWCAP_VFP;
330#endif
325 331
326 cpu_proc_init(); 332 cpu_proc_init();
327} 333}
@@ -401,7 +407,7 @@ static void __init early_initrd(char **p)
401} 407}
402__early_param("initrd=", early_initrd); 408__early_param("initrd=", early_initrd);
403 409
404static void __init add_memory(unsigned long start, unsigned long size) 410static void __init arm_add_memory(unsigned long start, unsigned long size)
405{ 411{
406 /* 412 /*
407 * Ensure that start/size are aligned to a page boundary. 413 * Ensure that start/size are aligned to a page boundary.
@@ -439,7 +445,7 @@ static void __init early_mem(char **p)
439 if (**p == '@') 445 if (**p == '@')
440 start = memparse(*p + 1, p); 446 start = memparse(*p + 1, p);
441 447
442 add_memory(start, size); 448 arm_add_memory(start, size);
443} 449}
444__early_param("mem=", early_mem); 450__early_param("mem=", early_mem);
445 451
@@ -581,7 +587,7 @@ static int __init parse_tag_mem32(const struct tag *tag)
581 tag->u.mem.start, tag->u.mem.size / 1024); 587 tag->u.mem.start, tag->u.mem.size / 1024);
582 return -EINVAL; 588 return -EINVAL;
583 } 589 }
584 add_memory(tag->u.mem.start, tag->u.mem.size); 590 arm_add_memory(tag->u.mem.start, tag->u.mem.size);
585 return 0; 591 return 0;
586} 592}
587 593
@@ -801,7 +807,7 @@ static int __init topology_init(void)
801{ 807{
802 int cpu; 808 int cpu;
803 809
804 for_each_cpu(cpu) 810 for_each_possible_cpu(cpu)
805 register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu, NULL); 811 register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu, NULL);
806 812
807 return 0; 813 return 0;
diff --git a/arch/arm/mach-at91rm9200/devices.c b/arch/arm/mach-at91rm9200/devices.c
index 1781b8f342c4..bfe47bd6e50c 100644
--- a/arch/arm/mach-at91rm9200/devices.c
+++ b/arch/arm/mach-at91rm9200/devices.c
@@ -194,13 +194,23 @@ void __init at91_add_device_eth(struct at91_eth_data *data) {}
194#if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) 194#if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE)
195static struct at91_cf_data cf_data; 195static struct at91_cf_data cf_data;
196 196
197static struct resource at91_cf_resources[] = {
198 [0] = {
199 .start = AT91_CF_BASE,
200 /* ties up CS4, CS5, and CS6 */
201 .end = AT91_CF_BASE + (0x30000000 - 1),
202 .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT,
203 },
204};
205
197static struct platform_device at91rm9200_cf_device = { 206static struct platform_device at91rm9200_cf_device = {
198 .name = "at91_cf", 207 .name = "at91_cf",
199 .id = -1, 208 .id = -1,
200 .dev = { 209 .dev = {
201 .platform_data = &cf_data, 210 .platform_data = &cf_data,
202 }, 211 },
203 .num_resources = 0, 212 .resource = at91_cf_resources,
213 .num_resources = ARRAY_SIZE(at91_cf_resources),
204}; 214};
205 215
206void __init at91_add_device_cf(struct at91_cf_data *data) 216void __init at91_add_device_cf(struct at91_cf_data *data)
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index a0888e160e3b..00b761ff0f9c 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -91,7 +91,7 @@ static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type);
91/* 91/*
92 * IRQ -> GPIO mapping table 92 * IRQ -> GPIO mapping table
93 */ 93 */
94static char irq2gpio[32] = { 94static signed char irq2gpio[32] = {
95 -1, -1, -1, -1, -1, -1, 0, 1, 95 -1, -1, -1, -1, -1, -1, 0, 1,
96 -1, -1, -1, -1, -1, -1, -1, -1, 96 -1, -1, -1, -1, -1, -1, -1, -1,
97 -1, -1, -1, 2, 3, 4, 5, 6, 97 -1, -1, -1, 2, 3, 4, 5, 6,
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 876c38da14f7..847329cafc5c 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -25,10 +25,6 @@
25#include <asm/arch/mux.h> 25#include <asm/arch/mux.h>
26#include <asm/arch/gpio.h> 26#include <asm/arch/gpio.h>
27 27
28extern void omap_nop_release(struct device *dev);
29
30/*-------------------------------------------------------------------------*/
31
32#if defined(CONFIG_OMAP1610_IR) || defined(CONFIG_OMAP161O_IR_MODULE) 28#if defined(CONFIG_OMAP1610_IR) || defined(CONFIG_OMAP161O_IR_MODULE)
33 29
34static u64 irda_dmamask = 0xffffffff; 30static u64 irda_dmamask = 0xffffffff;
@@ -37,7 +33,6 @@ static struct platform_device omap1610ir_device = {
37 .name = "omap1610-ir", 33 .name = "omap1610-ir",
38 .id = -1, 34 .id = -1,
39 .dev = { 35 .dev = {
40 .release = omap_nop_release,
41 .dma_mask = &irda_dmamask, 36 .dma_mask = &irda_dmamask,
42 }, 37 },
43}; 38};
@@ -84,9 +79,6 @@ static struct resource rtc_resources[] = {
84static struct platform_device omap_rtc_device = { 79static struct platform_device omap_rtc_device = {
85 .name = "omap_rtc", 80 .name = "omap_rtc",
86 .id = -1, 81 .id = -1,
87 .dev = {
88 .release = omap_nop_release,
89 },
90 .num_resources = ARRAY_SIZE(rtc_resources), 82 .num_resources = ARRAY_SIZE(rtc_resources),
91 .resource = rtc_resources, 83 .resource = rtc_resources,
92}; 84};
@@ -124,9 +116,6 @@ static struct resource sti_resources[] = {
124static struct platform_device sti_device = { 116static struct platform_device sti_device = {
125 .name = "sti", 117 .name = "sti",
126 .id = -1, 118 .id = -1,
127 .dev = {
128 .release = omap_nop_release,
129 },
130 .num_resources = ARRAY_SIZE(sti_resources), 119 .num_resources = ARRAY_SIZE(sti_resources),
131 .resource = sti_resources, 120 .resource = sti_resources,
132}; 121};
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index def9e5370edf..fb7f91da1aad 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -25,10 +25,6 @@
25#include <asm/arch/mux.h> 25#include <asm/arch/mux.h>
26#include <asm/arch/gpio.h> 26#include <asm/arch/gpio.h>
27 27
28extern void omap_nop_release(struct device *dev);
29
30/*-------------------------------------------------------------------------*/
31
32#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) 28#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
33 29
34#define OMAP2_I2C_BASE2 0x48072000 30#define OMAP2_I2C_BASE2 0x48072000
@@ -49,9 +45,6 @@ static struct resource i2c_resources2[] = {
49static struct platform_device omap_i2c_device2 = { 45static struct platform_device omap_i2c_device2 = {
50 .name = "i2c_omap", 46 .name = "i2c_omap",
51 .id = 2, 47 .id = 2,
52 .dev = {
53 .release = omap_nop_release,
54 },
55 .num_resources = ARRAY_SIZE(i2c_resources2), 48 .num_resources = ARRAY_SIZE(i2c_resources2),
56 .resource = i2c_resources2, 49 .resource = i2c_resources2,
57}; 50};
@@ -100,9 +93,6 @@ static struct resource sti_resources[] = {
100static struct platform_device sti_device = { 93static struct platform_device sti_device = {
101 .name = "sti", 94 .name = "sti",
102 .id = -1, 95 .id = -1,
103 .dev = {
104 .release = omap_nop_release,
105 },
106 .num_resources = ARRAY_SIZE(sti_resources), 96 .num_resources = ARRAY_SIZE(sti_resources),
107 .resource = sti_resources, 97 .resource = sti_resources,
108}; 98};
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
index b371d723635f..8a25a1c8019f 100644
--- a/arch/arm/mach-pxa/corgi_ssp.c
+++ b/arch/arm/mach-pxa/corgi_ssp.c
@@ -196,12 +196,9 @@ static int __init corgi_ssp_probe(struct platform_device *dev)
196 int ret; 196 int ret;
197 197
198 /* Chip Select - Disable All */ 198 /* Chip Select - Disable All */
199 GPDR(ssp_machinfo->cs_lcdcon) |= GPIO_bit(ssp_machinfo->cs_lcdcon); /* output */ 199 pxa_gpio_mode(ssp_machinfo->cs_lcdcon | GPIO_OUT | GPIO_DFLT_HIGH);
200 GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); /* High - Disable LCD Control/Timing Gen */ 200 pxa_gpio_mode(ssp_machinfo->cs_max1111 | GPIO_OUT | GPIO_DFLT_HIGH);
201 GPDR(ssp_machinfo->cs_max1111) |= GPIO_bit(ssp_machinfo->cs_max1111); /* output */ 201 pxa_gpio_mode(ssp_machinfo->cs_ads7846 | GPIO_OUT | GPIO_DFLT_HIGH);
202 GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
203 GPDR(ssp_machinfo->cs_ads7846) |= GPIO_bit(ssp_machinfo->cs_ads7846); /* output */
204 GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
205 202
206 ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0); 203 ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0);
207 204
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index b7f85e6d6b76..6de713ad319a 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -367,6 +367,8 @@ static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
367 source = S3C2410_MISCCR_CLK0_UPLL; 367 source = S3C2410_MISCCR_CLK0_UPLL;
368 else if (parent == &clk_f) 368 else if (parent == &clk_f)
369 source = S3C2410_MISCCR_CLK0_FCLK; 369 source = S3C2410_MISCCR_CLK0_FCLK;
370 else if (parent == &clk_h)
371 source = S3C2410_MISCCR_CLK0_HCLK;
370 else if (parent == &clk_p) 372 else if (parent == &clk_p)
371 source = S3C2410_MISCCR_CLK0_PCLK; 373 source = S3C2410_MISCCR_CLK0_PCLK;
372 else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0) 374 else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0)
@@ -376,6 +378,8 @@ static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
376 else 378 else
377 return -EINVAL; 379 return -EINVAL;
378 380
381 clk->parent = parent;
382
379 if (clk == &s3c24xx_dclk0) 383 if (clk == &s3c24xx_dclk0)
380 mask = S3C2410_MISCCR_CLK0_MASK; 384 mask = S3C2410_MISCCR_CLK0_MASK;
381 else { 385 else {
diff --git a/arch/arm/mach-s3c2410/common-smdk.c b/arch/arm/mach-s3c2410/common-smdk.c
index 36b8291b5e03..c940890f621f 100644
--- a/arch/arm/mach-s3c2410/common-smdk.c
+++ b/arch/arm/mach-s3c2410/common-smdk.c
@@ -37,6 +37,7 @@
37 37
38#include <asm/arch/nand.h> 38#include <asm/arch/nand.h>
39 39
40#include "common-smdk.h"
40#include "devs.h" 41#include "devs.h"
41#include "pm.h" 42#include "pm.h"
42 43
@@ -49,7 +50,7 @@ static struct mtd_partition smdk_default_nand_part[] = {
49 .offset = 0, 50 .offset = 0,
50 }, 51 },
51 [1] = { 52 [1] = {
52 .name = "S3C2410 flash parition 1", 53 .name = "S3C2410 flash partition 1",
53 .offset = 0, 54 .offset = 0,
54 .size = SZ_2M, 55 .size = SZ_2M,
55 }, 56 },
diff --git a/arch/arm/mach-s3c2410/s3c2440-clock.c b/arch/arm/mach-s3c2410/s3c2440-clock.c
index 57a15974d4b5..d7a30ed6c327 100644
--- a/arch/arm/mach-s3c2410/s3c2440-clock.c
+++ b/arch/arm/mach-s3c2410/s3c2440-clock.c
@@ -139,7 +139,7 @@ static int s3c2440_clk_add(struct sys_device *sysdev)
139 139
140 clkdivn = __raw_readl(S3C2410_CLKDIVN); 140 clkdivn = __raw_readl(S3C2410_CLKDIVN);
141 clkdivn |= S3C2440_CLKDIVN_UCLK; 141 clkdivn |= S3C2440_CLKDIVN_UCLK;
142 __raw_writel(camdivn, S3C2410_CLKDIVN); 142 __raw_writel(clkdivn, S3C2410_CLKDIVN);
143 143
144 mutex_unlock(&clocks_mutex); 144 mutex_unlock(&clocks_mutex);
145 } 145 }
diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S
index 5c4055b62d97..54e3c5bb5186 100644
--- a/arch/arm/mm/cache-v4wb.S
+++ b/arch/arm/mm/cache-v4wb.S
@@ -10,7 +10,7 @@
10#include <linux/config.h> 10#include <linux/config.h>
11#include <linux/linkage.h> 11#include <linux/linkage.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <asm/hardware.h> 13#include <asm/memory.h>
14#include <asm/page.h> 14#include <asm/page.h>
15#include "proc-macros.S" 15#include "proc-macros.S"
16 16
@@ -46,6 +46,11 @@
46 */ 46 */
47#define CACHE_DLIMIT (CACHE_DSIZE * 4) 47#define CACHE_DLIMIT (CACHE_DSIZE * 4)
48 48
49 .data
50flush_base:
51 .long FLUSH_BASE
52 .text
53
49/* 54/*
50 * flush_user_cache_all() 55 * flush_user_cache_all()
51 * 56 *
@@ -63,11 +68,21 @@ ENTRY(v4wb_flush_kern_cache_all)
63 mov ip, #0 68 mov ip, #0
64 mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache 69 mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
65__flush_whole_cache: 70__flush_whole_cache:
66 mov r0, #FLUSH_BASE 71 ldr r3, =flush_base
67 add r1, r0, #CACHE_DSIZE 72 ldr r1, [r3, #0]
681: ldr r2, [r0], #32 73 eor r1, r1, #CACHE_DSIZE
69 cmp r0, r1 74 str r1, [r3, #0]
75 add r2, r1, #CACHE_DSIZE
761: ldr r3, [r1], #32
77 cmp r1, r2
78 blo 1b
79#ifdef FLUSH_BASE_MINICACHE
80 add r2, r2, #FLUSH_BASE_MINICACHE - FLUSH_BASE
81 sub r1, r2, #512 @ only 512 bytes
821: ldr r3, [r1], #32
83 cmp r1, r2
70 blo 1b 84 blo 1b
85#endif
71 mcr p15, 0, ip, c7, c10, 4 @ drain write buffer 86 mcr p15, 0, ip, c7, c10, 4 @ drain write buffer
72 mov pc, lr 87 mov pc, lr
73 88
@@ -82,6 +97,7 @@ __flush_whole_cache:
82 * - flags - vma_area_struct flags describing address space 97 * - flags - vma_area_struct flags describing address space
83 */ 98 */
84ENTRY(v4wb_flush_user_cache_range) 99ENTRY(v4wb_flush_user_cache_range)
100 mov ip, #0
85 sub r3, r1, r0 @ calculate total size 101 sub r3, r1, r0 @ calculate total size
86 tst r2, #VM_EXEC @ executable region? 102 tst r2, #VM_EXEC @ executable region?
87 mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache 103 mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 88279124317a..9ea1f87a7079 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -20,6 +20,7 @@
20 20
21#include <asm/mach-types.h> 21#include <asm/mach-types.h>
22#include <asm/setup.h> 22#include <asm/setup.h>
23#include <asm/sizes.h>
23#include <asm/tlb.h> 24#include <asm/tlb.h>
24 25
25#include <asm/mach/arch.h> 26#include <asm/mach/arch.h>
@@ -455,14 +456,14 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
455#ifdef FLUSH_BASE 456#ifdef FLUSH_BASE
456 map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS); 457 map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS);
457 map.virtual = FLUSH_BASE; 458 map.virtual = FLUSH_BASE;
458 map.length = PGDIR_SIZE; 459 map.length = SZ_1M;
459 map.type = MT_CACHECLEAN; 460 map.type = MT_CACHECLEAN;
460 create_mapping(&map); 461 create_mapping(&map);
461#endif 462#endif
462#ifdef FLUSH_BASE_MINICACHE 463#ifdef FLUSH_BASE_MINICACHE
463 map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + PGDIR_SIZE); 464 map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + SZ_1M);
464 map.virtual = FLUSH_BASE_MINICACHE; 465 map.virtual = FLUSH_BASE_MINICACHE;
465 map.length = PGDIR_SIZE; 466 map.length = SZ_1M;
466 map.type = MT_MINICLEAN; 467 map.type = MT_MINICLEAN;
467 create_mapping(&map); 468 create_mapping(&map);
468#endif 469#endif
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index c916a6cae404..a2dd5ae1077d 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -26,22 +26,7 @@
26 * the cache line size of the I and D cache 26 * the cache line size of the I and D cache
27 */ 27 */
28#define DCACHELINESIZE 32 28#define DCACHELINESIZE 32
29#define FLUSH_OFFSET 32768
30 29
31 .macro flush_110_dcache rd, ra, re
32 ldr \rd, =flush_base
33 ldr \ra, [\rd]
34 eor \ra, \ra, #FLUSH_OFFSET
35 str \ra, [\rd]
36 add \re, \ra, #16384 @ only necessary for 16k
371001: ldr \rd, [\ra], #DCACHELINESIZE
38 teq \re, \ra
39 bne 1001b
40 .endm
41
42 .data
43flush_base:
44 .long FLUSH_BASE
45 .text 30 .text
46 31
47/* 32/*
@@ -145,13 +130,11 @@ ENTRY(cpu_sa110_dcache_clean_area)
145 */ 130 */
146 .align 5 131 .align 5
147ENTRY(cpu_sa110_switch_mm) 132ENTRY(cpu_sa110_switch_mm)
148 flush_110_dcache r3, ip, r1 133 str lr, [sp, #-4]!
149 mov r1, #0 134 bl v4wb_flush_kern_cache_all @ clears IP
150 mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache
151 mcr p15, 0, r1, c7, c10, 4 @ drain WB
152 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer 135 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
153 mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs 136 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
154 mov pc, lr 137 ldr pc, [sp], #4
155 138
156/* 139/*
157 * cpu_sa110_set_pte(ptep, pte) 140 * cpu_sa110_set_pte(ptep, pte)
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 41f21f2dd8ff..777ad99c1439 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -30,30 +30,6 @@
30 * the cache line size of the I and D cache 30 * the cache line size of the I and D cache
31 */ 31 */
32#define DCACHELINESIZE 32 32#define DCACHELINESIZE 32
33#define FLUSH_OFFSET 32768
34
35 .macro flush_1100_dcache rd, ra, re
36 ldr \rd, =flush_base
37 ldr \ra, [\rd]
38 eor \ra, \ra, #FLUSH_OFFSET
39 str \ra, [\rd]
40 add \re, \ra, #8192 @ only necessary for 8k
411001: ldr \rd, [\ra], #DCACHELINESIZE
42 teq \re, \ra
43 bne 1001b
44#ifdef FLUSH_BASE_MINICACHE
45 add \ra, \ra, #FLUSH_BASE_MINICACHE - FLUSH_BASE
46 add \re, \ra, #512 @ only 512 bytes
471002: ldr \rd, [\ra], #DCACHELINESIZE
48 teq \re, \ra
49 bne 1002b
50#endif
51 .endm
52
53 .data
54flush_base:
55 .long FLUSH_BASE
56 .text
57 33
58 __INIT 34 __INIT
59 35
@@ -79,9 +55,8 @@ ENTRY(cpu_sa1100_proc_fin)
79 stmfd sp!, {lr} 55 stmfd sp!, {lr}
80 mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE 56 mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
81 msr cpsr_c, ip 57 msr cpsr_c, ip
82 flush_1100_dcache r0, r1, r2 @ clean caches 58 bl v4wb_flush_kern_cache_all
83 mov r0, #0 59 mcr p15, 0, ip, c15, c2, 2 @ Disable clock switching
84 mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching
85 mrc p15, 0, r0, c1, c0, 0 @ ctrl register 60 mrc p15, 0, r0, c1, c0, 0 @ ctrl register
86 bic r0, r0, #0x1000 @ ...i............ 61 bic r0, r0, #0x1000 @ ...i............
87 bic r0, r0, #0x000e @ ............wca. 62 bic r0, r0, #0x000e @ ............wca.
@@ -167,14 +142,12 @@ ENTRY(cpu_sa1100_dcache_clean_area)
167 */ 142 */
168 .align 5 143 .align 5
169ENTRY(cpu_sa1100_switch_mm) 144ENTRY(cpu_sa1100_switch_mm)
170 flush_1100_dcache r3, ip, r1 145 str lr, [sp, #-4]!
171 mov ip, #0 146 bl v4wb_flush_kern_cache_all @ clears IP
172 mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
173 mcr p15, 0, ip, c9, c0, 0 @ invalidate RB 147 mcr p15, 0, ip, c9, c0, 0 @ invalidate RB
174 mcr p15, 0, ip, c7, c10, 4 @ drain WB
175 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer 148 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
176 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs 149 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
177 mov pc, lr 150 ldr pc, [sp], #4
178 151
179/* 152/*
180 * cpu_sa1100_set_pte(ptep, pte) 153 * cpu_sa1100_set_pte(ptep, pte)
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 06485c193ee3..32ec04c58bcd 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -58,7 +58,7 @@ struct clk * clk_get(struct device *dev, const char *id)
58 if (p->id == idno && 58 if (p->id == idno &&
59 strcmp(id, p->name) == 0 && try_module_get(p->owner)) { 59 strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
60 clk = p; 60 clk = p;
61 break; 61 goto found;
62 } 62 }
63 } 63 }
64 64
@@ -69,6 +69,7 @@ struct clk * clk_get(struct device *dev, const char *id)
69 } 69 }
70 } 70 }
71 71
72found:
72 mutex_unlock(&clocks_mutex); 73 mutex_unlock(&clocks_mutex);
73 74
74 return clk; 75 return clk;
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 079b67deac0f..5d5d6eb222dd 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -26,14 +26,6 @@
26#include <asm/arch/gpio.h> 26#include <asm/arch/gpio.h>
27#include <asm/arch/menelaus.h> 27#include <asm/arch/menelaus.h>
28 28
29
30void omap_nop_release(struct device *dev)
31{
32 /* Nothing */
33}
34
35/*-------------------------------------------------------------------------*/
36
37#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) 29#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
38 30
39#define OMAP1_I2C_BASE 0xfffb3800 31#define OMAP1_I2C_BASE 0xfffb3800
@@ -59,9 +51,6 @@ static struct resource i2c_resources1[] = {
59static struct platform_device omap_i2c_device1 = { 51static struct platform_device omap_i2c_device1 = {
60 .name = "i2c_omap", 52 .name = "i2c_omap",
61 .id = 1, 53 .id = 1,
62 .dev = {
63 .release = omap_nop_release,
64 },
65 .num_resources = ARRAY_SIZE(i2c_resources1), 54 .num_resources = ARRAY_SIZE(i2c_resources1),
66 .resource = i2c_resources1, 55 .resource = i2c_resources1,
67}; 56};
@@ -187,7 +176,6 @@ static struct platform_device mmc_omap_device1 = {
187 .name = "mmci-omap", 176 .name = "mmci-omap",
188 .id = 1, 177 .id = 1,
189 .dev = { 178 .dev = {
190 .release = omap_nop_release,
191 .dma_mask = &mmc1_dmamask, 179 .dma_mask = &mmc1_dmamask,
192 .platform_data = &mmc1_conf, 180 .platform_data = &mmc1_conf,
193 }, 181 },
@@ -217,7 +205,6 @@ static struct platform_device mmc_omap_device2 = {
217 .name = "mmci-omap", 205 .name = "mmci-omap",
218 .id = 2, 206 .id = 2,
219 .dev = { 207 .dev = {
220 .release = omap_nop_release,
221 .dma_mask = &mmc2_dmamask, 208 .dma_mask = &mmc2_dmamask,
222 .platform_data = &mmc2_conf, 209 .platform_data = &mmc2_conf,
223 }, 210 },
@@ -321,9 +308,6 @@ static struct resource uwire_resources[] = {
321static struct platform_device omap_uwire_device = { 308static struct platform_device omap_uwire_device = {
322 .name = "omap_uwire", 309 .name = "omap_uwire",
323 .id = -1, 310 .id = -1,
324 .dev = {
325 .release = omap_nop_release,
326 },
327 .num_resources = ARRAY_SIZE(uwire_resources), 311 .num_resources = ARRAY_SIZE(uwire_resources),
328 .resource = uwire_resources, 312 .resource = uwire_resources,
329}; 313};
@@ -365,9 +349,6 @@ static struct resource wdt_resources[] = {
365static struct platform_device omap_wdt_device = { 349static struct platform_device omap_wdt_device = {
366 .name = "omap_wdt", 350 .name = "omap_wdt",
367 .id = -1, 351 .id = -1,
368 .dev = {
369 .release = omap_nop_release,
370 },
371 .num_resources = ARRAY_SIZE(wdt_resources), 352 .num_resources = ARRAY_SIZE(wdt_resources),
372 .resource = wdt_resources, 353 .resource = wdt_resources,
373}; 354};
@@ -401,9 +382,6 @@ static struct resource rng_resources[] = {
401static struct platform_device omap_rng_device = { 382static struct platform_device omap_rng_device = {
402 .name = "omap_rng", 383 .name = "omap_rng",
403 .id = -1, 384 .id = -1,
404 .dev = {
405 .release = omap_nop_release,
406 },
407 .num_resources = ARRAY_SIZE(rng_resources), 385 .num_resources = ARRAY_SIZE(rng_resources),
408 .resource = rng_resources, 386 .resource = rng_resources,
409}; 387};
diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c
index 9b367a65cb4d..febd115dba28 100644
--- a/arch/arm/vfp/vfpdouble.c
+++ b/arch/arm/vfp/vfpdouble.c
@@ -588,6 +588,7 @@ static u32 vfp_double_ftosi(int sd, int unused, int dm, u32 fpscr)
588 struct vfp_double vdm; 588 struct vfp_double vdm;
589 u32 d, exceptions = 0; 589 u32 d, exceptions = 0;
590 int rmode = fpscr & FPSCR_RMODE_MASK; 590 int rmode = fpscr & FPSCR_RMODE_MASK;
591 int tm;
591 592
592 vfp_double_unpack(&vdm, vfp_get_double(dm)); 593 vfp_double_unpack(&vdm, vfp_get_double(dm));
593 vfp_double_dump("VDM", &vdm); 594 vfp_double_dump("VDM", &vdm);
@@ -595,10 +596,14 @@ static u32 vfp_double_ftosi(int sd, int unused, int dm, u32 fpscr)
595 /* 596 /*
596 * Do we have denormalised number? 597 * Do we have denormalised number?
597 */ 598 */
598 if (vfp_double_type(&vdm) & VFP_DENORMAL) 599 tm = vfp_double_type(&vdm);
600 if (tm & VFP_DENORMAL)
599 exceptions |= FPSCR_IDC; 601 exceptions |= FPSCR_IDC;
600 602
601 if (vdm.exponent >= 1023 + 32) { 603 if (tm & VFP_NAN) {
604 d = 0;
605 exceptions |= FPSCR_IOC;
606 } else if (vdm.exponent >= 1023 + 32) {
602 d = 0x7fffffff; 607 d = 0x7fffffff;
603 if (vdm.sign) 608 if (vdm.sign)
604 d = ~d; 609 d = ~d;
@@ -1122,9 +1127,9 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr)
1122{ 1127{
1123 u32 op = inst & FOP_MASK; 1128 u32 op = inst & FOP_MASK;
1124 u32 exceptions = 0; 1129 u32 exceptions = 0;
1125 unsigned int dd = vfp_get_sd(inst); 1130 unsigned int dd = vfp_get_dd(inst);
1126 unsigned int dn = vfp_get_sn(inst); 1131 unsigned int dn = vfp_get_dn(inst);
1127 unsigned int dm = vfp_get_sm(inst); 1132 unsigned int dm = vfp_get_dm(inst);
1128 unsigned int vecitr, veclen, vecstride; 1133 unsigned int vecitr, veclen, vecstride;
1129 u32 (*fop)(int, int, s32, u32); 1134 u32 (*fop)(int, int, s32, u32);
1130 1135
@@ -1141,7 +1146,7 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr)
1141 pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, 1146 pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride,
1142 (veclen >> FPSCR_LENGTH_BIT) + 1); 1147 (veclen >> FPSCR_LENGTH_BIT) + 1);
1143 1148
1144 fop = (op == FOP_EXT) ? fop_extfns[dn] : fop_fns[FOP_TO_IDX(op)]; 1149 fop = (op == FOP_EXT) ? fop_extfns[FEXT_TO_IDX(inst)] : fop_fns[FOP_TO_IDX(op)];
1145 if (!fop) 1150 if (!fop)
1146 goto invalid; 1151 goto invalid;
1147 1152
@@ -1149,17 +1154,13 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr)
1149 u32 except; 1154 u32 except;
1150 1155
1151 if (op == FOP_EXT) 1156 if (op == FOP_EXT)
1152 pr_debug("VFP: itr%d (d%u.%u) = op[%u] (d%u.%u)\n", 1157 pr_debug("VFP: itr%d (d%u) = op[%u] (d%u)\n",
1153 vecitr >> FPSCR_LENGTH_BIT, 1158 vecitr >> FPSCR_LENGTH_BIT,
1154 dd >> 1, dd & 1, dn, 1159 dd, dn, dm);
1155 dm >> 1, dm & 1);
1156 else 1160 else
1157 pr_debug("VFP: itr%d (d%u.%u) = (d%u.%u) op[%u] (d%u.%u)\n", 1161 pr_debug("VFP: itr%d (d%u) = (d%u) op[%u] (d%u)\n",
1158 vecitr >> FPSCR_LENGTH_BIT, 1162 vecitr >> FPSCR_LENGTH_BIT,
1159 dd >> 1, dd & 1, 1163 dd, dn, FOP_TO_IDX(op), dm);
1160 dn >> 1, dn & 1,
1161 FOP_TO_IDX(op),
1162 dm >> 1, dm & 1);
1163 1164
1164 except = fop(dd, dn, dm, fpscr); 1165 except = fop(dd, dn, dm, fpscr);
1165 pr_debug("VFP: itr%d: exceptions=%08x\n", 1166 pr_debug("VFP: itr%d: exceptions=%08x\n",
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
index b7ed57e00cd4..a3f65b47aea9 100644
--- a/arch/arm/vfp/vfphw.S
+++ b/arch/arm/vfp/vfphw.S
@@ -189,11 +189,10 @@ vfp_put_float:
189 189
190 .globl vfp_get_double 190 .globl vfp_get_double
191vfp_get_double: 191vfp_get_double:
192 mov r0, r0, lsr #1
193 add pc, pc, r0, lsl #3 192 add pc, pc, r0, lsl #3
194 mov r0, r0 193 mov r0, r0
195 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 194 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
196 mrrc p10, 1, r0, r1, c\dr @ fmrrd r0, r1, d\dr 195 mrrc p11, 1, r0, r1, c\dr @ fmrrd r0, r1, d\dr
197 mov pc, lr 196 mov pc, lr
198 .endr 197 .endr
199 198
@@ -204,10 +203,9 @@ vfp_get_double:
204 203
205 .globl vfp_put_double 204 .globl vfp_put_double
206vfp_put_double: 205vfp_put_double:
207 mov r0, r0, lsr #1
208 add pc, pc, r0, lsl #3 206 add pc, pc, r0, lsl #3
209 mov r0, r0 207 mov r0, r0
210 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 208 .irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
211 mcrr p10, 1, r1, r2, c\dr @ fmrrd r1, r2, d\dr 209 mcrr p11, 1, r1, r2, c\dr @ fmdrr r1, r2, d\dr
212 mov pc, lr 210 mov pc, lr
213 .endr 211 .endr
diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c
index 14dd696ddeb1..4ac27f193934 100644
--- a/arch/arm/vfp/vfpsingle.c
+++ b/arch/arm/vfp/vfpsingle.c
@@ -632,6 +632,7 @@ static u32 vfp_single_ftosi(int sd, int unused, s32 m, u32 fpscr)
632 struct vfp_single vsm; 632 struct vfp_single vsm;
633 u32 d, exceptions = 0; 633 u32 d, exceptions = 0;
634 int rmode = fpscr & FPSCR_RMODE_MASK; 634 int rmode = fpscr & FPSCR_RMODE_MASK;
635 int tm;
635 636
636 vfp_single_unpack(&vsm, m); 637 vfp_single_unpack(&vsm, m);
637 vfp_single_dump("VSM", &vsm); 638 vfp_single_dump("VSM", &vsm);
@@ -639,10 +640,14 @@ static u32 vfp_single_ftosi(int sd, int unused, s32 m, u32 fpscr)
639 /* 640 /*
640 * Do we have a denormalised number? 641 * Do we have a denormalised number?
641 */ 642 */
643 tm = vfp_single_type(&vsm);
642 if (vfp_single_type(&vsm) & VFP_DENORMAL) 644 if (vfp_single_type(&vsm) & VFP_DENORMAL)
643 exceptions |= FPSCR_IDC; 645 exceptions |= FPSCR_IDC;
644 646
645 if (vsm.exponent >= 127 + 32) { 647 if (tm & VFP_NAN) {
648 d = 0;
649 exceptions |= FPSCR_IOC;
650 } else if (vsm.exponent >= 127 + 32) {
646 /* 651 /*
647 * m >= 2^31-2^7: invalid 652 * m >= 2^31-2^7: invalid
648 */ 653 */
@@ -1188,7 +1193,7 @@ u32 vfp_single_cpdo(u32 inst, u32 fpscr)
1188 pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, 1193 pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride,
1189 (veclen >> FPSCR_LENGTH_BIT) + 1); 1194 (veclen >> FPSCR_LENGTH_BIT) + 1);
1190 1195
1191 fop = (op == FOP_EXT) ? fop_extfns[sn] : fop_fns[FOP_TO_IDX(op)]; 1196 fop = (op == FOP_EXT) ? fop_extfns[FEXT_TO_IDX(inst)] : fop_fns[FOP_TO_IDX(op)];
1192 if (!fop) 1197 if (!fop)
1193 goto invalid; 1198 goto invalid;
1194 1199
diff --git a/arch/arm26/kernel/armksyms.c b/arch/arm26/kernel/armksyms.c
index a6a1b3373444..9d66c27f2724 100644
--- a/arch/arm26/kernel/armksyms.c
+++ b/arch/arm26/kernel/armksyms.c
@@ -152,7 +152,6 @@ EXPORT_SYMBOL(strncmp);
152EXPORT_SYMBOL(strchr); 152EXPORT_SYMBOL(strchr);
153EXPORT_SYMBOL(strlen); 153EXPORT_SYMBOL(strlen);
154EXPORT_SYMBOL(strnlen); 154EXPORT_SYMBOL(strnlen);
155EXPORT_SYMBOL(strpbrk);
156EXPORT_SYMBOL(strrchr); 155EXPORT_SYMBOL(strrchr);
157EXPORT_SYMBOL(strstr); 156EXPORT_SYMBOL(strstr);
158EXPORT_SYMBOL(memset); 157EXPORT_SYMBOL(memset);
diff --git a/arch/cris/kernel/crisksyms.c b/arch/cris/kernel/crisksyms.c
index de39725da920..d57859053ce7 100644
--- a/arch/cris/kernel/crisksyms.c
+++ b/arch/cris/kernel/crisksyms.c
@@ -39,7 +39,6 @@ EXPORT_SYMBOL(loops_per_usec);
39/* String functions */ 39/* String functions */
40EXPORT_SYMBOL(memcmp); 40EXPORT_SYMBOL(memcmp);
41EXPORT_SYMBOL(memmove); 41EXPORT_SYMBOL(memmove);
42EXPORT_SYMBOL(strpbrk);
43EXPORT_SYMBOL(strstr); 42EXPORT_SYMBOL(strstr);
44EXPORT_SYMBOL(strcpy); 43EXPORT_SYMBOL(strcpy);
45EXPORT_SYMBOL(strchr); 44EXPORT_SYMBOL(strchr);
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
index 1d21c8d34d8a..a9b59527a741 100644
--- a/arch/frv/kernel/entry.S
+++ b/arch/frv/kernel/entry.S
@@ -1170,12 +1170,6 @@ __syscall_badsys:
1170# syscall vector table 1170# syscall vector table
1171# 1171#
1172############################################################################### 1172###############################################################################
1173#ifdef CONFIG_MMU
1174#define __MMU(X) X
1175#else
1176#define __MMU(X) sys_ni_syscall
1177#endif
1178
1179 .section .rodata 1173 .section .rodata
1180ALIGN 1174ALIGN
1181 .globl sys_call_table 1175 .globl sys_call_table
@@ -1305,7 +1299,7 @@ sys_call_table:
1305 .long sys_newuname 1299 .long sys_newuname
1306 .long sys_ni_syscall /* old "cacheflush" */ 1300 .long sys_ni_syscall /* old "cacheflush" */
1307 .long sys_adjtimex 1301 .long sys_adjtimex
1308 .long __MMU(sys_mprotect) /* 125 */ 1302 .long sys_mprotect /* 125 */
1309 .long sys_sigprocmask 1303 .long sys_sigprocmask
1310 .long sys_ni_syscall /* old "create_module" */ 1304 .long sys_ni_syscall /* old "create_module" */
1311 .long sys_init_module 1305 .long sys_init_module
@@ -1324,16 +1318,16 @@ sys_call_table:
1324 .long sys_getdents 1318 .long sys_getdents
1325 .long sys_select 1319 .long sys_select
1326 .long sys_flock 1320 .long sys_flock
1327 .long __MMU(sys_msync) 1321 .long sys_msync
1328 .long sys_readv /* 145 */ 1322 .long sys_readv /* 145 */
1329 .long sys_writev 1323 .long sys_writev
1330 .long sys_getsid 1324 .long sys_getsid
1331 .long sys_fdatasync 1325 .long sys_fdatasync
1332 .long sys_sysctl 1326 .long sys_sysctl
1333 .long __MMU(sys_mlock) /* 150 */ 1327 .long sys_mlock /* 150 */
1334 .long __MMU(sys_munlock) 1328 .long sys_munlock
1335 .long __MMU(sys_mlockall) 1329 .long sys_mlockall
1336 .long __MMU(sys_munlockall) 1330 .long sys_munlockall
1337 .long sys_sched_setparam 1331 .long sys_sched_setparam
1338 .long sys_sched_getparam /* 155 */ 1332 .long sys_sched_getparam /* 155 */
1339 .long sys_sched_setscheduler 1333 .long sys_sched_setscheduler
@@ -1343,7 +1337,7 @@ sys_call_table:
1343 .long sys_sched_get_priority_min /* 160 */ 1337 .long sys_sched_get_priority_min /* 160 */
1344 .long sys_sched_rr_get_interval 1338 .long sys_sched_rr_get_interval
1345 .long sys_nanosleep 1339 .long sys_nanosleep
1346 .long __MMU(sys_mremap) 1340 .long sys_mremap
1347 .long sys_setresuid16 1341 .long sys_setresuid16
1348 .long sys_getresuid16 /* 165 */ 1342 .long sys_getresuid16 /* 165 */
1349 .long sys_ni_syscall /* for vm86 */ 1343 .long sys_ni_syscall /* for vm86 */
@@ -1398,8 +1392,8 @@ sys_call_table:
1398 .long sys_setfsuid /* 215 */ 1392 .long sys_setfsuid /* 215 */
1399 .long sys_setfsgid 1393 .long sys_setfsgid
1400 .long sys_pivot_root 1394 .long sys_pivot_root
1401 .long __MMU(sys_mincore) 1395 .long sys_mincore
1402 .long __MMU(sys_madvise) 1396 .long sys_madvise
1403 .long sys_getdents64 /* 220 */ 1397 .long sys_getdents64 /* 220 */
1404 .long sys_fcntl64 1398 .long sys_fcntl64
1405 .long sys_ni_syscall /* reserved for TUX */ 1399 .long sys_ni_syscall /* reserved for TUX */
@@ -1437,7 +1431,7 @@ sys_call_table:
1437 .long sys_epoll_create 1431 .long sys_epoll_create
1438 .long sys_epoll_ctl /* 255 */ 1432 .long sys_epoll_ctl /* 255 */
1439 .long sys_epoll_wait 1433 .long sys_epoll_wait
1440 .long __MMU(sys_remap_file_pages) 1434 .long sys_remap_file_pages
1441 .long sys_set_tid_address 1435 .long sys_set_tid_address
1442 .long sys_timer_create 1436 .long sys_timer_create
1443 .long sys_timer_settime /* 260 */ 1437 .long sys_timer_settime /* 260 */
diff --git a/arch/frv/kernel/frv_ksyms.c b/arch/frv/kernel/frv_ksyms.c
index 07c8ffa0dd39..0f273a7aca5a 100644
--- a/arch/frv/kernel/frv_ksyms.c
+++ b/arch/frv/kernel/frv_ksyms.c
@@ -27,7 +27,6 @@ EXPORT_SYMBOL(__ioremap);
27EXPORT_SYMBOL(iounmap); 27EXPORT_SYMBOL(iounmap);
28 28
29EXPORT_SYMBOL(strnlen); 29EXPORT_SYMBOL(strnlen);
30EXPORT_SYMBOL(strpbrk);
31EXPORT_SYMBOL(strrchr); 30EXPORT_SYMBOL(strrchr);
32EXPORT_SYMBOL(strstr); 31EXPORT_SYMBOL(strstr);
33EXPORT_SYMBOL(strchr); 32EXPORT_SYMBOL(strchr);
diff --git a/arch/h8300/kernel/h8300_ksyms.c b/arch/h8300/kernel/h8300_ksyms.c
index b6cd78c972bb..f8d6dee84781 100644
--- a/arch/h8300/kernel/h8300_ksyms.c
+++ b/arch/h8300/kernel/h8300_ksyms.c
@@ -25,7 +25,6 @@ extern char h8300_debug_device[];
25/* platform dependent support */ 25/* platform dependent support */
26 26
27EXPORT_SYMBOL(strnlen); 27EXPORT_SYMBOL(strnlen);
28EXPORT_SYMBOL(strpbrk);
29EXPORT_SYMBOL(strrchr); 28EXPORT_SYMBOL(strrchr);
30EXPORT_SYMBOL(strstr); 29EXPORT_SYMBOL(strstr);
31EXPORT_SYMBOL(strchr); 30EXPORT_SYMBOL(strchr);
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index f17bd1d2707e..18ec9fe6deb6 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -53,6 +53,35 @@ source "init/Kconfig"
53 53
54menu "Processor type and features" 54menu "Processor type and features"
55 55
56config SMP
57 bool "Symmetric multi-processing support"
58 ---help---
59 This enables support for systems with more than one CPU. If you have
60 a system with only one CPU, like most personal computers, say N. If
61 you have a system with more than one CPU, say Y.
62
63 If you say N here, the kernel will run on single and multiprocessor
64 machines, but will use only one CPU of a multiprocessor machine. If
65 you say Y here, the kernel will run on many, but not all,
66 singleprocessor machines. On a singleprocessor machine, the kernel
67 will run faster if you say N here.
68
69 Note that if you say Y here and choose architecture "586" or
70 "Pentium" under "Processor family", the kernel will not work on 486
71 architectures. Similarly, multiprocessor kernels for the "PPro"
72 architecture may not work on all Pentium based boards.
73
74 People using multiprocessor machines who say Y here should also say
75 Y to "Enhanced Real Time Clock Support", below. The "Advanced Power
76 Management" code will be disabled if you say Y here.
77
78 See also the <file:Documentation/smp.txt>,
79 <file:Documentation/i386/IO-APIC.txt>,
80 <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
81 <http://www.tldp.org/docs.html#howto>.
82
83 If you don't know what to do here, say N.
84
56choice 85choice
57 prompt "Subarchitecture Type" 86 prompt "Subarchitecture Type"
58 default X86_PC 87 default X86_PC
@@ -178,35 +207,6 @@ config HPET_EMULATE_RTC
178 depends on HPET_TIMER && RTC=y 207 depends on HPET_TIMER && RTC=y
179 default y 208 default y
180 209
181config SMP
182 bool "Symmetric multi-processing support"
183 ---help---
184 This enables support for systems with more than one CPU. If you have
185 a system with only one CPU, like most personal computers, say N. If
186 you have a system with more than one CPU, say Y.
187
188 If you say N here, the kernel will run on single and multiprocessor
189 machines, but will use only one CPU of a multiprocessor machine. If
190 you say Y here, the kernel will run on many, but not all,
191 singleprocessor machines. On a singleprocessor machine, the kernel
192 will run faster if you say N here.
193
194 Note that if you say Y here and choose architecture "586" or
195 "Pentium" under "Processor family", the kernel will not work on 486
196 architectures. Similarly, multiprocessor kernels for the "PPro"
197 architecture may not work on all Pentium based boards.
198
199 People using multiprocessor machines who say Y here should also say
200 Y to "Enhanced Real Time Clock Support", below. The "Advanced Power
201 Management" code will be disabled if you say Y here.
202
203 See also the <file:Documentation/smp.txt>,
204 <file:Documentation/i386/IO-APIC.txt>,
205 <file:Documentation/nmi_watchdog.txt> and the SMP-HOWTO available at
206 <http://www.tldp.org/docs.html#howto>.
207
208 If you don't know what to do here, say N.
209
210config NR_CPUS 210config NR_CPUS
211 int "Maximum number of CPUs (2-255)" 211 int "Maximum number of CPUs (2-255)"
212 range 2 255 212 range 2 255
@@ -522,6 +522,12 @@ config NUMA
522comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI" 522comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI"
523 depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI) 523 depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI)
524 524
525config NODES_SHIFT
526 int
527 default "4" if X86_NUMAQ
528 default "3"
529 depends on NEED_MULTIPLE_NODES
530
525config HAVE_ARCH_BOOTMEM_NODE 531config HAVE_ARCH_BOOTMEM_NODE
526 bool 532 bool
527 depends on NUMA 533 depends on NUMA
@@ -757,15 +763,6 @@ config HOTPLUG_CPU
757 763
758 Say N. 764 Say N.
759 765
760config DOUBLEFAULT
761 default y
762 bool "Enable doublefault exception handler" if EMBEDDED
763 help
764 This option allows trapping of rare doublefault exceptions that
765 would otherwise cause a system to silently reboot. Disabling this
766 option saves about 4k and might cause you much additional grey
767 hair.
768
769endmenu 766endmenu
770 767
771 768
diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu
index 79603b3471f9..eb130482ba18 100644
--- a/arch/i386/Kconfig.cpu
+++ b/arch/i386/Kconfig.cpu
@@ -311,5 +311,5 @@ config X86_OOSTORE
311 311
312config X86_TSC 312config X86_TSC
313 bool 313 bool
314 depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ 314 depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1 || MGEODE_LX) && !X86_NUMAQ
315 default y 315 default y
diff --git a/arch/i386/Kconfig.debug b/arch/i386/Kconfig.debug
index 6e97df6979e8..c92191b1fb67 100644
--- a/arch/i386/Kconfig.debug
+++ b/arch/i386/Kconfig.debug
@@ -81,4 +81,13 @@ config X86_MPPARSE
81 depends on X86_LOCAL_APIC && !X86_VISWS 81 depends on X86_LOCAL_APIC && !X86_VISWS
82 default y 82 default y
83 83
84config DOUBLEFAULT
85 default y
86 bool "Enable doublefault exception handler" if EMBEDDED
87 help
88 This option allows trapping of rare doublefault exceptions that
89 would otherwise cause a system to silently reboot. Disabling this
90 option saves about 4k and might cause you much additional grey
91 hair.
92
84endmenu 93endmenu
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S
index 0000a2674537..c9343c3a8082 100644
--- a/arch/i386/boot/video.S
+++ b/arch/i386/boot/video.S
@@ -97,6 +97,7 @@
97#define PARAM_VESAPM_OFF 0x30 97#define PARAM_VESAPM_OFF 0x30
98#define PARAM_LFB_PAGES 0x32 98#define PARAM_LFB_PAGES 0x32
99#define PARAM_VESA_ATTRIB 0x34 99#define PARAM_VESA_ATTRIB 0x34
100#define PARAM_CAPABILITIES 0x36
100 101
101/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */ 102/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
102#ifdef CONFIG_VIDEO_RETAIN 103#ifdef CONFIG_VIDEO_RETAIN
@@ -233,6 +234,10 @@ mopar_gr:
233 movw 18(%di), %ax 234 movw 18(%di), %ax
234 movl %eax, %fs:(PARAM_LFB_SIZE) 235 movl %eax, %fs:(PARAM_LFB_SIZE)
235 236
237# store mode capabilities
238 movl 10(%di), %eax
239 movl %eax, %fs:(PARAM_CAPABILITIES)
240
236# switching the DAC to 8-bit is for <= 8 bpp only 241# switching the DAC to 8-bit is for <= 8 bpp only
237 movw %fs:(PARAM_LFB_DEPTH), %ax 242 movw %fs:(PARAM_LFB_DEPTH), %ax
238 cmpw $8, %ax 243 cmpw $8, %ax
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index 5b9ed21216cf..96fb8a020af2 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -6,7 +6,7 @@ extra-y := head.o init_task.o vmlinux.lds
6 6
7obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ 7obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \
8 ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ 8 ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \
9 pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \ 9 pci-dma.o i386_ksyms.o i387.o bootflag.o \
10 quirks.o i8237.o topology.o alternative.o 10 quirks.o i8237.o topology.o alternative.o
11 11
12obj-y += cpu/ 12obj-y += cpu/
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index 033066176b3e..049a25583793 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -215,7 +215,7 @@ static int __init acpi_parse_madt(unsigned long phys_addr, unsigned long size)
215{ 215{
216 struct acpi_table_madt *madt = NULL; 216 struct acpi_table_madt *madt = NULL;
217 217
218 if (!phys_addr || !size) 218 if (!phys_addr || !size || !cpu_has_apic)
219 return -EINVAL; 219 return -EINVAL;
220 220
221 madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size); 221 madt = (struct acpi_table_madt *)__acpi_map_table(phys_addr, size);
@@ -693,6 +693,9 @@ static int __init acpi_parse_madt_lapic_entries(void)
693{ 693{
694 int count; 694 int count;
695 695
696 if (!cpu_has_apic)
697 return -ENODEV;
698
696 /* 699 /*
697 * Note that the LAPIC address is obtained from the MADT (32-bit value) 700 * Note that the LAPIC address is obtained from the MADT (32-bit value)
698 * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). 701 * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
@@ -751,6 +754,9 @@ static int __init acpi_parse_madt_ioapic_entries(void)
751 return -ENODEV; 754 return -ENODEV;
752 } 755 }
753 756
757 if (!cpu_has_apic)
758 return -ENODEV;
759
754 /* 760 /*
755 * if "noapic" boot option, don't look for IO-APICs 761 * if "noapic" boot option, don't look for IO-APICs
756 */ 762 */
@@ -1096,6 +1102,9 @@ int __init acpi_boot_table_init(void)
1096 dmi_check_system(acpi_dmi_table); 1102 dmi_check_system(acpi_dmi_table);
1097#endif 1103#endif
1098 1104
1105 if (!cpu_has_apic)
1106 return -ENODEV;
1107
1099 /* 1108 /*
1100 * If acpi_disabled, bail out 1109 * If acpi_disabled, bail out
1101 * One exception: acpi=ht continues far enough to enumerate LAPICs 1110 * One exception: acpi=ht continues far enough to enumerate LAPICs
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 6273bf74c203..254cee9f0b7b 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -62,6 +62,18 @@ int apic_verbosity;
62 62
63static void apic_pm_activate(void); 63static void apic_pm_activate(void);
64 64
65int modern_apic(void)
66{
67 unsigned int lvr, version;
68 /* AMD systems use old APIC versions, so check the CPU */
69 if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
70 boot_cpu_data.x86 >= 0xf)
71 return 1;
72 lvr = apic_read(APIC_LVR);
73 version = GET_APIC_VERSION(lvr);
74 return version >= 0x14;
75}
76
65/* 77/*
66 * 'what should we do if we get a hw irq event on an illegal vector'. 78 * 'what should we do if we get a hw irq event on an illegal vector'.
67 * each architecture has to answer this themselves. 79 * each architecture has to answer this themselves.
@@ -119,10 +131,7 @@ void enable_NMI_through_LVT0 (void * dummy)
119 131
120int get_physical_broadcast(void) 132int get_physical_broadcast(void)
121{ 133{
122 unsigned int lvr, version; 134 if (modern_apic())
123 lvr = apic_read(APIC_LVR);
124 version = GET_APIC_VERSION(lvr);
125 if (!APIC_INTEGRATED(version) || version >= 0x14)
126 return 0xff; 135 return 0xff;
127 else 136 else
128 return 0xf; 137 return 0xf;
@@ -349,9 +358,9 @@ int __init verify_local_APIC(void)
349 358
350void __init sync_Arb_IDs(void) 359void __init sync_Arb_IDs(void)
351{ 360{
352 /* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 */ 361 /* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1
353 unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR)); 362 And not needed on AMD */
354 if (ver >= 0x14) /* P4 or higher */ 363 if (modern_apic())
355 return; 364 return;
356 /* 365 /*
357 * Wait for idle. 366 * Wait for idle.
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index da30a374dd4e..df0e1745f189 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -1079,7 +1079,7 @@ static int apm_console_blank(int blank)
1079 break; 1079 break;
1080 } 1080 }
1081 1081
1082 if (error == APM_NOT_ENGAGED && state != APM_STATE_READY) { 1082 if (error == APM_NOT_ENGAGED) {
1083 static int tried; 1083 static int tried;
1084 int eng_error; 1084 int eng_error;
1085 if (tried++ == 0) { 1085 if (tried++ == 0) {
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index 0810f81f2a05..786d1a57048b 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -207,13 +207,13 @@ static void __init init_amd(struct cpuinfo_x86 *c)
207 set_bit(X86_FEATURE_K7, c->x86_capability); 207 set_bit(X86_FEATURE_K7, c->x86_capability);
208 break; 208 break;
209 } 209 }
210 if (c->x86 >= 6)
211 set_bit(X86_FEATURE_FXSAVE_LEAK, c->x86_capability);
210 212
211 display_cacheinfo(c); 213 display_cacheinfo(c);
212 214
213 if (cpuid_eax(0x80000000) >= 0x80000008) { 215 if (cpuid_eax(0x80000000) >= 0x80000008) {
214 c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1; 216 c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
215 if (c->x86_max_cores & (c->x86_max_cores - 1))
216 c->x86_max_cores = 1;
217 } 217 }
218 218
219 if (cpuid_eax(0x80000000) >= 0x80000007) { 219 if (cpuid_eax(0x80000000) >= 0x80000007) {
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
index 712a26bd4457..71fffa174425 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
@@ -46,7 +46,7 @@
46 46
47#define PFX "powernow-k8: " 47#define PFX "powernow-k8: "
48#define BFX PFX "BIOS error: " 48#define BFX PFX "BIOS error: "
49#define VERSION "version 1.60.1" 49#define VERSION "version 1.60.2"
50#include "powernow-k8.h" 50#include "powernow-k8.h"
51 51
52/* serialize freq changes */ 52/* serialize freq changes */
@@ -55,7 +55,7 @@ static DEFINE_MUTEX(fidvid_mutex);
55static struct powernow_k8_data *powernow_data[NR_CPUS]; 55static struct powernow_k8_data *powernow_data[NR_CPUS];
56 56
57#ifndef CONFIG_SMP 57#ifndef CONFIG_SMP
58static cpumask_t cpu_core_map[1] = { CPU_MASK_ALL }; 58static cpumask_t cpu_core_map[1];
59#endif 59#endif
60 60
61/* Return a frequency in MHz, given an input fid */ 61/* Return a frequency in MHz, given an input fid */
@@ -905,11 +905,17 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
905{ 905{
906 cpumask_t oldmask = CPU_MASK_ALL; 906 cpumask_t oldmask = CPU_MASK_ALL;
907 struct powernow_k8_data *data = powernow_data[pol->cpu]; 907 struct powernow_k8_data *data = powernow_data[pol->cpu];
908 u32 checkfid = data->currfid; 908 u32 checkfid;
909 u32 checkvid = data->currvid; 909 u32 checkvid;
910 unsigned int newstate; 910 unsigned int newstate;
911 int ret = -EIO; 911 int ret = -EIO;
912 912
913 if (!data)
914 return -EINVAL;
915
916 checkfid = data->currfid;
917 checkvid = data->currvid;
918
913 /* only run on specific CPU from here on */ 919 /* only run on specific CPU from here on */
914 oldmask = current->cpus_allowed; 920 oldmask = current->cpus_allowed;
915 set_cpus_allowed(current, cpumask_of_cpu(pol->cpu)); 921 set_cpus_allowed(current, cpumask_of_cpu(pol->cpu));
@@ -969,6 +975,9 @@ static int powernowk8_verify(struct cpufreq_policy *pol)
969{ 975{
970 struct powernow_k8_data *data = powernow_data[pol->cpu]; 976 struct powernow_k8_data *data = powernow_data[pol->cpu];
971 977
978 if (!data)
979 return -EINVAL;
980
972 return cpufreq_frequency_table_verify(pol, data->powernow_table); 981 return cpufreq_frequency_table_verify(pol, data->powernow_table);
973} 982}
974 983
@@ -977,7 +986,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
977{ 986{
978 struct powernow_k8_data *data; 987 struct powernow_k8_data *data;
979 cpumask_t oldmask = CPU_MASK_ALL; 988 cpumask_t oldmask = CPU_MASK_ALL;
980 int rc, i; 989 int rc;
981 990
982 if (!cpu_online(pol->cpu)) 991 if (!cpu_online(pol->cpu))
983 return -ENODEV; 992 return -ENODEV;
@@ -1063,8 +1072,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
1063 printk("cpu_init done, current fid 0x%x, vid 0x%x\n", 1072 printk("cpu_init done, current fid 0x%x, vid 0x%x\n",
1064 data->currfid, data->currvid); 1073 data->currfid, data->currvid);
1065 1074
1066 for_each_cpu_mask(i, cpu_core_map[pol->cpu]) 1075 powernow_data[pol->cpu] = data;
1067 powernow_data[i] = data;
1068 1076
1069 return 0; 1077 return 0;
1070 1078
diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c
index 006141d1c12a..1d9a4abcdfc7 100644
--- a/arch/i386/kernel/cpuid.c
+++ b/arch/i386/kernel/cpuid.c
@@ -168,7 +168,7 @@ static int cpuid_class_device_create(int i)
168 return err; 168 return err;
169} 169}
170 170
171static int __devinit cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) 171static int cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
172{ 172{
173 unsigned int cpu = (unsigned long)hcpu; 173 unsigned int cpu = (unsigned long)hcpu;
174 174
diff --git a/arch/i386/kernel/dmi_scan.c b/arch/i386/kernel/dmi_scan.c
deleted file mode 100644
index 5efceebc48dc..000000000000
--- a/arch/i386/kernel/dmi_scan.c
+++ /dev/null
@@ -1,358 +0,0 @@
1#include <linux/types.h>
2#include <linux/string.h>
3#include <linux/init.h>
4#include <linux/module.h>
5#include <linux/dmi.h>
6#include <linux/efi.h>
7#include <linux/bootmem.h>
8#include <linux/slab.h>
9#include <asm/dmi.h>
10
11static char * __init dmi_string(struct dmi_header *dm, u8 s)
12{
13 u8 *bp = ((u8 *) dm) + dm->length;
14 char *str = "";
15
16 if (s) {
17 s--;
18 while (s > 0 && *bp) {
19 bp += strlen(bp) + 1;
20 s--;
21 }
22
23 if (*bp != 0) {
24 str = dmi_alloc(strlen(bp) + 1);
25 if (str != NULL)
26 strcpy(str, bp);
27 else
28 printk(KERN_ERR "dmi_string: out of memory.\n");
29 }
30 }
31
32 return str;
33}
34
35/*
36 * We have to be cautious here. We have seen BIOSes with DMI pointers
37 * pointing to completely the wrong place for example
38 */
39static int __init dmi_table(u32 base, int len, int num,
40 void (*decode)(struct dmi_header *))
41{
42 u8 *buf, *data;
43 int i = 0;
44
45 buf = dmi_ioremap(base, len);
46 if (buf == NULL)
47 return -1;
48
49 data = buf;
50
51 /*
52 * Stop when we see all the items the table claimed to have
53 * OR we run off the end of the table (also happens)
54 */
55 while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) {
56 struct dmi_header *dm = (struct dmi_header *)data;
57 /*
58 * We want to know the total length (formated area and strings)
59 * before decoding to make sure we won't run off the table in
60 * dmi_decode or dmi_string
61 */
62 data += dm->length;
63 while ((data - buf < len - 1) && (data[0] || data[1]))
64 data++;
65 if (data - buf < len - 1)
66 decode(dm);
67 data += 2;
68 i++;
69 }
70 dmi_iounmap(buf, len);
71 return 0;
72}
73
74static int __init dmi_checksum(u8 *buf)
75{
76 u8 sum = 0;
77 int a;
78
79 for (a = 0; a < 15; a++)
80 sum += buf[a];
81
82 return sum == 0;
83}
84
85static char *dmi_ident[DMI_STRING_MAX];
86static LIST_HEAD(dmi_devices);
87
88/*
89 * Save a DMI string
90 */
91static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string)
92{
93 char *p, *d = (char*) dm;
94
95 if (dmi_ident[slot])
96 return;
97
98 p = dmi_string(dm, d[string]);
99 if (p == NULL)
100 return;
101
102 dmi_ident[slot] = p;
103}
104
105static void __init dmi_save_devices(struct dmi_header *dm)
106{
107 int i, count = (dm->length - sizeof(struct dmi_header)) / 2;
108 struct dmi_device *dev;
109
110 for (i = 0; i < count; i++) {
111 char *d = (char *)(dm + 1) + (i * 2);
112
113 /* Skip disabled device */
114 if ((*d & 0x80) == 0)
115 continue;
116
117 dev = dmi_alloc(sizeof(*dev));
118 if (!dev) {
119 printk(KERN_ERR "dmi_save_devices: out of memory.\n");
120 break;
121 }
122
123 dev->type = *d++ & 0x7f;
124 dev->name = dmi_string(dm, *d);
125 dev->device_data = NULL;
126
127 list_add(&dev->list, &dmi_devices);
128 }
129}
130
131static void __init dmi_save_ipmi_device(struct dmi_header *dm)
132{
133 struct dmi_device *dev;
134 void * data;
135
136 data = dmi_alloc(dm->length);
137 if (data == NULL) {
138 printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n");
139 return;
140 }
141
142 memcpy(data, dm, dm->length);
143
144 dev = dmi_alloc(sizeof(*dev));
145 if (!dev) {
146 printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n");
147 return;
148 }
149
150 dev->type = DMI_DEV_TYPE_IPMI;
151 dev->name = "IPMI controller";
152 dev->device_data = data;
153
154 list_add(&dev->list, &dmi_devices);
155}
156
157/*
158 * Process a DMI table entry. Right now all we care about are the BIOS
159 * and machine entries. For 2.5 we should pull the smbus controller info
160 * out of here.
161 */
162static void __init dmi_decode(struct dmi_header *dm)
163{
164 switch(dm->type) {
165 case 0: /* BIOS Information */
166 dmi_save_ident(dm, DMI_BIOS_VENDOR, 4);
167 dmi_save_ident(dm, DMI_BIOS_VERSION, 5);
168 dmi_save_ident(dm, DMI_BIOS_DATE, 8);
169 break;
170 case 1: /* System Information */
171 dmi_save_ident(dm, DMI_SYS_VENDOR, 4);
172 dmi_save_ident(dm, DMI_PRODUCT_NAME, 5);
173 dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6);
174 dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7);
175 break;
176 case 2: /* Base Board Information */
177 dmi_save_ident(dm, DMI_BOARD_VENDOR, 4);
178 dmi_save_ident(dm, DMI_BOARD_NAME, 5);
179 dmi_save_ident(dm, DMI_BOARD_VERSION, 6);
180 break;
181 case 10: /* Onboard Devices Information */
182 dmi_save_devices(dm);
183 break;
184 case 38: /* IPMI Device Information */
185 dmi_save_ipmi_device(dm);
186 }
187}
188
189static int __init dmi_present(char __iomem *p)
190{
191 u8 buf[15];
192 memcpy_fromio(buf, p, 15);
193 if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) {
194 u16 num = (buf[13] << 8) | buf[12];
195 u16 len = (buf[7] << 8) | buf[6];
196 u32 base = (buf[11] << 24) | (buf[10] << 16) |
197 (buf[9] << 8) | buf[8];
198
199 /*
200 * DMI version 0.0 means that the real version is taken from
201 * the SMBIOS version, which we don't know at this point.
202 */
203 if (buf[14] != 0)
204 printk(KERN_INFO "DMI %d.%d present.\n",
205 buf[14] >> 4, buf[14] & 0xF);
206 else
207 printk(KERN_INFO "DMI present.\n");
208 if (dmi_table(base,len, num, dmi_decode) == 0)
209 return 0;
210 }
211 return 1;
212}
213
214void __init dmi_scan_machine(void)
215{
216 char __iomem *p, *q;
217 int rc;
218
219 if (efi_enabled) {
220 if (efi.smbios == EFI_INVALID_TABLE_ADDR)
221 goto out;
222
223 /* This is called as a core_initcall() because it isn't
224 * needed during early boot. This also means we can
225 * iounmap the space when we're done with it.
226 */
227 p = dmi_ioremap(efi.smbios, 32);
228 if (p == NULL)
229 goto out;
230
231 rc = dmi_present(p + 0x10); /* offset of _DMI_ string */
232 dmi_iounmap(p, 32);
233 if (!rc)
234 return;
235 }
236 else {
237 /*
238 * no iounmap() for that ioremap(); it would be a no-op, but
239 * it's so early in setup that sucker gets confused into doing
240 * what it shouldn't if we actually call it.
241 */
242 p = dmi_ioremap(0xF0000, 0x10000);
243 if (p == NULL)
244 goto out;
245
246 for (q = p; q < p + 0x10000; q += 16) {
247 rc = dmi_present(q);
248 if (!rc)
249 return;
250 }
251 }
252 out: printk(KERN_INFO "DMI not present or invalid.\n");
253}
254
255/**
256 * dmi_check_system - check system DMI data
257 * @list: array of dmi_system_id structures to match against
258 *
259 * Walk the blacklist table running matching functions until someone
260 * returns non zero or we hit the end. Callback function is called for
261 * each successfull match. Returns the number of matches.
262 */
263int dmi_check_system(struct dmi_system_id *list)
264{
265 int i, count = 0;
266 struct dmi_system_id *d = list;
267
268 while (d->ident) {
269 for (i = 0; i < ARRAY_SIZE(d->matches); i++) {
270 int s = d->matches[i].slot;
271 if (s == DMI_NONE)
272 continue;
273 if (dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr))
274 continue;
275 /* No match */
276 goto fail;
277 }
278 count++;
279 if (d->callback && d->callback(d))
280 break;
281fail: d++;
282 }
283
284 return count;
285}
286EXPORT_SYMBOL(dmi_check_system);
287
288/**
289 * dmi_get_system_info - return DMI data value
290 * @field: data index (see enum dmi_filed)
291 *
292 * Returns one DMI data value, can be used to perform
293 * complex DMI data checks.
294 */
295char *dmi_get_system_info(int field)
296{
297 return dmi_ident[field];
298}
299EXPORT_SYMBOL(dmi_get_system_info);
300
301/**
302 * dmi_find_device - find onboard device by type/name
303 * @type: device type or %DMI_DEV_TYPE_ANY to match all device types
304 * @desc: device name string or %NULL to match all
305 * @from: previous device found in search, or %NULL for new search.
306 *
307 * Iterates through the list of known onboard devices. If a device is
308 * found with a matching @vendor and @device, a pointer to its device
309 * structure is returned. Otherwise, %NULL is returned.
310 * A new search is initiated by passing %NULL to the @from argument.
311 * If @from is not %NULL, searches continue from next device.
312 */
313struct dmi_device * dmi_find_device(int type, const char *name,
314 struct dmi_device *from)
315{
316 struct list_head *d, *head = from ? &from->list : &dmi_devices;
317
318 for(d = head->next; d != &dmi_devices; d = d->next) {
319 struct dmi_device *dev = list_entry(d, struct dmi_device, list);
320
321 if (((type == DMI_DEV_TYPE_ANY) || (dev->type == type)) &&
322 ((name == NULL) || (strcmp(dev->name, name) == 0)))
323 return dev;
324 }
325
326 return NULL;
327}
328EXPORT_SYMBOL(dmi_find_device);
329
330/**
331 * dmi_get_year - Return year of a DMI date
332 * @field: data index (like dmi_get_system_info)
333 *
334 * Returns -1 when the field doesn't exist. 0 when it is broken.
335 */
336int dmi_get_year(int field)
337{
338 int year;
339 char *s = dmi_get_system_info(field);
340
341 if (!s)
342 return -1;
343 if (*s == '\0')
344 return 0;
345 s = strrchr(s, '/');
346 if (!s)
347 return 0;
348
349 s += 1;
350 year = simple_strtoul(s, NULL, 0);
351 if (year && year < 100) { /* 2-digit year */
352 year += 1900;
353 if (year < 1996) /* no dates < spec 1.0 */
354 year += 100;
355 }
356
357 return year;
358}
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
index 055325056a74..036a9857936f 100644
--- a/arch/i386/kernel/i386_ksyms.c
+++ b/arch/i386/kernel/i386_ksyms.c
@@ -19,7 +19,6 @@ EXPORT_SYMBOL(__put_user_2);
19EXPORT_SYMBOL(__put_user_4); 19EXPORT_SYMBOL(__put_user_4);
20EXPORT_SYMBOL(__put_user_8); 20EXPORT_SYMBOL(__put_user_8);
21 21
22EXPORT_SYMBOL(strpbrk);
23EXPORT_SYMBOL(strstr); 22EXPORT_SYMBOL(strstr);
24 23
25#ifdef CONFIG_SMP 24#ifdef CONFIG_SMP
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index f19768789e8a..043f5292e70a 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -43,7 +43,7 @@ DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
43DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); 43DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
44 44
45/* insert a jmp code */ 45/* insert a jmp code */
46static inline void set_jmp_op(void *from, void *to) 46static __always_inline void set_jmp_op(void *from, void *to)
47{ 47{
48 struct __arch_jmp_op { 48 struct __arch_jmp_op {
49 char op; 49 char op;
@@ -57,7 +57,7 @@ static inline void set_jmp_op(void *from, void *to)
57/* 57/*
58 * returns non-zero if opcodes can be boosted. 58 * returns non-zero if opcodes can be boosted.
59 */ 59 */
60static inline int can_boost(kprobe_opcode_t opcode) 60static __always_inline int can_boost(kprobe_opcode_t opcode)
61{ 61{
62 switch (opcode & 0xf0 ) { 62 switch (opcode & 0xf0 ) {
63 case 0x70: 63 case 0x70:
@@ -88,7 +88,7 @@ static inline int can_boost(kprobe_opcode_t opcode)
88/* 88/*
89 * returns non-zero if opcode modifies the interrupt flag. 89 * returns non-zero if opcode modifies the interrupt flag.
90 */ 90 */
91static inline int is_IF_modifier(kprobe_opcode_t opcode) 91static int __kprobes is_IF_modifier(kprobe_opcode_t opcode)
92{ 92{
93 switch (opcode) { 93 switch (opcode) {
94 case 0xfa: /* cli */ 94 case 0xfa: /* cli */
@@ -138,7 +138,7 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
138 mutex_unlock(&kprobe_mutex); 138 mutex_unlock(&kprobe_mutex);
139} 139}
140 140
141static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) 141static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
142{ 142{
143 kcb->prev_kprobe.kp = kprobe_running(); 143 kcb->prev_kprobe.kp = kprobe_running();
144 kcb->prev_kprobe.status = kcb->kprobe_status; 144 kcb->prev_kprobe.status = kcb->kprobe_status;
@@ -146,7 +146,7 @@ static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
146 kcb->prev_kprobe.saved_eflags = kcb->kprobe_saved_eflags; 146 kcb->prev_kprobe.saved_eflags = kcb->kprobe_saved_eflags;
147} 147}
148 148
149static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) 149static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
150{ 150{
151 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; 151 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
152 kcb->kprobe_status = kcb->prev_kprobe.status; 152 kcb->kprobe_status = kcb->prev_kprobe.status;
@@ -154,7 +154,7 @@ static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
154 kcb->kprobe_saved_eflags = kcb->prev_kprobe.saved_eflags; 154 kcb->kprobe_saved_eflags = kcb->prev_kprobe.saved_eflags;
155} 155}
156 156
157static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, 157static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
158 struct kprobe_ctlblk *kcb) 158 struct kprobe_ctlblk *kcb)
159{ 159{
160 __get_cpu_var(current_kprobe) = p; 160 __get_cpu_var(current_kprobe) = p;
@@ -164,7 +164,7 @@ static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
164 kcb->kprobe_saved_eflags &= ~IF_MASK; 164 kcb->kprobe_saved_eflags &= ~IF_MASK;
165} 165}
166 166
167static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) 167static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
168{ 168{
169 regs->eflags |= TF_MASK; 169 regs->eflags |= TF_MASK;
170 regs->eflags &= ~IF_MASK; 170 regs->eflags &= ~IF_MASK;
@@ -507,7 +507,7 @@ no_change:
507 * Interrupts are disabled on entry as trap1 is an interrupt gate and they 507 * Interrupts are disabled on entry as trap1 is an interrupt gate and they
508 * remain disabled thoroughout this function. 508 * remain disabled thoroughout this function.
509 */ 509 */
510static inline int post_kprobe_handler(struct pt_regs *regs) 510static int __kprobes post_kprobe_handler(struct pt_regs *regs)
511{ 511{
512 struct kprobe *cur = kprobe_running(); 512 struct kprobe *cur = kprobe_running();
513 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 513 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
@@ -543,7 +543,7 @@ out:
543 return 1; 543 return 1;
544} 544}
545 545
546static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) 546static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
547{ 547{
548 struct kprobe *cur = kprobe_running(); 548 struct kprobe *cur = kprobe_running();
549 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 549 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 8d8aa9d1796d..34d21e21e012 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -38,12 +38,6 @@
38int smp_found_config; 38int smp_found_config;
39unsigned int __initdata maxcpus = NR_CPUS; 39unsigned int __initdata maxcpus = NR_CPUS;
40 40
41#ifdef CONFIG_HOTPLUG_CPU
42#define CPU_HOTPLUG_ENABLED (1)
43#else
44#define CPU_HOTPLUG_ENABLED (0)
45#endif
46
47/* 41/*
48 * Various Linux-internal data structures created from the 42 * Various Linux-internal data structures created from the
49 * MP-table. 43 * MP-table.
@@ -110,21 +104,6 @@ static int __init mpf_checksum(unsigned char *mp, int len)
110static int mpc_record; 104static int mpc_record;
111static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata; 105static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata;
112 106
113#ifdef CONFIG_X86_NUMAQ
114static int MP_valid_apicid(int apicid, int version)
115{
116 return hweight_long(apicid & 0xf) == 1 && (apicid >> 4) != 0xf;
117}
118#else
119static int MP_valid_apicid(int apicid, int version)
120{
121 if (version >= 0x14)
122 return apicid < 0xff;
123 else
124 return apicid < 0xf;
125}
126#endif
127
128static void __devinit MP_processor_info (struct mpc_config_processor *m) 107static void __devinit MP_processor_info (struct mpc_config_processor *m)
129{ 108{
130 int ver, apicid; 109 int ver, apicid;
@@ -190,12 +169,6 @@ static void __devinit MP_processor_info (struct mpc_config_processor *m)
190 169
191 ver = m->mpc_apicver; 170 ver = m->mpc_apicver;
192 171
193 if (!MP_valid_apicid(apicid, ver)) {
194 printk(KERN_WARNING "Processor #%d INVALID. (Max ID: %d).\n",
195 m->mpc_apicid, MAX_APICS);
196 return;
197 }
198
199 /* 172 /*
200 * Validate version 173 * Validate version
201 */ 174 */
@@ -225,7 +198,14 @@ static void __devinit MP_processor_info (struct mpc_config_processor *m)
225 cpu_set(num_processors, cpu_possible_map); 198 cpu_set(num_processors, cpu_possible_map);
226 num_processors++; 199 num_processors++;
227 200
228 if (CPU_HOTPLUG_ENABLED || (num_processors > 8)) { 201 /*
202 * Would be preferable to switch to bigsmp when CONFIG_HOTPLUG_CPU=y
203 * but we need to work other dependencies like SMP_SUSPEND etc
204 * before this can be done without some confusion.
205 * if (CPU_HOTPLUG_ENABLED || num_processors > 8)
206 * - Ashok Raj <ashok.raj@intel.com>
207 */
208 if (num_processors > 8) {
229 switch (boot_cpu_data.x86_vendor) { 209 switch (boot_cpu_data.x86_vendor) {
230 case X86_VENDOR_INTEL: 210 case X86_VENDOR_INTEL:
231 if (!APIC_XAPIC(ver)) { 211 if (!APIC_XAPIC(ver)) {
@@ -249,6 +229,13 @@ static void __init MP_bus_info (struct mpc_config_bus *m)
249 229
250 mpc_oem_bus_info(m, str, translation_table[mpc_record]); 230 mpc_oem_bus_info(m, str, translation_table[mpc_record]);
251 231
232 if (m->mpc_busid >= MAX_MP_BUSSES) {
233 printk(KERN_WARNING "MP table busid value (%d) for bustype %s "
234 " is too large, max. supported is %d\n",
235 m->mpc_busid, str, MAX_MP_BUSSES - 1);
236 return;
237 }
238
252 if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) { 239 if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) {
253 mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; 240 mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA;
254 } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) { 241 } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) {
diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c
index 1d0a55e68760..7a328230e540 100644
--- a/arch/i386/kernel/msr.c
+++ b/arch/i386/kernel/msr.c
@@ -251,7 +251,7 @@ static int msr_class_device_create(int i)
251 return err; 251 return err;
252} 252}
253 253
254static int __devinit msr_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) 254static int msr_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
255{ 255{
256 unsigned int cpu = (unsigned long)hcpu; 256 unsigned int cpu = (unsigned long)hcpu;
257 257
diff --git a/arch/i386/kernel/reboot_fixups.c b/arch/i386/kernel/reboot_fixups.c
index 10e21a4773dd..99aab41a05b0 100644
--- a/arch/i386/kernel/reboot_fixups.c
+++ b/arch/i386/kernel/reboot_fixups.c
@@ -51,7 +51,5 @@ void mach_reboot_fixups(void)
51 51
52 cur->reboot_fixup(dev); 52 cur->reboot_fixup(dev);
53 } 53 }
54
55 printk(KERN_WARNING "No reboot fixup found for your hardware\n");
56} 54}
57 55
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index eacc3f0a2ea4..80cb3b2d0997 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -963,6 +963,36 @@ efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg)
963 return 0; 963 return 0;
964} 964}
965 965
966 /*
967 * This function checks if the entire range <start,end> is mapped with type.
968 *
969 * Note: this function only works correct if the e820 table is sorted and
970 * not-overlapping, which is the case
971 */
972int __init
973e820_all_mapped(unsigned long start, unsigned long end, unsigned type)
974{
975 int i;
976 for (i = 0; i < e820.nr_map; i++) {
977 struct e820entry *ei = &e820.map[i];
978 if (type && ei->type != type)
979 continue;
980 /* is the region (part) in overlap with the current region ?*/
981 if (ei->addr >= end || ei->addr + ei->size <= start)
982 continue;
983 /* if the region is at the beginning of <start,end> we move
984 * start to the end of the region since it's ok until there
985 */
986 if (ei->addr <= start)
987 start = ei->addr + ei->size;
988 /* if start is now at or beyond end, we're done, full
989 * coverage */
990 if (start >= end)
991 return 1; /* we're done */
992 }
993 return 0;
994}
995
966/* 996/*
967 * Find the highest page frame number we have available 997 * Find the highest page frame number we have available
968 */ 998 */
@@ -1317,8 +1347,8 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
1317/* 1347/*
1318 * Request address space for all standard resources 1348 * Request address space for all standard resources
1319 * 1349 *
1320 * This is called just before pcibios_assign_resources(), which is also 1350 * This is called just before pcibios_init(), which is also a
1321 * an fs_initcall, but is linked in later (in arch/i386/pci/i386.c). 1351 * subsys_initcall, but is linked in later (in arch/i386/pci/common.c).
1322 */ 1352 */
1323static int __init request_standard_resources(void) 1353static int __init request_standard_resources(void)
1324{ 1354{
@@ -1339,7 +1369,7 @@ static int __init request_standard_resources(void)
1339 return 0; 1369 return 0;
1340} 1370}
1341 1371
1342fs_initcall(request_standard_resources); 1372subsys_initcall(request_standard_resources);
1343 1373
1344static void __init register_memory(void) 1374static void __init register_memory(void)
1345{ 1375{
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S
index 4f58b9c0efe3..f48bef15b4f0 100644
--- a/arch/i386/kernel/syscall_table.S
+++ b/arch/i386/kernel/syscall_table.S
@@ -314,3 +314,4 @@ ENTRY(sys_call_table)
314 .long sys_get_robust_list 314 .long sys_get_robust_list
315 .long sys_splice 315 .long sys_splice
316 .long sys_sync_file_range 316 .long sys_sync_file_range
317 .long sys_tee /* 315 */
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index e38527994590..2d22f5761b1d 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -365,6 +365,9 @@ void die(const char * str, struct pt_regs * regs, long err)
365 365
366 if (++die.lock_owner_depth < 3) { 366 if (++die.lock_owner_depth < 3) {
367 int nl = 0; 367 int nl = 0;
368 unsigned long esp;
369 unsigned short ss;
370
368 handle_BUG(regs); 371 handle_BUG(regs);
369 printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); 372 printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
370#ifdef CONFIG_PREEMPT 373#ifdef CONFIG_PREEMPT
@@ -387,8 +390,19 @@ void die(const char * str, struct pt_regs * regs, long err)
387 printk("\n"); 390 printk("\n");
388 if (notify_die(DIE_OOPS, str, regs, err, 391 if (notify_die(DIE_OOPS, str, regs, err,
389 current->thread.trap_no, SIGSEGV) != 392 current->thread.trap_no, SIGSEGV) !=
390 NOTIFY_STOP) 393 NOTIFY_STOP) {
391 show_registers(regs); 394 show_registers(regs);
395 /* Executive summary in case the oops scrolled away */
396 esp = (unsigned long) (&regs->esp);
397 savesegment(ss, ss);
398 if (user_mode(regs)) {
399 esp = regs->esp;
400 ss = regs->xss & 0xffff;
401 }
402 printk(KERN_EMERG "EIP: [<%08lx>] ", regs->eip);
403 print_symbol("%s", regs->eip);
404 printk(" SS:ESP %04x:%08lx\n", ss, esp);
405 }
392 else 406 else
393 regs = NULL; 407 regs = NULL;
394 } else 408 } else
diff --git a/arch/i386/mach-voyager/voyager_cat.c b/arch/i386/mach-voyager/voyager_cat.c
index 23967fe658d3..10d21df14531 100644
--- a/arch/i386/mach-voyager/voyager_cat.c
+++ b/arch/i386/mach-voyager/voyager_cat.c
@@ -106,15 +106,20 @@ voyager_module_t *voyager_cat_list;
106 106
107/* the I/O port assignments for the VIC and QIC */ 107/* the I/O port assignments for the VIC and QIC */
108static struct resource vic_res = { 108static struct resource vic_res = {
109 "Voyager Interrupt Controller", 0xFC00, 0xFC6F }; 109 .name = "Voyager Interrupt Controller",
110 .start = 0xFC00,
111 .end = 0xFC6F
112};
110static struct resource qic_res = { 113static struct resource qic_res = {
111 "Quad Interrupt Controller", 0xFC70, 0xFCFF }; 114 .name = "Quad Interrupt Controller",
115 .start = 0xFC70,
116 .end = 0xFCFF
117};
112 118
113/* This function is used to pack a data bit stream inside a message. 119/* This function is used to pack a data bit stream inside a message.
114 * It writes num_bits of the data buffer in msg starting at start_bit. 120 * It writes num_bits of the data buffer in msg starting at start_bit.
115 * Note: This function assumes that any unused bit in the data stream 121 * Note: This function assumes that any unused bit in the data stream
116 * is set to zero so that the ors will work correctly */ 122 * is set to zero so that the ors will work correctly */
117#define BITS_PER_BYTE 8
118static void 123static void
119cat_pack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits) 124cat_pack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits)
120{ 125{
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 9f66ac582a8b..ae6534ad8161 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -651,6 +651,7 @@ void __init mem_init(void)
651 * Specifically, in the case of x86, we will always add 651 * Specifically, in the case of x86, we will always add
652 * memory to the highmem for now. 652 * memory to the highmem for now.
653 */ 653 */
654#ifdef CONFIG_HOTPLUG_MEMORY
654#ifndef CONFIG_NEED_MULTIPLE_NODES 655#ifndef CONFIG_NEED_MULTIPLE_NODES
655int add_memory(u64 start, u64 size) 656int add_memory(u64 start, u64 size)
656{ 657{
@@ -667,6 +668,7 @@ int remove_memory(u64 start, u64 size)
667 return -EINVAL; 668 return -EINVAL;
668} 669}
669#endif 670#endif
671#endif
670 672
671kmem_cache_t *pgd_cache; 673kmem_cache_t *pgd_cache;
672kmem_cache_t *pmd_cache; 674kmem_cache_t *pmd_cache;
diff --git a/arch/i386/pci/direct.c b/arch/i386/pci/direct.c
index 99012b93bd12..5d81fb510375 100644
--- a/arch/i386/pci/direct.c
+++ b/arch/i386/pci/direct.c
@@ -4,6 +4,7 @@
4 4
5#include <linux/pci.h> 5#include <linux/pci.h>
6#include <linux/init.h> 6#include <linux/init.h>
7#include <linux/dmi.h>
7#include "pci.h" 8#include "pci.h"
8 9
9/* 10/*
@@ -18,8 +19,10 @@ int pci_conf1_read(unsigned int seg, unsigned int bus,
18{ 19{
19 unsigned long flags; 20 unsigned long flags;
20 21
21 if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) 22 if ((bus > 255) || (devfn > 255) || (reg > 255)) {
23 *value = -1;
22 return -EINVAL; 24 return -EINVAL;
25 }
23 26
24 spin_lock_irqsave(&pci_config_lock, flags); 27 spin_lock_irqsave(&pci_config_lock, flags);
25 28
@@ -91,8 +94,10 @@ static int pci_conf2_read(unsigned int seg, unsigned int bus,
91 unsigned long flags; 94 unsigned long flags;
92 int dev, fn; 95 int dev, fn;
93 96
94 if (!value || (bus > 255) || (devfn > 255) || (reg > 255)) 97 if ((bus > 255) || (devfn > 255) || (reg > 255)) {
98 *value = -1;
95 return -EINVAL; 99 return -EINVAL;
100 }
96 101
97 dev = PCI_SLOT(devfn); 102 dev = PCI_SLOT(devfn);
98 fn = PCI_FUNC(devfn); 103 fn = PCI_FUNC(devfn);
@@ -188,6 +193,10 @@ static int __init pci_sanity_check(struct pci_raw_ops *o)
188 193
189 if (pci_probe & PCI_NO_CHECKS) 194 if (pci_probe & PCI_NO_CHECKS)
190 return 1; 195 return 1;
196 /* Assume Type 1 works for newer systems.
197 This handles machines that don't have anything on PCI Bus 0. */
198 if (dmi_get_year(DMI_BIOS_DATE) >= 2001)
199 return 1;
191 200
192 for (devfn = 0; devfn < 0x100; devfn++) { 201 for (devfn = 0; devfn < 0x100; devfn++) {
193 if (o->read(0, 0, devfn, PCI_CLASS_DEVICE, 2, &x)) 202 if (o->read(0, 0, devfn, PCI_CLASS_DEVICE, 2, &x))
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
index 3ca59cad05f3..73235443fda7 100644
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -588,7 +588,10 @@ static __init int via_router_probe(struct irq_router *r,
588 case PCI_DEVICE_ID_VIA_82C596: 588 case PCI_DEVICE_ID_VIA_82C596:
589 case PCI_DEVICE_ID_VIA_82C686: 589 case PCI_DEVICE_ID_VIA_82C686:
590 case PCI_DEVICE_ID_VIA_8231: 590 case PCI_DEVICE_ID_VIA_8231:
591 case PCI_DEVICE_ID_VIA_8233A:
591 case PCI_DEVICE_ID_VIA_8235: 592 case PCI_DEVICE_ID_VIA_8235:
593 case PCI_DEVICE_ID_VIA_8237:
594 case PCI_DEVICE_ID_VIA_8237_SATA:
592 /* FIXME: add new ones for 8233/5 */ 595 /* FIXME: add new ones for 8233/5 */
593 r->name = "VIA"; 596 r->name = "VIA";
594 r->get = pirq_via_get; 597 r->get = pirq_via_get;
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c
index 613789071f30..6b1ea0c9a570 100644
--- a/arch/i386/pci/mmconfig.c
+++ b/arch/i386/pci/mmconfig.c
@@ -12,14 +12,20 @@
12#include <linux/pci.h> 12#include <linux/pci.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/acpi.h> 14#include <linux/acpi.h>
15#include <asm/e820.h>
15#include "pci.h" 16#include "pci.h"
16 17
18#define MMCONFIG_APER_SIZE (256*1024*1024)
19
20/* Assume systems with more busses have correct MCFG */
21#define MAX_CHECK_BUS 16
22
17#define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) 23#define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG))
18 24
19/* The base address of the last MMCONFIG device accessed */ 25/* The base address of the last MMCONFIG device accessed */
20static u32 mmcfg_last_accessed_device; 26static u32 mmcfg_last_accessed_device;
21 27
22static DECLARE_BITMAP(fallback_slots, 32); 28static DECLARE_BITMAP(fallback_slots, MAX_CHECK_BUS*32);
23 29
24/* 30/*
25 * Functions for accessing PCI configuration space with MMCONFIG accesses 31 * Functions for accessing PCI configuration space with MMCONFIG accesses
@@ -29,8 +35,8 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
29 int cfg_num = -1; 35 int cfg_num = -1;
30 struct acpi_table_mcfg_config *cfg; 36 struct acpi_table_mcfg_config *cfg;
31 37
32 if (seg == 0 && bus == 0 && 38 if (seg == 0 && bus < MAX_CHECK_BUS &&
33 test_bit(PCI_SLOT(devfn), fallback_slots)) 39 test_bit(PCI_SLOT(devfn) + 32*bus, fallback_slots))
34 return 0; 40 return 0;
35 41
36 while (1) { 42 while (1) {
@@ -74,8 +80,10 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
74 unsigned long flags; 80 unsigned long flags;
75 u32 base; 81 u32 base;
76 82
77 if (!value || (bus > 255) || (devfn > 255) || (reg > 4095)) 83 if ((bus > 255) || (devfn > 255) || (reg > 4095)) {
84 *value = -1;
78 return -EINVAL; 85 return -EINVAL;
86 }
79 87
80 base = get_base_addr(seg, bus, devfn); 88 base = get_base_addr(seg, bus, devfn);
81 if (!base) 89 if (!base)
@@ -146,29 +154,34 @@ static struct pci_raw_ops pci_mmcfg = {
146 Normally this can be expressed in the MCFG by not listing them 154 Normally this can be expressed in the MCFG by not listing them
147 and assigning suitable _SEGs, but this isn't implemented in some BIOS. 155 and assigning suitable _SEGs, but this isn't implemented in some BIOS.
148 Instead try to discover all devices on bus 0 that are unreachable using MM 156 Instead try to discover all devices on bus 0 that are unreachable using MM
149 and fallback for them. 157 and fallback for them. */
150 We only do this for bus 0/seg 0 */
151static __init void unreachable_devices(void) 158static __init void unreachable_devices(void)
152{ 159{
153 int i; 160 int i, k;
154 unsigned long flags; 161 unsigned long flags;
155 162
156 for (i = 0; i < 32; i++) { 163 for (k = 0; k < MAX_CHECK_BUS; k++) {
157 u32 val1; 164 for (i = 0; i < 32; i++) {
158 u32 addr; 165 u32 val1;
159 166 u32 addr;
160 pci_conf1_read(0, 0, PCI_DEVFN(i, 0), 0, 4, &val1); 167
161 if (val1 == 0xffffffff) 168 pci_conf1_read(0, k, PCI_DEVFN(i, 0), 0, 4, &val1);
162 continue; 169 if (val1 == 0xffffffff)
163 170 continue;
164 /* Locking probably not needed, but safer */ 171
165 spin_lock_irqsave(&pci_config_lock, flags); 172 /* Locking probably not needed, but safer */
166 addr = get_base_addr(0, 0, PCI_DEVFN(i, 0)); 173 spin_lock_irqsave(&pci_config_lock, flags);
167 if (addr != 0) 174 addr = get_base_addr(0, k, PCI_DEVFN(i, 0));
168 pci_exp_set_dev_base(addr, 0, PCI_DEVFN(i, 0)); 175 if (addr != 0)
169 if (addr == 0 || readl((u32 __iomem *)mmcfg_virt_addr) != val1) 176 pci_exp_set_dev_base(addr, k, PCI_DEVFN(i, 0));
170 set_bit(i, fallback_slots); 177 if (addr == 0 ||
171 spin_unlock_irqrestore(&pci_config_lock, flags); 178 readl((u32 __iomem *)mmcfg_virt_addr) != val1) {
179 set_bit(i, fallback_slots);
180 printk(KERN_NOTICE
181 "PCI: No mmconfig possible on %x:%x\n", k, i);
182 }
183 spin_unlock_irqrestore(&pci_config_lock, flags);
184 }
172 } 185 }
173} 186}
174 187
@@ -183,6 +196,14 @@ void __init pci_mmcfg_init(void)
183 (pci_mmcfg_config[0].base_address == 0)) 196 (pci_mmcfg_config[0].base_address == 0))
184 return; 197 return;
185 198
199 if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
200 pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE,
201 E820_RESERVED)) {
202 printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n");
203 printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
204 return;
205 }
206
186 printk(KERN_INFO "PCI: Using MMCONFIG\n"); 207 printk(KERN_INFO "PCI: Using MMCONFIG\n");
187 raw_pci_ops = &pci_mmcfg; 208 raw_pci_ops = &pci_mmcfg;
188 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; 209 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index edffe25a477a..9f40eeff0b5c 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -260,15 +260,6 @@ config NR_CPUS
260 than 64 will cause the use of a CPU mask array, causing a small 260 than 64 will cause the use of a CPU mask array, causing a small
261 performance hit. 261 performance hit.
262 262
263config IA64_NR_NODES
264 int "Maximum number of NODEs (256-1024)" if (IA64_SGI_SN2 || IA64_GENERIC)
265 range 256 1024
266 depends on IA64_SGI_SN2 || IA64_GENERIC
267 default "256"
268 help
269 This option specifies the maximum number of nodes in your SSI system.
270 If in doubt, use the default.
271
272config HOTPLUG_CPU 263config HOTPLUG_CPU
273 bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" 264 bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
274 depends on SMP && EXPERIMENTAL 265 depends on SMP && EXPERIMENTAL
@@ -352,6 +343,16 @@ config NUMA
352 Access). This option is for configuring high-end multiprocessor 343 Access). This option is for configuring high-end multiprocessor
353 server systems. If in doubt, say N. 344 server systems. If in doubt, say N.
354 345
346config NODES_SHIFT
347 int "Max num nodes shift(3-10)"
348 range 3 10
349 default "8"
350 depends on NEED_MULTIPLE_NODES
351 help
352 This option specifies the maximum number of nodes in your SSI system.
353 MAX_NUMNODES will be 2^(This value).
354 If in doubt, use the default.
355
355# VIRTUAL_MEM_MAP and FLAT_NODE_MEM_MAP are functionally equivalent. 356# VIRTUAL_MEM_MAP and FLAT_NODE_MEM_MAP are functionally equivalent.
356# VIRTUAL_MEM_MAP has been retained for historical reasons. 357# VIRTUAL_MEM_MAP has been retained for historical reasons.
357config VIRTUAL_MEM_MAP 358config VIRTUAL_MEM_MAP
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index 59e871dae742..09a0dbc17fb6 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -7,7 +7,7 @@ extra-y := head.o init_task.o vmlinux.lds
7obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \ 7obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \
8 irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \ 8 irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \
9 salinfo.o semaphore.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \ 9 salinfo.o semaphore.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \
10 unwind.o mca.o mca_asm.o topology.o dmi_scan.o 10 unwind.o mca.o mca_asm.o topology.o
11 11
12obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o 12obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o
13obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o 13obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o
@@ -30,7 +30,6 @@ obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o
30obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o 30obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o
31obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o 31obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o
32mca_recovery-y += mca_drv.o mca_drv_asm.o 32mca_recovery-y += mca_drv.o mca_drv_asm.o
33dmi_scan-y += ../../i386/kernel/dmi_scan.o
34 33
35# The gate DSO image is built using a special linker script. 34# The gate DSO image is built using a special linker script.
36targets += gate.so gate-syms.o 35targets += gate.so gate-syms.o
diff --git a/arch/ia64/kernel/acpi-ext.c b/arch/ia64/kernel/acpi-ext.c
index 4a5574ff007b..fff82929d225 100644
--- a/arch/ia64/kernel/acpi-ext.c
+++ b/arch/ia64/kernel/acpi-ext.c
@@ -1,105 +1,104 @@
1/* 1/*
2 * arch/ia64/kernel/acpi-ext.c 2 * (c) Copyright 2003, 2006 Hewlett-Packard Development Company, L.P.
3 * Alex Williamson <alex.williamson@hp.com>
4 * Bjorn Helgaas <bjorn.helgaas@hp.com>
3 * 5 *
4 * Copyright (C) 2003 Hewlett-Packard 6 * This program is free software; you can redistribute it and/or modify
5 * Copyright (C) Alex Williamson 7 * it under the terms of the GNU General Public License version 2 as
6 * Copyright (C) Bjorn Helgaas 8 * published by the Free Software Foundation.
7 *
8 * Vendor specific extensions to ACPI.
9 */ 9 */
10 10
11#include <linux/config.h> 11#include <linux/config.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/types.h> 13#include <linux/types.h>
14#include <linux/acpi.h> 14#include <linux/acpi.h>
15#include <linux/efi.h>
16 15
17#include <asm/acpi-ext.h> 16#include <asm/acpi-ext.h>
18 17
19struct acpi_vendor_descriptor { 18/*
20 u8 guid_id; 19 * Device CSRs that do not appear in PCI config space should be described
21 efi_guid_t guid; 20 * via ACPI. This would normally be done with Address Space Descriptors
22}; 21 * marked as "consumer-only," but old versions of Windows and Linux ignore
22 * the producer/consumer flag, so HP invented a vendor-defined resource to
23 * describe the location and size of CSR space.
24 */
23 25
24struct acpi_vendor_info { 26struct acpi_vendor_uuid hp_ccsr_uuid = {
25 struct acpi_vendor_descriptor *descriptor; 27 .subtype = 2,
26 u8 *data; 28 .data = { 0xf9, 0xad, 0xe9, 0x69, 0x4f, 0x92, 0x5f, 0xab, 0xf6, 0x4a,
27 u32 length; 29 0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad },
28}; 30};
29 31
30acpi_status 32static acpi_status hp_ccsr_locate(acpi_handle obj, u64 *base, u64 *length)
31acpi_vendor_resource_match(struct acpi_resource *resource, void *context)
32{ 33{
33 struct acpi_vendor_info *info = (struct acpi_vendor_info *)context; 34 acpi_status status;
34 struct acpi_resource_vendor *vendor; 35 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
35 struct acpi_vendor_descriptor *descriptor; 36 struct acpi_resource *resource;
36 u32 byte_length; 37 struct acpi_resource_vendor_typed *vendor;
37
38 if (resource->type != ACPI_RESOURCE_TYPE_VENDOR)
39 return AE_OK;
40
41 vendor = (struct acpi_resource_vendor *)&resource->data;
42 descriptor = (struct acpi_vendor_descriptor *)vendor->byte_data;
43 if (vendor->byte_length <= sizeof(*info->descriptor) ||
44 descriptor->guid_id != info->descriptor->guid_id ||
45 efi_guidcmp(descriptor->guid, info->descriptor->guid))
46 return AE_OK;
47
48 byte_length = vendor->byte_length - sizeof(struct acpi_vendor_descriptor);
49 info->data = acpi_os_allocate(byte_length);
50 if (!info->data)
51 return AE_NO_MEMORY;
52
53 memcpy(info->data,
54 vendor->byte_data + sizeof(struct acpi_vendor_descriptor),
55 byte_length);
56 info->length = byte_length;
57 return AE_CTRL_TERMINATE;
58}
59 38
60acpi_status 39 status = acpi_get_vendor_resource(obj, METHOD_NAME__CRS, &hp_ccsr_uuid,
61acpi_find_vendor_resource(acpi_handle obj, struct acpi_vendor_descriptor * id, 40 &buffer);
62 u8 ** data, u32 * byte_length)
63{
64 struct acpi_vendor_info info;
65 41
66 info.descriptor = id; 42 resource = buffer.pointer;
67 info.data = NULL; 43 vendor = &resource->data.vendor_typed;
68 44
69 acpi_walk_resources(obj, METHOD_NAME__CRS, acpi_vendor_resource_match, 45 if (ACPI_FAILURE(status) || vendor->byte_length < 16) {
70 &info); 46 status = AE_NOT_FOUND;
71 if (!info.data) 47 goto exit;
72 return AE_NOT_FOUND; 48 }
73 49
74 *data = info.data; 50 memcpy(base, vendor->byte_data, sizeof(*base));
75 *byte_length = info.length; 51 memcpy(length, vendor->byte_data + 8, sizeof(*length));
76 return AE_OK; 52
53 exit:
54 acpi_os_free(buffer.pointer);
55 return status;
77} 56}
78 57
79struct acpi_vendor_descriptor hp_ccsr_descriptor = { 58struct csr_space {
80 .guid_id = 2, 59 u64 base;
81 .guid = 60 u64 length;
82 EFI_GUID(0x69e9adf9, 0x924f, 0xab5f, 0xf6, 0x4a, 0x24, 0xd2, 0x01,
83 0x37, 0x0e, 0xad)
84}; 61};
85 62
86acpi_status hp_acpi_csr_space(acpi_handle obj, u64 * csr_base, u64 * csr_length) 63static acpi_status find_csr_space(struct acpi_resource *resource, void *data)
87{ 64{
65 struct csr_space *space = data;
66 struct acpi_resource_address64 addr;
88 acpi_status status; 67 acpi_status status;
89 u8 *data;
90 u32 length;
91 68
92 status = 69 status = acpi_resource_to_address64(resource, &addr);
93 acpi_find_vendor_resource(obj, &hp_ccsr_descriptor, &data, &length); 70 if (ACPI_SUCCESS(status) &&
71 addr.resource_type == ACPI_MEMORY_RANGE &&
72 addr.address_length &&
73 addr.producer_consumer == ACPI_CONSUMER) {
74 space->base = addr.minimum;
75 space->length = addr.address_length;
76 return AE_CTRL_TERMINATE;
77 }
78 return AE_OK; /* keep looking */
79}
94 80
95 if (ACPI_FAILURE(status) || length != 16) 81static acpi_status hp_crs_locate(acpi_handle obj, u64 *base, u64 *length)
96 return AE_NOT_FOUND; 82{
83 struct csr_space space = { 0, 0 };
97 84
98 memcpy(csr_base, data, sizeof(*csr_base)); 85 acpi_walk_resources(obj, METHOD_NAME__CRS, find_csr_space, &space);
99 memcpy(csr_length, data + 8, sizeof(*csr_length)); 86 if (!space.length)
100 acpi_os_free(data); 87 return AE_NOT_FOUND;
101 88
89 *base = space.base;
90 *length = space.length;
102 return AE_OK; 91 return AE_OK;
103} 92}
104 93
94acpi_status hp_acpi_csr_space(acpi_handle obj, u64 *csr_base, u64 *csr_length)
95{
96 acpi_status status;
97
98 status = hp_ccsr_locate(obj, csr_base, csr_length);
99 if (ACPI_SUCCESS(status))
100 return status;
101
102 return hp_crs_locate(obj, csr_base, csr_length);
103}
105EXPORT_SYMBOL(hp_acpi_csr_space); 104EXPORT_SYMBOL(hp_acpi_csr_space);
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 750e8e7fbdc3..e30798811216 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1606,5 +1606,9 @@ sys_call_table:
1606 data8 sys_ni_syscall // 1295 reserved for ppoll 1606 data8 sys_ni_syscall // 1295 reserved for ppoll
1607 data8 sys_unshare 1607 data8 sys_unshare
1608 data8 sys_splice 1608 data8 sys_splice
1609 data8 sys_set_robust_list
1610 data8 sys_get_robust_list
1611 data8 sys_sync_file_range // 1300
1612 data8 sys_tee
1609 1613
1610 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls 1614 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 789881ca83d4..f9039f88d01d 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -251,7 +251,7 @@ static void __kprobes prepare_break_inst(uint template, uint slot,
251 update_kprobe_inst_flag(template, slot, major_opcode, kprobe_inst, p); 251 update_kprobe_inst_flag(template, slot, major_opcode, kprobe_inst, p);
252} 252}
253 253
254static inline void get_kprobe_inst(bundle_t *bundle, uint slot, 254static void __kprobes get_kprobe_inst(bundle_t *bundle, uint slot,
255 unsigned long *kprobe_inst, uint *major_opcode) 255 unsigned long *kprobe_inst, uint *major_opcode)
256{ 256{
257 unsigned long kprobe_inst_p0, kprobe_inst_p1; 257 unsigned long kprobe_inst_p0, kprobe_inst_p1;
@@ -278,7 +278,7 @@ static inline void get_kprobe_inst(bundle_t *bundle, uint slot,
278} 278}
279 279
280/* Returns non-zero if the addr is in the Interrupt Vector Table */ 280/* Returns non-zero if the addr is in the Interrupt Vector Table */
281static inline int in_ivt_functions(unsigned long addr) 281static int __kprobes in_ivt_functions(unsigned long addr)
282{ 282{
283 return (addr >= (unsigned long)__start_ivt_text 283 return (addr >= (unsigned long)__start_ivt_text
284 && addr < (unsigned long)__end_ivt_text); 284 && addr < (unsigned long)__end_ivt_text);
@@ -308,19 +308,19 @@ static int __kprobes valid_kprobe_addr(int template, int slot,
308 return 0; 308 return 0;
309} 309}
310 310
311static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) 311static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
312{ 312{
313 kcb->prev_kprobe.kp = kprobe_running(); 313 kcb->prev_kprobe.kp = kprobe_running();
314 kcb->prev_kprobe.status = kcb->kprobe_status; 314 kcb->prev_kprobe.status = kcb->kprobe_status;
315} 315}
316 316
317static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) 317static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
318{ 318{
319 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; 319 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
320 kcb->kprobe_status = kcb->prev_kprobe.status; 320 kcb->kprobe_status = kcb->prev_kprobe.status;
321} 321}
322 322
323static inline void set_current_kprobe(struct kprobe *p, 323static void __kprobes set_current_kprobe(struct kprobe *p,
324 struct kprobe_ctlblk *kcb) 324 struct kprobe_ctlblk *kcb)
325{ 325{
326 __get_cpu_var(current_kprobe) = p; 326 __get_cpu_var(current_kprobe) = p;
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index 8963171788d5..6a0880639bc9 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -581,10 +581,12 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs)
581{ 581{
582 unsigned long flags; 582 unsigned long flags;
583 int cpu = smp_processor_id(); 583 int cpu = smp_processor_id();
584 struct ia64_mca_notify_die nd =
585 { .sos = NULL, .monarch_cpu = &monarch_cpu };
584 586
585 /* Mask all interrupts */ 587 /* Mask all interrupts */
586 local_irq_save(flags); 588 local_irq_save(flags);
587 if (notify_die(DIE_MCA_RENDZVOUS_ENTER, "MCA", regs, 0, 0, 0) 589 if (notify_die(DIE_MCA_RENDZVOUS_ENTER, "MCA", regs, (long)&nd, 0, 0)
588 == NOTIFY_STOP) 590 == NOTIFY_STOP)
589 ia64_mca_spin(__FUNCTION__); 591 ia64_mca_spin(__FUNCTION__);
590 592
@@ -594,7 +596,7 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs)
594 */ 596 */
595 ia64_sal_mc_rendez(); 597 ia64_sal_mc_rendez();
596 598
597 if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", regs, 0, 0, 0) 599 if (notify_die(DIE_MCA_RENDZVOUS_PROCESS, "MCA", regs, (long)&nd, 0, 0)
598 == NOTIFY_STOP) 600 == NOTIFY_STOP)
599 ia64_mca_spin(__FUNCTION__); 601 ia64_mca_spin(__FUNCTION__);
600 602
@@ -602,7 +604,7 @@ ia64_mca_rendez_int_handler(int rendez_irq, void *arg, struct pt_regs *regs)
602 while (monarch_cpu != -1) 604 while (monarch_cpu != -1)
603 cpu_relax(); /* spin until monarch leaves */ 605 cpu_relax(); /* spin until monarch leaves */
604 606
605 if (notify_die(DIE_MCA_RENDZVOUS_LEAVE, "MCA", regs, 0, 0, 0) 607 if (notify_die(DIE_MCA_RENDZVOUS_LEAVE, "MCA", regs, (long)&nd, 0, 0)
606 == NOTIFY_STOP) 608 == NOTIFY_STOP)
607 ia64_mca_spin(__FUNCTION__); 609 ia64_mca_spin(__FUNCTION__);
608 610
@@ -961,7 +963,7 @@ no_mod:
961 */ 963 */
962 964
963static void 965static void
964ia64_wait_for_slaves(int monarch) 966ia64_wait_for_slaves(int monarch, const char *type)
965{ 967{
966 int c, wait = 0, missing = 0; 968 int c, wait = 0, missing = 0;
967 for_each_online_cpu(c) { 969 for_each_online_cpu(c) {
@@ -987,7 +989,7 @@ ia64_wait_for_slaves(int monarch)
987 } 989 }
988 if (!missing) 990 if (!missing)
989 goto all_in; 991 goto all_in;
990 printk(KERN_INFO "OS MCA slave did not rendezvous on cpu"); 992 printk(KERN_INFO "OS %s slave did not rendezvous on cpu", type);
991 for_each_online_cpu(c) { 993 for_each_online_cpu(c) {
992 if (c == monarch) 994 if (c == monarch)
993 continue; 995 continue;
@@ -998,7 +1000,7 @@ ia64_wait_for_slaves(int monarch)
998 return; 1000 return;
999 1001
1000all_in: 1002all_in:
1001 printk(KERN_INFO "All OS MCA slaves have reached rendezvous\n"); 1003 printk(KERN_INFO "All OS %s slaves have reached rendezvous\n", type);
1002 return; 1004 return;
1003} 1005}
1004 1006
@@ -1023,6 +1025,8 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
1023 &sos->proc_state_param; 1025 &sos->proc_state_param;
1024 int recover, cpu = smp_processor_id(); 1026 int recover, cpu = smp_processor_id();
1025 task_t *previous_current; 1027 task_t *previous_current;
1028 struct ia64_mca_notify_die nd =
1029 { .sos = sos, .monarch_cpu = &monarch_cpu };
1026 1030
1027 oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ 1031 oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */
1028 console_loglevel = 15; /* make sure printks make it to console */ 1032 console_loglevel = 15; /* make sure printks make it to console */
@@ -1031,10 +1035,10 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
1031 1035
1032 previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA"); 1036 previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA");
1033 monarch_cpu = cpu; 1037 monarch_cpu = cpu;
1034 if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, 0, 0, 0) 1038 if (notify_die(DIE_MCA_MONARCH_ENTER, "MCA", regs, (long)&nd, 0, 0)
1035 == NOTIFY_STOP) 1039 == NOTIFY_STOP)
1036 ia64_mca_spin(__FUNCTION__); 1040 ia64_mca_spin(__FUNCTION__);
1037 ia64_wait_for_slaves(cpu); 1041 ia64_wait_for_slaves(cpu, "MCA");
1038 1042
1039 /* Wakeup all the processors which are spinning in the rendezvous loop. 1043 /* Wakeup all the processors which are spinning in the rendezvous loop.
1040 * They will leave SAL, then spin in the OS with interrupts disabled 1044 * They will leave SAL, then spin in the OS with interrupts disabled
@@ -1043,7 +1047,7 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
1043 * spinning in SAL does not work. 1047 * spinning in SAL does not work.
1044 */ 1048 */
1045 ia64_mca_wakeup_all(); 1049 ia64_mca_wakeup_all();
1046 if (notify_die(DIE_MCA_MONARCH_PROCESS, "MCA", regs, 0, 0, 0) 1050 if (notify_die(DIE_MCA_MONARCH_PROCESS, "MCA", regs, (long)&nd, 0, 0)
1047 == NOTIFY_STOP) 1051 == NOTIFY_STOP)
1048 ia64_mca_spin(__FUNCTION__); 1052 ia64_mca_spin(__FUNCTION__);
1049 1053
@@ -1064,7 +1068,7 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
1064 ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA); 1068 ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA);
1065 sos->os_status = IA64_MCA_CORRECTED; 1069 sos->os_status = IA64_MCA_CORRECTED;
1066 } 1070 }
1067 if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, 0, 0, recover) 1071 if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, (long)&nd, 0, recover)
1068 == NOTIFY_STOP) 1072 == NOTIFY_STOP)
1069 ia64_mca_spin(__FUNCTION__); 1073 ia64_mca_spin(__FUNCTION__);
1070 1074
@@ -1351,10 +1355,14 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
1351 static atomic_t monarchs; 1355 static atomic_t monarchs;
1352 task_t *previous_current; 1356 task_t *previous_current;
1353 int cpu = smp_processor_id(); 1357 int cpu = smp_processor_id();
1358 struct ia64_mca_notify_die nd =
1359 { .sos = sos, .monarch_cpu = &monarch_cpu };
1354 1360
1355 oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ 1361 oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */
1356 console_loglevel = 15; /* make sure printks make it to console */ 1362 console_loglevel = 15; /* make sure printks make it to console */
1357 1363
1364 (void) notify_die(DIE_INIT_ENTER, "INIT", regs, (long)&nd, 0, 0);
1365
1358 printk(KERN_INFO "Entered OS INIT handler. PSP=%lx cpu=%d monarch=%ld\n", 1366 printk(KERN_INFO "Entered OS INIT handler. PSP=%lx cpu=%d monarch=%ld\n",
1359 sos->proc_state_param, cpu, sos->monarch); 1367 sos->proc_state_param, cpu, sos->monarch);
1360 salinfo_log_wakeup(SAL_INFO_TYPE_INIT, NULL, 0, 0); 1368 salinfo_log_wakeup(SAL_INFO_TYPE_INIT, NULL, 0, 0);
@@ -1390,15 +1398,15 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
1390 ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT; 1398 ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_INIT;
1391 while (monarch_cpu == -1) 1399 while (monarch_cpu == -1)
1392 cpu_relax(); /* spin until monarch enters */ 1400 cpu_relax(); /* spin until monarch enters */
1393 if (notify_die(DIE_INIT_SLAVE_ENTER, "INIT", regs, 0, 0, 0) 1401 if (notify_die(DIE_INIT_SLAVE_ENTER, "INIT", regs, (long)&nd, 0, 0)
1394 == NOTIFY_STOP) 1402 == NOTIFY_STOP)
1395 ia64_mca_spin(__FUNCTION__); 1403 ia64_mca_spin(__FUNCTION__);
1396 if (notify_die(DIE_INIT_SLAVE_PROCESS, "INIT", regs, 0, 0, 0) 1404 if (notify_die(DIE_INIT_SLAVE_PROCESS, "INIT", regs, (long)&nd, 0, 0)
1397 == NOTIFY_STOP) 1405 == NOTIFY_STOP)
1398 ia64_mca_spin(__FUNCTION__); 1406 ia64_mca_spin(__FUNCTION__);
1399 while (monarch_cpu != -1) 1407 while (monarch_cpu != -1)
1400 cpu_relax(); /* spin until monarch leaves */ 1408 cpu_relax(); /* spin until monarch leaves */
1401 if (notify_die(DIE_INIT_SLAVE_LEAVE, "INIT", regs, 0, 0, 0) 1409 if (notify_die(DIE_INIT_SLAVE_LEAVE, "INIT", regs, (long)&nd, 0, 0)
1402 == NOTIFY_STOP) 1410 == NOTIFY_STOP)
1403 ia64_mca_spin(__FUNCTION__); 1411 ia64_mca_spin(__FUNCTION__);
1404 printk("Slave on cpu %d returning to normal service.\n", cpu); 1412 printk("Slave on cpu %d returning to normal service.\n", cpu);
@@ -1409,7 +1417,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
1409 } 1417 }
1410 1418
1411 monarch_cpu = cpu; 1419 monarch_cpu = cpu;
1412 if (notify_die(DIE_INIT_MONARCH_ENTER, "INIT", regs, 0, 0, 0) 1420 if (notify_die(DIE_INIT_MONARCH_ENTER, "INIT", regs, (long)&nd, 0, 0)
1413 == NOTIFY_STOP) 1421 == NOTIFY_STOP)
1414 ia64_mca_spin(__FUNCTION__); 1422 ia64_mca_spin(__FUNCTION__);
1415 1423
@@ -1421,15 +1429,15 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
1421 */ 1429 */
1422 printk("Delaying for 5 seconds...\n"); 1430 printk("Delaying for 5 seconds...\n");
1423 udelay(5*1000000); 1431 udelay(5*1000000);
1424 ia64_wait_for_slaves(cpu); 1432 ia64_wait_for_slaves(cpu, "INIT");
1425 /* If nobody intercepts DIE_INIT_MONARCH_PROCESS then we drop through 1433 /* If nobody intercepts DIE_INIT_MONARCH_PROCESS then we drop through
1426 * to default_monarch_init_process() above and just print all the 1434 * to default_monarch_init_process() above and just print all the
1427 * tasks. 1435 * tasks.
1428 */ 1436 */
1429 if (notify_die(DIE_INIT_MONARCH_PROCESS, "INIT", regs, 0, 0, 0) 1437 if (notify_die(DIE_INIT_MONARCH_PROCESS, "INIT", regs, (long)&nd, 0, 0)
1430 == NOTIFY_STOP) 1438 == NOTIFY_STOP)
1431 ia64_mca_spin(__FUNCTION__); 1439 ia64_mca_spin(__FUNCTION__);
1432 if (notify_die(DIE_INIT_MONARCH_LEAVE, "INIT", regs, 0, 0, 0) 1440 if (notify_die(DIE_INIT_MONARCH_LEAVE, "INIT", regs, (long)&nd, 0, 0)
1433 == NOTIFY_STOP) 1441 == NOTIFY_STOP)
1434 ia64_mca_spin(__FUNCTION__); 1442 ia64_mca_spin(__FUNCTION__);
1435 printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu); 1443 printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu);
@@ -1631,6 +1639,7 @@ ia64_mca_init(void)
1631 printk(KERN_INFO "Increasing MCA rendezvous timeout from " 1639 printk(KERN_INFO "Increasing MCA rendezvous timeout from "
1632 "%ld to %ld milliseconds\n", timeout, isrv.v0); 1640 "%ld to %ld milliseconds\n", timeout, isrv.v0);
1633 timeout = isrv.v0; 1641 timeout = isrv.v0;
1642 (void) notify_die(DIE_MCA_NEW_TIMEOUT, "MCA", NULL, timeout, 0, 0);
1634 continue; 1643 continue;
1635 } 1644 }
1636 printk(KERN_ERR "Failed to register rendezvous interrupt " 1645 printk(KERN_ERR "Failed to register rendezvous interrupt "
diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S
index 60a464bfd9e2..6dff024cd62b 100644
--- a/arch/ia64/kernel/mca_asm.S
+++ b/arch/ia64/kernel/mca_asm.S
@@ -827,7 +827,7 @@ ia64_state_restore:
827 ld8 r9=[temp2],16 // sal_gp 827 ld8 r9=[temp2],16 // sal_gp
828 ;; 828 ;;
829 ld8 r22=[temp1],16 // pal_min_state, virtual 829 ld8 r22=[temp1],16 // pal_min_state, virtual
830 ld8 r21=[temp2],16 // prev_IA64_KR_CURRENT 830 ld8 r13=[temp2],16 // prev_IA64_KR_CURRENT
831 ;; 831 ;;
832 ld8 r16=[temp1],16 // prev_IA64_KR_CURRENT_STACK 832 ld8 r16=[temp1],16 // prev_IA64_KR_CURRENT_STACK
833 ld8 r20=[temp2],16 // prev_task 833 ld8 r20=[temp2],16 // prev_task
@@ -848,7 +848,7 @@ ia64_state_restore:
848 mov cr.iim=temp3 848 mov cr.iim=temp3
849 mov cr.iha=temp4 849 mov cr.iha=temp4
850 dep r22=0,r22,62,1 // pal_min_state, physical, uncached 850 dep r22=0,r22,62,1 // pal_min_state, physical, uncached
851 mov IA64_KR(CURRENT)=r21 851 mov IA64_KR(CURRENT)=r13
852 ld8 r8=[temp1] // os_status 852 ld8 r8=[temp1] // os_status
853 ld8 r10=[temp2] // context 853 ld8 r10=[temp2] // context
854 854
@@ -856,7 +856,7 @@ ia64_state_restore:
856 * avoid any dependencies on the algorithm in ia64_switch_to(), just 856 * avoid any dependencies on the algorithm in ia64_switch_to(), just
857 * purge any existing CURRENT_STACK mapping and insert the new one. 857 * purge any existing CURRENT_STACK mapping and insert the new one.
858 * 858 *
859 * r16 contains prev_IA64_KR_CURRENT_STACK, r21 contains 859 * r16 contains prev_IA64_KR_CURRENT_STACK, r13 contains
860 * prev_IA64_KR_CURRENT, these values may have been changed by the C 860 * prev_IA64_KR_CURRENT, these values may have been changed by the C
861 * code. Do not use r8, r9, r10, r22, they contain values ready for 861 * code. Do not use r8, r9, r10, r22, they contain values ready for
862 * the return to SAL. 862 * the return to SAL.
@@ -873,7 +873,7 @@ ia64_state_restore:
873 ;; 873 ;;
874 srlz.d 874 srlz.d
875 875
876 extr.u r19=r21,61,3 // r21 = prev_IA64_KR_CURRENT 876 extr.u r19=r13,61,3 // r13 = prev_IA64_KR_CURRENT
877 shl r20=r16,IA64_GRANULE_SHIFT // r16 = prev_IA64_KR_CURRENT_STACK 877 shl r20=r16,IA64_GRANULE_SHIFT // r16 = prev_IA64_KR_CURRENT_STACK
878 movl r21=PAGE_KERNEL // page properties 878 movl r21=PAGE_KERNEL // page properties
879 ;; 879 ;;
@@ -883,7 +883,7 @@ ia64_state_restore:
883(p6) br.spnt 1f // the dreaded cpu 0 idle task in region 5:( 883(p6) br.spnt 1f // the dreaded cpu 0 idle task in region 5:(
884 ;; 884 ;;
885 mov cr.itir=r18 885 mov cr.itir=r18
886 mov cr.ifa=r21 886 mov cr.ifa=r13
887 mov r20=IA64_TR_CURRENT_STACK 887 mov r20=IA64_TR_CURRENT_STACK
888 ;; 888 ;;
889 itr.d dtr[r20]=r21 889 itr.d dtr[r20]=r21
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
index 7a2f0a798d12..3a30cfc9574f 100644
--- a/arch/ia64/kernel/module.c
+++ b/arch/ia64/kernel/module.c
@@ -947,7 +947,7 @@ void
947percpu_modcopy (void *pcpudst, const void *src, unsigned long size) 947percpu_modcopy (void *pcpudst, const void *src, unsigned long size)
948{ 948{
949 unsigned int i; 949 unsigned int i;
950 for_each_cpu(i) { 950 for_each_possible_cpu(i) {
951 memcpy(pcpudst + __per_cpu_offset[i], src, size); 951 memcpy(pcpudst + __per_cpu_offset[i], src, size);
952 } 952 }
953} 953}
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index ec9eeb89975d..b6bcc9fa3603 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -519,6 +519,68 @@ void __cpuinit *per_cpu_init(void)
519} 519}
520#endif /* CONFIG_SMP */ 520#endif /* CONFIG_SMP */
521 521
522#ifdef CONFIG_VIRTUAL_MEM_MAP
523static inline int find_next_valid_pfn_for_pgdat(pg_data_t *pgdat, int i)
524{
525 unsigned long end_address, hole_next_pfn;
526 unsigned long stop_address;
527
528 end_address = (unsigned long) &vmem_map[pgdat->node_start_pfn + i];
529 end_address = PAGE_ALIGN(end_address);
530
531 stop_address = (unsigned long) &vmem_map[
532 pgdat->node_start_pfn + pgdat->node_spanned_pages];
533
534 do {
535 pgd_t *pgd;
536 pud_t *pud;
537 pmd_t *pmd;
538 pte_t *pte;
539
540 pgd = pgd_offset_k(end_address);
541 if (pgd_none(*pgd)) {
542 end_address += PGDIR_SIZE;
543 continue;
544 }
545
546 pud = pud_offset(pgd, end_address);
547 if (pud_none(*pud)) {
548 end_address += PUD_SIZE;
549 continue;
550 }
551
552 pmd = pmd_offset(pud, end_address);
553 if (pmd_none(*pmd)) {
554 end_address += PMD_SIZE;
555 continue;
556 }
557
558 pte = pte_offset_kernel(pmd, end_address);
559retry_pte:
560 if (pte_none(*pte)) {
561 end_address += PAGE_SIZE;
562 pte++;
563 if ((end_address < stop_address) &&
564 (end_address != ALIGN(end_address, 1UL << PMD_SHIFT)))
565 goto retry_pte;
566 continue;
567 }
568 /* Found next valid vmem_map page */
569 break;
570 } while (end_address < stop_address);
571
572 end_address = min(end_address, stop_address);
573 end_address = end_address - (unsigned long) vmem_map + sizeof(struct page) - 1;
574 hole_next_pfn = end_address / sizeof(struct page);
575 return hole_next_pfn - pgdat->node_start_pfn;
576}
577#else
578static inline int find_next_valid_pfn_for_pgdat(pg_data_t *pgdat, int i)
579{
580 return i + 1;
581}
582#endif
583
522/** 584/**
523 * show_mem - give short summary of memory stats 585 * show_mem - give short summary of memory stats
524 * 586 *
@@ -547,8 +609,10 @@ void show_mem(void)
547 struct page *page; 609 struct page *page;
548 if (pfn_valid(pgdat->node_start_pfn + i)) 610 if (pfn_valid(pgdat->node_start_pfn + i))
549 page = pfn_to_page(pgdat->node_start_pfn + i); 611 page = pfn_to_page(pgdat->node_start_pfn + i);
550 else 612 else {
613 i = find_next_valid_pfn_for_pgdat(pgdat, i) - 1;
551 continue; 614 continue;
615 }
552 if (PageReserved(page)) 616 if (PageReserved(page))
553 reserved++; 617 reserved++;
554 else if (PageSwapCache(page)) 618 else if (PageSwapCache(page))
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index af7eb087dca7..d98ec49570b8 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -60,6 +60,9 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
60 struct siginfo si; 60 struct siginfo si;
61 unsigned long mask; 61 unsigned long mask;
62 62
63 /* mmap_sem is performance critical.... */
64 prefetchw(&mm->mmap_sem);
65
63 /* 66 /*
64 * If we're in an interrupt or have no user context, we must not take the fault.. 67 * If we're in an interrupt or have no user context, we must not take the fault..
65 */ 68 */
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c
index d0abddd9ffe6..8255a9be4632 100644
--- a/arch/ia64/sn/kernel/xpc_channel.c
+++ b/arch/ia64/sn/kernel/xpc_channel.c
@@ -1831,7 +1831,7 @@ xpc_initiate_allocate(partid_t partid, int ch_number, u32 flags, void **payload)
1831{ 1831{
1832 struct xpc_partition *part = &xpc_partitions[partid]; 1832 struct xpc_partition *part = &xpc_partitions[partid];
1833 enum xpc_retval ret = xpcUnknownReason; 1833 enum xpc_retval ret = xpcUnknownReason;
1834 struct xpc_msg *msg; 1834 struct xpc_msg *msg = NULL;
1835 1835
1836 1836
1837 DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); 1837 DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS);
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index 05c864c6c2d9..41fd490af3b4 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -285,6 +285,11 @@ config NUMA
285 depends on SMP && BROKEN 285 depends on SMP && BROKEN
286 default n 286 default n
287 287
288config NODES_SHIFT
289 int
290 default "1"
291 depends on NEED_MULTIPLE_NODES
292
288# turning this on wastes a bunch of space. 293# turning this on wastes a bunch of space.
289# Summit needs it only when NUMA is on 294# Summit needs it only when NUMA is on
290config BOOT_IOREMAP 295config BOOT_IOREMAP
diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S
index 3871b65f0c82..920bb742b7a2 100644
--- a/arch/m32r/kernel/entry.S
+++ b/arch/m32r/kernel/entry.S
@@ -20,7 +20,7 @@
20 * Stack layout in 'ret_from_system_call': 20 * Stack layout in 'ret_from_system_call':
21 * ptrace needs to have all regs on the stack. 21 * ptrace needs to have all regs on the stack.
22 * if the order here is changed, it needs to be 22 * if the order here is changed, it needs to be
23 * updated in fork.c:copy_process, signal.c:do_signal, 23 * updated in fork.c:copy_thread, signal.c:do_signal,
24 * ptrace.c and ptrace.h 24 * ptrace.c and ptrace.h
25 * 25 *
26 * M32Rx/M32R2 M32R 26 * M32Rx/M32R2 M32R
@@ -41,18 +41,17 @@
41 * @(0x38,sp) - syscall_nr ditto 41 * @(0x38,sp) - syscall_nr ditto
42 * @(0x3c,sp) - acc0h @(0x3c,sp) - acch 42 * @(0x3c,sp) - acc0h @(0x3c,sp) - acch
43 * @(0x40,sp) - acc0l @(0x40,sp) - accl 43 * @(0x40,sp) - acc0l @(0x40,sp) - accl
44 * @(0x44,sp) - acc1h @(0x44,sp) - psw 44 * @(0x44,sp) - acc1h @(0x44,sp) - dummy_acc1h
45 * @(0x48,sp) - acc1l @(0x48,sp) - bpc 45 * @(0x48,sp) - acc1l @(0x48,sp) - dummy_acc1l
46 * @(0x4c,sp) - psw @(0x4c,sp) - bbpsw 46 * @(0x4c,sp) - psw ditto
47 * @(0x50,sp) - bpc @(0x50,sp) - bbpc 47 * @(0x50,sp) - bpc ditto
48 * @(0x54,sp) - bbpsw @(0x54,sp) - spu (cr3) 48 * @(0x54,sp) - bbpsw ditto
49 * @(0x58,sp) - bbpc @(0x58,sp) - fp (r13) 49 * @(0x58,sp) - bbpc ditto
50 * @(0x5c,sp) - spu (cr3) @(0x5c,sp) - lr (r14) 50 * @(0x5c,sp) - spu (cr3) ditto
51 * @(0x60,sp) - fp (r13) @(0x60,sp) - spi (cr12) 51 * @(0x60,sp) - fp (r13) ditto
52 * @(0x64,sp) - lr (r14) @(0x64,sp) - orig_r0 52 * @(0x64,sp) - lr (r14) ditto
53 * @(0x68,sp) - spi (cr2) 53 * @(0x68,sp) - spi (cr2) ditto
54 * @(0x6c,sp) - orig_r0 54 * @(0x6c,sp) - orig_r0 ditto
55 *
56 */ 55 */
57 56
58#include <linux/config.h> 57#include <linux/config.h>
@@ -102,6 +101,12 @@
102#define ACC0L(reg) @(0x40,reg) 101#define ACC0L(reg) @(0x40,reg)
103#define ACC1H(reg) @(0x44,reg) 102#define ACC1H(reg) @(0x44,reg)
104#define ACC1L(reg) @(0x48,reg) 103#define ACC1L(reg) @(0x48,reg)
104#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
105#define ACCH(reg) @(0x3C,reg)
106#define ACCL(reg) @(0x40,reg)
107#else
108#error unknown isa configuration
109#endif
105#define PSW(reg) @(0x4C,reg) 110#define PSW(reg) @(0x4C,reg)
106#define BPC(reg) @(0x50,reg) 111#define BPC(reg) @(0x50,reg)
107#define BBPSW(reg) @(0x54,reg) 112#define BBPSW(reg) @(0x54,reg)
@@ -111,21 +116,6 @@
111#define LR(reg) @(0x64,reg) 116#define LR(reg) @(0x64,reg)
112#define SP(reg) @(0x68,reg) 117#define SP(reg) @(0x68,reg)
113#define ORIG_R0(reg) @(0x6C,reg) 118#define ORIG_R0(reg) @(0x6C,reg)
114#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
115#define ACCH(reg) @(0x3C,reg)
116#define ACCL(reg) @(0x40,reg)
117#define PSW(reg) @(0x44,reg)
118#define BPC(reg) @(0x48,reg)
119#define BBPSW(reg) @(0x4C,reg)
120#define BBPC(reg) @(0x50,reg)
121#define SPU(reg) @(0x54,reg)
122#define FP(reg) @(0x58,reg) /* FP = R13 */
123#define LR(reg) @(0x5C,reg)
124#define SP(reg) @(0x60,reg)
125#define ORIG_R0(reg) @(0x64,reg)
126#else
127#error unknown isa configuration
128#endif
129 119
130CF_MASK = 0x00000001 120CF_MASK = 0x00000001
131TF_MASK = 0x00000100 121TF_MASK = 0x00000100
@@ -142,7 +132,7 @@ VM_MASK = 0x00020000
142#endif 132#endif
143 133
144ENTRY(ret_from_fork) 134ENTRY(ret_from_fork)
145 ld r0, @sp+ 135 pop r0
146 bl schedule_tail 136 bl schedule_tail
147 GET_THREAD_INFO(r8) 137 GET_THREAD_INFO(r8)
148 bra syscall_exit 138 bra syscall_exit
@@ -231,7 +221,7 @@ restore_all:
231 RESTORE_ALL 221 RESTORE_ALL
232 222
233 # perform work that needs to be done immediately before resumption 223 # perform work that needs to be done immediately before resumption
234 # r9 : frags 224 # r9 : flags
235 ALIGN 225 ALIGN
236work_pending: 226work_pending:
237 and3 r4, r9, #_TIF_NEED_RESCHED 227 and3 r4, r9, #_TIF_NEED_RESCHED
@@ -320,7 +310,7 @@ ENTRY(ei_handler)
320; GET_ICU_STATUS; 310; GET_ICU_STATUS;
321 seth r0, #shigh(M32R_ICU_ISTS_ADDR) 311 seth r0, #shigh(M32R_ICU_ISTS_ADDR)
322 ld r0, @(low(M32R_ICU_ISTS_ADDR),r0) 312 ld r0, @(low(M32R_ICU_ISTS_ADDR),r0)
323 st r0, @-sp 313 push r0
324#if defined(CONFIG_SMP) 314#if defined(CONFIG_SMP)
325 /* 315 /*
326 * If IRQ == 0 --> Nothing to do, Not write IMASK 316 * If IRQ == 0 --> Nothing to do, Not write IMASK
@@ -557,7 +547,7 @@ check_end:
557#endif /* CONFIG_PLAT_M32104UT */ 547#endif /* CONFIG_PLAT_M32104UT */
558 bl do_IRQ 548 bl do_IRQ
559#endif /* CONFIG_SMP */ 549#endif /* CONFIG_SMP */
560 ld r14, @sp+ 550 pop r14
561 seth r0, #shigh(M32R_ICU_IMASK_ADDR) 551 seth r0, #shigh(M32R_ICU_IMASK_ADDR)
562 st r14, @(low(M32R_ICU_IMASK_ADDR),r0) 552 st r14, @(low(M32R_ICU_IMASK_ADDR),r0)
563#else 553#else
@@ -1015,4 +1005,3 @@ ENTRY(sys_call_table)
1015 .long sys_waitid 1005 .long sys_waitid
1016 1006
1017syscall_table_size=(.-sys_call_table) 1007syscall_table_size=(.-sys_call_table)
1018
diff --git a/arch/m32r/kernel/m32r_ksyms.c b/arch/m32r/kernel/m32r_ksyms.c
index be8b711367ec..c50330fa83b9 100644
--- a/arch/m32r/kernel/m32r_ksyms.c
+++ b/arch/m32r/kernel/m32r_ksyms.c
@@ -23,9 +23,6 @@ EXPORT_SYMBOL(boot_cpu_data);
23EXPORT_SYMBOL(dump_fpu); 23EXPORT_SYMBOL(dump_fpu);
24EXPORT_SYMBOL(__ioremap); 24EXPORT_SYMBOL(__ioremap);
25EXPORT_SYMBOL(iounmap); 25EXPORT_SYMBOL(iounmap);
26EXPORT_SYMBOL(enable_irq);
27EXPORT_SYMBOL(disable_irq);
28EXPORT_SYMBOL(disable_irq_nosync);
29EXPORT_SYMBOL(kernel_thread); 26EXPORT_SYMBOL(kernel_thread);
30EXPORT_SYMBOL(__down); 27EXPORT_SYMBOL(__down);
31EXPORT_SYMBOL(__down_interruptible); 28EXPORT_SYMBOL(__down_interruptible);
@@ -38,13 +35,6 @@ EXPORT_SYMBOL(__udelay);
38EXPORT_SYMBOL(__delay); 35EXPORT_SYMBOL(__delay);
39EXPORT_SYMBOL(__const_udelay); 36EXPORT_SYMBOL(__const_udelay);
40 37
41EXPORT_SYMBOL(__get_user_1);
42EXPORT_SYMBOL(__get_user_2);
43EXPORT_SYMBOL(__get_user_4);
44
45EXPORT_SYMBOL(strpbrk);
46EXPORT_SYMBOL(strstr);
47
48EXPORT_SYMBOL(strncpy_from_user); 38EXPORT_SYMBOL(strncpy_from_user);
49EXPORT_SYMBOL(__strncpy_from_user); 39EXPORT_SYMBOL(__strncpy_from_user);
50EXPORT_SYMBOL(clear_user); 40EXPORT_SYMBOL(clear_user);
@@ -59,11 +49,8 @@ extern void *dcache_dummy;
59EXPORT_SYMBOL(dcache_dummy); 49EXPORT_SYMBOL(dcache_dummy);
60#endif 50#endif
61EXPORT_SYMBOL(cpu_data); 51EXPORT_SYMBOL(cpu_data);
62EXPORT_SYMBOL(cpu_online_map);
63EXPORT_SYMBOL(cpu_callout_map);
64 52
65/* Global SMP stuff */ 53/* Global SMP stuff */
66EXPORT_SYMBOL(synchronize_irq);
67EXPORT_SYMBOL(smp_call_function); 54EXPORT_SYMBOL(smp_call_function);
68 55
69/* TLB flushing */ 56/* TLB flushing */
@@ -83,27 +70,11 @@ EXPORT_SYMBOL(__lshrdi3);
83EXPORT_SYMBOL(__muldi3); 70EXPORT_SYMBOL(__muldi3);
84 71
85/* memory and string operations */ 72/* memory and string operations */
86EXPORT_SYMBOL(memchr);
87EXPORT_SYMBOL(memcpy); 73EXPORT_SYMBOL(memcpy);
88/* EXPORT_SYMBOL(memcpy_fromio); // not implement yet */
89/* EXPORT_SYMBOL(memcpy_toio); // not implement yet */
90EXPORT_SYMBOL(memset); 74EXPORT_SYMBOL(memset);
91/* EXPORT_SYMBOL(memset_io); // not implement yet */
92EXPORT_SYMBOL(memmove);
93EXPORT_SYMBOL(memcmp);
94EXPORT_SYMBOL(memscan);
95EXPORT_SYMBOL(copy_page); 75EXPORT_SYMBOL(copy_page);
96EXPORT_SYMBOL(clear_page); 76EXPORT_SYMBOL(clear_page);
97
98EXPORT_SYMBOL(strcat);
99EXPORT_SYMBOL(strchr);
100EXPORT_SYMBOL(strcmp);
101EXPORT_SYMBOL(strcpy);
102EXPORT_SYMBOL(strlen); 77EXPORT_SYMBOL(strlen);
103EXPORT_SYMBOL(strncat);
104EXPORT_SYMBOL(strncmp);
105EXPORT_SYMBOL(strnlen);
106EXPORT_SYMBOL(strncpy);
107 78
108EXPORT_SYMBOL(_inb); 79EXPORT_SYMBOL(_inb);
109EXPORT_SYMBOL(_inw); 80EXPORT_SYMBOL(_inw);
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c
index 5dfc7ea45cf7..065f5e719058 100644
--- a/arch/m32r/kernel/process.c
+++ b/arch/m32r/kernel/process.c
@@ -116,6 +116,10 @@ void cpu_idle (void)
116 116
117void machine_restart(char *__unused) 117void machine_restart(char *__unused)
118{ 118{
119#if defined(CONFIG_PLAT_MAPPI3)
120 outw(1, (unsigned long)PLD_REBOOT);
121#endif
122
119 printk("Please push reset button!\n"); 123 printk("Please push reset button!\n");
120 while (1) 124 while (1)
121 cpu_relax(); 125 cpu_relax();
diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c
index 0d78942b4c76..3cd3c2988a48 100644
--- a/arch/m32r/kernel/setup.c
+++ b/arch/m32r/kernel/setup.c
@@ -9,6 +9,7 @@
9 9
10#include <linux/config.h> 10#include <linux/config.h>
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/kernel.h>
12#include <linux/stddef.h> 13#include <linux/stddef.h>
13#include <linux/fs.h> 14#include <linux/fs.h>
14#include <linux/sched.h> 15#include <linux/sched.h>
@@ -219,8 +220,6 @@ static unsigned long __init setup_memory(void)
219extern unsigned long setup_memory(void); 220extern unsigned long setup_memory(void);
220#endif /* CONFIG_DISCONTIGMEM */ 221#endif /* CONFIG_DISCONTIGMEM */
221 222
222#define M32R_PCC_PCATCR 0x00ef7014 /* will move to m32r.h */
223
224void __init setup_arch(char **cmdline_p) 223void __init setup_arch(char **cmdline_p)
225{ 224{
226 ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); 225 ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
@@ -269,15 +268,14 @@ void __init setup_arch(char **cmdline_p)
269 paging_init(); 268 paging_init();
270} 269}
271 270
272static struct cpu cpu[NR_CPUS]; 271static struct cpu cpu_devices[NR_CPUS];
273 272
274static int __init topology_init(void) 273static int __init topology_init(void)
275{ 274{
276 int cpu_id; 275 int i;
277 276
278 for (cpu_id = 0; cpu_id < NR_CPUS; cpu_id++) 277 for_each_present_cpu(i)
279 if (cpu_possible(cpu_id)) 278 register_cpu(&cpu_devices[i], i, NULL);
280 register_cpu(&cpu[cpu_id], cpu_id, NULL);
281 279
282 return 0; 280 return 0;
283} 281}
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index cb33097fefc4..6498ee70bb73 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -118,6 +118,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
118#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) 118#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
119 COPY(acch); 119 COPY(acch);
120 COPY(accl); 120 COPY(accl);
121 COPY(dummy_acc1h);
122 COPY(dummy_acc1l);
121#else 123#else
122#error unknown isa configuration 124#error unknown isa configuration
123#endif 125#endif
@@ -203,6 +205,8 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
203#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) 205#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
204 COPY(acch); 206 COPY(acch);
205 COPY(accl); 207 COPY(accl);
208 COPY(dummy_acc1h);
209 COPY(dummy_acc1l);
206#else 210#else
207#error unknown isa configuration 211#error unknown isa configuration
208#endif 212#endif
diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c
index d7ec16e7fb25..840b4348bf0c 100644
--- a/arch/m32r/kernel/smpboot.c
+++ b/arch/m32r/kernel/smpboot.c
@@ -39,8 +39,10 @@
39 * Martin J. Bligh : Added support for multi-quad systems 39 * Martin J. Bligh : Added support for multi-quad systems
40 */ 40 */
41 41
42#include <linux/module.h>
42#include <linux/config.h> 43#include <linux/config.h>
43#include <linux/init.h> 44#include <linux/init.h>
45#include <linux/kernel.h>
44#include <linux/mm.h> 46#include <linux/mm.h>
45#include <linux/smp_lock.h> 47#include <linux/smp_lock.h>
46#include <linux/irq.h> 48#include <linux/irq.h>
@@ -72,11 +74,15 @@ physid_mask_t phys_cpu_present_map;
72 74
73/* Bitmask of currently online CPUs */ 75/* Bitmask of currently online CPUs */
74cpumask_t cpu_online_map; 76cpumask_t cpu_online_map;
77EXPORT_SYMBOL(cpu_online_map);
75 78
76cpumask_t cpu_bootout_map; 79cpumask_t cpu_bootout_map;
77cpumask_t cpu_bootin_map; 80cpumask_t cpu_bootin_map;
78cpumask_t cpu_callout_map;
79static cpumask_t cpu_callin_map; 81static cpumask_t cpu_callin_map;
82cpumask_t cpu_callout_map;
83EXPORT_SYMBOL(cpu_callout_map);
84cpumask_t cpu_possible_map = CPU_MASK_ALL;
85EXPORT_SYMBOL(cpu_possible_map);
80 86
81/* Per CPU bogomips and other parameters */ 87/* Per CPU bogomips and other parameters */
82struct cpuinfo_m32r cpu_data[NR_CPUS] __cacheline_aligned; 88struct cpuinfo_m32r cpu_data[NR_CPUS] __cacheline_aligned;
@@ -110,7 +116,6 @@ static unsigned int calibration_result;
110 116
111void smp_prepare_boot_cpu(void); 117void smp_prepare_boot_cpu(void);
112void smp_prepare_cpus(unsigned int); 118void smp_prepare_cpus(unsigned int);
113static void smp_tune_scheduling(void);
114static void init_ipi_lock(void); 119static void init_ipi_lock(void);
115static void do_boot_cpu(int); 120static void do_boot_cpu(int);
116int __cpu_up(unsigned int); 121int __cpu_up(unsigned int);
@@ -177,6 +182,9 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
177 } 182 }
178 for (phys_id = 0 ; phys_id < nr_cpu ; phys_id++) 183 for (phys_id = 0 ; phys_id < nr_cpu ; phys_id++)
179 physid_set(phys_id, phys_cpu_present_map); 184 physid_set(phys_id, phys_cpu_present_map);
185#ifndef CONFIG_HOTPLUG_CPU
186 cpu_present_map = cpu_possible_map;
187#endif
180 188
181 show_mp_info(nr_cpu); 189 show_mp_info(nr_cpu);
182 190
@@ -186,7 +194,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
186 * Setup boot CPU information 194 * Setup boot CPU information
187 */ 195 */
188 smp_store_cpu_info(0); /* Final full version of the data */ 196 smp_store_cpu_info(0); /* Final full version of the data */
189 smp_tune_scheduling();
190 197
191 /* 198 /*
192 * If SMP should be disabled, then really disable it! 199 * If SMP should be disabled, then really disable it!
@@ -230,11 +237,6 @@ smp_done:
230 Dprintk("Boot done.\n"); 237 Dprintk("Boot done.\n");
231} 238}
232 239
233static void __init smp_tune_scheduling(void)
234{
235 /* Nothing to do. */
236}
237
238/* 240/*
239 * init_ipi_lock : Initialize IPI locks. 241 * init_ipi_lock : Initialize IPI locks.
240 */ 242 */
@@ -629,4 +631,3 @@ static void __init unmap_cpu_to_physid(int cpu_id, int phys_id)
629 physid_2_cpu[phys_id] = -1; 631 physid_2_cpu[phys_id] = -1;
630 cpu_2_physid[cpu_id] = -1; 632 cpu_2_physid[cpu_id] = -1;
631} 633}
632
diff --git a/arch/m32r/lib/Makefile b/arch/m32r/lib/Makefile
index e632d10c7d78..d16b4e40d1ae 100644
--- a/arch/m32r/lib/Makefile
+++ b/arch/m32r/lib/Makefile
@@ -2,6 +2,6 @@
2# Makefile for M32R-specific library files.. 2# Makefile for M32R-specific library files..
3# 3#
4 4
5lib-y := checksum.o ashxdi3.o memset.o memcpy.o getuser.o \ 5lib-y := checksum.o ashxdi3.o memset.o memcpy.o \
6 putuser.o delay.o strlen.o usercopy.o csum_partial_copy.o 6 delay.o strlen.o usercopy.o csum_partial_copy.o
7 7
diff --git a/arch/m32r/lib/getuser.S b/arch/m32r/lib/getuser.S
deleted file mode 100644
index 58a0db055c5c..000000000000
--- a/arch/m32r/lib/getuser.S
+++ /dev/null
@@ -1,88 +0,0 @@
1/*
2 * __get_user functions.
3 *
4 * (C) Copyright 2001 Hirokazu Takata
5 *
6 * These functions have a non-standard call interface
7 * to make them more efficient, especially as they
8 * return an error value in addition to the "real"
9 * return value.
10 */
11
12#include <linux/config.h>
13
14/*
15 * __get_user_X
16 *
17 * Inputs: r0 contains the address
18 *
19 * Outputs: r0 is error code (0 or -EFAULT)
20 * r1 contains zero-extended value
21 *
22 * These functions should not modify any other registers,
23 * as they get called from within inline assembly.
24 */
25
26#ifdef CONFIG_ISA_DUAL_ISSUE
27
28 .text
29 .balign 4
30 .globl __get_user_1
31__get_user_1:
321: ldub r1, @r0 || ldi r0, #0
33 jmp r14
34
35 .balign 4
36 .globl __get_user_2
37__get_user_2:
382: lduh r1, @r0 || ldi r0, #0
39 jmp r14
40
41 .balign 4
42 .globl __get_user_4
43__get_user_4:
443: ld r1, @r0 || ldi r0, #0
45 jmp r14
46
47bad_get_user:
48 ldi r1, #0 || ldi r0, #-14
49 jmp r14
50
51#else /* not CONFIG_ISA_DUAL_ISSUE */
52
53 .text
54 .balign 4
55 .globl __get_user_1
56__get_user_1:
571: ldub r1, @r0
58 ldi r0, #0
59 jmp r14
60
61 .balign 4
62 .globl __get_user_2
63__get_user_2:
642: lduh r1, @r0
65 ldi r0, #0
66 jmp r14
67
68 .balign 4
69 .globl __get_user_4
70__get_user_4:
713: ld r1, @r0
72 ldi r0, #0
73 jmp r14
74
75bad_get_user:
76 ldi r1, #0
77 ldi r0, #-14
78 jmp r14
79
80#endif /* not CONFIG_ISA_DUAL_ISSUE */
81
82.section __ex_table,"a"
83 .long 1b,bad_get_user
84 .long 2b,bad_get_user
85 .long 3b,bad_get_user
86.previous
87
88 .end
diff --git a/arch/m32r/lib/putuser.S b/arch/m32r/lib/putuser.S
deleted file mode 100644
index 218154cc3890..000000000000
--- a/arch/m32r/lib/putuser.S
+++ /dev/null
@@ -1,84 +0,0 @@
1/*
2 * __put_user functions.
3 *
4 * (C) Copyright 1998 Linus Torvalds
5 * (C) Copyright 2001 Hirokazu Takata
6 *
7 * These functions have a non-standard call interface
8 * to make them more efficient.
9 */
10
11#include <linux/config.h>
12
13/*
14 * __put_user_X
15 *
16 * Inputs: r0 contains the address
17 * r1 contains the value
18 *
19 * Outputs: r0 is error code (0 or -EFAULT)
20 * r1 is corrupted (will contain "current_task").
21 *
22 * These functions should not modify any other registers,
23 * as they get called from within inline assembly.
24 */
25
26#ifdef CONFIG_ISA_DUAL_ISSUE
27
28 .text
29 .balign 4
30 .globl __put_user_1
31__put_user_1:
321: stb r1, @r0 || ldi r0, #0
33 jmp r14
34
35 .balign 4
36 .globl __put_user_2
37__put_user_2:
382: sth r1, @r0 || ldi r0, #0
39 jmp r14
40
41 .balign 4
42 .globl __put_user_4
43__put_user_4:
443: st r1, @r0 || ldi r0, #0
45 jmp r14
46
47bad_put_user:
48 ldi r0, #-14 || jmp r14
49
50#else /* not CONFIG_ISA_DUAL_ISSUE */
51
52 .text
53 .balign 4
54 .globl __put_user_1
55__put_user_1:
561: stb r1, @r0
57 ldi r0, #0
58 jmp r14
59
60 .balign 4
61 .globl __put_user_2
62__put_user_2:
632: sth r1, @r0
64 ldi r0, #0
65 jmp r14
66
67 .balign 4
68 .globl __put_user_4
69__put_user_4:
703: st r1, @r0
71 ldi r0, #0
72 jmp r14
73
74bad_put_user:
75 ldi r0, #-14
76 jmp r14
77
78#endif /* not CONFIG_ISA_DUAL_ISSUE */
79
80.section __ex_table,"a"
81 .long 1b,bad_put_user
82 .long 2b,bad_put_user
83 .long 3b,bad_put_user
84.previous
diff --git a/arch/m68k/kernel/m68k_ksyms.c b/arch/m68k/kernel/m68k_ksyms.c
index c3319514a85e..5b7952ea2bae 100644
--- a/arch/m68k/kernel/m68k_ksyms.c
+++ b/arch/m68k/kernel/m68k_ksyms.c
@@ -57,7 +57,6 @@ EXPORT_SYMBOL(dump_thread);
57EXPORT_SYMBOL(strnlen); 57EXPORT_SYMBOL(strnlen);
58EXPORT_SYMBOL(strrchr); 58EXPORT_SYMBOL(strrchr);
59EXPORT_SYMBOL(strstr); 59EXPORT_SYMBOL(strstr);
60EXPORT_SYMBOL(strpbrk);
61EXPORT_SYMBOL(enable_irq); 60EXPORT_SYMBOL(enable_irq);
62EXPORT_SYMBOL(disable_irq); 61EXPORT_SYMBOL(disable_irq);
63EXPORT_SYMBOL(kernel_thread); 62EXPORT_SYMBOL(kernel_thread);
diff --git a/arch/m68knommu/kernel/m68k_ksyms.c b/arch/m68knommu/kernel/m68k_ksyms.c
index f9b4ea16c099..4320d5dcc9cb 100644
--- a/arch/m68knommu/kernel/m68k_ksyms.c
+++ b/arch/m68knommu/kernel/m68k_ksyms.c
@@ -26,7 +26,6 @@ EXPORT_SYMBOL(__ioremap);
26EXPORT_SYMBOL(iounmap); 26EXPORT_SYMBOL(iounmap);
27EXPORT_SYMBOL(dump_fpu); 27EXPORT_SYMBOL(dump_fpu);
28EXPORT_SYMBOL(strnlen); 28EXPORT_SYMBOL(strnlen);
29EXPORT_SYMBOL(strpbrk);
30EXPORT_SYMBOL(strrchr); 29EXPORT_SYMBOL(strrchr);
31EXPORT_SYMBOL(strstr); 30EXPORT_SYMBOL(strstr);
32EXPORT_SYMBOL(strchr); 31EXPORT_SYMBOL(strchr);
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index e15709ce8866..87f0b79c6b15 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -816,6 +816,10 @@ config GENERIC_CALIBRATE_DELAY
816 bool 816 bool
817 default y 817 default y
818 818
819config SCHED_NO_NO_OMIT_FRAME_POINTER
820 bool
821 default y
822
819# 823#
820# Select some configuration options automatically based on user selections. 824# Select some configuration options automatically based on user selections.
821# 825#
@@ -1443,6 +1447,10 @@ choice
1443 prompt "MIPS MT options" 1447 prompt "MIPS MT options"
1444 depends on MIPS_MT 1448 depends on MIPS_MT
1445 1449
1450config MIPS_MT_SMTC
1451 bool "SMTC: Use all TCs on all VPEs for SMP"
1452 select SMP
1453
1446config MIPS_MT_SMP 1454config MIPS_MT_SMP
1447 bool "Use 1 TC on each available VPE for SMP" 1455 bool "Use 1 TC on each available VPE for SMP"
1448 select SMP 1456 select SMP
@@ -1456,6 +1464,11 @@ config MIPS_VPE_LOADER
1456 1464
1457endchoice 1465endchoice
1458 1466
1467config MIPS_MT_FPAFF
1468 bool "Dynamic FPU affinity for FP-intensive threads"
1469 depends on MIPS_MT
1470 default y
1471
1459config MIPS_VPE_LOADER_TOM 1472config MIPS_VPE_LOADER_TOM
1460 bool "Load VPE program into memory hidden from linux" 1473 bool "Load VPE program into memory hidden from linux"
1461 depends on MIPS_VPE_LOADER 1474 depends on MIPS_VPE_LOADER
@@ -1472,6 +1485,16 @@ config MIPS_VPE_APSP_API
1472 depends on MIPS_VPE_LOADER 1485 depends on MIPS_VPE_LOADER
1473 help 1486 help
1474 1487
1488config MIPS_APSP_KSPD
1489 bool "Enable KSPD"
1490 depends on MIPS_VPE_APSP_API
1491 default y
1492 help
1493 KSPD is a kernel daemon that accepts syscall requests from the SP
1494 side, actions them and returns the results. It also handles the
1495 "exit" syscall notifying other kernel modules the SP program is
1496 exiting. You probably want to say yes here.
1497
1475config SB1_PASS_1_WORKAROUNDS 1498config SB1_PASS_1_WORKAROUNDS
1476 bool 1499 bool
1477 depends on CPU_SB1_PASS_1 1500 depends on CPU_SB1_PASS_1
@@ -1590,11 +1613,16 @@ config ARCH_FLATMEM_ENABLE
1590 def_bool y 1613 def_bool y
1591 depends on !NUMA 1614 depends on !NUMA
1592 1615
1616config NODES_SHIFT
1617 int
1618 default "6"
1619 depends on NEED_MULTIPLE_NODES
1620
1593source "mm/Kconfig" 1621source "mm/Kconfig"
1594 1622
1595config SMP 1623config SMP
1596 bool "Multi-Processing support" 1624 bool "Multi-Processing support"
1597 depends on CPU_RM9000 || ((SIBYTE_BCM1x80 || SIBYTE_BCM1x55 || SIBYTE_SB1250 || QEMU) && !SIBYTE_STANDALONE) || SGI_IP27 || MIPS_MT_SMP 1625 depends on CPU_RM9000 || ((SIBYTE_BCM1x80 || SIBYTE_BCM1x55 || SIBYTE_SB1250 || QEMU) && !SIBYTE_STANDALONE) || SGI_IP27 || MIPS_MT_SMP || MIPS_MT_SMTC
1598 ---help--- 1626 ---help---
1599 This enables support for systems with more than one CPU. If you have 1627 This enables support for systems with more than one CPU. If you have
1600 a system with only one CPU, like most personal computers, say N. If 1628 a system with only one CPU, like most personal computers, say N. If
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 9a69e0f0ab76..69b9c1b8fafc 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -105,18 +105,18 @@ cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap
105cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap 105cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap
106cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap 106cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap
107cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap 107cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap
108cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips2 -mtune=r4600) \ 108cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
109 -Wa,-mips32 -Wa,--trap 109 -Wa,-mips32 -Wa,--trap
110cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips2 -mtune=r4600) \ 110cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
111 -Wa,-mips32r2 -Wa,--trap 111 -Wa,-mips32r2 -Wa,--trap
112cflags-$(CONFIG_CPU_MIPS64_R1) += $(call cc-option,-march=mips64,-mips2 -mtune=r4600) \ 112cflags-$(CONFIG_CPU_MIPS64_R1) += $(call cc-option,-march=mips64,-mips64 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) \
113 -Wa,-mips64 -Wa,--trap 113 -Wa,-mips64 -Wa,--trap
114cflags-$(CONFIG_CPU_MIPS64_R2) += $(call cc-option,-march=mips64r2,-mips2 -mtune=r4600 ) \ 114cflags-$(CONFIG_CPU_MIPS64_R2) += $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) \
115 -Wa,-mips64r2 -Wa,--trap 115 -Wa,-mips64r2 -Wa,--trap
116cflags-$(CONFIG_CPU_R5000) += -march=r5000 -Wa,--trap 116cflags-$(CONFIG_CPU_R5000) += -march=r5000 -Wa,--trap
117cflags-$(CONFIG_CPU_R5432) += $(call cc-options,-march=r5400,-march=r5000) \ 117cflags-$(CONFIG_CPU_R5432) += $(call cc-option,-march=r5400,-march=r5000) \
118 -Wa,--trap 118 -Wa,--trap
119cflags-$(CONFIG_CPU_NEVADA) += $(call cc-options,-march=rm5200,-march=r5000) \ 119cflags-$(CONFIG_CPU_NEVADA) += $(call cc-option,-march=rm5200,-march=r5000) \
120 -Wa,--trap 120 -Wa,--trap
121cflags-$(CONFIG_CPU_RM7000) += $(call cc-option,-march=rm7000,-march=r5000) \ 121cflags-$(CONFIG_CPU_RM7000) += $(call cc-option,-march=rm7000,-march=r5000) \
122 -Wa,--trap 122 -Wa,--trap
diff --git a/arch/mips/au1000/common/Makefile b/arch/mips/au1000/common/Makefile
index a1edfd1f643c..bf682f50b859 100644
--- a/arch/mips/au1000/common/Makefile
+++ b/arch/mips/au1000/common/Makefile
@@ -6,7 +6,7 @@
6# Makefile for the Alchemy Au1000 CPU, generic files. 6# Makefile for the Alchemy Au1000 CPU, generic files.
7# 7#
8 8
9obj-y += prom.o int-handler.o irq.o puts.o time.o reset.o \ 9obj-y += prom.o irq.o puts.o time.o reset.o \
10 au1xxx_irqmap.o clocks.o platform.o power.o setup.o \ 10 au1xxx_irqmap.o clocks.o platform.o power.o setup.o \
11 sleeper.o cputable.o dma.o dbdma.o gpio.o 11 sleeper.o cputable.o dma.o dbdma.o gpio.o
12 12
diff --git a/arch/mips/au1000/common/int-handler.S b/arch/mips/au1000/common/int-handler.S
deleted file mode 100644
index 1c4ca883321e..000000000000
--- a/arch/mips/au1000/common/int-handler.S
+++ /dev/null
@@ -1,68 +0,0 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: ppopov@mvista.com
4 *
5 * Interrupt dispatcher for Au1000 boards.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12#include <asm/asm.h>
13#include <asm/mipsregs.h>
14#include <asm/addrspace.h>
15#include <asm/regdef.h>
16#include <asm/stackframe.h>
17
18 .text
19 .set macro
20 .set noat
21 .align 5
22
23NESTED(au1000_IRQ, PT_SIZE, sp)
24 SAVE_ALL
25 CLI # Important: mark KERNEL mode !
26
27 mfc0 t0,CP0_CAUSE # get pending interrupts
28 mfc0 t1,CP0_STATUS # get enabled interrupts
29 and t0,t1 # isolate allowed ones
30
31 andi t0,0xff00 # isolate pending bits
32 beqz t0, 3f # spurious interrupt
33
34 andi a0, t0, CAUSEF_IP7
35 beq a0, zero, 1f
36 move a0, sp
37 jal mips_timer_interrupt
38 j ret_from_irq
39
401:
41 andi a0, t0, CAUSEF_IP2 # Interrupt Controller 0, Request 0
42 beq a0, zero, 2f
43 move a0,sp
44 jal intc0_req0_irqdispatch
45 j ret_from_irq
462:
47 andi a0, t0, CAUSEF_IP3 # Interrupt Controller 0, Request 1
48 beq a0, zero, 3f
49 move a0,sp
50 jal intc0_req1_irqdispatch
51 j ret_from_irq
523:
53 andi a0, t0, CAUSEF_IP4 # Interrupt Controller 1, Request 0
54 beq a0, zero, 4f
55 move a0,sp
56 jal intc1_req0_irqdispatch
57 j ret_from_irq
584:
59 andi a0, t0, CAUSEF_IP5 # Interrupt Controller 1, Request 1
60 beq a0, zero, 5f
61 move a0, sp
62 jal intc1_req1_irqdispatch
63 j ret_from_irq
64
655:
66 move a0, sp
67 j spurious_interrupt
68END(au1000_IRQ)
diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c
index 1339a0979f66..da61de776154 100644
--- a/arch/mips/au1000/common/irq.c
+++ b/arch/mips/au1000/common/irq.c
@@ -66,7 +66,6 @@
66#define EXT_INTC1_REQ1 5 /* IP 5 */ 66#define EXT_INTC1_REQ1 5 /* IP 5 */
67#define MIPS_TIMER_IP 7 /* IP 7 */ 67#define MIPS_TIMER_IP 7 /* IP 7 */
68 68
69extern asmlinkage void au1000_IRQ(void);
70extern void set_debug_traps(void); 69extern void set_debug_traps(void);
71extern irq_cpustat_t irq_stat [NR_CPUS]; 70extern irq_cpustat_t irq_stat [NR_CPUS];
72 71
@@ -446,7 +445,6 @@ void __init arch_init_irq(void)
446 extern int au1xxx_ic0_nr_irqs; 445 extern int au1xxx_ic0_nr_irqs;
447 446
448 cp0_status = read_c0_status(); 447 cp0_status = read_c0_status();
449 set_except_vector(0, au1000_IRQ);
450 448
451 /* Initialize interrupt controllers to a safe state. 449 /* Initialize interrupt controllers to a safe state.
452 */ 450 */
@@ -661,3 +659,21 @@ restore_au1xxx_intctl(void)
661 au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync(); 659 au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync();
662} 660}
663#endif /* CONFIG_PM */ 661#endif /* CONFIG_PM */
662
663asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
664{
665 unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
666
667 if (pending & CAUSEF_IP7)
668 mips_timer_interrupt(regs);
669 else if (pending & CAUSEF_IP2)
670 intc0_req0_irqdispatch(regs);
671 else if (pending & CAUSEF_IP3)
672 intc0_req1_irqdispatch(regs);
673 else if (pending & CAUSEF_IP4)
674 intc1_req0_irqdispatch(regs);
675 else if (pending & CAUSEF_IP5)
676 intc1_req1_irqdispatch(regs);
677 else
678 spurious_interrupt(regs);
679}
diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile
index 720e757b2b64..225ac8f34ccd 100644
--- a/arch/mips/cobalt/Makefile
+++ b/arch/mips/cobalt/Makefile
@@ -2,7 +2,7 @@
2# Makefile for the Cobalt micro systems family specific parts of the kernel 2# Makefile for the Cobalt micro systems family specific parts of the kernel
3# 3#
4 4
5obj-y := irq.o int-handler.o reset.o setup.o 5obj-y := irq.o reset.o setup.o
6 6
7obj-$(CONFIG_EARLY_PRINTK) += console.o 7obj-$(CONFIG_EARLY_PRINTK) += console.o
8 8
diff --git a/arch/mips/cobalt/int-handler.S b/arch/mips/cobalt/int-handler.S
deleted file mode 100644
index e75d5e3ca868..000000000000
--- a/arch/mips/cobalt/int-handler.S
+++ /dev/null
@@ -1,25 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1995, 1996, 1997, 2003 by Ralf Baechle
7 * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
8 */
9#include <asm/asm.h>
10#include <asm/mipsregs.h>
11#include <asm/mach-cobalt/cobalt.h>
12#include <asm/regdef.h>
13#include <asm/stackframe.h>
14
15 .text
16 .align 5
17 NESTED(cobalt_handle_int, PT_SIZE, sp)
18 SAVE_ALL
19 CLI
20
21 PTR_LA ra, ret_from_irq
22 move a0, sp
23 j cobalt_irq
24
25 END(cobalt_handle_int)
diff --git a/arch/mips/cobalt/irq.c b/arch/mips/cobalt/irq.c
index f9a108820d6e..0b75f4fb7195 100644
--- a/arch/mips/cobalt/irq.c
+++ b/arch/mips/cobalt/irq.c
@@ -20,8 +20,6 @@
20 20
21#include <asm/mach-cobalt/cobalt.h> 21#include <asm/mach-cobalt/cobalt.h>
22 22
23extern void cobalt_handle_int(void);
24
25/* 23/*
26 * We have two types of interrupts that we handle, ones that come in through 24 * We have two types of interrupts that we handle, ones that come in through
27 * the CPU interrupt lines, and ones that come in on the via chip. The CPU 25 * the CPU interrupt lines, and ones that come in on the via chip. The CPU
@@ -79,7 +77,7 @@ static inline void via_pic_irq(struct pt_regs *regs)
79 do_IRQ(irq, regs); 77 do_IRQ(irq, regs);
80} 78}
81 79
82asmlinkage void cobalt_irq(struct pt_regs *regs) 80asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
83{ 81{
84 unsigned pending; 82 unsigned pending;
85 83
@@ -122,8 +120,6 @@ void __init arch_init_irq(void)
122 */ 120 */
123 GALILEO_OUTL(0, GT_INTRMASK_OFS); 121 GALILEO_OUTL(0, GT_INTRMASK_OFS);
124 122
125 set_except_vector(0, cobalt_handle_int);
126
127 init_i8259_irqs(); /* 0 ... 15 */ 123 init_i8259_irqs(); /* 0 ... 15 */
128 mips_cpu_irq_init(COBALT_CPU_IRQ); /* 16 ... 23 */ 124 mips_cpu_irq_init(COBALT_CPU_IRQ); /* 16 ... 23 */
129 125
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig
new file mode 100644
index 000000000000..8a1e3ace0b2c
--- /dev/null
+++ b/arch/mips/configs/tb0287_defconfig
@@ -0,0 +1,1096 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.16
4# Wed Mar 22 11:07:34 2006
5#
6CONFIG_MIPS=y
7
8#
9# Machine selection
10#
11# CONFIG_MIPS_MTX1 is not set
12# CONFIG_MIPS_BOSPORUS is not set
13# CONFIG_MIPS_PB1000 is not set
14# CONFIG_MIPS_PB1100 is not set
15# CONFIG_MIPS_PB1500 is not set
16# CONFIG_MIPS_PB1550 is not set
17# CONFIG_MIPS_PB1200 is not set
18# CONFIG_MIPS_DB1000 is not set
19# CONFIG_MIPS_DB1100 is not set
20# CONFIG_MIPS_DB1500 is not set
21# CONFIG_MIPS_DB1550 is not set
22# CONFIG_MIPS_DB1200 is not set
23# CONFIG_MIPS_MIRAGE is not set
24# CONFIG_MIPS_COBALT is not set
25# CONFIG_MACH_DECSTATION is not set
26# CONFIG_MIPS_EV64120 is not set
27# CONFIG_MIPS_EV96100 is not set
28# CONFIG_MIPS_IVR is not set
29# CONFIG_MIPS_ITE8172 is not set
30# CONFIG_MACH_JAZZ is not set
31# CONFIG_LASAT is not set
32# CONFIG_MIPS_ATLAS is not set
33# CONFIG_MIPS_MALTA is not set
34# CONFIG_MIPS_SEAD is not set
35# CONFIG_MIPS_SIM is not set
36# CONFIG_MOMENCO_JAGUAR_ATX is not set
37# CONFIG_MOMENCO_OCELOT is not set
38# CONFIG_MOMENCO_OCELOT_3 is not set
39# CONFIG_MOMENCO_OCELOT_C is not set
40# CONFIG_MOMENCO_OCELOT_G is not set
41# CONFIG_MIPS_XXS1500 is not set
42# CONFIG_PNX8550_V2PCI is not set
43# CONFIG_PNX8550_JBS is not set
44# CONFIG_DDB5074 is not set
45# CONFIG_DDB5476 is not set
46# CONFIG_DDB5477 is not set
47CONFIG_MACH_VR41XX=y
48# CONFIG_PMC_YOSEMITE is not set
49# CONFIG_QEMU is not set
50# CONFIG_SGI_IP22 is not set
51# CONFIG_SGI_IP27 is not set
52# CONFIG_SGI_IP32 is not set
53# CONFIG_SIBYTE_BIGSUR is not set
54# CONFIG_SIBYTE_SWARM is not set
55# CONFIG_SIBYTE_SENTOSA is not set
56# CONFIG_SIBYTE_RHONE is not set
57# CONFIG_SIBYTE_CARMEL is not set
58# CONFIG_SIBYTE_PTSWARM is not set
59# CONFIG_SIBYTE_LITTLESUR is not set
60# CONFIG_SIBYTE_CRHINE is not set
61# CONFIG_SIBYTE_CRHONE is not set
62# CONFIG_SNI_RM200_PCI is not set
63# CONFIG_TOSHIBA_JMR3927 is not set
64# CONFIG_TOSHIBA_RBTX4927 is not set
65# CONFIG_TOSHIBA_RBTX4938 is not set
66# CONFIG_CASIO_E55 is not set
67# CONFIG_IBM_WORKPAD is not set
68# CONFIG_NEC_CMBVR4133 is not set
69CONFIG_TANBAC_TB022X=y
70# CONFIG_TANBAC_TB0226 is not set
71CONFIG_TANBAC_TB0287=y
72# CONFIG_VICTOR_MPC30X is not set
73# CONFIG_ZAO_CAPCELLA is not set
74CONFIG_PCI_VR41XX=y
75# CONFIG_VRC4173 is not set
76CONFIG_RWSEM_GENERIC_SPINLOCK=y
77CONFIG_GENERIC_CALIBRATE_DELAY=y
78CONFIG_DMA_NONCOHERENT=y
79CONFIG_DMA_NEED_PCI_MAP_STATE=y
80# CONFIG_CPU_BIG_ENDIAN is not set
81CONFIG_CPU_LITTLE_ENDIAN=y
82CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
83CONFIG_IRQ_CPU=y
84CONFIG_MIPS_L1_CACHE_SHIFT=5
85
86#
87# CPU selection
88#
89# CONFIG_CPU_MIPS32_R1 is not set
90# CONFIG_CPU_MIPS32_R2 is not set
91# CONFIG_CPU_MIPS64_R1 is not set
92# CONFIG_CPU_MIPS64_R2 is not set
93# CONFIG_CPU_R3000 is not set
94# CONFIG_CPU_TX39XX is not set
95CONFIG_CPU_VR41XX=y
96# CONFIG_CPU_R4300 is not set
97# CONFIG_CPU_R4X00 is not set
98# CONFIG_CPU_TX49XX is not set
99# CONFIG_CPU_R5000 is not set
100# CONFIG_CPU_R5432 is not set
101# CONFIG_CPU_R6000 is not set
102# CONFIG_CPU_NEVADA is not set
103# CONFIG_CPU_R8000 is not set
104# CONFIG_CPU_R10000 is not set
105# CONFIG_CPU_RM7000 is not set
106# CONFIG_CPU_RM9000 is not set
107# CONFIG_CPU_SB1 is not set
108CONFIG_SYS_HAS_CPU_VR41XX=y
109CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
110CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
111CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
112CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
113
114#
115# Kernel type
116#
117CONFIG_32BIT=y
118# CONFIG_64BIT is not set
119CONFIG_PAGE_SIZE_4KB=y
120# CONFIG_PAGE_SIZE_8KB is not set
121# CONFIG_PAGE_SIZE_16KB is not set
122# CONFIG_PAGE_SIZE_64KB is not set
123# CONFIG_MIPS_MT is not set
124# CONFIG_CPU_ADVANCED is not set
125CONFIG_CPU_HAS_SYNC=y
126CONFIG_GENERIC_HARDIRQS=y
127CONFIG_GENERIC_IRQ_PROBE=y
128CONFIG_ARCH_FLATMEM_ENABLE=y
129CONFIG_SELECT_MEMORY_MODEL=y
130CONFIG_FLATMEM_MANUAL=y
131# CONFIG_DISCONTIGMEM_MANUAL is not set
132# CONFIG_SPARSEMEM_MANUAL is not set
133CONFIG_FLATMEM=y
134CONFIG_FLAT_NODE_MEM_MAP=y
135# CONFIG_SPARSEMEM_STATIC is not set
136CONFIG_SPLIT_PTLOCK_CPUS=4
137CONFIG_PREEMPT_NONE=y
138# CONFIG_PREEMPT_VOLUNTARY is not set
139# CONFIG_PREEMPT is not set
140
141#
142# Code maturity level options
143#
144CONFIG_EXPERIMENTAL=y
145CONFIG_BROKEN_ON_SMP=y
146CONFIG_INIT_ENV_ARG_LIMIT=32
147
148#
149# General setup
150#
151CONFIG_LOCALVERSION=""
152CONFIG_LOCALVERSION_AUTO=y
153CONFIG_SWAP=y
154CONFIG_SYSVIPC=y
155# CONFIG_POSIX_MQUEUE is not set
156# CONFIG_BSD_PROCESS_ACCT is not set
157CONFIG_SYSCTL=y
158# CONFIG_AUDIT is not set
159# CONFIG_IKCONFIG is not set
160CONFIG_INITRAMFS_SOURCE=""
161# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
162CONFIG_EMBEDDED=y
163CONFIG_KALLSYMS=y
164# CONFIG_KALLSYMS_EXTRA_PASS is not set
165# CONFIG_HOTPLUG is not set
166CONFIG_PRINTK=y
167CONFIG_BUG=y
168CONFIG_ELF_CORE=y
169CONFIG_BASE_FULL=y
170CONFIG_FUTEX=y
171CONFIG_EPOLL=y
172CONFIG_SHMEM=y
173CONFIG_CC_ALIGN_FUNCTIONS=0
174CONFIG_CC_ALIGN_LABELS=0
175CONFIG_CC_ALIGN_LOOPS=0
176CONFIG_CC_ALIGN_JUMPS=0
177CONFIG_SLAB=y
178# CONFIG_TINY_SHMEM is not set
179CONFIG_BASE_SMALL=0
180# CONFIG_SLOB is not set
181
182#
183# Loadable module support
184#
185CONFIG_MODULES=y
186CONFIG_MODULE_UNLOAD=y
187# CONFIG_MODULE_FORCE_UNLOAD is not set
188CONFIG_OBSOLETE_MODPARM=y
189CONFIG_MODVERSIONS=y
190CONFIG_MODULE_SRCVERSION_ALL=y
191CONFIG_KMOD=y
192
193#
194# Block layer
195#
196# CONFIG_LBD is not set
197
198#
199# IO Schedulers
200#
201CONFIG_IOSCHED_NOOP=y
202CONFIG_IOSCHED_AS=y
203CONFIG_IOSCHED_DEADLINE=y
204CONFIG_IOSCHED_CFQ=y
205CONFIG_DEFAULT_AS=y
206# CONFIG_DEFAULT_DEADLINE is not set
207# CONFIG_DEFAULT_CFQ is not set
208# CONFIG_DEFAULT_NOOP is not set
209CONFIG_DEFAULT_IOSCHED="anticipatory"
210
211#
212# Bus options (PCI, PCMCIA, EISA, ISA, TC)
213#
214CONFIG_HW_HAS_PCI=y
215CONFIG_PCI=y
216# CONFIG_PCI_LEGACY_PROC is not set
217CONFIG_MMU=y
218
219#
220# PCCARD (PCMCIA/CardBus) support
221#
222# CONFIG_PCCARD is not set
223
224#
225# PCI Hotplug Support
226#
227# CONFIG_HOTPLUG_PCI is not set
228
229#
230# Executable file formats
231#
232CONFIG_BINFMT_ELF=y
233# CONFIG_BINFMT_MISC is not set
234CONFIG_TRAD_SIGNALS=y
235
236#
237# Networking
238#
239CONFIG_NET=y
240
241#
242# Networking options
243#
244# CONFIG_NETDEBUG is not set
245CONFIG_PACKET=y
246# CONFIG_PACKET_MMAP is not set
247CONFIG_UNIX=y
248CONFIG_XFRM=y
249CONFIG_XFRM_USER=m
250# CONFIG_NET_KEY is not set
251CONFIG_INET=y
252CONFIG_IP_MULTICAST=y
253CONFIG_IP_ADVANCED_ROUTER=y
254CONFIG_ASK_IP_FIB_HASH=y
255# CONFIG_IP_FIB_TRIE is not set
256CONFIG_IP_FIB_HASH=y
257CONFIG_IP_MULTIPLE_TABLES=y
258CONFIG_IP_ROUTE_MULTIPATH=y
259# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
260CONFIG_IP_ROUTE_VERBOSE=y
261CONFIG_IP_PNP=y
262# CONFIG_IP_PNP_DHCP is not set
263CONFIG_IP_PNP_BOOTP=y
264# CONFIG_IP_PNP_RARP is not set
265CONFIG_NET_IPIP=m
266CONFIG_NET_IPGRE=m
267# CONFIG_NET_IPGRE_BROADCAST is not set
268# CONFIG_IP_MROUTE is not set
269# CONFIG_ARPD is not set
270CONFIG_SYN_COOKIES=y
271# CONFIG_INET_AH is not set
272# CONFIG_INET_ESP is not set
273# CONFIG_INET_IPCOMP is not set
274CONFIG_INET_TUNNEL=m
275CONFIG_INET_DIAG=y
276CONFIG_INET_TCP_DIAG=y
277CONFIG_TCP_CONG_ADVANCED=y
278
279#
280# TCP congestion control
281#
282CONFIG_TCP_CONG_BIC=y
283CONFIG_TCP_CONG_CUBIC=m
284CONFIG_TCP_CONG_WESTWOOD=m
285CONFIG_TCP_CONG_HTCP=m
286# CONFIG_TCP_CONG_HSTCP is not set
287# CONFIG_TCP_CONG_HYBLA is not set
288# CONFIG_TCP_CONG_VEGAS is not set
289# CONFIG_TCP_CONG_SCALABLE is not set
290# CONFIG_IPV6 is not set
291# CONFIG_NETFILTER is not set
292
293#
294# DCCP Configuration (EXPERIMENTAL)
295#
296# CONFIG_IP_DCCP is not set
297
298#
299# SCTP Configuration (EXPERIMENTAL)
300#
301# CONFIG_IP_SCTP is not set
302
303#
304# TIPC Configuration (EXPERIMENTAL)
305#
306# CONFIG_TIPC is not set
307# CONFIG_ATM is not set
308# CONFIG_BRIDGE is not set
309# CONFIG_VLAN_8021Q is not set
310# CONFIG_DECNET is not set
311# CONFIG_LLC2 is not set
312# CONFIG_IPX is not set
313# CONFIG_ATALK is not set
314# CONFIG_X25 is not set
315# CONFIG_LAPB is not set
316# CONFIG_NET_DIVERT is not set
317# CONFIG_ECONET is not set
318# CONFIG_WAN_ROUTER is not set
319
320#
321# QoS and/or fair queueing
322#
323# CONFIG_NET_SCHED is not set
324
325#
326# Network testing
327#
328# CONFIG_NET_PKTGEN is not set
329# CONFIG_HAMRADIO is not set
330# CONFIG_IRDA is not set
331# CONFIG_BT is not set
332# CONFIG_IEEE80211 is not set
333
334#
335# Device Drivers
336#
337
338#
339# Generic Driver Options
340#
341CONFIG_STANDALONE=y
342CONFIG_PREVENT_FIRMWARE_BUILD=y
343# CONFIG_FW_LOADER is not set
344
345#
346# Connector - unified userspace <-> kernelspace linker
347#
348# CONFIG_CONNECTOR is not set
349
350#
351# Memory Technology Devices (MTD)
352#
353# CONFIG_MTD is not set
354
355#
356# Parallel port support
357#
358# CONFIG_PARPORT is not set
359
360#
361# Plug and Play support
362#
363
364#
365# Block devices
366#
367# CONFIG_BLK_CPQ_DA is not set
368# CONFIG_BLK_CPQ_CISS_DA is not set
369# CONFIG_BLK_DEV_DAC960 is not set
370# CONFIG_BLK_DEV_UMEM is not set
371# CONFIG_BLK_DEV_COW_COMMON is not set
372CONFIG_BLK_DEV_LOOP=m
373# CONFIG_BLK_DEV_CRYPTOLOOP is not set
374CONFIG_BLK_DEV_NBD=m
375# CONFIG_BLK_DEV_SX8 is not set
376# CONFIG_BLK_DEV_UB is not set
377CONFIG_BLK_DEV_RAM=y
378CONFIG_BLK_DEV_RAM_COUNT=16
379CONFIG_BLK_DEV_RAM_SIZE=4096
380# CONFIG_BLK_DEV_INITRD is not set
381# CONFIG_CDROM_PKTCDVD is not set
382# CONFIG_ATA_OVER_ETH is not set
383
384#
385# ATA/ATAPI/MFM/RLL support
386#
387CONFIG_IDE=y
388CONFIG_BLK_DEV_IDE=y
389
390#
391# Please see Documentation/ide.txt for help/info on IDE drives
392#
393# CONFIG_BLK_DEV_IDE_SATA is not set
394CONFIG_BLK_DEV_IDEDISK=y
395# CONFIG_IDEDISK_MULTI_MODE is not set
396# CONFIG_BLK_DEV_IDECD is not set
397# CONFIG_BLK_DEV_IDETAPE is not set
398# CONFIG_BLK_DEV_IDEFLOPPY is not set
399# CONFIG_BLK_DEV_IDESCSI is not set
400# CONFIG_IDE_TASK_IOCTL is not set
401
402#
403# IDE chipset support/bugfixes
404#
405CONFIG_IDE_GENERIC=y
406CONFIG_BLK_DEV_IDEPCI=y
407# CONFIG_IDEPCI_SHARE_IRQ is not set
408# CONFIG_BLK_DEV_OFFBOARD is not set
409# CONFIG_BLK_DEV_GENERIC is not set
410# CONFIG_BLK_DEV_OPTI621 is not set
411CONFIG_BLK_DEV_IDEDMA_PCI=y
412# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
413# CONFIG_IDEDMA_PCI_AUTO is not set
414# CONFIG_BLK_DEV_AEC62XX is not set
415# CONFIG_BLK_DEV_ALI15X3 is not set
416# CONFIG_BLK_DEV_AMD74XX is not set
417# CONFIG_BLK_DEV_CMD64X is not set
418# CONFIG_BLK_DEV_TRIFLEX is not set
419# CONFIG_BLK_DEV_CY82C693 is not set
420# CONFIG_BLK_DEV_CS5520 is not set
421# CONFIG_BLK_DEV_CS5530 is not set
422# CONFIG_BLK_DEV_HPT34X is not set
423# CONFIG_BLK_DEV_HPT366 is not set
424# CONFIG_BLK_DEV_SC1200 is not set
425# CONFIG_BLK_DEV_PIIX is not set
426# CONFIG_BLK_DEV_IT821X is not set
427# CONFIG_BLK_DEV_NS87415 is not set
428# CONFIG_BLK_DEV_PDC202XX_OLD is not set
429# CONFIG_BLK_DEV_PDC202XX_NEW is not set
430# CONFIG_BLK_DEV_SVWKS is not set
431CONFIG_BLK_DEV_SIIMAGE=y
432# CONFIG_BLK_DEV_SLC90E66 is not set
433# CONFIG_BLK_DEV_TRM290 is not set
434# CONFIG_BLK_DEV_VIA82CXXX is not set
435# CONFIG_IDE_ARM is not set
436CONFIG_BLK_DEV_IDEDMA=y
437# CONFIG_IDEDMA_IVB is not set
438# CONFIG_IDEDMA_AUTO is not set
439# CONFIG_BLK_DEV_HD is not set
440
441#
442# SCSI device support
443#
444# CONFIG_RAID_ATTRS is not set
445CONFIG_SCSI=y
446CONFIG_SCSI_PROC_FS=y
447
448#
449# SCSI support type (disk, tape, CD-ROM)
450#
451CONFIG_BLK_DEV_SD=y
452# CONFIG_CHR_DEV_ST is not set
453# CONFIG_CHR_DEV_OSST is not set
454# CONFIG_BLK_DEV_SR is not set
455# CONFIG_CHR_DEV_SG is not set
456# CONFIG_CHR_DEV_SCH is not set
457
458#
459# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
460#
461# CONFIG_SCSI_MULTI_LUN is not set
462# CONFIG_SCSI_CONSTANTS is not set
463# CONFIG_SCSI_LOGGING is not set
464
465#
466# SCSI Transport Attributes
467#
468# CONFIG_SCSI_SPI_ATTRS is not set
469# CONFIG_SCSI_FC_ATTRS is not set
470# CONFIG_SCSI_ISCSI_ATTRS is not set
471# CONFIG_SCSI_SAS_ATTRS is not set
472
473#
474# SCSI low-level drivers
475#
476# CONFIG_ISCSI_TCP is not set
477# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
478# CONFIG_SCSI_3W_9XXX is not set
479# CONFIG_SCSI_ACARD is not set
480# CONFIG_SCSI_AACRAID is not set
481# CONFIG_SCSI_AIC7XXX is not set
482# CONFIG_SCSI_AIC7XXX_OLD is not set
483# CONFIG_SCSI_AIC79XX is not set
484# CONFIG_SCSI_DPT_I2O is not set
485# CONFIG_MEGARAID_NEWGEN is not set
486# CONFIG_MEGARAID_LEGACY is not set
487# CONFIG_MEGARAID_SAS is not set
488# CONFIG_SCSI_SATA is not set
489# CONFIG_SCSI_DMX3191D is not set
490# CONFIG_SCSI_FUTURE_DOMAIN is not set
491# CONFIG_SCSI_IPS is not set
492# CONFIG_SCSI_INITIO is not set
493# CONFIG_SCSI_INIA100 is not set
494# CONFIG_SCSI_SYM53C8XX_2 is not set
495# CONFIG_SCSI_IPR is not set
496# CONFIG_SCSI_QLOGIC_FC is not set
497# CONFIG_SCSI_QLOGIC_1280 is not set
498# CONFIG_SCSI_QLA_FC is not set
499# CONFIG_SCSI_LPFC is not set
500# CONFIG_SCSI_DC395x is not set
501# CONFIG_SCSI_DC390T is not set
502# CONFIG_SCSI_NSP32 is not set
503# CONFIG_SCSI_DEBUG is not set
504
505#
506# Multi-device support (RAID and LVM)
507#
508# CONFIG_MD is not set
509
510#
511# Fusion MPT device support
512#
513# CONFIG_FUSION is not set
514# CONFIG_FUSION_SPI is not set
515# CONFIG_FUSION_FC is not set
516# CONFIG_FUSION_SAS is not set
517
518#
519# IEEE 1394 (FireWire) support
520#
521CONFIG_IEEE1394=m
522
523#
524# Subsystem Options
525#
526# CONFIG_IEEE1394_VERBOSEDEBUG is not set
527# CONFIG_IEEE1394_OUI_DB is not set
528CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
529CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
530# CONFIG_IEEE1394_EXPORT_FULL_API is not set
531
532#
533# Device Drivers
534#
535
536#
537# Texas Instruments PCILynx requires I2C
538#
539CONFIG_IEEE1394_OHCI1394=m
540
541#
542# Protocol Drivers
543#
544CONFIG_IEEE1394_VIDEO1394=m
545CONFIG_IEEE1394_SBP2=m
546# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
547CONFIG_IEEE1394_ETH1394=m
548CONFIG_IEEE1394_DV1394=m
549CONFIG_IEEE1394_RAWIO=m
550
551#
552# I2O device support
553#
554# CONFIG_I2O is not set
555
556#
557# Network device support
558#
559CONFIG_NETDEVICES=y
560CONFIG_DUMMY=m
561# CONFIG_BONDING is not set
562# CONFIG_EQUALIZER is not set
563# CONFIG_TUN is not set
564
565#
566# ARCnet devices
567#
568# CONFIG_ARCNET is not set
569
570#
571# PHY device support
572#
573# CONFIG_PHYLIB is not set
574
575#
576# Ethernet (10 or 100Mbit)
577#
578CONFIG_NET_ETHERNET=y
579CONFIG_MII=y
580# CONFIG_HAPPYMEAL is not set
581# CONFIG_SUNGEM is not set
582# CONFIG_CASSINI is not set
583# CONFIG_NET_VENDOR_3COM is not set
584# CONFIG_DM9000 is not set
585
586#
587# Tulip family network device support
588#
589# CONFIG_NET_TULIP is not set
590# CONFIG_HP100 is not set
591# CONFIG_NET_PCI is not set
592
593#
594# Ethernet (1000 Mbit)
595#
596# CONFIG_ACENIC is not set
597# CONFIG_DL2K is not set
598# CONFIG_E1000 is not set
599# CONFIG_NS83820 is not set
600# CONFIG_HAMACHI is not set
601# CONFIG_YELLOWFIN is not set
602CONFIG_R8169=y
603# CONFIG_R8169_NAPI is not set
604# CONFIG_SIS190 is not set
605# CONFIG_SKGE is not set
606# CONFIG_SKY2 is not set
607# CONFIG_SK98LIN is not set
608# CONFIG_TIGON3 is not set
609# CONFIG_BNX2 is not set
610
611#
612# Ethernet (10000 Mbit)
613#
614# CONFIG_CHELSIO_T1 is not set
615# CONFIG_IXGB is not set
616# CONFIG_S2IO is not set
617
618#
619# Token Ring devices
620#
621# CONFIG_TR is not set
622
623#
624# Wireless LAN (non-hamradio)
625#
626# CONFIG_NET_RADIO is not set
627
628#
629# Wan interfaces
630#
631# CONFIG_WAN is not set
632# CONFIG_FDDI is not set
633# CONFIG_HIPPI is not set
634# CONFIG_PPP is not set
635# CONFIG_SLIP is not set
636# CONFIG_NET_FC is not set
637# CONFIG_SHAPER is not set
638# CONFIG_NETCONSOLE is not set
639# CONFIG_NETPOLL is not set
640# CONFIG_NET_POLL_CONTROLLER is not set
641
642#
643# ISDN subsystem
644#
645# CONFIG_ISDN is not set
646
647#
648# Telephony Support
649#
650# CONFIG_PHONE is not set
651
652#
653# Input device support
654#
655CONFIG_INPUT=y
656
657#
658# Userland interfaces
659#
660# CONFIG_INPUT_MOUSEDEV is not set
661# CONFIG_INPUT_JOYDEV is not set
662# CONFIG_INPUT_TSDEV is not set
663# CONFIG_INPUT_EVDEV is not set
664# CONFIG_INPUT_EVBUG is not set
665
666#
667# Input Device Drivers
668#
669# CONFIG_INPUT_KEYBOARD is not set
670# CONFIG_INPUT_MOUSE is not set
671# CONFIG_INPUT_JOYSTICK is not set
672# CONFIG_INPUT_TOUCHSCREEN is not set
673# CONFIG_INPUT_MISC is not set
674
675#
676# Hardware I/O ports
677#
678# CONFIG_SERIO is not set
679# CONFIG_GAMEPORT is not set
680
681#
682# Character devices
683#
684CONFIG_VT=y
685CONFIG_VT_CONSOLE=y
686CONFIG_HW_CONSOLE=y
687# CONFIG_SERIAL_NONSTANDARD is not set
688
689#
690# Serial drivers
691#
692# CONFIG_SERIAL_8250 is not set
693
694#
695# Non-8250 serial port support
696#
697CONFIG_SERIAL_CORE=y
698CONFIG_SERIAL_CORE_CONSOLE=y
699CONFIG_SERIAL_VR41XX=y
700CONFIG_SERIAL_VR41XX_CONSOLE=y
701# CONFIG_SERIAL_JSM is not set
702CONFIG_UNIX98_PTYS=y
703CONFIG_LEGACY_PTYS=y
704CONFIG_LEGACY_PTY_COUNT=256
705
706#
707# IPMI
708#
709# CONFIG_IPMI_HANDLER is not set
710
711#
712# Watchdog Cards
713#
714# CONFIG_WATCHDOG is not set
715# CONFIG_RTC is not set
716# CONFIG_GEN_RTC is not set
717# CONFIG_RTC_VR41XX is not set
718# CONFIG_DTLK is not set
719# CONFIG_R3964 is not set
720# CONFIG_APPLICOM is not set
721# CONFIG_TANBAC_TB0219 is not set
722
723#
724# Ftape, the floppy tape device driver
725#
726# CONFIG_DRM is not set
727CONFIG_GPIO_VR41XX=y
728# CONFIG_RAW_DRIVER is not set
729
730#
731# TPM devices
732#
733# CONFIG_TCG_TPM is not set
734# CONFIG_TELCLOCK is not set
735
736#
737# I2C support
738#
739# CONFIG_I2C is not set
740
741#
742# SPI support
743#
744# CONFIG_SPI is not set
745# CONFIG_SPI_MASTER is not set
746
747#
748# Dallas's 1-wire bus
749#
750# CONFIG_W1 is not set
751
752#
753# Hardware Monitoring support
754#
755# CONFIG_HWMON is not set
756# CONFIG_HWMON_VID is not set
757
758#
759# Misc devices
760#
761
762#
763# Multimedia Capabilities Port drivers
764#
765
766#
767# Multimedia devices
768#
769# CONFIG_VIDEO_DEV is not set
770
771#
772# Digital Video Broadcasting Devices
773#
774# CONFIG_DVB is not set
775
776#
777# Graphics support
778#
779# CONFIG_FB is not set
780
781#
782# Console display driver support
783#
784# CONFIG_VGA_CONSOLE is not set
785CONFIG_DUMMY_CONSOLE=y
786
787#
788# Sound
789#
790# CONFIG_SOUND is not set
791
792#
793# USB support
794#
795CONFIG_USB_ARCH_HAS_HCD=y
796CONFIG_USB_ARCH_HAS_OHCI=y
797CONFIG_USB=m
798# CONFIG_USB_DEBUG is not set
799
800#
801# Miscellaneous USB options
802#
803# CONFIG_USB_DEVICEFS is not set
804# CONFIG_USB_BANDWIDTH is not set
805# CONFIG_USB_DYNAMIC_MINORS is not set
806# CONFIG_USB_OTG is not set
807
808#
809# USB Host Controller Drivers
810#
811CONFIG_USB_EHCI_HCD=m
812# CONFIG_USB_EHCI_SPLIT_ISO is not set
813# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
814# CONFIG_USB_ISP116X_HCD is not set
815CONFIG_USB_OHCI_HCD=m
816# CONFIG_USB_OHCI_BIG_ENDIAN is not set
817CONFIG_USB_OHCI_LITTLE_ENDIAN=y
818# CONFIG_USB_UHCI_HCD is not set
819# CONFIG_USB_SL811_HCD is not set
820
821#
822# USB Device Class drivers
823#
824# CONFIG_USB_ACM is not set
825# CONFIG_USB_PRINTER is not set
826
827#
828# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
829#
830
831#
832# may also be needed; see USB_STORAGE Help for more information
833#
834CONFIG_USB_STORAGE=m
835# CONFIG_USB_STORAGE_DEBUG is not set
836# CONFIG_USB_STORAGE_DATAFAB is not set
837# CONFIG_USB_STORAGE_FREECOM is not set
838# CONFIG_USB_STORAGE_ISD200 is not set
839# CONFIG_USB_STORAGE_DPCM is not set
840# CONFIG_USB_STORAGE_USBAT is not set
841# CONFIG_USB_STORAGE_SDDR09 is not set
842# CONFIG_USB_STORAGE_SDDR55 is not set
843# CONFIG_USB_STORAGE_JUMPSHOT is not set
844# CONFIG_USB_STORAGE_ALAUDA is not set
845# CONFIG_USB_LIBUSUAL is not set
846
847#
848# USB Input Devices
849#
850CONFIG_USB_HID=m
851CONFIG_USB_HIDINPUT=y
852# CONFIG_USB_HIDINPUT_POWERBOOK is not set
853# CONFIG_HID_FF is not set
854# CONFIG_USB_HIDDEV is not set
855
856#
857# USB HID Boot Protocol drivers
858#
859# CONFIG_USB_KBD is not set
860# CONFIG_USB_MOUSE is not set
861# CONFIG_USB_AIPTEK is not set
862# CONFIG_USB_WACOM is not set
863# CONFIG_USB_ACECAD is not set
864# CONFIG_USB_KBTAB is not set
865# CONFIG_USB_POWERMATE is not set
866# CONFIG_USB_MTOUCH is not set
867# CONFIG_USB_ITMTOUCH is not set
868# CONFIG_USB_EGALAX is not set
869# CONFIG_USB_YEALINK is not set
870# CONFIG_USB_XPAD is not set
871# CONFIG_USB_ATI_REMOTE is not set
872# CONFIG_USB_ATI_REMOTE2 is not set
873# CONFIG_USB_KEYSPAN_REMOTE is not set
874# CONFIG_USB_APPLETOUCH is not set
875
876#
877# USB Imaging devices
878#
879# CONFIG_USB_MDC800 is not set
880# CONFIG_USB_MICROTEK is not set
881
882#
883# USB Multimedia devices
884#
885# CONFIG_USB_DABUSB is not set
886
887#
888# Video4Linux support is needed for USB Multimedia device support
889#
890
891#
892# USB Network Adapters
893#
894# CONFIG_USB_CATC is not set
895# CONFIG_USB_KAWETH is not set
896# CONFIG_USB_PEGASUS is not set
897# CONFIG_USB_RTL8150 is not set
898# CONFIG_USB_USBNET is not set
899CONFIG_USB_MON=y
900
901#
902# USB port drivers
903#
904
905#
906# USB Serial Converter support
907#
908# CONFIG_USB_SERIAL is not set
909
910#
911# USB Miscellaneous drivers
912#
913# CONFIG_USB_EMI62 is not set
914# CONFIG_USB_EMI26 is not set
915# CONFIG_USB_AUERSWALD is not set
916# CONFIG_USB_RIO500 is not set
917# CONFIG_USB_LEGOTOWER is not set
918# CONFIG_USB_LCD is not set
919# CONFIG_USB_LED is not set
920# CONFIG_USB_CYTHERM is not set
921# CONFIG_USB_PHIDGETKIT is not set
922# CONFIG_USB_PHIDGETSERVO is not set
923# CONFIG_USB_IDMOUSE is not set
924# CONFIG_USB_SISUSBVGA is not set
925# CONFIG_USB_LD is not set
926
927#
928# USB DSL modem support
929#
930
931#
932# USB Gadget Support
933#
934# CONFIG_USB_GADGET is not set
935
936#
937# MMC/SD Card support
938#
939# CONFIG_MMC is not set
940
941#
942# InfiniBand support
943#
944# CONFIG_INFINIBAND is not set
945
946#
947# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
948#
949
950#
951# File systems
952#
953CONFIG_EXT2_FS=y
954# CONFIG_EXT2_FS_XATTR is not set
955# CONFIG_EXT2_FS_XIP is not set
956CONFIG_EXT3_FS=y
957CONFIG_EXT3_FS_XATTR=y
958# CONFIG_EXT3_FS_POSIX_ACL is not set
959# CONFIG_EXT3_FS_SECURITY is not set
960CONFIG_JBD=y
961# CONFIG_JBD_DEBUG is not set
962CONFIG_FS_MBCACHE=y
963# CONFIG_REISERFS_FS is not set
964# CONFIG_JFS_FS is not set
965# CONFIG_FS_POSIX_ACL is not set
966CONFIG_XFS_FS=y
967CONFIG_XFS_QUOTA=y
968# CONFIG_XFS_SECURITY is not set
969CONFIG_XFS_POSIX_ACL=y
970# CONFIG_XFS_RT is not set
971# CONFIG_OCFS2_FS is not set
972# CONFIG_MINIX_FS is not set
973CONFIG_ROMFS_FS=m
974CONFIG_INOTIFY=y
975# CONFIG_QUOTA is not set
976CONFIG_QUOTACTL=y
977# CONFIG_DNOTIFY is not set
978# CONFIG_AUTOFS_FS is not set
979CONFIG_AUTOFS4_FS=y
980# CONFIG_FUSE_FS is not set
981
982#
983# CD-ROM/DVD Filesystems
984#
985# CONFIG_ISO9660_FS is not set
986# CONFIG_UDF_FS is not set
987
988#
989# DOS/FAT/NT Filesystems
990#
991# CONFIG_MSDOS_FS is not set
992# CONFIG_VFAT_FS is not set
993# CONFIG_NTFS_FS is not set
994
995#
996# Pseudo filesystems
997#
998CONFIG_PROC_FS=y
999CONFIG_PROC_KCORE=y
1000CONFIG_SYSFS=y
1001CONFIG_TMPFS=y
1002# CONFIG_HUGETLB_PAGE is not set
1003CONFIG_RAMFS=y
1004# CONFIG_RELAYFS_FS is not set
1005# CONFIG_CONFIGFS_FS is not set
1006
1007#
1008# Miscellaneous filesystems
1009#
1010# CONFIG_ADFS_FS is not set
1011# CONFIG_AFFS_FS is not set
1012# CONFIG_HFS_FS is not set
1013# CONFIG_HFSPLUS_FS is not set
1014# CONFIG_BEFS_FS is not set
1015# CONFIG_BFS_FS is not set
1016# CONFIG_EFS_FS is not set
1017CONFIG_CRAMFS=m
1018# CONFIG_VXFS_FS is not set
1019# CONFIG_HPFS_FS is not set
1020# CONFIG_QNX4FS_FS is not set
1021# CONFIG_SYSV_FS is not set
1022# CONFIG_UFS_FS is not set
1023
1024#
1025# Network File Systems
1026#
1027CONFIG_NFS_FS=y
1028CONFIG_NFS_V3=y
1029# CONFIG_NFS_V3_ACL is not set
1030# CONFIG_NFS_V4 is not set
1031# CONFIG_NFS_DIRECTIO is not set
1032# CONFIG_NFSD is not set
1033CONFIG_ROOT_NFS=y
1034CONFIG_LOCKD=y
1035CONFIG_LOCKD_V4=y
1036CONFIG_NFS_COMMON=y
1037CONFIG_SUNRPC=y
1038# CONFIG_RPCSEC_GSS_KRB5 is not set
1039# CONFIG_RPCSEC_GSS_SPKM3 is not set
1040# CONFIG_SMB_FS is not set
1041# CONFIG_CIFS is not set
1042# CONFIG_NCP_FS is not set
1043# CONFIG_CODA_FS is not set
1044# CONFIG_AFS_FS is not set
1045# CONFIG_9P_FS is not set
1046
1047#
1048# Partition Types
1049#
1050# CONFIG_PARTITION_ADVANCED is not set
1051CONFIG_MSDOS_PARTITION=y
1052
1053#
1054# Native Language Support
1055#
1056# CONFIG_NLS is not set
1057
1058#
1059# Profiling support
1060#
1061# CONFIG_PROFILING is not set
1062
1063#
1064# Kernel hacking
1065#
1066# CONFIG_PRINTK_TIME is not set
1067# CONFIG_MAGIC_SYSRQ is not set
1068# CONFIG_DEBUG_KERNEL is not set
1069CONFIG_LOG_BUF_SHIFT=14
1070CONFIG_CROSSCOMPILE=y
1071CONFIG_CMDLINE="mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs"
1072
1073#
1074# Security options
1075#
1076CONFIG_KEYS=y
1077CONFIG_KEYS_DEBUG_PROC_KEYS=y
1078# CONFIG_SECURITY is not set
1079
1080#
1081# Cryptographic options
1082#
1083# CONFIG_CRYPTO is not set
1084
1085#
1086# Hardware crypto devices
1087#
1088
1089#
1090# Library routines
1091#
1092# CONFIG_CRC_CCITT is not set
1093# CONFIG_CRC16 is not set
1094CONFIG_CRC32=y
1095# CONFIG_LIBCRC32C is not set
1096CONFIG_ZLIB_INFLATE=m
diff --git a/arch/mips/ddb5xxx/ddb5074/Makefile b/arch/mips/ddb5xxx/ddb5074/Makefile
index 488206b8d94e..304c02107b46 100644
--- a/arch/mips/ddb5xxx/ddb5074/Makefile
+++ b/arch/mips/ddb5xxx/ddb5074/Makefile
@@ -3,6 +3,6 @@
3# under Linux. 3# under Linux.
4# 4#
5 5
6obj-y += setup.o irq.o int-handler.o nile4_pic.o 6obj-y += setup.o irq.o nile4_pic.o
7 7
8EXTRA_AFLAGS := $(CFLAGS) 8EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/ddb5xxx/ddb5074/int-handler.S b/arch/mips/ddb5xxx/ddb5074/int-handler.S
deleted file mode 100644
index a78644150b37..000000000000
--- a/arch/mips/ddb5xxx/ddb5074/int-handler.S
+++ /dev/null
@@ -1,120 +0,0 @@
1/*
2 * arch/mips/ddb5074/int-handler.S -- NEC DDB Vrc-5074 interrupt handler
3 *
4 * Based on arch/mips/sgi/kernel/indyIRQ.S
5 *
6 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
7 *
8 * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com>
9 * Sony Software Development Center Europe (SDCE), Brussels
10 */
11#include <asm/asm.h>
12#include <asm/mipsregs.h>
13#include <asm/regdef.h>
14#include <asm/stackframe.h>
15
16/* A lot of complication here is taken away because:
17 *
18 * 1) We handle one interrupt and return, sitting in a loop and moving across
19 * all the pending IRQ bits in the cause register is _NOT_ the answer, the
20 * common case is one pending IRQ so optimize in that direction.
21 *
22 * 2) We need not check against bits in the status register IRQ mask, that
23 * would make this routine slow as hell.
24 *
25 * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
26 * between like BSD spl() brain-damage.
27 *
28 * Furthermore, the IRQs on the INDY look basically (barring software IRQs
29 * which we don't use at all) like:
30 *
31 * MIPS IRQ Source
32 * -------- ------
33 * 0 Software (ignored)
34 * 1 Software (ignored)
35 * 2 Local IRQ level zero
36 * 3 Local IRQ level one
37 * 4 8254 Timer zero
38 * 5 8254 Timer one
39 * 6 Bus Error
40 * 7 R4k timer (what we use)
41 *
42 * We handle the IRQ according to _our_ priority which is:
43 *
44 * Highest ---- R4k Timer
45 * Local IRQ zero
46 * Local IRQ one
47 * Bus Error
48 * 8254 Timer zero
49 * Lowest ---- 8254 Timer one
50 *
51 * then we just return, if multiple IRQs are pending then we will just take
52 * another exception, big deal.
53 */
54
55 .text
56 .set noreorder
57 .set noat
58 .align 5
59 NESTED(ddbIRQ, PT_SIZE, sp)
60 SAVE_ALL
61 CLI
62 .set at
63 mfc0 s0, CP0_CAUSE # get irq mask
64
65#if 1
66 mfc0 t2,CP0_STATUS # get enabled interrupts
67 and s0,t2 # isolate allowed ones
68#endif
69 /* First we check for r4k counter/timer IRQ. */
70 andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero
71 beq a0, zero, 1f
72 andi a0, s0, CAUSEF_IP3 # delay slot, check local level one
73
74 /* Wheee, local level zero interrupt. */
75 jal ddb_local0_irqdispatch
76 move a0, sp # delay slot
77
78 j ret_from_irq
79 nop # delay slot
80
811:
82 beq a0, zero, 1f
83 andi a0, s0, CAUSEF_IP6 # delay slot, check bus error
84
85 /* Wheee, local level one interrupt. */
86 move a0, sp
87 jal ddb_local1_irqdispatch
88 nop
89
90 j ret_from_irq
91 nop
92
931:
94 beq a0, zero, 1f
95 nop
96
97 /* Wheee, an asynchronous bus error... */
98 move a0, sp
99 jal ddb_buserror_irq
100 nop
101
102 j ret_from_irq
103 nop
104
1051:
106 /* Here by mistake? This is possible, what can happen
107 * is that by the time we take the exception the IRQ
108 * pin goes low, so just leave if this is the case.
109 */
110 andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5)
111 beq a0, zero, 1f
112
113 /* Must be one of the 8254 timers... */
114 move a0, sp
115 jal ddb_8254timer_irq
116 nop
1171:
118 j ret_from_irq
119 nop
120 END(ddbIRQ)
diff --git a/arch/mips/ddb5xxx/ddb5074/irq.c b/arch/mips/ddb5xxx/ddb5074/irq.c
index 45088a1be414..60c087b7738c 100644
--- a/arch/mips/ddb5xxx/ddb5074/irq.c
+++ b/arch/mips/ddb5xxx/ddb5074/irq.c
@@ -21,8 +21,6 @@
21#include <asm/ddb5xxx/ddb5074.h> 21#include <asm/ddb5xxx/ddb5074.h>
22 22
23 23
24extern asmlinkage void ddbIRQ(void);
25
26static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; 24static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL };
27 25
28#define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */ 26#define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */
@@ -90,7 +88,7 @@ static void m1543_irq_setup(void)
90 88
91} 89}
92 90
93void ddb_local0_irqdispatch(struct pt_regs *regs) 91static void ddb_local0_irqdispatch(struct pt_regs *regs)
94{ 92{
95 u32 mask; 93 u32 mask;
96 int nile4_irq; 94 int nile4_irq;
@@ -118,29 +116,41 @@ void ddb_local0_irqdispatch(struct pt_regs *regs)
118 } 116 }
119} 117}
120 118
121void ddb_local1_irqdispatch(void) 119static void ddb_local1_irqdispatch(void)
122{ 120{
123 printk("ddb_local1_irqdispatch called\n"); 121 printk("ddb_local1_irqdispatch called\n");
124} 122}
125 123
126void ddb_buserror_irq(void) 124static void ddb_buserror_irq(void)
127{ 125{
128 printk("ddb_buserror_irq called\n"); 126 printk("ddb_buserror_irq called\n");
129} 127}
130 128
131void ddb_8254timer_irq(void) 129static void ddb_8254timer_irq(void)
132{ 130{
133 printk("ddb_8254timer_irq called\n"); 131 printk("ddb_8254timer_irq called\n");
134} 132}
135 133
134asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
135{
136 unsigned int pending = read_c0_cause() & read_c0_status();
137
138 if (pending & CAUSEF_IP2)
139 ddb_local0_irqdispatch(regs);
140 else if (pending & CAUSEF_IP3)
141 ddb_local1_irqdispatch();
142 else if (pending & CAUSEF_IP6)
143 ddb_buserror_irq();
144 else if (pending & (CAUSEF_IP4 | CAUSEF_IP5))
145 ddb_8254timer_irq();
146}
147
136void __init arch_init_irq(void) 148void __init arch_init_irq(void)
137{ 149{
138 /* setup cascade interrupts */ 150 /* setup cascade interrupts */
139 setup_irq(NILE4_IRQ_BASE + NILE4_INT_INTE, &irq_cascade); 151 setup_irq(NILE4_IRQ_BASE + NILE4_INT_INTE, &irq_cascade);
140 setup_irq(CPU_IRQ_BASE + CPU_NILE4_CASCADE, &irq_cascade); 152 setup_irq(CPU_IRQ_BASE + CPU_NILE4_CASCADE, &irq_cascade);
141 153
142 set_except_vector(0, ddbIRQ);
143
144 nile4_irq_setup(NILE4_IRQ_BASE); 154 nile4_irq_setup(NILE4_IRQ_BASE);
145 m1543_irq_setup(); 155 m1543_irq_setup();
146 init_i8259_irqs(); 156 init_i8259_irqs();
diff --git a/arch/mips/ddb5xxx/ddb5476/Makefile b/arch/mips/ddb5xxx/ddb5476/Makefile
index 61eec363cb02..ab0312cb47b4 100644
--- a/arch/mips/ddb5xxx/ddb5476/Makefile
+++ b/arch/mips/ddb5xxx/ddb5476/Makefile
@@ -3,7 +3,7 @@
3# under Linux. 3# under Linux.
4# 4#
5 5
6obj-y += setup.o irq.o int-handler.o nile4_pic.o vrc5476_irq.o 6obj-y += setup.o irq.o nile4_pic.o vrc5476_irq.o
7obj-$(CONFIG_KGDB) += dbg_io.o 7obj-$(CONFIG_KGDB) += dbg_io.o
8 8
9EXTRA_AFLAGS := $(CFLAGS) 9EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/ddb5xxx/ddb5476/int-handler.S b/arch/mips/ddb5xxx/ddb5476/int-handler.S
deleted file mode 100644
index 12c292e189ba..000000000000
--- a/arch/mips/ddb5xxx/ddb5476/int-handler.S
+++ /dev/null
@@ -1,112 +0,0 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: jsun@mvista.com or jsun@junsun.net
4 *
5 * First-level interrupt dispatcher for ddb5476
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12#include <asm/asm.h>
13#include <asm/mipsregs.h>
14#include <asm/addrspace.h>
15#include <asm/regdef.h>
16#include <asm/stackframe.h>
17
18#include <asm/ddb5xxx/ddb5476.h>
19
20/*
21 * first level interrupt dispatcher for ocelot board -
22 * We check for the timer first, then check PCI ints A and D.
23 * Then check for serial IRQ and fall through.
24 */
25 .align 5
26 NESTED(ddb5476_handle_int, PT_SIZE, sp)
27 SAVE_ALL
28 CLI
29 .set at
30 .set noreorder
31 mfc0 t0, CP0_CAUSE
32 mfc0 t2, CP0_STATUS
33
34 and t0, t2
35
36 andi t1, t0, STATUSF_IP7 /* cpu timer */
37 bnez t1, ll_cpu_ip7
38 andi t1, t0, STATUSF_IP2 /* vrc5476 & i8259 */
39 bnez t1, ll_cpu_ip2
40 andi t1, t0, STATUSF_IP3
41 bnez t1, ll_cpu_ip3
42 andi t1, t0, STATUSF_IP4
43 bnez t1, ll_cpu_ip4
44 andi t1, t0, STATUSF_IP5
45 bnez t1, ll_cpu_ip5
46 andi t1, t0, STATUSF_IP6
47 bnez t1, ll_cpu_ip6
48 andi t1, t0, STATUSF_IP0 /* software int 0 */
49 bnez t1, ll_cpu_ip0
50 andi t1, t0, STATUSF_IP1 /* software int 1 */
51 bnez t1, ll_cpu_ip1
52 nop
53
54 .set reorder
55
56 /* wrong alarm or masked ... */
57 // j spurious_interrupt
58 move a0, sp
59 jal vrc5476_irq_dispatch
60 j ret_from_irq
61 nop
62
63 .align 5
64
65ll_cpu_ip0:
66 li a0, CPU_IRQ_BASE + 0
67 move a1, sp
68 jal do_IRQ
69 j ret_from_irq
70
71ll_cpu_ip1:
72 li a0, CPU_IRQ_BASE + 1
73 move a1, sp
74 jal do_IRQ
75 j ret_from_irq
76
77ll_cpu_ip2: /* jump to second-level dispatching */
78 move a0, sp
79 jal vrc5476_irq_dispatch
80 j ret_from_irq
81
82ll_cpu_ip3:
83 li a0, CPU_IRQ_BASE + 3
84 move a1, sp
85 jal do_IRQ
86 j ret_from_irq
87
88ll_cpu_ip4:
89 li a0, CPU_IRQ_BASE + 4
90 move a1, sp
91 jal do_IRQ
92 j ret_from_irq
93
94ll_cpu_ip5:
95 li a0, CPU_IRQ_BASE + 5
96 move a1, sp
97 jal do_IRQ
98 j ret_from_irq
99
100ll_cpu_ip6:
101 li a0, CPU_IRQ_BASE + 6
102 move a1, sp
103 jal do_IRQ
104 j ret_from_irq
105
106ll_cpu_ip7:
107 li a0, CPU_IRQ_BASE + 7
108 move a1, sp
109 jal do_IRQ
110 j ret_from_irq
111
112 END(ddb5476_handle_int)
diff --git a/arch/mips/ddb5xxx/ddb5476/irq.c b/arch/mips/ddb5xxx/ddb5476/irq.c
index 5388b5868c4a..7583a1f30711 100644
--- a/arch/mips/ddb5xxx/ddb5476/irq.c
+++ b/arch/mips/ddb5xxx/ddb5476/irq.c
@@ -110,11 +110,36 @@ static void nile4_irq_setup(void)
110static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; 110static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL };
111static struct irqaction irq_error = { no_action, 0, CPU_MASK_NONE, "error", NULL, NULL }; 111static struct irqaction irq_error = { no_action, 0, CPU_MASK_NONE, "error", NULL, NULL };
112 112
113extern asmlinkage void ddb5476_handle_int(void);
114extern int setup_irq(unsigned int irq, struct irqaction *irqaction); 113extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
115extern void mips_cpu_irq_init(u32 irq_base); 114extern void mips_cpu_irq_init(u32 irq_base);
116extern void vrc5476_irq_init(u32 irq_base); 115extern void vrc5476_irq_init(u32 irq_base);
117 116
117extern void vrc5476_irq_dispatch(struct pt_regs *regs);
118
119asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
120{
121 unsigned int pending = read_c0_cause() & read_c0_status();
122
123 if (pending & STATUSF_IP7)
124 do_IRQ(CPU_IRQ_BASE + 7, regs);
125 else if (pending & STATUSF_IP2)
126 vrc5476_irq_dispatch(regs);
127 else if (pending & STATUSF_IP3)
128 do_IRQ(CPU_IRQ_BASE + 3, regs);
129 else if (pending & STATUSF_IP4)
130 do_IRQ(CPU_IRQ_BASE + 4, regs);
131 else if (pending & STATUSF_IP5)
132 do_IRQ(CPU_IRQ_BASE + 5, regs);
133 else if (pending & STATUSF_IP6)
134 do_IRQ(CPU_IRQ_BASE + 6, regs);
135 else if (pending & STATUSF_IP0)
136 do_IRQ(CPU_IRQ_BASE, regs);
137 else if (pending & STATUSF_IP1)
138 do_IRQ(CPU_IRQ_BASE + 1, regs);
139
140 vrc5476_irq_dispatch(regs);
141}
142
118void __init arch_init_irq(void) 143void __init arch_init_irq(void)
119{ 144{
120 /* hardware initialization */ 145 /* hardware initialization */
@@ -137,7 +162,4 @@ void __init arch_init_irq(void)
137 setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_LBRT, &irq_error); 162 setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_LBRT, &irq_error);
138 setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCIS, &irq_error); 163 setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCIS, &irq_error);
139 setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCI, &irq_error); 164 setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCI, &irq_error);
140
141 /* setup the grandpa intr vector */
142 set_except_vector(0, ddb5476_handle_int);
143} 165}
diff --git a/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c b/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
index f66fe5b58636..a3c5e7b18018 100644
--- a/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
+++ b/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c
@@ -77,11 +77,9 @@ vrc5476_irq_init(u32 base)
77} 77}
78 78
79 79
80asmlinkage void 80void
81vrc5476_irq_dispatch(struct pt_regs *regs) 81vrc5476_irq_dispatch(struct pt_regs *regs)
82{ 82{
83 extern void spurious_interrupt(void);
84
85 u32 mask; 83 u32 mask;
86 int nile4_irq; 84 int nile4_irq;
87 85
@@ -107,5 +105,5 @@ vrc5476_irq_dispatch(struct pt_regs *regs)
107 return; 105 return;
108 } 106 }
109 } 107 }
110 spurious_interrupt(); 108 spurious_interrupt(regs);
111} 109}
diff --git a/arch/mips/ddb5xxx/ddb5477/Makefile b/arch/mips/ddb5xxx/ddb5477/Makefile
index b79b43c9f93b..ea68815ad17a 100644
--- a/arch/mips/ddb5xxx/ddb5477/Makefile
+++ b/arch/mips/ddb5xxx/ddb5477/Makefile
@@ -2,7 +2,7 @@
2# Makefile for NEC DDB-Vrc5477 board 2# Makefile for NEC DDB-Vrc5477 board
3# 3#
4 4
5obj-y += int-handler.o irq.o irq_5477.o setup.o lcd44780.o 5obj-y += irq.o irq_5477.o setup.o lcd44780.o
6 6
7obj-$(CONFIG_RUNTIME_DEBUG) += debug.o 7obj-$(CONFIG_RUNTIME_DEBUG) += debug.o
8obj-$(CONFIG_KGDB) += kgdb_io.o 8obj-$(CONFIG_KGDB) += kgdb_io.o
diff --git a/arch/mips/ddb5xxx/ddb5477/int-handler.S b/arch/mips/ddb5xxx/ddb5477/int-handler.S
deleted file mode 100644
index a2502a14400e..000000000000
--- a/arch/mips/ddb5xxx/ddb5477/int-handler.S
+++ /dev/null
@@ -1,75 +0,0 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: jsun@mvista.com or jsun@junsun.net
4 *
5 * First-level interrupt dispatcher for ddb5477
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12#include <asm/asm.h>
13#include <asm/mipsregs.h>
14#include <asm/addrspace.h>
15#include <asm/regdef.h>
16#include <asm/stackframe.h>
17#include <asm/ddb5xxx/ddb5477.h>
18
19/*
20 * first level interrupt dispatcher for ocelot board -
21 * We check for the timer first, then check PCI ints A and D.
22 * Then check for serial IRQ and fall through.
23 */
24 .align 5
25 NESTED(ddb5477_handle_int, PT_SIZE, sp)
26 SAVE_ALL
27 CLI
28 .set at
29 .set noreorder
30 mfc0 t0, CP0_CAUSE
31 mfc0 t2, CP0_STATUS
32
33 and t0, t2
34
35 andi t1, t0, STATUSF_IP7 /* cpu timer */
36 bnez t1, ll_cputimer_irq
37 andi t1, t0, (STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6 )
38 bnez t1, ll_vrc5477_irq
39 andi t1, t0, STATUSF_IP0 /* software int 0 */
40 bnez t1, ll_cpu_ip0
41 andi t1, t0, STATUSF_IP1 /* software int 1 */
42 bnez t1, ll_cpu_ip1
43 nop
44 .set reorder
45
46 /* wrong alarm or masked ... */
47 j spurious_interrupt
48 nop
49 END(ddb5477_handle_int)
50
51 .align 5
52
53ll_vrc5477_irq:
54 move a0, sp
55 jal vrc5477_irq_dispatch
56 j ret_from_irq
57
58ll_cputimer_irq:
59 li a0, CPU_IRQ_BASE + 7
60 move a1, sp
61 jal do_IRQ
62 j ret_from_irq
63
64
65ll_cpu_ip0:
66 li a0, CPU_IRQ_BASE + 0
67 move a1, sp
68 jal do_IRQ
69 j ret_from_irq
70
71ll_cpu_ip1:
72 li a0, CPU_IRQ_BASE + 1
73 move a1, sp
74 jal do_IRQ
75 j ret_from_irq
diff --git a/arch/mips/ddb5xxx/ddb5477/irq.c b/arch/mips/ddb5xxx/ddb5477/irq.c
index 9ffe1a9142ca..de433cf9fb50 100644
--- a/arch/mips/ddb5xxx/ddb5477/irq.c
+++ b/arch/mips/ddb5xxx/ddb5477/irq.c
@@ -75,7 +75,6 @@ set_pci_int_attr(u32 pci, u32 intn, u32 active, u32 trigger)
75 75
76extern void vrc5477_irq_init(u32 base); 76extern void vrc5477_irq_init(u32 base);
77extern void mips_cpu_irq_init(u32 base); 77extern void mips_cpu_irq_init(u32 base);
78extern asmlinkage void ddb5477_handle_int(void);
79extern int setup_irq(unsigned int irq, struct irqaction *irqaction); 78extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
80static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; 79static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL };
81 80
@@ -135,9 +134,6 @@ void __init arch_init_irq(void)
135 /* setup cascade interrupts */ 134 /* setup cascade interrupts */
136 setup_irq(VRC5477_IRQ_BASE + VRC5477_I8259_CASCADE, &irq_cascade); 135 setup_irq(VRC5477_IRQ_BASE + VRC5477_I8259_CASCADE, &irq_cascade);
137 setup_irq(CPU_IRQ_BASE + CPU_VRC5477_CASCADE, &irq_cascade); 136 setup_irq(CPU_IRQ_BASE + CPU_VRC5477_CASCADE, &irq_cascade);
138
139 /* hook up the first-level interrupt handler */
140 set_except_vector(0, ddb5477_handle_int);
141} 137}
142 138
143u8 i8259_interrupt_ack(void) 139u8 i8259_interrupt_ack(void)
@@ -159,7 +155,7 @@ u8 i8259_interrupt_ack(void)
159 * the first level int-handler will jump here if it is a vrc5477 irq 155 * the first level int-handler will jump here if it is a vrc5477 irq
160 */ 156 */
161#define NUM_5477_IRQS 32 157#define NUM_5477_IRQS 32
162asmlinkage void 158static void
163vrc5477_irq_dispatch(struct pt_regs *regs) 159vrc5477_irq_dispatch(struct pt_regs *regs)
164{ 160{
165 u32 intStatus; 161 u32 intStatus;
@@ -197,3 +193,21 @@ vrc5477_irq_dispatch(struct pt_regs *regs)
197 } 193 }
198 } 194 }
199} 195}
196
197#define VR5477INTS (STATUSF_IP2|STATUSF_IP3|STATUSF_IP4|STATUSF_IP5|STATUSF_IP6)
198
199asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
200{
201 unsigned int pending = read_c0_cause() & read_c0_status();
202
203 if (pending & STATUSF_IP7)
204 do_IRQ(CPU_IRQ_BASE + 7, regs);
205 else if (pending & VR5477INTS)
206 vrc5477_irq_dispatch(regs);
207 else if (pending & STATUSF_IP0)
208 do_IRQ(CPU_IRQ_BASE, regs);
209 else if (pending & STATUSF_IP1)
210 do_IRQ(CPU_IRQ_BASE + 1, regs);
211 else
212 spurious_interrupt(regs);
213}
diff --git a/arch/mips/dec/boot/decstation.c b/arch/mips/dec/boot/decstation.c
index 56fd4277555e..4db8bacaf22d 100644
--- a/arch/mips/dec/boot/decstation.c
+++ b/arch/mips/dec/boot/decstation.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * arch/mips/dec/decstation.c 2 * arch/mips/dec/decstation.c
3 */ 3 */
4#include <asm/sections.h>
4 5
5#define RELOC 6#define RELOC
6#define INITRD 7#define INITRD
@@ -24,7 +25,7 @@
24#define INITRD_START (*(unsigned long *) (PARAM+0x218)) 25#define INITRD_START (*(unsigned long *) (PARAM+0x218))
25#define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c)) 26#define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c))
26 27
27extern int _ftext, _end; /* begin and end of kernel image */ 28extern int _ftext; /* begin and end of kernel image */
28extern void kernel_entry(int, char **, unsigned long, int *); 29extern void kernel_entry(int, char **, unsigned long, int *);
29 30
30void * memcpy(void * dest, const void *src, unsigned int count) 31void * memcpy(void * dest, const void *src, unsigned int count)
diff --git a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S
index 41fa372007bf..e8ec93e33fe6 100644
--- a/arch/mips/dec/int-handler.S
+++ b/arch/mips/dec/int-handler.S
@@ -36,7 +36,7 @@
36 .text 36 .text
37 .set noreorder 37 .set noreorder
38/* 38/*
39 * decstation_handle_int: Interrupt handler for DECstations 39 * plat_irq_dispatch: Interrupt handler for DECstations
40 * 40 *
41 * We follow the model in the Indy interrupt code by David Miller, where he 41 * We follow the model in the Indy interrupt code by David Miller, where he
42 * says: a lot of complication here is taken away because: 42 * says: a lot of complication here is taken away because:
@@ -125,11 +125,7 @@
125 * just take another exception, big deal. 125 * just take another exception, big deal.
126 */ 126 */
127 .align 5 127 .align 5
128 NESTED(decstation_handle_int, PT_SIZE, ra) 128 NESTED(plat_irq_dispatch, PT_SIZE, ra)
129 .set noat
130 SAVE_ALL
131 CLI # TEST: interrupts should be off
132 .set at
133 .set noreorder 129 .set noreorder
134 130
135 /* 131 /*
@@ -282,9 +278,11 @@ fpu:
282#endif 278#endif
283 279
284spurious: 280spurious:
285 j spurious_interrupt 281 jal spurious_interrupt
286 nop 282 nop
287 END(decstation_handle_int) 283 j ret_from_irq
284 nop
285 END(plat_irq_dispatch)
288 286
289/* 287/*
290 * Generic unimplemented interrupt routines -- cpu_mask_nr_tbl 288 * Generic unimplemented interrupt routines -- cpu_mask_nr_tbl
diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c
index 7c1ca8f6330e..ad5d436d80c1 100644
--- a/arch/mips/dec/setup.c
+++ b/arch/mips/dec/setup.c
@@ -48,8 +48,6 @@ extern void dec_machine_halt(void);
48extern void dec_machine_power_off(void); 48extern void dec_machine_power_off(void);
49extern irqreturn_t dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs); 49extern irqreturn_t dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs);
50 50
51extern asmlinkage void decstation_handle_int(void);
52
53unsigned long dec_kn_slot_base, dec_kn_slot_size; 51unsigned long dec_kn_slot_base, dec_kn_slot_size;
54 52
55EXPORT_SYMBOL(dec_kn_slot_base); 53EXPORT_SYMBOL(dec_kn_slot_base);
@@ -744,7 +742,6 @@ void __init arch_init_irq(void)
744 panic("Don't know how to set this up!"); 742 panic("Don't know how to set this up!");
745 break; 743 break;
746 } 744 }
747 set_except_vector(0, decstation_handle_int);
748 745
749 /* Free the FPU interrupt if the exception is present. */ 746 /* Free the FPU interrupt if the exception is present. */
750 if (!cpu_has_nofpuex) { 747 if (!cpu_has_nofpuex) {
diff --git a/arch/mips/galileo-boards/ev96100/Makefile b/arch/mips/galileo-boards/ev96100/Makefile
index 58c02f9db69d..cd868ec78cbc 100644
--- a/arch/mips/galileo-boards/ev96100/Makefile
+++ b/arch/mips/galileo-boards/ev96100/Makefile
@@ -6,4 +6,4 @@
6# Makefile for the Galileo EV96100 board. 6# Makefile for the Galileo EV96100 board.
7# 7#
8 8
9obj-y += init.o irq.o puts.o reset.o time.o int-handler.o setup.o 9obj-y += init.o irq.o puts.o reset.o time.o setup.o
diff --git a/arch/mips/galileo-boards/ev96100/int-handler.S b/arch/mips/galileo-boards/ev96100/int-handler.S
deleted file mode 100644
index ff4d10a38859..000000000000
--- a/arch/mips/galileo-boards/ev96100/int-handler.S
+++ /dev/null
@@ -1,33 +0,0 @@
1#include <asm/asm.h>
2#include <asm/mipsregs.h>
3#include <asm/regdef.h>
4#include <asm/stackframe.h>
5
6 .set noat
7 .align 5
8
9NESTED(ev96100IRQ, PT_SIZE, sp)
10 SAVE_ALL
11 CLI # Important: mark KERNEL mode !
12
13 mfc0 t0, CP0_CAUSE # get pending interrupts
14 mfc0 t1, CP0_STATUS # get enabled interrupts
15 and t0, t1 # isolate allowed ones
16
17 # FIX ME add R7000 extensions
18 andi t0,0xff00 # isolate pending bits
19 andi a0, t0, CAUSEF_IP7
20 beq a0, zero, 1f
21 move a0, sp
22 jal mips_timer_interrupt
23 j ret_from_irq
24
251: beqz t0, 3f # spurious interrupt
26
27 move a0, t0
28 move a1, sp
29 jal ev96100_cpu_irq
30 j ret_from_irq
31
323: j spurious_interrupt
33 END(ev96100IRQ)
diff --git a/arch/mips/galileo-boards/ev96100/irq.c b/arch/mips/galileo-boards/ev96100/irq.c
index 97bf094da4fe..ee5d6720f23b 100644
--- a/arch/mips/galileo-boards/ev96100/irq.c
+++ b/arch/mips/galileo-boards/ev96100/irq.c
@@ -40,8 +40,6 @@
40#include <linux/interrupt.h> 40#include <linux/interrupt.h>
41#include <asm/irq_cpu.h> 41#include <asm/irq_cpu.h>
42 42
43extern asmlinkage void ev96100IRQ(void);
44
45static inline unsigned int ffz8(unsigned int word) 43static inline unsigned int ffz8(unsigned int word)
46{ 44{
47 unsigned long k; 45 unsigned long k;
@@ -54,13 +52,26 @@ static inline unsigned int ffz8(unsigned int word)
54 return k; 52 return k;
55} 53}
56 54
57asmlinkage void ev96100_cpu_irq(unsigned int pendin) 55extern void mips_timer_interrupt(struct pt_regs *regs);
56
57asmlinkage void ev96100_cpu_irq(unsigned int pending, struct pt_regs *regs)
58{ 58{
59 do_IRQ(ffz8(pending >> 8), regs); 59 do_IRQ(ffz8(pending >> 8), regs);
60} 60}
61 61
62asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
63{
64 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
65
66 if (pending & CAUSEF_IP7)
67 mips_timer_interrupt(regs);
68 else if (pending)
69 ev96100_cpu_irq(pending, regs);
70 else
71 spurious_interrupt(regs);
72}
73
62void __init arch_init_irq(void) 74void __init arch_init_irq(void)
63{ 75{
64 set_except_vector(0, ev96100IRQ);
65 mips_cpu_irq_init(0); 76 mips_cpu_irq_init(0);
66} 77}
diff --git a/arch/mips/gt64120/ev64120/Makefile b/arch/mips/gt64120/ev64120/Makefile
index ebe91c57e173..b2c53a8f8718 100644
--- a/arch/mips/gt64120/ev64120/Makefile
+++ b/arch/mips/gt64120/ev64120/Makefile
@@ -6,6 +6,6 @@
6# Makefile for the Galileo EV64120 board. 6# Makefile for the Galileo EV64120 board.
7# 7#
8 8
9obj-y += int-handler.o irq.o promcon.o reset.o serialGT.o setup.o 9obj-y += irq.o promcon.o reset.o serialGT.o setup.o
10 10
11EXTRA_AFLAGS := $(CFLAGS) 11EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/gt64120/ev64120/int-handler.S b/arch/mips/gt64120/ev64120/int-handler.S
deleted file mode 100644
index 752435faf2de..000000000000
--- a/arch/mips/gt64120/ev64120/int-handler.S
+++ /dev/null
@@ -1,113 +0,0 @@
1/*
2 * int-handler.S
3 *
4 * Based on the cobalt handler.
5 */
6#include <asm/asm.h>
7#include <asm/mipsregs.h>
8#include <asm/addrspace.h>
9#include <asm/regdef.h>
10#include <asm/stackframe.h>
11
12/*
13 * galileo_handle_int -
14 * We check for the timer first, then check PCI ints A and D.
15 * Then check for serial IRQ and fall through.
16 */
17 .align 5
18 .set reorder
19 .set noat
20 NESTED(galileo_handle_int, PT_SIZE, sp)
21 SAVE_ALL
22 CLI
23 .set at
24 mfc0 t0,CP0_CAUSE
25 mfc0 t2,CP0_STATUS
26
27 and t0,t2
28
29 andi t1,t0,STATUSF_IP4 /* int2 hardware line (timer) */
30 bnez t1,ll_gt64120_irq
31 andi t1,t0,STATUSF_IP2 /* int0 hardware line */
32 bnez t1,ll_pci_intA
33 andi t1,t0,STATUSF_IP5 /* int3 hardware line */
34 bnez t1,ll_pci_intD
35 andi t1,t0,STATUSF_IP6 /* int4 hardware line */
36 bnez t1,ll_serial_irq
37 andi t1,t0,STATUSF_IP7 /* compare int */
38 bnez t1,ll_compare_irq
39 nop
40
41 /* wrong alarm or masked ... */
42 j spurious_interrupt
43 nop
44 END(galileo_handle_int)
45
46
47 .align 5
48 .set reorder
49ll_gt64120_irq:
50 li a0,4
51 move a1,sp
52 jal do_IRQ
53 nop
54 j ret_from_irq
55 nop
56
57 .align 5
58 .set reorder
59ll_compare_irq:
60 li a0,7
61 move a1,sp
62 jal do_IRQ
63 nop
64 j ret_from_irq
65 nop
66
67 .align 5
68 .set reorder
69ll_pci_intA:
70 move a0,sp
71 jal pci_intA
72 nop
73 j ret_from_irq
74 nop
75
76#if 0
77 .align 5
78 .set reorder
79ll_pci_intB:
80 move a0,sp
81 jal pci_intB
82 nop
83 j ret_from_irq
84 nop
85
86 .align 5
87 .set reorder
88ll_pci_intC:
89 move a0,sp
90 jal pci_intC
91 nop
92 j ret_from_irq
93 nop
94#endif
95
96 .align 5
97 .set reorder
98ll_pci_intD:
99 move a0,sp
100 jal pci_intD
101 nop
102 j ret_from_irq
103 nop
104
105 .align 5
106 .set reorder
107ll_serial_irq:
108 li a0,6
109 move a1,sp
110 jal do_IRQ
111 nop
112 j ret_from_irq
113 nop
diff --git a/arch/mips/gt64120/ev64120/irq.c b/arch/mips/gt64120/ev64120/irq.c
index 3b186159b21a..46c468b26b30 100644
--- a/arch/mips/gt64120/ev64120/irq.c
+++ b/arch/mips/gt64120/ev64120/irq.c
@@ -46,14 +46,22 @@
46#include <asm/system.h> 46#include <asm/system.h>
47#include <asm/gt64120.h> 47#include <asm/gt64120.h>
48 48
49asmlinkage inline void pci_intA(struct pt_regs *regs) 49asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
50{ 50{
51 do_IRQ(GT_INTA, regs); 51 unsigned int pending = read_c0_status() & read_c0_cause();
52} 52
53 53 if (pending & STATUSF_IP4) /* int2 hardware line (timer) */
54asmlinkage inline void pci_intD(struct pt_regs *regs) 54 do_IRQ(4, regs);
55{ 55 else if (pending & STATUSF_IP2) /* int0 hardware line */
56 do_IRQ(GT_INTD, regs); 56 do_IRQ(GT_INTA, regs);
57 else if (pending & STATUSF_IP5) /* int3 hardware line */
58 do_IRQ(GT_INTD, regs);
59 else if (pending & STATUSF_IP6) /* int4 hardware line */
60 do_IRQ(6, regs);
61 else if (pending & STATUSF_IP7) /* compare int */
62 do_IRQ(7, regs);
63 else
64 spurious_interrupt(regs);
57} 65}
58 66
59static void disable_ev64120_irq(unsigned int irq_nr) 67static void disable_ev64120_irq(unsigned int irq_nr)
@@ -109,16 +117,11 @@ static struct hw_interrupt_type ev64120_irq_type = {
109 117
110void gt64120_irq_setup(void) 118void gt64120_irq_setup(void)
111{ 119{
112 extern asmlinkage void galileo_handle_int(void);
113
114 /* 120 /*
115 * Clear all of the interrupts while we change the able around a bit. 121 * Clear all of the interrupts while we change the able around a bit.
116 */ 122 */
117 clear_c0_status(ST0_IM); 123 clear_c0_status(ST0_IM);
118 124
119 /* Sets the exception_handler array. */
120 set_except_vector(0, galileo_handle_int);
121
122 local_irq_disable(); 125 local_irq_disable();
123 126
124 /* 127 /*
diff --git a/arch/mips/gt64120/momenco_ocelot/Makefile b/arch/mips/gt64120/momenco_ocelot/Makefile
index 7b59c6567c79..6f708df8373b 100644
--- a/arch/mips/gt64120/momenco_ocelot/Makefile
+++ b/arch/mips/gt64120/momenco_ocelot/Makefile
@@ -2,7 +2,7 @@
2# Makefile for Momentum's Ocelot board. 2# Makefile for Momentum's Ocelot board.
3# 3#
4 4
5obj-y += int-handler.o irq.o prom.o reset.o setup.o 5obj-y += irq.o prom.o reset.o setup.o
6 6
7obj-$(CONFIG_KGDB) += dbg_io.o 7obj-$(CONFIG_KGDB) += dbg_io.o
8 8
diff --git a/arch/mips/gt64120/momenco_ocelot/int-handler.S b/arch/mips/gt64120/momenco_ocelot/int-handler.S
deleted file mode 100644
index 808acef248cc..000000000000
--- a/arch/mips/gt64120/momenco_ocelot/int-handler.S
+++ /dev/null
@@ -1,131 +0,0 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: jsun@mvista.com or jsun@junsun.net
4 *
5 * First-level interrupt dispatcher for ocelot board.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12#include <asm/asm.h>
13#include <asm/mipsregs.h>
14#include <asm/addrspace.h>
15#include <asm/regdef.h>
16#include <asm/stackframe.h>
17
18/*
19 * first level interrupt dispatcher for ocelot board -
20 * We check for the timer first, then check PCI ints A and D.
21 * Then check for serial IRQ and fall through.
22 */
23 .align 5
24 NESTED(ocelot_handle_int, PT_SIZE, sp)
25 SAVE_ALL
26 CLI
27 .set at
28 mfc0 t0, CP0_CAUSE
29 mfc0 t2, CP0_STATUS
30
31 and t0, t2
32
33 andi t1, t0, STATUSF_IP2 /* int0 hardware line */
34 bnez t1, ll_pri_enet_irq
35 andi t1, t0, STATUSF_IP3 /* int1 hardware line */
36 bnez t1, ll_sec_enet_irq
37 andi t1, t0, STATUSF_IP4 /* int2 hardware line */
38 bnez t1, ll_uart1_irq
39 andi t1, t0, STATUSF_IP5 /* int3 hardware line */
40 bnez t1, ll_cpci_irq
41 andi t1, t0, STATUSF_IP6 /* int4 hardware line */
42 bnez t1, ll_galileo_irq
43 andi t1, t0, STATUSF_IP7 /* cpu timer */
44 bnez t1, ll_cputimer_irq
45
46 /* now look at the extended interrupts */
47 mfc0 t0, CP0_CAUSE
48 cfc0 t1, CP0_S1_INTCONTROL
49
50 /* shift the mask 8 bits left to line up the bits */
51 sll t2, t1, 8
52
53 and t0, t2
54 srl t0, t0, 16
55
56 andi t1, t0, STATUSF_IP8 /* int6 hardware line */
57 bnez t1, ll_pmc1_irq
58 andi t1, t0, STATUSF_IP9 /* int7 hardware line */
59 bnez t1, ll_pmc2_irq
60 andi t1, t0, STATUSF_IP10 /* int8 hardware line */
61 bnez t1, ll_cpci_abcd_irq
62 andi t1, t0, STATUSF_IP11 /* int9 hardware line */
63 bnez t1, ll_uart2_irq
64
65 .set reorder
66
67 /* wrong alarm or masked ... */
68 j spurious_interrupt
69 nop
70 END(ocelot_handle_int)
71
72 .align 5
73ll_pri_enet_irq:
74 li a0, 2
75 move a1, sp
76 jal do_IRQ
77 j ret_from_irq
78
79ll_sec_enet_irq:
80 li a0, 3
81 move a1, sp
82 jal do_IRQ
83 j ret_from_irq
84
85ll_uart1_irq:
86 li a0, 4
87 move a1, sp
88 jal do_IRQ
89 j ret_from_irq
90
91ll_cpci_irq:
92 li a0, 5
93 move a1, sp
94 jal do_IRQ
95 j ret_from_irq
96
97ll_galileo_irq:
98 li a0, 6
99 move a1, sp
100 jal do_IRQ
101 j ret_from_irq
102
103ll_cputimer_irq:
104 li a0, 7
105 move a1, sp
106 jal do_IRQ
107 j ret_from_irq
108
109ll_pmc1_irq:
110 li a0, 8
111 move a1, sp
112 jal do_IRQ
113 j ret_from_irq
114
115ll_pmc2_irq:
116 li a0, 9
117 move a1, sp
118 jal do_IRQ
119 j ret_from_irq
120
121ll_cpci_abcd_irq:
122 li a0, 10
123 move a1, sp
124 jal do_IRQ
125 j ret_from_irq
126
127ll_uart2_irq:
128 li a0, 11
129 move a1, sp
130 jal do_IRQ
131 j ret_from_irq
diff --git a/arch/mips/gt64120/momenco_ocelot/irq.c b/arch/mips/gt64120/momenco_ocelot/irq.c
index 4f108da71b23..885f67f32ea3 100644
--- a/arch/mips/gt64120/momenco_ocelot/irq.c
+++ b/arch/mips/gt64120/momenco_ocelot/irq.c
@@ -48,7 +48,38 @@
48#include <asm/mipsregs.h> 48#include <asm/mipsregs.h>
49#include <asm/system.h> 49#include <asm/system.h>
50 50
51extern asmlinkage void ocelot_handle_int(void); 51asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
52{
53 unsigned int pending = read_c0_status() & read_c0_cause();
54
55 if (pending & STATUSF_IP2) /* int0 hardware line */
56 do_IRQ(2, regs);
57 else if (pending & STATUSF_IP3) /* int1 hardware line */
58 do_IRQ(3, regs);
59 else if (pending & STATUSF_IP4) /* int2 hardware line */
60 do_IRQ(4, regs);
61 else if (pending & STATUSF_IP5) /* int3 hardware line */
62 do_IRQ(5, regs);
63 else if (pending & STATUSF_IP6) /* int4 hardware line */
64 do_IRQ(6, regs);
65 else if (pending & STATUSF_IP7) /* cpu timer */
66 do_IRQ(7, regs);
67 else {
68 /*
69 * Now look at the extended interrupts
70 */
71 pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16;
72
73 if (pending & STATUSF_IP8) /* int6 hardware line */
74 do_IRQ(8, regs);
75 else if (pending & STATUSF_IP9) /* int7 hardware line */
76 do_IRQ(9, regs);
77 else if (pending & STATUSF_IP10) /* int8 hardware line */
78 do_IRQ(10, regs);
79 else if (pending & STATUSF_IP11) /* int9 hardware line */
80 do_IRQ(11, regs);
81 }
82}
52 83
53void __init arch_init_irq(void) 84void __init arch_init_irq(void)
54{ 85{
@@ -59,9 +90,6 @@ void __init arch_init_irq(void)
59 clear_c0_status(ST0_IM); 90 clear_c0_status(ST0_IM);
60 local_irq_disable(); 91 local_irq_disable();
61 92
62 /* Sets the first-level interrupt dispatcher. */
63 set_except_vector(0, ocelot_handle_int);
64
65 mips_cpu_irq_init(0); 93 mips_cpu_irq_init(0);
66 rm7k_cpu_irq_init(8); 94 rm7k_cpu_irq_init(8);
67} 95}
diff --git a/arch/mips/ite-boards/generic/Makefile b/arch/mips/ite-boards/generic/Makefile
index 0e7853f43983..63431538d0ec 100644
--- a/arch/mips/ite-boards/generic/Makefile
+++ b/arch/mips/ite-boards/generic/Makefile
@@ -6,7 +6,7 @@
6# Makefile for the ITE 8172 (qed-4n-s01b) board, generic files. 6# Makefile for the ITE 8172 (qed-4n-s01b) board, generic files.
7# 7#
8 8
9obj-y += it8172_setup.o irq.o int-handler.o pmon_prom.o \ 9obj-y += it8172_setup.o irq.o pmon_prom.o \
10 time.o lpc.o puts.o reset.o 10 time.o lpc.o puts.o reset.o
11 11
12obj-$(CONFIG_IT8172_CIR)+= it8172_cir.o 12obj-$(CONFIG_IT8172_CIR)+= it8172_cir.o
diff --git a/arch/mips/ite-boards/generic/int-handler.S b/arch/mips/ite-boards/generic/int-handler.S
deleted file mode 100644
index d190d8add9cb..000000000000
--- a/arch/mips/ite-boards/generic/int-handler.S
+++ /dev/null
@@ -1,63 +0,0 @@
1#include <asm/asm.h>
2#include <asm/mipsregs.h>
3#include <asm/regdef.h>
4#include <asm/stackframe.h>
5
6 .text
7 .set macro
8 .set noat
9 .align 5
10
11NESTED(it8172_IRQ, PT_SIZE, sp)
12 SAVE_ALL
13 CLI # Important: mark KERNEL mode !
14
15 /* We're working with 'reorder' set at this point. */
16 /*
17 * Get pending interrupts
18 */
19
20 mfc0 t0,CP0_CAUSE # get pending interrupts
21 mfc0 t1,CP0_STATUS # get enabled interrupts
22 and t0,t1 # isolate allowed ones
23
24 andi t0,0xff00 # isolate pending bits
25 beqz t0, 3f # spurious interrupt
26
27 andi a0, t0, CAUSEF_IP7
28 beq a0, zero, 1f
29
30 li a0, 127 # MIPS_CPU_TIMER_IRQ = (NR_IRQS-1)
31 move a1, sp
32 jal ll_timer_interrupt
33 j ret_from_irq
34 nop
35
361:
37 andi a0, t0, CAUSEF_IP2 # the only int we expect at this time
38 beq a0, zero, 3f
39 move a0,sp
40 jal it8172_hw0_irqdispatch
41
42 mfc0 t0,CP0_STATUS # disable interrupts
43 ori t0,1
44 xori t0,1
45 mtc0 t0,CP0_STATUS
46 nop
47 nop
48 nop
49
50 la a1, ret_from_irq
51 jr a1
52 nop
53
543:
55 move a0, sp
56 jal mips_spurious_interrupt
57 nop
58 la a1, ret_from_irq
59 jr a1
60 nop
61
62END(it8172_IRQ)
63
diff --git a/arch/mips/ite-boards/generic/irq.c b/arch/mips/ite-boards/generic/irq.c
index e67f96129491..77be7216bdd0 100644
--- a/arch/mips/ite-boards/generic/irq.c
+++ b/arch/mips/ite-boards/generic/irq.c
@@ -62,12 +62,8 @@
62 62
63#define ALLINTS_NOTIMER (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4) 63#define ALLINTS_NOTIMER (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4)
64 64
65void disable_it8172_irq(unsigned int irq_nr);
66void enable_it8172_irq(unsigned int irq_nr);
67
68extern void set_debug_traps(void); 65extern void set_debug_traps(void);
69extern void mips_timer_interrupt(int irq, struct pt_regs *regs); 66extern void mips_timer_interrupt(int irq, struct pt_regs *regs);
70extern asmlinkage void it8172_IRQ(void);
71 67
72struct it8172_intc_regs volatile *it8172_hw0_icregs = 68struct it8172_intc_regs volatile *it8172_hw0_icregs =
73 (struct it8172_intc_regs volatile *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_INTC_BASE)); 69 (struct it8172_intc_regs volatile *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_INTC_BASE));
@@ -181,8 +177,6 @@ void __init arch_init_irq(void)
181 int i; 177 int i;
182 unsigned long flags; 178 unsigned long flags;
183 179
184 set_except_vector(0, it8172_IRQ);
185
186 /* mask all interrupts */ 180 /* mask all interrupts */
187 it8172_hw0_icregs->lb_mask = 0xffff; 181 it8172_hw0_icregs->lb_mask = 0xffff;
188 it8172_hw0_icregs->lpc_mask = 0xffff; 182 it8172_hw0_icregs->lpc_mask = 0xffff;
@@ -282,6 +276,18 @@ void it8172_hw0_irqdispatch(struct pt_regs *regs)
282 do_IRQ(irq, regs); 276 do_IRQ(irq, regs);
283} 277}
284 278
279asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
280{
281 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
282
283 if (!pending)
284 mips_spurious_interrupt(regs);
285 else if (pending & CAUSEF_IP7)
286 ll_timer_interrupt(127, regs);
287 else if (pending & CAUSEF_IP2)
288 it8172_hw0_irqdispatch(regs);
289}
290
285void show_pending_irqs(void) 291void show_pending_irqs(void)
286{ 292{
287 fputs("intstatus: "); 293 fputs("intstatus: ");
diff --git a/arch/mips/ite-boards/generic/time.c b/arch/mips/ite-boards/generic/time.c
index b79817bb6cce..dee497a91807 100644
--- a/arch/mips/ite-boards/generic/time.c
+++ b/arch/mips/ite-boards/generic/time.c
@@ -29,6 +29,7 @@
29#include <linux/sched.h> 29#include <linux/sched.h>
30#include <linux/time.h> 30#include <linux/time.h>
31#include <linux/spinlock.h> 31#include <linux/spinlock.h>
32#include <linux/mc146818rtc.h>
32 33
33#include <asm/time.h> 34#include <asm/time.h>
34#include <asm/mipsregs.h> 35#include <asm/mipsregs.h>
diff --git a/arch/mips/ite-boards/ivr/init.c b/arch/mips/ite-boards/ivr/init.c
index b774db035b31..05cf9218c432 100644
--- a/arch/mips/ite-boards/ivr/init.c
+++ b/arch/mips/ite-boards/ivr/init.c
@@ -34,13 +34,13 @@
34#include <asm/bootinfo.h> 34#include <asm/bootinfo.h>
35#include <linux/string.h> 35#include <linux/string.h>
36#include <linux/kernel.h> 36#include <linux/kernel.h>
37#include <asm/sections.h>
37#include <asm/it8172/it8172.h> 38#include <asm/it8172/it8172.h>
38#include <asm/it8172/it8172_dbg.h> 39#include <asm/it8172/it8172_dbg.h>
39 40
40int prom_argc; 41int prom_argc;
41char **prom_argv, **prom_envp; 42char **prom_argv, **prom_envp;
42 43
43extern char _end;
44extern void __init prom_init_cmdline(void); 44extern void __init prom_init_cmdline(void);
45extern unsigned long __init prom_get_memsize(void); 45extern unsigned long __init prom_get_memsize(void);
46extern void __init it8172_init_ram_resource(unsigned long memsize); 46extern void __init it8172_init_ram_resource(unsigned long memsize);
diff --git a/arch/mips/ite-boards/qed-4n-s01b/init.c b/arch/mips/ite-boards/qed-4n-s01b/init.c
index e8ec8be66a80..ea2a754cafe5 100644
--- a/arch/mips/ite-boards/qed-4n-s01b/init.c
+++ b/arch/mips/ite-boards/qed-4n-s01b/init.c
@@ -34,13 +34,13 @@
34#include <asm/bootinfo.h> 34#include <asm/bootinfo.h>
35#include <linux/string.h> 35#include <linux/string.h>
36#include <linux/kernel.h> 36#include <linux/kernel.h>
37#include <asm/sections.h>
37#include <asm/it8172/it8172.h> 38#include <asm/it8172/it8172.h>
38#include <asm/it8172/it8172_dbg.h> 39#include <asm/it8172/it8172_dbg.h>
39 40
40int prom_argc; 41int prom_argc;
41char **prom_argv, **prom_envp; 42char **prom_argv, **prom_envp;
42 43
43extern char _end;
44extern void __init prom_init_cmdline(void); 44extern void __init prom_init_cmdline(void);
45extern unsigned long __init prom_get_memsize(void); 45extern unsigned long __init prom_get_memsize(void);
46extern void __init it8172_init_ram_resource(unsigned long memsize); 46extern void __init it8172_init_ram_resource(unsigned long memsize);
diff --git a/arch/mips/jazz/Makefile b/arch/mips/jazz/Makefile
index 85749246a671..02bd39add891 100644
--- a/arch/mips/jazz/Makefile
+++ b/arch/mips/jazz/Makefile
@@ -2,6 +2,6 @@
2# Makefile for the Jazz family specific parts of the kernel 2# Makefile for the Jazz family specific parts of the kernel
3# 3#
4 4
5obj-y := int-handler.o irq.o jazzdma.o reset.o setup.o 5obj-y := irq.o jazzdma.o reset.o setup.o
6 6
7EXTRA_AFLAGS := $(CFLAGS) 7EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/jazz/int-handler.S b/arch/mips/jazz/int-handler.S
deleted file mode 100644
index dc752c67b528..000000000000
--- a/arch/mips/jazz/int-handler.S
+++ /dev/null
@@ -1,282 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle and Andreas Busse
7 *
8 * Jazz family specific interrupt stuff
9 *
10 * To do: On Jazz machines we remap some non-ISA interrupts to ISA
11 * interrupts. These interrupts should use their own vectors.
12 * Squeeze the last cycles out of the handlers. Only a dead
13 * cycle is a good cycle.
14 */
15#include <asm/asm.h>
16#include <asm/mipsregs.h>
17#include <asm/jazz.h>
18#include <asm/regdef.h>
19#include <asm/stackframe.h>
20
21/*
22 * jazz_handle_int: Interrupt handler for the ACER Pica-61 boards
23 */
24 .set noreorder
25
26 NESTED(jazz_handle_int, PT_SIZE, ra)
27 .set noat
28 SAVE_ALL
29 CLI
30 .set at
31
32 /*
33 * Get pending interrupts
34 */
35 mfc0 t0,CP0_CAUSE # get pending interrupts
36 mfc0 t1,CP0_STATUS # get enabled interrupts
37 and t0,t1 # isolate allowed ones
38 andi t0,0xff00 # isolate pending bits
39 beqz t0,3f
40 sll t0,16 # delay slot
41
42 /*
43 * Find irq with highest priority
44 * FIXME: This is slow - use binary search
45 */
46 la t1,ll_vectors
471: bltz t0,2f # found pending irq
48 sll t0,1
49 b 1b
50 subu t1,PTRSIZE # delay slot
51
52 /*
53 * Do the low-level stuff
54 */
552: lw t0,(t1)
56 jr t0
57 nop # delay slot
58 END(jazz_handle_int)
59
60ll_sw0: li s1,~IE_SW0
61 mfc0 t0,CP0_CAUSE
62 and t0,s1
63 mtc0 t0,CP0_CAUSE
64 PANIC("Unimplemented sw0 handler")
65
66ll_sw1: li s1,~IE_SW1
67 mfc0 t0,CP0_CAUSE
68 and t0,s1
69 mtc0 t0,CP0_CAUSE
70 PANIC("Unimplemented sw1 handler")
71
72ll_local_dma: li s1,~IE_IRQ0
73 PANIC("Unimplemented local_dma handler")
74
75ll_local_dev: lbu t0,JAZZ_IO_IRQ_SOURCE
76#if PTRSIZE == 8 /* True 64 bit kernel */
77 dsll t0,1
78#endif
79 .set reorder
80 LONG_L t0,local_vector(t0)
81 jr t0
82 .set noreorder
83
84/*
85 * The braindead PICA hardware gives us no way to distinguish if we really
86 * received interrupt 7 from the (E)ISA bus or if we just received an
87 * interrupt with no findable cause. This sometimes happens with braindead
88 * cards. Oh well - for all the Jazz boxes slots are more or less just
89 * whistles and bells and we're aware of the problem.
90 */
91ll_isa_irq: lw a0, JAZZ_EISA_IRQ_ACK
92
93 jal do_IRQ
94 move a1,sp
95
96 j ret_from_irq
97 nop
98
99/*
100 * Hmm... This is not just a plain PC clone so the question is
101 * which devices on Jazz machines can generate an (E)ISA NMI?
102 * (Writing to nonexistent memory?)
103 */
104ll_isa_nmi: li s1,~IE_IRQ3
105 PANIC("Unimplemented isa_nmi handler")
106
107/*
108 * Timer IRQ - remapped to be more similar to an IBM compatible.
109 *
110 * The timer interrupt is handled specially to ensure that the jiffies
111 * variable is updated at all times. Specifically, the timer interrupt is
112 * just like the complete handlers except that it is invoked with interrupts
113 * disabled and should never re-enable them. If other interrupts were
114 * allowed to be processed while the timer interrupt is active, then the
115 * other interrupts would have to avoid using the jiffies variable for delay
116 * and interval timing operations to avoid hanging the system.
117 */
118ll_timer: lw zero,JAZZ_TIMER_REGISTER # timer irq cleared on read
119 li s1,~IE_IRQ4
120
121 li a0, JAZZ_TIMER_IRQ
122 jal do_IRQ
123 move a1,sp
124
125 mfc0 t0,CP0_STATUS # disable interrupts again
126 ori t0,1
127 xori t0,1
128 mtc0 t0,CP0_STATUS
129
130 j ret_from_irq
131 nop
132
133/*
134 * CPU count/compare IRQ (unused)
135 */
136ll_count: j ret_from_irq
137 mtc0 zero,CP0_COMPARE
138
139#if 0
140/*
141 * Call the handler for the interrupt
142 * (Currently unused)
143 */
144call_real: /*
145 * temporarily disable interrupt
146 */
147 mfc0 t2,CP0_STATUS
148 and t2,s1
149 mtc0 t2,CP0_STATUS
150 nor s1,zero,s1
151 jal do_IRQ
152
153 /*
154 * reenable interrupt
155 */
156 mfc0 t2,CP0_STATUS
157 or t2,s1
158 mtc0 t2,CP0_STATUS
159 j ret_from_irq
160#endif
161
162 .data
163 PTR ll_sw0 # SW0
164 PTR ll_sw1 # SW1
165 PTR ll_local_dma # Local DMA
166 PTR ll_local_dev # Local devices
167 PTR ll_isa_irq # ISA IRQ
168 PTR ll_isa_nmi # ISA NMI
169 PTR ll_timer # Timer
170ll_vectors: PTR ll_count # Count/Compare IRQ
171
172 /*
173 * Interrupt handlers for local devices.
174 */
175 .text
176 .set reorder
177loc_no_irq: PANIC("Unimplemented loc_no_irq handler")
178/*
179 * Parallel port IRQ
180 */
181loc_parallel: li s1,~JAZZ_IE_PARALLEL
182 li a0,JAZZ_PARALLEL_IRQ
183 b loc_call
184
185/*
186 * Floppy IRQ
187 */
188loc_floppy: li s1,~JAZZ_IE_FLOPPY
189 li a0,JAZZ_FLOPPY_IRQ
190 b loc_call
191
192/*
193 * Sound IRQ
194 */
195loc_sound: PANIC("Unimplemented loc_sound handler")
196loc_video: PANIC("Unimplemented loc_video handler")
197
198/*
199 * Ethernet interrupt handler
200 */
201loc_ethernet: li s1,~JAZZ_IE_ETHERNET
202 li a0,JAZZ_ETHERNET_IRQ
203 b loc_call
204
205/*
206 * SCSI interrupt handler
207 */
208loc_scsi: li s1,~JAZZ_IE_SCSI
209 li a0,JAZZ_SCSI_IRQ
210 b loc_call
211
212/*
213 * Keyboard interrupt handler
214 */
215loc_keyboard: li s1,~JAZZ_IE_KEYBOARD
216 li a0,JAZZ_KEYBOARD_IRQ
217 b loc_call
218
219/*
220 * Mouse interrupt handler
221 */
222loc_mouse: li s1,~JAZZ_IE_MOUSE
223 li a0,JAZZ_MOUSE_IRQ
224 b loc_call
225
226/*
227 * Serial port 1 IRQ
228 */
229loc_serial1: li s1,~JAZZ_IE_SERIAL1
230 li a0,JAZZ_SERIAL1_IRQ
231 b loc_call
232
233/*
234 * Serial port 2 IRQ
235 */
236loc_serial2: li s1,~JAZZ_IE_SERIAL2
237 li a0,JAZZ_SERIAL2_IRQ
238 b loc_call
239
240/*
241 * Call the interrupt handler for an interrupt generated by a
242 * local device.
243 */
244loc_call: /*
245 * Temporarily disable interrupt source
246 */
247 lhu t2,JAZZ_IO_IRQ_ENABLE
248 and t2,s1
249 sh t2,JAZZ_IO_IRQ_ENABLE
250
251 nor s1,zero,s1
252 jal do_IRQ
253
254 /*
255 * Reenable interrupt
256 */
257 lhu t2,JAZZ_IO_IRQ_ENABLE
258 or t2,s1
259 sh t2,JAZZ_IO_IRQ_ENABLE
260
261 j ret_from_irq
262
263/*
264 * "Jump extender" to reach spurious_interrupt
265 */
2663: j spurious_interrupt
267
268/*
269 * Vectors for interrupts generated by local devices
270 */
271 .data
272local_vector: PTR loc_no_irq
273 PTR loc_parallel
274 PTR loc_floppy
275 PTR loc_sound
276 PTR loc_video
277 PTR loc_ethernet
278 PTR loc_scsi
279 PTR loc_keyboard
280 PTR loc_mouse
281 PTR loc_serial1
282 PTR loc_serial2
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c
index b309b1bcf2e8..becc9accd495 100644
--- a/arch/mips/jazz/irq.c
+++ b/arch/mips/jazz/irq.c
@@ -15,8 +15,6 @@
15#include <asm/io.h> 15#include <asm/io.h>
16#include <asm/jazz.h> 16#include <asm/jazz.h>
17 17
18extern asmlinkage void jazz_handle_int(void);
19
20static DEFINE_SPINLOCK(r4030_lock); 18static DEFINE_SPINLOCK(r4030_lock);
21 19
22static void enable_r4030_irq(unsigned int irq) 20static void enable_r4030_irq(unsigned int irq)
@@ -90,10 +88,82 @@ void __init init_r4030_ints(void)
90 */ 88 */
91void __init arch_init_irq(void) 89void __init arch_init_irq(void)
92{ 90{
93 set_except_vector(0, jazz_handle_int);
94
95 init_i8259_irqs(); /* Integrated i8259 */ 91 init_i8259_irqs(); /* Integrated i8259 */
96 init_r4030_ints(); 92 init_r4030_ints();
97 93
98 change_c0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1); 94 change_c0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1);
99} 95}
96
97static void loc_call(unsigned int irq, struct pt_regs *regs, unsigned int mask)
98{
99 r4030_write_reg16(JAZZ_IO_IRQ_ENABLE,
100 r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) & mask);
101 do_IRQ(irq, regs);
102 r4030_write_reg16(JAZZ_IO_IRQ_ENABLE,
103 r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | mask);
104}
105
106static void ll_local_dev(struct pt_regs *regs)
107{
108 switch (r4030_read_reg32(JAZZ_IO_IRQ_SOURCE)) {
109 case 0:
110 panic("Unimplemented loc_no_irq handler");
111 break;
112 case 4:
113 loc_call(JAZZ_PARALLEL_IRQ, regs, JAZZ_IE_PARALLEL);
114 break;
115 case 8:
116 loc_call(JAZZ_PARALLEL_IRQ, regs, JAZZ_IE_FLOPPY);
117 break;
118 case 12:
119 panic("Unimplemented loc_sound handler");
120 break;
121 case 16:
122 panic("Unimplemented loc_video handler");
123 break;
124 case 20:
125 loc_call(JAZZ_ETHERNET_IRQ, regs, JAZZ_IE_ETHERNET);
126 break;
127 case 24:
128 loc_call(JAZZ_SCSI_IRQ, regs, JAZZ_IE_SCSI);
129 break;
130 case 28:
131 loc_call(JAZZ_KEYBOARD_IRQ, regs, JAZZ_IE_KEYBOARD);
132 break;
133 case 32:
134 loc_call(JAZZ_MOUSE_IRQ, regs, JAZZ_IE_MOUSE);
135 break;
136 case 36:
137 loc_call(JAZZ_SERIAL1_IRQ, regs, JAZZ_IE_SERIAL1);
138 break;
139 case 40:
140 loc_call(JAZZ_SERIAL2_IRQ, regs, JAZZ_IE_SERIAL2);
141 break;
142 }
143}
144
145asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
146{
147 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
148
149 if (pending & IE_IRQ5)
150 write_c0_compare(0);
151 else if (pending & IE_IRQ4) {
152 r4030_read_reg32(JAZZ_TIMER_REGISTER);
153 do_IRQ(JAZZ_TIMER_IRQ, regs);
154 } else if (pending & IE_IRQ3)
155 panic("Unimplemented ISA NMI handler");
156 else if (pending & IE_IRQ2)
157 do_IRQ(r4030_read_reg32(JAZZ_EISA_IRQ_ACK), regs);
158 else if (pending & IE_IRQ1) {
159 ll_local_dev(regs);
160 } else if (unlikely(pending & IE_IRQ0))
161 panic("Unimplemented local_dma handler");
162 else if (pending & IE_SW1) {
163 clear_c0_cause(IE_SW1);
164 panic("Unimplemented sw1 handler");
165 } else if (pending & IE_SW0) {
166 clear_c0_cause(IE_SW0);
167 panic("Unimplemented sw0 handler");
168 }
169}
diff --git a/arch/mips/jmr3927/common/rtc_ds1742.c b/arch/mips/jmr3927/common/rtc_ds1742.c
index a6bd3f4d3049..e6561345d12a 100644
--- a/arch/mips/jmr3927/common/rtc_ds1742.c
+++ b/arch/mips/jmr3927/common/rtc_ds1742.c
@@ -60,15 +60,15 @@ rtc_ds1742_get_time(void)
60 unsigned long flags; 60 unsigned long flags;
61 61
62 spin_lock_irqsave(&rtc_lock, flags); 62 spin_lock_irqsave(&rtc_lock, flags);
63 CMOS_WRITE(RTC_READ, RTC_CONTROL); 63 rtc_write(RTC_READ, RTC_CONTROL);
64 second = BCD2BIN(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); 64 second = BCD2BIN(rtc_read(RTC_SECONDS) & RTC_SECONDS_MASK);
65 minute = BCD2BIN(CMOS_READ(RTC_MINUTES)); 65 minute = BCD2BIN(rtc_read(RTC_MINUTES));
66 hour = BCD2BIN(CMOS_READ(RTC_HOURS)); 66 hour = BCD2BIN(rtc_read(RTC_HOURS));
67 day = BCD2BIN(CMOS_READ(RTC_DATE)); 67 day = BCD2BIN(rtc_read(RTC_DATE));
68 month = BCD2BIN(CMOS_READ(RTC_MONTH)); 68 month = BCD2BIN(rtc_read(RTC_MONTH));
69 year = BCD2BIN(CMOS_READ(RTC_YEAR)); 69 year = BCD2BIN(rtc_read(RTC_YEAR));
70 century = BCD2BIN(CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK); 70 century = BCD2BIN(rtc_read(RTC_CENTURY) & RTC_CENTURY_MASK);
71 CMOS_WRITE(0, RTC_CONTROL); 71 rtc_write(0, RTC_CONTROL);
72 spin_unlock_irqrestore(&rtc_lock, flags); 72 spin_unlock_irqrestore(&rtc_lock, flags);
73 73
74 year += century * 100; 74 year += century * 100;
@@ -87,16 +87,16 @@ rtc_ds1742_set_time(unsigned long t)
87 unsigned long flags; 87 unsigned long flags;
88 88
89 spin_lock_irqsave(&rtc_lock, flags); 89 spin_lock_irqsave(&rtc_lock, flags);
90 CMOS_WRITE(RTC_READ, RTC_CONTROL); 90 rtc_write(RTC_READ, RTC_CONTROL);
91 cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); 91 cmos_second = (u8)(rtc_read(RTC_SECONDS) & RTC_SECONDS_MASK);
92 cmos_minute = (u8)CMOS_READ(RTC_MINUTES); 92 cmos_minute = (u8)rtc_read(RTC_MINUTES);
93 cmos_hour = (u8)CMOS_READ(RTC_HOURS); 93 cmos_hour = (u8)rtc_read(RTC_HOURS);
94 cmos_day = (u8)CMOS_READ(RTC_DATE); 94 cmos_day = (u8)rtc_read(RTC_DATE);
95 cmos_month = (u8)CMOS_READ(RTC_MONTH); 95 cmos_month = (u8)rtc_read(RTC_MONTH);
96 cmos_year = (u8)CMOS_READ(RTC_YEAR); 96 cmos_year = (u8)rtc_read(RTC_YEAR);
97 cmos_century = CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK; 97 cmos_century = rtc_read(RTC_CENTURY) & RTC_CENTURY_MASK;
98 98
99 CMOS_WRITE(RTC_WRITE, RTC_CONTROL); 99 rtc_write(RTC_WRITE, RTC_CONTROL);
100 100
101 /* convert */ 101 /* convert */
102 to_tm(t, &tm); 102 to_tm(t, &tm);
@@ -104,18 +104,18 @@ rtc_ds1742_set_time(unsigned long t)
104 /* check each field one by one */ 104 /* check each field one by one */
105 year = BIN2BCD(tm.tm_year - EPOCH); 105 year = BIN2BCD(tm.tm_year - EPOCH);
106 if (year != cmos_year) { 106 if (year != cmos_year) {
107 CMOS_WRITE(year,RTC_YEAR); 107 rtc_write(year,RTC_YEAR);
108 } 108 }
109 109
110 month = BIN2BCD(tm.tm_mon); 110 month = BIN2BCD(tm.tm_mon);
111 if (month != (cmos_month & 0x1f)) { 111 if (month != (cmos_month & 0x1f)) {
112 CMOS_WRITE((month & 0x1f) | (cmos_month & ~0x1f),RTC_MONTH); 112 rtc_write((month & 0x1f) | (cmos_month & ~0x1f),RTC_MONTH);
113 } 113 }
114 114
115 day = BIN2BCD(tm.tm_mday); 115 day = BIN2BCD(tm.tm_mday);
116 if (day != cmos_day) { 116 if (day != cmos_day) {
117 117
118 CMOS_WRITE(day, RTC_DATE); 118 rtc_write(day, RTC_DATE);
119 } 119 }
120 120
121 if (cmos_hour & 0x40) { 121 if (cmos_hour & 0x40) {
@@ -130,20 +130,20 @@ rtc_ds1742_set_time(unsigned long t)
130 /* 24 hour format */ 130 /* 24 hour format */
131 hour = BIN2BCD(tm.tm_hour) & 0x3f; 131 hour = BIN2BCD(tm.tm_hour) & 0x3f;
132 } 132 }
133 if (hour != cmos_hour) CMOS_WRITE(hour, RTC_HOURS); 133 if (hour != cmos_hour) rtc_write(hour, RTC_HOURS);
134 134
135 minute = BIN2BCD(tm.tm_min); 135 minute = BIN2BCD(tm.tm_min);
136 if (minute != cmos_minute) { 136 if (minute != cmos_minute) {
137 CMOS_WRITE(minute, RTC_MINUTES); 137 rtc_write(minute, RTC_MINUTES);
138 } 138 }
139 139
140 second = BIN2BCD(tm.tm_sec); 140 second = BIN2BCD(tm.tm_sec);
141 if (second != cmos_second) { 141 if (second != cmos_second) {
142 CMOS_WRITE(second & RTC_SECONDS_MASK,RTC_SECONDS); 142 rtc_write(second & RTC_SECONDS_MASK,RTC_SECONDS);
143 } 143 }
144 144
145 /* RTC_CENTURY and RTC_CONTROL share same address... */ 145 /* RTC_CENTURY and RTC_CONTROL share same address... */
146 CMOS_WRITE(cmos_century, RTC_CONTROL); 146 rtc_write(cmos_century, RTC_CONTROL);
147 spin_unlock_irqrestore(&rtc_lock, flags); 147 spin_unlock_irqrestore(&rtc_lock, flags);
148 148
149 return 0; 149 return 0;
@@ -163,9 +163,9 @@ rtc_ds1742_init(unsigned long base)
163 rtc_mips_set_time = rtc_ds1742_set_time; 163 rtc_mips_set_time = rtc_ds1742_set_time;
164 164
165 /* clear oscillator stop bit */ 165 /* clear oscillator stop bit */
166 CMOS_WRITE(RTC_READ, RTC_CONTROL); 166 rtc_write(RTC_READ, RTC_CONTROL);
167 cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); 167 cmos_second = (u8)(rtc_read(RTC_SECONDS) & RTC_SECONDS_MASK);
168 CMOS_WRITE(RTC_WRITE, RTC_CONTROL); 168 rtc_write(RTC_WRITE, RTC_CONTROL);
169 CMOS_WRITE(cmos_second, RTC_SECONDS); /* clear msb */ 169 rtc_write(cmos_second, RTC_SECONDS); /* clear msb */
170 CMOS_WRITE(0, RTC_CONTROL); 170 rtc_write(0, RTC_CONTROL);
171} 171}
diff --git a/arch/mips/jmr3927/rbhma3100/Makefile b/arch/mips/jmr3927/rbhma3100/Makefile
index 75bf418b94c0..baf5077813c1 100644
--- a/arch/mips/jmr3927/rbhma3100/Makefile
+++ b/arch/mips/jmr3927/rbhma3100/Makefile
@@ -2,7 +2,7 @@
2# Makefile for TOSHIBA JMR-TX3927 board 2# Makefile for TOSHIBA JMR-TX3927 board
3# 3#
4 4
5obj-y += init.o int-handler.o irq.o setup.o 5obj-y += init.o irq.o setup.o
6obj-$(CONFIG_RUNTIME_DEBUG) += debug.o 6obj-$(CONFIG_RUNTIME_DEBUG) += debug.o
7obj-$(CONFIG_KGDB) += kgdb_io.o 7obj-$(CONFIG_KGDB) += kgdb_io.o
8 8
diff --git a/arch/mips/jmr3927/rbhma3100/int-handler.S b/arch/mips/jmr3927/rbhma3100/int-handler.S
deleted file mode 100644
index f85bbf407542..000000000000
--- a/arch/mips/jmr3927/rbhma3100/int-handler.S
+++ /dev/null
@@ -1,74 +0,0 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: MontaVista Software, Inc.
4 * ahennessy@mvista.com
5 *
6 * Based on arch/mips/tsdb/kernel/int-handler.S
7 *
8 * Copyright (C) 2000-2001 Toshiba Corporation
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
18 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
21 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
22 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#include <asm/asm.h>
32#include <asm/mipsregs.h>
33#include <asm/regdef.h>
34#include <asm/stackframe.h>
35#include <asm/jmr3927/jmr3927.h>
36
37 /* A lot of complication here is taken away because:
38 *
39 * 1) We handle one interrupt and return, sitting in a loop
40 * and moving across all the pending IRQ bits in the cause
41 * register is _NOT_ the answer, the common case is one
42 * pending IRQ so optimize in that direction.
43 *
44 * 2) We need not check against bits in the status register
45 * IRQ mask, that would make this routine slow as hell.
46 *
47 * 3) Linux only thinks in terms of all IRQs on or all IRQs
48 * off, nothing in between like BSD spl() brain-damage.
49 *
50 */
51
52/* Flush write buffer (needed?)
53 * NOTE: TX39xx performs "non-blocking load", so explicitly use the target
54 * register of LBU to flush immediately.
55 */
56#define FLUSH_WB(tmp) \
57 la tmp, JMR3927_IOC_REV_ADDR; \
58 lbu tmp, (tmp); \
59 move tmp, zero;
60
61 .text
62 .set noreorder
63 .set noat
64 .align 5
65 NESTED(jmr3927_IRQ, PT_SIZE, sp)
66 SAVE_ALL
67 CLI
68 .set at
69 jal jmr3927_irc_irqdispatch
70 move a0, sp
71 FLUSH_WB(t0)
72 j ret_from_irq
73 nop
74 END(jmr3927_IRQ)
diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c
index 2810727f1d4e..11304d1354f4 100644
--- a/arch/mips/jmr3927/rbhma3100/irq.c
+++ b/arch/mips/jmr3927/rbhma3100/irq.c
@@ -77,8 +77,6 @@ static int jmr3927_gen_iack(void)
77} 77}
78#endif 78#endif
79 79
80extern asmlinkage void jmr3927_IRQ(void);
81
82#define irc_dlevel 0 80#define irc_dlevel 0
83#define irc_elevel 1 81#define irc_elevel 1
84 82
@@ -262,7 +260,7 @@ void jmr3927_spurious(struct pt_regs *regs)
262 regs->cp0_cause, regs->cp0_epc, regs->regs[31]); 260 regs->cp0_cause, regs->cp0_epc, regs->regs[31]);
263} 261}
264 262
265void jmr3927_irc_irqdispatch(struct pt_regs *regs) 263asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
266{ 264{
267 int irq; 265 int irq;
268 266
@@ -398,8 +396,6 @@ void __init arch_init_irq(void)
398 396
399 jmr3927_irq_init(NR_ISA_IRQS); 397 jmr3927_irq_init(NR_ISA_IRQS);
400 398
401 set_except_vector(0, jmr3927_IRQ);
402
403 /* setup irq space */ 399 /* setup irq space */
404 add_tb_irq_space(&jmr3927_isac_irqspace); 400 add_tb_irq_space(&jmr3927_isac_irqspace);
405 add_tb_irq_space(&jmr3927_ioc_irqspace); 401 add_tb_irq_space(&jmr3927_ioc_irqspace);
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 309d54cceda3..34e8a256765c 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -34,8 +34,11 @@ obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o
34 34
35obj-$(CONFIG_SMP) += smp.o 35obj-$(CONFIG_SMP) += smp.o
36 36
37obj-$(CONFIG_MIPS_MT_SMP) += smp_mt.o 37obj-$(CONFIG_MIPS_MT) += mips-mt.o
38obj-$(CONFIG_MIPS_MT_SMTC) += smtc.o smtc-asm.o smtc-proc.o
39obj-$(CONFIG_MIPS_MT_SMP) += smp-mt.o
38 40
41obj-$(CONFIG_MIPS_APSP_KSPD) += kspd.o
39obj-$(CONFIG_MIPS_VPE_LOADER) += vpe.o 42obj-$(CONFIG_MIPS_VPE_LOADER) += vpe.o
40obj-$(CONFIG_MIPS_VPE_APSP_API) += rtlx.o 43obj-$(CONFIG_MIPS_VPE_APSP_API) += rtlx.o
41 44
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index ca6b03c773be..92b28b674d6f 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -69,6 +69,9 @@ void output_ptreg_defines(void)
69 offset("#define PT_BVADDR ", struct pt_regs, cp0_badvaddr); 69 offset("#define PT_BVADDR ", struct pt_regs, cp0_badvaddr);
70 offset("#define PT_STATUS ", struct pt_regs, cp0_status); 70 offset("#define PT_STATUS ", struct pt_regs, cp0_status);
71 offset("#define PT_CAUSE ", struct pt_regs, cp0_cause); 71 offset("#define PT_CAUSE ", struct pt_regs, cp0_cause);
72#ifdef CONFIG_MIPS_MT_SMTC
73 offset("#define PT_TCSTATUS ", struct pt_regs, cp0_tcstatus);
74#endif /* CONFIG_MIPS_MT_SMTC */
72 size("#define PT_SIZE ", struct pt_regs); 75 size("#define PT_SIZE ", struct pt_regs);
73 linefeed; 76 linefeed;
74} 77}
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index 83c87fe4ee4f..d101d2fb24ca 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -17,6 +17,9 @@
17#include <asm/isadep.h> 17#include <asm/isadep.h>
18#include <asm/thread_info.h> 18#include <asm/thread_info.h>
19#include <asm/war.h> 19#include <asm/war.h>
20#ifdef CONFIG_MIPS_MT_SMTC
21#include <asm/mipsmtregs.h>
22#endif
20 23
21#ifdef CONFIG_PREEMPT 24#ifdef CONFIG_PREEMPT
22 .macro preempt_stop 25 .macro preempt_stop
@@ -75,6 +78,37 @@ FEXPORT(syscall_exit)
75 bnez t0, syscall_exit_work 78 bnez t0, syscall_exit_work
76 79
77FEXPORT(restore_all) # restore full frame 80FEXPORT(restore_all) # restore full frame
81#ifdef CONFIG_MIPS_MT_SMTC
82/* Detect and execute deferred IPI "interrupts" */
83 move a0,sp
84 jal deferred_smtc_ipi
85/* Re-arm any temporarily masked interrupts not explicitly "acked" */
86 mfc0 v0, CP0_TCSTATUS
87 ori v1, v0, TCSTATUS_IXMT
88 mtc0 v1, CP0_TCSTATUS
89 andi v0, TCSTATUS_IXMT
90 ehb
91 mfc0 t0, CP0_TCCONTEXT
92 DMT 9 # dmt t1
93 jal mips_ihb
94 mfc0 t2, CP0_STATUS
95 andi t3, t0, 0xff00
96 or t2, t2, t3
97 mtc0 t2, CP0_STATUS
98 ehb
99 andi t1, t1, VPECONTROL_TE
100 beqz t1, 1f
101 EMT
1021:
103 mfc0 v1, CP0_TCSTATUS
104 /* We set IXMT above, XOR should cler it here */
105 xori v1, v1, TCSTATUS_IXMT
106 or v1, v0, v1
107 mtc0 v1, CP0_TCSTATUS
108 ehb
109 xor t0, t0, t3
110 mtc0 t0, CP0_TCCONTEXT
111#endif /* CONFIG_MIPS_MT_SMTC */
78 .set noat 112 .set noat
79 RESTORE_TEMP 113 RESTORE_TEMP
80 RESTORE_AT 114 RESTORE_AT
@@ -120,28 +154,17 @@ syscall_exit_work:
120 jal do_syscall_trace 154 jal do_syscall_trace
121 b resume_userspace 155 b resume_userspace
122 156
157#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT)
158
123/* 159/*
124 * Common spurious interrupt handler. 160 * MIPS32R2 Instruction Hazard Barrier - must be called
161 *
162 * For C code use the inline version named instruction_hazard().
125 */ 163 */
126LEAF(spurious_interrupt) 164LEAF(mips_ihb)
127 /* 165 .set mips32r2
128 * Someone tried to fool us by sending an interrupt but we 166 jr.hb ra
129 * couldn't find a cause for it. 167 nop
130 */ 168 END(mips_ihb)
131 PTR_LA t1, irq_err_count 169
132#ifdef CONFIG_SMP 170#endif /* CONFIG_CPU_MIPSR2 or CONFIG_MIPS_MT */
1331: ll t0, (t1)
134 addiu t0, 1
135 sc t0, (t1)
136#if R10000_LLSC_WAR
137 beqzl t0, 1b
138#else
139 beqz t0, 1b
140#endif
141#else
142 lw t0, (t1)
143 addiu t0, 1
144 sw t0, (t1)
145#endif
146 j ret_from_irq
147 END(spurious_interrupt)
diff --git a/arch/mips/kernel/gdb-low.S b/arch/mips/kernel/gdb-low.S
index 235ad9f6bd35..10f28fb9f008 100644
--- a/arch/mips/kernel/gdb-low.S
+++ b/arch/mips/kernel/gdb-low.S
@@ -283,11 +283,33 @@
283 */ 283 */
284 284
2853: 2853:
286#ifdef CONFIG_MIPS_MT_SMTC
287 /* Read-modify write of Status must be atomic */
288 mfc0 t2, CP0_TCSTATUS
289 ori t1, t2, TCSTATUS_IXMT
290 mtc0 t1, CP0_TCSTATUS
291 andi t2, t2, TCSTATUS_IXMT
292 ehb
293 DMT 9 # dmt t1
294 jal mips_ihb
295 nop
296#endif /* CONFIG_MIPS_MT_SMTC */
286 mfc0 t0, CP0_STATUS 297 mfc0 t0, CP0_STATUS
287 ori t0, 0x1f 298 ori t0, 0x1f
288 xori t0, 0x1f 299 xori t0, 0x1f
289 mtc0 t0, CP0_STATUS 300 mtc0 t0, CP0_STATUS
290 301#ifdef CONFIG_MIPS_MT_SMTC
302 andi t1, t1, VPECONTROL_TE
303 beqz t1, 9f
304 nop
305 EMT # emt
3069:
307 mfc0 t1, CP0_TCSTATUS
308 xori t1, t1, TCSTATUS_IXMT
309 or t1, t1, t2
310 mtc0 t1, CP0_TCSTATUS
311 ehb
312#endif /* CONFIG_MIPS_MT_SMTC */
291 LONG_L v0, GDB_FR_STATUS(sp) 313 LONG_L v0, GDB_FR_STATUS(sp)
292 LONG_L v1, GDB_FR_EPC(sp) 314 LONG_L v1, GDB_FR_EPC(sp)
293 mtc0 v0, CP0_STATUS 315 mtc0 v0, CP0_STATUS
diff --git a/arch/mips/kernel/gdb-stub.c b/arch/mips/kernel/gdb-stub.c
index d4f88e0af24c..6ecbdc1fefd1 100644
--- a/arch/mips/kernel/gdb-stub.c
+++ b/arch/mips/kernel/gdb-stub.c
@@ -140,6 +140,7 @@
140#include <asm/system.h> 140#include <asm/system.h>
141#include <asm/gdb-stub.h> 141#include <asm/gdb-stub.h>
142#include <asm/inst.h> 142#include <asm/inst.h>
143#include <asm/smp.h>
143 144
144/* 145/*
145 * external low-level support routines 146 * external low-level support routines
@@ -669,6 +670,64 @@ static void kgdb_wait(void *arg)
669 local_irq_restore(flags); 670 local_irq_restore(flags);
670} 671}
671 672
673/*
674 * GDB stub needs to call kgdb_wait on all processor with interrupts
675 * disabled, so it uses it's own special variant.
676 */
677static int kgdb_smp_call_kgdb_wait(void)
678{
679#ifdef CONFIG_SMP
680 struct call_data_struct data;
681 int i, cpus = num_online_cpus() - 1;
682 int cpu = smp_processor_id();
683
684 /*
685 * Can die spectacularly if this CPU isn't yet marked online
686 */
687 BUG_ON(!cpu_online(cpu));
688
689 if (!cpus)
690 return 0;
691
692 if (spin_is_locked(&smp_call_lock)) {
693 /*
694 * Some other processor is trying to make us do something
695 * but we're not going to respond... give up
696 */
697 return -1;
698 }
699
700 /*
701 * We will continue here, accepting the fact that
702 * the kernel may deadlock if another CPU attempts
703 * to call smp_call_function now...
704 */
705
706 data.func = kgdb_wait;
707 data.info = NULL;
708 atomic_set(&data.started, 0);
709 data.wait = 0;
710
711 spin_lock(&smp_call_lock);
712 call_data = &data;
713 mb();
714
715 /* Send a message to all other CPUs and wait for them to respond */
716 for (i = 0; i < NR_CPUS; i++)
717 if (cpu_online(i) && i != cpu)
718 core_send_ipi(i, SMP_CALL_FUNCTION);
719
720 /* Wait for response */
721 /* FIXME: lock-up detection, backtrace on lock-up */
722 while (atomic_read(&data.started) != cpus)
723 barrier();
724
725 call_data = NULL;
726 spin_unlock(&smp_call_lock);
727#endif
728
729 return 0;
730}
672 731
673/* 732/*
674 * This function does all command processing for interfacing to gdb. It 733 * This function does all command processing for interfacing to gdb. It
@@ -718,7 +777,7 @@ void handle_exception (struct gdb_regs *regs)
718 /* 777 /*
719 * force other cpus to enter kgdb 778 * force other cpus to enter kgdb
720 */ 779 */
721 smp_call_function(kgdb_wait, NULL, 0, 0); 780 kgdb_smp_call_kgdb_wait();
722 781
723 /* 782 /*
724 * If we're in breakpoint() increment the PC 783 * If we're in breakpoint() increment the PC
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index 13f22d1d0e8b..ff7af369f286 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -12,6 +12,7 @@
12#include <linux/init.h> 12#include <linux/init.h>
13 13
14#include <asm/asm.h> 14#include <asm/asm.h>
15#include <asm/asmmacro.h>
15#include <asm/cacheops.h> 16#include <asm/cacheops.h>
16#include <asm/regdef.h> 17#include <asm/regdef.h>
17#include <asm/fpregdef.h> 18#include <asm/fpregdef.h>
@@ -122,6 +123,20 @@ handle_vcei:
122 .set pop 123 .set pop
123 END(except_vec3_r4000) 124 END(except_vec3_r4000)
124 125
126 __FINIT
127
128 .align 5
129NESTED(handle_int, PT_SIZE, sp)
130 SAVE_ALL
131 CLI
132
133 PTR_LA ra, ret_from_irq
134 move a0, sp
135 j plat_irq_dispatch
136 END(handle_int)
137
138 __INIT
139
125/* 140/*
126 * Special interrupt vector for MIPS64 ISA & embedded MIPS processors. 141 * Special interrupt vector for MIPS64 ISA & embedded MIPS processors.
127 * This is a dedicated interrupt exception vector which reduces the 142 * This is a dedicated interrupt exception vector which reduces the
@@ -157,6 +172,15 @@ NESTED(except_vec_vi, 0, sp)
157 SAVE_AT 172 SAVE_AT
158 .set push 173 .set push
159 .set noreorder 174 .set noreorder
175#ifdef CONFIG_MIPS_MT_SMTC
176 /*
177 * To keep from blindly blocking *all* interrupts
178 * during service by SMTC kernel, we also want to
179 * pass the IM value to be cleared.
180 */
181EXPORT(except_vec_vi_mori)
182 ori a0, $0, 0
183#endif /* CONFIG_MIPS_MT_SMTC */
160EXPORT(except_vec_vi_lui) 184EXPORT(except_vec_vi_lui)
161 lui v0, 0 /* Patched */ 185 lui v0, 0 /* Patched */
162 j except_vec_vi_handler 186 j except_vec_vi_handler
@@ -173,6 +197,25 @@ EXPORT(except_vec_vi_end)
173NESTED(except_vec_vi_handler, 0, sp) 197NESTED(except_vec_vi_handler, 0, sp)
174 SAVE_TEMP 198 SAVE_TEMP
175 SAVE_STATIC 199 SAVE_STATIC
200#ifdef CONFIG_MIPS_MT_SMTC
201 /*
202 * SMTC has an interesting problem that interrupts are level-triggered,
203 * and the CLI macro will clear EXL, potentially causing a duplicate
204 * interrupt service invocation. So we need to clear the associated
205 * IM bit of Status prior to doing CLI, and restore it after the
206 * service routine has been invoked - we must assume that the
207 * service routine will have cleared the state, and any active
208 * level represents a new or otherwised unserviced event...
209 */
210 mfc0 t1, CP0_STATUS
211 and t0, a0, t1
212 mfc0 t2, CP0_TCCONTEXT
213 or t0, t0, t2
214 mtc0 t0, CP0_TCCONTEXT
215 xor t1, t1, t0
216 mtc0 t1, CP0_STATUS
217 ehb
218#endif /* CONFIG_MIPS_MT_SMTC */
176 CLI 219 CLI
177 move a0, sp 220 move a0, sp
178 jalr v0 221 jalr v0
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index 2e9122a4213a..bdf6f6eff721 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -18,6 +18,7 @@
18#include <linux/threads.h> 18#include <linux/threads.h>
19 19
20#include <asm/asm.h> 20#include <asm/asm.h>
21#include <asm/asmmacro.h>
21#include <asm/regdef.h> 22#include <asm/regdef.h>
22#include <asm/page.h> 23#include <asm/page.h>
23#include <asm/mipsregs.h> 24#include <asm/mipsregs.h>
@@ -82,12 +83,33 @@
82 */ 83 */
83 .macro setup_c0_status set clr 84 .macro setup_c0_status set clr
84 .set push 85 .set push
86#ifdef CONFIG_MIPS_MT_SMTC
87 /*
88 * For SMTC, we need to set privilege and disable interrupts only for
89 * the current TC, using the TCStatus register.
90 */
91 mfc0 t0, CP0_TCSTATUS
92 /* Fortunately CU 0 is in the same place in both registers */
93 /* Set TCU0, TMX, TKSU (for later inversion) and IXMT */
94 li t1, ST0_CU0 | 0x08001c00
95 or t0, t1
96 /* Clear TKSU, leave IXMT */
97 xori t0, 0x00001800
98 mtc0 t0, CP0_TCSTATUS
99 ehb
100 /* We need to leave the global IE bit set, but clear EXL...*/
101 mfc0 t0, CP0_STATUS
102 or t0, ST0_CU0 | ST0_EXL | ST0_ERL | \set | \clr
103 xor t0, ST0_EXL | ST0_ERL | \clr
104 mtc0 t0, CP0_STATUS
105#else
85 mfc0 t0, CP0_STATUS 106 mfc0 t0, CP0_STATUS
86 or t0, ST0_CU0|\set|0x1f|\clr 107 or t0, ST0_CU0|\set|0x1f|\clr
87 xor t0, 0x1f|\clr 108 xor t0, 0x1f|\clr
88 mtc0 t0, CP0_STATUS 109 mtc0 t0, CP0_STATUS
89 .set noreorder 110 .set noreorder
90 sll zero,3 # ehb 111 sll zero,3 # ehb
112#endif
91 .set pop 113 .set pop
92 .endm 114 .endm
93 115
@@ -134,6 +156,24 @@ NESTED(kernel_entry, 16, sp) # kernel entry point
134 156
135 ARC64_TWIDDLE_PC 157 ARC64_TWIDDLE_PC
136 158
159#ifdef CONFIG_MIPS_MT_SMTC
160 /*
161 * In SMTC kernel, "CLI" is thread-specific, in TCStatus.
162 * We still need to enable interrupts globally in Status,
163 * and clear EXL/ERL.
164 *
165 * TCContext is used to track interrupt levels under
166 * service in SMTC kernel. Clear for boot TC before
167 * allowing any interrupts.
168 */
169 mtc0 zero, CP0_TCCONTEXT
170
171 mfc0 t0, CP0_STATUS
172 ori t0, t0, 0xff1f
173 xori t0, t0, 0x001e
174 mtc0 t0, CP0_STATUS
175#endif /* CONFIG_MIPS_MT_SMTC */
176
137 PTR_LA t0, __bss_start # clear .bss 177 PTR_LA t0, __bss_start # clear .bss
138 LONG_S zero, (t0) 178 LONG_S zero, (t0)
139 PTR_LA t1, __bss_stop - LONGSIZE 179 PTR_LA t1, __bss_stop - LONGSIZE
@@ -166,8 +206,25 @@ NESTED(kernel_entry, 16, sp) # kernel entry point
166 * function after setting up the stack and gp registers. 206 * function after setting up the stack and gp registers.
167 */ 207 */
168NESTED(smp_bootstrap, 16, sp) 208NESTED(smp_bootstrap, 16, sp)
209#ifdef CONFIG_MIPS_MT_SMTC
210 /*
211 * Read-modify-writes of Status must be atomic, and this
212 * is one case where CLI is invoked without EXL being
213 * necessarily set. The CLI and setup_c0_status will
214 * in fact be redundant for all but the first TC of
215 * each VPE being booted.
216 */
217 DMT 10 # dmt t2 /* t0, t1 are used by CLI and setup_c0_status() */
218 jal mips_ihb
219#endif /* CONFIG_MIPS_MT_SMTC */
169 setup_c0_status_sec 220 setup_c0_status_sec
170 smp_slave_setup 221 smp_slave_setup
222#ifdef CONFIG_MIPS_MT_SMTC
223 andi t2, t2, VPECONTROL_TE
224 beqz t2, 2f
225 EMT # emt
2262:
227#endif /* CONFIG_MIPS_MT_SMTC */
171 j start_secondary 228 j start_secondary
172 END(smp_bootstrap) 229 END(smp_bootstrap)
173#endif /* CONFIG_SMP */ 230#endif /* CONFIG_SMP */
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index b974ac9057f6..2125ba5f1d9b 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -187,6 +187,10 @@ handle_real_irq:
187 outb(cached_21,0x21); 187 outb(cached_21,0x21);
188 outb(0x60+irq,0x20); /* 'Specific EOI' to master */ 188 outb(0x60+irq,0x20); /* 'Specific EOI' to master */
189 } 189 }
190#ifdef CONFIG_MIPS_MT_SMTC
191 if (irq_hwmask[irq] & ST0_IM)
192 set_c0_status(irq_hwmask[irq] & ST0_IM);
193#endif /* CONFIG_MIPS_MT_SMTC */
190 spin_unlock_irqrestore(&i8259A_lock, flags); 194 spin_unlock_irqrestore(&i8259A_lock, flags);
191 return; 195 return;
192 196
diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c
index 3f653c7cfbf3..97ebdc754b9e 100644
--- a/arch/mips/kernel/irq-msc01.c
+++ b/arch/mips/kernel/irq-msc01.c
@@ -76,6 +76,11 @@ static void level_mask_and_ack_msc_irq(unsigned int irq)
76 mask_msc_irq(irq); 76 mask_msc_irq(irq);
77 if (!cpu_has_veic) 77 if (!cpu_has_veic)
78 MSCIC_WRITE(MSC01_IC_EOI, 0); 78 MSCIC_WRITE(MSC01_IC_EOI, 0);
79#ifdef CONFIG_MIPS_MT_SMTC
80 /* This actually needs to be a call into platform code */
81 if (irq_hwmask[irq] & ST0_IM)
82 set_c0_status(irq_hwmask[irq] & ST0_IM);
83#endif /* CONFIG_MIPS_MT_SMTC */
79} 84}
80 85
81/* 86/*
@@ -92,6 +97,10 @@ static void edge_mask_and_ack_msc_irq(unsigned int irq)
92 MSCIC_WRITE(MSC01_IC_SUP+irq*8, r | ~MSC01_IC_SUP_EDGE_BIT); 97 MSCIC_WRITE(MSC01_IC_SUP+irq*8, r | ~MSC01_IC_SUP_EDGE_BIT);
93 MSCIC_WRITE(MSC01_IC_SUP+irq*8, r); 98 MSCIC_WRITE(MSC01_IC_SUP+irq*8, r);
94 } 99 }
100#ifdef CONFIG_MIPS_MT_SMTC
101 if (irq_hwmask[irq] & ST0_IM)
102 set_c0_status(irq_hwmask[irq] & ST0_IM);
103#endif /* CONFIG_MIPS_MT_SMTC */
95} 104}
96 105
97/* 106/*
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index 3dd76b3d2967..3dce742e716f 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -38,6 +38,15 @@ void ack_bad_irq(unsigned int irq)
38 38
39atomic_t irq_err_count; 39atomic_t irq_err_count;
40 40
41#ifdef CONFIG_MIPS_MT_SMTC
42/*
43 * SMTC Kernel needs to manipulate low-level CPU interrupt mask
44 * in do_IRQ. These are passed in setup_irq_smtc() and stored
45 * in this table.
46 */
47unsigned long irq_hwmask[NR_IRQS];
48#endif /* CONFIG_MIPS_MT_SMTC */
49
41#undef do_IRQ 50#undef do_IRQ
42 51
43/* 52/*
@@ -49,6 +58,7 @@ asmlinkage unsigned int do_IRQ(unsigned int irq, struct pt_regs *regs)
49{ 58{
50 irq_enter(); 59 irq_enter();
51 60
61 __DO_IRQ_SMTC_HOOK();
52 __do_IRQ(irq, regs); 62 __do_IRQ(irq, regs);
53 63
54 irq_exit(); 64 irq_exit();
@@ -101,6 +111,11 @@ skip:
101 return 0; 111 return 0;
102} 112}
103 113
114asmlinkage void spurious_interrupt(struct pt_regs *regs)
115{
116 atomic_inc(&irq_err_count);
117}
118
104#ifdef CONFIG_KGDB 119#ifdef CONFIG_KGDB
105extern void breakpoint(void); 120extern void breakpoint(void);
106extern void set_debug_traps(void); 121extern void set_debug_traps(void);
@@ -124,6 +139,9 @@ void __init init_IRQ(void)
124 irq_desc[i].depth = 1; 139 irq_desc[i].depth = 1;
125 irq_desc[i].handler = &no_irq_type; 140 irq_desc[i].handler = &no_irq_type;
126 spin_lock_init(&irq_desc[i].lock); 141 spin_lock_init(&irq_desc[i].lock);
142#ifdef CONFIG_MIPS_MT_SMTC
143 irq_hwmask[i] = 0;
144#endif /* CONFIG_MIPS_MT_SMTC */
127 } 145 }
128 146
129 arch_init_irq(); 147 arch_init_irq();
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c
new file mode 100644
index 000000000000..f06a144c7881
--- /dev/null
+++ b/arch/mips/kernel/kspd.c
@@ -0,0 +1,398 @@
1/*
2 * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved.
3 *
4 * This program is free software; you can distribute it and/or modify it
5 * under the terms of the GNU General Public License (Version 2) as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 * for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16 *
17 */
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/unistd.h>
21#include <linux/file.h>
22#include <linux/fs.h>
23#include <linux/syscalls.h>
24#include <linux/workqueue.h>
25#include <linux/errno.h>
26#include <linux/list.h>
27
28#include <asm/vpe.h>
29#include <asm/rtlx.h>
30#include <asm/kspd.h>
31
32static struct workqueue_struct *workqueue = NULL;
33static struct work_struct work;
34
35extern unsigned long cpu_khz;
36
37struct mtsp_syscall {
38 int cmd;
39 unsigned char abi;
40 unsigned char size;
41};
42
43struct mtsp_syscall_ret {
44 int retval;
45 int errno;
46};
47
48struct mtsp_syscall_generic {
49 int arg0;
50 int arg1;
51 int arg2;
52 int arg3;
53 int arg4;
54 int arg5;
55 int arg6;
56};
57
58static struct list_head kspd_notifylist;
59static int sp_stopping = 0;
60
61/* these should match with those in the SDE kit */
62#define MTSP_SYSCALL_BASE 0
63#define MTSP_SYSCALL_EXIT (MTSP_SYSCALL_BASE + 0)
64#define MTSP_SYSCALL_OPEN (MTSP_SYSCALL_BASE + 1)
65#define MTSP_SYSCALL_READ (MTSP_SYSCALL_BASE + 2)
66#define MTSP_SYSCALL_WRITE (MTSP_SYSCALL_BASE + 3)
67#define MTSP_SYSCALL_CLOSE (MTSP_SYSCALL_BASE + 4)
68#define MTSP_SYSCALL_LSEEK32 (MTSP_SYSCALL_BASE + 5)
69#define MTSP_SYSCALL_ISATTY (MTSP_SYSCALL_BASE + 6)
70#define MTSP_SYSCALL_GETTIME (MTSP_SYSCALL_BASE + 7)
71#define MTSP_SYSCALL_PIPEFREQ (MTSP_SYSCALL_BASE + 8)
72#define MTSP_SYSCALL_GETTOD (MTSP_SYSCALL_BASE + 9)
73
74#define MTSP_O_RDONLY 0x0000
75#define MTSP_O_WRONLY 0x0001
76#define MTSP_O_RDWR 0x0002
77#define MTSP_O_NONBLOCK 0x0004
78#define MTSP_O_APPEND 0x0008
79#define MTSP_O_SHLOCK 0x0010
80#define MTSP_O_EXLOCK 0x0020
81#define MTSP_O_ASYNC 0x0040
82#define MTSP_O_FSYNC O_SYNC
83#define MTSP_O_NOFOLLOW 0x0100
84#define MTSP_O_SYNC 0x0080
85#define MTSP_O_CREAT 0x0200
86#define MTSP_O_TRUNC 0x0400
87#define MTSP_O_EXCL 0x0800
88#define MTSP_O_BINARY 0x8000
89
90#define SP_VPE 1
91
92struct apsp_table {
93 int sp;
94 int ap;
95};
96
97/* we might want to do the mode flags too */
98struct apsp_table open_flags_table[] = {
99 { MTSP_O_RDWR, O_RDWR },
100 { MTSP_O_WRONLY, O_WRONLY },
101 { MTSP_O_CREAT, O_CREAT },
102 { MTSP_O_TRUNC, O_TRUNC },
103 { MTSP_O_NONBLOCK, O_NONBLOCK },
104 { MTSP_O_APPEND, O_APPEND },
105 { MTSP_O_NOFOLLOW, O_NOFOLLOW }
106};
107
108struct apsp_table syscall_command_table[] = {
109 { MTSP_SYSCALL_OPEN, __NR_open },
110 { MTSP_SYSCALL_CLOSE, __NR_close },
111 { MTSP_SYSCALL_READ, __NR_read },
112 { MTSP_SYSCALL_WRITE, __NR_write },
113 { MTSP_SYSCALL_LSEEK32, __NR_lseek }
114};
115
116static int sp_syscall(int num, int arg0, int arg1, int arg2, int arg3)
117{
118 register long int _num __asm__ ("$2") = num;
119 register long int _arg0 __asm__ ("$4") = arg0;
120 register long int _arg1 __asm__ ("$5") = arg1;
121 register long int _arg2 __asm__ ("$6") = arg2;
122 register long int _arg3 __asm__ ("$7") = arg3;
123
124 mm_segment_t old_fs;
125
126 old_fs = get_fs();
127 set_fs(KERNEL_DS);
128
129 __asm__ __volatile__ (
130 " syscall \n"
131 : "=r" (_num), "=r" (_arg3)
132 : "r" (_num), "r" (_arg0), "r" (_arg1), "r" (_arg2), "r" (_arg3));
133
134 set_fs(old_fs);
135
136 /* $a3 is error flag */
137 if (_arg3)
138 return -_num;
139
140 return _num;
141}
142
143static int translate_syscall_command(int cmd)
144{
145 int i;
146 int ret = -1;
147
148 for (i = 0; i < ARRAY_SIZE(syscall_command_table); i++) {
149 if ((cmd == syscall_command_table[i].sp))
150 return syscall_command_table[i].ap;
151 }
152
153 return ret;
154}
155
156static unsigned int translate_open_flags(int flags)
157{
158 int i;
159 unsigned int ret = 0;
160
161 for (i = 0; i < (sizeof(open_flags_table) / sizeof(struct apsp_table));
162 i++) {
163 if( (flags & open_flags_table[i].sp) ) {
164 ret |= open_flags_table[i].ap;
165 }
166 }
167
168 return ret;
169}
170
171
172static void sp_setfsuidgid( uid_t uid, gid_t gid)
173{
174 current->fsuid = uid;
175 current->fsgid = gid;
176
177 key_fsuid_changed(current);
178 key_fsgid_changed(current);
179}
180
181/*
182 * Expects a request to be on the sysio channel. Reads it. Decides whether
183 * its a linux syscall and runs it, or whatever. Puts the return code back
184 * into the request and sends the whole thing back.
185 */
186void sp_work_handle_request(void)
187{
188 struct mtsp_syscall sc;
189 struct mtsp_syscall_generic generic;
190 struct mtsp_syscall_ret ret;
191 struct kspd_notifications *n;
192 struct timeval tv;
193 struct timezone tz;
194 int cmd;
195
196 char *vcwd;
197 mm_segment_t old_fs;
198 int size;
199
200 ret.retval = -1;
201
202 if (!rtlx_read(RTLX_CHANNEL_SYSIO, &sc, sizeof(struct mtsp_syscall), 0)) {
203 printk(KERN_ERR "Expected request but nothing to read\n");
204 return;
205 }
206
207 size = sc.size;
208
209 if (size) {
210 if (!rtlx_read(RTLX_CHANNEL_SYSIO, &generic, size, 0)) {
211 printk(KERN_ERR "Expected request but nothing to read\n");
212 return;
213 }
214 }
215
216 /* Run the syscall at the priviledge of the user who loaded the
217 SP program */
218
219 if (vpe_getuid(SP_VPE))
220 sp_setfsuidgid( vpe_getuid(SP_VPE), vpe_getgid(SP_VPE));
221
222 switch (sc.cmd) {
223 /* needs the flags argument translating from SDE kit to
224 linux */
225 case MTSP_SYSCALL_PIPEFREQ:
226 ret.retval = cpu_khz * 1000;
227 ret.errno = 0;
228 break;
229
230 case MTSP_SYSCALL_GETTOD:
231 memset(&tz, 0, sizeof(tz));
232 if ((ret.retval = sp_syscall(__NR_gettimeofday, (int)&tv,
233 (int)&tz, 0,0)) == 0)
234 ret.retval = tv.tv_sec;
235
236 ret.errno = errno;
237 break;
238
239 case MTSP_SYSCALL_EXIT:
240 list_for_each_entry(n, &kspd_notifylist, list)
241 n->kspd_sp_exit(SP_VPE);
242 sp_stopping = 1;
243
244 printk(KERN_DEBUG "KSPD got exit syscall from SP exitcode %d\n",
245 generic.arg0);
246 break;
247
248 case MTSP_SYSCALL_OPEN:
249 generic.arg1 = translate_open_flags(generic.arg1);
250
251 vcwd = vpe_getcwd(SP_VPE);
252
253 /* change to the cwd of the process that loaded the SP program */
254 old_fs = get_fs();
255 set_fs(KERNEL_DS);
256 sys_chdir(vcwd);
257 set_fs(old_fs);
258
259 sc.cmd = __NR_open;
260
261 /* fall through */
262
263 default:
264 if ((sc.cmd >= __NR_Linux) &&
265 (sc.cmd <= (__NR_Linux + __NR_Linux_syscalls)) )
266 cmd = sc.cmd;
267 else
268 cmd = translate_syscall_command(sc.cmd);
269
270 if (cmd >= 0) {
271 ret.retval = sp_syscall(cmd, generic.arg0, generic.arg1,
272 generic.arg2, generic.arg3);
273 ret.errno = errno;
274 } else
275 printk(KERN_WARNING
276 "KSPD: Unknown SP syscall number %d\n", sc.cmd);
277 break;
278 } /* switch */
279
280 if (vpe_getuid(SP_VPE))
281 sp_setfsuidgid( 0, 0);
282
283 if ((rtlx_write(RTLX_CHANNEL_SYSIO, &ret, sizeof(struct mtsp_syscall_ret), 0))
284 < sizeof(struct mtsp_syscall_ret))
285 printk("KSPD: sp_work_handle_request failed to send to SP\n");
286}
287
288static void sp_cleanup(void)
289{
290 struct files_struct *files = current->files;
291 int i, j;
292 struct fdtable *fdt;
293
294 j = 0;
295
296 /*
297 * It is safe to dereference the fd table without RCU or
298 * ->file_lock
299 */
300 fdt = files_fdtable(files);
301 for (;;) {
302 unsigned long set;
303 i = j * __NFDBITS;
304 if (i >= fdt->max_fdset || i >= fdt->max_fds)
305 break;
306 set = fdt->open_fds->fds_bits[j++];
307 while (set) {
308 if (set & 1) {
309 struct file * file = xchg(&fdt->fd[i], NULL);
310 if (file)
311 filp_close(file, files);
312 }
313 i++;
314 set >>= 1;
315 }
316 }
317}
318
319static int channel_open = 0;
320
321/* the work handler */
322static void sp_work(void *data)
323{
324 if (!channel_open) {
325 if( rtlx_open(RTLX_CHANNEL_SYSIO, 1) != 0) {
326 printk("KSPD: unable to open sp channel\n");
327 sp_stopping = 1;
328 } else {
329 channel_open++;
330 printk(KERN_DEBUG "KSPD: SP channel opened\n");
331 }
332 } else {
333 /* wait for some data, allow it to sleep */
334 rtlx_read_poll(RTLX_CHANNEL_SYSIO, 1);
335
336 /* Check we haven't been woken because we are stopping */
337 if (!sp_stopping)
338 sp_work_handle_request();
339 }
340
341 if (!sp_stopping)
342 queue_work(workqueue, &work);
343 else
344 sp_cleanup();
345}
346
347static void startwork(int vpe)
348{
349 sp_stopping = channel_open = 0;
350
351 if (workqueue == NULL) {
352 if ((workqueue = create_singlethread_workqueue("kspd")) == NULL) {
353 printk(KERN_ERR "unable to start kspd\n");
354 return;
355 }
356
357 INIT_WORK(&work, sp_work, NULL);
358 queue_work(workqueue, &work);
359 } else
360 queue_work(workqueue, &work);
361
362}
363
364static void stopwork(int vpe)
365{
366 sp_stopping = 1;
367
368 printk(KERN_DEBUG "KSPD: SP stopping\n");
369}
370
371void kspd_notify(struct kspd_notifications *notify)
372{
373 list_add(&notify->list, &kspd_notifylist);
374}
375
376static struct vpe_notifications notify;
377static int kspd_module_init(void)
378{
379 INIT_LIST_HEAD(&kspd_notifylist);
380
381 notify.start = startwork;
382 notify.stop = stopwork;
383 vpe_notify(SP_VPE, &notify);
384
385 return 0;
386}
387
388static void kspd_module_exit(void)
389{
390
391}
392
393module_init(kspd_module_init);
394module_exit(kspd_module_exit);
395
396MODULE_DESCRIPTION("MIPS KSPD");
397MODULE_AUTHOR("Elizabeth Oldham, MIPS Technologies, Inc.");
398MODULE_LICENSE("GPL");
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 3f40c37a9ee6..7c953bcc5f6a 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -1182,6 +1182,16 @@ asmlinkage ssize_t sys32_readahead(int fd, u32 pad0, u64 a2, u64 a3,
1182 return sys_readahead(fd, merge_64(a2, a3), count); 1182 return sys_readahead(fd, merge_64(a2, a3), count);
1183} 1183}
1184 1184
1185asmlinkage long sys32_sync_file_range(int fd, int __pad,
1186 unsigned long a2, unsigned long a3,
1187 unsigned long a4, unsigned long a5,
1188 int flags)
1189{
1190 return sys_sync_file_range(fd,
1191 merge_64(a2, a3), merge_64(a4, a5),
1192 flags);
1193}
1194
1185/* Argument list sizes for sys_socketcall */ 1195/* Argument list sizes for sys_socketcall */
1186#define AL(x) ((x) * sizeof(unsigned int)) 1196#define AL(x) ((x) * sizeof(unsigned int))
1187static unsigned char socketcall_nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), 1197static unsigned char socketcall_nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c
new file mode 100644
index 000000000000..02237a685ec7
--- /dev/null
+++ b/arch/mips/kernel/mips-mt.c
@@ -0,0 +1,449 @@
1/*
2 * General MIPS MT support routines, usable in AP/SP, SMVP, or SMTC kernels
3 * Copyright (C) 2005 Mips Technologies, Inc
4 */
5
6#include <linux/kernel.h>
7#include <linux/sched.h>
8#include <linux/cpumask.h>
9#include <linux/interrupt.h>
10
11#include <asm/cpu.h>
12#include <asm/processor.h>
13#include <asm/atomic.h>
14#include <asm/system.h>
15#include <asm/hardirq.h>
16#include <asm/mmu_context.h>
17#include <asm/smp.h>
18#include <asm/mipsmtregs.h>
19#include <asm/r4kcache.h>
20#include <asm/cacheflush.h>
21
22/*
23 * CPU mask used to set process affinity for MT VPEs/TCs with FPUs
24 */
25
26cpumask_t mt_fpu_cpumask;
27
28#ifdef CONFIG_MIPS_MT_FPAFF
29
30#include <linux/cpu.h>
31#include <linux/delay.h>
32#include <asm/uaccess.h>
33
34unsigned long mt_fpemul_threshold = 0;
35
36/*
37 * Replacement functions for the sys_sched_setaffinity() and
38 * sys_sched_getaffinity() system calls, so that we can integrate
39 * FPU affinity with the user's requested processor affinity.
40 * This code is 98% identical with the sys_sched_setaffinity()
41 * and sys_sched_getaffinity() system calls, and should be
42 * updated when kernel/sched.c changes.
43 */
44
45/*
46 * find_process_by_pid - find a process with a matching PID value.
47 * used in sys_sched_set/getaffinity() in kernel/sched.c, so
48 * cloned here.
49 */
50static inline task_t *find_process_by_pid(pid_t pid)
51{
52 return pid ? find_task_by_pid(pid) : current;
53}
54
55
56/*
57 * mipsmt_sys_sched_setaffinity - set the cpu affinity of a process
58 */
59asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,
60 unsigned long __user *user_mask_ptr)
61{
62 cpumask_t new_mask;
63 cpumask_t effective_mask;
64 int retval;
65 task_t *p;
66
67 if (len < sizeof(new_mask))
68 return -EINVAL;
69
70 if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask)))
71 return -EFAULT;
72
73 lock_cpu_hotplug();
74 read_lock(&tasklist_lock);
75
76 p = find_process_by_pid(pid);
77 if (!p) {
78 read_unlock(&tasklist_lock);
79 unlock_cpu_hotplug();
80 return -ESRCH;
81 }
82
83 /*
84 * It is not safe to call set_cpus_allowed with the
85 * tasklist_lock held. We will bump the task_struct's
86 * usage count and drop tasklist_lock before invoking
87 * set_cpus_allowed.
88 */
89 get_task_struct(p);
90
91 retval = -EPERM;
92 if ((current->euid != p->euid) && (current->euid != p->uid) &&
93 !capable(CAP_SYS_NICE)) {
94 read_unlock(&tasklist_lock);
95 goto out_unlock;
96 }
97
98 /* Record new user-specified CPU set for future reference */
99 p->thread.user_cpus_allowed = new_mask;
100
101 /* Unlock the task list */
102 read_unlock(&tasklist_lock);
103
104 /* Compute new global allowed CPU set if necessary */
105 if( (p->thread.mflags & MF_FPUBOUND)
106 && cpus_intersects(new_mask, mt_fpu_cpumask)) {
107 cpus_and(effective_mask, new_mask, mt_fpu_cpumask);
108 retval = set_cpus_allowed(p, effective_mask);
109 } else {
110 p->thread.mflags &= ~MF_FPUBOUND;
111 retval = set_cpus_allowed(p, new_mask);
112 }
113
114
115out_unlock:
116 put_task_struct(p);
117 unlock_cpu_hotplug();
118 return retval;
119}
120
121/*
122 * mipsmt_sys_sched_getaffinity - get the cpu affinity of a process
123 */
124asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len,
125 unsigned long __user *user_mask_ptr)
126{
127 unsigned int real_len;
128 cpumask_t mask;
129 int retval;
130 task_t *p;
131
132 real_len = sizeof(mask);
133 if (len < real_len)
134 return -EINVAL;
135
136 lock_cpu_hotplug();
137 read_lock(&tasklist_lock);
138
139 retval = -ESRCH;
140 p = find_process_by_pid(pid);
141 if (!p)
142 goto out_unlock;
143
144 retval = 0;
145
146 cpus_and(mask, p->thread.user_cpus_allowed, cpu_possible_map);
147
148out_unlock:
149 read_unlock(&tasklist_lock);
150 unlock_cpu_hotplug();
151 if (retval)
152 return retval;
153 if (copy_to_user(user_mask_ptr, &mask, real_len))
154 return -EFAULT;
155 return real_len;
156}
157
158#endif /* CONFIG_MIPS_MT_FPAFF */
159
160/*
161 * Dump new MIPS MT state for the core. Does not leave TCs halted.
162 * Takes an argument which taken to be a pre-call MVPControl value.
163 */
164
165void mips_mt_regdump(unsigned long mvpctl)
166{
167 unsigned long flags;
168 unsigned long vpflags;
169 unsigned long mvpconf0;
170 int nvpe;
171 int ntc;
172 int i;
173 int tc;
174 unsigned long haltval;
175 unsigned long tcstatval;
176#ifdef CONFIG_MIPS_MT_SMTC
177 void smtc_soft_dump(void);
178#endif /* CONFIG_MIPT_MT_SMTC */
179
180 local_irq_save(flags);
181 vpflags = dvpe();
182 printk("=== MIPS MT State Dump ===\n");
183 printk("-- Global State --\n");
184 printk(" MVPControl Passed: %08lx\n", mvpctl);
185 printk(" MVPControl Read: %08lx\n", vpflags);
186 printk(" MVPConf0 : %08lx\n", (mvpconf0 = read_c0_mvpconf0()));
187 nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
188 ntc = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1;
189 printk("-- per-VPE State --\n");
190 for(i = 0; i < nvpe; i++) {
191 for(tc = 0; tc < ntc; tc++) {
192 settc(tc);
193 if((read_tc_c0_tcbind() & TCBIND_CURVPE) == i) {
194 printk(" VPE %d\n", i);
195 printk(" VPEControl : %08lx\n", read_vpe_c0_vpecontrol());
196 printk(" VPEConf0 : %08lx\n", read_vpe_c0_vpeconf0());
197 printk(" VPE%d.Status : %08lx\n",
198 i, read_vpe_c0_status());
199 printk(" VPE%d.EPC : %08lx\n", i, read_vpe_c0_epc());
200 printk(" VPE%d.Cause : %08lx\n", i, read_vpe_c0_cause());
201 printk(" VPE%d.Config7 : %08lx\n",
202 i, read_vpe_c0_config7());
203 break; /* Next VPE */
204 }
205 }
206 }
207 printk("-- per-TC State --\n");
208 for(tc = 0; tc < ntc; tc++) {
209 settc(tc);
210 if(read_tc_c0_tcbind() == read_c0_tcbind()) {
211 /* Are we dumping ourself? */
212 haltval = 0; /* Then we're not halted, and mustn't be */
213 tcstatval = flags; /* And pre-dump TCStatus is flags */
214 printk(" TC %d (current TC with VPE EPC above)\n", tc);
215 } else {
216 haltval = read_tc_c0_tchalt();
217 write_tc_c0_tchalt(1);
218 tcstatval = read_tc_c0_tcstatus();
219 printk(" TC %d\n", tc);
220 }
221 printk(" TCStatus : %08lx\n", tcstatval);
222 printk(" TCBind : %08lx\n", read_tc_c0_tcbind());
223 printk(" TCRestart : %08lx\n", read_tc_c0_tcrestart());
224 printk(" TCHalt : %08lx\n", haltval);
225 printk(" TCContext : %08lx\n", read_tc_c0_tccontext());
226 if (!haltval)
227 write_tc_c0_tchalt(0);
228 }
229#ifdef CONFIG_MIPS_MT_SMTC
230 smtc_soft_dump();
231#endif /* CONFIG_MIPT_MT_SMTC */
232 printk("===========================\n");
233 evpe(vpflags);
234 local_irq_restore(flags);
235}
236
237static int mt_opt_norps = 0;
238static int mt_opt_rpsctl = -1;
239static int mt_opt_nblsu = -1;
240static int mt_opt_forceconfig7 = 0;
241static int mt_opt_config7 = -1;
242
243static int __init rps_disable(char *s)
244{
245 mt_opt_norps = 1;
246 return 1;
247}
248__setup("norps", rps_disable);
249
250static int __init rpsctl_set(char *str)
251{
252 get_option(&str, &mt_opt_rpsctl);
253 return 1;
254}
255__setup("rpsctl=", rpsctl_set);
256
257static int __init nblsu_set(char *str)
258{
259 get_option(&str, &mt_opt_nblsu);
260 return 1;
261}
262__setup("nblsu=", nblsu_set);
263
264static int __init config7_set(char *str)
265{
266 get_option(&str, &mt_opt_config7);
267 mt_opt_forceconfig7 = 1;
268 return 1;
269}
270__setup("config7=", config7_set);
271
272/* Experimental cache flush control parameters that should go away some day */
273int mt_protiflush = 0;
274int mt_protdflush = 0;
275int mt_n_iflushes = 1;
276int mt_n_dflushes = 1;
277
278static int __init set_protiflush(char *s)
279{
280 mt_protiflush = 1;
281 return 1;
282}
283__setup("protiflush", set_protiflush);
284
285static int __init set_protdflush(char *s)
286{
287 mt_protdflush = 1;
288 return 1;
289}
290__setup("protdflush", set_protdflush);
291
292static int __init niflush(char *s)
293{
294 get_option(&s, &mt_n_iflushes);
295 return 1;
296}
297__setup("niflush=", niflush);
298
299static int __init ndflush(char *s)
300{
301 get_option(&s, &mt_n_dflushes);
302 return 1;
303}
304__setup("ndflush=", ndflush);
305#ifdef CONFIG_MIPS_MT_FPAFF
306static int fpaff_threshold = -1;
307
308static int __init fpaff_thresh(char *str)
309{
310 get_option(&str, &fpaff_threshold);
311 return 1;
312}
313
314__setup("fpaff=", fpaff_thresh);
315#endif /* CONFIG_MIPS_MT_FPAFF */
316
317static unsigned int itc_base = 0;
318
319static int __init set_itc_base(char *str)
320{
321 get_option(&str, &itc_base);
322 return 1;
323}
324
325__setup("itcbase=", set_itc_base);
326
327void mips_mt_set_cpuoptions(void)
328{
329 unsigned int oconfig7 = read_c0_config7();
330 unsigned int nconfig7 = oconfig7;
331
332 if (mt_opt_norps) {
333 printk("\"norps\" option deprectated: use \"rpsctl=\"\n");
334 }
335 if (mt_opt_rpsctl >= 0) {
336 printk("34K return prediction stack override set to %d.\n",
337 mt_opt_rpsctl);
338 if (mt_opt_rpsctl)
339 nconfig7 |= (1 << 2);
340 else
341 nconfig7 &= ~(1 << 2);
342 }
343 if (mt_opt_nblsu >= 0) {
344 printk("34K ALU/LSU sync override set to %d.\n", mt_opt_nblsu);
345 if (mt_opt_nblsu)
346 nconfig7 |= (1 << 5);
347 else
348 nconfig7 &= ~(1 << 5);
349 }
350 if (mt_opt_forceconfig7) {
351 printk("CP0.Config7 forced to 0x%08x.\n", mt_opt_config7);
352 nconfig7 = mt_opt_config7;
353 }
354 if (oconfig7 != nconfig7) {
355 __asm__ __volatile("sync");
356 write_c0_config7(nconfig7);
357 ehb ();
358 printk("Config7: 0x%08x\n", read_c0_config7());
359 }
360
361 /* Report Cache management debug options */
362 if (mt_protiflush)
363 printk("I-cache flushes single-threaded\n");
364 if (mt_protdflush)
365 printk("D-cache flushes single-threaded\n");
366 if (mt_n_iflushes != 1)
367 printk("I-Cache Flushes Repeated %d times\n", mt_n_iflushes);
368 if (mt_n_dflushes != 1)
369 printk("D-Cache Flushes Repeated %d times\n", mt_n_dflushes);
370
371#ifdef CONFIG_MIPS_MT_FPAFF
372 /* FPU Use Factor empirically derived from experiments on 34K */
373#define FPUSEFACTOR 333
374
375 if (fpaff_threshold >= 0) {
376 mt_fpemul_threshold = fpaff_threshold;
377 } else {
378 mt_fpemul_threshold =
379 (FPUSEFACTOR * (loops_per_jiffy/(500000/HZ))) / HZ;
380 }
381 printk("FPU Affinity set after %ld emulations\n",
382 mt_fpemul_threshold);
383#endif /* CONFIG_MIPS_MT_FPAFF */
384
385 if (itc_base != 0) {
386 /*
387 * Configure ITC mapping. This code is very
388 * specific to the 34K core family, which uses
389 * a special mode bit ("ITC") in the ErrCtl
390 * register to enable access to ITC control
391 * registers via cache "tag" operations.
392 */
393 unsigned long ectlval;
394 unsigned long itcblkgrn;
395
396 /* ErrCtl register is known as "ecc" to Linux */
397 ectlval = read_c0_ecc();
398 write_c0_ecc(ectlval | (0x1 << 26));
399 ehb();
400#define INDEX_0 (0x80000000)
401#define INDEX_8 (0x80000008)
402 /* Read "cache tag" for Dcache pseudo-index 8 */
403 cache_op(Index_Load_Tag_D, INDEX_8);
404 ehb();
405 itcblkgrn = read_c0_dtaglo();
406 itcblkgrn &= 0xfffe0000;
407 /* Set for 128 byte pitch of ITC cells */
408 itcblkgrn |= 0x00000c00;
409 /* Stage in Tag register */
410 write_c0_dtaglo(itcblkgrn);
411 ehb();
412 /* Write out to ITU with CACHE op */
413 cache_op(Index_Store_Tag_D, INDEX_8);
414 /* Now set base address, and turn ITC on with 0x1 bit */
415 write_c0_dtaglo((itc_base & 0xfffffc00) | 0x1 );
416 ehb();
417 /* Write out to ITU with CACHE op */
418 cache_op(Index_Store_Tag_D, INDEX_0);
419 write_c0_ecc(ectlval);
420 ehb();
421 printk("Mapped %ld ITC cells starting at 0x%08x\n",
422 ((itcblkgrn & 0x7fe00000) >> 20), itc_base);
423 }
424}
425
426/*
427 * Function to protect cache flushes from concurrent execution
428 * depends on MP software model chosen.
429 */
430
431void mt_cflush_lockdown(void)
432{
433#ifdef CONFIG_MIPS_MT_SMTC
434 void smtc_cflush_lockdown(void);
435
436 smtc_cflush_lockdown();
437#endif /* CONFIG_MIPS_MT_SMTC */
438 /* FILL IN VSMP and AP/SP VERSIONS HERE */
439}
440
441void mt_cflush_release(void)
442{
443#ifdef CONFIG_MIPS_MT_SMTC
444 void smtc_cflush_release(void);
445
446 smtc_cflush_release();
447#endif /* CONFIG_MIPS_MT_SMTC */
448 /* FILL IN VSMP and AP/SP VERSIONS HERE */
449}
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c
index 86e42c633f73..0a71a4c33716 100644
--- a/arch/mips/kernel/mips_ksyms.c
+++ b/arch/mips/kernel/mips_ksyms.c
@@ -28,22 +28,9 @@ extern long __strnlen_user_asm(const char *s);
28/* 28/*
29 * String functions 29 * String functions
30 */ 30 */
31EXPORT_SYMBOL(memchr);
32EXPORT_SYMBOL(memcmp);
33EXPORT_SYMBOL(memset); 31EXPORT_SYMBOL(memset);
34EXPORT_SYMBOL(memcpy); 32EXPORT_SYMBOL(memcpy);
35EXPORT_SYMBOL(memmove); 33EXPORT_SYMBOL(memmove);
36EXPORT_SYMBOL(strcat);
37EXPORT_SYMBOL(strchr);
38#ifdef CONFIG_64BIT
39EXPORT_SYMBOL(strncmp);
40#endif
41EXPORT_SYMBOL(strlen);
42EXPORT_SYMBOL(strpbrk);
43EXPORT_SYMBOL(strncat);
44EXPORT_SYMBOL(strnlen);
45EXPORT_SYMBOL(strrchr);
46EXPORT_SYMBOL(strstr);
47 34
48EXPORT_SYMBOL(kernel_thread); 35EXPORT_SYMBOL(kernel_thread);
49 36
@@ -62,6 +49,3 @@ EXPORT_SYMBOL(__strnlen_user_asm);
62EXPORT_SYMBOL(csum_partial); 49EXPORT_SYMBOL(csum_partial);
63 50
64EXPORT_SYMBOL(invalid_pte_table); 51EXPORT_SYMBOL(invalid_pte_table);
65#ifdef CONFIG_GENERIC_IRQ_PROBE
66EXPORT_SYMBOL(probe_irq_mask);
67#endif
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index c66db5e5ab62..199a06e873c6 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -41,6 +41,10 @@
41#include <asm/elf.h> 41#include <asm/elf.h>
42#include <asm/isadep.h> 42#include <asm/isadep.h>
43#include <asm/inst.h> 43#include <asm/inst.h>
44#ifdef CONFIG_MIPS_MT_SMTC
45#include <asm/mipsmtregs.h>
46extern void smtc_idle_loop_hook(void);
47#endif /* CONFIG_MIPS_MT_SMTC */
44 48
45/* 49/*
46 * The idle thread. There's no useful work to be done, so just try to conserve 50 * The idle thread. There's no useful work to be done, so just try to conserve
@@ -51,9 +55,13 @@ ATTRIB_NORET void cpu_idle(void)
51{ 55{
52 /* endless idle loop with no priority at all */ 56 /* endless idle loop with no priority at all */
53 while (1) { 57 while (1) {
54 while (!need_resched()) 58 while (!need_resched()) {
59#ifdef CONFIG_MIPS_MT_SMTC
60 smtc_idle_loop_hook();
61#endif /* CONFIG_MIPS_MT_SMTC */
55 if (cpu_wait) 62 if (cpu_wait)
56 (*cpu_wait)(); 63 (*cpu_wait)();
64 }
57 preempt_enable_no_resched(); 65 preempt_enable_no_resched();
58 schedule(); 66 schedule();
59 preempt_disable(); 67 preempt_disable();
@@ -177,6 +185,17 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
177 childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); 185 childregs->cp0_status &= ~(ST0_CU2|ST0_CU1);
178 clear_tsk_thread_flag(p, TIF_USEDFPU); 186 clear_tsk_thread_flag(p, TIF_USEDFPU);
179 187
188#ifdef CONFIG_MIPS_MT_FPAFF
189 /*
190 * FPU affinity support is cleaner if we track the
191 * user-visible CPU affinity from the very beginning.
192 * The generic cpus_allowed mask will already have
193 * been copied from the parent before copy_thread
194 * is invoked.
195 */
196 p->thread.user_cpus_allowed = p->cpus_allowed;
197#endif /* CONFIG_MIPS_MT_FPAFF */
198
180 if (clone_flags & CLONE_SETTLS) 199 if (clone_flags & CLONE_SETTLS)
181 ti->tp_value = regs->regs[7]; 200 ti->tp_value = regs->regs[7];
182 201
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index f838b36cc765..f3106d0771b0 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -248,10 +248,20 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
248 break; 248 break;
249 case FPC_EIR: { /* implementation / version register */ 249 case FPC_EIR: { /* implementation / version register */
250 unsigned int flags; 250 unsigned int flags;
251#ifdef CONFIG_MIPS_MT_SMTC
252 unsigned int irqflags;
253 unsigned int mtflags;
254#endif /* CONFIG_MIPS_MT_SMTC */
251 255
252 if (!cpu_has_fpu) 256 if (!cpu_has_fpu)
253 break; 257 break;
254 258
259#ifdef CONFIG_MIPS_MT_SMTC
260 /* Read-modify-write of Status must be atomic */
261 local_irq_save(irqflags);
262 mtflags = dmt();
263#endif /* CONFIG_MIPS_MT_SMTC */
264
255 preempt_disable(); 265 preempt_disable();
256 if (cpu_has_mipsmt) { 266 if (cpu_has_mipsmt) {
257 unsigned int vpflags = dvpe(); 267 unsigned int vpflags = dvpe();
@@ -266,6 +276,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
266 __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); 276 __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
267 write_c0_status(flags); 277 write_c0_status(flags);
268 } 278 }
279#ifdef CONFIG_MIPS_MT_SMTC
280 emt(mtflags);
281 local_irq_restore(irqflags);
282#endif /* CONFIG_MIPS_MT_SMTC */
269 preempt_enable(); 283 preempt_enable();
270 break; 284 break;
271 } 285 }
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index 0d5cf97af727..8704dc0496ea 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -173,12 +173,22 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
173 break; 173 break;
174 case FPC_EIR: { /* implementation / version register */ 174 case FPC_EIR: { /* implementation / version register */
175 unsigned int flags; 175 unsigned int flags;
176#ifdef CONFIG_MIPS_MT_SMTC
177 unsigned int irqflags;
178 unsigned int mtflags;
179#endif /* CONFIG_MIPS_MT_SMTC */
176 180
177 if (!cpu_has_fpu) { 181 if (!cpu_has_fpu) {
178 tmp = 0; 182 tmp = 0;
179 break; 183 break;
180 } 184 }
181 185
186#ifdef CONFIG_MIPS_MT_SMTC
187 /* Read-modify-write of Status must be atomic */
188 local_irq_save(irqflags);
189 mtflags = dmt();
190#endif /* CONFIG_MIPS_MT_SMTC */
191
182 preempt_disable(); 192 preempt_disable();
183 if (cpu_has_mipsmt) { 193 if (cpu_has_mipsmt) {
184 unsigned int vpflags = dvpe(); 194 unsigned int vpflags = dvpe();
@@ -193,6 +203,10 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
193 __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); 203 __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
194 write_c0_status(flags); 204 write_c0_status(flags);
195 } 205 }
206#ifdef CONFIG_MIPS_MT_SMTC
207 emt(mtflags);
208 local_irq_restore(irqflags);
209#endif /* CONFIG_MIPS_MT_SMTC */
196 preempt_enable(); 210 preempt_enable();
197 break; 211 break;
198 } 212 }
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
index d2afbd19a9c8..0b1b54acee9f 100644
--- a/arch/mips/kernel/r4k_switch.S
+++ b/arch/mips/kernel/r4k_switch.S
@@ -88,7 +88,18 @@
88 88
89 PTR_ADDIU t0, $28, _THREAD_SIZE - 32 89 PTR_ADDIU t0, $28, _THREAD_SIZE - 32
90 set_saved_sp t0, t1, t2 90 set_saved_sp t0, t1, t2
91 91#ifdef CONFIG_MIPS_MT_SMTC
92 /* Read-modify-writes of Status must be atomic on a VPE */
93 mfc0 t2, CP0_TCSTATUS
94 ori t1, t2, TCSTATUS_IXMT
95 mtc0 t1, CP0_TCSTATUS
96 andi t2, t2, TCSTATUS_IXMT
97 ehb
98 DMT 8 # dmt t0
99 move t1,ra
100 jal mips_ihb
101 move ra,t1
102#endif /* CONFIG_MIPS_MT_SMTC */
92 mfc0 t1, CP0_STATUS /* Do we really need this? */ 103 mfc0 t1, CP0_STATUS /* Do we really need this? */
93 li a3, 0xff01 104 li a3, 0xff01
94 and t1, a3 105 and t1, a3
@@ -97,6 +108,18 @@
97 and a2, a3 108 and a2, a3
98 or a2, t1 109 or a2, t1
99 mtc0 a2, CP0_STATUS 110 mtc0 a2, CP0_STATUS
111#ifdef CONFIG_MIPS_MT_SMTC
112 ehb
113 andi t0, t0, VPECONTROL_TE
114 beqz t0, 1f
115 emt
1161:
117 mfc0 t1, CP0_TCSTATUS
118 xori t1, t1, TCSTATUS_IXMT
119 or t1, t1, t2
120 mtc0 t1, CP0_TCSTATUS
121 ehb
122#endif /* CONFIG_MIPS_MT_SMTC */
100 move v0, a0 123 move v0, a0
101 jr ra 124 jr ra
102 END(resume) 125 END(resume)
@@ -131,10 +154,19 @@ LEAF(_restore_fp)
131#define FPU_DEFAULT 0x00000000 154#define FPU_DEFAULT 0x00000000
132 155
133LEAF(_init_fpu) 156LEAF(_init_fpu)
157#ifdef CONFIG_MIPS_MT_SMTC
158 /* Rather than manipulate per-VPE Status, set per-TC bit in TCStatus */
159 mfc0 t0, CP0_TCSTATUS
160 /* Bit position is the same for Status, TCStatus */
161 li t1, ST0_CU1
162 or t0, t1
163 mtc0 t0, CP0_TCSTATUS
164#else /* Normal MIPS CU1 enable */
134 mfc0 t0, CP0_STATUS 165 mfc0 t0, CP0_STATUS
135 li t1, ST0_CU1 166 li t1, ST0_CU1
136 or t0, t1 167 or t0, t1
137 mtc0 t0, CP0_STATUS 168 mtc0 t0, CP0_STATUS
169#endif /* CONFIG_MIPS_MT_SMTC */
138 fpu_enable_hazard 170 fpu_enable_hazard
139 171
140 li t1, FPU_DEFAULT 172 li t1, FPU_DEFAULT
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index 986a9cf23067..6179805af9f0 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -21,45 +21,44 @@
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/fs.h> 22#include <linux/fs.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <asm/uaccess.h>
25#include <linux/slab.h>
26#include <linux/list.h>
27#include <linux/vmalloc.h>
28#include <linux/elf.h>
29#include <linux/seq_file.h>
30#include <linux/syscalls.h>
31#include <linux/moduleloader.h>
24#include <linux/interrupt.h> 32#include <linux/interrupt.h>
25#include <linux/irq.h>
26#include <linux/poll.h> 33#include <linux/poll.h>
27#include <linux/sched.h> 34#include <linux/sched.h>
28#include <linux/wait.h> 35#include <linux/wait.h>
29
30#include <asm/mipsmtregs.h> 36#include <asm/mipsmtregs.h>
31#include <asm/bitops.h> 37#include <asm/cacheflush.h>
38#include <asm/atomic.h>
32#include <asm/cpu.h> 39#include <asm/cpu.h>
33#include <asm/processor.h> 40#include <asm/processor.h>
41#include <asm/system.h>
42#include <asm/vpe.h>
34#include <asm/rtlx.h> 43#include <asm/rtlx.h>
35#include <asm/uaccess.h>
36 44
37#define RTLX_TARG_VPE 1 45#define RTLX_TARG_VPE 1
38 46
39static struct rtlx_info *rtlx; 47static struct rtlx_info *rtlx;
40static int major; 48static int major;
41static char module_name[] = "rtlx"; 49static char module_name[] = "rtlx";
42static struct irqaction irq;
43static int irq_num;
44
45static inline int spacefree(int read, int write, int size)
46{
47 if (read == write) {
48 /*
49 * never fill the buffer completely, so indexes are always
50 * equal if empty and only empty, or !equal if data available
51 */
52 return size - 1;
53 }
54
55 return ((read + size - write) % size) - 1;
56}
57 50
58static struct chan_waitqueues { 51static struct chan_waitqueues {
59 wait_queue_head_t rt_queue; 52 wait_queue_head_t rt_queue;
60 wait_queue_head_t lx_queue; 53 wait_queue_head_t lx_queue;
54 int in_open;
61} channel_wqs[RTLX_CHANNELS]; 55} channel_wqs[RTLX_CHANNELS];
62 56
57static struct irqaction irq;
58static int irq_num;
59static struct vpe_notifications notify;
60static int sp_stopping = 0;
61
63extern void *vpe_get_shared(int index); 62extern void *vpe_get_shared(int index);
64 63
65static void rtlx_dispatch(struct pt_regs *regs) 64static void rtlx_dispatch(struct pt_regs *regs)
@@ -67,174 +66,298 @@ static void rtlx_dispatch(struct pt_regs *regs)
67 do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ, regs); 66 do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ, regs);
68} 67}
69 68
69
70/* Interrupt handler may be called before rtlx_init has otherwise had
71 a chance to run.
72*/
70static irqreturn_t rtlx_interrupt(int irq, void *dev_id, struct pt_regs *regs) 73static irqreturn_t rtlx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
71{ 74{
72 int i; 75 int i;
73 76
74 for (i = 0; i < RTLX_CHANNELS; i++) { 77 for (i = 0; i < RTLX_CHANNELS; i++) {
75 struct rtlx_channel *chan = &rtlx->channel[i]; 78 wake_up(&channel_wqs[i].lx_queue);
76 79 wake_up(&channel_wqs[i].rt_queue);
77 if (chan->lx_read != chan->lx_write)
78 wake_up_interruptible(&channel_wqs[i].lx_queue);
79 } 80 }
80 81
81 return IRQ_HANDLED; 82 return IRQ_HANDLED;
82} 83}
83 84
84/* call when we have the address of the shared structure from the SP side. */ 85static __attribute_used__ void dump_rtlx(void)
85static int rtlx_init(struct rtlx_info *rtlxi)
86{ 86{
87 int i; 87 int i;
88 88
89 if (rtlxi->id != RTLX_ID) { 89 printk("id 0x%lx state %d\n", rtlx->id, rtlx->state);
90 printk(KERN_WARNING "no valid RTLX id at 0x%p\n", rtlxi);
91 return -ENOEXEC;
92 }
93 90
94 /* initialise the wait queues */
95 for (i = 0; i < RTLX_CHANNELS; i++) { 91 for (i = 0; i < RTLX_CHANNELS; i++) {
96 init_waitqueue_head(&channel_wqs[i].rt_queue); 92 struct rtlx_channel *chan = &rtlx->channel[i];
97 init_waitqueue_head(&channel_wqs[i].lx_queue);
98 }
99 93
100 /* set up for interrupt handling */ 94 printk(" rt_state %d lx_state %d buffer_size %d\n",
101 memset(&irq, 0, sizeof(struct irqaction)); 95 chan->rt_state, chan->lx_state, chan->buffer_size);
102 96
103 if (cpu_has_vint) 97 printk(" rt_read %d rt_write %d\n",
104 set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch); 98 chan->rt_read, chan->rt_write);
105 99
106 irq_num = MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ; 100 printk(" lx_read %d lx_write %d\n",
107 irq.handler = rtlx_interrupt; 101 chan->lx_read, chan->lx_write);
108 irq.flags = SA_INTERRUPT; 102
109 irq.name = "RTLX"; 103 printk(" rt_buffer <%s>\n", chan->rt_buffer);
110 irq.dev_id = rtlx; 104 printk(" lx_buffer <%s>\n", chan->lx_buffer);
111 setup_irq(irq_num, &irq); 105 }
106}
107
108/* call when we have the address of the shared structure from the SP side. */
109static int rtlx_init(struct rtlx_info *rtlxi)
110{
111 if (rtlxi->id != RTLX_ID) {
112 printk(KERN_ERR "no valid RTLX id at 0x%p 0x%x\n", rtlxi, rtlxi->id);
113 return -ENOEXEC;
114 }
112 115
113 rtlx = rtlxi; 116 rtlx = rtlxi;
114 117
115 return 0; 118 return 0;
116} 119}
117 120
118/* only allow one open process at a time to open each channel */ 121/* notifications */
119static int rtlx_open(struct inode *inode, struct file *filp) 122static void starting(int vpe)
120{ 123{
121 int minor, ret; 124 int i;
125 sp_stopping = 0;
126
127 /* force a reload of rtlx */
128 rtlx=NULL;
129
130 /* wake up any sleeping rtlx_open's */
131 for (i = 0; i < RTLX_CHANNELS; i++)
132 wake_up_interruptible(&channel_wqs[i].lx_queue);
133}
134
135static void stopping(int vpe)
136{
137 int i;
138
139 sp_stopping = 1;
140 for (i = 0; i < RTLX_CHANNELS; i++)
141 wake_up_interruptible(&channel_wqs[i].lx_queue);
142}
143
144
145int rtlx_open(int index, int can_sleep)
146{
147 int ret;
122 struct rtlx_channel *chan; 148 struct rtlx_channel *chan;
149 volatile struct rtlx_info **p;
123 150
124 /* assume only 1 device at the mo. */ 151 if (index >= RTLX_CHANNELS) {
125 minor = MINOR(inode->i_rdev); 152 printk(KERN_DEBUG "rtlx_open index out of range\n");
153 return -ENOSYS;
154 }
155
156 if (channel_wqs[index].in_open) {
157 printk(KERN_DEBUG "rtlx_open channel %d already opened\n", index);
158 return -EBUSY;
159 }
160
161 channel_wqs[index].in_open++;
126 162
127 if (rtlx == NULL) { 163 if (rtlx == NULL) {
128 struct rtlx_info **p;
129 if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) { 164 if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) {
130 printk(KERN_ERR "vpe_get_shared is NULL. " 165 if (can_sleep) {
131 "Has an SP program been loaded?\n"); 166 DECLARE_WAITQUEUE(wait, current);
132 return -EFAULT; 167
168 /* go to sleep */
169 add_wait_queue(&channel_wqs[index].lx_queue, &wait);
170
171 set_current_state(TASK_INTERRUPTIBLE);
172 while ((p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) {
173 schedule();
174 set_current_state(TASK_INTERRUPTIBLE);
175 }
176
177 set_current_state(TASK_RUNNING);
178 remove_wait_queue(&channel_wqs[index].lx_queue, &wait);
179
180 /* back running */
181 } else {
182 printk( KERN_DEBUG "No SP program loaded, and device "
183 "opened with O_NONBLOCK\n");
184 channel_wqs[index].in_open = 0;
185 return -ENOSYS;
186 }
133 } 187 }
134 188
135 if (*p == NULL) { 189 if (*p == NULL) {
136 printk(KERN_ERR "vpe_shared %p %p\n", p, *p); 190 if (can_sleep) {
137 return -EFAULT; 191 DECLARE_WAITQUEUE(wait, current);
192
193 /* go to sleep */
194 add_wait_queue(&channel_wqs[index].lx_queue, &wait);
195
196 set_current_state(TASK_INTERRUPTIBLE);
197 while (*p == NULL) {
198 schedule();
199
200 /* reset task state to interruptable otherwise
201 we'll whizz round here like a very fast loopy
202 thing. schedule() appears to return with state
203 set to TASK_RUNNING.
204
205 If the loaded SP program, for whatever reason,
206 doesn't set up the shared structure *p will never
207 become true. So whoever connected to either /dev/rt?
208 or if it was kspd, will then take up rather a lot of
209 processor cycles.
210 */
211
212 set_current_state(TASK_INTERRUPTIBLE);
213 }
214
215 set_current_state(TASK_RUNNING);
216 remove_wait_queue(&channel_wqs[index].lx_queue, &wait);
217
218 /* back running */
219 }
220 else {
221 printk(" *vpe_get_shared is NULL. "
222 "Has an SP program been loaded?\n");
223 channel_wqs[index].in_open = 0;
224 return -ENOSYS;
225 }
226 }
227
228 if ((unsigned int)*p < KSEG0) {
229 printk(KERN_WARNING "vpe_get_shared returned an invalid pointer "
230 "maybe an error code %d\n", (int)*p);
231 channel_wqs[index].in_open = 0;
232 return -ENOSYS;
138 } 233 }
139 234
140 if ((ret = rtlx_init(*p)) < 0) 235 if ((ret = rtlx_init(*p)) < 0) {
141 return ret; 236 channel_wqs[index].in_open = 0;
237 return ret;
238 }
142 } 239 }
143 240
144 chan = &rtlx->channel[minor]; 241 chan = &rtlx->channel[index];
145 242
146 if (test_and_set_bit(RTLX_STATE_OPENED, &chan->lx_state)) 243 if (chan->lx_state == RTLX_STATE_OPENED) {
147 return -EBUSY; 244 channel_wqs[index].in_open = 0;
245 return -EBUSY;
246 }
148 247
248 chan->lx_state = RTLX_STATE_OPENED;
249 channel_wqs[index].in_open = 0;
149 return 0; 250 return 0;
150} 251}
151 252
152static int rtlx_release(struct inode *inode, struct file *filp) 253int rtlx_release(int index)
153{ 254{
154 int minor = MINOR(inode->i_rdev); 255 rtlx->channel[index].lx_state = RTLX_STATE_UNUSED;
155
156 clear_bit(RTLX_STATE_OPENED, &rtlx->channel[minor].lx_state);
157 smp_mb__after_clear_bit();
158
159 return 0; 256 return 0;
160} 257}
161 258
162static unsigned int rtlx_poll(struct file *file, poll_table * wait) 259unsigned int rtlx_read_poll(int index, int can_sleep)
163{ 260{
164 int minor; 261 struct rtlx_channel *chan;
165 unsigned int mask = 0;
166 struct rtlx_channel *chan;
167 262
168 minor = MINOR(file->f_dentry->d_inode->i_rdev); 263 if (rtlx == NULL)
169 chan = &rtlx->channel[minor]; 264 return 0;
170 265
171 poll_wait(file, &channel_wqs[minor].rt_queue, wait); 266 chan = &rtlx->channel[index];
172 poll_wait(file, &channel_wqs[minor].lx_queue, wait);
173 267
174 /* data available to read? */ 268 /* data available to read? */
175 if (chan->lx_read != chan->lx_write) 269 if (chan->lx_read == chan->lx_write) {
176 mask |= POLLIN | POLLRDNORM; 270 if (can_sleep) {
271 DECLARE_WAITQUEUE(wait, current);
177 272
178 /* space to write */ 273 /* go to sleep */
179 if (spacefree(chan->rt_read, chan->rt_write, chan->buffer_size)) 274 add_wait_queue(&channel_wqs[index].lx_queue, &wait);
180 mask |= POLLOUT | POLLWRNORM;
181 275
182 return mask; 276 set_current_state(TASK_INTERRUPTIBLE);
277 while (chan->lx_read == chan->lx_write) {
278 schedule();
279
280 set_current_state(TASK_INTERRUPTIBLE);
281
282 if (sp_stopping) {
283 set_current_state(TASK_RUNNING);
284 remove_wait_queue(&channel_wqs[index].lx_queue, &wait);
285 return 0;
286 }
287 }
288
289 set_current_state(TASK_RUNNING);
290 remove_wait_queue(&channel_wqs[index].lx_queue, &wait);
291
292 /* back running */
293 }
294 else
295 return 0;
296 }
297
298 return (chan->lx_write + chan->buffer_size - chan->lx_read)
299 % chan->buffer_size;
183} 300}
184 301
185static ssize_t rtlx_read(struct file *file, char __user * buffer, size_t count, 302static inline int write_spacefree(int read, int write, int size)
186 loff_t * ppos)
187{ 303{
188 unsigned long failed; 304 if (read == write) {
189 size_t fl = 0L; 305 /*
190 int minor; 306 * Never fill the buffer completely, so indexes are always
191 struct rtlx_channel *lx; 307 * equal if empty and only empty, or !equal if data available
192 DECLARE_WAITQUEUE(wait, current); 308 */
309 return size - 1;
310 }
193 311
194 minor = MINOR(file->f_dentry->d_inode->i_rdev); 312 return ((read + size - write) % size) - 1;
195 lx = &rtlx->channel[minor]; 313}
196 314
197 /* data available? */ 315unsigned int rtlx_write_poll(int index)
198 if (lx->lx_write == lx->lx_read) { 316{
199 if (file->f_flags & O_NONBLOCK) 317 struct rtlx_channel *chan = &rtlx->channel[index];
200 return 0; /* -EAGAIN makes cat whinge */ 318 return write_spacefree(chan->rt_read, chan->rt_write, chan->buffer_size);
319}
201 320
202 /* go to sleep */ 321static inline void copy_to(void *dst, void *src, size_t count, int user)
203 add_wait_queue(&channel_wqs[minor].lx_queue, &wait); 322{
204 set_current_state(TASK_INTERRUPTIBLE); 323 if (user)
324 copy_to_user(dst, src, count);
325 else
326 memcpy(dst, src, count);
327}
205 328
206 while (lx->lx_write == lx->lx_read) 329static inline void copy_from(void *dst, void *src, size_t count, int user)
207 schedule(); 330{
331 if (user)
332 copy_from_user(dst, src, count);
333 else
334 memcpy(dst, src, count);
335}
208 336
209 set_current_state(TASK_RUNNING); 337ssize_t rtlx_read(int index, void *buff, size_t count, int user)
210 remove_wait_queue(&channel_wqs[minor].lx_queue, &wait); 338{
339 size_t fl = 0L;
340 struct rtlx_channel *lx;
211 341
212 /* back running */ 342 if (rtlx == NULL)
213 } 343 return -ENOSYS;
344
345 lx = &rtlx->channel[index];
214 346
215 /* find out how much in total */ 347 /* find out how much in total */
216 count = min(count, 348 count = min(count,
217 (size_t)(lx->lx_write + lx->buffer_size - lx->lx_read) % lx->buffer_size); 349 (size_t)(lx->lx_write + lx->buffer_size - lx->lx_read)
350 % lx->buffer_size);
218 351
219 /* then how much from the read pointer onwards */ 352 /* then how much from the read pointer onwards */
220 fl = min(count, (size_t)lx->buffer_size - lx->lx_read); 353 fl = min( count, (size_t)lx->buffer_size - lx->lx_read);
221 354
222 failed = copy_to_user (buffer, &lx->lx_buffer[lx->lx_read], fl); 355 copy_to(buff, &lx->lx_buffer[lx->lx_read], fl, user);
223 if (failed) {
224 count = fl - failed;
225 goto out;
226 }
227 356
228 /* and if there is anything left at the beginning of the buffer */ 357 /* and if there is anything left at the beginning of the buffer */
229 if (count - fl) { 358 if ( count - fl )
230 failed = copy_to_user (buffer + fl, lx->lx_buffer, count - fl); 359 copy_to (buff + fl, lx->lx_buffer, count - fl, user);
231 if (failed) {
232 count -= failed;
233 goto out;
234 }
235 }
236 360
237out:
238 /* update the index */ 361 /* update the index */
239 lx->lx_read += count; 362 lx->lx_read += count;
240 lx->lx_read %= lx->buffer_size; 363 lx->lx_read %= lx->buffer_size;
@@ -242,20 +365,101 @@ out:
242 return count; 365 return count;
243} 366}
244 367
245static ssize_t rtlx_write(struct file *file, const char __user * buffer, 368ssize_t rtlx_write(int index, void *buffer, size_t count, int user)
369{
370 struct rtlx_channel *rt;
371 size_t fl;
372
373 if (rtlx == NULL)
374 return(-ENOSYS);
375
376 rt = &rtlx->channel[index];
377
378 /* total number of bytes to copy */
379 count = min(count,
380 (size_t)write_spacefree(rt->rt_read, rt->rt_write,
381 rt->buffer_size));
382
383 /* first bit from write pointer to the end of the buffer, or count */
384 fl = min(count, (size_t) rt->buffer_size - rt->rt_write);
385
386 copy_from (&rt->rt_buffer[rt->rt_write], buffer, fl, user);
387
388 /* if there's any left copy to the beginning of the buffer */
389 if( count - fl )
390 copy_from (rt->rt_buffer, buffer + fl, count - fl, user);
391
392 rt->rt_write += count;
393 rt->rt_write %= rt->buffer_size;
394
395 return(count);
396}
397
398
399static int file_open(struct inode *inode, struct file *filp)
400{
401 int minor = MINOR(inode->i_rdev);
402
403 return rtlx_open(minor, (filp->f_flags & O_NONBLOCK) ? 0 : 1);
404}
405
406static int file_release(struct inode *inode, struct file *filp)
407{
408 int minor;
409 minor = MINOR(inode->i_rdev);
410
411 return rtlx_release(minor);
412}
413
414static unsigned int file_poll(struct file *file, poll_table * wait)
415{
416 int minor;
417 unsigned int mask = 0;
418
419 minor = MINOR(file->f_dentry->d_inode->i_rdev);
420
421 poll_wait(file, &channel_wqs[minor].rt_queue, wait);
422 poll_wait(file, &channel_wqs[minor].lx_queue, wait);
423
424 if (rtlx == NULL)
425 return 0;
426
427 /* data available to read? */
428 if (rtlx_read_poll(minor, 0))
429 mask |= POLLIN | POLLRDNORM;
430
431 /* space to write */
432 if (rtlx_write_poll(minor))
433 mask |= POLLOUT | POLLWRNORM;
434
435 return mask;
436}
437
438static ssize_t file_read(struct file *file, char __user * buffer, size_t count,
439 loff_t * ppos)
440{
441 int minor = MINOR(file->f_dentry->d_inode->i_rdev);
442
443 /* data available? */
444 if (!rtlx_read_poll(minor, (file->f_flags & O_NONBLOCK) ? 0 : 1)) {
445 return 0; // -EAGAIN makes cat whinge
446 }
447
448 return rtlx_read(minor, buffer, count, 1);
449}
450
451static ssize_t file_write(struct file *file, const char __user * buffer,
246 size_t count, loff_t * ppos) 452 size_t count, loff_t * ppos)
247{ 453{
248 unsigned long failed;
249 int minor; 454 int minor;
250 struct rtlx_channel *rt; 455 struct rtlx_channel *rt;
251 size_t fl;
252 DECLARE_WAITQUEUE(wait, current); 456 DECLARE_WAITQUEUE(wait, current);
253 457
254 minor = MINOR(file->f_dentry->d_inode->i_rdev); 458 minor = MINOR(file->f_dentry->d_inode->i_rdev);
255 rt = &rtlx->channel[minor]; 459 rt = &rtlx->channel[minor];
256 460
257 /* any space left... */ 461 /* any space left... */
258 if (!spacefree(rt->rt_read, rt->rt_write, rt->buffer_size)) { 462 if (!rtlx_write_poll(minor)) {
259 463
260 if (file->f_flags & O_NONBLOCK) 464 if (file->f_flags & O_NONBLOCK)
261 return -EAGAIN; 465 return -EAGAIN;
@@ -263,61 +467,64 @@ static ssize_t rtlx_write(struct file *file, const char __user * buffer,
263 add_wait_queue(&channel_wqs[minor].rt_queue, &wait); 467 add_wait_queue(&channel_wqs[minor].rt_queue, &wait);
264 set_current_state(TASK_INTERRUPTIBLE); 468 set_current_state(TASK_INTERRUPTIBLE);
265 469
266 while (!spacefree(rt->rt_read, rt->rt_write, rt->buffer_size)) 470 while (!rtlx_write_poll(minor))
267 schedule(); 471 schedule();
268 472
269 set_current_state(TASK_RUNNING); 473 set_current_state(TASK_RUNNING);
270 remove_wait_queue(&channel_wqs[minor].rt_queue, &wait); 474 remove_wait_queue(&channel_wqs[minor].rt_queue, &wait);
271 } 475 }
272 476
273 /* total number of bytes to copy */ 477 return rtlx_write(minor, (void *)buffer, count, 1);
274 count = min(count, (size_t)spacefree(rt->rt_read, rt->rt_write, rt->buffer_size) );
275
276 /* first bit from write pointer to the end of the buffer, or count */
277 fl = min(count, (size_t) rt->buffer_size - rt->rt_write);
278
279 failed = copy_from_user(&rt->rt_buffer[rt->rt_write], buffer, fl);
280 if (failed) {
281 count = fl - failed;
282 goto out;
283 }
284
285 /* if there's any left copy to the beginning of the buffer */
286 if (count - fl) {
287 failed = copy_from_user(rt->rt_buffer, buffer + fl, count - fl);
288 if (failed) {
289 count -= failed;
290 goto out;
291 }
292 }
293
294out:
295 rt->rt_write += count;
296 rt->rt_write %= rt->buffer_size;
297
298 return count;
299} 478}
300 479
301static struct file_operations rtlx_fops = { 480static struct file_operations rtlx_fops = {
302 .owner = THIS_MODULE, 481 .owner = THIS_MODULE,
303 .open = rtlx_open, 482 .open = file_open,
304 .release = rtlx_release, 483 .release = file_release,
305 .write = rtlx_write, 484 .write = file_write,
306 .read = rtlx_read, 485 .read = file_read,
307 .poll = rtlx_poll 486 .poll = file_poll
308}; 487};
309 488
489static struct irqaction rtlx_irq = {
490 .handler = rtlx_interrupt,
491 .flags = SA_INTERRUPT,
492 .name = "RTLX",
493};
494
495static int rtlx_irq_num = MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ;
496
310static char register_chrdev_failed[] __initdata = 497static char register_chrdev_failed[] __initdata =
311 KERN_ERR "rtlx_module_init: unable to register device\n"; 498 KERN_ERR "rtlx_module_init: unable to register device\n";
312 499
313static int __init rtlx_module_init(void) 500static int rtlx_module_init(void)
314{ 501{
502 int i;
503
315 major = register_chrdev(0, module_name, &rtlx_fops); 504 major = register_chrdev(0, module_name, &rtlx_fops);
316 if (major < 0) { 505 if (major < 0) {
317 printk(register_chrdev_failed); 506 printk(register_chrdev_failed);
318 return major; 507 return major;
319 } 508 }
320 509
510 /* initialise the wait queues */
511 for (i = 0; i < RTLX_CHANNELS; i++) {
512 init_waitqueue_head(&channel_wqs[i].rt_queue);
513 init_waitqueue_head(&channel_wqs[i].lx_queue);
514 channel_wqs[i].in_open = 0;
515 }
516
517 /* set up notifiers */
518 notify.start = starting;
519 notify.stop = stopping;
520 vpe_notify(RTLX_TARG_VPE, &notify);
521
522 if (cpu_has_vint)
523 set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch);
524
525 rtlx_irq.dev_id = rtlx;
526 setup_irq(rtlx_irq_num, &rtlx_irq);
527
321 return 0; 528 return 0;
322} 529}
323 530
@@ -330,5 +537,5 @@ module_init(rtlx_module_init);
330module_exit(rtlx_module_exit); 537module_exit(rtlx_module_exit);
331 538
332MODULE_DESCRIPTION("MIPS RTLX"); 539MODULE_DESCRIPTION("MIPS RTLX");
333MODULE_AUTHOR("Elizabeth Clarke, MIPS Technologies, Inc."); 540MODULE_AUTHOR("Elizabeth Oldham, MIPS Technologies, Inc.");
334MODULE_LICENSE("GPL"); 541MODULE_LICENSE("GPL");
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index 2f2dc54b2e26..a0ac0e5f61ad 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -569,8 +569,19 @@ einval: li v0, -EINVAL
569 sys sys_tkill 2 569 sys sys_tkill 2
570 sys sys_sendfile64 5 570 sys sys_sendfile64 5
571 sys sys_futex 6 571 sys sys_futex 6
572#ifdef CONFIG_MIPS_MT_FPAFF
573 /*
574 * For FPU affinity scheduling on MIPS MT processors, we need to
575 * intercept sys_sched_xxxaffinity() calls until we get a proper hook
576 * in kernel/sched.c. Considered only temporary we only support these
577 * hooks for the 32-bit kernel - there is no MIPS64 MT processor atm.
578 */
579 sys mipsmt_sys_sched_setaffinity 3
580 sys mipsmt_sys_sched_getaffinity 3
581#else
572 sys sys_sched_setaffinity 3 582 sys sys_sched_setaffinity 3
573 sys sys_sched_getaffinity 3 /* 4240 */ 583 sys sys_sched_getaffinity 3 /* 4240 */
584#endif /* CONFIG_MIPS_MT_FPAFF */
574 sys sys_io_setup 2 585 sys sys_io_setup 2
575 sys sys_io_destroy 1 586 sys sys_io_destroy 1
576 sys sys_io_getevents 5 587 sys sys_io_getevents 5
@@ -634,6 +645,8 @@ einval: li v0, -EINVAL
634 sys sys_pselect6 6 645 sys sys_pselect6 6
635 sys sys_ppoll 5 646 sys sys_ppoll 5
636 sys sys_unshare 1 647 sys sys_unshare 1
648 sys sys_splice 4
649 sys sys_sync_file_range 7 /* 4305 */
637 .endm 650 .endm
638 651
639 /* We pre-compute the number of _instruction_ bytes needed to 652 /* We pre-compute the number of _instruction_ bytes needed to
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index 98bf25df56f3..9ba750887377 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -460,3 +460,5 @@ sys_call_table:
460 PTR sys_pselect6 /* 5260 */ 460 PTR sys_pselect6 /* 5260 */
461 PTR sys_ppoll 461 PTR sys_ppoll
462 PTR sys_unshare 462 PTR sys_unshare
463 PTR sys_splice
464 PTR sys_sync_file_range
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 05a2c0567dae..942aca26f9c4 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -386,3 +386,5 @@ EXPORT(sysn32_call_table)
386 PTR sys_pselect6 386 PTR sys_pselect6
387 PTR sys_ppoll /* 6265 */ 387 PTR sys_ppoll /* 6265 */
388 PTR sys_unshare 388 PTR sys_unshare
389 PTR sys_splice
390 PTR sys_sync_file_range
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 19c4ca481b02..b53a9207f530 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -508,4 +508,6 @@ sys_call_table:
508 PTR sys_pselect6 508 PTR sys_pselect6
509 PTR sys_ppoll 509 PTR sys_ppoll
510 PTR sys_unshare 510 PTR sys_unshare
511 PTR sys_splice
512 PTR sys32_sync_file_range /* 4305 */
511 .size sys_call_table,.-sys_call_table 513 .size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index dcbfd27071f0..bcf1b10e518f 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -529,7 +529,10 @@ void __init setup_arch(char **cmdline_p)
529 529
530int __init fpu_disable(char *s) 530int __init fpu_disable(char *s)
531{ 531{
532 cpu_data[0].options &= ~MIPS_CPU_FPU; 532 int i;
533
534 for (i = 0; i < NR_CPUS; i++)
535 cpu_data[i].options &= ~MIPS_CPU_FPU;
533 536
534 return 1; 537 return 1;
535} 538}
diff --git a/arch/mips/kernel/smp_mt.c b/arch/mips/kernel/smp-mt.c
index 993b8bf56aaf..57770902b9ae 100644
--- a/arch/mips/kernel/smp_mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -1,8 +1,4 @@
1/* 1/*
2 * Copyright (C) 2004, 2005 MIPS Technologies, Inc. All rights reserved.
3 *
4 * Elizabeth Clarke (beth@mips.com)
5 *
6 * This program is free software; you can distribute it and/or modify it 2 * This program is free software; you can distribute it and/or modify it
7 * under the terms of the GNU General Public License (Version 2) as 3 * under the terms of the GNU General Public License (Version 2) as
8 * published by the Free Software Foundation. 4 * published by the Free Software Foundation.
@@ -16,6 +12,10 @@
16 * with this program; if not, write to the Free Software Foundation, Inc., 12 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 13 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
18 * 14 *
15 * Copyright (C) 2004, 05, 06 MIPS Technologies, Inc.
16 * Elizabeth Clarke (beth@mips.com)
17 * Ralf Baechle (ralf@linux-mips.org)
18 * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
19 */ 19 */
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/sched.h> 21#include <linux/sched.h>
@@ -24,6 +24,7 @@
24#include <linux/compiler.h> 24#include <linux/compiler.h>
25 25
26#include <asm/atomic.h> 26#include <asm/atomic.h>
27#include <asm/cacheflush.h>
27#include <asm/cpu.h> 28#include <asm/cpu.h>
28#include <asm/processor.h> 29#include <asm/processor.h>
29#include <asm/system.h> 30#include <asm/system.h>
@@ -33,8 +34,8 @@
33#include <asm/time.h> 34#include <asm/time.h>
34#include <asm/mipsregs.h> 35#include <asm/mipsregs.h>
35#include <asm/mipsmtregs.h> 36#include <asm/mipsmtregs.h>
36#include <asm/cacheflush.h> 37#include <asm/mips_mt.h>
37#include <asm/mips-boards/maltaint.h> 38#include <asm/mips-boards/maltaint.h> /* This is f*cking wrong */
38 39
39#define MIPS_CPU_IPI_RESCHED_IRQ 0 40#define MIPS_CPU_IPI_RESCHED_IRQ 0
40#define MIPS_CPU_IPI_CALL_IRQ 1 41#define MIPS_CPU_IPI_CALL_IRQ 1
@@ -66,6 +67,7 @@ void __init sanitize_tlb_entries(void)
66 if (!cpu_has_mipsmt) 67 if (!cpu_has_mipsmt)
67 return; 68 return;
68 69
70 /* Enable VPC */
69 set_c0_mvpcontrol(MVPCONTROL_VPC); 71 set_c0_mvpcontrol(MVPCONTROL_VPC);
70 72
71 back_to_back_c0_hazard(); 73 back_to_back_c0_hazard();
@@ -106,12 +108,12 @@ void __init sanitize_tlb_entries(void)
106 108
107static void ipi_resched_dispatch (struct pt_regs *regs) 109static void ipi_resched_dispatch (struct pt_regs *regs)
108{ 110{
109 do_IRQ(MIPS_CPU_IPI_RESCHED_IRQ, regs); 111 do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ, regs);
110} 112}
111 113
112static void ipi_call_dispatch (struct pt_regs *regs) 114static void ipi_call_dispatch (struct pt_regs *regs)
113{ 115{
114 do_IRQ(MIPS_CPU_IPI_CALL_IRQ, regs); 116 do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ, regs);
115} 117}
116 118
117irqreturn_t ipi_resched_interrupt(int irq, void *dev_id, struct pt_regs *regs) 119irqreturn_t ipi_resched_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -148,6 +150,11 @@ void plat_smp_setup(void)
148 unsigned long val; 150 unsigned long val;
149 int i, num; 151 int i, num;
150 152
153#ifdef CONFIG_MIPS_MT_FPAFF
154 /* If we have an FPU, enroll ourselves in the FPU-full mask */
155 if (cpu_has_fpu)
156 cpu_set(0, mt_fpu_cpumask);
157#endif /* CONFIG_MIPS_MT_FPAFF */
151 if (!cpu_has_mipsmt) 158 if (!cpu_has_mipsmt)
152 return; 159 return;
153 160
@@ -155,6 +162,8 @@ void plat_smp_setup(void)
155 dvpe(); 162 dvpe();
156 dmt(); 163 dmt();
157 164
165 mips_mt_set_cpuoptions();
166
158 /* Put MVPE's into 'configuration state' */ 167 /* Put MVPE's into 'configuration state' */
159 set_c0_mvpcontrol(MVPCONTROL_VPC); 168 set_c0_mvpcontrol(MVPCONTROL_VPC);
160 169
@@ -189,11 +198,13 @@ void plat_smp_setup(void)
189 198
190 if (i != 0) { 199 if (i != 0) {
191 write_vpe_c0_status((read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0); 200 write_vpe_c0_status((read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0);
192 write_vpe_c0_cause(read_vpe_c0_cause() & ~CAUSEF_IP);
193 201
194 /* set config to be the same as vpe0, particularly kseg0 coherency alg */ 202 /* set config to be the same as vpe0, particularly kseg0 coherency alg */
195 write_vpe_c0_config( read_c0_config()); 203 write_vpe_c0_config( read_c0_config());
196 204
205 /* make sure there are no software interrupts pending */
206 write_vpe_c0_cause(read_vpe_c0_cause() & ~(C_SW1|C_SW0));
207
197 /* Propagate Config7 */ 208 /* Propagate Config7 */
198 write_vpe_c0_config7(read_c0_config7()); 209 write_vpe_c0_config7(read_c0_config7());
199 } 210 }
@@ -233,16 +244,16 @@ void plat_smp_setup(void)
233 /* We'll wait until starting the secondaries before starting MVPE */ 244 /* We'll wait until starting the secondaries before starting MVPE */
234 245
235 printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num); 246 printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num);
247}
236 248
249void __init plat_prepare_cpus(unsigned int max_cpus)
250{
237 /* set up ipi interrupts */ 251 /* set up ipi interrupts */
238 if (cpu_has_vint) { 252 if (cpu_has_vint) {
239 set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); 253 set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch);
240 set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); 254 set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch);
241 } 255 }
242}
243 256
244void __init plat_prepare_cpus(unsigned int max_cpus)
245{
246 cpu_ipi_resched_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ; 257 cpu_ipi_resched_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ;
247 cpu_ipi_call_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ; 258 cpu_ipi_call_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ;
248 259
@@ -287,7 +298,8 @@ void prom_boot_secondary(int cpu, struct task_struct *idle)
287 /* global pointer */ 298 /* global pointer */
288 write_tc_gpr_gp((unsigned long)gp); 299 write_tc_gpr_gp((unsigned long)gp);
289 300
290 flush_icache_range((unsigned long)gp, (unsigned long)(gp + 1)); 301 flush_icache_range((unsigned long)gp,
302 (unsigned long)(gp + sizeof(struct thread_info)));
291 303
292 /* finally out of configuration and into chaos */ 304 /* finally out of configuration and into chaos */
293 clear_c0_mvpcontrol(MVPCONTROL_VPC); 305 clear_c0_mvpcontrol(MVPCONTROL_VPC);
@@ -305,6 +317,12 @@ void prom_smp_finish(void)
305{ 317{
306 write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ)); 318 write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ));
307 319
320#ifdef CONFIG_MIPS_MT_FPAFF
321 /* If we have an FPU, enroll ourselves in the FPU-full mask */
322 if (cpu_has_fpu)
323 cpu_set(smp_processor_id(), mt_fpu_cpumask);
324#endif /* CONFIG_MIPS_MT_FPAFF */
325
308 local_irq_enable(); 326 local_irq_enable();
309} 327}
310 328
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 78d171bfa331..d42f358754ad 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -38,6 +38,10 @@
38#include <asm/mmu_context.h> 38#include <asm/mmu_context.h>
39#include <asm/smp.h> 39#include <asm/smp.h>
40 40
41#ifdef CONFIG_MIPS_MT_SMTC
42#include <asm/mipsmtregs.h>
43#endif /* CONFIG_MIPS_MT_SMTC */
44
41cpumask_t phys_cpu_present_map; /* Bitmask of available CPUs */ 45cpumask_t phys_cpu_present_map; /* Bitmask of available CPUs */
42volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */ 46volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */
43cpumask_t cpu_online_map; /* Bitmask of currently online CPUs */ 47cpumask_t cpu_online_map; /* Bitmask of currently online CPUs */
@@ -85,6 +89,10 @@ asmlinkage void start_secondary(void)
85{ 89{
86 unsigned int cpu; 90 unsigned int cpu;
87 91
92#ifdef CONFIG_MIPS_MT_SMTC
93 /* Only do cpu_probe for first TC of CPU */
94 if ((read_c0_tcbind() & TCBIND_CURTC) == 0)
95#endif /* CONFIG_MIPS_MT_SMTC */
88 cpu_probe(); 96 cpu_probe();
89 cpu_report(); 97 cpu_report();
90 per_cpu_trap_init(); 98 per_cpu_trap_init();
@@ -179,11 +187,13 @@ int smp_call_function (void (*func) (void *info), void *info, int retry,
179 if (wait) 187 if (wait)
180 while (atomic_read(&data.finished) != cpus) 188 while (atomic_read(&data.finished) != cpus)
181 barrier(); 189 barrier();
190 call_data = NULL;
182 spin_unlock(&smp_call_lock); 191 spin_unlock(&smp_call_lock);
183 192
184 return 0; 193 return 0;
185} 194}
186 195
196
187void smp_call_function_interrupt(void) 197void smp_call_function_interrupt(void)
188{ 198{
189 void (*func) (void *info) = call_data->func; 199 void (*func) (void *info) = call_data->func;
@@ -446,5 +456,3 @@ subsys_initcall(topology_init);
446 456
447EXPORT_SYMBOL(flush_tlb_page); 457EXPORT_SYMBOL(flush_tlb_page);
448EXPORT_SYMBOL(flush_tlb_one); 458EXPORT_SYMBOL(flush_tlb_one);
449EXPORT_SYMBOL(cpu_data);
450EXPORT_SYMBOL(synchronize_irq);
diff --git a/arch/mips/kernel/smtc-asm.S b/arch/mips/kernel/smtc-asm.S
new file mode 100644
index 000000000000..c9d65196d917
--- /dev/null
+++ b/arch/mips/kernel/smtc-asm.S
@@ -0,0 +1,130 @@
1/*
2 * Assembly Language Functions for MIPS MT SMTC support
3 */
4
5/*
6 * This file should be built into the kernel only if CONFIG_MIPS_MT_SMTC is set. */
7
8#include <asm/regdef.h>
9#include <asm/asmmacro.h>
10#include <asm/stackframe.h>
11#include <asm/stackframe.h>
12
13/*
14 * "Software Interrupt" linkage.
15 *
16 * This is invoked when an "Interrupt" is sent from one TC to another,
17 * where the TC to be interrupted is halted, has it's Restart address
18 * and Status values saved by the "remote control" thread, then modified
19 * to cause execution to begin here, in kenel mode. This code then
20 * disguises the TC state as that of an exception and transfers
21 * control to the general exception or vectored interrupt handler.
22 */
23 .set noreorder
24
25/*
26The __smtc_ipi_vector would use k0 and k1 as temporaries and
271) Set EXL (this is per-VPE, so this can't be done by proxy!)
282) Restore the K/CU and IXMT bits to the pre "exception" state
29 (EXL means no interrupts and access to the kernel map).
303) Set EPC to be the saved value of TCRestart.
314) Jump to the exception handler entry point passed by the sender.
32
33CAN WE PROVE THAT WE WON'T DO THIS IF INTS DISABLED??
34*/
35
36/*
37 * Reviled and slandered vision: Set EXL and restore K/CU/IXMT
38 * state of pre-halt thread, then save everything and call
39 * thought some function pointer to imaginary_exception, which
40 * will parse a register value or memory message queue to
41 * deliver things like interprocessor interrupts. On return
42 * from that function, jump to the global ret_from_irq code
43 * to invoke the scheduler and return as appropriate.
44 */
45
46#define PT_PADSLOT4 (PT_R0-8)
47#define PT_PADSLOT5 (PT_R0-4)
48
49 .text
50 .align 5
51FEXPORT(__smtc_ipi_vector)
52 .set noat
53 /* Disable thread scheduling to make Status update atomic */
54 DMT 27 # dmt k1
55 ehb
56 /* Set EXL */
57 mfc0 k0,CP0_STATUS
58 ori k0,k0,ST0_EXL
59 mtc0 k0,CP0_STATUS
60 ehb
61 /* Thread scheduling now inhibited by EXL. Restore TE state. */
62 andi k1,k1,VPECONTROL_TE
63 beqz k1,1f
64 emt
651:
66 /*
67 * The IPI sender has put some information on the anticipated
68 * kernel stack frame. If we were in user mode, this will be
69 * built above the saved kernel SP. If we were already in the
70 * kernel, it will be built above the current CPU SP.
71 *
72 * Were we in kernel mode, as indicated by CU0?
73 */
74 sll k1,k0,3
75 .set noreorder
76 bltz k1,2f
77 move k1,sp
78 .set reorder
79 /*
80 * If previously in user mode, set CU0 and use kernel stack.
81 */
82 li k1,ST0_CU0
83 or k1,k1,k0
84 mtc0 k1,CP0_STATUS
85 ehb
86 get_saved_sp
87 /* Interrupting TC will have pre-set values in slots in the new frame */
882: subu k1,k1,PT_SIZE
89 /* Load TCStatus Value */
90 lw k0,PT_TCSTATUS(k1)
91 /* Write it to TCStatus to restore CU/KSU/IXMT state */
92 mtc0 k0,$2,1
93 ehb
94 lw k0,PT_EPC(k1)
95 mtc0 k0,CP0_EPC
96 /* Save all will redundantly recompute the SP, but use it for now */
97 SAVE_ALL
98 CLI
99 move a0,sp
100 /* Function to be invoked passed stack pad slot 5 */
101 lw t0,PT_PADSLOT5(sp)
102 /* Argument from sender passed in stack pad slot 4 */
103 lw a1,PT_PADSLOT4(sp)
104 jalr t0
105 nop
106 j ret_from_irq
107 nop
108
109/*
110 * Called from idle loop to provoke processing of queued IPIs
111 * First IPI message in queue passed as argument.
112 */
113
114LEAF(self_ipi)
115 /* Before anything else, block interrupts */
116 mfc0 t0,CP0_TCSTATUS
117 ori t1,t0,TCSTATUS_IXMT
118 mtc0 t1,CP0_TCSTATUS
119 ehb
120 /* We know we're in kernel mode, so prepare stack frame */
121 subu t1,sp,PT_SIZE
122 sw ra,PT_EPC(t1)
123 sw a0,PT_PADSLOT4(t1)
124 la t2,ipi_decode
125 sw t2,PT_PADSLOT5(t1)
126 /* Save pre-disable value of TCStatus */
127 sw t0,PT_TCSTATUS(t1)
128 j __smtc_ipi_vector
129 nop
130END(self_ipi)
diff --git a/arch/mips/kernel/smtc-proc.c b/arch/mips/kernel/smtc-proc.c
new file mode 100644
index 000000000000..6f3709996172
--- /dev/null
+++ b/arch/mips/kernel/smtc-proc.c
@@ -0,0 +1,93 @@
1/*
2 * /proc hooks for SMTC kernel
3 * Copyright (C) 2005 Mips Technologies, Inc
4 */
5
6#include <linux/kernel.h>
7#include <linux/sched.h>
8#include <linux/cpumask.h>
9#include <linux/interrupt.h>
10
11#include <asm/cpu.h>
12#include <asm/processor.h>
13#include <asm/atomic.h>
14#include <asm/system.h>
15#include <asm/hardirq.h>
16#include <asm/mmu_context.h>
17#include <asm/smp.h>
18#include <asm/mipsregs.h>
19#include <asm/cacheflush.h>
20#include <linux/proc_fs.h>
21
22#include <asm/smtc_proc.h>
23
24/*
25 * /proc diagnostic and statistics hooks
26 */
27
28/*
29 * Statistics gathered
30 */
31unsigned long selfipis[NR_CPUS];
32
33struct smtc_cpu_proc smtc_cpu_stats[NR_CPUS];
34
35static struct proc_dir_entry *smtc_stats;
36
37atomic_t smtc_fpu_recoveries;
38
39static int proc_read_smtc(char *page, char **start, off_t off,
40 int count, int *eof, void *data)
41{
42 int totalen = 0;
43 int len;
44 int i;
45 extern unsigned long ebase;
46
47 len = sprintf(page, "SMTC Status Word: 0x%08x\n", smtc_status);
48 totalen += len;
49 page += len;
50 len = sprintf(page, "Config7: 0x%08x\n", read_c0_config7());
51 totalen += len;
52 page += len;
53 len = sprintf(page, "EBASE: 0x%08lx\n", ebase);
54 totalen += len;
55 page += len;
56 len = sprintf(page, "Counter Interrupts taken per CPU (TC)\n");
57 totalen += len;
58 page += len;
59 for (i=0; i < NR_CPUS; i++) {
60 len = sprintf(page, "%d: %ld\n", i, smtc_cpu_stats[i].timerints);
61 totalen += len;
62 page += len;
63 }
64 len = sprintf(page, "Self-IPIs by CPU:\n");
65 totalen += len;
66 page += len;
67 for(i = 0; i < NR_CPUS; i++) {
68 len = sprintf(page, "%d: %ld\n", i, smtc_cpu_stats[i].selfipis);
69 totalen += len;
70 page += len;
71 }
72 len = sprintf(page, "%d Recoveries of \"stolen\" FPU\n",
73 atomic_read(&smtc_fpu_recoveries));
74 totalen += len;
75 page += len;
76
77 return totalen;
78}
79
80void init_smtc_stats(void)
81{
82 int i;
83
84 for (i=0; i<NR_CPUS; i++) {
85 smtc_cpu_stats[i].timerints = 0;
86 smtc_cpu_stats[i].selfipis = 0;
87 }
88
89 atomic_set(&smtc_fpu_recoveries, 0);
90
91 smtc_stats = create_proc_read_entry("smtc", 0444, NULL,
92 proc_read_smtc, NULL);
93}
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
new file mode 100644
index 000000000000..2e8e52c135e6
--- /dev/null
+++ b/arch/mips/kernel/smtc.c
@@ -0,0 +1,1322 @@
1/* Copyright (C) 2004 Mips Technologies, Inc */
2
3#include <linux/kernel.h>
4#include <linux/sched.h>
5#include <linux/cpumask.h>
6#include <linux/interrupt.h>
7
8#include <asm/cpu.h>
9#include <asm/processor.h>
10#include <asm/atomic.h>
11#include <asm/system.h>
12#include <asm/hardirq.h>
13#include <asm/hazards.h>
14#include <asm/mmu_context.h>
15#include <asm/smp.h>
16#include <asm/mipsregs.h>
17#include <asm/cacheflush.h>
18#include <asm/time.h>
19#include <asm/addrspace.h>
20#include <asm/smtc.h>
21#include <asm/smtc_ipi.h>
22#include <asm/smtc_proc.h>
23
24/*
25 * This file should be built into the kernel only if CONFIG_MIPS_MT_SMTC is set.
26 */
27
28/*
29 * MIPSCPU_INT_BASE is identically defined in both
30 * asm-mips/mips-boards/maltaint.h and asm-mips/mips-boards/simint.h,
31 * but as yet there's no properly organized include structure that
32 * will ensure that the right *int.h file will be included for a
33 * given platform build.
34 */
35
36#define MIPSCPU_INT_BASE 16
37
38#define MIPS_CPU_IPI_IRQ 1
39
40#define LOCK_MT_PRA() \
41 local_irq_save(flags); \
42 mtflags = dmt()
43
44#define UNLOCK_MT_PRA() \
45 emt(mtflags); \
46 local_irq_restore(flags)
47
48#define LOCK_CORE_PRA() \
49 local_irq_save(flags); \
50 mtflags = dvpe()
51
52#define UNLOCK_CORE_PRA() \
53 evpe(mtflags); \
54 local_irq_restore(flags)
55
56/*
57 * Data structures purely associated with SMTC parallelism
58 */
59
60
61/*
62 * Table for tracking ASIDs whose lifetime is prolonged.
63 */
64
65asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS];
66
67/*
68 * Clock interrupt "latch" buffers, per "CPU"
69 */
70
71unsigned int ipi_timer_latch[NR_CPUS];
72
73/*
74 * Number of InterProcessor Interupt (IPI) message buffers to allocate
75 */
76
77#define IPIBUF_PER_CPU 4
78
79struct smtc_ipi_q IPIQ[NR_CPUS];
80struct smtc_ipi_q freeIPIq;
81
82
83/* Forward declarations */
84
85void ipi_decode(struct pt_regs *, struct smtc_ipi *);
86void post_direct_ipi(int cpu, struct smtc_ipi *pipi);
87void setup_cross_vpe_interrupts(void);
88void init_smtc_stats(void);
89
90/* Global SMTC Status */
91
92unsigned int smtc_status = 0;
93
94/* Boot command line configuration overrides */
95
96static int vpelimit = 0;
97static int tclimit = 0;
98static int ipibuffers = 0;
99static int nostlb = 0;
100static int asidmask = 0;
101unsigned long smtc_asid_mask = 0xff;
102
103static int __init maxvpes(char *str)
104{
105 get_option(&str, &vpelimit);
106 return 1;
107}
108
109static int __init maxtcs(char *str)
110{
111 get_option(&str, &tclimit);
112 return 1;
113}
114
115static int __init ipibufs(char *str)
116{
117 get_option(&str, &ipibuffers);
118 return 1;
119}
120
121static int __init stlb_disable(char *s)
122{
123 nostlb = 1;
124 return 1;
125}
126
127static int __init asidmask_set(char *str)
128{
129 get_option(&str, &asidmask);
130 switch(asidmask) {
131 case 0x1:
132 case 0x3:
133 case 0x7:
134 case 0xf:
135 case 0x1f:
136 case 0x3f:
137 case 0x7f:
138 case 0xff:
139 smtc_asid_mask = (unsigned long)asidmask;
140 break;
141 default:
142 printk("ILLEGAL ASID mask 0x%x from command line\n", asidmask);
143 }
144 return 1;
145}
146
147__setup("maxvpes=", maxvpes);
148__setup("maxtcs=", maxtcs);
149__setup("ipibufs=", ipibufs);
150__setup("nostlb", stlb_disable);
151__setup("asidmask=", asidmask_set);
152
153/* Enable additional debug checks before going into CPU idle loop */
154#define SMTC_IDLE_HOOK_DEBUG
155
156#ifdef SMTC_IDLE_HOOK_DEBUG
157
158static int hang_trig = 0;
159
160static int __init hangtrig_enable(char *s)
161{
162 hang_trig = 1;
163 return 1;
164}
165
166
167__setup("hangtrig", hangtrig_enable);
168
169#define DEFAULT_BLOCKED_IPI_LIMIT 32
170
171static int timerq_limit = DEFAULT_BLOCKED_IPI_LIMIT;
172
173static int __init tintq(char *str)
174{
175 get_option(&str, &timerq_limit);
176 return 1;
177}
178
179__setup("tintq=", tintq);
180
181int imstuckcount[2][8];
182/* vpemask represents IM/IE bits of per-VPE Status registers, low-to-high */
183int vpemask[2][8] = {{0,1,1,0,0,0,0,1},{0,1,0,0,0,0,0,1}};
184int tcnoprog[NR_CPUS];
185static atomic_t idle_hook_initialized = {0};
186static int clock_hang_reported[NR_CPUS];
187
188#endif /* SMTC_IDLE_HOOK_DEBUG */
189
190/* Initialize shared TLB - the should probably migrate to smtc_setup_cpus() */
191
192void __init sanitize_tlb_entries(void)
193{
194 printk("Deprecated sanitize_tlb_entries() invoked\n");
195}
196
197
198/*
199 * Configure shared TLB - VPC configuration bit must be set by caller
200 */
201
202void smtc_configure_tlb(void)
203{
204 int i,tlbsiz,vpes;
205 unsigned long mvpconf0;
206 unsigned long config1val;
207
208 /* Set up ASID preservation table */
209 for (vpes=0; vpes<MAX_SMTC_TLBS; vpes++) {
210 for(i = 0; i < MAX_SMTC_ASIDS; i++) {
211 smtc_live_asid[vpes][i] = 0;
212 }
213 }
214 mvpconf0 = read_c0_mvpconf0();
215
216 if ((vpes = ((mvpconf0 & MVPCONF0_PVPE)
217 >> MVPCONF0_PVPE_SHIFT) + 1) > 1) {
218 /* If we have multiple VPEs, try to share the TLB */
219 if ((mvpconf0 & MVPCONF0_TLBS) && !nostlb) {
220 /*
221 * If TLB sizing is programmable, shared TLB
222 * size is the total available complement.
223 * Otherwise, we have to take the sum of all
224 * static VPE TLB entries.
225 */
226 if ((tlbsiz = ((mvpconf0 & MVPCONF0_PTLBE)
227 >> MVPCONF0_PTLBE_SHIFT)) == 0) {
228 /*
229 * If there's more than one VPE, there had better
230 * be more than one TC, because we need one to bind
231 * to each VPE in turn to be able to read
232 * its configuration state!
233 */
234 settc(1);
235 /* Stop the TC from doing anything foolish */
236 write_tc_c0_tchalt(TCHALT_H);
237 mips_ihb();
238 /* No need to un-Halt - that happens later anyway */
239 for (i=0; i < vpes; i++) {
240 write_tc_c0_tcbind(i);
241 /*
242 * To be 100% sure we're really getting the right
243 * information, we exit the configuration state
244 * and do an IHB after each rebinding.
245 */
246 write_c0_mvpcontrol(
247 read_c0_mvpcontrol() & ~ MVPCONTROL_VPC );
248 mips_ihb();
249 /*
250 * Only count if the MMU Type indicated is TLB
251 */
252 if(((read_vpe_c0_config() & MIPS_CONF_MT) >> 7) == 1) {
253 config1val = read_vpe_c0_config1();
254 tlbsiz += ((config1val >> 25) & 0x3f) + 1;
255 }
256
257 /* Put core back in configuration state */
258 write_c0_mvpcontrol(
259 read_c0_mvpcontrol() | MVPCONTROL_VPC );
260 mips_ihb();
261 }
262 }
263 write_c0_mvpcontrol(read_c0_mvpcontrol() | MVPCONTROL_STLB);
264
265 /*
266 * Setup kernel data structures to use software total,
267 * rather than read the per-VPE Config1 value. The values
268 * for "CPU 0" gets copied to all the other CPUs as part
269 * of their initialization in smtc_cpu_setup().
270 */
271
272 tlbsiz = tlbsiz & 0x3f; /* MIPS32 limits TLB indices to 64 */
273 cpu_data[0].tlbsize = tlbsiz;
274 smtc_status |= SMTC_TLB_SHARED;
275
276 printk("TLB of %d entry pairs shared by %d VPEs\n",
277 tlbsiz, vpes);
278 } else {
279 printk("WARNING: TLB Not Sharable on SMTC Boot!\n");
280 }
281 }
282}
283
284
285/*
286 * Incrementally build the CPU map out of constituent MIPS MT cores,
287 * using the specified available VPEs and TCs. Plaform code needs
288 * to ensure that each MIPS MT core invokes this routine on reset,
289 * one at a time(!).
290 *
291 * This version of the build_cpu_map and prepare_cpus routines assumes
292 * that *all* TCs of a MIPS MT core will be used for Linux, and that
293 * they will be spread across *all* available VPEs (to minimise the
294 * loss of efficiency due to exception service serialization).
295 * An improved version would pick up configuration information and
296 * possibly leave some TCs/VPEs as "slave" processors.
297 *
298 * Use c0_MVPConf0 to find out how many TCs are available, setting up
299 * phys_cpu_present_map and the logical/physical mappings.
300 */
301
302int __init mipsmt_build_cpu_map(int start_cpu_slot)
303{
304 int i, ntcs;
305
306 /*
307 * The CPU map isn't actually used for anything at this point,
308 * so it's not clear what else we should do apart from set
309 * everything up so that "logical" = "physical".
310 */
311 ntcs = ((read_c0_mvpconf0() & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1;
312 for (i=start_cpu_slot; i<NR_CPUS && i<ntcs; i++) {
313 cpu_set(i, phys_cpu_present_map);
314 __cpu_number_map[i] = i;
315 __cpu_logical_map[i] = i;
316 }
317 /* Initialize map of CPUs with FPUs */
318 cpus_clear(mt_fpu_cpumask);
319
320 /* One of those TC's is the one booting, and not a secondary... */
321 printk("%i available secondary CPU TC(s)\n", i - 1);
322
323 return i;
324}
325
326/*
327 * Common setup before any secondaries are started
328 * Make sure all CPU's are in a sensible state before we boot any of the
329 * secondaries.
330 *
331 * For MIPS MT "SMTC" operation, we set up all TCs, spread as evenly
332 * as possible across the available VPEs.
333 */
334
335static void smtc_tc_setup(int vpe, int tc, int cpu)
336{
337 settc(tc);
338 write_tc_c0_tchalt(TCHALT_H);
339 mips_ihb();
340 write_tc_c0_tcstatus((read_tc_c0_tcstatus()
341 & ~(TCSTATUS_TKSU | TCSTATUS_DA | TCSTATUS_IXMT))
342 | TCSTATUS_A);
343 write_tc_c0_tccontext(0);
344 /* Bind tc to vpe */
345 write_tc_c0_tcbind(vpe);
346 /* In general, all TCs should have the same cpu_data indications */
347 memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips));
348 /* For 34Kf, start with TC/CPU 0 as sole owner of single FPU context */
349 if (cpu_data[0].cputype == CPU_34K)
350 cpu_data[cpu].options &= ~MIPS_CPU_FPU;
351 cpu_data[cpu].vpe_id = vpe;
352 cpu_data[cpu].tc_id = tc;
353}
354
355
356void mipsmt_prepare_cpus(void)
357{
358 int i, vpe, tc, ntc, nvpe, tcpervpe, slop, cpu;
359 unsigned long flags;
360 unsigned long val;
361 int nipi;
362 struct smtc_ipi *pipi;
363
364 /* disable interrupts so we can disable MT */
365 local_irq_save(flags);
366 /* disable MT so we can configure */
367 dvpe();
368 dmt();
369
370 freeIPIq.lock = SPIN_LOCK_UNLOCKED;
371
372 /*
373 * We probably don't have as many VPEs as we do SMP "CPUs",
374 * but it's possible - and in any case we'll never use more!
375 */
376 for (i=0; i<NR_CPUS; i++) {
377 IPIQ[i].head = IPIQ[i].tail = NULL;
378 IPIQ[i].lock = SPIN_LOCK_UNLOCKED;
379 IPIQ[i].depth = 0;
380 ipi_timer_latch[i] = 0;
381 }
382
383 /* cpu_data index starts at zero */
384 cpu = 0;
385 cpu_data[cpu].vpe_id = 0;
386 cpu_data[cpu].tc_id = 0;
387 cpu++;
388
389 /* Report on boot-time options */
390 mips_mt_set_cpuoptions ();
391 if (vpelimit > 0)
392 printk("Limit of %d VPEs set\n", vpelimit);
393 if (tclimit > 0)
394 printk("Limit of %d TCs set\n", tclimit);
395 if (nostlb) {
396 printk("Shared TLB Use Inhibited - UNSAFE for Multi-VPE Operation\n");
397 }
398 if (asidmask)
399 printk("ASID mask value override to 0x%x\n", asidmask);
400
401 /* Temporary */
402#ifdef SMTC_IDLE_HOOK_DEBUG
403 if (hang_trig)
404 printk("Logic Analyser Trigger on suspected TC hang\n");
405#endif /* SMTC_IDLE_HOOK_DEBUG */
406
407 /* Put MVPE's into 'configuration state' */
408 write_c0_mvpcontrol( read_c0_mvpcontrol() | MVPCONTROL_VPC );
409
410 val = read_c0_mvpconf0();
411 nvpe = ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;
412 if (vpelimit > 0 && nvpe > vpelimit)
413 nvpe = vpelimit;
414 ntc = ((val & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1;
415 if (ntc > NR_CPUS)
416 ntc = NR_CPUS;
417 if (tclimit > 0 && ntc > tclimit)
418 ntc = tclimit;
419 tcpervpe = ntc / nvpe;
420 slop = ntc % nvpe; /* Residual TCs, < NVPE */
421
422 /* Set up shared TLB */
423 smtc_configure_tlb();
424
425 for (tc = 0, vpe = 0 ; (vpe < nvpe) && (tc < ntc) ; vpe++) {
426 /*
427 * Set the MVP bits.
428 */
429 settc(tc);
430 write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_MVP);
431 if (vpe != 0)
432 printk(", ");
433 printk("VPE %d: TC", vpe);
434 for (i = 0; i < tcpervpe; i++) {
435 /*
436 * TC 0 is bound to VPE 0 at reset,
437 * and is presumably executing this
438 * code. Leave it alone!
439 */
440 if (tc != 0) {
441 smtc_tc_setup(vpe,tc, cpu);
442 cpu++;
443 }
444 printk(" %d", tc);
445 tc++;
446 }
447 if (slop) {
448 if (tc != 0) {
449 smtc_tc_setup(vpe,tc, cpu);
450 cpu++;
451 }
452 printk(" %d", tc);
453 tc++;
454 slop--;
455 }
456 if (vpe != 0) {
457 /*
458 * Clear any stale software interrupts from VPE's Cause
459 */
460 write_vpe_c0_cause(0);
461
462 /*
463 * Clear ERL/EXL of VPEs other than 0
464 * and set restricted interrupt enable/mask.
465 */
466 write_vpe_c0_status((read_vpe_c0_status()
467 & ~(ST0_BEV | ST0_ERL | ST0_EXL | ST0_IM))
468 | (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP7
469 | ST0_IE));
470 /*
471 * set config to be the same as vpe0,
472 * particularly kseg0 coherency alg
473 */
474 write_vpe_c0_config(read_c0_config());
475 /* Clear any pending timer interrupt */
476 write_vpe_c0_compare(0);
477 /* Propagate Config7 */
478 write_vpe_c0_config7(read_c0_config7());
479 }
480 /* enable multi-threading within VPE */
481 write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() | VPECONTROL_TE);
482 /* enable the VPE */
483 write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);
484 }
485
486 /*
487 * Pull any physically present but unused TCs out of circulation.
488 */
489 while (tc < (((val & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1)) {
490 cpu_clear(tc, phys_cpu_present_map);
491 cpu_clear(tc, cpu_present_map);
492 tc++;
493 }
494
495 /* release config state */
496 write_c0_mvpcontrol( read_c0_mvpcontrol() & ~ MVPCONTROL_VPC );
497
498 printk("\n");
499
500 /* Set up coprocessor affinity CPU mask(s) */
501
502 for (tc = 0; tc < ntc; tc++) {
503 if(cpu_data[tc].options & MIPS_CPU_FPU)
504 cpu_set(tc, mt_fpu_cpumask);
505 }
506
507 /* set up ipi interrupts... */
508
509 /* If we have multiple VPEs running, set up the cross-VPE interrupt */
510
511 if (nvpe > 1)
512 setup_cross_vpe_interrupts();
513
514 /* Set up queue of free IPI "messages". */
515 nipi = NR_CPUS * IPIBUF_PER_CPU;
516 if (ipibuffers > 0)
517 nipi = ipibuffers;
518
519 pipi = kmalloc(nipi *sizeof(struct smtc_ipi), GFP_KERNEL);
520 if (pipi == NULL)
521 panic("kmalloc of IPI message buffers failed\n");
522 else
523 printk("IPI buffer pool of %d buffers\n", nipi);
524 for (i = 0; i < nipi; i++) {
525 smtc_ipi_nq(&freeIPIq, pipi);
526 pipi++;
527 }
528
529 /* Arm multithreading and enable other VPEs - but all TCs are Halted */
530 emt(EMT_ENABLE);
531 evpe(EVPE_ENABLE);
532 local_irq_restore(flags);
533 /* Initialize SMTC /proc statistics/diagnostics */
534 init_smtc_stats();
535}
536
537
538/*
539 * Setup the PC, SP, and GP of a secondary processor and start it
540 * running!
541 * smp_bootstrap is the place to resume from
542 * __KSTK_TOS(idle) is apparently the stack pointer
543 * (unsigned long)idle->thread_info the gp
544 *
545 */
546void smtc_boot_secondary(int cpu, struct task_struct *idle)
547{
548 extern u32 kernelsp[NR_CPUS];
549 long flags;
550 int mtflags;
551
552 LOCK_MT_PRA();
553 if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) {
554 dvpe();
555 }
556 settc(cpu_data[cpu].tc_id);
557
558 /* pc */
559 write_tc_c0_tcrestart((unsigned long)&smp_bootstrap);
560
561 /* stack pointer */
562 kernelsp[cpu] = __KSTK_TOS(idle);
563 write_tc_gpr_sp(__KSTK_TOS(idle));
564
565 /* global pointer */
566 write_tc_gpr_gp((unsigned long)idle->thread_info);
567
568 smtc_status |= SMTC_MTC_ACTIVE;
569 write_tc_c0_tchalt(0);
570 if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) {
571 evpe(EVPE_ENABLE);
572 }
573 UNLOCK_MT_PRA();
574}
575
576void smtc_init_secondary(void)
577{
578 /*
579 * Start timer on secondary VPEs if necessary.
580 * mips_timer_setup should already have been invoked by init/main
581 * on "boot" TC. Like per_cpu_trap_init() hack, this assumes that
582 * SMTC init code assigns TCs consdecutively and in ascending order
583 * to across available VPEs.
584 */
585 if(((read_c0_tcbind() & TCBIND_CURTC) != 0)
586 && ((read_c0_tcbind() & TCBIND_CURVPE)
587 != cpu_data[smp_processor_id() - 1].vpe_id)){
588 write_c0_compare (read_c0_count() + mips_hpt_frequency/HZ);
589 }
590
591 local_irq_enable();
592}
593
594void smtc_smp_finish(void)
595{
596 printk("TC %d going on-line as CPU %d\n",
597 cpu_data[smp_processor_id()].tc_id, smp_processor_id());
598}
599
600void smtc_cpus_done(void)
601{
602}
603
604/*
605 * Support for SMTC-optimized driver IRQ registration
606 */
607
608/*
609 * SMTC Kernel needs to manipulate low-level CPU interrupt mask
610 * in do_IRQ. These are passed in setup_irq_smtc() and stored
611 * in this table.
612 */
613
614int setup_irq_smtc(unsigned int irq, struct irqaction * new,
615 unsigned long hwmask)
616{
617 irq_hwmask[irq] = hwmask;
618
619 return setup_irq(irq, new);
620}
621
622/*
623 * IPI model for SMTC is tricky, because interrupts aren't TC-specific.
624 * Within a VPE one TC can interrupt another by different approaches.
625 * The easiest to get right would probably be to make all TCs except
626 * the target IXMT and set a software interrupt, but an IXMT-based
627 * scheme requires that a handler must run before a new IPI could
628 * be sent, which would break the "broadcast" loops in MIPS MT.
629 * A more gonzo approach within a VPE is to halt the TC, extract
630 * its Restart, Status, and a couple of GPRs, and program the Restart
631 * address to emulate an interrupt.
632 *
633 * Within a VPE, one can be confident that the target TC isn't in
634 * a critical EXL state when halted, since the write to the Halt
635 * register could not have issued on the writing thread if the
636 * halting thread had EXL set. So k0 and k1 of the target TC
637 * can be used by the injection code. Across VPEs, one can't
638 * be certain that the target TC isn't in a critical exception
639 * state. So we try a two-step process of sending a software
640 * interrupt to the target VPE, which either handles the event
641 * itself (if it was the target) or injects the event within
642 * the VPE.
643 */
644
645void smtc_ipi_qdump(void)
646{
647 int i;
648
649 for (i = 0; i < NR_CPUS ;i++) {
650 printk("IPIQ[%d]: head = 0x%x, tail = 0x%x, depth = %d\n",
651 i, (unsigned)IPIQ[i].head, (unsigned)IPIQ[i].tail,
652 IPIQ[i].depth);
653 }
654}
655
656/*
657 * The standard atomic.h primitives don't quite do what we want
658 * here: We need an atomic add-and-return-previous-value (which
659 * could be done with atomic_add_return and a decrement) and an
660 * atomic set/zero-and-return-previous-value (which can't really
661 * be done with the atomic.h primitives). And since this is
662 * MIPS MT, we can assume that we have LL/SC.
663 */
664static __inline__ int atomic_postincrement(unsigned int *pv)
665{
666 unsigned long result;
667
668 unsigned long temp;
669
670 __asm__ __volatile__(
671 "1: ll %0, %2 \n"
672 " addu %1, %0, 1 \n"
673 " sc %1, %2 \n"
674 " beqz %1, 1b \n"
675 " sync \n"
676 : "=&r" (result), "=&r" (temp), "=m" (*pv)
677 : "m" (*pv)
678 : "memory");
679
680 return result;
681}
682
683/* No longer used in IPI dispatch, but retained for future recycling */
684
685static __inline__ int atomic_postclear(unsigned int *pv)
686{
687 unsigned long result;
688
689 unsigned long temp;
690
691 __asm__ __volatile__(
692 "1: ll %0, %2 \n"
693 " or %1, $0, $0 \n"
694 " sc %1, %2 \n"
695 " beqz %1, 1b \n"
696 " sync \n"
697 : "=&r" (result), "=&r" (temp), "=m" (*pv)
698 : "m" (*pv)
699 : "memory");
700
701 return result;
702}
703
704
705void smtc_send_ipi(int cpu, int type, unsigned int action)
706{
707 int tcstatus;
708 struct smtc_ipi *pipi;
709 long flags;
710 int mtflags;
711
712 if (cpu == smp_processor_id()) {
713 printk("Cannot Send IPI to self!\n");
714 return;
715 }
716 /* Set up a descriptor, to be delivered either promptly or queued */
717 pipi = smtc_ipi_dq(&freeIPIq);
718 if (pipi == NULL) {
719 bust_spinlocks(1);
720 mips_mt_regdump(dvpe());
721 panic("IPI Msg. Buffers Depleted\n");
722 }
723 pipi->type = type;
724 pipi->arg = (void *)action;
725 pipi->dest = cpu;
726 if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) {
727 /* If not on same VPE, enqueue and send cross-VPE interupt */
728 smtc_ipi_nq(&IPIQ[cpu], pipi);
729 LOCK_CORE_PRA();
730 settc(cpu_data[cpu].tc_id);
731 write_vpe_c0_cause(read_vpe_c0_cause() | C_SW1);
732 UNLOCK_CORE_PRA();
733 } else {
734 /*
735 * Not sufficient to do a LOCK_MT_PRA (dmt) here,
736 * since ASID shootdown on the other VPE may
737 * collide with this operation.
738 */
739 LOCK_CORE_PRA();
740 settc(cpu_data[cpu].tc_id);
741 /* Halt the targeted TC */
742 write_tc_c0_tchalt(TCHALT_H);
743 mips_ihb();
744
745 /*
746 * Inspect TCStatus - if IXMT is set, we have to queue
747 * a message. Otherwise, we set up the "interrupt"
748 * of the other TC
749 */
750 tcstatus = read_tc_c0_tcstatus();
751
752 if ((tcstatus & TCSTATUS_IXMT) != 0) {
753 /*
754 * Spin-waiting here can deadlock,
755 * so we queue the message for the target TC.
756 */
757 write_tc_c0_tchalt(0);
758 UNLOCK_CORE_PRA();
759 /* Try to reduce redundant timer interrupt messages */
760 if(type == SMTC_CLOCK_TICK) {
761 if(atomic_postincrement(&ipi_timer_latch[cpu])!=0) {
762 smtc_ipi_nq(&freeIPIq, pipi);
763 return;
764 }
765 }
766 smtc_ipi_nq(&IPIQ[cpu], pipi);
767 } else {
768 post_direct_ipi(cpu, pipi);
769 write_tc_c0_tchalt(0);
770 UNLOCK_CORE_PRA();
771 }
772 }
773}
774
775/*
776 * Send IPI message to Halted TC, TargTC/TargVPE already having been set
777 */
778void post_direct_ipi(int cpu, struct smtc_ipi *pipi)
779{
780 struct pt_regs *kstack;
781 unsigned long tcstatus;
782 unsigned long tcrestart;
783 extern u32 kernelsp[NR_CPUS];
784 extern void __smtc_ipi_vector(void);
785
786 /* Extract Status, EPC from halted TC */
787 tcstatus = read_tc_c0_tcstatus();
788 tcrestart = read_tc_c0_tcrestart();
789 /* If TCRestart indicates a WAIT instruction, advance the PC */
790 if ((tcrestart & 0x80000000)
791 && ((*(unsigned int *)tcrestart & 0xfe00003f) == 0x42000020)) {
792 tcrestart += 4;
793 }
794 /*
795 * Save on TC's future kernel stack
796 *
797 * CU bit of Status is indicator that TC was
798 * already running on a kernel stack...
799 */
800 if(tcstatus & ST0_CU0) {
801 /* Note that this "- 1" is pointer arithmetic */
802 kstack = ((struct pt_regs *)read_tc_gpr_sp()) - 1;
803 } else {
804 kstack = ((struct pt_regs *)kernelsp[cpu]) - 1;
805 }
806
807 kstack->cp0_epc = (long)tcrestart;
808 /* Save TCStatus */
809 kstack->cp0_tcstatus = tcstatus;
810 /* Pass token of operation to be performed kernel stack pad area */
811 kstack->pad0[4] = (unsigned long)pipi;
812 /* Pass address of function to be called likewise */
813 kstack->pad0[5] = (unsigned long)&ipi_decode;
814 /* Set interrupt exempt and kernel mode */
815 tcstatus |= TCSTATUS_IXMT;
816 tcstatus &= ~TCSTATUS_TKSU;
817 write_tc_c0_tcstatus(tcstatus);
818 ehb();
819 /* Set TC Restart address to be SMTC IPI vector */
820 write_tc_c0_tcrestart(__smtc_ipi_vector);
821}
822
823void ipi_resched_interrupt(struct pt_regs *regs)
824{
825 /* Return from interrupt should be enough to cause scheduler check */
826}
827
828
829void ipi_call_interrupt(struct pt_regs *regs)
830{
831 /* Invoke generic function invocation code in smp.c */
832 smp_call_function_interrupt();
833}
834
835void ipi_decode(struct pt_regs *regs, struct smtc_ipi *pipi)
836{
837 void *arg_copy = pipi->arg;
838 int type_copy = pipi->type;
839 int dest_copy = pipi->dest;
840
841 smtc_ipi_nq(&freeIPIq, pipi);
842 switch (type_copy) {
843 case SMTC_CLOCK_TICK:
844 /* Invoke Clock "Interrupt" */
845 ipi_timer_latch[dest_copy] = 0;
846#ifdef SMTC_IDLE_HOOK_DEBUG
847 clock_hang_reported[dest_copy] = 0;
848#endif /* SMTC_IDLE_HOOK_DEBUG */
849 local_timer_interrupt(0, NULL, regs);
850 break;
851 case LINUX_SMP_IPI:
852 switch ((int)arg_copy) {
853 case SMP_RESCHEDULE_YOURSELF:
854 ipi_resched_interrupt(regs);
855 break;
856 case SMP_CALL_FUNCTION:
857 ipi_call_interrupt(regs);
858 break;
859 default:
860 printk("Impossible SMTC IPI Argument 0x%x\n",
861 (int)arg_copy);
862 break;
863 }
864 break;
865 default:
866 printk("Impossible SMTC IPI Type 0x%x\n", type_copy);
867 break;
868 }
869}
870
871void deferred_smtc_ipi(struct pt_regs *regs)
872{
873 struct smtc_ipi *pipi;
874 unsigned long flags;
875/* DEBUG */
876 int q = smp_processor_id();
877
878 /*
879 * Test is not atomic, but much faster than a dequeue,
880 * and the vast majority of invocations will have a null queue.
881 */
882 if(IPIQ[q].head != NULL) {
883 while((pipi = smtc_ipi_dq(&IPIQ[q])) != NULL) {
884 /* ipi_decode() should be called with interrupts off */
885 local_irq_save(flags);
886 ipi_decode(regs, pipi);
887 local_irq_restore(flags);
888 }
889 }
890}
891
892/*
893 * Send clock tick to all TCs except the one executing the funtion
894 */
895
896void smtc_timer_broadcast(int vpe)
897{
898 int cpu;
899 int myTC = cpu_data[smp_processor_id()].tc_id;
900 int myVPE = cpu_data[smp_processor_id()].vpe_id;
901
902 smtc_cpu_stats[smp_processor_id()].timerints++;
903
904 for_each_online_cpu(cpu) {
905 if (cpu_data[cpu].vpe_id == myVPE &&
906 cpu_data[cpu].tc_id != myTC)
907 smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0);
908 }
909}
910
911/*
912 * Cross-VPE interrupts in the SMTC prototype use "software interrupts"
913 * set via cross-VPE MTTR manipulation of the Cause register. It would be
914 * in some regards preferable to have external logic for "doorbell" hardware
915 * interrupts.
916 */
917
918static int cpu_ipi_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_IRQ;
919
920static irqreturn_t ipi_interrupt(int irq, void *dev_idm, struct pt_regs *regs)
921{
922 int my_vpe = cpu_data[smp_processor_id()].vpe_id;
923 int my_tc = cpu_data[smp_processor_id()].tc_id;
924 int cpu;
925 struct smtc_ipi *pipi;
926 unsigned long tcstatus;
927 int sent;
928 long flags;
929 unsigned int mtflags;
930 unsigned int vpflags;
931
932 /*
933 * So long as cross-VPE interrupts are done via
934 * MFTR/MTTR read-modify-writes of Cause, we need
935 * to stop other VPEs whenever the local VPE does
936 * anything similar.
937 */
938 local_irq_save(flags);
939 vpflags = dvpe();
940 clear_c0_cause(0x100 << MIPS_CPU_IPI_IRQ);
941 set_c0_status(0x100 << MIPS_CPU_IPI_IRQ);
942 irq_enable_hazard();
943 evpe(vpflags);
944 local_irq_restore(flags);
945
946 /*
947 * Cross-VPE Interrupt handler: Try to directly deliver IPIs
948 * queued for TCs on this VPE other than the current one.
949 * Return-from-interrupt should cause us to drain the queue
950 * for the current TC, so we ought not to have to do it explicitly here.
951 */
952
953 for_each_online_cpu(cpu) {
954 if (cpu_data[cpu].vpe_id != my_vpe)
955 continue;
956
957 pipi = smtc_ipi_dq(&IPIQ[cpu]);
958 if (pipi != NULL) {
959 if (cpu_data[cpu].tc_id != my_tc) {
960 sent = 0;
961 LOCK_MT_PRA();
962 settc(cpu_data[cpu].tc_id);
963 write_tc_c0_tchalt(TCHALT_H);
964 mips_ihb();
965 tcstatus = read_tc_c0_tcstatus();
966 if ((tcstatus & TCSTATUS_IXMT) == 0) {
967 post_direct_ipi(cpu, pipi);
968 sent = 1;
969 }
970 write_tc_c0_tchalt(0);
971 UNLOCK_MT_PRA();
972 if (!sent) {
973 smtc_ipi_req(&IPIQ[cpu], pipi);
974 }
975 } else {
976 /*
977 * ipi_decode() should be called
978 * with interrupts off
979 */
980 local_irq_save(flags);
981 ipi_decode(regs, pipi);
982 local_irq_restore(flags);
983 }
984 }
985 }
986
987 return IRQ_HANDLED;
988}
989
990static void ipi_irq_dispatch(struct pt_regs *regs)
991{
992 do_IRQ(cpu_ipi_irq, regs);
993}
994
995static struct irqaction irq_ipi;
996
997void setup_cross_vpe_interrupts(void)
998{
999 if (!cpu_has_vint)
1000 panic("SMTC Kernel requires Vectored Interupt support");
1001
1002 set_vi_handler(MIPS_CPU_IPI_IRQ, ipi_irq_dispatch);
1003
1004 irq_ipi.handler = ipi_interrupt;
1005 irq_ipi.flags = SA_INTERRUPT;
1006 irq_ipi.name = "SMTC_IPI";
1007
1008 setup_irq_smtc(cpu_ipi_irq, &irq_ipi, (0x100 << MIPS_CPU_IPI_IRQ));
1009
1010 irq_desc[cpu_ipi_irq].status |= IRQ_PER_CPU;
1011}
1012
1013/*
1014 * SMTC-specific hacks invoked from elsewhere in the kernel.
1015 */
1016
1017void smtc_idle_loop_hook(void)
1018{
1019#ifdef SMTC_IDLE_HOOK_DEBUG
1020 int im;
1021 int flags;
1022 int mtflags;
1023 int bit;
1024 int vpe;
1025 int tc;
1026 int hook_ntcs;
1027 /*
1028 * printk within DMT-protected regions can deadlock,
1029 * so buffer diagnostic messages for later output.
1030 */
1031 char *pdb_msg;
1032 char id_ho_db_msg[768]; /* worst-case use should be less than 700 */
1033
1034 if (atomic_read(&idle_hook_initialized) == 0) { /* fast test */
1035 if (atomic_add_return(1, &idle_hook_initialized) == 1) {
1036 int mvpconf0;
1037 /* Tedious stuff to just do once */
1038 mvpconf0 = read_c0_mvpconf0();
1039 hook_ntcs = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1;
1040 if (hook_ntcs > NR_CPUS)
1041 hook_ntcs = NR_CPUS;
1042 for (tc = 0; tc < hook_ntcs; tc++) {
1043 tcnoprog[tc] = 0;
1044 clock_hang_reported[tc] = 0;
1045 }
1046 for (vpe = 0; vpe < 2; vpe++)
1047 for (im = 0; im < 8; im++)
1048 imstuckcount[vpe][im] = 0;
1049 printk("Idle loop test hook initialized for %d TCs\n", hook_ntcs);
1050 atomic_set(&idle_hook_initialized, 1000);
1051 } else {
1052 /* Someone else is initializing in parallel - let 'em finish */
1053 while (atomic_read(&idle_hook_initialized) < 1000)
1054 ;
1055 }
1056 }
1057
1058 /* Have we stupidly left IXMT set somewhere? */
1059 if (read_c0_tcstatus() & 0x400) {
1060 write_c0_tcstatus(read_c0_tcstatus() & ~0x400);
1061 ehb();
1062 printk("Dangling IXMT in cpu_idle()\n");
1063 }
1064
1065 /* Have we stupidly left an IM bit turned off? */
1066#define IM_LIMIT 2000
1067 local_irq_save(flags);
1068 mtflags = dmt();
1069 pdb_msg = &id_ho_db_msg[0];
1070 im = read_c0_status();
1071 vpe = cpu_data[smp_processor_id()].vpe_id;
1072 for (bit = 0; bit < 8; bit++) {
1073 /*
1074 * In current prototype, I/O interrupts
1075 * are masked for VPE > 0
1076 */
1077 if (vpemask[vpe][bit]) {
1078 if (!(im & (0x100 << bit)))
1079 imstuckcount[vpe][bit]++;
1080 else
1081 imstuckcount[vpe][bit] = 0;
1082 if (imstuckcount[vpe][bit] > IM_LIMIT) {
1083 set_c0_status(0x100 << bit);
1084 ehb();
1085 imstuckcount[vpe][bit] = 0;
1086 pdb_msg += sprintf(pdb_msg,
1087 "Dangling IM %d fixed for VPE %d\n", bit,
1088 vpe);
1089 }
1090 }
1091 }
1092
1093 /*
1094 * Now that we limit outstanding timer IPIs, check for hung TC
1095 */
1096 for (tc = 0; tc < NR_CPUS; tc++) {
1097 /* Don't check ourself - we'll dequeue IPIs just below */
1098 if ((tc != smp_processor_id()) &&
1099 ipi_timer_latch[tc] > timerq_limit) {
1100 if (clock_hang_reported[tc] == 0) {
1101 pdb_msg += sprintf(pdb_msg,
1102 "TC %d looks hung with timer latch at %d\n",
1103 tc, ipi_timer_latch[tc]);
1104 clock_hang_reported[tc]++;
1105 }
1106 }
1107 }
1108 emt(mtflags);
1109 local_irq_restore(flags);
1110 if (pdb_msg != &id_ho_db_msg[0])
1111 printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg);
1112#endif /* SMTC_IDLE_HOOK_DEBUG */
1113 /*
1114 * To the extent that we've ever turned interrupts off,
1115 * we may have accumulated deferred IPIs. This is subtle.
1116 * If we use the smtc_ipi_qdepth() macro, we'll get an
1117 * exact number - but we'll also disable interrupts
1118 * and create a window of failure where a new IPI gets
1119 * queued after we test the depth but before we re-enable
1120 * interrupts. So long as IXMT never gets set, however,
1121 * we should be OK: If we pick up something and dispatch
1122 * it here, that's great. If we see nothing, but concurrent
1123 * with this operation, another TC sends us an IPI, IXMT
1124 * is clear, and we'll handle it as a real pseudo-interrupt
1125 * and not a pseudo-pseudo interrupt.
1126 */
1127 if (IPIQ[smp_processor_id()].depth > 0) {
1128 struct smtc_ipi *pipi;
1129 extern void self_ipi(struct smtc_ipi *);
1130
1131 if ((pipi = smtc_ipi_dq(&IPIQ[smp_processor_id()])) != NULL) {
1132 self_ipi(pipi);
1133 smtc_cpu_stats[smp_processor_id()].selfipis++;
1134 }
1135 }
1136}
1137
1138void smtc_soft_dump(void)
1139{
1140 int i;
1141
1142 printk("Counter Interrupts taken per CPU (TC)\n");
1143 for (i=0; i < NR_CPUS; i++) {
1144 printk("%d: %ld\n", i, smtc_cpu_stats[i].timerints);
1145 }
1146 printk("Self-IPI invocations:\n");
1147 for (i=0; i < NR_CPUS; i++) {
1148 printk("%d: %ld\n", i, smtc_cpu_stats[i].selfipis);
1149 }
1150 smtc_ipi_qdump();
1151 printk("Timer IPI Backlogs:\n");
1152 for (i=0; i < NR_CPUS; i++) {
1153 printk("%d: %d\n", i, ipi_timer_latch[i]);
1154 }
1155 printk("%d Recoveries of \"stolen\" FPU\n",
1156 atomic_read(&smtc_fpu_recoveries));
1157}
1158
1159
1160/*
1161 * TLB management routines special to SMTC
1162 */
1163
1164void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
1165{
1166 unsigned long flags, mtflags, tcstat, prevhalt, asid;
1167 int tlb, i;
1168
1169 /*
1170 * It would be nice to be able to use a spinlock here,
1171 * but this is invoked from within TLB flush routines
1172 * that protect themselves with DVPE, so if a lock is
1173 * held by another TC, it'll never be freed.
1174 *
1175 * DVPE/DMT must not be done with interrupts enabled,
1176 * so even so most callers will already have disabled
1177 * them, let's be really careful...
1178 */
1179
1180 local_irq_save(flags);
1181 if (smtc_status & SMTC_TLB_SHARED) {
1182 mtflags = dvpe();
1183 tlb = 0;
1184 } else {
1185 mtflags = dmt();
1186 tlb = cpu_data[cpu].vpe_id;
1187 }
1188 asid = asid_cache(cpu);
1189
1190 do {
1191 if (!((asid += ASID_INC) & ASID_MASK) ) {
1192 if (cpu_has_vtag_icache)
1193 flush_icache_all();
1194 /* Traverse all online CPUs (hack requires contigous range) */
1195 for (i = 0; i < num_online_cpus(); i++) {
1196 /*
1197 * We don't need to worry about our own CPU, nor those of
1198 * CPUs who don't share our TLB.
1199 */
1200 if ((i != smp_processor_id()) &&
1201 ((smtc_status & SMTC_TLB_SHARED) ||
1202 (cpu_data[i].vpe_id == cpu_data[cpu].vpe_id))) {
1203 settc(cpu_data[i].tc_id);
1204 prevhalt = read_tc_c0_tchalt() & TCHALT_H;
1205 if (!prevhalt) {
1206 write_tc_c0_tchalt(TCHALT_H);
1207 mips_ihb();
1208 }
1209 tcstat = read_tc_c0_tcstatus();
1210 smtc_live_asid[tlb][(tcstat & ASID_MASK)] |= (asiduse)(0x1 << i);
1211 if (!prevhalt)
1212 write_tc_c0_tchalt(0);
1213 }
1214 }
1215 if (!asid) /* fix version if needed */
1216 asid = ASID_FIRST_VERSION;
1217 local_flush_tlb_all(); /* start new asid cycle */
1218 }
1219 } while (smtc_live_asid[tlb][(asid & ASID_MASK)]);
1220
1221 /*
1222 * SMTC shares the TLB within VPEs and possibly across all VPEs.
1223 */
1224 for (i = 0; i < num_online_cpus(); i++) {
1225 if ((smtc_status & SMTC_TLB_SHARED) ||
1226 (cpu_data[i].vpe_id == cpu_data[cpu].vpe_id))
1227 cpu_context(i, mm) = asid_cache(i) = asid;
1228 }
1229
1230 if (smtc_status & SMTC_TLB_SHARED)
1231 evpe(mtflags);
1232 else
1233 emt(mtflags);
1234 local_irq_restore(flags);
1235}
1236
1237/*
1238 * Invoked from macros defined in mmu_context.h
1239 * which must already have disabled interrupts
1240 * and done a DVPE or DMT as appropriate.
1241 */
1242
1243void smtc_flush_tlb_asid(unsigned long asid)
1244{
1245 int entry;
1246 unsigned long ehi;
1247
1248 entry = read_c0_wired();
1249
1250 /* Traverse all non-wired entries */
1251 while (entry < current_cpu_data.tlbsize) {
1252 write_c0_index(entry);
1253 ehb();
1254 tlb_read();
1255 ehb();
1256 ehi = read_c0_entryhi();
1257 if((ehi & ASID_MASK) == asid) {
1258 /*
1259 * Invalidate only entries with specified ASID,
1260 * makiing sure all entries differ.
1261 */
1262 write_c0_entryhi(CKSEG0 + (entry << (PAGE_SHIFT + 1)));
1263 write_c0_entrylo0(0);
1264 write_c0_entrylo1(0);
1265 mtc0_tlbw_hazard();
1266 tlb_write_indexed();
1267 }
1268 entry++;
1269 }
1270 write_c0_index(PARKED_INDEX);
1271 tlbw_use_hazard();
1272}
1273
1274/*
1275 * Support for single-threading cache flush operations.
1276 */
1277
1278int halt_state_save[NR_CPUS];
1279
1280/*
1281 * To really, really be sure that nothing is being done
1282 * by other TCs, halt them all. This code assumes that
1283 * a DVPE has already been done, so while their Halted
1284 * state is theoretically architecturally unstable, in
1285 * practice, it's not going to change while we're looking
1286 * at it.
1287 */
1288
1289void smtc_cflush_lockdown(void)
1290{
1291 int cpu;
1292
1293 for_each_online_cpu(cpu) {
1294 if (cpu != smp_processor_id()) {
1295 settc(cpu_data[cpu].tc_id);
1296 halt_state_save[cpu] = read_tc_c0_tchalt();
1297 write_tc_c0_tchalt(TCHALT_H);
1298 }
1299 }
1300 mips_ihb();
1301}
1302
1303/* It would be cheating to change the cpu_online states during a flush! */
1304
1305void smtc_cflush_release(void)
1306{
1307 int cpu;
1308
1309 /*
1310 * Start with a hazard barrier to ensure
1311 * that all CACHE ops have played through.
1312 */
1313 mips_ihb();
1314
1315 for_each_online_cpu(cpu) {
1316 if (cpu != smp_processor_id()) {
1317 settc(cpu_data[cpu].tc_id);
1318 write_tc_c0_tchalt(halt_state_save[cpu]);
1319 }
1320 }
1321 mips_ihb();
1322}
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 5e51a2d8f3f0..13ff4da598cd 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -116,8 +116,7 @@ static void c0_timer_ack(void)
116 write_c0_compare(expirelo); 116 write_c0_compare(expirelo);
117 117
118 /* Check to see if we have missed any timer interrupts. */ 118 /* Check to see if we have missed any timer interrupts. */
119 count = read_c0_count(); 119 while (((count = read_c0_count()) - expirelo) < 0x7fffffff) {
120 if ((count - expirelo) < 0x7fffffff) {
121 /* missed_timer_count++; */ 120 /* missed_timer_count++; */
122 expirelo = count + cycles_per_jiffy; 121 expirelo = count + cycles_per_jiffy;
123 write_c0_compare(expirelo); 122 write_c0_compare(expirelo);
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index bed0eb6cf55d..4901f0a37fca 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -42,6 +42,7 @@
42#include <asm/watch.h> 42#include <asm/watch.h>
43#include <asm/types.h> 43#include <asm/types.h>
44 44
45extern asmlinkage void handle_int(void);
45extern asmlinkage void handle_tlbm(void); 46extern asmlinkage void handle_tlbm(void);
46extern asmlinkage void handle_tlbl(void); 47extern asmlinkage void handle_tlbl(void);
47extern asmlinkage void handle_tlbs(void); 48extern asmlinkage void handle_tlbs(void);
@@ -279,9 +280,16 @@ static DEFINE_SPINLOCK(die_lock);
279NORET_TYPE void ATTRIB_NORET die(const char * str, struct pt_regs * regs) 280NORET_TYPE void ATTRIB_NORET die(const char * str, struct pt_regs * regs)
280{ 281{
281 static int die_counter; 282 static int die_counter;
283#ifdef CONFIG_MIPS_MT_SMTC
284 unsigned long dvpret = dvpe();
285#endif /* CONFIG_MIPS_MT_SMTC */
282 286
283 console_verbose(); 287 console_verbose();
284 spin_lock_irq(&die_lock); 288 spin_lock_irq(&die_lock);
289 bust_spinlocks(1);
290#ifdef CONFIG_MIPS_MT_SMTC
291 mips_mt_regdump(dvpret);
292#endif /* CONFIG_MIPS_MT_SMTC */
285 printk("%s[#%d]:\n", str, ++die_counter); 293 printk("%s[#%d]:\n", str, ++die_counter);
286 show_registers(regs); 294 show_registers(regs);
287 spin_unlock_irq(&die_lock); 295 spin_unlock_irq(&die_lock);
@@ -750,12 +758,43 @@ asmlinkage void do_cpu(struct pt_regs *regs)
750 &current->thread.fpu.soft); 758 &current->thread.fpu.soft);
751 if (sig) 759 if (sig)
752 force_sig(sig, current); 760 force_sig(sig, current);
761#ifdef CONFIG_MIPS_MT_FPAFF
762 else {
763 /*
764 * MIPS MT processors may have fewer FPU contexts
765 * than CPU threads. If we've emulated more than
766 * some threshold number of instructions, force
767 * migration to a "CPU" that has FP support.
768 */
769 if(mt_fpemul_threshold > 0
770 && ((current->thread.emulated_fp++
771 > mt_fpemul_threshold))) {
772 /*
773 * If there's no FPU present, or if the
774 * application has already restricted
775 * the allowed set to exclude any CPUs
776 * with FPUs, we'll skip the procedure.
777 */
778 if (cpus_intersects(current->cpus_allowed,
779 mt_fpu_cpumask)) {
780 cpumask_t tmask;
781
782 cpus_and(tmask,
783 current->thread.user_cpus_allowed,
784 mt_fpu_cpumask);
785 set_cpus_allowed(current, tmask);
786 current->thread.mflags |= MF_FPUBOUND;
787 }
788 }
789 }
790#endif /* CONFIG_MIPS_MT_FPAFF */
753 } 791 }
754 792
755 return; 793 return;
756 794
757 case 2: 795 case 2:
758 case 3: 796 case 3:
797 die_if_kernel("do_cpu invoked from kernel context!", regs);
759 break; 798 break;
760 } 799 }
761 800
@@ -793,6 +832,36 @@ asmlinkage void do_mcheck(struct pt_regs *regs)
793 832
794asmlinkage void do_mt(struct pt_regs *regs) 833asmlinkage void do_mt(struct pt_regs *regs)
795{ 834{
835 int subcode;
836
837 die_if_kernel("MIPS MT Thread exception in kernel", regs);
838
839 subcode = (read_vpe_c0_vpecontrol() & VPECONTROL_EXCPT)
840 >> VPECONTROL_EXCPT_SHIFT;
841 switch (subcode) {
842 case 0:
843 printk(KERN_ERR "Thread Underflow\n");
844 break;
845 case 1:
846 printk(KERN_ERR "Thread Overflow\n");
847 break;
848 case 2:
849 printk(KERN_ERR "Invalid YIELD Qualifier\n");
850 break;
851 case 3:
852 printk(KERN_ERR "Gating Storage Exception\n");
853 break;
854 case 4:
855 printk(KERN_ERR "YIELD Scheduler Exception\n");
856 break;
857 case 5:
858 printk(KERN_ERR "Gating Storage Schedulier Exception\n");
859 break;
860 default:
861 printk(KERN_ERR "*** UNKNOWN THREAD EXCEPTION %d ***\n",
862 subcode);
863 break;
864 }
796 die_if_kernel("MIPS MT Thread exception in kernel", regs); 865 die_if_kernel("MIPS MT Thread exception in kernel", regs);
797 866
798 force_sig(SIGILL, current); 867 force_sig(SIGILL, current);
@@ -928,7 +997,15 @@ void ejtag_exception_handler(struct pt_regs *regs)
928 */ 997 */
929void nmi_exception_handler(struct pt_regs *regs) 998void nmi_exception_handler(struct pt_regs *regs)
930{ 999{
1000#ifdef CONFIG_MIPS_MT_SMTC
1001 unsigned long dvpret = dvpe();
1002 bust_spinlocks(1);
1003 printk("NMI taken!!!!\n");
1004 mips_mt_regdump(dvpret);
1005#else
1006 bust_spinlocks(1);
931 printk("NMI taken!!!!\n"); 1007 printk("NMI taken!!!!\n");
1008#endif /* CONFIG_MIPS_MT_SMTC */
932 die("NMI", regs); 1009 die("NMI", regs);
933 while(1) ; 1010 while(1) ;
934} 1011}
@@ -960,27 +1037,29 @@ void *set_except_vector(int n, void *addr)
960 1037
961#ifdef CONFIG_CPU_MIPSR2 1038#ifdef CONFIG_CPU_MIPSR2
962/* 1039/*
963 * Shadow register allocation 1040 * MIPSR2 shadow register set allocation
964 * FIXME: SMP... 1041 * FIXME: SMP...
965 */ 1042 */
966 1043
967/* MIPSR2 shadow register sets */ 1044static struct shadow_registers {
968struct shadow_registers { 1045 /*
969 spinlock_t sr_lock; /* */ 1046 * Number of shadow register sets supported
970 int sr_supported; /* Number of shadow register sets supported */ 1047 */
971 int sr_allocated; /* Bitmap of allocated shadow registers */ 1048 unsigned long sr_supported;
1049 /*
1050 * Bitmap of allocated shadow registers
1051 */
1052 unsigned long sr_allocated;
972} shadow_registers; 1053} shadow_registers;
973 1054
974void mips_srs_init(void) 1055static void mips_srs_init(void)
975{ 1056{
976#ifdef CONFIG_CPU_MIPSR2_SRS 1057#ifdef CONFIG_CPU_MIPSR2_SRS
977 shadow_registers.sr_supported = ((read_c0_srsctl() >> 26) & 0x0f) + 1; 1058 shadow_registers.sr_supported = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
978 printk ("%d MIPSR2 register sets available\n", shadow_registers.sr_supported); 1059 printk(KERN_INFO "%d MIPSR2 register sets available\n",
979#else 1060 shadow_registers.sr_supported);
980 shadow_registers.sr_supported = 1;
981#endif 1061#endif
982 shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */ 1062 shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */
983 spin_lock_init(&shadow_registers.sr_lock);
984} 1063}
985 1064
986int mips_srs_max(void) 1065int mips_srs_max(void)
@@ -988,38 +1067,30 @@ int mips_srs_max(void)
988 return shadow_registers.sr_supported; 1067 return shadow_registers.sr_supported;
989} 1068}
990 1069
991int mips_srs_alloc (void) 1070int mips_srs_alloc(void)
992{ 1071{
993 struct shadow_registers *sr = &shadow_registers; 1072 struct shadow_registers *sr = &shadow_registers;
994 unsigned long flags;
995 int set; 1073 int set;
996 1074
997 spin_lock_irqsave(&sr->sr_lock, flags); 1075again:
1076 set = find_first_zero_bit(&sr->sr_allocated, sr->sr_supported);
1077 if (set >= sr->sr_supported)
1078 return -1;
998 1079
999 for (set = 0; set < sr->sr_supported; set++) { 1080 if (test_and_set_bit(set, &sr->sr_allocated))
1000 if ((sr->sr_allocated & (1 << set)) == 0) { 1081 goto again;
1001 sr->sr_allocated |= 1 << set;
1002 spin_unlock_irqrestore(&sr->sr_lock, flags);
1003 return set;
1004 }
1005 }
1006 1082
1007 /* None available */ 1083 return set;
1008 spin_unlock_irqrestore(&sr->sr_lock, flags);
1009 return -1;
1010} 1084}
1011 1085
1012void mips_srs_free (int set) 1086void mips_srs_free(int set)
1013{ 1087{
1014 struct shadow_registers *sr = &shadow_registers; 1088 struct shadow_registers *sr = &shadow_registers;
1015 unsigned long flags;
1016 1089
1017 spin_lock_irqsave(&sr->sr_lock, flags); 1090 clear_bit(set, &sr->sr_allocated);
1018 sr->sr_allocated &= ~(1 << set);
1019 spin_unlock_irqrestore(&sr->sr_lock, flags);
1020} 1091}
1021 1092
1022void *set_vi_srs_handler (int n, void *addr, int srs) 1093static void *set_vi_srs_handler(int n, void *addr, int srs)
1023{ 1094{
1024 unsigned long handler; 1095 unsigned long handler;
1025 unsigned long old_handler = vi_handlers[n]; 1096 unsigned long old_handler = vi_handlers[n];
@@ -1032,8 +1103,7 @@ void *set_vi_srs_handler (int n, void *addr, int srs)
1032 if (addr == NULL) { 1103 if (addr == NULL) {
1033 handler = (unsigned long) do_default_vi; 1104 handler = (unsigned long) do_default_vi;
1034 srs = 0; 1105 srs = 0;
1035 } 1106 } else
1036 else
1037 handler = (unsigned long) addr; 1107 handler = (unsigned long) addr;
1038 vi_handlers[n] = (unsigned long) addr; 1108 vi_handlers[n] = (unsigned long) addr;
1039 1109
@@ -1045,8 +1115,7 @@ void *set_vi_srs_handler (int n, void *addr, int srs)
1045 if (cpu_has_veic) { 1115 if (cpu_has_veic) {
1046 if (board_bind_eic_interrupt) 1116 if (board_bind_eic_interrupt)
1047 board_bind_eic_interrupt (n, srs); 1117 board_bind_eic_interrupt (n, srs);
1048 } 1118 } else if (cpu_has_vint) {
1049 else if (cpu_has_vint) {
1050 /* SRSMap is only defined if shadow sets are implemented */ 1119 /* SRSMap is only defined if shadow sets are implemented */
1051 if (mips_srs_max() > 1) 1120 if (mips_srs_max() > 1)
1052 change_c0_srsmap (0xf << n*4, srs << n*4); 1121 change_c0_srsmap (0xf << n*4, srs << n*4);
@@ -1060,6 +1129,15 @@ void *set_vi_srs_handler (int n, void *addr, int srs)
1060 1129
1061 extern char except_vec_vi, except_vec_vi_lui; 1130 extern char except_vec_vi, except_vec_vi_lui;
1062 extern char except_vec_vi_ori, except_vec_vi_end; 1131 extern char except_vec_vi_ori, except_vec_vi_end;
1132#ifdef CONFIG_MIPS_MT_SMTC
1133 /*
1134 * We need to provide the SMTC vectored interrupt handler
1135 * not only with the address of the handler, but with the
1136 * Status.IM bit to be masked before going there.
1137 */
1138 extern char except_vec_vi_mori;
1139 const int mori_offset = &except_vec_vi_mori - &except_vec_vi;
1140#endif /* CONFIG_MIPS_MT_SMTC */
1063 const int handler_len = &except_vec_vi_end - &except_vec_vi; 1141 const int handler_len = &except_vec_vi_end - &except_vec_vi;
1064 const int lui_offset = &except_vec_vi_lui - &except_vec_vi; 1142 const int lui_offset = &except_vec_vi_lui - &except_vec_vi;
1065 const int ori_offset = &except_vec_vi_ori - &except_vec_vi; 1143 const int ori_offset = &except_vec_vi_ori - &except_vec_vi;
@@ -1073,6 +1151,12 @@ void *set_vi_srs_handler (int n, void *addr, int srs)
1073 } 1151 }
1074 1152
1075 memcpy (b, &except_vec_vi, handler_len); 1153 memcpy (b, &except_vec_vi, handler_len);
1154#ifdef CONFIG_MIPS_MT_SMTC
1155 if (n > 7)
1156 printk("Vector index %d exceeds SMTC maximum\n", n);
1157 w = (u32 *)(b + mori_offset);
1158 *w = (*w & 0xffff0000) | (0x100 << n);
1159#endif /* CONFIG_MIPS_MT_SMTC */
1076 w = (u32 *)(b + lui_offset); 1160 w = (u32 *)(b + lui_offset);
1077 *w = (*w & 0xffff0000) | (((u32)handler >> 16) & 0xffff); 1161 *w = (*w & 0xffff0000) | (((u32)handler >> 16) & 0xffff);
1078 w = (u32 *)(b + ori_offset); 1162 w = (u32 *)(b + ori_offset);
@@ -1095,9 +1179,9 @@ void *set_vi_srs_handler (int n, void *addr, int srs)
1095 return (void *)old_handler; 1179 return (void *)old_handler;
1096} 1180}
1097 1181
1098void *set_vi_handler (int n, void *addr) 1182void *set_vi_handler(int n, void *addr)
1099{ 1183{
1100 return set_vi_srs_handler (n, addr, 0); 1184 return set_vi_srs_handler(n, addr, 0);
1101} 1185}
1102#endif 1186#endif
1103 1187
@@ -1113,8 +1197,29 @@ extern asmlinkage int _restore_fp_context(struct sigcontext *sc);
1113extern asmlinkage int fpu_emulator_save_context(struct sigcontext *sc); 1197extern asmlinkage int fpu_emulator_save_context(struct sigcontext *sc);
1114extern asmlinkage int fpu_emulator_restore_context(struct sigcontext *sc); 1198extern asmlinkage int fpu_emulator_restore_context(struct sigcontext *sc);
1115 1199
1200#ifdef CONFIG_SMP
1201static int smp_save_fp_context(struct sigcontext *sc)
1202{
1203 return cpu_has_fpu
1204 ? _save_fp_context(sc)
1205 : fpu_emulator_save_context(sc);
1206}
1207
1208static int smp_restore_fp_context(struct sigcontext *sc)
1209{
1210 return cpu_has_fpu
1211 ? _restore_fp_context(sc)
1212 : fpu_emulator_restore_context(sc);
1213}
1214#endif
1215
1116static inline void signal_init(void) 1216static inline void signal_init(void)
1117{ 1217{
1218#ifdef CONFIG_SMP
1219 /* For now just do the cpu_has_fpu check when the functions are invoked */
1220 save_fp_context = smp_save_fp_context;
1221 restore_fp_context = smp_restore_fp_context;
1222#else
1118 if (cpu_has_fpu) { 1223 if (cpu_has_fpu) {
1119 save_fp_context = _save_fp_context; 1224 save_fp_context = _save_fp_context;
1120 restore_fp_context = _restore_fp_context; 1225 restore_fp_context = _restore_fp_context;
@@ -1122,6 +1227,7 @@ static inline void signal_init(void)
1122 save_fp_context = fpu_emulator_save_context; 1227 save_fp_context = fpu_emulator_save_context;
1123 restore_fp_context = fpu_emulator_restore_context; 1228 restore_fp_context = fpu_emulator_restore_context;
1124 } 1229 }
1230#endif
1125} 1231}
1126 1232
1127#ifdef CONFIG_MIPS32_COMPAT 1233#ifdef CONFIG_MIPS32_COMPAT
@@ -1158,6 +1264,20 @@ void __init per_cpu_trap_init(void)
1158{ 1264{
1159 unsigned int cpu = smp_processor_id(); 1265 unsigned int cpu = smp_processor_id();
1160 unsigned int status_set = ST0_CU0; 1266 unsigned int status_set = ST0_CU0;
1267#ifdef CONFIG_MIPS_MT_SMTC
1268 int secondaryTC = 0;
1269 int bootTC = (cpu == 0);
1270
1271 /*
1272 * Only do per_cpu_trap_init() for first TC of Each VPE.
1273 * Note that this hack assumes that the SMTC init code
1274 * assigns TCs consecutively and in ascending order.
1275 */
1276
1277 if (((read_c0_tcbind() & TCBIND_CURTC) != 0) &&
1278 ((read_c0_tcbind() & TCBIND_CURVPE) == cpu_data[cpu - 1].vpe_id))
1279 secondaryTC = 1;
1280#endif /* CONFIG_MIPS_MT_SMTC */
1161 1281
1162 /* 1282 /*
1163 * Disable coprocessors and select 32-bit or 64-bit addressing 1283 * Disable coprocessors and select 32-bit or 64-bit addressing
@@ -1180,6 +1300,10 @@ void __init per_cpu_trap_init(void)
1180 write_c0_hwrena (0x0000000f); /* Allow rdhwr to all registers */ 1300 write_c0_hwrena (0x0000000f); /* Allow rdhwr to all registers */
1181#endif 1301#endif
1182 1302
1303#ifdef CONFIG_MIPS_MT_SMTC
1304 if (!secondaryTC) {
1305#endif /* CONFIG_MIPS_MT_SMTC */
1306
1183 /* 1307 /*
1184 * Interrupt handling. 1308 * Interrupt handling.
1185 */ 1309 */
@@ -1196,6 +1320,9 @@ void __init per_cpu_trap_init(void)
1196 } else 1320 } else
1197 set_c0_cause(CAUSEF_IV); 1321 set_c0_cause(CAUSEF_IV);
1198 } 1322 }
1323#ifdef CONFIG_MIPS_MT_SMTC
1324 }
1325#endif /* CONFIG_MIPS_MT_SMTC */
1199 1326
1200 cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; 1327 cpu_data[cpu].asid_cache = ASID_FIRST_VERSION;
1201 TLBMISS_HANDLER_SETUP(); 1328 TLBMISS_HANDLER_SETUP();
@@ -1205,8 +1332,14 @@ void __init per_cpu_trap_init(void)
1205 BUG_ON(current->mm); 1332 BUG_ON(current->mm);
1206 enter_lazy_tlb(&init_mm, current); 1333 enter_lazy_tlb(&init_mm, current);
1207 1334
1208 cpu_cache_init(); 1335#ifdef CONFIG_MIPS_MT_SMTC
1209 tlb_init(); 1336 if (bootTC) {
1337#endif /* CONFIG_MIPS_MT_SMTC */
1338 cpu_cache_init();
1339 tlb_init();
1340#ifdef CONFIG_MIPS_MT_SMTC
1341 }
1342#endif /* CONFIG_MIPS_MT_SMTC */
1210} 1343}
1211 1344
1212/* Install CPU exception handler */ 1345/* Install CPU exception handler */
@@ -1278,7 +1411,7 @@ void __init trap_init(void)
1278 if (cpu_has_veic || cpu_has_vint) { 1411 if (cpu_has_veic || cpu_has_vint) {
1279 int nvec = cpu_has_veic ? 64 : 8; 1412 int nvec = cpu_has_veic ? 64 : 8;
1280 for (i = 0; i < nvec; i++) 1413 for (i = 0; i < nvec; i++)
1281 set_vi_handler (i, NULL); 1414 set_vi_handler(i, NULL);
1282 } 1415 }
1283 else if (cpu_has_divec) 1416 else if (cpu_has_divec)
1284 set_handler(0x200, &except_vec4, 0x8); 1417 set_handler(0x200, &except_vec4, 0x8);
@@ -1297,6 +1430,7 @@ void __init trap_init(void)
1297 if (board_be_init) 1430 if (board_be_init)
1298 board_be_init(); 1431 board_be_init();
1299 1432
1433 set_except_vector(0, handle_int);
1300 set_except_vector(1, handle_tlbm); 1434 set_except_vector(1, handle_tlbm);
1301 set_except_vector(2, handle_tlbl); 1435 set_except_vector(2, handle_tlbl);
1302 set_except_vector(3, handle_tlbs); 1436 set_except_vector(3, handle_tlbs);
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 2ad0cedf29fe..14fa00e3cdfa 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -2,7 +2,7 @@
2#include <asm/asm-offsets.h> 2#include <asm/asm-offsets.h>
3#include <asm-generic/vmlinux.lds.h> 3#include <asm-generic/vmlinux.lds.h>
4 4
5#undef mips /* CPP really sucks for this job */ 5#undef mips
6#define mips mips 6#define mips mips
7OUTPUT_ARCH(mips) 7OUTPUT_ARCH(mips)
8ENTRY(kernel_entry) 8ENTRY(kernel_entry)
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index ae83b755cf4a..80ffaa6d50ad 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -13,7 +13,6 @@
13 * You should have received a copy of the GNU General Public License along 13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc., 14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 15 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
16 *
17 */ 16 */
18 17
19/* 18/*
@@ -27,11 +26,8 @@
27 * 26 *
28 * To load and run, simply cat a SP 'program file' to /dev/vpe1. 27 * To load and run, simply cat a SP 'program file' to /dev/vpe1.
29 * i.e cat spapp >/dev/vpe1. 28 * i.e cat spapp >/dev/vpe1.
30 *
31 * You'll need to have the following device files.
32 * mknod /dev/vpe0 c 63 0
33 * mknod /dev/vpe1 c 63 1
34 */ 29 */
30
35#include <linux/config.h> 31#include <linux/config.h>
36#include <linux/kernel.h> 32#include <linux/kernel.h>
37#include <linux/module.h> 33#include <linux/module.h>
@@ -55,6 +51,8 @@
55#include <asm/cpu.h> 51#include <asm/cpu.h>
56#include <asm/processor.h> 52#include <asm/processor.h>
57#include <asm/system.h> 53#include <asm/system.h>
54#include <asm/vpe.h>
55#include <asm/kspd.h>
58 56
59typedef void *vpe_handle; 57typedef void *vpe_handle;
60 58
@@ -68,6 +66,11 @@ typedef void *vpe_handle;
68static char module_name[] = "vpe"; 66static char module_name[] = "vpe";
69static int major; 67static int major;
70 68
69#ifdef CONFIG_MIPS_APSP_KSPD
70 static struct kspd_notifications kspd_events;
71static int kspd_events_reqd = 0;
72#endif
73
71/* grab the likely amount of memory we will need. */ 74/* grab the likely amount of memory we will need. */
72#ifdef CONFIG_MIPS_VPE_LOADER_TOM 75#ifdef CONFIG_MIPS_VPE_LOADER_TOM
73#define P_SIZE (2 * 1024 * 1024) 76#define P_SIZE (2 * 1024 * 1024)
@@ -76,7 +79,10 @@ static int major;
76#define P_SIZE (256 * 1024) 79#define P_SIZE (256 * 1024)
77#endif 80#endif
78 81
82extern unsigned long physical_memsize;
83
79#define MAX_VPES 16 84#define MAX_VPES 16
85#define VPE_PATH_MAX 256
80 86
81enum vpe_state { 87enum vpe_state {
82 VPE_STATE_UNUSED = 0, 88 VPE_STATE_UNUSED = 0,
@@ -102,6 +108,8 @@ struct vpe {
102 unsigned long len; 108 unsigned long len;
103 char *pbuffer; 109 char *pbuffer;
104 unsigned long plen; 110 unsigned long plen;
111 unsigned int uid, gid;
112 char cwd[VPE_PATH_MAX];
105 113
106 unsigned long __start; 114 unsigned long __start;
107 115
@@ -113,6 +121,9 @@ struct vpe {
113 121
114 /* shared symbol address */ 122 /* shared symbol address */
115 void *shared_ptr; 123 void *shared_ptr;
124
125 /* the list of who wants to know when something major happens */
126 struct list_head notify;
116}; 127};
117 128
118struct tc { 129struct tc {
@@ -138,7 +149,7 @@ struct vpecontrol_ {
138} vpecontrol; 149} vpecontrol;
139 150
140static void release_progmem(void *ptr); 151static void release_progmem(void *ptr);
141static void dump_vpe(struct vpe * v); 152/* static __attribute_used__ void dump_vpe(struct vpe * v); */
142extern void save_gp_address(unsigned int secbase, unsigned int rel); 153extern void save_gp_address(unsigned int secbase, unsigned int rel);
143 154
144/* get the vpe associated with this minor */ 155/* get the vpe associated with this minor */
@@ -146,12 +157,14 @@ struct vpe *get_vpe(int minor)
146{ 157{
147 struct vpe *v; 158 struct vpe *v;
148 159
160 if (!cpu_has_mipsmt)
161 return NULL;
162
149 list_for_each_entry(v, &vpecontrol.vpe_list, list) { 163 list_for_each_entry(v, &vpecontrol.vpe_list, list) {
150 if (v->minor == minor) 164 if (v->minor == minor)
151 return v; 165 return v;
152 } 166 }
153 167
154 printk(KERN_DEBUG "VPE: get_vpe minor %d not found\n", minor);
155 return NULL; 168 return NULL;
156} 169}
157 170
@@ -165,8 +178,6 @@ struct tc *get_tc(int index)
165 return t; 178 return t;
166 } 179 }
167 180
168 printk(KERN_DEBUG "VPE: get_tc index %d not found\n", index);
169
170 return NULL; 181 return NULL;
171} 182}
172 183
@@ -179,8 +190,6 @@ struct tc *get_tc_unused(void)
179 return t; 190 return t;
180 } 191 }
181 192
182 printk(KERN_DEBUG "VPE: All TC's are in use\n");
183
184 return NULL; 193 return NULL;
185} 194}
186 195
@@ -190,13 +199,13 @@ struct vpe *alloc_vpe(int minor)
190 struct vpe *v; 199 struct vpe *v;
191 200
192 if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) { 201 if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) {
193 printk(KERN_WARNING "VPE: alloc_vpe no mem\n");
194 return NULL; 202 return NULL;
195 } 203 }
196 204
197 INIT_LIST_HEAD(&v->tc); 205 INIT_LIST_HEAD(&v->tc);
198 list_add_tail(&v->list, &vpecontrol.vpe_list); 206 list_add_tail(&v->list, &vpecontrol.vpe_list);
199 207
208 INIT_LIST_HEAD(&v->notify);
200 v->minor = minor; 209 v->minor = minor;
201 return v; 210 return v;
202} 211}
@@ -207,7 +216,6 @@ struct tc *alloc_tc(int index)
207 struct tc *t; 216 struct tc *t;
208 217
209 if ((t = kzalloc(sizeof(struct tc), GFP_KERNEL)) == NULL) { 218 if ((t = kzalloc(sizeof(struct tc), GFP_KERNEL)) == NULL) {
210 printk(KERN_WARNING "VPE: alloc_tc no mem\n");
211 return NULL; 219 return NULL;
212 } 220 }
213 221
@@ -236,20 +244,16 @@ void dump_mtregs(void)
236 printk("config3 0x%lx MT %ld\n", val, 244 printk("config3 0x%lx MT %ld\n", val,
237 (val & CONFIG3_MT) >> CONFIG3_MT_SHIFT); 245 (val & CONFIG3_MT) >> CONFIG3_MT_SHIFT);
238 246
239 val = read_c0_mvpconf0();
240 printk("mvpconf0 0x%lx, PVPE %ld PTC %ld M %ld\n", val,
241 (val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT,
242 val & MVPCONF0_PTC, (val & MVPCONF0_M) >> MVPCONF0_M_SHIFT);
243
244 val = read_c0_mvpcontrol(); 247 val = read_c0_mvpcontrol();
245 printk("MVPControl 0x%lx, STLB %ld VPC %ld EVP %ld\n", val, 248 printk("MVPControl 0x%lx, STLB %ld VPC %ld EVP %ld\n", val,
246 (val & MVPCONTROL_STLB) >> MVPCONTROL_STLB_SHIFT, 249 (val & MVPCONTROL_STLB) >> MVPCONTROL_STLB_SHIFT,
247 (val & MVPCONTROL_VPC) >> MVPCONTROL_VPC_SHIFT, 250 (val & MVPCONTROL_VPC) >> MVPCONTROL_VPC_SHIFT,
248 (val & MVPCONTROL_EVP)); 251 (val & MVPCONTROL_EVP));
249 252
250 val = read_c0_vpeconf0(); 253 val = read_c0_mvpconf0();
251 printk("VPEConf0 0x%lx MVP %ld\n", val, 254 printk("mvpconf0 0x%lx, PVPE %ld PTC %ld M %ld\n", val,
252 (val & VPECONF0_MVP) >> VPECONF0_MVP_SHIFT); 255 (val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT,
256 val & MVPCONF0_PTC, (val & MVPCONF0_M) >> MVPCONF0_M_SHIFT);
253} 257}
254 258
255/* Find some VPE program space */ 259/* Find some VPE program space */
@@ -354,9 +358,9 @@ static int apply_r_mips_gprel16(struct module *me, uint32_t *location,
354 } 358 }
355 359
356 if( (rel > 32768) || (rel < -32768) ) { 360 if( (rel > 32768) || (rel < -32768) ) {
357 printk(KERN_ERR 361 printk(KERN_DEBUG "VPE loader: apply_r_mips_gprel16: "
358 "apply_r_mips_gprel16: relative address out of range 0x%x %d\n", 362 "relative address 0x%x out of range of gp register\n",
359 rel, rel); 363 rel);
360 return -ENOEXEC; 364 return -ENOEXEC;
361 } 365 }
362 366
@@ -374,8 +378,8 @@ static int apply_r_mips_pc16(struct module *me, uint32_t *location,
374 rel -= 1; // and one instruction less due to the branch delay slot. 378 rel -= 1; // and one instruction less due to the branch delay slot.
375 379
376 if( (rel > 32768) || (rel < -32768) ) { 380 if( (rel > 32768) || (rel < -32768) ) {
377 printk(KERN_ERR 381 printk(KERN_DEBUG "VPE loader: "
378 "apply_r_mips_pc16: relative address out of range 0x%x\n", rel); 382 "apply_r_mips_pc16: relative address out of range 0x%x\n", rel);
379 return -ENOEXEC; 383 return -ENOEXEC;
380 } 384 }
381 385
@@ -396,7 +400,8 @@ static int apply_r_mips_26(struct module *me, uint32_t *location,
396 Elf32_Addr v) 400 Elf32_Addr v)
397{ 401{
398 if (v % 4) { 402 if (v % 4) {
399 printk(KERN_ERR "module %s: dangerous relocation mod4\n", me->name); 403 printk(KERN_DEBUG "VPE loader: apply_r_mips_26 "
404 " unaligned relocation\n");
400 return -ENOEXEC; 405 return -ENOEXEC;
401 } 406 }
402 407
@@ -459,12 +464,13 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location,
459 /* 464 /*
460 * The value for the HI16 had best be the same. 465 * The value for the HI16 had best be the same.
461 */ 466 */
462 if (v != l->value) { 467 if (v != l->value) {
463 printk("%d != %d\n", v, l->value); 468 printk(KERN_DEBUG "VPE loader: "
464 goto out_danger; 469 "apply_r_mips_lo16/hi16: "
470 "inconsistent value information\n");
471 return -ENOEXEC;
465 } 472 }
466 473
467
468 /* 474 /*
469 * Do the HI16 relocation. Note that we actually don't 475 * Do the HI16 relocation. Note that we actually don't
470 * need to know anything about the LO16 itself, except 476 * need to know anything about the LO16 itself, except
@@ -500,11 +506,6 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location,
500 *location = insnlo; 506 *location = insnlo;
501 507
502 return 0; 508 return 0;
503
504out_danger:
505 printk(KERN_ERR "module %s: dangerous " "relocation\n", me->name);
506
507 return -ENOEXEC;
508} 509}
509 510
510static int (*reloc_handlers[]) (struct module *me, uint32_t *location, 511static int (*reloc_handlers[]) (struct module *me, uint32_t *location,
@@ -518,6 +519,15 @@ static int (*reloc_handlers[]) (struct module *me, uint32_t *location,
518 [R_MIPS_PC16] = apply_r_mips_pc16 519 [R_MIPS_PC16] = apply_r_mips_pc16
519}; 520};
520 521
522static char *rstrs[] = {
523 [R_MIPS_NONE] = "MIPS_NONE",
524 [R_MIPS_32] = "MIPS_32",
525 [R_MIPS_26] = "MIPS_26",
526 [R_MIPS_HI16] = "MIPS_HI16",
527 [R_MIPS_LO16] = "MIPS_LO16",
528 [R_MIPS_GPREL16] = "MIPS_GPREL16",
529 [R_MIPS_PC16] = "MIPS_PC16"
530};
521 531
522int apply_relocations(Elf32_Shdr *sechdrs, 532int apply_relocations(Elf32_Shdr *sechdrs,
523 const char *strtab, 533 const char *strtab,
@@ -552,15 +562,13 @@ int apply_relocations(Elf32_Shdr *sechdrs,
552 562
553 res = reloc_handlers[ELF32_R_TYPE(r_info)](me, location, v); 563 res = reloc_handlers[ELF32_R_TYPE(r_info)](me, location, v);
554 if( res ) { 564 if( res ) {
555 printk(KERN_DEBUG 565 char *r = rstrs[ELF32_R_TYPE(r_info)];
556 "relocation error 0x%x sym refer <%s> value 0x%x " 566 printk(KERN_WARNING "VPE loader: .text+0x%x "
557 "type 0x%x r_info 0x%x\n", 567 "relocation type %s for symbol \"%s\" failed\n",
558 (unsigned int)location, strtab + sym->st_name, v, 568 rel[i].r_offset, r ? r : "UNKNOWN",
559 r_info, ELF32_R_TYPE(r_info)); 569 strtab + sym->st_name);
560 }
561
562 if (res)
563 return res; 570 return res;
571 }
564 } 572 }
565 573
566 return 0; 574 return 0;
@@ -576,7 +584,7 @@ void save_gp_address(unsigned int secbase, unsigned int rel)
576 584
577 585
578/* Change all symbols so that sh_value encodes the pointer directly. */ 586/* Change all symbols so that sh_value encodes the pointer directly. */
579static int simplify_symbols(Elf_Shdr * sechdrs, 587static void simplify_symbols(Elf_Shdr * sechdrs,
580 unsigned int symindex, 588 unsigned int symindex,
581 const char *strtab, 589 const char *strtab,
582 const char *secstrings, 590 const char *secstrings,
@@ -585,18 +593,21 @@ static int simplify_symbols(Elf_Shdr * sechdrs,
585 Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr; 593 Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
586 unsigned long secbase, bssbase = 0; 594 unsigned long secbase, bssbase = 0;
587 unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym); 595 unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
588 int ret = 0, size; 596 int size;
589 597
590 /* find the .bss section for COMMON symbols */ 598 /* find the .bss section for COMMON symbols */
591 for (i = 0; i < nsecs; i++) { 599 for (i = 0; i < nsecs; i++) {
592 if (strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) == 0) 600 if (strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) == 0) {
593 bssbase = sechdrs[i].sh_addr; 601 bssbase = sechdrs[i].sh_addr;
602 break;
603 }
594 } 604 }
595 605
596 for (i = 1; i < n; i++) { 606 for (i = 1; i < n; i++) {
597 switch (sym[i].st_shndx) { 607 switch (sym[i].st_shndx) {
598 case SHN_COMMON: 608 case SHN_COMMON:
599 /* Allocate space for the symbol in the .bss section. st_value is currently size. 609 /* Allocate space for the symbol in the .bss section.
610 st_value is currently size.
600 We want it to have the address of the symbol. */ 611 We want it to have the address of the symbol. */
601 612
602 size = sym[i].st_value; 613 size = sym[i].st_value;
@@ -614,11 +625,9 @@ static int simplify_symbols(Elf_Shdr * sechdrs,
614 break; 625 break;
615 626
616 case SHN_MIPS_SCOMMON: 627 case SHN_MIPS_SCOMMON:
617 628 printk(KERN_DEBUG "simplify_symbols: ignoring SHN_MIPS_SCOMMON"
618 printk(KERN_DEBUG 629 "symbol <%s> st_shndx %d\n", strtab + sym[i].st_name,
619 "simplify_symbols: ignoring SHN_MIPS_SCOMMON symbol <%s> st_shndx %d\n", 630 sym[i].st_shndx);
620 strtab + sym[i].st_name, sym[i].st_shndx);
621
622 // .sbss section 631 // .sbss section
623 break; 632 break;
624 633
@@ -632,10 +641,7 @@ static int simplify_symbols(Elf_Shdr * sechdrs,
632 sym[i].st_value += secbase; 641 sym[i].st_value += secbase;
633 break; 642 break;
634 } 643 }
635
636 } 644 }
637
638 return ret;
639} 645}
640 646
641#ifdef DEBUG_ELFLOADER 647#ifdef DEBUG_ELFLOADER
@@ -655,9 +661,26 @@ static void dump_elfsymbols(Elf_Shdr * sechdrs, unsigned int symindex,
655 661
656static void dump_tc(struct tc *t) 662static void dump_tc(struct tc *t)
657{ 663{
658 printk(KERN_WARNING "VPE: TC index %d TCStatus 0x%lx halt 0x%lx\n", 664 unsigned long val;
659 t->index, read_tc_c0_tcstatus(), read_tc_c0_tchalt()); 665
660 printk(KERN_WARNING "VPE: tcrestart 0x%lx\n", read_tc_c0_tcrestart()); 666 settc(t->index);
667 printk(KERN_DEBUG "VPE loader: TC index %d targtc %ld "
668 "TCStatus 0x%lx halt 0x%lx\n",
669 t->index, read_c0_vpecontrol() & VPECONTROL_TARGTC,
670 read_tc_c0_tcstatus(), read_tc_c0_tchalt());
671
672 printk(KERN_DEBUG " tcrestart 0x%lx\n", read_tc_c0_tcrestart());
673 printk(KERN_DEBUG " tcbind 0x%lx\n", read_tc_c0_tcbind());
674
675 val = read_c0_vpeconf0();
676 printk(KERN_DEBUG " VPEConf0 0x%lx MVP %ld\n", val,
677 (val & VPECONF0_MVP) >> VPECONF0_MVP_SHIFT);
678
679 printk(KERN_DEBUG " c0 status 0x%lx\n", read_vpe_c0_status());
680 printk(KERN_DEBUG " c0 cause 0x%lx\n", read_vpe_c0_cause());
681
682 printk(KERN_DEBUG " c0 badvaddr 0x%lx\n", read_vpe_c0_badvaddr());
683 printk(KERN_DEBUG " c0 epc 0x%lx\n", read_vpe_c0_epc());
661} 684}
662 685
663static void dump_tclist(void) 686static void dump_tclist(void)
@@ -672,96 +695,108 @@ static void dump_tclist(void)
672/* We are prepared so configure and start the VPE... */ 695/* We are prepared so configure and start the VPE... */
673int vpe_run(struct vpe * v) 696int vpe_run(struct vpe * v)
674{ 697{
675 unsigned long val; 698 struct vpe_notifications *n;
699 unsigned long val, dmt_flag;
676 struct tc *t; 700 struct tc *t;
677 701
678 /* check we are the Master VPE */ 702 /* check we are the Master VPE */
679 val = read_c0_vpeconf0(); 703 val = read_c0_vpeconf0();
680 if (!(val & VPECONF0_MVP)) { 704 if (!(val & VPECONF0_MVP)) {
681 printk(KERN_WARNING 705 printk(KERN_WARNING
682 "VPE: only Master VPE's are allowed to configure MT\n"); 706 "VPE loader: only Master VPE's are allowed to configure MT\n");
683 return -1; 707 return -1;
684 } 708 }
685 709
686 /* disable MT (using dvpe) */ 710 /* disable MT (using dvpe) */
687 dvpe(); 711 dvpe();
688 712
713 if (!list_empty(&v->tc)) {
714 if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) {
715 printk(KERN_WARNING "VPE loader: TC %d is already in use.\n",
716 t->index);
717 return -ENOEXEC;
718 }
719 } else {
720 printk(KERN_WARNING "VPE loader: No TC's associated with VPE %d\n",
721 v->minor);
722 return -ENOEXEC;
723 }
724
689 /* Put MVPE's into 'configuration state' */ 725 /* Put MVPE's into 'configuration state' */
690 set_c0_mvpcontrol(MVPCONTROL_VPC); 726 set_c0_mvpcontrol(MVPCONTROL_VPC);
691 727
692 if (!list_empty(&v->tc)) {
693 if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) {
694 printk(KERN_WARNING "VPE: TC %d is already in use.\n",
695 t->index);
696 return -ENOEXEC;
697 }
698 } else {
699 printk(KERN_WARNING "VPE: No TC's associated with VPE %d\n",
700 v->minor);
701 return -ENOEXEC;
702 }
703
704 settc(t->index); 728 settc(t->index);
705 729
706 val = read_vpe_c0_vpeconf0();
707
708 /* should check it is halted, and not activated */ 730 /* should check it is halted, and not activated */
709 if ((read_tc_c0_tcstatus() & TCSTATUS_A) || !(read_tc_c0_tchalt() & TCHALT_H)) { 731 if ((read_tc_c0_tcstatus() & TCSTATUS_A) || !(read_tc_c0_tchalt() & TCHALT_H)) {
710 printk(KERN_WARNING "VPE: TC %d is already doing something!\n", 732 printk(KERN_WARNING "VPE loader: TC %d is already doing something!\n",
711 t->index); 733 t->index);
712
713 dump_tclist(); 734 dump_tclist();
714 return -ENOEXEC; 735 return -ENOEXEC;
715 } 736 }
716 737
738 /*
739 * Disable multi-threaded execution whilst we activate, clear the
740 * halt bit and bound the tc to the other VPE...
741 */
742 dmt_flag = dmt();
743
717 /* Write the address we want it to start running from in the TCPC register. */ 744 /* Write the address we want it to start running from in the TCPC register. */
718 write_tc_c0_tcrestart((unsigned long)v->__start); 745 write_tc_c0_tcrestart((unsigned long)v->__start);
719
720 /* write the sivc_info address to tccontext */
721 write_tc_c0_tccontext((unsigned long)0); 746 write_tc_c0_tccontext((unsigned long)0);
722 747 /*
723 /* Set up the XTC bit in vpeconf0 to point at our tc */ 748 * Mark the TC as activated, not interrupt exempt and not dynamically
724 write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | (t->index << VPECONF0_XTC_SHIFT)); 749 * allocatable
725 750 */
726 /* mark the TC as activated, not interrupt exempt and not dynamically allocatable */
727 val = read_tc_c0_tcstatus(); 751 val = read_tc_c0_tcstatus();
728 val = (val & ~(TCSTATUS_DA | TCSTATUS_IXMT)) | TCSTATUS_A; 752 val = (val & ~(TCSTATUS_DA | TCSTATUS_IXMT)) | TCSTATUS_A;
729 write_tc_c0_tcstatus(val); 753 write_tc_c0_tcstatus(val);
730 754
731 write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H); 755 write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H);
732 756
733 /* set up VPE1 */
734 write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE); // no multiple TC's
735 write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA); // enable this VPE
736
737 /* 757 /*
738 * The sde-kit passes 'memsize' to __start in $a3, so set something 758 * The sde-kit passes 'memsize' to __start in $a3, so set something
739 * here... 759 * here... Or set $a3 to zero and define DFLT_STACK_SIZE and
740 * Or set $a3 (register 7) to zero and define DFLT_STACK_SIZE and
741 * DFLT_HEAP_SIZE when you compile your program 760 * DFLT_HEAP_SIZE when you compile your program
742 */ 761 */
762 mttgpr(7, physical_memsize);
763
764
765 /* set up VPE1 */
766 /*
767 * bind the TC to VPE 1 as late as possible so we only have the final
768 * VPE registers to set up, and so an EJTAG probe can trigger on it
769 */
770 write_tc_c0_tcbind((read_tc_c0_tcbind() & ~TCBIND_CURVPE) | v->minor);
743 771
744 mttgpr(7, 0); 772 /* Set up the XTC bit in vpeconf0 to point at our tc */
773 write_vpe_c0_vpeconf0( (read_vpe_c0_vpeconf0() & ~(VPECONF0_XTC))
774 | (t->index << VPECONF0_XTC_SHIFT));
745 775
746 /* set config to be the same as vpe0, particularly kseg0 coherency alg */ 776 /* enable this VPE */
747 write_vpe_c0_config(read_c0_config()); 777 write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);
748 778
749 /* clear out any left overs from a previous program */ 779 /* clear out any left overs from a previous program */
780 write_vpe_c0_status(0);
750 write_vpe_c0_cause(0); 781 write_vpe_c0_cause(0);
751 782
752 /* take system out of configuration state */ 783 /* take system out of configuration state */
753 clear_c0_mvpcontrol(MVPCONTROL_VPC); 784 clear_c0_mvpcontrol(MVPCONTROL_VPC);
754 785
755 /* clear interrupts enabled IE, ERL, EXL, and KSU from c0 status */ 786 /* now safe to re-enable multi-threading */
756 write_vpe_c0_status(read_vpe_c0_status() & ~(ST0_ERL | ST0_KSU | ST0_IE | ST0_EXL)); 787 emt(dmt_flag);
757 788
758 /* set it running */ 789 /* set it running */
759 evpe(EVPE_ENABLE); 790 evpe(EVPE_ENABLE);
760 791
792 list_for_each_entry(n, &v->notify, list) {
793 n->start(v->minor);
794 }
795
761 return 0; 796 return 0;
762} 797}
763 798
764static unsigned long find_vpe_symbols(struct vpe * v, Elf_Shdr * sechdrs, 799static int find_vpe_symbols(struct vpe * v, Elf_Shdr * sechdrs,
765 unsigned int symindex, const char *strtab, 800 unsigned int symindex, const char *strtab,
766 struct module *mod) 801 struct module *mod)
767{ 802{
@@ -778,26 +813,28 @@ static unsigned long find_vpe_symbols(struct vpe * v, Elf_Shdr * sechdrs,
778 } 813 }
779 } 814 }
780 815
816 if ( (v->__start == 0) || (v->shared_ptr == NULL))
817 return -1;
818
781 return 0; 819 return 0;
782} 820}
783 821
784/* 822/*
785 * Allocates a VPE with some program code space(the load address), copies 823 * Allocates a VPE with some program code space(the load address), copies the
786 * the contents of the program (p)buffer performing relocatations/etc, 824 * contents of the program (p)buffer performing relocatations/etc, free's it
787 * free's it when finished. 825 * when finished.
788*/ 826 */
789int vpe_elfload(struct vpe * v) 827int vpe_elfload(struct vpe * v)
790{ 828{
791 Elf_Ehdr *hdr; 829 Elf_Ehdr *hdr;
792 Elf_Shdr *sechdrs; 830 Elf_Shdr *sechdrs;
793 long err = 0; 831 long err = 0;
794 char *secstrings, *strtab = NULL; 832 char *secstrings, *strtab = NULL;
795 unsigned int len, i, symindex = 0, strindex = 0; 833 unsigned int len, i, symindex = 0, strindex = 0, relocate = 0;
796
797 struct module mod; // so we can re-use the relocations code 834 struct module mod; // so we can re-use the relocations code
798 835
799 memset(&mod, 0, sizeof(struct module)); 836 memset(&mod, 0, sizeof(struct module));
800 strcpy(mod.name, "VPE dummy prog module"); 837 strcpy(mod.name, "VPE loader");
801 838
802 hdr = (Elf_Ehdr *) v->pbuffer; 839 hdr = (Elf_Ehdr *) v->pbuffer;
803 len = v->plen; 840 len = v->plen;
@@ -805,16 +842,22 @@ int vpe_elfload(struct vpe * v)
805 /* Sanity checks against insmoding binaries or wrong arch, 842 /* Sanity checks against insmoding binaries or wrong arch,
806 weird elf version */ 843 weird elf version */
807 if (memcmp(hdr->e_ident, ELFMAG, 4) != 0 844 if (memcmp(hdr->e_ident, ELFMAG, 4) != 0
808 || hdr->e_type != ET_REL || !elf_check_arch(hdr) 845 || (hdr->e_type != ET_REL && hdr->e_type != ET_EXEC)
846 || !elf_check_arch(hdr)
809 || hdr->e_shentsize != sizeof(*sechdrs)) { 847 || hdr->e_shentsize != sizeof(*sechdrs)) {
810 printk(KERN_WARNING 848 printk(KERN_WARNING
811 "VPE program, wrong arch or weird elf version\n"); 849 "VPE loader: program wrong arch or weird elf version\n");
812 850
813 return -ENOEXEC; 851 return -ENOEXEC;
814 } 852 }
815 853
854 if (hdr->e_type == ET_REL)
855 relocate = 1;
856
816 if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr)) { 857 if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr)) {
817 printk(KERN_ERR "VPE program length %u truncated\n", len); 858 printk(KERN_ERR "VPE loader: program length %u truncated\n",
859 len);
860
818 return -ENOEXEC; 861 return -ENOEXEC;
819 } 862 }
820 863
@@ -826,82 +869,126 @@ int vpe_elfload(struct vpe * v)
826 /* And these should exist, but gcc whinges if we don't init them */ 869 /* And these should exist, but gcc whinges if we don't init them */
827 symindex = strindex = 0; 870 symindex = strindex = 0;
828 871
829 for (i = 1; i < hdr->e_shnum; i++) { 872 if (relocate) {
830 873 for (i = 1; i < hdr->e_shnum; i++) {
831 if (sechdrs[i].sh_type != SHT_NOBITS 874 if (sechdrs[i].sh_type != SHT_NOBITS
832 && len < sechdrs[i].sh_offset + sechdrs[i].sh_size) { 875 && len < sechdrs[i].sh_offset + sechdrs[i].sh_size) {
833 printk(KERN_ERR "VPE program length %u truncated\n", 876 printk(KERN_ERR "VPE program length %u truncated\n",
834 len); 877 len);
835 return -ENOEXEC; 878 return -ENOEXEC;
836 } 879 }
837 880
838 /* Mark all sections sh_addr with their address in the 881 /* Mark all sections sh_addr with their address in the
839 temporary image. */ 882 temporary image. */
840 sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset; 883 sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset;
841 884
842 /* Internal symbols and strings. */ 885 /* Internal symbols and strings. */
843 if (sechdrs[i].sh_type == SHT_SYMTAB) { 886 if (sechdrs[i].sh_type == SHT_SYMTAB) {
844 symindex = i; 887 symindex = i;
845 strindex = sechdrs[i].sh_link; 888 strindex = sechdrs[i].sh_link;
846 strtab = (char *)hdr + sechdrs[strindex].sh_offset; 889 strtab = (char *)hdr + sechdrs[strindex].sh_offset;
890 }
847 } 891 }
892 layout_sections(&mod, hdr, sechdrs, secstrings);
848 } 893 }
849 894
850 layout_sections(&mod, hdr, sechdrs, secstrings);
851
852 v->load_addr = alloc_progmem(mod.core_size); 895 v->load_addr = alloc_progmem(mod.core_size);
853 memset(v->load_addr, 0, mod.core_size); 896 memset(v->load_addr, 0, mod.core_size);
854 897
855 printk("VPE elf_loader: loading to %p\n", v->load_addr); 898 printk("VPE loader: loading to %p\n", v->load_addr);
856 899
857 for (i = 0; i < hdr->e_shnum; i++) { 900 if (relocate) {
858 void *dest; 901 for (i = 0; i < hdr->e_shnum; i++) {
902 void *dest;
859 903
860 if (!(sechdrs[i].sh_flags & SHF_ALLOC)) 904 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
861 continue; 905 continue;
862 906
863 dest = v->load_addr + sechdrs[i].sh_entsize; 907 dest = v->load_addr + sechdrs[i].sh_entsize;
864 908
865 if (sechdrs[i].sh_type != SHT_NOBITS) 909 if (sechdrs[i].sh_type != SHT_NOBITS)
866 memcpy(dest, (void *)sechdrs[i].sh_addr, 910 memcpy(dest, (void *)sechdrs[i].sh_addr,
867 sechdrs[i].sh_size); 911 sechdrs[i].sh_size);
868 /* Update sh_addr to point to copy in image. */ 912 /* Update sh_addr to point to copy in image. */
869 sechdrs[i].sh_addr = (unsigned long)dest; 913 sechdrs[i].sh_addr = (unsigned long)dest;
870 }
871 914
872 /* Fix up syms, so that st_value is a pointer to location. */ 915 printk(KERN_DEBUG " section sh_name %s sh_addr 0x%x\n",
873 err = 916 secstrings + sechdrs[i].sh_name, sechdrs[i].sh_addr);
874 simplify_symbols(sechdrs, symindex, strtab, secstrings, 917 }
875 hdr->e_shnum, &mod);
876 if (err < 0) {
877 printk(KERN_WARNING "VPE: unable to simplify symbols\n");
878 goto cleanup;
879 }
880 918
881 /* Now do relocations. */ 919 /* Fix up syms, so that st_value is a pointer to location. */
882 for (i = 1; i < hdr->e_shnum; i++) { 920 simplify_symbols(sechdrs, symindex, strtab, secstrings,
883 const char *strtab = (char *)sechdrs[strindex].sh_addr; 921 hdr->e_shnum, &mod);
884 unsigned int info = sechdrs[i].sh_info; 922
885 923 /* Now do relocations. */
886 /* Not a valid relocation section? */ 924 for (i = 1; i < hdr->e_shnum; i++) {
887 if (info >= hdr->e_shnum) 925 const char *strtab = (char *)sechdrs[strindex].sh_addr;
888 continue; 926 unsigned int info = sechdrs[i].sh_info;
889 927
890 /* Don't bother with non-allocated sections */ 928 /* Not a valid relocation section? */
891 if (!(sechdrs[info].sh_flags & SHF_ALLOC)) 929 if (info >= hdr->e_shnum)
892 continue; 930 continue;
893 931
894 if (sechdrs[i].sh_type == SHT_REL) 932 /* Don't bother with non-allocated sections */
895 err = 933 if (!(sechdrs[info].sh_flags & SHF_ALLOC))
896 apply_relocations(sechdrs, strtab, symindex, i, &mod); 934 continue;
897 else if (sechdrs[i].sh_type == SHT_RELA) 935
898 err = apply_relocate_add(sechdrs, strtab, symindex, i, 936 if (sechdrs[i].sh_type == SHT_REL)
899 &mod); 937 err = apply_relocations(sechdrs, strtab, symindex, i,
900 if (err < 0) { 938 &mod);
901 printk(KERN_WARNING 939 else if (sechdrs[i].sh_type == SHT_RELA)
902 "vpe_elfload: error in relocations err %ld\n", 940 err = apply_relocate_add(sechdrs, strtab, symindex, i,
903 err); 941 &mod);
904 goto cleanup; 942 if (err < 0)
943 return err;
944
945 }
946 } else {
947 for (i = 0; i < hdr->e_shnum; i++) {
948
949 /* Internal symbols and strings. */
950 if (sechdrs[i].sh_type == SHT_SYMTAB) {
951 symindex = i;
952 strindex = sechdrs[i].sh_link;
953 strtab = (char *)hdr + sechdrs[strindex].sh_offset;
954
955 /* mark the symtab's address for when we try to find the
956 magic symbols */
957 sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset;
958 }
959
960 /* filter sections we dont want in the final image */
961 if (!(sechdrs[i].sh_flags & SHF_ALLOC) ||
962 (sechdrs[i].sh_type == SHT_MIPS_REGINFO)) {
963 printk( KERN_DEBUG " ignoring section, "
964 "name %s type %x address 0x%x \n",
965 secstrings + sechdrs[i].sh_name,
966 sechdrs[i].sh_type, sechdrs[i].sh_addr);
967 continue;
968 }
969
970 if (sechdrs[i].sh_addr < (unsigned int)v->load_addr) {
971 printk( KERN_WARNING "VPE loader: "
972 "fully linked image has invalid section, "
973 "name %s type %x address 0x%x, before load "
974 "address of 0x%x\n",
975 secstrings + sechdrs[i].sh_name,
976 sechdrs[i].sh_type, sechdrs[i].sh_addr,
977 (unsigned int)v->load_addr);
978 return -ENOEXEC;
979 }
980
981 printk(KERN_DEBUG " copying section sh_name %s, sh_addr 0x%x "
982 "size 0x%x0 from x%p\n",
983 secstrings + sechdrs[i].sh_name, sechdrs[i].sh_addr,
984 sechdrs[i].sh_size, hdr + sechdrs[i].sh_offset);
985
986 if (sechdrs[i].sh_type != SHT_NOBITS)
987 memcpy((void *)sechdrs[i].sh_addr,
988 (char *)hdr + sechdrs[i].sh_offset,
989 sechdrs[i].sh_size);
990 else
991 memset((void *)sechdrs[i].sh_addr, 0, sechdrs[i].sh_size);
905 } 992 }
906 } 993 }
907 994
@@ -910,71 +997,104 @@ int vpe_elfload(struct vpe * v)
910 (unsigned long)v->load_addr + v->len); 997 (unsigned long)v->load_addr + v->len);
911 998
912 if ((find_vpe_symbols(v, sechdrs, symindex, strtab, &mod)) < 0) { 999 if ((find_vpe_symbols(v, sechdrs, symindex, strtab, &mod)) < 0) {
1000 if (v->__start == 0) {
1001 printk(KERN_WARNING "VPE loader: program does not contain "
1002 "a __start symbol\n");
1003 return -ENOEXEC;
1004 }
913 1005
914 printk(KERN_WARNING 1006 if (v->shared_ptr == NULL)
915 "VPE: program doesn't contain __start or vpe_shared symbols\n"); 1007 printk(KERN_WARNING "VPE loader: "
916 err = -ENOEXEC; 1008 "program does not contain vpe_shared symbol.\n"
1009 " Unable to use AMVP (AP/SP) facilities.\n");
917 } 1010 }
918 1011
919 printk(" elf loaded\n"); 1012 printk(" elf loaded\n");
920 1013 return 0;
921cleanup:
922 return err;
923} 1014}
924 1015
925static void dump_vpe(struct vpe * v) 1016__attribute_used__ void dump_vpe(struct vpe * v)
926{ 1017{
927 struct tc *t; 1018 struct tc *t;
928 1019
1020 settc(v->minor);
1021
929 printk(KERN_DEBUG "VPEControl 0x%lx\n", read_vpe_c0_vpecontrol()); 1022 printk(KERN_DEBUG "VPEControl 0x%lx\n", read_vpe_c0_vpecontrol());
930 printk(KERN_DEBUG "VPEConf0 0x%lx\n", read_vpe_c0_vpeconf0()); 1023 printk(KERN_DEBUG "VPEConf0 0x%lx\n", read_vpe_c0_vpeconf0());
931 1024
932 list_for_each_entry(t, &vpecontrol.tc_list, list) { 1025 list_for_each_entry(t, &vpecontrol.tc_list, list)
933 dump_tc(t); 1026 dump_tc(t);
934 }
935} 1027}
936 1028
937/* checks for VPE is unused and gets ready to load program */ 1029static void cleanup_tc(struct tc *tc)
1030{
1031 int tmp;
1032
1033 /* Put MVPE's into 'configuration state' */
1034 set_c0_mvpcontrol(MVPCONTROL_VPC);
1035
1036 settc(tc->index);
1037 tmp = read_tc_c0_tcstatus();
1038
1039 /* mark not allocated and not dynamically allocatable */
1040 tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
1041 tmp |= TCSTATUS_IXMT; /* interrupt exempt */
1042 write_tc_c0_tcstatus(tmp);
1043
1044 write_tc_c0_tchalt(TCHALT_H);
1045
1046 /* bind it to anything other than VPE1 */
1047 write_tc_c0_tcbind(read_tc_c0_tcbind() & ~TCBIND_CURVPE); // | TCBIND_CURVPE
1048
1049 clear_c0_mvpcontrol(MVPCONTROL_VPC);
1050}
1051
1052static int getcwd(char *buff, int size)
1053{
1054 mm_segment_t old_fs;
1055 int ret;
1056
1057 old_fs = get_fs();
1058 set_fs(KERNEL_DS);
1059
1060 ret = sys_getcwd(buff,size);
1061
1062 set_fs(old_fs);
1063
1064 return ret;
1065}
1066
1067/* checks VPE is unused and gets ready to load program */
938static int vpe_open(struct inode *inode, struct file *filp) 1068static int vpe_open(struct inode *inode, struct file *filp)
939{ 1069{
940 int minor; 1070 int minor, ret;
941 struct vpe *v; 1071 struct vpe *v;
1072 struct vpe_notifications *not;
942 1073
943 /* assume only 1 device at the mo. */ 1074 /* assume only 1 device at the mo. */
944 if ((minor = MINOR(inode->i_rdev)) != 1) { 1075 if ((minor = MINOR(inode->i_rdev)) != 1) {
945 printk(KERN_WARNING "VPE: only vpe1 is supported\n"); 1076 printk(KERN_WARNING "VPE loader: only vpe1 is supported\n");
946 return -ENODEV; 1077 return -ENODEV;
947 } 1078 }
948 1079
949 if ((v = get_vpe(minor)) == NULL) { 1080 if ((v = get_vpe(minor)) == NULL) {
950 printk(KERN_WARNING "VPE: unable to get vpe\n"); 1081 printk(KERN_WARNING "VPE loader: unable to get vpe\n");
951 return -ENODEV; 1082 return -ENODEV;
952 } 1083 }
953 1084
954 if (v->state != VPE_STATE_UNUSED) { 1085 if (v->state != VPE_STATE_UNUSED) {
955 unsigned long tmp;
956 struct tc *t;
957
958 printk(KERN_WARNING "VPE: device %d already in use\n", minor);
959
960 dvpe(); 1086 dvpe();
961 dump_vpe(v);
962
963 printk(KERN_WARNING "VPE: re-initialising %d\n", minor);
964
965 release_progmem(v->load_addr);
966 1087
967 t = get_tc(minor); 1088 printk(KERN_DEBUG "VPE loader: tc in use dumping regs\n");
968 settc(minor);
969 tmp = read_tc_c0_tcstatus();
970 1089
971 /* mark not allocated and not dynamically allocatable */ 1090 dump_tc(get_tc(minor));
972 tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
973 tmp |= TCSTATUS_IXMT; /* interrupt exempt */
974 write_tc_c0_tcstatus(tmp);
975 1091
976 write_tc_c0_tchalt(TCHALT_H); 1092 list_for_each_entry(not, &v->notify, list) {
1093 not->stop(minor);
1094 }
977 1095
1096 release_progmem(v->load_addr);
1097 cleanup_tc(get_tc(minor));
978 } 1098 }
979 1099
980 // allocate it so when we get write ops we know it's expected. 1100 // allocate it so when we get write ops we know it's expected.
@@ -986,6 +1106,24 @@ static int vpe_open(struct inode *inode, struct file *filp)
986 v->load_addr = NULL; 1106 v->load_addr = NULL;
987 v->len = 0; 1107 v->len = 0;
988 1108
1109 v->uid = filp->f_uid;
1110 v->gid = filp->f_gid;
1111
1112#ifdef CONFIG_MIPS_APSP_KSPD
1113 /* get kspd to tell us when a syscall_exit happens */
1114 if (!kspd_events_reqd) {
1115 kspd_notify(&kspd_events);
1116 kspd_events_reqd++;
1117 }
1118#endif
1119
1120 v->cwd[0] = 0;
1121 ret = getcwd(v->cwd, VPE_PATH_MAX);
1122 if (ret < 0)
1123 printk(KERN_WARNING "VPE loader: open, getcwd returned %d\n", ret);
1124
1125 v->shared_ptr = NULL;
1126 v->__start = 0;
989 return 0; 1127 return 0;
990} 1128}
991 1129
@@ -1006,14 +1144,22 @@ static int vpe_release(struct inode *inode, struct file *filp)
1006 if (vpe_elfload(v) >= 0) 1144 if (vpe_elfload(v) >= 0)
1007 vpe_run(v); 1145 vpe_run(v);
1008 else { 1146 else {
1009 printk(KERN_WARNING "VPE: ELF load failed.\n"); 1147 printk(KERN_WARNING "VPE loader: ELF load failed.\n");
1010 ret = -ENOEXEC; 1148 ret = -ENOEXEC;
1011 } 1149 }
1012 } else { 1150 } else {
1013 printk(KERN_WARNING "VPE: only elf files are supported\n"); 1151 printk(KERN_WARNING "VPE loader: only elf files are supported\n");
1014 ret = -ENOEXEC; 1152 ret = -ENOEXEC;
1015 } 1153 }
1016 1154
1155 /* It's good to be able to run the SP and if it chokes have a look at
1156 the /dev/rt?. But if we reset the pointer to the shared struct we
1157 loose what has happened. So perhaps if garbage is sent to the vpe
1158 device, use it as a trigger for the reset. Hopefully a nice
1159 executable will be along shortly. */
1160 if (ret < 0)
1161 v->shared_ptr = NULL;
1162
1017 // cleanup any temp buffers 1163 // cleanup any temp buffers
1018 if (v->pbuffer) 1164 if (v->pbuffer)
1019 vfree(v->pbuffer); 1165 vfree(v->pbuffer);
@@ -1033,21 +1179,19 @@ static ssize_t vpe_write(struct file *file, const char __user * buffer,
1033 return -ENODEV; 1179 return -ENODEV;
1034 1180
1035 if (v->pbuffer == NULL) { 1181 if (v->pbuffer == NULL) {
1036 printk(KERN_ERR "vpe_write: no pbuffer\n"); 1182 printk(KERN_ERR "VPE loader: no buffer for program\n");
1037 return -ENOMEM; 1183 return -ENOMEM;
1038 } 1184 }
1039 1185
1040 if ((count + v->len) > v->plen) { 1186 if ((count + v->len) > v->plen) {
1041 printk(KERN_WARNING 1187 printk(KERN_WARNING
1042 "VPE Loader: elf size too big. Perhaps strip uneeded symbols\n"); 1188 "VPE loader: elf size too big. Perhaps strip uneeded symbols\n");
1043 return -ENOMEM; 1189 return -ENOMEM;
1044 } 1190 }
1045 1191
1046 count -= copy_from_user(v->pbuffer + v->len, buffer, count); 1192 count -= copy_from_user(v->pbuffer + v->len, buffer, count);
1047 if (!count) { 1193 if (!count)
1048 printk("vpe_write: copy_to_user failed\n");
1049 return -EFAULT; 1194 return -EFAULT;
1050 }
1051 1195
1052 v->len += count; 1196 v->len += count;
1053 return ret; 1197 return ret;
@@ -1149,16 +1293,70 @@ void *vpe_get_shared(int index)
1149{ 1293{
1150 struct vpe *v; 1294 struct vpe *v;
1151 1295
1152 if ((v = get_vpe(index)) == NULL) { 1296 if ((v = get_vpe(index)) == NULL)
1153 printk(KERN_WARNING "vpe: invalid vpe index %d\n", index);
1154 return NULL; 1297 return NULL;
1155 }
1156 1298
1157 return v->shared_ptr; 1299 return v->shared_ptr;
1158} 1300}
1159 1301
1160EXPORT_SYMBOL(vpe_get_shared); 1302EXPORT_SYMBOL(vpe_get_shared);
1161 1303
1304int vpe_getuid(int index)
1305{
1306 struct vpe *v;
1307
1308 if ((v = get_vpe(index)) == NULL)
1309 return -1;
1310
1311 return v->uid;
1312}
1313
1314EXPORT_SYMBOL(vpe_getuid);
1315
1316int vpe_getgid(int index)
1317{
1318 struct vpe *v;
1319
1320 if ((v = get_vpe(index)) == NULL)
1321 return -1;
1322
1323 return v->gid;
1324}
1325
1326EXPORT_SYMBOL(vpe_getgid);
1327
1328int vpe_notify(int index, struct vpe_notifications *notify)
1329{
1330 struct vpe *v;
1331
1332 if ((v = get_vpe(index)) == NULL)
1333 return -1;
1334
1335 list_add(&notify->list, &v->notify);
1336 return 0;
1337}
1338
1339EXPORT_SYMBOL(vpe_notify);
1340
1341char *vpe_getcwd(int index)
1342{
1343 struct vpe *v;
1344
1345 if ((v = get_vpe(index)) == NULL)
1346 return NULL;
1347
1348 return v->cwd;
1349}
1350
1351EXPORT_SYMBOL(vpe_getcwd);
1352
1353#ifdef CONFIG_MIPS_APSP_KSPD
1354static void kspd_sp_exit( int sp_id)
1355{
1356 cleanup_tc(get_tc(sp_id));
1357}
1358#endif
1359
1162static int __init vpe_module_init(void) 1360static int __init vpe_module_init(void)
1163{ 1361{
1164 struct vpe *v = NULL; 1362 struct vpe *v = NULL;
@@ -1201,7 +1399,8 @@ static int __init vpe_module_init(void)
1201 return -ENODEV; 1399 return -ENODEV;
1202 } 1400 }
1203 1401
1204 list_add(&t->tc, &v->tc); /* add the tc to the list of this vpe's tc's. */ 1402 /* add the tc to the list of this vpe's tc's. */
1403 list_add(&t->tc, &v->tc);
1205 1404
1206 /* deactivate all but vpe0 */ 1405 /* deactivate all but vpe0 */
1207 if (i != 0) { 1406 if (i != 0) {
@@ -1222,10 +1421,12 @@ static int __init vpe_module_init(void)
1222 ~(ST0_IM | ST0_IE | ST0_KSU)) 1421 ~(ST0_IM | ST0_IE | ST0_KSU))
1223 | ST0_CU0); 1422 | ST0_CU0);
1224 1423
1225 /* set config to be the same as vpe0, particularly kseg0 coherency alg */ 1424 /*
1425 * Set config to be the same as vpe0,
1426 * particularly kseg0 coherency alg
1427 */
1226 write_vpe_c0_config(read_c0_config()); 1428 write_vpe_c0_config(read_c0_config());
1227 } 1429 }
1228
1229 } 1430 }
1230 1431
1231 /* TC's */ 1432 /* TC's */
@@ -1234,23 +1435,28 @@ static int __init vpe_module_init(void)
1234 if (i != 0) { 1435 if (i != 0) {
1235 unsigned long tmp; 1436 unsigned long tmp;
1236 1437
1237 /* tc 0 will of course be running.... */
1238 if (i == 0)
1239 t->state = TC_STATE_RUNNING;
1240
1241 settc(i); 1438 settc(i);
1242 1439
1243 /* bind a TC to each VPE, May as well put all excess TC's 1440 /* Any TC that is bound to VPE0 gets left as is - in case
1244 on the last VPE */ 1441 we are running SMTC on VPE0. A TC that is bound to any
1245 if (i >= (((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1)) 1442 other VPE gets bound to VPE0, ideally I'd like to make
1246 write_tc_c0_tcbind(read_tc_c0_tcbind() | 1443 it homeless but it doesn't appear to let me bind a TC
1247 ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)); 1444 to a non-existent VPE. Which is perfectly reasonable.
1248 else 1445
1249 write_tc_c0_tcbind(read_tc_c0_tcbind() | i); 1446 The (un)bound state is visible to an EJTAG probe so may
1447 notify GDB...
1448 */
1449
1450 if (((tmp = read_tc_c0_tcbind()) & TCBIND_CURVPE)) {
1451 /* tc is bound >vpe0 */
1452 write_tc_c0_tcbind(tmp & ~TCBIND_CURVPE);
1453
1454 t->pvpe = get_vpe(0); /* set the parent vpe */
1455 }
1250 1456
1251 tmp = read_tc_c0_tcstatus(); 1457 tmp = read_tc_c0_tcstatus();
1252 1458
1253 /* mark not allocated and not dynamically allocatable */ 1459 /* mark not activated and not dynamically allocatable */
1254 tmp &= ~(TCSTATUS_A | TCSTATUS_DA); 1460 tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
1255 tmp |= TCSTATUS_IXMT; /* interrupt exempt */ 1461 tmp |= TCSTATUS_IXMT; /* interrupt exempt */
1256 write_tc_c0_tcstatus(tmp); 1462 write_tc_c0_tcstatus(tmp);
@@ -1262,6 +1468,9 @@ static int __init vpe_module_init(void)
1262 /* release config state */ 1468 /* release config state */
1263 clear_c0_mvpcontrol(MVPCONTROL_VPC); 1469 clear_c0_mvpcontrol(MVPCONTROL_VPC);
1264 1470
1471#ifdef CONFIG_MIPS_APSP_KSPD
1472 kspd_events.kspd_sp_exit = kspd_sp_exit;
1473#endif
1265 return 0; 1474 return 0;
1266} 1475}
1267 1476
@@ -1281,5 +1490,5 @@ static void __exit vpe_module_exit(void)
1281module_init(vpe_module_init); 1490module_init(vpe_module_init);
1282module_exit(vpe_module_exit); 1491module_exit(vpe_module_exit);
1283MODULE_DESCRIPTION("MIPS VPE Loader"); 1492MODULE_DESCRIPTION("MIPS VPE Loader");
1284MODULE_AUTHOR("Elizabeth Clarke, MIPS Technologies, Inc"); 1493MODULE_AUTHOR("Elizabeth Oldham, MIPS Technologies, Inc.");
1285MODULE_LICENSE("GPL"); 1494MODULE_LICENSE("GPL");
diff --git a/arch/mips/lasat/Makefile b/arch/mips/lasat/Makefile
index 0d5aec436725..99f5046fdf49 100644
--- a/arch/mips/lasat/Makefile
+++ b/arch/mips/lasat/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5obj-y += reset.o setup.o prom.o lasat_board.o \ 5obj-y += reset.o setup.o prom.o lasat_board.o \
6 at93c.o interrupt.o lasatIRQ.o 6 at93c.o interrupt.o
7 7
8obj-$(CONFIG_LASAT_SYSCTL) += sysctl.o 8obj-$(CONFIG_LASAT_SYSCTL) += sysctl.o
9obj-$(CONFIG_DS1603) += ds1603.o 9obj-$(CONFIG_DS1603) += ds1603.o
diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c
index 852a41901a5e..2d3472b21ebb 100644
--- a/arch/mips/lasat/interrupt.c
+++ b/arch/mips/lasat/interrupt.c
@@ -27,14 +27,13 @@
27#include <asm/bootinfo.h> 27#include <asm/bootinfo.h>
28#include <asm/irq.h> 28#include <asm/irq.h>
29#include <asm/lasat/lasatint.h> 29#include <asm/lasat/lasatint.h>
30#include <asm/time.h>
30#include <asm/gdb-stub.h> 31#include <asm/gdb-stub.h>
31 32
32static volatile int *lasat_int_status = NULL; 33static volatile int *lasat_int_status = NULL;
33static volatile int *lasat_int_mask = NULL; 34static volatile int *lasat_int_mask = NULL;
34static volatile int lasat_int_mask_shift; 35static volatile int lasat_int_mask_shift;
35 36
36extern asmlinkage void lasatIRQ(void);
37
38void disable_lasat_irq(unsigned int irq_nr) 37void disable_lasat_irq(unsigned int irq_nr)
39{ 38{
40 unsigned long flags; 39 unsigned long flags;
@@ -109,11 +108,17 @@ static unsigned long get_int_status_200(void)
109 return int_status; 108 return int_status;
110} 109}
111 110
112void lasat_hw0_irqdispatch(struct pt_regs *regs) 111asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
113{ 112{
114 unsigned long int_status; 113 unsigned long int_status;
114 unsigned int cause = read_c0_cause();
115 int irq; 115 int irq;
116 116
117 if (cause & CAUSEF_IP7) { /* R4000 count / compare IRQ */
118 ll_timer_interrupt(7, regs);
119 return;
120 }
121
117 int_status = get_int_status(); 122 int_status = get_int_status();
118 123
119 /* if int_status == 0, then the interrupt has already been cleared */ 124 /* if int_status == 0, then the interrupt has already been cleared */
@@ -147,9 +152,6 @@ void __init arch_init_irq(void)
147 panic("arch_init_irq: mips_machtype incorrect"); 152 panic("arch_init_irq: mips_machtype incorrect");
148 } 153 }
149 154
150 /* Now safe to set the exception vector. */
151 set_except_vector(0, lasatIRQ);
152
153 for (i = 0; i <= LASATINT_END; i++) { 155 for (i = 0; i <= LASATINT_END; i++) {
154 irq_desc[i].status = IRQ_DISABLED; 156 irq_desc[i].status = IRQ_DISABLED;
155 irq_desc[i].action = 0; 157 irq_desc[i].action = 0;
diff --git a/arch/mips/lasat/lasatIRQ.S b/arch/mips/lasat/lasatIRQ.S
deleted file mode 100644
index 2a2b0d056561..000000000000
--- a/arch/mips/lasat/lasatIRQ.S
+++ /dev/null
@@ -1,69 +0,0 @@
1/*
2 * Carsten Langgaard, carstenl@mips.com
3 * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved.
4 *
5 * This program is free software; you can distribute it and/or modify it
6 * under the terms of the GNU General Public License (Version 2) as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
17 *
18 * Interrupt exception dispatch code.
19 */
20#include <asm/asm.h>
21#include <asm/mipsregs.h>
22#include <asm/regdef.h>
23#include <asm/stackframe.h>
24
25 .text
26 .set noreorder
27 .align 5
28 NESTED(lasatIRQ, PT_SIZE, sp)
29 .set noat
30 SAVE_ALL
31 CLI
32 .set at
33 .set noreorder
34
35 mfc0 s0, CP0_CAUSE # get irq mask
36
37 /* First we check for r4k counter/timer IRQ. */
38 andi a0, s0, CAUSEF_IP7
39 beq a0, zero, 1f
40 andi a0, s0, CAUSEF_IP2 # delay slot, check hw0 interrupt
41
42 /* Wheee, a timer interrupt. */
43 li a0, 7
44 jal ll_timer_interrupt
45 move a1, sp
46
47 j ret_from_irq
48 nop
49
501:
51 /* Wheee, combined hardware level zero interrupt. */
52 jal lasat_hw0_irqdispatch
53 move a0, sp # delay slot
54
55 j ret_from_irq
56 nop # delay slot
57
581:
59 /*
60 * Here by mistake? This is possible, what can happen is that by the
61 * time we take the exception the IRQ pin goes low, so just leave if
62 * this is the case.
63 */
64 move a1,s0
65 mfc0 a1, CP0_EPC
66
67 j ret_from_irq
68 nop
69 END(lasatIRQ)
diff --git a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c
index bc0ebc69bfb3..db53950b7cfb 100644
--- a/arch/mips/mips-boards/atlas/atlas_int.c
+++ b/arch/mips/mips-boards/atlas/atlas_int.c
@@ -39,8 +39,6 @@
39 39
40static struct atlas_ictrl_regs *atlas_hw0_icregs; 40static struct atlas_ictrl_regs *atlas_hw0_icregs;
41 41
42extern asmlinkage void mipsIRQ(void);
43
44#if 0 42#if 0
45#define DEBUG_INT(x...) printk(x) 43#define DEBUG_INT(x...) printk(x)
46#else 44#else
@@ -98,7 +96,7 @@ static inline int ls1bit32(unsigned int x)
98 return b; 96 return b;
99} 97}
100 98
101void atlas_hw0_irqdispatch(struct pt_regs *regs) 99static inline void atlas_hw0_irqdispatch(struct pt_regs *regs)
102{ 100{
103 unsigned long int_status; 101 unsigned long int_status;
104 int irq; 102 int irq;
@@ -116,6 +114,91 @@ void atlas_hw0_irqdispatch(struct pt_regs *regs)
116 do_IRQ(irq, regs); 114 do_IRQ(irq, regs);
117} 115}
118 116
117static inline int clz(unsigned long x)
118{
119 __asm__ (
120 " .set push \n"
121 " .set mips32 \n"
122 " clz %0, %1 \n"
123 " .set pop \n"
124 : "=r" (x)
125 : "r" (x));
126
127 return x;
128}
129
130/*
131 * Version of ffs that only looks at bits 12..15.
132 */
133static inline unsigned int irq_ffs(unsigned int pending)
134{
135#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
136 return -clz(pending) + 31 - CAUSEB_IP;
137#else
138 unsigned int a0 = 7;
139 unsigned int t0;
140
141 t0 = s0 & 0xf000;
142 t0 = t0 < 1;
143 t0 = t0 << 2;
144 a0 = a0 - t0;
145 s0 = s0 << t0;
146
147 t0 = s0 & 0xc000;
148 t0 = t0 < 1;
149 t0 = t0 << 1;
150 a0 = a0 - t0;
151 s0 = s0 << t0;
152
153 t0 = s0 & 0x8000;
154 t0 = t0 < 1;
155 //t0 = t0 << 2;
156 a0 = a0 - t0;
157 //s0 = s0 << t0;
158
159 return a0;
160#endif
161}
162
163/*
164 * IRQs on the Atlas board look basically (barring software IRQs which we
165 * don't use at all and all external interrupt sources are combined together
166 * on hardware interrupt 0 (MIPS IRQ 2)) like:
167 *
168 * MIPS IRQ Source
169 * -------- ------
170 * 0 Software (ignored)
171 * 1 Software (ignored)
172 * 2 Combined hardware interrupt (hw0)
173 * 3 Hardware (ignored)
174 * 4 Hardware (ignored)
175 * 5 Hardware (ignored)
176 * 6 Hardware (ignored)
177 * 7 R4k timer (what we use)
178 *
179 * We handle the IRQ according to _our_ priority which is:
180 *
181 * Highest ---- R4k Timer
182 * Lowest ---- Combined hardware interrupt
183 *
184 * then we just return, if multiple IRQs are pending then we will just take
185 * another exception, big deal.
186 */
187asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
188{
189 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
190 int irq;
191
192 irq = irq_ffs(pending);
193
194 if (irq == MIPSCPU_INT_ATLAS)
195 atlas_hw0_irqdispatch(regs);
196 else if (irq > 0)
197 do_IRQ(MIPSCPU_INT_BASE + irq, regs);
198 else
199 spurious_interrupt(regs);
200}
201
119void __init arch_init_irq(void) 202void __init arch_init_irq(void)
120{ 203{
121 int i; 204 int i;
@@ -128,9 +211,6 @@ void __init arch_init_irq(void)
128 */ 211 */
129 atlas_hw0_icregs->intrsten = 0xffffffff; 212 atlas_hw0_icregs->intrsten = 0xffffffff;
130 213
131 /* Now safe to set the exception vector. */
132 set_except_vector(0, mipsIRQ);
133
134 for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) { 214 for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) {
135 irq_desc[i].status = IRQ_DISABLED; 215 irq_desc[i].status = IRQ_DISABLED;
136 irq_desc[i].action = 0; 216 irq_desc[i].action = 0;
diff --git a/arch/mips/mips-boards/generic/Makefile b/arch/mips/mips-boards/generic/Makefile
index b21bc6887fa8..be47c1c2bc80 100644
--- a/arch/mips/mips-boards/generic/Makefile
+++ b/arch/mips/mips-boards/generic/Makefile
@@ -18,8 +18,8 @@
18# Makefile for the MIPS boards generic routines under Linux. 18# Makefile for the MIPS boards generic routines under Linux.
19# 19#
20 20
21obj-y := mipsIRQ.o reset.o display.o init.o memory.o \ 21obj-y := reset.o display.o init.o memory.o printf.o \
22 printf.o cmdline.o time.o 22 cmdline.o time.o
23obj-$(CONFIG_PCI) += pci.o 23obj-$(CONFIG_PCI) += pci.o
24obj-$(CONFIG_KGDB) += gdb_hook.o 24obj-$(CONFIG_KGDB) += gdb_hook.o
25 25
diff --git a/arch/mips/mips-boards/generic/gdb_hook.c b/arch/mips/mips-boards/generic/gdb_hook.c
index 91a2ccbe3730..6a1854de4579 100644
--- a/arch/mips/mips-boards/generic/gdb_hook.c
+++ b/arch/mips/mips-boards/generic/gdb_hook.c
@@ -25,7 +25,7 @@
25#include <asm/serial.h> 25#include <asm/serial.h>
26#include <asm/io.h> 26#include <asm/io.h>
27 27
28static struct serial_state rs_table[RS_TABLE_SIZE] = { 28static struct serial_state rs_table[] = {
29 SERIAL_PORT_DFNS /* Defined in serial.h */ 29 SERIAL_PORT_DFNS /* Defined in serial.h */
30}; 30};
31 31
diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c
index eab5a705e989..17dfe6a8cab9 100644
--- a/arch/mips/mips-boards/generic/init.c
+++ b/arch/mips/mips-boards/generic/init.c
@@ -220,7 +220,6 @@ void __init kgdb_config (void)
220 generic_putDebugChar (*s++); 220 generic_putDebugChar (*s++);
221 } 221 }
222 222
223 kgdb_enabled = 1;
224 /* Breakpoint is invoked after interrupts are initialised */ 223 /* Breakpoint is invoked after interrupts are initialised */
225 } 224 }
226} 225}
diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c
index 32c9210373ac..bc4d093685bb 100644
--- a/arch/mips/mips-boards/generic/memory.c
+++ b/arch/mips/mips-boards/generic/memory.c
@@ -22,10 +22,12 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/mm.h> 23#include <linux/mm.h>
24#include <linux/bootmem.h> 24#include <linux/bootmem.h>
25#include <linux/pfn.h>
25#include <linux/string.h> 26#include <linux/string.h>
26 27
27#include <asm/bootinfo.h> 28#include <asm/bootinfo.h>
28#include <asm/page.h> 29#include <asm/page.h>
30#include <asm/sections.h>
29 31
30#include <asm/mips-boards/prom.h> 32#include <asm/mips-boards/prom.h>
31 33
@@ -46,9 +48,6 @@ static char *mtypes[3] = {
46}; 48};
47#endif 49#endif
48 50
49/* References to section boundaries */
50extern char _end;
51
52struct prom_pmemblock * __init prom_getmdesc(void) 51struct prom_pmemblock * __init prom_getmdesc(void)
53{ 52{
54 char *memsize_str; 53 char *memsize_str;
@@ -106,10 +105,10 @@ struct prom_pmemblock * __init prom_getmdesc(void)
106 105
107 mdesc[3].type = yamon_dontuse; 106 mdesc[3].type = yamon_dontuse;
108 mdesc[3].base = 0x00100000; 107 mdesc[3].base = 0x00100000;
109 mdesc[3].size = CPHYSADDR(PAGE_ALIGN(&_end)) - mdesc[3].base; 108 mdesc[3].size = CPHYSADDR(PFN_ALIGN((unsigned long)&_end)) - mdesc[3].base;
110 109
111 mdesc[4].type = yamon_free; 110 mdesc[4].type = yamon_free;
112 mdesc[4].base = CPHYSADDR(PAGE_ALIGN(&_end)); 111 mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end));
113 mdesc[4].size = memsize - mdesc[4].base; 112 mdesc[4].size = memsize - mdesc[4].base;
114 113
115 return &mdesc[0]; 114 return &mdesc[0];
diff --git a/arch/mips/mips-boards/generic/mipsIRQ.S b/arch/mips/mips-boards/generic/mipsIRQ.S
deleted file mode 100644
index ddd5c73a2971..000000000000
--- a/arch/mips/mips-boards/generic/mipsIRQ.S
+++ /dev/null
@@ -1,155 +0,0 @@
1/*
2 * Carsten Langgaard, carstenl@mips.com
3 * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved.
4 *
5 * ########################################################################
6 *
7 * This program is free software; you can distribute it and/or modify it
8 * under the terms of the GNU General Public License (Version 2) as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
19 *
20 * ########################################################################
21 *
22 * Interrupt exception dispatch code.
23 *
24 */
25#include <linux/config.h>
26
27#include <asm/asm.h>
28#include <asm/mipsregs.h>
29#include <asm/regdef.h>
30#include <asm/stackframe.h>
31
32#ifdef CONFIG_MIPS_ATLAS
33#include <asm/mips-boards/atlasint.h>
34#define CASCADE_IRQ MIPSCPU_INT_ATLAS
35#define CASCADE_DISPATCH atlas_hw0_irqdispatch
36#endif
37#ifdef CONFIG_MIPS_MALTA
38#include <asm/mips-boards/maltaint.h>
39#define CASCADE_IRQ MIPSCPU_INT_I8259A
40#define CASCADE_DISPATCH malta_hw0_irqdispatch
41#endif
42#ifdef CONFIG_MIPS_SEAD
43#include <asm/mips-boards/seadint.h>
44#endif
45
46/* A lot of complication here is taken away because:
47 *
48 * 1) We handle one interrupt and return, sitting in a loop and moving across
49 * all the pending IRQ bits in the cause register is _NOT_ the answer, the
50 * common case is one pending IRQ so optimize in that direction.
51 *
52 * 2) We need not check against bits in the status register IRQ mask, that
53 * would make this routine slow as hell.
54 *
55 * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
56 * between like BSD spl() brain-damage.
57 *
58 * Furthermore, the IRQs on the MIPS board look basically (barring software
59 * IRQs which we don't use at all and all external interrupt sources are
60 * combined together on hardware interrupt 0 (MIPS IRQ 2)) like:
61 *
62 * MIPS IRQ Source
63 * -------- ------
64 * 0 Software (ignored)
65 * 1 Software (ignored)
66 * 2 Combined hardware interrupt (hw0)
67 * 3 Hardware (ignored)
68 * 4 Hardware (ignored)
69 * 5 Hardware (ignored)
70 * 6 Hardware (ignored)
71 * 7 R4k timer (what we use)
72 *
73 * Note: On the SEAD board thing are a little bit different.
74 * Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired
75 * wired to UART1.
76 *
77 * We handle the IRQ according to _our_ priority which is:
78 *
79 * Highest ---- R4k Timer
80 * Lowest ---- Combined hardware interrupt
81 *
82 * then we just return, if multiple IRQs are pending then we will just take
83 * another exception, big deal.
84 */
85
86 .text
87 .set noreorder
88 .set noat
89 .align 5
90 NESTED(mipsIRQ, PT_SIZE, sp)
91 SAVE_ALL
92 CLI
93 .set at
94
95 mfc0 s0, CP0_CAUSE # get irq bits
96 mfc0 s1, CP0_STATUS # get irq mask
97 andi s0, ST0_IM # CAUSE.CE may be non-zero!
98 and s0, s1
99
100#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
101 .set mips32
102 clz a0, s0
103 .set mips0
104 negu a0
105 addu a0, 31-CAUSEB_IP
106 bltz a0, spurious
107#else
108 beqz s0, spurious
109 li a0, 7
110
111 and t0, s0, 0xf000
112 sltiu t0, t0, 1
113 sll t0, 2
114 subu a0, t0
115 sll s0, t0
116
117 and t0, s0, 0xc000
118 sltiu t0, t0, 1
119 sll t0, 1
120 subu a0, t0
121 sll s0, t0
122
123 and t0, s0, 0x8000
124 sltiu t0, t0, 1
125 # sll t0, 0
126 subu a0, t0
127 # sll s0, t0
128#endif
129
130#ifdef CASCADE_IRQ
131 li a1, CASCADE_IRQ
132 bne a0, a1, 1f
133 addu a0, MIPSCPU_INT_BASE
134
135 jal CASCADE_DISPATCH
136 move a0, sp
137
138 j ret_from_irq
139 nop
1401:
141#else
142 addu a0, MIPSCPU_INT_BASE
143#endif
144
145 jal do_IRQ
146 move a1, sp
147
148 j ret_from_irq
149 nop
150
151
152spurious:
153 j spurious_interrupt
154 nop
155 END(mipsIRQ)
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c
index 93f3bf2c2b22..a9f6124b3a22 100644
--- a/arch/mips/mips-boards/generic/time.c
+++ b/arch/mips/mips-boards/generic/time.c
@@ -30,6 +30,7 @@
30#include <linux/mc146818rtc.h> 30#include <linux/mc146818rtc.h>
31 31
32#include <asm/mipsregs.h> 32#include <asm/mipsregs.h>
33#include <asm/mipsmtregs.h>
33#include <asm/ptrace.h> 34#include <asm/ptrace.h>
34#include <asm/hardirq.h> 35#include <asm/hardirq.h>
35#include <asm/irq.h> 36#include <asm/irq.h>
@@ -50,16 +51,23 @@ unsigned long cpu_khz;
50static char display_string[] = " LINUX ON ATLAS "; 51static char display_string[] = " LINUX ON ATLAS ";
51#endif 52#endif
52#if defined(CONFIG_MIPS_MALTA) 53#if defined(CONFIG_MIPS_MALTA)
54#if defined(CONFIG_MIPS_MT_SMTC)
55static char display_string[] = " SMTC LINUX ON MALTA ";
56#else
53static char display_string[] = " LINUX ON MALTA "; 57static char display_string[] = " LINUX ON MALTA ";
58#endif /* CONFIG_MIPS_MT_SMTC */
54#endif 59#endif
55#if defined(CONFIG_MIPS_SEAD) 60#if defined(CONFIG_MIPS_SEAD)
56static char display_string[] = " LINUX ON SEAD "; 61static char display_string[] = " LINUX ON SEAD ";
57#endif 62#endif
58static unsigned int display_count = 0; 63static unsigned int display_count;
59#define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) 64#define MAX_DISPLAY_COUNT (sizeof(display_string) - 8)
60 65
61static unsigned int timer_tick_count=0; 66#define CPUCTR_IMASKBIT (0x100 << MIPSCPU_INT_CPUCTR)
67
68static unsigned int timer_tick_count;
62static int mips_cpu_timer_irq; 69static int mips_cpu_timer_irq;
70extern void smtc_timer_broadcast(int);
63 71
64static inline void scroll_display_message(void) 72static inline void scroll_display_message(void)
65{ 73{
@@ -75,15 +83,55 @@ static void mips_timer_dispatch (struct pt_regs *regs)
75 do_IRQ (mips_cpu_timer_irq, regs); 83 do_IRQ (mips_cpu_timer_irq, regs);
76} 84}
77 85
86/*
87 * Redeclare until I get around mopping the timer code insanity on MIPS.
88 */
78extern int null_perf_irq(struct pt_regs *regs); 89extern int null_perf_irq(struct pt_regs *regs);
79 90
80extern int (*perf_irq)(struct pt_regs *regs); 91extern int (*perf_irq)(struct pt_regs *regs);
81 92
82irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) 93irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
83{ 94{
84 int r2 = cpu_has_mips_r2;
85 int cpu = smp_processor_id(); 95 int cpu = smp_processor_id();
96 int r2 = cpu_has_mips_r2;
97
98#ifdef CONFIG_MIPS_MT_SMTC
99 /*
100 * In an SMTC system, one Count/Compare set exists per VPE.
101 * Which TC within a VPE gets the interrupt is essentially
102 * random - we only know that it shouldn't be one with
103 * IXMT set. Whichever TC gets the interrupt needs to
104 * send special interprocessor interrupts to the other
105 * TCs to make sure that they schedule, etc.
106 *
107 * That code is specific to the SMTC kernel, not to
108 * the a particular platform, so it's invoked from
109 * the general MIPS timer_interrupt routine.
110 */
111
112 /*
113 * DVPE is necessary so long as cross-VPE interrupts
114 * are done via read-modify-write of Cause register.
115 */
116 int vpflags = dvpe();
117 write_c0_compare (read_c0_count() - 1);
118 clear_c0_cause(CPUCTR_IMASKBIT);
119 evpe(vpflags);
120
121 if (cpu_data[cpu].vpe_id == 0) {
122 timer_interrupt(irq, dev_id, regs);
123 scroll_display_message();
124 } else
125 write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ));
126 smtc_timer_broadcast(cpu_data[cpu].vpe_id);
86 127
128 if (cpu != 0)
129 /*
130 * Other CPUs should do profiling and process accounting
131 */
132 local_timer_interrupt(irq, dev_id, regs);
133
134#else /* CONFIG_MIPS_MT_SMTC */
87 if (cpu == 0) { 135 if (cpu == 0) {
88 /* 136 /*
89 * CPU 0 handles the global timer interrupt job and process 137 * CPU 0 handles the global timer interrupt job and process
@@ -107,12 +155,14 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
107 * More support needs to be added to kernel/time for 155 * More support needs to be added to kernel/time for
108 * counter/timer interrupts on multiple CPU's 156 * counter/timer interrupts on multiple CPU's
109 */ 157 */
110 write_c0_compare (read_c0_count() + (mips_hpt_frequency/HZ)); 158 write_c0_compare(read_c0_count() + (mips_hpt_frequency/HZ));
159
111 /* 160 /*
112 * other CPUs should do profiling and process accounting 161 * Other CPUs should do profiling and process accounting
113 */ 162 */
114 local_timer_interrupt (irq, dev_id, regs); 163 local_timer_interrupt(irq, dev_id, regs);
115 } 164 }
165#endif /* CONFIG_MIPS_MT_SMTC */
116 166
117out: 167out:
118 return IRQ_HANDLED; 168 return IRQ_HANDLED;
@@ -126,7 +176,7 @@ static unsigned int __init estimate_cpu_frequency(void)
126 unsigned int prid = read_c0_prid() & 0xffff00; 176 unsigned int prid = read_c0_prid() & 0xffff00;
127 unsigned int count; 177 unsigned int count;
128 178
129#ifdef CONFIG_MIPS_SEAD 179#if defined(CONFIG_MIPS_SEAD) || defined(CONFIG_MIPS_SIM)
130 /* 180 /*
131 * The SEAD board doesn't have a real time clock, so we can't 181 * The SEAD board doesn't have a real time clock, so we can't
132 * really calculate the timer frequency 182 * really calculate the timer frequency
@@ -211,7 +261,11 @@ void __init mips_timer_setup(struct irqaction *irq)
211 261
212 /* we are using the cpu counter for timer interrupts */ 262 /* we are using the cpu counter for timer interrupts */
213 irq->handler = mips_timer_interrupt; /* we use our own handler */ 263 irq->handler = mips_timer_interrupt; /* we use our own handler */
264#ifdef CONFIG_MIPS_MT_SMTC
265 setup_irq_smtc(mips_cpu_timer_irq, irq, CPUCTR_IMASKBIT);
266#else
214 setup_irq(mips_cpu_timer_irq, irq); 267 setup_irq(mips_cpu_timer_irq, irq);
268#endif /* CONFIG_MIPS_MT_SMTC */
215 269
216#ifdef CONFIG_SMP 270#ifdef CONFIG_SMP
217 /* irq_desc(riptor) is a global resource, when the interrupt overlaps 271 /* irq_desc(riptor) is a global resource, when the interrupt overlaps
diff --git a/arch/mips/mips-boards/malta/Makefile b/arch/mips/mips-boards/malta/Makefile
index fd4c143c0e2f..77ee5c6d33c1 100644
--- a/arch/mips/mips-boards/malta/Makefile
+++ b/arch/mips/mips-boards/malta/Makefile
@@ -20,3 +20,4 @@
20# 20#
21 21
22obj-y := malta_int.o malta_setup.o 22obj-y := malta_int.o malta_setup.o
23obj-$(CONFIG_SMP) += malta_smp.o
diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c
index d06dc5ad6c9e..64db07d4dbe5 100644
--- a/arch/mips/mips-boards/malta/malta_int.c
+++ b/arch/mips/mips-boards/malta/malta_int.c
@@ -40,7 +40,6 @@
40#include <asm/mips-boards/msc01_pci.h> 40#include <asm/mips-boards/msc01_pci.h>
41#include <asm/msc01_ic.h> 41#include <asm/msc01_ic.h>
42 42
43extern asmlinkage void mipsIRQ(void);
44extern void mips_timer_interrupt(void); 43extern void mips_timer_interrupt(void);
45 44
46static DEFINE_SPINLOCK(mips_irq_lock); 45static DEFINE_SPINLOCK(mips_irq_lock);
@@ -114,13 +113,14 @@ static inline int get_int(void)
114 return irq; 113 return irq;
115} 114}
116 115
117void malta_hw0_irqdispatch(struct pt_regs *regs) 116static void malta_hw0_irqdispatch(struct pt_regs *regs)
118{ 117{
119 int irq; 118 int irq;
120 119
121 irq = get_int(); 120 irq = get_int();
122 if (irq < 0) 121 if (irq < 0) {
123 return; /* interrupt has already been cleared */ 122 return; /* interrupt has already been cleared */
123 }
124 124
125 do_IRQ(MALTA_INT_BASE+irq, regs); 125 do_IRQ(MALTA_INT_BASE+irq, regs);
126} 126}
@@ -182,6 +182,92 @@ void corehi_irqdispatch(struct pt_regs *regs)
182 die("CoreHi interrupt", regs); 182 die("CoreHi interrupt", regs);
183} 183}
184 184
185static inline int clz(unsigned long x)
186{
187 __asm__ (
188 " .set push \n"
189 " .set mips32 \n"
190 " clz %0, %1 \n"
191 " .set pop \n"
192 : "=r" (x)
193 : "r" (x));
194
195 return x;
196}
197
198/*
199 * Version of ffs that only looks at bits 12..15.
200 */
201static inline unsigned int irq_ffs(unsigned int pending)
202{
203#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
204 return -clz(pending) + 31 - CAUSEB_IP;
205#else
206 unsigned int a0 = 7;
207 unsigned int t0;
208
209 t0 = s0 & 0xf000;
210 t0 = t0 < 1;
211 t0 = t0 << 2;
212 a0 = a0 - t0;
213 s0 = s0 << t0;
214
215 t0 = s0 & 0xc000;
216 t0 = t0 < 1;
217 t0 = t0 << 1;
218 a0 = a0 - t0;
219 s0 = s0 << t0;
220
221 t0 = s0 & 0x8000;
222 t0 = t0 < 1;
223 //t0 = t0 << 2;
224 a0 = a0 - t0;
225 //s0 = s0 << t0;
226
227 return a0;
228#endif
229}
230
231/*
232 * IRQs on the Malta board look basically (barring software IRQs which we
233 * don't use at all and all external interrupt sources are combined together
234 * on hardware interrupt 0 (MIPS IRQ 2)) like:
235 *
236 * MIPS IRQ Source
237 * -------- ------
238 * 0 Software (ignored)
239 * 1 Software (ignored)
240 * 2 Combined hardware interrupt (hw0)
241 * 3 Hardware (ignored)
242 * 4 Hardware (ignored)
243 * 5 Hardware (ignored)
244 * 6 Hardware (ignored)
245 * 7 R4k timer (what we use)
246 *
247 * We handle the IRQ according to _our_ priority which is:
248 *
249 * Highest ---- R4k Timer
250 * Lowest ---- Combined hardware interrupt
251 *
252 * then we just return, if multiple IRQs are pending then we will just take
253 * another exception, big deal.
254 */
255
256asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
257{
258 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
259 int irq;
260
261 irq = irq_ffs(pending);
262
263 if (irq == MIPSCPU_INT_I8259A)
264 malta_hw0_irqdispatch(regs);
265 else if (irq > 0)
266 do_IRQ(MIPSCPU_INT_BASE + irq, regs);
267 else
268 spurious_interrupt(regs);
269}
270
185static struct irqaction i8259irq = { 271static struct irqaction i8259irq = {
186 .handler = no_action, 272 .handler = no_action,
187 .name = "XT-PIC cascade" 273 .name = "XT-PIC cascade"
@@ -214,7 +300,6 @@ int __initdata msc_nr_eicirqs = sizeof(msc_eicirqmap)/sizeof(msc_irqmap_t);
214 300
215void __init arch_init_irq(void) 301void __init arch_init_irq(void)
216{ 302{
217 set_except_vector(0, mipsIRQ);
218 init_i8259_irqs(); 303 init_i8259_irqs();
219 304
220 if (!cpu_has_veic) 305 if (!cpu_has_veic)
@@ -240,12 +325,17 @@ void __init arch_init_irq(void)
240 else if (cpu_has_vint) { 325 else if (cpu_has_vint) {
241 set_vi_handler (MIPSCPU_INT_I8259A, malta_hw0_irqdispatch); 326 set_vi_handler (MIPSCPU_INT_I8259A, malta_hw0_irqdispatch);
242 set_vi_handler (MIPSCPU_INT_COREHI, corehi_irqdispatch); 327 set_vi_handler (MIPSCPU_INT_COREHI, corehi_irqdispatch);
243 328#ifdef CONFIG_MIPS_MT_SMTC
329 setup_irq_smtc (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq,
330 (0x100 << MIPSCPU_INT_I8259A));
331 setup_irq_smtc (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI,
332 &corehi_irqaction, (0x100 << MIPSCPU_INT_COREHI));
333#else /* Not SMTC */
244 setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq); 334 setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq);
245 setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction); 335 setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction);
336#endif /* CONFIG_MIPS_MT_SMTC */
246 } 337 }
247 else { 338 else {
248 set_except_vector(0, mipsIRQ);
249 setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq); 339 setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq);
250 setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction); 340 setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction);
251 } 341 }
diff --git a/arch/mips/mips-boards/malta/malta_smp.c b/arch/mips/mips-boards/malta/malta_smp.c
new file mode 100644
index 000000000000..6c6c8eeedbce
--- /dev/null
+++ b/arch/mips/mips-boards/malta/malta_smp.c
@@ -0,0 +1,128 @@
1/*
2 * Malta Platform-specific hooks for SMP operation
3 */
4
5#include <linux/kernel.h>
6#include <linux/sched.h>
7#include <linux/cpumask.h>
8#include <linux/interrupt.h>
9
10#include <asm/atomic.h>
11#include <asm/cpu.h>
12#include <asm/processor.h>
13#include <asm/system.h>
14#include <asm/hardirq.h>
15#include <asm/mmu_context.h>
16#include <asm/smp.h>
17#ifdef CONFIG_MIPS_MT_SMTC
18#include <asm/smtc_ipi.h>
19#endif /* CONFIG_MIPS_MT_SMTC */
20
21/* VPE/SMP Prototype implements platform interfaces directly */
22#if !defined(CONFIG_MIPS_MT_SMP)
23
24/*
25 * Cause the specified action to be performed on a targeted "CPU"
26 */
27
28void core_send_ipi(int cpu, unsigned int action)
29{
30/* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
31#ifdef CONFIG_MIPS_MT_SMTC
32 smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
33#endif /* CONFIG_MIPS_MT_SMTC */
34}
35
36/*
37 * Detect available CPUs/VPEs/TCs and populate phys_cpu_present_map
38 */
39
40void __init prom_build_cpu_map(void)
41{
42 int nextslot;
43
44 /*
45 * As of November, 2004, MIPSsim only simulates one core
46 * at a time. However, that core may be a MIPS MT core
47 * with multiple virtual processors and thread contexts.
48 */
49
50 if (read_c0_config3() & (1<<2)) {
51 nextslot = mipsmt_build_cpu_map(1);
52 }
53}
54
55/*
56 * Platform "CPU" startup hook
57 */
58
59void prom_boot_secondary(int cpu, struct task_struct *idle)
60{
61#ifdef CONFIG_MIPS_MT_SMTC
62 smtc_boot_secondary(cpu, idle);
63#endif /* CONFIG_MIPS_MT_SMTC */
64}
65
66/*
67 * Post-config but pre-boot cleanup entry point
68 */
69
70void prom_init_secondary(void)
71{
72#ifdef CONFIG_MIPS_MT_SMTC
73 void smtc_init_secondary(void);
74 int myvpe;
75
76 /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */
77 myvpe = read_c0_tcbind() & TCBIND_CURVPE;
78 if (myvpe != 0) {
79 /* Ideally, this should be done only once per VPE, but... */
80 clear_c0_status(STATUSF_IP2);
81 set_c0_status(STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP3
82 | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6
83 | STATUSF_IP7);
84 }
85
86 smtc_init_secondary();
87#endif /* CONFIG_MIPS_MT_SMTC */
88}
89
90/*
91 * Platform SMP pre-initialization
92 *
93 * As noted above, we can assume a single CPU for now
94 * but it may be multithreaded.
95 */
96
97void plat_smp_setup(void)
98{
99 if (read_c0_config3() & (1<<2))
100 mipsmt_build_cpu_map(0);
101}
102
103void __init plat_prepare_cpus(unsigned int max_cpus)
104{
105 if (read_c0_config3() & (1<<2))
106 mipsmt_prepare_cpus();
107}
108
109/*
110 * SMP initialization finalization entry point
111 */
112
113void prom_smp_finish(void)
114{
115#ifdef CONFIG_MIPS_MT_SMTC
116 smtc_smp_finish();
117#endif /* CONFIG_MIPS_MT_SMTC */
118}
119
120/*
121 * Hook for after all CPUs are online
122 */
123
124void prom_cpus_done(void)
125{
126}
127
128#endif /* CONFIG_MIPS32R2_MT_SMP */
diff --git a/arch/mips/mips-boards/sead/sead_int.c b/arch/mips/mips-boards/sead/sead_int.c
index 90fda0d9915f..9168d934c661 100644
--- a/arch/mips/mips-boards/sead/sead_int.c
+++ b/arch/mips/mips-boards/sead/sead_int.c
@@ -24,16 +24,94 @@
24#include <linux/irq.h> 24#include <linux/irq.h>
25 25
26#include <asm/irq_cpu.h> 26#include <asm/irq_cpu.h>
27#include <asm/mipsregs.h>
27#include <asm/system.h> 28#include <asm/system.h>
28 29
29#include <asm/mips-boards/seadint.h> 30#include <asm/mips-boards/seadint.h>
30 31
31extern asmlinkage void mipsIRQ(void); 32static inline int clz(unsigned long x)
33{
34 __asm__ (
35 " .set push \n"
36 " .set mips32 \n"
37 " clz %0, %1 \n"
38 " .set pop \n"
39 : "=r" (x)
40 : "r" (x));
41
42 return x;
43}
44
45/*
46 * Version of ffs that only looks at bits 12..15.
47 */
48static inline unsigned int irq_ffs(unsigned int pending)
49{
50#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
51 return -clz(pending) + 31 - CAUSEB_IP;
52#else
53 unsigned int a0 = 7;
54 unsigned int t0;
55
56 t0 = s0 & 0xf000;
57 t0 = t0 < 1;
58 t0 = t0 << 2;
59 a0 = a0 - t0;
60 s0 = s0 << t0;
61
62 t0 = s0 & 0xc000;
63 t0 = t0 < 1;
64 t0 = t0 << 1;
65 a0 = a0 - t0;
66 s0 = s0 << t0;
67
68 t0 = s0 & 0x8000;
69 t0 = t0 < 1;
70 //t0 = t0 << 2;
71 a0 = a0 - t0;
72 //s0 = s0 << t0;
73
74 return a0;
75#endif
76}
77
78/*
79 * IRQs on the SEAD board look basically are combined together on hardware
80 * interrupt 0 (MIPS IRQ 2)) like:
81 *
82 * MIPS IRQ Source
83 * -------- ------
84 * 0 Software (ignored)
85 * 1 Software (ignored)
86 * 2 UART0 (hw0)
87 * 3 UART1 (hw1)
88 * 4 Hardware (ignored)
89 * 5 Hardware (ignored)
90 * 6 Hardware (ignored)
91 * 7 R4k timer (what we use)
92 *
93 * We handle the IRQ according to _our_ priority which is:
94 *
95 * Highest ---- R4k Timer
96 * Lowest ---- Combined hardware interrupt
97 *
98 * then we just return, if multiple IRQs are pending then we will just take
99 * another exception, big deal.
100 */
101asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
102{
103 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
104 int irq;
105
106 irq = irq_ffs(pending);
107
108 if (irq >= 0)
109 do_IRQ(MIPSCPU_INT_BASE + irq, regs);
110 else
111 spurious_interrupt(regs);
112}
32 113
33void __init arch_init_irq(void) 114void __init arch_init_irq(void)
34{ 115{
35 mips_cpu_irq_init(MIPSCPU_INT_BASE); 116 mips_cpu_irq_init(MIPSCPU_INT_BASE);
36
37 /* Now safe to set the exception vector. */
38 set_except_vector(0, mipsIRQ);
39} 117}
diff --git a/arch/mips/mips-boards/sim/cmdline.c b/arch/mips/mips-boards/sim/cmdline.c
deleted file mode 100644
index fef9fbd8e710..000000000000
--- a/arch/mips/mips-boards/sim/cmdline.c
+++ /dev/null
@@ -1,59 +0,0 @@
1/*
2 * Carsten Langgaard, carstenl@mips.com
3 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
4 *
5 * This program is free software; you can distribute it and/or modify it
6 * under the terms of the GNU General Public License (Version 2) as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
17 *
18 * Kernel command line creation using the prom monitor (YAMON) argc/argv.
19 */
20#include <linux/init.h>
21#include <linux/string.h>
22
23#include <asm/bootinfo.h>
24
25extern int prom_argc;
26extern int *_prom_argv;
27
28/*
29 * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
30 * This macro take care of sign extension.
31 */
32#define prom_argv(index) ((char *)(((int *)(int)_prom_argv)[(index)]))
33
34char arcs_cmdline[CL_SIZE];
35
36char * __init prom_getcmdline(void)
37{
38 return &(arcs_cmdline[0]);
39}
40
41
42void __init prom_init_cmdline(void)
43{
44 char *cp;
45 int actr;
46
47 actr = 1; /* Always ignore argv[0] */
48
49 cp = &(arcs_cmdline[0]);
50 while(actr < prom_argc) {
51 strcpy(cp, prom_argv(actr));
52 cp += strlen(prom_argv(actr));
53 *cp++ = ' ';
54 actr++;
55 }
56 if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
57 --cp;
58 *cp = '\0';
59}
diff --git a/arch/mips/mips-boards/sim/sim_cmdline.c b/arch/mips/mips-boards/sim/sim_cmdline.c
index 9df37c6fca36..c63021a5dc6c 100644
--- a/arch/mips/mips-boards/sim/sim_cmdline.c
+++ b/arch/mips/mips-boards/sim/sim_cmdline.c
@@ -26,8 +26,10 @@ char * __init prom_getcmdline(void)
26 return arcs_cmdline; 26 return arcs_cmdline;
27} 27}
28 28
29
30void __init prom_init_cmdline(void) 29void __init prom_init_cmdline(void)
31{ 30{
32 /* nothing to do */ 31 char *cp;
32 cp = arcs_cmdline;
33 /* Get boot line from environment? */
34 *cp = '\0';
33} 35}
diff --git a/arch/mips/mips-boards/sim/sim_int.c b/arch/mips/mips-boards/sim/sim_int.c
index a4d0a2c05031..2c15c8efec4e 100644
--- a/arch/mips/mips-boards/sim/sim_int.c
+++ b/arch/mips/mips-boards/sim/sim_int.c
@@ -25,17 +25,71 @@
25 25
26extern void mips_cpu_irq_init(int); 26extern void mips_cpu_irq_init(int);
27 27
28extern asmlinkage void simIRQ(void); 28static inline int clz(unsigned long x)
29{
30 __asm__ (
31 " .set push \n"
32 " .set mips32 \n"
33 " clz %0, %1 \n"
34 " .set pop \n"
35 : "=r" (x)
36 : "r" (x));
37
38 return x;
39}
40
41/*
42 * Version of ffs that only looks at bits 12..15.
43 */
44static inline unsigned int irq_ffs(unsigned int pending)
45{
46#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
47 return -clz(pending) + 31 - CAUSEB_IP;
48#else
49 unsigned int a0 = 7;
50 unsigned int t0;
51
52 t0 = s0 & 0xf000;
53 t0 = t0 < 1;
54 t0 = t0 << 2;
55 a0 = a0 - t0;
56 s0 = s0 << t0;
57
58 t0 = s0 & 0xc000;
59 t0 = t0 < 1;
60 t0 = t0 << 1;
61 a0 = a0 - t0;
62 s0 = s0 << t0;
29 63
30asmlinkage void sim_hw0_irqdispatch(struct pt_regs *regs) 64 t0 = s0 & 0x8000;
65 t0 = t0 < 1;
66 //t0 = t0 << 2;
67 a0 = a0 - t0;
68 //s0 = s0 << t0;
69
70 return a0;
71#endif
72}
73
74static inline void sim_hw0_irqdispatch(struct pt_regs *regs)
31{ 75{
32 do_IRQ(2, regs); 76 do_IRQ(2, regs);
33} 77}
34 78
35void __init arch_init_irq(void) 79asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
36{ 80{
37 /* Now safe to set the exception vector. */ 81 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
38 set_except_vector(0, simIRQ); 82 int irq;
83
84 irq = irq_ffs(pending);
39 85
86 if (irq > 0)
87 do_IRQ(MIPSCPU_INT_BASE + irq, regs);
88 else
89 spurious_interrupt(regs);
90}
91
92void __init arch_init_irq(void)
93{
40 mips_cpu_irq_init(MIPSCPU_INT_BASE); 94 mips_cpu_irq_init(MIPSCPU_INT_BASE);
41} 95}
diff --git a/arch/mips/mips-boards/sim/sim_irq.S b/arch/mips/mips-boards/sim/sim_irq.S
index da52297a2216..d16cf3822076 100644
--- a/arch/mips/mips-boards/sim/sim_irq.S
+++ b/arch/mips/mips-boards/sim/sim_irq.S
@@ -94,6 +94,8 @@
94 94
95 95
96spurious: 96spurious:
97 j spurious_interrupt 97 jal spurious_interrupt
98 nop
99 j ret_from_irq
98 nop 100 nop
99 END(simIRQ) 101 END(simIRQ)
diff --git a/arch/mips/mips-boards/sim/sim_mem.c b/arch/mips/mips-boards/sim/sim_mem.c
index e57f737bab10..f7ce76983328 100644
--- a/arch/mips/mips-boards/sim/sim_mem.c
+++ b/arch/mips/mips-boards/sim/sim_mem.c
@@ -18,9 +18,11 @@
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/mm.h> 19#include <linux/mm.h>
20#include <linux/bootmem.h> 20#include <linux/bootmem.h>
21#include <linux/pfn.h>
21 22
22#include <asm/bootinfo.h> 23#include <asm/bootinfo.h>
23#include <asm/page.h> 24#include <asm/page.h>
25#include <asm/sections.h>
24 26
25#include <asm/mips-boards/prom.h> 27#include <asm/mips-boards/prom.h>
26 28
@@ -39,9 +41,6 @@ static char *mtypes[3] = {
39}; 41};
40#endif 42#endif
41 43
42/* References to section boundaries */
43extern char _end;
44
45struct prom_pmemblock * __init prom_getmdesc(void) 44struct prom_pmemblock * __init prom_getmdesc(void)
46{ 45{
47 unsigned int memsize; 46 unsigned int memsize;
@@ -61,10 +60,10 @@ struct prom_pmemblock * __init prom_getmdesc(void)
61 60
62 mdesc[2].type = simmem_reserved; 61 mdesc[2].type = simmem_reserved;
63 mdesc[2].base = 0x00100000; 62 mdesc[2].base = 0x00100000;
64 mdesc[2].size = CPHYSADDR(PAGE_ALIGN(&_end)) - mdesc[2].base; 63 mdesc[2].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[2].base;
65 64
66 mdesc[3].type = simmem_free; 65 mdesc[3].type = simmem_free;
67 mdesc[3].base = CPHYSADDR(PAGE_ALIGN(&_end)); 66 mdesc[3].base = CPHYSADDR(PFN_ALIGN(&_end));
68 mdesc[3].size = memsize - mdesc[3].base; 67 mdesc[3].size = memsize - mdesc[3].base;
69 68
70 return &mdesc[0]; 69 return &mdesc[0];
diff --git a/arch/mips/mips-boards/sim/sim_smp.c b/arch/mips/mips-boards/sim/sim_smp.c
index a9f0c2bfe4ad..b7084e7c4bf9 100644
--- a/arch/mips/mips-boards/sim/sim_smp.c
+++ b/arch/mips/mips-boards/sim/sim_smp.c
@@ -44,8 +44,6 @@
44void core_send_ipi(int cpu, unsigned int action) 44void core_send_ipi(int cpu, unsigned int action)
45{ 45{
46#ifdef CONFIG_MIPS_MT_SMTC 46#ifdef CONFIG_MIPS_MT_SMTC
47 void smtc_send_ipi(int, int, unsigned int);
48
49 smtc_send_ipi(cpu, LINUX_SMP_IPI, action); 47 smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
50#endif /* CONFIG_MIPS_MT_SMTC */ 48#endif /* CONFIG_MIPS_MT_SMTC */
51/* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ 49/* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
@@ -59,15 +57,8 @@ void core_send_ipi(int cpu, unsigned int action)
59void __init prom_build_cpu_map(void) 57void __init prom_build_cpu_map(void)
60{ 58{
61#ifdef CONFIG_MIPS_MT_SMTC 59#ifdef CONFIG_MIPS_MT_SMTC
62 extern int mipsmt_build_cpu_map(int startslot);
63 int nextslot; 60 int nextslot;
64 61
65 cpus_clear(phys_cpu_present_map);
66
67 /* Register the boot CPU */
68
69 smp_prepare_boot_cpu();
70
71 /* 62 /*
72 * As of November, 2004, MIPSsim only simulates one core 63 * As of November, 2004, MIPSsim only simulates one core
73 * at a time. However, that core may be a MIPS MT core 64 * at a time. However, that core may be a MIPS MT core
@@ -87,8 +78,6 @@ void __init prom_build_cpu_map(void)
87void prom_boot_secondary(int cpu, struct task_struct *idle) 78void prom_boot_secondary(int cpu, struct task_struct *idle)
88{ 79{
89#ifdef CONFIG_MIPS_MT_SMTC 80#ifdef CONFIG_MIPS_MT_SMTC
90 extern void smtc_boot_secondary(int cpu, struct task_struct *t);
91
92 smtc_boot_secondary(cpu, idle); 81 smtc_boot_secondary(cpu, idle);
93#endif /* CONFIG_MIPS_MT_SMTC */ 82#endif /* CONFIG_MIPS_MT_SMTC */
94} 83}
@@ -113,7 +102,6 @@ void prom_init_secondary(void)
113void prom_prepare_cpus(unsigned int max_cpus) 102void prom_prepare_cpus(unsigned int max_cpus)
114{ 103{
115#ifdef CONFIG_MIPS_MT_SMTC 104#ifdef CONFIG_MIPS_MT_SMTC
116 void mipsmt_prepare_cpus(int c);
117 /* 105 /*
118 * As noted above, we can assume a single CPU for now 106 * As noted above, we can assume a single CPU for now
119 * but it may be multithreaded. 107 * but it may be multithreaded.
@@ -132,8 +120,6 @@ void prom_prepare_cpus(unsigned int max_cpus)
132void prom_smp_finish(void) 120void prom_smp_finish(void)
133{ 121{
134#ifdef CONFIG_MIPS_MT_SMTC 122#ifdef CONFIG_MIPS_MT_SMTC
135 void smtc_smp_finish(void);
136
137 smtc_smp_finish(); 123 smtc_smp_finish();
138#endif /* CONFIG_MIPS_MT_SMTC */ 124#endif /* CONFIG_MIPS_MT_SMTC */
139} 125}
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c
index 9dd1352d5748..bb041a22f20a 100644
--- a/arch/mips/mm/c-r3k.c
+++ b/arch/mips/mm/c-r3k.c
@@ -260,6 +260,10 @@ static void r3k_flush_cache_page(struct vm_area_struct *vma, unsigned long page,
260{ 260{
261} 261}
262 262
263static void local_r3k_flush_data_cache_page(unsigned long addr)
264{
265}
266
263static void r3k_flush_data_cache_page(unsigned long addr) 267static void r3k_flush_data_cache_page(unsigned long addr)
264{ 268{
265} 269}
@@ -335,6 +339,7 @@ void __init r3k_cache_init(void)
335 flush_icache_range = r3k_flush_icache_range; 339 flush_icache_range = r3k_flush_icache_range;
336 340
337 flush_cache_sigtramp = r3k_flush_cache_sigtramp; 341 flush_cache_sigtramp = r3k_flush_cache_sigtramp;
342 local_flush_data_cache_page = local_r3k_flush_data_cache_page;
338 flush_data_cache_page = r3k_flush_data_cache_page; 343 flush_data_cache_page = r3k_flush_data_cache_page;
339 344
340 _dma_cache_wback_inv = r3k_dma_cache_wback_inv; 345 _dma_cache_wback_inv = r3k_dma_cache_wback_inv;
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 32b7f6aeb983..4182e1176fae 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -154,7 +154,8 @@ static inline void blast_icache32_r4600_v1_page_indexed(unsigned long page)
154 154
155static inline void tx49_blast_icache32_page_indexed(unsigned long page) 155static inline void tx49_blast_icache32_page_indexed(unsigned long page)
156{ 156{
157 unsigned long start = page; 157 unsigned long indexmask = current_cpu_data.icache.waysize - 1;
158 unsigned long start = INDEX_BASE + (page & indexmask);
158 unsigned long end = start + PAGE_SIZE; 159 unsigned long end = start + PAGE_SIZE;
159 unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; 160 unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit;
160 unsigned long ws_end = current_cpu_data.icache.ways << 161 unsigned long ws_end = current_cpu_data.icache.ways <<
@@ -749,12 +750,12 @@ static void __init probe_pcache(void)
749 icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); 750 icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
750 c->icache.linesz = 16 << ((config & CONF_IB) >> 5); 751 c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
751 c->icache.ways = 2; 752 c->icache.ways = 2;
752 c->icache.waybit = ffs(icache_size/2) - 1; 753 c->icache.waybit = __ffs(icache_size/2);
753 754
754 dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); 755 dcache_size = 1 << (12 + ((config & CONF_DC) >> 6));
755 c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); 756 c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
756 c->dcache.ways = 2; 757 c->dcache.ways = 2;
757 c->dcache.waybit= ffs(dcache_size/2) - 1; 758 c->dcache.waybit= __ffs(dcache_size/2);
758 759
759 c->options |= MIPS_CPU_CACHE_CDEX_P; 760 c->options |= MIPS_CPU_CACHE_CDEX_P;
760 break; 761 break;
@@ -837,12 +838,12 @@ static void __init probe_pcache(void)
837 icache_size = 1 << (10 + ((config & CONF_IC) >> 9)); 838 icache_size = 1 << (10 + ((config & CONF_IC) >> 9));
838 c->icache.linesz = 16 << ((config & CONF_IB) >> 5); 839 c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
839 c->icache.ways = 2; 840 c->icache.ways = 2;
840 c->icache.waybit = ffs(icache_size/2) - 1; 841 c->icache.waybit = __ffs(icache_size/2);
841 842
842 dcache_size = 1 << (10 + ((config & CONF_DC) >> 6)); 843 dcache_size = 1 << (10 + ((config & CONF_DC) >> 6));
843 c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); 844 c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
844 c->dcache.ways = 2; 845 c->dcache.ways = 2;
845 c->dcache.waybit = ffs(dcache_size/2) - 1; 846 c->dcache.waybit = __ffs(dcache_size/2);
846 847
847 c->options |= MIPS_CPU_CACHE_CDEX_P; 848 c->options |= MIPS_CPU_CACHE_CDEX_P;
848 break; 849 break;
@@ -873,12 +874,12 @@ static void __init probe_pcache(void)
873 icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); 874 icache_size = 1 << (12 + ((config & CONF_IC) >> 9));
874 c->icache.linesz = 16 << ((config & CONF_IB) >> 5); 875 c->icache.linesz = 16 << ((config & CONF_IB) >> 5);
875 c->icache.ways = 4; 876 c->icache.ways = 4;
876 c->icache.waybit = ffs(icache_size / c->icache.ways) - 1; 877 c->icache.waybit = __ffs(icache_size / c->icache.ways);
877 878
878 dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); 879 dcache_size = 1 << (12 + ((config & CONF_DC) >> 6));
879 c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); 880 c->dcache.linesz = 16 << ((config & CONF_DB) >> 4);
880 c->dcache.ways = 4; 881 c->dcache.ways = 4;
881 c->dcache.waybit = ffs(dcache_size / c->dcache.ways) - 1; 882 c->dcache.waybit = __ffs(dcache_size / c->dcache.ways);
882 883
883#if !defined(CONFIG_SMP) || !defined(RM9000_CDEX_SMP_WAR) 884#if !defined(CONFIG_SMP) || !defined(RM9000_CDEX_SMP_WAR)
884 c->options |= MIPS_CPU_CACHE_CDEX_P; 885 c->options |= MIPS_CPU_CACHE_CDEX_P;
@@ -906,7 +907,7 @@ static void __init probe_pcache(void)
906 icache_size = c->icache.sets * 907 icache_size = c->icache.sets *
907 c->icache.ways * 908 c->icache.ways *
908 c->icache.linesz; 909 c->icache.linesz;
909 c->icache.waybit = ffs(icache_size/c->icache.ways) - 1; 910 c->icache.waybit = __ffs(icache_size/c->icache.ways);
910 911
911 if (config & 0x8) /* VI bit */ 912 if (config & 0x8) /* VI bit */
912 c->icache.flags |= MIPS_CACHE_VTAG; 913 c->icache.flags |= MIPS_CACHE_VTAG;
@@ -926,7 +927,7 @@ static void __init probe_pcache(void)
926 dcache_size = c->dcache.sets * 927 dcache_size = c->dcache.sets *
927 c->dcache.ways * 928 c->dcache.ways *
928 c->dcache.linesz; 929 c->dcache.linesz;
929 c->dcache.waybit = ffs(dcache_size/c->dcache.ways) - 1; 930 c->dcache.waybit = __ffs(dcache_size/c->dcache.ways);
930 931
931 c->options |= MIPS_CPU_PREFETCH; 932 c->options |= MIPS_CPU_PREFETCH;
932 break; 933 break;
@@ -1198,6 +1199,7 @@ void __init r4k_cache_init(void)
1198 1199
1199 flush_cache_sigtramp = r4k_flush_cache_sigtramp; 1200 flush_cache_sigtramp = r4k_flush_cache_sigtramp;
1200 flush_icache_all = r4k_flush_icache_all; 1201 flush_icache_all = r4k_flush_icache_all;
1202 local_flush_data_cache_page = local_r4k_flush_data_cache_page;
1201 flush_data_cache_page = r4k_flush_data_cache_page; 1203 flush_data_cache_page = r4k_flush_data_cache_page;
1202 flush_icache_range = r4k_flush_icache_range; 1204 flush_icache_range = r4k_flush_icache_range;
1203 1205
diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c
index 2f08b535f20e..f9b129491b1e 100644
--- a/arch/mips/mm/c-sb1.c
+++ b/arch/mips/mm/c-sb1.c
@@ -528,6 +528,7 @@ void sb1_cache_init(void)
528 flush_cache_page = sb1_flush_cache_page; 528 flush_cache_page = sb1_flush_cache_page;
529 529
530 flush_cache_sigtramp = sb1_flush_cache_sigtramp; 530 flush_cache_sigtramp = sb1_flush_cache_sigtramp;
531 local_flush_data_cache_page = (void *) sb1_nop;
531 flush_data_cache_page = (void *) sb1_nop; 532 flush_data_cache_page = (void *) sb1_nop;
532 533
533 /* Full flush */ 534 /* Full flush */
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c
index fe232e3988e3..5dfc9b1901f6 100644
--- a/arch/mips/mm/c-tx39.c
+++ b/arch/mips/mm/c-tx39.c
@@ -216,6 +216,11 @@ static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page
216 tx39_blast_icache_page_indexed(page); 216 tx39_blast_icache_page_indexed(page);
217} 217}
218 218
219static void local_tx39_flush_data_cache_page(void * addr)
220{
221 tx39_blast_dcache_page(addr);
222}
223
219static void tx39_flush_data_cache_page(unsigned long addr) 224static void tx39_flush_data_cache_page(unsigned long addr)
220{ 225{
221 tx39_blast_dcache_page(addr); 226 tx39_blast_dcache_page(addr);
@@ -381,6 +386,7 @@ void __init tx39_cache_init(void)
381 flush_icache_range = (void *) tx39h_flush_icache_all; 386 flush_icache_range = (void *) tx39h_flush_icache_all;
382 387
383 flush_cache_sigtramp = (void *) tx39h_flush_icache_all; 388 flush_cache_sigtramp = (void *) tx39h_flush_icache_all;
389 local_flush_data_cache_page = (void *) tx39h_flush_icache_all;
384 flush_data_cache_page = (void *) tx39h_flush_icache_all; 390 flush_data_cache_page = (void *) tx39h_flush_icache_all;
385 391
386 _dma_cache_wback_inv = tx39h_dma_cache_wback_inv; 392 _dma_cache_wback_inv = tx39h_dma_cache_wback_inv;
@@ -406,6 +412,7 @@ void __init tx39_cache_init(void)
406 flush_icache_range = tx39_flush_icache_range; 412 flush_icache_range = tx39_flush_icache_range;
407 413
408 flush_cache_sigtramp = tx39_flush_cache_sigtramp; 414 flush_cache_sigtramp = tx39_flush_cache_sigtramp;
415 local_flush_data_cache_page = local_tx39_flush_data_cache_page;
409 flush_data_cache_page = tx39_flush_data_cache_page; 416 flush_data_cache_page = tx39_flush_data_cache_page;
410 417
411 _dma_cache_wback_inv = tx39_dma_cache_wback_inv; 418 _dma_cache_wback_inv = tx39_dma_cache_wback_inv;
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 591c22b080e4..83a56296be86 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -30,6 +30,7 @@ void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page);
30 30
31/* MIPS specific cache operations */ 31/* MIPS specific cache operations */
32void (*flush_cache_sigtramp)(unsigned long addr); 32void (*flush_cache_sigtramp)(unsigned long addr);
33void (*local_flush_data_cache_page)(void * addr);
33void (*flush_data_cache_page)(unsigned long addr); 34void (*flush_data_cache_page)(unsigned long addr);
34void (*flush_icache_all)(void); 35void (*flush_icache_all)(void);
35 36
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 2d9624fd10ec..e3a617224868 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -157,7 +157,6 @@ no_context:
157 * Oops. The kernel tried to access some bad page. We'll have to 157 * Oops. The kernel tried to access some bad page. We'll have to
158 * terminate things with extreme prejudice. 158 * terminate things with extreme prejudice.
159 */ 159 */
160
161 bust_spinlocks(1); 160 bust_spinlocks(1);
162 161
163 printk(KERN_ALERT "CPU %d Unable to handle kernel paging request at " 162 printk(KERN_ALERT "CPU %d Unable to handle kernel paging request at "
@@ -188,11 +187,20 @@ do_sigbus:
188 /* Kernel mode? Handle exceptions or die */ 187 /* Kernel mode? Handle exceptions or die */
189 if (!user_mode(regs)) 188 if (!user_mode(regs))
190 goto no_context; 189 goto no_context;
191 190 else
192 /* 191 /*
193 * Send a sigbus, regardless of whether we were in kernel 192 * Send a sigbus, regardless of whether we were in kernel
194 * or user mode. 193 * or user mode.
195 */ 194 */
195#if 0
196 printk("do_page_fault() #3: sending SIGBUS to %s for "
197 "invalid %s\n%0*lx (epc == %0*lx, ra == %0*lx)\n",
198 tsk->comm,
199 write ? "write access to" : "read access from",
200 field, address,
201 field, (unsigned long) regs->cp0_epc,
202 field, (unsigned long) regs->regs[31]);
203#endif
196 tsk->thread.cp0_badvaddr = address; 204 tsk->thread.cp0_badvaddr = address;
197 info.si_signo = SIGBUS; 205 info.si_signo = SIGBUS;
198 info.si_errno = 0; 206 info.si_errno = 0;
@@ -201,7 +209,6 @@ do_sigbus:
201 force_sig_info(SIGBUS, &info, tsk); 209 force_sig_info(SIGBUS, &info, tsk);
202 210
203 return; 211 return;
204
205vmalloc_fault: 212vmalloc_fault:
206 { 213 {
207 /* 214 /*
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
index 1f7b37b38f5c..0c544375b856 100644
--- a/arch/mips/mm/highmem.c
+++ b/arch/mips/mm/highmem.c
@@ -83,6 +83,7 @@ void __kunmap_atomic(void *kvaddr, enum km_type type)
83 preempt_check_resched(); 83 preempt_check_resched();
84} 84}
85 85
86#ifndef CONFIG_LIMITED_DMA
86/* 87/*
87 * This is the same as kmap_atomic() but can map memory that doesn't 88 * This is the same as kmap_atomic() but can map memory that doesn't
88 * have a struct page associated with it. 89 * have a struct page associated with it.
@@ -101,6 +102,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
101 102
102 return (void*) vaddr; 103 return (void*) vaddr;
103} 104}
105#endif /* CONFIG_LIMITED_DMA */
104 106
105struct page *__kmap_atomic_to_page(void *ptr) 107struct page *__kmap_atomic_to_page(void *ptr)
106{ 108{
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index ad89c442f299..c22308b93ff0 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -276,6 +276,20 @@ void __init mem_init(void)
276} 276}
277#endif /* !CONFIG_NEED_MULTIPLE_NODES */ 277#endif /* !CONFIG_NEED_MULTIPLE_NODES */
278 278
279void free_init_pages(char *what, unsigned long begin, unsigned long end)
280{
281 unsigned long addr;
282
283 for (addr = begin; addr < end; addr += PAGE_SIZE) {
284 ClearPageReserved(virt_to_page(addr));
285 init_page_count(virt_to_page(addr));
286 memset((void *)addr, 0xcc, PAGE_SIZE);
287 free_page(addr);
288 totalram_pages++;
289 }
290 printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
291}
292
279#ifdef CONFIG_BLK_DEV_INITRD 293#ifdef CONFIG_BLK_DEV_INITRD
280void free_initrd_mem(unsigned long start, unsigned long end) 294void free_initrd_mem(unsigned long start, unsigned long end)
281{ 295{
@@ -284,16 +298,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
284 start = (unsigned long)phys_to_virt(CPHYSADDR(start)); 298 start = (unsigned long)phys_to_virt(CPHYSADDR(start));
285 end = (unsigned long)phys_to_virt(CPHYSADDR(end)); 299 end = (unsigned long)phys_to_virt(CPHYSADDR(end));
286#endif 300#endif
287 if (start < end) 301 free_init_pages("initrd memory", start, end);
288 printk(KERN_INFO "Freeing initrd memory: %ldk freed\n",
289 (end - start) >> 10);
290
291 for (; start < end; start += PAGE_SIZE) {
292 ClearPageReserved(virt_to_page(start));
293 init_page_count(virt_to_page(start));
294 free_page(start);
295 totalram_pages++;
296 }
297} 302}
298#endif 303#endif
299 304
@@ -301,24 +306,17 @@ extern unsigned long prom_free_prom_memory(void);
301 306
302void free_initmem(void) 307void free_initmem(void)
303{ 308{
304 unsigned long addr, page, freed; 309 unsigned long start, end, freed;
305 310
306 freed = prom_free_prom_memory(); 311 freed = prom_free_prom_memory();
312 if (freed)
313 printk(KERN_INFO "Freeing firmware memory: %ldk freed\n",freed);
307 314
308 addr = (unsigned long) &__init_begin; 315 start = (unsigned long)(&__init_begin);
309 while (addr < (unsigned long) &__init_end) { 316 end = (unsigned long)(&__init_end);
310#ifdef CONFIG_64BIT 317#ifdef CONFIG_64BIT
311 page = PAGE_OFFSET | CPHYSADDR(addr); 318 start = PAGE_OFFSET | CPHYSADDR(start);
312#else 319 end = PAGE_OFFSET | CPHYSADDR(end);
313 page = addr;
314#endif 320#endif
315 ClearPageReserved(virt_to_page(page)); 321 free_init_pages("unused kernel memory", start, end);
316 init_page_count(virt_to_page(page));
317 free_page(page);
318 totalram_pages++;
319 freed += PAGE_SIZE;
320 addr += PAGE_SIZE;
321 }
322 printk(KERN_INFO "Freeing unused kernel memory: %ldk freed\n",
323 freed >> 10);
324} 322}
diff --git a/arch/mips/mm/sc-rm7k.c b/arch/mips/mm/sc-rm7k.c
index 3b6cc9ba1b05..31ec73052423 100644
--- a/arch/mips/mm/sc-rm7k.c
+++ b/arch/mips/mm/sc-rm7k.c
@@ -138,7 +138,7 @@ void __init rm7k_sc_init(void)
138 138
139 c->scache.linesz = sc_lsize; 139 c->scache.linesz = sc_lsize;
140 c->scache.ways = 4; 140 c->scache.ways = 4;
141 c->scache.waybit= ffs(scache_size / c->scache.ways) - 1; 141 c->scache.waybit= __ffs(scache_size / c->scache.ways);
142 c->scache.waysize = scache_size / c->scache.ways; 142 c->scache.waysize = scache_size / c->scache.ways;
143 c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways); 143 c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways);
144 printk(KERN_INFO "Secondary cache size %dK, linesize %d bytes.\n", 144 printk(KERN_INFO "Secondary cache size %dK, linesize %d bytes.\n",
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index a865f2394cb0..9dca099ba16b 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -32,13 +32,35 @@ extern void build_tlb_refill_handler(void);
32 "nop; nop; nop; nop; nop; nop;\n\t" \ 32 "nop; nop; nop; nop; nop; nop;\n\t" \
33 ".set reorder\n\t") 33 ".set reorder\n\t")
34 34
35/* Atomicity and interruptability */
36#ifdef CONFIG_MIPS_MT_SMTC
37
38#include <asm/smtc.h>
39#include <asm/mipsmtregs.h>
40
41#define ENTER_CRITICAL(flags) \
42 { \
43 unsigned int mvpflags; \
44 local_irq_save(flags);\
45 mvpflags = dvpe()
46#define EXIT_CRITICAL(flags) \
47 evpe(mvpflags); \
48 local_irq_restore(flags); \
49 }
50#else
51
52#define ENTER_CRITICAL(flags) local_irq_save(flags)
53#define EXIT_CRITICAL(flags) local_irq_restore(flags)
54
55#endif /* CONFIG_MIPS_MT_SMTC */
56
35void local_flush_tlb_all(void) 57void local_flush_tlb_all(void)
36{ 58{
37 unsigned long flags; 59 unsigned long flags;
38 unsigned long old_ctx; 60 unsigned long old_ctx;
39 int entry; 61 int entry;
40 62
41 local_irq_save(flags); 63 ENTER_CRITICAL(flags);
42 /* Save old context and create impossible VPN2 value */ 64 /* Save old context and create impossible VPN2 value */
43 old_ctx = read_c0_entryhi(); 65 old_ctx = read_c0_entryhi();
44 write_c0_entrylo0(0); 66 write_c0_entrylo0(0);
@@ -57,7 +79,7 @@ void local_flush_tlb_all(void)
57 } 79 }
58 tlbw_use_hazard(); 80 tlbw_use_hazard();
59 write_c0_entryhi(old_ctx); 81 write_c0_entryhi(old_ctx);
60 local_irq_restore(flags); 82 EXIT_CRITICAL(flags);
61} 83}
62 84
63/* All entries common to a mm share an asid. To effectively flush 85/* All entries common to a mm share an asid. To effectively flush
@@ -87,6 +109,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
87 unsigned long flags; 109 unsigned long flags;
88 int size; 110 int size;
89 111
112 ENTER_CRITICAL(flags);
90 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; 113 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
91 size = (size + 1) >> 1; 114 size = (size + 1) >> 1;
92 local_irq_save(flags); 115 local_irq_save(flags);
@@ -120,7 +143,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
120 } else { 143 } else {
121 drop_mmu_context(mm, cpu); 144 drop_mmu_context(mm, cpu);
122 } 145 }
123 local_irq_restore(flags); 146 EXIT_CRITICAL(flags);
124 } 147 }
125} 148}
126 149
@@ -129,9 +152,9 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
129 unsigned long flags; 152 unsigned long flags;
130 int size; 153 int size;
131 154
155 ENTER_CRITICAL(flags);
132 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; 156 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
133 size = (size + 1) >> 1; 157 size = (size + 1) >> 1;
134 local_irq_save(flags);
135 if (size <= current_cpu_data.tlbsize / 2) { 158 if (size <= current_cpu_data.tlbsize / 2) {
136 int pid = read_c0_entryhi(); 159 int pid = read_c0_entryhi();
137 160
@@ -162,7 +185,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
162 } else { 185 } else {
163 local_flush_tlb_all(); 186 local_flush_tlb_all();
164 } 187 }
165 local_irq_restore(flags); 188 EXIT_CRITICAL(flags);
166} 189}
167 190
168void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) 191void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
@@ -175,7 +198,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
175 198
176 newpid = cpu_asid(cpu, vma->vm_mm); 199 newpid = cpu_asid(cpu, vma->vm_mm);
177 page &= (PAGE_MASK << 1); 200 page &= (PAGE_MASK << 1);
178 local_irq_save(flags); 201 ENTER_CRITICAL(flags);
179 oldpid = read_c0_entryhi(); 202 oldpid = read_c0_entryhi();
180 write_c0_entryhi(page | newpid); 203 write_c0_entryhi(page | newpid);
181 mtc0_tlbw_hazard(); 204 mtc0_tlbw_hazard();
@@ -194,7 +217,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
194 217
195 finish: 218 finish:
196 write_c0_entryhi(oldpid); 219 write_c0_entryhi(oldpid);
197 local_irq_restore(flags); 220 EXIT_CRITICAL(flags);
198 } 221 }
199} 222}
200 223
@@ -207,7 +230,7 @@ void local_flush_tlb_one(unsigned long page)
207 unsigned long flags; 230 unsigned long flags;
208 int oldpid, idx; 231 int oldpid, idx;
209 232
210 local_irq_save(flags); 233 ENTER_CRITICAL(flags);
211 oldpid = read_c0_entryhi(); 234 oldpid = read_c0_entryhi();
212 page &= (PAGE_MASK << 1); 235 page &= (PAGE_MASK << 1);
213 write_c0_entryhi(page); 236 write_c0_entryhi(page);
@@ -226,7 +249,7 @@ void local_flush_tlb_one(unsigned long page)
226 } 249 }
227 write_c0_entryhi(oldpid); 250 write_c0_entryhi(oldpid);
228 251
229 local_irq_restore(flags); 252 EXIT_CRITICAL(flags);
230} 253}
231 254
232/* 255/*
@@ -249,7 +272,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
249 if (current->active_mm != vma->vm_mm) 272 if (current->active_mm != vma->vm_mm)
250 return; 273 return;
251 274
252 local_irq_save(flags); 275 ENTER_CRITICAL(flags);
253 276
254 pid = read_c0_entryhi() & ASID_MASK; 277 pid = read_c0_entryhi() & ASID_MASK;
255 address &= (PAGE_MASK << 1); 278 address &= (PAGE_MASK << 1);
@@ -277,7 +300,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
277 else 300 else
278 tlb_write_indexed(); 301 tlb_write_indexed();
279 tlbw_use_hazard(); 302 tlbw_use_hazard();
280 local_irq_restore(flags); 303 EXIT_CRITICAL(flags);
281} 304}
282 305
283#if 0 306#if 0
@@ -291,7 +314,7 @@ static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma,
291 pte_t *ptep; 314 pte_t *ptep;
292 int idx; 315 int idx;
293 316
294 local_irq_save(flags); 317 ENTER_CRITICAL(flags);
295 address &= (PAGE_MASK << 1); 318 address &= (PAGE_MASK << 1);
296 asid = read_c0_entryhi() & ASID_MASK; 319 asid = read_c0_entryhi() & ASID_MASK;
297 write_c0_entryhi(address | asid); 320 write_c0_entryhi(address | asid);
@@ -310,7 +333,7 @@ static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma,
310 else 333 else
311 tlb_write_indexed(); 334 tlb_write_indexed();
312 tlbw_use_hazard(); 335 tlbw_use_hazard();
313 local_irq_restore(flags); 336 EXIT_CRITICAL(flags);
314} 337}
315#endif 338#endif
316 339
@@ -322,7 +345,7 @@ void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
322 unsigned long old_pagemask; 345 unsigned long old_pagemask;
323 unsigned long old_ctx; 346 unsigned long old_ctx;
324 347
325 local_irq_save(flags); 348 ENTER_CRITICAL(flags);
326 /* Save old context and create impossible VPN2 value */ 349 /* Save old context and create impossible VPN2 value */
327 old_ctx = read_c0_entryhi(); 350 old_ctx = read_c0_entryhi();
328 old_pagemask = read_c0_pagemask(); 351 old_pagemask = read_c0_pagemask();
@@ -342,7 +365,7 @@ void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
342 BARRIER; 365 BARRIER;
343 write_c0_pagemask(old_pagemask); 366 write_c0_pagemask(old_pagemask);
344 local_flush_tlb_all(); 367 local_flush_tlb_all();
345 local_irq_restore(flags); 368 EXIT_CRITICAL(flags);
346} 369}
347 370
348/* 371/*
@@ -362,7 +385,7 @@ __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
362 unsigned long old_pagemask; 385 unsigned long old_pagemask;
363 unsigned long old_ctx; 386 unsigned long old_ctx;
364 387
365 local_irq_save(flags); 388 ENTER_CRITICAL(flags);
366 /* Save old context and create impossible VPN2 value */ 389 /* Save old context and create impossible VPN2 value */
367 old_ctx = read_c0_entryhi(); 390 old_ctx = read_c0_entryhi();
368 old_pagemask = read_c0_pagemask(); 391 old_pagemask = read_c0_pagemask();
@@ -386,10 +409,11 @@ __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
386 write_c0_entryhi(old_ctx); 409 write_c0_entryhi(old_ctx);
387 write_c0_pagemask(old_pagemask); 410 write_c0_pagemask(old_pagemask);
388out: 411out:
389 local_irq_restore(flags); 412 EXIT_CRITICAL(flags);
390 return ret; 413 return ret;
391} 414}
392 415
416extern void __init sanitize_tlb_entries(void);
393static void __init probe_tlb(unsigned long config) 417static void __init probe_tlb(unsigned long config)
394{ 418{
395 struct cpuinfo_mips *c = &current_cpu_data; 419 struct cpuinfo_mips *c = &current_cpu_data;
@@ -402,6 +426,14 @@ static void __init probe_tlb(unsigned long config)
402 */ 426 */
403 if ((c->processor_id & 0xff0000) == PRID_COMP_LEGACY) 427 if ((c->processor_id & 0xff0000) == PRID_COMP_LEGACY)
404 return; 428 return;
429#ifdef CONFIG_MIPS_MT_SMTC
430 /*
431 * If TLB is shared in SMTC system, total size already
432 * has been calculated and written into cpu_data tlbsize
433 */
434 if((smtc_status & SMTC_TLB_SHARED) == SMTC_TLB_SHARED)
435 return;
436#endif /* CONFIG_MIPS_MT_SMTC */
405 437
406 reg = read_c0_config1(); 438 reg = read_c0_config1();
407 if (!((config >> 7) & 3)) 439 if (!((config >> 7) & 3))
@@ -410,6 +442,15 @@ static void __init probe_tlb(unsigned long config)
410 c->tlbsize = ((reg >> 25) & 0x3f) + 1; 442 c->tlbsize = ((reg >> 25) & 0x3f) + 1;
411} 443}
412 444
445static int __initdata ntlb = 0;
446static int __init set_ntlb(char *str)
447{
448 get_option(&str, &ntlb);
449 return 1;
450}
451
452__setup("ntlb=", set_ntlb);
453
413void __init tlb_init(void) 454void __init tlb_init(void)
414{ 455{
415 unsigned int config = read_c0_config(); 456 unsigned int config = read_c0_config();
@@ -432,5 +473,15 @@ void __init tlb_init(void)
432 473
433 /* Did I tell you that ARC SUCKS? */ 474 /* Did I tell you that ARC SUCKS? */
434 475
476 if (ntlb) {
477 if (ntlb > 1 && ntlb <= current_cpu_data.tlbsize) {
478 int wired = current_cpu_data.tlbsize - ntlb;
479 write_c0_wired(wired);
480 write_c0_index(wired-1);
481 printk ("Restricting TLB to %d entries\n", ntlb);
482 } else
483 printk("Ignoring invalid argument ntlb=%d\n", ntlb);
484 }
485
435 build_tlb_refill_handler(); 486 build_tlb_refill_handler();
436} 487}
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 599b3c297186..053dbacac56b 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -7,6 +7,16 @@
7 * 7 *
8 * Copyright (C) 2004,2005 by Thiemo Seufer 8 * Copyright (C) 2004,2005 by Thiemo Seufer
9 * Copyright (C) 2005 Maciej W. Rozycki 9 * Copyright (C) 2005 Maciej W. Rozycki
10 * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
11 *
12 * ... and the days got worse and worse and now you see
13 * I've gone completly out of my mind.
14 *
15 * They're coming to take me a away haha
16 * they're coming to take me a away hoho hihi haha
17 * to the funny farm where code is beautiful all the time ...
18 *
19 * (Condolences to Napoleon XIV)
10 */ 20 */
11 21
12#include <stdarg.h> 22#include <stdarg.h>
@@ -68,6 +78,7 @@ enum fields
68 BIMM = 0x040, 78 BIMM = 0x040,
69 JIMM = 0x080, 79 JIMM = 0x080,
70 FUNC = 0x100, 80 FUNC = 0x100,
81 SET = 0x200
71}; 82};
72 83
73#define OP_MASK 0x2f 84#define OP_MASK 0x2f
@@ -86,6 +97,8 @@ enum fields
86#define JIMM_SH 0 97#define JIMM_SH 0
87#define FUNC_MASK 0x2f 98#define FUNC_MASK 0x2f
88#define FUNC_SH 0 99#define FUNC_SH 0
100#define SET_MASK 0x7
101#define SET_SH 0
89 102
90enum opcode { 103enum opcode {
91 insn_invalid, 104 insn_invalid,
@@ -129,8 +142,8 @@ static __initdata struct insn insn_table[] = {
129 { insn_bne, M(bne_op,0,0,0,0,0), RS | RT | BIMM }, 142 { insn_bne, M(bne_op,0,0,0,0,0), RS | RT | BIMM },
130 { insn_daddiu, M(daddiu_op,0,0,0,0,0), RS | RT | SIMM }, 143 { insn_daddiu, M(daddiu_op,0,0,0,0,0), RS | RT | SIMM },
131 { insn_daddu, M(spec_op,0,0,0,0,daddu_op), RS | RT | RD }, 144 { insn_daddu, M(spec_op,0,0,0,0,daddu_op), RS | RT | RD },
132 { insn_dmfc0, M(cop0_op,dmfc_op,0,0,0,0), RT | RD }, 145 { insn_dmfc0, M(cop0_op,dmfc_op,0,0,0,0), RT | RD | SET},
133 { insn_dmtc0, M(cop0_op,dmtc_op,0,0,0,0), RT | RD }, 146 { insn_dmtc0, M(cop0_op,dmtc_op,0,0,0,0), RT | RD | SET},
134 { insn_dsll, M(spec_op,0,0,0,0,dsll_op), RT | RD | RE }, 147 { insn_dsll, M(spec_op,0,0,0,0,dsll_op), RT | RD | RE },
135 { insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE }, 148 { insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE },
136 { insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE }, 149 { insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE },
@@ -145,8 +158,8 @@ static __initdata struct insn insn_table[] = {
145 { insn_lld, M(lld_op,0,0,0,0,0), RS | RT | SIMM }, 158 { insn_lld, M(lld_op,0,0,0,0,0), RS | RT | SIMM },
146 { insn_lui, M(lui_op,0,0,0,0,0), RT | SIMM }, 159 { insn_lui, M(lui_op,0,0,0,0,0), RT | SIMM },
147 { insn_lw, M(lw_op,0,0,0,0,0), RS | RT | SIMM }, 160 { insn_lw, M(lw_op,0,0,0,0,0), RS | RT | SIMM },
148 { insn_mfc0, M(cop0_op,mfc_op,0,0,0,0), RT | RD }, 161 { insn_mfc0, M(cop0_op,mfc_op,0,0,0,0), RT | RD | SET},
149 { insn_mtc0, M(cop0_op,mtc_op,0,0,0,0), RT | RD }, 162 { insn_mtc0, M(cop0_op,mtc_op,0,0,0,0), RT | RD | SET},
150 { insn_ori, M(ori_op,0,0,0,0,0), RS | RT | UIMM }, 163 { insn_ori, M(ori_op,0,0,0,0,0), RS | RT | UIMM },
151 { insn_rfe, M(cop0_op,cop_op,0,0,0,rfe_op), 0 }, 164 { insn_rfe, M(cop0_op,cop_op,0,0,0,rfe_op), 0 },
152 { insn_sc, M(sc_op,0,0,0,0,0), RS | RT | SIMM }, 165 { insn_sc, M(sc_op,0,0,0,0,0), RS | RT | SIMM },
@@ -242,6 +255,14 @@ static __init u32 build_func(u32 arg)
242 return arg & FUNC_MASK; 255 return arg & FUNC_MASK;
243} 256}
244 257
258static __init u32 build_set(u32 arg)
259{
260 if (arg & ~SET_MASK)
261 printk(KERN_WARNING "TLB synthesizer field overflow\n");
262
263 return arg & SET_MASK;
264}
265
245/* 266/*
246 * The order of opcode arguments is implicitly left to right, 267 * The order of opcode arguments is implicitly left to right,
247 * starting with RS and ending with FUNC or IMM. 268 * starting with RS and ending with FUNC or IMM.
@@ -273,6 +294,7 @@ static void __init build_insn(u32 **buf, enum opcode opc, ...)
273 if (ip->fields & BIMM) op |= build_bimm(va_arg(ap, s32)); 294 if (ip->fields & BIMM) op |= build_bimm(va_arg(ap, s32));
274 if (ip->fields & JIMM) op |= build_jimm(va_arg(ap, u32)); 295 if (ip->fields & JIMM) op |= build_jimm(va_arg(ap, u32));
275 if (ip->fields & FUNC) op |= build_func(va_arg(ap, u32)); 296 if (ip->fields & FUNC) op |= build_func(va_arg(ap, u32));
297 if (ip->fields & SET) op |= build_set(va_arg(ap, u32));
276 va_end(ap); 298 va_end(ap);
277 299
278 **buf = op; 300 **buf = op;
@@ -358,8 +380,8 @@ I_u1s2(_bgezl);
358I_u1s2(_bltz); 380I_u1s2(_bltz);
359I_u1s2(_bltzl); 381I_u1s2(_bltzl);
360I_u1u2s3(_bne); 382I_u1u2s3(_bne);
361I_u1u2(_dmfc0); 383I_u1u2u3(_dmfc0);
362I_u1u2(_dmtc0); 384I_u1u2u3(_dmtc0);
363I_u2u1s3(_daddiu); 385I_u2u1s3(_daddiu);
364I_u3u1u2(_daddu); 386I_u3u1u2(_daddu);
365I_u2u1u3(_dsll); 387I_u2u1u3(_dsll);
@@ -376,8 +398,8 @@ I_u2s3u1(_ll);
376I_u2s3u1(_lld); 398I_u2s3u1(_lld);
377I_u1s2(_lui); 399I_u1s2(_lui);
378I_u2s3u1(_lw); 400I_u2s3u1(_lw);
379I_u1u2(_mfc0); 401I_u1u2u3(_mfc0);
380I_u1u2(_mtc0); 402I_u1u2u3(_mtc0);
381I_u2u1u3(_ori); 403I_u2u1u3(_ori);
382I_0(_rfe); 404I_0(_rfe);
383I_u2s3u1(_sc); 405I_u2s3u1(_sc);
@@ -451,8 +473,8 @@ L_LA(_r3000_write_probe_fail)
451# define i_SLL(buf, rs, rt, sh) i_dsll(buf, rs, rt, sh) 473# define i_SLL(buf, rs, rt, sh) i_dsll(buf, rs, rt, sh)
452# define i_SRA(buf, rs, rt, sh) i_dsra(buf, rs, rt, sh) 474# define i_SRA(buf, rs, rt, sh) i_dsra(buf, rs, rt, sh)
453# define i_SRL(buf, rs, rt, sh) i_dsrl(buf, rs, rt, sh) 475# define i_SRL(buf, rs, rt, sh) i_dsrl(buf, rs, rt, sh)
454# define i_MFC0(buf, rt, rd) i_dmfc0(buf, rt, rd) 476# define i_MFC0(buf, rt, rd...) i_dmfc0(buf, rt, rd)
455# define i_MTC0(buf, rt, rd) i_dmtc0(buf, rt, rd) 477# define i_MTC0(buf, rt, rd...) i_dmtc0(buf, rt, rd)
456# define i_ADDIU(buf, rs, rt, val) i_daddiu(buf, rs, rt, val) 478# define i_ADDIU(buf, rs, rt, val) i_daddiu(buf, rs, rt, val)
457# define i_ADDU(buf, rs, rt, rd) i_daddu(buf, rs, rt, rd) 479# define i_ADDU(buf, rs, rt, rd) i_daddu(buf, rs, rt, rd)
458# define i_SUBU(buf, rs, rt, rd) i_dsubu(buf, rs, rt, rd) 480# define i_SUBU(buf, rs, rt, rd) i_dsubu(buf, rs, rt, rd)
@@ -464,8 +486,8 @@ L_LA(_r3000_write_probe_fail)
464# define i_SLL(buf, rs, rt, sh) i_sll(buf, rs, rt, sh) 486# define i_SLL(buf, rs, rt, sh) i_sll(buf, rs, rt, sh)
465# define i_SRA(buf, rs, rt, sh) i_sra(buf, rs, rt, sh) 487# define i_SRA(buf, rs, rt, sh) i_sra(buf, rs, rt, sh)
466# define i_SRL(buf, rs, rt, sh) i_srl(buf, rs, rt, sh) 488# define i_SRL(buf, rs, rt, sh) i_srl(buf, rs, rt, sh)
467# define i_MFC0(buf, rt, rd) i_mfc0(buf, rt, rd) 489# define i_MFC0(buf, rt, rd...) i_mfc0(buf, rt, rd)
468# define i_MTC0(buf, rt, rd) i_mtc0(buf, rt, rd) 490# define i_MTC0(buf, rt, rd...) i_mtc0(buf, rt, rd)
469# define i_ADDIU(buf, rs, rt, val) i_addiu(buf, rs, rt, val) 491# define i_ADDIU(buf, rs, rt, val) i_addiu(buf, rs, rt, val)
470# define i_ADDU(buf, rs, rt, rd) i_addu(buf, rs, rt, rd) 492# define i_ADDU(buf, rs, rt, rd) i_addu(buf, rs, rt, rd)
471# define i_SUBU(buf, rs, rt, rd) i_subu(buf, rs, rt, rd) 493# define i_SUBU(buf, rs, rt, rd) i_subu(buf, rs, rt, rd)
@@ -670,14 +692,15 @@ static void __init il_bgezl(u32 **p, struct reloc **r, unsigned int reg,
670#define K1 27 692#define K1 27
671 693
672/* Some CP0 registers */ 694/* Some CP0 registers */
673#define C0_INDEX 0 695#define C0_INDEX 0, 0
674#define C0_ENTRYLO0 2 696#define C0_ENTRYLO0 2, 0
675#define C0_ENTRYLO1 3 697#define C0_TCBIND 2, 2
676#define C0_CONTEXT 4 698#define C0_ENTRYLO1 3, 0
677#define C0_BADVADDR 8 699#define C0_CONTEXT 4, 0
678#define C0_ENTRYHI 10 700#define C0_BADVADDR 8, 0
679#define C0_EPC 14 701#define C0_ENTRYHI 10, 0
680#define C0_XCONTEXT 20 702#define C0_EPC 14, 0
703#define C0_XCONTEXT 20, 0
681 704
682#ifdef CONFIG_64BIT 705#ifdef CONFIG_64BIT
683# define GET_CONTEXT(buf, reg) i_MFC0(buf, reg, C0_XCONTEXT) 706# define GET_CONTEXT(buf, reg) i_MFC0(buf, reg, C0_XCONTEXT)
@@ -742,7 +765,7 @@ static void __init build_r3000_tlb_refill_handler(void)
742 } 765 }
743#endif 766#endif
744 767
745 memcpy((void *)CAC_BASE, tlb_handler, 0x80); 768 memcpy((void *)ebase, tlb_handler, 0x80);
746} 769}
747 770
748/* 771/*
@@ -951,12 +974,20 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r,
951 /* No i_nop needed here, since the next insn doesn't touch TMP. */ 974 /* No i_nop needed here, since the next insn doesn't touch TMP. */
952 975
953#ifdef CONFIG_SMP 976#ifdef CONFIG_SMP
977# ifdef CONFIG_MIPS_MT_SMTC
978 /*
979 * SMTC uses TCBind value as "CPU" index
980 */
981 i_mfc0(p, ptr, C0_TCBIND);
982 i_dsrl(p, ptr, ptr, 19);
983# else
954 /* 984 /*
955 * 64 bit SMP running in XKPHYS has smp_processor_id() << 3 985 * 64 bit SMP running in XKPHYS has smp_processor_id() << 3
956 * stored in CONTEXT. 986 * stored in CONTEXT.
957 */ 987 */
958 i_dmfc0(p, ptr, C0_CONTEXT); 988 i_dmfc0(p, ptr, C0_CONTEXT);
959 i_dsrl(p, ptr, ptr, 23); 989 i_dsrl(p, ptr, ptr, 23);
990#endif
960 i_LA_mostly(p, tmp, pgdc); 991 i_LA_mostly(p, tmp, pgdc);
961 i_daddu(p, ptr, ptr, tmp); 992 i_daddu(p, ptr, ptr, tmp);
962 i_dmfc0(p, tmp, C0_BADVADDR); 993 i_dmfc0(p, tmp, C0_BADVADDR);
@@ -1014,9 +1045,21 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
1014 1045
1015 /* 32 bit SMP has smp_processor_id() stored in CONTEXT. */ 1046 /* 32 bit SMP has smp_processor_id() stored in CONTEXT. */
1016#ifdef CONFIG_SMP 1047#ifdef CONFIG_SMP
1048#ifdef CONFIG_MIPS_MT_SMTC
1049 /*
1050 * SMTC uses TCBind value as "CPU" index
1051 */
1052 i_mfc0(p, ptr, C0_TCBIND);
1053 i_LA_mostly(p, tmp, pgdc);
1054 i_srl(p, ptr, ptr, 19);
1055#else
1056 /*
1057 * smp_processor_id() << 3 is stored in CONTEXT.
1058 */
1017 i_mfc0(p, ptr, C0_CONTEXT); 1059 i_mfc0(p, ptr, C0_CONTEXT);
1018 i_LA_mostly(p, tmp, pgdc); 1060 i_LA_mostly(p, tmp, pgdc);
1019 i_srl(p, ptr, ptr, 23); 1061 i_srl(p, ptr, ptr, 23);
1062#endif
1020 i_addu(p, ptr, tmp, ptr); 1063 i_addu(p, ptr, tmp, ptr);
1021#else 1064#else
1022 i_LA_mostly(p, ptr, pgdc); 1065 i_LA_mostly(p, ptr, pgdc);
@@ -1247,7 +1290,7 @@ static void __init build_r4000_tlb_refill_handler(void)
1247 } 1290 }
1248#endif 1291#endif
1249 1292
1250 memcpy((void *)CAC_BASE, final_handler, 0x100); 1293 memcpy((void *)ebase, final_handler, 0x100);
1251} 1294}
1252 1295
1253/* 1296/*
diff --git a/arch/mips/momentum/jaguar_atx/Makefile b/arch/mips/momentum/jaguar_atx/Makefile
index 20bbd3ea44a8..67372f3f9654 100644
--- a/arch/mips/momentum/jaguar_atx/Makefile
+++ b/arch/mips/momentum/jaguar_atx/Makefile
@@ -6,7 +6,7 @@
6# unless it's something special (ie not a .c file). 6# unless it's something special (ie not a .c file).
7# 7#
8 8
9obj-y += int-handler.o irq.o prom.o reset.o setup.o 9obj-y += irq.o prom.o reset.o setup.o
10 10
11obj-$(CONFIG_SERIAL_8250_CONSOLE) += ja-console.o 11obj-$(CONFIG_SERIAL_8250_CONSOLE) += ja-console.o
12obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o 12obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o
diff --git a/arch/mips/momentum/jaguar_atx/int-handler.S b/arch/mips/momentum/jaguar_atx/int-handler.S
deleted file mode 100644
index 55bc789733f2..000000000000
--- a/arch/mips/momentum/jaguar_atx/int-handler.S
+++ /dev/null
@@ -1,128 +0,0 @@
1/*
2 * Copyright 2002 Momentum Computer Inc.
3 * Author: Matthew Dharm <mdharm@momenco.com>
4 *
5 * Based on work:
6 * Copyright 2001 MontaVista Software Inc.
7 * Author: jsun@mvista.com or jsun@junsun.net
8 *
9 * First-level interrupt dispatcher for Jaguar-ATX board.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 */
16#include <asm/asm.h>
17#include <asm/mipsregs.h>
18#include <asm/addrspace.h>
19#include <asm/regdef.h>
20#include <asm/stackframe.h>
21
22/*
23 * First level interrupt dispatcher for Ocelot-CS board
24 */
25 .align 5
26 NESTED(jaguar_handle_int, PT_SIZE, sp)
27 SAVE_ALL
28 CLI
29 .set at
30 mfc0 t0, CP0_CAUSE
31 mfc0 t2, CP0_STATUS
32
33 and t0, t2
34
35 andi t1, t0, STATUSF_IP0 /* sw0 software interrupt */
36 bnez t1, ll_sw0_irq
37 andi t1, t0, STATUSF_IP1 /* sw1 software interrupt */
38 bnez t1, ll_sw1_irq
39 andi t1, t0, STATUSF_IP2 /* int0 hardware line */
40 bnez t1, ll_pcixa_irq
41 andi t1, t0, STATUSF_IP3 /* int1 hardware line */
42 bnez t1, ll_pcixb_irq
43 andi t1, t0, STATUSF_IP4 /* int2 hardware line */
44 bnez t1, ll_pcia_irq
45 andi t1, t0, STATUSF_IP5 /* int3 hardware line */
46 bnez t1, ll_pcib_irq
47 andi t1, t0, STATUSF_IP6 /* int4 hardware line */
48 bnez t1, ll_uart_irq
49 andi t1, t0, STATUSF_IP7 /* cpu timer */
50 bnez t1, ll_cputimer_irq
51
52 nop
53 nop
54
55 /* now look at extended interrupts */
56 mfc0 t0, CP0_CAUSE
57 cfc0 t1, CP0_S1_INTCONTROL
58
59 /* shift the mask 8 bits left to line up the bits */
60 sll t2, t1, 8
61
62 and t0, t2
63 srl t0, t0, 16
64
65 andi t1, t0, STATUSF_IP8 /* int6 hardware line */
66 bnez t1, ll_mv64340_decode_irq
67
68 nop
69 nop
70
71 .set reorder
72
73 /* wrong alarm or masked ... */
74 j spurious_interrupt
75 nop
76 END(jaguar_handle_int)
77
78 .align 5
79ll_sw0_irq:
80 li a0, 0
81 move a1, sp
82 jal do_IRQ
83 j ret_from_irq
84ll_sw1_irq:
85 li a0, 1
86 move a1, sp
87 jal do_IRQ
88 j ret_from_irq
89ll_pcixa_irq:
90 li a0, 2
91 move a1, sp
92 jal do_IRQ
93 j ret_from_irq
94
95ll_pcixb_irq:
96 li a0, 3
97 move a1, sp
98 jal do_IRQ
99 j ret_from_irq
100
101ll_pcia_irq:
102 li a0, 4
103 move a1, sp
104 jal do_IRQ
105 j ret_from_irq
106
107ll_pcib_irq:
108 li a0, 5
109 move a1, sp
110 jal do_IRQ
111 j ret_from_irq
112
113ll_uart_irq:
114 li a0, 6
115 move a1, sp
116 jal do_IRQ
117 j ret_from_irq
118
119ll_cputimer_irq:
120 li a0, 7
121 move a1, sp
122 jal ll_timer_interrupt
123 j ret_from_irq
124
125ll_mv64340_decode_irq:
126 move a0, sp
127 jal ll_mv64340_irq
128 j ret_from_irq
diff --git a/arch/mips/momentum/jaguar_atx/irq.c b/arch/mips/momentum/jaguar_atx/irq.c
index 15588f91ace2..ec4032b38f19 100644
--- a/arch/mips/momentum/jaguar_atx/irq.c
+++ b/arch/mips/momentum/jaguar_atx/irq.c
@@ -10,7 +10,7 @@
10 * Copyright 2001 MontaVista Software Inc. 10 * Copyright 2001 MontaVista Software Inc.
11 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net 11 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
12 * 12 *
13 * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) 13 * Copyright (C) 2000, 01, 06 Ralf Baechle (ralf@linux-mips.org)
14 * 14 *
15 * This program is free software; you can redistribute it and/or modify it 15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the 16 * under the terms of the GNU General Public License as published by the
@@ -38,8 +38,37 @@
38#include <linux/types.h> 38#include <linux/types.h>
39#include <asm/irq_cpu.h> 39#include <asm/irq_cpu.h>
40#include <asm/mipsregs.h> 40#include <asm/mipsregs.h>
41#include <asm/time.h>
41 42
42extern asmlinkage void jaguar_handle_int(void); 43asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
44{
45 unsigned int pending = read_c0_cause() & read_c0_status();
46
47 if (pending & STATUSF_IP0)
48 do_IRQ(0, regs);
49 else if (pending & STATUSF_IP1)
50 do_IRQ(1, regs);
51 else if (pending & STATUSF_IP2)
52 do_IRQ(2, regs);
53 else if (pending & STATUSF_IP3)
54 do_IRQ(3, regs);
55 else if (pending & STATUSF_IP4)
56 do_IRQ(4, regs);
57 else if (pending & STATUSF_IP5)
58 do_IRQ(5, regs);
59 else if (pending & STATUSF_IP6)
60 do_IRQ(6, regs);
61 else if (pending & STATUSF_IP7)
62 ll_timer_interrupt(7, regs);
63 else {
64 /*
65 * Now look at the extended interrupts
66 */
67 pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16;
68 if (pending & STATUSF_IP8)
69 ll_mv64340_irq(regs);
70 }
71}
43 72
44static struct irqaction cascade_mv64340 = { 73static struct irqaction cascade_mv64340 = {
45 no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL 74 no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL
@@ -53,8 +82,6 @@ void __init arch_init_irq(void)
53 */ 82 */
54 clear_c0_status(ST0_IM); 83 clear_c0_status(ST0_IM);
55 84
56 /* Sets the first-level interrupt dispatcher. */
57 set_except_vector(0, jaguar_handle_int);
58 mips_cpu_irq_init(0); 85 mips_cpu_irq_init(0);
59 rm7k_cpu_irq_init(8); 86 rm7k_cpu_irq_init(8);
60 87
diff --git a/arch/mips/momentum/jaguar_atx/setup.c b/arch/mips/momentum/jaguar_atx/setup.c
index 91d9637143d7..1379c76845dc 100644
--- a/arch/mips/momentum/jaguar_atx/setup.c
+++ b/arch/mips/momentum/jaguar_atx/setup.c
@@ -381,24 +381,24 @@ void __init plat_setup(void)
381 * shut down ethernet ports, just to be sure our memory doesn't get 381 * shut down ethernet ports, just to be sure our memory doesn't get
382 * corrupted by random ethernet traffic. 382 * corrupted by random ethernet traffic.
383 */ 383 */
384 MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8); 384 MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8);
385 MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8); 385 MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8);
386 MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(2), 0xff << 8); 386 MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(2), 0xff << 8);
387 MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8); 387 MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8);
388 MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8); 388 MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8);
389 MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(2), 0xff << 8); 389 MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(2), 0xff << 8);
390 while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff); 390 while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff);
391 while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff); 391 while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff);
392 while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(2)) & 0xff); 392 while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(2)) & 0xff);
393 while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff); 393 while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff);
394 while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff); 394 while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff);
395 while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(2)) & 0xff); 395 while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(2)) & 0xff);
396 MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0), 396 MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0),
397 MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1); 397 MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1);
398 MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1), 398 MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1),
399 MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1); 399 MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1);
400 MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(2), 400 MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(2),
401 MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(2)) & ~1); 401 MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(2)) & ~1);
402 402
403 /* Turn off the Bit-Error LED */ 403 /* Turn off the Bit-Error LED */
404 JAGUAR_FPGA_WRITE(0x80, CLR); 404 JAGUAR_FPGA_WRITE(0x80, CLR);
diff --git a/arch/mips/momentum/ocelot_3/Makefile b/arch/mips/momentum/ocelot_3/Makefile
index aab8fd89f830..8bcea64dd27b 100644
--- a/arch/mips/momentum/ocelot_3/Makefile
+++ b/arch/mips/momentum/ocelot_3/Makefile
@@ -5,4 +5,4 @@
5# removes any old dependencies. DON'T put your own dependencies here 5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file). 6# unless it's something special (ie not a .c file).
7# 7#
8obj-y += int-handler.o irq.o prom.o reset.o setup.o 8obj-y += irq.o prom.o reset.o setup.o
diff --git a/arch/mips/momentum/ocelot_3/int-handler.S b/arch/mips/momentum/ocelot_3/int-handler.S
deleted file mode 100644
index 4522f09ed769..000000000000
--- a/arch/mips/momentum/ocelot_3/int-handler.S
+++ /dev/null
@@ -1,137 +0,0 @@
1/*
2 * Copyright 2002 Momentum Computer Inc.
3 * Author: Matthew Dharm <mdharm@momenco.com>
4 *
5 * Copyright 2001 MontaVista Software Inc.
6 * Author: jsun@mvista.com or jsun@junsun.net
7 *
8 * Copyright 2004 PMC-Sierra
9 * Author: Manish Lachwani (lachwani@pmc-sierra.com)
10 *
11 * Copyright (C) 2004 MontaVista Software Inc.
12 * Author: Manish Lachwani, mlachwani@mvista.com
13 *
14 * First-level interrupt dispatcher for Ocelot-3 board.
15 *
16 * This program is free software; you can redistribute it and/or modify it
17 * under the terms of the GNU General Public License as published by the
18 * Free Software Foundation; either version 2 of the License, or (at your
19 * option) any later version.
20 */
21#include <asm/asm.h>
22#include <asm/mipsregs.h>
23#include <asm/addrspace.h>
24#include <asm/regdef.h>
25#include <asm/stackframe.h>
26
27/*
28 * First level interrupt dispatcher for Ocelot-3 board
29 */
30 .align 5
31 NESTED(ocelot3_handle_int, PT_SIZE, sp)
32 SAVE_ALL
33 CLI
34 .set at
35
36 mfc0 t0, CP0_CAUSE
37 mfc0 t2, CP0_STATUS
38
39 and t0, t2
40
41 andi t1, t0, STATUSF_IP0 /* sw0 software interrupt (IRQ0) */
42 bnez t1, ll_sw0_irq
43
44 andi t1, t0, STATUSF_IP1 /* sw1 software interrupt (IRQ1) */
45 bnez t1, ll_sw1_irq
46
47 andi t1, t0, STATUSF_IP2 /* int0 hardware line (IRQ2) */
48 bnez t1, ll_pci0slot1_irq
49
50 andi t1, t0, STATUSF_IP3 /* int1 hardware line (IRQ3) */
51 bnez t1, ll_pci0slot2_irq
52
53 andi t1, t0, STATUSF_IP4 /* int2 hardware line (IRQ4) */
54 bnez t1, ll_pci1slot1_irq
55
56 andi t1, t0, STATUSF_IP5 /* int3 hardware line (IRQ5) */
57 bnez t1, ll_pci1slot2_irq
58
59 andi t1, t0, STATUSF_IP6 /* int4 hardware line (IRQ6) */
60 bnez t1, ll_uart_irq
61
62 andi t1, t0, STATUSF_IP7 /* cpu timer (IRQ7) */
63 bnez t1, ll_cputimer_irq
64
65 /* now look at extended interrupts */
66 mfc0 t0, CP0_CAUSE
67 cfc0 t1, CP0_S1_INTCONTROL
68
69 /* shift the mask 8 bits left to line up the bits */
70 sll t2, t1, 8
71
72 and t0, t2
73 srl t0, t0, 16
74
75 andi t1, t0, STATUSF_IP8 /* int6 hardware line (IRQ9) */
76 bnez t1, ll_mv64340_decode_irq
77
78 .set reorder
79
80 /* wrong alarm or masked ... */
81 j spurious_interrupt
82 nop
83 END(ocelot3_handle_int)
84
85 .align 5
86ll_sw0_irq:
87 li a0, 0 /* IRQ 1 */
88 move a1, sp
89 jal do_IRQ
90 j ret_from_irq
91ll_sw1_irq:
92 li a0, 1 /* IRQ 2 */
93 move a1, sp
94 jal do_IRQ
95 j ret_from_irq
96
97ll_pci0slot1_irq:
98 li a0, 2 /* IRQ 3 */
99 move a1, sp
100 jal do_IRQ
101 j ret_from_irq
102
103ll_pci0slot2_irq:
104 li a0, 3 /* IRQ 4 */
105 move a1, sp
106 jal do_IRQ
107 j ret_from_irq
108
109ll_pci1slot1_irq:
110 li a0, 4 /* IRQ 5 */
111 move a1, sp
112 jal do_IRQ
113 j ret_from_irq
114
115ll_pci1slot2_irq:
116 li a0, 5 /* IRQ 6 */
117 move a1, sp
118 jal do_IRQ
119 j ret_from_irq
120
121ll_uart_irq:
122 li a0, 6 /* IRQ 7 */
123 move a1, sp
124 jal do_IRQ
125 j ret_from_irq
126
127ll_cputimer_irq:
128 li a0, 7 /* IRQ 8 */
129 move a1, sp
130 jal do_IRQ
131 j ret_from_irq
132
133ll_mv64340_decode_irq:
134 move a0, sp
135 jal ll_mv64340_irq
136 j ret_from_irq
137
diff --git a/arch/mips/momentum/ocelot_3/irq.c b/arch/mips/momentum/ocelot_3/irq.c
index 42464dbd4ad2..87c63c340ae3 100644
--- a/arch/mips/momentum/ocelot_3/irq.c
+++ b/arch/mips/momentum/ocelot_3/irq.c
@@ -53,8 +53,6 @@
53#include <asm/mipsregs.h> 53#include <asm/mipsregs.h>
54#include <asm/system.h> 54#include <asm/system.h>
55 55
56extern asmlinkage void ocelot3_handle_int(void);
57
58static struct irqaction cascade_mv64340 = { 56static struct irqaction cascade_mv64340 = {
59 no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL 57 no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL
60}; 58};
@@ -67,9 +65,6 @@ void __init arch_init_irq(void)
67 */ 65 */
68 clear_c0_status(ST0_IM | ST0_BEV); 66 clear_c0_status(ST0_IM | ST0_BEV);
69 67
70 /* Sets the first-level interrupt dispatcher. */
71 set_except_vector(0, ocelot3_handle_int);
72 mips_cpu_irq_init(0);
73 rm7k_cpu_irq_init(8); 68 rm7k_cpu_irq_init(8);
74 69
75 /* set up the cascading interrupts */ 70 /* set up the cascading interrupts */
@@ -79,3 +74,36 @@ void __init arch_init_irq(void)
79 set_c0_status(ST0_IM); /* IE in the status register */ 74 set_c0_status(ST0_IM); /* IE in the status register */
80 75
81} 76}
77
78asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
79{
80 unsigned int pending = read_c0_cause() & read_c0_status();
81
82 if (pending & STATUSF_IP0)
83 do_IRQ(0, regs);
84 else if (pending & STATUSF_IP1)
85 do_IRQ(1, regs);
86 else if (pending & STATUSF_IP2)
87 do_IRQ(2, regs);
88 else if (pending & STATUSF_IP3)
89 do_IRQ(3, regs);
90 else if (pending & STATUSF_IP4)
91 do_IRQ(4, regs);
92 else if (pending & STATUSF_IP5)
93 do_IRQ(5, regs);
94 else if (pending & STATUSF_IP6)
95 do_IRQ(6, regs);
96 else if (pending & STATUSF_IP7)
97 do_IRQ(7, regs);
98 else {
99 /*
100 * Now look at the extended interrupts
101 */
102 pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16;
103
104 if (pending & STATUSF_IP8)
105 ll_mv64340_irq(regs);
106 else
107 spurious_interrupt(regs);
108 }
109}
diff --git a/arch/mips/momentum/ocelot_3/setup.c b/arch/mips/momentum/ocelot_3/setup.c
index 370e75d0e75c..c69195234309 100644
--- a/arch/mips/momentum/ocelot_3/setup.c
+++ b/arch/mips/momentum/ocelot_3/setup.c
@@ -329,22 +329,22 @@ void __init plat_setup(void)
329 /* shut down ethernet ports, just to be sure our memory doesn't get 329 /* shut down ethernet ports, just to be sure our memory doesn't get
330 * corrupted by random ethernet traffic. 330 * corrupted by random ethernet traffic.
331 */ 331 */
332 MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8); 332 MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8);
333 MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8); 333 MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8);
334 MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8); 334 MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8);
335 MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8); 335 MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8);
336 do {} 336 do {}
337 while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff); 337 while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff);
338 do {} 338 do {}
339 while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff); 339 while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff);
340 do {} 340 do {}
341 while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff); 341 while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff);
342 do {} 342 do {}
343 while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff); 343 while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff);
344 MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0), 344 MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0),
345 MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1); 345 MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1);
346 MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1), 346 MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1),
347 MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1); 347 MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1);
348 348
349 /* Turn off the Bit-Error LED */ 349 /* Turn off the Bit-Error LED */
350 OCELOT_FPGA_WRITE(0x80, CLR); 350 OCELOT_FPGA_WRITE(0x80, CLR);
diff --git a/arch/mips/momentum/ocelot_c/Makefile b/arch/mips/momentum/ocelot_c/Makefile
index 91240777f978..94802b4db472 100644
--- a/arch/mips/momentum/ocelot_c/Makefile
+++ b/arch/mips/momentum/ocelot_c/Makefile
@@ -2,7 +2,7 @@
2# Makefile for Momentum Computer's Ocelot-C and -CS boards. 2# Makefile for Momentum Computer's Ocelot-C and -CS boards.
3# 3#
4 4
5obj-y += cpci-irq.o int-handler.o irq.o prom.o reset.o \ 5obj-y += cpci-irq.o irq.o prom.o reset.o \
6 setup.o uart-irq.o 6 setup.o uart-irq.o
7 7
8obj-$(CONFIG_KGDB) += dbg_io.o 8obj-$(CONFIG_KGDB) += dbg_io.o
diff --git a/arch/mips/momentum/ocelot_c/int-handler.S b/arch/mips/momentum/ocelot_c/int-handler.S
deleted file mode 100644
index 52349d9bf1be..000000000000
--- a/arch/mips/momentum/ocelot_c/int-handler.S
+++ /dev/null
@@ -1,102 +0,0 @@
1/*
2 * Copyright 2002 Momentum Computer Inc.
3 * Author: Matthew Dharm <mdharm@momenco.com>
4 *
5 * Copyright 2001 MontaVista Software Inc.
6 * Author: jsun@mvista.com or jsun@junsun.net
7 *
8 * First-level interrupt dispatcher for Ocelot-CS board.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15#include <asm/asm.h>
16#include <asm/mipsregs.h>
17#include <asm/addrspace.h>
18#include <asm/regdef.h>
19#include <asm/stackframe.h>
20#include "ocelot_c_fpga.h"
21
22/*
23 * First level interrupt dispatcher for Ocelot-CS board
24 */
25 .align 5
26 NESTED(ocelot_handle_int, PT_SIZE, sp)
27 SAVE_ALL
28 CLI
29 .set at
30 mfc0 t0, CP0_CAUSE
31 mfc0 t2, CP0_STATUS
32
33 and t0, t2
34
35 andi t1, t0, STATUSF_IP0 /* sw0 software interrupt */
36 bnez t1, ll_sw0_irq
37 andi t1, t0, STATUSF_IP1 /* sw1 software interrupt */
38 bnez t1, ll_sw1_irq
39 andi t1, t0, STATUSF_IP2 /* int0 hardware line */
40 bnez t1, ll_scsi_irq
41 andi t1, t0, STATUSF_IP3 /* int1 hardware line */
42 bnez t1, ll_uart_decode_irq
43 andi t1, t0, STATUSF_IP4 /* int2 hardware line */
44 bnez t1, ll_pmc_irq
45 andi t1, t0, STATUSF_IP5 /* int3 hardware line */
46 bnez t1, ll_cpci_decode_irq
47 andi t1, t0, STATUSF_IP6 /* int4 hardware line */
48 bnez t1, ll_mv64340_decode_irq
49 andi t1, t0, STATUSF_IP7 /* cpu timer */
50 bnez t1, ll_cputimer_irq
51
52 .set reorder
53
54 /* wrong alarm or masked ... */
55 j spurious_interrupt
56 nop
57 END(ocelot_handle_int)
58
59 .align 5
60ll_sw0_irq:
61 li a0, 0
62 move a1, sp
63 jal do_IRQ
64 j ret_from_irq
65ll_sw1_irq:
66 li a0, 1
67 move a1, sp
68 jal do_IRQ
69 j ret_from_irq
70ll_scsi_irq:
71 li a0, 2
72 move a1, sp
73 jal do_IRQ
74 j ret_from_irq
75
76ll_uart_decode_irq:
77 move a0, sp
78 jal ll_uart_irq
79 j ret_from_irq
80
81ll_pmc_irq:
82 li a0, 4
83 move a1, sp
84 jal do_IRQ
85 j ret_from_irq
86
87ll_cpci_decode_irq:
88 move a0, sp
89 jal ll_cpci_irq
90 j ret_from_irq
91
92ll_mv64340_decode_irq:
93 move a0, sp
94 jal ll_mv64340_irq
95 j ret_from_irq
96
97ll_cputimer_irq:
98 li a0, 7
99 move a1, sp
100 jal do_IRQ
101 j ret_from_irq
102
diff --git a/arch/mips/momentum/ocelot_c/irq.c b/arch/mips/momentum/ocelot_c/irq.c
index a5764bc20e36..86f61ce59e53 100644
--- a/arch/mips/momentum/ocelot_c/irq.c
+++ b/arch/mips/momentum/ocelot_c/irq.c
@@ -48,7 +48,6 @@
48#include <asm/mipsregs.h> 48#include <asm/mipsregs.h>
49#include <asm/system.h> 49#include <asm/system.h>
50 50
51extern asmlinkage void ocelot_handle_int(void);
52extern void uart_irq_init(void); 51extern void uart_irq_init(void);
53extern void cpci_irq_init(void); 52extern void cpci_irq_init(void);
54 53
@@ -60,6 +59,33 @@ static struct irqaction cascade_mv64340 = {
60 no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade via MV64340", NULL, NULL 59 no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade via MV64340", NULL, NULL
61}; 60};
62 61
62extern void ll_uart_irq(struct pt_regs *regs);
63extern void ll_cpci_irq(struct pt_regs *regs);
64
65asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
66{
67 unsigned int pending = read_c0_cause() & read_c0_status();
68
69 if (pending & STATUSF_IP0)
70 do_IRQ(0, regs);
71 else if (pending & STATUSF_IP1)
72 do_IRQ(1, regs);
73 else if (pending & STATUSF_IP2)
74 do_IRQ(2, regs);
75 else if (pending & STATUSF_IP3)
76 ll_uart_irq(regs);
77 else if (pending & STATUSF_IP4)
78 do_IRQ(4, regs);
79 else if (pending & STATUSF_IP5)
80 ll_cpci_irq(regs);
81 else if (pending & STATUSF_IP6)
82 ll_mv64340_irq(regs);
83 else if (pending & STATUSF_IP7)
84 do_IRQ(7, regs);
85 else
86 spurious_interrupt(regs);
87}
88
63void __init arch_init_irq(void) 89void __init arch_init_irq(void)
64{ 90{
65 /* 91 /*
@@ -68,8 +94,6 @@ void __init arch_init_irq(void)
68 */ 94 */
69 clear_c0_status(ST0_IM); 95 clear_c0_status(ST0_IM);
70 96
71 /* Sets the first-level interrupt dispatcher. */
72 set_except_vector(0, ocelot_handle_int);
73 mips_cpu_irq_init(0); 97 mips_cpu_irq_init(0);
74 98
75 /* set up the cascading interrupts */ 99 /* set up the cascading interrupts */
diff --git a/arch/mips/momentum/ocelot_g/Makefile b/arch/mips/momentum/ocelot_g/Makefile
index e5f1cb086973..adb5665d40a9 100644
--- a/arch/mips/momentum/ocelot_g/Makefile
+++ b/arch/mips/momentum/ocelot_g/Makefile
@@ -2,7 +2,7 @@
2# Makefile for Momentum Computer's Ocelot-G board. 2# Makefile for Momentum Computer's Ocelot-G board.
3# 3#
4 4
5obj-y += int-handler.o irq.o gt-irq.o prom.o reset.o setup.o 5obj-y += irq.o gt-irq.o prom.o reset.o setup.o
6obj-$(CONFIG_KGDB) += dbg_io.o 6obj-$(CONFIG_KGDB) += dbg_io.o
7 7
8EXTRA_AFLAGS := $(CFLAGS) 8EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/momentum/ocelot_g/int-handler.S b/arch/mips/momentum/ocelot_g/int-handler.S
deleted file mode 100644
index 772e8f713176..000000000000
--- a/arch/mips/momentum/ocelot_g/int-handler.S
+++ /dev/null
@@ -1,131 +0,0 @@
1/*
2 * Copyright 2001 MontaVista Software Inc.
3 * Author: jsun@mvista.com or jsun@junsun.net
4 *
5 * First-level interrupt dispatcher for ocelot board.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12#include <asm/asm.h>
13#include <asm/mipsregs.h>
14#include <asm/addrspace.h>
15#include <asm/regdef.h>
16#include <asm/stackframe.h>
17
18/*
19 * first level interrupt dispatcher for ocelot board -
20 * We check for the timer first, then check PCI ints A and D.
21 * Then check for serial IRQ and fall through.
22 */
23 .align 5
24 NESTED(ocelot_handle_int, PT_SIZE, sp)
25 SAVE_ALL
26 CLI
27 .set at
28 mfc0 t0, CP0_CAUSE
29 mfc0 t2, CP0_STATUS
30
31 and t0, t2
32
33 andi t1, t0, STATUSF_IP2 /* int0 hardware line */
34 bnez t1, ll_pri_enet_irq
35 andi t1, t0, STATUSF_IP3 /* int1 hardware line */
36 bnez t1, ll_sec_enet_irq
37 andi t1, t0, STATUSF_IP4 /* int2 hardware line */
38 bnez t1, ll_uart_irq
39 andi t1, t0, STATUSF_IP5 /* int3 hardware line */
40 bnez t1, ll_cpci_irq
41 andi t1, t0, STATUSF_IP6 /* int4 hardware line */
42 bnez t1, ll_galileo_p0_irq
43 andi t1, t0, STATUSF_IP7 /* cpu timer */
44 bnez t1, ll_cputimer_irq
45
46 /* now look at the extended interrupts */
47 mfc0 t0, CP0_CAUSE
48 cfc0 t1, CP0_S1_INTCONTROL
49
50 /* shift the mask 8 bits left to line up the bits */
51 sll t2, t1, 8
52
53 and t0, t2
54 srl t0, t0, 16
55
56 andi t1, t0, STATUSF_IP8 /* int6 hardware line */
57 bnez t1, ll_galileo_p1_irq
58 andi t1, t0, STATUSF_IP9 /* int7 hardware line */
59 bnez t1, ll_pmc_irq
60 andi t1, t0, STATUSF_IP10 /* int8 hardware line */
61 bnez t1, ll_cpci_abcd_irq
62 andi t1, t0, STATUSF_IP11 /* int9 hardware line */
63 bnez t1, ll_testpoint_irq
64
65 .set reorder
66
67 /* wrong alarm or masked ... */
68 j spurious_interrupt
69 nop
70 END(ocelot_handle_int)
71
72 .align 5
73ll_pri_enet_irq:
74 li a0, 2
75 move a1, sp
76 jal do_IRQ
77 j ret_from_irq
78
79ll_sec_enet_irq:
80 li a0, 3
81 move a1, sp
82 jal do_IRQ
83 j ret_from_irq
84
85ll_uart_irq:
86 li a0, 4
87 move a1, sp
88 jal do_IRQ
89 j ret_from_irq
90
91ll_cpci_irq:
92 li a0, 5
93 move a1, sp
94 jal do_IRQ
95 j ret_from_irq
96
97ll_galileo_p0_irq:
98 li a0, 6
99 move a1, sp
100 jal do_IRQ
101 j ret_from_irq
102
103ll_cputimer_irq:
104 li a0, 7
105 move a1, sp
106 jal do_IRQ
107 j ret_from_irq
108
109ll_galileo_p1_irq:
110 li a0, 8
111 move a1, sp
112 jal do_IRQ
113 j ret_from_irq
114
115ll_pmc_irq:
116 li a0, 9
117 move a1, sp
118 jal do_IRQ
119 j ret_from_irq
120
121ll_cpci_abcd_irq:
122 li a0, 10
123 move a1, sp
124 jal do_IRQ
125 j ret_from_irq
126
127ll_testpoint_irq:
128 li a0, 11
129 move a1, sp
130 jal do_IRQ
131 j ret_from_irq
diff --git a/arch/mips/momentum/ocelot_g/irq.c b/arch/mips/momentum/ocelot_g/irq.c
index 5eb85b164205..7a4a419804f1 100644
--- a/arch/mips/momentum/ocelot_g/irq.c
+++ b/arch/mips/momentum/ocelot_g/irq.c
@@ -48,7 +48,41 @@
48#include <asm/mipsregs.h> 48#include <asm/mipsregs.h>
49#include <asm/system.h> 49#include <asm/system.h>
50 50
51extern asmlinkage void ocelot_handle_int(void); 51asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
52{
53 unsigned int pending = read_c0_cause() & read_c0_status();
54
55 if (pending & STATUSF_IP2)
56 do_IRQ(2, regs);
57 else if (pending & STATUSF_IP3)
58 do_IRQ(3, regs);
59 else if (pending & STATUSF_IP4)
60 do_IRQ(4, regs);
61 else if (pending & STATUSF_IP5)
62 do_IRQ(5, regs);
63 else if (pending & STATUSF_IP6)
64 do_IRQ(6, regs);
65 else if (pending & STATUSF_IP7)
66 do_IRQ(7, regs);
67 else {
68 /*
69 * Now look at the extended interrupts
70 */
71 pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16;
72
73 if (pending & STATUSF_IP8)
74 do_IRQ(8, regs);
75 else if (pending & STATUSF_IP9)
76 do_IRQ(9, regs);
77 else if (pending & STATUSF_IP10)
78 do_IRQ(10, regs);
79 else if (pending & STATUSF_IP11)
80 do_IRQ(11, regs);
81 else
82 spurious_interrupt(regs);
83 }
84}
85
52extern void gt64240_irq_init(void); 86extern void gt64240_irq_init(void);
53 87
54void __init arch_init_irq(void) 88void __init arch_init_irq(void)
@@ -60,8 +94,6 @@ void __init arch_init_irq(void)
60 clear_c0_status(ST0_IM); 94 clear_c0_status(ST0_IM);
61 local_irq_disable(); 95 local_irq_disable();
62 96
63 /* Sets the first-level interrupt dispatcher. */
64 set_except_vector(0, ocelot_handle_int);
65 mips_cpu_irq_init(0); 97 mips_cpu_irq_init(0);
66 rm7k_cpu_irq_init(8); 98 rm7k_cpu_irq_init(8);
67 99
diff --git a/arch/mips/philips/pnx8550/common/Makefile b/arch/mips/philips/pnx8550/common/Makefile
index 6e38f3bc443c..b7c638166e9f 100644
--- a/arch/mips/philips/pnx8550/common/Makefile
+++ b/arch/mips/philips/pnx8550/common/Makefile
@@ -22,6 +22,6 @@
22# under Linux. 22# under Linux.
23# 23#
24 24
25obj-y := setup.o prom.o mipsIRQ.o int.o reset.o time.o proc.o platform.o 25obj-y := setup.o prom.o int.o reset.o time.o proc.o platform.o
26obj-$(CONFIG_PCI) += pci.o 26obj-$(CONFIG_PCI) += pci.o
27obj-$(CONFIG_KGDB) += gdb_hook.o 27obj-$(CONFIG_KGDB) += gdb_hook.o
diff --git a/arch/mips/philips/pnx8550/common/int.c b/arch/mips/philips/pnx8550/common/int.c
index c500e2d41f2c..39ee6314f627 100644
--- a/arch/mips/philips/pnx8550/common/int.c
+++ b/arch/mips/philips/pnx8550/common/int.c
@@ -38,8 +38,6 @@
38#include <int.h> 38#include <int.h>
39#include <uart.h> 39#include <uart.h>
40 40
41extern asmlinkage void cp0_irqdispatch(void);
42
43static DEFINE_SPINLOCK(irq_lock); 41static DEFINE_SPINLOCK(irq_lock);
44 42
45/* default prio for interrupts */ 43/* default prio for interrupts */
@@ -55,7 +53,7 @@ static char gic_prio[PNX8550_INT_GIC_TOTINT] = {
55 1 // 70 53 1 // 70
56}; 54};
57 55
58void hw0_irqdispatch(int irq, struct pt_regs *regs) 56static void hw0_irqdispatch(int irq, struct pt_regs *regs)
59{ 57{
60 /* find out which interrupt */ 58 /* find out which interrupt */
61 irq = PNX8550_GIC_VECTOR_0 >> 3; 59 irq = PNX8550_GIC_VECTOR_0 >> 3;
@@ -68,7 +66,7 @@ void hw0_irqdispatch(int irq, struct pt_regs *regs)
68} 66}
69 67
70 68
71void timer_irqdispatch(int irq, struct pt_regs *regs) 69static void timer_irqdispatch(int irq, struct pt_regs *regs)
72{ 70{
73 irq = (0x01c0 & read_c0_config7()) >> 6; 71 irq = (0x01c0 & read_c0_config7()) >> 6;
74 72
@@ -88,6 +86,20 @@ void timer_irqdispatch(int irq, struct pt_regs *regs)
88 } 86 }
89} 87}
90 88
89asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
90{
91 unsigned int pending = read_c0_status() & read_c0_cause();
92
93 if (pending & STATUSF_IP2)
94 do_IRQ(2, regs);
95 else if (pending & STATUSF_IP7) {
96 if (read_c0_config7() & 0x01c0)
97 timer_irqdispatch(7, regs);
98 }
99
100 spurious_interrupt(regs);
101}
102
91static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask) 103static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
92{ 104{
93 unsigned long status = read_c0_status(); 105 unsigned long status = read_c0_status();
@@ -223,9 +235,6 @@ void __init arch_init_irq(void)
223 int i; 235 int i;
224 int configPR; 236 int configPR;
225 237
226 /* init of cp0 interrupts */
227 set_except_vector(0, cp0_irqdispatch);
228
229 for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) { 238 for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) {
230 irq_desc[i].handler = &level_irq_type; 239 irq_desc[i].handler = &level_irq_type;
231 pnx8550_ack(i); /* mask the irq just in case */ 240 pnx8550_ack(i); /* mask the irq just in case */
diff --git a/arch/mips/philips/pnx8550/common/mipsIRQ.S b/arch/mips/philips/pnx8550/common/mipsIRQ.S
deleted file mode 100644
index 338bffda3fab..000000000000
--- a/arch/mips/philips/pnx8550/common/mipsIRQ.S
+++ /dev/null
@@ -1,76 +0,0 @@
1/*
2 * Copyright (c) 2002 Philips, Inc. All rights.
3 * Copyright (c) 2002 Red Hat, Inc. All rights.
4 *
5 * This software may be freely redistributed under the terms of the
6 * GNU General Public License.
7 *
8 * You should have received a copy of the GNU General Public License
9 * along with this program; if not, write to the Free Software
10 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
11 *
12 * Based upon arch/mips/galileo-boards/ev64240/int-handler.S
13 *
14 */
15#include <asm/asm.h>
16#include <asm/mipsregs.h>
17#include <asm/addrspace.h>
18#include <asm/regdef.h>
19#include <asm/stackframe.h>
20
21/*
22 * cp0_irqdispatch
23 *
24 * Code to handle in-core interrupt exception.
25 */
26
27 .align 5
28 .set reorder
29 .set noat
30 NESTED(cp0_irqdispatch, PT_SIZE, sp)
31 SAVE_ALL
32 CLI
33 .set at
34 mfc0 t0,CP0_CAUSE
35 mfc0 t2,CP0_STATUS
36
37 and t0,t2
38
39 andi t1,t0,STATUSF_IP2 /* int0 hardware line */
40 bnez t1,ll_hw0_irq
41 nop
42
43 andi t1,t0,STATUSF_IP7 /* int5 hardware line */
44 bnez t1,ll_timer_irq
45 nop
46
47 /* wrong alarm or masked ... */
48
49 j spurious_interrupt
50 nop
51 END(cp0_irqdispatch)
52
53 .align 5
54 .set reorder
55ll_hw0_irq:
56 li a0,2
57 move a1,sp
58 jal hw0_irqdispatch
59 nop
60 j ret_from_irq
61 nop
62
63 .align 5
64 .set reorder
65ll_timer_irq:
66 mfc0 t3,CP0_CONFIG,7
67 andi t4,t3,0x01c0
68 beqz t4,ll_timer_out
69 nop
70 li a0,7
71 move a1,sp
72 jal timer_irqdispatch
73 nop
74
75ll_timer_out: j ret_from_irq
76 nop
diff --git a/arch/mips/philips/pnx8550/common/platform.c b/arch/mips/philips/pnx8550/common/platform.c
index a592260fd673..5436b4b97455 100644
--- a/arch/mips/philips/pnx8550/common/platform.c
+++ b/arch/mips/philips/pnx8550/common/platform.c
@@ -18,6 +18,7 @@
18#include <linux/resource.h> 18#include <linux/resource.h>
19#include <linux/serial.h> 19#include <linux/serial.h>
20#include <linux/serial_ip3106.h> 20#include <linux/serial_ip3106.h>
21#include <linux/platform_device.h>
21 22
22#include <int.h> 23#include <int.h>
23#include <usb.h> 24#include <usb.h>
diff --git a/arch/mips/pmc-sierra/yosemite/Makefile b/arch/mips/pmc-sierra/yosemite/Makefile
index ae96a71a3089..e931e0d44229 100644
--- a/arch/mips/pmc-sierra/yosemite/Makefile
+++ b/arch/mips/pmc-sierra/yosemite/Makefile
@@ -2,7 +2,7 @@
2# Makefile for the PMC-Sierra Titan 2# Makefile for the PMC-Sierra Titan
3# 3#
4 4
5obj-y += irq-handler.o irq.o i2c-yosemite.o prom.o py-console.o setup.o 5obj-y += irq.o i2c-yosemite.o prom.o py-console.o setup.o
6 6
7obj-$(CONFIG_KGDB) += dbg_io.o 7obj-$(CONFIG_KGDB) += dbg_io.o
8obj-$(CONFIG_SMP) += smp.o 8obj-$(CONFIG_SMP) += smp.o
diff --git a/arch/mips/pmc-sierra/yosemite/irq-handler.S b/arch/mips/pmc-sierra/yosemite/irq-handler.S
deleted file mode 100644
index 33b9c40d4f5c..000000000000
--- a/arch/mips/pmc-sierra/yosemite/irq-handler.S
+++ /dev/null
@@ -1,93 +0,0 @@
1/*
2 * Copyright 2003, 04 PMC-Sierra Inc.
3 * Author: Manish Lachwani (lachwani@pmc-sierra.com
4 * Copyright 2004 Ralf Baechle (ralf@linux-mips.org)
5 *
6 * First-level interrupt router for the PMC-Sierra Titan board
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * Titan supports Hypertransport or PCI but not both. Hence, one interrupt
14 * line is shared between the PCI slot A and Hypertransport. This is the
15 * Processor INTB #0.
16 */
17
18#include <linux/config.h>
19#include <asm/asm.h>
20#include <asm/mipsregs.h>
21#include <asm/addrspace.h>
22#include <asm/regdef.h>
23#include <asm/stackframe.h>
24
25 .align 5
26 NESTED(titan_handle_int, PT_SIZE, sp)
27 SAVE_ALL
28 CLI
29 .set at
30 .set noreorder
31 la ra, ret_from_irq
32 mfc0 t0, CP0_CAUSE
33 mfc0 t2, CP0_STATUS
34
35 and t0, t2
36
37 andi t2, t0, STATUSF_IP7 /* INTB5 hardware line */
38 bnez t2, ll_timer_irq /* Timer */
39 andi t1, t0, STATUSF_IP2 /* INTB0 hardware line */
40 bnez t1, ll_pcia_irq /* 64-bit PCI */
41 andi t2, t0, STATUSF_IP3 /* INTB1 hardware line */
42 bnez t2, ll_pcib_irq /* second 64-bit PCI slot */
43 andi t1, t0, STATUSF_IP4 /* INTB2 hardware line */
44 bnez t1, ll_duart_irq /* UART */
45 andi t2, t0, STATUSF_IP5 /* SMP inter-core interrupts */
46 bnez t2, ll_smp_irq
47 andi t1, t0, STATUSF_IP6
48 bnez t1, ll_ht_irq /* Hypertransport */
49
50 move a0, sp
51 j do_extended_irq
52 END(titan_handle_int)
53
54 .set reorder
55 .align 5
56
57ll_pcia_irq:
58 li a0, 2
59 move a1, sp
60#ifdef CONFIG_HYPERTRANSPORT
61 j ll_ht_smp_irq_handler
62#else
63 j do_IRQ
64#endif
65
66ll_pcib_irq:
67 li a0, 3
68 move a1, sp
69 j do_IRQ
70
71ll_duart_irq:
72 li a0, 4
73 move a1, sp
74 j do_IRQ
75
76ll_smp_irq:
77 li a0, 5
78 move a1, sp
79#ifdef CONFIG_SMP
80 j titan_mailbox_irq
81#else
82 j do_IRQ
83#endif
84
85ll_ht_irq:
86 li a0, 6
87 move a1, sp
88 j ll_ht_smp_irq_handler
89
90ll_timer_irq:
91 li a0, 7
92 move a1, sp
93 j do_IRQ
diff --git a/arch/mips/pmc-sierra/yosemite/irq.c b/arch/mips/pmc-sierra/yosemite/irq.c
index f4e2897d9bf7..a1f524fc4c10 100644
--- a/arch/mips/pmc-sierra/yosemite/irq.c
+++ b/arch/mips/pmc-sierra/yosemite/irq.c
@@ -2,6 +2,8 @@
2 * Copyright (C) 2003 PMC-Sierra Inc. 2 * Copyright (C) 2003 PMC-Sierra Inc.
3 * Author: Manish Lachwani (lachwani@pmc-sierra.com) 3 * Author: Manish Lachwani (lachwani@pmc-sierra.com)
4 * 4 *
5 * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
6 *
5 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the 8 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your 9 * Free Software Foundation; either version 2 of the License, or (at your
@@ -55,7 +57,6 @@
55#define HYPERTRANSPORT_INTC 0x7a /* INTC# */ 57#define HYPERTRANSPORT_INTC 0x7a /* INTC# */
56#define HYPERTRANSPORT_INTD 0x7b /* INTD# */ 58#define HYPERTRANSPORT_INTD 0x7b /* INTD# */
57 59
58extern asmlinkage void titan_handle_int(void);
59extern void jaguar_mailbox_irq(struct pt_regs *); 60extern void jaguar_mailbox_irq(struct pt_regs *);
60 61
61/* 62/*
@@ -125,6 +126,35 @@ asmlinkage void do_extended_irq(struct pt_regs *regs)
125 126
126} 127}
127 128
129asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
130{
131 unsigned int cause = read_c0_cause();
132 unsigned int status = read_c0_status();
133 unsigned int pending = cause & status;
134
135 if (pending & STATUSF_IP7) {
136 do_IRQ(7, regs);
137 } else if (pending & STATUSF_IP2) {
138#ifdef CONFIG_HYPERTRANSPORT
139 ll_ht_smp_irq_handler(2, regs);
140#else
141 do_IRQ(2, regs);
142#endif
143 } else if (pending & STATUSF_IP3) {
144 do_IRQ(3, regs);
145 } else if (pending & STATUSF_IP4) {
146 do_IRQ(4, regs);
147 } else if (pending & STATUSF_IP5) {
148#ifdef CONFIG_SMP
149 titan_mailbox_irq(regs);
150#else
151 do_IRQ(5, regs);
152#endif
153 } else if (pending & STATUSF_IP6) {
154 do_IRQ(4, regs);
155 }
156}
157
128#ifdef CONFIG_KGDB 158#ifdef CONFIG_KGDB
129extern void init_second_port(void); 159extern void init_second_port(void);
130#endif 160#endif
@@ -136,7 +166,6 @@ void __init arch_init_irq(void)
136{ 166{
137 clear_c0_status(ST0_IM); 167 clear_c0_status(ST0_IM);
138 168
139 set_except_vector(0, titan_handle_int);
140 mips_cpu_irq_init(0); 169 mips_cpu_irq_init(0);
141 rm7k_cpu_irq_init(8); 170 rm7k_cpu_irq_init(8);
142 rm9k_cpu_irq_init(12); 171 rm9k_cpu_irq_init(12);
diff --git a/arch/mips/qemu/Makefile b/arch/mips/qemu/Makefile
index 6a8e8bcef552..730f459f3e99 100644
--- a/arch/mips/qemu/Makefile
+++ b/arch/mips/qemu/Makefile
@@ -2,6 +2,6 @@
2# Makefile for Qemu specific kernel interface routines under Linux. 2# Makefile for Qemu specific kernel interface routines under Linux.
3# 3#
4 4
5obj-y = q-firmware.o q-int.o q-irq.o q-mem.o q-setup.o 5obj-y = q-firmware.o q-irq.o q-mem.o q-setup.o
6 6
7obj-$(CONFIG_SMP) += q-smp.o 7obj-$(CONFIG_SMP) += q-smp.o
diff --git a/arch/mips/qemu/q-int.S b/arch/mips/qemu/q-int.S
deleted file mode 100644
index 6e3dfe5eb14b..000000000000
--- a/arch/mips/qemu/q-int.S
+++ /dev/null
@@ -1,17 +0,0 @@
1/*
2 * Qemu interrupt handler code.
3 *
4 * Copyright (C) 2005 by Ralf Baechle
5 */
6#include <asm/asm.h>
7#include <asm/regdef.h>
8#include <asm/stackframe.h>
9
10 .align 5
11 NESTED(qemu_handle_int, PT_SIZE, sp)
12 SAVE_ALL
13 CLI
14 move a0, sp
15 PTR_LA ra, ret_from_irq
16 j do_qemu_int
17 END(qemu_handle_int)
diff --git a/arch/mips/qemu/q-irq.c b/arch/mips/qemu/q-irq.c
index 2c4e0704ff10..3352374c4c7d 100644
--- a/arch/mips/qemu/q-irq.c
+++ b/arch/mips/qemu/q-irq.c
@@ -9,7 +9,7 @@
9 9
10extern asmlinkage void qemu_handle_int(void); 10extern asmlinkage void qemu_handle_int(void);
11 11
12asmlinkage void do_qemu_int(struct pt_regs *regs) 12asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
13{ 13{
14 unsigned int pending = read_c0_status() & read_c0_cause(); 14 unsigned int pending = read_c0_status() & read_c0_cause();
15 15
@@ -29,7 +29,6 @@ asmlinkage void do_qemu_int(struct pt_regs *regs)
29 29
30void __init arch_init_irq(void) 30void __init arch_init_irq(void)
31{ 31{
32 set_except_vector(0, qemu_handle_int);
33 mips_hpt_frequency = QEMU_C0_COUNTER_CLOCK; /* 100MHz */ 32 mips_hpt_frequency = QEMU_C0_COUNTER_CLOCK; /* 100MHz */
34 33
35 init_i8259_irqs(); 34 init_i8259_irqs();
diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile
index eb0820fe50bd..6aa4c0cd169c 100644
--- a/arch/mips/sgi-ip22/Makefile
+++ b/arch/mips/sgi-ip22/Makefile
@@ -3,7 +3,7 @@
3# under Linux. 3# under Linux.
4# 4#
5 5
6obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-irq.o ip22-berr.o \ 6obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-berr.o \
7 ip22-time.o ip22-nvram.o ip22-reset.o ip22-setup.o 7 ip22-time.o ip22-nvram.o ip22-reset.o ip22-setup.o
8 8
9obj-$(CONFIG_EISA) += ip22-eisa.o 9obj-$(CONFIG_EISA) += ip22-eisa.o
diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c
index d16fb43b1a93..fc6a7e2b189c 100644
--- a/arch/mips/sgi-ip22/ip22-int.c
+++ b/arch/mips/sgi-ip22/ip22-int.c
@@ -37,7 +37,6 @@ static char lc1msk_to_irqnr[256];
37static char lc2msk_to_irqnr[256]; 37static char lc2msk_to_irqnr[256];
38static char lc3msk_to_irqnr[256]; 38static char lc3msk_to_irqnr[256];
39 39
40extern asmlinkage void indyIRQ(void);
41extern int ip22_eisa_init(void); 40extern int ip22_eisa_init(void);
42 41
43static void enable_local0_irq(unsigned int irq) 42static void enable_local0_irq(unsigned int irq)
@@ -224,7 +223,7 @@ static struct hw_interrupt_type ip22_local3_irq_type = {
224 .end = end_local3_irq, 223 .end = end_local3_irq,
225}; 224};
226 225
227void indy_local0_irqdispatch(struct pt_regs *regs) 226static void indy_local0_irqdispatch(struct pt_regs *regs)
228{ 227{
229 u8 mask = sgint->istat0 & sgint->imask0; 228 u8 mask = sgint->istat0 & sgint->imask0;
230 u8 mask2; 229 u8 mask2;
@@ -242,7 +241,7 @@ void indy_local0_irqdispatch(struct pt_regs *regs)
242 return; 241 return;
243} 242}
244 243
245void indy_local1_irqdispatch(struct pt_regs *regs) 244static void indy_local1_irqdispatch(struct pt_regs *regs)
246{ 245{
247 u8 mask = sgint->istat1 & sgint->imask1; 246 u8 mask = sgint->istat1 & sgint->imask1;
248 u8 mask2; 247 u8 mask2;
@@ -262,7 +261,7 @@ void indy_local1_irqdispatch(struct pt_regs *regs)
262 261
263extern void ip22_be_interrupt(int irq, struct pt_regs *regs); 262extern void ip22_be_interrupt(int irq, struct pt_regs *regs);
264 263
265void indy_buserror_irq(struct pt_regs *regs) 264static void indy_buserror_irq(struct pt_regs *regs)
266{ 265{
267 int irq = SGI_BUSERR_IRQ; 266 int irq = SGI_BUSERR_IRQ;
268 267
@@ -307,6 +306,56 @@ static struct irqaction map1_cascade = {
307#define SGI_INTERRUPTS SGINT_LOCAL3 306#define SGI_INTERRUPTS SGINT_LOCAL3
308#endif 307#endif
309 308
309extern void indy_r4k_timer_interrupt(struct pt_regs *regs);
310extern void indy_8254timer_irq(struct pt_regs *regs);
311
312/*
313 * IRQs on the INDY look basically (barring software IRQs which we don't use
314 * at all) like:
315 *
316 * MIPS IRQ Source
317 * -------- ------
318 * 0 Software (ignored)
319 * 1 Software (ignored)
320 * 2 Local IRQ level zero
321 * 3 Local IRQ level one
322 * 4 8254 Timer zero
323 * 5 8254 Timer one
324 * 6 Bus Error
325 * 7 R4k timer (what we use)
326 *
327 * We handle the IRQ according to _our_ priority which is:
328 *
329 * Highest ---- R4k Timer
330 * Local IRQ zero
331 * Local IRQ one
332 * Bus Error
333 * 8254 Timer zero
334 * Lowest ---- 8254 Timer one
335 *
336 * then we just return, if multiple IRQs are pending then we will just take
337 * another exception, big deal.
338 */
339
340asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
341{
342 unsigned int pending = read_c0_cause();
343
344 /*
345 * First we check for r4k counter/timer IRQ.
346 */
347 if (pending & CAUSEF_IP7)
348 indy_r4k_timer_interrupt(regs);
349 else if (pending & CAUSEF_IP2)
350 indy_local0_irqdispatch(regs);
351 else if (pending & CAUSEF_IP3)
352 indy_local1_irqdispatch(regs);
353 else if (pending & CAUSEF_IP6)
354 indy_buserror_irq(regs);
355 else if (pending & (CAUSEF_IP4 | CAUSEF_IP5))
356 indy_8254timer_irq(regs);
357}
358
310extern void mips_cpu_irq_init(unsigned int irq_base); 359extern void mips_cpu_irq_init(unsigned int irq_base);
311 360
312void __init arch_init_irq(void) 361void __init arch_init_irq(void)
@@ -369,8 +418,6 @@ void __init arch_init_irq(void)
369 sgint->cmeimask0 = 0; 418 sgint->cmeimask0 = 0;
370 sgint->cmeimask1 = 0; 419 sgint->cmeimask1 = 0;
371 420
372 set_except_vector(0, indyIRQ);
373
374 /* init CPU irqs */ 421 /* init CPU irqs */
375 mips_cpu_irq_init(SGINT_CPU); 422 mips_cpu_irq_init(SGINT_CPU);
376 423
diff --git a/arch/mips/sgi-ip22/ip22-irq.S b/arch/mips/sgi-ip22/ip22-irq.S
deleted file mode 100644
index 6ccbd9e1d967..000000000000
--- a/arch/mips/sgi-ip22/ip22-irq.S
+++ /dev/null
@@ -1,118 +0,0 @@
1/*
2 * ip22-irq.S: Interrupt exception dispatch code for FullHouse and
3 * Guiness.
4 *
5 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
6 */
7
8#include <asm/asm.h>
9#include <asm/mipsregs.h>
10#include <asm/regdef.h>
11#include <asm/stackframe.h>
12
13/* A lot of complication here is taken away because:
14 *
15 * 1) We handle one interrupt and return, sitting in a loop and moving across
16 * all the pending IRQ bits in the cause register is _NOT_ the answer, the
17 * common case is one pending IRQ so optimize in that direction.
18 *
19 * 2) We need not check against bits in the status register IRQ mask, that
20 * would make this routine slow as hell.
21 *
22 * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
23 * between like BSD spl() brain-damage.
24 *
25 * Furthermore, the IRQs on the INDY look basically (barring software IRQs
26 * which we don't use at all) like:
27 *
28 * MIPS IRQ Source
29 * -------- ------
30 * 0 Software (ignored)
31 * 1 Software (ignored)
32 * 2 Local IRQ level zero
33 * 3 Local IRQ level one
34 * 4 8254 Timer zero
35 * 5 8254 Timer one
36 * 6 Bus Error
37 * 7 R4k timer (what we use)
38 *
39 * We handle the IRQ according to _our_ priority which is:
40 *
41 * Highest ---- R4k Timer
42 * Local IRQ zero
43 * Local IRQ one
44 * Bus Error
45 * 8254 Timer zero
46 * Lowest ---- 8254 Timer one
47 *
48 * then we just return, if multiple IRQs are pending then we will just take
49 * another exception, big deal.
50 */
51
52 .text
53 .set noreorder
54 .set noat
55 .align 5
56 NESTED(indyIRQ, PT_SIZE, sp)
57 SAVE_ALL
58 CLI
59 .set at
60 mfc0 s0, CP0_CAUSE # get irq mask
61
62 /* First we check for r4k counter/timer IRQ. */
63 andi a0, s0, CAUSEF_IP7
64 beq a0, zero, 1f
65 andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero
66
67 /* Wheee, a timer interrupt. */
68 jal indy_r4k_timer_interrupt
69 move a0, sp # delay slot
70 j ret_from_irq
71 nop # delay slot
72
731:
74 beq a0, zero, 1f
75 andi a0, s0, CAUSEF_IP3 # delay slot, check local level one
76
77 /* Wheee, local level zero interrupt. */
78 jal indy_local0_irqdispatch
79 move a0, sp # delay slot
80
81 j ret_from_irq
82 nop # delay slot
83
841:
85 beq a0, zero, 1f
86 andi a0, s0, CAUSEF_IP6 # delay slot, check bus error
87
88 /* Wheee, local level one interrupt. */
89 jal indy_local1_irqdispatch
90 move a0, sp # delay slot
91 j ret_from_irq
92 nop # delay slot
93
941:
95 beq a0, zero, 1f
96 andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5) # delay slot
97
98 /* Wheee, an asynchronous bus error... */
99 jal indy_buserror_irq
100 move a0, sp # delay slot
101 j ret_from_irq
102 nop # delay slot
103
1041:
105 /* Here by mistake? It is possible, that by the time we take
106 * the exception the IRQ pin goes low, so just leave if this
107 * is the case.
108 */
109 beq a0, zero, 1f
110 nop # delay slot
111
112 /* Must be one of the 8254 timers... */
113 jal indy_8254timer_irq
114 move a0, sp # delay slot
1151:
116 j ret_from_irq
117 nop # delay slot
118 END(indyIRQ)
diff --git a/arch/mips/sgi-ip27/Makefile b/arch/mips/sgi-ip27/Makefile
index 4ba340780c35..686ba14e2882 100644
--- a/arch/mips/sgi-ip27/Makefile
+++ b/arch/mips/sgi-ip27/Makefile
@@ -2,7 +2,7 @@
2# Makefile for the IP27 specific kernel interface routines under Linux. 2# Makefile for the IP27 specific kernel interface routines under Linux.
3# 3#
4 4
5obj-y := ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \ 5obj-y := ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o \
6 ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o \ 6 ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o \
7 ip27-timer.o ip27-hubio.o ip27-xtalk.o 7 ip27-timer.o ip27-hubio.o ip27-xtalk.o
8 8
diff --git a/arch/mips/sgi-ip27/TODO b/arch/mips/sgi-ip27/TODO
index 32106131b0d0..19f1512c8f2e 100644
--- a/arch/mips/sgi-ip27/TODO
+++ b/arch/mips/sgi-ip27/TODO
@@ -9,10 +9,6 @@ ip27-init.c:find_lbaord_real. DONE
9in irix? 9in irix?
106. Investigate why things do not work without the setup_test() call 106. Investigate why things do not work without the setup_test() call
11being invoked on all nodes in ip27-memory.c. 11being invoked on all nodes in ip27-memory.c.
127. Too many CLIs in the locore handlers :
13For the low level handlers set up by set_except_vector(),
14__tlb_refill_debug_tramp, __xtlb_refill_debug_tramp and cacheerror,
15investigate whether the code should do CLI, STI or KMODE.
168. Too many do_page_faults invoked - investigate. 128. Too many do_page_faults invoked - investigate.
179. start_thread must turn off UX64 ... and define tlb_refill_debug. 139. start_thread must turn off UX64 ... and define tlb_refill_debug.
1810. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable 1410. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable
diff --git a/arch/mips/sgi-ip27/ip27-irq-glue.S b/arch/mips/sgi-ip27/ip27-irq-glue.S
deleted file mode 100644
index c304df715e0a..000000000000
--- a/arch/mips/sgi-ip27/ip27-irq-glue.S
+++ /dev/null
@@ -1,45 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1999 Ralf Baechle
7 * Copyright (C) 1999 Silicon Graphics, Inc.
8 */
9#include <asm/asm.h>
10#include <asm/mipsregs.h>
11#include <asm/regdef.h>
12#include <asm/stackframe.h>
13
14 .text
15 .align 5
16NESTED(ip27_irq, PT_SIZE, sp)
17 SAVE_ALL
18 CLI
19
20 mfc0 s0, CP0_CAUSE
21 mfc0 t0, CP0_STATUS
22 and s0, t0
23 move a0, sp
24 PTR_LA ra, ret_from_irq
25
26 /* First check for RT interrupt. */
27 andi t0, s0, CAUSEF_IP4
28 bnez t0, ip4
29 andi t0, s0, CAUSEF_IP2
30 bnez t0, ip2
31 andi t0, s0, CAUSEF_IP3
32 bnez t0, ip3
33 andi t0, s0, CAUSEF_IP5
34 bnez t0, ip5
35 andi t0, s0, CAUSEF_IP6
36 bnez t0, ip6
37 j ra
38
39ip2: j ip27_do_irq_mask0 # PI_INT_PEND_0 or CC_PEND_{A|B}
40ip3: j ip27_do_irq_mask1 # PI_INT_PEND_1
41ip4: j ip27_rt_timer_interrupt
42ip5: j ip27_prof_timer
43ip6: j ip27_hub_error
44
45 END(ip27_irq)
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index 2854ac4c9be1..2e643d2f51cb 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -130,7 +130,7 @@ static int ms1bit(unsigned long x)
130 * Kanoj 05.13.00 130 * Kanoj 05.13.00
131 */ 131 */
132 132
133void ip27_do_irq_mask0(struct pt_regs *regs) 133static void ip27_do_irq_mask0(struct pt_regs *regs)
134{ 134{
135 int irq, swlevel; 135 int irq, swlevel;
136 hubreg_t pend0, mask0; 136 hubreg_t pend0, mask0;
@@ -171,7 +171,7 @@ void ip27_do_irq_mask0(struct pt_regs *regs)
171 LOCAL_HUB_L(PI_INT_PEND0); 171 LOCAL_HUB_L(PI_INT_PEND0);
172} 172}
173 173
174void ip27_do_irq_mask1(struct pt_regs *regs) 174static void ip27_do_irq_mask1(struct pt_regs *regs)
175{ 175{
176 int irq, swlevel; 176 int irq, swlevel;
177 hubreg_t pend1, mask1; 177 hubreg_t pend1, mask1;
@@ -196,12 +196,12 @@ void ip27_do_irq_mask1(struct pt_regs *regs)
196 LOCAL_HUB_L(PI_INT_PEND1); 196 LOCAL_HUB_L(PI_INT_PEND1);
197} 197}
198 198
199void ip27_prof_timer(struct pt_regs *regs) 199static void ip27_prof_timer(struct pt_regs *regs)
200{ 200{
201 panic("CPU %d got a profiling interrupt", smp_processor_id()); 201 panic("CPU %d got a profiling interrupt", smp_processor_id());
202} 202}
203 203
204void ip27_hub_error(struct pt_regs *regs) 204static void ip27_hub_error(struct pt_regs *regs)
205{ 205{
206 panic("CPU %d got a hub error interrupt", smp_processor_id()); 206 panic("CPU %d got a hub error interrupt", smp_processor_id());
207} 207}
@@ -421,9 +421,26 @@ int __devinit request_bridge_irq(struct bridge_controller *bc)
421 return irq; 421 return irq;
422} 422}
423 423
424extern void ip27_rt_timer_interrupt(struct pt_regs *regs);
425
426asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
427{
428 unsigned long pending = read_c0_cause() & read_c0_status();
429
430 if (pending & CAUSEF_IP4)
431 ip27_rt_timer_interrupt(regs);
432 else if (pending & CAUSEF_IP2) /* PI_INT_PEND_0 or CC_PEND_{A|B} */
433 ip27_do_irq_mask0(regs);
434 else if (pending & CAUSEF_IP3) /* PI_INT_PEND_1 */
435 ip27_do_irq_mask1(regs);
436 else if (pending & CAUSEF_IP5)
437 ip27_prof_timer(regs);
438 else if (pending & CAUSEF_IP6)
439 ip27_hub_error(regs);
440}
441
424void __init arch_init_irq(void) 442void __init arch_init_irq(void)
425{ 443{
426 set_except_vector(0, ip27_irq);
427} 444}
428 445
429void install_ipi(void) 446void install_ipi(void)
diff --git a/arch/mips/sgi-ip32/Makefile b/arch/mips/sgi-ip32/Makefile
index 470898f4afe1..530bf848c3d0 100644
--- a/arch/mips/sgi-ip32/Makefile
+++ b/arch/mips/sgi-ip32/Makefile
@@ -3,7 +3,7 @@
3# under Linux. 3# under Linux.
4# 4#
5 5
6obj-y += ip32-berr.o ip32-irq.o ip32-irq-glue.o ip32-setup.o ip32-reset.o \ 6obj-y += ip32-berr.o ip32-irq.o ip32-setup.o ip32-reset.o \
7 crime.o ip32-memory.o 7 crime.o ip32-memory.o
8 8
9EXTRA_AFLAGS := $(CFLAGS) 9EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/sgi-ip32/ip32-irq-glue.S b/arch/mips/sgi-ip32/ip32-irq-glue.S
deleted file mode 100644
index 200924e1c4f5..000000000000
--- a/arch/mips/sgi-ip32/ip32-irq-glue.S
+++ /dev/null
@@ -1,86 +0,0 @@
1/*
2 * Low level interrupt handler for the SGI O2 aka IP32 aka Moosehead
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2000 Harald Koerfgen
9 * Copyright (C) 2001 Keith M Wesolowski
10 */
11#include <asm/asm.h>
12#include <asm/regdef.h>
13#include <asm/mipsregs.h>
14#include <asm/stackframe.h>
15#include <asm/addrspace.h>
16
17 .text
18 .set noreorder
19 .set noat
20 .align 5
21 NESTED(ip32_handle_int, PT_SIZE, ra)
22 .set noat
23 SAVE_ALL
24 CLI # TEST: interrupts should be off
25 .set at
26 .set noreorder
27
28 mfc0 s0,CP0_CAUSE
29
30 andi t1, s0, IE_IRQ0
31 bnez t1, handle_irq0
32 andi t1, s0, IE_IRQ1
33 bnez t1, handle_irq1
34 andi t1, s0, IE_IRQ2
35 bnez t1, handle_irq2
36 andi t1, s0, IE_IRQ3
37 bnez t1, handle_irq3
38 andi t1, s0, IE_IRQ4
39 bnez t1, handle_irq4
40 andi t1, s0, IE_IRQ5
41 bnez t1, handle_irq5
42 nop
43
44 /* Either someone has triggered the "software interrupts"
45 * or we lost an interrupt somehow. Ignore it.
46 */
47 j ret_from_irq
48 nop
49
50handle_irq0:
51 jal ip32_irq0
52 move a0, sp
53 j ret_from_irq
54 nop
55
56handle_irq1:
57 jal ip32_irq1
58 move a0, sp
59 j ret_from_irq
60 nop
61
62handle_irq2:
63 jal ip32_irq2
64 move a0, sp
65 j ret_from_irq
66 nop
67
68handle_irq3:
69 jal ip32_irq3
70 move a0, sp
71 j ret_from_irq
72 nop
73
74handle_irq4:
75 jal ip32_irq4
76 move a0, sp
77 j ret_from_irq
78 nop
79
80handle_irq5:
81 jal ip32_irq5
82 move a0, sp
83 j ret_from_irq
84 nop
85
86 END(ip32_handle_int)
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c
index 2eb22d692ed9..22a6df94b4a1 100644
--- a/arch/mips/sgi-ip32/ip32-irq.c
+++ b/arch/mips/sgi-ip32/ip32-irq.c
@@ -130,8 +130,6 @@ struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT,
130struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT, 130struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT,
131 CPU_MASK_NONE, "CRIME CPU error", NULL, NULL }; 131 CPU_MASK_NONE, "CRIME CPU error", NULL, NULL };
132 132
133extern void ip32_handle_int(void);
134
135/* 133/*
136 * For interrupts wired from a single device to the CPU. Only the clock 134 * For interrupts wired from a single device to the CPU. Only the clock
137 * uses this it seems, which is IRQ 0 and IP7. 135 * uses this it seems, which is IRQ 0 and IP7.
@@ -503,7 +501,7 @@ static void ip32_unknown_interrupt(struct pt_regs *regs)
503 501
504/* CRIME 1.1 appears to deliver all interrupts to this one pin. */ 502/* CRIME 1.1 appears to deliver all interrupts to this one pin. */
505/* change this to loop over all edge-triggered irqs, exception masked out ones */ 503/* change this to loop over all edge-triggered irqs, exception masked out ones */
506void ip32_irq0(struct pt_regs *regs) 504static void ip32_irq0(struct pt_regs *regs)
507{ 505{
508 uint64_t crime_int; 506 uint64_t crime_int;
509 int irq = 0; 507 int irq = 0;
@@ -520,31 +518,49 @@ void ip32_irq0(struct pt_regs *regs)
520 do_IRQ(irq, regs); 518 do_IRQ(irq, regs);
521} 519}
522 520
523void ip32_irq1(struct pt_regs *regs) 521static void ip32_irq1(struct pt_regs *regs)
524{ 522{
525 ip32_unknown_interrupt(regs); 523 ip32_unknown_interrupt(regs);
526} 524}
527 525
528void ip32_irq2(struct pt_regs *regs) 526static void ip32_irq2(struct pt_regs *regs)
529{ 527{
530 ip32_unknown_interrupt(regs); 528 ip32_unknown_interrupt(regs);
531} 529}
532 530
533void ip32_irq3(struct pt_regs *regs) 531static void ip32_irq3(struct pt_regs *regs)
534{ 532{
535 ip32_unknown_interrupt(regs); 533 ip32_unknown_interrupt(regs);
536} 534}
537 535
538void ip32_irq4(struct pt_regs *regs) 536static void ip32_irq4(struct pt_regs *regs)
539{ 537{
540 ip32_unknown_interrupt(regs); 538 ip32_unknown_interrupt(regs);
541} 539}
542 540
543void ip32_irq5(struct pt_regs *regs) 541static void ip32_irq5(struct pt_regs *regs)
544{ 542{
545 ll_timer_interrupt(IP32_R4K_TIMER_IRQ, regs); 543 ll_timer_interrupt(IP32_R4K_TIMER_IRQ, regs);
546} 544}
547 545
546asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
547{
548 unsigned int pending = read_c0_cause();
549
550 if (likely(pending & IE_IRQ0))
551 ip32_irq0(regs);
552 else if (unlikely(pending & IE_IRQ1))
553 ip32_irq1(regs);
554 else if (unlikely(pending & IE_IRQ2))
555 ip32_irq2(regs);
556 else if (unlikely(pending & IE_IRQ3))
557 ip32_irq3(regs);
558 else if (unlikely(pending & IE_IRQ4))
559 ip32_irq4(regs);
560 else if (likely(pending & IE_IRQ5))
561 ip32_irq5(regs);
562}
563
548void __init arch_init_irq(void) 564void __init arch_init_irq(void)
549{ 565{
550 unsigned int irq; 566 unsigned int irq;
@@ -556,7 +572,6 @@ void __init arch_init_irq(void)
556 crime->soft_int = 0; 572 crime->soft_int = 0;
557 mace->perif.ctrl.istat = 0; 573 mace->perif.ctrl.istat = 0;
558 mace->perif.ctrl.imask = 0; 574 mace->perif.ctrl.imask = 0;
559 set_except_vector(0, ip32_handle_int);
560 575
561 for (irq = 0; irq <= IP32_IRQ_MAX; irq++) { 576 for (irq = 0; irq <= IP32_IRQ_MAX; irq++) {
562 hw_irq_controller *controller; 577 hw_irq_controller *controller;
diff --git a/arch/mips/sibyte/bcm1480/Makefile b/arch/mips/sibyte/bcm1480/Makefile
index 538d5a51ae94..7b36ff3873b7 100644
--- a/arch/mips/sibyte/bcm1480/Makefile
+++ b/arch/mips/sibyte/bcm1480/Makefile
@@ -1,4 +1,4 @@
1obj-y := setup.o irq.o irq_handler.o time.o 1obj-y := setup.o irq.o time.o
2 2
3obj-$(CONFIG_SMP) += smp.o 3obj-$(CONFIG_SMP) += smp.o
4 4
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
index 9cf7d713b13c..e61760b14d99 100644
--- a/arch/mips/sibyte/bcm1480/irq.c
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -187,9 +187,6 @@ static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask)
187#endif 187#endif
188 188
189 189
190/* Defined in arch/mips/sibyte/bcm1480/irq_handler.S */
191extern void bcm1480_irq_handler(void);
192
193/*****************************************************************************/ 190/*****************************************************************************/
194 191
195static unsigned int startup_bcm1480_irq(unsigned int irq) 192static unsigned int startup_bcm1480_irq(unsigned int irq)
@@ -422,7 +419,6 @@ void __init arch_init_irq(void)
422#endif 419#endif
423 /* Enable necessary IPs, disable the rest */ 420 /* Enable necessary IPs, disable the rest */
424 change_c0_status(ST0_IM, imask); 421 change_c0_status(ST0_IM, imask);
425 set_except_vector(0, bcm1480_irq_handler);
426 422
427#ifdef CONFIG_KGDB 423#ifdef CONFIG_KGDB
428 if (kgdb_flag) { 424 if (kgdb_flag) {
@@ -473,3 +469,76 @@ void bcm1480_kgdb_interrupt(struct pt_regs *regs)
473} 469}
474 470
475#endif /* CONFIG_KGDB */ 471#endif /* CONFIG_KGDB */
472
473static inline int dclz(unsigned long long x)
474{
475 int lz;
476
477 __asm__ (
478 " .set push \n"
479 " .set mips64 \n"
480 " dclz %0, %1 \n"
481 " .set pop \n"
482 : "=r" (lz)
483 : "r" (x));
484
485 return lz;
486}
487
488extern void bcm1480_timer_interrupt(struct pt_regs *regs);
489extern void bcm1480_mailbox_interrupt(struct pt_regs *regs);
490extern void bcm1480_kgdb_interrupt(struct pt_regs *regs);
491
492asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
493{
494 unsigned int pending;
495
496#ifdef CONFIG_SIBYTE_BCM1480_PROF
497 /* Set compare to count to silence count/compare timer interrupts */
498 write_c0_compare(read_c0_count());
499#endif
500
501 pending = read_c0_cause();
502
503#ifdef CONFIG_SIBYTE_BCM1480_PROF
504 if (pending & CAUSEF_IP7) /* Cpu performance counter interrupt */
505 sbprof_cpu_intr(exception_epc(regs));
506#endif
507
508 if (pending & CAUSEF_IP4)
509 bcm1480_timer_interrupt(regs);
510
511#ifdef CONFIG_SMP
512 if (pending & CAUSEF_IP3)
513 bcm1480_mailbox_interrupt(regs);
514#endif
515
516#ifdef CONFIG_KGDB
517 if (pending & CAUSEF_IP6)
518 bcm1480_kgdb_interrupt(regs); /* KGDB (uart 1) */
519#endif
520
521 if (pending & CAUSEF_IP2) {
522 unsigned long long mask_h, mask_l;
523 unsigned long base;
524
525 /*
526 * Default...we've hit an IP[2] interrupt, which means we've
527 * got to check the 1480 interrupt registers to figure out what
528 * to do. Need to detect which CPU we're on, now that
529 * smp_affinity is supported.
530 */
531 base = A_BCM1480_IMR_MAPPER(smp_processor_id());
532 mask_h = __raw_readq(
533 IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H));
534 mask_l = __raw_readq(
535 IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L));
536
537 if (!mask_h) {
538 if (mask_h ^ 1)
539 do_IRQ(63 - dclz(mask_h), regs);
540 else
541 do_IRQ(127 - dclz(mask_l), regs);
542 }
543 }
544}
diff --git a/arch/mips/sibyte/bcm1480/irq_handler.S b/arch/mips/sibyte/bcm1480/irq_handler.S
deleted file mode 100644
index 408db88d050f..000000000000
--- a/arch/mips/sibyte/bcm1480/irq_handler.S
+++ /dev/null
@@ -1,165 +0,0 @@
1/*
2 * Copyright (C) 2000,2001,2002,2003,2004 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19/*
20 * bcm1480_irq_handler() is the routine that is actually called when an
21 * interrupt occurs. It is installed as the exception vector handler in
22 * init_IRQ() in arch/mips/sibyte/bcm1480/irq.c
23 *
24 * In the handle we figure out which interrupts need handling, and use that
25 * to call the dispatcher, which will take care of actually calling
26 * registered handlers
27 *
28 * Note that we take care of all raised interrupts in one go at the handler.
29 * This is more BSDish than the Indy code, and also, IMHO, more sane.
30 */
31#include <linux/config.h>
32
33#include <asm/addrspace.h>
34#include <asm/asm.h>
35#include <asm/mipsregs.h>
36#include <asm/regdef.h>
37#include <asm/stackframe.h>
38#include <asm/sibyte/sb1250_defs.h>
39#include <asm/sibyte/bcm1480_regs.h>
40#include <asm/sibyte/bcm1480_int.h>
41
42/*
43 * What a pain. We have to be really careful saving the upper 32 bits of any
44 * register across function calls if we don't want them trashed--since were
45 * running in -o32, the calling routing never saves the full 64 bits of a
46 * register across a function call. Being the interrupt handler, we're
47 * guaranteed that interrupts are disabled during this code so we don't have
48 * to worry about random interrupts blasting the high 32 bits.
49 */
50
51 .text
52 .set push
53 .set noreorder
54 .set noat
55 .set mips64
56 #.set mips4
57 .align 5
58 NESTED(bcm1480_irq_handler, PT_SIZE, sp)
59 SAVE_ALL
60 CLI
61
62#ifdef CONFIG_SIBYTE_BCM1480_PROF
63 /* Set compare to count to silence count/compare timer interrupts */
64 mfc0 t1, CP0_COUNT
65 mtc0 t1, CP0_COMPARE /* pause to clear IP[7] bit of cause ? */
66#endif
67 /* Read cause */
68 mfc0 s0, CP0_CAUSE
69
70#ifdef CONFIG_SIBYTE_BCM1480_PROF
71 /* Cpu performance counter interrupt is routed to IP[7] */
72 andi t1, s0, CAUSEF_IP7
73 beqz t1, 0f
74 srl t1, s0, (CAUSEB_BD-2) /* Shift BD bit to bit 2 */
75 and t1, t1, 0x4 /* mask to get just BD bit */
76#ifdef CONFIG_MIPS64
77 dmfc0 a0, CP0_EPC
78 daddu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */
79#else
80 mfc0 a0, CP0_EPC
81 addu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */
82#endif
83 jal sbprof_cpu_intr
84 nop
85 j ret_from_irq
86 nop
870:
88#endif
89
90 /* Timer interrupt is routed to IP[4] */
91 andi t1, s0, CAUSEF_IP4
92 beqz t1, 1f
93 nop
94 jal bcm1480_timer_interrupt
95 move a0, sp /* Pass the registers along */
96 j ret_from_irq
97 nop /* delay slot */
981:
99
100#ifdef CONFIG_SMP
101 /* Mailbox interrupt is routed to IP[3] */
102 andi t1, s0, CAUSEF_IP3
103 beqz t1, 2f
104 nop
105 jal bcm1480_mailbox_interrupt
106 move a0, sp
107 j ret_from_irq
108 nop /* delay slot */
1092:
110#endif
111
112#ifdef CONFIG_KGDB
113 /* KGDB (uart 1) interrupt is routed to IP[6] */
114 andi t1, s0, CAUSEF_IP6
115 beqz t1, 3f
116 nop /* delay slot */
117 jal bcm1480_kgdb_interrupt
118 move a0, sp
119 j ret_from_irq
120 nop /* delay slot */
1213:
122#endif
123
124 and t1, s0, CAUSEF_IP2
125 beqz t1, 9f
126 nop
127
128 /*
129 * Default...we've hit an IP[2] interrupt, which means we've got
130 * to check the 1480 interrupt registers to figure out what to do
131 * Need to detect which CPU we're on, now that smp_affinity is
132 * supported.
133 */
134 PTR_LA v0, CKSEG1 + A_BCM1480_IMR_CPU0_BASE
135#ifdef CONFIG_SMP
136 lw t1, TI_CPU($28)
137 sll t1, t1, BCM1480_IMR_REGISTER_SPACING_SHIFT
138 addu v0, v0, t1
139#endif
140
141 /* Read IP[2] status (get both high and low halves of status) */
142 ld s0, R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H(v0)
143 ld s1, R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L(v0)
144
145 move s2, zero /* intr number */
146 li s3, 64
147
148 beqz s0, 9f /* No interrupts. Return. */
149 move a1, sp
150
151 xori s4, s0, 1 /* if s0 (_H) == 1, it's a low intr, so... */
152 movz s2, s3, s4 /* start the intr number at 64, and */
153 movz s0, s1, s4 /* look at the low status value. */
154
155 dclz s1, s0 /* Find the next interrupt. */
156 dsubu a0, zero, s1
157 daddiu a0, a0, 63
158 jal do_IRQ
159 daddu a0, a0, s2
160
1619: j ret_from_irq
162 nop
163
164 .set pop
165 END(bcm1480_irq_handler)
diff --git a/arch/mips/sibyte/sb1250/Makefile b/arch/mips/sibyte/sb1250/Makefile
index a8af84697588..a2fdbd62f8ac 100644
--- a/arch/mips/sibyte/sb1250/Makefile
+++ b/arch/mips/sibyte/sb1250/Makefile
@@ -1,4 +1,4 @@
1obj-y := setup.o irq.o irq_handler.o time.o 1obj-y := setup.o irq.o time.o
2 2
3obj-$(CONFIG_SMP) += smp.o 3obj-$(CONFIG_SMP) += smp.o
4obj-$(CONFIG_SIBYTE_TBPROF) += bcm1250_tbprof.o 4obj-$(CONFIG_SIBYTE_TBPROF) += bcm1250_tbprof.o
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
index 589537bfcc3d..0f6e54db4888 100644
--- a/arch/mips/sibyte/sb1250/irq.c
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -163,10 +163,6 @@ static void sb1250_set_affinity(unsigned int irq, cpumask_t mask)
163} 163}
164#endif 164#endif
165 165
166
167/* Defined in arch/mips/sibyte/sb1250/irq_handler.S */
168extern void sb1250_irq_handler(void);
169
170/*****************************************************************************/ 166/*****************************************************************************/
171 167
172static unsigned int startup_sb1250_irq(unsigned int irq) 168static unsigned int startup_sb1250_irq(unsigned int irq)
@@ -379,7 +375,6 @@ void __init arch_init_irq(void)
379#endif 375#endif
380 /* Enable necessary IPs, disable the rest */ 376 /* Enable necessary IPs, disable the rest */
381 change_c0_status(ST0_IM, imask); 377 change_c0_status(ST0_IM, imask);
382 set_except_vector(0, sb1250_irq_handler);
383 378
384#ifdef CONFIG_KGDB 379#ifdef CONFIG_KGDB
385 if (kgdb_flag) { 380 if (kgdb_flag) {
@@ -409,7 +404,7 @@ void __init arch_init_irq(void)
409#define duart_out(reg, val) csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg))) 404#define duart_out(reg, val) csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
410#define duart_in(reg) csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg))) 405#define duart_in(reg) csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg)))
411 406
412void sb1250_kgdb_interrupt(struct pt_regs *regs) 407static void sb1250_kgdb_interrupt(struct pt_regs *regs)
413{ 408{
414 /* 409 /*
415 * Clear break-change status (allow some time for the remote 410 * Clear break-change status (allow some time for the remote
@@ -424,3 +419,74 @@ void sb1250_kgdb_interrupt(struct pt_regs *regs)
424} 419}
425 420
426#endif /* CONFIG_KGDB */ 421#endif /* CONFIG_KGDB */
422
423static inline int dclz(unsigned long long x)
424{
425 int lz;
426
427 __asm__ (
428 " .set push \n"
429 " .set mips64 \n"
430 " dclz %0, %1 \n"
431 " .set pop \n"
432 : "=r" (lz)
433 : "r" (x));
434
435 return lz;
436}
437
438asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
439{
440 unsigned int pending;
441
442#ifdef CONFIG_SIBYTE_SB1250_PROF
443 /* Set compare to count to silence count/compare timer interrupts */
444 write_c0_count(read_c0_count());
445#endif
446
447 /*
448 * What a pain. We have to be really careful saving the upper 32 bits
449 * of any * register across function calls if we don't want them
450 * trashed--since were running in -o32, the calling routing never saves
451 * the full 64 bits of a register across a function call. Being the
452 * interrupt handler, we're guaranteed that interrupts are disabled
453 * during this code so we don't have to worry about random interrupts
454 * blasting the high 32 bits.
455 */
456
457 pending = read_c0_cause();
458
459#ifdef CONFIG_SIBYTE_SB1250_PROF
460 if (pending & CAUSEF_IP7) { /* Cpu performance counter interrupt */
461 sbprof_cpu_intr(exception_epc(regs));
462 }
463#endif
464
465 if (pending & CAUSEF_IP4)
466 sb1250_timer_interrupt(regs);
467
468#ifdef CONFIG_SMP
469 if (pending & CAUSEF_IP3)
470 sb1250_mailbox_interrupt(regs);
471#endif
472
473#ifdef CONFIG_KGDB
474 if (pending & CAUSEF_IP6) /* KGDB (uart 1) */
475 sb1250_kgdb_interrupt(regs);
476#endif
477
478 if (pending & CAUSEF_IP2) {
479 unsigned long long mask;
480
481 /*
482 * Default...we've hit an IP[2] interrupt, which means we've
483 * got to check the 1250 interrupt registers to figure out what
484 * to do. Need to detect which CPU we're on, now that
485 ~ smp_affinity is supported.
486 */
487 mask = __raw_readq(IOADDR(A_IMR_REGISTER(smp_processor_id(),
488 R_IMR_INTERRUPT_STATUS_BASE)));
489 if (mask)
490 do_IRQ(63 - dclz(mask), regs);
491 }
492}
diff --git a/arch/mips/sibyte/sb1250/irq_handler.S b/arch/mips/sibyte/sb1250/irq_handler.S
deleted file mode 100644
index 60edc8fb302b..000000000000
--- a/arch/mips/sibyte/sb1250/irq_handler.S
+++ /dev/null
@@ -1,147 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19/*
20 * sb1250_handle_int() is the routine that is actually called when an interrupt
21 * occurs. It is installed as the exception vector handler in arch_init_irq()
22 * in arch/mips/sibyte/sb1250/irq.c
23 *
24 * In the handle we figure out which interrupts need handling, and use that to
25 * call the dispatcher, which will take care of actually calling registered
26 * handlers
27 *
28 * Note that we take care of all raised interrupts in one go at the handler.
29 * This is more BSDish than the Indy code, and also, IMHO, more sane.
30 */
31#include <linux/config.h>
32
33#include <asm/addrspace.h>
34#include <asm/asm.h>
35#include <asm/mipsregs.h>
36#include <asm/regdef.h>
37#include <asm/stackframe.h>
38#include <asm/sibyte/sb1250_defs.h>
39#include <asm/sibyte/sb1250_regs.h>
40#include <asm/sibyte/sb1250_int.h>
41
42/*
43 * What a pain. We have to be really careful saving the upper 32 bits of any
44 * register across function calls if we don't want them trashed--since were
45 * running in -o32, the calling routing never saves the full 64 bits of a
46 * register across a function call. Being the interrupt handler, we're
47 * guaranteed that interrupts are disabled during this code so we don't have
48 * to worry about random interrupts blasting the high 32 bits.
49 */
50
51 .text
52 .set push
53 .set noreorder
54 .set noat
55 .set mips64
56 .align 5
57 NESTED(sb1250_irq_handler, PT_SIZE, sp)
58 SAVE_ALL
59 CLI
60
61#ifdef CONFIG_SIBYTE_SB1250_PROF
62 /* Set compare to count to silence count/compare timer interrupts */
63 mfc0 t1, CP0_COUNT
64 mtc0 t1, CP0_COMPARE /* pause to clear IP[7] bit of cause ? */
65#endif
66 /* Read cause */
67 mfc0 s0, CP0_CAUSE
68
69#ifdef CONFIG_SIBYTE_SB1250_PROF
70 /* Cpu performance counter interrupt is routed to IP[7] */
71 andi t1, s0, CAUSEF_IP7
72 beqz t1, 0f
73 srl t1, s0, (CAUSEB_BD-2) /* Shift BD bit to bit 2 */
74 and t1, t1, 0x4 /* mask to get just BD bit */
75 mfc0 a0, CP0_EPC
76 jal sbprof_cpu_intr
77 addu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */
78 j ret_from_irq
79 nop
800:
81#endif
82
83 /* Timer interrupt is routed to IP[4] */
84 andi t1, s0, CAUSEF_IP4
85 beqz t1, 1f
86 nop
87 jal sb1250_timer_interrupt
88 move a0, sp /* Pass the registers along */
89 j ret_from_irq
90 nop # delay slot
911:
92
93#ifdef CONFIG_SMP
94 /* Mailbox interrupt is routed to IP[3] */
95 andi t1, s0, CAUSEF_IP3
96 beqz t1, 2f
97 nop
98 jal sb1250_mailbox_interrupt
99 move a0, sp
100 j ret_from_irq
101 nop # delay slot
1022:
103#endif
104
105#ifdef CONFIG_KGDB
106 /* KGDB (uart 1) interrupt is routed to IP[6] */
107 andi t1, s0, CAUSEF_IP6
108 beqz t1, 1f
109 nop # delay slot
110 jal sb1250_kgdb_interrupt
111 move a0, sp
112 j ret_from_irq
113 nop # delay slot
1141:
115#endif
116
117 and t1, s0, CAUSEF_IP2
118 beqz t1, 4f
119 nop
120
121 /*
122 * Default...we've hit an IP[2] interrupt, which means we've got to
123 * check the 1250 interrupt registers to figure out what to do
124 * Need to detect which CPU we're on, now that smp_affinity is supported.
125 */
126 PTR_LA v0, CKSEG1 + A_IMR_CPU0_BASE
127#ifdef CONFIG_SMP
128 lw t1, TI_CPU($28)
129 sll t1, IMR_REGISTER_SPACING_SHIFT
130 addu v0, t1
131#endif
132 ld s0, R_IMR_INTERRUPT_STATUS_BASE(v0) /* read IP[2] status */
133
134 beqz s0, 4f /* No interrupts. Return */
135 move a1, sp
136
1373: dclz s1, s0 /* Find the next interrupt */
138 dsubu a0, zero, s1
139 daddiu a0, a0, 63
140 jal do_IRQ
141 nop
142
1434: j ret_from_irq
144 nop
145
146 .set pop
147 END(sb1250_irq_handler)
diff --git a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile
index 1e5676e4be86..9c7eaa5fb210 100644
--- a/arch/mips/sni/Makefile
+++ b/arch/mips/sni/Makefile
@@ -2,6 +2,6 @@
2# Makefile for the SNI specific part of the kernel 2# Makefile for the SNI specific part of the kernel
3# 3#
4 4
5obj-y += int-handler.o irq.o pcimt_scache.o reset.o setup.o 5obj-y += irq.o pcimt_scache.o reset.o setup.o
6 6
7EXTRA_AFLAGS := $(CFLAGS) 7EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/sni/int-handler.S b/arch/mips/sni/int-handler.S
deleted file mode 100644
index 2cdc09f55f18..000000000000
--- a/arch/mips/sni/int-handler.S
+++ /dev/null
@@ -1,106 +0,0 @@
1/*
2 * SNI RM200 PCI specific interrupt handler code.
3 *
4 * Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000, 01 by Ralf Baechle
5 */
6#include <asm/asm.h>
7#include <asm/mipsregs.h>
8#include <asm/regdef.h>
9#include <asm/sni.h>
10#include <asm/stackframe.h>
11
12/*
13 * The PCI ASIC has the nasty property that it may delay writes if it is busy.
14 * As a consequence from writes that have not graduated when we exit from the
15 * interrupt handler we might catch a spurious interrupt. To avoid this we
16 * force the PCI ASIC to graduate all writes by executing a read from the
17 * PCI bus.
18 */
19 .set noreorder
20 .set noat
21 .align 5
22 NESTED(sni_rm200_pci_handle_int, PT_SIZE, sp)
23 SAVE_ALL
24 CLI
25 .set at
26
27 /* Blinken light ... */
28 lb t0, led_cache
29 addiu t0, 1
30 sb t0, led_cache
31 sb t0, PCIMT_CSLED # write only register
32 .data
33led_cache: .byte 0
34 .text
35
36 mfc0 t0, CP0_STATUS
37 mfc0 t1, CP0_CAUSE
38 and t0, t1
39
40 andi t1, t0, 0x0800 # hardware interrupt 1
41 bnez t1, _hwint1
42 andi t1, t0, 0x4000 # hardware interrupt 4
43 bnez t1, _hwint4
44 andi t1, t0, 0x2000 # hardware interrupt 3
45 bnez t1, _hwint3
46 andi t1, t0, 0x1000 # hardware interrupt 2
47 bnez t1, _hwint2
48 andi t1, t0, 0x8000 # hardware interrupt 5
49 bnez t1, _hwint5
50 andi t1, t0, 0x0400 # hardware interrupt 0
51 bnez t1, _hwint0
52 nop
53
54 j restore_all # spurious interrupt
55 nop
56
57 ##############################################################################
58
59/* hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
60 button interrupts. */
61_hwint0: jal pciasic_hwint0
62 move a0, sp
63 j ret_from_irq
64 nop
65
66/*
67 * hwint 1 deals with EISA and SCSI interrupts
68 */
69_hwint1: jal pciasic_hwint1
70 move a0, sp
71 j ret_from_irq
72 nop
73
74
75/*
76 * This interrupt was used for the com1 console on the first prototypes;
77 * it's unsed otherwise
78 */
79_hwint2: jal pciasic_hwint2
80 move a0, sp
81 j ret_from_irq
82 nop
83
84/*
85 * hwint 3 are the PCI interrupts A - D
86 */
87_hwint3: jal pciasic_hwint3
88 move a0, sp
89 j ret_from_irq
90 nop
91
92/*
93 * hwint 4 is used for only the onboard PCnet 32.
94 */
95_hwint4: jal pciasic_hwint4
96 move a0, sp
97 j ret_from_irq
98 nop
99
100/* hwint5 is the r4k count / compare interrupt */
101_hwint5: jal pciasic_hwint5
102 move a0, sp
103 j ret_from_irq
104 nop
105
106 END(sni_rm200_pci_handle_int)
diff --git a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c
index 952038aa4b90..7365b4853ddb 100644
--- a/arch/mips/sni/irq.c
+++ b/arch/mips/sni/irq.c
@@ -19,8 +19,6 @@
19 19
20DEFINE_SPINLOCK(pciasic_lock); 20DEFINE_SPINLOCK(pciasic_lock);
21 21
22extern asmlinkage void sni_rm200_pci_handle_int(void);
23
24static void enable_pciasic_irq(unsigned int irq) 22static void enable_pciasic_irq(unsigned int irq)
25{ 23{
26 unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2); 24 unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2);
@@ -71,20 +69,20 @@ static struct hw_interrupt_type pciasic_irq_type = {
71 * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug 69 * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
72 * button interrupts. Later ... 70 * button interrupts. Later ...
73 */ 71 */
74void pciasic_hwint0(struct pt_regs *regs) 72static void pciasic_hwint0(struct pt_regs *regs)
75{ 73{
76 panic("Received int0 but no handler yet ..."); 74 panic("Received int0 but no handler yet ...");
77} 75}
78 76
79/* This interrupt was used for the com1 console on the first prototypes. */ 77/* This interrupt was used for the com1 console on the first prototypes. */
80void pciasic_hwint2(struct pt_regs *regs) 78static void pciasic_hwint2(struct pt_regs *regs)
81{ 79{
82 /* I think this shouldn't happen on production machines. */ 80 /* I think this shouldn't happen on production machines. */
83 panic("hwint2 and no handler yet"); 81 panic("hwint2 and no handler yet");
84} 82}
85 83
86/* hwint5 is the r4k count / compare interrupt */ 84/* hwint5 is the r4k count / compare interrupt */
87void pciasic_hwint5(struct pt_regs *regs) 85static void pciasic_hwint5(struct pt_regs *regs)
88{ 86{
89 panic("hwint5 and no handler yet"); 87 panic("hwint5 and no handler yet");
90} 88}
@@ -105,7 +103,7 @@ static unsigned int ls1bit8(unsigned int x)
105 * 103 *
106 * The EISA_INT bit in CSITPEND is high active, all others are low active. 104 * The EISA_INT bit in CSITPEND is high active, all others are low active.
107 */ 105 */
108void pciasic_hwint1(struct pt_regs *regs) 106static void pciasic_hwint1(struct pt_regs *regs)
109{ 107{
110 u8 pend = *(volatile char *)PCIMT_CSITPEND; 108 u8 pend = *(volatile char *)PCIMT_CSITPEND;
111 unsigned long flags; 109 unsigned long flags;
@@ -135,7 +133,7 @@ void pciasic_hwint1(struct pt_regs *regs)
135/* 133/*
136 * hwint 3 should deal with the PCI A - D interrupts, 134 * hwint 3 should deal with the PCI A - D interrupts,
137 */ 135 */
138void pciasic_hwint3(struct pt_regs *regs) 136static void pciasic_hwint3(struct pt_regs *regs)
139{ 137{
140 u8 pend = *(volatile char *)PCIMT_CSITPEND; 138 u8 pend = *(volatile char *)PCIMT_CSITPEND;
141 int irq; 139 int irq;
@@ -150,13 +148,34 @@ void pciasic_hwint3(struct pt_regs *regs)
150/* 148/*
151 * hwint 4 is used for only the onboard PCnet 32. 149 * hwint 4 is used for only the onboard PCnet 32.
152 */ 150 */
153void pciasic_hwint4(struct pt_regs *regs) 151static void pciasic_hwint4(struct pt_regs *regs)
154{ 152{
155 clear_c0_status(IE_IRQ4); 153 clear_c0_status(IE_IRQ4);
156 do_IRQ(PCIMT_IRQ_ETHERNET, regs); 154 do_IRQ(PCIMT_IRQ_ETHERNET, regs);
157 set_c0_status(IE_IRQ4); 155 set_c0_status(IE_IRQ4);
158} 156}
159 157
158asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
159{
160 unsigned int pending = read_c0_status() & read_c0_cause();
161 static unsigned char led_cache;
162
163 *(volatile unsigned char *) PCIMT_CSLED = ++led_cache;
164
165 if (pending & 0x0800)
166 pciasic_hwint1(regs);
167 else if (pending & 0x4000)
168 pciasic_hwint4(regs);
169 else if (pending & 0x2000)
170 pciasic_hwint3(regs);
171 else if (pending & 0x1000)
172 pciasic_hwint2(regs);
173 else if (pending & 0x8000)
174 pciasic_hwint5(regs);
175 else if (pending & 0x0400)
176 pciasic_hwint0(regs);
177}
178
160void __init init_pciasic(void) 179void __init init_pciasic(void)
161{ 180{
162 unsigned long flags; 181 unsigned long flags;
@@ -176,8 +195,6 @@ void __init arch_init_irq(void)
176{ 195{
177 int i; 196 int i;
178 197
179 set_except_vector(0, sni_rm200_pci_handle_int);
180
181 init_i8259_irqs(); /* Integrated i8259 */ 198 init_i8259_irqs(); /* Integrated i8259 */
182 init_pciasic(); 199 init_pciasic();
183 200
diff --git a/arch/mips/tx4927/common/Makefile b/arch/mips/tx4927/common/Makefile
index 8fa126b296e1..9cb9535ebacb 100644
--- a/arch/mips/tx4927/common/Makefile
+++ b/arch/mips/tx4927/common/Makefile
@@ -6,7 +6,7 @@
6# unless it's something special (ie not a .c file). 6# unless it's something special (ie not a .c file).
7# 7#
8 8
9obj-y += tx4927_prom.o tx4927_setup.o tx4927_irq.o tx4927_irq_handler.o 9obj-y += tx4927_prom.o tx4927_setup.o tx4927_irq.o
10 10
11obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o 11obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o
12obj-$(CONFIG_KGDB) += tx4927_dbgio.o 12obj-$(CONFIG_KGDB) += tx4927_dbgio.o
diff --git a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/tx4927/common/tx4927_irq.c
index 5ab2e2b76018..8ca68015cf40 100644
--- a/arch/mips/tx4927/common/tx4927_irq.c
+++ b/arch/mips/tx4927/common/tx4927_irq.c
@@ -525,8 +525,6 @@ static void tx4927_irq_pic_end(unsigned int irq)
525 */ 525 */
526void __init tx4927_irq_init(void) 526void __init tx4927_irq_init(void)
527{ 527{
528 extern asmlinkage void tx4927_irq_handler(void);
529
530 TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "-\n"); 528 TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "-\n");
531 529
532 TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_cp0_init()\n"); 530 TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_cp0_init()\n");
@@ -535,16 +533,12 @@ void __init tx4927_irq_init(void)
535 TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_pic_init()\n"); 533 TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_pic_init()\n");
536 tx4927_irq_pic_init(); 534 tx4927_irq_pic_init();
537 535
538 TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT,
539 "=Calling set_except_vector(tx4927_irq_handler)\n");
540 set_except_vector(0, tx4927_irq_handler);
541
542 TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "+\n"); 536 TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "+\n");
543 537
544 return; 538 return;
545} 539}
546 540
547int tx4927_irq_nested(void) 541static int tx4927_irq_nested(void)
548{ 542{
549 int sw_irq = 0; 543 int sw_irq = 0;
550 u32 level2; 544 u32 level2;
@@ -582,3 +576,25 @@ int tx4927_irq_nested(void)
582 576
583 return (sw_irq); 577 return (sw_irq);
584} 578}
579
580asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
581{
582 unsigned int pending = read_c0_status() & read_c0_cause();
583
584 if (pending & STATUSF_IP7) /* cpu timer */
585 do_IRQ(TX4927_IRQ_CPU_TIMER, regs);
586 else if (pending & STATUSF_IP2) { /* tx4927 pic */
587 unsigned int irq = tx4927_irq_nested();
588
589 if (unlikely(irq == 0)) {
590 spurious_interrupt(regs);
591 return;
592 }
593 do_IRQ(irq, regs);
594 } else if (pending & STATUSF_IP0) /* user line 0 */
595 do_IRQ(TX4927_IRQ_USER0, regs);
596 else if (pending & STATUSF_IP1) /* user line 1 */
597 do_IRQ(TX4927_IRQ_USER1, regs);
598 else
599 spurious_interrupt(regs);
600}
diff --git a/arch/mips/tx4927/common/tx4927_irq_handler.S b/arch/mips/tx4927/common/tx4927_irq_handler.S
deleted file mode 100644
index dd3ceda9d712..000000000000
--- a/arch/mips/tx4927/common/tx4927_irq_handler.S
+++ /dev/null
@@ -1,103 +0,0 @@
1/*
2 * linux/arch/mips/tx4927/common/tx4927_irq_handler.S
3 *
4 * Primary interrupt handler for tx4927 based systems
5 *
6 * Author: MontaVista Software, Inc.
7 * Author: jsun@mvista.com or jsun@junsun.net
8 * source@mvista.com
9 *
10 * Copyright 2001-2002 MontaVista Software Inc.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
23 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
25 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
26 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * You should have received a copy of the GNU General Public License along
29 * with this program; if not, write to the Free Software Foundation, Inc.,
30 * 675 Mass Ave, Cambridge, MA 02139, USA.
31 */
32#include <asm/asm.h>
33#include <asm/mipsregs.h>
34#include <asm/addrspace.h>
35#include <asm/regdef.h>
36#include <asm/stackframe.h>
37#include <asm/tx4927/tx4927.h>
38
39 .align 5
40 NESTED(tx4927_irq_handler, PT_SIZE, sp)
41 SAVE_ALL
42 CLI
43 .set at
44
45 mfc0 t0, CP0_CAUSE
46 mfc0 t1, CP0_STATUS
47 and t0, t1
48
49 andi t1, t0, STATUSF_IP7 /* cpu timer */
50 bnez t1, ll_ip7
51
52 /* IP6..IP3 multiplexed -- do not use */
53
54 andi t1, t0, STATUSF_IP2 /* tx4927 pic */
55 bnez t1, ll_ip2
56
57 andi t1, t0, STATUSF_IP0 /* user line 0 */
58 bnez t1, ll_ip0
59
60 andi t1, t0, STATUSF_IP1 /* user line 1 */
61 bnez t1, ll_ip1
62
63 .set reorder
64
65 /* wrong alarm or masked ... */
66 j spurious_interrupt
67 nop
68 END(tx4927_irq_handler)
69
70 .align 5
71
72
73ll_ip7:
74 li a0, TX4927_IRQ_CPU_TIMER
75 move a1, sp
76 jal do_IRQ
77 j ret_from_irq
78
79ll_ip2:
80 jal tx4927_irq_nested
81 nop
82 beqz v0, goto_spurious_interrupt
83 nop
84 move a0, v0
85 move a1, sp
86 jal do_IRQ
87 j ret_from_irq
88
89goto_spurious_interrupt:
90 j spurious_interrupt
91 nop
92
93ll_ip1:
94 li a0, TX4927_IRQ_USER1
95 move a1, sp
96 jal do_IRQ
97 j ret_from_irq
98
99ll_ip0:
100 li a0, TX4927_IRQ_USER0
101 move a1, sp
102 jal do_IRQ
103 j ret_from_irq
diff --git a/arch/mips/tx4938/common/Makefile b/arch/mips/tx4938/common/Makefile
index 74c95c5bcdbf..2033ae77f632 100644
--- a/arch/mips/tx4938/common/Makefile
+++ b/arch/mips/tx4938/common/Makefile
@@ -6,6 +6,6 @@
6# unless it's something special (ie not a .c file). 6# unless it's something special (ie not a .c file).
7# 7#
8 8
9obj-y += prom.o setup.o irq.o irq_handler.o rtc_rx5c348.o 9obj-y += prom.o setup.o irq.o rtc_rx5c348.o
10obj-$(CONFIG_KGDB) += dbgio.o 10obj-$(CONFIG_KGDB) += dbgio.o
11 11
diff --git a/arch/mips/tx4938/common/irq.c b/arch/mips/tx4938/common/irq.c
index 4f90d7faf634..873805178d8e 100644
--- a/arch/mips/tx4938/common/irq.c
+++ b/arch/mips/tx4938/common/irq.c
@@ -392,11 +392,8 @@ tx4938_irq_pic_end(unsigned int irq)
392void __init 392void __init
393tx4938_irq_init(void) 393tx4938_irq_init(void)
394{ 394{
395 extern asmlinkage void tx4938_irq_handler(void);
396
397 tx4938_irq_cp0_init(); 395 tx4938_irq_cp0_init();
398 tx4938_irq_pic_init(); 396 tx4938_irq_pic_init();
399 set_except_vector(0, tx4938_irq_handler);
400 397
401 return; 398 return;
402} 399}
@@ -422,3 +419,21 @@ tx4938_irq_nested(void)
422 wbflush(); 419 wbflush();
423 return (sw_irq); 420 return (sw_irq);
424} 421}
422
423asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
424{
425 unsigned int pending = read_c0_cause() & read_c0_status();
426
427 if (pending & STATUSF_IP7)
428 do_IRQ(TX4938_IRQ_CPU_TIMER, regs);
429 else if (pending & STATUSF_IP2) {
430 int irq = tx4938_irq_nested();
431 if (irq)
432 do_IRQ(irq, regs);
433 else
434 spurious_interrupt(regs);
435 } else if (pending & STATUSF_IP1)
436 do_IRQ(TX4938_IRQ_USER1, regs);
437 else if (pending & STATUSF_IP0)
438 do_IRQ(TX4938_IRQ_USER0, regs);
439}
diff --git a/arch/mips/tx4938/common/irq_handler.S b/arch/mips/tx4938/common/irq_handler.S
deleted file mode 100644
index 1b2f72bac42d..000000000000
--- a/arch/mips/tx4938/common/irq_handler.S
+++ /dev/null
@@ -1,84 +0,0 @@
1/*
2 * linux/arch/mips/tx4938/common/handler.S
3 *
4 * Primary interrupt handler for tx4938 based systems
5 * Copyright (C) 2000-2001 Toshiba Corporation
6 *
7 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the
8 * terms of the GNU General Public License version 2. This program is
9 * licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 *
12 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com)
13 */
14#include <asm/asm.h>
15#include <asm/mipsregs.h>
16#include <asm/addrspace.h>
17#include <asm/regdef.h>
18#include <asm/stackframe.h>
19#include <asm/tx4938/rbtx4938.h>
20
21
22 .align 5
23 NESTED(tx4938_irq_handler, PT_SIZE, sp)
24 SAVE_ALL
25 CLI
26 .set at
27
28 mfc0 t0, CP0_CAUSE
29 mfc0 t1, CP0_STATUS
30 and t0, t1
31
32 andi t1, t0, STATUSF_IP7 /* cpu timer */
33 bnez t1, ll_ip7
34
35 /* IP6..IP3 multiplexed -- do not use */
36
37 andi t1, t0, STATUSF_IP2 /* tx4938 pic */
38 bnez t1, ll_ip2
39
40 andi t1, t0, STATUSF_IP1 /* user line 1 */
41 bnez t1, ll_ip1
42
43 andi t1, t0, STATUSF_IP0 /* user line 0 */
44 bnez t1, ll_ip0
45
46 .set reorder
47
48 nop
49 END(tx4938_irq_handler)
50
51 .align 5
52
53
54ll_ip7:
55 li a0, TX4938_IRQ_CPU_TIMER
56 move a1, sp
57 jal do_IRQ
58 j ret_from_irq
59
60
61ll_ip2:
62 jal tx4938_irq_nested
63 nop
64 beqz v0, goto_spurious_interrupt
65 nop
66 move a0, v0
67 move a1, sp
68 jal do_IRQ
69 j ret_from_irq
70
71goto_spurious_interrupt:
72 j ret_from_irq
73
74ll_ip1:
75 li a0, TX4938_IRQ_USER1
76 move a1, sp
77 jal do_IRQ
78 j ret_from_irq
79
80ll_ip0:
81 li a0, TX4938_IRQ_USER0
82 move a1, sp
83 jal do_IRQ
84 j ret_from_irq
diff --git a/arch/mips/vr41xx/Kconfig b/arch/mips/vr41xx/Kconfig
index a7add16c9aa4..055a2cdfc841 100644
--- a/arch/mips/vr41xx/Kconfig
+++ b/arch/mips/vr41xx/Kconfig
@@ -4,6 +4,8 @@ config CASIO_E55
4 select DMA_NONCOHERENT 4 select DMA_NONCOHERENT
5 select IRQ_CPU 5 select IRQ_CPU
6 select ISA 6 select ISA
7 select SYS_HAS_CPU_VR41XX
8 select SYS_SUPPORTS_32BIT_KERNEL
7 select SYS_SUPPORTS_LITTLE_ENDIAN 9 select SYS_SUPPORTS_LITTLE_ENDIAN
8 10
9config IBM_WORKPAD 11config IBM_WORKPAD
@@ -12,6 +14,8 @@ config IBM_WORKPAD
12 select DMA_NONCOHERENT 14 select DMA_NONCOHERENT
13 select IRQ_CPU 15 select IRQ_CPU
14 select ISA 16 select ISA
17 select SYS_HAS_CPU_VR41XX
18 select SYS_SUPPORTS_32BIT_KERNEL
15 select SYS_SUPPORTS_LITTLE_ENDIAN 19 select SYS_SUPPORTS_LITTLE_ENDIAN
16 20
17config NEC_CMBVR4133 21config NEC_CMBVR4133
@@ -21,6 +25,9 @@ config NEC_CMBVR4133
21 select DMA_NONCOHERENT 25 select DMA_NONCOHERENT
22 select IRQ_CPU 26 select IRQ_CPU
23 select HW_HAS_PCI 27 select HW_HAS_PCI
28 select SYS_HAS_CPU_VR41XX
29 select SYS_SUPPORTS_32BIT_KERNEL
30 select SYS_SUPPORTS_LITTLE_ENDIAN
24 31
25config ROCKHOPPER 32config ROCKHOPPER
26 bool "Support for Rockhopper baseboard" 33 bool "Support for Rockhopper baseboard"
@@ -34,6 +41,8 @@ config TANBAC_TB022X
34 select DMA_NONCOHERENT 41 select DMA_NONCOHERENT
35 select HW_HAS_PCI 42 select HW_HAS_PCI
36 select IRQ_CPU 43 select IRQ_CPU
44 select SYS_HAS_CPU_VR41XX
45 select SYS_SUPPORTS_32BIT_KERNEL
37 select SYS_SUPPORTS_LITTLE_ENDIAN 46 select SYS_SUPPORTS_LITTLE_ENDIAN
38 help 47 help
39 The TANBAC VR4131 multichip module(TB0225) and 48 The TANBAC VR4131 multichip module(TB0225) and
@@ -65,6 +74,8 @@ config VICTOR_MPC30X
65 select DMA_NONCOHERENT 74 select DMA_NONCOHERENT
66 select HW_HAS_PCI 75 select HW_HAS_PCI
67 select IRQ_CPU 76 select IRQ_CPU
77 select SYS_HAS_CPU_VR41XX
78 select SYS_SUPPORTS_32BIT_KERNEL
68 select SYS_SUPPORTS_LITTLE_ENDIAN 79 select SYS_SUPPORTS_LITTLE_ENDIAN
69 80
70config ZAO_CAPCELLA 81config ZAO_CAPCELLA
@@ -73,6 +84,8 @@ config ZAO_CAPCELLA
73 select DMA_NONCOHERENT 84 select DMA_NONCOHERENT
74 select HW_HAS_PCI 85 select HW_HAS_PCI
75 select IRQ_CPU 86 select IRQ_CPU
87 select SYS_HAS_CPU_VR41XX
88 select SYS_SUPPORTS_32BIT_KERNEL
76 select SYS_SUPPORTS_LITTLE_ENDIAN 89 select SYS_SUPPORTS_LITTLE_ENDIAN
77 90
78config PCI_VR41XX 91config PCI_VR41XX
diff --git a/arch/mips/vr41xx/common/Makefile b/arch/mips/vr41xx/common/Makefile
index 9096302a7ecc..aa373974c80f 100644
--- a/arch/mips/vr41xx/common/Makefile
+++ b/arch/mips/vr41xx/common/Makefile
@@ -2,7 +2,7 @@
2# Makefile for common code of the NEC VR4100 series. 2# Makefile for common code of the NEC VR4100 series.
3# 3#
4 4
5obj-y += bcu.o cmu.o icu.o init.o int-handler.o irq.o pmu.o type.o 5obj-y += bcu.o cmu.o icu.o init.o irq.o pmu.o type.o
6obj-$(CONFIG_VRC4173) += vrc4173.o 6obj-$(CONFIG_VRC4173) += vrc4173.o
7 7
8EXTRA_AFLAGS := $(CFLAGS) 8EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/vr41xx/common/int-handler.S b/arch/mips/vr41xx/common/int-handler.S
deleted file mode 100644
index 2b6043f16d09..000000000000
--- a/arch/mips/vr41xx/common/int-handler.S
+++ /dev/null
@@ -1,114 +0,0 @@
1/*
2 * FILE NAME
3 * arch/mips/vr41xx/common/int-handler.S
4 *
5 * BRIEF MODULE DESCRIPTION
6 * Interrupt dispatcher for the NEC VR4100 series.
7 *
8 * Author: Yoichi Yuasa
9 * yyuasa@mvista.com or source@mvista.com
10 *
11 * Copyright 2001 MontaVista Software Inc.
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
26 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
27 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * You should have received a copy of the GNU General Public License along
30 * with this program; if not, write to the Free Software Foundation, Inc.,
31 * 675 Mass Ave, Cambridge, MA 02139, USA.
32 */
33/*
34 * Changes:
35 * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com>
36 * - New creation, NEC VR4100 series are supported.
37 *
38 * Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
39 * - Coped with INTASSIGN of NEC VR4133.
40 */
41#include <asm/asm.h>
42#include <asm/regdef.h>
43#include <asm/mipsregs.h>
44#include <asm/stackframe.h>
45
46 .text
47 .set noreorder
48
49 .align 5
50 NESTED(vr41xx_handle_interrupt, PT_SIZE, ra)
51 .set noat
52 SAVE_ALL
53 CLI
54 .set at
55 .set noreorder
56
57 /*
58 * Get the pending interrupts
59 */
60 mfc0 t0, CP0_CAUSE
61 mfc0 t1, CP0_STATUS
62 andi t0, 0xff00
63 and t0, t0, t1
64
65 andi t1, t0, CAUSEF_IP7 # MIPS timer interrupt
66 bnez t1, handle_irq
67 li a0, 7
68
69 andi t1, t0, 0x7800 # check for Int1-4
70 beqz t1, 1f
71
72 andi t1, t0, CAUSEF_IP3 # check for Int1
73 bnez t1, handle_int
74 li a0, 3
75
76 andi t1, t0, CAUSEF_IP4 # check for Int2
77 bnez t1, handle_int
78 li a0, 4
79
80 andi t1, t0, CAUSEF_IP5 # check for Int3
81 bnez t1, handle_int
82 li a0, 5
83
84 andi t1, t0, CAUSEF_IP6 # check for Int4
85 bnez t1, handle_int
86 li a0, 6
87
881:
89 andi t1, t0, CAUSEF_IP2 # check for Int0
90 bnez t1, handle_int
91 li a0, 2
92
93 andi t1, t0, CAUSEF_IP0 # check for IP0
94 bnez t1, handle_irq
95 li a0, 0
96
97 andi t1, t0, CAUSEF_IP1 # check for IP1
98 bnez t1, handle_irq
99 li a0, 1
100
101 j spurious_interrupt
102 nop
103
104handle_int:
105 jal irq_dispatch
106 move a1, sp
107 j ret_from_irq
108 nop
109
110handle_irq:
111 jal do_IRQ
112 move a1, sp
113 j ret_from_irq
114 END(vr41xx_handle_interrupt)
diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c
index 61aa264275ff..86796bb63c3c 100644
--- a/arch/mips/vr41xx/common/irq.c
+++ b/arch/mips/vr41xx/common/irq.c
@@ -59,7 +59,7 @@ int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int, struct pt_regs *)
59 59
60EXPORT_SYMBOL_GPL(cascade_irq); 60EXPORT_SYMBOL_GPL(cascade_irq);
61 61
62asmlinkage void irq_dispatch(unsigned int irq, struct pt_regs *regs) 62static void irq_dispatch(unsigned int irq, struct pt_regs *regs)
63{ 63{
64 irq_cascade_t *cascade; 64 irq_cascade_t *cascade;
65 irq_desc_t *desc; 65 irq_desc_t *desc;
@@ -84,11 +84,32 @@ asmlinkage void irq_dispatch(unsigned int irq, struct pt_regs *regs)
84 do_IRQ(irq, regs); 84 do_IRQ(irq, regs);
85} 85}
86 86
87extern asmlinkage void vr41xx_handle_interrupt(void); 87asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
88{
89 unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
90
91 if (pending & CAUSEF_IP7)
92 do_IRQ(7, regs);
93 else if (pending & 0x7800) {
94 if (pending & CAUSEF_IP3)
95 irq_dispatch(3, regs);
96 else if (pending & CAUSEF_IP4)
97 irq_dispatch(4, regs);
98 else if (pending & CAUSEF_IP5)
99 irq_dispatch(5, regs);
100 else if (pending & CAUSEF_IP6)
101 irq_dispatch(6, regs);
102 } else if (pending & CAUSEF_IP2)
103 irq_dispatch(2, regs);
104 else if (pending & CAUSEF_IP0)
105 do_IRQ(0, regs);
106 else if (pending & CAUSEF_IP1)
107 do_IRQ(1, regs);
108 else
109 spurious_interrupt(regs);
110}
88 111
89void __init arch_init_irq(void) 112void __init arch_init_irq(void)
90{ 113{
91 mips_cpu_irq_init(MIPS_CPU_IRQ_BASE); 114 mips_cpu_irq_init(MIPS_CPU_IRQ_BASE);
92
93 set_except_vector(0, vr41xx_handle_interrupt);
94} 115}
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 2fdf21989dc2..19f911c5dd58 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -177,6 +177,11 @@ config ARCH_DISCONTIGMEM_DEFAULT
177 def_bool y 177 def_bool y
178 depends on ARCH_DISCONTIGMEM_ENABLE 178 depends on ARCH_DISCONTIGMEM_ENABLE
179 179
180config NODES_SHIFT
181 int
182 default "3"
183 depends on NEED_MULTIPLE_NODES
184
180source "kernel/Kconfig.preempt" 185source "kernel/Kconfig.preempt"
181source "kernel/Kconfig.hz" 186source "kernel/Kconfig.hz"
182source "mm/Kconfig" 187source "mm/Kconfig"
diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c
index 47ca5c0a323b..fc107add627c 100644
--- a/arch/parisc/kernel/parisc_ksyms.c
+++ b/arch/parisc/kernel/parisc_ksyms.c
@@ -31,7 +31,6 @@
31 31
32#include <linux/string.h> 32#include <linux/string.h>
33EXPORT_SYMBOL(memset); 33EXPORT_SYMBOL(memset);
34EXPORT_SYMBOL(strpbrk);
35 34
36#include <asm/atomic.h> 35#include <asm/atomic.h>
37EXPORT_SYMBOL(__xchg8); 36EXPORT_SYMBOL(__xchg8);
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 2cdc35ce8045..6729c98b66f9 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -366,6 +366,7 @@ config PPC_PMAC64
366 select U3_DART 366 select U3_DART
367 select MPIC_BROKEN_U3 367 select MPIC_BROKEN_U3
368 select GENERIC_TBSYNC 368 select GENERIC_TBSYNC
369 select PPC_970_NAP
369 default y 370 default y
370 371
371config PPC_PREP 372config PPC_PREP
@@ -383,6 +384,7 @@ config PPC_MAPLE
383 select MPIC_BROKEN_U3 384 select MPIC_BROKEN_U3
384 select GENERIC_TBSYNC 385 select GENERIC_TBSYNC
385 select PPC_UDBG_16550 386 select PPC_UDBG_16550
387 select PPC_970_NAP
386 default n 388 default n
387 help 389 help
388 This option enables support for the Maple 970FX Evaluation Board. 390 This option enables support for the Maple 970FX Evaluation Board.
@@ -457,6 +459,10 @@ config PPC_MPC106
457 bool 459 bool
458 default n 460 default n
459 461
462config PPC_970_NAP
463 bool
464 default n
465
460source "drivers/cpufreq/Kconfig" 466source "drivers/cpufreq/Kconfig"
461 467
462config CPU_FREQ_PMAC 468config CPU_FREQ_PMAC
@@ -649,6 +655,11 @@ config NUMA
649 depends on PPC64 655 depends on PPC64
650 default y if SMP && PPC_PSERIES 656 default y if SMP && PPC_PSERIES
651 657
658config NODES_SHIFT
659 int
660 default "4"
661 depends on NEED_MULTIPLE_NODES
662
652config ARCH_SELECT_MEMORY_MODEL 663config ARCH_SELECT_MEMORY_MODEL
653 def_bool y 664 def_bool y
654 depends on PPC64 665 depends on PPC64
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 6ec84d37a337..ed5b26aa8be3 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -104,6 +104,10 @@ ifndef CONFIG_FSL_BOOKE
104CFLAGS += -mstring 104CFLAGS += -mstring
105endif 105endif
106 106
107ifeq ($(CONFIG_6xx),y)
108CFLAGS += -mcpu=powerpc
109endif
110
107cpu-as-$(CONFIG_PPC64BRIDGE) += -Wa,-mppc64bridge 111cpu-as-$(CONFIG_PPC64BRIDGE) += -Wa,-mppc64bridge
108cpu-as-$(CONFIG_4xx) += -Wa,-m405 112cpu-as-$(CONFIG_4xx) += -Wa,-m405
109cpu-as-$(CONFIG_6xx) += -Wa,-maltivec 113cpu-as-$(CONFIG_6xx) += -Wa,-maltivec
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 0cc0995b81b0..803858e86160 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -20,7 +20,7 @@ obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
20 firmware.o sysfs.o 20 firmware.o sysfs.o
21obj-$(CONFIG_PPC64) += vdso64/ 21obj-$(CONFIG_PPC64) += vdso64/
22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o 22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
23obj-$(CONFIG_POWER4) += idle_power4.o 23obj-$(CONFIG_PPC_970_NAP) += idle_power4.o
24obj-$(CONFIG_PPC_OF) += of_device.o prom_parse.o 24obj-$(CONFIG_PPC_OF) += of_device.o prom_parse.o
25procfs-$(CONFIG_PPC64) := proc_ppc64.o 25procfs-$(CONFIG_PPC64) := proc_ppc64.o
26obj-$(CONFIG_PROC_FS) += $(procfs-y) 26obj-$(CONFIG_PROC_FS) += $(procfs-y)
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 54b48f330051..8f85c5e8a55a 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -91,6 +91,7 @@ int main(void)
91#endif /* CONFIG_PPC64 */ 91#endif /* CONFIG_PPC64 */
92 92
93 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); 93 DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
94 DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags));
94 DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); 95 DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
95 DEFINE(TI_TASK, offsetof(struct thread_info, task)); 96 DEFINE(TI_TASK, offsetof(struct thread_info, task));
96#ifdef CONFIG_PPC32 97#ifdef CONFIG_PPC32
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index b3a979467225..8866fd26c6b9 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -128,37 +128,36 @@ transfer_to_handler:
128 stw r12,4(r11) 128 stw r12,4(r11)
129#endif 129#endif
130 b 3f 130 b 3f
131
1312: /* if from kernel, check interrupted DOZE/NAP mode and 1322: /* if from kernel, check interrupted DOZE/NAP mode and
132 * check for stack overflow 133 * check for stack overflow
133 */ 134 */
135 lwz r9,THREAD_INFO-THREAD(r12)
136 cmplw r1,r9 /* if r1 <= current->thread_info */
137 ble- stack_ovf /* then the kernel stack overflowed */
1385:
134#ifdef CONFIG_6xx 139#ifdef CONFIG_6xx
135 mfspr r11,SPRN_HID0 140 tophys(r9,r9) /* check local flags */
136 mtcr r11 141 lwz r12,TI_LOCAL_FLAGS(r9)
137BEGIN_FTR_SECTION 142 mtcrf 0x01,r12
138 bt- 8,4f /* Check DOZE */ 143 bt- 31-TLF_NAPPING,4f
139END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
140BEGIN_FTR_SECTION
141 bt- 9,4f /* Check NAP */
142END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
143#endif /* CONFIG_6xx */ 144#endif /* CONFIG_6xx */
144 .globl transfer_to_handler_cont 145 .globl transfer_to_handler_cont
145transfer_to_handler_cont: 146transfer_to_handler_cont:
146 lwz r11,THREAD_INFO-THREAD(r12)
147 cmplw r1,r11 /* if r1 <= current->thread_info */
148 ble- stack_ovf /* then the kernel stack overflowed */
1493: 1473:
150 mflr r9 148 mflr r9
151 lwz r11,0(r9) /* virtual address of handler */ 149 lwz r11,0(r9) /* virtual address of handler */
152 lwz r9,4(r9) /* where to go when done */ 150 lwz r9,4(r9) /* where to go when done */
153 FIX_SRR1(r10,r12)
154 mtspr SPRN_SRR0,r11 151 mtspr SPRN_SRR0,r11
155 mtspr SPRN_SRR1,r10 152 mtspr SPRN_SRR1,r10
156 mtlr r9 153 mtlr r9
157 SYNC 154 SYNC
158 RFI /* jump to handler, enable MMU */ 155 RFI /* jump to handler, enable MMU */
159 156
160#ifdef CONFIG_6xx 157#ifdef CONFIG_6xx
1614: b power_save_6xx_restore 1584: rlwinm r12,r12,0,~_TLF_NAPPING
159 stw r12,TI_LOCAL_FLAGS(r9)
160 b power_save_6xx_restore
162#endif 161#endif
163 162
164/* 163/*
@@ -167,10 +166,10 @@ transfer_to_handler_cont:
167 */ 166 */
168stack_ovf: 167stack_ovf:
169 /* sometimes we use a statically-allocated stack, which is OK. */ 168 /* sometimes we use a statically-allocated stack, which is OK. */
170 lis r11,_end@h 169 lis r12,_end@h
171 ori r11,r11,_end@l 170 ori r12,r12,_end@l
172 cmplw r1,r11 171 cmplw r1,r12
173 ble 3b /* r1 <= &_end is OK */ 172 ble 5b /* r1 <= &_end is OK */
174 SAVE_NVGPRS(r11) 173 SAVE_NVGPRS(r11)
175 addi r3,r1,STACK_FRAME_OVERHEAD 174 addi r3,r1,STACK_FRAME_OVERHEAD
176 lis r1,init_thread_union@ha 175 lis r1,init_thread_union@ha
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index a5ae04a57c78..b7d140430a41 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -376,11 +376,28 @@ label##_common: \
376 bl hdlr; \ 376 bl hdlr; \
377 b .ret_from_except 377 b .ret_from_except
378 378
379/*
380 * Like STD_EXCEPTION_COMMON, but for exceptions that can occur
381 * in the idle task and therefore need the special idle handling.
382 */
383#define STD_EXCEPTION_COMMON_IDLE(trap, label, hdlr) \
384 .align 7; \
385 .globl label##_common; \
386label##_common: \
387 EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \
388 FINISH_NAP; \
389 DISABLE_INTS; \
390 bl .save_nvgprs; \
391 addi r3,r1,STACK_FRAME_OVERHEAD; \
392 bl hdlr; \
393 b .ret_from_except
394
379#define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr) \ 395#define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr) \
380 .align 7; \ 396 .align 7; \
381 .globl label##_common; \ 397 .globl label##_common; \
382label##_common: \ 398label##_common: \
383 EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ 399 EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \
400 FINISH_NAP; \
384 DISABLE_INTS; \ 401 DISABLE_INTS; \
385 bl .ppc64_runlatch_on; \ 402 bl .ppc64_runlatch_on; \
386 addi r3,r1,STACK_FRAME_OVERHEAD; \ 403 addi r3,r1,STACK_FRAME_OVERHEAD; \
@@ -388,6 +405,25 @@ label##_common: \
388 b .ret_from_except_lite 405 b .ret_from_except_lite
389 406
390/* 407/*
408 * When the idle code in power4_idle puts the CPU into NAP mode,
409 * it has to do so in a loop, and relies on the external interrupt
410 * and decrementer interrupt entry code to get it out of the loop.
411 * It sets the _TLF_NAPPING bit in current_thread_info()->local_flags
412 * to signal that it is in the loop and needs help to get out.
413 */
414#ifdef CONFIG_PPC_970_NAP
415#define FINISH_NAP \
416BEGIN_FTR_SECTION \
417 clrrdi r11,r1,THREAD_SHIFT; \
418 ld r9,TI_LOCAL_FLAGS(r11); \
419 andi. r10,r9,_TLF_NAPPING; \
420 bnel power4_fixup_nap; \
421END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
422#else
423#define FINISH_NAP
424#endif
425
426/*
391 * Start of pSeries system interrupt routines 427 * Start of pSeries system interrupt routines
392 */ 428 */
393 . = 0x100 429 . = 0x100
@@ -772,6 +808,7 @@ hardware_interrupt_iSeries_masked:
772 .globl machine_check_common 808 .globl machine_check_common
773machine_check_common: 809machine_check_common:
774 EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC) 810 EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
811 FINISH_NAP
775 DISABLE_INTS 812 DISABLE_INTS
776 bl .save_nvgprs 813 bl .save_nvgprs
777 addi r3,r1,STACK_FRAME_OVERHEAD 814 addi r3,r1,STACK_FRAME_OVERHEAD
@@ -783,7 +820,7 @@ machine_check_common:
783 STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) 820 STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
784 STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) 821 STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
785 STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) 822 STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
786 STD_EXCEPTION_COMMON(0xf00, performance_monitor, .performance_monitor_exception) 823 STD_EXCEPTION_COMMON_IDLE(0xf00, performance_monitor, .performance_monitor_exception)
787 STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception) 824 STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
788#ifdef CONFIG_ALTIVEC 825#ifdef CONFIG_ALTIVEC
789 STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception) 826 STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
@@ -1034,6 +1071,7 @@ unrecov_slb:
1034 .globl hardware_interrupt_entry 1071 .globl hardware_interrupt_entry
1035hardware_interrupt_common: 1072hardware_interrupt_common:
1036 EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN) 1073 EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN)
1074 FINISH_NAP
1037hardware_interrupt_entry: 1075hardware_interrupt_entry:
1038 DISABLE_INTS 1076 DISABLE_INTS
1039 bl .ppc64_runlatch_on 1077 bl .ppc64_runlatch_on
@@ -1041,6 +1079,15 @@ hardware_interrupt_entry:
1041 bl .do_IRQ 1079 bl .do_IRQ
1042 b .ret_from_except_lite 1080 b .ret_from_except_lite
1043 1081
1082#ifdef CONFIG_PPC_970_NAP
1083power4_fixup_nap:
1084 andc r9,r9,r10
1085 std r9,TI_LOCAL_FLAGS(r11)
1086 ld r10,_LINK(r1) /* make idle task do the */
1087 std r10,_NIP(r1) /* equivalent of a blr */
1088 blr
1089#endif
1090
1044 .align 7 1091 .align 7
1045 .globl alignment_common 1092 .globl alignment_common
1046alignment_common: 1093alignment_common:
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
index e9f321d74d85..d491052c8e0c 100644
--- a/arch/powerpc/kernel/idle.c
+++ b/arch/powerpc/kernel/idle.c
@@ -50,9 +50,9 @@ void cpu_idle(void)
50 50
51 set_thread_flag(TIF_POLLING_NRFLAG); 51 set_thread_flag(TIF_POLLING_NRFLAG);
52 while (1) { 52 while (1) {
53 ppc64_runlatch_off();
54
55 while (!need_resched() && !cpu_should_die()) { 53 while (!need_resched() && !cpu_should_die()) {
54 ppc64_runlatch_off();
55
56 if (ppc_md.power_save) { 56 if (ppc_md.power_save) {
57 clear_thread_flag(TIF_POLLING_NRFLAG); 57 clear_thread_flag(TIF_POLLING_NRFLAG);
58 /* 58 /*
diff --git a/arch/powerpc/kernel/idle_6xx.S b/arch/powerpc/kernel/idle_6xx.S
index 12a4efbaa08f..b45fa0e37212 100644
--- a/arch/powerpc/kernel/idle_6xx.S
+++ b/arch/powerpc/kernel/idle_6xx.S
@@ -22,8 +22,6 @@
22#include <asm/ppc_asm.h> 22#include <asm/ppc_asm.h>
23#include <asm/asm-offsets.h> 23#include <asm/asm-offsets.h>
24 24
25#undef DEBUG
26
27 .text 25 .text
28 26
29/* 27/*
@@ -109,12 +107,6 @@ BEGIN_FTR_SECTION
109 dcbf 0,r4 107 dcbf 0,r4
110 dcbf 0,r4 108 dcbf 0,r4
111END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) 109END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
112#ifdef DEBUG
113 lis r6,nap_enter_count@ha
114 lwz r4,nap_enter_count@l(r6)
115 addi r4,r4,1
116 stw r4,nap_enter_count@l(r6)
117#endif
1182: 1102:
119BEGIN_FTR_SECTION 111BEGIN_FTR_SECTION
120 /* Go to low speed mode on some 750FX */ 112 /* Go to low speed mode on some 750FX */
@@ -144,48 +136,42 @@ BEGIN_FTR_SECTION
144 DSSALL 136 DSSALL
145 sync 137 sync
146END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) 138END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
139 rlwinm r9,r1,0,0,31-THREAD_SHIFT /* current thread_info */
140 lwz r8,TI_LOCAL_FLAGS(r9) /* set napping bit */
141 ori r8,r8,_TLF_NAPPING /* so when we take an exception */
142 stw r8,TI_LOCAL_FLAGS(r9) /* it will return to our caller */
147 mfmsr r7 143 mfmsr r7
148 ori r7,r7,MSR_EE 144 ori r7,r7,MSR_EE
149 oris r7,r7,MSR_POW@h 145 oris r7,r7,MSR_POW@h
150 sync 1461: sync
151 isync
152 mtmsr r7 147 mtmsr r7
153 isync 148 isync
154 sync 149 b 1b
155 blr 150
156
157/* 151/*
158 * Return from NAP/DOZE mode, restore some CPU specific registers, 152 * Return from NAP/DOZE mode, restore some CPU specific registers,
159 * we are called with DR/IR still off and r2 containing physical 153 * we are called with DR/IR still off and r2 containing physical
160 * address of current. 154 * address of current. R11 points to the exception frame (physical
155 * address). We have to preserve r10.
161 */ 156 */
162_GLOBAL(power_save_6xx_restore) 157_GLOBAL(power_save_6xx_restore)
163 mfspr r11,SPRN_HID0 158 lwz r9,_LINK(r11) /* interrupted in ppc6xx_idle: */
164 rlwinm. r11,r11,0,10,8 /* Clear NAP & copy NAP bit !state to cr1 EQ */ 159 stw r9,_NIP(r11) /* make it do a blr */
165 cror 4*cr1+eq,4*cr0+eq,4*cr0+eq
166BEGIN_FTR_SECTION
167 rlwinm r11,r11,0,9,7 /* Clear DOZE */
168END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
169 mtspr SPRN_HID0, r11
170 160
171#ifdef DEBUG 161#ifdef CONFIG_SMP
172 beq cr1,1f 162 mfspr r12,SPRN_SPRG3
173 lis r11,(nap_return_count-KERNELBASE)@ha 163 lwz r11,TI_CPU(r12) /* get cpu number * 4 */
174 lwz r9,nap_return_count@l(r11)
175 addi r9,r9,1
176 stw r9,nap_return_count@l(r11)
1771:
178#endif
179
180 rlwinm r9,r1,0,0,18
181 tophys(r9,r9)
182 lwz r11,TI_CPU(r9)
183 slwi r11,r11,2 164 slwi r11,r11,2
165#else
166 li r11,0
167#endif
184 /* Todo make sure all these are in the same page 168 /* Todo make sure all these are in the same page
185 * and load r22 (@ha part + CPU offset) only once 169 * and load r11 (@ha part + CPU offset) only once
186 */ 170 */
187BEGIN_FTR_SECTION 171BEGIN_FTR_SECTION
188 beq cr1,1f 172 mfspr r9,SPRN_HID0
173 andis. r9,r9,HID0_NAP@h
174 beq 1f
189 addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha 175 addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha
190 lwz r9,nap_save_msscr0@l(r9) 176 lwz r9,nap_save_msscr0@l(r9)
191 mtspr SPRN_MSSCR0, r9 177 mtspr SPRN_MSSCR0, r9
@@ -210,10 +196,3 @@ _GLOBAL(nap_save_hid1)
210 196
211_GLOBAL(powersave_lowspeed) 197_GLOBAL(powersave_lowspeed)
212 .long 0 198 .long 0
213
214#ifdef DEBUG
215_GLOBAL(nap_enter_count)
216 .space 4
217_GLOBAL(nap_return_count)
218 .space 4
219#endif
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S
index 6dad1c02496e..d85c7c938eed 100644
--- a/arch/powerpc/kernel/idle_power4.S
+++ b/arch/powerpc/kernel/idle_power4.S
@@ -35,12 +35,16 @@ BEGIN_FTR_SECTION
35 DSSALL 35 DSSALL
36 sync 36 sync
37END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) 37END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
38 clrrdi r9,r1,THREAD_SHIFT /* current thread_info */
39 ld r8,TI_LOCAL_FLAGS(r9) /* set napping bit */
40 ori r8,r8,_TLF_NAPPING /* so when we take an exception */
41 std r8,TI_LOCAL_FLAGS(r9) /* it will return to our caller */
38 mfmsr r7 42 mfmsr r7
39 ori r7,r7,MSR_EE 43 ori r7,r7,MSR_EE
40 oris r7,r7,MSR_POW@h 44 oris r7,r7,MSR_POW@h
41 sync 451: sync
42 isync 46 isync
43 mtmsrd r7 47 mtmsrd r7
44 isync 48 isync
45 sync 49 b 1b
46 blr 50
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index bb5c9501234c..57d560c68897 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -272,18 +272,26 @@ unsigned int virt_irq_to_real_map[NR_IRQS];
272 * Don't use virtual irqs 0, 1, 2 for devices. 272 * Don't use virtual irqs 0, 1, 2 for devices.
273 * The pcnet32 driver considers interrupt numbers < 2 to be invalid, 273 * The pcnet32 driver considers interrupt numbers < 2 to be invalid,
274 * and 2 is the XICS IPI interrupt. 274 * and 2 is the XICS IPI interrupt.
275 * We limit virtual irqs to 17 less than NR_IRQS so that when we 275 * We limit virtual irqs to __irq_offet_value less than virt_irq_max so
276 * offset them by 16 (to reserve the first 16 for ISA interrupts) 276 * that when we offset them we don't end up with an interrupt
277 * we don't end up with an interrupt number >= NR_IRQS. 277 * number >= virt_irq_max.
278 */ 278 */
279#define MIN_VIRT_IRQ 3 279#define MIN_VIRT_IRQ 3
280#define MAX_VIRT_IRQ (NR_IRQS - NUM_ISA_INTERRUPTS - 1) 280
281#define NR_VIRT_IRQS (MAX_VIRT_IRQ - MIN_VIRT_IRQ + 1) 281unsigned int virt_irq_max;
282static unsigned int max_virt_irq;
283static unsigned int nr_virt_irqs;
282 284
283void 285void
284virt_irq_init(void) 286virt_irq_init(void)
285{ 287{
286 int i; 288 int i;
289
290 if ((virt_irq_max == 0) || (virt_irq_max > (NR_IRQS - 1)))
291 virt_irq_max = NR_IRQS - 1;
292 max_virt_irq = virt_irq_max - __irq_offset_value;
293 nr_virt_irqs = max_virt_irq - MIN_VIRT_IRQ + 1;
294
287 for (i = 0; i < NR_IRQS; i++) 295 for (i = 0; i < NR_IRQS; i++)
288 virt_irq_to_real_map[i] = UNDEFINED_IRQ; 296 virt_irq_to_real_map[i] = UNDEFINED_IRQ;
289} 297}
@@ -308,17 +316,17 @@ int virt_irq_create_mapping(unsigned int real_irq)
308 return real_irq; 316 return real_irq;
309 } 317 }
310 318
311 /* map to a number between MIN_VIRT_IRQ and MAX_VIRT_IRQ */ 319 /* map to a number between MIN_VIRT_IRQ and max_virt_irq */
312 virq = real_irq; 320 virq = real_irq;
313 if (virq > MAX_VIRT_IRQ) 321 if (virq > max_virt_irq)
314 virq = (virq % NR_VIRT_IRQS) + MIN_VIRT_IRQ; 322 virq = (virq % nr_virt_irqs) + MIN_VIRT_IRQ;
315 323
316 /* search for this number or a free slot */ 324 /* search for this number or a free slot */
317 first_virq = virq; 325 first_virq = virq;
318 while (virt_irq_to_real_map[virq] != UNDEFINED_IRQ) { 326 while (virt_irq_to_real_map[virq] != UNDEFINED_IRQ) {
319 if (virt_irq_to_real_map[virq] == real_irq) 327 if (virt_irq_to_real_map[virq] == real_irq)
320 return virq; 328 return virq;
321 if (++virq > MAX_VIRT_IRQ) 329 if (++virq > max_virt_irq)
322 virq = MIN_VIRT_IRQ; 330 virq = MIN_VIRT_IRQ;
323 if (virq == first_virq) 331 if (virq == first_virq)
324 goto nospace; /* oops, no free slots */ 332 goto nospace; /* oops, no free slots */
@@ -330,8 +338,8 @@ int virt_irq_create_mapping(unsigned int real_irq)
330 nospace: 338 nospace:
331 if (!warned) { 339 if (!warned) {
332 printk(KERN_CRIT "Interrupt table is full\n"); 340 printk(KERN_CRIT "Interrupt table is full\n");
333 printk(KERN_CRIT "Increase NR_IRQS (currently %d) " 341 printk(KERN_CRIT "Increase virt_irq_max (currently %d) "
334 "in your kernel sources and rebuild.\n", NR_IRQS); 342 "in your kernel sources and rebuild.\n", virt_irq_max);
335 warned = 1; 343 warned = 1;
336 } 344 }
337 return NO_IRQ; 345 return NO_IRQ;
@@ -349,8 +357,8 @@ unsigned int real_irq_to_virt_slowpath(unsigned int real_irq)
349 357
350 virq = real_irq; 358 virq = real_irq;
351 359
352 if (virq > MAX_VIRT_IRQ) 360 if (virq > max_virt_irq)
353 virq = (virq % NR_VIRT_IRQS) + MIN_VIRT_IRQ; 361 virq = (virq % nr_virt_irqs) + MIN_VIRT_IRQ;
354 362
355 first_virq = virq; 363 first_virq = virq;
356 364
@@ -360,7 +368,7 @@ unsigned int real_irq_to_virt_slowpath(unsigned int real_irq)
360 368
361 virq++; 369 virq++;
362 370
363 if (virq >= MAX_VIRT_IRQ) 371 if (virq >= max_virt_irq)
364 virq = 0; 372 virq = 0;
365 373
366 } while (first_virq != virq); 374 } while (first_virq != virq);
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index ad7a90212204..856ef1a832b9 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -88,7 +88,7 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
88 mutex_unlock(&kprobe_mutex); 88 mutex_unlock(&kprobe_mutex);
89} 89}
90 90
91static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) 91static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
92{ 92{
93 kprobe_opcode_t insn = *p->ainsn.insn; 93 kprobe_opcode_t insn = *p->ainsn.insn;
94 94
@@ -101,21 +101,21 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
101 regs->nip = (unsigned long)p->ainsn.insn; 101 regs->nip = (unsigned long)p->ainsn.insn;
102} 102}
103 103
104static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) 104static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
105{ 105{
106 kcb->prev_kprobe.kp = kprobe_running(); 106 kcb->prev_kprobe.kp = kprobe_running();
107 kcb->prev_kprobe.status = kcb->kprobe_status; 107 kcb->prev_kprobe.status = kcb->kprobe_status;
108 kcb->prev_kprobe.saved_msr = kcb->kprobe_saved_msr; 108 kcb->prev_kprobe.saved_msr = kcb->kprobe_saved_msr;
109} 109}
110 110
111static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) 111static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
112{ 112{
113 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; 113 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
114 kcb->kprobe_status = kcb->prev_kprobe.status; 114 kcb->kprobe_status = kcb->prev_kprobe.status;
115 kcb->kprobe_saved_msr = kcb->prev_kprobe.saved_msr; 115 kcb->kprobe_saved_msr = kcb->prev_kprobe.saved_msr;
116} 116}
117 117
118static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, 118static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
119 struct kprobe_ctlblk *kcb) 119 struct kprobe_ctlblk *kcb)
120{ 120{
121 __get_cpu_var(current_kprobe) = p; 121 __get_cpu_var(current_kprobe) = p;
@@ -141,7 +141,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
141 } 141 }
142} 142}
143 143
144static inline int kprobe_handler(struct pt_regs *regs) 144static int __kprobes kprobe_handler(struct pt_regs *regs)
145{ 145{
146 struct kprobe *p; 146 struct kprobe *p;
147 int ret = 0; 147 int ret = 0;
@@ -334,7 +334,7 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
334 regs->nip = (unsigned long)p->addr + 4; 334 regs->nip = (unsigned long)p->addr + 4;
335} 335}
336 336
337static inline int post_kprobe_handler(struct pt_regs *regs) 337static int __kprobes post_kprobe_handler(struct pt_regs *regs)
338{ 338{
339 struct kprobe *cur = kprobe_running(); 339 struct kprobe *cur = kprobe_running();
340 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 340 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
@@ -370,7 +370,7 @@ out:
370 return 1; 370 return 1;
371} 371}
372 372
373static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) 373static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
374{ 374{
375 struct kprobe *cur = kprobe_running(); 375 struct kprobe *cur = kprobe_running();
376 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 376 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index d66c5e77fcff..7e4d54821a07 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -1528,12 +1528,11 @@ static int __init prom_find_machine_type(void)
1528 * non-IBM designs ! 1528 * non-IBM designs !
1529 * - it has /rtas 1529 * - it has /rtas
1530 */ 1530 */
1531 len = prom_getprop(_prom->root, "model", 1531 len = prom_getprop(_prom->root, "device_type",
1532 compat, sizeof(compat)-1); 1532 compat, sizeof(compat)-1);
1533 if (len <= 0) 1533 if (len <= 0)
1534 return PLATFORM_GENERIC; 1534 return PLATFORM_GENERIC;
1535 compat[len] = 0; 1535 if (strncmp(compat, RELOC("chrp"), 4))
1536 if (strcmp(compat, "chrp"))
1537 return PLATFORM_GENERIC; 1536 return PLATFORM_GENERIC;
1538 1537
1539 /* Default to pSeries. We need to know if we are running LPAR */ 1538 /* Default to pSeries. We need to know if we are running LPAR */
diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c
index 456286cf1d14..9c9ad1fa9cce 100644
--- a/arch/powerpc/kernel/rtas-proc.c
+++ b/arch/powerpc/kernel/rtas-proc.c
@@ -258,11 +258,11 @@ static int __init proc_rtas_init(void)
258 struct proc_dir_entry *entry; 258 struct proc_dir_entry *entry;
259 259
260 if (!machine_is(pseries)) 260 if (!machine_is(pseries))
261 return 1; 261 return -ENODEV;
262 262
263 rtas_node = of_find_node_by_name(NULL, "rtas"); 263 rtas_node = of_find_node_by_name(NULL, "rtas");
264 if (rtas_node == NULL) 264 if (rtas_node == NULL)
265 return 1; 265 return -ENODEV;
266 266
267 entry = create_proc_entry("ppc64/rtas/progress", S_IRUGO|S_IWUSR, NULL); 267 entry = create_proc_entry("ppc64/rtas/progress", S_IRUGO|S_IWUSR, NULL);
268 if (entry) 268 if (entry)
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S
index 1424eab450ee..a14c96403840 100644
--- a/arch/powerpc/kernel/systbl.S
+++ b/arch/powerpc/kernel/systbl.S
@@ -323,3 +323,4 @@ COMPAT_SYS(pselect6)
323COMPAT_SYS(ppoll) 323COMPAT_SYS(ppoll)
324SYSCALL(unshare) 324SYSCALL(unshare)
325SYSCALL(splice) 325SYSCALL(splice)
326SYSCALL(tee)
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index 97898d5d34e5..1726bfe38ee0 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -1297,7 +1297,7 @@ static inline void setup_decr(struct spu_state *csa, struct spu *spu)
1297 cycles_t resume_time = get_cycles(); 1297 cycles_t resume_time = get_cycles();
1298 cycles_t delta_time = resume_time - csa->suspend_time; 1298 cycles_t delta_time = resume_time - csa->suspend_time;
1299 1299
1300 csa->lscsa->decr.slot[0] = delta_time; 1300 csa->lscsa->decr.slot[0] -= delta_time;
1301 } 1301 }
1302} 1302}
1303 1303
diff --git a/arch/powerpc/platforms/chrp/chrp.h b/arch/powerpc/platforms/chrp/chrp.h
index 63f0aee4c158..996c28744e96 100644
--- a/arch/powerpc/platforms/chrp/chrp.h
+++ b/arch/powerpc/platforms/chrp/chrp.h
@@ -9,3 +9,4 @@ extern long chrp_time_init(void);
9 9
10extern void chrp_find_bridges(void); 10extern void chrp_find_bridges(void);
11extern void chrp_event_scan(unsigned long); 11extern void chrp_event_scan(unsigned long);
12extern void chrp_pcibios_fixup(void);
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
index 8ef279ad36ad..ac224876ce59 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -23,6 +23,8 @@
23#include <asm/grackle.h> 23#include <asm/grackle.h>
24#include <asm/rtas.h> 24#include <asm/rtas.h>
25 25
26#include "chrp.h"
27
26/* LongTrail */ 28/* LongTrail */
27void __iomem *gg2_pci_config_base; 29void __iomem *gg2_pci_config_base;
28 30
@@ -314,6 +316,6 @@ chrp_find_bridges(void)
314 } 316 }
315 317
316 /* Do not fixup interrupts from OF tree on pegasos */ 318 /* Do not fixup interrupts from OF tree on pegasos */
317 if (is_pegasos == 0) 319 if (is_pegasos)
318 ppc_md.pcibios_fixup = chrp_pcibios_fixup; 320 ppc_md.pcibios_fixup = NULL;
319} 321}
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 23a201718704..18d89f38796b 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -440,8 +440,6 @@ void __init chrp_init_IRQ(void)
440 440
441 if (_chrp_type == _CHRP_Pegasos) 441 if (_chrp_type == _CHRP_Pegasos)
442 ppc_md.get_irq = i8259_irq; 442 ppc_md.get_irq = i8259_irq;
443 else
444 ppc_md.get_irq = mpic_get_irq;
445 443
446#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) 444#if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
447 /* see if there is a keyboard in the device tree 445 /* see if there is a keyboard in the device tree
@@ -528,26 +526,24 @@ static int __init chrp_probe(void)
528 /* Assume we have an 8259... */ 526 /* Assume we have an 8259... */
529 __irq_offset_value = NUM_ISA_INTERRUPTS; 527 __irq_offset_value = NUM_ISA_INTERRUPTS;
530 528
531 ppc_md.setup_arch = chrp_setup_arch; 529 return 1;
532 ppc_md.show_cpuinfo = chrp_show_cpuinfo;
533
534 ppc_md.init_IRQ = chrp_init_IRQ;
535 ppc_md.init = chrp_init2;
536
537 ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
538
539 ppc_md.restart = rtas_restart;
540 ppc_md.power_off = rtas_power_off;
541 ppc_md.halt = rtas_halt;
542
543 ppc_md.time_init = chrp_time_init;
544 ppc_md.calibrate_decr = generic_calibrate_decr;
545
546 /* this may get overridden with rtas routines later... */
547 ppc_md.set_rtc_time = chrp_set_rtc_time;
548 ppc_md.get_rtc_time = chrp_get_rtc_time;
549
550#ifdef CONFIG_SMP
551 smp_ops = &chrp_smp_ops;
552#endif /* CONFIG_SMP */
553} 530}
531
532define_machine(chrp) {
533 .name = "CHRP",
534 .probe = chrp_probe,
535 .setup_arch = chrp_setup_arch,
536 .init = chrp_init2,
537 .show_cpuinfo = chrp_show_cpuinfo,
538 .init_IRQ = chrp_init_IRQ,
539 .get_irq = mpic_get_irq,
540 .pcibios_fixup = chrp_pcibios_fixup,
541 .restart = rtas_restart,
542 .power_off = rtas_power_off,
543 .halt = rtas_halt,
544 .time_init = chrp_time_init,
545 .set_rtc_time = chrp_set_rtc_time,
546 .get_rtc_time = chrp_get_rtc_time,
547 .calibrate_decr = generic_calibrate_decr,
548 .phys_mem_access_prot = pci_phys_mem_access_prot,
549};
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 6ce8a404ba6b..a6fd9bedb074 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -54,6 +54,7 @@
54#include <asm/iseries/hv_lp_event.h> 54#include <asm/iseries/hv_lp_event.h>
55#include <asm/iseries/lpar_map.h> 55#include <asm/iseries/lpar_map.h>
56#include <asm/udbg.h> 56#include <asm/udbg.h>
57#include <asm/irq.h>
57 58
58#include "naca.h" 59#include "naca.h"
59#include "setup.h" 60#include "setup.h"
@@ -684,6 +685,12 @@ static int __init iseries_probe(void)
684 powerpc_firmware_features |= FW_FEATURE_ISERIES; 685 powerpc_firmware_features |= FW_FEATURE_ISERIES;
685 powerpc_firmware_features |= FW_FEATURE_LPAR; 686 powerpc_firmware_features |= FW_FEATURE_LPAR;
686 687
688 /*
689 * The Hypervisor only allows us up to 256 interrupt
690 * sources (the irq number is passed in a u8).
691 */
692 virt_irq_max = 255;
693
687 return 1; 694 return 1;
688} 695}
689 696
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 780fb27a0099..32eaddfa5470 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -957,8 +957,10 @@ static void eeh_remove_device(struct pci_dev *dev)
957 pci_addr_cache_remove_device(dev); 957 pci_addr_cache_remove_device(dev);
958 958
959 dn = pci_device_to_OF_node(dev); 959 dn = pci_device_to_OF_node(dev);
960 PCI_DN(dn)->pcidev = NULL; 960 if (PCI_DN(dn)->pcidev) {
961 pci_dev_put (dev); 961 PCI_DN(dn)->pcidev = NULL;
962 pci_dev_put (dev);
963 }
962} 964}
963 965
964void eeh_remove_bus_device(struct pci_dev *dev) 966void eeh_remove_bus_device(struct pci_dev *dev)
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c
index fcc4d561a236..e0000ce769e5 100644
--- a/arch/powerpc/platforms/pseries/rtasd.c
+++ b/arch/powerpc/platforms/pseries/rtasd.c
@@ -488,7 +488,7 @@ static int __init rtas_init(void)
488 /* No RTAS */ 488 /* No RTAS */
489 if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) { 489 if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) {
490 printk(KERN_INFO "rtasd: no event-scan on system\n"); 490 printk(KERN_INFO "rtasd: no event-scan on system\n");
491 return 1; 491 return -ENODEV;
492 } 492 }
493 493
494 entry = create_proc_entry("ppc64/rtas/error_log", S_IRUSR, NULL); 494 entry = create_proc_entry("ppc64/rtas/error_log", S_IRUSR, NULL);
diff --git a/arch/ppc/boot/lib/Makefile b/arch/ppc/boot/lib/Makefile
index d4077e69086f..80c84d562fa4 100644
--- a/arch/ppc/boot/lib/Makefile
+++ b/arch/ppc/boot/lib/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5CFLAGS_kbd.o := -Idrivers/char 5CFLAGS_kbd.o := -Idrivers/char
6CFLAGS_vreset.o := -I$(srctree)/arch/ppc/boot/include 6CFLAGS_vreset.o := -Iarch/ppc/boot/include
7 7
8zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c 8zlib := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c
9 9
diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
index 60c724e11584..7662c4e6e7d6 100644
--- a/arch/ppc/syslib/ppc_sys.c
+++ b/arch/ppc/syslib/ppc_sys.c
@@ -156,12 +156,13 @@ void platform_notify_map(const struct platform_notify_dev_map *map,
156 while (map->bus_id != NULL) { 156 while (map->bus_id != NULL) {
157 idx = -1; 157 idx = -1;
158 s = strrchr(dev->bus_id, '.'); 158 s = strrchr(dev->bus_id, '.');
159 if (s != NULL) 159 if (s != NULL) {
160 idx = (int)simple_strtol(s + 1, NULL, 10); 160 idx = (int)simple_strtol(s + 1, NULL, 10);
161 else 161 len = s - dev->bus_id;
162 } else {
162 s = dev->bus_id; 163 s = dev->bus_id;
163 164 len = strlen(dev->bus_id);
164 len = s - dev->bus_id; 165 }
165 166
166 if (!strncmp(dev->bus_id, map->bus_id, len)) { 167 if (!strncmp(dev->bus_id, map->bus_id, len)) {
167 pdev = container_of(dev, struct platform_device, dev); 168 pdev = container_of(dev, struct platform_device, dev);
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 6c6b197898d0..7bb16fb97d4f 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -67,7 +67,6 @@ cflags-$(CONFIG_WARN_STACK) += -mwarn-framesize=$(CONFIG_WARN_STACK_SIZE)
67endif 67endif
68 68
69CFLAGS += -mbackchain -msoft-float $(cflags-y) 69CFLAGS += -mbackchain -msoft-float $(cflags-y)
70CFLAGS += $(call cc-option,-finline-limit=10000)
71CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare 70CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare
72AFLAGS += $(aflags-y) 71AFLAGS += $(aflags-y)
73 72
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index f8d0cd540a06..f4dfc10026d2 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -1,10 +1,11 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.16-rc2 3# Linux kernel version: 2.6.17-rc1
4# Wed Feb 8 10:44:39 2006 4# Mon Apr 3 14:34:15 2006
5# 5#
6CONFIG_MMU=y 6CONFIG_MMU=y
7CONFIG_RWSEM_XCHGADD_ALGORITHM=y 7CONFIG_RWSEM_XCHGADD_ALGORITHM=y
8CONFIG_GENERIC_HWEIGHT=y
8CONFIG_GENERIC_CALIBRATE_DELAY=y 9CONFIG_GENERIC_CALIBRATE_DELAY=y
9CONFIG_S390=y 10CONFIG_S390=y
10 11
@@ -30,8 +31,8 @@ CONFIG_AUDIT=y
30CONFIG_IKCONFIG=y 31CONFIG_IKCONFIG=y
31CONFIG_IKCONFIG_PROC=y 32CONFIG_IKCONFIG_PROC=y
32# CONFIG_CPUSETS is not set 33# CONFIG_CPUSETS is not set
34# CONFIG_RELAY is not set
33CONFIG_INITRAMFS_SOURCE="" 35CONFIG_INITRAMFS_SOURCE=""
34CONFIG_UID16=y
35# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set 36# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
36# CONFIG_EMBEDDED is not set 37# CONFIG_EMBEDDED is not set
37CONFIG_KALLSYMS=y 38CONFIG_KALLSYMS=y
@@ -45,10 +46,6 @@ CONFIG_BASE_FULL=y
45CONFIG_FUTEX=y 46CONFIG_FUTEX=y
46CONFIG_EPOLL=y 47CONFIG_EPOLL=y
47CONFIG_SHMEM=y 48CONFIG_SHMEM=y
48CONFIG_CC_ALIGN_FUNCTIONS=0
49CONFIG_CC_ALIGN_LABELS=0
50CONFIG_CC_ALIGN_LOOPS=0
51CONFIG_CC_ALIGN_JUMPS=0
52CONFIG_SLAB=y 49CONFIG_SLAB=y
53# CONFIG_TINY_SHMEM is not set 50# CONFIG_TINY_SHMEM is not set
54CONFIG_BASE_SMALL=0 51CONFIG_BASE_SMALL=0
@@ -60,7 +57,6 @@ CONFIG_BASE_SMALL=0
60CONFIG_MODULES=y 57CONFIG_MODULES=y
61CONFIG_MODULE_UNLOAD=y 58CONFIG_MODULE_UNLOAD=y
62# CONFIG_MODULE_FORCE_UNLOAD is not set 59# CONFIG_MODULE_FORCE_UNLOAD is not set
63CONFIG_OBSOLETE_MODPARM=y
64CONFIG_MODVERSIONS=y 60CONFIG_MODVERSIONS=y
65# CONFIG_MODULE_SRCVERSION_ALL is not set 61# CONFIG_MODULE_SRCVERSION_ALL is not set
66CONFIG_KMOD=y 62CONFIG_KMOD=y
@@ -69,7 +65,7 @@ CONFIG_STOP_MACHINE=y
69# 65#
70# Block layer 66# Block layer
71# 67#
72# CONFIG_LBD is not set 68# CONFIG_BLK_DEV_IO_TRACE is not set
73 69
74# 70#
75# IO Schedulers 71# IO Schedulers
@@ -91,17 +87,20 @@ CONFIG_DEFAULT_IOSCHED="deadline"
91# 87#
92# Processor type and features 88# Processor type and features
93# 89#
94# CONFIG_64BIT is not set 90CONFIG_64BIT=y
95CONFIG_SMP=y 91CONFIG_SMP=y
96CONFIG_NR_CPUS=32 92CONFIG_NR_CPUS=32
97CONFIG_HOTPLUG_CPU=y 93CONFIG_HOTPLUG_CPU=y
98CONFIG_MATHEMU=y 94CONFIG_DEFAULT_MIGRATION_COST=1000000
95CONFIG_COMPAT=y
96CONFIG_SYSVIPC_COMPAT=y
97CONFIG_BINFMT_ELF32=y
99 98
100# 99#
101# Code generation options 100# Code generation options
102# 101#
103CONFIG_MARCH_G5=y 102# CONFIG_MARCH_G5 is not set
104# CONFIG_MARCH_Z900 is not set 103CONFIG_MARCH_Z900=y
105# CONFIG_MARCH_Z990 is not set 104# CONFIG_MARCH_Z990 is not set
106CONFIG_PACK_STACK=y 105CONFIG_PACK_STACK=y
107# CONFIG_SMALL_STACK is not set 106# CONFIG_SMALL_STACK is not set
@@ -143,7 +142,7 @@ CONFIG_VIRT_CPU_ACCOUNTING=y
143# CONFIG_APPLDATA_BASE is not set 142# CONFIG_APPLDATA_BASE is not set
144CONFIG_NO_IDLE_HZ=y 143CONFIG_NO_IDLE_HZ=y
145CONFIG_NO_IDLE_HZ_INIT=y 144CONFIG_NO_IDLE_HZ_INIT=y
146# CONFIG_KEXEC is not set 145CONFIG_KEXEC=y
147 146
148# 147#
149# Networking 148# Networking
@@ -173,6 +172,7 @@ CONFIG_IP_FIB_HASH=y
173# CONFIG_INET_AH is not set 172# CONFIG_INET_AH is not set
174# CONFIG_INET_ESP is not set 173# CONFIG_INET_ESP is not set
175# CONFIG_INET_IPCOMP is not set 174# CONFIG_INET_IPCOMP is not set
175# CONFIG_INET_XFRM_TUNNEL is not set
176# CONFIG_INET_TUNNEL is not set 176# CONFIG_INET_TUNNEL is not set
177CONFIG_INET_DIAG=y 177CONFIG_INET_DIAG=y
178CONFIG_INET_TCP_DIAG=y 178CONFIG_INET_TCP_DIAG=y
@@ -180,9 +180,11 @@ CONFIG_INET_TCP_DIAG=y
180CONFIG_TCP_CONG_BIC=y 180CONFIG_TCP_CONG_BIC=y
181CONFIG_IPV6=y 181CONFIG_IPV6=y
182# CONFIG_IPV6_PRIVACY is not set 182# CONFIG_IPV6_PRIVACY is not set
183# CONFIG_IPV6_ROUTER_PREF is not set
183# CONFIG_INET6_AH is not set 184# CONFIG_INET6_AH is not set
184# CONFIG_INET6_ESP is not set 185# CONFIG_INET6_ESP is not set
185# CONFIG_INET6_IPCOMP is not set 186# CONFIG_INET6_IPCOMP is not set
187# CONFIG_INET6_XFRM_TUNNEL is not set
186# CONFIG_INET6_TUNNEL is not set 188# CONFIG_INET6_TUNNEL is not set
187# CONFIG_IPV6_TUNNEL is not set 189# CONFIG_IPV6_TUNNEL is not set
188# CONFIG_NETFILTER is not set 190# CONFIG_NETFILTER is not set
@@ -276,6 +278,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
276# CONFIG_DEBUG_DRIVER is not set 278# CONFIG_DEBUG_DRIVER is not set
277 279
278# 280#
281# Connector - unified userspace <-> kernelspace linker
282#
283# CONFIG_CONNECTOR is not set
284
285#
279# SCSI device support 286# SCSI device support
280# 287#
281# CONFIG_RAID_ATTRS is not set 288# CONFIG_RAID_ATTRS is not set
@@ -340,8 +347,7 @@ CONFIG_DASD_PROFILE=y
340CONFIG_DASD_ECKD=y 347CONFIG_DASD_ECKD=y
341CONFIG_DASD_FBA=y 348CONFIG_DASD_FBA=y
342CONFIG_DASD_DIAG=y 349CONFIG_DASD_DIAG=y
343CONFIG_DASD_EER=m 350CONFIG_DASD_EER=y
344# CONFIG_DASD_CMB is not set
345# CONFIG_ATA_OVER_ETH is not set 351# CONFIG_ATA_OVER_ETH is not set
346 352
347# 353#
@@ -354,6 +360,7 @@ CONFIG_MD_RAID0=m
354CONFIG_MD_RAID1=m 360CONFIG_MD_RAID1=m
355# CONFIG_MD_RAID10 is not set 361# CONFIG_MD_RAID10 is not set
356CONFIG_MD_RAID5=m 362CONFIG_MD_RAID5=m
363# CONFIG_MD_RAID5_RESHAPE is not set
357# CONFIG_MD_RAID6 is not set 364# CONFIG_MD_RAID6 is not set
358CONFIG_MD_MULTIPATH=m 365CONFIG_MD_MULTIPATH=m
359# CONFIG_MD_FAULTY is not set 366# CONFIG_MD_FAULTY is not set
@@ -404,6 +411,7 @@ CONFIG_S390_TAPE_BLOCK=y
404# S/390 tape hardware support 411# S/390 tape hardware support
405# 412#
406CONFIG_S390_TAPE_34XX=m 413CONFIG_S390_TAPE_34XX=m
414# CONFIG_S390_TAPE_3590 is not set
407# CONFIG_VMLOGRDR is not set 415# CONFIG_VMLOGRDR is not set
408# CONFIG_VMCP is not set 416# CONFIG_VMCP is not set
409# CONFIG_MONREADER is not set 417# CONFIG_MONREADER is not set
@@ -529,7 +537,6 @@ CONFIG_SYSFS=y
529CONFIG_TMPFS=y 537CONFIG_TMPFS=y
530# CONFIG_HUGETLB_PAGE is not set 538# CONFIG_HUGETLB_PAGE is not set
531CONFIG_RAMFS=y 539CONFIG_RAMFS=y
532# CONFIG_RELAYFS_FS is not set
533# CONFIG_CONFIGFS_FS is not set 540# CONFIG_CONFIGFS_FS is not set
534 541
535# 542#
@@ -619,14 +626,15 @@ CONFIG_LOG_BUF_SHIFT=17
619# CONFIG_DETECT_SOFTLOCKUP is not set 626# CONFIG_DETECT_SOFTLOCKUP is not set
620# CONFIG_SCHEDSTATS is not set 627# CONFIG_SCHEDSTATS is not set
621# CONFIG_DEBUG_SLAB is not set 628# CONFIG_DEBUG_SLAB is not set
622# CONFIG_DEBUG_PREEMPT is not set 629CONFIG_DEBUG_PREEMPT=y
623CONFIG_DEBUG_MUTEXES=y 630CONFIG_DEBUG_MUTEXES=y
624# CONFIG_DEBUG_SPINLOCK is not set 631CONFIG_DEBUG_SPINLOCK=y
625# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 632CONFIG_DEBUG_SPINLOCK_SLEEP=y
626# CONFIG_DEBUG_KOBJECT is not set 633# CONFIG_DEBUG_KOBJECT is not set
627# CONFIG_DEBUG_INFO is not set 634# CONFIG_DEBUG_INFO is not set
628CONFIG_DEBUG_FS=y 635CONFIG_DEBUG_FS=y
629# CONFIG_DEBUG_VM is not set 636# CONFIG_DEBUG_VM is not set
637# CONFIG_UNWIND_INFO is not set
630CONFIG_FORCED_INLINING=y 638CONFIG_FORCED_INLINING=y
631# CONFIG_RCU_TORTURE_TEST is not set 639# CONFIG_RCU_TORTURE_TEST is not set
632 640
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 58583f459471..2bcecf422573 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -527,6 +527,11 @@ config CPU_HAS_SR_RB
527 See <file:Documentation/sh/register-banks.txt> for further 527 See <file:Documentation/sh/register-banks.txt> for further
528 information on SR.RB and register banking in the kernel in general. 528 information on SR.RB and register banking in the kernel in general.
529 529
530config NODES_SHIFT
531 int
532 default "1"
533 depends on NEED_MULTIPLE_NODES
534
530endmenu 535endmenu
531 536
532menu "Boot options" 537menu "Boot options"
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c
index 1cf94a618be3..d5d032533a8b 100644
--- a/arch/sh/kernel/sh_ksyms.c
+++ b/arch/sh/kernel/sh_ksyms.c
@@ -37,7 +37,6 @@ EXPORT_SYMBOL(disable_irq_nosync);
37EXPORT_SYMBOL(irq_desc); 37EXPORT_SYMBOL(irq_desc);
38EXPORT_SYMBOL(no_irq_type); 38EXPORT_SYMBOL(no_irq_type);
39 39
40EXPORT_SYMBOL(strpbrk);
41EXPORT_SYMBOL(strstr); 40EXPORT_SYMBOL(strstr);
42EXPORT_SYMBOL(strlen); 41EXPORT_SYMBOL(strlen);
43EXPORT_SYMBOL(strnlen); 42EXPORT_SYMBOL(strnlen);
diff --git a/arch/sh64/kernel/sh_ksyms.c b/arch/sh64/kernel/sh_ksyms.c
index de29c45f23a7..6f3a1c946339 100644
--- a/arch/sh64/kernel/sh_ksyms.c
+++ b/arch/sh64/kernel/sh_ksyms.c
@@ -41,7 +41,6 @@ EXPORT_SYMBOL(kernel_thread);
41/* Networking helper routines. */ 41/* Networking helper routines. */
42EXPORT_SYMBOL(csum_partial_copy); 42EXPORT_SYMBOL(csum_partial_copy);
43 43
44EXPORT_SYMBOL(strpbrk);
45EXPORT_SYMBOL(strstr); 44EXPORT_SYMBOL(strstr);
46 45
47#ifdef CONFIG_VT 46#ifdef CONFIG_VT
diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c
index 2be812115197..a93f5da6855d 100644
--- a/arch/sparc/kernel/smp.c
+++ b/arch/sparc/kernel/smp.c
@@ -244,7 +244,7 @@ int setup_profiling_timer(unsigned int multiplier)
244 return -EINVAL; 244 return -EINVAL;
245 245
246 spin_lock_irqsave(&prof_setup_lock, flags); 246 spin_lock_irqsave(&prof_setup_lock, flags);
247 for_each_cpu(i) { 247 for_each_possible_cpu(i) {
248 load_profile_irq(i, lvl14_resolution / multiplier); 248 load_profile_irq(i, lvl14_resolution / multiplier);
249 prof_multiplier(i) = multiplier; 249 prof_multiplier(i) = multiplier;
250 } 250 }
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
index 2c21d7907635..ec1c9687d679 100644
--- a/arch/sparc/kernel/sparc_ksyms.c
+++ b/arch/sparc/kernel/sparc_ksyms.c
@@ -263,7 +263,6 @@ EXPORT_SYMBOL(strcmp);
263EXPORT_SYMBOL(strncmp); 263EXPORT_SYMBOL(strncmp);
264EXPORT_SYMBOL(strchr); 264EXPORT_SYMBOL(strchr);
265EXPORT_SYMBOL(strrchr); 265EXPORT_SYMBOL(strrchr);
266EXPORT_SYMBOL(strpbrk);
267EXPORT_SYMBOL(strstr); 266EXPORT_SYMBOL(strstr);
268EXPORT_SYMBOL(page_kernel); 267EXPORT_SYMBOL(page_kernel);
269 268
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S
index fbbec5e761c6..db8faa75f94d 100644
--- a/arch/sparc/kernel/systbls.S
+++ b/arch/sparc/kernel/systbls.S
@@ -75,7 +75,7 @@ sys_call_table:
75/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy 75/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy
76/*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink 76/*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
77/*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid 77/*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
78/*280*/ .long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat 78/*280*/ .long sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
79/*285*/ .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64 79/*285*/ .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64
80/*290*/ .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat 80/*290*/ .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
81/*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare 81/*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
diff --git a/arch/sparc/math-emu/Makefile b/arch/sparc/math-emu/Makefile
index f84a9a6162be..8136987977f4 100644
--- a/arch/sparc/math-emu/Makefile
+++ b/arch/sparc/math-emu/Makefile
@@ -5,4 +5,4 @@
5obj-y := math.o 5obj-y := math.o
6 6
7EXTRA_AFLAGS := -ansi 7EXTRA_AFLAGS := -ansi
8EXTRA_CFLAGS = -I. -I$(TOPDIR)/include/math-emu -w 8EXTRA_CFLAGS = -I. -Iinclude/math-emu -w
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index d1e2fc566486..43a66f5407f4 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -187,13 +187,16 @@ config HUGETLB_PAGE_SIZE_512K
187 bool "512K" 187 bool "512K"
188 188
189config HUGETLB_PAGE_SIZE_64K 189config HUGETLB_PAGE_SIZE_64K
190 depends on !SPARC64_PAGE_SIZE_4MB && !SPARC64_PAGE_SIZE_512KB && !SPARC64_PAGE_SIZE_64K 190 depends on !SPARC64_PAGE_SIZE_4MB && !SPARC64_PAGE_SIZE_512KB && !SPARC64_PAGE_SIZE_64KB
191 bool "64K" 191 bool "64K"
192 192
193endchoice 193endchoice
194 194
195endmenu 195endmenu
196 196
197config ARCH_SELECT_MEMORY_MODEL
198 def_bool y
199
197config ARCH_SPARSEMEM_ENABLE 200config ARCH_SPARSEMEM_ENABLE
198 def_bool y 201 def_bool y
199 202
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 30389085a359..1317380fa937 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.16 3# Linux kernel version: 2.6.16
4# Fri Mar 31 01:40:57 2006 4# Sun Apr 2 19:31:04 2006
5# 5#
6CONFIG_SPARC=y 6CONFIG_SPARC=y
7CONFIG_SPARC64=y 7CONFIG_SPARC64=y
@@ -838,7 +838,6 @@ CONFIG_FB_TILEBLITTING=y
838# CONFIG_FB_NVIDIA is not set 838# CONFIG_FB_NVIDIA is not set
839# CONFIG_FB_RIVA is not set 839# CONFIG_FB_RIVA is not set
840# CONFIG_FB_MATROX is not set 840# CONFIG_FB_MATROX is not set
841# CONFIG_FB_RADEON_OLD is not set
842CONFIG_FB_RADEON=y 841CONFIG_FB_RADEON=y
843CONFIG_FB_RADEON_I2C=y 842CONFIG_FB_RADEON_I2C=y
844# CONFIG_FB_RADEON_DEBUG is not set 843# CONFIG_FB_RADEON_DEBUG is not set
@@ -924,6 +923,7 @@ CONFIG_SND_MTPAV=m
924# PCI devices 923# PCI devices
925# 924#
926# CONFIG_SND_AD1889 is not set 925# CONFIG_SND_AD1889 is not set
926# CONFIG_SND_ALS300 is not set
927CONFIG_SND_ALI5451=m 927CONFIG_SND_ALI5451=m
928# CONFIG_SND_ATIIXP is not set 928# CONFIG_SND_ATIIXP is not set
929# CONFIG_SND_ATIIXP_MODEM is not set 929# CONFIG_SND_ATIIXP_MODEM is not set
@@ -955,6 +955,7 @@ CONFIG_SND_ALI5451=m
955# CONFIG_SND_MIXART is not set 955# CONFIG_SND_MIXART is not set
956# CONFIG_SND_NM256 is not set 956# CONFIG_SND_NM256 is not set
957# CONFIG_SND_PCXHR is not set 957# CONFIG_SND_PCXHR is not set
958# CONFIG_SND_RIPTIDE is not set
958# CONFIG_SND_RME32 is not set 959# CONFIG_SND_RME32 is not set
959# CONFIG_SND_RME96 is not set 960# CONFIG_SND_RME96 is not set
960# CONFIG_SND_RME9652 is not set 961# CONFIG_SND_RME9652 is not set
@@ -1109,6 +1110,11 @@ CONFIG_USB_HIDDEV=y
1109# CONFIG_MMC is not set 1110# CONFIG_MMC is not set
1110 1111
1111# 1112#
1113# LED devices
1114#
1115# CONFIG_NEW_LEDS is not set
1116
1117#
1112# InfiniBand support 1118# InfiniBand support
1113# 1119#
1114# CONFIG_INFINIBAND is not set 1120# CONFIG_INFINIBAND is not set
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index ffc7309e9f22..2e1c824c1cc9 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -63,7 +63,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)
63 flushi(p->addr); 63 flushi(p->addr);
64} 64}
65 65
66static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) 66static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
67{ 67{
68 kcb->prev_kprobe.kp = kprobe_running(); 68 kcb->prev_kprobe.kp = kprobe_running();
69 kcb->prev_kprobe.status = kcb->kprobe_status; 69 kcb->prev_kprobe.status = kcb->kprobe_status;
@@ -71,7 +71,7 @@ static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
71 kcb->prev_kprobe.orig_tstate_pil = kcb->kprobe_orig_tstate_pil; 71 kcb->prev_kprobe.orig_tstate_pil = kcb->kprobe_orig_tstate_pil;
72} 72}
73 73
74static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) 74static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
75{ 75{
76 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; 76 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
77 kcb->kprobe_status = kcb->prev_kprobe.status; 77 kcb->kprobe_status = kcb->prev_kprobe.status;
@@ -79,7 +79,7 @@ static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
79 kcb->kprobe_orig_tstate_pil = kcb->prev_kprobe.orig_tstate_pil; 79 kcb->kprobe_orig_tstate_pil = kcb->prev_kprobe.orig_tstate_pil;
80} 80}
81 81
82static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, 82static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
83 struct kprobe_ctlblk *kcb) 83 struct kprobe_ctlblk *kcb)
84{ 84{
85 __get_cpu_var(current_kprobe) = p; 85 __get_cpu_var(current_kprobe) = p;
@@ -87,7 +87,7 @@ static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
87 kcb->kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL); 87 kcb->kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL);
88} 88}
89 89
90static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs, 90static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs,
91 struct kprobe_ctlblk *kcb) 91 struct kprobe_ctlblk *kcb)
92{ 92{
93 regs->tstate |= TSTATE_PIL; 93 regs->tstate |= TSTATE_PIL;
@@ -273,7 +273,7 @@ static void __kprobes resume_execution(struct kprobe *p,
273 kcb->kprobe_orig_tstate_pil); 273 kcb->kprobe_orig_tstate_pil);
274} 274}
275 275
276static inline int post_kprobe_handler(struct pt_regs *regs) 276static int __kprobes post_kprobe_handler(struct pt_regs *regs)
277{ 277{
278 struct kprobe *cur = kprobe_running(); 278 struct kprobe *cur = kprobe_running();
279 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 279 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
@@ -300,7 +300,7 @@ out:
300 return 1; 300 return 1;
301} 301}
302 302
303static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) 303static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
304{ 304{
305 struct kprobe *cur = kprobe_running(); 305 struct kprobe *cur = kprobe_running();
306 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 306 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index dfccff29e182..f97ddeb105ac 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -419,6 +419,7 @@ void pcibios_resource_to_bus(struct pci_dev *pdev, struct pci_bus_region *region
419 region->start = res->start - zero_res.start; 419 region->start = res->start - zero_res.start;
420 region->end = res->end - zero_res.start; 420 region->end = res->end - zero_res.start;
421} 421}
422EXPORT_SYMBOL(pcibios_resource_to_bus);
422 423
423void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res, 424void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res,
424 struct pci_bus_region *region) 425 struct pci_bus_region *region)
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index 9372d4f376d5..9e94db2573a2 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -1092,7 +1092,7 @@ void sun4v_pci_init(int node, char *model_name)
1092 } 1092 }
1093 } 1093 }
1094 1094
1095 for_each_cpu(i) { 1095 for_each_possible_cpu(i) {
1096 unsigned long page = get_zeroed_page(GFP_ATOMIC); 1096 unsigned long page = get_zeroed_page(GFP_ATOMIC);
1097 1097
1098 if (!page) 1098 if (!page)
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
index eb93e9c52846..49e6dedd027d 100644
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -244,6 +244,13 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
244 } 244 }
245 245
246 switch(request) { 246 switch(request) {
247 case PTRACE_PEEKUSR:
248 if (addr != 0)
249 pt_error_return(regs, EIO);
250 else
251 pt_succ_return(regs, 0);
252 goto out_tsk;
253
247 case PTRACE_PEEKTEXT: /* read word at location addr. */ 254 case PTRACE_PEEKTEXT: /* read word at location addr. */
248 case PTRACE_PEEKDATA: { 255 case PTRACE_PEEKDATA: {
249 unsigned long tmp64; 256 unsigned long tmp64;
@@ -602,6 +609,22 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
602 609
603 /* PTRACE_DUMPCORE unsupported... */ 610 /* PTRACE_DUMPCORE unsupported... */
604 611
612 case PTRACE_GETEVENTMSG: {
613 int err;
614
615 if (test_thread_flag(TIF_32BIT))
616 err = put_user(child->ptrace_message,
617 (unsigned int __user *) data);
618 else
619 err = put_user(child->ptrace_message,
620 (unsigned long __user *) data);
621 if (err)
622 pt_error_return(regs, -err);
623 else
624 pt_succ_return(regs, 0);
625 break;
626 }
627
605 default: { 628 default: {
606 int err = ptrace_request(child, request, addr, data); 629 int err = ptrace_request(child, request, addr, data);
607 if (err) 630 if (err)
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 7d0e67c1ce50..005167f82419 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -535,7 +535,7 @@ static int __init topology_init(void)
535 while (!cpu_find_by_instance(ncpus_probed, NULL, NULL)) 535 while (!cpu_find_by_instance(ncpus_probed, NULL, NULL))
536 ncpus_probed++; 536 ncpus_probed++;
537 537
538 for_each_cpu(i) { 538 for_each_possible_cpu(i) {
539 struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); 539 struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL);
540 if (p) { 540 if (p) {
541 register_cpu(p, i, NULL); 541 register_cpu(p, i, NULL);
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 8175a6968c6b..90eaca3ec9a6 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -745,12 +745,21 @@ struct call_data_struct {
745 int wait; 745 int wait;
746}; 746};
747 747
748static DEFINE_SPINLOCK(call_lock); 748static __cacheline_aligned_in_smp DEFINE_SPINLOCK(call_lock);
749static struct call_data_struct *call_data; 749static struct call_data_struct *call_data;
750 750
751extern unsigned long xcall_call_function; 751extern unsigned long xcall_call_function;
752 752
753/* 753/**
754 * smp_call_function(): Run a function on all other CPUs.
755 * @func: The function to run. This must be fast and non-blocking.
756 * @info: An arbitrary pointer to pass to the function.
757 * @nonatomic: currently unused.
758 * @wait: If true, wait (atomically) until function has completed on other CPUs.
759 *
760 * Returns 0 on success, else a negative status code. Does not return until
761 * remote CPUs are nearly ready to execute <<func>> or are or have executed.
762 *
754 * You must not call this function with disabled interrupts or from a 763 * You must not call this function with disabled interrupts or from a
755 * hardware interrupt handler or from a bottom half handler. 764 * hardware interrupt handler or from a bottom half handler.
756 */ 765 */
@@ -759,7 +768,6 @@ static int smp_call_function_mask(void (*func)(void *info), void *info,
759{ 768{
760 struct call_data_struct data; 769 struct call_data_struct data;
761 int cpus; 770 int cpus;
762 long timeout;
763 771
764 /* Can deadlock when called with interrupts disabled */ 772 /* Can deadlock when called with interrupts disabled */
765 WARN_ON(irqs_disabled()); 773 WARN_ON(irqs_disabled());
@@ -777,31 +785,18 @@ static int smp_call_function_mask(void (*func)(void *info), void *info,
777 goto out_unlock; 785 goto out_unlock;
778 786
779 call_data = &data; 787 call_data = &data;
788 mb();
780 789
781 smp_cross_call_masked(&xcall_call_function, 0, 0, 0, mask); 790 smp_cross_call_masked(&xcall_call_function, 0, 0, 0, mask);
782 791
783 /* 792 /* Wait for response */
784 * Wait for other cpus to complete function or at 793 while (atomic_read(&data.finished) != cpus)
785 * least snap the call data. 794 cpu_relax();
786 */
787 timeout = 1000000;
788 while (atomic_read(&data.finished) != cpus) {
789 if (--timeout <= 0)
790 goto out_timeout;
791 barrier();
792 udelay(1);
793 }
794 795
795out_unlock: 796out_unlock:
796 spin_unlock(&call_lock); 797 spin_unlock(&call_lock);
797 798
798 return 0; 799 return 0;
799
800out_timeout:
801 spin_unlock(&call_lock);
802 printk("XCALL: Remote cpus not responding, ncpus=%d finished=%d\n",
803 cpus, atomic_read(&data.finished));
804 return 0;
805} 800}
806 801
807int smp_call_function(void (*func)(void *info), void *info, 802int smp_call_function(void (*func)(void *info), void *info,
@@ -1285,7 +1280,7 @@ int setup_profiling_timer(unsigned int multiplier)
1285 return -EINVAL; 1280 return -EINVAL;
1286 1281
1287 spin_lock_irqsave(&prof_setup_lock, flags); 1282 spin_lock_irqsave(&prof_setup_lock, flags);
1288 for_each_cpu(i) 1283 for_each_possible_cpu(i)
1289 prof_multiplier(i) = multiplier; 1284 prof_multiplier(i) = multiplier;
1290 current_tick_offset = (timer_tick_offset / multiplier); 1285 current_tick_offset = (timer_tick_offset / multiplier);
1291 spin_unlock_irqrestore(&prof_setup_lock, flags); 1286 spin_unlock_irqrestore(&prof_setup_lock, flags);
@@ -1313,12 +1308,12 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
1313 } 1308 }
1314 } 1309 }
1315 1310
1316 for_each_cpu(i) { 1311 for_each_possible_cpu(i) {
1317 if (tlb_type == hypervisor) { 1312 if (tlb_type == hypervisor) {
1318 int j; 1313 int j;
1319 1314
1320 /* XXX get this mapping from machine description */ 1315 /* XXX get this mapping from machine description */
1321 for_each_cpu(j) { 1316 for_each_possible_cpu(j) {
1322 if ((j >> 2) == (i >> 2)) 1317 if ((j >> 2) == (i >> 2))
1323 cpu_set(j, cpu_sibling_map[i]); 1318 cpu_set(j, cpu_sibling_map[i]);
1324 } 1319 }
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index f5e8db1de76b..62d8a99271ea 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -276,7 +276,6 @@ EXPORT_SYMBOL(__prom_getsibling);
276EXPORT_SYMBOL(strlen); 276EXPORT_SYMBOL(strlen);
277EXPORT_SYMBOL(__strlen_user); 277EXPORT_SYMBOL(__strlen_user);
278EXPORT_SYMBOL(__strnlen_user); 278EXPORT_SYMBOL(__strnlen_user);
279EXPORT_SYMBOL(strpbrk);
280 279
281#ifdef CONFIG_SOLARIS_EMUL_MODULE 280#ifdef CONFIG_SOLARIS_EMUL_MODULE
282EXPORT_SYMBOL(linux_sparc_syscall); 281EXPORT_SYMBOL(linux_sparc_syscall);
diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S
index 86dd5cb81e09..f9b75760163c 100644
--- a/arch/sparc64/kernel/sys32.S
+++ b/arch/sparc64/kernel/sys32.S
@@ -138,6 +138,7 @@ SIGN2(sys32_ioprio_get, sys_ioprio_get, %o0, %o1)
138SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2) 138SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2)
139SIGN2(sys32_splice, sys_splice, %o0, %o1) 139SIGN2(sys32_splice, sys_splice, %o0, %o1)
140SIGN2(sys32_sync_file_range, compat_sync_file_range, %o0, %o5) 140SIGN2(sys32_sync_file_range, compat_sync_file_range, %o0, %o5)
141SIGN2(sys32_tee, sys_tee, %o0, %o1)
141 142
142 .globl sys32_mmap2 143 .globl sys32_mmap2
143sys32_mmap2: 144sys32_mmap2:
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index 857b82c82875..62672cd92eca 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -76,7 +76,7 @@ sys_call_table32:
76 .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy 76 .word sys_timer_delete, compat_sys_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
77/*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink 77/*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink
78 .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid 78 .word compat_sys_mq_timedsend, compat_sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid
79/*280*/ .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat 79/*280*/ .word sys32_tee, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat
80 .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_fstatat64 80 .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_fstatat64
81/*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat 81/*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
82 .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare 82 .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare
@@ -145,7 +145,7 @@ sys_call_table:
145 .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy 145 .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy
146/*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink 146/*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink
147 .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid 147 .word sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid
148/*280*/ .word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat 148/*280*/ .word sys_tee, sys_add_key, sys_request_key, sys_keyctl, sys_openat
149 .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64 149 .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64
150/*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat 150/*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat
151 .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare 151 .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index ff090bb9734b..2793a5d82380 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -1130,9 +1130,9 @@ static void cheetah_log_errors(struct pt_regs *regs, struct cheetah_err_info *in
1130 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), 1130 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
1131 afsr, afar, 1131 afsr, afar,
1132 (afsr & CHAFSR_TL1) ? 1 : 0); 1132 (afsr & CHAFSR_TL1) ? 1 : 0);
1133 printk("%s" "ERROR(%d): TPC[%016lx] TNPC[%016lx] TSTATE[%016lx]\n", 1133 printk("%s" "ERROR(%d): TPC[%lx] TNPC[%lx] O7[%lx] TSTATE[%lx]\n",
1134 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), 1134 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
1135 regs->tpc, regs->tnpc, regs->tstate); 1135 regs->tpc, regs->tnpc, regs->u_regs[UREG_I7], regs->tstate);
1136 printk("%s" "ERROR(%d): M_SYND(%lx), E_SYND(%lx)%s%s\n", 1136 printk("%s" "ERROR(%d): M_SYND(%lx), E_SYND(%lx)%s%s\n",
1137 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), 1137 (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(),
1138 (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT, 1138 (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT,
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 24790bed2054..a508e7a02891 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -159,6 +159,7 @@ archclean:
159$(SYMLINK_HEADERS): 159$(SYMLINK_HEADERS):
160 @echo ' SYMLINK $@' 160 @echo ' SYMLINK $@'
161ifneq ($(KBUILD_SRC),) 161ifneq ($(KBUILD_SRC),)
162 $(Q)mkdir -p $(objtree)/include/asm-um
162 $(Q)ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@ 163 $(Q)ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@
163else 164else
164 $(Q)cd $(TOPDIR)/$(dir $@) ; \ 165 $(Q)cd $(TOPDIR)/$(dir $@) ; \
@@ -168,7 +169,7 @@ endif
168include/asm-um/arch: 169include/asm-um/arch:
169 @echo ' SYMLINK $@' 170 @echo ' SYMLINK $@'
170ifneq ($(KBUILD_SRC),) 171ifneq ($(KBUILD_SRC),)
171 $(Q)mkdir -p include/asm-um 172 $(Q)mkdir -p $(objtree)/include/asm-um
172 $(Q)ln -fsn $(srctree)/include/asm-$(SUBARCH) include/asm-um/arch 173 $(Q)ln -fsn $(srctree)/include/asm-$(SUBARCH) include/asm-um/arch
173else 174else
174 $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch 175 $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch
diff --git a/arch/um/drivers/cow.h b/arch/um/drivers/cow.h
index 04e3958266e0..dc36b222100b 100644
--- a/arch/um/drivers/cow.h
+++ b/arch/um/drivers/cow.h
@@ -46,7 +46,7 @@ extern int file_reader(__u64 offset, char *buf, int len, void *arg);
46extern int read_cow_header(int (*reader)(__u64, char *, int, void *), 46extern int read_cow_header(int (*reader)(__u64, char *, int, void *),
47 void *arg, __u32 *version_out, 47 void *arg, __u32 *version_out,
48 char **backing_file_out, time_t *mtime_out, 48 char **backing_file_out, time_t *mtime_out,
49 __u64 *size_out, int *sectorsize_out, 49 unsigned long long *size_out, int *sectorsize_out,
50 __u32 *align_out, int *bitmap_offset_out); 50 __u32 *align_out, int *bitmap_offset_out);
51 51
52extern int write_cow_header(char *cow_file, int fd, char *backing_file, 52extern int write_cow_header(char *cow_file, int fd, char *backing_file,
diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h
index 94de4ead4f7a..7a5b4afde692 100644
--- a/arch/um/drivers/cow_sys.h
+++ b/arch/um/drivers/cow_sys.h
@@ -28,7 +28,7 @@ static inline int cow_seek_file(int fd, __u64 offset)
28 return(os_seek_file(fd, offset)); 28 return(os_seek_file(fd, offset));
29} 29}
30 30
31static inline int cow_file_size(char *file, __u64 *size_out) 31static inline int cow_file_size(char *file, unsigned long long *size_out)
32{ 32{
33 return(os_file_size(file, size_out)); 33 return(os_file_size(file, size_out));
34} 34}
diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c
index 61951b721268..6ab852bfcd3a 100644
--- a/arch/um/drivers/cow_user.c
+++ b/arch/um/drivers/cow_user.c
@@ -17,30 +17,34 @@
17 17
18#define PATH_LEN_V1 256 18#define PATH_LEN_V1 256
19 19
20typedef __u32 time32_t;
21
20struct cow_header_v1 { 22struct cow_header_v1 {
21 int magic; 23 __s32 magic;
22 int version; 24 __s32 version;
23 char backing_file[PATH_LEN_V1]; 25 char backing_file[PATH_LEN_V1];
24 time_t mtime; 26 time32_t mtime;
25 __u64 size; 27 __u64 size;
26 int sectorsize; 28 __s32 sectorsize;
27}; 29} __attribute__((packed));
28 30
29#define PATH_LEN_V2 MAXPATHLEN 31/* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in
32 * case other systems have different values for MAXPATHLEN.
33 *
34 * The same must hold for V2 - we want file format compatibility, not anything
35 * else.
36 */
37#define PATH_LEN_V3 4096
38#define PATH_LEN_V2 PATH_LEN_V3
30 39
31struct cow_header_v2 { 40struct cow_header_v2 {
32 __u32 magic; 41 __u32 magic;
33 __u32 version; 42 __u32 version;
34 char backing_file[PATH_LEN_V2]; 43 char backing_file[PATH_LEN_V2];
35 time_t mtime; 44 time32_t mtime;
36 __u64 size; 45 __u64 size;
37 int sectorsize; 46 __s32 sectorsize;
38}; 47} __attribute__((packed));
39
40/* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in
41 * case other systems have different values for MAXPATHLEN
42 */
43#define PATH_LEN_V3 4096
44 48
45/* Changes from V2 - 49/* Changes from V2 -
46 * PATH_LEN_V3 as described above 50 * PATH_LEN_V3 as described above
@@ -66,6 +70,15 @@ struct cow_header_v2 {
66 * Fixed (finally!) the rounding bug 70 * Fixed (finally!) the rounding bug
67 */ 71 */
68 72
73/* Until Dec2005, __attribute__((packed)) was left out from the below
74 * definition, leading on 64-bit systems to 4 bytes of padding after mtime, to
75 * align size to 8-byte alignment. This shifted all fields above (no padding
76 * was present on 32-bit, no other padding was added).
77 *
78 * However, this _can be detected_: it means that cow_format (always 0 until
79 * now) is shifted onto the first 4 bytes of backing_file, where it is otherwise
80 * impossible to find 4 zeros. -bb */
81
69struct cow_header_v3 { 82struct cow_header_v3 {
70 __u32 magic; 83 __u32 magic;
71 __u32 version; 84 __u32 version;
@@ -75,7 +88,19 @@ struct cow_header_v3 {
75 __u32 alignment; 88 __u32 alignment;
76 __u32 cow_format; 89 __u32 cow_format;
77 char backing_file[PATH_LEN_V3]; 90 char backing_file[PATH_LEN_V3];
78}; 91} __attribute__((packed));
92
93/* This is the broken layout used by some 64-bit binaries. */
94struct cow_header_v3_broken {
95 __u32 magic;
96 __u32 version;
97 __s64 mtime;
98 __u64 size;
99 __u32 sectorsize;
100 __u32 alignment;
101 __u32 cow_format;
102 char backing_file[PATH_LEN_V3];
103} __attribute__((packed));
79 104
80/* COW format definitions - for now, we have only the usual COW bitmap */ 105/* COW format definitions - for now, we have only the usual COW bitmap */
81#define COW_BITMAP 0 106#define COW_BITMAP 0
@@ -84,6 +109,7 @@ union cow_header {
84 struct cow_header_v1 v1; 109 struct cow_header_v1 v1;
85 struct cow_header_v2 v2; 110 struct cow_header_v2 v2;
86 struct cow_header_v3 v3; 111 struct cow_header_v3 v3;
112 struct cow_header_v3_broken v3_b;
87}; 113};
88 114
89#define COW_MAGIC 0x4f4f4f4d /* MOOO */ 115#define COW_MAGIC 0x4f4f4f4d /* MOOO */
@@ -184,8 +210,9 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
184 210
185 err = -EINVAL; 211 err = -EINVAL;
186 if(strlen(backing_file) > sizeof(header->backing_file) - 1){ 212 if(strlen(backing_file) > sizeof(header->backing_file) - 1){
213 /* Below, %zd is for a size_t value */
187 cow_printf("Backing file name \"%s\" is too long - names are " 214 cow_printf("Backing file name \"%s\" is too long - names are "
188 "limited to %d characters\n", backing_file, 215 "limited to %zd characters\n", backing_file,
189 sizeof(header->backing_file) - 1); 216 sizeof(header->backing_file) - 1);
190 goto out_free; 217 goto out_free;
191 } 218 }
@@ -300,7 +327,8 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
300 *align_out = *sectorsize_out; 327 *align_out = *sectorsize_out;
301 file = header->v2.backing_file; 328 file = header->v2.backing_file;
302 } 329 }
303 else if(version == 3){ 330 /* This is very subtle - see above at union cow_header definition */
331 else if(version == 3 && (*((int*)header->v3.backing_file) != 0)){
304 if(n < sizeof(header->v3)){ 332 if(n < sizeof(header->v3)){
305 cow_printf("read_cow_header - failed to read V3 " 333 cow_printf("read_cow_header - failed to read V3 "
306 "header\n"); 334 "header\n");
@@ -310,9 +338,43 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
310 *size_out = ntohll(header->v3.size); 338 *size_out = ntohll(header->v3.size);
311 *sectorsize_out = ntohl(header->v3.sectorsize); 339 *sectorsize_out = ntohl(header->v3.sectorsize);
312 *align_out = ntohl(header->v3.alignment); 340 *align_out = ntohl(header->v3.alignment);
341 if (*align_out == 0) {
342 cow_printf("read_cow_header - invalid COW header, "
343 "align == 0\n");
344 }
313 *bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out); 345 *bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out);
314 file = header->v3.backing_file; 346 file = header->v3.backing_file;
315 } 347 }
348 else if(version == 3){
349 cow_printf("read_cow_header - broken V3 file with"
350 " 64-bit layout - recovering content.\n");
351
352 if(n < sizeof(header->v3_b)){
353 cow_printf("read_cow_header - failed to read V3 "
354 "header\n");
355 goto out;
356 }
357
358 /* this was used until Dec2005 - 64bits are needed to represent
359 * 2038+. I.e. we can safely do this truncating cast.
360 *
361 * Additionally, we must use ntohl() instead of ntohll(), since
362 * the program used to use the former (tested - I got mtime
363 * mismatch "0 vs whatever").
364 *
365 * Ever heard about bug-to-bug-compatibility ? ;-) */
366 *mtime_out = (time32_t) ntohl(header->v3_b.mtime);
367
368 *size_out = ntohll(header->v3_b.size);
369 *sectorsize_out = ntohl(header->v3_b.sectorsize);
370 *align_out = ntohl(header->v3_b.alignment);
371 if (*align_out == 0) {
372 cow_printf("read_cow_header - invalid COW header, "
373 "align == 0\n");
374 }
375 *bitmap_offset_out = ROUND_UP(sizeof(header->v3_b), *align_out);
376 file = header->v3_b.backing_file;
377 }
316 else { 378 else {
317 cow_printf("read_cow_header - invalid COW version\n"); 379 cow_printf("read_cow_header - invalid COW version\n");
318 goto out; 380 goto out;
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 28e3760e8b98..6d7173fc55a3 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -62,7 +62,7 @@ static void mc_work_proc(void *unused)
62 unsigned long flags; 62 unsigned long flags;
63 63
64 while(!list_empty(&mc_requests)){ 64 while(!list_empty(&mc_requests)){
65 local_save_flags(flags); 65 local_irq_save(flags);
66 req = list_entry(mc_requests.next, struct mconsole_entry, 66 req = list_entry(mc_requests.next, struct mconsole_entry,
67 list); 67 list);
68 list_del(&req->list); 68 list_del(&req->list);
@@ -87,7 +87,7 @@ static irqreturn_t mconsole_interrupt(int irq, void *dev_id,
87 if(req.cmd->context == MCONSOLE_INTR) 87 if(req.cmd->context == MCONSOLE_INTR)
88 (*req.cmd->handler)(&req); 88 (*req.cmd->handler)(&req);
89 else { 89 else {
90 new = kmalloc(sizeof(*new), GFP_ATOMIC); 90 new = kmalloc(sizeof(*new), GFP_NOWAIT);
91 if(new == NULL) 91 if(new == NULL)
92 mconsole_reply(&req, "Out of memory", 1, 0); 92 mconsole_reply(&req, "Out of memory", 1, 0);
93 else { 93 else {
@@ -415,7 +415,6 @@ static int mem_config(char *str)
415 415
416 unplugged = page_address(page); 416 unplugged = page_address(page);
417 if(unplug_index == UNPLUGGED_PER_PAGE){ 417 if(unplug_index == UNPLUGGED_PER_PAGE){
418 INIT_LIST_HEAD(&unplugged->list);
419 list_add(&unplugged->list, &unplugged_pages); 418 list_add(&unplugged->list, &unplugged_pages);
420 unplug_index = 0; 419 unplug_index = 0;
421 } 420 }
@@ -616,7 +615,7 @@ static void console_write(struct console *console, const char *string,
616 return; 615 return;
617 616
618 while(1){ 617 while(1){
619 n = min((size_t)len, ARRAY_SIZE(console_buf) - console_index); 618 n = min((size_t) len, ARRAY_SIZE(console_buf) - console_index);
620 strncpy(&console_buf[console_index], string, n); 619 strncpy(&console_buf[console_index], string, n);
621 console_index += n; 620 console_index += n;
622 string += n; 621 string += n;
@@ -655,7 +654,6 @@ static void with_console(struct mc_request *req, void (*proc)(void *),
655 struct mconsole_entry entry; 654 struct mconsole_entry entry;
656 unsigned long flags; 655 unsigned long flags;
657 656
658 INIT_LIST_HEAD(&entry.list);
659 entry.request = *req; 657 entry.request = *req;
660 list_add(&entry.list, &clients); 658 list_add(&entry.list, &clients);
661 spin_lock_irqsave(&console_lock, flags); 659 spin_lock_irqsave(&console_lock, flags);
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index 0e2f06187ea7..0a7786e00cfb 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -182,7 +182,9 @@ static int change_tramp(char **argv, char *output, int output_len)
182 pe_data.stdout = fds[1]; 182 pe_data.stdout = fds[1];
183 pid = run_helper(change_pre_exec, &pe_data, argv, NULL); 183 pid = run_helper(change_pre_exec, &pe_data, argv, NULL);
184 184
185 read_output(fds[0], output, output_len); 185 if (pid > 0) /* Avoid hang as we won't get data in failure case. */
186 read_output(fds[0], output, output_len);
187
186 os_close_file(fds[0]); 188 os_close_file(fds[0]);
187 os_close_file(fds[1]); 189 os_close_file(fds[1]);
188 190
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index b94c66114bc8..33c5f6e625e8 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -104,7 +104,7 @@ static void slirp_close(int fd, void *data)
104 } 104 }
105 105
106 if(err == 0) { 106 if(err == 0) {
107 printk("slirp_close: process %d has not exited\n"); 107 printk("slirp_close: process %d has not exited\n", pri->pid);
108 return; 108 return;
109 } 109 }
110 110
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index 42557130a408..efa3d33c0be6 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -117,10 +117,6 @@ extern struct task_struct *get_task(int pid, int require);
117extern void machine_halt(void); 117extern void machine_halt(void);
118extern int is_syscall(unsigned long addr); 118extern int is_syscall(unsigned long addr);
119 119
120extern void arch_switch_to_tt(struct task_struct *from, struct task_struct *to);
121
122extern void arch_switch_to_skas(struct task_struct *from, struct task_struct *to);
123
124extern void free_irq(unsigned int, void *); 120extern void free_irq(unsigned int, void *);
125extern int cpu(void); 121extern int cpu(void);
126 122
diff --git a/arch/um/include/longjmp.h b/arch/um/include/longjmp.h
index 018b3819ab0b..8e7053013f7b 100644
--- a/arch/um/include/longjmp.h
+++ b/arch/um/include/longjmp.h
@@ -4,11 +4,11 @@
4#include <setjmp.h> 4#include <setjmp.h>
5#include "os.h" 5#include "os.h"
6 6
7#define UML_SIGLONGJMP(buf, val) do { \ 7#define UML_LONGJMP(buf, val) do { \
8 longjmp(*buf, val); \ 8 longjmp(*buf, val); \
9} while(0) 9} while(0)
10 10
11#define UML_SIGSETJMP(buf, enable) ({ \ 11#define UML_SETJMP(buf, enable) ({ \
12 int n; \ 12 int n; \
13 enable = get_signals(); \ 13 enable = get_signals(); \
14 n = setjmp(*buf); \ 14 n = setjmp(*buf); \
diff --git a/arch/um/include/sysdep-i386/kernel-offsets.h b/arch/um/include/sysdep-i386/kernel-offsets.h
index 82f96c574144..2c13de321f2f 100644
--- a/arch/um/include/sysdep-i386/kernel-offsets.h
+++ b/arch/um/include/sysdep-i386/kernel-offsets.h
@@ -1,6 +1,7 @@
1#include <linux/stddef.h> 1#include <linux/stddef.h>
2#include <linux/sched.h> 2#include <linux/sched.h>
3#include <linux/elf.h> 3#include <linux/elf.h>
4#include <asm/mman.h>
4 5
5#define DEFINE(sym, val) \ 6#define DEFINE(sym, val) \
6 asm volatile("\n->" #sym " %0 " #val : : "i" (val)) 7 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -16,6 +17,7 @@
16void foo(void) 17void foo(void)
17{ 18{
18 OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs); 19 OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs);
20 DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE);
19#ifdef CONFIG_MODE_TT 21#ifdef CONFIG_MODE_TT
20 OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); 22 OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
21#endif 23#endif
diff --git a/arch/um/include/sysdep-x86_64/kernel-offsets.h b/arch/um/include/sysdep-x86_64/kernel-offsets.h
index 5ce93abd0b54..939cc475757a 100644
--- a/arch/um/include/sysdep-x86_64/kernel-offsets.h
+++ b/arch/um/include/sysdep-x86_64/kernel-offsets.h
@@ -4,6 +4,7 @@
4#include <linux/time.h> 4#include <linux/time.h>
5#include <linux/elf.h> 5#include <linux/elf.h>
6#include <asm/page.h> 6#include <asm/page.h>
7#include <asm/mman.h>
7 8
8#define DEFINE(sym, val) \ 9#define DEFINE(sym, val) \
9 asm volatile("\n->" #sym " %0 " #val : : "i" (val)) 10 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -18,6 +19,7 @@
18 19
19void foo(void) 20void foo(void)
20{ 21{
22 DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE);
21#ifdef CONFIG_MODE_TT 23#ifdef CONFIG_MODE_TT
22 OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); 24 OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
23#endif 25#endif
diff --git a/arch/um/include/tt/tt.h b/arch/um/include/tt/tt.h
index 808521980186..acb8356e1f98 100644
--- a/arch/um/include/tt/tt.h
+++ b/arch/um/include/tt/tt.h
@@ -19,7 +19,8 @@ extern int fork_tramp(void *sig_stack);
19extern int do_proc_op(void *t, int proc_id); 19extern int do_proc_op(void *t, int proc_id);
20extern int tracer(int (*init_proc)(void *), void *sp); 20extern int tracer(int (*init_proc)(void *), void *sp);
21extern void attach_process(int pid); 21extern void attach_process(int pid);
22extern void tracer_panic(char *format, ...); 22extern void tracer_panic(char *format, ...)
23 __attribute__ ((format (printf, 1, 2)));
23extern void set_init_pid(int pid); 24extern void set_init_pid(int pid);
24extern int set_user_mode(void *task); 25extern int set_user_mode(void *task);
25extern void set_tracing(void *t, int tracing); 26extern void set_tracing(void *t, int tracing);
diff --git a/arch/um/include/user.h b/arch/um/include/user.h
index 91b0ac4ad88c..39f8c8801076 100644
--- a/arch/um/include/user.h
+++ b/arch/um/include/user.h
@@ -6,8 +6,10 @@
6#ifndef __USER_H__ 6#ifndef __USER_H__
7#define __USER_H__ 7#define __USER_H__
8 8
9extern void panic(const char *fmt, ...); 9extern void panic(const char *fmt, ...)
10extern int printk(const char *fmt, ...); 10 __attribute__ ((format (printf, 1, 2)));
11extern int printk(const char *fmt, ...)
12 __attribute__ ((format (printf, 1, 2)));
11extern void schedule(void); 13extern void schedule(void);
12extern void *um_kmalloc(int size); 14extern void *um_kmalloc(int size);
13extern void *um_kmalloc_atomic(int size); 15extern void *um_kmalloc_atomic(int size);
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
index fe0c29b5144d..802d7842514d 100644
--- a/arch/um/include/user_util.h
+++ b/arch/um/include/user_util.h
@@ -55,7 +55,8 @@ extern int get_pty(void);
55extern void *um_kmalloc(int size); 55extern void *um_kmalloc(int size);
56extern int switcheroo(int fd, int prot, void *from, void *to, int size); 56extern int switcheroo(int fd, int prot, void *from, void *to, int size);
57extern void do_exec(int old_pid, int new_pid); 57extern void do_exec(int old_pid, int new_pid);
58extern void tracer_panic(char *msg, ...); 58extern void tracer_panic(char *msg, ...)
59 __attribute__ ((format (printf, 1, 2)));
59extern int detach(int pid, int sig); 60extern int detach(int pid, int sig);
60extern int attach(int pid); 61extern int attach(int pid);
61extern void kill_child_dead(int pid); 62extern void kill_child_dead(int pid);
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index 7713e7a6f476..432cf0b97a13 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -39,7 +39,6 @@ EXPORT_SYMBOL(um_virt_to_phys);
39EXPORT_SYMBOL(mode_tt); 39EXPORT_SYMBOL(mode_tt);
40EXPORT_SYMBOL(handle_page_fault); 40EXPORT_SYMBOL(handle_page_fault);
41EXPORT_SYMBOL(find_iomem); 41EXPORT_SYMBOL(find_iomem);
42EXPORT_SYMBOL(end_iomem);
43 42
44#ifdef CONFIG_MODE_TT 43#ifdef CONFIG_MODE_TT
45EXPORT_SYMBOL(strncpy_from_user_tt); 44EXPORT_SYMBOL(strncpy_from_user_tt);
@@ -89,12 +88,10 @@ EXPORT_SYMBOL(dump_thread);
89EXPORT_SYMBOL(do_gettimeofday); 88EXPORT_SYMBOL(do_gettimeofday);
90EXPORT_SYMBOL(do_settimeofday); 89EXPORT_SYMBOL(do_settimeofday);
91 90
92/* This is here because UML expands open to sys_open, not to a system 91/* This is here because UML expands lseek to sys_lseek, not to a system
93 * call instruction. 92 * call instruction.
94 */ 93 */
95EXPORT_SYMBOL(sys_open);
96EXPORT_SYMBOL(sys_lseek); 94EXPORT_SYMBOL(sys_lseek);
97EXPORT_SYMBOL(sys_read);
98EXPORT_SYMBOL(sys_wait4); 95EXPORT_SYMBOL(sys_wait4);
99 96
100#ifdef CONFIG_SMP 97#ifdef CONFIG_SMP
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index 901b85e8a1c6..8f49507e64ef 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -40,7 +40,7 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
40 int fd) 40 int fd)
41{ 41{
42 struct addr_change change; 42 struct addr_change change;
43 void *output; 43 char *output;
44 int n; 44 int n;
45 45
46 change.what = op; 46 change.what = op;
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index 6490a4ff40ac..6987d1d247a2 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -43,7 +43,7 @@ static int helper_child(void *arg)
43 (*data->pre_exec)(data->pre_data); 43 (*data->pre_exec)(data->pre_data);
44 execvp(argv[0], argv); 44 execvp(argv[0], argv);
45 errval = errno; 45 errval = errno;
46 printk("execvp of '%s' failed - errno = %d\n", argv[0], errno); 46 printk("helper_child - execve of '%s' failed - errno = %d\n", argv[0], errno);
47 os_write_file(data->fd, &errval, sizeof(errval)); 47 os_write_file(data->fd, &errval, sizeof(errval));
48 kill(os_getpid(), SIGKILL); 48 kill(os_getpid(), SIGKILL);
49 return(0); 49 return(0);
@@ -92,15 +92,15 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
92 close(fds[1]); 92 close(fds[1]);
93 fds[1] = -1; 93 fds[1] = -1;
94 94
95 /*Read the errno value from the child.*/ 95 /* Read the errno value from the child, if the exec failed, or get 0 if
96 * the exec succeeded because the pipe fd was set as close-on-exec. */
96 n = os_read_file(fds[0], &ret, sizeof(ret)); 97 n = os_read_file(fds[0], &ret, sizeof(ret));
97 if(n < 0){ 98 if (n < 0) {
98 printk("run_helper : read on pipe failed, ret = %d\n", -n); 99 printk("run_helper : read on pipe failed, ret = %d\n", -n);
99 ret = n; 100 ret = n;
100 kill(pid, SIGKILL); 101 kill(pid, SIGKILL);
101 CATCH_EINTR(waitpid(pid, NULL, 0)); 102 CATCH_EINTR(waitpid(pid, NULL, 0));
102 } 103 } else if(n != 0){
103 else if(n != 0){
104 CATCH_EINTR(n = waitpid(pid, NULL, 0)); 104 CATCH_EINTR(n = waitpid(pid, NULL, 0));
105 ret = -errno; 105 ret = -errno;
106 } else { 106 } else {
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index 6ab372da9657..c6432e729241 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -8,6 +8,7 @@
8#include <fcntl.h> 8#include <fcntl.h>
9#include <sys/types.h> 9#include <sys/types.h>
10#include <sys/mman.h> 10#include <sys/mman.h>
11#include <sys/statfs.h>
11#include "kern_util.h" 12#include "kern_util.h"
12#include "user.h" 13#include "user.h"
13#include "user_util.h" 14#include "user_util.h"
@@ -19,6 +20,7 @@
19 20
20#include <sys/param.h> 21#include <sys/param.h>
21 22
23static char *default_tmpdir = "/tmp";
22static char *tempdir = NULL; 24static char *tempdir = NULL;
23 25
24static void __init find_tempdir(void) 26static void __init find_tempdir(void)
@@ -34,7 +36,7 @@ static void __init find_tempdir(void)
34 break; 36 break;
35 } 37 }
36 if((dir == NULL) || (*dir == '\0')) 38 if((dir == NULL) || (*dir == '\0'))
37 dir = "/tmp"; 39 dir = default_tmpdir;
38 40
39 tempdir = malloc(strlen(dir) + 2); 41 tempdir = malloc(strlen(dir) + 2);
40 if(tempdir == NULL){ 42 if(tempdir == NULL){
@@ -46,6 +48,96 @@ static void __init find_tempdir(void)
46 strcat(tempdir, "/"); 48 strcat(tempdir, "/");
47} 49}
48 50
51/* This will return 1, with the first character in buf being the
52 * character following the next instance of c in the file. This will
53 * read the file as needed. If there's an error, -errno is returned;
54 * if the end of the file is reached, 0 is returned.
55 */
56static int next(int fd, char *buf, int size, char c)
57{
58 int n;
59 char *ptr;
60
61 while((ptr = strchr(buf, c)) == NULL){
62 n = read(fd, buf, size - 1);
63 if(n == 0)
64 return 0;
65 else if(n < 0)
66 return -errno;
67
68 buf[n] = '\0';
69 }
70
71 ptr++;
72 memmove(buf, ptr, strlen(ptr) + 1);
73 return 1;
74}
75
76static int checked_tmpdir = 0;
77
78/* Look for a tmpfs mounted at /dev/shm. I couldn't find a cleaner
79 * way to do this than to parse /proc/mounts. statfs will return the
80 * same filesystem magic number and fs id for both /dev and /dev/shm
81 * when they are both tmpfs, so you can't tell if they are different
82 * filesystems. Also, there seems to be no other way of finding the
83 * mount point of a filesystem from within it.
84 *
85 * If a /dev/shm tmpfs entry is found, then we switch to using it.
86 * Otherwise, we stay with the default /tmp.
87 */
88static void which_tmpdir(void)
89{
90 int fd, found;
91 char buf[128] = { '\0' };
92
93 if(checked_tmpdir)
94 return;
95
96 checked_tmpdir = 1;
97
98 printf("Checking for tmpfs mount on /dev/shm...");
99
100 fd = open("/proc/mounts", O_RDONLY);
101 if(fd < 0){
102 printf("failed to open /proc/mounts, errno = %d\n", errno);
103 return;
104 }
105
106 while(1){
107 found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), ' ');
108 if(found != 1)
109 break;
110
111 if(!strncmp(buf, "/dev/shm", strlen("/dev/shm")))
112 goto found;
113
114 found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), '\n');
115 if(found != 1)
116 break;
117 }
118
119err:
120 if(found == 0)
121 printf("nothing mounted on /dev/shm\n");
122 else if(found < 0)
123 printf("read returned errno %d\n", -found);
124
125 return;
126
127found:
128 found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), ' ');
129 if(found != 1)
130 goto err;
131
132 if(strncmp(buf, "tmpfs", strlen("tmpfs"))){
133 printf("not tmpfs\n");
134 return;
135 }
136
137 printf("OK\n");
138 default_tmpdir = "/dev/shm";
139}
140
49/* 141/*
50 * This proc still used in tt-mode 142 * This proc still used in tt-mode
51 * (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger). 143 * (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger).
@@ -53,33 +145,37 @@ static void __init find_tempdir(void)
53 */ 145 */
54int make_tempfile(const char *template, char **out_tempname, int do_unlink) 146int make_tempfile(const char *template, char **out_tempname, int do_unlink)
55{ 147{
56 char tempname[MAXPATHLEN]; 148 char *tempname;
57 int fd; 149 int fd;
58 150
151 which_tmpdir();
152 tempname = malloc(MAXPATHLEN);
153
59 find_tempdir(); 154 find_tempdir();
60 if (*template != '/') 155 if (template[0] != '/')
61 strcpy(tempname, tempdir); 156 strcpy(tempname, tempdir);
62 else 157 else
63 *tempname = 0; 158 tempname[0] = '\0';
64 strcat(tempname, template); 159 strcat(tempname, template);
65 fd = mkstemp(tempname); 160 fd = mkstemp(tempname);
66 if(fd < 0){ 161 if(fd < 0){
67 fprintf(stderr, "open - cannot create %s: %s\n", tempname, 162 fprintf(stderr, "open - cannot create %s: %s\n", tempname,
68 strerror(errno)); 163 strerror(errno));
69 return -1; 164 goto out;
70 } 165 }
71 if(do_unlink && (unlink(tempname) < 0)){ 166 if(do_unlink && (unlink(tempname) < 0)){
72 perror("unlink"); 167 perror("unlink");
73 return -1; 168 goto out;
74 } 169 }
75 if(out_tempname){ 170 if(out_tempname){
76 *out_tempname = strdup(tempname); 171 *out_tempname = tempname;
77 if(*out_tempname == NULL){ 172 } else {
78 perror("strdup"); 173 free(tempname);
79 return -1;
80 }
81 } 174 }
82 return(fd); 175 return(fd);
176out:
177 free(tempname);
178 return -1;
83} 179}
84 180
85#define TEMPNAME_TEMPLATE "vm_file-XXXXXX" 181#define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
@@ -134,3 +230,26 @@ int create_mem_file(unsigned long long len)
134 } 230 }
135 return(fd); 231 return(fd);
136} 232}
233
234
235void check_tmpexec(void)
236{
237 void *addr;
238 int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE);
239
240 addr = mmap(NULL, UM_KERN_PAGE_SIZE,
241 PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0);
242 printf("Checking PROT_EXEC mmap in %s...",tempdir);
243 fflush(stdout);
244 if(addr == MAP_FAILED){
245 err = errno;
246 perror("failed");
247 if(err == EPERM)
248 printf("%s must be not mounted noexec\n",tempdir);
249 exit(1);
250 }
251 printf("OK\n");
252 munmap(addr, UM_KERN_PAGE_SIZE);
253
254 close(fd);
255}
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index 8176b0b52047..3505f44f8a25 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -190,7 +190,7 @@ int os_unmap_memory(void *addr, int len)
190} 190}
191 191
192#ifndef MADV_REMOVE 192#ifndef MADV_REMOVE
193#define MADV_REMOVE 0x5 /* remove these pages & resources */ 193#define MADV_REMOVE KERNEL_MADV_REMOVE
194#endif 194#endif
195 195
196int os_drop_memory(void *addr, int length) 196int os_drop_memory(void *addr, int length)
@@ -216,7 +216,7 @@ int can_drop_memory(void)
216 } 216 }
217 217
218 addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, 218 addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
219 MAP_PRIVATE, fd, 0); 219 MAP_SHARED, fd, 0);
220 if(addr == MAP_FAILED){ 220 if(addr == MAP_FAILED){
221 printk("Mapping test memory file failed, err = %d\n", -errno); 221 printk("Mapping test memory file failed, err = %d\n", -errno);
222 return 0; 222 return 0;
@@ -266,11 +266,11 @@ void init_new_thread_signals(int altstack)
266 266
267int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) 267int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
268{ 268{
269 sigjmp_buf buf; 269 jmp_buf buf;
270 int n, enable; 270 int n, enable;
271 271
272 *jmp_ptr = &buf; 272 *jmp_ptr = &buf;
273 n = UML_SIGSETJMP(&buf, enable); 273 n = UML_SETJMP(&buf, enable);
274 if(n != 0) 274 if(n != 0)
275 return(n); 275 return(n);
276 (*fn)(arg); 276 (*fn)(arg);
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
index 9ba942947146..00e9388e947a 100644
--- a/arch/um/os-Linux/sigio.c
+++ b/arch/um/os-Linux/sigio.c
@@ -304,8 +304,8 @@ out_clear_poll:
304 .size = 0, 304 .size = 0,
305 .used = 0 }); 305 .used = 0 });
306out_free: 306out_free:
307 kfree(p);
308 sigio_unlock(); 307 sigio_unlock();
308 kfree(p);
309out_close2: 309out_close2:
310 close(l_sigio_private[0]); 310 close(l_sigio_private[0]);
311 close(l_sigio_private[1]); 311 close(l_sigio_private[1]);
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index fbb080c2fc26..b3c11cfa995a 100644
--- a/arch/um/os-Linux/skas/mem.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -82,8 +82,8 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
82 if (offset) { 82 if (offset) {
83 data = (unsigned long *)(mm_idp->stack + 83 data = (unsigned long *)(mm_idp->stack +
84 offset - UML_CONFIG_STUB_DATA); 84 offset - UML_CONFIG_STUB_DATA);
85 printk("do_syscall_stub : ret = %d, offset = %d, " 85 printk("do_syscall_stub : ret = %ld, offset = %ld, "
86 "data = 0x%x\n", ret, offset, data); 86 "data = %p\n", ret, offset, data);
87 syscall = (unsigned long *)((unsigned long)data + data[0]); 87 syscall = (unsigned long *)((unsigned long)data + data[0]);
88 printk("do_syscall_stub: syscall %ld failed, return value = " 88 printk("do_syscall_stub: syscall %ld failed, return value = "
89 "0x%lx, expected return value = 0x%lx\n", 89 "0x%lx, expected return value = 0x%lx\n",
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index bbf34cb91ce1..0776bc18ca85 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -265,7 +265,7 @@ void userspace(union uml_pt_regs *regs)
265 if(err) 265 if(err)
266 panic("userspace - could not resume userspace process, " 266 panic("userspace - could not resume userspace process, "
267 "pid=%d, ptrace operation = %d, errno = %d\n", 267 "pid=%d, ptrace operation = %d, errno = %d\n",
268 op, errno); 268 pid, op, errno);
269 269
270 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); 270 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
271 if(err < 0) 271 if(err < 0)
@@ -369,7 +369,7 @@ int copy_context_skas0(unsigned long new_stack, int pid)
369 */ 369 */
370 wait_stub_done(pid, -1, "copy_context_skas0"); 370 wait_stub_done(pid, -1, "copy_context_skas0");
371 if (child_data->err != UML_CONFIG_STUB_DATA) 371 if (child_data->err != UML_CONFIG_STUB_DATA)
372 panic("copy_context_skas0 - stub-child reports error %d\n", 372 panic("copy_context_skas0 - stub-child reports error %ld\n",
373 child_data->err); 373 child_data->err);
374 374
375 if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, 375 if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
@@ -434,7 +434,7 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
434 void (*handler)(int)) 434 void (*handler)(int))
435{ 435{
436 unsigned long flags; 436 unsigned long flags;
437 sigjmp_buf switch_buf, fork_buf; 437 jmp_buf switch_buf, fork_buf;
438 int enable; 438 int enable;
439 439
440 *switch_buf_ptr = &switch_buf; 440 *switch_buf_ptr = &switch_buf;
@@ -450,7 +450,7 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
450 */ 450 */
451 flags = get_signals(); 451 flags = get_signals();
452 block_signals(); 452 block_signals();
453 if(UML_SIGSETJMP(&fork_buf, enable) == 0) 453 if(UML_SETJMP(&fork_buf, enable) == 0)
454 new_thread_proc(stack, handler); 454 new_thread_proc(stack, handler);
455 455
456 remove_sigstack(); 456 remove_sigstack();
@@ -466,35 +466,35 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
466 466
467void thread_wait(void *sw, void *fb) 467void thread_wait(void *sw, void *fb)
468{ 468{
469 sigjmp_buf buf, **switch_buf = sw, *fork_buf; 469 jmp_buf buf, **switch_buf = sw, *fork_buf;
470 int enable; 470 int enable;
471 471
472 *switch_buf = &buf; 472 *switch_buf = &buf;
473 fork_buf = fb; 473 fork_buf = fb;
474 if(UML_SIGSETJMP(&buf, enable) == 0) 474 if(UML_SETJMP(&buf, enable) == 0)
475 siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); 475 siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK);
476} 476}
477 477
478void switch_threads(void *me, void *next) 478void switch_threads(void *me, void *next)
479{ 479{
480 sigjmp_buf my_buf, **me_ptr = me, *next_buf = next; 480 jmp_buf my_buf, **me_ptr = me, *next_buf = next;
481 int enable; 481 int enable;
482 482
483 *me_ptr = &my_buf; 483 *me_ptr = &my_buf;
484 if(UML_SIGSETJMP(&my_buf, enable) == 0) 484 if(UML_SETJMP(&my_buf, enable) == 0)
485 UML_SIGLONGJMP(next_buf, 1); 485 UML_LONGJMP(next_buf, 1);
486} 486}
487 487
488static sigjmp_buf initial_jmpbuf; 488static jmp_buf initial_jmpbuf;
489 489
490/* XXX Make these percpu */ 490/* XXX Make these percpu */
491static void (*cb_proc)(void *arg); 491static void (*cb_proc)(void *arg);
492static void *cb_arg; 492static void *cb_arg;
493static sigjmp_buf *cb_back; 493static jmp_buf *cb_back;
494 494
495int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) 495int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
496{ 496{
497 sigjmp_buf **switch_buf = switch_buf_ptr; 497 jmp_buf **switch_buf = switch_buf_ptr;
498 int n, enable; 498 int n, enable;
499 499
500 set_handler(SIGWINCH, (__sighandler_t) sig_handler, 500 set_handler(SIGWINCH, (__sighandler_t) sig_handler,
@@ -502,7 +502,7 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
502 SIGVTALRM, -1); 502 SIGVTALRM, -1);
503 503
504 *fork_buf_ptr = &initial_jmpbuf; 504 *fork_buf_ptr = &initial_jmpbuf;
505 n = UML_SIGSETJMP(&initial_jmpbuf, enable); 505 n = UML_SETJMP(&initial_jmpbuf, enable);
506 switch(n){ 506 switch(n){
507 case INIT_JMP_NEW_THREAD: 507 case INIT_JMP_NEW_THREAD:
508 new_thread_proc((void *) stack, new_thread_handler); 508 new_thread_proc((void *) stack, new_thread_handler);
@@ -512,7 +512,7 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
512 break; 512 break;
513 case INIT_JMP_CALLBACK: 513 case INIT_JMP_CALLBACK:
514 (*cb_proc)(cb_arg); 514 (*cb_proc)(cb_arg);
515 UML_SIGLONGJMP(cb_back, 1); 515 UML_LONGJMP(cb_back, 1);
516 break; 516 break;
517 case INIT_JMP_HALT: 517 case INIT_JMP_HALT:
518 kmalloc_ok = 0; 518 kmalloc_ok = 0;
@@ -523,12 +523,12 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
523 default: 523 default:
524 panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); 524 panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
525 } 525 }
526 UML_SIGLONGJMP(*switch_buf, 1); 526 UML_LONGJMP(*switch_buf, 1);
527} 527}
528 528
529void initial_thread_cb_skas(void (*proc)(void *), void *arg) 529void initial_thread_cb_skas(void (*proc)(void *), void *arg)
530{ 530{
531 sigjmp_buf here; 531 jmp_buf here;
532 int enable; 532 int enable;
533 533
534 cb_proc = proc; 534 cb_proc = proc;
@@ -536,8 +536,8 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
536 cb_back = &here; 536 cb_back = &here;
537 537
538 block_signals(); 538 block_signals();
539 if(UML_SIGSETJMP(&here, enable) == 0) 539 if(UML_SETJMP(&here, enable) == 0)
540 UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK); 540 UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK);
541 unblock_signals(); 541 unblock_signals();
542 542
543 cb_proc = NULL; 543 cb_proc = NULL;
@@ -548,13 +548,13 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
548void halt_skas(void) 548void halt_skas(void)
549{ 549{
550 block_signals(); 550 block_signals();
551 UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_HALT); 551 UML_LONGJMP(&initial_jmpbuf, INIT_JMP_HALT);
552} 552}
553 553
554void reboot_skas(void) 554void reboot_skas(void)
555{ 555{
556 block_signals(); 556 block_signals();
557 UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT); 557 UML_LONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT);
558} 558}
559 559
560void switch_mm_skas(struct mm_id *mm_idp) 560void switch_mm_skas(struct mm_id *mm_idp)
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 387e26af301a..503148504009 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -296,29 +296,7 @@ static void __init check_ptrace(void)
296 check_sysemu(); 296 check_sysemu();
297} 297}
298 298
299extern int create_tmp_file(unsigned long long len); 299extern void check_tmpexec(void);
300
301static void check_tmpexec(void)
302{
303 void *addr;
304 int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE);
305
306 addr = mmap(NULL, UM_KERN_PAGE_SIZE,
307 PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0);
308 printf("Checking PROT_EXEC mmap in /tmp...");
309 fflush(stdout);
310 if(addr == MAP_FAILED){
311 err = errno;
312 perror("failed");
313 if(err == EPERM)
314 printf("/tmp must be not mounted noexec\n");
315 exit(1);
316 }
317 printf("OK\n");
318 munmap(addr, UM_KERN_PAGE_SIZE);
319
320 close(fd);
321}
322 300
323void os_early_checks(void) 301void os_early_checks(void)
324{ 302{
diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c
index ba21f0e04a2f..120abbe4e3ce 100644
--- a/arch/um/os-Linux/sys-i386/tls.c
+++ b/arch/um/os-Linux/sys-i386/tls.c
@@ -1,3 +1,4 @@
1#include <errno.h>
1#include <linux/unistd.h> 2#include <linux/unistd.h>
2#include "sysdep/tls.h" 3#include "sysdep/tls.h"
3#include "user_util.h" 4#include "user_util.h"
diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c
index a9f6b26f9828..90b29ae9af46 100644
--- a/arch/um/os-Linux/trap.c
+++ b/arch/um/os-Linux/trap.c
@@ -35,7 +35,7 @@ void os_fill_handlinfo(struct kern_handlers h)
35 35
36void do_longjmp(void *b, int val) 36void do_longjmp(void *b, int val)
37{ 37{
38 sigjmp_buf *buf = b; 38 jmp_buf *buf = b;
39 39
40 UML_SIGLONGJMP(buf, val); 40 UML_LONGJMP(buf, val);
41} 41}
diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c
index 166fb66995df..e523719330b2 100644
--- a/arch/um/os-Linux/uaccess.c
+++ b/arch/um/os-Linux/uaccess.c
@@ -16,9 +16,9 @@ unsigned long __do_user_copy(void *to, const void *from, int n,
16 unsigned long *faddrp = (unsigned long *) fault_addr, ret; 16 unsigned long *faddrp = (unsigned long *) fault_addr, ret;
17 int enable; 17 int enable;
18 18
19 sigjmp_buf jbuf; 19 jmp_buf jbuf;
20 *fault_catcher = &jbuf; 20 *fault_catcher = &jbuf;
21 if(UML_SIGSETJMP(&jbuf, enable) == 0){ 21 if(UML_SETJMP(&jbuf, enable) == 0){
22 (*op)(to, from, n); 22 (*op)(to, from, n);
23 ret = 0; 23 ret = 0;
24 *faulted_out = 0; 24 *faulted_out = 0;
diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c
index 198e59163288..34bfc1bb9e38 100644
--- a/arch/um/os-Linux/umid.c
+++ b/arch/um/os-Linux/umid.c
@@ -120,7 +120,8 @@ static int not_dead_yet(char *dir)
120 120
121 dead = 0; 121 dead = 0;
122 fd = open(file, O_RDONLY); 122 fd = open(file, O_RDONLY);
123 if(fd < 0){ 123 if(fd < 0) {
124 fd = -errno;
124 if(fd != -ENOENT){ 125 if(fd != -ENOENT){
125 printk("not_dead_yet : couldn't open pid file '%s', " 126 printk("not_dead_yet : couldn't open pid file '%s', "
126 "err = %d\n", file, -fd); 127 "err = %d\n", file, -fd);
@@ -130,9 +131,13 @@ static int not_dead_yet(char *dir)
130 131
131 err = 0; 132 err = 0;
132 n = read(fd, pid, sizeof(pid)); 133 n = read(fd, pid, sizeof(pid));
133 if(n <= 0){ 134 if(n < 0){
135 printk("not_dead_yet : couldn't read pid file '%s', "
136 "err = %d\n", file, errno);
137 goto out_close;
138 } else if(n == 0){
134 printk("not_dead_yet : couldn't read pid file '%s', " 139 printk("not_dead_yet : couldn't read pid file '%s', "
135 "err = %d\n", file, -n); 140 "0-byte read\n", file);
136 goto out_close; 141 goto out_close;
137 } 142 }
138 143
@@ -155,9 +160,9 @@ static int not_dead_yet(char *dir)
155 160
156 return err; 161 return err;
157 162
158 out_close: 163out_close:
159 close(fd); 164 close(fd);
160 out: 165out:
161 return 0; 166 return 0;
162} 167}
163 168
diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c
index 8da6ab31152a..2598158e1f53 100644
--- a/arch/um/os-Linux/user_syms.c
+++ b/arch/um/os-Linux/user_syms.c
@@ -18,14 +18,19 @@ extern void *memmove(void *, const void *, size_t);
18extern void *memset(void *, int, size_t); 18extern void *memset(void *, int, size_t);
19extern int printf(const char *, ...); 19extern int printf(const char *, ...);
20 20
21/* If they're not defined, the export is included in lib/string.c.*/
22#ifdef __HAVE_ARCH_STRLEN
21EXPORT_SYMBOL(strlen); 23EXPORT_SYMBOL(strlen);
24#endif
25#ifdef __HAVE_ARCH_STRSTR
26EXPORT_SYMBOL(strstr);
27#endif
28
22EXPORT_SYMBOL(memcpy); 29EXPORT_SYMBOL(memcpy);
23EXPORT_SYMBOL(memmove); 30EXPORT_SYMBOL(memmove);
24EXPORT_SYMBOL(memset); 31EXPORT_SYMBOL(memset);
25EXPORT_SYMBOL(printf); 32EXPORT_SYMBOL(printf);
26 33
27EXPORT_SYMBOL(strstr);
28
29/* Here, instead, I can provide a fake prototype. Yes, someone cares: genksyms. 34/* Here, instead, I can provide a fake prototype. Yes, someone cares: genksyms.
30 * However, the modules will use the CRC defined *here*, no matter if it is 35 * However, the modules will use the CRC defined *here*, no matter if it is
31 * good; so the versions of these symbols will always match 36 * good; so the versions of these symbols will always match
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c
index e32065e2fdc8..c47a2a7ce70e 100644
--- a/arch/um/os-Linux/util.c
+++ b/arch/um/os-Linux/util.c
@@ -104,7 +104,7 @@ void setup_hostinfo(void)
104int setjmp_wrapper(void (*proc)(void *, void *), ...) 104int setjmp_wrapper(void (*proc)(void *, void *), ...)
105{ 105{
106 va_list args; 106 va_list args;
107 sigjmp_buf buf; 107 jmp_buf buf;
108 int n; 108 int n;
109 109
110 n = sigsetjmp(buf, 1); 110 n = sigsetjmp(buf, 1);
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index b696b451774c..5e7a9c310aa5 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -9,10 +9,8 @@ USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
9 9
10$(USER_OBJS) $(USER_OBJS:.o=.i) $(USER_OBJS:.o=.s) $(USER_OBJS:.o=.lst): \ 10$(USER_OBJS) $(USER_OBJS:.o=.i) $(USER_OBJS:.o=.s) $(USER_OBJS:.o=.lst): \
11 c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(notdir $@)) 11 c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(notdir $@))
12$(USER_OBJS): cmd_checksrc = 12$(USER_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \
13$(USER_OBJS): quiet_cmd_checksrc = 13 -Dunix -D__unix__ -D__$(SUBARCH)__
14$(USER_OBJS): cmd_force_checksrc =
15$(USER_OBJS): quiet_cmd_force_checksrc =
16 14
17 15
18# The stubs and unmap.o can't try to call mcount or update basic block data 16# The stubs and unmap.o can't try to call mcount or update basic block data
diff --git a/arch/um/sys-i386/ksyms.c b/arch/um/sys-i386/ksyms.c
index db524ab3f743..2a1eac1859ce 100644
--- a/arch/um/sys-i386/ksyms.c
+++ b/arch/um/sys-i386/ksyms.c
@@ -15,7 +15,3 @@ EXPORT_SYMBOL(__up_wakeup);
15 15
16/* Networking helper routines. */ 16/* Networking helper routines. */
17EXPORT_SYMBOL(csum_partial); 17EXPORT_SYMBOL(csum_partial);
18
19/* delay core functions */
20EXPORT_SYMBOL(__const_udelay);
21EXPORT_SYMBOL(__udelay);
diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c
index 9f3bd8ed78f5..40aa88531446 100644
--- a/arch/um/sys-i386/ptrace_user.c
+++ b/arch/um/sys-i386/ptrace_user.c
@@ -57,7 +57,7 @@ static void write_debugregs(int pid, unsigned long *regs)
57 if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i], 57 if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i],
58 regs[i]) < 0) 58 regs[i]) < 0)
59 printk("write_debugregs - ptrace failed on " 59 printk("write_debugregs - ptrace failed on "
60 "register %d, value = 0x%x, errno = %d\n", i, 60 "register %d, value = 0x%lx, errno = %d\n", i,
61 regs[i], errno); 61 regs[i], errno);
62 } 62 }
63} 63}
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index f5d0e1c37ea2..0709fc6670c2 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -57,7 +57,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
57 return(0); 57 return(0);
58} 58}
59 59
60int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate __user *to_fp, 60int copy_sc_to_user_skas(struct sigcontext __user *to, struct _fpstate __user *to_fp,
61 struct pt_regs *regs, unsigned long sp) 61 struct pt_regs *regs, unsigned long sp)
62{ 62{
63 struct sigcontext sc; 63 struct sigcontext sc;
@@ -132,7 +132,7 @@ int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from,
132 return(err); 132 return(err);
133} 133}
134 134
135int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate __user *fp, 135int copy_sc_to_user_tt(struct sigcontext __user *to, struct _fpstate __user *fp,
136 struct sigcontext *from, int fpsize, unsigned long sp) 136 struct sigcontext *from, int fpsize, unsigned long sp)
137{ 137{
138 struct _fpstate __user *to_fp; 138 struct _fpstate __user *to_fp;
@@ -147,7 +147,7 @@ int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate __user *fp,
147 * delivery. The sp passed in is the original, and this needs 147 * delivery. The sp passed in is the original, and this needs
148 * to be restored, so we stick it in separately. 148 * to be restored, so we stick it in separately.
149 */ 149 */
150 err |= copy_to_user(&SC_SP(to), sp, sizeof(sp)); 150 err |= copy_to_user(&SC_SP(to), &sp, sizeof(sp));
151 151
152 if(from_fp != NULL){ 152 if(from_fp != NULL){
153 err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate)); 153 err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate));
@@ -167,7 +167,7 @@ static int copy_sc_from_user(struct pt_regs *to, void __user *from)
167 return(ret); 167 return(ret);
168} 168}
169 169
170static int copy_sc_to_user(struct sigcontext *to, struct _fpstate __user *fp, 170static int copy_sc_to_user(struct sigcontext __user *to, struct _fpstate __user *fp,
171 struct pt_regs *from, unsigned long sp) 171 struct pt_regs *from, unsigned long sp)
172{ 172{
173 return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), 173 return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c
index a37f672ec964..2355dc19c46c 100644
--- a/arch/um/sys-i386/stub_segv.c
+++ b/arch/um/sys-i386/stub_segv.c
@@ -27,6 +27,6 @@ stub_segv_handler(int sig)
27 * the stack in its original form when we do the sigreturn here, by 27 * the stack in its original form when we do the sigreturn here, by
28 * hand. 28 * hand.
29 */ 29 */
30 __asm__("mov %0,%%esp ; movl %1, %%eax ; " 30 __asm__ __volatile__("mov %0,%%esp ; movl %1, %%eax ; "
31 "int $0x80" : : "a" (sc), "g" (__NR_sigreturn)); 31 "int $0x80" : : "a" (sc), "g" (__NR_sigreturn));
32} 32}
diff --git a/arch/um/sys-i386/tls.c b/arch/um/sys-i386/tls.c
index a3188e861cc7..71b9796258ef 100644
--- a/arch/um/sys-i386/tls.c
+++ b/arch/um/sys-i386/tls.c
@@ -378,7 +378,7 @@ static int __init __setup_host_supports_tls(void) {
378 } else 378 } else
379 printk(KERN_ERR " Host TLS support NOT detected! " 379 printk(KERN_ERR " Host TLS support NOT detected! "
380 "TLS support inside UML will not work\n"); 380 "TLS support inside UML will not work\n");
381 return 1; 381 return 0;
382} 382}
383 383
384__initcall(__setup_host_supports_tls); 384__initcall(__setup_host_supports_tls);
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c
index e75c4e1838b0..a4c46a8af008 100644
--- a/arch/um/sys-x86_64/signal.c
+++ b/arch/um/sys-x86_64/signal.c
@@ -137,7 +137,7 @@ int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp,
137 * delivery. The sp passed in is the original, and this needs 137 * delivery. The sp passed in is the original, and this needs
138 * to be restored, so we stick it in separately. 138 * to be restored, so we stick it in separately.
139 */ 139 */
140 err |= copy_to_user(&SC_SP(to), sp, sizeof(sp)); 140 err |= copy_to_user(&SC_SP(to), &sp, sizeof(sp));
141 141
142 if(from_fp != NULL){ 142 if(from_fp != NULL){
143 err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate)); 143 err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate));
diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c
index a27099533198..1c967026c957 100644
--- a/arch/um/sys-x86_64/stub_segv.c
+++ b/arch/um/sys-x86_64/stub_segv.c
@@ -33,7 +33,7 @@ stub_segv_handler(int sig)
33 struct ucontext *uc; 33 struct ucontext *uc;
34 int pid; 34 int pid;
35 35
36 __asm__("movq %%rdx, %0" : "=g" (uc) :); 36 __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :);
37 GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), 37 GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA),
38 &uc->uc_mcontext); 38 &uc->uc_mcontext);
39 39
@@ -44,8 +44,8 @@ stub_segv_handler(int sig)
44 * the signal frame. So, we use the ucontext pointer, which we know 44 * the signal frame. So, we use the ucontext pointer, which we know
45 * already, to get the signal frame pointer, and add 8 to that. 45 * already, to get the signal frame pointer, and add 8 to that.
46 */ 46 */
47 __asm__("movq %0, %%rsp; movq %1, %%rax ; syscall": : 47 __asm__ __volatile__("movq %0, %%rsp; movq %1, %%rax ; syscall": :
48 "g" ((unsigned long) container_of(uc, struct rt_sigframe, 48 "g" ((unsigned long)
49 uc) + 8), 49 container_of(uc, struct rt_sigframe, uc) + 8),
50 "g" (__NR_rt_sigreturn)); 50 "g" (__NR_rt_sigreturn));
51} 51}
diff --git a/arch/v850/kernel/v850_ksyms.c b/arch/v850/kernel/v850_ksyms.c
index 8ffc29c1c89d..6bcfcfe88384 100644
--- a/arch/v850/kernel/v850_ksyms.c
+++ b/arch/v850/kernel/v850_ksyms.c
@@ -43,7 +43,6 @@ EXPORT_SYMBOL (strncmp);
43EXPORT_SYMBOL (strchr); 43EXPORT_SYMBOL (strchr);
44EXPORT_SYMBOL (strlen); 44EXPORT_SYMBOL (strlen);
45EXPORT_SYMBOL (strnlen); 45EXPORT_SYMBOL (strnlen);
46EXPORT_SYMBOL (strpbrk);
47EXPORT_SYMBOL (strrchr); 46EXPORT_SYMBOL (strrchr);
48EXPORT_SYMBOL (strstr); 47EXPORT_SYMBOL (strstr);
49EXPORT_SYMBOL (memset); 48EXPORT_SYMBOL (memset);
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 4310b4a311a5..408d44a59756 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -136,6 +136,11 @@ config X86_L1_CACHE_SHIFT
136 default "7" if GENERIC_CPU || MPSC 136 default "7" if GENERIC_CPU || MPSC
137 default "6" if MK8 137 default "6" if MK8
138 138
139config X86_INTERNODE_CACHE_BYTES
140 int
141 default "4096" if X86_VSMP
142 default X86_L1_CACHE_BYTES if !X86_VSMP
143
139config X86_TSC 144config X86_TSC
140 bool 145 bool
141 default y 146 default y
@@ -283,6 +288,11 @@ config K8_NUMA
283 Northbridge of Opteron. It is recommended to use X86_64_ACPI_NUMA 288 Northbridge of Opteron. It is recommended to use X86_64_ACPI_NUMA
284 instead, which also takes priority if both are compiled in. 289 instead, which also takes priority if both are compiled in.
285 290
291config NODES_SHIFT
292 int
293 default "6"
294 depends on NEED_MULTIPLE_NODES
295
286# Dummy CONFIG option to select ACPI_NUMA from drivers/acpi/Kconfig. 296# Dummy CONFIG option to select ACPI_NUMA from drivers/acpi/Kconfig.
287 297
288config X86_64_ACPI_NUMA 298config X86_64_ACPI_NUMA
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile
index 585fd4a559c8..e573e2ab5510 100644
--- a/arch/x86_64/Makefile
+++ b/arch/x86_64/Makefile
@@ -24,37 +24,37 @@
24LDFLAGS := -m elf_x86_64 24LDFLAGS := -m elf_x86_64
25OBJCOPYFLAGS := -O binary -R .note -R .comment -S 25OBJCOPYFLAGS := -O binary -R .note -R .comment -S
26LDFLAGS_vmlinux := 26LDFLAGS_vmlinux :=
27
28CHECKFLAGS += -D__x86_64__ -m64 27CHECKFLAGS += -D__x86_64__ -m64
29 28
29cflags-y :=
30cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8) 30cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8)
31cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona) 31cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona)
32cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic) 32cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic)
33CFLAGS += $(cflags-y)
34 33
35CFLAGS += -m64 34cflags-y += -m64
36CFLAGS += -mno-red-zone 35cflags-y += -mno-red-zone
37CFLAGS += -mcmodel=kernel 36cflags-y += -mcmodel=kernel
38CFLAGS += -pipe 37cflags-y += -pipe
39cflags-$(CONFIG_REORDER) += -ffunction-sections 38cflags-$(CONFIG_REORDER) += -ffunction-sections
40# this makes reading assembly source easier, but produces worse code 39# this makes reading assembly source easier, but produces worse code
41# actually it makes the kernel smaller too. 40# actually it makes the kernel smaller too.
42CFLAGS += -fno-reorder-blocks 41cflags-y += -fno-reorder-blocks
43CFLAGS += -Wno-sign-compare 42cflags-y += -Wno-sign-compare
44ifneq ($(CONFIG_UNWIND_INFO),y) 43ifneq ($(CONFIG_UNWIND_INFO),y)
45CFLAGS += -fno-asynchronous-unwind-tables 44cflags-y += -fno-asynchronous-unwind-tables
46endif 45endif
47ifneq ($(CONFIG_DEBUG_INFO),y) 46ifneq ($(CONFIG_DEBUG_INFO),y)
48# -fweb shrinks the kernel a bit, but the difference is very small 47# -fweb shrinks the kernel a bit, but the difference is very small
49# it also messes up debugging, so don't use it for now. 48# it also messes up debugging, so don't use it for now.
50#CFLAGS += $(call cc-option,-fweb) 49#cflags-y += $(call cc-option,-fweb)
51endif 50endif
52# -funit-at-a-time shrinks the kernel .text considerably 51# -funit-at-a-time shrinks the kernel .text considerably
53# unfortunately it makes reading oopses harder. 52# unfortunately it makes reading oopses harder.
54CFLAGS += $(call cc-option,-funit-at-a-time) 53cflags-y += $(call cc-option,-funit-at-a-time)
55# prevent gcc from generating any FP code by mistake 54# prevent gcc from generating any FP code by mistake
56CFLAGS += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) 55cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
57 56
57CFLAGS += $(cflags-y)
58AFLAGS += -m64 58AFLAGS += -m64
59 59
60head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o 60head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o
diff --git a/arch/x86_64/boot/video.S b/arch/x86_64/boot/video.S
index 0587477c99f2..32327bb37aff 100644
--- a/arch/x86_64/boot/video.S
+++ b/arch/x86_64/boot/video.S
@@ -97,6 +97,7 @@
97#define PARAM_VESAPM_OFF 0x30 97#define PARAM_VESAPM_OFF 0x30
98#define PARAM_LFB_PAGES 0x32 98#define PARAM_LFB_PAGES 0x32
99#define PARAM_VESA_ATTRIB 0x34 99#define PARAM_VESA_ATTRIB 0x34
100#define PARAM_CAPABILITIES 0x36
100 101
101/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */ 102/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
102#ifdef CONFIG_VIDEO_RETAIN 103#ifdef CONFIG_VIDEO_RETAIN
@@ -233,6 +234,10 @@ mopar_gr:
233 movw 18(%di), %ax 234 movw 18(%di), %ax
234 movl %eax, %fs:(PARAM_LFB_SIZE) 235 movl %eax, %fs:(PARAM_LFB_SIZE)
235 236
237# store mode capabilities
238 movl 10(%di), %eax
239 movl %eax, %fs:(PARAM_CAPABILITIES)
240
236# switching the DAC to 8-bit is for <= 8 bpp only 241# switching the DAC to 8-bit is for <= 8 bpp only
237 movw %fs:(PARAM_LFB_DEPTH), %ax 242 movw %fs:(PARAM_LFB_DEPTH), %ax
238 cmpw $8, %ax 243 cmpw $8, %ax
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
index 566ecc97ee5a..69db0c0721d1 100644
--- a/arch/x86_64/defconfig
+++ b/arch/x86_64/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.16-git9 3# Linux kernel version: 2.6.17-rc1-git11
4# Sat Mar 25 15:18:40 2006 4# Sun Apr 16 07:22:36 2006
5# 5#
6CONFIG_X86_64=y 6CONFIG_X86_64=y
7CONFIG_64BIT=y 7CONFIG_64BIT=y
@@ -9,6 +9,7 @@ CONFIG_X86=y
9CONFIG_SEMAPHORE_SLEEPERS=y 9CONFIG_SEMAPHORE_SLEEPERS=y
10CONFIG_MMU=y 10CONFIG_MMU=y
11CONFIG_RWSEM_GENERIC_SPINLOCK=y 11CONFIG_RWSEM_GENERIC_SPINLOCK=y
12CONFIG_GENERIC_HWEIGHT=y
12CONFIG_GENERIC_CALIBRATE_DELAY=y 13CONFIG_GENERIC_CALIBRATE_DELAY=y
13CONFIG_X86_CMPXCHG=y 14CONFIG_X86_CMPXCHG=y
14CONFIG_EARLY_PRINTK=y 15CONFIG_EARLY_PRINTK=y
@@ -55,11 +56,8 @@ CONFIG_BASE_FULL=y
55CONFIG_FUTEX=y 56CONFIG_FUTEX=y
56CONFIG_EPOLL=y 57CONFIG_EPOLL=y
57CONFIG_SHMEM=y 58CONFIG_SHMEM=y
58CONFIG_CC_ALIGN_FUNCTIONS=0
59CONFIG_CC_ALIGN_LABELS=0
60CONFIG_CC_ALIGN_LOOPS=0
61CONFIG_CC_ALIGN_JUMPS=0
62CONFIG_SLAB=y 59CONFIG_SLAB=y
60CONFIG_DOUBLEFAULT=y
63# CONFIG_TINY_SHMEM is not set 61# CONFIG_TINY_SHMEM is not set
64CONFIG_BASE_SMALL=0 62CONFIG_BASE_SMALL=0
65# CONFIG_SLOB is not set 63# CONFIG_SLOB is not set
@@ -70,7 +68,6 @@ CONFIG_BASE_SMALL=0
70CONFIG_MODULES=y 68CONFIG_MODULES=y
71CONFIG_MODULE_UNLOAD=y 69CONFIG_MODULE_UNLOAD=y
72CONFIG_MODULE_FORCE_UNLOAD=y 70CONFIG_MODULE_FORCE_UNLOAD=y
73CONFIG_OBSOLETE_MODPARM=y
74# CONFIG_MODVERSIONS is not set 71# CONFIG_MODVERSIONS is not set
75# CONFIG_MODULE_SRCVERSION_ALL is not set 72# CONFIG_MODULE_SRCVERSION_ALL is not set
76# CONFIG_KMOD is not set 73# CONFIG_KMOD is not set
@@ -81,6 +78,7 @@ CONFIG_STOP_MACHINE=y
81# 78#
82CONFIG_LBD=y 79CONFIG_LBD=y
83# CONFIG_BLK_DEV_IO_TRACE is not set 80# CONFIG_BLK_DEV_IO_TRACE is not set
81# CONFIG_LSF is not set
84 82
85# 83#
86# IO Schedulers 84# IO Schedulers
@@ -105,6 +103,7 @@ CONFIG_X86_PC=y
105CONFIG_GENERIC_CPU=y 103CONFIG_GENERIC_CPU=y
106CONFIG_X86_L1_CACHE_BYTES=128 104CONFIG_X86_L1_CACHE_BYTES=128
107CONFIG_X86_L1_CACHE_SHIFT=7 105CONFIG_X86_L1_CACHE_SHIFT=7
106CONFIG_X86_INTERNODE_CACHE_BYTES=128
108CONFIG_X86_TSC=y 107CONFIG_X86_TSC=y
109CONFIG_X86_GOOD_APIC=y 108CONFIG_X86_GOOD_APIC=y
110# CONFIG_MICROCODE is not set 109# CONFIG_MICROCODE is not set
@@ -116,12 +115,14 @@ CONFIG_X86_LOCAL_APIC=y
116CONFIG_MTRR=y 115CONFIG_MTRR=y
117CONFIG_SMP=y 116CONFIG_SMP=y
118CONFIG_SCHED_SMT=y 117CONFIG_SCHED_SMT=y
118CONFIG_SCHED_MC=y
119# CONFIG_PREEMPT_NONE is not set 119# CONFIG_PREEMPT_NONE is not set
120CONFIG_PREEMPT_VOLUNTARY=y 120CONFIG_PREEMPT_VOLUNTARY=y
121# CONFIG_PREEMPT is not set 121# CONFIG_PREEMPT is not set
122CONFIG_PREEMPT_BKL=y 122CONFIG_PREEMPT_BKL=y
123CONFIG_NUMA=y 123CONFIG_NUMA=y
124CONFIG_K8_NUMA=y 124CONFIG_K8_NUMA=y
125CONFIG_NODES_SHIFT=6
125CONFIG_X86_64_ACPI_NUMA=y 126CONFIG_X86_64_ACPI_NUMA=y
126CONFIG_NUMA_EMU=y 127CONFIG_NUMA_EMU=y
127CONFIG_ARCH_DISCONTIGMEM_ENABLE=y 128CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
@@ -138,6 +139,7 @@ CONFIG_NEED_MULTIPLE_NODES=y
138CONFIG_SPLIT_PTLOCK_CPUS=4 139CONFIG_SPLIT_PTLOCK_CPUS=4
139CONFIG_MIGRATION=y 140CONFIG_MIGRATION=y
140CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y 141CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
142CONFIG_OUT_OF_LINE_PFN_TO_PAGE=y
141CONFIG_NR_CPUS=32 143CONFIG_NR_CPUS=32
142CONFIG_HOTPLUG_CPU=y 144CONFIG_HOTPLUG_CPU=y
143CONFIG_HPET_TIMER=y 145CONFIG_HPET_TIMER=y
@@ -289,6 +291,7 @@ CONFIG_IP_PNP_DHCP=y
289# CONFIG_INET_AH is not set 291# CONFIG_INET_AH is not set
290# CONFIG_INET_ESP is not set 292# CONFIG_INET_ESP is not set
291# CONFIG_INET_IPCOMP is not set 293# CONFIG_INET_IPCOMP is not set
294# CONFIG_INET_XFRM_TUNNEL is not set
292# CONFIG_INET_TUNNEL is not set 295# CONFIG_INET_TUNNEL is not set
293CONFIG_INET_DIAG=y 296CONFIG_INET_DIAG=y
294CONFIG_INET_TCP_DIAG=y 297CONFIG_INET_TCP_DIAG=y
@@ -300,6 +303,7 @@ CONFIG_IPV6=y
300# CONFIG_INET6_AH is not set 303# CONFIG_INET6_AH is not set
301# CONFIG_INET6_ESP is not set 304# CONFIG_INET6_ESP is not set
302# CONFIG_INET6_IPCOMP is not set 305# CONFIG_INET6_IPCOMP is not set
306# CONFIG_INET6_XFRM_TUNNEL is not set
303# CONFIG_INET6_TUNNEL is not set 307# CONFIG_INET6_TUNNEL is not set
304# CONFIG_IPV6_TUNNEL is not set 308# CONFIG_IPV6_TUNNEL is not set
305# CONFIG_NETFILTER is not set 309# CONFIG_NETFILTER is not set
@@ -542,7 +546,6 @@ CONFIG_SCSI_SATA_INTEL_COMBINED=y
542# CONFIG_SCSI_INIA100 is not set 546# CONFIG_SCSI_INIA100 is not set
543# CONFIG_SCSI_SYM53C8XX_2 is not set 547# CONFIG_SCSI_SYM53C8XX_2 is not set
544# CONFIG_SCSI_IPR is not set 548# CONFIG_SCSI_IPR is not set
545# CONFIG_SCSI_QLOGIC_FC is not set
546# CONFIG_SCSI_QLOGIC_1280 is not set 549# CONFIG_SCSI_QLOGIC_1280 is not set
547# CONFIG_SCSI_QLA_FC is not set 550# CONFIG_SCSI_QLA_FC is not set
548# CONFIG_SCSI_LPFC is not set 551# CONFIG_SCSI_LPFC is not set
@@ -704,7 +707,6 @@ CONFIG_S2IO=m
704# Wireless LAN (non-hamradio) 707# Wireless LAN (non-hamradio)
705# 708#
706# CONFIG_NET_RADIO is not set 709# CONFIG_NET_RADIO is not set
707# CONFIG_NET_WIRELESS_RTNETLINK is not set
708 710
709# 711#
710# Wan interfaces 712# Wan interfaces
@@ -791,7 +793,7 @@ CONFIG_HW_CONSOLE=y
791# 793#
792CONFIG_SERIAL_8250=y 794CONFIG_SERIAL_8250=y
793CONFIG_SERIAL_8250_CONSOLE=y 795CONFIG_SERIAL_8250_CONSOLE=y
794# CONFIG_SERIAL_8250_ACPI is not set 796CONFIG_SERIAL_8250_PCI=y
795CONFIG_SERIAL_8250_NR_UARTS=4 797CONFIG_SERIAL_8250_NR_UARTS=4
796CONFIG_SERIAL_8250_RUNTIME_UARTS=4 798CONFIG_SERIAL_8250_RUNTIME_UARTS=4
797# CONFIG_SERIAL_8250_EXTENDED is not set 799# CONFIG_SERIAL_8250_EXTENDED is not set
@@ -921,6 +923,7 @@ CONFIG_HWMON=y
921# Digital Video Broadcasting Devices 923# Digital Video Broadcasting Devices
922# 924#
923# CONFIG_DVB is not set 925# CONFIG_DVB is not set
926# CONFIG_USB_DABUSB is not set
924 927
925# 928#
926# Graphics support 929# Graphics support
@@ -932,6 +935,8 @@ CONFIG_VIDEO_SELECT=y
932# Console display driver support 935# Console display driver support
933# 936#
934CONFIG_VGA_CONSOLE=y 937CONFIG_VGA_CONSOLE=y
938CONFIG_VGACON_SOFT_SCROLLBACK=y
939CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=256
935CONFIG_DUMMY_CONSOLE=y 940CONFIG_DUMMY_CONSOLE=y
936 941
937# 942#
@@ -1041,9 +1046,7 @@ CONFIG_USB_HIDINPUT=y
1041# CONFIG_USB_ACECAD is not set 1046# CONFIG_USB_ACECAD is not set
1042# CONFIG_USB_KBTAB is not set 1047# CONFIG_USB_KBTAB is not set
1043# CONFIG_USB_POWERMATE is not set 1048# CONFIG_USB_POWERMATE is not set
1044# CONFIG_USB_MTOUCH is not set 1049# CONFIG_USB_TOUCHSCREEN is not set
1045# CONFIG_USB_ITMTOUCH is not set
1046# CONFIG_USB_EGALAX is not set
1047# CONFIG_USB_YEALINK is not set 1050# CONFIG_USB_YEALINK is not set
1048# CONFIG_USB_XPAD is not set 1051# CONFIG_USB_XPAD is not set
1049# CONFIG_USB_ATI_REMOTE is not set 1052# CONFIG_USB_ATI_REMOTE is not set
@@ -1058,15 +1061,6 @@ CONFIG_USB_HIDINPUT=y
1058# CONFIG_USB_MICROTEK is not set 1061# CONFIG_USB_MICROTEK is not set
1059 1062
1060# 1063#
1061# USB Multimedia devices
1062#
1063# CONFIG_USB_DABUSB is not set
1064
1065#
1066# Video4Linux support is needed for USB Multimedia device support
1067#
1068
1069#
1070# USB Network Adapters 1064# USB Network Adapters
1071# 1065#
1072# CONFIG_USB_CATC is not set 1066# CONFIG_USB_CATC is not set
@@ -1118,9 +1112,23 @@ CONFIG_USB_MON=y
1118# CONFIG_MMC is not set 1112# CONFIG_MMC is not set
1119 1113
1120# 1114#
1115# LED devices
1116#
1117# CONFIG_NEW_LEDS is not set
1118
1119#
1120# LED drivers
1121#
1122
1123#
1124# LED Triggers
1125#
1126
1127#
1121# InfiniBand support 1128# InfiniBand support
1122# 1129#
1123# CONFIG_INFINIBAND is not set 1130# CONFIG_INFINIBAND is not set
1131# CONFIG_IPATH_CORE is not set
1124 1132
1125# 1133#
1126# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) 1134# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
@@ -1128,6 +1136,11 @@ CONFIG_USB_MON=y
1128# CONFIG_EDAC is not set 1136# CONFIG_EDAC is not set
1129 1137
1130# 1138#
1139# Real Time Clock
1140#
1141# CONFIG_RTC_CLASS is not set
1142
1143#
1131# Firmware Drivers 1144# Firmware Drivers
1132# 1145#
1133# CONFIG_EDD is not set 1146# CONFIG_EDD is not set
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index 35b2faccdc6c..57fc37e0fb9c 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -15,6 +15,8 @@
15#include <asm/vsyscall32.h> 15#include <asm/vsyscall32.h>
16#include <linux/linkage.h> 16#include <linux/linkage.h>
17 17
18#define IA32_NR_syscalls ((ia32_syscall_end - ia32_sys_call_table)/8)
19
18 .macro IA32_ARG_FIXUP noebp=0 20 .macro IA32_ARG_FIXUP noebp=0
19 movl %edi,%r8d 21 movl %edi,%r8d
20 .if \noebp 22 .if \noebp
@@ -109,8 +111,8 @@ ENTRY(ia32_sysenter_target)
109 CFI_REMEMBER_STATE 111 CFI_REMEMBER_STATE
110 jnz sysenter_tracesys 112 jnz sysenter_tracesys
111sysenter_do_call: 113sysenter_do_call:
112 cmpl $(IA32_NR_syscalls),%eax 114 cmpl $(IA32_NR_syscalls-1),%eax
113 jae ia32_badsys 115 ja ia32_badsys
114 IA32_ARG_FIXUP 1 116 IA32_ARG_FIXUP 1
115 call *ia32_sys_call_table(,%rax,8) 117 call *ia32_sys_call_table(,%rax,8)
116 movq %rax,RAX-ARGOFFSET(%rsp) 118 movq %rax,RAX-ARGOFFSET(%rsp)
@@ -210,8 +212,8 @@ ENTRY(ia32_cstar_target)
210 CFI_REMEMBER_STATE 212 CFI_REMEMBER_STATE
211 jnz cstar_tracesys 213 jnz cstar_tracesys
212cstar_do_call: 214cstar_do_call:
213 cmpl $IA32_NR_syscalls,%eax 215 cmpl $IA32_NR_syscalls-1,%eax
214 jae ia32_badsys 216 ja ia32_badsys
215 IA32_ARG_FIXUP 1 217 IA32_ARG_FIXUP 1
216 call *ia32_sys_call_table(,%rax,8) 218 call *ia32_sys_call_table(,%rax,8)
217 movq %rax,RAX-ARGOFFSET(%rsp) 219 movq %rax,RAX-ARGOFFSET(%rsp)
@@ -296,8 +298,8 @@ ENTRY(ia32_syscall)
296 testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10) 298 testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%r10)
297 jnz ia32_tracesys 299 jnz ia32_tracesys
298ia32_do_syscall: 300ia32_do_syscall:
299 cmpl $(IA32_NR_syscalls),%eax 301 cmpl $(IA32_NR_syscalls-1),%eax
300 jae ia32_badsys 302 ja ia32_badsys
301 IA32_ARG_FIXUP 303 IA32_ARG_FIXUP
302 call *ia32_sys_call_table(,%rax,8) # xxx: rip relative 304 call *ia32_sys_call_table(,%rax,8) # xxx: rip relative
303ia32_sysret: 305ia32_sysret:
@@ -685,12 +687,12 @@ ia32_sys_call_table:
685 .quad sys_readlinkat /* 305 */ 687 .quad sys_readlinkat /* 305 */
686 .quad sys_fchmodat 688 .quad sys_fchmodat
687 .quad sys_faccessat 689 .quad sys_faccessat
688 .quad sys_ni_syscall /* pselect6 for now */ 690 .quad quiet_ni_syscall /* pselect6 for now */
689 .quad sys_ni_syscall /* ppoll for now */ 691 .quad quiet_ni_syscall /* ppoll for now */
690 .quad sys_unshare /* 310 */ 692 .quad sys_unshare /* 310 */
691 .quad compat_sys_set_robust_list 693 .quad compat_sys_set_robust_list
692 .quad compat_sys_get_robust_list 694 .quad compat_sys_get_robust_list
695 .quad sys_splice
696 .quad sys_sync_file_range
697 .quad sys_tee
693ia32_syscall_end: 698ia32_syscall_end:
694 .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
695 .quad ni_syscall
696 .endr
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
index a098a11e7755..059c88313f4e 100644
--- a/arch/x86_64/kernel/Makefile
+++ b/arch/x86_64/kernel/Makefile
@@ -8,7 +8,7 @@ obj-y := process.o signal.o entry.o traps.o irq.o \
8 ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \ 8 ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \
9 x8664_ksyms.o i387.o syscall.o vsyscall.o \ 9 x8664_ksyms.o i387.o syscall.o vsyscall.o \
10 setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \ 10 setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \
11 dmi_scan.o pci-dma.o pci-nommu.o 11 pci-dma.o pci-nommu.o
12 12
13obj-$(CONFIG_X86_MCE) += mce.o 13obj-$(CONFIG_X86_MCE) += mce.o
14obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o 14obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o
@@ -49,5 +49,3 @@ intel_cacheinfo-y += ../../i386/kernel/cpu/intel_cacheinfo.o
49quirks-y += ../../i386/kernel/quirks.o 49quirks-y += ../../i386/kernel/quirks.o
50i8237-y += ../../i386/kernel/i8237.o 50i8237-y += ../../i386/kernel/i8237.o
51msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o 51msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o
52dmi_scan-y += ../../i386/kernel/dmi_scan.o
53
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c
index fffd6b0a2fab..70b9d21ed675 100644
--- a/arch/x86_64/kernel/aperture.c
+++ b/arch/x86_64/kernel/aperture.c
@@ -80,7 +80,7 @@ static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size)
80 printk("Aperture from %s beyond 4GB. Ignoring.\n",name); 80 printk("Aperture from %s beyond 4GB. Ignoring.\n",name);
81 return 0; 81 return 0;
82 } 82 }
83 if (e820_mapped(aper_base, aper_base + aper_size, E820_RAM)) { 83 if (e820_any_mapped(aper_base, aper_base + aper_size, E820_RAM)) {
84 printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name); 84 printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name);
85 return 0; 85 return 0;
86 } 86 }
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
index 293cd71a266a..62776c07cff1 100644
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -80,7 +80,12 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size)
80 return 0; 80 return 0;
81} 81}
82 82
83int __init e820_mapped(unsigned long start, unsigned long end, unsigned type) 83/*
84 * This function checks if any part of the range <start,end> is mapped
85 * with type.
86 */
87int __meminit
88e820_any_mapped(unsigned long start, unsigned long end, unsigned type)
84{ 89{
85 int i; 90 int i;
86 for (i = 0; i < e820.nr_map; i++) { 91 for (i = 0; i < e820.nr_map; i++) {
@@ -94,6 +99,35 @@ int __init e820_mapped(unsigned long start, unsigned long end, unsigned type)
94 return 0; 99 return 0;
95} 100}
96 101
102/*
103 * This function checks if the entire range <start,end> is mapped with type.
104 *
105 * Note: this function only works correct if the e820 table is sorted and
106 * not-overlapping, which is the case
107 */
108int __init e820_all_mapped(unsigned long start, unsigned long end, unsigned type)
109{
110 int i;
111 for (i = 0; i < e820.nr_map; i++) {
112 struct e820entry *ei = &e820.map[i];
113 if (type && ei->type != type)
114 continue;
115 /* is the region (part) in overlap with the current region ?*/
116 if (ei->addr >= end || ei->addr + ei->size <= start)
117 continue;
118
119 /* if the region is at the beginning of <start,end> we move
120 * start to the end of the region since it's ok until there
121 */
122 if (ei->addr <= start)
123 start = ei->addr + ei->size;
124 /* if start is now at or beyond end, we're done, full coverage */
125 if (start >= end)
126 return 1; /* we're done */
127 }
128 return 0;
129}
130
97/* 131/*
98 * Find a free area in a specific range. 132 * Find a free area in a specific range.
99 */ 133 */
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
index 8538bfea30e6..c946e4fe67a7 100644
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -180,6 +180,10 @@ rff_trace:
180 * 180 *
181 * XXX if we had a free scratch register we could save the RSP into the stack frame 181 * XXX if we had a free scratch register we could save the RSP into the stack frame
182 * and report it properly in ps. Unfortunately we haven't. 182 * and report it properly in ps. Unfortunately we haven't.
183 *
184 * When user can change the frames always force IRET. That is because
185 * it deals with uncanonical addresses better. SYSRET has trouble
186 * with them due to bugs in both AMD and Intel CPUs.
183 */ 187 */
184 188
185ENTRY(system_call) 189ENTRY(system_call)
@@ -254,7 +258,10 @@ sysret_signal:
254 xorl %esi,%esi # oldset -> arg2 258 xorl %esi,%esi # oldset -> arg2
255 call ptregscall_common 259 call ptregscall_common
2561: movl $_TIF_NEED_RESCHED,%edi 2601: movl $_TIF_NEED_RESCHED,%edi
257 jmp sysret_check 261 /* Use IRET because user could have changed frame. This
262 works because ptregscall_common has called FIXUP_TOP_OF_STACK. */
263 cli
264 jmp int_with_check
258 265
259badsys: 266badsys:
260 movq $-ENOSYS,RAX-ARGOFFSET(%rsp) 267 movq $-ENOSYS,RAX-ARGOFFSET(%rsp)
@@ -280,7 +287,8 @@ tracesys:
280 call syscall_trace_leave 287 call syscall_trace_leave
281 RESTORE_TOP_OF_STACK %rbx 288 RESTORE_TOP_OF_STACK %rbx
282 RESTORE_REST 289 RESTORE_REST
283 jmp ret_from_sys_call 290 /* Use IRET because user could have changed frame */
291 jmp int_ret_from_sys_call
284 CFI_ENDPROC 292 CFI_ENDPROC
285 293
286/* 294/*
@@ -408,25 +416,9 @@ ENTRY(stub_execve)
408 CFI_ADJUST_CFA_OFFSET -8 416 CFI_ADJUST_CFA_OFFSET -8
409 CFI_REGISTER rip, r11 417 CFI_REGISTER rip, r11
410 SAVE_REST 418 SAVE_REST
411 movq %r11, %r15
412 CFI_REGISTER rip, r15
413 FIXUP_TOP_OF_STACK %r11 419 FIXUP_TOP_OF_STACK %r11
414 call sys_execve 420 call sys_execve
415 GET_THREAD_INFO(%rcx)
416 bt $TIF_IA32,threadinfo_flags(%rcx)
417 CFI_REMEMBER_STATE
418 jc exec_32bit
419 RESTORE_TOP_OF_STACK %r11 421 RESTORE_TOP_OF_STACK %r11
420 movq %r15, %r11
421 CFI_REGISTER rip, r11
422 RESTORE_REST
423 pushq %r11
424 CFI_ADJUST_CFA_OFFSET 8
425 CFI_REL_OFFSET rip, 0
426 ret
427
428exec_32bit:
429 CFI_RESTORE_STATE
430 movq %rax,RAX(%rsp) 422 movq %rax,RAX(%rsp)
431 RESTORE_REST 423 RESTORE_REST
432 jmp int_ret_from_sys_call 424 jmp int_ret_from_sys_call
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
index accbff3fec49..1eaa5dae6174 100644
--- a/arch/x86_64/kernel/kprobes.c
+++ b/arch/x86_64/kernel/kprobes.c
@@ -53,7 +53,7 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
53/* 53/*
54 * returns non-zero if opcode modifies the interrupt flag. 54 * returns non-zero if opcode modifies the interrupt flag.
55 */ 55 */
56static inline int is_IF_modifier(kprobe_opcode_t *insn) 56static __always_inline int is_IF_modifier(kprobe_opcode_t *insn)
57{ 57{
58 switch (*insn) { 58 switch (*insn) {
59 case 0xfa: /* cli */ 59 case 0xfa: /* cli */
@@ -84,7 +84,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
84 * If it does, return the address of the 32-bit displacement word. 84 * If it does, return the address of the 32-bit displacement word.
85 * If not, return null. 85 * If not, return null.
86 */ 86 */
87static inline s32 *is_riprel(u8 *insn) 87static s32 __kprobes *is_riprel(u8 *insn)
88{ 88{
89#define W(row,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf) \ 89#define W(row,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf) \
90 (((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) | \ 90 (((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) | \
@@ -229,7 +229,7 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
229 mutex_unlock(&kprobe_mutex); 229 mutex_unlock(&kprobe_mutex);
230} 230}
231 231
232static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) 232static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
233{ 233{
234 kcb->prev_kprobe.kp = kprobe_running(); 234 kcb->prev_kprobe.kp = kprobe_running();
235 kcb->prev_kprobe.status = kcb->kprobe_status; 235 kcb->prev_kprobe.status = kcb->kprobe_status;
@@ -237,7 +237,7 @@ static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
237 kcb->prev_kprobe.saved_rflags = kcb->kprobe_saved_rflags; 237 kcb->prev_kprobe.saved_rflags = kcb->kprobe_saved_rflags;
238} 238}
239 239
240static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) 240static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
241{ 241{
242 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; 242 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
243 kcb->kprobe_status = kcb->prev_kprobe.status; 243 kcb->kprobe_status = kcb->prev_kprobe.status;
@@ -245,7 +245,7 @@ static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
245 kcb->kprobe_saved_rflags = kcb->prev_kprobe.saved_rflags; 245 kcb->kprobe_saved_rflags = kcb->prev_kprobe.saved_rflags;
246} 246}
247 247
248static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, 248static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
249 struct kprobe_ctlblk *kcb) 249 struct kprobe_ctlblk *kcb)
250{ 250{
251 __get_cpu_var(current_kprobe) = p; 251 __get_cpu_var(current_kprobe) = p;
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c
index 10b3e348fc99..6f0790e8b6d3 100644
--- a/arch/x86_64/kernel/mce.c
+++ b/arch/x86_64/kernel/mce.c
@@ -29,6 +29,8 @@
29#define MISC_MCELOG_MINOR 227 29#define MISC_MCELOG_MINOR 227
30#define NR_BANKS 6 30#define NR_BANKS 6
31 31
32atomic_t mce_entry;
33
32static int mce_dont_init; 34static int mce_dont_init;
33 35
34/* 0: always panic, 1: panic if deadlock possible, 2: try to avoid panic, 36/* 0: always panic, 1: panic if deadlock possible, 2: try to avoid panic,
@@ -172,10 +174,12 @@ void do_machine_check(struct pt_regs * regs, long error_code)
172 int i; 174 int i;
173 int panicm_found = 0; 175 int panicm_found = 0;
174 176
177 atomic_inc(&mce_entry);
178
175 if (regs) 179 if (regs)
176 notify_die(DIE_NMI, "machine check", regs, error_code, 18, SIGKILL); 180 notify_die(DIE_NMI, "machine check", regs, error_code, 18, SIGKILL);
177 if (!banks) 181 if (!banks)
178 return; 182 goto out2;
179 183
180 memset(&m, 0, sizeof(struct mce)); 184 memset(&m, 0, sizeof(struct mce));
181 m.cpu = safe_smp_processor_id(); 185 m.cpu = safe_smp_processor_id();
@@ -266,6 +270,8 @@ void do_machine_check(struct pt_regs * regs, long error_code)
266 out: 270 out:
267 /* Last thing done in the machine check exception to clear state. */ 271 /* Last thing done in the machine check exception to clear state. */
268 wrmsrl(MSR_IA32_MCG_STATUS, 0); 272 wrmsrl(MSR_IA32_MCG_STATUS, 0);
273 out2:
274 atomic_dec(&mce_entry);
269} 275}
270 276
271/* 277/*
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index d9e4067faf05..4e6357fe0ec3 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -34,6 +34,7 @@
34#include <asm/proto.h> 34#include <asm/proto.h>
35#include <asm/kdebug.h> 35#include <asm/kdebug.h>
36#include <asm/local.h> 36#include <asm/local.h>
37#include <asm/mce.h>
37 38
38/* 39/*
39 * lapic_nmi_owner tracks the ownership of the lapic NMI hardware: 40 * lapic_nmi_owner tracks the ownership of the lapic NMI hardware:
@@ -480,6 +481,12 @@ void __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
480 __get_cpu_var(nmi_touch) = 0; 481 __get_cpu_var(nmi_touch) = 0;
481 touched = 1; 482 touched = 1;
482 } 483 }
484#ifdef CONFIG_X86_MCE
485 /* Could check oops_in_progress here too, but it's safer
486 not too */
487 if (atomic_read(&mce_entry) > 0)
488 touched = 1;
489#endif
483 if (!touched && __get_cpu_var(last_irq_sum) == sum) { 490 if (!touched && __get_cpu_var(last_irq_sum) == sum) {
484 /* 491 /*
485 * Ayiee, looks like this CPU is stuck ... 492 * Ayiee, looks like this CPU is stuck ...
diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c
index 03c9eeedb0f3..af035ede70cd 100644
--- a/arch/x86_64/kernel/pci-dma.c
+++ b/arch/x86_64/kernel/pci-dma.c
@@ -48,9 +48,11 @@ dma_alloc_pages(struct device *dev, gfp_t gfp, unsigned order)
48{ 48{
49 struct page *page; 49 struct page *page;
50 int node; 50 int node;
51#ifdef CONFIG_PCI
51 if (dev->bus == &pci_bus_type) 52 if (dev->bus == &pci_bus_type)
52 node = pcibus_to_node(to_pci_dev(dev)->bus); 53 node = pcibus_to_node(to_pci_dev(dev)->bus);
53 else 54 else
55#endif
54 node = numa_node_id(); 56 node = numa_node_id();
55 page = alloc_pages_node(node, gfp, order); 57 page = alloc_pages_node(node, gfp, order);
56 return page ? page_address(page) : NULL; 58 return page ? page_address(page) : NULL;
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 70dd8e5c6889..fb903e65e079 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -575,8 +575,10 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
575 prev->userrsp = read_pda(oldrsp); 575 prev->userrsp = read_pda(oldrsp);
576 write_pda(oldrsp, next->userrsp); 576 write_pda(oldrsp, next->userrsp);
577 write_pda(pcurrent, next_p); 577 write_pda(pcurrent, next_p);
578
578 /* This must be here to ensure both math_state_restore() and 579 /* This must be here to ensure both math_state_restore() and
579 kernel_fpu_begin() work consistently. */ 580 kernel_fpu_begin() work consistently.
581 And the AMD workaround requires it to be after DS reload. */
580 unlazy_fpu(prev_p); 582 unlazy_fpu(prev_p);
581 write_pda(kernelstack, 583 write_pda(kernelstack,
582 task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET); 584 task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
@@ -781,10 +783,16 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
781 } 783 }
782 case ARCH_GET_GS: { 784 case ARCH_GET_GS: {
783 unsigned long base; 785 unsigned long base;
786 unsigned gsindex;
784 if (task->thread.gsindex == GS_TLS_SEL) 787 if (task->thread.gsindex == GS_TLS_SEL)
785 base = read_32bit_tls(task, GS_TLS); 788 base = read_32bit_tls(task, GS_TLS);
786 else if (doit) 789 else if (doit) {
787 rdmsrl(MSR_KERNEL_GS_BASE, base); 790 asm("movl %%gs,%0" : "=r" (gsindex));
791 if (gsindex)
792 rdmsrl(MSR_KERNEL_GS_BASE, base);
793 else
794 base = task->thread.gs;
795 }
788 else 796 else
789 base = task->thread.gs; 797 base = task->thread.gs;
790 ret = put_user(base, (unsigned long __user *)addr); 798 ret = put_user(base, (unsigned long __user *)addr);
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
index d44b2c1e63a6..da8e7903d817 100644
--- a/arch/x86_64/kernel/ptrace.c
+++ b/arch/x86_64/kernel/ptrace.c
@@ -274,11 +274,6 @@ static int putreg(struct task_struct *child,
274 return -EIO; 274 return -EIO;
275 value &= 0xffff; 275 value &= 0xffff;
276 break; 276 break;
277 case offsetof(struct user_regs_struct, rip):
278 /* Check if the new RIP address is canonical */
279 if (value >= TASK_SIZE_OF(child))
280 return -EIO;
281 break;
282 } 277 }
283 put_stack_long(child, regno - sizeof(struct pt_regs), value); 278 put_stack_long(child, regno - sizeof(struct pt_regs), value);
284 return 0; 279 return 0;
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 0856ad444f90..759070c82751 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -353,8 +353,10 @@ static __init void parse_cmdline_early (char ** cmdline_p)
353 if (fullarg(from, "enable_timer_pin_1")) 353 if (fullarg(from, "enable_timer_pin_1"))
354 disable_timer_pin_1 = -1; 354 disable_timer_pin_1 = -1;
355 355
356 if (fullarg(from, "nolapic") || fullarg(from, "disableapic")) 356 if (fullarg(from, "nolapic") || fullarg(from, "disableapic")) {
357 clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
357 disable_apic = 1; 358 disable_apic = 1;
359 }
358 360
359 if (fullarg(from, "noapic")) 361 if (fullarg(from, "noapic"))
360 skip_ioapic_setup = 1; 362 skip_ioapic_setup = 1;
@@ -928,6 +930,10 @@ static int __init init_amd(struct cpuinfo_x86 *c)
928 if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)) 930 if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58))
929 set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability); 931 set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
930 932
933 /* Enable workaround for FXSAVE leak */
934 if (c->x86 >= 6)
935 set_bit(X86_FEATURE_FXSAVE_LEAK, &c->x86_capability);
936
931 r = get_model_name(c); 937 r = get_model_name(c);
932 if (!r) { 938 if (!r) {
933 switch (c->x86) { 939 switch (c->x86) {
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index ef8bc46dc140..7392570f975d 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -726,7 +726,7 @@ static __init int late_hpet_init(void)
726 unsigned int ntimer; 726 unsigned int ntimer;
727 727
728 if (!vxtime.hpet_address) 728 if (!vxtime.hpet_address)
729 return -1; 729 return 0;
730 730
731 memset(&hd, 0, sizeof (hd)); 731 memset(&hd, 0, sizeof (hd));
732 732
@@ -917,6 +917,8 @@ void __init time_init(void)
917 vxtime.hpet_address = 0; 917 vxtime.hpet_address = 0;
918 918
919 if (hpet_use_timer) { 919 if (hpet_use_timer) {
920 /* set tick_nsec to use the proper rate for HPET */
921 tick_nsec = TICK_NSEC_HPET;
920 cpu_khz = hpet_calibrate_tsc(); 922 cpu_khz = hpet_calibrate_tsc();
921 timename = "HPET"; 923 timename = "HPET";
922#ifdef CONFIG_X86_PM_TIMER 924#ifdef CONFIG_X86_PM_TIMER
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index 6bda322d3caf..2700b1375c1f 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -30,6 +30,7 @@
30#include <linux/moduleparam.h> 30#include <linux/moduleparam.h>
31#include <linux/nmi.h> 31#include <linux/nmi.h>
32#include <linux/kprobes.h> 32#include <linux/kprobes.h>
33#include <linux/kexec.h>
33 34
34#include <asm/system.h> 35#include <asm/system.h>
35#include <asm/uaccess.h> 36#include <asm/uaccess.h>
@@ -433,6 +434,8 @@ void __kprobes __die(const char * str, struct pt_regs * regs, long err)
433 printk(KERN_ALERT "RIP "); 434 printk(KERN_ALERT "RIP ");
434 printk_address(regs->rip); 435 printk_address(regs->rip);
435 printk(" RSP <%016lx>\n", regs->rsp); 436 printk(" RSP <%016lx>\n", regs->rsp);
437 if (kexec_should_crash(current))
438 crash_kexec(regs);
436} 439}
437 440
438void die(const char * str, struct pt_regs * regs, long err) 441void die(const char * str, struct pt_regs * regs, long err)
@@ -455,6 +458,8 @@ void __kprobes die_nmi(char *str, struct pt_regs *regs)
455 */ 458 */
456 printk(str, safe_smp_processor_id()); 459 printk(str, safe_smp_processor_id());
457 show_registers(regs); 460 show_registers(regs);
461 if (kexec_should_crash(current))
462 crash_kexec(regs);
458 if (panic_on_timeout || panic_on_oops) 463 if (panic_on_timeout || panic_on_oops)
459 panic("nmi watchdog"); 464 panic("nmi watchdog");
460 printk("console shuts up ...\n"); 465 printk("console shuts up ...\n");
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S
index 39ff0708f803..b81f473c4a19 100644
--- a/arch/x86_64/kernel/vmlinux.lds.S
+++ b/arch/x86_64/kernel/vmlinux.lds.S
@@ -65,7 +65,7 @@ SECTIONS
65 .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { 65 .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
66 *(.data.cacheline_aligned) 66 *(.data.cacheline_aligned)
67 } 67 }
68 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); 68 . = ALIGN(CONFIG_X86_INTERNODE_CACHE_BYTES);
69 .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { 69 .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
70 *(.data.read_mostly) 70 *(.data.read_mostly)
71 } 71 }
diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c
index d78f46056bda..1def21c9f7cd 100644
--- a/arch/x86_64/kernel/x8664_ksyms.c
+++ b/arch/x86_64/kernel/x8664_ksyms.c
@@ -112,7 +112,6 @@ EXPORT_SYMBOL_GPL(unset_nmi_callback);
112#undef memcpy 112#undef memcpy
113#undef memset 113#undef memset
114#undef memmove 114#undef memmove
115#undef strlen
116 115
117extern void * memset(void *,int,__kernel_size_t); 116extern void * memset(void *,int,__kernel_size_t);
118extern size_t strlen(const char *); 117extern size_t strlen(const char *);
@@ -121,8 +120,6 @@ extern void * memcpy(void *,const void *,__kernel_size_t);
121extern void * __memcpy(void *,const void *,__kernel_size_t); 120extern void * __memcpy(void *,const void *,__kernel_size_t);
122 121
123EXPORT_SYMBOL(memset); 122EXPORT_SYMBOL(memset);
124EXPORT_SYMBOL(strlen);
125EXPORT_SYMBOL(strpbrk);
126EXPORT_SYMBOL(memmove); 123EXPORT_SYMBOL(memmove);
127EXPORT_SYMBOL(memcpy); 124EXPORT_SYMBOL(memcpy);
128EXPORT_SYMBOL(__memcpy); 125EXPORT_SYMBOL(__memcpy);
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index e5f7f1c34462..4ba34e95d835 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -305,7 +305,7 @@ static void __meminit phys_pud_init(pud_t *pud, unsigned long address, unsigned
305 if (paddr >= end) 305 if (paddr >= end)
306 break; 306 break;
307 307
308 if (!after_bootmem && !e820_mapped(paddr, paddr+PUD_SIZE, 0)) { 308 if (!after_bootmem && !e820_any_mapped(paddr, paddr+PUD_SIZE, 0)) {
309 set_pud(pud, __pud(0)); 309 set_pud(pud, __pud(0));
310 continue; 310 continue;
311 } 311 }
@@ -507,9 +507,8 @@ void __init clear_kernel_mapping(unsigned long address, unsigned long size)
507 507
508/* 508/*
509 * Memory hotplug specific functions 509 * Memory hotplug specific functions
510 * These are only for non-NUMA machines right now.
511 */ 510 */
512#ifdef CONFIG_MEMORY_HOTPLUG 511#if defined(CONFIG_ACPI_HOTPLUG_MEMORY) || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)
513 512
514void online_page(struct page *page) 513void online_page(struct page *page)
515{ 514{
@@ -520,6 +519,38 @@ void online_page(struct page *page)
520 num_physpages++; 519 num_physpages++;
521} 520}
522 521
522#ifndef CONFIG_MEMORY_HOTPLUG
523/*
524 * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance,
525 * just online the pages.
526 */
527int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages)
528{
529 int err = -EIO;
530 unsigned long pfn;
531 unsigned long total = 0, mem = 0;
532 for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) {
533 if (pfn_valid(pfn)) {
534 online_page(pfn_to_page(pfn));
535 err = 0;
536 mem++;
537 }
538 total++;
539 }
540 if (!err) {
541 z->spanned_pages += total;
542 z->present_pages += mem;
543 z->zone_pgdat->node_spanned_pages += total;
544 z->zone_pgdat->node_present_pages += mem;
545 }
546 return err;
547}
548#endif
549
550/*
551 * Memory is added always to NORMAL zone. This means you will never get
552 * additional DMA/DMA32 memory.
553 */
523int add_memory(u64 start, u64 size) 554int add_memory(u64 start, u64 size)
524{ 555{
525 struct pglist_data *pgdat = NODE_DATA(0); 556 struct pglist_data *pgdat = NODE_DATA(0);
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
index 4be82d6e2b48..cc02573a3271 100644
--- a/arch/x86_64/mm/numa.c
+++ b/arch/x86_64/mm/numa.c
@@ -100,11 +100,30 @@ int early_pfn_to_nid(unsigned long pfn)
100} 100}
101#endif 101#endif
102 102
103static void * __init
104early_node_mem(int nodeid, unsigned long start, unsigned long end,
105 unsigned long size)
106{
107 unsigned long mem = find_e820_area(start, end, size);
108 void *ptr;
109 if (mem != -1L)
110 return __va(mem);
111 ptr = __alloc_bootmem_nopanic(size,
112 SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS));
113 if (ptr == 0) {
114 printk(KERN_ERR "Cannot find %lu bytes in node %d\n",
115 size, nodeid);
116 return NULL;
117 }
118 return ptr;
119}
120
103/* Initialize bootmem allocator for a node */ 121/* Initialize bootmem allocator for a node */
104void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end) 122void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end)
105{ 123{
106 unsigned long start_pfn, end_pfn, bootmap_pages, bootmap_size, bootmap_start; 124 unsigned long start_pfn, end_pfn, bootmap_pages, bootmap_size, bootmap_start;
107 unsigned long nodedata_phys; 125 unsigned long nodedata_phys;
126 void *bootmap;
108 const int pgdat_size = round_up(sizeof(pg_data_t), PAGE_SIZE); 127 const int pgdat_size = round_up(sizeof(pg_data_t), PAGE_SIZE);
109 128
110 start = round_up(start, ZONE_ALIGN); 129 start = round_up(start, ZONE_ALIGN);
@@ -114,13 +133,11 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en
114 start_pfn = start >> PAGE_SHIFT; 133 start_pfn = start >> PAGE_SHIFT;
115 end_pfn = end >> PAGE_SHIFT; 134 end_pfn = end >> PAGE_SHIFT;
116 135
117 nodedata_phys = find_e820_area(start, end, pgdat_size); 136 node_data[nodeid] = early_node_mem(nodeid, start, end, pgdat_size);
118 if (nodedata_phys == -1L) 137 if (node_data[nodeid] == NULL)
119 panic("Cannot find memory pgdat in node %d\n", nodeid); 138 return;
120 139 nodedata_phys = __pa(node_data[nodeid]);
121 Dprintk("nodedata_phys %lx\n", nodedata_phys);
122 140
123 node_data[nodeid] = phys_to_virt(nodedata_phys);
124 memset(NODE_DATA(nodeid), 0, sizeof(pg_data_t)); 141 memset(NODE_DATA(nodeid), 0, sizeof(pg_data_t));
125 NODE_DATA(nodeid)->bdata = &plat_node_bdata[nodeid]; 142 NODE_DATA(nodeid)->bdata = &plat_node_bdata[nodeid];
126 NODE_DATA(nodeid)->node_start_pfn = start_pfn; 143 NODE_DATA(nodeid)->node_start_pfn = start_pfn;
@@ -129,9 +146,15 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en
129 /* Find a place for the bootmem map */ 146 /* Find a place for the bootmem map */
130 bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); 147 bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
131 bootmap_start = round_up(nodedata_phys + pgdat_size, PAGE_SIZE); 148 bootmap_start = round_up(nodedata_phys + pgdat_size, PAGE_SIZE);
132 bootmap_start = find_e820_area(bootmap_start, end, bootmap_pages<<PAGE_SHIFT); 149 bootmap = early_node_mem(nodeid, bootmap_start, end,
133 if (bootmap_start == -1L) 150 bootmap_pages<<PAGE_SHIFT);
134 panic("Not enough continuous space for bootmap on node %d", nodeid); 151 if (bootmap == NULL) {
152 if (nodedata_phys < start || nodedata_phys >= end)
153 free_bootmem((unsigned long)node_data[nodeid],pgdat_size);
154 node_data[nodeid] = NULL;
155 return;
156 }
157 bootmap_start = __pa(bootmap);
135 Dprintk("bootmap start %lu pages %lu\n", bootmap_start, bootmap_pages); 158 Dprintk("bootmap start %lu pages %lu\n", bootmap_start, bootmap_pages);
136 159
137 bootmap_size = init_bootmem_node(NODE_DATA(nodeid), 160 bootmap_size = init_bootmem_node(NODE_DATA(nodeid),
@@ -142,6 +165,9 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en
142 165
143 reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size); 166 reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size);
144 reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start, bootmap_pages<<PAGE_SHIFT); 167 reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start, bootmap_pages<<PAGE_SHIFT);
168#ifdef CONFIG_ACPI_NUMA
169 srat_reserve_add_area(nodeid);
170#endif
145 node_set_online(nodeid); 171 node_set_online(nodeid);
146} 172}
147 173
@@ -335,6 +361,8 @@ __init int numa_setup(char *opt)
335#ifdef CONFIG_ACPI_NUMA 361#ifdef CONFIG_ACPI_NUMA
336 if (!strncmp(opt,"noacpi",6)) 362 if (!strncmp(opt,"noacpi",6))
337 acpi_numa = -1; 363 acpi_numa = -1;
364 if (!strncmp(opt,"hotadd=", 7))
365 hotadd_percent = simple_strtoul(opt+7, NULL, 10);
338#endif 366#endif
339 return 1; 367 return 1;
340} 368}
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c
index 2eb879590dc4..15ae9fcd65a7 100644
--- a/arch/x86_64/mm/srat.c
+++ b/arch/x86_64/mm/srat.c
@@ -15,15 +15,26 @@
15#include <linux/bitmap.h> 15#include <linux/bitmap.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/topology.h> 17#include <linux/topology.h>
18#include <linux/bootmem.h>
19#include <linux/mm.h>
18#include <asm/proto.h> 20#include <asm/proto.h>
19#include <asm/numa.h> 21#include <asm/numa.h>
20#include <asm/e820.h> 22#include <asm/e820.h>
21 23
24#if (defined(CONFIG_ACPI_HOTPLUG_MEMORY) || \
25 defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)) \
26 && !defined(CONFIG_MEMORY_HOTPLUG)
27#define RESERVE_HOTADD 1
28#endif
29
22static struct acpi_table_slit *acpi_slit; 30static struct acpi_table_slit *acpi_slit;
23 31
24static nodemask_t nodes_parsed __initdata; 32static nodemask_t nodes_parsed __initdata;
25static nodemask_t nodes_found __initdata; 33static nodemask_t nodes_found __initdata;
26static struct bootnode nodes[MAX_NUMNODES] __initdata; 34static struct bootnode nodes[MAX_NUMNODES] __initdata;
35static struct bootnode nodes_add[MAX_NUMNODES] __initdata;
36static int found_add_area __initdata;
37int hotadd_percent __initdata = 10;
27static u8 pxm2node[256] = { [0 ... 255] = 0xff }; 38static u8 pxm2node[256] = { [0 ... 255] = 0xff };
28 39
29/* Too small nodes confuse the VM badly. Usually they result 40/* Too small nodes confuse the VM badly. Usually they result
@@ -71,6 +82,10 @@ static __init int conflicting_nodes(unsigned long start, unsigned long end)
71static __init void cutoff_node(int i, unsigned long start, unsigned long end) 82static __init void cutoff_node(int i, unsigned long start, unsigned long end)
72{ 83{
73 struct bootnode *nd = &nodes[i]; 84 struct bootnode *nd = &nodes[i];
85
86 if (found_add_area)
87 return;
88
74 if (nd->start < start) { 89 if (nd->start < start) {
75 nd->start = start; 90 nd->start = start;
76 if (nd->end < nd->start) 91 if (nd->end < nd->start)
@@ -90,6 +105,8 @@ static __init void bad_srat(void)
90 acpi_numa = -1; 105 acpi_numa = -1;
91 for (i = 0; i < MAX_LOCAL_APIC; i++) 106 for (i = 0; i < MAX_LOCAL_APIC; i++)
92 apicid_to_node[i] = NUMA_NO_NODE; 107 apicid_to_node[i] = NUMA_NO_NODE;
108 for (i = 0; i < MAX_NUMNODES; i++)
109 nodes_add[i].start = nodes[i].end = 0;
93} 110}
94 111
95static __init inline int srat_disabled(void) 112static __init inline int srat_disabled(void)
@@ -155,11 +172,114 @@ acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa)
155 pxm, pa->apic_id, node); 172 pxm, pa->apic_id, node);
156} 173}
157 174
175#ifdef RESERVE_HOTADD
176/*
177 * Protect against too large hotadd areas that would fill up memory.
178 */
179static int hotadd_enough_memory(struct bootnode *nd)
180{
181 static unsigned long allocated;
182 static unsigned long last_area_end;
183 unsigned long pages = (nd->end - nd->start) >> PAGE_SHIFT;
184 long mem = pages * sizeof(struct page);
185 unsigned long addr;
186 unsigned long allowed;
187 unsigned long oldpages = pages;
188
189 if (mem < 0)
190 return 0;
191 allowed = (end_pfn - e820_hole_size(0, end_pfn)) * PAGE_SIZE;
192 allowed = (allowed / 100) * hotadd_percent;
193 if (allocated + mem > allowed) {
194 /* Give them at least part of their hotadd memory upto hotadd_percent
195 It would be better to spread the limit out
196 over multiple hotplug areas, but that is too complicated
197 right now */
198 if (allocated >= allowed)
199 return 0;
200 pages = (allowed - allocated + mem) / sizeof(struct page);
201 mem = pages * sizeof(struct page);
202 nd->end = nd->start + pages*PAGE_SIZE;
203 }
204 /* Not completely fool proof, but a good sanity check */
205 addr = find_e820_area(last_area_end, end_pfn<<PAGE_SHIFT, mem);
206 if (addr == -1UL)
207 return 0;
208 if (pages != oldpages)
209 printk(KERN_NOTICE "SRAT: Hotadd area limited to %lu bytes\n",
210 pages << PAGE_SHIFT);
211 last_area_end = addr + mem;
212 allocated += mem;
213 return 1;
214}
215
216/*
217 * It is fine to add this area to the nodes data it will be used later
218 * This code supports one contigious hot add area per node.
219 */
220static int reserve_hotadd(int node, unsigned long start, unsigned long end)
221{
222 unsigned long s_pfn = start >> PAGE_SHIFT;
223 unsigned long e_pfn = end >> PAGE_SHIFT;
224 int changed = 0;
225 struct bootnode *nd = &nodes_add[node];
226
227 /* I had some trouble with strange memory hotadd regions breaking
228 the boot. Be very strict here and reject anything unexpected.
229 If you want working memory hotadd write correct SRATs.
230
231 The node size check is a basic sanity check to guard against
232 mistakes */
233 if ((signed long)(end - start) < NODE_MIN_SIZE) {
234 printk(KERN_ERR "SRAT: Hotplug area too small\n");
235 return -1;
236 }
237
238 /* This check might be a bit too strict, but I'm keeping it for now. */
239 if (e820_hole_size(s_pfn, e_pfn) != e_pfn - s_pfn) {
240 printk(KERN_ERR "SRAT: Hotplug area has existing memory\n");
241 return -1;
242 }
243
244 if (!hotadd_enough_memory(&nodes_add[node])) {
245 printk(KERN_ERR "SRAT: Hotplug area too large\n");
246 return -1;
247 }
248
249 /* Looks good */
250
251 found_add_area = 1;
252 if (nd->start == nd->end) {
253 nd->start = start;
254 nd->end = end;
255 changed = 1;
256 } else {
257 if (nd->start == end) {
258 nd->start = start;
259 changed = 1;
260 }
261 if (nd->end == start) {
262 nd->end = end;
263 changed = 1;
264 }
265 if (!changed)
266 printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n");
267 }
268
269 if ((nd->end >> PAGE_SHIFT) > end_pfn)
270 end_pfn = nd->end >> PAGE_SHIFT;
271
272 if (changed)
273 printk(KERN_INFO "SRAT: hot plug zone found %Lx - %Lx\n", nd->start, nd->end);
274 return 0;
275}
276#endif
277
158/* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ 278/* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
159void __init 279void __init
160acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) 280acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
161{ 281{
162 struct bootnode *nd; 282 struct bootnode *nd, oldnode;
163 unsigned long start, end; 283 unsigned long start, end;
164 int node, pxm; 284 int node, pxm;
165 int i; 285 int i;
@@ -172,6 +292,8 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
172 } 292 }
173 if (ma->flags.enabled == 0) 293 if (ma->flags.enabled == 0)
174 return; 294 return;
295 if (ma->flags.hot_pluggable && hotadd_percent == 0)
296 return;
175 start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32); 297 start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32);
176 end = start + (ma->length_lo | ((u64)ma->length_hi << 32)); 298 end = start + (ma->length_lo | ((u64)ma->length_hi << 32));
177 pxm = ma->proximity_domain; 299 pxm = ma->proximity_domain;
@@ -181,10 +303,6 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
181 bad_srat(); 303 bad_srat();
182 return; 304 return;
183 } 305 }
184 /* It is fine to add this area to the nodes data it will be used later*/
185 if (ma->flags.hot_pluggable == 1)
186 printk(KERN_INFO "SRAT: hot plug zone found %lx - %lx \n",
187 start, end);
188 i = conflicting_nodes(start, end); 306 i = conflicting_nodes(start, end);
189 if (i == node) { 307 if (i == node) {
190 printk(KERN_WARNING 308 printk(KERN_WARNING
@@ -199,6 +317,7 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
199 return; 317 return;
200 } 318 }
201 nd = &nodes[node]; 319 nd = &nodes[node];
320 oldnode = *nd;
202 if (!node_test_and_set(node, nodes_parsed)) { 321 if (!node_test_and_set(node, nodes_parsed)) {
203 nd->start = start; 322 nd->start = start;
204 nd->end = end; 323 nd->end = end;
@@ -208,8 +327,19 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
208 if (nd->end < end) 327 if (nd->end < end)
209 nd->end = end; 328 nd->end = end;
210 } 329 }
330
211 printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm, 331 printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm,
212 nd->start, nd->end); 332 nd->start, nd->end);
333
334#ifdef RESERVE_HOTADD
335 if (ma->flags.hot_pluggable && reserve_hotadd(node, start, end) < 0) {
336 /* Ignore hotadd region. Undo damage */
337 printk(KERN_NOTICE "SRAT: Hotplug region ignored\n");
338 *nd = oldnode;
339 if ((nd->start | nd->end) == 0)
340 node_clear(node, nodes_parsed);
341 }
342#endif
213} 343}
214 344
215/* Sanity check to catch more bad SRATs (they are amazingly common). 345/* Sanity check to catch more bad SRATs (they are amazingly common).
@@ -225,6 +355,9 @@ static int nodes_cover_memory(void)
225 unsigned long e = nodes[i].end >> PAGE_SHIFT; 355 unsigned long e = nodes[i].end >> PAGE_SHIFT;
226 pxmram += e - s; 356 pxmram += e - s;
227 pxmram -= e820_hole_size(s, e); 357 pxmram -= e820_hole_size(s, e);
358 pxmram -= nodes_add[i].end - nodes_add[i].start;
359 if ((long)pxmram < 0)
360 pxmram = 0;
228 } 361 }
229 362
230 e820ram = end_pfn - e820_hole_size(0, end_pfn); 363 e820ram = end_pfn - e820_hole_size(0, end_pfn);
@@ -258,7 +391,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
258 391
259 /* First clean up the node list */ 392 /* First clean up the node list */
260 for (i = 0; i < MAX_NUMNODES; i++) { 393 for (i = 0; i < MAX_NUMNODES; i++) {
261 cutoff_node(i, start, end); 394 cutoff_node(i, start, end);
262 if ((nodes[i].end - nodes[i].start) < NODE_MIN_SIZE) 395 if ((nodes[i].end - nodes[i].start) < NODE_MIN_SIZE)
263 unparse_node(i); 396 unparse_node(i);
264 } 397 }
@@ -282,6 +415,12 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
282 /* Finally register nodes */ 415 /* Finally register nodes */
283 for_each_node_mask(i, nodes_parsed) 416 for_each_node_mask(i, nodes_parsed)
284 setup_node_bootmem(i, nodes[i].start, nodes[i].end); 417 setup_node_bootmem(i, nodes[i].start, nodes[i].end);
418 /* Try again in case setup_node_bootmem missed one due
419 to missing bootmem */
420 for_each_node_mask(i, nodes_parsed)
421 if (!node_online(i))
422 setup_node_bootmem(i, nodes[i].start, nodes[i].end);
423
285 for (i = 0; i < NR_CPUS; i++) { 424 for (i = 0; i < NR_CPUS; i++) {
286 if (cpu_to_node[i] == NUMA_NO_NODE) 425 if (cpu_to_node[i] == NUMA_NO_NODE)
287 continue; 426 continue;
@@ -303,6 +442,25 @@ static int node_to_pxm(int n)
303 return 0; 442 return 0;
304} 443}
305 444
445void __init srat_reserve_add_area(int nodeid)
446{
447 if (found_add_area && nodes_add[nodeid].end) {
448 u64 total_mb;
449
450 printk(KERN_INFO "SRAT: Reserving hot-add memory space "
451 "for node %d at %Lx-%Lx\n",
452 nodeid, nodes_add[nodeid].start, nodes_add[nodeid].end);
453 total_mb = (nodes_add[nodeid].end - nodes_add[nodeid].start)
454 >> PAGE_SHIFT;
455 total_mb *= sizeof(struct page);
456 total_mb >>= 20;
457 printk(KERN_INFO "SRAT: This will cost you %Lu MB of "
458 "pre-allocated memory.\n", (unsigned long long)total_mb);
459 reserve_bootmem_node(NODE_DATA(nodeid), nodes_add[nodeid].start,
460 nodes_add[nodeid].end - nodes_add[nodeid].start);
461 }
462}
463
306int __node_distance(int a, int b) 464int __node_distance(int a, int b)
307{ 465{
308 int index; 466 int index;
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c
index e616500207e4..a2060e4d5de6 100644
--- a/arch/x86_64/pci/mmconfig.c
+++ b/arch/x86_64/pci/mmconfig.c
@@ -9,11 +9,16 @@
9#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/acpi.h> 10#include <linux/acpi.h>
11#include <linux/bitmap.h> 11#include <linux/bitmap.h>
12#include <asm/e820.h>
13
12#include "pci.h" 14#include "pci.h"
13 15
14#define MMCONFIG_APER_SIZE (256*1024*1024) 16#define MMCONFIG_APER_SIZE (256*1024*1024)
17/* Verify the first 16 busses. We assume that systems with more busses
18 get MCFG right. */
19#define MAX_CHECK_BUS 16
15 20
16static DECLARE_BITMAP(fallback_slots, 32); 21static DECLARE_BITMAP(fallback_slots, 32*MAX_CHECK_BUS);
17 22
18/* Static virtual mapping of the MMCONFIG aperture */ 23/* Static virtual mapping of the MMCONFIG aperture */
19struct mmcfg_virt { 24struct mmcfg_virt {
@@ -55,7 +60,8 @@ static char __iomem *get_virt(unsigned int seg, unsigned bus)
55static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) 60static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
56{ 61{
57 char __iomem *addr; 62 char __iomem *addr;
58 if (seg == 0 && bus == 0 && test_bit(PCI_SLOT(devfn), fallback_slots)) 63 if (seg == 0 && bus < MAX_CHECK_BUS &&
64 test_bit(32*bus + PCI_SLOT(devfn), fallback_slots))
59 return NULL; 65 return NULL;
60 addr = get_virt(seg, bus); 66 addr = get_virt(seg, bus);
61 if (!addr) 67 if (!addr)
@@ -69,8 +75,10 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
69 char __iomem *addr; 75 char __iomem *addr;
70 76
71 /* Why do we have this when nobody checks it. How about a BUG()!? -AK */ 77 /* Why do we have this when nobody checks it. How about a BUG()!? -AK */
72 if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095))) 78 if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) {
79 *value = -1;
73 return -EINVAL; 80 return -EINVAL;
81 }
74 82
75 addr = pci_dev_base(seg, bus, devfn); 83 addr = pci_dev_base(seg, bus, devfn);
76 if (!addr) 84 if (!addr)
@@ -129,21 +137,26 @@ static struct pci_raw_ops pci_mmcfg = {
129 Normally this can be expressed in the MCFG by not listing them 137 Normally this can be expressed in the MCFG by not listing them
130 and assigning suitable _SEGs, but this isn't implemented in some BIOS. 138 and assigning suitable _SEGs, but this isn't implemented in some BIOS.
131 Instead try to discover all devices on bus 0 that are unreachable using MM 139 Instead try to discover all devices on bus 0 that are unreachable using MM
132 and fallback for them. 140 and fallback for them. */
133 We only do this for bus 0/seg 0 */
134static __init void unreachable_devices(void) 141static __init void unreachable_devices(void)
135{ 142{
136 int i; 143 int i, k;
137 for (i = 0; i < 32; i++) { 144 /* Use the max bus number from ACPI here? */
138 u32 val1; 145 for (k = 0; k < MAX_CHECK_BUS; k++) {
139 char __iomem *addr; 146 for (i = 0; i < 32; i++) {
140 147 u32 val1;
141 pci_conf1_read(0, 0, PCI_DEVFN(i,0), 0, 4, &val1); 148 char __iomem *addr;
142 if (val1 == 0xffffffff) 149
143 continue; 150 pci_conf1_read(0, k, PCI_DEVFN(i,0), 0, 4, &val1);
144 addr = pci_dev_base(0, 0, PCI_DEVFN(i, 0)); 151 if (val1 == 0xffffffff)
145 if (addr == NULL|| readl(addr) != val1) { 152 continue;
146 set_bit(i, fallback_slots); 153 addr = pci_dev_base(0, k, PCI_DEVFN(i, 0));
154 if (addr == NULL|| readl(addr) != val1) {
155 set_bit(i + 32*k, fallback_slots);
156 printk(KERN_NOTICE
157 "PCI: No mmconfig possible on device %x:%x\n",
158 k, i);
159 }
147 } 160 }
148 } 161 }
149} 162}
@@ -161,6 +174,14 @@ void __init pci_mmcfg_init(void)
161 (pci_mmcfg_config[0].base_address == 0)) 174 (pci_mmcfg_config[0].base_address == 0))
162 return; 175 return;
163 176
177 if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
178 pci_mmcfg_config[0].base_address + MMCONFIG_APER_SIZE,
179 E820_RESERVED)) {
180 printk(KERN_ERR "PCI: BIOS Bug: MCFG area is not E820-reserved\n");
181 printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
182 return;
183 }
184
164 /* RED-PEN i386 doesn't do _nocache right now */ 185 /* RED-PEN i386 doesn't do _nocache right now */
165 pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); 186 pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);
166 if (pci_mmcfg_virt == NULL) { 187 if (pci_mmcfg_virt == NULL) {
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c
index 152b9370789b..a15b6e3e72c8 100644
--- a/arch/xtensa/kernel/xtensa_ksyms.c
+++ b/arch/xtensa/kernel/xtensa_ksyms.c
@@ -48,7 +48,6 @@ EXPORT_SYMBOL(memchr);
48EXPORT_SYMBOL(strcat); 48EXPORT_SYMBOL(strcat);
49EXPORT_SYMBOL(strchr); 49EXPORT_SYMBOL(strchr);
50EXPORT_SYMBOL(strlen); 50EXPORT_SYMBOL(strlen);
51EXPORT_SYMBOL(strpbrk);
52EXPORT_SYMBOL(strncat); 51EXPORT_SYMBOL(strncat);
53EXPORT_SYMBOL(strnlen); 52EXPORT_SYMBOL(strnlen);
54EXPORT_SYMBOL(strrchr); 53EXPORT_SYMBOL(strrchr);