aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/Kconfig2
-rw-r--r--arch/alpha/mm/init.c2
-rw-r--r--arch/arm/mach-pxa/corgi.c15
-rw-r--r--arch/arm/mm/ioremap.c2
-rw-r--r--arch/arm/plat-omap/usb.c2
-rw-r--r--arch/avr32/Kconfig196
-rw-r--r--arch/avr32/Kconfig.debug19
-rw-r--r--arch/avr32/Makefile84
-rw-r--r--arch/avr32/boards/atstk1000/Makefile2
-rw-r--r--arch/avr32/boards/atstk1000/atstk1002.c37
-rw-r--r--arch/avr32/boards/atstk1000/flash.c95
-rw-r--r--arch/avr32/boards/atstk1000/setup.c59
-rw-r--r--arch/avr32/boards/atstk1000/spi.c27
-rw-r--r--arch/avr32/boot/images/Makefile62
-rw-r--r--arch/avr32/boot/u-boot/Makefile3
-rw-r--r--arch/avr32/boot/u-boot/empty.S1
-rw-r--r--arch/avr32/boot/u-boot/head.S60
-rw-r--r--arch/avr32/configs/atstk1002_defconfig (renamed from arch/mips/configs/ev96100_defconfig)558
-rw-r--r--arch/avr32/kernel/Makefile18
-rw-r--r--arch/avr32/kernel/asm-offsets.c25
-rw-r--r--arch/avr32/kernel/avr32_ksyms.c55
-rw-r--r--arch/avr32/kernel/cpu.c327
-rw-r--r--arch/avr32/kernel/entry-avr32b.S678
-rw-r--r--arch/avr32/kernel/head.S45
-rw-r--r--arch/avr32/kernel/init_task.c38
-rw-r--r--arch/avr32/kernel/irq.c71
-rw-r--r--arch/avr32/kernel/kprobes.c270
-rw-r--r--arch/avr32/kernel/module.c324
-rw-r--r--arch/avr32/kernel/process.c276
-rw-r--r--arch/avr32/kernel/ptrace.c371
-rw-r--r--arch/avr32/kernel/semaphore.c148
-rw-r--r--arch/avr32/kernel/setup.c335
-rw-r--r--arch/avr32/kernel/signal.c328
-rw-r--r--arch/avr32/kernel/switch_to.S35
-rw-r--r--arch/avr32/kernel/sys_avr32.c51
-rw-r--r--arch/avr32/kernel/syscall-stubs.S102
-rw-r--r--arch/avr32/kernel/syscall_table.S289
-rw-r--r--arch/avr32/kernel/time.c238
-rw-r--r--arch/avr32/kernel/traps.c425
-rw-r--r--arch/avr32/kernel/vmlinux.lds.c139
-rw-r--r--arch/avr32/lib/Makefile10
-rw-r--r--arch/avr32/lib/__avr32_asr64.S31
-rw-r--r--arch/avr32/lib/__avr32_lsl64.S31
-rw-r--r--arch/avr32/lib/__avr32_lsr64.S31
-rw-r--r--arch/avr32/lib/clear_user.S76
-rw-r--r--arch/avr32/lib/copy_user.S119
-rw-r--r--arch/avr32/lib/csum_partial.S47
-rw-r--r--arch/avr32/lib/csum_partial_copy_generic.S99
-rw-r--r--arch/avr32/lib/delay.c55
-rw-r--r--arch/avr32/lib/findbit.S154
-rw-r--r--arch/avr32/lib/io-readsl.S24
-rw-r--r--arch/avr32/lib/io-readsw.S43
-rw-r--r--arch/avr32/lib/io-writesl.S20
-rw-r--r--arch/avr32/lib/io-writesw.S38
-rw-r--r--arch/avr32/lib/libgcc.h33
-rw-r--r--arch/avr32/lib/longlong.h98
-rw-r--r--arch/avr32/lib/memcpy.S62
-rw-r--r--arch/avr32/lib/memset.S72
-rw-r--r--arch/avr32/lib/strncpy_from_user.S60
-rw-r--r--arch/avr32/lib/strnlen_user.S67
-rw-r--r--arch/avr32/mach-at32ap/Makefile2
-rw-r--r--arch/avr32/mach-at32ap/at32ap.c90
-rw-r--r--arch/avr32/mach-at32ap/at32ap7000.c876
-rw-r--r--arch/avr32/mach-at32ap/clock.c148
-rw-r--r--arch/avr32/mach-at32ap/clock.h30
-rw-r--r--arch/avr32/mach-at32ap/extint.c171
-rw-r--r--arch/avr32/mach-at32ap/hsmc.c164
-rw-r--r--arch/avr32/mach-at32ap/hsmc.h127
-rw-r--r--arch/avr32/mach-at32ap/intc.c133
-rw-r--r--arch/avr32/mach-at32ap/intc.h327
-rw-r--r--arch/avr32/mach-at32ap/pio.c118
-rw-r--r--arch/avr32/mach-at32ap/pio.h178
-rw-r--r--arch/avr32/mach-at32ap/sm.c289
-rw-r--r--arch/avr32/mach-at32ap/sm.h240
-rw-r--r--arch/avr32/mm/Makefile6
-rw-r--r--arch/avr32/mm/cache.c150
-rw-r--r--arch/avr32/mm/clear_page.S25
-rw-r--r--arch/avr32/mm/copy_page.S28
-rw-r--r--arch/avr32/mm/dma-coherent.c139
-rw-r--r--arch/avr32/mm/fault.c315
-rw-r--r--arch/avr32/mm/init.c480
-rw-r--r--arch/avr32/mm/ioremap.c197
-rw-r--r--arch/avr32/mm/tlb.c380
-rw-r--r--arch/frv/Kconfig12
-rw-r--r--arch/frv/kernel/Makefile5
-rw-r--r--arch/frv/kernel/irq-mb93091.c157
-rw-r--r--arch/frv/kernel/irq-mb93093.c115
-rw-r--r--arch/frv/kernel/irq-mb93493.c160
-rw-r--r--arch/frv/kernel/irq-routing.c291
-rw-r--r--arch/frv/kernel/irq.c741
-rw-r--r--arch/frv/kernel/setup.c1
-rw-r--r--arch/frv/kernel/time.c1
-rw-r--r--arch/frv/mb93090-mb00/pci-irq.c1
-rw-r--r--arch/frv/mm/init.c2
-rw-r--r--arch/h8300/mm/init.c2
-rw-r--r--arch/i386/Kconfig35
-rw-r--r--arch/i386/Makefile8
-rw-r--r--arch/i386/boot/edd.S97
-rw-r--r--arch/i386/boot/setup.S4
-rw-r--r--arch/i386/defconfig1063
-rw-r--r--arch/i386/kernel/Makefile3
-rw-r--r--arch/i386/kernel/acpi/Makefile2
-rw-r--r--arch/i386/kernel/acpi/boot.c181
-rw-r--r--arch/i386/kernel/acpi/earlyquirk.c6
-rw-r--r--arch/i386/kernel/apic.c31
-rw-r--r--arch/i386/kernel/apm.c26
-rw-r--r--arch/i386/kernel/cpu/amd.c7
-rw-r--r--arch/i386/kernel/cpu/centaur.c24
-rw-r--r--arch/i386/kernel/cpu/common.c8
-rw-r--r--arch/i386/kernel/cpu/cpu.h2
-rw-r--r--arch/i386/kernel/cpu/cyrix.c42
-rw-r--r--arch/i386/kernel/cpu/intel.c3
-rw-r--r--arch/i386/kernel/cpu/mcheck/Makefile2
-rw-r--r--arch/i386/kernel/cpu/mcheck/p4.c26
-rw-r--r--arch/i386/kernel/cpu/mcheck/therm_throt.c180
-rw-r--r--arch/i386/kernel/cpu/mtrr/generic.c4
-rw-r--r--arch/i386/kernel/cpu/nexgen.c9
-rw-r--r--arch/i386/kernel/cpu/proc.c4
-rw-r--r--arch/i386/kernel/cpu/rise.c4
-rw-r--r--arch/i386/kernel/cpu/transmeta.c7
-rw-r--r--arch/i386/kernel/cpu/umc.c7
-rw-r--r--arch/i386/kernel/crash.c22
-rw-r--r--arch/i386/kernel/efi_stub.S1
-rw-r--r--arch/i386/kernel/entry.S110
-rw-r--r--arch/i386/kernel/head.S67
-rw-r--r--arch/i386/kernel/i8259.c6
-rw-r--r--arch/i386/kernel/io_apic.c125
-rw-r--r--arch/i386/kernel/machine_kexec.c140
-rw-r--r--arch/i386/kernel/mca.c8
-rw-r--r--arch/i386/kernel/microcode.c774
-rw-r--r--arch/i386/kernel/mpparse.c70
-rw-r--r--arch/i386/kernel/nmi.c940
-rw-r--r--arch/i386/kernel/process.c14
-rw-r--r--arch/i386/kernel/ptrace.c10
-rw-r--r--arch/i386/kernel/reboot.c12
-rw-r--r--arch/i386/kernel/relocate_kernel.S162
-rw-r--r--arch/i386/kernel/semaphore.c134
-rw-r--r--arch/i386/kernel/setup.c408
-rw-r--r--arch/i386/kernel/smp.c66
-rw-r--r--arch/i386/kernel/smpboot.c25
-rw-r--r--arch/i386/kernel/srat.c102
-rw-r--r--arch/i386/kernel/stacktrace.c98
-rw-r--r--arch/i386/kernel/syscall_table.S1
-rw-r--r--arch/i386/kernel/time.c73
-rw-r--r--arch/i386/kernel/time_hpet.c37
-rw-r--r--arch/i386/kernel/topology.c21
-rw-r--r--arch/i386/kernel/traps.c242
-rw-r--r--arch/i386/kernel/tsc.c2
-rw-r--r--arch/i386/kernel/vmlinux.lds.S12
-rw-r--r--arch/i386/lib/Makefile2
-rw-r--r--arch/i386/lib/semaphore.S217
-rw-r--r--arch/i386/mach-generic/bigsmp.c1
-rw-r--r--arch/i386/mach-generic/es7000.c1
-rw-r--r--arch/i386/mach-generic/probe.c60
-rw-r--r--arch/i386/mach-generic/summit.c1
-rw-r--r--arch/i386/mach-voyager/voyager_thread.c1
-rw-r--r--arch/i386/mm/boot_ioremap.c7
-rw-r--r--arch/i386/mm/discontig.c105
-rw-r--r--arch/i386/mm/extable.c2
-rw-r--r--arch/i386/mm/fault.c25
-rw-r--r--arch/i386/mm/highmem.c2
-rw-r--r--arch/i386/mm/init.c82
-rw-r--r--arch/i386/mm/pgtable.c30
-rw-r--r--arch/i386/oprofile/nmi_int.c88
-rw-r--r--arch/i386/oprofile/nmi_timer_int.c35
-rw-r--r--arch/i386/oprofile/op_model_athlon.c54
-rw-r--r--arch/i386/oprofile/op_model_p4.c152
-rw-r--r--arch/i386/oprofile/op_model_ppro.c65
-rw-r--r--arch/i386/oprofile/op_x86_model.h1
-rw-r--r--arch/i386/pci/Makefile2
-rw-r--r--arch/i386/pci/common.c4
-rw-r--r--arch/i386/pci/direct.c25
-rw-r--r--arch/i386/pci/early.c52
-rw-r--r--arch/i386/pci/init.c9
-rw-r--r--arch/i386/pci/mmconfig.c41
-rw-r--r--arch/i386/pci/pci.h7
-rw-r--r--arch/i386/power/swsusp.S2
-rw-r--r--arch/ia64/Kconfig20
-rw-r--r--arch/ia64/ia32/sys_ia32.c2
-rw-r--r--arch/ia64/kernel/Makefile5
-rw-r--r--arch/ia64/kernel/acpi.c13
-rw-r--r--arch/ia64/kernel/entry.S4
-rw-r--r--arch/ia64/kernel/esi.c205
-rw-r--r--arch/ia64/kernel/esi_stub.S96
-rw-r--r--arch/ia64/kernel/ia64_ksyms.c4
-rw-r--r--arch/ia64/kernel/kprobes.c61
-rw-r--r--arch/ia64/kernel/mca.c234
-rw-r--r--arch/ia64/kernel/mca_asm.S9
-rw-r--r--arch/ia64/kernel/mca_drv.c54
-rw-r--r--arch/ia64/kernel/mca_drv.h4
-rw-r--r--arch/ia64/kernel/numa.c34
-rw-r--r--arch/ia64/kernel/perfmon.c114
-rw-r--r--arch/ia64/kernel/salinfo.c4
-rw-r--r--arch/ia64/kernel/setup.c41
-rw-r--r--arch/ia64/kernel/smpboot.c24
-rw-r--r--arch/ia64/kernel/topology.c4
-rw-r--r--arch/ia64/kernel/uncached.c2
-rw-r--r--arch/ia64/kernel/vmlinux.lds.S8
-rw-r--r--arch/ia64/mm/contig.c84
-rw-r--r--arch/ia64/mm/discontig.c72
-rw-r--r--arch/ia64/mm/init.c12
-rw-r--r--arch/ia64/pci/pci.c3
-rw-r--r--arch/ia64/sn/kernel/bte.c3
-rw-r--r--arch/ia64/sn/kernel/sn2/sn_hwperf.c3
-rw-r--r--arch/m32r/mm/init.c2
-rw-r--r--arch/m68knommu/mm/init.c2
-rw-r--r--arch/mips/Kconfig46
-rw-r--r--arch/mips/Makefile8
-rw-r--r--arch/mips/au1000/common/dbdma.c10
-rw-r--r--arch/mips/au1000/db1x00/Makefile1
-rw-r--r--arch/mips/au1000/db1x00/mirage_ts.c260
-rw-r--r--arch/mips/basler/excite/excite_device.c16
-rw-r--r--arch/mips/basler/excite/excite_fpga.h80
-rw-r--r--arch/mips/configs/atlas_defconfig3
-rw-r--r--arch/mips/configs/bigsur_defconfig1
-rw-r--r--arch/mips/configs/capcella_defconfig1
-rw-r--r--arch/mips/configs/cobalt_defconfig3
-rw-r--r--arch/mips/configs/db1000_defconfig1
-rw-r--r--arch/mips/configs/db1100_defconfig1
-rw-r--r--arch/mips/configs/db1200_defconfig1
-rw-r--r--arch/mips/configs/db1500_defconfig1
-rw-r--r--arch/mips/configs/db1550_defconfig1
-rw-r--r--arch/mips/configs/ddb5477_defconfig1
-rw-r--r--arch/mips/configs/decstation_defconfig1
-rw-r--r--arch/mips/configs/e55_defconfig11
-rw-r--r--arch/mips/configs/emma2rh_defconfig1
-rw-r--r--arch/mips/configs/ev64120_defconfig1
-rw-r--r--arch/mips/configs/excite_defconfig1
-rw-r--r--arch/mips/configs/ip22_defconfig3
-rw-r--r--arch/mips/configs/ip27_defconfig3
-rw-r--r--arch/mips/configs/ip32_defconfig1
-rw-r--r--arch/mips/configs/it8172_defconfig1
-rw-r--r--arch/mips/configs/ivr_defconfig1
-rw-r--r--arch/mips/configs/jaguar-atx_defconfig3
-rw-r--r--arch/mips/configs/jmr3927_defconfig1
-rw-r--r--arch/mips/configs/lasat200_defconfig3
-rw-r--r--arch/mips/configs/malta_defconfig3
-rw-r--r--arch/mips/configs/mipssim_defconfig1
-rw-r--r--arch/mips/configs/mpc30x_defconfig13
-rw-r--r--arch/mips/configs/ocelot_3_defconfig1
-rw-r--r--arch/mips/configs/ocelot_c_defconfig3
-rw-r--r--arch/mips/configs/ocelot_defconfig3
-rw-r--r--arch/mips/configs/ocelot_g_defconfig3
-rw-r--r--arch/mips/configs/pb1100_defconfig1
-rw-r--r--arch/mips/configs/pb1500_defconfig1
-rw-r--r--arch/mips/configs/pb1550_defconfig1
-rw-r--r--arch/mips/configs/pnx8550-jbs_defconfig1
-rw-r--r--arch/mips/configs/pnx8550-v2pci_defconfig1
-rw-r--r--arch/mips/configs/qemu_defconfig3
-rw-r--r--arch/mips/configs/rbhma4500_defconfig1
-rw-r--r--arch/mips/configs/rm200_defconfig3
-rw-r--r--arch/mips/configs/sb1250-swarm_defconfig1
-rw-r--r--arch/mips/configs/sead_defconfig1
-rw-r--r--arch/mips/configs/tb0226_defconfig1
-rw-r--r--arch/mips/configs/tb0229_defconfig1
-rw-r--r--arch/mips/configs/tb0287_defconfig1
-rw-r--r--arch/mips/configs/workpad_defconfig11
-rw-r--r--arch/mips/configs/wrppmc_defconfig1
-rw-r--r--arch/mips/configs/yosemite_defconfig1
-rw-r--r--arch/mips/defconfig5
-rw-r--r--arch/mips/galileo-boards/ev96100/Makefile9
-rw-r--r--arch/mips/galileo-boards/ev96100/init.c173
-rw-r--r--arch/mips/galileo-boards/ev96100/irq.c77
-rw-r--r--arch/mips/galileo-boards/ev96100/puts.c138
-rw-r--r--arch/mips/galileo-boards/ev96100/reset.c70
-rw-r--r--arch/mips/galileo-boards/ev96100/setup.c159
-rw-r--r--arch/mips/galileo-boards/ev96100/time.c88
-rw-r--r--arch/mips/kernel/cpu-probe.c62
-rw-r--r--arch/mips/kernel/irixsig.c63
-rw-r--r--arch/mips/kernel/linux32.c10
-rw-r--r--arch/mips/kernel/process.c257
-rw-r--r--arch/mips/kernel/scall32-o32.S2
-rw-r--r--arch/mips/kernel/scall64-64.S2
-rw-r--r--arch/mips/kernel/scall64-n32.S6
-rw-r--r--arch/mips/kernel/scall64-o32.S4
-rw-r--r--arch/mips/kernel/setup.c439
-rw-r--r--arch/mips/kernel/signal.c8
-rw-r--r--arch/mips/kernel/signal32.c7
-rw-r--r--arch/mips/kernel/smp-mt.c2
-rw-r--r--arch/mips/kernel/smtc-asm.S2
-rw-r--r--arch/mips/kernel/syscall.c4
-rw-r--r--arch/mips/kernel/traps.c146
-rw-r--r--arch/mips/kernel/vpe.c6
-rw-r--r--arch/mips/mips-boards/atlas/atlas_int.c105
-rw-r--r--arch/mips/mips-boards/atlas/atlas_setup.c2
-rw-r--r--arch/mips/mips-boards/generic/time.c64
-rw-r--r--arch/mips/mm/c-r3k.c2
-rw-r--r--arch/mips/mm/c-r4k.c28
-rw-r--r--arch/mips/mm/c-sb1.c58
-rw-r--r--arch/mips/mm/c-tx39.c4
-rw-r--r--arch/mips/mm/cache.c18
-rw-r--r--arch/mips/mm/fault.c2
-rw-r--r--arch/mips/mm/init.c4
-rw-r--r--arch/mips/mm/tlb-r4k.c21
-rw-r--r--arch/mips/pci/Makefile4
-rw-r--r--arch/mips/pci/fixup-atlas.c20
-rw-r--r--arch/mips/pci/fixup-ev96100.c48
-rw-r--r--arch/mips/pci/ops-au1000.c2
-rw-r--r--arch/mips/pci/ops-gt96100.c169
-rw-r--r--arch/mips/pci/pci-ev96100.c63
-rw-r--r--arch/mips/pci/pci-ip27.c2
-rw-r--r--arch/mips/sgi-ip27/ip27-memory.c3
-rw-r--r--arch/mips/sibyte/bcm1480/irq.c19
-rw-r--r--arch/mips/sibyte/sb1250/irq.c17
-rw-r--r--arch/parisc/mm/init.c4
-rw-r--r--arch/powerpc/Kconfig7
-rw-r--r--arch/powerpc/kernel/swsusp_32.S4
-rw-r--r--arch/powerpc/kernel/sys_ppc32.c2
-rw-r--r--arch/powerpc/mm/mem.c51
-rw-r--r--arch/powerpc/mm/numa.c159
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c3
-rw-r--r--arch/powerpc/platforms/pseries/hvCall_inst.c2
-rw-r--r--arch/powerpc/sysdev/mpic.c2
-rw-r--r--arch/ppc/Kconfig3
-rw-r--r--arch/ppc/mm/init.c23
-rw-r--r--arch/s390/appldata/appldata_mem.c3
-rw-r--r--arch/s390/hypfs/inode.c7
-rw-r--r--arch/s390/kernel/compat_linux.c2
-rw-r--r--arch/s390/kernel/debug.c2
-rw-r--r--arch/s390/kernel/stacktrace.c17
-rw-r--r--arch/s390/mm/cmm.c205
-rw-r--r--arch/sh/Kconfig173
-rw-r--r--arch/sh/Kconfig.debug36
-rw-r--r--arch/sh/Makefile40
-rw-r--r--arch/sh/boards/adx/Makefile6
-rw-r--r--arch/sh/boards/adx/irq.c31
-rw-r--r--arch/sh/boards/adx/setup.c56
-rw-r--r--arch/sh/boards/bigsur/irq.c47
-rw-r--r--arch/sh/boards/bigsur/setup.c47
-rw-r--r--arch/sh/boards/cat68701/Makefile6
-rw-r--r--arch/sh/boards/cat68701/irq.c28
-rw-r--r--arch/sh/boards/cat68701/setup.c85
-rw-r--r--arch/sh/boards/cqreek/Makefile6
-rw-r--r--arch/sh/boards/cqreek/irq.c128
-rw-r--r--arch/sh/boards/cqreek/setup.c100
-rw-r--r--arch/sh/boards/dmida/Makefile7
-rw-r--r--arch/sh/boards/dmida/mach.c59
-rw-r--r--arch/sh/boards/dreamcast/irq.c15
-rw-r--r--arch/sh/boards/dreamcast/rtc.c22
-rw-r--r--arch/sh/boards/dreamcast/setup.c40
-rw-r--r--arch/sh/boards/ec3104/setup.c49
-rw-r--r--arch/sh/boards/harp/Makefile8
-rw-r--r--arch/sh/boards/harp/irq.c147
-rw-r--r--arch/sh/boards/harp/led.c51
-rw-r--r--arch/sh/boards/harp/mach.c62
-rw-r--r--arch/sh/boards/harp/pcidma.c42
-rw-r--r--arch/sh/boards/harp/setup.c90
-rw-r--r--arch/sh/boards/hp6xx/Makefile5
-rw-r--r--arch/sh/boards/hp6xx/hp6xx_apm.c123
-rw-r--r--arch/sh/boards/hp6xx/pm.c88
-rw-r--r--arch/sh/boards/hp6xx/pm_wakeup.S58
-rw-r--r--arch/sh/boards/hp6xx/setup.c62
-rw-r--r--arch/sh/boards/landisk/Makefile5
-rw-r--r--arch/sh/boards/landisk/io.c250
-rw-r--r--arch/sh/boards/landisk/irq.c99
-rw-r--r--arch/sh/boards/landisk/landisk_pwb.c348
-rw-r--r--arch/sh/boards/landisk/rtc.c93
-rw-r--r--arch/sh/boards/landisk/setup.c177
-rw-r--r--arch/sh/boards/mpc1211/rtc.c4
-rw-r--r--arch/sh/boards/mpc1211/setup.c71
-rw-r--r--arch/sh/boards/overdrive/Makefile8
-rw-r--r--arch/sh/boards/overdrive/fpga.c133
-rw-r--r--arch/sh/boards/overdrive/galileo.c587
-rw-r--r--arch/sh/boards/overdrive/io.c172
-rw-r--r--arch/sh/boards/overdrive/irq.c191
-rw-r--r--arch/sh/boards/overdrive/led.c58
-rw-r--r--arch/sh/boards/overdrive/mach.c62
-rw-r--r--arch/sh/boards/overdrive/pcidma.c46
-rw-r--r--arch/sh/boards/overdrive/setup.c36
-rw-r--r--arch/sh/boards/renesas/edosk7705/Makefile4
-rw-r--r--arch/sh/boards/renesas/edosk7705/setup.c29
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/Kconfig12
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/Makefile6
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/io.c252
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/irq.c6
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/led.c26
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/mach.c54
-rw-r--r--arch/sh/boards/renesas/hs7751rvoip/setup.c94
-rw-r--r--arch/sh/boards/renesas/r7780rp/Kconfig14
-rw-r--r--arch/sh/boards/renesas/r7780rp/Makefile6
-rw-r--r--arch/sh/boards/renesas/r7780rp/io.c301
-rw-r--r--arch/sh/boards/renesas/r7780rp/irq.c117
-rw-r--r--arch/sh/boards/renesas/r7780rp/led.c45
-rw-r--r--arch/sh/boards/renesas/r7780rp/setup.c163
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/Kconfig12
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/Makefile8
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/io.c191
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/irq.c6
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/led.c11
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/mach.c69
-rw-r--r--arch/sh/boards/renesas/rts7751r2d/setup.c139
-rw-r--r--arch/sh/boards/renesas/sh7710voipgw/Makefile1
-rw-r--r--arch/sh/boards/renesas/sh7710voipgw/setup.c109
-rw-r--r--arch/sh/boards/renesas/systemh/io.c163
-rw-r--r--arch/sh/boards/renesas/systemh/irq.c10
-rw-r--r--arch/sh/boards/renesas/systemh/setup.c30
-rw-r--r--arch/sh/boards/saturn/setup.c14
-rw-r--r--arch/sh/boards/se/7300/io.c8
-rw-r--r--arch/sh/boards/se/7300/irq.c2
-rw-r--r--arch/sh/boards/se/7300/led.c18
-rw-r--r--arch/sh/boards/se/7300/setup.c20
-rw-r--r--arch/sh/boards/se/73180/io.c6
-rw-r--r--arch/sh/boards/se/73180/irq.c9
-rw-r--r--arch/sh/boards/se/73180/led.c15
-rw-r--r--arch/sh/boards/se/73180/setup.c22
-rw-r--r--arch/sh/boards/se/7343/Makefile7
-rw-r--r--arch/sh/boards/se/7343/io.c275
-rw-r--r--arch/sh/boards/se/7343/irq.c193
-rw-r--r--arch/sh/boards/se/7343/led.c46
-rw-r--r--arch/sh/boards/se/7343/setup.c84
-rw-r--r--arch/sh/boards/se/770x/Makefile4
-rw-r--r--arch/sh/boards/se/770x/io.c61
-rw-r--r--arch/sh/boards/se/770x/irq.c2
-rw-r--r--arch/sh/boards/se/770x/led.c17
-rw-r--r--arch/sh/boards/se/770x/mach.c67
-rw-r--r--arch/sh/boards/se/770x/setup.c65
-rw-r--r--arch/sh/boards/se/7751/Makefile4
-rw-r--r--arch/sh/boards/se/7751/io.c171
-rw-r--r--arch/sh/boards/se/7751/irq.c2
-rw-r--r--arch/sh/boards/se/7751/led.c18
-rw-r--r--arch/sh/boards/se/7751/mach.c54
-rw-r--r--arch/sh/boards/se/7751/setup.c109
-rw-r--r--arch/sh/boards/sh03/rtc.c9
-rw-r--r--arch/sh/boards/sh03/setup.c49
-rw-r--r--arch/sh/boards/sh2000/Makefile6
-rw-r--r--arch/sh/boards/sh2000/setup.c70
-rw-r--r--arch/sh/boards/shmin/Makefile5
-rw-r--r--arch/sh/boards/shmin/setup.c41
-rw-r--r--arch/sh/boards/snapgear/io.c145
-rw-r--r--arch/sh/boards/snapgear/rtc.c34
-rw-r--r--arch/sh/boards/snapgear/setup.c115
-rw-r--r--arch/sh/boards/superh/microdev/irq.c39
-rw-r--r--arch/sh/boards/superh/microdev/setup.c113
-rw-r--r--arch/sh/boards/titan/Makefile5
-rw-r--r--arch/sh/boards/titan/io.c126
-rw-r--r--arch/sh/boards/titan/setup.c48
-rw-r--r--arch/sh/boards/unknown/setup.c13
-rw-r--r--arch/sh/boot/compressed/Makefile11
-rw-r--r--arch/sh/cchips/Kconfig6
-rw-r--r--arch/sh/cchips/hd6446x/hd64461/io.c20
-rw-r--r--arch/sh/cchips/hd6446x/hd64461/setup.c10
-rw-r--r--arch/sh/cchips/hd6446x/hd64465/setup.c6
-rw-r--r--arch/sh/cchips/voyagergx/irq.c23
-rw-r--r--arch/sh/cchips/voyagergx/setup.c2
-rw-r--r--arch/sh/configs/landisk_defconfig1373
-rw-r--r--arch/sh/configs/r7780rp_defconfig1099
-rw-r--r--arch/sh/configs/se73180_defconfig1
-rw-r--r--arch/sh/configs/se7343_defconfig997
-rw-r--r--arch/sh/configs/sh7710voipgw_defconfig913
-rw-r--r--arch/sh/configs/shmin_defconfig827
-rw-r--r--arch/sh/configs/titan_defconfig1367
-rw-r--r--arch/sh/drivers/dma/Kconfig3
-rw-r--r--arch/sh/drivers/dma/dma-g2.c54
-rw-r--r--arch/sh/drivers/dma/dma-pvr2.c5
-rw-r--r--arch/sh/drivers/dma/dma-sh.c19
-rw-r--r--arch/sh/drivers/pci/Makefile6
-rw-r--r--arch/sh/drivers/pci/fixups-dreamcast.c38
-rw-r--r--arch/sh/drivers/pci/fixups-r7780rp.c45
-rw-r--r--arch/sh/drivers/pci/fixups-rts7751r2d.c24
-rw-r--r--arch/sh/drivers/pci/fixups-sh03.c38
-rw-r--r--arch/sh/drivers/pci/ops-bigsur.c18
-rw-r--r--arch/sh/drivers/pci/ops-landisk.c68
-rw-r--r--arch/sh/drivers/pci/ops-r7780rp.c75
-rw-r--r--arch/sh/drivers/pci/ops-rts7751r2d.c13
-rw-r--r--arch/sh/drivers/pci/ops-sh4.c164
-rw-r--r--arch/sh/drivers/pci/ops-snapgear.c21
-rw-r--r--arch/sh/drivers/pci/ops-titan.c83
-rw-r--r--arch/sh/drivers/pci/pci-auto.c48
-rw-r--r--arch/sh/drivers/pci/pci-sh4.h180
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.c326
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.h174
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c139
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.h94
-rw-r--r--arch/sh/drivers/pci/pci-st40.c19
-rw-r--r--arch/sh/drivers/pci/pci.c105
-rw-r--r--arch/sh/kernel/Makefile5
-rw-r--r--arch/sh/kernel/apm.c539
-rw-r--r--arch/sh/kernel/cf-enabler.c12
-rw-r--r--arch/sh/kernel/cpu/Makefile1
-rw-r--r--arch/sh/kernel/cpu/clock.c19
-rw-r--r--arch/sh/kernel/cpu/init.c21
-rw-r--r--arch/sh/kernel/cpu/irq/Makefile5
-rw-r--r--arch/sh/kernel/cpu/irq/intc2.c6
-rw-r--r--arch/sh/kernel/cpu/irq/ipr.c14
-rw-r--r--arch/sh/kernel/cpu/irq/maskreg.c (renamed from arch/sh/boards/adx/irq_maskreg.c)61
-rw-r--r--arch/sh/kernel/cpu/irq/pint.c8
-rw-r--r--arch/sh/kernel/cpu/rtc.c128
-rw-r--r--arch/sh/kernel/cpu/sh3/Makefile13
-rw-r--r--arch/sh/kernel/cpu/sh3/clock-sh7706.c84
-rw-r--r--arch/sh/kernel/cpu/sh3/ex.S54
-rw-r--r--arch/sh/kernel/cpu/sh3/probe.c6
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7300.c43
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7705.c48
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7708.c43
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7709.c53
-rw-r--r--arch/sh/kernel/cpu/sh3/setup-sh7710.c43
-rw-r--r--arch/sh/kernel/cpu/sh4/Makefile10
-rw-r--r--arch/sh/kernel/cpu/sh4/ex.S176
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c138
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh4-202.c43
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh73180.c43
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7343.c43
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7750.c48
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7760.c53
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7770.c53
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7780.c79
-rw-r--r--arch/sh/kernel/cpu/sh4/sq.c543
-rw-r--r--arch/sh/kernel/early_printk.c106
-rw-r--r--arch/sh/kernel/entry.S333
-rw-r--r--arch/sh/kernel/head.S43
-rw-r--r--arch/sh/kernel/io.c67
-rw-r--r--arch/sh/kernel/irq.c168
-rw-r--r--arch/sh/kernel/kgdb_stub.c33
-rw-r--r--arch/sh/kernel/machine_kexec.c6
-rw-r--r--arch/sh/kernel/pm.c88
-rw-r--r--arch/sh/kernel/process.c28
-rw-r--r--arch/sh/kernel/ptrace.c1
-rw-r--r--arch/sh/kernel/semaphore.c2
-rw-r--r--arch/sh/kernel/setup.c117
-rw-r--r--arch/sh/kernel/sh_ksyms.c32
-rw-r--r--arch/sh/kernel/signal.c158
-rw-r--r--arch/sh/kernel/sys_sh.c56
-rw-r--r--arch/sh/kernel/syscalls.S353
-rw-r--r--arch/sh/kernel/time.c68
-rw-r--r--arch/sh/kernel/timers/timer-tmu.c24
-rw-r--r--arch/sh/kernel/traps.c184
-rw-r--r--arch/sh/kernel/vmlinux.lds.S17
-rw-r--r--arch/sh/kernel/vsyscall/Makefile36
-rw-r--r--arch/sh/kernel/vsyscall/vsyscall-note.S25
-rw-r--r--arch/sh/kernel/vsyscall/vsyscall-sigreturn.S39
-rw-r--r--arch/sh/kernel/vsyscall/vsyscall-syscall.S10
-rw-r--r--arch/sh/kernel/vsyscall/vsyscall-trapa.S42
-rw-r--r--arch/sh/kernel/vsyscall/vsyscall.c150
-rw-r--r--arch/sh/kernel/vsyscall/vsyscall.lds.S74
-rw-r--r--arch/sh/lib/checksum.S3
-rw-r--r--arch/sh/lib/memcpy-sh4.S4
-rw-r--r--arch/sh/lib/memset.S1
-rw-r--r--arch/sh/math-emu/Makefile1
-rw-r--r--arch/sh/math-emu/math.c624
-rw-r--r--arch/sh/math-emu/sfp-util.h72
-rw-r--r--arch/sh/mm/Kconfig78
-rw-r--r--arch/sh/mm/Makefile16
-rw-r--r--arch/sh/mm/cache-debugfs.c147
-rw-r--r--arch/sh/mm/cache-sh4.c685
-rw-r--r--arch/sh/mm/cache-sh7705.c19
-rw-r--r--arch/sh/mm/clear_page.S99
-rw-r--r--arch/sh/mm/consistent.c2
-rw-r--r--arch/sh/mm/fault.c207
-rw-r--r--arch/sh/mm/hugetlbpage.c52
-rw-r--r--arch/sh/mm/init.c32
-rw-r--r--arch/sh/mm/ioremap.c17
-rw-r--r--arch/sh/mm/pg-nommu.c17
-rw-r--r--arch/sh/mm/pg-sh4.c24
-rw-r--r--arch/sh/mm/pmb.c400
-rw-r--r--arch/sh/mm/tlb-flush.c134
-rw-r--r--arch/sh/mm/tlb-sh4.c8
-rw-r--r--arch/sh/oprofile/Makefile4
-rw-r--r--arch/sh/tools/mach-types10
-rw-r--r--arch/sh64/mm/init.c2
-rw-r--r--arch/sparc/mm/srmmu.c2
-rw-r--r--arch/sparc/mm/sun4c.c2
-rw-r--r--arch/sparc64/defconfig38
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c2
-rw-r--r--arch/sparc64/mm/init.c3
-rw-r--r--arch/sparc64/solaris/misc.c20
-rw-r--r--arch/sparc64/solaris/socksys.c6
-rw-r--r--arch/um/Makefile-x86_647
-rw-r--r--arch/um/drivers/chan_kern.c18
-rw-r--r--arch/um/drivers/daemon.h2
-rw-r--r--arch/um/drivers/daemon_kern.c2
-rw-r--r--arch/um/drivers/daemon_user.c2
-rw-r--r--arch/um/drivers/fd.c4
-rw-r--r--arch/um/drivers/hostaudio_kern.c4
-rw-r--r--arch/um/drivers/line.c6
-rw-r--r--arch/um/drivers/mcast.h2
-rw-r--r--arch/um/drivers/mcast_kern.c2
-rw-r--r--arch/um/drivers/mcast_user.c2
-rw-r--r--arch/um/drivers/mconsole_kern.c2
-rw-r--r--arch/um/drivers/mconsole_user.c7
-rw-r--r--arch/um/drivers/mmapper_kern.c4
-rw-r--r--arch/um/drivers/net_kern.c39
-rw-r--r--arch/um/drivers/null.c4
-rw-r--r--arch/um/drivers/pcap_kern.c4
-rw-r--r--arch/um/drivers/pcap_user.c2
-rw-r--r--arch/um/drivers/port_user.c4
-rw-r--r--arch/um/drivers/pty.c6
-rw-r--r--arch/um/drivers/random.c2
-rw-r--r--arch/um/drivers/slip.h2
-rw-r--r--arch/um/drivers/slip_kern.c2
-rw-r--r--arch/um/drivers/slip_user.c2
-rw-r--r--arch/um/drivers/slirp.h2
-rw-r--r--arch/um/drivers/slirp_kern.c2
-rw-r--r--arch/um/drivers/slirp_user.c2
-rw-r--r--arch/um/drivers/ssl.c4
-rw-r--r--arch/um/drivers/stdio_console.c2
-rw-r--r--arch/um/drivers/tty.c4
-rw-r--r--arch/um/drivers/xterm.c4
-rw-r--r--arch/um/include/chan_kern.h6
-rw-r--r--arch/um/include/chan_user.h6
-rw-r--r--arch/um/include/kern_util.h3
-rw-r--r--arch/um/include/line.h4
-rw-r--r--arch/um/include/longjmp.h5
-rw-r--r--arch/um/include/net_kern.h4
-rw-r--r--arch/um/include/net_user.h1
-rw-r--r--arch/um/include/os.h18
-rw-r--r--arch/um/include/registers.h3
-rw-r--r--arch/um/include/skas/skas.h3
-rw-r--r--arch/um/include/sysdep-i386/archsetjmp.h22
-rw-r--r--arch/um/include/sysdep-i386/signal.h27
-rw-r--r--arch/um/include/sysdep-x86_64/archsetjmp.h24
-rw-r--r--arch/um/include/sysdep-x86_64/ptrace.h43
-rw-r--r--arch/um/include/sysdep-x86_64/sc.h2
-rw-r--r--arch/um/include/sysdep-x86_64/signal.h29
-rw-r--r--arch/um/kernel/Makefile2
-rw-r--r--arch/um/kernel/exec.c4
-rw-r--r--arch/um/kernel/gmon_syms.c13
-rw-r--r--arch/um/kernel/irq.c34
-rw-r--r--arch/um/kernel/ksyms.c3
-rw-r--r--arch/um/kernel/mem.c10
-rw-r--r--arch/um/kernel/process.c (renamed from arch/um/kernel/process_kern.c)36
-rw-r--r--arch/um/kernel/reboot.c13
-rw-r--r--arch/um/kernel/skas/Makefile3
-rw-r--r--arch/um/kernel/skas/exec.c30
-rw-r--r--arch/um/kernel/skas/exec_kern.c41
-rw-r--r--arch/um/kernel/skas/mmu.c2
-rw-r--r--arch/um/kernel/skas/process.c217
-rw-r--r--arch/um/kernel/skas/process_kern.c533
-rw-r--r--arch/um/kernel/time.c14
-rw-r--r--arch/um/kernel/tlb.c370
-rw-r--r--arch/um/kernel/trap.c28
-rw-r--r--arch/um/kernel/um_arch.c2
-rw-r--r--arch/um/os-Linux/Makefile8
-rw-r--r--arch/um/os-Linux/drivers/etap.h2
-rw-r--r--arch/um/os-Linux/drivers/ethertap_kern.c2
-rw-r--r--arch/um/os-Linux/drivers/ethertap_user.c2
-rw-r--r--arch/um/os-Linux/drivers/tuntap.h2
-rw-r--r--arch/um/os-Linux/drivers/tuntap_kern.c2
-rw-r--r--arch/um/os-Linux/drivers/tuntap_user.c2
-rw-r--r--arch/um/os-Linux/helper.c22
-rw-r--r--arch/um/os-Linux/irq.c2
-rw-r--r--arch/um/os-Linux/main.c34
-rw-r--r--arch/um/os-Linux/mem.c6
-rw-r--r--arch/um/os-Linux/process.c13
-rw-r--r--arch/um/os-Linux/sigio.c103
-rw-r--r--arch/um/os-Linux/signal.c38
-rw-r--r--arch/um/os-Linux/skas/process.c92
-rw-r--r--arch/um/os-Linux/start_up.c1
-rw-r--r--arch/um/os-Linux/sys-i386/Makefile2
-rw-r--r--arch/um/os-Linux/sys-i386/registers.c17
-rw-r--r--arch/um/os-Linux/sys-i386/signal.c15
-rw-r--r--arch/um/os-Linux/sys-x86_64/Makefile2
-rw-r--r--arch/um/os-Linux/sys-x86_64/registers.c17
-rw-r--r--arch/um/os-Linux/sys-x86_64/signal.c16
-rw-r--r--arch/um/os-Linux/time.c22
-rw-r--r--arch/um/os-Linux/trap.c1
-rw-r--r--arch/um/os-Linux/uaccess.c3
-rw-r--r--arch/um/os-Linux/util.c5
-rw-r--r--arch/um/sys-i386/Makefile4
-rw-r--r--arch/um/sys-i386/bugs.c9
-rw-r--r--arch/um/sys-i386/ldt.c3
-rw-r--r--arch/um/sys-i386/ptrace_user.c5
-rw-r--r--arch/um/sys-i386/setjmp.S58
-rw-r--r--arch/um/sys-x86_64/Makefile4
-rw-r--r--arch/um/sys-x86_64/setjmp.S54
-rw-r--r--arch/x86_64/Kconfig53
-rw-r--r--arch/x86_64/Makefile10
-rw-r--r--arch/x86_64/boot/compressed/Makefile3
-rw-r--r--arch/x86_64/boot/setup.S4
-rw-r--r--arch/x86_64/defconfig109
-rw-r--r--arch/x86_64/ia32/ia32_aout.c8
-rw-r--r--arch/x86_64/ia32/ia32_signal.c53
-rw-r--r--arch/x86_64/ia32/ia32entry.S9
-rw-r--r--arch/x86_64/ia32/ptrace32.c10
-rw-r--r--arch/x86_64/ia32/sys_ia32.c54
-rw-r--r--arch/x86_64/kernel/Makefile9
-rw-r--r--arch/x86_64/kernel/aperture.c25
-rw-r--r--arch/x86_64/kernel/apic.c229
-rw-r--r--arch/x86_64/kernel/crash.c26
-rw-r--r--arch/x86_64/kernel/e820.c291
-rw-r--r--arch/x86_64/kernel/early-quirks.c122
-rw-r--r--arch/x86_64/kernel/early_printk.c20
-rw-r--r--arch/x86_64/kernel/entry.S63
-rw-r--r--arch/x86_64/kernel/genapic_cluster.c1
-rw-r--r--arch/x86_64/kernel/genapic_flat.c5
-rw-r--r--arch/x86_64/kernel/head.S15
-rw-r--r--arch/x86_64/kernel/head64.c44
-rw-r--r--arch/x86_64/kernel/i8259.c15
-rw-r--r--arch/x86_64/kernel/io_apic.c482
-rw-r--r--arch/x86_64/kernel/ioport.c1
-rw-r--r--arch/x86_64/kernel/irq.c12
-rw-r--r--arch/x86_64/kernel/machine_kexec.c99
-rw-r--r--arch/x86_64/kernel/mce.c29
-rw-r--r--arch/x86_64/kernel/mce_intel.c30
-rw-r--r--arch/x86_64/kernel/mpparse.c238
-rw-r--r--arch/x86_64/kernel/nmi.c840
-rw-r--r--arch/x86_64/kernel/pci-calgary.c142
-rw-r--r--arch/x86_64/kernel/pci-dma.c7
-rw-r--r--arch/x86_64/kernel/pci-gart.c3
-rw-r--r--arch/x86_64/kernel/pci-nommu.c1
-rw-r--r--arch/x86_64/kernel/process.c110
-rw-r--r--arch/x86_64/kernel/ptrace.c29
-rw-r--r--arch/x86_64/kernel/relocate_kernel.S171
-rw-r--r--arch/x86_64/kernel/setup.c249
-rw-r--r--arch/x86_64/kernel/setup64.c45
-rw-r--r--arch/x86_64/kernel/signal.c87
-rw-r--r--arch/x86_64/kernel/smp.c23
-rw-r--r--arch/x86_64/kernel/smpboot.c17
-rw-r--r--arch/x86_64/kernel/stacktrace.c220
-rw-r--r--arch/x86_64/kernel/suspend_asm.S2
-rw-r--r--arch/x86_64/kernel/tce.c12
-rw-r--r--arch/x86_64/kernel/time.c131
-rw-r--r--arch/x86_64/kernel/trampoline.S2
-rw-r--r--arch/x86_64/kernel/traps.c204
-rw-r--r--arch/x86_64/kernel/vmlinux.lds.S25
-rw-r--r--arch/x86_64/kernel/vsmp.c3
-rw-r--r--arch/x86_64/kernel/vsyscall.c98
-rw-r--r--arch/x86_64/kernel/x8664_ksyms.c1
-rw-r--r--arch/x86_64/lib/Makefile2
-rw-r--r--arch/x86_64/lib/clear_page.S47
-rw-r--r--arch/x86_64/lib/copy_page.S53
-rw-r--r--arch/x86_64/lib/copy_user.S153
-rw-r--r--arch/x86_64/lib/csum-copy.S26
-rw-r--r--arch/x86_64/lib/getuser.S32
-rw-r--r--arch/x86_64/lib/iomap_copy.S10
-rw-r--r--arch/x86_64/lib/memcpy.S69
-rw-r--r--arch/x86_64/lib/memset.S79
-rw-r--r--arch/x86_64/lib/putuser.S32
-rw-r--r--arch/x86_64/lib/rwlock.S38
-rw-r--r--arch/x86_64/lib/thunk.S43
-rw-r--r--arch/x86_64/mm/fault.c28
-rw-r--r--arch/x86_64/mm/init.c129
-rw-r--r--arch/x86_64/mm/k8topology.c6
-rw-r--r--arch/x86_64/mm/numa.c32
-rw-r--r--arch/x86_64/mm/pageattr.c24
-rw-r--r--arch/x86_64/mm/srat.c19
-rw-r--r--arch/x86_64/pci/Makefile3
-rw-r--r--arch/x86_64/pci/mmconfig.c44
737 files changed, 38994 insertions, 16687 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 213c7850d5fb..2b36afd8e969 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -381,7 +381,7 @@ config ALPHA_EV56
381 381
382config ALPHA_EV56 382config ALPHA_EV56
383 prompt "EV56 CPU (speed >= 333MHz)?" 383 prompt "EV56 CPU (speed >= 333MHz)?"
384 depends on ALPHA_NORITAKE && ALPHA_PRIMO 384 depends on ALPHA_NORITAKE || ALPHA_PRIMO
385 385
386config ALPHA_EV56 386config ALPHA_EV56
387 prompt "EV56 CPU (speed >= 400MHz)?" 387 prompt "EV56 CPU (speed >= 400MHz)?"
diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
index 917dad1b74c8..550f4907d613 100644
--- a/arch/alpha/mm/init.c
+++ b/arch/alpha/mm/init.c
@@ -270,7 +270,7 @@ callback_init(void * kernel_end)
270void 270void
271paging_init(void) 271paging_init(void)
272{ 272{
273 unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; 273 unsigned long zones_size[MAX_NR_ZONES] = {0, };
274 unsigned long dma_pfn, high_pfn; 274 unsigned long dma_pfn, high_pfn;
275 275
276 dma_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; 276 dma_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index cce26576999e..337c01c4ac37 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -284,21 +284,9 @@ static struct pxaficp_platform_data corgi_ficp_platform_data = {
284/* 284/*
285 * USB Device Controller 285 * USB Device Controller
286 */ 286 */
287static void corgi_udc_command(int cmd)
288{
289 switch(cmd) {
290 case PXA2XX_UDC_CMD_CONNECT:
291 GPSR(CORGI_GPIO_USB_PULLUP) = GPIO_bit(CORGI_GPIO_USB_PULLUP);
292 break;
293 case PXA2XX_UDC_CMD_DISCONNECT:
294 GPCR(CORGI_GPIO_USB_PULLUP) = GPIO_bit(CORGI_GPIO_USB_PULLUP);
295 break;
296 }
297}
298
299static struct pxa2xx_udc_mach_info udc_info __initdata = { 287static struct pxa2xx_udc_mach_info udc_info __initdata = {
300 /* no connect GPIO; corgi can't tell connection status */ 288 /* no connect GPIO; corgi can't tell connection status */
301 .udc_command = corgi_udc_command, 289 .gpio_pullup = CORGI_GPIO_USB_PULLUP,
302}; 290};
303 291
304 292
@@ -350,7 +338,6 @@ static void __init corgi_init(void)
350 corgi_ssp_set_machinfo(&corgi_ssp_machinfo); 338 corgi_ssp_set_machinfo(&corgi_ssp_machinfo);
351 339
352 pxa_gpio_mode(CORGI_GPIO_IR_ON | GPIO_OUT); 340 pxa_gpio_mode(CORGI_GPIO_IR_ON | GPIO_OUT);
353 pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT);
354 pxa_gpio_mode(CORGI_GPIO_HSYNC | GPIO_IN); 341 pxa_gpio_mode(CORGI_GPIO_HSYNC | GPIO_IN);
355 342
356 pxa_set_udc_info(&udc_info); 343 pxa_set_udc_info(&udc_info);
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 88a999df0ab3..591fc3187c7f 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -177,7 +177,7 @@ static void unmap_area_sections(unsigned long virt, unsigned long size)
177 * Free the page table, if there was one. 177 * Free the page table, if there was one.
178 */ 178 */
179 if ((pmd_val(pmd) & PMD_TYPE_MASK) == PMD_TYPE_TABLE) 179 if ((pmd_val(pmd) & PMD_TYPE_MASK) == PMD_TYPE_TABLE)
180 pte_free_kernel(pmd_page_kernel(pmd)); 180 pte_free_kernel(pmd_page_vaddr(pmd));
181 } 181 }
182 182
183 addr += PGDIR_SIZE; 183 addr += PGDIR_SIZE;
diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c
index 9b815327b6a5..7e8096809be2 100644
--- a/arch/arm/plat-omap/usb.c
+++ b/arch/arm/plat-omap/usb.c
@@ -26,7 +26,7 @@
26#include <linux/errno.h> 26#include <linux/errno.h>
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/usb_otg.h> 29#include <linux/usb/otg.h>
30 30
31#include <asm/io.h> 31#include <asm/io.h>
32#include <asm/irq.h> 32#include <asm/irq.h>
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
new file mode 100644
index 000000000000..5f1694eea842
--- /dev/null
+++ b/arch/avr32/Kconfig
@@ -0,0 +1,196 @@
1#
2# For a description of the syntax of this configuration file,
3# see Documentation/kbuild/kconfig-language.txt.
4#
5
6mainmenu "Linux Kernel Configuration"
7
8config AVR32
9 bool
10 default y
11 # With EMBEDDED=n, we get lots of stuff automatically selected
12 # that we usually don't need on AVR32.
13 select EMBEDDED
14 help
15 AVR32 is a high-performance 32-bit RISC microprocessor core,
16 designed for cost-sensitive embedded applications, with particular
17 emphasis on low power consumption and high code density.
18
19 There is an AVR32 Linux project with a web page at
20 http://avr32linux.org/.
21
22config UID16
23 bool
24
25config GENERIC_HARDIRQS
26 bool
27 default y
28
29config HARDIRQS_SW_RESEND
30 bool
31 default y
32
33config GENERIC_IRQ_PROBE
34 bool
35 default y
36
37config RWSEM_GENERIC_SPINLOCK
38 bool
39 default y
40
41config GENERIC_TIME
42 bool
43 default y
44
45config RWSEM_XCHGADD_ALGORITHM
46 bool
47
48config GENERIC_BUST_SPINLOCK
49 bool
50
51config GENERIC_HWEIGHT
52 bool
53 default y
54
55config GENERIC_CALIBRATE_DELAY
56 bool
57 default y
58
59source "init/Kconfig"
60
61menu "System Type and features"
62
63config SUBARCH_AVR32B
64 bool
65config MMU
66 bool
67config PERFORMANCE_COUNTERS
68 bool
69
70config PLATFORM_AT32AP
71 bool
72 select SUBARCH_AVR32B
73 select MMU
74 select PERFORMANCE_COUNTERS
75
76choice
77 prompt "AVR32 CPU type"
78 default CPU_AT32AP7000
79
80config CPU_AT32AP7000
81 bool "AT32AP7000"
82 select PLATFORM_AT32AP
83endchoice
84
85#
86# CPU Daughterboards for ATSTK1000
87config BOARD_ATSTK1002
88 bool
89
90choice
91 prompt "AVR32 board type"
92 default BOARD_ATSTK1000
93
94config BOARD_ATSTK1000
95 bool "ATSTK1000 evaluation board"
96 select BOARD_ATSTK1002 if CPU_AT32AP7000
97endchoice
98
99choice
100 prompt "Boot loader type"
101 default LOADER_U_BOOT
102
103config LOADER_U_BOOT
104 bool "U-Boot (or similar) bootloader"
105endchoice
106
107config LOAD_ADDRESS
108 hex
109 default 0x10000000 if LOADER_U_BOOT=y && CPU_AT32AP7000=y
110
111config ENTRY_ADDRESS
112 hex
113 default 0x90000000 if LOADER_U_BOOT=y && CPU_AT32AP7000=y
114
115config PHYS_OFFSET
116 hex
117 default 0x10000000 if CPU_AT32AP7000=y
118
119source "kernel/Kconfig.preempt"
120
121config HAVE_ARCH_BOOTMEM_NODE
122 bool
123 default n
124
125config ARCH_HAVE_MEMORY_PRESENT
126 bool
127 default n
128
129config NEED_NODE_MEMMAP_SIZE
130 bool
131 default n
132
133config ARCH_FLATMEM_ENABLE
134 bool
135 default y
136
137config ARCH_DISCONTIGMEM_ENABLE
138 bool
139 default n
140
141config ARCH_SPARSEMEM_ENABLE
142 bool
143 default n
144
145source "mm/Kconfig"
146
147config OWNERSHIP_TRACE
148 bool "Ownership trace support"
149 default y
150 help
151 Say Y to generate an Ownership Trace message on every context switch,
152 enabling Nexus-compliant debuggers to keep track of the PID of the
153 currently executing task.
154
155# FPU emulation goes here
156
157source "kernel/Kconfig.hz"
158
159config CMDLINE
160 string "Default kernel command line"
161 default ""
162 help
163 If you don't have a boot loader capable of passing a command line string
164 to the kernel, you may specify one here. As a minimum, you should specify
165 the memory size and the root device (e.g., mem=8M, root=/dev/nfs).
166
167endmenu
168
169menu "Bus options"
170
171config PCI
172 bool
173
174source "drivers/pci/Kconfig"
175
176source "drivers/pcmcia/Kconfig"
177
178endmenu
179
180menu "Executable file formats"
181source "fs/Kconfig.binfmt"
182endmenu
183
184source "net/Kconfig"
185
186source "drivers/Kconfig"
187
188source "fs/Kconfig"
189
190source "arch/avr32/Kconfig.debug"
191
192source "security/Kconfig"
193
194source "crypto/Kconfig"
195
196source "lib/Kconfig"
diff --git a/arch/avr32/Kconfig.debug b/arch/avr32/Kconfig.debug
new file mode 100644
index 000000000000..64ace00fe6cb
--- /dev/null
+++ b/arch/avr32/Kconfig.debug
@@ -0,0 +1,19 @@
1menu "Kernel hacking"
2
3config TRACE_IRQFLAGS_SUPPORT
4 bool
5 default y
6
7source "lib/Kconfig.debug"
8
9config KPROBES
10 bool "Kprobes"
11 depends on DEBUG_KERNEL
12 help
13 Kprobes allows you to trap at almost any kernel address and
14 execute a callback function. register_kprobe() establishes
15 a probepoint and specifies the callback. Kprobes is useful
16 for kernel debugging, non-intrusive instrumentation and testing.
17 If in doubt, say "N".
18
19endmenu
diff --git a/arch/avr32/Makefile b/arch/avr32/Makefile
new file mode 100644
index 000000000000..cefc95a73980
--- /dev/null
+++ b/arch/avr32/Makefile
@@ -0,0 +1,84 @@
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) 2004-2006 Atmel Corporation.
7
8# Default target when executing plain make
9.PHONY: all
10all: uImage vmlinux.elf linux.lst
11
12KBUILD_DEFCONFIG := atstk1002_defconfig
13
14CFLAGS += -pipe -fno-builtin -mno-pic
15AFLAGS += -mrelax -mno-pic
16CFLAGS_MODULE += -mno-relax
17LDFLAGS_vmlinux += --relax
18
19cpuflags-$(CONFIG_CPU_AP7000) += -mcpu=ap7000
20
21CFLAGS += $(cpuflags-y)
22AFLAGS += $(cpuflags-y)
23
24CHECKFLAGS += -D__avr32__
25
26LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
27
28head-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/head.o
29head-y += arch/avr32/kernel/head.o
30core-$(CONFIG_PLATFORM_AT32AP) += arch/avr32/mach-at32ap/
31core-$(CONFIG_BOARD_ATSTK1000) += arch/avr32/boards/atstk1000/
32core-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/
33core-y += arch/avr32/kernel/
34core-y += arch/avr32/mm/
35libs-y += arch/avr32/lib/ #$(LIBGCC)
36
37archincdir-$(CONFIG_PLATFORM_AT32AP) := arch-at32ap
38
39include/asm-avr32/.arch: $(wildcard include/config/platform/*.h) include/config/auto.conf
40 @echo ' SYMLINK include/asm-avr32/arch -> include/asm-avr32/$(archincdir-y)'
41ifneq ($(KBUILD_SRC),)
42 $(Q)mkdir -p include/asm-avr32
43 $(Q)ln -fsn $(srctree)/include/asm-avr32/$(archincdir-y) include/asm-avr32/arch
44else
45 $(Q)ln -fsn $(archincdir-y) include/asm-avr32/arch
46endif
47 @touch $@
48
49archprepare: include/asm-avr32/.arch
50
51BOOT_TARGETS := vmlinux.elf vmlinux.bin uImage uImage.srec
52
53.PHONY: $(BOOT_TARGETS) install
54
55boot := arch/$(ARCH)/boot/images
56
57 KBUILD_IMAGE := $(boot)/uImage
58vmlinux.elf: KBUILD_IMAGE := $(boot)/vmlinux.elf
59vmlinux.cso: KBUILD_IMAGE := $(boot)/vmlinux.cso
60uImage.srec: KBUILD_IMAGE := $(boot)/uImage.srec
61uImage: KBUILD_IMAGE := $(boot)/uImage
62
63quiet_cmd_listing = LST $@
64 cmd_listing = avr32-linux-objdump $(OBJDUMPFLAGS) -lS $< > $@
65quiet_cmd_disasm = DIS $@
66 cmd_disasm = avr32-linux-objdump $(OBJDUMPFLAGS) -d $< > $@
67
68vmlinux.elf vmlinux.bin uImage.srec uImage vmlinux.cso: vmlinux
69 $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
70
71install: vmlinux
72 $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@
73
74linux.s: vmlinux
75 $(call if_changed,disasm)
76
77linux.lst: vmlinux
78 $(call if_changed,listing)
79
80define archhelp
81 @echo '* vmlinux.elf - ELF image with load address 0'
82 @echo ' vmlinux.cso - PathFinder CSO image'
83 @echo ' uImage - Create a bootable image for U-Boot'
84endef
diff --git a/arch/avr32/boards/atstk1000/Makefile b/arch/avr32/boards/atstk1000/Makefile
new file mode 100644
index 000000000000..df9499480530
--- /dev/null
+++ b/arch/avr32/boards/atstk1000/Makefile
@@ -0,0 +1,2 @@
1obj-y += setup.o spi.o flash.o
2obj-$(CONFIG_BOARD_ATSTK1002) += atstk1002.o
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c
new file mode 100644
index 000000000000..49164e9aadd6
--- /dev/null
+++ b/arch/avr32/boards/atstk1000/atstk1002.c
@@ -0,0 +1,37 @@
1/*
2 * ATSTK1002 daughterboard-specific init code
3 *
4 * Copyright (C) 2005-2006 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/init.h>
11
12#include <asm/arch/board.h>
13
14struct eth_platform_data __initdata eth0_data = {
15 .valid = 1,
16 .mii_phy_addr = 0x10,
17 .is_rmii = 0,
18 .hw_addr = { 0x6a, 0x87, 0x71, 0x14, 0xcd, 0xcb },
19};
20
21extern struct lcdc_platform_data atstk1000_fb0_data;
22
23static int __init atstk1002_init(void)
24{
25 at32_add_system_devices();
26
27 at32_add_device_usart(1); /* /dev/ttyS0 */
28 at32_add_device_usart(2); /* /dev/ttyS1 */
29 at32_add_device_usart(3); /* /dev/ttyS2 */
30
31 at32_add_device_eth(0, &eth0_data);
32 at32_add_device_spi(0);
33 at32_add_device_lcdc(0, &atstk1000_fb0_data);
34
35 return 0;
36}
37postcore_initcall(atstk1002_init);
diff --git a/arch/avr32/boards/atstk1000/flash.c b/arch/avr32/boards/atstk1000/flash.c
new file mode 100644
index 000000000000..aac4300cca12
--- /dev/null
+++ b/arch/avr32/boards/atstk1000/flash.c
@@ -0,0 +1,95 @@
1/*
2 * ATSTK1000 board-specific flash initialization
3 *
4 * Copyright (C) 2005-2006 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/init.h>
11#include <linux/platform_device.h>
12#include <linux/mtd/mtd.h>
13#include <linux/mtd/partitions.h>
14#include <linux/mtd/physmap.h>
15
16#include <asm/arch/smc.h>
17
18static struct smc_config flash_config __initdata = {
19 .ncs_read_setup = 0,
20 .nrd_setup = 40,
21 .ncs_write_setup = 0,
22 .nwe_setup = 10,
23
24 .ncs_read_pulse = 80,
25 .nrd_pulse = 40,
26 .ncs_write_pulse = 65,
27 .nwe_pulse = 55,
28
29 .read_cycle = 120,
30 .write_cycle = 120,
31
32 .bus_width = 2,
33 .nrd_controlled = 1,
34 .nwe_controlled = 1,
35 .byte_write = 1,
36};
37
38static struct mtd_partition flash_parts[] = {
39 {
40 .name = "u-boot",
41 .offset = 0x00000000,
42 .size = 0x00020000, /* 128 KiB */
43 .mask_flags = MTD_WRITEABLE,
44 },
45 {
46 .name = "root",
47 .offset = 0x00020000,
48 .size = 0x007d0000,
49 },
50 {
51 .name = "env",
52 .offset = 0x007f0000,
53 .size = 0x00010000,
54 .mask_flags = MTD_WRITEABLE,
55 },
56};
57
58static struct physmap_flash_data flash_data = {
59 .width = 2,
60 .nr_parts = ARRAY_SIZE(flash_parts),
61 .parts = flash_parts,
62};
63
64static struct resource flash_resource = {
65 .start = 0x00000000,
66 .end = 0x007fffff,
67 .flags = IORESOURCE_MEM,
68};
69
70static struct platform_device flash_device = {
71 .name = "physmap-flash",
72 .id = 0,
73 .resource = &flash_resource,
74 .num_resources = 1,
75 .dev = {
76 .platform_data = &flash_data,
77 },
78};
79
80/* This needs to be called after the SMC has been initialized */
81static int __init atstk1000_flash_init(void)
82{
83 int ret;
84
85 ret = smc_set_configuration(0, &flash_config);
86 if (ret < 0) {
87 printk(KERN_ERR "atstk1000: failed to set NOR flash timing\n");
88 return ret;
89 }
90
91 platform_device_register(&flash_device);
92
93 return 0;
94}
95device_initcall(atstk1000_flash_init);
diff --git a/arch/avr32/boards/atstk1000/setup.c b/arch/avr32/boards/atstk1000/setup.c
new file mode 100644
index 000000000000..191ab85de9a3
--- /dev/null
+++ b/arch/avr32/boards/atstk1000/setup.c
@@ -0,0 +1,59 @@
1/*
2 * ATSTK1000 board-specific setup code.
3 *
4 * Copyright (C) 2005-2006 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/bootmem.h>
11#include <linux/init.h>
12#include <linux/types.h>
13#include <linux/linkage.h>
14
15#include <asm/setup.h>
16
17#include <asm/arch/board.h>
18
19/* Initialized by bootloader-specific startup code. */
20struct tag *bootloader_tags __initdata;
21
22struct lcdc_platform_data __initdata atstk1000_fb0_data;
23
24asmlinkage void __init board_early_init(void)
25{
26 extern void sdram_init(void);
27
28#ifdef CONFIG_LOADER_STANDALONE
29 sdram_init();
30#endif
31}
32
33void __init board_setup_fbmem(unsigned long fbmem_start,
34 unsigned long fbmem_size)
35{
36 if (!fbmem_size)
37 return;
38
39 if (!fbmem_start) {
40 void *fbmem;
41
42 fbmem = alloc_bootmem_low_pages(fbmem_size);
43 fbmem_start = __pa(fbmem);
44 } else {
45 pg_data_t *pgdat;
46
47 for_each_online_pgdat(pgdat) {
48 if (fbmem_start >= pgdat->bdata->node_boot_start
49 && fbmem_start <= pgdat->bdata->node_low_pfn)
50 reserve_bootmem_node(pgdat, fbmem_start,
51 fbmem_size);
52 }
53 }
54
55 printk("%luKiB framebuffer memory at address 0x%08lx\n",
56 fbmem_size >> 10, fbmem_start);
57 atstk1000_fb0_data.fbmem_start = fbmem_start;
58 atstk1000_fb0_data.fbmem_size = fbmem_size;
59}
diff --git a/arch/avr32/boards/atstk1000/spi.c b/arch/avr32/boards/atstk1000/spi.c
new file mode 100644
index 000000000000..567726c82c6e
--- /dev/null
+++ b/arch/avr32/boards/atstk1000/spi.c
@@ -0,0 +1,27 @@
1/*
2 * ATSTK1000 SPI devices
3 *
4 * Copyright (C) 2005 Atmel Norway
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/device.h>
11#include <linux/spi/spi.h>
12
13static struct spi_board_info spi_board_info[] __initdata = {
14 {
15 .modalias = "ltv350qv",
16 .max_speed_hz = 16000000,
17 .bus_num = 0,
18 .chip_select = 1,
19 },
20};
21
22static int board_init_spi(void)
23{
24 spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
25 return 0;
26}
27arch_initcall(board_init_spi);
diff --git a/arch/avr32/boot/images/Makefile b/arch/avr32/boot/images/Makefile
new file mode 100644
index 000000000000..ccd74eeecec3
--- /dev/null
+++ b/arch/avr32/boot/images/Makefile
@@ -0,0 +1,62 @@
1#
2# Copyright (C) 2004-2006 Atmel Corporation
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
9MKIMAGE := $(srctree)/scripts/mkuboot.sh
10
11extra-y := vmlinux.bin vmlinux.gz
12
13OBJCOPYFLAGS_vmlinux.bin := -O binary
14$(obj)/vmlinux.bin: vmlinux FORCE
15 $(call if_changed,objcopy)
16
17$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
18 $(call if_changed,gzip)
19
20quiet_cmd_uimage = UIMAGE $@
21 cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A avr32 -O linux -T kernel \
22 -C gzip -a $(CONFIG_LOAD_ADDRESS) -e $(CONFIG_ENTRY_ADDRESS) \
23 -n 'Linux-$(KERNELRELEASE)' -d $< $@
24
25targets += uImage uImage.srec
26$(obj)/uImage: $(obj)/vmlinux.gz
27 $(call if_changed,uimage)
28 @echo ' Image $@ is ready'
29
30OBJCOPYFLAGS_uImage.srec := -I binary -O srec
31$(obj)/uImage.srec: $(obj)/uImage
32 $(call if_changed,objcopy)
33
34OBJCOPYFLAGS_vmlinux.elf := --change-section-lma .text-0x80000000 \
35 --change-section-lma __ex_table-0x80000000 \
36 --change-section-lma .rodata-0x80000000 \
37 --change-section-lma .data-0x80000000 \
38 --change-section-lma .init-0x80000000 \
39 --change-section-lma .bss-0x80000000 \
40 --change-section-lma .initrd-0x80000000 \
41 --change-section-lma __param-0x80000000 \
42 --change-section-lma __ksymtab-0x80000000 \
43 --change-section-lma __ksymtab_gpl-0x80000000 \
44 --change-section-lma __kcrctab-0x80000000 \
45 --change-section-lma __kcrctab_gpl-0x80000000 \
46 --change-section-lma __ksymtab_strings-0x80000000 \
47 --change-section-lma .got-0x80000000 \
48 --set-start 0xa0000000
49$(obj)/vmlinux.elf: vmlinux FORCE
50 $(call if_changed,objcopy)
51
52quiet_cmd_sfdwarf = SFDWARF $@
53 cmd_sfdwarf = sfdwarf $< TO $@ GNUAVR IW $(SFDWARF_FLAGS) > $(obj)/sfdwarf.log
54
55$(obj)/vmlinux.cso: $(obj)/vmlinux.elf FORCE
56 $(call if_changed,sfdwarf)
57
58install: $(BOOTIMAGE)
59 sh $(srctree)/install-kernel.sh $<
60
61# Generated files to be removed upon make clean
62clean-files := vmlinux* uImage uImage.srec
diff --git a/arch/avr32/boot/u-boot/Makefile b/arch/avr32/boot/u-boot/Makefile
new file mode 100644
index 000000000000..125ddc96c275
--- /dev/null
+++ b/arch/avr32/boot/u-boot/Makefile
@@ -0,0 +1,3 @@
1extra-y := head.o
2
3obj-y := empty.o
diff --git a/arch/avr32/boot/u-boot/empty.S b/arch/avr32/boot/u-boot/empty.S
new file mode 100644
index 000000000000..8ac91a5f12f0
--- /dev/null
+++ b/arch/avr32/boot/u-boot/empty.S
@@ -0,0 +1 @@
/* Empty file */
diff --git a/arch/avr32/boot/u-boot/head.S b/arch/avr32/boot/u-boot/head.S
new file mode 100644
index 000000000000..4488fa27fe94
--- /dev/null
+++ b/arch/avr32/boot/u-boot/head.S
@@ -0,0 +1,60 @@
1/*
2 * Startup code for use with the u-boot bootloader.
3 *
4 * Copyright (C) 2004-2006 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <asm/setup.h>
11
12 /*
13 * The kernel is loaded where we want it to be and all caches
14 * have just been flushed. We get two parameters from u-boot:
15 *
16 * r12 contains a magic number (ATAG_MAGIC)
17 * r11 points to a tag table providing information about
18 * the system.
19 */
20 .section .init.text,"ax"
21 .global _start
22_start:
23 /* Check if the boot loader actually provided a tag table */
24 lddpc r0, magic_number
25 cp.w r12, r0
26 brne no_tag_table
27
28 /* Initialize .bss */
29 lddpc r2, bss_start_addr
30 lddpc r3, end_addr
31 mov r0, 0
32 mov r1, 0
331: st.d r2++, r0
34 cp r2, r3
35 brlo 1b
36
37 /*
38 * Save the tag table address for later use. This must be done
39 * _after_ .bss has been initialized...
40 */
41 lddpc r0, tag_table_addr
42 st.w r0[0], r11
43
44 /* Jump to loader-independent setup code */
45 rjmp kernel_entry
46
47 .align 2
48magic_number:
49 .long ATAG_MAGIC
50tag_table_addr:
51 .long bootloader_tags
52bss_start_addr:
53 .long __bss_start
54end_addr:
55 .long _end
56
57no_tag_table:
58 sub r12, pc, (. - 2f)
59 bral panic
602: .asciz "Boot loader didn't provide correct magic number\n"
diff --git a/arch/mips/configs/ev96100_defconfig b/arch/avr32/configs/atstk1002_defconfig
index 0bdc10f11610..1d22255009fd 100644
--- a/arch/mips/configs/ev96100_defconfig
+++ b/arch/avr32/configs/atstk1002_defconfig
@@ -1,158 +1,15 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.18-rc1 3# Linux kernel version: 2.6.18-rc1
4# Thu Jul 6 10:04:05 2006 4# Tue Jul 11 12:41:36 2006
5# 5#
6CONFIG_MIPS=y 6CONFIG_AVR32=y
7 7CONFIG_GENERIC_HARDIRQS=y
8# 8CONFIG_HARDIRQS_SW_RESEND=y
9# Machine selection 9CONFIG_GENERIC_IRQ_PROBE=y
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_BASLER_EXCITE is not set
25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set
28CONFIG_MIPS_EV96100=y
29# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set
32# CONFIG_LASAT is not set
33# CONFIG_MIPS_ATLAS is not set
34# CONFIG_MIPS_MALTA is not set
35# CONFIG_MIPS_SEAD is not set
36# CONFIG_WR_PPMC is not set
37# CONFIG_MIPS_SIM is not set
38# CONFIG_MOMENCO_JAGUAR_ATX is not set
39# CONFIG_MOMENCO_OCELOT is not set
40# CONFIG_MOMENCO_OCELOT_3 is not set
41# CONFIG_MOMENCO_OCELOT_C is not set
42# CONFIG_MOMENCO_OCELOT_G is not set
43# CONFIG_MIPS_XXS1500 is not set
44# CONFIG_PNX8550_V2PCI is not set
45# CONFIG_PNX8550_JBS is not set
46# CONFIG_DDB5477 is not set
47# CONFIG_MACH_VR41XX is not set
48# CONFIG_PMC_YOSEMITE is not set
49# CONFIG_QEMU is not set
50# CONFIG_MARKEINS is not set
51# CONFIG_SGI_IP22 is not set
52# CONFIG_SGI_IP27 is not set
53# CONFIG_SGI_IP32 is not set
54# CONFIG_SIBYTE_BIGSUR is not set
55# CONFIG_SIBYTE_SWARM is not set
56# CONFIG_SIBYTE_SENTOSA is not set
57# CONFIG_SIBYTE_RHONE is not set
58# CONFIG_SIBYTE_CARMEL is not set
59# CONFIG_SIBYTE_PTSWARM is not set
60# CONFIG_SIBYTE_LITTLESUR is not set
61# CONFIG_SIBYTE_CRHINE is not set
62# CONFIG_SIBYTE_CRHONE is not set
63# CONFIG_SNI_RM200_PCI is not set
64# CONFIG_TOSHIBA_JMR3927 is not set
65# CONFIG_TOSHIBA_RBTX4927 is not set
66# CONFIG_TOSHIBA_RBTX4938 is not set
67CONFIG_RWSEM_GENERIC_SPINLOCK=y 10CONFIG_RWSEM_GENERIC_SPINLOCK=y
68CONFIG_GENERIC_FIND_NEXT_BIT=y
69CONFIG_GENERIC_HWEIGHT=y 11CONFIG_GENERIC_HWEIGHT=y
70CONFIG_GENERIC_CALIBRATE_DELAY=y 12CONFIG_GENERIC_CALIBRATE_DELAY=y
71CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
72CONFIG_DMA_NONCOHERENT=y
73CONFIG_DMA_NEED_PCI_MAP_STATE=y
74CONFIG_CPU_BIG_ENDIAN=y
75# CONFIG_CPU_LITTLE_ENDIAN is not set
76CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
77CONFIG_IRQ_CPU=y
78CONFIG_MIPS_GT64120=y
79CONFIG_SWAP_IO_SPACE=y
80CONFIG_MIPS_GT96100=y
81CONFIG_MIPS_L1_CACHE_SHIFT=5
82
83#
84# CPU selection
85#
86# CONFIG_CPU_MIPS32_R1 is not set
87# CONFIG_CPU_MIPS32_R2 is not set
88# CONFIG_CPU_MIPS64_R1 is not set
89# CONFIG_CPU_MIPS64_R2 is not set
90# CONFIG_CPU_R3000 is not set
91# CONFIG_CPU_TX39XX is not set
92# CONFIG_CPU_VR41XX is not set
93# CONFIG_CPU_R4300 is not set
94# CONFIG_CPU_R4X00 is not set
95# CONFIG_CPU_TX49XX is not set
96# CONFIG_CPU_R5000 is not set
97# CONFIG_CPU_R5432 is not set
98# CONFIG_CPU_R6000 is not set
99# CONFIG_CPU_NEVADA is not set
100# CONFIG_CPU_R8000 is not set
101# CONFIG_CPU_R10000 is not set
102CONFIG_CPU_RM7000=y
103# CONFIG_CPU_RM9000 is not set
104# CONFIG_CPU_SB1 is not set
105CONFIG_SYS_HAS_CPU_R5000=y
106CONFIG_SYS_HAS_CPU_RM7000=y
107CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
108CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
109CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
110CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
111
112#
113# Kernel type
114#
115CONFIG_32BIT=y
116# CONFIG_64BIT is not set
117CONFIG_PAGE_SIZE_4KB=y
118# CONFIG_PAGE_SIZE_8KB is not set
119# CONFIG_PAGE_SIZE_16KB is not set
120# CONFIG_PAGE_SIZE_64KB is not set
121CONFIG_BOARD_SCACHE=y
122CONFIG_RM7000_CPU_SCACHE=y
123CONFIG_CPU_HAS_PREFETCH=y
124CONFIG_MIPS_MT_DISABLED=y
125# CONFIG_MIPS_MT_SMTC is not set
126# CONFIG_MIPS_MT_SMP is not set
127# CONFIG_MIPS_VPE_LOADER is not set
128# CONFIG_64BIT_PHYS_ADDR is not set
129CONFIG_CPU_HAS_LLSC=y
130CONFIG_CPU_HAS_SYNC=y
131CONFIG_GENERIC_HARDIRQS=y
132CONFIG_GENERIC_IRQ_PROBE=y
133CONFIG_CPU_SUPPORTS_HIGHMEM=y
134CONFIG_ARCH_FLATMEM_ENABLE=y
135CONFIG_SELECT_MEMORY_MODEL=y
136CONFIG_FLATMEM_MANUAL=y
137# CONFIG_DISCONTIGMEM_MANUAL is not set
138# CONFIG_SPARSEMEM_MANUAL is not set
139CONFIG_FLATMEM=y
140CONFIG_FLAT_NODE_MEM_MAP=y
141# CONFIG_SPARSEMEM_STATIC is not set
142CONFIG_SPLIT_PTLOCK_CPUS=4
143# CONFIG_RESOURCES_64BIT is not set
144# CONFIG_HZ_48 is not set
145# CONFIG_HZ_100 is not set
146# CONFIG_HZ_128 is not set
147# CONFIG_HZ_250 is not set
148# CONFIG_HZ_256 is not set
149CONFIG_HZ_1000=y
150# CONFIG_HZ_1024 is not set
151CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
152CONFIG_HZ=1000
153CONFIG_PREEMPT_NONE=y
154# CONFIG_PREEMPT_VOLUNTARY is not set
155# CONFIG_PREEMPT is not set
156CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" 13CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
157 14
158# 15#
@@ -166,34 +23,34 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
166# General setup 23# General setup
167# 24#
168CONFIG_LOCALVERSION="" 25CONFIG_LOCALVERSION=""
169CONFIG_LOCALVERSION_AUTO=y 26# CONFIG_LOCALVERSION_AUTO is not set
170CONFIG_SWAP=y 27CONFIG_SWAP=y
171CONFIG_SYSVIPC=y 28# CONFIG_SYSVIPC is not set
172# CONFIG_POSIX_MQUEUE is not set 29# CONFIG_POSIX_MQUEUE is not set
173# CONFIG_BSD_PROCESS_ACCT is not set 30# CONFIG_BSD_PROCESS_ACCT is not set
174CONFIG_SYSCTL=y 31CONFIG_SYSCTL=y
175# CONFIG_AUDIT is not set 32# CONFIG_AUDIT is not set
176# CONFIG_IKCONFIG is not set 33# CONFIG_IKCONFIG is not set
177CONFIG_RELAY=y 34# CONFIG_RELAY is not set
178CONFIG_INITRAMFS_SOURCE="" 35CONFIG_INITRAMFS_SOURCE=""
179# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set 36CONFIG_CC_OPTIMIZE_FOR_SIZE=y
180CONFIG_EMBEDDED=y 37CONFIG_EMBEDDED=y
181CONFIG_KALLSYMS=y 38CONFIG_KALLSYMS=y
39# CONFIG_KALLSYMS_ALL is not set
182# CONFIG_KALLSYMS_EXTRA_PASS is not set 40# CONFIG_KALLSYMS_EXTRA_PASS is not set
183# CONFIG_HOTPLUG is not set 41CONFIG_HOTPLUG=y
184CONFIG_PRINTK=y 42CONFIG_PRINTK=y
185CONFIG_BUG=y 43CONFIG_BUG=y
186CONFIG_ELF_CORE=y 44CONFIG_ELF_CORE=y
187CONFIG_BASE_FULL=y 45# CONFIG_BASE_FULL is not set
188CONFIG_RT_MUTEXES=y 46# CONFIG_FUTEX is not set
189CONFIG_FUTEX=y 47# CONFIG_EPOLL is not set
190CONFIG_EPOLL=y
191CONFIG_SHMEM=y 48CONFIG_SHMEM=y
192CONFIG_SLAB=y 49# CONFIG_SLAB is not set
193CONFIG_VM_EVENT_COUNTERS=y 50# CONFIG_VM_EVENT_COUNTERS is not set
194# CONFIG_TINY_SHMEM is not set 51# CONFIG_TINY_SHMEM is not set
195CONFIG_BASE_SMALL=0 52CONFIG_BASE_SMALL=1
196# CONFIG_SLOB is not set 53CONFIG_SLOB=y
197 54
198# 55#
199# Loadable module support 56# Loadable module support
@@ -201,52 +58,81 @@ CONFIG_BASE_SMALL=0
201CONFIG_MODULES=y 58CONFIG_MODULES=y
202CONFIG_MODULE_UNLOAD=y 59CONFIG_MODULE_UNLOAD=y
203# CONFIG_MODULE_FORCE_UNLOAD is not set 60# CONFIG_MODULE_FORCE_UNLOAD is not set
204CONFIG_MODVERSIONS=y 61# CONFIG_MODVERSIONS is not set
205CONFIG_MODULE_SRCVERSION_ALL=y 62# CONFIG_MODULE_SRCVERSION_ALL is not set
206# CONFIG_KMOD is not set 63# CONFIG_KMOD is not set
207 64
208# 65#
209# Block layer 66# Block layer
210# 67#
211# CONFIG_LBD is not set
212# CONFIG_BLK_DEV_IO_TRACE is not set 68# CONFIG_BLK_DEV_IO_TRACE is not set
213# CONFIG_LSF is not set
214 69
215# 70#
216# IO Schedulers 71# IO Schedulers
217# 72#
218CONFIG_IOSCHED_NOOP=y 73CONFIG_IOSCHED_NOOP=y
219CONFIG_IOSCHED_AS=y 74# CONFIG_IOSCHED_AS is not set
220CONFIG_IOSCHED_DEADLINE=y 75# CONFIG_IOSCHED_DEADLINE is not set
221CONFIG_IOSCHED_CFQ=y 76# CONFIG_IOSCHED_CFQ is not set
222CONFIG_DEFAULT_AS=y 77# CONFIG_DEFAULT_AS is not set
223# CONFIG_DEFAULT_DEADLINE is not set 78# CONFIG_DEFAULT_DEADLINE is not set
224# CONFIG_DEFAULT_CFQ is not set 79# CONFIG_DEFAULT_CFQ is not set
225# CONFIG_DEFAULT_NOOP is not set 80CONFIG_DEFAULT_NOOP=y
226CONFIG_DEFAULT_IOSCHED="anticipatory" 81CONFIG_DEFAULT_IOSCHED="noop"
227 82
228# 83#
229# Bus options (PCI, PCMCIA, EISA, ISA, TC) 84# System Type and features
230# 85#
231CONFIG_HW_HAS_PCI=y 86CONFIG_SUBARCH_AVR32B=y
232# CONFIG_PCI is not set
233CONFIG_MMU=y 87CONFIG_MMU=y
88CONFIG_PERFORMANCE_COUNTERS=y
89CONFIG_PLATFORM_AT32AP=y
90CONFIG_CPU_AT32AP7000=y
91CONFIG_BOARD_ATSTK1002=y
92CONFIG_BOARD_ATSTK1000=y
93CONFIG_LOADER_U_BOOT=y
94CONFIG_LOAD_ADDRESS=0x10000000
95CONFIG_ENTRY_ADDRESS=0x90000000
96CONFIG_PHYS_OFFSET=0x10000000
97CONFIG_PREEMPT_NONE=y
98# CONFIG_PREEMPT_VOLUNTARY is not set
99# CONFIG_PREEMPT is not set
100# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set
101# CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
102# CONFIG_NEED_NODE_MEMMAP_SIZE is not set
103CONFIG_ARCH_FLATMEM_ENABLE=y
104# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
105# CONFIG_ARCH_SPARSEMEM_ENABLE is not set
106CONFIG_SELECT_MEMORY_MODEL=y
107CONFIG_FLATMEM_MANUAL=y
108# CONFIG_DISCONTIGMEM_MANUAL is not set
109# CONFIG_SPARSEMEM_MANUAL is not set
110CONFIG_FLATMEM=y
111CONFIG_FLAT_NODE_MEM_MAP=y
112# CONFIG_SPARSEMEM_STATIC is not set
113CONFIG_SPLIT_PTLOCK_CPUS=4
114# CONFIG_RESOURCES_64BIT is not set
115# CONFIG_OWNERSHIP_TRACE is not set
116# CONFIG_HZ_100 is not set
117CONFIG_HZ_250=y
118# CONFIG_HZ_1000 is not set
119CONFIG_HZ=250
120CONFIG_CMDLINE=""
234 121
235# 122#
236# PCCARD (PCMCIA/CardBus) support 123# Bus options
237# 124#
238# CONFIG_PCCARD is not set
239 125
240# 126#
241# PCI Hotplug Support 127# PCCARD (PCMCIA/CardBus) support
242# 128#
129# CONFIG_PCCARD is not set
243 130
244# 131#
245# Executable file formats 132# Executable file formats
246# 133#
247CONFIG_BINFMT_ELF=y 134CONFIG_BINFMT_ELF=y
248# CONFIG_BINFMT_MISC is not set 135# CONFIG_BINFMT_MISC is not set
249CONFIG_TRAD_SIGNALS=y
250 136
251# 137#
252# Networking 138# Networking
@@ -257,18 +143,17 @@ CONFIG_NET=y
257# Networking options 143# Networking options
258# 144#
259# CONFIG_NETDEBUG is not set 145# CONFIG_NETDEBUG is not set
260# CONFIG_PACKET is not set 146CONFIG_PACKET=y
147CONFIG_PACKET_MMAP=y
261CONFIG_UNIX=y 148CONFIG_UNIX=y
262CONFIG_XFRM=y 149# CONFIG_NET_KEY is not set
263CONFIG_XFRM_USER=m
264CONFIG_NET_KEY=y
265CONFIG_INET=y 150CONFIG_INET=y
266# CONFIG_IP_MULTICAST is not set 151# CONFIG_IP_MULTICAST is not set
267# CONFIG_IP_ADVANCED_ROUTER is not set 152# CONFIG_IP_ADVANCED_ROUTER is not set
268CONFIG_IP_FIB_HASH=y 153CONFIG_IP_FIB_HASH=y
269CONFIG_IP_PNP=y 154CONFIG_IP_PNP=y
270# CONFIG_IP_PNP_DHCP is not set 155CONFIG_IP_PNP_DHCP=y
271CONFIG_IP_PNP_BOOTP=y 156# CONFIG_IP_PNP_BOOTP is not set
272# CONFIG_IP_PNP_RARP is not set 157# CONFIG_IP_PNP_RARP is not set
273# CONFIG_NET_IPIP is not set 158# CONFIG_NET_IPIP is not set
274# CONFIG_NET_IPGRE is not set 159# CONFIG_NET_IPGRE is not set
@@ -279,8 +164,8 @@ CONFIG_IP_PNP_BOOTP=y
279# CONFIG_INET_IPCOMP is not set 164# CONFIG_INET_IPCOMP is not set
280# CONFIG_INET_XFRM_TUNNEL is not set 165# CONFIG_INET_XFRM_TUNNEL is not set
281# CONFIG_INET_TUNNEL is not set 166# CONFIG_INET_TUNNEL is not set
282CONFIG_INET_XFRM_MODE_TRANSPORT=m 167# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
283CONFIG_INET_XFRM_MODE_TUNNEL=m 168# CONFIG_INET_XFRM_MODE_TUNNEL is not set
284CONFIG_INET_DIAG=y 169CONFIG_INET_DIAG=y
285CONFIG_INET_TCP_DIAG=y 170CONFIG_INET_TCP_DIAG=y
286# CONFIG_TCP_CONG_ADVANCED is not set 171# CONFIG_TCP_CONG_ADVANCED is not set
@@ -288,7 +173,7 @@ CONFIG_TCP_CONG_BIC=y
288# CONFIG_IPV6 is not set 173# CONFIG_IPV6 is not set
289# CONFIG_INET6_XFRM_TUNNEL is not set 174# CONFIG_INET6_XFRM_TUNNEL is not set
290# CONFIG_INET6_TUNNEL is not set 175# CONFIG_INET6_TUNNEL is not set
291CONFIG_NETWORK_SECMARK=y 176# CONFIG_NETWORK_SECMARK is not set
292# CONFIG_NETFILTER is not set 177# CONFIG_NETFILTER is not set
293 178
294# 179#
@@ -327,16 +212,11 @@ CONFIG_NETWORK_SECMARK=y
327# Network testing 212# Network testing
328# 213#
329# CONFIG_NET_PKTGEN is not set 214# CONFIG_NET_PKTGEN is not set
215# CONFIG_NET_TCPPROBE is not set
330# CONFIG_HAMRADIO is not set 216# CONFIG_HAMRADIO is not set
331# CONFIG_IRDA is not set 217# CONFIG_IRDA is not set
332# CONFIG_BT is not set 218# CONFIG_BT is not set
333CONFIG_IEEE80211=m 219# CONFIG_IEEE80211 is not set
334# CONFIG_IEEE80211_DEBUG is not set
335CONFIG_IEEE80211_CRYPT_WEP=m
336CONFIG_IEEE80211_CRYPT_CCMP=m
337CONFIG_IEEE80211_SOFTMAC=m
338# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set
339CONFIG_WIRELESS_EXT=y
340 220
341# 221#
342# Device Drivers 222# Device Drivers
@@ -346,14 +226,15 @@ CONFIG_WIRELESS_EXT=y
346# Generic Driver Options 226# Generic Driver Options
347# 227#
348CONFIG_STANDALONE=y 228CONFIG_STANDALONE=y
349CONFIG_PREVENT_FIRMWARE_BUILD=y 229# CONFIG_PREVENT_FIRMWARE_BUILD is not set
350# CONFIG_FW_LOADER is not set 230# CONFIG_FW_LOADER is not set
231# CONFIG_DEBUG_DRIVER is not set
351# CONFIG_SYS_HYPERVISOR is not set 232# CONFIG_SYS_HYPERVISOR is not set
352 233
353# 234#
354# Connector - unified userspace <-> kernelspace linker 235# Connector - unified userspace <-> kernelspace linker
355# 236#
356CONFIG_CONNECTOR=m 237# CONFIG_CONNECTOR is not set
357 238
358# 239#
359# Memory Technology Devices (MTD) 240# Memory Technology Devices (MTD)
@@ -373,14 +254,15 @@ CONFIG_CONNECTOR=m
373# Block devices 254# Block devices
374# 255#
375# CONFIG_BLK_DEV_COW_COMMON is not set 256# CONFIG_BLK_DEV_COW_COMMON is not set
376# CONFIG_BLK_DEV_LOOP is not set 257CONFIG_BLK_DEV_LOOP=m
377# CONFIG_BLK_DEV_NBD is not set 258# CONFIG_BLK_DEV_CRYPTOLOOP is not set
378# CONFIG_BLK_DEV_RAM is not set 259CONFIG_BLK_DEV_NBD=m
379# CONFIG_BLK_DEV_INITRD is not set 260CONFIG_BLK_DEV_RAM=m
380CONFIG_CDROM_PKTCDVD=m 261CONFIG_BLK_DEV_RAM_COUNT=16
381CONFIG_CDROM_PKTCDVD_BUFFERS=8 262CONFIG_BLK_DEV_RAM_SIZE=4096
382# CONFIG_CDROM_PKTCDVD_WCACHE is not set 263CONFIG_BLK_DEV_INITRD=y
383CONFIG_ATA_OVER_ETH=m 264# CONFIG_CDROM_PKTCDVD is not set
265# CONFIG_ATA_OVER_ETH is not set
384 266
385# 267#
386# ATA/ATAPI/MFM/RLL support 268# ATA/ATAPI/MFM/RLL support
@@ -390,7 +272,7 @@ CONFIG_ATA_OVER_ETH=m
390# 272#
391# SCSI device support 273# SCSI device support
392# 274#
393CONFIG_RAID_ATTRS=m 275# CONFIG_RAID_ATTRS is not set
394# CONFIG_SCSI is not set 276# CONFIG_SCSI is not set
395 277
396# 278#
@@ -415,34 +297,22 @@ CONFIG_RAID_ATTRS=m
415# Network device support 297# Network device support
416# 298#
417CONFIG_NETDEVICES=y 299CONFIG_NETDEVICES=y
418# CONFIG_DUMMY is not set 300CONFIG_DUMMY=y
419# CONFIG_BONDING is not set 301# CONFIG_BONDING is not set
420# CONFIG_EQUALIZER is not set 302# CONFIG_EQUALIZER is not set
421# CONFIG_TUN is not set 303CONFIG_TUN=m
422 304
423# 305#
424# PHY device support 306# PHY device support
425# 307#
426CONFIG_PHYLIB=m 308# CONFIG_PHYLIB is not set
427
428#
429# MII PHY device drivers
430#
431CONFIG_MARVELL_PHY=m
432CONFIG_DAVICOM_PHY=m
433CONFIG_QSEMI_PHY=m
434CONFIG_LXT_PHY=m
435CONFIG_CICADA_PHY=m
436CONFIG_VITESSE_PHY=m
437CONFIG_SMSC_PHY=m
438 309
439# 310#
440# Ethernet (10 or 100Mbit) 311# Ethernet (10 or 100Mbit)
441# 312#
442CONFIG_NET_ETHERNET=y 313CONFIG_NET_ETHERNET=y
443# CONFIG_MII is not set 314CONFIG_MII=y
444CONFIG_MIPS_GT96100ETH=y 315CONFIG_MACB=y
445# CONFIG_DM9000 is not set
446 316
447# 317#
448# Ethernet (1000 Mbit) 318# Ethernet (1000 Mbit)
@@ -465,7 +335,15 @@ CONFIG_MIPS_GT96100ETH=y
465# Wan interfaces 335# Wan interfaces
466# 336#
467# CONFIG_WAN is not set 337# CONFIG_WAN is not set
468# CONFIG_PPP is not set 338CONFIG_PPP=m
339# CONFIG_PPP_MULTILINK is not set
340# CONFIG_PPP_FILTER is not set
341CONFIG_PPP_ASYNC=m
342# CONFIG_PPP_SYNC_TTY is not set
343CONFIG_PPP_DEFLATE=m
344# CONFIG_PPP_BSDCOMP is not set
345# CONFIG_PPP_MPPE is not set
346# CONFIG_PPPOE is not set
469# CONFIG_SLIP is not set 347# CONFIG_SLIP is not set
470# CONFIG_SHAPER is not set 348# CONFIG_SHAPER is not set
471# CONFIG_NETCONSOLE is not set 349# CONFIG_NETCONSOLE is not set
@@ -485,65 +363,35 @@ CONFIG_MIPS_GT96100ETH=y
485# 363#
486# Input device support 364# Input device support
487# 365#
488CONFIG_INPUT=y 366# CONFIG_INPUT is not set
489
490#
491# Userland interfaces
492#
493CONFIG_INPUT_MOUSEDEV=y
494CONFIG_INPUT_MOUSEDEV_PSAUX=y
495CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
496CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
497# CONFIG_INPUT_JOYDEV is not set
498# CONFIG_INPUT_TSDEV is not set
499# CONFIG_INPUT_EVDEV is not set
500# CONFIG_INPUT_EVBUG is not set
501
502#
503# Input Device Drivers
504#
505# CONFIG_INPUT_KEYBOARD is not set
506# CONFIG_INPUT_MOUSE is not set
507# CONFIG_INPUT_JOYSTICK is not set
508# CONFIG_INPUT_TOUCHSCREEN is not set
509# CONFIG_INPUT_MISC is not set
510 367
511# 368#
512# Hardware I/O ports 369# Hardware I/O ports
513# 370#
514CONFIG_SERIO=y 371# CONFIG_SERIO is not set
515# CONFIG_SERIO_I8042 is not set
516CONFIG_SERIO_SERPORT=y
517# CONFIG_SERIO_LIBPS2 is not set
518CONFIG_SERIO_RAW=m
519# CONFIG_GAMEPORT is not set 372# CONFIG_GAMEPORT is not set
520 373
521# 374#
522# Character devices 375# Character devices
523# 376#
524CONFIG_VT=y 377# CONFIG_VT is not set
525CONFIG_VT_CONSOLE=y
526CONFIG_HW_CONSOLE=y
527CONFIG_VT_HW_CONSOLE_BINDING=y
528# CONFIG_SERIAL_NONSTANDARD is not set 378# CONFIG_SERIAL_NONSTANDARD is not set
529 379
530# 380#
531# Serial drivers 381# Serial drivers
532# 382#
533CONFIG_SERIAL_8250=y 383# CONFIG_SERIAL_8250 is not set
534CONFIG_SERIAL_8250_CONSOLE=y
535CONFIG_SERIAL_8250_NR_UARTS=4
536CONFIG_SERIAL_8250_RUNTIME_UARTS=4
537# CONFIG_SERIAL_8250_EXTENDED is not set
538 384
539# 385#
540# Non-8250 serial port support 386# Non-8250 serial port support
541# 387#
388CONFIG_SERIAL_AT91=y
389CONFIG_SERIAL_AT91_CONSOLE=y
390# CONFIG_SERIAL_AT91_TTYAT is not set
542CONFIG_SERIAL_CORE=y 391CONFIG_SERIAL_CORE=y
543CONFIG_SERIAL_CORE_CONSOLE=y 392CONFIG_SERIAL_CORE_CONSOLE=y
544CONFIG_UNIX98_PTYS=y 393CONFIG_UNIX98_PTYS=y
545CONFIG_LEGACY_PTYS=y 394# CONFIG_LEGACY_PTYS is not set
546CONFIG_LEGACY_PTY_COUNT=256
547 395
548# 396#
549# IPMI 397# IPMI
@@ -579,13 +427,23 @@ CONFIG_LEGACY_PTY_COUNT=256
579# 427#
580# SPI support 428# SPI support
581# 429#
582# CONFIG_SPI is not set 430CONFIG_SPI=y
583# CONFIG_SPI_MASTER is not set 431# CONFIG_SPI_DEBUG is not set
432CONFIG_SPI_MASTER=y
433
434#
435# SPI Master Controller Drivers
436#
437CONFIG_SPI_ATMEL=m
438# CONFIG_SPI_BITBANG is not set
439
440#
441# SPI Protocol Masters
442#
584 443
585# 444#
586# Dallas's 1-wire bus 445# Dallas's 1-wire bus
587# 446#
588# CONFIG_W1 is not set
589 447
590# 448#
591# Hardware Monitoring support 449# Hardware Monitoring support
@@ -612,13 +470,28 @@ CONFIG_VIDEO_V4L2=y
612# Graphics support 470# Graphics support
613# 471#
614# CONFIG_FIRMWARE_EDID is not set 472# CONFIG_FIRMWARE_EDID is not set
615# CONFIG_FB is not set 473CONFIG_FB=m
616 474CONFIG_FB_CFB_FILLRECT=m
617# 475CONFIG_FB_CFB_COPYAREA=m
618# Console display driver support 476CONFIG_FB_CFB_IMAGEBLIT=m
619# 477# CONFIG_FB_MACMODES is not set
620# CONFIG_VGA_CONSOLE is not set 478# CONFIG_FB_BACKLIGHT is not set
621CONFIG_DUMMY_CONSOLE=y 479# CONFIG_FB_MODE_HELPERS is not set
480# CONFIG_FB_TILEBLITTING is not set
481CONFIG_FB_SIDSA=m
482CONFIG_FB_SIDSA_DEFAULT_BPP=24
483# CONFIG_FB_S1D13XXX is not set
484# CONFIG_FB_VIRTUAL is not set
485
486#
487# Logo configuration
488#
489# CONFIG_LOGO is not set
490CONFIG_BACKLIGHT_LCD_SUPPORT=y
491# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
492CONFIG_LCD_CLASS_DEVICE=m
493CONFIG_LCD_DEVICE=y
494CONFIG_LCD_LTV350QV=m
622 495
623# 496#
624# Sound 497# Sound
@@ -697,15 +570,14 @@ CONFIG_EXT2_FS=y
697# CONFIG_FS_POSIX_ACL is not set 570# CONFIG_FS_POSIX_ACL is not set
698# CONFIG_XFS_FS is not set 571# CONFIG_XFS_FS is not set
699# CONFIG_OCFS2_FS is not set 572# CONFIG_OCFS2_FS is not set
700# CONFIG_MINIX_FS is not set 573CONFIG_MINIX_FS=m
701# CONFIG_ROMFS_FS is not set 574CONFIG_ROMFS_FS=m
702CONFIG_INOTIFY=y 575# CONFIG_INOTIFY is not set
703CONFIG_INOTIFY_USER=y
704# CONFIG_QUOTA is not set 576# CONFIG_QUOTA is not set
705CONFIG_DNOTIFY=y 577# CONFIG_DNOTIFY is not set
706# CONFIG_AUTOFS_FS is not set 578# CONFIG_AUTOFS_FS is not set
707# CONFIG_AUTOFS4_FS is not set 579# CONFIG_AUTOFS4_FS is not set
708CONFIG_FUSE_FS=m 580# CONFIG_FUSE_FS is not set
709 581
710# 582#
711# CD-ROM/DVD Filesystems 583# CD-ROM/DVD Filesystems
@@ -716,8 +588,11 @@ CONFIG_FUSE_FS=m
716# 588#
717# DOS/FAT/NT Filesystems 589# DOS/FAT/NT Filesystems
718# 590#
719# CONFIG_MSDOS_FS is not set 591CONFIG_FAT_FS=m
720# CONFIG_VFAT_FS is not set 592CONFIG_MSDOS_FS=m
593CONFIG_VFAT_FS=m
594CONFIG_FAT_DEFAULT_CODEPAGE=437
595CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
721# CONFIG_NTFS_FS is not set 596# CONFIG_NTFS_FS is not set
722 597
723# 598#
@@ -726,10 +601,10 @@ CONFIG_FUSE_FS=m
726CONFIG_PROC_FS=y 601CONFIG_PROC_FS=y
727CONFIG_PROC_KCORE=y 602CONFIG_PROC_KCORE=y
728CONFIG_SYSFS=y 603CONFIG_SYSFS=y
729# CONFIG_TMPFS is not set 604CONFIG_TMPFS=y
730# CONFIG_HUGETLB_PAGE is not set 605# CONFIG_HUGETLB_PAGE is not set
731CONFIG_RAMFS=y 606CONFIG_RAMFS=y
732# CONFIG_CONFIGFS_FS is not set 607CONFIG_CONFIGFS_FS=m
733 608
734# 609#
735# Miscellaneous filesystems 610# Miscellaneous filesystems
@@ -752,19 +627,25 @@ CONFIG_RAMFS=y
752# Network File Systems 627# Network File Systems
753# 628#
754CONFIG_NFS_FS=y 629CONFIG_NFS_FS=y
755# CONFIG_NFS_V3 is not set 630CONFIG_NFS_V3=y
631# CONFIG_NFS_V3_ACL is not set
756# CONFIG_NFS_V4 is not set 632# CONFIG_NFS_V4 is not set
757# CONFIG_NFS_DIRECTIO is not set 633# CONFIG_NFS_DIRECTIO is not set
758# CONFIG_NFSD is not set 634# CONFIG_NFSD is not set
759CONFIG_ROOT_NFS=y 635CONFIG_ROOT_NFS=y
760CONFIG_LOCKD=y 636CONFIG_LOCKD=y
637CONFIG_LOCKD_V4=y
761CONFIG_NFS_COMMON=y 638CONFIG_NFS_COMMON=y
762CONFIG_SUNRPC=y 639CONFIG_SUNRPC=y
763# CONFIG_RPCSEC_GSS_KRB5 is not set 640# CONFIG_RPCSEC_GSS_KRB5 is not set
764# CONFIG_RPCSEC_GSS_SPKM3 is not set 641# CONFIG_RPCSEC_GSS_SPKM3 is not set
765# CONFIG_SMB_FS is not set 642# CONFIG_SMB_FS is not set
766# CONFIG_CIFS is not set 643CONFIG_CIFS=m
644# CONFIG_CIFS_STATS is not set
645# CONFIG_CIFS_WEAK_PW_HASH is not set
646# CONFIG_CIFS_XATTR is not set
767# CONFIG_CIFS_DEBUG2 is not set 647# CONFIG_CIFS_DEBUG2 is not set
648# CONFIG_CIFS_EXPERIMENTAL is not set
768# CONFIG_NCP_FS is not set 649# CONFIG_NCP_FS is not set
769# CONFIG_CODA_FS is not set 650# CONFIG_CODA_FS is not set
770# CONFIG_AFS_FS is not set 651# CONFIG_AFS_FS is not set
@@ -779,60 +660,84 @@ CONFIG_MSDOS_PARTITION=y
779# 660#
780# Native Language Support 661# Native Language Support
781# 662#
782# CONFIG_NLS is not set 663CONFIG_NLS=m
783 664CONFIG_NLS_DEFAULT="iso8859-1"
784# 665CONFIG_NLS_CODEPAGE_437=m
785# Profiling support 666# CONFIG_NLS_CODEPAGE_737 is not set
786# 667# CONFIG_NLS_CODEPAGE_775 is not set
787# CONFIG_PROFILING is not set 668CONFIG_NLS_CODEPAGE_850=m
669# CONFIG_NLS_CODEPAGE_852 is not set
670# CONFIG_NLS_CODEPAGE_855 is not set
671# CONFIG_NLS_CODEPAGE_857 is not set
672# CONFIG_NLS_CODEPAGE_860 is not set
673# CONFIG_NLS_CODEPAGE_861 is not set
674# CONFIG_NLS_CODEPAGE_862 is not set
675# CONFIG_NLS_CODEPAGE_863 is not set
676# CONFIG_NLS_CODEPAGE_864 is not set
677# CONFIG_NLS_CODEPAGE_865 is not set
678# CONFIG_NLS_CODEPAGE_866 is not set
679# CONFIG_NLS_CODEPAGE_869 is not set
680# CONFIG_NLS_CODEPAGE_936 is not set
681# CONFIG_NLS_CODEPAGE_950 is not set
682# CONFIG_NLS_CODEPAGE_932 is not set
683# CONFIG_NLS_CODEPAGE_949 is not set
684# CONFIG_NLS_CODEPAGE_874 is not set
685# CONFIG_NLS_ISO8859_8 is not set
686# CONFIG_NLS_CODEPAGE_1250 is not set
687# CONFIG_NLS_CODEPAGE_1251 is not set
688# CONFIG_NLS_ASCII is not set
689CONFIG_NLS_ISO8859_1=m
690# CONFIG_NLS_ISO8859_2 is not set
691# CONFIG_NLS_ISO8859_3 is not set
692# CONFIG_NLS_ISO8859_4 is not set
693# CONFIG_NLS_ISO8859_5 is not set
694# CONFIG_NLS_ISO8859_6 is not set
695# CONFIG_NLS_ISO8859_7 is not set
696# CONFIG_NLS_ISO8859_9 is not set
697# CONFIG_NLS_ISO8859_13 is not set
698# CONFIG_NLS_ISO8859_14 is not set
699# CONFIG_NLS_ISO8859_15 is not set
700# CONFIG_NLS_KOI8_R is not set
701# CONFIG_NLS_KOI8_U is not set
702CONFIG_NLS_UTF8=m
788 703
789# 704#
790# Kernel hacking 705# Kernel hacking
791# 706#
792# CONFIG_PRINTK_TIME is not set 707CONFIG_TRACE_IRQFLAGS_SUPPORT=y
793# CONFIG_MAGIC_SYSRQ is not set 708CONFIG_PRINTK_TIME=y
709CONFIG_MAGIC_SYSRQ=y
794# CONFIG_UNUSED_SYMBOLS is not set 710# CONFIG_UNUSED_SYMBOLS is not set
795# CONFIG_DEBUG_KERNEL is not set 711CONFIG_DEBUG_KERNEL=y
796CONFIG_LOG_BUF_SHIFT=14 712CONFIG_LOG_BUF_SHIFT=14
797# CONFIG_DEBUG_FS is not set 713CONFIG_DETECT_SOFTLOCKUP=y
798CONFIG_CROSSCOMPILE=y 714# CONFIG_SCHEDSTATS is not set
799CONFIG_CMDLINE="" 715# CONFIG_DEBUG_SPINLOCK is not set
716# CONFIG_DEBUG_MUTEXES is not set
717# CONFIG_DEBUG_RWSEMS is not set
718# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
719# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
720# CONFIG_DEBUG_KOBJECT is not set
721CONFIG_DEBUG_BUGVERBOSE=y
722# CONFIG_DEBUG_INFO is not set
723CONFIG_DEBUG_FS=y
724# CONFIG_DEBUG_VM is not set
725CONFIG_FRAME_POINTER=y
726# CONFIG_UNWIND_INFO is not set
727CONFIG_FORCED_INLINING=y
728# CONFIG_RCU_TORTURE_TEST is not set
729CONFIG_KPROBES=y
800 730
801# 731#
802# Security options 732# Security options
803# 733#
804CONFIG_KEYS=y 734# CONFIG_KEYS is not set
805CONFIG_KEYS_DEBUG_PROC_KEYS=y
806# CONFIG_SECURITY is not set 735# CONFIG_SECURITY is not set
807 736
808# 737#
809# Cryptographic options 738# Cryptographic options
810# 739#
811CONFIG_CRYPTO=y 740# CONFIG_CRYPTO is not set
812CONFIG_CRYPTO_HMAC=y
813CONFIG_CRYPTO_NULL=m
814CONFIG_CRYPTO_MD4=m
815CONFIG_CRYPTO_MD5=m
816CONFIG_CRYPTO_SHA1=m
817CONFIG_CRYPTO_SHA256=m
818CONFIG_CRYPTO_SHA512=m
819CONFIG_CRYPTO_WP512=m
820CONFIG_CRYPTO_TGR192=m
821CONFIG_CRYPTO_DES=m
822CONFIG_CRYPTO_BLOWFISH=m
823CONFIG_CRYPTO_TWOFISH=m
824CONFIG_CRYPTO_SERPENT=m
825CONFIG_CRYPTO_AES=m
826CONFIG_CRYPTO_CAST5=m
827CONFIG_CRYPTO_CAST6=m
828CONFIG_CRYPTO_TEA=m
829CONFIG_CRYPTO_ARC4=m
830CONFIG_CRYPTO_KHAZAD=m
831CONFIG_CRYPTO_ANUBIS=m
832CONFIG_CRYPTO_DEFLATE=m
833CONFIG_CRYPTO_MICHAEL_MIC=m
834CONFIG_CRYPTO_CRC32C=m
835# CONFIG_CRYPTO_TEST is not set
836 741
837# 742#
838# Hardware crypto devices 743# Hardware crypto devices
@@ -841,10 +746,9 @@ CONFIG_CRYPTO_CRC32C=m
841# 746#
842# Library routines 747# Library routines
843# 748#
844# CONFIG_CRC_CCITT is not set 749CONFIG_CRC_CCITT=m
845CONFIG_CRC16=m 750# CONFIG_CRC16 is not set
846CONFIG_CRC32=m 751CONFIG_CRC32=m
847CONFIG_LIBCRC32C=m 752# CONFIG_LIBCRC32C is not set
848CONFIG_ZLIB_INFLATE=m 753CONFIG_ZLIB_INFLATE=m
849CONFIG_ZLIB_DEFLATE=m 754CONFIG_ZLIB_DEFLATE=m
850CONFIG_PLIST=y
diff --git a/arch/avr32/kernel/Makefile b/arch/avr32/kernel/Makefile
new file mode 100644
index 000000000000..90e5afff54a2
--- /dev/null
+++ b/arch/avr32/kernel/Makefile
@@ -0,0 +1,18 @@
1#
2# Makefile for the Linux/AVR32 kernel.
3#
4
5extra-y := head.o vmlinux.lds
6
7obj-$(CONFIG_SUBARCH_AVR32B) += entry-avr32b.o
8obj-y += syscall_table.o syscall-stubs.o irq.o
9obj-y += setup.o traps.o semaphore.o ptrace.o
10obj-y += signal.o sys_avr32.o process.o time.o
11obj-y += init_task.o switch_to.o cpu.o
12obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o
13obj-$(CONFIG_KPROBES) += kprobes.o
14
15USE_STANDARD_AS_RULE := true
16
17%.lds: %.lds.c FORCE
18 $(call if_changed_dep,cpp_lds_S)
diff --git a/arch/avr32/kernel/asm-offsets.c b/arch/avr32/kernel/asm-offsets.c
new file mode 100644
index 000000000000..97d865865667
--- /dev/null
+++ b/arch/avr32/kernel/asm-offsets.c
@@ -0,0 +1,25 @@
1/*
2 * Generate definitions needed by assembly language modules.
3 * This code generates raw asm output which is post-processed
4 * to extract and format the required data.
5 */
6
7#include <linux/thread_info.h>
8
9#define DEFINE(sym, val) \
10 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
11
12#define BLANK() asm volatile("\n->" : : )
13
14#define OFFSET(sym, str, mem) \
15 DEFINE(sym, offsetof(struct str, mem));
16
17void foo(void)
18{
19 OFFSET(TI_task, thread_info, task);
20 OFFSET(TI_exec_domain, thread_info, exec_domain);
21 OFFSET(TI_flags, thread_info, flags);
22 OFFSET(TI_cpu, thread_info, cpu);
23 OFFSET(TI_preempt_count, thread_info, preempt_count);
24 OFFSET(TI_restart_block, thread_info, restart_block);
25}
diff --git a/arch/avr32/kernel/avr32_ksyms.c b/arch/avr32/kernel/avr32_ksyms.c
new file mode 100644
index 000000000000..04f767a272b7
--- /dev/null
+++ b/arch/avr32/kernel/avr32_ksyms.c
@@ -0,0 +1,55 @@
1/*
2 * Export AVR32-specific functions for loadable modules.
3 *
4 * Copyright (C) 2004-2006 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/module.h>
11
12#include <asm/checksum.h>
13#include <asm/uaccess.h>
14#include <asm/delay.h>
15
16/*
17 * GCC functions
18 */
19extern unsigned long long __avr32_lsl64(unsigned long long u, unsigned long b);
20extern unsigned long long __avr32_lsr64(unsigned long long u, unsigned long b);
21extern unsigned long long __avr32_asr64(unsigned long long u, unsigned long b);
22EXPORT_SYMBOL(__avr32_lsl64);
23EXPORT_SYMBOL(__avr32_lsr64);
24EXPORT_SYMBOL(__avr32_asr64);
25
26/*
27 * String functions
28 */
29EXPORT_SYMBOL(memset);
30EXPORT_SYMBOL(memcpy);
31
32/*
33 * Userspace access stuff.
34 */
35EXPORT_SYMBOL(copy_from_user);
36EXPORT_SYMBOL(copy_to_user);
37EXPORT_SYMBOL(__copy_user);
38EXPORT_SYMBOL(strncpy_from_user);
39EXPORT_SYMBOL(__strncpy_from_user);
40EXPORT_SYMBOL(clear_user);
41EXPORT_SYMBOL(__clear_user);
42EXPORT_SYMBOL(csum_partial);
43EXPORT_SYMBOL(csum_partial_copy_generic);
44
45/* Delay loops (lib/delay.S) */
46EXPORT_SYMBOL(__ndelay);
47EXPORT_SYMBOL(__udelay);
48EXPORT_SYMBOL(__const_udelay);
49
50/* Bit operations (lib/findbit.S) */
51EXPORT_SYMBOL(find_first_zero_bit);
52EXPORT_SYMBOL(find_next_zero_bit);
53EXPORT_SYMBOL(find_first_bit);
54EXPORT_SYMBOL(find_next_bit);
55EXPORT_SYMBOL(generic_find_next_zero_le_bit);
diff --git a/arch/avr32/kernel/cpu.c b/arch/avr32/kernel/cpu.c
new file mode 100644
index 000000000000..342452ba2049
--- /dev/null
+++ b/arch/avr32/kernel/cpu.c
@@ -0,0 +1,327 @@
1/*
2 * Copyright (C) 2005-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#include <linux/init.h>
9#include <linux/sysdev.h>
10#include <linux/seq_file.h>
11#include <linux/cpu.h>
12#include <linux/percpu.h>
13#include <linux/param.h>
14#include <linux/errno.h>
15
16#include <asm/setup.h>
17#include <asm/sysreg.h>
18
19static DEFINE_PER_CPU(struct cpu, cpu_devices);
20
21#ifdef CONFIG_PERFORMANCE_COUNTERS
22
23/*
24 * XXX: If/when a SMP-capable implementation of AVR32 will ever be
25 * made, we must make sure that the code executes on the correct CPU.
26 */
27static ssize_t show_pc0event(struct sys_device *dev, char *buf)
28{
29 unsigned long pccr;
30
31 pccr = sysreg_read(PCCR);
32 return sprintf(buf, "0x%lx\n", (pccr >> 12) & 0x3f);
33}
34static ssize_t store_pc0event(struct sys_device *dev, const char *buf,
35 size_t count)
36{
37 unsigned long val;
38 char *endp;
39
40 val = simple_strtoul(buf, &endp, 0);
41 if (endp == buf || val > 0x3f)
42 return -EINVAL;
43 val = (val << 12) | (sysreg_read(PCCR) & 0xfffc0fff);
44 sysreg_write(PCCR, val);
45 return count;
46}
47static ssize_t show_pc0count(struct sys_device *dev, char *buf)
48{
49 unsigned long pcnt0;
50
51 pcnt0 = sysreg_read(PCNT0);
52 return sprintf(buf, "%lu\n", pcnt0);
53}
54static ssize_t store_pc0count(struct sys_device *dev, const char *buf,
55 size_t count)
56{
57 unsigned long val;
58 char *endp;
59
60 val = simple_strtoul(buf, &endp, 0);
61 if (endp == buf)
62 return -EINVAL;
63 sysreg_write(PCNT0, val);
64
65 return count;
66}
67
68static ssize_t show_pc1event(struct sys_device *dev, char *buf)
69{
70 unsigned long pccr;
71
72 pccr = sysreg_read(PCCR);
73 return sprintf(buf, "0x%lx\n", (pccr >> 18) & 0x3f);
74}
75static ssize_t store_pc1event(struct sys_device *dev, const char *buf,
76 size_t count)
77{
78 unsigned long val;
79 char *endp;
80
81 val = simple_strtoul(buf, &endp, 0);
82 if (endp == buf || val > 0x3f)
83 return -EINVAL;
84 val = (val << 18) | (sysreg_read(PCCR) & 0xff03ffff);
85 sysreg_write(PCCR, val);
86 return count;
87}
88static ssize_t show_pc1count(struct sys_device *dev, char *buf)
89{
90 unsigned long pcnt1;
91
92 pcnt1 = sysreg_read(PCNT1);
93 return sprintf(buf, "%lu\n", pcnt1);
94}
95static ssize_t store_pc1count(struct sys_device *dev, const char *buf,
96 size_t count)
97{
98 unsigned long val;
99 char *endp;
100
101 val = simple_strtoul(buf, &endp, 0);
102 if (endp == buf)
103 return -EINVAL;
104 sysreg_write(PCNT1, val);
105
106 return count;
107}
108
109static ssize_t show_pccycles(struct sys_device *dev, char *buf)
110{
111 unsigned long pccnt;
112
113 pccnt = sysreg_read(PCCNT);
114 return sprintf(buf, "%lu\n", pccnt);
115}
116static ssize_t store_pccycles(struct sys_device *dev, const char *buf,
117 size_t count)
118{
119 unsigned long val;
120 char *endp;
121
122 val = simple_strtoul(buf, &endp, 0);
123 if (endp == buf)
124 return -EINVAL;
125 sysreg_write(PCCNT, val);
126
127 return count;
128}
129
130static ssize_t show_pcenable(struct sys_device *dev, char *buf)
131{
132 unsigned long pccr;
133
134 pccr = sysreg_read(PCCR);
135 return sprintf(buf, "%c\n", (pccr & 1)?'1':'0');
136}
137static ssize_t store_pcenable(struct sys_device *dev, const char *buf,
138 size_t count)
139{
140 unsigned long pccr, val;
141 char *endp;
142
143 val = simple_strtoul(buf, &endp, 0);
144 if (endp == buf)
145 return -EINVAL;
146 if (val)
147 val = 1;
148
149 pccr = sysreg_read(PCCR);
150 pccr = (pccr & ~1UL) | val;
151 sysreg_write(PCCR, pccr);
152
153 return count;
154}
155
156static SYSDEV_ATTR(pc0event, 0600, show_pc0event, store_pc0event);
157static SYSDEV_ATTR(pc0count, 0600, show_pc0count, store_pc0count);
158static SYSDEV_ATTR(pc1event, 0600, show_pc1event, store_pc1event);
159static SYSDEV_ATTR(pc1count, 0600, show_pc1count, store_pc1count);
160static SYSDEV_ATTR(pccycles, 0600, show_pccycles, store_pccycles);
161static SYSDEV_ATTR(pcenable, 0600, show_pcenable, store_pcenable);
162
163#endif /* CONFIG_PERFORMANCE_COUNTERS */
164
165static int __init topology_init(void)
166{
167 int cpu;
168
169 for_each_possible_cpu(cpu) {
170 struct cpu *c = &per_cpu(cpu_devices, cpu);
171
172 register_cpu(c, cpu);
173
174#ifdef CONFIG_PERFORMANCE_COUNTERS
175 sysdev_create_file(&c->sysdev, &attr_pc0event);
176 sysdev_create_file(&c->sysdev, &attr_pc0count);
177 sysdev_create_file(&c->sysdev, &attr_pc1event);
178 sysdev_create_file(&c->sysdev, &attr_pc1count);
179 sysdev_create_file(&c->sysdev, &attr_pccycles);
180 sysdev_create_file(&c->sysdev, &attr_pcenable);
181#endif
182 }
183
184 return 0;
185}
186
187subsys_initcall(topology_init);
188
189static const char *cpu_names[] = {
190 "Morgan",
191 "AP7000",
192};
193#define NR_CPU_NAMES ARRAY_SIZE(cpu_names)
194
195static const char *arch_names[] = {
196 "AVR32A",
197 "AVR32B",
198};
199#define NR_ARCH_NAMES ARRAY_SIZE(arch_names)
200
201static const char *mmu_types[] = {
202 "No MMU",
203 "ITLB and DTLB",
204 "Shared TLB",
205 "MPU"
206};
207
208void __init setup_processor(void)
209{
210 unsigned long config0, config1;
211 unsigned cpu_id, cpu_rev, arch_id, arch_rev, mmu_type;
212 unsigned tmp;
213
214 config0 = sysreg_read(CONFIG0); /* 0x0000013e; */
215 config1 = sysreg_read(CONFIG1); /* 0x01f689a2; */
216 cpu_id = config0 >> 24;
217 cpu_rev = (config0 >> 16) & 0xff;
218 arch_id = (config0 >> 13) & 0x07;
219 arch_rev = (config0 >> 10) & 0x07;
220 mmu_type = (config0 >> 7) & 0x03;
221
222 boot_cpu_data.arch_type = arch_id;
223 boot_cpu_data.cpu_type = cpu_id;
224 boot_cpu_data.arch_revision = arch_rev;
225 boot_cpu_data.cpu_revision = cpu_rev;
226 boot_cpu_data.tlb_config = mmu_type;
227
228 tmp = (config1 >> 13) & 0x07;
229 if (tmp) {
230 boot_cpu_data.icache.ways = 1 << ((config1 >> 10) & 0x07);
231 boot_cpu_data.icache.sets = 1 << ((config1 >> 16) & 0x0f);
232 boot_cpu_data.icache.linesz = 1 << (tmp + 1);
233 }
234 tmp = (config1 >> 3) & 0x07;
235 if (tmp) {
236 boot_cpu_data.dcache.ways = 1 << (config1 & 0x07);
237 boot_cpu_data.dcache.sets = 1 << ((config1 >> 6) & 0x0f);
238 boot_cpu_data.dcache.linesz = 1 << (tmp + 1);
239 }
240
241 if ((cpu_id >= NR_CPU_NAMES) || (arch_id >= NR_ARCH_NAMES)) {
242 printk ("Unknown CPU configuration (ID %02x, arch %02x), "
243 "continuing anyway...\n",
244 cpu_id, arch_id);
245 return;
246 }
247
248 printk ("CPU: %s [%02x] revision %d (%s revision %d)\n",
249 cpu_names[cpu_id], cpu_id, cpu_rev,
250 arch_names[arch_id], arch_rev);
251 printk ("CPU: MMU configuration: %s\n", mmu_types[mmu_type]);
252 printk ("CPU: features:");
253 if (config0 & (1 << 6))
254 printk(" fpu");
255 if (config0 & (1 << 5))
256 printk(" java");
257 if (config0 & (1 << 4))
258 printk(" perfctr");
259 if (config0 & (1 << 3))
260 printk(" ocd");
261 printk("\n");
262}
263
264#ifdef CONFIG_PROC_FS
265static int c_show(struct seq_file *m, void *v)
266{
267 unsigned int icache_size, dcache_size;
268 unsigned int cpu = smp_processor_id();
269
270 icache_size = boot_cpu_data.icache.ways *
271 boot_cpu_data.icache.sets *
272 boot_cpu_data.icache.linesz;
273 dcache_size = boot_cpu_data.dcache.ways *
274 boot_cpu_data.dcache.sets *
275 boot_cpu_data.dcache.linesz;
276
277 seq_printf(m, "processor\t: %d\n", cpu);
278
279 if (boot_cpu_data.arch_type < NR_ARCH_NAMES)
280 seq_printf(m, "cpu family\t: %s revision %d\n",
281 arch_names[boot_cpu_data.arch_type],
282 boot_cpu_data.arch_revision);
283 if (boot_cpu_data.cpu_type < NR_CPU_NAMES)
284 seq_printf(m, "cpu type\t: %s revision %d\n",
285 cpu_names[boot_cpu_data.cpu_type],
286 boot_cpu_data.cpu_revision);
287
288 seq_printf(m, "i-cache\t\t: %dK (%u ways x %u sets x %u)\n",
289 icache_size >> 10,
290 boot_cpu_data.icache.ways,
291 boot_cpu_data.icache.sets,
292 boot_cpu_data.icache.linesz);
293 seq_printf(m, "d-cache\t\t: %dK (%u ways x %u sets x %u)\n",
294 dcache_size >> 10,
295 boot_cpu_data.dcache.ways,
296 boot_cpu_data.dcache.sets,
297 boot_cpu_data.dcache.linesz);
298 seq_printf(m, "bogomips\t: %lu.%02lu\n",
299 boot_cpu_data.loops_per_jiffy / (500000/HZ),
300 (boot_cpu_data.loops_per_jiffy / (5000/HZ)) % 100);
301
302 return 0;
303}
304
305static void *c_start(struct seq_file *m, loff_t *pos)
306{
307 return *pos < 1 ? (void *)1 : NULL;
308}
309
310static void *c_next(struct seq_file *m, void *v, loff_t *pos)
311{
312 ++*pos;
313 return NULL;
314}
315
316static void c_stop(struct seq_file *m, void *v)
317{
318
319}
320
321struct seq_operations cpuinfo_op = {
322 .start = c_start,
323 .next = c_next,
324 .stop = c_stop,
325 .show = c_show
326};
327#endif /* CONFIG_PROC_FS */
diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S
new file mode 100644
index 000000000000..eeb66792bc37
--- /dev/null
+++ b/arch/avr32/kernel/entry-avr32b.S
@@ -0,0 +1,678 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9/*
10 * This file contains the low-level entry-points into the kernel, that is,
11 * exception handlers, debug trap handlers, interrupt handlers and the
12 * system call handler.
13 */
14#include <linux/errno.h>
15
16#include <asm/asm.h>
17#include <asm/hardirq.h>
18#include <asm/irq.h>
19#include <asm/ocd.h>
20#include <asm/page.h>
21#include <asm/pgtable.h>
22#include <asm/ptrace.h>
23#include <asm/sysreg.h>
24#include <asm/thread_info.h>
25#include <asm/unistd.h>
26
27#ifdef CONFIG_PREEMPT
28# define preempt_stop mask_interrupts
29#else
30# define preempt_stop
31# define fault_resume_kernel fault_restore_all
32#endif
33
34#define __MASK(x) ((1 << (x)) - 1)
35#define IRQ_MASK ((__MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) | \
36 (__MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT))
37
38 .section .ex.text,"ax",@progbits
39 .align 2
40exception_vectors:
41 bral handle_critical
42 .align 2
43 bral handle_critical
44 .align 2
45 bral do_bus_error_write
46 .align 2
47 bral do_bus_error_read
48 .align 2
49 bral do_nmi_ll
50 .align 2
51 bral handle_address_fault
52 .align 2
53 bral handle_protection_fault
54 .align 2
55 bral handle_debug
56 .align 2
57 bral do_illegal_opcode_ll
58 .align 2
59 bral do_illegal_opcode_ll
60 .align 2
61 bral do_illegal_opcode_ll
62 .align 2
63 bral do_fpe_ll
64 .align 2
65 bral do_illegal_opcode_ll
66 .align 2
67 bral handle_address_fault
68 .align 2
69 bral handle_address_fault
70 .align 2
71 bral handle_protection_fault
72 .align 2
73 bral handle_protection_fault
74 .align 2
75 bral do_dtlb_modified
76
77 /*
78 * r0 : PGD/PT/PTE
79 * r1 : Offending address
80 * r2 : Scratch register
81 * r3 : Cause (5, 12 or 13)
82 */
83#define tlbmiss_save pushm r0-r3
84#define tlbmiss_restore popm r0-r3
85
86 .section .tlbx.ex.text,"ax",@progbits
87 .global itlb_miss
88itlb_miss:
89 tlbmiss_save
90 rjmp tlb_miss_common
91
92 .section .tlbr.ex.text,"ax",@progbits
93dtlb_miss_read:
94 tlbmiss_save
95 rjmp tlb_miss_common
96
97 .section .tlbw.ex.text,"ax",@progbits
98dtlb_miss_write:
99 tlbmiss_save
100
101 .global tlb_miss_common
102tlb_miss_common:
103 mfsr r0, SYSREG_PTBR
104 mfsr r1, SYSREG_TLBEAR
105
106 /* Is it the vmalloc space? */
107 bld r1, 31
108 brcs handle_vmalloc_miss
109
110 /* First level lookup */
111pgtbl_lookup:
112 lsr r2, r1, PGDIR_SHIFT
113 ld.w r0, r0[r2 << 2]
114 bld r0, _PAGE_BIT_PRESENT
115 brcc page_table_not_present
116
117 /* TODO: Check access rights on page table if necessary */
118
119 /* Translate to virtual address in P1. */
120 andl r0, 0xf000
121 sbr r0, 31
122
123 /* Second level lookup */
124 lsl r1, (32 - PGDIR_SHIFT)
125 lsr r1, (32 - PGDIR_SHIFT) + PAGE_SHIFT
126 add r2, r0, r1 << 2
127 ld.w r1, r2[0]
128 bld r1, _PAGE_BIT_PRESENT
129 brcc page_not_present
130
131 /* Mark the page as accessed */
132 sbr r1, _PAGE_BIT_ACCESSED
133 st.w r2[0], r1
134
135 /* Drop software flags */
136 andl r1, _PAGE_FLAGS_HARDWARE_MASK & 0xffff
137 mtsr SYSREG_TLBELO, r1
138
139 /* Figure out which entry we want to replace */
140 mfsr r0, SYSREG_TLBARLO
141 clz r2, r0
142 brcc 1f
143 mov r1, -1 /* All entries have been accessed, */
144 mtsr SYSREG_TLBARLO, r1 /* so reset TLBAR */
145 mov r2, 0 /* and start at 0 */
1461: mfsr r1, SYSREG_MMUCR
147 lsl r2, 14
148 andl r1, 0x3fff, COH
149 or r1, r2
150 mtsr SYSREG_MMUCR, r1
151
152 tlbw
153
154 tlbmiss_restore
155 rete
156
157handle_vmalloc_miss:
158 /* Simply do the lookup in init's page table */
159 mov r0, lo(swapper_pg_dir)
160 orh r0, hi(swapper_pg_dir)
161 rjmp pgtbl_lookup
162
163
164 /* --- System Call --- */
165
166 .section .scall.text,"ax",@progbits
167system_call:
168 pushm r12 /* r12_orig */
169 stmts --sp, r0-lr
170 zero_fp
171 mfsr r0, SYSREG_RAR_SUP
172 mfsr r1, SYSREG_RSR_SUP
173 stm --sp, r0-r1
174
175 /* check for syscall tracing */
176 get_thread_info r0
177 ld.w r1, r0[TI_flags]
178 bld r1, TIF_SYSCALL_TRACE
179 brcs syscall_trace_enter
180
181syscall_trace_cont:
182 cp.w r8, NR_syscalls
183 brhs syscall_badsys
184
185 lddpc lr, syscall_table_addr
186 ld.w lr, lr[r8 << 2]
187 mov r8, r5 /* 5th argument (6th is pushed by stub) */
188 icall lr
189
190 .global syscall_return
191syscall_return:
192 get_thread_info r0
193 mask_interrupts /* make sure we don't miss an interrupt
194 setting need_resched or sigpending
195 between sampling and the rets */
196
197 /* Store the return value so that the correct value is loaded below */
198 stdsp sp[REG_R12], r12
199
200 ld.w r1, r0[TI_flags]
201 andl r1, _TIF_ALLWORK_MASK, COH
202 brne syscall_exit_work
203
204syscall_exit_cont:
205 popm r8-r9
206 mtsr SYSREG_RAR_SUP, r8
207 mtsr SYSREG_RSR_SUP, r9
208 ldmts sp++, r0-lr
209 sub sp, -4 /* r12_orig */
210 rets
211
212 .align 2
213syscall_table_addr:
214 .long sys_call_table
215
216syscall_badsys:
217 mov r12, -ENOSYS
218 rjmp syscall_return
219
220 .global ret_from_fork
221ret_from_fork:
222 rcall schedule_tail
223
224 /* check for syscall tracing */
225 get_thread_info r0
226 ld.w r1, r0[TI_flags]
227 andl r1, _TIF_ALLWORK_MASK, COH
228 brne syscall_exit_work
229 rjmp syscall_exit_cont
230
231syscall_trace_enter:
232 pushm r8-r12
233 rcall syscall_trace
234 popm r8-r12
235 rjmp syscall_trace_cont
236
237syscall_exit_work:
238 bld r1, TIF_SYSCALL_TRACE
239 brcc 1f
240 unmask_interrupts
241 rcall syscall_trace
242 mask_interrupts
243 ld.w r1, r0[TI_flags]
244
2451: bld r1, TIF_NEED_RESCHED
246 brcc 2f
247 unmask_interrupts
248 rcall schedule
249 mask_interrupts
250 ld.w r1, r0[TI_flags]
251 rjmp 1b
252
2532: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK
254 tst r1, r2
255 breq 3f
256 unmask_interrupts
257 mov r12, sp
258 mov r11, r0
259 rcall do_notify_resume
260 mask_interrupts
261 ld.w r1, r0[TI_flags]
262 rjmp 1b
263
2643: bld r1, TIF_BREAKPOINT
265 brcc syscall_exit_cont
266 mfsr r3, SYSREG_TLBEHI
267 lddsp r2, sp[REG_PC]
268 andl r3, 0xff, COH
269 lsl r3, 1
270 sbr r3, 30
271 sbr r3, 0
272 mtdr DBGREG_BWA2A, r2
273 mtdr DBGREG_BWC2A, r3
274 rjmp syscall_exit_cont
275
276
277 /* The slow path of the TLB miss handler */
278page_table_not_present:
279page_not_present:
280 tlbmiss_restore
281 sub sp, 4
282 stmts --sp, r0-lr
283 rcall save_full_context_ex
284 mfsr r12, SYSREG_ECR
285 mov r11, sp
286 rcall do_page_fault
287 rjmp ret_from_exception
288
289 /* This function expects to find offending PC in SYSREG_RAR_EX */
290save_full_context_ex:
291 mfsr r8, SYSREG_RSR_EX
292 mov r12, r8
293 andh r8, (MODE_MASK >> 16), COH
294 mfsr r11, SYSREG_RAR_EX
295 brne 2f
296
2971: pushm r11, r12 /* PC and SR */
298 unmask_exceptions
299 ret r12
300
3012: sub r10, sp, -(FRAME_SIZE_FULL - REG_LR)
302 stdsp sp[4], r10 /* replace saved SP */
303 rjmp 1b
304
305 /* Low-level exception handlers */
306handle_critical:
307 pushm r12
308 pushm r0-r12
309 rcall save_full_context_ex
310 mfsr r12, SYSREG_ECR
311 mov r11, sp
312 rcall do_critical_exception
313
314 /* We should never get here... */
315bad_return:
316 sub r12, pc, (. - 1f)
317 bral panic
318 .align 2
3191: .asciz "Return from critical exception!"
320
321 .align 1
322do_bus_error_write:
323 sub sp, 4
324 stmts --sp, r0-lr
325 rcall save_full_context_ex
326 mov r11, 1
327 rjmp 1f
328
329do_bus_error_read:
330 sub sp, 4
331 stmts --sp, r0-lr
332 rcall save_full_context_ex
333 mov r11, 0
3341: mfsr r12, SYSREG_BEAR
335 mov r10, sp
336 rcall do_bus_error
337 rjmp ret_from_exception
338
339 .align 1
340do_nmi_ll:
341 sub sp, 4
342 stmts --sp, r0-lr
343 /* FIXME: Make sure RAR_NMI and RSR_NMI are pushed instead of *_EX */
344 rcall save_full_context_ex
345 mfsr r12, SYSREG_ECR
346 mov r11, sp
347 rcall do_nmi
348 rjmp bad_return
349
350handle_address_fault:
351 sub sp, 4
352 stmts --sp, r0-lr
353 rcall save_full_context_ex
354 mfsr r12, SYSREG_ECR
355 mov r11, sp
356 rcall do_address_exception
357 rjmp ret_from_exception
358
359handle_protection_fault:
360 sub sp, 4
361 stmts --sp, r0-lr
362 rcall save_full_context_ex
363 mfsr r12, SYSREG_ECR
364 mov r11, sp
365 rcall do_page_fault
366 rjmp ret_from_exception
367
368 .align 1
369do_illegal_opcode_ll:
370 sub sp, 4
371 stmts --sp, r0-lr
372 rcall save_full_context_ex
373 mfsr r12, SYSREG_ECR
374 mov r11, sp
375 rcall do_illegal_opcode
376 rjmp ret_from_exception
377
378do_dtlb_modified:
379 pushm r0-r3
380 mfsr r1, SYSREG_TLBEAR
381 mfsr r0, SYSREG_PTBR
382 lsr r2, r1, PGDIR_SHIFT
383 ld.w r0, r0[r2 << 2]
384 lsl r1, (32 - PGDIR_SHIFT)
385 lsr r1, (32 - PGDIR_SHIFT) + PAGE_SHIFT
386
387 /* Translate to virtual address in P1 */
388 andl r0, 0xf000
389 sbr r0, 31
390 add r2, r0, r1 << 2
391 ld.w r3, r2[0]
392 sbr r3, _PAGE_BIT_DIRTY
393 mov r0, r3
394 st.w r2[0], r3
395
396 /* The page table is up-to-date. Update the TLB entry as well */
397 andl r0, lo(_PAGE_FLAGS_HARDWARE_MASK)
398 mtsr SYSREG_TLBELO, r0
399
400 /* MMUCR[DRP] is updated automatically, so let's go... */
401 tlbw
402
403 popm r0-r3
404 rete
405
406do_fpe_ll:
407 sub sp, 4
408 stmts --sp, r0-lr
409 rcall save_full_context_ex
410 unmask_interrupts
411 mov r12, 26
412 mov r11, sp
413 rcall do_fpe
414 rjmp ret_from_exception
415
416ret_from_exception:
417 mask_interrupts
418 lddsp r4, sp[REG_SR]
419 andh r4, (MODE_MASK >> 16), COH
420 brne fault_resume_kernel
421
422 get_thread_info r0
423 ld.w r1, r0[TI_flags]
424 andl r1, _TIF_WORK_MASK, COH
425 brne fault_exit_work
426
427fault_resume_user:
428 popm r8-r9
429 mask_exceptions
430 mtsr SYSREG_RAR_EX, r8
431 mtsr SYSREG_RSR_EX, r9
432 ldmts sp++, r0-lr
433 sub sp, -4
434 rete
435
436fault_resume_kernel:
437#ifdef CONFIG_PREEMPT
438 get_thread_info r0
439 ld.w r2, r0[TI_preempt_count]
440 cp.w r2, 0
441 brne 1f
442 ld.w r1, r0[TI_flags]
443 bld r1, TIF_NEED_RESCHED
444 brcc 1f
445 lddsp r4, sp[REG_SR]
446 bld r4, SYSREG_GM_OFFSET
447 brcs 1f
448 rcall preempt_schedule_irq
4491:
450#endif
451
452 popm r8-r9
453 mask_exceptions
454 mfsr r1, SYSREG_SR
455 mtsr SYSREG_RAR_EX, r8
456 mtsr SYSREG_RSR_EX, r9
457 popm lr
458 sub sp, -4 /* ignore SP */
459 popm r0-r12
460 sub sp, -4 /* ignore r12_orig */
461 rete
462
463irq_exit_work:
464 /* Switch to exception mode so that we can share the same code. */
465 mfsr r8, SYSREG_SR
466 cbr r8, SYSREG_M0_OFFSET
467 orh r8, hi(SYSREG_BIT(M1) | SYSREG_BIT(M2))
468 mtsr SYSREG_SR, r8
469 sub pc, -2
470 get_thread_info r0
471 ld.w r1, r0[TI_flags]
472
473fault_exit_work:
474 bld r1, TIF_NEED_RESCHED
475 brcc 1f
476 unmask_interrupts
477 rcall schedule
478 mask_interrupts
479 ld.w r1, r0[TI_flags]
480 rjmp fault_exit_work
481
4821: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK
483 tst r1, r2
484 breq 2f
485 unmask_interrupts
486 mov r12, sp
487 mov r11, r0
488 rcall do_notify_resume
489 mask_interrupts
490 ld.w r1, r0[TI_flags]
491 rjmp fault_exit_work
492
4932: bld r1, TIF_BREAKPOINT
494 brcc fault_resume_user
495 mfsr r3, SYSREG_TLBEHI
496 lddsp r2, sp[REG_PC]
497 andl r3, 0xff, COH
498 lsl r3, 1
499 sbr r3, 30
500 sbr r3, 0
501 mtdr DBGREG_BWA2A, r2
502 mtdr DBGREG_BWC2A, r3
503 rjmp fault_resume_user
504
505 /* If we get a debug trap from privileged context we end up here */
506handle_debug_priv:
507 /* Fix up LR and SP in regs. r11 contains the mode we came from */
508 mfsr r8, SYSREG_SR
509 mov r9, r8
510 andh r8, hi(~MODE_MASK)
511 or r8, r11
512 mtsr SYSREG_SR, r8
513 sub pc, -2
514 stdsp sp[REG_LR], lr
515 mtsr SYSREG_SR, r9
516 sub pc, -2
517 sub r10, sp, -FRAME_SIZE_FULL
518 stdsp sp[REG_SP], r10
519 mov r12, sp
520 rcall do_debug_priv
521
522 /* Now, put everything back */
523 ssrf SR_EM_BIT
524 popm r10, r11
525 mtsr SYSREG_RAR_DBG, r10
526 mtsr SYSREG_RSR_DBG, r11
527 mfsr r8, SYSREG_SR
528 mov r9, r8
529 andh r8, hi(~MODE_MASK)
530 andh r11, hi(MODE_MASK)
531 or r8, r11
532 mtsr SYSREG_SR, r8
533 sub pc, -2
534 popm lr
535 mtsr SYSREG_SR, r9
536 sub pc, -2
537 sub sp, -4 /* skip SP */
538 popm r0-r12
539 sub sp, -4
540 retd
541
542 /*
543 * At this point, everything is masked, that is, interrupts,
544 * exceptions and debugging traps. We might get called from
545 * interrupt or exception context in some rare cases, but this
546 * will be taken care of by do_debug(), so we're not going to
547 * do a 100% correct context save here.
548 */
549handle_debug:
550 sub sp, 4 /* r12_orig */
551 stmts --sp, r0-lr
552 mfsr r10, SYSREG_RAR_DBG
553 mfsr r11, SYSREG_RSR_DBG
554 unmask_exceptions
555 pushm r10,r11
556 andh r11, (MODE_MASK >> 16), COH
557 brne handle_debug_priv
558
559 mov r12, sp
560 rcall do_debug
561
562 lddsp r10, sp[REG_SR]
563 andh r10, (MODE_MASK >> 16), COH
564 breq debug_resume_user
565
566debug_restore_all:
567 popm r10,r11
568 mask_exceptions
569 mtsr SYSREG_RSR_DBG, r11
570 mtsr SYSREG_RAR_DBG, r10
571 ldmts sp++, r0-lr
572 sub sp, -4
573 retd
574
575debug_resume_user:
576 get_thread_info r0
577 mask_interrupts
578
579 ld.w r1, r0[TI_flags]
580 andl r1, _TIF_DBGWORK_MASK, COH
581 breq debug_restore_all
582
5831: bld r1, TIF_NEED_RESCHED
584 brcc 2f
585 unmask_interrupts
586 rcall schedule
587 mask_interrupts
588 ld.w r1, r0[TI_flags]
589 rjmp 1b
590
5912: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK
592 tst r1, r2
593 breq 3f
594 unmask_interrupts
595 mov r12, sp
596 mov r11, r0
597 rcall do_notify_resume
598 mask_interrupts
599 ld.w r1, r0[TI_flags]
600 rjmp 1b
601
6023: bld r1, TIF_SINGLE_STEP
603 brcc debug_restore_all
604 mfdr r2, DBGREG_DC
605 sbr r2, DC_SS_BIT
606 mtdr DBGREG_DC, r2
607 rjmp debug_restore_all
608
609 .set rsr_int0, SYSREG_RSR_INT0
610 .set rsr_int1, SYSREG_RSR_INT1
611 .set rsr_int2, SYSREG_RSR_INT2
612 .set rsr_int3, SYSREG_RSR_INT3
613 .set rar_int0, SYSREG_RAR_INT0
614 .set rar_int1, SYSREG_RAR_INT1
615 .set rar_int2, SYSREG_RAR_INT2
616 .set rar_int3, SYSREG_RAR_INT3
617
618 .macro IRQ_LEVEL level
619 .type irq_level\level, @function
620irq_level\level:
621 sub sp, 4 /* r12_orig */
622 stmts --sp,r0-lr
623 mfsr r8, rar_int\level
624 mfsr r9, rsr_int\level
625 pushm r8-r9
626
627 mov r11, sp
628 mov r12, \level
629
630 rcall do_IRQ
631
632 lddsp r4, sp[REG_SR]
633 andh r4, (MODE_MASK >> 16), COH
634#ifdef CONFIG_PREEMPT
635 brne 2f
636#else
637 brne 1f
638#endif
639
640 get_thread_info r0
641 ld.w r1, r0[TI_flags]
642 andl r1, _TIF_WORK_MASK, COH
643 brne irq_exit_work
644
6451: popm r8-r9
646 mtsr rar_int\level, r8
647 mtsr rsr_int\level, r9
648 ldmts sp++,r0-lr
649 sub sp, -4 /* ignore r12_orig */
650 rete
651
652#ifdef CONFIG_PREEMPT
6532:
654 get_thread_info r0
655 ld.w r2, r0[TI_preempt_count]
656 cp.w r2, 0
657 brne 1b
658 ld.w r1, r0[TI_flags]
659 bld r1, TIF_NEED_RESCHED
660 brcc 1b
661 lddsp r4, sp[REG_SR]
662 bld r4, SYSREG_GM_OFFSET
663 brcs 1b
664 rcall preempt_schedule_irq
665 rjmp 1b
666#endif
667 .endm
668
669 .section .irq.text,"ax",@progbits
670
671 .global irq_level0
672 .global irq_level1
673 .global irq_level2
674 .global irq_level3
675 IRQ_LEVEL 0
676 IRQ_LEVEL 1
677 IRQ_LEVEL 2
678 IRQ_LEVEL 3
diff --git a/arch/avr32/kernel/head.S b/arch/avr32/kernel/head.S
new file mode 100644
index 000000000000..773b7ad87be9
--- /dev/null
+++ b/arch/avr32/kernel/head.S
@@ -0,0 +1,45 @@
1/*
2 * Non-board-specific low-level startup code
3 *
4 * Copyright (C) 2004-2006 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/linkage.h>
11
12#include <asm/page.h>
13#include <asm/thread_info.h>
14#include <asm/sysreg.h>
15
16 .section .init.text,"ax"
17 .global kernel_entry
18kernel_entry:
19 /* Initialize status register */
20 lddpc r0, init_sr
21 mtsr SYSREG_SR, r0
22
23 /* Set initial stack pointer */
24 lddpc sp, stack_addr
25 sub sp, -THREAD_SIZE
26
27#ifdef CONFIG_FRAME_POINTER
28 /* Mark last stack frame */
29 mov lr, 0
30 mov r7, 0
31#endif
32
33 /* Set up the PIO, SDRAM controller, early printk, etc. */
34 rcall board_early_init
35
36 /* Start the show */
37 lddpc pc, kernel_start_addr
38
39 .align 2
40init_sr:
41 .long 0x007f0000 /* Supervisor mode, everything masked */
42stack_addr:
43 .long init_thread_union
44kernel_start_addr:
45 .long start_kernel
diff --git a/arch/avr32/kernel/init_task.c b/arch/avr32/kernel/init_task.c
new file mode 100644
index 000000000000..effcacf9d1a2
--- /dev/null
+++ b/arch/avr32/kernel/init_task.c
@@ -0,0 +1,38 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#include <linux/module.h>
9#include <linux/fs.h>
10#include <linux/sched.h>
11#include <linux/init_task.h>
12#include <linux/mqueue.h>
13
14#include <asm/pgtable.h>
15
16static struct fs_struct init_fs = INIT_FS;
17static struct files_struct init_files = INIT_FILES;
18static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
19static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
20struct mm_struct init_mm = INIT_MM(init_mm);
21
22EXPORT_SYMBOL(init_mm);
23
24/*
25 * Initial thread structure. Must be aligned on an 8192-byte boundary.
26 */
27union thread_union init_thread_union
28 __attribute__((__section__(".data.init_task"))) =
29 { INIT_THREAD_INFO(init_task) };
30
31/*
32 * Initial task structure.
33 *
34 * All other task structs will be allocated on slabs in fork.c
35 */
36struct task_struct init_task = INIT_TASK(init_task);
37
38EXPORT_SYMBOL(init_task);
diff --git a/arch/avr32/kernel/irq.c b/arch/avr32/kernel/irq.c
new file mode 100644
index 000000000000..856f3548e664
--- /dev/null
+++ b/arch/avr32/kernel/irq.c
@@ -0,0 +1,71 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * Based on arch/i386/kernel/irq.c
5 * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This file contains the code used by various IRQ handling routines:
12 * asking for different IRQ's should be done through these routines
13 * instead of just grabbing them. Thus setups with different IRQ numbers
14 * shouldn't result in any weird surprises, and installing new handlers
15 * should be easier.
16 *
17 * IRQ's are in fact implemented a bit like signal handlers for the kernel.
18 * Naturally it's not a 1:1 relation, but there are similarities.
19 */
20
21#include <linux/interrupt.h>
22#include <linux/irq.h>
23#include <linux/kernel_stat.h>
24#include <linux/proc_fs.h>
25#include <linux/seq_file.h>
26#include <linux/sysdev.h>
27
28/*
29 * 'what should we do if we get a hw irq event on an illegal vector'.
30 * each architecture has to answer this themselves.
31 */
32void ack_bad_irq(unsigned int irq)
33{
34 printk("unexpected IRQ %u\n", irq);
35}
36
37#ifdef CONFIG_PROC_FS
38int show_interrupts(struct seq_file *p, void *v)
39{
40 int i = *(loff_t *)v, cpu;
41 struct irqaction *action;
42 unsigned long flags;
43
44 if (i == 0) {
45 seq_puts(p, " ");
46 for_each_online_cpu(cpu)
47 seq_printf(p, "CPU%d ", cpu);
48 seq_putc(p, '\n');
49 }
50
51 if (i < NR_IRQS) {
52 spin_lock_irqsave(&irq_desc[i].lock, flags);
53 action = irq_desc[i].action;
54 if (!action)
55 goto unlock;
56
57 seq_printf(p, "%3d: ", i);
58 for_each_online_cpu(cpu)
59 seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
60 seq_printf(p, " %s", action->name);
61 for (action = action->next; action; action = action->next)
62 seq_printf(p, ", %s", action->name);
63
64 seq_putc(p, '\n');
65 unlock:
66 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
67 }
68
69 return 0;
70}
71#endif
diff --git a/arch/avr32/kernel/kprobes.c b/arch/avr32/kernel/kprobes.c
new file mode 100644
index 000000000000..6caf9e8d8080
--- /dev/null
+++ b/arch/avr32/kernel/kprobes.c
@@ -0,0 +1,270 @@
1/*
2 * Kernel Probes (KProbes)
3 *
4 * Copyright (C) 2005-2006 Atmel Corporation
5 *
6 * Based on arch/ppc64/kernel/kprobes.c
7 * Copyright (C) IBM Corporation, 2002, 2004
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/kprobes.h>
15#include <linux/ptrace.h>
16
17#include <asm/cacheflush.h>
18#include <asm/kdebug.h>
19#include <asm/ocd.h>
20
21DEFINE_PER_CPU(struct kprobe *, current_kprobe);
22static unsigned long kprobe_status;
23static struct pt_regs jprobe_saved_regs;
24
25int __kprobes arch_prepare_kprobe(struct kprobe *p)
26{
27 int ret = 0;
28
29 if ((unsigned long)p->addr & 0x01) {
30 printk("Attempt to register kprobe at an unaligned address\n");
31 ret = -EINVAL;
32 }
33
34 /* XXX: Might be a good idea to check if p->addr is a valid
35 * kernel address as well... */
36
37 if (!ret) {
38 pr_debug("copy kprobe at %p\n", p->addr);
39 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
40 p->opcode = *p->addr;
41 }
42
43 return ret;
44}
45
46void __kprobes arch_arm_kprobe(struct kprobe *p)
47{
48 pr_debug("arming kprobe at %p\n", p->addr);
49 *p->addr = BREAKPOINT_INSTRUCTION;
50 flush_icache_range((unsigned long)p->addr,
51 (unsigned long)p->addr + sizeof(kprobe_opcode_t));
52}
53
54void __kprobes arch_disarm_kprobe(struct kprobe *p)
55{
56 pr_debug("disarming kprobe at %p\n", p->addr);
57 *p->addr = p->opcode;
58 flush_icache_range((unsigned long)p->addr,
59 (unsigned long)p->addr + sizeof(kprobe_opcode_t));
60}
61
62static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
63{
64 unsigned long dc;
65
66 pr_debug("preparing to singlestep over %p (PC=%08lx)\n",
67 p->addr, regs->pc);
68
69 BUG_ON(!(sysreg_read(SR) & SYSREG_BIT(SR_D)));
70
71 dc = __mfdr(DBGREG_DC);
72 dc |= DC_SS;
73 __mtdr(DBGREG_DC, dc);
74
75 /*
76 * We must run the instruction from its original location
77 * since it may actually reference PC.
78 *
79 * TODO: Do the instruction replacement directly in icache.
80 */
81 *p->addr = p->opcode;
82 flush_icache_range((unsigned long)p->addr,
83 (unsigned long)p->addr + sizeof(kprobe_opcode_t));
84}
85
86static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
87{
88 unsigned long dc;
89
90 pr_debug("resuming execution at PC=%08lx\n", regs->pc);
91
92 dc = __mfdr(DBGREG_DC);
93 dc &= ~DC_SS;
94 __mtdr(DBGREG_DC, dc);
95
96 *p->addr = BREAKPOINT_INSTRUCTION;
97 flush_icache_range((unsigned long)p->addr,
98 (unsigned long)p->addr + sizeof(kprobe_opcode_t));
99}
100
101static void __kprobes set_current_kprobe(struct kprobe *p)
102{
103 __get_cpu_var(current_kprobe) = p;
104}
105
106static int __kprobes kprobe_handler(struct pt_regs *regs)
107{
108 struct kprobe *p;
109 void *addr = (void *)regs->pc;
110 int ret = 0;
111
112 pr_debug("kprobe_handler: kprobe_running=%d\n",
113 kprobe_running());
114
115 /*
116 * We don't want to be preempted for the entire
117 * duration of kprobe processing
118 */
119 preempt_disable();
120
121 /* Check that we're not recursing */
122 if (kprobe_running()) {
123 p = get_kprobe(addr);
124 if (p) {
125 if (kprobe_status == KPROBE_HIT_SS) {
126 printk("FIXME: kprobe hit while single-stepping!\n");
127 goto no_kprobe;
128 }
129
130 printk("FIXME: kprobe hit while handling another kprobe\n");
131 goto no_kprobe;
132 } else {
133 p = kprobe_running();
134 if (p->break_handler && p->break_handler(p, regs))
135 goto ss_probe;
136 }
137 /* If it's not ours, can't be delete race, (we hold lock). */
138 goto no_kprobe;
139 }
140
141 p = get_kprobe(addr);
142 if (!p)
143 goto no_kprobe;
144
145 kprobe_status = KPROBE_HIT_ACTIVE;
146 set_current_kprobe(p);
147 if (p->pre_handler && p->pre_handler(p, regs))
148 /* handler has already set things up, so skip ss setup */
149 return 1;
150
151ss_probe:
152 prepare_singlestep(p, regs);
153 kprobe_status = KPROBE_HIT_SS;
154 return 1;
155
156no_kprobe:
157 return ret;
158}
159
160static int __kprobes post_kprobe_handler(struct pt_regs *regs)
161{
162 struct kprobe *cur = kprobe_running();
163
164 pr_debug("post_kprobe_handler, cur=%p\n", cur);
165
166 if (!cur)
167 return 0;
168
169 if (cur->post_handler) {
170 kprobe_status = KPROBE_HIT_SSDONE;
171 cur->post_handler(cur, regs, 0);
172 }
173
174 resume_execution(cur, regs);
175 reset_current_kprobe();
176 preempt_enable_no_resched();
177
178 return 1;
179}
180
181static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
182{
183 struct kprobe *cur = kprobe_running();
184
185 pr_debug("kprobe_fault_handler: trapnr=%d\n", trapnr);
186
187 if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
188 return 1;
189
190 if (kprobe_status & KPROBE_HIT_SS) {
191 resume_execution(cur, regs);
192 preempt_enable_no_resched();
193 }
194 return 0;
195}
196
197/*
198 * Wrapper routine to for handling exceptions.
199 */
200int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
201 unsigned long val, void *data)
202{
203 struct die_args *args = (struct die_args *)data;
204 int ret = NOTIFY_DONE;
205
206 pr_debug("kprobe_exceptions_notify: val=%lu, data=%p\n",
207 val, data);
208
209 switch (val) {
210 case DIE_BREAKPOINT:
211 if (kprobe_handler(args->regs))
212 ret = NOTIFY_STOP;
213 break;
214 case DIE_SSTEP:
215 if (post_kprobe_handler(args->regs))
216 ret = NOTIFY_STOP;
217 break;
218 case DIE_FAULT:
219 if (kprobe_running()
220 && kprobe_fault_handler(args->regs, args->trapnr))
221 ret = NOTIFY_STOP;
222 break;
223 default:
224 break;
225 }
226
227 return ret;
228}
229
230int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
231{
232 struct jprobe *jp = container_of(p, struct jprobe, kp);
233
234 memcpy(&jprobe_saved_regs, regs, sizeof(struct pt_regs));
235
236 /*
237 * TODO: We should probably save some of the stack here as
238 * well, since gcc may pass arguments on the stack for certain
239 * functions (lots of arguments, large aggregates, varargs)
240 */
241
242 /* setup return addr to the jprobe handler routine */
243 regs->pc = (unsigned long)jp->entry;
244 return 1;
245}
246
247void __kprobes jprobe_return(void)
248{
249 asm volatile("breakpoint" ::: "memory");
250}
251
252int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
253{
254 /*
255 * FIXME - we should ideally be validating that we got here 'cos
256 * of the "trap" in jprobe_return() above, before restoring the
257 * saved regs...
258 */
259 memcpy(regs, &jprobe_saved_regs, sizeof(struct pt_regs));
260 return 1;
261}
262
263int __init arch_init_kprobes(void)
264{
265 printk("KPROBES: Enabling monitor mode (MM|DBE)...\n");
266 __mtdr(DBGREG_DC, DC_MM | DC_DBE);
267
268 /* TODO: Register kretprobe trampoline */
269 return 0;
270}
diff --git a/arch/avr32/kernel/module.c b/arch/avr32/kernel/module.c
new file mode 100644
index 000000000000..dfc32f2817b6
--- /dev/null
+++ b/arch/avr32/kernel/module.c
@@ -0,0 +1,324 @@
1/*
2 * AVR32-specific kernel module loader
3 *
4 * Copyright (C) 2005-2006 Atmel Corporation
5 *
6 * GOT initialization parts are based on the s390 version
7 * Copyright (C) 2002, 2003 IBM Deutschland Entwicklung GmbH,
8 * IBM Corporation
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/moduleloader.h>
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/elf.h>
19#include <linux/vmalloc.h>
20
21void *module_alloc(unsigned long size)
22{
23 if (size == 0)
24 return NULL;
25 return vmalloc(size);
26}
27
28void module_free(struct module *mod, void *module_region)
29{
30 vfree(mod->arch.syminfo);
31 mod->arch.syminfo = NULL;
32
33 vfree(module_region);
34 /* FIXME: if module_region == mod->init_region, trim exception
35 * table entries. */
36}
37
38static inline int check_rela(Elf32_Rela *rela, struct module *module,
39 char *strings, Elf32_Sym *symbols)
40{
41 struct mod_arch_syminfo *info;
42
43 info = module->arch.syminfo + ELF32_R_SYM(rela->r_info);
44 switch (ELF32_R_TYPE(rela->r_info)) {
45 case R_AVR32_GOT32:
46 case R_AVR32_GOT16:
47 case R_AVR32_GOT8:
48 case R_AVR32_GOT21S:
49 case R_AVR32_GOT18SW: /* mcall */
50 case R_AVR32_GOT16S: /* ld.w */
51 if (rela->r_addend != 0) {
52 printk(KERN_ERR
53 "GOT relocation against %s at offset %u with addend\n",
54 strings + symbols[ELF32_R_SYM(rela->r_info)].st_name,
55 rela->r_offset);
56 return -ENOEXEC;
57 }
58 if (info->got_offset == -1UL) {
59 info->got_offset = module->arch.got_size;
60 module->arch.got_size += sizeof(void *);
61 }
62 pr_debug("GOT[%3lu] %s\n", info->got_offset,
63 strings + symbols[ELF32_R_SYM(rela->r_info)].st_name);
64 break;
65 }
66
67 return 0;
68}
69
70int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
71 char *secstrings, struct module *module)
72{
73 Elf32_Shdr *symtab;
74 Elf32_Sym *symbols;
75 Elf32_Rela *rela;
76 char *strings;
77 int nrela, i, j;
78 int ret;
79
80 /* Find the symbol table */
81 symtab = NULL;
82 for (i = 0; i < hdr->e_shnum; i++)
83 switch (sechdrs[i].sh_type) {
84 case SHT_SYMTAB:
85 symtab = &sechdrs[i];
86 break;
87 }
88 if (!symtab) {
89 printk(KERN_ERR "module %s: no symbol table\n", module->name);
90 return -ENOEXEC;
91 }
92
93 /* Allocate room for one syminfo structure per symbol. */
94 module->arch.nsyms = symtab->sh_size / sizeof(Elf_Sym);
95 module->arch.syminfo = vmalloc(module->arch.nsyms
96 * sizeof(struct mod_arch_syminfo));
97 if (!module->arch.syminfo)
98 return -ENOMEM;
99
100 symbols = (void *)hdr + symtab->sh_offset;
101 strings = (void *)hdr + sechdrs[symtab->sh_link].sh_offset;
102 for (i = 0; i < module->arch.nsyms; i++) {
103 if (symbols[i].st_shndx == SHN_UNDEF &&
104 strcmp(strings + symbols[i].st_name,
105 "_GLOBAL_OFFSET_TABLE_") == 0)
106 /* "Define" it as absolute. */
107 symbols[i].st_shndx = SHN_ABS;
108 module->arch.syminfo[i].got_offset = -1UL;
109 module->arch.syminfo[i].got_initialized = 0;
110 }
111
112 /* Allocate GOT entries for symbols that need it. */
113 module->arch.got_size = 0;
114 for (i = 0; i < hdr->e_shnum; i++) {
115 if (sechdrs[i].sh_type != SHT_RELA)
116 continue;
117 nrela = sechdrs[i].sh_size / sizeof(Elf32_Rela);
118 rela = (void *)hdr + sechdrs[i].sh_offset;
119 for (j = 0; j < nrela; j++) {
120 ret = check_rela(rela + j, module,
121 strings, symbols);
122 if (ret)
123 goto out_free_syminfo;
124 }
125 }
126
127 /*
128 * Increase core size to make room for GOT and set start
129 * offset for GOT.
130 */
131 module->core_size = ALIGN(module->core_size, 4);
132 module->arch.got_offset = module->core_size;
133 module->core_size += module->arch.got_size;
134
135 return 0;
136
137out_free_syminfo:
138 vfree(module->arch.syminfo);
139 module->arch.syminfo = NULL;
140
141 return ret;
142}
143
144static inline int reloc_overflow(struct module *module, const char *reloc_name,
145 Elf32_Addr relocation)
146{
147 printk(KERN_ERR "module %s: Value %lx does not fit relocation %s\n",
148 module->name, (unsigned long)relocation, reloc_name);
149 return -ENOEXEC;
150}
151
152#define get_u16(loc) (*((uint16_t *)loc))
153#define put_u16(loc, val) (*((uint16_t *)loc) = (val))
154
155int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
156 unsigned int symindex, unsigned int relindex,
157 struct module *module)
158{
159 Elf32_Shdr *symsec = sechdrs + symindex;
160 Elf32_Shdr *relsec = sechdrs + relindex;
161 Elf32_Shdr *dstsec = sechdrs + relsec->sh_info;
162 Elf32_Rela *rel = (void *)relsec->sh_addr;
163 unsigned int i;
164 int ret = 0;
165
166 for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rela); i++, rel++) {
167 struct mod_arch_syminfo *info;
168 Elf32_Sym *sym;
169 Elf32_Addr relocation;
170 uint32_t *location;
171 uint32_t value;
172
173 location = (void *)dstsec->sh_addr + rel->r_offset;
174 sym = (Elf32_Sym *)symsec->sh_addr + ELF32_R_SYM(rel->r_info);
175 relocation = sym->st_value + rel->r_addend;
176
177 info = module->arch.syminfo + ELF32_R_SYM(rel->r_info);
178
179 /* Initialize GOT entry if necessary */
180 switch (ELF32_R_TYPE(rel->r_info)) {
181 case R_AVR32_GOT32:
182 case R_AVR32_GOT16:
183 case R_AVR32_GOT8:
184 case R_AVR32_GOT21S:
185 case R_AVR32_GOT18SW:
186 case R_AVR32_GOT16S:
187 if (!info->got_initialized) {
188 Elf32_Addr *gotent;
189
190 gotent = (module->module_core
191 + module->arch.got_offset
192 + info->got_offset);
193 *gotent = relocation;
194 info->got_initialized = 1;
195 }
196
197 relocation = info->got_offset;
198 break;
199 }
200
201 switch (ELF32_R_TYPE(rel->r_info)) {
202 case R_AVR32_32:
203 case R_AVR32_32_CPENT:
204 *location = relocation;
205 break;
206 case R_AVR32_22H_PCREL:
207 relocation -= (Elf32_Addr)location;
208 if ((relocation & 0xffe00001) != 0
209 && (relocation & 0xffc00001) != 0xffc00000)
210 return reloc_overflow(module,
211 "R_AVR32_22H_PCREL",
212 relocation);
213 relocation >>= 1;
214
215 value = *location;
216 value = ((value & 0xe1ef0000)
217 | (relocation & 0xffff)
218 | ((relocation & 0x10000) << 4)
219 | ((relocation & 0x1e0000) << 8));
220 *location = value;
221 break;
222 case R_AVR32_11H_PCREL:
223 relocation -= (Elf32_Addr)location;
224 if ((relocation & 0xfffffc01) != 0
225 && (relocation & 0xfffff801) != 0xfffff800)
226 return reloc_overflow(module,
227 "R_AVR32_11H_PCREL",
228 relocation);
229 value = get_u16(location);
230 value = ((value & 0xf00c)
231 | ((relocation & 0x1fe) << 3)
232 | ((relocation & 0x600) >> 9));
233 put_u16(location, value);
234 break;
235 case R_AVR32_9H_PCREL:
236 relocation -= (Elf32_Addr)location;
237 if ((relocation & 0xffffff01) != 0
238 && (relocation & 0xfffffe01) != 0xfffffe00)
239 return reloc_overflow(module,
240 "R_AVR32_9H_PCREL",
241 relocation);
242 value = get_u16(location);
243 value = ((value & 0xf00f)
244 | ((relocation & 0x1fe) << 3));
245 put_u16(location, value);
246 break;
247 case R_AVR32_9UW_PCREL:
248 relocation -= ((Elf32_Addr)location) & 0xfffffffc;
249 if ((relocation & 0xfffffc03) != 0)
250 return reloc_overflow(module,
251 "R_AVR32_9UW_PCREL",
252 relocation);
253 value = get_u16(location);
254 value = ((value & 0xf80f)
255 | ((relocation & 0x1fc) << 2));
256 put_u16(location, value);
257 break;
258 case R_AVR32_GOTPC:
259 /*
260 * R6 = PC - (PC - GOT)
261 *
262 * At this point, relocation contains the
263 * value of PC. Just subtract the value of
264 * GOT, and we're done.
265 */
266 pr_debug("GOTPC: PC=0x%lx, got_offset=0x%lx, core=0x%p\n",
267 relocation, module->arch.got_offset,
268 module->module_core);
269 relocation -= ((unsigned long)module->module_core
270 + module->arch.got_offset);
271 *location = relocation;
272 break;
273 case R_AVR32_GOT18SW:
274 if ((relocation & 0xfffe0003) != 0
275 && (relocation & 0xfffc0003) != 0xffff0000)
276 return reloc_overflow(module, "R_AVR32_GOT18SW",
277 relocation);
278 relocation >>= 2;
279 /* fall through */
280 case R_AVR32_GOT16S:
281 if ((relocation & 0xffff8000) != 0
282 && (relocation & 0xffff0000) != 0xffff0000)
283 return reloc_overflow(module, "R_AVR32_GOT16S",
284 relocation);
285 pr_debug("GOT reloc @ 0x%lx -> %lu\n",
286 rel->r_offset, relocation);
287 value = *location;
288 value = ((value & 0xffff0000)
289 | (relocation & 0xffff));
290 *location = value;
291 break;
292
293 default:
294 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
295 module->name, ELF32_R_TYPE(rel->r_info));
296 return -ENOEXEC;
297 }
298 }
299
300 return ret;
301}
302
303int apply_relocate(Elf32_Shdr *sechdrs, const char *strtab,
304 unsigned int symindex, unsigned int relindex,
305 struct module *module)
306{
307 printk(KERN_ERR "module %s: REL relocations are not supported\n",
308 module->name);
309 return -ENOEXEC;
310}
311
312int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
313 struct module *module)
314{
315 vfree(module->arch.syminfo);
316 module->arch.syminfo = NULL;
317
318 return 0;
319}
320
321void module_arch_cleanup(struct module *module)
322{
323
324}
diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c
new file mode 100644
index 000000000000..317dc50945f2
--- /dev/null
+++ b/arch/avr32/kernel/process.c
@@ -0,0 +1,276 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#include <linux/sched.h>
9#include <linux/module.h>
10#include <linux/kallsyms.h>
11#include <linux/fs.h>
12#include <linux/ptrace.h>
13#include <linux/reboot.h>
14#include <linux/unistd.h>
15
16#include <asm/sysreg.h>
17#include <asm/ocd.h>
18
19void (*pm_power_off)(void) = NULL;
20EXPORT_SYMBOL(pm_power_off);
21
22/*
23 * This file handles the architecture-dependent parts of process handling..
24 */
25
26void cpu_idle(void)
27{
28 /* endless idle loop with no priority at all */
29 while (1) {
30 /* TODO: Enter sleep mode */
31 while (!need_resched())
32 cpu_relax();
33 preempt_enable_no_resched();
34 schedule();
35 preempt_disable();
36 }
37}
38
39void machine_halt(void)
40{
41}
42
43void machine_power_off(void)
44{
45}
46
47void machine_restart(char *cmd)
48{
49 __mtdr(DBGREG_DC, DC_DBE);
50 __mtdr(DBGREG_DC, DC_RES);
51 while (1) ;
52}
53
54/*
55 * PC is actually discarded when returning from a system call -- the
56 * return address must be stored in LR. This function will make sure
57 * LR points to do_exit before starting the thread.
58 *
59 * Also, when returning from fork(), r12 is 0, so we must copy the
60 * argument as well.
61 *
62 * r0 : The argument to the main thread function
63 * r1 : The address of do_exit
64 * r2 : The address of the main thread function
65 */
66asmlinkage extern void kernel_thread_helper(void);
67__asm__(" .type kernel_thread_helper, @function\n"
68 "kernel_thread_helper:\n"
69 " mov r12, r0\n"
70 " mov lr, r2\n"
71 " mov pc, r1\n"
72 " .size kernel_thread_helper, . - kernel_thread_helper");
73
74int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
75{
76 struct pt_regs regs;
77
78 memset(&regs, 0, sizeof(regs));
79
80 regs.r0 = (unsigned long)arg;
81 regs.r1 = (unsigned long)fn;
82 regs.r2 = (unsigned long)do_exit;
83 regs.lr = (unsigned long)kernel_thread_helper;
84 regs.pc = (unsigned long)kernel_thread_helper;
85 regs.sr = MODE_SUPERVISOR;
86
87 return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
88 0, &regs, 0, NULL, NULL);
89}
90EXPORT_SYMBOL(kernel_thread);
91
92/*
93 * Free current thread data structures etc
94 */
95void exit_thread(void)
96{
97 /* nothing to do */
98}
99
100void flush_thread(void)
101{
102 /* nothing to do */
103}
104
105void release_thread(struct task_struct *dead_task)
106{
107 /* do nothing */
108}
109
110static const char *cpu_modes[] = {
111 "Application", "Supervisor", "Interrupt level 0", "Interrupt level 1",
112 "Interrupt level 2", "Interrupt level 3", "Exception", "NMI"
113};
114
115void show_regs(struct pt_regs *regs)
116{
117 unsigned long sp = regs->sp;
118 unsigned long lr = regs->lr;
119 unsigned long mode = (regs->sr & MODE_MASK) >> MODE_SHIFT;
120
121 if (!user_mode(regs))
122 sp = (unsigned long)regs + FRAME_SIZE_FULL;
123
124 print_symbol("PC is at %s\n", instruction_pointer(regs));
125 print_symbol("LR is at %s\n", lr);
126 printk("pc : [<%08lx>] lr : [<%08lx>] %s\n"
127 "sp : %08lx r12: %08lx r11: %08lx\n",
128 instruction_pointer(regs),
129 lr, print_tainted(), sp, regs->r12, regs->r11);
130 printk("r10: %08lx r9 : %08lx r8 : %08lx\n",
131 regs->r10, regs->r9, regs->r8);
132 printk("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
133 regs->r7, regs->r6, regs->r5, regs->r4);
134 printk("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
135 regs->r3, regs->r2, regs->r1, regs->r0);
136 printk("Flags: %c%c%c%c%c\n",
137 regs->sr & SR_Q ? 'Q' : 'q',
138 regs->sr & SR_V ? 'V' : 'v',
139 regs->sr & SR_N ? 'N' : 'n',
140 regs->sr & SR_Z ? 'Z' : 'z',
141 regs->sr & SR_C ? 'C' : 'c');
142 printk("Mode bits: %c%c%c%c%c%c%c%c%c\n",
143 regs->sr & SR_H ? 'H' : 'h',
144 regs->sr & SR_R ? 'R' : 'r',
145 regs->sr & SR_J ? 'J' : 'j',
146 regs->sr & SR_EM ? 'E' : 'e',
147 regs->sr & SR_I3M ? '3' : '.',
148 regs->sr & SR_I2M ? '2' : '.',
149 regs->sr & SR_I1M ? '1' : '.',
150 regs->sr & SR_I0M ? '0' : '.',
151 regs->sr & SR_GM ? 'G' : 'g');
152 printk("CPU Mode: %s\n", cpu_modes[mode]);
153
154 show_trace(NULL, (unsigned long *)sp, regs);
155}
156EXPORT_SYMBOL(show_regs);
157
158/* Fill in the fpu structure for a core dump. This is easy -- we don't have any */
159int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
160{
161 /* Not valid */
162 return 0;
163}
164
165asmlinkage void ret_from_fork(void);
166
167int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
168 unsigned long unused,
169 struct task_struct *p, struct pt_regs *regs)
170{
171 struct pt_regs *childregs;
172
173 childregs = ((struct pt_regs *)(THREAD_SIZE + (unsigned long)p->thread_info)) - 1;
174 *childregs = *regs;
175
176 if (user_mode(regs))
177 childregs->sp = usp;
178 else
179 childregs->sp = (unsigned long)p->thread_info + THREAD_SIZE;
180
181 childregs->r12 = 0; /* Set return value for child */
182
183 p->thread.cpu_context.sr = MODE_SUPERVISOR | SR_GM;
184 p->thread.cpu_context.ksp = (unsigned long)childregs;
185 p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
186
187 return 0;
188}
189
190/* r12-r8 are dummy parameters to force the compiler to use the stack */
191asmlinkage int sys_fork(struct pt_regs *regs)
192{
193 return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
194}
195
196asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
197 unsigned long parent_tidptr,
198 unsigned long child_tidptr, struct pt_regs *regs)
199{
200 if (!newsp)
201 newsp = regs->sp;
202 return do_fork(clone_flags, newsp, regs, 0,
203 (int __user *)parent_tidptr,
204 (int __user *)child_tidptr);
205}
206
207asmlinkage int sys_vfork(struct pt_regs *regs)
208{
209 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs,
210 0, NULL, NULL);
211}
212
213asmlinkage int sys_execve(char __user *ufilename, char __user *__user *uargv,
214 char __user *__user *uenvp, struct pt_regs *regs)
215{
216 int error;
217 char *filename;
218
219 filename = getname(ufilename);
220 error = PTR_ERR(filename);
221 if (IS_ERR(filename))
222 goto out;
223
224 error = do_execve(filename, uargv, uenvp, regs);
225 if (error == 0)
226 current->ptrace &= ~PT_DTRACE;
227 putname(filename);
228
229out:
230 return error;
231}
232
233
234/*
235 * This function is supposed to answer the question "who called
236 * schedule()?"
237 */
238unsigned long get_wchan(struct task_struct *p)
239{
240 unsigned long pc;
241 unsigned long stack_page;
242
243 if (!p || p == current || p->state == TASK_RUNNING)
244 return 0;
245
246 stack_page = (unsigned long)p->thread_info;
247 BUG_ON(!stack_page);
248
249 /*
250 * The stored value of PC is either the address right after
251 * the call to __switch_to() or ret_from_fork.
252 */
253 pc = thread_saved_pc(p);
254 if (in_sched_functions(pc)) {
255#ifdef CONFIG_FRAME_POINTER
256 unsigned long fp = p->thread.cpu_context.r7;
257 BUG_ON(fp < stack_page || fp > (THREAD_SIZE + stack_page));
258 pc = *(unsigned long *)fp;
259#else
260 /*
261 * We depend on the frame size of schedule here, which
262 * is actually quite ugly. It might be possible to
263 * determine the frame size automatically at build
264 * time by doing this:
265 * - compile sched.c
266 * - disassemble the resulting sched.o
267 * - look for 'sub sp,??' shortly after '<schedule>:'
268 */
269 unsigned long sp = p->thread.cpu_context.ksp + 16;
270 BUG_ON(sp < stack_page || sp > (THREAD_SIZE + stack_page));
271 pc = *(unsigned long *)sp;
272#endif
273 }
274
275 return pc;
276}
diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c
new file mode 100644
index 000000000000..3c89e59029ab
--- /dev/null
+++ b/arch/avr32/kernel/ptrace.c
@@ -0,0 +1,371 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#undef DEBUG
9#include <linux/kernel.h>
10#include <linux/sched.h>
11#include <linux/mm.h>
12#include <linux/smp_lock.h>
13#include <linux/ptrace.h>
14#include <linux/errno.h>
15#include <linux/user.h>
16#include <linux/security.h>
17#include <linux/unistd.h>
18#include <linux/notifier.h>
19
20#include <asm/traps.h>
21#include <asm/uaccess.h>
22#include <asm/ocd.h>
23#include <asm/mmu_context.h>
24#include <asm/kdebug.h>
25
26static struct pt_regs *get_user_regs(struct task_struct *tsk)
27{
28 return (struct pt_regs *)((unsigned long) tsk->thread_info +
29 THREAD_SIZE - sizeof(struct pt_regs));
30}
31
32static void ptrace_single_step(struct task_struct *tsk)
33{
34 pr_debug("ptrace_single_step: pid=%u, SR=0x%08lx\n",
35 tsk->pid, tsk->thread.cpu_context.sr);
36 if (!(tsk->thread.cpu_context.sr & SR_D)) {
37 /*
38 * Set a breakpoint at the current pc to force the
39 * process into debug mode. The syscall/exception
40 * exit code will set a breakpoint at the return
41 * address when this flag is set.
42 */
43 pr_debug("ptrace_single_step: Setting TIF_BREAKPOINT\n");
44 set_tsk_thread_flag(tsk, TIF_BREAKPOINT);
45 }
46
47 /* The monitor code will do the actual step for us */
48 set_tsk_thread_flag(tsk, TIF_SINGLE_STEP);
49}
50
51/*
52 * Called by kernel/ptrace.c when detaching
53 *
54 * Make sure any single step bits, etc. are not set
55 */
56void ptrace_disable(struct task_struct *child)
57{
58 clear_tsk_thread_flag(child, TIF_SINGLE_STEP);
59}
60
61/*
62 * Handle hitting a breakpoint
63 */
64static void ptrace_break(struct task_struct *tsk, struct pt_regs *regs)
65{
66 siginfo_t info;
67
68 info.si_signo = SIGTRAP;
69 info.si_errno = 0;
70 info.si_code = TRAP_BRKPT;
71 info.si_addr = (void __user *)instruction_pointer(regs);
72
73 pr_debug("ptrace_break: Sending SIGTRAP to PID %u (pc = 0x%p)\n",
74 tsk->pid, info.si_addr);
75 force_sig_info(SIGTRAP, &info, tsk);
76}
77
78/*
79 * Read the word at offset "offset" into the task's "struct user". We
80 * actually access the pt_regs struct stored on the kernel stack.
81 */
82static int ptrace_read_user(struct task_struct *tsk, unsigned long offset,
83 unsigned long __user *data)
84{
85 unsigned long *regs;
86 unsigned long value;
87
88 pr_debug("ptrace_read_user(%p, %#lx, %p)\n",
89 tsk, offset, data);
90
91 if (offset & 3 || offset >= sizeof(struct user)) {
92 printk("ptrace_read_user: invalid offset 0x%08lx\n", offset);
93 return -EIO;
94 }
95
96 regs = (unsigned long *)get_user_regs(tsk);
97
98 value = 0;
99 if (offset < sizeof(struct pt_regs))
100 value = regs[offset / sizeof(regs[0])];
101
102 return put_user(value, data);
103}
104
105/*
106 * Write the word "value" to offset "offset" into the task's "struct
107 * user". We actually access the pt_regs struct stored on the kernel
108 * stack.
109 */
110static int ptrace_write_user(struct task_struct *tsk, unsigned long offset,
111 unsigned long value)
112{
113 unsigned long *regs;
114
115 if (offset & 3 || offset >= sizeof(struct user)) {
116 printk("ptrace_write_user: invalid offset 0x%08lx\n", offset);
117 return -EIO;
118 }
119
120 if (offset >= sizeof(struct pt_regs))
121 return 0;
122
123 regs = (unsigned long *)get_user_regs(tsk);
124 regs[offset / sizeof(regs[0])] = value;
125
126 return 0;
127}
128
129static int ptrace_getregs(struct task_struct *tsk, void __user *uregs)
130{
131 struct pt_regs *regs = get_user_regs(tsk);
132
133 return copy_to_user(uregs, regs, sizeof(*regs)) ? -EFAULT : 0;
134}
135
136static int ptrace_setregs(struct task_struct *tsk, const void __user *uregs)
137{
138 struct pt_regs newregs;
139 int ret;
140
141 ret = -EFAULT;
142 if (copy_from_user(&newregs, uregs, sizeof(newregs)) == 0) {
143 struct pt_regs *regs = get_user_regs(tsk);
144
145 ret = -EINVAL;
146 if (valid_user_regs(&newregs)) {
147 *regs = newregs;
148 ret = 0;
149 }
150 }
151
152 return ret;
153}
154
155long arch_ptrace(struct task_struct *child, long request, long addr, long data)
156{
157 unsigned long tmp;
158 int ret;
159
160 pr_debug("arch_ptrace(%ld, %ld, %#lx, %#lx)\n",
161 request, child->pid, addr, data);
162
163 pr_debug("ptrace: Enabling monitor mode...\n");
164 __mtdr(DBGREG_DC, __mfdr(DBGREG_DC) | DC_MM | DC_DBE);
165
166 switch (request) {
167 /* Read the word at location addr in the child process */
168 case PTRACE_PEEKTEXT:
169 case PTRACE_PEEKDATA:
170 ret = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
171 if (ret == sizeof(tmp))
172 ret = put_user(tmp, (unsigned long __user *)data);
173 else
174 ret = -EIO;
175 break;
176
177 case PTRACE_PEEKUSR:
178 ret = ptrace_read_user(child, addr,
179 (unsigned long __user *)data);
180 break;
181
182 /* Write the word in data at location addr */
183 case PTRACE_POKETEXT:
184 case PTRACE_POKEDATA:
185 ret = access_process_vm(child, addr, &data, sizeof(data), 1);
186 if (ret == sizeof(data))
187 ret = 0;
188 else
189 ret = -EIO;
190 break;
191
192 case PTRACE_POKEUSR:
193 ret = ptrace_write_user(child, addr, data);
194 break;
195
196 /* continue and stop at next (return from) syscall */
197 case PTRACE_SYSCALL:
198 /* restart after signal */
199 case PTRACE_CONT:
200 ret = -EIO;
201 if (!valid_signal(data))
202 break;
203 if (request == PTRACE_SYSCALL)
204 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
205 else
206 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
207 child->exit_code = data;
208 /* XXX: Are we sure no breakpoints are active here? */
209 wake_up_process(child);
210 ret = 0;
211 break;
212
213 /*
214 * Make the child exit. Best I can do is send it a
215 * SIGKILL. Perhaps it should be put in the status that it
216 * wants to exit.
217 */
218 case PTRACE_KILL:
219 ret = 0;
220 if (child->exit_state == EXIT_ZOMBIE)
221 break;
222 child->exit_code = SIGKILL;
223 wake_up_process(child);
224 break;
225
226 /*
227 * execute single instruction.
228 */
229 case PTRACE_SINGLESTEP:
230 ret = -EIO;
231 if (!valid_signal(data))
232 break;
233 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
234 ptrace_single_step(child);
235 child->exit_code = data;
236 wake_up_process(child);
237 ret = 0;
238 break;
239
240 /* Detach a process that was attached */
241 case PTRACE_DETACH:
242 ret = ptrace_detach(child, data);
243 break;
244
245 case PTRACE_GETREGS:
246 ret = ptrace_getregs(child, (void __user *)data);
247 break;
248
249 case PTRACE_SETREGS:
250 ret = ptrace_setregs(child, (const void __user *)data);
251 break;
252
253 default:
254 ret = ptrace_request(child, request, addr, data);
255 break;
256 }
257
258 pr_debug("sys_ptrace returning %d (DC = 0x%08lx)\n", ret, __mfdr(DBGREG_DC));
259 return ret;
260}
261
262asmlinkage void syscall_trace(void)
263{
264 pr_debug("syscall_trace called\n");
265 if (!test_thread_flag(TIF_SYSCALL_TRACE))
266 return;
267 if (!(current->ptrace & PT_PTRACED))
268 return;
269
270 pr_debug("syscall_trace: notifying parent\n");
271 /* The 0x80 provides a way for the tracing parent to
272 * distinguish between a syscall stop and SIGTRAP delivery */
273 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
274 ? 0x80 : 0));
275
276 /*
277 * this isn't the same as continuing with a signal, but it
278 * will do for normal use. strace only continues with a
279 * signal if the stopping signal is not SIGTRAP. -brl
280 */
281 if (current->exit_code) {
282 pr_debug("syscall_trace: sending signal %d to PID %u\n",
283 current->exit_code, current->pid);
284 send_sig(current->exit_code, current, 1);
285 current->exit_code = 0;
286 }
287}
288
289asmlinkage void do_debug_priv(struct pt_regs *regs)
290{
291 unsigned long dc, ds;
292 unsigned long die_val;
293
294 ds = __mfdr(DBGREG_DS);
295
296 pr_debug("do_debug_priv: pc = %08lx, ds = %08lx\n", regs->pc, ds);
297
298 if (ds & DS_SSS)
299 die_val = DIE_SSTEP;
300 else
301 die_val = DIE_BREAKPOINT;
302
303 if (notify_die(die_val, regs, 0, SIGTRAP) == NOTIFY_STOP)
304 return;
305
306 if (likely(ds & DS_SSS)) {
307 extern void itlb_miss(void);
308 extern void tlb_miss_common(void);
309 struct thread_info *ti;
310
311 dc = __mfdr(DBGREG_DC);
312 dc &= ~DC_SS;
313 __mtdr(DBGREG_DC, dc);
314
315 ti = current_thread_info();
316 ti->flags |= _TIF_BREAKPOINT;
317
318 /* The TLB miss handlers don't check thread flags */
319 if ((regs->pc >= (unsigned long)&itlb_miss)
320 && (regs->pc <= (unsigned long)&tlb_miss_common)) {
321 __mtdr(DBGREG_BWA2A, sysreg_read(RAR_EX));
322 __mtdr(DBGREG_BWC2A, 0x40000001 | (get_asid() << 1));
323 }
324
325 /*
326 * If we're running in supervisor mode, the breakpoint
327 * will take us where we want directly, no need to
328 * single step.
329 */
330 if ((regs->sr & MODE_MASK) != MODE_SUPERVISOR)
331 ti->flags |= TIF_SINGLE_STEP;
332 } else {
333 panic("Unable to handle debug trap at pc = %08lx\n",
334 regs->pc);
335 }
336}
337
338/*
339 * Handle breakpoints, single steps and other debuggy things. To keep
340 * things simple initially, we run with interrupts and exceptions
341 * disabled all the time.
342 */
343asmlinkage void do_debug(struct pt_regs *regs)
344{
345 unsigned long dc, ds;
346
347 ds = __mfdr(DBGREG_DS);
348 pr_debug("do_debug: pc = %08lx, ds = %08lx\n", regs->pc, ds);
349
350 if (test_thread_flag(TIF_BREAKPOINT)) {
351 pr_debug("TIF_BREAKPOINT set\n");
352 /* We're taking care of it */
353 clear_thread_flag(TIF_BREAKPOINT);
354 __mtdr(DBGREG_BWC2A, 0);
355 }
356
357 if (test_thread_flag(TIF_SINGLE_STEP)) {
358 pr_debug("TIF_SINGLE_STEP set, ds = 0x%08lx\n", ds);
359 if (ds & DS_SSS) {
360 dc = __mfdr(DBGREG_DC);
361 dc &= ~DC_SS;
362 __mtdr(DBGREG_DC, dc);
363
364 clear_thread_flag(TIF_SINGLE_STEP);
365 ptrace_break(current, regs);
366 }
367 } else {
368 /* regular breakpoint */
369 ptrace_break(current, regs);
370 }
371}
diff --git a/arch/avr32/kernel/semaphore.c b/arch/avr32/kernel/semaphore.c
new file mode 100644
index 000000000000..1e2705a05016
--- /dev/null
+++ b/arch/avr32/kernel/semaphore.c
@@ -0,0 +1,148 @@
1/*
2 * AVR32 sempahore implementation.
3 *
4 * Copyright (C) 2004-2006 Atmel Corporation
5 *
6 * Based on linux/arch/i386/kernel/semaphore.c
7 * Copyright (C) 1999 Linus Torvalds
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/sched.h>
15#include <linux/errno.h>
16#include <linux/module.h>
17
18#include <asm/semaphore.h>
19#include <asm/atomic.h>
20
21/*
22 * Semaphores are implemented using a two-way counter:
23 * The "count" variable is decremented for each process
24 * that tries to acquire the semaphore, while the "sleeping"
25 * variable is a count of such acquires.
26 *
27 * Notably, the inline "up()" and "down()" functions can
28 * efficiently test if they need to do any extra work (up
29 * needs to do something only if count was negative before
30 * the increment operation.
31 *
32 * "sleeping" and the contention routine ordering is protected
33 * by the spinlock in the semaphore's waitqueue head.
34 *
35 * Note that these functions are only called when there is
36 * contention on the lock, and as such all this is the
37 * "non-critical" part of the whole semaphore business. The
38 * critical part is the inline stuff in <asm/semaphore.h>
39 * where we want to avoid any extra jumps and calls.
40 */
41
42/*
43 * Logic:
44 * - only on a boundary condition do we need to care. When we go
45 * from a negative count to a non-negative, we wake people up.
46 * - when we go from a non-negative count to a negative do we
47 * (a) synchronize with the "sleeper" count and (b) make sure
48 * that we're on the wakeup list before we synchronize so that
49 * we cannot lose wakeup events.
50 */
51
52void __up(struct semaphore *sem)
53{
54 wake_up(&sem->wait);
55}
56EXPORT_SYMBOL(__up);
57
58void __sched __down(struct semaphore *sem)
59{
60 struct task_struct *tsk = current;
61 DECLARE_WAITQUEUE(wait, tsk);
62 unsigned long flags;
63
64 tsk->state = TASK_UNINTERRUPTIBLE;
65 spin_lock_irqsave(&sem->wait.lock, flags);
66 add_wait_queue_exclusive_locked(&sem->wait, &wait);
67
68 sem->sleepers++;
69 for (;;) {
70 int sleepers = sem->sleepers;
71
72 /*
73 * Add "everybody else" into it. They aren't
74 * playing, because we own the spinlock in
75 * the wait_queue_head.
76 */
77 if (atomic_add_return(sleepers - 1, &sem->count) >= 0) {
78 sem->sleepers = 0;
79 break;
80 }
81 sem->sleepers = 1; /* us - see -1 above */
82 spin_unlock_irqrestore(&sem->wait.lock, flags);
83
84 schedule();
85
86 spin_lock_irqsave(&sem->wait.lock, flags);
87 tsk->state = TASK_UNINTERRUPTIBLE;
88 }
89 remove_wait_queue_locked(&sem->wait, &wait);
90 wake_up_locked(&sem->wait);
91 spin_unlock_irqrestore(&sem->wait.lock, flags);
92 tsk->state = TASK_RUNNING;
93}
94EXPORT_SYMBOL(__down);
95
96int __sched __down_interruptible(struct semaphore *sem)
97{
98 int retval = 0;
99 struct task_struct *tsk = current;
100 DECLARE_WAITQUEUE(wait, tsk);
101 unsigned long flags;
102
103 tsk->state = TASK_INTERRUPTIBLE;
104 spin_lock_irqsave(&sem->wait.lock, flags);
105 add_wait_queue_exclusive_locked(&sem->wait, &wait);
106
107 sem->sleepers++;
108 for (;;) {
109 int sleepers = sem->sleepers;
110
111 /*
112 * With signals pending, this turns into the trylock
113 * failure case - we won't be sleeping, and we can't
114 * get the lock as it has contention. Just correct the
115 * count and exit.
116 */
117 if (signal_pending(current)) {
118 retval = -EINTR;
119 sem->sleepers = 0;
120 atomic_add(sleepers, &sem->count);
121 break;
122 }
123
124 /*
125 * Add "everybody else" into it. They aren't
126 * playing, because we own the spinlock in
127 * the wait_queue_head.
128 */
129 if (atomic_add_return(sleepers - 1, &sem->count) >= 0) {
130 sem->sleepers = 0;
131 break;
132 }
133 sem->sleepers = 1; /* us - see -1 above */
134 spin_unlock_irqrestore(&sem->wait.lock, flags);
135
136 schedule();
137
138 spin_lock_irqsave(&sem->wait.lock, flags);
139 tsk->state = TASK_INTERRUPTIBLE;
140 }
141 remove_wait_queue_locked(&sem->wait, &wait);
142 wake_up_locked(&sem->wait);
143 spin_unlock_irqrestore(&sem->wait.lock, flags);
144
145 tsk->state = TASK_RUNNING;
146 return retval;
147}
148EXPORT_SYMBOL(__down_interruptible);
diff --git a/arch/avr32/kernel/setup.c b/arch/avr32/kernel/setup.c
new file mode 100644
index 000000000000..5d68f3c6990b
--- /dev/null
+++ b/arch/avr32/kernel/setup.c
@@ -0,0 +1,335 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/clk.h>
10#include <linux/init.h>
11#include <linux/sched.h>
12#include <linux/console.h>
13#include <linux/ioport.h>
14#include <linux/bootmem.h>
15#include <linux/fs.h>
16#include <linux/module.h>
17#include <linux/root_dev.h>
18#include <linux/cpu.h>
19
20#include <asm/sections.h>
21#include <asm/processor.h>
22#include <asm/pgtable.h>
23#include <asm/setup.h>
24#include <asm/sysreg.h>
25
26#include <asm/arch/board.h>
27#include <asm/arch/init.h>
28
29extern int root_mountflags;
30
31/*
32 * Bootloader-provided information about physical memory
33 */
34struct tag_mem_range *mem_phys;
35struct tag_mem_range *mem_reserved;
36struct tag_mem_range *mem_ramdisk;
37
38/*
39 * Initialize loops_per_jiffy as 5000000 (500MIPS).
40 * Better make it too large than too small...
41 */
42struct avr32_cpuinfo boot_cpu_data = {
43 .loops_per_jiffy = 5000000
44};
45EXPORT_SYMBOL(boot_cpu_data);
46
47static char command_line[COMMAND_LINE_SIZE];
48
49/*
50 * Should be more than enough, but if you have a _really_ complex
51 * setup, you might need to increase the size of this...
52 */
53static struct tag_mem_range __initdata mem_range_cache[32];
54static unsigned mem_range_next_free;
55
56/*
57 * Standard memory resources
58 */
59static struct resource mem_res[] = {
60 {
61 .name = "Kernel code",
62 .start = 0,
63 .end = 0,
64 .flags = IORESOURCE_MEM
65 },
66 {
67 .name = "Kernel data",
68 .start = 0,
69 .end = 0,
70 .flags = IORESOURCE_MEM,
71 },
72};
73
74#define kernel_code mem_res[0]
75#define kernel_data mem_res[1]
76
77/*
78 * Early framebuffer allocation. Works as follows:
79 * - If fbmem_size is zero, nothing will be allocated or reserved.
80 * - If fbmem_start is zero when setup_bootmem() is called,
81 * fbmem_size bytes will be allocated from the bootmem allocator.
82 * - If fbmem_start is nonzero, an area of size fbmem_size will be
83 * reserved at the physical address fbmem_start if necessary. If
84 * the area isn't in a memory region known to the kernel, it will
85 * be left alone.
86 *
87 * Board-specific code may use these variables to set up platform data
88 * for the framebuffer driver if fbmem_size is nonzero.
89 */
90static unsigned long __initdata fbmem_start;
91static unsigned long __initdata fbmem_size;
92
93/*
94 * "fbmem=xxx[kKmM]" allocates the specified amount of boot memory for
95 * use as framebuffer.
96 *
97 * "fbmem=xxx[kKmM]@yyy[kKmM]" defines a memory region of size xxx and
98 * starting at yyy to be reserved for use as framebuffer.
99 *
100 * The kernel won't verify that the memory region starting at yyy
101 * actually contains usable RAM.
102 */
103static int __init early_parse_fbmem(char *p)
104{
105 fbmem_size = memparse(p, &p);
106 if (*p == '@')
107 fbmem_start = memparse(p, &p);
108 return 0;
109}
110early_param("fbmem", early_parse_fbmem);
111
112static inline void __init resource_init(void)
113{
114 struct tag_mem_range *region;
115
116 kernel_code.start = __pa(init_mm.start_code);
117 kernel_code.end = __pa(init_mm.end_code - 1);
118 kernel_data.start = __pa(init_mm.end_code);
119 kernel_data.end = __pa(init_mm.brk - 1);
120
121 for (region = mem_phys; region; region = region->next) {
122 struct resource *res;
123 unsigned long phys_start, phys_end;
124
125 if (region->size == 0)
126 continue;
127
128 phys_start = region->addr;
129 phys_end = phys_start + region->size - 1;
130
131 res = alloc_bootmem_low(sizeof(*res));
132 res->name = "System RAM";
133 res->start = phys_start;
134 res->end = phys_end;
135 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
136
137 request_resource (&iomem_resource, res);
138
139 if (kernel_code.start >= res->start &&
140 kernel_code.end <= res->end)
141 request_resource (res, &kernel_code);
142 if (kernel_data.start >= res->start &&
143 kernel_data.end <= res->end)
144 request_resource (res, &kernel_data);
145 }
146}
147
148static int __init parse_tag_core(struct tag *tag)
149{
150 if (tag->hdr.size > 2) {
151 if ((tag->u.core.flags & 1) == 0)
152 root_mountflags &= ~MS_RDONLY;
153 ROOT_DEV = new_decode_dev(tag->u.core.rootdev);
154 }
155 return 0;
156}
157__tagtable(ATAG_CORE, parse_tag_core);
158
159static int __init parse_tag_mem_range(struct tag *tag,
160 struct tag_mem_range **root)
161{
162 struct tag_mem_range *cur, **pprev;
163 struct tag_mem_range *new;
164
165 /*
166 * Ignore zero-sized entries. If we're running standalone, the
167 * SDRAM code may emit such entries if something goes
168 * wrong...
169 */
170 if (tag->u.mem_range.size == 0)
171 return 0;
172
173 /*
174 * Copy the data so the bootmem init code doesn't need to care
175 * about it.
176 */
177 if (mem_range_next_free >=
178 (sizeof(mem_range_cache) / sizeof(mem_range_cache[0])))
179 panic("Physical memory map too complex!\n");
180
181 new = &mem_range_cache[mem_range_next_free++];
182 *new = tag->u.mem_range;
183
184 pprev = root;
185 cur = *root;
186 while (cur) {
187 pprev = &cur->next;
188 cur = cur->next;
189 }
190
191 *pprev = new;
192 new->next = NULL;
193
194 return 0;
195}
196
197static int __init parse_tag_mem(struct tag *tag)
198{
199 return parse_tag_mem_range(tag, &mem_phys);
200}
201__tagtable(ATAG_MEM, parse_tag_mem);
202
203static int __init parse_tag_cmdline(struct tag *tag)
204{
205 strlcpy(saved_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
206 return 0;
207}
208__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
209
210static int __init parse_tag_rdimg(struct tag *tag)
211{
212 return parse_tag_mem_range(tag, &mem_ramdisk);
213}
214__tagtable(ATAG_RDIMG, parse_tag_rdimg);
215
216static int __init parse_tag_clock(struct tag *tag)
217{
218 /*
219 * We'll figure out the clocks by peeking at the system
220 * manager regs directly.
221 */
222 return 0;
223}
224__tagtable(ATAG_CLOCK, parse_tag_clock);
225
226static int __init parse_tag_rsvd_mem(struct tag *tag)
227{
228 return parse_tag_mem_range(tag, &mem_reserved);
229}
230__tagtable(ATAG_RSVD_MEM, parse_tag_rsvd_mem);
231
232static int __init parse_tag_ethernet(struct tag *tag)
233{
234#if 0
235 const struct platform_device *pdev;
236
237 /*
238 * We really need a bus type that supports "classes"...this
239 * will do for now (until we must handle other kinds of
240 * ethernet controllers)
241 */
242 pdev = platform_get_device("macb", tag->u.ethernet.mac_index);
243 if (pdev && pdev->dev.platform_data) {
244 struct eth_platform_data *data = pdev->dev.platform_data;
245
246 data->valid = 1;
247 data->mii_phy_addr = tag->u.ethernet.mii_phy_addr;
248 memcpy(data->hw_addr, tag->u.ethernet.hw_address,
249 sizeof(data->hw_addr));
250 }
251#endif
252 return 0;
253}
254__tagtable(ATAG_ETHERNET, parse_tag_ethernet);
255
256/*
257 * Scan the tag table for this tag, and call its parse function. The
258 * tag table is built by the linker from all the __tagtable
259 * declarations.
260 */
261static int __init parse_tag(struct tag *tag)
262{
263 extern struct tagtable __tagtable_begin, __tagtable_end;
264 struct tagtable *t;
265
266 for (t = &__tagtable_begin; t < &__tagtable_end; t++)
267 if (tag->hdr.tag == t->tag) {
268 t->parse(tag);
269 break;
270 }
271
272 return t < &__tagtable_end;
273}
274
275/*
276 * Parse all tags in the list we got from the boot loader
277 */
278static void __init parse_tags(struct tag *t)
279{
280 for (; t->hdr.tag != ATAG_NONE; t = tag_next(t))
281 if (!parse_tag(t))
282 printk(KERN_WARNING
283 "Ignoring unrecognised tag 0x%08x\n",
284 t->hdr.tag);
285}
286
287void __init setup_arch (char **cmdline_p)
288{
289 struct clk *cpu_clk;
290
291 parse_tags(bootloader_tags);
292
293 setup_processor();
294 setup_platform();
295
296 cpu_clk = clk_get(NULL, "cpu");
297 if (IS_ERR(cpu_clk)) {
298 printk(KERN_WARNING "Warning: Unable to get CPU clock\n");
299 } else {
300 unsigned long cpu_hz = clk_get_rate(cpu_clk);
301
302 /*
303 * Well, duh, but it's probably a good idea to
304 * increment the use count.
305 */
306 clk_enable(cpu_clk);
307
308 boot_cpu_data.clk = cpu_clk;
309 boot_cpu_data.loops_per_jiffy = cpu_hz * 4;
310 printk("CPU: Running at %lu.%03lu MHz\n",
311 ((cpu_hz + 500) / 1000) / 1000,
312 ((cpu_hz + 500) / 1000) % 1000);
313 }
314
315 init_mm.start_code = (unsigned long) &_text;
316 init_mm.end_code = (unsigned long) &_etext;
317 init_mm.end_data = (unsigned long) &_edata;
318 init_mm.brk = (unsigned long) &_end;
319
320 strlcpy(command_line, saved_command_line, COMMAND_LINE_SIZE);
321 *cmdline_p = command_line;
322 parse_early_param();
323
324 setup_bootmem();
325
326 board_setup_fbmem(fbmem_start, fbmem_size);
327
328#ifdef CONFIG_VT
329 conswitchp = &dummy_con;
330#endif
331
332 paging_init();
333
334 resource_init();
335}
diff --git a/arch/avr32/kernel/signal.c b/arch/avr32/kernel/signal.c
new file mode 100644
index 000000000000..33096651c24f
--- /dev/null
+++ b/arch/avr32/kernel/signal.c
@@ -0,0 +1,328 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * Based on linux/arch/sh/kernel/signal.c
5 * Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima
6 * Copyright (C) 1991, 1992 Linus Torvalds
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/sched.h>
14#include <linux/mm.h>
15#include <linux/errno.h>
16#include <linux/ptrace.h>
17#include <linux/unistd.h>
18#include <linux/suspend.h>
19
20#include <asm/uaccess.h>
21#include <asm/ucontext.h>
22
23#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
24
25asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
26 struct pt_regs *regs)
27{
28 return do_sigaltstack(uss, uoss, regs->sp);
29}
30
31struct rt_sigframe
32{
33 struct siginfo info;
34 struct ucontext uc;
35 unsigned long retcode;
36};
37
38static int
39restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
40{
41 int err = 0;
42
43#define COPY(x) err |= __get_user(regs->x, &sc->x)
44 COPY(sr);
45 COPY(pc);
46 COPY(lr);
47 COPY(sp);
48 COPY(r12);
49 COPY(r11);
50 COPY(r10);
51 COPY(r9);
52 COPY(r8);
53 COPY(r7);
54 COPY(r6);
55 COPY(r5);
56 COPY(r4);
57 COPY(r3);
58 COPY(r2);
59 COPY(r1);
60 COPY(r0);
61#undef COPY
62
63 /*
64 * Don't allow anyone to pretend they're running in supervisor
65 * mode or something...
66 */
67 err |= !valid_user_regs(regs);
68
69 return err;
70}
71
72
73asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
74{
75 struct rt_sigframe __user *frame;
76 sigset_t set;
77
78 frame = (struct rt_sigframe __user *)regs->sp;
79 pr_debug("SIG return: frame = %p\n", frame);
80
81 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
82 goto badframe;
83
84 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
85 goto badframe;
86
87 sigdelsetmask(&set, ~_BLOCKABLE);
88 spin_lock_irq(&current->sighand->siglock);
89 current->blocked = set;
90 recalc_sigpending();
91 spin_unlock_irq(&current->sighand->siglock);
92
93 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
94 goto badframe;
95
96 pr_debug("Context restored: pc = %08lx, lr = %08lx, sp = %08lx\n",
97 regs->pc, regs->lr, regs->sp);
98
99 return regs->r12;
100
101badframe:
102 force_sig(SIGSEGV, current);
103 return 0;
104}
105
106static int
107setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
108{
109 int err = 0;
110
111#define COPY(x) err |= __put_user(regs->x, &sc->x)
112 COPY(sr);
113 COPY(pc);
114 COPY(lr);
115 COPY(sp);
116 COPY(r12);
117 COPY(r11);
118 COPY(r10);
119 COPY(r9);
120 COPY(r8);
121 COPY(r7);
122 COPY(r6);
123 COPY(r5);
124 COPY(r4);
125 COPY(r3);
126 COPY(r2);
127 COPY(r1);
128 COPY(r0);
129#undef COPY
130
131 return err;
132}
133
134static inline void __user *
135get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, int framesize)
136{
137 unsigned long sp = regs->sp;
138
139 if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
140 sp = current->sas_ss_sp + current->sas_ss_size;
141
142 return (void __user *)((sp - framesize) & ~3);
143}
144
145static int
146setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
147 sigset_t *set, struct pt_regs *regs)
148{
149 struct rt_sigframe __user *frame;
150 int err = 0;
151
152 frame = get_sigframe(ka, regs, sizeof(*frame));
153 err = -EFAULT;
154 if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
155 goto out;
156
157 /*
158 * Set up the return code:
159 *
160 * mov r8, __NR_rt_sigreturn
161 * scall
162 *
163 * Note: This will blow up since we're using a non-executable
164 * stack. Better use SA_RESTORER.
165 */
166#if __NR_rt_sigreturn > 127
167# error __NR_rt_sigreturn must be < 127 to fit in a short mov
168#endif
169 err = __put_user(0x3008d733 | (__NR_rt_sigreturn << 20),
170 &frame->retcode);
171
172 err |= copy_siginfo_to_user(&frame->info, info);
173
174 /* Set up the ucontext */
175 err |= __put_user(0, &frame->uc.uc_flags);
176 err |= __put_user(NULL, &frame->uc.uc_link);
177 err |= __put_user((void __user *)current->sas_ss_sp,
178 &frame->uc.uc_stack.ss_sp);
179 err |= __put_user(sas_ss_flags(regs->sp),
180 &frame->uc.uc_stack.ss_flags);
181 err |= __put_user(current->sas_ss_size,
182 &frame->uc.uc_stack.ss_size);
183 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
184 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
185
186 if (err)
187 goto out;
188
189 regs->r12 = sig;
190 regs->r11 = (unsigned long) &frame->info;
191 regs->r10 = (unsigned long) &frame->uc;
192 regs->sp = (unsigned long) frame;
193 if (ka->sa.sa_flags & SA_RESTORER)
194 regs->lr = (unsigned long)ka->sa.sa_restorer;
195 else {
196 printk(KERN_NOTICE "[%s:%d] did not set SA_RESTORER\n",
197 current->comm, current->pid);
198 regs->lr = (unsigned long) &frame->retcode;
199 }
200
201 pr_debug("SIG deliver [%s:%d]: sig=%d sp=0x%lx pc=0x%lx->0x%p lr=0x%lx\n",
202 current->comm, current->pid, sig, regs->sp,
203 regs->pc, ka->sa.sa_handler, regs->lr);
204
205 regs->pc = (unsigned long) ka->sa.sa_handler;
206
207out:
208 return err;
209}
210
211static inline void restart_syscall(struct pt_regs *regs)
212{
213 if (regs->r12 == -ERESTART_RESTARTBLOCK)
214 regs->r8 = __NR_restart_syscall;
215 else
216 regs->r12 = regs->r12_orig;
217 regs->pc -= 2;
218}
219
220static inline void
221handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
222 sigset_t *oldset, struct pt_regs *regs, int syscall)
223{
224 int ret;
225
226 /*
227 * Set up the stack frame
228 */
229 ret = setup_rt_frame(sig, ka, info, oldset, regs);
230
231 /*
232 * Check that the resulting registers are sane
233 */
234 ret |= !valid_user_regs(regs);
235
236 /*
237 * Block the signal if we were unsuccessful.
238 */
239 if (ret != 0 || !(ka->sa.sa_flags & SA_NODEFER)) {
240 spin_lock_irq(&current->sighand->siglock);
241 sigorsets(&current->blocked, &current->blocked,
242 &ka->sa.sa_mask);
243 sigaddset(&current->blocked, sig);
244 recalc_sigpending();
245 spin_unlock_irq(&current->sighand->siglock);
246 }
247
248 if (ret == 0)
249 return;
250
251 force_sigsegv(sig, current);
252}
253
254/*
255 * Note that 'init' is a special process: it doesn't get signals it
256 * doesn't want to handle. Thus you cannot kill init even with a
257 * SIGKILL even by mistake.
258 */
259int do_signal(struct pt_regs *regs, sigset_t *oldset, int syscall)
260{
261 siginfo_t info;
262 int signr;
263 struct k_sigaction ka;
264
265 /*
266 * We want the common case to go fast, which is why we may in
267 * certain cases get here from kernel mode. Just return
268 * without doing anything if so.
269 */
270 if (!user_mode(regs))
271 return 0;
272
273 if (try_to_freeze()) {
274 signr = 0;
275 if (!signal_pending(current))
276 goto no_signal;
277 }
278
279 if (test_thread_flag(TIF_RESTORE_SIGMASK))
280 oldset = &current->saved_sigmask;
281 else if (!oldset)
282 oldset = &current->blocked;
283
284 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
285no_signal:
286 if (syscall) {
287 switch (regs->r12) {
288 case -ERESTART_RESTARTBLOCK:
289 case -ERESTARTNOHAND:
290 if (signr > 0) {
291 regs->r12 = -EINTR;
292 break;
293 }
294 /* fall through */
295 case -ERESTARTSYS:
296 if (signr > 0 && !(ka.sa.sa_flags & SA_RESTART)) {
297 regs->r12 = -EINTR;
298 break;
299 }
300 /* fall through */
301 case -ERESTARTNOINTR:
302 restart_syscall(regs);
303 }
304 }
305
306 if (signr == 0) {
307 /* No signal to deliver -- put the saved sigmask back */
308 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
309 clear_thread_flag(TIF_RESTORE_SIGMASK);
310 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
311 }
312 return 0;
313 }
314
315 handle_signal(signr, &ka, &info, oldset, regs, syscall);
316 return 1;
317}
318
319asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti)
320{
321 int syscall = 0;
322
323 if ((sysreg_read(SR) & MODE_MASK) == MODE_SUPERVISOR)
324 syscall = 1;
325
326 if (ti->flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
327 do_signal(regs, &current->blocked, syscall);
328}
diff --git a/arch/avr32/kernel/switch_to.S b/arch/avr32/kernel/switch_to.S
new file mode 100644
index 000000000000..a48d046723c5
--- /dev/null
+++ b/arch/avr32/kernel/switch_to.S
@@ -0,0 +1,35 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <asm/sysreg.h>
10
11 .text
12 .global __switch_to
13 .type __switch_to, @function
14
15 /* Switch thread context from "prev" to "next", returning "last"
16 * r12 : prev
17 * r11 : &prev->thread + 1
18 * r10 : &next->thread
19 */
20__switch_to:
21 stm --r11, r0,r1,r2,r3,r4,r5,r6,r7,sp,lr
22 mfsr r9, SYSREG_SR
23 st.w --r11, r9
24 ld.w r8, r10++
25 /*
26 * schedule() may have been called from a mode with a different
27 * set of registers. Make sure we don't lose anything here.
28 */
29 pushm r10,r12
30 mtsr SYSREG_SR, r8
31 frs /* flush the return stack */
32 sub pc, -2 /* flush the pipeline */
33 popm r10,r12
34 ldm r10++, r0,r1,r2,r3,r4,r5,r6,r7,sp,pc
35 .size __switch_to, . - __switch_to
diff --git a/arch/avr32/kernel/sys_avr32.c b/arch/avr32/kernel/sys_avr32.c
new file mode 100644
index 000000000000..6ec5693da448
--- /dev/null
+++ b/arch/avr32/kernel/sys_avr32.c
@@ -0,0 +1,51 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#include <linux/errno.h>
9#include <linux/fs.h>
10#include <linux/file.h>
11#include <linux/mm.h>
12#include <linux/unistd.h>
13
14#include <asm/mman.h>
15#include <asm/uaccess.h>
16
17asmlinkage int sys_pipe(unsigned long __user *filedes)
18{
19 int fd[2];
20 int error;
21
22 error = do_pipe(fd);
23 if (!error) {
24 if (copy_to_user(filedes, fd, sizeof(fd)))
25 error = -EFAULT;
26 }
27 return error;
28}
29
30asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
31 unsigned long prot, unsigned long flags,
32 unsigned long fd, off_t offset)
33{
34 int error = -EBADF;
35 struct file *file = NULL;
36
37 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
38 if (!(flags & MAP_ANONYMOUS)) {
39 file = fget(fd);
40 if (!file)
41 return error;
42 }
43
44 down_write(&current->mm->mmap_sem);
45 error = do_mmap_pgoff(file, addr, len, prot, flags, offset);
46 up_write(&current->mm->mmap_sem);
47
48 if (file)
49 fput(file);
50 return error;
51}
diff --git a/arch/avr32/kernel/syscall-stubs.S b/arch/avr32/kernel/syscall-stubs.S
new file mode 100644
index 000000000000..7589a9b426cb
--- /dev/null
+++ b/arch/avr32/kernel/syscall-stubs.S
@@ -0,0 +1,102 @@
1/*
2 * Copyright (C) 2005-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9/*
10 * Stubs for syscalls that require access to pt_regs or that take more
11 * than five parameters.
12 */
13
14#define ARG6 r3
15
16 .text
17 .global __sys_rt_sigsuspend
18 .type __sys_rt_sigsuspend,@function
19__sys_rt_sigsuspend:
20 mov r10, sp
21 rjmp sys_rt_sigsuspend
22
23 .global __sys_sigaltstack
24 .type __sys_sigaltstack,@function
25__sys_sigaltstack:
26 mov r10, sp
27 rjmp sys_sigaltstack
28
29 .global __sys_rt_sigreturn
30 .type __sys_rt_sigreturn,@function
31__sys_rt_sigreturn:
32 mov r12, sp
33 rjmp sys_rt_sigreturn
34
35 .global __sys_fork
36 .type __sys_fork,@function
37__sys_fork:
38 mov r12, sp
39 rjmp sys_fork
40
41 .global __sys_clone
42 .type __sys_clone,@function
43__sys_clone:
44 mov r8, sp
45 rjmp sys_clone
46
47 .global __sys_vfork
48 .type __sys_vfork,@function
49__sys_vfork:
50 mov r12, sp
51 rjmp sys_vfork
52
53 .global __sys_execve
54 .type __sys_execve,@function
55__sys_execve:
56 mov r9, sp
57 rjmp sys_execve
58
59 .global __sys_mmap2
60 .type __sys_mmap2,@function
61__sys_mmap2:
62 pushm lr
63 st.w --sp, ARG6
64 rcall sys_mmap2
65 sub sp, -4
66 popm pc
67
68 .global __sys_sendto
69 .type __sys_sendto,@function
70__sys_sendto:
71 pushm lr
72 st.w --sp, ARG6
73 rcall sys_sendto
74 sub sp, -4
75 popm pc
76
77 .global __sys_recvfrom
78 .type __sys_recvfrom,@function
79__sys_recvfrom:
80 pushm lr
81 st.w --sp, ARG6
82 rcall sys_recvfrom
83 sub sp, -4
84 popm pc
85
86 .global __sys_pselect6
87 .type __sys_pselect6,@function
88__sys_pselect6:
89 pushm lr
90 st.w --sp, ARG6
91 rcall sys_pselect6
92 sub sp, -4
93 popm pc
94
95 .global __sys_splice
96 .type __sys_splice,@function
97__sys_splice:
98 pushm lr
99 st.w --sp, ARG6
100 rcall sys_splice
101 sub sp, -4
102 popm pc
diff --git a/arch/avr32/kernel/syscall_table.S b/arch/avr32/kernel/syscall_table.S
new file mode 100644
index 000000000000..63b206965d05
--- /dev/null
+++ b/arch/avr32/kernel/syscall_table.S
@@ -0,0 +1,289 @@
1/*
2 * AVR32 system call table
3 *
4 * Copyright (C) 2004-2006 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#if !defined(CONFIG_NFSD) && !defined(CONFIG_NFSD_MODULE)
12#define sys_nfsservctl sys_ni_syscall
13#endif
14
15#if !defined(CONFIG_SYSV_IPC)
16# define sys_ipc sys_ni_syscall
17#endif
18
19 .section .rodata,"a",@progbits
20 .type sys_call_table,@object
21 .global sys_call_table
22 .align 2
23sys_call_table:
24 .long sys_restart_syscall
25 .long sys_exit
26 .long __sys_fork
27 .long sys_read
28 .long sys_write
29 .long sys_open /* 5 */
30 .long sys_close
31 .long sys_umask
32 .long sys_creat
33 .long sys_link
34 .long sys_unlink /* 10 */
35 .long __sys_execve
36 .long sys_chdir
37 .long sys_time
38 .long sys_mknod
39 .long sys_chmod /* 15 */
40 .long sys_chown
41 .long sys_lchown
42 .long sys_lseek
43 .long sys_llseek
44 .long sys_getpid /* 20 */
45 .long sys_mount
46 .long sys_umount
47 .long sys_setuid
48 .long sys_getuid
49 .long sys_stime /* 25 */
50 .long sys_ptrace
51 .long sys_alarm
52 .long sys_pause
53 .long sys_utime
54 .long sys_newstat /* 30 */
55 .long sys_newfstat
56 .long sys_newlstat
57 .long sys_access
58 .long sys_chroot
59 .long sys_sync /* 35 */
60 .long sys_fsync
61 .long sys_kill
62 .long sys_rename
63 .long sys_mkdir
64 .long sys_rmdir /* 40 */
65 .long sys_dup
66 .long sys_pipe
67 .long sys_times
68 .long __sys_clone
69 .long sys_brk /* 45 */
70 .long sys_setgid
71 .long sys_getgid
72 .long sys_getcwd
73 .long sys_geteuid
74 .long sys_getegid /* 50 */
75 .long sys_acct
76 .long sys_setfsuid
77 .long sys_setfsgid
78 .long sys_ioctl
79 .long sys_fcntl /* 55 */
80 .long sys_setpgid
81 .long sys_mremap
82 .long sys_setresuid
83 .long sys_getresuid
84 .long sys_setreuid /* 60 */
85 .long sys_setregid
86 .long sys_ustat
87 .long sys_dup2
88 .long sys_getppid
89 .long sys_getpgrp /* 65 */
90 .long sys_setsid
91 .long sys_rt_sigaction
92 .long __sys_rt_sigreturn
93 .long sys_rt_sigprocmask
94 .long sys_rt_sigpending /* 70 */
95 .long sys_rt_sigtimedwait
96 .long sys_rt_sigqueueinfo
97 .long __sys_rt_sigsuspend
98 .long sys_sethostname
99 .long sys_setrlimit /* 75 */
100 .long sys_getrlimit
101 .long sys_getrusage
102 .long sys_gettimeofday
103 .long sys_settimeofday
104 .long sys_getgroups /* 80 */
105 .long sys_setgroups
106 .long sys_select
107 .long sys_symlink
108 .long sys_fchdir
109 .long sys_readlink /* 85 */
110 .long sys_pread64
111 .long sys_pwrite64
112 .long sys_swapon
113 .long sys_reboot
114 .long __sys_mmap2 /* 90 */
115 .long sys_munmap
116 .long sys_truncate
117 .long sys_ftruncate
118 .long sys_fchmod
119 .long sys_fchown /* 95 */
120 .long sys_getpriority
121 .long sys_setpriority
122 .long sys_wait4
123 .long sys_statfs
124 .long sys_fstatfs /* 100 */
125 .long sys_vhangup
126 .long __sys_sigaltstack
127 .long sys_syslog
128 .long sys_setitimer
129 .long sys_getitimer /* 105 */
130 .long sys_swapoff
131 .long sys_sysinfo
132 .long sys_ipc
133 .long sys_sendfile
134 .long sys_setdomainname /* 110 */
135 .long sys_newuname
136 .long sys_adjtimex
137 .long sys_mprotect
138 .long __sys_vfork
139 .long sys_init_module /* 115 */
140 .long sys_delete_module
141 .long sys_quotactl
142 .long sys_getpgid
143 .long sys_bdflush
144 .long sys_sysfs /* 120 */
145 .long sys_personality
146 .long sys_ni_syscall /* reserved for afs_syscall */
147 .long sys_getdents
148 .long sys_flock
149 .long sys_msync /* 125 */
150 .long sys_readv
151 .long sys_writev
152 .long sys_getsid
153 .long sys_fdatasync
154 .long sys_sysctl /* 130 */
155 .long sys_mlock
156 .long sys_munlock
157 .long sys_mlockall
158 .long sys_munlockall
159 .long sys_sched_setparam /* 135 */
160 .long sys_sched_getparam
161 .long sys_sched_setscheduler
162 .long sys_sched_getscheduler
163 .long sys_sched_yield
164 .long sys_sched_get_priority_max /* 140 */
165 .long sys_sched_get_priority_min
166 .long sys_sched_rr_get_interval
167 .long sys_nanosleep
168 .long sys_poll
169 .long sys_nfsservctl /* 145 */
170 .long sys_setresgid
171 .long sys_getresgid
172 .long sys_prctl
173 .long sys_socket
174 .long sys_bind /* 150 */
175 .long sys_connect
176 .long sys_listen
177 .long sys_accept
178 .long sys_getsockname
179 .long sys_getpeername /* 155 */
180 .long sys_socketpair
181 .long sys_send
182 .long sys_recv
183 .long __sys_sendto
184 .long __sys_recvfrom /* 160 */
185 .long sys_shutdown
186 .long sys_setsockopt
187 .long sys_getsockopt
188 .long sys_sendmsg
189 .long sys_recvmsg /* 165 */
190 .long sys_truncate64
191 .long sys_ftruncate64
192 .long sys_stat64
193 .long sys_lstat64
194 .long sys_fstat64 /* 170 */
195 .long sys_pivot_root
196 .long sys_mincore
197 .long sys_madvise
198 .long sys_getdents64
199 .long sys_fcntl64 /* 175 */
200 .long sys_gettid
201 .long sys_readahead
202 .long sys_setxattr
203 .long sys_lsetxattr
204 .long sys_fsetxattr /* 180 */
205 .long sys_getxattr
206 .long sys_lgetxattr
207 .long sys_fgetxattr
208 .long sys_listxattr
209 .long sys_llistxattr /* 185 */
210 .long sys_flistxattr
211 .long sys_removexattr
212 .long sys_lremovexattr
213 .long sys_fremovexattr
214 .long sys_tkill /* 190 */
215 .long sys_sendfile64
216 .long sys_futex
217 .long sys_sched_setaffinity
218 .long sys_sched_getaffinity
219 .long sys_capget /* 195 */
220 .long sys_capset
221 .long sys_io_setup
222 .long sys_io_destroy
223 .long sys_io_getevents
224 .long sys_io_submit /* 200 */
225 .long sys_io_cancel
226 .long sys_fadvise64
227 .long sys_exit_group
228 .long sys_lookup_dcookie
229 .long sys_epoll_create /* 205 */
230 .long sys_epoll_ctl
231 .long sys_epoll_wait
232 .long sys_remap_file_pages
233 .long sys_set_tid_address
234 .long sys_timer_create /* 210 */
235 .long sys_timer_settime
236 .long sys_timer_gettime
237 .long sys_timer_getoverrun
238 .long sys_timer_delete
239 .long sys_clock_settime /* 215 */
240 .long sys_clock_gettime
241 .long sys_clock_getres
242 .long sys_clock_nanosleep
243 .long sys_statfs64
244 .long sys_fstatfs64 /* 220 */
245 .long sys_tgkill
246 .long sys_ni_syscall /* reserved for TUX */
247 .long sys_utimes
248 .long sys_fadvise64_64
249 .long sys_cacheflush /* 225 */
250 .long sys_ni_syscall /* sys_vserver */
251 .long sys_mq_open
252 .long sys_mq_unlink
253 .long sys_mq_timedsend
254 .long sys_mq_timedreceive /* 230 */
255 .long sys_mq_notify
256 .long sys_mq_getsetattr
257 .long sys_kexec_load
258 .long sys_waitid
259 .long sys_add_key /* 235 */
260 .long sys_request_key
261 .long sys_keyctl
262 .long sys_ioprio_set
263 .long sys_ioprio_get
264 .long sys_inotify_init /* 240 */
265 .long sys_inotify_add_watch
266 .long sys_inotify_rm_watch
267 .long sys_openat
268 .long sys_mkdirat
269 .long sys_mknodat /* 245 */
270 .long sys_fchownat
271 .long sys_futimesat
272 .long sys_fstatat64
273 .long sys_unlinkat
274 .long sys_renameat /* 250 */
275 .long sys_linkat
276 .long sys_symlinkat
277 .long sys_readlinkat
278 .long sys_fchmodat
279 .long sys_faccessat /* 255 */
280 .long __sys_pselect6
281 .long sys_ppoll
282 .long sys_unshare
283 .long sys_set_robust_list
284 .long sys_get_robust_list /* 260 */
285 .long __sys_splice
286 .long sys_sync_file_range
287 .long sys_tee
288 .long sys_vmsplice
289 .long sys_ni_syscall /* r8 is saturated at nr_syscalls */
diff --git a/arch/avr32/kernel/time.c b/arch/avr32/kernel/time.c
new file mode 100644
index 000000000000..b0e6b5855a38
--- /dev/null
+++ b/arch/avr32/kernel/time.c
@@ -0,0 +1,238 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * Based on MIPS implementation arch/mips/kernel/time.c
5 * Copyright 2001 MontaVista Software Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/clk.h>
13#include <linux/clocksource.h>
14#include <linux/time.h>
15#include <linux/module.h>
16#include <linux/interrupt.h>
17#include <linux/irq.h>
18#include <linux/kernel_stat.h>
19#include <linux/errno.h>
20#include <linux/init.h>
21#include <linux/profile.h>
22#include <linux/sysdev.h>
23
24#include <asm/div64.h>
25#include <asm/sysreg.h>
26#include <asm/io.h>
27#include <asm/sections.h>
28
29static cycle_t read_cycle_count(void)
30{
31 return (cycle_t)sysreg_read(COUNT);
32}
33
34static struct clocksource clocksource_avr32 = {
35 .name = "avr32",
36 .rating = 350,
37 .read = read_cycle_count,
38 .mask = CLOCKSOURCE_MASK(32),
39 .shift = 16,
40 .is_continuous = 1,
41};
42
43/*
44 * By default we provide the null RTC ops
45 */
46static unsigned long null_rtc_get_time(void)
47{
48 return mktime(2004, 1, 1, 0, 0, 0);
49}
50
51static int null_rtc_set_time(unsigned long sec)
52{
53 return 0;
54}
55
56static unsigned long (*rtc_get_time)(void) = null_rtc_get_time;
57static int (*rtc_set_time)(unsigned long) = null_rtc_set_time;
58
59/* how many counter cycles in a jiffy? */
60static unsigned long cycles_per_jiffy;
61
62/* cycle counter value at the previous timer interrupt */
63static unsigned int timerhi, timerlo;
64
65/* the count value for the next timer interrupt */
66static unsigned int expirelo;
67
68static void avr32_timer_ack(void)
69{
70 unsigned int count;
71
72 /* Ack this timer interrupt and set the next one */
73 expirelo += cycles_per_jiffy;
74 if (expirelo == 0) {
75 printk(KERN_DEBUG "expirelo == 0\n");
76 sysreg_write(COMPARE, expirelo + 1);
77 } else {
78 sysreg_write(COMPARE, expirelo);
79 }
80
81 /* Check to see if we have missed any timer interrupts */
82 count = sysreg_read(COUNT);
83 if ((count - expirelo) < 0x7fffffff) {
84 expirelo = count + cycles_per_jiffy;
85 sysreg_write(COMPARE, expirelo);
86 }
87}
88
89static unsigned int avr32_hpt_read(void)
90{
91 return sysreg_read(COUNT);
92}
93
94/*
95 * Taken from MIPS c0_hpt_timer_init().
96 *
97 * Why is it so complicated, and what is "count"? My assumption is
98 * that `count' specifies the "reference cycle", i.e. the cycle since
99 * reset that should mean "zero". The reason COUNT is written twice is
100 * probably to make sure we don't get any timer interrupts while we
101 * are messing with the counter.
102 */
103static void avr32_hpt_init(unsigned int count)
104{
105 count = sysreg_read(COUNT) - count;
106 expirelo = (count / cycles_per_jiffy + 1) * cycles_per_jiffy;
107 sysreg_write(COUNT, expirelo - cycles_per_jiffy);
108 sysreg_write(COMPARE, expirelo);
109 sysreg_write(COUNT, count);
110}
111
112/*
113 * Scheduler clock - returns current time in nanosec units.
114 */
115unsigned long long sched_clock(void)
116{
117 /* There must be better ways...? */
118 return (unsigned long long)jiffies * (1000000000 / HZ);
119}
120
121/*
122 * local_timer_interrupt() does profiling and process accounting on a
123 * per-CPU basis.
124 *
125 * In UP mode, it is invoked from the (global) timer_interrupt.
126 */
127static void local_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
128{
129 if (current->pid)
130 profile_tick(CPU_PROFILING, regs);
131 update_process_times(user_mode(regs));
132}
133
134static irqreturn_t
135timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
136{
137 unsigned int count;
138
139 /* ack timer interrupt and try to set next interrupt */
140 count = avr32_hpt_read();
141 avr32_timer_ack();
142
143 /* Update timerhi/timerlo for intra-jiffy calibration */
144 timerhi += count < timerlo; /* Wrap around */
145 timerlo = count;
146
147 /*
148 * Call the generic timer interrupt handler
149 */
150 write_seqlock(&xtime_lock);
151 do_timer(regs);
152 write_sequnlock(&xtime_lock);
153
154 /*
155 * In UP mode, we call local_timer_interrupt() to do profiling
156 * and process accounting.
157 *
158 * SMP is not supported yet.
159 */
160 local_timer_interrupt(irq, dev_id, regs);
161
162 return IRQ_HANDLED;
163}
164
165static struct irqaction timer_irqaction = {
166 .handler = timer_interrupt,
167 .flags = IRQF_DISABLED,
168 .name = "timer",
169};
170
171void __init time_init(void)
172{
173 unsigned long mult, shift, count_hz;
174 int ret;
175
176 xtime.tv_sec = rtc_get_time();
177 xtime.tv_nsec = 0;
178
179 set_normalized_timespec(&wall_to_monotonic,
180 -xtime.tv_sec, -xtime.tv_nsec);
181
182 printk("Before time_init: count=%08lx, compare=%08lx\n",
183 (unsigned long)sysreg_read(COUNT),
184 (unsigned long)sysreg_read(COMPARE));
185
186 count_hz = clk_get_rate(boot_cpu_data.clk);
187 shift = clocksource_avr32.shift;
188 mult = clocksource_hz2mult(count_hz, shift);
189 clocksource_avr32.mult = mult;
190
191 printk("Cycle counter: mult=%lu, shift=%lu\n", mult, shift);
192
193 {
194 u64 tmp;
195
196 tmp = TICK_NSEC;
197 tmp <<= shift;
198 tmp += mult / 2;
199 do_div(tmp, mult);
200
201 cycles_per_jiffy = tmp;
202 }
203
204 /* This sets up the high precision timer for the first interrupt. */
205 avr32_hpt_init(avr32_hpt_read());
206
207 printk("After time_init: count=%08lx, compare=%08lx\n",
208 (unsigned long)sysreg_read(COUNT),
209 (unsigned long)sysreg_read(COMPARE));
210
211 ret = clocksource_register(&clocksource_avr32);
212 if (ret)
213 printk(KERN_ERR
214 "timer: could not register clocksource: %d\n", ret);
215
216 ret = setup_irq(0, &timer_irqaction);
217 if (ret)
218 printk("timer: could not request IRQ 0: %d\n", ret);
219}
220
221static struct sysdev_class timer_class = {
222 set_kset_name("timer"),
223};
224
225static struct sys_device timer_device = {
226 .id = 0,
227 .cls = &timer_class,
228};
229
230static int __init init_timer_sysfs(void)
231{
232 int err = sysdev_class_register(&timer_class);
233 if (!err)
234 err = sysdev_register(&timer_device);
235 return err;
236}
237
238device_initcall(init_timer_sysfs);
diff --git a/arch/avr32/kernel/traps.c b/arch/avr32/kernel/traps.c
new file mode 100644
index 000000000000..7e803f4d7a12
--- /dev/null
+++ b/arch/avr32/kernel/traps.c
@@ -0,0 +1,425 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#undef DEBUG
9#include <linux/sched.h>
10#include <linux/init.h>
11#include <linux/module.h>
12#include <linux/kallsyms.h>
13#include <linux/notifier.h>
14
15#include <asm/traps.h>
16#include <asm/sysreg.h>
17#include <asm/addrspace.h>
18#include <asm/ocd.h>
19#include <asm/mmu_context.h>
20#include <asm/uaccess.h>
21
22static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
23{
24 unsigned long p;
25 int i;
26
27 printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
28
29 for (p = bottom & ~31; p < top; ) {
30 printk("%04lx: ", p & 0xffff);
31
32 for (i = 0; i < 8; i++, p += 4) {
33 unsigned int val;
34
35 if (p < bottom || p >= top)
36 printk(" ");
37 else {
38 if (__get_user(val, (unsigned int __user *)p)) {
39 printk("\n");
40 goto out;
41 }
42 printk("%08x ", val);
43 }
44 }
45 printk("\n");
46 }
47
48out:
49 return;
50}
51
52#ifdef CONFIG_FRAME_POINTER
53static inline void __show_trace(struct task_struct *tsk, unsigned long *sp,
54 struct pt_regs *regs)
55{
56 unsigned long __user *fp;
57 unsigned long __user *last_fp = NULL;
58
59 if (regs) {
60 fp = (unsigned long __user *)regs->r7;
61 } else if (tsk == current) {
62 register unsigned long __user *real_fp __asm__("r7");
63 fp = real_fp;
64 } else {
65 fp = (unsigned long __user *)tsk->thread.cpu_context.r7;
66 }
67
68 /*
69 * Walk the stack until (a) we get an exception, (b) the frame
70 * pointer becomes zero, or (c) the frame pointer gets stuck
71 * at the same value.
72 */
73 while (fp && fp != last_fp) {
74 unsigned long lr, new_fp = 0;
75
76 last_fp = fp;
77 if (__get_user(lr, fp))
78 break;
79 if (fp && __get_user(new_fp, fp + 1))
80 break;
81 fp = (unsigned long __user *)new_fp;
82
83 printk(" [<%08lx>] ", lr);
84 print_symbol("%s\n", lr);
85 }
86 printk("\n");
87}
88#else
89static inline void __show_trace(struct task_struct *tsk, unsigned long *sp,
90 struct pt_regs *regs)
91{
92 unsigned long addr;
93
94 while (!kstack_end(sp)) {
95 addr = *sp++;
96 if (kernel_text_address(addr)) {
97 printk(" [<%08lx>] ", addr);
98 print_symbol("%s\n", addr);
99 }
100 }
101}
102#endif
103
104void show_trace(struct task_struct *tsk, unsigned long *sp,
105 struct pt_regs *regs)
106{
107 if (regs &&
108 (((regs->sr & MODE_MASK) == MODE_EXCEPTION) ||
109 ((regs->sr & MODE_MASK) == MODE_USER)))
110 return;
111
112 printk ("Call trace:");
113#ifdef CONFIG_KALLSYMS
114 printk("\n");
115#endif
116
117 __show_trace(tsk, sp, regs);
118 printk("\n");
119}
120
121void show_stack(struct task_struct *tsk, unsigned long *sp)
122{
123 unsigned long stack;
124
125 if (!tsk)
126 tsk = current;
127 if (sp == 0) {
128 if (tsk == current) {
129 register unsigned long *real_sp __asm__("sp");
130 sp = real_sp;
131 } else {
132 sp = (unsigned long *)tsk->thread.cpu_context.ksp;
133 }
134 }
135
136 stack = (unsigned long)sp;
137 dump_mem("Stack: ", stack,
138 THREAD_SIZE + (unsigned long)tsk->thread_info);
139 show_trace(tsk, sp, NULL);
140}
141
142void dump_stack(void)
143{
144 show_stack(NULL, NULL);
145}
146EXPORT_SYMBOL(dump_stack);
147
148ATOMIC_NOTIFIER_HEAD(avr32_die_chain);
149
150int register_die_notifier(struct notifier_block *nb)
151{
152 pr_debug("register_die_notifier: %p\n", nb);
153
154 return atomic_notifier_chain_register(&avr32_die_chain, nb);
155}
156EXPORT_SYMBOL(register_die_notifier);
157
158int unregister_die_notifier(struct notifier_block *nb)
159{
160 return atomic_notifier_chain_unregister(&avr32_die_chain, nb);
161}
162EXPORT_SYMBOL(unregister_die_notifier);
163
164static DEFINE_SPINLOCK(die_lock);
165
166void __die(const char *str, struct pt_regs *regs, unsigned long err,
167 const char *file, const char *func, unsigned long line)
168{
169 struct task_struct *tsk = current;
170 static int die_counter;
171
172 console_verbose();
173 spin_lock_irq(&die_lock);
174 bust_spinlocks(1);
175
176 printk(KERN_ALERT "%s", str);
177 if (file && func)
178 printk(" in %s:%s, line %ld", file, func, line);
179 printk("[#%d]:\n", ++die_counter);
180 print_modules();
181 show_regs(regs);
182 printk("Process %s (pid: %d, stack limit = 0x%p)\n",
183 tsk->comm, tsk->pid, tsk->thread_info + 1);
184
185 if (!user_mode(regs) || in_interrupt()) {
186 dump_mem("Stack: ", regs->sp,
187 THREAD_SIZE + (unsigned long)tsk->thread_info);
188 }
189
190 bust_spinlocks(0);
191 spin_unlock_irq(&die_lock);
192 do_exit(SIGSEGV);
193}
194
195void __die_if_kernel(const char *str, struct pt_regs *regs, unsigned long err,
196 const char *file, const char *func, unsigned long line)
197{
198 if (!user_mode(regs))
199 __die(str, regs, err, file, func, line);
200}
201
202asmlinkage void do_nmi(unsigned long ecr, struct pt_regs *regs)
203{
204#ifdef CONFIG_SUBARCH_AVR32B
205 /*
206 * The exception entry always saves RSR_EX. For NMI, this is
207 * wrong; it should be RSR_NMI
208 */
209 regs->sr = sysreg_read(RSR_NMI);
210#endif
211
212 printk("NMI taken!!!!\n");
213 die("NMI", regs, ecr);
214 BUG();
215}
216
217asmlinkage void do_critical_exception(unsigned long ecr, struct pt_regs *regs)
218{
219 printk("Unable to handle critical exception %lu at pc = %08lx!\n",
220 ecr, regs->pc);
221 die("Oops", regs, ecr);
222 BUG();
223}
224
225asmlinkage void do_address_exception(unsigned long ecr, struct pt_regs *regs)
226{
227 siginfo_t info;
228
229 die_if_kernel("Oops: Address exception in kernel mode", regs, ecr);
230
231#ifdef DEBUG
232 if (ecr == ECR_ADDR_ALIGN_X)
233 pr_debug("Instruction Address Exception at pc = %08lx\n",
234 regs->pc);
235 else if (ecr == ECR_ADDR_ALIGN_R)
236 pr_debug("Data Address Exception (Read) at pc = %08lx\n",
237 regs->pc);
238 else if (ecr == ECR_ADDR_ALIGN_W)
239 pr_debug("Data Address Exception (Write) at pc = %08lx\n",
240 regs->pc);
241 else
242 BUG();
243
244 show_regs(regs);
245#endif
246
247 info.si_signo = SIGBUS;
248 info.si_errno = 0;
249 info.si_code = BUS_ADRALN;
250 info.si_addr = (void __user *)regs->pc;
251
252 force_sig_info(SIGBUS, &info, current);
253}
254
255/* This way of handling undefined instructions is stolen from ARM */
256static LIST_HEAD(undef_hook);
257static spinlock_t undef_lock = SPIN_LOCK_UNLOCKED;
258
259void register_undef_hook(struct undef_hook *hook)
260{
261 spin_lock_irq(&undef_lock);
262 list_add(&hook->node, &undef_hook);
263 spin_unlock_irq(&undef_lock);
264}
265
266void unregister_undef_hook(struct undef_hook *hook)
267{
268 spin_lock_irq(&undef_lock);
269 list_del(&hook->node);
270 spin_unlock_irq(&undef_lock);
271}
272
273static int do_cop_absent(u32 insn)
274{
275 int cop_nr;
276 u32 cpucr;
277 if ( (insn & 0xfdf00000) == 0xf1900000 )
278 /* LDC0 */
279 cop_nr = 0;
280 else
281 cop_nr = (insn >> 13) & 0x7;
282
283 /* Try enabling the coprocessor */
284 cpucr = sysreg_read(CPUCR);
285 cpucr |= (1 << (24 + cop_nr));
286 sysreg_write(CPUCR, cpucr);
287
288 cpucr = sysreg_read(CPUCR);
289 if ( !(cpucr & (1 << (24 + cop_nr))) ){
290 printk("Coprocessor #%i not found!\n", cop_nr);
291 return -1;
292 }
293
294 return 0;
295}
296
297#ifdef CONFIG_BUG
298#ifdef CONFIG_DEBUG_BUGVERBOSE
299static inline void do_bug_verbose(struct pt_regs *regs, u32 insn)
300{
301 char *file;
302 u16 line;
303 char c;
304
305 if (__get_user(line, (u16 __user *)(regs->pc + 2)))
306 return;
307 if (__get_user(file, (char * __user *)(regs->pc + 4))
308 || (unsigned long)file < PAGE_OFFSET
309 || __get_user(c, file))
310 file = "<bad filename>";
311
312 printk(KERN_ALERT "kernel BUG at %s:%d!\n", file, line);
313}
314#else
315static inline void do_bug_verbose(struct pt_regs *regs, u32 insn)
316{
317
318}
319#endif
320#endif
321
322asmlinkage void do_illegal_opcode(unsigned long ecr, struct pt_regs *regs)
323{
324 u32 insn;
325 struct undef_hook *hook;
326 siginfo_t info;
327 void __user *pc;
328
329 if (!user_mode(regs))
330 goto kernel_trap;
331
332 local_irq_enable();
333
334 pc = (void __user *)instruction_pointer(regs);
335 if (__get_user(insn, (u32 __user *)pc))
336 goto invalid_area;
337
338 if (ecr == ECR_COPROC_ABSENT) {
339 if (do_cop_absent(insn) == 0)
340 return;
341 }
342
343 spin_lock_irq(&undef_lock);
344 list_for_each_entry(hook, &undef_hook, node) {
345 if ((insn & hook->insn_mask) == hook->insn_val) {
346 if (hook->fn(regs, insn) == 0) {
347 spin_unlock_irq(&undef_lock);
348 return;
349 }
350 }
351 }
352 spin_unlock_irq(&undef_lock);
353
354invalid_area:
355
356#ifdef DEBUG
357 printk("Illegal instruction at pc = %08lx\n", regs->pc);
358 if (regs->pc < TASK_SIZE) {
359 unsigned long ptbr, pgd, pte, *p;
360
361 ptbr = sysreg_read(PTBR);
362 p = (unsigned long *)ptbr;
363 pgd = p[regs->pc >> 22];
364 p = (unsigned long *)((pgd & 0x1ffff000) | 0x80000000);
365 pte = p[(regs->pc >> 12) & 0x3ff];
366 printk("page table: 0x%08lx -> 0x%08lx -> 0x%08lx\n", ptbr, pgd, pte);
367 }
368#endif
369
370 info.si_signo = SIGILL;
371 info.si_errno = 0;
372 info.si_addr = (void __user *)regs->pc;
373 switch (ecr) {
374 case ECR_ILLEGAL_OPCODE:
375 case ECR_UNIMPL_INSTRUCTION:
376 info.si_code = ILL_ILLOPC;
377 break;
378 case ECR_PRIVILEGE_VIOLATION:
379 info.si_code = ILL_PRVOPC;
380 break;
381 case ECR_COPROC_ABSENT:
382 info.si_code = ILL_COPROC;
383 break;
384 default:
385 BUG();
386 }
387
388 force_sig_info(SIGILL, &info, current);
389 return;
390
391kernel_trap:
392#ifdef CONFIG_BUG
393 if (__kernel_text_address(instruction_pointer(regs))) {
394 insn = *(u16 *)instruction_pointer(regs);
395 if (insn == AVR32_BUG_OPCODE) {
396 do_bug_verbose(regs, insn);
397 die("Kernel BUG", regs, 0);
398 return;
399 }
400 }
401#endif
402
403 die("Oops: Illegal instruction in kernel code", regs, ecr);
404}
405
406asmlinkage void do_fpe(unsigned long ecr, struct pt_regs *regs)
407{
408 siginfo_t info;
409
410 printk("Floating-point exception at pc = %08lx\n", regs->pc);
411
412 /* We have no FPU... */
413 info.si_signo = SIGILL;
414 info.si_errno = 0;
415 info.si_addr = (void __user *)regs->pc;
416 info.si_code = ILL_COPROC;
417
418 force_sig_info(SIGILL, &info, current);
419}
420
421
422void __init trap_init(void)
423{
424
425}
diff --git a/arch/avr32/kernel/vmlinux.lds.c b/arch/avr32/kernel/vmlinux.lds.c
new file mode 100644
index 000000000000..cdd627c6b7dc
--- /dev/null
+++ b/arch/avr32/kernel/vmlinux.lds.c
@@ -0,0 +1,139 @@
1/*
2 * AVR32 linker script for the Linux kernel
3 *
4 * Copyright (C) 2004-2006 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#define LOAD_OFFSET 0x00000000
11#include <asm-generic/vmlinux.lds.h>
12
13OUTPUT_FORMAT("elf32-avr32", "elf32-avr32", "elf32-avr32")
14OUTPUT_ARCH(avr32)
15ENTRY(_start)
16
17/* Big endian */
18jiffies = jiffies_64 + 4;
19
20SECTIONS
21{
22 . = CONFIG_ENTRY_ADDRESS;
23 .init : AT(ADDR(.init) - LOAD_OFFSET) {
24 _stext = .;
25 __init_begin = .;
26 _sinittext = .;
27 *(.text.reset)
28 *(.init.text)
29 _einittext = .;
30 . = ALIGN(4);
31 __tagtable_begin = .;
32 *(.taglist)
33 __tagtable_end = .;
34 *(.init.data)
35 . = ALIGN(16);
36 __setup_start = .;
37 *(.init.setup)
38 __setup_end = .;
39 . = ALIGN(4);
40 __initcall_start = .;
41 *(.initcall1.init)
42 *(.initcall2.init)
43 *(.initcall3.init)
44 *(.initcall4.init)
45 *(.initcall5.init)
46 *(.initcall6.init)
47 *(.initcall7.init)
48 __initcall_end = .;
49 __con_initcall_start = .;
50 *(.con_initcall.init)
51 __con_initcall_end = .;
52 __security_initcall_start = .;
53 *(.security_initcall.init)
54 __security_initcall_end = .;
55 . = ALIGN(32);
56 __initramfs_start = .;
57 *(.init.ramfs)
58 __initramfs_end = .;
59 . = ALIGN(4096);
60 __init_end = .;
61 }
62
63 . = ALIGN(8192);
64 .text : AT(ADDR(.text) - LOAD_OFFSET) {
65 _evba = .;
66 _text = .;
67 *(.ex.text)
68 . = 0x50;
69 *(.tlbx.ex.text)
70 . = 0x60;
71 *(.tlbr.ex.text)
72 . = 0x70;
73 *(.tlbw.ex.text)
74 . = 0x100;
75 *(.scall.text)
76 *(.irq.text)
77 *(.text)
78 SCHED_TEXT
79 LOCK_TEXT
80 KPROBES_TEXT
81 *(.fixup)
82 *(.gnu.warning)
83 _etext = .;
84 } = 0xd703d703
85
86 . = ALIGN(4);
87 __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
88 __start___ex_table = .;
89 *(__ex_table)
90 __stop___ex_table = .;
91 }
92
93 RODATA
94
95 . = ALIGN(8192);
96
97 .data : AT(ADDR(.data) - LOAD_OFFSET) {
98 _data = .;
99 _sdata = .;
100 /*
101 * First, the init task union, aligned to an 8K boundary.
102 */
103 *(.data.init_task)
104
105 /* Then, the cacheline aligned data */
106 . = ALIGN(32);
107 *(.data.cacheline_aligned)
108
109 /* And the rest... */
110 *(.data.rel*)
111 *(.data)
112 CONSTRUCTORS
113
114 _edata = .;
115 }
116
117
118 . = ALIGN(8);
119 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
120 __bss_start = .;
121 *(.bss)
122 *(COMMON)
123 . = ALIGN(8);
124 __bss_stop = .;
125 _end = .;
126 }
127
128 /* When something in the kernel is NOT compiled as a module, the module
129 * cleanup code and data are put into these segments. Both can then be
130 * thrown away, as cleanup code is never called unless it's a module.
131 */
132 /DISCARD/ : {
133 *(.exit.text)
134 *(.exit.data)
135 *(.exitcall.exit)
136 }
137
138 DWARF_DEBUG
139}
diff --git a/arch/avr32/lib/Makefile b/arch/avr32/lib/Makefile
new file mode 100644
index 000000000000..09ac43e40522
--- /dev/null
+++ b/arch/avr32/lib/Makefile
@@ -0,0 +1,10 @@
1#
2# Makefile for AVR32-specific library files
3#
4
5lib-y := copy_user.o clear_user.o
6lib-y += strncpy_from_user.o strnlen_user.o
7lib-y += delay.o memset.o memcpy.o findbit.o
8lib-y += csum_partial.o csum_partial_copy_generic.o
9lib-y += io-readsw.o io-readsl.o io-writesw.o io-writesl.o
10lib-y += __avr32_lsl64.o __avr32_lsr64.o __avr32_asr64.o
diff --git a/arch/avr32/lib/__avr32_asr64.S b/arch/avr32/lib/__avr32_asr64.S
new file mode 100644
index 000000000000..368b6bca4c76
--- /dev/null
+++ b/arch/avr32/lib/__avr32_asr64.S
@@ -0,0 +1,31 @@
1/*
2 * Copyright (C) 2005-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9 /*
10 * DWtype __avr32_asr64(DWtype u, word_type b)
11 */
12 .text
13 .global __avr32_asr64
14 .type __avr32_asr64,@function
15__avr32_asr64:
16 cp.w r12, 0
17 reteq r12
18
19 rsub r9, r12, 32
20 brle 1f
21
22 lsl r8, r11, r9
23 lsr r10, r10, r12
24 asr r11, r11, r12
25 or r10, r8
26 retal r12
27
281: neg r9
29 asr r10, r11, r9
30 asr r11, 31
31 retal r12
diff --git a/arch/avr32/lib/__avr32_lsl64.S b/arch/avr32/lib/__avr32_lsl64.S
new file mode 100644
index 000000000000..f1dbc2b36257
--- /dev/null
+++ b/arch/avr32/lib/__avr32_lsl64.S
@@ -0,0 +1,31 @@
1/*
2 * Copyright (C) 2005-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9 /*
10 * DWtype __avr32_lsl64(DWtype u, word_type b)
11 */
12 .text
13 .global __avr32_lsl64
14 .type __avr32_lsl64,@function
15__avr32_lsl64:
16 cp.w r12, 0
17 reteq r12
18
19 rsub r9, r12, 32
20 brle 1f
21
22 lsr r8, r10, r9
23 lsl r10, r10, r12
24 lsl r11, r11, r12
25 or r11, r8
26 retal r12
27
281: neg r9
29 lsl r11, r10, r9
30 mov r10, 0
31 retal r12
diff --git a/arch/avr32/lib/__avr32_lsr64.S b/arch/avr32/lib/__avr32_lsr64.S
new file mode 100644
index 000000000000..e65bb7f0d24c
--- /dev/null
+++ b/arch/avr32/lib/__avr32_lsr64.S
@@ -0,0 +1,31 @@
1/*
2 * Copyright (C) 2005-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9 /*
10 * DWtype __avr32_lsr64(DWtype u, word_type b)
11 */
12 .text
13 .global __avr32_lsr64
14 .type __avr32_lsr64,@function
15__avr32_lsr64:
16 cp.w r12, 0
17 reteq r12
18
19 rsub r9, r12, 32
20 brle 1f
21
22 lsl r8, r11, r9
23 lsr r11, r11, r12
24 lsr r10, r10, r12
25 or r10, r8
26 retal r12
27
281: neg r9
29 lsr r10, r11, r9
30 mov r11, 0
31 retal r12
diff --git a/arch/avr32/lib/clear_user.S b/arch/avr32/lib/clear_user.S
new file mode 100644
index 000000000000..d8991b6f8eb7
--- /dev/null
+++ b/arch/avr32/lib/clear_user.S
@@ -0,0 +1,76 @@
1/*
2 * Copyright 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#include <asm/page.h>
9#include <asm/thread_info.h>
10#include <asm/asm.h>
11
12 .text
13 .align 1
14 .global clear_user
15 .type clear_user, "function"
16clear_user:
17 branch_if_kernel r8, __clear_user
18 ret_if_privileged r8, r12, r11, r11
19
20 .global __clear_user
21 .type __clear_user, "function"
22__clear_user:
23 mov r9, r12
24 mov r8, 0
25 andl r9, 3, COH
26 brne 5f
27
281: sub r11, 4
29 brlt 2f
30
3110: st.w r12++, r8
32 sub r11, 4
33 brge 10b
34
352: sub r11, -4
36 reteq 0
37
38 /* Unaligned count or address */
39 bld r11, 1
40 brcc 12f
4111: st.h r12++, r8
42 sub r11, 2
43 reteq 0
4412: st.b r12++, r8
45 retal 0
46
47 /* Unaligned address */
485: cp.w r11, 4
49 brlt 2b
50
51 lsl r9, 2
52 add pc, pc, r9
5313: st.b r12++, r8
54 sub r11, 1
5514: st.b r12++, r8
56 sub r11, 1
5715: st.b r12++, r8
58 sub r11, 1
59 rjmp 1b
60
61 .size clear_user, . - clear_user
62 .size __clear_user, . - __clear_user
63
64 .section .fixup, "ax"
65 .align 1
6618: sub r11, -4
6719: retal r11
68
69 .section __ex_table, "a"
70 .align 2
71 .long 10b, 18b
72 .long 11b, 19b
73 .long 12b, 19b
74 .long 13b, 19b
75 .long 14b, 19b
76 .long 15b, 19b
diff --git a/arch/avr32/lib/copy_user.S b/arch/avr32/lib/copy_user.S
new file mode 100644
index 000000000000..ea59c04b07de
--- /dev/null
+++ b/arch/avr32/lib/copy_user.S
@@ -0,0 +1,119 @@
1/*
2 * Copy to/from userspace with optional address space checking.
3 *
4 * Copyright 2004-2006 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <asm/page.h>
11#include <asm/thread_info.h>
12#include <asm/asm.h>
13
14 /*
15 * __kernel_size_t
16 * __copy_user(void *to, const void *from, __kernel_size_t n)
17 *
18 * Returns the number of bytes not copied. Might be off by
19 * max 3 bytes if we get a fault in the main loop.
20 *
21 * The address-space checking functions simply fall through to
22 * the non-checking version.
23 */
24 .text
25 .align 1
26 .global copy_from_user
27 .type copy_from_user, @function
28copy_from_user:
29 branch_if_kernel r8, __copy_user
30 ret_if_privileged r8, r11, r10, r10
31 rjmp __copy_user
32 .size copy_from_user, . - copy_from_user
33
34 .global copy_to_user
35 .type copy_to_user, @function
36copy_to_user:
37 branch_if_kernel r8, __copy_user
38 ret_if_privileged r8, r12, r10, r10
39 .size copy_to_user, . - copy_to_user
40
41 .global __copy_user
42 .type __copy_user, @function
43__copy_user:
44 mov r9, r11
45 andl r9, 3, COH
46 brne 6f
47
48 /* At this point, from is word-aligned */
491: sub r10, 4
50 brlt 3f
51
522:
5310: ld.w r8, r11++
5411: st.w r12++, r8
55 sub r10, 4
56 brge 2b
57
583: sub r10, -4
59 reteq 0
60
61 /*
62 * Handle unaligned count. Need to be careful with r10 here so
63 * that we return the correct value even if we get a fault
64 */
654:
6620: ld.ub r8, r11++
6721: st.b r12++, r8
68 sub r10, 1
69 reteq 0
7022: ld.ub r8, r11++
7123: st.b r12++, r8
72 sub r10, 1
73 reteq 0
7424: ld.ub r8, r11++
7525: st.b r12++, r8
76 retal 0
77
78 /* Handle unaligned from-pointer */
796: cp.w r10, 4
80 brlt 4b
81 rsub r9, r9, 4
82
8330: ld.ub r8, r11++
8431: st.b r12++, r8
85 sub r10, 1
86 sub r9, 1
87 breq 1b
8832: ld.ub r8, r11++
8933: st.b r12++, r8
90 sub r10, 1
91 sub r9, 1
92 breq 1b
9334: ld.ub r8, r11++
9435: st.b r12++, r8
95 sub r10, 1
96 rjmp 1b
97 .size __copy_user, . - __copy_user
98
99 .section .fixup,"ax"
100 .align 1
10119: sub r10, -4
10229: retal r10
103
104 .section __ex_table,"a"
105 .align 2
106 .long 10b, 19b
107 .long 11b, 19b
108 .long 20b, 29b
109 .long 21b, 29b
110 .long 22b, 29b
111 .long 23b, 29b
112 .long 24b, 29b
113 .long 25b, 29b
114 .long 30b, 29b
115 .long 31b, 29b
116 .long 32b, 29b
117 .long 33b, 29b
118 .long 34b, 29b
119 .long 35b, 29b
diff --git a/arch/avr32/lib/csum_partial.S b/arch/avr32/lib/csum_partial.S
new file mode 100644
index 000000000000..6a262b528eb7
--- /dev/null
+++ b/arch/avr32/lib/csum_partial.S
@@ -0,0 +1,47 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9 /*
10 * unsigned int csum_partial(const unsigned char *buff,
11 * int len, unsigned int sum)
12 */
13 .text
14 .global csum_partial
15 .type csum_partial,"function"
16 .align 1
17csum_partial:
18 /* checksum complete words, aligned or not */
193: sub r11, 4
20 brlt 5f
214: ld.w r9, r12++
22 add r10, r9
23 acr r10
24 sub r11, 4
25 brge 4b
26
27 /* return if we had a whole number of words */
285: sub r11, -4
29 reteq r10
30
31 /* checksum any remaining bytes at the end */
32 mov r9, 0
33 mov r8, 0
34 cp r11, 2
35 brlt 6f
36 ld.uh r9, r12++
37 sub r11, 2
38 breq 7f
39 lsl r9, 16
406: ld.ub r8, r12++
41 lsl r8, 8
427: or r9, r8
43 add r10, r9
44 acr r10
45
46 retal r10
47 .size csum_partial, . - csum_partial
diff --git a/arch/avr32/lib/csum_partial_copy_generic.S b/arch/avr32/lib/csum_partial_copy_generic.S
new file mode 100644
index 000000000000..a3a0f9b8929c
--- /dev/null
+++ b/arch/avr32/lib/csum_partial_copy_generic.S
@@ -0,0 +1,99 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#include <asm/errno.h>
9#include <asm/asm.h>
10
11 /*
12 * unsigned int csum_partial_copy_generic(const char *src, char *dst, int len
13 * int sum, int *src_err_ptr,
14 * int *dst_err_ptr)
15 *
16 * Copy src to dst while checksumming, otherwise like csum_partial.
17 */
18
19 .macro ld_src size, reg, ptr
209999: ld.\size \reg, \ptr
21 .section __ex_table, "a"
22 .long 9999b, fixup_ld_src
23 .previous
24 .endm
25
26 .macro st_dst size, ptr, reg
279999: st.\size \ptr, \reg
28 .section __ex_table, "a"
29 .long 9999b, fixup_st_dst
30 .previous
31 .endm
32
33 .text
34 .global csum_partial_copy_generic
35 .type csum_partial_copy_generic,"function"
36 .align 1
37csum_partial_copy_generic:
38 pushm r4-r7,lr
39
40 /* The inner loop */
411: sub r10, 4
42 brlt 5f
432: ld_src w, r5, r12++
44 st_dst w, r11++, r5
45 add r9, r5
46 acr r9
47 sub r10, 4
48 brge 2b
49
50 /* return if we had a whole number of words */
515: sub r10, -4
52 brne 7f
53
546: mov r12, r9
55 popm r4-r7,pc
56
57 /* handle additional bytes at the tail */
587: mov r5, 0
59 mov r4, 32
608: ld_src ub, r6, r12++
61 st_dst b, r11++, r6
62 lsl r5, 8
63 sub r4, 8
64 bfins r5, r6, 0, 8
65 sub r10, 1
66 brne 8b
67
68 lsl r5, r5, r4
69 add r9, r5
70 acr r9
71 rjmp 6b
72
73 /* Exception handler */
74 .section .fixup,"ax"
75 .align 1
76fixup_ld_src:
77 mov r9, -EFAULT
78 cp.w r8, 0
79 breq 1f
80 st.w r8[0], r9
81
821: /*
83 * TODO: zero the complete destination - computing the rest
84 * is too much work
85 */
86
87 mov r9, 0
88 rjmp 6b
89
90fixup_st_dst:
91 mov r9, -EFAULT
92 lddsp r8, sp[20]
93 cp.w r8, 0
94 breq 1f
95 st.w r8[0], r9
961: mov r9, 0
97 rjmp 6b
98
99 .previous
diff --git a/arch/avr32/lib/delay.c b/arch/avr32/lib/delay.c
new file mode 100644
index 000000000000..462c8307b680
--- /dev/null
+++ b/arch/avr32/lib/delay.c
@@ -0,0 +1,55 @@
1/*
2 * Precise Delay Loops for avr32
3 *
4 * Copyright (C) 1993 Linus Torvalds
5 * Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
6 * Copyright (C) 2005-2006 Atmel Corporation
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/delay.h>
14#include <linux/module.h>
15#include <linux/types.h>
16
17#include <asm/delay.h>
18#include <asm/processor.h>
19#include <asm/sysreg.h>
20
21int read_current_timer(unsigned long *timer_value)
22{
23 *timer_value = sysreg_read(COUNT);
24 return 0;
25}
26
27void __delay(unsigned long loops)
28{
29 unsigned bclock, now;
30
31 bclock = sysreg_read(COUNT);
32 do {
33 now = sysreg_read(COUNT);
34 } while ((now - bclock) < loops);
35}
36
37inline void __const_udelay(unsigned long xloops)
38{
39 unsigned long long loops;
40
41 asm("mulu.d %0, %1, %2"
42 : "=r"(loops)
43 : "r"(current_cpu_data.loops_per_jiffy * HZ), "r"(xloops));
44 __delay(loops >> 32);
45}
46
47void __udelay(unsigned long usecs)
48{
49 __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */
50}
51
52void __ndelay(unsigned long nsecs)
53{
54 __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */
55}
diff --git a/arch/avr32/lib/findbit.S b/arch/avr32/lib/findbit.S
new file mode 100644
index 000000000000..2b4856f4bf7c
--- /dev/null
+++ b/arch/avr32/lib/findbit.S
@@ -0,0 +1,154 @@
1/*
2 * Copyright (C) 2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#include <linux/linkage.h>
9
10 .text
11 /*
12 * unsigned long find_first_zero_bit(const unsigned long *addr,
13 * unsigned long size)
14 */
15ENTRY(find_first_zero_bit)
16 cp.w r11, 0
17 reteq r11
18 mov r9, r11
191: ld.w r8, r12[0]
20 com r8
21 brne .L_found
22 sub r12, -4
23 sub r9, 32
24 brgt 1b
25 retal r11
26
27 /*
28 * unsigned long find_next_zero_bit(const unsigned long *addr,
29 * unsigned long size,
30 * unsigned long offset)
31 */
32ENTRY(find_next_zero_bit)
33 lsr r8, r10, 5
34 sub r9, r11, r10
35 retle r11
36
37 lsl r8, 2
38 add r12, r8
39 andl r10, 31, COH
40 breq 1f
41
42 /* offset is not word-aligned. Handle the first (32 - r10) bits */
43 ld.w r8, r12[0]
44 com r8
45 sub r12, -4
46 lsr r8, r8, r10
47 brne .L_found
48
49 /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */
50 add r9, r10
51 sub r9, 32
52 retle r11
53
54 /* Main loop. offset must be word-aligned */
551: ld.w r8, r12[0]
56 com r8
57 brne .L_found
58 sub r12, -4
59 sub r9, 32
60 brgt 1b
61 retal r11
62
63 /* Common return path for when a bit is actually found. */
64.L_found:
65 brev r8
66 clz r10, r8
67 rsub r9, r11
68 add r10, r9
69
70 /* XXX: If we don't have to return exactly "size" when the bit
71 is not found, we may drop this "min" thing */
72 min r12, r11, r10
73 retal r12
74
75 /*
76 * unsigned long find_first_bit(const unsigned long *addr,
77 * unsigned long size)
78 */
79ENTRY(find_first_bit)
80 cp.w r11, 0
81 reteq r11
82 mov r9, r11
831: ld.w r8, r12[0]
84 cp.w r8, 0
85 brne .L_found
86 sub r12, -4
87 sub r9, 32
88 brgt 1b
89 retal r11
90
91 /*
92 * unsigned long find_next_bit(const unsigned long *addr,
93 * unsigned long size,
94 * unsigned long offset)
95 */
96ENTRY(find_next_bit)
97 lsr r8, r10, 5
98 sub r9, r11, r10
99 retle r11
100
101 lsl r8, 2
102 add r12, r8
103 andl r10, 31, COH
104 breq 1f
105
106 /* offset is not word-aligned. Handle the first (32 - r10) bits */
107 ld.w r8, r12[0]
108 sub r12, -4
109 lsr r8, r8, r10
110 brne .L_found
111
112 /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */
113 add r9, r10
114 sub r9, 32
115 retle r11
116
117 /* Main loop. offset must be word-aligned */
1181: ld.w r8, r12[0]
119 cp.w r8, 0
120 brne .L_found
121 sub r12, -4
122 sub r9, 32
123 brgt 1b
124 retal r11
125
126ENTRY(generic_find_next_zero_le_bit)
127 lsr r8, r10, 5
128 sub r9, r11, r10
129 retle r11
130
131 lsl r8, 2
132 add r12, r8
133 andl r10, 31, COH
134 breq 1f
135
136 /* offset is not word-aligned. Handle the first (32 - r10) bits */
137 ldswp.w r8, r12[0]
138 sub r12, -4
139 lsr r8, r8, r10
140 brne .L_found
141
142 /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */
143 add r9, r10
144 sub r9, 32
145 retle r11
146
147 /* Main loop. offset must be word-aligned */
1481: ldswp.w r8, r12[0]
149 cp.w r8, 0
150 brne .L_found
151 sub r12, -4
152 sub r9, 32
153 brgt 1b
154 retal r11
diff --git a/arch/avr32/lib/io-readsl.S b/arch/avr32/lib/io-readsl.S
new file mode 100644
index 000000000000..b103511ed6c4
--- /dev/null
+++ b/arch/avr32/lib/io-readsl.S
@@ -0,0 +1,24 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9 .global __raw_readsl
10 .type __raw_readsl,@function
11__raw_readsl:
12 cp.w r10, 0
13 reteq r12
14
15 /*
16 * If r11 isn't properly aligned, we might get an exception on
17 * some implementations. But there's not much we can do about it.
18 */
191: ld.w r8, r12[0]
20 sub r10, 1
21 st.w r11++, r8
22 brne 1b
23
24 retal r12
diff --git a/arch/avr32/lib/io-readsw.S b/arch/avr32/lib/io-readsw.S
new file mode 100644
index 000000000000..456be9909027
--- /dev/null
+++ b/arch/avr32/lib/io-readsw.S
@@ -0,0 +1,43 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9.Lnot_word_aligned:
10 /*
11 * Bad alignment will cause a hardware exception, which is as
12 * good as anything. No need for us to check for proper alignment.
13 */
14 ld.uh r8, r12[0]
15 sub r10, 1
16 st.h r11++, r8
17
18 /* fall through */
19
20 .global __raw_readsw
21 .type __raw_readsw,@function
22__raw_readsw:
23 cp.w r10, 0
24 reteq r12
25 mov r9, 3
26 tst r11, r9
27 brne .Lnot_word_aligned
28
29 sub r10, 2
30 brlt 2f
31
321: ldins.h r8:t, r12[0]
33 ldins.h r8:b, r12[0]
34 st.w r11++, r8
35 sub r10, 2
36 brge 1b
37
382: sub r10, -2
39 reteq r12
40
41 ld.uh r8, r12[0]
42 st.h r11++, r8
43 retal r12
diff --git a/arch/avr32/lib/io-writesl.S b/arch/avr32/lib/io-writesl.S
new file mode 100644
index 000000000000..22138b3a16e5
--- /dev/null
+++ b/arch/avr32/lib/io-writesl.S
@@ -0,0 +1,20 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9 .global __raw_writesl
10 .type __raw_writesl,@function
11__raw_writesl:
12 cp.w r10, 0
13 reteq r12
14
151: ld.w r8, r11++
16 sub r10, 1
17 st.w r12[0], r8
18 brne 1b
19
20 retal r12
diff --git a/arch/avr32/lib/io-writesw.S b/arch/avr32/lib/io-writesw.S
new file mode 100644
index 000000000000..8c4a53f1c52a
--- /dev/null
+++ b/arch/avr32/lib/io-writesw.S
@@ -0,0 +1,38 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9.Lnot_word_aligned:
10 ld.uh r8, r11++
11 sub r10, 1
12 st.h r12[0], r8
13
14 .global __raw_writesw
15 .type __raw_writesw,@function
16__raw_writesw:
17 cp.w r10, 0
18 mov r9, 3
19 reteq r12
20 tst r11, r9
21 brne .Lnot_word_aligned
22
23 sub r10, 2
24 brlt 2f
25
261: ld.w r8, r11++
27 bfextu r9, r8, 16, 16
28 st.h r12[0], r9
29 st.h r12[0], r8
30 sub r10, 2
31 brge 1b
32
332: sub r10, -2
34 reteq r12
35
36 ld.uh r8, r11++
37 st.h r12[0], r8
38 retal r12
diff --git a/arch/avr32/lib/libgcc.h b/arch/avr32/lib/libgcc.h
new file mode 100644
index 000000000000..5a091b5e3618
--- /dev/null
+++ b/arch/avr32/lib/libgcc.h
@@ -0,0 +1,33 @@
1/* Definitions for various functions 'borrowed' from gcc-3.4.3 */
2
3#define BITS_PER_UNIT 8
4
5typedef int QItype __attribute__ ((mode (QI)));
6typedef unsigned int UQItype __attribute__ ((mode (QI)));
7typedef int HItype __attribute__ ((mode (HI)));
8typedef unsigned int UHItype __attribute__ ((mode (HI)));
9typedef int SItype __attribute__ ((mode (SI)));
10typedef unsigned int USItype __attribute__ ((mode (SI)));
11typedef int DItype __attribute__ ((mode (DI)));
12typedef unsigned int UDItype __attribute__ ((mode (DI)));
13typedef float SFtype __attribute__ ((mode (SF)));
14typedef float DFtype __attribute__ ((mode (DF)));
15typedef int word_type __attribute__ ((mode (__word__)));
16
17#define W_TYPE_SIZE (4 * BITS_PER_UNIT)
18#define Wtype SItype
19#define UWtype USItype
20#define HWtype SItype
21#define UHWtype USItype
22#define DWtype DItype
23#define UDWtype UDItype
24#define __NW(a,b) __ ## a ## si ## b
25#define __NDW(a,b) __ ## a ## di ## b
26
27struct DWstruct {Wtype high, low;};
28
29typedef union
30{
31 struct DWstruct s;
32 DWtype ll;
33} DWunion;
diff --git a/arch/avr32/lib/longlong.h b/arch/avr32/lib/longlong.h
new file mode 100644
index 000000000000..cd5e369ac437
--- /dev/null
+++ b/arch/avr32/lib/longlong.h
@@ -0,0 +1,98 @@
1/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
2 Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000
3 Free Software Foundation, Inc.
4
5 This definition file is free software; you can redistribute it
6 and/or modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 2, or (at your option) any later version.
9
10 This definition file is distributed in the hope that it will be
11 useful, but WITHOUT ANY WARRANTY; without even the implied
12 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
19
20/* Borrowed from gcc-3.4.3 */
21
22#define __BITS4 (W_TYPE_SIZE / 4)
23#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
24#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
25#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
26
27#define count_leading_zeros(count, x) ((count) = __builtin_clz(x))
28
29#define __udiv_qrnnd_c(q, r, n1, n0, d) \
30 do { \
31 UWtype __d1, __d0, __q1, __q0; \
32 UWtype __r1, __r0, __m; \
33 __d1 = __ll_highpart (d); \
34 __d0 = __ll_lowpart (d); \
35 \
36 __r1 = (n1) % __d1; \
37 __q1 = (n1) / __d1; \
38 __m = (UWtype) __q1 * __d0; \
39 __r1 = __r1 * __ll_B | __ll_highpart (n0); \
40 if (__r1 < __m) \
41 { \
42 __q1--, __r1 += (d); \
43 if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
44 if (__r1 < __m) \
45 __q1--, __r1 += (d); \
46 } \
47 __r1 -= __m; \
48 \
49 __r0 = __r1 % __d1; \
50 __q0 = __r1 / __d1; \
51 __m = (UWtype) __q0 * __d0; \
52 __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
53 if (__r0 < __m) \
54 { \
55 __q0--, __r0 += (d); \
56 if (__r0 >= (d)) \
57 if (__r0 < __m) \
58 __q0--, __r0 += (d); \
59 } \
60 __r0 -= __m; \
61 \
62 (q) = (UWtype) __q1 * __ll_B | __q0; \
63 (r) = __r0; \
64 } while (0)
65
66#define udiv_qrnnd __udiv_qrnnd_c
67
68#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
69 do { \
70 UWtype __x; \
71 __x = (al) - (bl); \
72 (sh) = (ah) - (bh) - (__x > (al)); \
73 (sl) = __x; \
74 } while (0)
75
76#define umul_ppmm(w1, w0, u, v) \
77 do { \
78 UWtype __x0, __x1, __x2, __x3; \
79 UHWtype __ul, __vl, __uh, __vh; \
80 \
81 __ul = __ll_lowpart (u); \
82 __uh = __ll_highpart (u); \
83 __vl = __ll_lowpart (v); \
84 __vh = __ll_highpart (v); \
85 \
86 __x0 = (UWtype) __ul * __vl; \
87 __x1 = (UWtype) __ul * __vh; \
88 __x2 = (UWtype) __uh * __vl; \
89 __x3 = (UWtype) __uh * __vh; \
90 \
91 __x1 += __ll_highpart (__x0);/* this can't give carry */ \
92 __x1 += __x2; /* but this indeed can */ \
93 if (__x1 < __x2) /* did we get it? */ \
94 __x3 += __ll_B; /* yes, add it in the proper pos. */ \
95 \
96 (w1) = __x3 + __ll_highpart (__x1); \
97 (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
98 } while (0)
diff --git a/arch/avr32/lib/memcpy.S b/arch/avr32/lib/memcpy.S
new file mode 100644
index 000000000000..0abb26142b64
--- /dev/null
+++ b/arch/avr32/lib/memcpy.S
@@ -0,0 +1,62 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9 /*
10 * void *memcpy(void *to, const void *from, unsigned long n)
11 *
12 * This implementation does word-aligned loads in the main loop,
13 * possibly sacrificing alignment of stores.
14 *
15 * Hopefully, in most cases, both "to" and "from" will be
16 * word-aligned to begin with.
17 */
18 .text
19 .global memcpy
20 .type memcpy, @function
21memcpy:
22 mov r9, r11
23 andl r9, 3, COH
24 brne 1f
25
26 /* At this point, "from" is word-aligned */
272: sub r10, 4
28 mov r9, r12
29 brlt 4f
30
313: ld.w r8, r11++
32 sub r10, 4
33 st.w r12++, r8
34 brge 3b
35
364: neg r10
37 reteq r9
38
39 /* Handle unaligned count */
40 lsl r10, 2
41 add pc, pc, r10
42 ld.ub r8, r11++
43 st.b r12++, r8
44 ld.ub r8, r11++
45 st.b r12++, r8
46 ld.ub r8, r11++
47 st.b r12++, r8
48 retal r9
49
50 /* Handle unaligned "from" pointer */
511: sub r10, 4
52 brlt 4b
53 add r10, r9
54 lsl r9, 2
55 add pc, pc, r9
56 ld.ub r8, r11++
57 st.b r12++, r8
58 ld.ub r8, r11++
59 st.b r12++, r8
60 ld.ub r8, r11++
61 st.b r12++, r8
62 rjmp 2b
diff --git a/arch/avr32/lib/memset.S b/arch/avr32/lib/memset.S
new file mode 100644
index 000000000000..40da32c0480c
--- /dev/null
+++ b/arch/avr32/lib/memset.S
@@ -0,0 +1,72 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * Based on linux/arch/arm/lib/memset.S
5 * Copyright (C) 1995-2000 Russell King
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * ASM optimised string functions
12 */
13#include <asm/asm.h>
14
15 /*
16 * r12: void *b
17 * r11: int c
18 * r10: size_t len
19 *
20 * Returns b in r12
21 */
22 .text
23 .global memset
24 .type memset, @function
25 .align 5
26memset:
27 mov r9, r12
28 mov r8, r12
29 or r11, r11, r11 << 8
30 andl r9, 3, COH
31 brne 1f
32
332: or r11, r11, r11 << 16
34 sub r10, 4
35 brlt 5f
36
37 /* Let's do some real work */
384: st.w r8++, r11
39 sub r10, 4
40 brge 4b
41
42 /*
43 * When we get here, we've got less than 4 bytes to set. r10
44 * might be negative.
45 */
465: sub r10, -4
47 reteq r12
48
49 /* Fastpath ends here, exactly 32 bytes from memset */
50
51 /* Handle unaligned count or pointer */
52 bld r10, 1
53 brcc 6f
54 st.b r8++, r11
55 st.b r8++, r11
56 bld r10, 0
57 retcc r12
586: st.b r8++, r11
59 retal r12
60
61 /* Handle unaligned pointer */
621: sub r10, 4
63 brlt 5b
64 add r10, r9
65 lsl r9, 1
66 add pc, r9
67 st.b r8++, r11
68 st.b r8++, r11
69 st.b r8++, r11
70 rjmp 2b
71
72 .size memset, . - memset
diff --git a/arch/avr32/lib/strncpy_from_user.S b/arch/avr32/lib/strncpy_from_user.S
new file mode 100644
index 000000000000..72bd50599ec6
--- /dev/null
+++ b/arch/avr32/lib/strncpy_from_user.S
@@ -0,0 +1,60 @@
1/*
2 * Copy to/from userspace with optional address space checking.
3 *
4 * Copyright 2004-2006 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/errno.h>
11
12#include <asm/page.h>
13#include <asm/thread_info.h>
14#include <asm/asm.h>
15
16 /*
17 * long strncpy_from_user(char *dst, const char *src, long count)
18 *
19 * On success, returns the length of the string, not including
20 * the terminating NUL.
21 *
22 * If the string is longer than count, returns count
23 *
24 * If userspace access fails, returns -EFAULT
25 */
26 .text
27 .align 1
28 .global strncpy_from_user
29 .type strncpy_from_user, "function"
30strncpy_from_user:
31 mov r9, -EFAULT
32 branch_if_kernel r8, __strncpy_from_user
33 ret_if_privileged r8, r11, r10, r9
34
35 .global __strncpy_from_user
36 .type __strncpy_from_user, "function"
37__strncpy_from_user:
38 cp.w r10, 0
39 reteq 0
40
41 mov r9, r10
42
431: ld.ub r8, r11++
44 st.b r12++, r8
45 cp.w r8, 0
46 breq 2f
47 sub r9, 1
48 brne 1b
49
502: sub r10, r9
51 retal r10
52
53 .section .fixup, "ax"
54 .align 1
553: mov r12, -EFAULT
56 retal r12
57
58 .section __ex_table, "a"
59 .align 2
60 .long 1b, 3b
diff --git a/arch/avr32/lib/strnlen_user.S b/arch/avr32/lib/strnlen_user.S
new file mode 100644
index 000000000000..65ce11afa66a
--- /dev/null
+++ b/arch/avr32/lib/strnlen_user.S
@@ -0,0 +1,67 @@
1/*
2 * Copy to/from userspace with optional address space checking.
3 *
4 * Copyright 2004-2006 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <asm/page.h>
11#include <asm/thread_info.h>
12#include <asm/processor.h>
13#include <asm/asm.h>
14
15 .text
16 .align 1
17 .global strnlen_user
18 .type strnlen_user, "function"
19strnlen_user:
20 branch_if_kernel r8, __strnlen_user
21 sub r8, r11, 1
22 add r8, r12
23 retcs 0
24 brmi adjust_length /* do a closer inspection */
25
26 .global __strnlen_user
27 .type __strnlen_user, "function"
28__strnlen_user:
29 mov r10, r12
30
3110: ld.ub r8, r12++
32 cp.w r8, 0
33 breq 2f
34 sub r11, 1
35 brne 10b
36
37 sub r12, -1
382: sub r12, r10
39 retal r12
40
41
42 .type adjust_length, "function"
43adjust_length:
44 cp.w r12, 0 /* addr must always be < TASK_SIZE */
45 retmi 0
46
47 pushm lr
48 lddpc lr, _task_size
49 sub r11, lr, r12
50 mov r9, r11
51 rcall __strnlen_user
52 cp.w r12, r9
53 brgt 1f
54 popm pc
551: popm pc, r12=0
56
57 .align 2
58_task_size:
59 .long TASK_SIZE
60
61 .section .fixup, "ax"
62 .align 1
6319: retal 0
64
65 .section __ex_table, "a"
66 .align 2
67 .long 10b, 19b
diff --git a/arch/avr32/mach-at32ap/Makefile b/arch/avr32/mach-at32ap/Makefile
new file mode 100644
index 000000000000..f62eb6915510
--- /dev/null
+++ b/arch/avr32/mach-at32ap/Makefile
@@ -0,0 +1,2 @@
1obj-y += at32ap.o clock.o pio.o intc.o extint.o hsmc.o
2obj-$(CONFIG_CPU_AT32AP7000) += at32ap7000.o
diff --git a/arch/avr32/mach-at32ap/at32ap.c b/arch/avr32/mach-at32ap/at32ap.c
new file mode 100644
index 000000000000..f7cedf5aabea
--- /dev/null
+++ b/arch/avr32/mach-at32ap/at32ap.c
@@ -0,0 +1,90 @@
1/*
2 * Copyright (C) 2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/clk.h>
10#include <linux/err.h>
11#include <linux/init.h>
12#include <linux/platform_device.h>
13
14#include <asm/io.h>
15
16#include <asm/arch/init.h>
17#include <asm/arch/sm.h>
18
19struct at32_sm system_manager;
20
21static int __init at32_sm_init(void)
22{
23 struct resource *regs;
24 struct at32_sm *sm = &system_manager;
25 int ret = -ENXIO;
26
27 regs = platform_get_resource(&at32_sm_device, IORESOURCE_MEM, 0);
28 if (!regs)
29 goto fail;
30
31 spin_lock_init(&sm->lock);
32 sm->pdev = &at32_sm_device;
33
34 ret = -ENOMEM;
35 sm->regs = ioremap(regs->start, regs->end - regs->start + 1);
36 if (!sm->regs)
37 goto fail;
38
39 return 0;
40
41fail:
42 printk(KERN_ERR "Failed to initialize System Manager: %d\n", ret);
43 return ret;
44}
45
46void __init setup_platform(void)
47{
48 at32_sm_init();
49 at32_clock_init();
50 at32_portmux_init();
51
52 /* FIXME: This doesn't belong here */
53 at32_setup_serial_console(1);
54}
55
56static int __init pdc_probe(struct platform_device *pdev)
57{
58 struct clk *pclk, *hclk;
59
60 pclk = clk_get(&pdev->dev, "pclk");
61 if (IS_ERR(pclk)) {
62 dev_err(&pdev->dev, "no pclk defined\n");
63 return PTR_ERR(pclk);
64 }
65 hclk = clk_get(&pdev->dev, "hclk");
66 if (IS_ERR(hclk)) {
67 dev_err(&pdev->dev, "no hclk defined\n");
68 clk_put(pclk);
69 return PTR_ERR(hclk);
70 }
71
72 clk_enable(pclk);
73 clk_enable(hclk);
74
75 dev_info(&pdev->dev, "Atmel Peripheral DMA Controller enabled\n");
76 return 0;
77}
78
79static struct platform_driver pdc_driver = {
80 .probe = pdc_probe,
81 .driver = {
82 .name = "pdc",
83 },
84};
85
86static int __init pdc_init(void)
87{
88 return platform_driver_register(&pdc_driver);
89}
90arch_initcall(pdc_init);
diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c
new file mode 100644
index 000000000000..37982b60398e
--- /dev/null
+++ b/arch/avr32/mach-at32ap/at32ap7000.c
@@ -0,0 +1,876 @@
1/*
2 * Copyright (C) 2005-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#include <linux/clk.h>
9#include <linux/init.h>
10#include <linux/platform_device.h>
11
12#include <asm/io.h>
13
14#include <asm/arch/board.h>
15#include <asm/arch/portmux.h>
16#include <asm/arch/sm.h>
17
18#include "clock.h"
19#include "pio.h"
20#include "sm.h"
21
22#define PBMEM(base) \
23 { \
24 .start = base, \
25 .end = base + 0x3ff, \
26 .flags = IORESOURCE_MEM, \
27 }
28#define IRQ(num) \
29 { \
30 .start = num, \
31 .end = num, \
32 .flags = IORESOURCE_IRQ, \
33 }
34#define NAMED_IRQ(num, _name) \
35 { \
36 .start = num, \
37 .end = num, \
38 .name = _name, \
39 .flags = IORESOURCE_IRQ, \
40 }
41
42#define DEFINE_DEV(_name, _id) \
43static struct platform_device _name##_id##_device = { \
44 .name = #_name, \
45 .id = _id, \
46 .resource = _name##_id##_resource, \
47 .num_resources = ARRAY_SIZE(_name##_id##_resource), \
48}
49#define DEFINE_DEV_DATA(_name, _id) \
50static struct platform_device _name##_id##_device = { \
51 .name = #_name, \
52 .id = _id, \
53 .dev = { \
54 .platform_data = &_name##_id##_data, \
55 }, \
56 .resource = _name##_id##_resource, \
57 .num_resources = ARRAY_SIZE(_name##_id##_resource), \
58}
59
60#define DEV_CLK(_name, devname, bus, _index) \
61static struct clk devname##_##_name = { \
62 .name = #_name, \
63 .dev = &devname##_device.dev, \
64 .parent = &bus##_clk, \
65 .mode = bus##_clk_mode, \
66 .get_rate = bus##_clk_get_rate, \
67 .index = _index, \
68}
69
70enum {
71 PIOA,
72 PIOB,
73 PIOC,
74 PIOD,
75};
76
77enum {
78 FUNC_A,
79 FUNC_B,
80};
81
82unsigned long at32ap7000_osc_rates[3] = {
83 [0] = 32768,
84 /* FIXME: these are ATSTK1002-specific */
85 [1] = 20000000,
86 [2] = 12000000,
87};
88
89static unsigned long osc_get_rate(struct clk *clk)
90{
91 return at32ap7000_osc_rates[clk->index];
92}
93
94static unsigned long pll_get_rate(struct clk *clk, unsigned long control)
95{
96 unsigned long div, mul, rate;
97
98 if (!(control & SM_BIT(PLLEN)))
99 return 0;
100
101 div = SM_BFEXT(PLLDIV, control) + 1;
102 mul = SM_BFEXT(PLLMUL, control) + 1;
103
104 rate = clk->parent->get_rate(clk->parent);
105 rate = (rate + div / 2) / div;
106 rate *= mul;
107
108 return rate;
109}
110
111static unsigned long pll0_get_rate(struct clk *clk)
112{
113 u32 control;
114
115 control = sm_readl(&system_manager, PM_PLL0);
116
117 return pll_get_rate(clk, control);
118}
119
120static unsigned long pll1_get_rate(struct clk *clk)
121{
122 u32 control;
123
124 control = sm_readl(&system_manager, PM_PLL1);
125
126 return pll_get_rate(clk, control);
127}
128
129/*
130 * The AT32AP7000 has five primary clock sources: One 32kHz
131 * oscillator, two crystal oscillators and two PLLs.
132 */
133static struct clk osc32k = {
134 .name = "osc32k",
135 .get_rate = osc_get_rate,
136 .users = 1,
137 .index = 0,
138};
139static struct clk osc0 = {
140 .name = "osc0",
141 .get_rate = osc_get_rate,
142 .users = 1,
143 .index = 1,
144};
145static struct clk osc1 = {
146 .name = "osc1",
147 .get_rate = osc_get_rate,
148 .index = 2,
149};
150static struct clk pll0 = {
151 .name = "pll0",
152 .get_rate = pll0_get_rate,
153 .parent = &osc0,
154};
155static struct clk pll1 = {
156 .name = "pll1",
157 .get_rate = pll1_get_rate,
158 .parent = &osc0,
159};
160
161/*
162 * The main clock can be either osc0 or pll0. The boot loader may
163 * have chosen one for us, so we don't really know which one until we
164 * have a look at the SM.
165 */
166static struct clk *main_clock;
167
168/*
169 * Synchronous clocks are generated from the main clock. The clocks
170 * must satisfy the constraint
171 * fCPU >= fHSB >= fPB
172 * i.e. each clock must not be faster than its parent.
173 */
174static unsigned long bus_clk_get_rate(struct clk *clk, unsigned int shift)
175{
176 return main_clock->get_rate(main_clock) >> shift;
177};
178
179static void cpu_clk_mode(struct clk *clk, int enabled)
180{
181 struct at32_sm *sm = &system_manager;
182 unsigned long flags;
183 u32 mask;
184
185 spin_lock_irqsave(&sm->lock, flags);
186 mask = sm_readl(sm, PM_CPU_MASK);
187 if (enabled)
188 mask |= 1 << clk->index;
189 else
190 mask &= ~(1 << clk->index);
191 sm_writel(sm, PM_CPU_MASK, mask);
192 spin_unlock_irqrestore(&sm->lock, flags);
193}
194
195static unsigned long cpu_clk_get_rate(struct clk *clk)
196{
197 unsigned long cksel, shift = 0;
198
199 cksel = sm_readl(&system_manager, PM_CKSEL);
200 if (cksel & SM_BIT(CPUDIV))
201 shift = SM_BFEXT(CPUSEL, cksel) + 1;
202
203 return bus_clk_get_rate(clk, shift);
204}
205
206static void hsb_clk_mode(struct clk *clk, int enabled)
207{
208 struct at32_sm *sm = &system_manager;
209 unsigned long flags;
210 u32 mask;
211
212 spin_lock_irqsave(&sm->lock, flags);
213 mask = sm_readl(sm, PM_HSB_MASK);
214 if (enabled)
215 mask |= 1 << clk->index;
216 else
217 mask &= ~(1 << clk->index);
218 sm_writel(sm, PM_HSB_MASK, mask);
219 spin_unlock_irqrestore(&sm->lock, flags);
220}
221
222static unsigned long hsb_clk_get_rate(struct clk *clk)
223{
224 unsigned long cksel, shift = 0;
225
226 cksel = sm_readl(&system_manager, PM_CKSEL);
227 if (cksel & SM_BIT(HSBDIV))
228 shift = SM_BFEXT(HSBSEL, cksel) + 1;
229
230 return bus_clk_get_rate(clk, shift);
231}
232
233static void pba_clk_mode(struct clk *clk, int enabled)
234{
235 struct at32_sm *sm = &system_manager;
236 unsigned long flags;
237 u32 mask;
238
239 spin_lock_irqsave(&sm->lock, flags);
240 mask = sm_readl(sm, PM_PBA_MASK);
241 if (enabled)
242 mask |= 1 << clk->index;
243 else
244 mask &= ~(1 << clk->index);
245 sm_writel(sm, PM_PBA_MASK, mask);
246 spin_unlock_irqrestore(&sm->lock, flags);
247}
248
249static unsigned long pba_clk_get_rate(struct clk *clk)
250{
251 unsigned long cksel, shift = 0;
252
253 cksel = sm_readl(&system_manager, PM_CKSEL);
254 if (cksel & SM_BIT(PBADIV))
255 shift = SM_BFEXT(PBASEL, cksel) + 1;
256
257 return bus_clk_get_rate(clk, shift);
258}
259
260static void pbb_clk_mode(struct clk *clk, int enabled)
261{
262 struct at32_sm *sm = &system_manager;
263 unsigned long flags;
264 u32 mask;
265
266 spin_lock_irqsave(&sm->lock, flags);
267 mask = sm_readl(sm, PM_PBB_MASK);
268 if (enabled)
269 mask |= 1 << clk->index;
270 else
271 mask &= ~(1 << clk->index);
272 sm_writel(sm, PM_PBB_MASK, mask);
273 spin_unlock_irqrestore(&sm->lock, flags);
274}
275
276static unsigned long pbb_clk_get_rate(struct clk *clk)
277{
278 unsigned long cksel, shift = 0;
279
280 cksel = sm_readl(&system_manager, PM_CKSEL);
281 if (cksel & SM_BIT(PBBDIV))
282 shift = SM_BFEXT(PBBSEL, cksel) + 1;
283
284 return bus_clk_get_rate(clk, shift);
285}
286
287static struct clk cpu_clk = {
288 .name = "cpu",
289 .get_rate = cpu_clk_get_rate,
290 .users = 1,
291};
292static struct clk hsb_clk = {
293 .name = "hsb",
294 .parent = &cpu_clk,
295 .get_rate = hsb_clk_get_rate,
296};
297static struct clk pba_clk = {
298 .name = "pba",
299 .parent = &hsb_clk,
300 .mode = hsb_clk_mode,
301 .get_rate = pba_clk_get_rate,
302 .index = 1,
303};
304static struct clk pbb_clk = {
305 .name = "pbb",
306 .parent = &hsb_clk,
307 .mode = hsb_clk_mode,
308 .get_rate = pbb_clk_get_rate,
309 .users = 1,
310 .index = 2,
311};
312
313/* --------------------------------------------------------------------
314 * Generic Clock operations
315 * -------------------------------------------------------------------- */
316
317static void genclk_mode(struct clk *clk, int enabled)
318{
319 u32 control;
320
321 BUG_ON(clk->index > 7);
322
323 control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
324 if (enabled)
325 control |= SM_BIT(CEN);
326 else
327 control &= ~SM_BIT(CEN);
328 sm_writel(&system_manager, PM_GCCTRL + 4 * clk->index, control);
329}
330
331static unsigned long genclk_get_rate(struct clk *clk)
332{
333 u32 control;
334 unsigned long div = 1;
335
336 BUG_ON(clk->index > 7);
337
338 if (!clk->parent)
339 return 0;
340
341 control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
342 if (control & SM_BIT(DIVEN))
343 div = 2 * (SM_BFEXT(DIV, control) + 1);
344
345 return clk->parent->get_rate(clk->parent) / div;
346}
347
348static long genclk_set_rate(struct clk *clk, unsigned long rate, int apply)
349{
350 u32 control;
351 unsigned long parent_rate, actual_rate, div;
352
353 BUG_ON(clk->index > 7);
354
355 if (!clk->parent)
356 return 0;
357
358 parent_rate = clk->parent->get_rate(clk->parent);
359 control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
360
361 if (rate > 3 * parent_rate / 4) {
362 actual_rate = parent_rate;
363 control &= ~SM_BIT(DIVEN);
364 } else {
365 div = (parent_rate + rate) / (2 * rate) - 1;
366 control = SM_BFINS(DIV, div, control) | SM_BIT(DIVEN);
367 actual_rate = parent_rate / (2 * (div + 1));
368 }
369
370 printk("clk %s: new rate %lu (actual rate %lu)\n",
371 clk->name, rate, actual_rate);
372
373 if (apply)
374 sm_writel(&system_manager, PM_GCCTRL + 4 * clk->index,
375 control);
376
377 return actual_rate;
378}
379
380int genclk_set_parent(struct clk *clk, struct clk *parent)
381{
382 u32 control;
383
384 BUG_ON(clk->index > 7);
385
386 printk("clk %s: new parent %s (was %s)\n",
387 clk->name, parent->name,
388 clk->parent ? clk->parent->name : "(null)");
389
390 control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
391
392 if (parent == &osc1 || parent == &pll1)
393 control |= SM_BIT(OSCSEL);
394 else if (parent == &osc0 || parent == &pll0)
395 control &= ~SM_BIT(OSCSEL);
396 else
397 return -EINVAL;
398
399 if (parent == &pll0 || parent == &pll1)
400 control |= SM_BIT(PLLSEL);
401 else
402 control &= ~SM_BIT(PLLSEL);
403
404 sm_writel(&system_manager, PM_GCCTRL + 4 * clk->index, control);
405 clk->parent = parent;
406
407 return 0;
408}
409
410/* --------------------------------------------------------------------
411 * System peripherals
412 * -------------------------------------------------------------------- */
413static struct resource sm_resource[] = {
414 PBMEM(0xfff00000),
415 NAMED_IRQ(19, "eim"),
416 NAMED_IRQ(20, "pm"),
417 NAMED_IRQ(21, "rtc"),
418};
419struct platform_device at32_sm_device = {
420 .name = "sm",
421 .id = 0,
422 .resource = sm_resource,
423 .num_resources = ARRAY_SIZE(sm_resource),
424};
425DEV_CLK(pclk, at32_sm, pbb, 0);
426
427static struct resource intc0_resource[] = {
428 PBMEM(0xfff00400),
429};
430struct platform_device at32_intc0_device = {
431 .name = "intc",
432 .id = 0,
433 .resource = intc0_resource,
434 .num_resources = ARRAY_SIZE(intc0_resource),
435};
436DEV_CLK(pclk, at32_intc0, pbb, 1);
437
438static struct clk ebi_clk = {
439 .name = "ebi",
440 .parent = &hsb_clk,
441 .mode = hsb_clk_mode,
442 .get_rate = hsb_clk_get_rate,
443 .users = 1,
444};
445static struct clk hramc_clk = {
446 .name = "hramc",
447 .parent = &hsb_clk,
448 .mode = hsb_clk_mode,
449 .get_rate = hsb_clk_get_rate,
450 .users = 1,
451};
452
453static struct resource smc0_resource[] = {
454 PBMEM(0xfff03400),
455};
456DEFINE_DEV(smc, 0);
457DEV_CLK(pclk, smc0, pbb, 13);
458DEV_CLK(mck, smc0, hsb, 0);
459
460static struct platform_device pdc_device = {
461 .name = "pdc",
462 .id = 0,
463};
464DEV_CLK(hclk, pdc, hsb, 4);
465DEV_CLK(pclk, pdc, pba, 16);
466
467static struct clk pico_clk = {
468 .name = "pico",
469 .parent = &cpu_clk,
470 .mode = cpu_clk_mode,
471 .get_rate = cpu_clk_get_rate,
472 .users = 1,
473};
474
475/* --------------------------------------------------------------------
476 * PIO
477 * -------------------------------------------------------------------- */
478
479static struct resource pio0_resource[] = {
480 PBMEM(0xffe02800),
481 IRQ(13),
482};
483DEFINE_DEV(pio, 0);
484DEV_CLK(mck, pio0, pba, 10);
485
486static struct resource pio1_resource[] = {
487 PBMEM(0xffe02c00),
488 IRQ(14),
489};
490DEFINE_DEV(pio, 1);
491DEV_CLK(mck, pio1, pba, 11);
492
493static struct resource pio2_resource[] = {
494 PBMEM(0xffe03000),
495 IRQ(15),
496};
497DEFINE_DEV(pio, 2);
498DEV_CLK(mck, pio2, pba, 12);
499
500static struct resource pio3_resource[] = {
501 PBMEM(0xffe03400),
502 IRQ(16),
503};
504DEFINE_DEV(pio, 3);
505DEV_CLK(mck, pio3, pba, 13);
506
507void __init at32_add_system_devices(void)
508{
509 system_manager.eim_first_irq = NR_INTERNAL_IRQS;
510
511 platform_device_register(&at32_sm_device);
512 platform_device_register(&at32_intc0_device);
513 platform_device_register(&smc0_device);
514 platform_device_register(&pdc_device);
515
516 platform_device_register(&pio0_device);
517 platform_device_register(&pio1_device);
518 platform_device_register(&pio2_device);
519 platform_device_register(&pio3_device);
520}
521
522/* --------------------------------------------------------------------
523 * USART
524 * -------------------------------------------------------------------- */
525
526static struct resource usart0_resource[] = {
527 PBMEM(0xffe00c00),
528 IRQ(7),
529};
530DEFINE_DEV(usart, 0);
531DEV_CLK(usart, usart0, pba, 4);
532
533static struct resource usart1_resource[] = {
534 PBMEM(0xffe01000),
535 IRQ(7),
536};
537DEFINE_DEV(usart, 1);
538DEV_CLK(usart, usart1, pba, 4);
539
540static struct resource usart2_resource[] = {
541 PBMEM(0xffe01400),
542 IRQ(8),
543};
544DEFINE_DEV(usart, 2);
545DEV_CLK(usart, usart2, pba, 5);
546
547static struct resource usart3_resource[] = {
548 PBMEM(0xffe01800),
549 IRQ(9),
550};
551DEFINE_DEV(usart, 3);
552DEV_CLK(usart, usart3, pba, 6);
553
554static inline void configure_usart0_pins(void)
555{
556 portmux_set_func(PIOA, 8, FUNC_B); /* RXD */
557 portmux_set_func(PIOA, 9, FUNC_B); /* TXD */
558}
559
560static inline void configure_usart1_pins(void)
561{
562 portmux_set_func(PIOA, 17, FUNC_A); /* RXD */
563 portmux_set_func(PIOA, 18, FUNC_A); /* TXD */
564}
565
566static inline void configure_usart2_pins(void)
567{
568 portmux_set_func(PIOB, 26, FUNC_B); /* RXD */
569 portmux_set_func(PIOB, 27, FUNC_B); /* TXD */
570}
571
572static inline void configure_usart3_pins(void)
573{
574 portmux_set_func(PIOB, 18, FUNC_B); /* RXD */
575 portmux_set_func(PIOB, 17, FUNC_B); /* TXD */
576}
577
578static struct platform_device *setup_usart(unsigned int id)
579{
580 struct platform_device *pdev;
581
582 switch (id) {
583 case 0:
584 pdev = &usart0_device;
585 configure_usart0_pins();
586 break;
587 case 1:
588 pdev = &usart1_device;
589 configure_usart1_pins();
590 break;
591 case 2:
592 pdev = &usart2_device;
593 configure_usart2_pins();
594 break;
595 case 3:
596 pdev = &usart3_device;
597 configure_usart3_pins();
598 break;
599 default:
600 pdev = NULL;
601 break;
602 }
603
604 return pdev;
605}
606
607struct platform_device *__init at32_add_device_usart(unsigned int id)
608{
609 struct platform_device *pdev;
610
611 pdev = setup_usart(id);
612 if (pdev)
613 platform_device_register(pdev);
614
615 return pdev;
616}
617
618struct platform_device *at91_default_console_device;
619
620void __init at32_setup_serial_console(unsigned int usart_id)
621{
622 at91_default_console_device = setup_usart(usart_id);
623}
624
625/* --------------------------------------------------------------------
626 * Ethernet
627 * -------------------------------------------------------------------- */
628
629static struct eth_platform_data macb0_data;
630static struct resource macb0_resource[] = {
631 PBMEM(0xfff01800),
632 IRQ(25),
633};
634DEFINE_DEV_DATA(macb, 0);
635DEV_CLK(hclk, macb0, hsb, 8);
636DEV_CLK(pclk, macb0, pbb, 6);
637
638struct platform_device *__init
639at32_add_device_eth(unsigned int id, struct eth_platform_data *data)
640{
641 struct platform_device *pdev;
642
643 switch (id) {
644 case 0:
645 pdev = &macb0_device;
646
647 portmux_set_func(PIOC, 3, FUNC_A); /* TXD0 */
648 portmux_set_func(PIOC, 4, FUNC_A); /* TXD1 */
649 portmux_set_func(PIOC, 7, FUNC_A); /* TXEN */
650 portmux_set_func(PIOC, 8, FUNC_A); /* TXCK */
651 portmux_set_func(PIOC, 9, FUNC_A); /* RXD0 */
652 portmux_set_func(PIOC, 10, FUNC_A); /* RXD1 */
653 portmux_set_func(PIOC, 13, FUNC_A); /* RXER */
654 portmux_set_func(PIOC, 15, FUNC_A); /* RXDV */
655 portmux_set_func(PIOC, 16, FUNC_A); /* MDC */
656 portmux_set_func(PIOC, 17, FUNC_A); /* MDIO */
657
658 if (!data->is_rmii) {
659 portmux_set_func(PIOC, 0, FUNC_A); /* COL */
660 portmux_set_func(PIOC, 1, FUNC_A); /* CRS */
661 portmux_set_func(PIOC, 2, FUNC_A); /* TXER */
662 portmux_set_func(PIOC, 5, FUNC_A); /* TXD2 */
663 portmux_set_func(PIOC, 6, FUNC_A); /* TXD3 */
664 portmux_set_func(PIOC, 11, FUNC_A); /* RXD2 */
665 portmux_set_func(PIOC, 12, FUNC_A); /* RXD3 */
666 portmux_set_func(PIOC, 14, FUNC_A); /* RXCK */
667 portmux_set_func(PIOC, 18, FUNC_A); /* SPD */
668 }
669 break;
670
671 default:
672 return NULL;
673 }
674
675 memcpy(pdev->dev.platform_data, data, sizeof(struct eth_platform_data));
676 platform_device_register(pdev);
677
678 return pdev;
679}
680
681/* --------------------------------------------------------------------
682 * SPI
683 * -------------------------------------------------------------------- */
684static struct resource spi0_resource[] = {
685 PBMEM(0xffe00000),
686 IRQ(3),
687};
688DEFINE_DEV(spi, 0);
689DEV_CLK(mck, spi0, pba, 0);
690
691struct platform_device *__init at32_add_device_spi(unsigned int id)
692{
693 struct platform_device *pdev;
694
695 switch (id) {
696 case 0:
697 pdev = &spi0_device;
698 portmux_set_func(PIOA, 0, FUNC_A); /* MISO */
699 portmux_set_func(PIOA, 1, FUNC_A); /* MOSI */
700 portmux_set_func(PIOA, 2, FUNC_A); /* SCK */
701 portmux_set_func(PIOA, 3, FUNC_A); /* NPCS0 */
702 portmux_set_func(PIOA, 4, FUNC_A); /* NPCS1 */
703 portmux_set_func(PIOA, 5, FUNC_A); /* NPCS2 */
704 break;
705
706 default:
707 return NULL;
708 }
709
710 platform_device_register(pdev);
711 return pdev;
712}
713
714/* --------------------------------------------------------------------
715 * LCDC
716 * -------------------------------------------------------------------- */
717static struct lcdc_platform_data lcdc0_data;
718static struct resource lcdc0_resource[] = {
719 {
720 .start = 0xff000000,
721 .end = 0xff000fff,
722 .flags = IORESOURCE_MEM,
723 },
724 IRQ(1),
725};
726DEFINE_DEV_DATA(lcdc, 0);
727DEV_CLK(hclk, lcdc0, hsb, 7);
728static struct clk lcdc0_pixclk = {
729 .name = "pixclk",
730 .dev = &lcdc0_device.dev,
731 .mode = genclk_mode,
732 .get_rate = genclk_get_rate,
733 .set_rate = genclk_set_rate,
734 .set_parent = genclk_set_parent,
735 .index = 7,
736};
737
738struct platform_device *__init
739at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data)
740{
741 struct platform_device *pdev;
742
743 switch (id) {
744 case 0:
745 pdev = &lcdc0_device;
746 portmux_set_func(PIOC, 19, FUNC_A); /* CC */
747 portmux_set_func(PIOC, 20, FUNC_A); /* HSYNC */
748 portmux_set_func(PIOC, 21, FUNC_A); /* PCLK */
749 portmux_set_func(PIOC, 22, FUNC_A); /* VSYNC */
750 portmux_set_func(PIOC, 23, FUNC_A); /* DVAL */
751 portmux_set_func(PIOC, 24, FUNC_A); /* MODE */
752 portmux_set_func(PIOC, 25, FUNC_A); /* PWR */
753 portmux_set_func(PIOC, 26, FUNC_A); /* DATA0 */
754 portmux_set_func(PIOC, 27, FUNC_A); /* DATA1 */
755 portmux_set_func(PIOC, 28, FUNC_A); /* DATA2 */
756 portmux_set_func(PIOC, 29, FUNC_A); /* DATA3 */
757 portmux_set_func(PIOC, 30, FUNC_A); /* DATA4 */
758 portmux_set_func(PIOC, 31, FUNC_A); /* DATA5 */
759 portmux_set_func(PIOD, 0, FUNC_A); /* DATA6 */
760 portmux_set_func(PIOD, 1, FUNC_A); /* DATA7 */
761 portmux_set_func(PIOD, 2, FUNC_A); /* DATA8 */
762 portmux_set_func(PIOD, 3, FUNC_A); /* DATA9 */
763 portmux_set_func(PIOD, 4, FUNC_A); /* DATA10 */
764 portmux_set_func(PIOD, 5, FUNC_A); /* DATA11 */
765 portmux_set_func(PIOD, 6, FUNC_A); /* DATA12 */
766 portmux_set_func(PIOD, 7, FUNC_A); /* DATA13 */
767 portmux_set_func(PIOD, 8, FUNC_A); /* DATA14 */
768 portmux_set_func(PIOD, 9, FUNC_A); /* DATA15 */
769 portmux_set_func(PIOD, 10, FUNC_A); /* DATA16 */
770 portmux_set_func(PIOD, 11, FUNC_A); /* DATA17 */
771 portmux_set_func(PIOD, 12, FUNC_A); /* DATA18 */
772 portmux_set_func(PIOD, 13, FUNC_A); /* DATA19 */
773 portmux_set_func(PIOD, 14, FUNC_A); /* DATA20 */
774 portmux_set_func(PIOD, 15, FUNC_A); /* DATA21 */
775 portmux_set_func(PIOD, 16, FUNC_A); /* DATA22 */
776 portmux_set_func(PIOD, 17, FUNC_A); /* DATA23 */
777
778 clk_set_parent(&lcdc0_pixclk, &pll0);
779 clk_set_rate(&lcdc0_pixclk, clk_get_rate(&pll0));
780 break;
781
782 default:
783 return NULL;
784 }
785
786 memcpy(pdev->dev.platform_data, data,
787 sizeof(struct lcdc_platform_data));
788
789 platform_device_register(pdev);
790 return pdev;
791}
792
793struct clk *at32_clock_list[] = {
794 &osc32k,
795 &osc0,
796 &osc1,
797 &pll0,
798 &pll1,
799 &cpu_clk,
800 &hsb_clk,
801 &pba_clk,
802 &pbb_clk,
803 &at32_sm_pclk,
804 &at32_intc0_pclk,
805 &ebi_clk,
806 &hramc_clk,
807 &smc0_pclk,
808 &smc0_mck,
809 &pdc_hclk,
810 &pdc_pclk,
811 &pico_clk,
812 &pio0_mck,
813 &pio1_mck,
814 &pio2_mck,
815 &pio3_mck,
816 &usart0_usart,
817 &usart1_usart,
818 &usart2_usart,
819 &usart3_usart,
820 &macb0_hclk,
821 &macb0_pclk,
822 &spi0_mck,
823 &lcdc0_hclk,
824 &lcdc0_pixclk,
825};
826unsigned int at32_nr_clocks = ARRAY_SIZE(at32_clock_list);
827
828void __init at32_portmux_init(void)
829{
830 at32_init_pio(&pio0_device);
831 at32_init_pio(&pio1_device);
832 at32_init_pio(&pio2_device);
833 at32_init_pio(&pio3_device);
834}
835
836void __init at32_clock_init(void)
837{
838 struct at32_sm *sm = &system_manager;
839 u32 cpu_mask = 0, hsb_mask = 0, pba_mask = 0, pbb_mask = 0;
840 int i;
841
842 if (sm_readl(sm, PM_MCCTRL) & SM_BIT(PLLSEL))
843 main_clock = &pll0;
844 else
845 main_clock = &osc0;
846
847 if (sm_readl(sm, PM_PLL0) & SM_BIT(PLLOSC))
848 pll0.parent = &osc1;
849 if (sm_readl(sm, PM_PLL1) & SM_BIT(PLLOSC))
850 pll1.parent = &osc1;
851
852 /*
853 * Turn on all clocks that have at least one user already, and
854 * turn off everything else. We only do this for module
855 * clocks, and even though it isn't particularly pretty to
856 * check the address of the mode function, it should do the
857 * trick...
858 */
859 for (i = 0; i < ARRAY_SIZE(at32_clock_list); i++) {
860 struct clk *clk = at32_clock_list[i];
861
862 if (clk->mode == &cpu_clk_mode)
863 cpu_mask |= 1 << clk->index;
864 else if (clk->mode == &hsb_clk_mode)
865 hsb_mask |= 1 << clk->index;
866 else if (clk->mode == &pba_clk_mode)
867 pba_mask |= 1 << clk->index;
868 else if (clk->mode == &pbb_clk_mode)
869 pbb_mask |= 1 << clk->index;
870 }
871
872 sm_writel(sm, PM_CPU_MASK, cpu_mask);
873 sm_writel(sm, PM_HSB_MASK, hsb_mask);
874 sm_writel(sm, PM_PBA_MASK, pba_mask);
875 sm_writel(sm, PM_PBB_MASK, pbb_mask);
876}
diff --git a/arch/avr32/mach-at32ap/clock.c b/arch/avr32/mach-at32ap/clock.c
new file mode 100644
index 000000000000..3d0d1097389f
--- /dev/null
+++ b/arch/avr32/mach-at32ap/clock.c
@@ -0,0 +1,148 @@
1/*
2 * Clock management for AT32AP CPUs
3 *
4 * Copyright (C) 2006 Atmel Corporation
5 *
6 * Based on arch/arm/mach-at91rm9200/clock.c
7 * Copyright (C) 2005 David Brownell
8 * Copyright (C) 2005 Ivan Kokshaysky
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14#include <linux/clk.h>
15#include <linux/err.h>
16#include <linux/device.h>
17#include <linux/string.h>
18
19#include "clock.h"
20
21static spinlock_t clk_lock = SPIN_LOCK_UNLOCKED;
22
23struct clk *clk_get(struct device *dev, const char *id)
24{
25 int i;
26
27 for (i = 0; i < at32_nr_clocks; i++) {
28 struct clk *clk = at32_clock_list[i];
29
30 if (clk->dev == dev && strcmp(id, clk->name) == 0)
31 return clk;
32 }
33
34 return ERR_PTR(-ENOENT);
35}
36EXPORT_SYMBOL(clk_get);
37
38void clk_put(struct clk *clk)
39{
40 /* clocks are static for now, we can't free them */
41}
42EXPORT_SYMBOL(clk_put);
43
44static void __clk_enable(struct clk *clk)
45{
46 if (clk->parent)
47 __clk_enable(clk->parent);
48 if (clk->users++ == 0 && clk->mode)
49 clk->mode(clk, 1);
50}
51
52int clk_enable(struct clk *clk)
53{
54 unsigned long flags;
55
56 spin_lock_irqsave(&clk_lock, flags);
57 __clk_enable(clk);
58 spin_unlock_irqrestore(&clk_lock, flags);
59
60 return 0;
61}
62EXPORT_SYMBOL(clk_enable);
63
64static void __clk_disable(struct clk *clk)
65{
66 BUG_ON(clk->users == 0);
67
68 if (--clk->users == 0 && clk->mode)
69 clk->mode(clk, 0);
70 if (clk->parent)
71 __clk_disable(clk->parent);
72}
73
74void clk_disable(struct clk *clk)
75{
76 unsigned long flags;
77
78 spin_lock_irqsave(&clk_lock, flags);
79 __clk_disable(clk);
80 spin_unlock_irqrestore(&clk_lock, flags);
81}
82EXPORT_SYMBOL(clk_disable);
83
84unsigned long clk_get_rate(struct clk *clk)
85{
86 unsigned long flags;
87 unsigned long rate;
88
89 spin_lock_irqsave(&clk_lock, flags);
90 rate = clk->get_rate(clk);
91 spin_unlock_irqrestore(&clk_lock, flags);
92
93 return rate;
94}
95EXPORT_SYMBOL(clk_get_rate);
96
97long clk_round_rate(struct clk *clk, unsigned long rate)
98{
99 unsigned long flags, actual_rate;
100
101 if (!clk->set_rate)
102 return -ENOSYS;
103
104 spin_lock_irqsave(&clk_lock, flags);
105 actual_rate = clk->set_rate(clk, rate, 0);
106 spin_unlock_irqrestore(&clk_lock, flags);
107
108 return actual_rate;
109}
110EXPORT_SYMBOL(clk_round_rate);
111
112int clk_set_rate(struct clk *clk, unsigned long rate)
113{
114 unsigned long flags;
115 long ret;
116
117 if (!clk->set_rate)
118 return -ENOSYS;
119
120 spin_lock_irqsave(&clk_lock, flags);
121 ret = clk->set_rate(clk, rate, 1);
122 spin_unlock_irqrestore(&clk_lock, flags);
123
124 return (ret < 0) ? ret : 0;
125}
126EXPORT_SYMBOL(clk_set_rate);
127
128int clk_set_parent(struct clk *clk, struct clk *parent)
129{
130 unsigned long flags;
131 int ret;
132
133 if (!clk->set_parent)
134 return -ENOSYS;
135
136 spin_lock_irqsave(&clk_lock, flags);
137 ret = clk->set_parent(clk, parent);
138 spin_unlock_irqrestore(&clk_lock, flags);
139
140 return ret;
141}
142EXPORT_SYMBOL(clk_set_parent);
143
144struct clk *clk_get_parent(struct clk *clk)
145{
146 return clk->parent;
147}
148EXPORT_SYMBOL(clk_get_parent);
diff --git a/arch/avr32/mach-at32ap/clock.h b/arch/avr32/mach-at32ap/clock.h
new file mode 100644
index 000000000000..f953f044ba4d
--- /dev/null
+++ b/arch/avr32/mach-at32ap/clock.h
@@ -0,0 +1,30 @@
1/*
2 * Clock management for AT32AP CPUs
3 *
4 * Copyright (C) 2006 Atmel Corporation
5 *
6 * Based on arch/arm/mach-at91rm9200/clock.c
7 * Copyright (C) 2005 David Brownell
8 * Copyright (C) 2005 Ivan Kokshaysky
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14#include <linux/clk.h>
15
16struct clk {
17 const char *name; /* Clock name/function */
18 struct device *dev; /* Device the clock is used by */
19 struct clk *parent; /* Parent clock, if any */
20 void (*mode)(struct clk *clk, int enabled);
21 unsigned long (*get_rate)(struct clk *clk);
22 long (*set_rate)(struct clk *clk, unsigned long rate,
23 int apply);
24 int (*set_parent)(struct clk *clk, struct clk *parent);
25 u16 users; /* Enabled if non-zero */
26 u16 index; /* Sibling index */
27};
28
29extern struct clk *at32_clock_list[];
30extern unsigned int at32_nr_clocks;
diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c
new file mode 100644
index 000000000000..7da9c5f7a0eb
--- /dev/null
+++ b/arch/avr32/mach-at32ap/extint.c
@@ -0,0 +1,171 @@
1/*
2 * External interrupt handling for AT32AP CPUs
3 *
4 * Copyright (C) 2006 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/errno.h>
12#include <linux/init.h>
13#include <linux/interrupt.h>
14#include <linux/irq.h>
15#include <linux/platform_device.h>
16#include <linux/random.h>
17
18#include <asm/io.h>
19
20#include <asm/arch/sm.h>
21
22#include "sm.h"
23
24static void eim_ack_irq(unsigned int irq)
25{
26 struct at32_sm *sm = get_irq_chip_data(irq);
27 sm_writel(sm, EIM_ICR, 1 << (irq - sm->eim_first_irq));
28}
29
30static void eim_mask_irq(unsigned int irq)
31{
32 struct at32_sm *sm = get_irq_chip_data(irq);
33 sm_writel(sm, EIM_IDR, 1 << (irq - sm->eim_first_irq));
34}
35
36static void eim_mask_ack_irq(unsigned int irq)
37{
38 struct at32_sm *sm = get_irq_chip_data(irq);
39 sm_writel(sm, EIM_ICR, 1 << (irq - sm->eim_first_irq));
40 sm_writel(sm, EIM_IDR, 1 << (irq - sm->eim_first_irq));
41}
42
43static void eim_unmask_irq(unsigned int irq)
44{
45 struct at32_sm *sm = get_irq_chip_data(irq);
46 sm_writel(sm, EIM_IER, 1 << (irq - sm->eim_first_irq));
47}
48
49static int eim_set_irq_type(unsigned int irq, unsigned int flow_type)
50{
51 struct at32_sm *sm = get_irq_chip_data(irq);
52 unsigned int i = irq - sm->eim_first_irq;
53 u32 mode, edge, level;
54 unsigned long flags;
55 int ret = 0;
56
57 flow_type &= IRQ_TYPE_SENSE_MASK;
58
59 spin_lock_irqsave(&sm->lock, flags);
60
61 mode = sm_readl(sm, EIM_MODE);
62 edge = sm_readl(sm, EIM_EDGE);
63 level = sm_readl(sm, EIM_LEVEL);
64
65 switch (flow_type) {
66 case IRQ_TYPE_LEVEL_LOW:
67 mode |= 1 << i;
68 level &= ~(1 << i);
69 break;
70 case IRQ_TYPE_LEVEL_HIGH:
71 mode |= 1 << i;
72 level |= 1 << i;
73 break;
74 case IRQ_TYPE_EDGE_RISING:
75 mode &= ~(1 << i);
76 edge |= 1 << i;
77 break;
78 case IRQ_TYPE_EDGE_FALLING:
79 mode &= ~(1 << i);
80 edge &= ~(1 << i);
81 break;
82 default:
83 ret = -EINVAL;
84 break;
85 }
86
87 sm_writel(sm, EIM_MODE, mode);
88 sm_writel(sm, EIM_EDGE, edge);
89 sm_writel(sm, EIM_LEVEL, level);
90
91 spin_unlock_irqrestore(&sm->lock, flags);
92
93 return ret;
94}
95
96struct irq_chip eim_chip = {
97 .name = "eim",
98 .ack = eim_ack_irq,
99 .mask = eim_mask_irq,
100 .mask_ack = eim_mask_ack_irq,
101 .unmask = eim_unmask_irq,
102 .set_type = eim_set_irq_type,
103};
104
105static void demux_eim_irq(unsigned int irq, struct irq_desc *desc,
106 struct pt_regs *regs)
107{
108 struct at32_sm *sm = desc->handler_data;
109 struct irq_desc *ext_desc;
110 unsigned long status, pending;
111 unsigned int i, ext_irq;
112
113 spin_lock(&sm->lock);
114
115 status = sm_readl(sm, EIM_ISR);
116 pending = status & sm_readl(sm, EIM_IMR);
117
118 while (pending) {
119 i = fls(pending) - 1;
120 pending &= ~(1 << i);
121
122 ext_irq = i + sm->eim_first_irq;
123 ext_desc = irq_desc + ext_irq;
124 ext_desc->handle_irq(ext_irq, ext_desc, regs);
125 }
126
127 spin_unlock(&sm->lock);
128}
129
130static int __init eim_init(void)
131{
132 struct at32_sm *sm = &system_manager;
133 unsigned int i;
134 unsigned int nr_irqs;
135 unsigned int int_irq;
136 u32 pattern;
137
138 /*
139 * The EIM is really the same module as SM, so register
140 * mapping, etc. has been taken care of already.
141 */
142
143 /*
144 * Find out how many interrupt lines that are actually
145 * implemented in hardware.
146 */
147 sm_writel(sm, EIM_IDR, ~0UL);
148 sm_writel(sm, EIM_MODE, ~0UL);
149 pattern = sm_readl(sm, EIM_MODE);
150 nr_irqs = fls(pattern);
151
152 sm->eim_chip = &eim_chip;
153
154 for (i = 0; i < nr_irqs; i++) {
155 set_irq_chip(sm->eim_first_irq + i, &eim_chip);
156 set_irq_chip_data(sm->eim_first_irq + i, sm);
157 }
158
159 int_irq = platform_get_irq_byname(sm->pdev, "eim");
160
161 set_irq_chained_handler(int_irq, demux_eim_irq);
162 set_irq_data(int_irq, sm);
163
164 printk("EIM: External Interrupt Module at 0x%p, IRQ %u\n",
165 sm->regs, int_irq);
166 printk("EIM: Handling %u external IRQs, starting with IRQ %u\n",
167 nr_irqs, sm->eim_first_irq);
168
169 return 0;
170}
171arch_initcall(eim_init);
diff --git a/arch/avr32/mach-at32ap/hsmc.c b/arch/avr32/mach-at32ap/hsmc.c
new file mode 100644
index 000000000000..7691721928a7
--- /dev/null
+++ b/arch/avr32/mach-at32ap/hsmc.c
@@ -0,0 +1,164 @@
1/*
2 * Static Memory Controller for AT32 chips
3 *
4 * Copyright (C) 2006 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#define DEBUG
11#include <linux/clk.h>
12#include <linux/err.h>
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/platform_device.h>
16
17#include <asm/io.h>
18#include <asm/arch/smc.h>
19
20#include "hsmc.h"
21
22#define NR_CHIP_SELECTS 6
23
24struct hsmc {
25 void __iomem *regs;
26 struct clk *pclk;
27 struct clk *mck;
28};
29
30static struct hsmc *hsmc;
31
32int smc_set_configuration(int cs, const struct smc_config *config)
33{
34 unsigned long mul;
35 unsigned long offset;
36 u32 setup, pulse, cycle, mode;
37
38 if (!hsmc)
39 return -ENODEV;
40 if (cs >= NR_CHIP_SELECTS)
41 return -EINVAL;
42
43 /*
44 * cycles = x / T = x * f
45 * = ((x * 1000000000) * ((f * 65536) / 1000000000)) / 65536
46 * = ((x * 1000000000) * (((f / 10000) * 65536) / 100000)) / 65536
47 */
48 mul = (clk_get_rate(hsmc->mck) / 10000) << 16;
49 mul /= 100000;
50
51#define ns2cyc(x) ((((x) * mul) + 65535) >> 16)
52
53 setup = (HSMC_BF(NWE_SETUP, ns2cyc(config->nwe_setup))
54 | HSMC_BF(NCS_WR_SETUP, ns2cyc(config->ncs_write_setup))
55 | HSMC_BF(NRD_SETUP, ns2cyc(config->nrd_setup))
56 | HSMC_BF(NCS_RD_SETUP, ns2cyc(config->ncs_read_setup)));
57 pulse = (HSMC_BF(NWE_PULSE, ns2cyc(config->nwe_pulse))
58 | HSMC_BF(NCS_WR_PULSE, ns2cyc(config->ncs_write_pulse))
59 | HSMC_BF(NRD_PULSE, ns2cyc(config->nrd_pulse))
60 | HSMC_BF(NCS_RD_PULSE, ns2cyc(config->ncs_read_pulse)));
61 cycle = (HSMC_BF(NWE_CYCLE, ns2cyc(config->write_cycle))
62 | HSMC_BF(NRD_CYCLE, ns2cyc(config->read_cycle)));
63
64 switch (config->bus_width) {
65 case 1:
66 mode = HSMC_BF(DBW, HSMC_DBW_8_BITS);
67 break;
68 case 2:
69 mode = HSMC_BF(DBW, HSMC_DBW_16_BITS);
70 break;
71 case 4:
72 mode = HSMC_BF(DBW, HSMC_DBW_32_BITS);
73 break;
74 default:
75 return -EINVAL;
76 }
77
78 if (config->nrd_controlled)
79 mode |= HSMC_BIT(READ_MODE);
80 if (config->nwe_controlled)
81 mode |= HSMC_BIT(WRITE_MODE);
82 if (config->byte_write)
83 mode |= HSMC_BIT(BAT);
84
85 pr_debug("smc cs%d: setup/%08x pulse/%08x cycle/%08x mode/%08x\n",
86 cs, setup, pulse, cycle, mode);
87
88 offset = cs * 0x10;
89 hsmc_writel(hsmc, SETUP0 + offset, setup);
90 hsmc_writel(hsmc, PULSE0 + offset, pulse);
91 hsmc_writel(hsmc, CYCLE0 + offset, cycle);
92 hsmc_writel(hsmc, MODE0 + offset, mode);
93 hsmc_readl(hsmc, MODE0); /* I/O barrier */
94
95 return 0;
96}
97EXPORT_SYMBOL(smc_set_configuration);
98
99static int hsmc_probe(struct platform_device *pdev)
100{
101 struct resource *regs;
102 struct clk *pclk, *mck;
103 int ret;
104
105 if (hsmc)
106 return -EBUSY;
107
108 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
109 if (!regs)
110 return -ENXIO;
111 pclk = clk_get(&pdev->dev, "pclk");
112 if (IS_ERR(pclk))
113 return PTR_ERR(pclk);
114 mck = clk_get(&pdev->dev, "mck");
115 if (IS_ERR(mck)) {
116 ret = PTR_ERR(mck);
117 goto out_put_pclk;
118 }
119
120 ret = -ENOMEM;
121 hsmc = kzalloc(sizeof(struct hsmc), GFP_KERNEL);
122 if (!hsmc)
123 goto out_put_clocks;
124
125 clk_enable(pclk);
126 clk_enable(mck);
127
128 hsmc->pclk = pclk;
129 hsmc->mck = mck;
130 hsmc->regs = ioremap(regs->start, regs->end - regs->start + 1);
131 if (!hsmc->regs)
132 goto out_disable_clocks;
133
134 dev_info(&pdev->dev, "Atmel Static Memory Controller at 0x%08lx\n",
135 (unsigned long)regs->start);
136
137 platform_set_drvdata(pdev, hsmc);
138
139 return 0;
140
141out_disable_clocks:
142 clk_disable(mck);
143 clk_disable(pclk);
144 kfree(hsmc);
145out_put_clocks:
146 clk_put(mck);
147out_put_pclk:
148 clk_put(pclk);
149 hsmc = NULL;
150 return ret;
151}
152
153static struct platform_driver hsmc_driver = {
154 .probe = hsmc_probe,
155 .driver = {
156 .name = "smc",
157 },
158};
159
160static int __init hsmc_init(void)
161{
162 return platform_driver_register(&hsmc_driver);
163}
164arch_initcall(hsmc_init);
diff --git a/arch/avr32/mach-at32ap/hsmc.h b/arch/avr32/mach-at32ap/hsmc.h
new file mode 100644
index 000000000000..5681276fafdb
--- /dev/null
+++ b/arch/avr32/mach-at32ap/hsmc.h
@@ -0,0 +1,127 @@
1/*
2 * Register definitions for Atmel Static Memory Controller (SMC)
3 *
4 * Copyright (C) 2006 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef __ASM_AVR32_HSMC_H__
11#define __ASM_AVR32_HSMC_H__
12
13/* HSMC register offsets */
14#define HSMC_SETUP0 0x0000
15#define HSMC_PULSE0 0x0004
16#define HSMC_CYCLE0 0x0008
17#define HSMC_MODE0 0x000c
18#define HSMC_SETUP1 0x0010
19#define HSMC_PULSE1 0x0014
20#define HSMC_CYCLE1 0x0018
21#define HSMC_MODE1 0x001c
22#define HSMC_SETUP2 0x0020
23#define HSMC_PULSE2 0x0024
24#define HSMC_CYCLE2 0x0028
25#define HSMC_MODE2 0x002c
26#define HSMC_SETUP3 0x0030
27#define HSMC_PULSE3 0x0034
28#define HSMC_CYCLE3 0x0038
29#define HSMC_MODE3 0x003c
30#define HSMC_SETUP4 0x0040
31#define HSMC_PULSE4 0x0044
32#define HSMC_CYCLE4 0x0048
33#define HSMC_MODE4 0x004c
34#define HSMC_SETUP5 0x0050
35#define HSMC_PULSE5 0x0054
36#define HSMC_CYCLE5 0x0058
37#define HSMC_MODE5 0x005c
38
39/* Bitfields in SETUP0 */
40#define HSMC_NWE_SETUP_OFFSET 0
41#define HSMC_NWE_SETUP_SIZE 6
42#define HSMC_NCS_WR_SETUP_OFFSET 8
43#define HSMC_NCS_WR_SETUP_SIZE 6
44#define HSMC_NRD_SETUP_OFFSET 16
45#define HSMC_NRD_SETUP_SIZE 6
46#define HSMC_NCS_RD_SETUP_OFFSET 24
47#define HSMC_NCS_RD_SETUP_SIZE 6
48
49/* Bitfields in PULSE0 */
50#define HSMC_NWE_PULSE_OFFSET 0
51#define HSMC_NWE_PULSE_SIZE 7
52#define HSMC_NCS_WR_PULSE_OFFSET 8
53#define HSMC_NCS_WR_PULSE_SIZE 7
54#define HSMC_NRD_PULSE_OFFSET 16
55#define HSMC_NRD_PULSE_SIZE 7
56#define HSMC_NCS_RD_PULSE_OFFSET 24
57#define HSMC_NCS_RD_PULSE_SIZE 7
58
59/* Bitfields in CYCLE0 */
60#define HSMC_NWE_CYCLE_OFFSET 0
61#define HSMC_NWE_CYCLE_SIZE 9
62#define HSMC_NRD_CYCLE_OFFSET 16
63#define HSMC_NRD_CYCLE_SIZE 9
64
65/* Bitfields in MODE0 */
66#define HSMC_READ_MODE_OFFSET 0
67#define HSMC_READ_MODE_SIZE 1
68#define HSMC_WRITE_MODE_OFFSET 1
69#define HSMC_WRITE_MODE_SIZE 1
70#define HSMC_EXNW_MODE_OFFSET 4
71#define HSMC_EXNW_MODE_SIZE 2
72#define HSMC_BAT_OFFSET 8
73#define HSMC_BAT_SIZE 1
74#define HSMC_DBW_OFFSET 12
75#define HSMC_DBW_SIZE 2
76#define HSMC_TDF_CYCLES_OFFSET 16
77#define HSMC_TDF_CYCLES_SIZE 4
78#define HSMC_TDF_MODE_OFFSET 20
79#define HSMC_TDF_MODE_SIZE 1
80#define HSMC_PMEN_OFFSET 24
81#define HSMC_PMEN_SIZE 1
82#define HSMC_PS_OFFSET 28
83#define HSMC_PS_SIZE 2
84
85/* Constants for READ_MODE */
86#define HSMC_READ_MODE_NCS_CONTROLLED 0
87#define HSMC_READ_MODE_NRD_CONTROLLED 1
88
89/* Constants for WRITE_MODE */
90#define HSMC_WRITE_MODE_NCS_CONTROLLED 0
91#define HSMC_WRITE_MODE_NWE_CONTROLLED 1
92
93/* Constants for EXNW_MODE */
94#define HSMC_EXNW_MODE_DISABLED 0
95#define HSMC_EXNW_MODE_RESERVED 1
96#define HSMC_EXNW_MODE_FROZEN 2
97#define HSMC_EXNW_MODE_READY 3
98
99/* Constants for BAT */
100#define HSMC_BAT_BYTE_SELECT 0
101#define HSMC_BAT_BYTE_WRITE 1
102
103/* Constants for DBW */
104#define HSMC_DBW_8_BITS 0
105#define HSMC_DBW_16_BITS 1
106#define HSMC_DBW_32_BITS 2
107
108/* Bit manipulation macros */
109#define HSMC_BIT(name) \
110 (1 << HSMC_##name##_OFFSET)
111#define HSMC_BF(name,value) \
112 (((value) & ((1 << HSMC_##name##_SIZE) - 1)) \
113 << HSMC_##name##_OFFSET)
114#define HSMC_BFEXT(name,value) \
115 (((value) >> HSMC_##name##_OFFSET) \
116 & ((1 << HSMC_##name##_SIZE) - 1))
117#define HSMC_BFINS(name,value,old) \
118 (((old) & ~(((1 << HSMC_##name##_SIZE) - 1) \
119 << HSMC_##name##_OFFSET)) | HSMC_BF(name,value))
120
121/* Register access macros */
122#define hsmc_readl(port,reg) \
123 readl((port)->regs + HSMC_##reg)
124#define hsmc_writel(port,reg,value) \
125 writel((value), (port)->regs + HSMC_##reg)
126
127#endif /* __ASM_AVR32_HSMC_H__ */
diff --git a/arch/avr32/mach-at32ap/intc.c b/arch/avr32/mach-at32ap/intc.c
new file mode 100644
index 000000000000..74f8c9f2f03d
--- /dev/null
+++ b/arch/avr32/mach-at32ap/intc.c
@@ -0,0 +1,133 @@
1/*
2 * Copyright (C) 2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/clk.h>
10#include <linux/err.h>
11#include <linux/init.h>
12#include <linux/interrupt.h>
13#include <linux/irq.h>
14#include <linux/platform_device.h>
15
16#include <asm/io.h>
17
18#include "intc.h"
19
20struct intc {
21 void __iomem *regs;
22 struct irq_chip chip;
23};
24
25extern struct platform_device at32_intc0_device;
26
27/*
28 * TODO: We may be able to implement mask/unmask by setting IxM flags
29 * in the status register.
30 */
31static void intc_mask_irq(unsigned int irq)
32{
33
34}
35
36static void intc_unmask_irq(unsigned int irq)
37{
38
39}
40
41static struct intc intc0 = {
42 .chip = {
43 .name = "intc",
44 .mask = intc_mask_irq,
45 .unmask = intc_unmask_irq,
46 },
47};
48
49/*
50 * All interrupts go via intc at some point.
51 */
52asmlinkage void do_IRQ(int level, struct pt_regs *regs)
53{
54 struct irq_desc *desc;
55 unsigned int irq;
56 unsigned long status_reg;
57
58 local_irq_disable();
59
60 irq_enter();
61
62 irq = intc_readl(&intc0, INTCAUSE0 - 4 * level);
63 desc = irq_desc + irq;
64 desc->handle_irq(irq, desc, regs);
65
66 /*
67 * Clear all interrupt level masks so that we may handle
68 * interrupts during softirq processing. If this is a nested
69 * interrupt, interrupts must stay globally disabled until we
70 * return.
71 */
72 status_reg = sysreg_read(SR);
73 status_reg &= ~(SYSREG_BIT(I0M) | SYSREG_BIT(I1M)
74 | SYSREG_BIT(I2M) | SYSREG_BIT(I3M));
75 sysreg_write(SR, status_reg);
76
77 irq_exit();
78}
79
80void __init init_IRQ(void)
81{
82 extern void _evba(void);
83 extern void irq_level0(void);
84 struct resource *regs;
85 struct clk *pclk;
86 unsigned int i;
87 u32 offset, readback;
88
89 regs = platform_get_resource(&at32_intc0_device, IORESOURCE_MEM, 0);
90 if (!regs) {
91 printk(KERN_EMERG "intc: no mmio resource defined\n");
92 goto fail;
93 }
94 pclk = clk_get(&at32_intc0_device.dev, "pclk");
95 if (IS_ERR(pclk)) {
96 printk(KERN_EMERG "intc: no clock defined\n");
97 goto fail;
98 }
99
100 clk_enable(pclk);
101
102 intc0.regs = ioremap(regs->start, regs->end - regs->start + 1);
103 if (!intc0.regs) {
104 printk(KERN_EMERG "intc: failed to map registers (0x%08lx)\n",
105 (unsigned long)regs->start);
106 goto fail;
107 }
108
109 /*
110 * Initialize all interrupts to level 0 (lowest priority). The
111 * priority level may be changed by calling
112 * irq_set_priority().
113 *
114 */
115 offset = (unsigned long)&irq_level0 - (unsigned long)&_evba;
116 for (i = 0; i < NR_INTERNAL_IRQS; i++) {
117 intc_writel(&intc0, INTPR0 + 4 * i, offset);
118 readback = intc_readl(&intc0, INTPR0 + 4 * i);
119 if (readback == offset)
120 set_irq_chip_and_handler(i, &intc0.chip,
121 handle_simple_irq);
122 }
123
124 /* Unmask all interrupt levels */
125 sysreg_write(SR, (sysreg_read(SR)
126 & ~(SR_I3M | SR_I2M | SR_I1M | SR_I0M)));
127
128 return;
129
130fail:
131 panic("Interrupt controller initialization failed!\n");
132}
133
diff --git a/arch/avr32/mach-at32ap/intc.h b/arch/avr32/mach-at32ap/intc.h
new file mode 100644
index 000000000000..d289ca2fff13
--- /dev/null
+++ b/arch/avr32/mach-at32ap/intc.h
@@ -0,0 +1,327 @@
1/*
2 * Automatically generated by gen-header.xsl
3 */
4#ifndef __ASM_AVR32_PERIHP_INTC_H__
5#define __ASM_AVR32_PERIHP_INTC_H__
6
7#define INTC_NUM_INT_GRPS 33
8
9#define INTC_INTPR0 0x0
10# define INTC_INTPR0_INTLEV_OFFSET 30
11# define INTC_INTPR0_INTLEV_SIZE 2
12# define INTC_INTPR0_OFFSET_OFFSET 0
13# define INTC_INTPR0_OFFSET_SIZE 24
14#define INTC_INTREQ0 0x100
15# define INTC_INTREQ0_IREQUEST0_OFFSET 0
16# define INTC_INTREQ0_IREQUEST0_SIZE 1
17# define INTC_INTREQ0_IREQUEST1_OFFSET 1
18# define INTC_INTREQ0_IREQUEST1_SIZE 1
19#define INTC_INTPR1 0x4
20# define INTC_INTPR1_INTLEV_OFFSET 30
21# define INTC_INTPR1_INTLEV_SIZE 2
22# define INTC_INTPR1_OFFSET_OFFSET 0
23# define INTC_INTPR1_OFFSET_SIZE 24
24#define INTC_INTREQ1 0x104
25# define INTC_INTREQ1_IREQUEST32_OFFSET 0
26# define INTC_INTREQ1_IREQUEST32_SIZE 1
27# define INTC_INTREQ1_IREQUEST33_OFFSET 1
28# define INTC_INTREQ1_IREQUEST33_SIZE 1
29# define INTC_INTREQ1_IREQUEST34_OFFSET 2
30# define INTC_INTREQ1_IREQUEST34_SIZE 1
31# define INTC_INTREQ1_IREQUEST35_OFFSET 3
32# define INTC_INTREQ1_IREQUEST35_SIZE 1
33# define INTC_INTREQ1_IREQUEST36_OFFSET 4
34# define INTC_INTREQ1_IREQUEST36_SIZE 1
35# define INTC_INTREQ1_IREQUEST37_OFFSET 5
36# define INTC_INTREQ1_IREQUEST37_SIZE 1
37#define INTC_INTPR2 0x8
38# define INTC_INTPR2_INTLEV_OFFSET 30
39# define INTC_INTPR2_INTLEV_SIZE 2
40# define INTC_INTPR2_OFFSET_OFFSET 0
41# define INTC_INTPR2_OFFSET_SIZE 24
42#define INTC_INTREQ2 0x108
43# define INTC_INTREQ2_IREQUEST64_OFFSET 0
44# define INTC_INTREQ2_IREQUEST64_SIZE 1
45# define INTC_INTREQ2_IREQUEST65_OFFSET 1
46# define INTC_INTREQ2_IREQUEST65_SIZE 1
47# define INTC_INTREQ2_IREQUEST66_OFFSET 2
48# define INTC_INTREQ2_IREQUEST66_SIZE 1
49# define INTC_INTREQ2_IREQUEST67_OFFSET 3
50# define INTC_INTREQ2_IREQUEST67_SIZE 1
51# define INTC_INTREQ2_IREQUEST68_OFFSET 4
52# define INTC_INTREQ2_IREQUEST68_SIZE 1
53#define INTC_INTPR3 0xc
54# define INTC_INTPR3_INTLEV_OFFSET 30
55# define INTC_INTPR3_INTLEV_SIZE 2
56# define INTC_INTPR3_OFFSET_OFFSET 0
57# define INTC_INTPR3_OFFSET_SIZE 24
58#define INTC_INTREQ3 0x10c
59# define INTC_INTREQ3_IREQUEST96_OFFSET 0
60# define INTC_INTREQ3_IREQUEST96_SIZE 1
61#define INTC_INTPR4 0x10
62# define INTC_INTPR4_INTLEV_OFFSET 30
63# define INTC_INTPR4_INTLEV_SIZE 2
64# define INTC_INTPR4_OFFSET_OFFSET 0
65# define INTC_INTPR4_OFFSET_SIZE 24
66#define INTC_INTREQ4 0x110
67# define INTC_INTREQ4_IREQUEST128_OFFSET 0
68# define INTC_INTREQ4_IREQUEST128_SIZE 1
69#define INTC_INTPR5 0x14
70# define INTC_INTPR5_INTLEV_OFFSET 30
71# define INTC_INTPR5_INTLEV_SIZE 2
72# define INTC_INTPR5_OFFSET_OFFSET 0
73# define INTC_INTPR5_OFFSET_SIZE 24
74#define INTC_INTREQ5 0x114
75# define INTC_INTREQ5_IREQUEST160_OFFSET 0
76# define INTC_INTREQ5_IREQUEST160_SIZE 1
77#define INTC_INTPR6 0x18
78# define INTC_INTPR6_INTLEV_OFFSET 30
79# define INTC_INTPR6_INTLEV_SIZE 2
80# define INTC_INTPR6_OFFSET_OFFSET 0
81# define INTC_INTPR6_OFFSET_SIZE 24
82#define INTC_INTREQ6 0x118
83# define INTC_INTREQ6_IREQUEST192_OFFSET 0
84# define INTC_INTREQ6_IREQUEST192_SIZE 1
85#define INTC_INTPR7 0x1c
86# define INTC_INTPR7_INTLEV_OFFSET 30
87# define INTC_INTPR7_INTLEV_SIZE 2
88# define INTC_INTPR7_OFFSET_OFFSET 0
89# define INTC_INTPR7_OFFSET_SIZE 24
90#define INTC_INTREQ7 0x11c
91# define INTC_INTREQ7_IREQUEST224_OFFSET 0
92# define INTC_INTREQ7_IREQUEST224_SIZE 1
93#define INTC_INTPR8 0x20
94# define INTC_INTPR8_INTLEV_OFFSET 30
95# define INTC_INTPR8_INTLEV_SIZE 2
96# define INTC_INTPR8_OFFSET_OFFSET 0
97# define INTC_INTPR8_OFFSET_SIZE 24
98#define INTC_INTREQ8 0x120
99# define INTC_INTREQ8_IREQUEST256_OFFSET 0
100# define INTC_INTREQ8_IREQUEST256_SIZE 1
101#define INTC_INTPR9 0x24
102# define INTC_INTPR9_INTLEV_OFFSET 30
103# define INTC_INTPR9_INTLEV_SIZE 2
104# define INTC_INTPR9_OFFSET_OFFSET 0
105# define INTC_INTPR9_OFFSET_SIZE 24
106#define INTC_INTREQ9 0x124
107# define INTC_INTREQ9_IREQUEST288_OFFSET 0
108# define INTC_INTREQ9_IREQUEST288_SIZE 1
109#define INTC_INTPR10 0x28
110# define INTC_INTPR10_INTLEV_OFFSET 30
111# define INTC_INTPR10_INTLEV_SIZE 2
112# define INTC_INTPR10_OFFSET_OFFSET 0
113# define INTC_INTPR10_OFFSET_SIZE 24
114#define INTC_INTREQ10 0x128
115# define INTC_INTREQ10_IREQUEST320_OFFSET 0
116# define INTC_INTREQ10_IREQUEST320_SIZE 1
117#define INTC_INTPR11 0x2c
118# define INTC_INTPR11_INTLEV_OFFSET 30
119# define INTC_INTPR11_INTLEV_SIZE 2
120# define INTC_INTPR11_OFFSET_OFFSET 0
121# define INTC_INTPR11_OFFSET_SIZE 24
122#define INTC_INTREQ11 0x12c
123# define INTC_INTREQ11_IREQUEST352_OFFSET 0
124# define INTC_INTREQ11_IREQUEST352_SIZE 1
125#define INTC_INTPR12 0x30
126# define INTC_INTPR12_INTLEV_OFFSET 30
127# define INTC_INTPR12_INTLEV_SIZE 2
128# define INTC_INTPR12_OFFSET_OFFSET 0
129# define INTC_INTPR12_OFFSET_SIZE 24
130#define INTC_INTREQ12 0x130
131# define INTC_INTREQ12_IREQUEST384_OFFSET 0
132# define INTC_INTREQ12_IREQUEST384_SIZE 1
133#define INTC_INTPR13 0x34
134# define INTC_INTPR13_INTLEV_OFFSET 30
135# define INTC_INTPR13_INTLEV_SIZE 2
136# define INTC_INTPR13_OFFSET_OFFSET 0
137# define INTC_INTPR13_OFFSET_SIZE 24
138#define INTC_INTREQ13 0x134
139# define INTC_INTREQ13_IREQUEST416_OFFSET 0
140# define INTC_INTREQ13_IREQUEST416_SIZE 1
141#define INTC_INTPR14 0x38
142# define INTC_INTPR14_INTLEV_OFFSET 30
143# define INTC_INTPR14_INTLEV_SIZE 2
144# define INTC_INTPR14_OFFSET_OFFSET 0
145# define INTC_INTPR14_OFFSET_SIZE 24
146#define INTC_INTREQ14 0x138
147# define INTC_INTREQ14_IREQUEST448_OFFSET 0
148# define INTC_INTREQ14_IREQUEST448_SIZE 1
149#define INTC_INTPR15 0x3c
150# define INTC_INTPR15_INTLEV_OFFSET 30
151# define INTC_INTPR15_INTLEV_SIZE 2
152# define INTC_INTPR15_OFFSET_OFFSET 0
153# define INTC_INTPR15_OFFSET_SIZE 24
154#define INTC_INTREQ15 0x13c
155# define INTC_INTREQ15_IREQUEST480_OFFSET 0
156# define INTC_INTREQ15_IREQUEST480_SIZE 1
157#define INTC_INTPR16 0x40
158# define INTC_INTPR16_INTLEV_OFFSET 30
159# define INTC_INTPR16_INTLEV_SIZE 2
160# define INTC_INTPR16_OFFSET_OFFSET 0
161# define INTC_INTPR16_OFFSET_SIZE 24
162#define INTC_INTREQ16 0x140
163# define INTC_INTREQ16_IREQUEST512_OFFSET 0
164# define INTC_INTREQ16_IREQUEST512_SIZE 1
165#define INTC_INTPR17 0x44
166# define INTC_INTPR17_INTLEV_OFFSET 30
167# define INTC_INTPR17_INTLEV_SIZE 2
168# define INTC_INTPR17_OFFSET_OFFSET 0
169# define INTC_INTPR17_OFFSET_SIZE 24
170#define INTC_INTREQ17 0x144
171# define INTC_INTREQ17_IREQUEST544_OFFSET 0
172# define INTC_INTREQ17_IREQUEST544_SIZE 1
173#define INTC_INTPR18 0x48
174# define INTC_INTPR18_INTLEV_OFFSET 30
175# define INTC_INTPR18_INTLEV_SIZE 2
176# define INTC_INTPR18_OFFSET_OFFSET 0
177# define INTC_INTPR18_OFFSET_SIZE 24
178#define INTC_INTREQ18 0x148
179# define INTC_INTREQ18_IREQUEST576_OFFSET 0
180# define INTC_INTREQ18_IREQUEST576_SIZE 1
181#define INTC_INTPR19 0x4c
182# define INTC_INTPR19_INTLEV_OFFSET 30
183# define INTC_INTPR19_INTLEV_SIZE 2
184# define INTC_INTPR19_OFFSET_OFFSET 0
185# define INTC_INTPR19_OFFSET_SIZE 24
186#define INTC_INTREQ19 0x14c
187# define INTC_INTREQ19_IREQUEST608_OFFSET 0
188# define INTC_INTREQ19_IREQUEST608_SIZE 1
189# define INTC_INTREQ19_IREQUEST609_OFFSET 1
190# define INTC_INTREQ19_IREQUEST609_SIZE 1
191# define INTC_INTREQ19_IREQUEST610_OFFSET 2
192# define INTC_INTREQ19_IREQUEST610_SIZE 1
193# define INTC_INTREQ19_IREQUEST611_OFFSET 3
194# define INTC_INTREQ19_IREQUEST611_SIZE 1
195#define INTC_INTPR20 0x50
196# define INTC_INTPR20_INTLEV_OFFSET 30
197# define INTC_INTPR20_INTLEV_SIZE 2
198# define INTC_INTPR20_OFFSET_OFFSET 0
199# define INTC_INTPR20_OFFSET_SIZE 24
200#define INTC_INTREQ20 0x150
201# define INTC_INTREQ20_IREQUEST640_OFFSET 0
202# define INTC_INTREQ20_IREQUEST640_SIZE 1
203#define INTC_INTPR21 0x54
204# define INTC_INTPR21_INTLEV_OFFSET 30
205# define INTC_INTPR21_INTLEV_SIZE 2
206# define INTC_INTPR21_OFFSET_OFFSET 0
207# define INTC_INTPR21_OFFSET_SIZE 24
208#define INTC_INTREQ21 0x154
209# define INTC_INTREQ21_IREQUEST672_OFFSET 0
210# define INTC_INTREQ21_IREQUEST672_SIZE 1
211#define INTC_INTPR22 0x58
212# define INTC_INTPR22_INTLEV_OFFSET 30
213# define INTC_INTPR22_INTLEV_SIZE 2
214# define INTC_INTPR22_OFFSET_OFFSET 0
215# define INTC_INTPR22_OFFSET_SIZE 24
216#define INTC_INTREQ22 0x158
217# define INTC_INTREQ22_IREQUEST704_OFFSET 0
218# define INTC_INTREQ22_IREQUEST704_SIZE 1
219# define INTC_INTREQ22_IREQUEST705_OFFSET 1
220# define INTC_INTREQ22_IREQUEST705_SIZE 1
221# define INTC_INTREQ22_IREQUEST706_OFFSET 2
222# define INTC_INTREQ22_IREQUEST706_SIZE 1
223#define INTC_INTPR23 0x5c
224# define INTC_INTPR23_INTLEV_OFFSET 30
225# define INTC_INTPR23_INTLEV_SIZE 2
226# define INTC_INTPR23_OFFSET_OFFSET 0
227# define INTC_INTPR23_OFFSET_SIZE 24
228#define INTC_INTREQ23 0x15c
229# define INTC_INTREQ23_IREQUEST736_OFFSET 0
230# define INTC_INTREQ23_IREQUEST736_SIZE 1
231# define INTC_INTREQ23_IREQUEST737_OFFSET 1
232# define INTC_INTREQ23_IREQUEST737_SIZE 1
233# define INTC_INTREQ23_IREQUEST738_OFFSET 2
234# define INTC_INTREQ23_IREQUEST738_SIZE 1
235#define INTC_INTPR24 0x60
236# define INTC_INTPR24_INTLEV_OFFSET 30
237# define INTC_INTPR24_INTLEV_SIZE 2
238# define INTC_INTPR24_OFFSET_OFFSET 0
239# define INTC_INTPR24_OFFSET_SIZE 24
240#define INTC_INTREQ24 0x160
241# define INTC_INTREQ24_IREQUEST768_OFFSET 0
242# define INTC_INTREQ24_IREQUEST768_SIZE 1
243#define INTC_INTPR25 0x64
244# define INTC_INTPR25_INTLEV_OFFSET 30
245# define INTC_INTPR25_INTLEV_SIZE 2
246# define INTC_INTPR25_OFFSET_OFFSET 0
247# define INTC_INTPR25_OFFSET_SIZE 24
248#define INTC_INTREQ25 0x164
249# define INTC_INTREQ25_IREQUEST800_OFFSET 0
250# define INTC_INTREQ25_IREQUEST800_SIZE 1
251#define INTC_INTPR26 0x68
252# define INTC_INTPR26_INTLEV_OFFSET 30
253# define INTC_INTPR26_INTLEV_SIZE 2
254# define INTC_INTPR26_OFFSET_OFFSET 0
255# define INTC_INTPR26_OFFSET_SIZE 24
256#define INTC_INTREQ26 0x168
257# define INTC_INTREQ26_IREQUEST832_OFFSET 0
258# define INTC_INTREQ26_IREQUEST832_SIZE 1
259#define INTC_INTPR27 0x6c
260# define INTC_INTPR27_INTLEV_OFFSET 30
261# define INTC_INTPR27_INTLEV_SIZE 2
262# define INTC_INTPR27_OFFSET_OFFSET 0
263# define INTC_INTPR27_OFFSET_SIZE 24
264#define INTC_INTREQ27 0x16c
265# define INTC_INTREQ27_IREQUEST864_OFFSET 0
266# define INTC_INTREQ27_IREQUEST864_SIZE 1
267#define INTC_INTPR28 0x70
268# define INTC_INTPR28_INTLEV_OFFSET 30
269# define INTC_INTPR28_INTLEV_SIZE 2
270# define INTC_INTPR28_OFFSET_OFFSET 0
271# define INTC_INTPR28_OFFSET_SIZE 24
272#define INTC_INTREQ28 0x170
273# define INTC_INTREQ28_IREQUEST896_OFFSET 0
274# define INTC_INTREQ28_IREQUEST896_SIZE 1
275#define INTC_INTPR29 0x74
276# define INTC_INTPR29_INTLEV_OFFSET 30
277# define INTC_INTPR29_INTLEV_SIZE 2
278# define INTC_INTPR29_OFFSET_OFFSET 0
279# define INTC_INTPR29_OFFSET_SIZE 24
280#define INTC_INTREQ29 0x174
281# define INTC_INTREQ29_IREQUEST928_OFFSET 0
282# define INTC_INTREQ29_IREQUEST928_SIZE 1
283#define INTC_INTPR30 0x78
284# define INTC_INTPR30_INTLEV_OFFSET 30
285# define INTC_INTPR30_INTLEV_SIZE 2
286# define INTC_INTPR30_OFFSET_OFFSET 0
287# define INTC_INTPR30_OFFSET_SIZE 24
288#define INTC_INTREQ30 0x178
289# define INTC_INTREQ30_IREQUEST960_OFFSET 0
290# define INTC_INTREQ30_IREQUEST960_SIZE 1
291#define INTC_INTPR31 0x7c
292# define INTC_INTPR31_INTLEV_OFFSET 30
293# define INTC_INTPR31_INTLEV_SIZE 2
294# define INTC_INTPR31_OFFSET_OFFSET 0
295# define INTC_INTPR31_OFFSET_SIZE 24
296#define INTC_INTREQ31 0x17c
297# define INTC_INTREQ31_IREQUEST992_OFFSET 0
298# define INTC_INTREQ31_IREQUEST992_SIZE 1
299#define INTC_INTPR32 0x80
300# define INTC_INTPR32_INTLEV_OFFSET 30
301# define INTC_INTPR32_INTLEV_SIZE 2
302# define INTC_INTPR32_OFFSET_OFFSET 0
303# define INTC_INTPR32_OFFSET_SIZE 24
304#define INTC_INTREQ32 0x180
305# define INTC_INTREQ32_IREQUEST1024_OFFSET 0
306# define INTC_INTREQ32_IREQUEST1024_SIZE 1
307#define INTC_INTCAUSE0 0x20c
308# define INTC_INTCAUSE0_CAUSEGRP_OFFSET 0
309# define INTC_INTCAUSE0_CAUSEGRP_SIZE 6
310#define INTC_INTCAUSE1 0x208
311# define INTC_INTCAUSE1_CAUSEGRP_OFFSET 0
312# define INTC_INTCAUSE1_CAUSEGRP_SIZE 6
313#define INTC_INTCAUSE2 0x204
314# define INTC_INTCAUSE2_CAUSEGRP_OFFSET 0
315# define INTC_INTCAUSE2_CAUSEGRP_SIZE 6
316#define INTC_INTCAUSE3 0x200
317# define INTC_INTCAUSE3_CAUSEGRP_OFFSET 0
318# define INTC_INTCAUSE3_CAUSEGRP_SIZE 6
319
320#define INTC_BIT(name) (1 << INTC_##name##_OFFSET)
321#define INTC_MKBF(name, value) (((value) & ((1 << INTC_##name##_SIZE) - 1)) << INTC_##name##_OFFSET)
322#define INTC_GETBF(name, value) (((value) >> INTC_##name##_OFFSET) & ((1 << INTC_##name##_SIZE) - 1))
323
324#define intc_readl(port,reg) readl((port)->regs + INTC_##reg)
325#define intc_writel(port,reg,value) writel((value), (port)->regs + INTC_##reg)
326
327#endif /* __ASM_AVR32_PERIHP_INTC_H__ */
diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c
new file mode 100644
index 000000000000..d3aabfca8598
--- /dev/null
+++ b/arch/avr32/mach-at32ap/pio.c
@@ -0,0 +1,118 @@
1/*
2 * Atmel PIO2 Port Multiplexer support
3 *
4 * Copyright (C) 2004-2006 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/clk.h>
12#include <linux/debugfs.h>
13#include <linux/fs.h>
14#include <linux/platform_device.h>
15
16#include <asm/io.h>
17
18#include <asm/arch/portmux.h>
19
20#include "pio.h"
21
22#define MAX_NR_PIO_DEVICES 8
23
24struct pio_device {
25 void __iomem *regs;
26 const struct platform_device *pdev;
27 struct clk *clk;
28 u32 alloc_mask;
29 char name[32];
30};
31
32static struct pio_device pio_dev[MAX_NR_PIO_DEVICES];
33
34void portmux_set_func(unsigned int portmux_id, unsigned int pin_id,
35 unsigned int function_id)
36{
37 struct pio_device *pio;
38 u32 mask = 1 << pin_id;
39
40 BUG_ON(portmux_id >= MAX_NR_PIO_DEVICES);
41
42 pio = &pio_dev[portmux_id];
43
44 if (function_id)
45 pio_writel(pio, BSR, mask);
46 else
47 pio_writel(pio, ASR, mask);
48 pio_writel(pio, PDR, mask);
49}
50
51static int __init pio_probe(struct platform_device *pdev)
52{
53 struct pio_device *pio = NULL;
54
55 BUG_ON(pdev->id >= MAX_NR_PIO_DEVICES);
56 pio = &pio_dev[pdev->id];
57 BUG_ON(!pio->regs);
58
59 /* TODO: Interrupts */
60
61 platform_set_drvdata(pdev, pio);
62
63 printk(KERN_INFO "%s: Atmel Port Multiplexer at 0x%p (irq %d)\n",
64 pio->name, pio->regs, platform_get_irq(pdev, 0));
65
66 return 0;
67}
68
69static struct platform_driver pio_driver = {
70 .probe = pio_probe,
71 .driver = {
72 .name = "pio",
73 },
74};
75
76static int __init pio_init(void)
77{
78 return platform_driver_register(&pio_driver);
79}
80subsys_initcall(pio_init);
81
82void __init at32_init_pio(struct platform_device *pdev)
83{
84 struct resource *regs;
85 struct pio_device *pio;
86
87 if (pdev->id > MAX_NR_PIO_DEVICES) {
88 dev_err(&pdev->dev, "only %d PIO devices supported\n",
89 MAX_NR_PIO_DEVICES);
90 return;
91 }
92
93 pio = &pio_dev[pdev->id];
94 snprintf(pio->name, sizeof(pio->name), "pio%d", pdev->id);
95
96 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
97 if (!regs) {
98 dev_err(&pdev->dev, "no mmio resource defined\n");
99 return;
100 }
101
102 pio->clk = clk_get(&pdev->dev, "mck");
103 if (IS_ERR(pio->clk))
104 /*
105 * This is a fatal error, but if we continue we might
106 * be so lucky that we manage to initialize the
107 * console and display this message...
108 */
109 dev_err(&pdev->dev, "no mck clock defined\n");
110 else
111 clk_enable(pio->clk);
112
113 pio->pdev = pdev;
114 pio->regs = ioremap(regs->start, regs->end - regs->start + 1);
115
116 pio_writel(pio, ODR, ~0UL);
117 pio_writel(pio, PER, ~0UL);
118}
diff --git a/arch/avr32/mach-at32ap/pio.h b/arch/avr32/mach-at32ap/pio.h
new file mode 100644
index 000000000000..cfea12351599
--- /dev/null
+++ b/arch/avr32/mach-at32ap/pio.h
@@ -0,0 +1,178 @@
1/*
2 * Atmel PIO2 Port Multiplexer support
3 *
4 * Copyright (C) 2004-2006 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#ifndef __ARCH_AVR32_AT32AP_PIO_H__
11#define __ARCH_AVR32_AT32AP_PIO_H__
12
13/* PIO register offsets */
14#define PIO_PER 0x0000
15#define PIO_PDR 0x0004
16#define PIO_PSR 0x0008
17#define PIO_OER 0x0010
18#define PIO_ODR 0x0014
19#define PIO_OSR 0x0018
20#define PIO_IFER 0x0020
21#define PIO_IFDR 0x0024
22#define PIO_ISFR 0x0028
23#define PIO_SODR 0x0030
24#define PIO_CODR 0x0034
25#define PIO_ODSR 0x0038
26#define PIO_PDSR 0x003c
27#define PIO_IER 0x0040
28#define PIO_IDR 0x0044
29#define PIO_IMR 0x0048
30#define PIO_ISR 0x004c
31#define PIO_MDER 0x0050
32#define PIO_MDDR 0x0054
33#define PIO_MDSR 0x0058
34#define PIO_PUDR 0x0060
35#define PIO_PUER 0x0064
36#define PIO_PUSR 0x0068
37#define PIO_ASR 0x0070
38#define PIO_BSR 0x0074
39#define PIO_ABSR 0x0078
40#define PIO_OWER 0x00a0
41#define PIO_OWDR 0x00a4
42#define PIO_OWSR 0x00a8
43
44/* Bitfields in PER */
45
46/* Bitfields in PDR */
47
48/* Bitfields in PSR */
49
50/* Bitfields in OER */
51
52/* Bitfields in ODR */
53
54/* Bitfields in OSR */
55
56/* Bitfields in IFER */
57
58/* Bitfields in IFDR */
59
60/* Bitfields in ISFR */
61
62/* Bitfields in SODR */
63
64/* Bitfields in CODR */
65
66/* Bitfields in ODSR */
67
68/* Bitfields in PDSR */
69
70/* Bitfields in IER */
71
72/* Bitfields in IDR */
73
74/* Bitfields in IMR */
75
76/* Bitfields in ISR */
77
78/* Bitfields in MDER */
79
80/* Bitfields in MDDR */
81
82/* Bitfields in MDSR */
83
84/* Bitfields in PUDR */
85
86/* Bitfields in PUER */
87
88/* Bitfields in PUSR */
89
90/* Bitfields in ASR */
91
92/* Bitfields in BSR */
93
94/* Bitfields in ABSR */
95#define PIO_P0_OFFSET 0
96#define PIO_P0_SIZE 1
97#define PIO_P1_OFFSET 1
98#define PIO_P1_SIZE 1
99#define PIO_P2_OFFSET 2
100#define PIO_P2_SIZE 1
101#define PIO_P3_OFFSET 3
102#define PIO_P3_SIZE 1
103#define PIO_P4_OFFSET 4
104#define PIO_P4_SIZE 1
105#define PIO_P5_OFFSET 5
106#define PIO_P5_SIZE 1
107#define PIO_P6_OFFSET 6
108#define PIO_P6_SIZE 1
109#define PIO_P7_OFFSET 7
110#define PIO_P7_SIZE 1
111#define PIO_P8_OFFSET 8
112#define PIO_P8_SIZE 1
113#define PIO_P9_OFFSET 9
114#define PIO_P9_SIZE 1
115#define PIO_P10_OFFSET 10
116#define PIO_P10_SIZE 1
117#define PIO_P11_OFFSET 11
118#define PIO_P11_SIZE 1
119#define PIO_P12_OFFSET 12
120#define PIO_P12_SIZE 1
121#define PIO_P13_OFFSET 13
122#define PIO_P13_SIZE 1
123#define PIO_P14_OFFSET 14
124#define PIO_P14_SIZE 1
125#define PIO_P15_OFFSET 15
126#define PIO_P15_SIZE 1
127#define PIO_P16_OFFSET 16
128#define PIO_P16_SIZE 1
129#define PIO_P17_OFFSET 17
130#define PIO_P17_SIZE 1
131#define PIO_P18_OFFSET 18
132#define PIO_P18_SIZE 1
133#define PIO_P19_OFFSET 19
134#define PIO_P19_SIZE 1
135#define PIO_P20_OFFSET 20
136#define PIO_P20_SIZE 1
137#define PIO_P21_OFFSET 21
138#define PIO_P21_SIZE 1
139#define PIO_P22_OFFSET 22
140#define PIO_P22_SIZE 1
141#define PIO_P23_OFFSET 23
142#define PIO_P23_SIZE 1
143#define PIO_P24_OFFSET 24
144#define PIO_P24_SIZE 1
145#define PIO_P25_OFFSET 25
146#define PIO_P25_SIZE 1
147#define PIO_P26_OFFSET 26
148#define PIO_P26_SIZE 1
149#define PIO_P27_OFFSET 27
150#define PIO_P27_SIZE 1
151#define PIO_P28_OFFSET 28
152#define PIO_P28_SIZE 1
153#define PIO_P29_OFFSET 29
154#define PIO_P29_SIZE 1
155#define PIO_P30_OFFSET 30
156#define PIO_P30_SIZE 1
157#define PIO_P31_OFFSET 31
158#define PIO_P31_SIZE 1
159
160/* Bitfields in OWER */
161
162/* Bitfields in OWDR */
163
164/* Bitfields in OWSR */
165
166/* Bit manipulation macros */
167#define PIO_BIT(name) (1 << PIO_##name##_OFFSET)
168#define PIO_BF(name,value) (((value) & ((1 << PIO_##name##_SIZE) - 1)) << PIO_##name##_OFFSET)
169#define PIO_BFEXT(name,value) (((value) >> PIO_##name##_OFFSET) & ((1 << PIO_##name##_SIZE) - 1))
170#define PIO_BFINS(name,value,old) (((old) & ~(((1 << PIO_##name##_SIZE) - 1) << PIO_##name##_OFFSET)) | PIO_BF(name,value))
171
172/* Register access macros */
173#define pio_readl(port,reg) readl((port)->regs + PIO_##reg)
174#define pio_writel(port,reg,value) writel((value), (port)->regs + PIO_##reg)
175
176void at32_init_pio(struct platform_device *pdev);
177
178#endif /* __ARCH_AVR32_AT32AP_PIO_H__ */
diff --git a/arch/avr32/mach-at32ap/sm.c b/arch/avr32/mach-at32ap/sm.c
new file mode 100644
index 000000000000..03306eb0345e
--- /dev/null
+++ b/arch/avr32/mach-at32ap/sm.c
@@ -0,0 +1,289 @@
1/*
2 * System Manager driver for AT32AP CPUs
3 *
4 * Copyright (C) 2006 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/errno.h>
12#include <linux/init.h>
13#include <linux/interrupt.h>
14#include <linux/kernel.h>
15#include <linux/platform_device.h>
16#include <linux/random.h>
17#include <linux/spinlock.h>
18
19#include <asm/intc.h>
20#include <asm/io.h>
21#include <asm/irq.h>
22
23#include <asm/arch/sm.h>
24
25#include "sm.h"
26
27#define SM_EIM_IRQ_RESOURCE 1
28#define SM_PM_IRQ_RESOURCE 2
29#define SM_RTC_IRQ_RESOURCE 3
30
31#define to_eim(irqc) container_of(irqc, struct at32_sm, irqc)
32
33struct at32_sm system_manager;
34
35int __init at32_sm_init(void)
36{
37 struct resource *regs;
38 struct at32_sm *sm = &system_manager;
39 int ret = -ENXIO;
40
41 regs = platform_get_resource(&at32_sm_device, IORESOURCE_MEM, 0);
42 if (!regs)
43 goto fail;
44
45 spin_lock_init(&sm->lock);
46 sm->pdev = &at32_sm_device;
47
48 ret = -ENOMEM;
49 sm->regs = ioremap(regs->start, regs->end - regs->start + 1);
50 if (!sm->regs)
51 goto fail;
52
53 return 0;
54
55fail:
56 printk(KERN_ERR "Failed to initialize System Manager: %d\n", ret);
57 return ret;
58}
59
60/*
61 * External Interrupt Module (EIM).
62 *
63 * EIM gets level- or edge-triggered interrupts of either polarity
64 * from the outside and converts it to active-high level-triggered
65 * interrupts that the internal interrupt controller can handle. EIM
66 * also provides masking/unmasking of interrupts, as well as
67 * acknowledging of edge-triggered interrupts.
68 */
69
70static irqreturn_t spurious_eim_interrupt(int irq, void *dev_id,
71 struct pt_regs *regs)
72{
73 printk(KERN_WARNING "Spurious EIM interrupt %d\n", irq);
74 disable_irq(irq);
75 return IRQ_NONE;
76}
77
78static struct irqaction eim_spurious_action = {
79 .handler = spurious_eim_interrupt,
80};
81
82static irqreturn_t eim_handle_irq(int irq, void *dev_id, struct pt_regs *regs)
83{
84 struct irq_controller * irqc = dev_id;
85 struct at32_sm *sm = to_eim(irqc);
86 unsigned long pending;
87
88 /*
89 * No need to disable interrupts globally. The interrupt
90 * level relevant to this group must be masked all the time,
91 * so we know that this particular EIM instance will not be
92 * re-entered.
93 */
94 spin_lock(&sm->lock);
95
96 pending = intc_get_pending(sm->irqc.irq_group);
97 if (unlikely(!pending)) {
98 printk(KERN_ERR "EIM (group %u): No interrupts pending!\n",
99 sm->irqc.irq_group);
100 goto unlock;
101 }
102
103 do {
104 struct irqaction *action;
105 unsigned int i;
106
107 i = fls(pending) - 1;
108 pending &= ~(1 << i);
109 action = sm->action[i];
110
111 /* Acknowledge the interrupt */
112 sm_writel(sm, EIM_ICR, 1 << i);
113
114 spin_unlock(&sm->lock);
115
116 if (action->flags & SA_INTERRUPT)
117 local_irq_disable();
118 action->handler(sm->irqc.first_irq + i, action->dev_id, regs);
119 local_irq_enable();
120 spin_lock(&sm->lock);
121 if (action->flags & SA_SAMPLE_RANDOM)
122 add_interrupt_randomness(sm->irqc.first_irq + i);
123 } while (pending);
124
125unlock:
126 spin_unlock(&sm->lock);
127 return IRQ_HANDLED;
128}
129
130static void eim_mask(struct irq_controller *irqc, unsigned int irq)
131{
132 struct at32_sm *sm = to_eim(irqc);
133 unsigned int i;
134
135 i = irq - sm->irqc.first_irq;
136 sm_writel(sm, EIM_IDR, 1 << i);
137}
138
139static void eim_unmask(struct irq_controller *irqc, unsigned int irq)
140{
141 struct at32_sm *sm = to_eim(irqc);
142 unsigned int i;
143
144 i = irq - sm->irqc.first_irq;
145 sm_writel(sm, EIM_IER, 1 << i);
146}
147
148static int eim_setup(struct irq_controller *irqc, unsigned int irq,
149 struct irqaction *action)
150{
151 struct at32_sm *sm = to_eim(irqc);
152 sm->action[irq - sm->irqc.first_irq] = action;
153 /* Acknowledge earlier interrupts */
154 sm_writel(sm, EIM_ICR, (1<<(irq - sm->irqc.first_irq)));
155 eim_unmask(irqc, irq);
156 return 0;
157}
158
159static void eim_free(struct irq_controller *irqc, unsigned int irq,
160 void *dev)
161{
162 struct at32_sm *sm = to_eim(irqc);
163 eim_mask(irqc, irq);
164 sm->action[irq - sm->irqc.first_irq] = &eim_spurious_action;
165}
166
167static int eim_set_type(struct irq_controller *irqc, unsigned int irq,
168 unsigned int type)
169{
170 struct at32_sm *sm = to_eim(irqc);
171 unsigned long flags;
172 u32 value, pattern;
173
174 spin_lock_irqsave(&sm->lock, flags);
175
176 pattern = 1 << (irq - sm->irqc.first_irq);
177
178 value = sm_readl(sm, EIM_MODE);
179 if (type & IRQ_TYPE_LEVEL)
180 value |= pattern;
181 else
182 value &= ~pattern;
183 sm_writel(sm, EIM_MODE, value);
184 value = sm_readl(sm, EIM_EDGE);
185 if (type & IRQ_EDGE_RISING)
186 value |= pattern;
187 else
188 value &= ~pattern;
189 sm_writel(sm, EIM_EDGE, value);
190 value = sm_readl(sm, EIM_LEVEL);
191 if (type & IRQ_LEVEL_HIGH)
192 value |= pattern;
193 else
194 value &= ~pattern;
195 sm_writel(sm, EIM_LEVEL, value);
196
197 spin_unlock_irqrestore(&sm->lock, flags);
198
199 return 0;
200}
201
202static unsigned int eim_get_type(struct irq_controller *irqc,
203 unsigned int irq)
204{
205 struct at32_sm *sm = to_eim(irqc);
206 unsigned long flags;
207 unsigned int type = 0;
208 u32 mode, edge, level, pattern;
209
210 pattern = 1 << (irq - sm->irqc.first_irq);
211
212 spin_lock_irqsave(&sm->lock, flags);
213 mode = sm_readl(sm, EIM_MODE);
214 edge = sm_readl(sm, EIM_EDGE);
215 level = sm_readl(sm, EIM_LEVEL);
216 spin_unlock_irqrestore(&sm->lock, flags);
217
218 if (mode & pattern)
219 type |= IRQ_TYPE_LEVEL;
220 if (edge & pattern)
221 type |= IRQ_EDGE_RISING;
222 if (level & pattern)
223 type |= IRQ_LEVEL_HIGH;
224
225 return type;
226}
227
228static struct irq_controller_class eim_irq_class = {
229 .typename = "EIM",
230 .handle = eim_handle_irq,
231 .setup = eim_setup,
232 .free = eim_free,
233 .mask = eim_mask,
234 .unmask = eim_unmask,
235 .set_type = eim_set_type,
236 .get_type = eim_get_type,
237};
238
239static int __init eim_init(void)
240{
241 struct at32_sm *sm = &system_manager;
242 unsigned int i;
243 u32 pattern;
244 int ret;
245
246 /*
247 * The EIM is really the same module as SM, so register
248 * mapping, etc. has been taken care of already.
249 */
250
251 /*
252 * Find out how many interrupt lines that are actually
253 * implemented in hardware.
254 */
255 sm_writel(sm, EIM_IDR, ~0UL);
256 sm_writel(sm, EIM_MODE, ~0UL);
257 pattern = sm_readl(sm, EIM_MODE);
258 sm->irqc.nr_irqs = fls(pattern);
259
260 ret = -ENOMEM;
261 sm->action = kmalloc(sizeof(*sm->action) * sm->irqc.nr_irqs,
262 GFP_KERNEL);
263 if (!sm->action)
264 goto out;
265
266 for (i = 0; i < sm->irqc.nr_irqs; i++)
267 sm->action[i] = &eim_spurious_action;
268
269 spin_lock_init(&sm->lock);
270 sm->irqc.irq_group = sm->pdev->resource[SM_EIM_IRQ_RESOURCE].start;
271 sm->irqc.class = &eim_irq_class;
272
273 ret = intc_register_controller(&sm->irqc);
274 if (ret < 0)
275 goto out_free_actions;
276
277 printk("EIM: External Interrupt Module at 0x%p, IRQ group %u\n",
278 sm->regs, sm->irqc.irq_group);
279 printk("EIM: Handling %u external IRQs, starting with IRQ%u\n",
280 sm->irqc.nr_irqs, sm->irqc.first_irq);
281
282 return 0;
283
284out_free_actions:
285 kfree(sm->action);
286out:
287 return ret;
288}
289arch_initcall(eim_init);
diff --git a/arch/avr32/mach-at32ap/sm.h b/arch/avr32/mach-at32ap/sm.h
new file mode 100644
index 000000000000..27565822ae2a
--- /dev/null
+++ b/arch/avr32/mach-at32ap/sm.h
@@ -0,0 +1,240 @@
1/*
2 * Register definitions for SM
3 *
4 * System Manager
5 */
6#ifndef __ASM_AVR32_SM_H__
7#define __ASM_AVR32_SM_H__
8
9/* SM register offsets */
10#define SM_PM_MCCTRL 0x0000
11#define SM_PM_CKSEL 0x0004
12#define SM_PM_CPU_MASK 0x0008
13#define SM_PM_HSB_MASK 0x000c
14#define SM_PM_PBA_MASK 0x0010
15#define SM_PM_PBB_MASK 0x0014
16#define SM_PM_PLL0 0x0020
17#define SM_PM_PLL1 0x0024
18#define SM_PM_VCTRL 0x0030
19#define SM_PM_VMREF 0x0034
20#define SM_PM_VMV 0x0038
21#define SM_PM_IER 0x0040
22#define SM_PM_IDR 0x0044
23#define SM_PM_IMR 0x0048
24#define SM_PM_ISR 0x004c
25#define SM_PM_ICR 0x0050
26#define SM_PM_GCCTRL 0x0060
27#define SM_RTC_CTRL 0x0080
28#define SM_RTC_VAL 0x0084
29#define SM_RTC_TOP 0x0088
30#define SM_RTC_IER 0x0090
31#define SM_RTC_IDR 0x0094
32#define SM_RTC_IMR 0x0098
33#define SM_RTC_ISR 0x009c
34#define SM_RTC_ICR 0x00a0
35#define SM_WDT_CTRL 0x00b0
36#define SM_WDT_CLR 0x00b4
37#define SM_WDT_EXT 0x00b8
38#define SM_RC_RCAUSE 0x00c0
39#define SM_EIM_IER 0x0100
40#define SM_EIM_IDR 0x0104
41#define SM_EIM_IMR 0x0108
42#define SM_EIM_ISR 0x010c
43#define SM_EIM_ICR 0x0110
44#define SM_EIM_MODE 0x0114
45#define SM_EIM_EDGE 0x0118
46#define SM_EIM_LEVEL 0x011c
47#define SM_EIM_TEST 0x0120
48#define SM_EIM_NMIC 0x0124
49
50/* Bitfields in PM_MCCTRL */
51
52/* Bitfields in PM_CKSEL */
53#define SM_CPUSEL_OFFSET 0
54#define SM_CPUSEL_SIZE 3
55#define SM_CPUDIV_OFFSET 7
56#define SM_CPUDIV_SIZE 1
57#define SM_HSBSEL_OFFSET 8
58#define SM_HSBSEL_SIZE 3
59#define SM_HSBDIV_OFFSET 15
60#define SM_HSBDIV_SIZE 1
61#define SM_PBASEL_OFFSET 16
62#define SM_PBASEL_SIZE 3
63#define SM_PBADIV_OFFSET 23
64#define SM_PBADIV_SIZE 1
65#define SM_PBBSEL_OFFSET 24
66#define SM_PBBSEL_SIZE 3
67#define SM_PBBDIV_OFFSET 31
68#define SM_PBBDIV_SIZE 1
69
70/* Bitfields in PM_CPU_MASK */
71
72/* Bitfields in PM_HSB_MASK */
73
74/* Bitfields in PM_PBA_MASK */
75
76/* Bitfields in PM_PBB_MASK */
77
78/* Bitfields in PM_PLL0 */
79#define SM_PLLEN_OFFSET 0
80#define SM_PLLEN_SIZE 1
81#define SM_PLLOSC_OFFSET 1
82#define SM_PLLOSC_SIZE 1
83#define SM_PLLOPT_OFFSET 2
84#define SM_PLLOPT_SIZE 3
85#define SM_PLLDIV_OFFSET 8
86#define SM_PLLDIV_SIZE 8
87#define SM_PLLMUL_OFFSET 16
88#define SM_PLLMUL_SIZE 8
89#define SM_PLLCOUNT_OFFSET 24
90#define SM_PLLCOUNT_SIZE 6
91#define SM_PLLTEST_OFFSET 31
92#define SM_PLLTEST_SIZE 1
93
94/* Bitfields in PM_PLL1 */
95
96/* Bitfields in PM_VCTRL */
97#define SM_VAUTO_OFFSET 0
98#define SM_VAUTO_SIZE 1
99#define SM_PM_VCTRL_VAL_OFFSET 8
100#define SM_PM_VCTRL_VAL_SIZE 7
101
102/* Bitfields in PM_VMREF */
103#define SM_REFSEL_OFFSET 0
104#define SM_REFSEL_SIZE 4
105
106/* Bitfields in PM_VMV */
107#define SM_PM_VMV_VAL_OFFSET 0
108#define SM_PM_VMV_VAL_SIZE 8
109
110/* Bitfields in PM_IER */
111
112/* Bitfields in PM_IDR */
113
114/* Bitfields in PM_IMR */
115
116/* Bitfields in PM_ISR */
117
118/* Bitfields in PM_ICR */
119#define SM_LOCK0_OFFSET 0
120#define SM_LOCK0_SIZE 1
121#define SM_LOCK1_OFFSET 1
122#define SM_LOCK1_SIZE 1
123#define SM_WAKE_OFFSET 2
124#define SM_WAKE_SIZE 1
125#define SM_VOK_OFFSET 3
126#define SM_VOK_SIZE 1
127#define SM_VMRDY_OFFSET 4
128#define SM_VMRDY_SIZE 1
129#define SM_CKRDY_OFFSET 5
130#define SM_CKRDY_SIZE 1
131
132/* Bitfields in PM_GCCTRL */
133#define SM_OSCSEL_OFFSET 0
134#define SM_OSCSEL_SIZE 1
135#define SM_PLLSEL_OFFSET 1
136#define SM_PLLSEL_SIZE 1
137#define SM_CEN_OFFSET 2
138#define SM_CEN_SIZE 1
139#define SM_CPC_OFFSET 3
140#define SM_CPC_SIZE 1
141#define SM_DIVEN_OFFSET 4
142#define SM_DIVEN_SIZE 1
143#define SM_DIV_OFFSET 8
144#define SM_DIV_SIZE 8
145
146/* Bitfields in RTC_CTRL */
147#define SM_PCLR_OFFSET 1
148#define SM_PCLR_SIZE 1
149#define SM_TOPEN_OFFSET 2
150#define SM_TOPEN_SIZE 1
151#define SM_CLKEN_OFFSET 3
152#define SM_CLKEN_SIZE 1
153#define SM_PSEL_OFFSET 8
154#define SM_PSEL_SIZE 16
155
156/* Bitfields in RTC_VAL */
157#define SM_RTC_VAL_VAL_OFFSET 0
158#define SM_RTC_VAL_VAL_SIZE 31
159
160/* Bitfields in RTC_TOP */
161#define SM_RTC_TOP_VAL_OFFSET 0
162#define SM_RTC_TOP_VAL_SIZE 32
163
164/* Bitfields in RTC_IER */
165
166/* Bitfields in RTC_IDR */
167
168/* Bitfields in RTC_IMR */
169
170/* Bitfields in RTC_ISR */
171
172/* Bitfields in RTC_ICR */
173#define SM_TOPI_OFFSET 0
174#define SM_TOPI_SIZE 1
175
176/* Bitfields in WDT_CTRL */
177#define SM_KEY_OFFSET 24
178#define SM_KEY_SIZE 8
179
180/* Bitfields in WDT_CLR */
181
182/* Bitfields in WDT_EXT */
183
184/* Bitfields in RC_RCAUSE */
185#define SM_POR_OFFSET 0
186#define SM_POR_SIZE 1
187#define SM_BOD_OFFSET 1
188#define SM_BOD_SIZE 1
189#define SM_EXT_OFFSET 2
190#define SM_EXT_SIZE 1
191#define SM_WDT_OFFSET 3
192#define SM_WDT_SIZE 1
193#define SM_NTAE_OFFSET 4
194#define SM_NTAE_SIZE 1
195#define SM_SERP_OFFSET 5
196#define SM_SERP_SIZE 1
197
198/* Bitfields in EIM_IER */
199
200/* Bitfields in EIM_IDR */
201
202/* Bitfields in EIM_IMR */
203
204/* Bitfields in EIM_ISR */
205
206/* Bitfields in EIM_ICR */
207
208/* Bitfields in EIM_MODE */
209
210/* Bitfields in EIM_EDGE */
211#define SM_INT0_OFFSET 0
212#define SM_INT0_SIZE 1
213#define SM_INT1_OFFSET 1
214#define SM_INT1_SIZE 1
215#define SM_INT2_OFFSET 2
216#define SM_INT2_SIZE 1
217#define SM_INT3_OFFSET 3
218#define SM_INT3_SIZE 1
219
220/* Bitfields in EIM_LEVEL */
221
222/* Bitfields in EIM_TEST */
223#define SM_TESTEN_OFFSET 31
224#define SM_TESTEN_SIZE 1
225
226/* Bitfields in EIM_NMIC */
227#define SM_EN_OFFSET 0
228#define SM_EN_SIZE 1
229
230/* Bit manipulation macros */
231#define SM_BIT(name) (1 << SM_##name##_OFFSET)
232#define SM_BF(name,value) (((value) & ((1 << SM_##name##_SIZE) - 1)) << SM_##name##_OFFSET)
233#define SM_BFEXT(name,value) (((value) >> SM_##name##_OFFSET) & ((1 << SM_##name##_SIZE) - 1))
234#define SM_BFINS(name,value,old) (((old) & ~(((1 << SM_##name##_SIZE) - 1) << SM_##name##_OFFSET)) | SM_BF(name,value))
235
236/* Register access macros */
237#define sm_readl(port,reg) readl((port)->regs + SM_##reg)
238#define sm_writel(port,reg,value) writel((value), (port)->regs + SM_##reg)
239
240#endif /* __ASM_AVR32_SM_H__ */
diff --git a/arch/avr32/mm/Makefile b/arch/avr32/mm/Makefile
new file mode 100644
index 000000000000..0066491f90d4
--- /dev/null
+++ b/arch/avr32/mm/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the Linux/AVR32 kernel.
3#
4
5obj-y += init.o clear_page.o copy_page.o dma-coherent.o
6obj-y += ioremap.o cache.o fault.o tlb.o
diff --git a/arch/avr32/mm/cache.c b/arch/avr32/mm/cache.c
new file mode 100644
index 000000000000..450515b245a0
--- /dev/null
+++ b/arch/avr32/mm/cache.c
@@ -0,0 +1,150 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/highmem.h>
10#include <linux/unistd.h>
11
12#include <asm/cacheflush.h>
13#include <asm/cachectl.h>
14#include <asm/processor.h>
15#include <asm/uaccess.h>
16
17/*
18 * If you attempt to flush anything more than this, you need superuser
19 * privileges. The value is completely arbitrary.
20 */
21#define CACHEFLUSH_MAX_LEN 1024
22
23void invalidate_dcache_region(void *start, size_t size)
24{
25 unsigned long v, begin, end, linesz;
26
27 linesz = boot_cpu_data.dcache.linesz;
28
29 //printk("invalidate dcache: %p + %u\n", start, size);
30
31 /* You asked for it, you got it */
32 begin = (unsigned long)start & ~(linesz - 1);
33 end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
34
35 for (v = begin; v < end; v += linesz)
36 invalidate_dcache_line((void *)v);
37}
38
39void clean_dcache_region(void *start, size_t size)
40{
41 unsigned long v, begin, end, linesz;
42
43 linesz = boot_cpu_data.dcache.linesz;
44 begin = (unsigned long)start & ~(linesz - 1);
45 end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
46
47 for (v = begin; v < end; v += linesz)
48 clean_dcache_line((void *)v);
49 flush_write_buffer();
50}
51
52void flush_dcache_region(void *start, size_t size)
53{
54 unsigned long v, begin, end, linesz;
55
56 linesz = boot_cpu_data.dcache.linesz;
57 begin = (unsigned long)start & ~(linesz - 1);
58 end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
59
60 for (v = begin; v < end; v += linesz)
61 flush_dcache_line((void *)v);
62 flush_write_buffer();
63}
64
65void invalidate_icache_region(void *start, size_t size)
66{
67 unsigned long v, begin, end, linesz;
68
69 linesz = boot_cpu_data.icache.linesz;
70 begin = (unsigned long)start & ~(linesz - 1);
71 end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
72
73 for (v = begin; v < end; v += linesz)
74 invalidate_icache_line((void *)v);
75}
76
77static inline void __flush_icache_range(unsigned long start, unsigned long end)
78{
79 unsigned long v, linesz;
80
81 linesz = boot_cpu_data.dcache.linesz;
82 for (v = start; v < end; v += linesz) {
83 clean_dcache_line((void *)v);
84 invalidate_icache_line((void *)v);
85 }
86
87 flush_write_buffer();
88}
89
90/*
91 * This one is called after a module has been loaded.
92 */
93void flush_icache_range(unsigned long start, unsigned long end)
94{
95 unsigned long linesz;
96
97 linesz = boot_cpu_data.dcache.linesz;
98 __flush_icache_range(start & ~(linesz - 1),
99 (end + linesz - 1) & ~(linesz - 1));
100}
101
102/*
103 * This one is called from do_no_page(), do_swap_page() and install_page().
104 */
105void flush_icache_page(struct vm_area_struct *vma, struct page *page)
106{
107 if (vma->vm_flags & VM_EXEC) {
108 void *v = kmap(page);
109 __flush_icache_range((unsigned long)v, (unsigned long)v + PAGE_SIZE);
110 kunmap(v);
111 }
112}
113
114/*
115 * This one is used by copy_to_user_page()
116 */
117void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
118 unsigned long addr, int len)
119{
120 if (vma->vm_flags & VM_EXEC)
121 flush_icache_range(addr, addr + len);
122}
123
124asmlinkage int sys_cacheflush(int operation, void __user *addr, size_t len)
125{
126 int ret;
127
128 if (len > CACHEFLUSH_MAX_LEN) {
129 ret = -EPERM;
130 if (!capable(CAP_SYS_ADMIN))
131 goto out;
132 }
133
134 ret = -EFAULT;
135 if (!access_ok(VERIFY_WRITE, addr, len))
136 goto out;
137
138 switch (operation) {
139 case CACHE_IFLUSH:
140 flush_icache_range((unsigned long)addr,
141 (unsigned long)addr + len);
142 ret = 0;
143 break;
144 default:
145 ret = -EINVAL;
146 }
147
148out:
149 return ret;
150}
diff --git a/arch/avr32/mm/clear_page.S b/arch/avr32/mm/clear_page.S
new file mode 100644
index 000000000000..5d70dca00699
--- /dev/null
+++ b/arch/avr32/mm/clear_page.S
@@ -0,0 +1,25 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/linkage.h>
10#include <asm/page.h>
11
12/*
13 * clear_page
14 * r12: P1 address (to)
15 */
16 .text
17 .global clear_page
18clear_page:
19 sub r9, r12, -PAGE_SIZE
20 mov r10, 0
21 mov r11, 0
220: st.d r12++, r10
23 cp r12, r9
24 brne 0b
25 mov pc, lr
diff --git a/arch/avr32/mm/copy_page.S b/arch/avr32/mm/copy_page.S
new file mode 100644
index 000000000000..c2b3752946b8
--- /dev/null
+++ b/arch/avr32/mm/copy_page.S
@@ -0,0 +1,28 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#include <linux/linkage.h>
9#include <asm/page.h>
10
11/*
12 * copy_page
13 *
14 * r12 to (P1 address)
15 * r11 from (P1 address)
16 * r8-r10 scratch
17 */
18 .text
19 .global copy_page
20copy_page:
21 sub r10, r11, -(1 << PAGE_SHIFT)
22 /* pref r11[0] */
231: /* pref r11[8] */
24 ld.d r8, r11++
25 st.d r12++, r8
26 cp r11, r10
27 brlo 1b
28 mov pc, lr
diff --git a/arch/avr32/mm/dma-coherent.c b/arch/avr32/mm/dma-coherent.c
new file mode 100644
index 000000000000..44ab8a7bdae2
--- /dev/null
+++ b/arch/avr32/mm/dma-coherent.c
@@ -0,0 +1,139 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/dma-mapping.h>
10
11#include <asm/addrspace.h>
12#include <asm/cacheflush.h>
13
14void dma_cache_sync(void *vaddr, size_t size, int direction)
15{
16 /*
17 * No need to sync an uncached area
18 */
19 if (PXSEG(vaddr) == P2SEG)
20 return;
21
22 switch (direction) {
23 case DMA_FROM_DEVICE: /* invalidate only */
24 dma_cache_inv(vaddr, size);
25 break;
26 case DMA_TO_DEVICE: /* writeback only */
27 dma_cache_wback(vaddr, size);
28 break;
29 case DMA_BIDIRECTIONAL: /* writeback and invalidate */
30 dma_cache_wback_inv(vaddr, size);
31 break;
32 default:
33 BUG();
34 }
35}
36EXPORT_SYMBOL(dma_cache_sync);
37
38static struct page *__dma_alloc(struct device *dev, size_t size,
39 dma_addr_t *handle, gfp_t gfp)
40{
41 struct page *page, *free, *end;
42 int order;
43
44 size = PAGE_ALIGN(size);
45 order = get_order(size);
46
47 page = alloc_pages(gfp, order);
48 if (!page)
49 return NULL;
50 split_page(page, order);
51
52 /*
53 * When accessing physical memory with valid cache data, we
54 * get a cache hit even if the virtual memory region is marked
55 * as uncached.
56 *
57 * Since the memory is newly allocated, there is no point in
58 * doing a writeback. If the previous owner cares, he should
59 * have flushed the cache before releasing the memory.
60 */
61 invalidate_dcache_region(phys_to_virt(page_to_phys(page)), size);
62
63 *handle = page_to_bus(page);
64 free = page + (size >> PAGE_SHIFT);
65 end = page + (1 << order);
66
67 /*
68 * Free any unused pages
69 */
70 while (free < end) {
71 __free_page(free);
72 free++;
73 }
74
75 return page;
76}
77
78static void __dma_free(struct device *dev, size_t size,
79 struct page *page, dma_addr_t handle)
80{
81 struct page *end = page + (PAGE_ALIGN(size) >> PAGE_SHIFT);
82
83 while (page < end)
84 __free_page(page++);
85}
86
87void *dma_alloc_coherent(struct device *dev, size_t size,
88 dma_addr_t *handle, gfp_t gfp)
89{
90 struct page *page;
91 void *ret = NULL;
92
93 page = __dma_alloc(dev, size, handle, gfp);
94 if (page)
95 ret = phys_to_uncached(page_to_phys(page));
96
97 return ret;
98}
99EXPORT_SYMBOL(dma_alloc_coherent);
100
101void dma_free_coherent(struct device *dev, size_t size,
102 void *cpu_addr, dma_addr_t handle)
103{
104 void *addr = phys_to_cached(uncached_to_phys(cpu_addr));
105 struct page *page;
106
107 pr_debug("dma_free_coherent addr %p (phys %08lx) size %u\n",
108 cpu_addr, (unsigned long)handle, (unsigned)size);
109 BUG_ON(!virt_addr_valid(addr));
110 page = virt_to_page(addr);
111 __dma_free(dev, size, page, handle);
112}
113EXPORT_SYMBOL(dma_free_coherent);
114
115#if 0
116void *dma_alloc_writecombine(struct device *dev, size_t size,
117 dma_addr_t *handle, gfp_t gfp)
118{
119 struct page *page;
120
121 page = __dma_alloc(dev, size, handle, gfp);
122
123 /* Now, map the page into P3 with write-combining turned on */
124 return __ioremap(page_to_phys(page), size, _PAGE_BUFFER);
125}
126EXPORT_SYMBOL(dma_alloc_writecombine);
127
128void dma_free_writecombine(struct device *dev, size_t size,
129 void *cpu_addr, dma_addr_t handle)
130{
131 struct page *page;
132
133 iounmap(cpu_addr);
134
135 page = bus_to_page(handle);
136 __dma_free(dev, size, page, handle);
137}
138EXPORT_SYMBOL(dma_free_writecombine);
139#endif
diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
new file mode 100644
index 000000000000..678557260a35
--- /dev/null
+++ b/arch/avr32/mm/fault.c
@@ -0,0 +1,315 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * Based on linux/arch/sh/mm/fault.c:
5 * Copyright (C) 1999 Niibe Yutaka
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/mm.h>
13#include <linux/module.h>
14#include <linux/pagemap.h>
15
16#include <asm/kdebug.h>
17#include <asm/mmu_context.h>
18#include <asm/sysreg.h>
19#include <asm/uaccess.h>
20#include <asm/tlb.h>
21
22#ifdef DEBUG
23static void dump_code(unsigned long pc)
24{
25 char *p = (char *)pc;
26 char val;
27 int i;
28
29
30 printk(KERN_DEBUG "Code:");
31 for (i = 0; i < 16; i++) {
32 if (__get_user(val, p + i))
33 break;
34 printk(" %02x", val);
35 }
36 printk("\n");
37}
38#endif
39
40#ifdef CONFIG_KPROBES
41ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
42
43/* Hook to register for page fault notifications */
44int register_page_fault_notifier(struct notifier_block *nb)
45{
46 return atomic_notifier_chain_register(&notify_page_fault_chain, nb);
47}
48
49int unregister_page_fault_notifier(struct notifier_block *nb)
50{
51 return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
52}
53
54static inline int notify_page_fault(enum die_val val, struct pt_regs *regs,
55 int trap, int sig)
56{
57 struct die_args args = {
58 .regs = regs,
59 .trapnr = trap,
60 };
61 return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
62}
63#else
64static inline int notify_page_fault(enum die_val val, struct pt_regs *regs,
65 int trap, int sig)
66{
67 return NOTIFY_DONE;
68}
69#endif
70
71/*
72 * This routine handles page faults. It determines the address and the
73 * problem, and then passes it off to one of the appropriate routines.
74 *
75 * ecr is the Exception Cause Register. Possible values are:
76 * 5: Page not found (instruction access)
77 * 6: Protection fault (instruction access)
78 * 12: Page not found (read access)
79 * 13: Page not found (write access)
80 * 14: Protection fault (read access)
81 * 15: Protection fault (write access)
82 */
83asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
84{
85 struct task_struct *tsk;
86 struct mm_struct *mm;
87 struct vm_area_struct *vma;
88 const struct exception_table_entry *fixup;
89 unsigned long address;
90 unsigned long page;
91 int writeaccess = 0;
92
93 if (notify_page_fault(DIE_PAGE_FAULT, regs,
94 ecr, SIGSEGV) == NOTIFY_STOP)
95 return;
96
97 address = sysreg_read(TLBEAR);
98
99 tsk = current;
100 mm = tsk->mm;
101
102 /*
103 * If we're in an interrupt or have no user context, we must
104 * not take the fault...
105 */
106 if (in_atomic() || !mm || regs->sr & SYSREG_BIT(GM))
107 goto no_context;
108
109 local_irq_enable();
110
111 down_read(&mm->mmap_sem);
112
113 vma = find_vma(mm, address);
114 if (!vma)
115 goto bad_area;
116 if (vma->vm_start <= address)
117 goto good_area;
118 if (!(vma->vm_flags & VM_GROWSDOWN))
119 goto bad_area;
120 if (expand_stack(vma, address))
121 goto bad_area;
122
123 /*
124 * Ok, we have a good vm_area for this memory access, so we
125 * can handle it...
126 */
127good_area:
128 //pr_debug("good area: vm_flags = 0x%lx\n", vma->vm_flags);
129 switch (ecr) {
130 case ECR_PROTECTION_X:
131 case ECR_TLB_MISS_X:
132 if (!(vma->vm_flags & VM_EXEC))
133 goto bad_area;
134 break;
135 case ECR_PROTECTION_R:
136 case ECR_TLB_MISS_R:
137 if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)))
138 goto bad_area;
139 break;
140 case ECR_PROTECTION_W:
141 case ECR_TLB_MISS_W:
142 if (!(vma->vm_flags & VM_WRITE))
143 goto bad_area;
144 writeaccess = 1;
145 break;
146 default:
147 panic("Unhandled case %lu in do_page_fault!", ecr);
148 }
149
150 /*
151 * If for any reason at all we couldn't handle the fault, make
152 * sure we exit gracefully rather than endlessly redo the
153 * fault.
154 */
155survive:
156 switch (handle_mm_fault(mm, vma, address, writeaccess)) {
157 case VM_FAULT_MINOR:
158 tsk->min_flt++;
159 break;
160 case VM_FAULT_MAJOR:
161 tsk->maj_flt++;
162 break;
163 case VM_FAULT_SIGBUS:
164 goto do_sigbus;
165 case VM_FAULT_OOM:
166 goto out_of_memory;
167 default:
168 BUG();
169 }
170
171 up_read(&mm->mmap_sem);
172 return;
173
174 /*
175 * Something tried to access memory that isn't in our memory
176 * map. Fix it, but check if it's kernel or user first...
177 */
178bad_area:
179 pr_debug("Bad area [%s:%u]: addr %08lx, ecr %lu\n",
180 tsk->comm, tsk->pid, address, ecr);
181
182 up_read(&mm->mmap_sem);
183
184 if (user_mode(regs)) {
185 /* Hmm...we have to pass address and ecr somehow... */
186 /* tsk->thread.address = address;
187 tsk->thread.error_code = ecr; */
188#ifdef DEBUG
189 show_regs(regs);
190 dump_code(regs->pc);
191
192 page = sysreg_read(PTBR);
193 printk("ptbr = %08lx", page);
194 if (page) {
195 page = ((unsigned long *)page)[address >> 22];
196 printk(" pgd = %08lx", page);
197 if (page & _PAGE_PRESENT) {
198 page &= PAGE_MASK;
199 address &= 0x003ff000;
200 page = ((unsigned long *)__va(page))[address >> PAGE_SHIFT];
201 printk(" pte = %08lx\n", page);
202 }
203 }
204#endif
205 pr_debug("Sending SIGSEGV to PID %d...\n",
206 tsk->pid);
207 force_sig(SIGSEGV, tsk);
208 return;
209 }
210
211no_context:
212 pr_debug("No context\n");
213
214 /* Are we prepared to handle this kernel fault? */
215 fixup = search_exception_tables(regs->pc);
216 if (fixup) {
217 regs->pc = fixup->fixup;
218 pr_debug("Found fixup at %08lx\n", fixup->fixup);
219 return;
220 }
221
222 /*
223 * Oops. The kernel tried to access some bad page. We'll have
224 * to terminate things with extreme prejudice.
225 */
226 if (address < PAGE_SIZE)
227 printk(KERN_ALERT
228 "Unable to handle kernel NULL pointer dereference");
229 else
230 printk(KERN_ALERT
231 "Unable to handle kernel paging request");
232 printk(" at virtual address %08lx\n", address);
233 printk(KERN_ALERT "pc = %08lx\n", regs->pc);
234
235 page = sysreg_read(PTBR);
236 printk(KERN_ALERT "ptbr = %08lx", page);
237 if (page) {
238 page = ((unsigned long *)page)[address >> 22];
239 printk(" pgd = %08lx", page);
240 if (page & _PAGE_PRESENT) {
241 page &= PAGE_MASK;
242 address &= 0x003ff000;
243 page = ((unsigned long *)__va(page))[address >> PAGE_SHIFT];
244 printk(" pte = %08lx\n", page);
245 }
246 }
247 die("\nOops", regs, ecr);
248 do_exit(SIGKILL);
249
250 /*
251 * We ran out of memory, or some other thing happened to us
252 * that made us unable to handle the page fault gracefully.
253 */
254out_of_memory:
255 printk("Out of memory\n");
256 up_read(&mm->mmap_sem);
257 if (current->pid == 1) {
258 yield();
259 down_read(&mm->mmap_sem);
260 goto survive;
261 }
262 printk("VM: Killing process %s\n", tsk->comm);
263 if (user_mode(regs))
264 do_exit(SIGKILL);
265 goto no_context;
266
267do_sigbus:
268 up_read(&mm->mmap_sem);
269
270 /*
271 * Send a sigbus, regardless of whether we were in kernel or
272 * user mode.
273 */
274 /* address, error_code, trap_no, ... */
275#ifdef DEBUG
276 show_regs(regs);
277 dump_code(regs->pc);
278#endif
279 pr_debug("Sending SIGBUS to PID %d...\n", tsk->pid);
280 force_sig(SIGBUS, tsk);
281
282 /* Kernel mode? Handle exceptions or die */
283 if (!user_mode(regs))
284 goto no_context;
285}
286
287asmlinkage void do_bus_error(unsigned long addr, int write_access,
288 struct pt_regs *regs)
289{
290 printk(KERN_ALERT
291 "Bus error at physical address 0x%08lx (%s access)\n",
292 addr, write_access ? "write" : "read");
293 printk(KERN_INFO "DTLB dump:\n");
294 dump_dtlb();
295 die("Bus Error", regs, write_access);
296 do_exit(SIGKILL);
297}
298
299/*
300 * This functionality is currently not possible to implement because
301 * we're using segmentation to ensure a fixed mapping of the kernel
302 * virtual address space.
303 *
304 * It would be possible to implement this, but it would require us to
305 * disable segmentation at startup and load the kernel mappings into
306 * the TLB like any other pages. There will be lots of trickery to
307 * avoid recursive invocation of the TLB miss handler, though...
308 */
309#ifdef CONFIG_DEBUG_PAGEALLOC
310void kernel_map_pages(struct page *page, int numpages, int enable)
311{
312
313}
314EXPORT_SYMBOL(kernel_map_pages);
315#endif
diff --git a/arch/avr32/mm/init.c b/arch/avr32/mm/init.c
new file mode 100644
index 000000000000..3e6c41039808
--- /dev/null
+++ b/arch/avr32/mm/init.c
@@ -0,0 +1,480 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/kernel.h>
10#include <linux/mm.h>
11#include <linux/swap.h>
12#include <linux/init.h>
13#include <linux/initrd.h>
14#include <linux/mmzone.h>
15#include <linux/bootmem.h>
16#include <linux/pagemap.h>
17#include <linux/pfn.h>
18#include <linux/nodemask.h>
19
20#include <asm/page.h>
21#include <asm/mmu_context.h>
22#include <asm/tlb.h>
23#include <asm/io.h>
24#include <asm/dma.h>
25#include <asm/setup.h>
26#include <asm/sections.h>
27
28DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
29
30pgd_t swapper_pg_dir[PTRS_PER_PGD];
31
32struct page *empty_zero_page;
33
34/*
35 * Cache of MMU context last used.
36 */
37unsigned long mmu_context_cache = NO_CONTEXT;
38
39#define START_PFN (NODE_DATA(0)->bdata->node_boot_start >> PAGE_SHIFT)
40#define MAX_LOW_PFN (NODE_DATA(0)->bdata->node_low_pfn)
41
42void show_mem(void)
43{
44 int total = 0, reserved = 0, cached = 0;
45 int slab = 0, free = 0, shared = 0;
46 pg_data_t *pgdat;
47
48 printk("Mem-info:\n");
49 show_free_areas();
50
51 for_each_online_pgdat(pgdat) {
52 struct page *page, *end;
53
54 page = pgdat->node_mem_map;
55 end = page + pgdat->node_spanned_pages;
56
57 do {
58 total++;
59 if (PageReserved(page))
60 reserved++;
61 else if (PageSwapCache(page))
62 cached++;
63 else if (PageSlab(page))
64 slab++;
65 else if (!page_count(page))
66 free++;
67 else
68 shared += page_count(page) - 1;
69 page++;
70 } while (page < end);
71 }
72
73 printk ("%d pages of RAM\n", total);
74 printk ("%d free pages\n", free);
75 printk ("%d reserved pages\n", reserved);
76 printk ("%d slab pages\n", slab);
77 printk ("%d pages shared\n", shared);
78 printk ("%d pages swap cached\n", cached);
79}
80
81static void __init print_memory_map(const char *what,
82 struct tag_mem_range *mem)
83{
84 printk ("%s:\n", what);
85 for (; mem; mem = mem->next) {
86 printk (" %08lx - %08lx\n",
87 (unsigned long)mem->addr,
88 (unsigned long)(mem->addr + mem->size));
89 }
90}
91
92#define MAX_LOWMEM HIGHMEM_START
93#define MAX_LOWMEM_PFN PFN_DOWN(MAX_LOWMEM)
94
95/*
96 * Sort a list of memory regions in-place by ascending address.
97 *
98 * We're using bubble sort because we only have singly linked lists
99 * with few elements.
100 */
101static void __init sort_mem_list(struct tag_mem_range **pmem)
102{
103 int done;
104 struct tag_mem_range **a, **b;
105
106 if (!*pmem)
107 return;
108
109 do {
110 done = 1;
111 a = pmem, b = &(*pmem)->next;
112 while (*b) {
113 if ((*a)->addr > (*b)->addr) {
114 struct tag_mem_range *tmp;
115 tmp = (*b)->next;
116 (*b)->next = *a;
117 *a = *b;
118 *b = tmp;
119 done = 0;
120 }
121 a = &(*a)->next;
122 b = &(*a)->next;
123 }
124 } while (!done);
125}
126
127/*
128 * Find a free memory region large enough for storing the
129 * bootmem bitmap.
130 */
131static unsigned long __init
132find_bootmap_pfn(const struct tag_mem_range *mem)
133{
134 unsigned long bootmap_pages, bootmap_len;
135 unsigned long node_pages = PFN_UP(mem->size);
136 unsigned long bootmap_addr = mem->addr;
137 struct tag_mem_range *reserved = mem_reserved;
138 struct tag_mem_range *ramdisk = mem_ramdisk;
139 unsigned long kern_start = virt_to_phys(_stext);
140 unsigned long kern_end = virt_to_phys(_end);
141
142 bootmap_pages = bootmem_bootmap_pages(node_pages);
143 bootmap_len = bootmap_pages << PAGE_SHIFT;
144
145 /*
146 * Find a large enough region without reserved pages for
147 * storing the bootmem bitmap. We can take advantage of the
148 * fact that all lists have been sorted.
149 *
150 * We have to check explicitly reserved regions as well as the
151 * kernel image and any RAMDISK images...
152 *
153 * Oh, and we have to make sure we don't overwrite the taglist
154 * since we're going to use it until the bootmem allocator is
155 * fully up and running.
156 */
157 while (1) {
158 if ((bootmap_addr < kern_end) &&
159 ((bootmap_addr + bootmap_len) > kern_start))
160 bootmap_addr = kern_end;
161
162 while (reserved &&
163 (bootmap_addr >= (reserved->addr + reserved->size)))
164 reserved = reserved->next;
165
166 if (reserved &&
167 ((bootmap_addr + bootmap_len) >= reserved->addr)) {
168 bootmap_addr = reserved->addr + reserved->size;
169 continue;
170 }
171
172 while (ramdisk &&
173 (bootmap_addr >= (ramdisk->addr + ramdisk->size)))
174 ramdisk = ramdisk->next;
175
176 if (!ramdisk ||
177 ((bootmap_addr + bootmap_len) < ramdisk->addr))
178 break;
179
180 bootmap_addr = ramdisk->addr + ramdisk->size;
181 }
182
183 if ((PFN_UP(bootmap_addr) + bootmap_len) >= (mem->addr + mem->size))
184 return ~0UL;
185
186 return PFN_UP(bootmap_addr);
187}
188
189void __init setup_bootmem(void)
190{
191 unsigned bootmap_size;
192 unsigned long first_pfn, bootmap_pfn, pages;
193 unsigned long max_pfn, max_low_pfn;
194 unsigned long kern_start = virt_to_phys(_stext);
195 unsigned long kern_end = virt_to_phys(_end);
196 unsigned node = 0;
197 struct tag_mem_range *bank, *res;
198
199 sort_mem_list(&mem_phys);
200 sort_mem_list(&mem_reserved);
201
202 print_memory_map("Physical memory", mem_phys);
203 print_memory_map("Reserved memory", mem_reserved);
204
205 nodes_clear(node_online_map);
206
207 if (mem_ramdisk) {
208#ifdef CONFIG_BLK_DEV_INITRD
209 initrd_start = __va(mem_ramdisk->addr);
210 initrd_end = initrd_start + mem_ramdisk->size;
211
212 print_memory_map("RAMDISK images", mem_ramdisk);
213 if (mem_ramdisk->next)
214 printk(KERN_WARNING
215 "Warning: Only the first RAMDISK image "
216 "will be used\n");
217 sort_mem_list(&mem_ramdisk);
218#else
219 printk(KERN_WARNING "RAM disk image present, but "
220 "no initrd support in kernel!\n");
221#endif
222 }
223
224 if (mem_phys->next)
225 printk(KERN_WARNING "Only using first memory bank\n");
226
227 for (bank = mem_phys; bank; bank = NULL) {
228 first_pfn = PFN_UP(bank->addr);
229 max_low_pfn = max_pfn = PFN_DOWN(bank->addr + bank->size);
230 bootmap_pfn = find_bootmap_pfn(bank);
231 if (bootmap_pfn > max_pfn)
232 panic("No space for bootmem bitmap!\n");
233
234 if (max_low_pfn > MAX_LOWMEM_PFN) {
235 max_low_pfn = MAX_LOWMEM_PFN;
236#ifndef CONFIG_HIGHMEM
237 /*
238 * Lowmem is memory that can be addressed
239 * directly through P1/P2
240 */
241 printk(KERN_WARNING
242 "Node %u: Only %ld MiB of memory will be used.\n",
243 node, MAX_LOWMEM >> 20);
244 printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
245#else
246#error HIGHMEM is not supported by AVR32 yet
247#endif
248 }
249
250 /* Initialize the boot-time allocator with low memory only. */
251 bootmap_size = init_bootmem_node(NODE_DATA(node), bootmap_pfn,
252 first_pfn, max_low_pfn);
253
254 printk("Node %u: bdata = %p, bdata->node_bootmem_map = %p\n",
255 node, NODE_DATA(node)->bdata,
256 NODE_DATA(node)->bdata->node_bootmem_map);
257
258 /*
259 * Register fully available RAM pages with the bootmem
260 * allocator.
261 */
262 pages = max_low_pfn - first_pfn;
263 free_bootmem_node (NODE_DATA(node), PFN_PHYS(first_pfn),
264 PFN_PHYS(pages));
265
266 /*
267 * Reserve space for the kernel image (if present in
268 * this node)...
269 */
270 if ((kern_start >= PFN_PHYS(first_pfn)) &&
271 (kern_start < PFN_PHYS(max_pfn))) {
272 printk("Node %u: Kernel image %08lx - %08lx\n",
273 node, kern_start, kern_end);
274 reserve_bootmem_node(NODE_DATA(node), kern_start,
275 kern_end - kern_start);
276 }
277
278 /* ...the bootmem bitmap... */
279 reserve_bootmem_node(NODE_DATA(node),
280 PFN_PHYS(bootmap_pfn),
281 bootmap_size);
282
283 /* ...any RAMDISK images... */
284 for (res = mem_ramdisk; res; res = res->next) {
285 if (res->addr > PFN_PHYS(max_pfn))
286 break;
287
288 if (res->addr >= PFN_PHYS(first_pfn)) {
289 printk("Node %u: RAMDISK %08lx - %08lx\n",
290 node,
291 (unsigned long)res->addr,
292 (unsigned long)(res->addr + res->size));
293 reserve_bootmem_node(NODE_DATA(node),
294 res->addr, res->size);
295 }
296 }
297
298 /* ...and any other reserved regions. */
299 for (res = mem_reserved; res; res = res->next) {
300 if (res->addr > PFN_PHYS(max_pfn))
301 break;
302
303 if (res->addr >= PFN_PHYS(first_pfn)) {
304 printk("Node %u: Reserved %08lx - %08lx\n",
305 node,
306 (unsigned long)res->addr,
307 (unsigned long)(res->addr + res->size));
308 reserve_bootmem_node(NODE_DATA(node),
309 res->addr, res->size);
310 }
311 }
312
313 node_set_online(node);
314 }
315}
316
317/*
318 * paging_init() sets up the page tables
319 *
320 * This routine also unmaps the page at virtual kernel address 0, so
321 * that we can trap those pesky NULL-reference errors in the kernel.
322 */
323void __init paging_init(void)
324{
325 extern unsigned long _evba;
326 void *zero_page;
327 int nid;
328
329 /*
330 * Make sure we can handle exceptions before enabling
331 * paging. Not that we should ever _get_ any exceptions this
332 * early, but you never know...
333 */
334 printk("Exception vectors start at %p\n", &_evba);
335 sysreg_write(EVBA, (unsigned long)&_evba);
336
337 /*
338 * Since we are ready to handle exceptions now, we should let
339 * the CPU generate them...
340 */
341 __asm__ __volatile__ ("csrf %0" : : "i"(SR_EM_BIT));
342
343 /*
344 * Allocate the zero page. The allocator will panic if it
345 * can't satisfy the request, so no need to check.
346 */
347 zero_page = alloc_bootmem_low_pages_node(NODE_DATA(0),
348 PAGE_SIZE);
349
350 {
351 pgd_t *pg_dir;
352 int i;
353
354 pg_dir = swapper_pg_dir;
355 sysreg_write(PTBR, (unsigned long)pg_dir);
356
357 for (i = 0; i < PTRS_PER_PGD; i++)
358 pgd_val(pg_dir[i]) = 0;
359
360 enable_mmu();
361 printk ("CPU: Paging enabled\n");
362 }
363
364 for_each_online_node(nid) {
365 pg_data_t *pgdat = NODE_DATA(nid);
366 unsigned long zones_size[MAX_NR_ZONES];
367 unsigned long low, start_pfn;
368
369 start_pfn = pgdat->bdata->node_boot_start;
370 start_pfn >>= PAGE_SHIFT;
371 low = pgdat->bdata->node_low_pfn;
372
373 memset(zones_size, 0, sizeof(zones_size));
374 zones_size[ZONE_NORMAL] = low - start_pfn;
375
376 printk("Node %u: start_pfn = 0x%lx, low = 0x%lx\n",
377 nid, start_pfn, low);
378
379 free_area_init_node(nid, pgdat, zones_size, start_pfn, NULL);
380
381 printk("Node %u: mem_map starts at %p\n",
382 pgdat->node_id, pgdat->node_mem_map);
383 }
384
385 mem_map = NODE_DATA(0)->node_mem_map;
386
387 memset(zero_page, 0, PAGE_SIZE);
388 empty_zero_page = virt_to_page(zero_page);
389 flush_dcache_page(empty_zero_page);
390}
391
392void __init mem_init(void)
393{
394 int codesize, reservedpages, datasize, initsize;
395 int nid, i;
396
397 reservedpages = 0;
398 high_memory = NULL;
399
400 /* this will put all low memory onto the freelists */
401 for_each_online_node(nid) {
402 pg_data_t *pgdat = NODE_DATA(nid);
403 unsigned long node_pages = 0;
404 void *node_high_memory;
405
406 num_physpages += pgdat->node_present_pages;
407
408 if (pgdat->node_spanned_pages != 0)
409 node_pages = free_all_bootmem_node(pgdat);
410
411 totalram_pages += node_pages;
412
413 for (i = 0; i < node_pages; i++)
414 if (PageReserved(pgdat->node_mem_map + i))
415 reservedpages++;
416
417 node_high_memory = (void *)((pgdat->node_start_pfn
418 + pgdat->node_spanned_pages)
419 << PAGE_SHIFT);
420 if (node_high_memory > high_memory)
421 high_memory = node_high_memory;
422 }
423
424 max_mapnr = MAP_NR(high_memory);
425
426 codesize = (unsigned long)_etext - (unsigned long)_text;
427 datasize = (unsigned long)_edata - (unsigned long)_data;
428 initsize = (unsigned long)__init_end - (unsigned long)__init_begin;
429
430 printk ("Memory: %luk/%luk available (%dk kernel code, "
431 "%dk reserved, %dk data, %dk init)\n",
432 (unsigned long)nr_free_pages() << (PAGE_SHIFT - 10),
433 totalram_pages << (PAGE_SHIFT - 10),
434 codesize >> 10,
435 reservedpages << (PAGE_SHIFT - 10),
436 datasize >> 10,
437 initsize >> 10);
438}
439
440static inline void free_area(unsigned long addr, unsigned long end, char *s)
441{
442 unsigned int size = (end - addr) >> 10;
443
444 for (; addr < end; addr += PAGE_SIZE) {
445 struct page *page = virt_to_page(addr);
446 ClearPageReserved(page);
447 init_page_count(page);
448 free_page(addr);
449 totalram_pages++;
450 }
451
452 if (size && s)
453 printk(KERN_INFO "Freeing %s memory: %dK (%lx - %lx)\n",
454 s, size, end - (size << 10), end);
455}
456
457void free_initmem(void)
458{
459 free_area((unsigned long)__init_begin, (unsigned long)__init_end,
460 "init");
461}
462
463#ifdef CONFIG_BLK_DEV_INITRD
464
465static int keep_initrd;
466
467void free_initrd_mem(unsigned long start, unsigned long end)
468{
469 if (!keep_initrd)
470 free_area(start, end, "initrd");
471}
472
473static int __init keepinitrd_setup(char *__unused)
474{
475 keep_initrd = 1;
476 return 1;
477}
478
479__setup("keepinitrd", keepinitrd_setup);
480#endif
diff --git a/arch/avr32/mm/ioremap.c b/arch/avr32/mm/ioremap.c
new file mode 100644
index 000000000000..536021877df6
--- /dev/null
+++ b/arch/avr32/mm/ioremap.c
@@ -0,0 +1,197 @@
1/*
2 * Copyright (C) 2004-2006 Atmel Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#include <linux/vmalloc.h>
9#include <linux/module.h>
10
11#include <asm/io.h>
12#include <asm/pgtable.h>
13#include <asm/cacheflush.h>
14#include <asm/tlbflush.h>
15#include <asm/addrspace.h>
16
17static inline int remap_area_pte(pte_t *pte, unsigned long address,
18 unsigned long end, unsigned long phys_addr,
19 pgprot_t prot)
20{
21 unsigned long pfn;
22
23 pfn = phys_addr >> PAGE_SHIFT;
24 do {
25 WARN_ON(!pte_none(*pte));
26
27 set_pte(pte, pfn_pte(pfn, prot));
28 address += PAGE_SIZE;
29 pfn++;
30 pte++;
31 } while (address && (address < end));
32
33 return 0;
34}
35
36static inline int remap_area_pmd(pmd_t *pmd, unsigned long address,
37 unsigned long end, unsigned long phys_addr,
38 pgprot_t prot)
39{
40 unsigned long next;
41
42 phys_addr -= address;
43
44 do {
45 pte_t *pte = pte_alloc_kernel(pmd, address);
46 if (!pte)
47 return -ENOMEM;
48
49 next = (address + PMD_SIZE) & PMD_MASK;
50 if (remap_area_pte(pte, address, next,
51 address + phys_addr, prot))
52 return -ENOMEM;
53
54 address = next;
55 pmd++;
56 } while (address && (address < end));
57 return 0;
58}
59
60static int remap_area_pud(pud_t *pud, unsigned long address,
61 unsigned long end, unsigned long phys_addr,
62 pgprot_t prot)
63{
64 unsigned long next;
65
66 phys_addr -= address;
67
68 do {
69 pmd_t *pmd = pmd_alloc(&init_mm, pud, address);
70 if (!pmd)
71 return -ENOMEM;
72 next = (address + PUD_SIZE) & PUD_MASK;
73 if (remap_area_pmd(pmd, address, next,
74 phys_addr + address, prot))
75 return -ENOMEM;
76
77 address = next;
78 pud++;
79 } while (address && address < end);
80
81 return 0;
82}
83
84static int remap_area_pages(unsigned long address, unsigned long phys_addr,
85 size_t size, pgprot_t prot)
86{
87 unsigned long end = address + size;
88 unsigned long next;
89 pgd_t *pgd;
90 int err = 0;
91
92 phys_addr -= address;
93
94 pgd = pgd_offset_k(address);
95 flush_cache_all();
96 BUG_ON(address >= end);
97
98 spin_lock(&init_mm.page_table_lock);
99 do {
100 pud_t *pud = pud_alloc(&init_mm, pgd, address);
101
102 err = -ENOMEM;
103 if (!pud)
104 break;
105
106 next = (address + PGDIR_SIZE) & PGDIR_MASK;
107 if (next < address || next > end)
108 next = end;
109 err = remap_area_pud(pud, address, next,
110 phys_addr + address, prot);
111 if (err)
112 break;
113
114 address = next;
115 pgd++;
116 } while (address && (address < end));
117
118 spin_unlock(&init_mm.page_table_lock);
119 flush_tlb_all();
120 return err;
121}
122
123/*
124 * Re-map an arbitrary physical address space into the kernel virtual
125 * address space. Needed when the kernel wants to access physical
126 * memory directly.
127 */
128void __iomem *__ioremap(unsigned long phys_addr, size_t size,
129 unsigned long flags)
130{
131 void *addr;
132 struct vm_struct *area;
133 unsigned long offset, last_addr;
134 pgprot_t prot;
135
136 /*
137 * Check if we can simply use the P4 segment. This area is
138 * uncacheable, so if caching/buffering is requested, we can't
139 * use it.
140 */
141 if ((phys_addr >= P4SEG) && (flags == 0))
142 return (void __iomem *)phys_addr;
143
144 /* Don't allow wraparound or zero size */
145 last_addr = phys_addr + size - 1;
146 if (!size || last_addr < phys_addr)
147 return NULL;
148
149 /*
150 * XXX: When mapping regular RAM, we'd better make damn sure
151 * it's never used for anything else. But this is really the
152 * caller's responsibility...
153 */
154 if (PHYSADDR(P2SEGADDR(phys_addr)) == phys_addr)
155 return (void __iomem *)P2SEGADDR(phys_addr);
156
157 /* Mappings have to be page-aligned */
158 offset = phys_addr & ~PAGE_MASK;
159 phys_addr &= PAGE_MASK;
160 size = PAGE_ALIGN(last_addr + 1) - phys_addr;
161
162 prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY
163 | _PAGE_ACCESSED | _PAGE_TYPE_SMALL | flags);
164
165 /*
166 * Ok, go for it..
167 */
168 area = get_vm_area(size, VM_IOREMAP);
169 if (!area)
170 return NULL;
171 area->phys_addr = phys_addr;
172 addr = area->addr;
173 if (remap_area_pages((unsigned long)addr, phys_addr, size, prot)) {
174 vunmap(addr);
175 return NULL;
176 }
177
178 return (void __iomem *)(offset + (char *)addr);
179}
180EXPORT_SYMBOL(__ioremap);
181
182void __iounmap(void __iomem *addr)
183{
184 struct vm_struct *p;
185
186 if ((unsigned long)addr >= P4SEG)
187 return;
188
189 p = remove_vm_area((void *)(PAGE_MASK & (unsigned long __force)addr));
190 if (unlikely(!p)) {
191 printk (KERN_ERR "iounmap: bad address %p\n", addr);
192 return;
193 }
194
195 kfree (p);
196}
197EXPORT_SYMBOL(__iounmap);
diff --git a/arch/avr32/mm/tlb.c b/arch/avr32/mm/tlb.c
new file mode 100644
index 000000000000..7b073052203d
--- /dev/null
+++ b/arch/avr32/mm/tlb.c
@@ -0,0 +1,380 @@
1/*
2 * AVR32 TLB operations
3 *
4 * Copyright (C) 2004-2006 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/mm.h>
11
12#include <asm/mmu_context.h>
13
14#define _TLBEHI_I 0x100
15
16void show_dtlb_entry(unsigned int index)
17{
18 unsigned int tlbehi, tlbehi_save, tlbelo, mmucr, mmucr_save;
19 unsigned long flags;
20
21 local_irq_save(flags);
22 mmucr_save = sysreg_read(MMUCR);
23 tlbehi_save = sysreg_read(TLBEHI);
24 mmucr = mmucr_save & 0x13;
25 mmucr |= index << 14;
26 sysreg_write(MMUCR, mmucr);
27
28 asm volatile("tlbr" : : : "memory");
29 cpu_sync_pipeline();
30
31 tlbehi = sysreg_read(TLBEHI);
32 tlbelo = sysreg_read(TLBELO);
33
34 printk("%2u: %c %c %02x %05x %05x %o %o %c %c %c %c\n",
35 index,
36 (tlbehi & 0x200)?'1':'0',
37 (tlbelo & 0x100)?'1':'0',
38 (tlbehi & 0xff),
39 (tlbehi >> 12), (tlbelo >> 12),
40 (tlbelo >> 4) & 7, (tlbelo >> 2) & 3,
41 (tlbelo & 0x200)?'1':'0',
42 (tlbelo & 0x080)?'1':'0',
43 (tlbelo & 0x001)?'1':'0',
44 (tlbelo & 0x002)?'1':'0');
45
46 sysreg_write(MMUCR, mmucr_save);
47 sysreg_write(TLBEHI, tlbehi_save);
48 cpu_sync_pipeline();
49 local_irq_restore(flags);
50}
51
52void dump_dtlb(void)
53{
54 unsigned int i;
55
56 printk("ID V G ASID VPN PFN AP SZ C B W D\n");
57 for (i = 0; i < 32; i++)
58 show_dtlb_entry(i);
59}
60
61static unsigned long last_mmucr;
62
63static inline void set_replacement_pointer(unsigned shift)
64{
65 unsigned long mmucr, mmucr_save;
66
67 mmucr = mmucr_save = sysreg_read(MMUCR);
68
69 /* Does this mapping already exist? */
70 __asm__ __volatile__(
71 " tlbs\n"
72 " mfsr %0, %1"
73 : "=r"(mmucr)
74 : "i"(SYSREG_MMUCR));
75
76 if (mmucr & SYSREG_BIT(MMUCR_N)) {
77 /* Not found -- pick a not-recently-accessed entry */
78 unsigned long rp;
79 unsigned long tlbar = sysreg_read(TLBARLO);
80
81 rp = 32 - fls(tlbar);
82 if (rp == 32) {
83 rp = 0;
84 sysreg_write(TLBARLO, -1L);
85 }
86
87 mmucr &= 0x13;
88 mmucr |= (rp << shift);
89
90 sysreg_write(MMUCR, mmucr);
91 }
92
93 last_mmucr = mmucr;
94}
95
96static void update_dtlb(unsigned long address, pte_t pte, unsigned long asid)
97{
98 unsigned long vpn;
99
100 vpn = (address & MMU_VPN_MASK) | _TLBEHI_VALID | asid;
101 sysreg_write(TLBEHI, vpn);
102 cpu_sync_pipeline();
103
104 set_replacement_pointer(14);
105
106 sysreg_write(TLBELO, pte_val(pte) & _PAGE_FLAGS_HARDWARE_MASK);
107
108 /* Let's go */
109 asm volatile("nop\n\ttlbw" : : : "memory");
110 cpu_sync_pipeline();
111}
112
113void update_mmu_cache(struct vm_area_struct *vma,
114 unsigned long address, pte_t pte)
115{
116 unsigned long flags;
117
118 /* ptrace may call this routine */
119 if (vma && current->active_mm != vma->vm_mm)
120 return;
121
122 local_irq_save(flags);
123 update_dtlb(address, pte, get_asid());
124 local_irq_restore(flags);
125}
126
127void __flush_tlb_page(unsigned long asid, unsigned long page)
128{
129 unsigned long mmucr, tlbehi;
130
131 page |= asid;
132 sysreg_write(TLBEHI, page);
133 cpu_sync_pipeline();
134 asm volatile("tlbs");
135 mmucr = sysreg_read(MMUCR);
136
137 if (!(mmucr & SYSREG_BIT(MMUCR_N))) {
138 unsigned long tlbarlo;
139 unsigned long entry;
140
141 /* Clear the "valid" bit */
142 tlbehi = sysreg_read(TLBEHI);
143 tlbehi &= ~_TLBEHI_VALID;
144 sysreg_write(TLBEHI, tlbehi);
145 cpu_sync_pipeline();
146
147 /* mark the entry as "not accessed" */
148 entry = (mmucr >> 14) & 0x3f;
149 tlbarlo = sysreg_read(TLBARLO);
150 tlbarlo |= (0x80000000 >> entry);
151 sysreg_write(TLBARLO, tlbarlo);
152
153 /* update the entry with valid bit clear */
154 asm volatile("tlbw");
155 cpu_sync_pipeline();
156 }
157}
158
159void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
160{
161 if (vma->vm_mm && vma->vm_mm->context != NO_CONTEXT) {
162 unsigned long flags, asid;
163 unsigned long saved_asid = MMU_NO_ASID;
164
165 asid = vma->vm_mm->context & MMU_CONTEXT_ASID_MASK;
166 page &= PAGE_MASK;
167
168 local_irq_save(flags);
169 if (vma->vm_mm != current->mm) {
170 saved_asid = get_asid();
171 set_asid(asid);
172 }
173
174 __flush_tlb_page(asid, page);
175
176 if (saved_asid != MMU_NO_ASID)
177 set_asid(saved_asid);
178 local_irq_restore(flags);
179 }
180}
181
182void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
183 unsigned long end)
184{
185 struct mm_struct *mm = vma->vm_mm;
186
187 if (mm->context != NO_CONTEXT) {
188 unsigned long flags;
189 int size;
190
191 local_irq_save(flags);
192 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
193 if (size > (MMU_DTLB_ENTRIES / 4)) { /* Too many entries to flush */
194 mm->context = NO_CONTEXT;
195 if (mm == current->mm)
196 activate_context(mm);
197 } else {
198 unsigned long asid = mm->context & MMU_CONTEXT_ASID_MASK;
199 unsigned long saved_asid = MMU_NO_ASID;
200
201 start &= PAGE_MASK;
202 end += (PAGE_SIZE - 1);
203 end &= PAGE_MASK;
204 if (mm != current->mm) {
205 saved_asid = get_asid();
206 set_asid(asid);
207 }
208
209 while (start < end) {
210 __flush_tlb_page(asid, start);
211 start += PAGE_SIZE;
212 }
213 if (saved_asid != MMU_NO_ASID)
214 set_asid(saved_asid);
215 }
216 local_irq_restore(flags);
217 }
218}
219
220/*
221 * TODO: If this is only called for addresses > TASK_SIZE, we can probably
222 * skip the ASID stuff and just use the Global bit...
223 */
224void flush_tlb_kernel_range(unsigned long start, unsigned long end)
225{
226 unsigned long flags;
227 int size;
228
229 local_irq_save(flags);
230 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
231 if (size > (MMU_DTLB_ENTRIES / 4)) { /* Too many entries to flush */
232 flush_tlb_all();
233 } else {
234 unsigned long asid = init_mm.context & MMU_CONTEXT_ASID_MASK;
235 unsigned long saved_asid = get_asid();
236
237 start &= PAGE_MASK;
238 end += (PAGE_SIZE - 1);
239 end &= PAGE_MASK;
240 set_asid(asid);
241 while (start < end) {
242 __flush_tlb_page(asid, start);
243 start += PAGE_SIZE;
244 }
245 set_asid(saved_asid);
246 }
247 local_irq_restore(flags);
248}
249
250void flush_tlb_mm(struct mm_struct *mm)
251{
252 /* Invalidate all TLB entries of this process by getting a new ASID */
253 if (mm->context != NO_CONTEXT) {
254 unsigned long flags;
255
256 local_irq_save(flags);
257 mm->context = NO_CONTEXT;
258 if (mm == current->mm)
259 activate_context(mm);
260 local_irq_restore(flags);
261 }
262}
263
264void flush_tlb_all(void)
265{
266 unsigned long flags;
267
268 local_irq_save(flags);
269 sysreg_write(MMUCR, sysreg_read(MMUCR) | SYSREG_BIT(MMUCR_I));
270 local_irq_restore(flags);
271}
272
273#ifdef CONFIG_PROC_FS
274
275#include <linux/seq_file.h>
276#include <linux/proc_fs.h>
277#include <linux/init.h>
278
279static void *tlb_start(struct seq_file *tlb, loff_t *pos)
280{
281 static unsigned long tlb_index;
282
283 if (*pos >= 32)
284 return NULL;
285
286 tlb_index = 0;
287 return &tlb_index;
288}
289
290static void *tlb_next(struct seq_file *tlb, void *v, loff_t *pos)
291{
292 unsigned long *index = v;
293
294 if (*index >= 31)
295 return NULL;
296
297 ++*pos;
298 ++*index;
299 return index;
300}
301
302static void tlb_stop(struct seq_file *tlb, void *v)
303{
304
305}
306
307static int tlb_show(struct seq_file *tlb, void *v)
308{
309 unsigned int tlbehi, tlbehi_save, tlbelo, mmucr, mmucr_save;
310 unsigned long flags;
311 unsigned long *index = v;
312
313 if (*index == 0)
314 seq_puts(tlb, "ID V G ASID VPN PFN AP SZ C B W D\n");
315
316 BUG_ON(*index >= 32);
317
318 local_irq_save(flags);
319 mmucr_save = sysreg_read(MMUCR);
320 tlbehi_save = sysreg_read(TLBEHI);
321 mmucr = mmucr_save & 0x13;
322 mmucr |= *index << 14;
323 sysreg_write(MMUCR, mmucr);
324
325 asm volatile("tlbr" : : : "memory");
326 cpu_sync_pipeline();
327
328 tlbehi = sysreg_read(TLBEHI);
329 tlbelo = sysreg_read(TLBELO);
330
331 sysreg_write(MMUCR, mmucr_save);
332 sysreg_write(TLBEHI, tlbehi_save);
333 cpu_sync_pipeline();
334 local_irq_restore(flags);
335
336 seq_printf(tlb, "%2lu: %c %c %02x %05x %05x %o %o %c %c %c %c\n",
337 *index,
338 (tlbehi & 0x200)?'1':'0',
339 (tlbelo & 0x100)?'1':'0',
340 (tlbehi & 0xff),
341 (tlbehi >> 12), (tlbelo >> 12),
342 (tlbelo >> 4) & 7, (tlbelo >> 2) & 3,
343 (tlbelo & 0x200)?'1':'0',
344 (tlbelo & 0x080)?'1':'0',
345 (tlbelo & 0x001)?'1':'0',
346 (tlbelo & 0x002)?'1':'0');
347
348 return 0;
349}
350
351static struct seq_operations tlb_ops = {
352 .start = tlb_start,
353 .next = tlb_next,
354 .stop = tlb_stop,
355 .show = tlb_show,
356};
357
358static int tlb_open(struct inode *inode, struct file *file)
359{
360 return seq_open(file, &tlb_ops);
361}
362
363static struct file_operations proc_tlb_operations = {
364 .open = tlb_open,
365 .read = seq_read,
366 .llseek = seq_lseek,
367 .release = seq_release,
368};
369
370static int __init proctlb_init(void)
371{
372 struct proc_dir_entry *entry;
373
374 entry = create_proc_entry("tlb", 0, NULL);
375 if (entry)
376 entry->proc_fops = &proc_tlb_operations;
377 return 0;
378}
379late_initcall(proctlb_init);
380#endif /* CONFIG_PROC_FS */
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index a601a17cf568..f7b171b92ea2 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -27,7 +27,11 @@ config GENERIC_CALIBRATE_DELAY
27 27
28config GENERIC_HARDIRQS 28config GENERIC_HARDIRQS
29 bool 29 bool
30 default n 30 default y
31
32config GENERIC_HARDIRQS_NO__DO_IRQ
33 bool
34 default y
31 35
32config GENERIC_TIME 36config GENERIC_TIME
33 bool 37 bool
@@ -251,6 +255,12 @@ config MB93091_NO_MB
251endchoice 255endchoice
252endif 256endif
253 257
258config FUJITSU_MB93493
259 bool "MB93493 Multimedia chip"
260 help
261 Select this option if the MB93493 multimedia chip is going to be
262 used.
263
254choice 264choice
255 prompt "GP-Relative data support" 265 prompt "GP-Relative data support"
256 default GPREL_DATA_8 266 default GPREL_DATA_8
diff --git a/arch/frv/kernel/Makefile b/arch/frv/kernel/Makefile
index 5a827b349b5e..32db3499c461 100644
--- a/arch/frv/kernel/Makefile
+++ b/arch/frv/kernel/Makefile
@@ -10,15 +10,14 @@ extra-y:= head.o init_task.o vmlinux.lds
10obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \ 10obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \
11 process.o traps.o ptrace.o signal.o dma.o \ 11 process.o traps.o ptrace.o signal.o dma.o \
12 sys_frv.o time.o semaphore.o setup.o frv_ksyms.o \ 12 sys_frv.o time.o semaphore.o setup.o frv_ksyms.o \
13 debug-stub.o irq.o irq-routing.o sleep.o uaccess.o 13 debug-stub.o irq.o sleep.o uaccess.o
14 14
15obj-$(CONFIG_GDBSTUB) += gdb-stub.o gdb-io.o 15obj-$(CONFIG_GDBSTUB) += gdb-stub.o gdb-io.o
16 16
17obj-$(CONFIG_MB93091_VDK) += irq-mb93091.o 17obj-$(CONFIG_MB93091_VDK) += irq-mb93091.o
18obj-$(CONFIG_MB93093_PDK) += irq-mb93093.o
19obj-$(CONFIG_FUJITSU_MB93493) += irq-mb93493.o
20obj-$(CONFIG_PM) += pm.o cmode.o 18obj-$(CONFIG_PM) += pm.o cmode.o
21obj-$(CONFIG_MB93093_PDK) += pm-mb93093.o 19obj-$(CONFIG_MB93093_PDK) += pm-mb93093.o
20obj-$(CONFIG_FUJITSU_MB93493) += irq-mb93493.o
22obj-$(CONFIG_SYSCTL) += sysctl.o 21obj-$(CONFIG_SYSCTL) += sysctl.o
23obj-$(CONFIG_FUTEX) += futex.o 22obj-$(CONFIG_FUTEX) += futex.o
24obj-$(CONFIG_MODULES) += module.o 23obj-$(CONFIG_MODULES) += module.o
diff --git a/arch/frv/kernel/irq-mb93091.c b/arch/frv/kernel/irq-mb93091.c
index 1381abcd5cc9..369bc0a7443d 100644
--- a/arch/frv/kernel/irq-mb93091.c
+++ b/arch/frv/kernel/irq-mb93091.c
@@ -24,7 +24,6 @@
24#include <asm/delay.h> 24#include <asm/delay.h>
25#include <asm/irq.h> 25#include <asm/irq.h>
26#include <asm/irc-regs.h> 26#include <asm/irc-regs.h>
27#include <asm/irq-routing.h>
28 27
29#define __reg16(ADDR) (*(volatile unsigned short *)(ADDR)) 28#define __reg16(ADDR) (*(volatile unsigned short *)(ADDR))
30 29
@@ -33,83 +32,131 @@
33#define __get_IFR() ({ __reg16(0xffc0000c); }) 32#define __get_IFR() ({ __reg16(0xffc0000c); })
34#define __clr_IFR(M) do { __reg16(0xffc0000c) = ~(M); wmb(); } while(0) 33#define __clr_IFR(M) do { __reg16(0xffc0000c) = ~(M); wmb(); } while(0)
35 34
36static void frv_fpga_doirq(struct irq_source *source);
37static void frv_fpga_control(struct irq_group *group, int irq, int on);
38 35
39/*****************************************************************************/
40/* 36/*
41 * FPGA IRQ multiplexor 37 * on-motherboard FPGA PIC operations
42 */ 38 */
43static struct irq_source frv_fpga[4] = { 39static void frv_fpga_mask(unsigned int irq)
44#define __FPGA(X, M) \ 40{
45 [X] = { \ 41 uint16_t imr = __get_IMR();
46 .muxname = "fpga."#X, \
47 .irqmask = M, \
48 .doirq = frv_fpga_doirq, \
49 }
50 42
51 __FPGA(0, 0x0028), 43 imr |= 1 << (irq - IRQ_BASE_FPGA);
52 __FPGA(1, 0x0050),
53 __FPGA(2, 0x1c00),
54 __FPGA(3, 0x6386),
55};
56 44
57static struct irq_group frv_fpga_irqs = { 45 __set_IMR(imr);
58 .first_irq = IRQ_BASE_FPGA, 46}
59 .control = frv_fpga_control,
60 .sources = {
61 [ 1] = &frv_fpga[3],
62 [ 2] = &frv_fpga[3],
63 [ 3] = &frv_fpga[0],
64 [ 4] = &frv_fpga[1],
65 [ 5] = &frv_fpga[0],
66 [ 6] = &frv_fpga[1],
67 [ 7] = &frv_fpga[3],
68 [ 8] = &frv_fpga[3],
69 [ 9] = &frv_fpga[3],
70 [10] = &frv_fpga[2],
71 [11] = &frv_fpga[2],
72 [12] = &frv_fpga[2],
73 [13] = &frv_fpga[3],
74 [14] = &frv_fpga[3],
75 },
76};
77 47
48static void frv_fpga_ack(unsigned int irq)
49{
50 __clr_IFR(1 << (irq - IRQ_BASE_FPGA));
51}
78 52
79static void frv_fpga_control(struct irq_group *group, int index, int on) 53static void frv_fpga_mask_ack(unsigned int irq)
80{ 54{
81 uint16_t imr = __get_IMR(); 55 uint16_t imr = __get_IMR();
82 56
83 if (on) 57 imr |= 1 << (irq - IRQ_BASE_FPGA);
84 imr &= ~(1 << index); 58 __set_IMR(imr);
85 else 59
86 imr |= 1 << index; 60 __clr_IFR(1 << (irq - IRQ_BASE_FPGA));
61}
62
63static void frv_fpga_unmask(unsigned int irq)
64{
65 uint16_t imr = __get_IMR();
66
67 imr &= ~(1 << (irq - IRQ_BASE_FPGA));
87 68
88 __set_IMR(imr); 69 __set_IMR(imr);
89} 70}
90 71
91static void frv_fpga_doirq(struct irq_source *source) 72static struct irq_chip frv_fpga_pic = {
73 .name = "mb93091",
74 .ack = frv_fpga_ack,
75 .mask = frv_fpga_mask,
76 .mask_ack = frv_fpga_mask_ack,
77 .unmask = frv_fpga_unmask,
78};
79
80/*
81 * FPGA PIC interrupt handler
82 */
83static irqreturn_t fpga_interrupt(int irq, void *_mask, struct pt_regs *regs)
92{ 84{
93 uint16_t mask, imr; 85 uint16_t imr, mask = (unsigned long) _mask;
94 86
95 imr = __get_IMR(); 87 imr = __get_IMR();
96 mask = source->irqmask & ~imr & __get_IFR(); 88 mask = mask & ~imr & __get_IFR();
97 if (mask) { 89
98 __set_IMR(imr | mask); 90 /* poll all the triggered IRQs */
99 __clr_IFR(mask); 91 while (mask) {
100 distribute_irqs(&frv_fpga_irqs, mask); 92 int irq;
101 __set_IMR(imr); 93
94 asm("scan %1,gr0,%0" : "=r"(irq) : "r"(mask));
95 irq = 31 - irq;
96 mask &= ~(1 << irq);
97
98 generic_handle_irq(IRQ_BASE_FPGA + irq, regs);
102 } 99 }
100
101 return IRQ_HANDLED;
103} 102}
104 103
104/*
105 * define an interrupt action for each FPGA PIC output
106 * - use dev_id to indicate the FPGA PIC input to output mappings
107 */
108static struct irqaction fpga_irq[4] = {
109 [0] = {
110 .handler = fpga_interrupt,
111 .flags = IRQF_DISABLED | IRQF_SHARED,
112 .mask = CPU_MASK_NONE,
113 .name = "fpga.0",
114 .dev_id = (void *) 0x0028UL,
115 },
116 [1] = {
117 .handler = fpga_interrupt,
118 .flags = IRQF_DISABLED | IRQF_SHARED,
119 .mask = CPU_MASK_NONE,
120 .name = "fpga.1",
121 .dev_id = (void *) 0x0050UL,
122 },
123 [2] = {
124 .handler = fpga_interrupt,
125 .flags = IRQF_DISABLED | IRQF_SHARED,
126 .mask = CPU_MASK_NONE,
127 .name = "fpga.2",
128 .dev_id = (void *) 0x1c00UL,
129 },
130 [3] = {
131 .handler = fpga_interrupt,
132 .flags = IRQF_DISABLED | IRQF_SHARED,
133 .mask = CPU_MASK_NONE,
134 .name = "fpga.3",
135 .dev_id = (void *) 0x6386UL,
136 }
137};
138
139/*
140 * initialise the motherboard FPGA's PIC
141 */
105void __init fpga_init(void) 142void __init fpga_init(void)
106{ 143{
144 int irq;
145
146 /* all PIC inputs are all set to be low-level driven, apart from the
147 * NMI button (15) which is fixed at falling-edge
148 */
107 __set_IMR(0x7ffe); 149 __set_IMR(0x7ffe);
108 __clr_IFR(0x0000); 150 __clr_IFR(0x0000);
109 151
110 frv_irq_route_external(&frv_fpga[0], IRQ_CPU_EXTERNAL0); 152 for (irq = IRQ_BASE_FPGA + 1; irq <= IRQ_BASE_FPGA + 14; irq++)
111 frv_irq_route_external(&frv_fpga[1], IRQ_CPU_EXTERNAL1); 153 set_irq_chip_and_handler(irq, &frv_fpga_pic, handle_level_irq);
112 frv_irq_route_external(&frv_fpga[2], IRQ_CPU_EXTERNAL2); 154
113 frv_irq_route_external(&frv_fpga[3], IRQ_CPU_EXTERNAL3); 155 set_irq_chip_and_handler(IRQ_FPGA_NMI, &frv_fpga_pic, handle_edge_irq);
114 frv_irq_set_group(&frv_fpga_irqs); 156
157 /* the FPGA drives the first four external IRQ inputs on the CPU PIC */
158 setup_irq(IRQ_CPU_EXTERNAL0, &fpga_irq[0]);
159 setup_irq(IRQ_CPU_EXTERNAL1, &fpga_irq[1]);
160 setup_irq(IRQ_CPU_EXTERNAL2, &fpga_irq[2]);
161 setup_irq(IRQ_CPU_EXTERNAL3, &fpga_irq[3]);
115} 162}
diff --git a/arch/frv/kernel/irq-mb93093.c b/arch/frv/kernel/irq-mb93093.c
index 48b2a6420888..a43a22158956 100644
--- a/arch/frv/kernel/irq-mb93093.c
+++ b/arch/frv/kernel/irq-mb93093.c
@@ -1,6 +1,6 @@
1/* irq-mb93093.c: MB93093 FPGA interrupt handling 1/* irq-mb93093.c: MB93093 FPGA interrupt handling
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -24,7 +24,6 @@
24#include <asm/delay.h> 24#include <asm/delay.h>
25#include <asm/irq.h> 25#include <asm/irq.h>
26#include <asm/irc-regs.h> 26#include <asm/irc-regs.h>
27#include <asm/irq-routing.h>
28 27
29#define __reg16(ADDR) (*(volatile unsigned short *)(__region_CS2 + (ADDR))) 28#define __reg16(ADDR) (*(volatile unsigned short *)(__region_CS2 + (ADDR)))
30 29
@@ -33,66 +32,102 @@
33#define __get_IFR() ({ __reg16(0x02); }) 32#define __get_IFR() ({ __reg16(0x02); })
34#define __clr_IFR(M) do { __reg16(0x02) = ~(M); wmb(); } while(0) 33#define __clr_IFR(M) do { __reg16(0x02) = ~(M); wmb(); } while(0)
35 34
36static void frv_fpga_doirq(struct irq_source *source);
37static void frv_fpga_control(struct irq_group *group, int irq, int on);
38
39/*****************************************************************************/
40/* 35/*
41 * FPGA IRQ multiplexor 36 * off-CPU FPGA PIC operations
42 */ 37 */
43static struct irq_source frv_fpga[4] = { 38static void frv_fpga_mask(unsigned int irq)
44#define __FPGA(X, M) \ 39{
45 [X] = { \ 40 uint16_t imr = __get_IMR();
46 .muxname = "fpga."#X, \
47 .irqmask = M, \
48 .doirq = frv_fpga_doirq, \
49 }
50 41
51 __FPGA(0, 0x0700), 42 imr |= 1 << (irq - IRQ_BASE_FPGA);
52}; 43 __set_IMR(imr);
44}
53 45
54static struct irq_group frv_fpga_irqs = { 46static void frv_fpga_ack(unsigned int irq)
55 .first_irq = IRQ_BASE_FPGA, 47{
56 .control = frv_fpga_control, 48 __clr_IFR(1 << (irq - IRQ_BASE_FPGA));
57 .sources = { 49}
58 [ 8] = &frv_fpga[0], 50
59 [ 9] = &frv_fpga[0], 51static void frv_fpga_mask_ack(unsigned int irq)
60 [10] = &frv_fpga[0], 52{
61 }, 53 uint16_t imr = __get_IMR();
62};
63 54
55 imr |= 1 << (irq - IRQ_BASE_FPGA);
56 __set_IMR(imr);
57
58 __clr_IFR(1 << (irq - IRQ_BASE_FPGA));
59}
64 60
65static void frv_fpga_control(struct irq_group *group, int index, int on) 61static void frv_fpga_unmask(unsigned int irq)
66{ 62{
67 uint16_t imr = __get_IMR(); 63 uint16_t imr = __get_IMR();
68 64
69 if (on) 65 imr &= ~(1 << (irq - IRQ_BASE_FPGA));
70 imr &= ~(1 << index);
71 else
72 imr |= 1 << index;
73 66
74 __set_IMR(imr); 67 __set_IMR(imr);
75} 68}
76 69
77static void frv_fpga_doirq(struct irq_source *source) 70static struct irq_chip frv_fpga_pic = {
71 .name = "mb93093",
72 .ack = frv_fpga_ack,
73 .mask = frv_fpga_mask,
74 .mask_ack = frv_fpga_mask_ack,
75 .unmask = frv_fpga_unmask,
76 .end = frv_fpga_end,
77};
78
79/*
80 * FPGA PIC interrupt handler
81 */
82static irqreturn_t fpga_interrupt(int irq, void *_mask, struct pt_regs *regs)
78{ 83{
79 uint16_t mask, imr; 84 uint16_t imr, mask = (unsigned long) _mask;
80 85
81 imr = __get_IMR(); 86 imr = __get_IMR();
82 mask = source->irqmask & ~imr & __get_IFR(); 87 mask = mask & ~imr & __get_IFR();
83 if (mask) { 88
84 __set_IMR(imr | mask); 89 /* poll all the triggered IRQs */
85 __clr_IFR(mask); 90 while (mask) {
86 distribute_irqs(&frv_fpga_irqs, mask); 91 int irq;
87 __set_IMR(imr); 92
93 asm("scan %1,gr0,%0" : "=r"(irq) : "r"(mask));
94 irq = 31 - irq;
95 mask &= ~(1 << irq);
96
97 generic_irq_handle(IRQ_BASE_FPGA + irq, regs);
88 } 98 }
99
100 return IRQ_HANDLED;
89} 101}
90 102
103/*
104 * define an interrupt action for each FPGA PIC output
105 * - use dev_id to indicate the FPGA PIC input to output mappings
106 */
107static struct irqaction fpga_irq[1] = {
108 [0] = {
109 .handler = fpga_interrupt,
110 .flags = IRQF_DISABLED,
111 .mask = CPU_MASK_NONE,
112 .name = "fpga.0",
113 .dev_id = (void *) 0x0700UL,
114 }
115};
116
117/*
118 * initialise the motherboard FPGA's PIC
119 */
91void __init fpga_init(void) 120void __init fpga_init(void)
92{ 121{
122 int irq;
123
124 /* all PIC inputs are all set to be edge triggered */
93 __set_IMR(0x0700); 125 __set_IMR(0x0700);
94 __clr_IFR(0x0000); 126 __clr_IFR(0x0000);
95 127
96 frv_irq_route_external(&frv_fpga[0], IRQ_CPU_EXTERNAL2); 128 for (irq = IRQ_BASE_FPGA + 8; irq <= IRQ_BASE_FPGA + 10; irq++)
97 frv_irq_set_group(&frv_fpga_irqs); 129 set_irq_chip_and_handler(irq, &frv_fpga_pic, handle_edge_irq);
130
131 /* the FPGA drives external IRQ input #2 on the CPU PIC */
132 setup_irq(IRQ_CPU_EXTERNAL2, &fpga_irq[0]);
98} 133}
diff --git a/arch/frv/kernel/irq-mb93493.c b/arch/frv/kernel/irq-mb93493.c
index 988d035640e1..39c0188a3498 100644
--- a/arch/frv/kernel/irq-mb93493.c
+++ b/arch/frv/kernel/irq-mb93493.c
@@ -1,6 +1,6 @@
1/* irq-mb93493.c: MB93493 companion chip interrupt handler 1/* irq-mb93493.c: MB93493 companion chip interrupt handler
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -24,84 +24,126 @@
24#include <asm/delay.h> 24#include <asm/delay.h>
25#include <asm/irq.h> 25#include <asm/irq.h>
26#include <asm/irc-regs.h> 26#include <asm/irc-regs.h>
27#include <asm/irq-routing.h>
28#include <asm/mb93493-irqs.h> 27#include <asm/mb93493-irqs.h>
28#include <asm/mb93493-regs.h>
29 29
30static void frv_mb93493_doirq(struct irq_source *source); 30#define IRQ_ROUTE_ONE(X) (X##_ROUTE << (X - IRQ_BASE_MB93493))
31
32#define IRQ_ROUTING \
33 (IRQ_ROUTE_ONE(IRQ_MB93493_VDC) | \
34 IRQ_ROUTE_ONE(IRQ_MB93493_VCC) | \
35 IRQ_ROUTE_ONE(IRQ_MB93493_AUDIO_OUT) | \
36 IRQ_ROUTE_ONE(IRQ_MB93493_I2C_0) | \
37 IRQ_ROUTE_ONE(IRQ_MB93493_I2C_1) | \
38 IRQ_ROUTE_ONE(IRQ_MB93493_USB) | \
39 IRQ_ROUTE_ONE(IRQ_MB93493_LOCAL_BUS) | \
40 IRQ_ROUTE_ONE(IRQ_MB93493_PCMCIA) | \
41 IRQ_ROUTE_ONE(IRQ_MB93493_GPIO) | \
42 IRQ_ROUTE_ONE(IRQ_MB93493_AUDIO_IN))
31 43
32/*****************************************************************************/
33/* 44/*
34 * MB93493 companion chip IRQ multiplexor 45 * daughter board PIC operations
46 * - there is no way to ACK interrupts in the MB93493 chip
35 */ 47 */
36static struct irq_source frv_mb93493[2] = { 48static void frv_mb93493_mask(unsigned int irq)
37 [0] = {
38 .muxname = "mb93493.0",
39 .muxdata = __region_CS3 + 0x3d0,
40 .doirq = frv_mb93493_doirq,
41 .irqmask = 0x0000,
42 },
43 [1] = {
44 .muxname = "mb93493.1",
45 .muxdata = __region_CS3 + 0x3d4,
46 .doirq = frv_mb93493_doirq,
47 .irqmask = 0x0000,
48 },
49};
50
51static void frv_mb93493_control(struct irq_group *group, int index, int on)
52{ 49{
53 struct irq_source *source;
54 uint32_t iqsr; 50 uint32_t iqsr;
51 volatile void *piqsr;
55 52
56 if ((frv_mb93493[0].irqmask & (1 << index))) 53 if (IRQ_ROUTING & (1 << (irq - IRQ_BASE_MB93493)))
57 source = &frv_mb93493[0]; 54 piqsr = __addr_MB93493_IQSR(1);
58 else 55 else
59 source = &frv_mb93493[1]; 56 piqsr = __addr_MB93493_IQSR(0);
57
58 iqsr = readl(piqsr);
59 iqsr &= ~(1 << (irq - IRQ_BASE_MB93493 + 16));
60 writel(iqsr, piqsr);
61}
60 62
61 iqsr = readl(source->muxdata); 63static void frv_mb93493_ack(unsigned int irq)
62 if (on) 64{
63 iqsr |= 1 << (index + 16); 65}
66
67static void frv_mb93493_unmask(unsigned int irq)
68{
69 uint32_t iqsr;
70 volatile void *piqsr;
71
72 if (IRQ_ROUTING & (1 << (irq - IRQ_BASE_MB93493)))
73 piqsr = __addr_MB93493_IQSR(1);
64 else 74 else
65 iqsr &= ~(1 << (index + 16)); 75 piqsr = __addr_MB93493_IQSR(0);
66 76
67 writel(iqsr, source->muxdata); 77 iqsr = readl(piqsr);
78 iqsr |= 1 << (irq - IRQ_BASE_MB93493 + 16);
79 writel(iqsr, piqsr);
68} 80}
69 81
70static struct irq_group frv_mb93493_irqs = { 82static struct irq_chip frv_mb93493_pic = {
71 .first_irq = IRQ_BASE_MB93493, 83 .name = "mb93093",
72 .control = frv_mb93493_control, 84 .ack = frv_mb93493_ack,
85 .mask = frv_mb93493_mask,
86 .mask_ack = frv_mb93493_mask,
87 .unmask = frv_mb93493_unmask,
73}; 88};
74 89
75static void frv_mb93493_doirq(struct irq_source *source) 90/*
91 * MB93493 PIC interrupt handler
92 */
93static irqreturn_t mb93493_interrupt(int irq, void *_piqsr, struct pt_regs *regs)
76{ 94{
77 uint32_t mask = readl(source->muxdata); 95 volatile void *piqsr = _piqsr;
78 mask = mask & (mask >> 16) & 0xffff; 96 uint32_t iqsr;
79 97
80 if (mask) 98 iqsr = readl(piqsr);
81 distribute_irqs(&frv_mb93493_irqs, mask); 99 iqsr = iqsr & (iqsr >> 16) & 0xffff;
82}
83 100
84static void __init mb93493_irq_route(int irq, int source) 101 /* poll all the triggered IRQs */
85{ 102 while (iqsr) {
86 frv_mb93493[source].irqmask |= 1 << (irq - IRQ_BASE_MB93493); 103 int irq;
87 frv_mb93493_irqs.sources[irq - IRQ_BASE_MB93493] = &frv_mb93493[source]; 104
105 asm("scan %1,gr0,%0" : "=r"(irq) : "r"(iqsr));
106 irq = 31 - irq;
107 iqsr &= ~(1 << irq);
108
109 generic_handle_irq(IRQ_BASE_MB93493 + irq, regs);
110 }
111
112 return IRQ_HANDLED;
88} 113}
89 114
90void __init route_mb93493_irqs(void) 115/*
116 * define an interrupt action for each MB93493 PIC output
117 * - use dev_id to indicate the MB93493 PIC input to output mappings
118 */
119static struct irqaction mb93493_irq[2] = {
120 [0] = {
121 .handler = mb93493_interrupt,
122 .flags = IRQF_DISABLED | IRQF_SHARED,
123 .mask = CPU_MASK_NONE,
124 .name = "mb93493.0",
125 .dev_id = (void *) __addr_MB93493_IQSR(0),
126 },
127 [1] = {
128 .handler = mb93493_interrupt,
129 .flags = IRQF_DISABLED | IRQF_SHARED,
130 .mask = CPU_MASK_NONE,
131 .name = "mb93493.1",
132 .dev_id = (void *) __addr_MB93493_IQSR(1),
133 }
134};
135
136/*
137 * initialise the motherboard MB93493's PIC
138 */
139void __init mb93493_init(void)
91{ 140{
92 frv_irq_route_external(&frv_mb93493[0], IRQ_CPU_MB93493_0); 141 int irq;
93 frv_irq_route_external(&frv_mb93493[1], IRQ_CPU_MB93493_1); 142
94 143 for (irq = IRQ_BASE_MB93493 + 0; irq <= IRQ_BASE_MB93493 + 10; irq++)
95 frv_irq_set_group(&frv_mb93493_irqs); 144 set_irq_chip_and_handler(irq, &frv_mb93493_pic, handle_edge_irq);
96 145
97 mb93493_irq_route(IRQ_MB93493_VDC, IRQ_MB93493_VDC_ROUTE); 146 /* the MB93493 drives external IRQ inputs on the CPU PIC */
98 mb93493_irq_route(IRQ_MB93493_VCC, IRQ_MB93493_VCC_ROUTE); 147 setup_irq(IRQ_CPU_MB93493_0, &mb93493_irq[0]);
99 mb93493_irq_route(IRQ_MB93493_AUDIO_IN, IRQ_MB93493_AUDIO_IN_ROUTE); 148 setup_irq(IRQ_CPU_MB93493_1, &mb93493_irq[1]);
100 mb93493_irq_route(IRQ_MB93493_I2C_0, IRQ_MB93493_I2C_0_ROUTE);
101 mb93493_irq_route(IRQ_MB93493_I2C_1, IRQ_MB93493_I2C_1_ROUTE);
102 mb93493_irq_route(IRQ_MB93493_USB, IRQ_MB93493_USB_ROUTE);
103 mb93493_irq_route(IRQ_MB93493_LOCAL_BUS, IRQ_MB93493_LOCAL_BUS_ROUTE);
104 mb93493_irq_route(IRQ_MB93493_PCMCIA, IRQ_MB93493_PCMCIA_ROUTE);
105 mb93493_irq_route(IRQ_MB93493_GPIO, IRQ_MB93493_GPIO_ROUTE);
106 mb93493_irq_route(IRQ_MB93493_AUDIO_OUT, IRQ_MB93493_AUDIO_OUT_ROUTE);
107} 149}
diff --git a/arch/frv/kernel/irq-routing.c b/arch/frv/kernel/irq-routing.c
deleted file mode 100644
index 53886adf47de..000000000000
--- a/arch/frv/kernel/irq-routing.c
+++ /dev/null
@@ -1,291 +0,0 @@
1/* irq-routing.c: IRQ routing
2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/sched.h>
13#include <linux/random.h>
14#include <linux/init.h>
15#include <linux/serial_reg.h>
16#include <asm/io.h>
17#include <asm/irq-routing.h>
18#include <asm/irc-regs.h>
19#include <asm/serial-regs.h>
20#include <asm/dma.h>
21
22struct irq_level frv_irq_levels[16] = {
23 [0 ... 15] = {
24 .lock = SPIN_LOCK_UNLOCKED,
25 }
26};
27
28struct irq_group *irq_groups[NR_IRQ_GROUPS];
29
30extern struct irq_group frv_cpu_irqs;
31
32void __init frv_irq_route(struct irq_source *source, int irqlevel)
33{
34 source->level = &frv_irq_levels[irqlevel];
35 source->next = frv_irq_levels[irqlevel].sources;
36 frv_irq_levels[irqlevel].sources = source;
37}
38
39void __init frv_irq_route_external(struct irq_source *source, int irq)
40{
41 int irqlevel = 0;
42
43 switch (irq) {
44 case IRQ_CPU_EXTERNAL0: irqlevel = IRQ_XIRQ0_LEVEL; break;
45 case IRQ_CPU_EXTERNAL1: irqlevel = IRQ_XIRQ1_LEVEL; break;
46 case IRQ_CPU_EXTERNAL2: irqlevel = IRQ_XIRQ2_LEVEL; break;
47 case IRQ_CPU_EXTERNAL3: irqlevel = IRQ_XIRQ3_LEVEL; break;
48 case IRQ_CPU_EXTERNAL4: irqlevel = IRQ_XIRQ4_LEVEL; break;
49 case IRQ_CPU_EXTERNAL5: irqlevel = IRQ_XIRQ5_LEVEL; break;
50 case IRQ_CPU_EXTERNAL6: irqlevel = IRQ_XIRQ6_LEVEL; break;
51 case IRQ_CPU_EXTERNAL7: irqlevel = IRQ_XIRQ7_LEVEL; break;
52 default: BUG();
53 }
54
55 source->level = &frv_irq_levels[irqlevel];
56 source->next = frv_irq_levels[irqlevel].sources;
57 frv_irq_levels[irqlevel].sources = source;
58}
59
60void __init frv_irq_set_group(struct irq_group *group)
61{
62 irq_groups[group->first_irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP] = group;
63}
64
65void distribute_irqs(struct irq_group *group, unsigned long irqmask)
66{
67 struct irqaction *action;
68 int irq;
69
70 while (irqmask) {
71 asm("scan %1,gr0,%0" : "=r"(irq) : "r"(irqmask));
72 if (irq < 0 || irq > 31)
73 asm volatile("break");
74 irq = 31 - irq;
75
76 irqmask &= ~(1 << irq);
77 action = group->actions[irq];
78
79 irq += group->first_irq;
80
81 if (action) {
82 int status = 0;
83
84// if (!(action->flags & IRQF_DISABLED))
85// local_irq_enable();
86
87 do {
88 status |= action->flags;
89 action->handler(irq, action->dev_id, __frame);
90 action = action->next;
91 } while (action);
92
93 if (status & IRQF_SAMPLE_RANDOM)
94 add_interrupt_randomness(irq);
95 local_irq_disable();
96 }
97 }
98}
99
100/*****************************************************************************/
101/*
102 * CPU UART interrupts
103 */
104static void frv_cpuuart_doirq(struct irq_source *source)
105{
106// uint8_t iir = readb(source->muxdata + UART_IIR * 8);
107// if ((iir & 0x0f) != UART_IIR_NO_INT)
108 distribute_irqs(&frv_cpu_irqs, source->irqmask);
109}
110
111struct irq_source frv_cpuuart[2] = {
112#define __CPUUART(X, A) \
113 [X] = { \
114 .muxname = "uart", \
115 .muxdata = (volatile void __iomem *)(unsigned long)A,\
116 .irqmask = 1 << IRQ_CPU_UART##X, \
117 .doirq = frv_cpuuart_doirq, \
118 }
119
120 __CPUUART(0, UART0_BASE),
121 __CPUUART(1, UART1_BASE),
122};
123
124/*****************************************************************************/
125/*
126 * CPU DMA interrupts
127 */
128static void frv_cpudma_doirq(struct irq_source *source)
129{
130 uint32_t cstr = readl(source->muxdata + DMAC_CSTRx);
131 if (cstr & DMAC_CSTRx_INT)
132 distribute_irqs(&frv_cpu_irqs, source->irqmask);
133}
134
135struct irq_source frv_cpudma[8] = {
136#define __CPUDMA(X, A) \
137 [X] = { \
138 .muxname = "dma", \
139 .muxdata = (volatile void __iomem *)(unsigned long)A,\
140 .irqmask = 1 << IRQ_CPU_DMA##X, \
141 .doirq = frv_cpudma_doirq, \
142 }
143
144 __CPUDMA(0, 0xfe000900),
145 __CPUDMA(1, 0xfe000980),
146 __CPUDMA(2, 0xfe000a00),
147 __CPUDMA(3, 0xfe000a80),
148 __CPUDMA(4, 0xfe001000),
149 __CPUDMA(5, 0xfe001080),
150 __CPUDMA(6, 0xfe001100),
151 __CPUDMA(7, 0xfe001180),
152};
153
154/*****************************************************************************/
155/*
156 * CPU timer interrupts - can't tell whether they've generated an interrupt or not
157 */
158static void frv_cputimer_doirq(struct irq_source *source)
159{
160 distribute_irqs(&frv_cpu_irqs, source->irqmask);
161}
162
163struct irq_source frv_cputimer[3] = {
164#define __CPUTIMER(X) \
165 [X] = { \
166 .muxname = "timer", \
167 .muxdata = NULL, \
168 .irqmask = 1 << IRQ_CPU_TIMER##X, \
169 .doirq = frv_cputimer_doirq, \
170 }
171
172 __CPUTIMER(0),
173 __CPUTIMER(1),
174 __CPUTIMER(2),
175};
176
177/*****************************************************************************/
178/*
179 * external CPU interrupts - can't tell directly whether they've generated an interrupt or not
180 */
181static void frv_cpuexternal_doirq(struct irq_source *source)
182{
183 distribute_irqs(&frv_cpu_irqs, source->irqmask);
184}
185
186struct irq_source frv_cpuexternal[8] = {
187#define __CPUEXTERNAL(X) \
188 [X] = { \
189 .muxname = "ext", \
190 .muxdata = NULL, \
191 .irqmask = 1 << IRQ_CPU_EXTERNAL##X, \
192 .doirq = frv_cpuexternal_doirq, \
193 }
194
195 __CPUEXTERNAL(0),
196 __CPUEXTERNAL(1),
197 __CPUEXTERNAL(2),
198 __CPUEXTERNAL(3),
199 __CPUEXTERNAL(4),
200 __CPUEXTERNAL(5),
201 __CPUEXTERNAL(6),
202 __CPUEXTERNAL(7),
203};
204
205#define set_IRR(N,A,B,C,D) __set_IRR(N, (A << 28) | (B << 24) | (C << 20) | (D << 16))
206
207struct irq_group frv_cpu_irqs = {
208 .sources = {
209 [IRQ_CPU_UART0] = &frv_cpuuart[0],
210 [IRQ_CPU_UART1] = &frv_cpuuart[1],
211 [IRQ_CPU_TIMER0] = &frv_cputimer[0],
212 [IRQ_CPU_TIMER1] = &frv_cputimer[1],
213 [IRQ_CPU_TIMER2] = &frv_cputimer[2],
214 [IRQ_CPU_DMA0] = &frv_cpudma[0],
215 [IRQ_CPU_DMA1] = &frv_cpudma[1],
216 [IRQ_CPU_DMA2] = &frv_cpudma[2],
217 [IRQ_CPU_DMA3] = &frv_cpudma[3],
218 [IRQ_CPU_DMA4] = &frv_cpudma[4],
219 [IRQ_CPU_DMA5] = &frv_cpudma[5],
220 [IRQ_CPU_DMA6] = &frv_cpudma[6],
221 [IRQ_CPU_DMA7] = &frv_cpudma[7],
222 [IRQ_CPU_EXTERNAL0] = &frv_cpuexternal[0],
223 [IRQ_CPU_EXTERNAL1] = &frv_cpuexternal[1],
224 [IRQ_CPU_EXTERNAL2] = &frv_cpuexternal[2],
225 [IRQ_CPU_EXTERNAL3] = &frv_cpuexternal[3],
226 [IRQ_CPU_EXTERNAL4] = &frv_cpuexternal[4],
227 [IRQ_CPU_EXTERNAL5] = &frv_cpuexternal[5],
228 [IRQ_CPU_EXTERNAL6] = &frv_cpuexternal[6],
229 [IRQ_CPU_EXTERNAL7] = &frv_cpuexternal[7],
230 },
231};
232
233/*****************************************************************************/
234/*
235 * route the CPU's interrupt sources
236 */
237void __init route_cpu_irqs(void)
238{
239 frv_irq_set_group(&frv_cpu_irqs);
240
241 __set_IITMR(0, 0x003f0000); /* DMA0-3, TIMER0-2 IRQ detect levels */
242 __set_IITMR(1, 0x20000000); /* ERR0-1, UART0-1, DMA4-7 IRQ detect levels */
243
244 /* route UART and error interrupts */
245 frv_irq_route(&frv_cpuuart[0], IRQ_UART0_LEVEL);
246 frv_irq_route(&frv_cpuuart[1], IRQ_UART1_LEVEL);
247
248 set_IRR(6, IRQ_GDBSTUB_LEVEL, IRQ_GDBSTUB_LEVEL, IRQ_UART1_LEVEL, IRQ_UART0_LEVEL);
249
250 /* route DMA channel interrupts */
251 frv_irq_route(&frv_cpudma[0], IRQ_DMA0_LEVEL);
252 frv_irq_route(&frv_cpudma[1], IRQ_DMA1_LEVEL);
253 frv_irq_route(&frv_cpudma[2], IRQ_DMA2_LEVEL);
254 frv_irq_route(&frv_cpudma[3], IRQ_DMA3_LEVEL);
255 frv_irq_route(&frv_cpudma[4], IRQ_DMA4_LEVEL);
256 frv_irq_route(&frv_cpudma[5], IRQ_DMA5_LEVEL);
257 frv_irq_route(&frv_cpudma[6], IRQ_DMA6_LEVEL);
258 frv_irq_route(&frv_cpudma[7], IRQ_DMA7_LEVEL);
259
260 set_IRR(4, IRQ_DMA3_LEVEL, IRQ_DMA2_LEVEL, IRQ_DMA1_LEVEL, IRQ_DMA0_LEVEL);
261 set_IRR(7, IRQ_DMA7_LEVEL, IRQ_DMA6_LEVEL, IRQ_DMA5_LEVEL, IRQ_DMA4_LEVEL);
262
263 /* route timer interrupts */
264 frv_irq_route(&frv_cputimer[0], IRQ_TIMER0_LEVEL);
265 frv_irq_route(&frv_cputimer[1], IRQ_TIMER1_LEVEL);
266 frv_irq_route(&frv_cputimer[2], IRQ_TIMER2_LEVEL);
267
268 set_IRR(5, 0, IRQ_TIMER2_LEVEL, IRQ_TIMER1_LEVEL, IRQ_TIMER0_LEVEL);
269
270 /* route external interrupts */
271 frv_irq_route(&frv_cpuexternal[0], IRQ_XIRQ0_LEVEL);
272 frv_irq_route(&frv_cpuexternal[1], IRQ_XIRQ1_LEVEL);
273 frv_irq_route(&frv_cpuexternal[2], IRQ_XIRQ2_LEVEL);
274 frv_irq_route(&frv_cpuexternal[3], IRQ_XIRQ3_LEVEL);
275 frv_irq_route(&frv_cpuexternal[4], IRQ_XIRQ4_LEVEL);
276 frv_irq_route(&frv_cpuexternal[5], IRQ_XIRQ5_LEVEL);
277 frv_irq_route(&frv_cpuexternal[6], IRQ_XIRQ6_LEVEL);
278 frv_irq_route(&frv_cpuexternal[7], IRQ_XIRQ7_LEVEL);
279
280 set_IRR(2, IRQ_XIRQ7_LEVEL, IRQ_XIRQ6_LEVEL, IRQ_XIRQ5_LEVEL, IRQ_XIRQ4_LEVEL);
281 set_IRR(3, IRQ_XIRQ3_LEVEL, IRQ_XIRQ2_LEVEL, IRQ_XIRQ1_LEVEL, IRQ_XIRQ0_LEVEL);
282
283#if defined(CONFIG_MB93091_VDK)
284 __set_TM1(0x55550000); /* XIRQ7-0 all active low */
285#elif defined(CONFIG_MB93093_PDK)
286 __set_TM1(0x15550000); /* XIRQ7 active high, 6-0 all active low */
287#else
288#error dont know external IRQ trigger levels for this setup
289#endif
290
291} /* end route_cpu_irqs() */
diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c
index 08967010be04..5ac041c7c0a4 100644
--- a/arch/frv/kernel/irq.c
+++ b/arch/frv/kernel/irq.c
@@ -1,6 +1,6 @@
1/* irq.c: FRV IRQ handling 1/* irq.c: FRV IRQ handling
2 * 2 *
3 * Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2003, 2004, 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -9,13 +9,6 @@
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 */ 10 */
11 11
12/*
13 * (mostly architecture independent, will move to kernel/irq.c in 2.5.)
14 *
15 * IRQs are in fact implemented a bit like signal handlers for the kernel.
16 * Naturally it's not a 1:1 relation, but there are similarities.
17 */
18
19#include <linux/ptrace.h> 12#include <linux/ptrace.h>
20#include <linux/errno.h> 13#include <linux/errno.h>
21#include <linux/signal.h> 14#include <linux/signal.h>
@@ -43,19 +36,16 @@
43#include <asm/delay.h> 36#include <asm/delay.h>
44#include <asm/irq.h> 37#include <asm/irq.h>
45#include <asm/irc-regs.h> 38#include <asm/irc-regs.h>
46#include <asm/irq-routing.h>
47#include <asm/gdb-stub.h> 39#include <asm/gdb-stub.h>
48 40
49extern void __init fpga_init(void); 41#define set_IRR(N,A,B,C,D) __set_IRR(N, (A << 28) | (B << 24) | (C << 20) | (D << 16))
50extern void __init route_mb93493_irqs(void);
51
52static void register_irq_proc (unsigned int irq);
53 42
54/* 43extern void __init fpga_init(void);
55 * Special irq handlers. 44#ifdef CONFIG_FUJITSU_MB93493
56 */ 45extern void __init mb93493_init(void);
46#endif
57 47
58irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs) { return IRQ_HANDLED; } 48#define __reg16(ADDR) (*(volatile unsigned short *)(ADDR))
59 49
60atomic_t irq_err_count; 50atomic_t irq_err_count;
61 51
@@ -64,215 +54,86 @@ atomic_t irq_err_count;
64 */ 54 */
65int show_interrupts(struct seq_file *p, void *v) 55int show_interrupts(struct seq_file *p, void *v)
66{ 56{
67 struct irqaction *action; 57 int i = *(loff_t *) v, cpu;
68 struct irq_group *group; 58 struct irqaction * action;
69 unsigned long flags; 59 unsigned long flags;
70 int level, grp, ix, i, j;
71
72 i = *(loff_t *) v;
73
74 switch (i) {
75 case 0:
76 seq_printf(p, " ");
77 for_each_online_cpu(j)
78 seq_printf(p, "CPU%d ",j);
79
80 seq_putc(p, '\n');
81 break;
82 60
83 case 1 ... NR_IRQ_GROUPS * NR_IRQ_ACTIONS_PER_GROUP: 61 if (i == 0) {
84 local_irq_save(flags); 62 char cpuname[12];
85
86 grp = (i - 1) / NR_IRQ_ACTIONS_PER_GROUP;
87 group = irq_groups[grp];
88 if (!group)
89 goto skip;
90
91 ix = (i - 1) % NR_IRQ_ACTIONS_PER_GROUP;
92 action = group->actions[ix];
93 if (!action)
94 goto skip;
95
96 seq_printf(p, "%3d: ", i - 1);
97
98#ifndef CONFIG_SMP
99 seq_printf(p, "%10u ", kstat_irqs(i));
100#else
101 for_each_online_cpu(j)
102 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i - 1]);
103#endif
104
105 level = group->sources[ix]->level - frv_irq_levels;
106
107 seq_printf(p, " %12s@%x", group->sources[ix]->muxname, level);
108 seq_printf(p, " %s", action->name);
109
110 for (action = action->next; action; action = action->next)
111 seq_printf(p, ", %s", action->name);
112 63
64 seq_printf(p, " ");
65 for_each_present_cpu(cpu) {
66 sprintf(cpuname, "CPU%d", cpu);
67 seq_printf(p, " %10s", cpuname);
68 }
113 seq_putc(p, '\n'); 69 seq_putc(p, '\n');
114skip: 70 }
115 local_irq_restore(flags);
116 break;
117 71
118 case NR_IRQ_GROUPS * NR_IRQ_ACTIONS_PER_GROUP + 1: 72 if (i < NR_IRQS) {
119 seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); 73 spin_lock_irqsave(&irq_desc[i].lock, flags);
120 break; 74 action = irq_desc[i].action;
75 if (action) {
76 seq_printf(p, "%3d: ", i);
77 for_each_present_cpu(cpu)
78 seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
79 seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
80 seq_printf(p, " %s", action->name);
81 for (action = action->next;
82 action;
83 action = action->next)
84 seq_printf(p, ", %s", action->name);
85
86 seq_putc(p, '\n');
87 }
121 88
122 default: 89 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
123 break; 90 } else if (i == NR_IRQS) {
91 seq_printf(p, "Err: %10u\n", atomic_read(&irq_err_count));
124 } 92 }
125 93
126 return 0; 94 return 0;
127} 95}
128 96
129
130/* 97/*
131 * Generic enable/disable code: this just calls 98 * on-CPU PIC operations
132 * down into the PIC-specific version for the actual
133 * hardware disable after having gotten the irq
134 * controller lock.
135 */ 99 */
136 100static void frv_cpupic_ack(unsigned int irqlevel)
137/**
138 * disable_irq_nosync - disable an irq without waiting
139 * @irq: Interrupt to disable
140 *
141 * Disable the selected interrupt line. Disables and Enables are
142 * nested.
143 * Unlike disable_irq(), this function does not ensure existing
144 * instances of the IRQ handler have completed before returning.
145 *
146 * This function may be called from IRQ context.
147 */
148
149void disable_irq_nosync(unsigned int irq)
150{ 101{
151 struct irq_source *source; 102 __clr_RC(irqlevel);
152 struct irq_group *group; 103 __clr_IRL();
153 struct irq_level *level;
154 unsigned long flags;
155 int idx = irq & (NR_IRQ_ACTIONS_PER_GROUP - 1);
156
157 group = irq_groups[irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP];
158 if (!group)
159 BUG();
160
161 source = group->sources[idx];
162 if (!source)
163 BUG();
164
165 level = source->level;
166
167 spin_lock_irqsave(&level->lock, flags);
168
169 if (group->control) {
170 if (!group->disable_cnt[idx]++)
171 group->control(group, idx, 0);
172 } else if (!level->disable_count++) {
173 __set_MASK(level - frv_irq_levels);
174 }
175
176 spin_unlock_irqrestore(&level->lock, flags);
177} 104}
178 105
179EXPORT_SYMBOL(disable_irq_nosync); 106static void frv_cpupic_mask(unsigned int irqlevel)
180
181/**
182 * disable_irq - disable an irq and wait for completion
183 * @irq: Interrupt to disable
184 *
185 * Disable the selected interrupt line. Enables and Disables are
186 * nested.
187 * This function waits for any pending IRQ handlers for this interrupt
188 * to complete before returning. If you use this function while
189 * holding a resource the IRQ handler may need you will deadlock.
190 *
191 * This function may be called - with care - from IRQ context.
192 */
193
194void disable_irq(unsigned int irq)
195{ 107{
196 disable_irq_nosync(irq); 108 __set_MASK(irqlevel);
197
198#ifdef CONFIG_SMP
199 if (!local_irq_count(smp_processor_id())) {
200 do {
201 barrier();
202 } while (irq_desc[irq].status & IRQ_INPROGRESS);
203 }
204#endif
205} 109}
206 110
207EXPORT_SYMBOL(disable_irq); 111static void frv_cpupic_mask_ack(unsigned int irqlevel)
208
209/**
210 * enable_irq - enable handling of an irq
211 * @irq: Interrupt to enable
212 *
213 * Undoes the effect of one call to disable_irq(). If this
214 * matches the last disable, processing of interrupts on this
215 * IRQ line is re-enabled.
216 *
217 * This function may be called from IRQ context.
218 */
219
220void enable_irq(unsigned int irq)
221{ 112{
222 struct irq_source *source; 113 __set_MASK(irqlevel);
223 struct irq_group *group; 114 __clr_RC(irqlevel);
224 struct irq_level *level; 115 __clr_IRL();
225 unsigned long flags; 116}
226 int idx = irq & (NR_IRQ_ACTIONS_PER_GROUP - 1);
227 int count;
228
229 group = irq_groups[irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP];
230 if (!group)
231 BUG();
232
233 source = group->sources[idx];
234 if (!source)
235 BUG();
236
237 level = source->level;
238
239 spin_lock_irqsave(&level->lock, flags);
240
241 if (group->control)
242 count = group->disable_cnt[idx];
243 else
244 count = level->disable_count;
245
246 switch (count) {
247 case 1:
248 if (group->control) {
249 if (group->actions[idx])
250 group->control(group, idx, 1);
251 } else {
252 if (level->usage)
253 __clr_MASK(level - frv_irq_levels);
254 }
255 /* fall-through */
256
257 default:
258 count--;
259 break;
260
261 case 0:
262 printk("enable_irq(%u) unbalanced from %p\n", irq, __builtin_return_address(0));
263 }
264 117
265 if (group->control) 118static void frv_cpupic_unmask(unsigned int irqlevel)
266 group->disable_cnt[idx] = count; 119{
267 else 120 __clr_MASK(irqlevel);
268 level->disable_count = count; 121}
269 122
270 spin_unlock_irqrestore(&level->lock, flags); 123static void frv_cpupic_end(unsigned int irqlevel)
124{
125 __clr_MASK(irqlevel);
271} 126}
272 127
273EXPORT_SYMBOL(enable_irq); 128static struct irq_chip frv_cpu_pic = {
129 .name = "cpu",
130 .ack = frv_cpupic_ack,
131 .mask = frv_cpupic_mask,
132 .mask_ack = frv_cpupic_mask_ack,
133 .unmask = frv_cpupic_unmask,
134 .end = frv_cpupic_end,
135};
274 136
275/*****************************************************************************/
276/* 137/*
277 * handles all normal device IRQ's 138 * handles all normal device IRQ's
278 * - registers are referred to by the __frame variable (GR28) 139 * - registers are referred to by the __frame variable (GR28)
@@ -281,463 +142,65 @@ EXPORT_SYMBOL(enable_irq);
281 */ 142 */
282asmlinkage void do_IRQ(void) 143asmlinkage void do_IRQ(void)
283{ 144{
284 struct irq_source *source;
285 int level, cpu;
286
287 irq_enter(); 145 irq_enter();
288 146 generic_handle_irq(__get_IRL(), __frame);
289 level = (__frame->tbr >> 4) & 0xf;
290 cpu = smp_processor_id();
291
292 if ((unsigned long) __frame - (unsigned long) (current + 1) < 512)
293 BUG();
294
295 __set_MASK(level);
296 __clr_RC(level);
297 __clr_IRL();
298
299 kstat_this_cpu.irqs[level]++;
300
301 for (source = frv_irq_levels[level].sources; source; source = source->next)
302 source->doirq(source);
303
304 __clr_MASK(level);
305
306 irq_exit(); 147 irq_exit();
148}
307 149
308} /* end do_IRQ() */
309
310/*****************************************************************************/
311/* 150/*
312 * handles all NMIs when not co-opted by the debugger 151 * handles all NMIs when not co-opted by the debugger
313 * - registers are referred to by the __frame variable (GR28) 152 * - registers are referred to by the __frame variable (GR28)
314 */ 153 */
315asmlinkage void do_NMI(void) 154asmlinkage void do_NMI(void)
316{ 155{
317} /* end do_NMI() */
318
319/*****************************************************************************/
320/**
321 * request_irq - allocate an interrupt line
322 * @irq: Interrupt line to allocate
323 * @handler: Function to be called when the IRQ occurs
324 * @irqflags: Interrupt type flags
325 * @devname: An ascii name for the claiming device
326 * @dev_id: A cookie passed back to the handler function
327 *
328 * This call allocates interrupt resources and enables the
329 * interrupt line and IRQ handling. From the point this
330 * call is made your handler function may be invoked. Since
331 * your handler function must clear any interrupt the board
332 * raises, you must take care both to initialise your hardware
333 * and to set up the interrupt handler in the right order.
334 *
335 * Dev_id must be globally unique. Normally the address of the
336 * device data structure is used as the cookie. Since the handler
337 * receives this value it makes sense to use it.
338 *
339 * If your interrupt is shared you must pass a non NULL dev_id
340 * as this is required when freeing the interrupt.
341 *
342 * Flags:
343 *
344 * IRQF_SHARED Interrupt is shared
345 *
346 * IRQF_DISABLED Disable local interrupts while processing
347 *
348 * IRQF_SAMPLE_RANDOM The interrupt can be used for entropy
349 *
350 */
351
352int request_irq(unsigned int irq,
353 irqreturn_t (*handler)(int, void *, struct pt_regs *),
354 unsigned long irqflags,
355 const char * devname,
356 void *dev_id)
357{
358 int retval;
359 struct irqaction *action;
360
361#if 1
362 /*
363 * Sanity-check: shared interrupts should REALLY pass in
364 * a real dev-ID, otherwise we'll have trouble later trying
365 * to figure out which interrupt is which (messes up the
366 * interrupt freeing logic etc).
367 */
368 if (irqflags & IRQF_SHARED) {
369 if (!dev_id)
370 printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n",
371 devname, (&irq)[-1]);
372 }
373#endif
374
375 if ((irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP) >= NR_IRQ_GROUPS)
376 return -EINVAL;
377 if (!handler)
378 return -EINVAL;
379
380 action = (struct irqaction *) kmalloc(sizeof(struct irqaction), GFP_KERNEL);
381 if (!action)
382 return -ENOMEM;
383
384 action->handler = handler;
385 action->flags = irqflags;
386 action->mask = CPU_MASK_NONE;
387 action->name = devname;
388 action->next = NULL;
389 action->dev_id = dev_id;
390
391 retval = setup_irq(irq, action);
392 if (retval)
393 kfree(action);
394 return retval;
395}
396
397EXPORT_SYMBOL(request_irq);
398
399/**
400 * free_irq - free an interrupt
401 * @irq: Interrupt line to free
402 * @dev_id: Device identity to free
403 *
404 * Remove an interrupt handler. The handler is removed and if the
405 * interrupt line is no longer in use by any driver it is disabled.
406 * On a shared IRQ the caller must ensure the interrupt is disabled
407 * on the card it drives before calling this function. The function
408 * does not return until any executing interrupts for this IRQ
409 * have completed.
410 *
411 * This function may be called from interrupt context.
412 *
413 * Bugs: Attempting to free an irq in a handler for the same irq hangs
414 * the machine.
415 */
416
417void free_irq(unsigned int irq, void *dev_id)
418{
419 struct irq_source *source;
420 struct irq_group *group;
421 struct irq_level *level;
422 struct irqaction **p, **pp;
423 unsigned long flags;
424
425 if ((irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP) >= NR_IRQ_GROUPS)
426 return;
427
428 group = irq_groups[irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP];
429 if (!group)
430 BUG();
431
432 source = group->sources[irq & (NR_IRQ_ACTIONS_PER_GROUP - 1)];
433 if (!source)
434 BUG();
435
436 level = source->level;
437 p = &group->actions[irq & (NR_IRQ_ACTIONS_PER_GROUP - 1)];
438
439 spin_lock_irqsave(&level->lock, flags);
440
441 for (pp = p; *pp; pp = &(*pp)->next) {
442 struct irqaction *action = *pp;
443
444 if (action->dev_id != dev_id)
445 continue;
446
447 /* found it - remove from the list of entries */
448 *pp = action->next;
449
450 level->usage--;
451
452 if (p == pp && group->control)
453 group->control(group, irq & (NR_IRQ_ACTIONS_PER_GROUP - 1), 0);
454
455 if (level->usage == 0)
456 __set_MASK(level - frv_irq_levels);
457
458 spin_unlock_irqrestore(&level->lock,flags);
459
460#ifdef CONFIG_SMP
461 /* Wait to make sure it's not being used on another CPU */
462 while (desc->status & IRQ_INPROGRESS)
463 barrier();
464#endif
465 kfree(action);
466 return;
467 }
468}
469
470EXPORT_SYMBOL(free_irq);
471
472/*
473 * IRQ autodetection code..
474 *
475 * This depends on the fact that any interrupt that comes in on to an
476 * unassigned IRQ will cause GxICR_DETECT to be set
477 */
478
479static DECLARE_MUTEX(probe_sem);
480
481/**
482 * probe_irq_on - begin an interrupt autodetect
483 *
484 * Commence probing for an interrupt. The interrupts are scanned
485 * and a mask of potential interrupt lines is returned.
486 *
487 */
488
489unsigned long probe_irq_on(void)
490{
491 down(&probe_sem);
492 return 0;
493} 156}
494 157
495EXPORT_SYMBOL(probe_irq_on);
496
497/* 158/*
498 * Return a mask of triggered interrupts (this 159 * initialise the interrupt system
499 * can handle only legacy ISA interrupts).
500 */
501
502/**
503 * probe_irq_mask - scan a bitmap of interrupt lines
504 * @val: mask of interrupts to consider
505 *
506 * Scan the ISA bus interrupt lines and return a bitmap of
507 * active interrupts. The interrupt probe logic state is then
508 * returned to its previous value.
509 *
510 * Note: we need to scan all the irq's even though we will
511 * only return ISA irq numbers - just so that we reset them
512 * all to a known state.
513 */
514unsigned int probe_irq_mask(unsigned long xmask)
515{
516 up(&probe_sem);
517 return 0;
518}
519
520EXPORT_SYMBOL(probe_irq_mask);
521
522/*
523 * Return the one interrupt that triggered (this can
524 * handle any interrupt source).
525 */
526
527/**
528 * probe_irq_off - end an interrupt autodetect
529 * @xmask: mask of potential interrupts (unused)
530 *
531 * Scans the unused interrupt lines and returns the line which
532 * appears to have triggered the interrupt. If no interrupt was
533 * found then zero is returned. If more than one interrupt is
534 * found then minus the first candidate is returned to indicate
535 * their is doubt.
536 *
537 * The interrupt probe logic state is returned to its previous
538 * value.
539 *
540 * BUGS: When used in a module (which arguably shouldnt happen)
541 * nothing prevents two IRQ probe callers from overlapping. The
542 * results of this are non-optimal.
543 */ 160 */
544 161void __init init_IRQ(void)
545int probe_irq_off(unsigned long xmask)
546{
547 up(&probe_sem);
548 return -1;
549}
550
551EXPORT_SYMBOL(probe_irq_off);
552
553/* this was setup_x86_irq but it seems pretty generic */
554int setup_irq(unsigned int irq, struct irqaction *new)
555{
556 struct irq_source *source;
557 struct irq_group *group;
558 struct irq_level *level;
559 struct irqaction **p, **pp;
560 unsigned long flags;
561
562 group = irq_groups[irq >> NR_IRQ_LOG2_ACTIONS_PER_GROUP];
563 if (!group)
564 BUG();
565
566 source = group->sources[irq & (NR_IRQ_ACTIONS_PER_GROUP - 1)];
567 if (!source)
568 BUG();
569
570 level = source->level;
571
572 p = &group->actions[irq & (NR_IRQ_ACTIONS_PER_GROUP - 1)];
573
574 /*
575 * Some drivers like serial.c use request_irq() heavily,
576 * so we have to be careful not to interfere with a
577 * running system.
578 */
579 if (new->flags & IRQF_SAMPLE_RANDOM) {
580 /*
581 * This function might sleep, we want to call it first,
582 * outside of the atomic block.
583 * Yes, this might clear the entropy pool if the wrong
584 * driver is attempted to be loaded, without actually
585 * installing a new handler, but is this really a problem,
586 * only the sysadmin is able to do this.
587 */
588 rand_initialize_irq(irq);
589 }
590
591 /* must juggle the interrupt processing stuff with interrupts disabled */
592 spin_lock_irqsave(&level->lock, flags);
593
594 /* can't share interrupts unless all parties agree to */
595 if (level->usage != 0 && !(level->flags & new->flags & IRQF_SHARED)) {
596 spin_unlock_irqrestore(&level->lock,flags);
597 return -EBUSY;
598 }
599
600 /* add new interrupt at end of irq queue */
601 pp = p;
602 while (*pp)
603 pp = &(*pp)->next;
604
605 *pp = new;
606
607 level->usage++;
608 level->flags = new->flags;
609
610 /* turn the interrupts on */
611 if (level->usage == 1)
612 __clr_MASK(level - frv_irq_levels);
613
614 if (p == pp && group->control)
615 group->control(group, irq & (NR_IRQ_ACTIONS_PER_GROUP - 1), 1);
616
617 spin_unlock_irqrestore(&level->lock, flags);
618 register_irq_proc(irq);
619 return 0;
620}
621
622static struct proc_dir_entry * root_irq_dir;
623static struct proc_dir_entry * irq_dir [NR_IRQS];
624
625#define HEX_DIGITS 8
626
627static unsigned int parse_hex_value (const char __user *buffer,
628 unsigned long count, unsigned long *ret)
629{
630 unsigned char hexnum [HEX_DIGITS];
631 unsigned long value;
632 int i;
633
634 if (!count)
635 return -EINVAL;
636 if (count > HEX_DIGITS)
637 count = HEX_DIGITS;
638 if (copy_from_user(hexnum, buffer, count))
639 return -EFAULT;
640
641 /*
642 * Parse the first 8 characters as a hex string, any non-hex char
643 * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
644 */
645 value = 0;
646
647 for (i = 0; i < count; i++) {
648 unsigned int c = hexnum[i];
649
650 switch (c) {
651 case '0' ... '9': c -= '0'; break;
652 case 'a' ... 'f': c -= 'a'-10; break;
653 case 'A' ... 'F': c -= 'A'-10; break;
654 default:
655 goto out;
656 }
657 value = (value << 4) | c;
658 }
659out:
660 *ret = value;
661 return 0;
662}
663
664
665static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
666 int count, int *eof, void *data)
667{
668 unsigned long *mask = (unsigned long *) data;
669 if (count < HEX_DIGITS+1)
670 return -EINVAL;
671 return sprintf (page, "%08lx\n", *mask);
672}
673
674static int prof_cpu_mask_write_proc (struct file *file, const char __user *buffer,
675 unsigned long count, void *data)
676{
677 unsigned long *mask = (unsigned long *) data, full_count = count, err;
678 unsigned long new_value;
679
680 show_state();
681 err = parse_hex_value(buffer, count, &new_value);
682 if (err)
683 return err;
684
685 *mask = new_value;
686 return full_count;
687}
688
689#define MAX_NAMELEN 10
690
691static void register_irq_proc (unsigned int irq)
692{
693 char name [MAX_NAMELEN];
694
695 if (!root_irq_dir || irq_dir[irq])
696 return;
697
698 memset(name, 0, MAX_NAMELEN);
699 sprintf(name, "%d", irq);
700
701 /* create /proc/irq/1234 */
702 irq_dir[irq] = proc_mkdir(name, root_irq_dir);
703}
704
705unsigned long prof_cpu_mask = -1;
706
707void init_irq_proc (void)
708{ 162{
709 struct proc_dir_entry *entry; 163 int level;
710 int i;
711 164
712 /* create /proc/irq */ 165 for (level = 1; level <= 14; level++)
713 root_irq_dir = proc_mkdir("irq", NULL); 166 set_irq_chip_and_handler(level, &frv_cpu_pic,
167 handle_level_irq);
714 168
715 /* create /proc/irq/prof_cpu_mask */ 169 set_irq_handler(IRQ_CPU_TIMER0, handle_edge_irq);
716 entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir);
717 if (!entry)
718 return;
719 170
720 entry->nlink = 1; 171 /* set the trigger levels for internal interrupt sources
721 entry->data = (void *)&prof_cpu_mask; 172 * - timers all falling-edge
722 entry->read_proc = prof_cpu_mask_read_proc; 173 * - ERR0 is rising-edge
723 entry->write_proc = prof_cpu_mask_write_proc; 174 * - all others are high-level
724
725 /*
726 * Create entries for all existing IRQs.
727 */ 175 */
728 for (i = 0; i < NR_IRQS; i++) 176 __set_IITMR(0, 0x003f0000); /* DMA0-3, TIMER0-2 */
729 register_irq_proc(i); 177 __set_IITMR(1, 0x20000000); /* ERR0-1, UART0-1, DMA4-7 */
730} 178
179 /* route internal interrupts */
180 set_IRR(4, IRQ_DMA3_LEVEL, IRQ_DMA2_LEVEL, IRQ_DMA1_LEVEL,
181 IRQ_DMA0_LEVEL);
182 set_IRR(5, 0, IRQ_TIMER2_LEVEL, IRQ_TIMER1_LEVEL, IRQ_TIMER0_LEVEL);
183 set_IRR(6, IRQ_GDBSTUB_LEVEL, IRQ_GDBSTUB_LEVEL,
184 IRQ_UART1_LEVEL, IRQ_UART0_LEVEL);
185 set_IRR(7, IRQ_DMA7_LEVEL, IRQ_DMA6_LEVEL, IRQ_DMA5_LEVEL,
186 IRQ_DMA4_LEVEL);
187
188 /* route external interrupts */
189 set_IRR(2, IRQ_XIRQ7_LEVEL, IRQ_XIRQ6_LEVEL, IRQ_XIRQ5_LEVEL,
190 IRQ_XIRQ4_LEVEL);
191 set_IRR(3, IRQ_XIRQ3_LEVEL, IRQ_XIRQ2_LEVEL, IRQ_XIRQ1_LEVEL,
192 IRQ_XIRQ0_LEVEL);
193
194#if defined(CONFIG_MB93091_VDK)
195 __set_TM1(0x55550000); /* XIRQ7-0 all active low */
196#elif defined(CONFIG_MB93093_PDK)
197 __set_TM1(0x15550000); /* XIRQ7 active high, 6-0 all active low */
198#else
199#error dont know external IRQ trigger levels for this setup
200#endif
731 201
732/*****************************************************************************/
733/*
734 * initialise the interrupt system
735 */
736void __init init_IRQ(void)
737{
738 route_cpu_irqs();
739 fpga_init(); 202 fpga_init();
740#ifdef CONFIG_FUJITSU_MB93493 203#ifdef CONFIG_FUJITSU_MB93493
741 route_mb93493_irqs(); 204 mb93493_init();
742#endif 205#endif
743} /* end init_IRQ() */ 206}
diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c
index af08ccd4ed6e..d96a57e5f030 100644
--- a/arch/frv/kernel/setup.c
+++ b/arch/frv/kernel/setup.c
@@ -43,7 +43,6 @@
43#include <asm/mb-regs.h> 43#include <asm/mb-regs.h>
44#include <asm/mb93493-regs.h> 44#include <asm/mb93493-regs.h>
45#include <asm/gdb-stub.h> 45#include <asm/gdb-stub.h>
46#include <asm/irq-routing.h>
47#include <asm/io.h> 46#include <asm/io.h>
48 47
49#ifdef CONFIG_BLK_DEV_INITRD 48#ifdef CONFIG_BLK_DEV_INITRD
diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c
index 68a77fe3bb40..3d0284bccb94 100644
--- a/arch/frv/kernel/time.c
+++ b/arch/frv/kernel/time.c
@@ -26,7 +26,6 @@
26#include <asm/timer-regs.h> 26#include <asm/timer-regs.h>
27#include <asm/mb-regs.h> 27#include <asm/mb-regs.h>
28#include <asm/mb86943a.h> 28#include <asm/mb86943a.h>
29#include <asm/irq-routing.h>
30 29
31#include <linux/timex.h> 30#include <linux/timex.h>
32 31
diff --git a/arch/frv/mb93090-mb00/pci-irq.c b/arch/frv/mb93090-mb00/pci-irq.c
index 2278c80bd88c..ba587523c015 100644
--- a/arch/frv/mb93090-mb00/pci-irq.c
+++ b/arch/frv/mb93090-mb00/pci-irq.c
@@ -15,7 +15,6 @@
15 15
16#include <asm/io.h> 16#include <asm/io.h>
17#include <asm/smp.h> 17#include <asm/smp.h>
18#include <asm/irq-routing.h>
19 18
20#include "pci-frv.h" 19#include "pci-frv.h"
21 20
diff --git a/arch/frv/mm/init.c b/arch/frv/mm/init.c
index b5b4286f9dd4..3f3a0ed3539b 100644
--- a/arch/frv/mm/init.c
+++ b/arch/frv/mm/init.c
@@ -98,7 +98,7 @@ void show_mem(void)
98 */ 98 */
99void __init paging_init(void) 99void __init paging_init(void)
100{ 100{
101 unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; 101 unsigned long zones_size[MAX_NR_ZONES] = {0, };
102 102
103 /* allocate some pages for kernel housekeeping tasks */ 103 /* allocate some pages for kernel housekeeping tasks */
104 empty_bad_page_table = (unsigned long) alloc_bootmem_pages(PAGE_SIZE); 104 empty_bad_page_table = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
diff --git a/arch/h8300/mm/init.c b/arch/h8300/mm/init.c
index d3d40bdc2d6a..e4f4199f97ab 100644
--- a/arch/h8300/mm/init.c
+++ b/arch/h8300/mm/init.c
@@ -138,7 +138,7 @@ void paging_init(void)
138#endif 138#endif
139 139
140 { 140 {
141 unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; 141 unsigned long zones_size[MAX_NR_ZONES] = {0, };
142 142
143 zones_size[ZONE_DMA] = 0 >> PAGE_SHIFT; 143 zones_size[ZONE_DMA] = 0 >> PAGE_SHIFT;
144 zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT; 144 zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index b2751eadbc56..3fd2f256f2be 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -166,7 +166,6 @@ config X86_VISWS
166 166
167config X86_GENERICARCH 167config X86_GENERICARCH
168 bool "Generic architecture (Summit, bigsmp, ES7000, default)" 168 bool "Generic architecture (Summit, bigsmp, ES7000, default)"
169 depends on SMP
170 help 169 help
171 This option compiles in the Summit, bigsmp, ES7000, default subarchitectures. 170 This option compiles in the Summit, bigsmp, ES7000, default subarchitectures.
172 It is intended for a generic binary kernel. 171 It is intended for a generic binary kernel.
@@ -263,7 +262,7 @@ source "kernel/Kconfig.preempt"
263 262
264config X86_UP_APIC 263config X86_UP_APIC
265 bool "Local APIC support on uniprocessors" 264 bool "Local APIC support on uniprocessors"
266 depends on !SMP && !(X86_VISWS || X86_VOYAGER) 265 depends on !SMP && !(X86_VISWS || X86_VOYAGER || X86_GENERICARCH)
267 help 266 help
268 A local APIC (Advanced Programmable Interrupt Controller) is an 267 A local APIC (Advanced Programmable Interrupt Controller) is an
269 integrated interrupt controller in the CPU. If you have a single-CPU 268 integrated interrupt controller in the CPU. If you have a single-CPU
@@ -288,12 +287,12 @@ config X86_UP_IOAPIC
288 287
289config X86_LOCAL_APIC 288config X86_LOCAL_APIC
290 bool 289 bool
291 depends on X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) 290 depends on X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) || X86_GENERICARCH
292 default y 291 default y
293 292
294config X86_IO_APIC 293config X86_IO_APIC
295 bool 294 bool
296 depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) 295 depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) || X86_GENERICARCH
297 default y 296 default y
298 297
299config X86_VISWS_APIC 298config X86_VISWS_APIC
@@ -402,6 +401,7 @@ config X86_REBOOTFIXUPS
402 401
403config MICROCODE 402config MICROCODE
404 tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support" 403 tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support"
404 select FW_LOADER
405 ---help--- 405 ---help---
406 If you say Y here and also to "/dev file system support" in the 406 If you say Y here and also to "/dev file system support" in the
407 'File systems' section, you will be able to update the microcode on 407 'File systems' section, you will be able to update the microcode on
@@ -417,6 +417,11 @@ config MICROCODE
417 To compile this driver as a module, choose M here: the 417 To compile this driver as a module, choose M here: the
418 module will be called microcode. 418 module will be called microcode.
419 419
420config MICROCODE_OLD_INTERFACE
421 bool
422 depends on MICROCODE
423 default y
424
420config X86_MSR 425config X86_MSR
421 tristate "/dev/cpu/*/msr - Model-specific register support" 426 tristate "/dev/cpu/*/msr - Model-specific register support"
422 help 427 help
@@ -494,7 +499,7 @@ config HIGHMEM64G
494endchoice 499endchoice
495 500
496choice 501choice
497 depends on EXPERIMENTAL && !X86_PAE 502 depends on EXPERIMENTAL
498 prompt "Memory split" if EMBEDDED 503 prompt "Memory split" if EMBEDDED
499 default VMSPLIT_3G 504 default VMSPLIT_3G
500 help 505 help
@@ -516,6 +521,7 @@ choice
516 config VMSPLIT_3G 521 config VMSPLIT_3G
517 bool "3G/1G user/kernel split" 522 bool "3G/1G user/kernel split"
518 config VMSPLIT_3G_OPT 523 config VMSPLIT_3G_OPT
524 depends on !HIGHMEM
519 bool "3G/1G user/kernel split (for full 1G low memory)" 525 bool "3G/1G user/kernel split (for full 1G low memory)"
520 config VMSPLIT_2G 526 config VMSPLIT_2G
521 bool "2G/2G user/kernel split" 527 bool "2G/2G user/kernel split"
@@ -598,12 +604,10 @@ config ARCH_SELECT_MEMORY_MODEL
598 def_bool y 604 def_bool y
599 depends on ARCH_SPARSEMEM_ENABLE 605 depends on ARCH_SPARSEMEM_ENABLE
600 606
601source "mm/Kconfig" 607config ARCH_POPULATES_NODE_MAP
608 def_bool y
602 609
603config HAVE_ARCH_EARLY_PFN_TO_NID 610source "mm/Kconfig"
604 bool
605 default y
606 depends on NUMA
607 611
608config HIGHPTE 612config HIGHPTE
609 bool "Allocate 3rd-level pagetables from highmem" 613 bool "Allocate 3rd-level pagetables from highmem"
@@ -740,8 +744,7 @@ config SECCOMP
740source kernel/Kconfig.hz 744source kernel/Kconfig.hz
741 745
742config KEXEC 746config KEXEC
743 bool "kexec system call (EXPERIMENTAL)" 747 bool "kexec system call"
744 depends on EXPERIMENTAL
745 help 748 help
746 kexec is a system call that implements the ability to shutdown your 749 kexec is a system call that implements the ability to shutdown your
747 current kernel, and to start another kernel. It is like a reboot 750 current kernel, and to start another kernel. It is like a reboot
@@ -762,6 +765,13 @@ config CRASH_DUMP
762 depends on HIGHMEM 765 depends on HIGHMEM
763 help 766 help
764 Generate crash dump after being started by kexec. 767 Generate crash dump after being started by kexec.
768 This should be normally only set in special crash dump kernels
769 which are loaded in the main kernel with kexec-tools into
770 a specially reserved region and then later executed after
771 a crash by kdump/kexec. The crash dump kernel must be compiled
772 to a memory address not used by the main kernel or BIOS using
773 PHYSICAL_START.
774 For more details see Documentation/kdump/kdump.txt
765 775
766config PHYSICAL_START 776config PHYSICAL_START
767 hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) 777 hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
@@ -794,6 +804,7 @@ config HOTPLUG_CPU
794config COMPAT_VDSO 804config COMPAT_VDSO
795 bool "Compat VDSO support" 805 bool "Compat VDSO support"
796 default y 806 default y
807 depends on !PARAVIRT
797 help 808 help
798 Map the VDSO to the predictable old-style address too. 809 Map the VDSO to the predictable old-style address too.
799 ---help--- 810 ---help---
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index 3e4adb1e2244..7cc0b189b82b 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -46,6 +46,14 @@ cflags-y += -ffreestanding
46# a lot more stack due to the lack of sharing of stacklots: 46# a lot more stack due to the lack of sharing of stacklots:
47CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;) 47CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;)
48 48
49# do binutils support CFI?
50cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
51AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
52
53# is .cfi_signal_frame supported too?
54cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
55AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
56
49CFLAGS += $(cflags-y) 57CFLAGS += $(cflags-y)
50 58
51# Default subarch .c files 59# Default subarch .c files
diff --git a/arch/i386/boot/edd.S b/arch/i386/boot/edd.S
index 4b84ea216f2b..34321368011a 100644
--- a/arch/i386/boot/edd.S
+++ b/arch/i386/boot/edd.S
@@ -15,42 +15,95 @@
15#include <asm/setup.h> 15#include <asm/setup.h>
16 16
17#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) 17#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
18
19# It is assumed that %ds == INITSEG here
20
18 movb $0, (EDD_MBR_SIG_NR_BUF) 21 movb $0, (EDD_MBR_SIG_NR_BUF)
19 movb $0, (EDDNR) 22 movb $0, (EDDNR)
20 23
21# Check the command line for two options: 24# Check the command line for options:
22# edd=of disables EDD completely (edd=off) 25# edd=of disables EDD completely (edd=off)
23# edd=sk skips the MBR test (edd=skipmbr) 26# edd=sk skips the MBR test (edd=skipmbr)
27# edd=on re-enables EDD (edd=on)
28
24 pushl %esi 29 pushl %esi
25 cmpl $0, %cs:cmd_line_ptr 30 movw $edd_mbr_sig_start, %di # Default to edd=on
26 jz done_cl 31
27 movl %cs:(cmd_line_ptr), %esi 32 movl %cs:(cmd_line_ptr), %esi
28# ds:esi has the pointer to the command line now 33 andl %esi, %esi
29 movl $(COMMAND_LINE_SIZE-7), %ecx 34 jz old_cl # Old boot protocol?
30# loop through kernel command line one byte at a time 35
31cl_loop: 36# Convert to a real-mode pointer in fs:si
32 cmpl $EDD_CL_EQUALS, (%si) 37 movl %esi, %eax
38 shrl $4, %eax
39 movw %ax, %fs
40 andw $0xf, %si
41 jmp have_cl_pointer
42
43# Old-style boot protocol?
44old_cl:
45 push %ds # aka INITSEG
46 pop %fs
47
48 cmpw $0xa33f, (0x20)
49 jne done_cl # No command line at all?
50 movw (0x22), %si # Pointer relative to INITSEG
51
52# fs:si has the pointer to the command line now
53have_cl_pointer:
54
55# Loop through kernel command line one byte at a time. Just in
56# case the loader is buggy and failed to null-terminate the command line
57# terminate if we get close enough to the end of the segment that we
58# cannot fit "edd=XX"...
59cl_atspace:
60 cmpw $-5, %si # Watch for segment wraparound
61 jae done_cl
62 movl %fs:(%si), %eax
63 andb %al, %al # End of line?
64 jz done_cl
65 cmpl $EDD_CL_EQUALS, %eax
33 jz found_edd_equals 66 jz found_edd_equals
34 incl %esi 67 cmpb $0x20, %al # <= space consider whitespace
35 loop cl_loop 68 ja cl_skipword
36 jmp done_cl 69 incw %si
70 jmp cl_atspace
71
72cl_skipword:
73 cmpw $-5, %si # Watch for segment wraparound
74 jae done_cl
75 movb %fs:(%si), %al # End of string?
76 andb %al, %al
77 jz done_cl
78 cmpb $0x20, %al
79 jbe cl_atspace
80 incw %si
81 jmp cl_skipword
82
37found_edd_equals: 83found_edd_equals:
38# only looking at first two characters after equals 84# only looking at first two characters after equals
39 addl $4, %esi 85# late overrides early on the command line, so keep going after finding something
40 cmpw $EDD_CL_OFF, (%si) # edd=of 86 movw %fs:4(%si), %ax
41 jz do_edd_off 87 cmpw $EDD_CL_OFF, %ax # edd=of
42 cmpw $EDD_CL_SKIP, (%si) # edd=sk 88 je do_edd_off
43 jz do_edd_skipmbr 89 cmpw $EDD_CL_SKIP, %ax # edd=sk
44 jmp done_cl 90 je do_edd_skipmbr
91 cmpw $EDD_CL_ON, %ax # edd=on
92 je do_edd_on
93 jmp cl_skipword
45do_edd_skipmbr: 94do_edd_skipmbr:
46 popl %esi 95 movw $edd_start, %di
47 jmp edd_start 96 jmp cl_skipword
48do_edd_off: 97do_edd_off:
49 popl %esi 98 movw $edd_done, %di
50 jmp edd_done 99 jmp cl_skipword
100do_edd_on:
101 movw $edd_mbr_sig_start, %di
102 jmp cl_skipword
103
51done_cl: 104done_cl:
52 popl %esi 105 popl %esi
53 106 jmpw *%di
54 107
55# Read the first sector of each BIOS disk device and store the 4-byte signature 108# Read the first sector of each BIOS disk device and store the 4-byte signature
56edd_mbr_sig_start: 109edd_mbr_sig_start:
diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S
index d2b684cd620a..3aec4538a113 100644
--- a/arch/i386/boot/setup.S
+++ b/arch/i386/boot/setup.S
@@ -494,12 +494,12 @@ no_voyager:
494 movw %cs, %ax # aka SETUPSEG 494 movw %cs, %ax # aka SETUPSEG
495 subw $DELTA_INITSEG, %ax # aka INITSEG 495 subw $DELTA_INITSEG, %ax # aka INITSEG
496 movw %ax, %ds 496 movw %ax, %ds
497 movw $0, (0x1ff) # default is no pointing device 497 movb $0, (0x1ff) # default is no pointing device
498 int $0x11 # int 0x11: equipment list 498 int $0x11 # int 0x11: equipment list
499 testb $0x04, %al # check if mouse installed 499 testb $0x04, %al # check if mouse installed
500 jz no_psmouse 500 jz no_psmouse
501 501
502 movw $0xAA, (0x1ff) # device present 502 movb $0xAA, (0x1ff) # device present
503no_psmouse: 503no_psmouse:
504 504
505#if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE) 505#if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE)
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 89ebb7a316ab..1a29bfa26d0c 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -1,41 +1,51 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.18-git5
4# Tue Sep 26 09:30:47 2006
3# 5#
4CONFIG_X86_32=y 6CONFIG_X86_32=y
7CONFIG_GENERIC_TIME=y
8CONFIG_LOCKDEP_SUPPORT=y
9CONFIG_STACKTRACE_SUPPORT=y
5CONFIG_SEMAPHORE_SLEEPERS=y 10CONFIG_SEMAPHORE_SLEEPERS=y
6CONFIG_X86=y 11CONFIG_X86=y
7CONFIG_MMU=y 12CONFIG_MMU=y
8CONFIG_GENERIC_ISA_DMA=y 13CONFIG_GENERIC_ISA_DMA=y
9CONFIG_GENERIC_IOMAP=y 14CONFIG_GENERIC_IOMAP=y
15CONFIG_GENERIC_HWEIGHT=y
10CONFIG_ARCH_MAY_HAVE_PC_FDC=y 16CONFIG_ARCH_MAY_HAVE_PC_FDC=y
11CONFIG_DMI=y 17CONFIG_DMI=y
18CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
12 19
13# 20#
14# Code maturity level options 21# Code maturity level options
15# 22#
16CONFIG_EXPERIMENTAL=y 23CONFIG_EXPERIMENTAL=y
17CONFIG_BROKEN_ON_SMP=y 24CONFIG_LOCK_KERNEL=y
18CONFIG_INIT_ENV_ARG_LIMIT=32 25CONFIG_INIT_ENV_ARG_LIMIT=32
19 26
20# 27#
21# General setup 28# General setup
22# 29#
23CONFIG_LOCALVERSION="" 30CONFIG_LOCALVERSION=""
24# CONFIG_LOCALVERSION_AUTO is not set 31CONFIG_LOCALVERSION_AUTO=y
25CONFIG_SWAP=y 32CONFIG_SWAP=y
26CONFIG_SYSVIPC=y 33CONFIG_SYSVIPC=y
27# CONFIG_POSIX_MQUEUE is not set 34CONFIG_POSIX_MQUEUE=y
28# CONFIG_BSD_PROCESS_ACCT is not set 35# CONFIG_BSD_PROCESS_ACCT is not set
29CONFIG_SYSCTL=y 36# CONFIG_TASKSTATS is not set
30# CONFIG_AUDIT is not set 37# CONFIG_AUDIT is not set
31CONFIG_IKCONFIG=y 38CONFIG_IKCONFIG=y
32CONFIG_IKCONFIG_PROC=y 39CONFIG_IKCONFIG_PROC=y
40# CONFIG_CPUSETS is not set
41# CONFIG_RELAY is not set
33CONFIG_INITRAMFS_SOURCE="" 42CONFIG_INITRAMFS_SOURCE=""
34CONFIG_UID16=y
35CONFIG_VM86=y
36CONFIG_CC_OPTIMIZE_FOR_SIZE=y 43CONFIG_CC_OPTIMIZE_FOR_SIZE=y
37# CONFIG_EMBEDDED is not set 44# CONFIG_EMBEDDED is not set
45CONFIG_UID16=y
46CONFIG_SYSCTL=y
38CONFIG_KALLSYMS=y 47CONFIG_KALLSYMS=y
48CONFIG_KALLSYMS_ALL=y
39# CONFIG_KALLSYMS_EXTRA_PASS is not set 49# CONFIG_KALLSYMS_EXTRA_PASS is not set
40CONFIG_HOTPLUG=y 50CONFIG_HOTPLUG=y
41CONFIG_PRINTK=y 51CONFIG_PRINTK=y
@@ -45,11 +55,9 @@ CONFIG_BASE_FULL=y
45CONFIG_FUTEX=y 55CONFIG_FUTEX=y
46CONFIG_EPOLL=y 56CONFIG_EPOLL=y
47CONFIG_SHMEM=y 57CONFIG_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 58CONFIG_SLAB=y
59CONFIG_VM_EVENT_COUNTERS=y
60CONFIG_RT_MUTEXES=y
53# CONFIG_TINY_SHMEM is not set 61# CONFIG_TINY_SHMEM is not set
54CONFIG_BASE_SMALL=0 62CONFIG_BASE_SMALL=0
55# CONFIG_SLOB is not set 63# CONFIG_SLOB is not set
@@ -60,41 +68,45 @@ CONFIG_BASE_SMALL=0
60CONFIG_MODULES=y 68CONFIG_MODULES=y
61CONFIG_MODULE_UNLOAD=y 69CONFIG_MODULE_UNLOAD=y
62CONFIG_MODULE_FORCE_UNLOAD=y 70CONFIG_MODULE_FORCE_UNLOAD=y
63CONFIG_OBSOLETE_MODPARM=y
64# CONFIG_MODVERSIONS is not set 71# CONFIG_MODVERSIONS is not set
65# CONFIG_MODULE_SRCVERSION_ALL is not set 72# CONFIG_MODULE_SRCVERSION_ALL is not set
66# CONFIG_KMOD is not set 73# CONFIG_KMOD is not set
74CONFIG_STOP_MACHINE=y
67 75
68# 76#
69# Block layer 77# Block layer
70# 78#
71# CONFIG_LBD is not set 79CONFIG_LBD=y
80# CONFIG_BLK_DEV_IO_TRACE is not set
81# CONFIG_LSF is not set
72 82
73# 83#
74# IO Schedulers 84# IO Schedulers
75# 85#
76CONFIG_IOSCHED_NOOP=y 86CONFIG_IOSCHED_NOOP=y
77# CONFIG_IOSCHED_AS is not set 87CONFIG_IOSCHED_AS=y
78# CONFIG_IOSCHED_DEADLINE is not set 88CONFIG_IOSCHED_DEADLINE=y
79CONFIG_IOSCHED_CFQ=y 89CONFIG_IOSCHED_CFQ=y
80# CONFIG_DEFAULT_AS is not set 90CONFIG_DEFAULT_AS=y
81# CONFIG_DEFAULT_DEADLINE is not set 91# CONFIG_DEFAULT_DEADLINE is not set
82CONFIG_DEFAULT_CFQ=y 92# CONFIG_DEFAULT_CFQ is not set
83# CONFIG_DEFAULT_NOOP is not set 93# CONFIG_DEFAULT_NOOP is not set
84CONFIG_DEFAULT_IOSCHED="cfq" 94CONFIG_DEFAULT_IOSCHED="anticipatory"
85 95
86# 96#
87# Processor type and features 97# Processor type and features
88# 98#
89CONFIG_X86_PC=y 99CONFIG_SMP=y
100# CONFIG_X86_PC is not set
90# CONFIG_X86_ELAN is not set 101# CONFIG_X86_ELAN is not set
91# CONFIG_X86_VOYAGER is not set 102# CONFIG_X86_VOYAGER is not set
92# CONFIG_X86_NUMAQ is not set 103# CONFIG_X86_NUMAQ is not set
93# CONFIG_X86_SUMMIT is not set 104# CONFIG_X86_SUMMIT is not set
94# CONFIG_X86_BIGSMP is not set 105# CONFIG_X86_BIGSMP is not set
95# CONFIG_X86_VISWS is not set 106# CONFIG_X86_VISWS is not set
96# CONFIG_X86_GENERICARCH is not set 107CONFIG_X86_GENERICARCH=y
97# CONFIG_X86_ES7000 is not set 108# CONFIG_X86_ES7000 is not set
109CONFIG_X86_CYCLONE_TIMER=y
98# CONFIG_M386 is not set 110# CONFIG_M386 is not set
99# CONFIG_M486 is not set 111# CONFIG_M486 is not set
100# CONFIG_M586 is not set 112# CONFIG_M586 is not set
@@ -102,11 +114,11 @@ CONFIG_X86_PC=y
102# CONFIG_M586MMX is not set 114# CONFIG_M586MMX is not set
103# CONFIG_M686 is not set 115# CONFIG_M686 is not set
104# CONFIG_MPENTIUMII is not set 116# CONFIG_MPENTIUMII is not set
105# CONFIG_MPENTIUMIII is not set 117CONFIG_MPENTIUMIII=y
106# CONFIG_MPENTIUMM is not set 118# CONFIG_MPENTIUMM is not set
107# CONFIG_MPENTIUM4 is not set 119# CONFIG_MPENTIUM4 is not set
108# CONFIG_MK6 is not set 120# CONFIG_MK6 is not set
109CONFIG_MK7=y 121# CONFIG_MK7 is not set
110# CONFIG_MK8 is not set 122# CONFIG_MK8 is not set
111# CONFIG_MCRUSOE is not set 123# CONFIG_MCRUSOE is not set
112# CONFIG_MEFFICEON is not set 124# CONFIG_MEFFICEON is not set
@@ -117,10 +129,10 @@ CONFIG_MK7=y
117# CONFIG_MGEODE_LX is not set 129# CONFIG_MGEODE_LX is not set
118# CONFIG_MCYRIXIII is not set 130# CONFIG_MCYRIXIII is not set
119# CONFIG_MVIAC3_2 is not set 131# CONFIG_MVIAC3_2 is not set
120# CONFIG_X86_GENERIC is not set 132CONFIG_X86_GENERIC=y
121CONFIG_X86_CMPXCHG=y 133CONFIG_X86_CMPXCHG=y
122CONFIG_X86_XADD=y 134CONFIG_X86_XADD=y
123CONFIG_X86_L1_CACHE_SHIFT=6 135CONFIG_X86_L1_CACHE_SHIFT=7
124CONFIG_RWSEM_XCHGADD_ALGORITHM=y 136CONFIG_RWSEM_XCHGADD_ALGORITHM=y
125CONFIG_GENERIC_CALIBRATE_DELAY=y 137CONFIG_GENERIC_CALIBRATE_DELAY=y
126CONFIG_X86_WP_WORKS_OK=y 138CONFIG_X86_WP_WORKS_OK=y
@@ -131,26 +143,28 @@ CONFIG_X86_CMPXCHG64=y
131CONFIG_X86_GOOD_APIC=y 143CONFIG_X86_GOOD_APIC=y
132CONFIG_X86_INTEL_USERCOPY=y 144CONFIG_X86_INTEL_USERCOPY=y
133CONFIG_X86_USE_PPRO_CHECKSUM=y 145CONFIG_X86_USE_PPRO_CHECKSUM=y
134CONFIG_X86_USE_3DNOW=y
135CONFIG_X86_TSC=y 146CONFIG_X86_TSC=y
136# CONFIG_HPET_TIMER is not set 147CONFIG_HPET_TIMER=y
137# CONFIG_SMP is not set 148CONFIG_HPET_EMULATE_RTC=y
138CONFIG_PREEMPT_NONE=y 149CONFIG_NR_CPUS=32
139# CONFIG_PREEMPT_VOLUNTARY is not set 150CONFIG_SCHED_SMT=y
151CONFIG_SCHED_MC=y
152# CONFIG_PREEMPT_NONE is not set
153CONFIG_PREEMPT_VOLUNTARY=y
140# CONFIG_PREEMPT is not set 154# CONFIG_PREEMPT is not set
141CONFIG_X86_UP_APIC=y 155CONFIG_PREEMPT_BKL=y
142CONFIG_X86_UP_IOAPIC=y
143CONFIG_X86_LOCAL_APIC=y 156CONFIG_X86_LOCAL_APIC=y
144CONFIG_X86_IO_APIC=y 157CONFIG_X86_IO_APIC=y
145CONFIG_X86_MCE=y 158CONFIG_X86_MCE=y
146CONFIG_X86_MCE_NONFATAL=y 159CONFIG_X86_MCE_NONFATAL=y
147# CONFIG_X86_MCE_P4THERMAL is not set 160CONFIG_X86_MCE_P4THERMAL=y
161CONFIG_VM86=y
148# CONFIG_TOSHIBA is not set 162# CONFIG_TOSHIBA is not set
149# CONFIG_I8K is not set 163# CONFIG_I8K is not set
150# CONFIG_X86_REBOOTFIXUPS is not set 164# CONFIG_X86_REBOOTFIXUPS is not set
151# CONFIG_MICROCODE is not set 165CONFIG_MICROCODE=y
152# CONFIG_X86_MSR is not set 166CONFIG_X86_MSR=y
153# CONFIG_X86_CPUID is not set 167CONFIG_X86_CPUID=y
154 168
155# 169#
156# Firmware Drivers 170# Firmware Drivers
@@ -158,68 +172,67 @@ CONFIG_X86_MCE_NONFATAL=y
158# CONFIG_EDD is not set 172# CONFIG_EDD is not set
159# CONFIG_DELL_RBU is not set 173# CONFIG_DELL_RBU is not set
160# CONFIG_DCDBAS is not set 174# CONFIG_DCDBAS is not set
161CONFIG_NOHIGHMEM=y 175# CONFIG_NOHIGHMEM is not set
162# CONFIG_HIGHMEM4G is not set 176CONFIG_HIGHMEM4G=y
163# CONFIG_HIGHMEM64G is not set 177# CONFIG_HIGHMEM64G is not set
164CONFIG_VMSPLIT_3G=y
165# CONFIG_VMSPLIT_3G_OPT is not set
166# CONFIG_VMSPLIT_2G is not set
167# CONFIG_VMSPLIT_1G is not set
168CONFIG_PAGE_OFFSET=0xC0000000 178CONFIG_PAGE_OFFSET=0xC0000000
169CONFIG_ARCH_FLATMEM_ENABLE=y 179CONFIG_HIGHMEM=y
170CONFIG_ARCH_SPARSEMEM_ENABLE=y
171CONFIG_ARCH_SELECT_MEMORY_MODEL=y
172CONFIG_SELECT_MEMORY_MODEL=y 180CONFIG_SELECT_MEMORY_MODEL=y
173CONFIG_FLATMEM_MANUAL=y 181CONFIG_FLATMEM_MANUAL=y
174# CONFIG_DISCONTIGMEM_MANUAL is not set 182# CONFIG_DISCONTIGMEM_MANUAL is not set
175# CONFIG_SPARSEMEM_MANUAL is not set 183# CONFIG_SPARSEMEM_MANUAL is not set
176CONFIG_FLATMEM=y 184CONFIG_FLATMEM=y
177CONFIG_FLAT_NODE_MEM_MAP=y 185CONFIG_FLAT_NODE_MEM_MAP=y
178CONFIG_SPARSEMEM_STATIC=y 186# CONFIG_SPARSEMEM_STATIC is not set
179CONFIG_SPLIT_PTLOCK_CPUS=4 187CONFIG_SPLIT_PTLOCK_CPUS=4
188CONFIG_RESOURCES_64BIT=y
189# CONFIG_HIGHPTE is not set
180# CONFIG_MATH_EMULATION is not set 190# CONFIG_MATH_EMULATION is not set
181CONFIG_MTRR=y 191CONFIG_MTRR=y
182# CONFIG_EFI is not set 192# CONFIG_EFI is not set
193# CONFIG_IRQBALANCE is not set
183CONFIG_REGPARM=y 194CONFIG_REGPARM=y
184# CONFIG_SECCOMP is not set 195CONFIG_SECCOMP=y
185CONFIG_HZ_100=y 196# CONFIG_HZ_100 is not set
186# CONFIG_HZ_250 is not set 197CONFIG_HZ_250=y
187# CONFIG_HZ_1000 is not set 198# CONFIG_HZ_1000 is not set
188CONFIG_HZ=100 199CONFIG_HZ=250
189# CONFIG_KEXEC is not set 200# CONFIG_KEXEC is not set
201# CONFIG_CRASH_DUMP is not set
190CONFIG_PHYSICAL_START=0x100000 202CONFIG_PHYSICAL_START=0x100000
191CONFIG_DOUBLEFAULT=y 203# CONFIG_HOTPLUG_CPU is not set
204CONFIG_COMPAT_VDSO=y
205CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
192 206
193# 207#
194# Power management options (ACPI, APM) 208# Power management options (ACPI, APM)
195# 209#
196CONFIG_PM=y 210CONFIG_PM=y
197# CONFIG_PM_LEGACY is not set 211CONFIG_PM_LEGACY=y
198# CONFIG_PM_DEBUG is not set 212# CONFIG_PM_DEBUG is not set
199CONFIG_SOFTWARE_SUSPEND=y
200CONFIG_PM_STD_PARTITION=""
201 213
202# 214#
203# ACPI (Advanced Configuration and Power Interface) Support 215# ACPI (Advanced Configuration and Power Interface) Support
204# 216#
205CONFIG_ACPI=y 217CONFIG_ACPI=y
206# CONFIG_ACPI_SLEEP is not set 218CONFIG_ACPI_AC=y
207# CONFIG_ACPI_AC is not set 219CONFIG_ACPI_BATTERY=y
208# CONFIG_ACPI_BATTERY is not set 220CONFIG_ACPI_BUTTON=y
209# CONFIG_ACPI_BUTTON is not set
210# CONFIG_ACPI_VIDEO is not set 221# CONFIG_ACPI_VIDEO is not set
211# CONFIG_ACPI_HOTKEY is not set 222# CONFIG_ACPI_HOTKEY is not set
212# CONFIG_ACPI_FAN is not set 223CONFIG_ACPI_FAN=y
213# CONFIG_ACPI_PROCESSOR is not set 224# CONFIG_ACPI_DOCK is not set
225CONFIG_ACPI_PROCESSOR=y
226CONFIG_ACPI_THERMAL=y
214# CONFIG_ACPI_ASUS is not set 227# CONFIG_ACPI_ASUS is not set
215# CONFIG_ACPI_IBM is not set 228# CONFIG_ACPI_IBM is not set
216# CONFIG_ACPI_TOSHIBA is not set 229# CONFIG_ACPI_TOSHIBA is not set
217CONFIG_ACPI_BLACKLIST_YEAR=0 230CONFIG_ACPI_BLACKLIST_YEAR=2001
218# CONFIG_ACPI_DEBUG is not set 231CONFIG_ACPI_DEBUG=y
219CONFIG_ACPI_EC=y 232CONFIG_ACPI_EC=y
220CONFIG_ACPI_POWER=y 233CONFIG_ACPI_POWER=y
221CONFIG_ACPI_SYSTEM=y 234CONFIG_ACPI_SYSTEM=y
222# CONFIG_X86_PM_TIMER is not set 235CONFIG_X86_PM_TIMER=y
223# CONFIG_ACPI_CONTAINER is not set 236# CONFIG_ACPI_CONTAINER is not set
224 237
225# 238#
@@ -230,7 +243,41 @@ CONFIG_ACPI_SYSTEM=y
230# 243#
231# CPU Frequency scaling 244# CPU Frequency scaling
232# 245#
233# CONFIG_CPU_FREQ is not set 246CONFIG_CPU_FREQ=y
247CONFIG_CPU_FREQ_TABLE=y
248CONFIG_CPU_FREQ_DEBUG=y
249CONFIG_CPU_FREQ_STAT=y
250# CONFIG_CPU_FREQ_STAT_DETAILS is not set
251CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
252# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
253CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
254# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
255CONFIG_CPU_FREQ_GOV_USERSPACE=y
256CONFIG_CPU_FREQ_GOV_ONDEMAND=y
257# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
258
259#
260# CPUFreq processor drivers
261#
262CONFIG_X86_ACPI_CPUFREQ=y
263# CONFIG_X86_POWERNOW_K6 is not set
264# CONFIG_X86_POWERNOW_K7 is not set
265CONFIG_X86_POWERNOW_K8=y
266CONFIG_X86_POWERNOW_K8_ACPI=y
267# CONFIG_X86_GX_SUSPMOD is not set
268# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
269# CONFIG_X86_SPEEDSTEP_ICH is not set
270# CONFIG_X86_SPEEDSTEP_SMI is not set
271# CONFIG_X86_P4_CLOCKMOD is not set
272# CONFIG_X86_CPUFREQ_NFORCE2 is not set
273# CONFIG_X86_LONGRUN is not set
274# CONFIG_X86_LONGHAUL is not set
275
276#
277# shared options
278#
279CONFIG_X86_ACPI_CPUFREQ_PROC_INTF=y
280# CONFIG_X86_SPEEDSTEP_LIB is not set
234 281
235# 282#
236# Bus options (PCI, PCMCIA, EISA, MCA, ISA) 283# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
@@ -244,12 +291,13 @@ CONFIG_PCI_BIOS=y
244CONFIG_PCI_DIRECT=y 291CONFIG_PCI_DIRECT=y
245CONFIG_PCI_MMCONFIG=y 292CONFIG_PCI_MMCONFIG=y
246# CONFIG_PCIEPORTBUS is not set 293# CONFIG_PCIEPORTBUS is not set
247# CONFIG_PCI_MSI is not set 294CONFIG_PCI_MSI=y
248# CONFIG_PCI_LEGACY_PROC is not set 295# CONFIG_PCI_DEBUG is not set
249CONFIG_ISA_DMA_API=y 296CONFIG_ISA_DMA_API=y
250# CONFIG_ISA is not set 297# CONFIG_ISA is not set
251# CONFIG_MCA is not set 298# CONFIG_MCA is not set
252# CONFIG_SCx200 is not set 299# CONFIG_SCx200 is not set
300CONFIG_K8_NB=y
253 301
254# 302#
255# PCCARD (PCMCIA/CardBus) support 303# PCCARD (PCMCIA/CardBus) support
@@ -278,93 +326,54 @@ CONFIG_NET=y
278# 326#
279# CONFIG_NETDEBUG is not set 327# CONFIG_NETDEBUG is not set
280CONFIG_PACKET=y 328CONFIG_PACKET=y
281CONFIG_PACKET_MMAP=y 329# CONFIG_PACKET_MMAP is not set
282CONFIG_UNIX=y 330CONFIG_UNIX=y
331CONFIG_XFRM=y
332# CONFIG_XFRM_USER is not set
333# CONFIG_XFRM_SUB_POLICY is not set
283# CONFIG_NET_KEY is not set 334# CONFIG_NET_KEY is not set
284CONFIG_INET=y 335CONFIG_INET=y
285# CONFIG_IP_MULTICAST is not set 336CONFIG_IP_MULTICAST=y
286# CONFIG_IP_ADVANCED_ROUTER is not set 337# CONFIG_IP_ADVANCED_ROUTER is not set
287CONFIG_IP_FIB_HASH=y 338CONFIG_IP_FIB_HASH=y
288# CONFIG_IP_PNP is not set 339CONFIG_IP_PNP=y
340CONFIG_IP_PNP_DHCP=y
341# CONFIG_IP_PNP_BOOTP is not set
342# CONFIG_IP_PNP_RARP is not set
289# CONFIG_NET_IPIP is not set 343# CONFIG_NET_IPIP is not set
290# CONFIG_NET_IPGRE is not set 344# CONFIG_NET_IPGRE is not set
345# CONFIG_IP_MROUTE is not set
291# CONFIG_ARPD is not set 346# CONFIG_ARPD is not set
292# CONFIG_SYN_COOKIES is not set 347# CONFIG_SYN_COOKIES is not set
293# CONFIG_INET_AH is not set 348# CONFIG_INET_AH is not set
294# CONFIG_INET_ESP is not set 349# CONFIG_INET_ESP is not set
295# CONFIG_INET_IPCOMP is not set 350# CONFIG_INET_IPCOMP is not set
351# CONFIG_INET_XFRM_TUNNEL is not set
296# CONFIG_INET_TUNNEL is not set 352# CONFIG_INET_TUNNEL is not set
297# CONFIG_INET_DIAG is not set 353CONFIG_INET_XFRM_MODE_TRANSPORT=y
354CONFIG_INET_XFRM_MODE_TUNNEL=y
355CONFIG_INET_DIAG=y
356CONFIG_INET_TCP_DIAG=y
298# CONFIG_TCP_CONG_ADVANCED is not set 357# CONFIG_TCP_CONG_ADVANCED is not set
299CONFIG_TCP_CONG_BIC=y 358CONFIG_TCP_CONG_CUBIC=y
300 359CONFIG_DEFAULT_TCP_CONG="cubic"
301# 360CONFIG_IPV6=y
302# IP: Virtual Server Configuration 361# CONFIG_IPV6_PRIVACY is not set
303# 362# CONFIG_IPV6_ROUTER_PREF is not set
304# CONFIG_IP_VS is not set 363# CONFIG_INET6_AH is not set
305# CONFIG_IPV6 is not set 364# CONFIG_INET6_ESP is not set
306CONFIG_NETFILTER=y 365# CONFIG_INET6_IPCOMP is not set
307# CONFIG_NETFILTER_DEBUG is not set 366# CONFIG_IPV6_MIP6 is not set
308 367# CONFIG_INET6_XFRM_TUNNEL is not set
309# 368# CONFIG_INET6_TUNNEL is not set
310# Core Netfilter Configuration 369CONFIG_INET6_XFRM_MODE_TRANSPORT=y
311# 370CONFIG_INET6_XFRM_MODE_TUNNEL=y
312# CONFIG_NETFILTER_NETLINK is not set 371# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
313CONFIG_NETFILTER_XTABLES=y 372# CONFIG_IPV6_TUNNEL is not set
314# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set 373# CONFIG_IPV6_SUBTREES is not set
315# CONFIG_NETFILTER_XT_TARGET_MARK is not set 374# CONFIG_IPV6_MULTIPLE_TABLES is not set
316# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set 375# CONFIG_NETWORK_SECMARK is not set
317# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set 376# CONFIG_NETFILTER is not set
318# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set
319# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
320# CONFIG_NETFILTER_XT_MATCH_HELPER is not set
321# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
322CONFIG_NETFILTER_XT_MATCH_LIMIT=y
323CONFIG_NETFILTER_XT_MATCH_MAC=y
324# CONFIG_NETFILTER_XT_MATCH_MARK is not set
325# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
326# CONFIG_NETFILTER_XT_MATCH_REALM is not set
327# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
328CONFIG_NETFILTER_XT_MATCH_STATE=y
329# CONFIG_NETFILTER_XT_MATCH_STRING is not set
330# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
331
332#
333# IP: Netfilter Configuration
334#
335CONFIG_IP_NF_CONNTRACK=y
336# CONFIG_IP_NF_CT_ACCT is not set
337# CONFIG_IP_NF_CONNTRACK_MARK is not set
338# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
339# CONFIG_IP_NF_CT_PROTO_SCTP is not set
340CONFIG_IP_NF_FTP=y
341# CONFIG_IP_NF_IRC is not set
342# CONFIG_IP_NF_NETBIOS_NS is not set
343# CONFIG_IP_NF_TFTP is not set
344# CONFIG_IP_NF_AMANDA is not set
345# CONFIG_IP_NF_PPTP is not set
346# CONFIG_IP_NF_QUEUE is not set
347CONFIG_IP_NF_IPTABLES=y
348# CONFIG_IP_NF_MATCH_IPRANGE is not set
349# CONFIG_IP_NF_MATCH_MULTIPORT is not set
350# CONFIG_IP_NF_MATCH_TOS is not set
351# CONFIG_IP_NF_MATCH_RECENT is not set
352# CONFIG_IP_NF_MATCH_ECN is not set
353# CONFIG_IP_NF_MATCH_DSCP is not set
354# CONFIG_IP_NF_MATCH_AH_ESP is not set
355# CONFIG_IP_NF_MATCH_TTL is not set
356# CONFIG_IP_NF_MATCH_OWNER is not set
357# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
358# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
359CONFIG_IP_NF_FILTER=y
360# CONFIG_IP_NF_TARGET_REJECT is not set
361CONFIG_IP_NF_TARGET_LOG=y
362# CONFIG_IP_NF_TARGET_ULOG is not set
363# CONFIG_IP_NF_TARGET_TCPMSS is not set
364# CONFIG_IP_NF_NAT is not set
365# CONFIG_IP_NF_MANGLE is not set
366# CONFIG_IP_NF_RAW is not set
367# CONFIG_IP_NF_ARPTABLES is not set
368 377
369# 378#
370# DCCP Configuration (EXPERIMENTAL) 379# DCCP Configuration (EXPERIMENTAL)
@@ -389,7 +398,6 @@ CONFIG_IP_NF_TARGET_LOG=y
389# CONFIG_ATALK is not set 398# CONFIG_ATALK is not set
390# CONFIG_X25 is not set 399# CONFIG_X25 is not set
391# CONFIG_LAPB is not set 400# CONFIG_LAPB is not set
392# CONFIG_NET_DIVERT is not set
393# CONFIG_ECONET is not set 401# CONFIG_ECONET is not set
394# CONFIG_WAN_ROUTER is not set 402# CONFIG_WAN_ROUTER is not set
395 403
@@ -402,6 +410,7 @@ CONFIG_IP_NF_TARGET_LOG=y
402# Network testing 410# Network testing
403# 411#
404# CONFIG_NET_PKTGEN is not set 412# CONFIG_NET_PKTGEN is not set
413# CONFIG_NET_TCPPROBE is not set
405# CONFIG_HAMRADIO is not set 414# CONFIG_HAMRADIO is not set
406# CONFIG_IRDA is not set 415# CONFIG_IRDA is not set
407# CONFIG_BT is not set 416# CONFIG_BT is not set
@@ -416,7 +425,9 @@ CONFIG_IP_NF_TARGET_LOG=y
416# 425#
417CONFIG_STANDALONE=y 426CONFIG_STANDALONE=y
418CONFIG_PREVENT_FIRMWARE_BUILD=y 427CONFIG_PREVENT_FIRMWARE_BUILD=y
419# CONFIG_FW_LOADER is not set 428CONFIG_FW_LOADER=y
429# CONFIG_DEBUG_DRIVER is not set
430# CONFIG_SYS_HYPERVISOR is not set
420 431
421# 432#
422# Connector - unified userspace <-> kernelspace linker 433# Connector - unified userspace <-> kernelspace linker
@@ -431,13 +442,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
431# 442#
432# Parallel port support 443# Parallel port support
433# 444#
434CONFIG_PARPORT=y 445# CONFIG_PARPORT is not set
435CONFIG_PARPORT_PC=y
436# CONFIG_PARPORT_SERIAL is not set
437# CONFIG_PARPORT_PC_FIFO is not set
438# CONFIG_PARPORT_PC_SUPERIO is not set
439# CONFIG_PARPORT_GSC is not set
440CONFIG_PARPORT_1284=y
441 446
442# 447#
443# Plug and Play support 448# Plug and Play support
@@ -447,8 +452,7 @@ CONFIG_PARPORT_1284=y
447# 452#
448# Block devices 453# Block devices
449# 454#
450# CONFIG_BLK_DEV_FD is not set 455CONFIG_BLK_DEV_FD=y
451# CONFIG_PARIDE is not set
452# CONFIG_BLK_CPQ_DA is not set 456# CONFIG_BLK_CPQ_DA is not set
453# CONFIG_BLK_CPQ_CISS_DA is not set 457# CONFIG_BLK_CPQ_CISS_DA is not set
454# CONFIG_BLK_DEV_DAC960 is not set 458# CONFIG_BLK_DEV_DAC960 is not set
@@ -459,8 +463,11 @@ CONFIG_BLK_DEV_LOOP=y
459# CONFIG_BLK_DEV_NBD is not set 463# CONFIG_BLK_DEV_NBD is not set
460# CONFIG_BLK_DEV_SX8 is not set 464# CONFIG_BLK_DEV_SX8 is not set
461# CONFIG_BLK_DEV_UB is not set 465# CONFIG_BLK_DEV_UB is not set
462# CONFIG_BLK_DEV_RAM is not set 466CONFIG_BLK_DEV_RAM=y
463CONFIG_BLK_DEV_RAM_COUNT=16 467CONFIG_BLK_DEV_RAM_COUNT=16
468CONFIG_BLK_DEV_RAM_SIZE=4096
469CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
470CONFIG_BLK_DEV_INITRD=y
464# CONFIG_CDROM_PKTCDVD is not set 471# CONFIG_CDROM_PKTCDVD is not set
465# CONFIG_ATA_OVER_ETH is not set 472# CONFIG_ATA_OVER_ETH is not set
466 473
@@ -476,7 +483,7 @@ CONFIG_BLK_DEV_IDE=y
476# CONFIG_BLK_DEV_IDE_SATA is not set 483# CONFIG_BLK_DEV_IDE_SATA is not set
477# CONFIG_BLK_DEV_HD_IDE is not set 484# CONFIG_BLK_DEV_HD_IDE is not set
478CONFIG_BLK_DEV_IDEDISK=y 485CONFIG_BLK_DEV_IDEDISK=y
479# CONFIG_IDEDISK_MULTI_MODE is not set 486CONFIG_IDEDISK_MULTI_MODE=y
480CONFIG_BLK_DEV_IDECD=y 487CONFIG_BLK_DEV_IDECD=y
481# CONFIG_BLK_DEV_IDETAPE is not set 488# CONFIG_BLK_DEV_IDETAPE is not set
482# CONFIG_BLK_DEV_IDEFLOPPY is not set 489# CONFIG_BLK_DEV_IDEFLOPPY is not set
@@ -486,10 +493,10 @@ CONFIG_BLK_DEV_IDECD=y
486# 493#
487# IDE chipset support/bugfixes 494# IDE chipset support/bugfixes
488# 495#
489# CONFIG_IDE_GENERIC is not set 496CONFIG_IDE_GENERIC=y
490# CONFIG_BLK_DEV_CMD640 is not set 497# CONFIG_BLK_DEV_CMD640 is not set
491CONFIG_BLK_DEV_IDEPCI=y 498CONFIG_BLK_DEV_IDEPCI=y
492CONFIG_IDEPCI_SHARE_IRQ=y 499# CONFIG_IDEPCI_SHARE_IRQ is not set
493# CONFIG_BLK_DEV_OFFBOARD is not set 500# CONFIG_BLK_DEV_OFFBOARD is not set
494# CONFIG_BLK_DEV_GENERIC is not set 501# CONFIG_BLK_DEV_GENERIC is not set
495# CONFIG_BLK_DEV_OPTI621 is not set 502# CONFIG_BLK_DEV_OPTI621 is not set
@@ -500,7 +507,7 @@ CONFIG_IDEDMA_PCI_AUTO=y
500# CONFIG_IDEDMA_ONLYDISK is not set 507# CONFIG_IDEDMA_ONLYDISK is not set
501# CONFIG_BLK_DEV_AEC62XX is not set 508# CONFIG_BLK_DEV_AEC62XX is not set
502# CONFIG_BLK_DEV_ALI15X3 is not set 509# CONFIG_BLK_DEV_ALI15X3 is not set
503# CONFIG_BLK_DEV_AMD74XX is not set 510CONFIG_BLK_DEV_AMD74XX=y
504# CONFIG_BLK_DEV_ATIIXP is not set 511# CONFIG_BLK_DEV_ATIIXP is not set
505# CONFIG_BLK_DEV_CMD64X is not set 512# CONFIG_BLK_DEV_CMD64X is not set
506# CONFIG_BLK_DEV_TRIFLEX is not set 513# CONFIG_BLK_DEV_TRIFLEX is not set
@@ -511,7 +518,7 @@ CONFIG_IDEDMA_PCI_AUTO=y
511# CONFIG_BLK_DEV_HPT34X is not set 518# CONFIG_BLK_DEV_HPT34X is not set
512# CONFIG_BLK_DEV_HPT366 is not set 519# CONFIG_BLK_DEV_HPT366 is not set
513# CONFIG_BLK_DEV_SC1200 is not set 520# CONFIG_BLK_DEV_SC1200 is not set
514# CONFIG_BLK_DEV_PIIX is not set 521CONFIG_BLK_DEV_PIIX=y
515# CONFIG_BLK_DEV_IT821X is not set 522# CONFIG_BLK_DEV_IT821X is not set
516# CONFIG_BLK_DEV_NS87415 is not set 523# CONFIG_BLK_DEV_NS87415 is not set
517# CONFIG_BLK_DEV_PDC202XX_OLD is not set 524# CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -521,7 +528,7 @@ CONFIG_IDEDMA_PCI_AUTO=y
521# CONFIG_BLK_DEV_SIS5513 is not set 528# CONFIG_BLK_DEV_SIS5513 is not set
522# CONFIG_BLK_DEV_SLC90E66 is not set 529# CONFIG_BLK_DEV_SLC90E66 is not set
523# CONFIG_BLK_DEV_TRM290 is not set 530# CONFIG_BLK_DEV_TRM290 is not set
524CONFIG_BLK_DEV_VIA82CXXX=y 531# CONFIG_BLK_DEV_VIA82CXXX is not set
525# CONFIG_IDE_ARM is not set 532# CONFIG_IDE_ARM is not set
526CONFIG_BLK_DEV_IDEDMA=y 533CONFIG_BLK_DEV_IDEDMA=y
527# CONFIG_IDEDMA_IVB is not set 534# CONFIG_IDEDMA_IVB is not set
@@ -533,6 +540,7 @@ CONFIG_IDEDMA_AUTO=y
533# 540#
534# CONFIG_RAID_ATTRS is not set 541# CONFIG_RAID_ATTRS is not set
535CONFIG_SCSI=y 542CONFIG_SCSI=y
543CONFIG_SCSI_NETLINK=y
536# CONFIG_SCSI_PROC_FS is not set 544# CONFIG_SCSI_PROC_FS is not set
537 545
538# 546#
@@ -541,8 +549,9 @@ CONFIG_SCSI=y
541CONFIG_BLK_DEV_SD=y 549CONFIG_BLK_DEV_SD=y
542# CONFIG_CHR_DEV_ST is not set 550# CONFIG_CHR_DEV_ST is not set
543# CONFIG_CHR_DEV_OSST is not set 551# CONFIG_CHR_DEV_OSST is not set
544# CONFIG_BLK_DEV_SR is not set 552CONFIG_BLK_DEV_SR=y
545# CONFIG_CHR_DEV_SG is not set 553# CONFIG_BLK_DEV_SR_VENDOR is not set
554CONFIG_CHR_DEV_SG=y
546# CONFIG_CHR_DEV_SCH is not set 555# CONFIG_CHR_DEV_SCH is not set
547 556
548# 557#
@@ -553,29 +562,44 @@ CONFIG_BLK_DEV_SD=y
553# CONFIG_SCSI_LOGGING is not set 562# CONFIG_SCSI_LOGGING is not set
554 563
555# 564#
556# SCSI Transport Attributes 565# SCSI Transports
557# 566#
558# CONFIG_SCSI_SPI_ATTRS is not set 567CONFIG_SCSI_SPI_ATTRS=y
559# CONFIG_SCSI_FC_ATTRS is not set 568CONFIG_SCSI_FC_ATTRS=y
560# CONFIG_SCSI_ISCSI_ATTRS is not set 569# CONFIG_SCSI_ISCSI_ATTRS is not set
561# CONFIG_SCSI_SAS_ATTRS is not set 570# CONFIG_SCSI_SAS_ATTRS is not set
571# CONFIG_SCSI_SAS_LIBSAS is not set
562 572
563# 573#
564# SCSI low-level drivers 574# SCSI low-level drivers
565# 575#
566# CONFIG_ISCSI_TCP is not set 576# CONFIG_ISCSI_TCP is not set
567# CONFIG_BLK_DEV_3W_XXXX_RAID is not set 577CONFIG_BLK_DEV_3W_XXXX_RAID=y
568# CONFIG_SCSI_3W_9XXX is not set 578# CONFIG_SCSI_3W_9XXX is not set
569# CONFIG_SCSI_ACARD is not set 579# CONFIG_SCSI_ACARD is not set
570# CONFIG_SCSI_AACRAID is not set 580# CONFIG_SCSI_AACRAID is not set
571# CONFIG_SCSI_AIC7XXX is not set 581CONFIG_SCSI_AIC7XXX=y
582CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
583CONFIG_AIC7XXX_RESET_DELAY_MS=5000
584CONFIG_AIC7XXX_DEBUG_ENABLE=y
585CONFIG_AIC7XXX_DEBUG_MASK=0
586CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
572# CONFIG_SCSI_AIC7XXX_OLD is not set 587# CONFIG_SCSI_AIC7XXX_OLD is not set
573# CONFIG_SCSI_AIC79XX is not set 588CONFIG_SCSI_AIC79XX=y
589CONFIG_AIC79XX_CMDS_PER_DEVICE=32
590CONFIG_AIC79XX_RESET_DELAY_MS=4000
591# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
592# CONFIG_AIC79XX_DEBUG_ENABLE is not set
593CONFIG_AIC79XX_DEBUG_MASK=0
594# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
595# CONFIG_SCSI_AIC94XX is not set
574# CONFIG_SCSI_DPT_I2O is not set 596# CONFIG_SCSI_DPT_I2O is not set
597# CONFIG_SCSI_ADVANSYS is not set
598# CONFIG_SCSI_ARCMSR is not set
575# CONFIG_MEGARAID_NEWGEN is not set 599# CONFIG_MEGARAID_NEWGEN is not set
576# CONFIG_MEGARAID_LEGACY is not set 600# CONFIG_MEGARAID_LEGACY is not set
577# CONFIG_MEGARAID_SAS is not set 601# CONFIG_MEGARAID_SAS is not set
578# CONFIG_SCSI_SATA is not set 602# CONFIG_SCSI_HPTIOP is not set
579# CONFIG_SCSI_BUSLOGIC is not set 603# CONFIG_SCSI_BUSLOGIC is not set
580# CONFIG_SCSI_DMX3191D is not set 604# CONFIG_SCSI_DMX3191D is not set
581# CONFIG_SCSI_EATA is not set 605# CONFIG_SCSI_EATA is not set
@@ -584,11 +608,9 @@ CONFIG_BLK_DEV_SD=y
584# CONFIG_SCSI_IPS is not set 608# CONFIG_SCSI_IPS is not set
585# CONFIG_SCSI_INITIO is not set 609# CONFIG_SCSI_INITIO is not set
586# CONFIG_SCSI_INIA100 is not set 610# CONFIG_SCSI_INIA100 is not set
587# CONFIG_SCSI_PPA is not set 611# CONFIG_SCSI_STEX is not set
588# CONFIG_SCSI_IMM is not set
589# CONFIG_SCSI_SYM53C8XX_2 is not set 612# CONFIG_SCSI_SYM53C8XX_2 is not set
590# CONFIG_SCSI_IPR is not set 613# CONFIG_SCSI_IPR is not set
591# CONFIG_SCSI_QLOGIC_FC is not set
592# CONFIG_SCSI_QLOGIC_1280 is not set 614# CONFIG_SCSI_QLOGIC_1280 is not set
593# CONFIG_SCSI_QLA_FC is not set 615# CONFIG_SCSI_QLA_FC is not set
594# CONFIG_SCSI_LPFC is not set 616# CONFIG_SCSI_LPFC is not set
@@ -598,22 +620,114 @@ CONFIG_BLK_DEV_SD=y
598# CONFIG_SCSI_DEBUG is not set 620# CONFIG_SCSI_DEBUG is not set
599 621
600# 622#
623# Serial ATA (prod) and Parallel ATA (experimental) drivers
624#
625CONFIG_ATA=y
626CONFIG_SATA_AHCI=y
627CONFIG_SATA_SVW=y
628CONFIG_ATA_PIIX=y
629# CONFIG_SATA_MV is not set
630CONFIG_SATA_NV=y
631# CONFIG_PDC_ADMA is not set
632# CONFIG_SATA_QSTOR is not set
633# CONFIG_SATA_PROMISE is not set
634# CONFIG_SATA_SX4 is not set
635CONFIG_SATA_SIL=y
636# CONFIG_SATA_SIL24 is not set
637# CONFIG_SATA_SIS is not set
638# CONFIG_SATA_ULI is not set
639CONFIG_SATA_VIA=y
640# CONFIG_SATA_VITESSE is not set
641CONFIG_SATA_INTEL_COMBINED=y
642# CONFIG_PATA_ALI is not set
643# CONFIG_PATA_AMD is not set
644# CONFIG_PATA_ARTOP is not set
645# CONFIG_PATA_ATIIXP is not set
646# CONFIG_PATA_CMD64X is not set
647# CONFIG_PATA_CS5520 is not set
648# CONFIG_PATA_CS5530 is not set
649# CONFIG_PATA_CS5535 is not set
650# CONFIG_PATA_CYPRESS is not set
651# CONFIG_PATA_EFAR is not set
652# CONFIG_ATA_GENERIC is not set
653# CONFIG_PATA_HPT366 is not set
654# CONFIG_PATA_HPT37X is not set
655# CONFIG_PATA_HPT3X2N is not set
656# CONFIG_PATA_HPT3X3 is not set
657# CONFIG_PATA_IT821X is not set
658# CONFIG_PATA_JMICRON is not set
659# CONFIG_PATA_LEGACY is not set
660# CONFIG_PATA_TRIFLEX is not set
661# CONFIG_PATA_MPIIX is not set
662# CONFIG_PATA_OLDPIIX is not set
663# CONFIG_PATA_NETCELL is not set
664# CONFIG_PATA_NS87410 is not set
665# CONFIG_PATA_OPTI is not set
666# CONFIG_PATA_OPTIDMA is not set
667# CONFIG_PATA_PDC_OLD is not set
668# CONFIG_PATA_QDI is not set
669# CONFIG_PATA_RADISYS is not set
670# CONFIG_PATA_RZ1000 is not set
671# CONFIG_PATA_SC1200 is not set
672# CONFIG_PATA_SERVERWORKS is not set
673# CONFIG_PATA_PDC2027X is not set
674# CONFIG_PATA_SIL680 is not set
675# CONFIG_PATA_SIS is not set
676# CONFIG_PATA_VIA is not set
677# CONFIG_PATA_WINBOND is not set
678
679#
601# Multi-device support (RAID and LVM) 680# Multi-device support (RAID and LVM)
602# 681#
603# CONFIG_MD is not set 682CONFIG_MD=y
683# CONFIG_BLK_DEV_MD is not set
684CONFIG_BLK_DEV_DM=y
685# CONFIG_DM_CRYPT is not set
686# CONFIG_DM_SNAPSHOT is not set
687# CONFIG_DM_MIRROR is not set
688# CONFIG_DM_ZERO is not set
689# CONFIG_DM_MULTIPATH is not set
604 690
605# 691#
606# Fusion MPT device support 692# Fusion MPT device support
607# 693#
608# CONFIG_FUSION is not set 694CONFIG_FUSION=y
609# CONFIG_FUSION_SPI is not set 695CONFIG_FUSION_SPI=y
610# CONFIG_FUSION_FC is not set 696# CONFIG_FUSION_FC is not set
611# CONFIG_FUSION_SAS is not set 697# CONFIG_FUSION_SAS is not set
698CONFIG_FUSION_MAX_SGE=128
699# CONFIG_FUSION_CTL is not set
612 700
613# 701#
614# IEEE 1394 (FireWire) support 702# IEEE 1394 (FireWire) support
615# 703#
616# CONFIG_IEEE1394 is not set 704CONFIG_IEEE1394=y
705
706#
707# Subsystem Options
708#
709# CONFIG_IEEE1394_VERBOSEDEBUG is not set
710# CONFIG_IEEE1394_OUI_DB is not set
711# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set
712# CONFIG_IEEE1394_EXPORT_FULL_API is not set
713
714#
715# Device Drivers
716#
717
718#
719# Texas Instruments PCILynx requires I2C
720#
721CONFIG_IEEE1394_OHCI1394=y
722
723#
724# Protocol Drivers
725#
726# CONFIG_IEEE1394_VIDEO1394 is not set
727# CONFIG_IEEE1394_SBP2 is not set
728# CONFIG_IEEE1394_ETH1394 is not set
729# CONFIG_IEEE1394_DV1394 is not set
730CONFIG_IEEE1394_RAWIO=y
617 731
618# 732#
619# I2O device support 733# I2O device support
@@ -652,46 +766,63 @@ CONFIG_MII=y
652# 766#
653# Tulip family network device support 767# Tulip family network device support
654# 768#
655# CONFIG_NET_TULIP is not set 769CONFIG_NET_TULIP=y
770# CONFIG_DE2104X is not set
771CONFIG_TULIP=y
772# CONFIG_TULIP_MWI is not set
773# CONFIG_TULIP_MMIO is not set
774# CONFIG_TULIP_NAPI is not set
775# CONFIG_DE4X5 is not set
776# CONFIG_WINBOND_840 is not set
777# CONFIG_DM9102 is not set
778# CONFIG_ULI526X is not set
656# CONFIG_HP100 is not set 779# CONFIG_HP100 is not set
657CONFIG_NET_PCI=y 780CONFIG_NET_PCI=y
658# CONFIG_PCNET32 is not set 781# CONFIG_PCNET32 is not set
659# CONFIG_AMD8111_ETH is not set 782# CONFIG_AMD8111_ETH is not set
660# CONFIG_ADAPTEC_STARFIRE is not set 783# CONFIG_ADAPTEC_STARFIRE is not set
661# CONFIG_B44 is not set 784CONFIG_B44=y
662# CONFIG_FORCEDETH is not set 785CONFIG_FORCEDETH=y
786# CONFIG_FORCEDETH_NAPI is not set
663# CONFIG_DGRS is not set 787# CONFIG_DGRS is not set
664# CONFIG_EEPRO100 is not set 788# CONFIG_EEPRO100 is not set
665CONFIG_E100=y 789CONFIG_E100=y
666# CONFIG_FEALNX is not set 790# CONFIG_FEALNX is not set
667# CONFIG_NATSEMI is not set 791# CONFIG_NATSEMI is not set
668# CONFIG_NE2K_PCI is not set 792# CONFIG_NE2K_PCI is not set
669# CONFIG_8139CP is not set 793CONFIG_8139CP=y
670# CONFIG_8139TOO is not set 794CONFIG_8139TOO=y
795# CONFIG_8139TOO_PIO is not set
796# CONFIG_8139TOO_TUNE_TWISTER is not set
797# CONFIG_8139TOO_8129 is not set
798# CONFIG_8139_OLD_RX_RESET is not set
671# CONFIG_SIS900 is not set 799# CONFIG_SIS900 is not set
672# CONFIG_EPIC100 is not set 800# CONFIG_EPIC100 is not set
673# CONFIG_SUNDANCE is not set 801# CONFIG_SUNDANCE is not set
674# CONFIG_TLAN is not set 802# CONFIG_TLAN is not set
675# CONFIG_VIA_RHINE is not set 803# CONFIG_VIA_RHINE is not set
676# CONFIG_NET_POCKET is not set
677 804
678# 805#
679# Ethernet (1000 Mbit) 806# Ethernet (1000 Mbit)
680# 807#
681# CONFIG_ACENIC is not set 808# CONFIG_ACENIC is not set
682# CONFIG_DL2K is not set 809# CONFIG_DL2K is not set
683# CONFIG_E1000 is not set 810CONFIG_E1000=y
811# CONFIG_E1000_NAPI is not set
812# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
684# CONFIG_NS83820 is not set 813# CONFIG_NS83820 is not set
685# CONFIG_HAMACHI is not set 814# CONFIG_HAMACHI is not set
686# CONFIG_YELLOWFIN is not set 815# CONFIG_YELLOWFIN is not set
687# CONFIG_R8169 is not set 816CONFIG_R8169=y
817# CONFIG_R8169_NAPI is not set
688# CONFIG_SIS190 is not set 818# CONFIG_SIS190 is not set
689# CONFIG_SKGE is not set 819# CONFIG_SKGE is not set
690# CONFIG_SKY2 is not set 820CONFIG_SKY2=y
691# CONFIG_SK98LIN is not set 821# CONFIG_SK98LIN is not set
692# CONFIG_VIA_VELOCITY is not set 822# CONFIG_VIA_VELOCITY is not set
693# CONFIG_TIGON3 is not set 823CONFIG_TIGON3=y
694# CONFIG_BNX2 is not set 824CONFIG_BNX2=y
825# CONFIG_QLA3XXX is not set
695 826
696# 827#
697# Ethernet (10000 Mbit) 828# Ethernet (10000 Mbit)
@@ -699,6 +830,7 @@ CONFIG_E100=y
699# CONFIG_CHELSIO_T1 is not set 830# CONFIG_CHELSIO_T1 is not set
700# CONFIG_IXGB is not set 831# CONFIG_IXGB is not set
701# CONFIG_S2IO is not set 832# CONFIG_S2IO is not set
833# CONFIG_MYRI10GE is not set
702 834
703# 835#
704# Token Ring devices 836# Token Ring devices
@@ -716,14 +848,15 @@ CONFIG_E100=y
716# CONFIG_WAN is not set 848# CONFIG_WAN is not set
717# CONFIG_FDDI is not set 849# CONFIG_FDDI is not set
718# CONFIG_HIPPI is not set 850# CONFIG_HIPPI is not set
719# CONFIG_PLIP is not set
720# CONFIG_PPP is not set 851# CONFIG_PPP is not set
721# CONFIG_SLIP is not set 852# CONFIG_SLIP is not set
722# CONFIG_NET_FC is not set 853# CONFIG_NET_FC is not set
723# CONFIG_SHAPER is not set 854# CONFIG_SHAPER is not set
724# CONFIG_NETCONSOLE is not set 855CONFIG_NETCONSOLE=y
725# CONFIG_NETPOLL is not set 856CONFIG_NETPOLL=y
726# CONFIG_NET_POLL_CONTROLLER is not set 857# CONFIG_NETPOLL_RX is not set
858# CONFIG_NETPOLL_TRAP is not set
859CONFIG_NET_POLL_CONTROLLER=y
727 860
728# 861#
729# ISDN subsystem 862# ISDN subsystem
@@ -745,8 +878,8 @@ CONFIG_INPUT=y
745# 878#
746CONFIG_INPUT_MOUSEDEV=y 879CONFIG_INPUT_MOUSEDEV=y
747CONFIG_INPUT_MOUSEDEV_PSAUX=y 880CONFIG_INPUT_MOUSEDEV_PSAUX=y
748CONFIG_INPUT_MOUSEDEV_SCREEN_X=1280 881CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
749CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1024 882CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
750# CONFIG_INPUT_JOYDEV is not set 883# CONFIG_INPUT_JOYDEV is not set
751# CONFIG_INPUT_TSDEV is not set 884# CONFIG_INPUT_TSDEV is not set
752CONFIG_INPUT_EVDEV=y 885CONFIG_INPUT_EVDEV=y
@@ -776,7 +909,6 @@ CONFIG_SERIO=y
776CONFIG_SERIO_I8042=y 909CONFIG_SERIO_I8042=y
777# CONFIG_SERIO_SERPORT is not set 910# CONFIG_SERIO_SERPORT is not set
778# CONFIG_SERIO_CT82C710 is not set 911# CONFIG_SERIO_CT82C710 is not set
779# CONFIG_SERIO_PARKBD is not set
780# CONFIG_SERIO_PCIPS2 is not set 912# CONFIG_SERIO_PCIPS2 is not set
781CONFIG_SERIO_LIBPS2=y 913CONFIG_SERIO_LIBPS2=y
782# CONFIG_SERIO_RAW is not set 914# CONFIG_SERIO_RAW is not set
@@ -788,14 +920,15 @@ CONFIG_SERIO_LIBPS2=y
788CONFIG_VT=y 920CONFIG_VT=y
789CONFIG_VT_CONSOLE=y 921CONFIG_VT_CONSOLE=y
790CONFIG_HW_CONSOLE=y 922CONFIG_HW_CONSOLE=y
923# CONFIG_VT_HW_CONSOLE_BINDING is not set
791# CONFIG_SERIAL_NONSTANDARD is not set 924# CONFIG_SERIAL_NONSTANDARD is not set
792 925
793# 926#
794# Serial drivers 927# Serial drivers
795# 928#
796CONFIG_SERIAL_8250=y 929CONFIG_SERIAL_8250=y
797# CONFIG_SERIAL_8250_CONSOLE is not set 930CONFIG_SERIAL_8250_CONSOLE=y
798# CONFIG_SERIAL_8250_ACPI is not set 931CONFIG_SERIAL_8250_PCI=y
799CONFIG_SERIAL_8250_NR_UARTS=4 932CONFIG_SERIAL_8250_NR_UARTS=4
800CONFIG_SERIAL_8250_RUNTIME_UARTS=4 933CONFIG_SERIAL_8250_RUNTIME_UARTS=4
801# CONFIG_SERIAL_8250_EXTENDED is not set 934# CONFIG_SERIAL_8250_EXTENDED is not set
@@ -804,14 +937,11 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
804# Non-8250 serial port support 937# Non-8250 serial port support
805# 938#
806CONFIG_SERIAL_CORE=y 939CONFIG_SERIAL_CORE=y
940CONFIG_SERIAL_CORE_CONSOLE=y
807# CONFIG_SERIAL_JSM is not set 941# CONFIG_SERIAL_JSM is not set
808CONFIG_UNIX98_PTYS=y 942CONFIG_UNIX98_PTYS=y
809CONFIG_LEGACY_PTYS=y 943CONFIG_LEGACY_PTYS=y
810CONFIG_LEGACY_PTY_COUNT=256 944CONFIG_LEGACY_PTY_COUNT=256
811CONFIG_PRINTER=y
812# CONFIG_LP_CONSOLE is not set
813# CONFIG_PPDEV is not set
814# CONFIG_TIPAR is not set
815 945
816# 946#
817# IPMI 947# IPMI
@@ -822,8 +952,12 @@ CONFIG_PRINTER=y
822# Watchdog Cards 952# Watchdog Cards
823# 953#
824# CONFIG_WATCHDOG is not set 954# CONFIG_WATCHDOG is not set
825# CONFIG_HW_RANDOM is not set 955CONFIG_HW_RANDOM=y
826CONFIG_NVRAM=y 956CONFIG_HW_RANDOM_INTEL=y
957CONFIG_HW_RANDOM_AMD=y
958CONFIG_HW_RANDOM_GEODE=y
959CONFIG_HW_RANDOM_VIA=y
960# CONFIG_NVRAM is not set
827CONFIG_RTC=y 961CONFIG_RTC=y
828# CONFIG_DTLK is not set 962# CONFIG_DTLK is not set
829# CONFIG_R3964 is not set 963# CONFIG_R3964 is not set
@@ -833,31 +967,28 @@ CONFIG_RTC=y
833# 967#
834# Ftape, the floppy tape device driver 968# Ftape, the floppy tape device driver
835# 969#
836# CONFIG_FTAPE is not set
837CONFIG_AGP=y 970CONFIG_AGP=y
838# CONFIG_AGP_ALI is not set 971# CONFIG_AGP_ALI is not set
839# CONFIG_AGP_ATI is not set 972# CONFIG_AGP_ATI is not set
840# CONFIG_AGP_AMD is not set 973# CONFIG_AGP_AMD is not set
841# CONFIG_AGP_AMD64 is not set 974CONFIG_AGP_AMD64=y
842# CONFIG_AGP_INTEL is not set 975CONFIG_AGP_INTEL=y
843# CONFIG_AGP_NVIDIA is not set 976# CONFIG_AGP_NVIDIA is not set
844# CONFIG_AGP_SIS is not set 977# CONFIG_AGP_SIS is not set
845# CONFIG_AGP_SWORKS is not set 978# CONFIG_AGP_SWORKS is not set
846CONFIG_AGP_VIA=y 979# CONFIG_AGP_VIA is not set
847# CONFIG_AGP_EFFICEON is not set 980# CONFIG_AGP_EFFICEON is not set
848CONFIG_DRM=y 981# CONFIG_DRM is not set
849# CONFIG_DRM_TDFX is not set
850# CONFIG_DRM_R128 is not set
851CONFIG_DRM_RADEON=y
852# CONFIG_DRM_MGA is not set
853# CONFIG_DRM_SIS is not set
854# CONFIG_DRM_VIA is not set
855# CONFIG_DRM_SAVAGE is not set
856# CONFIG_MWAVE is not set 982# CONFIG_MWAVE is not set
983# CONFIG_PC8736x_GPIO is not set
984# CONFIG_NSC_GPIO is not set
857# CONFIG_CS5535_GPIO is not set 985# CONFIG_CS5535_GPIO is not set
858# CONFIG_RAW_DRIVER is not set 986CONFIG_RAW_DRIVER=y
859# CONFIG_HPET is not set 987CONFIG_MAX_RAW_DEVS=256
860# CONFIG_HANGCHECK_TIMER is not set 988CONFIG_HPET=y
989# CONFIG_HPET_RTC_IRQ is not set
990CONFIG_HPET_MMAP=y
991CONFIG_HANGCHECK_TIMER=y
861 992
862# 993#
863# TPM devices 994# TPM devices
@@ -868,59 +999,7 @@ CONFIG_DRM_RADEON=y
868# 999#
869# I2C support 1000# I2C support
870# 1001#
871CONFIG_I2C=y 1002# CONFIG_I2C is not set
872CONFIG_I2C_CHARDEV=y
873
874#
875# I2C Algorithms
876#
877CONFIG_I2C_ALGOBIT=y
878# CONFIG_I2C_ALGOPCF is not set
879# CONFIG_I2C_ALGOPCA is not set
880
881#
882# I2C Hardware Bus support
883#
884# CONFIG_I2C_ALI1535 is not set
885# CONFIG_I2C_ALI1563 is not set
886# CONFIG_I2C_ALI15X3 is not set
887# CONFIG_I2C_AMD756 is not set
888# CONFIG_I2C_AMD8111 is not set
889# CONFIG_I2C_I801 is not set
890# CONFIG_I2C_I810 is not set
891# CONFIG_I2C_PIIX4 is not set
892CONFIG_I2C_ISA=y
893# CONFIG_I2C_NFORCE2 is not set
894# CONFIG_I2C_PARPORT is not set
895# CONFIG_I2C_PARPORT_LIGHT is not set
896# CONFIG_I2C_PROSAVAGE is not set
897# CONFIG_I2C_SAVAGE4 is not set
898# CONFIG_SCx200_ACB is not set
899# CONFIG_I2C_SIS5595 is not set
900# CONFIG_I2C_SIS630 is not set
901# CONFIG_I2C_SIS96X is not set
902# CONFIG_I2C_STUB is not set
903# CONFIG_I2C_VIA is not set
904CONFIG_I2C_VIAPRO=y
905# CONFIG_I2C_VOODOO3 is not set
906# CONFIG_I2C_PCA_ISA is not set
907
908#
909# Miscellaneous I2C Chip support
910#
911# CONFIG_SENSORS_DS1337 is not set
912# CONFIG_SENSORS_DS1374 is not set
913# CONFIG_SENSORS_EEPROM is not set
914# CONFIG_SENSORS_PCF8574 is not set
915# CONFIG_SENSORS_PCA9539 is not set
916# CONFIG_SENSORS_PCF8591 is not set
917# CONFIG_SENSORS_RTC8564 is not set
918# CONFIG_SENSORS_MAX6875 is not set
919# CONFIG_RTC_X1205_I2C is not set
920# CONFIG_I2C_DEBUG_CORE is not set
921# CONFIG_I2C_DEBUG_ALGO is not set
922# CONFIG_I2C_DEBUG_BUS is not set
923# CONFIG_I2C_DEBUG_CHIP is not set
924 1003
925# 1004#
926# SPI support 1005# SPI support
@@ -931,51 +1010,12 @@ CONFIG_I2C_VIAPRO=y
931# 1010#
932# Dallas's 1-wire bus 1011# Dallas's 1-wire bus
933# 1012#
934# CONFIG_W1 is not set
935 1013
936# 1014#
937# Hardware Monitoring support 1015# Hardware Monitoring support
938# 1016#
939CONFIG_HWMON=y 1017# CONFIG_HWMON is not set
940CONFIG_HWMON_VID=y 1018# CONFIG_HWMON_VID is not set
941# CONFIG_SENSORS_ADM1021 is not set
942# CONFIG_SENSORS_ADM1025 is not set
943# CONFIG_SENSORS_ADM1026 is not set
944# CONFIG_SENSORS_ADM1031 is not set
945# CONFIG_SENSORS_ADM9240 is not set
946# CONFIG_SENSORS_ASB100 is not set
947# CONFIG_SENSORS_ATXP1 is not set
948# CONFIG_SENSORS_DS1621 is not set
949# CONFIG_SENSORS_F71805F is not set
950# CONFIG_SENSORS_FSCHER is not set
951# CONFIG_SENSORS_FSCPOS is not set
952# CONFIG_SENSORS_GL518SM is not set
953# CONFIG_SENSORS_GL520SM is not set
954CONFIG_SENSORS_IT87=y
955# CONFIG_SENSORS_LM63 is not set
956# CONFIG_SENSORS_LM75 is not set
957# CONFIG_SENSORS_LM77 is not set
958# CONFIG_SENSORS_LM78 is not set
959# CONFIG_SENSORS_LM80 is not set
960# CONFIG_SENSORS_LM83 is not set
961# CONFIG_SENSORS_LM85 is not set
962# CONFIG_SENSORS_LM87 is not set
963# CONFIG_SENSORS_LM90 is not set
964# CONFIG_SENSORS_LM92 is not set
965# CONFIG_SENSORS_MAX1619 is not set
966# CONFIG_SENSORS_PC87360 is not set
967# CONFIG_SENSORS_SIS5595 is not set
968# CONFIG_SENSORS_SMSC47M1 is not set
969# CONFIG_SENSORS_SMSC47B397 is not set
970# CONFIG_SENSORS_VIA686A is not set
971# CONFIG_SENSORS_VT8231 is not set
972# CONFIG_SENSORS_W83781D is not set
973# CONFIG_SENSORS_W83792D is not set
974# CONFIG_SENSORS_W83L785TS is not set
975# CONFIG_SENSORS_W83627HF is not set
976# CONFIG_SENSORS_W83627EHF is not set
977# CONFIG_SENSORS_HDAPS is not set
978# CONFIG_HWMON_DEBUG_CHIP is not set
979 1019
980# 1020#
981# Misc devices 1021# Misc devices
@@ -983,117 +1023,31 @@ CONFIG_SENSORS_IT87=y
983# CONFIG_IBM_ASM is not set 1023# CONFIG_IBM_ASM is not set
984 1024
985# 1025#
986# Multimedia Capabilities Port drivers
987#
988
989#
990# Multimedia devices 1026# Multimedia devices
991# 1027#
992CONFIG_VIDEO_DEV=y 1028# CONFIG_VIDEO_DEV is not set
993 1029CONFIG_VIDEO_V4L2=y
994#
995# Video For Linux
996#
997
998#
999# Video Adapters
1000#
1001# CONFIG_VIDEO_ADV_DEBUG is not set
1002# CONFIG_VIDEO_BT848 is not set
1003# CONFIG_VIDEO_BWQCAM is not set
1004# CONFIG_VIDEO_CQCAM is not set
1005# CONFIG_VIDEO_W9966 is not set
1006# CONFIG_VIDEO_CPIA is not set
1007# CONFIG_VIDEO_SAA5246A is not set
1008# CONFIG_VIDEO_SAA5249 is not set
1009# CONFIG_TUNER_3036 is not set
1010# CONFIG_VIDEO_STRADIS is not set
1011# CONFIG_VIDEO_ZORAN is not set
1012CONFIG_VIDEO_SAA7134=y
1013# CONFIG_VIDEO_SAA7134_ALSA is not set
1014# CONFIG_VIDEO_MXB is not set
1015# CONFIG_VIDEO_DPC is not set
1016# CONFIG_VIDEO_HEXIUM_ORION is not set
1017# CONFIG_VIDEO_HEXIUM_GEMINI is not set
1018# CONFIG_VIDEO_CX88 is not set
1019# CONFIG_VIDEO_EM28XX is not set
1020# CONFIG_VIDEO_OVCAMCHIP is not set
1021# CONFIG_VIDEO_AUDIO_DECODER is not set
1022# CONFIG_VIDEO_DECODER is not set
1023
1024#
1025# Radio Adapters
1026#
1027# CONFIG_RADIO_GEMTEK_PCI is not set
1028# CONFIG_RADIO_MAXIRADIO is not set
1029# CONFIG_RADIO_MAESTRO is not set
1030 1030
1031# 1031#
1032# Digital Video Broadcasting Devices 1032# Digital Video Broadcasting Devices
1033# 1033#
1034# CONFIG_DVB is not set 1034# CONFIG_DVB is not set
1035CONFIG_VIDEO_TUNER=y 1035# CONFIG_USB_DABUSB is not set
1036CONFIG_VIDEO_BUF=y
1037CONFIG_VIDEO_IR=y
1038 1036
1039# 1037#
1040# Graphics support 1038# Graphics support
1041# 1039#
1042CONFIG_FB=y 1040CONFIG_FIRMWARE_EDID=y
1043CONFIG_FB_CFB_FILLRECT=y 1041# CONFIG_FB is not set
1044CONFIG_FB_CFB_COPYAREA=y
1045CONFIG_FB_CFB_IMAGEBLIT=y
1046# CONFIG_FB_MACMODES is not set
1047CONFIG_FB_MODE_HELPERS=y
1048# CONFIG_FB_TILEBLITTING is not set
1049# CONFIG_FB_CIRRUS is not set
1050# CONFIG_FB_PM2 is not set
1051# CONFIG_FB_CYBER2000 is not set
1052# CONFIG_FB_ARC is not set
1053# CONFIG_FB_ASILIANT is not set
1054# CONFIG_FB_IMSTT is not set
1055# CONFIG_FB_VGA16 is not set
1056# CONFIG_FB_VESA is not set
1057CONFIG_VIDEO_SELECT=y
1058# CONFIG_FB_HGA is not set
1059# CONFIG_FB_S1D13XXX is not set
1060# CONFIG_FB_NVIDIA is not set
1061# CONFIG_FB_RIVA is not set
1062# CONFIG_FB_I810 is not set
1063# CONFIG_FB_INTEL is not set
1064# CONFIG_FB_MATROX is not set
1065# CONFIG_FB_RADEON_OLD is not set
1066CONFIG_FB_RADEON=y
1067CONFIG_FB_RADEON_I2C=y
1068# CONFIG_FB_RADEON_DEBUG is not set
1069# CONFIG_FB_ATY128 is not set
1070# CONFIG_FB_ATY is not set
1071# CONFIG_FB_SAVAGE is not set
1072# CONFIG_FB_SIS is not set
1073# CONFIG_FB_NEOMAGIC is not set
1074# CONFIG_FB_KYRO is not set
1075# CONFIG_FB_3DFX is not set
1076# CONFIG_FB_VOODOO1 is not set
1077# CONFIG_FB_CYBLA is not set
1078# CONFIG_FB_TRIDENT is not set
1079# CONFIG_FB_GEODE is not set
1080# CONFIG_FB_VIRTUAL is not set
1081 1042
1082# 1043#
1083# Console display driver support 1044# Console display driver support
1084# 1045#
1085CONFIG_VGA_CONSOLE=y 1046CONFIG_VGA_CONSOLE=y
1047CONFIG_VGACON_SOFT_SCROLLBACK=y
1048CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=128
1049CONFIG_VIDEO_SELECT=y
1086CONFIG_DUMMY_CONSOLE=y 1050CONFIG_DUMMY_CONSOLE=y
1087CONFIG_FRAMEBUFFER_CONSOLE=y
1088# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
1089# CONFIG_FONTS is not set
1090CONFIG_FONT_8x8=y
1091CONFIG_FONT_8x16=y
1092
1093#
1094# Logo configuration
1095#
1096# CONFIG_LOGO is not set
1097# CONFIG_BACKLIGHT_LCD_SUPPORT is not set 1051# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
1098 1052
1099# 1053#
@@ -1104,97 +1058,30 @@ CONFIG_SOUND=y
1104# 1058#
1105# Advanced Linux Sound Architecture 1059# Advanced Linux Sound Architecture
1106# 1060#
1107CONFIG_SND=y 1061# CONFIG_SND is not set
1108CONFIG_SND_TIMER=y
1109CONFIG_SND_PCM=y
1110CONFIG_SND_RAWMIDI=y
1111CONFIG_SND_SEQUENCER=y
1112# CONFIG_SND_SEQ_DUMMY is not set
1113# CONFIG_SND_MIXER_OSS is not set
1114# CONFIG_SND_PCM_OSS is not set
1115# CONFIG_SND_SEQUENCER_OSS is not set
1116CONFIG_SND_RTCTIMER=y
1117CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y
1118# CONFIG_SND_DYNAMIC_MINORS is not set
1119# CONFIG_SND_SUPPORT_OLD_API is not set
1120# CONFIG_SND_VERBOSE_PRINTK is not set
1121# CONFIG_SND_DEBUG is not set
1122
1123#
1124# Generic devices
1125#
1126CONFIG_SND_MPU401_UART=y
1127CONFIG_SND_AC97_CODEC=y
1128CONFIG_SND_AC97_BUS=y
1129# CONFIG_SND_DUMMY is not set
1130# CONFIG_SND_VIRMIDI is not set
1131# CONFIG_SND_MTPAV is not set
1132# CONFIG_SND_SERIAL_U16550 is not set
1133# CONFIG_SND_MPU401 is not set
1134
1135#
1136# PCI devices
1137#
1138# CONFIG_SND_AD1889 is not set
1139# CONFIG_SND_ALS4000 is not set
1140# CONFIG_SND_ALI5451 is not set
1141# CONFIG_SND_ATIIXP is not set
1142# CONFIG_SND_ATIIXP_MODEM is not set
1143# CONFIG_SND_AU8810 is not set
1144# CONFIG_SND_AU8820 is not set
1145# CONFIG_SND_AU8830 is not set
1146# CONFIG_SND_AZT3328 is not set
1147# CONFIG_SND_BT87X is not set
1148# CONFIG_SND_CA0106 is not set
1149# CONFIG_SND_CMIPCI is not set
1150# CONFIG_SND_CS4281 is not set
1151# CONFIG_SND_CS46XX is not set
1152# CONFIG_SND_CS5535AUDIO is not set
1153# CONFIG_SND_EMU10K1 is not set
1154# CONFIG_SND_EMU10K1X is not set
1155# CONFIG_SND_ENS1370 is not set
1156# CONFIG_SND_ENS1371 is not set
1157# CONFIG_SND_ES1938 is not set
1158# CONFIG_SND_ES1968 is not set
1159# CONFIG_SND_FM801 is not set
1160# CONFIG_SND_HDA_INTEL is not set
1161# CONFIG_SND_HDSP is not set
1162# CONFIG_SND_HDSPM is not set
1163# CONFIG_SND_ICE1712 is not set
1164# CONFIG_SND_ICE1724 is not set
1165# CONFIG_SND_INTEL8X0 is not set
1166# CONFIG_SND_INTEL8X0M is not set
1167# CONFIG_SND_KORG1212 is not set
1168# CONFIG_SND_MAESTRO3 is not set
1169# CONFIG_SND_MIXART is not set
1170# CONFIG_SND_NM256 is not set
1171# CONFIG_SND_PCXHR is not set
1172# CONFIG_SND_RME32 is not set
1173# CONFIG_SND_RME96 is not set
1174# CONFIG_SND_RME9652 is not set
1175# CONFIG_SND_SONICVIBES is not set
1176# CONFIG_SND_TRIDENT is not set
1177CONFIG_SND_VIA82XX=y
1178# CONFIG_SND_VIA82XX_MODEM is not set
1179# CONFIG_SND_VX222 is not set
1180# CONFIG_SND_YMFPCI is not set
1181
1182#
1183# USB devices
1184#
1185# CONFIG_SND_USB_AUDIO is not set
1186# CONFIG_SND_USB_USX2Y is not set
1187 1062
1188# 1063#
1189# Open Sound System 1064# Open Sound System
1190# 1065#
1191# CONFIG_SOUND_PRIME is not set 1066CONFIG_SOUND_PRIME=y
1067CONFIG_OSS_OBSOLETE_DRIVER=y
1068# CONFIG_SOUND_BT878 is not set
1069# CONFIG_SOUND_EMU10K1 is not set
1070# CONFIG_SOUND_FUSION is not set
1071# CONFIG_SOUND_ES1371 is not set
1072CONFIG_SOUND_ICH=y
1073# CONFIG_SOUND_TRIDENT is not set
1074# CONFIG_SOUND_MSNDCLAS is not set
1075# CONFIG_SOUND_MSNDPIN is not set
1076# CONFIG_SOUND_VIA82CXXX is not set
1077# CONFIG_SOUND_OSS is not set
1192 1078
1193# 1079#
1194# USB support 1080# USB support
1195# 1081#
1196CONFIG_USB_ARCH_HAS_HCD=y 1082CONFIG_USB_ARCH_HAS_HCD=y
1197CONFIG_USB_ARCH_HAS_OHCI=y 1083CONFIG_USB_ARCH_HAS_OHCI=y
1084CONFIG_USB_ARCH_HAS_EHCI=y
1198CONFIG_USB=y 1085CONFIG_USB=y
1199# CONFIG_USB_DEBUG is not set 1086# CONFIG_USB_DEBUG is not set
1200 1087
@@ -1213,17 +1100,19 @@ CONFIG_USB_DEVICEFS=y
1213CONFIG_USB_EHCI_HCD=y 1100CONFIG_USB_EHCI_HCD=y
1214# CONFIG_USB_EHCI_SPLIT_ISO is not set 1101# CONFIG_USB_EHCI_SPLIT_ISO is not set
1215# CONFIG_USB_EHCI_ROOT_HUB_TT is not set 1102# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
1103# CONFIG_USB_EHCI_TT_NEWSCHED is not set
1216# CONFIG_USB_ISP116X_HCD is not set 1104# CONFIG_USB_ISP116X_HCD is not set
1217# CONFIG_USB_OHCI_HCD is not set 1105CONFIG_USB_OHCI_HCD=y
1106# CONFIG_USB_OHCI_BIG_ENDIAN is not set
1107CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1218CONFIG_USB_UHCI_HCD=y 1108CONFIG_USB_UHCI_HCD=y
1219# CONFIG_USB_SL811_HCD is not set 1109# CONFIG_USB_SL811_HCD is not set
1220 1110
1221# 1111#
1222# USB Device Class drivers 1112# USB Device Class drivers
1223# 1113#
1224# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
1225# CONFIG_USB_ACM is not set 1114# CONFIG_USB_ACM is not set
1226# CONFIG_USB_PRINTER is not set 1115CONFIG_USB_PRINTER=y
1227 1116
1228# 1117#
1229# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' 1118# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -1248,21 +1137,17 @@ CONFIG_USB_STORAGE=y
1248# 1137#
1249# USB Input Devices 1138# USB Input Devices
1250# 1139#
1251# CONFIG_USB_HID is not set 1140CONFIG_USB_HID=y
1252 1141CONFIG_USB_HIDINPUT=y
1253# 1142# CONFIG_USB_HIDINPUT_POWERBOOK is not set
1254# USB HID Boot Protocol drivers 1143# CONFIG_HID_FF is not set
1255# 1144# CONFIG_USB_HIDDEV is not set
1256# CONFIG_USB_KBD is not set
1257# CONFIG_USB_MOUSE is not set
1258# CONFIG_USB_AIPTEK is not set 1145# CONFIG_USB_AIPTEK is not set
1259# CONFIG_USB_WACOM is not set 1146# CONFIG_USB_WACOM is not set
1260# CONFIG_USB_ACECAD is not set 1147# CONFIG_USB_ACECAD is not set
1261# CONFIG_USB_KBTAB is not set 1148# CONFIG_USB_KBTAB is not set
1262# CONFIG_USB_POWERMATE is not set 1149# CONFIG_USB_POWERMATE is not set
1263# CONFIG_USB_MTOUCH is not set 1150# CONFIG_USB_TOUCHSCREEN is not set
1264# CONFIG_USB_ITMTOUCH is not set
1265# CONFIG_USB_EGALAX is not set
1266# CONFIG_USB_YEALINK is not set 1151# CONFIG_USB_YEALINK is not set
1267# CONFIG_USB_XPAD is not set 1152# CONFIG_USB_XPAD is not set
1268# CONFIG_USB_ATI_REMOTE is not set 1153# CONFIG_USB_ATI_REMOTE is not set
@@ -1277,21 +1162,6 @@ CONFIG_USB_STORAGE=y
1277# CONFIG_USB_MICROTEK is not set 1162# CONFIG_USB_MICROTEK is not set
1278 1163
1279# 1164#
1280# USB Multimedia devices
1281#
1282# CONFIG_USB_DABUSB is not set
1283# CONFIG_USB_VICAM is not set
1284# CONFIG_USB_DSBR is not set
1285# CONFIG_USB_ET61X251 is not set
1286# CONFIG_USB_IBMCAM is not set
1287# CONFIG_USB_KONICAWC is not set
1288# CONFIG_USB_OV511 is not set
1289# CONFIG_USB_SE401 is not set
1290# CONFIG_USB_SN9C102 is not set
1291# CONFIG_USB_STV680 is not set
1292# CONFIG_USB_PWC is not set
1293
1294#
1295# USB Network Adapters 1165# USB Network Adapters
1296# 1166#
1297# CONFIG_USB_CATC is not set 1167# CONFIG_USB_CATC is not set
@@ -1299,12 +1169,11 @@ CONFIG_USB_STORAGE=y
1299# CONFIG_USB_PEGASUS is not set 1169# CONFIG_USB_PEGASUS is not set
1300# CONFIG_USB_RTL8150 is not set 1170# CONFIG_USB_RTL8150 is not set
1301# CONFIG_USB_USBNET is not set 1171# CONFIG_USB_USBNET is not set
1302# CONFIG_USB_MON is not set 1172CONFIG_USB_MON=y
1303 1173
1304# 1174#
1305# USB port drivers 1175# USB port drivers
1306# 1176#
1307# CONFIG_USB_USS720 is not set
1308 1177
1309# 1178#
1310# USB Serial Converter support 1179# USB Serial Converter support
@@ -1321,10 +1190,12 @@ CONFIG_USB_STORAGE=y
1321# CONFIG_USB_LEGOTOWER is not set 1190# CONFIG_USB_LEGOTOWER is not set
1322# CONFIG_USB_LCD is not set 1191# CONFIG_USB_LCD is not set
1323# CONFIG_USB_LED is not set 1192# CONFIG_USB_LED is not set
1193# CONFIG_USB_CYPRESS_CY7C63 is not set
1324# CONFIG_USB_CYTHERM is not set 1194# CONFIG_USB_CYTHERM is not set
1325# CONFIG_USB_PHIDGETKIT is not set 1195# CONFIG_USB_PHIDGETKIT is not set
1326# CONFIG_USB_PHIDGETSERVO is not set 1196# CONFIG_USB_PHIDGETSERVO is not set
1327# CONFIG_USB_IDMOUSE is not set 1197# CONFIG_USB_IDMOUSE is not set
1198# CONFIG_USB_APPLEDISPLAY is not set
1328# CONFIG_USB_SISUSBVGA is not set 1199# CONFIG_USB_SISUSBVGA is not set
1329# CONFIG_USB_LD is not set 1200# CONFIG_USB_LD is not set
1330# CONFIG_USB_TEST is not set 1201# CONFIG_USB_TEST is not set
@@ -1344,56 +1215,96 @@ CONFIG_USB_STORAGE=y
1344# CONFIG_MMC is not set 1215# CONFIG_MMC is not set
1345 1216
1346# 1217#
1218# LED devices
1219#
1220# CONFIG_NEW_LEDS is not set
1221
1222#
1223# LED drivers
1224#
1225
1226#
1227# LED Triggers
1228#
1229
1230#
1347# InfiniBand support 1231# InfiniBand support
1348# 1232#
1349# CONFIG_INFINIBAND is not set 1233# CONFIG_INFINIBAND is not set
1350 1234
1351# 1235#
1352# SN Devices 1236# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
1237#
1238# CONFIG_EDAC is not set
1239
1240#
1241# Real Time Clock
1353# 1242#
1243# CONFIG_RTC_CLASS is not set
1354 1244
1355# 1245#
1356# EDAC - error detection and reporting (RAS) 1246# DMA Engine support
1247#
1248# CONFIG_DMA_ENGINE is not set
1249
1250#
1251# DMA Clients
1252#
1253
1254#
1255# DMA Devices
1357# 1256#
1358# CONFIG_EDAC is not set
1359 1257
1360# 1258#
1361# File systems 1259# File systems
1362# 1260#
1363CONFIG_EXT2_FS=y 1261CONFIG_EXT2_FS=y
1364# CONFIG_EXT2_FS_XATTR is not set 1262CONFIG_EXT2_FS_XATTR=y
1263CONFIG_EXT2_FS_POSIX_ACL=y
1264# CONFIG_EXT2_FS_SECURITY is not set
1365# CONFIG_EXT2_FS_XIP is not set 1265# CONFIG_EXT2_FS_XIP is not set
1366# CONFIG_EXT3_FS is not set 1266CONFIG_EXT3_FS=y
1367# CONFIG_REISERFS_FS is not set 1267CONFIG_EXT3_FS_XATTR=y
1268CONFIG_EXT3_FS_POSIX_ACL=y
1269# CONFIG_EXT3_FS_SECURITY is not set
1270CONFIG_JBD=y
1271# CONFIG_JBD_DEBUG is not set
1272CONFIG_FS_MBCACHE=y
1273CONFIG_REISERFS_FS=y
1274# CONFIG_REISERFS_CHECK is not set
1275# CONFIG_REISERFS_PROC_INFO is not set
1276CONFIG_REISERFS_FS_XATTR=y
1277CONFIG_REISERFS_FS_POSIX_ACL=y
1278# CONFIG_REISERFS_FS_SECURITY is not set
1368# CONFIG_JFS_FS is not set 1279# CONFIG_JFS_FS is not set
1369# CONFIG_FS_POSIX_ACL is not set 1280CONFIG_FS_POSIX_ACL=y
1370# CONFIG_XFS_FS is not set 1281# CONFIG_XFS_FS is not set
1371# CONFIG_OCFS2_FS is not set 1282# CONFIG_OCFS2_FS is not set
1372# CONFIG_MINIX_FS is not set 1283# CONFIG_MINIX_FS is not set
1373# CONFIG_ROMFS_FS is not set 1284# CONFIG_ROMFS_FS is not set
1374# CONFIG_INOTIFY is not set 1285CONFIG_INOTIFY=y
1286CONFIG_INOTIFY_USER=y
1375# CONFIG_QUOTA is not set 1287# CONFIG_QUOTA is not set
1376CONFIG_DNOTIFY=y 1288CONFIG_DNOTIFY=y
1377# CONFIG_AUTOFS_FS is not set 1289# CONFIG_AUTOFS_FS is not set
1378# CONFIG_AUTOFS4_FS is not set 1290CONFIG_AUTOFS4_FS=y
1379# CONFIG_FUSE_FS is not set 1291# CONFIG_FUSE_FS is not set
1380 1292
1381# 1293#
1382# CD-ROM/DVD Filesystems 1294# CD-ROM/DVD Filesystems
1383# 1295#
1384CONFIG_ISO9660_FS=y 1296CONFIG_ISO9660_FS=y
1385CONFIG_JOLIET=y 1297# CONFIG_JOLIET is not set
1386CONFIG_ZISOFS=y 1298# CONFIG_ZISOFS is not set
1387CONFIG_ZISOFS_FS=y
1388# CONFIG_UDF_FS is not set 1299# CONFIG_UDF_FS is not set
1389 1300
1390# 1301#
1391# DOS/FAT/NT Filesystems 1302# DOS/FAT/NT Filesystems
1392# 1303#
1393CONFIG_FAT_FS=y 1304CONFIG_FAT_FS=y
1394# CONFIG_MSDOS_FS is not set 1305CONFIG_MSDOS_FS=y
1395CONFIG_VFAT_FS=y 1306CONFIG_VFAT_FS=y
1396CONFIG_FAT_DEFAULT_CODEPAGE=850 1307CONFIG_FAT_DEFAULT_CODEPAGE=437
1397CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" 1308CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1398# CONFIG_NTFS_FS is not set 1309# CONFIG_NTFS_FS is not set
1399 1310
@@ -1404,10 +1315,9 @@ CONFIG_PROC_FS=y
1404CONFIG_PROC_KCORE=y 1315CONFIG_PROC_KCORE=y
1405CONFIG_SYSFS=y 1316CONFIG_SYSFS=y
1406CONFIG_TMPFS=y 1317CONFIG_TMPFS=y
1407# CONFIG_HUGETLBFS is not set 1318CONFIG_HUGETLBFS=y
1408# CONFIG_HUGETLB_PAGE is not set 1319CONFIG_HUGETLB_PAGE=y
1409CONFIG_RAMFS=y 1320CONFIG_RAMFS=y
1410# CONFIG_RELAYFS_FS is not set
1411# CONFIG_CONFIGFS_FS is not set 1321# CONFIG_CONFIGFS_FS is not set
1412 1322
1413# 1323#
@@ -1430,13 +1340,26 @@ CONFIG_RAMFS=y
1430# 1340#
1431# Network File Systems 1341# Network File Systems
1432# 1342#
1433# CONFIG_NFS_FS is not set 1343CONFIG_NFS_FS=y
1434# CONFIG_NFSD is not set 1344CONFIG_NFS_V3=y
1345# CONFIG_NFS_V3_ACL is not set
1346# CONFIG_NFS_V4 is not set
1347# CONFIG_NFS_DIRECTIO is not set
1348CONFIG_NFSD=y
1349CONFIG_NFSD_V3=y
1350# CONFIG_NFSD_V3_ACL is not set
1351# CONFIG_NFSD_V4 is not set
1352CONFIG_NFSD_TCP=y
1353CONFIG_ROOT_NFS=y
1354CONFIG_LOCKD=y
1355CONFIG_LOCKD_V4=y
1356CONFIG_EXPORTFS=y
1357CONFIG_NFS_COMMON=y
1358CONFIG_SUNRPC=y
1359# CONFIG_RPCSEC_GSS_KRB5 is not set
1360# CONFIG_RPCSEC_GSS_SPKM3 is not set
1435# CONFIG_SMB_FS is not set 1361# CONFIG_SMB_FS is not set
1436CONFIG_CIFS=y 1362# CONFIG_CIFS is not set
1437# CONFIG_CIFS_STATS is not set
1438# CONFIG_CIFS_XATTR is not set
1439# CONFIG_CIFS_EXPERIMENTAL is not set
1440# CONFIG_NCP_FS is not set 1363# CONFIG_NCP_FS is not set
1441# CONFIG_CODA_FS is not set 1364# CONFIG_CODA_FS is not set
1442# CONFIG_AFS_FS is not set 1365# CONFIG_AFS_FS is not set
@@ -1445,33 +1368,18 @@ CONFIG_CIFS=y
1445# 1368#
1446# Partition Types 1369# Partition Types
1447# 1370#
1448CONFIG_PARTITION_ADVANCED=y 1371# CONFIG_PARTITION_ADVANCED is not set
1449# CONFIG_ACORN_PARTITION is not set
1450# CONFIG_OSF_PARTITION is not set
1451# CONFIG_AMIGA_PARTITION is not set
1452# CONFIG_ATARI_PARTITION is not set
1453# CONFIG_MAC_PARTITION is not set
1454CONFIG_MSDOS_PARTITION=y 1372CONFIG_MSDOS_PARTITION=y
1455# CONFIG_BSD_DISKLABEL is not set
1456# CONFIG_MINIX_SUBPARTITION is not set
1457# CONFIG_SOLARIS_X86_PARTITION is not set
1458# CONFIG_UNIXWARE_DISKLABEL is not set
1459# CONFIG_LDM_PARTITION is not set
1460# CONFIG_SGI_PARTITION is not set
1461# CONFIG_ULTRIX_PARTITION is not set
1462# CONFIG_SUN_PARTITION is not set
1463# CONFIG_KARMA_PARTITION is not set
1464# CONFIG_EFI_PARTITION is not set
1465 1373
1466# 1374#
1467# Native Language Support 1375# Native Language Support
1468# 1376#
1469CONFIG_NLS=y 1377CONFIG_NLS=y
1470CONFIG_NLS_DEFAULT="iso8859-15" 1378CONFIG_NLS_DEFAULT="iso8859-1"
1471# CONFIG_NLS_CODEPAGE_437 is not set 1379CONFIG_NLS_CODEPAGE_437=y
1472# CONFIG_NLS_CODEPAGE_737 is not set 1380# CONFIG_NLS_CODEPAGE_737 is not set
1473# CONFIG_NLS_CODEPAGE_775 is not set 1381# CONFIG_NLS_CODEPAGE_775 is not set
1474CONFIG_NLS_CODEPAGE_850=y 1382# CONFIG_NLS_CODEPAGE_850 is not set
1475# CONFIG_NLS_CODEPAGE_852 is not set 1383# CONFIG_NLS_CODEPAGE_852 is not set
1476# CONFIG_NLS_CODEPAGE_855 is not set 1384# CONFIG_NLS_CODEPAGE_855 is not set
1477# CONFIG_NLS_CODEPAGE_857 is not set 1385# CONFIG_NLS_CODEPAGE_857 is not set
@@ -1491,7 +1399,7 @@ CONFIG_NLS_CODEPAGE_850=y
1491# CONFIG_NLS_ISO8859_8 is not set 1399# CONFIG_NLS_ISO8859_8 is not set
1492# CONFIG_NLS_CODEPAGE_1250 is not set 1400# CONFIG_NLS_CODEPAGE_1250 is not set
1493# CONFIG_NLS_CODEPAGE_1251 is not set 1401# CONFIG_NLS_CODEPAGE_1251 is not set
1494# CONFIG_NLS_ASCII is not set 1402CONFIG_NLS_ASCII=y
1495CONFIG_NLS_ISO8859_1=y 1403CONFIG_NLS_ISO8859_1=y
1496# CONFIG_NLS_ISO8859_2 is not set 1404# CONFIG_NLS_ISO8859_2 is not set
1497# CONFIG_NLS_ISO8859_3 is not set 1405# CONFIG_NLS_ISO8859_3 is not set
@@ -1510,20 +1418,50 @@ CONFIG_NLS_UTF8=y
1510# 1418#
1511# Instrumentation Support 1419# Instrumentation Support
1512# 1420#
1513# CONFIG_PROFILING is not set 1421CONFIG_PROFILING=y
1514# CONFIG_KPROBES is not set 1422CONFIG_OPROFILE=y
1423CONFIG_KPROBES=y
1515 1424
1516# 1425#
1517# Kernel hacking 1426# Kernel hacking
1518# 1427#
1428CONFIG_TRACE_IRQFLAGS_SUPPORT=y
1519# CONFIG_PRINTK_TIME is not set 1429# CONFIG_PRINTK_TIME is not set
1520CONFIG_MAGIC_SYSRQ=y 1430CONFIG_MAGIC_SYSRQ=y
1521# CONFIG_DEBUG_KERNEL is not set 1431CONFIG_UNUSED_SYMBOLS=y
1522CONFIG_LOG_BUF_SHIFT=14 1432CONFIG_DEBUG_KERNEL=y
1433CONFIG_LOG_BUF_SHIFT=18
1434CONFIG_DETECT_SOFTLOCKUP=y
1435# CONFIG_SCHEDSTATS is not set
1436# CONFIG_DEBUG_SLAB is not set
1437# CONFIG_DEBUG_RT_MUTEXES is not set
1438# CONFIG_RT_MUTEX_TESTER is not set
1439# CONFIG_DEBUG_SPINLOCK is not set
1440# CONFIG_DEBUG_MUTEXES is not set
1441# CONFIG_DEBUG_RWSEMS is not set
1442# CONFIG_DEBUG_LOCK_ALLOC is not set
1443# CONFIG_PROVE_LOCKING is not set
1444# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1445# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1446# CONFIG_DEBUG_KOBJECT is not set
1447# CONFIG_DEBUG_HIGHMEM is not set
1523CONFIG_DEBUG_BUGVERBOSE=y 1448CONFIG_DEBUG_BUGVERBOSE=y
1449# CONFIG_DEBUG_INFO is not set
1450# CONFIG_DEBUG_FS is not set
1451# CONFIG_DEBUG_VM is not set
1452# CONFIG_FRAME_POINTER is not set
1453CONFIG_UNWIND_INFO=y
1454CONFIG_STACK_UNWIND=y
1455# CONFIG_FORCED_INLINING is not set
1456# CONFIG_RCU_TORTURE_TEST is not set
1524CONFIG_EARLY_PRINTK=y 1457CONFIG_EARLY_PRINTK=y
1458CONFIG_DEBUG_STACKOVERFLOW=y
1459# CONFIG_DEBUG_STACK_USAGE is not set
1460# CONFIG_DEBUG_RODATA is not set
1461# CONFIG_4KSTACKS is not set
1525CONFIG_X86_FIND_SMP_CONFIG=y 1462CONFIG_X86_FIND_SMP_CONFIG=y
1526CONFIG_X86_MPPARSE=y 1463CONFIG_X86_MPPARSE=y
1464CONFIG_DOUBLEFAULT=y
1527 1465
1528# 1466#
1529# Security options 1467# Security options
@@ -1537,10 +1475,6 @@ CONFIG_X86_MPPARSE=y
1537# CONFIG_CRYPTO is not set 1475# CONFIG_CRYPTO is not set
1538 1476
1539# 1477#
1540# Hardware crypto devices
1541#
1542
1543#
1544# Library routines 1478# Library routines
1545# 1479#
1546# CONFIG_CRC_CCITT is not set 1480# CONFIG_CRC_CCITT is not set
@@ -1548,7 +1482,12 @@ CONFIG_X86_MPPARSE=y
1548CONFIG_CRC32=y 1482CONFIG_CRC32=y
1549# CONFIG_LIBCRC32C is not set 1483# CONFIG_LIBCRC32C is not set
1550CONFIG_ZLIB_INFLATE=y 1484CONFIG_ZLIB_INFLATE=y
1485CONFIG_PLIST=y
1551CONFIG_GENERIC_HARDIRQS=y 1486CONFIG_GENERIC_HARDIRQS=y
1552CONFIG_GENERIC_IRQ_PROBE=y 1487CONFIG_GENERIC_IRQ_PROBE=y
1488CONFIG_GENERIC_PENDING_IRQ=y
1489CONFIG_X86_SMP=y
1490CONFIG_X86_HT=y
1553CONFIG_X86_BIOS_REBOOT=y 1491CONFIG_X86_BIOS_REBOOT=y
1492CONFIG_X86_TRAMPOLINE=y
1554CONFIG_KTIME_SCALAR=y 1493CONFIG_KTIME_SCALAR=y
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index 5427a842e841..1a884b6e6e5c 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -4,7 +4,7 @@
4 4
5extra-y := head.o init_task.o vmlinux.lds 5extra-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 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 bootflag.o \ 9 pci-dma.o i386_ksyms.o i387.o bootflag.o \
10 quirks.o i8237.o topology.o alternative.o i8253.o tsc.o 10 quirks.o i8237.o topology.o alternative.o i8253.o tsc.o
@@ -81,4 +81,5 @@ $(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \
81 $(call if_changed,syscall) 81 $(call if_changed,syscall)
82 82
83k8-y += ../../x86_64/kernel/k8.o 83k8-y += ../../x86_64/kernel/k8.o
84stacktrace-y += ../../x86_64/kernel/stacktrace.o
84 85
diff --git a/arch/i386/kernel/acpi/Makefile b/arch/i386/kernel/acpi/Makefile
index 7e9ac99354f4..7f7be01f44e6 100644
--- a/arch/i386/kernel/acpi/Makefile
+++ b/arch/i386/kernel/acpi/Makefile
@@ -1,5 +1,7 @@
1obj-$(CONFIG_ACPI) += boot.o 1obj-$(CONFIG_ACPI) += boot.o
2ifneq ($(CONFIG_PCI),)
2obj-$(CONFIG_X86_IO_APIC) += earlyquirk.o 3obj-$(CONFIG_X86_IO_APIC) += earlyquirk.o
4endif
3obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o 5obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o
4 6
5ifneq ($(CONFIG_ACPI_PROCESSOR),) 7ifneq ($(CONFIG_ACPI_PROCESSOR),)
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index ee003bc0e8b1..1aaea6ab8c46 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -26,9 +26,12 @@
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/acpi.h> 27#include <linux/acpi.h>
28#include <linux/efi.h> 28#include <linux/efi.h>
29#include <linux/cpumask.h>
29#include <linux/module.h> 30#include <linux/module.h>
30#include <linux/dmi.h> 31#include <linux/dmi.h>
31#include <linux/irq.h> 32#include <linux/irq.h>
33#include <linux/bootmem.h>
34#include <linux/ioport.h>
32 35
33#include <asm/pgtable.h> 36#include <asm/pgtable.h>
34#include <asm/io_apic.h> 37#include <asm/io_apic.h>
@@ -36,11 +39,17 @@
36#include <asm/io.h> 39#include <asm/io.h>
37#include <asm/mpspec.h> 40#include <asm/mpspec.h>
38 41
39#ifdef CONFIG_X86_64 42static int __initdata acpi_force = 0;
40 43
41extern void __init clustered_apic_check(void); 44#ifdef CONFIG_ACPI
45int acpi_disabled = 0;
46#else
47int acpi_disabled = 1;
48#endif
49EXPORT_SYMBOL(acpi_disabled);
50
51#ifdef CONFIG_X86_64
42 52
43extern int gsi_irq_sharing(int gsi);
44#include <asm/proto.h> 53#include <asm/proto.h>
45 54
46static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return 0; } 55static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return 0; }
@@ -506,16 +515,76 @@ EXPORT_SYMBOL(acpi_register_gsi);
506#ifdef CONFIG_ACPI_HOTPLUG_CPU 515#ifdef CONFIG_ACPI_HOTPLUG_CPU
507int acpi_map_lsapic(acpi_handle handle, int *pcpu) 516int acpi_map_lsapic(acpi_handle handle, int *pcpu)
508{ 517{
509 /* TBD */ 518 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
510 return -EINVAL; 519 union acpi_object *obj;
520 struct acpi_table_lapic *lapic;
521 cpumask_t tmp_map, new_map;
522 u8 physid;
523 int cpu;
524
525 if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer)))
526 return -EINVAL;
527
528 if (!buffer.length || !buffer.pointer)
529 return -EINVAL;
530
531 obj = buffer.pointer;
532 if (obj->type != ACPI_TYPE_BUFFER ||
533 obj->buffer.length < sizeof(*lapic)) {
534 kfree(buffer.pointer);
535 return -EINVAL;
536 }
537
538 lapic = (struct acpi_table_lapic *)obj->buffer.pointer;
539
540 if ((lapic->header.type != ACPI_MADT_LAPIC) ||
541 (!lapic->flags.enabled)) {
542 kfree(buffer.pointer);
543 return -EINVAL;
544 }
545
546 physid = lapic->id;
547
548 kfree(buffer.pointer);
549 buffer.length = ACPI_ALLOCATE_BUFFER;
550 buffer.pointer = NULL;
551
552 tmp_map = cpu_present_map;
553 mp_register_lapic(physid, lapic->flags.enabled);
554
555 /*
556 * If mp_register_lapic successfully generates a new logical cpu
557 * number, then the following will get us exactly what was mapped
558 */
559 cpus_andnot(new_map, cpu_present_map, tmp_map);
560 if (cpus_empty(new_map)) {
561 printk ("Unable to map lapic to logical cpu number\n");
562 return -EINVAL;
563 }
564
565 cpu = first_cpu(new_map);
566
567 *pcpu = cpu;
568 return 0;
511} 569}
512 570
513EXPORT_SYMBOL(acpi_map_lsapic); 571EXPORT_SYMBOL(acpi_map_lsapic);
514 572
515int acpi_unmap_lsapic(int cpu) 573int acpi_unmap_lsapic(int cpu)
516{ 574{
517 /* TBD */ 575 int i;
518 return -EINVAL; 576
577 for_each_possible_cpu(i) {
578 if (x86_acpiid_to_apicid[i] == x86_cpu_to_apicid[cpu]) {
579 x86_acpiid_to_apicid[i] = -1;
580 break;
581 }
582 }
583 x86_cpu_to_apicid[cpu] = -1;
584 cpu_clear(cpu, cpu_present_map);
585 num_processors--;
586
587 return (0);
519} 588}
520 589
521EXPORT_SYMBOL(acpi_unmap_lsapic); 590EXPORT_SYMBOL(acpi_unmap_lsapic);
@@ -579,6 +648,8 @@ static int __init acpi_parse_sbf(unsigned long phys_addr, unsigned long size)
579static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) 648static int __init acpi_parse_hpet(unsigned long phys, unsigned long size)
580{ 649{
581 struct acpi_table_hpet *hpet_tbl; 650 struct acpi_table_hpet *hpet_tbl;
651 struct resource *hpet_res;
652 resource_size_t res_start;
582 653
583 if (!phys || !size) 654 if (!phys || !size)
584 return -EINVAL; 655 return -EINVAL;
@@ -594,12 +665,26 @@ static int __init acpi_parse_hpet(unsigned long phys, unsigned long size)
594 "memory.\n"); 665 "memory.\n");
595 return -1; 666 return -1;
596 } 667 }
668
669#define HPET_RESOURCE_NAME_SIZE 9
670 hpet_res = alloc_bootmem(sizeof(*hpet_res) + HPET_RESOURCE_NAME_SIZE);
671 if (hpet_res) {
672 memset(hpet_res, 0, sizeof(*hpet_res));
673 hpet_res->name = (void *)&hpet_res[1];
674 hpet_res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
675 snprintf((char *)hpet_res->name, HPET_RESOURCE_NAME_SIZE,
676 "HPET %u", hpet_tbl->number);
677 hpet_res->end = (1 * 1024) - 1;
678 }
679
597#ifdef CONFIG_X86_64 680#ifdef CONFIG_X86_64
598 vxtime.hpet_address = hpet_tbl->addr.addrl | 681 vxtime.hpet_address = hpet_tbl->addr.addrl |
599 ((long)hpet_tbl->addr.addrh << 32); 682 ((long)hpet_tbl->addr.addrh << 32);
600 683
601 printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", 684 printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n",
602 hpet_tbl->id, vxtime.hpet_address); 685 hpet_tbl->id, vxtime.hpet_address);
686
687 res_start = vxtime.hpet_address;
603#else /* X86 */ 688#else /* X86 */
604 { 689 {
605 extern unsigned long hpet_address; 690 extern unsigned long hpet_address;
@@ -607,9 +692,17 @@ static int __init acpi_parse_hpet(unsigned long phys, unsigned long size)
607 hpet_address = hpet_tbl->addr.addrl; 692 hpet_address = hpet_tbl->addr.addrl;
608 printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", 693 printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n",
609 hpet_tbl->id, hpet_address); 694 hpet_tbl->id, hpet_address);
695
696 res_start = hpet_address;
610 } 697 }
611#endif /* X86 */ 698#endif /* X86 */
612 699
700 if (hpet_res) {
701 hpet_res->start = res_start;
702 hpet_res->end += res_start;
703 insert_resource(&iomem_resource, hpet_res);
704 }
705
613 return 0; 706 return 0;
614} 707}
615#else 708#else
@@ -860,8 +953,6 @@ static void __init acpi_process_madt(void)
860 return; 953 return;
861} 954}
862 955
863extern int acpi_force;
864
865#ifdef __i386__ 956#ifdef __i386__
866 957
867static int __init disable_acpi_irq(struct dmi_system_id *d) 958static int __init disable_acpi_irq(struct dmi_system_id *d)
@@ -1163,3 +1254,75 @@ int __init acpi_boot_init(void)
1163 1254
1164 return 0; 1255 return 0;
1165} 1256}
1257
1258static int __init parse_acpi(char *arg)
1259{
1260 if (!arg)
1261 return -EINVAL;
1262
1263 /* "acpi=off" disables both ACPI table parsing and interpreter */
1264 if (strcmp(arg, "off") == 0) {
1265 disable_acpi();
1266 }
1267 /* acpi=force to over-ride black-list */
1268 else if (strcmp(arg, "force") == 0) {
1269 acpi_force = 1;
1270 acpi_ht = 1;
1271 acpi_disabled = 0;
1272 }
1273 /* acpi=strict disables out-of-spec workarounds */
1274 else if (strcmp(arg, "strict") == 0) {
1275 acpi_strict = 1;
1276 }
1277 /* Limit ACPI just to boot-time to enable HT */
1278 else if (strcmp(arg, "ht") == 0) {
1279 if (!acpi_force)
1280 disable_acpi();
1281 acpi_ht = 1;
1282 }
1283 /* "acpi=noirq" disables ACPI interrupt routing */
1284 else if (strcmp(arg, "noirq") == 0) {
1285 acpi_noirq_set();
1286 } else {
1287 /* Core will printk when we return error. */
1288 return -EINVAL;
1289 }
1290 return 0;
1291}
1292early_param("acpi", parse_acpi);
1293
1294/* FIXME: Using pci= for an ACPI parameter is a travesty. */
1295static int __init parse_pci(char *arg)
1296{
1297 if (arg && strcmp(arg, "noacpi") == 0)
1298 acpi_disable_pci();
1299 return 0;
1300}
1301early_param("pci", parse_pci);
1302
1303#ifdef CONFIG_X86_IO_APIC
1304static int __init parse_acpi_skip_timer_override(char *arg)
1305{
1306 acpi_skip_timer_override = 1;
1307 return 0;
1308}
1309early_param("acpi_skip_timer_override", parse_acpi_skip_timer_override);
1310#endif /* CONFIG_X86_IO_APIC */
1311
1312static int __init setup_acpi_sci(char *s)
1313{
1314 if (!s)
1315 return -EINVAL;
1316 if (!strcmp(s, "edge"))
1317 acpi_sci_flags.trigger = 1;
1318 else if (!strcmp(s, "level"))
1319 acpi_sci_flags.trigger = 3;
1320 else if (!strcmp(s, "high"))
1321 acpi_sci_flags.polarity = 1;
1322 else if (!strcmp(s, "low"))
1323 acpi_sci_flags.polarity = 3;
1324 else
1325 return -EINVAL;
1326 return 0;
1327}
1328early_param("acpi_sci", setup_acpi_sci);
diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c
index 1649a175a206..fe799b11ac0a 100644
--- a/arch/i386/kernel/acpi/earlyquirk.c
+++ b/arch/i386/kernel/acpi/earlyquirk.c
@@ -48,7 +48,11 @@ void __init check_acpi_pci(void)
48 int num, slot, func; 48 int num, slot, func;
49 49
50 /* Assume the machine supports type 1. If not it will 50 /* Assume the machine supports type 1. If not it will
51 always read ffffffff and should not have any side effect. */ 51 always read ffffffff and should not have any side effect.
52 Actually a few buggy systems can machine check. Allow the user
53 to disable it by command line option at least -AK */
54 if (!early_pci_allowed())
55 return;
52 56
53 /* Poor man's PCI discovery */ 57 /* Poor man's PCI discovery */
54 for (num = 0; num < 32; num++) { 58 for (num = 0; num < 32; num++) {
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 8c844d07862f..90faae5c5d30 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -52,7 +52,18 @@ static cpumask_t timer_bcast_ipi;
52/* 52/*
53 * Knob to control our willingness to enable the local APIC. 53 * Knob to control our willingness to enable the local APIC.
54 */ 54 */
55int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ 55static int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */
56
57static inline void lapic_disable(void)
58{
59 enable_local_apic = -1;
60 clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
61}
62
63static inline void lapic_enable(void)
64{
65 enable_local_apic = 1;
66}
56 67
57/* 68/*
58 * Debug level 69 * Debug level
@@ -586,8 +597,7 @@ void __devinit setup_local_APIC(void)
586 printk("No ESR for 82489DX.\n"); 597 printk("No ESR for 82489DX.\n");
587 } 598 }
588 599
589 if (nmi_watchdog == NMI_LOCAL_APIC) 600 setup_apic_nmi_watchdog(NULL);
590 setup_apic_nmi_watchdog();
591 apic_pm_activate(); 601 apic_pm_activate();
592} 602}
593 603
@@ -1373,3 +1383,18 @@ int __init APIC_init_uniprocessor (void)
1373 1383
1374 return 0; 1384 return 0;
1375} 1385}
1386
1387static int __init parse_lapic(char *arg)
1388{
1389 lapic_enable();
1390 return 0;
1391}
1392early_param("lapic", parse_lapic);
1393
1394static int __init parse_nolapic(char *arg)
1395{
1396 lapic_disable();
1397 return 0;
1398}
1399early_param("nolapic", parse_nolapic);
1400
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 8591f2fa920c..ff9ce4b5eaa8 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -1154,9 +1154,11 @@ out:
1154 1154
1155static void set_time(void) 1155static void set_time(void)
1156{ 1156{
1157 struct timespec ts;
1157 if (got_clock_diff) { /* Must know time zone in order to set clock */ 1158 if (got_clock_diff) { /* Must know time zone in order to set clock */
1158 xtime.tv_sec = get_cmos_time() + clock_cmos_diff; 1159 ts.tv_sec = get_cmos_time() + clock_cmos_diff;
1159 xtime.tv_nsec = 0; 1160 ts.tv_nsec = 0;
1161 do_settimeofday(&ts);
1160 } 1162 }
1161} 1163}
1162 1164
@@ -1232,13 +1234,8 @@ static int suspend(int vetoable)
1232 restore_processor_state(); 1234 restore_processor_state();
1233 1235
1234 local_irq_disable(); 1236 local_irq_disable();
1235 write_seqlock(&xtime_lock);
1236 spin_lock(&i8253_lock);
1237 reinit_timer();
1238 set_time(); 1237 set_time();
1239 1238 reinit_timer();
1240 spin_unlock(&i8253_lock);
1241 write_sequnlock(&xtime_lock);
1242 1239
1243 if (err == APM_NO_ERROR) 1240 if (err == APM_NO_ERROR)
1244 err = APM_SUCCESS; 1241 err = APM_SUCCESS;
@@ -1365,9 +1362,7 @@ static void check_events(void)
1365 ignore_bounce = 1; 1362 ignore_bounce = 1;
1366 if ((event != APM_NORMAL_RESUME) 1363 if ((event != APM_NORMAL_RESUME)
1367 || (ignore_normal_resume == 0)) { 1364 || (ignore_normal_resume == 0)) {
1368 write_seqlock_irq(&xtime_lock);
1369 set_time(); 1365 set_time();
1370 write_sequnlock_irq(&xtime_lock);
1371 device_resume(); 1366 device_resume();
1372 pm_send_all(PM_RESUME, (void *)0); 1367 pm_send_all(PM_RESUME, (void *)0);
1373 queue_event(event, NULL); 1368 queue_event(event, NULL);
@@ -1383,9 +1378,7 @@ static void check_events(void)
1383 break; 1378 break;
1384 1379
1385 case APM_UPDATE_TIME: 1380 case APM_UPDATE_TIME:
1386 write_seqlock_irq(&xtime_lock);
1387 set_time(); 1381 set_time();
1388 write_sequnlock_irq(&xtime_lock);
1389 break; 1382 break;
1390 1383
1391 case APM_CRITICAL_SUSPEND: 1384 case APM_CRITICAL_SUSPEND:
@@ -2339,6 +2332,7 @@ static int __init apm_init(void)
2339 ret = kernel_thread(apm, NULL, CLONE_KERNEL | SIGCHLD); 2332 ret = kernel_thread(apm, NULL, CLONE_KERNEL | SIGCHLD);
2340 if (ret < 0) { 2333 if (ret < 0) {
2341 printk(KERN_ERR "apm: disabled - Unable to start kernel thread.\n"); 2334 printk(KERN_ERR "apm: disabled - Unable to start kernel thread.\n");
2335 remove_proc_entry("apm", NULL);
2342 return -ENOMEM; 2336 return -ENOMEM;
2343 } 2337 }
2344 2338
@@ -2348,7 +2342,13 @@ static int __init apm_init(void)
2348 return 0; 2342 return 0;
2349 } 2343 }
2350 2344
2351 misc_register(&apm_device); 2345 /*
2346 * Note we don't actually care if the misc_device cannot be registered.
2347 * this driver can do its job without it, even if userspace can't
2348 * control it. just log the error
2349 */
2350 if (misc_register(&apm_device))
2351 printk(KERN_WARNING "apm: Could not register misc device.\n");
2352 2352
2353 if (HZ != 100) 2353 if (HZ != 100)
2354 idle_period = (idle_period * HZ) / 100; 2354 idle_period = (idle_period * HZ) / 100;
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index e6a2d6b80cda..e4758095d87a 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -22,7 +22,7 @@
22extern void vide(void); 22extern void vide(void);
23__asm__(".align 4\nvide: ret"); 23__asm__(".align 4\nvide: ret");
24 24
25static void __init init_amd(struct cpuinfo_x86 *c) 25static void __cpuinit init_amd(struct cpuinfo_x86 *c)
26{ 26{
27 u32 l, h; 27 u32 l, h;
28 int mbytes = num_physpages >> (20-PAGE_SHIFT); 28 int mbytes = num_physpages >> (20-PAGE_SHIFT);
@@ -246,7 +246,7 @@ static void __init init_amd(struct cpuinfo_x86 *c)
246 num_cache_leaves = 3; 246 num_cache_leaves = 3;
247} 247}
248 248
249static unsigned int amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) 249static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size)
250{ 250{
251 /* AMD errata T13 (order #21922) */ 251 /* AMD errata T13 (order #21922) */
252 if ((c->x86 == 6)) { 252 if ((c->x86 == 6)) {
@@ -259,7 +259,7 @@ static unsigned int amd_size_cache(struct cpuinfo_x86 * c, unsigned int size)
259 return size; 259 return size;
260} 260}
261 261
262static struct cpu_dev amd_cpu_dev __initdata = { 262static struct cpu_dev amd_cpu_dev __cpuinitdata = {
263 .c_vendor = "AMD", 263 .c_vendor = "AMD",
264 .c_ident = { "AuthenticAMD" }, 264 .c_ident = { "AuthenticAMD" },
265 .c_models = { 265 .c_models = {
@@ -275,7 +275,6 @@ static struct cpu_dev amd_cpu_dev __initdata = {
275 }, 275 },
276 }, 276 },
277 .c_init = init_amd, 277 .c_init = init_amd,
278 .c_identify = generic_identify,
279 .c_size_cache = amd_size_cache, 278 .c_size_cache = amd_size_cache,
280}; 279};
281 280
diff --git a/arch/i386/kernel/cpu/centaur.c b/arch/i386/kernel/cpu/centaur.c
index bd75629dd262..8c25047975c0 100644
--- a/arch/i386/kernel/cpu/centaur.c
+++ b/arch/i386/kernel/cpu/centaur.c
@@ -9,7 +9,7 @@
9 9
10#ifdef CONFIG_X86_OOSTORE 10#ifdef CONFIG_X86_OOSTORE
11 11
12static u32 __init power2(u32 x) 12static u32 __cpuinit power2(u32 x)
13{ 13{
14 u32 s=1; 14 u32 s=1;
15 while(s<=x) 15 while(s<=x)
@@ -22,7 +22,7 @@ static u32 __init power2(u32 x)
22 * Set up an actual MCR 22 * Set up an actual MCR
23 */ 23 */
24 24
25static void __init centaur_mcr_insert(int reg, u32 base, u32 size, int key) 25static void __cpuinit centaur_mcr_insert(int reg, u32 base, u32 size, int key)
26{ 26{
27 u32 lo, hi; 27 u32 lo, hi;
28 28
@@ -40,7 +40,7 @@ static void __init centaur_mcr_insert(int reg, u32 base, u32 size, int key)
40 * Shortcut: We know you can't put 4Gig of RAM on a winchip 40 * Shortcut: We know you can't put 4Gig of RAM on a winchip
41 */ 41 */
42 42
43static u32 __init ramtop(void) /* 16388 */ 43static u32 __cpuinit ramtop(void) /* 16388 */
44{ 44{
45 int i; 45 int i;
46 u32 top = 0; 46 u32 top = 0;
@@ -91,7 +91,7 @@ static u32 __init ramtop(void) /* 16388 */
91 * Compute a set of MCR's to give maximum coverage 91 * Compute a set of MCR's to give maximum coverage
92 */ 92 */
93 93
94static int __init centaur_mcr_compute(int nr, int key) 94static int __cpuinit centaur_mcr_compute(int nr, int key)
95{ 95{
96 u32 mem = ramtop(); 96 u32 mem = ramtop();
97 u32 root = power2(mem); 97 u32 root = power2(mem);
@@ -166,7 +166,7 @@ static int __init centaur_mcr_compute(int nr, int key)
166 return ct; 166 return ct;
167} 167}
168 168
169static void __init centaur_create_optimal_mcr(void) 169static void __cpuinit centaur_create_optimal_mcr(void)
170{ 170{
171 int i; 171 int i;
172 /* 172 /*
@@ -189,7 +189,7 @@ static void __init centaur_create_optimal_mcr(void)
189 wrmsr(MSR_IDT_MCR0+i, 0, 0); 189 wrmsr(MSR_IDT_MCR0+i, 0, 0);
190} 190}
191 191
192static void __init winchip2_create_optimal_mcr(void) 192static void __cpuinit winchip2_create_optimal_mcr(void)
193{ 193{
194 u32 lo, hi; 194 u32 lo, hi;
195 int i; 195 int i;
@@ -227,7 +227,7 @@ static void __init winchip2_create_optimal_mcr(void)
227 * Handle the MCR key on the Winchip 2. 227 * Handle the MCR key on the Winchip 2.
228 */ 228 */
229 229
230static void __init winchip2_unprotect_mcr(void) 230static void __cpuinit winchip2_unprotect_mcr(void)
231{ 231{
232 u32 lo, hi; 232 u32 lo, hi;
233 u32 key; 233 u32 key;
@@ -239,7 +239,7 @@ static void __init winchip2_unprotect_mcr(void)
239 wrmsr(MSR_IDT_MCR_CTRL, lo, hi); 239 wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
240} 240}
241 241
242static void __init winchip2_protect_mcr(void) 242static void __cpuinit winchip2_protect_mcr(void)
243{ 243{
244 u32 lo, hi; 244 u32 lo, hi;
245 245
@@ -257,7 +257,7 @@ static void __init winchip2_protect_mcr(void)
257#define RNG_ENABLED (1 << 3) 257#define RNG_ENABLED (1 << 3)
258#define RNG_ENABLE (1 << 6) /* MSR_VIA_RNG */ 258#define RNG_ENABLE (1 << 6) /* MSR_VIA_RNG */
259 259
260static void __init init_c3(struct cpuinfo_x86 *c) 260static void __cpuinit init_c3(struct cpuinfo_x86 *c)
261{ 261{
262 u32 lo, hi; 262 u32 lo, hi;
263 263
@@ -303,7 +303,7 @@ static void __init init_c3(struct cpuinfo_x86 *c)
303 display_cacheinfo(c); 303 display_cacheinfo(c);
304} 304}
305 305
306static void __init init_centaur(struct cpuinfo_x86 *c) 306static void __cpuinit init_centaur(struct cpuinfo_x86 *c)
307{ 307{
308 enum { 308 enum {
309 ECX8=1<<1, 309 ECX8=1<<1,
@@ -442,7 +442,7 @@ static void __init init_centaur(struct cpuinfo_x86 *c)
442 } 442 }
443} 443}
444 444
445static unsigned int centaur_size_cache(struct cpuinfo_x86 * c, unsigned int size) 445static unsigned int __cpuinit centaur_size_cache(struct cpuinfo_x86 * c, unsigned int size)
446{ 446{
447 /* VIA C3 CPUs (670-68F) need further shifting. */ 447 /* VIA C3 CPUs (670-68F) need further shifting. */
448 if ((c->x86 == 6) && ((c->x86_model == 7) || (c->x86_model == 8))) 448 if ((c->x86 == 6) && ((c->x86_model == 7) || (c->x86_model == 8)))
@@ -457,7 +457,7 @@ static unsigned int centaur_size_cache(struct cpuinfo_x86 * c, unsigned int size
457 return size; 457 return size;
458} 458}
459 459
460static struct cpu_dev centaur_cpu_dev __initdata = { 460static struct cpu_dev centaur_cpu_dev __cpuinitdata = {
461 .c_vendor = "Centaur", 461 .c_vendor = "Centaur",
462 .c_ident = { "CentaurHauls" }, 462 .c_ident = { "CentaurHauls" },
463 .c_init = init_centaur, 463 .c_init = init_centaur,
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 70c87de582c7..2799baaadf45 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -36,7 +36,7 @@ struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
36 36
37extern int disable_pse; 37extern int disable_pse;
38 38
39static void default_init(struct cpuinfo_x86 * c) 39static void __cpuinit default_init(struct cpuinfo_x86 * c)
40{ 40{
41 /* Not much we can do here... */ 41 /* Not much we can do here... */
42 /* Check if at least it has cpuid */ 42 /* Check if at least it has cpuid */
@@ -49,7 +49,7 @@ static void default_init(struct cpuinfo_x86 * c)
49 } 49 }
50} 50}
51 51
52static struct cpu_dev default_cpu = { 52static struct cpu_dev __cpuinitdata default_cpu = {
53 .c_init = default_init, 53 .c_init = default_init,
54 .c_vendor = "Unknown", 54 .c_vendor = "Unknown",
55}; 55};
@@ -265,7 +265,7 @@ static void __init early_cpu_detect(void)
265 } 265 }
266} 266}
267 267
268void __cpuinit generic_identify(struct cpuinfo_x86 * c) 268static void __cpuinit generic_identify(struct cpuinfo_x86 * c)
269{ 269{
270 u32 tfms, xlvl; 270 u32 tfms, xlvl;
271 int ebx; 271 int ebx;
@@ -675,7 +675,7 @@ old_gdt:
675#endif 675#endif
676 676
677 /* Clear %fs and %gs. */ 677 /* Clear %fs and %gs. */
678 asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs"); 678 asm volatile ("movl %0, %%fs; movl %0, %%gs" : : "r" (0));
679 679
680 /* Clear all 6 debug registers: */ 680 /* Clear all 6 debug registers: */
681 set_debugreg(0, 0); 681 set_debugreg(0, 0);
diff --git a/arch/i386/kernel/cpu/cpu.h b/arch/i386/kernel/cpu/cpu.h
index 5a1d4f163e84..2f6432cef6ff 100644
--- a/arch/i386/kernel/cpu/cpu.h
+++ b/arch/i386/kernel/cpu/cpu.h
@@ -24,7 +24,5 @@ extern struct cpu_dev * cpu_devs [X86_VENDOR_NUM];
24extern int get_model_name(struct cpuinfo_x86 *c); 24extern int get_model_name(struct cpuinfo_x86 *c);
25extern void display_cacheinfo(struct cpuinfo_x86 *c); 25extern void display_cacheinfo(struct cpuinfo_x86 *c);
26 26
27extern void generic_identify(struct cpuinfo_x86 * c);
28
29extern void early_intel_workaround(struct cpuinfo_x86 *c); 27extern void early_intel_workaround(struct cpuinfo_x86 *c);
30 28
diff --git a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c
index f03b7f94c304..c0c3b59de32c 100644
--- a/arch/i386/kernel/cpu/cyrix.c
+++ b/arch/i386/kernel/cpu/cyrix.c
@@ -12,7 +12,7 @@
12/* 12/*
13 * Read NSC/Cyrix DEVID registers (DIR) to get more detailed info. about the CPU 13 * Read NSC/Cyrix DEVID registers (DIR) to get more detailed info. about the CPU
14 */ 14 */
15static void __init do_cyrix_devid(unsigned char *dir0, unsigned char *dir1) 15static void __cpuinit do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
16{ 16{
17 unsigned char ccr2, ccr3; 17 unsigned char ccr2, ccr3;
18 unsigned long flags; 18 unsigned long flags;
@@ -52,25 +52,25 @@ static void __init do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
52 * Actually since bugs.h doesn't even reference this perhaps someone should 52 * Actually since bugs.h doesn't even reference this perhaps someone should
53 * fix the documentation ??? 53 * fix the documentation ???
54 */ 54 */
55static unsigned char Cx86_dir0_msb __initdata = 0; 55static unsigned char Cx86_dir0_msb __cpuinitdata = 0;
56 56
57static char Cx86_model[][9] __initdata = { 57static char Cx86_model[][9] __cpuinitdata = {
58 "Cx486", "Cx486", "5x86 ", "6x86", "MediaGX ", "6x86MX ", 58 "Cx486", "Cx486", "5x86 ", "6x86", "MediaGX ", "6x86MX ",
59 "M II ", "Unknown" 59 "M II ", "Unknown"
60}; 60};
61static char Cx486_name[][5] __initdata = { 61static char Cx486_name[][5] __cpuinitdata = {
62 "SLC", "DLC", "SLC2", "DLC2", "SRx", "DRx", 62 "SLC", "DLC", "SLC2", "DLC2", "SRx", "DRx",
63 "SRx2", "DRx2" 63 "SRx2", "DRx2"
64}; 64};
65static char Cx486S_name[][4] __initdata = { 65static char Cx486S_name[][4] __cpuinitdata = {
66 "S", "S2", "Se", "S2e" 66 "S", "S2", "Se", "S2e"
67}; 67};
68static char Cx486D_name[][4] __initdata = { 68static char Cx486D_name[][4] __cpuinitdata = {
69 "DX", "DX2", "?", "?", "?", "DX4" 69 "DX", "DX2", "?", "?", "?", "DX4"
70}; 70};
71static char Cx86_cb[] __initdata = "?.5x Core/Bus Clock"; 71static char Cx86_cb[] __cpuinitdata = "?.5x Core/Bus Clock";
72static char cyrix_model_mult1[] __initdata = "12??43"; 72static char cyrix_model_mult1[] __cpuinitdata = "12??43";
73static char cyrix_model_mult2[] __initdata = "12233445"; 73static char cyrix_model_mult2[] __cpuinitdata = "12233445";
74 74
75/* 75/*
76 * Reset the slow-loop (SLOP) bit on the 686(L) which is set by some old 76 * Reset the slow-loop (SLOP) bit on the 686(L) which is set by some old
@@ -82,7 +82,7 @@ static char cyrix_model_mult2[] __initdata = "12233445";
82 82
83extern void calibrate_delay(void) __init; 83extern void calibrate_delay(void) __init;
84 84
85static void __init check_cx686_slop(struct cpuinfo_x86 *c) 85static void __cpuinit check_cx686_slop(struct cpuinfo_x86 *c)
86{ 86{
87 unsigned long flags; 87 unsigned long flags;
88 88
@@ -107,7 +107,7 @@ static void __init check_cx686_slop(struct cpuinfo_x86 *c)
107} 107}
108 108
109 109
110static void __init set_cx86_reorder(void) 110static void __cpuinit set_cx86_reorder(void)
111{ 111{
112 u8 ccr3; 112 u8 ccr3;
113 113
@@ -122,7 +122,7 @@ static void __init set_cx86_reorder(void)
122 setCx86(CX86_CCR3, ccr3); 122 setCx86(CX86_CCR3, ccr3);
123} 123}
124 124
125static void __init set_cx86_memwb(void) 125static void __cpuinit set_cx86_memwb(void)
126{ 126{
127 u32 cr0; 127 u32 cr0;
128 128
@@ -137,7 +137,7 @@ static void __init set_cx86_memwb(void)
137 setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x14 ); 137 setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x14 );
138} 138}
139 139
140static void __init set_cx86_inc(void) 140static void __cpuinit set_cx86_inc(void)
141{ 141{
142 unsigned char ccr3; 142 unsigned char ccr3;
143 143
@@ -158,7 +158,7 @@ static void __init set_cx86_inc(void)
158 * Configure later MediaGX and/or Geode processor. 158 * Configure later MediaGX and/or Geode processor.
159 */ 159 */
160 160
161static void __init geode_configure(void) 161static void __cpuinit geode_configure(void)
162{ 162{
163 unsigned long flags; 163 unsigned long flags;
164 u8 ccr3, ccr4; 164 u8 ccr3, ccr4;
@@ -184,14 +184,14 @@ static void __init geode_configure(void)
184 184
185 185
186#ifdef CONFIG_PCI 186#ifdef CONFIG_PCI
187static struct pci_device_id __initdata cyrix_55x0[] = { 187static struct pci_device_id __cpuinitdata cyrix_55x0[] = {
188 { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510) }, 188 { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510) },
189 { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520) }, 189 { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520) },
190 { }, 190 { },
191}; 191};
192#endif 192#endif
193 193
194static void __init init_cyrix(struct cpuinfo_x86 *c) 194static void __cpuinit init_cyrix(struct cpuinfo_x86 *c)
195{ 195{
196 unsigned char dir0, dir0_msn, dir0_lsn, dir1 = 0; 196 unsigned char dir0, dir0_msn, dir0_lsn, dir1 = 0;
197 char *buf = c->x86_model_id; 197 char *buf = c->x86_model_id;
@@ -346,7 +346,7 @@ static void __init init_cyrix(struct cpuinfo_x86 *c)
346/* 346/*
347 * Handle National Semiconductor branded processors 347 * Handle National Semiconductor branded processors
348 */ 348 */
349static void __init init_nsc(struct cpuinfo_x86 *c) 349static void __cpuinit init_nsc(struct cpuinfo_x86 *c)
350{ 350{
351 /* There may be GX1 processors in the wild that are branded 351 /* There may be GX1 processors in the wild that are branded
352 * NSC and not Cyrix. 352 * NSC and not Cyrix.
@@ -394,7 +394,7 @@ static inline int test_cyrix_52div(void)
394 return (unsigned char) (test >> 8) == 0x02; 394 return (unsigned char) (test >> 8) == 0x02;
395} 395}
396 396
397static void cyrix_identify(struct cpuinfo_x86 * c) 397static void __cpuinit cyrix_identify(struct cpuinfo_x86 * c)
398{ 398{
399 /* Detect Cyrix with disabled CPUID */ 399 /* Detect Cyrix with disabled CPUID */
400 if ( c->x86 == 4 && test_cyrix_52div() ) { 400 if ( c->x86 == 4 && test_cyrix_52div() ) {
@@ -427,10 +427,9 @@ static void cyrix_identify(struct cpuinfo_x86 * c)
427 local_irq_restore(flags); 427 local_irq_restore(flags);
428 } 428 }
429 } 429 }
430 generic_identify(c);
431} 430}
432 431
433static struct cpu_dev cyrix_cpu_dev __initdata = { 432static struct cpu_dev cyrix_cpu_dev __cpuinitdata = {
434 .c_vendor = "Cyrix", 433 .c_vendor = "Cyrix",
435 .c_ident = { "CyrixInstead" }, 434 .c_ident = { "CyrixInstead" },
436 .c_init = init_cyrix, 435 .c_init = init_cyrix,
@@ -453,11 +452,10 @@ static int __init cyrix_exit_cpu(void)
453 452
454late_initcall(cyrix_exit_cpu); 453late_initcall(cyrix_exit_cpu);
455 454
456static struct cpu_dev nsc_cpu_dev __initdata = { 455static struct cpu_dev nsc_cpu_dev __cpuinitdata = {
457 .c_vendor = "NSC", 456 .c_vendor = "NSC",
458 .c_ident = { "Geode by NSC" }, 457 .c_ident = { "Geode by NSC" },
459 .c_init = init_nsc, 458 .c_init = init_nsc,
460 .c_identify = generic_identify,
461}; 459};
462 460
463int __init nsc_init_cpu(void) 461int __init nsc_init_cpu(void)
diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c
index 5a2e270924b1..94a95aa5227e 100644
--- a/arch/i386/kernel/cpu/intel.c
+++ b/arch/i386/kernel/cpu/intel.c
@@ -198,7 +198,7 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
198} 198}
199 199
200 200
201static unsigned int intel_size_cache(struct cpuinfo_x86 * c, unsigned int size) 201static unsigned int __cpuinit intel_size_cache(struct cpuinfo_x86 * c, unsigned int size)
202{ 202{
203 /* Intel PIII Tualatin. This comes in two flavours. 203 /* Intel PIII Tualatin. This comes in two flavours.
204 * One has 256kb of cache, the other 512. We have no way 204 * One has 256kb of cache, the other 512. We have no way
@@ -263,7 +263,6 @@ static struct cpu_dev intel_cpu_dev __cpuinitdata = {
263 }, 263 },
264 }, 264 },
265 .c_init = init_intel, 265 .c_init = init_intel,
266 .c_identify = generic_identify,
267 .c_size_cache = intel_size_cache, 266 .c_size_cache = intel_size_cache,
268}; 267};
269 268
diff --git a/arch/i386/kernel/cpu/mcheck/Makefile b/arch/i386/kernel/cpu/mcheck/Makefile
index 30808f3d6715..f1ebe1c1c17a 100644
--- a/arch/i386/kernel/cpu/mcheck/Makefile
+++ b/arch/i386/kernel/cpu/mcheck/Makefile
@@ -1,2 +1,2 @@
1obj-y = mce.o k7.o p4.o p5.o p6.o winchip.o 1obj-y = mce.o k7.o p4.o p5.o p6.o winchip.o therm_throt.o
2obj-$(CONFIG_X86_MCE_NONFATAL) += non-fatal.o 2obj-$(CONFIG_X86_MCE_NONFATAL) += non-fatal.o
diff --git a/arch/i386/kernel/cpu/mcheck/p4.c b/arch/i386/kernel/cpu/mcheck/p4.c
index b95f1b3d53aa..504434a46011 100644
--- a/arch/i386/kernel/cpu/mcheck/p4.c
+++ b/arch/i386/kernel/cpu/mcheck/p4.c
@@ -13,6 +13,8 @@
13#include <asm/msr.h> 13#include <asm/msr.h>
14#include <asm/apic.h> 14#include <asm/apic.h>
15 15
16#include <asm/therm_throt.h>
17
16#include "mce.h" 18#include "mce.h"
17 19
18/* as supported by the P4/Xeon family */ 20/* as supported by the P4/Xeon family */
@@ -44,25 +46,12 @@ static void unexpected_thermal_interrupt(struct pt_regs *regs)
44/* P4/Xeon Thermal transition interrupt handler */ 46/* P4/Xeon Thermal transition interrupt handler */
45static void intel_thermal_interrupt(struct pt_regs *regs) 47static void intel_thermal_interrupt(struct pt_regs *regs)
46{ 48{
47 u32 l, h; 49 __u64 msr_val;
48 unsigned int cpu = smp_processor_id();
49 static unsigned long next[NR_CPUS];
50 50
51 ack_APIC_irq(); 51 ack_APIC_irq();
52 52
53 if (time_after(next[cpu], jiffies)) 53 rdmsrl(MSR_IA32_THERM_STATUS, msr_val);
54 return; 54 therm_throt_process(msr_val & 0x1);
55
56 next[cpu] = jiffies + HZ*5;
57 rdmsr(MSR_IA32_THERM_STATUS, l, h);
58 if (l & 0x1) {
59 printk(KERN_EMERG "CPU%d: Temperature above threshold\n", cpu);
60 printk(KERN_EMERG "CPU%d: Running in modulated clock mode\n",
61 cpu);
62 add_taint(TAINT_MACHINE_CHECK);
63 } else {
64 printk(KERN_INFO "CPU%d: Temperature/speed normal\n", cpu);
65 }
66} 55}
67 56
68/* Thermal interrupt handler for this CPU setup */ 57/* Thermal interrupt handler for this CPU setup */
@@ -122,10 +111,13 @@ static void intel_init_thermal(struct cpuinfo_x86 *c)
122 111
123 rdmsr (MSR_IA32_MISC_ENABLE, l, h); 112 rdmsr (MSR_IA32_MISC_ENABLE, l, h);
124 wrmsr (MSR_IA32_MISC_ENABLE, l | (1<<3), h); 113 wrmsr (MSR_IA32_MISC_ENABLE, l | (1<<3), h);
125 114
126 l = apic_read (APIC_LVTTHMR); 115 l = apic_read (APIC_LVTTHMR);
127 apic_write_around (APIC_LVTTHMR, l & ~APIC_LVT_MASKED); 116 apic_write_around (APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
128 printk (KERN_INFO "CPU%d: Thermal monitoring enabled\n", cpu); 117 printk (KERN_INFO "CPU%d: Thermal monitoring enabled\n", cpu);
118
119 /* enable thermal throttle processing */
120 atomic_set(&therm_throt_en, 1);
129 return; 121 return;
130} 122}
131#endif /* CONFIG_X86_MCE_P4THERMAL */ 123#endif /* CONFIG_X86_MCE_P4THERMAL */
diff --git a/arch/i386/kernel/cpu/mcheck/therm_throt.c b/arch/i386/kernel/cpu/mcheck/therm_throt.c
new file mode 100644
index 000000000000..4f43047de406
--- /dev/null
+++ b/arch/i386/kernel/cpu/mcheck/therm_throt.c
@@ -0,0 +1,180 @@
1/*
2 * linux/arch/i386/kerne/cpu/mcheck/therm_throt.c
3 *
4 * Thermal throttle event support code (such as syslog messaging and rate
5 * limiting) that was factored out from x86_64 (mce_intel.c) and i386 (p4.c).
6 * This allows consistent reporting of CPU thermal throttle events.
7 *
8 * Maintains a counter in /sys that keeps track of the number of thermal
9 * events, such that the user knows how bad the thermal problem might be
10 * (since the logging to syslog and mcelog is rate limited).
11 *
12 * Author: Dmitriy Zavin (dmitriyz@google.com)
13 *
14 * Credits: Adapted from Zwane Mwaikambo's original code in mce_intel.c.
15 * Inspired by Ross Biro's and Al Borchers' counter code.
16 */
17
18#include <linux/percpu.h>
19#include <linux/sysdev.h>
20#include <linux/cpu.h>
21#include <asm/cpu.h>
22#include <linux/notifier.h>
23#include <asm/therm_throt.h>
24
25/* How long to wait between reporting thermal events */
26#define CHECK_INTERVAL (300 * HZ)
27
28static DEFINE_PER_CPU(__u64, next_check) = INITIAL_JIFFIES;
29static DEFINE_PER_CPU(unsigned long, thermal_throttle_count);
30atomic_t therm_throt_en = ATOMIC_INIT(0);
31
32#ifdef CONFIG_SYSFS
33#define define_therm_throt_sysdev_one_ro(_name) \
34 static SYSDEV_ATTR(_name, 0444, therm_throt_sysdev_show_##_name, NULL)
35
36#define define_therm_throt_sysdev_show_func(name) \
37static ssize_t therm_throt_sysdev_show_##name(struct sys_device *dev, \
38 char *buf) \
39{ \
40 unsigned int cpu = dev->id; \
41 ssize_t ret; \
42 \
43 preempt_disable(); /* CPU hotplug */ \
44 if (cpu_online(cpu)) \
45 ret = sprintf(buf, "%lu\n", \
46 per_cpu(thermal_throttle_##name, cpu)); \
47 else \
48 ret = 0; \
49 preempt_enable(); \
50 \
51 return ret; \
52}
53
54define_therm_throt_sysdev_show_func(count);
55define_therm_throt_sysdev_one_ro(count);
56
57static struct attribute *thermal_throttle_attrs[] = {
58 &attr_count.attr,
59 NULL
60};
61
62static struct attribute_group thermal_throttle_attr_group = {
63 .attrs = thermal_throttle_attrs,
64 .name = "thermal_throttle"
65};
66#endif /* CONFIG_SYSFS */
67
68/***
69 * therm_throt_process - Process thermal throttling event from interrupt
70 * @curr: Whether the condition is current or not (boolean), since the
71 * thermal interrupt normally gets called both when the thermal
72 * event begins and once the event has ended.
73 *
74 * This function is called by the thermal interrupt after the
75 * IRQ has been acknowledged.
76 *
77 * It will take care of rate limiting and printing messages to the syslog.
78 *
79 * Returns: 0 : Event should NOT be further logged, i.e. still in
80 * "timeout" from previous log message.
81 * 1 : Event should be logged further, and a message has been
82 * printed to the syslog.
83 */
84int therm_throt_process(int curr)
85{
86 unsigned int cpu = smp_processor_id();
87 __u64 tmp_jiffs = get_jiffies_64();
88
89 if (curr)
90 __get_cpu_var(thermal_throttle_count)++;
91
92 if (time_before64(tmp_jiffs, __get_cpu_var(next_check)))
93 return 0;
94
95 __get_cpu_var(next_check) = tmp_jiffs + CHECK_INTERVAL;
96
97 /* if we just entered the thermal event */
98 if (curr) {
99 printk(KERN_CRIT "CPU%d: Temperature above threshold, "
100 "cpu clock throttled (total events = %lu)\n", cpu,
101 __get_cpu_var(thermal_throttle_count));
102
103 add_taint(TAINT_MACHINE_CHECK);
104 } else {
105 printk(KERN_CRIT "CPU%d: Temperature/speed normal\n", cpu);
106 }
107
108 return 1;
109}
110
111#ifdef CONFIG_SYSFS
112/* Add/Remove thermal_throttle interface for CPU device */
113static __cpuinit int thermal_throttle_add_dev(struct sys_device * sys_dev)
114{
115 sysfs_create_group(&sys_dev->kobj, &thermal_throttle_attr_group);
116 return 0;
117}
118
119#ifdef CONFIG_HOTPLUG_CPU
120static __cpuinit int thermal_throttle_remove_dev(struct sys_device * sys_dev)
121{
122 sysfs_remove_group(&sys_dev->kobj, &thermal_throttle_attr_group);
123 return 0;
124}
125
126/* Mutex protecting device creation against CPU hotplug */
127static DEFINE_MUTEX(therm_cpu_lock);
128
129/* Get notified when a cpu comes on/off. Be hotplug friendly. */
130static __cpuinit int thermal_throttle_cpu_callback(struct notifier_block *nfb,
131 unsigned long action,
132 void *hcpu)
133{
134 unsigned int cpu = (unsigned long)hcpu;
135 struct sys_device *sys_dev;
136
137 sys_dev = get_cpu_sysdev(cpu);
138 mutex_lock(&therm_cpu_lock);
139 switch (action) {
140 case CPU_ONLINE:
141 thermal_throttle_add_dev(sys_dev);
142 break;
143 case CPU_DEAD:
144 thermal_throttle_remove_dev(sys_dev);
145 break;
146 }
147 mutex_unlock(&therm_cpu_lock);
148 return NOTIFY_OK;
149}
150
151static struct notifier_block thermal_throttle_cpu_notifier =
152{
153 .notifier_call = thermal_throttle_cpu_callback,
154};
155#endif /* CONFIG_HOTPLUG_CPU */
156
157static __init int thermal_throttle_init_device(void)
158{
159 unsigned int cpu = 0;
160
161 if (!atomic_read(&therm_throt_en))
162 return 0;
163
164 register_hotcpu_notifier(&thermal_throttle_cpu_notifier);
165
166#ifdef CONFIG_HOTPLUG_CPU
167 mutex_lock(&therm_cpu_lock);
168#endif
169 /* connect live CPUs to sysfs */
170 for_each_online_cpu(cpu)
171 thermal_throttle_add_dev(get_cpu_sysdev(cpu));
172#ifdef CONFIG_HOTPLUG_CPU
173 mutex_unlock(&therm_cpu_lock);
174#endif
175
176 return 0;
177}
178
179device_initcall(thermal_throttle_init_device);
180#endif /* CONFIG_SYSFS */
diff --git a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c
index 169ac8e0db68..0b61eed8bbd8 100644
--- a/arch/i386/kernel/cpu/mtrr/generic.c
+++ b/arch/i386/kernel/cpu/mtrr/generic.c
@@ -243,7 +243,7 @@ static DEFINE_SPINLOCK(set_atomicity_lock);
243 * has been called. 243 * has been called.
244 */ 244 */
245 245
246static void prepare_set(void) 246static void prepare_set(void) __acquires(set_atomicity_lock)
247{ 247{
248 unsigned long cr0; 248 unsigned long cr0;
249 249
@@ -274,7 +274,7 @@ static void prepare_set(void)
274 mtrr_wrmsr(MTRRdefType_MSR, deftype_lo & 0xf300UL, deftype_hi); 274 mtrr_wrmsr(MTRRdefType_MSR, deftype_lo & 0xf300UL, deftype_hi);
275} 275}
276 276
277static void post_set(void) 277static void post_set(void) __releases(set_atomicity_lock)
278{ 278{
279 /* Flush TLBs (no need to flush caches - they are disabled) */ 279 /* Flush TLBs (no need to flush caches - they are disabled) */
280 __flush_tlb(); 280 __flush_tlb();
diff --git a/arch/i386/kernel/cpu/nexgen.c b/arch/i386/kernel/cpu/nexgen.c
index ad87fa58058d..8bf23cc80c63 100644
--- a/arch/i386/kernel/cpu/nexgen.c
+++ b/arch/i386/kernel/cpu/nexgen.c
@@ -10,7 +10,7 @@
10 * to have CPUID. (Thanks to Herbert Oppmann) 10 * to have CPUID. (Thanks to Herbert Oppmann)
11 */ 11 */
12 12
13static int __init deep_magic_nexgen_probe(void) 13static int __cpuinit deep_magic_nexgen_probe(void)
14{ 14{
15 int ret; 15 int ret;
16 16
@@ -27,21 +27,20 @@ static int __init deep_magic_nexgen_probe(void)
27 return ret; 27 return ret;
28} 28}
29 29
30static void __init init_nexgen(struct cpuinfo_x86 * c) 30static void __cpuinit init_nexgen(struct cpuinfo_x86 * c)
31{ 31{
32 c->x86_cache_size = 256; /* A few had 1 MB... */ 32 c->x86_cache_size = 256; /* A few had 1 MB... */
33} 33}
34 34
35static void __init nexgen_identify(struct cpuinfo_x86 * c) 35static void __cpuinit nexgen_identify(struct cpuinfo_x86 * c)
36{ 36{
37 /* Detect NexGen with old hypercode */ 37 /* Detect NexGen with old hypercode */
38 if ( deep_magic_nexgen_probe() ) { 38 if ( deep_magic_nexgen_probe() ) {
39 strcpy(c->x86_vendor_id, "NexGenDriven"); 39 strcpy(c->x86_vendor_id, "NexGenDriven");
40 } 40 }
41 generic_identify(c);
42} 41}
43 42
44static struct cpu_dev nexgen_cpu_dev __initdata = { 43static struct cpu_dev nexgen_cpu_dev __cpuinitdata = {
45 .c_vendor = "Nexgen", 44 .c_vendor = "Nexgen",
46 .c_ident = { "NexGenDriven" }, 45 .c_ident = { "NexGenDriven" },
47 .c_models = { 46 .c_models = {
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
index f54a15268ed7..76aac088a323 100644
--- a/arch/i386/kernel/cpu/proc.c
+++ b/arch/i386/kernel/cpu/proc.c
@@ -46,8 +46,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
46 46
47 /* Intel-defined (#2) */ 47 /* Intel-defined (#2) */
48 "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est", 48 "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est",
49 "tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL, 49 "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
50 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 50 NULL, NULL, "dca", NULL, NULL, NULL, NULL, NULL,
51 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 51 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
52 52
53 /* VIA/Cyrix/Centaur-defined */ 53 /* VIA/Cyrix/Centaur-defined */
diff --git a/arch/i386/kernel/cpu/rise.c b/arch/i386/kernel/cpu/rise.c
index d08d5a2811c8..9317f7414989 100644
--- a/arch/i386/kernel/cpu/rise.c
+++ b/arch/i386/kernel/cpu/rise.c
@@ -5,7 +5,7 @@
5 5
6#include "cpu.h" 6#include "cpu.h"
7 7
8static void __init init_rise(struct cpuinfo_x86 *c) 8static void __cpuinit init_rise(struct cpuinfo_x86 *c)
9{ 9{
10 printk("CPU: Rise iDragon"); 10 printk("CPU: Rise iDragon");
11 if (c->x86_model > 2) 11 if (c->x86_model > 2)
@@ -28,7 +28,7 @@ static void __init init_rise(struct cpuinfo_x86 *c)
28 set_bit(X86_FEATURE_CX8, c->x86_capability); 28 set_bit(X86_FEATURE_CX8, c->x86_capability);
29} 29}
30 30
31static struct cpu_dev rise_cpu_dev __initdata = { 31static struct cpu_dev rise_cpu_dev __cpuinitdata = {
32 .c_vendor = "Rise", 32 .c_vendor = "Rise",
33 .c_ident = { "RiseRiseRise" }, 33 .c_ident = { "RiseRiseRise" },
34 .c_models = { 34 .c_models = {
diff --git a/arch/i386/kernel/cpu/transmeta.c b/arch/i386/kernel/cpu/transmeta.c
index 7214c9b577ab..4056fb7d2cdf 100644
--- a/arch/i386/kernel/cpu/transmeta.c
+++ b/arch/i386/kernel/cpu/transmeta.c
@@ -5,7 +5,7 @@
5#include <asm/msr.h> 5#include <asm/msr.h>
6#include "cpu.h" 6#include "cpu.h"
7 7
8static void __init init_transmeta(struct cpuinfo_x86 *c) 8static void __cpuinit init_transmeta(struct cpuinfo_x86 *c)
9{ 9{
10 unsigned int cap_mask, uk, max, dummy; 10 unsigned int cap_mask, uk, max, dummy;
11 unsigned int cms_rev1, cms_rev2; 11 unsigned int cms_rev1, cms_rev2;
@@ -85,10 +85,9 @@ static void __init init_transmeta(struct cpuinfo_x86 *c)
85#endif 85#endif
86} 86}
87 87
88static void __init transmeta_identify(struct cpuinfo_x86 * c) 88static void __cpuinit transmeta_identify(struct cpuinfo_x86 * c)
89{ 89{
90 u32 xlvl; 90 u32 xlvl;
91 generic_identify(c);
92 91
93 /* Transmeta-defined flags: level 0x80860001 */ 92 /* Transmeta-defined flags: level 0x80860001 */
94 xlvl = cpuid_eax(0x80860000); 93 xlvl = cpuid_eax(0x80860000);
@@ -98,7 +97,7 @@ static void __init transmeta_identify(struct cpuinfo_x86 * c)
98 } 97 }
99} 98}
100 99
101static struct cpu_dev transmeta_cpu_dev __initdata = { 100static struct cpu_dev transmeta_cpu_dev __cpuinitdata = {
102 .c_vendor = "Transmeta", 101 .c_vendor = "Transmeta",
103 .c_ident = { "GenuineTMx86", "TransmetaCPU" }, 102 .c_ident = { "GenuineTMx86", "TransmetaCPU" },
104 .c_init = init_transmeta, 103 .c_init = init_transmeta,
diff --git a/arch/i386/kernel/cpu/umc.c b/arch/i386/kernel/cpu/umc.c
index 2cd988f6dc55..1bf3f87e9c5b 100644
--- a/arch/i386/kernel/cpu/umc.c
+++ b/arch/i386/kernel/cpu/umc.c
@@ -5,12 +5,8 @@
5 5
6/* UMC chips appear to be only either 386 or 486, so no special init takes place. 6/* UMC chips appear to be only either 386 or 486, so no special init takes place.
7 */ 7 */
8static void __init init_umc(struct cpuinfo_x86 * c)
9{
10
11}
12 8
13static struct cpu_dev umc_cpu_dev __initdata = { 9static struct cpu_dev umc_cpu_dev __cpuinitdata = {
14 .c_vendor = "UMC", 10 .c_vendor = "UMC",
15 .c_ident = { "UMC UMC UMC" }, 11 .c_ident = { "UMC UMC UMC" },
16 .c_models = { 12 .c_models = {
@@ -21,7 +17,6 @@ static struct cpu_dev umc_cpu_dev __initdata = {
21 } 17 }
22 }, 18 },
23 }, 19 },
24 .c_init = init_umc,
25}; 20};
26 21
27int __init umc_init_cpu(void) 22int __init umc_init_cpu(void)
diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c
index 5b96f038367f..67d297dc1003 100644
--- a/arch/i386/kernel/crash.c
+++ b/arch/i386/kernel/crash.c
@@ -22,6 +22,8 @@
22#include <asm/nmi.h> 22#include <asm/nmi.h>
23#include <asm/hw_irq.h> 23#include <asm/hw_irq.h>
24#include <asm/apic.h> 24#include <asm/apic.h>
25#include <asm/kdebug.h>
26
25#include <mach_ipi.h> 27#include <mach_ipi.h>
26 28
27 29
@@ -93,16 +95,25 @@ static void crash_save_self(struct pt_regs *regs)
93#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) 95#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
94static atomic_t waiting_for_crash_ipi; 96static atomic_t waiting_for_crash_ipi;
95 97
96static int crash_nmi_callback(struct pt_regs *regs, int cpu) 98static int crash_nmi_callback(struct notifier_block *self,
99 unsigned long val, void *data)
97{ 100{
101 struct pt_regs *regs;
98 struct pt_regs fixed_regs; 102 struct pt_regs fixed_regs;
103 int cpu;
104
105 if (val != DIE_NMI_IPI)
106 return NOTIFY_OK;
107
108 regs = ((struct die_args *)data)->regs;
109 cpu = raw_smp_processor_id();
99 110
100 /* Don't do anything if this handler is invoked on crashing cpu. 111 /* Don't do anything if this handler is invoked on crashing cpu.
101 * Otherwise, system will completely hang. Crashing cpu can get 112 * Otherwise, system will completely hang. Crashing cpu can get
102 * an NMI if system was initially booted with nmi_watchdog parameter. 113 * an NMI if system was initially booted with nmi_watchdog parameter.
103 */ 114 */
104 if (cpu == crashing_cpu) 115 if (cpu == crashing_cpu)
105 return 1; 116 return NOTIFY_STOP;
106 local_irq_disable(); 117 local_irq_disable();
107 118
108 if (!user_mode_vm(regs)) { 119 if (!user_mode_vm(regs)) {
@@ -125,13 +136,18 @@ static void smp_send_nmi_allbutself(void)
125 send_IPI_allbutself(NMI_VECTOR); 136 send_IPI_allbutself(NMI_VECTOR);
126} 137}
127 138
139static struct notifier_block crash_nmi_nb = {
140 .notifier_call = crash_nmi_callback,
141};
142
128static void nmi_shootdown_cpus(void) 143static void nmi_shootdown_cpus(void)
129{ 144{
130 unsigned long msecs; 145 unsigned long msecs;
131 146
132 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); 147 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
133 /* Would it be better to replace the trap vector here? */ 148 /* Would it be better to replace the trap vector here? */
134 set_nmi_callback(crash_nmi_callback); 149 if (register_die_notifier(&crash_nmi_nb))
150 return; /* return what? */
135 /* Ensure the new callback function is set before sending 151 /* Ensure the new callback function is set before sending
136 * out the NMI 152 * out the NMI
137 */ 153 */
diff --git a/arch/i386/kernel/efi_stub.S b/arch/i386/kernel/efi_stub.S
index d3ee73a3eee3..ef00bb77d7e4 100644
--- a/arch/i386/kernel/efi_stub.S
+++ b/arch/i386/kernel/efi_stub.S
@@ -7,7 +7,6 @@
7 7
8#include <linux/linkage.h> 8#include <linux/linkage.h>
9#include <asm/page.h> 9#include <asm/page.h>
10#include <asm/pgtable.h>
11 10
12/* 11/*
13 * efi_call_phys(void *, ...) is a function with variable parameters. 12 * efi_call_phys(void *, ...) is a function with variable parameters.
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 87f9f60b803b..5a63d6fdb70e 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -76,8 +76,15 @@ DF_MASK = 0x00000400
76NT_MASK = 0x00004000 76NT_MASK = 0x00004000
77VM_MASK = 0x00020000 77VM_MASK = 0x00020000
78 78
79/* These are replaces for paravirtualization */
80#define DISABLE_INTERRUPTS cli
81#define ENABLE_INTERRUPTS sti
82#define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
83#define INTERRUPT_RETURN iret
84#define GET_CR0_INTO_EAX movl %cr0, %eax
85
79#ifdef CONFIG_PREEMPT 86#ifdef CONFIG_PREEMPT
80#define preempt_stop cli; TRACE_IRQS_OFF 87#define preempt_stop DISABLE_INTERRUPTS; TRACE_IRQS_OFF
81#else 88#else
82#define preempt_stop 89#define preempt_stop
83#define resume_kernel restore_nocheck 90#define resume_kernel restore_nocheck
@@ -176,18 +183,21 @@ VM_MASK = 0x00020000
176 183
177#define RING0_INT_FRAME \ 184#define RING0_INT_FRAME \
178 CFI_STARTPROC simple;\ 185 CFI_STARTPROC simple;\
186 CFI_SIGNAL_FRAME;\
179 CFI_DEF_CFA esp, 3*4;\ 187 CFI_DEF_CFA esp, 3*4;\
180 /*CFI_OFFSET cs, -2*4;*/\ 188 /*CFI_OFFSET cs, -2*4;*/\
181 CFI_OFFSET eip, -3*4 189 CFI_OFFSET eip, -3*4
182 190
183#define RING0_EC_FRAME \ 191#define RING0_EC_FRAME \
184 CFI_STARTPROC simple;\ 192 CFI_STARTPROC simple;\
193 CFI_SIGNAL_FRAME;\
185 CFI_DEF_CFA esp, 4*4;\ 194 CFI_DEF_CFA esp, 4*4;\
186 /*CFI_OFFSET cs, -2*4;*/\ 195 /*CFI_OFFSET cs, -2*4;*/\
187 CFI_OFFSET eip, -3*4 196 CFI_OFFSET eip, -3*4
188 197
189#define RING0_PTREGS_FRAME \ 198#define RING0_PTREGS_FRAME \
190 CFI_STARTPROC simple;\ 199 CFI_STARTPROC simple;\
200 CFI_SIGNAL_FRAME;\
191 CFI_DEF_CFA esp, OLDESP-EBX;\ 201 CFI_DEF_CFA esp, OLDESP-EBX;\
192 /*CFI_OFFSET cs, CS-OLDESP;*/\ 202 /*CFI_OFFSET cs, CS-OLDESP;*/\
193 CFI_OFFSET eip, EIP-OLDESP;\ 203 CFI_OFFSET eip, EIP-OLDESP;\
@@ -233,10 +243,11 @@ ret_from_intr:
233check_userspace: 243check_userspace:
234 movl EFLAGS(%esp), %eax # mix EFLAGS and CS 244 movl EFLAGS(%esp), %eax # mix EFLAGS and CS
235 movb CS(%esp), %al 245 movb CS(%esp), %al
236 testl $(VM_MASK | 3), %eax 246 andl $(VM_MASK | SEGMENT_RPL_MASK), %eax
237 jz resume_kernel 247 cmpl $USER_RPL, %eax
248 jb resume_kernel # not returning to v8086 or userspace
238ENTRY(resume_userspace) 249ENTRY(resume_userspace)
239 cli # make sure we don't miss an interrupt 250 DISABLE_INTERRUPTS # make sure we don't miss an interrupt
240 # setting need_resched or sigpending 251 # setting need_resched or sigpending
241 # between sampling and the iret 252 # between sampling and the iret
242 movl TI_flags(%ebp), %ecx 253 movl TI_flags(%ebp), %ecx
@@ -247,7 +258,7 @@ ENTRY(resume_userspace)
247 258
248#ifdef CONFIG_PREEMPT 259#ifdef CONFIG_PREEMPT
249ENTRY(resume_kernel) 260ENTRY(resume_kernel)
250 cli 261 DISABLE_INTERRUPTS
251 cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? 262 cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ?
252 jnz restore_nocheck 263 jnz restore_nocheck
253need_resched: 264need_resched:
@@ -267,6 +278,7 @@ need_resched:
267 # sysenter call handler stub 278 # sysenter call handler stub
268ENTRY(sysenter_entry) 279ENTRY(sysenter_entry)
269 CFI_STARTPROC simple 280 CFI_STARTPROC simple
281 CFI_SIGNAL_FRAME
270 CFI_DEF_CFA esp, 0 282 CFI_DEF_CFA esp, 0
271 CFI_REGISTER esp, ebp 283 CFI_REGISTER esp, ebp
272 movl TSS_sysenter_esp0(%esp),%esp 284 movl TSS_sysenter_esp0(%esp),%esp
@@ -275,7 +287,7 @@ sysenter_past_esp:
275 * No need to follow this irqs on/off section: the syscall 287 * No need to follow this irqs on/off section: the syscall
276 * disabled irqs and here we enable it straight after entry: 288 * disabled irqs and here we enable it straight after entry:
277 */ 289 */
278 sti 290 ENABLE_INTERRUPTS
279 pushl $(__USER_DS) 291 pushl $(__USER_DS)
280 CFI_ADJUST_CFA_OFFSET 4 292 CFI_ADJUST_CFA_OFFSET 4
281 /*CFI_REL_OFFSET ss, 0*/ 293 /*CFI_REL_OFFSET ss, 0*/
@@ -320,7 +332,7 @@ sysenter_past_esp:
320 jae syscall_badsys 332 jae syscall_badsys
321 call *sys_call_table(,%eax,4) 333 call *sys_call_table(,%eax,4)
322 movl %eax,EAX(%esp) 334 movl %eax,EAX(%esp)
323 cli 335 DISABLE_INTERRUPTS
324 TRACE_IRQS_OFF 336 TRACE_IRQS_OFF
325 movl TI_flags(%ebp), %ecx 337 movl TI_flags(%ebp), %ecx
326 testw $_TIF_ALLWORK_MASK, %cx 338 testw $_TIF_ALLWORK_MASK, %cx
@@ -330,8 +342,7 @@ sysenter_past_esp:
330 movl OLDESP(%esp), %ecx 342 movl OLDESP(%esp), %ecx
331 xorl %ebp,%ebp 343 xorl %ebp,%ebp
332 TRACE_IRQS_ON 344 TRACE_IRQS_ON
333 sti 345 ENABLE_INTERRUPTS_SYSEXIT
334 sysexit
335 CFI_ENDPROC 346 CFI_ENDPROC
336 347
337 348
@@ -356,7 +367,7 @@ syscall_call:
356 call *sys_call_table(,%eax,4) 367 call *sys_call_table(,%eax,4)
357 movl %eax,EAX(%esp) # store the return value 368 movl %eax,EAX(%esp) # store the return value
358syscall_exit: 369syscall_exit:
359 cli # make sure we don't miss an interrupt 370 DISABLE_INTERRUPTS # make sure we don't miss an interrupt
360 # setting need_resched or sigpending 371 # setting need_resched or sigpending
361 # between sampling and the iret 372 # between sampling and the iret
362 TRACE_IRQS_OFF 373 TRACE_IRQS_OFF
@@ -371,8 +382,8 @@ restore_all:
371 # See comments in process.c:copy_thread() for details. 382 # See comments in process.c:copy_thread() for details.
372 movb OLDSS(%esp), %ah 383 movb OLDSS(%esp), %ah
373 movb CS(%esp), %al 384 movb CS(%esp), %al
374 andl $(VM_MASK | (4 << 8) | 3), %eax 385 andl $(VM_MASK | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax
375 cmpl $((4 << 8) | 3), %eax 386 cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax
376 CFI_REMEMBER_STATE 387 CFI_REMEMBER_STATE
377 je ldt_ss # returning to user-space with LDT SS 388 je ldt_ss # returning to user-space with LDT SS
378restore_nocheck: 389restore_nocheck:
@@ -381,11 +392,11 @@ restore_nocheck_notrace:
381 RESTORE_REGS 392 RESTORE_REGS
382 addl $4, %esp 393 addl $4, %esp
383 CFI_ADJUST_CFA_OFFSET -4 394 CFI_ADJUST_CFA_OFFSET -4
3841: iret 3951: INTERRUPT_RETURN
385.section .fixup,"ax" 396.section .fixup,"ax"
386iret_exc: 397iret_exc:
387 TRACE_IRQS_ON 398 TRACE_IRQS_ON
388 sti 399 ENABLE_INTERRUPTS
389 pushl $0 # no error code 400 pushl $0 # no error code
390 pushl $do_iret_error 401 pushl $do_iret_error
391 jmp error_code 402 jmp error_code
@@ -409,7 +420,7 @@ ldt_ss:
409 * dosemu and wine happy. */ 420 * dosemu and wine happy. */
410 subl $8, %esp # reserve space for switch16 pointer 421 subl $8, %esp # reserve space for switch16 pointer
411 CFI_ADJUST_CFA_OFFSET 8 422 CFI_ADJUST_CFA_OFFSET 8
412 cli 423 DISABLE_INTERRUPTS
413 TRACE_IRQS_OFF 424 TRACE_IRQS_OFF
414 movl %esp, %eax 425 movl %esp, %eax
415 /* Set up the 16bit stack frame with switch32 pointer on top, 426 /* Set up the 16bit stack frame with switch32 pointer on top,
@@ -419,7 +430,7 @@ ldt_ss:
419 TRACE_IRQS_IRET 430 TRACE_IRQS_IRET
420 RESTORE_REGS 431 RESTORE_REGS
421 lss 20+4(%esp), %esp # switch to 16bit stack 432 lss 20+4(%esp), %esp # switch to 16bit stack
4221: iret 4331: INTERRUPT_RETURN
423.section __ex_table,"a" 434.section __ex_table,"a"
424 .align 4 435 .align 4
425 .long 1b,iret_exc 436 .long 1b,iret_exc
@@ -434,7 +445,7 @@ work_pending:
434 jz work_notifysig 445 jz work_notifysig
435work_resched: 446work_resched:
436 call schedule 447 call schedule
437 cli # make sure we don't miss an interrupt 448 DISABLE_INTERRUPTS # make sure we don't miss an interrupt
438 # setting need_resched or sigpending 449 # setting need_resched or sigpending
439 # between sampling and the iret 450 # between sampling and the iret
440 TRACE_IRQS_OFF 451 TRACE_IRQS_OFF
@@ -490,7 +501,7 @@ syscall_exit_work:
490 testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl 501 testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl
491 jz work_pending 502 jz work_pending
492 TRACE_IRQS_ON 503 TRACE_IRQS_ON
493 sti # could let do_syscall_trace() call 504 ENABLE_INTERRUPTS # could let do_syscall_trace() call
494 # schedule() instead 505 # schedule() instead
495 movl %esp, %eax 506 movl %esp, %eax
496 movl $1, %edx 507 movl $1, %edx
@@ -591,11 +602,9 @@ ENTRY(name) \
591/* The include is where all of the SMP etc. interrupts come from */ 602/* The include is where all of the SMP etc. interrupts come from */
592#include "entry_arch.h" 603#include "entry_arch.h"
593 604
594ENTRY(divide_error) 605KPROBE_ENTRY(page_fault)
595 RING0_INT_FRAME 606 RING0_EC_FRAME
596 pushl $0 # no error code 607 pushl $do_page_fault
597 CFI_ADJUST_CFA_OFFSET 4
598 pushl $do_divide_error
599 CFI_ADJUST_CFA_OFFSET 4 608 CFI_ADJUST_CFA_OFFSET 4
600 ALIGN 609 ALIGN
601error_code: 610error_code:
@@ -645,6 +654,7 @@ error_code:
645 call *%edi 654 call *%edi
646 jmp ret_from_exception 655 jmp ret_from_exception
647 CFI_ENDPROC 656 CFI_ENDPROC
657KPROBE_END(page_fault)
648 658
649ENTRY(coprocessor_error) 659ENTRY(coprocessor_error)
650 RING0_INT_FRAME 660 RING0_INT_FRAME
@@ -669,7 +679,7 @@ ENTRY(device_not_available)
669 pushl $-1 # mark this as an int 679 pushl $-1 # mark this as an int
670 CFI_ADJUST_CFA_OFFSET 4 680 CFI_ADJUST_CFA_OFFSET 4
671 SAVE_ALL 681 SAVE_ALL
672 movl %cr0, %eax 682 GET_CR0_INTO_EAX
673 testl $0x4, %eax # EM (math emulation bit) 683 testl $0x4, %eax # EM (math emulation bit)
674 jne device_not_available_emulate 684 jne device_not_available_emulate
675 preempt_stop 685 preempt_stop
@@ -702,9 +712,15 @@ device_not_available_emulate:
702 jne ok; \ 712 jne ok; \
703label: \ 713label: \
704 movl TSS_sysenter_esp0+offset(%esp),%esp; \ 714 movl TSS_sysenter_esp0+offset(%esp),%esp; \
715 CFI_DEF_CFA esp, 0; \
716 CFI_UNDEFINED eip; \
705 pushfl; \ 717 pushfl; \
718 CFI_ADJUST_CFA_OFFSET 4; \
706 pushl $__KERNEL_CS; \ 719 pushl $__KERNEL_CS; \
707 pushl $sysenter_past_esp 720 CFI_ADJUST_CFA_OFFSET 4; \
721 pushl $sysenter_past_esp; \
722 CFI_ADJUST_CFA_OFFSET 4; \
723 CFI_REL_OFFSET eip, 0
708 724
709KPROBE_ENTRY(debug) 725KPROBE_ENTRY(debug)
710 RING0_INT_FRAME 726 RING0_INT_FRAME
@@ -720,7 +736,8 @@ debug_stack_correct:
720 call do_debug 736 call do_debug
721 jmp ret_from_exception 737 jmp ret_from_exception
722 CFI_ENDPROC 738 CFI_ENDPROC
723 .previous .text 739KPROBE_END(debug)
740
724/* 741/*
725 * NMI is doubly nasty. It can happen _while_ we're handling 742 * NMI is doubly nasty. It can happen _while_ we're handling
726 * a debug fault, and the debug fault hasn't yet been able to 743 * a debug fault, and the debug fault hasn't yet been able to
@@ -729,7 +746,7 @@ debug_stack_correct:
729 * check whether we got an NMI on the debug path where the debug 746 * check whether we got an NMI on the debug path where the debug
730 * fault happened on the sysenter path. 747 * fault happened on the sysenter path.
731 */ 748 */
732ENTRY(nmi) 749KPROBE_ENTRY(nmi)
733 RING0_INT_FRAME 750 RING0_INT_FRAME
734 pushl %eax 751 pushl %eax
735 CFI_ADJUST_CFA_OFFSET 4 752 CFI_ADJUST_CFA_OFFSET 4
@@ -754,6 +771,7 @@ ENTRY(nmi)
754 cmpl $sysenter_entry,12(%esp) 771 cmpl $sysenter_entry,12(%esp)
755 je nmi_debug_stack_check 772 je nmi_debug_stack_check
756nmi_stack_correct: 773nmi_stack_correct:
774 /* We have a RING0_INT_FRAME here */
757 pushl %eax 775 pushl %eax
758 CFI_ADJUST_CFA_OFFSET 4 776 CFI_ADJUST_CFA_OFFSET 4
759 SAVE_ALL 777 SAVE_ALL
@@ -764,9 +782,12 @@ nmi_stack_correct:
764 CFI_ENDPROC 782 CFI_ENDPROC
765 783
766nmi_stack_fixup: 784nmi_stack_fixup:
785 RING0_INT_FRAME
767 FIX_STACK(12,nmi_stack_correct, 1) 786 FIX_STACK(12,nmi_stack_correct, 1)
768 jmp nmi_stack_correct 787 jmp nmi_stack_correct
788
769nmi_debug_stack_check: 789nmi_debug_stack_check:
790 /* We have a RING0_INT_FRAME here */
770 cmpw $__KERNEL_CS,16(%esp) 791 cmpw $__KERNEL_CS,16(%esp)
771 jne nmi_stack_correct 792 jne nmi_stack_correct
772 cmpl $debug,(%esp) 793 cmpl $debug,(%esp)
@@ -777,8 +798,10 @@ nmi_debug_stack_check:
777 jmp nmi_stack_correct 798 jmp nmi_stack_correct
778 799
779nmi_16bit_stack: 800nmi_16bit_stack:
780 RING0_INT_FRAME 801 /* We have a RING0_INT_FRAME here.
781 /* create the pointer to lss back */ 802 *
803 * create the pointer to lss back
804 */
782 pushl %ss 805 pushl %ss
783 CFI_ADJUST_CFA_OFFSET 4 806 CFI_ADJUST_CFA_OFFSET 4
784 pushl %esp 807 pushl %esp
@@ -799,12 +822,13 @@ nmi_16bit_stack:
799 call do_nmi 822 call do_nmi
800 RESTORE_REGS 823 RESTORE_REGS
801 lss 12+4(%esp), %esp # back to 16bit stack 824 lss 12+4(%esp), %esp # back to 16bit stack
8021: iret 8251: INTERRUPT_RETURN
803 CFI_ENDPROC 826 CFI_ENDPROC
804.section __ex_table,"a" 827.section __ex_table,"a"
805 .align 4 828 .align 4
806 .long 1b,iret_exc 829 .long 1b,iret_exc
807.previous 830.previous
831KPROBE_END(nmi)
808 832
809KPROBE_ENTRY(int3) 833KPROBE_ENTRY(int3)
810 RING0_INT_FRAME 834 RING0_INT_FRAME
@@ -816,7 +840,7 @@ KPROBE_ENTRY(int3)
816 call do_int3 840 call do_int3
817 jmp ret_from_exception 841 jmp ret_from_exception
818 CFI_ENDPROC 842 CFI_ENDPROC
819 .previous .text 843KPROBE_END(int3)
820 844
821ENTRY(overflow) 845ENTRY(overflow)
822 RING0_INT_FRAME 846 RING0_INT_FRAME
@@ -881,7 +905,7 @@ KPROBE_ENTRY(general_protection)
881 CFI_ADJUST_CFA_OFFSET 4 905 CFI_ADJUST_CFA_OFFSET 4
882 jmp error_code 906 jmp error_code
883 CFI_ENDPROC 907 CFI_ENDPROC
884 .previous .text 908KPROBE_END(general_protection)
885 909
886ENTRY(alignment_check) 910ENTRY(alignment_check)
887 RING0_EC_FRAME 911 RING0_EC_FRAME
@@ -890,13 +914,14 @@ ENTRY(alignment_check)
890 jmp error_code 914 jmp error_code
891 CFI_ENDPROC 915 CFI_ENDPROC
892 916
893KPROBE_ENTRY(page_fault) 917ENTRY(divide_error)
894 RING0_EC_FRAME 918 RING0_INT_FRAME
895 pushl $do_page_fault 919 pushl $0 # no error code
920 CFI_ADJUST_CFA_OFFSET 4
921 pushl $do_divide_error
896 CFI_ADJUST_CFA_OFFSET 4 922 CFI_ADJUST_CFA_OFFSET 4
897 jmp error_code 923 jmp error_code
898 CFI_ENDPROC 924 CFI_ENDPROC
899 .previous .text
900 925
901#ifdef CONFIG_X86_MCE 926#ifdef CONFIG_X86_MCE
902ENTRY(machine_check) 927ENTRY(machine_check)
@@ -949,6 +974,19 @@ ENTRY(arch_unwind_init_running)
949ENDPROC(arch_unwind_init_running) 974ENDPROC(arch_unwind_init_running)
950#endif 975#endif
951 976
977ENTRY(kernel_thread_helper)
978 pushl $0 # fake return address for unwinder
979 CFI_STARTPROC
980 movl %edx,%eax
981 push %edx
982 CFI_ADJUST_CFA_OFFSET 4
983 call *%ebx
984 push %eax
985 CFI_ADJUST_CFA_OFFSET 4
986 call do_exit
987 CFI_ENDPROC
988ENDPROC(kernel_thread_helper)
989
952.section .rodata,"a" 990.section .rodata,"a"
953#include "syscall_table.S" 991#include "syscall_table.S"
954 992
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index a6b8bd89aa27..be9d883c62ce 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -371,8 +371,65 @@ rp_sidt:
371 addl $8,%edi 371 addl $8,%edi
372 dec %ecx 372 dec %ecx
373 jne rp_sidt 373 jne rp_sidt
374
375.macro set_early_handler handler,trapno
376 lea \handler,%edx
377 movl $(__KERNEL_CS << 16),%eax
378 movw %dx,%ax
379 movw $0x8E00,%dx /* interrupt gate - dpl=0, present */
380 lea idt_table,%edi
381 movl %eax,8*\trapno(%edi)
382 movl %edx,8*\trapno+4(%edi)
383.endm
384
385 set_early_handler handler=early_divide_err,trapno=0
386 set_early_handler handler=early_illegal_opcode,trapno=6
387 set_early_handler handler=early_protection_fault,trapno=13
388 set_early_handler handler=early_page_fault,trapno=14
389
374 ret 390 ret
375 391
392early_divide_err:
393 xor %edx,%edx
394 pushl $0 /* fake errcode */
395 jmp early_fault
396
397early_illegal_opcode:
398 movl $6,%edx
399 pushl $0 /* fake errcode */
400 jmp early_fault
401
402early_protection_fault:
403 movl $13,%edx
404 jmp early_fault
405
406early_page_fault:
407 movl $14,%edx
408 jmp early_fault
409
410early_fault:
411 cld
412#ifdef CONFIG_PRINTK
413 movl $(__KERNEL_DS),%eax
414 movl %eax,%ds
415 movl %eax,%es
416 cmpl $2,early_recursion_flag
417 je hlt_loop
418 incl early_recursion_flag
419 movl %cr2,%eax
420 pushl %eax
421 pushl %edx /* trapno */
422 pushl $fault_msg
423#ifdef CONFIG_EARLY_PRINTK
424 call early_printk
425#else
426 call printk
427#endif
428#endif
429hlt_loop:
430 hlt
431 jmp hlt_loop
432
376/* This is the default interrupt "handler" :-) */ 433/* This is the default interrupt "handler" :-) */
377 ALIGN 434 ALIGN
378ignore_int: 435ignore_int:
@@ -386,6 +443,9 @@ ignore_int:
386 movl $(__KERNEL_DS),%eax 443 movl $(__KERNEL_DS),%eax
387 movl %eax,%ds 444 movl %eax,%ds
388 movl %eax,%es 445 movl %eax,%es
446 cmpl $2,early_recursion_flag
447 je hlt_loop
448 incl early_recursion_flag
389 pushl 16(%esp) 449 pushl 16(%esp)
390 pushl 24(%esp) 450 pushl 24(%esp)
391 pushl 32(%esp) 451 pushl 32(%esp)
@@ -431,9 +491,16 @@ ENTRY(stack_start)
431 491
432ready: .byte 0 492ready: .byte 0
433 493
494early_recursion_flag:
495 .long 0
496
434int_msg: 497int_msg:
435 .asciz "Unknown interrupt or fault at EIP %p %p %p\n" 498 .asciz "Unknown interrupt or fault at EIP %p %p %p\n"
436 499
500fault_msg:
501 .ascii "Int %d: CR2 %p err %p EIP %p CS %p flags %p\n"
502 .asciz "Stack: %p %p %p %p %p %p %p %p\n"
503
437/* 504/*
438 * The IDT and GDT 'descriptors' are a strange 48-bit object 505 * The IDT and GDT 'descriptors' are a strange 48-bit object
439 * only used by the lidt and lgdt instructions. They are not 506 * only used by the lidt and lgdt instructions. They are not
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
index d4756d154f47..ea5f4e7958d8 100644
--- a/arch/i386/kernel/i8259.c
+++ b/arch/i386/kernel/i8259.c
@@ -45,6 +45,8 @@ static void end_8259A_irq (unsigned int irq)
45 45
46#define shutdown_8259A_irq disable_8259A_irq 46#define shutdown_8259A_irq disable_8259A_irq
47 47
48static int i8259A_auto_eoi;
49
48static void mask_and_ack_8259A(unsigned int); 50static void mask_and_ack_8259A(unsigned int);
49 51
50unsigned int startup_8259A_irq(unsigned int irq) 52unsigned int startup_8259A_irq(unsigned int irq)
@@ -253,7 +255,7 @@ static void save_ELCR(char *trigger)
253 255
254static int i8259A_resume(struct sys_device *dev) 256static int i8259A_resume(struct sys_device *dev)
255{ 257{
256 init_8259A(0); 258 init_8259A(i8259A_auto_eoi);
257 restore_ELCR(irq_trigger); 259 restore_ELCR(irq_trigger);
258 return 0; 260 return 0;
259} 261}
@@ -301,6 +303,8 @@ void init_8259A(int auto_eoi)
301{ 303{
302 unsigned long flags; 304 unsigned long flags;
303 305
306 i8259A_auto_eoi = auto_eoi;
307
304 spin_lock_irqsave(&i8259A_lock, flags); 308 spin_lock_irqsave(&i8259A_lock, flags);
305 309
306 outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ 310 outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 4fb32c551fe0..fd0df75cfbda 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -40,6 +40,7 @@
40#include <asm/nmi.h> 40#include <asm/nmi.h>
41 41
42#include <mach_apic.h> 42#include <mach_apic.h>
43#include <mach_apicdef.h>
43 44
44#include "io_ports.h" 45#include "io_ports.h"
45 46
@@ -65,7 +66,7 @@ int sis_apic_bug = -1;
65 */ 66 */
66int nr_ioapic_registers[MAX_IO_APICS]; 67int nr_ioapic_registers[MAX_IO_APICS];
67 68
68int disable_timer_pin_1 __initdata; 69static int disable_timer_pin_1 __initdata;
69 70
70/* 71/*
71 * Rough estimation of how many shared IRQs there are, can 72 * Rough estimation of how many shared IRQs there are, can
@@ -93,6 +94,34 @@ int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1};
93#define vector_to_irq(vector) (vector) 94#define vector_to_irq(vector) (vector)
94#endif 95#endif
95 96
97
98union entry_union {
99 struct { u32 w1, w2; };
100 struct IO_APIC_route_entry entry;
101};
102
103static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin)
104{
105 union entry_union eu;
106 unsigned long flags;
107 spin_lock_irqsave(&ioapic_lock, flags);
108 eu.w1 = io_apic_read(apic, 0x10 + 2 * pin);
109 eu.w2 = io_apic_read(apic, 0x11 + 2 * pin);
110 spin_unlock_irqrestore(&ioapic_lock, flags);
111 return eu.entry;
112}
113
114static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
115{
116 unsigned long flags;
117 union entry_union eu;
118 eu.entry = e;
119 spin_lock_irqsave(&ioapic_lock, flags);
120 io_apic_write(apic, 0x10 + 2*pin, eu.w1);
121 io_apic_write(apic, 0x11 + 2*pin, eu.w2);
122 spin_unlock_irqrestore(&ioapic_lock, flags);
123}
124
96/* 125/*
97 * The common case is 1:1 IRQ<->pin mappings. Sometimes there are 126 * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
98 * shared ISA-space IRQs, so we have to support them. We are super 127 * shared ISA-space IRQs, so we have to support them. We are super
@@ -200,13 +229,9 @@ static void unmask_IO_APIC_irq (unsigned int irq)
200static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) 229static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
201{ 230{
202 struct IO_APIC_route_entry entry; 231 struct IO_APIC_route_entry entry;
203 unsigned long flags;
204 232
205 /* Check delivery_mode to be sure we're not clearing an SMI pin */ 233 /* Check delivery_mode to be sure we're not clearing an SMI pin */
206 spin_lock_irqsave(&ioapic_lock, flags); 234 entry = ioapic_read_entry(apic, pin);
207 *(((int*)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
208 *(((int*)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
209 spin_unlock_irqrestore(&ioapic_lock, flags);
210 if (entry.delivery_mode == dest_SMI) 235 if (entry.delivery_mode == dest_SMI)
211 return; 236 return;
212 237
@@ -215,10 +240,7 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
215 */ 240 */
216 memset(&entry, 0, sizeof(entry)); 241 memset(&entry, 0, sizeof(entry));
217 entry.mask = 1; 242 entry.mask = 1;
218 spin_lock_irqsave(&ioapic_lock, flags); 243 ioapic_write_entry(apic, pin, entry);
219 io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry) + 0));
220 io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry) + 1));
221 spin_unlock_irqrestore(&ioapic_lock, flags);
222} 244}
223 245
224static void clear_IO_APIC (void) 246static void clear_IO_APIC (void)
@@ -1283,9 +1305,8 @@ static void __init setup_IO_APIC_irqs(void)
1283 if (!apic && (irq < 16)) 1305 if (!apic && (irq < 16))
1284 disable_8259A_irq(irq); 1306 disable_8259A_irq(irq);
1285 } 1307 }
1308 ioapic_write_entry(apic, pin, entry);
1286 spin_lock_irqsave(&ioapic_lock, flags); 1309 spin_lock_irqsave(&ioapic_lock, flags);
1287 io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
1288 io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
1289 set_native_irq_info(irq, TARGET_CPUS); 1310 set_native_irq_info(irq, TARGET_CPUS);
1290 spin_unlock_irqrestore(&ioapic_lock, flags); 1311 spin_unlock_irqrestore(&ioapic_lock, flags);
1291 } 1312 }
@@ -1301,7 +1322,6 @@ static void __init setup_IO_APIC_irqs(void)
1301static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, int vector) 1322static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, int vector)
1302{ 1323{
1303 struct IO_APIC_route_entry entry; 1324 struct IO_APIC_route_entry entry;
1304 unsigned long flags;
1305 1325
1306 memset(&entry,0,sizeof(entry)); 1326 memset(&entry,0,sizeof(entry));
1307 1327
@@ -1331,10 +1351,7 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in
1331 /* 1351 /*
1332 * Add it to the IO-APIC irq-routing table: 1352 * Add it to the IO-APIC irq-routing table:
1333 */ 1353 */
1334 spin_lock_irqsave(&ioapic_lock, flags); 1354 ioapic_write_entry(apic, pin, entry);
1335 io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
1336 io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
1337 spin_unlock_irqrestore(&ioapic_lock, flags);
1338 1355
1339 enable_8259A_irq(0); 1356 enable_8259A_irq(0);
1340} 1357}
@@ -1444,10 +1461,7 @@ void __init print_IO_APIC(void)
1444 for (i = 0; i <= reg_01.bits.entries; i++) { 1461 for (i = 0; i <= reg_01.bits.entries; i++) {
1445 struct IO_APIC_route_entry entry; 1462 struct IO_APIC_route_entry entry;
1446 1463
1447 spin_lock_irqsave(&ioapic_lock, flags); 1464 entry = ioapic_read_entry(apic, i);
1448 *(((int *)&entry)+0) = io_apic_read(apic, 0x10+i*2);
1449 *(((int *)&entry)+1) = io_apic_read(apic, 0x11+i*2);
1450 spin_unlock_irqrestore(&ioapic_lock, flags);
1451 1465
1452 printk(KERN_DEBUG " %02x %03X %02X ", 1466 printk(KERN_DEBUG " %02x %03X %02X ",
1453 i, 1467 i,
@@ -1666,10 +1680,7 @@ static void __init enable_IO_APIC(void)
1666 /* See if any of the pins is in ExtINT mode */ 1680 /* See if any of the pins is in ExtINT mode */
1667 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { 1681 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
1668 struct IO_APIC_route_entry entry; 1682 struct IO_APIC_route_entry entry;
1669 spin_lock_irqsave(&ioapic_lock, flags); 1683 entry = ioapic_read_entry(apic, pin);
1670 *(((int *)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
1671 *(((int *)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
1672 spin_unlock_irqrestore(&ioapic_lock, flags);
1673 1684
1674 1685
1675 /* If the interrupt line is enabled and in ExtInt mode 1686 /* If the interrupt line is enabled and in ExtInt mode
@@ -1726,7 +1737,6 @@ void disable_IO_APIC(void)
1726 */ 1737 */
1727 if (ioapic_i8259.pin != -1) { 1738 if (ioapic_i8259.pin != -1) {
1728 struct IO_APIC_route_entry entry; 1739 struct IO_APIC_route_entry entry;
1729 unsigned long flags;
1730 1740
1731 memset(&entry, 0, sizeof(entry)); 1741 memset(&entry, 0, sizeof(entry));
1732 entry.mask = 0; /* Enabled */ 1742 entry.mask = 0; /* Enabled */
@@ -1743,12 +1753,7 @@ void disable_IO_APIC(void)
1743 /* 1753 /*
1744 * Add it to the IO-APIC irq-routing table: 1754 * Add it to the IO-APIC irq-routing table:
1745 */ 1755 */
1746 spin_lock_irqsave(&ioapic_lock, flags); 1756 ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry);
1747 io_apic_write(ioapic_i8259.apic, 0x11+2*ioapic_i8259.pin,
1748 *(((int *)&entry)+1));
1749 io_apic_write(ioapic_i8259.apic, 0x10+2*ioapic_i8259.pin,
1750 *(((int *)&entry)+0));
1751 spin_unlock_irqrestore(&ioapic_lock, flags);
1752 } 1757 }
1753 disconnect_bsp_APIC(ioapic_i8259.pin != -1); 1758 disconnect_bsp_APIC(ioapic_i8259.pin != -1);
1754} 1759}
@@ -2213,17 +2218,13 @@ static inline void unlock_ExtINT_logic(void)
2213 int apic, pin, i; 2218 int apic, pin, i;
2214 struct IO_APIC_route_entry entry0, entry1; 2219 struct IO_APIC_route_entry entry0, entry1;
2215 unsigned char save_control, save_freq_select; 2220 unsigned char save_control, save_freq_select;
2216 unsigned long flags;
2217 2221
2218 pin = find_isa_irq_pin(8, mp_INT); 2222 pin = find_isa_irq_pin(8, mp_INT);
2219 apic = find_isa_irq_apic(8, mp_INT); 2223 apic = find_isa_irq_apic(8, mp_INT);
2220 if (pin == -1) 2224 if (pin == -1)
2221 return; 2225 return;
2222 2226
2223 spin_lock_irqsave(&ioapic_lock, flags); 2227 entry0 = ioapic_read_entry(apic, pin);
2224 *(((int *)&entry0) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
2225 *(((int *)&entry0) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
2226 spin_unlock_irqrestore(&ioapic_lock, flags);
2227 clear_IO_APIC_pin(apic, pin); 2228 clear_IO_APIC_pin(apic, pin);
2228 2229
2229 memset(&entry1, 0, sizeof(entry1)); 2230 memset(&entry1, 0, sizeof(entry1));
@@ -2236,10 +2237,7 @@ static inline void unlock_ExtINT_logic(void)
2236 entry1.trigger = 0; 2237 entry1.trigger = 0;
2237 entry1.vector = 0; 2238 entry1.vector = 0;
2238 2239
2239 spin_lock_irqsave(&ioapic_lock, flags); 2240 ioapic_write_entry(apic, pin, entry1);
2240 io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry1) + 1));
2241 io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry1) + 0));
2242 spin_unlock_irqrestore(&ioapic_lock, flags);
2243 2241
2244 save_control = CMOS_READ(RTC_CONTROL); 2242 save_control = CMOS_READ(RTC_CONTROL);
2245 save_freq_select = CMOS_READ(RTC_FREQ_SELECT); 2243 save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
@@ -2258,10 +2256,7 @@ static inline void unlock_ExtINT_logic(void)
2258 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); 2256 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
2259 clear_IO_APIC_pin(apic, pin); 2257 clear_IO_APIC_pin(apic, pin);
2260 2258
2261 spin_lock_irqsave(&ioapic_lock, flags); 2259 ioapic_write_entry(apic, pin, entry0);
2262 io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry0) + 1));
2263 io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry0) + 0));
2264 spin_unlock_irqrestore(&ioapic_lock, flags);
2265} 2260}
2266 2261
2267int timer_uses_ioapic_pin_0; 2262int timer_uses_ioapic_pin_0;
@@ -2461,17 +2456,12 @@ static int ioapic_suspend(struct sys_device *dev, pm_message_t state)
2461{ 2456{
2462 struct IO_APIC_route_entry *entry; 2457 struct IO_APIC_route_entry *entry;
2463 struct sysfs_ioapic_data *data; 2458 struct sysfs_ioapic_data *data;
2464 unsigned long flags;
2465 int i; 2459 int i;
2466 2460
2467 data = container_of(dev, struct sysfs_ioapic_data, dev); 2461 data = container_of(dev, struct sysfs_ioapic_data, dev);
2468 entry = data->entry; 2462 entry = data->entry;
2469 spin_lock_irqsave(&ioapic_lock, flags); 2463 for (i = 0; i < nr_ioapic_registers[dev->id]; i ++)
2470 for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) { 2464 entry[i] = ioapic_read_entry(dev->id, i);
2471 *(((int *)entry) + 1) = io_apic_read(dev->id, 0x11 + 2 * i);
2472 *(((int *)entry) + 0) = io_apic_read(dev->id, 0x10 + 2 * i);
2473 }
2474 spin_unlock_irqrestore(&ioapic_lock, flags);
2475 2465
2476 return 0; 2466 return 0;
2477} 2467}
@@ -2493,11 +2483,9 @@ static int ioapic_resume(struct sys_device *dev)
2493 reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid; 2483 reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid;
2494 io_apic_write(dev->id, 0, reg_00.raw); 2484 io_apic_write(dev->id, 0, reg_00.raw);
2495 } 2485 }
2496 for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) {
2497 io_apic_write(dev->id, 0x11+2*i, *(((int *)entry)+1));
2498 io_apic_write(dev->id, 0x10+2*i, *(((int *)entry)+0));
2499 }
2500 spin_unlock_irqrestore(&ioapic_lock, flags); 2486 spin_unlock_irqrestore(&ioapic_lock, flags);
2487 for (i = 0; i < nr_ioapic_registers[dev->id]; i ++)
2488 ioapic_write_entry(dev->id, i, entry[i]);
2501 2489
2502 return 0; 2490 return 0;
2503} 2491}
@@ -2694,9 +2682,8 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a
2694 if (!ioapic && (irq < 16)) 2682 if (!ioapic && (irq < 16))
2695 disable_8259A_irq(irq); 2683 disable_8259A_irq(irq);
2696 2684
2685 ioapic_write_entry(ioapic, pin, entry);
2697 spin_lock_irqsave(&ioapic_lock, flags); 2686 spin_lock_irqsave(&ioapic_lock, flags);
2698 io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1));
2699 io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0));
2700 set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS); 2687 set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS);
2701 spin_unlock_irqrestore(&ioapic_lock, flags); 2688 spin_unlock_irqrestore(&ioapic_lock, flags);
2702 2689
@@ -2704,3 +2691,25 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a
2704} 2691}
2705 2692
2706#endif /* CONFIG_ACPI */ 2693#endif /* CONFIG_ACPI */
2694
2695static int __init parse_disable_timer_pin_1(char *arg)
2696{
2697 disable_timer_pin_1 = 1;
2698 return 0;
2699}
2700early_param("disable_timer_pin_1", parse_disable_timer_pin_1);
2701
2702static int __init parse_enable_timer_pin_1(char *arg)
2703{
2704 disable_timer_pin_1 = -1;
2705 return 0;
2706}
2707early_param("enable_timer_pin_1", parse_enable_timer_pin_1);
2708
2709static int __init parse_noapic(char *arg)
2710{
2711 /* disable IO-APIC */
2712 disable_ioapic_setup();
2713 return 0;
2714}
2715early_param("noapic", parse_noapic);
diff --git a/arch/i386/kernel/machine_kexec.c b/arch/i386/kernel/machine_kexec.c
index 6b1ae6ba76f0..91966bafb3dc 100644
--- a/arch/i386/kernel/machine_kexec.c
+++ b/arch/i386/kernel/machine_kexec.c
@@ -9,6 +9,7 @@
9#include <linux/mm.h> 9#include <linux/mm.h>
10#include <linux/kexec.h> 10#include <linux/kexec.h>
11#include <linux/delay.h> 11#include <linux/delay.h>
12#include <linux/init.h>
12#include <asm/pgtable.h> 13#include <asm/pgtable.h>
13#include <asm/pgalloc.h> 14#include <asm/pgalloc.h>
14#include <asm/tlbflush.h> 15#include <asm/tlbflush.h>
@@ -20,70 +21,13 @@
20#include <asm/system.h> 21#include <asm/system.h>
21 22
22#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) 23#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
23 24static u32 kexec_pgd[1024] PAGE_ALIGNED;
24#define L0_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) 25#ifdef CONFIG_X86_PAE
25#define L1_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) 26static u32 kexec_pmd0[1024] PAGE_ALIGNED;
26#define L2_ATTR (_PAGE_PRESENT) 27static u32 kexec_pmd1[1024] PAGE_ALIGNED;
27
28#define LEVEL0_SIZE (1UL << 12UL)
29
30#ifndef CONFIG_X86_PAE
31#define LEVEL1_SIZE (1UL << 22UL)
32static u32 pgtable_level1[1024] PAGE_ALIGNED;
33
34static void identity_map_page(unsigned long address)
35{
36 unsigned long level1_index, level2_index;
37 u32 *pgtable_level2;
38
39 /* Find the current page table */
40 pgtable_level2 = __va(read_cr3());
41
42 /* Find the indexes of the physical address to identity map */
43 level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
44 level2_index = address / LEVEL1_SIZE;
45
46 /* Identity map the page table entry */
47 pgtable_level1[level1_index] = address | L0_ATTR;
48 pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
49
50 /* Flush the tlb so the new mapping takes effect.
51 * Global tlb entries are not flushed but that is not an issue.
52 */
53 load_cr3(pgtable_level2);
54}
55
56#else
57#define LEVEL1_SIZE (1UL << 21UL)
58#define LEVEL2_SIZE (1UL << 30UL)
59static u64 pgtable_level1[512] PAGE_ALIGNED;
60static u64 pgtable_level2[512] PAGE_ALIGNED;
61
62static void identity_map_page(unsigned long address)
63{
64 unsigned long level1_index, level2_index, level3_index;
65 u64 *pgtable_level3;
66
67 /* Find the current page table */
68 pgtable_level3 = __va(read_cr3());
69
70 /* Find the indexes of the physical address to identity map */
71 level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
72 level2_index = (address % LEVEL2_SIZE)/LEVEL1_SIZE;
73 level3_index = address / LEVEL2_SIZE;
74
75 /* Identity map the page table entry */
76 pgtable_level1[level1_index] = address | L0_ATTR;
77 pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
78 set_64bit(&pgtable_level3[level3_index],
79 __pa(pgtable_level2) | L2_ATTR);
80
81 /* Flush the tlb so the new mapping takes effect.
82 * Global tlb entries are not flushed but that is not an issue.
83 */
84 load_cr3(pgtable_level3);
85}
86#endif 28#endif
29static u32 kexec_pte0[1024] PAGE_ALIGNED;
30static u32 kexec_pte1[1024] PAGE_ALIGNED;
87 31
88static void set_idt(void *newidt, __u16 limit) 32static void set_idt(void *newidt, __u16 limit)
89{ 33{
@@ -127,16 +71,6 @@ static void load_segments(void)
127#undef __STR 71#undef __STR
128} 72}
129 73
130typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)(
131 unsigned long indirection_page,
132 unsigned long reboot_code_buffer,
133 unsigned long start_address,
134 unsigned int has_pae) ATTRIB_NORET;
135
136extern const unsigned char relocate_new_kernel[];
137extern void relocate_new_kernel_end(void);
138extern const unsigned int relocate_new_kernel_size;
139
140/* 74/*
141 * A architecture hook called to validate the 75 * A architecture hook called to validate the
142 * proposed image and prepare the control pages 76 * proposed image and prepare the control pages
@@ -169,25 +103,29 @@ void machine_kexec_cleanup(struct kimage *image)
169 */ 103 */
170NORET_TYPE void machine_kexec(struct kimage *image) 104NORET_TYPE void machine_kexec(struct kimage *image)
171{ 105{
172 unsigned long page_list; 106 unsigned long page_list[PAGES_NR];
173 unsigned long reboot_code_buffer; 107 void *control_page;
174
175 relocate_new_kernel_t rnk;
176 108
177 /* Interrupts aren't acceptable while we reboot */ 109 /* Interrupts aren't acceptable while we reboot */
178 local_irq_disable(); 110 local_irq_disable();
179 111
180 /* Compute some offsets */ 112 control_page = page_address(image->control_code_page);
181 reboot_code_buffer = page_to_pfn(image->control_code_page) 113 memcpy(control_page, relocate_kernel, PAGE_SIZE);
182 << PAGE_SHIFT; 114
183 page_list = image->head; 115 page_list[PA_CONTROL_PAGE] = __pa(control_page);
184 116 page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
185 /* Set up an identity mapping for the reboot_code_buffer */ 117 page_list[PA_PGD] = __pa(kexec_pgd);
186 identity_map_page(reboot_code_buffer); 118 page_list[VA_PGD] = (unsigned long)kexec_pgd;
187 119#ifdef CONFIG_X86_PAE
188 /* copy it out */ 120 page_list[PA_PMD_0] = __pa(kexec_pmd0);
189 memcpy((void *)reboot_code_buffer, relocate_new_kernel, 121 page_list[VA_PMD_0] = (unsigned long)kexec_pmd0;
190 relocate_new_kernel_size); 122 page_list[PA_PMD_1] = __pa(kexec_pmd1);
123 page_list[VA_PMD_1] = (unsigned long)kexec_pmd1;
124#endif
125 page_list[PA_PTE_0] = __pa(kexec_pte0);
126 page_list[VA_PTE_0] = (unsigned long)kexec_pte0;
127 page_list[PA_PTE_1] = __pa(kexec_pte1);
128 page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
191 129
192 /* The segment registers are funny things, they have both a 130 /* The segment registers are funny things, they have both a
193 * visible and an invisible part. Whenever the visible part is 131 * visible and an invisible part. Whenever the visible part is
@@ -206,6 +144,28 @@ NORET_TYPE void machine_kexec(struct kimage *image)
206 set_idt(phys_to_virt(0),0); 144 set_idt(phys_to_virt(0),0);
207 145
208 /* now call it */ 146 /* now call it */
209 rnk = (relocate_new_kernel_t) reboot_code_buffer; 147 relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
210 (*rnk)(page_list, reboot_code_buffer, image->start, cpu_has_pae); 148 image->start, cpu_has_pae);
149}
150
151/* crashkernel=size@addr specifies the location to reserve for
152 * a crash kernel. By reserving this memory we guarantee
153 * that linux never sets it up as a DMA target.
154 * Useful for holding code to do something appropriate
155 * after a kernel panic.
156 */
157static int __init parse_crashkernel(char *arg)
158{
159 unsigned long size, base;
160 size = memparse(arg, &arg);
161 if (*arg == '@') {
162 base = memparse(arg+1, &arg);
163 /* FIXME: Do I want a sanity check
164 * to validate the memory range?
165 */
166 crashk_res.start = base;
167 crashk_res.end = base + size - 1;
168 }
169 return 0;
211} 170}
171early_param("crashkernel", parse_crashkernel);
diff --git a/arch/i386/kernel/mca.c b/arch/i386/kernel/mca.c
index cd5456f14af4..eb57a851789d 100644
--- a/arch/i386/kernel/mca.c
+++ b/arch/i386/kernel/mca.c
@@ -42,6 +42,7 @@
42#include <linux/errno.h> 42#include <linux/errno.h>
43#include <linux/kernel.h> 43#include <linux/kernel.h>
44#include <linux/mca.h> 44#include <linux/mca.h>
45#include <linux/kprobes.h>
45#include <asm/system.h> 46#include <asm/system.h>
46#include <asm/io.h> 47#include <asm/io.h>
47#include <linux/proc_fs.h> 48#include <linux/proc_fs.h>
@@ -414,7 +415,8 @@ subsys_initcall(mca_init);
414 415
415/*--------------------------------------------------------------------*/ 416/*--------------------------------------------------------------------*/
416 417
417static void mca_handle_nmi_device(struct mca_device *mca_dev, int check_flag) 418static __kprobes void
419mca_handle_nmi_device(struct mca_device *mca_dev, int check_flag)
418{ 420{
419 int slot = mca_dev->slot; 421 int slot = mca_dev->slot;
420 422
@@ -444,7 +446,7 @@ static void mca_handle_nmi_device(struct mca_device *mca_dev, int check_flag)
444 446
445/*--------------------------------------------------------------------*/ 447/*--------------------------------------------------------------------*/
446 448
447static int mca_handle_nmi_callback(struct device *dev, void *data) 449static int __kprobes mca_handle_nmi_callback(struct device *dev, void *data)
448{ 450{
449 struct mca_device *mca_dev = to_mca_device(dev); 451 struct mca_device *mca_dev = to_mca_device(dev);
450 unsigned char pos5; 452 unsigned char pos5;
@@ -462,7 +464,7 @@ static int mca_handle_nmi_callback(struct device *dev, void *data)
462 return 0; 464 return 0;
463} 465}
464 466
465void mca_handle_nmi(void) 467void __kprobes mca_handle_nmi(void)
466{ 468{
467 /* First try - scan the various adapters and see if a specific 469 /* First try - scan the various adapters and see if a specific
468 * adapter was responsible for the error. 470 * adapter was responsible for the error.
diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c
index 40b44cc0d14b..9b9479768d5e 100644
--- a/arch/i386/kernel/microcode.c
+++ b/arch/i386/kernel/microcode.c
@@ -2,6 +2,7 @@
2 * Intel CPU Microcode Update Driver for Linux 2 * Intel CPU Microcode Update Driver for Linux
3 * 3 *
4 * Copyright (C) 2000-2004 Tigran Aivazian 4 * Copyright (C) 2000-2004 Tigran Aivazian
5 * 2006 Shaohua Li <shaohua.li@intel.com>
5 * 6 *
6 * This driver allows to upgrade microcode on Intel processors 7 * This driver allows to upgrade microcode on Intel processors
7 * belonging to IA-32 family - PentiumPro, Pentium II, 8 * belonging to IA-32 family - PentiumPro, Pentium II,
@@ -82,6 +83,9 @@
82#include <linux/spinlock.h> 83#include <linux/spinlock.h>
83#include <linux/mm.h> 84#include <linux/mm.h>
84#include <linux/mutex.h> 85#include <linux/mutex.h>
86#include <linux/cpu.h>
87#include <linux/firmware.h>
88#include <linux/platform_device.h>
85 89
86#include <asm/msr.h> 90#include <asm/msr.h>
87#include <asm/uaccess.h> 91#include <asm/uaccess.h>
@@ -91,9 +95,6 @@ MODULE_DESCRIPTION("Intel CPU (IA-32) Microcode Update Driver");
91MODULE_AUTHOR("Tigran Aivazian <tigran@veritas.com>"); 95MODULE_AUTHOR("Tigran Aivazian <tigran@veritas.com>");
92MODULE_LICENSE("GPL"); 96MODULE_LICENSE("GPL");
93 97
94static int verbose;
95module_param(verbose, int, 0644);
96
97#define MICROCODE_VERSION "1.14a" 98#define MICROCODE_VERSION "1.14a"
98 99
99#define DEFAULT_UCODE_DATASIZE (2000) /* 2000 bytes */ 100#define DEFAULT_UCODE_DATASIZE (2000) /* 2000 bytes */
@@ -120,55 +121,40 @@ static DEFINE_SPINLOCK(microcode_update_lock);
120/* no concurrent ->write()s are allowed on /dev/cpu/microcode */ 121/* no concurrent ->write()s are allowed on /dev/cpu/microcode */
121static DEFINE_MUTEX(microcode_mutex); 122static DEFINE_MUTEX(microcode_mutex);
122 123
123static void __user *user_buffer; /* user area microcode data buffer */
124static unsigned int user_buffer_size; /* it's size */
125
126typedef enum mc_error_code {
127 MC_SUCCESS = 0,
128 MC_IGNORED = 1,
129 MC_NOTFOUND = 2,
130 MC_MARKED = 3,
131 MC_ALLOCATED = 4,
132} mc_error_code_t;
133
134static struct ucode_cpu_info { 124static struct ucode_cpu_info {
125 int valid;
135 unsigned int sig; 126 unsigned int sig;
136 unsigned int pf, orig_pf; 127 unsigned int pf;
137 unsigned int rev; 128 unsigned int rev;
138 unsigned int cksum;
139 mc_error_code_t err;
140 microcode_t *mc; 129 microcode_t *mc;
141} ucode_cpu_info[NR_CPUS]; 130} ucode_cpu_info[NR_CPUS];
142
143static int microcode_open (struct inode *unused1, struct file *unused2)
144{
145 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
146}
147 131
148static void collect_cpu_info (void *unused) 132static void collect_cpu_info(int cpu_num)
149{ 133{
150 int cpu_num = smp_processor_id();
151 struct cpuinfo_x86 *c = cpu_data + cpu_num; 134 struct cpuinfo_x86 *c = cpu_data + cpu_num;
152 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 135 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
153 unsigned int val[2]; 136 unsigned int val[2];
154 137
155 uci->sig = uci->pf = uci->rev = uci->cksum = 0; 138 /* We should bind the task to the CPU */
156 uci->err = MC_NOTFOUND; 139 BUG_ON(raw_smp_processor_id() != cpu_num);
140 uci->pf = uci->rev = 0;
157 uci->mc = NULL; 141 uci->mc = NULL;
142 uci->valid = 1;
158 143
159 if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || 144 if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 ||
160 cpu_has(c, X86_FEATURE_IA64)) { 145 cpu_has(c, X86_FEATURE_IA64)) {
161 printk(KERN_ERR "microcode: CPU%d not a capable Intel processor\n", cpu_num); 146 printk(KERN_ERR "microcode: CPU%d not a capable Intel "
147 "processor\n", cpu_num);
148 uci->valid = 0;
162 return; 149 return;
163 } else { 150 }
164 uci->sig = cpuid_eax(0x00000001);
165 151
166 if ((c->x86_model >= 5) || (c->x86 > 6)) { 152 uci->sig = cpuid_eax(0x00000001);
167 /* get processor flags from MSR 0x17 */ 153
168 rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); 154 if ((c->x86_model >= 5) || (c->x86 > 6)) {
169 uci->pf = 1 << ((val[1] >> 18) & 7); 155 /* get processor flags from MSR 0x17 */
170 } 156 rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
171 uci->orig_pf = uci->pf; 157 uci->pf = 1 << ((val[1] >> 18) & 7);
172 } 158 }
173 159
174 wrmsr(MSR_IA32_UCODE_REV, 0, 0); 160 wrmsr(MSR_IA32_UCODE_REV, 0, 0);
@@ -180,218 +166,159 @@ static void collect_cpu_info (void *unused)
180 uci->sig, uci->pf, uci->rev); 166 uci->sig, uci->pf, uci->rev);
181} 167}
182 168
183static inline void mark_microcode_update (int cpu_num, microcode_header_t *mc_header, int sig, int pf, int cksum) 169static inline int microcode_update_match(int cpu_num,
170 microcode_header_t *mc_header, int sig, int pf)
184{ 171{
185 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 172 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
186 173
187 pr_debug("Microcode Found.\n"); 174 if (!sigmatch(sig, uci->sig, pf, uci->pf)
188 pr_debug(" Header Revision 0x%x\n", mc_header->hdrver); 175 || mc_header->rev <= uci->rev)
189 pr_debug(" Loader Revision 0x%x\n", mc_header->ldrver); 176 return 0;
190 pr_debug(" Revision 0x%x \n", mc_header->rev); 177 return 1;
191 pr_debug(" Date %x/%x/%x\n",
192 ((mc_header->date >> 24 ) & 0xff),
193 ((mc_header->date >> 16 ) & 0xff),
194 (mc_header->date & 0xFFFF));
195 pr_debug(" Signature 0x%x\n", sig);
196 pr_debug(" Type 0x%x Family 0x%x Model 0x%x Stepping 0x%x\n",
197 ((sig >> 12) & 0x3),
198 ((sig >> 8) & 0xf),
199 ((sig >> 4) & 0xf),
200 ((sig & 0xf)));
201 pr_debug(" Processor Flags 0x%x\n", pf);
202 pr_debug(" Checksum 0x%x\n", cksum);
203
204 if (mc_header->rev < uci->rev) {
205 if (uci->err == MC_NOTFOUND) {
206 uci->err = MC_IGNORED;
207 uci->cksum = mc_header->rev;
208 } else if (uci->err == MC_IGNORED && uci->cksum < mc_header->rev)
209 uci->cksum = mc_header->rev;
210 } else if (mc_header->rev == uci->rev) {
211 if (uci->err < MC_MARKED) {
212 /* notify the caller of success on this cpu */
213 uci->err = MC_SUCCESS;
214 }
215 } else if (uci->err != MC_ALLOCATED || mc_header->rev > uci->mc->hdr.rev) {
216 pr_debug("microcode: CPU%d found a matching microcode update with "
217 " revision 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev);
218 uci->cksum = cksum;
219 uci->pf = pf; /* keep the original mc pf for cksum calculation */
220 uci->err = MC_MARKED; /* found the match */
221 for_each_online_cpu(cpu_num) {
222 if (ucode_cpu_info + cpu_num != uci
223 && ucode_cpu_info[cpu_num].mc == uci->mc) {
224 uci->mc = NULL;
225 break;
226 }
227 }
228 if (uci->mc != NULL) {
229 vfree(uci->mc);
230 uci->mc = NULL;
231 }
232 }
233 return;
234} 178}
235 179
236static int find_matching_ucodes (void) 180static int microcode_sanity_check(void *mc)
237{ 181{
238 int cursor = 0; 182 microcode_header_t *mc_header = mc;
239 int error = 0; 183 struct extended_sigtable *ext_header = NULL;
240 184 struct extended_signature *ext_sig;
241 while (cursor + MC_HEADER_SIZE < user_buffer_size) { 185 unsigned long total_size, data_size, ext_table_size;
242 microcode_header_t mc_header; 186 int sum, orig_sum, ext_sigcount = 0, i;
243 void *newmc = NULL; 187
244 int i, sum, cpu_num, allocated_flag, total_size, data_size, ext_table_size; 188 total_size = get_totalsize(mc_header);
189 data_size = get_datasize(mc_header);
190 if (data_size + MC_HEADER_SIZE > total_size) {
191 printk(KERN_ERR "microcode: error! "
192 "Bad data size in microcode data file\n");
193 return -EINVAL;
194 }
245 195
246 if (copy_from_user(&mc_header, user_buffer + cursor, MC_HEADER_SIZE)) { 196 if (mc_header->ldrver != 1 || mc_header->hdrver != 1) {
247 printk(KERN_ERR "microcode: error! Can not read user data\n"); 197 printk(KERN_ERR "microcode: error! "
248 error = -EFAULT; 198 "Unknown microcode update format\n");
249 goto out; 199 return -EINVAL;
200 }
201 ext_table_size = total_size - (MC_HEADER_SIZE + data_size);
202 if (ext_table_size) {
203 if ((ext_table_size < EXT_HEADER_SIZE)
204 || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) {
205 printk(KERN_ERR "microcode: error! "
206 "Small exttable size in microcode data file\n");
207 return -EINVAL;
250 } 208 }
251 209 ext_header = mc + MC_HEADER_SIZE + data_size;
252 total_size = get_totalsize(&mc_header); 210 if (ext_table_size != exttable_size(ext_header)) {
253 if ((cursor + total_size > user_buffer_size) || (total_size < DEFAULT_UCODE_TOTALSIZE)) { 211 printk(KERN_ERR "microcode: error! "
254 printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); 212 "Bad exttable size in microcode data file\n");
255 error = -EINVAL; 213 return -EFAULT;
256 goto out;
257 } 214 }
215 ext_sigcount = ext_header->count;
216 }
258 217
259 data_size = get_datasize(&mc_header); 218 /* check extended table checksum */
260 if ((data_size + MC_HEADER_SIZE > total_size) || (data_size < DEFAULT_UCODE_DATASIZE)) { 219 if (ext_table_size) {
261 printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); 220 int ext_table_sum = 0;
262 error = -EINVAL; 221 int *ext_tablep = (int *)ext_header;
263 goto out; 222
223 i = ext_table_size / DWSIZE;
224 while (i--)
225 ext_table_sum += ext_tablep[i];
226 if (ext_table_sum) {
227 printk(KERN_WARNING "microcode: aborting, "
228 "bad extended signature table checksum\n");
229 return -EINVAL;
264 } 230 }
231 }
265 232
266 if (mc_header.ldrver != 1 || mc_header.hdrver != 1) { 233 /* calculate the checksum */
267 printk(KERN_ERR "microcode: error! Unknown microcode update format\n"); 234 orig_sum = 0;
268 error = -EINVAL; 235 i = (MC_HEADER_SIZE + data_size) / DWSIZE;
269 goto out; 236 while (i--)
237 orig_sum += ((int *)mc)[i];
238 if (orig_sum) {
239 printk(KERN_ERR "microcode: aborting, bad checksum\n");
240 return -EINVAL;
241 }
242 if (!ext_table_size)
243 return 0;
244 /* check extended signature checksum */
245 for (i = 0; i < ext_sigcount; i++) {
246 ext_sig = (struct extended_signature *)((void *)ext_header
247 + EXT_HEADER_SIZE + EXT_SIGNATURE_SIZE * i);
248 sum = orig_sum
249 - (mc_header->sig + mc_header->pf + mc_header->cksum)
250 + (ext_sig->sig + ext_sig->pf + ext_sig->cksum);
251 if (sum) {
252 printk(KERN_ERR "microcode: aborting, bad checksum\n");
253 return -EINVAL;
270 } 254 }
255 }
256 return 0;
257}
271 258
272 for_each_online_cpu(cpu_num) { 259/*
273 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 260 * return 0 - no update found
274 261 * return 1 - found update
275 if (sigmatch(mc_header.sig, uci->sig, mc_header.pf, uci->orig_pf)) 262 * return < 0 - error
276 mark_microcode_update(cpu_num, &mc_header, mc_header.sig, mc_header.pf, mc_header.cksum); 263 */
277 } 264static int get_maching_microcode(void *mc, int cpu)
265{
266 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
267 microcode_header_t *mc_header = mc;
268 struct extended_sigtable *ext_header;
269 unsigned long total_size = get_totalsize(mc_header);
270 int ext_sigcount, i;
271 struct extended_signature *ext_sig;
272 void *new_mc;
273
274 if (microcode_update_match(cpu, mc_header,
275 mc_header->sig, mc_header->pf))
276 goto find;
277
278 if (total_size <= get_datasize(mc_header) + MC_HEADER_SIZE)
279 return 0;
280
281 ext_header = (struct extended_sigtable *)(mc +
282 get_datasize(mc_header) + MC_HEADER_SIZE);
283 ext_sigcount = ext_header->count;
284 ext_sig = (struct extended_signature *)((void *)ext_header
285 + EXT_HEADER_SIZE);
286 for (i = 0; i < ext_sigcount; i++) {
287 if (microcode_update_match(cpu, mc_header,
288 ext_sig->sig, ext_sig->pf))
289 goto find;
290 ext_sig++;
291 }
292 return 0;
293find:
294 pr_debug("microcode: CPU %d found a matching microcode update with"
295 " version 0x%x (current=0x%x)\n", cpu, mc_header->rev,uci->rev);
296 new_mc = vmalloc(total_size);
297 if (!new_mc) {
298 printk(KERN_ERR "microcode: error! Can not allocate memory\n");
299 return -ENOMEM;
300 }
278 301
279 ext_table_size = total_size - (MC_HEADER_SIZE + data_size); 302 /* free previous update file */
280 if (ext_table_size) { 303 vfree(uci->mc);
281 struct extended_sigtable ext_header;
282 struct extended_signature ext_sig;
283 int ext_sigcount;
284 304
285 if ((ext_table_size < EXT_HEADER_SIZE) 305 memcpy(new_mc, mc, total_size);
286 || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) { 306 uci->mc = new_mc;
287 printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); 307 return 1;
288 error = -EINVAL;
289 goto out;
290 }
291 if (copy_from_user(&ext_header, user_buffer + cursor
292 + MC_HEADER_SIZE + data_size, EXT_HEADER_SIZE)) {
293 printk(KERN_ERR "microcode: error! Can not read user data\n");
294 error = -EFAULT;
295 goto out;
296 }
297 if (ext_table_size != exttable_size(&ext_header)) {
298 printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");
299 error = -EFAULT;
300 goto out;
301 }
302
303 ext_sigcount = ext_header.count;
304
305 for (i = 0; i < ext_sigcount; i++) {
306 if (copy_from_user(&ext_sig, user_buffer + cursor + MC_HEADER_SIZE + data_size + EXT_HEADER_SIZE
307 + EXT_SIGNATURE_SIZE * i, EXT_SIGNATURE_SIZE)) {
308 printk(KERN_ERR "microcode: error! Can not read user data\n");
309 error = -EFAULT;
310 goto out;
311 }
312 for_each_online_cpu(cpu_num) {
313 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
314
315 if (sigmatch(ext_sig.sig, uci->sig, ext_sig.pf, uci->orig_pf)) {
316 mark_microcode_update(cpu_num, &mc_header, ext_sig.sig, ext_sig.pf, ext_sig.cksum);
317 }
318 }
319 }
320 }
321 /* now check if any cpu has matched */
322 allocated_flag = 0;
323 sum = 0;
324 for_each_online_cpu(cpu_num) {
325 if (ucode_cpu_info[cpu_num].err == MC_MARKED) {
326 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
327 if (!allocated_flag) {
328 allocated_flag = 1;
329 newmc = vmalloc(total_size);
330 if (!newmc) {
331 printk(KERN_ERR "microcode: error! Can not allocate memory\n");
332 error = -ENOMEM;
333 goto out;
334 }
335 if (copy_from_user(newmc + MC_HEADER_SIZE,
336 user_buffer + cursor + MC_HEADER_SIZE,
337 total_size - MC_HEADER_SIZE)) {
338 printk(KERN_ERR "microcode: error! Can not read user data\n");
339 vfree(newmc);
340 error = -EFAULT;
341 goto out;
342 }
343 memcpy(newmc, &mc_header, MC_HEADER_SIZE);
344 /* check extended table checksum */
345 if (ext_table_size) {
346 int ext_table_sum = 0;
347 int * ext_tablep = (((void *) newmc) + MC_HEADER_SIZE + data_size);
348 i = ext_table_size / DWSIZE;
349 while (i--) ext_table_sum += ext_tablep[i];
350 if (ext_table_sum) {
351 printk(KERN_WARNING "microcode: aborting, bad extended signature table checksum\n");
352 vfree(newmc);
353 error = -EINVAL;
354 goto out;
355 }
356 }
357
358 /* calculate the checksum */
359 i = (MC_HEADER_SIZE + data_size) / DWSIZE;
360 while (i--) sum += ((int *)newmc)[i];
361 sum -= (mc_header.sig + mc_header.pf + mc_header.cksum);
362 }
363 ucode_cpu_info[cpu_num].mc = newmc;
364 ucode_cpu_info[cpu_num].err = MC_ALLOCATED; /* mc updated */
365 if (sum + uci->sig + uci->pf + uci->cksum != 0) {
366 printk(KERN_ERR "microcode: CPU%d aborting, bad checksum\n", cpu_num);
367 error = -EINVAL;
368 goto out;
369 }
370 }
371 }
372 cursor += total_size; /* goto the next update patch */
373 } /* end of while */
374out:
375 return error;
376} 308}
377 309
378static void do_update_one (void * unused) 310static void apply_microcode(int cpu)
379{ 311{
380 unsigned long flags; 312 unsigned long flags;
381 unsigned int val[2]; 313 unsigned int val[2];
382 int cpu_num = smp_processor_id(); 314 int cpu_num = raw_smp_processor_id();
383 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; 315 struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
384 316
385 if (uci->mc == NULL) { 317 /* We should bind the task to the CPU */
386 if (verbose) { 318 BUG_ON(cpu_num != cpu);
387 if (uci->err == MC_SUCCESS) 319
388 printk(KERN_INFO "microcode: CPU%d already at revision 0x%x\n", 320 if (uci->mc == NULL)
389 cpu_num, uci->rev);
390 else
391 printk(KERN_INFO "microcode: No new microcode data for CPU%d\n", cpu_num);
392 }
393 return; 321 return;
394 }
395 322
396 /* serialize access to the physical write to MSR 0x79 */ 323 /* serialize access to the physical write to MSR 0x79 */
397 spin_lock_irqsave(&microcode_update_lock, flags); 324 spin_lock_irqsave(&microcode_update_lock, flags);
@@ -408,68 +335,107 @@ static void do_update_one (void * unused)
408 /* get the current revision from MSR 0x8B */ 335 /* get the current revision from MSR 0x8B */
409 rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); 336 rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
410 337
411 /* notify the caller of success on this cpu */
412 uci->err = MC_SUCCESS;
413 spin_unlock_irqrestore(&microcode_update_lock, flags); 338 spin_unlock_irqrestore(&microcode_update_lock, flags);
414 printk(KERN_INFO "microcode: CPU%d updated from revision " 339 if (val[1] != uci->mc->hdr.rev) {
340 printk(KERN_ERR "microcode: CPU%d updated from revision "
341 "0x%x to 0x%x failed\n", cpu_num, uci->rev, val[1]);
342 return;
343 }
344 pr_debug("microcode: CPU%d updated from revision "
415 "0x%x to 0x%x, date = %08x \n", 345 "0x%x to 0x%x, date = %08x \n",
416 cpu_num, uci->rev, val[1], uci->mc->hdr.date); 346 cpu_num, uci->rev, val[1], uci->mc->hdr.date);
417 return; 347 uci->rev = val[1];
418} 348}
419 349
420static int do_microcode_update (void) 350#ifdef CONFIG_MICROCODE_OLD_INTERFACE
421{ 351static void __user *user_buffer; /* user area microcode data buffer */
422 int i, error; 352static unsigned int user_buffer_size; /* it's size */
423 353
424 if (on_each_cpu(collect_cpu_info, NULL, 1, 1) != 0) { 354static long get_next_ucode(void **mc, long offset)
425 printk(KERN_ERR "microcode: Error! Could not run on all processors\n"); 355{
426 error = -EIO; 356 microcode_header_t mc_header;
427 goto out; 357 unsigned long total_size;
358
359 /* No more data */
360 if (offset >= user_buffer_size)
361 return 0;
362 if (copy_from_user(&mc_header, user_buffer + offset, MC_HEADER_SIZE)) {
363 printk(KERN_ERR "microcode: error! Can not read user data\n");
364 return -EFAULT;
428 } 365 }
429 366 total_size = get_totalsize(&mc_header);
430 if ((error = find_matching_ucodes())) { 367 if (offset + total_size > user_buffer_size) {
431 printk(KERN_ERR "microcode: Error in the microcode data\n"); 368 printk(KERN_ERR "microcode: error! Bad total size in microcode "
432 goto out_free; 369 "data file\n");
370 return -EINVAL;
433 } 371 }
434 372 *mc = vmalloc(total_size);
435 if (on_each_cpu(do_update_one, NULL, 1, 1) != 0) { 373 if (!*mc)
436 printk(KERN_ERR "microcode: Error! Could not run on all processors\n"); 374 return -ENOMEM;
437 error = -EIO; 375 if (copy_from_user(*mc, user_buffer + offset, total_size)) {
376 printk(KERN_ERR "microcode: error! Can not read user data\n");
377 vfree(*mc);
378 return -EFAULT;
438 } 379 }
380 return offset + total_size;
381}
382
383static int do_microcode_update (void)
384{
385 long cursor = 0;
386 int error = 0;
387 void *new_mc;
388 int cpu;
389 cpumask_t old;
390
391 old = current->cpus_allowed;
439 392
440out_free: 393 while ((cursor = get_next_ucode(&new_mc, cursor)) > 0) {
441 for_each_online_cpu(i) { 394 error = microcode_sanity_check(new_mc);
442 if (ucode_cpu_info[i].mc) { 395 if (error)
443 int j; 396 goto out;
444 void *tmp = ucode_cpu_info[i].mc; 397 /*
445 vfree(tmp); 398 * It's possible the data file has multiple matching ucode,
446 for_each_online_cpu(j) { 399 * lets keep searching till the latest version
447 if (ucode_cpu_info[j].mc == tmp) 400 */
448 ucode_cpu_info[j].mc = NULL; 401 for_each_online_cpu(cpu) {
449 } 402 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
403
404 if (!uci->valid)
405 continue;
406 set_cpus_allowed(current, cpumask_of_cpu(cpu));
407 error = get_maching_microcode(new_mc, cpu);
408 if (error < 0)
409 goto out;
410 if (error == 1)
411 apply_microcode(cpu);
450 } 412 }
451 if (ucode_cpu_info[i].err == MC_IGNORED && verbose) 413 vfree(new_mc);
452 printk(KERN_WARNING "microcode: CPU%d not 'upgrading' to earlier revision"
453 " 0x%x (current=0x%x)\n", i, ucode_cpu_info[i].cksum, ucode_cpu_info[i].rev);
454 } 414 }
455out: 415out:
416 if (cursor > 0)
417 vfree(new_mc);
418 if (cursor < 0)
419 error = cursor;
420 set_cpus_allowed(current, old);
456 return error; 421 return error;
457} 422}
458 423
424static int microcode_open (struct inode *unused1, struct file *unused2)
425{
426 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
427}
428
459static ssize_t microcode_write (struct file *file, const char __user *buf, size_t len, loff_t *ppos) 429static ssize_t microcode_write (struct file *file, const char __user *buf, size_t len, loff_t *ppos)
460{ 430{
461 ssize_t ret; 431 ssize_t ret;
462 432
463 if (len < DEFAULT_UCODE_TOTALSIZE) {
464 printk(KERN_ERR "microcode: not enough data\n");
465 return -EINVAL;
466 }
467
468 if ((len >> PAGE_SHIFT) > num_physpages) { 433 if ((len >> PAGE_SHIFT) > num_physpages) {
469 printk(KERN_ERR "microcode: too much data (max %ld pages)\n", num_physpages); 434 printk(KERN_ERR "microcode: too much data (max %ld pages)\n", num_physpages);
470 return -EINVAL; 435 return -EINVAL;
471 } 436 }
472 437
438 lock_cpu_hotplug();
473 mutex_lock(&microcode_mutex); 439 mutex_lock(&microcode_mutex);
474 440
475 user_buffer = (void __user *) buf; 441 user_buffer = (void __user *) buf;
@@ -480,6 +446,7 @@ static ssize_t microcode_write (struct file *file, const char __user *buf, size_
480 ret = (ssize_t)len; 446 ret = (ssize_t)len;
481 447
482 mutex_unlock(&microcode_mutex); 448 mutex_unlock(&microcode_mutex);
449 unlock_cpu_hotplug();
483 450
484 return ret; 451 return ret;
485} 452}
@@ -496,7 +463,7 @@ static struct miscdevice microcode_dev = {
496 .fops = &microcode_fops, 463 .fops = &microcode_fops,
497}; 464};
498 465
499static int __init microcode_init (void) 466static int __init microcode_dev_init (void)
500{ 467{
501 int error; 468 int error;
502 469
@@ -508,6 +475,280 @@ static int __init microcode_init (void)
508 return error; 475 return error;
509 } 476 }
510 477
478 return 0;
479}
480
481static void __exit microcode_dev_exit (void)
482{
483 misc_deregister(&microcode_dev);
484}
485
486MODULE_ALIAS_MISCDEV(MICROCODE_MINOR);
487#else
488#define microcode_dev_init() 0
489#define microcode_dev_exit() do { } while(0)
490#endif
491
492static long get_next_ucode_from_buffer(void **mc, void *buf,
493 unsigned long size, long offset)
494{
495 microcode_header_t *mc_header;
496 unsigned long total_size;
497
498 /* No more data */
499 if (offset >= size)
500 return 0;
501 mc_header = (microcode_header_t *)(buf + offset);
502 total_size = get_totalsize(mc_header);
503
504 if (offset + total_size > size) {
505 printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");
506 return -EINVAL;
507 }
508
509 *mc = vmalloc(total_size);
510 if (!*mc) {
511 printk(KERN_ERR "microcode: error! Can not allocate memory\n");
512 return -ENOMEM;
513 }
514 memcpy(*mc, buf + offset, total_size);
515 return offset + total_size;
516}
517
518/* fake device for request_firmware */
519static struct platform_device *microcode_pdev;
520
521static int cpu_request_microcode(int cpu)
522{
523 char name[30];
524 struct cpuinfo_x86 *c = cpu_data + cpu;
525 const struct firmware *firmware;
526 void *buf;
527 unsigned long size;
528 long offset = 0;
529 int error;
530 void *mc;
531
532 /* We should bind the task to the CPU */
533 BUG_ON(cpu != raw_smp_processor_id());
534 sprintf(name,"intel-ucode/%02x-%02x-%02x",
535 c->x86, c->x86_model, c->x86_mask);
536 error = request_firmware(&firmware, name, &microcode_pdev->dev);
537 if (error) {
538 pr_debug("ucode data file %s load failed\n", name);
539 return error;
540 }
541 buf = (void *)firmware->data;
542 size = firmware->size;
543 while ((offset = get_next_ucode_from_buffer(&mc, buf, size, offset))
544 > 0) {
545 error = microcode_sanity_check(mc);
546 if (error)
547 break;
548 error = get_maching_microcode(mc, cpu);
549 if (error < 0)
550 break;
551 /*
552 * It's possible the data file has multiple matching ucode,
553 * lets keep searching till the latest version
554 */
555 if (error == 1) {
556 apply_microcode(cpu);
557 error = 0;
558 }
559 vfree(mc);
560 }
561 if (offset > 0)
562 vfree(mc);
563 if (offset < 0)
564 error = offset;
565 release_firmware(firmware);
566
567 return error;
568}
569
570static void microcode_init_cpu(int cpu)
571{
572 cpumask_t old;
573 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
574
575 old = current->cpus_allowed;
576
577 set_cpus_allowed(current, cpumask_of_cpu(cpu));
578 mutex_lock(&microcode_mutex);
579 collect_cpu_info(cpu);
580 if (uci->valid)
581 cpu_request_microcode(cpu);
582 mutex_unlock(&microcode_mutex);
583 set_cpus_allowed(current, old);
584}
585
586static void microcode_fini_cpu(int cpu)
587{
588 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
589
590 mutex_lock(&microcode_mutex);
591 uci->valid = 0;
592 vfree(uci->mc);
593 uci->mc = NULL;
594 mutex_unlock(&microcode_mutex);
595}
596
597static ssize_t reload_store(struct sys_device *dev, const char *buf, size_t sz)
598{
599 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
600 char *end;
601 unsigned long val = simple_strtoul(buf, &end, 0);
602 int err = 0;
603 int cpu = dev->id;
604
605 if (end == buf)
606 return -EINVAL;
607 if (val == 1) {
608 cpumask_t old;
609
610 old = current->cpus_allowed;
611
612 lock_cpu_hotplug();
613 set_cpus_allowed(current, cpumask_of_cpu(cpu));
614
615 mutex_lock(&microcode_mutex);
616 if (uci->valid)
617 err = cpu_request_microcode(cpu);
618 mutex_unlock(&microcode_mutex);
619 unlock_cpu_hotplug();
620 set_cpus_allowed(current, old);
621 }
622 if (err)
623 return err;
624 return sz;
625}
626
627static ssize_t version_show(struct sys_device *dev, char *buf)
628{
629 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
630
631 return sprintf(buf, "0x%x\n", uci->rev);
632}
633
634static ssize_t pf_show(struct sys_device *dev, char *buf)
635{
636 struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
637
638 return sprintf(buf, "0x%x\n", uci->pf);
639}
640
641static SYSDEV_ATTR(reload, 0200, NULL, reload_store);
642static SYSDEV_ATTR(version, 0400, version_show, NULL);
643static SYSDEV_ATTR(processor_flags, 0400, pf_show, NULL);
644
645static struct attribute *mc_default_attrs[] = {
646 &attr_reload.attr,
647 &attr_version.attr,
648 &attr_processor_flags.attr,
649 NULL
650};
651
652static struct attribute_group mc_attr_group = {
653 .attrs = mc_default_attrs,
654 .name = "microcode",
655};
656
657static int mc_sysdev_add(struct sys_device *sys_dev)
658{
659 int cpu = sys_dev->id;
660 struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
661
662 if (!cpu_online(cpu))
663 return 0;
664 pr_debug("Microcode:CPU %d added\n", cpu);
665 memset(uci, 0, sizeof(*uci));
666 sysfs_create_group(&sys_dev->kobj, &mc_attr_group);
667
668 microcode_init_cpu(cpu);
669 return 0;
670}
671
672static int mc_sysdev_remove(struct sys_device *sys_dev)
673{
674 int cpu = sys_dev->id;
675
676 if (!cpu_online(cpu))
677 return 0;
678 pr_debug("Microcode:CPU %d removed\n", cpu);
679 microcode_fini_cpu(cpu);
680 sysfs_remove_group(&sys_dev->kobj, &mc_attr_group);
681 return 0;
682}
683
684static int mc_sysdev_resume(struct sys_device *dev)
685{
686 int cpu = dev->id;
687
688 if (!cpu_online(cpu))
689 return 0;
690 pr_debug("Microcode:CPU %d resumed\n", cpu);
691 /* only CPU 0 will apply ucode here */
692 apply_microcode(0);
693 return 0;
694}
695
696static struct sysdev_driver mc_sysdev_driver = {
697 .add = mc_sysdev_add,
698 .remove = mc_sysdev_remove,
699 .resume = mc_sysdev_resume,
700};
701
702#ifdef CONFIG_HOTPLUG_CPU
703static __cpuinit int
704mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)
705{
706 unsigned int cpu = (unsigned long)hcpu;
707 struct sys_device *sys_dev;
708
709 sys_dev = get_cpu_sysdev(cpu);
710 switch (action) {
711 case CPU_ONLINE:
712 case CPU_DOWN_FAILED:
713 mc_sysdev_add(sys_dev);
714 break;
715 case CPU_DOWN_PREPARE:
716 mc_sysdev_remove(sys_dev);
717 break;
718 }
719 return NOTIFY_OK;
720}
721
722static struct notifier_block mc_cpu_notifier = {
723 .notifier_call = mc_cpu_callback,
724};
725#endif
726
727static int __init microcode_init (void)
728{
729 int error;
730
731 error = microcode_dev_init();
732 if (error)
733 return error;
734 microcode_pdev = platform_device_register_simple("microcode", -1,
735 NULL, 0);
736 if (IS_ERR(microcode_pdev)) {
737 microcode_dev_exit();
738 return PTR_ERR(microcode_pdev);
739 }
740
741 lock_cpu_hotplug();
742 error = sysdev_driver_register(&cpu_sysdev_class, &mc_sysdev_driver);
743 unlock_cpu_hotplug();
744 if (error) {
745 microcode_dev_exit();
746 platform_device_unregister(microcode_pdev);
747 return error;
748 }
749
750 register_hotcpu_notifier(&mc_cpu_notifier);
751
511 printk(KERN_INFO 752 printk(KERN_INFO
512 "IA-32 Microcode Update Driver: v" MICROCODE_VERSION " <tigran@veritas.com>\n"); 753 "IA-32 Microcode Update Driver: v" MICROCODE_VERSION " <tigran@veritas.com>\n");
513 return 0; 754 return 0;
@@ -515,9 +756,16 @@ static int __init microcode_init (void)
515 756
516static void __exit microcode_exit (void) 757static void __exit microcode_exit (void)
517{ 758{
518 misc_deregister(&microcode_dev); 759 microcode_dev_exit();
760
761 unregister_hotcpu_notifier(&mc_cpu_notifier);
762
763 lock_cpu_hotplug();
764 sysdev_driver_unregister(&cpu_sysdev_class, &mc_sysdev_driver);
765 unlock_cpu_hotplug();
766
767 platform_device_unregister(microcode_pdev);
519} 768}
520 769
521module_init(microcode_init) 770module_init(microcode_init)
522module_exit(microcode_exit) 771module_exit(microcode_exit)
523MODULE_ALIAS_MISCDEV(MICROCODE_MINOR);
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index a70b5fa0ef06..442aaf8c77eb 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -30,6 +30,7 @@
30#include <asm/io_apic.h> 30#include <asm/io_apic.h>
31 31
32#include <mach_apic.h> 32#include <mach_apic.h>
33#include <mach_apicdef.h>
33#include <mach_mpparse.h> 34#include <mach_mpparse.h>
34#include <bios_ebda.h> 35#include <bios_ebda.h>
35 36
@@ -68,7 +69,7 @@ unsigned int def_to_bigsmp = 0;
68/* Processor that is doing the boot up */ 69/* Processor that is doing the boot up */
69unsigned int boot_cpu_physical_apicid = -1U; 70unsigned int boot_cpu_physical_apicid = -1U;
70/* Internal processor count */ 71/* Internal processor count */
71static unsigned int __devinitdata num_processors; 72unsigned int __cpuinitdata num_processors;
72 73
73/* Bitmask of physically existing CPUs */ 74/* Bitmask of physically existing CPUs */
74physid_mask_t phys_cpu_present_map; 75physid_mask_t phys_cpu_present_map;
@@ -228,12 +229,14 @@ static void __init MP_bus_info (struct mpc_config_bus *m)
228 229
229 mpc_oem_bus_info(m, str, translation_table[mpc_record]); 230 mpc_oem_bus_info(m, str, translation_table[mpc_record]);
230 231
232#if MAX_MP_BUSSES < 256
231 if (m->mpc_busid >= MAX_MP_BUSSES) { 233 if (m->mpc_busid >= MAX_MP_BUSSES) {
232 printk(KERN_WARNING "MP table busid value (%d) for bustype %s " 234 printk(KERN_WARNING "MP table busid value (%d) for bustype %s "
233 " is too large, max. supported is %d\n", 235 " is too large, max. supported is %d\n",
234 m->mpc_busid, str, MAX_MP_BUSSES - 1); 236 m->mpc_busid, str, MAX_MP_BUSSES - 1);
235 return; 237 return;
236 } 238 }
239#endif
237 240
238 if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) { 241 if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) {
239 mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; 242 mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA;
@@ -293,19 +296,6 @@ static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m)
293 m->mpc_irqtype, m->mpc_irqflag & 3, 296 m->mpc_irqtype, m->mpc_irqflag & 3,
294 (m->mpc_irqflag >> 2) &3, m->mpc_srcbusid, 297 (m->mpc_irqflag >> 2) &3, m->mpc_srcbusid,
295 m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint); 298 m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint);
296 /*
297 * Well it seems all SMP boards in existence
298 * use ExtINT/LVT1 == LINT0 and
299 * NMI/LVT2 == LINT1 - the following check
300 * will show us if this assumptions is false.
301 * Until then we do not have to add baggage.
302 */
303 if ((m->mpc_irqtype == mp_ExtINT) &&
304 (m->mpc_destapiclint != 0))
305 BUG();
306 if ((m->mpc_irqtype == mp_NMI) &&
307 (m->mpc_destapiclint != 1))
308 BUG();
309} 299}
310 300
311#ifdef CONFIG_X86_NUMAQ 301#ifdef CONFIG_X86_NUMAQ
@@ -822,8 +812,7 @@ int es7000_plat;
822 812
823#ifdef CONFIG_ACPI 813#ifdef CONFIG_ACPI
824 814
825void __init mp_register_lapic_address ( 815void __init mp_register_lapic_address(u64 address)
826 u64 address)
827{ 816{
828 mp_lapic_addr = (unsigned long) address; 817 mp_lapic_addr = (unsigned long) address;
829 818
@@ -835,13 +824,10 @@ void __init mp_register_lapic_address (
835 Dprintk("Boot CPU = %d\n", boot_cpu_physical_apicid); 824 Dprintk("Boot CPU = %d\n", boot_cpu_physical_apicid);
836} 825}
837 826
838 827void __devinit mp_register_lapic (u8 id, u8 enabled)
839void __devinit mp_register_lapic (
840 u8 id,
841 u8 enabled)
842{ 828{
843 struct mpc_config_processor processor; 829 struct mpc_config_processor processor;
844 int boot_cpu = 0; 830 int boot_cpu = 0;
845 831
846 if (MAX_APICS - id <= 0) { 832 if (MAX_APICS - id <= 0) {
847 printk(KERN_WARNING "Processor #%d invalid (max %d)\n", 833 printk(KERN_WARNING "Processor #%d invalid (max %d)\n",
@@ -878,11 +864,9 @@ static struct mp_ioapic_routing {
878 u32 pin_programmed[4]; 864 u32 pin_programmed[4];
879} mp_ioapic_routing[MAX_IO_APICS]; 865} mp_ioapic_routing[MAX_IO_APICS];
880 866
881 867static int mp_find_ioapic (int gsi)
882static int mp_find_ioapic (
883 int gsi)
884{ 868{
885 int i = 0; 869 int i = 0;
886 870
887 /* Find the IOAPIC that manages this GSI. */ 871 /* Find the IOAPIC that manages this GSI. */
888 for (i = 0; i < nr_ioapics; i++) { 872 for (i = 0; i < nr_ioapics; i++) {
@@ -895,15 +879,11 @@ static int mp_find_ioapic (
895 879
896 return -1; 880 return -1;
897} 881}
898
899 882
900void __init mp_register_ioapic ( 883void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base)
901 u8 id,
902 u32 address,
903 u32 gsi_base)
904{ 884{
905 int idx = 0; 885 int idx = 0;
906 int tmpid; 886 int tmpid;
907 887
908 if (nr_ioapics >= MAX_IO_APICS) { 888 if (nr_ioapics >= MAX_IO_APICS) {
909 printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " 889 printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded "
@@ -949,16 +929,10 @@ void __init mp_register_ioapic (
949 mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr, 929 mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr,
950 mp_ioapic_routing[idx].gsi_base, 930 mp_ioapic_routing[idx].gsi_base,
951 mp_ioapic_routing[idx].gsi_end); 931 mp_ioapic_routing[idx].gsi_end);
952
953 return;
954} 932}
955 933
956 934void __init
957void __init mp_override_legacy_irq ( 935mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
958 u8 bus_irq,
959 u8 polarity,
960 u8 trigger,
961 u32 gsi)
962{ 936{
963 struct mpc_config_intsrc intsrc; 937 struct mpc_config_intsrc intsrc;
964 int ioapic = -1; 938 int ioapic = -1;
@@ -996,15 +970,13 @@ void __init mp_override_legacy_irq (
996 mp_irqs[mp_irq_entries] = intsrc; 970 mp_irqs[mp_irq_entries] = intsrc;
997 if (++mp_irq_entries == MAX_IRQ_SOURCES) 971 if (++mp_irq_entries == MAX_IRQ_SOURCES)
998 panic("Max # of irq sources exceeded!\n"); 972 panic("Max # of irq sources exceeded!\n");
999
1000 return;
1001} 973}
1002 974
1003void __init mp_config_acpi_legacy_irqs (void) 975void __init mp_config_acpi_legacy_irqs (void)
1004{ 976{
1005 struct mpc_config_intsrc intsrc; 977 struct mpc_config_intsrc intsrc;
1006 int i = 0; 978 int i = 0;
1007 int ioapic = -1; 979 int ioapic = -1;
1008 980
1009 /* 981 /*
1010 * Fabricate the legacy ISA bus (bus #31). 982 * Fabricate the legacy ISA bus (bus #31).
@@ -1073,12 +1045,12 @@ void __init mp_config_acpi_legacy_irqs (void)
1073 1045
1074#define MAX_GSI_NUM 4096 1046#define MAX_GSI_NUM 4096
1075 1047
1076int mp_register_gsi (u32 gsi, int triggering, int polarity) 1048int mp_register_gsi(u32 gsi, int triggering, int polarity)
1077{ 1049{
1078 int ioapic = -1; 1050 int ioapic = -1;
1079 int ioapic_pin = 0; 1051 int ioapic_pin = 0;
1080 int idx, bit = 0; 1052 int idx, bit = 0;
1081 static int pci_irq = 16; 1053 static int pci_irq = 16;
1082 /* 1054 /*
1083 * Mapping between Global System Interrups, which 1055 * Mapping between Global System Interrups, which
1084 * represent all possible interrupts, and IRQs 1056 * represent all possible interrupts, and IRQs
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
index acb351478e42..dbda706fdd14 100644
--- a/arch/i386/kernel/nmi.c
+++ b/arch/i386/kernel/nmi.c
@@ -21,83 +21,174 @@
21#include <linux/sysdev.h> 21#include <linux/sysdev.h>
22#include <linux/sysctl.h> 22#include <linux/sysctl.h>
23#include <linux/percpu.h> 23#include <linux/percpu.h>
24#include <linux/dmi.h>
25#include <linux/kprobes.h>
24 26
25#include <asm/smp.h> 27#include <asm/smp.h>
26#include <asm/nmi.h> 28#include <asm/nmi.h>
29#include <asm/kdebug.h>
27#include <asm/intel_arch_perfmon.h> 30#include <asm/intel_arch_perfmon.h>
28 31
29#include "mach_traps.h" 32#include "mach_traps.h"
30 33
31unsigned int nmi_watchdog = NMI_NONE; 34/* perfctr_nmi_owner tracks the ownership of the perfctr registers:
32extern int unknown_nmi_panic; 35 * evtsel_nmi_owner tracks the ownership of the event selection
33static unsigned int nmi_hz = HZ; 36 * - different performance counters/ event selection may be reserved for
34static unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */ 37 * different subsystems this reservation system just tries to coordinate
35static unsigned int nmi_p4_cccr_val; 38 * things a little
36extern void show_registers(struct pt_regs *regs); 39 */
40static DEFINE_PER_CPU(unsigned long, perfctr_nmi_owner);
41static DEFINE_PER_CPU(unsigned long, evntsel_nmi_owner[3]);
37 42
38/* 43/* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's
39 * lapic_nmi_owner tracks the ownership of the lapic NMI hardware: 44 * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now)
40 * - it may be reserved by some other driver, or not
41 * - when not reserved by some other driver, it may be used for
42 * the NMI watchdog, or not
43 *
44 * This is maintained separately from nmi_active because the NMI
45 * watchdog may also be driven from the I/O APIC timer.
46 */ 45 */
47static DEFINE_SPINLOCK(lapic_nmi_owner_lock); 46#define NMI_MAX_COUNTER_BITS 66
48static unsigned int lapic_nmi_owner;
49#define LAPIC_NMI_WATCHDOG (1<<0)
50#define LAPIC_NMI_RESERVED (1<<1)
51 47
52/* nmi_active: 48/* nmi_active:
53 * +1: the lapic NMI watchdog is active, but can be disabled 49 * >0: the lapic NMI watchdog is active, but can be disabled
54 * 0: the lapic NMI watchdog has not been set up, and cannot 50 * <0: the lapic NMI watchdog has not been set up, and cannot
55 * be enabled 51 * be enabled
56 * -1: the lapic NMI watchdog is disabled, but can be enabled 52 * 0: the lapic NMI watchdog is disabled, but can be enabled
57 */ 53 */
58int nmi_active; 54atomic_t nmi_active = ATOMIC_INIT(0); /* oprofile uses this */
59 55
60#define K7_EVNTSEL_ENABLE (1 << 22) 56unsigned int nmi_watchdog = NMI_DEFAULT;
61#define K7_EVNTSEL_INT (1 << 20) 57static unsigned int nmi_hz = HZ;
62#define K7_EVNTSEL_OS (1 << 17)
63#define K7_EVNTSEL_USR (1 << 16)
64#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76
65#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING
66 58
67#define P6_EVNTSEL0_ENABLE (1 << 22) 59struct nmi_watchdog_ctlblk {
68#define P6_EVNTSEL_INT (1 << 20) 60 int enabled;
69#define P6_EVNTSEL_OS (1 << 17) 61 u64 check_bit;
70#define P6_EVNTSEL_USR (1 << 16) 62 unsigned int cccr_msr;
71#define P6_EVENT_CPU_CLOCKS_NOT_HALTED 0x79 63 unsigned int perfctr_msr; /* the MSR to reset in NMI handler */
72#define P6_NMI_EVENT P6_EVENT_CPU_CLOCKS_NOT_HALTED 64 unsigned int evntsel_msr; /* the MSR to select the events to handle */
65};
66static DEFINE_PER_CPU(struct nmi_watchdog_ctlblk, nmi_watchdog_ctlblk);
73 67
74#define MSR_P4_MISC_ENABLE 0x1A0 68/* local prototypes */
75#define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7) 69static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu);
76#define MSR_P4_MISC_ENABLE_PEBS_UNAVAIL (1<<12)
77#define MSR_P4_PERFCTR0 0x300
78#define MSR_P4_CCCR0 0x360
79#define P4_ESCR_EVENT_SELECT(N) ((N)<<25)
80#define P4_ESCR_OS (1<<3)
81#define P4_ESCR_USR (1<<2)
82#define P4_CCCR_OVF_PMI0 (1<<26)
83#define P4_CCCR_OVF_PMI1 (1<<27)
84#define P4_CCCR_THRESHOLD(N) ((N)<<20)
85#define P4_CCCR_COMPLEMENT (1<<19)
86#define P4_CCCR_COMPARE (1<<18)
87#define P4_CCCR_REQUIRED (3<<16)
88#define P4_CCCR_ESCR_SELECT(N) ((N)<<13)
89#define P4_CCCR_ENABLE (1<<12)
90/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter
91 CRU_ESCR0 (with any non-null event selector) through a complemented
92 max threshold. [IA32-Vol3, Section 14.9.9] */
93#define MSR_P4_IQ_COUNTER0 0x30C
94#define P4_NMI_CRU_ESCR0 (P4_ESCR_EVENT_SELECT(0x3F)|P4_ESCR_OS|P4_ESCR_USR)
95#define P4_NMI_IQ_CCCR0 \
96 (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \
97 P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE)
98 70
99#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL 71extern void show_registers(struct pt_regs *regs);
100#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK 72extern int unknown_nmi_panic;
73
74/* converts an msr to an appropriate reservation bit */
75static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr)
76{
77 /* returns the bit offset of the performance counter register */
78 switch (boot_cpu_data.x86_vendor) {
79 case X86_VENDOR_AMD:
80 return (msr - MSR_K7_PERFCTR0);
81 case X86_VENDOR_INTEL:
82 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON))
83 return (msr - MSR_ARCH_PERFMON_PERFCTR0);
84
85 switch (boot_cpu_data.x86) {
86 case 6:
87 return (msr - MSR_P6_PERFCTR0);
88 case 15:
89 return (msr - MSR_P4_BPU_PERFCTR0);
90 }
91 }
92 return 0;
93}
94
95/* converts an msr to an appropriate reservation bit */
96static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr)
97{
98 /* returns the bit offset of the event selection register */
99 switch (boot_cpu_data.x86_vendor) {
100 case X86_VENDOR_AMD:
101 return (msr - MSR_K7_EVNTSEL0);
102 case X86_VENDOR_INTEL:
103 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON))
104 return (msr - MSR_ARCH_PERFMON_EVENTSEL0);
105
106 switch (boot_cpu_data.x86) {
107 case 6:
108 return (msr - MSR_P6_EVNTSEL0);
109 case 15:
110 return (msr - MSR_P4_BSU_ESCR0);
111 }
112 }
113 return 0;
114}
115
116/* checks for a bit availability (hack for oprofile) */
117int avail_to_resrv_perfctr_nmi_bit(unsigned int counter)
118{
119 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
120
121 return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner)));
122}
123
124/* checks the an msr for availability */
125int avail_to_resrv_perfctr_nmi(unsigned int msr)
126{
127 unsigned int counter;
128
129 counter = nmi_perfctr_msr_to_bit(msr);
130 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
131
132 return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner)));
133}
134
135int reserve_perfctr_nmi(unsigned int msr)
136{
137 unsigned int counter;
138
139 counter = nmi_perfctr_msr_to_bit(msr);
140 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
141
142 if (!test_and_set_bit(counter, &__get_cpu_var(perfctr_nmi_owner)))
143 return 1;
144 return 0;
145}
146
147void release_perfctr_nmi(unsigned int msr)
148{
149 unsigned int counter;
150
151 counter = nmi_perfctr_msr_to_bit(msr);
152 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
153
154 clear_bit(counter, &__get_cpu_var(perfctr_nmi_owner));
155}
156
157int reserve_evntsel_nmi(unsigned int msr)
158{
159 unsigned int counter;
160
161 counter = nmi_evntsel_msr_to_bit(msr);
162 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
163
164 if (!test_and_set_bit(counter, &__get_cpu_var(evntsel_nmi_owner)[0]))
165 return 1;
166 return 0;
167}
168
169void release_evntsel_nmi(unsigned int msr)
170{
171 unsigned int counter;
172
173 counter = nmi_evntsel_msr_to_bit(msr);
174 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
175
176 clear_bit(counter, &__get_cpu_var(evntsel_nmi_owner)[0]);
177}
178
179static __cpuinit inline int nmi_known_cpu(void)
180{
181 switch (boot_cpu_data.x86_vendor) {
182 case X86_VENDOR_AMD:
183 return ((boot_cpu_data.x86 == 15) || (boot_cpu_data.x86 == 6));
184 case X86_VENDOR_INTEL:
185 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON))
186 return 1;
187 else
188 return ((boot_cpu_data.x86 == 15) || (boot_cpu_data.x86 == 6));
189 }
190 return 0;
191}
101 192
102#ifdef CONFIG_SMP 193#ifdef CONFIG_SMP
103/* The performance counters used by NMI_LOCAL_APIC don't trigger when 194/* The performance counters used by NMI_LOCAL_APIC don't trigger when
@@ -125,7 +216,18 @@ static int __init check_nmi_watchdog(void)
125 unsigned int *prev_nmi_count; 216 unsigned int *prev_nmi_count;
126 int cpu; 217 int cpu;
127 218
128 if (nmi_watchdog == NMI_NONE) 219 /* Enable NMI watchdog for newer systems.
220 Actually it should be safe for most systems before 2004 too except
221 for some IBM systems that corrupt registers when NMI happens
222 during SMM. Unfortunately we don't have more exact information
223 on these and use this coarse check. */
224 if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004)
225 nmi_watchdog = NMI_LOCAL_APIC;
226
227 if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT))
228 return 0;
229
230 if (!atomic_read(&nmi_active))
129 return 0; 231 return 0;
130 232
131 prev_nmi_count = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL); 233 prev_nmi_count = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL);
@@ -149,25 +251,45 @@ static int __init check_nmi_watchdog(void)
149 if (!cpu_isset(cpu, cpu_callin_map)) 251 if (!cpu_isset(cpu, cpu_callin_map))
150 continue; 252 continue;
151#endif 253#endif
254 if (!per_cpu(nmi_watchdog_ctlblk, cpu).enabled)
255 continue;
152 if (nmi_count(cpu) - prev_nmi_count[cpu] <= 5) { 256 if (nmi_count(cpu) - prev_nmi_count[cpu] <= 5) {
153 endflag = 1;
154 printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n", 257 printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n",
155 cpu, 258 cpu,
156 prev_nmi_count[cpu], 259 prev_nmi_count[cpu],
157 nmi_count(cpu)); 260 nmi_count(cpu));
158 nmi_active = 0; 261 per_cpu(nmi_watchdog_ctlblk, cpu).enabled = 0;
159 lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG; 262 atomic_dec(&nmi_active);
160 kfree(prev_nmi_count);
161 return -1;
162 } 263 }
163 } 264 }
265 if (!atomic_read(&nmi_active)) {
266 kfree(prev_nmi_count);
267 atomic_set(&nmi_active, -1);
268 return -1;
269 }
164 endflag = 1; 270 endflag = 1;
165 printk("OK.\n"); 271 printk("OK.\n");
166 272
167 /* now that we know it works we can reduce NMI frequency to 273 /* now that we know it works we can reduce NMI frequency to
168 something more reasonable; makes a difference in some configs */ 274 something more reasonable; makes a difference in some configs */
169 if (nmi_watchdog == NMI_LOCAL_APIC) 275 if (nmi_watchdog == NMI_LOCAL_APIC) {
276 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
277
170 nmi_hz = 1; 278 nmi_hz = 1;
279 /*
280 * On Intel CPUs with ARCH_PERFMON only 32 bits in the counter
281 * are writable, with higher bits sign extending from bit 31.
282 * So, we can only program the counter with 31 bit values and
283 * 32nd bit should be 1, for 33.. to be 1.
284 * Find the appropriate nmi_hz
285 */
286 if (wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0 &&
287 ((u64)cpu_khz * 1000) > 0x7fffffffULL) {
288 u64 count = (u64)cpu_khz * 1000;
289 do_div(count, 0x7fffffffUL);
290 nmi_hz = count + 1;
291 }
292 }
171 293
172 kfree(prev_nmi_count); 294 kfree(prev_nmi_count);
173 return 0; 295 return 0;
@@ -181,124 +303,70 @@ static int __init setup_nmi_watchdog(char *str)
181 303
182 get_option(&str, &nmi); 304 get_option(&str, &nmi);
183 305
184 if (nmi >= NMI_INVALID) 306 if ((nmi >= NMI_INVALID) || (nmi < NMI_NONE))
185 return 0; 307 return 0;
186 if (nmi == NMI_NONE)
187 nmi_watchdog = nmi;
188 /* 308 /*
189 * If any other x86 CPU has a local APIC, then 309 * If any other x86 CPU has a local APIC, then
190 * please test the NMI stuff there and send me the 310 * please test the NMI stuff there and send me the
191 * missing bits. Right now Intel P6/P4 and AMD K7 only. 311 * missing bits. Right now Intel P6/P4 and AMD K7 only.
192 */ 312 */
193 if ((nmi == NMI_LOCAL_APIC) && 313 if ((nmi == NMI_LOCAL_APIC) && (nmi_known_cpu() == 0))
194 (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && 314 return 0; /* no lapic support */
195 (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15)) 315 nmi_watchdog = nmi;
196 nmi_watchdog = nmi;
197 if ((nmi == NMI_LOCAL_APIC) &&
198 (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
199 (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15))
200 nmi_watchdog = nmi;
201 /*
202 * We can enable the IO-APIC watchdog
203 * unconditionally.
204 */
205 if (nmi == NMI_IO_APIC) {
206 nmi_active = 1;
207 nmi_watchdog = nmi;
208 }
209 return 1; 316 return 1;
210} 317}
211 318
212__setup("nmi_watchdog=", setup_nmi_watchdog); 319__setup("nmi_watchdog=", setup_nmi_watchdog);
213 320
214static void disable_intel_arch_watchdog(void);
215
216static void disable_lapic_nmi_watchdog(void) 321static void disable_lapic_nmi_watchdog(void)
217{ 322{
218 if (nmi_active <= 0) 323 BUG_ON(nmi_watchdog != NMI_LOCAL_APIC);
324
325 if (atomic_read(&nmi_active) <= 0)
219 return; 326 return;
220 switch (boot_cpu_data.x86_vendor) {
221 case X86_VENDOR_AMD:
222 wrmsr(MSR_K7_EVNTSEL0, 0, 0);
223 break;
224 case X86_VENDOR_INTEL:
225 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
226 disable_intel_arch_watchdog();
227 break;
228 }
229 switch (boot_cpu_data.x86) {
230 case 6:
231 if (boot_cpu_data.x86_model > 0xd)
232 break;
233 327
234 wrmsr(MSR_P6_EVNTSEL0, 0, 0); 328 on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1);
235 break;
236 case 15:
237 if (boot_cpu_data.x86_model > 0x4)
238 break;
239 329
240 wrmsr(MSR_P4_IQ_CCCR0, 0, 0); 330 BUG_ON(atomic_read(&nmi_active) != 0);
241 wrmsr(MSR_P4_CRU_ESCR0, 0, 0);
242 break;
243 }
244 break;
245 }
246 nmi_active = -1;
247 /* tell do_nmi() and others that we're not active any more */
248 nmi_watchdog = 0;
249} 331}
250 332
251static void enable_lapic_nmi_watchdog(void) 333static void enable_lapic_nmi_watchdog(void)
252{ 334{
253 if (nmi_active < 0) { 335 BUG_ON(nmi_watchdog != NMI_LOCAL_APIC);
254 nmi_watchdog = NMI_LOCAL_APIC;
255 setup_apic_nmi_watchdog();
256 }
257}
258 336
259int reserve_lapic_nmi(void) 337 /* are we already enabled */
260{ 338 if (atomic_read(&nmi_active) != 0)
261 unsigned int old_owner; 339 return;
262
263 spin_lock(&lapic_nmi_owner_lock);
264 old_owner = lapic_nmi_owner;
265 lapic_nmi_owner |= LAPIC_NMI_RESERVED;
266 spin_unlock(&lapic_nmi_owner_lock);
267 if (old_owner & LAPIC_NMI_RESERVED)
268 return -EBUSY;
269 if (old_owner & LAPIC_NMI_WATCHDOG)
270 disable_lapic_nmi_watchdog();
271 return 0;
272}
273 340
274void release_lapic_nmi(void) 341 /* are we lapic aware */
275{ 342 if (nmi_known_cpu() <= 0)
276 unsigned int new_owner; 343 return;
277 344
278 spin_lock(&lapic_nmi_owner_lock); 345 on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1);
279 new_owner = lapic_nmi_owner & ~LAPIC_NMI_RESERVED; 346 touch_nmi_watchdog();
280 lapic_nmi_owner = new_owner;
281 spin_unlock(&lapic_nmi_owner_lock);
282 if (new_owner & LAPIC_NMI_WATCHDOG)
283 enable_lapic_nmi_watchdog();
284} 347}
285 348
286void disable_timer_nmi_watchdog(void) 349void disable_timer_nmi_watchdog(void)
287{ 350{
288 if ((nmi_watchdog != NMI_IO_APIC) || (nmi_active <= 0)) 351 BUG_ON(nmi_watchdog != NMI_IO_APIC);
352
353 if (atomic_read(&nmi_active) <= 0)
289 return; 354 return;
290 355
291 unset_nmi_callback(); 356 disable_irq(0);
292 nmi_active = -1; 357 on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1);
293 nmi_watchdog = NMI_NONE; 358
359 BUG_ON(atomic_read(&nmi_active) != 0);
294} 360}
295 361
296void enable_timer_nmi_watchdog(void) 362void enable_timer_nmi_watchdog(void)
297{ 363{
298 if (nmi_active < 0) { 364 BUG_ON(nmi_watchdog != NMI_IO_APIC);
299 nmi_watchdog = NMI_IO_APIC; 365
366 if (atomic_read(&nmi_active) == 0) {
300 touch_nmi_watchdog(); 367 touch_nmi_watchdog();
301 nmi_active = 1; 368 on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1);
369 enable_irq(0);
302 } 370 }
303} 371}
304 372
@@ -308,15 +376,20 @@ static int nmi_pm_active; /* nmi_active before suspend */
308 376
309static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state) 377static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state)
310{ 378{
311 nmi_pm_active = nmi_active; 379 /* only CPU0 goes here, other CPUs should be offline */
312 disable_lapic_nmi_watchdog(); 380 nmi_pm_active = atomic_read(&nmi_active);
381 stop_apic_nmi_watchdog(NULL);
382 BUG_ON(atomic_read(&nmi_active) != 0);
313 return 0; 383 return 0;
314} 384}
315 385
316static int lapic_nmi_resume(struct sys_device *dev) 386static int lapic_nmi_resume(struct sys_device *dev)
317{ 387{
318 if (nmi_pm_active > 0) 388 /* only CPU0 goes here, other CPUs should be offline */
319 enable_lapic_nmi_watchdog(); 389 if (nmi_pm_active > 0) {
390 setup_apic_nmi_watchdog(NULL);
391 touch_nmi_watchdog();
392 }
320 return 0; 393 return 0;
321} 394}
322 395
@@ -336,7 +409,13 @@ static int __init init_lapic_nmi_sysfs(void)
336{ 409{
337 int error; 410 int error;
338 411
339 if (nmi_active == 0 || nmi_watchdog != NMI_LOCAL_APIC) 412 /* should really be a BUG_ON but b/c this is an
413 * init call, it just doesn't work. -dcz
414 */
415 if (nmi_watchdog != NMI_LOCAL_APIC)
416 return 0;
417
418 if ( atomic_read(&nmi_active) < 0 )
340 return 0; 419 return 0;
341 420
342 error = sysdev_class_register(&nmi_sysclass); 421 error = sysdev_class_register(&nmi_sysclass);
@@ -354,138 +433,269 @@ late_initcall(init_lapic_nmi_sysfs);
354 * Original code written by Keith Owens. 433 * Original code written by Keith Owens.
355 */ 434 */
356 435
357static void clear_msr_range(unsigned int base, unsigned int n) 436static void write_watchdog_counter(unsigned int perfctr_msr, const char *descr)
358{
359 unsigned int i;
360
361 for(i = 0; i < n; ++i)
362 wrmsr(base+i, 0, 0);
363}
364
365static void write_watchdog_counter(const char *descr)
366{ 437{
367 u64 count = (u64)cpu_khz * 1000; 438 u64 count = (u64)cpu_khz * 1000;
368 439
369 do_div(count, nmi_hz); 440 do_div(count, nmi_hz);
370 if(descr) 441 if(descr)
371 Dprintk("setting %s to -0x%08Lx\n", descr, count); 442 Dprintk("setting %s to -0x%08Lx\n", descr, count);
372 wrmsrl(nmi_perfctr_msr, 0 - count); 443 wrmsrl(perfctr_msr, 0 - count);
373} 444}
374 445
375static void setup_k7_watchdog(void) 446/* Note that these events don't tick when the CPU idles. This means
447 the frequency varies with CPU load. */
448
449#define K7_EVNTSEL_ENABLE (1 << 22)
450#define K7_EVNTSEL_INT (1 << 20)
451#define K7_EVNTSEL_OS (1 << 17)
452#define K7_EVNTSEL_USR (1 << 16)
453#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76
454#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING
455
456static int setup_k7_watchdog(void)
376{ 457{
458 unsigned int perfctr_msr, evntsel_msr;
377 unsigned int evntsel; 459 unsigned int evntsel;
460 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
461
462 perfctr_msr = MSR_K7_PERFCTR0;
463 evntsel_msr = MSR_K7_EVNTSEL0;
464 if (!reserve_perfctr_nmi(perfctr_msr))
465 goto fail;
378 466
379 nmi_perfctr_msr = MSR_K7_PERFCTR0; 467 if (!reserve_evntsel_nmi(evntsel_msr))
468 goto fail1;
380 469
381 clear_msr_range(MSR_K7_EVNTSEL0, 4); 470 wrmsrl(perfctr_msr, 0UL);
382 clear_msr_range(MSR_K7_PERFCTR0, 4);
383 471
384 evntsel = K7_EVNTSEL_INT 472 evntsel = K7_EVNTSEL_INT
385 | K7_EVNTSEL_OS 473 | K7_EVNTSEL_OS
386 | K7_EVNTSEL_USR 474 | K7_EVNTSEL_USR
387 | K7_NMI_EVENT; 475 | K7_NMI_EVENT;
388 476
389 wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); 477 /* setup the timer */
390 write_watchdog_counter("K7_PERFCTR0"); 478 wrmsr(evntsel_msr, evntsel, 0);
479 write_watchdog_counter(perfctr_msr, "K7_PERFCTR0");
391 apic_write(APIC_LVTPC, APIC_DM_NMI); 480 apic_write(APIC_LVTPC, APIC_DM_NMI);
392 evntsel |= K7_EVNTSEL_ENABLE; 481 evntsel |= K7_EVNTSEL_ENABLE;
393 wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); 482 wrmsr(evntsel_msr, evntsel, 0);
483
484 wd->perfctr_msr = perfctr_msr;
485 wd->evntsel_msr = evntsel_msr;
486 wd->cccr_msr = 0; //unused
487 wd->check_bit = 1ULL<<63;
488 return 1;
489fail1:
490 release_perfctr_nmi(perfctr_msr);
491fail:
492 return 0;
493}
494
495static void stop_k7_watchdog(void)
496{
497 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
498
499 wrmsr(wd->evntsel_msr, 0, 0);
500
501 release_evntsel_nmi(wd->evntsel_msr);
502 release_perfctr_nmi(wd->perfctr_msr);
394} 503}
395 504
396static void setup_p6_watchdog(void) 505#define P6_EVNTSEL0_ENABLE (1 << 22)
506#define P6_EVNTSEL_INT (1 << 20)
507#define P6_EVNTSEL_OS (1 << 17)
508#define P6_EVNTSEL_USR (1 << 16)
509#define P6_EVENT_CPU_CLOCKS_NOT_HALTED 0x79
510#define P6_NMI_EVENT P6_EVENT_CPU_CLOCKS_NOT_HALTED
511
512static int setup_p6_watchdog(void)
397{ 513{
514 unsigned int perfctr_msr, evntsel_msr;
398 unsigned int evntsel; 515 unsigned int evntsel;
516 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
517
518 perfctr_msr = MSR_P6_PERFCTR0;
519 evntsel_msr = MSR_P6_EVNTSEL0;
520 if (!reserve_perfctr_nmi(perfctr_msr))
521 goto fail;
399 522
400 nmi_perfctr_msr = MSR_P6_PERFCTR0; 523 if (!reserve_evntsel_nmi(evntsel_msr))
524 goto fail1;
401 525
402 clear_msr_range(MSR_P6_EVNTSEL0, 2); 526 wrmsrl(perfctr_msr, 0UL);
403 clear_msr_range(MSR_P6_PERFCTR0, 2);
404 527
405 evntsel = P6_EVNTSEL_INT 528 evntsel = P6_EVNTSEL_INT
406 | P6_EVNTSEL_OS 529 | P6_EVNTSEL_OS
407 | P6_EVNTSEL_USR 530 | P6_EVNTSEL_USR
408 | P6_NMI_EVENT; 531 | P6_NMI_EVENT;
409 532
410 wrmsr(MSR_P6_EVNTSEL0, evntsel, 0); 533 /* setup the timer */
411 write_watchdog_counter("P6_PERFCTR0"); 534 wrmsr(evntsel_msr, evntsel, 0);
535 write_watchdog_counter(perfctr_msr, "P6_PERFCTR0");
412 apic_write(APIC_LVTPC, APIC_DM_NMI); 536 apic_write(APIC_LVTPC, APIC_DM_NMI);
413 evntsel |= P6_EVNTSEL0_ENABLE; 537 evntsel |= P6_EVNTSEL0_ENABLE;
414 wrmsr(MSR_P6_EVNTSEL0, evntsel, 0); 538 wrmsr(evntsel_msr, evntsel, 0);
539
540 wd->perfctr_msr = perfctr_msr;
541 wd->evntsel_msr = evntsel_msr;
542 wd->cccr_msr = 0; //unused
543 wd->check_bit = 1ULL<<39;
544 return 1;
545fail1:
546 release_perfctr_nmi(perfctr_msr);
547fail:
548 return 0;
549}
550
551static void stop_p6_watchdog(void)
552{
553 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
554
555 wrmsr(wd->evntsel_msr, 0, 0);
556
557 release_evntsel_nmi(wd->evntsel_msr);
558 release_perfctr_nmi(wd->perfctr_msr);
415} 559}
416 560
561/* Note that these events don't tick when the CPU idles. This means
562 the frequency varies with CPU load. */
563
564#define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7)
565#define P4_ESCR_EVENT_SELECT(N) ((N)<<25)
566#define P4_ESCR_OS (1<<3)
567#define P4_ESCR_USR (1<<2)
568#define P4_CCCR_OVF_PMI0 (1<<26)
569#define P4_CCCR_OVF_PMI1 (1<<27)
570#define P4_CCCR_THRESHOLD(N) ((N)<<20)
571#define P4_CCCR_COMPLEMENT (1<<19)
572#define P4_CCCR_COMPARE (1<<18)
573#define P4_CCCR_REQUIRED (3<<16)
574#define P4_CCCR_ESCR_SELECT(N) ((N)<<13)
575#define P4_CCCR_ENABLE (1<<12)
576#define P4_CCCR_OVF (1<<31)
577/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter
578 CRU_ESCR0 (with any non-null event selector) through a complemented
579 max threshold. [IA32-Vol3, Section 14.9.9] */
580
417static int setup_p4_watchdog(void) 581static int setup_p4_watchdog(void)
418{ 582{
583 unsigned int perfctr_msr, evntsel_msr, cccr_msr;
584 unsigned int evntsel, cccr_val;
419 unsigned int misc_enable, dummy; 585 unsigned int misc_enable, dummy;
586 unsigned int ht_num;
587 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
420 588
421 rdmsr(MSR_P4_MISC_ENABLE, misc_enable, dummy); 589 rdmsr(MSR_IA32_MISC_ENABLE, misc_enable, dummy);
422 if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL)) 590 if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL))
423 return 0; 591 return 0;
424 592
425 nmi_perfctr_msr = MSR_P4_IQ_COUNTER0;
426 nmi_p4_cccr_val = P4_NMI_IQ_CCCR0;
427#ifdef CONFIG_SMP 593#ifdef CONFIG_SMP
428 if (smp_num_siblings == 2) 594 /* detect which hyperthread we are on */
429 nmi_p4_cccr_val |= P4_CCCR_OVF_PMI1; 595 if (smp_num_siblings == 2) {
596 unsigned int ebx, apicid;
597
598 ebx = cpuid_ebx(1);
599 apicid = (ebx >> 24) & 0xff;
600 ht_num = apicid & 1;
601 } else
430#endif 602#endif
603 ht_num = 0;
431 604
432 if (!(misc_enable & MSR_P4_MISC_ENABLE_PEBS_UNAVAIL)) 605 /* performance counters are shared resources
433 clear_msr_range(0x3F1, 2); 606 * assign each hyperthread its own set
434 /* MSR 0x3F0 seems to have a default value of 0xFC00, but current 607 * (re-use the ESCR0 register, seems safe
435 docs doesn't fully define it, so leave it alone for now. */ 608 * and keeps the cccr_val the same)
436 if (boot_cpu_data.x86_model >= 0x3) { 609 */
437 /* MSR_P4_IQ_ESCR0/1 (0x3ba/0x3bb) removed */ 610 if (!ht_num) {
438 clear_msr_range(0x3A0, 26); 611 /* logical cpu 0 */
439 clear_msr_range(0x3BC, 3); 612 perfctr_msr = MSR_P4_IQ_PERFCTR0;
613 evntsel_msr = MSR_P4_CRU_ESCR0;
614 cccr_msr = MSR_P4_IQ_CCCR0;
615 cccr_val = P4_CCCR_OVF_PMI0 | P4_CCCR_ESCR_SELECT(4);
440 } else { 616 } else {
441 clear_msr_range(0x3A0, 31); 617 /* logical cpu 1 */
618 perfctr_msr = MSR_P4_IQ_PERFCTR1;
619 evntsel_msr = MSR_P4_CRU_ESCR0;
620 cccr_msr = MSR_P4_IQ_CCCR1;
621 cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4);
442 } 622 }
443 clear_msr_range(0x3C0, 6); 623
444 clear_msr_range(0x3C8, 6); 624 if (!reserve_perfctr_nmi(perfctr_msr))
445 clear_msr_range(0x3E0, 2); 625 goto fail;
446 clear_msr_range(MSR_P4_CCCR0, 18); 626
447 clear_msr_range(MSR_P4_PERFCTR0, 18); 627 if (!reserve_evntsel_nmi(evntsel_msr))
448 628 goto fail1;
449 wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0); 629
450 wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 0); 630 evntsel = P4_ESCR_EVENT_SELECT(0x3F)
451 write_watchdog_counter("P4_IQ_COUNTER0"); 631 | P4_ESCR_OS
632 | P4_ESCR_USR;
633
634 cccr_val |= P4_CCCR_THRESHOLD(15)
635 | P4_CCCR_COMPLEMENT
636 | P4_CCCR_COMPARE
637 | P4_CCCR_REQUIRED;
638
639 wrmsr(evntsel_msr, evntsel, 0);
640 wrmsr(cccr_msr, cccr_val, 0);
641 write_watchdog_counter(perfctr_msr, "P4_IQ_COUNTER0");
452 apic_write(APIC_LVTPC, APIC_DM_NMI); 642 apic_write(APIC_LVTPC, APIC_DM_NMI);
453 wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); 643 cccr_val |= P4_CCCR_ENABLE;
644 wrmsr(cccr_msr, cccr_val, 0);
645 wd->perfctr_msr = perfctr_msr;
646 wd->evntsel_msr = evntsel_msr;
647 wd->cccr_msr = cccr_msr;
648 wd->check_bit = 1ULL<<39;
454 return 1; 649 return 1;
650fail1:
651 release_perfctr_nmi(perfctr_msr);
652fail:
653 return 0;
455} 654}
456 655
457static void disable_intel_arch_watchdog(void) 656static void stop_p4_watchdog(void)
458{ 657{
459 unsigned ebx; 658 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
460 659
461 /* 660 wrmsr(wd->cccr_msr, 0, 0);
462 * Check whether the Architectural PerfMon supports 661 wrmsr(wd->evntsel_msr, 0, 0);
463 * Unhalted Core Cycles Event or not. 662
464 * NOTE: Corresponding bit = 0 in ebp indicates event present. 663 release_evntsel_nmi(wd->evntsel_msr);
465 */ 664 release_perfctr_nmi(wd->perfctr_msr);
466 ebx = cpuid_ebx(10);
467 if (!(ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT))
468 wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, 0, 0);
469} 665}
470 666
667#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL
668#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK
669
471static int setup_intel_arch_watchdog(void) 670static int setup_intel_arch_watchdog(void)
472{ 671{
672 unsigned int ebx;
673 union cpuid10_eax eax;
674 unsigned int unused;
675 unsigned int perfctr_msr, evntsel_msr;
473 unsigned int evntsel; 676 unsigned int evntsel;
474 unsigned ebx; 677 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
475 678
476 /* 679 /*
477 * Check whether the Architectural PerfMon supports 680 * Check whether the Architectural PerfMon supports
478 * Unhalted Core Cycles Event or not. 681 * Unhalted Core Cycles Event or not.
479 * NOTE: Corresponding bit = 0 in ebp indicates event present. 682 * NOTE: Corresponding bit = 0 in ebx indicates event present.
480 */ 683 */
481 ebx = cpuid_ebx(10); 684 cpuid(10, &(eax.full), &ebx, &unused, &unused);
482 if ((ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) 685 if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) ||
483 return 0; 686 (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT))
687 goto fail;
688
689 perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0;
690 evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL0;
484 691
485 nmi_perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; 692 if (!reserve_perfctr_nmi(perfctr_msr))
693 goto fail;
486 694
487 clear_msr_range(MSR_ARCH_PERFMON_EVENTSEL0, 2); 695 if (!reserve_evntsel_nmi(evntsel_msr))
488 clear_msr_range(MSR_ARCH_PERFMON_PERFCTR0, 2); 696 goto fail1;
697
698 wrmsrl(perfctr_msr, 0UL);
489 699
490 evntsel = ARCH_PERFMON_EVENTSEL_INT 700 evntsel = ARCH_PERFMON_EVENTSEL_INT
491 | ARCH_PERFMON_EVENTSEL_OS 701 | ARCH_PERFMON_EVENTSEL_OS
@@ -493,51 +703,145 @@ static int setup_intel_arch_watchdog(void)
493 | ARCH_PERFMON_NMI_EVENT_SEL 703 | ARCH_PERFMON_NMI_EVENT_SEL
494 | ARCH_PERFMON_NMI_EVENT_UMASK; 704 | ARCH_PERFMON_NMI_EVENT_UMASK;
495 705
496 wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0); 706 /* setup the timer */
497 write_watchdog_counter("INTEL_ARCH_PERFCTR0"); 707 wrmsr(evntsel_msr, evntsel, 0);
708 write_watchdog_counter(perfctr_msr, "INTEL_ARCH_PERFCTR0");
498 apic_write(APIC_LVTPC, APIC_DM_NMI); 709 apic_write(APIC_LVTPC, APIC_DM_NMI);
499 evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE; 710 evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE;
500 wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0); 711 wrmsr(evntsel_msr, evntsel, 0);
712
713 wd->perfctr_msr = perfctr_msr;
714 wd->evntsel_msr = evntsel_msr;
715 wd->cccr_msr = 0; //unused
716 wd->check_bit = 1ULL << (eax.split.bit_width - 1);
501 return 1; 717 return 1;
718fail1:
719 release_perfctr_nmi(perfctr_msr);
720fail:
721 return 0;
502} 722}
503 723
504void setup_apic_nmi_watchdog (void) 724static void stop_intel_arch_watchdog(void)
505{ 725{
506 switch (boot_cpu_data.x86_vendor) { 726 unsigned int ebx;
507 case X86_VENDOR_AMD: 727 union cpuid10_eax eax;
508 if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15) 728 unsigned int unused;
509 return; 729 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
510 setup_k7_watchdog(); 730
511 break; 731 /*
512 case X86_VENDOR_INTEL: 732 * Check whether the Architectural PerfMon supports
513 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { 733 * Unhalted Core Cycles Event or not.
514 if (!setup_intel_arch_watchdog()) 734 * NOTE: Corresponding bit = 0 in ebx indicates event present.
735 */
736 cpuid(10, &(eax.full), &ebx, &unused, &unused);
737 if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) ||
738 (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT))
739 return;
740
741 wrmsr(wd->evntsel_msr, 0, 0);
742 release_evntsel_nmi(wd->evntsel_msr);
743 release_perfctr_nmi(wd->perfctr_msr);
744}
745
746void setup_apic_nmi_watchdog (void *unused)
747{
748 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
749
750 /* only support LOCAL and IO APICs for now */
751 if ((nmi_watchdog != NMI_LOCAL_APIC) &&
752 (nmi_watchdog != NMI_IO_APIC))
753 return;
754
755 if (wd->enabled == 1)
756 return;
757
758 /* cheap hack to support suspend/resume */
759 /* if cpu0 is not active neither should the other cpus */
760 if ((smp_processor_id() != 0) && (atomic_read(&nmi_active) <= 0))
761 return;
762
763 if (nmi_watchdog == NMI_LOCAL_APIC) {
764 switch (boot_cpu_data.x86_vendor) {
765 case X86_VENDOR_AMD:
766 if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15)
515 return; 767 return;
516 break; 768 if (!setup_k7_watchdog())
517 }
518 switch (boot_cpu_data.x86) {
519 case 6:
520 if (boot_cpu_data.x86_model > 0xd)
521 return; 769 return;
522
523 setup_p6_watchdog();
524 break; 770 break;
525 case 15: 771 case X86_VENDOR_INTEL:
526 if (boot_cpu_data.x86_model > 0x4) 772 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
527 return; 773 if (!setup_intel_arch_watchdog())
774 return;
775 break;
776 }
777 switch (boot_cpu_data.x86) {
778 case 6:
779 if (boot_cpu_data.x86_model > 0xd)
780 return;
781
782 if (!setup_p6_watchdog())
783 return;
784 break;
785 case 15:
786 if (boot_cpu_data.x86_model > 0x4)
787 return;
528 788
529 if (!setup_p4_watchdog()) 789 if (!setup_p4_watchdog())
790 return;
791 break;
792 default:
530 return; 793 return;
794 }
531 break; 795 break;
532 default: 796 default:
533 return; 797 return;
534 } 798 }
535 break; 799 }
536 default: 800 wd->enabled = 1;
801 atomic_inc(&nmi_active);
802}
803
804void stop_apic_nmi_watchdog(void *unused)
805{
806 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
807
808 /* only support LOCAL and IO APICs for now */
809 if ((nmi_watchdog != NMI_LOCAL_APIC) &&
810 (nmi_watchdog != NMI_IO_APIC))
811 return;
812
813 if (wd->enabled == 0)
537 return; 814 return;
815
816 if (nmi_watchdog == NMI_LOCAL_APIC) {
817 switch (boot_cpu_data.x86_vendor) {
818 case X86_VENDOR_AMD:
819 stop_k7_watchdog();
820 break;
821 case X86_VENDOR_INTEL:
822 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
823 stop_intel_arch_watchdog();
824 break;
825 }
826 switch (boot_cpu_data.x86) {
827 case 6:
828 if (boot_cpu_data.x86_model > 0xd)
829 break;
830 stop_p6_watchdog();
831 break;
832 case 15:
833 if (boot_cpu_data.x86_model > 0x4)
834 break;
835 stop_p4_watchdog();
836 break;
837 }
838 break;
839 default:
840 return;
841 }
538 } 842 }
539 lapic_nmi_owner = LAPIC_NMI_WATCHDOG; 843 wd->enabled = 0;
540 nmi_active = 1; 844 atomic_dec(&nmi_active);
541} 845}
542 846
543/* 847/*
@@ -579,7 +883,7 @@ EXPORT_SYMBOL(touch_nmi_watchdog);
579 883
580extern void die_nmi(struct pt_regs *, const char *msg); 884extern void die_nmi(struct pt_regs *, const char *msg);
581 885
582void nmi_watchdog_tick (struct pt_regs * regs) 886__kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
583{ 887{
584 888
585 /* 889 /*
@@ -588,11 +892,23 @@ void nmi_watchdog_tick (struct pt_regs * regs)
588 * smp_processor_id(). 892 * smp_processor_id().
589 */ 893 */
590 unsigned int sum; 894 unsigned int sum;
895 int touched = 0;
591 int cpu = smp_processor_id(); 896 int cpu = smp_processor_id();
897 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
898 u64 dummy;
899 int rc=0;
900
901 /* check for other users first */
902 if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT)
903 == NOTIFY_STOP) {
904 rc = 1;
905 touched = 1;
906 }
592 907
593 sum = per_cpu(irq_stat, cpu).apic_timer_irqs; 908 sum = per_cpu(irq_stat, cpu).apic_timer_irqs;
594 909
595 if (last_irq_sums[cpu] == sum) { 910 /* if the apic timer isn't firing, this cpu isn't doing much */
911 if (!touched && last_irq_sums[cpu] == sum) {
596 /* 912 /*
597 * Ayiee, looks like this CPU is stuck ... 913 * Ayiee, looks like this CPU is stuck ...
598 * wait a few IRQs (5 seconds) before doing the oops ... 914 * wait a few IRQs (5 seconds) before doing the oops ...
@@ -607,27 +923,59 @@ void nmi_watchdog_tick (struct pt_regs * regs)
607 last_irq_sums[cpu] = sum; 923 last_irq_sums[cpu] = sum;
608 alert_counter[cpu] = 0; 924 alert_counter[cpu] = 0;
609 } 925 }
610 if (nmi_perfctr_msr) { 926 /* see if the nmi watchdog went off */
611 if (nmi_perfctr_msr == MSR_P4_IQ_COUNTER0) { 927 if (wd->enabled) {
612 /* 928 if (nmi_watchdog == NMI_LOCAL_APIC) {
613 * P4 quirks: 929 rdmsrl(wd->perfctr_msr, dummy);
614 * - An overflown perfctr will assert its interrupt 930 if (dummy & wd->check_bit){
615 * until the OVF flag in its CCCR is cleared. 931 /* this wasn't a watchdog timer interrupt */
616 * - LVTPC is masked on interrupt and must be 932 goto done;
617 * unmasked by the LVTPC handler. 933 }
934
935 /* only Intel P4 uses the cccr msr */
936 if (wd->cccr_msr != 0) {
937 /*
938 * P4 quirks:
939 * - An overflown perfctr will assert its interrupt
940 * until the OVF flag in its CCCR is cleared.
941 * - LVTPC is masked on interrupt and must be
942 * unmasked by the LVTPC handler.
943 */
944 rdmsrl(wd->cccr_msr, dummy);
945 dummy &= ~P4_CCCR_OVF;
946 wrmsrl(wd->cccr_msr, dummy);
947 apic_write(APIC_LVTPC, APIC_DM_NMI);
948 }
949 else if (wd->perfctr_msr == MSR_P6_PERFCTR0 ||
950 wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) {
951 /* P6 based Pentium M need to re-unmask
952 * the apic vector but it doesn't hurt
953 * other P6 variant.
954 * ArchPerfom/Core Duo also needs this */
955 apic_write(APIC_LVTPC, APIC_DM_NMI);
956 }
957 /* start the cycle over again */
958 write_watchdog_counter(wd->perfctr_msr, NULL);
959 rc = 1;
960 } else if (nmi_watchdog == NMI_IO_APIC) {
961 /* don't know how to accurately check for this.
962 * just assume it was a watchdog timer interrupt
963 * This matches the old behaviour.
618 */ 964 */
619 wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); 965 rc = 1;
620 apic_write(APIC_LVTPC, APIC_DM_NMI);
621 } 966 }
622 else if (nmi_perfctr_msr == MSR_P6_PERFCTR0 ||
623 nmi_perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) {
624 /* Only P6 based Pentium M need to re-unmask
625 * the apic vector but it doesn't hurt
626 * other P6 variant */
627 apic_write(APIC_LVTPC, APIC_DM_NMI);
628 }
629 write_watchdog_counter(NULL);
630 } 967 }
968done:
969 return rc;
970}
971
972int do_nmi_callback(struct pt_regs * regs, int cpu)
973{
974#ifdef CONFIG_SYSCTL
975 if (unknown_nmi_panic)
976 return unknown_nmi_panic_callback(regs, cpu);
977#endif
978 return 0;
631} 979}
632 980
633#ifdef CONFIG_SYSCTL 981#ifdef CONFIG_SYSCTL
@@ -637,36 +985,46 @@ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu)
637 unsigned char reason = get_nmi_reason(); 985 unsigned char reason = get_nmi_reason();
638 char buf[64]; 986 char buf[64];
639 987
640 if (!(reason & 0xc0)) { 988 sprintf(buf, "NMI received for unknown reason %02x\n", reason);
641 sprintf(buf, "NMI received for unknown reason %02x\n", reason); 989 die_nmi(regs, buf);
642 die_nmi(regs, buf);
643 }
644 return 0; 990 return 0;
645} 991}
646 992
647/* 993/*
648 * proc handler for /proc/sys/kernel/unknown_nmi_panic 994 * proc handler for /proc/sys/kernel/nmi
649 */ 995 */
650int proc_unknown_nmi_panic(ctl_table *table, int write, struct file *file, 996int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file,
651 void __user *buffer, size_t *length, loff_t *ppos) 997 void __user *buffer, size_t *length, loff_t *ppos)
652{ 998{
653 int old_state; 999 int old_state;
654 1000
655 old_state = unknown_nmi_panic; 1001 nmi_watchdog_enabled = (atomic_read(&nmi_active) > 0) ? 1 : 0;
1002 old_state = nmi_watchdog_enabled;
656 proc_dointvec(table, write, file, buffer, length, ppos); 1003 proc_dointvec(table, write, file, buffer, length, ppos);
657 if (!!old_state == !!unknown_nmi_panic) 1004 if (!!old_state == !!nmi_watchdog_enabled)
658 return 0; 1005 return 0;
659 1006
660 if (unknown_nmi_panic) { 1007 if (atomic_read(&nmi_active) < 0) {
661 if (reserve_lapic_nmi() < 0) { 1008 printk( KERN_WARNING "NMI watchdog is permanently disabled\n");
662 unknown_nmi_panic = 0; 1009 return -EIO;
663 return -EBUSY; 1010 }
664 } else { 1011
665 set_nmi_callback(unknown_nmi_panic_callback); 1012 if (nmi_watchdog == NMI_DEFAULT) {
666 } 1013 if (nmi_known_cpu() > 0)
1014 nmi_watchdog = NMI_LOCAL_APIC;
1015 else
1016 nmi_watchdog = NMI_IO_APIC;
1017 }
1018
1019 if (nmi_watchdog == NMI_LOCAL_APIC) {
1020 if (nmi_watchdog_enabled)
1021 enable_lapic_nmi_watchdog();
1022 else
1023 disable_lapic_nmi_watchdog();
667 } else { 1024 } else {
668 release_lapic_nmi(); 1025 printk( KERN_WARNING
669 unset_nmi_callback(); 1026 "NMI watchdog doesn't know what hardware to touch\n");
1027 return -EIO;
670 } 1028 }
671 return 0; 1029 return 0;
672} 1030}
@@ -675,7 +1033,11 @@ int proc_unknown_nmi_panic(ctl_table *table, int write, struct file *file,
675 1033
676EXPORT_SYMBOL(nmi_active); 1034EXPORT_SYMBOL(nmi_active);
677EXPORT_SYMBOL(nmi_watchdog); 1035EXPORT_SYMBOL(nmi_watchdog);
678EXPORT_SYMBOL(reserve_lapic_nmi); 1036EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi);
679EXPORT_SYMBOL(release_lapic_nmi); 1037EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit);
1038EXPORT_SYMBOL(reserve_perfctr_nmi);
1039EXPORT_SYMBOL(release_perfctr_nmi);
1040EXPORT_SYMBOL(reserve_evntsel_nmi);
1041EXPORT_SYMBOL(release_evntsel_nmi);
680EXPORT_SYMBOL(disable_timer_nmi_watchdog); 1042EXPORT_SYMBOL(disable_timer_nmi_watchdog);
681EXPORT_SYMBOL(enable_timer_nmi_watchdog); 1043EXPORT_SYMBOL(enable_timer_nmi_watchdog);
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 8657c739656a..8c190ca7ae44 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -37,6 +37,7 @@
37#include <linux/kallsyms.h> 37#include <linux/kallsyms.h>
38#include <linux/ptrace.h> 38#include <linux/ptrace.h>
39#include <linux/random.h> 39#include <linux/random.h>
40#include <linux/personality.h>
40 41
41#include <asm/uaccess.h> 42#include <asm/uaccess.h>
42#include <asm/pgtable.h> 43#include <asm/pgtable.h>
@@ -320,15 +321,6 @@ void show_regs(struct pt_regs * regs)
320 * the "args". 321 * the "args".
321 */ 322 */
322extern void kernel_thread_helper(void); 323extern void kernel_thread_helper(void);
323__asm__(".section .text\n"
324 ".align 4\n"
325 "kernel_thread_helper:\n\t"
326 "movl %edx,%eax\n\t"
327 "pushl %edx\n\t"
328 "call *%ebx\n\t"
329 "pushl %eax\n\t"
330 "call do_exit\n"
331 ".previous");
332 324
333/* 325/*
334 * Create a kernel thread 326 * Create a kernel thread
@@ -346,7 +338,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
346 regs.xes = __USER_DS; 338 regs.xes = __USER_DS;
347 regs.orig_eax = -1; 339 regs.orig_eax = -1;
348 regs.eip = (unsigned long) kernel_thread_helper; 340 regs.eip = (unsigned long) kernel_thread_helper;
349 regs.xcs = __KERNEL_CS; 341 regs.xcs = __KERNEL_CS | get_kernel_rpl();
350 regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2; 342 regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
351 343
352 /* Ok, create the new process.. */ 344 /* Ok, create the new process.. */
@@ -905,7 +897,7 @@ asmlinkage int sys_get_thread_area(struct user_desc __user *u_info)
905 897
906unsigned long arch_align_stack(unsigned long sp) 898unsigned long arch_align_stack(unsigned long sp)
907{ 899{
908 if (randomize_va_space) 900 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
909 sp -= get_random_int() % 8192; 901 sp -= get_random_int() % 8192;
910 return sp & ~0xf; 902 return sp & ~0xf;
911} 903}
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index d3db03f4085d..775f50e9395b 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -185,17 +185,17 @@ static unsigned long convert_eip_to_linear(struct task_struct *child, struct pt_
185 return addr; 185 return addr;
186} 186}
187 187
188static inline int is_at_popf(struct task_struct *child, struct pt_regs *regs) 188static inline int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs)
189{ 189{
190 int i, copied; 190 int i, copied;
191 unsigned char opcode[16]; 191 unsigned char opcode[15];
192 unsigned long addr = convert_eip_to_linear(child, regs); 192 unsigned long addr = convert_eip_to_linear(child, regs);
193 193
194 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0); 194 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
195 for (i = 0; i < copied; i++) { 195 for (i = 0; i < copied; i++) {
196 switch (opcode[i]) { 196 switch (opcode[i]) {
197 /* popf */ 197 /* popf and iret */
198 case 0x9d: 198 case 0x9d: case 0xcf:
199 return 1; 199 return 1;
200 /* opcode and address size prefixes */ 200 /* opcode and address size prefixes */
201 case 0x66: case 0x67: 201 case 0x66: case 0x67:
@@ -247,7 +247,7 @@ static void set_singlestep(struct task_struct *child)
247 * don't mark it as being "us" that set it, so that we 247 * don't mark it as being "us" that set it, so that we
248 * won't clear it by hand later. 248 * won't clear it by hand later.
249 */ 249 */
250 if (is_at_popf(child, regs)) 250 if (is_setting_trap_flag(child, regs))
251 return; 251 return;
252 252
253 child->ptrace |= PT_DTRACE; 253 child->ptrace |= PT_DTRACE;
diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c
index 54cfeabbc5e4..84278e0093a2 100644
--- a/arch/i386/kernel/reboot.c
+++ b/arch/i386/kernel/reboot.c
@@ -145,14 +145,10 @@ real_mode_gdt_entries [3] =
145 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */ 145 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
146}; 146};
147 147
148static struct 148static struct Xgt_desc_struct
149{ 149real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries },
150 unsigned short size __attribute__ ((packed)); 150real_mode_idt = { 0x3ff, 0 },
151 unsigned long long * base __attribute__ ((packed)); 151no_idt = { 0, 0 };
152}
153real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries },
154real_mode_idt = { 0x3ff, NULL },
155no_idt = { 0, NULL };
156 152
157 153
158/* This is 16-bit protected mode code to disable paging and the cache, 154/* This is 16-bit protected mode code to disable paging and the cache,
diff --git a/arch/i386/kernel/relocate_kernel.S b/arch/i386/kernel/relocate_kernel.S
index d312616effa1..f151d6fae462 100644
--- a/arch/i386/kernel/relocate_kernel.S
+++ b/arch/i386/kernel/relocate_kernel.S
@@ -7,16 +7,138 @@
7 */ 7 */
8 8
9#include <linux/linkage.h> 9#include <linux/linkage.h>
10#include <asm/page.h>
11#include <asm/kexec.h>
12
13/*
14 * Must be relocatable PIC code callable as a C function
15 */
16
17#define PTR(x) (x << 2)
18#define PAGE_ALIGNED (1 << PAGE_SHIFT)
19#define PAGE_ATTR 0x63 /* _PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY */
20#define PAE_PGD_ATTR 0x01 /* _PAGE_PRESENT */
21
22 .text
23 .align PAGE_ALIGNED
24 .globl relocate_kernel
25relocate_kernel:
26 movl 8(%esp), %ebp /* list of pages */
27
28#ifdef CONFIG_X86_PAE
29 /* map the control page at its virtual address */
30
31 movl PTR(VA_PGD)(%ebp), %edi
32 movl PTR(VA_CONTROL_PAGE)(%ebp), %eax
33 andl $0xc0000000, %eax
34 shrl $27, %eax
35 addl %edi, %eax
36
37 movl PTR(PA_PMD_0)(%ebp), %edx
38 orl $PAE_PGD_ATTR, %edx
39 movl %edx, (%eax)
40
41 movl PTR(VA_PMD_0)(%ebp), %edi
42 movl PTR(VA_CONTROL_PAGE)(%ebp), %eax
43 andl $0x3fe00000, %eax
44 shrl $18, %eax
45 addl %edi, %eax
46
47 movl PTR(PA_PTE_0)(%ebp), %edx
48 orl $PAGE_ATTR, %edx
49 movl %edx, (%eax)
50
51 movl PTR(VA_PTE_0)(%ebp), %edi
52 movl PTR(VA_CONTROL_PAGE)(%ebp), %eax
53 andl $0x001ff000, %eax
54 shrl $9, %eax
55 addl %edi, %eax
56
57 movl PTR(PA_CONTROL_PAGE)(%ebp), %edx
58 orl $PAGE_ATTR, %edx
59 movl %edx, (%eax)
60
61 /* identity map the control page at its physical address */
62
63 movl PTR(VA_PGD)(%ebp), %edi
64 movl PTR(PA_CONTROL_PAGE)(%ebp), %eax
65 andl $0xc0000000, %eax
66 shrl $27, %eax
67 addl %edi, %eax
68
69 movl PTR(PA_PMD_1)(%ebp), %edx
70 orl $PAE_PGD_ATTR, %edx
71 movl %edx, (%eax)
72
73 movl PTR(VA_PMD_1)(%ebp), %edi
74 movl PTR(PA_CONTROL_PAGE)(%ebp), %eax
75 andl $0x3fe00000, %eax
76 shrl $18, %eax
77 addl %edi, %eax
78
79 movl PTR(PA_PTE_1)(%ebp), %edx
80 orl $PAGE_ATTR, %edx
81 movl %edx, (%eax)
82
83 movl PTR(VA_PTE_1)(%ebp), %edi
84 movl PTR(PA_CONTROL_PAGE)(%ebp), %eax
85 andl $0x001ff000, %eax
86 shrl $9, %eax
87 addl %edi, %eax
88
89 movl PTR(PA_CONTROL_PAGE)(%ebp), %edx
90 orl $PAGE_ATTR, %edx
91 movl %edx, (%eax)
92#else
93 /* map the control page at its virtual address */
94
95 movl PTR(VA_PGD)(%ebp), %edi
96 movl PTR(VA_CONTROL_PAGE)(%ebp), %eax
97 andl $0xffc00000, %eax
98 shrl $20, %eax
99 addl %edi, %eax
100
101 movl PTR(PA_PTE_0)(%ebp), %edx
102 orl $PAGE_ATTR, %edx
103 movl %edx, (%eax)
104
105 movl PTR(VA_PTE_0)(%ebp), %edi
106 movl PTR(VA_CONTROL_PAGE)(%ebp), %eax
107 andl $0x003ff000, %eax
108 shrl $10, %eax
109 addl %edi, %eax
110
111 movl PTR(PA_CONTROL_PAGE)(%ebp), %edx
112 orl $PAGE_ATTR, %edx
113 movl %edx, (%eax)
114
115 /* identity map the control page at its physical address */
116
117 movl PTR(VA_PGD)(%ebp), %edi
118 movl PTR(PA_CONTROL_PAGE)(%ebp), %eax
119 andl $0xffc00000, %eax
120 shrl $20, %eax
121 addl %edi, %eax
122
123 movl PTR(PA_PTE_1)(%ebp), %edx
124 orl $PAGE_ATTR, %edx
125 movl %edx, (%eax)
126
127 movl PTR(VA_PTE_1)(%ebp), %edi
128 movl PTR(PA_CONTROL_PAGE)(%ebp), %eax
129 andl $0x003ff000, %eax
130 shrl $10, %eax
131 addl %edi, %eax
132
133 movl PTR(PA_CONTROL_PAGE)(%ebp), %edx
134 orl $PAGE_ATTR, %edx
135 movl %edx, (%eax)
136#endif
10 137
11 /*
12 * Must be relocatable PIC code callable as a C function, that once
13 * it starts can not use the previous processes stack.
14 */
15 .globl relocate_new_kernel
16relocate_new_kernel: 138relocate_new_kernel:
17 /* read the arguments and say goodbye to the stack */ 139 /* read the arguments and say goodbye to the stack */
18 movl 4(%esp), %ebx /* page_list */ 140 movl 4(%esp), %ebx /* page_list */
19 movl 8(%esp), %ebp /* reboot_code_buffer */ 141 movl 8(%esp), %ebp /* list of pages */
20 movl 12(%esp), %edx /* start address */ 142 movl 12(%esp), %edx /* start address */
21 movl 16(%esp), %ecx /* cpu_has_pae */ 143 movl 16(%esp), %ecx /* cpu_has_pae */
22 144
@@ -24,11 +146,26 @@ relocate_new_kernel:
24 pushl $0 146 pushl $0
25 popfl 147 popfl
26 148
27 /* set a new stack at the bottom of our page... */ 149 /* get physical address of control page now */
28 lea 4096(%ebp), %esp 150 /* this is impossible after page table switch */
151 movl PTR(PA_CONTROL_PAGE)(%ebp), %edi
29 152
30 /* store the parameters back on the stack */ 153 /* switch to new set of page tables */
31 pushl %edx /* store the start address */ 154 movl PTR(PA_PGD)(%ebp), %eax
155 movl %eax, %cr3
156
157 /* setup a new stack at the end of the physical control page */
158 lea 4096(%edi), %esp
159
160 /* jump to identity mapped page */
161 movl %edi, %eax
162 addl $(identity_mapped - relocate_kernel), %eax
163 pushl %eax
164 ret
165
166identity_mapped:
167 /* store the start address on the stack */
168 pushl %edx
32 169
33 /* Set cr0 to a known state: 170 /* Set cr0 to a known state:
34 * 31 0 == Paging disabled 171 * 31 0 == Paging disabled
@@ -113,8 +250,3 @@ relocate_new_kernel:
113 xorl %edi, %edi 250 xorl %edi, %edi
114 xorl %ebp, %ebp 251 xorl %ebp, %ebp
115 ret 252 ret
116relocate_new_kernel_end:
117
118 .globl relocate_new_kernel_size
119relocate_new_kernel_size:
120 .long relocate_new_kernel_end - relocate_new_kernel
diff --git a/arch/i386/kernel/semaphore.c b/arch/i386/kernel/semaphore.c
deleted file mode 100644
index 98352c374c76..000000000000
--- a/arch/i386/kernel/semaphore.c
+++ /dev/null
@@ -1,134 +0,0 @@
1/*
2 * i386 semaphore implementation.
3 *
4 * (C) Copyright 1999 Linus Torvalds
5 *
6 * Portions Copyright 1999 Red Hat, Inc.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 *
13 * rw semaphores implemented November 1999 by Benjamin LaHaise <bcrl@kvack.org>
14 */
15#include <asm/semaphore.h>
16
17/*
18 * The semaphore operations have a special calling sequence that
19 * allow us to do a simpler in-line version of them. These routines
20 * need to convert that sequence back into the C sequence when
21 * there is contention on the semaphore.
22 *
23 * %eax contains the semaphore pointer on entry. Save the C-clobbered
24 * registers (%eax, %edx and %ecx) except %eax whish is either a return
25 * value or just clobbered..
26 */
27asm(
28".section .sched.text\n"
29".align 4\n"
30".globl __down_failed\n"
31"__down_failed:\n\t"
32#if defined(CONFIG_FRAME_POINTER)
33 "pushl %ebp\n\t"
34 "movl %esp,%ebp\n\t"
35#endif
36 "pushl %edx\n\t"
37 "pushl %ecx\n\t"
38 "call __down\n\t"
39 "popl %ecx\n\t"
40 "popl %edx\n\t"
41#if defined(CONFIG_FRAME_POINTER)
42 "movl %ebp,%esp\n\t"
43 "popl %ebp\n\t"
44#endif
45 "ret"
46);
47
48asm(
49".section .sched.text\n"
50".align 4\n"
51".globl __down_failed_interruptible\n"
52"__down_failed_interruptible:\n\t"
53#if defined(CONFIG_FRAME_POINTER)
54 "pushl %ebp\n\t"
55 "movl %esp,%ebp\n\t"
56#endif
57 "pushl %edx\n\t"
58 "pushl %ecx\n\t"
59 "call __down_interruptible\n\t"
60 "popl %ecx\n\t"
61 "popl %edx\n\t"
62#if defined(CONFIG_FRAME_POINTER)
63 "movl %ebp,%esp\n\t"
64 "popl %ebp\n\t"
65#endif
66 "ret"
67);
68
69asm(
70".section .sched.text\n"
71".align 4\n"
72".globl __down_failed_trylock\n"
73"__down_failed_trylock:\n\t"
74#if defined(CONFIG_FRAME_POINTER)
75 "pushl %ebp\n\t"
76 "movl %esp,%ebp\n\t"
77#endif
78 "pushl %edx\n\t"
79 "pushl %ecx\n\t"
80 "call __down_trylock\n\t"
81 "popl %ecx\n\t"
82 "popl %edx\n\t"
83#if defined(CONFIG_FRAME_POINTER)
84 "movl %ebp,%esp\n\t"
85 "popl %ebp\n\t"
86#endif
87 "ret"
88);
89
90asm(
91".section .sched.text\n"
92".align 4\n"
93".globl __up_wakeup\n"
94"__up_wakeup:\n\t"
95 "pushl %edx\n\t"
96 "pushl %ecx\n\t"
97 "call __up\n\t"
98 "popl %ecx\n\t"
99 "popl %edx\n\t"
100 "ret"
101);
102
103/*
104 * rw spinlock fallbacks
105 */
106#if defined(CONFIG_SMP)
107asm(
108".section .sched.text\n"
109".align 4\n"
110".globl __write_lock_failed\n"
111"__write_lock_failed:\n\t"
112 LOCK_PREFIX "addl $" RW_LOCK_BIAS_STR ",(%eax)\n"
113"1: rep; nop\n\t"
114 "cmpl $" RW_LOCK_BIAS_STR ",(%eax)\n\t"
115 "jne 1b\n\t"
116 LOCK_PREFIX "subl $" RW_LOCK_BIAS_STR ",(%eax)\n\t"
117 "jnz __write_lock_failed\n\t"
118 "ret"
119);
120
121asm(
122".section .sched.text\n"
123".align 4\n"
124".globl __read_lock_failed\n"
125"__read_lock_failed:\n\t"
126 LOCK_PREFIX "incl (%eax)\n"
127"1: rep; nop\n\t"
128 "cmpl $1,(%eax)\n\t"
129 "js 1b\n\t"
130 LOCK_PREFIX "decl (%eax)\n\t"
131 "js __read_lock_failed\n\t"
132 "ret"
133);
134#endif
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index f1682206d304..814cdebf7377 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -53,6 +53,7 @@
53#include <asm/apic.h> 53#include <asm/apic.h>
54#include <asm/e820.h> 54#include <asm/e820.h>
55#include <asm/mpspec.h> 55#include <asm/mpspec.h>
56#include <asm/mmzone.h>
56#include <asm/setup.h> 57#include <asm/setup.h>
57#include <asm/arch_hooks.h> 58#include <asm/arch_hooks.h>
58#include <asm/sections.h> 59#include <asm/sections.h>
@@ -89,18 +90,6 @@ EXPORT_SYMBOL(boot_cpu_data);
89 90
90unsigned long mmu_cr4_features; 91unsigned long mmu_cr4_features;
91 92
92#ifdef CONFIG_ACPI
93 int acpi_disabled = 0;
94#else
95 int acpi_disabled = 1;
96#endif
97EXPORT_SYMBOL(acpi_disabled);
98
99#ifdef CONFIG_ACPI
100int __initdata acpi_force = 0;
101extern acpi_interrupt_flags acpi_sci_flags;
102#endif
103
104/* for MCA, but anyone else can use it if they want */ 93/* for MCA, but anyone else can use it if they want */
105unsigned int machine_id; 94unsigned int machine_id;
106#ifdef CONFIG_MCA 95#ifdef CONFIG_MCA
@@ -148,7 +137,6 @@ EXPORT_SYMBOL(ist_info);
148struct e820map e820; 137struct e820map e820;
149 138
150extern void early_cpu_init(void); 139extern void early_cpu_init(void);
151extern void generic_apic_probe(char *);
152extern int root_mountflags; 140extern int root_mountflags;
153 141
154unsigned long saved_videomode; 142unsigned long saved_videomode;
@@ -700,238 +688,150 @@ static inline void copy_edd(void)
700} 688}
701#endif 689#endif
702 690
703static void __init parse_cmdline_early (char ** cmdline_p) 691static int __initdata user_defined_memmap = 0;
704{
705 char c = ' ', *to = command_line, *from = saved_command_line;
706 int len = 0;
707 int userdef = 0;
708 692
709 /* Save unparsed command line copy for /proc/cmdline */ 693/*
710 saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; 694 * "mem=nopentium" disables the 4MB page tables.
695 * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM
696 * to <mem>, overriding the bios size.
697 * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from
698 * <start> to <start>+<mem>, overriding the bios size.
699 *
700 * HPA tells me bootloaders need to parse mem=, so no new
701 * option should be mem= [also see Documentation/i386/boot.txt]
702 */
703static int __init parse_mem(char *arg)
704{
705 if (!arg)
706 return -EINVAL;
711 707
712 for (;;) { 708 if (strcmp(arg, "nopentium") == 0) {
713 if (c != ' ') 709 clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability);
714 goto next_char; 710 disable_pse = 1;
715 /* 711 } else {
716 * "mem=nopentium" disables the 4MB page tables. 712 /* If the user specifies memory size, we
717 * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM 713 * limit the BIOS-provided memory map to
718 * to <mem>, overriding the bios size. 714 * that size. exactmap can be used to specify
719 * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from 715 * the exact map. mem=number can be used to
720 * <start> to <start>+<mem>, overriding the bios size. 716 * trim the existing memory map.
721 *
722 * HPA tells me bootloaders need to parse mem=, so no new
723 * option should be mem= [also see Documentation/i386/boot.txt]
724 */ 717 */
725 if (!memcmp(from, "mem=", 4)) { 718 unsigned long long mem_size;
726 if (to != command_line)
727 to--;
728 if (!memcmp(from+4, "nopentium", 9)) {
729 from += 9+4;
730 clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability);
731 disable_pse = 1;
732 } else {
733 /* If the user specifies memory size, we
734 * limit the BIOS-provided memory map to
735 * that size. exactmap can be used to specify
736 * the exact map. mem=number can be used to
737 * trim the existing memory map.
738 */
739 unsigned long long mem_size;
740
741 mem_size = memparse(from+4, &from);
742 limit_regions(mem_size);
743 userdef=1;
744 }
745 }
746
747 else if (!memcmp(from, "memmap=", 7)) {
748 if (to != command_line)
749 to--;
750 if (!memcmp(from+7, "exactmap", 8)) {
751#ifdef CONFIG_CRASH_DUMP
752 /* If we are doing a crash dump, we
753 * still need to know the real mem
754 * size before original memory map is
755 * reset.
756 */
757 find_max_pfn();
758 saved_max_pfn = max_pfn;
759#endif
760 from += 8+7;
761 e820.nr_map = 0;
762 userdef = 1;
763 } else {
764 /* If the user specifies memory size, we
765 * limit the BIOS-provided memory map to
766 * that size. exactmap can be used to specify
767 * the exact map. mem=number can be used to
768 * trim the existing memory map.
769 */
770 unsigned long long start_at, mem_size;
771 719
772 mem_size = memparse(from+7, &from); 720 mem_size = memparse(arg, &arg);
773 if (*from == '@') { 721 limit_regions(mem_size);
774 start_at = memparse(from+1, &from); 722 user_defined_memmap = 1;
775 add_memory_region(start_at, mem_size, E820_RAM); 723 }
776 } else if (*from == '#') { 724 return 0;
777 start_at = memparse(from+1, &from); 725}
778 add_memory_region(start_at, mem_size, E820_ACPI); 726early_param("mem", parse_mem);
779 } else if (*from == '$') {
780 start_at = memparse(from+1, &from);
781 add_memory_region(start_at, mem_size, E820_RESERVED);
782 } else {
783 limit_regions(mem_size);
784 userdef=1;
785 }
786 }
787 }
788
789 else if (!memcmp(from, "noexec=", 7))
790 noexec_setup(from + 7);
791 727
728static int __init parse_memmap(char *arg)
729{
730 if (!arg)
731 return -EINVAL;
792 732
793#ifdef CONFIG_X86_SMP 733 if (strcmp(arg, "exactmap") == 0) {
794 /* 734#ifdef CONFIG_CRASH_DUMP
795 * If the BIOS enumerates physical processors before logical, 735 /* If we are doing a crash dump, we
796 * maxcpus=N at enumeration-time can be used to disable HT. 736 * still need to know the real mem
737 * size before original memory map is
738 * reset.
797 */ 739 */
798 else if (!memcmp(from, "maxcpus=", 8)) { 740 find_max_pfn();
799 extern unsigned int maxcpus; 741 saved_max_pfn = max_pfn;
800
801 maxcpus = simple_strtoul(from + 8, NULL, 0);
802 }
803#endif 742#endif
804 743 e820.nr_map = 0;
805#ifdef CONFIG_ACPI 744 user_defined_memmap = 1;
806 /* "acpi=off" disables both ACPI table parsing and interpreter */ 745 } else {
807 else if (!memcmp(from, "acpi=off", 8)) { 746 /* If the user specifies memory size, we
808 disable_acpi(); 747 * limit the BIOS-provided memory map to
809 } 748 * that size. exactmap can be used to specify
810 749 * the exact map. mem=number can be used to
811 /* acpi=force to over-ride black-list */ 750 * trim the existing memory map.
812 else if (!memcmp(from, "acpi=force", 10)) { 751 */
813 acpi_force = 1; 752 unsigned long long start_at, mem_size;
814 acpi_ht = 1; 753
815 acpi_disabled = 0; 754 mem_size = memparse(arg, &arg);
816 } 755 if (*arg == '@') {
817 756 start_at = memparse(arg+1, &arg);
818 /* acpi=strict disables out-of-spec workarounds */ 757 add_memory_region(start_at, mem_size, E820_RAM);
819 else if (!memcmp(from, "acpi=strict", 11)) { 758 } else if (*arg == '#') {
820 acpi_strict = 1; 759 start_at = memparse(arg+1, &arg);
821 } 760 add_memory_region(start_at, mem_size, E820_ACPI);
822 761 } else if (*arg == '$') {
823 /* Limit ACPI just to boot-time to enable HT */ 762 start_at = memparse(arg+1, &arg);
824 else if (!memcmp(from, "acpi=ht", 7)) { 763 add_memory_region(start_at, mem_size, E820_RESERVED);
825 if (!acpi_force) 764 } else {
826 disable_acpi(); 765 limit_regions(mem_size);
827 acpi_ht = 1; 766 user_defined_memmap = 1;
828 }
829
830 /* "pci=noacpi" disable ACPI IRQ routing and PCI scan */
831 else if (!memcmp(from, "pci=noacpi", 10)) {
832 acpi_disable_pci();
833 }
834 /* "acpi=noirq" disables ACPI interrupt routing */
835 else if (!memcmp(from, "acpi=noirq", 10)) {
836 acpi_noirq_set();
837 } 767 }
768 }
769 return 0;
770}
771early_param("memmap", parse_memmap);
838 772
839 else if (!memcmp(from, "acpi_sci=edge", 13)) 773#ifdef CONFIG_PROC_VMCORE
840 acpi_sci_flags.trigger = 1; 774/* elfcorehdr= specifies the location of elf core header
841 775 * stored by the crashed kernel.
842 else if (!memcmp(from, "acpi_sci=level", 14)) 776 */
843 acpi_sci_flags.trigger = 3; 777static int __init parse_elfcorehdr(char *arg)
844 778{
845 else if (!memcmp(from, "acpi_sci=high", 13)) 779 if (!arg)
846 acpi_sci_flags.polarity = 1; 780 return -EINVAL;
847 781
848 else if (!memcmp(from, "acpi_sci=low", 12)) 782 elfcorehdr_addr = memparse(arg, &arg);
849 acpi_sci_flags.polarity = 3; 783 return 0;
784}
785early_param("elfcorehdr", parse_elfcorehdr);
786#endif /* CONFIG_PROC_VMCORE */
850 787
851#ifdef CONFIG_X86_IO_APIC 788/*
852 else if (!memcmp(from, "acpi_skip_timer_override", 24)) 789 * highmem=size forces highmem to be exactly 'size' bytes.
853 acpi_skip_timer_override = 1; 790 * This works even on boxes that have no highmem otherwise.
791 * This also works to reduce highmem size on bigger boxes.
792 */
793static int __init parse_highmem(char *arg)
794{
795 if (!arg)
796 return -EINVAL;
854 797
855 if (!memcmp(from, "disable_timer_pin_1", 19)) 798 highmem_pages = memparse(arg, &arg) >> PAGE_SHIFT;
856 disable_timer_pin_1 = 1; 799 return 0;
857 if (!memcmp(from, "enable_timer_pin_1", 18)) 800}
858 disable_timer_pin_1 = -1; 801early_param("highmem", parse_highmem);
859 802
860 /* disable IO-APIC */ 803/*
861 else if (!memcmp(from, "noapic", 6)) 804 * vmalloc=size forces the vmalloc area to be exactly 'size'
862 disable_ioapic_setup(); 805 * bytes. This can be used to increase (or decrease) the
863#endif /* CONFIG_X86_IO_APIC */ 806 * vmalloc area - the default is 128m.
864#endif /* CONFIG_ACPI */ 807 */
808static int __init parse_vmalloc(char *arg)
809{
810 if (!arg)
811 return -EINVAL;
865 812
866#ifdef CONFIG_X86_LOCAL_APIC 813 __VMALLOC_RESERVE = memparse(arg, &arg);
867 /* enable local APIC */ 814 return 0;
868 else if (!memcmp(from, "lapic", 5)) 815}
869 lapic_enable(); 816early_param("vmalloc", parse_vmalloc);
870 817
871 /* disable local APIC */ 818/*
872 else if (!memcmp(from, "nolapic", 6)) 819 * reservetop=size reserves a hole at the top of the kernel address space which
873 lapic_disable(); 820 * a hypervisor can load into later. Needed for dynamically loaded hypervisors,
874#endif /* CONFIG_X86_LOCAL_APIC */ 821 * so relocating the fixmap can be done before paging initialization.
822 */
823static int __init parse_reservetop(char *arg)
824{
825 unsigned long address;
875 826
876#ifdef CONFIG_KEXEC 827 if (!arg)
877 /* crashkernel=size@addr specifies the location to reserve for 828 return -EINVAL;
878 * a crash kernel. By reserving this memory we guarantee
879 * that linux never set's it up as a DMA target.
880 * Useful for holding code to do something appropriate
881 * after a kernel panic.
882 */
883 else if (!memcmp(from, "crashkernel=", 12)) {
884 unsigned long size, base;
885 size = memparse(from+12, &from);
886 if (*from == '@') {
887 base = memparse(from+1, &from);
888 /* FIXME: Do I want a sanity check
889 * to validate the memory range?
890 */
891 crashk_res.start = base;
892 crashk_res.end = base + size - 1;
893 }
894 }
895#endif
896#ifdef CONFIG_PROC_VMCORE
897 /* elfcorehdr= specifies the location of elf core header
898 * stored by the crashed kernel.
899 */
900 else if (!memcmp(from, "elfcorehdr=", 11))
901 elfcorehdr_addr = memparse(from+11, &from);
902#endif
903 829
904 /* 830 address = memparse(arg, &arg);
905 * highmem=size forces highmem to be exactly 'size' bytes. 831 reserve_top_address(address);
906 * This works even on boxes that have no highmem otherwise. 832 return 0;
907 * This also works to reduce highmem size on bigger boxes.
908 */
909 else if (!memcmp(from, "highmem=", 8))
910 highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT;
911
912 /*
913 * vmalloc=size forces the vmalloc area to be exactly 'size'
914 * bytes. This can be used to increase (or decrease) the
915 * vmalloc area - the default is 128m.
916 */
917 else if (!memcmp(from, "vmalloc=", 8))
918 __VMALLOC_RESERVE = memparse(from+8, &from);
919
920 next_char:
921 c = *(from++);
922 if (!c)
923 break;
924 if (COMMAND_LINE_SIZE <= ++len)
925 break;
926 *(to++) = c;
927 }
928 *to = '\0';
929 *cmdline_p = command_line;
930 if (userdef) {
931 printk(KERN_INFO "user-defined physical RAM map:\n");
932 print_memory_map("user");
933 }
934} 833}
834early_param("reservetop", parse_reservetop);
935 835
936/* 836/*
937 * Callback for efi_memory_walk. 837 * Callback for efi_memory_walk.
@@ -1170,6 +1070,14 @@ static unsigned long __init setup_memory(void)
1170 } 1070 }
1171 printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", 1071 printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
1172 pages_to_mb(highend_pfn - highstart_pfn)); 1072 pages_to_mb(highend_pfn - highstart_pfn));
1073 num_physpages = highend_pfn;
1074 high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1;
1075#else
1076 num_physpages = max_low_pfn;
1077 high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1;
1078#endif
1079#ifdef CONFIG_FLATMEM
1080 max_mapnr = num_physpages;
1173#endif 1081#endif
1174 printk(KERN_NOTICE "%ldMB LOWMEM available.\n", 1082 printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
1175 pages_to_mb(max_low_pfn)); 1083 pages_to_mb(max_low_pfn));
@@ -1181,22 +1089,20 @@ static unsigned long __init setup_memory(void)
1181 1089
1182void __init zone_sizes_init(void) 1090void __init zone_sizes_init(void)
1183{ 1091{
1184 unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
1185 unsigned int max_dma, low;
1186
1187 max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
1188 low = max_low_pfn;
1189
1190 if (low < max_dma)
1191 zones_size[ZONE_DMA] = low;
1192 else {
1193 zones_size[ZONE_DMA] = max_dma;
1194 zones_size[ZONE_NORMAL] = low - max_dma;
1195#ifdef CONFIG_HIGHMEM 1092#ifdef CONFIG_HIGHMEM
1196 zones_size[ZONE_HIGHMEM] = highend_pfn - low; 1093 unsigned long max_zone_pfns[MAX_NR_ZONES] = {
1094 virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT,
1095 max_low_pfn,
1096 highend_pfn};
1097 add_active_range(0, 0, highend_pfn);
1098#else
1099 unsigned long max_zone_pfns[MAX_NR_ZONES] = {
1100 virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT,
1101 max_low_pfn};
1102 add_active_range(0, 0, max_low_pfn);
1197#endif 1103#endif
1198 } 1104
1199 free_area_init(zones_size); 1105 free_area_init_nodes(max_zone_pfns);
1200} 1106}
1201#else 1107#else
1202extern unsigned long __init setup_memory(void); 1108extern unsigned long __init setup_memory(void);
@@ -1258,7 +1164,7 @@ void __init setup_bootmem_allocator(void)
1258 */ 1164 */
1259 find_smp_config(); 1165 find_smp_config();
1260#endif 1166#endif
1261 1167 numa_kva_reserve();
1262#ifdef CONFIG_BLK_DEV_INITRD 1168#ifdef CONFIG_BLK_DEV_INITRD
1263 if (LOADER_TYPE && INITRD_START) { 1169 if (LOADER_TYPE && INITRD_START) {
1264 if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { 1170 if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
@@ -1499,17 +1405,15 @@ void __init setup_arch(char **cmdline_p)
1499 data_resource.start = virt_to_phys(_etext); 1405 data_resource.start = virt_to_phys(_etext);
1500 data_resource.end = virt_to_phys(_edata)-1; 1406 data_resource.end = virt_to_phys(_edata)-1;
1501 1407
1502 parse_cmdline_early(cmdline_p); 1408 parse_early_param();
1503 1409
1504#ifdef CONFIG_EARLY_PRINTK 1410 if (user_defined_memmap) {
1505 { 1411 printk(KERN_INFO "user-defined physical RAM map:\n");
1506 char *s = strstr(*cmdline_p, "earlyprintk="); 1412 print_memory_map("user");
1507 if (s) {
1508 setup_early_printk(strchr(s, '=') + 1);
1509 printk("early console enabled\n");
1510 }
1511 } 1413 }
1512#endif 1414
1415 strlcpy(command_line, saved_command_line, COMMAND_LINE_SIZE);
1416 *cmdline_p = command_line;
1513 1417
1514 max_low_pfn = setup_memory(); 1418 max_low_pfn = setup_memory();
1515 1419
@@ -1538,7 +1442,7 @@ void __init setup_arch(char **cmdline_p)
1538 dmi_scan_machine(); 1442 dmi_scan_machine();
1539 1443
1540#ifdef CONFIG_X86_GENERICARCH 1444#ifdef CONFIG_X86_GENERICARCH
1541 generic_apic_probe(*cmdline_p); 1445 generic_apic_probe();
1542#endif 1446#endif
1543 if (efi_enabled) 1447 if (efi_enabled)
1544 efi_map_memmap(); 1448 efi_map_memmap();
@@ -1550,9 +1454,11 @@ void __init setup_arch(char **cmdline_p)
1550 acpi_boot_table_init(); 1454 acpi_boot_table_init();
1551#endif 1455#endif
1552 1456
1457#ifdef CONFIG_PCI
1553#ifdef CONFIG_X86_IO_APIC 1458#ifdef CONFIG_X86_IO_APIC
1554 check_acpi_pci(); /* Checks more than just ACPI actually */ 1459 check_acpi_pci(); /* Checks more than just ACPI actually */
1555#endif 1460#endif
1461#endif
1556 1462
1557#ifdef CONFIG_ACPI 1463#ifdef CONFIG_ACPI
1558 acpi_boot_init(); 1464 acpi_boot_init();
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index c10789d7a9d3..465188e2d701 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -634,3 +634,69 @@ fastcall void smp_call_function_interrupt(struct pt_regs *regs)
634 } 634 }
635} 635}
636 636
637/*
638 * this function sends a 'generic call function' IPI to one other CPU
639 * in the system.
640 *
641 * cpu is a standard Linux logical CPU number.
642 */
643static void
644__smp_call_function_single(int cpu, void (*func) (void *info), void *info,
645 int nonatomic, int wait)
646{
647 struct call_data_struct data;
648 int cpus = 1;
649
650 data.func = func;
651 data.info = info;
652 atomic_set(&data.started, 0);
653 data.wait = wait;
654 if (wait)
655 atomic_set(&data.finished, 0);
656
657 call_data = &data;
658 wmb();
659 /* Send a message to all other CPUs and wait for them to respond */
660 send_IPI_mask(cpumask_of_cpu(cpu), CALL_FUNCTION_VECTOR);
661
662 /* Wait for response */
663 while (atomic_read(&data.started) != cpus)
664 cpu_relax();
665
666 if (!wait)
667 return;
668
669 while (atomic_read(&data.finished) != cpus)
670 cpu_relax();
671}
672
673/*
674 * smp_call_function_single - Run a function on another CPU
675 * @func: The function to run. This must be fast and non-blocking.
676 * @info: An arbitrary pointer to pass to the function.
677 * @nonatomic: Currently unused.
678 * @wait: If true, wait until function has completed on other CPUs.
679 *
680 * Retrurns 0 on success, else a negative status code.
681 *
682 * Does not return until the remote CPU is nearly ready to execute <func>
683 * or is or has executed.
684 */
685
686int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
687 int nonatomic, int wait)
688{
689 /* prevent preemption and reschedule on another processor */
690 int me = get_cpu();
691 if (cpu == me) {
692 WARN_ON(1);
693 put_cpu();
694 return -EBUSY;
695 }
696 spin_lock_bh(&call_lock);
697 __smp_call_function_single(cpu, func, info, nonatomic, wait);
698 spin_unlock_bh(&call_lock);
699 put_cpu();
700 return 0;
701}
702EXPORT_SYMBOL(smp_call_function_single);
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index f948419c888a..020d873b7d21 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -177,6 +177,9 @@ static void __devinit smp_store_cpu_info(int id)
177 */ 177 */
178 if ((c->x86_vendor == X86_VENDOR_AMD) && (c->x86 == 6)) { 178 if ((c->x86_vendor == X86_VENDOR_AMD) && (c->x86 == 6)) {
179 179
180 if (num_possible_cpus() == 1)
181 goto valid_k7;
182
180 /* Athlon 660/661 is valid. */ 183 /* Athlon 660/661 is valid. */
181 if ((c->x86_model==6) && ((c->x86_mask==0) || (c->x86_mask==1))) 184 if ((c->x86_model==6) && ((c->x86_mask==0) || (c->x86_mask==1)))
182 goto valid_k7; 185 goto valid_k7;
@@ -642,9 +645,13 @@ static void map_cpu_to_logical_apicid(void)
642{ 645{
643 int cpu = smp_processor_id(); 646 int cpu = smp_processor_id();
644 int apicid = logical_smp_processor_id(); 647 int apicid = logical_smp_processor_id();
648 int node = apicid_to_node(apicid);
649
650 if (!node_online(node))
651 node = first_online_node;
645 652
646 cpu_2_logical_apicid[cpu] = apicid; 653 cpu_2_logical_apicid[cpu] = apicid;
647 map_cpu_to_node(cpu, apicid_to_node(apicid)); 654 map_cpu_to_node(cpu, node);
648} 655}
649 656
650static void unmap_cpu_to_logical_apicid(int cpu) 657static void unmap_cpu_to_logical_apicid(int cpu)
@@ -1372,7 +1379,8 @@ int __cpu_disable(void)
1372 */ 1379 */
1373 if (cpu == 0) 1380 if (cpu == 0)
1374 return -EBUSY; 1381 return -EBUSY;
1375 1382 if (nmi_watchdog == NMI_LOCAL_APIC)
1383 stop_apic_nmi_watchdog(NULL);
1376 clear_local_APIC(); 1384 clear_local_APIC();
1377 /* Allow any queued timer interrupts to get serviced */ 1385 /* Allow any queued timer interrupts to get serviced */
1378 local_irq_enable(); 1386 local_irq_enable();
@@ -1486,3 +1494,16 @@ void __init smp_intr_init(void)
1486 /* IPI for generic function call */ 1494 /* IPI for generic function call */
1487 set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); 1495 set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
1488} 1496}
1497
1498/*
1499 * If the BIOS enumerates physical processors before logical,
1500 * maxcpus=N at enumeration-time can be used to disable HT.
1501 */
1502static int __init parse_maxcpus(char *arg)
1503{
1504 extern unsigned int maxcpus;
1505
1506 maxcpus = simple_strtoul(arg, NULL, 0);
1507 return 0;
1508}
1509early_param("maxcpus", parse_maxcpus);
diff --git a/arch/i386/kernel/srat.c b/arch/i386/kernel/srat.c
index b1809c9a0899..32413122c4c2 100644
--- a/arch/i386/kernel/srat.c
+++ b/arch/i386/kernel/srat.c
@@ -42,7 +42,7 @@
42#define PXM_BITMAP_LEN (MAX_PXM_DOMAINS / 8) 42#define PXM_BITMAP_LEN (MAX_PXM_DOMAINS / 8)
43static u8 pxm_bitmap[PXM_BITMAP_LEN]; /* bitmap of proximity domains */ 43static u8 pxm_bitmap[PXM_BITMAP_LEN]; /* bitmap of proximity domains */
44 44
45#define MAX_CHUNKS_PER_NODE 4 45#define MAX_CHUNKS_PER_NODE 3
46#define MAXCHUNKS (MAX_CHUNKS_PER_NODE * MAX_NUMNODES) 46#define MAXCHUNKS (MAX_CHUNKS_PER_NODE * MAX_NUMNODES)
47struct node_memory_chunk_s { 47struct node_memory_chunk_s {
48 unsigned long start_pfn; 48 unsigned long start_pfn;
@@ -54,8 +54,6 @@ struct node_memory_chunk_s {
54static struct node_memory_chunk_s node_memory_chunk[MAXCHUNKS]; 54static struct node_memory_chunk_s node_memory_chunk[MAXCHUNKS];
55 55
56static int num_memory_chunks; /* total number of memory chunks */ 56static int num_memory_chunks; /* total number of memory chunks */
57static int zholes_size_init;
58static unsigned long zholes_size[MAX_NUMNODES * MAX_NR_ZONES];
59 57
60extern void * boot_ioremap(unsigned long, unsigned long); 58extern void * boot_ioremap(unsigned long, unsigned long);
61 59
@@ -135,50 +133,6 @@ static void __init parse_memory_affinity_structure (char *sratp)
135 "enabled and removable" : "enabled" ) ); 133 "enabled and removable" : "enabled" ) );
136} 134}
137 135
138#if MAX_NR_ZONES != 4
139#error "MAX_NR_ZONES != 4, chunk_to_zone requires review"
140#endif
141/* Take a chunk of pages from page frame cstart to cend and count the number
142 * of pages in each zone, returned via zones[].
143 */
144static __init void chunk_to_zones(unsigned long cstart, unsigned long cend,
145 unsigned long *zones)
146{
147 unsigned long max_dma;
148 extern unsigned long max_low_pfn;
149
150 int z;
151 unsigned long rend;
152
153 /* FIXME: MAX_DMA_ADDRESS and max_low_pfn are trying to provide
154 * similarly scoped information and should be handled in a consistant
155 * manner.
156 */
157 max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
158
159 /* Split the hole into the zones in which it falls. Repeatedly
160 * take the segment in which the remaining hole starts, round it
161 * to the end of that zone.
162 */
163 memset(zones, 0, MAX_NR_ZONES * sizeof(long));
164 while (cstart < cend) {
165 if (cstart < max_dma) {
166 z = ZONE_DMA;
167 rend = (cend < max_dma)? cend : max_dma;
168
169 } else if (cstart < max_low_pfn) {
170 z = ZONE_NORMAL;
171 rend = (cend < max_low_pfn)? cend : max_low_pfn;
172
173 } else {
174 z = ZONE_HIGHMEM;
175 rend = cend;
176 }
177 zones[z] += rend - cstart;
178 cstart = rend;
179 }
180}
181
182/* 136/*
183 * The SRAT table always lists ascending addresses, so can always 137 * The SRAT table always lists ascending addresses, so can always
184 * assume that the first "start" address that you see is the real 138 * assume that the first "start" address that you see is the real
@@ -223,7 +177,6 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp)
223 177
224 memset(pxm_bitmap, 0, sizeof(pxm_bitmap)); /* init proximity domain bitmap */ 178 memset(pxm_bitmap, 0, sizeof(pxm_bitmap)); /* init proximity domain bitmap */
225 memset(node_memory_chunk, 0, sizeof(node_memory_chunk)); 179 memset(node_memory_chunk, 0, sizeof(node_memory_chunk));
226 memset(zholes_size, 0, sizeof(zholes_size));
227 180
228 num_memory_chunks = 0; 181 num_memory_chunks = 0;
229 while (p < end) { 182 while (p < end) {
@@ -287,6 +240,7 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp)
287 printk("chunk %d nid %d start_pfn %08lx end_pfn %08lx\n", 240 printk("chunk %d nid %d start_pfn %08lx end_pfn %08lx\n",
288 j, chunk->nid, chunk->start_pfn, chunk->end_pfn); 241 j, chunk->nid, chunk->start_pfn, chunk->end_pfn);
289 node_read_chunk(chunk->nid, chunk); 242 node_read_chunk(chunk->nid, chunk);
243 add_active_range(chunk->nid, chunk->start_pfn, chunk->end_pfn);
290 } 244 }
291 245
292 for_each_online_node(nid) { 246 for_each_online_node(nid) {
@@ -395,57 +349,7 @@ int __init get_memcfg_from_srat(void)
395 return acpi20_parse_srat((struct acpi_table_srat *)header); 349 return acpi20_parse_srat((struct acpi_table_srat *)header);
396 } 350 }
397out_err: 351out_err:
352 remove_all_active_ranges();
398 printk("failed to get NUMA memory information from SRAT table\n"); 353 printk("failed to get NUMA memory information from SRAT table\n");
399 return 0; 354 return 0;
400} 355}
401
402/* For each node run the memory list to determine whether there are
403 * any memory holes. For each hole determine which ZONE they fall
404 * into.
405 *
406 * NOTE#1: this requires knowledge of the zone boundries and so
407 * _cannot_ be performed before those are calculated in setup_memory.
408 *
409 * NOTE#2: we rely on the fact that the memory chunks are ordered by
410 * start pfn number during setup.
411 */
412static void __init get_zholes_init(void)
413{
414 int nid;
415 int c;
416 int first;
417 unsigned long end = 0;
418
419 for_each_online_node(nid) {
420 first = 1;
421 for (c = 0; c < num_memory_chunks; c++){
422 if (node_memory_chunk[c].nid == nid) {
423 if (first) {
424 end = node_memory_chunk[c].end_pfn;
425 first = 0;
426
427 } else {
428 /* Record any gap between this chunk
429 * and the previous chunk on this node
430 * against the zones it spans.
431 */
432 chunk_to_zones(end,
433 node_memory_chunk[c].start_pfn,
434 &zholes_size[nid * MAX_NR_ZONES]);
435 }
436 }
437 }
438 }
439}
440
441unsigned long * __init get_zholes_size(int nid)
442{
443 if (!zholes_size_init) {
444 zholes_size_init++;
445 get_zholes_init();
446 }
447 if (nid >= MAX_NUMNODES || !node_online(nid))
448 printk("%s: nid = %d is invalid/offline. num_online_nodes = %d",
449 __FUNCTION__, nid, num_online_nodes());
450 return &zholes_size[nid * MAX_NR_ZONES];
451}
diff --git a/arch/i386/kernel/stacktrace.c b/arch/i386/kernel/stacktrace.c
deleted file mode 100644
index e62a037ab399..000000000000
--- a/arch/i386/kernel/stacktrace.c
+++ /dev/null
@@ -1,98 +0,0 @@
1/*
2 * arch/i386/kernel/stacktrace.c
3 *
4 * Stack trace management functions
5 *
6 * Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
7 */
8#include <linux/sched.h>
9#include <linux/stacktrace.h>
10
11static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
12{
13 return p > (void *)tinfo &&
14 p < (void *)tinfo + THREAD_SIZE - 3;
15}
16
17/*
18 * Save stack-backtrace addresses into a stack_trace buffer:
19 */
20static inline unsigned long
21save_context_stack(struct stack_trace *trace, unsigned int skip,
22 struct thread_info *tinfo, unsigned long *stack,
23 unsigned long ebp)
24{
25 unsigned long addr;
26
27#ifdef CONFIG_FRAME_POINTER
28 while (valid_stack_ptr(tinfo, (void *)ebp)) {
29 addr = *(unsigned long *)(ebp + 4);
30 if (!skip)
31 trace->entries[trace->nr_entries++] = addr;
32 else
33 skip--;
34 if (trace->nr_entries >= trace->max_entries)
35 break;
36 /*
37 * break out of recursive entries (such as
38 * end_of_stack_stop_unwind_function):
39 */
40 if (ebp == *(unsigned long *)ebp)
41 break;
42
43 ebp = *(unsigned long *)ebp;
44 }
45#else
46 while (valid_stack_ptr(tinfo, stack)) {
47 addr = *stack++;
48 if (__kernel_text_address(addr)) {
49 if (!skip)
50 trace->entries[trace->nr_entries++] = addr;
51 else
52 skip--;
53 if (trace->nr_entries >= trace->max_entries)
54 break;
55 }
56 }
57#endif
58
59 return ebp;
60}
61
62/*
63 * Save stack-backtrace addresses into a stack_trace buffer.
64 * If all_contexts is set, all contexts (hardirq, softirq and process)
65 * are saved. If not set then only the current context is saved.
66 */
67void save_stack_trace(struct stack_trace *trace,
68 struct task_struct *task, int all_contexts,
69 unsigned int skip)
70{
71 unsigned long ebp;
72 unsigned long *stack = &ebp;
73
74 WARN_ON(trace->nr_entries || !trace->max_entries);
75
76 if (!task || task == current) {
77 /* Grab ebp right from our regs: */
78 asm ("movl %%ebp, %0" : "=r" (ebp));
79 } else {
80 /* ebp is the last reg pushed by switch_to(): */
81 ebp = *(unsigned long *) task->thread.esp;
82 }
83
84 while (1) {
85 struct thread_info *context = (struct thread_info *)
86 ((unsigned long)stack & (~(THREAD_SIZE - 1)));
87
88 ebp = save_context_stack(trace, skip, context, stack, ebp);
89 stack = (unsigned long *)context->previous_esp;
90 if (!all_contexts || !stack ||
91 trace->nr_entries >= trace->max_entries)
92 break;
93 trace->entries[trace->nr_entries++] = ULONG_MAX;
94 if (trace->nr_entries >= trace->max_entries)
95 break;
96 }
97}
98
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S
index dd63d4775398..7e639f78b0b9 100644
--- a/arch/i386/kernel/syscall_table.S
+++ b/arch/i386/kernel/syscall_table.S
@@ -317,3 +317,4 @@ ENTRY(sys_call_table)
317 .long sys_tee /* 315 */ 317 .long sys_tee /* 315 */
318 .long sys_vmsplice 318 .long sys_vmsplice
319 .long sys_move_pages 319 .long sys_move_pages
320 .long sys_getcpu
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index edd00f6cee37..86944acfb647 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -130,18 +130,33 @@ static int set_rtc_mmss(unsigned long nowtime)
130 130
131int timer_ack; 131int timer_ack;
132 132
133#if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER)
134unsigned long profile_pc(struct pt_regs *regs) 133unsigned long profile_pc(struct pt_regs *regs)
135{ 134{
136 unsigned long pc = instruction_pointer(regs); 135 unsigned long pc = instruction_pointer(regs);
137 136
138 if (!user_mode_vm(regs) && in_lock_functions(pc)) 137#ifdef CONFIG_SMP
138 if (!user_mode_vm(regs) && in_lock_functions(pc)) {
139#ifdef CONFIG_FRAME_POINTER
139 return *(unsigned long *)(regs->ebp + 4); 140 return *(unsigned long *)(regs->ebp + 4);
140 141#else
142 unsigned long *sp;
143 if ((regs->xcs & 3) == 0)
144 sp = (unsigned long *)&regs->esp;
145 else
146 sp = (unsigned long *)regs->esp;
147 /* Return address is either directly at stack pointer
148 or above a saved eflags. Eflags has bits 22-31 zero,
149 kernel addresses don't. */
150 if (sp[0] >> 22)
151 return sp[0];
152 if (sp[1] >> 22)
153 return sp[1];
154#endif
155 }
156#endif
141 return pc; 157 return pc;
142} 158}
143EXPORT_SYMBOL(profile_pc); 159EXPORT_SYMBOL(profile_pc);
144#endif
145 160
146/* 161/*
147 * This is the same as the above, except we _also_ save the current 162 * This is the same as the above, except we _also_ save the current
@@ -270,16 +285,19 @@ void notify_arch_cmos_timer(void)
270 mod_timer(&sync_cmos_timer, jiffies + 1); 285 mod_timer(&sync_cmos_timer, jiffies + 1);
271} 286}
272 287
273static long clock_cmos_diff, sleep_start; 288static long clock_cmos_diff;
289static unsigned long sleep_start;
274 290
275static int timer_suspend(struct sys_device *dev, pm_message_t state) 291static int timer_suspend(struct sys_device *dev, pm_message_t state)
276{ 292{
277 /* 293 /*
278 * Estimate time zone so that set_time can update the clock 294 * Estimate time zone so that set_time can update the clock
279 */ 295 */
280 clock_cmos_diff = -get_cmos_time(); 296 unsigned long ctime = get_cmos_time();
297
298 clock_cmos_diff = -ctime;
281 clock_cmos_diff += get_seconds(); 299 clock_cmos_diff += get_seconds();
282 sleep_start = get_cmos_time(); 300 sleep_start = ctime;
283 return 0; 301 return 0;
284} 302}
285 303
@@ -287,18 +305,29 @@ static int timer_resume(struct sys_device *dev)
287{ 305{
288 unsigned long flags; 306 unsigned long flags;
289 unsigned long sec; 307 unsigned long sec;
290 unsigned long sleep_length; 308 unsigned long ctime = get_cmos_time();
291 309 long sleep_length = (ctime - sleep_start) * HZ;
310 struct timespec ts;
311
312 if (sleep_length < 0) {
313 printk(KERN_WARNING "CMOS clock skew detected in timer resume!\n");
314 /* The time after the resume must not be earlier than the time
315 * before the suspend or some nasty things will happen
316 */
317 sleep_length = 0;
318 ctime = sleep_start;
319 }
292#ifdef CONFIG_HPET_TIMER 320#ifdef CONFIG_HPET_TIMER
293 if (is_hpet_enabled()) 321 if (is_hpet_enabled())
294 hpet_reenable(); 322 hpet_reenable();
295#endif 323#endif
296 setup_pit_timer(); 324 setup_pit_timer();
297 sec = get_cmos_time() + clock_cmos_diff; 325
298 sleep_length = (get_cmos_time() - sleep_start) * HZ; 326 sec = ctime + clock_cmos_diff;
327 ts.tv_sec = sec;
328 ts.tv_nsec = 0;
329 do_settimeofday(&ts);
299 write_seqlock_irqsave(&xtime_lock, flags); 330 write_seqlock_irqsave(&xtime_lock, flags);
300 xtime.tv_sec = sec;
301 xtime.tv_nsec = 0;
302 jiffies_64 += sleep_length; 331 jiffies_64 += sleep_length;
303 wall_jiffies += sleep_length; 332 wall_jiffies += sleep_length;
304 write_sequnlock_irqrestore(&xtime_lock, flags); 333 write_sequnlock_irqrestore(&xtime_lock, flags);
@@ -334,10 +363,11 @@ extern void (*late_time_init)(void);
334/* Duplicate of time_init() below, with hpet_enable part added */ 363/* Duplicate of time_init() below, with hpet_enable part added */
335static void __init hpet_time_init(void) 364static void __init hpet_time_init(void)
336{ 365{
337 xtime.tv_sec = get_cmos_time(); 366 struct timespec ts;
338 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); 367 ts.tv_sec = get_cmos_time();
339 set_normalized_timespec(&wall_to_monotonic, 368 ts.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
340 -xtime.tv_sec, -xtime.tv_nsec); 369
370 do_settimeofday(&ts);
341 371
342 if ((hpet_enable() >= 0) && hpet_use_timer) { 372 if ((hpet_enable() >= 0) && hpet_use_timer) {
343 printk("Using HPET for base-timer\n"); 373 printk("Using HPET for base-timer\n");
@@ -349,6 +379,7 @@ static void __init hpet_time_init(void)
349 379
350void __init time_init(void) 380void __init time_init(void)
351{ 381{
382 struct timespec ts;
352#ifdef CONFIG_HPET_TIMER 383#ifdef CONFIG_HPET_TIMER
353 if (is_hpet_capable()) { 384 if (is_hpet_capable()) {
354 /* 385 /*
@@ -359,10 +390,10 @@ void __init time_init(void)
359 return; 390 return;
360 } 391 }
361#endif 392#endif
362 xtime.tv_sec = get_cmos_time(); 393 ts.tv_sec = get_cmos_time();
363 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); 394 ts.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
364 set_normalized_timespec(&wall_to_monotonic, 395
365 -xtime.tv_sec, -xtime.tv_nsec); 396 do_settimeofday(&ts);
366 397
367 time_init_hook(); 398 time_init_hook();
368} 399}
diff --git a/arch/i386/kernel/time_hpet.c b/arch/i386/kernel/time_hpet.c
index 14a1376fedd1..6bf14a4e995e 100644
--- a/arch/i386/kernel/time_hpet.c
+++ b/arch/i386/kernel/time_hpet.c
@@ -301,23 +301,25 @@ int hpet_rtc_timer_init(void)
301 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ; 301 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
302 302
303 local_irq_save(flags); 303 local_irq_save(flags);
304
304 cnt = hpet_readl(HPET_COUNTER); 305 cnt = hpet_readl(HPET_COUNTER);
305 cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq); 306 cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
306 hpet_writel(cnt, HPET_T1_CMP); 307 hpet_writel(cnt, HPET_T1_CMP);
307 hpet_t1_cmp = cnt; 308 hpet_t1_cmp = cnt;
308 local_irq_restore(flags);
309 309
310 cfg = hpet_readl(HPET_T1_CFG); 310 cfg = hpet_readl(HPET_T1_CFG);
311 cfg &= ~HPET_TN_PERIODIC; 311 cfg &= ~HPET_TN_PERIODIC;
312 cfg |= HPET_TN_ENABLE | HPET_TN_32BIT; 312 cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
313 hpet_writel(cfg, HPET_T1_CFG); 313 hpet_writel(cfg, HPET_T1_CFG);
314 314
315 local_irq_restore(flags);
316
315 return 1; 317 return 1;
316} 318}
317 319
318static void hpet_rtc_timer_reinit(void) 320static void hpet_rtc_timer_reinit(void)
319{ 321{
320 unsigned int cfg, cnt; 322 unsigned int cfg, cnt, ticks_per_int, lost_ints;
321 323
322 if (unlikely(!(PIE_on | AIE_on | UIE_on))) { 324 if (unlikely(!(PIE_on | AIE_on | UIE_on))) {
323 cfg = hpet_readl(HPET_T1_CFG); 325 cfg = hpet_readl(HPET_T1_CFG);
@@ -332,10 +334,33 @@ static void hpet_rtc_timer_reinit(void)
332 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ; 334 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
333 335
334 /* It is more accurate to use the comparator value than current count.*/ 336 /* It is more accurate to use the comparator value than current count.*/
335 cnt = hpet_t1_cmp; 337 ticks_per_int = hpet_tick * HZ / hpet_rtc_int_freq;
336 cnt += hpet_tick*HZ/hpet_rtc_int_freq; 338 hpet_t1_cmp += ticks_per_int;
337 hpet_writel(cnt, HPET_T1_CMP); 339 hpet_writel(hpet_t1_cmp, HPET_T1_CMP);
338 hpet_t1_cmp = cnt; 340
341 /*
342 * If the interrupt handler was delayed too long, the write above tries
343 * to schedule the next interrupt in the past and the hardware would
344 * not interrupt until the counter had wrapped around.
345 * So we have to check that the comparator wasn't set to a past time.
346 */
347 cnt = hpet_readl(HPET_COUNTER);
348 if (unlikely((int)(cnt - hpet_t1_cmp) > 0)) {
349 lost_ints = (cnt - hpet_t1_cmp) / ticks_per_int + 1;
350 /* Make sure that, even with the time needed to execute
351 * this code, the next scheduled interrupt has been moved
352 * back to the future: */
353 lost_ints++;
354
355 hpet_t1_cmp += lost_ints * ticks_per_int;
356 hpet_writel(hpet_t1_cmp, HPET_T1_CMP);
357
358 if (PIE_on)
359 PIE_count += lost_ints;
360
361 printk(KERN_WARNING "rtc: lost some interrupts at %ldHz.\n",
362 hpet_rtc_int_freq);
363 }
339} 364}
340 365
341/* 366/*
diff --git a/arch/i386/kernel/topology.c b/arch/i386/kernel/topology.c
index e2e281d4bcc8..07d6da36a825 100644
--- a/arch/i386/kernel/topology.c
+++ b/arch/i386/kernel/topology.c
@@ -28,6 +28,7 @@
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/smp.h> 29#include <linux/smp.h>
30#include <linux/nodemask.h> 30#include <linux/nodemask.h>
31#include <linux/mmzone.h>
31#include <asm/cpu.h> 32#include <asm/cpu.h>
32 33
33static struct i386_cpu cpu_devices[NR_CPUS]; 34static struct i386_cpu cpu_devices[NR_CPUS];
@@ -55,34 +56,18 @@ EXPORT_SYMBOL(arch_register_cpu);
55EXPORT_SYMBOL(arch_unregister_cpu); 56EXPORT_SYMBOL(arch_unregister_cpu);
56#endif /*CONFIG_HOTPLUG_CPU*/ 57#endif /*CONFIG_HOTPLUG_CPU*/
57 58
58
59
60#ifdef CONFIG_NUMA
61#include <linux/mmzone.h>
62
63static int __init topology_init(void) 59static int __init topology_init(void)
64{ 60{
65 int i; 61 int i;
66 62
63#ifdef CONFIG_NUMA
67 for_each_online_node(i) 64 for_each_online_node(i)
68 register_one_node(i); 65 register_one_node(i);
66#endif /* CONFIG_NUMA */
69 67
70 for_each_present_cpu(i) 68 for_each_present_cpu(i)
71 arch_register_cpu(i); 69 arch_register_cpu(i);
72 return 0; 70 return 0;
73} 71}
74 72
75#else /* !CONFIG_NUMA */
76
77static int __init topology_init(void)
78{
79 int i;
80
81 for_each_present_cpu(i)
82 arch_register_cpu(i);
83 return 0;
84}
85
86#endif /* CONFIG_NUMA */
87
88subsys_initcall(topology_init); 73subsys_initcall(topology_init);
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 7e9edafffd8a..a13037fe0ee3 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -28,6 +28,7 @@
28#include <linux/kprobes.h> 28#include <linux/kprobes.h>
29#include <linux/kexec.h> 29#include <linux/kexec.h>
30#include <linux/unwind.h> 30#include <linux/unwind.h>
31#include <linux/uaccess.h>
31 32
32#ifdef CONFIG_EISA 33#ifdef CONFIG_EISA
33#include <linux/ioport.h> 34#include <linux/ioport.h>
@@ -40,7 +41,6 @@
40 41
41#include <asm/processor.h> 42#include <asm/processor.h>
42#include <asm/system.h> 43#include <asm/system.h>
43#include <asm/uaccess.h>
44#include <asm/io.h> 44#include <asm/io.h>
45#include <asm/atomic.h> 45#include <asm/atomic.h>
46#include <asm/debugreg.h> 46#include <asm/debugreg.h>
@@ -51,6 +51,7 @@
51#include <asm/smp.h> 51#include <asm/smp.h>
52#include <asm/arch_hooks.h> 52#include <asm/arch_hooks.h>
53#include <asm/kdebug.h> 53#include <asm/kdebug.h>
54#include <asm/stacktrace.h>
54 55
55#include <linux/module.h> 56#include <linux/module.h>
56 57
@@ -118,26 +119,16 @@ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
118 p < (void *)tinfo + THREAD_SIZE - 3; 119 p < (void *)tinfo + THREAD_SIZE - 3;
119} 120}
120 121
121/*
122 * Print one address/symbol entries per line.
123 */
124static inline void print_addr_and_symbol(unsigned long addr, char *log_lvl)
125{
126 printk(" [<%08lx>] ", addr);
127
128 print_symbol("%s\n", addr);
129}
130
131static inline unsigned long print_context_stack(struct thread_info *tinfo, 122static inline unsigned long print_context_stack(struct thread_info *tinfo,
132 unsigned long *stack, unsigned long ebp, 123 unsigned long *stack, unsigned long ebp,
133 char *log_lvl) 124 struct stacktrace_ops *ops, void *data)
134{ 125{
135 unsigned long addr; 126 unsigned long addr;
136 127
137#ifdef CONFIG_FRAME_POINTER 128#ifdef CONFIG_FRAME_POINTER
138 while (valid_stack_ptr(tinfo, (void *)ebp)) { 129 while (valid_stack_ptr(tinfo, (void *)ebp)) {
139 addr = *(unsigned long *)(ebp + 4); 130 addr = *(unsigned long *)(ebp + 4);
140 print_addr_and_symbol(addr, log_lvl); 131 ops->address(data, addr);
141 /* 132 /*
142 * break out of recursive entries (such as 133 * break out of recursive entries (such as
143 * end_of_stack_stop_unwind_function): 134 * end_of_stack_stop_unwind_function):
@@ -150,30 +141,37 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo,
150 while (valid_stack_ptr(tinfo, stack)) { 141 while (valid_stack_ptr(tinfo, stack)) {
151 addr = *stack++; 142 addr = *stack++;
152 if (__kernel_text_address(addr)) 143 if (__kernel_text_address(addr))
153 print_addr_and_symbol(addr, log_lvl); 144 ops->address(data, addr);
154 } 145 }
155#endif 146#endif
156 return ebp; 147 return ebp;
157} 148}
158 149
150struct ops_and_data {
151 struct stacktrace_ops *ops;
152 void *data;
153};
154
159static asmlinkage int 155static asmlinkage int
160show_trace_unwind(struct unwind_frame_info *info, void *log_lvl) 156dump_trace_unwind(struct unwind_frame_info *info, void *data)
161{ 157{
158 struct ops_and_data *oad = (struct ops_and_data *)data;
162 int n = 0; 159 int n = 0;
163 160
164 while (unwind(info) == 0 && UNW_PC(info)) { 161 while (unwind(info) == 0 && UNW_PC(info)) {
165 n++; 162 n++;
166 print_addr_and_symbol(UNW_PC(info), log_lvl); 163 oad->ops->address(oad->data, UNW_PC(info));
167 if (arch_unw_user_mode(info)) 164 if (arch_unw_user_mode(info))
168 break; 165 break;
169 } 166 }
170 return n; 167 return n;
171} 168}
172 169
173static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, 170void dump_trace(struct task_struct *task, struct pt_regs *regs,
174 unsigned long *stack, char *log_lvl) 171 unsigned long *stack,
172 struct stacktrace_ops *ops, void *data)
175{ 173{
176 unsigned long ebp; 174 unsigned long ebp = 0;
177 175
178 if (!task) 176 if (!task)
179 task = current; 177 task = current;
@@ -181,54 +179,116 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
181 if (call_trace >= 0) { 179 if (call_trace >= 0) {
182 int unw_ret = 0; 180 int unw_ret = 0;
183 struct unwind_frame_info info; 181 struct unwind_frame_info info;
182 struct ops_and_data oad = { .ops = ops, .data = data };
184 183
185 if (regs) { 184 if (regs) {
186 if (unwind_init_frame_info(&info, task, regs) == 0) 185 if (unwind_init_frame_info(&info, task, regs) == 0)
187 unw_ret = show_trace_unwind(&info, log_lvl); 186 unw_ret = dump_trace_unwind(&info, &oad);
188 } else if (task == current) 187 } else if (task == current)
189 unw_ret = unwind_init_running(&info, show_trace_unwind, log_lvl); 188 unw_ret = unwind_init_running(&info, dump_trace_unwind, &oad);
190 else { 189 else {
191 if (unwind_init_blocked(&info, task) == 0) 190 if (unwind_init_blocked(&info, task) == 0)
192 unw_ret = show_trace_unwind(&info, log_lvl); 191 unw_ret = dump_trace_unwind(&info, &oad);
193 } 192 }
194 if (unw_ret > 0) { 193 if (unw_ret > 0) {
195 if (call_trace == 1 && !arch_unw_user_mode(&info)) { 194 if (call_trace == 1 && !arch_unw_user_mode(&info)) {
196 print_symbol("DWARF2 unwinder stuck at %s\n", 195 ops->warning_symbol(data, "DWARF2 unwinder stuck at %s\n",
197 UNW_PC(&info)); 196 UNW_PC(&info));
198 if (UNW_SP(&info) >= PAGE_OFFSET) { 197 if (UNW_SP(&info) >= PAGE_OFFSET) {
199 printk("Leftover inexact backtrace:\n"); 198 ops->warning(data, "Leftover inexact backtrace:\n");
200 stack = (void *)UNW_SP(&info); 199 stack = (void *)UNW_SP(&info);
200 if (!stack)
201 return;
202 ebp = UNW_FP(&info);
201 } else 203 } else
202 printk("Full inexact backtrace again:\n"); 204 ops->warning(data, "Full inexact backtrace again:\n");
203 } else if (call_trace >= 1) 205 } else if (call_trace >= 1)
204 return; 206 return;
205 else 207 else
206 printk("Full inexact backtrace again:\n"); 208 ops->warning(data, "Full inexact backtrace again:\n");
207 } else 209 } else
208 printk("Inexact backtrace:\n"); 210 ops->warning(data, "Inexact backtrace:\n");
211 }
212 if (!stack) {
213 unsigned long dummy;
214 stack = &dummy;
215 if (task && task != current)
216 stack = (unsigned long *)task->thread.esp;
209 } 217 }
210 218
211 if (task == current) { 219#ifdef CONFIG_FRAME_POINTER
212 /* Grab ebp right from our regs */ 220 if (!ebp) {
213 asm ("movl %%ebp, %0" : "=r" (ebp) : ); 221 if (task == current) {
214 } else { 222 /* Grab ebp right from our regs */
215 /* ebp is the last reg pushed by switch_to */ 223 asm ("movl %%ebp, %0" : "=r" (ebp) : );
216 ebp = *(unsigned long *) task->thread.esp; 224 } else {
225 /* ebp is the last reg pushed by switch_to */
226 ebp = *(unsigned long *) task->thread.esp;
227 }
217 } 228 }
229#endif
218 230
219 while (1) { 231 while (1) {
220 struct thread_info *context; 232 struct thread_info *context;
221 context = (struct thread_info *) 233 context = (struct thread_info *)
222 ((unsigned long)stack & (~(THREAD_SIZE - 1))); 234 ((unsigned long)stack & (~(THREAD_SIZE - 1)));
223 ebp = print_context_stack(context, stack, ebp, log_lvl); 235 ebp = print_context_stack(context, stack, ebp, ops, data);
236 /* Should be after the line below, but somewhere
237 in early boot context comes out corrupted and we
238 can't reference it -AK */
239 if (ops->stack(data, "IRQ") < 0)
240 break;
224 stack = (unsigned long*)context->previous_esp; 241 stack = (unsigned long*)context->previous_esp;
225 if (!stack) 242 if (!stack)
226 break; 243 break;
227 printk("%s =======================\n", log_lvl);
228 } 244 }
229} 245}
246EXPORT_SYMBOL(dump_trace);
247
248static void
249print_trace_warning_symbol(void *data, char *msg, unsigned long symbol)
250{
251 printk(data);
252 print_symbol(msg, symbol);
253 printk("\n");
254}
255
256static void print_trace_warning(void *data, char *msg)
257{
258 printk("%s%s\n", (char *)data, msg);
259}
260
261static int print_trace_stack(void *data, char *name)
262{
263 return 0;
264}
265
266/*
267 * Print one address/symbol entries per line.
268 */
269static void print_trace_address(void *data, unsigned long addr)
270{
271 printk("%s [<%08lx>] ", (char *)data, addr);
272 print_symbol("%s\n", addr);
273}
274
275static struct stacktrace_ops print_trace_ops = {
276 .warning = print_trace_warning,
277 .warning_symbol = print_trace_warning_symbol,
278 .stack = print_trace_stack,
279 .address = print_trace_address,
280};
281
282static void
283show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
284 unsigned long * stack, char *log_lvl)
285{
286 dump_trace(task, regs, stack, &print_trace_ops, log_lvl);
287 printk("%s =======================\n", log_lvl);
288}
230 289
231void show_trace(struct task_struct *task, struct pt_regs *regs, unsigned long * stack) 290void show_trace(struct task_struct *task, struct pt_regs *regs,
291 unsigned long * stack)
232{ 292{
233 show_trace_log_lvl(task, regs, stack, ""); 293 show_trace_log_lvl(task, regs, stack, "");
234} 294}
@@ -291,8 +351,9 @@ void show_registers(struct pt_regs *regs)
291 ss = regs->xss & 0xffff; 351 ss = regs->xss & 0xffff;
292 } 352 }
293 print_modules(); 353 print_modules();
294 printk(KERN_EMERG "CPU: %d\nEIP: %04x:[<%08lx>] %s VLI\n" 354 printk(KERN_EMERG "CPU: %d\n"
295 "EFLAGS: %08lx (%s %.*s) \n", 355 KERN_EMERG "EIP: %04x:[<%08lx>] %s VLI\n"
356 KERN_EMERG "EFLAGS: %08lx (%s %.*s)\n",
296 smp_processor_id(), 0xffff & regs->xcs, regs->eip, 357 smp_processor_id(), 0xffff & regs->xcs, regs->eip,
297 print_tainted(), regs->eflags, system_utsname.release, 358 print_tainted(), regs->eflags, system_utsname.release,
298 (int)strcspn(system_utsname.version, " "), 359 (int)strcspn(system_utsname.version, " "),
@@ -313,6 +374,8 @@ void show_registers(struct pt_regs *regs)
313 */ 374 */
314 if (in_kernel) { 375 if (in_kernel) {
315 u8 __user *eip; 376 u8 __user *eip;
377 int code_bytes = 64;
378 unsigned char c;
316 379
317 printk("\n" KERN_EMERG "Stack: "); 380 printk("\n" KERN_EMERG "Stack: ");
318 show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG); 381 show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG);
@@ -320,9 +383,12 @@ void show_registers(struct pt_regs *regs)
320 printk(KERN_EMERG "Code: "); 383 printk(KERN_EMERG "Code: ");
321 384
322 eip = (u8 __user *)regs->eip - 43; 385 eip = (u8 __user *)regs->eip - 43;
323 for (i = 0; i < 64; i++, eip++) { 386 if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) {
324 unsigned char c; 387 /* try starting at EIP */
325 388 eip = (u8 __user *)regs->eip;
389 code_bytes = 32;
390 }
391 for (i = 0; i < code_bytes; i++, eip++) {
326 if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) { 392 if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) {
327 printk(" Bad EIP value."); 393 printk(" Bad EIP value.");
328 break; 394 break;
@@ -343,7 +409,7 @@ static void handle_BUG(struct pt_regs *regs)
343 409
344 if (eip < PAGE_OFFSET) 410 if (eip < PAGE_OFFSET)
345 return; 411 return;
346 if (__get_user(ud2, (unsigned short __user *)eip)) 412 if (probe_kernel_address((unsigned short __user *)eip, ud2))
347 return; 413 return;
348 if (ud2 != 0x0b0f) 414 if (ud2 != 0x0b0f)
349 return; 415 return;
@@ -356,7 +422,8 @@ static void handle_BUG(struct pt_regs *regs)
356 char *file; 422 char *file;
357 char c; 423 char c;
358 424
359 if (__get_user(line, (unsigned short __user *)(eip + 2))) 425 if (probe_kernel_address((unsigned short __user *)(eip + 2),
426 line))
360 break; 427 break;
361 if (__get_user(file, (char * __user *)(eip + 4)) || 428 if (__get_user(file, (char * __user *)(eip + 4)) ||
362 (unsigned long)file < PAGE_OFFSET || __get_user(c, file)) 429 (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
@@ -629,18 +696,24 @@ gp_in_kernel:
629 } 696 }
630} 697}
631 698
632static void mem_parity_error(unsigned char reason, struct pt_regs * regs) 699static __kprobes void
700mem_parity_error(unsigned char reason, struct pt_regs * regs)
633{ 701{
634 printk(KERN_EMERG "Uhhuh. NMI received. Dazed and confused, but trying " 702 printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x on "
635 "to continue\n"); 703 "CPU %d.\n", reason, smp_processor_id());
636 printk(KERN_EMERG "You probably have a hardware problem with your RAM " 704 printk(KERN_EMERG "You probably have a hardware problem with your RAM "
637 "chips\n"); 705 "chips\n");
706 if (panic_on_unrecovered_nmi)
707 panic("NMI: Not continuing");
708
709 printk(KERN_EMERG "Dazed and confused, but trying to continue\n");
638 710
639 /* Clear and disable the memory parity error line. */ 711 /* Clear and disable the memory parity error line. */
640 clear_mem_error(reason); 712 clear_mem_error(reason);
641} 713}
642 714
643static void io_check_error(unsigned char reason, struct pt_regs * regs) 715static __kprobes void
716io_check_error(unsigned char reason, struct pt_regs * regs)
644{ 717{
645 unsigned long i; 718 unsigned long i;
646 719
@@ -656,7 +729,8 @@ static void io_check_error(unsigned char reason, struct pt_regs * regs)
656 outb(reason, 0x61); 729 outb(reason, 0x61);
657} 730}
658 731
659static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) 732static __kprobes void
733unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
660{ 734{
661#ifdef CONFIG_MCA 735#ifdef CONFIG_MCA
662 /* Might actually be able to figure out what the guilty party 736 /* Might actually be able to figure out what the guilty party
@@ -666,15 +740,18 @@ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
666 return; 740 return;
667 } 741 }
668#endif 742#endif
669 printk("Uhhuh. NMI received for unknown reason %02x on CPU %d.\n", 743 printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x on "
670 reason, smp_processor_id()); 744 "CPU %d.\n", reason, smp_processor_id());
671 printk("Dazed and confused, but trying to continue\n"); 745 printk(KERN_EMERG "Do you have a strange power saving mode enabled?\n");
672 printk("Do you have a strange power saving mode enabled?\n"); 746 if (panic_on_unrecovered_nmi)
747 panic("NMI: Not continuing");
748
749 printk(KERN_EMERG "Dazed and confused, but trying to continue\n");
673} 750}
674 751
675static DEFINE_SPINLOCK(nmi_print_lock); 752static DEFINE_SPINLOCK(nmi_print_lock);
676 753
677void die_nmi (struct pt_regs *regs, const char *msg) 754void __kprobes die_nmi(struct pt_regs *regs, const char *msg)
678{ 755{
679 if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 2, SIGINT) == 756 if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 2, SIGINT) ==
680 NOTIFY_STOP) 757 NOTIFY_STOP)
@@ -706,7 +783,7 @@ void die_nmi (struct pt_regs *regs, const char *msg)
706 do_exit(SIGSEGV); 783 do_exit(SIGSEGV);
707} 784}
708 785
709static void default_do_nmi(struct pt_regs * regs) 786static __kprobes void default_do_nmi(struct pt_regs * regs)
710{ 787{
711 unsigned char reason = 0; 788 unsigned char reason = 0;
712 789
@@ -723,12 +800,12 @@ static void default_do_nmi(struct pt_regs * regs)
723 * Ok, so this is none of the documented NMI sources, 800 * Ok, so this is none of the documented NMI sources,
724 * so it must be the NMI watchdog. 801 * so it must be the NMI watchdog.
725 */ 802 */
726 if (nmi_watchdog) { 803 if (nmi_watchdog_tick(regs, reason))
727 nmi_watchdog_tick(regs);
728 return; 804 return;
729 } 805 if (!do_nmi_callback(regs, smp_processor_id()))
730#endif 806#endif
731 unknown_nmi_error(reason, regs); 807 unknown_nmi_error(reason, regs);
808
732 return; 809 return;
733 } 810 }
734 if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) 811 if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP)
@@ -744,14 +821,7 @@ static void default_do_nmi(struct pt_regs * regs)
744 reassert_nmi(); 821 reassert_nmi();
745} 822}
746 823
747static int dummy_nmi_callback(struct pt_regs * regs, int cpu) 824fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code)
748{
749 return 0;
750}
751
752static nmi_callback_t nmi_callback = dummy_nmi_callback;
753
754fastcall void do_nmi(struct pt_regs * regs, long error_code)
755{ 825{
756 int cpu; 826 int cpu;
757 827
@@ -761,25 +831,11 @@ fastcall void do_nmi(struct pt_regs * regs, long error_code)
761 831
762 ++nmi_count(cpu); 832 ++nmi_count(cpu);
763 833
764 if (!rcu_dereference(nmi_callback)(regs, cpu)) 834 default_do_nmi(regs);
765 default_do_nmi(regs);
766 835
767 nmi_exit(); 836 nmi_exit();
768} 837}
769 838
770void set_nmi_callback(nmi_callback_t callback)
771{
772 vmalloc_sync_all();
773 rcu_assign_pointer(nmi_callback, callback);
774}
775EXPORT_SYMBOL_GPL(set_nmi_callback);
776
777void unset_nmi_callback(void)
778{
779 nmi_callback = dummy_nmi_callback;
780}
781EXPORT_SYMBOL_GPL(unset_nmi_callback);
782
783#ifdef CONFIG_KPROBES 839#ifdef CONFIG_KPROBES
784fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code) 840fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code)
785{ 841{
@@ -1119,20 +1175,6 @@ void __init trap_init_f00f_bug(void)
1119} 1175}
1120#endif 1176#endif
1121 1177
1122#define _set_gate(gate_addr,type,dpl,addr,seg) \
1123do { \
1124 int __d0, __d1; \
1125 __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
1126 "movw %4,%%dx\n\t" \
1127 "movl %%eax,%0\n\t" \
1128 "movl %%edx,%1" \
1129 :"=m" (*((long *) (gate_addr))), \
1130 "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \
1131 :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
1132 "3" ((char *) (addr)),"2" ((seg) << 16)); \
1133} while (0)
1134
1135
1136/* 1178/*
1137 * This needs to use 'idt_table' rather than 'idt', and 1179 * This needs to use 'idt_table' rather than 'idt', and
1138 * thus use the _nonmapped_ version of the IDT, as the 1180 * thus use the _nonmapped_ version of the IDT, as the
@@ -1141,7 +1183,7 @@ do { \
1141 */ 1183 */
1142void set_intr_gate(unsigned int n, void *addr) 1184void set_intr_gate(unsigned int n, void *addr)
1143{ 1185{
1144 _set_gate(idt_table+n,14,0,addr,__KERNEL_CS); 1186 _set_gate(n, DESCTYPE_INT, addr, __KERNEL_CS);
1145} 1187}
1146 1188
1147/* 1189/*
@@ -1149,22 +1191,22 @@ void set_intr_gate(unsigned int n, void *addr)
1149 */ 1191 */
1150static inline void set_system_intr_gate(unsigned int n, void *addr) 1192static inline void set_system_intr_gate(unsigned int n, void *addr)
1151{ 1193{
1152 _set_gate(idt_table+n, 14, 3, addr, __KERNEL_CS); 1194 _set_gate(n, DESCTYPE_INT | DESCTYPE_DPL3, addr, __KERNEL_CS);
1153} 1195}
1154 1196
1155static void __init set_trap_gate(unsigned int n, void *addr) 1197static void __init set_trap_gate(unsigned int n, void *addr)
1156{ 1198{
1157 _set_gate(idt_table+n,15,0,addr,__KERNEL_CS); 1199 _set_gate(n, DESCTYPE_TRAP, addr, __KERNEL_CS);
1158} 1200}
1159 1201
1160static void __init set_system_gate(unsigned int n, void *addr) 1202static void __init set_system_gate(unsigned int n, void *addr)
1161{ 1203{
1162 _set_gate(idt_table+n,15,3,addr,__KERNEL_CS); 1204 _set_gate(n, DESCTYPE_TRAP | DESCTYPE_DPL3, addr, __KERNEL_CS);
1163} 1205}
1164 1206
1165static void __init set_task_gate(unsigned int n, unsigned int gdt_entry) 1207static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
1166{ 1208{
1167 _set_gate(idt_table+n,5,0,0,(gdt_entry<<3)); 1209 _set_gate(n, DESCTYPE_TASK, (void *)0, (gdt_entry<<3));
1168} 1210}
1169 1211
1170 1212
diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c
index 7e0d8dab2075..b8fa0a8b2e47 100644
--- a/arch/i386/kernel/tsc.c
+++ b/arch/i386/kernel/tsc.c
@@ -192,7 +192,7 @@ int recalibrate_cpu_khz(void)
192 192
193EXPORT_SYMBOL(recalibrate_cpu_khz); 193EXPORT_SYMBOL(recalibrate_cpu_khz);
194 194
195void tsc_init(void) 195void __init tsc_init(void)
196{ 196{
197 if (!cpu_has_tsc || tsc_disable) 197 if (!cpu_has_tsc || tsc_disable)
198 return; 198 return;
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S
index 2d4f1386e2b1..1e7ac1c44ddc 100644
--- a/arch/i386/kernel/vmlinux.lds.S
+++ b/arch/i386/kernel/vmlinux.lds.S
@@ -13,6 +13,12 @@ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
13OUTPUT_ARCH(i386) 13OUTPUT_ARCH(i386)
14ENTRY(phys_startup_32) 14ENTRY(phys_startup_32)
15jiffies = jiffies_64; 15jiffies = jiffies_64;
16
17PHDRS {
18 text PT_LOAD FLAGS(5); /* R_E */
19 data PT_LOAD FLAGS(7); /* RWE */
20 note PT_NOTE FLAGS(4); /* R__ */
21}
16SECTIONS 22SECTIONS
17{ 23{
18 . = __KERNEL_START; 24 . = __KERNEL_START;
@@ -26,7 +32,7 @@ SECTIONS
26 KPROBES_TEXT 32 KPROBES_TEXT
27 *(.fixup) 33 *(.fixup)
28 *(.gnu.warning) 34 *(.gnu.warning)
29 } = 0x9090 35 } :text = 0x9090
30 36
31 _etext = .; /* End of text section */ 37 _etext = .; /* End of text section */
32 38
@@ -48,7 +54,7 @@ SECTIONS
48 .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */ 54 .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
49 *(.data) 55 *(.data)
50 CONSTRUCTORS 56 CONSTRUCTORS
51 } 57 } :data
52 58
53 . = ALIGN(4096); 59 . = ALIGN(4096);
54 __nosave_begin = .; 60 __nosave_begin = .;
@@ -184,4 +190,6 @@ SECTIONS
184 STABS_DEBUG 190 STABS_DEBUG
185 191
186 DWARF_DEBUG 192 DWARF_DEBUG
193
194 NOTES
187} 195}
diff --git a/arch/i386/lib/Makefile b/arch/i386/lib/Makefile
index 914933e9ec3d..d86a548b8d54 100644
--- a/arch/i386/lib/Makefile
+++ b/arch/i386/lib/Makefile
@@ -4,6 +4,6 @@
4 4
5 5
6lib-y = checksum.o delay.o usercopy.o getuser.o putuser.o memcpy.o strstr.o \ 6lib-y = checksum.o delay.o usercopy.o getuser.o putuser.o memcpy.o strstr.o \
7 bitops.o 7 bitops.o semaphore.o
8 8
9lib-$(CONFIG_X86_USE_3DNOW) += mmx.o 9lib-$(CONFIG_X86_USE_3DNOW) += mmx.o
diff --git a/arch/i386/lib/semaphore.S b/arch/i386/lib/semaphore.S
new file mode 100644
index 000000000000..01f80b5c45d2
--- /dev/null
+++ b/arch/i386/lib/semaphore.S
@@ -0,0 +1,217 @@
1/*
2 * i386 semaphore implementation.
3 *
4 * (C) Copyright 1999 Linus Torvalds
5 *
6 * Portions Copyright 1999 Red Hat, Inc.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 *
13 * rw semaphores implemented November 1999 by Benjamin LaHaise <bcrl@kvack.org>
14 */
15
16#include <linux/config.h>
17#include <linux/linkage.h>
18#include <asm/rwlock.h>
19#include <asm/alternative-asm.i>
20#include <asm/frame.i>
21#include <asm/dwarf2.h>
22
23/*
24 * The semaphore operations have a special calling sequence that
25 * allow us to do a simpler in-line version of them. These routines
26 * need to convert that sequence back into the C sequence when
27 * there is contention on the semaphore.
28 *
29 * %eax contains the semaphore pointer on entry. Save the C-clobbered
30 * registers (%eax, %edx and %ecx) except %eax whish is either a return
31 * value or just clobbered..
32 */
33 .section .sched.text
34ENTRY(__down_failed)
35 CFI_STARTPROC
36 FRAME
37 pushl %edx
38 CFI_ADJUST_CFA_OFFSET 4
39 CFI_REL_OFFSET edx,0
40 pushl %ecx
41 CFI_ADJUST_CFA_OFFSET 4
42 CFI_REL_OFFSET ecx,0
43 call __down
44 popl %ecx
45 CFI_ADJUST_CFA_OFFSET -4
46 CFI_RESTORE ecx
47 popl %edx
48 CFI_ADJUST_CFA_OFFSET -4
49 CFI_RESTORE edx
50 ENDFRAME
51 ret
52 CFI_ENDPROC
53 END(__down_failed)
54
55ENTRY(__down_failed_interruptible)
56 CFI_STARTPROC
57 FRAME
58 pushl %edx
59 CFI_ADJUST_CFA_OFFSET 4
60 CFI_REL_OFFSET edx,0
61 pushl %ecx
62 CFI_ADJUST_CFA_OFFSET 4
63 CFI_REL_OFFSET ecx,0
64 call __down_interruptible
65 popl %ecx
66 CFI_ADJUST_CFA_OFFSET -4
67 CFI_RESTORE ecx
68 popl %edx
69 CFI_ADJUST_CFA_OFFSET -4
70 CFI_RESTORE edx
71 ENDFRAME
72 ret
73 CFI_ENDPROC
74 END(__down_failed_interruptible)
75
76ENTRY(__down_failed_trylock)
77 CFI_STARTPROC
78 FRAME
79 pushl %edx
80 CFI_ADJUST_CFA_OFFSET 4
81 CFI_REL_OFFSET edx,0
82 pushl %ecx
83 CFI_ADJUST_CFA_OFFSET 4
84 CFI_REL_OFFSET ecx,0
85 call __down_trylock
86 popl %ecx
87 CFI_ADJUST_CFA_OFFSET -4
88 CFI_RESTORE ecx
89 popl %edx
90 CFI_ADJUST_CFA_OFFSET -4
91 CFI_RESTORE edx
92 ENDFRAME
93 ret
94 CFI_ENDPROC
95 END(__down_failed_trylock)
96
97ENTRY(__up_wakeup)
98 CFI_STARTPROC
99 FRAME
100 pushl %edx
101 CFI_ADJUST_CFA_OFFSET 4
102 CFI_REL_OFFSET edx,0
103 pushl %ecx
104 CFI_ADJUST_CFA_OFFSET 4
105 CFI_REL_OFFSET ecx,0
106 call __up
107 popl %ecx
108 CFI_ADJUST_CFA_OFFSET -4
109 CFI_RESTORE ecx
110 popl %edx
111 CFI_ADJUST_CFA_OFFSET -4
112 CFI_RESTORE edx
113 ENDFRAME
114 ret
115 CFI_ENDPROC
116 END(__up_wakeup)
117
118/*
119 * rw spinlock fallbacks
120 */
121#ifdef CONFIG_SMP
122ENTRY(__write_lock_failed)
123 CFI_STARTPROC simple
124 FRAME
1252: LOCK_PREFIX
126 addl $ RW_LOCK_BIAS,(%eax)
1271: rep; nop
128 cmpl $ RW_LOCK_BIAS,(%eax)
129 jne 1b
130 LOCK_PREFIX
131 subl $ RW_LOCK_BIAS,(%eax)
132 jnz 2b
133 ENDFRAME
134 ret
135 CFI_ENDPROC
136 END(__write_lock_failed)
137
138ENTRY(__read_lock_failed)
139 CFI_STARTPROC
140 FRAME
1412: LOCK_PREFIX
142 incl (%eax)
1431: rep; nop
144 cmpl $1,(%eax)
145 js 1b
146 LOCK_PREFIX
147 decl (%eax)
148 js 2b
149 ENDFRAME
150 ret
151 CFI_ENDPROC
152 END(__read_lock_failed)
153
154#endif
155
156/* Fix up special calling conventions */
157ENTRY(call_rwsem_down_read_failed)
158 CFI_STARTPROC
159 push %ecx
160 CFI_ADJUST_CFA_OFFSET 4
161 CFI_REL_OFFSET ecx,0
162 push %edx
163 CFI_ADJUST_CFA_OFFSET 4
164 CFI_REL_OFFSET edx,0
165 call rwsem_down_read_failed
166 pop %edx
167 CFI_ADJUST_CFA_OFFSET -4
168 pop %ecx
169 CFI_ADJUST_CFA_OFFSET -4
170 ret
171 CFI_ENDPROC
172 END(call_rwsem_down_read_failed)
173
174ENTRY(call_rwsem_down_write_failed)
175 CFI_STARTPROC
176 push %ecx
177 CFI_ADJUST_CFA_OFFSET 4
178 CFI_REL_OFFSET ecx,0
179 calll rwsem_down_write_failed
180 pop %ecx
181 CFI_ADJUST_CFA_OFFSET -4
182 ret
183 CFI_ENDPROC
184 END(call_rwsem_down_write_failed)
185
186ENTRY(call_rwsem_wake)
187 CFI_STARTPROC
188 decw %dx /* do nothing if still outstanding active readers */
189 jnz 1f
190 push %ecx
191 CFI_ADJUST_CFA_OFFSET 4
192 CFI_REL_OFFSET ecx,0
193 call rwsem_wake
194 pop %ecx
195 CFI_ADJUST_CFA_OFFSET -4
1961: ret
197 CFI_ENDPROC
198 END(call_rwsem_wake)
199
200/* Fix up special calling conventions */
201ENTRY(call_rwsem_downgrade_wake)
202 CFI_STARTPROC
203 push %ecx
204 CFI_ADJUST_CFA_OFFSET 4
205 CFI_REL_OFFSET ecx,0
206 push %edx
207 CFI_ADJUST_CFA_OFFSET 4
208 CFI_REL_OFFSET edx,0
209 call rwsem_downgrade_wake
210 pop %edx
211 CFI_ADJUST_CFA_OFFSET -4
212 pop %ecx
213 CFI_ADJUST_CFA_OFFSET -4
214 ret
215 CFI_ENDPROC
216 END(call_rwsem_downgrade_wake)
217
diff --git a/arch/i386/mach-generic/bigsmp.c b/arch/i386/mach-generic/bigsmp.c
index ef7a6e6fcb9f..33d9f93557ba 100644
--- a/arch/i386/mach-generic/bigsmp.c
+++ b/arch/i386/mach-generic/bigsmp.c
@@ -5,6 +5,7 @@
5#define APIC_DEFINITION 1 5#define APIC_DEFINITION 1
6#include <linux/threads.h> 6#include <linux/threads.h>
7#include <linux/cpumask.h> 7#include <linux/cpumask.h>
8#include <asm/smp.h>
8#include <asm/mpspec.h> 9#include <asm/mpspec.h>
9#include <asm/genapic.h> 10#include <asm/genapic.h>
10#include <asm/fixmap.h> 11#include <asm/fixmap.h>
diff --git a/arch/i386/mach-generic/es7000.c b/arch/i386/mach-generic/es7000.c
index 845cdd0b3593..aa144d82334d 100644
--- a/arch/i386/mach-generic/es7000.c
+++ b/arch/i386/mach-generic/es7000.c
@@ -4,6 +4,7 @@
4#define APIC_DEFINITION 1 4#define APIC_DEFINITION 1
5#include <linux/threads.h> 5#include <linux/threads.h>
6#include <linux/cpumask.h> 6#include <linux/cpumask.h>
7#include <asm/smp.h>
7#include <asm/mpspec.h> 8#include <asm/mpspec.h>
8#include <asm/genapic.h> 9#include <asm/genapic.h>
9#include <asm/fixmap.h> 10#include <asm/fixmap.h>
diff --git a/arch/i386/mach-generic/probe.c b/arch/i386/mach-generic/probe.c
index bcd1bcfaa723..94b1fd9cbe3c 100644
--- a/arch/i386/mach-generic/probe.c
+++ b/arch/i386/mach-generic/probe.c
@@ -9,6 +9,7 @@
9#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <linux/ctype.h> 10#include <linux/ctype.h>
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/errno.h>
12#include <asm/fixmap.h> 13#include <asm/fixmap.h>
13#include <asm/mpspec.h> 14#include <asm/mpspec.h>
14#include <asm/apicdef.h> 15#include <asm/apicdef.h>
@@ -29,7 +30,24 @@ struct genapic *apic_probe[] __initdata = {
29 NULL, 30 NULL,
30}; 31};
31 32
32static int cmdline_apic; 33static int cmdline_apic __initdata;
34static int __init parse_apic(char *arg)
35{
36 int i;
37
38 if (!arg)
39 return -EINVAL;
40
41 for (i = 0; apic_probe[i]; i++) {
42 if (!strcmp(apic_probe[i]->name, arg)) {
43 genapic = apic_probe[i];
44 cmdline_apic = 1;
45 return 0;
46 }
47 }
48 return -ENOENT;
49}
50early_param("apic", parse_apic);
33 51
34void __init generic_bigsmp_probe(void) 52void __init generic_bigsmp_probe(void)
35{ 53{
@@ -48,40 +66,20 @@ void __init generic_bigsmp_probe(void)
48 } 66 }
49} 67}
50 68
51void __init generic_apic_probe(char *command_line) 69void __init generic_apic_probe(void)
52{ 70{
53 char *s; 71 if (!cmdline_apic) {
54 int i; 72 int i;
55 int changed = 0; 73 for (i = 0; apic_probe[i]; i++) {
56 74 if (apic_probe[i]->probe()) {
57 s = strstr(command_line, "apic=");
58 if (s && (s == command_line || isspace(s[-1]))) {
59 char *p = strchr(s, ' '), old;
60 if (!p)
61 p = strchr(s, '\0');
62 old = *p;
63 *p = 0;
64 for (i = 0; !changed && apic_probe[i]; i++) {
65 if (!strcmp(apic_probe[i]->name, s+5)) {
66 changed = 1;
67 genapic = apic_probe[i]; 75 genapic = apic_probe[i];
76 break;
68 } 77 }
69 } 78 }
70 if (!changed) 79 /* Not visible without early console */
71 printk(KERN_ERR "Unknown genapic `%s' specified.\n", s); 80 if (!apic_probe[i])
72 *p = old; 81 panic("Didn't find an APIC driver");
73 cmdline_apic = changed;
74 }
75 for (i = 0; !changed && apic_probe[i]; i++) {
76 if (apic_probe[i]->probe()) {
77 changed = 1;
78 genapic = apic_probe[i];
79 }
80 } 82 }
81 /* Not visible without early console */
82 if (!changed)
83 panic("Didn't find an APIC driver");
84
85 printk(KERN_INFO "Using APIC driver %s\n", genapic->name); 83 printk(KERN_INFO "Using APIC driver %s\n", genapic->name);
86} 84}
87 85
@@ -119,7 +117,9 @@ int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
119 return 0; 117 return 0;
120} 118}
121 119
120#ifdef CONFIG_SMP
122int hard_smp_processor_id(void) 121int hard_smp_processor_id(void)
123{ 122{
124 return genapic->get_apic_id(*(unsigned long *)(APIC_BASE+APIC_ID)); 123 return genapic->get_apic_id(*(unsigned long *)(APIC_BASE+APIC_ID));
125} 124}
125#endif
diff --git a/arch/i386/mach-generic/summit.c b/arch/i386/mach-generic/summit.c
index b73501ddd653..f7e5d66648dc 100644
--- a/arch/i386/mach-generic/summit.c
+++ b/arch/i386/mach-generic/summit.c
@@ -4,6 +4,7 @@
4#define APIC_DEFINITION 1 4#define APIC_DEFINITION 1
5#include <linux/threads.h> 5#include <linux/threads.h>
6#include <linux/cpumask.h> 6#include <linux/cpumask.h>
7#include <asm/smp.h>
7#include <asm/mpspec.h> 8#include <asm/mpspec.h>
8#include <asm/genapic.h> 9#include <asm/genapic.h>
9#include <asm/fixmap.h> 10#include <asm/fixmap.h>
diff --git a/arch/i386/mach-voyager/voyager_thread.c b/arch/i386/mach-voyager/voyager_thread.c
index 50f6de6ff64d..f39887359e8e 100644
--- a/arch/i386/mach-voyager/voyager_thread.c
+++ b/arch/i386/mach-voyager/voyager_thread.c
@@ -130,7 +130,6 @@ thread(void *unused)
130 init_timer(&wakeup_timer); 130 init_timer(&wakeup_timer);
131 131
132 sigfillset(&current->blocked); 132 sigfillset(&current->blocked);
133 current->signal->tty = NULL;
134 133
135 printk(KERN_NOTICE "Voyager starting monitor thread\n"); 134 printk(KERN_NOTICE "Voyager starting monitor thread\n");
136 135
diff --git a/arch/i386/mm/boot_ioremap.c b/arch/i386/mm/boot_ioremap.c
index 5d44f4f5ff59..4de11f508c3a 100644
--- a/arch/i386/mm/boot_ioremap.c
+++ b/arch/i386/mm/boot_ioremap.c
@@ -29,8 +29,11 @@
29 */ 29 */
30 30
31#define BOOT_PTE_PTRS (PTRS_PER_PTE*2) 31#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
32#define boot_pte_index(address) \ 32
33 (((address) >> PAGE_SHIFT) & (BOOT_PTE_PTRS - 1)) 33static unsigned long boot_pte_index(unsigned long vaddr)
34{
35 return __pa(vaddr) >> PAGE_SHIFT;
36}
34 37
35static inline boot_pte_t* boot_vaddr_to_pte(void *address) 38static inline boot_pte_t* boot_vaddr_to_pte(void *address)
36{ 39{
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c
index 7c392dc553b8..51e3739dd227 100644
--- a/arch/i386/mm/discontig.c
+++ b/arch/i386/mm/discontig.c
@@ -117,7 +117,8 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
117 117
118void *node_remap_end_vaddr[MAX_NUMNODES]; 118void *node_remap_end_vaddr[MAX_NUMNODES];
119void *node_remap_alloc_vaddr[MAX_NUMNODES]; 119void *node_remap_alloc_vaddr[MAX_NUMNODES];
120 120static unsigned long kva_start_pfn;
121static unsigned long kva_pages;
121/* 122/*
122 * FLAT - support for basic PC memory model with discontig enabled, essentially 123 * FLAT - support for basic PC memory model with discontig enabled, essentially
123 * a single node with all available processors in it with a flat 124 * a single node with all available processors in it with a flat
@@ -156,21 +157,6 @@ static void __init find_max_pfn_node(int nid)
156 BUG(); 157 BUG();
157} 158}
158 159
159/* Find the owning node for a pfn. */
160int early_pfn_to_nid(unsigned long pfn)
161{
162 int nid;
163
164 for_each_node(nid) {
165 if (node_end_pfn[nid] == 0)
166 break;
167 if (node_start_pfn[nid] <= pfn && node_end_pfn[nid] >= pfn)
168 return nid;
169 }
170
171 return 0;
172}
173
174/* 160/*
175 * Allocate memory for the pg_data_t for this node via a crude pre-bootmem 161 * Allocate memory for the pg_data_t for this node via a crude pre-bootmem
176 * method. For node zero take this from the bottom of memory, for 162 * method. For node zero take this from the bottom of memory, for
@@ -226,6 +212,8 @@ static unsigned long calculate_numa_remap_pages(void)
226 unsigned long pfn; 212 unsigned long pfn;
227 213
228 for_each_online_node(nid) { 214 for_each_online_node(nid) {
215 unsigned old_end_pfn = node_end_pfn[nid];
216
229 /* 217 /*
230 * The acpi/srat node info can show hot-add memroy zones 218 * The acpi/srat node info can show hot-add memroy zones
231 * where memory could be added but not currently present. 219 * where memory could be added but not currently present.
@@ -275,6 +263,7 @@ static unsigned long calculate_numa_remap_pages(void)
275 263
276 node_end_pfn[nid] -= size; 264 node_end_pfn[nid] -= size;
277 node_remap_start_pfn[nid] = node_end_pfn[nid]; 265 node_remap_start_pfn[nid] = node_end_pfn[nid];
266 shrink_active_range(nid, old_end_pfn, node_end_pfn[nid]);
278 } 267 }
279 printk("Reserving total of %ld pages for numa KVA remap\n", 268 printk("Reserving total of %ld pages for numa KVA remap\n",
280 reserve_pages); 269 reserve_pages);
@@ -286,7 +275,6 @@ unsigned long __init setup_memory(void)
286{ 275{
287 int nid; 276 int nid;
288 unsigned long system_start_pfn, system_max_low_pfn; 277 unsigned long system_start_pfn, system_max_low_pfn;
289 unsigned long reserve_pages;
290 278
291 /* 279 /*
292 * When mapping a NUMA machine we allocate the node_mem_map arrays 280 * When mapping a NUMA machine we allocate the node_mem_map arrays
@@ -298,14 +286,23 @@ unsigned long __init setup_memory(void)
298 find_max_pfn(); 286 find_max_pfn();
299 get_memcfg_numa(); 287 get_memcfg_numa();
300 288
301 reserve_pages = calculate_numa_remap_pages(); 289 kva_pages = calculate_numa_remap_pages();
302 290
303 /* partially used pages are not usable - thus round upwards */ 291 /* partially used pages are not usable - thus round upwards */
304 system_start_pfn = min_low_pfn = PFN_UP(init_pg_tables_end); 292 system_start_pfn = min_low_pfn = PFN_UP(init_pg_tables_end);
305 293
306 system_max_low_pfn = max_low_pfn = find_max_low_pfn() - reserve_pages; 294 kva_start_pfn = find_max_low_pfn() - kva_pages;
307 printk("reserve_pages = %ld find_max_low_pfn() ~ %ld\n", 295
308 reserve_pages, max_low_pfn + reserve_pages); 296#ifdef CONFIG_BLK_DEV_INITRD
297 /* Numa kva area is below the initrd */
298 if (LOADER_TYPE && INITRD_START)
299 kva_start_pfn = PFN_DOWN(INITRD_START) - kva_pages;
300#endif
301 kva_start_pfn -= kva_start_pfn & (PTRS_PER_PTE-1);
302
303 system_max_low_pfn = max_low_pfn = find_max_low_pfn();
304 printk("kva_start_pfn ~ %ld find_max_low_pfn() ~ %ld\n",
305 kva_start_pfn, max_low_pfn);
309 printk("max_pfn = %ld\n", max_pfn); 306 printk("max_pfn = %ld\n", max_pfn);
310#ifdef CONFIG_HIGHMEM 307#ifdef CONFIG_HIGHMEM
311 highstart_pfn = highend_pfn = max_pfn; 308 highstart_pfn = highend_pfn = max_pfn;
@@ -313,6 +310,11 @@ unsigned long __init setup_memory(void)
313 highstart_pfn = system_max_low_pfn; 310 highstart_pfn = system_max_low_pfn;
314 printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", 311 printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
315 pages_to_mb(highend_pfn - highstart_pfn)); 312 pages_to_mb(highend_pfn - highstart_pfn));
313 num_physpages = highend_pfn;
314 high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1;
315#else
316 num_physpages = system_max_low_pfn;
317 high_memory = (void *) __va(system_max_low_pfn * PAGE_SIZE - 1) + 1;
316#endif 318#endif
317 printk(KERN_NOTICE "%ldMB LOWMEM available.\n", 319 printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
318 pages_to_mb(system_max_low_pfn)); 320 pages_to_mb(system_max_low_pfn));
@@ -323,7 +325,7 @@ unsigned long __init setup_memory(void)
323 (ulong) pfn_to_kaddr(max_low_pfn)); 325 (ulong) pfn_to_kaddr(max_low_pfn));
324 for_each_online_node(nid) { 326 for_each_online_node(nid) {
325 node_remap_start_vaddr[nid] = pfn_to_kaddr( 327 node_remap_start_vaddr[nid] = pfn_to_kaddr(
326 highstart_pfn + node_remap_offset[nid]); 328 kva_start_pfn + node_remap_offset[nid]);
327 /* Init the node remap allocator */ 329 /* Init the node remap allocator */
328 node_remap_end_vaddr[nid] = node_remap_start_vaddr[nid] + 330 node_remap_end_vaddr[nid] = node_remap_start_vaddr[nid] +
329 (node_remap_size[nid] * PAGE_SIZE); 331 (node_remap_size[nid] * PAGE_SIZE);
@@ -338,7 +340,6 @@ unsigned long __init setup_memory(void)
338 } 340 }
339 printk("High memory starts at vaddr %08lx\n", 341 printk("High memory starts at vaddr %08lx\n",
340 (ulong) pfn_to_kaddr(highstart_pfn)); 342 (ulong) pfn_to_kaddr(highstart_pfn));
341 vmalloc_earlyreserve = reserve_pages * PAGE_SIZE;
342 for_each_online_node(nid) 343 for_each_online_node(nid)
343 find_max_pfn_node(nid); 344 find_max_pfn_node(nid);
344 345
@@ -348,48 +349,30 @@ unsigned long __init setup_memory(void)
348 return max_low_pfn; 349 return max_low_pfn;
349} 350}
350 351
352void __init numa_kva_reserve(void)
353{
354 reserve_bootmem(PFN_PHYS(kva_start_pfn),PFN_PHYS(kva_pages));
355}
356
351void __init zone_sizes_init(void) 357void __init zone_sizes_init(void)
352{ 358{
353 int nid; 359 int nid;
354 360 unsigned long max_zone_pfns[MAX_NR_ZONES] = {
355 361 virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT,
356 for_each_online_node(nid) { 362 max_low_pfn,
357 unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; 363 highend_pfn
358 unsigned long *zholes_size; 364 };
359 unsigned int max_dma; 365
360 366 /* If SRAT has not registered memory, register it now */
361 unsigned long low = max_low_pfn; 367 if (find_max_pfn_with_active_regions() == 0) {
362 unsigned long start = node_start_pfn[nid]; 368 for_each_online_node(nid) {
363 unsigned long high = node_end_pfn[nid]; 369 if (node_has_online_mem(nid))
364 370 add_active_range(nid, node_start_pfn[nid],
365 max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; 371 node_end_pfn[nid]);
366
367 if (node_has_online_mem(nid)){
368 if (start > low) {
369#ifdef CONFIG_HIGHMEM
370 BUG_ON(start > high);
371 zones_size[ZONE_HIGHMEM] = high - start;
372#endif
373 } else {
374 if (low < max_dma)
375 zones_size[ZONE_DMA] = low;
376 else {
377 BUG_ON(max_dma > low);
378 BUG_ON(low > high);
379 zones_size[ZONE_DMA] = max_dma;
380 zones_size[ZONE_NORMAL] = low - max_dma;
381#ifdef CONFIG_HIGHMEM
382 zones_size[ZONE_HIGHMEM] = high - low;
383#endif
384 }
385 }
386 } 372 }
387
388 zholes_size = get_zholes_size(nid);
389
390 free_area_init_node(nid, NODE_DATA(nid), zones_size, start,
391 zholes_size);
392 } 373 }
374
375 free_area_init_nodes(max_zone_pfns);
393 return; 376 return;
394} 377}
395 378
@@ -409,7 +392,7 @@ void __init set_highmem_pages_init(int bad_ppro)
409 zone_end_pfn = zone_start_pfn + zone->spanned_pages; 392 zone_end_pfn = zone_start_pfn + zone->spanned_pages;
410 393
411 printk("Initializing %s for node %d (%08lx:%08lx)\n", 394 printk("Initializing %s for node %d (%08lx:%08lx)\n",
412 zone->name, zone->zone_pgdat->node_id, 395 zone->name, zone_to_nid(zone),
413 zone_start_pfn, zone_end_pfn); 396 zone_start_pfn, zone_end_pfn);
414 397
415 for (node_pfn = zone_start_pfn; node_pfn < zone_end_pfn; node_pfn++) { 398 for (node_pfn = zone_start_pfn; node_pfn < zone_end_pfn; node_pfn++) {
diff --git a/arch/i386/mm/extable.c b/arch/i386/mm/extable.c
index de03c5430abc..0ce4f22a2635 100644
--- a/arch/i386/mm/extable.c
+++ b/arch/i386/mm/extable.c
@@ -11,7 +11,7 @@ int fixup_exception(struct pt_regs *regs)
11 const struct exception_table_entry *fixup; 11 const struct exception_table_entry *fixup;
12 12
13#ifdef CONFIG_PNPBIOS 13#ifdef CONFIG_PNPBIOS
14 if (unlikely((regs->xcs & ~15) == (GDT_ENTRY_PNPBIOS_BASE << 3))) 14 if (unlikely(SEGMENT_IS_PNP_CODE(regs->xcs)))
15 { 15 {
16 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp; 16 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
17 extern u32 pnp_bios_is_utter_crap; 17 extern u32 pnp_bios_is_utter_crap;
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
index f7279468323a..5e17a3f43b41 100644
--- a/arch/i386/mm/fault.c
+++ b/arch/i386/mm/fault.c
@@ -27,21 +27,24 @@
27#include <asm/uaccess.h> 27#include <asm/uaccess.h>
28#include <asm/desc.h> 28#include <asm/desc.h>
29#include <asm/kdebug.h> 29#include <asm/kdebug.h>
30#include <asm/segment.h>
30 31
31extern void die(const char *,struct pt_regs *,long); 32extern void die(const char *,struct pt_regs *,long);
32 33
33#ifdef CONFIG_KPROBES 34static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
34ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); 35
35int register_page_fault_notifier(struct notifier_block *nb) 36int register_page_fault_notifier(struct notifier_block *nb)
36{ 37{
37 vmalloc_sync_all(); 38 vmalloc_sync_all();
38 return atomic_notifier_chain_register(&notify_page_fault_chain, nb); 39 return atomic_notifier_chain_register(&notify_page_fault_chain, nb);
39} 40}
41EXPORT_SYMBOL_GPL(register_page_fault_notifier);
40 42
41int unregister_page_fault_notifier(struct notifier_block *nb) 43int unregister_page_fault_notifier(struct notifier_block *nb)
42{ 44{
43 return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb); 45 return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
44} 46}
47EXPORT_SYMBOL_GPL(unregister_page_fault_notifier);
45 48
46static inline int notify_page_fault(enum die_val val, const char *str, 49static inline int notify_page_fault(enum die_val val, const char *str,
47 struct pt_regs *regs, long err, int trap, int sig) 50 struct pt_regs *regs, long err, int trap, int sig)
@@ -55,14 +58,6 @@ static inline int notify_page_fault(enum die_val val, const char *str,
55 }; 58 };
56 return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args); 59 return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
57} 60}
58#else
59static inline int notify_page_fault(enum die_val val, const char *str,
60 struct pt_regs *regs, long err, int trap, int sig)
61{
62 return NOTIFY_DONE;
63}
64#endif
65
66 61
67/* 62/*
68 * Unlock any spinlocks which will prevent us from getting the 63 * Unlock any spinlocks which will prevent us from getting the
@@ -119,10 +114,10 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs,
119 } 114 }
120 115
121 /* The standard kernel/user address space limit. */ 116 /* The standard kernel/user address space limit. */
122 *eip_limit = (seg & 3) ? USER_DS.seg : KERNEL_DS.seg; 117 *eip_limit = user_mode(regs) ? USER_DS.seg : KERNEL_DS.seg;
123 118
124 /* By far the most common cases. */ 119 /* By far the most common cases. */
125 if (likely(seg == __USER_CS || seg == __KERNEL_CS)) 120 if (likely(SEGMENT_IS_FLAT_CODE(seg)))
126 return eip; 121 return eip;
127 122
128 /* Check the segment exists, is within the current LDT/GDT size, 123 /* Check the segment exists, is within the current LDT/GDT size,
@@ -436,11 +431,7 @@ good_area:
436 write = 0; 431 write = 0;
437 switch (error_code & 3) { 432 switch (error_code & 3) {
438 default: /* 3: write, present */ 433 default: /* 3: write, present */
439#ifdef TEST_VERIFY_AREA 434 /* fall through */
440 if (regs->cs == KERNEL_CS)
441 printk("WP fault at %08lx\n", regs->eip);
442#endif
443 /* fall through */
444 case 2: /* write, not present */ 435 case 2: /* write, not present */
445 if (!(vma->vm_flags & VM_WRITE)) 436 if (!(vma->vm_flags & VM_WRITE))
446 goto bad_area; 437 goto bad_area;
diff --git a/arch/i386/mm/highmem.c b/arch/i386/mm/highmem.c
index b6eb4dcb8777..ba44000b9069 100644
--- a/arch/i386/mm/highmem.c
+++ b/arch/i386/mm/highmem.c
@@ -54,7 +54,7 @@ void kunmap_atomic(void *kvaddr, enum km_type type)
54 unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; 54 unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
55 enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); 55 enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
56 56
57 if (vaddr < FIXADDR_START) { // FIXME 57 if (vaddr >= PAGE_OFFSET && vaddr < (unsigned long)high_memory) {
58 dec_preempt_count(); 58 dec_preempt_count();
59 preempt_check_resched(); 59 preempt_check_resched();
60 return; 60 return;
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 89e8486aac34..4a5a914b3432 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -435,16 +435,22 @@ u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
435 * on Enable 435 * on Enable
436 * off Disable 436 * off Disable
437 */ 437 */
438void __init noexec_setup(const char *str) 438static int __init noexec_setup(char *str)
439{ 439{
440 if (!strncmp(str, "on",2) && cpu_has_nx) { 440 if (!str || !strcmp(str, "on")) {
441 __supported_pte_mask |= _PAGE_NX; 441 if (cpu_has_nx) {
442 disable_nx = 0; 442 __supported_pte_mask |= _PAGE_NX;
443 } else if (!strncmp(str,"off",3)) { 443 disable_nx = 0;
444 }
445 } else if (!strcmp(str,"off")) {
444 disable_nx = 1; 446 disable_nx = 1;
445 __supported_pte_mask &= ~_PAGE_NX; 447 __supported_pte_mask &= ~_PAGE_NX;
446 } 448 } else
449 return -EINVAL;
450
451 return 0;
447} 452}
453early_param("noexec", noexec_setup);
448 454
449int nx_enabled = 0; 455int nx_enabled = 0;
450#ifdef CONFIG_X86_PAE 456#ifdef CONFIG_X86_PAE
@@ -552,18 +558,6 @@ static void __init test_wp_bit(void)
552 } 558 }
553} 559}
554 560
555static void __init set_max_mapnr_init(void)
556{
557#ifdef CONFIG_HIGHMEM
558 num_physpages = highend_pfn;
559#else
560 num_physpages = max_low_pfn;
561#endif
562#ifdef CONFIG_FLATMEM
563 max_mapnr = num_physpages;
564#endif
565}
566
567static struct kcore_list kcore_mem, kcore_vmalloc; 561static struct kcore_list kcore_mem, kcore_vmalloc;
568 562
569void __init mem_init(void) 563void __init mem_init(void)
@@ -590,14 +584,6 @@ void __init mem_init(void)
590 } 584 }
591#endif 585#endif
592 586
593 set_max_mapnr_init();
594
595#ifdef CONFIG_HIGHMEM
596 high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1;
597#else
598 high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1;
599#endif
600
601 /* this will put all low memory onto the freelists */ 587 /* this will put all low memory onto the freelists */
602 totalram_pages += free_all_bootmem(); 588 totalram_pages += free_all_bootmem();
603 589
@@ -629,6 +615,48 @@ void __init mem_init(void)
629 (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)) 615 (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
630 ); 616 );
631 617
618#if 1 /* double-sanity-check paranoia */
619 printk("virtual kernel memory layout:\n"
620 " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
621#ifdef CONFIG_HIGHMEM
622 " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
623#endif
624 " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n"
625 " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n"
626 " .init : 0x%08lx - 0x%08lx (%4ld kB)\n"
627 " .data : 0x%08lx - 0x%08lx (%4ld kB)\n"
628 " .text : 0x%08lx - 0x%08lx (%4ld kB)\n",
629 FIXADDR_START, FIXADDR_TOP,
630 (FIXADDR_TOP - FIXADDR_START) >> 10,
631
632#ifdef CONFIG_HIGHMEM
633 PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE,
634 (LAST_PKMAP*PAGE_SIZE) >> 10,
635#endif
636
637 VMALLOC_START, VMALLOC_END,
638 (VMALLOC_END - VMALLOC_START) >> 20,
639
640 (unsigned long)__va(0), (unsigned long)high_memory,
641 ((unsigned long)high_memory - (unsigned long)__va(0)) >> 20,
642
643 (unsigned long)&__init_begin, (unsigned long)&__init_end,
644 ((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10,
645
646 (unsigned long)&_etext, (unsigned long)&_edata,
647 ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
648
649 (unsigned long)&_text, (unsigned long)&_etext,
650 ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
651
652#ifdef CONFIG_HIGHMEM
653 BUG_ON(PKMAP_BASE+LAST_PKMAP*PAGE_SIZE > FIXADDR_START);
654 BUG_ON(VMALLOC_END > PKMAP_BASE);
655#endif
656 BUG_ON(VMALLOC_START > VMALLOC_END);
657 BUG_ON((unsigned long)high_memory > VMALLOC_START);
658#endif /* double-sanity-check paranoia */
659
632#ifdef CONFIG_X86_PAE 660#ifdef CONFIG_X86_PAE
633 if (!cpu_has_pae) 661 if (!cpu_has_pae)
634 panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!"); 662 panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
@@ -657,7 +685,7 @@ void __init mem_init(void)
657int arch_add_memory(int nid, u64 start, u64 size) 685int arch_add_memory(int nid, u64 start, u64 size)
658{ 686{
659 struct pglist_data *pgdata = &contig_page_data; 687 struct pglist_data *pgdata = &contig_page_data;
660 struct zone *zone = pgdata->node_zones + MAX_NR_ZONES-1; 688 struct zone *zone = pgdata->node_zones + ZONE_HIGHMEM;
661 unsigned long start_pfn = start >> PAGE_SHIFT; 689 unsigned long start_pfn = start >> PAGE_SHIFT;
662 unsigned long nr_pages = size >> PAGE_SHIFT; 690 unsigned long nr_pages = size >> PAGE_SHIFT;
663 691
diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c
index bd98768d8764..10126e3f8174 100644
--- a/arch/i386/mm/pgtable.c
+++ b/arch/i386/mm/pgtable.c
@@ -12,6 +12,7 @@
12#include <linux/slab.h> 12#include <linux/slab.h>
13#include <linux/pagemap.h> 13#include <linux/pagemap.h>
14#include <linux/spinlock.h> 14#include <linux/spinlock.h>
15#include <linux/module.h>
15 16
16#include <asm/system.h> 17#include <asm/system.h>
17#include <asm/pgtable.h> 18#include <asm/pgtable.h>
@@ -60,7 +61,9 @@ void show_mem(void)
60 printk(KERN_INFO "%lu pages writeback\n", 61 printk(KERN_INFO "%lu pages writeback\n",
61 global_page_state(NR_WRITEBACK)); 62 global_page_state(NR_WRITEBACK));
62 printk(KERN_INFO "%lu pages mapped\n", global_page_state(NR_FILE_MAPPED)); 63 printk(KERN_INFO "%lu pages mapped\n", global_page_state(NR_FILE_MAPPED));
63 printk(KERN_INFO "%lu pages slab\n", global_page_state(NR_SLAB)); 64 printk(KERN_INFO "%lu pages slab\n",
65 global_page_state(NR_SLAB_RECLAIMABLE) +
66 global_page_state(NR_SLAB_UNRECLAIMABLE));
64 printk(KERN_INFO "%lu pages pagetables\n", 67 printk(KERN_INFO "%lu pages pagetables\n",
65 global_page_state(NR_PAGETABLE)); 68 global_page_state(NR_PAGETABLE));
66} 69}
@@ -137,6 +140,12 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
137 __flush_tlb_one(vaddr); 140 __flush_tlb_one(vaddr);
138} 141}
139 142
143static int fixmaps;
144#ifndef CONFIG_COMPAT_VDSO
145unsigned long __FIXADDR_TOP = 0xfffff000;
146EXPORT_SYMBOL(__FIXADDR_TOP);
147#endif
148
140void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags) 149void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
141{ 150{
142 unsigned long address = __fix_to_virt(idx); 151 unsigned long address = __fix_to_virt(idx);
@@ -146,6 +155,25 @@ void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
146 return; 155 return;
147 } 156 }
148 set_pte_pfn(address, phys >> PAGE_SHIFT, flags); 157 set_pte_pfn(address, phys >> PAGE_SHIFT, flags);
158 fixmaps++;
159}
160
161/**
162 * reserve_top_address - reserves a hole in the top of kernel address space
163 * @reserve - size of hole to reserve
164 *
165 * Can be used to relocate the fixmap area and poke a hole in the top
166 * of kernel address space to make room for a hypervisor.
167 */
168void reserve_top_address(unsigned long reserve)
169{
170 BUG_ON(fixmaps > 0);
171#ifdef CONFIG_COMPAT_VDSO
172 BUG_ON(reserve != 0);
173#else
174 __FIXADDR_TOP = -reserve - PAGE_SIZE;
175 __VMALLOC_RESERVE += reserve;
176#endif
149} 177}
150 178
151pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) 179pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
diff --git a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
index 5f8dc8a21bd7..3700eef78743 100644
--- a/arch/i386/oprofile/nmi_int.c
+++ b/arch/i386/oprofile/nmi_int.c
@@ -17,14 +17,15 @@
17#include <asm/nmi.h> 17#include <asm/nmi.h>
18#include <asm/msr.h> 18#include <asm/msr.h>
19#include <asm/apic.h> 19#include <asm/apic.h>
20#include <asm/kdebug.h>
20 21
21#include "op_counter.h" 22#include "op_counter.h"
22#include "op_x86_model.h" 23#include "op_x86_model.h"
23 24
24static struct op_x86_model_spec const * model; 25static struct op_x86_model_spec const * model;
25static struct op_msrs cpu_msrs[NR_CPUS]; 26static struct op_msrs cpu_msrs[NR_CPUS];
26static unsigned long saved_lvtpc[NR_CPUS]; 27static unsigned long saved_lvtpc[NR_CPUS];
27 28
28static int nmi_start(void); 29static int nmi_start(void);
29static void nmi_stop(void); 30static void nmi_stop(void);
30 31
@@ -82,13 +83,24 @@ static void exit_driverfs(void)
82#define exit_driverfs() do { } while (0) 83#define exit_driverfs() do { } while (0)
83#endif /* CONFIG_PM */ 84#endif /* CONFIG_PM */
84 85
85 86static int profile_exceptions_notify(struct notifier_block *self,
86static int nmi_callback(struct pt_regs * regs, int cpu) 87 unsigned long val, void *data)
87{ 88{
88 return model->check_ctrs(regs, &cpu_msrs[cpu]); 89 struct die_args *args = (struct die_args *)data;
90 int ret = NOTIFY_DONE;
91 int cpu = smp_processor_id();
92
93 switch(val) {
94 case DIE_NMI:
95 if (model->check_ctrs(args->regs, &cpu_msrs[cpu]))
96 ret = NOTIFY_STOP;
97 break;
98 default:
99 break;
100 }
101 return ret;
89} 102}
90 103
91
92static void nmi_cpu_save_registers(struct op_msrs * msrs) 104static void nmi_cpu_save_registers(struct op_msrs * msrs)
93{ 105{
94 unsigned int const nr_ctrs = model->num_counters; 106 unsigned int const nr_ctrs = model->num_counters;
@@ -98,15 +110,19 @@ static void nmi_cpu_save_registers(struct op_msrs * msrs)
98 unsigned int i; 110 unsigned int i;
99 111
100 for (i = 0; i < nr_ctrs; ++i) { 112 for (i = 0; i < nr_ctrs; ++i) {
101 rdmsr(counters[i].addr, 113 if (counters[i].addr){
102 counters[i].saved.low, 114 rdmsr(counters[i].addr,
103 counters[i].saved.high); 115 counters[i].saved.low,
116 counters[i].saved.high);
117 }
104 } 118 }
105 119
106 for (i = 0; i < nr_ctrls; ++i) { 120 for (i = 0; i < nr_ctrls; ++i) {
107 rdmsr(controls[i].addr, 121 if (controls[i].addr){
108 controls[i].saved.low, 122 rdmsr(controls[i].addr,
109 controls[i].saved.high); 123 controls[i].saved.low,
124 controls[i].saved.high);
125 }
110 } 126 }
111} 127}
112 128
@@ -170,27 +186,29 @@ static void nmi_cpu_setup(void * dummy)
170 apic_write(APIC_LVTPC, APIC_DM_NMI); 186 apic_write(APIC_LVTPC, APIC_DM_NMI);
171} 187}
172 188
189static struct notifier_block profile_exceptions_nb = {
190 .notifier_call = profile_exceptions_notify,
191 .next = NULL,
192 .priority = 0
193};
173 194
174static int nmi_setup(void) 195static int nmi_setup(void)
175{ 196{
197 int err=0;
198
176 if (!allocate_msrs()) 199 if (!allocate_msrs())
177 return -ENOMEM; 200 return -ENOMEM;
178 201
179 /* We walk a thin line between law and rape here. 202 if ((err = register_die_notifier(&profile_exceptions_nb))){
180 * We need to be careful to install our NMI handler
181 * without actually triggering any NMIs as this will
182 * break the core code horrifically.
183 */
184 if (reserve_lapic_nmi() < 0) {
185 free_msrs(); 203 free_msrs();
186 return -EBUSY; 204 return err;
187 } 205 }
206
188 /* We need to serialize save and setup for HT because the subset 207 /* We need to serialize save and setup for HT because the subset
189 * of msrs are distinct for save and setup operations 208 * of msrs are distinct for save and setup operations
190 */ 209 */
191 on_each_cpu(nmi_save_registers, NULL, 0, 1); 210 on_each_cpu(nmi_save_registers, NULL, 0, 1);
192 on_each_cpu(nmi_cpu_setup, NULL, 0, 1); 211 on_each_cpu(nmi_cpu_setup, NULL, 0, 1);
193 set_nmi_callback(nmi_callback);
194 nmi_enabled = 1; 212 nmi_enabled = 1;
195 return 0; 213 return 0;
196} 214}
@@ -205,15 +223,19 @@ static void nmi_restore_registers(struct op_msrs * msrs)
205 unsigned int i; 223 unsigned int i;
206 224
207 for (i = 0; i < nr_ctrls; ++i) { 225 for (i = 0; i < nr_ctrls; ++i) {
208 wrmsr(controls[i].addr, 226 if (controls[i].addr){
209 controls[i].saved.low, 227 wrmsr(controls[i].addr,
210 controls[i].saved.high); 228 controls[i].saved.low,
229 controls[i].saved.high);
230 }
211 } 231 }
212 232
213 for (i = 0; i < nr_ctrs; ++i) { 233 for (i = 0; i < nr_ctrs; ++i) {
214 wrmsr(counters[i].addr, 234 if (counters[i].addr){
215 counters[i].saved.low, 235 wrmsr(counters[i].addr,
216 counters[i].saved.high); 236 counters[i].saved.low,
237 counters[i].saved.high);
238 }
217 } 239 }
218} 240}
219 241
@@ -234,6 +256,7 @@ static void nmi_cpu_shutdown(void * dummy)
234 apic_write(APIC_LVTPC, saved_lvtpc[cpu]); 256 apic_write(APIC_LVTPC, saved_lvtpc[cpu]);
235 apic_write(APIC_LVTERR, v); 257 apic_write(APIC_LVTERR, v);
236 nmi_restore_registers(msrs); 258 nmi_restore_registers(msrs);
259 model->shutdown(msrs);
237} 260}
238 261
239 262
@@ -241,8 +264,7 @@ static void nmi_shutdown(void)
241{ 264{
242 nmi_enabled = 0; 265 nmi_enabled = 0;
243 on_each_cpu(nmi_cpu_shutdown, NULL, 0, 1); 266 on_each_cpu(nmi_cpu_shutdown, NULL, 0, 1);
244 unset_nmi_callback(); 267 unregister_die_notifier(&profile_exceptions_nb);
245 release_lapic_nmi();
246 free_msrs(); 268 free_msrs();
247} 269}
248 270
@@ -284,6 +306,14 @@ static int nmi_create_files(struct super_block * sb, struct dentry * root)
284 struct dentry * dir; 306 struct dentry * dir;
285 char buf[4]; 307 char buf[4];
286 308
309 /* quick little hack to _not_ expose a counter if it is not
310 * available for use. This should protect userspace app.
311 * NOTE: assumes 1:1 mapping here (that counters are organized
312 * sequentially in their struct assignment).
313 */
314 if (unlikely(!avail_to_resrv_perfctr_nmi_bit(i)))
315 continue;
316
287 snprintf(buf, sizeof(buf), "%d", i); 317 snprintf(buf, sizeof(buf), "%d", i);
288 dir = oprofilefs_mkdir(sb, root, buf); 318 dir = oprofilefs_mkdir(sb, root, buf);
289 oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled); 319 oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled);
diff --git a/arch/i386/oprofile/nmi_timer_int.c b/arch/i386/oprofile/nmi_timer_int.c
index 930a1127bb30..abf0ba52a635 100644
--- a/arch/i386/oprofile/nmi_timer_int.c
+++ b/arch/i386/oprofile/nmi_timer_int.c
@@ -17,34 +17,49 @@
17#include <asm/nmi.h> 17#include <asm/nmi.h>
18#include <asm/apic.h> 18#include <asm/apic.h>
19#include <asm/ptrace.h> 19#include <asm/ptrace.h>
20#include <asm/kdebug.h>
20 21
21static int nmi_timer_callback(struct pt_regs * regs, int cpu) 22static int profile_timer_exceptions_notify(struct notifier_block *self,
23 unsigned long val, void *data)
22{ 24{
23 oprofile_add_sample(regs, 0); 25 struct die_args *args = (struct die_args *)data;
24 return 1; 26 int ret = NOTIFY_DONE;
27
28 switch(val) {
29 case DIE_NMI:
30 oprofile_add_sample(args->regs, 0);
31 ret = NOTIFY_STOP;
32 break;
33 default:
34 break;
35 }
36 return ret;
25} 37}
26 38
39static struct notifier_block profile_timer_exceptions_nb = {
40 .notifier_call = profile_timer_exceptions_notify,
41 .next = NULL,
42 .priority = 0
43};
44
27static int timer_start(void) 45static int timer_start(void)
28{ 46{
29 disable_timer_nmi_watchdog(); 47 if (register_die_notifier(&profile_timer_exceptions_nb))
30 set_nmi_callback(nmi_timer_callback); 48 return 1;
31 return 0; 49 return 0;
32} 50}
33 51
34 52
35static void timer_stop(void) 53static void timer_stop(void)
36{ 54{
37 enable_timer_nmi_watchdog(); 55 unregister_die_notifier(&profile_timer_exceptions_nb);
38 unset_nmi_callback();
39 synchronize_sched(); /* Allow already-started NMIs to complete. */ 56 synchronize_sched(); /* Allow already-started NMIs to complete. */
40} 57}
41 58
42 59
43int __init op_nmi_timer_init(struct oprofile_operations * ops) 60int __init op_nmi_timer_init(struct oprofile_operations * ops)
44{ 61{
45 extern int nmi_active; 62 if ((nmi_watchdog != NMI_IO_APIC) || (atomic_read(&nmi_active) <= 0))
46
47 if (nmi_active <= 0)
48 return -ENODEV; 63 return -ENODEV;
49 64
50 ops->start = timer_start; 65 ops->start = timer_start;
diff --git a/arch/i386/oprofile/op_model_athlon.c b/arch/i386/oprofile/op_model_athlon.c
index 693bdea4a52b..3057a19e4641 100644
--- a/arch/i386/oprofile/op_model_athlon.c
+++ b/arch/i386/oprofile/op_model_athlon.c
@@ -21,10 +21,12 @@
21#define NUM_COUNTERS 4 21#define NUM_COUNTERS 4
22#define NUM_CONTROLS 4 22#define NUM_CONTROLS 4
23 23
24#define CTR_IS_RESERVED(msrs,c) (msrs->counters[(c)].addr ? 1 : 0)
24#define CTR_READ(l,h,msrs,c) do {rdmsr(msrs->counters[(c)].addr, (l), (h));} while (0) 25#define CTR_READ(l,h,msrs,c) do {rdmsr(msrs->counters[(c)].addr, (l), (h));} while (0)
25#define CTR_WRITE(l,msrs,c) do {wrmsr(msrs->counters[(c)].addr, -(unsigned int)(l), -1);} while (0) 26#define CTR_WRITE(l,msrs,c) do {wrmsr(msrs->counters[(c)].addr, -(unsigned int)(l), -1);} while (0)
26#define CTR_OVERFLOWED(n) (!((n) & (1U<<31))) 27#define CTR_OVERFLOWED(n) (!((n) & (1U<<31)))
27 28
29#define CTRL_IS_RESERVED(msrs,c) (msrs->controls[(c)].addr ? 1 : 0)
28#define CTRL_READ(l,h,msrs,c) do {rdmsr(msrs->controls[(c)].addr, (l), (h));} while (0) 30#define CTRL_READ(l,h,msrs,c) do {rdmsr(msrs->controls[(c)].addr, (l), (h));} while (0)
29#define CTRL_WRITE(l,h,msrs,c) do {wrmsr(msrs->controls[(c)].addr, (l), (h));} while (0) 31#define CTRL_WRITE(l,h,msrs,c) do {wrmsr(msrs->controls[(c)].addr, (l), (h));} while (0)
30#define CTRL_SET_ACTIVE(n) (n |= (1<<22)) 32#define CTRL_SET_ACTIVE(n) (n |= (1<<22))
@@ -40,15 +42,21 @@ static unsigned long reset_value[NUM_COUNTERS];
40 42
41static void athlon_fill_in_addresses(struct op_msrs * const msrs) 43static void athlon_fill_in_addresses(struct op_msrs * const msrs)
42{ 44{
43 msrs->counters[0].addr = MSR_K7_PERFCTR0; 45 int i;
44 msrs->counters[1].addr = MSR_K7_PERFCTR1; 46
45 msrs->counters[2].addr = MSR_K7_PERFCTR2; 47 for (i=0; i < NUM_COUNTERS; i++) {
46 msrs->counters[3].addr = MSR_K7_PERFCTR3; 48 if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i))
47 49 msrs->counters[i].addr = MSR_K7_PERFCTR0 + i;
48 msrs->controls[0].addr = MSR_K7_EVNTSEL0; 50 else
49 msrs->controls[1].addr = MSR_K7_EVNTSEL1; 51 msrs->counters[i].addr = 0;
50 msrs->controls[2].addr = MSR_K7_EVNTSEL2; 52 }
51 msrs->controls[3].addr = MSR_K7_EVNTSEL3; 53
54 for (i=0; i < NUM_CONTROLS; i++) {
55 if (reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i))
56 msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i;
57 else
58 msrs->controls[i].addr = 0;
59 }
52} 60}
53 61
54 62
@@ -59,19 +67,23 @@ static void athlon_setup_ctrs(struct op_msrs const * const msrs)
59 67
60 /* clear all counters */ 68 /* clear all counters */
61 for (i = 0 ; i < NUM_CONTROLS; ++i) { 69 for (i = 0 ; i < NUM_CONTROLS; ++i) {
70 if (unlikely(!CTRL_IS_RESERVED(msrs,i)))
71 continue;
62 CTRL_READ(low, high, msrs, i); 72 CTRL_READ(low, high, msrs, i);
63 CTRL_CLEAR(low); 73 CTRL_CLEAR(low);
64 CTRL_WRITE(low, high, msrs, i); 74 CTRL_WRITE(low, high, msrs, i);
65 } 75 }
66 76
67 /* avoid a false detection of ctr overflows in NMI handler */ 77 /* avoid a false detection of ctr overflows in NMI handler */
68 for (i = 0; i < NUM_COUNTERS; ++i) { 78 for (i = 0; i < NUM_COUNTERS; ++i) {
79 if (unlikely(!CTR_IS_RESERVED(msrs,i)))
80 continue;
69 CTR_WRITE(1, msrs, i); 81 CTR_WRITE(1, msrs, i);
70 } 82 }
71 83
72 /* enable active counters */ 84 /* enable active counters */
73 for (i = 0; i < NUM_COUNTERS; ++i) { 85 for (i = 0; i < NUM_COUNTERS; ++i) {
74 if (counter_config[i].enabled) { 86 if ((counter_config[i].enabled) && (CTR_IS_RESERVED(msrs,i))) {
75 reset_value[i] = counter_config[i].count; 87 reset_value[i] = counter_config[i].count;
76 88
77 CTR_WRITE(counter_config[i].count, msrs, i); 89 CTR_WRITE(counter_config[i].count, msrs, i);
@@ -98,6 +110,8 @@ static int athlon_check_ctrs(struct pt_regs * const regs,
98 int i; 110 int i;
99 111
100 for (i = 0 ; i < NUM_COUNTERS; ++i) { 112 for (i = 0 ; i < NUM_COUNTERS; ++i) {
113 if (!reset_value[i])
114 continue;
101 CTR_READ(low, high, msrs, i); 115 CTR_READ(low, high, msrs, i);
102 if (CTR_OVERFLOWED(low)) { 116 if (CTR_OVERFLOWED(low)) {
103 oprofile_add_sample(regs, i); 117 oprofile_add_sample(regs, i);
@@ -132,12 +146,27 @@ static void athlon_stop(struct op_msrs const * const msrs)
132 /* Subtle: stop on all counters to avoid race with 146 /* Subtle: stop on all counters to avoid race with
133 * setting our pm callback */ 147 * setting our pm callback */
134 for (i = 0 ; i < NUM_COUNTERS ; ++i) { 148 for (i = 0 ; i < NUM_COUNTERS ; ++i) {
149 if (!reset_value[i])
150 continue;
135 CTRL_READ(low, high, msrs, i); 151 CTRL_READ(low, high, msrs, i);
136 CTRL_SET_INACTIVE(low); 152 CTRL_SET_INACTIVE(low);
137 CTRL_WRITE(low, high, msrs, i); 153 CTRL_WRITE(low, high, msrs, i);
138 } 154 }
139} 155}
140 156
157static void athlon_shutdown(struct op_msrs const * const msrs)
158{
159 int i;
160
161 for (i = 0 ; i < NUM_COUNTERS ; ++i) {
162 if (CTR_IS_RESERVED(msrs,i))
163 release_perfctr_nmi(MSR_K7_PERFCTR0 + i);
164 }
165 for (i = 0 ; i < NUM_CONTROLS ; ++i) {
166 if (CTRL_IS_RESERVED(msrs,i))
167 release_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
168 }
169}
141 170
142struct op_x86_model_spec const op_athlon_spec = { 171struct op_x86_model_spec const op_athlon_spec = {
143 .num_counters = NUM_COUNTERS, 172 .num_counters = NUM_COUNTERS,
@@ -146,5 +175,6 @@ struct op_x86_model_spec const op_athlon_spec = {
146 .setup_ctrs = &athlon_setup_ctrs, 175 .setup_ctrs = &athlon_setup_ctrs,
147 .check_ctrs = &athlon_check_ctrs, 176 .check_ctrs = &athlon_check_ctrs,
148 .start = &athlon_start, 177 .start = &athlon_start,
149 .stop = &athlon_stop 178 .stop = &athlon_stop,
179 .shutdown = &athlon_shutdown
150}; 180};
diff --git a/arch/i386/oprofile/op_model_p4.c b/arch/i386/oprofile/op_model_p4.c
index 7c61d357b82b..47925927b12f 100644
--- a/arch/i386/oprofile/op_model_p4.c
+++ b/arch/i386/oprofile/op_model_p4.c
@@ -32,7 +32,7 @@
32#define NUM_CONTROLS_HT2 (NUM_ESCRS_HT2 + NUM_CCCRS_HT2) 32#define NUM_CONTROLS_HT2 (NUM_ESCRS_HT2 + NUM_CCCRS_HT2)
33 33
34static unsigned int num_counters = NUM_COUNTERS_NON_HT; 34static unsigned int num_counters = NUM_COUNTERS_NON_HT;
35 35static unsigned int num_controls = NUM_CONTROLS_NON_HT;
36 36
37/* this has to be checked dynamically since the 37/* this has to be checked dynamically since the
38 hyper-threadedness of a chip is discovered at 38 hyper-threadedness of a chip is discovered at
@@ -40,8 +40,10 @@ static unsigned int num_counters = NUM_COUNTERS_NON_HT;
40static inline void setup_num_counters(void) 40static inline void setup_num_counters(void)
41{ 41{
42#ifdef CONFIG_SMP 42#ifdef CONFIG_SMP
43 if (smp_num_siblings == 2) 43 if (smp_num_siblings == 2){
44 num_counters = NUM_COUNTERS_HT2; 44 num_counters = NUM_COUNTERS_HT2;
45 num_controls = NUM_CONTROLS_HT2;
46 }
45#endif 47#endif
46} 48}
47 49
@@ -97,15 +99,6 @@ static struct p4_counter_binding p4_counters [NUM_COUNTERS_NON_HT] = {
97 99
98#define NUM_UNUSED_CCCRS NUM_CCCRS_NON_HT - NUM_COUNTERS_NON_HT 100#define NUM_UNUSED_CCCRS NUM_CCCRS_NON_HT - NUM_COUNTERS_NON_HT
99 101
100/* All cccr we don't use. */
101static int p4_unused_cccr[NUM_UNUSED_CCCRS] = {
102 MSR_P4_BPU_CCCR1, MSR_P4_BPU_CCCR3,
103 MSR_P4_MS_CCCR1, MSR_P4_MS_CCCR3,
104 MSR_P4_FLAME_CCCR1, MSR_P4_FLAME_CCCR3,
105 MSR_P4_IQ_CCCR0, MSR_P4_IQ_CCCR1,
106 MSR_P4_IQ_CCCR2, MSR_P4_IQ_CCCR3
107};
108
109/* p4 event codes in libop/op_event.h are indices into this table. */ 102/* p4 event codes in libop/op_event.h are indices into this table. */
110 103
111static struct p4_event_binding p4_events[NUM_EVENTS] = { 104static struct p4_event_binding p4_events[NUM_EVENTS] = {
@@ -372,6 +365,8 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = {
372#define CCCR_OVF_P(cccr) ((cccr) & (1U<<31)) 365#define CCCR_OVF_P(cccr) ((cccr) & (1U<<31))
373#define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31))) 366#define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31)))
374 367
368#define CTRL_IS_RESERVED(msrs,c) (msrs->controls[(c)].addr ? 1 : 0)
369#define CTR_IS_RESERVED(msrs,c) (msrs->counters[(c)].addr ? 1 : 0)
375#define CTR_READ(l,h,i) do {rdmsr(p4_counters[(i)].counter_address, (l), (h));} while (0) 370#define CTR_READ(l,h,i) do {rdmsr(p4_counters[(i)].counter_address, (l), (h));} while (0)
376#define CTR_WRITE(l,i) do {wrmsr(p4_counters[(i)].counter_address, -(u32)(l), -1);} while (0) 371#define CTR_WRITE(l,i) do {wrmsr(p4_counters[(i)].counter_address, -(u32)(l), -1);} while (0)
377#define CTR_OVERFLOW_P(ctr) (!((ctr) & 0x80000000)) 372#define CTR_OVERFLOW_P(ctr) (!((ctr) & 0x80000000))
@@ -401,29 +396,34 @@ static unsigned long reset_value[NUM_COUNTERS_NON_HT];
401static void p4_fill_in_addresses(struct op_msrs * const msrs) 396static void p4_fill_in_addresses(struct op_msrs * const msrs)
402{ 397{
403 unsigned int i; 398 unsigned int i;
404 unsigned int addr, stag; 399 unsigned int addr, cccraddr, stag;
405 400
406 setup_num_counters(); 401 setup_num_counters();
407 stag = get_stagger(); 402 stag = get_stagger();
408 403
409 /* the counter registers we pay attention to */ 404 /* initialize some registers */
410 for (i = 0; i < num_counters; ++i) { 405 for (i = 0; i < num_counters; ++i) {
411 msrs->counters[i].addr = 406 msrs->counters[i].addr = 0;
412 p4_counters[VIRT_CTR(stag, i)].counter_address;
413 } 407 }
414 408 for (i = 0; i < num_controls; ++i) {
415 /* FIXME: bad feeling, we don't save the 10 counters we don't use. */ 409 msrs->controls[i].addr = 0;
416
417 /* 18 CCCR registers */
418 for (i = 0, addr = MSR_P4_BPU_CCCR0 + stag;
419 addr <= MSR_P4_IQ_CCCR5; ++i, addr += addr_increment()) {
420 msrs->controls[i].addr = addr;
421 } 410 }
422 411
412 /* the counter & cccr registers we pay attention to */
413 for (i = 0; i < num_counters; ++i) {
414 addr = p4_counters[VIRT_CTR(stag, i)].counter_address;
415 cccraddr = p4_counters[VIRT_CTR(stag, i)].cccr_address;
416 if (reserve_perfctr_nmi(addr)){
417 msrs->counters[i].addr = addr;
418 msrs->controls[i].addr = cccraddr;
419 }
420 }
421
423 /* 43 ESCR registers in three or four discontiguous group */ 422 /* 43 ESCR registers in three or four discontiguous group */
424 for (addr = MSR_P4_BSU_ESCR0 + stag; 423 for (addr = MSR_P4_BSU_ESCR0 + stag;
425 addr < MSR_P4_IQ_ESCR0; ++i, addr += addr_increment()) { 424 addr < MSR_P4_IQ_ESCR0; ++i, addr += addr_increment()) {
426 msrs->controls[i].addr = addr; 425 if (reserve_evntsel_nmi(addr))
426 msrs->controls[i].addr = addr;
427 } 427 }
428 428
429 /* no IQ_ESCR0/1 on some models, we save a seconde time BSU_ESCR0/1 429 /* no IQ_ESCR0/1 on some models, we save a seconde time BSU_ESCR0/1
@@ -431,47 +431,57 @@ static void p4_fill_in_addresses(struct op_msrs * const msrs)
431 if (boot_cpu_data.x86_model >= 0x3) { 431 if (boot_cpu_data.x86_model >= 0x3) {
432 for (addr = MSR_P4_BSU_ESCR0 + stag; 432 for (addr = MSR_P4_BSU_ESCR0 + stag;
433 addr <= MSR_P4_BSU_ESCR1; ++i, addr += addr_increment()) { 433 addr <= MSR_P4_BSU_ESCR1; ++i, addr += addr_increment()) {
434 msrs->controls[i].addr = addr; 434 if (reserve_evntsel_nmi(addr))
435 msrs->controls[i].addr = addr;
435 } 436 }
436 } else { 437 } else {
437 for (addr = MSR_P4_IQ_ESCR0 + stag; 438 for (addr = MSR_P4_IQ_ESCR0 + stag;
438 addr <= MSR_P4_IQ_ESCR1; ++i, addr += addr_increment()) { 439 addr <= MSR_P4_IQ_ESCR1; ++i, addr += addr_increment()) {
439 msrs->controls[i].addr = addr; 440 if (reserve_evntsel_nmi(addr))
441 msrs->controls[i].addr = addr;
440 } 442 }
441 } 443 }
442 444
443 for (addr = MSR_P4_RAT_ESCR0 + stag; 445 for (addr = MSR_P4_RAT_ESCR0 + stag;
444 addr <= MSR_P4_SSU_ESCR0; ++i, addr += addr_increment()) { 446 addr <= MSR_P4_SSU_ESCR0; ++i, addr += addr_increment()) {
445 msrs->controls[i].addr = addr; 447 if (reserve_evntsel_nmi(addr))
448 msrs->controls[i].addr = addr;
446 } 449 }
447 450
448 for (addr = MSR_P4_MS_ESCR0 + stag; 451 for (addr = MSR_P4_MS_ESCR0 + stag;
449 addr <= MSR_P4_TC_ESCR1; ++i, addr += addr_increment()) { 452 addr <= MSR_P4_TC_ESCR1; ++i, addr += addr_increment()) {
450 msrs->controls[i].addr = addr; 453 if (reserve_evntsel_nmi(addr))
454 msrs->controls[i].addr = addr;
451 } 455 }
452 456
453 for (addr = MSR_P4_IX_ESCR0 + stag; 457 for (addr = MSR_P4_IX_ESCR0 + stag;
454 addr <= MSR_P4_CRU_ESCR3; ++i, addr += addr_increment()) { 458 addr <= MSR_P4_CRU_ESCR3; ++i, addr += addr_increment()) {
455 msrs->controls[i].addr = addr; 459 if (reserve_evntsel_nmi(addr))
460 msrs->controls[i].addr = addr;
456 } 461 }
457 462
458 /* there are 2 remaining non-contiguously located ESCRs */ 463 /* there are 2 remaining non-contiguously located ESCRs */
459 464
460 if (num_counters == NUM_COUNTERS_NON_HT) { 465 if (num_counters == NUM_COUNTERS_NON_HT) {
461 /* standard non-HT CPUs handle both remaining ESCRs*/ 466 /* standard non-HT CPUs handle both remaining ESCRs*/
462 msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; 467 if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR5))
463 msrs->controls[i++].addr = MSR_P4_CRU_ESCR4; 468 msrs->controls[i++].addr = MSR_P4_CRU_ESCR5;
469 if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR4))
470 msrs->controls[i++].addr = MSR_P4_CRU_ESCR4;
464 471
465 } else if (stag == 0) { 472 } else if (stag == 0) {
466 /* HT CPUs give the first remainder to the even thread, as 473 /* HT CPUs give the first remainder to the even thread, as
467 the 32nd control register */ 474 the 32nd control register */
468 msrs->controls[i++].addr = MSR_P4_CRU_ESCR4; 475 if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR4))
476 msrs->controls[i++].addr = MSR_P4_CRU_ESCR4;
469 477
470 } else { 478 } else {
471 /* and two copies of the second to the odd thread, 479 /* and two copies of the second to the odd thread,
472 for the 22st and 23nd control registers */ 480 for the 22st and 23nd control registers */
473 msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; 481 if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR5)) {
474 msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; 482 msrs->controls[i++].addr = MSR_P4_CRU_ESCR5;
483 msrs->controls[i++].addr = MSR_P4_CRU_ESCR5;
484 }
475 } 485 }
476} 486}
477 487
@@ -544,7 +554,6 @@ static void p4_setup_ctrs(struct op_msrs const * const msrs)
544{ 554{
545 unsigned int i; 555 unsigned int i;
546 unsigned int low, high; 556 unsigned int low, high;
547 unsigned int addr;
548 unsigned int stag; 557 unsigned int stag;
549 558
550 stag = get_stagger(); 559 stag = get_stagger();
@@ -557,59 +566,24 @@ static void p4_setup_ctrs(struct op_msrs const * const msrs)
557 566
558 /* clear the cccrs we will use */ 567 /* clear the cccrs we will use */
559 for (i = 0 ; i < num_counters ; i++) { 568 for (i = 0 ; i < num_counters ; i++) {
569 if (unlikely(!CTRL_IS_RESERVED(msrs,i)))
570 continue;
560 rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high); 571 rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high);
561 CCCR_CLEAR(low); 572 CCCR_CLEAR(low);
562 CCCR_SET_REQUIRED_BITS(low); 573 CCCR_SET_REQUIRED_BITS(low);
563 wrmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high); 574 wrmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high);
564 } 575 }
565 576
566 /* clear cccrs outside our concern */
567 for (i = stag ; i < NUM_UNUSED_CCCRS ; i += addr_increment()) {
568 rdmsr(p4_unused_cccr[i], low, high);
569 CCCR_CLEAR(low);
570 CCCR_SET_REQUIRED_BITS(low);
571 wrmsr(p4_unused_cccr[i], low, high);
572 }
573
574 /* clear all escrs (including those outside our concern) */ 577 /* clear all escrs (including those outside our concern) */
575 for (addr = MSR_P4_BSU_ESCR0 + stag; 578 for (i = num_counters; i < num_controls; i++) {
576 addr < MSR_P4_IQ_ESCR0; addr += addr_increment()) { 579 if (unlikely(!CTRL_IS_RESERVED(msrs,i)))
577 wrmsr(addr, 0, 0); 580 continue;
578 } 581 wrmsr(msrs->controls[i].addr, 0, 0);
579
580 /* On older models clear also MSR_P4_IQ_ESCR0/1 */
581 if (boot_cpu_data.x86_model < 0x3) {
582 wrmsr(MSR_P4_IQ_ESCR0, 0, 0);
583 wrmsr(MSR_P4_IQ_ESCR1, 0, 0);
584 }
585
586 for (addr = MSR_P4_RAT_ESCR0 + stag;
587 addr <= MSR_P4_SSU_ESCR0; ++i, addr += addr_increment()) {
588 wrmsr(addr, 0, 0);
589 }
590
591 for (addr = MSR_P4_MS_ESCR0 + stag;
592 addr <= MSR_P4_TC_ESCR1; addr += addr_increment()){
593 wrmsr(addr, 0, 0);
594 }
595
596 for (addr = MSR_P4_IX_ESCR0 + stag;
597 addr <= MSR_P4_CRU_ESCR3; addr += addr_increment()){
598 wrmsr(addr, 0, 0);
599 } 582 }
600 583
601 if (num_counters == NUM_COUNTERS_NON_HT) {
602 wrmsr(MSR_P4_CRU_ESCR4, 0, 0);
603 wrmsr(MSR_P4_CRU_ESCR5, 0, 0);
604 } else if (stag == 0) {
605 wrmsr(MSR_P4_CRU_ESCR4, 0, 0);
606 } else {
607 wrmsr(MSR_P4_CRU_ESCR5, 0, 0);
608 }
609
610 /* setup all counters */ 584 /* setup all counters */
611 for (i = 0 ; i < num_counters ; ++i) { 585 for (i = 0 ; i < num_counters ; ++i) {
612 if (counter_config[i].enabled) { 586 if ((counter_config[i].enabled) && (CTRL_IS_RESERVED(msrs,i))) {
613 reset_value[i] = counter_config[i].count; 587 reset_value[i] = counter_config[i].count;
614 pmc_setup_one_p4_counter(i); 588 pmc_setup_one_p4_counter(i);
615 CTR_WRITE(counter_config[i].count, VIRT_CTR(stag, i)); 589 CTR_WRITE(counter_config[i].count, VIRT_CTR(stag, i));
@@ -696,12 +670,32 @@ static void p4_stop(struct op_msrs const * const msrs)
696 stag = get_stagger(); 670 stag = get_stagger();
697 671
698 for (i = 0; i < num_counters; ++i) { 672 for (i = 0; i < num_counters; ++i) {
673 if (!reset_value[i])
674 continue;
699 CCCR_READ(low, high, VIRT_CTR(stag, i)); 675 CCCR_READ(low, high, VIRT_CTR(stag, i));
700 CCCR_SET_DISABLE(low); 676 CCCR_SET_DISABLE(low);
701 CCCR_WRITE(low, high, VIRT_CTR(stag, i)); 677 CCCR_WRITE(low, high, VIRT_CTR(stag, i));
702 } 678 }
703} 679}
704 680
681static void p4_shutdown(struct op_msrs const * const msrs)
682{
683 int i;
684
685 for (i = 0 ; i < num_counters ; ++i) {
686 if (CTR_IS_RESERVED(msrs,i))
687 release_perfctr_nmi(msrs->counters[i].addr);
688 }
689 /* some of the control registers are specially reserved in
690 * conjunction with the counter registers (hence the starting offset).
691 * This saves a few bits.
692 */
693 for (i = num_counters ; i < num_controls ; ++i) {
694 if (CTRL_IS_RESERVED(msrs,i))
695 release_evntsel_nmi(msrs->controls[i].addr);
696 }
697}
698
705 699
706#ifdef CONFIG_SMP 700#ifdef CONFIG_SMP
707struct op_x86_model_spec const op_p4_ht2_spec = { 701struct op_x86_model_spec const op_p4_ht2_spec = {
@@ -711,7 +705,8 @@ struct op_x86_model_spec const op_p4_ht2_spec = {
711 .setup_ctrs = &p4_setup_ctrs, 705 .setup_ctrs = &p4_setup_ctrs,
712 .check_ctrs = &p4_check_ctrs, 706 .check_ctrs = &p4_check_ctrs,
713 .start = &p4_start, 707 .start = &p4_start,
714 .stop = &p4_stop 708 .stop = &p4_stop,
709 .shutdown = &p4_shutdown
715}; 710};
716#endif 711#endif
717 712
@@ -722,5 +717,6 @@ struct op_x86_model_spec const op_p4_spec = {
722 .setup_ctrs = &p4_setup_ctrs, 717 .setup_ctrs = &p4_setup_ctrs,
723 .check_ctrs = &p4_check_ctrs, 718 .check_ctrs = &p4_check_ctrs,
724 .start = &p4_start, 719 .start = &p4_start,
725 .stop = &p4_stop 720 .stop = &p4_stop,
721 .shutdown = &p4_shutdown
726}; 722};
diff --git a/arch/i386/oprofile/op_model_ppro.c b/arch/i386/oprofile/op_model_ppro.c
index 5c3ab4b027ad..f88e05ba8eb3 100644
--- a/arch/i386/oprofile/op_model_ppro.c
+++ b/arch/i386/oprofile/op_model_ppro.c
@@ -22,10 +22,12 @@
22#define NUM_COUNTERS 2 22#define NUM_COUNTERS 2
23#define NUM_CONTROLS 2 23#define NUM_CONTROLS 2
24 24
25#define CTR_IS_RESERVED(msrs,c) (msrs->counters[(c)].addr ? 1 : 0)
25#define CTR_READ(l,h,msrs,c) do {rdmsr(msrs->counters[(c)].addr, (l), (h));} while (0) 26#define CTR_READ(l,h,msrs,c) do {rdmsr(msrs->counters[(c)].addr, (l), (h));} while (0)
26#define CTR_WRITE(l,msrs,c) do {wrmsr(msrs->counters[(c)].addr, -(u32)(l), -1);} while (0) 27#define CTR_WRITE(l,msrs,c) do {wrmsr(msrs->counters[(c)].addr, -(u32)(l), -1);} while (0)
27#define CTR_OVERFLOWED(n) (!((n) & (1U<<31))) 28#define CTR_OVERFLOWED(n) (!((n) & (1U<<31)))
28 29
30#define CTRL_IS_RESERVED(msrs,c) (msrs->controls[(c)].addr ? 1 : 0)
29#define CTRL_READ(l,h,msrs,c) do {rdmsr((msrs->controls[(c)].addr), (l), (h));} while (0) 31#define CTRL_READ(l,h,msrs,c) do {rdmsr((msrs->controls[(c)].addr), (l), (h));} while (0)
30#define CTRL_WRITE(l,h,msrs,c) do {wrmsr((msrs->controls[(c)].addr), (l), (h));} while (0) 32#define CTRL_WRITE(l,h,msrs,c) do {wrmsr((msrs->controls[(c)].addr), (l), (h));} while (0)
31#define CTRL_SET_ACTIVE(n) (n |= (1<<22)) 33#define CTRL_SET_ACTIVE(n) (n |= (1<<22))
@@ -41,11 +43,21 @@ static unsigned long reset_value[NUM_COUNTERS];
41 43
42static void ppro_fill_in_addresses(struct op_msrs * const msrs) 44static void ppro_fill_in_addresses(struct op_msrs * const msrs)
43{ 45{
44 msrs->counters[0].addr = MSR_P6_PERFCTR0; 46 int i;
45 msrs->counters[1].addr = MSR_P6_PERFCTR1; 47
48 for (i=0; i < NUM_COUNTERS; i++) {
49 if (reserve_perfctr_nmi(MSR_P6_PERFCTR0 + i))
50 msrs->counters[i].addr = MSR_P6_PERFCTR0 + i;
51 else
52 msrs->counters[i].addr = 0;
53 }
46 54
47 msrs->controls[0].addr = MSR_P6_EVNTSEL0; 55 for (i=0; i < NUM_CONTROLS; i++) {
48 msrs->controls[1].addr = MSR_P6_EVNTSEL1; 56 if (reserve_evntsel_nmi(MSR_P6_EVNTSEL0 + i))
57 msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i;
58 else
59 msrs->controls[i].addr = 0;
60 }
49} 61}
50 62
51 63
@@ -56,6 +68,8 @@ static void ppro_setup_ctrs(struct op_msrs const * const msrs)
56 68
57 /* clear all counters */ 69 /* clear all counters */
58 for (i = 0 ; i < NUM_CONTROLS; ++i) { 70 for (i = 0 ; i < NUM_CONTROLS; ++i) {
71 if (unlikely(!CTRL_IS_RESERVED(msrs,i)))
72 continue;
59 CTRL_READ(low, high, msrs, i); 73 CTRL_READ(low, high, msrs, i);
60 CTRL_CLEAR(low); 74 CTRL_CLEAR(low);
61 CTRL_WRITE(low, high, msrs, i); 75 CTRL_WRITE(low, high, msrs, i);
@@ -63,12 +77,14 @@ static void ppro_setup_ctrs(struct op_msrs const * const msrs)
63 77
64 /* avoid a false detection of ctr overflows in NMI handler */ 78 /* avoid a false detection of ctr overflows in NMI handler */
65 for (i = 0; i < NUM_COUNTERS; ++i) { 79 for (i = 0; i < NUM_COUNTERS; ++i) {
80 if (unlikely(!CTR_IS_RESERVED(msrs,i)))
81 continue;
66 CTR_WRITE(1, msrs, i); 82 CTR_WRITE(1, msrs, i);
67 } 83 }
68 84
69 /* enable active counters */ 85 /* enable active counters */
70 for (i = 0; i < NUM_COUNTERS; ++i) { 86 for (i = 0; i < NUM_COUNTERS; ++i) {
71 if (counter_config[i].enabled) { 87 if ((counter_config[i].enabled) && (CTR_IS_RESERVED(msrs,i))) {
72 reset_value[i] = counter_config[i].count; 88 reset_value[i] = counter_config[i].count;
73 89
74 CTR_WRITE(counter_config[i].count, msrs, i); 90 CTR_WRITE(counter_config[i].count, msrs, i);
@@ -81,6 +97,8 @@ static void ppro_setup_ctrs(struct op_msrs const * const msrs)
81 CTRL_SET_UM(low, counter_config[i].unit_mask); 97 CTRL_SET_UM(low, counter_config[i].unit_mask);
82 CTRL_SET_EVENT(low, counter_config[i].event); 98 CTRL_SET_EVENT(low, counter_config[i].event);
83 CTRL_WRITE(low, high, msrs, i); 99 CTRL_WRITE(low, high, msrs, i);
100 } else {
101 reset_value[i] = 0;
84 } 102 }
85 } 103 }
86} 104}
@@ -93,6 +111,8 @@ static int ppro_check_ctrs(struct pt_regs * const regs,
93 int i; 111 int i;
94 112
95 for (i = 0 ; i < NUM_COUNTERS; ++i) { 113 for (i = 0 ; i < NUM_COUNTERS; ++i) {
114 if (!reset_value[i])
115 continue;
96 CTR_READ(low, high, msrs, i); 116 CTR_READ(low, high, msrs, i);
97 if (CTR_OVERFLOWED(low)) { 117 if (CTR_OVERFLOWED(low)) {
98 oprofile_add_sample(regs, i); 118 oprofile_add_sample(regs, i);
@@ -118,18 +138,38 @@ static int ppro_check_ctrs(struct pt_regs * const regs,
118static void ppro_start(struct op_msrs const * const msrs) 138static void ppro_start(struct op_msrs const * const msrs)
119{ 139{
120 unsigned int low,high; 140 unsigned int low,high;
121 CTRL_READ(low, high, msrs, 0); 141
122 CTRL_SET_ACTIVE(low); 142 if (reset_value[0]) {
123 CTRL_WRITE(low, high, msrs, 0); 143 CTRL_READ(low, high, msrs, 0);
144 CTRL_SET_ACTIVE(low);
145 CTRL_WRITE(low, high, msrs, 0);
146 }
124} 147}
125 148
126 149
127static void ppro_stop(struct op_msrs const * const msrs) 150static void ppro_stop(struct op_msrs const * const msrs)
128{ 151{
129 unsigned int low,high; 152 unsigned int low,high;
130 CTRL_READ(low, high, msrs, 0); 153
131 CTRL_SET_INACTIVE(low); 154 if (reset_value[0]) {
132 CTRL_WRITE(low, high, msrs, 0); 155 CTRL_READ(low, high, msrs, 0);
156 CTRL_SET_INACTIVE(low);
157 CTRL_WRITE(low, high, msrs, 0);
158 }
159}
160
161static void ppro_shutdown(struct op_msrs const * const msrs)
162{
163 int i;
164
165 for (i = 0 ; i < NUM_COUNTERS ; ++i) {
166 if (CTR_IS_RESERVED(msrs,i))
167 release_perfctr_nmi(MSR_P6_PERFCTR0 + i);
168 }
169 for (i = 0 ; i < NUM_CONTROLS ; ++i) {
170 if (CTRL_IS_RESERVED(msrs,i))
171 release_evntsel_nmi(MSR_P6_EVNTSEL0 + i);
172 }
133} 173}
134 174
135 175
@@ -140,5 +180,6 @@ struct op_x86_model_spec const op_ppro_spec = {
140 .setup_ctrs = &ppro_setup_ctrs, 180 .setup_ctrs = &ppro_setup_ctrs,
141 .check_ctrs = &ppro_check_ctrs, 181 .check_ctrs = &ppro_check_ctrs,
142 .start = &ppro_start, 182 .start = &ppro_start,
143 .stop = &ppro_stop 183 .stop = &ppro_stop,
184 .shutdown = &ppro_shutdown
144}; 185};
diff --git a/arch/i386/oprofile/op_x86_model.h b/arch/i386/oprofile/op_x86_model.h
index 123b7e90a9ee..abb1aa95b979 100644
--- a/arch/i386/oprofile/op_x86_model.h
+++ b/arch/i386/oprofile/op_x86_model.h
@@ -40,6 +40,7 @@ struct op_x86_model_spec {
40 struct op_msrs const * const msrs); 40 struct op_msrs const * const msrs);
41 void (*start)(struct op_msrs const * const msrs); 41 void (*start)(struct op_msrs const * const msrs);
42 void (*stop)(struct op_msrs const * const msrs); 42 void (*stop)(struct op_msrs const * const msrs);
43 void (*shutdown)(struct op_msrs const * const msrs);
43}; 44};
44 45
45extern struct op_x86_model_spec const op_ppro_spec; 46extern struct op_x86_model_spec const op_ppro_spec;
diff --git a/arch/i386/pci/Makefile b/arch/i386/pci/Makefile
index 62ad75c57e6a..1594d2f55c8f 100644
--- a/arch/i386/pci/Makefile
+++ b/arch/i386/pci/Makefile
@@ -11,4 +11,4 @@ pci-y += legacy.o irq.o
11pci-$(CONFIG_X86_VISWS) := visws.o fixup.o 11pci-$(CONFIG_X86_VISWS) := visws.o fixup.o
12pci-$(CONFIG_X86_NUMAQ) := numa.o irq.o 12pci-$(CONFIG_X86_NUMAQ) := numa.o irq.o
13 13
14obj-y += $(pci-y) common.o 14obj-y += $(pci-y) common.o early.o
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c
index 0a362e3aeac5..68bce194e688 100644
--- a/arch/i386/pci/common.c
+++ b/arch/i386/pci/common.c
@@ -242,6 +242,10 @@ char * __devinit pcibios_setup(char *str)
242 acpi_noirq_set(); 242 acpi_noirq_set();
243 return NULL; 243 return NULL;
244 } 244 }
245 else if (!strcmp(str, "noearly")) {
246 pci_probe |= PCI_PROBE_NOEARLY;
247 return NULL;
248 }
245#ifndef CONFIG_X86_VISWS 249#ifndef CONFIG_X86_VISWS
246 else if (!strcmp(str, "usepirqmask")) { 250 else if (!strcmp(str, "usepirqmask")) {
247 pci_probe |= PCI_USE_PIRQ_MASK; 251 pci_probe |= PCI_USE_PIRQ_MASK;
diff --git a/arch/i386/pci/direct.c b/arch/i386/pci/direct.c
index 5d81fb510375..5acf0b4743cf 100644
--- a/arch/i386/pci/direct.c
+++ b/arch/i386/pci/direct.c
@@ -254,7 +254,16 @@ static int __init pci_check_type2(void)
254 return works; 254 return works;
255} 255}
256 256
257void __init pci_direct_init(void) 257void __init pci_direct_init(int type)
258{
259 printk(KERN_INFO "PCI: Using configuration type %d\n", type);
260 if (type == 1)
261 raw_pci_ops = &pci_direct_conf1;
262 else
263 raw_pci_ops = &pci_direct_conf2;
264}
265
266int __init pci_direct_probe(void)
258{ 267{
259 struct resource *region, *region2; 268 struct resource *region, *region2;
260 269
@@ -264,19 +273,16 @@ void __init pci_direct_init(void)
264 if (!region) 273 if (!region)
265 goto type2; 274 goto type2;
266 275
267 if (pci_check_type1()) { 276 if (pci_check_type1())
268 printk(KERN_INFO "PCI: Using configuration type 1\n"); 277 return 1;
269 raw_pci_ops = &pci_direct_conf1;
270 return;
271 }
272 release_resource(region); 278 release_resource(region);
273 279
274 type2: 280 type2:
275 if ((pci_probe & PCI_PROBE_CONF2) == 0) 281 if ((pci_probe & PCI_PROBE_CONF2) == 0)
276 return; 282 return 0;
277 region = request_region(0xCF8, 4, "PCI conf2"); 283 region = request_region(0xCF8, 4, "PCI conf2");
278 if (!region) 284 if (!region)
279 return; 285 return 0;
280 region2 = request_region(0xC000, 0x1000, "PCI conf2"); 286 region2 = request_region(0xC000, 0x1000, "PCI conf2");
281 if (!region2) 287 if (!region2)
282 goto fail2; 288 goto fail2;
@@ -284,10 +290,11 @@ void __init pci_direct_init(void)
284 if (pci_check_type2()) { 290 if (pci_check_type2()) {
285 printk(KERN_INFO "PCI: Using configuration type 2\n"); 291 printk(KERN_INFO "PCI: Using configuration type 2\n");
286 raw_pci_ops = &pci_direct_conf2; 292 raw_pci_ops = &pci_direct_conf2;
287 return; 293 return 2;
288 } 294 }
289 295
290 release_resource(region2); 296 release_resource(region2);
291 fail2: 297 fail2:
292 release_resource(region); 298 release_resource(region);
299 return 0;
293} 300}
diff --git a/arch/i386/pci/early.c b/arch/i386/pci/early.c
new file mode 100644
index 000000000000..713d6c866cae
--- /dev/null
+++ b/arch/i386/pci/early.c
@@ -0,0 +1,52 @@
1#include <linux/kernel.h>
2#include <linux/pci.h>
3#include <asm/pci-direct.h>
4#include <asm/io.h>
5#include "pci.h"
6
7/* Direct PCI access. This is used for PCI accesses in early boot before
8 the PCI subsystem works. */
9
10#define PDprintk(x...)
11
12u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
13{
14 u32 v;
15 outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
16 v = inl(0xcfc);
17 if (v != 0xffffffff)
18 PDprintk("%x reading 4 from %x: %x\n", slot, offset, v);
19 return v;
20}
21
22u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset)
23{
24 u8 v;
25 outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
26 v = inb(0xcfc + (offset&3));
27 PDprintk("%x reading 1 from %x: %x\n", slot, offset, v);
28 return v;
29}
30
31u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset)
32{
33 u16 v;
34 outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
35 v = inw(0xcfc + (offset&2));
36 PDprintk("%x reading 2 from %x: %x\n", slot, offset, v);
37 return v;
38}
39
40void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset,
41 u32 val)
42{
43 PDprintk("%x writing to %x: %x\n", slot, offset, val);
44 outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
45 outl(val, 0xcfc);
46}
47
48int early_pci_allowed(void)
49{
50 return (pci_probe & (PCI_PROBE_CONF1|PCI_PROBE_NOEARLY)) ==
51 PCI_PROBE_CONF1;
52}
diff --git a/arch/i386/pci/init.c b/arch/i386/pci/init.c
index 51087a9d9172..d028e1b05c36 100644
--- a/arch/i386/pci/init.c
+++ b/arch/i386/pci/init.c
@@ -6,8 +6,13 @@
6 in the right sequence from here. */ 6 in the right sequence from here. */
7static __init int pci_access_init(void) 7static __init int pci_access_init(void)
8{ 8{
9 int type = 0;
10
11#ifdef CONFIG_PCI_DIRECT
12 type = pci_direct_probe();
13#endif
9#ifdef CONFIG_PCI_MMCONFIG 14#ifdef CONFIG_PCI_MMCONFIG
10 pci_mmcfg_init(); 15 pci_mmcfg_init(type);
11#endif 16#endif
12 if (raw_pci_ops) 17 if (raw_pci_ops)
13 return 0; 18 return 0;
@@ -21,7 +26,7 @@ static __init int pci_access_init(void)
21 * fails. 26 * fails.
22 */ 27 */
23#ifdef CONFIG_PCI_DIRECT 28#ifdef CONFIG_PCI_DIRECT
24 pci_direct_init(); 29 pci_direct_init(type);
25#endif 30#endif
26 return 0; 31 return 0;
27} 32}
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c
index 972180f738d9..05be8db58a8c 100644
--- a/arch/i386/pci/mmconfig.c
+++ b/arch/i386/pci/mmconfig.c
@@ -151,6 +151,38 @@ static struct pci_raw_ops pci_mmcfg = {
151 .write = pci_mmcfg_write, 151 .write = pci_mmcfg_write,
152}; 152};
153 153
154
155static __init void pci_mmcfg_insert_resources(void)
156{
157#define PCI_MMCFG_RESOURCE_NAME_LEN 19
158 int i;
159 struct resource *res;
160 char *names;
161 unsigned num_buses;
162
163 res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res),
164 pci_mmcfg_config_num, GFP_KERNEL);
165
166 if (!res) {
167 printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n");
168 return;
169 }
170
171 names = (void *)&res[pci_mmcfg_config_num];
172 for (i = 0; i < pci_mmcfg_config_num; i++, res++) {
173 num_buses = pci_mmcfg_config[i].end_bus_number -
174 pci_mmcfg_config[i].start_bus_number + 1;
175 res->name = names;
176 snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u",
177 pci_mmcfg_config[i].pci_segment_group_number);
178 res->start = pci_mmcfg_config[i].base_address;
179 res->end = res->start + (num_buses << 20) - 1;
180 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
181 insert_resource(&iomem_resource, res);
182 names += PCI_MMCFG_RESOURCE_NAME_LEN;
183 }
184}
185
154/* K8 systems have some devices (typically in the builtin northbridge) 186/* K8 systems have some devices (typically in the builtin northbridge)
155 that are only accessible using type1 187 that are only accessible using type1
156 Normally this can be expressed in the MCFG by not listing them 188 Normally this can be expressed in the MCFG by not listing them
@@ -187,7 +219,9 @@ static __init void unreachable_devices(void)
187 } 219 }
188} 220}
189 221
190void __init pci_mmcfg_init(void) 222
223
224void __init pci_mmcfg_init(int type)
191{ 225{
192 if ((pci_probe & PCI_PROBE_MMCONF) == 0) 226 if ((pci_probe & PCI_PROBE_MMCONF) == 0)
193 return; 227 return;
@@ -198,7 +232,9 @@ void __init pci_mmcfg_init(void)
198 (pci_mmcfg_config[0].base_address == 0)) 232 (pci_mmcfg_config[0].base_address == 0))
199 return; 233 return;
200 234
201 if (!e820_all_mapped(pci_mmcfg_config[0].base_address, 235 /* Only do this check when type 1 works. If it doesn't work
236 assume we run on a Mac and always use MCFG */
237 if (type == 1 && !e820_all_mapped(pci_mmcfg_config[0].base_address,
202 pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, 238 pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN,
203 E820_RESERVED)) { 239 E820_RESERVED)) {
204 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", 240 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n",
@@ -212,4 +248,5 @@ void __init pci_mmcfg_init(void)
212 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; 248 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
213 249
214 unreachable_devices(); 250 unreachable_devices();
251 pci_mmcfg_insert_resources();
215} 252}
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h
index bf4e79335388..1814f74569c6 100644
--- a/arch/i386/pci/pci.h
+++ b/arch/i386/pci/pci.h
@@ -17,6 +17,7 @@
17#define PCI_PROBE_CONF2 0x0004 17#define PCI_PROBE_CONF2 0x0004
18#define PCI_PROBE_MMCONF 0x0008 18#define PCI_PROBE_MMCONF 0x0008
19#define PCI_PROBE_MASK 0x000f 19#define PCI_PROBE_MASK 0x000f
20#define PCI_PROBE_NOEARLY 0x0010
20 21
21#define PCI_NO_SORT 0x0100 22#define PCI_NO_SORT 0x0100
22#define PCI_BIOS_SORT 0x0200 23#define PCI_BIOS_SORT 0x0200
@@ -81,7 +82,9 @@ extern int pci_conf1_write(unsigned int seg, unsigned int bus,
81extern int pci_conf1_read(unsigned int seg, unsigned int bus, 82extern int pci_conf1_read(unsigned int seg, unsigned int bus,
82 unsigned int devfn, int reg, int len, u32 *value); 83 unsigned int devfn, int reg, int len, u32 *value);
83 84
84extern void pci_direct_init(void); 85extern int pci_direct_probe(void);
86extern void pci_direct_init(int type);
85extern void pci_pcbios_init(void); 87extern void pci_pcbios_init(void);
86extern void pci_mmcfg_init(void); 88extern void pci_mmcfg_init(int type);
87extern void pcibios_sort(void); 89extern void pcibios_sort(void);
90
diff --git a/arch/i386/power/swsusp.S b/arch/i386/power/swsusp.S
index c893b897217f..8a2b50a0aaad 100644
--- a/arch/i386/power/swsusp.S
+++ b/arch/i386/power/swsusp.S
@@ -32,7 +32,7 @@ ENTRY(swsusp_arch_resume)
32 movl $swsusp_pg_dir-__PAGE_OFFSET, %ecx 32 movl $swsusp_pg_dir-__PAGE_OFFSET, %ecx
33 movl %ecx, %cr3 33 movl %ecx, %cr3
34 34
35 movl pagedir_nosave, %edx 35 movl restore_pblist, %edx
36 .p2align 4,,7 36 .p2align 4,,7
37 37
38copy_loop: 38copy_loop:
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index db274da7dba1..0b7f701d5cf7 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -66,15 +66,6 @@ config IA64_UNCACHED_ALLOCATOR
66 bool 66 bool
67 select GENERIC_ALLOCATOR 67 select GENERIC_ALLOCATOR
68 68
69config DMA_IS_DMA32
70 bool
71 default y
72
73config DMA_IS_NORMAL
74 bool
75 depends on IA64_SGI_SN2
76 default y
77
78config AUDIT_ARCH 69config AUDIT_ARCH
79 bool 70 bool
80 default y 71 default y
@@ -365,6 +356,9 @@ config NODES_SHIFT
365 MAX_NUMNODES will be 2^(This value). 356 MAX_NUMNODES will be 2^(This value).
366 If in doubt, use the default. 357 If in doubt, use the default.
367 358
359config ARCH_POPULATES_NODE_MAP
360 def_bool y
361
368# VIRTUAL_MEM_MAP and FLAT_NODE_MEM_MAP are functionally equivalent. 362# VIRTUAL_MEM_MAP and FLAT_NODE_MEM_MAP are functionally equivalent.
369# VIRTUAL_MEM_MAP has been retained for historical reasons. 363# VIRTUAL_MEM_MAP has been retained for historical reasons.
370config VIRTUAL_MEM_MAP 364config VIRTUAL_MEM_MAP
@@ -429,6 +423,14 @@ config IA64_PALINFO
429config SGI_SN 423config SGI_SN
430 def_bool y if (IA64_SGI_SN2 || IA64_GENERIC) 424 def_bool y if (IA64_SGI_SN2 || IA64_GENERIC)
431 425
426config IA64_ESI
427 bool "ESI (Extensible SAL Interface) support"
428 help
429 If you say Y here, support is built into the kernel to
430 make ESI calls. ESI calls are used to support vendor-specific
431 firmware extensions, such as the ability to inject memory-errors
432 for test-purposes. If you're unsure, say N.
433
432source "drivers/sn/Kconfig" 434source "drivers/sn/Kconfig"
433 435
434source "drivers/firmware/Kconfig" 436source "drivers/firmware/Kconfig"
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index 6aa3c51619ca..bddbd22706ed 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -1942,7 +1942,7 @@ struct sysctl32 {
1942 unsigned int __unused[4]; 1942 unsigned int __unused[4];
1943}; 1943};
1944 1944
1945#ifdef CONFIG_SYSCTL 1945#ifdef CONFIG_SYSCTL_SYSCALL
1946asmlinkage long 1946asmlinkage long
1947sys32_sysctl (struct sysctl32 __user *args) 1947sys32_sysctl (struct sysctl32 __user *args)
1948{ 1948{
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index ad8215a3c586..31497496eb4b 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -32,6 +32,11 @@ obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o
32obj-$(CONFIG_AUDIT) += audit.o 32obj-$(CONFIG_AUDIT) += audit.o
33mca_recovery-y += mca_drv.o mca_drv_asm.o 33mca_recovery-y += mca_drv.o mca_drv_asm.o
34 34
35obj-$(CONFIG_IA64_ESI) += esi.o
36ifneq ($(CONFIG_IA64_ESI),)
37obj-y += esi_stub.o # must be in kernel proper
38endif
39
35# The gate DSO image is built using a special linker script. 40# The gate DSO image is built using a special linker script.
36targets += gate.so gate-syms.o 41targets += gate.so gate-syms.o
37 42
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 0176556aeecc..32c3abededc6 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -771,16 +771,19 @@ int acpi_map_cpu2node(acpi_handle handle, int cpu, long physid)
771{ 771{
772#ifdef CONFIG_ACPI_NUMA 772#ifdef CONFIG_ACPI_NUMA
773 int pxm_id; 773 int pxm_id;
774 int nid;
774 775
775 pxm_id = acpi_get_pxm(handle); 776 pxm_id = acpi_get_pxm(handle);
776
777 /* 777 /*
778 * Assuming that the container driver would have set the proximity 778 * We don't have cpu-only-node hotadd. But if the system equips
779 * domain and would have initialized pxm_to_node(pxm_id) && pxm_flag 779 * SRAT table, pxm is already found and node is ready.
780 * So, just pxm_to_nid(pxm) is OK.
781 * This code here is for the system which doesn't have full SRAT
782 * table for possible cpus.
780 */ 783 */
781 node_cpuid[cpu].nid = (pxm_id < 0) ? 0 : pxm_to_node(pxm_id); 784 nid = acpi_map_pxm_to_node(pxm_id);
782
783 node_cpuid[cpu].phys_id = physid; 785 node_cpuid[cpu].phys_id = physid;
786 node_cpuid[cpu].nid = nid;
784#endif 787#endif
785 return (0); 788 return (0);
786} 789}
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index fef06571be99..12701cf32d99 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1605,8 +1605,8 @@ sys_call_table:
1605 data8 sys_ni_syscall // 1295 reserved for ppoll 1605 data8 sys_ni_syscall // 1295 reserved for ppoll
1606 data8 sys_unshare 1606 data8 sys_unshare
1607 data8 sys_splice 1607 data8 sys_splice
1608 data8 sys_ni_syscall // reserved for set_robust_list 1608 data8 sys_set_robust_list
1609 data8 sys_ni_syscall // reserved for get_robust_list 1609 data8 sys_get_robust_list
1610 data8 sys_sync_file_range // 1300 1610 data8 sys_sync_file_range // 1300
1611 data8 sys_tee 1611 data8 sys_tee
1612 data8 sys_vmsplice 1612 data8 sys_vmsplice
diff --git a/arch/ia64/kernel/esi.c b/arch/ia64/kernel/esi.c
new file mode 100644
index 000000000000..ebf4e988e78c
--- /dev/null
+++ b/arch/ia64/kernel/esi.c
@@ -0,0 +1,205 @@
1/*
2 * Extensible SAL Interface (ESI) support routines.
3 *
4 * Copyright (C) 2006 Hewlett-Packard Co
5 * Alex Williamson <alex.williamson@hp.com>
6 */
7#include <linux/kernel.h>
8#include <linux/init.h>
9#include <linux/module.h>
10#include <linux/string.h>
11
12#include <asm/esi.h>
13#include <asm/sal.h>
14
15MODULE_AUTHOR("Alex Williamson <alex.williamson@hp.com>");
16MODULE_DESCRIPTION("Extensible SAL Interface (ESI) support");
17MODULE_LICENSE("GPL");
18
19#define MODULE_NAME "esi"
20
21#define ESI_TABLE_GUID \
22 EFI_GUID(0x43EA58DC, 0xCF28, 0x4b06, 0xB3, \
23 0x91, 0xB7, 0x50, 0x59, 0x34, 0x2B, 0xD4)
24
25enum esi_systab_entry_type {
26 ESI_DESC_ENTRY_POINT = 0
27};
28
29/*
30 * Entry type: Size:
31 * 0 48
32 */
33#define ESI_DESC_SIZE(type) "\060"[(unsigned) (type)]
34
35typedef struct ia64_esi_desc_entry_point {
36 u8 type;
37 u8 reserved1[15];
38 u64 esi_proc;
39 u64 gp;
40 efi_guid_t guid;
41} ia64_esi_desc_entry_point_t;
42
43struct pdesc {
44 void *addr;
45 void *gp;
46};
47
48static struct ia64_sal_systab *esi_systab;
49
50static int __init esi_init (void)
51{
52 efi_config_table_t *config_tables;
53 struct ia64_sal_systab *systab;
54 unsigned long esi = 0;
55 char *p;
56 int i;
57
58 config_tables = __va(efi.systab->tables);
59
60 for (i = 0; i < (int) efi.systab->nr_tables; ++i) {
61 if (efi_guidcmp(config_tables[i].guid, ESI_TABLE_GUID) == 0) {
62 esi = config_tables[i].table;
63 break;
64 }
65 }
66
67 if (!esi)
68 return -ENODEV;;
69
70 systab = __va(esi);
71
72 if (strncmp(systab->signature, "ESIT", 4) != 0) {
73 printk(KERN_ERR "bad signature in ESI system table!");
74 return -ENODEV;
75 }
76
77 p = (char *) (systab + 1);
78 for (i = 0; i < systab->entry_count; i++) {
79 /*
80 * The first byte of each entry type contains the type
81 * descriptor.
82 */
83 switch (*p) {
84 case ESI_DESC_ENTRY_POINT:
85 break;
86 default:
87 printk(KERN_WARNING "Unkown table type %d found in "
88 "ESI table, ignoring rest of table\n", *p);
89 return -ENODEV;
90 }
91
92 p += ESI_DESC_SIZE(*p);
93 }
94
95 esi_systab = systab;
96 return 0;
97}
98
99
100int ia64_esi_call (efi_guid_t guid, struct ia64_sal_retval *isrvp,
101 enum esi_proc_type proc_type, u64 func,
102 u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6,
103 u64 arg7)
104{
105 struct ia64_fpreg fr[6];
106 unsigned long flags = 0;
107 int i;
108 char *p;
109
110 if (!esi_systab)
111 return -1;
112
113 p = (char *) (esi_systab + 1);
114 for (i = 0; i < esi_systab->entry_count; i++) {
115 if (*p == ESI_DESC_ENTRY_POINT) {
116 ia64_esi_desc_entry_point_t *esi = (void *)p;
117 if (!efi_guidcmp(guid, esi->guid)) {
118 ia64_sal_handler esi_proc;
119 struct pdesc pdesc;
120
121 pdesc.addr = __va(esi->esi_proc);
122 pdesc.gp = __va(esi->gp);
123
124 esi_proc = (ia64_sal_handler) &pdesc;
125
126 ia64_save_scratch_fpregs(fr);
127 if (proc_type == ESI_PROC_SERIALIZED)
128 spin_lock_irqsave(&sal_lock, flags);
129 else if (proc_type == ESI_PROC_MP_SAFE)
130 local_irq_save(flags);
131 else
132 preempt_disable();
133 *isrvp = (*esi_proc)(func, arg1, arg2, arg3,
134 arg4, arg5, arg6, arg7);
135 if (proc_type == ESI_PROC_SERIALIZED)
136 spin_unlock_irqrestore(&sal_lock,
137 flags);
138 else if (proc_type == ESI_PROC_MP_SAFE)
139 local_irq_restore(flags);
140 else
141 preempt_enable();
142 ia64_load_scratch_fpregs(fr);
143 return 0;
144 }
145 }
146 p += ESI_DESC_SIZE(*p);
147 }
148 return -1;
149}
150EXPORT_SYMBOL_GPL(ia64_esi_call);
151
152int ia64_esi_call_phys (efi_guid_t guid, struct ia64_sal_retval *isrvp,
153 u64 func, u64 arg1, u64 arg2, u64 arg3, u64 arg4,
154 u64 arg5, u64 arg6, u64 arg7)
155{
156 struct ia64_fpreg fr[6];
157 unsigned long flags;
158 u64 esi_params[8];
159 char *p;
160 int i;
161
162 if (!esi_systab)
163 return -1;
164
165 p = (char *) (esi_systab + 1);
166 for (i = 0; i < esi_systab->entry_count; i++) {
167 if (*p == ESI_DESC_ENTRY_POINT) {
168 ia64_esi_desc_entry_point_t *esi = (void *)p;
169 if (!efi_guidcmp(guid, esi->guid)) {
170 ia64_sal_handler esi_proc;
171 struct pdesc pdesc;
172
173 pdesc.addr = (void *)esi->esi_proc;
174 pdesc.gp = (void *)esi->gp;
175
176 esi_proc = (ia64_sal_handler) &pdesc;
177
178 esi_params[0] = func;
179 esi_params[1] = arg1;
180 esi_params[2] = arg2;
181 esi_params[3] = arg3;
182 esi_params[4] = arg4;
183 esi_params[5] = arg5;
184 esi_params[6] = arg6;
185 esi_params[7] = arg7;
186 ia64_save_scratch_fpregs(fr);
187 spin_lock_irqsave(&sal_lock, flags);
188 *isrvp = esi_call_phys(esi_proc, esi_params);
189 spin_unlock_irqrestore(&sal_lock, flags);
190 ia64_load_scratch_fpregs(fr);
191 return 0;
192 }
193 }
194 p += ESI_DESC_SIZE(*p);
195 }
196 return -1;
197}
198EXPORT_SYMBOL_GPL(ia64_esi_call_phys);
199
200static void __exit esi_exit (void)
201{
202}
203
204module_init(esi_init);
205module_exit(esi_exit); /* makes module removable... */
diff --git a/arch/ia64/kernel/esi_stub.S b/arch/ia64/kernel/esi_stub.S
new file mode 100644
index 000000000000..6b3d6c1f99b6
--- /dev/null
+++ b/arch/ia64/kernel/esi_stub.S
@@ -0,0 +1,96 @@
1/*
2 * ESI call stub.
3 *
4 * Copyright (C) 2005 Hewlett-Packard Co
5 * Alex Williamson <alex.williamson@hp.com>
6 *
7 * Based on EFI call stub by David Mosberger. The stub is virtually
8 * identical to the one for EFI phys-mode calls, except that ESI
9 * calls may have up to 8 arguments, so they get passed to this routine
10 * through memory.
11 *
12 * This stub allows us to make ESI calls in physical mode with interrupts
13 * turned off. ESI calls may not support calling from virtual mode.
14 *
15 * Google for "Extensible SAL specification" for a document describing the
16 * ESI standard.
17 */
18
19/*
20 * PSR settings as per SAL spec (Chapter 8 in the "IA-64 System
21 * Abstraction Layer Specification", revision 2.6e). Note that
22 * psr.dfl and psr.dfh MUST be cleared, despite what this manual says.
23 * Otherwise, SAL dies whenever it's trying to do an IA-32 BIOS call
24 * (the br.ia instruction fails unless psr.dfl and psr.dfh are
25 * cleared). Fortunately, SAL promises not to touch the floating
26 * point regs, so at least we don't have to save f2-f127.
27 */
28#define PSR_BITS_TO_CLEAR \
29 (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_RT | \
30 IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | \
31 IA64_PSR_DFL | IA64_PSR_DFH)
32
33#define PSR_BITS_TO_SET \
34 (IA64_PSR_BN)
35
36#include <asm/processor.h>
37#include <asm/asmmacro.h>
38
39/*
40 * Inputs:
41 * in0 = address of function descriptor of ESI routine to call
42 * in1 = address of array of ESI parameters
43 *
44 * Outputs:
45 * r8 = result returned by called function
46 */
47GLOBAL_ENTRY(esi_call_phys)
48 .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
49 alloc loc1=ar.pfs,2,7,8,0
50 ld8 r2=[in0],8 // load ESI function's entry point
51 mov loc0=rp
52 .body
53 ;;
54 ld8 out0=[in1],8 // ESI params loaded from array
55 ;; // passing all as inputs doesn't work
56 ld8 out1=[in1],8
57 ;;
58 ld8 out2=[in1],8
59 ;;
60 ld8 out3=[in1],8
61 ;;
62 ld8 out4=[in1],8
63 ;;
64 ld8 out5=[in1],8
65 ;;
66 ld8 out6=[in1],8
67 ;;
68 ld8 out7=[in1]
69 mov loc2=gp // save global pointer
70 mov loc4=ar.rsc // save RSE configuration
71 mov ar.rsc=0 // put RSE in enforced lazy, LE mode
72 ;;
73 ld8 gp=[in0] // load ESI function's global pointer
74 movl r16=PSR_BITS_TO_CLEAR
75 mov loc3=psr // save processor status word
76 movl r17=PSR_BITS_TO_SET
77 ;;
78 or loc3=loc3,r17
79 mov b6=r2
80 ;;
81 andcm r16=loc3,r16 // get psr with IT, DT, and RT bits cleared
82 br.call.sptk.many rp=ia64_switch_mode_phys
83.ret0: mov loc5=r19 // old ar.bsp
84 mov loc6=r20 // old sp
85 br.call.sptk.many rp=b6 // call the ESI function
86.ret1: mov ar.rsc=0 // put RSE in enforced lazy, LE mode
87 mov r16=loc3 // save virtual mode psr
88 mov r19=loc5 // save virtual mode bspstore
89 mov r20=loc6 // save virtual mode sp
90 br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
91.ret2: mov ar.rsc=loc4 // restore RSE configuration
92 mov ar.pfs=loc1
93 mov rp=loc0
94 mov gp=loc2
95 br.ret.sptk.many rp
96END(esi_call_phys)
diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c
index 3ead20fb6f4b..879c1817bd1c 100644
--- a/arch/ia64/kernel/ia64_ksyms.c
+++ b/arch/ia64/kernel/ia64_ksyms.c
@@ -105,5 +105,9 @@ EXPORT_SYMBOL(ia64_spinlock_contention);
105# endif 105# endif
106#endif 106#endif
107 107
108#if defined(CONFIG_IA64_ESI) || defined(CONFIG_IA64_ESI_MODULE)
109extern void esi_call_phys (void);
110EXPORT_SYMBOL_GPL(esi_call_phys);
111#endif
108extern char ia64_ivt[]; 112extern char ia64_ivt[];
109EXPORT_SYMBOL(ia64_ivt); 113EXPORT_SYMBOL(ia64_ivt);
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 781960f80b6f..169ec3a7156c 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -136,10 +136,8 @@ static void __kprobes update_kprobe_inst_flag(uint template, uint slot,
136static int __kprobes unsupported_inst(uint template, uint slot, 136static int __kprobes unsupported_inst(uint template, uint slot,
137 uint major_opcode, 137 uint major_opcode,
138 unsigned long kprobe_inst, 138 unsigned long kprobe_inst,
139 struct kprobe *p) 139 unsigned long addr)
140{ 140{
141 unsigned long addr = (unsigned long)p->addr;
142
143 if (bundle_encoding[template][slot] == I) { 141 if (bundle_encoding[template][slot] == I) {
144 switch (major_opcode) { 142 switch (major_opcode) {
145 case 0x0: //I_UNIT_MISC_OPCODE: 143 case 0x0: //I_UNIT_MISC_OPCODE:
@@ -217,7 +215,7 @@ static void __kprobes prepare_break_inst(uint template, uint slot,
217 struct kprobe *p) 215 struct kprobe *p)
218{ 216{
219 unsigned long break_inst = BREAK_INST; 217 unsigned long break_inst = BREAK_INST;
220 bundle_t *bundle = &p->ainsn.insn.bundle; 218 bundle_t *bundle = &p->opcode.bundle;
221 219
222 /* 220 /*
223 * Copy the original kprobe_inst qualifying predicate(qp) 221 * Copy the original kprobe_inst qualifying predicate(qp)
@@ -423,11 +421,9 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
423 unsigned long *kprobe_addr = (unsigned long *)(addr & ~0xFULL); 421 unsigned long *kprobe_addr = (unsigned long *)(addr & ~0xFULL);
424 unsigned long kprobe_inst=0; 422 unsigned long kprobe_inst=0;
425 unsigned int slot = addr & 0xf, template, major_opcode = 0; 423 unsigned int slot = addr & 0xf, template, major_opcode = 0;
426 bundle_t *bundle = &p->ainsn.insn.bundle; 424 bundle_t *bundle;
427
428 memcpy(&p->opcode.bundle, kprobe_addr, sizeof(bundle_t));
429 memcpy(&p->ainsn.insn.bundle, kprobe_addr, sizeof(bundle_t));
430 425
426 bundle = &((kprobe_opcode_t *)kprobe_addr)->bundle;
431 template = bundle->quad0.template; 427 template = bundle->quad0.template;
432 428
433 if(valid_kprobe_addr(template, slot, addr)) 429 if(valid_kprobe_addr(template, slot, addr))
@@ -440,20 +436,19 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
440 /* Get kprobe_inst and major_opcode from the bundle */ 436 /* Get kprobe_inst and major_opcode from the bundle */
441 get_kprobe_inst(bundle, slot, &kprobe_inst, &major_opcode); 437 get_kprobe_inst(bundle, slot, &kprobe_inst, &major_opcode);
442 438
443 if (unsupported_inst(template, slot, major_opcode, kprobe_inst, p)) 439 if (unsupported_inst(template, slot, major_opcode, kprobe_inst, addr))
444 return -EINVAL; 440 return -EINVAL;
445 441
446 prepare_break_inst(template, slot, major_opcode, kprobe_inst, p);
447 442
448 return 0; 443 p->ainsn.insn = get_insn_slot();
449} 444 if (!p->ainsn.insn)
445 return -ENOMEM;
446 memcpy(&p->opcode, kprobe_addr, sizeof(kprobe_opcode_t));
447 memcpy(p->ainsn.insn, kprobe_addr, sizeof(kprobe_opcode_t));
450 448
451void __kprobes flush_insn_slot(struct kprobe *p) 449 prepare_break_inst(template, slot, major_opcode, kprobe_inst, p);
452{
453 unsigned long arm_addr;
454 450
455 arm_addr = ((unsigned long)&p->opcode.bundle) & ~0xFULL; 451 return 0;
456 flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t));
457} 452}
458 453
459void __kprobes arch_arm_kprobe(struct kprobe *p) 454void __kprobes arch_arm_kprobe(struct kprobe *p)
@@ -461,9 +456,10 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)
461 unsigned long addr = (unsigned long)p->addr; 456 unsigned long addr = (unsigned long)p->addr;
462 unsigned long arm_addr = addr & ~0xFULL; 457 unsigned long arm_addr = addr & ~0xFULL;
463 458
464 flush_insn_slot(p); 459 flush_icache_range((unsigned long)p->ainsn.insn,
465 memcpy((char *)arm_addr, &p->ainsn.insn.bundle, sizeof(bundle_t)); 460 (unsigned long)p->ainsn.insn + sizeof(kprobe_opcode_t));
466 flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t)); 461 memcpy((char *)arm_addr, &p->opcode, sizeof(kprobe_opcode_t));
462 flush_icache_range(arm_addr, arm_addr + sizeof(kprobe_opcode_t));
467} 463}
468 464
469void __kprobes arch_disarm_kprobe(struct kprobe *p) 465void __kprobes arch_disarm_kprobe(struct kprobe *p)
@@ -471,11 +467,18 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)
471 unsigned long addr = (unsigned long)p->addr; 467 unsigned long addr = (unsigned long)p->addr;
472 unsigned long arm_addr = addr & ~0xFULL; 468 unsigned long arm_addr = addr & ~0xFULL;
473 469
474 /* p->opcode contains the original unaltered bundle */ 470 /* p->ainsn.insn contains the original unaltered kprobe_opcode_t */
475 memcpy((char *) arm_addr, (char *) &p->opcode.bundle, sizeof(bundle_t)); 471 memcpy((char *) arm_addr, (char *) p->ainsn.insn,
476 flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t)); 472 sizeof(kprobe_opcode_t));
473 flush_icache_range(arm_addr, arm_addr + sizeof(kprobe_opcode_t));
477} 474}
478 475
476void __kprobes arch_remove_kprobe(struct kprobe *p)
477{
478 mutex_lock(&kprobe_mutex);
479 free_insn_slot(p->ainsn.insn);
480 mutex_unlock(&kprobe_mutex);
481}
479/* 482/*
480 * We are resuming execution after a single step fault, so the pt_regs 483 * We are resuming execution after a single step fault, so the pt_regs
481 * structure reflects the register state after we executed the instruction 484 * structure reflects the register state after we executed the instruction
@@ -486,12 +489,12 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)
486 */ 489 */
487static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) 490static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
488{ 491{
489 unsigned long bundle_addr = ((unsigned long) (&p->opcode.bundle)) & ~0xFULL; 492 unsigned long bundle_addr = (unsigned long) (&p->ainsn.insn->bundle);
490 unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL; 493 unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL;
491 unsigned long template; 494 unsigned long template;
492 int slot = ((unsigned long)p->addr & 0xf); 495 int slot = ((unsigned long)p->addr & 0xf);
493 496
494 template = p->opcode.bundle.quad0.template; 497 template = p->ainsn.insn->bundle.quad0.template;
495 498
496 if (slot == 1 && bundle_encoding[template][1] == L) 499 if (slot == 1 && bundle_encoding[template][1] == L)
497 slot = 2; 500 slot = 2;
@@ -553,7 +556,7 @@ turn_ss_off:
553 556
554static void __kprobes prepare_ss(struct kprobe *p, struct pt_regs *regs) 557static void __kprobes prepare_ss(struct kprobe *p, struct pt_regs *regs)
555{ 558{
556 unsigned long bundle_addr = (unsigned long) &p->opcode.bundle; 559 unsigned long bundle_addr = (unsigned long) &p->ainsn.insn->bundle;
557 unsigned long slot = (unsigned long)p->addr & 0xf; 560 unsigned long slot = (unsigned long)p->addr & 0xf;
558 561
559 /* single step inline if break instruction */ 562 /* single step inline if break instruction */
@@ -768,6 +771,12 @@ static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr)
768 */ 771 */
769 if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) 772 if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
770 return 1; 773 return 1;
774 /*
775 * In case the user-specified fault handler returned
776 * zero, try to fix up.
777 */
778 if (ia64_done_with_exception(regs))
779 return 1;
771 780
772 /* 781 /*
773 * Let ia64_do_page_fault() fix it. 782 * Let ia64_do_page_fault() fix it.
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index 2fbe4536fe18..bfbd8986153b 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -54,6 +54,9 @@
54 * 54 *
55 * 2005-10-07 Keith Owens <kaos@sgi.com> 55 * 2005-10-07 Keith Owens <kaos@sgi.com>
56 * Add notify_die() hooks. 56 * Add notify_die() hooks.
57 *
58 * 2006-09-15 Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
59 * Add printing support for MCA/INIT.
57 */ 60 */
58#include <linux/types.h> 61#include <linux/types.h>
59#include <linux/init.h> 62#include <linux/init.h>
@@ -136,11 +139,175 @@ extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe);
136 139
137static int mca_init __initdata; 140static int mca_init __initdata;
138 141
142/*
143 * limited & delayed printing support for MCA/INIT handler
144 */
145
146#define mprintk(fmt...) ia64_mca_printk(fmt)
147
148#define MLOGBUF_SIZE (512+256*NR_CPUS)
149#define MLOGBUF_MSGMAX 256
150static char mlogbuf[MLOGBUF_SIZE];
151static DEFINE_SPINLOCK(mlogbuf_wlock); /* mca context only */
152static DEFINE_SPINLOCK(mlogbuf_rlock); /* normal context only */
153static unsigned long mlogbuf_start;
154static unsigned long mlogbuf_end;
155static unsigned int mlogbuf_finished = 0;
156static unsigned long mlogbuf_timestamp = 0;
157
158static int loglevel_save = -1;
159#define BREAK_LOGLEVEL(__console_loglevel) \
160 oops_in_progress = 1; \
161 if (loglevel_save < 0) \
162 loglevel_save = __console_loglevel; \
163 __console_loglevel = 15;
164
165#define RESTORE_LOGLEVEL(__console_loglevel) \
166 if (loglevel_save >= 0) { \
167 __console_loglevel = loglevel_save; \
168 loglevel_save = -1; \
169 } \
170 mlogbuf_finished = 0; \
171 oops_in_progress = 0;
172
173/*
174 * Push messages into buffer, print them later if not urgent.
175 */
176void ia64_mca_printk(const char *fmt, ...)
177{
178 va_list args;
179 int printed_len;
180 char temp_buf[MLOGBUF_MSGMAX];
181 char *p;
182
183 va_start(args, fmt);
184 printed_len = vscnprintf(temp_buf, sizeof(temp_buf), fmt, args);
185 va_end(args);
186
187 /* Copy the output into mlogbuf */
188 if (oops_in_progress) {
189 /* mlogbuf was abandoned, use printk directly instead. */
190 printk(temp_buf);
191 } else {
192 spin_lock(&mlogbuf_wlock);
193 for (p = temp_buf; *p; p++) {
194 unsigned long next = (mlogbuf_end + 1) % MLOGBUF_SIZE;
195 if (next != mlogbuf_start) {
196 mlogbuf[mlogbuf_end] = *p;
197 mlogbuf_end = next;
198 } else {
199 /* buffer full */
200 break;
201 }
202 }
203 mlogbuf[mlogbuf_end] = '\0';
204 spin_unlock(&mlogbuf_wlock);
205 }
206}
207EXPORT_SYMBOL(ia64_mca_printk);
208
209/*
210 * Print buffered messages.
211 * NOTE: call this after returning normal context. (ex. from salinfod)
212 */
213void ia64_mlogbuf_dump(void)
214{
215 char temp_buf[MLOGBUF_MSGMAX];
216 char *p;
217 unsigned long index;
218 unsigned long flags;
219 unsigned int printed_len;
220
221 /* Get output from mlogbuf */
222 while (mlogbuf_start != mlogbuf_end) {
223 temp_buf[0] = '\0';
224 p = temp_buf;
225 printed_len = 0;
226
227 spin_lock_irqsave(&mlogbuf_rlock, flags);
228
229 index = mlogbuf_start;
230 while (index != mlogbuf_end) {
231 *p = mlogbuf[index];
232 index = (index + 1) % MLOGBUF_SIZE;
233 if (!*p)
234 break;
235 p++;
236 if (++printed_len >= MLOGBUF_MSGMAX - 1)
237 break;
238 }
239 *p = '\0';
240 if (temp_buf[0])
241 printk(temp_buf);
242 mlogbuf_start = index;
243
244 mlogbuf_timestamp = 0;
245 spin_unlock_irqrestore(&mlogbuf_rlock, flags);
246 }
247}
248EXPORT_SYMBOL(ia64_mlogbuf_dump);
249
250/*
251 * Call this if system is going to down or if immediate flushing messages to
252 * console is required. (ex. recovery was failed, crash dump is going to be
253 * invoked, long-wait rendezvous etc.)
254 * NOTE: this should be called from monarch.
255 */
256static void ia64_mlogbuf_finish(int wait)
257{
258 BREAK_LOGLEVEL(console_loglevel);
259
260 spin_lock_init(&mlogbuf_rlock);
261 ia64_mlogbuf_dump();
262 printk(KERN_EMERG "mlogbuf_finish: printing switched to urgent mode, "
263 "MCA/INIT might be dodgy or fail.\n");
264
265 if (!wait)
266 return;
267
268 /* wait for console */
269 printk("Delaying for 5 seconds...\n");
270 udelay(5*1000000);
271
272 mlogbuf_finished = 1;
273}
274EXPORT_SYMBOL(ia64_mlogbuf_finish);
275
276/*
277 * Print buffered messages from INIT context.
278 */
279static void ia64_mlogbuf_dump_from_init(void)
280{
281 if (mlogbuf_finished)
282 return;
283
284 if (mlogbuf_timestamp && (mlogbuf_timestamp + 30*HZ > jiffies)) {
285 printk(KERN_ERR "INIT: mlogbuf_dump is interrupted by INIT "
286 " and the system seems to be messed up.\n");
287 ia64_mlogbuf_finish(0);
288 return;
289 }
290
291 if (!spin_trylock(&mlogbuf_rlock)) {
292 printk(KERN_ERR "INIT: mlogbuf_dump is interrupted by INIT. "
293 "Generated messages other than stack dump will be "
294 "buffered to mlogbuf and will be printed later.\n");
295 printk(KERN_ERR "INIT: If messages would not printed after "
296 "this INIT, wait 30sec and assert INIT again.\n");
297 if (!mlogbuf_timestamp)
298 mlogbuf_timestamp = jiffies;
299 return;
300 }
301 spin_unlock(&mlogbuf_rlock);
302 ia64_mlogbuf_dump();
303}
139 304
140static void inline 305static void inline
141ia64_mca_spin(const char *func) 306ia64_mca_spin(const char *func)
142{ 307{
143 printk(KERN_EMERG "%s: spinning here, not returning to SAL\n", func); 308 if (monarch_cpu == smp_processor_id())
309 ia64_mlogbuf_finish(0);
310 mprintk(KERN_EMERG "%s: spinning here, not returning to SAL\n", func);
144 while (1) 311 while (1)
145 cpu_relax(); 312 cpu_relax();
146} 313}
@@ -344,9 +511,6 @@ ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs)
344 /* SAL spec states this should run w/ interrupts enabled */ 511 /* SAL spec states this should run w/ interrupts enabled */
345 local_irq_enable(); 512 local_irq_enable();
346 513
347 /* Get the CPE error record and log it */
348 ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CPE);
349
350 spin_lock(&cpe_history_lock); 514 spin_lock(&cpe_history_lock);
351 if (!cpe_poll_enabled && cpe_vector >= 0) { 515 if (!cpe_poll_enabled && cpe_vector >= 0) {
352 516
@@ -375,7 +539,7 @@ ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs)
375 mod_timer(&cpe_poll_timer, jiffies + MIN_CPE_POLL_INTERVAL); 539 mod_timer(&cpe_poll_timer, jiffies + MIN_CPE_POLL_INTERVAL);
376 540
377 /* lock already released, get out now */ 541 /* lock already released, get out now */
378 return IRQ_HANDLED; 542 goto out;
379 } else { 543 } else {
380 cpe_history[index++] = now; 544 cpe_history[index++] = now;
381 if (index == CPE_HISTORY_LENGTH) 545 if (index == CPE_HISTORY_LENGTH)
@@ -383,6 +547,10 @@ ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs)
383 } 547 }
384 } 548 }
385 spin_unlock(&cpe_history_lock); 549 spin_unlock(&cpe_history_lock);
550out:
551 /* Get the CPE error record and log it */
552 ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CPE);
553
386 return IRQ_HANDLED; 554 return IRQ_HANDLED;
387} 555}
388 556
@@ -988,18 +1156,22 @@ ia64_wait_for_slaves(int monarch, const char *type)
988 } 1156 }
989 if (!missing) 1157 if (!missing)
990 goto all_in; 1158 goto all_in;
991 printk(KERN_INFO "OS %s slave did not rendezvous on cpu", type); 1159 /*
1160 * Maybe slave(s) dead. Print buffered messages immediately.
1161 */
1162 ia64_mlogbuf_finish(0);
1163 mprintk(KERN_INFO "OS %s slave did not rendezvous on cpu", type);
992 for_each_online_cpu(c) { 1164 for_each_online_cpu(c) {
993 if (c == monarch) 1165 if (c == monarch)
994 continue; 1166 continue;
995 if (ia64_mc_info.imi_rendez_checkin[c] == IA64_MCA_RENDEZ_CHECKIN_NOTDONE) 1167 if (ia64_mc_info.imi_rendez_checkin[c] == IA64_MCA_RENDEZ_CHECKIN_NOTDONE)
996 printk(" %d", c); 1168 mprintk(" %d", c);
997 } 1169 }
998 printk("\n"); 1170 mprintk("\n");
999 return; 1171 return;
1000 1172
1001all_in: 1173all_in:
1002 printk(KERN_INFO "All OS %s slaves have reached rendezvous\n", type); 1174 mprintk(KERN_INFO "All OS %s slaves have reached rendezvous\n", type);
1003 return; 1175 return;
1004} 1176}
1005 1177
@@ -1027,10 +1199,8 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
1027 struct ia64_mca_notify_die nd = 1199 struct ia64_mca_notify_die nd =
1028 { .sos = sos, .monarch_cpu = &monarch_cpu }; 1200 { .sos = sos, .monarch_cpu = &monarch_cpu };
1029 1201
1030 oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ 1202 mprintk(KERN_INFO "Entered OS MCA handler. PSP=%lx cpu=%d "
1031 console_loglevel = 15; /* make sure printks make it to console */ 1203 "monarch=%ld\n", sos->proc_state_param, cpu, sos->monarch);
1032 printk(KERN_INFO "Entered OS MCA handler. PSP=%lx cpu=%d monarch=%ld\n",
1033 sos->proc_state_param, cpu, sos->monarch);
1034 1204
1035 previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA"); 1205 previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA");
1036 monarch_cpu = cpu; 1206 monarch_cpu = cpu;
@@ -1066,6 +1236,9 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
1066 rh->severity = sal_log_severity_corrected; 1236 rh->severity = sal_log_severity_corrected;
1067 ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA); 1237 ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA);
1068 sos->os_status = IA64_MCA_CORRECTED; 1238 sos->os_status = IA64_MCA_CORRECTED;
1239 } else {
1240 /* Dump buffered message to console */
1241 ia64_mlogbuf_finish(1);
1069 } 1242 }
1070 if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, (long)&nd, 0, recover) 1243 if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, (long)&nd, 0, recover)
1071 == NOTIFY_STOP) 1244 == NOTIFY_STOP)
@@ -1106,9 +1279,6 @@ ia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs)
1106 /* SAL spec states this should run w/ interrupts enabled */ 1279 /* SAL spec states this should run w/ interrupts enabled */
1107 local_irq_enable(); 1280 local_irq_enable();
1108 1281
1109 /* Get the CMC error record and log it */
1110 ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CMC);
1111
1112 spin_lock(&cmc_history_lock); 1282 spin_lock(&cmc_history_lock);
1113 if (!cmc_polling_enabled) { 1283 if (!cmc_polling_enabled) {
1114 int i, count = 1; /* we know 1 happened now */ 1284 int i, count = 1; /* we know 1 happened now */
@@ -1141,7 +1311,7 @@ ia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs)
1141 mod_timer(&cmc_poll_timer, jiffies + CMC_POLL_INTERVAL); 1311 mod_timer(&cmc_poll_timer, jiffies + CMC_POLL_INTERVAL);
1142 1312
1143 /* lock already released, get out now */ 1313 /* lock already released, get out now */
1144 return IRQ_HANDLED; 1314 goto out;
1145 } else { 1315 } else {
1146 cmc_history[index++] = now; 1316 cmc_history[index++] = now;
1147 if (index == CMC_HISTORY_LENGTH) 1317 if (index == CMC_HISTORY_LENGTH)
@@ -1149,6 +1319,10 @@ ia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs)
1149 } 1319 }
1150 } 1320 }
1151 spin_unlock(&cmc_history_lock); 1321 spin_unlock(&cmc_history_lock);
1322out:
1323 /* Get the CMC error record and log it */
1324 ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CMC);
1325
1152 return IRQ_HANDLED; 1326 return IRQ_HANDLED;
1153} 1327}
1154 1328
@@ -1305,6 +1479,15 @@ default_monarch_init_process(struct notifier_block *self, unsigned long val, voi
1305 struct task_struct *g, *t; 1479 struct task_struct *g, *t;
1306 if (val != DIE_INIT_MONARCH_PROCESS) 1480 if (val != DIE_INIT_MONARCH_PROCESS)
1307 return NOTIFY_DONE; 1481 return NOTIFY_DONE;
1482
1483 /*
1484 * FIXME: mlogbuf will brim over with INIT stack dumps.
1485 * To enable show_stack from INIT, we use oops_in_progress which should
1486 * be used in real oops. This would cause something wrong after INIT.
1487 */
1488 BREAK_LOGLEVEL(console_loglevel);
1489 ia64_mlogbuf_dump_from_init();
1490
1308 printk(KERN_ERR "Processes interrupted by INIT -"); 1491 printk(KERN_ERR "Processes interrupted by INIT -");
1309 for_each_online_cpu(c) { 1492 for_each_online_cpu(c) {
1310 struct ia64_sal_os_state *s; 1493 struct ia64_sal_os_state *s;
@@ -1326,6 +1509,8 @@ default_monarch_init_process(struct notifier_block *self, unsigned long val, voi
1326 } while_each_thread (g, t); 1509 } while_each_thread (g, t);
1327 read_unlock(&tasklist_lock); 1510 read_unlock(&tasklist_lock);
1328 } 1511 }
1512 /* FIXME: This will not restore zapped printk locks. */
1513 RESTORE_LOGLEVEL(console_loglevel);
1329 return NOTIFY_DONE; 1514 return NOTIFY_DONE;
1330} 1515}
1331 1516
@@ -1357,12 +1542,9 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
1357 struct ia64_mca_notify_die nd = 1542 struct ia64_mca_notify_die nd =
1358 { .sos = sos, .monarch_cpu = &monarch_cpu }; 1543 { .sos = sos, .monarch_cpu = &monarch_cpu };
1359 1544
1360 oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */
1361 console_loglevel = 15; /* make sure printks make it to console */
1362
1363 (void) notify_die(DIE_INIT_ENTER, "INIT", regs, (long)&nd, 0, 0); 1545 (void) notify_die(DIE_INIT_ENTER, "INIT", regs, (long)&nd, 0, 0);
1364 1546
1365 printk(KERN_INFO "Entered OS INIT handler. PSP=%lx cpu=%d monarch=%ld\n", 1547 mprintk(KERN_INFO "Entered OS INIT handler. PSP=%lx cpu=%d monarch=%ld\n",
1366 sos->proc_state_param, cpu, sos->monarch); 1548 sos->proc_state_param, cpu, sos->monarch);
1367 salinfo_log_wakeup(SAL_INFO_TYPE_INIT, NULL, 0, 0); 1549 salinfo_log_wakeup(SAL_INFO_TYPE_INIT, NULL, 0, 0);
1368 1550
@@ -1375,7 +1557,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
1375 * fix their proms and get their customers updated. 1557 * fix their proms and get their customers updated.
1376 */ 1558 */
1377 if (!sos->monarch && atomic_add_return(1, &slaves) == num_online_cpus()) { 1559 if (!sos->monarch && atomic_add_return(1, &slaves) == num_online_cpus()) {
1378 printk(KERN_WARNING "%s: Promoting cpu %d to monarch.\n", 1560 mprintk(KERN_WARNING "%s: Promoting cpu %d to monarch.\n",
1379 __FUNCTION__, cpu); 1561 __FUNCTION__, cpu);
1380 atomic_dec(&slaves); 1562 atomic_dec(&slaves);
1381 sos->monarch = 1; 1563 sos->monarch = 1;
@@ -1387,7 +1569,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
1387 * fix their proms and get their customers updated. 1569 * fix their proms and get their customers updated.
1388 */ 1570 */
1389 if (sos->monarch && atomic_add_return(1, &monarchs) > 1) { 1571 if (sos->monarch && atomic_add_return(1, &monarchs) > 1) {
1390 printk(KERN_WARNING "%s: Demoting cpu %d to slave.\n", 1572 mprintk(KERN_WARNING "%s: Demoting cpu %d to slave.\n",
1391 __FUNCTION__, cpu); 1573 __FUNCTION__, cpu);
1392 atomic_dec(&monarchs); 1574 atomic_dec(&monarchs);
1393 sos->monarch = 0; 1575 sos->monarch = 0;
@@ -1408,7 +1590,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
1408 if (notify_die(DIE_INIT_SLAVE_LEAVE, "INIT", regs, (long)&nd, 0, 0) 1590 if (notify_die(DIE_INIT_SLAVE_LEAVE, "INIT", regs, (long)&nd, 0, 0)
1409 == NOTIFY_STOP) 1591 == NOTIFY_STOP)
1410 ia64_mca_spin(__FUNCTION__); 1592 ia64_mca_spin(__FUNCTION__);
1411 printk("Slave on cpu %d returning to normal service.\n", cpu); 1593 mprintk("Slave on cpu %d returning to normal service.\n", cpu);
1412 set_curr_task(cpu, previous_current); 1594 set_curr_task(cpu, previous_current);
1413 ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; 1595 ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
1414 atomic_dec(&slaves); 1596 atomic_dec(&slaves);
@@ -1426,7 +1608,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
1426 * same serial line, the user will need some time to switch out of the BMC before 1608 * same serial line, the user will need some time to switch out of the BMC before
1427 * the dump begins. 1609 * the dump begins.
1428 */ 1610 */
1429 printk("Delaying for 5 seconds...\n"); 1611 mprintk("Delaying for 5 seconds...\n");
1430 udelay(5*1000000); 1612 udelay(5*1000000);
1431 ia64_wait_for_slaves(cpu, "INIT"); 1613 ia64_wait_for_slaves(cpu, "INIT");
1432 /* If nobody intercepts DIE_INIT_MONARCH_PROCESS then we drop through 1614 /* If nobody intercepts DIE_INIT_MONARCH_PROCESS then we drop through
@@ -1439,7 +1621,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw,
1439 if (notify_die(DIE_INIT_MONARCH_LEAVE, "INIT", regs, (long)&nd, 0, 0) 1621 if (notify_die(DIE_INIT_MONARCH_LEAVE, "INIT", regs, (long)&nd, 0, 0)
1440 == NOTIFY_STOP) 1622 == NOTIFY_STOP)
1441 ia64_mca_spin(__FUNCTION__); 1623 ia64_mca_spin(__FUNCTION__);
1442 printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu); 1624 mprintk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu);
1443 atomic_dec(&monarchs); 1625 atomic_dec(&monarchs);
1444 set_curr_task(cpu, previous_current); 1626 set_curr_task(cpu, previous_current);
1445 monarch_cpu = -1; 1627 monarch_cpu = -1;
diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S
index 96047491d1b9..c6b607c00dee 100644
--- a/arch/ia64/kernel/mca_asm.S
+++ b/arch/ia64/kernel/mca_asm.S
@@ -1025,18 +1025,13 @@ ia64_old_stack:
1025 1025
1026ia64_set_kernel_registers: 1026ia64_set_kernel_registers:
1027 add temp3=MCA_SP_OFFSET, r3 1027 add temp3=MCA_SP_OFFSET, r3
1028 add temp4=MCA_SOS_OFFSET+SOS(OS_GP), r3
1029 mov b0=r2 // save return address 1028 mov b0=r2 // save return address
1030 GET_IA64_MCA_DATA(temp1) 1029 GET_IA64_MCA_DATA(temp1)
1031 ;; 1030 ;;
1032 add temp4=temp4, temp1 // &struct ia64_sal_os_state.os_gp
1033 add r12=temp1, temp3 // kernel stack pointer on MCA/INIT stack 1031 add r12=temp1, temp3 // kernel stack pointer on MCA/INIT stack
1034 add r13=temp1, r3 // set current to start of MCA/INIT stack 1032 add r13=temp1, r3 // set current to start of MCA/INIT stack
1035 add r20=temp1, r3 // physical start of MCA/INIT stack 1033 add r20=temp1, r3 // physical start of MCA/INIT stack
1036 ;; 1034 ;;
1037 ld8 r1=[temp4] // OS GP from SAL OS state
1038 ;;
1039 DATA_PA_TO_VA(r1,temp1)
1040 DATA_PA_TO_VA(r12,temp2) 1035 DATA_PA_TO_VA(r12,temp2)
1041 DATA_PA_TO_VA(r13,temp3) 1036 DATA_PA_TO_VA(r13,temp3)
1042 ;; 1037 ;;
@@ -1067,6 +1062,10 @@ ia64_set_kernel_registers:
1067 mov cr.itir=r18 1062 mov cr.itir=r18
1068 mov cr.ifa=r13 1063 mov cr.ifa=r13
1069 mov r20=IA64_TR_CURRENT_STACK 1064 mov r20=IA64_TR_CURRENT_STACK
1065
1066 movl r17=FPSR_DEFAULT
1067 ;;
1068 mov.m ar.fpsr=r17 // set ar.fpsr to kernel default value
1070 ;; 1069 ;;
1071 itr.d dtr[r20]=r21 1070 itr.d dtr[r20]=r21
1072 ;; 1071 ;;
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c
index 8db6e0cedadc..a45009d2bc90 100644
--- a/arch/ia64/kernel/mca_drv.c
+++ b/arch/ia64/kernel/mca_drv.c
@@ -79,14 +79,30 @@ static int
79fatal_mca(const char *fmt, ...) 79fatal_mca(const char *fmt, ...)
80{ 80{
81 va_list args; 81 va_list args;
82 char buf[256];
82 83
83 va_start(args, fmt); 84 va_start(args, fmt);
84 vprintk(fmt, args); 85 vsnprintf(buf, sizeof(buf), fmt, args);
85 va_end(args); 86 va_end(args);
87 ia64_mca_printk(KERN_ALERT "MCA: %s\n", buf);
86 88
87 return MCA_NOT_RECOVERED; 89 return MCA_NOT_RECOVERED;
88} 90}
89 91
92static int
93mca_recovered(const char *fmt, ...)
94{
95 va_list args;
96 char buf[256];
97
98 va_start(args, fmt);
99 vsnprintf(buf, sizeof(buf), fmt, args);
100 va_end(args);
101 ia64_mca_printk(KERN_INFO "MCA: %s\n", buf);
102
103 return MCA_RECOVERED;
104}
105
90/** 106/**
91 * mca_page_isolate - isolate a poisoned page in order not to use it later 107 * mca_page_isolate - isolate a poisoned page in order not to use it later
92 * @paddr: poisoned memory location 108 * @paddr: poisoned memory location
@@ -140,6 +156,7 @@ mca_page_isolate(unsigned long paddr)
140void 156void
141mca_handler_bh(unsigned long paddr, void *iip, unsigned long ipsr) 157mca_handler_bh(unsigned long paddr, void *iip, unsigned long ipsr)
142{ 158{
159 ia64_mlogbuf_dump();
143 printk(KERN_ERR "OS_MCA: process [cpu %d, pid: %d, uid: %d, " 160 printk(KERN_ERR "OS_MCA: process [cpu %d, pid: %d, uid: %d, "
144 "iip: %p, psr: 0x%lx,paddr: 0x%lx](%s) encounters MCA.\n", 161 "iip: %p, psr: 0x%lx,paddr: 0x%lx](%s) encounters MCA.\n",
145 raw_smp_processor_id(), current->pid, current->uid, 162 raw_smp_processor_id(), current->pid, current->uid,
@@ -440,7 +457,7 @@ recover_from_read_error(slidx_table_t *slidx,
440 457
441 /* Is target address valid? */ 458 /* Is target address valid? */
442 if (!pbci->tv) 459 if (!pbci->tv)
443 return fatal_mca(KERN_ALERT "MCA: target address not valid\n"); 460 return fatal_mca("target address not valid");
444 461
445 /* 462 /*
446 * cpu read or memory-mapped io read 463 * cpu read or memory-mapped io read
@@ -458,7 +475,7 @@ recover_from_read_error(slidx_table_t *slidx,
458 475
459 /* Is minstate valid? */ 476 /* Is minstate valid? */
460 if (!peidx_bottom(peidx) || !(peidx_bottom(peidx)->valid.minstate)) 477 if (!peidx_bottom(peidx) || !(peidx_bottom(peidx)->valid.minstate))
461 return fatal_mca(KERN_ALERT "MCA: minstate not valid\n"); 478 return fatal_mca("minstate not valid");
462 psr1 =(struct ia64_psr *)&(peidx_minstate_area(peidx)->pmsa_ipsr); 479 psr1 =(struct ia64_psr *)&(peidx_minstate_area(peidx)->pmsa_ipsr);
463 psr2 =(struct ia64_psr *)&(peidx_minstate_area(peidx)->pmsa_xpsr); 480 psr2 =(struct ia64_psr *)&(peidx_minstate_area(peidx)->pmsa_xpsr);
464 481
@@ -492,13 +509,14 @@ recover_from_read_error(slidx_table_t *slidx,
492 psr2->bn = 1; 509 psr2->bn = 1;
493 psr2->i = 0; 510 psr2->i = 0;
494 511
495 return MCA_RECOVERED; 512 return mca_recovered("user memory corruption. "
513 "kill affected process - recovered.");
496 } 514 }
497 515
498 } 516 }
499 517
500 return fatal_mca(KERN_ALERT "MCA: kernel context not recovered," 518 return fatal_mca("kernel context not recovered, iip 0x%lx\n",
501 " iip 0x%lx\n", pmsa->pmsa_iip); 519 pmsa->pmsa_iip);
502} 520}
503 521
504/** 522/**
@@ -584,13 +602,13 @@ recover_from_processor_error(int platform, slidx_table_t *slidx,
584 * The machine check is corrected. 602 * The machine check is corrected.
585 */ 603 */
586 if (psp->cm == 1) 604 if (psp->cm == 1)
587 return MCA_RECOVERED; 605 return mca_recovered("machine check is already corrected.");
588 606
589 /* 607 /*
590 * The error was not contained. Software must be reset. 608 * The error was not contained. Software must be reset.
591 */ 609 */
592 if (psp->us || psp->ci == 0) 610 if (psp->us || psp->ci == 0)
593 return fatal_mca(KERN_ALERT "MCA: error not contained\n"); 611 return fatal_mca("error not contained");
594 612
595 /* 613 /*
596 * The cache check and bus check bits have four possible states 614 * The cache check and bus check bits have four possible states
@@ -601,22 +619,22 @@ recover_from_processor_error(int platform, slidx_table_t *slidx,
601 * 1 1 Memory error, attempt recovery 619 * 1 1 Memory error, attempt recovery
602 */ 620 */
603 if (psp->bc == 0 || pbci == NULL) 621 if (psp->bc == 0 || pbci == NULL)
604 return fatal_mca(KERN_ALERT "MCA: No bus check\n"); 622 return fatal_mca("No bus check");
605 623
606 /* 624 /*
607 * Sorry, we cannot handle so many. 625 * Sorry, we cannot handle so many.
608 */ 626 */
609 if (peidx_bus_check_num(peidx) > 1) 627 if (peidx_bus_check_num(peidx) > 1)
610 return fatal_mca(KERN_ALERT "MCA: Too many bus checks\n"); 628 return fatal_mca("Too many bus checks");
611 /* 629 /*
612 * Well, here is only one bus error. 630 * Well, here is only one bus error.
613 */ 631 */
614 if (pbci->ib) 632 if (pbci->ib)
615 return fatal_mca(KERN_ALERT "MCA: Internal Bus error\n"); 633 return fatal_mca("Internal Bus error");
616 if (pbci->cc) 634 if (pbci->cc)
617 return fatal_mca(KERN_ALERT "MCA: Cache-cache error\n"); 635 return fatal_mca("Cache-cache error");
618 if (pbci->eb && pbci->bsi > 0) 636 if (pbci->eb && pbci->bsi > 0)
619 return fatal_mca(KERN_ALERT "MCA: External bus check fatal status\n"); 637 return fatal_mca("External bus check fatal status");
620 638
621 /* 639 /*
622 * This is a local MCA and estimated as recoverble external bus error. 640 * This is a local MCA and estimated as recoverble external bus error.
@@ -628,7 +646,7 @@ recover_from_processor_error(int platform, slidx_table_t *slidx,
628 /* 646 /*
629 * On account of strange SAL error record, we cannot recover. 647 * On account of strange SAL error record, we cannot recover.
630 */ 648 */
631 return fatal_mca(KERN_ALERT "MCA: Strange SAL record\n"); 649 return fatal_mca("Strange SAL record");
632} 650}
633 651
634/** 652/**
@@ -657,10 +675,10 @@ mca_try_to_recover(void *rec, struct ia64_sal_os_state *sos)
657 675
658 /* Now, OS can recover when there is one processor error section */ 676 /* Now, OS can recover when there is one processor error section */
659 if (n_proc_err > 1) 677 if (n_proc_err > 1)
660 return fatal_mca(KERN_ALERT "MCA: Too Many Errors\n"); 678 return fatal_mca("Too Many Errors");
661 else if (n_proc_err == 0) 679 else if (n_proc_err == 0)
662 /* Weird SAL record ... We need not to recover */ 680 /* Weird SAL record ... We can't do anything */
663 return fatal_mca(KERN_ALERT "MCA: Weird SAL record\n"); 681 return fatal_mca("Weird SAL record");
664 682
665 /* Make index of processor error section */ 683 /* Make index of processor error section */
666 mca_make_peidx((sal_log_processor_info_t*) 684 mca_make_peidx((sal_log_processor_info_t*)
@@ -671,7 +689,7 @@ mca_try_to_recover(void *rec, struct ia64_sal_os_state *sos)
671 689
672 /* Check whether MCA is global or not */ 690 /* Check whether MCA is global or not */
673 if (is_mca_global(&peidx, &pbci, sos)) 691 if (is_mca_global(&peidx, &pbci, sos))
674 return fatal_mca(KERN_ALERT "MCA: global MCA\n"); 692 return fatal_mca("global MCA");
675 693
676 /* Try to recover a processor error */ 694 /* Try to recover a processor error */
677 return recover_from_processor_error(platform_err, &slidx, &peidx, 695 return recover_from_processor_error(platform_err, &slidx, &peidx,
diff --git a/arch/ia64/kernel/mca_drv.h b/arch/ia64/kernel/mca_drv.h
index 31a2e52bb16f..c85e943ba5fd 100644
--- a/arch/ia64/kernel/mca_drv.h
+++ b/arch/ia64/kernel/mca_drv.h
@@ -118,3 +118,7 @@ struct mca_table_entry {
118 118
119extern const struct mca_table_entry *search_mca_tables (unsigned long addr); 119extern const struct mca_table_entry *search_mca_tables (unsigned long addr);
120extern int mca_recover_range(unsigned long); 120extern int mca_recover_range(unsigned long);
121extern void ia64_mca_printk(const char * fmt, ...)
122 __attribute__ ((format (printf, 1, 2)));
123extern void ia64_mlogbuf_dump(void);
124
diff --git a/arch/ia64/kernel/numa.c b/arch/ia64/kernel/numa.c
index 1cc360c83e7a..20340631179f 100644
--- a/arch/ia64/kernel/numa.c
+++ b/arch/ia64/kernel/numa.c
@@ -29,6 +29,36 @@ EXPORT_SYMBOL(cpu_to_node_map);
29 29
30cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned; 30cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
31 31
32void __cpuinit map_cpu_to_node(int cpu, int nid)
33{
34 int oldnid;
35 if (nid < 0) { /* just initialize by zero */
36 cpu_to_node_map[cpu] = 0;
37 return;
38 }
39 /* sanity check first */
40 oldnid = cpu_to_node_map[cpu];
41 if (cpu_isset(cpu, node_to_cpu_mask[oldnid])) {
42 return; /* nothing to do */
43 }
44 /* we don't have cpu-driven node hot add yet...
45 In usual case, node is created from SRAT at boot time. */
46 if (!node_online(nid))
47 nid = first_online_node;
48 cpu_to_node_map[cpu] = nid;
49 cpu_set(cpu, node_to_cpu_mask[nid]);
50 return;
51}
52
53void __cpuinit unmap_cpu_from_node(int cpu, int nid)
54{
55 WARN_ON(!cpu_isset(cpu, node_to_cpu_mask[nid]));
56 WARN_ON(cpu_to_node_map[cpu] != nid);
57 cpu_to_node_map[cpu] = 0;
58 cpu_clear(cpu, node_to_cpu_mask[nid]);
59}
60
61
32/** 62/**
33 * build_cpu_to_node_map - setup cpu to node and node to cpumask arrays 63 * build_cpu_to_node_map - setup cpu to node and node to cpumask arrays
34 * 64 *
@@ -49,8 +79,6 @@ void __init build_cpu_to_node_map(void)
49 node = node_cpuid[i].nid; 79 node = node_cpuid[i].nid;
50 break; 80 break;
51 } 81 }
52 cpu_to_node_map[cpu] = (node >= 0) ? node : 0; 82 map_cpu_to_node(cpu, node);
53 if (node >= 0)
54 cpu_set(cpu, node_to_cpu_mask[node]);
55 } 83 }
56} 84}
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index 84a7e52f56f6..281004ff7b00 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -34,6 +34,7 @@
34#include <linux/file.h> 34#include <linux/file.h>
35#include <linux/poll.h> 35#include <linux/poll.h>
36#include <linux/vfs.h> 36#include <linux/vfs.h>
37#include <linux/smp.h>
37#include <linux/pagemap.h> 38#include <linux/pagemap.h>
38#include <linux/mount.h> 39#include <linux/mount.h>
39#include <linux/bitops.h> 40#include <linux/bitops.h>
@@ -62,6 +63,9 @@
62 63
63#define PFM_INVALID_ACTIVATION (~0UL) 64#define PFM_INVALID_ACTIVATION (~0UL)
64 65
66#define PFM_NUM_PMC_REGS 64 /* PMC save area for ctxsw */
67#define PFM_NUM_PMD_REGS 64 /* PMD save area for ctxsw */
68
65/* 69/*
66 * depth of message queue 70 * depth of message queue
67 */ 71 */
@@ -296,14 +300,17 @@ typedef struct pfm_context {
296 unsigned long ctx_reload_pmcs[4]; /* bitmask of force reload PMC on ctxsw in */ 300 unsigned long ctx_reload_pmcs[4]; /* bitmask of force reload PMC on ctxsw in */
297 unsigned long ctx_used_monitors[4]; /* bitmask of monitor PMC being used */ 301 unsigned long ctx_used_monitors[4]; /* bitmask of monitor PMC being used */
298 302
299 unsigned long ctx_pmcs[IA64_NUM_PMC_REGS]; /* saved copies of PMC values */ 303 unsigned long ctx_pmcs[PFM_NUM_PMC_REGS]; /* saved copies of PMC values */
300 304
301 unsigned int ctx_used_ibrs[1]; /* bitmask of used IBR (speedup ctxsw in) */ 305 unsigned int ctx_used_ibrs[1]; /* bitmask of used IBR (speedup ctxsw in) */
302 unsigned int ctx_used_dbrs[1]; /* bitmask of used DBR (speedup ctxsw in) */ 306 unsigned int ctx_used_dbrs[1]; /* bitmask of used DBR (speedup ctxsw in) */
303 unsigned long ctx_dbrs[IA64_NUM_DBG_REGS]; /* DBR values (cache) when not loaded */ 307 unsigned long ctx_dbrs[IA64_NUM_DBG_REGS]; /* DBR values (cache) when not loaded */
304 unsigned long ctx_ibrs[IA64_NUM_DBG_REGS]; /* IBR values (cache) when not loaded */ 308 unsigned long ctx_ibrs[IA64_NUM_DBG_REGS]; /* IBR values (cache) when not loaded */
305 309
306 pfm_counter_t ctx_pmds[IA64_NUM_PMD_REGS]; /* software state for PMDS */ 310 pfm_counter_t ctx_pmds[PFM_NUM_PMD_REGS]; /* software state for PMDS */
311
312 unsigned long th_pmcs[PFM_NUM_PMC_REGS]; /* PMC thread save state */
313 unsigned long th_pmds[PFM_NUM_PMD_REGS]; /* PMD thread save state */
307 314
308 u64 ctx_saved_psr_up; /* only contains psr.up value */ 315 u64 ctx_saved_psr_up; /* only contains psr.up value */
309 316
@@ -867,7 +874,6 @@ static void
867pfm_mask_monitoring(struct task_struct *task) 874pfm_mask_monitoring(struct task_struct *task)
868{ 875{
869 pfm_context_t *ctx = PFM_GET_CTX(task); 876 pfm_context_t *ctx = PFM_GET_CTX(task);
870 struct thread_struct *th = &task->thread;
871 unsigned long mask, val, ovfl_mask; 877 unsigned long mask, val, ovfl_mask;
872 int i; 878 int i;
873 879
@@ -888,7 +894,7 @@ pfm_mask_monitoring(struct task_struct *task)
888 * So in both cases, the live register contains the owner's 894 * So in both cases, the live register contains the owner's
889 * state. We can ONLY touch the PMU registers and NOT the PSR. 895 * state. We can ONLY touch the PMU registers and NOT the PSR.
890 * 896 *
891 * As a consequence to this call, the thread->pmds[] array 897 * As a consequence to this call, the ctx->th_pmds[] array
892 * contains stale information which must be ignored 898 * contains stale information which must be ignored
893 * when context is reloaded AND monitoring is active (see 899 * when context is reloaded AND monitoring is active (see
894 * pfm_restart). 900 * pfm_restart).
@@ -923,9 +929,9 @@ pfm_mask_monitoring(struct task_struct *task)
923 mask = ctx->ctx_used_monitors[0] >> PMU_FIRST_COUNTER; 929 mask = ctx->ctx_used_monitors[0] >> PMU_FIRST_COUNTER;
924 for(i= PMU_FIRST_COUNTER; mask; i++, mask>>=1) { 930 for(i= PMU_FIRST_COUNTER; mask; i++, mask>>=1) {
925 if ((mask & 0x1) == 0UL) continue; 931 if ((mask & 0x1) == 0UL) continue;
926 ia64_set_pmc(i, th->pmcs[i] & ~0xfUL); 932 ia64_set_pmc(i, ctx->th_pmcs[i] & ~0xfUL);
927 th->pmcs[i] &= ~0xfUL; 933 ctx->th_pmcs[i] &= ~0xfUL;
928 DPRINT_ovfl(("pmc[%d]=0x%lx\n", i, th->pmcs[i])); 934 DPRINT_ovfl(("pmc[%d]=0x%lx\n", i, ctx->th_pmcs[i]));
929 } 935 }
930 /* 936 /*
931 * make all of this visible 937 * make all of this visible
@@ -942,7 +948,6 @@ static void
942pfm_restore_monitoring(struct task_struct *task) 948pfm_restore_monitoring(struct task_struct *task)
943{ 949{
944 pfm_context_t *ctx = PFM_GET_CTX(task); 950 pfm_context_t *ctx = PFM_GET_CTX(task);
945 struct thread_struct *th = &task->thread;
946 unsigned long mask, ovfl_mask; 951 unsigned long mask, ovfl_mask;
947 unsigned long psr, val; 952 unsigned long psr, val;
948 int i, is_system; 953 int i, is_system;
@@ -1008,9 +1013,9 @@ pfm_restore_monitoring(struct task_struct *task)
1008 mask = ctx->ctx_used_monitors[0] >> PMU_FIRST_COUNTER; 1013 mask = ctx->ctx_used_monitors[0] >> PMU_FIRST_COUNTER;
1009 for(i= PMU_FIRST_COUNTER; mask; i++, mask>>=1) { 1014 for(i= PMU_FIRST_COUNTER; mask; i++, mask>>=1) {
1010 if ((mask & 0x1) == 0UL) continue; 1015 if ((mask & 0x1) == 0UL) continue;
1011 th->pmcs[i] = ctx->ctx_pmcs[i]; 1016 ctx->th_pmcs[i] = ctx->ctx_pmcs[i];
1012 ia64_set_pmc(i, th->pmcs[i]); 1017 ia64_set_pmc(i, ctx->th_pmcs[i]);
1013 DPRINT(("[%d] pmc[%d]=0x%lx\n", task->pid, i, th->pmcs[i])); 1018 DPRINT(("[%d] pmc[%d]=0x%lx\n", task->pid, i, ctx->th_pmcs[i]));
1014 } 1019 }
1015 ia64_srlz_d(); 1020 ia64_srlz_d();
1016 1021
@@ -1069,7 +1074,6 @@ pfm_restore_pmds(unsigned long *pmds, unsigned long mask)
1069static inline void 1074static inline void
1070pfm_copy_pmds(struct task_struct *task, pfm_context_t *ctx) 1075pfm_copy_pmds(struct task_struct *task, pfm_context_t *ctx)
1071{ 1076{
1072 struct thread_struct *thread = &task->thread;
1073 unsigned long ovfl_val = pmu_conf->ovfl_val; 1077 unsigned long ovfl_val = pmu_conf->ovfl_val;
1074 unsigned long mask = ctx->ctx_all_pmds[0]; 1078 unsigned long mask = ctx->ctx_all_pmds[0];
1075 unsigned long val; 1079 unsigned long val;
@@ -1091,11 +1095,11 @@ pfm_copy_pmds(struct task_struct *task, pfm_context_t *ctx)
1091 ctx->ctx_pmds[i].val = val & ~ovfl_val; 1095 ctx->ctx_pmds[i].val = val & ~ovfl_val;
1092 val &= ovfl_val; 1096 val &= ovfl_val;
1093 } 1097 }
1094 thread->pmds[i] = val; 1098 ctx->th_pmds[i] = val;
1095 1099
1096 DPRINT(("pmd[%d]=0x%lx soft_val=0x%lx\n", 1100 DPRINT(("pmd[%d]=0x%lx soft_val=0x%lx\n",
1097 i, 1101 i,
1098 thread->pmds[i], 1102 ctx->th_pmds[i],
1099 ctx->ctx_pmds[i].val)); 1103 ctx->ctx_pmds[i].val));
1100 } 1104 }
1101} 1105}
@@ -1106,7 +1110,6 @@ pfm_copy_pmds(struct task_struct *task, pfm_context_t *ctx)
1106static inline void 1110static inline void
1107pfm_copy_pmcs(struct task_struct *task, pfm_context_t *ctx) 1111pfm_copy_pmcs(struct task_struct *task, pfm_context_t *ctx)
1108{ 1112{
1109 struct thread_struct *thread = &task->thread;
1110 unsigned long mask = ctx->ctx_all_pmcs[0]; 1113 unsigned long mask = ctx->ctx_all_pmcs[0];
1111 int i; 1114 int i;
1112 1115
@@ -1114,8 +1117,8 @@ pfm_copy_pmcs(struct task_struct *task, pfm_context_t *ctx)
1114 1117
1115 for (i=0; mask; i++, mask>>=1) { 1118 for (i=0; mask; i++, mask>>=1) {
1116 /* masking 0 with ovfl_val yields 0 */ 1119 /* masking 0 with ovfl_val yields 0 */
1117 thread->pmcs[i] = ctx->ctx_pmcs[i]; 1120 ctx->th_pmcs[i] = ctx->ctx_pmcs[i];
1118 DPRINT(("pmc[%d]=0x%lx\n", i, thread->pmcs[i])); 1121 DPRINT(("pmc[%d]=0x%lx\n", i, ctx->th_pmcs[i]));
1119 } 1122 }
1120} 1123}
1121 1124
@@ -2859,7 +2862,6 @@ pfm_reset_regs(pfm_context_t *ctx, unsigned long *ovfl_regs, int is_long_reset)
2859static int 2862static int
2860pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) 2863pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
2861{ 2864{
2862 struct thread_struct *thread = NULL;
2863 struct task_struct *task; 2865 struct task_struct *task;
2864 pfarg_reg_t *req = (pfarg_reg_t *)arg; 2866 pfarg_reg_t *req = (pfarg_reg_t *)arg;
2865 unsigned long value, pmc_pm; 2867 unsigned long value, pmc_pm;
@@ -2880,7 +2882,6 @@ pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
2880 if (state == PFM_CTX_ZOMBIE) return -EINVAL; 2882 if (state == PFM_CTX_ZOMBIE) return -EINVAL;
2881 2883
2882 if (is_loaded) { 2884 if (is_loaded) {
2883 thread = &task->thread;
2884 /* 2885 /*
2885 * In system wide and when the context is loaded, access can only happen 2886 * In system wide and when the context is loaded, access can only happen
2886 * when the caller is running on the CPU being monitored by the session. 2887 * when the caller is running on the CPU being monitored by the session.
@@ -3035,7 +3036,7 @@ pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
3035 * 3036 *
3036 * The value in ctx_pmcs[] can only be changed in pfm_write_pmcs(). 3037 * The value in ctx_pmcs[] can only be changed in pfm_write_pmcs().
3037 * 3038 *
3038 * The value in thread->pmcs[] may be modified on overflow, i.e., when 3039 * The value in th_pmcs[] may be modified on overflow, i.e., when
3039 * monitoring needs to be stopped. 3040 * monitoring needs to be stopped.
3040 */ 3041 */
3041 if (is_monitor) CTX_USED_MONITOR(ctx, 1UL << cnum); 3042 if (is_monitor) CTX_USED_MONITOR(ctx, 1UL << cnum);
@@ -3049,7 +3050,7 @@ pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
3049 /* 3050 /*
3050 * write thread state 3051 * write thread state
3051 */ 3052 */
3052 if (is_system == 0) thread->pmcs[cnum] = value; 3053 if (is_system == 0) ctx->th_pmcs[cnum] = value;
3053 3054
3054 /* 3055 /*
3055 * write hardware register if we can 3056 * write hardware register if we can
@@ -3101,7 +3102,6 @@ error:
3101static int 3102static int
3102pfm_write_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) 3103pfm_write_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
3103{ 3104{
3104 struct thread_struct *thread = NULL;
3105 struct task_struct *task; 3105 struct task_struct *task;
3106 pfarg_reg_t *req = (pfarg_reg_t *)arg; 3106 pfarg_reg_t *req = (pfarg_reg_t *)arg;
3107 unsigned long value, hw_value, ovfl_mask; 3107 unsigned long value, hw_value, ovfl_mask;
@@ -3125,7 +3125,6 @@ pfm_write_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
3125 * the owner of the local PMU. 3125 * the owner of the local PMU.
3126 */ 3126 */
3127 if (likely(is_loaded)) { 3127 if (likely(is_loaded)) {
3128 thread = &task->thread;
3129 /* 3128 /*
3130 * In system wide and when the context is loaded, access can only happen 3129 * In system wide and when the context is loaded, access can only happen
3131 * when the caller is running on the CPU being monitored by the session. 3130 * when the caller is running on the CPU being monitored by the session.
@@ -3233,7 +3232,7 @@ pfm_write_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
3233 /* 3232 /*
3234 * write thread state 3233 * write thread state
3235 */ 3234 */
3236 if (is_system == 0) thread->pmds[cnum] = hw_value; 3235 if (is_system == 0) ctx->th_pmds[cnum] = hw_value;
3237 3236
3238 /* 3237 /*
3239 * write hardware register if we can 3238 * write hardware register if we can
@@ -3299,7 +3298,6 @@ abort_mission:
3299static int 3298static int
3300pfm_read_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) 3299pfm_read_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
3301{ 3300{
3302 struct thread_struct *thread = NULL;
3303 struct task_struct *task; 3301 struct task_struct *task;
3304 unsigned long val = 0UL, lval, ovfl_mask, sval; 3302 unsigned long val = 0UL, lval, ovfl_mask, sval;
3305 pfarg_reg_t *req = (pfarg_reg_t *)arg; 3303 pfarg_reg_t *req = (pfarg_reg_t *)arg;
@@ -3323,7 +3321,6 @@ pfm_read_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
3323 if (state == PFM_CTX_ZOMBIE) return -EINVAL; 3321 if (state == PFM_CTX_ZOMBIE) return -EINVAL;
3324 3322
3325 if (likely(is_loaded)) { 3323 if (likely(is_loaded)) {
3326 thread = &task->thread;
3327 /* 3324 /*
3328 * In system wide and when the context is loaded, access can only happen 3325 * In system wide and when the context is loaded, access can only happen
3329 * when the caller is running on the CPU being monitored by the session. 3326 * when the caller is running on the CPU being monitored by the session.
@@ -3385,7 +3382,7 @@ pfm_read_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
3385 * if context is zombie, then task does not exist anymore. 3382 * if context is zombie, then task does not exist anymore.
3386 * In this case, we use the full value saved in the context (pfm_flush_regs()). 3383 * In this case, we use the full value saved in the context (pfm_flush_regs()).
3387 */ 3384 */
3388 val = is_loaded ? thread->pmds[cnum] : 0UL; 3385 val = is_loaded ? ctx->th_pmds[cnum] : 0UL;
3389 } 3386 }
3390 rd_func = pmu_conf->pmd_desc[cnum].read_check; 3387 rd_func = pmu_conf->pmd_desc[cnum].read_check;
3391 3388
@@ -4354,8 +4351,8 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
4354 pfm_copy_pmds(task, ctx); 4351 pfm_copy_pmds(task, ctx);
4355 pfm_copy_pmcs(task, ctx); 4352 pfm_copy_pmcs(task, ctx);
4356 4353
4357 pmcs_source = thread->pmcs; 4354 pmcs_source = ctx->th_pmcs;
4358 pmds_source = thread->pmds; 4355 pmds_source = ctx->th_pmds;
4359 4356
4360 /* 4357 /*
4361 * always the case for system-wide 4358 * always the case for system-wide
@@ -5864,14 +5861,12 @@ void
5864pfm_save_regs(struct task_struct *task) 5861pfm_save_regs(struct task_struct *task)
5865{ 5862{
5866 pfm_context_t *ctx; 5863 pfm_context_t *ctx;
5867 struct thread_struct *t;
5868 unsigned long flags; 5864 unsigned long flags;
5869 u64 psr; 5865 u64 psr;
5870 5866
5871 5867
5872 ctx = PFM_GET_CTX(task); 5868 ctx = PFM_GET_CTX(task);
5873 if (ctx == NULL) return; 5869 if (ctx == NULL) return;
5874 t = &task->thread;
5875 5870
5876 /* 5871 /*
5877 * we always come here with interrupts ALREADY disabled by 5872 * we always come here with interrupts ALREADY disabled by
@@ -5929,19 +5924,19 @@ pfm_save_regs(struct task_struct *task)
5929 * guarantee we will be schedule at that same 5924 * guarantee we will be schedule at that same
5930 * CPU again. 5925 * CPU again.
5931 */ 5926 */
5932 pfm_save_pmds(t->pmds, ctx->ctx_used_pmds[0]); 5927 pfm_save_pmds(ctx->th_pmds, ctx->ctx_used_pmds[0]);
5933 5928
5934 /* 5929 /*
5935 * save pmc0 ia64_srlz_d() done in pfm_save_pmds() 5930 * save pmc0 ia64_srlz_d() done in pfm_save_pmds()
5936 * we will need it on the restore path to check 5931 * we will need it on the restore path to check
5937 * for pending overflow. 5932 * for pending overflow.
5938 */ 5933 */
5939 t->pmcs[0] = ia64_get_pmc(0); 5934 ctx->th_pmcs[0] = ia64_get_pmc(0);
5940 5935
5941 /* 5936 /*
5942 * unfreeze PMU if had pending overflows 5937 * unfreeze PMU if had pending overflows
5943 */ 5938 */
5944 if (t->pmcs[0] & ~0x1UL) pfm_unfreeze_pmu(); 5939 if (ctx->th_pmcs[0] & ~0x1UL) pfm_unfreeze_pmu();
5945 5940
5946 /* 5941 /*
5947 * finally, allow context access. 5942 * finally, allow context access.
@@ -5986,7 +5981,6 @@ static void
5986pfm_lazy_save_regs (struct task_struct *task) 5981pfm_lazy_save_regs (struct task_struct *task)
5987{ 5982{
5988 pfm_context_t *ctx; 5983 pfm_context_t *ctx;
5989 struct thread_struct *t;
5990 unsigned long flags; 5984 unsigned long flags;
5991 5985
5992 { u64 psr = pfm_get_psr(); 5986 { u64 psr = pfm_get_psr();
@@ -5994,7 +5988,6 @@ pfm_lazy_save_regs (struct task_struct *task)
5994 } 5988 }
5995 5989
5996 ctx = PFM_GET_CTX(task); 5990 ctx = PFM_GET_CTX(task);
5997 t = &task->thread;
5998 5991
5999 /* 5992 /*
6000 * we need to mask PMU overflow here to 5993 * we need to mask PMU overflow here to
@@ -6019,19 +6012,19 @@ pfm_lazy_save_regs (struct task_struct *task)
6019 /* 6012 /*
6020 * save all the pmds we use 6013 * save all the pmds we use
6021 */ 6014 */
6022 pfm_save_pmds(t->pmds, ctx->ctx_used_pmds[0]); 6015 pfm_save_pmds(ctx->th_pmds, ctx->ctx_used_pmds[0]);
6023 6016
6024 /* 6017 /*
6025 * save pmc0 ia64_srlz_d() done in pfm_save_pmds() 6018 * save pmc0 ia64_srlz_d() done in pfm_save_pmds()
6026 * it is needed to check for pended overflow 6019 * it is needed to check for pended overflow
6027 * on the restore path 6020 * on the restore path
6028 */ 6021 */
6029 t->pmcs[0] = ia64_get_pmc(0); 6022 ctx->th_pmcs[0] = ia64_get_pmc(0);
6030 6023
6031 /* 6024 /*
6032 * unfreeze PMU if had pending overflows 6025 * unfreeze PMU if had pending overflows
6033 */ 6026 */
6034 if (t->pmcs[0] & ~0x1UL) pfm_unfreeze_pmu(); 6027 if (ctx->th_pmcs[0] & ~0x1UL) pfm_unfreeze_pmu();
6035 6028
6036 /* 6029 /*
6037 * now get can unmask PMU interrupts, they will 6030 * now get can unmask PMU interrupts, they will
@@ -6050,7 +6043,6 @@ void
6050pfm_load_regs (struct task_struct *task) 6043pfm_load_regs (struct task_struct *task)
6051{ 6044{
6052 pfm_context_t *ctx; 6045 pfm_context_t *ctx;
6053 struct thread_struct *t;
6054 unsigned long pmc_mask = 0UL, pmd_mask = 0UL; 6046 unsigned long pmc_mask = 0UL, pmd_mask = 0UL;
6055 unsigned long flags; 6047 unsigned long flags;
6056 u64 psr, psr_up; 6048 u64 psr, psr_up;
@@ -6061,11 +6053,10 @@ pfm_load_regs (struct task_struct *task)
6061 6053
6062 BUG_ON(GET_PMU_OWNER()); 6054 BUG_ON(GET_PMU_OWNER());
6063 6055
6064 t = &task->thread;
6065 /* 6056 /*
6066 * possible on unload 6057 * possible on unload
6067 */ 6058 */
6068 if (unlikely((t->flags & IA64_THREAD_PM_VALID) == 0)) return; 6059 if (unlikely((task->thread.flags & IA64_THREAD_PM_VALID) == 0)) return;
6069 6060
6070 /* 6061 /*
6071 * we always come here with interrupts ALREADY disabled by 6062 * we always come here with interrupts ALREADY disabled by
@@ -6147,21 +6138,21 @@ pfm_load_regs (struct task_struct *task)
6147 * 6138 *
6148 * XXX: optimize here 6139 * XXX: optimize here
6149 */ 6140 */
6150 if (pmd_mask) pfm_restore_pmds(t->pmds, pmd_mask); 6141 if (pmd_mask) pfm_restore_pmds(ctx->th_pmds, pmd_mask);
6151 if (pmc_mask) pfm_restore_pmcs(t->pmcs, pmc_mask); 6142 if (pmc_mask) pfm_restore_pmcs(ctx->th_pmcs, pmc_mask);
6152 6143
6153 /* 6144 /*
6154 * check for pending overflow at the time the state 6145 * check for pending overflow at the time the state
6155 * was saved. 6146 * was saved.
6156 */ 6147 */
6157 if (unlikely(PMC0_HAS_OVFL(t->pmcs[0]))) { 6148 if (unlikely(PMC0_HAS_OVFL(ctx->th_pmcs[0]))) {
6158 /* 6149 /*
6159 * reload pmc0 with the overflow information 6150 * reload pmc0 with the overflow information
6160 * On McKinley PMU, this will trigger a PMU interrupt 6151 * On McKinley PMU, this will trigger a PMU interrupt
6161 */ 6152 */
6162 ia64_set_pmc(0, t->pmcs[0]); 6153 ia64_set_pmc(0, ctx->th_pmcs[0]);
6163 ia64_srlz_d(); 6154 ia64_srlz_d();
6164 t->pmcs[0] = 0UL; 6155 ctx->th_pmcs[0] = 0UL;
6165 6156
6166 /* 6157 /*
6167 * will replay the PMU interrupt 6158 * will replay the PMU interrupt
@@ -6214,7 +6205,6 @@ pfm_load_regs (struct task_struct *task)
6214void 6205void
6215pfm_load_regs (struct task_struct *task) 6206pfm_load_regs (struct task_struct *task)
6216{ 6207{
6217 struct thread_struct *t;
6218 pfm_context_t *ctx; 6208 pfm_context_t *ctx;
6219 struct task_struct *owner; 6209 struct task_struct *owner;
6220 unsigned long pmd_mask, pmc_mask; 6210 unsigned long pmd_mask, pmc_mask;
@@ -6223,7 +6213,6 @@ pfm_load_regs (struct task_struct *task)
6223 6213
6224 owner = GET_PMU_OWNER(); 6214 owner = GET_PMU_OWNER();
6225 ctx = PFM_GET_CTX(task); 6215 ctx = PFM_GET_CTX(task);
6226 t = &task->thread;
6227 psr = pfm_get_psr(); 6216 psr = pfm_get_psr();
6228 6217
6229 BUG_ON(psr & (IA64_PSR_UP|IA64_PSR_PP)); 6218 BUG_ON(psr & (IA64_PSR_UP|IA64_PSR_PP));
@@ -6286,22 +6275,22 @@ pfm_load_regs (struct task_struct *task)
6286 */ 6275 */
6287 pmc_mask = ctx->ctx_all_pmcs[0]; 6276 pmc_mask = ctx->ctx_all_pmcs[0];
6288 6277
6289 pfm_restore_pmds(t->pmds, pmd_mask); 6278 pfm_restore_pmds(ctx->th_pmds, pmd_mask);
6290 pfm_restore_pmcs(t->pmcs, pmc_mask); 6279 pfm_restore_pmcs(ctx->th_pmcs, pmc_mask);
6291 6280
6292 /* 6281 /*
6293 * check for pending overflow at the time the state 6282 * check for pending overflow at the time the state
6294 * was saved. 6283 * was saved.
6295 */ 6284 */
6296 if (unlikely(PMC0_HAS_OVFL(t->pmcs[0]))) { 6285 if (unlikely(PMC0_HAS_OVFL(ctx->th_pmcs[0]))) {
6297 /* 6286 /*
6298 * reload pmc0 with the overflow information 6287 * reload pmc0 with the overflow information
6299 * On McKinley PMU, this will trigger a PMU interrupt 6288 * On McKinley PMU, this will trigger a PMU interrupt
6300 */ 6289 */
6301 ia64_set_pmc(0, t->pmcs[0]); 6290 ia64_set_pmc(0, ctx->th_pmcs[0]);
6302 ia64_srlz_d(); 6291 ia64_srlz_d();
6303 6292
6304 t->pmcs[0] = 0UL; 6293 ctx->th_pmcs[0] = 0UL;
6305 6294
6306 /* 6295 /*
6307 * will replay the PMU interrupt 6296 * will replay the PMU interrupt
@@ -6376,11 +6365,11 @@ pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx)
6376 */ 6365 */
6377 pfm_unfreeze_pmu(); 6366 pfm_unfreeze_pmu();
6378 } else { 6367 } else {
6379 pmc0 = task->thread.pmcs[0]; 6368 pmc0 = ctx->th_pmcs[0];
6380 /* 6369 /*
6381 * clear whatever overflow status bits there were 6370 * clear whatever overflow status bits there were
6382 */ 6371 */
6383 task->thread.pmcs[0] = 0; 6372 ctx->th_pmcs[0] = 0;
6384 } 6373 }
6385 ovfl_val = pmu_conf->ovfl_val; 6374 ovfl_val = pmu_conf->ovfl_val;
6386 /* 6375 /*
@@ -6401,7 +6390,7 @@ pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx)
6401 /* 6390 /*
6402 * can access PMU always true in system wide mode 6391 * can access PMU always true in system wide mode
6403 */ 6392 */
6404 val = pmd_val = can_access_pmu ? ia64_get_pmd(i) : task->thread.pmds[i]; 6393 val = pmd_val = can_access_pmu ? ia64_get_pmd(i) : ctx->th_pmds[i];
6405 6394
6406 if (PMD_IS_COUNTING(i)) { 6395 if (PMD_IS_COUNTING(i)) {
6407 DPRINT(("[%d] pmd[%d] ctx_pmd=0x%lx hw_pmd=0x%lx\n", 6396 DPRINT(("[%d] pmd[%d] ctx_pmd=0x%lx hw_pmd=0x%lx\n",
@@ -6433,7 +6422,7 @@ pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx)
6433 6422
6434 DPRINT(("[%d] ctx_pmd[%d]=0x%lx pmd_val=0x%lx\n", task->pid, i, val, pmd_val)); 6423 DPRINT(("[%d] ctx_pmd[%d]=0x%lx pmd_val=0x%lx\n", task->pid, i, val, pmd_val));
6435 6424
6436 if (is_self) task->thread.pmds[i] = pmd_val; 6425 if (is_self) ctx->th_pmds[i] = pmd_val;
6437 6426
6438 ctx->ctx_pmds[i].val = val; 6427 ctx->ctx_pmds[i].val = val;
6439 } 6428 }
@@ -6677,7 +6666,7 @@ pfm_init(void)
6677 ffz(pmu_conf->ovfl_val)); 6666 ffz(pmu_conf->ovfl_val));
6678 6667
6679 /* sanity check */ 6668 /* sanity check */
6680 if (pmu_conf->num_pmds >= IA64_NUM_PMD_REGS || pmu_conf->num_pmcs >= IA64_NUM_PMC_REGS) { 6669 if (pmu_conf->num_pmds >= PFM_NUM_PMD_REGS || pmu_conf->num_pmcs >= PFM_NUM_PMC_REGS) {
6681 printk(KERN_ERR "perfmon: not enough pmc/pmd, perfmon disabled\n"); 6670 printk(KERN_ERR "perfmon: not enough pmc/pmd, perfmon disabled\n");
6682 pmu_conf = NULL; 6671 pmu_conf = NULL;
6683 return -1; 6672 return -1;
@@ -6752,7 +6741,6 @@ void
6752dump_pmu_state(const char *from) 6741dump_pmu_state(const char *from)
6753{ 6742{
6754 struct task_struct *task; 6743 struct task_struct *task;
6755 struct thread_struct *t;
6756 struct pt_regs *regs; 6744 struct pt_regs *regs;
6757 pfm_context_t *ctx; 6745 pfm_context_t *ctx;
6758 unsigned long psr, dcr, info, flags; 6746 unsigned long psr, dcr, info, flags;
@@ -6797,16 +6785,14 @@ dump_pmu_state(const char *from)
6797 ia64_psr(regs)->up = 0; 6785 ia64_psr(regs)->up = 0;
6798 ia64_psr(regs)->pp = 0; 6786 ia64_psr(regs)->pp = 0;
6799 6787
6800 t = &current->thread;
6801
6802 for (i=1; PMC_IS_LAST(i) == 0; i++) { 6788 for (i=1; PMC_IS_LAST(i) == 0; i++) {
6803 if (PMC_IS_IMPL(i) == 0) continue; 6789 if (PMC_IS_IMPL(i) == 0) continue;
6804 printk("->CPU%d pmc[%d]=0x%lx thread_pmc[%d]=0x%lx\n", this_cpu, i, ia64_get_pmc(i), i, t->pmcs[i]); 6790 printk("->CPU%d pmc[%d]=0x%lx thread_pmc[%d]=0x%lx\n", this_cpu, i, ia64_get_pmc(i), i, ctx->th_pmcs[i]);
6805 } 6791 }
6806 6792
6807 for (i=1; PMD_IS_LAST(i) == 0; i++) { 6793 for (i=1; PMD_IS_LAST(i) == 0; i++) {
6808 if (PMD_IS_IMPL(i) == 0) continue; 6794 if (PMD_IS_IMPL(i) == 0) continue;
6809 printk("->CPU%d pmd[%d]=0x%lx thread_pmd[%d]=0x%lx\n", this_cpu, i, ia64_get_pmd(i), i, t->pmds[i]); 6795 printk("->CPU%d pmd[%d]=0x%lx thread_pmd[%d]=0x%lx\n", this_cpu, i, ia64_get_pmd(i), i, ctx->th_pmds[i]);
6810 } 6796 }
6811 6797
6812 if (ctx) { 6798 if (ctx) {
diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c
index 9065f0f01ba3..e63b8ca5344a 100644
--- a/arch/ia64/kernel/salinfo.c
+++ b/arch/ia64/kernel/salinfo.c
@@ -266,6 +266,7 @@ salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe)
266/* Check for outstanding MCA/INIT records every minute (arbitrary) */ 266/* Check for outstanding MCA/INIT records every minute (arbitrary) */
267#define SALINFO_TIMER_DELAY (60*HZ) 267#define SALINFO_TIMER_DELAY (60*HZ)
268static struct timer_list salinfo_timer; 268static struct timer_list salinfo_timer;
269extern void ia64_mlogbuf_dump(void);
269 270
270static void 271static void
271salinfo_timeout_check(struct salinfo_data *data) 272salinfo_timeout_check(struct salinfo_data *data)
@@ -283,6 +284,7 @@ salinfo_timeout_check(struct salinfo_data *data)
283static void 284static void
284salinfo_timeout (unsigned long arg) 285salinfo_timeout (unsigned long arg)
285{ 286{
287 ia64_mlogbuf_dump();
286 salinfo_timeout_check(salinfo_data + SAL_INFO_TYPE_MCA); 288 salinfo_timeout_check(salinfo_data + SAL_INFO_TYPE_MCA);
287 salinfo_timeout_check(salinfo_data + SAL_INFO_TYPE_INIT); 289 salinfo_timeout_check(salinfo_data + SAL_INFO_TYPE_INIT);
288 salinfo_timer.expires = jiffies + SALINFO_TIMER_DELAY; 290 salinfo_timer.expires = jiffies + SALINFO_TIMER_DELAY;
@@ -332,6 +334,8 @@ retry:
332 if (cpu == -1) 334 if (cpu == -1)
333 goto retry; 335 goto retry;
334 336
337 ia64_mlogbuf_dump();
338
335 /* for next read, start checking at next CPU */ 339 /* for next read, start checking at next CPU */
336 data->cpu_check = cpu; 340 data->cpu_check = cpu;
337 if (++data->cpu_check == NR_CPUS) 341 if (++data->cpu_check == NR_CPUS)
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 7ad0d9cc6db6..84f93c0f2c66 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -509,7 +509,7 @@ show_cpuinfo (struct seq_file *m, void *v)
509 { 1UL << 1, "spontaneous deferral"}, 509 { 1UL << 1, "spontaneous deferral"},
510 { 1UL << 2, "16-byte atomic ops" } 510 { 1UL << 2, "16-byte atomic ops" }
511 }; 511 };
512 char family[32], features[128], *cp, sep; 512 char features[128], *cp, sep;
513 struct cpuinfo_ia64 *c = v; 513 struct cpuinfo_ia64 *c = v;
514 unsigned long mask; 514 unsigned long mask;
515 unsigned long proc_freq; 515 unsigned long proc_freq;
@@ -517,12 +517,6 @@ show_cpuinfo (struct seq_file *m, void *v)
517 517
518 mask = c->features; 518 mask = c->features;
519 519
520 switch (c->family) {
521 case 0x07: memcpy(family, "Itanium", 8); break;
522 case 0x1f: memcpy(family, "Itanium 2", 10); break;
523 default: sprintf(family, "%u", c->family); break;
524 }
525
526 /* build the feature string: */ 520 /* build the feature string: */
527 memcpy(features, " standard", 10); 521 memcpy(features, " standard", 10);
528 cp = features; 522 cp = features;
@@ -553,8 +547,9 @@ show_cpuinfo (struct seq_file *m, void *v)
553 "processor : %d\n" 547 "processor : %d\n"
554 "vendor : %s\n" 548 "vendor : %s\n"
555 "arch : IA-64\n" 549 "arch : IA-64\n"
556 "family : %s\n" 550 "family : %u\n"
557 "model : %u\n" 551 "model : %u\n"
552 "model name : %s\n"
558 "revision : %u\n" 553 "revision : %u\n"
559 "archrev : %u\n" 554 "archrev : %u\n"
560 "features :%s\n" /* don't change this---it _is_ right! */ 555 "features :%s\n" /* don't change this---it _is_ right! */
@@ -563,7 +558,8 @@ show_cpuinfo (struct seq_file *m, void *v)
563 "cpu MHz : %lu.%06lu\n" 558 "cpu MHz : %lu.%06lu\n"
564 "itc MHz : %lu.%06lu\n" 559 "itc MHz : %lu.%06lu\n"
565 "BogoMIPS : %lu.%02lu\n", 560 "BogoMIPS : %lu.%02lu\n",
566 cpunum, c->vendor, family, c->model, c->revision, c->archrev, 561 cpunum, c->vendor, c->family, c->model,
562 c->model_name, c->revision, c->archrev,
567 features, c->ppn, c->number, 563 features, c->ppn, c->number,
568 proc_freq / 1000, proc_freq % 1000, 564 proc_freq / 1000, proc_freq % 1000,
569 c->itc_freq / 1000000, c->itc_freq % 1000000, 565 c->itc_freq / 1000000, c->itc_freq % 1000000,
@@ -611,6 +607,31 @@ struct seq_operations cpuinfo_op = {
611 .show = show_cpuinfo 607 .show = show_cpuinfo
612}; 608};
613 609
610static char brandname[128];
611
612static char * __cpuinit
613get_model_name(__u8 family, __u8 model)
614{
615 char brand[128];
616
617 if (ia64_pal_get_brand_info(brand)) {
618 if (family == 0x7)
619 memcpy(brand, "Merced", 7);
620 else if (family == 0x1f) switch (model) {
621 case 0: memcpy(brand, "McKinley", 9); break;
622 case 1: memcpy(brand, "Madison", 8); break;
623 case 2: memcpy(brand, "Madison up to 9M cache", 23); break;
624 } else
625 memcpy(brand, "Unknown", 8);
626 }
627 if (brandname[0] == '\0')
628 return strcpy(brandname, brand);
629 else if (strcmp(brandname, brand) == 0)
630 return brandname;
631 else
632 return kstrdup(brand, GFP_KERNEL);
633}
634
614static void __cpuinit 635static void __cpuinit
615identify_cpu (struct cpuinfo_ia64 *c) 636identify_cpu (struct cpuinfo_ia64 *c)
616{ 637{
@@ -640,7 +661,6 @@ identify_cpu (struct cpuinfo_ia64 *c)
640 pal_status_t status; 661 pal_status_t status;
641 unsigned long impl_va_msb = 50, phys_addr_size = 44; /* Itanium defaults */ 662 unsigned long impl_va_msb = 50, phys_addr_size = 44; /* Itanium defaults */
642 int i; 663 int i;
643
644 for (i = 0; i < 5; ++i) 664 for (i = 0; i < 5; ++i)
645 cpuid.bits[i] = ia64_get_cpuid(i); 665 cpuid.bits[i] = ia64_get_cpuid(i);
646 666
@@ -663,6 +683,7 @@ identify_cpu (struct cpuinfo_ia64 *c)
663 c->family = cpuid.field.family; 683 c->family = cpuid.field.family;
664 c->archrev = cpuid.field.archrev; 684 c->archrev = cpuid.field.archrev;
665 c->features = cpuid.field.features; 685 c->features = cpuid.field.features;
686 c->model_name = get_model_name(c->family, c->model);
666 687
667 status = ia64_pal_vm_summary(&vm1, &vm2); 688 status = ia64_pal_vm_summary(&vm1, &vm2);
668 if (status == PAL_STATUS_SUCCESS) { 689 if (status == PAL_STATUS_SUCCESS) {
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 6203ed4ec8cf..f7d7f5668144 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -879,3 +879,27 @@ identify_siblings(struct cpuinfo_ia64 *c)
879 c->core_id = info.log1_cid; 879 c->core_id = info.log1_cid;
880 c->thread_id = info.log1_tid; 880 c->thread_id = info.log1_tid;
881} 881}
882
883/*
884 * returns non zero, if multi-threading is enabled
885 * on at least one physical package. Due to hotplug cpu
886 * and (maxcpus=), all threads may not necessarily be enabled
887 * even though the processor supports multi-threading.
888 */
889int is_multithreading_enabled(void)
890{
891 int i, j;
892
893 for_each_present_cpu(i) {
894 for_each_present_cpu(j) {
895 if (j == i)
896 continue;
897 if ((cpu_data(j)->socket_id == cpu_data(i)->socket_id)) {
898 if (cpu_data(j)->core_id == cpu_data(i)->core_id)
899 return 1;
900 }
901 }
902 }
903 return 0;
904}
905EXPORT_SYMBOL_GPL(is_multithreading_enabled);
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
index f648c610b10c..5629b45e89c6 100644
--- a/arch/ia64/kernel/topology.c
+++ b/arch/ia64/kernel/topology.c
@@ -36,6 +36,7 @@ int arch_register_cpu(int num)
36 */ 36 */
37 if (!can_cpei_retarget() && is_cpu_cpei_target(num)) 37 if (!can_cpei_retarget() && is_cpu_cpei_target(num))
38 sysfs_cpus[num].cpu.no_control = 1; 38 sysfs_cpus[num].cpu.no_control = 1;
39 map_cpu_to_node(num, node_cpuid[num].nid);
39#endif 40#endif
40 41
41 return register_cpu(&sysfs_cpus[num].cpu, num); 42 return register_cpu(&sysfs_cpus[num].cpu, num);
@@ -45,7 +46,8 @@ int arch_register_cpu(int num)
45 46
46void arch_unregister_cpu(int num) 47void arch_unregister_cpu(int num)
47{ 48{
48 return unregister_cpu(&sysfs_cpus[num].cpu); 49 unregister_cpu(&sysfs_cpus[num].cpu);
50 unmap_cpu_from_node(num, cpu_to_node(num));
49} 51}
50EXPORT_SYMBOL(arch_register_cpu); 52EXPORT_SYMBOL(arch_register_cpu);
51EXPORT_SYMBOL(arch_unregister_cpu); 53EXPORT_SYMBOL(arch_unregister_cpu);
diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c
index 4c73a6763669..c58e933694d5 100644
--- a/arch/ia64/kernel/uncached.c
+++ b/arch/ia64/kernel/uncached.c
@@ -98,7 +98,7 @@ static int uncached_add_chunk(struct uncached_pool *uc_pool, int nid)
98 98
99 /* attempt to allocate a granule's worth of cached memory pages */ 99 /* attempt to allocate a granule's worth of cached memory pages */
100 100
101 page = alloc_pages_node(nid, GFP_KERNEL | __GFP_ZERO, 101 page = alloc_pages_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE,
102 IA64_GRANULE_SHIFT-PAGE_SHIFT); 102 IA64_GRANULE_SHIFT-PAGE_SHIFT);
103 if (!page) { 103 if (!page) {
104 mutex_unlock(&uc_pool->add_chunk_mutex); 104 mutex_unlock(&uc_pool->add_chunk_mutex);
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index 5b0d5f64a9b1..b3b2e389d6b2 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -184,7 +184,9 @@ SECTIONS
184 *(.data.gate) 184 *(.data.gate)
185 __stop_gate_section = .; 185 __stop_gate_section = .;
186 } 186 }
187 . = ALIGN(PAGE_SIZE); /* make sure the gate page doesn't expose kernel data */ 187 . = ALIGN(PAGE_SIZE); /* make sure the gate page doesn't expose
188 * kernel data
189 */
188 190
189 .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) 191 .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET)
190 { *(.data.read_mostly) } 192 { *(.data.read_mostly) }
@@ -202,7 +204,9 @@ SECTIONS
202 *(.data.percpu) 204 *(.data.percpu)
203 __per_cpu_end = .; 205 __per_cpu_end = .;
204 } 206 }
205 . = __phys_per_cpu_start + PERCPU_PAGE_SIZE; /* ensure percpu data fits into percpu page size */ 207 . = __phys_per_cpu_start + PERCPU_PAGE_SIZE; /* ensure percpu data fits
208 * into percpu page size
209 */
206 210
207 data : { } :data 211 data : { } :data
208 .data : AT(ADDR(.data) - LOAD_OFFSET) 212 .data : AT(ADDR(.data) - LOAD_OFFSET)
diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c
index e004143ba86b..daf977ff2920 100644
--- a/arch/ia64/mm/contig.c
+++ b/arch/ia64/mm/contig.c
@@ -26,7 +26,6 @@
26#include <asm/mca.h> 26#include <asm/mca.h>
27 27
28#ifdef CONFIG_VIRTUAL_MEM_MAP 28#ifdef CONFIG_VIRTUAL_MEM_MAP
29static unsigned long num_dma_physpages;
30static unsigned long max_gap; 29static unsigned long max_gap;
31#endif 30#endif
32 31
@@ -41,10 +40,11 @@ show_mem (void)
41 int i, total = 0, reserved = 0; 40 int i, total = 0, reserved = 0;
42 int shared = 0, cached = 0; 41 int shared = 0, cached = 0;
43 42
44 printk("Mem-info:\n"); 43 printk(KERN_INFO "Mem-info:\n");
45 show_free_areas(); 44 show_free_areas();
46 45
47 printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); 46 printk(KERN_INFO "Free swap: %6ldkB\n",
47 nr_swap_pages<<(PAGE_SHIFT-10));
48 i = max_mapnr; 48 i = max_mapnr;
49 for (i = 0; i < max_mapnr; i++) { 49 for (i = 0; i < max_mapnr; i++) {
50 if (!pfn_valid(i)) { 50 if (!pfn_valid(i)) {
@@ -63,12 +63,12 @@ show_mem (void)
63 else if (page_count(mem_map + i)) 63 else if (page_count(mem_map + i))
64 shared += page_count(mem_map + i) - 1; 64 shared += page_count(mem_map + i) - 1;
65 } 65 }
66 printk("%d pages of RAM\n", total); 66 printk(KERN_INFO "%d pages of RAM\n", total);
67 printk("%d reserved pages\n", reserved); 67 printk(KERN_INFO "%d reserved pages\n", reserved);
68 printk("%d pages shared\n", shared); 68 printk(KERN_INFO "%d pages shared\n", shared);
69 printk("%d pages swap cached\n", cached); 69 printk(KERN_INFO "%d pages swap cached\n", cached);
70 printk("%ld pages in page table cache\n", 70 printk(KERN_INFO "%ld pages in page table cache\n",
71 pgtable_quicklist_total_size()); 71 pgtable_quicklist_total_size());
72} 72}
73 73
74/* physical address where the bootmem map is located */ 74/* physical address where the bootmem map is located */
@@ -218,18 +218,6 @@ count_pages (u64 start, u64 end, void *arg)
218 return 0; 218 return 0;
219} 219}
220 220
221#ifdef CONFIG_VIRTUAL_MEM_MAP
222static int
223count_dma_pages (u64 start, u64 end, void *arg)
224{
225 unsigned long *count = arg;
226
227 if (start < MAX_DMA_ADDRESS)
228 *count += (min(end, MAX_DMA_ADDRESS) - start) >> PAGE_SHIFT;
229 return 0;
230}
231#endif
232
233/* 221/*
234 * Set up the page tables. 222 * Set up the page tables.
235 */ 223 */
@@ -238,45 +226,22 @@ void __init
238paging_init (void) 226paging_init (void)
239{ 227{
240 unsigned long max_dma; 228 unsigned long max_dma;
241 unsigned long zones_size[MAX_NR_ZONES]; 229 unsigned long nid = 0;
242#ifdef CONFIG_VIRTUAL_MEM_MAP 230 unsigned long max_zone_pfns[MAX_NR_ZONES];
243 unsigned long zholes_size[MAX_NR_ZONES];
244#endif
245
246 /* initialize mem_map[] */
247
248 memset(zones_size, 0, sizeof(zones_size));
249 231
250 num_physpages = 0; 232 num_physpages = 0;
251 efi_memmap_walk(count_pages, &num_physpages); 233 efi_memmap_walk(count_pages, &num_physpages);
252 234
253 max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT; 235 max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
236 max_zone_pfns[ZONE_DMA] = max_dma;
237 max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
254 238
255#ifdef CONFIG_VIRTUAL_MEM_MAP 239#ifdef CONFIG_VIRTUAL_MEM_MAP
256 memset(zholes_size, 0, sizeof(zholes_size)); 240 efi_memmap_walk(register_active_ranges, &nid);
257
258 num_dma_physpages = 0;
259 efi_memmap_walk(count_dma_pages, &num_dma_physpages);
260
261 if (max_low_pfn < max_dma) {
262 zones_size[ZONE_DMA] = max_low_pfn;
263 zholes_size[ZONE_DMA] = max_low_pfn - num_dma_physpages;
264 } else {
265 zones_size[ZONE_DMA] = max_dma;
266 zholes_size[ZONE_DMA] = max_dma - num_dma_physpages;
267 if (num_physpages > num_dma_physpages) {
268 zones_size[ZONE_NORMAL] = max_low_pfn - max_dma;
269 zholes_size[ZONE_NORMAL] =
270 ((max_low_pfn - max_dma) -
271 (num_physpages - num_dma_physpages));
272 }
273 }
274
275 efi_memmap_walk(find_largest_hole, (u64 *)&max_gap); 241 efi_memmap_walk(find_largest_hole, (u64 *)&max_gap);
276 if (max_gap < LARGE_GAP) { 242 if (max_gap < LARGE_GAP) {
277 vmem_map = (struct page *) 0; 243 vmem_map = (struct page *) 0;
278 free_area_init_node(0, NODE_DATA(0), zones_size, 0, 244 free_area_init_nodes(max_zone_pfns);
279 zholes_size);
280 } else { 245 } else {
281 unsigned long map_size; 246 unsigned long map_size;
282 247
@@ -288,20 +253,19 @@ paging_init (void)
288 vmem_map = (struct page *) vmalloc_end; 253 vmem_map = (struct page *) vmalloc_end;
289 efi_memmap_walk(create_mem_map_page_table, NULL); 254 efi_memmap_walk(create_mem_map_page_table, NULL);
290 255
291 NODE_DATA(0)->node_mem_map = vmem_map; 256 /*
292 free_area_init_node(0, NODE_DATA(0), zones_size, 257 * alloc_node_mem_map makes an adjustment for mem_map
293 0, zholes_size); 258 * which isn't compatible with vmem_map.
259 */
260 NODE_DATA(0)->node_mem_map = vmem_map +
261 find_min_pfn_with_active_regions();
262 free_area_init_nodes(max_zone_pfns);
294 263
295 printk("Virtual mem_map starts at 0x%p\n", mem_map); 264 printk("Virtual mem_map starts at 0x%p\n", mem_map);
296 } 265 }
297#else /* !CONFIG_VIRTUAL_MEM_MAP */ 266#else /* !CONFIG_VIRTUAL_MEM_MAP */
298 if (max_low_pfn < max_dma) 267 add_active_range(0, 0, max_low_pfn);
299 zones_size[ZONE_DMA] = max_low_pfn; 268 free_area_init_nodes(max_zone_pfns);
300 else {
301 zones_size[ZONE_DMA] = max_dma;
302 zones_size[ZONE_NORMAL] = max_low_pfn - max_dma;
303 }
304 free_area_init(zones_size);
305#endif /* !CONFIG_VIRTUAL_MEM_MAP */ 269#endif /* !CONFIG_VIRTUAL_MEM_MAP */
306 zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page)); 270 zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
307} 271}
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index d260bffa01ab..d497b6b0f5b2 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -547,15 +547,16 @@ void show_mem(void)
547 unsigned long total_present = 0; 547 unsigned long total_present = 0;
548 pg_data_t *pgdat; 548 pg_data_t *pgdat;
549 549
550 printk("Mem-info:\n"); 550 printk(KERN_INFO "Mem-info:\n");
551 show_free_areas(); 551 show_free_areas();
552 printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); 552 printk(KERN_INFO "Free swap: %6ldkB\n",
553 nr_swap_pages<<(PAGE_SHIFT-10));
554 printk(KERN_INFO "Node memory in pages:\n");
553 for_each_online_pgdat(pgdat) { 555 for_each_online_pgdat(pgdat) {
554 unsigned long present; 556 unsigned long present;
555 unsigned long flags; 557 unsigned long flags;
556 int shared = 0, cached = 0, reserved = 0; 558 int shared = 0, cached = 0, reserved = 0;
557 559
558 printk("Node ID: %d\n", pgdat->node_id);
559 pgdat_resize_lock(pgdat, &flags); 560 pgdat_resize_lock(pgdat, &flags);
560 present = pgdat->node_present_pages; 561 present = pgdat->node_present_pages;
561 for(i = 0; i < pgdat->node_spanned_pages; i++) { 562 for(i = 0; i < pgdat->node_spanned_pages; i++) {
@@ -579,18 +580,17 @@ void show_mem(void)
579 total_reserved += reserved; 580 total_reserved += reserved;
580 total_cached += cached; 581 total_cached += cached;
581 total_shared += shared; 582 total_shared += shared;
582 printk("\t%ld pages of RAM\n", present); 583 printk(KERN_INFO "Node %4d: RAM: %11ld, rsvd: %8d, "
583 printk("\t%d reserved pages\n", reserved); 584 "shrd: %10d, swpd: %10d\n", pgdat->node_id,
584 printk("\t%d pages shared\n", shared); 585 present, reserved, shared, cached);
585 printk("\t%d pages swap cached\n", cached);
586 } 586 }
587 printk("%ld pages of RAM\n", total_present); 587 printk(KERN_INFO "%ld pages of RAM\n", total_present);
588 printk("%d reserved pages\n", total_reserved); 588 printk(KERN_INFO "%d reserved pages\n", total_reserved);
589 printk("%d pages shared\n", total_shared); 589 printk(KERN_INFO "%d pages shared\n", total_shared);
590 printk("%d pages swap cached\n", total_cached); 590 printk(KERN_INFO "%d pages swap cached\n", total_cached);
591 printk("Total of %ld pages in page table cache\n", 591 printk(KERN_INFO "Total of %ld pages in page table cache\n",
592 pgtable_quicklist_total_size()); 592 pgtable_quicklist_total_size());
593 printk("%d free buffer pages\n", nr_free_buffer_pages()); 593 printk(KERN_INFO "%d free buffer pages\n", nr_free_buffer_pages());
594} 594}
595 595
596/** 596/**
@@ -654,6 +654,7 @@ static __init int count_node_pages(unsigned long start, unsigned long len, int n
654{ 654{
655 unsigned long end = start + len; 655 unsigned long end = start + len;
656 656
657 add_active_range(node, start >> PAGE_SHIFT, end >> PAGE_SHIFT);
657 mem_data[node].num_physpages += len >> PAGE_SHIFT; 658 mem_data[node].num_physpages += len >> PAGE_SHIFT;
658 if (start <= __pa(MAX_DMA_ADDRESS)) 659 if (start <= __pa(MAX_DMA_ADDRESS))
659 mem_data[node].num_dma_physpages += 660 mem_data[node].num_dma_physpages +=
@@ -678,10 +679,10 @@ static __init int count_node_pages(unsigned long start, unsigned long len, int n
678void __init paging_init(void) 679void __init paging_init(void)
679{ 680{
680 unsigned long max_dma; 681 unsigned long max_dma;
681 unsigned long zones_size[MAX_NR_ZONES];
682 unsigned long zholes_size[MAX_NR_ZONES];
683 unsigned long pfn_offset = 0; 682 unsigned long pfn_offset = 0;
683 unsigned long max_pfn = 0;
684 int node; 684 int node;
685 unsigned long max_zone_pfns[MAX_NR_ZONES];
685 686
686 max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT; 687 max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT;
687 688
@@ -698,47 +699,20 @@ void __init paging_init(void)
698#endif 699#endif
699 700
700 for_each_online_node(node) { 701 for_each_online_node(node) {
701 memset(zones_size, 0, sizeof(zones_size));
702 memset(zholes_size, 0, sizeof(zholes_size));
703
704 num_physpages += mem_data[node].num_physpages; 702 num_physpages += mem_data[node].num_physpages;
705
706 if (mem_data[node].min_pfn >= max_dma) {
707 /* All of this node's memory is above ZONE_DMA */
708 zones_size[ZONE_NORMAL] = mem_data[node].max_pfn -
709 mem_data[node].min_pfn;
710 zholes_size[ZONE_NORMAL] = mem_data[node].max_pfn -
711 mem_data[node].min_pfn -
712 mem_data[node].num_physpages;
713 } else if (mem_data[node].max_pfn < max_dma) {
714 /* All of this node's memory is in ZONE_DMA */
715 zones_size[ZONE_DMA] = mem_data[node].max_pfn -
716 mem_data[node].min_pfn;
717 zholes_size[ZONE_DMA] = mem_data[node].max_pfn -
718 mem_data[node].min_pfn -
719 mem_data[node].num_dma_physpages;
720 } else {
721 /* This node has memory in both zones */
722 zones_size[ZONE_DMA] = max_dma -
723 mem_data[node].min_pfn;
724 zholes_size[ZONE_DMA] = zones_size[ZONE_DMA] -
725 mem_data[node].num_dma_physpages;
726 zones_size[ZONE_NORMAL] = mem_data[node].max_pfn -
727 max_dma;
728 zholes_size[ZONE_NORMAL] = zones_size[ZONE_NORMAL] -
729 (mem_data[node].num_physpages -
730 mem_data[node].num_dma_physpages);
731 }
732
733 pfn_offset = mem_data[node].min_pfn; 703 pfn_offset = mem_data[node].min_pfn;
734 704
735#ifdef CONFIG_VIRTUAL_MEM_MAP 705#ifdef CONFIG_VIRTUAL_MEM_MAP
736 NODE_DATA(node)->node_mem_map = vmem_map + pfn_offset; 706 NODE_DATA(node)->node_mem_map = vmem_map + pfn_offset;
737#endif 707#endif
738 free_area_init_node(node, NODE_DATA(node), zones_size, 708 if (mem_data[node].max_pfn > max_pfn)
739 pfn_offset, zholes_size); 709 max_pfn = mem_data[node].max_pfn;
740 } 710 }
741 711
712 max_zone_pfns[ZONE_DMA] = max_dma;
713 max_zone_pfns[ZONE_NORMAL] = max_pfn;
714 free_area_init_nodes(max_zone_pfns);
715
742 zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page)); 716 zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
743} 717}
744 718
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 30617ccb4f7e..ff87a5cba399 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -593,6 +593,18 @@ find_largest_hole (u64 start, u64 end, void *arg)
593 last_end = end; 593 last_end = end;
594 return 0; 594 return 0;
595} 595}
596
597int __init
598register_active_ranges(u64 start, u64 end, void *nid)
599{
600 BUG_ON(nid == NULL);
601 BUG_ON(*(unsigned long *)nid >= MAX_NUMNODES);
602
603 add_active_range(*(unsigned long *)nid,
604 __pa(start) >> PAGE_SHIFT,
605 __pa(end) >> PAGE_SHIFT);
606 return 0;
607}
596#endif /* CONFIG_VIRTUAL_MEM_MAP */ 608#endif /* CONFIG_VIRTUAL_MEM_MAP */
597 609
598static int __init 610static int __init
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 60b45e79f080..15c7c670da39 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -562,7 +562,8 @@ pcibios_enable_device (struct pci_dev *dev, int mask)
562void 562void
563pcibios_disable_device (struct pci_dev *dev) 563pcibios_disable_device (struct pci_dev *dev)
564{ 564{
565 acpi_pci_irq_disable(dev); 565 if (dev->is_enabled)
566 acpi_pci_irq_disable(dev);
566} 567}
567 568
568void 569void
diff --git a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c
index 27dee4584061..7f73ad4408aa 100644
--- a/arch/ia64/sn/kernel/bte.c
+++ b/arch/ia64/sn/kernel/bte.c
@@ -277,8 +277,7 @@ bte_result_t bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode)
277 } 277 }
278 278
279 /* temporary buffer used during unaligned transfers */ 279 /* temporary buffer used during unaligned transfers */
280 bteBlock_unaligned = kmalloc(len + 3 * L1_CACHE_BYTES, 280 bteBlock_unaligned = kmalloc(len + 3 * L1_CACHE_BYTES, GFP_KERNEL);
281 GFP_KERNEL | GFP_DMA);
282 if (bteBlock_unaligned == NULL) { 281 if (bteBlock_unaligned == NULL) {
283 return BTEFAIL_NOTAVAIL; 282 return BTEFAIL_NOTAVAIL;
284 } 283 }
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
index 9a8a29339d2d..b632b9c1e3b3 100644
--- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c
+++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
@@ -32,9 +32,10 @@
32#include <linux/cpumask.h> 32#include <linux/cpumask.h>
33#include <linux/smp_lock.h> 33#include <linux/smp_lock.h>
34#include <linux/nodemask.h> 34#include <linux/nodemask.h>
35#include <linux/smp.h>
36
35#include <asm/processor.h> 37#include <asm/processor.h>
36#include <asm/topology.h> 38#include <asm/topology.h>
37#include <asm/smp.h>
38#include <asm/semaphore.h> 39#include <asm/semaphore.h>
39#include <asm/uaccess.h> 40#include <asm/uaccess.h>
40#include <asm/sal.h> 41#include <asm/sal.h>
diff --git a/arch/m32r/mm/init.c b/arch/m32r/mm/init.c
index b71348fec1f4..bbd97c85bc5d 100644
--- a/arch/m32r/mm/init.c
+++ b/arch/m32r/mm/init.c
@@ -100,7 +100,7 @@ void free_initrd_mem(unsigned long, unsigned long);
100#ifndef CONFIG_DISCONTIGMEM 100#ifndef CONFIG_DISCONTIGMEM
101unsigned long __init zone_sizes_init(void) 101unsigned long __init zone_sizes_init(void)
102{ 102{
103 unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; 103 unsigned long zones_size[MAX_NR_ZONES] = {0, };
104 unsigned long max_dma; 104 unsigned long max_dma;
105 unsigned long low; 105 unsigned long low;
106 unsigned long start_pfn; 106 unsigned long start_pfn;
diff --git a/arch/m68knommu/mm/init.c b/arch/m68knommu/mm/init.c
index e4c233eef195..06e538d1be3a 100644
--- a/arch/m68knommu/mm/init.c
+++ b/arch/m68knommu/mm/init.c
@@ -136,7 +136,7 @@ void paging_init(void)
136#endif 136#endif
137 137
138 { 138 {
139 unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; 139 unsigned long zones_size[MAX_NR_ZONES] = {0, };
140 140
141 zones_size[ZONE_DMA] = 0 >> PAGE_SHIFT; 141 zones_size[ZONE_DMA] = 0 >> PAGE_SHIFT;
142 zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT; 142 zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 330f6abc7703..30750c54bdf5 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -126,7 +126,7 @@ config BASLER_EXCITE
126 select IRQ_CPU 126 select IRQ_CPU
127 select IRQ_CPU_RM7K 127 select IRQ_CPU_RM7K
128 select IRQ_CPU_RM9K 128 select IRQ_CPU_RM9K
129 select SERIAL_RM9000 129 select MIPS_RM9122
130 select SYS_HAS_CPU_RM9000 130 select SYS_HAS_CPU_RM9000
131 select SYS_SUPPORTS_32BIT_KERNEL 131 select SYS_SUPPORTS_32BIT_KERNEL
132 select SYS_SUPPORTS_64BIT_KERNEL 132 select SYS_SUPPORTS_64BIT_KERNEL
@@ -203,26 +203,6 @@ config MIPS_EV64120
203 <http://www.marvell.com/>. Say Y here if you wish to build a 203 <http://www.marvell.com/>. Say Y here if you wish to build a
204 kernel for this platform. 204 kernel for this platform.
205 205
206config MIPS_EV96100
207 bool "Galileo EV96100 Evaluation board (EXPERIMENTAL)"
208 depends on EXPERIMENTAL
209 select DMA_NONCOHERENT
210 select HW_HAS_PCI
211 select IRQ_CPU
212 select MIPS_GT96100
213 select RM7000_CPU_SCACHE
214 select SWAP_IO_SPACE
215 select SYS_HAS_CPU_R5000
216 select SYS_HAS_CPU_RM7000
217 select SYS_SUPPORTS_32BIT_KERNEL
218 select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL
219 select SYS_SUPPORTS_BIG_ENDIAN
220 help
221 This is an evaluation board based on the Galileo GT-96100 LAN/WAN
222 communications controllers containing a MIPS R5000 compatible core
223 running at 83MHz. Their website is <http://www.marvell.com/>. Say Y
224 here if you wish to build a kernel for this platform.
225
226config MIPS_IVR 206config MIPS_IVR
227 bool "Globespan IVR board" 207 bool "Globespan IVR board"
228 select DMA_NONCOHERENT 208 select DMA_NONCOHERENT
@@ -974,6 +954,12 @@ config MIPS_TX3927
974 bool 954 bool
975 select HAS_TXX9_SERIAL 955 select HAS_TXX9_SERIAL
976 956
957config MIPS_RM9122
958 bool
959 select SERIAL_RM9000
960 select GPI_RM9000
961 select WDT_RM9000
962
977config PCI_MARVELL 963config PCI_MARVELL
978 bool 964 bool
979 965
@@ -1024,6 +1010,15 @@ config EMMA2RH
1024 depends on MARKEINS 1010 depends on MARKEINS
1025 default y 1011 default y
1026 1012
1013config SERIAL_RM9000
1014 bool
1015
1016config GPI_RM9000
1017 bool
1018
1019config WDT_RM9000
1020 bool
1021
1027# 1022#
1028# Unfortunately not all GT64120 systems run the chip at the same clock. 1023# Unfortunately not all GT64120 systems run the chip at the same clock.
1029# As the user for the clock rate and try to minimize the available options. 1024# As the user for the clock rate and try to minimize the available options.
@@ -1054,10 +1049,6 @@ config AU1X00_USB_DEVICE
1054 depends on MIPS_PB1500 || MIPS_PB1100 || MIPS_PB1000 1049 depends on MIPS_PB1500 || MIPS_PB1100 || MIPS_PB1000
1055 default n 1050 default n
1056 1051
1057config MIPS_GT96100
1058 bool
1059 select MIPS_GT64120
1060
1061config IT8172_CIR 1052config IT8172_CIR
1062 bool 1053 bool
1063 depends on MIPS_ITE8172 || MIPS_IVR 1054 depends on MIPS_ITE8172 || MIPS_IVR
@@ -1527,6 +1518,7 @@ config MIPS_MT_SMTC
1527 select CPU_MIPSR2_SRS 1518 select CPU_MIPSR2_SRS
1528 select MIPS_MT 1519 select MIPS_MT
1529 select SMP 1520 select SMP
1521 select SYS_SUPPORTS_SMP
1530 help 1522 help
1531 This is a kernel model which is known a SMTC or lately has been 1523 This is a kernel model which is known a SMTC or lately has been
1532 marketesed into SMVP. 1524 marketesed into SMVP.
@@ -1538,6 +1530,7 @@ config MIPS_MT_SMP
1538 select CPU_MIPSR2_SRS 1530 select CPU_MIPSR2_SRS
1539 select MIPS_MT 1531 select MIPS_MT
1540 select SMP 1532 select SMP
1533 select SYS_SUPPORTS_SMP
1541 help 1534 help
1542 This is a kernel model which is also known a VSMP or lately 1535 This is a kernel model which is also known a VSMP or lately
1543 has been marketesed into SMVP. 1536 has been marketesed into SMVP.
@@ -1649,9 +1642,7 @@ config GENERIC_IRQ_PROBE
1649 default y 1642 default y
1650 1643
1651config IRQ_PER_CPU 1644config IRQ_PER_CPU
1652 depends on SMP
1653 bool 1645 bool
1654 default y
1655 1646
1656# 1647#
1657# - Highmem only makes sense for the 32-bit kernel. 1648# - Highmem only makes sense for the 32-bit kernel.
@@ -1719,6 +1710,7 @@ source "mm/Kconfig"
1719config SMP 1710config SMP
1720 bool "Multi-Processing support" 1711 bool "Multi-Processing support"
1721 depends on SYS_SUPPORTS_SMP 1712 depends on SYS_SUPPORTS_SMP
1713 select IRQ_PER_CPU
1722 help 1714 help
1723 This enables support for systems with more than one CPU. If you have 1715 This enables support for systems with more than one CPU. If you have
1724 a system with only one CPU, like most personal computers, say N. If 1716 a system with only one CPU, like most personal computers, say N. If
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index d333ce4ba26b..e521826b4234 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -280,13 +280,6 @@ cflags-$(CONFIG_MIPS_EV64120) += -Iinclude/asm-mips/mach-ev64120
280load-$(CONFIG_MIPS_EV64120) += 0xffffffff80100000 280load-$(CONFIG_MIPS_EV64120) += 0xffffffff80100000
281 281
282# 282#
283# Galileo EV96100 Board
284#
285core-$(CONFIG_MIPS_EV96100) += arch/mips/galileo-boards/ev96100/
286cflags-$(CONFIG_MIPS_EV96100) += -Iinclude/asm-mips/mach-ev96100
287load-$(CONFIG_MIPS_EV96100) += 0xffffffff80100000
288
289#
290# Wind River PPMC Board (4KC + GT64120) 283# Wind River PPMC Board (4KC + GT64120)
291# 284#
292core-$(CONFIG_WR_PPMC) += arch/mips/gt64120/wrppmc/ 285core-$(CONFIG_WR_PPMC) += arch/mips/gt64120/wrppmc/
@@ -330,6 +323,7 @@ load-$(CONFIG_MIPS_MALTA) += 0xffffffff80100000
330# MIPS SEAD board 323# MIPS SEAD board
331# 324#
332core-$(CONFIG_MIPS_SEAD) += arch/mips/mips-boards/sead/ 325core-$(CONFIG_MIPS_SEAD) += arch/mips/mips-boards/sead/
326cflags-$(CONFIG_MIPS_SEAD) += -Iinclude/asm-mips/mach-mips
333load-$(CONFIG_MIPS_SEAD) += 0xffffffff80100000 327load-$(CONFIG_MIPS_SEAD) += 0xffffffff80100000
334 328
335# 329#
diff --git a/arch/mips/au1000/common/dbdma.c b/arch/mips/au1000/common/dbdma.c
index 98244d51c154..c4fae8ff4671 100644
--- a/arch/mips/au1000/common/dbdma.c
+++ b/arch/mips/au1000/common/dbdma.c
@@ -230,7 +230,7 @@ EXPORT_SYMBOL(au1xxx_ddma_add_device);
230*/ 230*/
231u32 231u32
232au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, 232au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
233 void (*callback)(int, void *, struct pt_regs *), void *callparam) 233 void (*callback)(int, void *), void *callparam)
234{ 234{
235 unsigned long flags; 235 unsigned long flags;
236 u32 used, chan, rv; 236 u32 used, chan, rv;
@@ -248,8 +248,10 @@ au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
248 au1xxx_dbdma_init(); 248 au1xxx_dbdma_init();
249 dbdma_initialized = 1; 249 dbdma_initialized = 1;
250 250
251 if ((stp = find_dbdev_id(srcid)) == NULL) return 0; 251 if ((stp = find_dbdev_id(srcid)) == NULL)
252 if ((dtp = find_dbdev_id(destid)) == NULL) return 0; 252 return 0;
253 if ((dtp = find_dbdev_id(destid)) == NULL)
254 return 0;
253 255
254 used = 0; 256 used = 0;
255 rv = 0; 257 rv = 0;
@@ -869,7 +871,7 @@ dbdma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
869 au_sync(); 871 au_sync();
870 872
871 if (ctp->chan_callback) 873 if (ctp->chan_callback)
872 (ctp->chan_callback)(irq, ctp->chan_callparam, regs); 874 (ctp->chan_callback)(irq, ctp->chan_callparam);
873 875
874 ctp->cur_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr)); 876 ctp->cur_ptr = phys_to_virt(DSCR_GET_NXTPTR(dp->dscr_nxtptr));
875 return IRQ_RETVAL(1); 877 return IRQ_RETVAL(1);
diff --git a/arch/mips/au1000/db1x00/Makefile b/arch/mips/au1000/db1x00/Makefile
index 4c7d763f2113..51d62bd5d900 100644
--- a/arch/mips/au1000/db1x00/Makefile
+++ b/arch/mips/au1000/db1x00/Makefile
@@ -6,4 +6,3 @@
6# Makefile for the Alchemy Semiconductor Db1x00 board. 6# Makefile for the Alchemy Semiconductor Db1x00 board.
7 7
8lib-y := init.o board_setup.o irqmap.o 8lib-y := init.o board_setup.o irqmap.o
9obj-$(CONFIG_WM97XX_COMODULE) += mirage_ts.o
diff --git a/arch/mips/au1000/db1x00/mirage_ts.c b/arch/mips/au1000/db1x00/mirage_ts.c
deleted file mode 100644
index 0942dcf69518..000000000000
--- a/arch/mips/au1000/db1x00/mirage_ts.c
+++ /dev/null
@@ -1,260 +0,0 @@
1/*
2 * linux/arch/mips/au1000/db1x00/mirage_ts.c
3 *
4 * BRIEF MODULE DESCRIPTION
5 * Glue between Mirage board-specific touchscreen pieces
6 * and generic Wolfson Codec touchscreen support.
7 *
8 * Based on pb1100_ts.c used in Hydrogen II.
9 *
10 * Copyright (c) 2003 Embedded Edge, LLC
11 * dan@embeddededge.com
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. IN
21 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * 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#include <linux/types.h>
35#include <linux/module.h>
36#include <linux/sched.h>
37#include <linux/kernel.h>
38#include <linux/init.h>
39#include <linux/fs.h>
40#include <linux/poll.h>
41#include <linux/proc_fs.h>
42#include <linux/smp.h>
43#include <linux/smp_lock.h>
44#include <linux/wait.h>
45
46#include <asm/segment.h>
47#include <asm/irq.h>
48#include <asm/uaccess.h>
49#include <asm/delay.h>
50#include <asm/au1000.h>
51
52/*
53 * Imported interface to Wolfson Codec driver.
54 */
55extern void *wm97xx_ts_get_handle(int which);
56extern int wm97xx_ts_ready(void* ts_handle);
57extern void wm97xx_ts_set_cal(void* ts_handle, int xscale, int xtrans, int yscale, int ytrans);
58extern u16 wm97xx_ts_get_ac97(void* ts_handle, u8 reg);
59extern void wm97xx_ts_set_ac97(void* ts_handle, u8 reg, u16 val);
60extern int wm97xx_ts_read_data(void* ts_handle, long* x, long* y, long* pressure);
61extern void wm97xx_ts_send_data(void* ts_handle, long x, long y, long z);
62
63int wm97xx_comodule_present = 1;
64
65
66#define TS_NAME "mirage_ts"
67
68#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg)
69#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg)
70#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg)
71#define DPRINTK(format, arg...) printk("%s: " format "\n", __FUNCTION__ , ## arg)
72
73
74#define PEN_DOWN_IRQ AU1000_GPIO_7
75
76static struct task_struct *ts_task = 0;
77static DECLARE_COMPLETION(ts_complete);
78static DECLARE_WAIT_QUEUE_HEAD(pendown_wait);
79
80#ifdef CONFIG_WM97XX_FIVEWIRETS
81static int release_pressure = 1;
82#else
83static int release_pressure = 50;
84#endif
85
86typedef struct {
87 long x;
88 long y;
89} DOWN_EVENT;
90
91#define SAMPLE_RATE 50 /* samples per second */
92#define PEN_DEBOUNCE 5 /* samples for settling - fn of SAMPLE_RATE */
93#define PEN_UP_TIMEOUT 10 /* in seconds */
94#define PEN_UP_SETTLE 5 /* samples per second */
95
96static struct {
97 int xscale;
98 int xtrans;
99 int yscale;
100 int ytrans;
101} mirage_ts_cal =
102{
103#if 0
104 .xscale = 84,
105 .xtrans = -157,
106 .yscale = 66,
107 .ytrans = -150,
108#else
109 .xscale = 84,
110 .xtrans = -150,
111 .yscale = 66,
112 .ytrans = -146,
113#endif
114};
115
116
117static void pendown_irq(int irqnr, void *devid, struct pt_regs *regs)
118{
119//DPRINTK("got one 0x%x", au_readl(SYS_PINSTATERD));
120 wake_up(&pendown_wait);
121}
122
123static int ts_thread(void *id)
124{
125 static int pen_was_down = 0;
126 static DOWN_EVENT pen_xy;
127 long x, y, z;
128 void *ts; /* handle */
129 struct task_struct *tsk = current;
130 int timeout = HZ / SAMPLE_RATE;
131
132 ts_task = tsk;
133
134 daemonize();
135 tsk->tty = NULL;
136 tsk->policy = SCHED_FIFO;
137 tsk->rt_priority = 1;
138 strcpy(tsk->comm, "touchscreen");
139
140 /* only want to receive SIGKILL */
141 spin_lock_irq(&tsk->sigmask_lock);
142 siginitsetinv(&tsk->blocked, sigmask(SIGKILL));
143 recalc_sigpending(tsk);
144 spin_unlock_irq(&tsk->sigmask_lock);
145
146 /* get handle for codec */
147 ts = wm97xx_ts_get_handle(0);
148
149 /* proceed only after everybody is ready */
150 wait_event_timeout(pendown_wait, wm97xx_ts_ready(ts), HZ/4);
151
152 /* board-specific calibration */
153 wm97xx_ts_set_cal(ts,
154 mirage_ts_cal.xscale,
155 mirage_ts_cal.xtrans,
156 mirage_ts_cal.yscale,
157 mirage_ts_cal.ytrans);
158
159 /* route Wolfson pendown interrupts to our GPIO */
160 au_sync();
161 wm97xx_ts_set_ac97(ts, 0x4c, wm97xx_ts_get_ac97(ts, 0x4c) & ~0x0008);
162 au_sync();
163 wm97xx_ts_set_ac97(ts, 0x56, wm97xx_ts_get_ac97(ts, 0x56) & ~0x0008);
164 au_sync();
165 wm97xx_ts_set_ac97(ts, 0x52, wm97xx_ts_get_ac97(ts, 0x52) | 0x2008);
166 au_sync();
167
168 for (;;) {
169 interruptible_sleep_on_timeout(&pendown_wait, timeout);
170 disable_irq(PEN_DOWN_IRQ);
171 if (signal_pending(tsk)) {
172 break;
173 }
174
175 /* read codec */
176 if (!wm97xx_ts_read_data(ts, &x, &y, &z))
177 z = 0; /* treat no-data and pen-up the same */
178
179 if (signal_pending(tsk)) {
180 break;
181 }
182
183 if (z >= release_pressure) {
184 y = ~y; /* top to bottom */
185 if (pen_was_down > 1 /*&& pen_was_down < PEN_DEBOUNCE*/) {//THXXX
186 /* bounce ? */
187 x = pen_xy.x;
188 y = pen_xy.y;
189 --pen_was_down;
190 } else if (pen_was_down <= 1) {
191 pen_xy.x = x;
192 pen_xy.y = y;
193 if (pen_was_down)
194 wm97xx_ts_send_data(ts, x, y, z);
195 pen_was_down = PEN_DEBOUNCE;
196 }
197 //wm97xx_ts_send_data(ts, x, y, z);
198 timeout = HZ / SAMPLE_RATE;
199 } else {
200 if (pen_was_down) {
201 if (--pen_was_down)
202 z = release_pressure;
203 else //THXXX
204 wm97xx_ts_send_data(ts, pen_xy.x, pen_xy.y, z);
205 }
206 /* The pendown signal takes some time to settle after
207 * reading the pen pressure so wait a little
208 * before enabling the pen.
209 */
210 if (! pen_was_down) {
211// interruptible_sleep_on_timeout(&pendown_wait, HZ / PEN_UP_SETTLE);
212 timeout = HZ * PEN_UP_TIMEOUT;
213 }
214 }
215 enable_irq(PEN_DOWN_IRQ);
216 }
217 enable_irq(PEN_DOWN_IRQ);
218 ts_task = NULL;
219 complete(&ts_complete);
220 return 0;
221}
222
223static int __init ts_mirage_init(void)
224{
225 int ret;
226
227 /* pen down signal is connected to GPIO 7 */
228
229 ret = request_irq(PEN_DOWN_IRQ, pendown_irq, 0, "ts-pendown", NULL);
230 if (ret) {
231 err("unable to get pendown irq%d: [%d]", PEN_DOWN_IRQ, ret);
232 return ret;
233 }
234
235 lock_kernel();
236 ret = kernel_thread(ts_thread, NULL, CLONE_FS | CLONE_FILES);
237 if (ret < 0) {
238 unlock_kernel();
239 return ret;
240 }
241 unlock_kernel();
242
243 info("Mirage touchscreen IRQ initialized.");
244
245 return 0;
246}
247
248static void __exit ts_mirage_exit(void)
249{
250 if (ts_task) {
251 send_sig(SIGKILL, ts_task, 1);
252 wait_for_completion(&ts_complete);
253 }
254
255 free_irq(PEN_DOWN_IRQ, NULL);
256}
257
258module_init(ts_mirage_init);
259module_exit(ts_mirage_exit);
260
diff --git a/arch/mips/basler/excite/excite_device.c b/arch/mips/basler/excite/excite_device.c
index bbb4ea43da88..cc1ce77eab4a 100644
--- a/arch/mips/basler/excite/excite_device.c
+++ b/arch/mips/basler/excite/excite_device.c
@@ -68,7 +68,7 @@ enum {
68 68
69 69
70static struct resource 70static struct resource
71 excite_ctr_resource = { 71 excite_ctr_resource __attribute__((unused)) = {
72 .name = "GPI counters", 72 .name = "GPI counters",
73 .start = 0, 73 .start = 0,
74 .end = 5, 74 .end = 5,
@@ -77,7 +77,7 @@ static struct resource
77 .sibling = NULL, 77 .sibling = NULL,
78 .child = NULL 78 .child = NULL
79 }, 79 },
80 excite_gpislice_resource = { 80 excite_gpislice_resource __attribute__((unused)) = {
81 .name = "GPI slices", 81 .name = "GPI slices",
82 .start = 0, 82 .start = 0,
83 .end = 1, 83 .end = 1,
@@ -86,7 +86,7 @@ static struct resource
86 .sibling = NULL, 86 .sibling = NULL,
87 .child = NULL 87 .child = NULL
88 }, 88 },
89 excite_mdio_channel_resource = { 89 excite_mdio_channel_resource __attribute__((unused)) = {
90 .name = "MDIO channels", 90 .name = "MDIO channels",
91 .start = 0, 91 .start = 0,
92 .end = 1, 92 .end = 1,
@@ -95,7 +95,7 @@ static struct resource
95 .sibling = NULL, 95 .sibling = NULL,
96 .child = NULL 96 .child = NULL
97 }, 97 },
98 excite_fifomem_resource = { 98 excite_fifomem_resource __attribute__((unused)) = {
99 .name = "FIFO memory", 99 .name = "FIFO memory",
100 .start = 0, 100 .start = 0,
101 .end = 767, 101 .end = 767,
@@ -104,7 +104,7 @@ static struct resource
104 .sibling = NULL, 104 .sibling = NULL,
105 .child = NULL 105 .child = NULL
106 }, 106 },
107 excite_scram_resource = { 107 excite_scram_resource __attribute__((unused)) = {
108 .name = "Scratch RAM", 108 .name = "Scratch RAM",
109 .start = EXCITE_PHYS_SCRAM, 109 .start = EXCITE_PHYS_SCRAM,
110 .end = EXCITE_PHYS_SCRAM + EXCITE_SIZE_SCRAM - 1, 110 .end = EXCITE_PHYS_SCRAM + EXCITE_SIZE_SCRAM - 1,
@@ -113,7 +113,7 @@ static struct resource
113 .sibling = NULL, 113 .sibling = NULL,
114 .child = NULL 114 .child = NULL
115 }, 115 },
116 excite_fpga_resource = { 116 excite_fpga_resource __attribute__((unused)) = {
117 .name = "System FPGA", 117 .name = "System FPGA",
118 .start = EXCITE_PHYS_FPGA, 118 .start = EXCITE_PHYS_FPGA,
119 .end = EXCITE_PHYS_FPGA + EXCITE_SIZE_FPGA - 1, 119 .end = EXCITE_PHYS_FPGA + EXCITE_SIZE_FPGA - 1,
@@ -122,7 +122,7 @@ static struct resource
122 .sibling = NULL, 122 .sibling = NULL,
123 .child = NULL 123 .child = NULL
124 }, 124 },
125 excite_nand_resource = { 125 excite_nand_resource __attribute__((unused)) = {
126 .name = "NAND flash control", 126 .name = "NAND flash control",
127 .start = EXCITE_PHYS_NAND, 127 .start = EXCITE_PHYS_NAND,
128 .end = EXCITE_PHYS_NAND + EXCITE_SIZE_NAND - 1, 128 .end = EXCITE_PHYS_NAND + EXCITE_SIZE_NAND - 1,
@@ -131,7 +131,7 @@ static struct resource
131 .sibling = NULL, 131 .sibling = NULL,
132 .child = NULL 132 .child = NULL
133 }, 133 },
134 excite_titan_resource = { 134 excite_titan_resource __attribute__((unused)) = {
135 .name = "TITAN registers", 135 .name = "TITAN registers",
136 .start = EXCITE_PHYS_TITAN, 136 .start = EXCITE_PHYS_TITAN,
137 .end = EXCITE_PHYS_TITAN + EXCITE_SIZE_TITAN - 1, 137 .end = EXCITE_PHYS_TITAN + EXCITE_SIZE_TITAN - 1,
diff --git a/arch/mips/basler/excite/excite_fpga.h b/arch/mips/basler/excite/excite_fpga.h
deleted file mode 100644
index 38fcda703a0b..000000000000
--- a/arch/mips/basler/excite/excite_fpga.h
+++ /dev/null
@@ -1,80 +0,0 @@
1#ifndef EXCITE_FPGA_H_INCLUDED
2#define EXCITE_FPGA_H_INCLUDED
3
4
5/**
6 * Adress alignment of the individual FPGA bytes.
7 * The address arrangement of the individual bytes of the FPGA is two
8 * byte aligned at the embedded MK2 platform.
9 */
10#ifdef EXCITE_CCI_FPGA_MK2
11typedef unsigned char excite_cci_fpga_align_t __attribute__ ((aligned(2)));
12#else
13typedef unsigned char excite_cci_fpga_align_t;
14#endif
15
16
17/**
18 * Size of Dual Ported RAM.
19 */
20#define EXCITE_DPR_SIZE 263
21
22
23/**
24 * Size of Reserved Status Fields in Dual Ported RAM.
25 */
26#define EXCITE_DPR_STATUS_SIZE 7
27
28
29
30/**
31 * FPGA.
32 * Hardware register layout of the FPGA interface. The FPGA must accessed
33 * byte wise solely.
34 * @see EXCITE_CCI_DPR_MK2
35 */
36typedef struct excite_fpga {
37
38 /**
39 * Dual Ported RAM.
40 */
41 excite_cci_fpga_align_t dpr[EXCITE_DPR_SIZE];
42
43 /**
44 * Status.
45 */
46 excite_cci_fpga_align_t status[EXCITE_DPR_STATUS_SIZE];
47
48#ifdef EXCITE_CCI_FPGA_MK2
49 /**
50 * RM9000 Interrupt.
51 * Write access initiates interrupt at the RM9000 (MIPS) processor of the eXcite.
52 */
53 excite_cci_fpga_align_t rm9k_int;
54#else
55 /**
56 * MK2 Interrupt.
57 * Write access initiates interrupt at the ARM processor of the MK2.
58 */
59 excite_cci_fpga_align_t mk2_int;
60
61 excite_cci_fpga_align_t gap[0x1000-0x10f];
62
63 /**
64 * IRQ Source/Acknowledge.
65 */
66 excite_cci_fpga_align_t rm9k_irq_src;
67
68 /**
69 * IRQ Mask.
70 * Set bits enable the related interrupt.
71 */
72 excite_cci_fpga_align_t rm9k_irq_mask;
73#endif
74
75
76} excite_fpga;
77
78
79
80#endif /* ndef EXCITE_FPGA_H_INCLUDED */
diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig
index 54274065e9a5..d3705284de39 100644
--- a/arch/mips/configs/atlas_defconfig
+++ b/arch/mips/configs/atlas_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
@@ -1193,7 +1192,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1193CONFIG_PROC_FS=y 1192CONFIG_PROC_FS=y
1194CONFIG_PROC_KCORE=y 1193CONFIG_PROC_KCORE=y
1195CONFIG_SYSFS=y 1194CONFIG_SYSFS=y
1196# CONFIG_TMPFS is not set 1195CONFIG_TMPFS=y
1197# CONFIG_HUGETLB_PAGE is not set 1196# CONFIG_HUGETLB_PAGE is not set
1198CONFIG_RAMFS=y 1197CONFIG_RAMFS=y
1199# CONFIG_CONFIGFS_FS is not set 1198# CONFIG_CONFIGFS_FS is not set
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
index 887fd959482a..e12a475dcbf4 100644
--- a/arch/mips/configs/bigsur_defconfig
+++ b/arch/mips/configs/bigsur_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig
index a01344f3a4c2..bfade9abb767 100644
--- a/arch/mips/configs/capcella_defconfig
+++ b/arch/mips/configs/capcella_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
index c95682445a28..4baf2ff1128a 100644
--- a/arch/mips/configs/cobalt_defconfig
+++ b/arch/mips/configs/cobalt_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25CONFIG_MIPS_COBALT=y 25CONFIG_MIPS_COBALT=y
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
@@ -828,7 +827,7 @@ CONFIG_FUSE_FS=y
828CONFIG_PROC_FS=y 827CONFIG_PROC_FS=y
829CONFIG_PROC_KCORE=y 828CONFIG_PROC_KCORE=y
830CONFIG_SYSFS=y 829CONFIG_SYSFS=y
831# CONFIG_TMPFS is not set 830CONFIG_TMPFS=y
832# CONFIG_HUGETLB_PAGE is not set 831# CONFIG_HUGETLB_PAGE is not set
833CONFIG_RAMFS=y 832CONFIG_RAMFS=y
834# CONFIG_CONFIGFS_FS is not set 833# CONFIG_CONFIGFS_FS is not set
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
index c2f33d3af62c..93cca1585bc3 100644
--- a/arch/mips/configs/db1000_defconfig
+++ b/arch/mips/configs/db1000_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS_DB1000=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
index 8c44d16ae9a2..ffd99252a837 100644
--- a/arch/mips/configs/db1100_defconfig
+++ b/arch/mips/configs/db1100_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS_DB1100=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
index c13768e75ac5..63eac5e89b9c 100644
--- a/arch/mips/configs/db1200_defconfig
+++ b/arch/mips/configs/db1200_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS_DB1200=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
index 8aea73fae7fb..25a095f7dc4e 100644
--- a/arch/mips/configs/db1500_defconfig
+++ b/arch/mips/configs/db1500_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS_DB1500=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
index 90ccb7359630..dda469c842b3 100644
--- a/arch/mips/configs/db1550_defconfig
+++ b/arch/mips/configs/db1550_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS_DB1550=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig
index b598cf08f156..fcd3dd19bc74 100644
--- a/arch/mips/configs/ddb5477_defconfig
+++ b/arch/mips/configs/ddb5477_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig
index 597150b14077..8683e0df12e0 100644
--- a/arch/mips/configs/decstation_defconfig
+++ b/arch/mips/configs/decstation_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26CONFIG_MACH_DECSTATION=y 26CONFIG_MACH_DECSTATION=y
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig
index fa2996bb4b7c..4ace61c95778 100644
--- a/arch/mips/configs/e55_defconfig
+++ b/arch/mips/configs/e55_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.18-rc1 3# Linux kernel version: 2.6.18-rc2
4# Thu Jul 6 10:04:02 2006 4# Tue Jul 25 23:15:03 2006
5# 5#
6CONFIG_MIPS=y 6CONFIG_MIPS=y
7 7
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
@@ -227,7 +226,6 @@ CONFIG_MMU=y
227# 226#
228# PCCARD (PCMCIA/CardBus) support 227# PCCARD (PCMCIA/CardBus) support
229# 228#
230# CONFIG_PCCARD is not set
231 229
232# 230#
233# PCI Hotplug Support 231# PCI Hotplug Support
@@ -254,7 +252,6 @@ CONFIG_TRAD_SIGNALS=y
254# 252#
255CONFIG_STANDALONE=y 253CONFIG_STANDALONE=y
256CONFIG_PREVENT_FIRMWARE_BUILD=y 254CONFIG_PREVENT_FIRMWARE_BUILD=y
257# CONFIG_FW_LOADER is not set
258# CONFIG_SYS_HYPERVISOR is not set 255# CONFIG_SYS_HYPERVISOR is not set
259 256
260# 257#
@@ -284,6 +281,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
284CONFIG_BLK_DEV_RAM=m 281CONFIG_BLK_DEV_RAM=m
285CONFIG_BLK_DEV_RAM_COUNT=16 282CONFIG_BLK_DEV_RAM_COUNT=16
286CONFIG_BLK_DEV_RAM_SIZE=4096 283CONFIG_BLK_DEV_RAM_SIZE=4096
284CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
287# CONFIG_BLK_DEV_INITRD is not set 285# CONFIG_BLK_DEV_INITRD is not set
288# CONFIG_CDROM_PKTCDVD is not set 286# CONFIG_CDROM_PKTCDVD is not set
289 287
@@ -643,6 +641,7 @@ CONFIG_MSDOS_PARTITION=y
643# 641#
644# Kernel hacking 642# Kernel hacking
645# 643#
644CONFIG_TRACE_IRQFLAGS_SUPPORT=y
646# CONFIG_PRINTK_TIME is not set 645# CONFIG_PRINTK_TIME is not set
647# CONFIG_MAGIC_SYSRQ is not set 646# CONFIG_MAGIC_SYSRQ is not set
648# CONFIG_UNUSED_SYMBOLS is not set 647# CONFIG_UNUSED_SYMBOLS is not set
@@ -650,7 +649,7 @@ CONFIG_MSDOS_PARTITION=y
650CONFIG_LOG_BUF_SHIFT=14 649CONFIG_LOG_BUF_SHIFT=14
651# CONFIG_DEBUG_FS is not set 650# CONFIG_DEBUG_FS is not set
652CONFIG_CROSSCOMPILE=y 651CONFIG_CROSSCOMPILE=y
653CONFIG_CMDLINE="console=ttyVR0,19200 mem=8M" 652CONFIG_CMDLINE="console=ttyVR0,19200 ide0=0x1f0,0x3f6,40 mem=8M"
654 653
655# 654#
656# Security options 655# Security options
diff --git a/arch/mips/configs/emma2rh_defconfig b/arch/mips/configs/emma2rh_defconfig
index 375b2ac24a49..5847c916c130 100644
--- a/arch/mips/configs/emma2rh_defconfig
+++ b/arch/mips/configs/emma2rh_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig
index b0afc118bd5c..bc4c4f125c48 100644
--- a/arch/mips/configs/ev64120_defconfig
+++ b/arch/mips/configs/ev64120_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27CONFIG_MIPS_EV64120=y 27CONFIG_MIPS_EV64120=y
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig
index 045ebd089893..eb87cbbfd037 100644
--- a/arch/mips/configs/excite_defconfig
+++ b/arch/mips/configs/excite_defconfig
@@ -26,7 +26,6 @@ CONFIG_BASLER_EXCITE=y
26# CONFIG_MIPS_COBALT is not set 26# CONFIG_MIPS_COBALT is not set
27# CONFIG_MACH_DECSTATION is not set 27# CONFIG_MACH_DECSTATION is not set
28# CONFIG_MIPS_EV64120 is not set 28# CONFIG_MIPS_EV64120 is not set
29# CONFIG_MIPS_EV96100 is not set
30# CONFIG_MIPS_IVR is not set 29# CONFIG_MIPS_IVR is not set
31# CONFIG_MIPS_ITE8172 is not set 30# CONFIG_MIPS_ITE8172 is not set
32# CONFIG_MACH_JAZZ is not set 31# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig
index ef16d1fb5071..cc9b24eda9e8 100644
--- a/arch/mips/configs/ip22_defconfig
+++ b/arch/mips/configs/ip22_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
@@ -1013,7 +1012,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1013CONFIG_PROC_FS=y 1012CONFIG_PROC_FS=y
1014CONFIG_PROC_KCORE=y 1013CONFIG_PROC_KCORE=y
1015CONFIG_SYSFS=y 1014CONFIG_SYSFS=y
1016# CONFIG_TMPFS is not set 1015CONFIG_TMPFS=y
1017# CONFIG_HUGETLB_PAGE is not set 1016# CONFIG_HUGETLB_PAGE is not set
1018CONFIG_RAMFS=y 1017CONFIG_RAMFS=y
1019# CONFIG_CONFIGFS_FS is not set 1018# CONFIG_CONFIGFS_FS is not set
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index 4bf1ee7f5f00..50092ba8aa71 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
@@ -900,7 +899,7 @@ CONFIG_FUSE_FS=m
900CONFIG_PROC_FS=y 899CONFIG_PROC_FS=y
901CONFIG_PROC_KCORE=y 900CONFIG_PROC_KCORE=y
902CONFIG_SYSFS=y 901CONFIG_SYSFS=y
903# CONFIG_TMPFS is not set 902CONFIG_TMPFS=y
904# CONFIG_HUGETLB_PAGE is not set 903# CONFIG_HUGETLB_PAGE is not set
905CONFIG_RAMFS=y 904CONFIG_RAMFS=y
906# CONFIG_CONFIGFS_FS is not set 905# CONFIG_CONFIGFS_FS is not set
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index f83dc09c3ca9..dec2ba6ba03f 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/it8172_defconfig b/arch/mips/configs/it8172_defconfig
index a91d72a9ca86..37f9dd7187b1 100644
--- a/arch/mips/configs/it8172_defconfig
+++ b/arch/mips/configs/it8172_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30CONFIG_MIPS_ITE8172=y 29CONFIG_MIPS_ITE8172=y
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/ivr_defconfig b/arch/mips/configs/ivr_defconfig
index cebc67212d06..18874a4c24fe 100644
--- a/arch/mips/configs/ivr_defconfig
+++ b/arch/mips/configs/ivr_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29CONFIG_MIPS_IVR=y 28CONFIG_MIPS_IVR=y
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/jaguar-atx_defconfig b/arch/mips/configs/jaguar-atx_defconfig
index 5d9eb11aba3d..9f1e3048d623 100644
--- a/arch/mips/configs/jaguar-atx_defconfig
+++ b/arch/mips/configs/jaguar-atx_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
@@ -731,7 +730,7 @@ CONFIG_FUSE_FS=m
731CONFIG_PROC_FS=y 730CONFIG_PROC_FS=y
732CONFIG_PROC_KCORE=y 731CONFIG_PROC_KCORE=y
733CONFIG_SYSFS=y 732CONFIG_SYSFS=y
734# CONFIG_TMPFS is not set 733CONFIG_TMPFS=y
735# CONFIG_HUGETLB_PAGE is not set 734# CONFIG_HUGETLB_PAGE is not set
736CONFIG_RAMFS=y 735CONFIG_RAMFS=y
737 736
diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig
index be45a9044d06..fded3f73815f 100644
--- a/arch/mips/configs/jmr3927_defconfig
+++ b/arch/mips/configs/jmr3927_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig
index 64dc9f45a19c..320b8cdd6e58 100644
--- a/arch/mips/configs/lasat200_defconfig
+++ b/arch/mips/configs/lasat200_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
@@ -905,7 +904,7 @@ CONFIG_FUSE_FS=m
905CONFIG_PROC_FS=y 904CONFIG_PROC_FS=y
906CONFIG_PROC_KCORE=y 905CONFIG_PROC_KCORE=y
907CONFIG_SYSFS=y 906CONFIG_SYSFS=y
908# CONFIG_TMPFS is not set 907CONFIG_TMPFS=y
909# CONFIG_HUGETLB_PAGE is not set 908# CONFIG_HUGETLB_PAGE is not set
910CONFIG_RAMFS=y 909CONFIG_RAMFS=y
911# CONFIG_CONFIGFS_FS is not set 910# CONFIG_CONFIGFS_FS is not set
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
index 2690baf15a85..0ba1ef5048fb 100644
--- a/arch/mips/configs/malta_defconfig
+++ b/arch/mips/configs/malta_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
@@ -1230,7 +1229,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1230CONFIG_PROC_FS=y 1229CONFIG_PROC_FS=y
1231CONFIG_PROC_KCORE=y 1230CONFIG_PROC_KCORE=y
1232CONFIG_SYSFS=y 1231CONFIG_SYSFS=y
1233# CONFIG_TMPFS is not set 1232CONFIG_TMPFS=y
1234# CONFIG_HUGETLB_PAGE is not set 1233# CONFIG_HUGETLB_PAGE is not set
1235CONFIG_RAMFS=y 1234CONFIG_RAMFS=y
1236# CONFIG_CONFIGFS_FS is not set 1235# CONFIG_CONFIGFS_FS is not set
diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
index c298979c18ae..adbeeadddb8f 100644
--- a/arch/mips/configs/mipssim_defconfig
+++ b/arch/mips/configs/mipssim_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig
index 938b38ab5239..79fd544fcb2a 100644
--- a/arch/mips/configs/mpc30x_defconfig
+++ b/arch/mips/configs/mpc30x_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.18-rc1 3# Linux kernel version: 2.6.18-rc2
4# Thu Jul 6 10:04:15 2006 4# Tue Jul 25 23:16:46 2006
5# 5#
6CONFIG_MIPS=y 6CONFIG_MIPS=y
7 7
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
@@ -71,7 +70,6 @@ CONFIG_MACH_VR41XX=y
71CONFIG_VICTOR_MPC30X=y 70CONFIG_VICTOR_MPC30X=y
72# CONFIG_ZAO_CAPCELLA is not set 71# CONFIG_ZAO_CAPCELLA is not set
73CONFIG_PCI_VR41XX=y 72CONFIG_PCI_VR41XX=y
74CONFIG_VRC4173=y
75CONFIG_RWSEM_GENERIC_SPINLOCK=y 73CONFIG_RWSEM_GENERIC_SPINLOCK=y
76CONFIG_GENERIC_FIND_NEXT_BIT=y 74CONFIG_GENERIC_FIND_NEXT_BIT=y
77CONFIG_GENERIC_HWEIGHT=y 75CONFIG_GENERIC_HWEIGHT=y
@@ -168,6 +166,7 @@ CONFIG_SWAP=y
168CONFIG_SYSVIPC=y 166CONFIG_SYSVIPC=y
169# CONFIG_POSIX_MQUEUE is not set 167# CONFIG_POSIX_MQUEUE is not set
170# CONFIG_BSD_PROCESS_ACCT is not set 168# CONFIG_BSD_PROCESS_ACCT is not set
169# CONFIG_TASKSTATS is not set
171CONFIG_SYSCTL=y 170CONFIG_SYSCTL=y
172# CONFIG_AUDIT is not set 171# CONFIG_AUDIT is not set
173# CONFIG_IKCONFIG is not set 172# CONFIG_IKCONFIG is not set
@@ -841,7 +840,7 @@ CONFIG_USB_PEGASUS=m
841# CONFIG_USB_LEGOTOWER is not set 840# CONFIG_USB_LEGOTOWER is not set
842# CONFIG_USB_LCD is not set 841# CONFIG_USB_LCD is not set
843# CONFIG_USB_LED is not set 842# CONFIG_USB_LED is not set
844# CONFIG_USB_CY7C63 is not set 843# CONFIG_USB_CYPRESS_CY7C63 is not set
845# CONFIG_USB_CYTHERM is not set 844# CONFIG_USB_CYTHERM is not set
846# CONFIG_USB_PHIDGETKIT is not set 845# CONFIG_USB_PHIDGETKIT is not set
847# CONFIG_USB_PHIDGETSERVO is not set 846# CONFIG_USB_PHIDGETSERVO is not set
@@ -982,7 +981,6 @@ CONFIG_SUNRPC=y
982# CONFIG_RPCSEC_GSS_SPKM3 is not set 981# CONFIG_RPCSEC_GSS_SPKM3 is not set
983# CONFIG_SMB_FS is not set 982# CONFIG_SMB_FS is not set
984# CONFIG_CIFS is not set 983# CONFIG_CIFS is not set
985# CONFIG_CIFS_DEBUG2 is not set
986# CONFIG_NCP_FS is not set 984# CONFIG_NCP_FS is not set
987# CONFIG_CODA_FS is not set 985# CONFIG_CODA_FS is not set
988# CONFIG_AFS_FS is not set 986# CONFIG_AFS_FS is not set
@@ -1007,6 +1005,7 @@ CONFIG_MSDOS_PARTITION=y
1007# 1005#
1008# Kernel hacking 1006# Kernel hacking
1009# 1007#
1008CONFIG_TRACE_IRQFLAGS_SUPPORT=y
1010# CONFIG_PRINTK_TIME is not set 1009# CONFIG_PRINTK_TIME is not set
1011# CONFIG_MAGIC_SYSRQ is not set 1010# CONFIG_MAGIC_SYSRQ is not set
1012# CONFIG_UNUSED_SYMBOLS is not set 1011# CONFIG_UNUSED_SYMBOLS is not set
@@ -1014,7 +1013,7 @@ CONFIG_MSDOS_PARTITION=y
1014CONFIG_LOG_BUF_SHIFT=14 1013CONFIG_LOG_BUF_SHIFT=14
1015# CONFIG_DEBUG_FS is not set 1014# CONFIG_DEBUG_FS is not set
1016CONFIG_CROSSCOMPILE=y 1015CONFIG_CROSSCOMPILE=y
1017CONFIG_CMDLINE="mem=32M console=ttyVR0,19200" 1016CONFIG_CMDLINE="mem=32M console=ttyVR0,19200 ide0=0x170,0x376,73"
1018 1017
1019# 1018#
1020# Security options 1019# Security options
diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig
index ec5758f22676..4d87da2b99fd 100644
--- a/arch/mips/configs/ocelot_3_defconfig
+++ b/arch/mips/configs/ocelot_3_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig
index 0d33d87de1a1..a7ac2b0a8273 100644
--- a/arch/mips/configs/ocelot_c_defconfig
+++ b/arch/mips/configs/ocelot_c_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
@@ -774,7 +773,7 @@ CONFIG_FUSE_FS=y
774CONFIG_PROC_FS=y 773CONFIG_PROC_FS=y
775CONFIG_PROC_KCORE=y 774CONFIG_PROC_KCORE=y
776CONFIG_SYSFS=y 775CONFIG_SYSFS=y
777# CONFIG_TMPFS is not set 776CONFIG_TMPFS=y
778# CONFIG_HUGETLB_PAGE is not set 777# CONFIG_HUGETLB_PAGE is not set
779CONFIG_RAMFS=y 778CONFIG_RAMFS=y
780# CONFIG_CONFIGFS_FS is not set 779# CONFIG_CONFIGFS_FS is not set
diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig
index 4b999102715e..853e7bba5122 100644
--- a/arch/mips/configs/ocelot_defconfig
+++ b/arch/mips/configs/ocelot_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
@@ -723,7 +722,7 @@ CONFIG_FUSE_FS=y
723CONFIG_PROC_FS=y 722CONFIG_PROC_FS=y
724CONFIG_PROC_KCORE=y 723CONFIG_PROC_KCORE=y
725CONFIG_SYSFS=y 724CONFIG_SYSFS=y
726# CONFIG_TMPFS is not set 725CONFIG_TMPFS=y
727# CONFIG_HUGETLB_PAGE is not set 726# CONFIG_HUGETLB_PAGE is not set
728CONFIG_RAMFS=y 727CONFIG_RAMFS=y
729# CONFIG_CONFIGFS_FS is not set 728# CONFIG_CONFIGFS_FS is not set
diff --git a/arch/mips/configs/ocelot_g_defconfig b/arch/mips/configs/ocelot_g_defconfig
index 827b344f6010..8524efa23a49 100644
--- a/arch/mips/configs/ocelot_g_defconfig
+++ b/arch/mips/configs/ocelot_g_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
@@ -777,7 +776,7 @@ CONFIG_FUSE_FS=y
777CONFIG_PROC_FS=y 776CONFIG_PROC_FS=y
778CONFIG_PROC_KCORE=y 777CONFIG_PROC_KCORE=y
779CONFIG_SYSFS=y 778CONFIG_SYSFS=y
780# CONFIG_TMPFS is not set 779CONFIG_TMPFS=y
781# CONFIG_HUGETLB_PAGE is not set 780# CONFIG_HUGETLB_PAGE is not set
782CONFIG_RAMFS=y 781CONFIG_RAMFS=y
783# CONFIG_CONFIGFS_FS is not set 782# CONFIG_CONFIGFS_FS is not set
diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
index 9ed60fef69e0..1a16e92900cb 100644
--- a/arch/mips/configs/pb1100_defconfig
+++ b/arch/mips/configs/pb1100_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS_PB1100=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
index 6774254b1be6..9ea8edea6f29 100644
--- a/arch/mips/configs/pb1500_defconfig
+++ b/arch/mips/configs/pb1500_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS_PB1500=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
index 1afe5bf6e765..c4a158976f8f 100644
--- a/arch/mips/configs/pb1550_defconfig
+++ b/arch/mips/configs/pb1550_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS_PB1550=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig
index ac616c82d348..1cbf270c301c 100644
--- a/arch/mips/configs/pnx8550-jbs_defconfig
+++ b/arch/mips/configs/pnx8550-jbs_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/pnx8550-v2pci_defconfig b/arch/mips/configs/pnx8550-v2pci_defconfig
index a8eb51bae3f3..bec30b15b9bd 100644
--- a/arch/mips/configs/pnx8550-v2pci_defconfig
+++ b/arch/mips/configs/pnx8550-v2pci_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig
index 6a63a113b7ea..f5f799e93707 100644
--- a/arch/mips/configs/qemu_defconfig
+++ b/arch/mips/configs/qemu_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
@@ -687,7 +686,7 @@ CONFIG_FUSE_FS=y
687CONFIG_PROC_FS=y 686CONFIG_PROC_FS=y
688CONFIG_PROC_KCORE=y 687CONFIG_PROC_KCORE=y
689CONFIG_SYSFS=y 688CONFIG_SYSFS=y
690# CONFIG_TMPFS is not set 689CONFIG_TMPFS=y
691# CONFIG_HUGETLB_PAGE is not set 690# CONFIG_HUGETLB_PAGE is not set
692CONFIG_RAMFS=y 691CONFIG_RAMFS=y
693 692
diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig
index 6779f449bd2d..2f5650227ba3 100644
--- a/arch/mips/configs/rbhma4500_defconfig
+++ b/arch/mips/configs/rbhma4500_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index b7826d3a2b77..4fee90b2b100 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
@@ -1442,7 +1441,7 @@ CONFIG_NTFS_FS=m
1442CONFIG_PROC_FS=y 1441CONFIG_PROC_FS=y
1443CONFIG_PROC_KCORE=y 1442CONFIG_PROC_KCORE=y
1444CONFIG_SYSFS=y 1443CONFIG_SYSFS=y
1445# CONFIG_TMPFS is not set 1444CONFIG_TMPFS=y
1446# CONFIG_HUGETLB_PAGE is not set 1445# CONFIG_HUGETLB_PAGE is not set
1447CONFIG_RAMFS=y 1446CONFIG_RAMFS=y
1448# CONFIG_CONFIGFS_FS is not set 1447# CONFIG_CONFIGFS_FS is not set
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
index 625c1c619b6b..9041f095f96f 100644
--- a/arch/mips/configs/sb1250-swarm_defconfig
+++ b/arch/mips/configs/sb1250-swarm_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig
index 4401b602118f..02abb2f1bfaf 100644
--- a/arch/mips/configs/sead_defconfig
+++ b/arch/mips/configs/sead_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig
index 2ba4e25e8c34..ca3d0c4ba15b 100644
--- a/arch/mips/configs/tb0226_defconfig
+++ b/arch/mips/configs/tb0226_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/tb0229_defconfig b/arch/mips/configs/tb0229_defconfig
index fc8a407c1add..4e2009ace278 100644
--- a/arch/mips/configs/tb0229_defconfig
+++ b/arch/mips/configs/tb0229_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig
index effcb63b81a3..535a813d01a9 100644
--- a/arch/mips/configs/tb0287_defconfig
+++ b/arch/mips/configs/tb0287_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig
index 4891d02ef8ca..3a3ef20b21cc 100644
--- a/arch/mips/configs/workpad_defconfig
+++ b/arch/mips/configs/workpad_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.18-rc1 3# Linux kernel version: 2.6.18-rc2
4# Thu Jul 6 10:04:21 2006 4# Tue Jul 25 23:13:04 2006
5# 5#
6CONFIG_MIPS=y 6CONFIG_MIPS=y
7 7
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
@@ -166,6 +165,7 @@ CONFIG_SWAP=y
166CONFIG_SYSVIPC=y 165CONFIG_SYSVIPC=y
167# CONFIG_POSIX_MQUEUE is not set 166# CONFIG_POSIX_MQUEUE is not set
168# CONFIG_BSD_PROCESS_ACCT is not set 167# CONFIG_BSD_PROCESS_ACCT is not set
168# CONFIG_TASKSTATS is not set
169CONFIG_SYSCTL=y 169CONFIG_SYSCTL=y
170# CONFIG_AUDIT is not set 170# CONFIG_AUDIT is not set
171# CONFIG_IKCONFIG is not set 171# CONFIG_IKCONFIG is not set
@@ -379,6 +379,7 @@ CONFIG_CONNECTOR=m
379CONFIG_BLK_DEV_RAM=m 379CONFIG_BLK_DEV_RAM=m
380CONFIG_BLK_DEV_RAM_COUNT=16 380CONFIG_BLK_DEV_RAM_COUNT=16
381CONFIG_BLK_DEV_RAM_SIZE=4096 381CONFIG_BLK_DEV_RAM_SIZE=4096
382CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
382# CONFIG_BLK_DEV_INITRD is not set 383# CONFIG_BLK_DEV_INITRD is not set
383# CONFIG_CDROM_PKTCDVD is not set 384# CONFIG_CDROM_PKTCDVD is not set
384# CONFIG_ATA_OVER_ETH is not set 385# CONFIG_ATA_OVER_ETH is not set
@@ -855,7 +856,6 @@ CONFIG_SUNRPC=y
855# CONFIG_RPCSEC_GSS_SPKM3 is not set 856# CONFIG_RPCSEC_GSS_SPKM3 is not set
856# CONFIG_SMB_FS is not set 857# CONFIG_SMB_FS is not set
857# CONFIG_CIFS is not set 858# CONFIG_CIFS is not set
858# CONFIG_CIFS_DEBUG2 is not set
859# CONFIG_NCP_FS is not set 859# CONFIG_NCP_FS is not set
860# CONFIG_CODA_FS is not set 860# CONFIG_CODA_FS is not set
861# CONFIG_AFS_FS is not set 861# CONFIG_AFS_FS is not set
@@ -880,6 +880,7 @@ CONFIG_MSDOS_PARTITION=y
880# 880#
881# Kernel hacking 881# Kernel hacking
882# 882#
883CONFIG_TRACE_IRQFLAGS_SUPPORT=y
883# CONFIG_PRINTK_TIME is not set 884# CONFIG_PRINTK_TIME is not set
884# CONFIG_MAGIC_SYSRQ is not set 885# CONFIG_MAGIC_SYSRQ is not set
885# CONFIG_UNUSED_SYMBOLS is not set 886# CONFIG_UNUSED_SYMBOLS is not set
@@ -887,7 +888,7 @@ CONFIG_MSDOS_PARTITION=y
887CONFIG_LOG_BUF_SHIFT=14 888CONFIG_LOG_BUF_SHIFT=14
888# CONFIG_DEBUG_FS is not set 889# CONFIG_DEBUG_FS is not set
889CONFIG_CROSSCOMPILE=y 890CONFIG_CROSSCOMPILE=y
890CONFIG_CMDLINE="console=ttyVR0,19200 mem=16M" 891CONFIG_CMDLINE="console=ttyVR0,19200 ide0=0x170,0x376,49 mem=16M"
891 892
892# 893#
893# Security options 894# Security options
diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig
index 3e4b16b39827..e6b1dea55842 100644
--- a/arch/mips/configs/wrppmc_defconfig
+++ b/arch/mips/configs/wrppmc_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
index 3a68d8a25b66..06a072b77b1c 100644
--- a/arch/mips/configs/yosemite_defconfig
+++ b/arch/mips/configs/yosemite_defconfig
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index fff6fcc96212..cc9b24eda9e8 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/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.18-rc1 3# Linux kernel version: 2.6.18-rc1
4# Thu Jul 6 09:49:33 2006 4# Thu Jul 6 10:04:10 2006
5# 5#
6CONFIG_MIPS=y 6CONFIG_MIPS=y
7 7
@@ -25,7 +25,6 @@ CONFIG_MIPS=y
25# CONFIG_MIPS_COBALT is not set 25# CONFIG_MIPS_COBALT is not set
26# CONFIG_MACH_DECSTATION is not set 26# CONFIG_MACH_DECSTATION is not set
27# CONFIG_MIPS_EV64120 is not set 27# CONFIG_MIPS_EV64120 is not set
28# CONFIG_MIPS_EV96100 is not set
29# CONFIG_MIPS_IVR is not set 28# CONFIG_MIPS_IVR is not set
30# CONFIG_MIPS_ITE8172 is not set 29# CONFIG_MIPS_ITE8172 is not set
31# CONFIG_MACH_JAZZ is not set 30# CONFIG_MACH_JAZZ is not set
@@ -1013,7 +1012,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1013CONFIG_PROC_FS=y 1012CONFIG_PROC_FS=y
1014CONFIG_PROC_KCORE=y 1013CONFIG_PROC_KCORE=y
1015CONFIG_SYSFS=y 1014CONFIG_SYSFS=y
1016# CONFIG_TMPFS is not set 1015CONFIG_TMPFS=y
1017# CONFIG_HUGETLB_PAGE is not set 1016# CONFIG_HUGETLB_PAGE is not set
1018CONFIG_RAMFS=y 1017CONFIG_RAMFS=y
1019# CONFIG_CONFIGFS_FS is not set 1018# CONFIG_CONFIGFS_FS is not set
diff --git a/arch/mips/galileo-boards/ev96100/Makefile b/arch/mips/galileo-boards/ev96100/Makefile
deleted file mode 100644
index cd868ec78cbc..000000000000
--- a/arch/mips/galileo-boards/ev96100/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
1#
2# Copyright 2000 MontaVista Software Inc.
3# Author: MontaVista Software, Inc.
4# ppopov@mvista.com or source@mvista.com
5#
6# Makefile for the Galileo EV96100 board.
7#
8
9obj-y += init.o irq.o puts.o reset.o time.o setup.o
diff --git a/arch/mips/galileo-boards/ev96100/init.c b/arch/mips/galileo-boards/ev96100/init.c
deleted file mode 100644
index a01fe9b36f2c..000000000000
--- a/arch/mips/galileo-boards/ev96100/init.c
+++ /dev/null
@@ -1,173 +0,0 @@
1/*
2 * Copyright 2000 MontaVista Software Inc.
3 * Author: MontaVista Software, Inc.
4 * ppopov@mvista.com or source@mvista.com
5 *
6 * This file was derived from Carsten Langgaard's
7 * arch/mips/mips-boards/generic/generic.c
8 *
9 * Carsten Langgaard, carstenl@mips.com
10 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
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. IN
20 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * 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 <linux/init.h>
33#include <linux/mm.h>
34#include <linux/sched.h>
35#include <linux/bootmem.h>
36#include <linux/string.h>
37#include <linux/kernel.h>
38
39#include <asm/addrspace.h>
40#include <asm/bootinfo.h>
41#include <asm/gt64120.h>
42
43
44/* Environment variable */
45
46typedef struct {
47 char *name;
48 char *val;
49} t_env_var;
50
51int prom_argc;
52char **prom_argv, **prom_envp;
53
54int init_debug = 0;
55
56char * __init prom_getcmdline(void)
57{
58 return &(arcs_cmdline[0]);
59}
60
61unsigned long __init prom_free_prom_memory(void)
62{
63 return 0;
64}
65
66void __init prom_init_cmdline(void)
67{
68 char *cp;
69 int actr;
70
71 actr = 1; /* Always ignore argv[0] */
72
73 cp = &(arcs_cmdline[0]);
74 while(actr < prom_argc) {
75 strcpy(cp, prom_argv[actr]);
76 cp += strlen(prom_argv[actr]);
77 *cp++ = ' ';
78 actr++;
79 }
80 if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */
81 --cp;
82 *cp = '\0';
83}
84
85char *prom_getenv(char *envname)
86{
87 /*
88 * Return a pointer to the given environment variable.
89 */
90
91 t_env_var *env = (t_env_var *) prom_envp;
92 int i;
93
94 i = strlen(envname);
95
96 while (env->name) {
97 if (strncmp(envname, env->name, i) == 0) {
98 return (env->val);
99 }
100 env++;
101 }
102 return (NULL);
103}
104
105static inline unsigned char str2hexnum(unsigned char c)
106{
107 if (c >= '0' && c <= '9')
108 return c - '0';
109 if (c >= 'a' && c <= 'f')
110 return c - 'a' + 10;
111 return 0; /* foo */
112}
113
114static inline void str2eaddr(unsigned char *ea, unsigned char *str)
115{
116 int i;
117
118 for (i = 0; i < 6; i++) {
119 unsigned char num;
120
121 if ((*str == '.') || (*str == ':'))
122 str++;
123 num = str2hexnum(*str++) << 4;
124 num |= (str2hexnum(*str++));
125 ea[i] = num;
126 }
127}
128
129int get_ethernet_addr(char *ethernet_addr)
130{
131 char *ethaddr_str;
132
133 ethaddr_str = prom_getenv("ethaddr");
134 if (!ethaddr_str) {
135 printk("ethaddr not set in boot prom\n");
136 return -1;
137 }
138 str2eaddr(ethernet_addr, ethaddr_str);
139
140 if (init_debug > 1) {
141 int i;
142 printk("get_ethernet_addr: ");
143 for (i = 0; i < 5; i++)
144 printk("%02x:",
145 (unsigned char) *(ethernet_addr + i));
146 printk("%02x\n", *(ethernet_addr + i));
147 }
148
149 return 0;
150}
151
152const char *get_system_type(void)
153{
154 return "Galileo EV96100";
155}
156
157void __init prom_init(void)
158{
159 volatile unsigned char *uart;
160 char ppbuf[8];
161
162 prom_argc = fw_arg0;
163 prom_argv = (char **) fw_arg1;
164 prom_envp = (char **) fw_arg2;
165
166 mips_machgroup = MACH_GROUP_GALILEO;
167 mips_machtype = MACH_EV96100;
168
169 prom_init_cmdline();
170
171 /* 32 MB upgradable */
172 add_memory_region(0, 32 << 20, BOOT_MEM_RAM);
173}
diff --git a/arch/mips/galileo-boards/ev96100/irq.c b/arch/mips/galileo-boards/ev96100/irq.c
deleted file mode 100644
index ee5d6720f23b..000000000000
--- a/arch/mips/galileo-boards/ev96100/irq.c
+++ /dev/null
@@ -1,77 +0,0 @@
1/*
2 * Copyright 2000 MontaVista Software Inc.
3 * Author: MontaVista Software, Inc.
4 * ppopov@mvista.com or source@mvista.com
5 *
6 * This file was derived from Carsten Langgaard's
7 * arch/mips/mips-boards/atlas/atlas_int.c.
8 *
9 * Carsten Langgaard, carstenl@mips.com
10 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
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. IN
20 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * 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 <linux/errno.h>
33#include <linux/init.h>
34#include <linux/kernel_stat.h>
35#include <linux/irq.h>
36#include <linux/module.h>
37#include <linux/signal.h>
38#include <linux/sched.h>
39#include <linux/types.h>
40#include <linux/interrupt.h>
41#include <asm/irq_cpu.h>
42
43static inline unsigned int ffz8(unsigned int word)
44{
45 unsigned long k;
46
47 k = 7;
48 if (word & 0x0fUL) { k -= 4; word <<= 4; }
49 if (word & 0x30UL) { k -= 2; word <<= 2; }
50 if (word & 0x40UL) { k -= 1; }
51
52 return k;
53}
54
55extern void mips_timer_interrupt(struct pt_regs *regs);
56
57asmlinkage void ev96100_cpu_irq(unsigned int pending, struct pt_regs *regs)
58{
59 do_IRQ(ffz8(pending >> 8), regs);
60}
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
74void __init arch_init_irq(void)
75{
76 mips_cpu_irq_init(0);
77}
diff --git a/arch/mips/galileo-boards/ev96100/puts.c b/arch/mips/galileo-boards/ev96100/puts.c
deleted file mode 100644
index 49dc6d137b9c..000000000000
--- a/arch/mips/galileo-boards/ev96100/puts.c
+++ /dev/null
@@ -1,138 +0,0 @@
1
2/*
3 * Debug routines which directly access the uart.
4 */
5
6#include <linux/types.h>
7#include <asm/gt64120.h>
8
9
10//#define SERIAL_BASE EV96100_UART0_REGS_BASE
11#define SERIAL_BASE 0xBD000020
12#define NS16550_BASE SERIAL_BASE
13
14#define SERA_CMD 0x0D
15#define SERA_DATA 0x08
16//#define SERB_CMD 0x05
17#define SERB_CMD 20
18#define SERB_DATA 0x00
19#define TX_BUSY 0x20
20
21#define TIMEOUT 0xffff
22#undef SLOW_DOWN
23
24static const char digits[16] = "0123456789abcdef";
25static volatile unsigned char *const com1 = (unsigned char *) SERIAL_BASE;
26
27
28#ifdef SLOW_DOWN
29static inline void slow_down()
30{
31 int k;
32 for (k = 0; k < 10000; k++);
33}
34#else
35#define slow_down()
36#endif
37
38void putch(const unsigned char c)
39{
40 unsigned char ch;
41 int i = 0;
42
43 do {
44 ch = com1[SERB_CMD];
45 slow_down();
46 i++;
47 if (i > TIMEOUT) {
48 break;
49 }
50 } while (0 == (ch & TX_BUSY));
51 com1[SERB_DATA] = c;
52}
53
54void putchar(const unsigned char c)
55{
56 unsigned char ch;
57 int i = 0;
58
59 do {
60 ch = com1[SERB_CMD];
61 slow_down();
62 i++;
63 if (i > TIMEOUT) {
64 break;
65 }
66 } while (0 == (ch & TX_BUSY));
67 com1[SERB_DATA] = c;
68}
69
70void puts(unsigned char *cp)
71{
72 unsigned char ch;
73 int i = 0;
74
75 while (*cp) {
76 do {
77 ch = com1[SERB_CMD];
78 slow_down();
79 i++;
80 if (i > TIMEOUT) {
81 break;
82 }
83 } while (0 == (ch & TX_BUSY));
84 com1[SERB_DATA] = *cp++;
85 }
86 putch('\r');
87 putch('\n');
88}
89
90void fputs(unsigned char *cp)
91{
92 unsigned char ch;
93 int i = 0;
94
95 while (*cp) {
96
97 do {
98 ch = com1[SERB_CMD];
99 slow_down();
100 i++;
101 if (i > TIMEOUT) {
102 break;
103 }
104 } while (0 == (ch & TX_BUSY));
105 com1[SERB_DATA] = *cp++;
106 }
107}
108
109
110void put64(uint64_t ul)
111{
112 int cnt;
113 unsigned ch;
114
115 cnt = 16; /* 16 nibbles in a 64 bit long */
116 putch('0');
117 putch('x');
118 do {
119 cnt--;
120 ch = (unsigned char) (ul >> cnt * 4) & 0x0F;
121 putch(digits[ch]);
122 } while (cnt > 0);
123}
124
125void put32(unsigned u)
126{
127 int cnt;
128 unsigned ch;
129
130 cnt = 8; /* 8 nibbles in a 32 bit long */
131 putch('0');
132 putch('x');
133 do {
134 cnt--;
135 ch = (unsigned char) (u >> cnt * 4) & 0x0F;
136 putch(digits[ch]);
137 } while (cnt > 0);
138}
diff --git a/arch/mips/galileo-boards/ev96100/reset.c b/arch/mips/galileo-boards/ev96100/reset.c
deleted file mode 100644
index 5ef9b7f896e6..000000000000
--- a/arch/mips/galileo-boards/ev96100/reset.c
+++ /dev/null
@@ -1,70 +0,0 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * Galileo EV96100 reset routines.
4 *
5 * Copyright 2000 MontaVista Software Inc.
6 * Author: MontaVista Software, Inc.
7 * ppopov@mvista.com or source@mvista.com
8 *
9 * This file was derived from Carsten Langgaard's
10 * arch/mips/mips-boards/generic/reset.c
11 *
12 * Carsten Langgaard, carstenl@mips.com
13 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
14 *
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
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
19 *
20 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
21 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
23 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * You should have received a copy of the GNU General Public License along
32 * with this program; if not, write to the Free Software Foundation, Inc.,
33 * 675 Mass Ave, Cambridge, MA 02139, USA.
34 */
35#include <linux/sched.h>
36#include <linux/mm.h>
37#include <asm/io.h>
38#include <asm/pgtable.h>
39#include <asm/processor.h>
40#include <asm/reboot.h>
41#include <asm/system.h>
42#include <asm/gt64120.h>
43
44static void mips_machine_restart(char *command);
45static void mips_machine_halt(void);
46
47static void mips_machine_restart(char *command)
48{
49 set_c0_status(ST0_BEV | ST0_ERL);
50 change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
51 flush_cache_all();
52 write_c0_wired(0);
53 __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
54 while (1);
55}
56
57static void mips_machine_halt(void)
58{
59 printk(KERN_NOTICE "You can safely turn off the power\n");
60 while (1)
61 __asm__(".set\tmips3\n\t"
62 "wait\n\t"
63 ".set\tmips0");
64}
65
66void mips_reboot_setup(void)
67{
68 _machine_restart = mips_machine_restart;
69 _machine_halt = mips_machine_halt;
70}
diff --git a/arch/mips/galileo-boards/ev96100/setup.c b/arch/mips/galileo-boards/ev96100/setup.c
deleted file mode 100644
index 639ad5562c63..000000000000
--- a/arch/mips/galileo-boards/ev96100/setup.c
+++ /dev/null
@@ -1,159 +0,0 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * Galileo EV96100 setup.
4 *
5 * Copyright 2000 MontaVista Software Inc.
6 * Author: MontaVista Software, Inc.
7 * ppopov@mvista.com or source@mvista.com
8 *
9 * This file was derived from Carsten Langgaard's
10 * arch/mips/mips-boards/atlas/atlas_setup.c.
11 *
12 * Carsten Langgaard, carstenl@mips.com
13 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
14 *
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
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
19 *
20 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
21 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
23 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * You should have received a copy of the GNU General Public License along
32 * with this program; if not, write to the Free Software Foundation, Inc.,
33 * 675 Mass Ave, Cambridge, MA 02139, USA.
34 */
35#include <linux/init.h>
36#include <linux/sched.h>
37#include <linux/ioport.h>
38#include <linux/string.h>
39#include <linux/ctype.h>
40#include <linux/pci.h>
41
42#include <asm/cpu.h>
43#include <asm/bootinfo.h>
44#include <asm/mipsregs.h>
45#include <asm/irq.h>
46#include <asm/delay.h>
47#include <asm/gt64120.h>
48#include <asm/galileo-boards/ev96100int.h>
49
50
51extern char *__init prom_getcmdline(void);
52
53extern void mips_reboot_setup(void);
54
55unsigned char mac_0_1[12];
56
57void __init plat_mem_setup(void)
58{
59 unsigned int config = read_c0_config();
60 unsigned int status = read_c0_status();
61 unsigned int info = read_c0_info();
62 u32 tmp;
63
64 char *argptr;
65
66 clear_c0_status(ST0_FR);
67
68 if (config & 0x8)
69 printk("Secondary cache is enabled\n");
70 else
71 printk("Secondary cache is disabled\n");
72
73 if (status & (1 << 27))
74 printk("User-mode cache ops enabled\n");
75 else
76 printk("User-mode cache ops disabled\n");
77
78 printk("CP0 info reg: %x\n", (unsigned) info);
79 if (info & (1 << 28))
80 printk("burst mode Scache RAMS\n");
81 else
82 printk("pipelined Scache RAMS\n");
83
84 if (info & 0x1)
85 printk("Atomic Enable is set\n");
86
87 argptr = prom_getcmdline();
88#ifdef CONFIG_SERIAL_CONSOLE
89 if (strstr(argptr, "console=") == NULL) {
90 argptr = prom_getcmdline();
91 strcat(argptr, " console=ttyS0,115200");
92 }
93#endif
94
95 mips_reboot_setup();
96
97 set_io_port_base(KSEG1);
98 ioport_resource.start = GT_PCI_IO_BASE;
99 ioport_resource.end = GT_PCI_IO_BASE + 0x01ffffff;
100
101#ifdef CONFIG_BLK_DEV_INITRD
102 ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
103#endif
104
105
106 /*
107 * Setup GT controller master bit so we can do config cycles
108 */
109
110 /* Clear cause register bits */
111 GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
112 GT_INTRCAUSE_TARABORT0_BIT));
113 /* Setup address */
114 GT_WRITE(GT_PCI0_CFGADDR_OFS,
115 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) |
116 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
117 ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
118 GT_PCI0_CFGADDR_CONFIGEN_BIT);
119
120 udelay(2);
121 tmp = GT_READ(GT_PCI0_CFGDATA_OFS);
122
123 tmp |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
124 PCI_COMMAND_MASTER | PCI_COMMAND_SERR);
125 GT_WRITE(GT_PCI0_CFGADDR_OFS,
126 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) |
127 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
128 ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
129 GT_PCI0_CFGADDR_CONFIGEN_BIT);
130 udelay(2);
131 GT_WRITE(GT_PCI0_CFGDATA_OFS, tmp);
132
133 /* Setup address */
134 GT_WRITE(GT_PCI0_CFGADDR_OFS,
135 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) |
136 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
137 ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
138 GT_PCI0_CFGADDR_CONFIGEN_BIT);
139
140 udelay(2);
141 tmp = GT_READ(GT_PCI0_CFGDATA_OFS);
142}
143
144unsigned short get_gt_devid(void)
145{
146 u32 gt_devid;
147
148 /* Figure out if this is a gt96100 or gt96100A */
149 GT_WRITE(GT_PCI0_CFGADDR_OFS,
150 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) |
151 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
152 ((PCI_VENDOR_ID / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
153 GT_PCI0_CFGADDR_CONFIGEN_BIT);
154
155 udelay(4);
156 gt_devid = GT_READ(GT_PCI0_CFGDATA_OFS);
157
158 return gt_devid >> 16;
159}
diff --git a/arch/mips/galileo-boards/ev96100/time.c b/arch/mips/galileo-boards/ev96100/time.c
deleted file mode 100644
index 8cbe8426491a..000000000000
--- a/arch/mips/galileo-boards/ev96100/time.c
+++ /dev/null
@@ -1,88 +0,0 @@
1/*
2 * BRIEF MODULE DESCRIPTION
3 * Galileo EV96100 rtc routines.
4 *
5 * Copyright 2000 MontaVista Software Inc.
6 * Author: MontaVista Software, Inc.
7 * ppopov@mvista.com or source@mvista.com
8 *
9 * This file was derived from Carsten Langgaard's
10 * arch/mips/mips-boards/atlas/atlas_rtc.c.
11 *
12 * Carsten Langgaard, carstenl@mips.com
13 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
14 *
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
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
19 *
20 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
21 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
23 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * You should have received a copy of the GNU General Public License along
32 * with this program; if not, write to the Free Software Foundation, Inc.,
33 * 675 Mass Ave, Cambridge, MA 02139, USA.
34 */
35#include <linux/init.h>
36#include <linux/kernel_stat.h>
37#include <linux/module.h>
38#include <linux/sched.h>
39#include <linux/spinlock.h>
40#include <linux/timex.h>
41
42#include <asm/mipsregs.h>
43#include <asm/ptrace.h>
44#include <asm/time.h>
45
46
47#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
48
49extern volatile unsigned long wall_jiffies;
50unsigned long missed_heart_beats = 0;
51
52static unsigned long r4k_offset; /* Amount to increment compare reg each time */
53static unsigned long r4k_cur; /* What counter should be at next timer irq */
54
55static inline void ack_r4ktimer(unsigned long newval)
56{
57 write_c0_compare(newval);
58}
59
60/*
61 * There are a lot of conceptually broken versions of the MIPS timer interrupt
62 * handler floating around. This one is rather different, but the algorithm
63 * is probably more robust.
64 */
65void mips_timer_interrupt(struct pt_regs *regs)
66{
67 int irq = 7; /* FIX ME */
68
69 if (r4k_offset == 0) {
70 goto null;
71 }
72
73 do {
74 kstat_this_cpu.irqs[irq]++;
75 do_timer(regs);
76#ifndef CONFIG_SMP
77 update_process_times(user_mode(regs));
78#endif
79 r4k_cur += r4k_offset;
80 ack_r4ktimer(r4k_cur);
81
82 } while (((unsigned long)read_c0_count()
83 - r4k_cur) < 0x7fffffff);
84 return;
85
86null:
87 ack_r4ktimer(0);
88}
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index aa2caa67299a..9fbf8430c849 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -38,15 +38,40 @@ static void r3081_wait(void)
38 38
39static void r39xx_wait(void) 39static void r39xx_wait(void)
40{ 40{
41 unsigned long cfg = read_c0_conf(); 41 local_irq_disable();
42 write_c0_conf(cfg | TX39_CONF_HALT); 42 if (!need_resched())
43 write_c0_conf(read_c0_conf() | TX39_CONF_HALT);
44 local_irq_enable();
43} 45}
44 46
47/*
48 * There is a race when WAIT instruction executed with interrupt
49 * enabled.
50 * But it is implementation-dependent wheter the pipelie restarts when
51 * a non-enabled interrupt is requested.
52 */
45static void r4k_wait(void) 53static void r4k_wait(void)
46{ 54{
47 __asm__(".set\tmips3\n\t" 55 __asm__(" .set mips3 \n"
48 "wait\n\t" 56 " wait \n"
49 ".set\tmips0"); 57 " .set mips0 \n");
58}
59
60/*
61 * This variant is preferable as it allows testing need_resched and going to
62 * sleep depending on the outcome atomically. Unfortunately the "It is
63 * implementation-dependent whether the pipeline restarts when a non-enabled
64 * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes
65 * using this version a gamble.
66 */
67static void r4k_wait_irqoff(void)
68{
69 local_irq_disable();
70 if (!need_resched())
71 __asm__(" .set mips3 \n"
72 " wait \n"
73 " .set mips0 \n");
74 local_irq_enable();
50} 75}
51 76
52/* The Au1xxx wait is available only if using 32khz counter or 77/* The Au1xxx wait is available only if using 32khz counter or
@@ -56,17 +81,17 @@ int allow_au1k_wait;
56static void au1k_wait(void) 81static void au1k_wait(void)
57{ 82{
58 /* using the wait instruction makes CP0 counter unusable */ 83 /* using the wait instruction makes CP0 counter unusable */
59 __asm__(".set mips3\n\t" 84 __asm__(" .set mips3 \n"
60 "cache 0x14, 0(%0)\n\t" 85 " cache 0x14, 0(%0) \n"
61 "cache 0x14, 32(%0)\n\t" 86 " cache 0x14, 32(%0) \n"
62 "sync\n\t" 87 " sync \n"
63 "nop\n\t" 88 " nop \n"
64 "wait\n\t" 89 " wait \n"
65 "nop\n\t" 90 " nop \n"
66 "nop\n\t" 91 " nop \n"
67 "nop\n\t" 92 " nop \n"
68 "nop\n\t" 93 " nop \n"
69 ".set mips0\n\t" 94 " .set mips0 \n"
70 : : "r" (au1k_wait)); 95 : : "r" (au1k_wait));
71} 96}
72 97
@@ -111,7 +136,6 @@ static inline void check_wait(void)
111 case CPU_NEVADA: 136 case CPU_NEVADA:
112 case CPU_RM7000: 137 case CPU_RM7000:
113 case CPU_RM9000: 138 case CPU_RM9000:
114 case CPU_TX49XX:
115 case CPU_4KC: 139 case CPU_4KC:
116 case CPU_4KEC: 140 case CPU_4KEC:
117 case CPU_4KSC: 141 case CPU_4KSC:
@@ -125,6 +149,10 @@ static inline void check_wait(void)
125 cpu_wait = r4k_wait; 149 cpu_wait = r4k_wait;
126 printk(" available.\n"); 150 printk(" available.\n");
127 break; 151 break;
152 case CPU_TX49XX:
153 cpu_wait = r4k_wait_irqoff;
154 printk(" available.\n");
155 break;
128 case CPU_AU1000: 156 case CPU_AU1000:
129 case CPU_AU1100: 157 case CPU_AU1100:
130 case CPU_AU1500: 158 case CPU_AU1500:
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index 676e868d26fb..2132485caa74 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -17,6 +17,7 @@
17 17
18#include <asm/ptrace.h> 18#include <asm/ptrace.h>
19#include <asm/uaccess.h> 19#include <asm/uaccess.h>
20#include <asm/unistd.h>
20 21
21#undef DEBUG_SIG 22#undef DEBUG_SIG
22 23
@@ -172,11 +173,12 @@ static inline int handle_signal(unsigned long sig, siginfo_t *info,
172 return ret; 173 return ret;
173} 174}
174 175
175asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) 176void do_irix_signal(struct pt_regs *regs)
176{ 177{
177 struct k_sigaction ka; 178 struct k_sigaction ka;
178 siginfo_t info; 179 siginfo_t info;
179 int signr; 180 int signr;
181 sigset_t *oldset;
180 182
181 /* 183 /*
182 * We want the common case to go fast, which is why we may in certain 184 * We want the common case to go fast, which is why we may in certain
@@ -184,19 +186,28 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
184 * if so. 186 * if so.
185 */ 187 */
186 if (!user_mode(regs)) 188 if (!user_mode(regs))
187 return 1; 189 return;
188 190
189 if (try_to_freeze()) 191 if (test_thread_flag(TIF_RESTORE_SIGMASK))
190 goto no_signal; 192 oldset = &current->saved_sigmask;
191 193 else
192 if (!oldset)
193 oldset = &current->blocked; 194 oldset = &current->blocked;
194 195
195 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 196 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
196 if (signr > 0) 197 if (signr > 0) {
197 return handle_signal(signr, &info, &ka, oldset, regs); 198 /* Whee! Actually deliver the signal. */
199 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
200 /* a signal was successfully delivered; the saved
201 * sigmask will have been stored in the signal frame,
202 * and will be restored by sigreturn, so we can simply
203 * clear the TIF_RESTORE_SIGMASK flag */
204 if (test_thread_flag(TIF_RESTORE_SIGMASK))
205 clear_thread_flag(TIF_RESTORE_SIGMASK);
206 }
207
208 return;
209 }
198 210
199no_signal:
200 /* 211 /*
201 * Who's code doesn't conform to the restartable syscall convention 212 * Who's code doesn't conform to the restartable syscall convention
202 * dies here!!! The li instruction, a single machine instruction, 213 * dies here!!! The li instruction, a single machine instruction,
@@ -208,8 +219,22 @@ no_signal:
208 regs->regs[2] == ERESTARTNOINTR) { 219 regs->regs[2] == ERESTARTNOINTR) {
209 regs->cp0_epc -= 8; 220 regs->cp0_epc -= 8;
210 } 221 }
222 if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
223 regs->regs[2] = __NR_restart_syscall;
224 regs->regs[7] = regs->regs[26];
225 regs->cp0_epc -= 4;
226 }
227 regs->regs[0] = 0; /* Don't deal with this again. */
228 }
229
230 /*
231 * If there's no signal to deliver, we just put the saved sigmask
232 * back
233 */
234 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
235 clear_thread_flag(TIF_RESTORE_SIGMASK);
236 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
211 } 237 }
212 return 0;
213} 238}
214 239
215asmlinkage void 240asmlinkage void
@@ -298,6 +323,9 @@ struct sigact_irix5 {
298 int _unused0[2]; 323 int _unused0[2];
299}; 324};
300 325
326#define SIG_SETMASK32 256 /* Goodie from SGI for BSD compatibility:
327 set only the low 32 bit of the sigset. */
328
301#ifdef DEBUG_SIG 329#ifdef DEBUG_SIG
302static inline void dump_sigact_irix5(struct sigact_irix5 *p) 330static inline void dump_sigact_irix5(struct sigact_irix5 *p)
303{ 331{
@@ -413,7 +441,7 @@ asmlinkage int irix_sigprocmask(int how, irix_sigset_t __user *new,
413 441
414asmlinkage int irix_sigsuspend(struct pt_regs *regs) 442asmlinkage int irix_sigsuspend(struct pt_regs *regs)
415{ 443{
416 sigset_t saveset, newset; 444 sigset_t newset;
417 sigset_t __user *uset; 445 sigset_t __user *uset;
418 446
419 uset = (sigset_t __user *) regs->regs[4]; 447 uset = (sigset_t __user *) regs->regs[4];
@@ -422,18 +450,15 @@ asmlinkage int irix_sigsuspend(struct pt_regs *regs)
422 sigdelsetmask(&newset, ~_BLOCKABLE); 450 sigdelsetmask(&newset, ~_BLOCKABLE);
423 451
424 spin_lock_irq(&current->sighand->siglock); 452 spin_lock_irq(&current->sighand->siglock);
425 saveset = current->blocked; 453 current->saved_sigmask = current->blocked;
426 current->blocked = newset; 454 current->blocked = newset;
427 recalc_sigpending(); 455 recalc_sigpending();
428 spin_unlock_irq(&current->sighand->siglock); 456 spin_unlock_irq(&current->sighand->siglock);
429 457
430 regs->regs[2] = -EINTR; 458 current->state = TASK_INTERRUPTIBLE;
431 while (1) { 459 schedule();
432 current->state = TASK_INTERRUPTIBLE; 460 set_thread_flag(TIF_RESTORE_SIGMASK);
433 schedule(); 461 return -ERESTARTNOHAND;
434 if (do_irix_signal(&saveset, regs))
435 return -EINTR;
436 }
437} 462}
438 463
439/* hate hate hate... */ 464/* hate hate hate... */
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 450ac592da57..43b1162d714f 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -991,7 +991,7 @@ struct sysctl_args32
991 unsigned int __unused[4]; 991 unsigned int __unused[4];
992}; 992};
993 993
994#ifdef CONFIG_SYSCTL 994#ifdef CONFIG_SYSCTL_SYSCALL
995 995
996asmlinkage long sys32_sysctl(struct sysctl_args32 __user *args) 996asmlinkage long sys32_sysctl(struct sysctl_args32 __user *args)
997{ 997{
@@ -1032,7 +1032,7 @@ asmlinkage long sys32_sysctl(struct sysctl_args32 __user *args)
1032 return error; 1032 return error;
1033} 1033}
1034 1034
1035#endif /* CONFIG_SYSCTL */ 1035#endif /* CONFIG_SYSCTL_SYSCALL */
1036 1036
1037asmlinkage long sys32_newuname(struct new_utsname __user * name) 1037asmlinkage long sys32_newuname(struct new_utsname __user * name)
1038{ 1038{
@@ -1296,9 +1296,3 @@ _sys32_clone(nabi_no_regargs struct pt_regs regs)
1296 return do_fork(clone_flags, newsp, &regs, 0, 1296 return do_fork(clone_flags, newsp, &regs, 0,
1297 parent_tidptr, child_tidptr); 1297 parent_tidptr, child_tidptr);
1298} 1298}
1299
1300extern asmlinkage void sys_set_thread_area(u32 addr);
1301asmlinkage void sys32_set_thread_area(u32 addr)
1302{
1303 sys_set_thread_area(AA(addr));
1304}
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 7ab67f786bfe..2613a0dd4b82 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -273,104 +273,107 @@ long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
273 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL); 273 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
274} 274}
275 275
276static struct mips_frame_info { 276/*
277 void *func; 277 *
278 unsigned long func_size; 278 */
279 int frame_size; 279struct mips_frame_info {
280 int pc_offset; 280 void *func;
281} *schedule_frame, mfinfo[64]; 281 unsigned long func_size;
282static int mfinfo_num; 282 int frame_size;
283 283 int pc_offset;
284static int __init get_frame_info(struct mips_frame_info *info) 284};
285
286static inline int is_ra_save_ins(union mips_instruction *ip)
285{ 287{
286 int i; 288 /* sw / sd $ra, offset($sp) */
287 void *func = info->func; 289 return (ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) &&
288 union mips_instruction *ip = (union mips_instruction *)func; 290 ip->i_format.rs == 29 &&
291 ip->i_format.rt == 31;
292}
293
294static inline int is_jal_jalr_jr_ins(union mips_instruction *ip)
295{
296 if (ip->j_format.opcode == jal_op)
297 return 1;
298 if (ip->r_format.opcode != spec_op)
299 return 0;
300 return ip->r_format.func == jalr_op || ip->r_format.func == jr_op;
301}
302
303static inline int is_sp_move_ins(union mips_instruction *ip)
304{
305 /* addiu/daddiu sp,sp,-imm */
306 if (ip->i_format.rs != 29 || ip->i_format.rt != 29)
307 return 0;
308 if (ip->i_format.opcode == addiu_op || ip->i_format.opcode == daddiu_op)
309 return 1;
310 return 0;
311}
312
313static int get_frame_info(struct mips_frame_info *info)
314{
315 union mips_instruction *ip = info->func;
316 unsigned max_insns = info->func_size / sizeof(union mips_instruction);
317 unsigned i;
318
289 info->pc_offset = -1; 319 info->pc_offset = -1;
290 info->frame_size = 0; 320 info->frame_size = 0;
291 for (i = 0; i < 128; i++, ip++) {
292 /* if jal, jalr, jr, stop. */
293 if (ip->j_format.opcode == jal_op ||
294 (ip->r_format.opcode == spec_op &&
295 (ip->r_format.func == jalr_op ||
296 ip->r_format.func == jr_op)))
297 break;
298 321
299 if (info->func_size && i >= info->func_size / 4) 322 if (!ip)
323 goto err;
324
325 if (max_insns == 0)
326 max_insns = 128U; /* unknown function size */
327 max_insns = min(128U, max_insns);
328
329 for (i = 0; i < max_insns; i++, ip++) {
330
331 if (is_jal_jalr_jr_ins(ip))
300 break; 332 break;
301 if ( 333 if (!info->frame_size) {
302#ifdef CONFIG_32BIT 334 if (is_sp_move_ins(ip))
303 ip->i_format.opcode == addiu_op && 335 info->frame_size = - ip->i_format.simmediate;
304#endif 336 continue;
305#ifdef CONFIG_64BIT
306 ip->i_format.opcode == daddiu_op &&
307#endif
308 ip->i_format.rs == 29 &&
309 ip->i_format.rt == 29) {
310 /* addiu/daddiu sp,sp,-imm */
311 if (info->frame_size)
312 continue;
313 info->frame_size = - ip->i_format.simmediate;
314 } 337 }
315 338 if (info->pc_offset == -1 && is_ra_save_ins(ip)) {
316 if (
317#ifdef CONFIG_32BIT
318 ip->i_format.opcode == sw_op &&
319#endif
320#ifdef CONFIG_64BIT
321 ip->i_format.opcode == sd_op &&
322#endif
323 ip->i_format.rs == 29 &&
324 ip->i_format.rt == 31) {
325 /* sw / sd $ra, offset($sp) */
326 if (info->pc_offset != -1)
327 continue;
328 info->pc_offset = 339 info->pc_offset =
329 ip->i_format.simmediate / sizeof(long); 340 ip->i_format.simmediate / sizeof(long);
341 break;
330 } 342 }
331 } 343 }
332 if (info->pc_offset == -1 || info->frame_size == 0) { 344 if (info->frame_size && info->pc_offset >= 0) /* nested */
333 if (func == schedule) 345 return 0;
334 printk("Can't analyze prologue code at %p\n", func); 346 if (info->pc_offset < 0) /* leaf */
335 info->pc_offset = -1; 347 return 1;
336 info->frame_size = 0; 348 /* prologue seems boggus... */
337 } 349err:
338 350 return -1;
339 return 0;
340} 351}
341 352
353static struct mips_frame_info schedule_mfi __read_mostly;
354
342static int __init frame_info_init(void) 355static int __init frame_info_init(void)
343{ 356{
344 int i; 357 unsigned long size = 0;
345#ifdef CONFIG_KALLSYMS 358#ifdef CONFIG_KALLSYMS
359 unsigned long ofs;
346 char *modname; 360 char *modname;
347 char namebuf[KSYM_NAME_LEN + 1]; 361 char namebuf[KSYM_NAME_LEN + 1];
348 unsigned long start, size, ofs; 362
349 extern char __sched_text_start[], __sched_text_end[]; 363 kallsyms_lookup((unsigned long)schedule, &size, &ofs, &modname, namebuf);
350 extern char __lock_text_start[], __lock_text_end[];
351
352 start = (unsigned long)__sched_text_start;
353 for (i = 0; i < ARRAY_SIZE(mfinfo); i++) {
354 if (start == (unsigned long)schedule)
355 schedule_frame = &mfinfo[i];
356 if (!kallsyms_lookup(start, &size, &ofs, &modname, namebuf))
357 break;
358 mfinfo[i].func = (void *)(start + ofs);
359 mfinfo[i].func_size = size;
360 start += size - ofs;
361 if (start >= (unsigned long)__lock_text_end)
362 break;
363 if (start == (unsigned long)__sched_text_end)
364 start = (unsigned long)__lock_text_start;
365 }
366#else
367 mfinfo[0].func = schedule;
368 schedule_frame = &mfinfo[0];
369#endif 364#endif
370 for (i = 0; i < ARRAY_SIZE(mfinfo) && mfinfo[i].func; i++) 365 schedule_mfi.func = schedule;
371 get_frame_info(&mfinfo[i]); 366 schedule_mfi.func_size = size;
367
368 get_frame_info(&schedule_mfi);
369
370 /*
371 * Without schedule() frame info, result given by
372 * thread_saved_pc() and get_wchan() are not reliable.
373 */
374 if (schedule_mfi.pc_offset < 0)
375 printk("Can't analyze schedule() prologue at %p\n", schedule);
372 376
373 mfinfo_num = i;
374 return 0; 377 return 0;
375} 378}
376 379
@@ -386,54 +389,86 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
386 /* New born processes are a special case */ 389 /* New born processes are a special case */
387 if (t->reg31 == (unsigned long) ret_from_fork) 390 if (t->reg31 == (unsigned long) ret_from_fork)
388 return t->reg31; 391 return t->reg31;
389 392 if (schedule_mfi.pc_offset < 0)
390 if (!schedule_frame || schedule_frame->pc_offset < 0)
391 return 0; 393 return 0;
392 return ((unsigned long *)t->reg29)[schedule_frame->pc_offset]; 394 return ((unsigned long *)t->reg29)[schedule_mfi.pc_offset];
393} 395}
394 396
395/* get_wchan - a maintenance nightmare^W^Wpain in the ass ... */ 397
396unsigned long get_wchan(struct task_struct *p) 398#ifdef CONFIG_KALLSYMS
399/* used by show_backtrace() */
400unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
401 unsigned long pc, unsigned long ra)
397{ 402{
398 unsigned long stack_page; 403 unsigned long stack_page;
399 unsigned long pc; 404 struct mips_frame_info info;
400#ifdef CONFIG_KALLSYMS 405 char *modname;
401 unsigned long frame; 406 char namebuf[KSYM_NAME_LEN + 1];
402#endif 407 unsigned long size, ofs;
408 int leaf;
403 409
404 if (!p || p == current || p->state == TASK_RUNNING) 410 stack_page = (unsigned long)task_stack_page(task);
411 if (!stack_page)
405 return 0; 412 return 0;
406 413
407 stack_page = (unsigned long)task_stack_page(p); 414 if (!kallsyms_lookup(pc, &size, &ofs, &modname, namebuf))
408 if (!stack_page || !mfinfo_num) 415 return 0;
416 /*
417 * Return ra if an exception occured at the first instruction
418 */
419 if (unlikely(ofs == 0))
420 return ra;
421
422 info.func = (void *)(pc - ofs);
423 info.func_size = ofs; /* analyze from start to ofs */
424 leaf = get_frame_info(&info);
425 if (leaf < 0)
426 return 0;
427
428 if (*sp < stack_page ||
429 *sp + info.frame_size > stack_page + THREAD_SIZE - 32)
409 return 0; 430 return 0;
410 431
411 pc = thread_saved_pc(p); 432 if (leaf)
433 /*
434 * For some extreme cases, get_frame_info() can
435 * consider wrongly a nested function as a leaf
436 * one. In that cases avoid to return always the
437 * same value.
438 */
439 pc = pc != ra ? ra : 0;
440 else
441 pc = ((unsigned long *)(*sp))[info.pc_offset];
442
443 *sp += info.frame_size;
444 return __kernel_text_address(pc) ? pc : 0;
445}
446#endif
447
448/*
449 * get_wchan - a maintenance nightmare^W^Wpain in the ass ...
450 */
451unsigned long get_wchan(struct task_struct *task)
452{
453 unsigned long pc = 0;
412#ifdef CONFIG_KALLSYMS 454#ifdef CONFIG_KALLSYMS
413 if (!in_sched_functions(pc)) 455 unsigned long sp;
414 return pc; 456#endif
415 457
416 frame = p->thread.reg29 + schedule_frame->frame_size; 458 if (!task || task == current || task->state == TASK_RUNNING)
417 do { 459 goto out;
418 int i; 460 if (!task_stack_page(task))
461 goto out;
419 462
420 if (frame < stack_page || frame > stack_page + THREAD_SIZE - 32) 463 pc = thread_saved_pc(task);
421 return 0;
422 464
423 for (i = mfinfo_num - 1; i >= 0; i--) { 465#ifdef CONFIG_KALLSYMS
424 if (pc >= (unsigned long) mfinfo[i].func) 466 sp = task->thread.reg29 + schedule_mfi.frame_size;
425 break;
426 }
427 if (i < 0)
428 break;
429 467
430 pc = ((unsigned long *)frame)[mfinfo[i].pc_offset]; 468 while (in_sched_functions(pc))
431 if (!mfinfo[i].frame_size) 469 pc = unwind_stack(task, &sp, pc, 0);
432 break;
433 frame += mfinfo[i].frame_size;
434 } while (in_sched_functions(pc));
435#endif 470#endif
436 471
472out:
437 return pc; 473 return pc;
438} 474}
439
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index ba1bcd83c7d3..e71785102206 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -662,6 +662,8 @@ einval: li v0, -EINVAL
662 sys sys_tee 4 662 sys sys_tee 4
663 sys sys_vmsplice 4 663 sys sys_vmsplice 4
664 sys sys_move_pages 6 664 sys sys_move_pages 6
665 sys sys_set_robust_list 2
666 sys sys_get_robust_list 3
665 .endm 667 .endm
666 668
667 /* We pre-compute the number of _instruction_ bytes needed to 669 /* 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 939e172db953..4c22d0b4825d 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -466,3 +466,5 @@ sys_call_table:
466 PTR sys_tee /* 5265 */ 466 PTR sys_tee /* 5265 */
467 PTR sys_vmsplice 467 PTR sys_vmsplice
468 PTR sys_move_pages 468 PTR sys_move_pages
469 PTR sys_set_robust_list
470 PTR sys_get_robust_list
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 98abbc5a9f13..f25c2a2f1038 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -247,7 +247,7 @@ EXPORT(sysn32_call_table)
247 PTR sys_capset 247 PTR sys_capset
248 PTR sys32_rt_sigpending /* 6125 */ 248 PTR sys32_rt_sigpending /* 6125 */
249 PTR compat_sys_rt_sigtimedwait 249 PTR compat_sys_rt_sigtimedwait
250 PTR sys_rt_sigqueueinfo 250 PTR sys32_rt_sigqueueinfo
251 PTR sysn32_rt_sigsuspend 251 PTR sysn32_rt_sigsuspend
252 PTR sys32_sigaltstack 252 PTR sys32_sigaltstack
253 PTR compat_sys_utime /* 6130 */ 253 PTR compat_sys_utime /* 6130 */
@@ -390,5 +390,7 @@ EXPORT(sysn32_call_table)
390 PTR sys_splice 390 PTR sys_splice
391 PTR sys_sync_file_range 391 PTR sys_sync_file_range
392 PTR sys_tee 392 PTR sys_tee
393 PTR sys_vmsplice /* 6271 */ 393 PTR sys_vmsplice /* 6270 */
394 PTR sys_move_pages 394 PTR sys_move_pages
395 PTR compat_sys_set_robust_list
396 PTR compat_sys_get_robust_list
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 505c9ee54009..288ee4ac4dbb 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -498,7 +498,7 @@ sys_call_table:
498 PTR sys_mknodat /* 4290 */ 498 PTR sys_mknodat /* 4290 */
499 PTR sys_fchownat 499 PTR sys_fchownat
500 PTR compat_sys_futimesat 500 PTR compat_sys_futimesat
501 PTR compat_sys_newfstatat 501 PTR sys_newfstatat
502 PTR sys_unlinkat 502 PTR sys_unlinkat
503 PTR sys_renameat /* 4295 */ 503 PTR sys_renameat /* 4295 */
504 PTR sys_linkat 504 PTR sys_linkat
@@ -514,4 +514,6 @@ sys_call_table:
514 PTR sys_tee 514 PTR sys_tee
515 PTR sys_vmsplice 515 PTR sys_vmsplice
516 PTR compat_sys_move_pages 516 PTR compat_sys_move_pages
517 PTR compat_sys_set_robust_list
518 PTR compat_sys_get_robust_list /* 4310 */
517 .size sys_call_table,.-sys_call_table 519 .size sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 8c2b596a136f..fdbb508661c5 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -10,29 +10,15 @@
10 * Copyright (C) 1999 Silicon Graphics, Inc. 10 * Copyright (C) 1999 Silicon Graphics, Inc.
11 * Copyright (C) 2000 2001, 2002 Maciej W. Rozycki 11 * Copyright (C) 2000 2001, 2002 Maciej W. Rozycki
12 */ 12 */
13#include <linux/errno.h>
14#include <linux/init.h> 13#include <linux/init.h>
15#include <linux/ioport.h> 14#include <linux/ioport.h>
16#include <linux/sched.h>
17#include <linux/kernel.h>
18#include <linux/mm.h>
19#include <linux/module.h> 15#include <linux/module.h>
20#include <linux/stddef.h>
21#include <linux/string.h>
22#include <linux/unistd.h>
23#include <linux/slab.h>
24#include <linux/user.h>
25#include <linux/utsname.h>
26#include <linux/a.out.h>
27#include <linux/screen_info.h> 16#include <linux/screen_info.h>
28#include <linux/bootmem.h> 17#include <linux/bootmem.h>
29#include <linux/initrd.h> 18#include <linux/initrd.h>
30#include <linux/major.h>
31#include <linux/kdev_t.h>
32#include <linux/root_dev.h> 19#include <linux/root_dev.h>
33#include <linux/highmem.h> 20#include <linux/highmem.h>
34#include <linux/console.h> 21#include <linux/console.h>
35#include <linux/mmzone.h>
36#include <linux/pfn.h> 22#include <linux/pfn.h>
37 23
38#include <asm/addrspace.h> 24#include <asm/addrspace.h>
@@ -96,6 +82,12 @@ void __init add_memory_region(phys_t start, phys_t size, long type)
96 int x = boot_mem_map.nr_map; 82 int x = boot_mem_map.nr_map;
97 struct boot_mem_map_entry *prev = boot_mem_map.map + x - 1; 83 struct boot_mem_map_entry *prev = boot_mem_map.map + x - 1;
98 84
85 /* Sanity check */
86 if (start + size < start) {
87 printk("Trying to add an invalid memory region, skipped\n");
88 return;
89 }
90
99 /* 91 /*
100 * Try to merge with previous entry if any. This is far less than 92 * Try to merge with previous entry if any. This is far less than
101 * perfect but is sufficient for most real world cases. 93 * perfect but is sufficient for most real world cases.
@@ -143,167 +135,132 @@ static void __init print_memory_map(void)
143 } 135 }
144} 136}
145 137
146static inline void parse_cmdline_early(void) 138/*
139 * Manage initrd
140 */
141#ifdef CONFIG_BLK_DEV_INITRD
142
143static int __init rd_start_early(char *p)
147{ 144{
148 char c = ' ', *to = command_line, *from = saved_command_line; 145 unsigned long start = memparse(p, &p);
149 unsigned long start_at, mem_size;
150 int len = 0;
151 int usermem = 0;
152 146
153 printk("Determined physical RAM map:\n"); 147#ifdef CONFIG_64BIT
154 print_memory_map(); 148 /* HACK: Guess if the sign extension was forgotten */
149 if (start > 0x0000000080000000 && start < 0x00000000ffffffff)
150 start |= 0xffffffff00000000UL;
151#endif
152 initrd_start = start;
153 initrd_end += start;
155 154
156 for (;;) { 155 return 0;
157 /* 156}
158 * "mem=XXX[kKmM]" defines a memory region from 157early_param("rd_start", rd_start_early);
159 * 0 to <XXX>, overriding the determined size.
160 * "mem=XXX[KkmM]@YYY[KkmM]" defines a memory region from
161 * <YYY> to <YYY>+<XXX>, overriding the determined size.
162 */
163 if (c == ' ' && !memcmp(from, "mem=", 4)) {
164 if (to != command_line)
165 to--;
166 /*
167 * If a user specifies memory size, we
168 * blow away any automatically generated
169 * size.
170 */
171 if (usermem == 0) {
172 boot_mem_map.nr_map = 0;
173 usermem = 1;
174 }
175 mem_size = memparse(from + 4, &from);
176 if (*from == '@')
177 start_at = memparse(from + 1, &from);
178 else
179 start_at = 0;
180 add_memory_region(start_at, mem_size, BOOT_MEM_RAM);
181 }
182 c = *(from++);
183 if (!c)
184 break;
185 if (CL_SIZE <= ++len)
186 break;
187 *(to++) = c;
188 }
189 *to = '\0';
190 158
191 if (usermem) { 159static int __init rd_size_early(char *p)
192 printk("User-defined physical RAM map:\n"); 160{
193 print_memory_map(); 161 initrd_end += memparse(p, &p);
194 } 162
163 return 0;
195} 164}
165early_param("rd_size", rd_size_early);
196 166
197static inline int parse_rd_cmdline(unsigned long* rd_start, unsigned long* rd_end) 167static unsigned long __init init_initrd(void)
198{ 168{
169 unsigned long tmp, end, size;
170 u32 *initrd_header;
171
172 ROOT_DEV = Root_RAM0;
173
199 /* 174 /*
200 * "rd_start=0xNNNNNNNN" defines the memory address of an initrd 175 * Board specific code or command line parser should have
201 * "rd_size=0xNN" it's size 176 * already set up initrd_start and initrd_end. In these cases
177 * perfom sanity checks and use them if all looks good.
202 */ 178 */
203 unsigned long start = 0; 179 size = initrd_end - initrd_start;
204 unsigned long size = 0; 180 if (initrd_end == 0 || size == 0) {
205 unsigned long end; 181 initrd_start = 0;
206 char cmd_line[CL_SIZE]; 182 initrd_end = 0;
207 char *start_str; 183 } else
208 char *size_str; 184 return initrd_end;
209 char *tmp; 185
210 186 end = (unsigned long)&_end;
211 strcpy(cmd_line, command_line); 187 tmp = PAGE_ALIGN(end) - sizeof(u32) * 2;
212 *command_line = 0; 188 if (tmp < end)
213 tmp = cmd_line; 189 tmp += PAGE_SIZE;
214 /* Ignore "rd_start=" strings in other parameters. */ 190
215 start_str = strstr(cmd_line, "rd_start="); 191 initrd_header = (u32 *)tmp;
216 if (start_str && start_str != cmd_line && *(start_str - 1) != ' ') 192 if (initrd_header[0] == 0x494E5244) {
217 start_str = strstr(start_str, " rd_start="); 193 initrd_start = (unsigned long)&initrd_header[2];
218 while (start_str) { 194 initrd_end = initrd_start + initrd_header[1];
219 if (start_str != cmd_line)
220 strncat(command_line, tmp, start_str - tmp);
221 start = memparse(start_str + 9, &start_str);
222 tmp = start_str + 1;
223 start_str = strstr(start_str, " rd_start=");
224 } 195 }
225 if (*tmp) 196 return initrd_end;
226 strcat(command_line, tmp); 197}
227 198
228 strcpy(cmd_line, command_line); 199static void __init finalize_initrd(void)
229 *command_line = 0; 200{
230 tmp = cmd_line; 201 unsigned long size = initrd_end - initrd_start;
231 /* Ignore "rd_size" strings in other parameters. */ 202
232 size_str = strstr(cmd_line, "rd_size="); 203 if (size == 0) {
233 if (size_str && size_str != cmd_line && *(size_str - 1) != ' ') 204 printk(KERN_INFO "Initrd not found or empty");
234 size_str = strstr(size_str, " rd_size="); 205 goto disable;
235 while (size_str) { 206 }
236 if (size_str != cmd_line) 207 if (CPHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) {
237 strncat(command_line, tmp, size_str - tmp); 208 printk("Initrd extends beyond end of memory");
238 size = memparse(size_str + 8, &size_str); 209 goto disable;
239 tmp = size_str + 1;
240 size_str = strstr(size_str, " rd_size=");
241 } 210 }
242 if (*tmp)
243 strcat(command_line, tmp);
244 211
245#ifdef CONFIG_64BIT 212 reserve_bootmem(CPHYSADDR(initrd_start), size);
246 /* HACK: Guess if the sign extension was forgotten */ 213 initrd_below_start_ok = 1;
247 if (start > 0x0000000080000000 && start < 0x00000000ffffffff) 214
248 start |= 0xffffffff00000000UL; 215 printk(KERN_INFO "Initial ramdisk at: 0x%lx (%lu bytes)\n",
216 initrd_start, size);
217 return;
218disable:
219 printk(" - disabling initrd\n");
220 initrd_start = 0;
221 initrd_end = 0;
222}
223
224#else /* !CONFIG_BLK_DEV_INITRD */
225
226#define init_initrd() 0
227#define finalize_initrd() do {} while (0)
228
249#endif 229#endif
250 230
251 end = start + size; 231/*
252 if (start && end) { 232 * Initialize the bootmem allocator. It also setup initrd related data
253 *rd_start = start; 233 * if needed.
254 *rd_end = end; 234 */
255 return 1; 235#ifdef CONFIG_SGI_IP27
256 } 236
257 return 0; 237static void __init bootmem_init(void)
238{
239 init_initrd();
240 finalize_initrd();
258} 241}
259 242
260#define MAXMEM HIGHMEM_START 243#else /* !CONFIG_SGI_IP27 */
261#define MAXMEM_PFN PFN_DOWN(MAXMEM)
262 244
263static inline void bootmem_init(void) 245static void __init bootmem_init(void)
264{ 246{
265 unsigned long start_pfn; 247 unsigned long reserved_end;
266 unsigned long reserved_end = (unsigned long)&_end; 248 unsigned long highest = 0;
267#ifndef CONFIG_SGI_IP27 249 unsigned long mapstart = -1UL;
268 unsigned long first_usable_pfn;
269 unsigned long bootmap_size; 250 unsigned long bootmap_size;
270 int i; 251 int i;
271#endif
272#ifdef CONFIG_BLK_DEV_INITRD
273 int initrd_reserve_bootmem = 0;
274
275 /* Board specific code should have set up initrd_start and initrd_end */
276 ROOT_DEV = Root_RAM0;
277 if (parse_rd_cmdline(&initrd_start, &initrd_end)) {
278 reserved_end = max(reserved_end, initrd_end);
279 initrd_reserve_bootmem = 1;
280 } else {
281 unsigned long tmp;
282 u32 *initrd_header;
283
284 tmp = ((reserved_end + PAGE_SIZE-1) & PAGE_MASK) - sizeof(u32) * 2;
285 if (tmp < reserved_end)
286 tmp += PAGE_SIZE;
287 initrd_header = (u32 *)tmp;
288 if (initrd_header[0] == 0x494E5244) {
289 initrd_start = (unsigned long)&initrd_header[2];
290 initrd_end = initrd_start + initrd_header[1];
291 reserved_end = max(reserved_end, initrd_end);
292 initrd_reserve_bootmem = 1;
293 }
294 }
295#endif /* CONFIG_BLK_DEV_INITRD */
296 252
297 /* 253 /*
298 * Partially used pages are not usable - thus 254 * Init any data related to initrd. It's a nop if INITRD is
299 * we are rounding upwards. 255 * not selected. Once that done we can determine the low bound
256 * of usable memory.
300 */ 257 */
301 start_pfn = PFN_UP(CPHYSADDR(reserved_end)); 258 reserved_end = init_initrd();
259 reserved_end = PFN_UP(CPHYSADDR(max(reserved_end, (unsigned long)&_end)));
302 260
303#ifndef CONFIG_SGI_IP27 261 /*
304 /* Find the highest page frame number we have available. */ 262 * Find the highest page frame number we have available.
305 max_pfn = 0; 263 */
306 first_usable_pfn = -1UL;
307 for (i = 0; i < boot_mem_map.nr_map; i++) { 264 for (i = 0; i < boot_mem_map.nr_map; i++) {
308 unsigned long start, end; 265 unsigned long start, end;
309 266
@@ -312,56 +269,38 @@ static inline void bootmem_init(void)
312 269
313 start = PFN_UP(boot_mem_map.map[i].addr); 270 start = PFN_UP(boot_mem_map.map[i].addr);
314 end = PFN_DOWN(boot_mem_map.map[i].addr 271 end = PFN_DOWN(boot_mem_map.map[i].addr
315 + boot_mem_map.map[i].size); 272 + boot_mem_map.map[i].size);
316 273
317 if (start >= end) 274 if (end > highest)
275 highest = end;
276 if (end <= reserved_end)
318 continue; 277 continue;
319 if (end > max_pfn) 278 if (start >= mapstart)
320 max_pfn = end; 279 continue;
321 if (start < first_usable_pfn) { 280 mapstart = max(reserved_end, start);
322 if (start > start_pfn) {
323 first_usable_pfn = start;
324 } else if (end > start_pfn) {
325 first_usable_pfn = start_pfn;
326 }
327 }
328 } 281 }
329 282
330 /* 283 /*
331 * Determine low and high memory ranges 284 * Determine low and high memory ranges
332 */ 285 */
333 max_low_pfn = max_pfn; 286 if (highest > PFN_DOWN(HIGHMEM_START)) {
334 if (max_low_pfn > MAXMEM_PFN) { 287#ifdef CONFIG_HIGHMEM
335 max_low_pfn = MAXMEM_PFN; 288 highstart_pfn = PFN_DOWN(HIGHMEM_START);
336#ifndef CONFIG_HIGHMEM 289 highend_pfn = highest;
337 /* Maximum memory usable is what is directly addressable */
338 printk(KERN_WARNING "Warning only %ldMB will be used.\n",
339 MAXMEM >> 20);
340 printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
341#endif 290#endif
291 highest = PFN_DOWN(HIGHMEM_START);
342 } 292 }
343 293
344#ifdef CONFIG_HIGHMEM
345 /* 294 /*
346 * Crude, we really should make a better attempt at detecting 295 * Initialize the boot-time allocator with low memory only.
347 * highstart_pfn
348 */ 296 */
349 highstart_pfn = highend_pfn = max_pfn; 297 bootmap_size = init_bootmem(mapstart, highest);
350 if (max_pfn > MAXMEM_PFN) {
351 highstart_pfn = MAXMEM_PFN;
352 printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
353 (highend_pfn - highstart_pfn) >> (20 - PAGE_SHIFT));
354 }
355#endif
356
357 /* Initialize the boot-time allocator with low memory only. */
358 bootmap_size = init_bootmem(first_usable_pfn, max_low_pfn);
359 298
360 /* 299 /*
361 * Register fully available low RAM pages with the bootmem allocator. 300 * Register fully available low RAM pages with the bootmem allocator.
362 */ 301 */
363 for (i = 0; i < boot_mem_map.nr_map; i++) { 302 for (i = 0; i < boot_mem_map.nr_map; i++) {
364 unsigned long curr_pfn, last_pfn, size; 303 unsigned long start, end, size;
365 304
366 /* 305 /*
367 * Reserve usable memory. 306 * Reserve usable memory.
@@ -369,85 +308,50 @@ static inline void bootmem_init(void)
369 if (boot_mem_map.map[i].type != BOOT_MEM_RAM) 308 if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
370 continue; 309 continue;
371 310
372 /* 311 start = PFN_UP(boot_mem_map.map[i].addr);
373 * We are rounding up the start address of usable memory: 312 end = PFN_DOWN(boot_mem_map.map[i].addr
374 */
375 curr_pfn = PFN_UP(boot_mem_map.map[i].addr);
376 if (curr_pfn >= max_low_pfn)
377 continue;
378 if (curr_pfn < start_pfn)
379 curr_pfn = start_pfn;
380
381 /*
382 * ... and at the end of the usable range downwards:
383 */
384 last_pfn = PFN_DOWN(boot_mem_map.map[i].addr
385 + boot_mem_map.map[i].size); 313 + boot_mem_map.map[i].size);
386
387 if (last_pfn > max_low_pfn)
388 last_pfn = max_low_pfn;
389
390 /* 314 /*
391 * Only register lowmem part of lowmem segment with bootmem. 315 * We are rounding up the start address of usable memory
316 * and at the end of the usable range downwards.
392 */ 317 */
393 size = last_pfn - curr_pfn; 318 if (start >= max_low_pfn)
394 if (curr_pfn > PFN_DOWN(HIGHMEM_START))
395 continue;
396 if (curr_pfn + size - 1 > PFN_DOWN(HIGHMEM_START))
397 size = PFN_DOWN(HIGHMEM_START) - curr_pfn;
398 if (!size)
399 continue; 319 continue;
320 if (start < reserved_end)
321 start = reserved_end;
322 if (end > max_low_pfn)
323 end = max_low_pfn;
400 324
401 /* 325 /*
402 * ... finally, did all the rounding and playing 326 * ... finally, is the area going away?
403 * around just make the area go away?
404 */ 327 */
405 if (last_pfn <= curr_pfn) 328 if (end <= start)
406 continue; 329 continue;
330 size = end - start;
407 331
408 /* Register lowmem ranges */ 332 /* Register lowmem ranges */
409 free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); 333 free_bootmem(PFN_PHYS(start), size << PAGE_SHIFT);
410 memory_present(0, curr_pfn, curr_pfn + size - 1); 334 memory_present(0, start, end);
411 } 335 }
412 336
413 /* Reserve the bootmap memory. */ 337 /*
414 reserve_bootmem(PFN_PHYS(first_usable_pfn), bootmap_size); 338 * Reserve the bootmap memory.
415#endif /* CONFIG_SGI_IP27 */ 339 */
416 340 reserve_bootmem(PFN_PHYS(mapstart), bootmap_size);
417#ifdef CONFIG_BLK_DEV_INITRD
418 initrd_below_start_ok = 1;
419 if (initrd_start) {
420 unsigned long initrd_size = ((unsigned char *)initrd_end) -
421 ((unsigned char *)initrd_start);
422 const int width = sizeof(long) * 2;
423
424 printk("Initial ramdisk at: 0x%p (%lu bytes)\n",
425 (void *)initrd_start, initrd_size);
426
427 if (CPHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) {
428 printk("initrd extends beyond end of memory "
429 "(0x%0*Lx > 0x%0*Lx)\ndisabling initrd\n",
430 width,
431 (unsigned long long) CPHYSADDR(initrd_end),
432 width,
433 (unsigned long long) PFN_PHYS(max_low_pfn));
434 initrd_start = initrd_end = 0;
435 initrd_reserve_bootmem = 0;
436 }
437 341
438 if (initrd_reserve_bootmem) 342 /*
439 reserve_bootmem(CPHYSADDR(initrd_start), initrd_size); 343 * Reserve initrd memory if needed.
440 } 344 */
441#endif /* CONFIG_BLK_DEV_INITRD */ 345 finalize_initrd();
442} 346}
443 347
348#endif /* CONFIG_SGI_IP27 */
349
444/* 350/*
445 * arch_mem_init - initialize memory managment subsystem 351 * arch_mem_init - initialize memory managment subsystem
446 * 352 *
447 * o plat_mem_setup() detects the memory configuration and will record detected 353 * o plat_mem_setup() detects the memory configuration and will record detected
448 * memory areas using add_memory_region. 354 * memory areas using add_memory_region.
449 * o parse_cmdline_early() parses the command line for mem= options which,
450 * iff detected, will override the results of the automatic detection.
451 * 355 *
452 * At this stage the memory configuration of the system is known to the 356 * At this stage the memory configuration of the system is known to the
453 * kernel but generic memory managment system is still entirely uninitialized. 357 * kernel but generic memory managment system is still entirely uninitialized.
@@ -465,25 +369,59 @@ static inline void bootmem_init(void)
465 * initialization hook for anything else was introduced. 369 * initialization hook for anything else was introduced.
466 */ 370 */
467 371
468extern void plat_mem_setup(void); 372static int usermem __initdata = 0;
373
374static int __init early_parse_mem(char *p)
375{
376 unsigned long start, size;
377
378 /*
379 * If a user specifies memory size, we
380 * blow away any automatically generated
381 * size.
382 */
383 if (usermem == 0) {
384 boot_mem_map.nr_map = 0;
385 usermem = 1;
386 }
387 start = 0;
388 size = memparse(p, &p);
389 if (*p == '@')
390 start = memparse(p + 1, &p);
391
392 add_memory_region(start, size, BOOT_MEM_RAM);
393 return 0;
394}
395early_param("mem", early_parse_mem);
469 396
470static void __init arch_mem_init(char **cmdline_p) 397static void __init arch_mem_init(char **cmdline_p)
471{ 398{
399 extern void plat_mem_setup(void);
400
472 /* call board setup routine */ 401 /* call board setup routine */
473 plat_mem_setup(); 402 plat_mem_setup();
474 403
404 printk("Determined physical RAM map:\n");
405 print_memory_map();
406
475 strlcpy(command_line, arcs_cmdline, sizeof(command_line)); 407 strlcpy(command_line, arcs_cmdline, sizeof(command_line));
476 strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); 408 strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
477 409
478 *cmdline_p = command_line; 410 *cmdline_p = command_line;
479 411
480 parse_cmdline_early(); 412 parse_early_param();
413
414 if (usermem) {
415 printk("User-defined physical RAM map:\n");
416 print_memory_map();
417 }
418
481 bootmem_init(); 419 bootmem_init();
482 sparse_init(); 420 sparse_init();
483 paging_init(); 421 paging_init();
484} 422}
485 423
486static inline void resource_init(void) 424static void __init resource_init(void)
487{ 425{
488 int i; 426 int i;
489 427
@@ -504,10 +442,10 @@ static inline void resource_init(void)
504 442
505 start = boot_mem_map.map[i].addr; 443 start = boot_mem_map.map[i].addr;
506 end = boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1; 444 end = boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1;
507 if (start >= MAXMEM) 445 if (start >= HIGHMEM_START)
508 continue; 446 continue;
509 if (end >= MAXMEM) 447 if (end >= HIGHMEM_START)
510 end = MAXMEM - 1; 448 end = HIGHMEM_START - 1;
511 449
512 res = alloc_bootmem(sizeof(struct resource)); 450 res = alloc_bootmem(sizeof(struct resource));
513 switch (boot_mem_map.map[i].type) { 451 switch (boot_mem_map.map[i].type) {
@@ -536,9 +474,6 @@ static inline void resource_init(void)
536 } 474 }
537} 475}
538 476
539#undef MAXMEM
540#undef MAXMEM_PFN
541
542void __init setup_arch(char **cmdline_p) 477void __init setup_arch(char **cmdline_p)
543{ 478{
544 cpu_probe(); 479 cpu_probe();
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 6b4d9be31615..b9d358e05214 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -424,15 +424,11 @@ void do_signal(struct pt_regs *regs)
424 if (!user_mode(regs)) 424 if (!user_mode(regs))
425 return; 425 return;
426 426
427 if (try_to_freeze())
428 goto no_signal;
429
430 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 427 if (test_thread_flag(TIF_RESTORE_SIGMASK))
431 oldset = &current->saved_sigmask; 428 oldset = &current->saved_sigmask;
432 else 429 else
433 oldset = &current->blocked; 430 oldset = &current->blocked;
434 431
435
436 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 432 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
437 if (signr > 0) { 433 if (signr > 0) {
438 /* Whee! Actually deliver the signal. */ 434 /* Whee! Actually deliver the signal. */
@@ -446,9 +442,10 @@ void do_signal(struct pt_regs *regs)
446 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 442 if (test_thread_flag(TIF_RESTORE_SIGMASK))
447 clear_thread_flag(TIF_RESTORE_SIGMASK); 443 clear_thread_flag(TIF_RESTORE_SIGMASK);
448 } 444 }
445
446 return;
449 } 447 }
450 448
451no_signal:
452 /* 449 /*
453 * Who's code doesn't conform to the restartable syscall convention 450 * Who's code doesn't conform to the restartable syscall convention
454 * dies here!!! The li instruction, a single machine instruction, 451 * dies here!!! The li instruction, a single machine instruction,
@@ -466,6 +463,7 @@ no_signal:
466 regs->regs[7] = regs->regs[26]; 463 regs->regs[7] = regs->regs[26];
467 regs->cp0_epc -= 4; 464 regs->cp0_epc -= 4;
468 } 465 }
466 regs->regs[0] = 0; /* Don't deal with this again. */
469 } 467 }
470 468
471 /* 469 /*
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index f32a22997c3d..c86a5ddff050 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -815,9 +815,6 @@ void do_signal32(struct pt_regs *regs)
815 if (!user_mode(regs)) 815 if (!user_mode(regs))
816 return; 816 return;
817 817
818 if (try_to_freeze())
819 goto no_signal;
820
821 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 818 if (test_thread_flag(TIF_RESTORE_SIGMASK))
822 oldset = &current->saved_sigmask; 819 oldset = &current->saved_sigmask;
823 else 820 else
@@ -836,9 +833,10 @@ void do_signal32(struct pt_regs *regs)
836 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 833 if (test_thread_flag(TIF_RESTORE_SIGMASK))
837 clear_thread_flag(TIF_RESTORE_SIGMASK); 834 clear_thread_flag(TIF_RESTORE_SIGMASK);
838 } 835 }
836
837 return;
839 } 838 }
840 839
841no_signal:
842 /* 840 /*
843 * Who's code doesn't conform to the restartable syscall convention 841 * Who's code doesn't conform to the restartable syscall convention
844 * dies here!!! The li instruction, a single machine instruction, 842 * dies here!!! The li instruction, a single machine instruction,
@@ -856,6 +854,7 @@ no_signal:
856 regs->regs[7] = regs->regs[26]; 854 regs->regs[7] = regs->regs[26];
857 regs->cp0_epc -= 4; 855 regs->cp0_epc -= 4;
858 } 856 }
857 regs->regs[0] = 0; /* Don't deal with this again. */
859 } 858 }
860 859
861 /* 860 /*
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index 93429a4d3012..766253c44f3f 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -203,7 +203,7 @@ void plat_smp_setup(void)
203 write_vpe_c0_config( read_c0_config()); 203 write_vpe_c0_config( read_c0_config());
204 204
205 /* make sure there are no software interrupts pending */ 205 /* make sure there are no software interrupts pending */
206 write_vpe_c0_cause(read_vpe_c0_cause() & ~(C_SW1|C_SW0)); 206 write_vpe_c0_cause(0);
207 207
208 /* Propagate Config7 */ 208 /* Propagate Config7 */
209 write_vpe_c0_config7(read_c0_config7()); 209 write_vpe_c0_config7(read_c0_config7());
diff --git a/arch/mips/kernel/smtc-asm.S b/arch/mips/kernel/smtc-asm.S
index 4cc3dea36612..76cb31d57482 100644
--- a/arch/mips/kernel/smtc-asm.S
+++ b/arch/mips/kernel/smtc-asm.S
@@ -8,7 +8,7 @@
8#include <asm/regdef.h> 8#include <asm/regdef.h>
9#include <asm/asmmacro.h> 9#include <asm/asmmacro.h>
10#include <asm/stackframe.h> 10#include <asm/stackframe.h>
11#include <asm/stackframe.h> 11#include <asm/irqflags.h>
12 12
13/* 13/*
14 * "Software Interrupt" linkage. 14 * "Software Interrupt" linkage.
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 0721314db657..9951240cc3fd 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -263,7 +263,7 @@ asmlinkage int sys_olduname(struct oldold_utsname __user * name)
263 return error; 263 return error;
264} 264}
265 265
266void sys_set_thread_area(unsigned long addr) 266asmlinkage int sys_set_thread_area(unsigned long addr)
267{ 267{
268 struct thread_info *ti = task_thread_info(current); 268 struct thread_info *ti = task_thread_info(current);
269 269
@@ -271,6 +271,8 @@ void sys_set_thread_area(unsigned long addr)
271 271
272 /* If some future MIPS implementation has this register in hardware, 272 /* If some future MIPS implementation has this register in hardware,
273 * we will need to update it here (and in context switches). */ 273 * we will need to update it here (and in context switches). */
274
275 return 0;
274} 276}
275 277
276asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3) 278asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3)
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 954a198494ef..e51d8fd9a152 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -20,6 +20,7 @@
20#include <linux/spinlock.h> 20#include <linux/spinlock.h>
21#include <linux/kallsyms.h> 21#include <linux/kallsyms.h>
22#include <linux/bootmem.h> 22#include <linux/bootmem.h>
23#include <linux/interrupt.h>
23 24
24#include <asm/bootinfo.h> 25#include <asm/bootinfo.h>
25#include <asm/branch.h> 26#include <asm/branch.h>
@@ -72,28 +73,68 @@ void (*board_nmi_handler_setup)(void);
72void (*board_ejtag_handler_setup)(void); 73void (*board_ejtag_handler_setup)(void);
73void (*board_bind_eic_interrupt)(int irq, int regset); 74void (*board_bind_eic_interrupt)(int irq, int regset);
74 75
75/* 76
76 * These constant is for searching for possible module text segments. 77static void show_raw_backtrace(unsigned long reg29)
77 * MODULE_RANGE is a guess of how much space is likely to be vmalloced. 78{
78 */ 79 unsigned long *sp = (unsigned long *)reg29;
79#define MODULE_RANGE (8*1024*1024) 80 unsigned long addr;
81
82 printk("Call Trace:");
83#ifdef CONFIG_KALLSYMS
84 printk("\n");
85#endif
86 while (!kstack_end(sp)) {
87 addr = *sp++;
88 if (__kernel_text_address(addr))
89 print_ip_sym(addr);
90 }
91 printk("\n");
92}
93
94#ifdef CONFIG_KALLSYMS
95static int raw_show_trace;
96static int __init set_raw_show_trace(char *str)
97{
98 raw_show_trace = 1;
99 return 1;
100}
101__setup("raw_show_trace", set_raw_show_trace);
102
103extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
104 unsigned long pc, unsigned long ra);
105
106static void show_backtrace(struct task_struct *task, struct pt_regs *regs)
107{
108 unsigned long sp = regs->regs[29];
109 unsigned long ra = regs->regs[31];
110 unsigned long pc = regs->cp0_epc;
111
112 if (raw_show_trace || !__kernel_text_address(pc)) {
113 show_raw_backtrace(sp);
114 return;
115 }
116 printk("Call Trace:\n");
117 do {
118 print_ip_sym(pc);
119 pc = unwind_stack(task, &sp, pc, ra);
120 ra = 0;
121 } while (pc);
122 printk("\n");
123}
124#else
125#define show_backtrace(task, r) show_raw_backtrace((r)->regs[29]);
126#endif
80 127
81/* 128/*
82 * This routine abuses get_user()/put_user() to reference pointers 129 * This routine abuses get_user()/put_user() to reference pointers
83 * with at least a bit of error checking ... 130 * with at least a bit of error checking ...
84 */ 131 */
85void show_stack(struct task_struct *task, unsigned long *sp) 132static void show_stacktrace(struct task_struct *task, struct pt_regs *regs)
86{ 133{
87 const int field = 2 * sizeof(unsigned long); 134 const int field = 2 * sizeof(unsigned long);
88 long stackdata; 135 long stackdata;
89 int i; 136 int i;
90 137 unsigned long *sp = (unsigned long *)regs->regs[29];
91 if (!sp) {
92 if (task && task != current)
93 sp = (unsigned long *) task->thread.reg29;
94 else
95 sp = (unsigned long *) &sp;
96 }
97 138
98 printk("Stack :"); 139 printk("Stack :");
99 i = 0; 140 i = 0;
@@ -114,32 +155,48 @@ void show_stack(struct task_struct *task, unsigned long *sp)
114 i++; 155 i++;
115 } 156 }
116 printk("\n"); 157 printk("\n");
158 show_backtrace(task, regs);
117} 159}
118 160
119void show_trace(struct task_struct *task, unsigned long *stack) 161static __always_inline void prepare_frametrace(struct pt_regs *regs)
120{ 162{
121 const int field = 2 * sizeof(unsigned long); 163 __asm__ __volatile__(
122 unsigned long addr; 164 ".set push\n\t"
123 165 ".set noat\n\t"
124 if (!stack) { 166#ifdef CONFIG_64BIT
125 if (task && task != current) 167 "1: dla $1, 1b\n\t"
126 stack = (unsigned long *) task->thread.reg29; 168 "sd $1, %0\n\t"
127 else 169 "sd $29, %1\n\t"
128 stack = (unsigned long *) &stack; 170 "sd $31, %2\n\t"
129 } 171#else
130 172 "1: la $1, 1b\n\t"
131 printk("Call Trace:"); 173 "sw $1, %0\n\t"
132#ifdef CONFIG_KALLSYMS 174 "sw $29, %1\n\t"
133 printk("\n"); 175 "sw $31, %2\n\t"
134#endif 176#endif
135 while (!kstack_end(stack)) { 177 ".set pop\n\t"
136 addr = *stack++; 178 : "=m" (regs->cp0_epc),
137 if (__kernel_text_address(addr)) { 179 "=m" (regs->regs[29]), "=m" (regs->regs[31])
138 printk(" [<%0*lx>] ", field, addr); 180 : : "memory");
139 print_symbol("%s\n", addr); 181}
182
183void show_stack(struct task_struct *task, unsigned long *sp)
184{
185 struct pt_regs regs;
186 if (sp) {
187 regs.regs[29] = (unsigned long)sp;
188 regs.regs[31] = 0;
189 regs.cp0_epc = 0;
190 } else {
191 if (task && task != current) {
192 regs.regs[29] = task->thread.reg29;
193 regs.regs[31] = 0;
194 regs.cp0_epc = task->thread.reg31;
195 } else {
196 prepare_frametrace(&regs);
140 } 197 }
141 } 198 }
142 printk("\n"); 199 show_stacktrace(task, &regs);
143} 200}
144 201
145/* 202/*
@@ -147,9 +204,15 @@ void show_trace(struct task_struct *task, unsigned long *stack)
147 */ 204 */
148void dump_stack(void) 205void dump_stack(void)
149{ 206{
150 unsigned long stack; 207 struct pt_regs regs;
151 208
152 show_trace(current, &stack); 209 /*
210 * Remove any garbage that may be in regs (specially func
211 * addresses) to avoid show_raw_backtrace() to report them
212 */
213 memset(&regs, 0, sizeof(regs));
214 prepare_frametrace(&regs);
215 show_backtrace(current, &regs);
153} 216}
154 217
155EXPORT_SYMBOL(dump_stack); 218EXPORT_SYMBOL(dump_stack);
@@ -268,8 +331,7 @@ void show_registers(struct pt_regs *regs)
268 print_modules(); 331 print_modules();
269 printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n", 332 printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n",
270 current->comm, current->pid, current_thread_info(), current); 333 current->comm, current->pid, current_thread_info(), current);
271 show_stack(current, (long *) regs->regs[29]); 334 show_stacktrace(current, regs);
272 show_trace(current, (long *) regs->regs[29]);
273 show_code((unsigned int *) regs->cp0_epc); 335 show_code((unsigned int *) regs->cp0_epc);
274 printk("\n"); 336 printk("\n");
275} 337}
@@ -292,6 +354,16 @@ NORET_TYPE void ATTRIB_NORET die(const char * str, struct pt_regs * regs)
292 printk("%s[#%d]:\n", str, ++die_counter); 354 printk("%s[#%d]:\n", str, ++die_counter);
293 show_registers(regs); 355 show_registers(regs);
294 spin_unlock_irq(&die_lock); 356 spin_unlock_irq(&die_lock);
357
358 if (in_interrupt())
359 panic("Fatal exception in interrupt");
360
361 if (panic_on_oops) {
362 printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
363 ssleep(5);
364 panic("Fatal exception");
365 }
366
295 do_exit(SIGSEGV); 367 do_exit(SIGSEGV);
296} 368}
297 369
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 9ee0ec2cd067..51ddd2166898 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -768,10 +768,16 @@ int vpe_run(struct vpe * v)
768 */ 768 */
769 write_tc_c0_tcbind((read_tc_c0_tcbind() & ~TCBIND_CURVPE) | v->minor); 769 write_tc_c0_tcbind((read_tc_c0_tcbind() & ~TCBIND_CURVPE) | v->minor);
770 770
771 write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~(VPECONF0_VPA));
772
773 back_to_back_c0_hazard();
774
771 /* Set up the XTC bit in vpeconf0 to point at our tc */ 775 /* Set up the XTC bit in vpeconf0 to point at our tc */
772 write_vpe_c0_vpeconf0( (read_vpe_c0_vpeconf0() & ~(VPECONF0_XTC)) 776 write_vpe_c0_vpeconf0( (read_vpe_c0_vpeconf0() & ~(VPECONF0_XTC))
773 | (t->index << VPECONF0_XTC_SHIFT)); 777 | (t->index << VPECONF0_XTC_SHIFT));
774 778
779 back_to_back_c0_hazard();
780
775 /* enable this VPE */ 781 /* enable this VPE */
776 write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA); 782 write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);
777 783
diff --git a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c
index fb25e0377f11..a020a3cb4f4b 100644
--- a/arch/mips/mips-boards/atlas/atlas_int.c
+++ b/arch/mips/mips-boards/atlas/atlas_int.c
@@ -1,6 +1,8 @@
1/* 1/*
2 * Carsten Langgaard, carstenl@mips.com 2 * Copyright (C) 1999, 2000, 2006 MIPS Technologies, Inc.
3 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. 3 * All rights reserved.
4 * Authors: Carsten Langgaard <carstenl@mips.com>
5 * Maciej W. Rozycki <macro@mips.com>
4 * 6 *
5 * ######################################################################## 7 * ########################################################################
6 * 8 *
@@ -25,17 +27,20 @@
25 */ 27 */
26#include <linux/compiler.h> 28#include <linux/compiler.h>
27#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/irq.h>
28#include <linux/sched.h> 31#include <linux/sched.h>
29#include <linux/slab.h> 32#include <linux/slab.h>
30#include <linux/interrupt.h> 33#include <linux/interrupt.h>
31#include <linux/kernel_stat.h> 34#include <linux/kernel_stat.h>
32 35
33#include <asm/irq.h> 36#include <asm/gdb-stub.h>
34#include <asm/io.h> 37#include <asm/io.h>
38#include <asm/irq_cpu.h>
39#include <asm/msc01_ic.h>
40
35#include <asm/mips-boards/atlas.h> 41#include <asm/mips-boards/atlas.h>
36#include <asm/mips-boards/atlasint.h> 42#include <asm/mips-boards/atlasint.h>
37#include <asm/gdb-stub.h> 43#include <asm/mips-boards/generic.h>
38
39 44
40static struct atlas_ictrl_regs *atlas_hw0_icregs; 45static struct atlas_ictrl_regs *atlas_hw0_icregs;
41 46
@@ -47,13 +52,13 @@ static struct atlas_ictrl_regs *atlas_hw0_icregs;
47 52
48void disable_atlas_irq(unsigned int irq_nr) 53void disable_atlas_irq(unsigned int irq_nr)
49{ 54{
50 atlas_hw0_icregs->intrsten = (1 << (irq_nr-ATLASINT_BASE)); 55 atlas_hw0_icregs->intrsten = 1 << (irq_nr - ATLAS_INT_BASE);
51 iob(); 56 iob();
52} 57}
53 58
54void enable_atlas_irq(unsigned int irq_nr) 59void enable_atlas_irq(unsigned int irq_nr)
55{ 60{
56 atlas_hw0_icregs->intseten = (1 << (irq_nr-ATLASINT_BASE)); 61 atlas_hw0_icregs->intseten = 1 << (irq_nr - ATLAS_INT_BASE);
57 iob(); 62 iob();
58} 63}
59 64
@@ -107,7 +112,7 @@ static inline void atlas_hw0_irqdispatch(struct pt_regs *regs)
107 if (unlikely(int_status == 0)) 112 if (unlikely(int_status == 0))
108 return; 113 return;
109 114
110 irq = ATLASINT_BASE + ls1bit32(int_status); 115 irq = ATLAS_INT_BASE + ls1bit32(int_status);
111 116
112 DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq); 117 DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq);
113 118
@@ -161,15 +166,14 @@ static inline unsigned int irq_ffs(unsigned int pending)
161} 166}
162 167
163/* 168/*
164 * IRQs on the Atlas board look basically (barring software IRQs which we 169 * IRQs on the Atlas board look basically like (all external interrupt
165 * don't use at all and all external interrupt sources are combined together 170 * sources are combined together on hardware interrupt 0 (MIPS IRQ 2)):
166 * on hardware interrupt 0 (MIPS IRQ 2)) like:
167 * 171 *
168 * MIPS IRQ Source 172 * MIPS IRQ Source
169 * -------- ------ 173 * -------- ------
170 * 0 Software (ignored) 174 * 0 Software 0 (reschedule IPI on MT)
171 * 1 Software (ignored) 175 * 1 Software 1 (remote call IPI on MT)
172 * 2 Combined hardware interrupt (hw0) 176 * 2 Combined Atlas hardware interrupt (hw0)
173 * 3 Hardware (ignored) 177 * 3 Hardware (ignored)
174 * 4 Hardware (ignored) 178 * 4 Hardware (ignored)
175 * 5 Hardware (ignored) 179 * 5 Hardware (ignored)
@@ -179,7 +183,7 @@ static inline unsigned int irq_ffs(unsigned int pending)
179 * We handle the IRQ according to _our_ priority which is: 183 * We handle the IRQ according to _our_ priority which is:
180 * 184 *
181 * Highest ---- R4k Timer 185 * Highest ---- R4k Timer
182 * Lowest ---- Combined hardware interrupt 186 * Lowest ---- Software 0
183 * 187 *
184 * then we just return, if multiple IRQs are pending then we will just take 188 * then we just return, if multiple IRQs are pending then we will just take
185 * another exception, big deal. 189 * another exception, big deal.
@@ -193,17 +197,19 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
193 197
194 if (irq == MIPSCPU_INT_ATLAS) 198 if (irq == MIPSCPU_INT_ATLAS)
195 atlas_hw0_irqdispatch(regs); 199 atlas_hw0_irqdispatch(regs);
196 else if (irq > 0) 200 else if (irq >= 0)
197 do_IRQ(MIPSCPU_INT_BASE + irq, regs); 201 do_IRQ(MIPSCPU_INT_BASE + irq, regs);
198 else 202 else
199 spurious_interrupt(regs); 203 spurious_interrupt(regs);
200} 204}
201 205
202void __init arch_init_irq(void) 206static inline void init_atlas_irqs (int base)
203{ 207{
204 int i; 208 int i;
205 209
206 atlas_hw0_icregs = (struct atlas_ictrl_regs *)ioremap (ATLAS_ICTRL_REGS_BASE, sizeof(struct atlas_ictrl_regs *)); 210 atlas_hw0_icregs = (struct atlas_ictrl_regs *)
211 ioremap(ATLAS_ICTRL_REGS_BASE,
212 sizeof(struct atlas_ictrl_regs *));
207 213
208 /* 214 /*
209 * Mask out all interrupt by writing "1" to all bit position in 215 * Mask out all interrupt by writing "1" to all bit position in
@@ -211,7 +217,7 @@ void __init arch_init_irq(void)
211 */ 217 */
212 atlas_hw0_icregs->intrsten = 0xffffffff; 218 atlas_hw0_icregs->intrsten = 0xffffffff;
213 219
214 for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) { 220 for (i = ATLAS_INT_BASE; i <= ATLAS_INT_END; i++) {
215 irq_desc[i].status = IRQ_DISABLED; 221 irq_desc[i].status = IRQ_DISABLED;
216 irq_desc[i].action = 0; 222 irq_desc[i].action = 0;
217 irq_desc[i].depth = 1; 223 irq_desc[i].depth = 1;
@@ -219,3 +225,62 @@ void __init arch_init_irq(void)
219 spin_lock_init(&irq_desc[i].lock); 225 spin_lock_init(&irq_desc[i].lock);
220 } 226 }
221} 227}
228
229static struct irqaction atlasirq = {
230 .handler = no_action,
231 .name = "Atlas cascade"
232};
233
234msc_irqmap_t __initdata msc_irqmap[] = {
235 {MSC01C_INT_TMR, MSC01_IRQ_EDGE, 0},
236 {MSC01C_INT_PCI, MSC01_IRQ_LEVEL, 0},
237};
238int __initdata msc_nr_irqs = sizeof(msc_irqmap) / sizeof(*msc_irqmap);
239
240msc_irqmap_t __initdata msc_eicirqmap[] = {
241 {MSC01E_INT_SW0, MSC01_IRQ_LEVEL, 0},
242 {MSC01E_INT_SW1, MSC01_IRQ_LEVEL, 0},
243 {MSC01E_INT_ATLAS, MSC01_IRQ_LEVEL, 0},
244 {MSC01E_INT_TMR, MSC01_IRQ_EDGE, 0},
245 {MSC01E_INT_PCI, MSC01_IRQ_LEVEL, 0},
246 {MSC01E_INT_PERFCTR, MSC01_IRQ_LEVEL, 0},
247 {MSC01E_INT_CPUCTR, MSC01_IRQ_LEVEL, 0}
248};
249int __initdata msc_nr_eicirqs = sizeof(msc_eicirqmap) / sizeof(*msc_eicirqmap);
250
251void __init arch_init_irq(void)
252{
253 init_atlas_irqs(ATLAS_INT_BASE);
254
255 if (!cpu_has_veic)
256 mips_cpu_irq_init(MIPSCPU_INT_BASE);
257
258 switch(mips_revision_corid) {
259 case MIPS_REVISION_CORID_CORE_MSC:
260 case MIPS_REVISION_CORID_CORE_FPGA2:
261 case MIPS_REVISION_CORID_CORE_FPGA3:
262 case MIPS_REVISION_CORID_CORE_24K:
263 case MIPS_REVISION_CORID_CORE_EMUL_MSC:
264 if (cpu_has_veic)
265 init_msc_irqs (MSC01E_INT_BASE,
266 msc_eicirqmap, msc_nr_eicirqs);
267 else
268 init_msc_irqs (MSC01C_INT_BASE,
269 msc_irqmap, msc_nr_irqs);
270 }
271
272
273 if (cpu_has_veic) {
274 set_vi_handler (MSC01E_INT_ATLAS, atlas_hw0_irqdispatch);
275 setup_irq (MSC01E_INT_BASE + MSC01E_INT_ATLAS, &atlasirq);
276 } else if (cpu_has_vint) {
277 set_vi_handler (MIPSCPU_INT_ATLAS, atlas_hw0_irqdispatch);
278#ifdef CONFIG_MIPS_MT_SMTC
279 setup_irq_smtc (MIPSCPU_INT_BASE + MIPSCPU_INT_ATLAS,
280 &atlasirq, (0x100 << MIPSCPU_INT_ATLAS));
281#else /* Not SMTC */
282 setup_irq(MIPSCPU_INT_BASE + MIPSCPU_INT_ATLAS, &atlasirq);
283#endif /* CONFIG_MIPS_MT_SMTC */
284 } else
285 setup_irq(MIPSCPU_INT_BASE + MIPSCPU_INT_ATLAS, &atlasirq);
286}
diff --git a/arch/mips/mips-boards/atlas/atlas_setup.c b/arch/mips/mips-boards/atlas/atlas_setup.c
index 9871a91fdb07..0c6b0ce15028 100644
--- a/arch/mips/mips-boards/atlas/atlas_setup.c
+++ b/arch/mips/mips-boards/atlas/atlas_setup.c
@@ -77,7 +77,7 @@ static void __init serial_init(void)
77#else 77#else
78 s.iobase = ATLAS_UART_REGS_BASE+3; 78 s.iobase = ATLAS_UART_REGS_BASE+3;
79#endif 79#endif
80 s.irq = ATLASINT_UART; 80 s.irq = ATLAS_INT_UART;
81 s.uartclk = ATLAS_BASE_BAUD * 16; 81 s.uartclk = ATLAS_BASE_BAUD * 16;
82 s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ; 82 s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ;
83 s.iotype = UPIO_PORT; 83 s.iotype = UPIO_PORT;
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c
index 557bf961f36a..8d15861fce61 100644
--- a/arch/mips/mips-boards/generic/time.c
+++ b/arch/mips/mips-boards/generic/time.c
@@ -41,8 +41,13 @@
41 41
42#include <asm/mips-boards/generic.h> 42#include <asm/mips-boards/generic.h>
43#include <asm/mips-boards/prom.h> 43#include <asm/mips-boards/prom.h>
44
45#ifdef CONFIG_MIPS_ATLAS
46#include <asm/mips-boards/atlasint.h>
47#endif
48#ifdef CONFIG_MIPS_MALTA
44#include <asm/mips-boards/maltaint.h> 49#include <asm/mips-boards/maltaint.h>
45#include <asm/mc146818-time.h> 50#endif
46 51
47unsigned long cpu_khz; 52unsigned long cpu_khz;
48 53
@@ -92,10 +97,9 @@ extern int (*perf_irq)(struct pt_regs *regs);
92irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) 97irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
93{ 98{
94 int cpu = smp_processor_id(); 99 int cpu = smp_processor_id();
95 int r2 = cpu_has_mips_r2;
96 100
97#ifdef CONFIG_MIPS_MT_SMTC 101#ifdef CONFIG_MIPS_MT_SMTC
98 /* 102 /*
99 * In an SMTC system, one Count/Compare set exists per VPE. 103 * In an SMTC system, one Count/Compare set exists per VPE.
100 * Which TC within a VPE gets the interrupt is essentially 104 * Which TC within a VPE gets the interrupt is essentially
101 * random - we only know that it shouldn't be one with 105 * random - we only know that it shouldn't be one with
@@ -108,29 +112,46 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
108 * the general MIPS timer_interrupt routine. 112 * the general MIPS timer_interrupt routine.
109 */ 113 */
110 114
115 int vpflags;
116
111 /* 117 /*
112 * DVPE is necessary so long as cross-VPE interrupts 118 * We could be here due to timer interrupt,
113 * are done via read-modify-write of Cause register. 119 * perf counter overflow, or both.
114 */ 120 */
115 int vpflags = dvpe(); 121 if (read_c0_cause() & (1 << 26))
116 write_c0_compare (read_c0_count() - 1); 122 perf_irq(regs);
117 clear_c0_cause(CPUCTR_IMASKBIT);
118 evpe(vpflags);
119 123
120 if (cpu_data[cpu].vpe_id == 0) { 124 if (read_c0_cause() & (1 << 30)) {
121 timer_interrupt(irq, dev_id, regs); 125 /* If timer interrupt, make it de-assert */
122 scroll_display_message(); 126 write_c0_compare (read_c0_count() - 1);
123 } else
124 write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ));
125 smtc_timer_broadcast(cpu_data[cpu].vpe_id);
126
127 if (cpu != 0)
128 /* 127 /*
129 * Other CPUs should do profiling and process accounting 128 * DVPE is necessary so long as cross-VPE interrupts
129 * are done via read-modify-write of Cause register.
130 */ 130 */
131 local_timer_interrupt(irq, dev_id, regs); 131 vpflags = dvpe();
132 132 clear_c0_cause(CPUCTR_IMASKBIT);
133 evpe(vpflags);
134 /*
135 * There are things we only want to do once per tick
136 * in an "MP" system. One TC of each VPE will take
137 * the actual timer interrupt. The others will get
138 * timer broadcast IPIs. We use whoever it is that takes
139 * the tick on VPE 0 to run the full timer_interrupt().
140 */
141 if (cpu_data[cpu].vpe_id == 0) {
142 timer_interrupt(irq, NULL, regs);
143 smtc_timer_broadcast(cpu_data[cpu].vpe_id);
144 scroll_display_message();
145 } else {
146 write_c0_compare(read_c0_count() +
147 (mips_hpt_frequency/HZ));
148 local_timer_interrupt(irq, dev_id, regs);
149 smtc_timer_broadcast(cpu_data[cpu].vpe_id);
150 }
151 }
133#else /* CONFIG_MIPS_MT_SMTC */ 152#else /* CONFIG_MIPS_MT_SMTC */
153 int r2 = cpu_has_mips_r2;
154
134 if (cpu == 0) { 155 if (cpu == 0) {
135 /* 156 /*
136 * CPU 0 handles the global timer interrupt job and process 157 * CPU 0 handles the global timer interrupt job and process
@@ -161,9 +182,8 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
161 */ 182 */
162 local_timer_interrupt(irq, dev_id, regs); 183 local_timer_interrupt(irq, dev_id, regs);
163 } 184 }
164#endif /* CONFIG_MIPS_MT_SMTC */
165
166out: 185out:
186#endif /* CONFIG_MIPS_MT_SMTC */
167 return IRQ_HANDLED; 187 return IRQ_HANDLED;
168} 188}
169 189
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c
index bb041a22f20a..e1f35ef81145 100644
--- a/arch/mips/mm/c-r3k.c
+++ b/arch/mips/mm/c-r3k.c
@@ -335,7 +335,7 @@ void __init r3k_cache_init(void)
335 flush_cache_mm = r3k_flush_cache_mm; 335 flush_cache_mm = r3k_flush_cache_mm;
336 flush_cache_range = r3k_flush_cache_range; 336 flush_cache_range = r3k_flush_cache_range;
337 flush_cache_page = r3k_flush_cache_page; 337 flush_cache_page = r3k_flush_cache_page;
338 flush_icache_page = r3k_flush_icache_page; 338 __flush_icache_page = r3k_flush_icache_page;
339 flush_icache_range = r3k_flush_icache_range; 339 flush_icache_range = r3k_flush_icache_range;
340 340
341 flush_cache_sigtramp = r3k_flush_cache_sigtramp; 341 flush_cache_sigtramp = r3k_flush_cache_sigtramp;
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 069803f58f3b..0b2da53750bd 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -89,7 +89,7 @@ static inline void r4k_blast_dcache_page_dc32(unsigned long addr)
89 blast_dcache32_page(addr); 89 blast_dcache32_page(addr);
90} 90}
91 91
92static inline void r4k_blast_dcache_page_setup(void) 92static void __init r4k_blast_dcache_page_setup(void)
93{ 93{
94 unsigned long dc_lsize = cpu_dcache_line_size(); 94 unsigned long dc_lsize = cpu_dcache_line_size();
95 95
@@ -103,7 +103,7 @@ static inline void r4k_blast_dcache_page_setup(void)
103 103
104static void (* r4k_blast_dcache_page_indexed)(unsigned long addr); 104static void (* r4k_blast_dcache_page_indexed)(unsigned long addr);
105 105
106static inline void r4k_blast_dcache_page_indexed_setup(void) 106static void __init r4k_blast_dcache_page_indexed_setup(void)
107{ 107{
108 unsigned long dc_lsize = cpu_dcache_line_size(); 108 unsigned long dc_lsize = cpu_dcache_line_size();
109 109
@@ -117,7 +117,7 @@ static inline void r4k_blast_dcache_page_indexed_setup(void)
117 117
118static void (* r4k_blast_dcache)(void); 118static void (* r4k_blast_dcache)(void);
119 119
120static inline void r4k_blast_dcache_setup(void) 120static void __init r4k_blast_dcache_setup(void)
121{ 121{
122 unsigned long dc_lsize = cpu_dcache_line_size(); 122 unsigned long dc_lsize = cpu_dcache_line_size();
123 123
@@ -202,7 +202,7 @@ static inline void tx49_blast_icache32_page_indexed(unsigned long page)
202 202
203static void (* r4k_blast_icache_page)(unsigned long addr); 203static void (* r4k_blast_icache_page)(unsigned long addr);
204 204
205static inline void r4k_blast_icache_page_setup(void) 205static void __init r4k_blast_icache_page_setup(void)
206{ 206{
207 unsigned long ic_lsize = cpu_icache_line_size(); 207 unsigned long ic_lsize = cpu_icache_line_size();
208 208
@@ -219,7 +219,7 @@ static inline void r4k_blast_icache_page_setup(void)
219 219
220static void (* r4k_blast_icache_page_indexed)(unsigned long addr); 220static void (* r4k_blast_icache_page_indexed)(unsigned long addr);
221 221
222static inline void r4k_blast_icache_page_indexed_setup(void) 222static void __init r4k_blast_icache_page_indexed_setup(void)
223{ 223{
224 unsigned long ic_lsize = cpu_icache_line_size(); 224 unsigned long ic_lsize = cpu_icache_line_size();
225 225
@@ -243,7 +243,7 @@ static inline void r4k_blast_icache_page_indexed_setup(void)
243 243
244static void (* r4k_blast_icache)(void); 244static void (* r4k_blast_icache)(void);
245 245
246static inline void r4k_blast_icache_setup(void) 246static void __init r4k_blast_icache_setup(void)
247{ 247{
248 unsigned long ic_lsize = cpu_icache_line_size(); 248 unsigned long ic_lsize = cpu_icache_line_size();
249 249
@@ -264,7 +264,7 @@ static inline void r4k_blast_icache_setup(void)
264 264
265static void (* r4k_blast_scache_page)(unsigned long addr); 265static void (* r4k_blast_scache_page)(unsigned long addr);
266 266
267static inline void r4k_blast_scache_page_setup(void) 267static void __init r4k_blast_scache_page_setup(void)
268{ 268{
269 unsigned long sc_lsize = cpu_scache_line_size(); 269 unsigned long sc_lsize = cpu_scache_line_size();
270 270
@@ -282,7 +282,7 @@ static inline void r4k_blast_scache_page_setup(void)
282 282
283static void (* r4k_blast_scache_page_indexed)(unsigned long addr); 283static void (* r4k_blast_scache_page_indexed)(unsigned long addr);
284 284
285static inline void r4k_blast_scache_page_indexed_setup(void) 285static void __init r4k_blast_scache_page_indexed_setup(void)
286{ 286{
287 unsigned long sc_lsize = cpu_scache_line_size(); 287 unsigned long sc_lsize = cpu_scache_line_size();
288 288
@@ -300,7 +300,7 @@ static inline void r4k_blast_scache_page_indexed_setup(void)
300 300
301static void (* r4k_blast_scache)(void); 301static void (* r4k_blast_scache)(void);
302 302
303static inline void r4k_blast_scache_setup(void) 303static void __init r4k_blast_scache_setup(void)
304{ 304{
305 unsigned long sc_lsize = cpu_scache_line_size(); 305 unsigned long sc_lsize = cpu_scache_line_size();
306 306
@@ -475,7 +475,7 @@ static inline void local_r4k_flush_cache_page(void *args)
475 } 475 }
476 } 476 }
477 if (exec) { 477 if (exec) {
478 if (cpu_has_vtag_icache) { 478 if (cpu_has_vtag_icache && mm == current->active_mm) {
479 int cpu = smp_processor_id(); 479 int cpu = smp_processor_id();
480 480
481 if (cpu_context(cpu, mm) != 0) 481 if (cpu_context(cpu, mm) != 0)
@@ -599,7 +599,7 @@ static inline void local_r4k_flush_icache_page(void *args)
599 * We're not sure of the virtual address(es) involved here, so 599 * We're not sure of the virtual address(es) involved here, so
600 * we have to flush the entire I-cache. 600 * we have to flush the entire I-cache.
601 */ 601 */
602 if (cpu_has_vtag_icache) { 602 if (cpu_has_vtag_icache && vma->vm_mm == current->active_mm) {
603 int cpu = smp_processor_id(); 603 int cpu = smp_processor_id();
604 604
605 if (cpu_context(cpu, vma->vm_mm) != 0) 605 if (cpu_context(cpu, vma->vm_mm) != 0)
@@ -1221,7 +1221,7 @@ void au1x00_fixup_config_od(void)
1221 } 1221 }
1222} 1222}
1223 1223
1224static inline void coherency_setup(void) 1224static void __init coherency_setup(void)
1225{ 1225{
1226 change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); 1226 change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
1227 1227
@@ -1242,7 +1242,7 @@ static inline void coherency_setup(void)
1242 clear_c0_config(CONF_CU); 1242 clear_c0_config(CONF_CU);
1243 break; 1243 break;
1244 /* 1244 /*
1245 * We need to catch the ealry Alchemy SOCs with 1245 * We need to catch the early Alchemy SOCs with
1246 * the write-only co_config.od bit and set it back to one... 1246 * the write-only co_config.od bit and set it back to one...
1247 */ 1247 */
1248 case CPU_AU1000: /* rev. DA, HA, HB */ 1248 case CPU_AU1000: /* rev. DA, HA, HB */
@@ -1291,7 +1291,7 @@ void __init r4k_cache_init(void)
1291 __flush_cache_all = r4k___flush_cache_all; 1291 __flush_cache_all = r4k___flush_cache_all;
1292 flush_cache_mm = r4k_flush_cache_mm; 1292 flush_cache_mm = r4k_flush_cache_mm;
1293 flush_cache_page = r4k_flush_cache_page; 1293 flush_cache_page = r4k_flush_cache_page;
1294 flush_icache_page = r4k_flush_icache_page; 1294 __flush_icache_page = r4k_flush_icache_page;
1295 flush_cache_range = r4k_flush_cache_range; 1295 flush_cache_range = r4k_flush_cache_range;
1296 1296
1297 flush_cache_sigtramp = r4k_flush_cache_sigtramp; 1297 flush_cache_sigtramp = r4k_flush_cache_sigtramp;
diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c
index 2d71efb82ac5..16bad7c0a63f 100644
--- a/arch/mips/mm/c-sb1.c
+++ b/arch/mips/mm/c-sb1.c
@@ -155,6 +155,26 @@ static inline void __sb1_flush_icache_all(void)
155} 155}
156 156
157/* 157/*
158 * Invalidate a range of the icache. The addresses are virtual, and
159 * the cache is virtually indexed and tagged. However, we don't
160 * necessarily have the right ASID context, so use index ops instead
161 * of hit ops.
162 */
163static inline void __sb1_flush_icache_range(unsigned long start,
164 unsigned long end)
165{
166 start &= ~(icache_line_size - 1);
167 end = (end + icache_line_size - 1) & ~(icache_line_size - 1);
168
169 while (start != end) {
170 cache_set_op(Index_Invalidate_I, start & icache_index_mask);
171 start += icache_line_size;
172 }
173 mispredict();
174 sync();
175}
176
177/*
158 * Flush the icache for a given physical page. Need to writeback the 178 * Flush the icache for a given physical page. Need to writeback the
159 * dcache first, then invalidate the icache. If the page isn't 179 * dcache first, then invalidate the icache. If the page isn't
160 * executable, nothing is required. 180 * executable, nothing is required.
@@ -173,8 +193,11 @@ static void local_sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long
173 /* 193 /*
174 * Bumping the ASID is probably cheaper than the flush ... 194 * Bumping the ASID is probably cheaper than the flush ...
175 */ 195 */
176 if (cpu_context(cpu, vma->vm_mm) != 0) 196 if (vma->vm_mm == current->active_mm) {
177 drop_mmu_context(vma->vm_mm, cpu); 197 if (cpu_context(cpu, vma->vm_mm) != 0)
198 drop_mmu_context(vma->vm_mm, cpu);
199 } else
200 __sb1_flush_icache_range(addr, addr + PAGE_SIZE);
178} 201}
179 202
180#ifdef CONFIG_SMP 203#ifdef CONFIG_SMP
@@ -210,26 +233,6 @@ void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsign
210 __attribute__((alias("local_sb1_flush_cache_page"))); 233 __attribute__((alias("local_sb1_flush_cache_page")));
211#endif 234#endif
212 235
213/*
214 * Invalidate a range of the icache. The addresses are virtual, and
215 * the cache is virtually indexed and tagged. However, we don't
216 * necessarily have the right ASID context, so use index ops instead
217 * of hit ops.
218 */
219static inline void __sb1_flush_icache_range(unsigned long start,
220 unsigned long end)
221{
222 start &= ~(icache_line_size - 1);
223 end = (end + icache_line_size - 1) & ~(icache_line_size - 1);
224
225 while (start != end) {
226 cache_set_op(Index_Invalidate_I, start & icache_index_mask);
227 start += icache_line_size;
228 }
229 mispredict();
230 sync();
231}
232
233 236
234/* 237/*
235 * Invalidate all caches on this CPU 238 * Invalidate all caches on this CPU
@@ -326,9 +329,12 @@ static void local_sb1_flush_icache_page(struct vm_area_struct *vma,
326 * If there's a context, bump the ASID (cheaper than a flush, 329 * If there's a context, bump the ASID (cheaper than a flush,
327 * since we don't know VAs!) 330 * since we don't know VAs!)
328 */ 331 */
329 if (cpu_context(cpu, vma->vm_mm) != 0) { 332 if (vma->vm_mm == current->active_mm) {
330 drop_mmu_context(vma->vm_mm, cpu); 333 if (cpu_context(cpu, vma->vm_mm) != 0)
331 } 334 drop_mmu_context(vma->vm_mm, cpu);
335 } else
336 __sb1_flush_icache_range(start, start + PAGE_SIZE);
337
332} 338}
333 339
334#ifdef CONFIG_SMP 340#ifdef CONFIG_SMP
@@ -520,7 +526,7 @@ void sb1_cache_init(void)
520 526
521 /* These routines are for Icache coherence with the Dcache */ 527 /* These routines are for Icache coherence with the Dcache */
522 flush_icache_range = sb1_flush_icache_range; 528 flush_icache_range = sb1_flush_icache_range;
523 flush_icache_page = sb1_flush_icache_page; 529 __flush_icache_page = sb1_flush_icache_page;
524 flush_icache_all = __sb1_flush_icache_all; /* local only */ 530 flush_icache_all = __sb1_flush_icache_all; /* local only */
525 531
526 /* This implies an Icache flush too, so can't be nop'ed */ 532 /* This implies an Icache flush too, so can't be nop'ed */
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c
index 5dfc9b1901f6..932a09d7ef84 100644
--- a/arch/mips/mm/c-tx39.c
+++ b/arch/mips/mm/c-tx39.c
@@ -382,7 +382,7 @@ void __init tx39_cache_init(void)
382 flush_cache_mm = (void *) tx39h_flush_icache_all; 382 flush_cache_mm = (void *) tx39h_flush_icache_all;
383 flush_cache_range = (void *) tx39h_flush_icache_all; 383 flush_cache_range = (void *) tx39h_flush_icache_all;
384 flush_cache_page = (void *) tx39h_flush_icache_all; 384 flush_cache_page = (void *) tx39h_flush_icache_all;
385 flush_icache_page = (void *) tx39h_flush_icache_all; 385 __flush_icache_page = (void *) tx39h_flush_icache_all;
386 flush_icache_range = (void *) tx39h_flush_icache_all; 386 flush_icache_range = (void *) tx39h_flush_icache_all;
387 387
388 flush_cache_sigtramp = (void *) tx39h_flush_icache_all; 388 flush_cache_sigtramp = (void *) tx39h_flush_icache_all;
@@ -408,7 +408,7 @@ void __init tx39_cache_init(void)
408 flush_cache_mm = tx39_flush_cache_mm; 408 flush_cache_mm = tx39_flush_cache_mm;
409 flush_cache_range = tx39_flush_cache_range; 409 flush_cache_range = tx39_flush_cache_range;
410 flush_cache_page = tx39_flush_cache_page; 410 flush_cache_page = tx39_flush_cache_page;
411 flush_icache_page = tx39_flush_icache_page; 411 __flush_icache_page = tx39_flush_icache_page;
412 flush_icache_range = tx39_flush_icache_range; 412 flush_icache_range = tx39_flush_icache_range;
413 413
414 flush_cache_sigtramp = tx39_flush_cache_sigtramp; 414 flush_cache_sigtramp = tx39_flush_cache_sigtramp;
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index ddd3a2de1d73..40c8b0235183 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -25,7 +25,7 @@ void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start,
25void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, 25void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page,
26 unsigned long pfn); 26 unsigned long pfn);
27void (*flush_icache_range)(unsigned long start, unsigned long end); 27void (*flush_icache_range)(unsigned long start, unsigned long end);
28void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page); 28void (*__flush_icache_page)(struct vm_area_struct *vma, struct page *page);
29 29
30/* MIPS specific cache operations */ 30/* MIPS specific cache operations */
31void (*flush_cache_sigtramp)(unsigned long addr); 31void (*flush_cache_sigtramp)(unsigned long addr);
@@ -70,6 +70,8 @@ void __flush_dcache_page(struct page *page)
70 struct address_space *mapping = page_mapping(page); 70 struct address_space *mapping = page_mapping(page);
71 unsigned long addr; 71 unsigned long addr;
72 72
73 if (PageHighMem(page))
74 return;
73 if (mapping && !mapping_mapped(mapping)) { 75 if (mapping && !mapping_mapped(mapping)) {
74 SetPageDcacheDirty(page); 76 SetPageDcacheDirty(page);
75 return; 77 return;
@@ -91,16 +93,16 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address,
91{ 93{
92 struct page *page; 94 struct page *page;
93 unsigned long pfn, addr; 95 unsigned long pfn, addr;
96 int exec = (vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc;
94 97
95 pfn = pte_pfn(pte); 98 pfn = pte_pfn(pte);
96 if (pfn_valid(pfn) && (page = pfn_to_page(pfn), page_mapping(page)) && 99 if (unlikely(!pfn_valid(pfn)))
97 Page_dcache_dirty(page)) { 100 return;
98 if (pages_do_alias((unsigned long)page_address(page), 101 page = pfn_to_page(pfn);
99 address & PAGE_MASK)) { 102 if (page_mapping(page) && Page_dcache_dirty(page)) {
100 addr = (unsigned long) page_address(page); 103 addr = (unsigned long) page_address(page);
104 if (exec || pages_do_alias(addr, address & PAGE_MASK))
101 flush_data_cache_page(addr); 105 flush_data_cache_page(addr);
102 }
103
104 ClearPageDcacheDirty(page); 106 ClearPageDcacheDirty(page);
105 } 107 }
106} 108}
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index e3a617224868..a4f8c45c4e8e 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -89,7 +89,7 @@ good_area:
89 if (!(vma->vm_flags & VM_WRITE)) 89 if (!(vma->vm_flags & VM_WRITE))
90 goto bad_area; 90 goto bad_area;
91 } else { 91 } else {
92 if (!(vma->vm_flags & (VM_READ | VM_EXEC))) 92 if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)))
93 goto bad_area; 93 goto bad_area;
94 } 94 }
95 95
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index c52497bb102a..5b06349af2d5 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -163,10 +163,10 @@ static int __init page_is_ram(unsigned long pagenr)
163 163
164void __init paging_init(void) 164void __init paging_init(void)
165{ 165{
166 unsigned long zones_size[] = { [0 ... MAX_NR_ZONES - 1] = 0 }; 166 unsigned long zones_size[] = { 0, };
167 unsigned long max_dma, high, low; 167 unsigned long max_dma, high, low;
168#ifndef CONFIG_FLATMEM 168#ifndef CONFIG_FLATMEM
169 unsigned long zholes_size[] = { [0 ... MAX_NR_ZONES - 1] = 0 }; 169 unsigned long zholes_size[] = { 0, };
170 unsigned long i, j, pfn; 170 unsigned long i, j, pfn;
171#endif 171#endif
172 172
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 2cde1b772443..2e0e21ef433e 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -26,11 +26,6 @@ extern void build_tlb_refill_handler(void);
26 */ 26 */
27#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1))) 27#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
28 28
29/* CP0 hazard avoidance. */
30#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \
31 "nop; nop; nop; nop; nop; nop;\n\t" \
32 ".set reorder\n\t")
33
34/* Atomicity and interruptability */ 29/* Atomicity and interruptability */
35#ifdef CONFIG_MIPS_MT_SMTC 30#ifdef CONFIG_MIPS_MT_SMTC
36 31
@@ -126,7 +121,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
126 start += (PAGE_SIZE << 1); 121 start += (PAGE_SIZE << 1);
127 mtc0_tlbw_hazard(); 122 mtc0_tlbw_hazard();
128 tlb_probe(); 123 tlb_probe();
129 BARRIER; 124 tlb_probe_hazard();
130 idx = read_c0_index(); 125 idx = read_c0_index();
131 write_c0_entrylo0(0); 126 write_c0_entrylo0(0);
132 write_c0_entrylo1(0); 127 write_c0_entrylo1(0);
@@ -168,7 +163,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
168 start += (PAGE_SIZE << 1); 163 start += (PAGE_SIZE << 1);
169 mtc0_tlbw_hazard(); 164 mtc0_tlbw_hazard();
170 tlb_probe(); 165 tlb_probe();
171 BARRIER; 166 tlb_probe_hazard();
172 idx = read_c0_index(); 167 idx = read_c0_index();
173 write_c0_entrylo0(0); 168 write_c0_entrylo0(0);
174 write_c0_entrylo1(0); 169 write_c0_entrylo1(0);
@@ -202,7 +197,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
202 write_c0_entryhi(page | newpid); 197 write_c0_entryhi(page | newpid);
203 mtc0_tlbw_hazard(); 198 mtc0_tlbw_hazard();
204 tlb_probe(); 199 tlb_probe();
205 BARRIER; 200 tlb_probe_hazard();
206 idx = read_c0_index(); 201 idx = read_c0_index();
207 write_c0_entrylo0(0); 202 write_c0_entrylo0(0);
208 write_c0_entrylo1(0); 203 write_c0_entrylo1(0);
@@ -235,7 +230,7 @@ void local_flush_tlb_one(unsigned long page)
235 write_c0_entryhi(page); 230 write_c0_entryhi(page);
236 mtc0_tlbw_hazard(); 231 mtc0_tlbw_hazard();
237 tlb_probe(); 232 tlb_probe();
238 BARRIER; 233 tlb_probe_hazard();
239 idx = read_c0_index(); 234 idx = read_c0_index();
240 write_c0_entrylo0(0); 235 write_c0_entrylo0(0);
241 write_c0_entrylo1(0); 236 write_c0_entrylo1(0);
@@ -279,7 +274,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
279 pgdp = pgd_offset(vma->vm_mm, address); 274 pgdp = pgd_offset(vma->vm_mm, address);
280 mtc0_tlbw_hazard(); 275 mtc0_tlbw_hazard();
281 tlb_probe(); 276 tlb_probe();
282 BARRIER; 277 tlb_probe_hazard();
283 pudp = pud_offset(pgdp, address); 278 pudp = pud_offset(pgdp, address);
284 pmdp = pmd_offset(pudp, address); 279 pmdp = pmd_offset(pudp, address);
285 idx = read_c0_index(); 280 idx = read_c0_index();
@@ -320,7 +315,7 @@ static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma,
320 pgdp = pgd_offset(vma->vm_mm, address); 315 pgdp = pgd_offset(vma->vm_mm, address);
321 mtc0_tlbw_hazard(); 316 mtc0_tlbw_hazard();
322 tlb_probe(); 317 tlb_probe();
323 BARRIER; 318 tlb_probe_hazard();
324 pmdp = pmd_offset(pgdp, address); 319 pmdp = pmd_offset(pgdp, address);
325 idx = read_c0_index(); 320 idx = read_c0_index();
326 ptep = pte_offset_map(pmdp, address); 321 ptep = pte_offset_map(pmdp, address);
@@ -351,7 +346,7 @@ void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
351 wired = read_c0_wired(); 346 wired = read_c0_wired();
352 write_c0_wired(wired + 1); 347 write_c0_wired(wired + 1);
353 write_c0_index(wired); 348 write_c0_index(wired);
354 BARRIER; 349 tlbw_use_hazard(); /* What is the hazard here? */
355 write_c0_pagemask(pagemask); 350 write_c0_pagemask(pagemask);
356 write_c0_entryhi(entryhi); 351 write_c0_entryhi(entryhi);
357 write_c0_entrylo0(entrylo0); 352 write_c0_entrylo0(entrylo0);
@@ -361,7 +356,7 @@ void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
361 tlbw_use_hazard(); 356 tlbw_use_hazard();
362 357
363 write_c0_entryhi(old_ctx); 358 write_c0_entryhi(old_ctx);
364 BARRIER; 359 tlbw_use_hazard(); /* What is the hazard here? */
365 write_c0_pagemask(old_pagemask); 360 write_c0_pagemask(old_pagemask);
366 local_flush_tlb_all(); 361 local_flush_tlb_all();
367 EXIT_CRITICAL(flags); 362 EXIT_CRITICAL(flags);
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index 35d5927706ea..edefa97b2330 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -11,7 +11,6 @@ obj-$(CONFIG_ITE_BOARD_GEN) += ops-it8172.o
11obj-$(CONFIG_MIPS_BONITO64) += ops-bonito64.o 11obj-$(CONFIG_MIPS_BONITO64) += ops-bonito64.o
12obj-$(CONFIG_MIPS_GT64111) += ops-gt64111.o 12obj-$(CONFIG_MIPS_GT64111) += ops-gt64111.o
13obj-$(CONFIG_MIPS_GT64120) += ops-gt64120.o 13obj-$(CONFIG_MIPS_GT64120) += ops-gt64120.o
14obj-$(CONFIG_MIPS_GT96100) += ops-gt96100.o
15obj-$(CONFIG_PCI_MARVELL) += ops-marvell.o 14obj-$(CONFIG_PCI_MARVELL) += ops-marvell.o
16obj-$(CONFIG_MIPS_MSC) += ops-msc.o 15obj-$(CONFIG_MIPS_MSC) += ops-msc.o
17obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o 16obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o
@@ -28,8 +27,7 @@ obj-$(CONFIG_DDB5477) += fixup-ddb5477.o pci-ddb5477.o ops-ddb5477.o
28obj-$(CONFIG_LASAT) += pci-lasat.o 27obj-$(CONFIG_LASAT) += pci-lasat.o
29obj-$(CONFIG_MIPS_ATLAS) += fixup-atlas.o 28obj-$(CONFIG_MIPS_ATLAS) += fixup-atlas.o
30obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o 29obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o
31obj-$(CONFIG_MIPS_EV96100) += fixup-ev64120.o 30obj-$(CONFIG_MIPS_EV64120) += fixup-ev64120.o
32obj-$(CONFIG_MIPS_EV96100) += fixup-ev96100.o pci-ev96100.o
33obj-$(CONFIG_MIPS_ITE8172) += fixup-ite8172g.o 31obj-$(CONFIG_MIPS_ITE8172) += fixup-ite8172g.o
34obj-$(CONFIG_MIPS_IVR) += fixup-ivr.o 32obj-$(CONFIG_MIPS_IVR) += fixup-ivr.o
35obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o 33obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o
diff --git a/arch/mips/pci/fixup-atlas.c b/arch/mips/pci/fixup-atlas.c
index 439510af3037..c6cd6e9cdfbc 100644
--- a/arch/mips/pci/fixup-atlas.c
+++ b/arch/mips/pci/fixup-atlas.c
@@ -21,16 +21,16 @@
21 21
22#include <asm/mips-boards/atlasint.h> 22#include <asm/mips-boards/atlasint.h>
23 23
24#define PCIA ATLASINT_PCIA 24#define PCIA ATLAS_INT_PCIA
25#define PCIB ATLASINT_PCIB 25#define PCIB ATLAS_INT_PCIB
26#define PCIC ATLASINT_PCIC 26#define PCIC ATLAS_INT_PCIC
27#define PCID ATLASINT_PCID 27#define PCID ATLAS_INT_PCID
28#define INTA ATLASINT_INTA 28#define INTA ATLAS_INT_INTA
29#define INTB ATLASINT_INTB 29#define INTB ATLAS_INT_INTB
30#define ETH ATLASINT_ETH 30#define ETH ATLAS_INT_ETH
31#define INTC ATLASINT_INTC 31#define INTC ATLAS_INT_INTC
32#define SCSI ATLASINT_SCSI 32#define SCSI ATLAS_INT_SCSI
33#define INTD ATLASINT_INTD 33#define INTD ATLAS_INT_INTD
34 34
35static char irq_tab[][5] __initdata = { 35static char irq_tab[][5] __initdata = {
36 /* INTA INTB INTC INTD */ 36 /* INTA INTB INTC INTD */
diff --git a/arch/mips/pci/fixup-ev96100.c b/arch/mips/pci/fixup-ev96100.c
deleted file mode 100644
index e2bc977b6d58..000000000000
--- a/arch/mips/pci/fixup-ev96100.c
+++ /dev/null
@@ -1,48 +0,0 @@
1/*
2 *
3 * BRIEF MODULE DESCRIPTION
4 * EV96100 Board specific pci fixups.
5 *
6 * Copyright 2001 MontaVista Software Inc.
7 * Author: MontaVista Software, Inc.
8 * ppopov@mvista.com or source@mvista.com
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#include <linux/init.h>
31#include <linux/types.h>
32#include <linux/pci.h>
33
34static char irq_tab_ev96100[][5] __initdata = {
35 [8] = { 0, 5, 5, 5, 5 },
36 [9] = { 0, 2, 2, 2, 2 }
37};
38
39int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
40{
41 return irq_tab_ev96100[slot][pin];
42}
43
44/* Do platform specific device initialization at pci_enable_device() time */
45int pcibios_plat_dev_init(struct pci_dev *dev)
46{
47 return 0;
48}
diff --git a/arch/mips/pci/ops-au1000.c b/arch/mips/pci/ops-au1000.c
index 0c0c1e6519f9..8ae46481fcb7 100644
--- a/arch/mips/pci/ops-au1000.c
+++ b/arch/mips/pci/ops-au1000.c
@@ -110,7 +110,7 @@ static int config_access(unsigned char access_type, struct pci_bus *bus,
110 if (first_cfg) { 110 if (first_cfg) {
111 /* reserve a wired entry for pci config accesses */ 111 /* reserve a wired entry for pci config accesses */
112 first_cfg = 0; 112 first_cfg = 0;
113 pci_cfg_vm = get_vm_area(0x2000, 0); 113 pci_cfg_vm = get_vm_area(0x2000, VM_IOREMAP);
114 if (!pci_cfg_vm) 114 if (!pci_cfg_vm)
115 panic (KERN_ERR "PCI unable to get vm area\n"); 115 panic (KERN_ERR "PCI unable to get vm area\n");
116 pci_cfg_wired_entry = read_c0_wired(); 116 pci_cfg_wired_entry = read_c0_wired();
diff --git a/arch/mips/pci/ops-gt96100.c b/arch/mips/pci/ops-gt96100.c
deleted file mode 100644
index 9e4ea6627e21..000000000000
--- a/arch/mips/pci/ops-gt96100.c
+++ /dev/null
@@ -1,169 +0,0 @@
1/*
2 *
3 * BRIEF MODULE DESCRIPTION
4 * Galileo EV96100 board specific pci support.
5 *
6 * Copyright 2000 MontaVista Software Inc.
7 * Author: MontaVista Software, Inc.
8 * ppopov@mvista.com or source@mvista.com
9 *
10 * This file was derived from Carsten Langgaard's
11 * arch/mips/mips-boards/generic/pci.c
12 *
13 * Carsten Langgaard, carstenl@mips.com
14 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
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 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
24 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * You should have received a copy of the GNU General Public License along
33 * with this program; if not, write to the Free Software Foundation, Inc.,
34 * 675 Mass Ave, Cambridge, MA 02139, USA.
35 */
36#include <linux/types.h>
37#include <linux/pci.h>
38#include <linux/kernel.h>
39#include <linux/init.h>
40
41#include <asm/delay.h>
42#include <asm/gt64120.h>
43#include <asm/galileo-boards/ev96100.h>
44
45#define PCI_ACCESS_READ 0
46#define PCI_ACCESS_WRITE 1
47
48static int static gt96100_config_access(unsigned char access_type,
49 struct pci_bus *bus, unsigned int devfn, int where, u32 * data)
50{
51 unsigned char bus = bus->number;
52 u32 intr;
53
54 /*
55 * Because of a bug in the galileo (for slot 31).
56 */
57 if (bus == 0 && devfn >= PCI_DEVFN(31, 0))
58 return PCIBIOS_DEVICE_NOT_FOUND;
59
60 /* Clear cause register bits */
61 GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
62 GT_INTRCAUSE_TARABORT0_BIT));
63
64 /* Setup address */
65 GT_WRITE(GT_PCI0_CFGADDR_OFS,
66 (bus << GT_PCI0_CFGADDR_BUSNUM_SHF) |
67 (devfn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
68 ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
69 GT_PCI0_CFGADDR_CONFIGEN_BIT);
70 udelay(2);
71
72
73 if (access_type == PCI_ACCESS_WRITE) {
74 if (devfn != 0)
75 *data = le32_to_cpu(*data);
76 GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
77 } else {
78 *data = GT_READ(GT_PCI0_CFGDATA_OFS);
79 if (devfn != 0)
80 *data = le32_to_cpu(*data);
81 }
82
83 udelay(2);
84
85 /* Check for master or target abort */
86 intr = GT_READ(GT_INTRCAUSE_OFS);
87
88 if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)) {
89 /* Error occured */
90
91 /* Clear bits */
92 GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
93 GT_INTRCAUSE_TARABORT0_BIT));
94 return -1;
95 }
96 return 0;
97}
98
99/*
100 * We can't address 8 and 16 bit words directly. Instead we have to
101 * read/write a 32bit word and mask/modify the data we actually want.
102 */
103static int gt96100_pcibios_read(struct pci_bus *bus, unsigned int devfn,
104 int where, int size, u32 * val)
105{
106 u32 data = 0;
107
108 if (gt96100_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
109 return PCIBIOS_DEVICE_NOT_FOUND;
110
111 switch (size) {
112 case 1:
113 *val = (data >> ((where & 3) << 3)) & 0xff;
114 break;
115
116 case 2:
117 *val = (data >> ((where & 3) << 3)) & 0xffff;
118 break;
119
120 case 4:
121 *val = data;
122 break;
123 }
124 return PCIBIOS_SUCCESSFUL;
125}
126
127static int gt96100_pcibios_write(struct pci_bus *bus, unsigned int devfn,
128 int where, int size, u32 val)
129{
130 u32 data = 0;
131
132 switch (size) {
133 case 1:
134 if (gt96100_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
135 return -1;
136
137 data = (data & ~(0xff << ((where & 3) << 3))) |
138 (val << ((where & 3) << 3));
139
140 if (gt96100_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
141 return -1;
142
143 return PCIBIOS_SUCCESSFUL;
144
145 case 2:
146 if (gt96100_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
147 return -1;
148
149 data = (data & ~(0xffff << ((where & 3) << 3))) |
150 (val << ((where & 3) << 3));
151
152 if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &data))
153 return -1;
154
155
156 return PCIBIOS_SUCCESSFUL;
157
158 case 4:
159 if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &val))
160 return -1;
161
162 return PCIBIOS_SUCCESSFUL;
163 }
164}
165
166struct pci_ops gt96100_pci_ops = {
167 .read = gt96100_pcibios_read,
168 .write = gt96100_pcibios_write
169};
diff --git a/arch/mips/pci/pci-ev96100.c b/arch/mips/pci/pci-ev96100.c
deleted file mode 100644
index f9457ea00def..000000000000
--- a/arch/mips/pci/pci-ev96100.c
+++ /dev/null
@@ -1,63 +0,0 @@
1/*
2 * Copyright 2000 MontaVista Software Inc.
3 * Author: MontaVista Software, Inc.
4 * ppopov@mvista.com or source@mvista.com
5 *
6 * Carsten Langgaard, carstenl@mips.com
7 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
8 *
9 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
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 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
22 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * You should have received a copy of the GNU General Public License along
28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 675 Mass Ave, Cambridge, MA 02139, USA.
30 */
31#include <linux/types.h>
32#include <linux/pci.h>
33#include <linux/kernel.h>
34#include <linux/init.h>
35
36static struct resource pci_io_resource = {
37 .name = "io pci IO space",
38 .start = 0x10000000,
39 .end = 0x11ffffff,
40 .flags = IORESOURCE_IO
41};
42
43static struct resource pci_mem_resource = {
44 .name = "ext pci memory space",
45 .start = 0x12000000,
46 .end = 0x13ffffff,
47 .flags = IORESOURCE_MEM
48};
49
50extern struct pci_ops gt96100_pci_ops;
51
52struct pci_controller ev96100_controller = {
53 .pci_ops = &gt96100_pci_ops,
54 .io_resource = &pci_io_resource,
55 .mem_resource = &pci_mem_resource,
56};
57
58static void ev96100_pci_init(void)
59{
60 register_pci_controller(&ev96100_controller);
61}
62
63arch_initcall(ev96100_pci_init);
diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c
index 80eb9af9ecdf..405ce0152739 100644
--- a/arch/mips/pci/pci-ip27.c
+++ b/arch/mips/pci/pci-ip27.c
@@ -16,8 +16,6 @@
16#include <asm/sn/intr.h> 16#include <asm/sn/intr.h>
17#include <asm/sn/sn0/hub.h> 17#include <asm/sn/sn0/hub.h>
18 18
19extern unsigned int allocate_irqno(void);
20
21/* 19/*
22 * Max #PCI busses we can handle; ie, max #PCI bridges. 20 * Max #PCI busses we can handle; ie, max #PCI bridges.
23 */ 21 */
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c
index efe6971fc800..16e5682b01f1 100644
--- a/arch/mips/sgi-ip27/ip27-memory.c
+++ b/arch/mips/sgi-ip27/ip27-memory.c
@@ -19,6 +19,7 @@
19#include <linux/swap.h> 19#include <linux/swap.h>
20#include <linux/bootmem.h> 20#include <linux/bootmem.h>
21#include <linux/pfn.h> 21#include <linux/pfn.h>
22#include <linux/highmem.h>
22#include <asm/page.h> 23#include <asm/page.h>
23#include <asm/sections.h> 24#include <asm/sections.h>
24 25
@@ -508,7 +509,7 @@ extern unsigned long setup_zero_pages(void);
508 509
509void __init paging_init(void) 510void __init paging_init(void)
510{ 511{
511 unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; 512 unsigned long zones_size[MAX_NR_ZONES] = {0, };
512 unsigned node; 513 unsigned node;
513 514
514 pagetable_init(); 515 pagetable_init();
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
index ed325f0ab28a..a0222fa4416c 100644
--- a/arch/mips/sibyte/bcm1480/irq.c
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -469,21 +469,6 @@ void bcm1480_kgdb_interrupt(struct pt_regs *regs)
469 469
470#endif /* CONFIG_KGDB */ 470#endif /* CONFIG_KGDB */
471 471
472static inline int dclz(unsigned long long x)
473{
474 int lz;
475
476 __asm__ (
477 " .set push \n"
478 " .set mips64 \n"
479 " dclz %0, %1 \n"
480 " .set pop \n"
481 : "=r" (lz)
482 : "r" (x));
483
484 return lz;
485}
486
487extern void bcm1480_timer_interrupt(struct pt_regs *regs); 472extern void bcm1480_timer_interrupt(struct pt_regs *regs);
488extern void bcm1480_mailbox_interrupt(struct pt_regs *regs); 473extern void bcm1480_mailbox_interrupt(struct pt_regs *regs);
489extern void bcm1480_kgdb_interrupt(struct pt_regs *regs); 474extern void bcm1480_kgdb_interrupt(struct pt_regs *regs);
@@ -536,9 +521,9 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
536 521
537 if (mask_h) { 522 if (mask_h) {
538 if (mask_h ^ 1) 523 if (mask_h ^ 1)
539 do_IRQ(63 - dclz(mask_h), regs); 524 do_IRQ(fls64(mask_h) - 1, regs);
540 else 525 else
541 do_IRQ(127 - dclz(mask_l), regs); 526 do_IRQ(63 + fls64(mask_l), regs);
542 } 527 }
543 } 528 }
544} 529}
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
index 1de71adec6c6..a451b4c7732d 100644
--- a/arch/mips/sibyte/sb1250/irq.c
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -419,21 +419,6 @@ static void sb1250_kgdb_interrupt(struct pt_regs *regs)
419 419
420#endif /* CONFIG_KGDB */ 420#endif /* CONFIG_KGDB */
421 421
422static inline int dclz(unsigned long long x)
423{
424 int lz;
425
426 __asm__ (
427 " .set push \n"
428 " .set mips64 \n"
429 " dclz %0, %1 \n"
430 " .set pop \n"
431 : "=r" (lz)
432 : "r" (x));
433
434 return lz;
435}
436
437extern void sb1250_timer_interrupt(struct pt_regs *regs); 422extern void sb1250_timer_interrupt(struct pt_regs *regs);
438extern void sb1250_mailbox_interrupt(struct pt_regs *regs); 423extern void sb1250_mailbox_interrupt(struct pt_regs *regs);
439extern void sb1250_kgdb_interrupt(struct pt_regs *regs); 424extern void sb1250_kgdb_interrupt(struct pt_regs *regs);
@@ -490,6 +475,6 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
490 mask = __raw_readq(IOADDR(A_IMR_REGISTER(smp_processor_id(), 475 mask = __raw_readq(IOADDR(A_IMR_REGISTER(smp_processor_id(),
491 R_IMR_INTERRUPT_STATUS_BASE))); 476 R_IMR_INTERRUPT_STATUS_BASE)));
492 if (mask) 477 if (mask)
493 do_IRQ(63 - dclz(mask), regs); 478 do_IRQ(fls64(mask) - 1, regs);
494 } 479 }
495} 480}
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index f2b96f1e0da7..25ad28d63e88 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -551,7 +551,7 @@ void show_mem(void)
551 551
552 printk("Zone list for zone %d on node %d: ", j, i); 552 printk("Zone list for zone %d on node %d: ", j, i);
553 for (k = 0; zl->zones[k] != NULL; k++) 553 for (k = 0; zl->zones[k] != NULL; k++)
554 printk("[%d/%s] ", zl->zones[k]->zone_pgdat->node_id, zl->zones[k]->name); 554 printk("[%d/%s] ", zone_to_nid(zl->zones[k]), zl->zones[k]->name);
555 printk("\n"); 555 printk("\n");
556 } 556 }
557 } 557 }
@@ -809,7 +809,7 @@ void __init paging_init(void)
809 flush_tlb_all_local(NULL); 809 flush_tlb_all_local(NULL);
810 810
811 for (i = 0; i < npmem_ranges; i++) { 811 for (i = 0; i < npmem_ranges; i++) {
812 unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0 }; 812 unsigned long zones_size[MAX_NR_ZONES] = { 0, };
813 813
814 /* We have an IOMMU, so all memory can go into a single 814 /* We have an IOMMU, so all memory can go into a single
815 ZONE_DMA zone. */ 815 ZONE_DMA zone. */
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index de1ef2fa1a20..a0dd1b0ee483 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -731,11 +731,10 @@ config ARCH_SPARSEMEM_DEFAULT
731 def_bool y 731 def_bool y
732 depends on SMP && PPC_PSERIES 732 depends on SMP && PPC_PSERIES
733 733
734source "mm/Kconfig" 734config ARCH_POPULATES_NODE_MAP
735
736config HAVE_ARCH_EARLY_PFN_TO_NID
737 def_bool y 735 def_bool y
738 depends on NEED_MULTIPLE_NODES 736
737source "mm/Kconfig"
739 738
740config ARCH_MEMORY_PROBE 739config ARCH_MEMORY_PROBE
741 def_bool y 740 def_bool y
diff --git a/arch/powerpc/kernel/swsusp_32.S b/arch/powerpc/kernel/swsusp_32.S
index 7369f9a6ad25..69e8f86aa4f8 100644
--- a/arch/powerpc/kernel/swsusp_32.S
+++ b/arch/powerpc/kernel/swsusp_32.S
@@ -159,8 +159,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
159 isync 159 isync
160 160
161 /* Load ptr the list of pages to copy in r3 */ 161 /* Load ptr the list of pages to copy in r3 */
162 lis r11,(pagedir_nosave - KERNELBASE)@h 162 lis r11,(restore_pblist - KERNELBASE)@h
163 ori r11,r11,pagedir_nosave@l 163 ori r11,r11,restore_pblist@l
164 lwz r10,0(r11) 164 lwz r10,0(r11)
165 165
166 /* Copy the pages. This is a very basic implementation, to 166 /* Copy the pages. This is a very basic implementation, to
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index 2e292863e982..5e391fc25340 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -740,7 +740,7 @@ asmlinkage long compat_sys_umask(u32 mask)
740 return sys_umask((int)mask); 740 return sys_umask((int)mask);
741} 741}
742 742
743#ifdef CONFIG_SYSCTL 743#ifdef CONFIG_SYSCTL_SYSCALL
744struct __sysctl_args32 { 744struct __sysctl_args32 {
745 u32 name; 745 u32 name;
746 int nlen; 746 int nlen;
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index eebd8b83a6b0..16fe027bbc12 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -256,20 +256,22 @@ void __init do_init_bootmem(void)
256 256
257 boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages); 257 boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages);
258 258
259 /* Add active regions with valid PFNs */
260 for (i = 0; i < lmb.memory.cnt; i++) {
261 unsigned long start_pfn, end_pfn;
262 start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT;
263 end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i);
264 add_active_range(0, start_pfn, end_pfn);
265 }
266
259 /* Add all physical memory to the bootmem map, mark each area 267 /* Add all physical memory to the bootmem map, mark each area
260 * present. 268 * present.
261 */ 269 */
262 for (i = 0; i < lmb.memory.cnt; i++) {
263 unsigned long base = lmb.memory.region[i].base;
264 unsigned long size = lmb_size_bytes(&lmb.memory, i);
265#ifdef CONFIG_HIGHMEM 270#ifdef CONFIG_HIGHMEM
266 if (base >= total_lowmem) 271 free_bootmem_with_active_regions(0, total_lowmem >> PAGE_SHIFT);
267 continue; 272#else
268 if (base + size > total_lowmem) 273 free_bootmem_with_active_regions(0, max_pfn);
269 size = total_lowmem - base;
270#endif 274#endif
271 free_bootmem(base, size);
272 }
273 275
274 /* reserve the sections we're already using */ 276 /* reserve the sections we're already using */
275 for (i = 0; i < lmb.reserved.cnt; i++) 277 for (i = 0; i < lmb.reserved.cnt; i++)
@@ -277,9 +279,8 @@ void __init do_init_bootmem(void)
277 lmb_size_bytes(&lmb.reserved, i)); 279 lmb_size_bytes(&lmb.reserved, i));
278 280
279 /* XXX need to clip this if using highmem? */ 281 /* XXX need to clip this if using highmem? */
280 for (i = 0; i < lmb.memory.cnt; i++) 282 sparse_memory_present_with_active_regions(0);
281 memory_present(0, lmb_start_pfn(&lmb.memory, i), 283
282 lmb_end_pfn(&lmb.memory, i));
283 init_bootmem_done = 1; 284 init_bootmem_done = 1;
284} 285}
285 286
@@ -288,10 +289,9 @@ void __init do_init_bootmem(void)
288 */ 289 */
289void __init paging_init(void) 290void __init paging_init(void)
290{ 291{
291 unsigned long zones_size[MAX_NR_ZONES];
292 unsigned long zholes_size[MAX_NR_ZONES];
293 unsigned long total_ram = lmb_phys_mem_size(); 292 unsigned long total_ram = lmb_phys_mem_size();
294 unsigned long top_of_ram = lmb_end_of_DRAM(); 293 unsigned long top_of_ram = lmb_end_of_DRAM();
294 unsigned long max_zone_pfns[MAX_NR_ZONES];
295 295
296#ifdef CONFIG_HIGHMEM 296#ifdef CONFIG_HIGHMEM
297 map_page(PKMAP_BASE, 0, 0); /* XXX gross */ 297 map_page(PKMAP_BASE, 0, 0); /* XXX gross */
@@ -307,26 +307,13 @@ void __init paging_init(void)
307 top_of_ram, total_ram); 307 top_of_ram, total_ram);
308 printk(KERN_DEBUG "Memory hole size: %ldMB\n", 308 printk(KERN_DEBUG "Memory hole size: %ldMB\n",
309 (top_of_ram - total_ram) >> 20); 309 (top_of_ram - total_ram) >> 20);
310 /*
311 * All pages are DMA-able so we put them all in the DMA zone.
312 */
313 memset(zones_size, 0, sizeof(zones_size));
314 memset(zholes_size, 0, sizeof(zholes_size));
315
316 zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
317 zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT;
318
319#ifdef CONFIG_HIGHMEM 310#ifdef CONFIG_HIGHMEM
320 zones_size[ZONE_DMA] = total_lowmem >> PAGE_SHIFT; 311 max_zone_pfns[0] = total_lowmem >> PAGE_SHIFT;
321 zones_size[ZONE_HIGHMEM] = (total_memory - total_lowmem) >> PAGE_SHIFT; 312 max_zone_pfns[1] = top_of_ram >> PAGE_SHIFT;
322 zholes_size[ZONE_HIGHMEM] = (top_of_ram - total_ram) >> PAGE_SHIFT;
323#else 313#else
324 zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT; 314 max_zone_pfns[0] = top_of_ram >> PAGE_SHIFT;
325 zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT; 315#endif
326#endif /* CONFIG_HIGHMEM */ 316 free_area_init_nodes(max_zone_pfns);
327
328 free_area_init_node(0, NODE_DATA(0), zones_size,
329 __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size);
330} 317}
331#endif /* ! CONFIG_NEED_MULTIPLE_NODES */ 318#endif /* ! CONFIG_NEED_MULTIPLE_NODES */
332 319
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 6c0f1c7d83e5..43c272075e1a 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -39,96 +39,6 @@ static bootmem_data_t __initdata plat_node_bdata[MAX_NUMNODES];
39static int min_common_depth; 39static int min_common_depth;
40static int n_mem_addr_cells, n_mem_size_cells; 40static int n_mem_addr_cells, n_mem_size_cells;
41 41
42/*
43 * We need somewhere to store start/end/node for each region until we have
44 * allocated the real node_data structures.
45 */
46#define MAX_REGIONS (MAX_LMB_REGIONS*2)
47static struct {
48 unsigned long start_pfn;
49 unsigned long end_pfn;
50 int nid;
51} init_node_data[MAX_REGIONS] __initdata;
52
53int __init early_pfn_to_nid(unsigned long pfn)
54{
55 unsigned int i;
56
57 for (i = 0; init_node_data[i].end_pfn; i++) {
58 unsigned long start_pfn = init_node_data[i].start_pfn;
59 unsigned long end_pfn = init_node_data[i].end_pfn;
60
61 if ((start_pfn <= pfn) && (pfn < end_pfn))
62 return init_node_data[i].nid;
63 }
64
65 return -1;
66}
67
68void __init add_region(unsigned int nid, unsigned long start_pfn,
69 unsigned long pages)
70{
71 unsigned int i;
72
73 dbg("add_region nid %d start_pfn 0x%lx pages 0x%lx\n",
74 nid, start_pfn, pages);
75
76 for (i = 0; init_node_data[i].end_pfn; i++) {
77 if (init_node_data[i].nid != nid)
78 continue;
79 if (init_node_data[i].end_pfn == start_pfn) {
80 init_node_data[i].end_pfn += pages;
81 return;
82 }
83 if (init_node_data[i].start_pfn == (start_pfn + pages)) {
84 init_node_data[i].start_pfn -= pages;
85 return;
86 }
87 }
88
89 /*
90 * Leave last entry NULL so we dont iterate off the end (we use
91 * entry.end_pfn to terminate the walk).
92 */
93 if (i >= (MAX_REGIONS - 1)) {
94 printk(KERN_ERR "WARNING: too many memory regions in "
95 "numa code, truncating\n");
96 return;
97 }
98
99 init_node_data[i].start_pfn = start_pfn;
100 init_node_data[i].end_pfn = start_pfn + pages;
101 init_node_data[i].nid = nid;
102}
103
104/* We assume init_node_data has no overlapping regions */
105void __init get_region(unsigned int nid, unsigned long *start_pfn,
106 unsigned long *end_pfn, unsigned long *pages_present)
107{
108 unsigned int i;
109
110 *start_pfn = -1UL;
111 *end_pfn = *pages_present = 0;
112
113 for (i = 0; init_node_data[i].end_pfn; i++) {
114 if (init_node_data[i].nid != nid)
115 continue;
116
117 *pages_present += init_node_data[i].end_pfn -
118 init_node_data[i].start_pfn;
119
120 if (init_node_data[i].start_pfn < *start_pfn)
121 *start_pfn = init_node_data[i].start_pfn;
122
123 if (init_node_data[i].end_pfn > *end_pfn)
124 *end_pfn = init_node_data[i].end_pfn;
125 }
126
127 /* We didnt find a matching region, return start/end as 0 */
128 if (*start_pfn == -1UL)
129 *start_pfn = 0;
130}
131
132static void __cpuinit map_cpu_to_node(int cpu, int node) 42static void __cpuinit map_cpu_to_node(int cpu, int node)
133{ 43{
134 numa_cpu_lookup_table[cpu] = node; 44 numa_cpu_lookup_table[cpu] = node;
@@ -468,8 +378,8 @@ new_range:
468 continue; 378 continue;
469 } 379 }
470 380
471 add_region(nid, start >> PAGE_SHIFT, 381 add_active_range(nid, start >> PAGE_SHIFT,
472 size >> PAGE_SHIFT); 382 (start >> PAGE_SHIFT) + (size >> PAGE_SHIFT));
473 383
474 if (--ranges) 384 if (--ranges)
475 goto new_range; 385 goto new_range;
@@ -482,6 +392,7 @@ static void __init setup_nonnuma(void)
482{ 392{
483 unsigned long top_of_ram = lmb_end_of_DRAM(); 393 unsigned long top_of_ram = lmb_end_of_DRAM();
484 unsigned long total_ram = lmb_phys_mem_size(); 394 unsigned long total_ram = lmb_phys_mem_size();
395 unsigned long start_pfn, end_pfn;
485 unsigned int i; 396 unsigned int i;
486 397
487 printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", 398 printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
@@ -489,9 +400,11 @@ static void __init setup_nonnuma(void)
489 printk(KERN_DEBUG "Memory hole size: %ldMB\n", 400 printk(KERN_DEBUG "Memory hole size: %ldMB\n",
490 (top_of_ram - total_ram) >> 20); 401 (top_of_ram - total_ram) >> 20);
491 402
492 for (i = 0; i < lmb.memory.cnt; ++i) 403 for (i = 0; i < lmb.memory.cnt; ++i) {
493 add_region(0, lmb.memory.region[i].base >> PAGE_SHIFT, 404 start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT;
494 lmb_size_pages(&lmb.memory, i)); 405 end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i);
406 add_active_range(0, start_pfn, end_pfn);
407 }
495 node_set_online(0); 408 node_set_online(0);
496} 409}
497 410
@@ -630,11 +543,11 @@ void __init do_init_bootmem(void)
630 (void *)(unsigned long)boot_cpuid); 543 (void *)(unsigned long)boot_cpuid);
631 544
632 for_each_online_node(nid) { 545 for_each_online_node(nid) {
633 unsigned long start_pfn, end_pfn, pages_present; 546 unsigned long start_pfn, end_pfn;
634 unsigned long bootmem_paddr; 547 unsigned long bootmem_paddr;
635 unsigned long bootmap_pages; 548 unsigned long bootmap_pages;
636 549
637 get_region(nid, &start_pfn, &end_pfn, &pages_present); 550 get_pfn_range_for_nid(nid, &start_pfn, &end_pfn);
638 551
639 /* Allocate the node structure node local if possible */ 552 /* Allocate the node structure node local if possible */
640 NODE_DATA(nid) = careful_allocation(nid, 553 NODE_DATA(nid) = careful_allocation(nid,
@@ -667,19 +580,7 @@ void __init do_init_bootmem(void)
667 init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT, 580 init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT,
668 start_pfn, end_pfn); 581 start_pfn, end_pfn);
669 582
670 /* Add free regions on this node */ 583 free_bootmem_with_active_regions(nid, end_pfn);
671 for (i = 0; init_node_data[i].end_pfn; i++) {
672 unsigned long start, end;
673
674 if (init_node_data[i].nid != nid)
675 continue;
676
677 start = init_node_data[i].start_pfn << PAGE_SHIFT;
678 end = init_node_data[i].end_pfn << PAGE_SHIFT;
679
680 dbg("free_bootmem %lx %lx\n", start, end - start);
681 free_bootmem_node(NODE_DATA(nid), start, end - start);
682 }
683 584
684 /* Mark reserved regions on this node */ 585 /* Mark reserved regions on this node */
685 for (i = 0; i < lmb.reserved.cnt; i++) { 586 for (i = 0; i < lmb.reserved.cnt; i++) {
@@ -710,44 +611,16 @@ void __init do_init_bootmem(void)
710 } 611 }
711 } 612 }
712 613
713 /* Add regions into sparsemem */ 614 sparse_memory_present_with_active_regions(nid);
714 for (i = 0; init_node_data[i].end_pfn; i++) {
715 unsigned long start, end;
716
717 if (init_node_data[i].nid != nid)
718 continue;
719
720 start = init_node_data[i].start_pfn;
721 end = init_node_data[i].end_pfn;
722
723 memory_present(nid, start, end);
724 }
725 } 615 }
726} 616}
727 617
728void __init paging_init(void) 618void __init paging_init(void)
729{ 619{
730 unsigned long zones_size[MAX_NR_ZONES]; 620 unsigned long max_zone_pfns[MAX_NR_ZONES] = {
731 unsigned long zholes_size[MAX_NR_ZONES]; 621 lmb_end_of_DRAM() >> PAGE_SHIFT
732 int nid; 622 };
733 623 free_area_init_nodes(max_zone_pfns);
734 memset(zones_size, 0, sizeof(zones_size));
735 memset(zholes_size, 0, sizeof(zholes_size));
736
737 for_each_online_node(nid) {
738 unsigned long start_pfn, end_pfn, pages_present;
739
740 get_region(nid, &start_pfn, &end_pfn, &pages_present);
741
742 zones_size[ZONE_DMA] = end_pfn - start_pfn;
743 zholes_size[ZONE_DMA] = zones_size[ZONE_DMA] - pages_present;
744
745 dbg("free_area_init node %d %lx %lx (hole: %lx)\n", nid,
746 zones_size[ZONE_DMA], start_pfn, zholes_size[ZONE_DMA]);
747
748 free_area_init_node(nid, NODE_DATA(nid), zones_size, start_pfn,
749 zholes_size);
750 }
751} 624}
752 625
753static int __init early_numa(char *p) 626static int __init early_numa(char *p)
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 7b4572805db9..3950ddccb2c8 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -82,7 +82,6 @@ spufs_new_inode(struct super_block *sb, int mode)
82 inode->i_mode = mode; 82 inode->i_mode = mode;
83 inode->i_uid = current->fsuid; 83 inode->i_uid = current->fsuid;
84 inode->i_gid = current->fsgid; 84 inode->i_gid = current->fsgid;
85 inode->i_blksize = PAGE_CACHE_SIZE;
86 inode->i_blocks = 0; 85 inode->i_blocks = 0;
87 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 86 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
88out: 87out:
@@ -120,7 +119,7 @@ spufs_new_file(struct super_block *sb, struct dentry *dentry,
120 ret = 0; 119 ret = 0;
121 inode->i_op = &spufs_file_iops; 120 inode->i_op = &spufs_file_iops;
122 inode->i_fop = fops; 121 inode->i_fop = fops;
123 inode->u.generic_ip = SPUFS_I(inode)->i_ctx = get_spu_context(ctx); 122 inode->i_private = SPUFS_I(inode)->i_ctx = get_spu_context(ctx);
124 d_add(dentry, inode); 123 d_add(dentry, inode);
125out: 124out:
126 return ret; 125 return ret;
diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c
index 641e6511cf06..446e17d162a5 100644
--- a/arch/powerpc/platforms/pseries/hvCall_inst.c
+++ b/arch/powerpc/platforms/pseries/hvCall_inst.c
@@ -85,7 +85,7 @@ static int hcall_inst_seq_open(struct inode *inode, struct file *file)
85 85
86 rc = seq_open(file, &hcall_inst_seq_ops); 86 rc = seq_open(file, &hcall_inst_seq_ops);
87 seq = file->private_data; 87 seq = file->private_data;
88 seq->private = file->f_dentry->d_inode->u.generic_ip; 88 seq->private = file->f_dentry->d_inode->i_private;
89 89
90 return rc; 90 return rc;
91} 91}
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index b604926401f5..723972bb5bd9 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -339,7 +339,7 @@ static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase,
339 for (pos = readb(devbase + PCI_CAPABILITY_LIST); pos != 0; 339 for (pos = readb(devbase + PCI_CAPABILITY_LIST); pos != 0;
340 pos = readb(devbase + pos + PCI_CAP_LIST_NEXT)) { 340 pos = readb(devbase + pos + PCI_CAP_LIST_NEXT)) {
341 u8 id = readb(devbase + pos + PCI_CAP_LIST_ID); 341 u8 id = readb(devbase + pos + PCI_CAP_LIST_ID);
342 if (id == PCI_CAP_ID_HT_IRQCONF) { 342 if (id == PCI_CAP_ID_HT) {
343 id = readb(devbase + pos + 3); 343 id = readb(devbase + pos + 3);
344 if (id == 0x80) 344 if (id == 0x80)
345 break; 345 break;
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 8fa10cf661a8..fdd9e7b66244 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -953,6 +953,9 @@ config NR_CPUS
953config HIGHMEM 953config HIGHMEM
954 bool "High memory support" 954 bool "High memory support"
955 955
956config ARCH_POPULATES_NODE_MAP
957 def_bool y
958
956source kernel/Kconfig.hz 959source kernel/Kconfig.hz
957source kernel/Kconfig.preempt 960source kernel/Kconfig.preempt
958source "mm/Kconfig" 961source "mm/Kconfig"
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index 523392d460fa..410200046af1 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -358,8 +358,8 @@ void __init do_init_bootmem(void)
358 */ 358 */
359void __init paging_init(void) 359void __init paging_init(void)
360{ 360{
361 unsigned long zones_size[MAX_NR_ZONES], i; 361 unsigned long start_pfn, end_pfn;
362 362 unsigned long max_zone_pfns[MAX_NR_ZONES];
363#ifdef CONFIG_HIGHMEM 363#ifdef CONFIG_HIGHMEM
364 map_page(PKMAP_BASE, 0, 0); /* XXX gross */ 364 map_page(PKMAP_BASE, 0, 0); /* XXX gross */
365 pkmap_page_table = pte_offset_kernel(pmd_offset(pgd_offset_k 365 pkmap_page_table = pte_offset_kernel(pmd_offset(pgd_offset_k
@@ -369,19 +369,18 @@ void __init paging_init(void)
369 (KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN); 369 (KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN);
370 kmap_prot = PAGE_KERNEL; 370 kmap_prot = PAGE_KERNEL;
371#endif /* CONFIG_HIGHMEM */ 371#endif /* CONFIG_HIGHMEM */
372 372 /* All pages are DMA-able so we put them all in the DMA zone. */
373 /* 373 start_pfn = __pa(PAGE_OFFSET) >> PAGE_SHIFT;
374 * All pages are DMA-able so we put them all in the DMA zone. 374 end_pfn = start_pfn + (total_memory >> PAGE_SHIFT);
375 */ 375 add_active_range(0, start_pfn, end_pfn);
376 zones_size[ZONE_DMA] = total_lowmem >> PAGE_SHIFT;
377 for (i = 1; i < MAX_NR_ZONES; i++)
378 zones_size[i] = 0;
379 376
380#ifdef CONFIG_HIGHMEM 377#ifdef CONFIG_HIGHMEM
381 zones_size[ZONE_HIGHMEM] = (total_memory - total_lowmem) >> PAGE_SHIFT; 378 max_zone_pfns[0] = total_lowmem >> PAGE_SHIFT;
379 max_zone_pfns[1] = total_memory >> PAGE_SHIFT;
380#else
381 max_zone_pfns[0] = total_memory >> PAGE_SHIFT;
382#endif /* CONFIG_HIGHMEM */ 382#endif /* CONFIG_HIGHMEM */
383 383 free_area_init_nodes(max_zone_pfns);
384 free_area_init(zones_size);
385} 384}
386 385
387void __init mem_init(void) 386void __init mem_init(void)
diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c
index ab3b0765a64e..8aea3698a77b 100644
--- a/arch/s390/appldata/appldata_mem.c
+++ b/arch/s390/appldata/appldata_mem.c
@@ -117,8 +117,7 @@ static void appldata_get_mem_data(void *data)
117 mem_data->pgpgout = ev[PGPGOUT] >> 1; 117 mem_data->pgpgout = ev[PGPGOUT] >> 1;
118 mem_data->pswpin = ev[PSWPIN]; 118 mem_data->pswpin = ev[PSWPIN];
119 mem_data->pswpout = ev[PSWPOUT]; 119 mem_data->pswpout = ev[PSWPOUT];
120 mem_data->pgalloc = ev[PGALLOC_HIGH] + ev[PGALLOC_NORMAL] + 120 mem_data->pgalloc = ev[PGALLOC_NORMAL] + ev[PGALLOC_DMA];
121 ev[PGALLOC_DMA];
122 mem_data->pgfault = ev[PGFAULT]; 121 mem_data->pgfault = ev[PGFAULT];
123 mem_data->pgmajfault = ev[PGMAJFAULT]; 122 mem_data->pgmajfault = ev[PGMAJFAULT];
124 123
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index bdade5f2e325..813fc21358f9 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -91,7 +91,6 @@ static struct inode *hypfs_make_inode(struct super_block *sb, int mode)
91 ret->i_mode = mode; 91 ret->i_mode = mode;
92 ret->i_uid = hypfs_info->uid; 92 ret->i_uid = hypfs_info->uid;
93 ret->i_gid = hypfs_info->gid; 93 ret->i_gid = hypfs_info->gid;
94 ret->i_blksize = PAGE_CACHE_SIZE;
95 ret->i_blocks = 0; 94 ret->i_blocks = 0;
96 ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME; 95 ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME;
97 if (mode & S_IFDIR) 96 if (mode & S_IFDIR)
@@ -104,13 +103,13 @@ static struct inode *hypfs_make_inode(struct super_block *sb, int mode)
104 103
105static void hypfs_drop_inode(struct inode *inode) 104static void hypfs_drop_inode(struct inode *inode)
106{ 105{
107 kfree(inode->u.generic_ip); 106 kfree(inode->i_private);
108 generic_delete_inode(inode); 107 generic_delete_inode(inode);
109} 108}
110 109
111static int hypfs_open(struct inode *inode, struct file *filp) 110static int hypfs_open(struct inode *inode, struct file *filp)
112{ 111{
113 char *data = filp->f_dentry->d_inode->u.generic_ip; 112 char *data = filp->f_dentry->d_inode->i_private;
114 struct hypfs_sb_info *fs_info; 113 struct hypfs_sb_info *fs_info;
115 114
116 if (filp->f_mode & FMODE_WRITE) { 115 if (filp->f_mode & FMODE_WRITE) {
@@ -352,7 +351,7 @@ static struct dentry *hypfs_create_file(struct super_block *sb,
352 parent->d_inode->i_nlink++; 351 parent->d_inode->i_nlink++;
353 } else 352 } else
354 BUG(); 353 BUG();
355 inode->u.generic_ip = data; 354 inode->i_private = data;
356 d_instantiate(dentry, inode); 355 d_instantiate(dentry, inode);
357 dget(dentry); 356 dget(dentry);
358 return dentry; 357 return dentry;
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 785c9f70ac98..91b2884fa5c4 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -708,7 +708,7 @@ asmlinkage long sys32_sendfile64(int out_fd, int in_fd,
708 return ret; 708 return ret;
709} 709}
710 710
711#ifdef CONFIG_SYSCTL 711#ifdef CONFIG_SYSCTL_SYSCALL
712struct __sysctl_args32 { 712struct __sysctl_args32 {
713 u32 name; 713 u32 name;
714 int nlen; 714 int nlen;
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index 7ba20922a535..43f3d0c7e132 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -603,7 +603,7 @@ debug_open(struct inode *inode, struct file *file)
603 debug_info_t *debug_info, *debug_info_snapshot; 603 debug_info_t *debug_info, *debug_info_snapshot;
604 604
605 down(&debug_lock); 605 down(&debug_lock);
606 debug_info = (struct debug_info*)file->f_dentry->d_inode->u.generic_ip; 606 debug_info = file->f_dentry->d_inode->i_private;
607 /* find debug view */ 607 /* find debug view */
608 for (i = 0; i < DEBUG_MAX_VIEWS; i++) { 608 for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
609 if (!debug_info->views[i]) 609 if (!debug_info->views[i])
diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c
index de83f38288d0..d9428a0fc8fb 100644
--- a/arch/s390/kernel/stacktrace.c
+++ b/arch/s390/kernel/stacktrace.c
@@ -59,9 +59,7 @@ static inline unsigned long save_context_stack(struct stack_trace *trace,
59 } 59 }
60} 60}
61 61
62void save_stack_trace(struct stack_trace *trace, 62void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
63 struct task_struct *task, int all_contexts,
64 unsigned int skip)
65{ 63{
66 register unsigned long sp asm ("15"); 64 register unsigned long sp asm ("15");
67 unsigned long orig_sp; 65 unsigned long orig_sp;
@@ -69,22 +67,23 @@ void save_stack_trace(struct stack_trace *trace,
69 sp &= PSW_ADDR_INSN; 67 sp &= PSW_ADDR_INSN;
70 orig_sp = sp; 68 orig_sp = sp;
71 69
72 sp = save_context_stack(trace, &skip, sp, 70 sp = save_context_stack(trace, &trace->skip, sp,
73 S390_lowcore.panic_stack - PAGE_SIZE, 71 S390_lowcore.panic_stack - PAGE_SIZE,
74 S390_lowcore.panic_stack); 72 S390_lowcore.panic_stack);
75 if ((sp != orig_sp) && !all_contexts) 73 if ((sp != orig_sp) && !trace->all_contexts)
76 return; 74 return;
77 sp = save_context_stack(trace, &skip, sp, 75 sp = save_context_stack(trace, &trace->skip, sp,
78 S390_lowcore.async_stack - ASYNC_SIZE, 76 S390_lowcore.async_stack - ASYNC_SIZE,
79 S390_lowcore.async_stack); 77 S390_lowcore.async_stack);
80 if ((sp != orig_sp) && !all_contexts) 78 if ((sp != orig_sp) && !trace->all_contexts)
81 return; 79 return;
82 if (task) 80 if (task)
83 save_context_stack(trace, &skip, sp, 81 save_context_stack(trace, &trace->skip, sp,
84 (unsigned long) task_stack_page(task), 82 (unsigned long) task_stack_page(task),
85 (unsigned long) task_stack_page(task) + THREAD_SIZE); 83 (unsigned long) task_stack_page(task) + THREAD_SIZE);
86 else 84 else
87 save_context_stack(trace, &skip, sp, S390_lowcore.thread_info, 85 save_context_stack(trace, &trace->skip, sp,
86 S390_lowcore.thread_info,
88 S390_lowcore.thread_info + THREAD_SIZE); 87 S390_lowcore.thread_info + THREAD_SIZE);
89 return; 88 return;
90} 89}
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index 786a44dba5bf..607f50ead1fd 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -15,6 +15,8 @@
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/sysctl.h> 16#include <linux/sysctl.h>
17#include <linux/ctype.h> 17#include <linux/ctype.h>
18#include <linux/swap.h>
19#include <linux/kthread.h>
18 20
19#include <asm/pgalloc.h> 21#include <asm/pgalloc.h>
20#include <asm/uaccess.h> 22#include <asm/uaccess.h>
@@ -34,18 +36,18 @@ struct cmm_page_array {
34 unsigned long pages[CMM_NR_PAGES]; 36 unsigned long pages[CMM_NR_PAGES];
35}; 37};
36 38
37static long cmm_pages = 0; 39static long cmm_pages;
38static long cmm_timed_pages = 0; 40static long cmm_timed_pages;
39static volatile long cmm_pages_target = 0; 41static volatile long cmm_pages_target;
40static volatile long cmm_timed_pages_target = 0; 42static volatile long cmm_timed_pages_target;
41static long cmm_timeout_pages = 0; 43static long cmm_timeout_pages;
42static long cmm_timeout_seconds = 0; 44static long cmm_timeout_seconds;
43 45
44static struct cmm_page_array *cmm_page_list = NULL; 46static struct cmm_page_array *cmm_page_list;
45static struct cmm_page_array *cmm_timed_page_list = NULL; 47static struct cmm_page_array *cmm_timed_page_list;
48static DEFINE_SPINLOCK(cmm_lock);
46 49
47static unsigned long cmm_thread_active = 0; 50static struct task_struct *cmm_thread_ptr;
48static struct work_struct cmm_thread_starter;
49static wait_queue_head_t cmm_thread_wait; 51static wait_queue_head_t cmm_thread_wait;
50static struct timer_list cmm_timer; 52static struct timer_list cmm_timer;
51 53
@@ -53,71 +55,100 @@ static void cmm_timer_fn(unsigned long);
53static void cmm_set_timer(void); 55static void cmm_set_timer(void);
54 56
55static long 57static long
56cmm_alloc_pages(long pages, long *counter, struct cmm_page_array **list) 58cmm_alloc_pages(long nr, long *counter, struct cmm_page_array **list)
57{ 59{
58 struct cmm_page_array *pa; 60 struct cmm_page_array *pa, *npa;
59 unsigned long page; 61 unsigned long addr;
60 62
61 pa = *list; 63 while (nr) {
62 while (pages) { 64 addr = __get_free_page(GFP_NOIO);
63 page = __get_free_page(GFP_NOIO); 65 if (!addr)
64 if (!page)
65 break; 66 break;
67 spin_lock(&cmm_lock);
68 pa = *list;
66 if (!pa || pa->index >= CMM_NR_PAGES) { 69 if (!pa || pa->index >= CMM_NR_PAGES) {
67 /* Need a new page for the page list. */ 70 /* Need a new page for the page list. */
68 pa = (struct cmm_page_array *) 71 spin_unlock(&cmm_lock);
72 npa = (struct cmm_page_array *)
69 __get_free_page(GFP_NOIO); 73 __get_free_page(GFP_NOIO);
70 if (!pa) { 74 if (!npa) {
71 free_page(page); 75 free_page(addr);
72 break; 76 break;
73 } 77 }
74 pa->next = *list; 78 spin_lock(&cmm_lock);
75 pa->index = 0; 79 pa = *list;
76 *list = pa; 80 if (!pa || pa->index >= CMM_NR_PAGES) {
81 npa->next = pa;
82 npa->index = 0;
83 pa = npa;
84 *list = pa;
85 } else
86 free_page((unsigned long) npa);
77 } 87 }
78 diag10(page); 88 diag10(addr);
79 pa->pages[pa->index++] = page; 89 pa->pages[pa->index++] = addr;
80 (*counter)++; 90 (*counter)++;
81 pages--; 91 spin_unlock(&cmm_lock);
92 nr--;
82 } 93 }
83 return pages; 94 return nr;
84} 95}
85 96
86static void 97static long
87cmm_free_pages(long pages, long *counter, struct cmm_page_array **list) 98cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
88{ 99{
89 struct cmm_page_array *pa; 100 struct cmm_page_array *pa;
90 unsigned long page; 101 unsigned long addr;
91 102
103 spin_lock(&cmm_lock);
92 pa = *list; 104 pa = *list;
93 while (pages) { 105 while (nr) {
94 if (!pa || pa->index <= 0) 106 if (!pa || pa->index <= 0)
95 break; 107 break;
96 page = pa->pages[--pa->index]; 108 addr = pa->pages[--pa->index];
97 if (pa->index == 0) { 109 if (pa->index == 0) {
98 pa = pa->next; 110 pa = pa->next;
99 free_page((unsigned long) *list); 111 free_page((unsigned long) *list);
100 *list = pa; 112 *list = pa;
101 } 113 }
102 free_page(page); 114 free_page(addr);
103 (*counter)--; 115 (*counter)--;
104 pages--; 116 nr--;
105 } 117 }
118 spin_unlock(&cmm_lock);
119 return nr;
106} 120}
107 121
122static int cmm_oom_notify(struct notifier_block *self,
123 unsigned long dummy, void *parm)
124{
125 unsigned long *freed = parm;
126 long nr = 256;
127
128 nr = cmm_free_pages(nr, &cmm_timed_pages, &cmm_timed_page_list);
129 if (nr > 0)
130 nr = cmm_free_pages(nr, &cmm_pages, &cmm_page_list);
131 cmm_pages_target = cmm_pages;
132 cmm_timed_pages_target = cmm_timed_pages;
133 *freed += 256 - nr;
134 return NOTIFY_OK;
135}
136
137static struct notifier_block cmm_oom_nb = {
138 .notifier_call = cmm_oom_notify
139};
140
108static int 141static int
109cmm_thread(void *dummy) 142cmm_thread(void *dummy)
110{ 143{
111 int rc; 144 int rc;
112 145
113 daemonize("cmmthread");
114 while (1) { 146 while (1) {
115 rc = wait_event_interruptible(cmm_thread_wait, 147 rc = wait_event_interruptible(cmm_thread_wait,
116 (cmm_pages != cmm_pages_target || 148 (cmm_pages != cmm_pages_target ||
117 cmm_timed_pages != cmm_timed_pages_target)); 149 cmm_timed_pages != cmm_timed_pages_target ||
118 if (rc == -ERESTARTSYS) { 150 kthread_should_stop()));
119 /* Got kill signal. End thread. */ 151 if (kthread_should_stop() || rc == -ERESTARTSYS) {
120 clear_bit(0, &cmm_thread_active);
121 cmm_pages_target = cmm_pages; 152 cmm_pages_target = cmm_pages;
122 cmm_timed_pages_target = cmm_timed_pages; 153 cmm_timed_pages_target = cmm_timed_pages;
123 break; 154 break;
@@ -143,16 +174,8 @@ cmm_thread(void *dummy)
143} 174}
144 175
145static void 176static void
146cmm_start_thread(void)
147{
148 kernel_thread(cmm_thread, NULL, 0);
149}
150
151static void
152cmm_kick_thread(void) 177cmm_kick_thread(void)
153{ 178{
154 if (!test_and_set_bit(0, &cmm_thread_active))
155 schedule_work(&cmm_thread_starter);
156 wake_up(&cmm_thread_wait); 179 wake_up(&cmm_thread_wait);
157} 180}
158 181
@@ -177,21 +200,21 @@ cmm_set_timer(void)
177static void 200static void
178cmm_timer_fn(unsigned long ignored) 201cmm_timer_fn(unsigned long ignored)
179{ 202{
180 long pages; 203 long nr;
181 204
182 pages = cmm_timed_pages_target - cmm_timeout_pages; 205 nr = cmm_timed_pages_target - cmm_timeout_pages;
183 if (pages < 0) 206 if (nr < 0)
184 cmm_timed_pages_target = 0; 207 cmm_timed_pages_target = 0;
185 else 208 else
186 cmm_timed_pages_target = pages; 209 cmm_timed_pages_target = nr;
187 cmm_kick_thread(); 210 cmm_kick_thread();
188 cmm_set_timer(); 211 cmm_set_timer();
189} 212}
190 213
191void 214void
192cmm_set_pages(long pages) 215cmm_set_pages(long nr)
193{ 216{
194 cmm_pages_target = pages; 217 cmm_pages_target = nr;
195 cmm_kick_thread(); 218 cmm_kick_thread();
196} 219}
197 220
@@ -202,9 +225,9 @@ cmm_get_pages(void)
202} 225}
203 226
204void 227void
205cmm_add_timed_pages(long pages) 228cmm_add_timed_pages(long nr)
206{ 229{
207 cmm_timed_pages_target += pages; 230 cmm_timed_pages_target += nr;
208 cmm_kick_thread(); 231 cmm_kick_thread();
209} 232}
210 233
@@ -215,9 +238,9 @@ cmm_get_timed_pages(void)
215} 238}
216 239
217void 240void
218cmm_set_timeout(long pages, long seconds) 241cmm_set_timeout(long nr, long seconds)
219{ 242{
220 cmm_timeout_pages = pages; 243 cmm_timeout_pages = nr;
221 cmm_timeout_seconds = seconds; 244 cmm_timeout_seconds = seconds;
222 cmm_set_timer(); 245 cmm_set_timer();
223} 246}
@@ -245,7 +268,7 @@ cmm_pages_handler(ctl_table *ctl, int write, struct file *filp,
245 void __user *buffer, size_t *lenp, loff_t *ppos) 268 void __user *buffer, size_t *lenp, loff_t *ppos)
246{ 269{
247 char buf[16], *p; 270 char buf[16], *p;
248 long pages; 271 long nr;
249 int len; 272 int len;
250 273
251 if (!*lenp || (*ppos && !write)) { 274 if (!*lenp || (*ppos && !write)) {
@@ -260,17 +283,17 @@ cmm_pages_handler(ctl_table *ctl, int write, struct file *filp,
260 return -EFAULT; 283 return -EFAULT;
261 buf[sizeof(buf) - 1] = '\0'; 284 buf[sizeof(buf) - 1] = '\0';
262 cmm_skip_blanks(buf, &p); 285 cmm_skip_blanks(buf, &p);
263 pages = simple_strtoul(p, &p, 0); 286 nr = simple_strtoul(p, &p, 0);
264 if (ctl == &cmm_table[0]) 287 if (ctl == &cmm_table[0])
265 cmm_set_pages(pages); 288 cmm_set_pages(nr);
266 else 289 else
267 cmm_add_timed_pages(pages); 290 cmm_add_timed_pages(nr);
268 } else { 291 } else {
269 if (ctl == &cmm_table[0]) 292 if (ctl == &cmm_table[0])
270 pages = cmm_get_pages(); 293 nr = cmm_get_pages();
271 else 294 else
272 pages = cmm_get_timed_pages(); 295 nr = cmm_get_timed_pages();
273 len = sprintf(buf, "%ld\n", pages); 296 len = sprintf(buf, "%ld\n", nr);
274 if (len > *lenp) 297 if (len > *lenp)
275 len = *lenp; 298 len = *lenp;
276 if (copy_to_user(buffer, buf, len)) 299 if (copy_to_user(buffer, buf, len))
@@ -286,7 +309,7 @@ cmm_timeout_handler(ctl_table *ctl, int write, struct file *filp,
286 void __user *buffer, size_t *lenp, loff_t *ppos) 309 void __user *buffer, size_t *lenp, loff_t *ppos)
287{ 310{
288 char buf[64], *p; 311 char buf[64], *p;
289 long pages, seconds; 312 long nr, seconds;
290 int len; 313 int len;
291 314
292 if (!*lenp || (*ppos && !write)) { 315 if (!*lenp || (*ppos && !write)) {
@@ -301,10 +324,10 @@ cmm_timeout_handler(ctl_table *ctl, int write, struct file *filp,
301 return -EFAULT; 324 return -EFAULT;
302 buf[sizeof(buf) - 1] = '\0'; 325 buf[sizeof(buf) - 1] = '\0';
303 cmm_skip_blanks(buf, &p); 326 cmm_skip_blanks(buf, &p);
304 pages = simple_strtoul(p, &p, 0); 327 nr = simple_strtoul(p, &p, 0);
305 cmm_skip_blanks(p, &p); 328 cmm_skip_blanks(p, &p);
306 seconds = simple_strtoul(p, &p, 0); 329 seconds = simple_strtoul(p, &p, 0);
307 cmm_set_timeout(pages, seconds); 330 cmm_set_timeout(nr, seconds);
308 } else { 331 } else {
309 len = sprintf(buf, "%ld %ld\n", 332 len = sprintf(buf, "%ld %ld\n",
310 cmm_timeout_pages, cmm_timeout_seconds); 333 cmm_timeout_pages, cmm_timeout_seconds);
@@ -357,7 +380,7 @@ static struct ctl_table cmm_dir_table[] = {
357static void 380static void
358cmm_smsg_target(char *from, char *msg) 381cmm_smsg_target(char *from, char *msg)
359{ 382{
360 long pages, seconds; 383 long nr, seconds;
361 384
362 if (strlen(sender) > 0 && strcmp(from, sender) != 0) 385 if (strlen(sender) > 0 && strcmp(from, sender) != 0)
363 return; 386 return;
@@ -366,27 +389,27 @@ cmm_smsg_target(char *from, char *msg)
366 if (strncmp(msg, "SHRINK", 6) == 0) { 389 if (strncmp(msg, "SHRINK", 6) == 0) {
367 if (!cmm_skip_blanks(msg + 6, &msg)) 390 if (!cmm_skip_blanks(msg + 6, &msg))
368 return; 391 return;
369 pages = simple_strtoul(msg, &msg, 0); 392 nr = simple_strtoul(msg, &msg, 0);
370 cmm_skip_blanks(msg, &msg); 393 cmm_skip_blanks(msg, &msg);
371 if (*msg == '\0') 394 if (*msg == '\0')
372 cmm_set_pages(pages); 395 cmm_set_pages(nr);
373 } else if (strncmp(msg, "RELEASE", 7) == 0) { 396 } else if (strncmp(msg, "RELEASE", 7) == 0) {
374 if (!cmm_skip_blanks(msg + 7, &msg)) 397 if (!cmm_skip_blanks(msg + 7, &msg))
375 return; 398 return;
376 pages = simple_strtoul(msg, &msg, 0); 399 nr = simple_strtoul(msg, &msg, 0);
377 cmm_skip_blanks(msg, &msg); 400 cmm_skip_blanks(msg, &msg);
378 if (*msg == '\0') 401 if (*msg == '\0')
379 cmm_add_timed_pages(pages); 402 cmm_add_timed_pages(nr);
380 } else if (strncmp(msg, "REUSE", 5) == 0) { 403 } else if (strncmp(msg, "REUSE", 5) == 0) {
381 if (!cmm_skip_blanks(msg + 5, &msg)) 404 if (!cmm_skip_blanks(msg + 5, &msg))
382 return; 405 return;
383 pages = simple_strtoul(msg, &msg, 0); 406 nr = simple_strtoul(msg, &msg, 0);
384 if (!cmm_skip_blanks(msg, &msg)) 407 if (!cmm_skip_blanks(msg, &msg))
385 return; 408 return;
386 seconds = simple_strtoul(msg, &msg, 0); 409 seconds = simple_strtoul(msg, &msg, 0);
387 cmm_skip_blanks(msg, &msg); 410 cmm_skip_blanks(msg, &msg);
388 if (*msg == '\0') 411 if (*msg == '\0')
389 cmm_set_timeout(pages, seconds); 412 cmm_set_timeout(nr, seconds);
390 } 413 }
391} 414}
392#endif 415#endif
@@ -396,21 +419,49 @@ struct ctl_table_header *cmm_sysctl_header;
396static int 419static int
397cmm_init (void) 420cmm_init (void)
398{ 421{
422 int rc = -ENOMEM;
423
399#ifdef CONFIG_CMM_PROC 424#ifdef CONFIG_CMM_PROC
400 cmm_sysctl_header = register_sysctl_table(cmm_dir_table, 1); 425 cmm_sysctl_header = register_sysctl_table(cmm_dir_table, 1);
426 if (!cmm_sysctl_header)
427 goto out;
401#endif 428#endif
402#ifdef CONFIG_CMM_IUCV 429#ifdef CONFIG_CMM_IUCV
403 smsg_register_callback(SMSG_PREFIX, cmm_smsg_target); 430 rc = smsg_register_callback(SMSG_PREFIX, cmm_smsg_target);
431 if (rc < 0)
432 goto out_smsg;
404#endif 433#endif
405 INIT_WORK(&cmm_thread_starter, (void *) cmm_start_thread, NULL); 434 rc = register_oom_notifier(&cmm_oom_nb);
435 if (rc < 0)
436 goto out_oom_notify;
406 init_waitqueue_head(&cmm_thread_wait); 437 init_waitqueue_head(&cmm_thread_wait);
407 init_timer(&cmm_timer); 438 init_timer(&cmm_timer);
408 return 0; 439 cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread");
440 rc = IS_ERR(cmm_thread_ptr) ? PTR_ERR(cmm_thread_ptr) : 0;
441 if (!rc)
442 goto out;
443 /*
444 * kthread_create failed. undo all the stuff from above again.
445 */
446 unregister_oom_notifier(&cmm_oom_nb);
447
448out_oom_notify:
449#ifdef CONFIG_CMM_IUCV
450 smsg_unregister_callback(SMSG_PREFIX, cmm_smsg_target);
451out_smsg:
452#endif
453#ifdef CONFIG_CMM_PROC
454 unregister_sysctl_table(cmm_sysctl_header);
455#endif
456out:
457 return rc;
409} 458}
410 459
411static void 460static void
412cmm_exit(void) 461cmm_exit(void)
413{ 462{
463 kthread_stop(cmm_thread_ptr);
464 unregister_oom_notifier(&cmm_oom_nb);
414 cmm_free_pages(cmm_pages, &cmm_pages, &cmm_page_list); 465 cmm_free_pages(cmm_pages, &cmm_pages, &cmm_page_list);
415 cmm_free_pages(cmm_timed_pages, &cmm_timed_pages, &cmm_timed_page_list); 466 cmm_free_pages(cmm_timed_pages, &cmm_timed_pages, &cmm_timed_page_list);
416#ifdef CONFIG_CMM_PROC 467#ifdef CONFIG_CMM_PROC
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 1a0db1d4c952..1cc5c9b27bfd 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -8,6 +8,7 @@ mainmenu "Linux/SuperH Kernel Configuration"
8config SUPERH 8config SUPERH
9 bool 9 bool
10 default y 10 default y
11 select EMBEDDED
11 help 12 help
12 The SuperH is a RISC processor targeted for use in embedded systems 13 The SuperH is a RISC processor targeted for use in embedded systems
13 and consumer electronics; it was also used in the Sega Dreamcast 14 and consumer electronics; it was also used in the Sega Dreamcast
@@ -51,18 +52,23 @@ source "init/Kconfig"
51 52
52menu "System type" 53menu "System type"
53 54
55config SOLUTION_ENGINE
56 bool
57
54choice 58choice
55 prompt "SuperH system type" 59 prompt "SuperH system type"
56 default SH_UNKNOWN 60 default SH_UNKNOWN
57 61
58config SH_SOLUTION_ENGINE 62config SH_SOLUTION_ENGINE
59 bool "SolutionEngine" 63 bool "SolutionEngine"
64 select SOLUTION_ENGINE
60 help 65 help
61 Select SolutionEngine if configuring for a Hitachi SH7709 66 Select SolutionEngine if configuring for a Hitachi SH7709
62 or SH7750 evaluation board. 67 or SH7750 evaluation board.
63 68
64config SH_7751_SOLUTION_ENGINE 69config SH_7751_SOLUTION_ENGINE
65 bool "SolutionEngine7751" 70 bool "SolutionEngine7751"
71 select SOLUTION_ENGINE
66 select CPU_SUBTYPE_SH7751 72 select CPU_SUBTYPE_SH7751
67 help 73 help
68 Select 7751 SolutionEngine if configuring for a Hitachi SH7751 74 Select 7751 SolutionEngine if configuring for a Hitachi SH7751
@@ -70,17 +76,27 @@ config SH_7751_SOLUTION_ENGINE
70 76
71config SH_7300_SOLUTION_ENGINE 77config SH_7300_SOLUTION_ENGINE
72 bool "SolutionEngine7300" 78 bool "SolutionEngine7300"
79 select SOLUTION_ENGINE
73 select CPU_SUBTYPE_SH7300 80 select CPU_SUBTYPE_SH7300
74 help 81 help
75 Select 7300 SolutionEngine if configuring for a Hitachi SH7300(SH-Mobile V) 82 Select 7300 SolutionEngine if configuring for a Hitachi
76 evaluation board. 83 SH7300(SH-Mobile V) evaluation board.
84
85config SH_7343_SOLUTION_ENGINE
86 bool "SolutionEngine7343"
87 select SOLUTION_ENGINE
88 select CPU_SUBTYPE_SH7343
89 help
90 Select 7343 SolutionEngine if configuring for a Hitachi
91 SH7343 (SH-Mobile 3AS) evaluation board.
77 92
78config SH_73180_SOLUTION_ENGINE 93config SH_73180_SOLUTION_ENGINE
79 bool "SolutionEngine73180" 94 bool "SolutionEngine73180"
80 select CPU_SUBTYPE_SH73180 95 select SOLUTION_ENGINE
81 help 96 select CPU_SUBTYPE_SH73180
82 Select 73180 SolutionEngine if configuring for a Hitachi SH73180(SH-Mobile 3) 97 help
83 evaluation board. 98 Select 73180 SolutionEngine if configuring for a Hitachi
99 SH73180(SH-Mobile 3) evaluation board.
84 100
85config SH_7751_SYSTEMH 101config SH_7751_SYSTEMH
86 bool "SystemH7751R" 102 bool "SystemH7751R"
@@ -89,12 +105,6 @@ config SH_7751_SYSTEMH
89 Select SystemH if you are configuring for a Renesas SystemH 105 Select SystemH if you are configuring for a Renesas SystemH
90 7751R evaluation board. 106 7751R evaluation board.
91 107
92config SH_STB1_HARP
93 bool "STB1_Harp"
94
95config SH_STB1_OVERDRIVE
96 bool "STB1_Overdrive"
97
98config SH_HP6XX 108config SH_HP6XX
99 bool "HP6XX" 109 bool "HP6XX"
100 help 110 help
@@ -102,19 +112,6 @@ config SH_HP6XX
102 More information (hardware only) at 112 More information (hardware only) at
103 <http://www.hp.com/jornada/>. 113 <http://www.hp.com/jornada/>.
104 114
105config SH_CQREEK
106 bool "CqREEK"
107 help
108 Select CqREEK if configuring for a CqREEK SH7708 or SH7750.
109 More information at
110 <http://sources.redhat.com/ecos/hardware.html#SuperH>.
111
112config SH_DMIDA
113 bool "DMIDA"
114 help
115 Select DMIDA if configuring for a DataMyte 4000 Industrial
116 Digital Assistant. More information at <http://www.dmida.com/>.
117
118config SH_EC3104 115config SH_EC3104
119 bool "EC3104" 116 bool "EC3104"
120 help 117 help
@@ -136,25 +133,9 @@ config SH_DREAMCAST
136 <http://www.m17n.org/linux-sh/dreamcast/>. There is a 133 <http://www.m17n.org/linux-sh/dreamcast/>. There is a
137 Dreamcast project is at <http://linuxdc.sourceforge.net/>. 134 Dreamcast project is at <http://linuxdc.sourceforge.net/>.
138 135
139config SH_CAT68701
140 bool "CAT68701"
141
142config SH_BIGSUR 136config SH_BIGSUR
143 bool "BigSur" 137 bool "BigSur"
144 138
145config SH_SH2000
146 bool "SH2000"
147 select CPU_SUBTYPE_SH7709
148 help
149 SH-2000 is a single-board computer based around SH7709A chip
150 intended for embedded applications.
151 It has an Ethernet interface (CS8900A), direct connected
152 Compact Flash socket, three serial ports and PC-104 bus.
153 More information at <http://sh2000.sh-linux.org>.
154
155config SH_ADX
156 bool "ADX"
157
158config SH_MPC1211 139config SH_MPC1211
159 bool "Interface MPC1211" 140 bool "Interface MPC1211"
160 help 141 help
@@ -184,6 +165,13 @@ config SH_HS7751RVOIP
184 Select HS7751RVOIP if configuring for a Renesas Technology 165 Select HS7751RVOIP if configuring for a Renesas Technology
185 Sales VoIP board. 166 Sales VoIP board.
186 167
168config SH_7710VOIPGW
169 bool "SH7710-VOIP-GW"
170 select CPU_SUBTYPE_SH7710
171 help
172 Select this option to build a kernel for the SH7710 based
173 VOIP GW.
174
187config SH_RTS7751R2D 175config SH_RTS7751R2D
188 bool "RTS7751R2D" 176 bool "RTS7751R2D"
189 select CPU_SUBTYPE_SH7751R 177 select CPU_SUBTYPE_SH7751R
@@ -222,6 +210,12 @@ config SH_TITAN
222 Select Titan if you are configuring for a Nimble Microsystems 210 Select Titan if you are configuring for a Nimble Microsystems
223 NetEngine NP51R. 211 NetEngine NP51R.
224 212
213config SH_SHMIN
214 bool "SHMIN"
215 select CPU_SUBTYPE_SH7706
216 help
217 Select SHMIN if configureing for the SHMIN board
218
225config SH_UNKNOWN 219config SH_UNKNOWN
226 bool "BareCPU" 220 bool "BareCPU"
227 help 221 help
@@ -238,35 +232,9 @@ endchoice
238 232
239source "arch/sh/mm/Kconfig" 233source "arch/sh/mm/Kconfig"
240 234
241config MEMORY_START
242 hex "Physical memory start address"
243 default "0x08000000"
244 ---help---
245 Computers built with Hitachi SuperH processors always
246 map the ROM starting at address zero. But the processor
247 does not specify the range that RAM takes.
248
249 The physical memory (RAM) start address will be automatically
250 set to 08000000. Other platforms, such as the Solution Engine
251 boards typically map RAM at 0C000000.
252
253 Tweak this only when porting to a new machine which does not
254 already have a defconfig. Changing it from the known correct
255 value on any of the known systems will only lead to disaster.
256
257config MEMORY_SIZE
258 hex "Physical memory size"
259 default "0x00400000"
260 help
261 This sets the default memory size assumed by your SH kernel. It can
262 be overridden as normal by the 'mem=' argument on the kernel command
263 line. If unsure, consult your board specifications or just leave it
264 as 0x00400000 which was the default value before this became
265 configurable.
266
267config CF_ENABLER 235config CF_ENABLER
268 bool "Compact Flash Enabler support" 236 bool "Compact Flash Enabler support"
269 depends on SH_ADX || SH_SOLUTION_ENGINE || SH_UNKNOWN || SH_CAT68701 || SH_SH03 237 depends on SH_SOLUTION_ENGINE || SH_UNKNOWN || SH_SH03
270 ---help--- 238 ---help---
271 Compact Flash is a small, removable mass storage device introduced 239 Compact Flash is a small, removable mass storage device introduced
272 in 1994 originally as a PCMCIA device. If you say `Y' here, you 240 in 1994 originally as a PCMCIA device. If you say `Y' here, you
@@ -294,7 +262,7 @@ config CF_AREA5
294 - "Area5" if CompactFlash is connected to Area 5 (0x14000000) 262 - "Area5" if CompactFlash is connected to Area 5 (0x14000000)
295 - "Area6" if it is connected to Area 6 (0x18000000) 263 - "Area6" if it is connected to Area 6 (0x18000000)
296 264
297 "Area6" will work for most boards. For ADX, select "Area5". 265 "Area6" will work for most boards.
298 266
299config CF_AREA6 267config CF_AREA6
300 bool "Area6" 268 bool "Area6"
@@ -316,19 +284,6 @@ config CPU_LITTLE_ENDIAN
316 endian byte order. These modes require different kernels. Say Y if 284 endian byte order. These modes require different kernels. Say Y if
317 your machine is little endian, N if it's a big endian machine. 285 your machine is little endian, N if it's a big endian machine.
318 286
319# The SH7750 RTC module is disabled in the Dreamcast
320config SH_RTC
321 bool
322 depends on !SH_DREAMCAST && !SH_SATURN && !SH_7300_SOLUTION_ENGINE && \
323 !SH_73180_SOLUTION_ENGINE && !SH_LANDISK && \
324 !SH_R7780RP
325 default y
326 help
327 Selecting this option will allow the Linux kernel to emulate
328 PC's RTC.
329
330 If unsure, say N.
331
332config SH_FPU 287config SH_FPU
333 bool "FPU support" 288 bool "FPU support"
334 depends on !CPU_SH3 289 depends on !CPU_SH3
@@ -339,14 +294,22 @@ config SH_FPU
339 294
340 This option must be set in order to enable the FPU. 295 This option must be set in order to enable the FPU.
341 296
297config SH_FPU_EMU
298 bool "FPU emulation support"
299 depends on !SH_FPU && EXPERIMENTAL
300 default n
301 help
302 Selecting this option will enable support for software FPU emulation.
303 Most SH-3 users will want to say Y here, whereas most SH-4 users will
304 want to say N.
305
342config SH_DSP 306config SH_DSP
343 bool "DSP support" 307 bool "DSP support"
344 depends on !CPU_SH4 308 default y if SH4AL_DSP || !CPU_SH4
345 default y 309 default n
346 help 310 help
347 Selecting this option will enable support for SH processors that 311 Selecting this option will enable support for SH processors that
348 have DSP units (ie, SH2-DSP and SH3-DSP). It is safe to say Y here 312 have DSP units (ie, SH2-DSP, SH3-DSP, and SH4AL-DSP).
349 by default, as the existance of the DSP will be probed at runtime.
350 313
351 This option must be set in order to enable the DSP. 314 This option must be set in order to enable the DSP.
352 315
@@ -373,6 +336,9 @@ config CPU_HAS_INTEVT
373config CPU_HAS_PINT_IRQ 336config CPU_HAS_PINT_IRQ
374 bool 337 bool
375 338
339config CPU_HAS_MASKREG_IRQ
340 bool
341
376config CPU_HAS_INTC2_IRQ 342config CPU_HAS_INTC2_IRQ
377 bool 343 bool
378 344
@@ -400,16 +366,19 @@ config SH_TMU
400 366
401endmenu 367endmenu
402 368
403#source "arch/sh/boards/renesas/hs7751rvoip/Kconfig" 369source "arch/sh/boards/renesas/hs7751rvoip/Kconfig"
370
371source "arch/sh/boards/renesas/rts7751r2d/Kconfig"
404 372
405#source "arch/sh/boards/renesas/rts7751r2d/Kconfig" 373source "arch/sh/boards/renesas/r7780rp/Kconfig"
406 374
407config SH_PCLK_FREQ 375config SH_PCLK_FREQ
408 int "Peripheral clock frequency (in Hz)" 376 int "Peripheral clock frequency (in Hz)"
409 default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780 377 default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780
410 default "60000000" if CPU_SUBTYPE_SH7751 378 default "60000000" if CPU_SUBTYPE_SH7751
411 default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || CPU_SUBTYPE_SH7760 379 default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || \
412 default "27000000" if CPU_SUBTYPE_SH73180 380 CPU_SUBTYPE_SH7760
381 default "27000000" if CPU_SUBTYPE_SH73180 || CPU_SUBTYPE_SH7343
413 default "66000000" if CPU_SUBTYPE_SH4_202 382 default "66000000" if CPU_SUBTYPE_SH4_202
414 help 383 help
415 This option is used to specify the peripheral clock frequency. 384 This option is used to specify the peripheral clock frequency.
@@ -440,10 +409,8 @@ source "arch/sh/cchips/Kconfig"
440 409
441config HEARTBEAT 410config HEARTBEAT
442 bool "Heartbeat LED" 411 bool "Heartbeat LED"
443 depends on SH_MPC1211 || SH_SH03 || SH_CAT68701 || \ 412 depends on SH_MPC1211 || SH_SH03 || \
444 SH_STB1_HARP || SH_STB1_OVERDRIVE || SH_BIGSUR || \ 413 SH_BIGSUR || SOLUTION_ENGINE || \
445 SH_7751_SOLUTION_ENGINE || SH_7300_SOLUTION_ENGINE || \
446 SH_73180_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || \
447 SH_RTS7751R2D || SH_SH4202_MICRODEV || SH_LANDISK 414 SH_RTS7751R2D || SH_SH4202_MICRODEV || SH_LANDISK
448 help 415 help
449 Use the power-on LED on your machine as a load meter. The exact 416 Use the power-on LED on your machine as a load meter. The exact
@@ -459,6 +426,8 @@ config ISA_DMA_API
459 426
460menu "Kernel features" 427menu "Kernel features"
461 428
429source kernel/Kconfig.hz
430
462config KEXEC 431config KEXEC
463 bool "kexec system call (EXPERIMENTAL)" 432 bool "kexec system call (EXPERIMENTAL)"
464 depends on EXPERIMENTAL 433 depends on EXPERIMENTAL
@@ -476,10 +445,6 @@ config KEXEC
476 support. As of this writing the exact hardware interface is 445 support. As of this writing the exact hardware interface is
477 strongly in flux, so no good recommendation can be made. 446 strongly in flux, so no good recommendation can be made.
478 447
479config PREEMPT
480 bool "Preemptible Kernel (EXPERIMENTAL)"
481 depends on EXPERIMENTAL
482
483config SMP 448config SMP
484 bool "Symmetric multi-processing support" 449 bool "Symmetric multi-processing support"
485 ---help--- 450 ---help---
@@ -515,6 +480,8 @@ config NR_CPUS
515 This is purely to save memory - each supported CPU adds 480 This is purely to save memory - each supported CPU adds
516 approximately eight kilobytes to the kernel image. 481 approximately eight kilobytes to the kernel image.
517 482
483source "kernel/Kconfig.preempt"
484
518config CPU_HAS_SR_RB 485config CPU_HAS_SR_RB
519 bool "CPU has SR.RB" 486 bool "CPU has SR.RB"
520 depends on CPU_SH3 || CPU_SH4 487 depends on CPU_SH3 || CPU_SH4
@@ -636,6 +603,16 @@ source "fs/Kconfig.binfmt"
636 603
637endmenu 604endmenu
638 605
606menu "Power management options (EXPERIMENTAL)"
607depends on EXPERIMENTAL
608
609source kernel/power/Kconfig
610
611config APM
612 bool "Advanced Power Management Emulation"
613 depends on PM
614endmenu
615
639source "net/Kconfig" 616source "net/Kconfig"
640 617
641source "drivers/Kconfig" 618source "drivers/Kconfig"
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug
index 8fb31ab2c02c..48479e014dac 100644
--- a/arch/sh/Kconfig.debug
+++ b/arch/sh/Kconfig.debug
@@ -30,8 +30,35 @@ config EARLY_PRINTK
30 when the kernel may crash or hang before the serial console is 30 when the kernel may crash or hang before the serial console is
31 initialised. If unsure, say N. 31 initialised. If unsure, say N.
32 32
33config DEBUG_STACKOVERFLOW
34 bool "Check for stack overflows"
35 depends on DEBUG_KERNEL
36 help
37 This option will cause messages to be printed if free stack space
38 drops below a certain limit.
39
40config DEBUG_STACK_USAGE
41 bool "Stack utilization instrumentation"
42 depends on DEBUG_KERNEL
43 help
44 Enables the display of the minimum amount of free stack which each
45 task has ever had available in the sysrq-T and sysrq-P debug output.
46
47 This option will slow down process creation somewhat.
48
49config 4KSTACKS
50 bool "Use 4Kb for kernel stacks instead of 8Kb"
51 depends on DEBUG_KERNEL
52 help
53 If you say Y here the kernel will use a 4Kb stacksize for the
54 kernel stack attached to each process/thread. This facilitates
55 running more threads on a system and also reduces the pressure
56 on the VM subsystem for higher order allocations. This option
57 will also use IRQ stacks to compensate for the reduced stackspace.
58
33config KGDB 59config KGDB
34 bool "Include KGDB kernel debugger" 60 bool "Include KGDB kernel debugger"
61 select FRAME_POINTER
35 help 62 help
36 Include in-kernel hooks for kgdb, the Linux kernel source level 63 Include in-kernel hooks for kgdb, the Linux kernel source level
37 debugger. See <http://kgdb.sourceforge.net/> for more information. 64 debugger. See <http://kgdb.sourceforge.net/> for more information.
@@ -112,13 +139,4 @@ endchoice
112 139
113endmenu 140endmenu
114 141
115config FRAME_POINTER
116 bool "Compile the kernel with frame pointers"
117 default y if KGDB
118 help
119 If you say Y here the resulting kernel image will be slightly larger
120 and slower, but it will give very useful debugging information.
121 If you don't debug the kernel, you can say N, but we may not be able
122 to solve problems without frame pointers.
123
124endmenu 142endmenu
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index e467a450662b..26d62ff51a64 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -18,11 +18,13 @@ cflags-y := -mb
18cflags-$(CONFIG_CPU_LITTLE_ENDIAN) := -ml 18cflags-$(CONFIG_CPU_LITTLE_ENDIAN) := -ml
19 19
20isa-y := any 20isa-y := any
21isa-$(CONFIG_SH_DSP) := sh
21isa-$(CONFIG_CPU_SH2) := sh2 22isa-$(CONFIG_CPU_SH2) := sh2
23isa-$(CONFIG_CPU_SH2A) := sh2a
22isa-$(CONFIG_CPU_SH3) := sh3 24isa-$(CONFIG_CPU_SH3) := sh3
23isa-$(CONFIG_CPU_SH4) := sh4 25isa-$(CONFIG_CPU_SH4) := sh4
24isa-$(CONFIG_CPU_SH4A) := sh4a 26isa-$(CONFIG_CPU_SH4A) := sh4a
25isa-$(CONFIG_CPU_SH2A) := sh2a 27isa-$(CONFIG_CPU_SH4AL_DSP) := sh4al
26 28
27isa-$(CONFIG_SH_DSP) := $(isa-y)-dsp 29isa-$(CONFIG_SH_DSP) := $(isa-y)-dsp
28 30
@@ -30,9 +32,11 @@ ifndef CONFIG_MMU
30isa-y := $(isa-y)-nommu 32isa-y := $(isa-y)-nommu
31endif 33endif
32 34
35ifndef CONFIG_SH_DSP
33ifndef CONFIG_SH_FPU 36ifndef CONFIG_SH_FPU
34isa-y := $(isa-y)-nofpu 37isa-y := $(isa-y)-nofpu
35endif 38endif
39endif
36 40
37cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) 41cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),)
38 42
@@ -79,24 +83,19 @@ head-y := arch/sh/kernel/head.o arch/sh/kernel/init_task.o
79LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) 83LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
80 84
81core-y += arch/sh/kernel/ arch/sh/mm/ 85core-y += arch/sh/kernel/ arch/sh/mm/
86core-$(CONFIG_SH_FPU_EMU) += arch/sh/math-emu/
82 87
83# Boards 88# Boards
84machdir-$(CONFIG_SH_SOLUTION_ENGINE) := se/770x 89machdir-$(CONFIG_SH_SOLUTION_ENGINE) := se/770x
85machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se/7751 90machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se/7751
86machdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se/7300 91machdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se/7300
92machdir-$(CONFIG_SH_7343_SOLUTION_ENGINE) := se/7343
87machdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se/73180 93machdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se/73180
88machdir-$(CONFIG_SH_STB1_HARP) := harp
89machdir-$(CONFIG_SH_STB1_OVERDRIVE) := overdrive
90machdir-$(CONFIG_SH_HP6XX) := hp6xx 94machdir-$(CONFIG_SH_HP6XX) := hp6xx
91machdir-$(CONFIG_SH_CQREEK) := cqreek
92machdir-$(CONFIG_SH_DMIDA) := dmida
93machdir-$(CONFIG_SH_EC3104) := ec3104 95machdir-$(CONFIG_SH_EC3104) := ec3104
94machdir-$(CONFIG_SH_SATURN) := saturn 96machdir-$(CONFIG_SH_SATURN) := saturn
95machdir-$(CONFIG_SH_DREAMCAST) := dreamcast 97machdir-$(CONFIG_SH_DREAMCAST) := dreamcast
96machdir-$(CONFIG_SH_CAT68701) := cat68701
97machdir-$(CONFIG_SH_BIGSUR) := bigsur 98machdir-$(CONFIG_SH_BIGSUR) := bigsur
98machdir-$(CONFIG_SH_SH2000) := sh2000
99machdir-$(CONFIG_SH_ADX) := adx
100machdir-$(CONFIG_SH_MPC1211) := mpc1211 99machdir-$(CONFIG_SH_MPC1211) := mpc1211
101machdir-$(CONFIG_SH_SH03) := sh03 100machdir-$(CONFIG_SH_SH03) := sh03
102machdir-$(CONFIG_SH_SECUREEDGE5410) := snapgear 101machdir-$(CONFIG_SH_SECUREEDGE5410) := snapgear
@@ -104,16 +103,16 @@ machdir-$(CONFIG_SH_HS7751RVOIP) := renesas/hs7751rvoip
104machdir-$(CONFIG_SH_RTS7751R2D) := renesas/rts7751r2d 103machdir-$(CONFIG_SH_RTS7751R2D) := renesas/rts7751r2d
105machdir-$(CONFIG_SH_7751_SYSTEMH) := renesas/systemh 104machdir-$(CONFIG_SH_7751_SYSTEMH) := renesas/systemh
106machdir-$(CONFIG_SH_EDOSK7705) := renesas/edosk7705 105machdir-$(CONFIG_SH_EDOSK7705) := renesas/edosk7705
106machdir-$(CONFIG_SH_R7780RP) := renesas/r7780rp
107machdir-$(CONFIG_SH_7710VOIPGW) := renesas/sh7710voipgw
107machdir-$(CONFIG_SH_SH4202_MICRODEV) := superh/microdev 108machdir-$(CONFIG_SH_SH4202_MICRODEV) := superh/microdev
109machdir-$(CONFIG_SH_LANDISK) := landisk
110machdir-$(CONFIG_SH_TITAN) := titan
111machdir-$(CONFIG_SH_SHMIN) := shmin
108machdir-$(CONFIG_SH_UNKNOWN) := unknown 112machdir-$(CONFIG_SH_UNKNOWN) := unknown
109 113
110incdir-y := $(notdir $(machdir-y)) 114incdir-y := $(notdir $(machdir-y))
111 115incdir-$(CONFIG_SH_HP6XX) := hp6xx
112incdir-$(CONFIG_SH_SOLUTION_ENGINE) := se
113incdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se7751
114incdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se7300
115incdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se73180
116incdir-$(CONFIG_SH_HP600) := hp6xx
117 116
118ifneq ($(machdir-y),) 117ifneq ($(machdir-y),)
119core-y += arch/sh/boards/$(machdir-y)/ 118core-y += arch/sh/boards/$(machdir-y)/
@@ -137,17 +136,14 @@ boot := arch/sh/boot
137 136
138CPPFLAGS_vmlinux.lds := -traditional 137CPPFLAGS_vmlinux.lds := -traditional
139 138
140ifneq ($(KBUILD_SRC),)
141incdir-prefix := $(srctree)/include/asm-sh/ 139incdir-prefix := $(srctree)/include/asm-sh/
142else
143incdir-prefix :=
144endif
145 140
146# Update machine arch and proc symlinks if something which affects 141# Update machine arch and proc symlinks if something which affects
147# them changed. We use .arch and .mach to indicate when they were 142# them changed. We use .arch and .mach to indicate when they were
148# updated last, otherwise make uses the target directory mtime. 143# updated last, otherwise make uses the target directory mtime.
149 144
150include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/auto.conf 145include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) \
146 include/config/auto.conf FORCE
151 @echo ' SYMLINK include/asm-sh/cpu -> include/asm-sh/$(cpuincdir-y)' 147 @echo ' SYMLINK include/asm-sh/cpu -> include/asm-sh/$(cpuincdir-y)'
152 $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi 148 $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi
153 $(Q)ln -fsn $(incdir-prefix)$(cpuincdir-y) include/asm-sh/cpu 149 $(Q)ln -fsn $(incdir-prefix)$(cpuincdir-y) include/asm-sh/cpu
@@ -157,7 +153,8 @@ include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/auto.conf
157# don't, just reference the parent directory so the semantics are 153# don't, just reference the parent directory so the semantics are
158# kept roughly the same. 154# kept roughly the same.
159 155
160include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/auto.conf 156include/asm-sh/.mach: $(wildcard include/config/sh/*.h) \
157 include/config/auto.conf FORCE
161 @echo -n ' SYMLINK include/asm-sh/mach -> ' 158 @echo -n ' SYMLINK include/asm-sh/mach -> '
162 $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi 159 $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi
163 $(Q)if [ -d $(incdir-prefix)$(incdir-y) ]; then \ 160 $(Q)if [ -d $(incdir-prefix)$(incdir-y) ]; then \
@@ -170,7 +167,7 @@ include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/auto.conf
170 fi 167 fi
171 @touch $@ 168 @touch $@
172 169
173archprepare: maketools include/asm-sh/.cpu include/asm-sh/.mach 170archprepare: include/asm-sh/.cpu include/asm-sh/.mach maketools
174 171
175PHONY += maketools FORCE 172PHONY += maketools FORCE
176maketools: include/linux/version.h FORCE 173maketools: include/linux/version.h FORCE
@@ -191,4 +188,3 @@ CLEAN_FILES += include/asm-sh/machtypes.h
191define archhelp 188define archhelp
192 @echo ' zImage - Compressed kernel image (arch/sh/boot/zImage)' 189 @echo ' zImage - Compressed kernel image (arch/sh/boot/zImage)'
193endef 190endef
194
diff --git a/arch/sh/boards/adx/Makefile b/arch/sh/boards/adx/Makefile
deleted file mode 100644
index 5b1c531b3991..000000000000
--- a/arch/sh/boards/adx/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
1#
2# Makefile for ADX boards
3#
4
5obj-y := setup.o irq.o irq_maskreq.o
6
diff --git a/arch/sh/boards/adx/irq.c b/arch/sh/boards/adx/irq.c
deleted file mode 100644
index c6ca409dff98..000000000000
--- a/arch/sh/boards/adx/irq.c
+++ /dev/null
@@ -1,31 +0,0 @@
1/*
2 * linux/arch/sh/boards/adx/irq.c
3 *
4 * Copyright (C) 2001 A&D Co., Ltd.
5 *
6 * I/O routine and setup routines for A&D ADX Board
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 *
12 */
13
14#include <asm/irq.h>
15
16void init_adx_IRQ(void)
17{
18 int i;
19
20/* printk("init_adx_IRQ()\n");*/
21 /* setup irq_mask_register */
22 irq_mask_register = (unsigned short *)0xa6000008;
23
24 /* cover all external interrupt area by maskreg_irq_type
25 * (Actually, irq15 doesn't exist)
26 */
27 for (i = 0; i < 16; i++) {
28 make_maskreg_irq(i);
29 disable_irq(i);
30 }
31}
diff --git a/arch/sh/boards/adx/setup.c b/arch/sh/boards/adx/setup.c
deleted file mode 100644
index 4938d9592343..000000000000
--- a/arch/sh/boards/adx/setup.c
+++ /dev/null
@@ -1,56 +0,0 @@
1/*
2 * linux/arch/sh/board/adx/setup.c
3 *
4 * Copyright (C) 2001 A&D Co., Ltd.
5 *
6 * I/O routine and setup routines for A&D ADX Board
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 *
12 */
13
14#include <asm/machvec.h>
15#include <linux/module.h>
16
17extern void init_adx_IRQ(void);
18extern void *cf_io_base;
19
20const char *get_system_type(void)
21{
22 return "A&D ADX";
23}
24
25unsigned long adx_isa_port2addr(unsigned long offset)
26{
27 /* CompactFlash (IDE) */
28 if (((offset >= 0x1f0) && (offset <= 0x1f7)) || (offset == 0x3f6)) {
29 return (unsigned long)cf_io_base + offset;
30 }
31
32 /* eth0 */
33 if ((offset >= 0x300) && (offset <= 0x30f)) {
34 return 0xa5000000 + offset; /* COMM BOARD (AREA1) */
35 }
36
37 return offset + 0xb0000000; /* IOBUS (AREA 4)*/
38}
39
40/*
41 * The Machine Vector
42 */
43
44struct sh_machine_vector mv_adx __initmv = {
45 .mv_nr_irqs = 48,
46 .mv_isa_port2addr = adx_isa_port2addr,
47 .mv_init_irq = init_adx_IRQ,
48};
49ALIAS_MV(adx)
50
51int __init platform_setup(void)
52{
53 /* Nothing to see here .. */
54 return 0;
55}
56
diff --git a/arch/sh/boards/bigsur/irq.c b/arch/sh/boards/bigsur/irq.c
index ac946a2201c7..1ab04da36382 100644
--- a/arch/sh/boards/bigsur/irq.c
+++ b/arch/sh/boards/bigsur/irq.c
@@ -19,6 +19,7 @@
19 * IRQ functions for a Hitachi Big Sur Evaluation Board. 19 * IRQ functions for a Hitachi Big Sur Evaluation Board.
20 * 20 *
21 */ 21 */
22#undef DEBUG
22 23
23#include <linux/sched.h> 24#include <linux/sched.h>
24#include <linux/module.h> 25#include <linux/module.h>
@@ -41,10 +42,8 @@
41#undef BIGSUR_DEBUG 42#undef BIGSUR_DEBUG
42 43
43#ifdef BIGSUR_DEBUG 44#ifdef BIGSUR_DEBUG
44#define DPRINTK(args...) printk(args)
45#define DIPRINTK(n, args...) if (BIGSUR_DEBUG>(n)) printk(args) 45#define DIPRINTK(n, args...) if (BIGSUR_DEBUG>(n)) printk(args)
46#else 46#else
47#define DPRINTK(args...)
48#define DIPRINTK(n, args...) 47#define DIPRINTK(n, args...)
49#endif /* BIGSUR_DEBUG */ 48#endif /* BIGSUR_DEBUG */
50 49
@@ -60,45 +59,39 @@ extern int hd64465_irq_demux(int irq);
60/* Level 1 IRQ routines */ 59/* Level 1 IRQ routines */
61static void disable_bigsur_l1irq(unsigned int irq) 60static void disable_bigsur_l1irq(unsigned int irq)
62{ 61{
63 unsigned long flags;
64 unsigned char mask; 62 unsigned char mask;
65 unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0; 63 unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0;
66 unsigned char bit = (1 << ((irq - MGATE_IRQ_LOW)%8) ); 64 unsigned char bit = (1 << ((irq - MGATE_IRQ_LOW)%8) );
67 65
68 if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) { 66 if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
69 DPRINTK("Disable L1 IRQ %d\n", irq); 67 pr_debug("Disable L1 IRQ %d\n", irq);
70 DIPRINTK(2,"disable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n", 68 DIPRINTK(2,"disable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n",
71 mask_port, bit); 69 mask_port, bit);
72 local_irq_save(flags);
73 70
74 /* Disable IRQ - set mask bit */ 71 /* Disable IRQ - set mask bit */
75 mask = inb(mask_port) | bit; 72 mask = inb(mask_port) | bit;
76 outb(mask, mask_port); 73 outb(mask, mask_port);
77 local_irq_restore(flags);
78 return; 74 return;
79 } 75 }
80 DPRINTK("disable_bigsur_l1irq: Invalid IRQ %d\n", irq); 76 pr_debug("disable_bigsur_l1irq: Invalid IRQ %d\n", irq);
81} 77}
82 78
83static void enable_bigsur_l1irq(unsigned int irq) 79static void enable_bigsur_l1irq(unsigned int irq)
84{ 80{
85 unsigned long flags;
86 unsigned char mask; 81 unsigned char mask;
87 unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0; 82 unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0;
88 unsigned char bit = (1 << ((irq - MGATE_IRQ_LOW)%8) ); 83 unsigned char bit = (1 << ((irq - MGATE_IRQ_LOW)%8) );
89 84
90 if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) { 85 if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
91 DPRINTK("Enable L1 IRQ %d\n", irq); 86 pr_debug("Enable L1 IRQ %d\n", irq);
92 DIPRINTK(2,"enable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n", 87 DIPRINTK(2,"enable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n",
93 mask_port, bit); 88 mask_port, bit);
94 local_irq_save(flags);
95 /* Enable L1 IRQ - clear mask bit */ 89 /* Enable L1 IRQ - clear mask bit */
96 mask = inb(mask_port) & ~bit; 90 mask = inb(mask_port) & ~bit;
97 outb(mask, mask_port); 91 outb(mask, mask_port);
98 local_irq_restore(flags);
99 return; 92 return;
100 } 93 }
101 DPRINTK("enable_bigsur_l1irq: Invalid IRQ %d\n", irq); 94 pr_debug("enable_bigsur_l1irq: Invalid IRQ %d\n", irq);
102} 95}
103 96
104 97
@@ -126,51 +119,45 @@ static const u32 imr_offset = BIGSUR_IMR0 - BIGSUR_IMR1;
126/* Level 2 IRQ routines */ 119/* Level 2 IRQ routines */
127static void disable_bigsur_l2irq(unsigned int irq) 120static void disable_bigsur_l2irq(unsigned int irq)
128{ 121{
129 unsigned long flags;
130 unsigned char mask; 122 unsigned char mask;
131 unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8); 123 unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8);
132 unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset; 124 unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset;
133 125
134 if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) { 126 if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
135 DPRINTK("Disable L2 IRQ %d\n", irq); 127 pr_debug("Disable L2 IRQ %d\n", irq);
136 DIPRINTK(2,"disable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n", 128 DIPRINTK(2,"disable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n",
137 mask_port, bit); 129 mask_port, bit);
138 local_irq_save(flags);
139 130
140 /* Disable L2 IRQ - set mask bit */ 131 /* Disable L2 IRQ - set mask bit */
141 mask = inb(mask_port) | bit; 132 mask = inb(mask_port) | bit;
142 outb(mask, mask_port); 133 outb(mask, mask_port);
143 local_irq_restore(flags);
144 return; 134 return;
145 } 135 }
146 DPRINTK("disable_bigsur_l2irq: Invalid IRQ %d\n", irq); 136 pr_debug("disable_bigsur_l2irq: Invalid IRQ %d\n", irq);
147} 137}
148 138
149static void enable_bigsur_l2irq(unsigned int irq) 139static void enable_bigsur_l2irq(unsigned int irq)
150{ 140{
151 unsigned long flags;
152 unsigned char mask; 141 unsigned char mask;
153 unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8); 142 unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8);
154 unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset; 143 unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset;
155 144
156 if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) { 145 if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) {
157 DPRINTK("Enable L2 IRQ %d\n", irq); 146 pr_debug("Enable L2 IRQ %d\n", irq);
158 DIPRINTK(2,"enable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n", 147 DIPRINTK(2,"enable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n",
159 mask_port, bit); 148 mask_port, bit);
160 local_irq_save(flags);
161 149
162 /* Enable L2 IRQ - clear mask bit */ 150 /* Enable L2 IRQ - clear mask bit */
163 mask = inb(mask_port) & ~bit; 151 mask = inb(mask_port) & ~bit;
164 outb(mask, mask_port); 152 outb(mask, mask_port);
165 local_irq_restore(flags);
166 return; 153 return;
167 } 154 }
168 DPRINTK("enable_bigsur_l2irq: Invalid IRQ %d\n", irq); 155 pr_debug("enable_bigsur_l2irq: Invalid IRQ %d\n", irq);
169} 156}
170 157
171static void mask_and_ack_bigsur(unsigned int irq) 158static void mask_and_ack_bigsur(unsigned int irq)
172{ 159{
173 DPRINTK("mask_and_ack_bigsur IRQ %d\n", irq); 160 pr_debug("mask_and_ack_bigsur IRQ %d\n", irq);
174 if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) 161 if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
175 disable_bigsur_l1irq(irq); 162 disable_bigsur_l1irq(irq);
176 else 163 else
@@ -179,7 +166,7 @@ static void mask_and_ack_bigsur(unsigned int irq)
179 166
180static void end_bigsur_irq(unsigned int irq) 167static void end_bigsur_irq(unsigned int irq)
181{ 168{
182 DPRINTK("end_bigsur_irq IRQ %d\n", irq); 169 pr_debug("end_bigsur_irq IRQ %d\n", irq);
183 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { 170 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
184 if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) 171 if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
185 enable_bigsur_l1irq(irq); 172 enable_bigsur_l1irq(irq);
@@ -193,7 +180,7 @@ static unsigned int startup_bigsur_irq(unsigned int irq)
193 u8 mask; 180 u8 mask;
194 u32 reg; 181 u32 reg;
195 182
196 DPRINTK("startup_bigsur_irq IRQ %d\n", irq); 183 pr_debug("startup_bigsur_irq IRQ %d\n", irq);
197 184
198 if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) { 185 if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) {
199 /* Enable the L1 IRQ */ 186 /* Enable the L1 IRQ */
@@ -218,7 +205,7 @@ static unsigned int startup_bigsur_irq(unsigned int irq)
218 205
219static void shutdown_bigsur_irq(unsigned int irq) 206static void shutdown_bigsur_irq(unsigned int irq)
220{ 207{
221 DPRINTK("shutdown_bigsur_irq IRQ %d\n", irq); 208 pr_debug("shutdown_bigsur_irq IRQ %d\n", irq);
222 if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) 209 if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH)
223 disable_bigsur_l1irq(irq); 210 disable_bigsur_l1irq(irq);
224 else 211 else
@@ -260,7 +247,7 @@ static void make_bigsur_l1isr(unsigned int irq) {
260 disable_bigsur_l1irq(irq); 247 disable_bigsur_l1irq(irq);
261 return; 248 return;
262 } 249 }
263 DPRINTK("make_bigsur_l1isr: bad irq, %d\n", irq); 250 pr_debug("make_bigsur_l1isr: bad irq, %d\n", irq);
264 return; 251 return;
265} 252}
266 253
@@ -277,7 +264,7 @@ static void make_bigsur_l2isr(unsigned int irq) {
277 disable_bigsur_l2irq(irq); 264 disable_bigsur_l2irq(irq);
278 return; 265 return;
279 } 266 }
280 DPRINTK("make_bigsur_l2isr: bad irq, %d\n", irq); 267 pr_debug("make_bigsur_l2isr: bad irq, %d\n", irq);
281 return; 268 return;
282} 269}
283 270
diff --git a/arch/sh/boards/bigsur/setup.c b/arch/sh/boards/bigsur/setup.c
index dfeede9da50f..9711c20fc9e4 100644
--- a/arch/sh/boards/bigsur/setup.c
+++ b/arch/sh/boards/bigsur/setup.c
@@ -41,31 +41,7 @@
41// Big Sur Init Routines 41// Big Sur Init Routines
42/*===========================================================*/ 42/*===========================================================*/
43 43
44const char *get_system_type(void) 44static void __init bigsur_setup(char **cmdline_p)
45{
46 return "Big Sur";
47}
48
49/*
50 * The Machine Vector
51 */
52extern void heartbeat_bigsur(void);
53extern void init_bigsur_IRQ(void);
54
55struct sh_machine_vector mv_bigsur __initmv = {
56 .mv_nr_irqs = NR_IRQS, // Defined in <asm/irq.h>
57
58 .mv_isa_port2addr = bigsur_isa_port2addr,
59 .mv_irq_demux = bigsur_irq_demux,
60
61 .mv_init_irq = init_bigsur_IRQ,
62#ifdef CONFIG_HEARTBEAT
63 .mv_heartbeat = heartbeat_bigsur,
64#endif
65};
66ALIAS_MV(bigsur)
67
68int __init platform_setup(void)
69{ 45{
70 /* Mask all 2nd level IRQ's */ 46 /* Mask all 2nd level IRQ's */
71 outb(-1,BIGSUR_IMR0); 47 outb(-1,BIGSUR_IMR0);
@@ -89,7 +65,24 @@ int __init platform_setup(void)
89 outw(1, BIGSUR_ETHR+0xe); 65 outw(1, BIGSUR_ETHR+0xe);
90 /* set the IO port to BIGSUR_ETHER_IOPORT */ 66 /* set the IO port to BIGSUR_ETHER_IOPORT */
91 outw(BIGSUR_ETHER_IOPORT<<3, BIGSUR_ETHR+0x2); 67 outw(BIGSUR_ETHER_IOPORT<<3, BIGSUR_ETHR+0x2);
92
93 return 0;
94} 68}
95 69
70/*
71 * The Machine Vector
72 */
73extern void heartbeat_bigsur(void);
74extern void init_bigsur_IRQ(void);
75
76struct sh_machine_vector mv_bigsur __initmv = {
77 .mv_name = "Big Sur",
78 .mv_setup = bigsur_setup,
79
80 .mv_isa_port2addr = bigsur_isa_port2addr,
81 .mv_irq_demux = bigsur_irq_demux,
82
83 .mv_init_irq = init_bigsur_IRQ,
84#ifdef CONFIG_HEARTBEAT
85 .mv_heartbeat = heartbeat_bigsur,
86#endif
87};
88ALIAS_MV(bigsur)
diff --git a/arch/sh/boards/cat68701/Makefile b/arch/sh/boards/cat68701/Makefile
deleted file mode 100644
index 52c1de0a6dfd..000000000000
--- a/arch/sh/boards/cat68701/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
1#
2# Makefile for the CAT-68701 specific parts of the kernel
3#
4
5obj-y := setup.o irq.o
6
diff --git a/arch/sh/boards/cat68701/irq.c b/arch/sh/boards/cat68701/irq.c
deleted file mode 100644
index f9a6d185fb8b..000000000000
--- a/arch/sh/boards/cat68701/irq.c
+++ /dev/null
@@ -1,28 +0,0 @@
1/*
2 * linux/arch/sh/boards/cat68701/irq.c
3 *
4 * Copyright (C) 2000 Niibe Yutaka
5 * 2001 Yutaro Ebihara
6 *
7 * Setup routines for A-ONE Corp CAT-68701 SH7708 Board
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 *
13 */
14
15#include <asm/irq.h>
16
17int cat68701_irq_demux(int irq)
18{
19 if(irq==13) return 14;
20 if(irq==7) return 10;
21 return irq;
22}
23
24void init_cat68701_IRQ()
25{
26 make_imask_irq(10);
27 make_imask_irq(14);
28}
diff --git a/arch/sh/boards/cat68701/setup.c b/arch/sh/boards/cat68701/setup.c
deleted file mode 100644
index 90e5175df227..000000000000
--- a/arch/sh/boards/cat68701/setup.c
+++ /dev/null
@@ -1,85 +0,0 @@
1/*
2 * linux/arch/sh/boards/cat68701/setup.c
3 *
4 * Copyright (C) 2000 Niibe Yutaka
5 * 2001 Yutaro Ebihara
6 *
7 * Setup routines for A-ONE Corp CAT-68701 SH7708 Board
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 *
13 */
14
15#include <asm/io.h>
16#include <asm/machvec.h>
17#include <asm/mach/io.h>
18#include <linux/module.h>
19#include <linux/init.h>
20#include <linux/sched.h>
21
22const char *get_system_type(void)
23{
24 return "CAT-68701";
25}
26
27#ifdef CONFIG_HEARTBEAT
28void heartbeat_cat68701()
29{
30 static unsigned int cnt = 0, period = 0 , bit = 0;
31 cnt += 1;
32 if (cnt < period) {
33 return;
34 }
35 cnt = 0;
36
37 /* Go through the points (roughly!):
38 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
39 */
40 period = 110 - ( (300<<FSHIFT)/
41 ((avenrun[0]/5) + (3<<FSHIFT)) );
42
43 if(bit){ bit=0; }else{ bit=1; }
44 outw(bit<<15,0x3fe);
45}
46#endif /* CONFIG_HEARTBEAT */
47
48unsigned long cat68701_isa_port2addr(unsigned long offset)
49{
50 /* CompactFlash (IDE) */
51 if (((offset >= 0x1f0) && (offset <= 0x1f7)) || (offset==0x3f6))
52 return 0xba000000 + offset;
53
54 /* INPUT PORT */
55 if ((offset >= 0x3fc) && (offset <= 0x3fd))
56 return 0xb4007000 + offset;
57
58 /* OUTPUT PORT */
59 if ((offset >= 0x3fe) && (offset <= 0x3ff))
60 return 0xb4007400 + offset;
61
62 return offset + 0xb4000000; /* other I/O (EREA 5)*/
63}
64
65/*
66 * The Machine Vector
67 */
68
69struct sh_machine_vector mv_cat68701 __initmv = {
70 .mv_nr_irqs = 32,
71 .mv_isa_port2addr = cat68701_isa_port2addr,
72 .mv_irq_demux = cat68701_irq_demux,
73
74 .mv_init_irq = init_cat68701_IRQ,
75#ifdef CONFIG_HEARTBEAT
76 .mv_heartbeat = heartbeat_cat68701,
77#endif
78};
79ALIAS_MV(cat68701)
80
81int __init platform_setup(void)
82{
83 /* dummy read erea5 (CS8900A) */
84}
85
diff --git a/arch/sh/boards/cqreek/Makefile b/arch/sh/boards/cqreek/Makefile
deleted file mode 100644
index 1a788a85eba3..000000000000
--- a/arch/sh/boards/cqreek/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
1#
2# Makefile for the CqREEK specific parts of the kernel
3#
4
5obj-y := setup.o irq.o
6
diff --git a/arch/sh/boards/cqreek/irq.c b/arch/sh/boards/cqreek/irq.c
deleted file mode 100644
index 2955adc52310..000000000000
--- a/arch/sh/boards/cqreek/irq.c
+++ /dev/null
@@ -1,128 +0,0 @@
1/* $Id: irq.c,v 1.1.2.4 2002/11/04 20:33:56 lethal Exp $
2 *
3 * arch/sh/boards/cqreek/irq.c
4 *
5 * Copyright (C) 2000 Niibe Yutaka
6 *
7 * CqREEK IDE/ISA Bridge Support.
8 *
9 */
10
11#include <linux/irq.h>
12#include <linux/init.h>
13
14#include <asm/cqreek/cqreek.h>
15#include <asm/io.h>
16#include <asm/io_generic.h>
17#include <asm/irq.h>
18#include <asm/machvec.h>
19#include <asm/machvec_init.h>
20#include <asm/rtc.h>
21
22struct cqreek_irq_data {
23 unsigned short mask_port; /* Port of Interrupt Mask Register */
24 unsigned short stat_port; /* Port of Interrupt Status Register */
25 unsigned short bit; /* Value of the bit */
26};
27static struct cqreek_irq_data cqreek_irq_data[NR_IRQS];
28
29static void disable_cqreek_irq(unsigned int irq)
30{
31 unsigned long flags;
32 unsigned short mask;
33 unsigned short mask_port = cqreek_irq_data[irq].mask_port;
34 unsigned short bit = cqreek_irq_data[irq].bit;
35
36 local_irq_save(flags);
37 /* Disable IRQ */
38 mask = inw(mask_port) & ~bit;
39 outw_p(mask, mask_port);
40 local_irq_restore(flags);
41}
42
43static void enable_cqreek_irq(unsigned int irq)
44{
45 unsigned long flags;
46 unsigned short mask;
47 unsigned short mask_port = cqreek_irq_data[irq].mask_port;
48 unsigned short bit = cqreek_irq_data[irq].bit;
49
50 local_irq_save(flags);
51 /* Enable IRQ */
52 mask = inw(mask_port) | bit;
53 outw_p(mask, mask_port);
54 local_irq_restore(flags);
55}
56
57static void mask_and_ack_cqreek(unsigned int irq)
58{
59 unsigned short stat_port = cqreek_irq_data[irq].stat_port;
60 unsigned short bit = cqreek_irq_data[irq].bit;
61
62 disable_cqreek_irq(irq);
63 /* Clear IRQ (it might be edge IRQ) */
64 inw(stat_port);
65 outw_p(bit, stat_port);
66}
67
68static void end_cqreek_irq(unsigned int irq)
69{
70 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
71 enable_cqreek_irq(irq);
72}
73
74static unsigned int startup_cqreek_irq(unsigned int irq)
75{
76 enable_cqreek_irq(irq);
77 return 0;
78}
79
80static void shutdown_cqreek_irq(unsigned int irq)
81{
82 disable_cqreek_irq(irq);
83}
84
85static struct hw_interrupt_type cqreek_irq_type = {
86 .typename = "CqREEK-IRQ",
87 .startup = startup_cqreek_irq,
88 .shutdown = shutdown_cqreek_irq,
89 .enable = enable_cqreek_irq,
90 .disable = disable_cqreek_irq,
91 .ack = mask_and_ack_cqreek,
92 .end = end_cqreek_irq
93};
94
95int cqreek_has_ide, cqreek_has_isa;
96
97/* XXX: This is just for test for my NE2000 ISA board
98 What we really need is virtualized IRQ and demultiplexer like HP600 port */
99void __init init_cqreek_IRQ(void)
100{
101 if (cqreek_has_ide) {
102 cqreek_irq_data[14].mask_port = BRIDGE_IDE_INTR_MASK;
103 cqreek_irq_data[14].stat_port = BRIDGE_IDE_INTR_STAT;
104 cqreek_irq_data[14].bit = 1;
105
106 irq_desc[14].chip = &cqreek_irq_type;
107 irq_desc[14].status = IRQ_DISABLED;
108 irq_desc[14].action = 0;
109 irq_desc[14].depth = 1;
110
111 disable_cqreek_irq(14);
112 }
113
114 if (cqreek_has_isa) {
115 cqreek_irq_data[10].mask_port = BRIDGE_ISA_INTR_MASK;
116 cqreek_irq_data[10].stat_port = BRIDGE_ISA_INTR_STAT;
117 cqreek_irq_data[10].bit = (1 << 10);
118
119 /* XXX: Err... we may need demultiplexer for ISA irq... */
120 irq_desc[10].chip = &cqreek_irq_type;
121 irq_desc[10].status = IRQ_DISABLED;
122 irq_desc[10].action = 0;
123 irq_desc[10].depth = 1;
124
125 disable_cqreek_irq(10);
126 }
127}
128
diff --git a/arch/sh/boards/cqreek/setup.c b/arch/sh/boards/cqreek/setup.c
deleted file mode 100644
index eff4ed93599f..000000000000
--- a/arch/sh/boards/cqreek/setup.c
+++ /dev/null
@@ -1,100 +0,0 @@
1/* $Id: setup.c,v 1.5 2003/08/04 01:51:58 lethal Exp $
2 *
3 * arch/sh/kernel/setup_cqreek.c
4 *
5 * Copyright (C) 2000 Niibe Yutaka
6 *
7 * CqREEK IDE/ISA Bridge Support.
8 *
9 */
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/irq.h>
14
15#include <asm/mach/cqreek.h>
16#include <asm/machvec.h>
17#include <asm/io.h>
18#include <asm/io_generic.h>
19#include <asm/irq.h>
20#include <asm/rtc.h>
21
22#define IDE_OFFSET 0xA4000000UL
23#define ISA_OFFSET 0xA4A00000UL
24
25const char *get_system_type(void)
26{
27 return "CqREEK";
28}
29
30static unsigned long cqreek_port2addr(unsigned long port)
31{
32 if (0x0000<=port && port<=0x0040)
33 return IDE_OFFSET + port;
34 if ((0x01f0<=port && port<=0x01f7) || port == 0x03f6)
35 return IDE_OFFSET + port;
36
37 return ISA_OFFSET + port;
38}
39
40/*
41 * The Machine Vector
42 */
43struct sh_machine_vector mv_cqreek __initmv = {
44#if defined(CONFIG_CPU_SH4)
45 .mv_nr_irqs = 48,
46#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
47 .mv_nr_irqs = 32,
48#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
49 .mv_nr_irqs = 61,
50#endif
51
52 .mv_init_irq = init_cqreek_IRQ,
53
54 .mv_isa_port2addr = cqreek_port2addr,
55};
56ALIAS_MV(cqreek)
57
58/*
59 * Initialize the board
60 */
61void __init platform_setup(void)
62{
63 int i;
64/* udelay is not available at setup time yet... */
65#define DELAY() do {for (i=0; i<10000; i++) ctrl_inw(0xa0000000);} while(0)
66
67 if ((inw (BRIDGE_FEATURE) & 1)) { /* We have IDE interface */
68 outw_p(0, BRIDGE_IDE_INTR_LVL);
69 outw_p(0, BRIDGE_IDE_INTR_MASK);
70
71 outw_p(0, BRIDGE_IDE_CTRL);
72 DELAY();
73
74 outw_p(0x8000, BRIDGE_IDE_CTRL);
75 DELAY();
76
77 outw_p(0xffff, BRIDGE_IDE_INTR_STAT); /* Clear interrupt status */
78 outw_p(0x0f-14, BRIDGE_IDE_INTR_LVL); /* Use 14 IPR */
79 outw_p(1, BRIDGE_IDE_INTR_MASK); /* Enable interrupt */
80 cqreek_has_ide=1;
81 }
82
83 if ((inw (BRIDGE_FEATURE) & 2)) { /* We have ISA interface */
84 outw_p(0, BRIDGE_ISA_INTR_LVL);
85 outw_p(0, BRIDGE_ISA_INTR_MASK);
86
87 outw_p(0, BRIDGE_ISA_CTRL);
88 DELAY();
89 outw_p(0x8000, BRIDGE_ISA_CTRL);
90 DELAY();
91
92 outw_p(0xffff, BRIDGE_ISA_INTR_STAT); /* Clear interrupt status */
93 outw_p(0x0f-10, BRIDGE_ISA_INTR_LVL); /* Use 10 IPR */
94 outw_p(0xfff8, BRIDGE_ISA_INTR_MASK); /* Enable interrupt */
95 cqreek_has_isa=1;
96 }
97
98 printk(KERN_INFO "CqREEK Setup (IDE=%d, ISA=%d)...done\n", cqreek_has_ide, cqreek_has_isa);
99}
100
diff --git a/arch/sh/boards/dmida/Makefile b/arch/sh/boards/dmida/Makefile
deleted file mode 100644
index 75999aa0a2d9..000000000000
--- a/arch/sh/boards/dmida/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
1#
2# Makefile for the DataMyte Industrial Digital Assistant(tm) specific parts
3# of the kernel
4#
5
6obj-y := mach.o
7
diff --git a/arch/sh/boards/dmida/mach.c b/arch/sh/boards/dmida/mach.c
deleted file mode 100644
index d03a25f989c2..000000000000
--- a/arch/sh/boards/dmida/mach.c
+++ /dev/null
@@ -1,59 +0,0 @@
1/*
2 * linux/arch/sh/boards/dmida/mach.c
3 *
4 * by Greg Banks <gbanks@pocketpenguins.com>
5 * (c) 2000 PocketPenguins Inc
6 *
7 * Derived from mach_hp600.c, which bore the message:
8 * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
9 *
10 * May be copied or modified under the terms of the GNU General Public
11 * License. See linux/COPYING for more information.
12 *
13 * Machine vector for the DataMyte Industrial Digital Assistant(tm).
14 * See http://www.dmida.com
15 *
16 */
17
18#include <linux/init.h>
19
20#include <asm/machvec.h>
21#include <asm/rtc.h>
22#include <asm/machvec_init.h>
23
24#include <asm/io.h>
25#include <asm/hd64465/hd64465.h>
26#include <asm/irq.h>
27
28/*
29 * The Machine Vector
30 */
31
32struct sh_machine_vector mv_dmida __initmv = {
33 .mv_nr_irqs = HD64465_IRQ_BASE+HD64465_IRQ_NUM,
34
35 .mv_inb = hd64465_inb,
36 .mv_inw = hd64465_inw,
37 .mv_inl = hd64465_inl,
38 .mv_outb = hd64465_outb,
39 .mv_outw = hd64465_outw,
40 .mv_outl = hd64465_outl,
41
42 .mv_inb_p = hd64465_inb_p,
43 .mv_inw_p = hd64465_inw,
44 .mv_inl_p = hd64465_inl,
45 .mv_outb_p = hd64465_outb_p,
46 .mv_outw_p = hd64465_outw,
47 .mv_outl_p = hd64465_outl,
48
49 .mv_insb = hd64465_insb,
50 .mv_insw = hd64465_insw,
51 .mv_insl = hd64465_insl,
52 .mv_outsb = hd64465_outsb,
53 .mv_outsw = hd64465_outsw,
54 .mv_outsl = hd64465_outsl,
55
56 .mv_irq_demux = hd64465_irq_demux,
57};
58ALIAS_MV(dmida)
59
diff --git a/arch/sh/boards/dreamcast/irq.c b/arch/sh/boards/dreamcast/irq.c
index b10a6b11c034..5bf01f86c20c 100644
--- a/arch/sh/boards/dreamcast/irq.c
+++ b/arch/sh/boards/dreamcast/irq.c
@@ -10,7 +10,6 @@
10 */ 10 */
11 11
12#include <linux/irq.h> 12#include <linux/irq.h>
13
14#include <asm/io.h> 13#include <asm/io.h>
15#include <asm/irq.h> 14#include <asm/irq.h>
16#include <asm/dreamcast/sysasic.h> 15#include <asm/dreamcast/sysasic.h>
@@ -26,10 +25,10 @@
26 event. 25 event.
27 26
28 There are three 32-bit ESRs located at 0xa05f8900 - 0xa05f6908. Event 27 There are three 32-bit ESRs located at 0xa05f8900 - 0xa05f6908. Event
29 types can be found in include/asm-sh/dc_sysasic.h. There are three groups 28 types can be found in include/asm-sh/dreamcast/sysasic.h. There are three
30 of EMRs that parallel the ESRs. Each EMR group corresponds to an IRQ, so 29 groups of EMRs that parallel the ESRs. Each EMR group corresponds to an
31 0xa05f6910 - 0xa05f6918 triggers IRQ 13, 0xa05f6920 - 0xa05f6928 triggers 30 IRQ, so 0xa05f6910 - 0xa05f6918 triggers IRQ 13, 0xa05f6920 - 0xa05f6928
32 IRQ 11, and 0xa05f6930 - 0xa05f6938 triggers IRQ 9. 31 triggers IRQ 11, and 0xa05f6930 - 0xa05f6938 triggers IRQ 9.
33 32
34 In the kernel, these events are mapped to virtual IRQs so that drivers can 33 In the kernel, these events are mapped to virtual IRQs so that drivers can
35 respond to them as they would a normal interrupt. In order to keep this 34 respond to them as they would a normal interrupt. In order to keep this
@@ -57,29 +56,23 @@
57/* Disable the hardware event by masking its bit in its EMR */ 56/* Disable the hardware event by masking its bit in its EMR */
58static inline void disable_systemasic_irq(unsigned int irq) 57static inline void disable_systemasic_irq(unsigned int irq)
59{ 58{
60 unsigned long flags;
61 __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2); 59 __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
62 __u32 mask; 60 __u32 mask;
63 61
64 local_irq_save(flags);
65 mask = inl(emr); 62 mask = inl(emr);
66 mask &= ~(1 << EVENT_BIT(irq)); 63 mask &= ~(1 << EVENT_BIT(irq));
67 outl(mask, emr); 64 outl(mask, emr);
68 local_irq_restore(flags);
69} 65}
70 66
71/* Enable the hardware event by setting its bit in its EMR */ 67/* Enable the hardware event by setting its bit in its EMR */
72static inline void enable_systemasic_irq(unsigned int irq) 68static inline void enable_systemasic_irq(unsigned int irq)
73{ 69{
74 unsigned long flags;
75 __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2); 70 __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2);
76 __u32 mask; 71 __u32 mask;
77 72
78 local_irq_save(flags);
79 mask = inl(emr); 73 mask = inl(emr);
80 mask |= (1 << EVENT_BIT(irq)); 74 mask |= (1 << EVENT_BIT(irq));
81 outl(mask, emr); 75 outl(mask, emr);
82 local_irq_restore(flags);
83} 76}
84 77
85/* Acknowledge a hardware event by writing its bit back to its ESR */ 78/* Acknowledge a hardware event by writing its bit back to its ESR */
diff --git a/arch/sh/boards/dreamcast/rtc.c b/arch/sh/boards/dreamcast/rtc.c
index 379de1629134..b3a876a3b859 100644
--- a/arch/sh/boards/dreamcast/rtc.c
+++ b/arch/sh/boards/dreamcast/rtc.c
@@ -1,4 +1,5 @@
1/* arch/sh/kernel/rtc-aica.c 1/*
2 * arch/sh/boards/dreamcast/rtc.c
2 * 3 *
3 * Dreamcast AICA RTC routines. 4 * Dreamcast AICA RTC routines.
4 * 5 *
@@ -10,15 +11,12 @@
10 */ 11 */
11 12
12#include <linux/time.h> 13#include <linux/time.h>
13 14#include <asm/rtc.h>
14#include <asm/io.h> 15#include <asm/io.h>
15 16
16extern void (*rtc_get_time)(struct timespec *);
17extern int (*rtc_set_time)(const time_t);
18
19/* The AICA RTC has an Epoch of 1/1/1950, so we must subtract 20 years (in 17/* The AICA RTC has an Epoch of 1/1/1950, so we must subtract 20 years (in
20 seconds to get the standard Unix Epoch when getting the time, and add 20 18 seconds) to get the standard Unix Epoch when getting the time, and add
21 years when setting the time. */ 19 20 years when setting the time. */
22#define TWENTY_YEARS ((20 * 365LU + 5) * 86400) 20#define TWENTY_YEARS ((20 * 365LU + 5) * 86400)
23 21
24/* The AICA RTC is represented by a 32-bit seconds counter stored in 2 16-bit 22/* The AICA RTC is represented by a 32-bit seconds counter stored in 2 16-bit
@@ -32,7 +30,8 @@ extern int (*rtc_set_time)(const time_t);
32 * 30 *
33 * Grabs the current RTC seconds counter and adjusts it to the Unix Epoch. 31 * Grabs the current RTC seconds counter and adjusts it to the Unix Epoch.
34 */ 32 */
35void aica_rtc_gettimeofday(struct timespec *ts) { 33void aica_rtc_gettimeofday(struct timespec *ts)
34{
36 unsigned long val1, val2; 35 unsigned long val1, val2;
37 36
38 do { 37 do {
@@ -55,7 +54,8 @@ void aica_rtc_gettimeofday(struct timespec *ts) {
55 * 54 *
56 * Adjusts the given @tv to the AICA Epoch and sets the RTC seconds counter. 55 * Adjusts the given @tv to the AICA Epoch and sets the RTC seconds counter.
57 */ 56 */
58int aica_rtc_settimeofday(const time_t secs) { 57int aica_rtc_settimeofday(const time_t secs)
58{
59 unsigned long val1, val2; 59 unsigned long val1, val2;
60 unsigned long adj = secs + TWENTY_YEARS; 60 unsigned long adj = secs + TWENTY_YEARS;
61 61
@@ -75,7 +75,7 @@ int aica_rtc_settimeofday(const time_t secs) {
75 75
76void aica_time_init(void) 76void aica_time_init(void)
77{ 77{
78 rtc_get_time = aica_rtc_gettimeofday; 78 rtc_sh_get_time = aica_rtc_gettimeofday;
79 rtc_set_time = aica_rtc_settimeofday; 79 rtc_sh_set_time = aica_rtc_settimeofday;
80} 80}
81 81
diff --git a/arch/sh/boards/dreamcast/setup.c b/arch/sh/boards/dreamcast/setup.c
index 0027b80a2343..f13017eeeb27 100644
--- a/arch/sh/boards/dreamcast/setup.c
+++ b/arch/sh/boards/dreamcast/setup.c
@@ -22,41 +22,21 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/irq.h> 23#include <linux/irq.h>
24#include <linux/device.h> 24#include <linux/device.h>
25
26#include <asm/io.h> 25#include <asm/io.h>
27#include <asm/irq.h> 26#include <asm/irq.h>
27#include <asm/rtc.h>
28#include <asm/machvec.h> 28#include <asm/machvec.h>
29#include <asm/machvec_init.h>
30#include <asm/mach/sysasic.h> 29#include <asm/mach/sysasic.h>
31 30
32extern struct hw_interrupt_type systemasic_int; 31extern struct hw_interrupt_type systemasic_int;
33/* XXX: Move this into it's proper header. */
34extern void (*board_time_init)(void);
35extern void aica_time_init(void); 32extern void aica_time_init(void);
36extern int gapspci_init(void); 33extern int gapspci_init(void);
37extern int systemasic_irq_demux(int); 34extern int systemasic_irq_demux(int);
38 35
39void *dreamcast_consistent_alloc(struct device *, size_t, dma_addr_t *, int); 36void *dreamcast_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t);
40int dreamcast_consistent_free(struct device *, size_t, void *, dma_addr_t); 37int dreamcast_consistent_free(struct device *, size_t, void *, dma_addr_t);
41 38
42const char *get_system_type(void) 39static void __init dreamcast_setup(char **cmdline_p)
43{
44 return "Sega Dreamcast";
45}
46
47struct sh_machine_vector mv_dreamcast __initmv = {
48 .mv_nr_irqs = NR_IRQS,
49
50 .mv_irq_demux = systemasic_irq_demux,
51
52#ifdef CONFIG_PCI
53 .mv_consistent_alloc = dreamcast_consistent_alloc,
54 .mv_consistent_free = dreamcast_consistent_free,
55#endif
56};
57ALIAS_MV(dreamcast)
58
59int __init platform_setup(void)
60{ 40{
61 int i; 41 int i;
62 42
@@ -78,6 +58,16 @@ int __init platform_setup(void)
78 if (gapspci_init() < 0) 58 if (gapspci_init() < 0)
79 printk(KERN_WARNING "GAPSPCI was not detected.\n"); 59 printk(KERN_WARNING "GAPSPCI was not detected.\n");
80#endif 60#endif
81
82 return 0;
83} 61}
62
63struct sh_machine_vector mv_dreamcast __initmv = {
64 .mv_name = "Sega Dreamcast",
65 .mv_setup = dreamcast_setup,
66 .mv_irq_demux = systemasic_irq_demux,
67
68#ifdef CONFIG_PCI
69 .mv_consistent_alloc = dreamcast_consistent_alloc,
70 .mv_consistent_free = dreamcast_consistent_free,
71#endif
72};
73ALIAS_MV(dreamcast)
diff --git a/arch/sh/boards/ec3104/setup.c b/arch/sh/boards/ec3104/setup.c
index 4b3ef16a0e96..902bc975a13e 100644
--- a/arch/sh/boards/ec3104/setup.c
+++ b/arch/sh/boards/ec3104/setup.c
@@ -21,22 +21,36 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/irq.h> 22#include <linux/irq.h>
23#include <linux/types.h> 23#include <linux/types.h>
24
25#include <asm/io.h> 24#include <asm/io.h>
26#include <asm/irq.h> 25#include <asm/irq.h>
27#include <asm/machvec.h> 26#include <asm/machvec.h>
28#include <asm/mach/ec3104.h> 27#include <asm/mach/ec3104.h>
29 28
30const char *get_system_type(void) 29static void __init ec3104_setup(char **cmdline_p)
31{ 30{
32 return "EC3104"; 31 char str[8];
32 int i;
33
34 for (i=0; i<8; i++)
35 str[i] = ctrl_readb(EC3104_BASE + i);
36
37 for (i = EC3104_IRQBASE; i < EC3104_IRQBASE + 32; i++)
38 irq_desc[i].handler = &ec3104_int;
39
40 printk("initializing EC3104 \"%.8s\" at %08x, IRQ %d, IRQ base %d\n",
41 str, EC3104_BASE, EC3104_IRQ, EC3104_IRQBASE);
42
43 /* mask all interrupts. this should have been done by the boot
44 * loader for us but we want to be sure ... */
45 ctrl_writel(0xffffffff, EC3104_IMR);
33} 46}
34 47
35/* 48/*
36 * The Machine Vector 49 * The Machine Vector
37 */ 50 */
38
39struct sh_machine_vector mv_ec3104 __initmv = { 51struct sh_machine_vector mv_ec3104 __initmv = {
52 .mv_name = "EC3104",
53 .mv_setup = ec3104_setup,
40 .mv_nr_irqs = 96, 54 .mv_nr_irqs = 96,
41 55
42 .mv_inb = ec3104_inb, 56 .mv_inb = ec3104_inb,
@@ -48,31 +62,4 @@ struct sh_machine_vector mv_ec3104 __initmv = {
48 62
49 .mv_irq_demux = ec3104_irq_demux, 63 .mv_irq_demux = ec3104_irq_demux,
50}; 64};
51
52ALIAS_MV(ec3104) 65ALIAS_MV(ec3104)
53
54int __init platform_setup(void)
55{
56 char str[8];
57 int i;
58
59 if (0)
60 return 0;
61
62 for (i=0; i<8; i++)
63 str[i] = ctrl_readb(EC3104_BASE + i);
64
65 for (i = EC3104_IRQBASE; i < EC3104_IRQBASE + 32; i++)
66 irq_desc[i].chip = &ec3104_int;
67
68 printk("initializing EC3104 \"%.8s\" at %08x, IRQ %d, IRQ base %d\n",
69 str, EC3104_BASE, EC3104_IRQ, EC3104_IRQBASE);
70
71
72 /* mask all interrupts. this should have been done by the boot
73 * loader for us but we want to be sure ... */
74 ctrl_writel(0xffffffff, EC3104_IMR);
75
76 return 0;
77}
78
diff --git a/arch/sh/boards/harp/Makefile b/arch/sh/boards/harp/Makefile
deleted file mode 100644
index eb753d31812e..000000000000
--- a/arch/sh/boards/harp/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
1#
2# Makefile for STMicroelectronics board specific parts of the kernel
3#
4
5obj-y := irq.o setup.o mach.o led.o
6
7obj-$(CONFIG_PCI) += pcidma.o
8
diff --git a/arch/sh/boards/harp/irq.c b/arch/sh/boards/harp/irq.c
deleted file mode 100644
index 96bb41c9fc55..000000000000
--- a/arch/sh/boards/harp/irq.c
+++ /dev/null
@@ -1,147 +0,0 @@
1/*
2 * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * Looks after interrupts on the HARP board.
8 *
9 * Bases on the IPR irq system
10 */
11
12#include <linux/init.h>
13#include <linux/irq.h>
14
15#include <asm/system.h>
16#include <asm/io.h>
17#include <asm/harp/harp.h>
18
19
20#define NUM_EXTERNAL_IRQS 16
21
22// Early versions of the STB1 Overdrive required this nasty frig
23//#define INVERT_INTMASK_WRITES
24
25static void enable_harp_irq(unsigned int irq);
26static void disable_harp_irq(unsigned int irq);
27
28/* shutdown is same as "disable" */
29#define shutdown_harp_irq disable_harp_irq
30
31static void mask_and_ack_harp(unsigned int);
32static void end_harp_irq(unsigned int irq);
33
34static unsigned int startup_harp_irq(unsigned int irq)
35{
36 enable_harp_irq(irq);
37 return 0; /* never anything pending */
38}
39
40static struct hw_interrupt_type harp_irq_type = {
41 .typename = "Harp-IRQ",
42 .startup = startup_harp_irq,
43 .shutdown = shutdown_harp_irq,
44 .enable = enable_harp_irq,
45 .disable = disable_harp_irq,
46 .ack = mask_and_ack_harp,
47 .end = end_harp_irq
48};
49
50static void disable_harp_irq(unsigned int irq)
51{
52 unsigned val, flags;
53 unsigned maskReg;
54 unsigned mask;
55 int pri;
56
57 if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
58 return;
59
60 pri = 15 - irq;
61
62 if (pri < 8) {
63 maskReg = EPLD_INTMASK0;
64 } else {
65 maskReg = EPLD_INTMASK1;
66 pri -= 8;
67 }
68
69 local_irq_save(flags);
70 mask = ctrl_inl(maskReg);
71 mask &= (~(1 << pri));
72#if defined(INVERT_INTMASK_WRITES)
73 mask ^= 0xff;
74#endif
75 ctrl_outl(mask, maskReg);
76 local_irq_restore(flags);
77}
78
79static void enable_harp_irq(unsigned int irq)
80{
81 unsigned flags;
82 unsigned maskReg;
83 unsigned mask;
84 int pri;
85
86 if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
87 return;
88
89 pri = 15 - irq;
90
91 if (pri < 8) {
92 maskReg = EPLD_INTMASK0;
93 } else {
94 maskReg = EPLD_INTMASK1;
95 pri -= 8;
96 }
97
98 local_irq_save(flags);
99 mask = ctrl_inl(maskReg);
100
101
102 mask |= (1 << pri);
103
104#if defined(INVERT_INTMASK_WRITES)
105 mask ^= 0xff;
106#endif
107 ctrl_outl(mask, maskReg);
108
109 local_irq_restore(flags);
110}
111
112/* This functions sets the desired irq handler to be an overdrive type */
113static void __init make_harp_irq(unsigned int irq)
114{
115 disable_irq_nosync(irq);
116 irq_desc[irq].chip = &harp_irq_type;
117 disable_harp_irq(irq);
118}
119
120static void mask_and_ack_harp(unsigned int irq)
121{
122 disable_harp_irq(irq);
123}
124
125static void end_harp_irq(unsigned int irq)
126{
127 enable_harp_irq(irq);
128}
129
130void __init init_harp_irq(void)
131{
132 int i;
133
134#if !defined(INVERT_INTMASK_WRITES)
135 // On the harp these are set to enable an interrupt
136 ctrl_outl(0x00, EPLD_INTMASK0);
137 ctrl_outl(0x00, EPLD_INTMASK1);
138#else
139 // On the Overdrive the data is inverted before being stored in the reg
140 ctrl_outl(0xff, EPLD_INTMASK0);
141 ctrl_outl(0xff, EPLD_INTMASK1);
142#endif
143
144 for (i = 0; i < NUM_EXTERNAL_IRQS; i++) {
145 make_harp_irq(i);
146 }
147}
diff --git a/arch/sh/boards/harp/led.c b/arch/sh/boards/harp/led.c
deleted file mode 100644
index aeb7b392b190..000000000000
--- a/arch/sh/boards/harp/led.c
+++ /dev/null
@@ -1,51 +0,0 @@
1/*
2 * linux/arch/sh/stboards/led.c
3 *
4 * Copyright (C) 2000 Stuart Menefy <stuart.menefy@st.com>
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * This file contains ST40STB1 HARP and compatible code.
10 */
11
12#include <asm/io.h>
13#include <asm/harp/harp.h>
14
15/* Harp: Flash LD10 (front pannel) connected to EPLD (IC8) */
16/* Overdrive: Flash LD1 (front panel) connected to EPLD (IC4) */
17/* Works for HARP and overdrive */
18static void mach_led(int position, int value)
19{
20 if (value) {
21 ctrl_outl(EPLD_LED_ON, EPLD_LED);
22 } else {
23 ctrl_outl(EPLD_LED_OFF, EPLD_LED);
24 }
25}
26
27#ifdef CONFIG_HEARTBEAT
28
29#include <linux/sched.h>
30
31/* acts like an actual heart beat -- ie thump-thump-pause... */
32void heartbeat_harp(void)
33{
34 static unsigned cnt = 0, period = 0, dist = 0;
35
36 if (cnt == 0 || cnt == dist)
37 mach_led( -1, 1);
38 else if (cnt == 7 || cnt == dist+7)
39 mach_led( -1, 0);
40
41 if (++cnt > period) {
42 cnt = 0;
43 /* The hyperbolic function below modifies the heartbeat period
44 * length in dependency of the current (5min) load. It goes
45 * through the points f(0)=126, f(1)=86, f(5)=51,
46 * f(inf)->30. */
47 period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
48 dist = period / 4;
49 }
50}
51#endif
diff --git a/arch/sh/boards/harp/mach.c b/arch/sh/boards/harp/mach.c
deleted file mode 100644
index a946dd1674ca..000000000000
--- a/arch/sh/boards/harp/mach.c
+++ /dev/null
@@ -1,62 +0,0 @@
1/*
2 * linux/arch/sh/boards/harp/mach.c
3 *
4 * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Machine vector for the STMicroelectronics STB1 HARP and compatible boards
10 */
11
12#include <linux/init.h>
13
14#include <asm/machvec.h>
15#include <asm/rtc.h>
16#include <asm/machvec_init.h>
17#include <asm/hd64465/io.h>
18#include <asm/hd64465/hd64465.h>
19
20void setup_harp(void);
21void init_harp_irq(void);
22void heartbeat_harp(void);
23
24/*
25 * The Machine Vector
26 */
27
28struct sh_machine_vector mv_harp __initmv = {
29 .mv_nr_irqs = 89 + HD64465_IRQ_NUM,
30
31 .mv_inb = hd64465_inb,
32 .mv_inw = hd64465_inw,
33 .mv_inl = hd64465_inl,
34 .mv_outb = hd64465_outb,
35 .mv_outw = hd64465_outw,
36 .mv_outl = hd64465_outl,
37
38 .mv_inb_p = hd64465_inb_p,
39 .mv_inw_p = hd64465_inw,
40 .mv_inl_p = hd64465_inl,
41 .mv_outb_p = hd64465_outb_p,
42 .mv_outw_p = hd64465_outw,
43 .mv_outl_p = hd64465_outl,
44
45 .mv_insb = hd64465_insb,
46 .mv_insw = hd64465_insw,
47 .mv_insl = hd64465_insl,
48 .mv_outsb = hd64465_outsb,
49 .mv_outsw = hd64465_outsw,
50 .mv_outsl = hd64465_outsl,
51
52 .mv_isa_port2addr = hd64465_isa_port2addr,
53
54#ifdef CONFIG_PCI
55 .mv_init_irq = init_harp_irq,
56#endif
57#ifdef CONFIG_HEARTBEAT
58 .mv_heartbeat = heartbeat_harp,
59#endif
60};
61
62ALIAS_MV(harp)
diff --git a/arch/sh/boards/harp/pcidma.c b/arch/sh/boards/harp/pcidma.c
deleted file mode 100644
index 475311390fd6..000000000000
--- a/arch/sh/boards/harp/pcidma.c
+++ /dev/null
@@ -1,42 +0,0 @@
1/*
2 * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * Dynamic DMA mapping support.
8 */
9
10#include <linux/types.h>
11#include <linux/mm.h>
12#include <linux/string.h>
13#include <linux/pci.h>
14#include <asm/io.h>
15#include <asm/addrspace.h>
16
17
18void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
19 dma_addr_t * dma_handle)
20{
21 void *ret;
22 int gfp = GFP_ATOMIC;
23
24 ret = (void *) __get_free_pages(gfp, get_order(size));
25
26 if (ret != NULL) {
27 /* Is it neccessary to do the memset? */
28 memset(ret, 0, size);
29 *dma_handle = virt_to_bus(ret);
30 }
31 /* We must flush the cache before we pass it on to the device */
32 flush_cache_all();
33 return P2SEGADDR(ret);
34}
35
36void pci_free_consistent(struct pci_dev *hwdev, size_t size,
37 void *vaddr, dma_addr_t dma_handle)
38{
39 unsigned long p1addr=P1SEGADDR((unsigned long)vaddr);
40
41 free_pages(p1addr, get_order(size));
42}
diff --git a/arch/sh/boards/harp/setup.c b/arch/sh/boards/harp/setup.c
deleted file mode 100644
index 886e450ab63e..000000000000
--- a/arch/sh/boards/harp/setup.c
+++ /dev/null
@@ -1,90 +0,0 @@
1/*
2 * arch/sh/stboard/setup.c
3 *
4 * Copyright (C) 2001 Stuart Menefy (stuart.menefy@st.com)
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * STMicroelectronics ST40STB1 HARP and compatible support.
10 */
11
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <asm/io.h>
15#include <asm/harp/harp.h>
16
17const char *get_system_type(void)
18{
19 return "STB1 Harp";
20}
21
22/*
23 * Initialize the board
24 */
25int __init platform_setup(void)
26{
27#ifdef CONFIG_SH_STB1_HARP
28 unsigned long ic8_version, ic36_version;
29
30 ic8_version = ctrl_inl(EPLD_REVID2);
31 ic36_version = ctrl_inl(EPLD_REVID1);
32
33 printk("STMicroelectronics STB1 HARP initialisaton\n");
34 printk("EPLD versions: IC8: %d.%02d, IC36: %d.%02d\n",
35 (ic8_version >> 4) & 0xf, ic8_version & 0xf,
36 (ic36_version >> 4) & 0xf, ic36_version & 0xf);
37#elif defined(CONFIG_SH_STB1_OVERDRIVE)
38 unsigned long version;
39
40 version = ctrl_inl(EPLD_REVID);
41
42 printk("STMicroelectronics STB1 Overdrive initialisaton\n");
43 printk("EPLD version: %d.%02d\n",
44 (version >> 4) & 0xf, version & 0xf);
45#else
46#error Undefined machine
47#endif
48
49 /* Currently all STB1 chips have problems with the sleep instruction,
50 * so disable it here.
51 */
52 disable_hlt();
53
54 return 0;
55}
56
57/*
58 * pcibios_map_platform_irq
59 *
60 * This is board specific and returns the IRQ for a given PCI device.
61 * It is used by the PCI code (arch/sh/kernel/st40_pci*)
62 *
63 */
64
65#define HARP_PCI_IRQ 1
66#define HARP_BRIDGE_IRQ 2
67#define OVERDRIVE_SLOT0_IRQ 0
68
69
70int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin)
71{
72 switch (slot) {
73#ifdef CONFIG_SH_STB1_HARP
74 case 2: /*This is the PCI slot on the */
75 return HARP_PCI_IRQ;
76 case 1: /* this is the bridge */
77 return HARP_BRIDGE_IRQ;
78#elif defined(CONFIG_SH_STB1_OVERDRIVE)
79 case 1:
80 case 2:
81 case 3:
82 return slot - 1;
83#else
84#error Unknown board
85#endif
86 default:
87 return -1;
88 }
89}
90
diff --git a/arch/sh/boards/hp6xx/Makefile b/arch/sh/boards/hp6xx/Makefile
index 927fe0aa5dfa..ff1b7f5b4e91 100644
--- a/arch/sh/boards/hp6xx/Makefile
+++ b/arch/sh/boards/hp6xx/Makefile
@@ -2,5 +2,6 @@
2# Makefile for the HP6xx specific parts of the kernel 2# Makefile for the HP6xx specific parts of the kernel
3# 3#
4 4
5obj-y := mach.o setup.o 5obj-y := setup.o
6 6obj-$(CONFIG_PM) += pm.o pm_wakeup.o
7obj-$(CONFIG_APM) += hp6xx_apm.o
diff --git a/arch/sh/boards/hp6xx/hp6xx_apm.c b/arch/sh/boards/hp6xx/hp6xx_apm.c
new file mode 100644
index 000000000000..ad0e712c29f6
--- /dev/null
+++ b/arch/sh/boards/hp6xx/hp6xx_apm.c
@@ -0,0 +1,123 @@
1/*
2 * bios-less APM driver for hp680
3 *
4 * Copyright 2005 (c) Andriy Skulysh <askulysh@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License.
8 */
9#include <linux/config.h>
10#include <linux/module.h>
11#include <linux/apm_bios.h>
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/interrupt.h>
15#include <asm/io.h>
16#include <asm/apm.h>
17#include <asm/adc.h>
18#include <asm/hp6xx/hp6xx.h>
19
20#define SH7709_PGDR 0xa400012c
21
22#define APM_CRITICAL 10
23#define APM_LOW 30
24
25#define HP680_BATTERY_MAX 875
26#define HP680_BATTERY_MIN 600
27#define HP680_BATTERY_AC_ON 900
28
29#define MODNAME "hp6x0_apm"
30
31static int hp6x0_apm_get_info(char *buf, char **start, off_t fpos, int length)
32{
33 u8 pgdr;
34 char *p;
35 int battery_status;
36 int battery_flag;
37 int ac_line_status;
38 int time_units = APM_BATTERY_LIFE_UNKNOWN;
39
40 int battery = adc_single(ADC_CHANNEL_BATTERY);
41 int backup = adc_single(ADC_CHANNEL_BACKUP);
42 int charging = adc_single(ADC_CHANNEL_CHARGE);
43 int percentage;
44
45 percentage = 100 * (battery - HP680_BATTERY_MIN) /
46 (HP680_BATTERY_MAX - HP680_BATTERY_MIN);
47
48 ac_line_status = (battery > HP680_BATTERY_AC_ON) ?
49 APM_AC_ONLINE : APM_AC_OFFLINE;
50
51 p = buf;
52
53 pgdr = ctrl_inb(SH7709_PGDR);
54 if (pgdr & PGDR_MAIN_BATTERY_OUT) {
55 battery_status = APM_BATTERY_STATUS_NOT_PRESENT;
56 battery_flag = 0x80;
57 percentage = -1;
58 } else if (charging < 8 ) {
59 battery_status = APM_BATTERY_STATUS_CHARGING;
60 battery_flag = 0x08;
61 ac_line_status = 0xff;
62 } else if (percentage <= APM_CRITICAL) {
63 battery_status = APM_BATTERY_STATUS_CRITICAL;
64 battery_flag = 0x04;
65 } else if (percentage <= APM_LOW) {
66 battery_status = APM_BATTERY_STATUS_LOW;
67 battery_flag = 0x02;
68 } else {
69 battery_status = APM_BATTERY_STATUS_HIGH;
70 battery_flag = 0x01;
71 }
72
73 p += sprintf(p, "1.0 1.2 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n",
74 APM_32_BIT_SUPPORT,
75 ac_line_status,
76 battery_status,
77 battery_flag,
78 percentage,
79 time_units,
80 "min");
81 p += sprintf(p, "bat=%d backup=%d charge=%d\n",
82 battery, backup, charging);
83
84 return p - buf;
85}
86
87static irqreturn_t hp6x0_apm_interrupt(int irq, void *dev, struct pt_regs *regs)
88{
89 if (!apm_suspended)
90 apm_queue_event(APM_USER_SUSPEND);
91
92 return IRQ_HANDLED;
93}
94
95static int __init hp6x0_apm_init(void)
96{
97 int ret;
98
99 ret = request_irq(HP680_BTN_IRQ, hp6x0_apm_interrupt,
100 SA_INTERRUPT, MODNAME, 0);
101 if (unlikely(ret < 0)) {
102 printk(KERN_ERR MODNAME ": IRQ %d request failed\n",
103 HP680_BTN_IRQ);
104 return ret;
105 }
106
107 apm_get_info = hp6x0_apm_get_info;
108
109 return ret;
110}
111
112static void __exit hp6x0_apm_exit(void)
113{
114 free_irq(HP680_BTN_IRQ, 0);
115 apm_get_info = 0;
116}
117
118module_init(hp6x0_apm_init);
119module_exit(hp6x0_apm_exit);
120
121MODULE_AUTHOR("Adriy Skulysh");
122MODULE_DESCRIPTION("hp6xx Advanced Power Management");
123MODULE_LICENSE("GPL");
diff --git a/arch/sh/boards/hp6xx/pm.c b/arch/sh/boards/hp6xx/pm.c
new file mode 100644
index 000000000000..0e501bcbd7a9
--- /dev/null
+++ b/arch/sh/boards/hp6xx/pm.c
@@ -0,0 +1,88 @@
1/*
2 * hp6x0 Power Management Routines
3 *
4 * Copyright (c) 2006 Andriy Skulysh <askulsyh@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License.
8 */
9#include <linux/config.h>
10#include <linux/init.h>
11#include <linux/suspend.h>
12#include <linux/errno.h>
13#include <linux/time.h>
14#include <asm/io.h>
15#include <asm/hd64461.h>
16#include <asm/hp6xx/hp6xx.h>
17#include <asm/cpu/dac.h>
18#include <asm/pm.h>
19
20#define STBCR 0xffffff82
21#define STBCR2 0xffffff88
22
23static int hp6x0_pm_enter(suspend_state_t state)
24{
25 u8 stbcr, stbcr2;
26#ifdef CONFIG_HD64461_ENABLER
27 u8 scr;
28 u16 hd64461_stbcr;
29#endif
30
31 if (state != PM_SUSPEND_MEM)
32 return -EINVAL;
33
34#ifdef CONFIG_HD64461_ENABLER
35 outb(0, HD64461_PCC1CSCIER);
36
37 scr = inb(HD64461_PCC1SCR);
38 scr |= HD64461_PCCSCR_VCC1;
39 outb(scr, HD64461_PCC1SCR);
40
41 hd64461_stbcr = inw(HD64461_STBCR);
42 hd64461_stbcr |= HD64461_STBCR_SPC1ST;
43 outw(hd64461_stbcr, HD64461_STBCR);
44#endif
45
46 ctrl_outb(0x1f, DACR);
47
48 stbcr = ctrl_inb(STBCR);
49 ctrl_outb(0x01, STBCR);
50
51 stbcr2 = ctrl_inb(STBCR2);
52 ctrl_outb(0x7f , STBCR2);
53
54 outw(0xf07f, HD64461_SCPUCR);
55
56 pm_enter();
57
58 outw(0, HD64461_SCPUCR);
59 ctrl_outb(stbcr, STBCR);
60 ctrl_outb(stbcr2, STBCR2);
61
62#ifdef CONFIG_HD64461_ENABLER
63 hd64461_stbcr = inw(HD64461_STBCR);
64 hd64461_stbcr &= ~HD64461_STBCR_SPC1ST;
65 outw(hd64461_stbcr, HD64461_STBCR);
66
67 outb(0x4c, HD64461_PCC1CSCIER);
68 outb(0x00, HD64461_PCC1CSCR);
69#endif
70
71 return 0;
72}
73
74/*
75 * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
76 */
77static struct pm_ops hp6x0_pm_ops = {
78 .pm_disk_mode = PM_DISK_FIRMWARE,
79 .enter = hp6x0_pm_enter,
80};
81
82static int __init hp6x0_pm_init(void)
83{
84 pm_set_ops(&hp6x0_pm_ops);
85 return 0;
86}
87
88late_initcall(hp6x0_pm_init);
diff --git a/arch/sh/boards/hp6xx/pm_wakeup.S b/arch/sh/boards/hp6xx/pm_wakeup.S
new file mode 100644
index 000000000000..45e9bf0b9115
--- /dev/null
+++ b/arch/sh/boards/hp6xx/pm_wakeup.S
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 2006 Andriy Skulysh <askulsyh@gmail.com>
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 */
9
10#include <linux/linkage.h>
11#include <asm/cpu/mmu_context.h>
12
13#define k0 r0
14#define k1 r1
15#define k2 r2
16#define k3 r3
17#define k4 r4
18
19/*
20 * Kernel mode register usage:
21 * k0 scratch
22 * k1 scratch
23 * k2 scratch (Exception code)
24 * k3 scratch (Return address)
25 * k4 scratch
26 * k5 reserved
27 * k6 Global Interrupt Mask (0--15 << 4)
28 * k7 CURRENT_THREAD_INFO (pointer to current thread info)
29 */
30
31ENTRY(wakeup_start)
32! clear STBY bit
33 mov #-126, k2
34 and #127, k0
35 mov.b k0, @k2
36! enable refresh
37 mov.l 5f, k1
38 mov.w 6f, k0
39 mov.w k0, @k1
40! jump to handler
41 mov.l 2f, k2
42 mov.l 3f, k3
43 mov.l @k2, k2
44
45 mov.l 4f, k1
46 jmp @k1
47 nop
48
49 .align 2
501: .long EXPEVT
512: .long INTEVT
523: .long ret_from_irq
534: .long handle_exception
545: .long 0xffffff68
556: .word 0x0524
56
57ENTRY(wakeup_end)
58 nop
diff --git a/arch/sh/boards/hp6xx/setup.c b/arch/sh/boards/hp6xx/setup.c
index 71f315663cc9..60ab17ad6054 100644
--- a/arch/sh/boards/hp6xx/setup.c
+++ b/arch/sh/boards/hp6xx/setup.c
@@ -8,22 +8,22 @@
8 * 8 *
9 * Setup code for an HP680 (internal peripherials only) 9 * Setup code for an HP680 (internal peripherials only)
10 */ 10 */
11 11#include <linux/types.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <asm/io.h>
14#include <asm/hd64461.h> 13#include <asm/hd64461.h>
14#include <asm/io.h>
15#include <asm/irq.h>
15#include <asm/hp6xx/hp6xx.h> 16#include <asm/hp6xx/hp6xx.h>
16#include <asm/cpu/dac.h> 17#include <asm/cpu/dac.h>
17 18
18const char *get_system_type(void) 19#define SCPCR 0xa4000116
19{ 20#define SCPDR 0xa4000136
20 return "HP6xx";
21}
22 21
23int __init platform_setup(void) 22static void __init hp6xx_setup(char **cmdline_p)
24{ 23{
25 u8 v8; 24 u8 v8;
26 u16 v; 25 u16 v;
26
27 v = inw(HD64461_STBCR); 27 v = inw(HD64461_STBCR);
28 v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST | 28 v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST |
29 HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST | 29 HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST |
@@ -50,5 +50,51 @@ int __init platform_setup(void)
50 v8 &= ~DACR_DAE; 50 v8 &= ~DACR_DAE;
51 ctrl_outb(v8,DACR); 51 ctrl_outb(v8,DACR);
52 52
53 return 0; 53 v8 = ctrl_inb(SCPDR);
54 v8 |= SCPDR_TS_SCAN_X | SCPDR_TS_SCAN_Y;
55 v8 &= ~SCPDR_TS_SCAN_ENABLE;
56 ctrl_outb(v8, SCPDR);
57
58 v = ctrl_inw(SCPCR);
59 v &= ~SCPCR_TS_MASK;
60 v |= SCPCR_TS_ENABLE;
61 ctrl_outw(v, SCPCR);
54} 62}
63
64/*
65 * XXX: This is stupid, we should have a generic machine vector for the cchips
66 * and just wrap the platform setup code in to this, as it's the only thing
67 * that ends up being different.
68 */
69struct sh_machine_vector mv_hp6xx __initmv = {
70 .mv_name = "hp6xx",
71 .mv_setup = hp6xx_setup,
72 .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM,
73
74 .mv_inb = hd64461_inb,
75 .mv_inw = hd64461_inw,
76 .mv_inl = hd64461_inl,
77 .mv_outb = hd64461_outb,
78 .mv_outw = hd64461_outw,
79 .mv_outl = hd64461_outl,
80
81 .mv_inb_p = hd64461_inb_p,
82 .mv_inw_p = hd64461_inw,
83 .mv_inl_p = hd64461_inl,
84 .mv_outb_p = hd64461_outb_p,
85 .mv_outw_p = hd64461_outw,
86 .mv_outl_p = hd64461_outl,
87
88 .mv_insb = hd64461_insb,
89 .mv_insw = hd64461_insw,
90 .mv_insl = hd64461_insl,
91 .mv_outsb = hd64461_outsb,
92 .mv_outsw = hd64461_outsw,
93 .mv_outsl = hd64461_outsl,
94
95 .mv_readw = hd64461_readw,
96 .mv_writew = hd64461_writew,
97
98 .mv_irq_demux = hd64461_irq_demux,
99};
100ALIAS_MV(hp6xx)
diff --git a/arch/sh/boards/landisk/Makefile b/arch/sh/boards/landisk/Makefile
new file mode 100644
index 000000000000..89e4beb2ad47
--- /dev/null
+++ b/arch/sh/boards/landisk/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for I-O DATA DEVICE, INC. "LANDISK Series"
3#
4
5obj-y := setup.o io.o irq.o rtc.o landisk_pwb.o
diff --git a/arch/sh/boards/landisk/io.c b/arch/sh/boards/landisk/io.c
new file mode 100644
index 000000000000..92498b4947d5
--- /dev/null
+++ b/arch/sh/boards/landisk/io.c
@@ -0,0 +1,250 @@
1/*
2 * arch/sh/boards/landisk/io.c
3 *
4 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
5 * Based largely on io_se.c.
6 *
7 * I/O routine for I-O Data Device, Inc. LANDISK.
8 *
9 * Initial version only to support LAN access; some
10 * placeholder code from io_landisk.c left in with the
11 * expectation of later SuperIO and PCMCIA access.
12 */
13/*
14 * modifed by kogiidena
15 * 2005.03.03
16 */
17#include <linux/kernel.h>
18#include <linux/types.h>
19#include <linux/pci.h>
20#include <asm/landisk/iodata_landisk.h>
21#include <asm/addrspace.h>
22#include <asm/io.h>
23
24extern void *area5_io_base; /* Area 5 I/O Base address */
25extern void *area6_io_base; /* Area 6 I/O Base address */
26
27static inline unsigned long port2adr(unsigned int port)
28{
29 if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
30 if (port == 0x3f6)
31 return ((unsigned long)area5_io_base + 0x2c);
32 else
33 return ((unsigned long)area5_io_base + PA_PIDE_OFFSET +
34 ((port - 0x1f0) << 1));
35 else if ((0x170 <= port && port < 0x178) || port == 0x376)
36 if (port == 0x376)
37 return ((unsigned long)area6_io_base + 0x2c);
38 else
39 return ((unsigned long)area6_io_base + PA_SIDE_OFFSET +
40 ((port - 0x170) << 1));
41 else
42 maybebadio((unsigned long)port);
43
44 return port;
45}
46
47/*
48 * General outline: remap really low stuff [eventually] to SuperIO,
49 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
50 * is mapped through the PCI IO window. Stuff with high bits (PXSEG)
51 * should be way beyond the window, and is used w/o translation for
52 * compatibility.
53 */
54u8 landisk_inb(unsigned long port)
55{
56 if (PXSEG(port))
57 return ctrl_inb(port);
58 else if (is_pci_ioaddr(port))
59 return ctrl_inb(pci_ioaddr(port));
60
61 return ctrl_inw(port2adr(port)) & 0xff;
62}
63
64u8 landisk_inb_p(unsigned long port)
65{
66 u8 v;
67
68 if (PXSEG(port))
69 v = ctrl_inb(port);
70 else if (is_pci_ioaddr(port))
71 v = ctrl_inb(pci_ioaddr(port));
72 else
73 v = ctrl_inw(port2adr(port)) & 0xff;
74
75 ctrl_delay();
76
77 return v;
78}
79
80u16 landisk_inw(unsigned long port)
81{
82 if (PXSEG(port))
83 return ctrl_inw(port);
84 else if (is_pci_ioaddr(port))
85 return ctrl_inw(pci_ioaddr(port));
86 else
87 maybebadio(port);
88
89 return 0;
90}
91
92u32 landisk_inl(unsigned long port)
93{
94 if (PXSEG(port))
95 return ctrl_inl(port);
96 else if (is_pci_ioaddr(port))
97 return ctrl_inl(pci_ioaddr(port));
98 else
99 maybebadio(port);
100
101 return 0;
102}
103
104void landisk_outb(u8 value, unsigned long port)
105{
106 if (PXSEG(port))
107 ctrl_outb(value, port);
108 else if (is_pci_ioaddr(port))
109 ctrl_outb(value, pci_ioaddr(port));
110 else
111 ctrl_outw(value, port2adr(port));
112}
113
114void landisk_outb_p(u8 value, unsigned long port)
115{
116 if (PXSEG(port))
117 ctrl_outb(value, port);
118 else if (is_pci_ioaddr(port))
119 ctrl_outb(value, pci_ioaddr(port));
120 else
121 ctrl_outw(value, port2adr(port));
122 ctrl_delay();
123}
124
125void landisk_outw(u16 value, unsigned long port)
126{
127 if (PXSEG(port))
128 ctrl_outw(value, port);
129 else if (is_pci_ioaddr(port))
130 ctrl_outw(value, pci_ioaddr(port));
131 else
132 maybebadio(port);
133}
134
135void landisk_outl(u32 value, unsigned long port)
136{
137 if (PXSEG(port))
138 ctrl_outl(value, port);
139 else if (is_pci_ioaddr(port))
140 ctrl_outl(value, pci_ioaddr(port));
141 else
142 maybebadio(port);
143}
144
145void landisk_insb(unsigned long port, void *dst, unsigned long count)
146{
147 volatile u16 *p;
148 u8 *buf = dst;
149
150 if (PXSEG(port)) {
151 while (count--)
152 *buf++ = *(volatile u8 *)port;
153 } else if (is_pci_ioaddr(port)) {
154 volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
155
156 while (count--)
157 *buf++ = *bp;
158 } else {
159 p = (volatile u16 *)port2adr(port);
160 while (count--)
161 *buf++ = *p & 0xff;
162 }
163}
164
165void landisk_insw(unsigned long port, void *dst, unsigned long count)
166{
167 volatile u16 *p;
168 u16 *buf = dst;
169
170 if (PXSEG(port))
171 p = (volatile u16 *)port;
172 else if (is_pci_ioaddr(port))
173 p = (volatile u16 *)pci_ioaddr(port);
174 else
175 p = (volatile u16 *)port2adr(port);
176 while (count--)
177 *buf++ = *p;
178}
179
180void landisk_insl(unsigned long port, void *dst, unsigned long count)
181{
182 u32 *buf = dst;
183
184 if (is_pci_ioaddr(port)) {
185 volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
186
187 while (count--)
188 *buf++ = *p;
189 } else
190 maybebadio(port);
191}
192
193void landisk_outsb(unsigned long port, const void *src, unsigned long count)
194{
195 volatile u16 *p;
196 const u8 *buf = src;
197
198 if (PXSEG(port))
199 while (count--)
200 ctrl_outb(*buf++, port);
201 else if (is_pci_ioaddr(port)) {
202 volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
203
204 while (count--)
205 *bp = *buf++;
206 } else {
207 p = (volatile u16 *)port2adr(port);
208 while (count--)
209 *p = *buf++;
210 }
211}
212
213void landisk_outsw(unsigned long port, const void *src, unsigned long count)
214{
215 volatile u16 *p;
216 const u16 *buf = src;
217
218 if (PXSEG(port))
219 p = (volatile u16 *)port;
220 else if (is_pci_ioaddr(port))
221 p = (volatile u16 *)pci_ioaddr(port);
222 else
223 p = (volatile u16 *)port2adr(port);
224
225 while (count--)
226 *p = *buf++;
227}
228
229void landisk_outsl(unsigned long port, const void *src, unsigned long count)
230{
231 const u32 *buf = src;
232
233 if (is_pci_ioaddr(port)) {
234 volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
235
236 while (count--)
237 *p = *buf++;
238 } else
239 maybebadio(port);
240}
241
242void __iomem *landisk_ioport_map(unsigned long port, unsigned int size)
243{
244 if (PXSEG(port))
245 return (void __iomem *)port;
246 else if (is_pci_ioaddr(port))
247 return (void __iomem *)pci_ioaddr(port);
248
249 return (void __iomem *)port2adr(port);
250}
diff --git a/arch/sh/boards/landisk/irq.c b/arch/sh/boards/landisk/irq.c
new file mode 100644
index 000000000000..a006d6443225
--- /dev/null
+++ b/arch/sh/boards/landisk/irq.c
@@ -0,0 +1,99 @@
1/*
2 * arch/sh/boards/landisk/irq.c
3 *
4 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
5 * Based largely on io_se.c.
6 *
7 * I/O routine for I-O Data Device, Inc. LANDISK.
8 *
9 * Initial version only to support LAN access; some
10 * placeholder code from io_landisk.c left in with the
11 * expectation of later SuperIO and PCMCIA access.
12 */
13/*
14 * modified by kogiidena
15 * 2005.03.03
16 */
17
18#include <linux/config.h>
19#include <linux/init.h>
20#include <linux/irq.h>
21#include <asm/io.h>
22#include <asm/irq.h>
23#include <asm/landisk/iodata_landisk.h>
24
25static void enable_landisk_irq(unsigned int irq);
26static void disable_landisk_irq(unsigned int irq);
27
28/* shutdown is same as "disable" */
29#define shutdown_landisk_irq disable_landisk_irq
30
31static void ack_landisk_irq(unsigned int irq);
32static void end_landisk_irq(unsigned int irq);
33
34static unsigned int startup_landisk_irq(unsigned int irq)
35{
36 enable_landisk_irq(irq);
37 return 0; /* never anything pending */
38}
39
40static void disable_landisk_irq(unsigned int irq)
41{
42 unsigned char val;
43 unsigned char mask = 0xff ^ (0x01 << (irq - 5));
44
45 /* Set the priority in IPR to 0 */
46 val = ctrl_inb(PA_IMASK);
47 val &= mask;
48 ctrl_outb(val, PA_IMASK);
49}
50
51static void enable_landisk_irq(unsigned int irq)
52{
53 unsigned char val;
54 unsigned char value = (0x01 << (irq - 5));
55
56 /* Set priority in IPR back to original value */
57 val = ctrl_inb(PA_IMASK);
58 val |= value;
59 ctrl_outb(val, PA_IMASK);
60}
61
62static void ack_landisk_irq(unsigned int irq)
63{
64 disable_landisk_irq(irq);
65}
66
67static void end_landisk_irq(unsigned int irq)
68{
69 if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
70 enable_landisk_irq(irq);
71}
72
73static struct hw_interrupt_type landisk_irq_type = {
74 .typename = "LANDISK IRQ",
75 .startup = startup_landisk_irq,
76 .shutdown = shutdown_landisk_irq,
77 .enable = enable_landisk_irq,
78 .disable = disable_landisk_irq,
79 .ack = ack_landisk_irq,
80 .end = end_landisk_irq
81};
82
83static void make_landisk_irq(unsigned int irq)
84{
85 disable_irq_nosync(irq);
86 irq_desc[irq].handler = &landisk_irq_type;
87 disable_landisk_irq(irq);
88}
89
90/*
91 * Initialize IRQ setting
92 */
93void __init init_landisk_IRQ(void)
94{
95 int i;
96
97 for (i = 5; i < 14; i++)
98 make_landisk_irq(i);
99}
diff --git a/arch/sh/boards/landisk/landisk_pwb.c b/arch/sh/boards/landisk/landisk_pwb.c
new file mode 100644
index 000000000000..e75cb578a28b
--- /dev/null
+++ b/arch/sh/boards/landisk/landisk_pwb.c
@@ -0,0 +1,348 @@
1/*
2 * arch/sh/boards/landisk/landisk_pwb.c -- driver for the Power control switch.
3 *
4 * This driver will also support the I-O DATA Device, Inc. LANDISK Board.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copylight (C) 2002 Atom Create Engineering Co., Ltd.
11 *
12 * LED control drive function added by kogiidena
13 */
14
15#include <linux/config.h>
16#include <linux/module.h>
17#include <linux/errno.h>
18#include <linux/signal.h>
19#include <linux/major.h>
20#include <linux/poll.h>
21#include <linux/init.h>
22#include <linux/delay.h>
23#include <linux/sched.h>
24#include <linux/timer.h>
25#include <linux/interrupt.h>
26
27#include <asm/system.h>
28#include <asm/io.h>
29#include <asm/irq.h>
30#include <asm/uaccess.h>
31#include <asm/landisk/iodata_landisk.h>
32
33#define SHUTDOWN_BTN_MINOR 1 /* Shutdown button device minor no. */
34#define LED_MINOR 21 /* LED minor no. */
35#define BTN_MINOR 22 /* BUTTON minor no. */
36#define GIO_MINOR 40 /* GIO minor no. */
37
38static int openCnt;
39static int openCntLED;
40static int openCntGio;
41static int openCntBtn;
42static int landisk_btn;
43static int landisk_btnctrlpid;
44/*
45 * Functions prototypes
46 */
47
48static int gio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
49 unsigned long arg);
50
51static int swdrv_open(struct inode *inode, struct file *filp)
52{
53 int minor;
54
55 minor = MINOR(inode->i_rdev);
56 filp->private_data = (void *)minor;
57
58 if (minor == SHUTDOWN_BTN_MINOR) {
59 if (openCnt > 0) {
60 return -EALREADY;
61 } else {
62 openCnt++;
63 return 0;
64 }
65 } else if (minor == LED_MINOR) {
66 if (openCntLED > 0) {
67 return -EALREADY;
68 } else {
69 openCntLED++;
70 return 0;
71 }
72 } else if (minor == BTN_MINOR) {
73 if (openCntBtn > 0) {
74 return -EALREADY;
75 } else {
76 openCntBtn++;
77 return 0;
78 }
79 } else if (minor == GIO_MINOR) {
80 if (openCntGio > 0) {
81 return -EALREADY;
82 } else {
83 openCntGio++;
84 return 0;
85 }
86 }
87 return -ENOENT;
88
89}
90
91static int swdrv_close(struct inode *inode, struct file *filp)
92{
93 int minor;
94
95 minor = MINOR(inode->i_rdev);
96 if (minor == SHUTDOWN_BTN_MINOR) {
97 openCnt--;
98 } else if (minor == LED_MINOR) {
99 openCntLED--;
100 } else if (minor == BTN_MINOR) {
101 openCntBtn--;
102 } else if (minor == GIO_MINOR) {
103 openCntGio--;
104 }
105 return 0;
106}
107
108static int swdrv_read(struct file *filp, char *buff, size_t count,
109 loff_t * ppos)
110{
111 int minor;
112 minor = (int)(filp->private_data);
113
114 if (!access_ok(VERIFY_WRITE, (void *)buff, count))
115 return -EFAULT;
116
117 if (minor == SHUTDOWN_BTN_MINOR) {
118 if (landisk_btn & 0x10) {
119 put_user(1, buff);
120 return 1;
121 } else {
122 return 0;
123 }
124 }
125 return 0;
126}
127
128static int swdrv_write(struct file *filp, const char *buff, size_t count,
129 loff_t * ppos)
130{
131 int minor;
132 minor = (int)(filp->private_data);
133
134 if (minor == SHUTDOWN_BTN_MINOR) {
135 return count;
136 }
137 return count;
138}
139
140static irqreturn_t sw_interrupt(int irq, void *dev_id, struct pt_regs *regs)
141{
142 landisk_btn = (0x0ff & (~ctrl_inb(PA_STATUS)));
143 disable_irq(IRQ_BUTTON);
144 disable_irq(IRQ_POWER);
145 ctrl_outb(0x00, PA_PWRINT_CLR);
146
147 if (landisk_btnctrlpid != 0) {
148 kill_proc(landisk_btnctrlpid, SIGUSR1, 1);
149 landisk_btnctrlpid = 0;
150 }
151
152 return IRQ_HANDLED;
153}
154
155static struct file_operations swdrv_fops = {
156 .read = swdrv_read, /* read */
157 .write = swdrv_write, /* write */
158 .open = swdrv_open, /* open */
159 .release = swdrv_close, /* release */
160 .ioctl = gio_ioctl, /* ioctl */
161
162};
163
164static char banner[] __initdata =
165 KERN_INFO "LANDISK and USL-5P Button, LED and GIO driver initialized\n";
166
167int __init swdrv_init(void)
168{
169 int error;
170
171 printk("%s", banner);
172
173 openCnt = 0;
174 openCntLED = 0;
175 openCntBtn = 0;
176 openCntGio = 0;
177 landisk_btn = 0;
178 landisk_btnctrlpid = 0;
179
180 if ((error = register_chrdev(SHUTDOWN_BTN_MAJOR, "swdrv", &swdrv_fops))) {
181 printk(KERN_ERR
182 "Button, LED and GIO driver:Couldn't register driver, error=%d\n",
183 error);
184 return 1;
185 }
186
187 if (request_irq(IRQ_POWER, sw_interrupt, 0, "SHUTDOWNSWITCH", NULL)) {
188 printk(KERN_ERR "Unable to get IRQ 11.\n");
189 return 1;
190 }
191 if (request_irq(IRQ_BUTTON, sw_interrupt, 0, "USL-5P BUTTON", NULL)) {
192 printk(KERN_ERR "Unable to get IRQ 12.\n");
193 return 1;
194 }
195 ctrl_outb(0x00, PA_PWRINT_CLR);
196
197 return 0;
198}
199
200module_init(swdrv_init);
201
202/*
203 * gio driver
204 *
205 */
206
207#include <asm/landisk/gio.h>
208
209static int gio_ioctl(struct inode *inode, struct file *filp,
210 unsigned int cmd, unsigned long arg)
211{
212 int minor;
213 unsigned int data, mask;
214 static unsigned int addr = 0;
215
216 minor = (int)(filp->private_data);
217
218 /* access control */
219 if (minor == GIO_MINOR) {
220 ;
221 } else if (minor == LED_MINOR) {
222 if (((cmd & 0x0ff) >= 9) && ((cmd & 0x0ff) < 20)) {
223 ;
224 } else {
225 return -EINVAL;
226 }
227 } else if (minor == BTN_MINOR) {
228 if (((cmd & 0x0ff) >= 20) && ((cmd & 0x0ff) < 30)) {
229 ;
230 } else {
231 return -EINVAL;
232 }
233 } else {
234 return -EINVAL;
235 }
236
237 if (cmd & 0x01) { /* write */
238 if (copy_from_user(&data, (int *)arg, sizeof(int))) {
239 return -EFAULT;
240 }
241 }
242
243 switch (cmd) {
244 case GIODRV_IOCSGIOSETADDR: /* addres set */
245 addr = data;
246 break;
247
248 case GIODRV_IOCSGIODATA1: /* write byte */
249 ctrl_outb((unsigned char)(0x0ff & data), addr);
250 break;
251
252 case GIODRV_IOCSGIODATA2: /* write word */
253 if (addr & 0x01) {
254 return -EFAULT;
255 }
256 ctrl_outw((unsigned short int)(0x0ffff & data), addr);
257 break;
258
259 case GIODRV_IOCSGIODATA4: /* write long */
260 if (addr & 0x03) {
261 return -EFAULT;
262 }
263 ctrl_outl(data, addr);
264 break;
265
266 case GIODRV_IOCGGIODATA1: /* read byte */
267 data = ctrl_inb(addr);
268 break;
269
270 case GIODRV_IOCGGIODATA2: /* read word */
271 if (addr & 0x01) {
272 return -EFAULT;
273 }
274 data = ctrl_inw(addr);
275 break;
276
277 case GIODRV_IOCGGIODATA4: /* read long */
278 if (addr & 0x03) {
279 return -EFAULT;
280 }
281 data = ctrl_inl(addr);
282 break;
283 case GIODRV_IOCSGIO_LED: /* write */
284 mask = ((data & 0x00ffffff) << 8)
285 | ((data & 0x0000ffff) << 16)
286 | ((data & 0x000000ff) << 24);
287 landisk_ledparam = data & (~mask);
288 if (landisk_arch == 0) { /* arch == landisk */
289 landisk_ledparam &= 0x03030303;
290 mask = (~(landisk_ledparam >> 22)) & 0x000c;
291 landisk_ledparam |= mask;
292 } else { /* arch == usl-5p */
293 mask = (landisk_ledparam >> 24) & 0x0001;
294 landisk_ledparam |= mask;
295 landisk_ledparam &= 0x007f7f7f;
296 }
297 landisk_ledparam |= 0x80;
298 break;
299 case GIODRV_IOCGGIO_LED: /* read */
300 data = landisk_ledparam;
301 if (landisk_arch == 0) { /* arch == landisk */
302 data &= 0x03030303;
303 } else { /* arch == usl-5p */
304 ;
305 }
306 data &= (~0x080);
307 break;
308 case GIODRV_IOCSGIO_BUZZER: /* write */
309 landisk_buzzerparam = data;
310 landisk_ledparam |= 0x80;
311 break;
312 case GIODRV_IOCGGIO_LANDISK: /* read */
313 data = landisk_arch & 0x01;
314 break;
315 case GIODRV_IOCGGIO_BTN: /* read */
316 data = (0x0ff & ctrl_inb(PA_PWRINT_CLR));
317 data <<= 8;
318 data |= (0x0ff & ctrl_inb(PA_IMASK));
319 data <<= 8;
320 data |= (0x0ff & landisk_btn);
321 data <<= 8;
322 data |= (0x0ff & (~ctrl_inb(PA_STATUS)));
323 break;
324 case GIODRV_IOCSGIO_BTNPID: /* write */
325 landisk_btnctrlpid = data;
326 landisk_btn = 0;
327 if (irq_desc[IRQ_BUTTON].depth) {
328 enable_irq(IRQ_BUTTON);
329 }
330 if (irq_desc[IRQ_POWER].depth) {
331 enable_irq(IRQ_POWER);
332 }
333 break;
334 case GIODRV_IOCGGIO_BTNPID: /* read */
335 data = landisk_btnctrlpid;
336 break;
337 default:
338 return -EFAULT;
339 break;
340 }
341
342 if ((cmd & 0x01) == 0) { /* read */
343 if (copy_to_user((int *)arg, &data, sizeof(int))) {
344 return -EFAULT;
345 }
346 }
347 return 0;
348}
diff --git a/arch/sh/boards/landisk/rtc.c b/arch/sh/boards/landisk/rtc.c
new file mode 100644
index 000000000000..35ba726a0979
--- /dev/null
+++ b/arch/sh/boards/landisk/rtc.c
@@ -0,0 +1,93 @@
1/*
2 * arch/sh/boards/landisk/rtc.c -- RTC support
3 *
4 * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
5 * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
6 */
7/*
8 * modifed by kogiidena
9 * 2005.09.16
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14#include <linux/kernel.h>
15#include <linux/sched.h>
16#include <linux/time.h>
17#include <linux/delay.h>
18#include <linux/spinlock.h>
19#include <linux/bcd.h>
20#include <asm/rtc.h>
21
22extern spinlock_t rtc_lock;
23
24extern void
25rs5c313_set_cmos_time(unsigned int BCD_yr, unsigned int BCD_mon,
26 unsigned int BCD_day, unsigned int BCD_hr,
27 unsigned int BCD_min, unsigned int BCD_sec);
28
29extern unsigned long
30rs5c313_get_cmos_time(unsigned int *BCD_yr, unsigned int *BCD_mon,
31 unsigned int *BCD_day, unsigned int *BCD_hr,
32 unsigned int *BCD_min, unsigned int *BCD_sec);
33
34void landisk_rtc_gettimeofday(struct timespec *tv)
35{
36 unsigned int BCD_yr, BCD_mon, BCD_day, BCD_hr, BCD_min, BCD_sec;
37 unsigned long flags;
38
39 spin_lock_irqsave(&rtc_lock, flags);
40 tv->tv_sec = rs5c313_get_cmos_time
41 (&BCD_yr, &BCD_mon, &BCD_day, &BCD_hr, &BCD_min, &BCD_sec);
42 tv->tv_nsec = 0;
43 spin_unlock_irqrestore(&rtc_lock, flags);
44}
45
46int landisk_rtc_settimeofday(const time_t secs)
47{
48 int retval = 0;
49 int real_seconds, real_minutes, cmos_minutes;
50 unsigned long flags;
51 unsigned long nowtime = secs;
52 unsigned int BCD_yr, BCD_mon, BCD_day, BCD_hr, BCD_min, BCD_sec;
53
54 spin_lock_irqsave(&rtc_lock, flags);
55
56 rs5c313_get_cmos_time
57 (&BCD_yr, &BCD_mon, &BCD_day, &BCD_hr, &BCD_min, &BCD_sec);
58 cmos_minutes = BCD_min;
59 BCD_TO_BIN(cmos_minutes);
60
61 /*
62 * since we're only adjusting minutes and seconds,
63 * don't interfere with hour overflow. This avoids
64 * messing with unknown time zones but requires your
65 * RTC not to be off by more than 15 minutes
66 */
67 real_seconds = nowtime % 60;
68 real_minutes = nowtime / 60;
69 if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1)
70 real_minutes += 30; /* correct for half hour time zone */
71 real_minutes %= 60;
72
73 if (abs(real_minutes - cmos_minutes) < 30) {
74 BIN_TO_BCD(real_seconds);
75 BIN_TO_BCD(real_minutes);
76 rs5c313_set_cmos_time(BCD_yr, BCD_mon, BCD_day, BCD_hr,
77 real_minutes, real_seconds);
78 } else {
79 printk(KERN_WARNING
80 "set_rtc_time: can't update from %d to %d\n",
81 cmos_minutes, real_minutes);
82 retval = -1;
83 }
84
85 spin_unlock_irqrestore(&rtc_lock, flags);
86 return retval;
87}
88
89void landisk_time_init(void)
90{
91 rtc_sh_get_time = landisk_rtc_gettimeofday;
92 rtc_sh_set_time = landisk_rtc_settimeofday;
93}
diff --git a/arch/sh/boards/landisk/setup.c b/arch/sh/boards/landisk/setup.c
new file mode 100644
index 000000000000..127b9e020e00
--- /dev/null
+++ b/arch/sh/boards/landisk/setup.c
@@ -0,0 +1,177 @@
1/*
2 * arch/sh/boards/landisk/setup.c
3 *
4 * Copyright (C) 2000 Kazumoto Kojima
5 * Copyright (C) 2002 Paul Mundt
6 *
7 * I-O DATA Device, Inc. LANDISK Support.
8 *
9 * Modified for LANDISK by
10 * Atom Create Engineering Co., Ltd. 2002.
11 *
12 * modifed by kogiidena
13 * 2005.09.16
14 *
15 * This file is subject to the terms and conditions of the GNU General Public
16 * License. See the file "COPYING" in the main directory of this archive
17 * for more details.
18 */
19#include <linux/config.h>
20#include <linux/init.h>
21#include <linux/pm.h>
22#include <linux/mm.h>
23#include <asm/machvec.h>
24#include <asm/rtc.h>
25#include <asm/landisk/iodata_landisk.h>
26#include <asm/io.h>
27
28void landisk_time_init(void);
29void init_landisk_IRQ(void);
30
31int landisk_ledparam;
32int landisk_buzzerparam;
33int landisk_arch;
34
35/* cycle the led's in the clasic knightrider/sun pattern */
36static void heartbeat_landisk(void)
37{
38 static unsigned int cnt = 0, blink = 0x00, period = 25;
39 volatile u8 *p = (volatile u8 *)PA_LED;
40 char data;
41
42 if ((landisk_ledparam & 0x080) == 0)
43 return;
44
45 cnt += 1;
46
47 if (cnt < period)
48 return;
49
50 cnt = 0;
51 blink++;
52
53 data = (blink & 0x01) ? (landisk_ledparam >> 16) : 0;
54 data |= (blink & 0x02) ? (landisk_ledparam >> 8) : 0;
55 data |= landisk_ledparam;
56
57 /* buzzer */
58 if (landisk_buzzerparam & 0x1) {
59 data |= 0x80;
60 } else {
61 data &= 0x7f;
62 }
63 *p = data;
64
65 if (((landisk_ledparam & 0x007f7f00) == 0) &&
66 (landisk_buzzerparam == 0))
67 landisk_ledparam &= (~0x0080);
68
69 landisk_buzzerparam >>= 1;
70}
71
72static void landisk_power_off(void)
73{
74 ctrl_outb(0x01, PA_SHUTDOWN);
75}
76
77static void check_usl5p(void)
78{
79 volatile u8 *p = (volatile u8 *)PA_LED;
80 u8 tmp1, tmp2;
81
82 tmp1 = *p;
83 *p = 0x40;
84 tmp2 = *p;
85 *p = tmp1;
86
87 landisk_arch = (tmp2 == 0x40);
88 if (landisk_arch == 1) {
89 /* arch == usl-5p */
90 landisk_ledparam = 0x00000380;
91 landisk_ledparam |= (tmp1 & 0x07c);
92 } else {
93 /* arch == landisk */
94 landisk_ledparam = 0x02000180;
95 landisk_ledparam |= 0x04;
96 }
97}
98
99void *area5_io_base;
100void *area6_io_base;
101
102static int __init landisk_cf_init(void)
103{
104 pgprot_t prot;
105 unsigned long paddrbase, psize;
106
107 /* open I/O area window */
108 paddrbase = virt_to_phys((void *)PA_AREA5_IO);
109 psize = PAGE_SIZE;
110 prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16);
111 area5_io_base = p3_ioremap(paddrbase, psize, prot.pgprot);
112 if (!area5_io_base) {
113 printk("allocate_cf_area : can't open CF I/O window!\n");
114 return -ENOMEM;
115 }
116
117 paddrbase = virt_to_phys((void *)PA_AREA6_IO);
118 psize = PAGE_SIZE;
119 prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO16);
120 area6_io_base = p3_ioremap(paddrbase, psize, prot.pgprot);
121 if (!area6_io_base) {
122 printk("allocate_cf_area : can't open HDD I/O window!\n");
123 return -ENOMEM;
124 }
125
126 printk(KERN_INFO "Allocate Area5/6 success.\n");
127
128 /* XXX : do we need attribute and common-memory area also? */
129
130 return 0;
131}
132
133static void __init landisk_setup(char **cmdline_p)
134{
135 device_initcall(landisk_cf_init);
136
137 landisk_buzzerparam = 0;
138 check_usl5p();
139
140 printk(KERN_INFO "I-O DATA DEVICE, INC. \"LANDISK Series\" support.\n");
141
142 board_time_init = landisk_time_init;
143 pm_power_off = landisk_power_off;
144}
145
146/*
147 * The Machine Vector
148 */
149struct sh_machine_vector mv_landisk __initmv = {
150 .mv_name = "LANDISK",
151 .mv_setup = landisk_setup,
152 .mv_nr_irqs = 72,
153 .mv_inb = landisk_inb,
154 .mv_inw = landisk_inw,
155 .mv_inl = landisk_inl,
156 .mv_outb = landisk_outb,
157 .mv_outw = landisk_outw,
158 .mv_outl = landisk_outl,
159 .mv_inb_p = landisk_inb_p,
160 .mv_inw_p = landisk_inw,
161 .mv_inl_p = landisk_inl,
162 .mv_outb_p = landisk_outb_p,
163 .mv_outw_p = landisk_outw,
164 .mv_outl_p = landisk_outl,
165 .mv_insb = landisk_insb,
166 .mv_insw = landisk_insw,
167 .mv_insl = landisk_insl,
168 .mv_outsb = landisk_outsb,
169 .mv_outsw = landisk_outsw,
170 .mv_outsl = landisk_outsl,
171 .mv_ioport_map = landisk_ioport_map,
172 .mv_init_irq = init_landisk_IRQ,
173#ifdef CONFIG_HEARTBEAT
174 .mv_heartbeat = heartbeat_landisk,
175#endif
176};
177ALIAS_MV(landisk)
diff --git a/arch/sh/boards/mpc1211/rtc.c b/arch/sh/boards/mpc1211/rtc.c
index a76c655dceee..03b123a4bba4 100644
--- a/arch/sh/boards/mpc1211/rtc.c
+++ b/arch/sh/boards/mpc1211/rtc.c
@@ -130,7 +130,7 @@ int mpc1211_rtc_settimeofday(const struct timeval *tv)
130 130
131void mpc1211_time_init(void) 131void mpc1211_time_init(void)
132{ 132{
133 rtc_get_time = mpc1211_rtc_gettimeofday; 133 rtc_sh_get_time = mpc1211_rtc_gettimeofday;
134 rtc_set_time = mpc1211_rtc_settimeofday; 134 rtc_sh_set_time = mpc1211_rtc_settimeofday;
135} 135}
136 136
diff --git a/arch/sh/boards/mpc1211/setup.c b/arch/sh/boards/mpc1211/setup.c
index 2bfb221cc35c..8eb5d4303972 100644
--- a/arch/sh/boards/mpc1211/setup.c
+++ b/arch/sh/boards/mpc1211/setup.c
@@ -10,14 +10,12 @@
10#include <linux/hdreg.h> 10#include <linux/hdreg.h>
11#include <linux/ide.h> 11#include <linux/ide.h>
12#include <linux/interrupt.h> 12#include <linux/interrupt.h>
13
14#include <asm/io.h> 13#include <asm/io.h>
15#include <asm/machvec.h> 14#include <asm/machvec.h>
16#include <asm/mpc1211/mpc1211.h> 15#include <asm/mpc1211/mpc1211.h>
17#include <asm/mpc1211/pci.h> 16#include <asm/mpc1211/pci.h>
18#include <asm/mpc1211/m1543c.h> 17#include <asm/mpc1211/m1543c.h>
19 18
20
21/* ALI15X3 SMBus address offsets */ 19/* ALI15X3 SMBus address offsets */
22#define SMBHSTSTS (0 + 0x3100) 20#define SMBHSTSTS (0 + 0x3100)
23#define SMBHSTCNT (1 + 0x3100) 21#define SMBHSTCNT (1 + 0x3100)
@@ -50,11 +48,6 @@
50#define ALI15X3_STS_TERM 0x80 /* terminated by abort */ 48#define ALI15X3_STS_TERM 0x80 /* terminated by abort */
51#define ALI15X3_STS_ERR 0xE0 /* all the bad error bits */ 49#define ALI15X3_STS_ERR 0xE0 /* all the bad error bits */
52 50
53const char *get_system_type(void)
54{
55 return "Interface MPC-1211(CTP/PCI/MPC-SH02)";
56}
57
58static void __init pci_write_config(unsigned long busNo, 51static void __init pci_write_config(unsigned long busNo,
59 unsigned long devNo, 52 unsigned long devNo,
60 unsigned long fncNo, 53 unsigned long fncNo,
@@ -80,9 +73,6 @@ volatile unsigned long irq_err_count;
80 73
81static void disable_mpc1211_irq(unsigned int irq) 74static void disable_mpc1211_irq(unsigned int irq)
82{ 75{
83 unsigned long flags;
84
85 save_and_cli(flags);
86 if( irq < 8) { 76 if( irq < 8) {
87 m_irq_mask |= (1 << irq); 77 m_irq_mask |= (1 << irq);
88 outb(m_irq_mask,I8259_M_MR); 78 outb(m_irq_mask,I8259_M_MR);
@@ -90,16 +80,11 @@ static void disable_mpc1211_irq(unsigned int irq)
90 s_irq_mask |= (1 << (irq - 8)); 80 s_irq_mask |= (1 << (irq - 8));
91 outb(s_irq_mask,I8259_S_MR); 81 outb(s_irq_mask,I8259_S_MR);
92 } 82 }
93 restore_flags(flags);
94 83
95} 84}
96 85
97static void enable_mpc1211_irq(unsigned int irq) 86static void enable_mpc1211_irq(unsigned int irq)
98{ 87{
99 unsigned long flags;
100
101 save_and_cli(flags);
102
103 if( irq < 8) { 88 if( irq < 8) {
104 m_irq_mask &= ~(1 << irq); 89 m_irq_mask &= ~(1 << irq);
105 outb(m_irq_mask,I8259_M_MR); 90 outb(m_irq_mask,I8259_M_MR);
@@ -107,7 +92,6 @@ static void enable_mpc1211_irq(unsigned int irq)
107 s_irq_mask &= ~(1 << (irq - 8)); 92 s_irq_mask &= ~(1 << (irq - 8));
108 outb(s_irq_mask,I8259_S_MR); 93 outb(s_irq_mask,I8259_S_MR);
109 } 94 }
110 restore_flags(flags);
111} 95}
112 96
113static inline int mpc1211_irq_real(unsigned int irq) 97static inline int mpc1211_irq_real(unsigned int irq)
@@ -131,10 +115,6 @@ static inline int mpc1211_irq_real(unsigned int irq)
131 115
132static void mask_and_ack_mpc1211(unsigned int irq) 116static void mask_and_ack_mpc1211(unsigned int irq)
133{ 117{
134 unsigned long flags;
135
136 save_and_cli(flags);
137
138 if(irq < 8) { 118 if(irq < 8) {
139 if(m_irq_mask & (1<<irq)){ 119 if(m_irq_mask & (1<<irq)){
140 if(!mpc1211_irq_real(irq)){ 120 if(!mpc1211_irq_real(irq)){
@@ -162,7 +142,6 @@ static void mask_and_ack_mpc1211(unsigned int irq)
162 outb(0x60+(irq-8),I8259_S_CR); /* EOI */ 142 outb(0x60+(irq-8),I8259_S_CR); /* EOI */
163 outb(0x60+2,I8259_M_CR); 143 outb(0x60+2,I8259_M_CR);
164 } 144 }
165 restore_flags(flags);
166} 145}
167 146
168static void end_mpc1211_irq(unsigned int irq) 147static void end_mpc1211_irq(unsigned int irq)
@@ -219,7 +198,7 @@ int mpc1211_irq_demux(int irq)
219 return irq; 198 return irq;
220} 199}
221 200
222void __init init_mpc1211_IRQ(void) 201static void __init init_mpc1211_IRQ(void)
223{ 202{
224 int i; 203 int i;
225 /* 204 /*
@@ -255,23 +234,12 @@ void __init init_mpc1211_IRQ(void)
255 } 234 }
256} 235}
257 236
258/* 237static void delay1000(void)
259 Initialize the board
260*/
261
262
263static void delay (void)
264{
265 volatile unsigned short tmp;
266 tmp = *(volatile unsigned short *) 0xa0000000;
267}
268
269static void delay1000 (void)
270{ 238{
271 int i; 239 int i;
272 240
273 for (i=0; i<1000; i++) 241 for (i=0; i<1000; i++)
274 delay (); 242 ctrl_delay();
275} 243}
276 244
277static int put_smb_blk(unsigned char *p, int address, int command, int no) 245static int put_smb_blk(unsigned char *p, int address, int command, int no)
@@ -314,26 +282,10 @@ static int put_smb_blk(unsigned char *p, int address, int command, int no)
314 return 0; 282 return 0;
315} 283}
316 284
317/*
318 * The Machine Vector
319 */
320
321struct sh_machine_vector mv_mpc1211 __initmv = {
322 .mv_nr_irqs = 48,
323 .mv_irq_demux = mpc1211_irq_demux,
324 .mv_init_irq = init_mpc1211_IRQ,
325
326#ifdef CONFIG_HEARTBEAT
327 .mv_heartbeat = heartbeat_mpc1211,
328#endif
329};
330
331ALIAS_MV(mpc1211)
332
333/* arch/sh/boards/mpc1211/rtc.c */ 285/* arch/sh/boards/mpc1211/rtc.c */
334void mpc1211_time_init(void); 286void mpc1211_time_init(void);
335 287
336int __init platform_setup(void) 288static void __init mpc1211_setup(char **cmdline_p)
337{ 289{
338 unsigned char spd_buf[128]; 290 unsigned char spd_buf[128];
339 291
@@ -357,3 +309,18 @@ int __init platform_setup(void)
357 return 0; 309 return 0;
358} 310}
359 311
312/*
313 * The Machine Vector
314 */
315struct sh_machine_vector mv_mpc1211 __initmv = {
316 .mv_name = "Interface MPC-1211(CTP/PCI/MPC-SH02)",
317 .mv_setup = mpc1211_setup,
318 .mv_nr_irqs = 48,
319 .mv_irq_demux = mpc1211_irq_demux,
320 .mv_init_irq = init_mpc1211_IRQ,
321
322#ifdef CONFIG_HEARTBEAT
323 .mv_heartbeat = heartbeat_mpc1211,
324#endif
325};
326ALIAS_MV(mpc1211)
diff --git a/arch/sh/boards/overdrive/Makefile b/arch/sh/boards/overdrive/Makefile
deleted file mode 100644
index 245f03baf762..000000000000
--- a/arch/sh/boards/overdrive/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
1#
2# Makefile for the STMicroelectronics Overdrive specific parts of the kernel
3#
4
5obj-y := mach.o setup.o io.o irq.o led.o
6
7obj-$(CONFIG_PCI) += fpga.o galileo.o pcidma.o
8
diff --git a/arch/sh/boards/overdrive/fpga.c b/arch/sh/boards/overdrive/fpga.c
deleted file mode 100644
index 956c23901228..000000000000
--- a/arch/sh/boards/overdrive/fpga.c
+++ /dev/null
@@ -1,133 +0,0 @@
1/*
2 * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * This file handles programming up the Altera Flex10K that interfaces to
8 * the Galileo, and does the PS/2 keyboard and mouse
9 *
10 */
11
12
13#include <linux/kernel.h>
14#include <linux/smp.h>
15#include <linux/smp_lock.h>
16#include <linux/init.h>
17#include <linux/errno.h>
18#include <linux/pci.h>
19#include <linux/delay.h>
20
21
22#include <asm/overdriver/gt64111.h>
23#include <asm/overdrive/overdrive.h>
24#include <asm/overdrive/fpga.h>
25
26#define FPGA_NotConfigHigh() (*FPGA_ControlReg) = (*FPGA_ControlReg) | ENABLE_FPGA_BIT
27#define FPGA_NotConfigLow() (*FPGA_ControlReg) = (*FPGA_ControlReg) & RESET_FPGA_MASK
28
29/* I need to find out what (if any) the real delay factor here is */
30/* The delay is definately not critical */
31#define long_delay() {int i;for(i=0;i<10000;i++);}
32#define short_delay() {int i;for(i=0;i<100;i++);}
33
34static void __init program_overdrive_fpga(const unsigned char *fpgacode,
35 int size)
36{
37 int timeout = 0;
38 int i, j;
39 unsigned char b;
40 static volatile unsigned char *FPGA_ControlReg =
41 (volatile unsigned char *) (OVERDRIVE_CTRL);
42 static volatile unsigned char *FPGA_ProgramReg =
43 (volatile unsigned char *) (FPGA_DCLK_ADDRESS);
44
45 printk("FPGA: Commencing FPGA Programming\n");
46
47 /* The PCI reset but MUST be low when programming the FPGA !!! */
48 b = (*FPGA_ControlReg) & RESET_PCI_MASK;
49
50 (*FPGA_ControlReg) = b;
51
52 /* Prepare FPGA to program */
53
54 FPGA_NotConfigHigh();
55 long_delay();
56
57 FPGA_NotConfigLow();
58 short_delay();
59
60 while ((*FPGA_ProgramReg & FPGA_NOT_STATUS) != 0) {
61 printk("FPGA: Waiting for NotStatus to go Low ... \n");
62 }
63
64 FPGA_NotConfigHigh();
65
66 /* Wait for FPGA "ready to be programmed" signal */
67 printk("FPGA: Waiting for NotStatus to go high (FPGA ready)... \n");
68
69 for (timeout = 0;
70 (((*FPGA_ProgramReg & FPGA_NOT_STATUS) == 0)
71 && (timeout < FPGA_TIMEOUT)); timeout++);
72
73 /* Check if timeout condition occured - i.e. an error */
74
75 if (timeout == FPGA_TIMEOUT) {
76 printk
77 ("FPGA: Failed to program - Timeout waiting for notSTATUS to go high\n");
78 return;
79 }
80
81 printk("FPGA: Copying data to FPGA ... %d bytes\n", size);
82
83 /* Copy array to FPGA - bit at a time */
84
85 for (i = 0; i < size; i++) {
86 volatile unsigned w = 0;
87
88 for (j = 0; j < 8; j++) {
89 *FPGA_ProgramReg = (fpgacode[i] >> j) & 0x01;
90 short_delay();
91 }
92 if ((i & 0x3ff) == 0) {
93 printk(".");
94 }
95 }
96
97 /* Waiting for CONFDONE to go high - means the program is complete */
98
99 for (timeout = 0;
100 (((*FPGA_ProgramReg & FPGA_CONFDONE) == 0)
101 && (timeout < FPGA_TIMEOUT)); timeout++) {
102
103 *FPGA_ProgramReg = 0x0;
104 long_delay();
105 }
106
107 if (timeout == FPGA_TIMEOUT) {
108 printk
109 ("FPGA: Failed to program - Timeout waiting for CONFDONE to go high\n");
110 return;
111 } else { /* Clock another 10 times - gets the device into a working state */
112 for (i = 0; i < 10; i++) {
113 *FPGA_ProgramReg = 0x0;
114 short_delay();
115 }
116 }
117
118 printk("FPGA: Programming complete\n");
119}
120
121
122static const unsigned char __init fpgacode[] = {
123#include "./overdrive.ttf" /* Code from maxplus2 compiler */
124 , 0, 0
125};
126
127
128int __init init_overdrive_fpga(void)
129{
130 program_overdrive_fpga(fpgacode, sizeof(fpgacode));
131
132 return 0;
133}
diff --git a/arch/sh/boards/overdrive/galileo.c b/arch/sh/boards/overdrive/galileo.c
deleted file mode 100644
index 29e48971bba0..000000000000
--- a/arch/sh/boards/overdrive/galileo.c
+++ /dev/null
@@ -1,587 +0,0 @@
1/*
2 * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * This file contains the PCI routines required for the Galileo GT6411
8 * PCI bridge as used on the Orion and Overdrive boards.
9 *
10 */
11
12#include <linux/kernel.h>
13#include <linux/smp.h>
14#include <linux/smp_lock.h>
15#include <linux/init.h>
16#include <linux/errno.h>
17#include <linux/pci.h>
18#include <linux/delay.h>
19#include <linux/types.h>
20#include <linux/ioport.h>
21
22#include <asm/overdrive/overdrive.h>
23#include <asm/overdrive/gt64111.h>
24
25
26/* After boot, we shift the Galileo registers so that they appear
27 * in BANK6, along with IO space. This means we can have one contingous
28 * lump of PCI address space without these registers appearing in the
29 * middle of them
30 */
31
32#define GT64111_BASE_ADDRESS 0xbb000000
33#define GT64111_IO_BASE_ADDRESS 0x1000
34/* The GT64111 registers appear at this address to the SH4 after reset */
35#define RESET_GT64111_BASE_ADDRESS 0xb4000000
36
37/* Macros used to access the Galileo registers */
38#define RESET_GT64111_REG(x) (RESET_GT64111_BASE_ADDRESS+x)
39#define GT64111_REG(x) (GT64111_BASE_ADDRESS+x)
40
41#define RESET_GT_WRITE(x,v) writel((v),RESET_GT64111_REG(x))
42
43#define RESET_GT_READ(x) readl(RESET_GT64111_REG(x))
44
45#define GT_WRITE(x,v) writel((v),GT64111_REG(x))
46#define GT_WRITE_BYTE(x,v) writeb((v),GT64111_REG(x))
47#define GT_WRITE_SHORT(x,v) writew((v),GT64111_REG(x))
48
49#define GT_READ(x) readl(GT64111_REG(x))
50#define GT_READ_BYTE(x) readb(GT64111_REG(x))
51#define GT_READ_SHORT(x) readw(GT64111_REG(x))
52
53
54/* Where the various SH banks start at */
55#define SH_BANK4_ADR 0xb0000000
56#define SH_BANK5_ADR 0xb4000000
57#define SH_BANK6_ADR 0xb8000000
58
59/* Masks out everything but lines 28,27,26 */
60#define BANK_SELECT_MASK 0x1c000000
61
62#define SH4_TO_BANK(x) ( (x) & BANK_SELECT_MASK)
63
64/*
65 * Masks used for address conversaion. Bank 6 is used for IO and
66 * has all the address bits zeroed by the FPGA. Special case this
67 */
68#define MEMORY_BANK_MASK 0x1fffffff
69#define IO_BANK_MASK 0x03ffffff
70
71/* Mark bank 6 as the bank used for IO. You can change this in the FPGA code
72 * if you want
73 */
74#define IO_BANK_ADR PCI_GTIO_BASE
75
76/* Will select the correct mask to apply depending on the SH$ address */
77#define SELECT_BANK_MASK(x) \
78 ( (SH4_TO_BANK(x)==SH4_TO_BANK(IO_BANK_ADR)) ? IO_BANK_MASK : MEMORY_BANK_MASK)
79
80/* Converts between PCI space and P2 region */
81#define SH4_TO_PCI(x) ((x)&SELECT_BANK_MASK(x))
82
83/* Various macros for figuring out what to stick in the Galileo registers.
84 * You *really* don't want to figure this stuff out by hand, you always get
85 * it wrong
86 */
87#define GT_MEM_LO_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>21)&0x7ff)
88#define GT_MEM_HI_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>21)&0x7f)
89#define GT_MEM_SUB_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>20)&0xff)
90
91#define PROGRAM_HI_LO(block,a,s) \
92 GT_WRITE(block##_LO_DEC_ADR,GT_MEM_LO_ADR(a));\
93 GT_WRITE(block##_HI_DEC_ADR,GT_MEM_HI_ADR(a+s-1))
94
95#define PROGRAM_SUB_HI_LO(block,a,s) \
96 GT_WRITE(block##_LO_DEC_ADR,GT_MEM_SUB_ADR(a));\
97 GT_WRITE(block##_HI_DEC_ADR,GT_MEM_SUB_ADR(a+s-1))
98
99/* We need to set the size, and the offset register */
100
101#define GT_BAR_MASK(x) ((x)&~0xfff)
102
103/* Macro to set up the BAR in the Galileo. Essentially used for the DRAM */
104#define PROGRAM_GT_BAR(block,a,s) \
105 GT_WRITE(PCI_##block##_BANK_SIZE,GT_BAR_MASK((s-1)));\
106 write_config_to_galileo(PCI_CONFIG_##block##_BASE_ADR,\
107 GT_BAR_MASK(a))
108
109#define DISABLE_GT_BAR(block) \
110 GT_WRITE(PCI_##block##_BANK_SIZE,0),\
111 GT_CONFIG_WRITE(PCI_CONFIG_##block##_BASE_ADR,\
112 0x80000000)
113
114/* Macros to disable things we are not going to use */
115#define DISABLE_DECODE(x) GT_WRITE(x##_LO_DEC_ADR,0x7ff);\
116 GT_WRITE(x##_HI_DEC_ADR,0x00)
117
118#define DISABLE_SUB_DECODE(x) GT_WRITE(x##_LO_DEC_ADR,0xff);\
119 GT_WRITE(x##_HI_DEC_ADR,0x00)
120
121static void __init reset_pci(void)
122{
123 /* Set RESET_PCI bit high */
124 writeb(readb(OVERDRIVE_CTRL) | ENABLE_PCI_BIT, OVERDRIVE_CTRL);
125 udelay(250);
126
127 /* Set RESET_PCI bit low */
128 writeb(readb(OVERDRIVE_CTRL) & RESET_PCI_MASK, OVERDRIVE_CTRL);
129 udelay(250);
130
131 writeb(readb(OVERDRIVE_CTRL) | ENABLE_PCI_BIT, OVERDRIVE_CTRL);
132 udelay(250);
133}
134
135static int write_config_to_galileo(int where, u32 val);
136#define GT_CONFIG_WRITE(where,val) write_config_to_galileo(where,val)
137
138#define ENABLE_PCI_DRAM
139
140
141#ifdef TEST_DRAM
142/* Test function to check out if the PCI DRAM is working OK */
143static int /* __init */ test_dram(unsigned *base, unsigned size)
144{
145 unsigned *p = base;
146 unsigned *end = (unsigned *) (((unsigned) base) + size);
147 unsigned w;
148
149 for (p = base; p < end; p++) {
150 *p = 0xffffffff;
151 if (*p != 0xffffffff) {
152 printk("AAARGH -write failed!!! at %p is %x\n", p,
153 *p);
154 return 0;
155 }
156 *p = 0x0;
157 if (*p != 0x0) {
158 printk("AAARGH -write failed!!!\n");
159 return 0;
160 }
161 }
162
163 for (p = base; p < end; p++) {
164 *p = (unsigned) p;
165 if (*p != (unsigned) p) {
166 printk("Failed at 0x%p, actually is 0x%x\n", p,
167 *p);
168 return 0;
169 }
170 }
171
172 for (p = base; p < end; p++) {
173 w = ((unsigned) p & 0xffff0000);
174 *p = w | (w >> 16);
175 }
176
177 for (p = base; p < end; p++) {
178 w = ((unsigned) p & 0xffff0000);
179 w |= (w >> 16);
180 if (*p != w) {
181 printk
182 ("Failed at 0x%p, should be 0x%x actually is 0x%x\n",
183 p, w, *p);
184 return 0;
185 }
186 }
187
188 return 1;
189}
190#endif
191
192
193/* Function to set up and initialise the galileo. This sets up the BARS,
194 * maps the DRAM into the address space etc,etc
195 */
196int __init galileo_init(void)
197{
198 reset_pci();
199
200 /* Now shift the galileo regs into this block */
201 RESET_GT_WRITE(INTERNAL_SPACE_DEC,
202 GT_MEM_LO_ADR(GT64111_BASE_ADDRESS));
203
204 /* Should have a sanity check here, that you can read back at the new
205 * address what you just wrote
206 */
207
208 /* Disable decode for all regions */
209 DISABLE_DECODE(RAS10);
210 DISABLE_DECODE(RAS32);
211 DISABLE_DECODE(CS20);
212 DISABLE_DECODE(CS3);
213 DISABLE_DECODE(PCI_IO);
214 DISABLE_DECODE(PCI_MEM0);
215 DISABLE_DECODE(PCI_MEM1);
216
217 /* Disable all BARS */
218 GT_WRITE(BAR_ENABLE_ADR, 0x1ff);
219 DISABLE_GT_BAR(RAS10);
220 DISABLE_GT_BAR(RAS32);
221 DISABLE_GT_BAR(CS20);
222 DISABLE_GT_BAR(CS3);
223
224 /* Tell the BAR where the IO registers now are */
225 GT_CONFIG_WRITE(PCI_CONFIG_INT_REG_IO_ADR,GT_BAR_MASK(
226 (GT64111_IO_BASE_ADDRESS &
227 IO_BANK_MASK)));
228 /* set up a 112 Mb decode */
229 PROGRAM_HI_LO(PCI_MEM0, SH_BANK4_ADR, 112 * 1024 * 1024);
230
231 /* Set up a 32 MB io space decode */
232 PROGRAM_HI_LO(PCI_IO, IO_BANK_ADR, 32 * 1024 * 1024);
233
234#ifdef ENABLE_PCI_DRAM
235 /* Program up the DRAM configuration - there is DRAM only in bank 0 */
236 /* Now set up the DRAM decode */
237 PROGRAM_HI_LO(RAS10, PCI_DRAM_BASE, PCI_DRAM_SIZE);
238 /* And the sub decode */
239 PROGRAM_SUB_HI_LO(RAS0, PCI_DRAM_BASE, PCI_DRAM_SIZE);
240
241 DISABLE_SUB_DECODE(RAS1);
242
243 /* Set refresh rate */
244 GT_WRITE(DRAM_BANK0_PARMS, 0x3f);
245 GT_WRITE(DRAM_CFG, 0x100);
246
247 /* we have to lob off the top bits rememeber!! */
248 PROGRAM_GT_BAR(RAS10, SH4_TO_PCI(PCI_DRAM_BASE), PCI_DRAM_SIZE);
249
250#endif
251
252 /* We are only interested in decoding RAS10 and the Galileo's internal
253 * registers (as IO) on the PCI bus
254 */
255#ifdef ENABLE_PCI_DRAM
256 GT_WRITE(BAR_ENABLE_ADR, (~((1 << 8) | (1 << 3))) & 0x1ff);
257#else
258 GT_WRITE(BAR_ENABLE_ADR, (~(1 << 3)) & 0x1ff);
259#endif
260
261 /* Change the class code to host bridge, it actually powers up
262 * as a memory controller
263 */
264 GT_CONFIG_WRITE(8, 0x06000011);
265
266 /* Allow the galileo to master the PCI bus */
267 GT_CONFIG_WRITE(PCI_COMMAND,
268 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
269 PCI_COMMAND_IO);
270
271
272#if 0
273 printk("Testing PCI DRAM - ");
274 if(test_dram(PCI_DRAM_BASE,PCI_DRAM_SIZE)) {
275 printk("Passed\n");
276 }else {
277 printk("FAILED\n");
278 }
279#endif
280 return 0;
281
282}
283
284
285#define SET_CONFIG_BITS(bus,devfn,where)\
286 ((1<<31) | ((bus) << 16) | ((devfn) << 8) | ((where) & ~3))
287
288#define CONFIG_CMD(dev, where) SET_CONFIG_BITS((dev)->bus->number,(dev)->devfn,where)
289
290/* This write to the galileo config registers, unlike the functions below, can
291 * be used before the PCI subsystem has started up
292 */
293static int __init write_config_to_galileo(int where, u32 val)
294{
295 GT_WRITE(PCI_CFG_ADR, SET_CONFIG_BITS(0, 0, where));
296
297 GT_WRITE(PCI_CFG_DATA, val);
298 return 0;
299}
300
301/* We exclude the galileo and slot 31, the galileo because I don't know how to stop
302 * the setup code shagging up the setup I have done on it, and 31 because the whole
303 * thing locks up if you try to access that slot (which doesn't exist of course anyway
304 */
305
306#define EXCLUDED_DEV(dev) ((dev->bus->number==0) && ((PCI_SLOT(dev->devfn)==0) || (PCI_SLOT(dev->devfn) == 31)))
307
308static int galileo_read_config_byte(struct pci_dev *dev, int where,
309 u8 * val)
310{
311
312
313 /* I suspect this doesn't work because this drives a special cycle ? */
314 if (EXCLUDED_DEV(dev)) {
315 *val = 0xff;
316 return PCIBIOS_SUCCESSFUL;
317 }
318 /* Start the config cycle */
319 GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
320 /* Read back the result */
321 *val = GT_READ_BYTE(PCI_CFG_DATA + (where & 3));
322
323 return PCIBIOS_SUCCESSFUL;
324}
325
326
327static int galileo_read_config_word(struct pci_dev *dev, int where,
328 u16 * val)
329{
330
331 if (EXCLUDED_DEV(dev)) {
332 *val = 0xffff;
333 return PCIBIOS_SUCCESSFUL;
334 }
335
336 GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
337 *val = GT_READ_SHORT(PCI_CFG_DATA + (where & 2));
338
339 return PCIBIOS_SUCCESSFUL;
340}
341
342
343static int galileo_read_config_dword(struct pci_dev *dev, int where,
344 u32 * val)
345{
346 if (EXCLUDED_DEV(dev)) {
347 *val = 0xffffffff;
348 return PCIBIOS_SUCCESSFUL;
349 }
350
351 GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
352 *val = GT_READ(PCI_CFG_DATA);
353
354 return PCIBIOS_SUCCESSFUL;
355}
356
357static int galileo_write_config_byte(struct pci_dev *dev, int where,
358 u8 val)
359{
360 GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
361
362 GT_WRITE_BYTE(PCI_CFG_DATA + (where & 3), val);
363
364 return PCIBIOS_SUCCESSFUL;
365}
366
367
368static int galileo_write_config_word(struct pci_dev *dev, int where,
369 u16 val)
370{
371 GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
372
373 GT_WRITE_SHORT(PCI_CFG_DATA + (where & 2), val);
374
375 return PCIBIOS_SUCCESSFUL;
376}
377
378static int galileo_write_config_dword(struct pci_dev *dev, int where,
379 u32 val)
380{
381 GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where));
382
383 GT_WRITE(PCI_CFG_DATA, val);
384
385 return PCIBIOS_SUCCESSFUL;
386}
387
388static struct pci_ops pci_config_ops = {
389 galileo_read_config_byte,
390 galileo_read_config_word,
391 galileo_read_config_dword,
392 galileo_write_config_byte,
393 galileo_write_config_word,
394 galileo_write_config_dword
395};
396
397
398/* Everything hangs off this */
399static struct pci_bus *pci_root_bus;
400
401
402static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
403{
404 return PCI_SLOT(dev->devfn);
405}
406
407static int __init map_od_irq(struct pci_dev *dev, u8 slot, u8 pin)
408{
409 /* Slot 1: Galileo
410 * Slot 2: PCI Slot 1
411 * Slot 3: PCI Slot 2
412 * Slot 4: ESS
413 */
414 switch (slot) {
415 case 2:
416 return OVERDRIVE_PCI_IRQ1;
417 case 3:
418 /* Note this assumes you have a hacked card in slot 2 */
419 return OVERDRIVE_PCI_IRQ2;
420 case 4:
421 return OVERDRIVE_ESS_IRQ;
422 default:
423 /* printk("PCI: Unexpected IRQ mapping request for slot %d\n", slot); */
424 return -1;
425 }
426}
427
428
429
430void __init
431pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
432{
433 ranges->io_start -= bus->resource[0]->start;
434 ranges->io_end -= bus->resource[0]->start;
435 ranges->mem_start -= bus->resource[1]->start;
436 ranges->mem_end -= bus->resource[1]->start;
437}
438
439static void __init pci_fixup_ide_bases(struct pci_dev *d)
440{
441 int i;
442
443 /*
444 * PCI IDE controllers use non-standard I/O port decoding, respect it.
445 */
446 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
447 return;
448 printk("PCI: IDE base address fixup for %s\n", pci_name(d));
449 for(i=0; i<4; i++) {
450 struct resource *r = &d->resource[i];
451 if ((r->start & ~0x80) == 0x374) {
452 r->start |= 2;
453 r->end = r->start;
454 }
455 }
456}
457DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
458
459void __init pcibios_init(void)
460{
461 static struct resource galio,galmem;
462
463 /* Allocate the registers used by the Galileo */
464 galio.flags = IORESOURCE_IO;
465 galio.name = "Galileo GT64011";
466 galmem.flags = IORESOURCE_MEM|IORESOURCE_PREFETCH;
467 galmem.name = "Galileo GT64011 DRAM";
468
469 allocate_resource(&ioport_resource, &galio, 256,
470 GT64111_IO_BASE_ADDRESS,GT64111_IO_BASE_ADDRESS+256, 256, NULL, NULL);
471 allocate_resource(&iomem_resource, &galmem,PCI_DRAM_SIZE,
472 PHYSADDR(PCI_DRAM_BASE), PHYSADDR(PCI_DRAM_BASE)+PCI_DRAM_SIZE,
473 PCI_DRAM_SIZE, NULL, NULL);
474
475 /* ok, do the scan man */
476 pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL);
477
478 pci_assign_unassigned_resources();
479 pci_fixup_irqs(no_swizzle, map_od_irq);
480
481#ifdef TEST_DRAM
482 printk("Testing PCI DRAM - ");
483 if(test_dram(PCI_DRAM_BASE,PCI_DRAM_SIZE)) {
484 printk("Passed\n");
485 }else {
486 printk("FAILED\n");
487 }
488#endif
489
490}
491
492char * __init pcibios_setup(char *str)
493{
494 return str;
495}
496
497
498
499int pcibios_enable_device(struct pci_dev *dev)
500{
501
502 u16 cmd, old_cmd;
503 int idx;
504 struct resource *r;
505
506 pci_read_config_word(dev, PCI_COMMAND, &cmd);
507 old_cmd = cmd;
508 for (idx = 0; idx < 6; idx++) {
509 r = dev->resource + idx;
510 if (!r->start && r->end) {
511 printk(KERN_ERR
512 "PCI: Device %s not available because"
513 " of resource collisions\n",
514 pci_name(dev));
515 return -EINVAL;
516 }
517 if (r->flags & IORESOURCE_IO)
518 cmd |= PCI_COMMAND_IO;
519 if (r->flags & IORESOURCE_MEM)
520 cmd |= PCI_COMMAND_MEMORY;
521 }
522 if (cmd != old_cmd) {
523 printk("PCI: enabling device %s (%04x -> %04x)\n",
524 pci_name(dev), old_cmd, cmd);
525 pci_write_config_word(dev, PCI_COMMAND, cmd);
526 }
527 return 0;
528
529}
530
531/* We should do some optimisation work here I think. Ok for now though */
532void __init pcibios_fixup_bus(struct pci_bus *bus)
533{
534
535}
536
537void pcibios_align_resource(void *data, struct resource *res,
538 resource_size_t size)
539{
540}
541
542void __init pcibios_update_resource(struct pci_dev *dev, struct resource *root,
543 struct resource *res, int resource)
544{
545
546 unsigned long where, size;
547 u32 reg;
548
549
550 printk("PCI: Assigning %3s %08lx to %s\n",
551 res->flags & IORESOURCE_IO ? "IO" : "MEM",
552 res->start, dev->name);
553
554 where = PCI_BASE_ADDRESS_0 + resource * 4;
555 size = res->end - res->start;
556
557 pci_read_config_dword(dev, where, &reg);
558 reg = (reg & size) | (((u32) (res->start - root->start)) & ~size);
559 pci_write_config_dword(dev, where, reg);
560}
561
562
563void __init pcibios_update_irq(struct pci_dev *dev, int irq)
564{
565 printk("PCI: Assigning IRQ %02d to %s\n", irq, dev->name);
566 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
567}
568
569/*
570 * If we set up a device for bus mastering, we need to check the latency
571 * timer as certain crappy BIOSes forget to set it properly.
572 */
573unsigned int pcibios_max_latency = 255;
574
575void pcibios_set_master(struct pci_dev *dev)
576{
577 u8 lat;
578 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
579 if (lat < 16)
580 lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
581 else if (lat > pcibios_max_latency)
582 lat = pcibios_max_latency;
583 else
584 return;
585 printk("PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat);
586 pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
587}
diff --git a/arch/sh/boards/overdrive/io.c b/arch/sh/boards/overdrive/io.c
deleted file mode 100644
index 4671b6b047bb..000000000000
--- a/arch/sh/boards/overdrive/io.c
+++ /dev/null
@@ -1,172 +0,0 @@
1/*
2 * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * This file contains the I/O routines for use on the overdrive board
8 *
9 */
10
11#include <linux/types.h>
12#include <linux/delay.h>
13#include <asm/processor.h>
14#include <asm/io.h>
15#include <asm/addrspace.h>
16
17#include <asm/overdrive/overdrive.h>
18
19/*
20 * readX/writeX() are used to access memory mapped devices. On some
21 * architectures the memory mapped IO stuff needs to be accessed
22 * differently. On the SuperH architecture, we just read/write the
23 * memory location directly.
24 */
25
26#define dprintk(x...)
27
28/* Translates an IO address to where it is mapped in memory */
29
30#define io_addr(x) (((unsigned)(x))|PCI_GTIO_BASE)
31
32unsigned char od_inb(unsigned long port)
33{
34dprintk("od_inb(%x)\n", port);
35 return readb(io_addr(port)) & 0xff;
36}
37
38
39unsigned short od_inw(unsigned long port)
40{
41dprintk("od_inw(%x)\n", port);
42 return readw(io_addr(port)) & 0xffff;
43}
44
45unsigned int od_inl(unsigned long port)
46{
47dprintk("od_inl(%x)\n", port);
48 return readl(io_addr(port));
49}
50
51void od_outb(unsigned char value, unsigned long port)
52{
53dprintk("od_outb(%x, %x)\n", value, port);
54 writeb(value, io_addr(port));
55}
56
57void od_outw(unsigned short value, unsigned long port)
58{
59dprintk("od_outw(%x, %x)\n", value, port);
60 writew(value, io_addr(port));
61}
62
63void od_outl(unsigned int value, unsigned long port)
64{
65dprintk("od_outl(%x, %x)\n", value, port);
66 writel(value, io_addr(port));
67}
68
69/* This is horrible at the moment - needs more work to do something sensible */
70#define IO_DELAY() udelay(10)
71
72#define OUT_DELAY(x,type) \
73void od_out##x##_p(unsigned type value,unsigned long port){out##x(value,port);IO_DELAY();}
74
75#define IN_DELAY(x,type) \
76unsigned type od_in##x##_p(unsigned long port) {unsigned type tmp=in##x(port);IO_DELAY();return tmp;}
77
78
79OUT_DELAY(b,char)
80OUT_DELAY(w,short)
81OUT_DELAY(l,int)
82
83IN_DELAY(b,char)
84IN_DELAY(w,short)
85IN_DELAY(l,int)
86
87
88/* Now for the string version of these functions */
89void od_outsb(unsigned long port, const void *addr, unsigned long count)
90{
91 int i;
92 unsigned char *p = (unsigned char *) addr;
93
94 for (i = 0; i < count; i++, p++) {
95 outb(*p, port);
96 }
97}
98
99
100void od_insb(unsigned long port, void *addr, unsigned long count)
101{
102 int i;
103 unsigned char *p = (unsigned char *) addr;
104
105 for (i = 0; i < count; i++, p++) {
106 *p = inb(port);
107 }
108}
109
110/* For the 16 and 32 bit string functions, we have to worry about alignment.
111 * The SH does not do unaligned accesses, so we have to read as bytes and
112 * then write as a word or dword.
113 * This can be optimised a lot more, especially in the case where the data
114 * is aligned
115 */
116
117void od_outsw(unsigned long port, const void *addr, unsigned long count)
118{
119 int i;
120 unsigned short tmp;
121 unsigned char *p = (unsigned char *) addr;
122
123 for (i = 0; i < count; i++, p += 2) {
124 tmp = (*p) | ((*(p + 1)) << 8);
125 outw(tmp, port);
126 }
127}
128
129
130void od_insw(unsigned long port, void *addr, unsigned long count)
131{
132 int i;
133 unsigned short tmp;
134 unsigned char *p = (unsigned char *) addr;
135
136 for (i = 0; i < count; i++, p += 2) {
137 tmp = inw(port);
138 p[0] = tmp & 0xff;
139 p[1] = (tmp >> 8) & 0xff;
140 }
141}
142
143
144void od_outsl(unsigned long port, const void *addr, unsigned long count)
145{
146 int i;
147 unsigned tmp;
148 unsigned char *p = (unsigned char *) addr;
149
150 for (i = 0; i < count; i++, p += 4) {
151 tmp = (*p) | ((*(p + 1)) << 8) | ((*(p + 2)) << 16) |
152 ((*(p + 3)) << 24);
153 outl(tmp, port);
154 }
155}
156
157
158void od_insl(unsigned long port, void *addr, unsigned long count)
159{
160 int i;
161 unsigned tmp;
162 unsigned char *p = (unsigned char *) addr;
163
164 for (i = 0; i < count; i++, p += 4) {
165 tmp = inl(port);
166 p[0] = tmp & 0xff;
167 p[1] = (tmp >> 8) & 0xff;
168 p[2] = (tmp >> 16) & 0xff;
169 p[3] = (tmp >> 24) & 0xff;
170
171 }
172}
diff --git a/arch/sh/boards/overdrive/irq.c b/arch/sh/boards/overdrive/irq.c
deleted file mode 100644
index 5d730c70389e..000000000000
--- a/arch/sh/boards/overdrive/irq.c
+++ /dev/null
@@ -1,191 +0,0 @@
1/*
2 * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * Looks after interrupts on the overdrive board.
8 *
9 * Bases on the IPR irq system
10 */
11
12#include <linux/init.h>
13#include <linux/irq.h>
14
15#include <asm/system.h>
16#include <asm/io.h>
17
18#include <asm/overdrive/overdrive.h>
19
20struct od_data {
21 int overdrive_irq;
22 int irq_mask;
23};
24
25#define NUM_EXTERNAL_IRQS 16
26#define EXTERNAL_IRQ_NOT_IN_USE (-1)
27#define EXTERNAL_IRQ_NOT_ASSIGNED (-1)
28
29/*
30 * This table is used to determine what to program into the FPGA's CT register
31 * for the specified Linux IRQ.
32 *
33 * The irq_mask gives the interrupt number from the PCI board (PCI_Int(6:0))
34 * but is one greater than that because the because the FPGA treats 0
35 * as disabled, a value of 1 asserts PCI_Int0, and so on.
36 *
37 * The overdrive_irq specifies which of the eight interrupt sources generates
38 * that interrupt, and but is multiplied by four to give the bit offset into
39 * the CT register.
40 *
41 * The seven interrupts levels (SH4 IRL's) we have available here is hardwired
42 * by the EPLD. The assignments here of which PCI interrupt generates each
43 * level is arbitary.
44 */
45static struct od_data od_data_table[NUM_EXTERNAL_IRQS] = {
46 /* overdrive_irq , irq_mask */
47 {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 0 */
48 {EXTERNAL_IRQ_NOT_ASSIGNED, 7}, /* 1 */
49 {EXTERNAL_IRQ_NOT_ASSIGNED, 6}, /* 2 */
50 {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 3 */
51 {EXTERNAL_IRQ_NOT_ASSIGNED, 5}, /* 4 */
52 {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 5 */
53 {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 6 */
54 {EXTERNAL_IRQ_NOT_ASSIGNED, 4}, /* 7 */
55 {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 8 */
56 {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 9 */
57 {EXTERNAL_IRQ_NOT_ASSIGNED, 3}, /* 10 */
58 {EXTERNAL_IRQ_NOT_ASSIGNED, 2}, /* 11 */
59 {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 12 */
60 {EXTERNAL_IRQ_NOT_ASSIGNED, 1}, /* 13 */
61 {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 14 */
62 {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE} /* 15 */
63};
64
65static void set_od_data(int overdrive_irq, int irq)
66{
67 if (irq >= NUM_EXTERNAL_IRQS || irq < 0)
68 return;
69 od_data_table[irq].overdrive_irq = overdrive_irq << 2;
70}
71
72static void enable_od_irq(unsigned int irq);
73void disable_od_irq(unsigned int irq);
74
75/* shutdown is same as "disable" */
76#define shutdown_od_irq disable_od_irq
77
78static void mask_and_ack_od(unsigned int);
79static void end_od_irq(unsigned int irq);
80
81static unsigned int startup_od_irq(unsigned int irq)
82{
83 enable_od_irq(irq);
84 return 0; /* never anything pending */
85}
86
87static struct hw_interrupt_type od_irq_type = {
88 .typename = "Overdrive-IRQ",
89 .startup = startup_od_irq,
90 .shutdown = shutdown_od_irq,
91 .enable = enable_od_irq,
92 .disable = disable_od_irq,
93 .ack = mask_and_ack_od,
94 .end = end_od_irq
95};
96
97static void disable_od_irq(unsigned int irq)
98{
99 unsigned val, flags;
100 int overdrive_irq;
101 unsigned mask;
102
103 /* Not a valid interrupt */
104 if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
105 return;
106
107 /* Is is necessary to use a cli here? Would a spinlock not be
108 * mroe efficient?
109 */
110 local_irq_save(flags);
111 overdrive_irq = od_data_table[irq].overdrive_irq;
112 if (overdrive_irq != EXTERNAL_IRQ_NOT_ASSIGNED) {
113 mask = ~(0x7 << overdrive_irq);
114 val = ctrl_inl(OVERDRIVE_INT_CT);
115 val &= mask;
116 ctrl_outl(val, OVERDRIVE_INT_CT);
117 }
118 local_irq_restore(flags);
119}
120
121static void enable_od_irq(unsigned int irq)
122{
123 unsigned val, flags;
124 int overdrive_irq;
125 unsigned mask;
126
127 /* Not a valid interrupt */
128 if (irq < 0 || irq >= NUM_EXTERNAL_IRQS)
129 return;
130
131 /* Set priority in OD back to original value */
132 local_irq_save(flags);
133 /* This one is not in use currently */
134 overdrive_irq = od_data_table[irq].overdrive_irq;
135 if (overdrive_irq != EXTERNAL_IRQ_NOT_ASSIGNED) {
136 val = ctrl_inl(OVERDRIVE_INT_CT);
137 mask = ~(0x7 << overdrive_irq);
138 val &= mask;
139 mask = od_data_table[irq].irq_mask << overdrive_irq;
140 val |= mask;
141 ctrl_outl(val, OVERDRIVE_INT_CT);
142 }
143 local_irq_restore(flags);
144}
145
146
147
148/* this functions sets the desired irq handler to be an overdrive type */
149static void __init make_od_irq(unsigned int irq)
150{
151 disable_irq_nosync(irq);
152 irq_desc[irq].chip = &od_irq_type;
153 disable_od_irq(irq);
154}
155
156
157static void mask_and_ack_od(unsigned int irq)
158{
159 disable_od_irq(irq);
160}
161
162static void end_od_irq(unsigned int irq)
163{
164 enable_od_irq(irq);
165}
166
167void __init init_overdrive_irq(void)
168{
169 int i;
170
171 /* Disable all interrupts */
172 ctrl_outl(0, OVERDRIVE_INT_CT);
173
174 /* Update interrupt pin mode to use encoded interrupts */
175 i = ctrl_inw(INTC_ICR);
176 i &= ~INTC_ICR_IRLM;
177 ctrl_outw(i, INTC_ICR);
178
179 for (i = 0; i < NUM_EXTERNAL_IRQS; i++) {
180 if (od_data_table[i].irq_mask != EXTERNAL_IRQ_NOT_IN_USE) {
181 make_od_irq(i);
182 } else if (i != 15) { // Cannot use imask on level 15
183 make_imask_irq(i);
184 }
185 }
186
187 /* Set up the interrupts */
188 set_od_data(OVERDRIVE_PCI_INTA, OVERDRIVE_PCI_IRQ1);
189 set_od_data(OVERDRIVE_PCI_INTB, OVERDRIVE_PCI_IRQ2);
190 set_od_data(OVERDRIVE_AUDIO_INT, OVERDRIVE_ESS_IRQ);
191}
diff --git a/arch/sh/boards/overdrive/led.c b/arch/sh/boards/overdrive/led.c
deleted file mode 100644
index 860d7f204a4e..000000000000
--- a/arch/sh/boards/overdrive/led.c
+++ /dev/null
@@ -1,58 +0,0 @@
1/*
2 * linux/arch/sh/overdrive/led.c
3 *
4 * Copyright (C) 1999 Stuart Menefy <stuart.menefy@st.com>
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * This file contains an Overdrive specific LED feature.
10 */
11
12#include <asm/system.h>
13#include <asm/io.h>
14#include <asm/overdrive/overdrive.h>
15
16static void mach_led(int position, int value)
17{
18 unsigned long flags;
19 unsigned long reg;
20
21 local_irq_save(flags);
22
23 reg = readl(OVERDRIVE_CTRL);
24 if (value) {
25 reg |= (1<<3);
26 } else {
27 reg &= ~(1<<3);
28 }
29 writel(reg, OVERDRIVE_CTRL);
30
31 local_irq_restore(flags);
32}
33
34#ifdef CONFIG_HEARTBEAT
35
36#include <linux/sched.h>
37
38/* acts like an actual heart beat -- ie thump-thump-pause... */
39void heartbeat_od(void)
40{
41 static unsigned cnt = 0, period = 0, dist = 0;
42
43 if (cnt == 0 || cnt == dist)
44 mach_led( -1, 1);
45 else if (cnt == 7 || cnt == dist+7)
46 mach_led( -1, 0);
47
48 if (++cnt > period) {
49 cnt = 0;
50 /* The hyperbolic function below modifies the heartbeat period
51 * length in dependency of the current (5min) load. It goes
52 * through the points f(0)=126, f(1)=86, f(5)=51,
53 * f(inf)->30. */
54 period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
55 dist = period / 4;
56 }
57}
58#endif /* CONFIG_HEARTBEAT */
diff --git a/arch/sh/boards/overdrive/mach.c b/arch/sh/boards/overdrive/mach.c
deleted file mode 100644
index 2834a03ae477..000000000000
--- a/arch/sh/boards/overdrive/mach.c
+++ /dev/null
@@ -1,62 +0,0 @@
1/*
2 * linux/arch/sh/overdrive/mach.c
3 *
4 * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Machine vector for the STMicroelectronics Overdrive
10 */
11
12#include <linux/init.h>
13
14#include <asm/machvec.h>
15#include <asm/rtc.h>
16#include <asm/machvec_init.h>
17
18#include <asm/io_unknown.h>
19#include <asm/io_generic.h>
20#include <asm/overdrive/io.h>
21
22void heartbeat_od(void);
23void init_overdrive_irq(void);
24void galileo_pcibios_init(void);
25
26/*
27 * The Machine Vector
28 */
29
30struct sh_machine_vector mv_od __initmv = {
31 .mv_nr_irqs = 48,
32
33 .mv_inb = od_inb,
34 .mv_inw = od_inw,
35 .mv_inl = od_inl,
36 .mv_outb = od_outb,
37 .mv_outw = od_outw,
38 .mv_outl = od_outl,
39
40 .mv_inb_p = od_inb_p,
41 .mv_inw_p = od_inw_p,
42 .mv_inl_p = od_inl_p,
43 .mv_outb_p = od_outb_p,
44 .mv_outw_p = od_outw_p,
45 .mv_outl_p = od_outl_p,
46
47 .mv_insb = od_insb,
48 .mv_insw = od_insw,
49 .mv_insl = od_insl,
50 .mv_outsb = od_outsb,
51 .mv_outsw = od_outsw,
52 .mv_outsl = od_outsl,
53
54#ifdef CONFIG_PCI
55 .mv_init_irq = init_overdrive_irq,
56#endif
57#ifdef CONFIG_HEARTBEAT
58 .mv_heartbeat = heartbeat_od,
59#endif
60};
61
62ALIAS_MV(od)
diff --git a/arch/sh/boards/overdrive/pcidma.c b/arch/sh/boards/overdrive/pcidma.c
deleted file mode 100644
index 1c9bfeda00b7..000000000000
--- a/arch/sh/boards/overdrive/pcidma.c
+++ /dev/null
@@ -1,46 +0,0 @@
1/*
2 * Copyright (C) 2000 David J. Mckay (david.mckay@st.com)
3 *
4 * May be copied or modified under the terms of the GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * Dynamic DMA mapping support.
8 *
9 * On the overdrive, we can only DMA from memory behind the PCI bus!
10 * this means that all DMA'able memory must come from there.
11 * this restriction will not apply to later boards.
12 */
13
14#include <linux/types.h>
15#include <linux/mm.h>
16#include <linux/string.h>
17#include <linux/pci.h>
18#include <asm/io.h>
19
20void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
21 dma_addr_t * dma_handle)
22{
23 void *ret;
24 int gfp = GFP_ATOMIC;
25
26 printk("BUG: pci_alloc_consistent() called - not yet supported\n");
27 /* We ALWAYS need DMA memory on the overdrive hardware,
28 * due to it's extreme weirdness
29 * Need to flush the cache here as well, since the memory
30 * can still be seen through the cache!
31 */
32 gfp |= GFP_DMA;
33 ret = (void *) __get_free_pages(gfp, get_order(size));
34
35 if (ret != NULL) {
36 memset(ret, 0, size);
37 *dma_handle = virt_to_bus(ret);
38 }
39 return ret;
40}
41
42void pci_free_consistent(struct pci_dev *hwdev, size_t size,
43 void *vaddr, dma_addr_t dma_handle)
44{
45 free_pages((unsigned long) vaddr, get_order(size));
46}
diff --git a/arch/sh/boards/overdrive/setup.c b/arch/sh/boards/overdrive/setup.c
deleted file mode 100644
index a3a7744c2047..000000000000
--- a/arch/sh/boards/overdrive/setup.c
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2 * arch/sh/overdrive/setup.c
3 *
4 * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * STMicroelectronics Overdrive Support.
10 */
11
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <asm/io.h>
15
16#include <asm/overdrive/overdrive.h>
17#include <asm/overdrive/fpga.h>
18
19const char *get_system_type(void)
20{
21 return "SH7750 Overdrive";
22}
23
24/*
25 * Initialize the board
26 */
27int __init platform_setup(void)
28{
29#ifdef CONFIG_PCI
30 init_overdrive_fpga();
31 galileo_init();
32#endif
33
34 /* Enable RS232 receive buffers */
35 writel(0x1e, OVERDRIVE_CTRL);
36}
diff --git a/arch/sh/boards/renesas/edosk7705/Makefile b/arch/sh/boards/renesas/edosk7705/Makefile
index 7fccbf2e4a1d..14bdd531f116 100644
--- a/arch/sh/boards/renesas/edosk7705/Makefile
+++ b/arch/sh/boards/renesas/edosk7705/Makefile
@@ -1,10 +1,6 @@
1# 1#
2# Makefile for the EDOSK7705 specific parts of the kernel 2# Makefile for the EDOSK7705 specific parts of the kernel
3# 3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7#
8 4
9obj-y := setup.o io.o 5obj-y := setup.o io.o
10 6
diff --git a/arch/sh/boards/renesas/edosk7705/setup.c b/arch/sh/boards/renesas/edosk7705/setup.c
index ba143fa4afaa..ec5be0107719 100644
--- a/arch/sh/boards/renesas/edosk7705/setup.c
+++ b/arch/sh/boards/renesas/edosk7705/setup.c
@@ -8,19 +8,21 @@
8 * Modified for edosk7705 development 8 * Modified for edosk7705 development
9 * board by S. Dunn, 2003. 9 * board by S. Dunn, 2003.
10 */ 10 */
11
12#include <linux/init.h> 11#include <linux/init.h>
13#include <asm/machvec.h> 12#include <asm/machvec.h>
14#include <asm/machvec_init.h>
15#include <asm/edosk7705/io.h> 13#include <asm/edosk7705/io.h>
16 14
17static void init_edosk7705(void); 15static void __init sh_edosk7705_init_irq(void)
16{
17 /* This is the Ethernet interrupt */
18 make_imask_irq(0x09);
19}
18 20
19/* 21/*
20 * The Machine Vector 22 * The Machine Vector
21 */ 23 */
22
23struct sh_machine_vector mv_edosk7705 __initmv = { 24struct sh_machine_vector mv_edosk7705 __initmv = {
25 .mv_name = "EDOSK7705",
24 .mv_nr_irqs = 80, 26 .mv_nr_irqs = 80,
25 27
26 .mv_inb = sh_edosk7705_inb, 28 .mv_inb = sh_edosk7705_inb,
@@ -37,23 +39,6 @@ struct sh_machine_vector mv_edosk7705 __initmv = {
37 .mv_outsl = sh_edosk7705_outsl, 39 .mv_outsl = sh_edosk7705_outsl,
38 40
39 .mv_isa_port2addr = sh_edosk7705_isa_port2addr, 41 .mv_isa_port2addr = sh_edosk7705_isa_port2addr,
40 .mv_init_irq = init_edosk7705, 42 .mv_init_irq = sh_edosk7705_init_irq,
41}; 43};
42ALIAS_MV(edosk7705) 44ALIAS_MV(edosk7705)
43
44static void __init init_edosk7705(void)
45{
46 /* This is the Ethernet interrupt */
47 make_imask_irq(0x09);
48}
49
50const char *get_system_type(void)
51{
52 return "EDOSK7705";
53}
54
55void __init platform_setup(void)
56{
57 /* Nothing .. */
58}
59
diff --git a/arch/sh/boards/renesas/hs7751rvoip/Kconfig b/arch/sh/boards/renesas/hs7751rvoip/Kconfig
new file mode 100644
index 000000000000..1743be477be5
--- /dev/null
+++ b/arch/sh/boards/renesas/hs7751rvoip/Kconfig
@@ -0,0 +1,12 @@
1if SH_HS7751RVOIP
2
3menu "HS7751RVoIP options"
4
5config HS7751RVOIP_CODEC
6 bool "Support VoIP Codec section"
7 help
8 Selecting this option will support CODEC section.
9
10endmenu
11
12endif
diff --git a/arch/sh/boards/renesas/hs7751rvoip/Makefile b/arch/sh/boards/renesas/hs7751rvoip/Makefile
index e8b4109ace11..e626377c55ee 100644
--- a/arch/sh/boards/renesas/hs7751rvoip/Makefile
+++ b/arch/sh/boards/renesas/hs7751rvoip/Makefile
@@ -1,12 +1,8 @@
1# 1#
2# Makefile for the HS7751RVoIP specific parts of the kernel 2# Makefile for the HS7751RVoIP specific parts of the kernel
3# 3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7#
8 4
9obj-y := mach.o setup.o io.o irq.o led.o 5obj-y := setup.o io.o irq.o
10 6
11obj-$(CONFIG_PCI) += pci.o 7obj-$(CONFIG_PCI) += pci.o
12 8
diff --git a/arch/sh/boards/renesas/hs7751rvoip/io.c b/arch/sh/boards/renesas/hs7751rvoip/io.c
index 3a1abfa2fefb..9ea1136b219b 100644
--- a/arch/sh/boards/renesas/hs7751rvoip/io.c
+++ b/arch/sh/boards/renesas/hs7751rvoip/io.c
@@ -10,21 +10,16 @@
10 * placeholder code from io_hs7751rvoip.c left in with the 10 * placeholder code from io_hs7751rvoip.c left in with the
11 * expectation of later SuperIO and PCMCIA access. 11 * expectation of later SuperIO and PCMCIA access.
12 */ 12 */
13
14#include <linux/kernel.h> 13#include <linux/kernel.h>
15#include <linux/types.h> 14#include <linux/types.h>
15#include <linux/module.h>
16#include <linux/pci.h>
16#include <asm/io.h> 17#include <asm/io.h>
17#include <asm/hs7751rvoip/hs7751rvoip.h> 18#include <asm/hs7751rvoip/hs7751rvoip.h>
18#include <asm/addrspace.h> 19#include <asm/addrspace.h>
19 20
20#include <linux/module.h>
21#include <linux/pci.h>
22#include "../../../drivers/pci/pci-sh7751.h"
23
24extern void *area5_io8_base; /* Area 5 8bit I/O Base address */
25extern void *area6_io8_base; /* Area 6 8bit I/O Base address */ 21extern void *area6_io8_base; /* Area 6 8bit I/O Base address */
26extern void *area5_io16_base; /* Area 5 16bit I/O Base address */ 22extern void *area5_io16_base; /* Area 5 16bit I/O Base address */
27extern void *area6_io16_base; /* Area 6 16bit I/O Base address */
28 23
29/* 24/*
30 * The 7751R HS7751RVoIP uses the built-in PCI controller (PCIC) 25 * The 7751R HS7751RVoIP uses the built-in PCI controller (PCIC)
@@ -33,25 +28,8 @@ extern void *area6_io16_base; /* Area 6 16bit I/O Base address */
33 * like the other Solution Engine boards. 28 * like the other Solution Engine boards.
34 */ 29 */
35 30
36#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR)
37#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR)
38#define PCI_IO_AREA SH7751_PCI_IO_BASE
39#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE
40
41#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
42
43#if defined(CONFIG_HS7751RVOIP_CODEC)
44#define CODEC_IO_BASE 0x1000 31#define CODEC_IO_BASE 0x1000
45#endif 32#define CODEC_IOMAP(a) ((unsigned long)area6_io8_base + ((a) - CODEC_IO_BASE))
46
47#define maybebadio(name,port) \
48 printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
49 #name, (port), (__u32) __builtin_return_address(0))
50
51static inline void delay(void)
52{
53 ctrl_inw(0xa0000000);
54}
55 33
56static inline unsigned long port2adr(unsigned int port) 34static inline unsigned long port2adr(unsigned int port)
57{ 35{
@@ -59,9 +37,10 @@ static inline unsigned long port2adr(unsigned int port)
59 if (port == 0x3f6) 37 if (port == 0x3f6)
60 return ((unsigned long)area5_io16_base + 0x0c); 38 return ((unsigned long)area5_io16_base + 0x0c);
61 else 39 else
62 return ((unsigned long)area5_io16_base + 0x800 + ((port-0x1f0) << 1)); 40 return ((unsigned long)area5_io16_base + 0x800 +
41 ((port-0x1f0) << 1));
63 else 42 else
64 maybebadio(port2adr, (unsigned long)port); 43 maybebadio((unsigned long)port);
65 return port; 44 return port;
66} 45}
67 46
@@ -78,25 +57,10 @@ static inline int shifted_port(unsigned long port)
78} 57}
79 58
80#if defined(CONFIG_HS7751RVOIP_CODEC) 59#if defined(CONFIG_HS7751RVOIP_CODEC)
81static inline int 60#define codec_port(port) \
82codec_port(unsigned long port) 61 ((CODEC_IO_BASE <= (port)) && ((port) < (CODEC_IO_BASE + 0x20)))
83{
84 if (CODEC_IO_BASE <= port && port < (CODEC_IO_BASE+0x20))
85 return 1;
86 else
87 return 0;
88}
89#endif
90
91/* In case someone configures the kernel w/o PCI support: in that */
92/* scenario, don't ever bother to check for PCI-window addresses */
93
94/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
95#if defined(CONFIG_PCI)
96#define CHECK_SH7751_PCIIO(port) \
97 ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
98#else 62#else
99#define CHECK_SH7751_PCIIO(port) (0) 63#define codec_port(port) (0)
100#endif 64#endif
101 65
102/* 66/*
@@ -109,15 +73,13 @@ codec_port(unsigned long port)
109unsigned char hs7751rvoip_inb(unsigned long port) 73unsigned char hs7751rvoip_inb(unsigned long port)
110{ 74{
111 if (PXSEG(port)) 75 if (PXSEG(port))
112 return *(volatile unsigned char *)port; 76 return ctrl_inb(port);
113#if defined(CONFIG_HS7751RVOIP_CODEC)
114 else if (codec_port(port)) 77 else if (codec_port(port))
115 return *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)); 78 return ctrl_inb(CODEC_IOMAP(port));
116#endif 79 else if (is_pci_ioaddr(port) || shifted_port(port))
117 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) 80 return ctrl_inb(pci_ioaddr(port));
118 return *(volatile unsigned char *)PCI_IOMAP(port);
119 else 81 else
120 return (*(volatile unsigned short *)port2adr(port) & 0xff); 82 return ctrl_inw(port2adr(port)) & 0xff;
121} 83}
122 84
123unsigned char hs7751rvoip_inb_p(unsigned long port) 85unsigned char hs7751rvoip_inb_p(unsigned long port)
@@ -125,38 +87,36 @@ unsigned char hs7751rvoip_inb_p(unsigned long port)
125 unsigned char v; 87 unsigned char v;
126 88
127 if (PXSEG(port)) 89 if (PXSEG(port))
128 v = *(volatile unsigned char *)port; 90 v = ctrl_inb(port);
129#if defined(CONFIG_HS7751RVOIP_CODEC)
130 else if (codec_port(port)) 91 else if (codec_port(port))
131 v = *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)); 92 v = ctrl_inb(CODEC_IOMAP(port));
132#endif 93 else if (is_pci_ioaddr(port) || shifted_port(port))
133 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) 94 v = ctrl_inb(pci_ioaddr(port));
134 v = *(volatile unsigned char *)PCI_IOMAP(port);
135 else 95 else
136 v = (*(volatile unsigned short *)port2adr(port) & 0xff); 96 v = ctrl_inw(port2adr(port)) & 0xff;
137 delay(); 97 ctrl_delay();
138 return v; 98 return v;
139} 99}
140 100
141unsigned short hs7751rvoip_inw(unsigned long port) 101unsigned short hs7751rvoip_inw(unsigned long port)
142{ 102{
143 if (PXSEG(port)) 103 if (PXSEG(port))
144 return *(volatile unsigned short *)port; 104 return ctrl_inw(port);
145 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) 105 else if (is_pci_ioaddr(port) || shifted_port(port))
146 return *(volatile unsigned short *)PCI_IOMAP(port); 106 return ctrl_inw(pci_ioaddr(port));
147 else 107 else
148 maybebadio(inw, port); 108 maybebadio(port);
149 return 0; 109 return 0;
150} 110}
151 111
152unsigned int hs7751rvoip_inl(unsigned long port) 112unsigned int hs7751rvoip_inl(unsigned long port)
153{ 113{
154 if (PXSEG(port)) 114 if (PXSEG(port))
155 return *(volatile unsigned long *)port; 115 return ctrl_inl(port);
156 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) 116 else if (is_pci_ioaddr(port) || shifted_port(port))
157 return *(volatile unsigned long *)PCI_IOMAP(port); 117 return ctrl_inl(pci_ioaddr(port));
158 else 118 else
159 maybebadio(inl, port); 119 maybebadio(port);
160 return 0; 120 return 0;
161} 121}
162 122
@@ -164,146 +124,160 @@ void hs7751rvoip_outb(unsigned char value, unsigned long port)
164{ 124{
165 125
166 if (PXSEG(port)) 126 if (PXSEG(port))
167 *(volatile unsigned char *)port = value; 127 ctrl_outb(value, port);
168#if defined(CONFIG_HS7751RVOIP_CODEC)
169 else if (codec_port(port)) 128 else if (codec_port(port))
170 *(volatile unsigned cjar *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = value; 129 ctrl_outb(value, CODEC_IOMAP(port));
171#endif 130 else if (is_pci_ioaddr(port) || shifted_port(port))
172 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) 131 ctrl_outb(value, pci_ioaddr(port));
173 *(unsigned char *)PCI_IOMAP(port) = value;
174 else 132 else
175 *(volatile unsigned short *)port2adr(port) = value; 133 ctrl_outb(value, port2adr(port));
176} 134}
177 135
178void hs7751rvoip_outb_p(unsigned char value, unsigned long port) 136void hs7751rvoip_outb_p(unsigned char value, unsigned long port)
179{ 137{
180 if (PXSEG(port)) 138 if (PXSEG(port))
181 *(volatile unsigned char *)port = value; 139 ctrl_outb(value, port);
182#if defined(CONFIG_HS7751RVOIP_CODEC)
183 else if (codec_port(port)) 140 else if (codec_port(port))
184 *(volatile unsigned cjar *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = value; 141 ctrl_outb(value, CODEC_IOMAP(port));
185#endif 142 else if (is_pci_ioaddr(port) || shifted_port(port))
186 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) 143 ctrl_outb(value, pci_ioaddr(port));
187 *(unsigned char *)PCI_IOMAP(port) = value;
188 else 144 else
189 *(volatile unsigned short *)port2adr(port) = value; 145 ctrl_outw(value, port2adr(port));
190 delay(); 146
147 ctrl_delay();
191} 148}
192 149
193void hs7751rvoip_outw(unsigned short value, unsigned long port) 150void hs7751rvoip_outw(unsigned short value, unsigned long port)
194{ 151{
195 if (PXSEG(port)) 152 if (PXSEG(port))
196 *(volatile unsigned short *)port = value; 153 ctrl_outw(value, port);
197 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) 154 else if (is_pci_ioaddr(port) || shifted_port(port))
198 *(unsigned short *)PCI_IOMAP(port) = value; 155 ctrl_outw(value, pci_ioaddr(port));
199 else 156 else
200 maybebadio(outw, port); 157 maybebadio(port);
201} 158}
202 159
203void hs7751rvoip_outl(unsigned int value, unsigned long port) 160void hs7751rvoip_outl(unsigned int value, unsigned long port)
204{ 161{
205 if (PXSEG(port)) 162 if (PXSEG(port))
206 *(volatile unsigned long *)port = value; 163 ctrl_outl(value, port);
207 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) 164 else if (is_pci_ioaddr(port) || shifted_port(port))
208 *((unsigned long *)PCI_IOMAP(port)) = value; 165 ctrl_outl(value, pci_ioaddr(port));
209 else 166 else
210 maybebadio(outl, port); 167 maybebadio(port);
211} 168}
212 169
213void hs7751rvoip_insb(unsigned long port, void *addr, unsigned long count) 170void hs7751rvoip_insb(unsigned long port, void *addr, unsigned long count)
214{ 171{
172 u8 *buf = addr;
173
215 if (PXSEG(port)) 174 if (PXSEG(port))
216 while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)port; 175 while (count--)
217#if defined(CONFIG_HS7751RVOIP_CODEC) 176 *buf++ = ctrl_inb(port);
218 else if (codec_port(port)) 177 else if (codec_port(port))
219 while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)); 178 while (count--)
220#endif 179 *buf++ = ctrl_inb(CODEC_IOMAP(port));
221 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { 180 else if (is_pci_ioaddr(port) || shifted_port(port)) {
222 volatile __u8 *bp = (__u8 *)PCI_IOMAP(port); 181 volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
223 182
224 while (count--) *((volatile unsigned char *) addr)++ = *bp; 183 while (count--)
184 *buf++ = *bp;
225 } else { 185 } else {
226 volatile __u16 *p = (volatile unsigned short *)port2adr(port); 186 volatile u16 *p = (volatile u16 *)port2adr(port);
227 187
228 while (count--) *((unsigned char *) addr)++ = *p & 0xff; 188 while (count--)
189 *buf++ = *p & 0xff;
229 } 190 }
230} 191}
231 192
232void hs7751rvoip_insw(unsigned long port, void *addr, unsigned long count) 193void hs7751rvoip_insw(unsigned long port, void *addr, unsigned long count)
233{ 194{
234 volatile __u16 *p; 195 volatile u16 *p;
196 u16 *buf = addr;
235 197
236 if (PXSEG(port)) 198 if (PXSEG(port))
237 p = (volatile unsigned short *)port; 199 p = (volatile u16 *)port;
238 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) 200 else if (is_pci_ioaddr(port) || shifted_port(port))
239 p = (volatile unsigned short *)PCI_IOMAP(port); 201 p = (volatile u16 *)pci_ioaddr(port);
240 else 202 else
241 p = (volatile unsigned short *)port2adr(port); 203 p = (volatile u16 *)port2adr(port);
242 while (count--) *((__u16 *) addr)++ = *p; 204 while (count--)
205 *buf++ = *p;
243} 206}
244 207
245void hs7751rvoip_insl(unsigned long port, void *addr, unsigned long count) 208void hs7751rvoip_insl(unsigned long port, void *addr, unsigned long count)
246{ 209{
247 if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) {
248 volatile __u32 *p = (__u32 *)PCI_IOMAP(port);
249 210
250 while (count--) *((__u32 *) addr)++ = *p; 211 if (is_pci_ioaddr(port) || shifted_port(port)) {
212 volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
213 u32 *buf = addr;
214
215 while (count--)
216 *buf++ = *p;
251 } else 217 } else
252 maybebadio(insl, port); 218 maybebadio(port);
253} 219}
254 220
255void hs7751rvoip_outsb(unsigned long port, const void *addr, unsigned long count) 221void hs7751rvoip_outsb(unsigned long port, const void *addr, unsigned long count)
256{ 222{
223 const u8 *buf = addr;
224
257 if (PXSEG(port)) 225 if (PXSEG(port))
258 while (count--) *(volatile unsigned char *)port = *((unsigned char *) addr)++; 226 while (count--)
259#if defined(CONFIG_HS7751RVOIP_CODEC) 227 ctrl_outb(*buf++, port);
260 else if (codec_port(port)) 228 else if (codec_port(port))
261 while (count--) *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = *((unsigned char *) addr)++; 229 while (count--)
262#endif 230 ctrl_outb(*buf++, CODEC_IOMAP(port));
263 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { 231 else if (is_pci_ioaddr(port) || shifted_port(port)) {
264 volatile __u8 *bp = (__u8 *)PCI_IOMAP(port); 232 volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
265 233
266 while (count--) *bp = *((volatile unsigned char *) addr)++; 234 while (count--)
235 *bp = *buf++;
267 } else { 236 } else {
268 volatile __u16 *p = (volatile unsigned short *)port2adr(port); 237 volatile u16 *p = (volatile u16 *)port2adr(port);
269 238
270 while (count--) *p = *((unsigned char *) addr)++; 239 while (count--)
240 *p = *buf++;
271 } 241 }
272} 242}
273 243
274void hs7751rvoip_outsw(unsigned long port, const void *addr, unsigned long count) 244void hs7751rvoip_outsw(unsigned long port, const void *addr, unsigned long count)
275{ 245{
276 volatile __u16 *p; 246 volatile u16 *p;
247 const u16 *buf = addr;
277 248
278 if (PXSEG(port)) 249 if (PXSEG(port))
279 p = (volatile unsigned short *)port; 250 p = (volatile u16 *)port;
280 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) 251 else if (is_pci_ioaddr(port) || shifted_port(port))
281 p = (volatile unsigned short *)PCI_IOMAP(port); 252 p = (volatile u16 *)pci_ioaddr(port);
282 else 253 else
283 p = (volatile unsigned short *)port2adr(port); 254 p = (volatile u16 *)port2adr(port);
284 while (count--) *p = *((__u16 *) addr)++; 255
256 while (count--)
257 *p = *buf++;
285} 258}
286 259
287void hs7751rvoip_outsl(unsigned long port, const void *addr, unsigned long count) 260void hs7751rvoip_outsl(unsigned long port, const void *addr, unsigned long count)
288{ 261{
289 if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { 262 const u32 *buf = addr;
290 volatile __u32 *p = (__u32 *)PCI_IOMAP(port);
291 263
292 while (count--) *p = *((__u32 *) addr)++; 264 if (is_pci_ioaddr(port) || shifted_port(port)) {
265 volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
266
267 while (count--)
268 *p = *buf++;
293 } else 269 } else
294 maybebadio(outsl, port); 270 maybebadio(port);
295} 271}
296 272
297void *hs7751rvoip_ioremap(unsigned long offset, unsigned long size) 273void __iomem *hs7751rvoip_ioport_map(unsigned long port, unsigned int size)
298{ 274{
299 if (offset >= 0xfd000000) 275 if (PXSEG(port))
300 return (void *)offset; 276 return (void __iomem *)port;
301 else 277 else if (unlikely(codec_port(port) && (size == 1)))
302 return (void *)P2SEGADDR(offset); 278 return (void __iomem *)CODEC_IOMAP(port);
303} 279 else if (is_pci_ioaddr(port))
304EXPORT_SYMBOL(hs7751rvoip_ioremap); 280 return (void __iomem *)pci_ioaddr(port);
305 281
306unsigned long hs7751rvoip_isa_port2addr(unsigned long offset) 282 return (void __iomem *)port2adr(port);
307{
308 return port2adr(offset);
309} 283}
diff --git a/arch/sh/boards/renesas/hs7751rvoip/irq.c b/arch/sh/boards/renesas/hs7751rvoip/irq.c
index 705b7ddcb0d2..c617b188258a 100644
--- a/arch/sh/boards/renesas/hs7751rvoip/irq.c
+++ b/arch/sh/boards/renesas/hs7751rvoip/irq.c
@@ -35,30 +35,24 @@ static unsigned int startup_hs7751rvoip_irq(unsigned int irq)
35 35
36static void disable_hs7751rvoip_irq(unsigned int irq) 36static void disable_hs7751rvoip_irq(unsigned int irq)
37{ 37{
38 unsigned long flags;
39 unsigned short val; 38 unsigned short val;
40 unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]); 39 unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]);
41 40
42 /* Set the priority in IPR to 0 */ 41 /* Set the priority in IPR to 0 */
43 local_irq_save(flags);
44 val = ctrl_inw(IRLCNTR3); 42 val = ctrl_inw(IRLCNTR3);
45 val &= mask; 43 val &= mask;
46 ctrl_outw(val, IRLCNTR3); 44 ctrl_outw(val, IRLCNTR3);
47 local_irq_restore(flags);
48} 45}
49 46
50static void enable_hs7751rvoip_irq(unsigned int irq) 47static void enable_hs7751rvoip_irq(unsigned int irq)
51{ 48{
52 unsigned long flags;
53 unsigned short val; 49 unsigned short val;
54 unsigned short value = (0x0001 << mask_pos[irq]); 50 unsigned short value = (0x0001 << mask_pos[irq]);
55 51
56 /* Set priority in IPR back to original value */ 52 /* Set priority in IPR back to original value */
57 local_irq_save(flags);
58 val = ctrl_inw(IRLCNTR3); 53 val = ctrl_inw(IRLCNTR3);
59 val |= value; 54 val |= value;
60 ctrl_outw(val, IRLCNTR3); 55 ctrl_outw(val, IRLCNTR3);
61 local_irq_restore(flags);
62} 56}
63 57
64static void ack_hs7751rvoip_irq(unsigned int irq) 58static void ack_hs7751rvoip_irq(unsigned int irq)
diff --git a/arch/sh/boards/renesas/hs7751rvoip/led.c b/arch/sh/boards/renesas/hs7751rvoip/led.c
deleted file mode 100644
index b6608fff9f38..000000000000
--- a/arch/sh/boards/renesas/hs7751rvoip/led.c
+++ /dev/null
@@ -1,26 +0,0 @@
1/*
2 * linux/arch/sh/kernel/setup_hs7751rvoip.c
3 *
4 * Copyright (C) 2000 Kazumoto Kojima
5 *
6 * Renesas Technology Sales HS7751RVoIP Support.
7 *
8 * Modified for HS7751RVoIP by
9 * Atom Create Engineering Co., Ltd. 2002.
10 * Lineo uSolutions, Inc. 2003.
11 */
12
13#include <asm/io.h>
14#include <asm/hs7751rvoip/hs7751rvoip.h>
15
16extern unsigned int debug_counter;
17
18void debug_led_disp(void)
19{
20 unsigned short value;
21
22 value = (unsigned char)debug_counter++;
23 ctrl_outb((0xf0|value), PA_OUTPORTR);
24 if (value == 0x0f)
25 debug_counter = 0;
26}
diff --git a/arch/sh/boards/renesas/hs7751rvoip/mach.c b/arch/sh/boards/renesas/hs7751rvoip/mach.c
deleted file mode 100644
index caf967f77c61..000000000000
--- a/arch/sh/boards/renesas/hs7751rvoip/mach.c
+++ /dev/null
@@ -1,54 +0,0 @@
1/*
2 * linux/arch/sh/kernel/mach_hs7751rvoip.c
3 *
4 * Minor tweak of mach_se.c file to reference hs7751rvoip-specific items.
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Machine vector for the Renesas Technology sales HS7751RVoIP
10 */
11
12#include <linux/init.h>
13
14#include <asm/machvec.h>
15#include <asm/rtc.h>
16#include <asm/irq.h>
17#include <asm/hs7751rvoip/io.h>
18
19extern void init_hs7751rvoip_IRQ(void);
20extern void *hs7751rvoip_ioremap(unsigned long, unsigned long);
21
22/*
23 * The Machine Vector
24 */
25
26struct sh_machine_vector mv_hs7751rvoip __initmv = {
27 .mv_nr_irqs = 72,
28
29 .mv_inb = hs7751rvoip_inb,
30 .mv_inw = hs7751rvoip_inw,
31 .mv_inl = hs7751rvoip_inl,
32 .mv_outb = hs7751rvoip_outb,
33 .mv_outw = hs7751rvoip_outw,
34 .mv_outl = hs7751rvoip_outl,
35
36 .mv_inb_p = hs7751rvoip_inb_p,
37 .mv_inw_p = hs7751rvoip_inw,
38 .mv_inl_p = hs7751rvoip_inl,
39 .mv_outb_p = hs7751rvoip_outb_p,
40 .mv_outw_p = hs7751rvoip_outw,
41 .mv_outl_p = hs7751rvoip_outl,
42
43 .mv_insb = hs7751rvoip_insb,
44 .mv_insw = hs7751rvoip_insw,
45 .mv_insl = hs7751rvoip_insl,
46 .mv_outsb = hs7751rvoip_outsb,
47 .mv_outsw = hs7751rvoip_outsw,
48 .mv_outsl = hs7751rvoip_outsl,
49
50 .mv_ioremap = hs7751rvoip_ioremap,
51 .mv_isa_port2addr = hs7751rvoip_isa_port2addr,
52 .mv_init_irq = init_hs7751rvoip_IRQ,
53};
54ALIAS_MV(hs7751rvoip)
diff --git a/arch/sh/boards/renesas/hs7751rvoip/setup.c b/arch/sh/boards/renesas/hs7751rvoip/setup.c
index 29fb5ff70fb5..0414c15c3458 100644
--- a/arch/sh/boards/renesas/hs7751rvoip/setup.c
+++ b/arch/sh/boards/renesas/hs7751rvoip/setup.c
@@ -1,44 +1,38 @@
1/* 1/*
2 * linux/arch/sh/kernel/setup_hs7751rvoip.c 2 * Renesas Technology Sales HS7751RVoIP Support.
3 * 3 *
4 * Copyright (C) 2000 Kazumoto Kojima 4 * Copyright (C) 2000 Kazumoto Kojima
5 * 5 *
6 * Renesas Technology Sales HS7751RVoIP Support.
7 *
8 * Modified for HS7751RVoIP by 6 * Modified for HS7751RVoIP by
9 * Atom Create Engineering Co., Ltd. 2002. 7 * Atom Create Engineering Co., Ltd. 2002.
10 * Lineo uSolutions, Inc. 2003. 8 * Lineo uSolutions, Inc. 2003.
11 */ 9 */
12
13#include <linux/init.h> 10#include <linux/init.h>
14#include <linux/irq.h> 11#include <linux/irq.h>
15 12#include <linux/mm.h>
13#include <linux/vmalloc.h>
16#include <linux/hdreg.h> 14#include <linux/hdreg.h>
17#include <linux/ide.h> 15#include <linux/ide.h>
16#include <linux/pm.h>
18#include <asm/io.h> 17#include <asm/io.h>
19#include <asm/hs7751rvoip/hs7751rvoip.h> 18#include <asm/hs7751rvoip/hs7751rvoip.h>
19#include <asm/machvec.h>
20#include <asm/rtc.h>
21#include <asm/irq.h>
20 22
21#include <linux/mm.h> 23static void __init hs7751rvoip_init_irq(void)
22#include <linux/vmalloc.h>
23
24/* defined in mm/ioremap.c */
25extern void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags);
26
27unsigned int debug_counter;
28
29const char *get_system_type(void)
30{ 24{
31 return "HS7751RVoIP"; 25#if defined(CONFIG_HS7751RVOIP_CODEC)
26 make_ipr_irq(DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
27 make_ipr_irq(DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
28#endif
29
30 init_hs7751rvoip_IRQ();
32} 31}
33 32
34/* 33static void hs7751rvoip_power_off(void)
35 * Initialize the board
36 */
37void __init platform_setup(void)
38{ 34{
39 printk(KERN_INFO "Renesas Technology Sales HS7751RVoIP-2 support.\n"); 35 ctrl_outw(ctrl_inw(PA_OUTPORTR) & 0xffdf, PA_OUTPORTR);
40 ctrl_outb(0xf0, PA_OUTPORTR);
41 debug_counter = 0;
42} 36}
43 37
44void *area5_io8_base; 38void *area5_io8_base;
@@ -46,16 +40,15 @@ void *area6_io8_base;
46void *area5_io16_base; 40void *area5_io16_base;
47void *area6_io16_base; 41void *area6_io16_base;
48 42
49int __init cf_init(void) 43static int __init hs7751rvoip_cf_init(void)
50{ 44{
51 pgprot_t prot; 45 pgprot_t prot;
52 unsigned long paddrbase, psize; 46 unsigned long paddrbase;
53 47
54 /* open I/O area window */ 48 /* open I/O area window */
55 paddrbase = virt_to_phys((void *)(PA_AREA5_IO+0x00000800)); 49 paddrbase = virt_to_phys((void *)(PA_AREA5_IO+0x00000800));
56 psize = PAGE_SIZE;
57 prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_COM16); 50 prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_COM16);
58 area5_io16_base = p3_ioremap(paddrbase, psize, prot.pgprot); 51 area5_io16_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot);
59 if (!area5_io16_base) { 52 if (!area5_io16_base) {
60 printk("allocate_cf_area : can't open CF I/O window!\n"); 53 printk("allocate_cf_area : can't open CF I/O window!\n");
61 return -ENOMEM; 54 return -ENOMEM;
@@ -64,19 +57,18 @@ int __init cf_init(void)
64 /* XXX : do we need attribute and common-memory area also? */ 57 /* XXX : do we need attribute and common-memory area also? */
65 58
66 paddrbase = virt_to_phys((void *)PA_AREA6_IO); 59 paddrbase = virt_to_phys((void *)PA_AREA6_IO);
67 psize = PAGE_SIZE;
68#if defined(CONFIG_HS7751RVOIP_CODEC) 60#if defined(CONFIG_HS7751RVOIP_CODEC)
69 prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_COM8); 61 prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_COM8);
70#else 62#else
71 prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO8); 63 prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO8);
72#endif 64#endif
73 area6_io8_base = p3_ioremap(paddrbase, psize, prot.pgprot); 65 area6_io8_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot);
74 if (!area6_io8_base) { 66 if (!area6_io8_base) {
75 printk("allocate_cf_area : can't open CODEC I/O 8bit window!\n"); 67 printk("allocate_cf_area : can't open CODEC I/O 8bit window!\n");
76 return -ENOMEM; 68 return -ENOMEM;
77 } 69 }
78 prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO16); 70 prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO16);
79 area6_io16_base = p3_ioremap(paddrbase, psize, prot.pgprot); 71 area6_io16_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot);
80 if (!area6_io16_base) { 72 if (!area6_io16_base) {
81 printk("allocate_cf_area : can't open CODEC I/O 16bit window!\n"); 73 printk("allocate_cf_area : can't open CODEC I/O 16bit window!\n");
82 return -ENOMEM; 74 return -ENOMEM;
@@ -85,4 +77,46 @@ int __init cf_init(void)
85 return 0; 77 return 0;
86} 78}
87 79
88__initcall (cf_init); 80/*
81 * Initialize the board
82 */
83static void __init hs7751rvoip_setup(char **cmdline_p)
84{
85 device_initcall(hs7751rvoip_cf_init);
86
87 ctrl_outb(0xf0, PA_OUTPORTR);
88 pm_power_off = hs7751rvoip_power_off;
89
90 printk(KERN_INFO "Renesas Technology Sales HS7751RVoIP-2 support.\n");
91}
92
93struct sh_machine_vector mv_hs7751rvoip __initmv = {
94 .mv_name = "HS7751RVoIP",
95 .mv_setup = hs7751rvoip_setup,
96 .mv_nr_irqs = 72,
97
98 .mv_inb = hs7751rvoip_inb,
99 .mv_inw = hs7751rvoip_inw,
100 .mv_inl = hs7751rvoip_inl,
101 .mv_outb = hs7751rvoip_outb,
102 .mv_outw = hs7751rvoip_outw,
103 .mv_outl = hs7751rvoip_outl,
104
105 .mv_inb_p = hs7751rvoip_inb_p,
106 .mv_inw_p = hs7751rvoip_inw,
107 .mv_inl_p = hs7751rvoip_inl,
108 .mv_outb_p = hs7751rvoip_outb_p,
109 .mv_outw_p = hs7751rvoip_outw,
110 .mv_outl_p = hs7751rvoip_outl,
111
112 .mv_insb = hs7751rvoip_insb,
113 .mv_insw = hs7751rvoip_insw,
114 .mv_insl = hs7751rvoip_insl,
115 .mv_outsb = hs7751rvoip_outsb,
116 .mv_outsw = hs7751rvoip_outsw,
117 .mv_outsl = hs7751rvoip_outsl,
118
119 .mv_init_irq = hs7751rvoip_init_irq,
120 .mv_ioport_map = hs7751rvoip_ioport_map,
121};
122ALIAS_MV(hs7751rvoip)
diff --git a/arch/sh/boards/renesas/r7780rp/Kconfig b/arch/sh/boards/renesas/r7780rp/Kconfig
new file mode 100644
index 000000000000..c26d9813d239
--- /dev/null
+++ b/arch/sh/boards/renesas/r7780rp/Kconfig
@@ -0,0 +1,14 @@
1if SH_R7780RP
2
3menu "R7780RP options"
4
5config SH_R7780MP
6 bool "R7780MP board support"
7 default y
8 help
9 Selecting this option will enable support for the mass-production
10 version of the R7780RP. If in doubt, say Y.
11
12endmenu
13
14endif
diff --git a/arch/sh/boards/renesas/r7780rp/Makefile b/arch/sh/boards/renesas/r7780rp/Makefile
new file mode 100644
index 000000000000..f1776d027978
--- /dev/null
+++ b/arch/sh/boards/renesas/r7780rp/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the R7780RP-1 specific parts of the kernel
3#
4
5obj-y := setup.o io.o irq.o
6obj-$(CONFIG_HEARTBEAT) += led.o
diff --git a/arch/sh/boards/renesas/r7780rp/io.c b/arch/sh/boards/renesas/r7780rp/io.c
new file mode 100644
index 000000000000..db92d6e6ae99
--- /dev/null
+++ b/arch/sh/boards/renesas/r7780rp/io.c
@@ -0,0 +1,301 @@
1/*
2 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
3 * Based largely on io_se.c.
4 *
5 * I/O routine for Renesas Solutions Highlander R7780RP-1
6 *
7 * Initial version only to support LAN access; some
8 * placeholder code from io_r7780rp.c left in with the
9 * expectation of later SuperIO and PCMCIA access.
10 */
11#include <linux/pci.h>
12#include <linux/kernel.h>
13#include <linux/types.h>
14#include <asm/r7780rp/r7780rp.h>
15#include <asm/addrspace.h>
16#include <asm/io.h>
17
18static inline unsigned long port2adr(unsigned int port)
19{
20 if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
21 if (port == 0x3f6)
22 return (PA_AREA5_IO + 0x80c);
23 else
24 return (PA_AREA5_IO + 0x1000 + ((port-0x1f0) << 1));
25 else
26 maybebadio((unsigned long)port);
27
28 return port;
29}
30
31static inline unsigned long port88796l(unsigned int port, int flag)
32{
33 unsigned long addr;
34
35 if (flag)
36 addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1);
37 else
38 addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1) + 0x1000;
39
40 return addr;
41}
42
43/* The 7780 R7780RP-1 seems to have everything hooked */
44/* up pretty normally (nothing on high-bytes only...) so this */
45/* shouldn't be needed */
46static inline int shifted_port(unsigned long port)
47{
48 /* For IDE registers, value is not shifted */
49 if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
50 return 0;
51 else
52 return 1;
53}
54
55#if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE)
56#define CHECK_AX88796L_PORT(port) \
57 ((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20)))
58#else
59#define CHECK_AX88796L_PORT(port) (0)
60#endif
61
62/*
63 * General outline: remap really low stuff [eventually] to SuperIO,
64 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
65 * is mapped through the PCI IO window. Stuff with high bits (PXSEG)
66 * should be way beyond the window, and is used w/o translation for
67 * compatibility.
68 */
69u8 r7780rp_inb(unsigned long port)
70{
71 if (CHECK_AX88796L_PORT(port))
72 return ctrl_inw(port88796l(port, 0)) & 0xff;
73 else if (PXSEG(port))
74 return ctrl_inb(port);
75 else if (is_pci_ioaddr(port) || shifted_port(port))
76 return ctrl_inb(pci_ioaddr(port));
77
78 return ctrl_inw(port2adr(port)) & 0xff;
79}
80
81u8 r7780rp_inb_p(unsigned long port)
82{
83 u8 v;
84
85 if (CHECK_AX88796L_PORT(port))
86 v = ctrl_inw(port88796l(port, 0)) & 0xff;
87 else if (PXSEG(port))
88 v = ctrl_inb(port);
89 else if (is_pci_ioaddr(port) || shifted_port(port))
90 v = ctrl_inb(pci_ioaddr(port));
91 else
92 v = ctrl_inw(port2adr(port)) & 0xff;
93
94 ctrl_delay();
95
96 return v;
97}
98
99u16 r7780rp_inw(unsigned long port)
100{
101 if (CHECK_AX88796L_PORT(port))
102 maybebadio(port);
103 else if (PXSEG(port))
104 return ctrl_inw(port);
105 else if (is_pci_ioaddr(port) || shifted_port(port))
106 return ctrl_inw(pci_ioaddr(port));
107 else
108 maybebadio(port);
109
110 return 0;
111}
112
113u32 r7780rp_inl(unsigned long port)
114{
115 if (CHECK_AX88796L_PORT(port))
116 maybebadio(port);
117 else if (PXSEG(port))
118 return ctrl_inl(port);
119 else if (is_pci_ioaddr(port) || shifted_port(port))
120 return ctrl_inl(pci_ioaddr(port));
121 else
122 maybebadio(port);
123
124 return 0;
125}
126
127void r7780rp_outb(u8 value, unsigned long port)
128{
129 if (CHECK_AX88796L_PORT(port))
130 ctrl_outw(value, port88796l(port, 0));
131 else if (PXSEG(port))
132 ctrl_outb(value, port);
133 else if (is_pci_ioaddr(port) || shifted_port(port))
134 ctrl_outb(value, pci_ioaddr(port));
135 else
136 ctrl_outw(value, port2adr(port));
137}
138
139void r7780rp_outb_p(u8 value, unsigned long port)
140{
141 if (CHECK_AX88796L_PORT(port))
142 ctrl_outw(value, port88796l(port, 0));
143 else if (PXSEG(port))
144 ctrl_outb(value, port);
145 else if (is_pci_ioaddr(port) || shifted_port(port))
146 ctrl_outb(value, pci_ioaddr(port));
147 else
148 ctrl_outw(value, port2adr(port));
149
150 ctrl_delay();
151}
152
153void r7780rp_outw(u16 value, unsigned long port)
154{
155 if (CHECK_AX88796L_PORT(port))
156 maybebadio(port);
157 else if (PXSEG(port))
158 ctrl_outw(value, port);
159 else if (is_pci_ioaddr(port) || shifted_port(port))
160 ctrl_outw(value, pci_ioaddr(port));
161 else
162 maybebadio(port);
163}
164
165void r7780rp_outl(u32 value, unsigned long port)
166{
167 if (CHECK_AX88796L_PORT(port))
168 maybebadio(port);
169 else if (PXSEG(port))
170 ctrl_outl(value, port);
171 else if (is_pci_ioaddr(port) || shifted_port(port))
172 ctrl_outl(value, pci_ioaddr(port));
173 else
174 maybebadio(port);
175}
176
177void r7780rp_insb(unsigned long port, void *dst, unsigned long count)
178{
179 volatile u16 *p;
180 u8 *buf = dst;
181
182 if (CHECK_AX88796L_PORT(port)) {
183 p = (volatile u16 *)port88796l(port, 0);
184 while (count--)
185 *buf++ = *p & 0xff;
186 } else if (PXSEG(port)) {
187 while (count--)
188 *buf++ = *(volatile u8 *)port;
189 } else if (is_pci_ioaddr(port) || shifted_port(port)) {
190 volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
191
192 while (count--)
193 *buf++ = *bp;
194 } else {
195 p = (volatile u16 *)port2adr(port);
196 while (count--)
197 *buf++ = *p & 0xff;
198 }
199}
200
201void r7780rp_insw(unsigned long port, void *dst, unsigned long count)
202{
203 volatile u16 *p;
204 u16 *buf = dst;
205
206 if (CHECK_AX88796L_PORT(port))
207 p = (volatile u16 *)port88796l(port, 1);
208 else if (PXSEG(port))
209 p = (volatile u16 *)port;
210 else if (is_pci_ioaddr(port) || shifted_port(port))
211 p = (volatile u16 *)pci_ioaddr(port);
212 else
213 p = (volatile u16 *)port2adr(port);
214
215 while (count--)
216 *buf++ = *p;
217}
218
219void r7780rp_insl(unsigned long port, void *dst, unsigned long count)
220{
221 u32 *buf = dst;
222
223 if (CHECK_AX88796L_PORT(port))
224 maybebadio(port);
225 else if (is_pci_ioaddr(port) || shifted_port(port)) {
226 volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
227
228 while (count--)
229 *buf++ = *p;
230 } else
231 maybebadio(port);
232}
233
234void r7780rp_outsb(unsigned long port, const void *src, unsigned long count)
235{
236 volatile u16 *p;
237 const u8 *buf = src;
238
239 if (CHECK_AX88796L_PORT(port)) {
240 p = (volatile u16 *)port88796l(port, 0);
241 while (count--)
242 *p = *buf++;
243 } else if (PXSEG(port))
244 while (count--)
245 ctrl_outb(*buf++, port);
246 else if (is_pci_ioaddr(port) || shifted_port(port)) {
247 volatile u8 *bp = (volatile u8 *)pci_ioaddr(port);
248
249 while (count--)
250 *bp = *buf++;
251 } else {
252 p = (volatile u16 *)port2adr(port);
253 while (count--)
254 *p = *buf++;
255 }
256}
257
258void r7780rp_outsw(unsigned long port, const void *src, unsigned long count)
259{
260 volatile u16 *p;
261 const u16 *buf = src;
262
263 if (CHECK_AX88796L_PORT(port))
264 p = (volatile u16 *)port88796l(port, 1);
265 else if (PXSEG(port))
266 p = (volatile u16 *)port;
267 else if (is_pci_ioaddr(port) || shifted_port(port))
268 p = (volatile u16 *)pci_ioaddr(port);
269 else
270 p = (volatile u16 *)port2adr(port);
271
272 while (count--)
273 *p = *buf++;
274}
275
276void r7780rp_outsl(unsigned long port, const void *src, unsigned long count)
277{
278 const u32 *buf = src;
279
280 if (CHECK_AX88796L_PORT(port))
281 maybebadio(port);
282 else if (is_pci_ioaddr(port) || shifted_port(port)) {
283 volatile u32 *p = (volatile u32 *)pci_ioaddr(port);
284
285 while (count--)
286 *p = *buf++;
287 } else
288 maybebadio(port);
289}
290
291void __iomem *r7780rp_ioport_map(unsigned long port, unsigned int size)
292{
293 if (CHECK_AX88796L_PORT(port))
294 return (void __iomem *)port88796l(port, size > 1);
295 else if (PXSEG(port))
296 return (void __iomem *)port;
297 else if (is_pci_ioaddr(port) || shifted_port(port))
298 return (void __iomem *)pci_ioaddr(port);
299
300 return (void __iomem *)port2adr(port);
301}
diff --git a/arch/sh/boards/renesas/r7780rp/irq.c b/arch/sh/boards/renesas/r7780rp/irq.c
new file mode 100644
index 000000000000..61d5e5d3c294
--- /dev/null
+++ b/arch/sh/boards/renesas/r7780rp/irq.c
@@ -0,0 +1,117 @@
1/*
2 * linux/arch/sh/boards/renesas/r7780rp/irq.c
3 *
4 * Copyright (C) 2000 Kazumoto Kojima
5 *
6 * Renesas Solutions Highlander R7780RP-1 Support.
7 *
8 * Modified for R7780RP-1 by
9 * Atom Create Engineering Co., Ltd. 2002.
10 */
11
12#include <linux/config.h>
13#include <linux/init.h>
14#include <linux/irq.h>
15#include <asm/io.h>
16#include <asm/irq.h>
17#include <asm/r7780rp/r7780rp.h>
18
19#ifdef CONFIG_SH_R7780MP
20static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0};
21#else
22static int mask_pos[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 5, 6, 4, 0, 1, 2, 0};
23#endif
24
25static void enable_r7780rp_irq(unsigned int irq);
26static void disable_r7780rp_irq(unsigned int irq);
27
28/* shutdown is same as "disable" */
29#define shutdown_r7780rp_irq disable_r7780rp_irq
30
31static void ack_r7780rp_irq(unsigned int irq);
32static void end_r7780rp_irq(unsigned int irq);
33
34static unsigned int startup_r7780rp_irq(unsigned int irq)
35{
36 enable_r7780rp_irq(irq);
37 return 0; /* never anything pending */
38}
39
40static void disable_r7780rp_irq(unsigned int irq)
41{
42 unsigned short val;
43 unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]);
44
45 /* Set the priority in IPR to 0 */
46 val = ctrl_inw(IRLCNTR1);
47 val &= mask;
48 ctrl_outw(val, IRLCNTR1);
49}
50
51static void enable_r7780rp_irq(unsigned int irq)
52{
53 unsigned short val;
54 unsigned short value = (0x0001 << mask_pos[irq]);
55
56 /* Set priority in IPR back to original value */
57 val = ctrl_inw(IRLCNTR1);
58 val |= value;
59 ctrl_outw(val, IRLCNTR1);
60}
61
62static void ack_r7780rp_irq(unsigned int irq)
63{
64 disable_r7780rp_irq(irq);
65}
66
67static void end_r7780rp_irq(unsigned int irq)
68{
69 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
70 enable_r7780rp_irq(irq);
71}
72
73static struct hw_interrupt_type r7780rp_irq_type = {
74 .typename = "R7780RP-IRQ",
75 .startup = startup_r7780rp_irq,
76 .shutdown = shutdown_r7780rp_irq,
77 .enable = enable_r7780rp_irq,
78 .disable = disable_r7780rp_irq,
79 .ack = ack_r7780rp_irq,
80 .end = end_r7780rp_irq,
81};
82
83static void make_r7780rp_irq(unsigned int irq)
84{
85 disable_irq_nosync(irq);
86 irq_desc[irq].handler = &r7780rp_irq_type;
87 disable_r7780rp_irq(irq);
88}
89
90/*
91 * Initialize IRQ setting
92 */
93void __init init_r7780rp_IRQ(void)
94{
95 int i;
96
97 /* IRL0=PCI Slot #A
98 * IRL1=PCI Slot #B
99 * IRL2=PCI Slot #C
100 * IRL3=PCI Slot #D
101 * IRL4=CF Card
102 * IRL5=CF Card Insert
103 * IRL6=M66596
104 * IRL7=SD Card
105 * IRL8=Touch Panel
106 * IRL9=SCI
107 * IRL10=Serial
108 * IRL11=Extention #A
109 * IRL11=Extention #B
110 * IRL12=Debug LAN
111 * IRL13=Push Switch
112 * IRL14=ZiggBee IO
113 */
114
115 for (i=0; i<15; i++)
116 make_r7780rp_irq(i);
117}
diff --git a/arch/sh/boards/renesas/r7780rp/led.c b/arch/sh/boards/renesas/r7780rp/led.c
new file mode 100644
index 000000000000..9f02766b6f53
--- /dev/null
+++ b/arch/sh/boards/renesas/r7780rp/led.c
@@ -0,0 +1,45 @@
1/*
2 * Copyright (C) Atom Create Engineering Co., Ltd.
3 *
4 * May be copied or modified under the terms of GNU General Public
5 * License. See linux/COPYING for more information.
6 *
7 * This file contains Renesas Solutions HIGHLANDER R7780RP-1 specific LED code.
8 */
9
10#include <linux/config.h>
11#include <linux/sched.h>
12#include <asm/io.h>
13#include <asm/r7780rp/r7780rp.h>
14
15/* Cycle the LED's in the clasic Knightriger/Sun pattern */
16void heartbeat_r7780rp(void)
17{
18 static unsigned int cnt = 0, period = 0;
19 volatile unsigned short *p = (volatile unsigned short *)PA_OBLED;
20 static unsigned bit = 0, up = 1;
21 unsigned bit_pos[] = {2, 1, 0, 3, 6, 5, 4, 7};
22
23 cnt += 1;
24 if (cnt < period)
25 return;
26
27 cnt = 0;
28
29 /* Go through the points (roughly!):
30 * f(0)=10, f(1)=16, f(2)=20, f(5)=35, f(int)->110
31 */
32 period = 110 - ((300 << FSHIFT)/((avenrun[0]/5) + (3<<FSHIFT)));
33
34 *p = 1 << bit_pos[bit];
35 if (up)
36 if (bit == 7) {
37 bit--;
38 up = 0;
39 } else
40 bit++;
41 else if (bit == 0)
42 up = 1;
43 else
44 bit--;
45}
diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c
new file mode 100644
index 000000000000..b941aa0aa34e
--- /dev/null
+++ b/arch/sh/boards/renesas/r7780rp/setup.c
@@ -0,0 +1,163 @@
1/*
2 * arch/sh/boards/renesas/r7780rp/setup.c
3 *
4 * Copyright (C) 2002 Atom Create Engineering Co., Ltd.
5 * Copyright (C) 2005, 2006 Paul Mundt
6 *
7 * Renesas Solutions Highlander R7780RP-1 Support.
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#include <linux/init.h>
14#include <linux/platform_device.h>
15#include <asm/machvec.h>
16#include <asm/r7780rp/r7780rp.h>
17#include <asm/clock.h>
18#include <asm/io.h>
19
20extern void heartbeat_r7780rp(void);
21extern void init_r7780rp_IRQ(void);
22
23static struct resource m66596_usb_host_resources[] = {
24 [0] = {
25 .start = 0xa4800000,
26 .end = 0xa4ffffff,
27 .flags = IORESOURCE_MEM,
28 },
29 [1] = {
30 .start = 6, /* irq number */
31 .end = 6,
32 .flags = IORESOURCE_IRQ,
33 },
34};
35
36static struct platform_device m66596_usb_host_device = {
37 .name = "m66596-hcd",
38 .id = 0,
39 .dev = {
40 .dma_mask = NULL, /* don't use dma */
41 .coherent_dma_mask = 0xffffffff,
42 },
43 .num_resources = ARRAY_SIZE(m66596_usb_host_resources),
44 .resource = m66596_usb_host_resources,
45};
46
47static struct platform_device *r7780rp_devices[] __initdata = {
48 &m66596_usb_host_device,
49};
50
51static int __init r7780rp_devices_setup(void)
52{
53 return platform_add_devices(r7780rp_devices,
54 ARRAY_SIZE(r7780rp_devices));
55}
56
57/*
58 * Platform specific clocks
59 */
60static void ivdr_clk_enable(struct clk *clk)
61{
62 ctrl_outw(ctrl_inw(PA_IVDRCTL) | (1 << 8), PA_IVDRCTL);
63}
64
65static void ivdr_clk_disable(struct clk *clk)
66{
67 ctrl_outw(ctrl_inw(PA_IVDRCTL) & ~(1 << 8), PA_IVDRCTL);
68}
69
70static struct clk_ops ivdr_clk_ops = {
71 .enable = ivdr_clk_enable,
72 .disable = ivdr_clk_disable,
73};
74
75static struct clk ivdr_clk = {
76 .name = "ivdr_clk",
77 .ops = &ivdr_clk_ops,
78};
79
80static struct clk *r7780rp_clocks[] = {
81 &ivdr_clk,
82};
83
84static void r7780rp_power_off(void)
85{
86#ifdef CONFIG_SH_R7780MP
87 ctrl_outw(0x0001, PA_POFF);
88#endif
89}
90
91/*
92 * Initialize the board
93 */
94static void __init r7780rp_setup(char **cmdline_p)
95{
96 u16 ver = ctrl_inw(PA_VERREG);
97 int i;
98
99 device_initcall(r7780rp_devices_setup);
100
101 printk(KERN_INFO "Renesas Solutions Highlander R7780RP-1 support.\n");
102
103 printk(KERN_INFO "Board version: %d (revision %d), "
104 "FPGA version: %d (revision %d)\n",
105 (ver >> 12) & 0xf, (ver >> 8) & 0xf,
106 (ver >> 4) & 0xf, ver & 0xf);
107
108 /*
109 * Enable the important clocks right away..
110 */
111 for (i = 0; i < ARRAY_SIZE(r7780rp_clocks); i++) {
112 struct clk *clk = r7780rp_clocks[i];
113
114 clk_register(clk);
115 clk_enable(clk);
116 }
117
118 ctrl_outw(0x0000, PA_OBLED); /* Clear LED. */
119#ifndef CONFIG_SH_R7780MP
120 ctrl_outw(0x0001, PA_SDPOW); /* SD Power ON */
121#endif
122 ctrl_outw(ctrl_inw(PA_IVDRCTL) | 0x0100, PA_IVDRCTL); /* Si13112 */
123
124 pm_power_off = r7780rp_power_off;
125}
126
127/*
128 * The Machine Vector
129 */
130struct sh_machine_vector mv_r7780rp __initmv = {
131 .mv_name = "Highlander R7780RP-1",
132 .mv_setup = r7780rp_setup,
133
134 .mv_nr_irqs = 109,
135
136 .mv_inb = r7780rp_inb,
137 .mv_inw = r7780rp_inw,
138 .mv_inl = r7780rp_inl,
139 .mv_outb = r7780rp_outb,
140 .mv_outw = r7780rp_outw,
141 .mv_outl = r7780rp_outl,
142
143 .mv_inb_p = r7780rp_inb_p,
144 .mv_inw_p = r7780rp_inw,
145 .mv_inl_p = r7780rp_inl,
146 .mv_outb_p = r7780rp_outb_p,
147 .mv_outw_p = r7780rp_outw,
148 .mv_outl_p = r7780rp_outl,
149
150 .mv_insb = r7780rp_insb,
151 .mv_insw = r7780rp_insw,
152 .mv_insl = r7780rp_insl,
153 .mv_outsb = r7780rp_outsb,
154 .mv_outsw = r7780rp_outsw,
155 .mv_outsl = r7780rp_outsl,
156
157 .mv_ioport_map = r7780rp_ioport_map,
158 .mv_init_irq = init_r7780rp_IRQ,
159#ifdef CONFIG_HEARTBEAT
160 .mv_heartbeat = heartbeat_r7780rp,
161#endif
162};
163ALIAS_MV(r7780rp)
diff --git a/arch/sh/boards/renesas/rts7751r2d/Kconfig b/arch/sh/boards/renesas/rts7751r2d/Kconfig
new file mode 100644
index 000000000000..7780d1fb13ff
--- /dev/null
+++ b/arch/sh/boards/renesas/rts7751r2d/Kconfig
@@ -0,0 +1,12 @@
1if SH_RTS7751R2D
2
3menu "RTS7751R2D options"
4
5config RTS7751R2D_REV11
6 bool "RTS7751R2D Rev. 1.1 board support"
7 help
8 Selecting this option will support version rev. 1.1.
9endmenu
10
11endif
12
diff --git a/arch/sh/boards/renesas/rts7751r2d/Makefile b/arch/sh/boards/renesas/rts7751r2d/Makefile
index daa53334bdc3..686fc9ea5989 100644
--- a/arch/sh/boards/renesas/rts7751r2d/Makefile
+++ b/arch/sh/boards/renesas/rts7751r2d/Makefile
@@ -1,10 +1,6 @@
1# 1#
2# Makefile for the RTS7751R2D specific parts of the kernel 2# Makefile for the RTS7751R2D specific parts of the kernel
3# 3#
4# Note! Dependencies are done automagically by 'make dep', which also
5# removes any old dependencies. DON'T put your own dependencies here
6# unless it's something special (ie not a .c file).
7#
8
9obj-y := mach.o setup.o io.o irq.o led.o
10 4
5obj-y := setup.o io.o irq.o
6obj-$(CONFIG_HEARTBEAT) += led.o
diff --git a/arch/sh/boards/renesas/rts7751r2d/io.c b/arch/sh/boards/renesas/rts7751r2d/io.c
index 123abbbc91e0..135aa0b5e62d 100644
--- a/arch/sh/boards/renesas/rts7751r2d/io.c
+++ b/arch/sh/boards/renesas/rts7751r2d/io.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/sh/kernel/io_rts7751r2d.c
3 *
4 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel 2 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
5 * Based largely on io_se.c. 3 * Based largely on io_se.c.
6 * 4 *
@@ -10,17 +8,13 @@
10 * placeholder code from io_rts7751r2d.c left in with the 8 * placeholder code from io_rts7751r2d.c left in with the
11 * expectation of later SuperIO and PCMCIA access. 9 * expectation of later SuperIO and PCMCIA access.
12 */ 10 */
13
14#include <linux/kernel.h> 11#include <linux/kernel.h>
15#include <linux/types.h> 12#include <linux/types.h>
16#include <asm/io.h> 13#include <linux/pci.h>
17#include <asm/rts7751r2d/rts7751r2d.h> 14#include <asm/rts7751r2d/rts7751r2d.h>
15#include <asm/io.h>
18#include <asm/addrspace.h> 16#include <asm/addrspace.h>
19 17
20#include <linux/module.h>
21#include <linux/pci.h>
22#include "../../../drivers/pci/pci-sh7751.h"
23
24/* 18/*
25 * The 7751R RTS7751R2D uses the built-in PCI controller (PCIC) 19 * The 7751R RTS7751R2D uses the built-in PCI controller (PCIC)
26 * of the 7751R processor, and has a SuperIO accessible via the PCI. 20 * of the 7751R processor, and has a SuperIO accessible via the PCI.
@@ -28,22 +22,6 @@
28 * like the other Solution Engine boards. 22 * like the other Solution Engine boards.
29 */ 23 */
30 24
31#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR)
32#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR)
33#define PCI_IO_AREA SH7751_PCI_IO_BASE
34#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE
35
36#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
37
38#define maybebadio(name,port) \
39 printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
40 #name, (port), (__u32) __builtin_return_address(0))
41
42static inline void delay(void)
43{
44 ctrl_inw(0xa0000000);
45}
46
47static inline unsigned long port2adr(unsigned int port) 25static inline unsigned long port2adr(unsigned int port)
48{ 26{
49 if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) 27 if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
@@ -52,7 +30,7 @@ static inline unsigned long port2adr(unsigned int port)
52 else 30 else
53 return (PA_AREA5_IO + 0x1000 + ((port-0x1f0) << 1)); 31 return (PA_AREA5_IO + 0x1000 + ((port-0x1f0) << 1));
54 else 32 else
55 maybebadio(port2adr, (unsigned long)port); 33 maybebadio((unsigned long)port);
56 34
57 return port; 35 return port;
58} 36}
@@ -81,17 +59,6 @@ static inline int shifted_port(unsigned long port)
81 return 1; 59 return 1;
82} 60}
83 61
84/* In case someone configures the kernel w/o PCI support: in that */
85/* scenario, don't ever bother to check for PCI-window addresses */
86
87/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
88#if defined(CONFIG_PCI)
89#define CHECK_SH7751_PCIIO(port) \
90 ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
91#else
92#define CHECK_SH7751_PCIIO(port) (0)
93#endif
94
95#if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE) 62#if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE)
96#define CHECK_AX88796L_PORT(port) \ 63#define CHECK_AX88796L_PORT(port) \
97 ((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20))) 64 ((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20)))
@@ -112,8 +79,8 @@ unsigned char rts7751r2d_inb(unsigned long port)
112 return (*(volatile unsigned short *)port88796l(port, 0)) & 0xff; 79 return (*(volatile unsigned short *)port88796l(port, 0)) & 0xff;
113 else if (PXSEG(port)) 80 else if (PXSEG(port))
114 return *(volatile unsigned char *)port; 81 return *(volatile unsigned char *)port;
115 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) 82 else if (is_pci_ioaddr(port) || shifted_port(port))
116 return *(volatile unsigned char *)PCI_IOMAP(port); 83 return *(volatile unsigned char *)pci_ioaddr(port);
117 else 84 else
118 return (*(volatile unsigned short *)port2adr(port) & 0xff); 85 return (*(volatile unsigned short *)port2adr(port) & 0xff);
119} 86}
@@ -126,11 +93,12 @@ unsigned char rts7751r2d_inb_p(unsigned long port)
126 v = (*(volatile unsigned short *)port88796l(port, 0)) & 0xff; 93 v = (*(volatile unsigned short *)port88796l(port, 0)) & 0xff;
127 else if (PXSEG(port)) 94 else if (PXSEG(port))
128 v = *(volatile unsigned char *)port; 95 v = *(volatile unsigned char *)port;
129 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) 96 else if (is_pci_ioaddr(port) || shifted_port(port))
130 v = *(volatile unsigned char *)PCI_IOMAP(port); 97 v = *(volatile unsigned char *)pci_ioaddr(port);
131 else 98 else
132 v = (*(volatile unsigned short *)port2adr(port) & 0xff); 99 v = (*(volatile unsigned short *)port2adr(port) & 0xff);
133 delay(); 100
101 ctrl_delay();
134 102
135 return v; 103 return v;
136} 104}
@@ -138,13 +106,13 @@ unsigned char rts7751r2d_inb_p(unsigned long port)
138unsigned short rts7751r2d_inw(unsigned long port) 106unsigned short rts7751r2d_inw(unsigned long port)
139{ 107{
140 if (CHECK_AX88796L_PORT(port)) 108 if (CHECK_AX88796L_PORT(port))
141 maybebadio(inw, port); 109 maybebadio(port);
142 else if (PXSEG(port)) 110 else if (PXSEG(port))
143 return *(volatile unsigned short *)port; 111 return *(volatile unsigned short *)port;
144 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) 112 else if (is_pci_ioaddr(port) || shifted_port(port))
145 return *(volatile unsigned short *)PCI_IOMAP(port); 113 return *(volatile unsigned short *)pci_ioaddr(port);
146 else 114 else
147 maybebadio(inw, port); 115 maybebadio(port);
148 116
149 return 0; 117 return 0;
150} 118}
@@ -152,13 +120,13 @@ unsigned short rts7751r2d_inw(unsigned long port)
152unsigned int rts7751r2d_inl(unsigned long port) 120unsigned int rts7751r2d_inl(unsigned long port)
153{ 121{
154 if (CHECK_AX88796L_PORT(port)) 122 if (CHECK_AX88796L_PORT(port))
155 maybebadio(inl, port); 123 maybebadio(port);
156 else if (PXSEG(port)) 124 else if (PXSEG(port))
157 return *(volatile unsigned long *)port; 125 return *(volatile unsigned long *)port;
158 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) 126 else if (is_pci_ioaddr(port) || shifted_port(port))
159 return *(volatile unsigned long *)PCI_IOMAP(port); 127 return *(volatile unsigned long *)pci_ioaddr(port);
160 else 128 else
161 maybebadio(inl, port); 129 maybebadio(port);
162 130
163 return 0; 131 return 0;
164} 132}
@@ -169,8 +137,8 @@ void rts7751r2d_outb(unsigned char value, unsigned long port)
169 *((volatile unsigned short *)port88796l(port, 0)) = value; 137 *((volatile unsigned short *)port88796l(port, 0)) = value;
170 else if (PXSEG(port)) 138 else if (PXSEG(port))
171 *(volatile unsigned char *)port = value; 139 *(volatile unsigned char *)port = value;
172 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) 140 else if (is_pci_ioaddr(port) || shifted_port(port))
173 *(volatile unsigned char *)PCI_IOMAP(port) = value; 141 *(volatile unsigned char *)pci_ioaddr(port) = value;
174 else 142 else
175 *(volatile unsigned short *)port2adr(port) = value; 143 *(volatile unsigned short *)port2adr(port) = value;
176} 144}
@@ -181,143 +149,152 @@ void rts7751r2d_outb_p(unsigned char value, unsigned long port)
181 *((volatile unsigned short *)port88796l(port, 0)) = value; 149 *((volatile unsigned short *)port88796l(port, 0)) = value;
182 else if (PXSEG(port)) 150 else if (PXSEG(port))
183 *(volatile unsigned char *)port = value; 151 *(volatile unsigned char *)port = value;
184 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) 152 else if (is_pci_ioaddr(port) || shifted_port(port))
185 *(volatile unsigned char *)PCI_IOMAP(port) = value; 153 *(volatile unsigned char *)pci_ioaddr(port) = value;
186 else 154 else
187 *(volatile unsigned short *)port2adr(port) = value; 155 *(volatile unsigned short *)port2adr(port) = value;
188 delay(); 156
157 ctrl_delay();
189} 158}
190 159
191void rts7751r2d_outw(unsigned short value, unsigned long port) 160void rts7751r2d_outw(unsigned short value, unsigned long port)
192{ 161{
193 if (CHECK_AX88796L_PORT(port)) 162 if (CHECK_AX88796L_PORT(port))
194 maybebadio(outw, port); 163 maybebadio(port);
195 else if (PXSEG(port)) 164 else if (PXSEG(port))
196 *(volatile unsigned short *)port = value; 165 *(volatile unsigned short *)port = value;
197 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) 166 else if (is_pci_ioaddr(port) || shifted_port(port))
198 *(volatile unsigned short *)PCI_IOMAP(port) = value; 167 *(volatile unsigned short *)pci_ioaddr(port) = value;
199 else 168 else
200 maybebadio(outw, port); 169 maybebadio(port);
201} 170}
202 171
203void rts7751r2d_outl(unsigned int value, unsigned long port) 172void rts7751r2d_outl(unsigned int value, unsigned long port)
204{ 173{
205 if (CHECK_AX88796L_PORT(port)) 174 if (CHECK_AX88796L_PORT(port))
206 maybebadio(outl, port); 175 maybebadio(port);
207 else if (PXSEG(port)) 176 else if (PXSEG(port))
208 *(volatile unsigned long *)port = value; 177 *(volatile unsigned long *)port = value;
209 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) 178 else if (is_pci_ioaddr(port) || shifted_port(port))
210 *(volatile unsigned long *)PCI_IOMAP(port) = value; 179 *(volatile unsigned long *)pci_ioaddr(port) = value;
211 else 180 else
212 maybebadio(outl, port); 181 maybebadio(port);
213} 182}
214 183
215void rts7751r2d_insb(unsigned long port, void *addr, unsigned long count) 184void rts7751r2d_insb(unsigned long port, void *addr, unsigned long count)
216{ 185{
186 unsigned long a = (unsigned long)addr;
217 volatile __u8 *bp; 187 volatile __u8 *bp;
218 volatile __u16 *p; 188 volatile __u16 *p;
219 unsigned char *s = addr;
220 189
221 if (CHECK_AX88796L_PORT(port)) { 190 if (CHECK_AX88796L_PORT(port)) {
222 p = (volatile unsigned short *)port88796l(port, 0); 191 p = (volatile unsigned short *)port88796l(port, 0);
223 while (count--) *s++ = *p & 0xff; 192 while (count--)
193 ctrl_outb(*p & 0xff, a++);
224 } else if (PXSEG(port)) 194 } else if (PXSEG(port))
225 while (count--) *s++ = *(volatile unsigned char *)port; 195 while (count--)
226 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { 196 ctrl_outb(ctrl_inb(port), a++);
227 bp = (__u8 *)PCI_IOMAP(port); 197 else if (is_pci_ioaddr(port) || shifted_port(port)) {
228 while (count--) *s++ = *bp; 198 bp = (__u8 *)pci_ioaddr(port);
199 while (count--)
200 ctrl_outb(*bp, a++);
229 } else { 201 } else {
230 p = (volatile unsigned short *)port2adr(port); 202 p = (volatile unsigned short *)port2adr(port);
231 while (count--) *s++ = *p & 0xff; 203 while (count--)
204 ctrl_outb(*p & 0xff, a++);
232 } 205 }
233} 206}
234 207
235void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count) 208void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count)
236{ 209{
210 unsigned long a = (unsigned long)addr;
237 volatile __u16 *p; 211 volatile __u16 *p;
238 __u16 *s = addr;
239 212
240 if (CHECK_AX88796L_PORT(port)) 213 if (CHECK_AX88796L_PORT(port))
241 p = (volatile unsigned short *)port88796l(port, 1); 214 p = (volatile unsigned short *)port88796l(port, 1);
242 else if (PXSEG(port)) 215 else if (PXSEG(port))
243 p = (volatile unsigned short *)port; 216 p = (volatile unsigned short *)port;
244 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) 217 else if (is_pci_ioaddr(port) || shifted_port(port))
245 p = (volatile unsigned short *)PCI_IOMAP(port); 218 p = (volatile unsigned short *)pci_ioaddr(port);
246 else 219 else
247 p = (volatile unsigned short *)port2adr(port); 220 p = (volatile unsigned short *)port2adr(port);
248 while (count--) *s++ = *p; 221 while (count--)
222 ctrl_outw(*p, a++);
249} 223}
250 224
251void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count) 225void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count)
252{ 226{
253 if (CHECK_AX88796L_PORT(port)) 227 if (CHECK_AX88796L_PORT(port))
254 maybebadio(insl, port); 228 maybebadio(port);
255 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { 229 else if (is_pci_ioaddr(port) || shifted_port(port)) {
256 volatile __u32 *p = (__u32 *)PCI_IOMAP(port); 230 unsigned long a = (unsigned long)addr;
257 __u32 *s = addr; 231
258 232 while (count--) {
259 while (count--) *s++ = *p; 233 ctrl_outl(ctrl_inl(pci_ioaddr(port)), a);
234 a += 4;
235 }
260 } else 236 } else
261 maybebadio(insl, port); 237 maybebadio(port);
262} 238}
263 239
264void rts7751r2d_outsb(unsigned long port, const void *addr, unsigned long count) 240void rts7751r2d_outsb(unsigned long port, const void *addr, unsigned long count)
265{ 241{
242 unsigned long a = (unsigned long)addr;
266 volatile __u8 *bp; 243 volatile __u8 *bp;
267 volatile __u16 *p; 244 volatile __u16 *p;
268 const __u8 *s = addr;
269 245
270 if (CHECK_AX88796L_PORT(port)) { 246 if (CHECK_AX88796L_PORT(port)) {
271 p = (volatile unsigned short *)port88796l(port, 0); 247 p = (volatile unsigned short *)port88796l(port, 0);
272 while (count--) *p = *s++; 248 while (count--)
249 *p = ctrl_inb(a++);
273 } else if (PXSEG(port)) 250 } else if (PXSEG(port))
274 while (count--) *(volatile unsigned char *)port = *s++; 251 while (count--)
275 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { 252 ctrl_outb(a++, port);
276 bp = (__u8 *)PCI_IOMAP(port); 253 else if (is_pci_ioaddr(port) || shifted_port(port)) {
277 while (count--) *bp = *s++; 254 bp = (__u8 *)pci_ioaddr(port);
255 while (count--)
256 *bp = ctrl_inb(a++);
278 } else { 257 } else {
279 p = (volatile unsigned short *)port2adr(port); 258 p = (volatile unsigned short *)port2adr(port);
280 while (count--) *p = *s++; 259 while (count--)
260 *p = ctrl_inb(a++);
281 } 261 }
282} 262}
283 263
284void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count) 264void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count)
285{ 265{
266 unsigned long a = (unsigned long)addr;
286 volatile __u16 *p; 267 volatile __u16 *p;
287 const __u16 *s = addr;
288 268
289 if (CHECK_AX88796L_PORT(port)) 269 if (CHECK_AX88796L_PORT(port))
290 p = (volatile unsigned short *)port88796l(port, 1); 270 p = (volatile unsigned short *)port88796l(port, 1);
291 else if (PXSEG(port)) 271 else if (PXSEG(port))
292 p = (volatile unsigned short *)port; 272 p = (volatile unsigned short *)port;
293 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) 273 else if (is_pci_ioaddr(port) || shifted_port(port))
294 p = (volatile unsigned short *)PCI_IOMAP(port); 274 p = (volatile unsigned short *)pci_ioaddr(port);
295 else 275 else
296 p = (volatile unsigned short *)port2adr(port); 276 p = (volatile unsigned short *)port2adr(port);
297 while (count--) *p = *s++; 277
278 while (count--) {
279 ctrl_outw(*p, a);
280 a += 2;
281 }
298} 282}
299 283
300void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count) 284void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count)
301{ 285{
302 if (CHECK_AX88796L_PORT(port)) 286 if (CHECK_AX88796L_PORT(port))
303 maybebadio(outsl, port); 287 maybebadio(port);
304 else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { 288 else if (is_pci_ioaddr(port) || shifted_port(port)) {
305 volatile __u32 *p = (__u32 *)PCI_IOMAP(port); 289 unsigned long a = (unsigned long)addr;
306 const __u32 *s = addr; 290
307 291 while (count--) {
308 while (count--) *p = *s++; 292 ctrl_outl(ctrl_inl(a), pci_ioaddr(port));
293 a += 4;
294 }
309 } else 295 } else
310 maybebadio(outsl, port); 296 maybebadio(port);
311}
312
313void *rts7751r2d_ioremap(unsigned long offset, unsigned long size)
314{
315 if (offset >= 0xfd000000)
316 return (void *)offset;
317 else
318 return (void *)P2SEGADDR(offset);
319} 297}
320EXPORT_SYMBOL(rts7751r2d_ioremap);
321 298
322unsigned long rts7751r2d_isa_port2addr(unsigned long offset) 299unsigned long rts7751r2d_isa_port2addr(unsigned long offset)
323{ 300{
diff --git a/arch/sh/boards/renesas/rts7751r2d/irq.c b/arch/sh/boards/renesas/rts7751r2d/irq.c
index 154535440bbf..c915e7a3693a 100644
--- a/arch/sh/boards/renesas/rts7751r2d/irq.c
+++ b/arch/sh/boards/renesas/rts7751r2d/irq.c
@@ -41,30 +41,24 @@ static unsigned int startup_rts7751r2d_irq(unsigned int irq)
41 41
42static void disable_rts7751r2d_irq(unsigned int irq) 42static void disable_rts7751r2d_irq(unsigned int irq)
43{ 43{
44 unsigned long flags;
45 unsigned short val; 44 unsigned short val;
46 unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]); 45 unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]);
47 46
48 /* Set the priority in IPR to 0 */ 47 /* Set the priority in IPR to 0 */
49 local_irq_save(flags);
50 val = ctrl_inw(IRLCNTR1); 48 val = ctrl_inw(IRLCNTR1);
51 val &= mask; 49 val &= mask;
52 ctrl_outw(val, IRLCNTR1); 50 ctrl_outw(val, IRLCNTR1);
53 local_irq_restore(flags);
54} 51}
55 52
56static void enable_rts7751r2d_irq(unsigned int irq) 53static void enable_rts7751r2d_irq(unsigned int irq)
57{ 54{
58 unsigned long flags;
59 unsigned short val; 55 unsigned short val;
60 unsigned short value = (0x0001 << mask_pos[irq]); 56 unsigned short value = (0x0001 << mask_pos[irq]);
61 57
62 /* Set priority in IPR back to original value */ 58 /* Set priority in IPR back to original value */
63 local_irq_save(flags);
64 val = ctrl_inw(IRLCNTR1); 59 val = ctrl_inw(IRLCNTR1);
65 val |= value; 60 val |= value;
66 ctrl_outw(val, IRLCNTR1); 61 ctrl_outw(val, IRLCNTR1);
67 local_irq_restore(flags);
68} 62}
69 63
70int rts7751r2d_irq_demux(int irq) 64int rts7751r2d_irq_demux(int irq)
diff --git a/arch/sh/boards/renesas/rts7751r2d/led.c b/arch/sh/boards/renesas/rts7751r2d/led.c
index 4d16de71fac1..e14a13d12d4a 100644
--- a/arch/sh/boards/renesas/rts7751r2d/led.c
+++ b/arch/sh/boards/renesas/rts7751r2d/led.c
@@ -12,8 +12,6 @@
12#include <asm/io.h> 12#include <asm/io.h>
13#include <asm/rts7751r2d/rts7751r2d.h> 13#include <asm/rts7751r2d/rts7751r2d.h>
14 14
15extern unsigned int debug_counter;
16
17#ifdef CONFIG_HEARTBEAT 15#ifdef CONFIG_HEARTBEAT
18 16
19#include <linux/sched.h> 17#include <linux/sched.h>
@@ -55,12 +53,3 @@ void rts7751r2d_led(unsigned short value)
55 ctrl_outw(value, PA_OUTPORT); 53 ctrl_outw(value, PA_OUTPORT);
56} 54}
57 55
58void debug_led_disp(void)
59{
60 unsigned short value;
61
62 value = (unsigned short)debug_counter++;
63 rts7751r2d_led(value);
64 if (value == 0xff)
65 debug_counter = 0;
66}
diff --git a/arch/sh/boards/renesas/rts7751r2d/mach.c b/arch/sh/boards/renesas/rts7751r2d/mach.c
deleted file mode 100644
index 5ed9e97ea197..000000000000
--- a/arch/sh/boards/renesas/rts7751r2d/mach.c
+++ /dev/null
@@ -1,69 +0,0 @@
1/*
2 * linux/arch/sh/kernel/mach_rts7751r2d.c
3 *
4 * Minor tweak of mach_se.c file to reference rts7751r2d-specific items.
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Machine vector for the Renesas Technology sales RTS7751R2D
10 */
11
12#include <linux/init.h>
13#include <linux/types.h>
14
15#include <asm/machvec.h>
16#include <asm/rtc.h>
17#include <asm/irq.h>
18#include <asm/rts7751r2d/io.h>
19
20extern void heartbeat_rts7751r2d(void);
21extern void init_rts7751r2d_IRQ(void);
22extern void *rts7751r2d_ioremap(unsigned long, unsigned long);
23extern int rts7751r2d_irq_demux(int irq);
24
25extern void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t);
26extern int voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t);
27
28/*
29 * The Machine Vector
30 */
31
32struct sh_machine_vector mv_rts7751r2d __initmv = {
33 .mv_nr_irqs = 72,
34
35 .mv_inb = rts7751r2d_inb,
36 .mv_inw = rts7751r2d_inw,
37 .mv_inl = rts7751r2d_inl,
38 .mv_outb = rts7751r2d_outb,
39 .mv_outw = rts7751r2d_outw,
40 .mv_outl = rts7751r2d_outl,
41
42 .mv_inb_p = rts7751r2d_inb_p,
43 .mv_inw_p = rts7751r2d_inw,
44 .mv_inl_p = rts7751r2d_inl,
45 .mv_outb_p = rts7751r2d_outb_p,
46 .mv_outw_p = rts7751r2d_outw,
47 .mv_outl_p = rts7751r2d_outl,
48
49 .mv_insb = rts7751r2d_insb,
50 .mv_insw = rts7751r2d_insw,
51 .mv_insl = rts7751r2d_insl,
52 .mv_outsb = rts7751r2d_outsb,
53 .mv_outsw = rts7751r2d_outsw,
54 .mv_outsl = rts7751r2d_outsl,
55
56 .mv_ioremap = rts7751r2d_ioremap,
57 .mv_isa_port2addr = rts7751r2d_isa_port2addr,
58 .mv_init_irq = init_rts7751r2d_IRQ,
59#ifdef CONFIG_HEARTBEAT
60 .mv_heartbeat = heartbeat_rts7751r2d,
61#endif
62 .mv_irq_demux = rts7751r2d_irq_demux,
63
64#ifdef CONFIG_USB_OHCI_HCD
65 .mv_consistent_alloc = voyagergx_consistent_alloc,
66 .mv_consistent_free = voyagergx_consistent_free,
67#endif
68};
69ALIAS_MV(rts7751r2d)
diff --git a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c
index 2587fd1a0240..20597a6e6702 100644
--- a/arch/sh/boards/renesas/rts7751r2d/setup.c
+++ b/arch/sh/boards/renesas/rts7751r2d/setup.c
@@ -1,31 +1,142 @@
1/* 1/*
2 * linux/arch/sh/kernel/setup_rts7751r2d.c
3 *
4 * Copyright (C) 2000 Kazumoto Kojima
5 *
6 * Renesas Technology Sales RTS7751R2D Support. 2 * Renesas Technology Sales RTS7751R2D Support.
7 * 3 *
8 * Modified for RTS7751R2D by 4 * Copyright (C) 2002 Atom Create Engineering Co., Ltd.
9 * Atom Create Engineering Co., Ltd. 2002. 5 * Copyright (C) 2004 - 2006 Paul Mundt
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */ 10 */
11
12#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/platform_device.h>
13#include <linux/serial_8250.h>
14#include <linux/pm.h>
13#include <asm/io.h> 15#include <asm/io.h>
14#include <asm/rts7751r2d/rts7751r2d.h> 16#include <asm/machvec.h>
17#include <asm/mach/rts7751r2d.h>
18#include <asm/voyagergx.h>
19
20extern void heartbeat_rts7751r2d(void);
21extern void init_rts7751r2d_IRQ(void);
22extern int rts7751r2d_irq_demux(int irq);
23
24extern void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t);
25extern int voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t);
26
27static struct plat_serial8250_port uart_platform_data[] = {
28 {
29 .membase = (void *)VOYAGER_UART_BASE,
30 .mapbase = VOYAGER_UART_BASE,
31 .iotype = UPIO_MEM,
32 .irq = VOYAGER_UART0_IRQ,
33 .flags = UPF_BOOT_AUTOCONF,
34 .regshift = 2,
35 .uartclk = (9600 * 16),
36 }, {
37 .flags = 0,
38 },
39};
40
41static void __init voyagergx_serial_init(void)
42{
43 unsigned long val;
44
45 /*
46 * GPIO Control
47 */
48 val = inl(GPIO_MUX_HIGH);
49 val |= 0x00001fe0;
50 outl(val, GPIO_MUX_HIGH);
51
52 /*
53 * Power Mode Gate
54 */
55 val = inl(POWER_MODE0_GATE);
56 val |= (POWER_MODE0_GATE_U0 | POWER_MODE0_GATE_U1);
57 outl(val, POWER_MODE0_GATE);
58
59 val = inl(POWER_MODE1_GATE);
60 val |= (POWER_MODE1_GATE_U0 | POWER_MODE1_GATE_U1);
61 outl(val, POWER_MODE1_GATE);
62}
63
64static struct platform_device uart_device = {
65 .name = "serial8250",
66 .id = -1,
67 .dev = {
68 .platform_data = uart_platform_data,
69 },
70};
71
72static struct platform_device *rts7751r2d_devices[] __initdata = {
73 &uart_device,
74};
15 75
16unsigned int debug_counter; 76static int __init rts7751r2d_devices_setup(void)
77{
78 return platform_add_devices(rts7751r2d_devices,
79 ARRAY_SIZE(rts7751r2d_devices));
80}
17 81
18const char *get_system_type(void) 82static void rts7751r2d_power_off(void)
19{ 83{
20 return "RTS7751R2D"; 84 ctrl_outw(0x0001, PA_POWOFF);
21} 85}
22 86
23/* 87/*
24 * Initialize the board 88 * Initialize the board
25 */ 89 */
26void __init platform_setup(void) 90static void __init rts7751r2d_setup(char **cmdline_p)
27{ 91{
28 printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n"); 92 device_initcall(rts7751r2d_devices_setup);
93
29 ctrl_outw(0x0000, PA_OUTPORT); 94 ctrl_outw(0x0000, PA_OUTPORT);
30 debug_counter = 0; 95 pm_power_off = rts7751r2d_power_off;
96
97 voyagergx_serial_init();
98
99 printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n");
31} 100}
101
102/*
103 * The Machine Vector
104 */
105struct sh_machine_vector mv_rts7751r2d __initmv = {
106 .mv_name = "RTS7751R2D",
107 .mv_setup = rts7751r2d_setup,
108 .mv_nr_irqs = 72,
109
110 .mv_inb = rts7751r2d_inb,
111 .mv_inw = rts7751r2d_inw,
112 .mv_inl = rts7751r2d_inl,
113 .mv_outb = rts7751r2d_outb,
114 .mv_outw = rts7751r2d_outw,
115 .mv_outl = rts7751r2d_outl,
116
117 .mv_inb_p = rts7751r2d_inb_p,
118 .mv_inw_p = rts7751r2d_inw,
119 .mv_inl_p = rts7751r2d_inl,
120 .mv_outb_p = rts7751r2d_outb_p,
121 .mv_outw_p = rts7751r2d_outw,
122 .mv_outl_p = rts7751r2d_outl,
123
124 .mv_insb = rts7751r2d_insb,
125 .mv_insw = rts7751r2d_insw,
126 .mv_insl = rts7751r2d_insl,
127 .mv_outsb = rts7751r2d_outsb,
128 .mv_outsw = rts7751r2d_outsw,
129 .mv_outsl = rts7751r2d_outsl,
130
131 .mv_init_irq = init_rts7751r2d_IRQ,
132#ifdef CONFIG_HEARTBEAT
133 .mv_heartbeat = heartbeat_rts7751r2d,
134#endif
135 .mv_irq_demux = rts7751r2d_irq_demux,
136
137#ifdef CONFIG_USB_SM501
138 .mv_consistent_alloc = voyagergx_consistent_alloc,
139 .mv_consistent_free = voyagergx_consistent_free,
140#endif
141};
142ALIAS_MV(rts7751r2d)
diff --git a/arch/sh/boards/renesas/sh7710voipgw/Makefile b/arch/sh/boards/renesas/sh7710voipgw/Makefile
new file mode 100644
index 000000000000..77037567633b
--- /dev/null
+++ b/arch/sh/boards/renesas/sh7710voipgw/Makefile
@@ -0,0 +1 @@
obj-y := setup.o
diff --git a/arch/sh/boards/renesas/sh7710voipgw/setup.c b/arch/sh/boards/renesas/sh7710voipgw/setup.c
new file mode 100644
index 000000000000..e57e7afab8c6
--- /dev/null
+++ b/arch/sh/boards/renesas/sh7710voipgw/setup.c
@@ -0,0 +1,109 @@
1/*
2 * Renesas Technology SH7710 VoIP Gateway
3 *
4 * Copyright (C) 2006 Ranjit Deshpande
5 * Kenati Technologies Inc.
6 *
7 * May be copied or modified under the terms of the GNU General Public
8 * License. See linux/COPYING for more information.
9 */
10#include <linux/init.h>
11#include <asm/machvec.h>
12#include <asm/irq.h>
13#include <asm/io.h>
14#include <asm/irq.h>
15
16/*
17 * Initialize IRQ setting
18 */
19static void __init sh7710voipgw_init_irq(void)
20{
21 /* Disable all interrupts in IPR registers */
22 ctrl_outw(0x0, INTC_IPRA);
23 ctrl_outw(0x0, INTC_IPRB);
24 ctrl_outw(0x0, INTC_IPRC);
25 ctrl_outw(0x0, INTC_IPRD);
26 ctrl_outw(0x0, INTC_IPRE);
27 ctrl_outw(0x0, INTC_IPRF);
28 ctrl_outw(0x0, INTC_IPRG);
29 ctrl_outw(0x0, INTC_IPRH);
30 ctrl_outw(0x0, INTC_IPRI);
31
32 /* Ack all interrupt sources in the IRR0 register */
33 ctrl_outb(0x3f, INTC_IRR0);
34
35 /* Use IRQ0 - IRQ3 as active low interrupt lines i.e. disable
36 * IRL mode.
37 */
38 ctrl_outw(0x2aa, INTC_ICR1);
39
40 /* Now make IPR interrupts */
41 make_ipr_irq(TIMER2_IRQ, TIMER2_IPR_ADDR,
42 TIMER2_IPR_POS, TIMER2_PRIORITY);
43 make_ipr_irq(WDT_IRQ, WDT_IPR_ADDR, WDT_IPR_POS, WDT_PRIORITY);
44
45 /* SCIF0 */
46 make_ipr_irq(SCIF0_ERI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS,
47 SCIF0_PRIORITY);
48 make_ipr_irq(SCIF0_RXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS,
49 SCIF0_PRIORITY);
50 make_ipr_irq(SCIF0_BRI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS,
51 SCIF0_PRIORITY);
52 make_ipr_irq(SCIF0_TXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS,
53 SCIF0_PRIORITY);
54
55 /* DMAC-1 */
56 make_ipr_irq(DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
57 make_ipr_irq(DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
58 make_ipr_irq(DMTE2_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
59 make_ipr_irq(DMTE3_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
60
61 /* DMAC-2 */
62 make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
63 make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
64
65 /* IPSEC */
66 make_ipr_irq(IPSEC_IRQ, IPSEC_IPR_ADDR, IPSEC_IPR_POS, IPSEC_PRIORITY);
67
68 /* EDMAC */
69 make_ipr_irq(EDMAC0_IRQ, EDMAC0_IPR_ADDR, EDMAC0_IPR_POS,
70 EDMAC0_PRIORITY);
71 make_ipr_irq(EDMAC1_IRQ, EDMAC1_IPR_ADDR, EDMAC1_IPR_POS,
72 EDMAC1_PRIORITY);
73 make_ipr_irq(EDMAC2_IRQ, EDMAC2_IPR_ADDR, EDMAC2_IPR_POS,
74 EDMAC2_PRIORITY);
75
76 /* SIOF0 */
77 make_ipr_irq(SIOF0_ERI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS,
78 SIOF0_PRIORITY);
79 make_ipr_irq(SIOF0_TXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS,
80 SIOF0_PRIORITY);
81 make_ipr_irq(SIOF0_RXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS,
82 SIOF0_PRIORITY);
83 make_ipr_irq(SIOF0_CCI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS,
84 SIOF0_PRIORITY);
85
86 /* SIOF1 */
87 make_ipr_irq(SIOF1_ERI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS,
88 SIOF1_PRIORITY);
89 make_ipr_irq(SIOF1_TXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS,
90 SIOF1_PRIORITY);
91 make_ipr_irq(SIOF1_RXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS,
92 SIOF1_PRIORITY);
93 make_ipr_irq(SIOF1_CCI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS,
94 SIOF1_PRIORITY);
95
96 /* SLIC IRQ's */
97 make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY);
98 make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY);
99}
100
101/*
102 * The Machine Vector
103 */
104struct sh_machine_vector mv_sh7710voipgw __initmv = {
105 .mv_name = "SH7710 VoIP Gateway",
106 .mv_nr_irqs = 104,
107 .mv_init_irq = sh7710voipgw_init_irq,
108};
109ALIAS_MV(sh7710voipgw)
diff --git a/arch/sh/boards/renesas/systemh/io.c b/arch/sh/boards/renesas/systemh/io.c
index cf979011aa94..cde6e5d192c4 100644
--- a/arch/sh/boards/renesas/systemh/io.c
+++ b/arch/sh/boards/renesas/systemh/io.c
@@ -5,66 +5,25 @@
5 * Based largely on io_se.c. 5 * Based largely on io_se.c.
6 * 6 *
7 * I/O routine for Hitachi 7751 Systemh. 7 * I/O routine for Hitachi 7751 Systemh.
8 *
9 */ 8 */
10
11#include <linux/kernel.h> 9#include <linux/kernel.h>
12#include <linux/types.h> 10#include <linux/types.h>
13#include <asm/systemh/7751systemh.h> 11#include <linux/pci.h>
12#include <asm/systemh7751.h>
14#include <asm/addrspace.h> 13#include <asm/addrspace.h>
15#include <asm/io.h> 14#include <asm/io.h>
16 15
17#include <linux/pci.h>
18#include "../../drivers/pci/pci-sh7751.h"
19
20/*
21 * The 7751 SystemH Engine uses the built-in PCI controller (PCIC)
22 * of the 7751 processor, and has a SuperIO accessible on its memory
23 * bus.
24 */
25
26#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR)
27#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR)
28#define PCI_IO_AREA SH7751_PCI_IO_BASE
29#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE
30
31#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
32#define ETHER_IOMAP(adr) (0xB3000000 + (adr)) /*map to 16bits access area 16#define ETHER_IOMAP(adr) (0xB3000000 + (adr)) /*map to 16bits access area
33 of smc lan chip*/ 17 of smc lan chip*/
34
35#define maybebadio(name,port) \
36 printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
37 #name, (port), (__u32) __builtin_return_address(0))
38
39static inline void delay(void)
40{
41 ctrl_inw(0xa0000000);
42}
43
44static inline volatile __u16 * 18static inline volatile __u16 *
45port2adr(unsigned int port) 19port2adr(unsigned int port)
46{ 20{
47 if (port >= 0x2000) 21 if (port >= 0x2000)
48 return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); 22 return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
49#if 0 23 maybebadio((unsigned long)port);
50 else
51 return (volatile __u16 *) (PA_SUPERIO + (port << 1));
52#endif
53 maybebadio(name,(unsigned long)port);
54 return (volatile __u16*)port; 24 return (volatile __u16*)port;
55} 25}
56 26
57/* In case someone configures the kernel w/o PCI support: in that */
58/* scenario, don't ever bother to check for PCI-window addresses */
59
60/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
61#if defined(CONFIG_PCI)
62#define CHECK_SH7751_PCIIO(port) \
63 ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
64#else
65#define CHECK_SH7751_PCIIO(port) (0)
66#endif
67
68/* 27/*
69 * General outline: remap really low stuff [eventually] to SuperIO, 28 * General outline: remap really low stuff [eventually] to SuperIO,
70 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) 29 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
@@ -76,8 +35,8 @@ unsigned char sh7751systemh_inb(unsigned long port)
76{ 35{
77 if (PXSEG(port)) 36 if (PXSEG(port))
78 return *(volatile unsigned char *)port; 37 return *(volatile unsigned char *)port;
79 else if (CHECK_SH7751_PCIIO(port)) 38 else if (is_pci_ioaddr(port))
80 return *(volatile unsigned char *)PCI_IOMAP(port); 39 return *(volatile unsigned char *)pci_ioaddr(port);
81 else if (port <= 0x3F1) 40 else if (port <= 0x3F1)
82 return *(volatile unsigned char *)ETHER_IOMAP(port); 41 return *(volatile unsigned char *)ETHER_IOMAP(port);
83 else 42 else
@@ -90,13 +49,13 @@ unsigned char sh7751systemh_inb_p(unsigned long port)
90 49
91 if (PXSEG(port)) 50 if (PXSEG(port))
92 v = *(volatile unsigned char *)port; 51 v = *(volatile unsigned char *)port;
93 else if (CHECK_SH7751_PCIIO(port)) 52 else if (is_pci_ioaddr(port))
94 v = *(volatile unsigned char *)PCI_IOMAP(port); 53 v = *(volatile unsigned char *)pci_ioaddr(port);
95 else if (port <= 0x3F1) 54 else if (port <= 0x3F1)
96 v = *(volatile unsigned char *)ETHER_IOMAP(port); 55 v = *(volatile unsigned char *)ETHER_IOMAP(port);
97 else 56 else
98 v = (*port2adr(port))&0xff; 57 v = (*port2adr(port))&0xff;
99 delay(); 58 ctrl_delay();
100 return v; 59 return v;
101} 60}
102 61
@@ -104,14 +63,14 @@ unsigned short sh7751systemh_inw(unsigned long port)
104{ 63{
105 if (PXSEG(port)) 64 if (PXSEG(port))
106 return *(volatile unsigned short *)port; 65 return *(volatile unsigned short *)port;
107 else if (CHECK_SH7751_PCIIO(port)) 66 else if (is_pci_ioaddr(port))
108 return *(volatile unsigned short *)PCI_IOMAP(port); 67 return *(volatile unsigned short *)pci_ioaddr(port);
109 else if (port >= 0x2000) 68 else if (port >= 0x2000)
110 return *port2adr(port); 69 return *port2adr(port);
111 else if (port <= 0x3F1) 70 else if (port <= 0x3F1)
112 return *(volatile unsigned int *)ETHER_IOMAP(port); 71 return *(volatile unsigned int *)ETHER_IOMAP(port);
113 else 72 else
114 maybebadio(inw, port); 73 maybebadio(port);
115 return 0; 74 return 0;
116} 75}
117 76
@@ -119,14 +78,14 @@ unsigned int sh7751systemh_inl(unsigned long port)
119{ 78{
120 if (PXSEG(port)) 79 if (PXSEG(port))
121 return *(volatile unsigned long *)port; 80 return *(volatile unsigned long *)port;
122 else if (CHECK_SH7751_PCIIO(port)) 81 else if (is_pci_ioaddr(port))
123 return *(volatile unsigned int *)PCI_IOMAP(port); 82 return *(volatile unsigned int *)pci_ioaddr(port);
124 else if (port >= 0x2000) 83 else if (port >= 0x2000)
125 return *port2adr(port); 84 return *port2adr(port);
126 else if (port <= 0x3F1) 85 else if (port <= 0x3F1)
127 return *(volatile unsigned int *)ETHER_IOMAP(port); 86 return *(volatile unsigned int *)ETHER_IOMAP(port);
128 else 87 else
129 maybebadio(inl, port); 88 maybebadio(port);
130 return 0; 89 return 0;
131} 90}
132 91
@@ -135,8 +94,8 @@ void sh7751systemh_outb(unsigned char value, unsigned long port)
135 94
136 if (PXSEG(port)) 95 if (PXSEG(port))
137 *(volatile unsigned char *)port = value; 96 *(volatile unsigned char *)port = value;
138 else if (CHECK_SH7751_PCIIO(port)) 97 else if (is_pci_ioaddr(port))
139 *((unsigned char*)PCI_IOMAP(port)) = value; 98 *((unsigned char*)pci_ioaddr(port)) = value;
140 else if (port <= 0x3F1) 99 else if (port <= 0x3F1)
141 *(volatile unsigned char *)ETHER_IOMAP(port) = value; 100 *(volatile unsigned char *)ETHER_IOMAP(port) = value;
142 else 101 else
@@ -147,37 +106,37 @@ void sh7751systemh_outb_p(unsigned char value, unsigned long port)
147{ 106{
148 if (PXSEG(port)) 107 if (PXSEG(port))
149 *(volatile unsigned char *)port = value; 108 *(volatile unsigned char *)port = value;
150 else if (CHECK_SH7751_PCIIO(port)) 109 else if (is_pci_ioaddr(port))
151 *((unsigned char*)PCI_IOMAP(port)) = value; 110 *((unsigned char*)pci_ioaddr(port)) = value;
152 else if (port <= 0x3F1) 111 else if (port <= 0x3F1)
153 *(volatile unsigned char *)ETHER_IOMAP(port) = value; 112 *(volatile unsigned char *)ETHER_IOMAP(port) = value;
154 else 113 else
155 *(port2adr(port)) = value; 114 *(port2adr(port)) = value;
156 delay(); 115 ctrl_delay();
157} 116}
158 117
159void sh7751systemh_outw(unsigned short value, unsigned long port) 118void sh7751systemh_outw(unsigned short value, unsigned long port)
160{ 119{
161 if (PXSEG(port)) 120 if (PXSEG(port))
162 *(volatile unsigned short *)port = value; 121 *(volatile unsigned short *)port = value;
163 else if (CHECK_SH7751_PCIIO(port)) 122 else if (is_pci_ioaddr(port))
164 *((unsigned short *)PCI_IOMAP(port)) = value; 123 *((unsigned short *)pci_ioaddr(port)) = value;
165 else if (port >= 0x2000) 124 else if (port >= 0x2000)
166 *port2adr(port) = value; 125 *port2adr(port) = value;
167 else if (port <= 0x3F1) 126 else if (port <= 0x3F1)
168 *(volatile unsigned short *)ETHER_IOMAP(port) = value; 127 *(volatile unsigned short *)ETHER_IOMAP(port) = value;
169 else 128 else
170 maybebadio(outw, port); 129 maybebadio(port);
171} 130}
172 131
173void sh7751systemh_outl(unsigned int value, unsigned long port) 132void sh7751systemh_outl(unsigned int value, unsigned long port)
174{ 133{
175 if (PXSEG(port)) 134 if (PXSEG(port))
176 *(volatile unsigned long *)port = value; 135 *(volatile unsigned long *)port = value;
177 else if (CHECK_SH7751_PCIIO(port)) 136 else if (is_pci_ioaddr(port))
178 *((unsigned long*)PCI_IOMAP(port)) = value; 137 *((unsigned long*)pci_ioaddr(port)) = value;
179 else 138 else
180 maybebadio(outl, port); 139 maybebadio(port);
181} 140}
182 141
183void sh7751systemh_insb(unsigned long port, void *addr, unsigned long count) 142void sh7751systemh_insb(unsigned long port, void *addr, unsigned long count)
@@ -194,7 +153,7 @@ void sh7751systemh_insw(unsigned long port, void *addr, unsigned long count)
194 153
195void sh7751systemh_insl(unsigned long port, void *addr, unsigned long count) 154void sh7751systemh_insl(unsigned long port, void *addr, unsigned long count)
196{ 155{
197 maybebadio(insl, port); 156 maybebadio(port);
198} 157}
199 158
200void sh7751systemh_outsb(unsigned long port, const void *addr, unsigned long count) 159void sh7751systemh_outsb(unsigned long port, const void *addr, unsigned long count)
@@ -211,73 +170,5 @@ void sh7751systemh_outsw(unsigned long port, const void *addr, unsigned long cou
211 170
212void sh7751systemh_outsl(unsigned long port, const void *addr, unsigned long count) 171void sh7751systemh_outsl(unsigned long port, const void *addr, unsigned long count)
213{ 172{
214 maybebadio(outsw, port); 173 maybebadio(port);
215}
216
217/* For read/write calls, just copy generic (pass-thru); PCIMBR is */
218/* already set up. For a larger memory space, these would need to */
219/* reset PCIMBR as needed on a per-call basis... */
220
221unsigned char sh7751systemh_readb(unsigned long addr)
222{
223 return *(volatile unsigned char*)addr;
224}
225
226unsigned short sh7751systemh_readw(unsigned long addr)
227{
228 return *(volatile unsigned short*)addr;
229}
230
231unsigned int sh7751systemh_readl(unsigned long addr)
232{
233 return *(volatile unsigned long*)addr;
234}
235
236void sh7751systemh_writeb(unsigned char b, unsigned long addr)
237{
238 *(volatile unsigned char*)addr = b;
239}
240
241void sh7751systemh_writew(unsigned short b, unsigned long addr)
242{
243 *(volatile unsigned short*)addr = b;
244}
245
246void sh7751systemh_writel(unsigned int b, unsigned long addr)
247{
248 *(volatile unsigned long*)addr = b;
249}
250
251
252
253/* Map ISA bus address to the real address. Only for PCMCIA. */
254
255/* ISA page descriptor. */
256static __u32 sh_isa_memmap[256];
257
258#if 0
259static int
260sh_isa_mmap(__u32 start, __u32 length, __u32 offset)
261{
262 int idx;
263
264 if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000))
265 return -1;
266
267 idx = start >> 12;
268 sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff);
269 printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n",
270 start, length, offset, idx, sh_isa_memmap[idx]);
271 return 0;
272}
273#endif
274
275unsigned long
276sh7751systemh_isa_port2addr(unsigned long offset)
277{
278 int idx;
279
280 idx = (offset >> 12) & 0xff;
281 offset &= 0xfff;
282 return sh_isa_memmap[idx] + offset;
283} 174}
diff --git a/arch/sh/boards/renesas/systemh/irq.c b/arch/sh/boards/renesas/systemh/irq.c
index 8372d967f601..8d016dae2333 100644
--- a/arch/sh/boards/renesas/systemh/irq.c
+++ b/arch/sh/boards/renesas/systemh/irq.c
@@ -15,7 +15,7 @@
15#include <linux/hdreg.h> 15#include <linux/hdreg.h>
16#include <linux/ide.h> 16#include <linux/ide.h>
17#include <asm/io.h> 17#include <asm/io.h>
18#include <asm/mach/7751systemh.h> 18#include <asm/systemh7751.h>
19#include <asm/smc37c93x.h> 19#include <asm/smc37c93x.h>
20 20
21/* address of external interrupt mask register 21/* address of external interrupt mask register
@@ -57,12 +57,9 @@ static void shutdown_systemh_irq(unsigned int irq)
57static void disable_systemh_irq(unsigned int irq) 57static void disable_systemh_irq(unsigned int irq)
58{ 58{
59 if (systemh_irq_mask_register) { 59 if (systemh_irq_mask_register) {
60 unsigned long flags;
61 unsigned long val, mask = 0x01 << 1; 60 unsigned long val, mask = 0x01 << 1;
62 61
63 /* Clear the "irq"th bit in the mask and set it in the request */ 62 /* Clear the "irq"th bit in the mask and set it in the request */
64 local_irq_save(flags);
65
66 val = ctrl_inl((unsigned long)systemh_irq_mask_register); 63 val = ctrl_inl((unsigned long)systemh_irq_mask_register);
67 val &= ~mask; 64 val &= ~mask;
68 ctrl_outl(val, (unsigned long)systemh_irq_mask_register); 65 ctrl_outl(val, (unsigned long)systemh_irq_mask_register);
@@ -70,23 +67,18 @@ static void disable_systemh_irq(unsigned int irq)
70 val = ctrl_inl((unsigned long)systemh_irq_request_register); 67 val = ctrl_inl((unsigned long)systemh_irq_request_register);
71 val |= mask; 68 val |= mask;
72 ctrl_outl(val, (unsigned long)systemh_irq_request_register); 69 ctrl_outl(val, (unsigned long)systemh_irq_request_register);
73
74 local_irq_restore(flags);
75 } 70 }
76} 71}
77 72
78static void enable_systemh_irq(unsigned int irq) 73static void enable_systemh_irq(unsigned int irq)
79{ 74{
80 if (systemh_irq_mask_register) { 75 if (systemh_irq_mask_register) {
81 unsigned long flags;
82 unsigned long val, mask = 0x01 << 1; 76 unsigned long val, mask = 0x01 << 1;
83 77
84 /* Set "irq"th bit in the mask register */ 78 /* Set "irq"th bit in the mask register */
85 local_irq_save(flags);
86 val = ctrl_inl((unsigned long)systemh_irq_mask_register); 79 val = ctrl_inl((unsigned long)systemh_irq_mask_register);
87 val |= mask; 80 val |= mask;
88 ctrl_outl(val, (unsigned long)systemh_irq_mask_register); 81 ctrl_outl(val, (unsigned long)systemh_irq_mask_register);
89 local_irq_restore(flags);
90 } 82 }
91} 83}
92 84
diff --git a/arch/sh/boards/renesas/systemh/setup.c b/arch/sh/boards/renesas/systemh/setup.c
index 826fa3d7669c..a8467bf90c25 100644
--- a/arch/sh/boards/renesas/systemh/setup.c
+++ b/arch/sh/boards/renesas/systemh/setup.c
@@ -15,28 +15,21 @@
15 * for more details. 15 * for more details.
16 */ 16 */
17#include <linux/init.h> 17#include <linux/init.h>
18#include <asm/mach/7751systemh.h>
19#include <asm/mach/io.h>
20#include <asm/machvec.h> 18#include <asm/machvec.h>
19#include <asm/systemh7751.h>
21 20
22extern void make_systemh_irq(unsigned int irq); 21extern void make_systemh_irq(unsigned int irq);
23 22
24const char *get_system_type(void)
25{
26 return "7751 SystemH";
27}
28
29/* 23/*
30 * Initialize IRQ setting 24 * Initialize IRQ setting
31 */ 25 */
32void __init init_7751systemh_IRQ(void) 26static void __init sh7751systemh_init_irq(void)
33{ 27{
34/* make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); LAN */
35/* make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-4); */
36 make_systemh_irq(0xb); /* Ethernet interrupt */ 28 make_systemh_irq(0xb); /* Ethernet interrupt */
37} 29}
38 30
39struct sh_machine_vector mv_7751systemh __initmv = { 31struct sh_machine_vector mv_7751systemh __initmv = {
32 .mv_name = "7751 SystemH",
40 .mv_nr_irqs = 72, 33 .mv_nr_irqs = 72,
41 34
42 .mv_inb = sh7751systemh_inb, 35 .mv_inb = sh7751systemh_inb,
@@ -60,21 +53,6 @@ struct sh_machine_vector mv_7751systemh __initmv = {
60 .mv_outsw = sh7751systemh_outsw, 53 .mv_outsw = sh7751systemh_outsw,
61 .mv_outsl = sh7751systemh_outsl, 54 .mv_outsl = sh7751systemh_outsl,
62 55
63 .mv_readb = sh7751systemh_readb, 56 .mv_init_irq = sh7751system_init_irq,
64 .mv_readw = sh7751systemh_readw,
65 .mv_readl = sh7751systemh_readl,
66 .mv_writeb = sh7751systemh_writeb,
67 .mv_writew = sh7751systemh_writew,
68 .mv_writel = sh7751systemh_writel,
69
70 .mv_isa_port2addr = sh7751systemh_isa_port2addr,
71
72 .mv_init_irq = init_7751systemh_IRQ,
73}; 57};
74ALIAS_MV(7751systemh) 58ALIAS_MV(7751systemh)
75
76int __init platform_setup(void)
77{
78 return 0;
79}
80
diff --git a/arch/sh/boards/saturn/setup.c b/arch/sh/boards/saturn/setup.c
index bea6c572ad82..a3a37c9aad2e 100644
--- a/arch/sh/boards/saturn/setup.c
+++ b/arch/sh/boards/saturn/setup.c
@@ -9,22 +9,17 @@
9 */ 9 */
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/init.h> 11#include <linux/init.h>
12
13#include <asm/io.h> 12#include <asm/io.h>
14#include <asm/machvec.h> 13#include <asm/machvec.h>
15#include <asm/mach/io.h> 14#include <asm/mach/io.h>
16 15
17extern int saturn_irq_demux(int irq_nr); 16extern int saturn_irq_demux(int irq_nr);
18 17
19const char *get_system_type(void)
20{
21 return "Sega Saturn";
22}
23
24/* 18/*
25 * The Machine Vector 19 * The Machine Vector
26 */ 20 */
27struct sh_machine_vector mv_saturn __initmv = { 21struct sh_machine_vector mv_saturn __initmv = {
22 .mv_name = "Sega Saturn",
28 .mv_nr_irqs = 80, /* Fix this later */ 23 .mv_nr_irqs = 80, /* Fix this later */
29 24
30 .mv_isa_port2addr = saturn_isa_port2addr, 25 .mv_isa_port2addr = saturn_isa_port2addr,
@@ -33,11 +28,4 @@ struct sh_machine_vector mv_saturn __initmv = {
33 .mv_ioremap = saturn_ioremap, 28 .mv_ioremap = saturn_ioremap,
34 .mv_iounmap = saturn_iounmap, 29 .mv_iounmap = saturn_iounmap,
35}; 30};
36
37ALIAS_MV(saturn) 31ALIAS_MV(saturn)
38
39int __init platform_setup(void)
40{
41 return 0;
42}
43
diff --git a/arch/sh/boards/se/7300/io.c b/arch/sh/boards/se/7300/io.c
index f449a94ddffd..8a03d7a52a7c 100644
--- a/arch/sh/boards/se/7300/io.c
+++ b/arch/sh/boards/se/7300/io.c
@@ -9,8 +9,8 @@
9 */ 9 */
10 10
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <asm/mach/se7300.h>
13#include <asm/io.h> 12#include <asm/io.h>
13#include <asm/se7300.h>
14 14
15#define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a) 15#define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a)
16 16
@@ -99,6 +99,7 @@ bad_outb(struct iop *p, unsigned char value, unsigned long port)
99 badio(inw, port); 99 badio(inw, port);
100} 100}
101 101
102#ifdef CONFIG_SMC91X
102/* MSTLANEX01 LAN at 0xb400:0000 */ 103/* MSTLANEX01 LAN at 0xb400:0000 */
103static struct iop laniop = { 104static struct iop laniop = {
104 .start = 0x300, 105 .start = 0x300,
@@ -110,6 +111,7 @@ static struct iop laniop = {
110 .outb = simple_outb, 111 .outb = simple_outb,
111 .outw = simple_outw, 112 .outw = simple_outw,
112}; 113};
114#endif
113 115
114/* NE2000 pc card NIC */ 116/* NE2000 pc card NIC */
115static struct iop neiop = { 117static struct iop neiop = {
@@ -123,6 +125,7 @@ static struct iop neiop = {
123 .outw = simple_outw, 125 .outw = simple_outw,
124}; 126};
125 127
128#ifdef CONFIG_IDE
126/* CF in CF slot */ 129/* CF in CF slot */
127static struct iop cfiop = { 130static struct iop cfiop = {
128 .base = 0xb0600000, 131 .base = 0xb0600000,
@@ -132,12 +135,13 @@ static struct iop cfiop = {
132 .outb = pcc_outb, 135 .outb = pcc_outb,
133 .outw = simple_outw, 136 .outw = simple_outw,
134}; 137};
138#endif
135 139
136static __inline__ struct iop * 140static __inline__ struct iop *
137port2iop(unsigned long port) 141port2iop(unsigned long port)
138{ 142{
139 if (0) ; 143 if (0) ;
140#if defined(CONFIG_SMC91111) 144#if defined(CONFIG_SMC91X)
141 else if (laniop.check(&laniop, port)) 145 else if (laniop.check(&laniop, port))
142 return &laniop; 146 return &laniop;
143#endif 147#endif
diff --git a/arch/sh/boards/se/7300/irq.c b/arch/sh/boards/se/7300/irq.c
index 216a78d1a108..ad1034f98a29 100644
--- a/arch/sh/boards/se/7300/irq.c
+++ b/arch/sh/boards/se/7300/irq.c
@@ -11,7 +11,7 @@
11#include <linux/irq.h> 11#include <linux/irq.h>
12#include <asm/irq.h> 12#include <asm/irq.h>
13#include <asm/io.h> 13#include <asm/io.h>
14#include <asm/mach/se7300.h> 14#include <asm/se7300.h>
15 15
16/* 16/*
17 * Initialize IRQ setting 17 * Initialize IRQ setting
diff --git a/arch/sh/boards/se/7300/led.c b/arch/sh/boards/se/7300/led.c
index ad51f0a9c1e3..4d03bb7774be 100644
--- a/arch/sh/boards/se/7300/led.c
+++ b/arch/sh/boards/se/7300/led.c
@@ -12,24 +12,10 @@
12 */ 12 */
13 13
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <asm/mach/se7300.h> 15#include <asm/se7300.h>
16
17static void
18mach_led(int position, int value)
19{
20 volatile unsigned short *p = (volatile unsigned short *) PA_LED;
21
22 if (value) {
23 *p |= (1 << 8);
24 } else {
25 *p &= ~(1 << 8);
26 }
27}
28
29 16
30/* Cycle the LED's in the clasic Knightrider/Sun pattern */ 17/* Cycle the LED's in the clasic Knightrider/Sun pattern */
31void 18void heartbeat_7300se(void)
32heartbeat_7300se(void)
33{ 19{
34 static unsigned int cnt = 0, period = 0; 20 static unsigned int cnt = 0, period = 0;
35 volatile unsigned short *p = (volatile unsigned short *) PA_LED; 21 volatile unsigned short *p = (volatile unsigned short *) PA_LED;
diff --git a/arch/sh/boards/se/7300/setup.c b/arch/sh/boards/se/7300/setup.c
index ebcd98d4c081..6f082a722d42 100644
--- a/arch/sh/boards/se/7300/setup.c
+++ b/arch/sh/boards/se/7300/setup.c
@@ -9,23 +9,16 @@
9 9
10#include <linux/init.h> 10#include <linux/init.h>
11#include <asm/machvec.h> 11#include <asm/machvec.h>
12#include <asm/machvec_init.h> 12#include <asm/se7300.h>
13#include <asm/mach/io.h>
14 13
15void heartbeat_7300se(void); 14void heartbeat_7300se(void);
16void init_7300se_IRQ(void); 15void init_7300se_IRQ(void);
17 16
18const char *
19get_system_type(void)
20{
21 return "SolutionEngine 7300";
22}
23
24/* 17/*
25 * The Machine Vector 18 * The Machine Vector
26 */ 19 */
27
28struct sh_machine_vector mv_7300se __initmv = { 20struct sh_machine_vector mv_7300se __initmv = {
21 .mv_name = "SolutionEngine 7300",
29 .mv_nr_irqs = 109, 22 .mv_nr_irqs = 109,
30 .mv_inb = sh7300se_inb, 23 .mv_inb = sh7300se_inb,
31 .mv_inw = sh7300se_inw, 24 .mv_inw = sh7300se_inw,
@@ -53,13 +46,4 @@ struct sh_machine_vector mv_7300se __initmv = {
53 .mv_heartbeat = heartbeat_7300se, 46 .mv_heartbeat = heartbeat_7300se,
54#endif 47#endif
55}; 48};
56
57ALIAS_MV(7300se) 49ALIAS_MV(7300se)
58/*
59 * Initialize the board
60 */
61void __init
62platform_setup(void)
63{
64
65}
diff --git a/arch/sh/boards/se/73180/io.c b/arch/sh/boards/se/73180/io.c
index 755df5ac4a4e..72715575458b 100644
--- a/arch/sh/boards/se/73180/io.c
+++ b/arch/sh/boards/se/73180/io.c
@@ -99,6 +99,7 @@ bad_outb(struct iop *p, unsigned char value, unsigned long port)
99 badio(inw, port); 99 badio(inw, port);
100} 100}
101 101
102#ifdef CONFIG_SMC91X
102/* MSTLANEX01 LAN at 0xb400:0000 */ 103/* MSTLANEX01 LAN at 0xb400:0000 */
103static struct iop laniop = { 104static struct iop laniop = {
104 .start = 0x300, 105 .start = 0x300,
@@ -110,6 +111,7 @@ static struct iop laniop = {
110 .outb = simple_outb, 111 .outb = simple_outb,
111 .outw = simple_outw, 112 .outw = simple_outw,
112}; 113};
114#endif
113 115
114/* NE2000 pc card NIC */ 116/* NE2000 pc card NIC */
115static struct iop neiop = { 117static struct iop neiop = {
@@ -123,6 +125,7 @@ static struct iop neiop = {
123 .outw = simple_outw, 125 .outw = simple_outw,
124}; 126};
125 127
128#ifdef CONFIG_IDE
126/* CF in CF slot */ 129/* CF in CF slot */
127static struct iop cfiop = { 130static struct iop cfiop = {
128 .base = 0xb0600000, 131 .base = 0xb0600000,
@@ -132,12 +135,13 @@ static struct iop cfiop = {
132 .outb = pcc_outb, 135 .outb = pcc_outb,
133 .outw = simple_outw, 136 .outw = simple_outw,
134}; 137};
138#endif
135 139
136static __inline__ struct iop * 140static __inline__ struct iop *
137port2iop(unsigned long port) 141port2iop(unsigned long port)
138{ 142{
139 if (0) ; 143 if (0) ;
140#if defined(CONFIG_SMC91111) 144#if defined(CONFIG_SMC91X)
141 else if (laniop.check(&laniop, port)) 145 else if (laniop.check(&laniop, port))
142 return &laniop; 146 return &laniop;
143#endif 147#endif
diff --git a/arch/sh/boards/se/73180/irq.c b/arch/sh/boards/se/73180/irq.c
index 4344d0ef24aa..2c62b8ea350e 100644
--- a/arch/sh/boards/se/73180/irq.c
+++ b/arch/sh/boards/se/73180/irq.c
@@ -7,7 +7,6 @@
7 * Modified for SH-Mobile SolutionEngine 73180 Support 7 * Modified for SH-Mobile SolutionEngine 73180 Support
8 * by YOSHII Takashi <yoshii-takashi@hitachi-ul.co.jp> 8 * by YOSHII Takashi <yoshii-takashi@hitachi-ul.co.jp>
9 * 9 *
10 *
11 */ 10 */
12 11
13#include <linux/init.h> 12#include <linux/init.h>
@@ -17,14 +16,6 @@
17#include <asm/mach/se73180.h> 16#include <asm/mach/se73180.h>
18 17
19static int 18static int
20intreq2irq(int i)
21{
22 if (i == 5)
23 return 10;
24 return 32 + 7 - i;
25}
26
27static int
28irq2intreq(int irq) 19irq2intreq(int irq)
29{ 20{
30 if (irq == 10) 21 if (irq == 10)
diff --git a/arch/sh/boards/se/73180/led.c b/arch/sh/boards/se/73180/led.c
index 610439fde6ee..4b72e9a3ead9 100644
--- a/arch/sh/boards/se/73180/led.c
+++ b/arch/sh/boards/se/73180/led.c
@@ -14,21 +14,8 @@
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <asm/mach/se73180.h> 15#include <asm/mach/se73180.h>
16 16
17static void
18mach_led(int position, int value)
19{
20 volatile unsigned short *p = (volatile unsigned short *) PA_LED;
21
22 if (value) {
23 *p |= (1 << LED_SHIFT);
24 } else {
25 *p &= ~(1 << LED_SHIFT);
26 }
27}
28
29/* Cycle the LED's in the clasic Knightrider/Sun pattern */ 17/* Cycle the LED's in the clasic Knightrider/Sun pattern */
30void 18void heartbeat_73180se(void)
31heartbeat_73180se(void)
32{ 19{
33 static unsigned int cnt = 0, period = 0; 20 static unsigned int cnt = 0, period = 0;
34 volatile unsigned short *p = (volatile unsigned short *) PA_LED; 21 volatile unsigned short *p = (volatile unsigned short *) PA_LED;
diff --git a/arch/sh/boards/se/73180/setup.c b/arch/sh/boards/se/73180/setup.c
index cdb7b5f8d942..b38ef50a160a 100644
--- a/arch/sh/boards/se/73180/setup.c
+++ b/arch/sh/boards/se/73180/setup.c
@@ -11,23 +11,17 @@
11 11
12#include <linux/init.h> 12#include <linux/init.h>
13#include <asm/machvec.h> 13#include <asm/machvec.h>
14#include <asm/machvec_init.h> 14#include <asm/se73180.h>
15#include <asm/mach/io.h> 15#include <asm/irq.h>
16 16
17void heartbeat_73180se(void); 17void heartbeat_73180se(void);
18void init_73180se_IRQ(void); 18void init_73180se_IRQ(void);
19 19
20const char *
21get_system_type(void)
22{
23 return "SolutionEngine 73180";
24}
25
26/* 20/*
27 * The Machine Vector 21 * The Machine Vector
28 */ 22 */
29
30struct sh_machine_vector mv_73180se __initmv = { 23struct sh_machine_vector mv_73180se __initmv = {
24 .mv_name = "SolutionEngine 73180",
31 .mv_nr_irqs = 108, 25 .mv_nr_irqs = 108,
32 .mv_inb = sh73180se_inb, 26 .mv_inb = sh73180se_inb,
33 .mv_inw = sh73180se_inw, 27 .mv_inw = sh73180se_inw,
@@ -51,17 +45,9 @@ struct sh_machine_vector mv_73180se __initmv = {
51 .mv_outsl = sh73180se_outsl, 45 .mv_outsl = sh73180se_outsl,
52 46
53 .mv_init_irq = init_73180se_IRQ, 47 .mv_init_irq = init_73180se_IRQ,
48 .mv_irq_demux = shmse_irq_demux,
54#ifdef CONFIG_HEARTBEAT 49#ifdef CONFIG_HEARTBEAT
55 .mv_heartbeat = heartbeat_73180se, 50 .mv_heartbeat = heartbeat_73180se,
56#endif 51#endif
57}; 52};
58
59ALIAS_MV(73180se) 53ALIAS_MV(73180se)
60/*
61 * Initialize the board
62 */
63void __init
64platform_setup(void)
65{
66
67}
diff --git a/arch/sh/boards/se/7343/Makefile b/arch/sh/boards/se/7343/Makefile
new file mode 100644
index 000000000000..4291069c0b4f
--- /dev/null
+++ b/arch/sh/boards/se/7343/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the 7343 SolutionEngine specific parts of the kernel
3#
4
5obj-y := setup.o io.o irq.o
6
7obj-$(CONFIG_HEARTBEAT) += led.o
diff --git a/arch/sh/boards/se/7343/io.c b/arch/sh/boards/se/7343/io.c
new file mode 100644
index 000000000000..646661a146ad
--- /dev/null
+++ b/arch/sh/boards/se/7343/io.c
@@ -0,0 +1,275 @@
1/*
2 * arch/sh/boards/se/7343/io.c
3 *
4 * I/O routine for SH-Mobile3AS 7343 SolutionEngine.
5 *
6 */
7
8#include <linux/config.h>
9#include <linux/kernel.h>
10#include <asm/io.h>
11#include <asm/mach/se7343.h>
12
13#define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a)
14
15struct iop {
16 unsigned long start, end;
17 unsigned long base;
18 struct iop *(*check) (struct iop * p, unsigned long port);
19 unsigned char (*inb) (struct iop * p, unsigned long port);
20 unsigned short (*inw) (struct iop * p, unsigned long port);
21 void (*outb) (struct iop * p, unsigned char value, unsigned long port);
22 void (*outw) (struct iop * p, unsigned short value, unsigned long port);
23};
24
25struct iop *
26simple_check(struct iop *p, unsigned long port)
27{
28 static int count;
29
30 if (count < 100)
31 count++;
32
33 port &= 0xFFFF;
34
35 if ((p->start <= port) && (port <= p->end))
36 return p;
37 else
38 badio(check, port);
39}
40
41struct iop *
42ide_check(struct iop *p, unsigned long port)
43{
44 if (((0x1f0 <= port) && (port <= 0x1f7)) || (port == 0x3f7))
45 return p;
46 return NULL;
47}
48
49unsigned char
50simple_inb(struct iop *p, unsigned long port)
51{
52 return *(unsigned char *) (p->base + port);
53}
54
55unsigned short
56simple_inw(struct iop *p, unsigned long port)
57{
58 return *(unsigned short *) (p->base + port);
59}
60
61void
62simple_outb(struct iop *p, unsigned char value, unsigned long port)
63{
64 *(unsigned char *) (p->base + port) = value;
65}
66
67void
68simple_outw(struct iop *p, unsigned short value, unsigned long port)
69{
70 *(unsigned short *) (p->base + port) = value;
71}
72
73unsigned char
74pcc_inb(struct iop *p, unsigned long port)
75{
76 unsigned long addr = p->base + port + 0x40000;
77 unsigned long v;
78
79 if (port & 1)
80 addr += 0x00400000;
81 v = *(volatile unsigned char *) addr;
82 return v;
83}
84
85void
86pcc_outb(struct iop *p, unsigned char value, unsigned long port)
87{
88 unsigned long addr = p->base + port + 0x40000;
89
90 if (port & 1)
91 addr += 0x00400000;
92 *(volatile unsigned char *) addr = value;
93}
94
95unsigned char
96bad_inb(struct iop *p, unsigned long port)
97{
98 badio(inb, port);
99}
100
101void
102bad_outb(struct iop *p, unsigned char value, unsigned long port)
103{
104 badio(inw, port);
105}
106
107#ifdef CONFIG_SMC91X
108/* MSTLANEX01 LAN at 0xb400:0000 */
109static struct iop laniop = {
110 .start = 0x00,
111 .end = 0x0F,
112 .base = 0x04000000,
113 .check = simple_check,
114 .inb = simple_inb,
115 .inw = simple_inw,
116 .outb = simple_outb,
117 .outw = simple_outw,
118};
119#endif
120
121#ifdef CONFIG_NE2000
122/* NE2000 pc card NIC */
123static struct iop neiop = {
124 .start = 0x280,
125 .end = 0x29f,
126 .base = 0xb0600000 + 0x80, /* soft 0x280 -> hard 0x300 */
127 .check = simple_check,
128 .inb = pcc_inb,
129 .inw = simple_inw,
130 .outb = pcc_outb,
131 .outw = simple_outw,
132};
133#endif
134
135#ifdef CONFIG_IDE
136/* CF in CF slot */
137static struct iop cfiop = {
138 .base = 0xb0600000,
139 .check = ide_check,
140 .inb = pcc_inb,
141 .inw = simple_inw,
142 .outb = pcc_outb,
143 .outw = simple_outw,
144};
145#endif
146
147static __inline__ struct iop *
148port2iop(unsigned long port)
149{
150 if (0) ;
151#if defined(CONFIG_SMC91X)
152 else if (laniop.check(&laniop, port))
153 return &laniop;
154#endif
155#if defined(CONFIG_NE2000)
156 else if (neiop.check(&neiop, port))
157 return &neiop;
158#endif
159#if defined(CONFIG_IDE)
160 else if (cfiop.check(&cfiop, port))
161 return &cfiop;
162#endif
163 else
164 return NULL;
165}
166
167static inline void
168delay(void)
169{
170 ctrl_inw(0xac000000);
171 ctrl_inw(0xac000000);
172}
173
174unsigned char
175sh7343se_inb(unsigned long port)
176{
177 struct iop *p = port2iop(port);
178 return (p->inb) (p, port);
179}
180
181unsigned char
182sh7343se_inb_p(unsigned long port)
183{
184 unsigned char v = sh7343se_inb(port);
185 delay();
186 return v;
187}
188
189unsigned short
190sh7343se_inw(unsigned long port)
191{
192 struct iop *p = port2iop(port);
193 return (p->inw) (p, port);
194}
195
196unsigned int
197sh7343se_inl(unsigned long port)
198{
199 badio(inl, port);
200}
201
202void
203sh7343se_outb(unsigned char value, unsigned long port)
204{
205 struct iop *p = port2iop(port);
206 (p->outb) (p, value, port);
207}
208
209void
210sh7343se_outb_p(unsigned char value, unsigned long port)
211{
212 sh7343se_outb(value, port);
213 delay();
214}
215
216void
217sh7343se_outw(unsigned short value, unsigned long port)
218{
219 struct iop *p = port2iop(port);
220 (p->outw) (p, value, port);
221}
222
223void
224sh7343se_outl(unsigned int value, unsigned long port)
225{
226 badio(outl, port);
227}
228
229void
230sh7343se_insb(unsigned long port, void *addr, unsigned long count)
231{
232 unsigned char *a = addr;
233 struct iop *p = port2iop(port);
234 while (count--)
235 *a++ = (p->inb) (p, port);
236}
237
238void
239sh7343se_insw(unsigned long port, void *addr, unsigned long count)
240{
241 unsigned short *a = addr;
242 struct iop *p = port2iop(port);
243 while (count--)
244 *a++ = (p->inw) (p, port);
245}
246
247void
248sh7343se_insl(unsigned long port, void *addr, unsigned long count)
249{
250 badio(insl, port);
251}
252
253void
254sh7343se_outsb(unsigned long port, const void *addr, unsigned long count)
255{
256 unsigned char *a = (unsigned char *) addr;
257 struct iop *p = port2iop(port);
258 while (count--)
259 (p->outb) (p, *a++, port);
260}
261
262void
263sh7343se_outsw(unsigned long port, const void *addr, unsigned long count)
264{
265 unsigned short *a = (unsigned short *) addr;
266 struct iop *p = port2iop(port);
267 while (count--)
268 (p->outw) (p, *a++, port);
269}
270
271void
272sh7343se_outsl(unsigned long port, const void *addr, unsigned long count)
273{
274 badio(outsw, port);
275}
diff --git a/arch/sh/boards/se/7343/irq.c b/arch/sh/boards/se/7343/irq.c
new file mode 100644
index 000000000000..b41e3d4ea37c
--- /dev/null
+++ b/arch/sh/boards/se/7343/irq.c
@@ -0,0 +1,193 @@
1/*
2 * arch/sh/boards/se/7343/irq.c
3 *
4 */
5
6#include <linux/config.h>
7#include <linux/init.h>
8#include <linux/interrupt.h>
9#include <linux/irq.h>
10#include <asm/irq.h>
11#include <asm/io.h>
12#include <asm/mach/se7343.h>
13
14static void
15disable_intreq_irq(unsigned int irq)
16{
17 int bit = irq - OFFCHIP_IRQ_BASE;
18 u16 val;
19
20 val = ctrl_inw(PA_CPLD_IMSK);
21 val |= 1 << bit;
22 ctrl_outw(val, PA_CPLD_IMSK);
23}
24
25static void
26enable_intreq_irq(unsigned int irq)
27{
28 int bit = irq - OFFCHIP_IRQ_BASE;
29 u16 val;
30
31 val = ctrl_inw(PA_CPLD_IMSK);
32 val &= ~(1 << bit);
33 ctrl_outw(val, PA_CPLD_IMSK);
34}
35
36static void
37mask_and_ack_intreq_irq(unsigned int irq)
38{
39 disable_intreq_irq(irq);
40}
41
42static unsigned int
43startup_intreq_irq(unsigned int irq)
44{
45 enable_intreq_irq(irq);
46 return 0;
47}
48
49static void
50shutdown_intreq_irq(unsigned int irq)
51{
52 disable_intreq_irq(irq);
53}
54
55static void
56end_intreq_irq(unsigned int irq)
57{
58 if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
59 enable_intreq_irq(irq);
60}
61
62static struct hw_interrupt_type intreq_irq_type = {
63 .typename = "FPGA-IRQ",
64 .startup = startup_intreq_irq,
65 .shutdown = shutdown_intreq_irq,
66 .enable = enable_intreq_irq,
67 .disable = disable_intreq_irq,
68 .ack = mask_and_ack_intreq_irq,
69 .end = end_intreq_irq
70};
71
72static void
73make_intreq_irq(unsigned int irq)
74{
75 disable_irq_nosync(irq);
76 irq_desc[irq].handler = &intreq_irq_type;
77 disable_intreq_irq(irq);
78}
79
80int
81shmse_irq_demux(int irq)
82{
83 int bit;
84 volatile u16 val;
85
86 if (irq == IRQ5_IRQ) {
87 /* Read status Register */
88 val = ctrl_inw(PA_CPLD_ST);
89 bit = ffs(val);
90 if (bit != 0)
91 return OFFCHIP_IRQ_BASE + bit - 1;
92 }
93 return irq;
94}
95
96/* IRQ5 is multiplexed between the following sources:
97 * 1. PC Card socket
98 * 2. Extension slot
99 * 3. USB Controller
100 * 4. Serial Controller
101 *
102 * We configure IRQ5 as a cascade IRQ.
103 */
104static struct irqaction irq5 = { no_action, 0, CPU_MASK_NONE, "IRQ5-cascade",
105 NULL, NULL};
106
107/*
108 * Initialize IRQ setting
109 */
110void __init
111init_7343se_IRQ(void)
112{
113 /* Setup Multiplexed interrupts */
114 ctrl_outw(8, PA_CPLD_MODESET); /* Set all CPLD interrupts to active
115 * low.
116 */
117 /* Mask all CPLD controller interrupts */
118 ctrl_outw(0x0fff, PA_CPLD_IMSK);
119
120 /* PC Card interrupts */
121 make_intreq_irq(PC_IRQ0);
122 make_intreq_irq(PC_IRQ1);
123 make_intreq_irq(PC_IRQ2);
124 make_intreq_irq(PC_IRQ3);
125
126 /* Extension Slot Interrupts */
127 make_intreq_irq(EXT_IRQ0);
128 make_intreq_irq(EXT_IRQ1);
129 make_intreq_irq(EXT_IRQ2);
130 make_intreq_irq(EXT_IRQ3);
131
132 /* USB Controller interrupts */
133 make_intreq_irq(USB_IRQ0);
134 make_intreq_irq(USB_IRQ1);
135
136 /* Serial Controller interrupts */
137 make_intreq_irq(UART_IRQ0);
138 make_intreq_irq(UART_IRQ1);
139
140 /* Setup all external interrupts to be active low */
141 ctrl_outw(0xaaaa, INTC_ICR1);
142
143 make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR+2, IRQ5_IPR_POS, IRQ5_PRIORITY);
144 setup_irq(IRQ5_IRQ, &irq5);
145 /* Set port control to use IRQ5 */
146 *(u16 *)0xA4050108 &= ~0xc;
147
148 make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
149 make_ipr_irq(VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8);
150
151 ctrl_outb(0x0f, INTC_IMCR5); /* enable SCIF IRQ */
152
153 make_ipr_irq(DMTE0_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
154 make_ipr_irq(DMTE1_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
155 make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
156 make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY);
157 make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
158 make_ipr_irq(DMTE5_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY);
159
160 /* I2C block */
161 make_ipr_irq(IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY);
162 make_ipr_irq(IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS,
163 IIC0_PRIORITY);
164 make_ipr_irq(IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS,
165 IIC0_PRIORITY);
166 make_ipr_irq(IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY);
167
168 make_ipr_irq(IIC1_ALI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY);
169 make_ipr_irq(IIC1_TACKI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS,
170 IIC1_PRIORITY);
171 make_ipr_irq(IIC1_WAITI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS,
172 IIC1_PRIORITY);
173 make_ipr_irq(IIC1_DTEI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY);
174
175 /* SIOF */
176 make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY);
177
178 /* SIU */
179 make_ipr_irq(SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY);
180
181 /* VIO interrupt */
182 make_ipr_irq(CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
183 make_ipr_irq(BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
184 make_ipr_irq(VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY);
185
186 /*MFI interrupt*/
187
188 make_ipr_irq(MFI_IRQ, MFI_IPR_ADDR, MFI_IPR_POS, MFI_PRIORITY);
189
190 /* LCD controller */
191 make_ipr_irq(LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY);
192 ctrl_outw(0x2000, PA_MRSHPC + 0x0c); /* mrshpc irq enable */
193}
diff --git a/arch/sh/boards/se/7343/led.c b/arch/sh/boards/se/7343/led.c
new file mode 100644
index 000000000000..6a439cf83e46
--- /dev/null
+++ b/arch/sh/boards/se/7343/led.c
@@ -0,0 +1,46 @@
1/*
2 * arch/sh/boards/se/7343/led.c
3 *
4 */
5
6#include <linux/config.h>
7#include <linux/sched.h>
8#include <asm/mach/se7343.h>
9
10/* Cycle the LED's in the clasic Knightrider/Sun pattern */
11void heartbeat_7343se(void)
12{
13 static unsigned int cnt = 0, period = 0;
14 volatile unsigned short *p = (volatile unsigned short *) PA_LED;
15 static unsigned bit = 0, up = 1;
16
17 cnt += 1;
18 if (cnt < period) {
19 return;
20 }
21
22 cnt = 0;
23
24 /* Go through the points (roughly!):
25 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
26 */
27 period = 110 - ((300 << FSHIFT) / ((avenrun[0] / 5) + (3 << FSHIFT)));
28
29 if (up) {
30 if (bit == 7) {
31 bit--;
32 up = 0;
33 } else {
34 bit++;
35 }
36 } else {
37 if (bit == 0) {
38 bit++;
39 up = 1;
40 } else {
41 bit--;
42 }
43 }
44 *p = 1 << (bit + LED_SHIFT);
45
46}
diff --git a/arch/sh/boards/se/7343/setup.c b/arch/sh/boards/se/7343/setup.c
new file mode 100644
index 000000000000..787322291fb3
--- /dev/null
+++ b/arch/sh/boards/se/7343/setup.c
@@ -0,0 +1,84 @@
1#include <linux/config.h>
2#include <linux/init.h>
3#include <linux/platform_device.h>
4#include <asm/machvec.h>
5#include <asm/mach/se7343.h>
6#include <asm/irq.h>
7
8void heartbeat_7343se(void);
9void init_7343se_IRQ(void);
10
11static struct resource smc91x_resources[] = {
12 [0] = {
13 .start = 0x10000000,
14 .end = 0x1000000F,
15 .flags = IORESOURCE_MEM,
16 },
17 [1] = {
18 /*
19 * shared with other devices via externel
20 * interrupt controller in FPGA...
21 */
22 .start = EXT_IRQ2,
23 .end = EXT_IRQ2,
24 .flags = IORESOURCE_IRQ,
25 },
26};
27
28static struct platform_device smc91x_device = {
29 .name = "smc91x",
30 .id = 0,
31 .num_resources = ARRAY_SIZE(smc91x_resources),
32 .resource = smc91x_resources,
33};
34
35static struct platform_device *smc91x_platform_devices[] __initdata = {
36 &smc91x_device,
37};
38
39static int __init sh7343se_devices_setup(void)
40{
41 return platform_add_devices(smc91x_platform_devices,
42 ARRAY_SIZE(smc91x_platform_devices));
43}
44
45static void __init sh7343se_setup(char **cmdline_p)
46{
47 device_initcall(sh7343se_devices_setup);
48}
49
50/*
51 * The Machine Vector
52 */
53struct sh_machine_vector mv_7343se __initmv = {
54 .mv_name = "SolutionEngine 7343",
55 .mv_setup = sh7343se_setup,
56 .mv_nr_irqs = 108,
57 .mv_inb = sh7343se_inb,
58 .mv_inw = sh7343se_inw,
59 .mv_inl = sh7343se_inl,
60 .mv_outb = sh7343se_outb,
61 .mv_outw = sh7343se_outw,
62 .mv_outl = sh7343se_outl,
63
64 .mv_inb_p = sh7343se_inb_p,
65 .mv_inw_p = sh7343se_inw,
66 .mv_inl_p = sh7343se_inl,
67 .mv_outb_p = sh7343se_outb_p,
68 .mv_outw_p = sh7343se_outw,
69 .mv_outl_p = sh7343se_outl,
70
71 .mv_insb = sh7343se_insb,
72 .mv_insw = sh7343se_insw,
73 .mv_insl = sh7343se_insl,
74 .mv_outsb = sh7343se_outsb,
75 .mv_outsw = sh7343se_outsw,
76 .mv_outsl = sh7343se_outsl,
77
78 .mv_init_irq = init_7343se_IRQ,
79 .mv_irq_demux = shmse_irq_demux,
80#ifdef CONFIG_HEARTBEAT
81 .mv_heartbeat = heartbeat_7343se,
82#endif
83};
84ALIAS_MV(7343se)
diff --git a/arch/sh/boards/se/770x/Makefile b/arch/sh/boards/se/770x/Makefile
index be89a73cc418..9a5035f80ec0 100644
--- a/arch/sh/boards/se/770x/Makefile
+++ b/arch/sh/boards/se/770x/Makefile
@@ -2,5 +2,5 @@
2# Makefile for the 770x SolutionEngine specific parts of the kernel 2# Makefile for the 770x SolutionEngine specific parts of the kernel
3# 3#
4 4
5obj-y := mach.o setup.o io.o irq.o led.o 5obj-y := setup.o io.o irq.o
6 6obj-$(CONFIG_HEARTBEAT) += led.o
diff --git a/arch/sh/boards/se/770x/io.c b/arch/sh/boards/se/770x/io.c
index 9a39ee963143..9941949331ab 100644
--- a/arch/sh/boards/se/770x/io.c
+++ b/arch/sh/boards/se/770x/io.c
@@ -1,4 +1,4 @@
1/* $Id: io.c,v 1.5 2004/02/22 23:08:43 kkojima Exp $ 1/* $Id: io.c,v 1.7 2006/02/05 21:55:29 lethal Exp $
2 * 2 *
3 * linux/arch/sh/kernel/io_se.c 3 * linux/arch/sh/kernel/io_se.c
4 * 4 *
@@ -11,7 +11,7 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/types.h> 12#include <linux/types.h>
13#include <asm/io.h> 13#include <asm/io.h>
14#include <asm/se/se.h> 14#include <asm/se.h>
15 15
16/* SH pcmcia io window base, start and end. */ 16/* SH pcmcia io window base, start and end. */
17int sh_pcic_io_wbase = 0xb8400000; 17int sh_pcic_io_wbase = 0xb8400000;
@@ -20,11 +20,6 @@ int sh_pcic_io_stop;
20int sh_pcic_io_type; 20int sh_pcic_io_type;
21int sh_pcic_io_dummy; 21int sh_pcic_io_dummy;
22 22
23static inline void delay(void)
24{
25 ctrl_inw(0xa0000000);
26}
27
28/* MS7750 requires special versions of in*, out* routines, since 23/* MS7750 requires special versions of in*, out* routines, since
29 PC-like io ports are located at upper half byte of 16-bit word which 24 PC-like io ports are located at upper half byte of 16-bit word which
30 can be accessed only with 16-bit wide. */ 25 can be accessed only with 16-bit wide. */
@@ -52,10 +47,6 @@ shifted_port(unsigned long port)
52 return 1; 47 return 1;
53} 48}
54 49
55#define maybebadio(name,port) \
56 printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
57 #name, (port), (__u32) __builtin_return_address(0))
58
59unsigned char se_inb(unsigned long port) 50unsigned char se_inb(unsigned long port)
60{ 51{
61 if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) 52 if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)
@@ -76,7 +67,7 @@ unsigned char se_inb_p(unsigned long port)
76 v = (*port2adr(port) >> 8); 67 v = (*port2adr(port) >> 8);
77 else 68 else
78 v = (*port2adr(port))&0xff; 69 v = (*port2adr(port))&0xff;
79 delay(); 70 ctrl_delay();
80 return v; 71 return v;
81} 72}
82 73
@@ -86,13 +77,13 @@ unsigned short se_inw(unsigned long port)
86 (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)) 77 (sh_pcic_io_start <= port && port <= sh_pcic_io_stop))
87 return *port2adr(port); 78 return *port2adr(port);
88 else 79 else
89 maybebadio(inw, port); 80 maybebadio(port);
90 return 0; 81 return 0;
91} 82}
92 83
93unsigned int se_inl(unsigned long port) 84unsigned int se_inl(unsigned long port)
94{ 85{
95 maybebadio(inl, port); 86 maybebadio(port);
96 return 0; 87 return 0;
97} 88}
98 89
@@ -114,7 +105,7 @@ void se_outb_p(unsigned char value, unsigned long port)
114 *(port2adr(port)) = value << 8; 105 *(port2adr(port)) = value << 8;
115 else 106 else
116 *(port2adr(port)) = value; 107 *(port2adr(port)) = value;
117 delay(); 108 ctrl_delay();
118} 109}
119 110
120void se_outw(unsigned short value, unsigned long port) 111void se_outw(unsigned short value, unsigned long port)
@@ -123,12 +114,12 @@ void se_outw(unsigned short value, unsigned long port)
123 (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)) 114 (sh_pcic_io_start <= port && port <= sh_pcic_io_stop))
124 *port2adr(port) = value; 115 *port2adr(port) = value;
125 else 116 else
126 maybebadio(outw, port); 117 maybebadio(port);
127} 118}
128 119
129void se_outl(unsigned int value, unsigned long port) 120void se_outl(unsigned int value, unsigned long port)
130{ 121{
131 maybebadio(outl, port); 122 maybebadio(port);
132} 123}
133 124
134void se_insb(unsigned long port, void *addr, unsigned long count) 125void se_insb(unsigned long port, void *addr, unsigned long count)
@@ -159,7 +150,7 @@ void se_insw(unsigned long port, void *addr, unsigned long count)
159 150
160void se_insl(unsigned long port, void *addr, unsigned long count) 151void se_insl(unsigned long port, void *addr, unsigned long count)
161{ 152{
162 maybebadio(insl, port); 153 maybebadio(port);
163} 154}
164 155
165void se_outsb(unsigned long port, const void *addr, unsigned long count) 156void se_outsb(unsigned long port, const void *addr, unsigned long count)
@@ -190,37 +181,5 @@ void se_outsw(unsigned long port, const void *addr, unsigned long count)
190 181
191void se_outsl(unsigned long port, const void *addr, unsigned long count) 182void se_outsl(unsigned long port, const void *addr, unsigned long count)
192{ 183{
193 maybebadio(outsw, port); 184 maybebadio(port);
194}
195
196/* Map ISA bus address to the real address. Only for PCMCIA. */
197
198/* ISA page descriptor. */
199static __u32 sh_isa_memmap[256];
200
201static int
202sh_isa_mmap(__u32 start, __u32 length, __u32 offset)
203{
204 int idx;
205
206 if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000))
207 return -1;
208
209 idx = start >> 12;
210 sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff);
211#if 0
212 printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n",
213 start, length, offset, idx, sh_isa_memmap[idx]);
214#endif
215 return 0;
216}
217
218unsigned long
219se_isa_port2addr(unsigned long offset)
220{
221 int idx;
222
223 idx = (offset >> 12) & 0xff;
224 offset &= 0xfff;
225 return sh_isa_memmap[idx] + offset;
226} 185}
diff --git a/arch/sh/boards/se/770x/irq.c b/arch/sh/boards/se/770x/irq.c
index 3e558716ce10..cff6700bbafd 100644
--- a/arch/sh/boards/se/770x/irq.c
+++ b/arch/sh/boards/se/770x/irq.c
@@ -11,7 +11,7 @@
11#include <linux/irq.h> 11#include <linux/irq.h>
12#include <asm/irq.h> 12#include <asm/irq.h>
13#include <asm/io.h> 13#include <asm/io.h>
14#include <asm/se/se.h> 14#include <asm/se.h>
15 15
16/* 16/*
17 * Initialize IRQ setting 17 * Initialize IRQ setting
diff --git a/arch/sh/boards/se/770x/led.c b/arch/sh/boards/se/770x/led.c
index 3cddbda025fc..daf7b1ee786a 100644
--- a/arch/sh/boards/se/770x/led.c
+++ b/arch/sh/boards/se/770x/led.c
@@ -9,22 +9,8 @@
9 * This file contains Solution Engine specific LED code. 9 * This file contains Solution Engine specific LED code.
10 */ 10 */
11 11
12#include <asm/se/se.h>
13
14static void mach_led(int position, int value)
15{
16 volatile unsigned short* p = (volatile unsigned short*)PA_LED;
17
18 if (value) {
19 *p |= (1<<8);
20 } else {
21 *p &= ~(1<<8);
22 }
23}
24
25#ifdef CONFIG_HEARTBEAT
26
27#include <linux/sched.h> 12#include <linux/sched.h>
13#include <asm/se.h>
28 14
29/* Cycle the LED's in the clasic Knightrider/Sun pattern */ 15/* Cycle the LED's in the clasic Knightrider/Sun pattern */
30void heartbeat_se(void) 16void heartbeat_se(void)
@@ -64,4 +50,3 @@ void heartbeat_se(void)
64 *p = 1<<(bit+8); 50 *p = 1<<(bit+8);
65 51
66} 52}
67#endif /* CONFIG_HEARTBEAT */
diff --git a/arch/sh/boards/se/770x/mach.c b/arch/sh/boards/se/770x/mach.c
deleted file mode 100644
index 6ec07bd3dcf1..000000000000
--- a/arch/sh/boards/se/770x/mach.c
+++ /dev/null
@@ -1,67 +0,0 @@
1/*
2 * linux/arch/sh/kernel/mach_se.c
3 *
4 * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com)
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Machine vector for the Hitachi SolutionEngine
10 */
11
12#include <linux/init.h>
13
14#include <asm/machvec.h>
15#include <asm/rtc.h>
16#include <asm/machvec_init.h>
17
18#include <asm/se/io.h>
19
20void heartbeat_se(void);
21void setup_se(void);
22void init_se_IRQ(void);
23
24/*
25 * The Machine Vector
26 */
27
28struct sh_machine_vector mv_se __initmv = {
29#if defined(CONFIG_CPU_SH4)
30 .mv_nr_irqs = 48,
31#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
32 .mv_nr_irqs = 32,
33#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
34 .mv_nr_irqs = 61,
35#elif defined(CONFIG_CPU_SUBTYPE_SH7705)
36 .mv_nr_irqs = 86,
37#endif
38
39 .mv_inb = se_inb,
40 .mv_inw = se_inw,
41 .mv_inl = se_inl,
42 .mv_outb = se_outb,
43 .mv_outw = se_outw,
44 .mv_outl = se_outl,
45
46 .mv_inb_p = se_inb_p,
47 .mv_inw_p = se_inw,
48 .mv_inl_p = se_inl,
49 .mv_outb_p = se_outb_p,
50 .mv_outw_p = se_outw,
51 .mv_outl_p = se_outl,
52
53 .mv_insb = se_insb,
54 .mv_insw = se_insw,
55 .mv_insl = se_insl,
56 .mv_outsb = se_outsb,
57 .mv_outsw = se_outsw,
58 .mv_outsl = se_outsl,
59
60 .mv_isa_port2addr = se_isa_port2addr,
61
62 .mv_init_irq = init_se_IRQ,
63#ifdef CONFIG_HEARTBEAT
64 .mv_heartbeat = heartbeat_se,
65#endif
66};
67ALIAS_MV(se)
diff --git a/arch/sh/boards/se/770x/setup.c b/arch/sh/boards/se/770x/setup.c
index 7d1a071727cc..f3f82b7c8217 100644
--- a/arch/sh/boards/se/770x/setup.c
+++ b/arch/sh/boards/se/770x/setup.c
@@ -7,15 +7,17 @@
7 * Hitachi SolutionEngine Support. 7 * Hitachi SolutionEngine Support.
8 * 8 *
9 */ 9 */
10
11#include <linux/init.h> 10#include <linux/init.h>
12#include <linux/irq.h> 11#include <linux/irq.h>
13
14#include <linux/hdreg.h> 12#include <linux/hdreg.h>
15#include <linux/ide.h> 13#include <linux/ide.h>
16#include <asm/io.h> 14#include <asm/io.h>
17#include <asm/se/se.h> 15#include <asm/se.h>
18#include <asm/se/smc37c93x.h> 16#include <asm/smc37c93x.h>
17#include <asm/machvec.h>
18
19void heartbeat_se(void);
20void init_se_IRQ(void);
19 21
20/* 22/*
21 * Configure the Super I/O chip 23 * Configure the Super I/O chip
@@ -26,7 +28,8 @@ static void __init smsc_config(int index, int data)
26 outb_p(data, DATA_PORT); 28 outb_p(data, DATA_PORT);
27} 29}
28 30
29static void __init init_smsc(void) 31/* XXX: Another candidate for a more generic cchip machine vector */
32static void __init smsc_setup(char **cmdline_p)
30{ 33{
31 outb_p(CONFIG_ENTER, CONFIG_PORT); 34 outb_p(CONFIG_ENTER, CONFIG_PORT);
32 outb_p(CONFIG_ENTER, CONFIG_PORT); 35 outb_p(CONFIG_ENTER, CONFIG_PORT);
@@ -69,16 +72,46 @@ static void __init init_smsc(void)
69 outb_p(CONFIG_EXIT, CONFIG_PORT); 72 outb_p(CONFIG_EXIT, CONFIG_PORT);
70} 73}
71 74
72const char *get_system_type(void)
73{
74 return "SolutionEngine";
75}
76
77/* 75/*
78 * Initialize the board 76 * The Machine Vector
79 */ 77 */
80void __init platform_setup(void) 78struct sh_machine_vector mv_se __initmv = {
81{ 79 .mv_name = "SolutionEngine",
82 init_smsc(); 80 .mv_setup = smsc_setup,
83 /* XXX: RTC setting comes here */ 81#if defined(CONFIG_CPU_SH4)
84} 82 .mv_nr_irqs = 48,
83#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
84 .mv_nr_irqs = 32,
85#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
86 .mv_nr_irqs = 61,
87#elif defined(CONFIG_CPU_SUBTYPE_SH7705)
88 .mv_nr_irqs = 86,
89#endif
90
91 .mv_inb = se_inb,
92 .mv_inw = se_inw,
93 .mv_inl = se_inl,
94 .mv_outb = se_outb,
95 .mv_outw = se_outw,
96 .mv_outl = se_outl,
97
98 .mv_inb_p = se_inb_p,
99 .mv_inw_p = se_inw,
100 .mv_inl_p = se_inl,
101 .mv_outb_p = se_outb_p,
102 .mv_outw_p = se_outw,
103 .mv_outl_p = se_outl,
104
105 .mv_insb = se_insb,
106 .mv_insw = se_insw,
107 .mv_insl = se_insl,
108 .mv_outsb = se_outsb,
109 .mv_outsw = se_outsw,
110 .mv_outsl = se_outsl,
111
112 .mv_init_irq = init_se_IRQ,
113#ifdef CONFIG_HEARTBEAT
114 .mv_heartbeat = heartbeat_se,
115#endif
116};
117ALIAS_MV(se)
diff --git a/arch/sh/boards/se/7751/Makefile b/arch/sh/boards/se/7751/Makefile
index ce7ca247f84d..188900c48321 100644
--- a/arch/sh/boards/se/7751/Makefile
+++ b/arch/sh/boards/se/7751/Makefile
@@ -2,7 +2,7 @@
2# Makefile for the 7751 SolutionEngine specific parts of the kernel 2# Makefile for the 7751 SolutionEngine specific parts of the kernel
3# 3#
4 4
5obj-y := mach.o setup.o io.o irq.o led.o 5obj-y := setup.o io.o irq.o
6 6
7obj-$(CONFIG_PCI) += pci.o 7obj-$(CONFIG_PCI) += pci.o
8 8obj-$(CONFIG_HEARTBEAT) += led.o
diff --git a/arch/sh/boards/se/7751/io.c b/arch/sh/boards/se/7751/io.c
index 99041b269261..e8d846cec89d 100644
--- a/arch/sh/boards/se/7751/io.c
+++ b/arch/sh/boards/se/7751/io.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/sh/kernel/io_7751se.c
3 *
4 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel 2 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
5 * Based largely on io_se.c. 3 * Based largely on io_se.c.
6 * 4 *
@@ -10,96 +8,21 @@
10 * placeholder code from io_se.c left in with the 8 * placeholder code from io_se.c left in with the
11 * expectation of later SuperIO and PCMCIA access. 9 * expectation of later SuperIO and PCMCIA access.
12 */ 10 */
13
14#include <linux/kernel.h> 11#include <linux/kernel.h>
15#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/pci.h>
16#include <asm/io.h> 14#include <asm/io.h>
17#include <asm/se7751/se7751.h> 15#include <asm/se7751.h>
18#include <asm/addrspace.h> 16#include <asm/addrspace.h>
19 17
20#include <linux/pci.h> 18static inline volatile u16 *port2adr(unsigned int port)
21#include "../../../drivers/pci/pci-sh7751.h"
22
23#if 0
24/******************************************************************
25 * Variables from io_se.c, related to PCMCIA (not PCI); we're not
26 * compiling them in, and have removed references from functions
27 * which follow. [Many checked for IO ports in the range bounded
28 * by sh_pcic_io_start/stop, and used sh_pcic_io_wbase as offset.
29 * As start/stop are uninitialized, only port 0x0 would match?]
30 * When used, remember to adjust names to avoid clash with io_se?
31 *****************************************************************/
32/* SH pcmcia io window base, start and end. */
33int sh_pcic_io_wbase = 0xb8400000;
34int sh_pcic_io_start;
35int sh_pcic_io_stop;
36int sh_pcic_io_type;
37int sh_pcic_io_dummy;
38/*************************************************************/
39#endif
40
41/*
42 * The 7751 Solution Engine uses the built-in PCI controller (PCIC)
43 * of the 7751 processor, and has a SuperIO accessible via the PCI.
44 * The board also includes a PCMCIA controller on its memory bus,
45 * like the other Solution Engine boards.
46 */
47
48#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR)
49#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR)
50#define PCI_IO_AREA SH7751_PCI_IO_BASE
51#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE
52
53#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
54
55#define maybebadio(name,port) \
56 printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
57 #name, (port), (__u32) __builtin_return_address(0))
58
59static inline void delay(void)
60{
61 ctrl_inw(0xa0000000);
62}
63
64static inline volatile __u16 *
65port2adr(unsigned int port)
66{ 19{
67 if (port >= 0x2000) 20 if (port >= 0x2000)
68 return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); 21 return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
69#if 0 22 maybebadio((unsigned long)port);
70 else
71 return (volatile __u16 *) (PA_SUPERIO + (port << 1));
72#endif
73 maybebadio(name,(unsigned long)port);
74 return (volatile __u16*)port; 23 return (volatile __u16*)port;
75} 24}
76 25
77#if 0
78/* The 7751 Solution Engine seems to have everything hooked */
79/* up pretty normally (nothing on high-bytes only...) so this */
80/* shouldn't be needed */
81static inline int
82shifted_port(unsigned long port)
83{
84 /* For IDE registers, value is not shifted */
85 if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6)
86 return 0;
87 else
88 return 1;
89}
90#endif
91
92/* In case someone configures the kernel w/o PCI support: in that */
93/* scenario, don't ever bother to check for PCI-window addresses */
94
95/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
96#if defined(CONFIG_PCI)
97#define CHECK_SH7751_PCIIO(port) \
98 ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
99#else
100#define CHECK_SH7751_PCIIO(port) (0)
101#endif
102
103/* 26/*
104 * General outline: remap really low stuff [eventually] to SuperIO, 27 * General outline: remap really low stuff [eventually] to SuperIO,
105 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) 28 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
@@ -111,10 +34,10 @@ unsigned char sh7751se_inb(unsigned long port)
111{ 34{
112 if (PXSEG(port)) 35 if (PXSEG(port))
113 return *(volatile unsigned char *)port; 36 return *(volatile unsigned char *)port;
114 else if (CHECK_SH7751_PCIIO(port)) 37 else if (is_pci_ioaddr(port))
115 return *(volatile unsigned char *)PCI_IOMAP(port); 38 return *(volatile unsigned char *)pci_ioaddr(port);
116 else 39 else
117 return (*port2adr(port))&0xff; 40 return (*port2adr(port)) & 0xff;
118} 41}
119 42
120unsigned char sh7751se_inb_p(unsigned long port) 43unsigned char sh7751se_inb_p(unsigned long port)
@@ -123,11 +46,11 @@ unsigned char sh7751se_inb_p(unsigned long port)
123 46
124 if (PXSEG(port)) 47 if (PXSEG(port))
125 v = *(volatile unsigned char *)port; 48 v = *(volatile unsigned char *)port;
126 else if (CHECK_SH7751_PCIIO(port)) 49 else if (is_pci_ioaddr(port))
127 v = *(volatile unsigned char *)PCI_IOMAP(port); 50 v = *(volatile unsigned char *)pci_ioaddr(port);
128 else 51 else
129 v = (*port2adr(port))&0xff; 52 v = (*port2adr(port)) & 0xff;
130 delay(); 53 ctrl_delay();
131 return v; 54 return v;
132} 55}
133 56
@@ -135,12 +58,12 @@ unsigned short sh7751se_inw(unsigned long port)
135{ 58{
136 if (PXSEG(port)) 59 if (PXSEG(port))
137 return *(volatile unsigned short *)port; 60 return *(volatile unsigned short *)port;
138 else if (CHECK_SH7751_PCIIO(port)) 61 else if (is_pci_ioaddr(port))
139 return *(volatile unsigned short *)PCI_IOMAP(port); 62 return *(volatile unsigned short *)pci_ioaddr(port);
140 else if (port >= 0x2000) 63 else if (port >= 0x2000)
141 return *port2adr(port); 64 return *port2adr(port);
142 else 65 else
143 maybebadio(inw, port); 66 maybebadio(port);
144 return 0; 67 return 0;
145} 68}
146 69
@@ -148,12 +71,12 @@ unsigned int sh7751se_inl(unsigned long port)
148{ 71{
149 if (PXSEG(port)) 72 if (PXSEG(port))
150 return *(volatile unsigned long *)port; 73 return *(volatile unsigned long *)port;
151 else if (CHECK_SH7751_PCIIO(port)) 74 else if (is_pci_ioaddr(port))
152 return *(volatile unsigned int *)PCI_IOMAP(port); 75 return *(volatile unsigned int *)pci_ioaddr(port);
153 else if (port >= 0x2000) 76 else if (port >= 0x2000)
154 return *port2adr(port); 77 return *port2adr(port);
155 else 78 else
156 maybebadio(inl, port); 79 maybebadio(port);
157 return 0; 80 return 0;
158} 81}
159 82
@@ -162,8 +85,8 @@ void sh7751se_outb(unsigned char value, unsigned long port)
162 85
163 if (PXSEG(port)) 86 if (PXSEG(port))
164 *(volatile unsigned char *)port = value; 87 *(volatile unsigned char *)port = value;
165 else if (CHECK_SH7751_PCIIO(port)) 88 else if (is_pci_ioaddr(port))
166 *((unsigned char*)PCI_IOMAP(port)) = value; 89 *((unsigned char*)pci_ioaddr(port)) = value;
167 else 90 else
168 *(port2adr(port)) = value; 91 *(port2adr(port)) = value;
169} 92}
@@ -172,73 +95,41 @@ void sh7751se_outb_p(unsigned char value, unsigned long port)
172{ 95{
173 if (PXSEG(port)) 96 if (PXSEG(port))
174 *(volatile unsigned char *)port = value; 97 *(volatile unsigned char *)port = value;
175 else if (CHECK_SH7751_PCIIO(port)) 98 else if (is_pci_ioaddr(port))
176 *((unsigned char*)PCI_IOMAP(port)) = value; 99 *((unsigned char*)pci_ioaddr(port)) = value;
177 else 100 else
178 *(port2adr(port)) = value; 101 *(port2adr(port)) = value;
179 delay(); 102 ctrl_delay();
180} 103}
181 104
182void sh7751se_outw(unsigned short value, unsigned long port) 105void sh7751se_outw(unsigned short value, unsigned long port)
183{ 106{
184 if (PXSEG(port)) 107 if (PXSEG(port))
185 *(volatile unsigned short *)port = value; 108 *(volatile unsigned short *)port = value;
186 else if (CHECK_SH7751_PCIIO(port)) 109 else if (is_pci_ioaddr(port))
187 *((unsigned short *)PCI_IOMAP(port)) = value; 110 *((unsigned short *)pci_ioaddr(port)) = value;
188 else if (port >= 0x2000) 111 else if (port >= 0x2000)
189 *port2adr(port) = value; 112 *port2adr(port) = value;
190 else 113 else
191 maybebadio(outw, port); 114 maybebadio(port);
192} 115}
193 116
194void sh7751se_outl(unsigned int value, unsigned long port) 117void sh7751se_outl(unsigned int value, unsigned long port)
195{ 118{
196 if (PXSEG(port)) 119 if (PXSEG(port))
197 *(volatile unsigned long *)port = value; 120 *(volatile unsigned long *)port = value;
198 else if (CHECK_SH7751_PCIIO(port)) 121 else if (is_pci_ioaddr(port))
199 *((unsigned long*)PCI_IOMAP(port)) = value; 122 *((unsigned long*)pci_ioaddr(port)) = value;
200 else 123 else
201 maybebadio(outl, port); 124 maybebadio(port);
202} 125}
203 126
204void sh7751se_insl(unsigned long port, void *addr, unsigned long count) 127void sh7751se_insl(unsigned long port, void *addr, unsigned long count)
205{ 128{
206 maybebadio(insl, port); 129 maybebadio(port);
207} 130}
208 131
209void sh7751se_outsl(unsigned long port, const void *addr, unsigned long count) 132void sh7751se_outsl(unsigned long port, const void *addr, unsigned long count)
210{ 133{
211 maybebadio(outsw, port); 134 maybebadio(port);
212}
213
214/* Map ISA bus address to the real address. Only for PCMCIA. */
215
216/* ISA page descriptor. */
217static __u32 sh_isa_memmap[256];
218
219#if 0
220static int
221sh_isa_mmap(__u32 start, __u32 length, __u32 offset)
222{
223 int idx;
224
225 if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000))
226 return -1;
227
228 idx = start >> 12;
229 sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff);
230 printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n",
231 start, length, offset, idx, sh_isa_memmap[idx]);
232 return 0;
233}
234#endif
235
236unsigned long
237sh7751se_isa_port2addr(unsigned long offset)
238{
239 int idx;
240
241 idx = (offset >> 12) & 0xff;
242 offset &= 0xfff;
243 return sh_isa_memmap[idx] + offset;
244} 135}
diff --git a/arch/sh/boards/se/7751/irq.c b/arch/sh/boards/se/7751/irq.c
index bf6c023615df..c607b0a48479 100644
--- a/arch/sh/boards/se/7751/irq.c
+++ b/arch/sh/boards/se/7751/irq.c
@@ -12,7 +12,7 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/irq.h> 13#include <linux/irq.h>
14#include <asm/irq.h> 14#include <asm/irq.h>
15#include <asm/se7751/se7751.h> 15#include <asm/se7751.h>
16 16
17/* 17/*
18 * Initialize IRQ setting 18 * Initialize IRQ setting
diff --git a/arch/sh/boards/se/7751/led.c b/arch/sh/boards/se/7751/led.c
index a878726d3c7c..ff0355dea81b 100644
--- a/arch/sh/boards/se/7751/led.c
+++ b/arch/sh/boards/se/7751/led.c
@@ -8,23 +8,8 @@
8 * 8 *
9 * This file contains Solution Engine specific LED code. 9 * This file contains Solution Engine specific LED code.
10 */ 10 */
11
12#include <asm/se7751/se7751.h>
13
14static void mach_led(int position, int value)
15{
16 volatile unsigned short* p = (volatile unsigned short*)PA_LED;
17
18 if (value) {
19 *p |= (1<<8);
20 } else {
21 *p &= ~(1<<8);
22 }
23}
24
25#ifdef CONFIG_HEARTBEAT
26
27#include <linux/sched.h> 11#include <linux/sched.h>
12#include <asm/se7751.h>
28 13
29/* Cycle the LED's in the clasic Knightrider/Sun pattern */ 14/* Cycle the LED's in the clasic Knightrider/Sun pattern */
30void heartbeat_7751se(void) 15void heartbeat_7751se(void)
@@ -64,4 +49,3 @@ void heartbeat_7751se(void)
64 *p = 1<<(bit+8); 49 *p = 1<<(bit+8);
65 50
66} 51}
67#endif /* CONFIG_HEARTBEAT */
diff --git a/arch/sh/boards/se/7751/mach.c b/arch/sh/boards/se/7751/mach.c
deleted file mode 100644
index 62d8d3e62590..000000000000
--- a/arch/sh/boards/se/7751/mach.c
+++ /dev/null
@@ -1,54 +0,0 @@
1/*
2 * linux/arch/sh/kernel/mach_7751se.c
3 *
4 * Minor tweak of mach_se.c file to reference 7751se-specific items.
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * Machine vector for the Hitachi 7751 SolutionEngine
10 */
11
12#include <linux/init.h>
13
14#include <asm/machvec.h>
15#include <asm/rtc.h>
16#include <asm/machvec_init.h>
17
18#include <asm/se7751/io.h>
19
20void heartbeat_7751se(void);
21void init_7751se_IRQ(void);
22
23/*
24 * The Machine Vector
25 */
26
27struct sh_machine_vector mv_7751se __initmv = {
28 .mv_nr_irqs = 72,
29
30 .mv_inb = sh7751se_inb,
31 .mv_inw = sh7751se_inw,
32 .mv_inl = sh7751se_inl,
33 .mv_outb = sh7751se_outb,
34 .mv_outw = sh7751se_outw,
35 .mv_outl = sh7751se_outl,
36
37 .mv_inb_p = sh7751se_inb_p,
38 .mv_inw_p = sh7751se_inw,
39 .mv_inl_p = sh7751se_inl,
40 .mv_outb_p = sh7751se_outb_p,
41 .mv_outw_p = sh7751se_outw,
42 .mv_outl_p = sh7751se_outl,
43
44 .mv_insl = sh7751se_insl,
45 .mv_outsl = sh7751se_outsl,
46
47 .mv_isa_port2addr = sh7751se_isa_port2addr,
48
49 .mv_init_irq = init_7751se_IRQ,
50#ifdef CONFIG_HEARTBEAT
51 .mv_heartbeat = heartbeat_7751se,
52#endif
53};
54ALIAS_MV(7751se)
diff --git a/arch/sh/boards/se/7751/setup.c b/arch/sh/boards/se/7751/setup.c
index 48dc5aee67d4..73e826310ba8 100644
--- a/arch/sh/boards/se/7751/setup.c
+++ b/arch/sh/boards/se/7751/setup.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * linux/arch/sh/kernel/setup_7751se.c 2 * linux/arch/sh/kernel/setup_7751se.c
3 * 3 *
4 * Copyright (C) 2000 Kazumoto Kojima 4 * Copyright (C) 2000 Kazumoto Kojima
@@ -11,78 +11,15 @@
11 11
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/irq.h> 13#include <linux/irq.h>
14
15#include <linux/hdreg.h>
16#include <linux/ide.h> 14#include <linux/ide.h>
17#include <asm/io.h> 15#include <asm/io.h>
18#include <asm/se7751/se7751.h> 16#include <asm/se7751.h>
19 17
20#ifdef CONFIG_SH_KGDB 18void heartbeat_7751se(void);
21#include <asm/kgdb.h> 19void init_7751se_IRQ(void);
22#endif
23
24/*
25 * Configure the Super I/O chip
26 */
27#if 0
28/* Leftover code from regular Solution Engine, for reference. */
29/* The SH7751 Solution Engine has a different SuperIO. */
30static void __init smsc_config(int index, int data)
31{
32 outb_p(index, INDEX_PORT);
33 outb_p(data, DATA_PORT);
34}
35
36static void __init init_smsc(void)
37{
38 outb_p(CONFIG_ENTER, CONFIG_PORT);
39 outb_p(CONFIG_ENTER, CONFIG_PORT);
40
41 /* FDC */
42 smsc_config(CURRENT_LDN_INDEX, LDN_FDC);
43 smsc_config(ACTIVATE_INDEX, 0x01);
44 smsc_config(IRQ_SELECT_INDEX, 6); /* IRQ6 */
45
46 /* IDE1 */
47 smsc_config(CURRENT_LDN_INDEX, LDN_IDE1);
48 smsc_config(ACTIVATE_INDEX, 0x01);
49 smsc_config(IRQ_SELECT_INDEX, 14); /* IRQ14 */
50
51 /* AUXIO (GPIO): to use IDE1 */
52 smsc_config(CURRENT_LDN_INDEX, LDN_AUXIO);
53 smsc_config(GPIO46_INDEX, 0x00); /* nIOROP */
54 smsc_config(GPIO47_INDEX, 0x00); /* nIOWOP */
55
56 /* COM1 */
57 smsc_config(CURRENT_LDN_INDEX, LDN_COM1);
58 smsc_config(ACTIVATE_INDEX, 0x01);
59 smsc_config(IO_BASE_HI_INDEX, 0x03);
60 smsc_config(IO_BASE_LO_INDEX, 0xf8);
61 smsc_config(IRQ_SELECT_INDEX, 4); /* IRQ4 */
62
63 /* COM2 */
64 smsc_config(CURRENT_LDN_INDEX, LDN_COM2);
65 smsc_config(ACTIVATE_INDEX, 0x01);
66 smsc_config(IO_BASE_HI_INDEX, 0x02);
67 smsc_config(IO_BASE_LO_INDEX, 0xf8);
68 smsc_config(IRQ_SELECT_INDEX, 3); /* IRQ3 */
69
70 /* RTC */
71 smsc_config(CURRENT_LDN_INDEX, LDN_RTC);
72 smsc_config(ACTIVATE_INDEX, 0x01);
73 smsc_config(IRQ_SELECT_INDEX, 8); /* IRQ8 */
74
75 /* XXX: PARPORT, KBD, and MOUSE will come here... */
76 outb_p(CONFIG_EXIT, CONFIG_PORT);
77}
78#endif
79
80const char *get_system_type(void)
81{
82 return "7751 SolutionEngine";
83}
84 20
85#ifdef CONFIG_SH_KGDB 21#ifdef CONFIG_SH_KGDB
22#include <asm/kgdb.h>
86static int kgdb_uart_setup(void); 23static int kgdb_uart_setup(void);
87static struct kgdb_sermap kgdb_uart_sermap = 24static struct kgdb_sermap kgdb_uart_sermap =
88{ "ttyS", 0, kgdb_uart_setup, NULL }; 25{ "ttyS", 0, kgdb_uart_setup, NULL };
@@ -91,7 +28,7 @@ static struct kgdb_sermap kgdb_uart_sermap =
91/* 28/*
92 * Initialize the board 29 * Initialize the board
93 */ 30 */
94void __init platform_setup(void) 31static void __init sh7751se_setup(char **cmdline_p)
95{ 32{
96 /* Call init_smsc() replacement to set up SuperIO. */ 33 /* Call init_smsc() replacement to set up SuperIO. */
97 /* XXX: RTC setting comes here */ 34 /* XXX: RTC setting comes here */
@@ -225,3 +162,37 @@ static int kgdb_uart_setup(void)
225 return 0; 162 return 0;
226} 163}
227#endif /* CONFIG_SH_KGDB */ 164#endif /* CONFIG_SH_KGDB */
165
166
167/*
168 * The Machine Vector
169 */
170
171struct sh_machine_vector mv_7751se __initmv = {
172 .mv_name = "7751 SolutionEngine",
173 .mv_setup = sh7751se_setup,
174 .mv_nr_irqs = 72,
175
176 .mv_inb = sh7751se_inb,
177 .mv_inw = sh7751se_inw,
178 .mv_inl = sh7751se_inl,
179 .mv_outb = sh7751se_outb,
180 .mv_outw = sh7751se_outw,
181 .mv_outl = sh7751se_outl,
182
183 .mv_inb_p = sh7751se_inb_p,
184 .mv_inw_p = sh7751se_inw,
185 .mv_inl_p = sh7751se_inl,
186 .mv_outb_p = sh7751se_outb_p,
187 .mv_outw_p = sh7751se_outw,
188 .mv_outl_p = sh7751se_outl,
189
190 .mv_insl = sh7751se_insl,
191 .mv_outsl = sh7751se_outsl,
192
193 .mv_init_irq = init_7751se_IRQ,
194#ifdef CONFIG_HEARTBEAT
195 .mv_heartbeat = heartbeat_7751se,
196#endif
197};
198ALIAS_MV(7751se)
diff --git a/arch/sh/boards/sh03/rtc.c b/arch/sh/boards/sh03/rtc.c
index d609863cfe53..0a9266bb51c5 100644
--- a/arch/sh/boards/sh03/rtc.c
+++ b/arch/sh/boards/sh03/rtc.c
@@ -10,9 +10,10 @@
10#include <linux/sched.h> 10#include <linux/sched.h>
11#include <linux/time.h> 11#include <linux/time.h>
12#include <linux/bcd.h> 12#include <linux/bcd.h>
13#include <asm/io.h>
14#include <linux/rtc.h> 13#include <linux/rtc.h>
15#include <linux/spinlock.h> 14#include <linux/spinlock.h>
15#include <asm/io.h>
16#include <asm/rtc.h>
16 17
17#define RTC_BASE 0xb0000000 18#define RTC_BASE 0xb0000000
18#define RTC_SEC1 (RTC_BASE + 0) 19#define RTC_SEC1 (RTC_BASE + 0)
@@ -34,8 +35,6 @@
34#define RTC_BUSY 1 35#define RTC_BUSY 1
35#define RTC_STOP 2 36#define RTC_STOP 2
36 37
37extern void (*rtc_get_time)(struct timespec *);
38extern int (*rtc_set_time)(const time_t);
39extern spinlock_t rtc_lock; 38extern spinlock_t rtc_lock;
40 39
41unsigned long get_cmos_time(void) 40unsigned long get_cmos_time(void)
@@ -128,6 +127,6 @@ int sh03_rtc_settimeofday(const time_t secs)
128 127
129void sh03_time_init(void) 128void sh03_time_init(void)
130{ 129{
131 rtc_get_time = sh03_rtc_gettimeofday; 130 rtc_sh_get_time = sh03_rtc_gettimeofday;
132 rtc_set_time = sh03_rtc_settimeofday; 131 rtc_sh_set_time = sh03_rtc_settimeofday;
133} 132}
diff --git a/arch/sh/boards/sh03/setup.c b/arch/sh/boards/sh03/setup.c
index 60290f8f289c..6c310587ddfe 100644
--- a/arch/sh/boards/sh03/setup.c
+++ b/arch/sh/boards/sh03/setup.c
@@ -7,22 +7,13 @@
7 7
8#include <linux/init.h> 8#include <linux/init.h>
9#include <linux/irq.h> 9#include <linux/irq.h>
10#include <linux/hdreg.h>
11#include <linux/ide.h>
12#include <asm/io.h> 10#include <asm/io.h>
11#include <asm/rtc.h>
13#include <asm/sh03/io.h> 12#include <asm/sh03/io.h>
14#include <asm/sh03/sh03.h> 13#include <asm/sh03/sh03.h>
15#include <asm/addrspace.h> 14#include <asm/addrspace.h>
16#include "../../drivers/pci/pci-sh7751.h"
17 15
18extern void (*board_time_init)(void); 16static void __init init_sh03_IRQ(void)
19
20const char *get_system_type(void)
21{
22 return "Interface CTP/PCI-SH03)";
23}
24
25void init_sh03_IRQ(void)
26{ 17{
27 ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); 18 ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
28 19
@@ -34,38 +25,34 @@ void init_sh03_IRQ(void)
34 25
35extern void *cf_io_base; 26extern void *cf_io_base;
36 27
37unsigned long sh03_isa_port2addr(unsigned long port) 28static void __iomem *sh03_ioport_map(unsigned long port, unsigned int size)
38{ 29{
39 if (PXSEG(port)) 30 if (PXSEG(port))
40 return port; 31 return (void __iomem *)port;
41 /* CompactFlash (IDE) */ 32 /* CompactFlash (IDE) */
42 if (((port >= 0x1f0) && (port <= 0x1f7)) || (port == 0x3f6)) { 33 if (((port >= 0x1f0) && (port <= 0x1f7)) || (port == 0x3f6))
43 return (unsigned long)cf_io_base + port; 34 return (void __iomem *)((unsigned long)cf_io_base + port);
44 } 35
45 return port + SH7751_PCI_IO_BASE; 36 return (void __iomem *)(port + PCI_IO_BASE);
46} 37}
47 38
48/* 39/* arch/sh/boards/sh03/rtc.c */
49 * The Machine Vector 40void sh03_time_init(void);
50 */ 41
42static void __init sh03_setup(char **cmdline_p)
43{
44 board_time_init = sh03_time_init;
45}
51 46
52struct sh_machine_vector mv_sh03 __initmv = { 47struct sh_machine_vector mv_sh03 __initmv = {
48 .mv_name = "Interface (CTP/PCI-SH03)",
49 .mv_setup = sh03_setup,
53 .mv_nr_irqs = 48, 50 .mv_nr_irqs = 48,
54 .mv_isa_port2addr = sh03_isa_port2addr, 51 .mv_ioport_map = sh03_ioport_map,
55 .mv_init_irq = init_sh03_IRQ, 52 .mv_init_irq = init_sh03_IRQ,
56 53
57#ifdef CONFIG_HEARTBEAT 54#ifdef CONFIG_HEARTBEAT
58 .mv_heartbeat = heartbeat_sh03, 55 .mv_heartbeat = heartbeat_sh03,
59#endif 56#endif
60}; 57};
61
62ALIAS_MV(sh03) 58ALIAS_MV(sh03)
63
64/* arch/sh/boards/sh03/rtc.c */
65void sh03_time_init(void);
66
67int __init platform_setup(void)
68{
69 board_time_init = sh03_time_init;
70 return 0;
71}
diff --git a/arch/sh/boards/sh2000/Makefile b/arch/sh/boards/sh2000/Makefile
deleted file mode 100644
index 05d390c3599c..000000000000
--- a/arch/sh/boards/sh2000/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
1#
2# Makefile for the SH2000 specific parts of the kernel
3#
4
5obj-y := setup.o
6
diff --git a/arch/sh/boards/sh2000/setup.c b/arch/sh/boards/sh2000/setup.c
deleted file mode 100644
index 2fe6a11765e9..000000000000
--- a/arch/sh/boards/sh2000/setup.c
+++ /dev/null
@@ -1,70 +0,0 @@
1/*
2 * linux/arch/sh/kernel/setup_sh2000.c
3 *
4 * Copyright (C) 2001 SUGIOKA Tochinobu
5 *
6 * SH-2000 Support.
7 *
8 */
9
10#include <linux/init.h>
11#include <linux/irq.h>
12
13#include <asm/io.h>
14#include <asm/machvec.h>
15#include <asm/mach/sh2000.h>
16
17#define CF_CIS_BASE 0xb4200000
18
19#define PORT_PECR 0xa4000108
20#define PORT_PHCR 0xa400010E
21#define PORT_ICR1 0xa4000010
22#define PORT_IRR0 0xa4000004
23
24#define IDE_OFFSET 0xb6200000
25#define NIC_OFFSET 0xb6000000
26#define EXTBUS_OFFSET 0xba000000
27
28
29const char *get_system_type(void)
30{
31 return "sh2000";
32}
33
34static unsigned long sh2000_isa_port2addr(unsigned long offset)
35{
36 if((offset & ~7) == 0x1f0 || offset == 0x3f6)
37 return IDE_OFFSET + offset;
38 else if((offset & ~0x1f) == 0x300)
39 return NIC_OFFSET + offset;
40 return EXTBUS_OFFSET + offset;
41}
42
43/*
44 * The Machine Vector
45 */
46struct sh_machine_vector mv_sh2000 __initmv = {
47 .mv_nr_irqs = 80,
48 .mv_isa_port2addr = sh2000_isa_port2addr,
49};
50ALIAS_MV(sh2000)
51
52/*
53 * Initialize the board
54 */
55int __init platform_setup(void)
56{
57 /* XXX: RTC setting comes here */
58
59 /* These should be done by BIOS/IPL ... */
60 /* Enable nCE2A, nCE2B output */
61 ctrl_outw(ctrl_inw(PORT_PECR) & ~0xf00, PORT_PECR);
62 /* Enable the Compact Flash card, and set the level interrupt */
63 ctrl_outw(0x0042, CF_CIS_BASE+0x0200);
64 /* Enable interrupt */
65 ctrl_outw(ctrl_inw(PORT_PHCR) & ~0x03f3, PORT_PHCR);
66 ctrl_outw(1, PORT_ICR1);
67 ctrl_outw(ctrl_inw(PORT_IRR0) & ~0xff3f, PORT_IRR0);
68 printk(KERN_INFO "SH-2000 Setup...done\n");
69 return 0;
70}
diff --git a/arch/sh/boards/shmin/Makefile b/arch/sh/boards/shmin/Makefile
new file mode 100644
index 000000000000..3190cc72430e
--- /dev/null
+++ b/arch/sh/boards/shmin/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for the SHMIN board.
3#
4
5obj-y := setup.o
diff --git a/arch/sh/boards/shmin/setup.c b/arch/sh/boards/shmin/setup.c
new file mode 100644
index 000000000000..2f0c19706cf9
--- /dev/null
+++ b/arch/sh/boards/shmin/setup.c
@@ -0,0 +1,41 @@
1/*
2 * arch/sh/boards/shmin/setup.c
3 *
4 * Copyright (C) 2006 Takashi YOSHII
5 *
6 * SHMIN Support.
7 */
8#include <linux/init.h>
9#include <asm/machvec.h>
10#include <asm/shmin/shmin.h>
11#include <asm/clock.h>
12#include <asm/irq.h>
13#include <asm/io.h>
14
15#define PFC_PHCR 0xa400010e
16
17static void __init init_shmin_irq(void)
18{
19 ctrl_outw(0x2a00, PFC_PHCR); // IRQ0-3=IRQ
20 ctrl_outw(0x0aaa, INTC_ICR1); // IRQ0-3=IRQ-mode,Low-active.
21}
22
23static void __iomem *shmin_ioport_map(unsigned long port, unsigned int size)
24{
25 static int dummy;
26
27 if ((port & ~0x1f) == SHMIN_NE_BASE)
28 return (void __iomem *)(SHMIN_IO_BASE + port);
29
30 dummy = 0;
31
32 return &dummy;
33
34}
35
36struct sh_machine_vector mv_shmin __initmv = {
37 .mv_name = "SHMIN",
38 .mv_init_irq = init_shmin_irq,
39 .mv_ioport_map = shmin_ioport_map,
40};
41ALIAS_MV(shmin)
diff --git a/arch/sh/boards/snapgear/io.c b/arch/sh/boards/snapgear/io.c
index e2eb78fc381d..0f4824264557 100644
--- a/arch/sh/boards/snapgear/io.c
+++ b/arch/sh/boards/snapgear/io.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * linux/arch/sh/kernel/io_7751se.c
3 *
4 * Copyright (C) 2002 David McCullough <davidm@snapgear.com> 2 * Copyright (C) 2002 David McCullough <davidm@snapgear.com>
5 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel 3 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel
6 * Based largely on io_se.c. 4 * Based largely on io_se.c.
@@ -11,67 +9,22 @@
11 * placeholder code from io_se.c left in with the 9 * placeholder code from io_se.c left in with the
12 * expectation of later SuperIO and PCMCIA access. 10 * expectation of later SuperIO and PCMCIA access.
13 */ 11 */
14
15#include <linux/kernel.h> 12#include <linux/kernel.h>
16#include <linux/types.h> 13#include <linux/types.h>
17#include <linux/pci.h> 14#include <linux/pci.h>
18#include <asm/io.h> 15#include <asm/io.h>
19#include <asm/addrspace.h> 16#include <asm/addrspace.h>
20 17
21#include <asm/pci.h>
22#include "../../drivers/pci/pci-sh7751.h"
23
24#ifdef CONFIG_SH_SECUREEDGE5410 18#ifdef CONFIG_SH_SECUREEDGE5410
25unsigned short secureedge5410_ioport; 19unsigned short secureedge5410_ioport;
26#endif 20#endif
27 21
28/*
29 * The SnapGear uses the built-in PCI controller (PCIC)
30 * of the 7751 processor
31 */
32
33#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR)
34#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR)
35#define PCI_IO_AREA SH7751_PCI_IO_BASE
36#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE
37
38
39#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK))
40
41
42#define maybebadio(name,port) \
43 printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \
44 #name, (port), (__u32) __builtin_return_address(0))
45
46
47static inline void delay(void)
48{
49 ctrl_inw(0xa0000000);
50}
51
52
53static inline volatile __u16 *port2adr(unsigned int port) 22static inline volatile __u16 *port2adr(unsigned int port)
54{ 23{
55#if 0 24 maybebadio((unsigned long)port);
56 if (port >= 0x2000)
57 return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000));
58#endif
59 maybebadio(name,(unsigned long)port);
60 return (volatile __u16*)port; 25 return (volatile __u16*)port;
61} 26}
62 27
63
64/* In case someone configures the kernel w/o PCI support: in that */
65/* scenario, don't ever bother to check for PCI-window addresses */
66
67/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */
68#if defined(CONFIG_PCI)
69#define CHECK_SH7751_PCIIO(port) \
70 ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE)))
71#else
72#define CHECK_SH7751_PCIIO(port) (0)
73#endif
74
75/* 28/*
76 * General outline: remap really low stuff [eventually] to SuperIO, 29 * General outline: remap really low stuff [eventually] to SuperIO,
77 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) 30 * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO)
@@ -79,148 +32,106 @@ static inline volatile __u16 *port2adr(unsigned int port)
79 * should be way beyond the window, and is used w/o translation for 32 * should be way beyond the window, and is used w/o translation for
80 * compatibility. 33 * compatibility.
81 */ 34 */
82
83unsigned char snapgear_inb(unsigned long port) 35unsigned char snapgear_inb(unsigned long port)
84{ 36{
85 if (PXSEG(port)) 37 if (PXSEG(port))
86 return *(volatile unsigned char *)port; 38 return *(volatile unsigned char *)port;
87 else if (CHECK_SH7751_PCIIO(port)) 39 else if (is_pci_ioaddr(port))
88 return *(volatile unsigned char *)PCI_IOMAP(port); 40 return *(volatile unsigned char *)pci_ioaddr(port);
89 else 41 else
90 return (*port2adr(port))&0xff; 42 return (*port2adr(port)) & 0xff;
91} 43}
92 44
93
94unsigned char snapgear_inb_p(unsigned long port) 45unsigned char snapgear_inb_p(unsigned long port)
95{ 46{
96 unsigned char v; 47 unsigned char v;
97 48
98 if (PXSEG(port)) 49 if (PXSEG(port))
99 v = *(volatile unsigned char *)port; 50 v = *(volatile unsigned char *)port;
100 else if (CHECK_SH7751_PCIIO(port)) 51 else if (is_pci_ioaddr(port))
101 v = *(volatile unsigned char *)PCI_IOMAP(port); 52 v = *(volatile unsigned char *)pci_ioaddr(port);
102 else 53 else
103 v = (*port2adr(port))&0xff; 54 v = (*port2adr(port))&0xff;
104 delay(); 55 ctrl_delay();
105 return v; 56 return v;
106} 57}
107 58
108
109unsigned short snapgear_inw(unsigned long port) 59unsigned short snapgear_inw(unsigned long port)
110{ 60{
111 if (PXSEG(port)) 61 if (PXSEG(port))
112 return *(volatile unsigned short *)port; 62 return *(volatile unsigned short *)port;
113 else if (CHECK_SH7751_PCIIO(port)) 63 else if (is_pci_ioaddr(port))
114 return *(volatile unsigned short *)PCI_IOMAP(port); 64 return *(volatile unsigned short *)pci_ioaddr(port);
115 else if (port >= 0x2000) 65 else if (port >= 0x2000)
116 return *port2adr(port); 66 return *port2adr(port);
117 else 67 else
118 maybebadio(inw, port); 68 maybebadio(port);
119 return 0; 69 return 0;
120} 70}
121 71
122
123unsigned int snapgear_inl(unsigned long port) 72unsigned int snapgear_inl(unsigned long port)
124{ 73{
125 if (PXSEG(port)) 74 if (PXSEG(port))
126 return *(volatile unsigned long *)port; 75 return *(volatile unsigned long *)port;
127 else if (CHECK_SH7751_PCIIO(port)) 76 else if (is_pci_ioaddr(port))
128 return *(volatile unsigned int *)PCI_IOMAP(port); 77 return *(volatile unsigned int *)pci_ioaddr(port);
129 else if (port >= 0x2000) 78 else if (port >= 0x2000)
130 return *port2adr(port); 79 return *port2adr(port);
131 else 80 else
132 maybebadio(inl, port); 81 maybebadio(port);
133 return 0; 82 return 0;
134} 83}
135 84
136
137void snapgear_outb(unsigned char value, unsigned long port) 85void snapgear_outb(unsigned char value, unsigned long port)
138{ 86{
139 87
140 if (PXSEG(port)) 88 if (PXSEG(port))
141 *(volatile unsigned char *)port = value; 89 *(volatile unsigned char *)port = value;
142 else if (CHECK_SH7751_PCIIO(port)) 90 else if (is_pci_ioaddr(port))
143 *((unsigned char*)PCI_IOMAP(port)) = value; 91 *((unsigned char*)pci_ioaddr(port)) = value;
144 else 92 else
145 *(port2adr(port)) = value; 93 *(port2adr(port)) = value;
146} 94}
147 95
148
149void snapgear_outb_p(unsigned char value, unsigned long port) 96void snapgear_outb_p(unsigned char value, unsigned long port)
150{ 97{
151 if (PXSEG(port)) 98 if (PXSEG(port))
152 *(volatile unsigned char *)port = value; 99 *(volatile unsigned char *)port = value;
153 else if (CHECK_SH7751_PCIIO(port)) 100 else if (is_pci_ioaddr(port))
154 *((unsigned char*)PCI_IOMAP(port)) = value; 101 *((unsigned char*)pci_ioaddr(port)) = value;
155 else 102 else
156 *(port2adr(port)) = value; 103 *(port2adr(port)) = value;
157 delay(); 104 ctrl_delay();
158} 105}
159 106
160
161void snapgear_outw(unsigned short value, unsigned long port) 107void snapgear_outw(unsigned short value, unsigned long port)
162{ 108{
163 if (PXSEG(port)) 109 if (PXSEG(port))
164 *(volatile unsigned short *)port = value; 110 *(volatile unsigned short *)port = value;
165 else if (CHECK_SH7751_PCIIO(port)) 111 else if (is_pci_ioaddr(port))
166 *((unsigned short *)PCI_IOMAP(port)) = value; 112 *((unsigned short *)pci_ioaddr(port)) = value;
167 else if (port >= 0x2000) 113 else if (port >= 0x2000)
168 *port2adr(port) = value; 114 *port2adr(port) = value;
169 else 115 else
170 maybebadio(outw, port); 116 maybebadio(port);
171} 117}
172 118
173
174void snapgear_outl(unsigned int value, unsigned long port) 119void snapgear_outl(unsigned int value, unsigned long port)
175{ 120{
176 if (PXSEG(port)) 121 if (PXSEG(port))
177 *(volatile unsigned long *)port = value; 122 *(volatile unsigned long *)port = value;
178 else if (CHECK_SH7751_PCIIO(port)) 123 else if (is_pci_ioaddr(port))
179 *((unsigned long*)PCI_IOMAP(port)) = value; 124 *((unsigned long*)pci_ioaddr(port)) = value;
180 else 125 else
181 maybebadio(outl, port); 126 maybebadio(port);
182} 127}
183 128
184void snapgear_insl(unsigned long port, void *addr, unsigned long count) 129void snapgear_insl(unsigned long port, void *addr, unsigned long count)
185{ 130{
186 maybebadio(insl, port); 131 maybebadio(port);
187} 132}
188 133
189void snapgear_outsl(unsigned long port, const void *addr, unsigned long count) 134void snapgear_outsl(unsigned long port, const void *addr, unsigned long count)
190{ 135{
191 maybebadio(outsw, port); 136 maybebadio(port);
192}
193
194/* Map ISA bus address to the real address. Only for PCMCIA. */
195
196
197/* ISA page descriptor. */
198static __u32 sh_isa_memmap[256];
199
200
201#if 0
202static int sh_isa_mmap(__u32 start, __u32 length, __u32 offset)
203{
204 int idx;
205
206 if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000))
207 return -1;
208
209 idx = start >> 12;
210 sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff);
211#if 0
212 printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n",
213 start, length, offset, idx, sh_isa_memmap[idx]);
214#endif
215 return 0;
216}
217#endif
218
219unsigned long snapgear_isa_port2addr(unsigned long offset)
220{
221 int idx;
222
223 idx = (offset >> 12) & 0xff;
224 offset &= 0xfff;
225 return sh_isa_memmap[idx] + offset;
226} 137}
diff --git a/arch/sh/boards/snapgear/rtc.c b/arch/sh/boards/snapgear/rtc.c
index b71e009da35c..1659fdd6695a 100644
--- a/arch/sh/boards/snapgear/rtc.c
+++ b/arch/sh/boards/snapgear/rtc.c
@@ -17,14 +17,9 @@
17#include <linux/time.h> 17#include <linux/time.h>
18#include <linux/rtc.h> 18#include <linux/rtc.h>
19#include <linux/mc146818rtc.h> 19#include <linux/mc146818rtc.h>
20
21#include <asm/io.h> 20#include <asm/io.h>
22#include <asm/rtc.h>
23#include <asm/mc146818rtc.h>
24
25/****************************************************************************/
26 21
27static int use_ds1302 = 0; 22static int use_ds1302;
28 23
29/****************************************************************************/ 24/****************************************************************************/
30/* 25/*
@@ -82,10 +77,6 @@ static unsigned int ds1302_readbyte(unsigned int addr)
82 unsigned int val; 77 unsigned int val;
83 unsigned long flags; 78 unsigned long flags;
84 79
85#if 0
86 printk("SnapGear RTC: ds1302_readbyte(addr=%x)\n", addr);
87#endif
88
89 local_irq_save(flags); 80 local_irq_save(flags);
90 set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK); 81 set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK);
91 set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); 82 set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
@@ -104,10 +95,6 @@ static void ds1302_writebyte(unsigned int addr, unsigned int val)
104{ 95{
105 unsigned long flags; 96 unsigned long flags;
106 97
107#if 0
108 printk("SnapGear RTC: ds1302_writebyte(addr=%x)\n", addr);
109#endif
110
111 local_irq_save(flags); 98 local_irq_save(flags);
112 set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK); 99 set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK);
113 set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); 100 set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
@@ -168,11 +155,8 @@ void __init secureedge5410_rtc_init(void)
168 } 155 }
169 156
170 if (use_ds1302) { 157 if (use_ds1302) {
171 rtc_get_time = snapgear_rtc_gettimeofday; 158 rtc_sh_get_time = snapgear_rtc_gettimeofday;
172 rtc_set_time = snapgear_rtc_settimeofday; 159 rtc_sh_set_time = snapgear_rtc_settimeofday;
173 } else {
174 rtc_get_time = sh_rtc_gettimeofday;
175 rtc_set_time = sh_rtc_settimeofday;
176 } 160 }
177 161
178 printk("SnapGear RTC: using %s rtc.\n", use_ds1302 ? "ds1302" : "internal"); 162 printk("SnapGear RTC: using %s rtc.\n", use_ds1302 ? "ds1302" : "internal");
@@ -187,10 +171,8 @@ void snapgear_rtc_gettimeofday(struct timespec *ts)
187{ 171{
188 unsigned int sec, min, hr, day, mon, yr; 172 unsigned int sec, min, hr, day, mon, yr;
189 173
190 if (!use_ds1302) { 174 if (!use_ds1302)
191 sh_rtc_gettimeofday(ts);
192 return; 175 return;
193 }
194 176
195 sec = bcd2int(ds1302_readbyte(RTC_ADDR_SEC)); 177 sec = bcd2int(ds1302_readbyte(RTC_ADDR_SEC));
196 min = bcd2int(ds1302_readbyte(RTC_ADDR_MIN)); 178 min = bcd2int(ds1302_readbyte(RTC_ADDR_MIN));
@@ -231,7 +213,7 @@ int snapgear_rtc_settimeofday(const time_t secs)
231 unsigned long nowtime; 213 unsigned long nowtime;
232 214
233 if (!use_ds1302) 215 if (!use_ds1302)
234 return sh_rtc_settimeofday(secs); 216 return 0;
235 217
236/* 218/*
237 * This is called direct from the kernel timer handling code. 219 * This is called direct from the kernel timer handling code.
@@ -240,10 +222,6 @@ int snapgear_rtc_settimeofday(const time_t secs)
240 222
241 nowtime = secs; 223 nowtime = secs;
242 224
243#if 1
244 printk("SnapGear RTC: snapgear_rtc_settimeofday(nowtime=%ld)\n", nowtime);
245#endif
246
247 /* STOP RTC */ 225 /* STOP RTC */
248 ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80); 226 ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80);
249 227
@@ -329,5 +307,3 @@ void secureedge5410_cmos_write(unsigned char val, int addr)
329 default: break; 307 default: break;
330 } 308 }
331} 309}
332
333/****************************************************************************/
diff --git a/arch/sh/boards/snapgear/setup.c b/arch/sh/boards/snapgear/setup.c
index f1f7c70c9402..f5e98c56b530 100644
--- a/arch/sh/boards/snapgear/setup.c
+++ b/arch/sh/boards/snapgear/setup.c
@@ -1,5 +1,4 @@
1/****************************************************************************/ 1/*
2/*
3 * linux/arch/sh/boards/snapgear/setup.c 2 * linux/arch/sh/boards/snapgear/setup.c
4 * 3 *
5 * Copyright (C) 2002 David McCullough <davidm@snapgear.com> 4 * Copyright (C) 2002 David McCullough <davidm@snapgear.com>
@@ -12,8 +11,6 @@
12 * Modified for 7751 Solution Engine by 11 * Modified for 7751 Solution Engine by
13 * Ian da Silva and Jeremy Siegel, 2001. 12 * Ian da Silva and Jeremy Siegel, 2001.
14 */ 13 */
15/****************************************************************************/
16
17#include <linux/init.h> 14#include <linux/init.h>
18#include <linux/irq.h> 15#include <linux/irq.h>
19#include <linux/interrupt.h> 16#include <linux/interrupt.h>
@@ -21,14 +18,13 @@
21#include <linux/delay.h> 18#include <linux/delay.h>
22#include <linux/module.h> 19#include <linux/module.h>
23#include <linux/sched.h> 20#include <linux/sched.h>
24
25#include <asm/machvec.h> 21#include <asm/machvec.h>
26#include <asm/mach/io.h> 22#include <asm/snapgear.h>
27#include <asm/irq.h> 23#include <asm/irq.h>
28#include <asm/io.h> 24#include <asm/io.h>
25#include <asm/rtc.h>
29#include <asm/cpu/timer.h> 26#include <asm/cpu/timer.h>
30 27
31extern void (*board_time_init)(void);
32extern void secureedge5410_rtc_init(void); 28extern void secureedge5410_rtc_init(void);
33extern void pcibios_init(void); 29extern void pcibios_init(void);
34 30
@@ -85,101 +81,20 @@ static void __init init_snapgear_IRQ(void)
85 make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY); 81 make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY);
86} 82}
87 83
88/****************************************************************************/
89/*
90 * Fast poll interrupt simulator.
91 */
92
93/* 84/*
94 * Leave all of the fast timer/fast poll stuff commented out for now, since 85 * Initialize the board
95 * it's not clear whether it actually works or not. Since it wasn't being used
96 * at all in 2.4, we'll assume it's not sane for 2.6 either.. -- PFM
97 */
98#if 0
99#define FAST_POLL 1000
100//#define FAST_POLL_INTR
101
102#define FASTTIMER_IRQ 17
103#define FASTTIMER_IPR_ADDR INTC_IPRA
104#define FASTTIMER_IPR_POS 2
105#define FASTTIMER_PRIORITY 3
106
107#ifdef FAST_POLL_INTR
108#define TMU1_TCR_INIT 0x0020
109#else
110#define TMU1_TCR_INIT 0
111#endif
112#define TMU_TSTR_INIT 1
113#define TMU1_TCR_CALIB 0x0000
114
115
116#ifdef FAST_POLL_INTR
117static void fast_timer_irq(int irq, void *dev_instance, struct pt_regs *regs)
118{
119 unsigned long timer_status;
120 timer_status = ctrl_inw(TMU1_TCR);
121 timer_status &= ~0x100;
122 ctrl_outw(timer_status, TMU1_TCR);
123}
124#endif
125
126/*
127 * return the current ticks on the fast timer
128 */
129
130unsigned long fast_timer_count(void)
131{
132 return(ctrl_inl(TMU1_TCNT));
133}
134
135/*
136 * setup a fast timer for profiling etc etc
137 */ 86 */
138 87static void __init snapgear_setup(char **cmdline_p)
139static void setup_fast_timer()
140{
141 unsigned long interval;
142
143#ifdef FAST_POLL_INTR
144 interval = (current_cpu_data.module_clock/4 + FAST_POLL/2) / FAST_POLL;
145
146 make_ipr_irq(FASTTIMER_IRQ, FASTTIMER_IPR_ADDR, FASTTIMER_IPR_POS,
147 FASTTIMER_PRIORITY);
148
149 printk("SnapGear: %dHz fast timer on IRQ %d\n",FAST_POLL,FASTTIMER_IRQ);
150
151 if (request_irq(FASTTIMER_IRQ, fast_timer_irq, 0, "SnapGear fast timer",
152 NULL) != 0)
153 printk("%s(%d): request_irq() failed?\n", __FILE__, __LINE__);
154#else
155 printk("SnapGear: fast timer running\n",FAST_POLL,FASTTIMER_IRQ);
156 interval = 0xffffffff;
157#endif
158
159 ctrl_outb(ctrl_inb(TMU_TSTR) & ~0x2, TMU_TSTR); /* disable timer 1 */
160 ctrl_outw(TMU1_TCR_INIT, TMU1_TCR);
161 ctrl_outl(interval, TMU1_TCOR);
162 ctrl_outl(interval, TMU1_TCNT);
163 ctrl_outb(ctrl_inb(TMU_TSTR) | 0x2, TMU_TSTR); /* enable timer 1 */
164
165 printk("Timer count 1 = 0x%x\n", fast_timer_count());
166 udelay(1000);
167 printk("Timer count 2 = 0x%x\n", fast_timer_count());
168}
169#endif
170
171/****************************************************************************/
172
173const char *get_system_type(void)
174{ 88{
175 return "SnapGear SecureEdge5410"; 89 board_time_init = secureedge5410_rtc_init;
176} 90}
177 91
178/* 92/*
179 * The Machine Vector 93 * The Machine Vector
180 */ 94 */
181
182struct sh_machine_vector mv_snapgear __initmv = { 95struct sh_machine_vector mv_snapgear __initmv = {
96 .mv_name = "SnapGear SecureEdge5410",
97 .mv_setup = snapgear_setup,
183 .mv_nr_irqs = 72, 98 .mv_nr_irqs = 72,
184 99
185 .mv_inb = snapgear_inb, 100 .mv_inb = snapgear_inb,
@@ -196,20 +111,6 @@ struct sh_machine_vector mv_snapgear __initmv = {
196 .mv_outw_p = snapgear_outw, 111 .mv_outw_p = snapgear_outw,
197 .mv_outl_p = snapgear_outl, 112 .mv_outl_p = snapgear_outl,
198 113
199 .mv_isa_port2addr = snapgear_isa_port2addr,
200
201 .mv_init_irq = init_snapgear_IRQ, 114 .mv_init_irq = init_snapgear_IRQ,
202}; 115};
203ALIAS_MV(snapgear) 116ALIAS_MV(snapgear)
204
205/*
206 * Initialize the board
207 */
208
209int __init platform_setup(void)
210{
211 board_time_init = secureedge5410_rtc_init;
212
213 return 0;
214}
215
diff --git a/arch/sh/boards/superh/microdev/irq.c b/arch/sh/boards/superh/microdev/irq.c
index 236398fbc083..8c64baa30364 100644
--- a/arch/sh/boards/superh/microdev/irq.c
+++ b/arch/sh/boards/superh/microdev/irq.c
@@ -11,14 +11,12 @@
11 11
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/irq.h> 13#include <linux/irq.h>
14
15#include <asm/system.h> 14#include <asm/system.h>
16#include <asm/io.h> 15#include <asm/io.h>
17#include <asm/microdev.h> 16#include <asm/microdev.h>
18 17
19#define NUM_EXTERNAL_IRQS 16 /* IRL0 .. IRL15 */ 18#define NUM_EXTERNAL_IRQS 16 /* IRL0 .. IRL15 */
20 19
21
22static const struct { 20static const struct {
23 unsigned char fpgaIrq; 21 unsigned char fpgaIrq;
24 unsigned char mapped; 22 unsigned char mapped;
@@ -93,53 +91,42 @@ static struct hw_interrupt_type microdev_irq_type = {
93 91
94static void disable_microdev_irq(unsigned int irq) 92static void disable_microdev_irq(unsigned int irq)
95{ 93{
96 unsigned int flags;
97 unsigned int fpgaIrq; 94 unsigned int fpgaIrq;
98 95
99 if (irq >= NUM_EXTERNAL_IRQS) return; 96 if (irq >= NUM_EXTERNAL_IRQS)
100 if (!fpgaIrqTable[irq].mapped) return; 97 return;
98 if (!fpgaIrqTable[irq].mapped)
99 return;
101 100
102 fpgaIrq = fpgaIrqTable[irq].fpgaIrq; 101 fpgaIrq = fpgaIrqTable[irq].fpgaIrq;
103 102
104 /* disable interrupts */ 103 /* disable interupts on the FPGA INTC register */
105 local_irq_save(flags);
106
107 /* disable interupts on the FPGA INTC register */
108 ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG); 104 ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG);
109
110 /* restore interrupts */
111 local_irq_restore(flags);
112} 105}
113 106
114static void enable_microdev_irq(unsigned int irq) 107static void enable_microdev_irq(unsigned int irq)
115{ 108{
116 unsigned long priorityReg, priorities, pri; 109 unsigned long priorityReg, priorities, pri;
117 unsigned int flags;
118 unsigned int fpgaIrq; 110 unsigned int fpgaIrq;
119 111
120 112 if (unlikely(irq >= NUM_EXTERNAL_IRQS))
121 if (irq >= NUM_EXTERNAL_IRQS) return; 113 return;
122 if (!fpgaIrqTable[irq].mapped) return; 114 if (unlikely(!fpgaIrqTable[irq].mapped))
115 return;
123 116
124 pri = 15 - irq; 117 pri = 15 - irq;
125 118
126 fpgaIrq = fpgaIrqTable[irq].fpgaIrq; 119 fpgaIrq = fpgaIrqTable[irq].fpgaIrq;
127 priorityReg = MICRODEV_FPGA_INTPRI_REG(fpgaIrq); 120 priorityReg = MICRODEV_FPGA_INTPRI_REG(fpgaIrq);
128 121
129 /* disable interrupts */ 122 /* set priority for the interrupt */
130 local_irq_save(flags);
131
132 /* set priority for the interrupt */
133 priorities = ctrl_inl(priorityReg); 123 priorities = ctrl_inl(priorityReg);
134 priorities &= ~MICRODEV_FPGA_INTPRI_MASK(fpgaIrq); 124 priorities &= ~MICRODEV_FPGA_INTPRI_MASK(fpgaIrq);
135 priorities |= MICRODEV_FPGA_INTPRI_LEVEL(fpgaIrq, pri); 125 priorities |= MICRODEV_FPGA_INTPRI_LEVEL(fpgaIrq, pri);
136 ctrl_outl(priorities, priorityReg); 126 ctrl_outl(priorities, priorityReg);
137 127
138 /* enable interupts on the FPGA INTC register */ 128 /* enable interupts on the FPGA INTC register */
139 ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG); 129 ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG);
140
141 /* restore interrupts */
142 local_irq_restore(flags);
143} 130}
144 131
145 /* This functions sets the desired irq handler to be a MicroDev type */ 132 /* This functions sets the desired irq handler to be a MicroDev type */
@@ -158,9 +145,7 @@ static void mask_and_ack_microdev(unsigned int irq)
158static void end_microdev_irq(unsigned int irq) 145static void end_microdev_irq(unsigned int irq)
159{ 146{
160 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) 147 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
161 {
162 enable_microdev_irq(irq); 148 enable_microdev_irq(irq);
163 }
164} 149}
165 150
166extern void __init init_microdev_irq(void) 151extern void __init init_microdev_irq(void)
@@ -171,9 +156,7 @@ extern void __init init_microdev_irq(void)
171 ctrl_outl(~0ul, MICRODEV_FPGA_INTDSB_REG); 156 ctrl_outl(~0ul, MICRODEV_FPGA_INTDSB_REG);
172 157
173 for (i = 0; i < NUM_EXTERNAL_IRQS; i++) 158 for (i = 0; i < NUM_EXTERNAL_IRQS; i++)
174 {
175 make_microdev_irq(i); 159 make_microdev_irq(i);
176 }
177} 160}
178 161
179extern void microdev_print_fpga_intc_status(void) 162extern void microdev_print_fpga_intc_status(void)
diff --git a/arch/sh/boards/superh/microdev/setup.c b/arch/sh/boards/superh/microdev/setup.c
index 61b402a3f5d7..031c814e6e76 100644
--- a/arch/sh/boards/superh/microdev/setup.c
+++ b/arch/sh/boards/superh/microdev/setup.c
@@ -10,7 +10,6 @@
10 * May be copied or modified under the terms of the GNU General Public 10 * May be copied or modified under the terms of the GNU General Public
11 * License. See linux/COPYING for more information. 11 * License. See linux/COPYING for more information.
12 */ 12 */
13
14#include <linux/init.h> 13#include <linux/init.h>
15#include <linux/platform_device.h> 14#include <linux/platform_device.h>
16#include <linux/ioport.h> 15#include <linux/ioport.h>
@@ -21,41 +20,6 @@
21 20
22extern void microdev_heartbeat(void); 21extern void microdev_heartbeat(void);
23 22
24/*
25 * The Machine Vector
26 */
27
28struct sh_machine_vector mv_sh4202_microdev __initmv = {
29 .mv_nr_irqs = 72, /* QQQ need to check this - use the MACRO */
30
31 .mv_inb = microdev_inb,
32 .mv_inw = microdev_inw,
33 .mv_inl = microdev_inl,
34 .mv_outb = microdev_outb,
35 .mv_outw = microdev_outw,
36 .mv_outl = microdev_outl,
37
38 .mv_inb_p = microdev_inb_p,
39 .mv_inw_p = microdev_inw_p,
40 .mv_inl_p = microdev_inl_p,
41 .mv_outb_p = microdev_outb_p,
42 .mv_outw_p = microdev_outw_p,
43 .mv_outl_p = microdev_outl_p,
44
45 .mv_insb = microdev_insb,
46 .mv_insw = microdev_insw,
47 .mv_insl = microdev_insl,
48 .mv_outsb = microdev_outsb,
49 .mv_outsw = microdev_outsw,
50 .mv_outsl = microdev_outsl,
51
52 .mv_init_irq = init_microdev_irq,
53
54#ifdef CONFIG_HEARTBEAT
55 .mv_heartbeat = microdev_heartbeat,
56#endif
57};
58ALIAS_MV(sh4202_microdev)
59 23
60/****************************************************************************/ 24/****************************************************************************/
61 25
@@ -113,11 +77,6 @@ ALIAS_MV(sh4202_microdev)
113 /* assume a Keyboard Controller is present */ 77 /* assume a Keyboard Controller is present */
114int microdev_kbd_controller_present = 1; 78int microdev_kbd_controller_present = 1;
115 79
116const char *get_system_type(void)
117{
118 return "SH4-202 MicroDev";
119}
120
121static struct resource smc91x_resources[] = { 80static struct resource smc91x_resources[] = {
122 [0] = { 81 [0] = {
123 .start = 0x300, 82 .start = 0x300,
@@ -291,25 +250,9 @@ static int __init microdev_devices_setup(void)
291 return platform_add_devices(microdev_devices, ARRAY_SIZE(microdev_devices)); 250 return platform_add_devices(microdev_devices, ARRAY_SIZE(microdev_devices));
292} 251}
293 252
294__initcall(microdev_devices_setup); 253/*
295 254 * Setup for the SMSC FDC37C93xAPM
296void __init platform_setup(void) 255 */
297{
298 int * const fpgaRevisionRegister = (int*)(MICRODEV_FPGA_GP_BASE + 0x8ul);
299 const int fpgaRevision = *fpgaRevisionRegister;
300 int * const CacheControlRegister = (int*)CCR;
301
302 printk("SuperH %s board (FPGA rev: 0x%0x, CCR: 0x%0x)\n",
303 get_system_type(), fpgaRevision, *CacheControlRegister);
304}
305
306
307/****************************************************************************/
308
309
310 /*
311 * Setup for the SMSC FDC37C93xAPM
312 */
313static int __init smsc_superio_setup(void) 256static int __init smsc_superio_setup(void)
314{ 257{
315 258
@@ -412,8 +355,52 @@ static int __init smsc_superio_setup(void)
412 return 0; 355 return 0;
413} 356}
414 357
358static void __init microdev_setup(char **cmdline_p)
359{
360 int * const fpgaRevisionRegister = (int*)(MICRODEV_FPGA_GP_BASE + 0x8ul);
361 const int fpgaRevision = *fpgaRevisionRegister;
362 int * const CacheControlRegister = (int*)CCR;
363
364 device_initcall(microdev_devices_setup);
365 device_initcall(smsc_superio_setup);
415 366
416/* This is grotty, but, because kernel is always referenced on the link line 367 printk("SuperH %s board (FPGA rev: 0x%0x, CCR: 0x%0x)\n",
417 * before any devices, this is safe. 368 get_system_type(), fpgaRevision, *CacheControlRegister);
369}
370
371/*
372 * The Machine Vector
418 */ 373 */
419__initcall(smsc_superio_setup); 374struct sh_machine_vector mv_sh4202_microdev __initmv = {
375 .mv_name = "SH4-202 MicroDev",
376 .mv_setup = microdev_setup,
377 .mv_nr_irqs = 72, /* QQQ need to check this - use the MACRO */
378
379 .mv_inb = microdev_inb,
380 .mv_inw = microdev_inw,
381 .mv_inl = microdev_inl,
382 .mv_outb = microdev_outb,
383 .mv_outw = microdev_outw,
384 .mv_outl = microdev_outl,
385
386 .mv_inb_p = microdev_inb_p,
387 .mv_inw_p = microdev_inw_p,
388 .mv_inl_p = microdev_inl_p,
389 .mv_outb_p = microdev_outb_p,
390 .mv_outw_p = microdev_outw_p,
391 .mv_outl_p = microdev_outl_p,
392
393 .mv_insb = microdev_insb,
394 .mv_insw = microdev_insw,
395 .mv_insl = microdev_insl,
396 .mv_outsb = microdev_outsb,
397 .mv_outsw = microdev_outsw,
398 .mv_outsl = microdev_outsl,
399
400 .mv_init_irq = init_microdev_irq,
401
402#ifdef CONFIG_HEARTBEAT
403 .mv_heartbeat = microdev_heartbeat,
404#endif
405};
406ALIAS_MV(sh4202_microdev)
diff --git a/arch/sh/boards/titan/Makefile b/arch/sh/boards/titan/Makefile
new file mode 100644
index 000000000000..08d753700062
--- /dev/null
+++ b/arch/sh/boards/titan/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for the Nimble Microsystems TITAN specific parts of the kernel
3#
4
5obj-y := setup.o io.o
diff --git a/arch/sh/boards/titan/io.c b/arch/sh/boards/titan/io.c
new file mode 100644
index 000000000000..4730c1dd697d
--- /dev/null
+++ b/arch/sh/boards/titan/io.c
@@ -0,0 +1,126 @@
1/*
2 * I/O routines for Titan
3 */
4#include <linux/pci.h>
5#include <asm/machvec.h>
6#include <asm/addrspace.h>
7#include <asm/titan.h>
8#include <asm/io.h>
9
10static inline unsigned int port2adr(unsigned int port)
11{
12 maybebadio((unsigned long)port);
13 return port;
14}
15
16u8 titan_inb(unsigned long port)
17{
18 if (PXSEG(port))
19 return ctrl_inb(port);
20 else if (is_pci_ioaddr(port))
21 return ctrl_inb(pci_ioaddr(port));
22 return ctrl_inw(port2adr(port)) & 0xff;
23}
24
25u8 titan_inb_p(unsigned long port)
26{
27 u8 v;
28
29 if (PXSEG(port))
30 v = ctrl_inb(port);
31 else if (is_pci_ioaddr(port))
32 v = ctrl_inb(pci_ioaddr(port));
33 else
34 v = ctrl_inw(port2adr(port)) & 0xff;
35 ctrl_delay();
36 return v;
37}
38
39u16 titan_inw(unsigned long port)
40{
41 if (PXSEG(port))
42 return ctrl_inw(port);
43 else if (is_pci_ioaddr(port))
44 return ctrl_inw(pci_ioaddr(port));
45 else if (port >= 0x2000)
46 return ctrl_inw(port2adr(port));
47 else
48 maybebadio(port);
49 return 0;
50}
51
52u32 titan_inl(unsigned long port)
53{
54 if (PXSEG(port))
55 return ctrl_inl(port);
56 else if (is_pci_ioaddr(port))
57 return ctrl_inl(pci_ioaddr(port));
58 else if (port >= 0x2000)
59 return ctrl_inw(port2adr(port));
60 else
61 maybebadio(port);
62 return 0;
63}
64
65void titan_outb(u8 value, unsigned long port)
66{
67 if (PXSEG(port))
68 ctrl_outb(value, port);
69 else if (is_pci_ioaddr(port))
70 ctrl_outb(value, pci_ioaddr(port));
71 else
72 ctrl_outw(value, port2adr(port));
73}
74
75void titan_outb_p(u8 value, unsigned long port)
76{
77 if (PXSEG(port))
78 ctrl_outb(value, port);
79 else if (is_pci_ioaddr(port))
80 ctrl_outb(value, pci_ioaddr(port));
81 else
82 ctrl_outw(value, port2adr(port));
83 ctrl_delay();
84}
85
86void titan_outw(u16 value, unsigned long port)
87{
88 if (PXSEG(port))
89 ctrl_outw(value, port);
90 else if (is_pci_ioaddr(port))
91 ctrl_outw(value, pci_ioaddr(port));
92 else if (port >= 0x2000)
93 ctrl_outw(value, port2adr(port));
94 else
95 maybebadio(port);
96}
97
98void titan_outl(u32 value, unsigned long port)
99{
100 if (PXSEG(port))
101 ctrl_outl(value, port);
102 else if (is_pci_ioaddr(port))
103 ctrl_outl(value, pci_ioaddr(port));
104 else
105 maybebadio(port);
106}
107
108void titan_insl(unsigned long port, void *dst, unsigned long count)
109{
110 maybebadio(port);
111}
112
113void titan_outsl(unsigned long port, const void *src, unsigned long count)
114{
115 maybebadio(port);
116}
117
118void __iomem *titan_ioport_map(unsigned long port, unsigned int size)
119{
120 if (PXSEG(port) || is_pci_memaddr(port))
121 return (void __iomem *)port;
122 else if (is_pci_ioaddr(port))
123 return (void __iomem *)pci_ioaddr(port);
124
125 return (void __iomem *)port2adr(port);
126}
diff --git a/arch/sh/boards/titan/setup.c b/arch/sh/boards/titan/setup.c
new file mode 100644
index 000000000000..52b66d8b8d2a
--- /dev/null
+++ b/arch/sh/boards/titan/setup.c
@@ -0,0 +1,48 @@
1/*
2 * Setup for Titan
3 */
4
5#include <linux/init.h>
6#include <asm/irq.h>
7#include <asm/titan.h>
8#include <asm/io.h>
9
10extern void __init pcibios_init_platform(void);
11
12static void __init init_titan_irq(void)
13{
14 /* enable individual interrupt mode for externals */
15 ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
16
17 make_ipr_irq( TITAN_IRQ_WAN, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY); /* PCIRQ0 */
18 make_ipr_irq( TITAN_IRQ_LAN, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY); /* PCIRQ1 */
19 make_ipr_irq( TITAN_IRQ_MPCIA, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY); /* PCIRQ2 */
20 make_ipr_irq( TITAN_IRQ_USB, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY); /* PCIRQ3 */
21}
22
23struct sh_machine_vector mv_titan __initmv = {
24 .mv_name = "Titan",
25
26 .mv_inb = titan_inb,
27 .mv_inw = titan_inw,
28 .mv_inl = titan_inl,
29 .mv_outb = titan_outb,
30 .mv_outw = titan_outw,
31 .mv_outl = titan_outl,
32
33 .mv_inb_p = titan_inb_p,
34 .mv_inw_p = titan_inw,
35 .mv_inl_p = titan_inl,
36 .mv_outb_p = titan_outb_p,
37 .mv_outw_p = titan_outw,
38 .mv_outl_p = titan_outl,
39
40 .mv_insl = titan_insl,
41 .mv_outsl = titan_outsl,
42
43 .mv_ioport_map = titan_ioport_map,
44
45 .mv_init_irq = init_titan_irq,
46 .mv_init_pci = pcibios_init_platform,
47};
48ALIAS_MV(titan)
diff --git a/arch/sh/boards/unknown/setup.c b/arch/sh/boards/unknown/setup.c
index c5e4ed10876b..1c941370a2e3 100644
--- a/arch/sh/boards/unknown/setup.c
+++ b/arch/sh/boards/unknown/setup.c
@@ -14,19 +14,8 @@
14 */ 14 */
15#include <linux/init.h> 15#include <linux/init.h>
16#include <asm/machvec.h> 16#include <asm/machvec.h>
17#include <asm/irq.h>
18 17
19struct sh_machine_vector mv_unknown __initmv = { 18struct sh_machine_vector mv_unknown __initmv = {
20 .mv_nr_irqs = NR_IRQS, 19 .mv_name = "Unknown",
21}; 20};
22ALIAS_MV(unknown) 21ALIAS_MV(unknown)
23
24const char *get_system_type(void)
25{
26 return "Unknown";
27}
28
29void __init platform_setup(void)
30{
31}
32
diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile
index 75a6876bf6c6..e5f443790079 100644
--- a/arch/sh/boot/compressed/Makefile
+++ b/arch/sh/boot/compressed/Makefile
@@ -18,13 +18,20 @@ endif
18# Assign dummy values if these 2 variables are not defined, 18# Assign dummy values if these 2 variables are not defined,
19# in order to suppress error message. 19# in order to suppress error message.
20# 20#
21CONFIG_PAGE_OFFSET ?= 0x80000000
21CONFIG_MEMORY_START ?= 0x0c000000 22CONFIG_MEMORY_START ?= 0x0c000000
22CONFIG_BOOT_LINK_OFFSET ?= 0x00800000 23CONFIG_BOOT_LINK_OFFSET ?= 0x00800000
23IMAGE_OFFSET := $(shell printf "0x%8x" $$[0x80000000+$(CONFIG_MEMORY_START)+$(CONFIG_BOOT_LINK_OFFSET)]) 24
25IMAGE_OFFSET := $(shell printf "0x%08x" $$[$(CONFIG_PAGE_OFFSET) + \
26 $(CONFIG_MEMORY_START) + \
27 $(CONFIG_BOOT_LINK_OFFSET)])
28
29LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
24 30
25LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup -T $(obj)/../../kernel/vmlinux.lds 31LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup -T $(obj)/../../kernel/vmlinux.lds
26 32
27$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE 33
34$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(LIBGCC) FORCE
28 $(call if_changed,ld) 35 $(call if_changed,ld)
29 @: 36 @:
30 37
diff --git a/arch/sh/cchips/Kconfig b/arch/sh/cchips/Kconfig
index 155d139884c3..0582ca8346b6 100644
--- a/arch/sh/cchips/Kconfig
+++ b/arch/sh/cchips/Kconfig
@@ -65,6 +65,11 @@ config HD64461_IRQ
65 65
66 Do not change this unless you know what you are doing. 66 Do not change this unless you know what you are doing.
67 67
68config HD64461_IOBASE
69 hex "HD64461 start address"
70 depends on HD64461
71 default "0xb0000000"
72
68config HD64461_ENABLER 73config HD64461_ENABLER
69 bool "HD64461 PCMCIA enabler" 74 bool "HD64461 PCMCIA enabler"
70 depends on HD64461 75 depends on HD64461
@@ -73,7 +78,6 @@ config HD64461_ENABLER
73 via the HD64461 companion chip. 78 via the HD64461 companion chip.
74 Otherwise, say N. 79 Otherwise, say N.
75 80
76
77config HD64465_IOBASE 81config HD64465_IOBASE
78 hex "HD64465 start address" 82 hex "HD64465 start address"
79 depends on HD64465 83 depends on HD64465
diff --git a/arch/sh/cchips/hd6446x/hd64461/io.c b/arch/sh/cchips/hd6446x/hd64461/io.c
index ac3062671db7..7909a1b7b512 100644
--- a/arch/sh/cchips/hd6446x/hd64461/io.c
+++ b/arch/sh/cchips/hd6446x/hd64461/io.c
@@ -1,11 +1,10 @@
1/* 1/*
2 * $Id: io.c,v 1.6 2004/03/16 00:07:50 lethal Exp $
3 * Copyright (C) 2000 YAEGASHI Takeshi 2 * Copyright (C) 2000 YAEGASHI Takeshi
4 * Typical I/O routines for HD64461 system. 3 * Typical I/O routines for HD64461 system.
5 */ 4 */
6 5
7#include <asm/io.h> 6#include <asm/io.h>
8#include <asm/hd64461/hd64461.h> 7#include <asm/hd64461.h>
9 8
10#define MEM_BASE (CONFIG_HD64461_IOBASE - HD64461_STBCR) 9#define MEM_BASE (CONFIG_HD64461_IOBASE - HD64461_STBCR)
11 10
@@ -54,11 +53,6 @@ static __inline__ unsigned long PORT2ADDR(unsigned long port)
54 return 0xa0000000 + (port & 0x1fffffff); 53 return 0xa0000000 + (port & 0x1fffffff);
55} 54}
56 55
57static inline void delay(void)
58{
59 ctrl_inw(0xa0000000);
60}
61
62unsigned char hd64461_inb(unsigned long port) 56unsigned char hd64461_inb(unsigned long port)
63{ 57{
64 return *(volatile unsigned char*)PORT2ADDR(port); 58 return *(volatile unsigned char*)PORT2ADDR(port);
@@ -67,7 +61,7 @@ unsigned char hd64461_inb(unsigned long port)
67unsigned char hd64461_inb_p(unsigned long port) 61unsigned char hd64461_inb_p(unsigned long port)
68{ 62{
69 unsigned long v = *(volatile unsigned char*)PORT2ADDR(port); 63 unsigned long v = *(volatile unsigned char*)PORT2ADDR(port);
70 delay(); 64 ctrl_delay();
71 return v; 65 return v;
72} 66}
73 67
@@ -89,7 +83,7 @@ void hd64461_outb(unsigned char b, unsigned long port)
89void hd64461_outb_p(unsigned char b, unsigned long port) 83void hd64461_outb_p(unsigned char b, unsigned long port)
90{ 84{
91 *(volatile unsigned char*)PORT2ADDR(port) = b; 85 *(volatile unsigned char*)PORT2ADDR(port) = b;
92 delay(); 86 ctrl_delay();
93} 87}
94 88
95void hd64461_outw(unsigned short b, unsigned long port) 89void hd64461_outw(unsigned short b, unsigned long port)
@@ -144,13 +138,13 @@ void hd64461_outsl(unsigned long port, const void *buffer, unsigned long count)
144 while(count--) *addr=*buf++; 138 while(count--) *addr=*buf++;
145} 139}
146 140
147unsigned short hd64461_readw(unsigned long addr) 141unsigned short hd64461_readw(void __iomem *addr)
148{ 142{
149 return *(volatile unsigned short*)(MEM_BASE+addr); 143 return ctrl_inw(MEM_BASE+(unsigned long __force)addr);
150} 144}
151 145
152void hd64461_writew(unsigned short b, unsigned long addr) 146void hd64461_writew(unsigned short b, void __iomem *addr)
153{ 147{
154 *(volatile unsigned short*)(MEM_BASE+addr) = b; 148 ctrl_outw(b, MEM_BASE+(unsigned long __force)addr);
155} 149}
156 150
diff --git a/arch/sh/cchips/hd6446x/hd64461/setup.c b/arch/sh/cchips/hd6446x/hd64461/setup.c
index ad126016720f..38f1e8171a3a 100644
--- a/arch/sh/cchips/hd6446x/hd64461/setup.c
+++ b/arch/sh/cchips/hd6446x/hd64461/setup.c
@@ -11,36 +11,28 @@
11#include <linux/interrupt.h> 11#include <linux/interrupt.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/irq.h> 13#include <linux/irq.h>
14
15#include <asm/io.h> 14#include <asm/io.h>
16#include <asm/irq.h> 15#include <asm/irq.h>
17 16#include <asm/hd64461.h>
18#include <asm/hd64461/hd64461.h>
19 17
20static void disable_hd64461_irq(unsigned int irq) 18static void disable_hd64461_irq(unsigned int irq)
21{ 19{
22 unsigned long flags;
23 unsigned short nimr; 20 unsigned short nimr;
24 unsigned short mask = 1 << (irq - HD64461_IRQBASE); 21 unsigned short mask = 1 << (irq - HD64461_IRQBASE);
25 22
26 local_irq_save(flags);
27 nimr = inw(HD64461_NIMR); 23 nimr = inw(HD64461_NIMR);
28 nimr |= mask; 24 nimr |= mask;
29 outw(nimr, HD64461_NIMR); 25 outw(nimr, HD64461_NIMR);
30 local_irq_restore(flags);
31} 26}
32 27
33static void enable_hd64461_irq(unsigned int irq) 28static void enable_hd64461_irq(unsigned int irq)
34{ 29{
35 unsigned long flags;
36 unsigned short nimr; 30 unsigned short nimr;
37 unsigned short mask = 1 << (irq - HD64461_IRQBASE); 31 unsigned short mask = 1 << (irq - HD64461_IRQBASE);
38 32
39 local_irq_save(flags);
40 nimr = inw(HD64461_NIMR); 33 nimr = inw(HD64461_NIMR);
41 nimr &= ~mask; 34 nimr &= ~mask;
42 outw(nimr, HD64461_NIMR); 35 outw(nimr, HD64461_NIMR);
43 local_irq_restore(flags);
44} 36}
45 37
46static void mask_and_ack_hd64461(unsigned int irq) 38static void mask_and_ack_hd64461(unsigned int irq)
diff --git a/arch/sh/cchips/hd6446x/hd64465/setup.c b/arch/sh/cchips/hd6446x/hd64465/setup.c
index d2b2851bc44b..30573d3e1966 100644
--- a/arch/sh/cchips/hd6446x/hd64465/setup.c
+++ b/arch/sh/cchips/hd6446x/hd64465/setup.c
@@ -25,31 +25,25 @@
25 25
26static void disable_hd64465_irq(unsigned int irq) 26static void disable_hd64465_irq(unsigned int irq)
27{ 27{
28 unsigned long flags;
29 unsigned short nimr; 28 unsigned short nimr;
30 unsigned short mask = 1 << (irq - HD64465_IRQ_BASE); 29 unsigned short mask = 1 << (irq - HD64465_IRQ_BASE);
31 30
32 pr_debug("disable_hd64465_irq(%d): mask=%x\n", irq, mask); 31 pr_debug("disable_hd64465_irq(%d): mask=%x\n", irq, mask);
33 local_irq_save(flags);
34 nimr = inw(HD64465_REG_NIMR); 32 nimr = inw(HD64465_REG_NIMR);
35 nimr |= mask; 33 nimr |= mask;
36 outw(nimr, HD64465_REG_NIMR); 34 outw(nimr, HD64465_REG_NIMR);
37 local_irq_restore(flags);
38} 35}
39 36
40 37
41static void enable_hd64465_irq(unsigned int irq) 38static void enable_hd64465_irq(unsigned int irq)
42{ 39{
43 unsigned long flags;
44 unsigned short nimr; 40 unsigned short nimr;
45 unsigned short mask = 1 << (irq - HD64465_IRQ_BASE); 41 unsigned short mask = 1 << (irq - HD64465_IRQ_BASE);
46 42
47 pr_debug("enable_hd64465_irq(%d): mask=%x\n", irq, mask); 43 pr_debug("enable_hd64465_irq(%d): mask=%x\n", irq, mask);
48 local_irq_save(flags);
49 nimr = inw(HD64465_REG_NIMR); 44 nimr = inw(HD64465_REG_NIMR);
50 nimr &= ~mask; 45 nimr &= ~mask;
51 outw(nimr, HD64465_REG_NIMR); 46 outw(nimr, HD64465_REG_NIMR);
52 local_irq_restore(flags);
53} 47}
54 48
55 49
diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c
index 0dc1fb8f9687..392c8b12ce36 100644
--- a/arch/sh/cchips/voyagergx/irq.c
+++ b/arch/sh/cchips/voyagergx/irq.c
@@ -32,37 +32,30 @@
32 32
33#include <asm/io.h> 33#include <asm/io.h>
34#include <asm/irq.h> 34#include <asm/irq.h>
35#include <asm/rts7751r2d/rts7751r2d.h> 35#include <asm/voyagergx.h>
36#include <asm/rts7751r2d/voyagergx_reg.h>
37 36
38static void disable_voyagergx_irq(unsigned int irq) 37static void disable_voyagergx_irq(unsigned int irq)
39{ 38{
40 unsigned long flags, val; 39 unsigned long val;
41 unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); 40 unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE);
42 41
43 pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask); 42 pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask);
44 local_irq_save(flags);
45 val = inl(VOYAGER_INT_MASK); 43 val = inl(VOYAGER_INT_MASK);
46 val &= ~mask; 44 val &= ~mask;
47 outl(val, VOYAGER_INT_MASK); 45 outl(val, VOYAGER_INT_MASK);
48 local_irq_restore(flags);
49} 46}
50 47
51
52static void enable_voyagergx_irq(unsigned int irq) 48static void enable_voyagergx_irq(unsigned int irq)
53{ 49{
54 unsigned long flags, val; 50 unsigned long val;
55 unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); 51 unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE);
56 52
57 pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask); 53 pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask);
58 local_irq_save(flags);
59 val = inl(VOYAGER_INT_MASK); 54 val = inl(VOYAGER_INT_MASK);
60 val |= mask; 55 val |= mask;
61 outl(val, VOYAGER_INT_MASK); 56 outl(val, VOYAGER_INT_MASK);
62 local_irq_restore(flags);
63} 57}
64 58
65
66static void mask_and_ack_voyagergx(unsigned int irq) 59static void mask_and_ack_voyagergx(unsigned int irq)
67{ 60{
68 disable_voyagergx_irq(irq); 61 disable_voyagergx_irq(irq);
@@ -95,7 +88,8 @@ static struct hw_interrupt_type voyagergx_irq_type = {
95 .end = end_voyagergx_irq, 88 .end = end_voyagergx_irq,
96}; 89};
97 90
98static irqreturn_t voyagergx_interrupt(int irq, void *dev_id, struct pt_regs *regs) 91static irqreturn_t voyagergx_interrupt(int irq, void *dev_id,
92 struct pt_regs *regs)
99{ 93{
100 printk(KERN_INFO 94 printk(KERN_INFO
101 "VoyagerGX: spurious interrupt, status: 0x%x\n", 95 "VoyagerGX: spurious interrupt, status: 0x%x\n",
@@ -103,9 +97,6 @@ static irqreturn_t voyagergx_interrupt(int irq, void *dev_id, struct pt_regs *re
103 return IRQ_HANDLED; 97 return IRQ_HANDLED;
104} 98}
105 99
106
107/*====================================================*/
108
109static struct { 100static struct {
110 int (*func)(int, void *); 101 int (*func)(int, void *);
111 void *dev; 102 void *dev;
diff --git a/arch/sh/cchips/voyagergx/setup.c b/arch/sh/cchips/voyagergx/setup.c
index 139ca88ac9e6..66b2fedd7ad9 100644
--- a/arch/sh/cchips/voyagergx/setup.c
+++ b/arch/sh/cchips/voyagergx/setup.c
@@ -13,7 +13,7 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <asm/io.h> 15#include <asm/io.h>
16#include <asm/rts7751r2d/voyagergx_reg.h> 16#include <asm/voyagergx.h>
17 17
18static int __init setup_voyagergx(void) 18static int __init setup_voyagergx(void)
19{ 19{
diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig
new file mode 100644
index 000000000000..6b43316d03cf
--- /dev/null
+++ b/arch/sh/configs/landisk_defconfig
@@ -0,0 +1,1373 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.13-sh
4# Sun Sep 11 13:00:46 2005
5#
6CONFIG_SUPERH=y
7CONFIG_UID16=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_GENERIC_IRQ_PROBE=y
11CONFIG_GENERIC_CALIBRATE_DELAY=y
12CONFIG_GENERIC_IOMAP=y
13
14#
15# Code maturity level options
16#
17CONFIG_EXPERIMENTAL=y
18CONFIG_CLEAN_COMPILE=y
19CONFIG_BROKEN_ON_SMP=y
20CONFIG_INIT_ENV_ARG_LIMIT=32
21
22#
23# General setup
24#
25CONFIG_LOCALVERSION=""
26CONFIG_LOCALVERSION_AUTO=y
27CONFIG_SWAP=y
28CONFIG_SYSVIPC=y
29# CONFIG_POSIX_MQUEUE is not set
30# CONFIG_BSD_PROCESS_ACCT is not set
31CONFIG_SYSCTL=y
32# CONFIG_AUDIT is not set
33CONFIG_HOTPLUG=y
34CONFIG_KOBJECT_UEVENT=y
35# CONFIG_IKCONFIG is not set
36CONFIG_INITRAMFS_SOURCE=""
37# CONFIG_EMBEDDED is not set
38CONFIG_KALLSYMS=y
39CONFIG_KALLSYMS_EXTRA_PASS=y
40CONFIG_PRINTK=y
41CONFIG_BUG=y
42CONFIG_BASE_FULL=y
43CONFIG_FUTEX=y
44CONFIG_EPOLL=y
45CONFIG_SHMEM=y
46CONFIG_CC_ALIGN_FUNCTIONS=0
47CONFIG_CC_ALIGN_LABELS=0
48CONFIG_CC_ALIGN_LOOPS=0
49CONFIG_CC_ALIGN_JUMPS=0
50# CONFIG_TINY_SHMEM is not set
51CONFIG_BASE_SMALL=0
52
53#
54# Loadable module support
55#
56CONFIG_MODULES=y
57CONFIG_MODULE_UNLOAD=y
58CONFIG_MODULE_FORCE_UNLOAD=y
59CONFIG_OBSOLETE_MODPARM=y
60# CONFIG_MODVERSIONS is not set
61# CONFIG_MODULE_SRCVERSION_ALL is not set
62CONFIG_KMOD=y
63
64#
65# System type
66#
67# CONFIG_SH_SOLUTION_ENGINE is not set
68# CONFIG_SH_7751_SOLUTION_ENGINE is not set
69# CONFIG_SH_7300_SOLUTION_ENGINE is not set
70# CONFIG_SH_73180_SOLUTION_ENGINE is not set
71# CONFIG_SH_7751_SYSTEMH is not set
72# CONFIG_SH_STB1_HARP is not set
73# CONFIG_SH_STB1_OVERDRIVE is not set
74# CONFIG_SH_HP6XX is not set
75# CONFIG_SH_CQREEK is not set
76# CONFIG_SH_DMIDA is not set
77# CONFIG_SH_EC3104 is not set
78# CONFIG_SH_SATURN is not set
79# CONFIG_SH_DREAMCAST is not set
80# CONFIG_SH_CAT68701 is not set
81# CONFIG_SH_BIGSUR is not set
82# CONFIG_SH_SH2000 is not set
83# CONFIG_SH_ADX is not set
84# CONFIG_SH_MPC1211 is not set
85# CONFIG_SH_SH03 is not set
86# CONFIG_SH_SECUREEDGE5410 is not set
87# CONFIG_SH_HS7751RVOIP is not set
88# CONFIG_SH_RTS7751R2D is not set
89# CONFIG_SH_EDOSK7705 is not set
90# CONFIG_SH_SH4202_MICRODEV is not set
91CONFIG_SH_LANDISK=y
92# CONFIG_SH_TITAN is not set
93# CONFIG_SH_UNKNOWN is not set
94
95#
96# Processor selection
97#
98CONFIG_CPU_SH4=y
99
100#
101# SH-2 Processor Support
102#
103# CONFIG_CPU_SUBTYPE_SH7604 is not set
104
105#
106# SH-3 Processor Support
107#
108# CONFIG_CPU_SUBTYPE_SH7300 is not set
109# CONFIG_CPU_SUBTYPE_SH7705 is not set
110# CONFIG_CPU_SUBTYPE_SH7707 is not set
111# CONFIG_CPU_SUBTYPE_SH7708 is not set
112# CONFIG_CPU_SUBTYPE_SH7709 is not set
113
114#
115# SH-4 Processor Support
116#
117# CONFIG_CPU_SUBTYPE_SH7750 is not set
118# CONFIG_CPU_SUBTYPE_SH7091 is not set
119# CONFIG_CPU_SUBTYPE_SH7750R is not set
120# CONFIG_CPU_SUBTYPE_SH7750S is not set
121CONFIG_CPU_SUBTYPE_SH7751=y
122CONFIG_CPU_SUBTYPE_SH7751R=y
123# CONFIG_CPU_SUBTYPE_SH7760 is not set
124# CONFIG_CPU_SUBTYPE_SH4_202 is not set
125
126#
127# ST40 Processor Support
128#
129# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
130# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
131
132#
133# SH-4A Processor Support
134#
135# CONFIG_CPU_SUBTYPE_SH73180 is not set
136# CONFIG_CPU_SUBTYPE_SH7770 is not set
137# CONFIG_CPU_SUBTYPE_SH7780 is not set
138
139#
140# Memory management options
141#
142CONFIG_MMU=y
143CONFIG_SELECT_MEMORY_MODEL=y
144CONFIG_FLATMEM_MANUAL=y
145# CONFIG_DISCONTIGMEM_MANUAL is not set
146# CONFIG_SPARSEMEM_MANUAL is not set
147CONFIG_FLATMEM=y
148CONFIG_FLAT_NODE_MEM_MAP=y
149# CONFIG_SPARSEMEM_STATIC is not set
150
151#
152# Cache configuration
153#
154# CONFIG_SH_DIRECT_MAPPED is not set
155# CONFIG_SH_WRITETHROUGH is not set
156# CONFIG_SH_OCRAM is not set
157CONFIG_MEMORY_START=0x0c000000
158CONFIG_MEMORY_SIZE=0x04000000
159
160#
161# Processor features
162#
163CONFIG_CPU_LITTLE_ENDIAN=y
164CONFIG_SH_FPU=y
165# CONFIG_SH_STORE_QUEUES is not set
166
167#
168# Timer support
169#
170CONFIG_SH_TMU=y
171CONFIG_SH_PCLK_FREQ_BOOL=y
172CONFIG_SH_PCLK_FREQ=33333333
173
174#
175# CPU Frequency scaling
176#
177# CONFIG_CPU_FREQ is not set
178
179#
180# DMA support
181#
182CONFIG_SH_DMA=y
183CONFIG_NR_ONCHIP_DMA_CHANNELS=4
184# CONFIG_NR_DMA_CHANNELS_BOOL is not set
185
186#
187# Companion Chips
188#
189# CONFIG_HD6446X_SERIES is not set
190CONFIG_HEARTBEAT=y
191
192#
193# Kernel features
194#
195CONFIG_KEXEC=y
196# CONFIG_PREEMPT is not set
197# CONFIG_SMP is not set
198
199#
200# Boot options
201#
202CONFIG_ZERO_PAGE_OFFSET=0x00001000
203CONFIG_BOOT_LINK_OFFSET=0x00800000
204# CONFIG_UBC_WAKEUP is not set
205# CONFIG_CMDLINE_BOOL is not set
206
207#
208# Bus options
209#
210CONFIG_ISA=y
211CONFIG_PCI=y
212CONFIG_SH_PCIDMA_NONCOHERENT=y
213CONFIG_PCI_AUTO=y
214CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
215CONFIG_PCI_LEGACY_PROC=y
216
217#
218# PCCARD (PCMCIA/CardBus) support
219#
220CONFIG_PCCARD=y
221# CONFIG_PCMCIA_DEBUG is not set
222CONFIG_PCMCIA=y
223CONFIG_PCMCIA_LOAD_CIS=y
224CONFIG_PCMCIA_IOCTL=y
225CONFIG_CARDBUS=y
226
227#
228# PC-card bridges
229#
230CONFIG_YENTA=y
231# CONFIG_PD6729 is not set
232# CONFIG_I82092 is not set
233# CONFIG_I82365 is not set
234# CONFIG_TCIC is not set
235CONFIG_PCMCIA_PROBE=y
236CONFIG_PCCARD_NONSTATIC=y
237
238#
239# PCI Hotplug Support
240#
241# CONFIG_HOTPLUG_PCI is not set
242
243#
244# Executable file formats
245#
246CONFIG_BINFMT_ELF=y
247# CONFIG_BINFMT_FLAT is not set
248# CONFIG_BINFMT_MISC is not set
249
250#
251# Networking
252#
253CONFIG_NET=y
254
255#
256# Networking options
257#
258CONFIG_PACKET=y
259# CONFIG_PACKET_MMAP is not set
260CONFIG_UNIX=y
261# CONFIG_NET_KEY is not set
262CONFIG_INET=y
263# CONFIG_IP_MULTICAST is not set
264CONFIG_IP_ADVANCED_ROUTER=y
265CONFIG_ASK_IP_FIB_HASH=y
266# CONFIG_IP_FIB_TRIE is not set
267CONFIG_IP_FIB_HASH=y
268# CONFIG_IP_MULTIPLE_TABLES is not set
269# CONFIG_IP_ROUTE_MULTIPATH is not set
270# CONFIG_IP_ROUTE_VERBOSE is not set
271CONFIG_IP_PNP=y
272# CONFIG_IP_PNP_DHCP is not set
273# CONFIG_IP_PNP_BOOTP is not set
274# CONFIG_IP_PNP_RARP is not set
275# CONFIG_NET_IPIP is not set
276# CONFIG_NET_IPGRE is not set
277# CONFIG_ARPD is not set
278# CONFIG_SYN_COOKIES is not set
279# CONFIG_INET_AH is not set
280# CONFIG_INET_ESP is not set
281# CONFIG_INET_IPCOMP is not set
282# CONFIG_INET_TUNNEL is not set
283CONFIG_INET_DIAG=y
284CONFIG_INET_TCP_DIAG=y
285# CONFIG_TCP_CONG_ADVANCED is not set
286CONFIG_TCP_CONG_BIC=y
287
288#
289# IP: Virtual Server Configuration
290#
291# CONFIG_IP_VS is not set
292# CONFIG_IPV6 is not set
293CONFIG_NETFILTER=y
294# CONFIG_NETFILTER_DEBUG is not set
295# CONFIG_NETFILTER_NETLINK is not set
296
297#
298# IP: Netfilter Configuration
299#
300CONFIG_IP_NF_CONNTRACK=m
301CONFIG_IP_NF_CT_ACCT=y
302CONFIG_IP_NF_CONNTRACK_MARK=y
303# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
304# CONFIG_IP_NF_CT_PROTO_SCTP is not set
305CONFIG_IP_NF_FTP=m
306CONFIG_IP_NF_IRC=m
307# CONFIG_IP_NF_NETBIOS_NS is not set
308CONFIG_IP_NF_TFTP=m
309CONFIG_IP_NF_AMANDA=m
310# CONFIG_IP_NF_PPTP is not set
311CONFIG_IP_NF_QUEUE=m
312CONFIG_IP_NF_IPTABLES=m
313CONFIG_IP_NF_MATCH_LIMIT=m
314CONFIG_IP_NF_MATCH_IPRANGE=m
315CONFIG_IP_NF_MATCH_MAC=m
316CONFIG_IP_NF_MATCH_PKTTYPE=m
317CONFIG_IP_NF_MATCH_MARK=m
318CONFIG_IP_NF_MATCH_MULTIPORT=m
319CONFIG_IP_NF_MATCH_TOS=m
320CONFIG_IP_NF_MATCH_RECENT=m
321CONFIG_IP_NF_MATCH_ECN=m
322CONFIG_IP_NF_MATCH_DSCP=m
323CONFIG_IP_NF_MATCH_AH_ESP=m
324CONFIG_IP_NF_MATCH_LENGTH=m
325CONFIG_IP_NF_MATCH_TTL=m
326CONFIG_IP_NF_MATCH_TCPMSS=m
327CONFIG_IP_NF_MATCH_HELPER=m
328CONFIG_IP_NF_MATCH_STATE=m
329CONFIG_IP_NF_MATCH_CONNTRACK=m
330CONFIG_IP_NF_MATCH_OWNER=m
331CONFIG_IP_NF_MATCH_ADDRTYPE=m
332CONFIG_IP_NF_MATCH_REALM=m
333CONFIG_IP_NF_MATCH_SCTP=m
334# CONFIG_IP_NF_MATCH_DCCP is not set
335CONFIG_IP_NF_MATCH_COMMENT=m
336CONFIG_IP_NF_MATCH_CONNMARK=m
337# CONFIG_IP_NF_MATCH_CONNBYTES is not set
338CONFIG_IP_NF_MATCH_HASHLIMIT=m
339# CONFIG_IP_NF_MATCH_STRING is not set
340CONFIG_IP_NF_FILTER=m
341CONFIG_IP_NF_TARGET_REJECT=m
342CONFIG_IP_NF_TARGET_LOG=m
343CONFIG_IP_NF_TARGET_ULOG=m
344CONFIG_IP_NF_TARGET_TCPMSS=m
345# CONFIG_IP_NF_TARGET_NFQUEUE is not set
346CONFIG_IP_NF_NAT=m
347CONFIG_IP_NF_NAT_NEEDED=y
348CONFIG_IP_NF_TARGET_MASQUERADE=m
349CONFIG_IP_NF_TARGET_REDIRECT=m
350CONFIG_IP_NF_TARGET_NETMAP=m
351CONFIG_IP_NF_TARGET_SAME=m
352# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
353CONFIG_IP_NF_NAT_IRC=m
354CONFIG_IP_NF_NAT_FTP=m
355CONFIG_IP_NF_NAT_TFTP=m
356CONFIG_IP_NF_NAT_AMANDA=m
357CONFIG_IP_NF_MANGLE=m
358CONFIG_IP_NF_TARGET_TOS=m
359CONFIG_IP_NF_TARGET_ECN=m
360CONFIG_IP_NF_TARGET_DSCP=m
361CONFIG_IP_NF_TARGET_MARK=m
362CONFIG_IP_NF_TARGET_CLASSIFY=m
363# CONFIG_IP_NF_TARGET_TTL is not set
364CONFIG_IP_NF_TARGET_CONNMARK=m
365# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
366CONFIG_IP_NF_RAW=m
367CONFIG_IP_NF_TARGET_NOTRACK=m
368CONFIG_IP_NF_ARPTABLES=m
369CONFIG_IP_NF_ARPFILTER=m
370CONFIG_IP_NF_ARP_MANGLE=m
371
372#
373# DCCP Configuration (EXPERIMENTAL)
374#
375# CONFIG_IP_DCCP is not set
376
377#
378# SCTP Configuration (EXPERIMENTAL)
379#
380# CONFIG_IP_SCTP is not set
381# CONFIG_ATM is not set
382# CONFIG_BRIDGE is not set
383# CONFIG_VLAN_8021Q is not set
384# CONFIG_DECNET is not set
385CONFIG_LLC=m
386# CONFIG_LLC2 is not set
387# CONFIG_IPX is not set
388CONFIG_ATALK=m
389# CONFIG_DEV_APPLETALK is not set
390# CONFIG_X25 is not set
391# CONFIG_LAPB is not set
392# CONFIG_NET_DIVERT is not set
393# CONFIG_ECONET is not set
394# CONFIG_WAN_ROUTER is not set
395# CONFIG_NET_SCHED is not set
396CONFIG_NET_CLS_ROUTE=y
397
398#
399# Network testing
400#
401# CONFIG_NET_PKTGEN is not set
402# CONFIG_HAMRADIO is not set
403# CONFIG_IRDA is not set
404# CONFIG_BT is not set
405# CONFIG_IEEE80211 is not set
406
407#
408# Device Drivers
409#
410
411#
412# Generic Driver Options
413#
414CONFIG_STANDALONE=y
415CONFIG_PREVENT_FIRMWARE_BUILD=y
416CONFIG_FW_LOADER=y
417
418#
419# Connector - unified userspace <-> kernelspace linker
420#
421# CONFIG_CONNECTOR is not set
422
423#
424# Memory Technology Devices (MTD)
425#
426# CONFIG_MTD is not set
427
428#
429# Parallel port support
430#
431# CONFIG_PARPORT is not set
432
433#
434# Plug and Play support
435#
436# CONFIG_PNP is not set
437
438#
439# Block devices
440#
441# CONFIG_BLK_CPQ_DA is not set
442# CONFIG_BLK_CPQ_CISS_DA is not set
443# CONFIG_BLK_DEV_DAC960 is not set
444# CONFIG_BLK_DEV_UMEM is not set
445# CONFIG_BLK_DEV_COW_COMMON is not set
446CONFIG_BLK_DEV_LOOP=y
447# CONFIG_BLK_DEV_CRYPTOLOOP is not set
448# CONFIG_BLK_DEV_NBD is not set
449# CONFIG_BLK_DEV_SX8 is not set
450# CONFIG_BLK_DEV_UB is not set
451CONFIG_BLK_DEV_RAM=y
452CONFIG_BLK_DEV_RAM_COUNT=16
453CONFIG_BLK_DEV_RAM_SIZE=4096
454# CONFIG_BLK_DEV_INITRD is not set
455# CONFIG_LBD is not set
456# CONFIG_CDROM_PKTCDVD is not set
457
458#
459# IO Schedulers
460#
461CONFIG_IOSCHED_NOOP=y
462CONFIG_IOSCHED_AS=y
463CONFIG_IOSCHED_DEADLINE=y
464CONFIG_IOSCHED_CFQ=y
465# CONFIG_ATA_OVER_ETH is not set
466
467#
468# ATA/ATAPI/MFM/RLL support
469#
470CONFIG_IDE=y
471CONFIG_IDE_MAX_HWIFS=4
472CONFIG_BLK_DEV_IDE=y
473
474#
475# Please see Documentation/ide.txt for help/info on IDE drives
476#
477# CONFIG_BLK_DEV_IDE_SATA is not set
478CONFIG_BLK_DEV_IDEDISK=y
479# CONFIG_IDEDISK_MULTI_MODE is not set
480# CONFIG_BLK_DEV_IDECS is not set
481CONFIG_BLK_DEV_IDECD=y
482# CONFIG_BLK_DEV_IDETAPE is not set
483# CONFIG_BLK_DEV_IDEFLOPPY is not set
484CONFIG_BLK_DEV_IDESCSI=y
485# CONFIG_IDE_TASK_IOCTL is not set
486
487#
488# IDE chipset support/bugfixes
489#
490CONFIG_IDE_GENERIC=y
491CONFIG_BLK_DEV_IDEPCI=y
492CONFIG_IDEPCI_SHARE_IRQ=y
493CONFIG_BLK_DEV_OFFBOARD=y
494CONFIG_BLK_DEV_GENERIC=y
495# CONFIG_BLK_DEV_OPTI621 is not set
496CONFIG_BLK_DEV_IDEDMA_PCI=y
497# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
498CONFIG_IDEDMA_PCI_AUTO=y
499CONFIG_IDEDMA_ONLYDISK=y
500CONFIG_BLK_DEV_AEC62XX=y
501# CONFIG_BLK_DEV_ALI15X3 is not set
502# CONFIG_BLK_DEV_AMD74XX is not set
503# CONFIG_BLK_DEV_CMD64X is not set
504# CONFIG_BLK_DEV_TRIFLEX is not set
505# CONFIG_BLK_DEV_CY82C693 is not set
506# CONFIG_BLK_DEV_CS5520 is not set
507# CONFIG_BLK_DEV_CS5530 is not set
508# CONFIG_BLK_DEV_HPT34X is not set
509# CONFIG_BLK_DEV_HPT366 is not set
510# CONFIG_BLK_DEV_SC1200 is not set
511# CONFIG_BLK_DEV_PIIX is not set
512# CONFIG_BLK_DEV_IT821X is not set
513# CONFIG_BLK_DEV_NS87415 is not set
514# CONFIG_BLK_DEV_PDC202XX_OLD is not set
515# CONFIG_BLK_DEV_PDC202XX_NEW is not set
516# CONFIG_BLK_DEV_SVWKS is not set
517# CONFIG_BLK_DEV_SIIMAGE is not set
518# CONFIG_BLK_DEV_SLC90E66 is not set
519# CONFIG_BLK_DEV_TRM290 is not set
520# CONFIG_BLK_DEV_VIA82CXXX is not set
521CONFIG_IDE_SH=y
522# CONFIG_IDE_ARM is not set
523# CONFIG_IDE_CHIPSETS is not set
524CONFIG_BLK_DEV_IDEDMA=y
525# CONFIG_IDEDMA_IVB is not set
526CONFIG_IDEDMA_AUTO=y
527# CONFIG_BLK_DEV_HD is not set
528
529#
530# SCSI device support
531#
532# CONFIG_RAID_ATTRS is not set
533CONFIG_SCSI=y
534CONFIG_SCSI_PROC_FS=y
535
536#
537# SCSI support type (disk, tape, CD-ROM)
538#
539CONFIG_BLK_DEV_SD=y
540# CONFIG_CHR_DEV_ST is not set
541# CONFIG_CHR_DEV_OSST is not set
542# CONFIG_BLK_DEV_SR is not set
543# CONFIG_CHR_DEV_SG is not set
544# CONFIG_CHR_DEV_SCH is not set
545
546#
547# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
548#
549CONFIG_SCSI_MULTI_LUN=y
550# CONFIG_SCSI_CONSTANTS is not set
551# CONFIG_SCSI_LOGGING is not set
552
553#
554# SCSI Transport Attributes
555#
556# CONFIG_SCSI_SPI_ATTRS is not set
557# CONFIG_SCSI_FC_ATTRS is not set
558# CONFIG_SCSI_ISCSI_ATTRS is not set
559# CONFIG_SCSI_SAS_ATTRS is not set
560
561#
562# SCSI low-level drivers
563#
564# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
565# CONFIG_SCSI_3W_9XXX is not set
566# CONFIG_SCSI_ACARD is not set
567# CONFIG_SCSI_AHA152X is not set
568# CONFIG_SCSI_AACRAID is not set
569# CONFIG_SCSI_AIC7XXX is not set
570# CONFIG_SCSI_AIC7XXX_OLD is not set
571# CONFIG_SCSI_AIC79XX is not set
572# CONFIG_SCSI_DPT_I2O is not set
573# CONFIG_SCSI_IN2000 is not set
574# CONFIG_MEGARAID_NEWGEN is not set
575# CONFIG_MEGARAID_LEGACY is not set
576# CONFIG_MEGARAID_SAS is not set
577# CONFIG_SCSI_SATA is not set
578# CONFIG_SCSI_DMX3191D is not set
579# CONFIG_SCSI_DTC3280 is not set
580# CONFIG_SCSI_FUTURE_DOMAIN is not set
581# CONFIG_SCSI_GENERIC_NCR5380 is not set
582# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
583# CONFIG_SCSI_IPS is not set
584# CONFIG_SCSI_INITIO is not set
585# CONFIG_SCSI_INIA100 is not set
586# CONFIG_SCSI_NCR53C406A is not set
587# CONFIG_SCSI_SYM53C8XX_2 is not set
588# CONFIG_SCSI_IPR is not set
589# CONFIG_SCSI_PAS16 is not set
590# CONFIG_SCSI_PSI240I is not set
591# CONFIG_SCSI_QLOGIC_FAS is not set
592# CONFIG_SCSI_QLOGIC_FC is not set
593# CONFIG_SCSI_QLOGIC_1280 is not set
594CONFIG_SCSI_QLA2XXX=y
595# CONFIG_SCSI_QLA21XX is not set
596# CONFIG_SCSI_QLA22XX is not set
597# CONFIG_SCSI_QLA2300 is not set
598# CONFIG_SCSI_QLA2322 is not set
599# CONFIG_SCSI_QLA6312 is not set
600# CONFIG_SCSI_QLA24XX is not set
601# CONFIG_SCSI_LPFC is not set
602# CONFIG_SCSI_SYM53C416 is not set
603# CONFIG_SCSI_DC395x is not set
604# CONFIG_SCSI_DC390T is not set
605# CONFIG_SCSI_T128 is not set
606# CONFIG_SCSI_NSP32 is not set
607# CONFIG_SCSI_DEBUG is not set
608
609#
610# PCMCIA SCSI adapter support
611#
612# CONFIG_PCMCIA_AHA152X is not set
613# CONFIG_PCMCIA_FDOMAIN is not set
614# CONFIG_PCMCIA_NINJA_SCSI is not set
615# CONFIG_PCMCIA_QLOGIC is not set
616# CONFIG_PCMCIA_SYM53C500 is not set
617
618#
619# Old CD-ROM drivers (not SCSI, not IDE)
620#
621# CONFIG_CD_NO_IDESCSI is not set
622
623#
624# Multi-device support (RAID and LVM)
625#
626CONFIG_MD=y
627CONFIG_BLK_DEV_MD=m
628CONFIG_MD_LINEAR=m
629CONFIG_MD_RAID0=m
630CONFIG_MD_RAID1=m
631# CONFIG_MD_RAID10 is not set
632# CONFIG_MD_RAID5 is not set
633# CONFIG_MD_RAID6 is not set
634# CONFIG_MD_MULTIPATH is not set
635# CONFIG_MD_FAULTY is not set
636# CONFIG_BLK_DEV_DM is not set
637
638#
639# Fusion MPT device support
640#
641# CONFIG_FUSION is not set
642# CONFIG_FUSION_SPI is not set
643# CONFIG_FUSION_FC is not set
644# CONFIG_FUSION_SAS is not set
645
646#
647# IEEE 1394 (FireWire) support
648#
649# CONFIG_IEEE1394 is not set
650
651#
652# I2O device support
653#
654# CONFIG_I2O is not set
655
656#
657# Network device support
658#
659CONFIG_NETDEVICES=y
660# CONFIG_DUMMY is not set
661# CONFIG_BONDING is not set
662# CONFIG_EQUALIZER is not set
663CONFIG_TUN=m
664
665#
666# ARCnet devices
667#
668# CONFIG_ARCNET is not set
669
670#
671# PHY device support
672#
673# CONFIG_PHYLIB is not set
674
675#
676# Ethernet (10 or 100Mbit)
677#
678CONFIG_NET_ETHERNET=y
679CONFIG_MII=y
680# CONFIG_STNIC is not set
681# CONFIG_HAPPYMEAL is not set
682# CONFIG_SUNGEM is not set
683# CONFIG_CASSINI is not set
684# CONFIG_NET_VENDOR_3COM is not set
685# CONFIG_NET_VENDOR_SMC is not set
686# CONFIG_SMC91X is not set
687# CONFIG_NET_VENDOR_RACAL is not set
688
689#
690# Tulip family network device support
691#
692# CONFIG_NET_TULIP is not set
693# CONFIG_AT1700 is not set
694# CONFIG_DEPCA is not set
695# CONFIG_HP100 is not set
696# CONFIG_NET_ISA is not set
697# CONFIG_NE2000 is not set
698CONFIG_NET_PCI=y
699# CONFIG_PCNET32 is not set
700# CONFIG_AMD8111_ETH is not set
701# CONFIG_ADAPTEC_STARFIRE is not set
702# CONFIG_AC3200 is not set
703# CONFIG_APRICOT is not set
704# CONFIG_B44 is not set
705# CONFIG_FORCEDETH is not set
706# CONFIG_CS89x0 is not set
707# CONFIG_DGRS is not set
708# CONFIG_EEPRO100 is not set
709# CONFIG_E100 is not set
710# CONFIG_FEALNX is not set
711# CONFIG_NATSEMI is not set
712# CONFIG_NE2K_PCI is not set
713CONFIG_8139CP=y
714# CONFIG_8139TOO is not set
715# CONFIG_SIS900 is not set
716# CONFIG_EPIC100 is not set
717# CONFIG_SUNDANCE is not set
718# CONFIG_TLAN is not set
719# CONFIG_VIA_RHINE is not set
720
721#
722# Ethernet (1000 Mbit)
723#
724# CONFIG_ACENIC is not set
725# CONFIG_DL2K is not set
726# CONFIG_E1000 is not set
727# CONFIG_NS83820 is not set
728# CONFIG_HAMACHI is not set
729# CONFIG_YELLOWFIN is not set
730# CONFIG_R8169 is not set
731# CONFIG_SIS190 is not set
732# CONFIG_SKGE is not set
733# CONFIG_SK98LIN is not set
734# CONFIG_VIA_VELOCITY is not set
735# CONFIG_TIGON3 is not set
736# CONFIG_BNX2 is not set
737
738#
739# Ethernet (10000 Mbit)
740#
741# CONFIG_CHELSIO_T1 is not set
742# CONFIG_IXGB is not set
743# CONFIG_S2IO is not set
744
745#
746# Token Ring devices
747#
748# CONFIG_TR is not set
749
750#
751# Wireless LAN (non-hamradio)
752#
753# CONFIG_NET_RADIO is not set
754
755#
756# PCMCIA network device support
757#
758# CONFIG_NET_PCMCIA is not set
759
760#
761# Wan interfaces
762#
763# CONFIG_WAN is not set
764# CONFIG_FDDI is not set
765# CONFIG_HIPPI is not set
766# CONFIG_PPP is not set
767# CONFIG_SLIP is not set
768# CONFIG_NET_FC is not set
769# CONFIG_SHAPER is not set
770# CONFIG_NETCONSOLE is not set
771# CONFIG_NETPOLL is not set
772# CONFIG_NET_POLL_CONTROLLER is not set
773
774#
775# ISDN subsystem
776#
777# CONFIG_ISDN is not set
778
779#
780# Telephony Support
781#
782# CONFIG_PHONE is not set
783
784#
785# Input device support
786#
787CONFIG_INPUT=y
788
789#
790# Userland interfaces
791#
792CONFIG_INPUT_MOUSEDEV=y
793# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
794CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
795CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
796# CONFIG_INPUT_JOYDEV is not set
797# CONFIG_INPUT_TSDEV is not set
798# CONFIG_INPUT_EVDEV is not set
799# CONFIG_INPUT_EVBUG is not set
800
801#
802# Input Device Drivers
803#
804# CONFIG_INPUT_KEYBOARD is not set
805# CONFIG_INPUT_MOUSE is not set
806# CONFIG_INPUT_JOYSTICK is not set
807# CONFIG_INPUT_TOUCHSCREEN is not set
808# CONFIG_INPUT_MISC is not set
809
810#
811# Hardware I/O ports
812#
813# CONFIG_SERIO is not set
814# CONFIG_GAMEPORT is not set
815
816#
817# Character devices
818#
819CONFIG_VT=y
820CONFIG_VT_CONSOLE=y
821CONFIG_HW_CONSOLE=y
822# CONFIG_SERIAL_NONSTANDARD is not set
823
824#
825# Serial drivers
826#
827# CONFIG_SERIAL_8250 is not set
828
829#
830# Non-8250 serial port support
831#
832CONFIG_SERIAL_SH_SCI=y
833CONFIG_SERIAL_SH_SCI_CONSOLE=y
834CONFIG_SERIAL_CORE=y
835CONFIG_SERIAL_CORE_CONSOLE=y
836# CONFIG_SERIAL_JSM is not set
837CONFIG_UNIX98_PTYS=y
838CONFIG_LEGACY_PTYS=y
839CONFIG_LEGACY_PTY_COUNT=256
840
841#
842# IPMI
843#
844# CONFIG_IPMI_HANDLER is not set
845
846#
847# Watchdog Cards
848#
849# CONFIG_WATCHDOG is not set
850# CONFIG_RTC is not set
851CONFIG_RS5C313_RTC=y
852# CONFIG_GEN_RTC is not set
853# CONFIG_DTLK is not set
854# CONFIG_R3964 is not set
855# CONFIG_APPLICOM is not set
856
857#
858# Ftape, the floppy tape device driver
859#
860# CONFIG_DRM is not set
861
862#
863# PCMCIA character devices
864#
865# CONFIG_SYNCLINK_CS is not set
866# CONFIG_RAW_DRIVER is not set
867
868#
869# TPM devices
870#
871# CONFIG_TCG_TPM is not set
872
873#
874# I2C support
875#
876# CONFIG_I2C is not set
877
878#
879# Dallas's 1-wire bus
880#
881# CONFIG_W1 is not set
882
883#
884# Hardware Monitoring support
885#
886CONFIG_HWMON=y
887# CONFIG_HWMON_VID is not set
888# CONFIG_HWMON_DEBUG_CHIP is not set
889
890#
891# Misc devices
892#
893
894#
895# Multimedia Capabilities Port drivers
896#
897
898#
899# Multimedia devices
900#
901CONFIG_VIDEO_DEV=m
902
903#
904# Video For Linux
905#
906
907#
908# Video Adapters
909#
910# CONFIG_VIDEO_PMS is not set
911# CONFIG_VIDEO_CPIA is not set
912# CONFIG_VIDEO_STRADIS is not set
913# CONFIG_VIDEO_MXB is not set
914# CONFIG_VIDEO_DPC is not set
915# CONFIG_VIDEO_HEXIUM_ORION is not set
916# CONFIG_VIDEO_HEXIUM_GEMINI is not set
917
918#
919# Radio Adapters
920#
921# CONFIG_RADIO_CADET is not set
922# CONFIG_RADIO_RTRACK is not set
923# CONFIG_RADIO_RTRACK2 is not set
924# CONFIG_RADIO_AZTECH is not set
925# CONFIG_RADIO_GEMTEK is not set
926# CONFIG_RADIO_GEMTEK_PCI is not set
927# CONFIG_RADIO_MAXIRADIO is not set
928# CONFIG_RADIO_MAESTRO is not set
929# CONFIG_RADIO_SF16FMI is not set
930# CONFIG_RADIO_SF16FMR2 is not set
931# CONFIG_RADIO_TERRATEC is not set
932# CONFIG_RADIO_TRUST is not set
933# CONFIG_RADIO_TYPHOON is not set
934# CONFIG_RADIO_ZOLTRIX is not set
935
936#
937# Digital Video Broadcasting Devices
938#
939# CONFIG_DVB is not set
940
941#
942# Graphics support
943#
944# CONFIG_FB is not set
945
946#
947# Console display driver support
948#
949# CONFIG_MDA_CONSOLE is not set
950CONFIG_DUMMY_CONSOLE=y
951CONFIG_FONT_8x16=y
952
953#
954# Sound
955#
956CONFIG_SOUND=m
957
958#
959# Advanced Linux Sound Architecture
960#
961# CONFIG_SND is not set
962
963#
964# Open Sound System
965#
966CONFIG_SOUND_PRIME=m
967# CONFIG_SOUND_BT878 is not set
968# CONFIG_SOUND_CMPCI is not set
969# CONFIG_SOUND_EMU10K1 is not set
970# CONFIG_SOUND_FUSION is not set
971# CONFIG_SOUND_CS4281 is not set
972# CONFIG_SOUND_ES1370 is not set
973# CONFIG_SOUND_ES1371 is not set
974# CONFIG_SOUND_ESSSOLO1 is not set
975# CONFIG_SOUND_MAESTRO is not set
976# CONFIG_SOUND_MAESTRO3 is not set
977# CONFIG_SOUND_ICH is not set
978# CONFIG_SOUND_SONICVIBES is not set
979# CONFIG_SOUND_TRIDENT is not set
980# CONFIG_SOUND_MSNDCLAS is not set
981# CONFIG_SOUND_MSNDPIN is not set
982# CONFIG_SOUND_VIA82CXXX is not set
983# CONFIG_SOUND_ALI5455 is not set
984# CONFIG_SOUND_FORTE is not set
985# CONFIG_SOUND_RME96XX is not set
986# CONFIG_SOUND_AD1980 is not set
987
988#
989# USB support
990#
991CONFIG_USB_ARCH_HAS_HCD=y
992CONFIG_USB_ARCH_HAS_OHCI=y
993CONFIG_USB=y
994# CONFIG_USB_DEBUG is not set
995
996#
997# Miscellaneous USB options
998#
999CONFIG_USB_DEVICEFS=y
1000# CONFIG_USB_BANDWIDTH is not set
1001# CONFIG_USB_DYNAMIC_MINORS is not set
1002# CONFIG_USB_OTG is not set
1003
1004#
1005# USB Host Controller Drivers
1006#
1007CONFIG_USB_EHCI_HCD=y
1008# CONFIG_USB_EHCI_SPLIT_ISO is not set
1009# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
1010# CONFIG_USB_ISP116X_HCD is not set
1011CONFIG_USB_OHCI_HCD=y
1012# CONFIG_USB_OHCI_BIG_ENDIAN is not set
1013CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1014# CONFIG_USB_UHCI_HCD is not set
1015# CONFIG_USB_SL811_HCD is not set
1016
1017#
1018# USB Device Class drivers
1019#
1020CONFIG_OBSOLETE_OSS_USB_DRIVER=y
1021CONFIG_USB_AUDIO=m
1022# CONFIG_USB_BLUETOOTH_TTY is not set
1023CONFIG_USB_MIDI=m
1024# CONFIG_USB_ACM is not set
1025CONFIG_USB_PRINTER=m
1026
1027#
1028# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
1029#
1030CONFIG_USB_STORAGE=m
1031# CONFIG_USB_STORAGE_DEBUG is not set
1032CONFIG_USB_STORAGE_DATAFAB=y
1033CONFIG_USB_STORAGE_FREECOM=y
1034CONFIG_USB_STORAGE_ISD200=y
1035CONFIG_USB_STORAGE_DPCM=y
1036# CONFIG_USB_STORAGE_USBAT is not set
1037CONFIG_USB_STORAGE_SDDR09=y
1038CONFIG_USB_STORAGE_SDDR55=y
1039CONFIG_USB_STORAGE_JUMPSHOT=y
1040
1041#
1042# USB Input Devices
1043#
1044CONFIG_USB_HID=m
1045CONFIG_USB_HIDINPUT=y
1046# CONFIG_HID_FF is not set
1047# CONFIG_USB_HIDDEV is not set
1048
1049#
1050# USB HID Boot Protocol drivers
1051#
1052# CONFIG_USB_KBD is not set
1053# CONFIG_USB_MOUSE is not set
1054# CONFIG_USB_AIPTEK is not set
1055# CONFIG_USB_WACOM is not set
1056# CONFIG_USB_ACECAD is not set
1057# CONFIG_USB_KBTAB is not set
1058# CONFIG_USB_POWERMATE is not set
1059# CONFIG_USB_MTOUCH is not set
1060# CONFIG_USB_ITMTOUCH is not set
1061# CONFIG_USB_EGALAX is not set
1062# CONFIG_USB_YEALINK is not set
1063# CONFIG_USB_XPAD is not set
1064# CONFIG_USB_ATI_REMOTE is not set
1065# CONFIG_USB_KEYSPAN_REMOTE is not set
1066# CONFIG_USB_APPLETOUCH is not set
1067
1068#
1069# USB Imaging devices
1070#
1071# CONFIG_USB_MDC800 is not set
1072# CONFIG_USB_MICROTEK is not set
1073
1074#
1075# USB Multimedia devices
1076#
1077CONFIG_USB_DABUSB=m
1078CONFIG_USB_VICAM=m
1079CONFIG_USB_DSBR=m
1080CONFIG_USB_IBMCAM=m
1081CONFIG_USB_KONICAWC=m
1082CONFIG_USB_OV511=m
1083CONFIG_USB_SE401=m
1084CONFIG_USB_SN9C102=m
1085CONFIG_USB_STV680=m
1086CONFIG_USB_PWC=m
1087
1088#
1089# USB Network Adapters
1090#
1091# CONFIG_USB_CATC is not set
1092# CONFIG_USB_KAWETH is not set
1093CONFIG_USB_PEGASUS=m
1094CONFIG_USB_RTL8150=m
1095# CONFIG_USB_USBNET is not set
1096CONFIG_USB_MON=y
1097
1098#
1099# USB port drivers
1100#
1101
1102#
1103# USB Serial Converter support
1104#
1105CONFIG_USB_SERIAL=m
1106# CONFIG_USB_SERIAL_GENERIC is not set
1107# CONFIG_USB_SERIAL_AIRPRIME is not set
1108# CONFIG_USB_SERIAL_BELKIN is not set
1109# CONFIG_USB_SERIAL_WHITEHEAT is not set
1110# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
1111# CONFIG_USB_SERIAL_CP2101 is not set
1112# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
1113# CONFIG_USB_SERIAL_EMPEG is not set
1114CONFIG_USB_SERIAL_FTDI_SIO=m
1115# CONFIG_USB_SERIAL_VISOR is not set
1116# CONFIG_USB_SERIAL_IPAQ is not set
1117# CONFIG_USB_SERIAL_IR is not set
1118# CONFIG_USB_SERIAL_EDGEPORT is not set
1119# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
1120# CONFIG_USB_SERIAL_GARMIN is not set
1121# CONFIG_USB_SERIAL_IPW is not set
1122# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
1123# CONFIG_USB_SERIAL_KEYSPAN is not set
1124# CONFIG_USB_SERIAL_KLSI is not set
1125# CONFIG_USB_SERIAL_KOBIL_SCT is not set
1126# CONFIG_USB_SERIAL_MCT_U232 is not set
1127CONFIG_USB_SERIAL_PL2303=m
1128# CONFIG_USB_SERIAL_HP4X is not set
1129# CONFIG_USB_SERIAL_SAFE is not set
1130# CONFIG_USB_SERIAL_TI is not set
1131# CONFIG_USB_SERIAL_CYBERJACK is not set
1132# CONFIG_USB_SERIAL_XIRCOM is not set
1133# CONFIG_USB_SERIAL_OPTION is not set
1134# CONFIG_USB_SERIAL_OMNINET is not set
1135
1136#
1137# USB Miscellaneous drivers
1138#
1139CONFIG_USB_EMI62=m
1140CONFIG_USB_EMI26=m
1141# CONFIG_USB_AUERSWALD is not set
1142# CONFIG_USB_RIO500 is not set
1143# CONFIG_USB_LEGOTOWER is not set
1144# CONFIG_USB_LCD is not set
1145# CONFIG_USB_LED is not set
1146# CONFIG_USB_CYTHERM is not set
1147# CONFIG_USB_PHIDGETKIT is not set
1148# CONFIG_USB_PHIDGETSERVO is not set
1149# CONFIG_USB_IDMOUSE is not set
1150CONFIG_USB_SISUSBVGA=m
1151CONFIG_USB_SISUSBVGA_CON=y
1152# CONFIG_USB_LD is not set
1153# CONFIG_USB_TEST is not set
1154
1155#
1156# USB DSL modem support
1157#
1158
1159#
1160# USB Gadget Support
1161#
1162# CONFIG_USB_GADGET is not set
1163
1164#
1165# MMC/SD Card support
1166#
1167# CONFIG_MMC is not set
1168
1169#
1170# InfiniBand support
1171#
1172# CONFIG_INFINIBAND is not set
1173
1174#
1175# SN Devices
1176#
1177
1178#
1179# File systems
1180#
1181CONFIG_EXT2_FS=y
1182# CONFIG_EXT2_FS_XATTR is not set
1183# CONFIG_EXT2_FS_XIP is not set
1184CONFIG_EXT3_FS=y
1185CONFIG_EXT3_FS_XATTR=y
1186# CONFIG_EXT3_FS_POSIX_ACL is not set
1187# CONFIG_EXT3_FS_SECURITY is not set
1188CONFIG_JBD=y
1189# CONFIG_JBD_DEBUG is not set
1190CONFIG_FS_MBCACHE=y
1191CONFIG_REISERFS_FS=y
1192# CONFIG_REISERFS_CHECK is not set
1193# CONFIG_REISERFS_PROC_INFO is not set
1194# CONFIG_REISERFS_FS_XATTR is not set
1195# CONFIG_JFS_FS is not set
1196# CONFIG_FS_POSIX_ACL is not set
1197# CONFIG_XFS_FS is not set
1198# CONFIG_MINIX_FS is not set
1199CONFIG_ROMFS_FS=y
1200CONFIG_INOTIFY=y
1201# CONFIG_QUOTA is not set
1202CONFIG_DNOTIFY=y
1203# CONFIG_AUTOFS_FS is not set
1204# CONFIG_AUTOFS4_FS is not set
1205# CONFIG_FUSE_FS is not set
1206
1207#
1208# CD-ROM/DVD Filesystems
1209#
1210CONFIG_ISO9660_FS=m
1211# CONFIG_JOLIET is not set
1212# CONFIG_ZISOFS is not set
1213# CONFIG_UDF_FS is not set
1214
1215#
1216# DOS/FAT/NT Filesystems
1217#
1218CONFIG_FAT_FS=y
1219CONFIG_MSDOS_FS=y
1220CONFIG_VFAT_FS=y
1221CONFIG_FAT_DEFAULT_CODEPAGE=437
1222CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1223CONFIG_NTFS_FS=m
1224# CONFIG_NTFS_DEBUG is not set
1225CONFIG_NTFS_RW=y
1226
1227#
1228# Pseudo filesystems
1229#
1230CONFIG_PROC_FS=y
1231# CONFIG_PROC_KCORE is not set
1232CONFIG_SYSFS=y
1233CONFIG_TMPFS=y
1234# CONFIG_HUGETLBFS is not set
1235# CONFIG_HUGETLB_PAGE is not set
1236CONFIG_RAMFS=y
1237# CONFIG_RELAYFS_FS is not set
1238
1239#
1240# Miscellaneous filesystems
1241#
1242# CONFIG_ADFS_FS is not set
1243# CONFIG_AFFS_FS is not set
1244# CONFIG_HFS_FS is not set
1245# CONFIG_HFSPLUS_FS is not set
1246# CONFIG_BEFS_FS is not set
1247# CONFIG_BFS_FS is not set
1248# CONFIG_EFS_FS is not set
1249# CONFIG_CRAMFS is not set
1250# CONFIG_VXFS_FS is not set
1251# CONFIG_HPFS_FS is not set
1252# CONFIG_QNX4FS_FS is not set
1253# CONFIG_SYSV_FS is not set
1254CONFIG_UFS_FS=m
1255CONFIG_UFS_FS_WRITE=y
1256
1257#
1258# Network File Systems
1259#
1260CONFIG_NFS_FS=m
1261CONFIG_NFS_V3=y
1262# CONFIG_NFS_V3_ACL is not set
1263# CONFIG_NFS_V4 is not set
1264# CONFIG_NFS_DIRECTIO is not set
1265CONFIG_NFSD=m
1266CONFIG_NFSD_V3=y
1267# CONFIG_NFSD_V3_ACL is not set
1268# CONFIG_NFSD_V4 is not set
1269CONFIG_NFSD_TCP=y
1270CONFIG_LOCKD=m
1271CONFIG_LOCKD_V4=y
1272CONFIG_EXPORTFS=m
1273CONFIG_NFS_COMMON=y
1274CONFIG_SUNRPC=m
1275# CONFIG_RPCSEC_GSS_KRB5 is not set
1276# CONFIG_RPCSEC_GSS_SPKM3 is not set
1277CONFIG_SMB_FS=m
1278# CONFIG_SMB_NLS_DEFAULT is not set
1279# CONFIG_CIFS is not set
1280# CONFIG_NCP_FS is not set
1281# CONFIG_CODA_FS is not set
1282# CONFIG_AFS_FS is not set
1283# CONFIG_9P_FS is not set
1284
1285#
1286# Partition Types
1287#
1288# CONFIG_PARTITION_ADVANCED is not set
1289CONFIG_MSDOS_PARTITION=y
1290
1291#
1292# Native Language Support
1293#
1294CONFIG_NLS=y
1295CONFIG_NLS_DEFAULT="iso8859-1"
1296CONFIG_NLS_CODEPAGE_437=y
1297# CONFIG_NLS_CODEPAGE_737 is not set
1298# CONFIG_NLS_CODEPAGE_775 is not set
1299# CONFIG_NLS_CODEPAGE_850 is not set
1300# CONFIG_NLS_CODEPAGE_852 is not set
1301# CONFIG_NLS_CODEPAGE_855 is not set
1302# CONFIG_NLS_CODEPAGE_857 is not set
1303# CONFIG_NLS_CODEPAGE_860 is not set
1304# CONFIG_NLS_CODEPAGE_861 is not set
1305# CONFIG_NLS_CODEPAGE_862 is not set
1306# CONFIG_NLS_CODEPAGE_863 is not set
1307# CONFIG_NLS_CODEPAGE_864 is not set
1308# CONFIG_NLS_CODEPAGE_865 is not set
1309# CONFIG_NLS_CODEPAGE_866 is not set
1310# CONFIG_NLS_CODEPAGE_869 is not set
1311# CONFIG_NLS_CODEPAGE_936 is not set
1312# CONFIG_NLS_CODEPAGE_950 is not set
1313CONFIG_NLS_CODEPAGE_932=y
1314# CONFIG_NLS_CODEPAGE_949 is not set
1315# CONFIG_NLS_CODEPAGE_874 is not set
1316# CONFIG_NLS_ISO8859_8 is not set
1317# CONFIG_NLS_CODEPAGE_1250 is not set
1318# CONFIG_NLS_CODEPAGE_1251 is not set
1319# CONFIG_NLS_ASCII is not set
1320# CONFIG_NLS_ISO8859_1 is not set
1321# CONFIG_NLS_ISO8859_2 is not set
1322# CONFIG_NLS_ISO8859_3 is not set
1323# CONFIG_NLS_ISO8859_4 is not set
1324# CONFIG_NLS_ISO8859_5 is not set
1325# CONFIG_NLS_ISO8859_6 is not set
1326# CONFIG_NLS_ISO8859_7 is not set
1327# CONFIG_NLS_ISO8859_9 is not set
1328# CONFIG_NLS_ISO8859_13 is not set
1329# CONFIG_NLS_ISO8859_14 is not set
1330# CONFIG_NLS_ISO8859_15 is not set
1331# CONFIG_NLS_KOI8_R is not set
1332# CONFIG_NLS_KOI8_U is not set
1333# CONFIG_NLS_UTF8 is not set
1334
1335#
1336# Profiling support
1337#
1338# CONFIG_PROFILING is not set
1339
1340#
1341# Kernel hacking
1342#
1343# CONFIG_PRINTK_TIME is not set
1344# CONFIG_DEBUG_KERNEL is not set
1345CONFIG_LOG_BUF_SHIFT=14
1346# CONFIG_FRAME_POINTER is not set
1347CONFIG_SH_STANDARD_BIOS=y
1348# CONFIG_EARLY_SCIF_CONSOLE is not set
1349# CONFIG_EARLY_PRINTK is not set
1350# CONFIG_KGDB is not set
1351
1352#
1353# Security options
1354#
1355# CONFIG_KEYS is not set
1356# CONFIG_SECURITY is not set
1357
1358#
1359# Cryptographic options
1360#
1361# CONFIG_CRYPTO is not set
1362
1363#
1364# Hardware crypto devices
1365#
1366
1367#
1368# Library routines
1369#
1370# CONFIG_CRC_CCITT is not set
1371# CONFIG_CRC16 is not set
1372CONFIG_CRC32=y
1373# CONFIG_LIBCRC32C is not set
diff --git a/arch/sh/configs/r7780rp_defconfig b/arch/sh/configs/r7780rp_defconfig
new file mode 100644
index 000000000000..d597fc571549
--- /dev/null
+++ b/arch/sh/configs/r7780rp_defconfig
@@ -0,0 +1,1099 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.15-sh
4# Sat Jan 7 19:47:53 2006
5#
6CONFIG_SUPERH=y
7CONFIG_UID16=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_GENERIC_IRQ_PROBE=y
11CONFIG_GENERIC_CALIBRATE_DELAY=y
12
13#
14# Code maturity level options
15#
16CONFIG_EXPERIMENTAL=y
17CONFIG_CLEAN_COMPILE=y
18CONFIG_BROKEN_ON_SMP=y
19CONFIG_LOCK_KERNEL=y
20CONFIG_INIT_ENV_ARG_LIMIT=32
21
22#
23# General setup
24#
25CONFIG_LOCALVERSION=""
26CONFIG_LOCALVERSION_AUTO=y
27CONFIG_SWAP=y
28CONFIG_SYSVIPC=y
29# CONFIG_POSIX_MQUEUE is not set
30CONFIG_BSD_PROCESS_ACCT=y
31# CONFIG_BSD_PROCESS_ACCT_V3 is not set
32CONFIG_SYSCTL=y
33# CONFIG_AUDIT is not set
34CONFIG_HOTPLUG=y
35CONFIG_KOBJECT_UEVENT=y
36CONFIG_IKCONFIG=y
37CONFIG_IKCONFIG_PROC=y
38CONFIG_INITRAMFS_SOURCE=""
39CONFIG_CC_OPTIMIZE_FOR_SIZE=y
40CONFIG_EMBEDDED=y
41CONFIG_KALLSYMS=y
42# CONFIG_KALLSYMS_ALL is not set
43# CONFIG_KALLSYMS_EXTRA_PASS is not set
44CONFIG_PRINTK=y
45CONFIG_BUG=y
46CONFIG_BASE_FULL=y
47# CONFIG_FUTEX is not set
48# CONFIG_EPOLL is not set
49CONFIG_SHMEM=y
50CONFIG_CC_ALIGN_FUNCTIONS=0
51CONFIG_CC_ALIGN_LABELS=0
52CONFIG_CC_ALIGN_LOOPS=0
53CONFIG_CC_ALIGN_JUMPS=0
54# CONFIG_TINY_SHMEM is not set
55CONFIG_BASE_SMALL=0
56
57#
58# Loadable module support
59#
60CONFIG_MODULES=y
61CONFIG_MODULE_UNLOAD=y
62# CONFIG_MODULE_FORCE_UNLOAD is not set
63CONFIG_OBSOLETE_MODPARM=y
64# CONFIG_MODVERSIONS is not set
65# CONFIG_MODULE_SRCVERSION_ALL is not set
66CONFIG_KMOD=y
67
68#
69# Block layer
70#
71# CONFIG_LBD is not set
72
73#
74# IO Schedulers
75#
76CONFIG_IOSCHED_NOOP=y
77# CONFIG_IOSCHED_AS is not set
78# CONFIG_IOSCHED_DEADLINE is not set
79# CONFIG_IOSCHED_CFQ is not set
80# CONFIG_DEFAULT_AS is not set
81# CONFIG_DEFAULT_DEADLINE is not set
82# CONFIG_DEFAULT_CFQ is not set
83CONFIG_DEFAULT_NOOP=y
84CONFIG_DEFAULT_IOSCHED="noop"
85
86#
87# System type
88#
89# CONFIG_SH_SOLUTION_ENGINE is not set
90# CONFIG_SH_7751_SOLUTION_ENGINE is not set
91# CONFIG_SH_7300_SOLUTION_ENGINE is not set
92# CONFIG_SH_73180_SOLUTION_ENGINE is not set
93# CONFIG_SH_7751_SYSTEMH is not set
94# CONFIG_SH_STB1_HARP is not set
95# CONFIG_SH_STB1_OVERDRIVE is not set
96# CONFIG_SH_HP6XX is not set
97# CONFIG_SH_CQREEK is not set
98# CONFIG_SH_DMIDA is not set
99# CONFIG_SH_EC3104 is not set
100# CONFIG_SH_SATURN is not set
101# CONFIG_SH_DREAMCAST is not set
102# CONFIG_SH_CAT68701 is not set
103# CONFIG_SH_BIGSUR is not set
104# CONFIG_SH_SH2000 is not set
105# CONFIG_SH_ADX is not set
106# CONFIG_SH_MPC1211 is not set
107# CONFIG_SH_SH03 is not set
108# CONFIG_SH_SECUREEDGE5410 is not set
109# CONFIG_SH_HS7751RVOIP is not set
110# CONFIG_SH_RTS7751R2D is not set
111# CONFIG_SH_R77703DRP is not set
112CONFIG_SH_R7780RP=y
113# CONFIG_SH_EDOSK7705 is not set
114# CONFIG_SH_SH4202_MICRODEV is not set
115# CONFIG_SH_LANDISK is not set
116# CONFIG_SH_TITAN is not set
117# CONFIG_SH_UNKNOWN is not set
118
119#
120# Processor selection
121#
122CONFIG_CPU_SH4=y
123CONFIG_CPU_SH4A=y
124
125#
126# SH-2 Processor Support
127#
128# CONFIG_CPU_SUBTYPE_SH7604 is not set
129
130#
131# SH-3 Processor Support
132#
133# CONFIG_CPU_SUBTYPE_SH7300 is not set
134# CONFIG_CPU_SUBTYPE_SH7705 is not set
135# CONFIG_CPU_SUBTYPE_SH7707 is not set
136# CONFIG_CPU_SUBTYPE_SH7708 is not set
137# CONFIG_CPU_SUBTYPE_SH7709 is not set
138
139#
140# SH-4 Processor Support
141#
142# CONFIG_CPU_SUBTYPE_SH7750 is not set
143# CONFIG_CPU_SUBTYPE_SH7091 is not set
144# CONFIG_CPU_SUBTYPE_SH7750R is not set
145# CONFIG_CPU_SUBTYPE_SH7750S is not set
146# CONFIG_CPU_SUBTYPE_SH7751 is not set
147# CONFIG_CPU_SUBTYPE_SH7751R is not set
148# CONFIG_CPU_SUBTYPE_SH7760 is not set
149# CONFIG_CPU_SUBTYPE_SH4_202 is not set
150
151#
152# ST40 Processor Support
153#
154# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
155# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
156
157#
158# SH-4A Processor Support
159#
160# CONFIG_CPU_SUBTYPE_SH73180 is not set
161# CONFIG_CPU_SUBTYPE_SH7770 is not set
162CONFIG_CPU_SUBTYPE_SH7780=y
163
164#
165# Memory management options
166#
167CONFIG_MMU=y
168CONFIG_32BIT=y
169CONFIG_HUGETLB_PAGE_SIZE_64K=y
170# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
171CONFIG_SELECT_MEMORY_MODEL=y
172CONFIG_FLATMEM_MANUAL=y
173# CONFIG_DISCONTIGMEM_MANUAL is not set
174# CONFIG_SPARSEMEM_MANUAL is not set
175CONFIG_FLATMEM=y
176CONFIG_FLAT_NODE_MEM_MAP=y
177# CONFIG_SPARSEMEM_STATIC is not set
178CONFIG_SPLIT_PTLOCK_CPUS=4
179
180#
181# Cache configuration
182#
183# CONFIG_SH_DIRECT_MAPPED is not set
184# CONFIG_SH_WRITETHROUGH is not set
185# CONFIG_SH_OCRAM is not set
186CONFIG_MEMORY_START=0x08000000
187CONFIG_MEMORY_SIZE=0x08000000
188
189#
190# Processor features
191#
192CONFIG_CPU_LITTLE_ENDIAN=y
193CONFIG_SH_FPU=y
194CONFIG_SH_STORE_QUEUES=y
195
196#
197# Timer support
198#
199CONFIG_SH_TMU=y
200CONFIG_SH_PCLK_FREQ_BOOL=y
201CONFIG_SH_PCLK_FREQ=32000000
202
203#
204# CPU Frequency scaling
205#
206# CONFIG_CPU_FREQ is not set
207
208#
209# DMA support
210#
211CONFIG_SH_DMA=y
212CONFIG_NR_ONCHIP_DMA_CHANNELS=6
213# CONFIG_NR_DMA_CHANNELS_BOOL is not set
214
215#
216# Companion Chips
217#
218# CONFIG_HD6446X_SERIES is not set
219
220#
221# Kernel features
222#
223# CONFIG_KEXEC is not set
224CONFIG_PREEMPT=y
225# CONFIG_SMP is not set
226CONFIG_CPU_HAS_INTEVT=y
227CONFIG_CPU_HAS_INTC2_IRQ=y
228
229#
230# Boot options
231#
232CONFIG_ZERO_PAGE_OFFSET=0x00001000
233CONFIG_BOOT_LINK_OFFSET=0x00800000
234# CONFIG_UBC_WAKEUP is not set
235CONFIG_CMDLINE_BOOL=y
236CONFIG_CMDLINE="mem=128M console=ttySC0,115200 root=/dev/hda1"
237
238#
239# Bus options
240#
241CONFIG_PCI=y
242CONFIG_SH_PCIDMA_NONCOHERENT=y
243CONFIG_PCI_AUTO=y
244CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
245CONFIG_PCI_LEGACY_PROC=y
246# CONFIG_PCI_DEBUG is not set
247
248#
249# PCCARD (PCMCIA/CardBus) support
250#
251# CONFIG_PCCARD is not set
252
253#
254# PCI Hotplug Support
255#
256CONFIG_HOTPLUG_PCI=y
257# CONFIG_HOTPLUG_PCI_FAKE is not set
258# CONFIG_HOTPLUG_PCI_CPCI is not set
259# CONFIG_HOTPLUG_PCI_SHPC is not set
260
261#
262# Executable file formats
263#
264CONFIG_BINFMT_ELF=y
265# CONFIG_BINFMT_FLAT is not set
266# CONFIG_BINFMT_MISC is not set
267
268#
269# Networking
270#
271CONFIG_NET=y
272
273#
274# Networking options
275#
276CONFIG_PACKET=y
277# CONFIG_PACKET_MMAP is not set
278CONFIG_UNIX=y
279# CONFIG_NET_KEY is not set
280CONFIG_INET=y
281# CONFIG_IP_MULTICAST is not set
282CONFIG_IP_ADVANCED_ROUTER=y
283CONFIG_ASK_IP_FIB_HASH=y
284# CONFIG_IP_FIB_TRIE is not set
285CONFIG_IP_FIB_HASH=y
286# CONFIG_IP_MULTIPLE_TABLES is not set
287# CONFIG_IP_ROUTE_MULTIPATH is not set
288# CONFIG_IP_ROUTE_VERBOSE is not set
289CONFIG_IP_PNP=y
290CONFIG_IP_PNP_DHCP=y
291# CONFIG_IP_PNP_BOOTP is not set
292# CONFIG_IP_PNP_RARP is not set
293# CONFIG_NET_IPIP is not set
294# CONFIG_NET_IPGRE is not set
295# CONFIG_ARPD is not set
296# CONFIG_SYN_COOKIES is not set
297# CONFIG_INET_AH is not set
298# CONFIG_INET_ESP is not set
299# CONFIG_INET_IPCOMP is not set
300# CONFIG_INET_TUNNEL is not set
301CONFIG_INET_DIAG=y
302CONFIG_INET_TCP_DIAG=y
303# CONFIG_TCP_CONG_ADVANCED is not set
304CONFIG_TCP_CONG_BIC=y
305# CONFIG_IPV6 is not set
306# CONFIG_NETFILTER is not set
307
308#
309# DCCP Configuration (EXPERIMENTAL)
310#
311# CONFIG_IP_DCCP is not set
312
313#
314# SCTP Configuration (EXPERIMENTAL)
315#
316# CONFIG_IP_SCTP is not set
317# CONFIG_ATM is not set
318CONFIG_BRIDGE=m
319# CONFIG_VLAN_8021Q is not set
320# CONFIG_DECNET is not set
321# CONFIG_LLC2 is not set
322# CONFIG_IPX is not set
323# CONFIG_ATALK is not set
324# CONFIG_X25 is not set
325# CONFIG_LAPB is not set
326# CONFIG_NET_DIVERT is not set
327# CONFIG_ECONET is not set
328# CONFIG_WAN_ROUTER is not set
329
330#
331# QoS and/or fair queueing
332#
333# CONFIG_NET_SCHED is not set
334
335#
336# Network testing
337#
338# CONFIG_NET_PKTGEN is not set
339# CONFIG_HAMRADIO is not set
340# CONFIG_IRDA is not set
341# CONFIG_BT is not set
342# CONFIG_IEEE80211 is not set
343
344#
345# Device Drivers
346#
347
348#
349# Generic Driver Options
350#
351CONFIG_STANDALONE=y
352CONFIG_PREVENT_FIRMWARE_BUILD=y
353CONFIG_FW_LOADER=m
354# CONFIG_DEBUG_DRIVER is not set
355
356#
357# Connector - unified userspace <-> kernelspace linker
358#
359# CONFIG_CONNECTOR is not set
360
361#
362# Memory Technology Devices (MTD)
363#
364# CONFIG_MTD is not set
365
366#
367# Parallel port support
368#
369# CONFIG_PARPORT is not set
370
371#
372# Plug and Play support
373#
374
375#
376# Block devices
377#
378# CONFIG_BLK_CPQ_DA is not set
379# CONFIG_BLK_CPQ_CISS_DA is not set
380# CONFIG_BLK_DEV_DAC960 is not set
381# CONFIG_BLK_DEV_UMEM is not set
382# CONFIG_BLK_DEV_COW_COMMON is not set
383# CONFIG_BLK_DEV_LOOP is not set
384# CONFIG_BLK_DEV_NBD is not set
385# CONFIG_BLK_DEV_SX8 is not set
386CONFIG_BLK_DEV_RAM=y
387CONFIG_BLK_DEV_RAM_COUNT=16
388CONFIG_BLK_DEV_RAM_SIZE=4096
389# CONFIG_BLK_DEV_INITRD is not set
390# CONFIG_CDROM_PKTCDVD is not set
391# CONFIG_ATA_OVER_ETH is not set
392
393#
394# ATA/ATAPI/MFM/RLL support
395#
396CONFIG_IDE=m
397CONFIG_IDE_MAX_HWIFS=4
398CONFIG_BLK_DEV_IDE=m
399
400#
401# Please see Documentation/ide.txt for help/info on IDE drives
402#
403CONFIG_BLK_DEV_IDE_SATA=y
404CONFIG_BLK_DEV_IDEDISK=m
405CONFIG_IDEDISK_MULTI_MODE=y
406# CONFIG_BLK_DEV_IDECD is not set
407# CONFIG_BLK_DEV_IDETAPE is not set
408# CONFIG_BLK_DEV_IDEFLOPPY is not set
409CONFIG_BLK_DEV_IDESCSI=m
410# CONFIG_IDE_TASK_IOCTL is not set
411
412#
413# IDE chipset support/bugfixes
414#
415CONFIG_IDE_GENERIC=m
416CONFIG_BLK_DEV_IDEPCI=y
417CONFIG_IDEPCI_SHARE_IRQ=y
418# CONFIG_BLK_DEV_OFFBOARD is not set
419CONFIG_BLK_DEV_GENERIC=m
420# CONFIG_BLK_DEV_OPTI621 is not set
421CONFIG_BLK_DEV_IDEDMA_PCI=y
422# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
423CONFIG_IDEDMA_PCI_AUTO=y
424# CONFIG_IDEDMA_ONLYDISK is not set
425CONFIG_BLK_DEV_AEC62XX=m
426# CONFIG_BLK_DEV_ALI15X3 is not set
427# CONFIG_BLK_DEV_AMD74XX is not set
428# CONFIG_BLK_DEV_CMD64X is not set
429# CONFIG_BLK_DEV_TRIFLEX is not set
430# CONFIG_BLK_DEV_CY82C693 is not set
431# CONFIG_BLK_DEV_CS5520 is not set
432# CONFIG_BLK_DEV_CS5530 is not set
433# CONFIG_BLK_DEV_HPT34X is not set
434# CONFIG_BLK_DEV_HPT366 is not set
435# CONFIG_BLK_DEV_SC1200 is not set
436# CONFIG_BLK_DEV_PIIX is not set
437# CONFIG_BLK_DEV_IT821X is not set
438# CONFIG_BLK_DEV_NS87415 is not set
439# CONFIG_BLK_DEV_PDC202XX_OLD is not set
440CONFIG_BLK_DEV_PDC202XX_NEW=m
441# CONFIG_PDC202XX_FORCE is not set
442# CONFIG_BLK_DEV_SVWKS is not set
443CONFIG_BLK_DEV_SIIMAGE=m
444# CONFIG_BLK_DEV_SLC90E66 is not set
445# CONFIG_BLK_DEV_TRM290 is not set
446# CONFIG_BLK_DEV_VIA82CXXX is not set
447CONFIG_IDE_SH=y
448# CONFIG_IDE_ARM is not set
449CONFIG_BLK_DEV_IDEDMA=y
450# CONFIG_IDEDMA_IVB is not set
451CONFIG_IDEDMA_AUTO=y
452# CONFIG_BLK_DEV_HD is not set
453
454#
455# SCSI device support
456#
457# CONFIG_RAID_ATTRS is not set
458CONFIG_SCSI=m
459CONFIG_SCSI_PROC_FS=y
460
461#
462# SCSI support type (disk, tape, CD-ROM)
463#
464CONFIG_BLK_DEV_SD=m
465# CONFIG_CHR_DEV_ST is not set
466# CONFIG_CHR_DEV_OSST is not set
467# CONFIG_BLK_DEV_SR is not set
468CONFIG_CHR_DEV_SG=m
469# CONFIG_CHR_DEV_SCH is not set
470
471#
472# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
473#
474# CONFIG_SCSI_MULTI_LUN is not set
475# CONFIG_SCSI_CONSTANTS is not set
476# CONFIG_SCSI_LOGGING is not set
477
478#
479# SCSI Transport Attributes
480#
481# CONFIG_SCSI_SPI_ATTRS is not set
482# CONFIG_SCSI_FC_ATTRS is not set
483# CONFIG_SCSI_ISCSI_ATTRS is not set
484# CONFIG_SCSI_SAS_ATTRS is not set
485
486#
487# SCSI low-level drivers
488#
489# CONFIG_ISCSI_TCP is not set
490# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
491# CONFIG_SCSI_3W_9XXX is not set
492# CONFIG_SCSI_ACARD is not set
493# CONFIG_SCSI_AACRAID is not set
494# CONFIG_SCSI_AIC7XXX is not set
495# CONFIG_SCSI_AIC7XXX_OLD is not set
496# CONFIG_SCSI_AIC79XX is not set
497# CONFIG_SCSI_DPT_I2O is not set
498# CONFIG_MEGARAID_NEWGEN is not set
499# CONFIG_MEGARAID_LEGACY is not set
500# CONFIG_MEGARAID_SAS is not set
501# CONFIG_SCSI_SATA is not set
502# CONFIG_SCSI_DMX3191D is not set
503# CONFIG_SCSI_FUTURE_DOMAIN is not set
504# CONFIG_SCSI_IPS is not set
505# CONFIG_SCSI_INITIO is not set
506# CONFIG_SCSI_INIA100 is not set
507# CONFIG_SCSI_SYM53C8XX_2 is not set
508# CONFIG_SCSI_IPR is not set
509# CONFIG_SCSI_QLOGIC_FC is not set
510# CONFIG_SCSI_QLOGIC_1280 is not set
511CONFIG_SCSI_QLA2XXX=m
512# CONFIG_SCSI_QLA21XX is not set
513# CONFIG_SCSI_QLA22XX is not set
514# CONFIG_SCSI_QLA2300 is not set
515# CONFIG_SCSI_QLA2322 is not set
516# CONFIG_SCSI_QLA6312 is not set
517# CONFIG_SCSI_QLA24XX is not set
518# CONFIG_SCSI_LPFC is not set
519# CONFIG_SCSI_DC395x is not set
520# CONFIG_SCSI_DC390T is not set
521# CONFIG_SCSI_NSP32 is not set
522# CONFIG_SCSI_DEBUG is not set
523
524#
525# Multi-device support (RAID and LVM)
526#
527# CONFIG_MD is not set
528
529#
530# Fusion MPT device support
531#
532# CONFIG_FUSION is not set
533# CONFIG_FUSION_SPI is not set
534# CONFIG_FUSION_FC is not set
535# CONFIG_FUSION_SAS is not set
536
537#
538# IEEE 1394 (FireWire) support
539#
540# CONFIG_IEEE1394 is not set
541
542#
543# I2O device support
544#
545# CONFIG_I2O is not set
546
547#
548# Network device support
549#
550CONFIG_NETDEVICES=y
551# CONFIG_DUMMY is not set
552# CONFIG_BONDING is not set
553# CONFIG_EQUALIZER is not set
554# CONFIG_TUN is not set
555
556#
557# ARCnet devices
558#
559# CONFIG_ARCNET is not set
560
561#
562# PHY device support
563#
564# CONFIG_PHYLIB is not set
565
566#
567# Ethernet (10 or 100Mbit)
568#
569CONFIG_NET_ETHERNET=y
570CONFIG_MII=y
571# CONFIG_STNIC is not set
572# CONFIG_HAPPYMEAL is not set
573# CONFIG_SUNGEM is not set
574# CONFIG_CASSINI is not set
575# CONFIG_NET_VENDOR_3COM is not set
576# CONFIG_SMC91X is not set
577
578#
579# Tulip family network device support
580#
581# CONFIG_NET_TULIP is not set
582# CONFIG_HP100 is not set
583CONFIG_NE2000=y
584CONFIG_NET_PCI=y
585CONFIG_PCNET32=m
586# CONFIG_AMD8111_ETH is not set
587# CONFIG_ADAPTEC_STARFIRE is not set
588# CONFIG_B44 is not set
589# CONFIG_FORCEDETH is not set
590# CONFIG_DGRS is not set
591# CONFIG_EEPRO100 is not set
592# CONFIG_E100 is not set
593# CONFIG_FEALNX is not set
594# CONFIG_NATSEMI is not set
595# CONFIG_NE2K_PCI is not set
596CONFIG_8139CP=m
597CONFIG_8139TOO=m
598# CONFIG_8139TOO_PIO is not set
599# CONFIG_8139TOO_TUNE_TWISTER is not set
600CONFIG_8139TOO_8129=y
601# CONFIG_8139_OLD_RX_RESET is not set
602# CONFIG_SIS900 is not set
603# CONFIG_EPIC100 is not set
604# CONFIG_SUNDANCE is not set
605# CONFIG_TLAN is not set
606CONFIG_VIA_RHINE=m
607CONFIG_VIA_RHINE_MMIO=y
608
609#
610# Ethernet (1000 Mbit)
611#
612# CONFIG_ACENIC is not set
613# CONFIG_DL2K is not set
614CONFIG_E1000=m
615# CONFIG_E1000_NAPI is not set
616# CONFIG_NS83820 is not set
617# CONFIG_HAMACHI is not set
618# CONFIG_YELLOWFIN is not set
619CONFIG_R8169=y
620# CONFIG_R8169_NAPI is not set
621# CONFIG_SIS190 is not set
622# CONFIG_SKGE is not set
623# CONFIG_SK98LIN is not set
624# CONFIG_VIA_VELOCITY is not set
625# CONFIG_TIGON3 is not set
626# CONFIG_BNX2 is not set
627
628#
629# Ethernet (10000 Mbit)
630#
631# CONFIG_CHELSIO_T1 is not set
632# CONFIG_IXGB is not set
633# CONFIG_S2IO is not set
634
635#
636# Token Ring devices
637#
638# CONFIG_TR is not set
639
640#
641# Wireless LAN (non-hamradio)
642#
643CONFIG_NET_RADIO=y
644
645#
646# Obsolete Wireless cards support (pre-802.11)
647#
648# CONFIG_STRIP is not set
649
650#
651# Wireless 802.11b ISA/PCI cards support
652#
653CONFIG_HERMES=m
654# CONFIG_PLX_HERMES is not set
655# CONFIG_TMD_HERMES is not set
656# CONFIG_NORTEL_HERMES is not set
657# CONFIG_PCI_HERMES is not set
658# CONFIG_ATMEL is not set
659
660#
661# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
662#
663CONFIG_PRISM54=m
664# CONFIG_HOSTAP is not set
665CONFIG_NET_WIRELESS=y
666
667#
668# Wan interfaces
669#
670# CONFIG_WAN is not set
671# CONFIG_FDDI is not set
672# CONFIG_HIPPI is not set
673# CONFIG_PPP is not set
674# CONFIG_SLIP is not set
675# CONFIG_NET_FC is not set
676# CONFIG_SHAPER is not set
677# CONFIG_NETCONSOLE is not set
678# CONFIG_NETPOLL is not set
679# CONFIG_NET_POLL_CONTROLLER is not set
680
681#
682# ISDN subsystem
683#
684# CONFIG_ISDN is not set
685
686#
687# Telephony Support
688#
689# CONFIG_PHONE is not set
690
691#
692# Input device support
693#
694CONFIG_INPUT=y
695
696#
697# Userland interfaces
698#
699CONFIG_INPUT_MOUSEDEV=y
700# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
701CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
702CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
703# CONFIG_INPUT_JOYDEV is not set
704# CONFIG_INPUT_TSDEV is not set
705# CONFIG_INPUT_EVDEV is not set
706# CONFIG_INPUT_EVBUG is not set
707
708#
709# Input Device Drivers
710#
711CONFIG_INPUT_KEYBOARD=y
712CONFIG_KEYBOARD_ATKBD=y
713# CONFIG_KEYBOARD_SUNKBD is not set
714# CONFIG_KEYBOARD_LKKBD is not set
715# CONFIG_KEYBOARD_XTKBD is not set
716# CONFIG_KEYBOARD_NEWTON is not set
717# CONFIG_INPUT_MOUSE is not set
718# CONFIG_INPUT_JOYSTICK is not set
719# CONFIG_INPUT_TOUCHSCREEN is not set
720# CONFIG_INPUT_MISC is not set
721
722#
723# Hardware I/O ports
724#
725CONFIG_SERIO=y
726# CONFIG_SERIO_I8042 is not set
727# CONFIG_SERIO_SERPORT is not set
728# CONFIG_SERIO_PCIPS2 is not set
729CONFIG_SERIO_LIBPS2=y
730# CONFIG_SERIO_RAW is not set
731# CONFIG_GAMEPORT is not set
732
733#
734# Character devices
735#
736# CONFIG_VT is not set
737# CONFIG_SERIAL_NONSTANDARD is not set
738
739#
740# Serial drivers
741#
742# CONFIG_SERIAL_8250 is not set
743
744#
745# Non-8250 serial port support
746#
747CONFIG_SERIAL_SH_SCI=y
748CONFIG_SERIAL_SH_SCI_CONSOLE=y
749CONFIG_SERIAL_CORE=y
750CONFIG_SERIAL_CORE_CONSOLE=y
751# CONFIG_SERIAL_JSM is not set
752CONFIG_UNIX98_PTYS=y
753CONFIG_LEGACY_PTYS=y
754CONFIG_LEGACY_PTY_COUNT=256
755
756#
757# IPMI
758#
759# CONFIG_IPMI_HANDLER is not set
760
761#
762# Watchdog Cards
763#
764# CONFIG_WATCHDOG is not set
765# CONFIG_RTC is not set
766# CONFIG_GEN_RTC is not set
767# CONFIG_DTLK is not set
768# CONFIG_R3964 is not set
769# CONFIG_APPLICOM is not set
770
771#
772# Ftape, the floppy tape device driver
773#
774# CONFIG_DRM is not set
775# CONFIG_RAW_DRIVER is not set
776
777#
778# TPM devices
779#
780# CONFIG_TCG_TPM is not set
781# CONFIG_TELCLOCK is not set
782
783#
784# I2C support
785#
786# CONFIG_I2C is not set
787
788#
789# Dallas's 1-wire bus
790#
791# CONFIG_W1 is not set
792
793#
794# Hardware Monitoring support
795#
796CONFIG_HWMON=y
797# CONFIG_HWMON_VID is not set
798# CONFIG_HWMON_DEBUG_CHIP is not set
799
800#
801# Misc devices
802#
803
804#
805# Multimedia Capabilities Port drivers
806#
807
808#
809# Multimedia devices
810#
811# CONFIG_VIDEO_DEV is not set
812
813#
814# Digital Video Broadcasting Devices
815#
816# CONFIG_DVB is not set
817
818#
819# Graphics support
820#
821# CONFIG_FB is not set
822
823#
824# Sound
825#
826CONFIG_SOUND=m
827
828#
829# Advanced Linux Sound Architecture
830#
831# CONFIG_SND is not set
832
833#
834# Open Sound System
835#
836CONFIG_SOUND_PRIME=m
837# CONFIG_OBSOLETE_OSS_DRIVER is not set
838# CONFIG_SOUND_FUSION is not set
839# CONFIG_SOUND_ICH is not set
840# CONFIG_SOUND_TRIDENT is not set
841# CONFIG_SOUND_MSNDCLAS is not set
842# CONFIG_SOUND_MSNDPIN is not set
843
844#
845# USB support
846#
847CONFIG_USB_ARCH_HAS_HCD=y
848CONFIG_USB_ARCH_HAS_OHCI=y
849# CONFIG_USB is not set
850
851#
852# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
853#
854
855#
856# USB Gadget Support
857#
858# CONFIG_USB_GADGET is not set
859
860#
861# MMC/SD Card support
862#
863# CONFIG_MMC is not set
864
865#
866# InfiniBand support
867#
868# CONFIG_INFINIBAND is not set
869
870#
871# SN Devices
872#
873
874#
875# File systems
876#
877CONFIG_EXT2_FS=y
878# CONFIG_EXT2_FS_XATTR is not set
879# CONFIG_EXT2_FS_XIP is not set
880CONFIG_EXT3_FS=y
881CONFIG_EXT3_FS_XATTR=y
882# CONFIG_EXT3_FS_POSIX_ACL is not set
883# CONFIG_EXT3_FS_SECURITY is not set
884CONFIG_JBD=y
885# CONFIG_JBD_DEBUG is not set
886CONFIG_FS_MBCACHE=y
887# CONFIG_REISERFS_FS is not set
888# CONFIG_JFS_FS is not set
889CONFIG_FS_POSIX_ACL=y
890# CONFIG_XFS_FS is not set
891CONFIG_MINIX_FS=y
892# CONFIG_ROMFS_FS is not set
893CONFIG_INOTIFY=y
894# CONFIG_QUOTA is not set
895CONFIG_DNOTIFY=y
896# CONFIG_AUTOFS_FS is not set
897# CONFIG_AUTOFS4_FS is not set
898# CONFIG_FUSE_FS is not set
899
900#
901# CD-ROM/DVD Filesystems
902#
903# CONFIG_ISO9660_FS is not set
904# CONFIG_UDF_FS is not set
905
906#
907# DOS/FAT/NT Filesystems
908#
909CONFIG_FAT_FS=y
910CONFIG_MSDOS_FS=y
911CONFIG_VFAT_FS=y
912CONFIG_FAT_DEFAULT_CODEPAGE=437
913CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
914CONFIG_NTFS_FS=y
915# CONFIG_NTFS_DEBUG is not set
916CONFIG_NTFS_RW=y
917
918#
919# Pseudo filesystems
920#
921CONFIG_PROC_FS=y
922CONFIG_PROC_KCORE=y
923CONFIG_SYSFS=y
924# CONFIG_TMPFS is not set
925CONFIG_HUGETLBFS=y
926CONFIG_HUGETLB_PAGE=y
927CONFIG_RAMFS=y
928# CONFIG_RELAYFS_FS is not set
929
930#
931# Miscellaneous filesystems
932#
933# CONFIG_ADFS_FS is not set
934# CONFIG_AFFS_FS is not set
935# CONFIG_HFS_FS is not set
936# CONFIG_HFSPLUS_FS is not set
937# CONFIG_BEFS_FS is not set
938# CONFIG_BFS_FS is not set
939# CONFIG_EFS_FS is not set
940# CONFIG_CRAMFS is not set
941# CONFIG_VXFS_FS is not set
942# CONFIG_HPFS_FS is not set
943# CONFIG_QNX4FS_FS is not set
944# CONFIG_SYSV_FS is not set
945# CONFIG_UFS_FS is not set
946
947#
948# Network File Systems
949#
950CONFIG_NFS_FS=y
951CONFIG_NFS_V3=y
952# CONFIG_NFS_V3_ACL is not set
953CONFIG_NFS_V4=y
954# CONFIG_NFS_DIRECTIO is not set
955CONFIG_NFSD=y
956CONFIG_NFSD_V3=y
957# CONFIG_NFSD_V3_ACL is not set
958CONFIG_NFSD_V4=y
959CONFIG_NFSD_TCP=y
960CONFIG_ROOT_NFS=y
961CONFIG_LOCKD=y
962CONFIG_LOCKD_V4=y
963CONFIG_EXPORTFS=y
964CONFIG_NFS_COMMON=y
965CONFIG_SUNRPC=y
966CONFIG_SUNRPC_GSS=y
967CONFIG_RPCSEC_GSS_KRB5=y
968# CONFIG_RPCSEC_GSS_SPKM3 is not set
969# CONFIG_SMB_FS is not set
970# CONFIG_CIFS is not set
971# CONFIG_NCP_FS is not set
972# CONFIG_CODA_FS is not set
973# CONFIG_AFS_FS is not set
974# CONFIG_9P_FS is not set
975
976#
977# Partition Types
978#
979# CONFIG_PARTITION_ADVANCED is not set
980CONFIG_MSDOS_PARTITION=y
981
982#
983# Native Language Support
984#
985CONFIG_NLS=y
986CONFIG_NLS_DEFAULT="iso8859-1"
987CONFIG_NLS_CODEPAGE_437=y
988# CONFIG_NLS_CODEPAGE_737 is not set
989# CONFIG_NLS_CODEPAGE_775 is not set
990# CONFIG_NLS_CODEPAGE_850 is not set
991# CONFIG_NLS_CODEPAGE_852 is not set
992# CONFIG_NLS_CODEPAGE_855 is not set
993# CONFIG_NLS_CODEPAGE_857 is not set
994# CONFIG_NLS_CODEPAGE_860 is not set
995# CONFIG_NLS_CODEPAGE_861 is not set
996# CONFIG_NLS_CODEPAGE_862 is not set
997# CONFIG_NLS_CODEPAGE_863 is not set
998# CONFIG_NLS_CODEPAGE_864 is not set
999# CONFIG_NLS_CODEPAGE_865 is not set
1000# CONFIG_NLS_CODEPAGE_866 is not set
1001# CONFIG_NLS_CODEPAGE_869 is not set
1002# CONFIG_NLS_CODEPAGE_936 is not set
1003# CONFIG_NLS_CODEPAGE_950 is not set
1004CONFIG_NLS_CODEPAGE_932=y
1005# CONFIG_NLS_CODEPAGE_949 is not set
1006# CONFIG_NLS_CODEPAGE_874 is not set
1007# CONFIG_NLS_ISO8859_8 is not set
1008# CONFIG_NLS_CODEPAGE_1250 is not set
1009# CONFIG_NLS_CODEPAGE_1251 is not set
1010# CONFIG_NLS_ASCII is not set
1011CONFIG_NLS_ISO8859_1=y
1012# CONFIG_NLS_ISO8859_2 is not set
1013# CONFIG_NLS_ISO8859_3 is not set
1014# CONFIG_NLS_ISO8859_4 is not set
1015# CONFIG_NLS_ISO8859_5 is not set
1016# CONFIG_NLS_ISO8859_6 is not set
1017# CONFIG_NLS_ISO8859_7 is not set
1018# CONFIG_NLS_ISO8859_9 is not set
1019# CONFIG_NLS_ISO8859_13 is not set
1020# CONFIG_NLS_ISO8859_14 is not set
1021# CONFIG_NLS_ISO8859_15 is not set
1022# CONFIG_NLS_KOI8_R is not set
1023# CONFIG_NLS_KOI8_U is not set
1024# CONFIG_NLS_UTF8 is not set
1025
1026#
1027# Profiling support
1028#
1029# CONFIG_PROFILING is not set
1030
1031#
1032# Kernel hacking
1033#
1034# CONFIG_PRINTK_TIME is not set
1035CONFIG_DEBUG_KERNEL=y
1036# CONFIG_MAGIC_SYSRQ is not set
1037CONFIG_LOG_BUF_SHIFT=14
1038CONFIG_DETECT_SOFTLOCKUP=y
1039# CONFIG_SCHEDSTATS is not set
1040# CONFIG_DEBUG_SLAB is not set
1041CONFIG_DEBUG_PREEMPT=y
1042CONFIG_DEBUG_SPINLOCK=y
1043# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1044# CONFIG_DEBUG_KOBJECT is not set
1045# CONFIG_DEBUG_INFO is not set
1046CONFIG_DEBUG_FS=y
1047# CONFIG_DEBUG_VM is not set
1048CONFIG_FRAME_POINTER=y
1049# CONFIG_RCU_TORTURE_TEST is not set
1050# CONFIG_SH_STANDARD_BIOS is not set
1051# CONFIG_EARLY_SCIF_CONSOLE is not set
1052# CONFIG_KGDB is not set
1053
1054#
1055# Security options
1056#
1057# CONFIG_KEYS is not set
1058# CONFIG_SECURITY is not set
1059
1060#
1061# Cryptographic options
1062#
1063CONFIG_CRYPTO=y
1064CONFIG_CRYPTO_HMAC=y
1065# CONFIG_CRYPTO_NULL is not set
1066# CONFIG_CRYPTO_MD4 is not set
1067CONFIG_CRYPTO_MD5=y
1068# CONFIG_CRYPTO_SHA1 is not set
1069# CONFIG_CRYPTO_SHA256 is not set
1070# CONFIG_CRYPTO_SHA512 is not set
1071# CONFIG_CRYPTO_WP512 is not set
1072# CONFIG_CRYPTO_TGR192 is not set
1073CONFIG_CRYPTO_DES=y
1074# CONFIG_CRYPTO_BLOWFISH is not set
1075# CONFIG_CRYPTO_TWOFISH is not set
1076# CONFIG_CRYPTO_SERPENT is not set
1077# CONFIG_CRYPTO_AES is not set
1078# CONFIG_CRYPTO_CAST5 is not set
1079# CONFIG_CRYPTO_CAST6 is not set
1080# CONFIG_CRYPTO_TEA is not set
1081# CONFIG_CRYPTO_ARC4 is not set
1082# CONFIG_CRYPTO_KHAZAD is not set
1083# CONFIG_CRYPTO_ANUBIS is not set
1084# CONFIG_CRYPTO_DEFLATE is not set
1085# CONFIG_CRYPTO_MICHAEL_MIC is not set
1086# CONFIG_CRYPTO_CRC32C is not set
1087# CONFIG_CRYPTO_TEST is not set
1088
1089#
1090# Hardware crypto devices
1091#
1092
1093#
1094# Library routines
1095#
1096# CONFIG_CRC_CCITT is not set
1097# CONFIG_CRC16 is not set
1098CONFIG_CRC32=y
1099# CONFIG_LIBCRC32C is not set
diff --git a/arch/sh/configs/se73180_defconfig b/arch/sh/configs/se73180_defconfig
index d217e44c89a6..fe19feb95ca9 100644
--- a/arch/sh/configs/se73180_defconfig
+++ b/arch/sh/configs/se73180_defconfig
@@ -78,6 +78,7 @@ CONFIG_SH_73180_SOLUTION_ENGINE=y
78# CONFIG_SH_SECUREEDGE5410 is not set 78# CONFIG_SH_SECUREEDGE5410 is not set
79# CONFIG_SH_HS7751RVOIP is not set 79# CONFIG_SH_HS7751RVOIP is not set
80# CONFIG_SH_RTS7751R2D is not set 80# CONFIG_SH_RTS7751R2D is not set
81# CONFIG_SH_R7780RP is not set
81# CONFIG_SH_EDOSK7705 is not set 82# CONFIG_SH_EDOSK7705 is not set
82# CONFIG_SH_SH4202_MICRODEV is not set 83# CONFIG_SH_SH4202_MICRODEV is not set
83# CONFIG_SH_UNKNOWN is not set 84# CONFIG_SH_UNKNOWN is not set
diff --git a/arch/sh/configs/se7343_defconfig b/arch/sh/configs/se7343_defconfig
new file mode 100644
index 000000000000..948e507b52be
--- /dev/null
+++ b/arch/sh/configs/se7343_defconfig
@@ -0,0 +1,997 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.17
4# Mon Aug 7 20:14:44 2006
5#
6CONFIG_SUPERH=y
7CONFIG_RWSEM_GENERIC_SPINLOCK=y
8CONFIG_GENERIC_FIND_NEXT_BIT=y
9CONFIG_GENERIC_HWEIGHT=y
10CONFIG_GENERIC_HARDIRQS=y
11CONFIG_GENERIC_IRQ_PROBE=y
12CONFIG_GENERIC_CALIBRATE_DELAY=y
13
14#
15# Code maturity level options
16#
17CONFIG_EXPERIMENTAL=y
18CONFIG_BROKEN_ON_SMP=y
19CONFIG_INIT_ENV_ARG_LIMIT=32
20
21#
22# General setup
23#
24CONFIG_LOCALVERSION=""
25CONFIG_LOCALVERSION_AUTO=y
26# CONFIG_SWAP is not set
27CONFIG_SYSVIPC=y
28CONFIG_POSIX_MQUEUE=y
29# CONFIG_BSD_PROCESS_ACCT is not set
30CONFIG_SYSCTL=y
31# CONFIG_AUDIT is not set
32# CONFIG_IKCONFIG is not set
33# CONFIG_RELAY is not set
34CONFIG_INITRAMFS_SOURCE=""
35CONFIG_UID16=y
36CONFIG_CC_OPTIMIZE_FOR_SIZE=y
37CONFIG_EMBEDDED=y
38CONFIG_KALLSYMS=y
39# CONFIG_KALLSYMS_EXTRA_PASS is not set
40CONFIG_HOTPLUG=y
41CONFIG_PRINTK=y
42CONFIG_BUG=y
43CONFIG_ELF_CORE=y
44CONFIG_BASE_FULL=y
45# CONFIG_FUTEX is not set
46# CONFIG_EPOLL is not set
47# CONFIG_SHMEM is not set
48CONFIG_SLAB=y
49CONFIG_TINY_SHMEM=y
50CONFIG_BASE_SMALL=0
51# CONFIG_SLOB is not set
52CONFIG_OBSOLETE_INTERMODULE=y
53
54#
55# Loadable module support
56#
57CONFIG_MODULES=y
58CONFIG_MODULE_UNLOAD=y
59CONFIG_MODULE_FORCE_UNLOAD=y
60# CONFIG_MODVERSIONS is not set
61# CONFIG_MODULE_SRCVERSION_ALL is not set
62# CONFIG_KMOD is not set
63
64#
65# Block layer
66#
67# CONFIG_LBD is not set
68# CONFIG_BLK_DEV_IO_TRACE is not set
69# CONFIG_LSF is not set
70
71#
72# IO Schedulers
73#
74CONFIG_IOSCHED_NOOP=y
75# CONFIG_IOSCHED_AS is not set
76CONFIG_IOSCHED_DEADLINE=y
77# CONFIG_IOSCHED_CFQ is not set
78# CONFIG_DEFAULT_AS is not set
79CONFIG_DEFAULT_DEADLINE=y
80# CONFIG_DEFAULT_CFQ is not set
81# CONFIG_DEFAULT_NOOP is not set
82CONFIG_DEFAULT_IOSCHED="deadline"
83
84#
85# System type
86#
87CONFIG_SOLUTION_ENGINE=y
88# CONFIG_SH_SOLUTION_ENGINE is not set
89# CONFIG_SH_7751_SOLUTION_ENGINE is not set
90# CONFIG_SH_7300_SOLUTION_ENGINE is not set
91CONFIG_SH_7343_SOLUTION_ENGINE=y
92# CONFIG_SH_73180_SOLUTION_ENGINE is not set
93# CONFIG_SH_7751_SYSTEMH is not set
94# CONFIG_SH_HP6XX is not set
95# CONFIG_SH_EC3104 is not set
96# CONFIG_SH_SATURN is not set
97# CONFIG_SH_DREAMCAST is not set
98# CONFIG_SH_BIGSUR is not set
99# CONFIG_SH_MPC1211 is not set
100# CONFIG_SH_SH03 is not set
101# CONFIG_SH_SECUREEDGE5410 is not set
102# CONFIG_SH_HS7751RVOIP is not set
103# CONFIG_SH_7710VOIPGW is not set
104# CONFIG_SH_RTS7751R2D is not set
105# CONFIG_SH_R7780RP is not set
106# CONFIG_SH_EDOSK7705 is not set
107# CONFIG_SH_SH4202_MICRODEV is not set
108# CONFIG_SH_LANDISK is not set
109# CONFIG_SH_TITAN is not set
110# CONFIG_SH_SHMIN is not set
111# CONFIG_SH_UNKNOWN is not set
112
113#
114# Processor selection
115#
116CONFIG_CPU_SH4=y
117CONFIG_CPU_SH4A=y
118
119#
120# SH-2 Processor Support
121#
122# CONFIG_CPU_SUBTYPE_SH7604 is not set
123
124#
125# SH-3 Processor Support
126#
127# CONFIG_CPU_SUBTYPE_SH7300 is not set
128# CONFIG_CPU_SUBTYPE_SH7705 is not set
129# CONFIG_CPU_SUBTYPE_SH7706 is not set
130# CONFIG_CPU_SUBTYPE_SH7707 is not set
131# CONFIG_CPU_SUBTYPE_SH7708 is not set
132# CONFIG_CPU_SUBTYPE_SH7709 is not set
133# CONFIG_CPU_SUBTYPE_SH7710 is not set
134
135#
136# SH-4 Processor Support
137#
138# CONFIG_CPU_SUBTYPE_SH7750 is not set
139# CONFIG_CPU_SUBTYPE_SH7091 is not set
140# CONFIG_CPU_SUBTYPE_SH7750R is not set
141# CONFIG_CPU_SUBTYPE_SH7750S is not set
142# CONFIG_CPU_SUBTYPE_SH7751 is not set
143# CONFIG_CPU_SUBTYPE_SH7751R is not set
144# CONFIG_CPU_SUBTYPE_SH7760 is not set
145# CONFIG_CPU_SUBTYPE_SH4_202 is not set
146
147#
148# ST40 Processor Support
149#
150# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
151# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
152
153#
154# SH-4A Processor Support
155#
156# CONFIG_CPU_SUBTYPE_SH73180 is not set
157CONFIG_CPU_SUBTYPE_SH7343=y
158# CONFIG_CPU_SUBTYPE_SH7770 is not set
159# CONFIG_CPU_SUBTYPE_SH7780 is not set
160
161#
162# Memory management options
163#
164CONFIG_MMU=y
165CONFIG_PAGE_OFFSET=0x80000000
166CONFIG_MEMORY_START=0x0c000000
167CONFIG_MEMORY_SIZE=0x01000000
168CONFIG_32BIT=y
169CONFIG_SELECT_MEMORY_MODEL=y
170CONFIG_FLATMEM_MANUAL=y
171# CONFIG_DISCONTIGMEM_MANUAL is not set
172# CONFIG_SPARSEMEM_MANUAL is not set
173CONFIG_FLATMEM=y
174CONFIG_FLAT_NODE_MEM_MAP=y
175# CONFIG_SPARSEMEM_STATIC is not set
176CONFIG_SPLIT_PTLOCK_CPUS=4
177
178#
179# Cache configuration
180#
181# CONFIG_SH_DIRECT_MAPPED is not set
182# CONFIG_SH_WRITETHROUGH is not set
183# CONFIG_SH_OCRAM is not set
184
185#
186# Processor features
187#
188CONFIG_CPU_LITTLE_ENDIAN=y
189# CONFIG_SH_FPU is not set
190# CONFIG_SH_FPU_EMU is not set
191CONFIG_SH_DSP=y
192# CONFIG_SH_STORE_QUEUES is not set
193CONFIG_CPU_HAS_INTEVT=y
194CONFIG_CPU_HAS_SR_RB=y
195
196#
197# Timer support
198#
199CONFIG_SH_TMU=y
200CONFIG_SH_PCLK_FREQ=27000000
201
202#
203# CPU Frequency scaling
204#
205# CONFIG_CPU_FREQ is not set
206
207#
208# DMA support
209#
210# CONFIG_SH_DMA is not set
211
212#
213# Companion Chips
214#
215# CONFIG_HD6446X_SERIES is not set
216CONFIG_HEARTBEAT=y
217
218#
219# Kernel features
220#
221# CONFIG_HZ_100 is not set
222CONFIG_HZ_250=y
223# CONFIG_HZ_1000 is not set
224CONFIG_HZ=250
225# CONFIG_KEXEC is not set
226# CONFIG_SMP is not set
227CONFIG_PREEMPT_NONE=y
228# CONFIG_PREEMPT_VOLUNTARY is not set
229# CONFIG_PREEMPT is not set
230
231#
232# Boot options
233#
234CONFIG_ZERO_PAGE_OFFSET=0x00001000
235CONFIG_BOOT_LINK_OFFSET=0x00800000
236# CONFIG_UBC_WAKEUP is not set
237# CONFIG_CMDLINE_BOOL is not set
238
239#
240# Bus options
241#
242# CONFIG_PCI is not set
243
244#
245# PCCARD (PCMCIA/CardBus) support
246#
247# CONFIG_PCCARD is not set
248
249#
250# PCI Hotplug Support
251#
252
253#
254# Executable file formats
255#
256CONFIG_BINFMT_ELF=y
257# CONFIG_BINFMT_FLAT is not set
258# CONFIG_BINFMT_MISC is not set
259
260#
261# Power management options (EXPERIMENTAL)
262#
263# CONFIG_PM is not set
264
265#
266# Networking
267#
268CONFIG_NET=y
269
270#
271# Networking options
272#
273# CONFIG_NETDEBUG is not set
274CONFIG_PACKET=y
275CONFIG_PACKET_MMAP=y
276CONFIG_UNIX=y
277# CONFIG_NET_KEY is not set
278CONFIG_INET=y
279# CONFIG_IP_MULTICAST is not set
280# CONFIG_IP_ADVANCED_ROUTER is not set
281CONFIG_IP_FIB_HASH=y
282CONFIG_IP_PNP=y
283CONFIG_IP_PNP_DHCP=y
284# CONFIG_IP_PNP_BOOTP is not set
285# CONFIG_IP_PNP_RARP is not set
286# CONFIG_NET_IPIP is not set
287# CONFIG_NET_IPGRE is not set
288# CONFIG_ARPD is not set
289CONFIG_SYN_COOKIES=y
290# CONFIG_INET_AH is not set
291# CONFIG_INET_ESP is not set
292# CONFIG_INET_IPCOMP is not set
293# CONFIG_INET_XFRM_TUNNEL is not set
294# CONFIG_INET_TUNNEL is not set
295# CONFIG_INET_DIAG is not set
296# CONFIG_TCP_CONG_ADVANCED is not set
297CONFIG_TCP_CONG_BIC=y
298# CONFIG_IPV6 is not set
299# CONFIG_INET6_XFRM_TUNNEL is not set
300# CONFIG_INET6_TUNNEL is not set
301# CONFIG_NETFILTER is not set
302
303#
304# DCCP Configuration (EXPERIMENTAL)
305#
306# CONFIG_IP_DCCP is not set
307
308#
309# SCTP Configuration (EXPERIMENTAL)
310#
311# CONFIG_IP_SCTP is not set
312
313#
314# TIPC Configuration (EXPERIMENTAL)
315#
316# CONFIG_TIPC is not set
317# CONFIG_ATM is not set
318# CONFIG_BRIDGE is not set
319# CONFIG_VLAN_8021Q is not set
320# CONFIG_DECNET is not set
321# CONFIG_LLC2 is not set
322# CONFIG_IPX is not set
323# CONFIG_ATALK is not set
324# CONFIG_X25 is not set
325# CONFIG_LAPB is not set
326# CONFIG_NET_DIVERT is not set
327# CONFIG_ECONET is not set
328# CONFIG_WAN_ROUTER is not set
329
330#
331# QoS and/or fair queueing
332#
333# CONFIG_NET_SCHED is not set
334
335#
336# Network testing
337#
338# CONFIG_NET_PKTGEN is not set
339# CONFIG_HAMRADIO is not set
340# CONFIG_IRDA is not set
341# CONFIG_BT is not set
342# CONFIG_IEEE80211 is not set
343
344#
345# Device Drivers
346#
347
348#
349# Generic Driver Options
350#
351CONFIG_STANDALONE=y
352CONFIG_PREVENT_FIRMWARE_BUILD=y
353CONFIG_FW_LOADER=y
354
355#
356# Connector - unified userspace <-> kernelspace linker
357#
358# CONFIG_CONNECTOR is not set
359
360#
361# Memory Technology Devices (MTD)
362#
363CONFIG_MTD=y
364# CONFIG_MTD_DEBUG is not set
365CONFIG_MTD_CONCAT=y
366CONFIG_MTD_PARTITIONS=y
367# CONFIG_MTD_REDBOOT_PARTS is not set
368# CONFIG_MTD_CMDLINE_PARTS is not set
369
370#
371# User Modules And Translation Layers
372#
373CONFIG_MTD_CHAR=y
374CONFIG_MTD_BLOCK=y
375# CONFIG_FTL is not set
376# CONFIG_NFTL is not set
377# CONFIG_INFTL is not set
378# CONFIG_RFD_FTL is not set
379
380#
381# RAM/ROM/Flash chip drivers
382#
383CONFIG_MTD_CFI=y
384# CONFIG_MTD_JEDECPROBE is not set
385CONFIG_MTD_GEN_PROBE=y
386# CONFIG_MTD_CFI_ADV_OPTIONS is not set
387CONFIG_MTD_MAP_BANK_WIDTH_1=y
388CONFIG_MTD_MAP_BANK_WIDTH_2=y
389CONFIG_MTD_MAP_BANK_WIDTH_4=y
390# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
391# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
392# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
393CONFIG_MTD_CFI_I1=y
394CONFIG_MTD_CFI_I2=y
395# CONFIG_MTD_CFI_I4 is not set
396# CONFIG_MTD_CFI_I8 is not set
397# CONFIG_MTD_CFI_INTELEXT is not set
398CONFIG_MTD_CFI_AMDSTD=y
399# CONFIG_MTD_CFI_STAA is not set
400CONFIG_MTD_CFI_UTIL=y
401CONFIG_MTD_RAM=y
402# CONFIG_MTD_ROM is not set
403# CONFIG_MTD_ABSENT is not set
404# CONFIG_MTD_OBSOLETE_CHIPS is not set
405
406#
407# Mapping drivers for chip access
408#
409# CONFIG_MTD_COMPLEX_MAPPINGS is not set
410# CONFIG_MTD_PHYSMAP is not set
411# CONFIG_MTD_SOLUTIONENGINE is not set
412# CONFIG_MTD_PLATRAM is not set
413
414#
415# Self-contained MTD device drivers
416#
417# CONFIG_MTD_SLRAM is not set
418# CONFIG_MTD_PHRAM is not set
419# CONFIG_MTD_MTDRAM is not set
420# CONFIG_MTD_BLOCK2MTD is not set
421
422#
423# Disk-On-Chip Device Drivers
424#
425# CONFIG_MTD_DOC2000 is not set
426# CONFIG_MTD_DOC2001 is not set
427# CONFIG_MTD_DOC2001PLUS is not set
428
429#
430# NAND Flash Device Drivers
431#
432# CONFIG_MTD_NAND is not set
433
434#
435# OneNAND Flash Device Drivers
436#
437# CONFIG_MTD_ONENAND is not set
438
439#
440# Parallel port support
441#
442# CONFIG_PARPORT is not set
443
444#
445# Plug and Play support
446#
447
448#
449# Block devices
450#
451# CONFIG_BLK_DEV_COW_COMMON is not set
452# CONFIG_BLK_DEV_LOOP is not set
453# CONFIG_BLK_DEV_NBD is not set
454# CONFIG_BLK_DEV_RAM is not set
455# CONFIG_BLK_DEV_INITRD is not set
456# CONFIG_CDROM_PKTCDVD is not set
457# CONFIG_ATA_OVER_ETH is not set
458
459#
460# ATA/ATAPI/MFM/RLL support
461#
462# CONFIG_IDE is not set
463
464#
465# SCSI device support
466#
467# CONFIG_RAID_ATTRS is not set
468# CONFIG_SCSI is not set
469
470#
471# Multi-device support (RAID and LVM)
472#
473# CONFIG_MD is not set
474
475#
476# Fusion MPT device support
477#
478# CONFIG_FUSION is not set
479
480#
481# IEEE 1394 (FireWire) support
482#
483
484#
485# I2O device support
486#
487
488#
489# Network device support
490#
491CONFIG_NETDEVICES=y
492# CONFIG_DUMMY is not set
493# CONFIG_BONDING is not set
494# CONFIG_EQUALIZER is not set
495# CONFIG_TUN is not set
496
497#
498# PHY device support
499#
500# CONFIG_PHYLIB is not set
501
502#
503# Ethernet (10 or 100Mbit)
504#
505CONFIG_NET_ETHERNET=y
506CONFIG_MII=y
507# CONFIG_STNIC is not set
508CONFIG_SMC91X=y
509# CONFIG_NE2000 is not set
510
511#
512# Ethernet (1000 Mbit)
513#
514
515#
516# Ethernet (10000 Mbit)
517#
518
519#
520# Token Ring devices
521#
522
523#
524# Wireless LAN (non-hamradio)
525#
526# CONFIG_NET_RADIO is not set
527
528#
529# Wan interfaces
530#
531# CONFIG_WAN is not set
532# CONFIG_PPP is not set
533# CONFIG_SLIP is not set
534# CONFIG_SHAPER is not set
535# CONFIG_NETCONSOLE is not set
536# CONFIG_NETPOLL is not set
537# CONFIG_NET_POLL_CONTROLLER is not set
538
539#
540# ISDN subsystem
541#
542# CONFIG_ISDN is not set
543
544#
545# Telephony Support
546#
547# CONFIG_PHONE is not set
548
549#
550# Input device support
551#
552CONFIG_INPUT=y
553
554#
555# Userland interfaces
556#
557# CONFIG_INPUT_MOUSEDEV is not set
558# CONFIG_INPUT_JOYDEV is not set
559# CONFIG_INPUT_TSDEV is not set
560# CONFIG_INPUT_EVDEV is not set
561# CONFIG_INPUT_EVBUG is not set
562
563#
564# Input Device Drivers
565#
566# CONFIG_INPUT_KEYBOARD is not set
567# CONFIG_INPUT_MOUSE is not set
568# CONFIG_INPUT_JOYSTICK is not set
569# CONFIG_INPUT_TOUCHSCREEN is not set
570# CONFIG_INPUT_MISC is not set
571
572#
573# Hardware I/O ports
574#
575# CONFIG_SERIO is not set
576# CONFIG_GAMEPORT is not set
577
578#
579# Character devices
580#
581CONFIG_VT=y
582CONFIG_VT_CONSOLE=y
583CONFIG_HW_CONSOLE=y
584# CONFIG_SERIAL_NONSTANDARD is not set
585
586#
587# Serial drivers
588#
589# CONFIG_SERIAL_8250 is not set
590
591#
592# Non-8250 serial port support
593#
594CONFIG_SERIAL_SH_SCI=y
595CONFIG_SERIAL_SH_SCI_NR_UARTS=2
596CONFIG_SERIAL_SH_SCI_CONSOLE=y
597CONFIG_SERIAL_CORE=y
598CONFIG_SERIAL_CORE_CONSOLE=y
599# CONFIG_UNIX98_PTYS is not set
600CONFIG_LEGACY_PTYS=y
601CONFIG_LEGACY_PTY_COUNT=256
602
603#
604# IPMI
605#
606# CONFIG_IPMI_HANDLER is not set
607
608#
609# Watchdog Cards
610#
611# CONFIG_WATCHDOG is not set
612# CONFIG_RTC is not set
613# CONFIG_GEN_RTC is not set
614# CONFIG_DTLK is not set
615# CONFIG_R3964 is not set
616
617#
618# Ftape, the floppy tape device driver
619#
620# CONFIG_RAW_DRIVER is not set
621
622#
623# TPM devices
624#
625# CONFIG_TCG_TPM is not set
626# CONFIG_TELCLOCK is not set
627
628#
629# I2C support
630#
631CONFIG_I2C=y
632CONFIG_I2C_CHARDEV=y
633
634#
635# I2C Algorithms
636#
637# CONFIG_I2C_ALGOBIT is not set
638# CONFIG_I2C_ALGOPCF is not set
639# CONFIG_I2C_ALGOPCA is not set
640
641#
642# I2C Hardware Bus support
643#
644# CONFIG_I2C_PARPORT_LIGHT is not set
645# CONFIG_I2C_STUB is not set
646# CONFIG_I2C_PCA_ISA is not set
647CONFIG_I2C_SH7343=y
648
649#
650# Miscellaneous I2C Chip support
651#
652# CONFIG_SENSORS_DS1337 is not set
653# CONFIG_SENSORS_DS1374 is not set
654# CONFIG_SENSORS_EEPROM is not set
655# CONFIG_SENSORS_PCF8574 is not set
656# CONFIG_SENSORS_PCA9539 is not set
657# CONFIG_SENSORS_PCF8591 is not set
658# CONFIG_SENSORS_MAX6875 is not set
659# CONFIG_I2C_DEBUG_CORE is not set
660# CONFIG_I2C_DEBUG_ALGO is not set
661# CONFIG_I2C_DEBUG_BUS is not set
662# CONFIG_I2C_DEBUG_CHIP is not set
663
664#
665# SPI support
666#
667# CONFIG_SPI is not set
668# CONFIG_SPI_MASTER is not set
669
670#
671# Dallas's 1-wire bus
672#
673# CONFIG_W1 is not set
674
675#
676# Hardware Monitoring support
677#
678# CONFIG_HWMON is not set
679# CONFIG_HWMON_VID is not set
680
681#
682# Misc devices
683#
684
685#
686# Multimedia devices
687#
688CONFIG_VIDEO_DEV=y
689CONFIG_VIDEO_V4L1=y
690CONFIG_VIDEO_V4L1_COMPAT=y
691CONFIG_VIDEO_V4L2=y
692
693#
694# Video Capture Adapters
695#
696
697#
698# Video Capture Adapters
699#
700# CONFIG_VIDEO_ADV_DEBUG is not set
701# CONFIG_VIDEO_VIVI is not set
702# CONFIG_VIDEO_CPIA is not set
703# CONFIG_VIDEO_SAA5246A is not set
704# CONFIG_VIDEO_SAA5249 is not set
705# CONFIG_TUNER_3036 is not set
706# CONFIG_VIDEO_OVCAMCHIP is not set
707
708#
709# Encoders and Decoders
710#
711# CONFIG_VIDEO_MSP3400 is not set
712# CONFIG_VIDEO_CS53L32A is not set
713# CONFIG_VIDEO_WM8775 is not set
714# CONFIG_VIDEO_WM8739 is not set
715# CONFIG_VIDEO_CX25840 is not set
716# CONFIG_VIDEO_SAA711X is not set
717# CONFIG_VIDEO_SAA7127 is not set
718# CONFIG_VIDEO_UPD64031A is not set
719# CONFIG_VIDEO_UPD64083 is not set
720
721#
722# Radio Adapters
723#
724# CONFIG_RADIO_MAESTRO is not set
725
726#
727# Digital Video Broadcasting Devices
728#
729# CONFIG_DVB is not set
730
731#
732# Graphics support
733#
734CONFIG_FB=y
735# CONFIG_FB_CFB_FILLRECT is not set
736# CONFIG_FB_CFB_COPYAREA is not set
737# CONFIG_FB_CFB_IMAGEBLIT is not set
738# CONFIG_FB_MACMODES is not set
739CONFIG_FB_FIRMWARE_EDID=y
740# CONFIG_FB_MODE_HELPERS is not set
741# CONFIG_FB_TILEBLITTING is not set
742# CONFIG_FB_EPSON1355 is not set
743# CONFIG_FB_S1D13XXX is not set
744# CONFIG_FB_VIRTUAL is not set
745
746#
747# Console display driver support
748#
749CONFIG_DUMMY_CONSOLE=y
750# CONFIG_FRAMEBUFFER_CONSOLE is not set
751
752#
753# Logo configuration
754#
755# CONFIG_LOGO is not set
756# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
757
758#
759# Sound
760#
761CONFIG_SOUND=y
762
763#
764# Advanced Linux Sound Architecture
765#
766CONFIG_SND=y
767CONFIG_SND_TIMER=y
768CONFIG_SND_PCM=y
769CONFIG_SND_SEQUENCER=y
770# CONFIG_SND_SEQ_DUMMY is not set
771CONFIG_SND_OSSEMUL=y
772# CONFIG_SND_MIXER_OSS is not set
773CONFIG_SND_PCM_OSS=y
774CONFIG_SND_PCM_OSS_PLUGINS=y
775# CONFIG_SND_SEQUENCER_OSS is not set
776# CONFIG_SND_DYNAMIC_MINORS is not set
777CONFIG_SND_SUPPORT_OLD_API=y
778CONFIG_SND_VERBOSE_PROCFS=y
779# CONFIG_SND_VERBOSE_PRINTK is not set
780# CONFIG_SND_DEBUG is not set
781
782#
783# Generic devices
784#
785# CONFIG_SND_DUMMY is not set
786# CONFIG_SND_VIRMIDI is not set
787# CONFIG_SND_MTPAV is not set
788# CONFIG_SND_SERIAL_U16550 is not set
789# CONFIG_SND_MPU401 is not set
790
791#
792# SuperH devices
793#
794CONFIG_SH7343_SIU=m
795CONFIG_AK4537_CODEC=y
796
797#
798# Open Sound System
799#
800# CONFIG_SOUND_PRIME is not set
801
802#
803# USB support
804#
805# CONFIG_USB_ARCH_HAS_HCD is not set
806# CONFIG_USB_ARCH_HAS_OHCI is not set
807# CONFIG_USB_ARCH_HAS_EHCI is not set
808
809#
810# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
811#
812
813#
814# USB Gadget Support
815#
816# CONFIG_USB_GADGET is not set
817
818#
819# MMC/SD Card support
820#
821# CONFIG_MMC is not set
822
823#
824# LED devices
825#
826# CONFIG_NEW_LEDS is not set
827
828#
829# LED drivers
830#
831
832#
833# LED Triggers
834#
835
836#
837# InfiniBand support
838#
839
840#
841# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
842#
843
844#
845# Real Time Clock
846#
847# CONFIG_RTC_CLASS is not set
848
849#
850# File systems
851#
852# CONFIG_EXT2_FS is not set
853# CONFIG_EXT3_FS is not set
854# CONFIG_REISERFS_FS is not set
855# CONFIG_JFS_FS is not set
856# CONFIG_FS_POSIX_ACL is not set
857# CONFIG_XFS_FS is not set
858# CONFIG_OCFS2_FS is not set
859# CONFIG_MINIX_FS is not set
860# CONFIG_ROMFS_FS is not set
861# CONFIG_INOTIFY is not set
862# CONFIG_QUOTA is not set
863# CONFIG_DNOTIFY is not set
864# CONFIG_AUTOFS_FS is not set
865# CONFIG_AUTOFS4_FS is not set
866# CONFIG_FUSE_FS is not set
867
868#
869# CD-ROM/DVD Filesystems
870#
871# CONFIG_ISO9660_FS is not set
872# CONFIG_UDF_FS is not set
873
874#
875# DOS/FAT/NT Filesystems
876#
877# CONFIG_MSDOS_FS is not set
878# CONFIG_VFAT_FS is not set
879# CONFIG_NTFS_FS is not set
880
881#
882# Pseudo filesystems
883#
884CONFIG_PROC_FS=y
885# CONFIG_PROC_KCORE is not set
886CONFIG_SYSFS=y
887CONFIG_TMPFS=y
888# CONFIG_HUGETLBFS is not set
889# CONFIG_HUGETLB_PAGE is not set
890CONFIG_RAMFS=y
891# CONFIG_CONFIGFS_FS is not set
892
893#
894# Miscellaneous filesystems
895#
896# CONFIG_ADFS_FS is not set
897# CONFIG_AFFS_FS is not set
898# CONFIG_HFS_FS is not set
899# CONFIG_HFSPLUS_FS is not set
900# CONFIG_BEFS_FS is not set
901# CONFIG_BFS_FS is not set
902# CONFIG_EFS_FS is not set
903# CONFIG_JFFS_FS is not set
904CONFIG_JFFS2_FS=y
905CONFIG_JFFS2_FS_DEBUG=0
906CONFIG_JFFS2_FS_WRITEBUFFER=y
907# CONFIG_JFFS2_SUMMARY is not set
908# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
909CONFIG_JFFS2_ZLIB=y
910CONFIG_JFFS2_RTIME=y
911# CONFIG_JFFS2_RUBIN is not set
912# CONFIG_CRAMFS is not set
913# CONFIG_VXFS_FS is not set
914# CONFIG_HPFS_FS is not set
915# CONFIG_QNX4FS_FS is not set
916# CONFIG_SYSV_FS is not set
917# CONFIG_UFS_FS is not set
918
919#
920# Network File Systems
921#
922CONFIG_NFS_FS=y
923CONFIG_NFS_V3=y
924# CONFIG_NFS_V3_ACL is not set
925# CONFIG_NFS_V4 is not set
926# CONFIG_NFS_DIRECTIO is not set
927CONFIG_NFSD=y
928# CONFIG_NFSD_V3 is not set
929# CONFIG_NFSD_TCP is not set
930CONFIG_ROOT_NFS=y
931CONFIG_LOCKD=y
932CONFIG_LOCKD_V4=y
933CONFIG_EXPORTFS=y
934CONFIG_NFS_COMMON=y
935CONFIG_SUNRPC=y
936# CONFIG_RPCSEC_GSS_KRB5 is not set
937# CONFIG_RPCSEC_GSS_SPKM3 is not set
938# CONFIG_SMB_FS is not set
939# CONFIG_CIFS is not set
940# CONFIG_NCP_FS is not set
941# CONFIG_CODA_FS is not set
942# CONFIG_AFS_FS is not set
943# CONFIG_9P_FS is not set
944
945#
946# Partition Types
947#
948# CONFIG_PARTITION_ADVANCED is not set
949CONFIG_MSDOS_PARTITION=y
950
951#
952# Native Language Support
953#
954# CONFIG_NLS is not set
955
956#
957# Profiling support
958#
959# CONFIG_PROFILING is not set
960
961#
962# Kernel hacking
963#
964# CONFIG_PRINTK_TIME is not set
965# CONFIG_MAGIC_SYSRQ is not set
966# CONFIG_DEBUG_KERNEL is not set
967CONFIG_LOG_BUF_SHIFT=14
968# CONFIG_DEBUG_BUGVERBOSE is not set
969# CONFIG_DEBUG_FS is not set
970# CONFIG_SH_STANDARD_BIOS is not set
971# CONFIG_EARLY_SCIF_CONSOLE is not set
972# CONFIG_KGDB is not set
973
974#
975# Security options
976#
977# CONFIG_KEYS is not set
978# CONFIG_SECURITY is not set
979
980#
981# Cryptographic options
982#
983# CONFIG_CRYPTO is not set
984
985#
986# Hardware crypto devices
987#
988
989#
990# Library routines
991#
992# CONFIG_CRC_CCITT is not set
993# CONFIG_CRC16 is not set
994CONFIG_CRC32=y
995# CONFIG_LIBCRC32C is not set
996CONFIG_ZLIB_INFLATE=y
997CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/sh/configs/sh7710voipgw_defconfig b/arch/sh/configs/sh7710voipgw_defconfig
new file mode 100644
index 000000000000..ec9a3034daa5
--- /dev/null
+++ b/arch/sh/configs/sh7710voipgw_defconfig
@@ -0,0 +1,913 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.17
4# Mon Aug 7 17:07:06 2006
5#
6CONFIG_SUPERH=y
7CONFIG_RWSEM_GENERIC_SPINLOCK=y
8CONFIG_GENERIC_FIND_NEXT_BIT=y
9CONFIG_GENERIC_HWEIGHT=y
10CONFIG_GENERIC_HARDIRQS=y
11CONFIG_GENERIC_IRQ_PROBE=y
12CONFIG_GENERIC_CALIBRATE_DELAY=y
13
14#
15# Code maturity level options
16#
17CONFIG_EXPERIMENTAL=y
18CONFIG_BROKEN_ON_SMP=y
19CONFIG_INIT_ENV_ARG_LIMIT=32
20
21#
22# General setup
23#
24CONFIG_LOCALVERSION=""
25CONFIG_LOCALVERSION_AUTO=y
26# CONFIG_SWAP is not set
27CONFIG_SYSVIPC=y
28CONFIG_POSIX_MQUEUE=y
29# CONFIG_BSD_PROCESS_ACCT is not set
30CONFIG_SYSCTL=y
31# CONFIG_AUDIT is not set
32# CONFIG_IKCONFIG is not set
33# CONFIG_RELAY is not set
34CONFIG_INITRAMFS_SOURCE=""
35CONFIG_UID16=y
36CONFIG_CC_OPTIMIZE_FOR_SIZE=y
37CONFIG_EMBEDDED=y
38CONFIG_KALLSYMS=y
39# CONFIG_KALLSYMS_EXTRA_PASS is not set
40CONFIG_HOTPLUG=y
41CONFIG_PRINTK=y
42CONFIG_BUG=y
43CONFIG_ELF_CORE=y
44CONFIG_BASE_FULL=y
45# CONFIG_FUTEX is not set
46# CONFIG_EPOLL is not set
47# CONFIG_SHMEM is not set
48CONFIG_SLAB=y
49CONFIG_TINY_SHMEM=y
50CONFIG_BASE_SMALL=0
51# CONFIG_SLOB is not set
52CONFIG_OBSOLETE_INTERMODULE=y
53
54#
55# Loadable module support
56#
57CONFIG_MODULES=y
58CONFIG_MODULE_UNLOAD=y
59CONFIG_MODULE_FORCE_UNLOAD=y
60# CONFIG_MODVERSIONS is not set
61# CONFIG_MODULE_SRCVERSION_ALL is not set
62# CONFIG_KMOD is not set
63
64#
65# Block layer
66#
67# CONFIG_LBD is not set
68# CONFIG_BLK_DEV_IO_TRACE is not set
69# CONFIG_LSF is not set
70
71#
72# IO Schedulers
73#
74CONFIG_IOSCHED_NOOP=y
75# CONFIG_IOSCHED_AS is not set
76CONFIG_IOSCHED_DEADLINE=y
77# CONFIG_IOSCHED_CFQ is not set
78# CONFIG_DEFAULT_AS is not set
79CONFIG_DEFAULT_DEADLINE=y
80# CONFIG_DEFAULT_CFQ is not set
81# CONFIG_DEFAULT_NOOP is not set
82CONFIG_DEFAULT_IOSCHED="deadline"
83
84#
85# System type
86#
87# CONFIG_SH_SOLUTION_ENGINE is not set
88# CONFIG_SH_7751_SOLUTION_ENGINE is not set
89# CONFIG_SH_7300_SOLUTION_ENGINE is not set
90# CONFIG_SH_73180_SOLUTION_ENGINE is not set
91# CONFIG_SH_7751_SYSTEMH is not set
92# CONFIG_SH_HP6XX is not set
93# CONFIG_SH_EC3104 is not set
94# CONFIG_SH_SATURN is not set
95# CONFIG_SH_DREAMCAST is not set
96# CONFIG_SH_BIGSUR is not set
97# CONFIG_SH_MPC1211 is not set
98# CONFIG_SH_SH03 is not set
99# CONFIG_SH_SECUREEDGE5410 is not set
100# CONFIG_SH_HS7751RVOIP is not set
101CONFIG_SH_7710VOIPGW=y
102# CONFIG_SH_RTS7751R2D is not set
103# CONFIG_SH_R7780RP is not set
104# CONFIG_SH_EDOSK7705 is not set
105# CONFIG_SH_SH4202_MICRODEV is not set
106# CONFIG_SH_LANDISK is not set
107# CONFIG_SH_TITAN is not set
108# CONFIG_SH_SHMIN is not set
109# CONFIG_SH_UNKNOWN is not set
110
111#
112# Processor selection
113#
114CONFIG_CPU_SH3=y
115
116#
117# SH-2 Processor Support
118#
119# CONFIG_CPU_SUBTYPE_SH7604 is not set
120
121#
122# SH-3 Processor Support
123#
124# CONFIG_CPU_SUBTYPE_SH7300 is not set
125# CONFIG_CPU_SUBTYPE_SH7705 is not set
126# CONFIG_CPU_SUBTYPE_SH7706 is not set
127# CONFIG_CPU_SUBTYPE_SH7707 is not set
128# CONFIG_CPU_SUBTYPE_SH7708 is not set
129# CONFIG_CPU_SUBTYPE_SH7709 is not set
130CONFIG_CPU_SUBTYPE_SH7710=y
131
132#
133# SH-4 Processor Support
134#
135# CONFIG_CPU_SUBTYPE_SH7750 is not set
136# CONFIG_CPU_SUBTYPE_SH7091 is not set
137# CONFIG_CPU_SUBTYPE_SH7750R is not set
138# CONFIG_CPU_SUBTYPE_SH7750S is not set
139# CONFIG_CPU_SUBTYPE_SH7751 is not set
140# CONFIG_CPU_SUBTYPE_SH7751R is not set
141# CONFIG_CPU_SUBTYPE_SH7760 is not set
142# CONFIG_CPU_SUBTYPE_SH4_202 is not set
143
144#
145# ST40 Processor Support
146#
147# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
148# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
149
150#
151# SH-4A Processor Support
152#
153# CONFIG_CPU_SUBTYPE_SH73180 is not set
154# CONFIG_CPU_SUBTYPE_SH7770 is not set
155# CONFIG_CPU_SUBTYPE_SH7780 is not set
156
157#
158# Memory management options
159#
160CONFIG_MMU=y
161CONFIG_PAGE_OFFSET=0x80000000
162CONFIG_MEMORY_START=0x0c000000
163CONFIG_MEMORY_SIZE=0x00800000
164CONFIG_SELECT_MEMORY_MODEL=y
165CONFIG_FLATMEM_MANUAL=y
166# CONFIG_DISCONTIGMEM_MANUAL is not set
167# CONFIG_SPARSEMEM_MANUAL is not set
168CONFIG_FLATMEM=y
169CONFIG_FLAT_NODE_MEM_MAP=y
170# CONFIG_SPARSEMEM_STATIC is not set
171CONFIG_SPLIT_PTLOCK_CPUS=4
172
173#
174# Cache configuration
175#
176# CONFIG_SH_DIRECT_MAPPED is not set
177# CONFIG_SH_WRITETHROUGH is not set
178# CONFIG_SH_OCRAM is not set
179
180#
181# Processor features
182#
183CONFIG_CPU_LITTLE_ENDIAN=y
184# CONFIG_SH_FPU_EMU is not set
185CONFIG_SH_DSP=y
186# CONFIG_SH_ADC is not set
187CONFIG_CPU_HAS_INTEVT=y
188CONFIG_CPU_HAS_SR_RB=y
189
190#
191# Timer support
192#
193CONFIG_SH_TMU=y
194CONFIG_SH_PCLK_FREQ=32768000
195
196#
197# CPU Frequency scaling
198#
199# CONFIG_CPU_FREQ is not set
200
201#
202# DMA support
203#
204# CONFIG_SH_DMA is not set
205
206#
207# Companion Chips
208#
209# CONFIG_HD6446X_SERIES is not set
210
211#
212# Kernel features
213#
214# CONFIG_HZ_100 is not set
215CONFIG_HZ_250=y
216# CONFIG_HZ_1000 is not set
217CONFIG_HZ=250
218# CONFIG_KEXEC is not set
219# CONFIG_PREEMPT is not set
220# CONFIG_SMP is not set
221CONFIG_PREEMPT_NONE=y
222# CONFIG_PREEMPT_VOLUNTARY is not set
223
224#
225# Boot options
226#
227CONFIG_ZERO_PAGE_OFFSET=0x00001000
228CONFIG_BOOT_LINK_OFFSET=0x00800000
229# CONFIG_UBC_WAKEUP is not set
230# CONFIG_CMDLINE_BOOL is not set
231
232#
233# Bus options
234#
235# CONFIG_PCI is not set
236
237#
238# PCCARD (PCMCIA/CardBus) support
239#
240# CONFIG_PCCARD is not set
241
242#
243# PCI Hotplug Support
244#
245
246#
247# Executable file formats
248#
249CONFIG_BINFMT_ELF=y
250# CONFIG_BINFMT_FLAT is not set
251# CONFIG_BINFMT_MISC is not set
252
253#
254# Power management options (EXPERIMENTAL)
255#
256# CONFIG_PM is not set
257
258#
259# Networking
260#
261CONFIG_NET=y
262
263#
264# Networking options
265#
266# CONFIG_NETDEBUG is not set
267CONFIG_PACKET=y
268# CONFIG_PACKET_MMAP is not set
269CONFIG_UNIX=y
270# CONFIG_NET_KEY is not set
271CONFIG_INET=y
272# CONFIG_IP_MULTICAST is not set
273# CONFIG_IP_ADVANCED_ROUTER is not set
274CONFIG_IP_FIB_HASH=y
275# CONFIG_IP_PNP is not set
276# CONFIG_NET_IPIP is not set
277# CONFIG_NET_IPGRE is not set
278# CONFIG_ARPD is not set
279CONFIG_SYN_COOKIES=y
280# CONFIG_INET_AH is not set
281# CONFIG_INET_ESP is not set
282# CONFIG_INET_IPCOMP is not set
283# CONFIG_INET_XFRM_TUNNEL is not set
284# CONFIG_INET_TUNNEL is not set
285# CONFIG_INET_DIAG is not set
286# CONFIG_TCP_CONG_ADVANCED is not set
287CONFIG_TCP_CONG_BIC=y
288
289#
290# IP: Virtual Server Configuration
291#
292# CONFIG_IP_VS is not set
293# CONFIG_IPV6 is not set
294# CONFIG_INET6_XFRM_TUNNEL is not set
295# CONFIG_INET6_TUNNEL is not set
296CONFIG_NETFILTER=y
297# CONFIG_NETFILTER_DEBUG is not set
298
299#
300# Core Netfilter Configuration
301#
302# CONFIG_NETFILTER_NETLINK is not set
303# CONFIG_NETFILTER_XTABLES is not set
304
305#
306# IP: Netfilter Configuration
307#
308CONFIG_IP_NF_CONNTRACK=y
309# CONFIG_IP_NF_CT_ACCT is not set
310# CONFIG_IP_NF_CONNTRACK_MARK is not set
311# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
312# CONFIG_IP_NF_CT_PROTO_SCTP is not set
313CONFIG_IP_NF_FTP=m
314# CONFIG_IP_NF_IRC is not set
315# CONFIG_IP_NF_NETBIOS_NS is not set
316# CONFIG_IP_NF_TFTP is not set
317# CONFIG_IP_NF_AMANDA is not set
318CONFIG_IP_NF_PPTP=m
319# CONFIG_IP_NF_H323 is not set
320# CONFIG_IP_NF_QUEUE is not set
321
322#
323# DCCP Configuration (EXPERIMENTAL)
324#
325# CONFIG_IP_DCCP is not set
326
327#
328# SCTP Configuration (EXPERIMENTAL)
329#
330# CONFIG_IP_SCTP is not set
331
332#
333# TIPC Configuration (EXPERIMENTAL)
334#
335# CONFIG_TIPC is not set
336# CONFIG_ATM is not set
337# CONFIG_BRIDGE is not set
338# CONFIG_VLAN_8021Q is not set
339# CONFIG_DECNET is not set
340# CONFIG_LLC2 is not set
341# CONFIG_IPX is not set
342# CONFIG_ATALK is not set
343# CONFIG_X25 is not set
344# CONFIG_LAPB is not set
345# CONFIG_NET_DIVERT is not set
346# CONFIG_ECONET is not set
347# CONFIG_WAN_ROUTER is not set
348
349#
350# QoS and/or fair queueing
351#
352CONFIG_NET_SCHED=y
353CONFIG_NET_SCH_CLK_JIFFIES=y
354# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
355# CONFIG_NET_SCH_CLK_CPU is not set
356
357#
358# Queueing/Scheduling
359#
360CONFIG_NET_SCH_CBQ=y
361# CONFIG_NET_SCH_HTB is not set
362# CONFIG_NET_SCH_HFSC is not set
363# CONFIG_NET_SCH_PRIO is not set
364# CONFIG_NET_SCH_RED is not set
365# CONFIG_NET_SCH_SFQ is not set
366# CONFIG_NET_SCH_TEQL is not set
367# CONFIG_NET_SCH_TBF is not set
368# CONFIG_NET_SCH_GRED is not set
369# CONFIG_NET_SCH_DSMARK is not set
370# CONFIG_NET_SCH_NETEM is not set
371CONFIG_NET_SCH_INGRESS=y
372
373#
374# Classification
375#
376CONFIG_NET_CLS=y
377CONFIG_NET_CLS_BASIC=y
378CONFIG_NET_CLS_TCINDEX=y
379CONFIG_NET_CLS_ROUTE4=y
380CONFIG_NET_CLS_ROUTE=y
381# CONFIG_NET_CLS_FW is not set
382CONFIG_NET_CLS_U32=y
383# CONFIG_CLS_U32_PERF is not set
384# CONFIG_CLS_U32_MARK is not set
385# CONFIG_NET_CLS_RSVP is not set
386# CONFIG_NET_CLS_RSVP6 is not set
387# CONFIG_NET_EMATCH is not set
388# CONFIG_NET_CLS_ACT is not set
389CONFIG_NET_CLS_POLICE=y
390# CONFIG_NET_CLS_IND is not set
391CONFIG_NET_ESTIMATOR=y
392
393#
394# Network testing
395#
396# CONFIG_NET_PKTGEN is not set
397# CONFIG_HAMRADIO is not set
398# CONFIG_IRDA is not set
399# CONFIG_BT is not set
400# CONFIG_IEEE80211 is not set
401
402#
403# Device Drivers
404#
405
406#
407# Generic Driver Options
408#
409CONFIG_STANDALONE=y
410CONFIG_PREVENT_FIRMWARE_BUILD=y
411CONFIG_FW_LOADER=y
412
413#
414# Connector - unified userspace <-> kernelspace linker
415#
416# CONFIG_CONNECTOR is not set
417
418#
419# Memory Technology Devices (MTD)
420#
421CONFIG_MTD=y
422# CONFIG_MTD_DEBUG is not set
423# CONFIG_MTD_CONCAT is not set
424CONFIG_MTD_PARTITIONS=y
425# CONFIG_MTD_REDBOOT_PARTS is not set
426# CONFIG_MTD_CMDLINE_PARTS is not set
427
428#
429# User Modules And Translation Layers
430#
431CONFIG_MTD_CHAR=y
432CONFIG_MTD_BLOCK=y
433# CONFIG_FTL is not set
434# CONFIG_NFTL is not set
435# CONFIG_INFTL is not set
436# CONFIG_RFD_FTL is not set
437
438#
439# RAM/ROM/Flash chip drivers
440#
441CONFIG_MTD_CFI=y
442# CONFIG_MTD_JEDECPROBE is not set
443CONFIG_MTD_GEN_PROBE=y
444# CONFIG_MTD_CFI_ADV_OPTIONS is not set
445CONFIG_MTD_MAP_BANK_WIDTH_1=y
446CONFIG_MTD_MAP_BANK_WIDTH_2=y
447CONFIG_MTD_MAP_BANK_WIDTH_4=y
448# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
449# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
450# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
451CONFIG_MTD_CFI_I1=y
452CONFIG_MTD_CFI_I2=y
453# CONFIG_MTD_CFI_I4 is not set
454# CONFIG_MTD_CFI_I8 is not set
455# CONFIG_MTD_CFI_INTELEXT is not set
456CONFIG_MTD_CFI_AMDSTD=y
457# CONFIG_MTD_CFI_STAA is not set
458CONFIG_MTD_CFI_UTIL=y
459CONFIG_MTD_RAM=y
460# CONFIG_MTD_ROM is not set
461# CONFIG_MTD_ABSENT is not set
462# CONFIG_MTD_OBSOLETE_CHIPS is not set
463
464#
465# Mapping drivers for chip access
466#
467# CONFIG_MTD_COMPLEX_MAPPINGS is not set
468# CONFIG_MTD_PHYSMAP is not set
469# CONFIG_MTD_SOLUTIONENGINE is not set
470CONFIG_MTD_SH7710VOIPGW=y
471# CONFIG_MTD_PLATRAM is not set
472
473#
474# Self-contained MTD device drivers
475#
476# CONFIG_MTD_SLRAM is not set
477# CONFIG_MTD_PHRAM is not set
478# CONFIG_MTD_MTDRAM is not set
479# CONFIG_MTD_BLOCK2MTD is not set
480
481#
482# Disk-On-Chip Device Drivers
483#
484# CONFIG_MTD_DOC2000 is not set
485# CONFIG_MTD_DOC2001 is not set
486# CONFIG_MTD_DOC2001PLUS is not set
487
488#
489# NAND Flash Device Drivers
490#
491# CONFIG_MTD_NAND is not set
492
493#
494# OneNAND Flash Device Drivers
495#
496# CONFIG_MTD_ONENAND is not set
497
498#
499# Parallel port support
500#
501# CONFIG_PARPORT is not set
502
503#
504# Plug and Play support
505#
506
507#
508# Block devices
509#
510# CONFIG_BLK_DEV_COW_COMMON is not set
511# CONFIG_BLK_DEV_LOOP is not set
512# CONFIG_BLK_DEV_NBD is not set
513# CONFIG_BLK_DEV_RAM is not set
514# CONFIG_BLK_DEV_INITRD is not set
515# CONFIG_CDROM_PKTCDVD is not set
516# CONFIG_ATA_OVER_ETH is not set
517
518#
519# ATA/ATAPI/MFM/RLL support
520#
521# CONFIG_IDE is not set
522
523#
524# SCSI device support
525#
526# CONFIG_RAID_ATTRS is not set
527# CONFIG_SCSI is not set
528
529#
530# Multi-device support (RAID and LVM)
531#
532# CONFIG_MD is not set
533
534#
535# Fusion MPT device support
536#
537# CONFIG_FUSION is not set
538
539#
540# IEEE 1394 (FireWire) support
541#
542
543#
544# I2O device support
545#
546
547#
548# Network device support
549#
550CONFIG_NETDEVICES=y
551# CONFIG_DUMMY is not set
552# CONFIG_BONDING is not set
553# CONFIG_EQUALIZER is not set
554# CONFIG_TUN is not set
555
556#
557# PHY device support
558#
559# CONFIG_PHYLIB is not set
560
561#
562# Ethernet (10 or 100Mbit)
563#
564CONFIG_NET_ETHERNET=y
565# CONFIG_MII is not set
566# CONFIG_STNIC is not set
567# CONFIG_SMC91X is not set
568# CONFIG_NE2000 is not set
569
570#
571# Ethernet (1000 Mbit)
572#
573
574#
575# Ethernet (10000 Mbit)
576#
577
578#
579# Token Ring devices
580#
581
582#
583# Wireless LAN (non-hamradio)
584#
585# CONFIG_NET_RADIO is not set
586
587#
588# Wan interfaces
589#
590# CONFIG_WAN is not set
591# CONFIG_PPP is not set
592# CONFIG_SLIP is not set
593# CONFIG_SHAPER is not set
594# CONFIG_NETCONSOLE is not set
595# CONFIG_NETPOLL is not set
596# CONFIG_NET_POLL_CONTROLLER is not set
597
598#
599# ISDN subsystem
600#
601# CONFIG_ISDN is not set
602
603#
604# Telephony Support
605#
606CONFIG_PHONE=y
607# CONFIG_PHONE_IXJ is not set
608
609#
610# Input device support
611#
612CONFIG_INPUT=y
613
614#
615# Userland interfaces
616#
617# CONFIG_INPUT_MOUSEDEV is not set
618# CONFIG_INPUT_JOYDEV is not set
619# CONFIG_INPUT_TSDEV is not set
620# CONFIG_INPUT_EVDEV is not set
621# CONFIG_INPUT_EVBUG is not set
622
623#
624# Input Device Drivers
625#
626# CONFIG_INPUT_KEYBOARD is not set
627# CONFIG_INPUT_MOUSE is not set
628# CONFIG_INPUT_JOYSTICK is not set
629# CONFIG_INPUT_TOUCHSCREEN is not set
630# CONFIG_INPUT_MISC is not set
631
632#
633# Hardware I/O ports
634#
635# CONFIG_SERIO is not set
636# CONFIG_GAMEPORT is not set
637
638#
639# Character devices
640#
641# CONFIG_VT is not set
642# CONFIG_SERIAL_NONSTANDARD is not set
643
644#
645# Serial drivers
646#
647# CONFIG_SERIAL_8250 is not set
648
649#
650# Non-8250 serial port support
651#
652CONFIG_SERIAL_SH_SCI=y
653CONFIG_SERIAL_SH_SCI_NR_UARTS=2
654CONFIG_SERIAL_SH_SCI_CONSOLE=y
655CONFIG_SERIAL_CORE=y
656CONFIG_SERIAL_CORE_CONSOLE=y
657# CONFIG_UNIX98_PTYS is not set
658CONFIG_LEGACY_PTYS=y
659CONFIG_LEGACY_PTY_COUNT=256
660
661#
662# IPMI
663#
664# CONFIG_IPMI_HANDLER is not set
665
666#
667# Watchdog Cards
668#
669# CONFIG_WATCHDOG is not set
670# CONFIG_RTC is not set
671# CONFIG_GEN_RTC is not set
672# CONFIG_DTLK is not set
673# CONFIG_R3964 is not set
674
675#
676# Ftape, the floppy tape device driver
677#
678# CONFIG_RAW_DRIVER is not set
679
680#
681# TPM devices
682#
683# CONFIG_TCG_TPM is not set
684# CONFIG_TELCLOCK is not set
685
686#
687# I2C support
688#
689# CONFIG_I2C is not set
690
691#
692# SPI support
693#
694# CONFIG_SPI is not set
695# CONFIG_SPI_MASTER is not set
696
697#
698# Dallas's 1-wire bus
699#
700# CONFIG_W1 is not set
701
702#
703# Hardware Monitoring support
704#
705# CONFIG_HWMON is not set
706# CONFIG_HWMON_VID is not set
707
708#
709# Misc devices
710#
711
712#
713# Multimedia devices
714#
715# CONFIG_VIDEO_DEV is not set
716CONFIG_VIDEO_V4L2=y
717
718#
719# Digital Video Broadcasting Devices
720#
721# CONFIG_DVB is not set
722
723#
724# Graphics support
725#
726# CONFIG_FB is not set
727
728#
729# Sound
730#
731# CONFIG_SOUND is not set
732
733#
734# USB support
735#
736# CONFIG_USB_ARCH_HAS_HCD is not set
737# CONFIG_USB_ARCH_HAS_OHCI is not set
738# CONFIG_USB_ARCH_HAS_EHCI is not set
739
740#
741# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
742#
743
744#
745# USB Gadget Support
746#
747# CONFIG_USB_GADGET is not set
748
749#
750# MMC/SD Card support
751#
752# CONFIG_MMC is not set
753
754#
755# LED devices
756#
757# CONFIG_NEW_LEDS is not set
758
759#
760# LED drivers
761#
762
763#
764# LED Triggers
765#
766
767#
768# InfiniBand support
769#
770
771#
772# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
773#
774
775#
776# Real Time Clock
777#
778# CONFIG_RTC_CLASS is not set
779
780#
781# File systems
782#
783# CONFIG_EXT2_FS is not set
784# CONFIG_EXT3_FS is not set
785# CONFIG_REISERFS_FS is not set
786# CONFIG_JFS_FS is not set
787# CONFIG_FS_POSIX_ACL is not set
788# CONFIG_XFS_FS is not set
789# CONFIG_OCFS2_FS is not set
790# CONFIG_MINIX_FS is not set
791# CONFIG_ROMFS_FS is not set
792# CONFIG_INOTIFY is not set
793# CONFIG_QUOTA is not set
794# CONFIG_DNOTIFY is not set
795# CONFIG_AUTOFS_FS is not set
796# CONFIG_AUTOFS4_FS is not set
797# CONFIG_FUSE_FS is not set
798
799#
800# CD-ROM/DVD Filesystems
801#
802# CONFIG_ISO9660_FS is not set
803# CONFIG_UDF_FS is not set
804
805#
806# DOS/FAT/NT Filesystems
807#
808# CONFIG_MSDOS_FS is not set
809# CONFIG_VFAT_FS is not set
810# CONFIG_NTFS_FS is not set
811
812#
813# Pseudo filesystems
814#
815CONFIG_PROC_FS=y
816# CONFIG_PROC_KCORE is not set
817CONFIG_SYSFS=y
818CONFIG_TMPFS=y
819# CONFIG_HUGETLBFS is not set
820# CONFIG_HUGETLB_PAGE is not set
821CONFIG_RAMFS=y
822# CONFIG_CONFIGFS_FS is not set
823
824#
825# Miscellaneous filesystems
826#
827# CONFIG_ADFS_FS is not set
828# CONFIG_AFFS_FS is not set
829# CONFIG_HFS_FS is not set
830# CONFIG_HFSPLUS_FS is not set
831# CONFIG_BEFS_FS is not set
832# CONFIG_BFS_FS is not set
833# CONFIG_EFS_FS is not set
834# CONFIG_JFFS_FS is not set
835CONFIG_JFFS2_FS=y
836CONFIG_JFFS2_FS_DEBUG=0
837CONFIG_JFFS2_FS_WRITEBUFFER=y
838# CONFIG_JFFS2_SUMMARY is not set
839# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
840CONFIG_JFFS2_ZLIB=y
841CONFIG_JFFS2_RTIME=y
842# CONFIG_JFFS2_RUBIN is not set
843# CONFIG_CRAMFS is not set
844# CONFIG_VXFS_FS is not set
845# CONFIG_HPFS_FS is not set
846# CONFIG_QNX4FS_FS is not set
847# CONFIG_SYSV_FS is not set
848# CONFIG_UFS_FS is not set
849
850#
851# Network File Systems
852#
853# CONFIG_NFS_FS is not set
854# CONFIG_NFSD is not set
855# CONFIG_SMB_FS is not set
856# CONFIG_CIFS is not set
857# CONFIG_NCP_FS is not set
858# CONFIG_CODA_FS is not set
859# CONFIG_AFS_FS is not set
860# CONFIG_9P_FS is not set
861
862#
863# Partition Types
864#
865# CONFIG_PARTITION_ADVANCED is not set
866CONFIG_MSDOS_PARTITION=y
867
868#
869# Native Language Support
870#
871# CONFIG_NLS is not set
872
873#
874# Profiling support
875#
876# CONFIG_PROFILING is not set
877
878#
879# Kernel hacking
880#
881# CONFIG_PRINTK_TIME is not set
882# CONFIG_MAGIC_SYSRQ is not set
883# CONFIG_DEBUG_KERNEL is not set
884CONFIG_LOG_BUF_SHIFT=14
885# CONFIG_DEBUG_BUGVERBOSE is not set
886# CONFIG_DEBUG_FS is not set
887# CONFIG_SH_STANDARD_BIOS is not set
888# CONFIG_KGDB is not set
889
890#
891# Security options
892#
893# CONFIG_KEYS is not set
894# CONFIG_SECURITY is not set
895
896#
897# Cryptographic options
898#
899# CONFIG_CRYPTO is not set
900
901#
902# Hardware crypto devices
903#
904
905#
906# Library routines
907#
908# CONFIG_CRC_CCITT is not set
909# CONFIG_CRC16 is not set
910CONFIG_CRC32=y
911# CONFIG_LIBCRC32C is not set
912CONFIG_ZLIB_INFLATE=y
913CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/sh/configs/shmin_defconfig b/arch/sh/configs/shmin_defconfig
new file mode 100644
index 000000000000..382b3bd3963b
--- /dev/null
+++ b/arch/sh/configs/shmin_defconfig
@@ -0,0 +1,827 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.17
4# Wed Aug 2 01:45:03 2006
5#
6CONFIG_SUPERH=y
7CONFIG_RWSEM_GENERIC_SPINLOCK=y
8CONFIG_GENERIC_FIND_NEXT_BIT=y
9CONFIG_GENERIC_HWEIGHT=y
10CONFIG_GENERIC_HARDIRQS=y
11CONFIG_GENERIC_IRQ_PROBE=y
12CONFIG_GENERIC_CALIBRATE_DELAY=y
13CONFIG_PTRACE=y
14
15#
16# Code maturity level options
17#
18CONFIG_EXPERIMENTAL=y
19CONFIG_BROKEN_ON_SMP=y
20CONFIG_INIT_ENV_ARG_LIMIT=32
21
22#
23# General setup
24#
25CONFIG_LOCALVERSION=""
26CONFIG_LOCALVERSION_AUTO=y
27# CONFIG_SWAP is not set
28# CONFIG_SYSVIPC is not set
29# CONFIG_POSIX_MQUEUE is not set
30# CONFIG_BSD_PROCESS_ACCT is not set
31# CONFIG_SYSCTL is not set
32# CONFIG_AUDIT is not set
33# CONFIG_IKCONFIG is not set
34# CONFIG_RELAY is not set
35CONFIG_INITRAMFS_SOURCE=""
36# CONFIG_UID16 is not set
37CONFIG_CC_OPTIMIZE_FOR_SIZE=y
38CONFIG_EMBEDDED=y
39# CONFIG_KALLSYMS is not set
40# CONFIG_HOTPLUG is not set
41CONFIG_PRINTK=y
42# CONFIG_BUG is not set
43# CONFIG_ELF_CORE is not set
44# CONFIG_BASE_FULL is not set
45# CONFIG_FUTEX is not set
46# CONFIG_EPOLL is not set
47# CONFIG_SHMEM is not set
48# CONFIG_SLAB is not set
49CONFIG_TINY_SHMEM=y
50CONFIG_BASE_SMALL=1
51CONFIG_SLOB=y
52CONFIG_OBSOLETE_INTERMODULE=y
53
54#
55# Loadable module support
56#
57# CONFIG_MODULES is not set
58
59#
60# Block layer
61#
62# CONFIG_LBD is not set
63# CONFIG_LSF is not set
64
65#
66# IO Schedulers
67#
68CONFIG_IOSCHED_NOOP=y
69# CONFIG_IOSCHED_AS is not set
70# CONFIG_IOSCHED_DEADLINE is not set
71# CONFIG_IOSCHED_CFQ is not set
72# CONFIG_DEFAULT_AS is not set
73# CONFIG_DEFAULT_DEADLINE is not set
74# CONFIG_DEFAULT_CFQ is not set
75CONFIG_DEFAULT_NOOP=y
76CONFIG_DEFAULT_IOSCHED="noop"
77
78#
79# System type
80#
81# CONFIG_SH_SOLUTION_ENGINE is not set
82# CONFIG_SH_7709_SOLUTION_ENGINE is not set
83# CONFIG_SH_7751_SOLUTION_ENGINE is not set
84# CONFIG_SH_7300_SOLUTION_ENGINE is not set
85# CONFIG_SH_73180_SOLUTION_ENGINE is not set
86# CONFIG_SH_7751_SYSTEMH is not set
87# CONFIG_SH_STB1_HARP is not set
88# CONFIG_SH_STB1_OVERDRIVE is not set
89# CONFIG_SH_HP6XX is not set
90# CONFIG_SH_CQREEK is not set
91# CONFIG_SH_DMIDA is not set
92# CONFIG_SH_EC3104 is not set
93# CONFIG_SH_SATURN is not set
94# CONFIG_SH_DREAMCAST is not set
95# CONFIG_SH_CAT68701 is not set
96# CONFIG_SH_BIGSUR is not set
97# CONFIG_SH_SH2000 is not set
98# CONFIG_SH_ADX is not set
99# CONFIG_SH_MPC1211 is not set
100# CONFIG_SH_SH03 is not set
101# CONFIG_SH_SECUREEDGE5410 is not set
102# CONFIG_SH_HS7751RVOIP is not set
103# CONFIG_SH_RTS7751R2D is not set
104# CONFIG_SH_R7780RP is not set
105# CONFIG_SH_EDOSK7705 is not set
106# CONFIG_SH_SH4202_MICRODEV is not set
107# CONFIG_SH_LANDISK is not set
108# CONFIG_SH_TITAN is not set
109CONFIG_SH_SHMIN=y
110# CONFIG_SH_UNKNOWN is not set
111
112#
113# Processor selection
114#
115CONFIG_CPU_SH3=y
116
117#
118# SH-2 Processor Support
119#
120# CONFIG_CPU_SUBTYPE_SH7604 is not set
121
122#
123# SH-3 Processor Support
124#
125# CONFIG_CPU_SUBTYPE_SH7300 is not set
126# CONFIG_CPU_SUBTYPE_SH7705 is not set
127CONFIG_CPU_SUBTYPE_SH7706=y
128# CONFIG_CPU_SUBTYPE_SH7707 is not set
129# CONFIG_CPU_SUBTYPE_SH7708 is not set
130# CONFIG_CPU_SUBTYPE_SH7709 is not set
131
132#
133# SH-4 Processor Support
134#
135# CONFIG_CPU_SUBTYPE_SH7750 is not set
136# CONFIG_CPU_SUBTYPE_SH7091 is not set
137# CONFIG_CPU_SUBTYPE_SH7750R is not set
138# CONFIG_CPU_SUBTYPE_SH7750S is not set
139# CONFIG_CPU_SUBTYPE_SH7751 is not set
140# CONFIG_CPU_SUBTYPE_SH7751R is not set
141# CONFIG_CPU_SUBTYPE_SH7760 is not set
142# CONFIG_CPU_SUBTYPE_SH4_202 is not set
143
144#
145# ST40 Processor Support
146#
147# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
148# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
149
150#
151# SH-4A Processor Support
152#
153# CONFIG_CPU_SUBTYPE_SH73180 is not set
154# CONFIG_CPU_SUBTYPE_SH7770 is not set
155# CONFIG_CPU_SUBTYPE_SH7780 is not set
156
157#
158# Memory management options
159#
160CONFIG_MMU=y
161CONFIG_PAGE_OFFSET=0x80000000
162CONFIG_MEMORY_START=0x0c000000
163CONFIG_MEMORY_SIZE=0x00800000
164CONFIG_SELECT_MEMORY_MODEL=y
165CONFIG_FLATMEM_MANUAL=y
166# CONFIG_DISCONTIGMEM_MANUAL is not set
167# CONFIG_SPARSEMEM_MANUAL is not set
168CONFIG_FLATMEM=y
169CONFIG_FLAT_NODE_MEM_MAP=y
170# CONFIG_SPARSEMEM_STATIC is not set
171CONFIG_SPLIT_PTLOCK_CPUS=4
172
173#
174# Cache configuration
175#
176# CONFIG_SH_DIRECT_MAPPED is not set
177# CONFIG_SH_WRITETHROUGH is not set
178# CONFIG_SH_OCRAM is not set
179
180#
181# Processor features
182#
183CONFIG_CPU_LITTLE_ENDIAN=y
184# CONFIG_SH_FPU_EMU is not set
185# CONFIG_SH_DSP is not set
186# CONFIG_SH_ADC is not set
187CONFIG_CPU_HAS_INTEVT=y
188CONFIG_CPU_HAS_SR_RB=y
189
190#
191# Timer support
192#
193CONFIG_SH_TMU=y
194CONFIG_SH_PCLK_FREQ=32000000
195
196#
197# CPU Frequency scaling
198#
199# CONFIG_CPU_FREQ is not set
200
201#
202# DMA support
203#
204# CONFIG_SH_DMA is not set
205
206#
207# Companion Chips
208#
209# CONFIG_HD6446X_SERIES is not set
210
211#
212# Kernel features
213#
214# CONFIG_KEXEC is not set
215# CONFIG_PREEMPT is not set
216# CONFIG_SMP is not set
217
218#
219# Boot options
220#
221CONFIG_ZERO_PAGE_OFFSET=0x00001000
222CONFIG_BOOT_LINK_OFFSET=0x00210000
223# CONFIG_UBC_WAKEUP is not set
224CONFIG_CMDLINE_BOOL=y
225CONFIG_CMDLINE="console=ttySC1,115200 root=1f01 mtdparts=phys_mapped_flash:64k(firm)ro,-(sys) netdev=34,0x300,eth0 "
226
227#
228# Bus options
229#
230# CONFIG_PCI is not set
231
232#
233# PCCARD (PCMCIA/CardBus) support
234#
235# CONFIG_PCCARD is not set
236
237#
238# PCI Hotplug Support
239#
240
241#
242# Executable file formats
243#
244CONFIG_BINFMT_ELF=y
245# CONFIG_BINFMT_FLAT is not set
246# CONFIG_BINFMT_MISC is not set
247
248#
249# Power management options (EXPERIMENTAL)
250#
251# CONFIG_PM is not set
252
253#
254# Networking
255#
256CONFIG_NET=y
257
258#
259# Networking options
260#
261# CONFIG_NETDEBUG is not set
262# CONFIG_PACKET is not set
263CONFIG_UNIX=y
264# CONFIG_NET_KEY is not set
265CONFIG_INET=y
266# CONFIG_IP_MULTICAST is not set
267# CONFIG_IP_ADVANCED_ROUTER is not set
268CONFIG_IP_FIB_HASH=y
269CONFIG_IP_PNP=y
270# CONFIG_IP_PNP_DHCP is not set
271# CONFIG_IP_PNP_BOOTP is not set
272# CONFIG_IP_PNP_RARP is not set
273# CONFIG_NET_IPIP is not set
274# CONFIG_NET_IPGRE is not set
275# CONFIG_ARPD is not set
276# CONFIG_SYN_COOKIES is not set
277# CONFIG_INET_AH is not set
278# CONFIG_INET_ESP is not set
279# CONFIG_INET_IPCOMP is not set
280# CONFIG_INET_XFRM_TUNNEL is not set
281# CONFIG_INET_TUNNEL is not set
282CONFIG_INET_DIAG=y
283CONFIG_INET_TCP_DIAG=y
284# CONFIG_TCP_CONG_ADVANCED is not set
285CONFIG_TCP_CONG_BIC=y
286# CONFIG_IPV6 is not set
287# CONFIG_INET6_XFRM_TUNNEL is not set
288# CONFIG_INET6_TUNNEL is not set
289# CONFIG_NETFILTER is not set
290
291#
292# DCCP Configuration (EXPERIMENTAL)
293#
294# CONFIG_IP_DCCP is not set
295
296#
297# SCTP Configuration (EXPERIMENTAL)
298#
299# CONFIG_IP_SCTP is not set
300
301#
302# TIPC Configuration (EXPERIMENTAL)
303#
304# CONFIG_TIPC is not set
305# CONFIG_ATM is not set
306# CONFIG_BRIDGE is not set
307# CONFIG_VLAN_8021Q is not set
308# CONFIG_DECNET is not set
309# CONFIG_LLC2 is not set
310# CONFIG_IPX is not set
311# CONFIG_ATALK is not set
312# CONFIG_X25 is not set
313# CONFIG_LAPB is not set
314# CONFIG_NET_DIVERT is not set
315# CONFIG_ECONET is not set
316# CONFIG_WAN_ROUTER is not set
317
318#
319# QoS and/or fair queueing
320#
321# CONFIG_NET_SCHED is not set
322
323#
324# Network testing
325#
326# CONFIG_NET_PKTGEN is not set
327# CONFIG_HAMRADIO is not set
328# CONFIG_IRDA is not set
329# CONFIG_BT is not set
330# CONFIG_IEEE80211 is not set
331
332#
333# Device Drivers
334#
335
336#
337# Generic Driver Options
338#
339CONFIG_STANDALONE=y
340CONFIG_PREVENT_FIRMWARE_BUILD=y
341# CONFIG_FW_LOADER is not set
342
343#
344# Connector - unified userspace <-> kernelspace linker
345#
346# CONFIG_CONNECTOR is not set
347
348#
349# Memory Technology Devices (MTD)
350#
351CONFIG_MTD=y
352# CONFIG_MTD_DEBUG is not set
353# CONFIG_MTD_CONCAT is not set
354CONFIG_MTD_PARTITIONS=y
355# CONFIG_MTD_REDBOOT_PARTS is not set
356CONFIG_MTD_CMDLINE_PARTS=y
357
358#
359# User Modules And Translation Layers
360#
361# CONFIG_MTD_CHAR is not set
362CONFIG_MTD_BLOCK=y
363# CONFIG_FTL is not set
364# CONFIG_NFTL is not set
365# CONFIG_INFTL is not set
366# CONFIG_RFD_FTL is not set
367
368#
369# RAM/ROM/Flash chip drivers
370#
371# CONFIG_MTD_CFI is not set
372CONFIG_MTD_JEDECPROBE=y
373CONFIG_MTD_GEN_PROBE=y
374# CONFIG_MTD_CFI_ADV_OPTIONS is not set
375CONFIG_MTD_MAP_BANK_WIDTH_1=y
376CONFIG_MTD_MAP_BANK_WIDTH_2=y
377CONFIG_MTD_MAP_BANK_WIDTH_4=y
378# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
379# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
380# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
381CONFIG_MTD_CFI_I1=y
382CONFIG_MTD_CFI_I2=y
383# CONFIG_MTD_CFI_I4 is not set
384# CONFIG_MTD_CFI_I8 is not set
385# CONFIG_MTD_CFI_INTELEXT is not set
386CONFIG_MTD_CFI_AMDSTD=y
387# CONFIG_MTD_CFI_STAA is not set
388CONFIG_MTD_CFI_UTIL=y
389# CONFIG_MTD_RAM is not set
390# CONFIG_MTD_ROM is not set
391# CONFIG_MTD_ABSENT is not set
392# CONFIG_MTD_OBSOLETE_CHIPS is not set
393
394#
395# Mapping drivers for chip access
396#
397# CONFIG_MTD_COMPLEX_MAPPINGS is not set
398CONFIG_MTD_PHYSMAP=y
399CONFIG_MTD_PHYSMAP_START=0xa0000000
400CONFIG_MTD_PHYSMAP_LEN=0x80000
401CONFIG_MTD_PHYSMAP_BANKWIDTH=1
402# CONFIG_MTD_PLATRAM is not set
403
404#
405# Self-contained MTD device drivers
406#
407# CONFIG_MTD_SLRAM is not set
408# CONFIG_MTD_PHRAM is not set
409# CONFIG_MTD_MTDRAM is not set
410# CONFIG_MTD_BLOCK2MTD is not set
411
412#
413# Disk-On-Chip Device Drivers
414#
415# CONFIG_MTD_DOC2000 is not set
416# CONFIG_MTD_DOC2001 is not set
417# CONFIG_MTD_DOC2001PLUS is not set
418
419#
420# NAND Flash Device Drivers
421#
422# CONFIG_MTD_NAND is not set
423
424#
425# OneNAND Flash Device Drivers
426#
427# CONFIG_MTD_ONENAND is not set
428
429#
430# Parallel port support
431#
432# CONFIG_PARPORT is not set
433
434#
435# Plug and Play support
436#
437
438#
439# Block devices
440#
441# CONFIG_BLK_DEV_COW_COMMON is not set
442CONFIG_BLK_DEV_LOOP=y
443# CONFIG_BLK_DEV_CRYPTOLOOP is not set
444# CONFIG_BLK_DEV_NBD is not set
445# CONFIG_BLK_DEV_RAM is not set
446# CONFIG_BLK_DEV_INITRD is not set
447# CONFIG_CDROM_PKTCDVD is not set
448# CONFIG_ATA_OVER_ETH is not set
449
450#
451# ATA/ATAPI/MFM/RLL support
452#
453# CONFIG_IDE is not set
454
455#
456# SCSI device support
457#
458# CONFIG_RAID_ATTRS is not set
459# CONFIG_SCSI is not set
460
461#
462# Multi-device support (RAID and LVM)
463#
464# CONFIG_MD is not set
465
466#
467# Fusion MPT device support
468#
469# CONFIG_FUSION is not set
470
471#
472# IEEE 1394 (FireWire) support
473#
474
475#
476# I2O device support
477#
478
479#
480# Network device support
481#
482CONFIG_NETDEVICES=y
483# CONFIG_DUMMY is not set
484# CONFIG_BONDING is not set
485# CONFIG_EQUALIZER is not set
486# CONFIG_TUN is not set
487
488#
489# PHY device support
490#
491# CONFIG_PHYLIB is not set
492
493#
494# Ethernet (10 or 100Mbit)
495#
496CONFIG_NET_ETHERNET=y
497# CONFIG_MII is not set
498# CONFIG_STNIC is not set
499# CONFIG_SMC91X is not set
500CONFIG_NE2000=y
501
502#
503# Ethernet (1000 Mbit)
504#
505
506#
507# Ethernet (10000 Mbit)
508#
509
510#
511# Token Ring devices
512#
513
514#
515# Wireless LAN (non-hamradio)
516#
517# CONFIG_NET_RADIO is not set
518
519#
520# Wan interfaces
521#
522# CONFIG_WAN is not set
523# CONFIG_PPP is not set
524# CONFIG_SLIP is not set
525# CONFIG_SHAPER is not set
526# CONFIG_NETCONSOLE is not set
527# CONFIG_NETPOLL is not set
528# CONFIG_NET_POLL_CONTROLLER is not set
529
530#
531# ISDN subsystem
532#
533# CONFIG_ISDN is not set
534
535#
536# Telephony Support
537#
538# CONFIG_PHONE is not set
539
540#
541# Input device support
542#
543# CONFIG_INPUT is not set
544
545#
546# Hardware I/O ports
547#
548# CONFIG_SERIO is not set
549# CONFIG_GAMEPORT is not set
550
551#
552# Character devices
553#
554# CONFIG_VT is not set
555# CONFIG_SERIAL_NONSTANDARD is not set
556
557#
558# Serial drivers
559#
560# CONFIG_SERIAL_8250 is not set
561
562#
563# Non-8250 serial port support
564#
565CONFIG_SERIAL_SH_SCI=y
566CONFIG_SERIAL_SH_SCI_NR_UARTS=2
567CONFIG_SERIAL_SH_SCI_CONSOLE=y
568CONFIG_SERIAL_CORE=y
569CONFIG_SERIAL_CORE_CONSOLE=y
570CONFIG_UNIX98_PTYS=y
571CONFIG_LEGACY_PTYS=y
572CONFIG_LEGACY_PTY_COUNT=256
573
574#
575# IPMI
576#
577# CONFIG_IPMI_HANDLER is not set
578
579#
580# Watchdog Cards
581#
582# CONFIG_WATCHDOG is not set
583# CONFIG_RTC is not set
584# CONFIG_GEN_RTC is not set
585# CONFIG_DTLK is not set
586# CONFIG_R3964 is not set
587
588#
589# Ftape, the floppy tape device driver
590#
591# CONFIG_RAW_DRIVER is not set
592
593#
594# TPM devices
595#
596# CONFIG_TCG_TPM is not set
597# CONFIG_TELCLOCK is not set
598
599#
600# I2C support
601#
602# CONFIG_I2C is not set
603
604#
605# SPI support
606#
607# CONFIG_SPI is not set
608# CONFIG_SPI_MASTER is not set
609
610#
611# Dallas's 1-wire bus
612#
613# CONFIG_W1 is not set
614
615#
616# Hardware Monitoring support
617#
618# CONFIG_HWMON is not set
619# CONFIG_HWMON_VID is not set
620
621#
622# Misc devices
623#
624
625#
626# Multimedia devices
627#
628# CONFIG_VIDEO_DEV is not set
629CONFIG_VIDEO_V4L2=y
630
631#
632# Digital Video Broadcasting Devices
633#
634# CONFIG_DVB is not set
635
636#
637# Graphics support
638#
639# CONFIG_FB is not set
640
641#
642# Sound
643#
644# CONFIG_SOUND is not set
645
646#
647# USB support
648#
649# CONFIG_USB_ARCH_HAS_HCD is not set
650# CONFIG_USB_ARCH_HAS_OHCI is not set
651# CONFIG_USB_ARCH_HAS_EHCI is not set
652
653#
654# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
655#
656
657#
658# USB Gadget Support
659#
660# CONFIG_USB_GADGET is not set
661
662#
663# MMC/SD Card support
664#
665# CONFIG_MMC is not set
666
667#
668# LED devices
669#
670# CONFIG_NEW_LEDS is not set
671
672#
673# LED drivers
674#
675
676#
677# LED Triggers
678#
679
680#
681# InfiniBand support
682#
683
684#
685# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
686#
687
688#
689# Real Time Clock
690#
691# CONFIG_RTC_CLASS is not set
692
693#
694# File systems
695#
696# CONFIG_EXT2_FS is not set
697# CONFIG_EXT3_FS is not set
698# CONFIG_REISERFS_FS is not set
699# CONFIG_JFS_FS is not set
700# CONFIG_FS_POSIX_ACL is not set
701# CONFIG_XFS_FS is not set
702# CONFIG_OCFS2_FS is not set
703# CONFIG_MINIX_FS is not set
704# CONFIG_ROMFS_FS is not set
705# CONFIG_INOTIFY is not set
706# CONFIG_QUOTA is not set
707# CONFIG_DNOTIFY is not set
708# CONFIG_AUTOFS_FS is not set
709# CONFIG_AUTOFS4_FS is not set
710# CONFIG_FUSE_FS is not set
711
712#
713# CD-ROM/DVD Filesystems
714#
715# CONFIG_ISO9660_FS is not set
716# CONFIG_UDF_FS is not set
717
718#
719# DOS/FAT/NT Filesystems
720#
721# CONFIG_MSDOS_FS is not set
722# CONFIG_VFAT_FS is not set
723# CONFIG_NTFS_FS is not set
724
725#
726# Pseudo filesystems
727#
728CONFIG_PROC_FS=y
729# CONFIG_PROC_KCORE is not set
730# CONFIG_SYSFS is not set
731CONFIG_TMPFS=y
732# CONFIG_HUGETLBFS is not set
733# CONFIG_HUGETLB_PAGE is not set
734CONFIG_RAMFS=y
735
736#
737# Miscellaneous filesystems
738#
739# CONFIG_ADFS_FS is not set
740# CONFIG_AFFS_FS is not set
741# CONFIG_HFS_FS is not set
742# CONFIG_HFSPLUS_FS is not set
743# CONFIG_BEFS_FS is not set
744# CONFIG_BFS_FS is not set
745# CONFIG_EFS_FS is not set
746# CONFIG_JFFS_FS is not set
747# CONFIG_JFFS2_FS is not set
748CONFIG_CRAMFS=y
749# CONFIG_VXFS_FS is not set
750# CONFIG_HPFS_FS is not set
751# CONFIG_QNX4FS_FS is not set
752# CONFIG_SYSV_FS is not set
753# CONFIG_UFS_FS is not set
754
755#
756# Network File Systems
757#
758CONFIG_NFS_FS=y
759CONFIG_NFS_V3=y
760# CONFIG_NFS_V3_ACL is not set
761# CONFIG_NFS_V4 is not set
762# CONFIG_NFS_DIRECTIO is not set
763# CONFIG_NFSD is not set
764CONFIG_ROOT_NFS=y
765CONFIG_LOCKD=y
766CONFIG_LOCKD_V4=y
767CONFIG_NFS_COMMON=y
768CONFIG_SUNRPC=y
769# CONFIG_RPCSEC_GSS_KRB5 is not set
770# CONFIG_RPCSEC_GSS_SPKM3 is not set
771# CONFIG_SMB_FS is not set
772# CONFIG_CIFS is not set
773# CONFIG_NCP_FS is not set
774# CONFIG_CODA_FS is not set
775# CONFIG_AFS_FS is not set
776# CONFIG_9P_FS is not set
777
778#
779# Partition Types
780#
781# CONFIG_PARTITION_ADVANCED is not set
782CONFIG_MSDOS_PARTITION=y
783
784#
785# Native Language Support
786#
787# CONFIG_NLS is not set
788
789#
790# Profiling support
791#
792# CONFIG_PROFILING is not set
793
794#
795# Kernel hacking
796#
797# CONFIG_PRINTK_TIME is not set
798# CONFIG_MAGIC_SYSRQ is not set
799# CONFIG_DEBUG_KERNEL is not set
800CONFIG_LOG_BUF_SHIFT=14
801# CONFIG_UNWIND_INFO is not set
802CONFIG_SH_STANDARD_BIOS=y
803CONFIG_EARLY_PRINTK=y
804# CONFIG_KGDB is not set
805
806#
807# Security options
808#
809# CONFIG_KEYS is not set
810
811#
812# Cryptographic options
813#
814# CONFIG_CRYPTO is not set
815
816#
817# Hardware crypto devices
818#
819
820#
821# Library routines
822#
823# CONFIG_CRC_CCITT is not set
824# CONFIG_CRC16 is not set
825CONFIG_CRC32=y
826# CONFIG_LIBCRC32C is not set
827CONFIG_ZLIB_INFLATE=y
diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig
new file mode 100644
index 000000000000..1db2904de9e5
--- /dev/null
+++ b/arch/sh/configs/titan_defconfig
@@ -0,0 +1,1367 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.14-sh
4# Wed Nov 9 00:35:56 2005
5#
6CONFIG_SUPERH=y
7CONFIG_UID16=y
8CONFIG_RWSEM_GENERIC_SPINLOCK=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_GENERIC_IRQ_PROBE=y
11CONFIG_GENERIC_CALIBRATE_DELAY=y
12CONFIG_GENERIC_IOMAP=y
13
14#
15# Code maturity level options
16#
17CONFIG_EXPERIMENTAL=y
18CONFIG_CLEAN_COMPILE=y
19CONFIG_BROKEN_ON_SMP=y
20CONFIG_INIT_ENV_ARG_LIMIT=32
21
22#
23# General setup
24#
25CONFIG_LOCALVERSION=""
26CONFIG_LOCALVERSION_AUTO=y
27CONFIG_SWAP=y
28CONFIG_SYSVIPC=y
29# CONFIG_POSIX_MQUEUE is not set
30# CONFIG_BSD_PROCESS_ACCT is not set
31CONFIG_SYSCTL=y
32# CONFIG_AUDIT is not set
33CONFIG_HOTPLUG=y
34CONFIG_KOBJECT_UEVENT=y
35CONFIG_IKCONFIG=y
36CONFIG_IKCONFIG_PROC=y
37CONFIG_INITRAMFS_SOURCE=""
38# CONFIG_EMBEDDED is not set
39CONFIG_KALLSYMS=y
40# CONFIG_KALLSYMS_ALL is not set
41# CONFIG_KALLSYMS_EXTRA_PASS is not set
42CONFIG_PRINTK=y
43CONFIG_BUG=y
44CONFIG_BASE_FULL=y
45CONFIG_FUTEX=y
46CONFIG_EPOLL=y
47CONFIG_SHMEM=y
48CONFIG_CC_ALIGN_FUNCTIONS=0
49CONFIG_CC_ALIGN_LABELS=0
50CONFIG_CC_ALIGN_LOOPS=0
51CONFIG_CC_ALIGN_JUMPS=0
52# CONFIG_TINY_SHMEM is not set
53CONFIG_BASE_SMALL=0
54
55#
56# Loadable module support
57#
58CONFIG_MODULES=y
59CONFIG_MODULE_UNLOAD=y
60CONFIG_MODULE_FORCE_UNLOAD=y
61CONFIG_OBSOLETE_MODPARM=y
62# CONFIG_MODVERSIONS is not set
63# CONFIG_MODULE_SRCVERSION_ALL is not set
64CONFIG_KMOD=y
65
66#
67# System type
68#
69# CONFIG_SH_SOLUTION_ENGINE is not set
70# CONFIG_SH_7751_SOLUTION_ENGINE is not set
71# CONFIG_SH_7300_SOLUTION_ENGINE is not set
72# CONFIG_SH_73180_SOLUTION_ENGINE is not set
73# CONFIG_SH_7751_SYSTEMH is not set
74CONFIG_SH_TITAN=y
75# CONFIG_SH_STB1_HARP is not set
76# CONFIG_SH_STB1_OVERDRIVE is not set
77# CONFIG_SH_HP6XX is not set
78# CONFIG_SH_CQREEK is not set
79# CONFIG_SH_DMIDA is not set
80# CONFIG_SH_EC3104 is not set
81# CONFIG_SH_SATURN is not set
82# CONFIG_SH_DREAMCAST is not set
83# CONFIG_SH_CAT68701 is not set
84# CONFIG_SH_BIGSUR is not set
85# CONFIG_SH_SH2000 is not set
86# CONFIG_SH_ADX is not set
87# CONFIG_SH_MPC1211 is not set
88# CONFIG_SH_SH03 is not set
89# CONFIG_SH_SECUREEDGE5410 is not set
90# CONFIG_SH_HS7751RVOIP is not set
91# CONFIG_SH_RTS7751R2D is not set
92# CONFIG_SH_EDOSK7705 is not set
93# CONFIG_SH_SH4202_MICRODEV is not set
94# CONFIG_SH_LANDISK is not set
95# CONFIG_SH_UNKNOWN is not set
96
97#
98# Processor selection
99#
100CONFIG_CPU_SH4=y
101
102#
103# SH-2 Processor Support
104#
105# CONFIG_CPU_SUBTYPE_SH7604 is not set
106
107#
108# SH-3 Processor Support
109#
110# CONFIG_CPU_SUBTYPE_SH7300 is not set
111# CONFIG_CPU_SUBTYPE_SH7705 is not set
112# CONFIG_CPU_SUBTYPE_SH7707 is not set
113# CONFIG_CPU_SUBTYPE_SH7708 is not set
114# CONFIG_CPU_SUBTYPE_SH7709 is not set
115
116#
117# SH-4 Processor Support
118#
119# CONFIG_CPU_SUBTYPE_SH7750 is not set
120# CONFIG_CPU_SUBTYPE_SH7091 is not set
121# CONFIG_CPU_SUBTYPE_SH7750R is not set
122# CONFIG_CPU_SUBTYPE_SH7750S is not set
123CONFIG_CPU_SUBTYPE_SH7751=y
124CONFIG_CPU_SUBTYPE_SH7751R=y
125# CONFIG_CPU_SUBTYPE_SH7760 is not set
126# CONFIG_CPU_SUBTYPE_SH4_202 is not set
127
128#
129# ST40 Processor Support
130#
131# CONFIG_CPU_SUBTYPE_ST40STB1 is not set
132# CONFIG_CPU_SUBTYPE_ST40GX1 is not set
133
134#
135# SH-4A Processor Support
136#
137# CONFIG_CPU_SUBTYPE_SH73180 is not set
138# CONFIG_CPU_SUBTYPE_SH7770 is not set
139# CONFIG_CPU_SUBTYPE_SH7780 is not set
140
141#
142# Memory management options
143#
144CONFIG_MMU=y
145CONFIG_SELECT_MEMORY_MODEL=y
146CONFIG_FLATMEM_MANUAL=y
147# CONFIG_DISCONTIGMEM_MANUAL is not set
148# CONFIG_SPARSEMEM_MANUAL is not set
149CONFIG_FLATMEM=y
150CONFIG_FLAT_NODE_MEM_MAP=y
151# CONFIG_SPARSEMEM_STATIC is not set
152
153#
154# Cache configuration
155#
156# CONFIG_SH_DIRECT_MAPPED is not set
157# CONFIG_SH_WRITETHROUGH is not set
158# CONFIG_SH_OCRAM is not set
159CONFIG_MEMORY_START=0x08030000
160CONFIG_MEMORY_SIZE=0x7fd0000
161
162#
163# Processor features
164#
165CONFIG_CPU_LITTLE_ENDIAN=y
166CONFIG_SH_RTC=y
167CONFIG_SH_FPU=y
168# CONFIG_SH_STORE_QUEUES is not set
169
170#
171# Timer support
172#
173CONFIG_SH_TMU=y
174CONFIG_SH_PCLK_FREQ_BOOL=y
175CONFIG_SH_PCLK_FREQ=30000000
176
177#
178# CPU Frequency scaling
179#
180# CONFIG_CPU_FREQ is not set
181
182#
183# DMA support
184#
185CONFIG_SH_DMA=y
186CONFIG_NR_ONCHIP_DMA_CHANNELS=8
187# CONFIG_NR_DMA_CHANNELS_BOOL is not set
188
189#
190# Companion Chips
191#
192# CONFIG_HD6446X_SERIES is not set
193
194#
195# Kernel features
196#
197# CONFIG_KEXEC is not set
198# CONFIG_PREEMPT is not set
199# CONFIG_SMP is not set
200
201#
202# Boot options
203#
204CONFIG_ZERO_PAGE_OFFSET=0x00001000
205CONFIG_BOOT_LINK_OFFSET=0x009e0000
206# CONFIG_UBC_WAKEUP is not set
207CONFIG_CMDLINE_BOOL=y
208CONFIG_CMDLINE="console=ttySC1,38400N81 root=/dev/nfs ip=:::::eth1:autoconf"
209
210#
211# Bus options
212#
213CONFIG_PCI=y
214CONFIG_SH_PCIDMA_NONCOHERENT=y
215CONFIG_PCI_AUTO=y
216CONFIG_PCI_AUTO_UPDATE_RESOURCES=y
217CONFIG_PCI_LEGACY_PROC=y
218#CONFIG_PCI_DEBUG is not set
219
220#
221# PCCARD (PCMCIA/CardBus) support
222#
223# CONFIG_PCCARD is not set
224
225#
226# PCI Hotplug Support
227#
228CONFIG_HOTPLUG_PCI=y
229# CONFIG_HOTPLUG_PCI_FAKE is not set
230# CONFIG_HOTPLUG_PCI_CPCI is not set
231# CONFIG_HOTPLUG_PCI_SHPC is not set
232
233#
234# Executable file formats
235#
236CONFIG_BINFMT_ELF=y
237# CONFIG_BINFMT_FLAT is not set
238# CONFIG_BINFMT_MISC is not set
239
240#
241# Networking
242#
243CONFIG_NET=y
244
245#
246# Networking options
247#
248CONFIG_PACKET=y
249CONFIG_PACKET_MMAP=y
250CONFIG_UNIX=y
251CONFIG_XFRM=y
252# CONFIG_XFRM_USER is not set
253CONFIG_NET_KEY=y
254CONFIG_INET=y
255CONFIG_IP_MULTICAST=y
256CONFIG_IP_ADVANCED_ROUTER=y
257CONFIG_ASK_IP_FIB_HASH=y
258# CONFIG_IP_FIB_TRIE is not set
259CONFIG_IP_FIB_HASH=y
260CONFIG_IP_MULTIPLE_TABLES=y
261# CONFIG_IP_ROUTE_FWMARK is not set
262CONFIG_IP_ROUTE_MULTIPATH=y
263CONFIG_IP_ROUTE_MULTIPATH_CACHED=y
264CONFIG_IP_ROUTE_MULTIPATH_RR=m
265CONFIG_IP_ROUTE_MULTIPATH_RANDOM=m
266CONFIG_IP_ROUTE_MULTIPATH_WRANDOM=m
267CONFIG_IP_ROUTE_MULTIPATH_DRR=m
268# CONFIG_IP_ROUTE_VERBOSE is not set
269CONFIG_IP_PNP=y
270CONFIG_IP_PNP_DHCP=y
271CONFIG_IP_PNP_BOOTP=y
272CONFIG_IP_PNP_RARP=y
273CONFIG_NET_IPIP=m
274CONFIG_NET_IPGRE=m
275CONFIG_NET_IPGRE_BROADCAST=y
276CONFIG_IP_MROUTE=y
277CONFIG_IP_PIMSM_V1=y
278CONFIG_IP_PIMSM_V2=y
279# CONFIG_ARPD is not set
280CONFIG_SYN_COOKIES=y
281CONFIG_INET_AH=m
282CONFIG_INET_ESP=m
283CONFIG_INET_IPCOMP=m
284CONFIG_INET_TUNNEL=m
285CONFIG_INET_DIAG=m
286CONFIG_INET_TCP_DIAG=m
287# CONFIG_TCP_CONG_ADVANCED is not set
288CONFIG_TCP_CONG_BIC=y
289
290#
291# IP: Virtual Server Configuration
292#
293# CONFIG_IP_VS is not set
294CONFIG_IPV6=m
295CONFIG_IPV6_PRIVACY=y
296CONFIG_INET6_AH=m
297CONFIG_INET6_ESP=m
298CONFIG_INET6_IPCOMP=m
299CONFIG_INET6_TUNNEL=m
300CONFIG_IPV6_TUNNEL=m
301CONFIG_NETFILTER=y
302# CONFIG_NETFILTER_DEBUG is not set
303CONFIG_BRIDGE_NETFILTER=y
304CONFIG_NETFILTER_NETLINK=m
305CONFIG_NETFILTER_NETLINK_QUEUE=m
306CONFIG_NETFILTER_NETLINK_LOG=m
307
308#
309# IP: Netfilter Configuration
310#
311CONFIG_IP_NF_CONNTRACK=m
312CONFIG_IP_NF_CT_ACCT=y
313CONFIG_IP_NF_CONNTRACK_MARK=y
314CONFIG_IP_NF_CONNTRACK_EVENTS=y
315CONFIG_IP_NF_CONNTRACK_NETLINK=m
316# CONFIG_IP_NF_CT_PROTO_SCTP is not set
317CONFIG_IP_NF_FTP=m
318CONFIG_IP_NF_IRC=m
319CONFIG_IP_NF_NETBIOS_NS=m
320CONFIG_IP_NF_TFTP=m
321# CONFIG_IP_NF_AMANDA is not set
322CONFIG_IP_NF_PPTP=m
323CONFIG_IP_NF_QUEUE=m
324CONFIG_IP_NF_IPTABLES=m
325CONFIG_IP_NF_MATCH_LIMIT=m
326CONFIG_IP_NF_MATCH_IPRANGE=m
327CONFIG_IP_NF_MATCH_MAC=m
328CONFIG_IP_NF_MATCH_PKTTYPE=m
329CONFIG_IP_NF_MATCH_MARK=m
330CONFIG_IP_NF_MATCH_MULTIPORT=m
331CONFIG_IP_NF_MATCH_TOS=m
332CONFIG_IP_NF_MATCH_RECENT=m
333CONFIG_IP_NF_MATCH_ECN=m
334CONFIG_IP_NF_MATCH_DSCP=m
335CONFIG_IP_NF_MATCH_AH_ESP=m
336CONFIG_IP_NF_MATCH_LENGTH=m
337CONFIG_IP_NF_MATCH_TTL=m
338CONFIG_IP_NF_MATCH_TCPMSS=m
339CONFIG_IP_NF_MATCH_HELPER=m
340CONFIG_IP_NF_MATCH_STATE=m
341CONFIG_IP_NF_MATCH_CONNTRACK=m
342CONFIG_IP_NF_MATCH_OWNER=m
343# CONFIG_IP_NF_MATCH_PHYSDEV is not set
344CONFIG_IP_NF_MATCH_ADDRTYPE=m
345CONFIG_IP_NF_MATCH_REALM=m
346# CONFIG_IP_NF_MATCH_SCTP is not set
347# CONFIG_IP_NF_MATCH_DCCP is not set
348CONFIG_IP_NF_MATCH_COMMENT=m
349CONFIG_IP_NF_MATCH_CONNMARK=m
350CONFIG_IP_NF_MATCH_CONNBYTES=m
351CONFIG_IP_NF_MATCH_HASHLIMIT=m
352CONFIG_IP_NF_MATCH_STRING=m
353CONFIG_IP_NF_FILTER=m
354CONFIG_IP_NF_TARGET_REJECT=m
355CONFIG_IP_NF_TARGET_LOG=m
356CONFIG_IP_NF_TARGET_ULOG=m
357CONFIG_IP_NF_TARGET_TCPMSS=m
358CONFIG_IP_NF_TARGET_NFQUEUE=m
359CONFIG_IP_NF_NAT=m
360CONFIG_IP_NF_NAT_NEEDED=y
361CONFIG_IP_NF_TARGET_MASQUERADE=m
362CONFIG_IP_NF_TARGET_REDIRECT=m
363CONFIG_IP_NF_TARGET_NETMAP=m
364CONFIG_IP_NF_TARGET_SAME=m
365CONFIG_IP_NF_NAT_SNMP_BASIC=m
366CONFIG_IP_NF_NAT_IRC=m
367CONFIG_IP_NF_NAT_FTP=m
368CONFIG_IP_NF_NAT_TFTP=m
369CONFIG_IP_NF_NAT_PPTP=m
370CONFIG_IP_NF_MANGLE=m
371CONFIG_IP_NF_TARGET_TOS=m
372CONFIG_IP_NF_TARGET_ECN=m
373CONFIG_IP_NF_TARGET_DSCP=m
374CONFIG_IP_NF_TARGET_MARK=m
375CONFIG_IP_NF_TARGET_CLASSIFY=m
376CONFIG_IP_NF_TARGET_TTL=m
377CONFIG_IP_NF_TARGET_CONNMARK=m
378CONFIG_IP_NF_TARGET_CLUSTERIP=m
379CONFIG_IP_NF_RAW=m
380CONFIG_IP_NF_TARGET_NOTRACK=m
381CONFIG_IP_NF_ARPTABLES=m
382CONFIG_IP_NF_ARPFILTER=m
383CONFIG_IP_NF_ARP_MANGLE=m
384
385#
386# IPv6: Netfilter Configuration (EXPERIMENTAL)
387#
388CONFIG_IP6_NF_QUEUE=m
389CONFIG_IP6_NF_IPTABLES=m
390CONFIG_IP6_NF_MATCH_LIMIT=m
391CONFIG_IP6_NF_MATCH_MAC=m
392CONFIG_IP6_NF_MATCH_RT=m
393CONFIG_IP6_NF_MATCH_OPTS=m
394CONFIG_IP6_NF_MATCH_FRAG=m
395CONFIG_IP6_NF_MATCH_HL=m
396CONFIG_IP6_NF_MATCH_MULTIPORT=m
397CONFIG_IP6_NF_MATCH_OWNER=m
398CONFIG_IP6_NF_MATCH_MARK=m
399CONFIG_IP6_NF_MATCH_IPV6HEADER=m
400CONFIG_IP6_NF_MATCH_AHESP=m
401CONFIG_IP6_NF_MATCH_LENGTH=m
402CONFIG_IP6_NF_MATCH_EUI64=m
403# CONFIG_IP6_NF_MATCH_PHYSDEV is not set
404CONFIG_IP6_NF_FILTER=m
405CONFIG_IP6_NF_TARGET_LOG=m
406CONFIG_IP6_NF_TARGET_REJECT=m
407CONFIG_IP6_NF_TARGET_NFQUEUE=m
408CONFIG_IP6_NF_MANGLE=m
409CONFIG_IP6_NF_TARGET_MARK=m
410CONFIG_IP6_NF_TARGET_HL=m
411CONFIG_IP6_NF_RAW=m
412
413#
414# Bridge: Netfilter Configuration
415#
416# CONFIG_BRIDGE_NF_EBTABLES is not set
417
418#
419# DCCP Configuration (EXPERIMENTAL)
420#
421# CONFIG_IP_DCCP is not set
422
423#
424# SCTP Configuration (EXPERIMENTAL)
425#
426# CONFIG_IP_SCTP is not set
427# CONFIG_ATM is not set
428CONFIG_BRIDGE=m
429CONFIG_VLAN_8021Q=m
430# CONFIG_DECNET is not set
431# CONFIG_LLC2 is not set
432# CONFIG_IPX is not set
433# CONFIG_ATALK is not set
434# CONFIG_X25 is not set
435# CONFIG_LAPB is not set
436# CONFIG_NET_DIVERT is not set
437# CONFIG_ECONET is not set
438# CONFIG_WAN_ROUTER is not set
439CONFIG_NET_SCHED=y
440CONFIG_NET_SCH_CLK_JIFFIES=y
441# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
442# CONFIG_NET_SCH_CLK_CPU is not set
443CONFIG_NET_SCH_CBQ=m
444CONFIG_NET_SCH_HTB=m
445CONFIG_NET_SCH_HFSC=m
446CONFIG_NET_SCH_PRIO=m
447CONFIG_NET_SCH_RED=m
448CONFIG_NET_SCH_SFQ=m
449CONFIG_NET_SCH_TEQL=m
450CONFIG_NET_SCH_TBF=m
451CONFIG_NET_SCH_GRED=m
452CONFIG_NET_SCH_DSMARK=m
453CONFIG_NET_SCH_NETEM=m
454CONFIG_NET_SCH_INGRESS=m
455CONFIG_NET_QOS=y
456CONFIG_NET_ESTIMATOR=y
457CONFIG_NET_CLS=y
458CONFIG_NET_CLS_BASIC=m
459CONFIG_NET_CLS_TCINDEX=m
460CONFIG_NET_CLS_ROUTE4=m
461CONFIG_NET_CLS_ROUTE=y
462CONFIG_NET_CLS_FW=m
463CONFIG_NET_CLS_U32=m
464CONFIG_CLS_U32_PERF=y
465CONFIG_NET_CLS_IND=y
466CONFIG_CLS_U32_MARK=y
467CONFIG_NET_CLS_RSVP=m
468CONFIG_NET_CLS_RSVP6=m
469CONFIG_NET_EMATCH=y
470CONFIG_NET_EMATCH_STACK=32
471CONFIG_NET_EMATCH_CMP=m
472CONFIG_NET_EMATCH_NBYTE=m
473CONFIG_NET_EMATCH_U32=m
474CONFIG_NET_EMATCH_META=m
475CONFIG_NET_EMATCH_TEXT=m
476CONFIG_NET_CLS_ACT=y
477CONFIG_NET_ACT_POLICE=m
478CONFIG_NET_ACT_GACT=m
479CONFIG_GACT_PROB=y
480CONFIG_NET_ACT_MIRRED=m
481CONFIG_NET_ACT_IPT=m
482CONFIG_NET_ACT_PEDIT=m
483# CONFIG_NET_ACT_SIMP is not set
484
485#
486# Network testing
487#
488# CONFIG_NET_PKTGEN is not set
489# CONFIG_HAMRADIO is not set
490# CONFIG_IRDA is not set
491# CONFIG_BT is not set
492# CONFIG_IEEE80211 is not set
493
494#
495# Device Drivers
496#
497
498#
499# Generic Driver Options
500#
501CONFIG_STANDALONE=y
502CONFIG_PREVENT_FIRMWARE_BUILD=y
503CONFIG_FW_LOADER=m
504# CONFIG_DEBUG_DRIVER is not set
505
506#
507# Connector - unified userspace <-> kernelspace linker
508#
509CONFIG_CONNECTOR=m
510
511#
512# Memory Technology Devices (MTD)
513#
514# CONFIG_MTD is not set
515
516#
517# Parallel port support
518#
519# CONFIG_PARPORT is not set
520
521#
522# Plug and Play support
523#
524
525#
526# Block devices
527#
528# CONFIG_BLK_CPQ_DA is not set
529# CONFIG_BLK_CPQ_CISS_DA is not set
530# CONFIG_BLK_DEV_DAC960 is not set
531CONFIG_BLK_SSFDC=y
532# CONFIG_BLK_DEV_UMEM is not set
533# CONFIG_BLK_DEV_COW_COMMON is not set
534CONFIG_BLK_DEV_LOOP=m
535# CONFIG_BLK_DEV_CRYPTOLOOP is not set
536# CONFIG_BLK_DEV_NBD is not set
537# CONFIG_BLK_DEV_SX8 is not set
538# CONFIG_BLK_DEV_UB is not set
539CONFIG_BLK_DEV_RAM=y
540CONFIG_BLK_DEV_RAM_COUNT=16
541CONFIG_BLK_DEV_RAM_SIZE=4096
542CONFIG_BLK_DEV_INITRD=y
543# CONFIG_LBD is not set
544# CONFIG_CDROM_PKTCDVD is not set
545
546#
547# IO Schedulers
548#
549CONFIG_IOSCHED_NOOP=y
550CONFIG_IOSCHED_AS=y
551CONFIG_IOSCHED_DEADLINE=y
552CONFIG_IOSCHED_CFQ=y
553# CONFIG_ATA_OVER_ETH is not set
554
555#
556# ATA/ATAPI/MFM/RLL support
557#
558# CONFIG_IDE is not set
559
560#
561# SCSI device support
562#
563# CONFIG_RAID_ATTRS is not set
564CONFIG_SCSI=m
565CONFIG_SCSI_PROC_FS=y
566
567#
568# SCSI support type (disk, tape, CD-ROM)
569#
570CONFIG_BLK_DEV_SD=m
571# CONFIG_CHR_DEV_ST is not set
572# CONFIG_CHR_DEV_OSST is not set
573CONFIG_BLK_DEV_SR=m
574# CONFIG_BLK_DEV_SR_VENDOR is not set
575CONFIG_CHR_DEV_SG=m
576# CONFIG_CHR_DEV_SCH is not set
577
578#
579# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
580#
581# CONFIG_SCSI_MULTI_LUN is not set
582# CONFIG_SCSI_CONSTANTS is not set
583# CONFIG_SCSI_LOGGING is not set
584
585#
586# SCSI Transport Attributes
587#
588# CONFIG_SCSI_SPI_ATTRS is not set
589# CONFIG_SCSI_FC_ATTRS is not set
590# CONFIG_SCSI_ISCSI_ATTRS is not set
591# CONFIG_SCSI_SAS_ATTRS is not set
592
593#
594# SCSI low-level drivers
595#
596# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
597# CONFIG_SCSI_3W_9XXX is not set
598# CONFIG_SCSI_ACARD is not set
599# CONFIG_SCSI_AACRAID is not set
600# CONFIG_SCSI_AIC7XXX is not set
601# CONFIG_SCSI_AIC7XXX_OLD is not set
602# CONFIG_SCSI_AIC79XX is not set
603# CONFIG_SCSI_DPT_I2O is not set
604# CONFIG_MEGARAID_NEWGEN is not set
605# CONFIG_MEGARAID_LEGACY is not set
606# CONFIG_MEGARAID_SAS is not set
607# CONFIG_SCSI_SATA is not set
608# CONFIG_SCSI_DMX3191D is not set
609# CONFIG_SCSI_FUTURE_DOMAIN is not set
610# CONFIG_SCSI_IPS is not set
611# CONFIG_SCSI_INITIO is not set
612# CONFIG_SCSI_INIA100 is not set
613# CONFIG_SCSI_SYM53C8XX_2 is not set
614# CONFIG_SCSI_IPR is not set
615# CONFIG_SCSI_QLOGIC_FC is not set
616# CONFIG_SCSI_QLOGIC_1280 is not set
617CONFIG_SCSI_QLA2XXX=m
618# CONFIG_SCSI_QLA21XX is not set
619# CONFIG_SCSI_QLA22XX is not set
620# CONFIG_SCSI_QLA2300 is not set
621# CONFIG_SCSI_QLA2322 is not set
622# CONFIG_SCSI_QLA6312 is not set
623# CONFIG_SCSI_QLA24XX is not set
624# CONFIG_SCSI_LPFC is not set
625# CONFIG_SCSI_DC395x is not set
626# CONFIG_SCSI_DC390T is not set
627# CONFIG_SCSI_NSP32 is not set
628# CONFIG_SCSI_DEBUG is not set
629
630#
631# Multi-device support (RAID and LVM)
632#
633# CONFIG_MD is not set
634
635#
636# Fusion MPT device support
637#
638# CONFIG_FUSION is not set
639# CONFIG_FUSION_SPI is not set
640# CONFIG_FUSION_FC is not set
641# CONFIG_FUSION_SAS is not set
642
643#
644# IEEE 1394 (FireWire) support
645#
646# CONFIG_IEEE1394 is not set
647
648#
649# I2O device support
650#
651# CONFIG_I2O is not set
652
653#
654# Network device support
655#
656CONFIG_NETDEVICES=y
657# CONFIG_DUMMY is not set
658# CONFIG_BONDING is not set
659# CONFIG_EQUALIZER is not set
660CONFIG_TUN=m
661
662#
663# ARCnet devices
664#
665# CONFIG_ARCNET is not set
666
667#
668# PHY device support
669#
670CONFIG_PHYLIB=m
671CONFIG_PHYCONTROL=y
672
673#
674# MII PHY device drivers
675#
676CONFIG_MARVELL_PHY=m
677CONFIG_DAVICOM_PHY=m
678CONFIG_QSEMI_PHY=m
679CONFIG_LXT_PHY=m
680CONFIG_CICADA_PHY=m
681
682#
683# Ethernet (10 or 100Mbit)
684#
685CONFIG_NET_ETHERNET=y
686CONFIG_MII=y
687# CONFIG_STNIC is not set
688# CONFIG_HAPPYMEAL is not set
689# CONFIG_SUNGEM is not set
690CONFIG_CASSINI=m
691# CONFIG_NET_VENDOR_3COM is not set
692# CONFIG_SMC91X is not set
693
694#
695# Tulip family network device support
696#
697# CONFIG_NET_TULIP is not set
698# CONFIG_HP100 is not set
699# CONFIG_NE2000 is not set
700CONFIG_NET_PCI=y
701# CONFIG_PCNET32 is not set
702# CONFIG_AMD8111_ETH is not set
703# CONFIG_ADAPTEC_STARFIRE is not set
704# CONFIG_B44 is not set
705# CONFIG_FORCEDETH is not set
706# CONFIG_DGRS is not set
707# CONFIG_EEPRO100 is not set
708# CONFIG_E100 is not set
709# CONFIG_FEALNX is not set
710# CONFIG_NATSEMI is not set
711# CONFIG_NE2K_PCI is not set
712# CONFIG_8139CP is not set
713CONFIG_8139TOO=y
714# CONFIG_8139TOO_PIO is not set
715CONFIG_8139TOO_TUNE_TWISTER=y
716# CONFIG_8139TOO_8129 is not set
717CONFIG_8139_OLD_RX_RESET=y
718# CONFIG_SIS900 is not set
719# CONFIG_EPIC100 is not set
720# CONFIG_SUNDANCE is not set
721# CONFIG_TLAN is not set
722# CONFIG_VIA_RHINE is not set
723
724#
725# Ethernet (1000 Mbit)
726#
727# CONFIG_ACENIC is not set
728# CONFIG_DL2K is not set
729# CONFIG_E1000 is not set
730# CONFIG_NS83820 is not set
731# CONFIG_HAMACHI is not set
732# CONFIG_YELLOWFIN is not set
733# CONFIG_R8169 is not set
734# CONFIG_SIS190 is not set
735# CONFIG_SKGE is not set
736# CONFIG_SK98LIN is not set
737# CONFIG_VIA_VELOCITY is not set
738# CONFIG_TIGON3 is not set
739# CONFIG_BNX2 is not set
740
741#
742# Ethernet (10000 Mbit)
743#
744# CONFIG_CHELSIO_T1 is not set
745# CONFIG_IXGB is not set
746# CONFIG_S2IO is not set
747
748#
749# Token Ring devices
750#
751# CONFIG_TR is not set
752
753#
754# Wireless LAN (non-hamradio)
755#
756CONFIG_NET_RADIO=y
757
758#
759# Obsolete Wireless cards support (pre-802.11)
760#
761# CONFIG_STRIP is not set
762
763#
764# Wireless 802.11b ISA/PCI cards support
765#
766# CONFIG_HERMES is not set
767# CONFIG_ATMEL is not set
768
769#
770# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
771#
772CONFIG_PRISM54=m
773# CONFIG_HOSTAP is not set
774CONFIG_NET_WIRELESS=y
775
776#
777# Wan interfaces
778#
779# CONFIG_WAN is not set
780# CONFIG_FDDI is not set
781# CONFIG_HIPPI is not set
782CONFIG_PPP=m
783CONFIG_PPP_MULTILINK=y
784CONFIG_PPP_FILTER=y
785CONFIG_PPP_ASYNC=m
786CONFIG_PPP_SYNC_TTY=m
787CONFIG_PPP_DEFLATE=m
788CONFIG_PPP_BSDCOMP=m
789CONFIG_PPPOE=m
790# CONFIG_SLIP is not set
791# CONFIG_NET_FC is not set
792# CONFIG_SHAPER is not set
793# CONFIG_NETCONSOLE is not set
794# CONFIG_NETPOLL is not set
795# CONFIG_NET_POLL_CONTROLLER is not set
796
797#
798# ISDN subsystem
799#
800# CONFIG_ISDN is not set
801
802#
803# Telephony Support
804#
805# CONFIG_PHONE is not set
806
807#
808# Input device support
809#
810CONFIG_INPUT=y
811
812#
813# Userland interfaces
814#
815CONFIG_INPUT_MOUSEDEV=y
816# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
817CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
818CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
819# CONFIG_INPUT_JOYDEV is not set
820# CONFIG_INPUT_TSDEV is not set
821# CONFIG_INPUT_EVDEV is not set
822# CONFIG_INPUT_EVBUG is not set
823
824#
825# Input Device Drivers
826#
827# CONFIG_INPUT_KEYBOARD is not set
828# CONFIG_INPUT_MOUSE is not set
829# CONFIG_INPUT_JOYSTICK is not set
830# CONFIG_INPUT_TOUCHSCREEN is not set
831# CONFIG_INPUT_MISC is not set
832
833#
834# Hardware I/O ports
835#
836# CONFIG_SERIO is not set
837# CONFIG_GAMEPORT is not set
838
839#
840# Character devices
841#
842CONFIG_VT=y
843CONFIG_VT_CONSOLE=y
844CONFIG_HW_CONSOLE=y
845# CONFIG_SERIAL_NONSTANDARD is not set
846
847#
848# Serial drivers
849#
850# CONFIG_SERIAL_8250 is not set
851
852#
853# Non-8250 serial port support
854#
855CONFIG_SERIAL_SH_SCI=y
856CONFIG_SERIAL_SH_SCI_CONSOLE=y
857CONFIG_SERIAL_CORE=y
858CONFIG_SERIAL_CORE_CONSOLE=y
859# CONFIG_SERIAL_JSM is not set
860CONFIG_UNIX98_PTYS=y
861CONFIG_LEGACY_PTYS=y
862CONFIG_LEGACY_PTY_COUNT=256
863
864#
865# IPMI
866#
867# CONFIG_IPMI_HANDLER is not set
868
869#
870# Watchdog Cards
871#
872# CONFIG_WATCHDOG is not set
873# CONFIG_RTC is not set
874# CONFIG_GEN_RTC is not set
875# CONFIG_DTLK is not set
876# CONFIG_R3964 is not set
877# CONFIG_APPLICOM is not set
878
879#
880# Ftape, the floppy tape device driver
881#
882# CONFIG_DRM is not set
883# CONFIG_RAW_DRIVER is not set
884
885#
886# TPM devices
887#
888# CONFIG_TCG_TPM is not set
889
890#
891# I2C support
892#
893# CONFIG_I2C is not set
894
895#
896# Dallas's 1-wire bus
897#
898# CONFIG_W1 is not set
899
900#
901# Hardware Monitoring support
902#
903CONFIG_HWMON=y
904# CONFIG_HWMON_VID is not set
905# CONFIG_HWMON_DEBUG_CHIP is not set
906
907#
908# Misc devices
909#
910
911#
912# Multimedia Capabilities Port drivers
913#
914
915#
916# Multimedia devices
917#
918# CONFIG_VIDEO_DEV is not set
919
920#
921# Digital Video Broadcasting Devices
922#
923# CONFIG_DVB is not set
924
925#
926# Graphics support
927#
928# CONFIG_FB is not set
929
930#
931# Console display driver support
932#
933CONFIG_DUMMY_CONSOLE=y
934
935#
936# Sound
937#
938# CONFIG_SOUND is not set
939
940#
941# USB support
942#
943CONFIG_USB_ARCH_HAS_HCD=y
944CONFIG_USB_ARCH_HAS_OHCI=y
945CONFIG_USB=m
946# CONFIG_USB_DEBUG is not set
947
948#
949# Miscellaneous USB options
950#
951CONFIG_USB_DEVICEFS=y
952# CONFIG_USB_BANDWIDTH is not set
953# CONFIG_USB_DYNAMIC_MINORS is not set
954# CONFIG_USB_OTG is not set
955
956#
957# USB Host Controller Drivers
958#
959CONFIG_USB_EHCI_HCD=m
960# CONFIG_USB_EHCI_SPLIT_ISO is not set
961# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
962# CONFIG_USB_ISP116X_HCD is not set
963CONFIG_USB_OHCI_HCD=m
964# CONFIG_USB_OHCI_BIG_ENDIAN is not set
965CONFIG_USB_OHCI_LITTLE_ENDIAN=y
966# CONFIG_USB_UHCI_HCD is not set
967# CONFIG_USB_SL811_HCD is not set
968
969#
970# USB Device Class drivers
971#
972# CONFIG_USB_BLUETOOTH_TTY is not set
973# CONFIG_USB_ACM is not set
974# CONFIG_USB_PRINTER is not set
975
976#
977# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
978#
979CONFIG_USB_STORAGE=m
980# CONFIG_USB_STORAGE_DEBUG is not set
981# CONFIG_USB_STORAGE_DATAFAB is not set
982# CONFIG_USB_STORAGE_FREECOM is not set
983# CONFIG_USB_STORAGE_DPCM is not set
984# CONFIG_USB_STORAGE_USBAT is not set
985# CONFIG_USB_STORAGE_SDDR09 is not set
986# CONFIG_USB_STORAGE_SDDR55 is not set
987# CONFIG_USB_STORAGE_JUMPSHOT is not set
988
989#
990# USB Input Devices
991#
992# CONFIG_USB_HID is not set
993
994#
995# USB HID Boot Protocol drivers
996#
997# CONFIG_USB_KBD is not set
998# CONFIG_USB_MOUSE is not set
999# CONFIG_USB_AIPTEK is not set
1000# CONFIG_USB_WACOM is not set
1001# CONFIG_USB_ACECAD is not set
1002# CONFIG_USB_KBTAB is not set
1003# CONFIG_USB_POWERMATE is not set
1004# CONFIG_USB_MTOUCH is not set
1005# CONFIG_USB_ITMTOUCH is not set
1006# CONFIG_USB_EGALAX is not set
1007# CONFIG_USB_YEALINK is not set
1008# CONFIG_USB_XPAD is not set
1009# CONFIG_USB_ATI_REMOTE is not set
1010# CONFIG_USB_KEYSPAN_REMOTE is not set
1011# CONFIG_USB_APPLETOUCH is not set
1012
1013#
1014# USB Imaging devices
1015#
1016# CONFIG_USB_MDC800 is not set
1017# CONFIG_USB_MICROTEK is not set
1018
1019#
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
1030#
1031# CONFIG_USB_CATC is not set
1032# CONFIG_USB_KAWETH is not set
1033# CONFIG_USB_PEGASUS is not set
1034# CONFIG_USB_RTL8150 is not set
1035# CONFIG_USB_USBNET is not set
1036# CONFIG_USB_ZD1201 is not set
1037CONFIG_USB_MON=y
1038
1039#
1040# USB port drivers
1041#
1042
1043#
1044# USB Serial Converter support
1045#
1046CONFIG_USB_SERIAL=m
1047CONFIG_USB_SERIAL_GENERIC=y
1048# CONFIG_USB_SERIAL_AIRPRIME is not set
1049# CONFIG_USB_SERIAL_BELKIN is not set
1050# CONFIG_USB_SERIAL_WHITEHEAT is not set
1051# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
1052# CONFIG_USB_SERIAL_CP2101 is not set
1053# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
1054# CONFIG_USB_SERIAL_EMPEG is not set
1055# CONFIG_USB_SERIAL_FTDI_SIO is not set
1056# CONFIG_USB_SERIAL_VISOR is not set
1057# CONFIG_USB_SERIAL_IPAQ is not set
1058# CONFIG_USB_SERIAL_IR is not set
1059# CONFIG_USB_SERIAL_EDGEPORT is not set
1060# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
1061# CONFIG_USB_SERIAL_GARMIN is not set
1062# CONFIG_USB_SERIAL_IPW is not set
1063# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
1064# CONFIG_USB_SERIAL_KEYSPAN is not set
1065# CONFIG_USB_SERIAL_KLSI is not set
1066# CONFIG_USB_SERIAL_KOBIL_SCT is not set
1067# CONFIG_USB_SERIAL_MCT_U232 is not set
1068CONFIG_USB_SERIAL_PL2303=m
1069# CONFIG_USB_SERIAL_HP4X is not set
1070# CONFIG_USB_SERIAL_SAFE is not set
1071# CONFIG_USB_SERIAL_TI is not set
1072# CONFIG_USB_SERIAL_CYBERJACK is not set
1073# CONFIG_USB_SERIAL_XIRCOM is not set
1074# CONFIG_USB_SERIAL_OMNINET is not set
1075
1076#
1077# USB Miscellaneous drivers
1078#
1079# CONFIG_USB_EMI62 is not set
1080# CONFIG_USB_EMI26 is not set
1081# CONFIG_USB_AUERSWALD is not set
1082# CONFIG_USB_RIO500 is not set
1083# CONFIG_USB_LEGOTOWER is not set
1084# CONFIG_USB_LCD is not set
1085# CONFIG_USB_LED is not set
1086# CONFIG_USB_CYTHERM is not set
1087# CONFIG_USB_PHIDGETKIT is not set
1088# CONFIG_USB_PHIDGETSERVO is not set
1089# CONFIG_USB_IDMOUSE is not set
1090# CONFIG_USB_SISUSBVGA is not set
1091# CONFIG_USB_LD is not set
1092# CONFIG_USB_TEST is not set
1093
1094#
1095# USB DSL modem support
1096#
1097
1098#
1099# USB Gadget Support
1100#
1101# CONFIG_USB_GADGET is not set
1102
1103#
1104# MMC/SD Card support
1105#
1106# CONFIG_MMC is not set
1107
1108#
1109# InfiniBand support
1110#
1111# CONFIG_INFINIBAND is not set
1112
1113#
1114# SN Devices
1115#
1116
1117#
1118# File systems
1119#
1120CONFIG_EXT2_FS=y
1121CONFIG_EXT2_FS_XATTR=y
1122CONFIG_EXT2_FS_POSIX_ACL=y
1123CONFIG_EXT2_FS_SECURITY=y
1124# CONFIG_EXT2_FS_XIP is not set
1125CONFIG_EXT3_FS=y
1126CONFIG_EXT3_FS_XATTR=y
1127CONFIG_EXT3_FS_POSIX_ACL=y
1128CONFIG_EXT3_FS_SECURITY=y
1129CONFIG_JBD=y
1130# CONFIG_JBD_DEBUG is not set
1131CONFIG_FS_MBCACHE=y
1132CONFIG_REISERFS_FS=m
1133# CONFIG_REISERFS_CHECK is not set
1134# CONFIG_REISERFS_PROC_INFO is not set
1135# CONFIG_REISERFS_FS_XATTR is not set
1136# CONFIG_JFS_FS is not set
1137CONFIG_FS_POSIX_ACL=y
1138# CONFIG_XFS_FS is not set
1139# CONFIG_MINIX_FS is not set
1140# CONFIG_ROMFS_FS is not set
1141CONFIG_INOTIFY=y
1142# CONFIG_QUOTA is not set
1143CONFIG_DNOTIFY=y
1144# CONFIG_AUTOFS_FS is not set
1145# CONFIG_AUTOFS4_FS is not set
1146CONFIG_FUSE_FS=m
1147
1148#
1149# CD-ROM/DVD Filesystems
1150#
1151CONFIG_ISO9660_FS=m
1152CONFIG_JOLIET=y
1153CONFIG_ZISOFS=y
1154CONFIG_ZISOFS_FS=m
1155CONFIG_UDF_FS=m
1156CONFIG_UDF_NLS=y
1157
1158#
1159# DOS/FAT/NT Filesystems
1160#
1161CONFIG_FAT_FS=m
1162CONFIG_MSDOS_FS=m
1163CONFIG_VFAT_FS=m
1164CONFIG_FAT_DEFAULT_CODEPAGE=437
1165CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1166# CONFIG_NTFS_FS is not set
1167
1168#
1169# Pseudo filesystems
1170#
1171CONFIG_PROC_FS=y
1172CONFIG_PROC_KCORE=y
1173CONFIG_SYSFS=y
1174CONFIG_TMPFS=y
1175# CONFIG_HUGETLBFS is not set
1176# CONFIG_HUGETLB_PAGE is not set
1177CONFIG_RAMFS=y
1178CONFIG_RELAYFS_FS=m
1179
1180#
1181# Miscellaneous filesystems
1182#
1183# CONFIG_ADFS_FS is not set
1184# CONFIG_AFFS_FS is not set
1185# CONFIG_HFS_FS is not set
1186# CONFIG_HFSPLUS_FS is not set
1187# CONFIG_BEFS_FS is not set
1188# CONFIG_BFS_FS is not set
1189# CONFIG_EFS_FS is not set
1190# CONFIG_CRAMFS is not set
1191# CONFIG_VXFS_FS is not set
1192# CONFIG_HPFS_FS is not set
1193# CONFIG_QNX4FS_FS is not set
1194# CONFIG_SYSV_FS is not set
1195# CONFIG_UFS_FS is not set
1196
1197#
1198# Network File Systems
1199#
1200CONFIG_NFS_FS=y
1201CONFIG_NFS_V3=y
1202# CONFIG_NFS_V3_ACL is not set
1203# CONFIG_NFS_V4 is not set
1204# CONFIG_NFS_DIRECTIO is not set
1205CONFIG_NFSD=y
1206CONFIG_NFSD_V3=y
1207# CONFIG_NFSD_V3_ACL is not set
1208# CONFIG_NFSD_V4 is not set
1209CONFIG_NFSD_TCP=y
1210CONFIG_ROOT_NFS=y
1211CONFIG_LOCKD=y
1212CONFIG_LOCKD_V4=y
1213CONFIG_EXPORTFS=y
1214CONFIG_NFS_COMMON=y
1215CONFIG_SUNRPC=y
1216# CONFIG_RPCSEC_GSS_KRB5 is not set
1217# CONFIG_RPCSEC_GSS_SPKM3 is not set
1218CONFIG_SMB_FS=m
1219# CONFIG_SMB_NLS_DEFAULT is not set
1220# CONFIG_CIFS is not set
1221# CONFIG_NCP_FS is not set
1222# CONFIG_CODA_FS is not set
1223# CONFIG_AFS_FS is not set
1224CONFIG_9P_FS=m
1225
1226#
1227# Partition Types
1228#
1229CONFIG_PARTITION_ADVANCED=y
1230# CONFIG_ACORN_PARTITION is not set
1231# CONFIG_OSF_PARTITION is not set
1232# CONFIG_AMIGA_PARTITION is not set
1233# CONFIG_ATARI_PARTITION is not set
1234# CONFIG_MAC_PARTITION is not set
1235CONFIG_MSDOS_PARTITION=y
1236# CONFIG_BSD_DISKLABEL is not set
1237# CONFIG_MINIX_SUBPARTITION is not set
1238# CONFIG_SOLARIS_X86_PARTITION is not set
1239# CONFIG_UNIXWARE_DISKLABEL is not set
1240# CONFIG_LDM_PARTITION is not set
1241# CONFIG_SGI_PARTITION is not set
1242# CONFIG_ULTRIX_PARTITION is not set
1243# CONFIG_SUN_PARTITION is not set
1244# CONFIG_EFI_PARTITION is not set
1245
1246#
1247# Native Language Support
1248#
1249CONFIG_NLS=m
1250CONFIG_NLS_DEFAULT="iso8859-1"
1251CONFIG_NLS_CODEPAGE_437=m
1252# CONFIG_NLS_CODEPAGE_737 is not set
1253# CONFIG_NLS_CODEPAGE_775 is not set
1254# CONFIG_NLS_CODEPAGE_850 is not set
1255# CONFIG_NLS_CODEPAGE_852 is not set
1256# CONFIG_NLS_CODEPAGE_855 is not set
1257# CONFIG_NLS_CODEPAGE_857 is not set
1258# CONFIG_NLS_CODEPAGE_860 is not set
1259# CONFIG_NLS_CODEPAGE_861 is not set
1260# CONFIG_NLS_CODEPAGE_862 is not set
1261# CONFIG_NLS_CODEPAGE_863 is not set
1262# CONFIG_NLS_CODEPAGE_864 is not set
1263# CONFIG_NLS_CODEPAGE_865 is not set
1264# CONFIG_NLS_CODEPAGE_866 is not set
1265# CONFIG_NLS_CODEPAGE_869 is not set
1266# CONFIG_NLS_CODEPAGE_936 is not set
1267# CONFIG_NLS_CODEPAGE_950 is not set
1268# CONFIG_NLS_CODEPAGE_932 is not set
1269# CONFIG_NLS_CODEPAGE_949 is not set
1270# CONFIG_NLS_CODEPAGE_874 is not set
1271# CONFIG_NLS_ISO8859_8 is not set
1272# CONFIG_NLS_CODEPAGE_1250 is not set
1273# CONFIG_NLS_CODEPAGE_1251 is not set
1274CONFIG_NLS_ASCII=m
1275CONFIG_NLS_ISO8859_1=m
1276# CONFIG_NLS_ISO8859_2 is not set
1277# CONFIG_NLS_ISO8859_3 is not set
1278# CONFIG_NLS_ISO8859_4 is not set
1279# CONFIG_NLS_ISO8859_5 is not set
1280# CONFIG_NLS_ISO8859_6 is not set
1281# CONFIG_NLS_ISO8859_7 is not set
1282# CONFIG_NLS_ISO8859_9 is not set
1283# CONFIG_NLS_ISO8859_13 is not set
1284# CONFIG_NLS_ISO8859_14 is not set
1285# CONFIG_NLS_ISO8859_15 is not set
1286# CONFIG_NLS_KOI8_R is not set
1287# CONFIG_NLS_KOI8_U is not set
1288CONFIG_NLS_UTF8=m
1289
1290#
1291# Profiling support
1292#
1293# CONFIG_PROFILING is not set
1294
1295#
1296# Kernel hacking
1297#
1298# CONFIG_PRINTK_TIME is not set
1299CONFIG_DEBUG_KERNEL=y
1300CONFIG_MAGIC_SYSRQ=y
1301CONFIG_LOG_BUF_SHIFT=16
1302# CONFIG_DETECT_SOFTLOCKUP is not set
1303# CONFIG_SCHEDSTATS is not set
1304CONFIG_DEBUG_SLAB=y
1305# CONFIG_DEBUG_SPINLOCK is not set
1306# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1307# CONFIG_DEBUG_KOBJECT is not set
1308# CONFIG_DEBUG_INFO is not set
1309# CONFIG_DEBUG_FS is not set
1310# CONFIG_FRAME_POINTER is not set
1311# CONFIG_SH_STANDARD_BIOS is not set
1312CONFIG_EARLY_SCIF_CONSOLE=y
1313# CONFIG_EARLY_PRINTK is not set
1314# CONFIG_KGDB is not set
1315
1316#
1317# Security options
1318#
1319# CONFIG_KEYS is not set
1320# CONFIG_SECURITY is not set
1321
1322#
1323# Cryptographic options
1324#
1325CONFIG_CRYPTO=y
1326CONFIG_CRYPTO_HMAC=y
1327# CONFIG_CRYPTO_NULL is not set
1328CONFIG_CRYPTO_MD4=m
1329CONFIG_CRYPTO_MD5=m
1330CONFIG_CRYPTO_SHA1=m
1331CONFIG_CRYPTO_SHA256=m
1332CONFIG_CRYPTO_SHA512=m
1333CONFIG_CRYPTO_WP512=m
1334CONFIG_CRYPTO_TGR192=m
1335CONFIG_CRYPTO_DES=m
1336CONFIG_CRYPTO_BLOWFISH=m
1337CONFIG_CRYPTO_TWOFISH=m
1338CONFIG_CRYPTO_SERPENT=m
1339CONFIG_CRYPTO_AES=m
1340CONFIG_CRYPTO_CAST5=m
1341CONFIG_CRYPTO_CAST6=m
1342CONFIG_CRYPTO_TEA=m
1343CONFIG_CRYPTO_ARC4=m
1344CONFIG_CRYPTO_KHAZAD=m
1345CONFIG_CRYPTO_ANUBIS=m
1346CONFIG_CRYPTO_DEFLATE=m
1347CONFIG_CRYPTO_MICHAEL_MIC=m
1348CONFIG_CRYPTO_CRC32C=m
1349# CONFIG_CRYPTO_TEST is not set
1350
1351#
1352# Hardware crypto devices
1353#
1354
1355#
1356# Library routines
1357#
1358CONFIG_CRC_CCITT=m
1359CONFIG_CRC16=m
1360CONFIG_CRC32=y
1361CONFIG_LIBCRC32C=m
1362CONFIG_ZLIB_INFLATE=m
1363CONFIG_ZLIB_DEFLATE=m
1364CONFIG_TEXTSEARCH=y
1365CONFIG_TEXTSEARCH_KMP=m
1366CONFIG_TEXTSEARCH_BM=m
1367CONFIG_TEXTSEARCH_FSM=m
diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig
index 0f15216cd39d..defc13c37d48 100644
--- a/arch/sh/drivers/dma/Kconfig
+++ b/arch/sh/drivers/dma/Kconfig
@@ -11,6 +11,8 @@ config SH_DMA
11config NR_ONCHIP_DMA_CHANNELS 11config NR_ONCHIP_DMA_CHANNELS
12 depends on SH_DMA 12 depends on SH_DMA
13 int "Number of on-chip DMAC channels" 13 int "Number of on-chip DMAC channels"
14 default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R
15 default "12" if CPU_SUBTYPE_SH7780
14 default "4" 16 default "4"
15 help 17 help
16 This allows you to specify the number of channels that the on-chip 18 This allows you to specify the number of channels that the on-chip
@@ -52,4 +54,3 @@ config DMA_PAGE_OPS_CHANNEL
52 are dual-address capable. 54 are dual-address capable.
53 55
54endmenu 56endmenu
55
diff --git a/arch/sh/drivers/dma/dma-g2.c b/arch/sh/drivers/dma/dma-g2.c
index 0f866f8789f0..9cb070924180 100644
--- a/arch/sh/drivers/dma/dma-g2.c
+++ b/arch/sh/drivers/dma/dma-g2.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * G2 bus DMA support 4 * G2 bus DMA support
5 * 5 *
6 * Copyright (C) 2003, 2004 Paul Mundt 6 * Copyright (C) 2003 - 2006 Paul Mundt
7 * 7 *
8 * This file is subject to the terms and conditions of the GNU General Public 8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive 9 * License. See the file "COPYING" in the main directory of this archive
@@ -13,7 +13,7 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16 16#include <asm/cacheflush.h>
17#include <asm/mach/sysasic.h> 17#include <asm/mach/sysasic.h>
18#include <asm/mach/dma.h> 18#include <asm/mach/dma.h>
19#include <asm/dma.h> 19#include <asm/dma.h>
@@ -47,17 +47,31 @@ struct g2_dma_info {
47 47
48static volatile struct g2_dma_info *g2_dma = (volatile struct g2_dma_info *)0xa05f7800; 48static volatile struct g2_dma_info *g2_dma = (volatile struct g2_dma_info *)0xa05f7800;
49 49
50#define g2_bytes_remaining(i) \
51 ((g2_dma->channel[i].size - \
52 g2_dma->status[i].size) & 0x0fffffff)
53
50static irqreturn_t g2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) 54static irqreturn_t g2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
51{ 55{
52 /* FIXME: Do some meaningful completion work here.. */ 56 int i;
53 return IRQ_HANDLED;
54}
55 57
56static struct irqaction g2_dma_irq = { 58 for (i = 0; i < G2_NR_DMA_CHANNELS; i++) {
57 .name = "g2 DMA handler", 59 if (g2_dma->status[i].status & 0x20000000) {
58 .handler = g2_dma_interrupt, 60 unsigned int bytes = g2_bytes_remaining(i);
59 .flags = IRQF_DISABLED, 61
60}; 62 if (likely(bytes == 0)) {
63 struct dma_info *info = dev_id;
64 struct dma_channel *chan = info->channels + i;
65
66 wake_up(&chan->wait_queue);
67
68 return IRQ_HANDLED;
69 }
70 }
71 }
72
73 return IRQ_NONE;
74}
61 75
62static int g2_enable_dma(struct dma_channel *chan) 76static int g2_enable_dma(struct dma_channel *chan)
63{ 77{
@@ -135,8 +149,14 @@ static int g2_xfer_dma(struct dma_channel *chan)
135 return 0; 149 return 0;
136} 150}
137 151
152static int g2_get_residue(struct dma_channel *chan)
153{
154 return g2_bytes_remaining(chan->chan);
155}
156
138static struct dma_ops g2_dma_ops = { 157static struct dma_ops g2_dma_ops = {
139 .xfer = g2_xfer_dma, 158 .xfer = g2_xfer_dma,
159 .get_residue = g2_get_residue,
140}; 160};
141 161
142static struct dma_info g2_dma_info = { 162static struct dma_info g2_dma_info = {
@@ -148,13 +168,22 @@ static struct dma_info g2_dma_info = {
148 168
149static int __init g2_dma_init(void) 169static int __init g2_dma_init(void)
150{ 170{
151 setup_irq(HW_EVENT_G2_DMA, &g2_dma_irq); 171 int ret;
172
173 ret = request_irq(HW_EVENT_G2_DMA, g2_dma_interrupt, IRQF_DISABLED,
174 "g2 DMA handler", &g2_dma_info);
175 if (unlikely(ret))
176 return -EINVAL;
152 177
153 /* Magic */ 178 /* Magic */
154 g2_dma->wait_state = 27; 179 g2_dma->wait_state = 27;
155 g2_dma->magic = 0x4659404f; 180 g2_dma->magic = 0x4659404f;
156 181
157 return register_dmac(&g2_dma_info); 182 ret = register_dmac(&g2_dma_info);
183 if (unlikely(ret != 0))
184 free_irq(HW_EVENT_G2_DMA, 0);
185
186 return ret;
158} 187}
159 188
160static void __exit g2_dma_exit(void) 189static void __exit g2_dma_exit(void)
@@ -169,4 +198,3 @@ module_exit(g2_dma_exit);
169MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); 198MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
170MODULE_DESCRIPTION("G2 bus DMA driver"); 199MODULE_DESCRIPTION("G2 bus DMA driver");
171MODULE_LICENSE("GPL"); 200MODULE_LICENSE("GPL");
172
diff --git a/arch/sh/drivers/dma/dma-pvr2.c b/arch/sh/drivers/dma/dma-pvr2.c
index 30a580aa7cbd..3b0b0f60bb3c 100644
--- a/arch/sh/drivers/dma/dma-pvr2.c
+++ b/arch/sh/drivers/dma/dma-pvr2.c
@@ -18,8 +18,8 @@
18#include <asm/dma.h> 18#include <asm/dma.h>
19#include <asm/io.h> 19#include <asm/io.h>
20 20
21static unsigned int xfer_complete = 0; 21static unsigned int xfer_complete;
22static int count = 0; 22static int count;
23 23
24static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) 24static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
25{ 25{
@@ -107,4 +107,3 @@ module_exit(pvr2_dma_exit);
107MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>"); 107MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
108MODULE_DESCRIPTION("NEC PowerVR 2 DMA driver"); 108MODULE_DESCRIPTION("NEC PowerVR 2 DMA driver");
109MODULE_LICENSE("GPL"); 109MODULE_LICENSE("GPL");
110
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c
index e028a2d2a4ea..cbbe8bce3d67 100644
--- a/arch/sh/drivers/dma/dma-sh.c
+++ b/arch/sh/drivers/dma/dma-sh.c
@@ -11,14 +11,10 @@
11 * License. See the file "COPYING" in the main directory of this archive 11 * License. See the file "COPYING" in the main directory of this archive
12 * for more details. 12 * for more details.
13 */ 13 */
14
15#include <linux/init.h> 14#include <linux/init.h>
16#include <linux/irq.h>
17#include <linux/interrupt.h> 15#include <linux/interrupt.h>
18#include <linux/module.h> 16#include <linux/module.h>
19#include <asm/dreamcast/dma.h> 17#include <asm/dreamcast/dma.h>
20#include <asm/signal.h>
21#include <asm/irq.h>
22#include <asm/dma.h> 18#include <asm/dma.h>
23#include <asm/io.h> 19#include <asm/io.h>
24#include "dma-sh.h" 20#include "dma-sh.h"
@@ -84,18 +80,23 @@ static irqreturn_t dma_tei(int irq, void *dev_id, struct pt_regs *regs)
84 80
85static int sh_dmac_request_dma(struct dma_channel *chan) 81static int sh_dmac_request_dma(struct dma_channel *chan)
86{ 82{
87 char name[32]; 83 if (unlikely(!chan->flags & DMA_TEI_CAPABLE))
84 return 0;
88 85
89 snprintf(name, sizeof(name), "DMAC Transfer End (Channel %d)", 86 chan->name = kzalloc(32, GFP_KERNEL);
87 if (unlikely(chan->name == NULL))
88 return -ENOMEM;
89 snprintf(chan->name, 32, "DMAC Transfer End (Channel %d)",
90 chan->chan); 90 chan->chan);
91 91
92 return request_irq(get_dmte_irq(chan->chan), dma_tei, 92 return request_irq(get_dmte_irq(chan->chan), dma_tei,
93 IRQF_DISABLED, name, chan); 93 IRQF_DISABLED, chan->name, chan);
94} 94}
95 95
96static void sh_dmac_free_dma(struct dma_channel *chan) 96static void sh_dmac_free_dma(struct dma_channel *chan)
97{ 97{
98 free_irq(get_dmte_irq(chan->chan), chan); 98 free_irq(get_dmte_irq(chan->chan), chan);
99 kfree(chan->name);
99} 100}
100 101
101static void 102static void
@@ -259,7 +260,7 @@ static int __init sh_dmac_init(void)
259#ifdef CONFIG_CPU_SH4 260#ifdef CONFIG_CPU_SH4
260 make_ipr_irq(DMAE_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); 261 make_ipr_irq(DMAE_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY);
261 i = request_irq(DMAE_IRQ, dma_err, IRQF_DISABLED, "DMAC Address Error", 0); 262 i = request_irq(DMAE_IRQ, dma_err, IRQF_DISABLED, "DMAC Address Error", 0);
262 if (i < 0) 263 if (unlikely(i < 0))
263 return i; 264 return i;
264#endif 265#endif
265 266
@@ -274,7 +275,7 @@ static int __init sh_dmac_init(void)
274 * been set. 275 * been set.
275 */ 276 */
276 i = dmaor_reset(); 277 i = dmaor_reset();
277 if (i < 0) 278 if (unlikely(i != 0))
278 return i; 279 return i;
279 280
280 return register_dmac(info); 281 return register_dmac(info);
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile
index 365bc16a4a83..9e00cb8a39e9 100644
--- a/arch/sh/drivers/pci/Makefile
+++ b/arch/sh/drivers/pci/Makefile
@@ -6,7 +6,8 @@ obj-y += pci.o
6obj-$(CONFIG_PCI_AUTO) += pci-auto.o 6obj-$(CONFIG_PCI_AUTO) += pci-auto.o
7 7
8obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += pci-st40.o 8obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += pci-st40.o
9obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o 9obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o
10obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o
10 11
11obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \ 12obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \
12 dma-dreamcast.o 13 dma-dreamcast.o
@@ -14,3 +15,6 @@ obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o
14obj-$(CONFIG_SH_BIGSUR) += ops-bigsur.o 15obj-$(CONFIG_SH_BIGSUR) += ops-bigsur.o
15obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o 16obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o
16obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o 17obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o
18obj-$(CONFIG_SH_R7780RP) += ops-r7780rp.o fixups-r7780rp.o
19obj-$(CONFIG_SH_TITAN) += ops-titan.o
20obj-$(CONFIG_SH_LANDISK) += ops-landisk.o
diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c
index 63b1c6f4b8d2..c0af5f7ef414 100644
--- a/arch/sh/drivers/pci/fixups-dreamcast.c
+++ b/arch/sh/drivers/pci/fixups-dreamcast.c
@@ -4,7 +4,7 @@
4 * PCI fixups for the Sega Dreamcast 4 * PCI fixups for the Sega Dreamcast
5 * 5 *
6 * Copyright (C) 2001, 2002 M. R. Brown 6 * Copyright (C) 2001, 2002 M. R. Brown
7 * Copyright (C) 2002, 2003 Paul Mundt 7 * Copyright (C) 2002, 2003, 2006 Paul Mundt
8 * 8 *
9 * This file originally bore the message (with enclosed-$): 9 * This file originally bore the message (with enclosed-$):
10 * Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp 10 * Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp
@@ -45,36 +45,16 @@ static void __init gapspci_fixup_resources(struct pci_dev *dev)
45 printk("PCI: Failed resource fixup\n"); 45 printk("PCI: Failed resource fixup\n");
46 } 46 }
47} 47}
48
49DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources); 48DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources);
50 49
51void __init pcibios_fixup_bus(struct pci_bus *bus) 50int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin)
52{ 51{
53 /* 52 /*
54 * We don't have any sub bus to fix up, and this is a rather 53 * The interrupt routing semantics here are quite trivial.
55 * stupid place to put general device fixups. Don't do it. 54 *
56 * Use the pcibios_fixups table or suffer the consequences. 55 * We basically only support one interrupt, so we only bother
56 * updating a device's interrupt line with this single shared
57 * interrupt. Keeps routing quite simple, doesn't it?
57 */ 58 */
59 return GAPSPCI_IRQ;
58} 60}
59
60void __init pcibios_fixup_irqs(void)
61{
62 struct pci_dev *dev = 0;
63
64 for_each_pci_dev(dev) {
65 /*
66 * The interrupt routing semantics here are quite trivial.
67 *
68 * We basically only support one interrupt, so we only bother
69 * updating a device's interrupt line with this single shared
70 * interrupt. Keeps routing quite simple, doesn't it?
71 */
72 printk(KERN_NOTICE "PCI: Fixing up IRQ routing for device %s\n",
73 pci_name(dev));
74
75 dev->irq = GAPSPCI_IRQ;
76
77 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
78 }
79}
80
diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c
new file mode 100644
index 000000000000..3e321df65d22
--- /dev/null
+++ b/arch/sh/drivers/pci/fixups-r7780rp.c
@@ -0,0 +1,45 @@
1/*
2 * arch/sh/drivers/pci/fixups-r7780rp.c
3 *
4 * Highlander R7780RP-1 PCI fixups
5 *
6 * Copyright (C) 2003 Lineo uSolutions, Inc.
7 * Copyright (C) 2004 - 2006 Paul Mundt
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#include <linux/pci.h>
14#include "pci-sh4.h"
15#include <asm/io.h>
16
17int pci_fixup_pcic(void)
18{
19 pci_write_reg(0x000043ff, SH4_PCIINTM);
20 pci_write_reg(0x0000380f, SH4_PCIAINTM);
21
22 pci_write_reg(0xfbb00047, SH7780_PCICMD);
23 pci_write_reg(0x00000000, SH7780_PCIIBAR);
24
25 pci_write_reg(0x00011912, SH7780_PCISVID);
26 pci_write_reg(0x08000000, SH7780_PCICSCR0);
27 pci_write_reg(0x0000001b, SH7780_PCICSAR0);
28 pci_write_reg(0xfd000000, SH7780_PCICSCR1);
29 pci_write_reg(0x0000000f, SH7780_PCICSAR1);
30
31 pci_write_reg(0xfd000000, SH7780_PCIMBR0);
32 pci_write_reg(0x00fc0000, SH7780_PCIMBMR0);
33
34#ifdef CONFIG_32BIT
35 pci_write_reg(0xc0000000, SH7780_PCIMBR2);
36 pci_write_reg(0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2);
37#endif
38
39 /* Set IOBR for windows containing area specified in pci.h */
40 pci_write_reg((PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE - 1)),
41 SH7780_PCIIOBR);
42 pci_write_reg(((SH7780_PCI_IO_SIZE-1) & (7<<18)), SH7780_PCIIOBMR);
43
44 return 0;
45}
diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c
index 0c590fc7a081..e72ceb560d5b 100644
--- a/arch/sh/drivers/pci/fixups-rts7751r2d.c
+++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c
@@ -10,8 +10,7 @@
10 * License. See the file "COPYING" in the main directory of this archive 10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details. 11 * for more details.
12 */ 12 */
13#include "pci-sh7751.h" 13#include "pci-sh4.h"
14#include <asm/io.h>
15 14
16#define PCIMCR_MRSET_OFF 0xBFFFFFFF 15#define PCIMCR_MRSET_OFF 0xBFFFFFFF
17#define PCIMCR_RFSH_OFF 0xFFFFFFFB 16#define PCIMCR_RFSH_OFF 0xFFFFFFFB
@@ -22,22 +21,23 @@ int pci_fixup_pcic(void)
22 21
23 bcr1 = inl(SH7751_BCR1); 22 bcr1 = inl(SH7751_BCR1);
24 bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ 23 bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */
25 outl(bcr1, PCI_REG(SH7751_PCIBCR1)); 24 pci_write_reg(bcr1, SH4_PCIBCR1);
26 25
27 /* Enable all interrupts, so we known what to fix */ 26 /* Enable all interrupts, so we known what to fix */
28 outl(0x0000c3ff, PCI_REG(SH7751_PCIINTM)); 27 pci_write_reg(0x0000c3ff, SH4_PCIINTM);
29 outl(0x0000380f, PCI_REG(SH7751_PCIAINTM)); 28 pci_write_reg(0x0000380f, SH4_PCIAINTM);
30 29
31 outl(0xfb900047, PCI_REG(SH7751_PCICONF1)); 30 pci_write_reg(0xfb900047, SH7751_PCICONF1);
32 outl(0xab000001, PCI_REG(SH7751_PCICONF4)); 31 pci_write_reg(0xab000001, SH7751_PCICONF4);
33 32
34 mcr = inl(SH7751_MCR); 33 mcr = inl(SH7751_MCR);
35 mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; 34 mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF;
36 outl(mcr, PCI_REG(SH7751_PCIMCR)); 35 pci_write_reg(mcr, SH4_PCIMCR);
36
37 pci_write_reg(0x0c000000, SH7751_PCICONF5);
38 pci_write_reg(0xd0000000, SH7751_PCICONF6);
39 pci_write_reg(0x0c000000, SH4_PCILAR0);
40 pci_write_reg(0x00000000, SH4_PCILAR1);
37 41
38 outl(0x0c000000, PCI_REG(SH7751_PCICONF5));
39 outl(0xd0000000, PCI_REG(SH7751_PCICONF6));
40 outl(0x0c000000, PCI_REG(SH7751_PCILAR0));
41 outl(0x00000000, PCI_REG(SH7751_PCILAR1));
42 return 0; 42 return 0;
43} 43}
diff --git a/arch/sh/drivers/pci/fixups-sh03.c b/arch/sh/drivers/pci/fixups-sh03.c
index 57ac26c2171f..2e8a18b7ee53 100644
--- a/arch/sh/drivers/pci/fixups-sh03.c
+++ b/arch/sh/drivers/pci/fixups-sh03.c
@@ -3,11 +3,7 @@
3#include <linux/types.h> 3#include <linux/types.h>
4#include <linux/pci.h> 4#include <linux/pci.h>
5 5
6/* 6int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin)
7 * IRQ functions
8 */
9
10int __init pcibios_map_platform_irq(u8 slot, u8 pin, struct pci_dev *dev)
11{ 7{
12 int irq; 8 int irq;
13 9
@@ -17,8 +13,9 @@ int __init pcibios_map_platform_irq(u8 slot, u8 pin, struct pci_dev *dev)
17 case 8: return 5; /* eth1 */ 13 case 8: return 5; /* eth1 */
18 case 6: return 2; /* PCI bridge */ 14 case 6: return 2; /* PCI bridge */
19 default: 15 default:
20 printk("PCI: Bad IRQ mapping request for slot %d\n", slot); 16 printk(KERN_ERR "PCI: Bad IRQ mapping request "
21 return 2; 17 "for slot %d\n", slot);
18 return 2;
22 } 19 }
23 } else { 20 } else {
24 switch (pin) { 21 switch (pin) {
@@ -32,30 +29,3 @@ int __init pcibios_map_platform_irq(u8 slot, u8 pin, struct pci_dev *dev)
32 } 29 }
33 return irq; 30 return irq;
34} 31}
35
36static u8 __init sh03_no_swizzle(struct pci_dev *dev, u8 *pin)
37{
38 /* no swizzling */
39 return PCI_SLOT(dev->devfn);
40}
41
42static int sh03_pci_lookup_irq(struct pci_dev *dev, u8 slot, u8 pin)
43{
44 int irq = -1;
45
46 /* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */
47 irq = pcibios_map_platform_irq(slot, pin, dev);
48 if( irq < 0 ) {
49 pr_debug("PCI: Error mapping IRQ on device %s\n", pci_name(dev));
50 return irq;
51 }
52
53 pr_debug("Setting IRQ for slot %s to %d\n", pci_name(dev), irq);
54
55 return irq;
56}
57
58void __init pcibios_fixup_irqs(void)
59{
60 pci_fixup_irqs(sh03_no_swizzle, sh03_pci_lookup_irq);
61}
diff --git a/arch/sh/drivers/pci/ops-bigsur.c b/arch/sh/drivers/pci/ops-bigsur.c
index ae82c6ca05e5..5da501bd77b5 100644
--- a/arch/sh/drivers/pci/ops-bigsur.c
+++ b/arch/sh/drivers/pci/ops-bigsur.c
@@ -10,15 +10,12 @@
10 * 10 *
11 * PCI initialization for the Hitachi Big Sur Evaluation Board 11 * PCI initialization for the Hitachi Big Sur Evaluation Board
12 */ 12 */
13
14#include <linux/kernel.h> 13#include <linux/kernel.h>
15#include <linux/types.h> 14#include <linux/types.h>
16#include <linux/init.h> 15#include <linux/init.h>
17#include <linux/delay.h>
18#include <linux/pci.h> 16#include <linux/pci.h>
19
20#include <asm/io.h> 17#include <asm/io.h>
21#include "pci-sh7751.h" 18#include "pci-sh4.h"
22#include <asm/bigsur/bigsur.h> 19#include <asm/bigsur/bigsur.h>
23 20
24#define BIGSUR_PCI_IO 0x4000 21#define BIGSUR_PCI_IO 0x4000
@@ -41,11 +38,11 @@ static struct resource sh7751_mem_resource = {
41extern struct pci_ops sh7751_pci_ops; 38extern struct pci_ops sh7751_pci_ops;
42 39
43struct pci_channel board_pci_channels[] = { 40struct pci_channel board_pci_channels[] = {
44 { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, 41 { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
45 { 0, } 42 { 0, }
46}; 43};
47 44
48static struct sh7751_pci_address_map sh7751_pci_map = { 45static struct sh4_pci_address_map sh7751_pci_map = {
49 .window0 = { 46 .window0 = {
50 .base = SH7751_CS3_BASE_ADDR, 47 .base = SH7751_CS3_BASE_ADDR,
51 .size = BIGSUR_LSR0_SIZE, 48 .size = BIGSUR_LSR0_SIZE,
@@ -58,7 +55,7 @@ static struct sh7751_pci_address_map sh7751_pci_map = {
58}; 55};
59 56
60/* 57/*
61 * Initialize the Big Sur PCI interface 58 * Initialize the Big Sur PCI interface
62 * Setup hardware to be Central Funtion 59 * Setup hardware to be Central Funtion
63 * Copy the BSR regs to the PCI interface 60 * Copy the BSR regs to the PCI interface
64 * Setup PCI windows into local RAM 61 * Setup PCI windows into local RAM
@@ -68,15 +65,15 @@ int __init pcibios_init_platform(void)
68 return sh7751_pcic_init(&sh7751_pci_map); 65 return sh7751_pcic_init(&sh7751_pci_map);
69} 66}
70 67
71int pcibios_map_platform_irq(u8 slot, u8 pin) 68int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
72{ 69{
73 /* 70 /*
74 * The Big Sur can be used in a CPCI chassis, but the SH7751 PCI 71 * The Big Sur can be used in a CPCI chassis, but the SH7751 PCI
75 * interface is on the wrong end of the board so that it can also 72 * interface is on the wrong end of the board so that it can also
76 * support a V320 CPI interface chip... Therefor the IRQ mapping is 73 * support a V320 CPI interface chip... Therefor the IRQ mapping is
77 * somewhat use dependent... I'l assume a linear map for now, i.e. 74 * somewhat use dependent... I'l assume a linear map for now, i.e.
78 * INTA=slot0,pin0... INTD=slot3,pin0... 75 * INTA=slot0,pin0... INTD=slot3,pin0...
79 */ 76 */
80 int irq = (slot + pin-1) % 4 + BIGSUR_SH7751_PCI_IRQ_BASE; 77 int irq = (slot + pin-1) % 4 + BIGSUR_SH7751_PCI_IRQ_BASE;
81 78
82 PCIDBG(2, "PCI: Mapping Big Sur IRQ for slot %d, pin %c to irq %d\n", 79 PCIDBG(2, "PCI: Mapping Big Sur IRQ for slot %d, pin %c to irq %d\n",
@@ -84,4 +81,3 @@ int pcibios_map_platform_irq(u8 slot, u8 pin)
84 81
85 return irq; 82 return irq;
86} 83}
87
diff --git a/arch/sh/drivers/pci/ops-landisk.c b/arch/sh/drivers/pci/ops-landisk.c
new file mode 100644
index 000000000000..ada301c21fe7
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-landisk.c
@@ -0,0 +1,68 @@
1/*
2 * arch/sh/drivers/pci/ops-landisk.c
3 *
4 * PCI initialization for the I-O DATA Device, Inc. LANDISK board
5 *
6 * Copyright (C) 2006 kogiidena
7 *
8 * May be copied or modified under the terms of the GNU General Public
9 * License. See linux/COPYING for more information.
10 */
11#include <linux/config.h>
12#include <linux/kernel.h>
13#include <linux/types.h>
14#include <linux/init.h>
15#include <linux/delay.h>
16#include <linux/pci.h>
17#include "pci-sh4.h"
18
19static struct resource sh7751_io_resource = {
20 .name = "SH7751 IO",
21 .start = 0x4000,
22 .end = 0x4000 + SH7751_PCI_IO_SIZE - 1,
23 .flags = IORESOURCE_IO
24};
25
26static struct resource sh7751_mem_resource = {
27 .name = "SH7751 mem",
28 .start = SH7751_PCI_MEMORY_BASE,
29 .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
30 .flags = IORESOURCE_MEM
31};
32
33struct pci_channel board_pci_channels[] = {
34 {&sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0x3ff},
35 {NULL, NULL, NULL, 0, 0},
36};
37
38static struct sh4_pci_address_map sh7751_pci_map = {
39 .window0 = {
40 .base = SH7751_CS3_BASE_ADDR,
41 .size = (64 << 20), /* 64MB */
42 },
43
44 .flags = SH4_PCIC_NO_RESET,
45};
46
47int __init pcibios_init_platform(void)
48{
49 return sh7751_pcic_init(&sh7751_pci_map);
50}
51
52int pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
53{
54 /*
55 * slot0: pin1-4 = irq5,6,7,8
56 * slot1: pin1-4 = irq6,7,8,5
57 * slot2: pin1-4 = irq7,8,5,6
58 * slot3: pin1-4 = irq8,5,6,7
59 */
60 int irq = ((slot + pin - 1) & 0x3) + 5;
61
62 if ((slot | (pin - 1)) > 0x3) {
63 printk("PCI: Bad IRQ mapping request for slot %d pin %c\n",
64 slot, pin - 1 + 'A');
65 return -1;
66 }
67 return irq;
68}
diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c
new file mode 100644
index 000000000000..554d5ed2c586
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-r7780rp.c
@@ -0,0 +1,75 @@
1/*
2 * Author: Ian DaSilva (idasilva@mvista.com)
3 *
4 * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
5 *
6 * May be copied or modified under the terms of the GNU General Public
7 * License. See linux/COPYING for more information.
8 *
9 * PCI initialization for the Renesas SH7780 Highlander R7780RP-1 board
10 */
11
12#include <linux/config.h>
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pci.h>
18#include <asm/r7780rp/r7780rp.h>
19#include <asm/io.h>
20#include "pci-sh4.h"
21
22int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
23{
24 switch (slot) {
25 case 0: return IRQ_PCISLOT1; /* PCI Interrupt #1 */
26 case 1: return IRQ_PCISLOT2; /* PCI Interrupt #2 */
27 case 2: return IRQ_PCISLOT3; /* PCI Interrupt #3 */
28 case 3: return IRQ_PCISLOT4; /* PCI Interrupt E4 */
29 default:
30 printk(KERN_ERR "PCI: Bad IRQ mapping "
31 "request for slot %d, func %d\n", slot, pin-1);
32 return -1;
33 }
34}
35
36static struct resource sh7780_io_resource = {
37 .name = "SH7780_IO",
38 .start = 0x2000,
39 .end = 0x2000 + SH7780_PCI_IO_SIZE - 1,
40 .flags = IORESOURCE_IO
41};
42
43static struct resource sh7780_mem_resource = {
44 .name = "SH7780_mem",
45 .start = SH7780_PCI_MEMORY_BASE,
46 .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1,
47 .flags = IORESOURCE_MEM
48};
49
50extern struct pci_ops sh7780_pci_ops;
51
52struct pci_channel board_pci_channels[] = {
53 { &sh4_pci_ops, &sh7780_io_resource, &sh7780_mem_resource, 0, 0xff },
54 { NULL, NULL, NULL, 0, 0 },
55};
56EXPORT_SYMBOL(board_pci_channels);
57
58static struct sh4_pci_address_map sh7780_pci_map = {
59 .window0 = {
60 .base = SH7780_CS2_BASE_ADDR,
61 .size = 0x04000000,
62 },
63
64 .window1 = {
65 .base = SH7780_CS3_BASE_ADDR,
66 .size = 0x04000000,
67 },
68
69 .flags = SH4_PCIC_NO_RESET,
70};
71
72int __init pcibios_init_platform(void)
73{
74 return sh7780_pcic_init(&sh7780_pci_map);
75}
diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c
index 83171d10141a..88f44e245424 100644
--- a/arch/sh/drivers/pci/ops-rts7751r2d.c
+++ b/arch/sh/drivers/pci/ops-rts7751r2d.c
@@ -17,12 +17,11 @@
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/pci.h> 18#include <linux/pci.h>
19#include <linux/module.h> 19#include <linux/module.h>
20
21#include <asm/io.h>
22#include "pci-sh7751.h"
23#include <asm/rts7751r2d/rts7751r2d.h> 20#include <asm/rts7751r2d/rts7751r2d.h>
21#include <asm/io.h>
22#include "pci-sh4.h"
24 23
25int __init pcibios_map_platform_irq(u8 slot, u8 pin) 24int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
26{ 25{
27 switch (slot) { 26 switch (slot) {
28 case 0: return IRQ_PCISLOT1; /* PCI Extend slot #1 */ 27 case 0: return IRQ_PCISLOT1; /* PCI Extend slot #1 */
@@ -52,12 +51,12 @@ static struct resource sh7751_mem_resource = {
52extern struct pci_ops sh7751_pci_ops; 51extern struct pci_ops sh7751_pci_ops;
53 52
54struct pci_channel board_pci_channels[] = { 53struct pci_channel board_pci_channels[] = {
55 { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, 54 { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
56 { NULL, NULL, NULL, 0, 0 }, 55 { NULL, NULL, NULL, 0, 0 },
57}; 56};
58EXPORT_SYMBOL(board_pci_channels); 57EXPORT_SYMBOL(board_pci_channels);
59 58
60static struct sh7751_pci_address_map sh7751_pci_map = { 59static struct sh4_pci_address_map sh7751_pci_map = {
61 .window0 = { 60 .window0 = {
62 .base = SH7751_CS3_BASE_ADDR, 61 .base = SH7751_CS3_BASE_ADDR,
63 .size = 0x04000000, 62 .size = 0x04000000,
@@ -68,7 +67,7 @@ static struct sh7751_pci_address_map sh7751_pci_map = {
68 .size = 0x00000000, /* Unused */ 67 .size = 0x00000000, /* Unused */
69 }, 68 },
70 69
71 .flags = SH7751_PCIC_NO_RESET, 70 .flags = SH4_PCIC_NO_RESET,
72}; 71};
73 72
74int __init pcibios_init_platform(void) 73int __init pcibios_init_platform(void)
diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c
new file mode 100644
index 000000000000..2d4371009a5e
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-sh4.c
@@ -0,0 +1,164 @@
1/*
2 * Generic SH-4 / SH-4A PCIC operations (SH7751, SH7780).
3 *
4 * Copyright (C) 2002 - 2006 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License v2. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/pci.h>
11#include <asm/addrspace.h>
12#include <asm/io.h>
13#include "pci-sh4.h"
14
15/*
16 * Direct access to PCI hardware...
17 */
18#define CONFIG_CMD(bus, devfn, where) \
19 P1SEGADDR((bus->number << 16) | (devfn << 8) | (where & ~3))
20
21static DEFINE_SPINLOCK(sh4_pci_lock);
22
23/*
24 * Functions for accessing PCI configuration space with type 1 accesses
25 */
26static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn,
27 int where, int size, u32 *val)
28{
29 unsigned long flags;
30 u32 data;
31
32 /*
33 * PCIPDR may only be accessed as 32 bit words,
34 * so we must do byte alignment by hand
35 */
36 spin_lock_irqsave(&sh4_pci_lock, flags);
37 pci_write_reg(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
38 data = pci_read_reg(SH4_PCIPDR);
39 spin_unlock_irqrestore(&sh4_pci_lock, flags);
40
41 switch (size) {
42 case 1:
43 *val = (data >> ((where & 3) << 3)) & 0xff;
44 break;
45 case 2:
46 *val = (data >> ((where & 2) << 3)) & 0xffff;
47 break;
48 case 4:
49 *val = data;
50 break;
51 default:
52 return PCIBIOS_FUNC_NOT_SUPPORTED;
53 }
54
55 return PCIBIOS_SUCCESSFUL;
56}
57
58/*
59 * Since SH4 only does 32bit access we'll have to do a read,
60 * mask,write operation.
61 * We'll allow an odd byte offset, though it should be illegal.
62 */
63static int sh4_pci_write(struct pci_bus *bus, unsigned int devfn,
64 int where, int size, u32 val)
65{
66 unsigned long flags;
67 int shift;
68 u32 data;
69
70 spin_lock_irqsave(&sh4_pci_lock, flags);
71 pci_write_reg(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR);
72 data = pci_read_reg(SH4_PCIPDR);
73 spin_unlock_irqrestore(&sh4_pci_lock, flags);
74
75 switch (size) {
76 case 1:
77 shift = (where & 3) << 3;
78 data &= ~(0xff << shift);
79 data |= ((val & 0xff) << shift);
80 break;
81 case 2:
82 shift = (where & 2) << 3;
83 data &= ~(0xffff << shift);
84 data |= ((val & 0xffff) << shift);
85 break;
86 case 4:
87 data = val;
88 break;
89 default:
90 return PCIBIOS_FUNC_NOT_SUPPORTED;
91 }
92
93 pci_write_reg(data, SH4_PCIPDR);
94
95 return PCIBIOS_SUCCESSFUL;
96}
97
98struct pci_ops sh4_pci_ops = {
99 .read = sh4_pci_read,
100 .write = sh4_pci_write,
101};
102
103/*
104 * Not really related to pci_ops, but it's common and not worth shoving
105 * somewhere else for now..
106 */
107static unsigned int pci_probe = PCI_PROBE_CONF1;
108
109int __init sh4_pci_check_direct(void)
110{
111 /*
112 * Check if configuration works.
113 */
114 if (pci_probe & PCI_PROBE_CONF1) {
115 unsigned int tmp = pci_read_reg(SH4_PCIPAR);
116
117 pci_write_reg(P1SEG, SH4_PCIPAR);
118
119 if (pci_read_reg(SH4_PCIPAR) == P1SEG) {
120 pci_write_reg(tmp, SH4_PCIPAR);
121 printk(KERN_INFO "PCI: Using configuration type 1\n");
122 request_region(PCI_REG(SH4_PCIPAR), 8, "PCI conf1");
123
124 return 0;
125 }
126
127 pci_write_reg(tmp, SH4_PCIPAR);
128 }
129
130 pr_debug("PCI: pci_check_direct failed\n");
131 return -EINVAL;
132}
133
134/* Handle generic fixups */
135static void __init pci_fixup_ide_bases(struct pci_dev *d)
136{
137 int i;
138
139 /*
140 * PCI IDE controllers use non-standard I/O port decoding, respect it.
141 */
142 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
143 return;
144 pr_debug("PCI: IDE base address fixup for %s\n", pci_name(d));
145 for(i = 0; i < 4; i++) {
146 struct resource *r = &d->resource[i];
147
148 if ((r->start & ~0x80) == 0x374) {
149 r->start |= 2;
150 r->end = r->start;
151 }
152 }
153}
154DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
155
156char * __init pcibios_setup(char *str)
157{
158 if (!strcmp(str, "off")) {
159 pci_probe = 0;
160 return NULL;
161 }
162
163 return str;
164}
diff --git a/arch/sh/drivers/pci/ops-snapgear.c b/arch/sh/drivers/pci/ops-snapgear.c
index 3cbd14dd28fe..53dd893d4e54 100644
--- a/arch/sh/drivers/pci/ops-snapgear.c
+++ b/arch/sh/drivers/pci/ops-snapgear.c
@@ -2,7 +2,7 @@
2 * arch/sh/drivers/pci/ops-snapgear.c 2 * arch/sh/drivers/pci/ops-snapgear.c
3 * 3 *
4 * Author: David McCullough <davidm@snapgear.com> 4 * Author: David McCullough <davidm@snapgear.com>
5 * 5 *
6 * Ported to new API by Paul Mundt <lethal@linux-sh.org> 6 * Ported to new API by Paul Mundt <lethal@linux-sh.org>
7 * 7 *
8 * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. 8 * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
@@ -12,15 +12,11 @@
12 * 12 *
13 * PCI initialization for the SnapGear boards 13 * PCI initialization for the SnapGear boards
14 */ 14 */
15
16#include <linux/kernel.h> 15#include <linux/kernel.h>
17#include <linux/types.h> 16#include <linux/types.h>
18#include <linux/init.h> 17#include <linux/init.h>
19#include <linux/delay.h>
20#include <linux/pci.h> 18#include <linux/pci.h>
21 19#include "pci-sh4.h"
22#include <asm/io.h>
23#include "pci-sh7751.h"
24 20
25#define SNAPGEAR_PCI_IO 0x4000 21#define SNAPGEAR_PCI_IO 0x4000
26#define SNAPGEAR_PCI_MEM 0xfd000000 22#define SNAPGEAR_PCI_MEM 0xfd000000
@@ -43,14 +39,12 @@ static struct resource sh7751_mem_resource = {
43 .flags = IORESOURCE_MEM, 39 .flags = IORESOURCE_MEM,
44}; 40};
45 41
46extern struct pci_ops sh7751_pci_ops;
47
48struct pci_channel board_pci_channels[] = { 42struct pci_channel board_pci_channels[] = {
49 { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, 43 { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
50 { 0, } 44 { 0, }
51}; 45};
52 46
53static struct sh7751_pci_address_map sh7751_pci_map = { 47static struct sh4_pci_address_map sh7751_pci_map = {
54 .window0 = { 48 .window0 = {
55 .base = SH7751_CS2_BASE_ADDR, 49 .base = SH7751_CS2_BASE_ADDR,
56 .size = SNAPGEAR_LSR0_SIZE, 50 .size = SNAPGEAR_LSR0_SIZE,
@@ -61,11 +55,11 @@ static struct sh7751_pci_address_map sh7751_pci_map = {
61 .size = SNAPGEAR_LSR1_SIZE, 55 .size = SNAPGEAR_LSR1_SIZE,
62 }, 56 },
63 57
64 .flags = SH7751_PCIC_NO_RESET, 58 .flags = SH4_PCIC_NO_RESET,
65}; 59};
66 60
67/* 61/*
68 * Initialize the SnapGear PCI interface 62 * Initialize the SnapGear PCI interface
69 * Setup hardware to be Central Funtion 63 * Setup hardware to be Central Funtion
70 * Copy the BSR regs to the PCI interface 64 * Copy the BSR regs to the PCI interface
71 * Setup PCI windows into local RAM 65 * Setup PCI windows into local RAM
@@ -75,7 +69,7 @@ int __init pcibios_init_platform(void)
75 return sh7751_pcic_init(&sh7751_pci_map); 69 return sh7751_pcic_init(&sh7751_pci_map);
76} 70}
77 71
78int __init pcibios_map_platform_irq(u8 slot, u8 pin) 72int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
79{ 73{
80 int irq = -1; 74 int irq = -1;
81 75
@@ -98,4 +92,3 @@ void __init pcibios_fixup(void)
98{ 92{
99 /* Nothing to fixup .. */ 93 /* Nothing to fixup .. */
100} 94}
101
diff --git a/arch/sh/drivers/pci/ops-titan.c b/arch/sh/drivers/pci/ops-titan.c
new file mode 100644
index 000000000000..c6097bcd97fd
--- /dev/null
+++ b/arch/sh/drivers/pci/ops-titan.c
@@ -0,0 +1,83 @@
1/*
2 * arch/sh/drivers/pci/ops-titan.c
3 *
4 * Ported to new API by Paul Mundt <lethal@linux-sh.org>
5 *
6 * Modified from ops-snapgear.c written by David McCullough
7 * Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
8 *
9 * May be copied or modified under the terms of the GNU General Public
10 * License. See linux/COPYING for more information.
11 *
12 * PCI initialization for the Titan boards
13 */
14
15#include <linux/config.h>
16#include <linux/kernel.h>
17#include <linux/types.h>
18#include <linux/init.h>
19#include <linux/pci.h>
20#include <asm/io.h>
21#include <asm/titan.h>
22#include "pci-sh4.h"
23
24int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
25{
26 int irq = -1;
27
28 switch (slot) {
29 case 0: irq = TITAN_IRQ_WAN; break; /* eth0 (WAN) */
30 case 1: irq = TITAN_IRQ_LAN; break; /* eth1 (LAN) */
31 case 2: irq = TITAN_IRQ_MPCIA; break; /* mPCI A */
32 case 3: irq = TITAN_IRQ_MPCIB; break; /* mPCI B */
33 case 4: irq = TITAN_IRQ_USB; break; /* USB */
34 default:
35 printk(KERN_INFO "PCI: Bad IRQ mapping "
36 "request for slot %d\n", slot);
37 return -1;
38 }
39
40 printk("PCI: Mapping TITAN IRQ for slot %d, pin %c to irq %d\n",
41 slot, pin - 1 + 'A', irq);
42
43 return irq;
44}
45
46static struct resource sh7751_io_resource = {
47 .name = "SH7751_IO",
48 .start = SH7751_PCI_IO_BASE,
49 .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1,
50 .flags = IORESOURCE_IO
51};
52
53static struct resource sh7751_mem_resource = {
54 .name = "SH7751_mem",
55 .start = SH7751_PCI_MEMORY_BASE,
56 .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1,
57 .flags = IORESOURCE_MEM
58};
59
60struct pci_channel board_pci_channels[] = {
61 { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff },
62 { NULL, NULL, NULL, 0, 0 },
63};
64EXPORT_SYMBOL(board_pci_channels);
65
66static struct sh4_pci_address_map sh7751_pci_map = {
67 .window0 = {
68 .base = SH7751_CS2_BASE_ADDR,
69 .size = SH7751_MEM_REGION_SIZE*2, /* cs2 and cs3 */
70 },
71
72 .window1 = {
73 .base = SH7751_CS2_BASE_ADDR,
74 .size = SH7751_MEM_REGION_SIZE*2,
75 },
76
77 .flags = SH4_PCIC_NO_RESET,
78};
79
80int __init pcibios_init_platform(void)
81{
82 return sh7751_pcic_init(&sh7751_pci_map);
83}
diff --git a/arch/sh/drivers/pci/pci-auto.c b/arch/sh/drivers/pci/pci-auto.c
index 4cef4d1d8c84..ecf16344f94a 100644
--- a/arch/sh/drivers/pci/pci-auto.c
+++ b/arch/sh/drivers/pci/pci-auto.c
@@ -45,11 +45,11 @@
45#include <linux/types.h> 45#include <linux/types.h>
46#include <linux/pci.h> 46#include <linux/pci.h>
47 47
48#undef DEBUG 48#define DEBUG
49#ifdef DEBUG 49#ifdef DEBUG
50#define DBG(x...) printk(x) 50#define DBG(x...) printk(x)
51#else 51#else
52#define DBG(x...) 52#define DBG(x...)
53#endif 53#endif
54 54
55/* 55/*
@@ -102,7 +102,7 @@ static u32 pciauto_upper_iospc;
102static u32 pciauto_lower_memspc; 102static u32 pciauto_lower_memspc;
103static u32 pciauto_upper_memspc; 103static u32 pciauto_upper_memspc;
104 104
105static void __init 105static void __init
106pciauto_setup_bars(struct pci_channel *hose, 106pciauto_setup_bars(struct pci_channel *hose,
107 int top_bus, 107 int top_bus,
108 int current_bus, 108 int current_bus,
@@ -116,7 +116,6 @@ pciauto_setup_bars(struct pci_channel *hose,
116 int found_mem64 = 0; 116 int found_mem64 = 0;
117 117
118 for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4) { 118 for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4) {
119#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
120 u32 bar_addr; 119 u32 bar_addr;
121 120
122 /* Read the old BAR value */ 121 /* Read the old BAR value */
@@ -125,7 +124,6 @@ pciauto_setup_bars(struct pci_channel *hose,
125 pci_devfn, 124 pci_devfn,
126 bar, 125 bar,
127 &bar_addr); 126 &bar_addr);
128#endif
129 127
130 /* Tickle the BAR and get the response */ 128 /* Tickle the BAR and get the response */
131 early_write_config_dword(hose, top_bus, 129 early_write_config_dword(hose, top_bus,
@@ -140,8 +138,7 @@ pciauto_setup_bars(struct pci_channel *hose,
140 bar, 138 bar,
141 &bar_response); 139 &bar_response);
142 140
143#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D) 141 /*
144 /*
145 * Write the old BAR value back out, only update the BAR 142 * Write the old BAR value back out, only update the BAR
146 * if we implicitly want resources to be updated, which 143 * if we implicitly want resources to be updated, which
147 * is done by the generic code further down. -- PFM. 144 * is done by the generic code further down. -- PFM.
@@ -151,7 +148,6 @@ pciauto_setup_bars(struct pci_channel *hose,
151 pci_devfn, 148 pci_devfn,
152 bar, 149 bar,
153 bar_addr); 150 bar_addr);
154#endif
155 151
156 /* If BAR is not implemented go to the next BAR */ 152 /* If BAR is not implemented go to the next BAR */
157 if (!bar_response) 153 if (!bar_response)
@@ -177,7 +173,7 @@ retry:
177 PCI_BASE_ADDRESS_MEM_TYPE_64) 173 PCI_BASE_ADDRESS_MEM_TYPE_64)
178 found_mem64 = 1; 174 found_mem64 = 1;
179 175
180 addr_mask = PCI_BASE_ADDRESS_MEM_MASK; 176 addr_mask = PCI_BASE_ADDRESS_MEM_MASK;
181 upper_limit = &pciauto_upper_memspc; 177 upper_limit = &pciauto_upper_memspc;
182 lower_limit = &pciauto_lower_memspc; 178 lower_limit = &pciauto_lower_memspc;
183 DBG(" Mem"); 179 DBG(" Mem");
@@ -193,22 +189,22 @@ retry:
193 if ((bar_value + bar_size) > *upper_limit) { 189 if ((bar_value + bar_size) > *upper_limit) {
194 if (bar_response & PCI_BASE_ADDRESS_SPACE) { 190 if (bar_response & PCI_BASE_ADDRESS_SPACE) {
195 if (io_resource_inuse->child) { 191 if (io_resource_inuse->child) {
196 io_resource_inuse = 192 io_resource_inuse =
197 io_resource_inuse->child; 193 io_resource_inuse->child;
198 pciauto_lower_iospc = 194 pciauto_lower_iospc =
199 io_resource_inuse->start; 195 io_resource_inuse->start;
200 pciauto_upper_iospc = 196 pciauto_upper_iospc =
201 io_resource_inuse->end + 1; 197 io_resource_inuse->end + 1;
202 goto retry; 198 goto retry;
203 } 199 }
204 200
205 } else { 201 } else {
206 if (mem_resource_inuse->child) { 202 if (mem_resource_inuse->child) {
207 mem_resource_inuse = 203 mem_resource_inuse =
208 mem_resource_inuse->child; 204 mem_resource_inuse->child;
209 pciauto_lower_memspc = 205 pciauto_lower_memspc =
210 mem_resource_inuse->start; 206 mem_resource_inuse->start;
211 pciauto_upper_memspc = 207 pciauto_upper_memspc =
212 mem_resource_inuse->end + 1; 208 mem_resource_inuse->end + 1;
213 goto retry; 209 goto retry;
214 } 210 }
@@ -230,7 +226,7 @@ retry:
230 * If we are a 64-bit decoder then increment to the 226 * If we are a 64-bit decoder then increment to the
231 * upper 32 bits of the bar and force it to locate 227 * upper 32 bits of the bar and force it to locate
232 * in the lower 4GB of memory. 228 * in the lower 4GB of memory.
233 */ 229 */
234 if (found_mem64) { 230 if (found_mem64) {
235 bar += 4; 231 bar += 4;
236 early_write_config_dword(hose, top_bus, 232 early_write_config_dword(hose, top_bus,
@@ -362,7 +358,6 @@ pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose,
362{ 358{
363 u32 temp; 359 u32 temp;
364 360
365#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D)
366 /* 361 /*
367 * [jsun] we always bump up baselines a little, so that if there 362 * [jsun] we always bump up baselines a little, so that if there
368 * nothing behind P2P bridge, we don't wind up overlapping IO/MEM 363 * nothing behind P2P bridge, we don't wind up overlapping IO/MEM
@@ -370,7 +365,6 @@ pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose,
370 */ 365 */
371 pciauto_lower_memspc += 1; 366 pciauto_lower_memspc += 1;
372 pciauto_lower_iospc += 1; 367 pciauto_lower_iospc += 1;
373#endif
374 368
375 /* 369 /*
376 * Configure subordinate bus number. The PCI subsystem 370 * Configure subordinate bus number. The PCI subsystem
@@ -396,11 +390,6 @@ pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose,
396 * configured by this routine to happily live behind a 390 * configured by this routine to happily live behind a
397 * P2P bridge in a system. 391 * P2P bridge in a system.
398 */ 392 */
399#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D)
400 pciauto_lower_memspc += 0x00400000;
401 pciauto_lower_iospc += 0x00004000;
402#endif
403
404 /* Align memory and I/O to 4KB and 4 byte boundaries. */ 393 /* Align memory and I/O to 4KB and 4 byte boundaries. */
405 pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1)) 394 pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1))
406 & ~(0x1000 - 1); 395 & ~(0x1000 - 1);
@@ -433,12 +422,12 @@ pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus)
433 int devfn_stop = 0xff; 422 int devfn_stop = 0xff;
434 423
435 sub_bus = current_bus; 424 sub_bus = current_bus;
436 425
437 if (hose->first_devfn) 426 if (hose->first_devfn)
438 devfn_start = hose->first_devfn; 427 devfn_start = hose->first_devfn;
439 if (hose->last_devfn) 428 if (hose->last_devfn)
440 devfn_stop = hose->last_devfn; 429 devfn_stop = hose->last_devfn;
441 430
442 for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) { 431 for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
443 432
444 if (PCI_FUNC(pci_devfn) && !found_multi) 433 if (PCI_FUNC(pci_devfn) && !found_multi)
@@ -471,9 +460,6 @@ pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus)
471 if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) { 460 if ((pci_class >> 16) == PCI_CLASS_BRIDGE_PCI) {
472 DBG(" Bridge: primary=%.2x, secondary=%.2x\n", 461 DBG(" Bridge: primary=%.2x, secondary=%.2x\n",
473 current_bus, sub_bus + 1); 462 current_bus, sub_bus + 1);
474#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D)
475 pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_1);
476#endif
477 pciauto_prescan_setup_bridge(hose, top_bus, current_bus, 463 pciauto_prescan_setup_bridge(hose, top_bus, current_bus,
478 pci_devfn, sub_bus); 464 pci_devfn, sub_bus);
479 DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", 465 DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n",
@@ -490,10 +476,10 @@ pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus)
490 DBG("PCI Autoconfig: Found CardBus bridge, device %d function %d\n", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn)); 476 DBG("PCI Autoconfig: Found CardBus bridge, device %d function %d\n", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn));
491 /* Place CardBus Socket/ExCA registers */ 477 /* Place CardBus Socket/ExCA registers */
492 pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_0); 478 pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_0);
493 479
494 pciauto_prescan_setup_cardbus_bridge(hose, top_bus, 480 pciauto_prescan_setup_cardbus_bridge(hose, top_bus,
495 current_bus, pci_devfn, sub_bus); 481 current_bus, pci_devfn, sub_bus);
496 482
497 DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", 483 DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n",
498 sub_bus + 1, 484 sub_bus + 1,
499 pciauto_lower_iospc, pciauto_lower_memspc); 485 pciauto_lower_iospc, pciauto_lower_memspc);
diff --git a/arch/sh/drivers/pci/pci-sh4.h b/arch/sh/drivers/pci/pci-sh4.h
new file mode 100644
index 000000000000..5a61d6041f2c
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-sh4.h
@@ -0,0 +1,180 @@
1#ifndef __PCI_SH4_H
2#define __PCI_SH4_H
3
4#ifdef CONFIG_CPU_SUBTYPE_SH7780
5#include "pci-sh7780.h"
6#else
7#include "pci-sh7751.h"
8#endif
9
10#include <asm/io.h>
11
12/* startup values */
13#define PCI_PROBE_BIOS 1
14#define PCI_PROBE_CONF1 2
15#define PCI_PROBE_CONF2 4
16#define PCI_NO_SORT 0x100
17#define PCI_BIOS_SORT 0x200
18#define PCI_NO_CHECKS 0x400
19#define PCI_ASSIGN_ROMS 0x1000
20#define PCI_BIOS_IRQ_SCAN 0x2000
21
22#define SH4_PCICR 0x100 /* PCI Control Register */
23 #define SH4_PCICR_PREFIX 0xA5000000 /* CR prefix for write */
24 #define SH4_PCICR_FTO 0x00000400 /* TRDY/IRDY Enable */
25 #define SH4_PCICR_TRSB 0x00000200 /* Target Read Single */
26 #define SH4_PCICR_BSWP 0x00000100 /* Target Byte Swap */
27 #define SH4_PCICR_PLUP 0x00000080 /* Enable PCI Pullup */
28 #define SH4_PCICR_ARBM 0x00000040 /* PCI Arbitration Mode */
29 #define SH4_PCICR_MD 0x00000030 /* MD9 and MD10 status */
30 #define SH4_PCICR_SERR 0x00000008 /* SERR output assert */
31 #define SH4_PCICR_INTA 0x00000004 /* INTA output assert */
32 #define SH4_PCICR_PRST 0x00000002 /* PCI Reset Assert */
33 #define SH4_PCICR_CFIN 0x00000001 /* Central Fun. Init Done */
34#define SH4_PCILSR0 0x104 /* PCI Local Space Register0 */
35#define SH4_PCILSR1 0x108 /* PCI Local Space Register1 */
36#define SH4_PCILAR0 0x10C /* PCI Local Addr Register1 */
37#define SH4_PCILAR1 0x110 /* PCI Local Addr Register1 */
38#define SH4_PCIINT 0x114 /* PCI Interrupt Register */
39 #define SH4_PCIINT_MLCK 0x00008000 /* Master Lock Error */
40 #define SH4_PCIINT_TABT 0x00004000 /* Target Abort Error */
41 #define SH4_PCIINT_TRET 0x00000200 /* Target Retry Error */
42 #define SH4_PCIINT_MFDE 0x00000100 /* Master Func. Disable Error */
43 #define SH4_PCIINT_PRTY 0x00000080 /* Address Parity Error */
44 #define SH4_PCIINT_SERR 0x00000040 /* SERR Detection Error */
45 #define SH4_PCIINT_TWDP 0x00000020 /* Tgt. Write Parity Error */
46 #define SH4_PCIINT_TRDP 0x00000010 /* Tgt. Read Parity Err Det. */
47 #define SH4_PCIINT_MTABT 0x00000008 /* Master-Tgt. Abort Error */
48 #define SH4_PCIINT_MMABT 0x00000004 /* Master-Master Abort Error */
49 #define SH4_PCIINT_MWPD 0x00000002 /* Master Write PERR Detect */
50 #define SH4_PCIINT_MRPD 0x00000001 /* Master Read PERR Detect */
51#define SH4_PCIINTM 0x118 /* PCI Interrupt Mask */
52#define SH4_PCIALR 0x11C /* Error Address Register */
53#define SH4_PCICLR 0x120 /* Error Command/Data */
54 #define SH4_PCICLR_MPIO 0x80000000
55 #define SH4_PCICLR_MDMA0 0x40000000 /* DMA0 Transfer Error */
56 #define SH4_PCICLR_MDMA1 0x20000000 /* DMA1 Transfer Error */
57 #define SH4_PCICLR_MDMA2 0x10000000 /* DMA2 Transfer Error */
58 #define SH4_PCICLR_MDMA3 0x08000000 /* DMA3 Transfer Error */
59 #define SH4_PCICLR_TGT 0x04000000 /* Target Transfer Error */
60 #define SH4_PCICLR_CMDL 0x0000000F /* PCI Command at Error */
61#define SH4_PCIAINT 0x130 /* Arbiter Interrupt Register */
62 #define SH4_PCIAINT_MBKN 0x00002000 /* Master Broken Interrupt */
63 #define SH4_PCIAINT_TBTO 0x00001000 /* Target Bus Time Out */
64 #define SH4_PCIAINT_MBTO 0x00001000 /* Master Bus Time Out */
65 #define SH4_PCIAINT_TABT 0x00000008 /* Target Abort */
66 #define SH4_PCIAINT_MABT 0x00000004 /* Master Abort */
67 #define SH4_PCIAINT_RDPE 0x00000002 /* Read Data Parity Error */
68 #define SH4_PCIAINT_WDPE 0x00000001 /* Write Data Parity Error */
69#define SH4_PCIAINTM 0x134 /* Arbiter Int. Mask Register */
70#define SH4_PCIBMLR 0x138 /* Error Bus Master Register */
71 #define SH4_PCIBMLR_REQ4 0x00000010 /* REQ4 bus master at error */
72 #define SH4_PCIBMLR_REQ3 0x00000008 /* REQ3 bus master at error */
73 #define SH4_PCIBMLR_REQ2 0x00000004 /* REQ2 bus master at error */
74 #define SH4_PCIBMLR_REQ1 0x00000002 /* REQ1 bus master at error */
75 #define SH4_PCIBMLR_REQ0 0x00000001 /* REQ0 bus master at error */
76#define SH4_PCIDMABT 0x140 /* DMA Transfer Arb. Register */
77 #define SH4_PCIDMABT_RRBN 0x00000001 /* DMA Arbitor Round-Robin */
78#define SH4_PCIDPA0 0x180 /* DMA0 Transfer Addr. */
79#define SH4_PCIDLA0 0x184 /* DMA0 Local Addr. */
80#define SH4_PCIDTC0 0x188 /* DMA0 Transfer Cnt. */
81#define SH4_PCIDCR0 0x18C /* DMA0 Control Register */
82 #define SH4_PCIDCR_ALGN 0x00000600 /* DMA Alignment Mode */
83 #define SH4_PCIDCR_MAST 0x00000100 /* DMA Termination Type */
84 #define SH4_PCIDCR_INTM 0x00000080 /* DMA Interrupt Done Mask*/
85 #define SH4_PCIDCR_INTS 0x00000040 /* DMA Interrupt Done Status */
86 #define SH4_PCIDCR_LHLD 0x00000020 /* Local Address Control */
87 #define SH4_PCIDCR_PHLD 0x00000010 /* PCI Address Control*/
88 #define SH4_PCIDCR_IOSEL 0x00000008 /* PCI Address Space Type */
89 #define SH4_PCIDCR_DIR 0x00000004 /* DMA Transfer Direction */
90 #define SH4_PCIDCR_STOP 0x00000002 /* Force DMA Stop */
91 #define SH4_PCIDCR_STRT 0x00000001 /* DMA Start */
92#define SH4_PCIDPA1 0x190 /* DMA1 Transfer Addr. */
93#define SH4_PCIDLA1 0x194 /* DMA1 Local Addr. */
94#define SH4_PCIDTC1 0x198 /* DMA1 Transfer Cnt. */
95#define SH4_PCIDCR1 0x19C /* DMA1 Control Register */
96#define SH4_PCIDPA2 0x1A0 /* DMA2 Transfer Addr. */
97#define SH4_PCIDLA2 0x1A4 /* DMA2 Local Addr. */
98#define SH4_PCIDTC2 0x1A8 /* DMA2 Transfer Cnt. */
99#define SH4_PCIDCR2 0x1AC /* DMA2 Control Register */
100#define SH4_PCIDPA3 0x1B0 /* DMA3 Transfer Addr. */
101#define SH4_PCIDLA3 0x1B4 /* DMA3 Local Addr. */
102#define SH4_PCIDTC3 0x1B8 /* DMA3 Transfer Cnt. */
103#define SH4_PCIDCR3 0x1BC /* DMA3 Control Register */
104#define SH4_PCIPAR 0x1C0 /* PIO Address Register */
105 #define SH4_PCIPAR_CFGEN 0x80000000 /* Configuration Enable */
106 #define SH4_PCIPAR_BUSNO 0x00FF0000 /* Config. Bus Number */
107 #define SH4_PCIPAR_DEVNO 0x0000FF00 /* Config. Device Number */
108 #define SH4_PCIPAR_REGAD 0x000000FC /* Register Address Number */
109#define SH4_PCIMBR 0x1C4 /* Memory Base Address */
110 #define SH4_PCIMBR_MASK 0xFF000000 /* Memory Space Mask */
111 #define SH4_PCIMBR_LOCK 0x00000001 /* Lock Memory Space */
112#define SH4_PCIIOBR 0x1C8 /* I/O Base Address Register */
113 #define SH4_PCIIOBR_MASK 0xFFFC0000 /* IO Space Mask */
114 #define SH4_PCIIOBR_LOCK 0x00000001 /* Lock IO Space */
115#define SH4_PCIPINT 0x1CC /* Power Mgmnt Int. Register */
116 #define SH4_PCIPINT_D3 0x00000002 /* D3 Pwr Mgmt. Interrupt */
117 #define SH4_PCIPINT_D0 0x00000001 /* D0 Pwr Mgmt. Interrupt */
118#define SH4_PCIPINTM 0x1D0 /* Power Mgmnt Mask Register */
119#define SH4_PCICLKR 0x1D4 /* Clock Ctrl. Register */
120 #define SH4_PCICLKR_PCSTP 0x00000002 /* PCI Clock Stop */
121 #define SH4_PCICLKR_BCSTP 0x00000001 /* BCLK Clock Stop */
122/* For definitions of BCR, MCR see ... */
123#define SH4_PCIBCR1 0x1E0 /* Memory BCR1 Register */
124 #define SH4_PCIMBR0 SH4_PCIBCR1
125#define SH4_PCIBCR2 0x1E4 /* Memory BCR2 Register */
126 #define SH4_PCIMBMR0 SH4_PCIBCR2
127#define SH4_PCIWCR1 0x1E8 /* Wait Control 1 Register */
128#define SH4_PCIWCR2 0x1EC /* Wait Control 2 Register */
129#define SH4_PCIWCR3 0x1F0 /* Wait Control 3 Register */
130 #define SH4_PCIMBR2 SH4_PCIWCR3
131#define SH4_PCIMCR 0x1F4 /* Memory Control Register */
132#define SH4_PCIBCR3 0x1f8 /* Memory BCR3 Register */
133#define SH4_PCIPCTR 0x200 /* Port Control Register */
134 #define SH4_PCIPCTR_P2EN 0x000400000 /* Port 2 Enable */
135 #define SH4_PCIPCTR_P1EN 0x000200000 /* Port 1 Enable */
136 #define SH4_PCIPCTR_P0EN 0x000100000 /* Port 0 Enable */
137 #define SH4_PCIPCTR_P2UP 0x000000020 /* Port2 Pull Up Enable */
138 #define SH4_PCIPCTR_P2IO 0x000000010 /* Port2 Output Enable */
139 #define SH4_PCIPCTR_P1UP 0x000000008 /* Port1 Pull Up Enable */
140 #define SH4_PCIPCTR_P1IO 0x000000004 /* Port1 Output Enable */
141 #define SH4_PCIPCTR_P0UP 0x000000002 /* Port0 Pull Up Enable */
142 #define SH4_PCIPCTR_P0IO 0x000000001 /* Port0 Output Enable */
143#define SH4_PCIPDTR 0x204 /* Port Data Register */
144 #define SH4_PCIPDTR_PB5 0x000000020 /* Port 5 Enable */
145 #define SH4_PCIPDTR_PB4 0x000000010 /* Port 4 Enable */
146 #define SH4_PCIPDTR_PB3 0x000000008 /* Port 3 Enable */
147 #define SH4_PCIPDTR_PB2 0x000000004 /* Port 2 Enable */
148 #define SH4_PCIPDTR_PB1 0x000000002 /* Port 1 Enable */
149 #define SH4_PCIPDTR_PB0 0x000000001 /* Port 0 Enable */
150#define SH4_PCIPDR 0x220 /* Port IO Data Register */
151
152/* Flags */
153#define SH4_PCIC_NO_RESET 0x0001
154
155/* arch/sh/kernel/drivers/pci/ops-sh4.c */
156extern struct pci_ops sh4_pci_ops;
157int sh4_pci_check_direct(void);
158int pci_fixup_pcic(void);
159
160struct sh4_pci_address_space {
161 unsigned long base;
162 unsigned long size;
163};
164
165struct sh4_pci_address_map {
166 struct sh4_pci_address_space window0;
167 struct sh4_pci_address_space window1;
168 unsigned long flags;
169};
170
171static inline void pci_write_reg(unsigned long val, unsigned long reg)
172{
173 outl(val, PCI_REG(reg));
174}
175
176static inline unsigned long pci_read_reg(unsigned long reg)
177{
178 return inl(PCI_REG(reg));
179}
180#endif /* __PCI_SH4_H */
diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c
index 682f3dae305d..dbe837884983 100644
--- a/arch/sh/drivers/pci/pci-sh7751.c
+++ b/arch/sh/drivers/pci/pci-sh7751.c
@@ -15,180 +15,14 @@
15 15
16#undef DEBUG 16#undef DEBUG
17 17
18#include <linux/types.h>
19#include <linux/kernel.h>
20#include <linux/init.h> 18#include <linux/init.h>
21#include <linux/pci.h> 19#include <linux/pci.h>
22#include <linux/sched.h> 20#include <linux/types.h>
23#include <linux/ioport.h>
24#include <linux/errno.h> 21#include <linux/errno.h>
25#include <linux/irq.h>
26#include <linux/delay.h> 22#include <linux/delay.h>
27 23#include "pci-sh4.h"
28#include <asm/machvec.h> 24#include <asm/addrspace.h>
29#include <asm/io.h> 25#include <asm/io.h>
30#include "pci-sh7751.h"
31
32static unsigned int pci_probe = PCI_PROBE_CONF1;
33extern int pci_fixup_pcic(void);
34
35void pcibios_fixup_irqs(void) __attribute__ ((weak));
36
37/*
38 * Direct access to PCI hardware...
39 */
40
41#define CONFIG_CMD(bus, devfn, where) (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3))
42
43/*
44 * Functions for accessing PCI configuration space with type 1 accesses
45 */
46static int sh7751_pci_read(struct pci_bus *bus, unsigned int devfn,
47 int where, int size, u32 *val)
48{
49 unsigned long flags;
50 u32 data;
51
52 /*
53 * PCIPDR may only be accessed as 32 bit words,
54 * so we must do byte alignment by hand
55 */
56 local_irq_save(flags);
57 outl(CONFIG_CMD(bus,devfn,where), PCI_REG(SH7751_PCIPAR));
58 data = inl(PCI_REG(SH7751_PCIPDR));
59 local_irq_restore(flags);
60
61 switch (size) {
62 case 1:
63 *val = (data >> ((where & 3) << 3)) & 0xff;
64 break;
65 case 2:
66 *val = (data >> ((where & 2) << 3)) & 0xffff;
67 break;
68 case 4:
69 *val = data;
70 break;
71 default:
72 return PCIBIOS_FUNC_NOT_SUPPORTED;
73 }
74
75 return PCIBIOS_SUCCESSFUL;
76}
77
78/*
79 * Since SH7751 only does 32bit access we'll have to do a read,
80 * mask,write operation.
81 * We'll allow an odd byte offset, though it should be illegal.
82 */
83static int sh7751_pci_write(struct pci_bus *bus, unsigned int devfn,
84 int where, int size, u32 val)
85{
86 unsigned long flags;
87 int shift;
88 u32 data;
89
90 local_irq_save(flags);
91 outl(CONFIG_CMD(bus,devfn,where), PCI_REG(SH7751_PCIPAR));
92 data = inl(PCI_REG(SH7751_PCIPDR));
93 local_irq_restore(flags);
94
95 switch (size) {
96 case 1:
97 shift = (where & 3) << 3;
98 data &= ~(0xff << shift);
99 data |= ((val & 0xff) << shift);
100 break;
101 case 2:
102 shift = (where & 2) << 3;
103 data &= ~(0xffff << shift);
104 data |= ((val & 0xffff) << shift);
105 break;
106 case 4:
107 data = val;
108 break;
109 default:
110 return PCIBIOS_FUNC_NOT_SUPPORTED;
111 }
112
113 outl(data, PCI_REG(SH7751_PCIPDR));
114
115 return PCIBIOS_SUCCESSFUL;
116}
117
118#undef CONFIG_CMD
119
120struct pci_ops sh7751_pci_ops = {
121 .read = sh7751_pci_read,
122 .write = sh7751_pci_write,
123};
124
125static int __init pci_check_direct(void)
126{
127 unsigned int tmp, id;
128
129 /* check for SH7751/SH7751R hardware */
130 id = inl(SH7751_PCIREG_BASE+SH7751_PCICONF0);
131 if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) &&
132 id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) {
133 pr_debug("PCI: This is not an SH7751(R) (%x)\n", id);
134 return -ENODEV;
135 }
136
137 /*
138 * Check if configuration works.
139 */
140 if (pci_probe & PCI_PROBE_CONF1) {
141 tmp = inl (PCI_REG(SH7751_PCIPAR));
142 outl (0x80000000, PCI_REG(SH7751_PCIPAR));
143 if (inl (PCI_REG(SH7751_PCIPAR)) == 0x80000000) {
144 outl (tmp, PCI_REG(SH7751_PCIPAR));
145 printk(KERN_INFO "PCI: Using configuration type 1\n");
146 request_region(PCI_REG(SH7751_PCIPAR), 8, "PCI conf1");
147 return 0;
148 }
149 outl (tmp, PCI_REG(SH7751_PCIPAR));
150 }
151
152 pr_debug("PCI: pci_check_direct failed\n");
153 return -EINVAL;
154}
155
156/***************************************************************************************/
157
158/*
159 * Handle bus scanning and fixups ....
160 */
161
162static void __init pci_fixup_ide_bases(struct pci_dev *d)
163{
164 int i;
165
166 /*
167 * PCI IDE controllers use non-standard I/O port decoding, respect it.
168 */
169 if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
170 return;
171 pr_debug("PCI: IDE base address fixup for %s\n", pci_name(d));
172 for(i=0; i<4; i++) {
173 struct resource *r = &d->resource[i];
174 if ((r->start & ~0x80) == 0x374) {
175 r->start |= 2;
176 r->end = r->start;
177 }
178 }
179}
180
181DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases);
182
183/*
184 * Called after each bus is probed, but before its children
185 * are examined.
186 */
187
188void __init pcibios_fixup_bus(struct pci_bus *b)
189{
190 pci_read_bridge_bases(b);
191}
192 26
193/* 27/*
194 * Initialization. Try all known PCI access methods. Note that we support 28 * Initialization. Try all known PCI access methods. Note that we support
@@ -196,25 +30,29 @@ void __init pcibios_fixup_bus(struct pci_bus *b)
196 * to access config space. 30 * to access config space.
197 * 31 *
198 * Note that the platform specific initialization (BSC registers, and memory 32 * Note that the platform specific initialization (BSC registers, and memory
199 * space mapping) will be called via the machine vectors (sh_mv.mv_pci_init()) if it 33 * space mapping) will be called via the platform defined function
200 * exitst and via the platform defined function pcibios_init_platform(). 34 * pcibios_init_platform().
201 * See pci_bigsur.c for implementation;
202 *
203 * The BIOS version of the pci functions is not yet implemented but it is left
204 * in for completeness. Currently an error will be genereated at compile time.
205 */ 35 */
206
207static int __init sh7751_pci_init(void) 36static int __init sh7751_pci_init(void)
208{ 37{
38 unsigned int id;
209 int ret; 39 int ret;
210 40
211 pr_debug("PCI: Starting intialization.\n"); 41 pr_debug("PCI: Starting intialization.\n");
212 if ((ret = pci_check_direct()) != 0) 42
43 /* check for SH7751/SH7751R hardware */
44 id = pci_read_reg(SH7751_PCICONF0);
45 if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) &&
46 id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) {
47 pr_debug("PCI: This is not an SH7751(R) (%x)\n", id);
48 return -ENODEV;
49 }
50
51 if ((ret = sh4_pci_check_direct()) != 0)
213 return ret; 52 return ret;
214 53
215 return pcibios_init_platform(); 54 return pcibios_init_platform();
216} 55}
217
218subsys_initcall(sh7751_pci_init); 56subsys_initcall(sh7751_pci_init);
219 57
220static int __init __area_sdram_check(unsigned int area) 58static int __init __area_sdram_check(unsigned int area)
@@ -223,26 +61,26 @@ static int __init __area_sdram_check(unsigned int area)
223 61
224 word = inl(SH7751_BCR1); 62 word = inl(SH7751_BCR1);
225 /* check BCR for SDRAM in area */ 63 /* check BCR for SDRAM in area */
226 if(((word >> area) & 1) == 0) { 64 if (((word >> area) & 1) == 0) {
227 printk("PCI: Area %d is not configured for SDRAM. BCR1=0x%x\n", 65 printk("PCI: Area %d is not configured for SDRAM. BCR1=0x%x\n",
228 area, word); 66 area, word);
229 return 0; 67 return 0;
230 } 68 }
231 outl(word, PCI_REG(SH7751_PCIBCR1)); 69 pci_write_reg(word, SH4_PCIBCR1);
232 70
233 word = (u16)inw(SH7751_BCR2); 71 word = (u16)inw(SH7751_BCR2);
234 /* check BCR2 for 32bit SDRAM interface*/ 72 /* check BCR2 for 32bit SDRAM interface*/
235 if(((word >> (area << 1)) & 0x3) != 0x3) { 73 if (((word >> (area << 1)) & 0x3) != 0x3) {
236 printk("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%x\n", 74 printk("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%x\n",
237 area, word); 75 area, word);
238 return 0; 76 return 0;
239 } 77 }
240 outl(word, PCI_REG(SH7751_PCIBCR2)); 78 pci_write_reg(word, SH4_PCIBCR2);
241 79
242 return 1; 80 return 1;
243} 81}
244 82
245int __init sh7751_pcic_init(struct sh7751_pci_address_map *map) 83int __init sh7751_pcic_init(struct sh4_pci_address_map *map)
246{ 84{
247 u32 reg; 85 u32 reg;
248 u32 word; 86 u32 word;
@@ -251,39 +89,39 @@ int __init sh7751_pcic_init(struct sh7751_pci_address_map *map)
251 reg = inl(SH7751_BCR1); 89 reg = inl(SH7751_BCR1);
252 reg |= 0x80000; 90 reg |= 0x80000;
253 outl(reg, SH7751_BCR1); 91 outl(reg, SH7751_BCR1);
254 92
255 /* Turn the clocks back on (not done in reset)*/ 93 /* Turn the clocks back on (not done in reset)*/
256 outl(0, PCI_REG(SH7751_PCICLKR)); 94 pci_write_reg(0, SH4_PCICLKR);
257 /* Clear Powerdown IRQ's (not done in reset) */ 95 /* Clear Powerdown IRQ's (not done in reset) */
258 word = SH7751_PCIPINT_D3 | SH7751_PCIPINT_D0; 96 word = SH4_PCIPINT_D3 | SH4_PCIPINT_D0;
259 outl(word, PCI_REG(SH7751_PCIPINT)); 97 pci_write_reg(word, SH4_PCIPINT);
260 98
261 /* 99 /*
262 * This code is unused for some boards as it is done in the 100 * This code is unused for some boards as it is done in the
263 * bootloader and doing it here means the MAC addresses loaded 101 * bootloader and doing it here means the MAC addresses loaded
264 * by the bootloader get lost. 102 * by the bootloader get lost.
265 */ 103 */
266 if (!(map->flags & SH7751_PCIC_NO_RESET)) { 104 if (!(map->flags & SH4_PCIC_NO_RESET)) {
267 /* toggle PCI reset pin */ 105 /* toggle PCI reset pin */
268 word = SH7751_PCICR_PREFIX | SH7751_PCICR_PRST; 106 word = SH4_PCICR_PREFIX | SH4_PCICR_PRST;
269 outl(word,PCI_REG(SH7751_PCICR)); 107 pci_write_reg(word, SH4_PCICR);
270 /* Wait for a long time... not 1 sec. but long enough */ 108 /* Wait for a long time... not 1 sec. but long enough */
271 mdelay(100); 109 mdelay(100);
272 word = SH7751_PCICR_PREFIX; 110 word = SH4_PCICR_PREFIX;
273 outl(word,PCI_REG(SH7751_PCICR)); 111 pci_write_reg(word, SH4_PCICR);
274 } 112 }
275 113
276 /* set the command/status bits to: 114 /* set the command/status bits to:
277 * Wait Cycle Control + Parity Enable + Bus Master + 115 * Wait Cycle Control + Parity Enable + Bus Master +
278 * Mem space enable 116 * Mem space enable
279 */ 117 */
280 word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER | 118 word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER |
281 SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES; 119 SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES;
282 outl(word, PCI_REG(SH7751_PCICONF1)); 120 pci_write_reg(word, SH7751_PCICONF1);
283 121
284 /* define this host as the host bridge */ 122 /* define this host as the host bridge */
285 word = SH7751_PCI_HOST_BRIDGE << 24; 123 word = PCI_BASE_CLASS_BRIDGE << 24;
286 outl(word, PCI_REG(SH7751_PCICONF2)); 124 pci_write_reg(word, SH7751_PCICONF2);
287 125
288 /* Set IO and Mem windows to local address 126 /* Set IO and Mem windows to local address
289 * Make PCI and local address the same for easy 1 to 1 mapping 127 * Make PCI and local address the same for easy 1 to 1 mapping
@@ -291,46 +129,49 @@ int __init sh7751_pcic_init(struct sh7751_pci_address_map *map)
291 * Window1 = map->window1.size @ cached area base = SDRAM 129 * Window1 = map->window1.size @ cached area base = SDRAM
292 */ 130 */
293 word = map->window0.size - 1; 131 word = map->window0.size - 1;
294 outl(word, PCI_REG(SH7751_PCILSR0)); 132 pci_write_reg(word, SH4_PCILSR0);
295 word = map->window1.size - 1; 133 word = map->window1.size - 1;
296 outl(word, PCI_REG(SH7751_PCILSR1)); 134 pci_write_reg(word, SH4_PCILSR1);
297 /* Set the values on window 0 PCI config registers */ 135 /* Set the values on window 0 PCI config registers */
298 word = P2SEGADDR(map->window0.base); 136 word = P2SEGADDR(map->window0.base);
299 outl(word, PCI_REG(SH7751_PCILAR0)); 137 pci_write_reg(word, SH4_PCILAR0);
300 outl(word, PCI_REG(SH7751_PCICONF5)); 138 pci_write_reg(word, SH7751_PCICONF5);
301 /* Set the values on window 1 PCI config registers */ 139 /* Set the values on window 1 PCI config registers */
302 word = PHYSADDR(map->window1.base); 140 word = PHYSADDR(map->window1.base);
303 outl(word, PCI_REG(SH7751_PCILAR1)); 141 pci_write_reg(word, SH4_PCILAR1);
304 outl(word, PCI_REG(SH7751_PCICONF6)); 142 pci_write_reg(word, SH7751_PCICONF6);
305 143
306 /* Set the local 16MB PCI memory space window to 144 /* Set the local 16MB PCI memory space window to
307 * the lowest PCI mapped address 145 * the lowest PCI mapped address
308 */ 146 */
309 word = PCIBIOS_MIN_MEM & SH7751_PCIMBR_MASK; 147 word = PCIBIOS_MIN_MEM & SH4_PCIMBR_MASK;
310 PCIDBG(2,"PCI: Setting upper bits of Memory window to 0x%x\n", word); 148 pr_debug("PCI: Setting upper bits of Memory window to 0x%x\n", word);
311 outl(word , PCI_REG(SH7751_PCIMBR)); 149 pci_write_reg(word , SH4_PCIMBR);
312 150
313 /* Map IO space into PCI IO window 151 /* Map IO space into PCI IO window
314 * The IO window is 64K-PCIBIOS_MIN_IO in size 152 * The IO window is 64K-PCIBIOS_MIN_IO in size
315 * IO addresses will be translated to the 153 * IO addresses will be translated to the
316 * PCI IO window base address 154 * PCI IO window base address
317 */ 155 */
318 PCIDBG(3,"PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", PCIBIOS_MIN_IO, 156 pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n",
319 (64*1024), SH7751_PCI_IO_BASE+PCIBIOS_MIN_IO); 157 PCIBIOS_MIN_IO, (64 << 10),
158 SH4_PCI_IO_BASE + PCIBIOS_MIN_IO);
320 159
321 /* 160 /*
322 * XXX: For now, leave this board-specific. In the event we have other 161 * XXX: For now, leave this board-specific. In the event we have other
323 * boards that need to do similar work, this can be wrapped. 162 * boards that need to do similar work, this can be wrapped.
324 */ 163 */
325#ifdef CONFIG_SH_BIGSUR 164#ifdef CONFIG_SH_BIGSUR
326 bigsur_port_map(PCIBIOS_MIN_IO, (64*1024), SH7751_PCI_IO_BASE+PCIBIOS_MIN_IO,0); 165 bigsur_port_map(PCIBIOS_MIN_IO, (64 << 10),
166 SH4_PCI_IO_BASE + PCIBIOS_MIN_IO, 0);
327#endif 167#endif
328 168
329 /* Make sure the MSB's of IO window are set to access PCI space correctly */ 169 /* Make sure the MSB's of IO window are set to access PCI space
330 word = PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK; 170 * correctly */
331 PCIDBG(2,"PCI: Setting upper bits of IO window to 0x%x\n", word); 171 word = PCIBIOS_MIN_IO & SH4_PCIIOBR_MASK;
332 outl(word, PCI_REG(SH7751_PCIIOBR)); 172 pr_debug("PCI: Setting upper bits of IO window to 0x%x\n", word);
333 173 pci_write_reg(word, SH4_PCIIOBR);
174
334 /* Set PCI WCRx, BCRx's, copy from BSC locations */ 175 /* Set PCI WCRx, BCRx's, copy from BSC locations */
335 176
336 /* check BCR for SDRAM in specified area */ 177 /* check BCR for SDRAM in specified area */
@@ -349,13 +190,13 @@ int __init sh7751_pcic_init(struct sh7751_pci_address_map *map)
349 190
350 /* configure the wait control registers */ 191 /* configure the wait control registers */
351 word = inl(SH7751_WCR1); 192 word = inl(SH7751_WCR1);
352 outl(word, PCI_REG(SH7751_PCIWCR1)); 193 pci_write_reg(word, SH4_PCIWCR1);
353 word = inl(SH7751_WCR2); 194 word = inl(SH7751_WCR2);
354 outl(word, PCI_REG(SH7751_PCIWCR2)); 195 pci_write_reg(word, SH4_PCIWCR2);
355 word = inl(SH7751_WCR3); 196 word = inl(SH7751_WCR3);
356 outl(word, PCI_REG(SH7751_PCIWCR3)); 197 pci_write_reg(word, SH4_PCIWCR3);
357 word = inl(SH7751_MCR); 198 word = inl(SH7751_MCR);
358 outl(word, PCI_REG(SH7751_PCIMCR)); 199 pci_write_reg(word, SH4_PCIMCR);
359 200
360 /* NOTE: I'm ignoring the PCI error IRQs for now.. 201 /* NOTE: I'm ignoring the PCI error IRQs for now..
361 * TODO: add support for the internal error interrupts and 202 * TODO: add support for the internal error interrupts and
@@ -368,49 +209,8 @@ int __init sh7751_pcic_init(struct sh7751_pci_address_map *map)
368 209
369 /* SH7751 init done, set central function init complete */ 210 /* SH7751 init done, set central function init complete */
370 /* use round robin mode to stop a device starving/overruning */ 211 /* use round robin mode to stop a device starving/overruning */
371 word = SH7751_PCICR_PREFIX | SH7751_PCICR_CFIN | SH7751_PCICR_ARBM; 212 word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM;
372 outl(word,PCI_REG(SH7751_PCICR)); 213 pci_write_reg(word, SH4_PCICR);
373 214
374 return 1; 215 return 1;
375} 216}
376
377char * __init pcibios_setup(char *str)
378{
379 if (!strcmp(str, "off")) {
380 pci_probe = 0;
381 return NULL;
382 }
383
384 return str;
385}
386
387/*
388 * IRQ functions
389 */
390static u8 __init sh7751_no_swizzle(struct pci_dev *dev, u8 *pin)
391{
392 /* no swizzling */
393 return PCI_SLOT(dev->devfn);
394}
395
396static int sh7751_pci_lookup_irq(struct pci_dev *dev, u8 slot, u8 pin)
397{
398 int irq = -1;
399
400 /* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */
401 irq = pcibios_map_platform_irq(slot,pin);
402 if( irq < 0 ) {
403 pr_debug("PCI: Error mapping IRQ on device %s\n", pci_name(dev));
404 return irq;
405 }
406
407 pr_debug("Setting IRQ for slot %s to %d\n", pci_name(dev), irq);
408
409 return irq;
410}
411
412void __init pcibios_fixup_irqs(void)
413{
414 pci_fixup_irqs(sh7751_no_swizzle, sh7751_pci_lookup_irq);
415}
416
diff --git a/arch/sh/drivers/pci/pci-sh7751.h b/arch/sh/drivers/pci/pci-sh7751.h
index 1fee5cae10d1..68e3cb5e6bec 100644
--- a/arch/sh/drivers/pci/pci-sh7751.h
+++ b/arch/sh/drivers/pci/pci-sh7751.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * Dustin McIntire (dustin@sensoria.com) (c) 2001 4 * Dustin McIntire (dustin@sensoria.com) (c) 2001
5 * Paul Mundt (lethal@linux-sh.org) (c) 2003 5 * Paul Mundt (lethal@linux-sh.org) (c) 2003
6 * 6 *
7 * May be copied or modified under the terms of the GNU General Public 7 * May be copied or modified under the terms of the GNU General Public
8 * License. See linux/COPYING for more information. 8 * License. See linux/COPYING for more information.
9 * 9 *
@@ -12,28 +12,6 @@
12#ifndef _PCI_SH7751_H_ 12#ifndef _PCI_SH7751_H_
13#define _PCI_SH7751_H_ 13#define _PCI_SH7751_H_
14 14
15#include <linux/pci.h>
16
17/* set debug level 4=verbose...1=terse */
18//#define DEBUG_PCI 3
19#undef DEBUG_PCI
20
21#ifdef DEBUG_PCI
22#define PCIDBG(n, x...) { if(DEBUG_PCI>=n) printk(x); }
23#else
24#define PCIDBG(n, x...)
25#endif
26
27/* startup values */
28#define PCI_PROBE_BIOS 1
29#define PCI_PROBE_CONF1 2
30#define PCI_PROBE_CONF2 4
31#define PCI_NO_SORT 0x100
32#define PCI_BIOS_SORT 0x200
33#define PCI_NO_CHECKS 0x400
34#define PCI_ASSIGN_ROMS 0x1000
35#define PCI_BIOS_IRQ_SCAN 0x2000
36
37/* Platform Specific Values */ 15/* Platform Specific Values */
38#define SH7751_VENDOR_ID 0x1054 16#define SH7751_VENDOR_ID 0x1054
39#define SH7751_DEVICE_ID 0x3505 17#define SH7751_DEVICE_ID 0x3505
@@ -128,131 +106,6 @@
128 #define SH7751_PCICONF17_PMEN 0x00010000 /* PME Enable */ 106 #define SH7751_PCICONF17_PMEN 0x00010000 /* PME Enable */
129 #define SH7751_PCICONF17_PWST 0x00000003 /* Power State */ 107 #define SH7751_PCICONF17_PWST 0x00000003 /* Power State */
130/* SH7715 Internal PCI Registers */ 108/* SH7715 Internal PCI Registers */
131#define SH7751_PCICR 0x100 /* PCI Control Register */
132 #define SH7751_PCICR_PREFIX 0xA5000000 /* CR prefix for write */
133 #define SH7751_PCICR_TRSB 0x00000200 /* Target Read Single */
134 #define SH7751_PCICR_BSWP 0x00000100 /* Target Byte Swap */
135 #define SH7751_PCICR_PLUP 0x00000080 /* Enable PCI Pullup */
136 #define SH7751_PCICR_ARBM 0x00000040 /* PCI Arbitration Mode */
137 #define SH7751_PCICR_MD 0x00000030 /* MD9 and MD10 status */
138 #define SH7751_PCICR_SERR 0x00000008 /* SERR output assert */
139 #define SH7751_PCICR_INTA 0x00000004 /* INTA output assert */
140 #define SH7751_PCICR_PRST 0x00000002 /* PCI Reset Assert */
141 #define SH7751_PCICR_CFIN 0x00000001 /* Central Fun. Init Done */
142#define SH7751_PCILSR0 0x104 /* PCI Local Space Register0 */
143#define SH7751_PCILSR1 0x108 /* PCI Local Space Register1 */
144#define SH7751_PCILAR0 0x10C /* PCI Local Address Register1 */
145#define SH7751_PCILAR1 0x110 /* PCI Local Address Register1 */
146#define SH7751_PCIINT 0x114 /* PCI Interrupt Register */
147 #define SH7751_PCIINT_MLCK 0x00008000 /* Master Lock Error */
148 #define SH7751_PCIINT_TABT 0x00004000 /* Target Abort Error */
149 #define SH7751_PCIINT_TRET 0x00000200 /* Target Retry Error */
150 #define SH7751_PCIINT_MFDE 0x00000100 /* Master Func. Disable Error */
151 #define SH7751_PCIINT_PRTY 0x00000080 /* Address Parity Error */
152 #define SH7751_PCIINT_SERR 0x00000040 /* SERR Detection Error */
153 #define SH7751_PCIINT_TWDP 0x00000020 /* Tgt. Write Parity Error */
154 #define SH7751_PCIINT_TRDP 0x00000010 /* Tgt. Read Parity Error Det. */
155 #define SH7751_PCIINT_MTABT 0x00000008 /* Master-Tgt. Abort Error */
156 #define SH7751_PCIINT_MMABT 0x00000004 /* Master-Master Abort Error */
157 #define SH7751_PCIINT_MWPD 0x00000002 /* Master Write PERR Detect */
158 #define SH7751_PCIINT_MRPD 0x00000002 /* Master Read PERR Detect */
159#define SH7751_PCIINTM 0x118 /* PCI Interrupt Mask Register */
160#define SH7751_PCIALR 0x11C /* Error Address Register */
161#define SH7751_PCICLR 0x120 /* Error Command/Data Register */
162 #define SH7751_PCICLR_MPIO 0x80000000 /* Error Command/Data Register */
163 #define SH7751_PCICLR_MDMA0 0x40000000 /* DMA0 Transfer Error */
164 #define SH7751_PCICLR_MDMA1 0x20000000 /* DMA1 Transfer Error */
165 #define SH7751_PCICLR_MDMA2 0x10000000 /* DMA2 Transfer Error */
166 #define SH7751_PCICLR_MDMA3 0x08000000 /* DMA3 Transfer Error */
167 #define SH7751_PCICLR_TGT 0x04000000 /* Target Transfer Error */
168 #define SH7751_PCICLR_CMDL 0x0000000F /* PCI Command at Error */
169#define SH7751_PCIAINT 0x130 /* Arbiter Interrupt Register */
170 #define SH7751_PCIAINT_MBKN 0x00002000 /* Master Broken Interrupt */
171 #define SH7751_PCIAINT_TBTO 0x00001000 /* Target Bus Time Out */
172 #define SH7751_PCIAINT_MBTO 0x00001000 /* Master Bus Time Out */
173 #define SH7751_PCIAINT_TABT 0x00000008 /* Target Abort */
174 #define SH7751_PCIAINT_MABT 0x00000004 /* Master Abort */
175 #define SH7751_PCIAINT_RDPE 0x00000002 /* Read Data Parity Error */
176 #define SH7751_PCIAINT_WDPE 0x00000002 /* Write Data Parity Error */
177#define SH7751_PCIAINTM 0x134 /* Arbiter Int. Mask Register */
178#define SH7751_PCIBMLR 0x138 /* Error Bus Master Register */
179 #define SH7751_PCIBMLR_REQ4 0x00000010 /* REQ4 bus master at error */
180 #define SH7751_PCIBMLR_REQ3 0x00000008 /* REQ3 bus master at error */
181 #define SH7751_PCIBMLR_REQ2 0x00000004 /* REQ2 bus master at error */
182 #define SH7751_PCIBMLR_REQ1 0x00000002 /* REQ1 bus master at error */
183 #define SH7751_PCIBMLR_REQ0 0x00000001 /* REQ0 bus master at error */
184#define SH7751_PCIDMABT 0x140 /* DMA Transfer Arb. Register */
185 #define SH7751_PCIDMABT_RRBN 0x00000001 /* DMA Arbitor Round-Robin */
186#define SH7751_PCIDPA0 0x180 /* DMA0 Transfer Addr. Register */
187#define SH7751_PCIDLA0 0x184 /* DMA0 Local Addr. Register */
188#define SH7751_PCIDTC0 0x188 /* DMA0 Transfer Cnt. Register */
189#define SH7751_PCIDCR0 0x18C /* DMA0 Control Register */
190 #define SH7751_PCIDCR_ALGN 0x00000600 /* DMA Alignment Mode */
191 #define SH7751_PCIDCR_MAST 0x00000100 /* DMA Termination Type */
192 #define SH7751_PCIDCR_INTM 0x00000080 /* DMA Interrupt Done Mask*/
193 #define SH7751_PCIDCR_INTS 0x00000040 /* DMA Interrupt Done Status */
194 #define SH7751_PCIDCR_LHLD 0x00000020 /* Local Address Control */
195 #define SH7751_PCIDCR_PHLD 0x00000010 /* PCI Address Control*/
196 #define SH7751_PCIDCR_IOSEL 0x00000008 /* PCI Address Space Type */
197 #define SH7751_PCIDCR_DIR 0x00000004 /* DMA Transfer Direction */
198 #define SH7751_PCIDCR_STOP 0x00000002 /* Force DMA Stop */
199 #define SH7751_PCIDCR_STRT 0x00000001 /* DMA Start */
200#define SH7751_PCIDPA1 0x190 /* DMA1 Transfer Addr. Register */
201#define SH7751_PCIDLA1 0x194 /* DMA1 Local Addr. Register */
202#define SH7751_PCIDTC1 0x198 /* DMA1 Transfer Cnt. Register */
203#define SH7751_PCIDCR1 0x19C /* DMA1 Control Register */
204#define SH7751_PCIDPA2 0x1A0 /* DMA2 Transfer Addr. Register */
205#define SH7751_PCIDLA2 0x1A4 /* DMA2 Local Addr. Register */
206#define SH7751_PCIDTC2 0x1A8 /* DMA2 Transfer Cnt. Register */
207#define SH7751_PCIDCR2 0x1AC /* DMA2 Control Register */
208#define SH7751_PCIDPA3 0x1B0 /* DMA3 Transfer Addr. Register */
209#define SH7751_PCIDLA3 0x1B4 /* DMA3 Local Addr. Register */
210#define SH7751_PCIDTC3 0x1B8 /* DMA3 Transfer Cnt. Register */
211#define SH7751_PCIDCR3 0x1BC /* DMA3 Control Register */
212#define SH7751_PCIPAR 0x1C0 /* PIO Address Register */
213 #define SH7751_PCIPAR_CFGEN 0x80000000 /* Configuration Enable */
214 #define SH7751_PCIPAR_BUSNO 0x00FF0000 /* Config. Bus Number */
215 #define SH7751_PCIPAR_DEVNO 0x0000FF00 /* Config. Device Number */
216 #define SH7751_PCIPAR_REGAD 0x000000FC /* Register Address Number */
217#define SH7751_PCIMBR 0x1C4 /* Memory Base Address Register */
218 #define SH7751_PCIMBR_MASK 0xFF000000 /* Memory Space Mask */
219 #define SH7751_PCIMBR_LOCK 0x00000001 /* Lock Memory Space */
220#define SH7751_PCIIOBR 0x1C8 /* I/O Base Address Register */
221 #define SH7751_PCIIOBR_MASK 0xFFFC0000 /* IO Space Mask */
222 #define SH7751_PCIIOBR_LOCK 0x00000001 /* Lock IO Space */
223#define SH7751_PCIPINT 0x1CC /* Power Mgmnt Int. Register */
224 #define SH7751_PCIPINT_D3 0x00000002 /* D3 Pwr Mgmt. Interrupt */
225 #define SH7751_PCIPINT_D0 0x00000001 /* D0 Pwr Mgmt. Interrupt */
226#define SH7751_PCIPINTM 0x1D0 /* Power Mgmnt Mask Register */
227#define SH7751_PCICLKR 0x1D4 /* Clock Ctrl. Register */
228 #define SH7751_PCICLKR_PCSTP 0x00000002 /* PCI Clock Stop */
229 #define SH7751_PCICLKR_BCSTP 0x00000002 /* BCLK Clock Stop */
230/* For definitions of BCR, MCR see ... */
231#define SH7751_PCIBCR1 0x1E0 /* Memory BCR1 Register */
232#define SH7751_PCIBCR2 0x1E4 /* Memory BCR2 Register */
233#define SH7751_PCIWCR1 0x1E8 /* Wait Control 1 Register */
234#define SH7751_PCIWCR2 0x1EC /* Wait Control 2 Register */
235#define SH7751_PCIWCR3 0x1F0 /* Wait Control 3 Register */
236#define SH7751_PCIMCR 0x1F4 /* Memory Control Register */
237#define SH7751_PCIBCR3 0x1f8 /* Memory BCR3 Register */
238#define SH7751_PCIPCTR 0x200 /* Port Control Register */
239 #define SH7751_PCIPCTR_P2EN 0x000400000 /* Port 2 Enable */
240 #define SH7751_PCIPCTR_P1EN 0x000200000 /* Port 1 Enable */
241 #define SH7751_PCIPCTR_P0EN 0x000100000 /* Port 0 Enable */
242 #define SH7751_PCIPCTR_P2UP 0x000000020 /* Port2 Pull Up Enable */
243 #define SH7751_PCIPCTR_P2IO 0x000000010 /* Port2 Output Enable */
244 #define SH7751_PCIPCTR_P1UP 0x000000008 /* Port1 Pull Up Enable */
245 #define SH7751_PCIPCTR_P1IO 0x000000004 /* Port1 Output Enable */
246 #define SH7751_PCIPCTR_P0UP 0x000000002 /* Port0 Pull Up Enable */
247 #define SH7751_PCIPCTR_P0IO 0x000000001 /* Port0 Output Enable */
248#define SH7751_PCIPDTR 0x204 /* Port Data Register */
249 #define SH7751_PCIPDTR_PB5 0x000000020 /* Port 5 Enable */
250 #define SH7751_PCIPDTR_PB4 0x000000010 /* Port 4 Enable */
251 #define SH7751_PCIPDTR_PB3 0x000000008 /* Port 3 Enable */
252 #define SH7751_PCIPDTR_PB2 0x000000004 /* Port 2 Enable */
253 #define SH7751_PCIPDTR_PB1 0x000000002 /* Port 1 Enable */
254 #define SH7751_PCIPDTR_PB0 0x000000001 /* Port 0 Enable */
255#define SH7751_PCIPDR 0x220 /* Port IO Data Register */
256 109
257/* Memory Control Registers */ 110/* Memory Control Registers */
258#define SH7751_BCR1 0xFF800000 /* Memory BCR1 Register */ 111#define SH7751_BCR1 0xFF800000 /* Memory BCR1 Register */
@@ -274,30 +127,9 @@
274#define SH7751_CS5_BASE_ADDR (SH7751_CS4_BASE_ADDR + SH7751_MEM_REGION_SIZE) 127#define SH7751_CS5_BASE_ADDR (SH7751_CS4_BASE_ADDR + SH7751_MEM_REGION_SIZE)
275#define SH7751_CS6_BASE_ADDR (SH7751_CS5_BASE_ADDR + SH7751_MEM_REGION_SIZE) 128#define SH7751_CS6_BASE_ADDR (SH7751_CS5_BASE_ADDR + SH7751_MEM_REGION_SIZE)
276 129
277/* General PCI values */ 130struct sh4_pci_address_map;
278#define SH7751_PCI_HOST_BRIDGE 0x6
279
280/* Flags */
281#define SH7751_PCIC_NO_RESET 0x0001
282
283/* External functions defined per platform i.e. Big Sur, SE... (these could be routed
284 * through the machine vectors... */
285extern int pcibios_init_platform(void);
286extern int pcibios_map_platform_irq(u8 slot, u8 pin);
287
288struct sh7751_pci_address_space {
289 unsigned long base;
290 unsigned long size;
291};
292
293struct sh7751_pci_address_map {
294 struct sh7751_pci_address_space window0;
295 struct sh7751_pci_address_space window1;
296 unsigned long flags;
297};
298 131
299/* arch/sh/drivers/pci/pci-sh7751.c */ 132/* arch/sh/drivers/pci/pci-sh7751.c */
300extern int sh7751_pcic_init(struct sh7751_pci_address_map *map); 133int sh7751_pcic_init(struct sh4_pci_address_map *map);
301 134
302#endif /* _PCI_SH7751_H_ */ 135#endif /* _PCI_SH7751_H_ */
303
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
new file mode 100644
index 000000000000..bd3064a82087
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -0,0 +1,139 @@
1/*
2 * Low-Level PCI Support for the SH7780
3 *
4 * Dustin McIntire (dustin@sensoria.com)
5 * Derived from arch/i386/kernel/pci-*.c which bore the message:
6 * (c) 1999--2000 Martin Mares <mj@ucw.cz>
7 *
8 * Ported to the new API by Paul Mundt <lethal@linux-sh.org>
9 * With cleanup by Paul van Gool <pvangool@mimotech.com>
10 *
11 * May be copied or modified under the terms of the GNU General Public
12 * License. See linux/COPYING for more information.
13 *
14 */
15
16#undef DEBUG
17
18#include <linux/config.h>
19#include <linux/types.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/pci.h>
23#include <linux/errno.h>
24#include <linux/delay.h>
25#include "pci-sh4.h"
26
27/*
28 * Initialization. Try all known PCI access methods. Note that we support
29 * using both PCI BIOS and direct access: in such cases, we use I/O ports
30 * to access config space.
31 *
32 * Note that the platform specific initialization (BSC registers, and memory
33 * space mapping) will be called via the platform defined function
34 * pcibios_init_platform().
35 */
36static int __init sh7780_pci_init(void)
37{
38 unsigned int id;
39 int ret;
40
41 pr_debug("PCI: Starting intialization.\n");
42
43 outl(0x00000001, SH7780_PCI_VCR2); /* Enable PCIC */
44
45 /* check for SH7780/SH7780R hardware */
46 id = pci_read_reg(SH7780_PCIVID);
47 if ((id != ((SH7780_DEVICE_ID << 16) | SH7780_VENDOR_ID)) &&
48 (id != ((SH7781_DEVICE_ID << 16) | SH7780_VENDOR_ID))) {
49 printk(KERN_ERR "PCI: This is not an SH7780 (%x)\n", id);
50 return -ENODEV;
51 }
52
53 /* Setup the INTC */
54 ctrl_outl(0x00200000, INTC_ICR0); /* INTC SH-4 Mode */
55 ctrl_outl(0x00078000, INTC_INT2MSKCR); /* enable PCIINTA - PCIINTD */
56 ctrl_outl(0x40000000, INTC_INTMSK1); /* disable IRL4-7 Interrupt */
57 ctrl_outl(0x0000fffe, INTC_INTMSK2); /* disable IRL4-7 Interrupt */
58 ctrl_outl(0x80000000, INTC_INTMSKCLR1); /* enable IRL0-3 Interrupt */
59 ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); /* enable IRL0-3 Interrupt */
60
61 if ((ret = sh4_pci_check_direct()) != 0)
62 return ret;
63
64 return pcibios_init_platform();
65}
66core_initcall(sh7780_pci_init);
67
68int __init sh7780_pcic_init(struct sh4_pci_address_map *map)
69{
70 u32 word;
71
72 /*
73 * This code is unused for some boards as it is done in the
74 * bootloader and doing it here means the MAC addresses loaded
75 * by the bootloader get lost.
76 */
77 if (!(map->flags & SH4_PCIC_NO_RESET)) {
78 /* toggle PCI reset pin */
79 word = SH4_PCICR_PREFIX | SH4_PCICR_PRST;
80 pci_write_reg(word, SH4_PCICR);
81 /* Wait for a long time... not 1 sec. but long enough */
82 mdelay(100);
83 word = SH4_PCICR_PREFIX;
84 pci_write_reg(word, SH4_PCICR);
85 }
86
87 /* set the command/status bits to:
88 * Wait Cycle Control + Parity Enable + Bus Master +
89 * Mem space enable
90 */
91 pci_write_reg(0x00000046, SH7780_PCICMD);
92
93 /* define this host as the host bridge */
94 word = PCI_BASE_CLASS_BRIDGE << 24;
95 pci_write_reg(word, SH7780_PCIRID);
96
97 /* Set IO and Mem windows to local address
98 * Make PCI and local address the same for easy 1 to 1 mapping
99 * Window0 = map->window0.size @ non-cached area base = SDRAM
100 * Window1 = map->window1.size @ cached area base = SDRAM
101 */
102 word = ((map->window0.size - 1) & 0x1ff00001) | 0x01;
103 pci_write_reg(0x07f00001, SH4_PCILSR0);
104 word = ((map->window1.size - 1) & 0x1ff00001) | 0x01;
105 pci_write_reg(0x00000001, SH4_PCILSR1);
106 /* Set the values on window 0 PCI config registers */
107 word = P2SEGADDR(map->window0.base);
108 pci_write_reg(0xa8000000, SH4_PCILAR0);
109 pci_write_reg(0x08000000, SH7780_PCIMBAR0);
110 /* Set the values on window 1 PCI config registers */
111 word = P2SEGADDR(map->window1.base);
112 pci_write_reg(0x00000000, SH4_PCILAR1);
113 pci_write_reg(0x00000000, SH7780_PCIMBAR1);
114
115 /* Map IO space into PCI IO window
116 * The IO window is 64K-PCIBIOS_MIN_IO in size
117 * IO addresses will be translated to the
118 * PCI IO window base address
119 */
120 pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n",
121 PCIBIOS_MIN_IO, (64 << 10),
122 SH7780_PCI_IO_BASE + PCIBIOS_MIN_IO);
123
124 /* NOTE: I'm ignoring the PCI error IRQs for now..
125 * TODO: add support for the internal error interrupts and
126 * DMA interrupts...
127 */
128
129#ifdef CONFIG_SH_R7780RP
130 pci_fixup_pcic();
131#endif
132
133 /* SH7780 init done, set central function init complete */
134 /* use round robin mode to stop a device starving/overruning */
135 word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO;
136 pci_write_reg(word, SH4_PCICR);
137
138 return 1;
139}
diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h
new file mode 100644
index 000000000000..f02d2180a4bc
--- /dev/null
+++ b/arch/sh/drivers/pci/pci-sh7780.h
@@ -0,0 +1,94 @@
1/*
2 * Low-Level PCI Support for SH7780 targets
3 *
4 * Dustin McIntire (dustin@sensoria.com) (c) 2001
5 * Paul Mundt (lethal@linux-sh.org) (c) 2003
6 *
7 * May be copied or modified under the terms of the GNU General Public
8 * License. See linux/COPYING for more information.
9 *
10 */
11
12#ifndef _PCI_SH7780_H_
13#define _PCI_SH7780_H_
14
15/* Platform Specific Values */
16#define SH7780_VENDOR_ID 0x1912
17#define SH7780_DEVICE_ID 0x0002
18#define SH7781_DEVICE_ID 0x0001
19
20/* SH7780 Control Registers */
21#define SH7780_PCI_VCR0 0xFE000000
22#define SH7780_PCI_VCR1 0xFE000004
23#define SH7780_PCI_VCR2 0xFE000008
24
25/* SH7780 Specific Values */
26#define SH7780_PCI_CONFIG_BASE 0xFD000000 /* Config space base addr */
27#define SH7780_PCI_CONFIG_SIZE 0x01000000 /* Config space size */
28
29#define SH7780_PCI_MEMORY_BASE 0xFD000000 /* Memory space base addr */
30#define SH7780_PCI_MEM_SIZE 0x01000000 /* Size of Memory window */
31
32#define SH7780_PCI_IO_BASE 0xFE400000 /* IO space base address */
33#define SH7780_PCI_IO_SIZE 0x00400000 /* Size of IO window */
34
35#define SH7780_PCIREG_BASE 0xFE040000 /* PCI regs base address */
36#define PCI_REG(n) (SH7780_PCIREG_BASE+n)
37
38/* SH7780 PCI Config Registers */
39#define SH7780_PCIVID 0x000 /* Vendor ID */
40#define SH7780_PCIDID 0x002 /* Device ID */
41#define SH7780_PCICMD 0x004 /* Command */
42#define SH7780_PCISTATUS 0x006 /* Status */
43#define SH7780_PCIRID 0x008 /* Revision ID */
44#define SH7780_PCIPIF 0x009 /* Program Interface */
45#define SH7780_PCISUB 0x00a /* Sub class code */
46#define SH7780_PCIBCC 0x00b /* Base class code */
47#define SH7780_PCICLS 0x00c /* Cache line size */
48#define SH7780_PCILTM 0x00d /* latency timer */
49#define SH7780_PCIHDR 0x00e /* Header type */
50#define SH7780_PCIBIST 0x00f /* BIST */
51#define SH7780_PCIIBAR 0x010 /* IO Base address */
52#define SH7780_PCIMBAR0 0x014 /* Memory base address0 */
53#define SH7780_PCIMBAR1 0x018 /* Memory base address1 */
54#define SH7780_PCISVID 0x02c /* Sub system vendor ID */
55#define SH7780_PCISID 0x02e /* Sub system ID */
56#define SH7780_PCICP 0x034
57#define SH7780_PCIINTLINE 0x03c /* Interrupt line */
58#define SH7780_PCIINTPIN 0x03d /* Interrupt pin */
59#define SH7780_PCIMINGNT 0x03e /* Minumum grand */
60#define SH7780_PCIMAXLAT 0x03f /* Maxmum latency */
61#define SH7780_PCICID 0x040
62#define SH7780_PCINIP 0x041
63#define SH7780_PCIPMC 0x042
64#define SH7780_PCIPMCSR 0x044
65#define SH7780_PCIPMCSR_BSE 0x046
66#define SH7780_PCICDD 0x047
67
68#define SH7780_PCIMBR0 0x1E0
69#define SH7780_PCIMBMR0 0x1E4
70#define SH7780_PCIMBR2 0x1F0
71#define SH7780_PCIMBMR2 0x1F4
72#define SH7780_PCIIOBR 0x1F8
73#define SH7780_PCIIOBMR 0x1FC
74#define SH7780_PCICSCR0 0x210 /* Cache Snoop1 Cnt. Register */
75#define SH7780_PCICSCR1 0x214 /* Cache Snoop2 Cnt. Register */
76#define SH7780_PCICSAR0 0x218 /* Cache Snoop1 Addr. Register */
77#define SH7780_PCICSAR1 0x21C /* Cache Snoop2 Addr. Register */
78
79/* General Memory Config Addresses */
80#define SH7780_CS0_BASE_ADDR 0x0
81#define SH7780_MEM_REGION_SIZE 0x04000000
82#define SH7780_CS1_BASE_ADDR (SH7780_CS0_BASE_ADDR + SH7780_MEM_REGION_SIZE)
83#define SH7780_CS2_BASE_ADDR (SH7780_CS1_BASE_ADDR + SH7780_MEM_REGION_SIZE)
84#define SH7780_CS3_BASE_ADDR (SH7780_CS2_BASE_ADDR + SH7780_MEM_REGION_SIZE)
85#define SH7780_CS4_BASE_ADDR (SH7780_CS3_BASE_ADDR + SH7780_MEM_REGION_SIZE)
86#define SH7780_CS5_BASE_ADDR (SH7780_CS4_BASE_ADDR + SH7780_MEM_REGION_SIZE)
87#define SH7780_CS6_BASE_ADDR (SH7780_CS5_BASE_ADDR + SH7780_MEM_REGION_SIZE)
88
89struct sh4_pci_address_map;
90
91/* arch/sh/drivers/pci/pci-sh7780.c */
92int sh7780_pcic_init(struct sh4_pci_address_map *map);
93
94#endif /* _PCI_SH7780_H_ */
diff --git a/arch/sh/drivers/pci/pci-st40.c b/arch/sh/drivers/pci/pci-st40.c
index 7c81b8b65bb5..4ab5ea6b35fb 100644
--- a/arch/sh/drivers/pci/pci-st40.c
+++ b/arch/sh/drivers/pci/pci-st40.c
@@ -70,12 +70,6 @@
70static void pci_set_rbar_region(unsigned int region, unsigned long localAddr, 70static void pci_set_rbar_region(unsigned int region, unsigned long localAddr,
71 unsigned long pciOffset, unsigned long regionSize); 71 unsigned long pciOffset, unsigned long regionSize);
72 72
73/*
74 * The pcibios_map_platform_irq function is defined in the appropriate
75 * board specific code and referenced here
76 */
77extern int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin);
78
79static __init void SetPCIPLL(void) 73static __init void SetPCIPLL(void)
80{ 74{
81 { 75 {
@@ -422,13 +416,6 @@ struct pci_ops st40pci_config_ops = {
422/* Everything hangs off this */ 416/* Everything hangs off this */
423static struct pci_bus *pci_root_bus; 417static struct pci_bus *pci_root_bus;
424 418
425
426static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin)
427{
428 return PCI_SLOT(dev->devfn);
429}
430
431
432static int __init pcibios_init(void) 419static int __init pcibios_init(void)
433{ 420{
434 extern unsigned long memory_start, memory_end; 421 extern unsigned long memory_start, memory_end;
@@ -465,17 +452,11 @@ static int __init pcibios_init(void)
465 /* ok, do the scan man */ 452 /* ok, do the scan man */
466 pci_root_bus = pci_scan_bus(0, &st40pci_config_ops, NULL); 453 pci_root_bus = pci_scan_bus(0, &st40pci_config_ops, NULL);
467 pci_assign_unassigned_resources(); 454 pci_assign_unassigned_resources();
468 pci_fixup_irqs(no_swizzle, pcibios_map_platform_irq);
469 455
470 return 0; 456 return 0;
471} 457}
472
473subsys_initcall(pcibios_init); 458subsys_initcall(pcibios_init);
474 459
475void __init pcibios_fixup_bus(struct pci_bus *bus)
476{
477}
478
479/* 460/*
480 * Publish a region of local address space over the PCI bus 461 * Publish a region of local address space over the PCI bus
481 * to other devices. 462 * to other devices.
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index 3d546ba329cf..d439336d2e18 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -1,21 +1,45 @@
1/* arch/sh/kernel/pci.c 1/*
2 * $Id: pci.c,v 1.1 2003/08/24 19:15:45 lethal Exp $ 2 * arch/sh/drivers/pci/pci.c
3 * 3 *
4 * Copyright (c) 2002 M. R. Brown <mrbrown@linux-sh.org> 4 * Copyright (c) 2002 M. R. Brown <mrbrown@linux-sh.org>
5 * 5 * Copyright (c) 2004 - 2006 Paul Mundt <lethal@linux-sh.org>
6 * 6 *
7 * These functions are collected here to reduce duplication of common 7 * These functions are collected here to reduce duplication of common
8 * code amongst the many platform-specific PCI support code files. 8 * code amongst the many platform-specific PCI support code files.
9 * 9 *
10 * These routines require the following board-specific routines: 10 * These routines require the following board-specific routines:
11 * void pcibios_fixup_irqs(); 11 * void pcibios_fixup_irqs();
12 * 12 *
13 * See include/asm-sh/pci.h for more information. 13 * See include/asm-sh/pci.h for more information.
14 *
15 * This file is subject to the terms and conditions of the GNU General Public
16 * License. See the file "COPYING" in the main directory of this archive
17 * for more details.
14 */ 18 */
15
16#include <linux/kernel.h> 19#include <linux/kernel.h>
17#include <linux/pci.h> 20#include <linux/pci.h>
18#include <linux/init.h> 21#include <linux/init.h>
22#include <asm/io.h>
23
24static inline u8 bridge_swizzle(u8 pin, u8 slot)
25{
26 return (((pin - 1) + slot) % 4) + 1;
27}
28
29static u8 __init simple_swizzle(struct pci_dev *dev, u8 *pinp)
30{
31 u8 pin = *pinp;
32
33 while (dev->bus->parent) {
34 pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
35 /* Move up the chain of bridges. */
36 dev = dev->bus->self;
37 }
38 *pinp = pin;
39
40 /* The slot is the slot of the last bridge. */
41 return PCI_SLOT(dev->devfn);
42}
19 43
20static int __init pcibios_init(void) 44static int __init pcibios_init(void)
21{ 45{
@@ -26,26 +50,32 @@ static int __init pcibios_init(void)
26#ifdef CONFIG_PCI_AUTO 50#ifdef CONFIG_PCI_AUTO
27 /* assign resources */ 51 /* assign resources */
28 busno = 0; 52 busno = 0;
29 for (p = board_pci_channels; p->pci_ops != NULL; p++) { 53 for (p = board_pci_channels; p->pci_ops != NULL; p++)
30 busno = pciauto_assign_resources(busno, p) + 1; 54 busno = pciauto_assign_resources(busno, p) + 1;
31 }
32#endif 55#endif
33 56
34 /* scan the buses */ 57 /* scan the buses */
35 busno = 0; 58 busno = 0;
36 for (p= board_pci_channels; p->pci_ops != NULL; p++) { 59 for (p = board_pci_channels; p->pci_ops != NULL; p++) {
37 bus = pci_scan_bus(busno, p->pci_ops, p); 60 bus = pci_scan_bus(busno, p->pci_ops, p);
38 busno = bus->subordinate+1; 61 busno = bus->subordinate + 1;
39 } 62 }
40 63
41 /* board-specific fixups */ 64 pci_fixup_irqs(simple_swizzle, pcibios_map_platform_irq);
42 pcibios_fixup_irqs();
43 65
44 return 0; 66 return 0;
45} 67}
46
47subsys_initcall(pcibios_init); 68subsys_initcall(pcibios_init);
48 69
70/*
71 * Called after each bus is probed, but before its children
72 * are examined.
73 */
74void __init pcibios_fixup_bus(struct pci_bus *bus)
75{
76 pci_read_bridge_bases(bus);
77}
78
49void 79void
50pcibios_update_resource(struct pci_dev *dev, struct resource *root, 80pcibios_update_resource(struct pci_dev *dev, struct resource *root,
51 struct resource *res, int resource) 81 struct resource *res, int resource)
@@ -61,13 +91,17 @@ pcibios_update_resource(struct pci_dev *dev, struct resource *root,
61 new |= PCI_ROM_ADDRESS_ENABLE; 91 new |= PCI_ROM_ADDRESS_ENABLE;
62 reg = dev->rom_base_reg; 92 reg = dev->rom_base_reg;
63 } else { 93 } else {
64 /* Somebody might have asked allocation of a non-standard resource */ 94 /*
95 * Somebody might have asked allocation of a non-standard
96 * resource
97 */
65 return; 98 return;
66 } 99 }
67 100
68 pci_write_config_dword(dev, reg, new); 101 pci_write_config_dword(dev, reg, new);
69 pci_read_config_dword(dev, reg, &check); 102 pci_read_config_dword(dev, reg, &check);
70 if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) { 103 if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ?
104 PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
71 printk(KERN_ERR "PCI: Error while updating region " 105 printk(KERN_ERR "PCI: Error while updating region "
72 "%s/%d (%08x != %08x)\n", pci_name(dev), resource, 106 "%s/%d (%08x != %08x)\n", pci_name(dev), resource,
73 new, check); 107 new, check);
@@ -145,7 +179,8 @@ void pcibios_set_master(struct pci_dev *dev)
145 lat = pcibios_max_latency; 179 lat = pcibios_max_latency;
146 else 180 else
147 return; 181 return;
148 printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat); 182 printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n",
183 pci_name(dev), lat);
149 pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); 184 pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
150} 185}
151 186
@@ -153,3 +188,39 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq)
153{ 188{
154 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); 189 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
155} 190}
191
192void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
193{
194 unsigned long start = pci_resource_start(dev, bar);
195 unsigned long len = pci_resource_len(dev, bar);
196 unsigned long flags = pci_resource_flags(dev, bar);
197
198 if (unlikely(!len || !start))
199 return NULL;
200 if (maxlen && len > maxlen)
201 len = maxlen;
202
203 /*
204 * Presently the IORESOURCE_MEM case is a bit special, most
205 * SH7751 style PCI controllers have PCI memory at a fixed
206 * location in the address space where no remapping is desired
207 * (typically at 0xfd000000, but is_pci_memaddr() will know
208 * best). With the IORESOURCE_MEM case more care has to be taken
209 * to inhibit page table mapping for legacy cores, but this is
210 * punted off to __ioremap().
211 * -- PFM.
212 */
213 if (flags & IORESOURCE_IO)
214 return ioport_map(start, len);
215 if (flags & IORESOURCE_MEM)
216 return ioremap(start, len);
217
218 return NULL;
219}
220EXPORT_SYMBOL(pci_iomap);
221
222void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
223{
224 iounmap(addr);
225}
226EXPORT_SYMBOL(pci_iounmap);
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index f05cd96f8867..5da88a43d350 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -6,9 +6,10 @@ extra-y := head.o init_task.o vmlinux.lds
6 6
7obj-y := process.o signal.o entry.o traps.o irq.o \ 7obj-y := process.o signal.o entry.o traps.o irq.o \
8 ptrace.o setup.o time.o sys_sh.o semaphore.o \ 8 ptrace.o setup.o time.o sys_sh.o semaphore.o \
9 io.o io_generic.o sh_ksyms.o 9 io.o io_generic.o sh_ksyms.o syscalls.o
10 10
11obj-y += cpu/ timers/ 11obj-y += cpu/ timers/
12obj-$(CONFIG_VSYSCALL) += vsyscall/
12 13
13obj-$(CONFIG_SMP) += smp.o 14obj-$(CONFIG_SMP) += smp.o
14obj-$(CONFIG_CF_ENABLER) += cf-enabler.o 15obj-$(CONFIG_CF_ENABLER) += cf-enabler.o
@@ -18,3 +19,5 @@ obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o
18obj-$(CONFIG_MODULES) += module.o 19obj-$(CONFIG_MODULES) += module.o
19obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 20obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
20obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 21obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
22obj-$(CONFIG_APM) += apm.o
23obj-$(CONFIG_PM) += pm.o
diff --git a/arch/sh/kernel/apm.c b/arch/sh/kernel/apm.c
new file mode 100644
index 000000000000..871e7d640002
--- /dev/null
+++ b/arch/sh/kernel/apm.c
@@ -0,0 +1,539 @@
1/*
2 * bios-less APM driver for hp680
3 *
4 * Copyright 2005 (c) Andriy Skulysh <askulysh@gmail.com>
5 *
6 * based on ARM APM driver by
7 * Jamey Hicks <jamey@crl.dec.com>
8 *
9 * adapted from the APM BIOS driver for Linux by
10 * Stephen Rothwell (sfr@linuxcare.com)
11 *
12 * APM 1.2 Reference:
13 * Intel Corporation, Microsoft Corporation. Advanced Power Management
14 * (APM) BIOS Interface Specification, Revision 1.2, February 1996.
15 *
16 * [This document is available from Microsoft at:
17 * http://www.microsoft.com/hwdev/busbios/amp_12.htm]
18 */
19#include <linux/config.h>
20#include <linux/module.h>
21#include <linux/poll.h>
22#include <linux/timer.h>
23#include <linux/slab.h>
24#include <linux/proc_fs.h>
25#include <linux/miscdevice.h>
26#include <linux/apm_bios.h>
27#include <linux/pm.h>
28#include <linux/pm_legacy.h>
29#include <asm/apm.h>
30
31#define MODNAME "apm"
32
33/*
34 * The apm_bios device is one of the misc char devices.
35 * This is its minor number.
36 */
37#define APM_MINOR_DEV 134
38
39/*
40 * Maximum number of events stored
41 */
42#define APM_MAX_EVENTS 16
43
44struct apm_queue {
45 unsigned int event_head;
46 unsigned int event_tail;
47 apm_event_t events[APM_MAX_EVENTS];
48};
49
50/*
51 * The per-file APM data
52 */
53struct apm_user {
54 struct list_head list;
55
56 unsigned int suser: 1;
57 unsigned int writer: 1;
58 unsigned int reader: 1;
59
60 int suspend_result;
61 unsigned int suspend_state;
62#define SUSPEND_NONE 0 /* no suspend pending */
63#define SUSPEND_PENDING 1 /* suspend pending read */
64#define SUSPEND_READ 2 /* suspend read, pending ack */
65#define SUSPEND_ACKED 3 /* suspend acked */
66#define SUSPEND_DONE 4 /* suspend completed */
67
68 struct apm_queue queue;
69};
70
71/*
72 * Local variables
73 */
74static int suspends_pending;
75
76static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
77static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
78
79/*
80 * This is a list of everyone who has opened /dev/apm_bios
81 */
82static DECLARE_RWSEM(user_list_lock);
83static LIST_HEAD(apm_user_list);
84
85/*
86 * kapmd info. kapmd provides us a process context to handle
87 * "APM" events within - specifically necessary if we're going
88 * to be suspending the system.
89 */
90static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait);
91static DECLARE_COMPLETION(kapmd_exit);
92static DEFINE_SPINLOCK(kapmd_queue_lock);
93static struct apm_queue kapmd_queue;
94
95int apm_suspended;
96EXPORT_SYMBOL(apm_suspended);
97
98/* Platform-specific apm_read_proc(). */
99int (*apm_get_info)(char *buf, char **start, off_t fpos, int length);
100EXPORT_SYMBOL(apm_get_info);
101
102/*
103 * APM event queue management.
104 */
105static inline int queue_empty(struct apm_queue *q)
106{
107 return q->event_head == q->event_tail;
108}
109
110static inline apm_event_t queue_get_event(struct apm_queue *q)
111{
112 q->event_tail = (q->event_tail + 1) % APM_MAX_EVENTS;
113 return q->events[q->event_tail];
114}
115
116static void queue_add_event(struct apm_queue *q, apm_event_t event)
117{
118 q->event_head = (q->event_head + 1) % APM_MAX_EVENTS;
119 if (q->event_head == q->event_tail) {
120 static int notified;
121
122 if (notified++ == 0)
123 printk(KERN_ERR "apm: an event queue overflowed\n");
124
125 q->event_tail = (q->event_tail + 1) % APM_MAX_EVENTS;
126 }
127 q->events[q->event_head] = event;
128}
129
130static void queue_event_one_user(struct apm_user *as, apm_event_t event)
131{
132 if (as->suser && as->writer) {
133 switch (event) {
134 case APM_SYS_SUSPEND:
135 case APM_USER_SUSPEND:
136 /*
137 * If this user already has a suspend pending,
138 * don't queue another one.
139 */
140 if (as->suspend_state != SUSPEND_NONE)
141 return;
142
143 as->suspend_state = SUSPEND_PENDING;
144 suspends_pending++;
145 break;
146 }
147 }
148 queue_add_event(&as->queue, event);
149}
150
151static void queue_event(apm_event_t event, struct apm_user *sender)
152{
153 struct apm_user *as;
154
155 down_read(&user_list_lock);
156
157 list_for_each_entry(as, &apm_user_list, list)
158 if (as != sender && as->reader)
159 queue_event_one_user(as, event);
160
161 up_read(&user_list_lock);
162 wake_up_interruptible(&apm_waitqueue);
163}
164
165/**
166 * apm_queue_event - queue an APM event for kapmd
167 * @event: APM event
168 *
169 * Queue an APM event for kapmd to process and ultimately take the
170 * appropriate action. Only a subset of events are handled:
171 * %APM_LOW_BATTERY
172 * %APM_POWER_STATUS_CHANGE
173 * %APM_USER_SUSPEND
174 * %APM_SYS_SUSPEND
175 * %APM_CRITICAL_SUSPEND
176 */
177void apm_queue_event(apm_event_t event)
178{
179 spin_lock_irq(&kapmd_queue_lock);
180 queue_add_event(&kapmd_queue, event);
181 spin_unlock_irq(&kapmd_queue_lock);
182
183 wake_up_interruptible(&kapmd_wait);
184}
185EXPORT_SYMBOL(apm_queue_event);
186
187static void apm_suspend(void)
188{
189 struct apm_user *as;
190 int err;
191
192 apm_suspended = 1;
193 err = pm_suspend(PM_SUSPEND_MEM);
194
195 /*
196 * Anyone on the APM queues will think we're still suspended.
197 * Send a message so everyone knows we're now awake again.
198 */
199 queue_event(APM_NORMAL_RESUME, NULL);
200
201 /*
202 * Finally, wake up anyone who is sleeping on the suspend.
203 */
204 down_read(&user_list_lock);
205 list_for_each_entry(as, &apm_user_list, list) {
206 as->suspend_result = err;
207 as->suspend_state = SUSPEND_DONE;
208 }
209 up_read(&user_list_lock);
210
211 wake_up(&apm_suspend_waitqueue);
212 apm_suspended = 0;
213}
214
215static ssize_t apm_read(struct file *fp, char __user *buf,
216 size_t count, loff_t *ppos)
217{
218 struct apm_user *as = fp->private_data;
219 apm_event_t event;
220 int i = count, ret = 0;
221
222 if (count < sizeof(apm_event_t))
223 return -EINVAL;
224
225 if (queue_empty(&as->queue) && fp->f_flags & O_NONBLOCK)
226 return -EAGAIN;
227
228 wait_event_interruptible(apm_waitqueue, !queue_empty(&as->queue));
229
230 while ((i >= sizeof(event)) && !queue_empty(&as->queue)) {
231 event = queue_get_event(&as->queue);
232
233 ret = -EFAULT;
234 if (copy_to_user(buf, &event, sizeof(event)))
235 break;
236
237 if (event == APM_SYS_SUSPEND || event == APM_USER_SUSPEND)
238 as->suspend_state = SUSPEND_READ;
239
240 buf += sizeof(event);
241 i -= sizeof(event);
242 }
243
244 if (i < count)
245 ret = count - i;
246
247 return ret;
248}
249
250static unsigned int apm_poll(struct file *fp, poll_table * wait)
251{
252 struct apm_user *as = fp->private_data;
253
254 poll_wait(fp, &apm_waitqueue, wait);
255 return queue_empty(&as->queue) ? 0 : POLLIN | POLLRDNORM;
256}
257
258/*
259 * apm_ioctl - handle APM ioctl
260 *
261 * APM_IOC_SUSPEND
262 * This IOCTL is overloaded, and performs two functions. It is used to:
263 * - initiate a suspend
264 * - acknowledge a suspend read from /dev/apm_bios.
265 * Only when everyone who has opened /dev/apm_bios with write permission
266 * has acknowledge does the actual suspend happen.
267 */
268static int
269apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg)
270{
271 struct apm_user *as = filp->private_data;
272 unsigned long flags;
273 int err = -EINVAL;
274
275 if (!as->suser || !as->writer)
276 return -EPERM;
277
278 switch (cmd) {
279 case APM_IOC_SUSPEND:
280 as->suspend_result = -EINTR;
281
282 if (as->suspend_state == SUSPEND_READ) {
283 /*
284 * If we read a suspend command from /dev/apm_bios,
285 * then the corresponding APM_IOC_SUSPEND ioctl is
286 * interpreted as an acknowledge.
287 */
288 as->suspend_state = SUSPEND_ACKED;
289 suspends_pending--;
290 } else {
291 /*
292 * Otherwise it is a request to suspend the system.
293 * Queue an event for all readers, and expect an
294 * acknowledge from all writers who haven't already
295 * acknowledged.
296 */
297 queue_event(APM_USER_SUSPEND, as);
298 }
299
300 /*
301 * If there are no further acknowledges required, suspend
302 * the system.
303 */
304 if (suspends_pending == 0)
305 apm_suspend();
306
307 /*
308 * Wait for the suspend/resume to complete. If there are
309 * pending acknowledges, we wait here for them.
310 *
311 * Note that we need to ensure that the PM subsystem does
312 * not kick us out of the wait when it suspends the threads.
313 */
314 flags = current->flags;
315 current->flags |= PF_NOFREEZE;
316
317 /*
318 * Note: do not allow a thread which is acking the suspend
319 * to escape until the resume is complete.
320 */
321 if (as->suspend_state == SUSPEND_ACKED)
322 wait_event(apm_suspend_waitqueue,
323 as->suspend_state == SUSPEND_DONE);
324 else
325 wait_event_interruptible(apm_suspend_waitqueue,
326 as->suspend_state == SUSPEND_DONE);
327
328 current->flags = flags;
329 err = as->suspend_result;
330 as->suspend_state = SUSPEND_NONE;
331 break;
332 }
333
334 return err;
335}
336
337static int apm_release(struct inode * inode, struct file * filp)
338{
339 struct apm_user *as = filp->private_data;
340 filp->private_data = NULL;
341
342 down_write(&user_list_lock);
343 list_del(&as->list);
344 up_write(&user_list_lock);
345
346 /*
347 * We are now unhooked from the chain. As far as new
348 * events are concerned, we no longer exist. However, we
349 * need to balance suspends_pending, which means the
350 * possibility of sleeping.
351 */
352 if (as->suspend_state != SUSPEND_NONE) {
353 suspends_pending -= 1;
354 if (suspends_pending == 0)
355 apm_suspend();
356 }
357
358 kfree(as);
359 return 0;
360}
361
362static int apm_open(struct inode * inode, struct file * filp)
363{
364 struct apm_user *as;
365
366 as = kzalloc(sizeof(*as), GFP_KERNEL);
367 if (as) {
368 /*
369 * XXX - this is a tiny bit broken, when we consider BSD
370 * process accounting. If the device is opened by root, we
371 * instantly flag that we used superuser privs. Who knows,
372 * we might close the device immediately without doing a
373 * privileged operation -- cevans
374 */
375 as->suser = capable(CAP_SYS_ADMIN);
376 as->writer = (filp->f_mode & FMODE_WRITE) == FMODE_WRITE;
377 as->reader = (filp->f_mode & FMODE_READ) == FMODE_READ;
378
379 down_write(&user_list_lock);
380 list_add(&as->list, &apm_user_list);
381 up_write(&user_list_lock);
382
383 filp->private_data = as;
384 }
385
386 return as ? 0 : -ENOMEM;
387}
388
389static struct file_operations apm_bios_fops = {
390 .owner = THIS_MODULE,
391 .read = apm_read,
392 .poll = apm_poll,
393 .ioctl = apm_ioctl,
394 .open = apm_open,
395 .release = apm_release,
396};
397
398static struct miscdevice apm_device = {
399 .minor = APM_MINOR_DEV,
400 .name = "apm_bios",
401 .fops = &apm_bios_fops
402};
403
404
405#ifdef CONFIG_PROC_FS
406/*
407 * Arguments, with symbols from linux/apm_bios.h.
408 *
409 * 0) Linux driver version (this will change if format changes)
410 * 1) APM BIOS Version. Usually 1.0, 1.1 or 1.2.
411 * 2) APM flags from APM Installation Check (0x00):
412 * bit 0: APM_16_BIT_SUPPORT
413 * bit 1: APM_32_BIT_SUPPORT
414 * bit 2: APM_IDLE_SLOWS_CLOCK
415 * bit 3: APM_BIOS_DISABLED
416 * bit 4: APM_BIOS_DISENGAGED
417 * 3) AC line status
418 * 0x00: Off-line
419 * 0x01: On-line
420 * 0x02: On backup power (BIOS >= 1.1 only)
421 * 0xff: Unknown
422 * 4) Battery status
423 * 0x00: High
424 * 0x01: Low
425 * 0x02: Critical
426 * 0x03: Charging
427 * 0x04: Selected battery not present (BIOS >= 1.2 only)
428 * 0xff: Unknown
429 * 5) Battery flag
430 * bit 0: High
431 * bit 1: Low
432 * bit 2: Critical
433 * bit 3: Charging
434 * bit 7: No system battery
435 * 0xff: Unknown
436 * 6) Remaining battery life (percentage of charge):
437 * 0-100: valid
438 * -1: Unknown
439 * 7) Remaining battery life (time units):
440 * Number of remaining minutes or seconds
441 * -1: Unknown
442 * 8) min = minutes; sec = seconds
443 */
444static int apm_read_proc(char *buf, char **start, off_t fpos, int length)
445{
446 if (likely(apm_get_info))
447 return apm_get_info(buf, start, fpos, length);
448
449 return -EINVAL;
450}
451#endif
452
453static int kapmd(void *arg)
454{
455 daemonize("kapmd");
456 current->flags |= PF_NOFREEZE;
457
458 do {
459 apm_event_t event;
460
461 wait_event_interruptible(kapmd_wait,
462 !queue_empty(&kapmd_queue) || !pm_active);
463
464 if (!pm_active)
465 break;
466
467 spin_lock_irq(&kapmd_queue_lock);
468 event = 0;
469 if (!queue_empty(&kapmd_queue))
470 event = queue_get_event(&kapmd_queue);
471 spin_unlock_irq(&kapmd_queue_lock);
472
473 switch (event) {
474 case 0:
475 break;
476
477 case APM_LOW_BATTERY:
478 case APM_POWER_STATUS_CHANGE:
479 queue_event(event, NULL);
480 break;
481
482 case APM_USER_SUSPEND:
483 case APM_SYS_SUSPEND:
484 queue_event(event, NULL);
485 if (suspends_pending == 0)
486 apm_suspend();
487 break;
488
489 case APM_CRITICAL_SUSPEND:
490 apm_suspend();
491 break;
492 }
493 } while (1);
494
495 complete_and_exit(&kapmd_exit, 0);
496}
497
498static int __init apm_init(void)
499{
500 int ret;
501
502 pm_active = 1;
503
504 ret = kernel_thread(kapmd, NULL, CLONE_KERNEL);
505 if (unlikely(ret < 0)) {
506 pm_active = 0;
507 return ret;
508 }
509
510 create_proc_info_entry("apm", 0, NULL, apm_read_proc);
511
512 ret = misc_register(&apm_device);
513 if (unlikely(ret != 0)) {
514 remove_proc_entry("apm", NULL);
515
516 pm_active = 0;
517 wake_up(&kapmd_wait);
518 wait_for_completion(&kapmd_exit);
519 }
520
521 return ret;
522}
523
524static void __exit apm_exit(void)
525{
526 misc_deregister(&apm_device);
527 remove_proc_entry("apm", NULL);
528
529 pm_active = 0;
530 wake_up(&kapmd_wait);
531 wait_for_completion(&kapmd_exit);
532}
533
534module_init(apm_init);
535module_exit(apm_exit);
536
537MODULE_AUTHOR("Stephen Rothwell, Andriy Skulysh");
538MODULE_DESCRIPTION("Advanced Power Management");
539MODULE_LICENSE("GPL");
diff --git a/arch/sh/kernel/cf-enabler.c b/arch/sh/kernel/cf-enabler.c
index f1f9ab87f0b0..3e5fa1e24df0 100644
--- a/arch/sh/kernel/cf-enabler.c
+++ b/arch/sh/kernel/cf-enabler.c
@@ -10,7 +10,8 @@
10 */ 10 */
11 11
12#include <linux/init.h> 12#include <linux/init.h>
13 13#include <linux/mm.h>
14#include <linux/vmalloc.h>
14#include <asm/io.h> 15#include <asm/io.h>
15#include <asm/irq.h> 16#include <asm/irq.h>
16 17
@@ -32,8 +33,6 @@
32/* SH4 can't access PCMCIA interface through P2 area. 33/* SH4 can't access PCMCIA interface through P2 area.
33 * we must remap it with appropreate attribute bit of the page set. 34 * we must remap it with appropreate attribute bit of the page set.
34 * this part is based on Greg Banks' hd64465_ss.c implementation - Masahiro Abe */ 35 * this part is based on Greg Banks' hd64465_ss.c implementation - Masahiro Abe */
35#include <linux/mm.h>
36#include <linux/vmalloc.h>
37 36
38#if defined(CONFIG_CF_AREA6) 37#if defined(CONFIG_CF_AREA6)
39#define slot_no 0 38#define slot_no 0
@@ -41,9 +40,6 @@
41#define slot_no 1 40#define slot_no 1
42#endif 41#endif
43 42
44/* defined in mm/ioremap.c */
45extern void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags);
46
47/* use this pointer to access to directly connected compact flash io area*/ 43/* use this pointer to access to directly connected compact flash io area*/
48void *cf_io_base; 44void *cf_io_base;
49 45
@@ -62,7 +58,7 @@ static int __init allocate_cf_area(void)
62 return -ENOMEM; 58 return -ENOMEM;
63 } 59 }
64/* printk("p3_ioremap(paddr=0x%08lx, psize=0x%08lx, prot=0x%08lx)=0x%08lx\n", 60/* printk("p3_ioremap(paddr=0x%08lx, psize=0x%08lx, prot=0x%08lx)=0x%08lx\n",
65 paddrbase, psize, prot.pgprot, cf_io_base);*/ 61 paddrbase, psize, prot.pgprot, cf_io_base);*/
66 62
67 /* XXX : do we need attribute and common-memory area also? */ 63 /* XXX : do we need attribute and common-memory area also? */
68 64
@@ -87,7 +83,7 @@ static int __init cf_init_default(void)
87} 83}
88 84
89#if defined(CONFIG_SH_SOLUTION_ENGINE) 85#if defined(CONFIG_SH_SOLUTION_ENGINE)
90#include <asm/se/se.h> 86#include <asm/se.h>
91 87
92/* 88/*
93 * SolutionEngine 89 * SolutionEngine
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile
index 59d5b748752f..fb5dac069382 100644
--- a/arch/sh/kernel/cpu/Makefile
+++ b/arch/sh/kernel/cpu/Makefile
@@ -8,6 +8,5 @@ obj-$(CONFIG_CPU_SH2) += sh2/
8obj-$(CONFIG_CPU_SH3) += sh3/ 8obj-$(CONFIG_CPU_SH3) += sh3/
9obj-$(CONFIG_CPU_SH4) += sh4/ 9obj-$(CONFIG_CPU_SH4) += sh4/
10 10
11obj-$(CONFIG_SH_RTC) += rtc.o
12obj-$(CONFIG_UBC_WAKEUP) += ubc.o 11obj-$(CONFIG_UBC_WAKEUP) += ubc.o
13obj-$(CONFIG_SH_ADC) += adc.o 12obj-$(CONFIG_SH_ADC) += adc.o
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index 97fa37f42b84..51ec64cdf348 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * arch/sh/kernel/cpu/clock.c - SuperH clock framework 2 * arch/sh/kernel/cpu/clock.c - SuperH clock framework
3 * 3 *
4 * Copyright (C) 2005 Paul Mundt 4 * Copyright (C) 2005, 2006 Paul Mundt
5 * 5 *
6 * This clock framework is derived from the OMAP version by: 6 * This clock framework is derived from the OMAP version by:
7 * 7 *
@@ -15,6 +15,7 @@
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/mutex.h>
18#include <linux/list.h> 19#include <linux/list.h>
19#include <linux/kref.h> 20#include <linux/kref.h>
20#include <linux/seq_file.h> 21#include <linux/seq_file.h>
@@ -24,7 +25,7 @@
24 25
25static LIST_HEAD(clock_list); 26static LIST_HEAD(clock_list);
26static DEFINE_SPINLOCK(clock_lock); 27static DEFINE_SPINLOCK(clock_lock);
27static DECLARE_MUTEX(clock_list_sem); 28static DEFINE_MUTEX(clock_list_sem);
28 29
29/* 30/*
30 * Each subtype is expected to define the init routines for these clocks, 31 * Each subtype is expected to define the init routines for these clocks,
@@ -140,21 +141,21 @@ void clk_disable(struct clk *clk)
140 141
141int clk_register(struct clk *clk) 142int clk_register(struct clk *clk)
142{ 143{
143 down(&clock_list_sem); 144 mutex_lock(&clock_list_sem);
144 145
145 list_add(&clk->node, &clock_list); 146 list_add(&clk->node, &clock_list);
146 kref_init(&clk->kref); 147 kref_init(&clk->kref);
147 148
148 up(&clock_list_sem); 149 mutex_unlock(&clock_list_sem);
149 150
150 return 0; 151 return 0;
151} 152}
152 153
153void clk_unregister(struct clk *clk) 154void clk_unregister(struct clk *clk)
154{ 155{
155 down(&clock_list_sem); 156 mutex_lock(&clock_list_sem);
156 list_del(&clk->node); 157 list_del(&clk->node);
157 up(&clock_list_sem); 158 mutex_unlock(&clock_list_sem);
158} 159}
159 160
160inline unsigned long clk_get_rate(struct clk *clk) 161inline unsigned long clk_get_rate(struct clk *clk)
@@ -198,14 +199,14 @@ struct clk *clk_get(const char *id)
198{ 199{
199 struct clk *p, *clk = ERR_PTR(-ENOENT); 200 struct clk *p, *clk = ERR_PTR(-ENOENT);
200 201
201 down(&clock_list_sem); 202 mutex_lock(&clock_list_sem);
202 list_for_each_entry(p, &clock_list, node) { 203 list_for_each_entry(p, &clock_list, node) {
203 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { 204 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
204 clk = p; 205 clk = p;
205 break; 206 break;
206 } 207 }
207 } 208 }
208 up(&clock_list_sem); 209 mutex_unlock(&clock_list_sem);
209 210
210 return clk; 211 return clk;
211} 212}
@@ -225,7 +226,7 @@ int __init clk_init(void)
225{ 226{
226 int i, ret = 0; 227 int i, ret = 0;
227 228
228 BUG_ON(unlikely(!master_clk.rate)); 229 BUG_ON(!master_clk.rate);
229 230
230 for (i = 0; i < ARRAY_SIZE(onchip_clocks); i++) { 231 for (i = 0; i < ARRAY_SIZE(onchip_clocks); i++) {
231 struct clk *clk = onchip_clocks[i]; 232 struct clk *clk = onchip_clocks[i];
diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c
index 868e68b28880..bfb90eb0b7a6 100644
--- a/arch/sh/kernel/cpu/init.c
+++ b/arch/sh/kernel/cpu/init.c
@@ -4,6 +4,7 @@
4 * CPU init code 4 * CPU init code
5 * 5 *
6 * Copyright (C) 2002, 2003 Paul Mundt 6 * Copyright (C) 2002, 2003 Paul Mundt
7 * Copyright (C) 2003 Richard Curnow
7 * 8 *
8 * This file is subject to the terms and conditions of the GNU General Public 9 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive 10 * License. See the file "COPYING" in the main directory of this archive
@@ -13,6 +14,7 @@
13#include <linux/kernel.h> 14#include <linux/kernel.h>
14#include <asm/processor.h> 15#include <asm/processor.h>
15#include <asm/uaccess.h> 16#include <asm/uaccess.h>
17#include <asm/page.h>
16#include <asm/system.h> 18#include <asm/system.h>
17#include <asm/cacheflush.h> 19#include <asm/cacheflush.h>
18#include <asm/cache.h> 20#include <asm/cache.h>
@@ -51,7 +53,15 @@ static void __init cache_init(void)
51 ccr = ctrl_inl(CCR); 53 ccr = ctrl_inl(CCR);
52 54
53 /* 55 /*
54 * If the cache is already enabled .. flush it. 56 * At this point we don't know whether the cache is enabled or not - a
57 * bootloader may have enabled it. There are at least 2 things that
58 * could be dirty in the cache at this point:
59 * 1. kernel command line set up by boot loader
60 * 2. spilled registers from the prolog of this function
61 * => before re-initialising the cache, we must do a purge of the whole
62 * cache out to memory for safety. As long as nothing is spilled
63 * during the loop to lines that have already been done, this is safe.
64 * - RPC
55 */ 65 */
56 if (ccr & CCR_CACHE_ENABLE) { 66 if (ccr & CCR_CACHE_ENABLE) {
57 unsigned long ways, waysize, addrstart; 67 unsigned long ways, waysize, addrstart;
@@ -98,6 +108,8 @@ static void __init cache_init(void)
98 /* Force EMODE if possible */ 108 /* Force EMODE if possible */
99 if (cpu_data->dcache.ways > 1) 109 if (cpu_data->dcache.ways > 1)
100 flags |= CCR_CACHE_EMODE; 110 flags |= CCR_CACHE_EMODE;
111 else
112 flags &= ~CCR_CACHE_EMODE;
101#endif 113#endif
102 114
103#ifdef CONFIG_SH_WRITETHROUGH 115#ifdef CONFIG_SH_WRITETHROUGH
@@ -112,6 +124,9 @@ static void __init cache_init(void)
112 /* Turn on OCRAM -- halve the OC */ 124 /* Turn on OCRAM -- halve the OC */
113 flags |= CCR_CACHE_ORA; 125 flags |= CCR_CACHE_ORA;
114 cpu_data->dcache.sets >>= 1; 126 cpu_data->dcache.sets >>= 1;
127
128 cpu_data->dcache.way_size = cpu_data->dcache.sets *
129 cpu_data->dcache.linesz;
115#endif 130#endif
116 131
117 ctrl_outl(flags, CCR); 132 ctrl_outl(flags, CCR);
@@ -184,6 +199,10 @@ asmlinkage void __init sh_cpu_init(void)
184 /* Init the cache */ 199 /* Init the cache */
185 cache_init(); 200 cache_init();
186 201
202 shm_align_mask = max_t(unsigned long,
203 cpu_data->dcache.way_size - 1,
204 PAGE_SIZE - 1);
205
187 /* Disable the FPU */ 206 /* Disable the FPU */
188 if (fpu_disabled) { 207 if (fpu_disabled) {
189 printk("FPU Disabled\n"); 208 printk("FPU Disabled\n");
diff --git a/arch/sh/kernel/cpu/irq/Makefile b/arch/sh/kernel/cpu/irq/Makefile
index e3cccea15e1d..1c034c283f59 100644
--- a/arch/sh/kernel/cpu/irq/Makefile
+++ b/arch/sh/kernel/cpu/irq/Makefile
@@ -3,5 +3,6 @@
3# 3#
4obj-y += ipr.o imask.o 4obj-y += ipr.o imask.o
5 5
6obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o 6obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o
7obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o 7obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o
8obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o
diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c
index 30064bf6e154..e30e4b7aa70e 100644
--- a/arch/sh/kernel/cpu/irq/intc2.c
+++ b/arch/sh/kernel/cpu/irq/intc2.c
@@ -241,9 +241,9 @@ static struct intc2_init {
241 /* 110-111 reserved/unused */ 241 /* 110-111 reserved/unused */
242#elif defined(CONFIG_CPU_SUBTYPE_SH7780) 242#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
243 { TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2}, 243 { TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2},
244#ifdef CONFIG_SH_RTC 244 { 21, 1, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY },
245 { RTC_IRQ, 4, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY }, 245 { 22, 1, 1, 0, INTC_RTC_MSK, TIMER_PRIORITY },
246#endif 246 { 23, 1, 2, 0, INTC_RTC_MSK, TIMER_PRIORITY },
247 { SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, 247 { SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
248 { SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, 248 { SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
249 { SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, 249 { SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c
index 0f545941fb4f..f785822cd5de 100644
--- a/arch/sh/kernel/cpu/irq/ipr.c
+++ b/arch/sh/kernel/cpu/irq/ipr.c
@@ -57,31 +57,27 @@ static struct hw_interrupt_type ipr_irq_type = {
57 57
58static void disable_ipr_irq(unsigned int irq) 58static void disable_ipr_irq(unsigned int irq)
59{ 59{
60 unsigned long val, flags; 60 unsigned long val;
61 unsigned int addr = ipr_data[irq].addr; 61 unsigned int addr = ipr_data[irq].addr;
62 unsigned short mask = 0xffff ^ (0x0f << ipr_data[irq].shift); 62 unsigned short mask = 0xffff ^ (0x0f << ipr_data[irq].shift);
63 63
64 /* Set the priority in IPR to 0 */ 64 /* Set the priority in IPR to 0 */
65 local_irq_save(flags);
66 val = ctrl_inw(addr); 65 val = ctrl_inw(addr);
67 val &= mask; 66 val &= mask;
68 ctrl_outw(val, addr); 67 ctrl_outw(val, addr);
69 local_irq_restore(flags);
70} 68}
71 69
72static void enable_ipr_irq(unsigned int irq) 70static void enable_ipr_irq(unsigned int irq)
73{ 71{
74 unsigned long val, flags; 72 unsigned long val;
75 unsigned int addr = ipr_data[irq].addr; 73 unsigned int addr = ipr_data[irq].addr;
76 int priority = ipr_data[irq].priority; 74 int priority = ipr_data[irq].priority;
77 unsigned short value = (priority << ipr_data[irq].shift); 75 unsigned short value = (priority << ipr_data[irq].shift);
78 76
79 /* Set priority in IPR back to original value */ 77 /* Set priority in IPR back to original value */
80 local_irq_save(flags);
81 val = ctrl_inw(addr); 78 val = ctrl_inw(addr);
82 val |= value; 79 val |= value;
83 ctrl_outw(val, addr); 80 ctrl_outw(val, addr);
84 local_irq_restore(flags);
85} 81}
86 82
87static void mask_and_ack_ipr(unsigned int irq) 83static void mask_and_ack_ipr(unsigned int irq)
@@ -89,6 +85,7 @@ static void mask_and_ack_ipr(unsigned int irq)
89 disable_ipr_irq(irq); 85 disable_ipr_irq(irq);
90 86
91#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ 87#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
88 defined(CONFIG_CPU_SUBTYPE_SH7706) || \
92 defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) 89 defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
93 /* This is needed when we use edge triggered setting */ 90 /* This is needed when we use edge triggered setting */
94 /* XXX: Is it really needed? */ 91 /* XXX: Is it really needed? */
@@ -123,7 +120,7 @@ void __init init_IRQ(void)
123#ifndef CONFIG_CPU_SUBTYPE_SH7780 120#ifndef CONFIG_CPU_SUBTYPE_SH7780
124 make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY); 121 make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY);
125 make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY); 122 make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY);
126#if defined(CONFIG_SH_RTC) 123#ifdef RTC_IRQ
127 make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY); 124 make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY);
128#endif 125#endif
129 126
@@ -162,6 +159,7 @@ void __init init_IRQ(void)
162#endif 159#endif
163 160
164#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ 161#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
162 defined(CONFIG_CPU_SUBTYPE_SH7706) || \
165 defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) 163 defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
166 /* 164 /*
167 * Initialize the Interrupt Controller (INTC) 165 * Initialize the Interrupt Controller (INTC)
@@ -192,6 +190,8 @@ void __init init_IRQ(void)
192 /* Perform the machine specific initialisation */ 190 /* Perform the machine specific initialisation */
193 if (sh_mv.mv_init_irq != NULL) 191 if (sh_mv.mv_init_irq != NULL)
194 sh_mv.mv_init_irq(); 192 sh_mv.mv_init_irq();
193
194 irq_ctx_init(smp_processor_id());
195} 195}
196 196
197#if !defined(CONFIG_CPU_HAS_PINT_IRQ) 197#if !defined(CONFIG_CPU_HAS_PINT_IRQ)
diff --git a/arch/sh/boards/adx/irq_maskreg.c b/arch/sh/kernel/cpu/irq/maskreg.c
index 4b2abe5eb165..492db31b3cab 100644
--- a/arch/sh/boards/adx/irq_maskreg.c
+++ b/arch/sh/kernel/cpu/irq/maskreg.c
@@ -1,30 +1,23 @@
1/* 1/*
2 * linux/arch/sh/kernel/irq_maskreg.c 2 * Interrupt handling for Simple external interrupt mask register
3 * 3 *
4 * Copyright (C) 2001 A&D Co., Ltd. <http://www.aandd.co.jp> 4 * Copyright (C) 2001 A&D Co., Ltd. <http://www.aandd.co.jp>
5 * 5 *
6 * This file may be copied or modified under the terms of the GNU
7 * General Public License. See linux/COPYING for more information.
8 *
9 * Interrupt handling for Simple external interrupt mask register
10 *
11 * This is for the machine which have single 16 bit register 6 * This is for the machine which have single 16 bit register
12 * for masking external IRQ individually. 7 * for masking external IRQ individually.
13 * Each bit of the register is for masking each interrupt. 8 * Each bit of the register is for masking each interrupt.
9 *
10 * This file may be copied or modified under the terms of the GNU
11 * General Public License. See linux/COPYING for more information.
14 */ 12 */
15
16#include <linux/kernel.h> 13#include <linux/kernel.h>
17#include <linux/init.h> 14#include <linux/init.h>
18#include <linux/irq.h> 15#include <linux/irq.h>
19
20#include <asm/system.h> 16#include <asm/system.h>
21#include <asm/io.h> 17#include <asm/io.h>
22#include <asm/machvec.h>
23 18
24/* address of external interrupt mask register 19/* address of external interrupt mask register */
25 * address must be set prior to use these (maybe in init_XXX_irq()) 20unsigned long irq_mask_register;
26 * XXX : is it better to use .config than specifying it in code? */
27unsigned short *irq_mask_register = 0;
28 21
29/* forward declaration */ 22/* forward declaration */
30static unsigned int startup_maskreg_irq(unsigned int irq); 23static unsigned int startup_maskreg_irq(unsigned int irq);
@@ -36,7 +29,7 @@ static void end_maskreg_irq(unsigned int irq);
36 29
37/* hw_interrupt_type */ 30/* hw_interrupt_type */
38static struct hw_interrupt_type maskreg_irq_type = { 31static struct hw_interrupt_type maskreg_irq_type = {
39 .typename = " Mask Register", 32 .typename = "Mask Register",
40 .startup = startup_maskreg_irq, 33 .startup = startup_maskreg_irq,
41 .shutdown = shutdown_maskreg_irq, 34 .shutdown = shutdown_maskreg_irq,
42 .enable = enable_maskreg_irq, 35 .enable = enable_maskreg_irq,
@@ -47,7 +40,7 @@ static struct hw_interrupt_type maskreg_irq_type = {
47 40
48/* actual implementatin */ 41/* actual implementatin */
49static unsigned int startup_maskreg_irq(unsigned int irq) 42static unsigned int startup_maskreg_irq(unsigned int irq)
50{ 43{
51 enable_maskreg_irq(irq); 44 enable_maskreg_irq(irq);
52 return 0; /* never anything pending */ 45 return 0; /* never anything pending */
53} 46}
@@ -59,32 +52,26 @@ static void shutdown_maskreg_irq(unsigned int irq)
59 52
60static void disable_maskreg_irq(unsigned int irq) 53static void disable_maskreg_irq(unsigned int irq)
61{ 54{
62 if (irq_mask_register) { 55 unsigned short val, mask = 0x01 << irq;
63 unsigned long flags; 56
64 unsigned short val, mask = 0x01 << irq; 57 BUG_ON(!irq_mask_register);
65 58
66 /* Set "irq"th bit */ 59 /* Set "irq"th bit */
67 local_irq_save(flags); 60 val = ctrl_inw(irq_mask_register);
68 val = ctrl_inw((unsigned long)irq_mask_register); 61 val |= mask;
69 val |= mask; 62 ctrl_outw(val, irq_mask_register);
70 ctrl_outw(val, (unsigned long)irq_mask_register);
71 local_irq_restore(flags);
72 }
73} 63}
74 64
75static void enable_maskreg_irq(unsigned int irq) 65static void enable_maskreg_irq(unsigned int irq)
76{ 66{
77 if (irq_mask_register) { 67 unsigned short val, mask = ~(0x01 << irq);
78 unsigned long flags; 68
79 unsigned short val, mask = ~(0x01 << irq); 69 BUG_ON(!irq_mask_register);
80 70
81 /* Clear "irq"th bit */ 71 /* Clear "irq"th bit */
82 local_irq_save(flags); 72 val = ctrl_inw(irq_mask_register);
83 val = ctrl_inw((unsigned long)irq_mask_register); 73 val &= mask;
84 val &= mask; 74 ctrl_outw(val, irq_mask_register);
85 ctrl_outw(val, (unsigned long)irq_mask_register);
86 local_irq_restore(flags);
87 }
88} 75}
89 76
90static void mask_and_ack_maskreg(unsigned int irq) 77static void mask_and_ack_maskreg(unsigned int irq)
@@ -101,6 +88,6 @@ static void end_maskreg_irq(unsigned int irq)
101void make_maskreg_irq(unsigned int irq) 88void make_maskreg_irq(unsigned int irq)
102{ 89{
103 disable_irq_nosync(irq); 90 disable_irq_nosync(irq);
104 irq_desc[irq].chip = &maskreg_irq_type; 91 irq_desc[irq].handler = &maskreg_irq_type;
105 disable_maskreg_irq(irq); 92 disable_maskreg_irq(irq);
106} 93}
diff --git a/arch/sh/kernel/cpu/irq/pint.c b/arch/sh/kernel/cpu/irq/pint.c
index 80cd8108d36a..17f47b373d6e 100644
--- a/arch/sh/kernel/cpu/irq/pint.c
+++ b/arch/sh/kernel/cpu/irq/pint.c
@@ -48,26 +48,22 @@ static struct hw_interrupt_type pint_irq_type = {
48 48
49static void disable_pint_irq(unsigned int irq) 49static void disable_pint_irq(unsigned int irq)
50{ 50{
51 unsigned long val, flags; 51 unsigned long val;
52 52
53 local_irq_save(flags);
54 val = ctrl_inw(INTC_INTER); 53 val = ctrl_inw(INTC_INTER);
55 val &= ~(1 << (irq - PINT_IRQ_BASE)); 54 val &= ~(1 << (irq - PINT_IRQ_BASE));
56 ctrl_outw(val, INTC_INTER); /* disable PINTn */ 55 ctrl_outw(val, INTC_INTER); /* disable PINTn */
57 portcr_mask &= ~(3 << (irq - PINT_IRQ_BASE)*2); 56 portcr_mask &= ~(3 << (irq - PINT_IRQ_BASE)*2);
58 local_irq_restore(flags);
59} 57}
60 58
61static void enable_pint_irq(unsigned int irq) 59static void enable_pint_irq(unsigned int irq)
62{ 60{
63 unsigned long val, flags; 61 unsigned long val;
64 62
65 local_irq_save(flags);
66 val = ctrl_inw(INTC_INTER); 63 val = ctrl_inw(INTC_INTER);
67 val |= 1 << (irq - PINT_IRQ_BASE); 64 val |= 1 << (irq - PINT_IRQ_BASE);
68 ctrl_outw(val, INTC_INTER); /* enable PINTn */ 65 ctrl_outw(val, INTC_INTER); /* enable PINTn */
69 portcr_mask |= 3 << (irq - PINT_IRQ_BASE)*2; 66 portcr_mask |= 3 << (irq - PINT_IRQ_BASE)*2;
70 local_irq_restore(flags);
71} 67}
72 68
73static void mask_and_ack_pint(unsigned int irq) 69static void mask_and_ack_pint(unsigned int irq)
diff --git a/arch/sh/kernel/cpu/rtc.c b/arch/sh/kernel/cpu/rtc.c
deleted file mode 100644
index 4304cf75cfa2..000000000000
--- a/arch/sh/kernel/cpu/rtc.c
+++ /dev/null
@@ -1,128 +0,0 @@
1/*
2 * linux/arch/sh/kernel/rtc.c -- SH3 / SH4 on-chip RTC support
3 *
4 * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
5 * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
6 */
7
8#include <linux/init.h>
9#include <linux/kernel.h>
10#include <linux/sched.h>
11#include <linux/time.h>
12#include <linux/bcd.h>
13#include <asm/io.h>
14#include <asm/rtc.h>
15
16void sh_rtc_gettimeofday(struct timespec *ts)
17{
18 unsigned int sec128, sec, sec2, min, hr, wk, day, mon, yr, yr100, cf_bit;
19 unsigned long flags;
20
21 again:
22 do {
23 local_irq_save(flags);
24 ctrl_outb(0, RCR1); /* Clear CF-bit */
25 sec128 = ctrl_inb(R64CNT);
26 sec = ctrl_inb(RSECCNT);
27 min = ctrl_inb(RMINCNT);
28 hr = ctrl_inb(RHRCNT);
29 wk = ctrl_inb(RWKCNT);
30 day = ctrl_inb(RDAYCNT);
31 mon = ctrl_inb(RMONCNT);
32#if defined(CONFIG_CPU_SH4)
33 yr = ctrl_inw(RYRCNT);
34 yr100 = (yr >> 8);
35 yr &= 0xff;
36#else
37 yr = ctrl_inb(RYRCNT);
38 yr100 = (yr == 0x99) ? 0x19 : 0x20;
39#endif
40 sec2 = ctrl_inb(R64CNT);
41 cf_bit = ctrl_inb(RCR1) & RCR1_CF;
42 local_irq_restore(flags);
43 } while (cf_bit != 0 || ((sec128 ^ sec2) & RTC_BIT_INVERTED) != 0);
44
45 BCD_TO_BIN(yr100);
46 BCD_TO_BIN(yr);
47 BCD_TO_BIN(mon);
48 BCD_TO_BIN(day);
49 BCD_TO_BIN(hr);
50 BCD_TO_BIN(min);
51 BCD_TO_BIN(sec);
52
53 if (yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 ||
54 hr > 23 || min > 59 || sec > 59) {
55 printk(KERN_ERR
56 "SH RTC: invalid value, resetting to 1 Jan 2000\n");
57 local_irq_save(flags);
58 ctrl_outb(RCR2_RESET, RCR2); /* Reset & Stop */
59 ctrl_outb(0, RSECCNT);
60 ctrl_outb(0, RMINCNT);
61 ctrl_outb(0, RHRCNT);
62 ctrl_outb(6, RWKCNT);
63 ctrl_outb(1, RDAYCNT);
64 ctrl_outb(1, RMONCNT);
65#if defined(CONFIG_CPU_SH4)
66 ctrl_outw(0x2000, RYRCNT);
67#else
68 ctrl_outb(0, RYRCNT);
69#endif
70 ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start */
71 goto again;
72 }
73
74#if RTC_BIT_INVERTED != 0
75 if ((sec128 & RTC_BIT_INVERTED))
76 sec--;
77#endif
78
79 ts->tv_sec = mktime(yr100 * 100 + yr, mon, day, hr, min, sec);
80 ts->tv_nsec = ((sec128 * 1000000) / 128) * 1000;
81}
82
83/*
84 * Changed to only care about tv_sec, and not the full timespec struct
85 * (i.e. tv_nsec). It can easily be switched to timespec for future cpus
86 * that support setting usec or nsec RTC values.
87 */
88int sh_rtc_settimeofday(const time_t secs)
89{
90 int retval = 0;
91 int real_seconds, real_minutes, cmos_minutes;
92 unsigned long flags;
93
94 local_irq_save(flags);
95 ctrl_outb(RCR2_RESET, RCR2); /* Reset pre-scaler & stop RTC */
96
97 cmos_minutes = ctrl_inb(RMINCNT);
98 BCD_TO_BIN(cmos_minutes);
99
100 /*
101 * since we're only adjusting minutes and seconds,
102 * don't interfere with hour overflow. This avoids
103 * messing with unknown time zones but requires your
104 * RTC not to be off by more than 15 minutes
105 */
106 real_seconds = secs % 60;
107 real_minutes = secs / 60;
108 if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
109 real_minutes += 30; /* correct for half hour time zone */
110 real_minutes %= 60;
111
112 if (abs(real_minutes - cmos_minutes) < 30) {
113 BIN_TO_BCD(real_seconds);
114 BIN_TO_BCD(real_minutes);
115 ctrl_outb(real_seconds, RSECCNT);
116 ctrl_outb(real_minutes, RMINCNT);
117 } else {
118 printk(KERN_WARNING
119 "set_rtc_time: can't update from %d to %d\n",
120 cmos_minutes, real_minutes);
121 retval = -1;
122 }
123
124 ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start RTC */
125 local_irq_restore(flags);
126
127 return retval;
128}
diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile
index b54dbb9a0c86..58d3815695ff 100644
--- a/arch/sh/kernel/cpu/sh3/Makefile
+++ b/arch/sh/kernel/cpu/sh3/Makefile
@@ -4,10 +4,21 @@
4 4
5obj-y := ex.o probe.o 5obj-y := ex.o probe.o
6 6
7# CPU subtype setup
8obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o
9obj-$(CONFIG_CPU_SUBTYPE_SH7706) += setup-sh7709.o
10obj-$(CONFIG_CPU_SUBTYPE_SH7707) += setup-sh7709.o
11obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh7708.o
12obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh7709.o
13obj-$(CONFIG_CPU_SUBTYPE_SH7300) += setup-sh7300.o
14obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o
15
16# Primary on-chip clocks (common)
7clock-$(CONFIG_CPU_SH3) := clock-sh3.o 17clock-$(CONFIG_CPU_SH3) := clock-sh3.o
8clock-$(CONFIG_CPU_SUBTYPE_SH7300) := clock-sh7300.o 18clock-$(CONFIG_CPU_SUBTYPE_SH7300) := clock-sh7300.o
9clock-$(CONFIG_CPU_SUBTYPE_SH7705) := clock-sh7705.o 19clock-$(CONFIG_CPU_SUBTYPE_SH7705) := clock-sh7705.o
20clock-$(CONFIG_CPU_SUBTYPE_SH7706) := clock-sh7706.o
10clock-$(CONFIG_CPU_SUBTYPE_SH7709) := clock-sh7709.o 21clock-$(CONFIG_CPU_SUBTYPE_SH7709) := clock-sh7709.o
22clock-$(CONFIG_CPU_SUBTYPE_SH7710) := clock-sh7300.o
11 23
12obj-y += $(clock-y) 24obj-y += $(clock-y)
13
diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7706.c b/arch/sh/kernel/cpu/sh3/clock-sh7706.c
new file mode 100644
index 000000000000..0cf96f9833bc
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh3/clock-sh7706.c
@@ -0,0 +1,84 @@
1/*
2 * arch/sh/kernel/cpu/sh3/clock-sh7706.c
3 *
4 * SH7706 support for the clock framework
5 *
6 * Copyright (C) 2006 Takashi YOSHII
7 *
8 * Based on arch/sh/kernel/cpu/sh3/clock-sh7709.c
9 * Copyright (C) 2005 Andriy Skulysh
10 *
11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file "COPYING" in the main directory of this archive
13 * for more details.
14 */
15#include <linux/init.h>
16#include <linux/kernel.h>
17#include <asm/clock.h>
18#include <asm/freq.h>
19#include <asm/io.h>
20
21static int stc_multipliers[] = { 1, 2, 4, 1, 3, 6, 1, 1 };
22static int ifc_divisors[] = { 1, 2, 4, 1, 3, 1, 1, 1 };
23static int pfc_divisors[] = { 1, 2, 4, 1, 3, 6, 1, 1 };
24
25static void master_clk_init(struct clk *clk)
26{
27 int frqcr = ctrl_inw(FRQCR);
28 int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
29
30 clk->rate *= pfc_divisors[idx];
31}
32
33static struct clk_ops sh7706_master_clk_ops = {
34 .init = master_clk_init,
35};
36
37static void module_clk_recalc(struct clk *clk)
38{
39 int frqcr = ctrl_inw(FRQCR);
40 int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003);
41
42 clk->rate = clk->parent->rate / pfc_divisors[idx];
43}
44
45static struct clk_ops sh7706_module_clk_ops = {
46 .recalc = module_clk_recalc,
47};
48
49static void bus_clk_recalc(struct clk *clk)
50{
51 int frqcr = ctrl_inw(FRQCR);
52 int idx = ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4);
53
54 clk->rate = clk->parent->rate / stc_multipliers[idx];
55}
56
57static struct clk_ops sh7706_bus_clk_ops = {
58 .recalc = bus_clk_recalc,
59};
60
61static void cpu_clk_recalc(struct clk *clk)
62{
63 int frqcr = ctrl_inw(FRQCR);
64 int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2);
65
66 clk->rate = clk->parent->rate / ifc_divisors[idx];
67}
68
69static struct clk_ops sh7706_cpu_clk_ops = {
70 .recalc = cpu_clk_recalc,
71};
72
73static struct clk_ops *sh7706_clk_ops[] = {
74 &sh7706_master_clk_ops,
75 &sh7706_module_clk_ops,
76 &sh7706_bus_clk_ops,
77 &sh7706_cpu_clk_ops,
78};
79
80void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
81{
82 if (idx < ARRAY_SIZE(sh7706_clk_ops))
83 *ops = sh7706_clk_ops[idx];
84}
diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S
index cc04e9e239ff..44daf44833f9 100644
--- a/arch/sh/kernel/cpu/sh3/ex.S
+++ b/arch/sh/kernel/cpu/sh3/ex.S
@@ -84,8 +84,12 @@ ENTRY(interrupt_table)
84 .long do_IRQ ! rovi 84 .long do_IRQ ! rovi
85 .long do_IRQ 85 .long do_IRQ
86 .long do_IRQ /* 5E0 */ 86 .long do_IRQ /* 5E0 */
87#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ 87#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \
88 defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) 88 defined(CONFIG_CPU_SUBTYPE_SH7709) || \
89 defined(CONFIG_CPU_SUBTYPE_SH7706) || \
90 defined(CONFIG_CPU_SUBTYPE_SH7300) || \
91 defined(CONFIG_CPU_SUBTYPE_SH7705) || \
92 defined(CONFIG_CPU_SUBTYPE_SH7710)
89 .long do_IRQ ! 32 IRQ irq0 /* 600 */ 93 .long do_IRQ ! 32 IRQ irq0 /* 600 */
90 .long do_IRQ ! 33 irq1 94 .long do_IRQ ! 33 irq1
91 .long do_IRQ ! 34 irq2 95 .long do_IRQ ! 34 irq2
@@ -147,6 +151,51 @@ ENTRY(interrupt_table)
147 .long do_IRQ ! 62 PCC pcc0i 151 .long do_IRQ ! 62 PCC pcc0i
148 .long do_IRQ ! 63 pcc1i /* 9E0 */ 152 .long do_IRQ ! 63 pcc1i /* 9E0 */
149#endif 153#endif
154#if defined(CONFIG_CPU_SUBTYPE_SH7710)
155 .long exception_none ! 61 /* 9A0 */
156 .long exception_none ! 62
157 .long exception_none ! 63
158 .long exception_none ! 64 /* A00 */
159 .long exception_none ! 65
160 .long exception_none ! 66
161 .long exception_none ! 67
162 .long exception_none ! 68
163 .long exception_none ! 69
164 .long exception_none ! 70
165 .long exception_none ! 71
166 .long exception_none ! 72 /* B00 */
167 .long exception_none ! 73
168 .long exception_none ! 74
169 .long exception_none ! 75
170 .long do_IRQ ! 76 DMAC2 dei4 /* B80 */
171 .long do_IRQ ! 77 DMAC2 dei5
172 .long exception_none ! 78
173 .long do_IRQ ! 79 IPSEC ipseci /* BE0 */
174 .long do_IRQ ! 80 EDMAC eint0 /* C00 */
175 .long do_IRQ ! 81 EDMAC eint1
176 .long do_IRQ ! 82 EDMAC eint2
177 .long exception_none ! 83 /* C60 */
178 .long exception_none ! 84
179 .long exception_none ! 85
180 .long exception_none ! 86
181 .long exception_none ! 87
182 .long exception_none ! 88 /* D00 */
183 .long exception_none ! 89
184 .long exception_none ! 90
185 .long exception_none ! 91
186 .long exception_none ! 92
187 .long exception_none ! 93
188 .long exception_none ! 94
189 .long exception_none ! 95
190 .long do_IRQ ! 96 SIOF eri0 /* E00 */
191 .long do_IRQ ! 97 txi0
192 .long do_IRQ ! 98 rxi0
193 .long do_IRQ ! 99 cci0
194 .long do_IRQ ! 100 eri1 /* E80 */
195 .long do_IRQ ! 101 txi1
196 .long do_IRQ ! 102 rxi2
197 .long do_IRQ ! 103 cci3
198#endif
150#if defined(CONFIG_CPU_SUBTYPE_SH7300) 199#if defined(CONFIG_CPU_SUBTYPE_SH7300)
151 .long do_IRQ ! 64 200 .long do_IRQ ! 64
152 .long do_IRQ ! 65 201 .long do_IRQ ! 65
@@ -195,4 +244,3 @@ ENTRY(interrupt_table)
195 .long do_IRQ ! 108 244 .long do_IRQ ! 108
196#endif 245#endif
197#endif 246#endif
198
diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c
index 5cdc88638601..e67098836290 100644
--- a/arch/sh/kernel/cpu/sh3/probe.c
+++ b/arch/sh/kernel/cpu/sh3/probe.c
@@ -72,6 +72,12 @@ int __init detect_cpu_and_cache_system(void)
72 cpu_data->dcache.sets = 256; 72 cpu_data->dcache.sets = 256;
73 cpu_data->type = CPU_SH7729; 73 cpu_data->type = CPU_SH7729;
74 74
75#if defined(CONFIG_CPU_SUBTYPE_SH7706)
76 cpu_data->type = CPU_SH7706;
77#endif
78#if defined(CONFIG_CPU_SUBTYPE_SH7710)
79 cpu_data->type = CPU_SH7710;
80#endif
75#if defined(CONFIG_CPU_SUBTYPE_SH7705) 81#if defined(CONFIG_CPU_SUBTYPE_SH7705)
76 cpu_data->type = CPU_SH7705; 82 cpu_data->type = CPU_SH7705;
77 83
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7300.c b/arch/sh/kernel/cpu/sh3/setup-sh7300.c
new file mode 100644
index 000000000000..ab4d204bfba5
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7300.c
@@ -0,0 +1,43 @@
1/*
2 * SH7300 Setup
3 *
4 * Copyright (C) 2006 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
13#include <asm/sci.h>
14
15static struct plat_sci_port sci_platform_data[] = {
16 {
17 .mapbase = 0xa4430000,
18 .flags = UPF_BOOT_AUTOCONF,
19 .type = PORT_SCI,
20 .irqs = { 80, 80, 80, 80 },
21 }, {
22 .flags = 0,
23 }
24};
25
26static struct platform_device sci_device = {
27 .name = "sh-sci",
28 .id = -1,
29 .dev = {
30 .platform_data = sci_platform_data,
31 },
32};
33
34static struct platform_device *sh7300_devices[] __initdata = {
35 &sci_device,
36};
37
38static int __init sh7300_devices_setup(void)
39{
40 return platform_add_devices(sh7300_devices,
41 ARRAY_SIZE(sh7300_devices));
42}
43__initcall(sh7300_devices_setup);
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
new file mode 100644
index 000000000000..a8e41c5241fa
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c
@@ -0,0 +1,48 @@
1/*
2 * SH7705 Setup
3 *
4 * Copyright (C) 2006 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
13#include <asm/sci.h>
14
15static struct plat_sci_port sci_platform_data[] = {
16 {
17 .mapbase = 0xa4400000,
18 .flags = UPF_BOOT_AUTOCONF,
19 .type = PORT_SCIF,
20 .irqs = { 52, 53, 55, 54 },
21 }, {
22 .mapbase = 0xa4410000,
23 .flags = UPF_BOOT_AUTOCONF,
24 .type = PORT_SCIF,
25 .irqs = { 56, 57, 59, 58 },
26 }, {
27 .flags = 0,
28 }
29};
30
31static struct platform_device sci_device = {
32 .name = "sh-sci",
33 .id = -1,
34 .dev = {
35 .platform_data = sci_platform_data,
36 },
37};
38
39static struct platform_device *sh7705_devices[] __initdata = {
40 &sci_device,
41};
42
43static int __init sh7705_devices_setup(void)
44{
45 return platform_add_devices(sh7705_devices,
46 ARRAY_SIZE(sh7705_devices));
47}
48__initcall(sh7705_devices_setup);
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7708.c b/arch/sh/kernel/cpu/sh3/setup-sh7708.c
new file mode 100644
index 000000000000..f933723911ca
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7708.c
@@ -0,0 +1,43 @@
1/*
2 * SH7708 Setup
3 *
4 * Copyright (C) 2006 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
13#include <asm/sci.h>
14
15static struct plat_sci_port sci_platform_data[] = {
16 {
17 .mapbase = 0xfffffe80,
18 .flags = UPF_BOOT_AUTOCONF,
19 .type = PORT_SCI,
20 .irqs = { 23, 24, 25, 0 },
21 }, {
22 .flags = 0,
23 }
24};
25
26static struct platform_device sci_device = {
27 .name = "sh-sci",
28 .id = -1,
29 .dev = {
30 .platform_data = sci_platform_data,
31 },
32};
33
34static struct platform_device *sh7708_devices[] __initdata = {
35 &sci_device,
36};
37
38static int __init sh7708_devices_setup(void)
39{
40 return platform_add_devices(sh7708_devices,
41 ARRAY_SIZE(sh7708_devices));
42}
43__initcall(sh7708_devices_setup);
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7709.c b/arch/sh/kernel/cpu/sh3/setup-sh7709.c
new file mode 100644
index 000000000000..ff43ef2a1f0c
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7709.c
@@ -0,0 +1,53 @@
1/*
2 * SH7707/SH7709 Setup
3 *
4 * Copyright (C) 2006 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
13#include <asm/sci.h>
14
15static struct plat_sci_port sci_platform_data[] = {
16 {
17 .mapbase = 0xfffffe80,
18 .flags = UPF_BOOT_AUTOCONF,
19 .type = PORT_SCI,
20 .irqs = { 23, 24, 25, 0 },
21 }, {
22 .mapbase = 0xa4000150,
23 .flags = UPF_BOOT_AUTOCONF,
24 .type = PORT_SCIF,
25 .irqs = { 56, 57, 59, 58 },
26 }, {
27 .mapbase = 0xa4000140,
28 .flags = UPF_BOOT_AUTOCONF,
29 .type = PORT_IRDA,
30 .irqs = { 52, 53, 55, 54 },
31 }, {
32 .flags = 0,
33 }
34};
35
36static struct platform_device sci_device = {
37 .name = "sh-sci",
38 .id = -1,
39 .dev = {
40 .platform_data = sci_platform_data,
41 },
42};
43
44static struct platform_device *sh7709_devices[] __initdata = {
45 &sci_device,
46};
47
48static int __init sh7709_devices_setup(void)
49{
50 return platform_add_devices(sh7709_devices,
51 ARRAY_SIZE(sh7709_devices));
52}
53__initcall(sh7709_devices_setup);
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
new file mode 100644
index 000000000000..895f99ee6a95
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c
@@ -0,0 +1,43 @@
1/*
2 * SH7710 Setup
3 *
4 * Copyright (C) 2006 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
13#include <asm/sci.h>
14
15static struct plat_sci_port sci_platform_data[] = {
16 {
17 .mapbase = 0xa4400000,
18 .flags = UPF_BOOT_AUTOCONF,
19 .type = PORT_SCIF,
20 .irqs = { 52, 53, 55, 54 },
21 }, {
22 .flags = 0,
23 }
24};
25
26static struct platform_device sci_device = {
27 .name = "sh-sci",
28 .id = -1,
29 .dev = {
30 .platform_data = sci_platform_data,
31 },
32};
33
34static struct platform_device *sh7710_devices[] __initdata = {
35 &sci_device,
36};
37
38static int __init sh7710_devices_setup(void)
39{
40 return platform_add_devices(sh7710_devices,
41 ARRAY_SIZE(sh7710_devices));
42}
43__initcall(sh7710_devices_setup);
diff --git a/arch/sh/kernel/cpu/sh4/Makefile b/arch/sh/kernel/cpu/sh4/Makefile
index 3d5cafc71ae3..8dbf3895ece7 100644
--- a/arch/sh/kernel/cpu/sh4/Makefile
+++ b/arch/sh/kernel/cpu/sh4/Makefile
@@ -7,6 +7,16 @@ obj-y := ex.o probe.o
7obj-$(CONFIG_SH_FPU) += fpu.o 7obj-$(CONFIG_SH_FPU) += fpu.o
8obj-$(CONFIG_SH_STORE_QUEUES) += sq.o 8obj-$(CONFIG_SH_STORE_QUEUES) += sq.o
9 9
10# CPU subtype setup
11obj-$(CONFIG_CPU_SUBTYPE_SH7750) += setup-sh7750.o
12obj-$(CONFIG_CPU_SUBTYPE_SH7751) += setup-sh7750.o
13obj-$(CONFIG_CPU_SUBTYPE_SH7760) += setup-sh7760.o
14obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o
15obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o
16obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o
17obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o
18obj-$(CONFIG_CPU_SUBTYPE_SH4_202) += setup-sh4-202.o
19
10# Primary on-chip clocks (common) 20# Primary on-chip clocks (common)
11clock-$(CONFIG_CPU_SH4) := clock-sh4.o 21clock-$(CONFIG_CPU_SH4) := clock-sh4.o
12clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o 22clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o
diff --git a/arch/sh/kernel/cpu/sh4/ex.S b/arch/sh/kernel/cpu/sh4/ex.S
index 26a27df06505..7146893a6cca 100644
--- a/arch/sh/kernel/cpu/sh4/ex.S
+++ b/arch/sh/kernel/cpu/sh4/ex.S
@@ -72,6 +72,7 @@ ENTRY(interrupt_table)
72 .long do_IRQ ! 1110 72 .long do_IRQ ! 1110
73 .long exception_error 73 .long exception_error
74 ! Internal hardware 74 ! Internal hardware
75#ifndef CONFIG_CPU_SUBTYPE_SH7780
75 .long do_IRQ ! TMU0 tuni0 /* 400 */ 76 .long do_IRQ ! TMU0 tuni0 /* 400 */
76 .long do_IRQ ! TMU1 tuni1 77 .long do_IRQ ! TMU1 tuni1
77 .long do_IRQ ! TMU2 tuni2 78 .long do_IRQ ! TMU2 tuni2
@@ -122,6 +123,13 @@ ENTRY(interrupt_table)
122 .long do_IRQ ! 45 dmte5 123 .long do_IRQ ! 45 dmte5
123 .long do_IRQ ! 46 dmte6 124 .long do_IRQ ! 46 dmte6
124 .long do_IRQ ! 47 dmte7 /* 7E0 */ 125 .long do_IRQ ! 47 dmte7 /* 7E0 */
126#elif defined(CONFIG_CPU_SUBTYPE_SH7343)
127 .long do_IRQ ! 44 IIC1 ali /* 780 */
128 .long do_IRQ ! 45 tacki
129 .long do_IRQ ! 46 waiti
130 .long do_IRQ ! 47 dtei /* 7E0 */
131 .long do_IRQ ! 48 DMAC dei0 /* 800 */
132 .long do_IRQ ! 49 dei1 /* 820 */
125#else 133#else
126 .long exception_error ! 44 /* 780 */ 134 .long exception_error ! 44 /* 780 */
127 .long exception_error ! 45 135 .long exception_error ! 45
@@ -131,7 +139,8 @@ ENTRY(interrupt_table)
131#if defined(CONFIG_SH_FPU) 139#if defined(CONFIG_SH_FPU)
132 .long do_fpu_state_restore ! 48 /* 800 */ 140 .long do_fpu_state_restore ! 48 /* 800 */
133 .long do_fpu_state_restore ! 49 /* 820 */ 141 .long do_fpu_state_restore ! 49 /* 820 */
134#else 142#elif !defined(CONFIG_CPU_SUBTYPE_SH7343) && \
143 !defined(CONFIG_CPU_SUBTYPE_SH73180)
135 .long exception_error 144 .long exception_error
136 .long exception_error 145 .long exception_error
137#endif 146#endif
@@ -224,7 +233,7 @@ ENTRY(interrupt_table)
224 .long exception_error 233 .long exception_error
225 .long do_IRQ ! ADC adi 234 .long do_IRQ ! ADC adi
226 .long do_IRQ ! CMT cmti /* FA0 */ 235 .long do_IRQ ! CMT cmti /* FA0 */
227#elif defined(CONFIG_CPU_SUBTYPE_SH73180) 236#elif defined(CONFIG_CPU_SUBTYPE_SH73180) || defined(CONFIG_CPU_SUBTYPE_SH7343)
228 .long do_IRQ ! 50 0x840 237 .long do_IRQ ! 50 0x840
229 .long do_IRQ ! 51 0x860 238 .long do_IRQ ! 51 0x860
230 .long do_IRQ ! 52 0x880 239 .long do_IRQ ! 52 0x880
@@ -379,5 +388,168 @@ ENTRY(interrupt_table)
379 .long exception_error ! 141 0x13a0 388 .long exception_error ! 141 0x13a0
380 .long exception_error ! 142 0x13c0 389 .long exception_error ! 142 0x13c0
381 .long exception_error ! 143 0x13e0 390 .long exception_error ! 143 0x13e0
391#elif defined(CONFIG_CPU_SUBTYPE_SH7770)
392 .long do_IRQ ! 50 0x840
393 .long do_IRQ ! 51 0x860
394 .long do_IRQ ! 52 0x880
395 .long do_IRQ ! 53 0x8a0
396 .long do_IRQ ! 54 0x8c0
397 .long do_IRQ ! 55 0x8e0
398 .long do_IRQ ! 56 0x900
399 .long do_IRQ ! 57 0x920
400 .long do_IRQ ! 58 0x940
401 .long do_IRQ ! 59 0x960
402 .long do_IRQ ! 60 0x980
403 .long do_IRQ ! 61 0x9a0
404 .long do_IRQ ! 62 0x9c0
405 .long do_IRQ ! 63 0x9e0
406 .long do_IRQ ! 64 0xa00
407 .long do_IRQ ! 65 0xa20
408 .long do_IRQ ! 66 0xa4d
409 .long do_IRQ ! 67 0xa60
410 .long do_IRQ ! 68 0xa80
411 .long do_IRQ ! 69 0xaa0
412 .long do_IRQ ! 70 0xac0
413 .long do_IRQ ! 71 0xae0
414 .long do_IRQ ! 72 0xb00
415 .long do_IRQ ! 73 0xb20
416 .long do_IRQ ! 74 0xb40
417 .long do_IRQ ! 75 0xb60
418 .long do_IRQ ! 76 0xb80
419 .long do_IRQ ! 77 0xba0
420 .long do_IRQ ! 78 0xbc0
421 .long do_IRQ ! 79 0xbe0
422 .long do_IRQ ! 80 0xc00
423 .long do_IRQ ! 81 0xc20
424 .long do_IRQ ! 82 0xc40
425 .long do_IRQ ! 83 0xc60
426 .long do_IRQ ! 84 0xc80
427 .long do_IRQ ! 85 0xca0
428 .long do_IRQ ! 86 0xcc0
429 .long do_IRQ ! 87 0xce0
430 .long do_IRQ ! 88 0xd00
431 .long do_IRQ ! 89 0xd20
432 .long do_IRQ ! 90 0xd40
433 .long do_IRQ ! 91 0xd60
434 .long do_IRQ ! 92 0xd80
435 .long do_IRQ ! 93 0xda0
436 .long do_IRQ ! 94 0xdc0
437 .long do_IRQ ! 95 0xde0
438 .long do_IRQ ! 96 0xe00
439 .long do_IRQ ! 97 0xe20
440 .long do_IRQ ! 98 0xe40
441 .long do_IRQ ! 99 0xe60
442 .long do_IRQ ! 100 0xe80
443 .long do_IRQ ! 101 0xea0
444 .long do_IRQ ! 102 0xec0
445 .long do_IRQ ! 103 0xee0
446 .long do_IRQ ! 104 0xf00
447 .long do_IRQ ! 105 0xf20
448 .long do_IRQ ! 106 0xf40
449 .long do_IRQ ! 107 0xf60
450 .long do_IRQ ! 108 0xf80
451#endif
452#else
453 .long exception_error /* 400 */
454 .long exception_error
455 .long exception_error
456 .long exception_error
457 .long do_IRQ ! RTC ati
458 .long do_IRQ ! pri
459 .long do_IRQ ! cui
460 .long exception_error
461 .long exception_error /* 500 */
462 .long exception_error
463 .long exception_error
464 .long do_IRQ ! WDT iti /* 560 */
465 .long do_IRQ ! TMU-ch0
466 .long do_IRQ ! TMU-ch1
467 .long do_IRQ ! TMU-ch2
468 .long do_IRQ ! ticpi2 /* 5E0 */
469 .long do_IRQ ! 32 Hitachi UDI /* 600 */
470 .long exception_error
471 .long do_IRQ ! 34 DMAC dmte0
472 .long do_IRQ ! 35 dmte1
473 .long do_IRQ ! 36 dmte2
474 .long do_IRQ ! 37 dmte3
475 .long do_IRQ ! 38 dmae
476 .long exception_error ! 39 /* 6E0 */
477 .long do_IRQ ! 40 SCIF-ch0 eri /* 700 */
478 .long do_IRQ ! 41 rxi
479 .long do_IRQ ! 42 bri
480 .long do_IRQ ! 43 txi
481 .long do_IRQ ! 44 DMAC dmte4 /* 780 */
482 .long do_IRQ ! 45 dmte5
483 .long do_IRQ ! 46 dmte6
484 .long do_IRQ ! 47 dmte7 /* 7E0 */
485#if defined(CONFIG_SH_FPU)
486 .long do_fpu_state_restore ! 48 /* 800 */
487 .long do_fpu_state_restore ! 49 /* 820 */
488#else
489 .long exception_error
490 .long exception_error
491#endif
492 .long exception_error /* 840 */
493 .long exception_error
494 .long exception_error
495 .long exception_error
496 .long exception_error
497 .long exception_error
498 .long do_IRQ ! 56 CMT /* 900 */
499 .long exception_error
500 .long exception_error
501 .long exception_error
502 .long do_IRQ ! 60 HAC
503 .long exception_error
504 .long exception_error
505 .long exception_error
506 .long do_IRQ ! PCI serr /* A00 */
507 .long do_IRQ ! INTA
508 .long do_IRQ ! INTB
509 .long do_IRQ ! INTC
510 .long do_IRQ ! INTD
511 .long do_IRQ ! err
512 .long do_IRQ ! pwd3
513 .long do_IRQ ! pwd2
514 .long do_IRQ ! pwd1 /* B00 */
515 .long do_IRQ ! pwd0
516 .long exception_error
517 .long exception_error
518 .long do_IRQ ! SCIF-ch1 eri /* B80 */
519 .long do_IRQ ! rxi
520 .long do_IRQ ! bri
521 .long do_IRQ ! txi
522 .long do_IRQ ! SIOF /* C00 */
523 .long exception_error
524 .long exception_error
525 .long exception_error
526 .long do_IRQ ! HSPI /* C80 */
527 .long exception_error
528 .long exception_error
529 .long exception_error
530 .long do_IRQ ! MMCIF fatat /* D00 */
531 .long do_IRQ ! tran
532 .long do_IRQ ! err
533 .long do_IRQ ! frdy
534 .long do_IRQ ! DMAC dmint8 /* D80 */
535 .long do_IRQ ! dmint9
536 .long do_IRQ ! dmint10
537 .long do_IRQ ! dmint11
538 .long do_IRQ ! TMU-ch3 /* E00 */
539 .long do_IRQ ! TMU-ch4
540 .long do_IRQ ! TMU-ch5
541 .long exception_error
542 .long do_IRQ ! SSI
543 .long exception_error
544 .long exception_error
545 .long exception_error
546 .long do_IRQ ! FLCTL flste /* F00 */
547 .long do_IRQ ! fltend
548 .long do_IRQ ! fltrq0
549 .long do_IRQ ! fltrq1
550 .long do_IRQ ! GPIO gpioi0 /* F80 */
551 .long do_IRQ ! gpioi1
552 .long do_IRQ ! gpioi2
553 .long do_IRQ ! gpioi3
382#endif 554#endif
383 555
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index 42427b79697b..c294de1e14a3 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * CPU Subtype Probing for SH-4. 4 * CPU Subtype Probing for SH-4.
5 * 5 *
6 * Copyright (C) 2001, 2002, 2003, 2004 Paul Mundt 6 * Copyright (C) 2001 - 2006 Paul Mundt
7 * Copyright (C) 2003 Richard Curnow 7 * Copyright (C) 2003 Richard Curnow
8 * 8 *
9 * This file is subject to the terms and conditions of the GNU General Public 9 * This file is subject to the terms and conditions of the GNU General Public
@@ -29,7 +29,7 @@ int __init detect_cpu_and_cache_system(void)
29 [9] = (1 << 16) 29 [9] = (1 << 16)
30 }; 30 };
31 31
32 pvr = (ctrl_inl(CCN_PVR) >> 8) & 0xffff; 32 pvr = (ctrl_inl(CCN_PVR) >> 8) & 0xffffff;
33 prr = (ctrl_inl(CCN_PRR) >> 4) & 0xff; 33 prr = (ctrl_inl(CCN_PRR) >> 4) & 0xff;
34 cvr = (ctrl_inl(CCN_CVR)); 34 cvr = (ctrl_inl(CCN_CVR));
35 35
@@ -38,7 +38,6 @@ int __init detect_cpu_and_cache_system(void)
38 */ 38 */
39 cpu_data->icache.way_incr = (1 << 13); 39 cpu_data->icache.way_incr = (1 << 13);
40 cpu_data->icache.entry_shift = 5; 40 cpu_data->icache.entry_shift = 5;
41 cpu_data->icache.entry_mask = 0x1fe0;
42 cpu_data->icache.sets = 256; 41 cpu_data->icache.sets = 256;
43 cpu_data->icache.ways = 1; 42 cpu_data->icache.ways = 1;
44 cpu_data->icache.linesz = L1_CACHE_BYTES; 43 cpu_data->icache.linesz = L1_CACHE_BYTES;
@@ -48,13 +47,29 @@ int __init detect_cpu_and_cache_system(void)
48 */ 47 */
49 cpu_data->dcache.way_incr = (1 << 14); 48 cpu_data->dcache.way_incr = (1 << 14);
50 cpu_data->dcache.entry_shift = 5; 49 cpu_data->dcache.entry_shift = 5;
51 cpu_data->dcache.entry_mask = 0x3fe0;
52 cpu_data->dcache.sets = 512; 50 cpu_data->dcache.sets = 512;
53 cpu_data->dcache.ways = 1; 51 cpu_data->dcache.ways = 1;
54 cpu_data->dcache.linesz = L1_CACHE_BYTES; 52 cpu_data->dcache.linesz = L1_CACHE_BYTES;
55 53
56 /* Set the FPU flag, virtually all SH-4's have one */ 54 /*
57 cpu_data->flags |= CPU_HAS_FPU; 55 * Setup some generic flags we can probe
56 * (L2 and DSP detection only work on SH-4A)
57 */
58 if (((pvr >> 16) & 0xff) == 0x10) {
59 if ((cvr & 0x02000000) == 0)
60 cpu_data->flags |= CPU_HAS_L2_CACHE;
61 if ((cvr & 0x10000000) == 0)
62 cpu_data->flags |= CPU_HAS_DSP;
63
64 cpu_data->flags |= CPU_HAS_LLSC;
65 }
66
67 /* FPU detection works for everyone */
68 if ((cvr & 0x20000000) == 1)
69 cpu_data->flags |= CPU_HAS_FPU;
70
71 /* Mask off the upper chip ID */
72 pvr &= 0xffff;
58 73
59 /* 74 /*
60 * Probe the underlying processor version/revision and 75 * Probe the underlying processor version/revision and
@@ -63,56 +78,101 @@ int __init detect_cpu_and_cache_system(void)
63 switch (pvr) { 78 switch (pvr) {
64 case 0x205: 79 case 0x205:
65 cpu_data->type = CPU_SH7750; 80 cpu_data->type = CPU_SH7750;
66 cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_PERF_COUNTER; 81 cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU |
82 CPU_HAS_PERF_COUNTER | CPU_HAS_PTEA;
67 break; 83 break;
68 case 0x206: 84 case 0x206:
69 cpu_data->type = CPU_SH7750S; 85 cpu_data->type = CPU_SH7750S;
70 cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_PERF_COUNTER; 86 cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU |
87 CPU_HAS_PERF_COUNTER | CPU_HAS_PTEA;
71 break; 88 break;
72 case 0x1100: 89 case 0x1100:
73 cpu_data->type = CPU_SH7751; 90 cpu_data->type = CPU_SH7751;
91 cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA;
74 break; 92 break;
75 case 0x2000: 93 case 0x2000:
76 cpu_data->type = CPU_SH73180; 94 cpu_data->type = CPU_SH73180;
77 cpu_data->icache.ways = 4; 95 cpu_data->icache.ways = 4;
78 cpu_data->dcache.ways = 4; 96 cpu_data->dcache.ways = 4;
79 cpu_data->flags &= ~CPU_HAS_FPU; 97 cpu_data->flags |= CPU_HAS_LLSC;
98 break;
99 case 0x2001:
100 case 0x2004:
101 cpu_data->type = CPU_SH7770;
102 cpu_data->icache.ways = 4;
103 cpu_data->dcache.ways = 4;
104
105 cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_LLSC;
106 break;
107 case 0x2006:
108 case 0x200A:
109 if (prr == 0x61)
110 cpu_data->type = CPU_SH7781;
111 else
112 cpu_data->type = CPU_SH7780;
113
114 cpu_data->icache.ways = 4;
115 cpu_data->dcache.ways = 4;
116
117 cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
118 CPU_HAS_LLSC;
119 break;
120 case 0x3000:
121 case 0x3003:
122 cpu_data->type = CPU_SH7343;
123 cpu_data->icache.ways = 4;
124 cpu_data->dcache.ways = 4;
125 cpu_data->flags |= CPU_HAS_LLSC;
80 break; 126 break;
81 case 0x8000: 127 case 0x8000:
82 cpu_data->type = CPU_ST40RA; 128 cpu_data->type = CPU_ST40RA;
129 cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA;
83 break; 130 break;
84 case 0x8100: 131 case 0x8100:
85 cpu_data->type = CPU_ST40GX1; 132 cpu_data->type = CPU_ST40GX1;
133 cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA;
86 break; 134 break;
87 case 0x700: 135 case 0x700:
88 cpu_data->type = CPU_SH4_501; 136 cpu_data->type = CPU_SH4_501;
89 cpu_data->icache.ways = 2; 137 cpu_data->icache.ways = 2;
90 cpu_data->dcache.ways = 2; 138 cpu_data->dcache.ways = 2;
91 139 cpu_data->flags |= CPU_HAS_PTEA;
92 /* No FPU on the SH4-500 series.. */
93 cpu_data->flags &= ~CPU_HAS_FPU;
94 break; 140 break;
95 case 0x600: 141 case 0x600:
96 cpu_data->type = CPU_SH4_202; 142 cpu_data->type = CPU_SH4_202;
97 cpu_data->icache.ways = 2; 143 cpu_data->icache.ways = 2;
98 cpu_data->dcache.ways = 2; 144 cpu_data->dcache.ways = 2;
145 cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA;
99 break; 146 break;
100 case 0x500 ... 0x501: 147 case 0x500 ... 0x501:
101 switch (prr) { 148 switch (prr) {
102 case 0x10: cpu_data->type = CPU_SH7750R; break; 149 case 0x10:
103 case 0x11: cpu_data->type = CPU_SH7751R; break; 150 cpu_data->type = CPU_SH7750R;
104 case 0x50: cpu_data->type = CPU_SH7760; break; 151 break;
152 case 0x11:
153 cpu_data->type = CPU_SH7751R;
154 break;
155 case 0x50 ... 0x5f:
156 cpu_data->type = CPU_SH7760;
157 break;
105 } 158 }
106 159
107 cpu_data->icache.ways = 2; 160 cpu_data->icache.ways = 2;
108 cpu_data->dcache.ways = 2; 161 cpu_data->dcache.ways = 2;
109 162
163 cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA;
164
110 break; 165 break;
111 default: 166 default:
112 cpu_data->type = CPU_SH_NONE; 167 cpu_data->type = CPU_SH_NONE;
113 break; 168 break;
114 } 169 }
115 170
171#ifdef CONFIG_SH_DIRECT_MAPPED
172 cpu_data->icache.ways = 1;
173 cpu_data->dcache.ways = 1;
174#endif
175
116 /* 176 /*
117 * On anything that's not a direct-mapped cache, look to the CVR 177 * On anything that's not a direct-mapped cache, look to the CVR
118 * for I/D-cache specifics. 178 * for I/D-cache specifics.
@@ -121,18 +181,56 @@ int __init detect_cpu_and_cache_system(void)
121 size = sizes[(cvr >> 20) & 0xf]; 181 size = sizes[(cvr >> 20) & 0xf];
122 cpu_data->icache.way_incr = (size >> 1); 182 cpu_data->icache.way_incr = (size >> 1);
123 cpu_data->icache.sets = (size >> 6); 183 cpu_data->icache.sets = (size >> 6);
124 cpu_data->icache.entry_mask = 184
125 (cpu_data->icache.way_incr - (1 << 5));
126 } 185 }
127 186
187 /* Setup the rest of the I-cache info */
188 cpu_data->icache.entry_mask = cpu_data->icache.way_incr -
189 cpu_data->icache.linesz;
190
191 cpu_data->icache.way_size = cpu_data->icache.sets *
192 cpu_data->icache.linesz;
193
194 /* And the rest of the D-cache */
128 if (cpu_data->dcache.ways > 1) { 195 if (cpu_data->dcache.ways > 1) {
129 size = sizes[(cvr >> 16) & 0xf]; 196 size = sizes[(cvr >> 16) & 0xf];
130 cpu_data->dcache.way_incr = (size >> 1); 197 cpu_data->dcache.way_incr = (size >> 1);
131 cpu_data->dcache.sets = (size >> 6); 198 cpu_data->dcache.sets = (size >> 6);
132 cpu_data->dcache.entry_mask = 199 }
133 (cpu_data->dcache.way_incr - (1 << 5)); 200
201 cpu_data->dcache.entry_mask = cpu_data->dcache.way_incr -
202 cpu_data->dcache.linesz;
203
204 cpu_data->dcache.way_size = cpu_data->dcache.sets *
205 cpu_data->dcache.linesz;
206
207 /*
208 * Setup the L2 cache desc
209 *
210 * SH-4A's have an optional PIPT L2.
211 */
212 if (cpu_data->flags & CPU_HAS_L2_CACHE) {
213 /*
214 * Size calculation is much more sensible
215 * than it is for the L1.
216 *
217 * Sizes are 128KB, 258KB, 512KB, and 1MB.
218 */
219 size = (cvr & 0xf) << 17;
220
221 BUG_ON(!size);
222
223 cpu_data->scache.way_incr = (1 << 16);
224 cpu_data->scache.entry_shift = 5;
225 cpu_data->scache.ways = 4;
226 cpu_data->scache.linesz = L1_CACHE_BYTES;
227 cpu_data->scache.entry_mask =
228 (cpu_data->scache.way_incr - cpu_data->scache.linesz);
229 cpu_data->scache.sets = size /
230 (cpu_data->scache.linesz * cpu_data->scache.ways);
231 cpu_data->scache.way_size =
232 (cpu_data->scache.sets * cpu_data->scache.linesz);
134 } 233 }
135 234
136 return 0; 235 return 0;
137} 236}
138
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
new file mode 100644
index 000000000000..6e4e96541358
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c
@@ -0,0 +1,43 @@
1/*
2 * SH4-202 Setup
3 *
4 * Copyright (C) 2006 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
13#include <asm/sci.h>
14
15static struct plat_sci_port sci_platform_data[] = {
16 {
17 .mapbase = 0xffe80000,
18 .flags = UPF_BOOT_AUTOCONF,
19 .type = PORT_SCIF,
20 .irqs = { 40, 41, 43, 42 },
21 }, {
22 .flags = 0,
23 }
24};
25
26static struct platform_device sci_device = {
27 .name = "sh-sci",
28 .id = -1,
29 .dev = {
30 .platform_data = sci_platform_data,
31 },
32};
33
34static struct platform_device *sh4202_devices[] __initdata = {
35 &sci_device,
36};
37
38static int __init sh4202_devices_setup(void)
39{
40 return platform_add_devices(sh4202_devices,
41 ARRAY_SIZE(sh4202_devices));
42}
43__initcall(sh4202_devices_setup);
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh73180.c b/arch/sh/kernel/cpu/sh4/setup-sh73180.c
new file mode 100644
index 000000000000..cc9ea1e2e5df
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4/setup-sh73180.c
@@ -0,0 +1,43 @@
1/*
2 * SH73180 Setup
3 *
4 * Copyright (C) 2006 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
13#include <asm/sci.h>
14
15static struct plat_sci_port sci_platform_data[] = {
16 {
17 .mapbase = 0xffe80000,
18 .flags = UPF_BOOT_AUTOCONF,
19 .type = PORT_SCIF,
20 .irqs = { 80, 81, 83, 82 },
21 }, {
22 .flags = 0,
23 }
24};
25
26static struct platform_device sci_device = {
27 .name = "sh-sci",
28 .id = -1,
29 .dev = {
30 .platform_data = sci_platform_data,
31 },
32};
33
34static struct platform_device *sh73180_devices[] __initdata = {
35 &sci_device,
36};
37
38static int __init sh73180_devices_setup(void)
39{
40 return platform_add_devices(sh73180_devices,
41 ARRAY_SIZE(sh73180_devices));
42}
43__initcall(sh73180_devices_setup);
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7343.c b/arch/sh/kernel/cpu/sh4/setup-sh7343.c
new file mode 100644
index 000000000000..91d61cf91ba1
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7343.c
@@ -0,0 +1,43 @@
1/*
2 * SH7343 Setup
3 *
4 * Copyright (C) 2006 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
13#include <asm/sci.h>
14
15static struct plat_sci_port sci_platform_data[] = {
16 {
17 .mapbase = 0xffe00000,
18 .flags = UPF_BOOT_AUTOCONF,
19 .type = PORT_SCIF,
20 .irqs = { 80, 81, 83, 82 },
21 }, {
22 .flags = 0,
23 }
24};
25
26static struct platform_device sci_device = {
27 .name = "sh-sci",
28 .id = -1,
29 .dev = {
30 .platform_data = sci_platform_data,
31 },
32};
33
34static struct platform_device *sh7343_devices[] __initdata = {
35 &sci_device,
36};
37
38static int __init sh7343_devices_setup(void)
39{
40 return platform_add_devices(sh7343_devices,
41 ARRAY_SIZE(sh7343_devices));
42}
43__initcall(sh7343_devices_setup);
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
new file mode 100644
index 000000000000..50812d57c1c1
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c
@@ -0,0 +1,48 @@
1/*
2 * SH7750/SH7751 Setup
3 *
4 * Copyright (C) 2006 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
13#include <asm/sci.h>
14
15static struct plat_sci_port sci_platform_data[] = {
16 {
17 .mapbase = 0xffe00000,
18 .flags = UPF_BOOT_AUTOCONF,
19 .type = PORT_SCI,
20 .irqs = { 23, 24, 25, 0 },
21 }, {
22 .mapbase = 0xffe80000,
23 .flags = UPF_BOOT_AUTOCONF,
24 .type = PORT_SCIF,
25 .irqs = { 40, 41, 43, 42 },
26 }, {
27 .flags = 0,
28 }
29};
30
31static struct platform_device sci_device = {
32 .name = "sh-sci",
33 .id = -1,
34 .dev = {
35 .platform_data = sci_platform_data,
36 },
37};
38
39static struct platform_device *sh7750_devices[] __initdata = {
40 &sci_device,
41};
42
43static int __init sh7750_devices_setup(void)
44{
45 return platform_add_devices(sh7750_devices,
46 ARRAY_SIZE(sh7750_devices));
47}
48__initcall(sh7750_devices_setup);
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
new file mode 100644
index 000000000000..97f1c9af35d6
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
@@ -0,0 +1,53 @@
1/*
2 * SH7760 Setup
3 *
4 * Copyright (C) 2006 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
13#include <asm/sci.h>
14
15static struct plat_sci_port sci_platform_data[] = {
16 {
17 .mapbase = 0xfe600000,
18 .flags = UPF_BOOT_AUTOCONF,
19 .type = PORT_SCIF,
20 .irqs = { 52, 53, 55, 54 },
21 }, {
22 .mapbase = 0xfe610000,
23 .flags = UPF_BOOT_AUTOCONF,
24 .type = PORT_SCIF,
25 .irqs = { 72, 73, 75, 74 },
26 }, {
27 .mapbase = 0xfe620000,
28 .flags = UPF_BOOT_AUTOCONF,
29 .type = PORT_SCIF,
30 .irqs = { 76, 77, 79, 78 },
31 }, {
32 .flags = 0,
33 }
34};
35
36static struct platform_device sci_device = {
37 .name = "sh-sci",
38 .id = -1,
39 .dev = {
40 .platform_data = sci_platform_data,
41 },
42};
43
44static struct platform_device *sh7760_devices[] __initdata = {
45 &sci_device,
46};
47
48static int __init sh7760_devices_setup(void)
49{
50 return platform_add_devices(sh7760_devices,
51 ARRAY_SIZE(sh7760_devices));
52}
53__initcall(sh7760_devices_setup);
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7770.c b/arch/sh/kernel/cpu/sh4/setup-sh7770.c
new file mode 100644
index 000000000000..6a04cc5f5aca
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7770.c
@@ -0,0 +1,53 @@
1/*
2 * SH7770 Setup
3 *
4 * Copyright (C) 2006 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
13#include <asm/sci.h>
14
15static struct plat_sci_port sci_platform_data[] = {
16 {
17 .mapbase = 0xff923000,
18 .flags = UPF_BOOT_AUTOCONF,
19 .type = PORT_SCIF,
20 .irqs = { 61, 61, 61, 61 },
21 }, {
22 .mapbase = 0xff924000,
23 .flags = UPF_BOOT_AUTOCONF,
24 .type = PORT_SCIF,
25 .irqs = { 62, 62, 62, 62 },
26 }, {
27 .mapbase = 0xff925000,
28 .flags = UPF_BOOT_AUTOCONF,
29 .type = PORT_SCIF,
30 .irqs = { 63, 63, 63, 63 },
31 }, {
32 .flags = 0,
33 }
34};
35
36static struct platform_device sci_device = {
37 .name = "sh-sci",
38 .id = -1,
39 .dev = {
40 .platform_data = sci_platform_data,
41 },
42};
43
44static struct platform_device *sh7770_devices[] __initdata = {
45 &sci_device,
46};
47
48static int __init sh7770_devices_setup(void)
49{
50 return platform_add_devices(sh7770_devices,
51 ARRAY_SIZE(sh7770_devices));
52}
53__initcall(sh7770_devices_setup);
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7780.c b/arch/sh/kernel/cpu/sh4/setup-sh7780.c
new file mode 100644
index 000000000000..72493f259edc
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7780.c
@@ -0,0 +1,79 @@
1/*
2 * SH7780 Setup
3 *
4 * Copyright (C) 2006 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/platform_device.h>
11#include <linux/init.h>
12#include <linux/serial.h>
13#include <asm/sci.h>
14
15static struct resource rtc_resources[] = {
16 [0] = {
17 .start = 0xffe80000,
18 .end = 0xffe80000 + 0x58 - 1,
19 .flags = IORESOURCE_IO,
20 },
21 [1] = {
22 /* Period IRQ */
23 .start = 21,
24 .flags = IORESOURCE_IRQ,
25 },
26 [2] = {
27 /* Carry IRQ */
28 .start = 22,
29 .flags = IORESOURCE_IRQ,
30 },
31 [3] = {
32 /* Alarm IRQ */
33 .start = 23,
34 .flags = IORESOURCE_IRQ,
35 },
36};
37
38static struct platform_device rtc_device = {
39 .name = "sh-rtc",
40 .id = -1,
41 .num_resources = ARRAY_SIZE(rtc_resources),
42 .resource = rtc_resources,
43};
44
45static struct plat_sci_port sci_platform_data[] = {
46 {
47 .mapbase = 0xffe00000,
48 .flags = UPF_BOOT_AUTOCONF,
49 .type = PORT_SCIF,
50 .irqs = { 40, 41, 43, 42 },
51 }, {
52 .mapbase = 0xffe10000,
53 .flags = UPF_BOOT_AUTOCONF,
54 .type = PORT_SCIF,
55 .irqs = { 76, 77, 79, 78 },
56 }, {
57 .flags = 0,
58 }
59};
60
61static struct platform_device sci_device = {
62 .name = "sh-sci",
63 .id = -1,
64 .dev = {
65 .platform_data = sci_platform_data,
66 },
67};
68
69static struct platform_device *sh7780_devices[] __initdata = {
70 &rtc_device,
71 &sci_device,
72};
73
74static int __init sh7780_devices_setup(void)
75{
76 return platform_add_devices(sh7780_devices,
77 ARRAY_SIZE(sh7780_devices));
78}
79__initcall(sh7780_devices_setup);
diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c
index b09805f3ee23..7bcc73f9b8df 100644
--- a/arch/sh/kernel/cpu/sh4/sq.c
+++ b/arch/sh/kernel/cpu/sh4/sq.c
@@ -1,49 +1,52 @@
1/* 1/*
2 * arch/sh/kernel/cpu/sq.c 2 * arch/sh/kernel/cpu/sh4/sq.c
3 * 3 *
4 * General management API for SH-4 integrated Store Queues 4 * General management API for SH-4 integrated Store Queues
5 * 5 *
6 * Copyright (C) 2001, 2002, 2003, 2004 Paul Mundt 6 * Copyright (C) 2001 - 2006 Paul Mundt
7 * Copyright (C) 2001, 2002 M. R. Brown 7 * Copyright (C) 2001, 2002 M. R. Brown
8 * 8 *
9 * Some of this code has been adopted directly from the old arch/sh/mm/sq.c
10 * hack that was part of the LinuxDC project. For all intents and purposes,
11 * this is a completely new interface that really doesn't have much in common
12 * with the old zone-based approach at all. In fact, it's only listed here for
13 * general completeness.
14 *
15 * This file is subject to the terms and conditions of the GNU General Public 9 * This file is subject to the terms and conditions of the GNU General Public
16 * License. See the file "COPYING" in the main directory of this archive 10 * License. See the file "COPYING" in the main directory of this archive
17 * for more details. 11 * for more details.
18 */ 12 */
19#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/cpu.h>
15#include <linux/bitmap.h>
16#include <linux/sysdev.h>
20#include <linux/kernel.h> 17#include <linux/kernel.h>
21#include <linux/module.h> 18#include <linux/module.h>
22#include <linux/slab.h> 19#include <linux/slab.h>
23#include <linux/list.h>
24#include <linux/proc_fs.h>
25#include <linux/miscdevice.h>
26#include <linux/vmalloc.h> 20#include <linux/vmalloc.h>
27 21#include <linux/mm.h>
28#include <asm/io.h> 22#include <asm/io.h>
29#include <asm/page.h> 23#include <asm/page.h>
30#include <asm/mmu_context.h> 24#include <asm/cacheflush.h>
31#include <asm/cpu/sq.h> 25#include <asm/cpu/sq.h>
32 26
33static LIST_HEAD(sq_mapping_list); 27struct sq_mapping;
28
29struct sq_mapping {
30 const char *name;
31
32 unsigned long sq_addr;
33 unsigned long addr;
34 unsigned int size;
35
36 struct sq_mapping *next;
37};
38
39static struct sq_mapping *sq_mapping_list;
34static DEFINE_SPINLOCK(sq_mapping_lock); 40static DEFINE_SPINLOCK(sq_mapping_lock);
41static kmem_cache_t *sq_cache;
42static unsigned long *sq_bitmap;
35 43
36/** 44#define store_queue_barrier() \
37 * sq_flush - Flush (prefetch) the store queue cache 45do { \
38 * @addr: the store queue address to flush 46 (void)ctrl_inl(P4SEG_STORE_QUE); \
39 * 47 ctrl_outl(0, P4SEG_STORE_QUE + 0); \
40 * Executes a prefetch instruction on the specified store queue cache, 48 ctrl_outl(0, P4SEG_STORE_QUE + 8); \
41 * so that the cached data is written to physical memory. 49} while (0);
42 */
43inline void sq_flush(void *addr)
44{
45 __asm__ __volatile__ ("pref @%0" : : "r" (addr) : "memory");
46}
47 50
48/** 51/**
49 * sq_flush_range - Flush (prefetch) a specific SQ range 52 * sq_flush_range - Flush (prefetch) a specific SQ range
@@ -56,152 +59,73 @@ inline void sq_flush(void *addr)
56void sq_flush_range(unsigned long start, unsigned int len) 59void sq_flush_range(unsigned long start, unsigned int len)
57{ 60{
58 volatile unsigned long *sq = (unsigned long *)start; 61 volatile unsigned long *sq = (unsigned long *)start;
59 unsigned long dummy;
60 62
61 /* Flush the queues */ 63 /* Flush the queues */
62 for (len >>= 5; len--; sq += 8) 64 for (len >>= 5; len--; sq += 8)
63 sq_flush((void *)sq); 65 prefetchw((void *)sq);
64 66
65 /* Wait for completion */ 67 /* Wait for completion */
66 dummy = ctrl_inl(P4SEG_STORE_QUE); 68 store_queue_barrier();
67
68 ctrl_outl(0, P4SEG_STORE_QUE + 0);
69 ctrl_outl(0, P4SEG_STORE_QUE + 8);
70} 69}
71 70
72static struct sq_mapping *__sq_alloc_mapping(unsigned long virt, unsigned long phys, unsigned long size, const char *name) 71static inline void sq_mapping_list_add(struct sq_mapping *map)
73{ 72{
74 struct sq_mapping *map; 73 struct sq_mapping **p, *tmp;
75
76 if (virt + size > SQ_ADDRMAX)
77 return ERR_PTR(-ENOSPC);
78
79 map = kmalloc(sizeof(struct sq_mapping), GFP_KERNEL);
80 if (!map)
81 return ERR_PTR(-ENOMEM);
82 74
83 INIT_LIST_HEAD(&map->list); 75 spin_lock_irq(&sq_mapping_lock);
84 76
85 map->sq_addr = virt; 77 p = &sq_mapping_list;
86 map->addr = phys; 78 while ((tmp = *p) != NULL)
87 map->size = size + 1; 79 p = &tmp->next;
88 map->name = name;
89 80
90 list_add(&map->list, &sq_mapping_list); 81 map->next = tmp;
82 *p = map;
91 83
92 return map; 84 spin_unlock_irq(&sq_mapping_lock);
93} 85}
94 86
95static unsigned long __sq_get_next_addr(void) 87static inline void sq_mapping_list_del(struct sq_mapping *map)
96{ 88{
97 if (!list_empty(&sq_mapping_list)) { 89 struct sq_mapping **p, *tmp;
98 struct list_head *pos, *tmp; 90
99 91 spin_lock_irq(&sq_mapping_lock);
100 /* 92
101 * Read one off the list head, as it will have the highest 93 for (p = &sq_mapping_list; (tmp = *p); p = &tmp->next)
102 * mapped allocation. Set the next one up right above it. 94 if (tmp == map) {
103 * 95 *p = tmp->next;
104 * This is somewhat sub-optimal, as we don't look at 96 break;
105 * gaps between allocations or anything lower then the
106 * highest-level allocation.
107 *
108 * However, in the interest of performance and the general
109 * lack of desire to do constant list rebalancing, we don't
110 * worry about it.
111 */
112 list_for_each_safe(pos, tmp, &sq_mapping_list) {
113 struct sq_mapping *entry;
114
115 entry = list_entry(pos, typeof(*entry), list);
116
117 return entry->sq_addr + entry->size;
118 } 97 }
119 }
120 98
121 return P4SEG_STORE_QUE; 99 spin_unlock_irq(&sq_mapping_lock);
122} 100}
123 101
124/** 102static int __sq_remap(struct sq_mapping *map, unsigned long flags)
125 * __sq_remap - Perform a translation from the SQ to a phys addr
126 * @map: sq mapping containing phys and store queue addresses.
127 *
128 * Maps the store queue address specified in the mapping to the physical
129 * address specified in the mapping.
130 */
131static struct sq_mapping *__sq_remap(struct sq_mapping *map)
132{ 103{
133 unsigned long flags, pteh, ptel; 104#if defined(CONFIG_MMU)
134 struct vm_struct *vma; 105 struct vm_struct *vma;
135 pgprot_t pgprot;
136
137 /*
138 * Without an MMU (or with it turned off), this is much more
139 * straightforward, as we can just load up each queue's QACR with
140 * the physical address appropriately masked.
141 */
142
143 ctrl_outl(((map->addr >> 26) << 2) & 0x1c, SQ_QACR0);
144 ctrl_outl(((map->addr >> 26) << 2) & 0x1c, SQ_QACR1);
145 106
146#ifdef CONFIG_MMU
147 /*
148 * With an MMU on the other hand, things are slightly more involved.
149 * Namely, we have to have a direct mapping between the SQ addr and
150 * the associated physical address in the UTLB by way of setting up
151 * a virt<->phys translation by hand. We do this by simply specifying
152 * the SQ addr in UTLB.VPN and the associated physical address in
153 * UTLB.PPN.
154 *
155 * Notably, even though this is a special case translation, and some
156 * of the configuration bits are meaningless, we're still required
157 * to have a valid ASID context in PTEH.
158 *
159 * We could also probably get by without explicitly setting PTEA, but
160 * we do it here just for good measure.
161 */
162 spin_lock_irqsave(&sq_mapping_lock, flags);
163
164 pteh = map->sq_addr;
165 ctrl_outl((pteh & MMU_VPN_MASK) | get_asid(), MMU_PTEH);
166
167 ptel = map->addr & PAGE_MASK;
168 ctrl_outl(((ptel >> 28) & 0xe) | (ptel & 0x1), MMU_PTEA);
169
170 pgprot = pgprot_noncached(PAGE_KERNEL);
171
172 ptel &= _PAGE_FLAGS_HARDWARE_MASK;
173 ptel |= pgprot_val(pgprot);
174 ctrl_outl(ptel, MMU_PTEL);
175
176 __asm__ __volatile__ ("ldtlb" : : : "memory");
177
178 spin_unlock_irqrestore(&sq_mapping_lock, flags);
179
180 /*
181 * Next, we need to map ourselves in the kernel page table, so that
182 * future accesses after a TLB flush will be handled when we take a
183 * page fault.
184 *
185 * Theoretically we could just do this directly and not worry about
186 * setting up the translation by hand ahead of time, but for the
187 * cases where we want a one-shot SQ mapping followed by a quick
188 * writeout before we hit the TLB flush, we do it anyways. This way
189 * we at least save ourselves the initial page fault overhead.
190 */
191 vma = __get_vm_area(map->size, VM_ALLOC, map->sq_addr, SQ_ADDRMAX); 107 vma = __get_vm_area(map->size, VM_ALLOC, map->sq_addr, SQ_ADDRMAX);
192 if (!vma) 108 if (!vma)
193 return ERR_PTR(-ENOMEM); 109 return -ENOMEM;
194 110
195 vma->phys_addr = map->addr; 111 vma->phys_addr = map->addr;
196 112
197 if (remap_area_pages((unsigned long)vma->addr, vma->phys_addr, 113 if (remap_area_pages((unsigned long)vma->addr, vma->phys_addr,
198 map->size, pgprot_val(pgprot))) { 114 map->size, flags)) {
199 vunmap(vma->addr); 115 vunmap(vma->addr);
200 return NULL; 116 return -EAGAIN;
201 } 117 }
202#endif /* CONFIG_MMU */ 118#else
119 /*
120 * Without an MMU (or with it turned off), this is much more
121 * straightforward, as we can just load up each queue's QACR with
122 * the physical address appropriately masked.
123 */
124 ctrl_outl(((map->addr >> 26) << 2) & 0x1c, SQ_QACR0);
125 ctrl_outl(((map->addr >> 26) << 2) & 0x1c, SQ_QACR1);
126#endif
203 127
204 return map; 128 return 0;
205} 129}
206 130
207/** 131/**
@@ -209,42 +133,65 @@ static struct sq_mapping *__sq_remap(struct sq_mapping *map)
209 * @phys: Physical address of mapping. 133 * @phys: Physical address of mapping.
210 * @size: Length of mapping. 134 * @size: Length of mapping.
211 * @name: User invoking mapping. 135 * @name: User invoking mapping.
136 * @flags: Protection flags.
212 * 137 *
213 * Remaps the physical address @phys through the next available store queue 138 * Remaps the physical address @phys through the next available store queue
214 * address of @size length. @name is logged at boot time as well as through 139 * address of @size length. @name is logged at boot time as well as through
215 * the procfs interface. 140 * the sysfs interface.
216 *
217 * A pre-allocated and filled sq_mapping pointer is returned, and must be
218 * cleaned up with a call to sq_unmap() when the user is done with the
219 * mapping.
220 */ 141 */
221struct sq_mapping *sq_remap(unsigned long phys, unsigned int size, const char *name) 142unsigned long sq_remap(unsigned long phys, unsigned int size,
143 const char *name, unsigned long flags)
222{ 144{
223 struct sq_mapping *map; 145 struct sq_mapping *map;
224 unsigned long virt, end; 146 unsigned long end;
225 unsigned int psz; 147 unsigned int psz;
148 int ret, page;
226 149
227 /* Don't allow wraparound or zero size */ 150 /* Don't allow wraparound or zero size */
228 end = phys + size - 1; 151 end = phys + size - 1;
229 if (!size || end < phys) 152 if (unlikely(!size || end < phys))
230 return NULL; 153 return -EINVAL;
231 /* Don't allow anyone to remap normal memory.. */ 154 /* Don't allow anyone to remap normal memory.. */
232 if (phys < virt_to_phys(high_memory)) 155 if (unlikely(phys < virt_to_phys(high_memory)))
233 return NULL; 156 return -EINVAL;
234 157
235 phys &= PAGE_MASK; 158 phys &= PAGE_MASK;
159 size = PAGE_ALIGN(end + 1) - phys;
160
161 map = kmem_cache_alloc(sq_cache, GFP_KERNEL);
162 if (unlikely(!map))
163 return -ENOMEM;
164
165 map->addr = phys;
166 map->size = size;
167 map->name = name;
168
169 page = bitmap_find_free_region(sq_bitmap, 0x04000000,
170 get_order(map->size));
171 if (unlikely(page < 0)) {
172 ret = -ENOSPC;
173 goto out;
174 }
175
176 map->sq_addr = P4SEG_STORE_QUE + (page << PAGE_SHIFT);
177
178 ret = __sq_remap(map, flags);
179 if (unlikely(ret != 0))
180 goto out;
181
182 psz = (size + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
183 pr_info("sqremap: %15s [%4d page%s] va 0x%08lx pa 0x%08lx\n",
184 likely(map->name) ? map->name : "???",
185 psz, psz == 1 ? " " : "s",
186 map->sq_addr, map->addr);
236 187
237 size = PAGE_ALIGN(end + 1) - phys; 188 sq_mapping_list_add(map);
238 virt = __sq_get_next_addr();
239 psz = (size + (PAGE_SIZE - 1)) / PAGE_SIZE;
240 map = __sq_alloc_mapping(virt, phys, size, name);
241 189
242 printk("sqremap: %15s [%4d page%s] va 0x%08lx pa 0x%08lx\n", 190 return map->sq_addr;
243 map->name ? map->name : "???",
244 psz, psz == 1 ? " " : "s",
245 map->sq_addr, map->addr);
246 191
247 return __sq_remap(map); 192out:
193 kmem_cache_free(sq_cache, map);
194 return ret;
248} 195}
249 196
250/** 197/**
@@ -255,188 +202,198 @@ struct sq_mapping *sq_remap(unsigned long phys, unsigned int size, const char *n
255 * sq_remap(). Also frees up the pte that was previously inserted into 202 * sq_remap(). Also frees up the pte that was previously inserted into
256 * the kernel page table and discards the UTLB translation. 203 * the kernel page table and discards the UTLB translation.
257 */ 204 */
258void sq_unmap(struct sq_mapping *map) 205void sq_unmap(unsigned long vaddr)
259{ 206{
260 if (map->sq_addr > (unsigned long)high_memory) 207 struct sq_mapping **p, *map;
261 vfree((void *)(map->sq_addr & PAGE_MASK)); 208 struct vm_struct *vma;
209 int page;
262 210
263 list_del(&map->list); 211 for (p = &sq_mapping_list; (map = *p); p = &map->next)
264 kfree(map); 212 if (map->sq_addr == vaddr)
265} 213 break;
266 214
267/** 215 if (unlikely(!map)) {
268 * sq_clear - Clear a store queue range 216 printk("%s: bad store queue address 0x%08lx\n",
269 * @addr: Address to start clearing from. 217 __FUNCTION__, vaddr);
270 * @len: Length to clear. 218 return;
271 * 219 }
272 * A quick zero-fill implementation for clearing out memory that has been
273 * remapped through the store queues.
274 */
275void sq_clear(unsigned long addr, unsigned int len)
276{
277 int i;
278 220
279 /* Clear out both queues linearly */ 221 page = (map->sq_addr - P4SEG_STORE_QUE) >> PAGE_SHIFT;
280 for (i = 0; i < 8; i++) { 222 bitmap_release_region(sq_bitmap, page, get_order(map->size));
281 ctrl_outl(0, addr + i + 0); 223
282 ctrl_outl(0, addr + i + 8); 224#ifdef CONFIG_MMU
225 vma = remove_vm_area((void *)(map->sq_addr & PAGE_MASK));
226 if (!vma) {
227 printk(KERN_ERR "%s: bad address 0x%08lx\n",
228 __FUNCTION__, map->sq_addr);
229 return;
283 } 230 }
231#endif
232
233 sq_mapping_list_del(map);
284 234
285 sq_flush_range(addr, len); 235 kmem_cache_free(sq_cache, map);
286} 236}
287 237
288/** 238/*
289 * sq_vma_unmap - Unmap a VMA range 239 * Needlessly complex sysfs interface. Unfortunately it doesn't seem like
290 * @area: VMA containing range. 240 * there is any other easy way to add things on a per-cpu basis without
291 * @addr: Start of range. 241 * putting the directory entries somewhere stupid and having to create
292 * @len: Length of range. 242 * links in sysfs by hand back in to the per-cpu directories.
293 * 243 *
294 * Searches the sq_mapping_list for a mapping matching the sq addr @addr, 244 * Some day we may want to have an additional abstraction per store
295 * and subsequently frees up the entry. Further cleanup is done by generic 245 * queue, but considering the kobject hell we already have to deal with,
296 * code. 246 * it's simply not worth the trouble.
297 */ 247 */
298static void sq_vma_unmap(struct vm_area_struct *area, 248static struct kobject *sq_kobject[NR_CPUS];
299 unsigned long addr, size_t len)
300{
301 struct list_head *pos, *tmp;
302 249
303 list_for_each_safe(pos, tmp, &sq_mapping_list) { 250struct sq_sysfs_attr {
304 struct sq_mapping *entry; 251 struct attribute attr;
252 ssize_t (*show)(char *buf);
253 ssize_t (*store)(const char *buf, size_t count);
254};
305 255
306 entry = list_entry(pos, typeof(*entry), list); 256#define to_sq_sysfs_attr(attr) container_of(attr, struct sq_sysfs_attr, attr)
307 257
308 if (entry->sq_addr == addr) { 258static ssize_t sq_sysfs_show(struct kobject *kobj, struct attribute *attr,
309 /* 259 char *buf)
310 * We could probably get away without doing the tlb flush 260{
311 * here, as generic code should take care of most of this 261 struct sq_sysfs_attr *sattr = to_sq_sysfs_attr(attr);
312 * when unmapping the rest of the VMA range for us. Leave
313 * it in for added sanity for the time being..
314 */
315 __flush_tlb_page(get_asid(), entry->sq_addr & PAGE_MASK);
316 262
317 list_del(&entry->list); 263 if (likely(sattr->show))
318 kfree(entry); 264 return sattr->show(buf);
319 265
320 return; 266 return -EIO;
321 }
322 }
323} 267}
324 268
325/** 269static ssize_t sq_sysfs_store(struct kobject *kobj, struct attribute *attr,
326 * sq_vma_sync - Sync a VMA range 270 const char *buf, size_t count)
327 * @area: VMA containing range.
328 * @start: Start of range.
329 * @len: Length of range.
330 * @flags: Additional flags.
331 *
332 * Synchronizes an sq mapped range by flushing the store queue cache for
333 * the duration of the mapping.
334 *
335 * Used internally for user mappings, which must use msync() to prefetch
336 * the store queue cache.
337 */
338static int sq_vma_sync(struct vm_area_struct *area,
339 unsigned long start, size_t len, unsigned int flags)
340{ 271{
341 sq_flush_range(start, len); 272 struct sq_sysfs_attr *sattr = to_sq_sysfs_attr(attr);
342 273
343 return 0; 274 if (likely(sattr->store))
275 return sattr->store(buf, count);
276
277 return -EIO;
344} 278}
345 279
346static struct vm_operations_struct sq_vma_ops = { 280static ssize_t mapping_show(char *buf)
347 .unmap = sq_vma_unmap, 281{
348 .sync = sq_vma_sync, 282 struct sq_mapping **list, *entry;
349}; 283 char *p = buf;
350 284
351/** 285 for (list = &sq_mapping_list; (entry = *list); list = &entry->next)
352 * sq_mmap - mmap() for /dev/cpu/sq 286 p += sprintf(p, "%08lx-%08lx [%08lx]: %s\n",
353 * @file: unused. 287 entry->sq_addr, entry->sq_addr + entry->size,
354 * @vma: VMA to remap. 288 entry->addr, entry->name);
355 * 289
356 * Remap the specified vma @vma through the store queues, and setup associated 290 return p - buf;
357 * information for the new mapping. Also build up the page tables for the new 291}
358 * area. 292
359 */ 293static ssize_t mapping_store(const char *buf, size_t count)
360static int sq_mmap(struct file *file, struct vm_area_struct *vma)
361{ 294{
362 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; 295 unsigned long base = 0, len = 0;
363 unsigned long size = vma->vm_end - vma->vm_start;
364 struct sq_mapping *map;
365 296
366 /* 297 sscanf(buf, "%lx %lx", &base, &len);
367 * We're not interested in any arbitrary virtual address that has 298 if (!base)
368 * been stuck in the VMA, as we already know what addresses we 299 return -EIO;
369 * want. Save off the size, and reposition the VMA to begin at
370 * the next available sq address.
371 */
372 vma->vm_start = __sq_get_next_addr();
373 vma->vm_end = vma->vm_start + size;
374 300
375 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 301 if (likely(len)) {
302 int ret = sq_remap(base, len, "Userspace",
303 pgprot_val(PAGE_SHARED));
304 if (ret < 0)
305 return ret;
306 } else
307 sq_unmap(base);
376 308
377 vma->vm_flags |= VM_IO | VM_RESERVED; 309 return count;
310}
378 311
379 map = __sq_alloc_mapping(vma->vm_start, offset, size, "Userspace"); 312static struct sq_sysfs_attr mapping_attr =
313 __ATTR(mapping, 0644, mapping_show, mapping_store);
380 314
381 if (io_remap_pfn_range(vma, map->sq_addr, map->addr >> PAGE_SHIFT, 315static struct attribute *sq_sysfs_attrs[] = {
382 size, vma->vm_page_prot)) 316 &mapping_attr.attr,
383 return -EAGAIN; 317 NULL,
318};
384 319
385 vma->vm_ops = &sq_vma_ops; 320static struct sysfs_ops sq_sysfs_ops = {
321 .show = sq_sysfs_show,
322 .store = sq_sysfs_store,
323};
386 324
387 return 0; 325static struct kobj_type ktype_percpu_entry = {
388} 326 .sysfs_ops = &sq_sysfs_ops,
327 .default_attrs = sq_sysfs_attrs,
328};
389 329
390#ifdef CONFIG_PROC_FS 330static int __devinit sq_sysdev_add(struct sys_device *sysdev)
391static int sq_mapping_read_proc(char *buf, char **start, off_t off,
392 int len, int *eof, void *data)
393{ 331{
394 struct list_head *pos; 332 unsigned int cpu = sysdev->id;
395 char *p = buf; 333 struct kobject *kobj;
396 334
397 list_for_each_prev(pos, &sq_mapping_list) { 335 sq_kobject[cpu] = kzalloc(sizeof(struct kobject), GFP_KERNEL);
398 struct sq_mapping *entry; 336 if (unlikely(!sq_kobject[cpu]))
337 return -ENOMEM;
399 338
400 entry = list_entry(pos, typeof(*entry), list); 339 kobj = sq_kobject[cpu];
340 kobj->parent = &sysdev->kobj;
341 kobject_set_name(kobj, "%s", "sq");
342 kobj->ktype = &ktype_percpu_entry;
401 343
402 p += sprintf(p, "%08lx-%08lx [%08lx]: %s\n", entry->sq_addr, 344 return kobject_register(kobj);
403 entry->sq_addr + entry->size - 1, entry->addr,
404 entry->name);
405 }
406
407 return p - buf;
408} 345}
409#endif
410 346
411static struct file_operations sq_fops = { 347static int __devexit sq_sysdev_remove(struct sys_device *sysdev)
412 .owner = THIS_MODULE, 348{
413 .mmap = sq_mmap, 349 unsigned int cpu = sysdev->id;
414}; 350 struct kobject *kobj = sq_kobject[cpu];
415 351
416static struct miscdevice sq_dev = { 352 kobject_unregister(kobj);
417 .minor = STORE_QUEUE_MINOR, 353 return 0;
418 .name = "sq", 354}
419 .fops = &sq_fops, 355
356static struct sysdev_driver sq_sysdev_driver = {
357 .add = sq_sysdev_add,
358 .remove = __devexit_p(sq_sysdev_remove),
420}; 359};
421 360
422static int __init sq_api_init(void) 361static int __init sq_api_init(void)
423{ 362{
424 int ret; 363 unsigned int nr_pages = 0x04000000 >> PAGE_SHIFT;
364 unsigned int size = (nr_pages + (BITS_PER_LONG - 1)) / BITS_PER_LONG;
365 int ret = -ENOMEM;
366
425 printk(KERN_NOTICE "sq: Registering store queue API.\n"); 367 printk(KERN_NOTICE "sq: Registering store queue API.\n");
426 368
427 create_proc_read_entry("sq_mapping", 0, 0, sq_mapping_read_proc, 0); 369 sq_cache = kmem_cache_create("store_queue_cache",
370 sizeof(struct sq_mapping), 0, 0,
371 NULL, NULL);
372 if (unlikely(!sq_cache))
373 return ret;
428 374
429 ret = misc_register(&sq_dev); 375 sq_bitmap = kzalloc(size, GFP_KERNEL);
430 if (ret) 376 if (unlikely(!sq_bitmap))
431 remove_proc_entry("sq_mapping", NULL); 377 goto out;
378
379 ret = sysdev_driver_register(&cpu_sysdev_class, &sq_sysdev_driver);
380 if (unlikely(ret != 0))
381 goto out;
382
383 return 0;
384
385out:
386 kfree(sq_bitmap);
387 kmem_cache_destroy(sq_cache);
432 388
433 return ret; 389 return ret;
434} 390}
435 391
436static void __exit sq_api_exit(void) 392static void __exit sq_api_exit(void)
437{ 393{
438 misc_deregister(&sq_dev); 394 sysdev_driver_unregister(&cpu_sysdev_class, &sq_sysdev_driver);
439 remove_proc_entry("sq_mapping", NULL); 395 kfree(sq_bitmap);
396 kmem_cache_destroy(sq_cache);
440} 397}
441 398
442module_init(sq_api_init); 399module_init(sq_api_init);
@@ -445,11 +402,7 @@ module_exit(sq_api_exit);
445MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, M. R. Brown <mrbrown@0xd6.org>"); 402MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, M. R. Brown <mrbrown@0xd6.org>");
446MODULE_DESCRIPTION("Simple API for SH-4 integrated Store Queues"); 403MODULE_DESCRIPTION("Simple API for SH-4 integrated Store Queues");
447MODULE_LICENSE("GPL"); 404MODULE_LICENSE("GPL");
448MODULE_ALIAS_MISCDEV(STORE_QUEUE_MINOR);
449 405
450EXPORT_SYMBOL(sq_remap); 406EXPORT_SYMBOL(sq_remap);
451EXPORT_SYMBOL(sq_unmap); 407EXPORT_SYMBOL(sq_unmap);
452EXPORT_SYMBOL(sq_clear);
453EXPORT_SYMBOL(sq_flush);
454EXPORT_SYMBOL(sq_flush_range); 408EXPORT_SYMBOL(sq_flush_range);
455
diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c
index 1378db375e17..a00022722e9e 100644
--- a/arch/sh/kernel/early_printk.c
+++ b/arch/sh/kernel/early_printk.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 1999, 2000 Niibe Yutaka 4 * Copyright (C) 1999, 2000 Niibe Yutaka
5 * Copyright (C) 2002 M. R. Brown 5 * Copyright (C) 2002 M. R. Brown
6 * Copyright (C) 2004 Paul Mundt 6 * Copyright (C) 2004 - 2006 Paul Mundt
7 * 7 *
8 * This file is subject to the terms and conditions of the GNU General Public 8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive 9 * License. See the file "COPYING" in the main directory of this archive
@@ -49,7 +49,7 @@ static int __init sh_console_setup(struct console *co, char *options)
49 return 0; 49 return 0;
50} 50}
51 51
52static struct console early_console = { 52static struct console bios_console = {
53 .name = "bios", 53 .name = "bios",
54 .write = sh_console_write, 54 .write = sh_console_write,
55 .setup = sh_console_setup, 55 .setup = sh_console_setup,
@@ -59,34 +59,43 @@ static struct console early_console = {
59#endif 59#endif
60 60
61#ifdef CONFIG_EARLY_SCIF_CONSOLE 61#ifdef CONFIG_EARLY_SCIF_CONSOLE
62#include <linux/serial_core.h>
63#include "../../../drivers/serial/sh-sci.h"
64
65#ifdef CONFIG_CPU_SH4
62#define SCIF_REG 0xffe80000 66#define SCIF_REG 0xffe80000
67#elif defined(CONFIG_CPU_SUBTYPE_SH72060)
68#define SCIF_REG 0xfffe9800
69#else
70#error "Undefined SCIF for this subtype"
71#endif
72
73static struct uart_port scif_port = {
74 .mapbase = SCIF_REG,
75 .membase = (char __iomem *)SCIF_REG,
76};
63 77
64static void scif_sercon_putc(int c) 78static void scif_sercon_putc(int c)
65{ 79{
66 while (!(ctrl_inw(SCIF_REG + 0x10) & 0x20)) ; 80 while (((sci_in(&scif_port, SCFDR) & 0x1f00 >> 8) == 16))
81 ;
67 82
68 ctrl_outb(c, SCIF_REG + 12); 83 sci_out(&scif_port, SCxTDR, c);
69 ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0x9f), SCIF_REG + 0x10); 84 sci_in(&scif_port, SCxSR);
85 sci_out(&scif_port, SCxSR, 0xf3 & ~(0x20 | 0x40));
86
87 while ((sci_in(&scif_port, SCxSR) & 0x40) == 0);
88 ;
70 89
71 if (c == '\n') 90 if (c == '\n')
72 scif_sercon_putc('\r'); 91 scif_sercon_putc('\r');
73} 92}
74 93
75static void scif_sercon_flush(void) 94static void scif_sercon_write(struct console *con, const char *s,
76{ 95 unsigned count)
77 ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0xbf), SCIF_REG + 0x10);
78
79 while (!(ctrl_inw(SCIF_REG + 0x10) & 0x40)) ;
80
81 ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0xbf), SCIF_REG + 0x10);
82}
83
84static void scif_sercon_write(struct console *con, const char *s, unsigned count)
85{ 96{
86 while (count-- > 0) 97 while (count-- > 0)
87 scif_sercon_putc(*s++); 98 scif_sercon_putc(*s++);
88
89 scif_sercon_flush();
90} 99}
91 100
92static int __init scif_sercon_setup(struct console *con, char *options) 101static int __init scif_sercon_setup(struct console *con, char *options)
@@ -96,7 +105,7 @@ static int __init scif_sercon_setup(struct console *con, char *options)
96 return 0; 105 return 0;
97} 106}
98 107
99static struct console early_console = { 108static struct console scif_console = {
100 .name = "sercon", 109 .name = "sercon",
101 .write = scif_sercon_write, 110 .write = scif_sercon_write,
102 .setup = scif_sercon_setup, 111 .setup = scif_sercon_setup,
@@ -104,7 +113,7 @@ static struct console early_console = {
104 .index = -1, 113 .index = -1,
105}; 114};
106 115
107void scif_sercon_init(int baud) 116static void scif_sercon_init(int baud)
108{ 117{
109 ctrl_outw(0, SCIF_REG + 8); 118 ctrl_outw(0, SCIF_REG + 8);
110 ctrl_outw(0, SCIF_REG); 119 ctrl_outw(0, SCIF_REG);
@@ -122,16 +131,61 @@ void scif_sercon_init(int baud)
122} 131}
123#endif 132#endif
124 133
125void __init enable_early_printk(void) 134/*
135 * Setup a default console, if more than one is compiled in, rely on the
136 * earlyprintk= parsing to give priority.
137 */
138static struct console *early_console =
139#ifdef CONFIG_SH_STANDARD_BIOS
140 &bios_console
141#elif defined(CONFIG_EARLY_SCIF_CONSOLE)
142 &scif_console
143#else
144 NULL
145#endif
146 ;
147
148static int __initdata keep_early;
149
150int __init setup_early_printk(char *opt)
126{ 151{
127#ifdef CONFIG_EARLY_SCIF_CONSOLE 152 char *space;
128 scif_sercon_init(115200); 153 char buf[256];
154
155 strlcpy(buf, opt, sizeof(buf));
156 space = strchr(buf, ' ');
157 if (space)
158 *space = 0;
159
160 if (strstr(buf, "keep"))
161 keep_early = 1;
162
163#ifdef CONFIG_SH_STANDARD_BIOS
164 if (!strncmp(buf, "bios", 4))
165 early_console = &bios_console;
166#endif
167#if defined(CONFIG_EARLY_SCIF_CONSOLE)
168 if (!strncmp(buf, "serial", 6)) {
169 early_console = &scif_console;
170
171#ifdef CONFIG_CPU_SH4
172 scif_sercon_init(115200);
173#endif
174 }
129#endif 175#endif
130 register_console(&early_console); 176
177 if (likely(early_console))
178 register_console(early_console);
179
180 return 1;
131} 181}
182__setup("earlyprintk=", setup_early_printk);
132 183
133void disable_early_printk(void) 184void __init disable_early_printk(void)
134{ 185{
135 unregister_console(&early_console); 186 if (!keep_early) {
187 printk("disabling early console\n");
188 unregister_console(early_console);
189 } else
190 printk("keeping early console\n");
136} 191}
137
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
index 7dfd2ba75f7f..fe8221855b28 100644
--- a/arch/sh/kernel/entry.S
+++ b/arch/sh/kernel/entry.S
@@ -18,24 +18,6 @@
18#include <asm/cpu/mmu_context.h> 18#include <asm/cpu/mmu_context.h>
19#include <asm/unistd.h> 19#include <asm/unistd.h>
20 20
21#if !defined(CONFIG_NFSD) && !defined(CONFIG_NFSD_MODULE)
22#define sys_nfsservctl sys_ni_syscall
23#endif
24
25#if !defined(CONFIG_MMU)
26#define sys_madvise sys_ni_syscall
27#define sys_readahead sys_ni_syscall
28#define sys_mprotect sys_ni_syscall
29#define sys_msync sys_ni_syscall
30#define sys_mlock sys_ni_syscall
31#define sys_munlock sys_ni_syscall
32#define sys_mlockall sys_ni_syscall
33#define sys_munlockall sys_ni_syscall
34#define sys_mremap sys_ni_syscall
35#define sys_mincore sys_ni_syscall
36#define sys_remap_file_pages sys_ni_syscall
37#endif
38
39! NOTE: 21! NOTE:
40! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address 22! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
41! to be jumped is too far, but it causes illegal slot exception. 23! to be jumped is too far, but it causes illegal slot exception.
@@ -326,7 +308,7 @@ ENTRY(exception_error)
326 .align 2 308 .align 2
327ret_from_exception: 309ret_from_exception:
328 preempt_stop() 310 preempt_stop()
329ret_from_irq: 311ENTRY(ret_from_irq)
330 ! 312 !
331 mov #OFF_SR, r0 313 mov #OFF_SR, r0
332 mov.l @(r0,r15), r0 ! get status register 314 mov.l @(r0,r15), r0 ! get status register
@@ -389,11 +371,12 @@ work_pending:
389 ! r8: current_thread_info 371 ! r8: current_thread_info
390 ! t: result of "tst #_TIF_NEED_RESCHED, r0" 372 ! t: result of "tst #_TIF_NEED_RESCHED, r0"
391 bf/s work_resched 373 bf/s work_resched
392 tst #_TIF_SIGPENDING, r0 374 tst #(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r0
393work_notifysig: 375work_notifysig:
394 bt/s restore_all 376 bt/s restore_all
395 mov r15, r4 377 mov r15, r4
396 mov #0, r5 378 mov r12, r5 ! set arg1(save_r0)
379 mov r0, r6
397 mov.l 2f, r1 380 mov.l 2f, r1
398 mova restore_all, r0 381 mova restore_all, r0
399 jmp @r1 382 jmp @r1
@@ -431,7 +414,7 @@ work_resched:
431 414
432 .align 2 415 .align 2
4331: .long schedule 4161: .long schedule
4342: .long do_signal 4172: .long do_notify_resume
435 418
436 .align 2 419 .align 2
437syscall_exit_work: 420syscall_exit_work:
@@ -552,6 +535,7 @@ syscall_call:
552 mov.l @r9, r8 535 mov.l @r9, r8
553 jsr @r8 ! jump to specific syscall handler 536 jsr @r8 ! jump to specific syscall handler
554 nop 537 nop
538 mov.l @(OFF_R0,r15), r12 ! save r0
555 mov.l r0, @(OFF_R0,r15) ! save the return value 539 mov.l r0, @(OFF_R0,r15) ! save the return value
556 ! 540 !
557syscall_exit: 541syscall_exit:
@@ -644,7 +628,7 @@ skip_restore:
644 ! 628 !
645#if defined(CONFIG_KGDB_NMI) 629#if defined(CONFIG_KGDB_NMI)
646 ! Clear in_nmi 630 ! Clear in_nmi
647 mov.l 4f, k0 631 mov.l 6f, k0
648 mov #0, k1 632 mov #0, k1
649 mov.b k1, @k0 633 mov.b k1, @k0
650#endif 634#endif
@@ -722,7 +706,7 @@ interrupt:
722! 706!
723! 707!
724 .align 2 708 .align 2
725handle_exception: 709ENTRY(handle_exception)
726 ! Using k0, k1 for scratch registers (r0_bank1, r1_bank), 710 ! Using k0, k1 for scratch registers (r0_bank1, r1_bank),
727 ! save all registers onto stack. 711 ! save all registers onto stack.
728 ! 712 !
@@ -732,8 +716,8 @@ handle_exception:
732 bt/s 1f ! It's a kernel to kernel transition. 716 bt/s 1f ! It's a kernel to kernel transition.
733 mov r15, k0 ! save original stack to k0 717 mov r15, k0 ! save original stack to k0
734 /* User space to kernel */ 718 /* User space to kernel */
735 mov #0x20, k1 719 mov #(THREAD_SIZE >> 8), k1
736 shll8 k1 ! k1 := 8192 (== THREAD_SIZE) 720 shll8 k1 ! k1 := THREAD_SIZE
737 add current, k1 721 add current, k1
738 mov k1, r15 ! change to kernel stack 722 mov k1, r15 ! change to kernel stack
739 ! 723 !
@@ -838,300 +822,3 @@ ENTRY(exception_none)
838 rts 822 rts
839 nop 823 nop
840 824
841 .data
842ENTRY(sys_call_table)
843 .long sys_ni_syscall /* 0 - old "setup()" system call*/
844 .long sys_exit
845 .long sys_fork
846 .long sys_read
847 .long sys_write
848 .long sys_open /* 5 */
849 .long sys_close
850 .long sys_waitpid
851 .long sys_creat
852 .long sys_link
853 .long sys_unlink /* 10 */
854 .long sys_execve
855 .long sys_chdir
856 .long sys_time
857 .long sys_mknod
858 .long sys_chmod /* 15 */
859 .long sys_lchown16
860 .long sys_ni_syscall /* old break syscall holder */
861 .long sys_stat
862 .long sys_lseek
863 .long sys_getpid /* 20 */
864 .long sys_mount
865 .long sys_oldumount
866 .long sys_setuid16
867 .long sys_getuid16
868 .long sys_stime /* 25 */
869 .long sys_ptrace
870 .long sys_alarm
871 .long sys_fstat
872 .long sys_pause
873 .long sys_utime /* 30 */
874 .long sys_ni_syscall /* old stty syscall holder */
875 .long sys_ni_syscall /* old gtty syscall holder */
876 .long sys_access
877 .long sys_nice
878 .long sys_ni_syscall /* 35 */ /* old ftime syscall holder */
879 .long sys_sync
880 .long sys_kill
881 .long sys_rename
882 .long sys_mkdir
883 .long sys_rmdir /* 40 */
884 .long sys_dup
885 .long sys_pipe
886 .long sys_times
887 .long sys_ni_syscall /* old prof syscall holder */
888 .long sys_brk /* 45 */
889 .long sys_setgid16
890 .long sys_getgid16
891 .long sys_signal
892 .long sys_geteuid16
893 .long sys_getegid16 /* 50 */
894 .long sys_acct
895 .long sys_umount /* recycled never used phys() */
896 .long sys_ni_syscall /* old lock syscall holder */
897 .long sys_ioctl
898 .long sys_fcntl /* 55 */
899 .long sys_ni_syscall /* old mpx syscall holder */
900 .long sys_setpgid
901 .long sys_ni_syscall /* old ulimit syscall holder */
902 .long sys_ni_syscall /* sys_olduname */
903 .long sys_umask /* 60 */
904 .long sys_chroot
905 .long sys_ustat
906 .long sys_dup2
907 .long sys_getppid
908 .long sys_getpgrp /* 65 */
909 .long sys_setsid
910 .long sys_sigaction
911 .long sys_sgetmask
912 .long sys_ssetmask
913 .long sys_setreuid16 /* 70 */
914 .long sys_setregid16
915 .long sys_sigsuspend
916 .long sys_sigpending
917 .long sys_sethostname
918 .long sys_setrlimit /* 75 */
919 .long sys_old_getrlimit
920 .long sys_getrusage
921 .long sys_gettimeofday
922 .long sys_settimeofday
923 .long sys_getgroups16 /* 80 */
924 .long sys_setgroups16
925 .long sys_ni_syscall /* sys_oldselect */
926 .long sys_symlink
927 .long sys_lstat
928 .long sys_readlink /* 85 */
929 .long sys_uselib
930 .long sys_swapon
931 .long sys_reboot
932 .long old_readdir
933 .long old_mmap /* 90 */
934 .long sys_munmap
935 .long sys_truncate
936 .long sys_ftruncate
937 .long sys_fchmod
938 .long sys_fchown16 /* 95 */
939 .long sys_getpriority
940 .long sys_setpriority
941 .long sys_ni_syscall /* old profil syscall holder */
942 .long sys_statfs
943 .long sys_fstatfs /* 100 */
944 .long sys_ni_syscall /* ioperm */
945 .long sys_socketcall
946 .long sys_syslog
947 .long sys_setitimer
948 .long sys_getitimer /* 105 */
949 .long sys_newstat
950 .long sys_newlstat
951 .long sys_newfstat
952 .long sys_uname
953 .long sys_ni_syscall /* 110 */ /* iopl */
954 .long sys_vhangup
955 .long sys_ni_syscall /* idle */
956 .long sys_ni_syscall /* vm86old */
957 .long sys_wait4
958 .long sys_swapoff /* 115 */
959 .long sys_sysinfo
960 .long sys_ipc
961 .long sys_fsync
962 .long sys_sigreturn
963 .long sys_clone /* 120 */
964 .long sys_setdomainname
965 .long sys_newuname
966 .long sys_ni_syscall /* sys_modify_ldt */
967 .long sys_adjtimex
968 .long sys_mprotect /* 125 */
969 .long sys_sigprocmask
970 .long sys_ni_syscall /* old "create_module" */
971 .long sys_init_module
972 .long sys_delete_module
973 .long sys_ni_syscall /* 130: old "get_kernel_syms" */
974 .long sys_quotactl
975 .long sys_getpgid
976 .long sys_fchdir
977 .long sys_bdflush
978 .long sys_sysfs /* 135 */
979 .long sys_personality
980 .long sys_ni_syscall /* for afs_syscall */
981 .long sys_setfsuid16
982 .long sys_setfsgid16
983 .long sys_llseek /* 140 */
984 .long sys_getdents
985 .long sys_select
986 .long sys_flock
987 .long sys_msync
988 .long sys_readv /* 145 */
989 .long sys_writev
990 .long sys_getsid
991 .long sys_fdatasync
992 .long sys_sysctl
993 .long sys_mlock /* 150 */
994 .long sys_munlock
995 .long sys_mlockall
996 .long sys_munlockall
997 .long sys_sched_setparam
998 .long sys_sched_getparam /* 155 */
999 .long sys_sched_setscheduler
1000 .long sys_sched_getscheduler
1001 .long sys_sched_yield
1002 .long sys_sched_get_priority_max
1003 .long sys_sched_get_priority_min /* 160 */
1004 .long sys_sched_rr_get_interval
1005 .long sys_nanosleep
1006 .long sys_mremap
1007 .long sys_setresuid16
1008 .long sys_getresuid16 /* 165 */
1009 .long sys_ni_syscall /* vm86 */
1010 .long sys_ni_syscall /* old "query_module" */
1011 .long sys_poll
1012 .long sys_nfsservctl
1013 .long sys_setresgid16 /* 170 */
1014 .long sys_getresgid16
1015 .long sys_prctl
1016 .long sys_rt_sigreturn
1017 .long sys_rt_sigaction
1018 .long sys_rt_sigprocmask /* 175 */
1019 .long sys_rt_sigpending
1020 .long sys_rt_sigtimedwait
1021 .long sys_rt_sigqueueinfo
1022 .long sys_rt_sigsuspend
1023 .long sys_pread_wrapper /* 180 */
1024 .long sys_pwrite_wrapper
1025 .long sys_chown16
1026 .long sys_getcwd
1027 .long sys_capget
1028 .long sys_capset /* 185 */
1029 .long sys_sigaltstack
1030 .long sys_sendfile
1031 .long sys_ni_syscall /* streams1 */
1032 .long sys_ni_syscall /* streams2 */
1033 .long sys_vfork /* 190 */
1034 .long sys_getrlimit
1035 .long sys_mmap2
1036 .long sys_truncate64
1037 .long sys_ftruncate64
1038 .long sys_stat64 /* 195 */
1039 .long sys_lstat64
1040 .long sys_fstat64
1041 .long sys_lchown
1042 .long sys_getuid
1043 .long sys_getgid /* 200 */
1044 .long sys_geteuid
1045 .long sys_getegid
1046 .long sys_setreuid
1047 .long sys_setregid
1048 .long sys_getgroups /* 205 */
1049 .long sys_setgroups
1050 .long sys_fchown
1051 .long sys_setresuid
1052 .long sys_getresuid
1053 .long sys_setresgid /* 210 */
1054 .long sys_getresgid
1055 .long sys_chown
1056 .long sys_setuid
1057 .long sys_setgid
1058 .long sys_setfsuid /* 215 */
1059 .long sys_setfsgid
1060 .long sys_pivot_root
1061 .long sys_mincore
1062 .long sys_madvise
1063 .long sys_getdents64 /* 220 */
1064 .long sys_fcntl64
1065 .long sys_ni_syscall /* reserved for TUX */
1066 .long sys_ni_syscall /* Reserved for Security */
1067 .long sys_gettid
1068 .long sys_readahead /* 225 */
1069 .long sys_setxattr
1070 .long sys_lsetxattr
1071 .long sys_fsetxattr
1072 .long sys_getxattr
1073 .long sys_lgetxattr /* 230 */
1074 .long sys_fgetxattr
1075 .long sys_listxattr
1076 .long sys_llistxattr
1077 .long sys_flistxattr
1078 .long sys_removexattr /* 235 */
1079 .long sys_lremovexattr
1080 .long sys_fremovexattr
1081 .long sys_tkill
1082 .long sys_sendfile64
1083 .long sys_futex /* 240 */
1084 .long sys_sched_setaffinity
1085 .long sys_sched_getaffinity
1086 .long sys_ni_syscall
1087 .long sys_ni_syscall
1088 .long sys_io_setup /* 245 */
1089 .long sys_io_destroy
1090 .long sys_io_getevents
1091 .long sys_io_submit
1092 .long sys_io_cancel
1093 .long sys_fadvise64 /* 250 */
1094 .long sys_ni_syscall
1095 .long sys_exit_group
1096 .long sys_lookup_dcookie
1097 .long sys_epoll_create
1098 .long sys_epoll_ctl /* 255 */
1099 .long sys_epoll_wait
1100 .long sys_remap_file_pages
1101 .long sys_set_tid_address
1102 .long sys_timer_create
1103 .long sys_timer_settime /* 260 */
1104 .long sys_timer_gettime
1105 .long sys_timer_getoverrun
1106 .long sys_timer_delete
1107 .long sys_clock_settime
1108 .long sys_clock_gettime /* 265 */
1109 .long sys_clock_getres
1110 .long sys_clock_nanosleep
1111 .long sys_statfs64
1112 .long sys_fstatfs64
1113 .long sys_tgkill /* 270 */
1114 .long sys_utimes
1115 .long sys_fadvise64_64_wrapper
1116 .long sys_ni_syscall /* Reserved for vserver */
1117 .long sys_ni_syscall /* Reserved for mbind */
1118 .long sys_ni_syscall /* 275 - get_mempolicy */
1119 .long sys_ni_syscall /* set_mempolicy */
1120 .long sys_mq_open
1121 .long sys_mq_unlink
1122 .long sys_mq_timedsend
1123 .long sys_mq_timedreceive /* 280 */
1124 .long sys_mq_notify
1125 .long sys_mq_getsetattr
1126 .long sys_ni_syscall /* Reserved for kexec */
1127 .long sys_waitid
1128 .long sys_add_key /* 285 */
1129 .long sys_request_key
1130 .long sys_keyctl
1131 .long sys_ioprio_set
1132 .long sys_ioprio_get
1133 .long sys_inotify_init /* 290 */
1134 .long sys_inotify_add_watch
1135 .long sys_inotify_rm_watch
1136
1137/* End of entry.S */
diff --git a/arch/sh/kernel/head.S b/arch/sh/kernel/head.S
index 9b9e6ef626ce..f5f53d14f245 100644
--- a/arch/sh/kernel/head.S
+++ b/arch/sh/kernel/head.S
@@ -11,6 +11,18 @@
11 * Head.S contains the SH exception handlers and startup code. 11 * Head.S contains the SH exception handlers and startup code.
12 */ 12 */
13#include <linux/linkage.h> 13#include <linux/linkage.h>
14#include <asm/thread_info.h>
15
16#ifdef CONFIG_CPU_SH4A
17#define SYNCO() synco
18
19#define PREFI(label, reg) \
20 mov.l label, reg; \
21 prefi @reg
22#else
23#define SYNCO()
24#define PREFI(label, reg)
25#endif
14 26
15 .section .empty_zero_page, "aw" 27 .section .empty_zero_page, "aw"
16ENTRY(empty_zero_page) 28ENTRY(empty_zero_page)
@@ -42,18 +54,25 @@ ENTRY(_stext)
42 ! Initialize global interrupt mask 54 ! Initialize global interrupt mask
43 mov #0, r0 55 mov #0, r0
44 ldc r0, r6_bank 56 ldc r0, r6_bank
57
58 /*
59 * Prefetch if possible to reduce cache miss penalty.
60 *
61 * We do this early on for SH-4A as a micro-optimization,
62 * as later on we will have speculative execution enabled
63 * and this will become less of an issue.
64 */
65 PREFI(5f, r0)
66 PREFI(6f, r0)
67
45 ! 68 !
46 mov.l 2f, r0 69 mov.l 2f, r0
47 mov r0, r15 ! Set initial r15 (stack pointer) 70 mov r0, r15 ! Set initial r15 (stack pointer)
48 mov #0x20, r1 ! 71 mov #(THREAD_SIZE >> 8), r1
49 shll8 r1 ! r1 = 8192 72 shll8 r1 ! r1 = THREAD_SIZE
50 sub r1, r0 ! 73 sub r1, r0 !
51 ldc r0, r7_bank ! ... and initial thread_info 74 ldc r0, r7_bank ! ... and initial thread_info
52 ! 75
53 ! Additional CPU initialization
54 mov.l 6f, r0
55 jsr @r0
56 nop
57 ! Clear BSS area 76 ! Clear BSS area
58 mov.l 3f, r1 77 mov.l 3f, r1
59 add #4, r1 78 add #4, r1
@@ -62,6 +81,14 @@ ENTRY(_stext)
629: cmp/hs r2, r1 819: cmp/hs r2, r1
63 bf/s 9b ! while (r1 < r2) 82 bf/s 9b ! while (r1 < r2)
64 mov.l r0,@-r2 83 mov.l r0,@-r2
84
85 ! Additional CPU initialization
86 mov.l 6f, r0
87 jsr @r0
88 nop
89
90 SYNCO() ! Wait for pending instructions..
91
65 ! Start kernel 92 ! Start kernel
66 mov.l 5f, r0 93 mov.l 5f, r0
67 jmp @r0 94 jmp @r0
@@ -69,7 +96,7 @@ ENTRY(_stext)
69 96
70 .balign 4 97 .balign 4
711: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF 981: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF
722: .long stack 992: .long init_thread_union+THREAD_SIZE
733: .long __bss_start 1003: .long __bss_start
744: .long _end 1014: .long _end
755: .long start_kernel 1025: .long start_kernel
diff --git a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c
index 71c9fde2fd90..501fe03e3715 100644
--- a/arch/sh/kernel/io.c
+++ b/arch/sh/kernel/io.c
@@ -61,6 +61,73 @@ void memset_io(volatile void __iomem *dst, int c, unsigned long count)
61} 61}
62EXPORT_SYMBOL(memset_io); 62EXPORT_SYMBOL(memset_io);
63 63
64void __raw_readsl(unsigned long addr, void *datap, int len)
65{
66 u32 *data;
67
68 for (data = datap; (len != 0) && (((u32)data & 0x1f) != 0); len--)
69 *data++ = ctrl_inl(addr);
70
71 if (likely(len >= (0x20 >> 2))) {
72 int tmp2, tmp3, tmp4, tmp5, tmp6;
73
74 __asm__ __volatile__(
75 "1: \n\t"
76 "mov.l @%7, r0 \n\t"
77 "mov.l @%7, %2 \n\t"
78#ifdef CONFIG_CPU_SH4
79 "movca.l r0, @%0 \n\t"
80#else
81 "mov.l r0, @%0 \n\t"
82#endif
83 "mov.l @%7, %3 \n\t"
84 "mov.l @%7, %4 \n\t"
85 "mov.l @%7, %5 \n\t"
86 "mov.l @%7, %6 \n\t"
87 "mov.l @%7, r7 \n\t"
88 "mov.l @%7, r0 \n\t"
89 "mov.l %2, @(0x04,%0) \n\t"
90 "mov #0x20>>2, %2 \n\t"
91 "mov.l %3, @(0x08,%0) \n\t"
92 "sub %2, %1 \n\t"
93 "mov.l %4, @(0x0c,%0) \n\t"
94 "cmp/hi %1, %2 ! T if 32 > len \n\t"
95 "mov.l %5, @(0x10,%0) \n\t"
96 "mov.l %6, @(0x14,%0) \n\t"
97 "mov.l r7, @(0x18,%0) \n\t"
98 "mov.l r0, @(0x1c,%0) \n\t"
99 "bf.s 1b \n\t"
100 " add #0x20, %0 \n\t"
101 : "=&r" (data), "=&r" (len),
102 "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4),
103 "=&r" (tmp5), "=&r" (tmp6)
104 : "r"(addr), "0" (data), "1" (len)
105 : "r0", "r7", "t", "memory");
106 }
107
108 for (; len != 0; len--)
109 *data++ = ctrl_inl(addr);
110}
111EXPORT_SYMBOL(__raw_readsl);
112
113void __raw_writesl(unsigned long addr, const void *data, int len)
114{
115 if (likely(len != 0)) {
116 int tmp1;
117
118 __asm__ __volatile__ (
119 "1: \n\t"
120 "mov.l @%0+, %1 \n\t"
121 "dt %3 \n\t"
122 "bf.s 1b \n\t"
123 " mov.l %1, @%4 \n\t"
124 : "=&r" (data), "=&r" (tmp1)
125 : "0" (data), "r" (len), "r"(addr)
126 : "t", "memory");
127 }
128}
129EXPORT_SYMBOL(__raw_writesl);
130
64void __iomem *ioport_map(unsigned long port, unsigned int nr) 131void __iomem *ioport_map(unsigned long port, unsigned int nr)
65{ 132{
66 return sh_mv.mv_ioport_map(port, nr); 133 return sh_mv.mv_ioport_map(port, nr);
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index c2e07f7f3496..c7ebd6aec951 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -1,5 +1,4 @@
1/* $Id: irq.c,v 1.20 2004/01/13 05:52:11 kkojima Exp $ 1/*
2 *
3 * linux/arch/sh/kernel/irq.c 2 * linux/arch/sh/kernel/irq.c
4 * 3 *
5 * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar 4 * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
@@ -7,13 +6,15 @@
7 * 6 *
8 * SuperH version: Copyright (C) 1999 Niibe Yutaka 7 * SuperH version: Copyright (C) 1999 Niibe Yutaka
9 */ 8 */
10
11#include <linux/irq.h> 9#include <linux/irq.h>
12#include <linux/interrupt.h> 10#include <linux/interrupt.h>
11#include <linux/module.h>
13#include <linux/kernel_stat.h> 12#include <linux/kernel_stat.h>
14#include <linux/seq_file.h> 13#include <linux/seq_file.h>
15#include <asm/irq.h> 14#include <asm/irq.h>
16#include <asm/processor.h> 15#include <asm/processor.h>
16#include <asm/uaccess.h>
17#include <asm/thread_info.h>
17#include <asm/cpu/mmu_context.h> 18#include <asm/cpu/mmu_context.h>
18 19
19/* 20/*
@@ -60,15 +61,46 @@ unlock:
60} 61}
61#endif 62#endif
62 63
64#ifdef CONFIG_4KSTACKS
65/*
66 * per-CPU IRQ handling contexts (thread information and stack)
67 */
68union irq_ctx {
69 struct thread_info tinfo;
70 u32 stack[THREAD_SIZE/sizeof(u32)];
71};
72
73static union irq_ctx *hardirq_ctx[NR_CPUS];
74static union irq_ctx *softirq_ctx[NR_CPUS];
75#endif
63 76
64asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, 77asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
65 unsigned long r6, unsigned long r7, 78 unsigned long r6, unsigned long r7,
66 struct pt_regs regs) 79 struct pt_regs regs)
67{ 80{
68 int irq = r4; 81 int irq = r4;
82#ifdef CONFIG_4KSTACKS
83 union irq_ctx *curctx, *irqctx;
84#endif
69 85
70 irq_enter(); 86 irq_enter();
71 87
88#ifdef CONFIG_DEBUG_STACKOVERFLOW
89 /* Debugging check for stack overflow: is there less than 1KB free? */
90 {
91 long sp;
92
93 __asm__ __volatile__ ("and r15, %0" :
94 "=r" (sp) : "0" (THREAD_SIZE - 1));
95
96 if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
97 printk("do_IRQ: stack overflow: %ld\n",
98 sp - sizeof(struct thread_info));
99 dump_stack();
100 }
101 }
102#endif
103
72#ifdef CONFIG_CPU_HAS_INTEVT 104#ifdef CONFIG_CPU_HAS_INTEVT
73 __asm__ __volatile__ ( 105 __asm__ __volatile__ (
74#ifdef CONFIG_CPU_HAS_SR_RB 106#ifdef CONFIG_CPU_HAS_SR_RB
@@ -87,7 +119,135 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
87#endif 119#endif
88 120
89 irq = irq_demux(irq); 121 irq = irq_demux(irq);
90 __do_IRQ(irq, &regs); 122
123#ifdef CONFIG_4KSTACKS
124 curctx = (union irq_ctx *)current_thread_info();
125 irqctx = hardirq_ctx[smp_processor_id()];
126
127 /*
128 * this is where we switch to the IRQ stack. However, if we are
129 * already using the IRQ stack (because we interrupted a hardirq
130 * handler) we can't do that and just have to keep using the
131 * current stack (which is the irq stack already after all)
132 */
133 if (curctx != irqctx) {
134 u32 *isp;
135
136 isp = (u32 *)((char *)irqctx + sizeof(*irqctx));
137 irqctx->tinfo.task = curctx->tinfo.task;
138 irqctx->tinfo.previous_sp = current_stack_pointer;
139
140 __asm__ __volatile__ (
141 "mov %0, r4 \n"
142 "mov %1, r5 \n"
143 "mov r15, r9 \n"
144 "jsr @%2 \n"
145 /* swith to the irq stack */
146 " mov %3, r15 \n"
147 /* restore the stack (ring zero) */
148 "mov r9, r15 \n"
149 : /* no outputs */
150 : "r" (irq), "r" (&regs), "r" (__do_IRQ), "r" (isp)
151 /* XXX: A somewhat excessive clobber list? -PFM */
152 : "memory", "r0", "r1", "r2", "r3", "r4",
153 "r5", "r6", "r7", "r8", "t", "pr"
154 );
155 } else
156#endif
157 __do_IRQ(irq, &regs);
158
91 irq_exit(); 159 irq_exit();
160
92 return 1; 161 return 1;
93} 162}
163
164#ifdef CONFIG_4KSTACKS
165/*
166 * These should really be __section__(".bss.page_aligned") as well, but
167 * gcc's 3.0 and earlier don't handle that correctly.
168 */
169static char softirq_stack[NR_CPUS * THREAD_SIZE]
170 __attribute__((__aligned__(THREAD_SIZE)));
171
172static char hardirq_stack[NR_CPUS * THREAD_SIZE]
173 __attribute__((__aligned__(THREAD_SIZE)));
174
175/*
176 * allocate per-cpu stacks for hardirq and for softirq processing
177 */
178void irq_ctx_init(int cpu)
179{
180 union irq_ctx *irqctx;
181
182 if (hardirq_ctx[cpu])
183 return;
184
185 irqctx = (union irq_ctx *)&hardirq_stack[cpu * THREAD_SIZE];
186 irqctx->tinfo.task = NULL;
187 irqctx->tinfo.exec_domain = NULL;
188 irqctx->tinfo.cpu = cpu;
189 irqctx->tinfo.preempt_count = HARDIRQ_OFFSET;
190 irqctx->tinfo.addr_limit = MAKE_MM_SEG(0);
191
192 hardirq_ctx[cpu] = irqctx;
193
194 irqctx = (union irq_ctx *)&softirq_stack[cpu * THREAD_SIZE];
195 irqctx->tinfo.task = NULL;
196 irqctx->tinfo.exec_domain = NULL;
197 irqctx->tinfo.cpu = cpu;
198 irqctx->tinfo.preempt_count = SOFTIRQ_OFFSET;
199 irqctx->tinfo.addr_limit = MAKE_MM_SEG(0);
200
201 softirq_ctx[cpu] = irqctx;
202
203 printk("CPU %u irqstacks, hard=%p soft=%p\n",
204 cpu, hardirq_ctx[cpu], softirq_ctx[cpu]);
205}
206
207void irq_ctx_exit(int cpu)
208{
209 hardirq_ctx[cpu] = NULL;
210}
211
212extern asmlinkage void __do_softirq(void);
213
214asmlinkage void do_softirq(void)
215{
216 unsigned long flags;
217 struct thread_info *curctx;
218 union irq_ctx *irqctx;
219 u32 *isp;
220
221 if (in_interrupt())
222 return;
223
224 local_irq_save(flags);
225
226 if (local_softirq_pending()) {
227 curctx = current_thread_info();
228 irqctx = softirq_ctx[smp_processor_id()];
229 irqctx->tinfo.task = curctx->task;
230 irqctx->tinfo.previous_sp = current_stack_pointer;
231
232 /* build the stack frame on the softirq stack */
233 isp = (u32 *)((char *)irqctx + sizeof(*irqctx));
234
235 __asm__ __volatile__ (
236 "mov r15, r9 \n"
237 "jsr @%0 \n"
238 /* switch to the softirq stack */
239 " mov %1, r15 \n"
240 /* restore the thread stack */
241 "mov r9, r15 \n"
242 : /* no outputs */
243 : "r" (__do_softirq), "r" (isp)
244 /* XXX: A somewhat excessive clobber list? -PFM */
245 : "memory", "r0", "r1", "r2", "r3", "r4",
246 "r5", "r6", "r7", "r8", "r9", "r15", "t", "pr"
247 );
248 }
249
250 local_irq_restore(flags);
251}
252EXPORT_SYMBOL(do_softirq);
253#endif
diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c
index 42638b92b51c..9c6315f0335d 100644
--- a/arch/sh/kernel/kgdb_stub.c
+++ b/arch/sh/kernel/kgdb_stub.c
@@ -101,16 +101,17 @@
101#include <linux/linkage.h> 101#include <linux/linkage.h>
102#include <linux/init.h> 102#include <linux/init.h>
103 103
104#ifdef CONFIG_SH_KGDB_CONSOLE
105#include <linux/console.h>
106#endif
107
104#include <asm/system.h> 108#include <asm/system.h>
105#include <asm/current.h> 109#include <asm/current.h>
106#include <asm/signal.h> 110#include <asm/signal.h>
107#include <asm/pgtable.h> 111#include <asm/pgtable.h>
108#include <asm/ptrace.h> 112#include <asm/ptrace.h>
109#include <asm/kgdb.h> 113#include <asm/kgdb.h>
110 114#include <asm/io.h>
111#ifdef CONFIG_SH_KGDB_CONSOLE
112#include <linux/console.h>
113#endif
114 115
115/* Function pointers for linkage */ 116/* Function pointers for linkage */
116kgdb_debug_hook_t *kgdb_debug_hook; 117kgdb_debug_hook_t *kgdb_debug_hook;
@@ -240,7 +241,6 @@ static jmp_buf rem_com_env;
240/* Misc static */ 241/* Misc static */
241static int stepped_address; 242static int stepped_address;
242static short stepped_opcode; 243static short stepped_opcode;
243static const char hexchars[] = "0123456789abcdef";
244static char in_buffer[BUFMAX]; 244static char in_buffer[BUFMAX];
245static char out_buffer[OUTBUFMAX]; 245static char out_buffer[OUTBUFMAX];
246 246
@@ -253,29 +253,6 @@ typedef unsigned char threadref[8];
253#define BUF_THREAD_ID_SIZE 16 253#define BUF_THREAD_ID_SIZE 16
254#endif 254#endif
255 255
256/* Return addr as a real volatile address */
257static inline unsigned int ctrl_inl(const unsigned long addr)
258{
259 return *(volatile unsigned long *) addr;
260}
261
262/* Correctly set *addr using volatile */
263static inline void ctrl_outl(const unsigned int b, unsigned long addr)
264{
265 *(volatile unsigned long *) addr = b;
266}
267
268/* Get high hex bits */
269static char highhex(const int x)
270{
271 return hexchars[(x >> 4) & 0xf];
272}
273
274/* Get low hex bits */
275static char lowhex(const int x)
276{
277 return hexchars[x & 0xf];
278}
279 256
280/* Convert ch to hex */ 257/* Convert ch to hex */
281static int hex(const char ch) 258static int hex(const char ch)
diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c
index 6bcd8d92399f..08587cdb64d6 100644
--- a/arch/sh/kernel/machine_kexec.c
+++ b/arch/sh/kernel/machine_kexec.c
@@ -29,12 +29,6 @@ extern const unsigned char relocate_new_kernel[];
29extern const unsigned int relocate_new_kernel_size; 29extern const unsigned int relocate_new_kernel_size;
30extern void *gdb_vbr_vector; 30extern void *gdb_vbr_vector;
31 31
32/*
33 * Provide a dummy crash_notes definition while crash dump arrives to ppc.
34 * This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
35 */
36void *crash_notes = NULL;
37
38void machine_shutdown(void) 32void machine_shutdown(void)
39{ 33{
40} 34}
diff --git a/arch/sh/kernel/pm.c b/arch/sh/kernel/pm.c
new file mode 100644
index 000000000000..10ab62c9aede
--- /dev/null
+++ b/arch/sh/kernel/pm.c
@@ -0,0 +1,88 @@
1/*
2 * Generic Power Management Routine
3 *
4 * Copyright (c) 2006 Andriy Skulysh <askulsyh@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License.
8 */
9#include <linux/suspend.h>
10#include <linux/delay.h>
11#include <linux/gfp.h>
12#include <asm/freq.h>
13#include <asm/io.h>
14#include <asm/watchdog.h>
15#include <asm/pm.h>
16
17#define INTR_OFFSET 0x600
18
19#define STBCR 0xffffff82
20#define STBCR2 0xffffff88
21
22#define STBCR_STBY 0x80
23#define STBCR_MSTP2 0x04
24
25#define MCR 0xffffff68
26#define RTCNT 0xffffff70
27
28#define MCR_RMODE 2
29#define MCR_RFSH 4
30
31void pm_enter(void)
32{
33 u8 stbcr, csr;
34 u16 frqcr, mcr;
35 u32 vbr_new, vbr_old;
36
37 set_bl_bit();
38
39 /* set wdt */
40 csr = sh_wdt_read_csr();
41 csr &= ~WTCSR_TME;
42 csr |= WTCSR_CKS_4096;
43 sh_wdt_write_csr(csr);
44 csr = sh_wdt_read_csr();
45 sh_wdt_write_cnt(0);
46
47 /* disable PLL1 */
48 frqcr = ctrl_inw(FRQCR);
49 frqcr &= ~(FRQCR_PLLEN | FRQCR_PSTBY);
50 ctrl_outw(frqcr, FRQCR);
51
52 /* enable standby */
53 stbcr = ctrl_inb(STBCR);
54 ctrl_outb(stbcr | STBCR_STBY | STBCR_MSTP2, STBCR);
55
56 /* set self-refresh */
57 mcr = ctrl_inw(MCR);
58 ctrl_outw(mcr & ~MCR_RFSH, MCR);
59
60 /* set interrupt handler */
61 asm volatile("stc vbr, %0" : "=r" (vbr_old));
62 vbr_new = get_zeroed_page(GFP_ATOMIC);
63 udelay(50);
64 memcpy((void*)(vbr_new + INTR_OFFSET),
65 &wakeup_start, &wakeup_end - &wakeup_start);
66 asm volatile("ldc %0, vbr" : : "r" (vbr_new));
67
68 ctrl_outw(0, RTCNT);
69 ctrl_outw(mcr | MCR_RFSH | MCR_RMODE, MCR);
70
71 cpu_sleep();
72
73 asm volatile("ldc %0, vbr" : : "r" (vbr_old));
74
75 free_page(vbr_new);
76
77 /* enable PLL1 */
78 frqcr = ctrl_inw(FRQCR);
79 frqcr |= FRQCR_PSTBY;
80 ctrl_outw(frqcr, FRQCR);
81 udelay(50);
82 frqcr |= FRQCR_PLLEN;
83 ctrl_outw(frqcr, FRQCR);
84
85 ctrl_outb(stbcr, STBCR);
86
87 clear_bl_bit();
88}
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index f2031314cb2b..0b1d5dd7a93b 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -81,16 +81,6 @@ void cpu_idle(void)
81 81
82void machine_restart(char * __unused) 82void machine_restart(char * __unused)
83{ 83{
84
85#ifdef CONFIG_KEXEC
86 struct kimage *image;
87 image = xchg(&kexec_image, 0);
88 if (image) {
89 machine_shutdown();
90 machine_kexec(image);
91 }
92#endif
93
94 /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */ 84 /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */
95 asm volatile("ldc %0, sr\n\t" 85 asm volatile("ldc %0, sr\n\t"
96 "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001)); 86 "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001));
@@ -263,6 +253,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
263 unsigned long unused, 253 unsigned long unused,
264 struct task_struct *p, struct pt_regs *regs) 254 struct task_struct *p, struct pt_regs *regs)
265{ 255{
256 struct thread_info *ti = task_thread_info(p);
266 struct pt_regs *childregs; 257 struct pt_regs *childregs;
267#if defined(CONFIG_SH_FPU) 258#if defined(CONFIG_SH_FPU)
268 struct task_struct *tsk = current; 259 struct task_struct *tsk = current;
@@ -277,8 +268,10 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
277 268
278 if (user_mode(regs)) { 269 if (user_mode(regs)) {
279 childregs->regs[15] = usp; 270 childregs->regs[15] = usp;
271 ti->addr_limit = USER_DS;
280 } else { 272 } else {
281 childregs->regs[15] = (unsigned long)task_stack_page(p) + THREAD_SIZE; 273 childregs->regs[15] = (unsigned long)task_stack_page(p) + THREAD_SIZE;
274 ti->addr_limit = KERNEL_DS;
282 } 275 }
283 if (clone_flags & CLONE_SETTLS) { 276 if (clone_flags & CLONE_SETTLS) {
284 childregs->gbr = childregs->regs[0]; 277 childregs->gbr = childregs->regs[0];
@@ -299,13 +292,15 @@ ubc_set_tracing(int asid, unsigned long pc)
299{ 292{
300 ctrl_outl(pc, UBC_BARA); 293 ctrl_outl(pc, UBC_BARA);
301 294
295#ifdef CONFIG_MMU
302 /* We don't have any ASID settings for the SH-2! */ 296 /* We don't have any ASID settings for the SH-2! */
303 if (cpu_data->type != CPU_SH7604) 297 if (cpu_data->type != CPU_SH7604)
304 ctrl_outb(asid, UBC_BASRA); 298 ctrl_outb(asid, UBC_BASRA);
299#endif
305 300
306 ctrl_outl(0, UBC_BAMRA); 301 ctrl_outl(0, UBC_BAMRA);
307 302
308 if (cpu_data->type == CPU_SH7729) { 303 if (cpu_data->type == CPU_SH7729 || cpu_data->type == CPU_SH7710) {
309 ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA); 304 ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA);
310 ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR); 305 ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR);
311 } else { 306 } else {
@@ -344,6 +339,7 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne
344 } 339 }
345#endif 340#endif
346 341
342#ifdef CONFIG_MMU
347 /* 343 /*
348 * Restore the kernel mode register 344 * Restore the kernel mode register
349 * k7 (r7_bank1) 345 * k7 (r7_bank1)
@@ -351,19 +347,21 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne
351 asm volatile("ldc %0, r7_bank" 347 asm volatile("ldc %0, r7_bank"
352 : /* no output */ 348 : /* no output */
353 : "r" (task_thread_info(next))); 349 : "r" (task_thread_info(next)));
350#endif
354 351
355#ifdef CONFIG_MMU
356 /* If no tasks are using the UBC, we're done */ 352 /* If no tasks are using the UBC, we're done */
357 if (ubc_usercnt == 0) 353 if (ubc_usercnt == 0)
358 /* If no tasks are using the UBC, we're done */; 354 /* If no tasks are using the UBC, we're done */;
359 else if (next->thread.ubc_pc && next->mm) { 355 else if (next->thread.ubc_pc && next->mm) {
360 ubc_set_tracing(next->mm->context & MMU_CONTEXT_ASID_MASK, 356 int asid = 0;
361 next->thread.ubc_pc); 357#ifdef CONFIG_MMU
358 asid |= next->mm->context.id & MMU_CONTEXT_ASID_MASK;
359#endif
360 ubc_set_tracing(asid, next->thread.ubc_pc);
362 } else { 361 } else {
363 ctrl_outw(0, UBC_BBRA); 362 ctrl_outw(0, UBC_BBRA);
364 ctrl_outw(0, UBC_BBRB); 363 ctrl_outw(0, UBC_BBRB);
365 } 364 }
366#endif
367 365
368 return prev; 366 return prev;
369} 367}
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
index f7eebbde3291..04ca13a041c1 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace.c
@@ -224,7 +224,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
224 224
225 case PTRACE_SETDSPREGS: { 225 case PTRACE_SETDSPREGS: {
226 unsigned long dp; 226 unsigned long dp;
227 int i;
228 227
229 ret = -EIO; 228 ret = -EIO;
230 dp = ((unsigned long) child) + THREAD_SIZE - 229 dp = ((unsigned long) child) + THREAD_SIZE -
diff --git a/arch/sh/kernel/semaphore.c b/arch/sh/kernel/semaphore.c
index a3c24dcbf01d..184119eeae56 100644
--- a/arch/sh/kernel/semaphore.c
+++ b/arch/sh/kernel/semaphore.c
@@ -14,7 +14,7 @@
14#include <asm/semaphore.h> 14#include <asm/semaphore.h>
15#include <asm/semaphore-helper.h> 15#include <asm/semaphore-helper.h>
16 16
17spinlock_t semaphore_wake_lock; 17DEFINE_SPINLOCK(semaphore_wake_lock);
18 18
19/* 19/*
20 * Semaphores are implemented using a two-way counter: 20 * Semaphores are implemented using a two-way counter:
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index e75189cb1db7..5f587332234a 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -43,27 +43,14 @@ extern void * __rd_start, * __rd_end;
43 * The bigger value means no problem. 43 * The bigger value means no problem.
44 */ 44 */
45struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 10000000, }; 45struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 10000000, };
46#ifdef CONFIG_VT
46struct screen_info screen_info; 47struct screen_info screen_info;
48#endif
47 49
48#if defined(CONFIG_SH_UNKNOWN) 50#if defined(CONFIG_SH_UNKNOWN)
49struct sh_machine_vector sh_mv; 51struct sh_machine_vector sh_mv;
50#endif 52#endif
51 53
52/* We need this to satisfy some external references. */
53struct screen_info screen_info = {
54 0, 25, /* orig-x, orig-y */
55 0, /* unused */
56 0, /* orig-video-page */
57 0, /* orig-video-mode */
58 80, /* orig-video-cols */
59 0,0,0, /* ega_ax, ega_bx, ega_cx */
60 25, /* orig-video-lines */
61 0, /* orig-video-isVGA */
62 16 /* orig-video-points */
63};
64
65extern void platform_setup(void);
66extern char *get_system_type(void);
67extern int root_mountflags; 54extern int root_mountflags;
68 55
69#define MV_NAME_SIZE 32 56#define MV_NAME_SIZE 32
@@ -90,29 +77,8 @@ static struct sh_machine_vector* __init get_mv_byname(const char* name);
90 77
91static char command_line[COMMAND_LINE_SIZE] = { 0, }; 78static char command_line[COMMAND_LINE_SIZE] = { 0, };
92 79
93struct resource standard_io_resources[] = { 80static struct resource code_resource = { .name = "Kernel code", };
94 { "dma1", 0x00, 0x1f }, 81static struct resource data_resource = { .name = "Kernel data", };
95 { "pic1", 0x20, 0x3f },
96 { "timer", 0x40, 0x5f },
97 { "keyboard", 0x60, 0x6f },
98 { "dma page reg", 0x80, 0x8f },
99 { "pic2", 0xa0, 0xbf },
100 { "dma2", 0xc0, 0xdf },
101 { "fpu", 0xf0, 0xff }
102};
103
104#define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource))
105
106/* System RAM - interrupted by the 640kB-1M hole */
107#define code_resource (ram_resources[3])
108#define data_resource (ram_resources[4])
109static struct resource ram_resources[] = {
110 { "System RAM", 0x000000, 0x09ffff, IORESOURCE_BUSY },
111 { "System RAM", 0x100000, 0x100000, IORESOURCE_BUSY },
112 { "Video RAM area", 0x0a0000, 0x0bffff },
113 { "Kernel code", 0x100000, 0 },
114 { "Kernel data", 0, 0 }
115};
116 82
117unsigned long memory_start, memory_end; 83unsigned long memory_start, memory_end;
118 84
@@ -145,6 +111,24 @@ static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE],
145 memory_end = memory_start + mem_size; 111 memory_end = memory_start + mem_size;
146 } 112 }
147 } 113 }
114
115#ifdef CONFIG_EARLY_PRINTK
116 if (c == ' ' && !memcmp(from, "earlyprintk=", 12)) {
117 char *ep_end;
118
119 if (to != command_line)
120 to--;
121
122 from += 12;
123 ep_end = strchr(from, ' ');
124
125 setup_early_printk(from);
126 printk("early console enabled\n");
127
128 from = ep_end;
129 }
130#endif
131
148 if (c == ' ' && !memcmp(from, "sh_mv=", 6)) { 132 if (c == ' ' && !memcmp(from, "sh_mv=", 6)) {
149 char* mv_end; 133 char* mv_end;
150 char* mv_comma; 134 char* mv_comma;
@@ -237,6 +221,9 @@ static int __init sh_mv_setup(char **cmdline_p)
237 __set_io_port_base(mv_io_base); 221 __set_io_port_base(mv_io_base);
238#endif 222#endif
239 223
224 if (!sh_mv.mv_nr_irqs)
225 sh_mv.mv_nr_irqs = NR_IRQS;
226
240 return 0; 227 return 0;
241} 228}
242 229
@@ -245,11 +232,6 @@ void __init setup_arch(char **cmdline_p)
245 unsigned long bootmap_size; 232 unsigned long bootmap_size;
246 unsigned long start_pfn, max_pfn, max_low_pfn; 233 unsigned long start_pfn, max_pfn, max_low_pfn;
247 234
248#ifdef CONFIG_EARLY_PRINTK
249 extern void enable_early_printk(void);
250
251 enable_early_printk();
252#endif
253#ifdef CONFIG_CMDLINE_BOOL 235#ifdef CONFIG_CMDLINE_BOOL
254 strcpy(COMMAND_LINE, CONFIG_CMDLINE); 236 strcpy(COMMAND_LINE, CONFIG_CMDLINE);
255#endif 237#endif
@@ -368,14 +350,14 @@ void __init setup_arch(char **cmdline_p)
368#endif 350#endif
369 351
370 /* Perform the machine specific initialisation */ 352 /* Perform the machine specific initialisation */
371 platform_setup(); 353 if (likely(sh_mv.mv_setup))
354 sh_mv.mv_setup(cmdline_p);
372 355
373 paging_init(); 356 paging_init();
374} 357}
375 358
376struct sh_machine_vector* __init get_mv_byname(const char* name) 359struct sh_machine_vector* __init get_mv_byname(const char* name)
377{ 360{
378 extern int strcasecmp(const char *, const char *);
379 extern long __machvec_start, __machvec_end; 361 extern long __machvec_start, __machvec_end;
380 struct sh_machine_vector *all_vecs = 362 struct sh_machine_vector *all_vecs =
381 (struct sh_machine_vector *)&__machvec_start; 363 (struct sh_machine_vector *)&__machvec_start;
@@ -410,25 +392,18 @@ static int __init topology_init(void)
410subsys_initcall(topology_init); 392subsys_initcall(topology_init);
411 393
412static const char *cpu_name[] = { 394static const char *cpu_name[] = {
413 [CPU_SH7604] = "SH7604", 395 [CPU_SH7604] = "SH7604", [CPU_SH7300] = "SH7300",
414 [CPU_SH7705] = "SH7705", 396 [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706",
415 [CPU_SH7708] = "SH7708", 397 [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708",
416 [CPU_SH7729] = "SH7729", 398 [CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710",
417 [CPU_SH7300] = "SH7300", 399 [CPU_SH7729] = "SH7729", [CPU_SH7750] = "SH7750",
418 [CPU_SH7750] = "SH7750", 400 [CPU_SH7750S] = "SH7750S", [CPU_SH7750R] = "SH7750R",
419 [CPU_SH7750S] = "SH7750S", 401 [CPU_SH7751] = "SH7751", [CPU_SH7751R] = "SH7751R",
420 [CPU_SH7750R] = "SH7750R", 402 [CPU_SH7760] = "SH7760", [CPU_SH73180] = "SH73180",
421 [CPU_SH7751] = "SH7751", 403 [CPU_ST40RA] = "ST40RA", [CPU_ST40GX1] = "ST40GX1",
422 [CPU_SH7751R] = "SH7751R", 404 [CPU_SH4_202] = "SH4-202", [CPU_SH4_501] = "SH4-501",
423 [CPU_SH7760] = "SH7760", 405 [CPU_SH7770] = "SH7770", [CPU_SH7780] = "SH7780",
424 [CPU_SH73180] = "SH73180", 406 [CPU_SH7781] = "SH7781", [CPU_SH7343] = "SH7343",
425 [CPU_ST40RA] = "ST40RA",
426 [CPU_ST40GX1] = "ST40GX1",
427 [CPU_SH4_202] = "SH4-202",
428 [CPU_SH4_501] = "SH4-501",
429 [CPU_SH7770] = "SH7770",
430 [CPU_SH7780] = "SH7780",
431 [CPU_SH7781] = "SH7781",
432 [CPU_SH_NONE] = "Unknown" 407 [CPU_SH_NONE] = "Unknown"
433}; 408};
434 409
@@ -438,8 +413,10 @@ const char *get_cpu_subtype(void)
438} 413}
439 414
440#ifdef CONFIG_PROC_FS 415#ifdef CONFIG_PROC_FS
416/* Symbolic CPU flags, keep in sync with asm/cpu-features.h */
441static const char *cpu_flags[] = { 417static const char *cpu_flags[] = {
442 "none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr", "ptea", NULL 418 "none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr",
419 "ptea", "llsc", "l2", NULL
443}; 420};
444 421
445static void show_cpuflags(struct seq_file *m) 422static void show_cpuflags(struct seq_file *m)
@@ -460,7 +437,8 @@ static void show_cpuflags(struct seq_file *m)
460 seq_printf(m, "\n"); 437 seq_printf(m, "\n");
461} 438}
462 439
463static void show_cacheinfo(struct seq_file *m, const char *type, struct cache_info info) 440static void show_cacheinfo(struct seq_file *m, const char *type,
441 struct cache_info info)
464{ 442{
465 unsigned int cache_size; 443 unsigned int cache_size;
466 444
@@ -493,7 +471,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
493 * unified cache on the SH-2 and SH-3, as well as the harvard 471 * unified cache on the SH-2 and SH-3, as well as the harvard
494 * style cache on the SH-4. 472 * style cache on the SH-4.
495 */ 473 */
496 if (test_bit(SH_CACHE_COMBINED, &(boot_cpu_data.icache.flags))) { 474 if (boot_cpu_data.icache.flags & SH_CACHE_COMBINED) {
497 seq_printf(m, "unified\n"); 475 seq_printf(m, "unified\n");
498 show_cacheinfo(m, "cache", boot_cpu_data.icache); 476 show_cacheinfo(m, "cache", boot_cpu_data.icache);
499 } else { 477 } else {
@@ -502,6 +480,10 @@ static int show_cpuinfo(struct seq_file *m, void *v)
502 show_cacheinfo(m, "dcache", boot_cpu_data.dcache); 480 show_cacheinfo(m, "dcache", boot_cpu_data.dcache);
503 } 481 }
504 482
483 /* Optional secondary cache */
484 if (boot_cpu_data.flags & CPU_HAS_L2_CACHE)
485 show_cacheinfo(m, "scache", boot_cpu_data.scache);
486
505 seq_printf(m, "bogomips\t: %lu.%02lu\n", 487 seq_printf(m, "bogomips\t: %lu.%02lu\n",
506 boot_cpu_data.loops_per_jiffy/(500000/HZ), 488 boot_cpu_data.loops_per_jiffy/(500000/HZ),
507 (boot_cpu_data.loops_per_jiffy/(5000/HZ)) % 100); 489 (boot_cpu_data.loops_per_jiffy/(5000/HZ)) % 100);
@@ -617,4 +599,3 @@ static int __init kgdb_parse_options(char *options)
617} 599}
618__setup("kgdb=", kgdb_parse_options); 600__setup("kgdb=", kgdb_parse_options);
619#endif /* CONFIG_SH_KGDB */ 601#endif /* CONFIG_SH_KGDB */
620
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c
index 245ed8f945e8..d3cbfa2ad4a7 100644
--- a/arch/sh/kernel/sh_ksyms.c
+++ b/arch/sh/kernel/sh_ksyms.c
@@ -27,21 +27,11 @@ EXPORT_SYMBOL(sh_mv);
27 27
28/* platform dependent support */ 28/* platform dependent support */
29EXPORT_SYMBOL(dump_fpu); 29EXPORT_SYMBOL(dump_fpu);
30EXPORT_SYMBOL(iounmap);
31EXPORT_SYMBOL(enable_irq);
32EXPORT_SYMBOL(disable_irq);
33EXPORT_SYMBOL(probe_irq_mask);
34EXPORT_SYMBOL(kernel_thread); 30EXPORT_SYMBOL(kernel_thread);
35EXPORT_SYMBOL(disable_irq_nosync);
36EXPORT_SYMBOL(irq_desc); 31EXPORT_SYMBOL(irq_desc);
37EXPORT_SYMBOL(no_irq_type); 32EXPORT_SYMBOL(no_irq_type);
38 33
39EXPORT_SYMBOL(strstr);
40EXPORT_SYMBOL(strlen); 34EXPORT_SYMBOL(strlen);
41EXPORT_SYMBOL(strnlen);
42EXPORT_SYMBOL(strchr);
43EXPORT_SYMBOL(strcat);
44EXPORT_SYMBOL(strncat);
45 35
46/* PCI exports */ 36/* PCI exports */
47#ifdef CONFIG_PCI 37#ifdef CONFIG_PCI
@@ -52,13 +42,8 @@ EXPORT_SYMBOL(pci_free_consistent);
52/* mem exports */ 42/* mem exports */
53EXPORT_SYMBOL(memchr); 43EXPORT_SYMBOL(memchr);
54EXPORT_SYMBOL(memcpy); 44EXPORT_SYMBOL(memcpy);
55EXPORT_SYMBOL(memcpy_fromio);
56EXPORT_SYMBOL(memcpy_toio);
57EXPORT_SYMBOL(memset); 45EXPORT_SYMBOL(memset);
58EXPORT_SYMBOL(memset_io);
59EXPORT_SYMBOL(memmove); 46EXPORT_SYMBOL(memmove);
60EXPORT_SYMBOL(memcmp);
61EXPORT_SYMBOL(memscan);
62EXPORT_SYMBOL(__copy_user); 47EXPORT_SYMBOL(__copy_user);
63EXPORT_SYMBOL(boot_cpu_data); 48EXPORT_SYMBOL(boot_cpu_data);
64 49
@@ -94,7 +79,9 @@ EXPORT_SYMBOL(strcpy);
94DECLARE_EXPORT(__movstr_i4_even); 79DECLARE_EXPORT(__movstr_i4_even);
95DECLARE_EXPORT(__movstr_i4_odd); 80DECLARE_EXPORT(__movstr_i4_odd);
96DECLARE_EXPORT(__movstrSI12_i4); 81DECLARE_EXPORT(__movstrSI12_i4);
82#endif
97 83
84#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)
98/* needed by some modules */ 85/* needed by some modules */
99EXPORT_SYMBOL(flush_cache_all); 86EXPORT_SYMBOL(flush_cache_all);
100EXPORT_SYMBOL(flush_cache_range); 87EXPORT_SYMBOL(flush_cache_range);
@@ -102,11 +89,9 @@ EXPORT_SYMBOL(flush_dcache_page);
102EXPORT_SYMBOL(__flush_purge_region); 89EXPORT_SYMBOL(__flush_purge_region);
103#endif 90#endif
104 91
105#if defined(CONFIG_SH7705_CACHE_32KB) 92#if defined(CONFIG_MMU) && (defined(CONFIG_CPU_SH4) || \
106EXPORT_SYMBOL(flush_cache_all); 93 defined(CONFIG_SH7705_CACHE_32KB))
107EXPORT_SYMBOL(flush_cache_range); 94EXPORT_SYMBOL(clear_user_page);
108EXPORT_SYMBOL(flush_dcache_page);
109EXPORT_SYMBOL(__flush_purge_region);
110#endif 95#endif
111 96
112EXPORT_SYMBOL(flush_tlb_page); 97EXPORT_SYMBOL(flush_tlb_page);
@@ -116,7 +101,12 @@ EXPORT_SYMBOL(__down_trylock);
116EXPORT_SYMBOL(synchronize_irq); 101EXPORT_SYMBOL(synchronize_irq);
117#endif 102#endif
118 103
104#ifdef CONFIG_PM
105EXPORT_SYMBOL(pm_suspend);
106#endif
107
119EXPORT_SYMBOL(csum_partial); 108EXPORT_SYMBOL(csum_partial);
109#ifdef CONFIG_IPV6
120EXPORT_SYMBOL(csum_ipv6_magic); 110EXPORT_SYMBOL(csum_ipv6_magic);
121EXPORT_SYMBOL(consistent_sync); 111#endif
122EXPORT_SYMBOL(clear_page); 112EXPORT_SYMBOL(clear_page);
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index b475c4d2405f..5213f5bc6ce0 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -8,7 +8,6 @@
8 * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima 8 * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima
9 * 9 *
10 */ 10 */
11
12#include <linux/sched.h> 11#include <linux/sched.h>
13#include <linux/mm.h> 12#include <linux/mm.h>
14#include <linux/smp.h> 13#include <linux/smp.h>
@@ -21,6 +20,7 @@
21#include <linux/unistd.h> 20#include <linux/unistd.h>
22#include <linux/stddef.h> 21#include <linux/stddef.h>
23#include <linux/tty.h> 22#include <linux/tty.h>
23#include <linux/elf.h>
24#include <linux/personality.h> 24#include <linux/personality.h>
25#include <linux/binfmts.h> 25#include <linux/binfmts.h>
26 26
@@ -29,12 +29,8 @@
29#include <asm/pgtable.h> 29#include <asm/pgtable.h>
30#include <asm/cacheflush.h> 30#include <asm/cacheflush.h>
31 31
32#define DEBUG_SIG 0
33
34#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 32#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
35 33
36asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
37
38/* 34/*
39 * Atomically swap in the new signal mask, and wait for a signal. 35 * Atomically swap in the new signal mask, and wait for a signal.
40 */ 36 */
@@ -43,51 +39,17 @@ sys_sigsuspend(old_sigset_t mask,
43 unsigned long r5, unsigned long r6, unsigned long r7, 39 unsigned long r5, unsigned long r6, unsigned long r7,
44 struct pt_regs regs) 40 struct pt_regs regs)
45{ 41{
46 sigset_t saveset;
47
48 mask &= _BLOCKABLE; 42 mask &= _BLOCKABLE;
49 spin_lock_irq(&current->sighand->siglock); 43 spin_lock_irq(&current->sighand->siglock);
50 saveset = current->blocked; 44 current->saved_sigmask = current->blocked;
51 siginitset(&current->blocked, mask); 45 siginitset(&current->blocked, mask);
52 recalc_sigpending(); 46 recalc_sigpending();
53 spin_unlock_irq(&current->sighand->siglock); 47 spin_unlock_irq(&current->sighand->siglock);
54 48
55 regs.regs[0] = -EINTR; 49 current->state = TASK_INTERRUPTIBLE;
56 while (1) { 50 schedule();
57 current->state = TASK_INTERRUPTIBLE; 51 set_thread_flag(TIF_RESTORE_SIGMASK);
58 schedule(); 52 return -ERESTARTNOHAND;
59 if (do_signal(&regs, &saveset))
60 return -EINTR;
61 }
62}
63
64asmlinkage int
65sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize,
66 unsigned long r6, unsigned long r7,
67 struct pt_regs regs)
68{
69 sigset_t saveset, newset;
70
71 /* XXX: Don't preclude handling different sized sigset_t's. */
72 if (sigsetsize != sizeof(sigset_t))
73 return -EINVAL;
74
75 if (copy_from_user(&newset, unewset, sizeof(newset)))
76 return -EFAULT;
77 sigdelsetmask(&newset, ~_BLOCKABLE);
78 spin_lock_irq(&current->sighand->siglock);
79 saveset = current->blocked;
80 current->blocked = newset;
81 recalc_sigpending();
82 spin_unlock_irq(&current->sighand->siglock);
83
84 regs.regs[0] = -EINTR;
85 while (1) {
86 current->state = TASK_INTERRUPTIBLE;
87 schedule();
88 if (do_signal(&regs, &saveset))
89 return -EINTR;
90 }
91} 53}
92 54
93asmlinkage int 55asmlinkage int
@@ -348,7 +310,12 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
348 return (void __user *)((sp - frame_size) & -8ul); 310 return (void __user *)((sp - frame_size) & -8ul);
349} 311}
350 312
351static void setup_frame(int sig, struct k_sigaction *ka, 313/* These symbols are defined with the addresses in the vsyscall page.
314 See vsyscall-trapa.S. */
315extern void __user __kernel_sigreturn;
316extern void __user __kernel_rt_sigreturn;
317
318static int setup_frame(int sig, struct k_sigaction *ka,
352 sigset_t *set, struct pt_regs *regs) 319 sigset_t *set, struct pt_regs *regs)
353{ 320{
354 struct sigframe __user *frame; 321 struct sigframe __user *frame;
@@ -368,15 +335,18 @@ static void setup_frame(int sig, struct k_sigaction *ka,
368 335
369 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); 336 err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
370 337
371 if (_NSIG_WORDS > 1) { 338 if (_NSIG_WORDS > 1)
372 err |= __copy_to_user(frame->extramask, &set->sig[1], 339 err |= __copy_to_user(frame->extramask, &set->sig[1],
373 sizeof(frame->extramask)); 340 sizeof(frame->extramask));
374 }
375 341
376 /* Set up to return from userspace. If provided, use a stub 342 /* Set up to return from userspace. If provided, use a stub
377 already in userspace. */ 343 already in userspace. */
378 if (ka->sa.sa_flags & SA_RESTORER) { 344 if (ka->sa.sa_flags & SA_RESTORER) {
379 regs->pr = (unsigned long) ka->sa.sa_restorer; 345 regs->pr = (unsigned long) ka->sa.sa_restorer;
346#ifdef CONFIG_VSYSCALL
347 } else if (likely(current->mm->context.vdso)) {
348 regs->pr = VDSO_SYM(&__kernel_sigreturn);
349#endif
380 } else { 350 } else {
381 /* Generate return code (system call to sigreturn) */ 351 /* Generate return code (system call to sigreturn) */
382 err |= __put_user(MOVW(7), &frame->retcode[0]); 352 err |= __put_user(MOVW(7), &frame->retcode[0]);
@@ -402,21 +372,22 @@ static void setup_frame(int sig, struct k_sigaction *ka,
402 372
403 set_fs(USER_DS); 373 set_fs(USER_DS);
404 374
405#if DEBUG_SIG 375 pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
406 printk("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n", 376 current->comm, current->pid, frame, regs->pc, regs->pr);
407 current->comm, current->pid, frame, regs->pc, regs->pr);
408#endif
409 377
410 flush_cache_sigtramp(regs->pr); 378 flush_cache_sigtramp(regs->pr);
379
411 if ((-regs->pr & (L1_CACHE_BYTES-1)) < sizeof(frame->retcode)) 380 if ((-regs->pr & (L1_CACHE_BYTES-1)) < sizeof(frame->retcode))
412 flush_cache_sigtramp(regs->pr + L1_CACHE_BYTES); 381 flush_cache_sigtramp(regs->pr + L1_CACHE_BYTES);
413 return; 382
383 return 0;
414 384
415give_sigsegv: 385give_sigsegv:
416 force_sigsegv(sig, current); 386 force_sigsegv(sig, current);
387 return -EFAULT;
417} 388}
418 389
419static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 390static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
420 sigset_t *set, struct pt_regs *regs) 391 sigset_t *set, struct pt_regs *regs)
421{ 392{
422 struct rt_sigframe __user *frame; 393 struct rt_sigframe __user *frame;
@@ -452,6 +423,10 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
452 already in userspace. */ 423 already in userspace. */
453 if (ka->sa.sa_flags & SA_RESTORER) { 424 if (ka->sa.sa_flags & SA_RESTORER) {
454 regs->pr = (unsigned long) ka->sa.sa_restorer; 425 regs->pr = (unsigned long) ka->sa.sa_restorer;
426#ifdef CONFIG_VSYSCALL
427 } else if (likely(current->mm->context.vdso)) {
428 regs->pr = VDSO_SYM(&__kernel_rt_sigreturn);
429#endif
455 } else { 430 } else {
456 /* Generate return code (system call to rt_sigreturn) */ 431 /* Generate return code (system call to rt_sigreturn) */
457 err |= __put_user(MOVW(7), &frame->retcode[0]); 432 err |= __put_user(MOVW(7), &frame->retcode[0]);
@@ -477,28 +452,31 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
477 452
478 set_fs(USER_DS); 453 set_fs(USER_DS);
479 454
480#if DEBUG_SIG 455 pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
481 printk("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n", 456 current->comm, current->pid, frame, regs->pc, regs->pr);
482 current->comm, current->pid, frame, regs->pc, regs->pr);
483#endif
484 457
485 flush_cache_sigtramp(regs->pr); 458 flush_cache_sigtramp(regs->pr);
459
486 if ((-regs->pr & (L1_CACHE_BYTES-1)) < sizeof(frame->retcode)) 460 if ((-regs->pr & (L1_CACHE_BYTES-1)) < sizeof(frame->retcode))
487 flush_cache_sigtramp(regs->pr + L1_CACHE_BYTES); 461 flush_cache_sigtramp(regs->pr + L1_CACHE_BYTES);
488 return; 462
463 return 0;
489 464
490give_sigsegv: 465give_sigsegv:
491 force_sigsegv(sig, current); 466 force_sigsegv(sig, current);
467 return -EFAULT;
492} 468}
493 469
494/* 470/*
495 * OK, we're invoking a handler 471 * OK, we're invoking a handler
496 */ 472 */
497 473
498static void 474static int
499handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, 475handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
500 sigset_t *oldset, struct pt_regs *regs) 476 sigset_t *oldset, struct pt_regs *regs)
501{ 477{
478 int ret;
479
502 /* Are we from a system call? */ 480 /* Are we from a system call? */
503 if (regs->tra >= 0) { 481 if (regs->tra >= 0) {
504 /* If so, check system call restarting.. */ 482 /* If so, check system call restarting.. */
@@ -539,19 +517,23 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
539 517
540 /* Set up the stack frame */ 518 /* Set up the stack frame */
541 if (ka->sa.sa_flags & SA_SIGINFO) 519 if (ka->sa.sa_flags & SA_SIGINFO)
542 setup_rt_frame(sig, ka, info, oldset, regs); 520 ret = setup_rt_frame(sig, ka, info, oldset, regs);
543 else 521 else
544 setup_frame(sig, ka, oldset, regs); 522 ret = setup_frame(sig, ka, oldset, regs);
545 523
546 if (ka->sa.sa_flags & SA_ONESHOT) 524 if (ka->sa.sa_flags & SA_ONESHOT)
547 ka->sa.sa_handler = SIG_DFL; 525 ka->sa.sa_handler = SIG_DFL;
548 526
549 spin_lock_irq(&current->sighand->siglock); 527 if (ret == 0) {
550 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 528 spin_lock_irq(&current->sighand->siglock);
551 if (!(ka->sa.sa_flags & SA_NODEFER)) 529 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
552 sigaddset(&current->blocked,sig); 530 if (!(ka->sa.sa_flags & SA_NODEFER))
553 recalc_sigpending(); 531 sigaddset(&current->blocked,sig);
554 spin_unlock_irq(&current->sighand->siglock); 532 recalc_sigpending();
533 spin_unlock_irq(&current->sighand->siglock);
534 }
535
536 return ret;
555} 537}
556 538
557/* 539/*
@@ -563,11 +545,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
563 * the kernel can handle, and then we build all the user-level signal handling 545 * the kernel can handle, and then we build all the user-level signal handling
564 * stack-frames in one go after that. 546 * stack-frames in one go after that.
565 */ 547 */
566int do_signal(struct pt_regs *regs, sigset_t *oldset) 548static void do_signal(struct pt_regs *regs, unsigned int save_r0)
567{ 549{
568 siginfo_t info; 550 siginfo_t info;
569 int signr; 551 int signr;
570 struct k_sigaction ka; 552 struct k_sigaction ka;
553 sigset_t *oldset;
571 554
572 /* 555 /*
573 * We want the common case to go fast, which 556 * We want the common case to go fast, which
@@ -576,19 +559,27 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
576 * if so. 559 * if so.
577 */ 560 */
578 if (!user_mode(regs)) 561 if (!user_mode(regs))
579 return 1; 562 return;
580 563
581 if (try_to_freeze()) 564 if (try_to_freeze())
582 goto no_signal; 565 goto no_signal;
583 566
584 if (!oldset) 567 if (test_thread_flag(TIF_RESTORE_SIGMASK))
568 oldset = &current->saved_sigmask;
569 else
585 oldset = &current->blocked; 570 oldset = &current->blocked;
586 571
587 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 572 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
588 if (signr > 0) { 573 if (signr > 0) {
589 /* Whee! Actually deliver the signal. */ 574 /* Whee! Actually deliver the signal. */
590 handle_signal(signr, &ka, &info, oldset, regs); 575 if (handle_signal(signr, &ka, &info, oldset, regs) == 0) {
591 return 1; 576 /* a signal was successfully delivered; the saved
577 * sigmask will have been stored in the signal frame,
578 * and will be restored by sigreturn, so we can simply
579 * clear the TIF_RESTORE_SIGMASK flag */
580 if (test_thread_flag(TIF_RESTORE_SIGMASK))
581 clear_thread_flag(TIF_RESTORE_SIGMASK);
582 }
592 } 583 }
593 584
594 no_signal: 585 no_signal:
@@ -597,10 +588,27 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
597 /* Restart the system call - no handlers present */ 588 /* Restart the system call - no handlers present */
598 if (regs->regs[0] == -ERESTARTNOHAND || 589 if (regs->regs[0] == -ERESTARTNOHAND ||
599 regs->regs[0] == -ERESTARTSYS || 590 regs->regs[0] == -ERESTARTSYS ||
600 regs->regs[0] == -ERESTARTNOINTR || 591 regs->regs[0] == -ERESTARTNOINTR) {
601 regs->regs[0] == -ERESTART_RESTARTBLOCK) { 592 regs->regs[0] = save_r0;
593 regs->pc -= 2;
594 } else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) {
602 regs->pc -= 2; 595 regs->pc -= 2;
596 regs->regs[3] = __NR_restart_syscall;
603 } 597 }
604 } 598 }
605 return 0; 599
600 /* if there's no signal to deliver, we just put the saved sigmask
601 * back */
602 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
603 clear_thread_flag(TIF_RESTORE_SIGMASK);
604 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
605 }
606}
607
608asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0,
609 __u32 thread_info_flags)
610{
611 /* deal with pending signal delivery */
612 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
613 do_signal(regs, save_r0);
606} 614}
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index 917b2f32f260..b68ff705f067 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -21,7 +21,8 @@
21#include <linux/mman.h> 21#include <linux/mman.h>
22#include <linux/file.h> 22#include <linux/file.h>
23#include <linux/utsname.h> 23#include <linux/utsname.h>
24 24#include <linux/module.h>
25#include <asm/cacheflush.h>
25#include <asm/uaccess.h> 26#include <asm/uaccess.h>
26#include <asm/ipc.h> 27#include <asm/ipc.h>
27 28
@@ -44,11 +45,16 @@ asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
44 return error; 45 return error;
45} 46}
46 47
47#if defined(HAVE_ARCH_UNMAPPED_AREA) 48unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */
49
50EXPORT_SYMBOL(shm_align_mask);
51
48/* 52/*
49 * To avoid cache alias, we map the shard page with same color. 53 * To avoid cache aliases, we map the shared page with same color.
50 */ 54 */
51#define COLOUR_ALIGN(addr) (((addr)+SHMLBA-1)&~(SHMLBA-1)) 55#define COLOUR_ALIGN(addr, pgoff) \
56 ((((addr) + shm_align_mask) & ~shm_align_mask) + \
57 (((pgoff) << PAGE_SHIFT) & shm_align_mask))
52 58
53unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, 59unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
54 unsigned long len, unsigned long pgoff, unsigned long flags) 60 unsigned long len, unsigned long pgoff, unsigned long flags)
@@ -56,43 +62,52 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
56 struct mm_struct *mm = current->mm; 62 struct mm_struct *mm = current->mm;
57 struct vm_area_struct *vma; 63 struct vm_area_struct *vma;
58 unsigned long start_addr; 64 unsigned long start_addr;
65 int do_colour_align;
59 66
60 if (flags & MAP_FIXED) { 67 if (flags & MAP_FIXED) {
61 /* We do not accept a shared mapping if it would violate 68 /* We do not accept a shared mapping if it would violate
62 * cache aliasing constraints. 69 * cache aliasing constraints.
63 */ 70 */
64 if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1))) 71 if ((flags & MAP_SHARED) && (addr & shm_align_mask))
65 return -EINVAL; 72 return -EINVAL;
66 return addr; 73 return addr;
67 } 74 }
68 75
69 if (len > TASK_SIZE) 76 if (unlikely(len > TASK_SIZE))
70 return -ENOMEM; 77 return -ENOMEM;
71 78
79 do_colour_align = 0;
80 if (filp || (flags & MAP_SHARED))
81 do_colour_align = 1;
82
72 if (addr) { 83 if (addr) {
73 if (flags & MAP_PRIVATE) 84 if (do_colour_align)
74 addr = PAGE_ALIGN(addr); 85 addr = COLOUR_ALIGN(addr, pgoff);
75 else 86 else
76 addr = COLOUR_ALIGN(addr); 87 addr = PAGE_ALIGN(addr);
88
77 vma = find_vma(mm, addr); 89 vma = find_vma(mm, addr);
78 if (TASK_SIZE - len >= addr && 90 if (TASK_SIZE - len >= addr &&
79 (!vma || addr + len <= vma->vm_start)) 91 (!vma || addr + len <= vma->vm_start))
80 return addr; 92 return addr;
81 } 93 }
82 if (len <= mm->cached_hole_size) { 94
95 if (len > mm->cached_hole_size) {
96 start_addr = addr = mm->free_area_cache;
97 } else {
83 mm->cached_hole_size = 0; 98 mm->cached_hole_size = 0;
84 mm->free_area_cache = TASK_UNMAPPED_BASE; 99 start_addr = addr = TASK_UNMAPPED_BASE;
85 } 100 }
86 if (flags & MAP_PRIVATE)
87 addr = PAGE_ALIGN(mm->free_area_cache);
88 else
89 addr = COLOUR_ALIGN(mm->free_area_cache);
90 start_addr = addr;
91 101
92full_search: 102full_search:
103 if (do_colour_align)
104 addr = COLOUR_ALIGN(addr, pgoff);
105 else
106 addr = PAGE_ALIGN(mm->free_area_cache);
107
93 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { 108 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
94 /* At this point: (!vma || addr < vma->vm_end). */ 109 /* At this point: (!vma || addr < vma->vm_end). */
95 if (TASK_SIZE - len < addr) { 110 if (unlikely(TASK_SIZE - len < addr)) {
96 /* 111 /*
97 * Start a new search - just in case we missed 112 * Start a new search - just in case we missed
98 * some holes. 113 * some holes.
@@ -104,7 +119,7 @@ full_search:
104 } 119 }
105 return -ENOMEM; 120 return -ENOMEM;
106 } 121 }
107 if (!vma || addr + len <= vma->vm_start) { 122 if (likely(!vma || addr + len <= vma->vm_start)) {
108 /* 123 /*
109 * Remember the place where we stopped the search: 124 * Remember the place where we stopped the search:
110 */ 125 */
@@ -115,11 +130,10 @@ full_search:
115 mm->cached_hole_size = vma->vm_start - addr; 130 mm->cached_hole_size = vma->vm_start - addr;
116 131
117 addr = vma->vm_end; 132 addr = vma->vm_end;
118 if (!(flags & MAP_PRIVATE)) 133 if (do_colour_align)
119 addr = COLOUR_ALIGN(addr); 134 addr = COLOUR_ALIGN(addr, pgoff);
120 } 135 }
121} 136}
122#endif
123 137
124static inline long 138static inline long
125do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, 139do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
diff --git a/arch/sh/kernel/syscalls.S b/arch/sh/kernel/syscalls.S
new file mode 100644
index 000000000000..768334e95075
--- /dev/null
+++ b/arch/sh/kernel/syscalls.S
@@ -0,0 +1,353 @@
1/*
2 * arch/sh/kernel/syscalls.S
3 *
4 * System call table for SuperH
5 *
6 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka
7 * Copyright (C) 2003 Paul Mundt
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 *
13 */
14#include <linux/sys.h>
15#include <linux/linkage.h>
16
17#if !defined(CONFIG_NFSD) && !defined(CONFIG_NFSD_MODULE)
18#define sys_nfsservctl sys_ni_syscall
19#endif
20
21#if !defined(CONFIG_MMU)
22#define sys_madvise sys_ni_syscall
23#define sys_readahead sys_ni_syscall
24#define sys_mprotect sys_ni_syscall
25#define sys_msync sys_ni_syscall
26#define sys_mlock sys_ni_syscall
27#define sys_munlock sys_ni_syscall
28#define sys_mlockall sys_ni_syscall
29#define sys_munlockall sys_ni_syscall
30#define sys_mremap sys_ni_syscall
31#define sys_mincore sys_ni_syscall
32#define sys_remap_file_pages sys_ni_syscall
33#endif
34
35 .data
36ENTRY(sys_call_table)
37 .long sys_restart_syscall /* 0 - old "setup()" system call*/
38 .long sys_exit
39 .long sys_fork
40 .long sys_read
41 .long sys_write
42 .long sys_open /* 5 */
43 .long sys_close
44 .long sys_waitpid
45 .long sys_creat
46 .long sys_link
47 .long sys_unlink /* 10 */
48 .long sys_execve
49 .long sys_chdir
50 .long sys_time
51 .long sys_mknod
52 .long sys_chmod /* 15 */
53 .long sys_lchown16
54 .long sys_ni_syscall /* old break syscall holder */
55 .long sys_stat
56 .long sys_lseek
57 .long sys_getpid /* 20 */
58 .long sys_mount
59 .long sys_oldumount
60 .long sys_setuid16
61 .long sys_getuid16
62 .long sys_stime /* 25 */
63 .long sys_ptrace
64 .long sys_alarm
65 .long sys_fstat
66 .long sys_pause
67 .long sys_utime /* 30 */
68 .long sys_ni_syscall /* old stty syscall holder */
69 .long sys_ni_syscall /* old gtty syscall holder */
70 .long sys_access
71 .long sys_nice
72 .long sys_ni_syscall /* 35 */ /* old ftime syscall holder */
73 .long sys_sync
74 .long sys_kill
75 .long sys_rename
76 .long sys_mkdir
77 .long sys_rmdir /* 40 */
78 .long sys_dup
79 .long sys_pipe
80 .long sys_times
81 .long sys_ni_syscall /* old prof syscall holder */
82 .long sys_brk /* 45 */
83 .long sys_setgid16
84 .long sys_getgid16
85 .long sys_signal
86 .long sys_geteuid16
87 .long sys_getegid16 /* 50 */
88 .long sys_acct
89 .long sys_umount /* recycled never used phys() */
90 .long sys_ni_syscall /* old lock syscall holder */
91 .long sys_ioctl
92 .long sys_fcntl /* 55 */
93 .long sys_ni_syscall /* old mpx syscall holder */
94 .long sys_setpgid
95 .long sys_ni_syscall /* old ulimit syscall holder */
96 .long sys_ni_syscall /* sys_olduname */
97 .long sys_umask /* 60 */
98 .long sys_chroot
99 .long sys_ustat
100 .long sys_dup2
101 .long sys_getppid
102 .long sys_getpgrp /* 65 */
103 .long sys_setsid
104 .long sys_sigaction
105 .long sys_sgetmask
106 .long sys_ssetmask
107 .long sys_setreuid16 /* 70 */
108 .long sys_setregid16
109 .long sys_sigsuspend
110 .long sys_sigpending
111 .long sys_sethostname
112 .long sys_setrlimit /* 75 */
113 .long sys_old_getrlimit
114 .long sys_getrusage
115 .long sys_gettimeofday
116 .long sys_settimeofday
117 .long sys_getgroups16 /* 80 */
118 .long sys_setgroups16
119 .long sys_ni_syscall /* sys_oldselect */
120 .long sys_symlink
121 .long sys_lstat
122 .long sys_readlink /* 85 */
123 .long sys_uselib
124 .long sys_swapon
125 .long sys_reboot
126 .long old_readdir
127 .long old_mmap /* 90 */
128 .long sys_munmap
129 .long sys_truncate
130 .long sys_ftruncate
131 .long sys_fchmod
132 .long sys_fchown16 /* 95 */
133 .long sys_getpriority
134 .long sys_setpriority
135 .long sys_ni_syscall /* old profil syscall holder */
136 .long sys_statfs
137 .long sys_fstatfs /* 100 */
138 .long sys_ni_syscall /* ioperm */
139 .long sys_socketcall
140 .long sys_syslog
141 .long sys_setitimer
142 .long sys_getitimer /* 105 */
143 .long sys_newstat
144 .long sys_newlstat
145 .long sys_newfstat
146 .long sys_uname
147 .long sys_ni_syscall /* 110 */ /* iopl */
148 .long sys_vhangup
149 .long sys_ni_syscall /* idle */
150 .long sys_ni_syscall /* vm86old */
151 .long sys_wait4
152 .long sys_swapoff /* 115 */
153 .long sys_sysinfo
154 .long sys_ipc
155 .long sys_fsync
156 .long sys_sigreturn
157 .long sys_clone /* 120 */
158 .long sys_setdomainname
159 .long sys_newuname
160 .long sys_ni_syscall /* sys_modify_ldt */
161 .long sys_adjtimex
162 .long sys_mprotect /* 125 */
163 .long sys_sigprocmask
164 .long sys_ni_syscall /* old "create_module" */
165 .long sys_init_module
166 .long sys_delete_module
167 .long sys_ni_syscall /* 130: old "get_kernel_syms" */
168 .long sys_quotactl
169 .long sys_getpgid
170 .long sys_fchdir
171 .long sys_bdflush
172 .long sys_sysfs /* 135 */
173 .long sys_personality
174 .long sys_ni_syscall /* for afs_syscall */
175 .long sys_setfsuid16
176 .long sys_setfsgid16
177 .long sys_llseek /* 140 */
178 .long sys_getdents
179 .long sys_select
180 .long sys_flock
181 .long sys_msync
182 .long sys_readv /* 145 */
183 .long sys_writev
184 .long sys_getsid
185 .long sys_fdatasync
186 .long sys_sysctl
187 .long sys_mlock /* 150 */
188 .long sys_munlock
189 .long sys_mlockall
190 .long sys_munlockall
191 .long sys_sched_setparam
192 .long sys_sched_getparam /* 155 */
193 .long sys_sched_setscheduler
194 .long sys_sched_getscheduler
195 .long sys_sched_yield
196 .long sys_sched_get_priority_max
197 .long sys_sched_get_priority_min /* 160 */
198 .long sys_sched_rr_get_interval
199 .long sys_nanosleep
200 .long sys_mremap
201 .long sys_setresuid16
202 .long sys_getresuid16 /* 165 */
203 .long sys_ni_syscall /* vm86 */
204 .long sys_ni_syscall /* old "query_module" */
205 .long sys_poll
206 .long sys_nfsservctl
207 .long sys_setresgid16 /* 170 */
208 .long sys_getresgid16
209 .long sys_prctl
210 .long sys_rt_sigreturn
211 .long sys_rt_sigaction
212 .long sys_rt_sigprocmask /* 175 */
213 .long sys_rt_sigpending
214 .long sys_rt_sigtimedwait
215 .long sys_rt_sigqueueinfo
216 .long sys_rt_sigsuspend
217 .long sys_pread_wrapper /* 180 */
218 .long sys_pwrite_wrapper
219 .long sys_chown16
220 .long sys_getcwd
221 .long sys_capget
222 .long sys_capset /* 185 */
223 .long sys_sigaltstack
224 .long sys_sendfile
225 .long sys_ni_syscall /* streams1 */
226 .long sys_ni_syscall /* streams2 */
227 .long sys_vfork /* 190 */
228 .long sys_getrlimit
229 .long sys_mmap2
230 .long sys_truncate64
231 .long sys_ftruncate64
232 .long sys_stat64 /* 195 */
233 .long sys_lstat64
234 .long sys_fstat64
235 .long sys_lchown
236 .long sys_getuid
237 .long sys_getgid /* 200 */
238 .long sys_geteuid
239 .long sys_getegid
240 .long sys_setreuid
241 .long sys_setregid
242 .long sys_getgroups /* 205 */
243 .long sys_setgroups
244 .long sys_fchown
245 .long sys_setresuid
246 .long sys_getresuid
247 .long sys_setresgid /* 210 */
248 .long sys_getresgid
249 .long sys_chown
250 .long sys_setuid
251 .long sys_setgid
252 .long sys_setfsuid /* 215 */
253 .long sys_setfsgid
254 .long sys_pivot_root
255 .long sys_mincore
256 .long sys_madvise
257 .long sys_getdents64 /* 220 */
258 .long sys_fcntl64
259 .long sys_ni_syscall /* reserved for TUX */
260 .long sys_ni_syscall /* Reserved for Security */
261 .long sys_gettid
262 .long sys_readahead /* 225 */
263 .long sys_setxattr
264 .long sys_lsetxattr
265 .long sys_fsetxattr
266 .long sys_getxattr
267 .long sys_lgetxattr /* 230 */
268 .long sys_fgetxattr
269 .long sys_listxattr
270 .long sys_llistxattr
271 .long sys_flistxattr
272 .long sys_removexattr /* 235 */
273 .long sys_lremovexattr
274 .long sys_fremovexattr
275 .long sys_tkill
276 .long sys_sendfile64
277 .long sys_futex /* 240 */
278 .long sys_sched_setaffinity
279 .long sys_sched_getaffinity
280 .long sys_ni_syscall
281 .long sys_ni_syscall
282 .long sys_io_setup /* 245 */
283 .long sys_io_destroy
284 .long sys_io_getevents
285 .long sys_io_submit
286 .long sys_io_cancel
287 .long sys_fadvise64 /* 250 */
288 .long sys_ni_syscall
289 .long sys_exit_group
290 .long sys_lookup_dcookie
291 .long sys_epoll_create
292 .long sys_epoll_ctl /* 255 */
293 .long sys_epoll_wait
294 .long sys_remap_file_pages
295 .long sys_set_tid_address
296 .long sys_timer_create
297 .long sys_timer_settime /* 260 */
298 .long sys_timer_gettime
299 .long sys_timer_getoverrun
300 .long sys_timer_delete
301 .long sys_clock_settime
302 .long sys_clock_gettime /* 265 */
303 .long sys_clock_getres
304 .long sys_clock_nanosleep
305 .long sys_statfs64
306 .long sys_fstatfs64
307 .long sys_tgkill /* 270 */
308 .long sys_utimes
309 .long sys_fadvise64_64_wrapper
310 .long sys_ni_syscall /* Reserved for vserver */
311 .long sys_ni_syscall /* Reserved for mbind */
312 .long sys_ni_syscall /* 275 - get_mempolicy */
313 .long sys_ni_syscall /* set_mempolicy */
314 .long sys_mq_open
315 .long sys_mq_unlink
316 .long sys_mq_timedsend
317 .long sys_mq_timedreceive /* 280 */
318 .long sys_mq_notify
319 .long sys_mq_getsetattr
320 .long sys_kexec_load
321 .long sys_waitid
322 .long sys_ni_syscall /* 285 */
323 .long sys_add_key
324 .long sys_request_key
325 .long sys_keyctl
326 .long sys_ioprio_set
327 .long sys_ioprio_get /* 290 */
328 .long sys_inotify_init
329 .long sys_inotify_add_watch
330 .long sys_inotify_rm_watch
331 .long sys_migrate_pages
332 .long sys_openat /* 295 */
333 .long sys_mkdirat
334 .long sys_mknodat
335 .long sys_fchownat
336 .long sys_futimesat
337 .long sys_fstatat64 /* 300 */
338 .long sys_unlinkat
339 .long sys_renameat
340 .long sys_linkat
341 .long sys_symlinkat
342 .long sys_readlinkat /* 305 */
343 .long sys_fchmodat
344 .long sys_faccessat
345 .long sys_pselect6
346 .long sys_ppoll
347 .long sys_unshare /* 310 */
348 .long sys_set_robust_list
349 .long sys_get_robust_list
350 .long sys_splice
351 .long sys_sync_file_range
352 .long sys_tee /* 315 */
353 .long sys_vmsplice
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
index a1589f85499d..149d9713eddf 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time.c
@@ -3,13 +3,12 @@
3 * 3 *
4 * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka 4 * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
5 * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> 5 * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
6 * Copyright (C) 2002, 2003, 2004, 2005 Paul Mundt 6 * Copyright (C) 2002 - 2006 Paul Mundt
7 * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org> 7 * Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org>
8 * 8 *
9 * Some code taken from i386 version. 9 * Some code taken from i386 version.
10 * Copyright (C) 1991, 1992, 1995 Linus Torvalds 10 * Copyright (C) 1991, 1992, 1995 Linus Torvalds
11 */ 11 */
12
13#include <linux/kernel.h> 12#include <linux/kernel.h>
14#include <linux/module.h> 13#include <linux/module.h>
15#include <linux/init.h> 14#include <linux/init.h>
@@ -26,15 +25,20 @@ struct sys_timer *sys_timer;
26DEFINE_SPINLOCK(rtc_lock); 25DEFINE_SPINLOCK(rtc_lock);
27EXPORT_SYMBOL(rtc_lock); 26EXPORT_SYMBOL(rtc_lock);
28 27
29/* XXX: Can we initialize this in a routine somewhere? Dreamcast doesn't want 28/* Dummy RTC ops */
30 * these routines anywhere... */ 29static void null_rtc_get_time(struct timespec *tv)
31#ifdef CONFIG_SH_RTC 30{
32void (*rtc_get_time)(struct timespec *) = sh_rtc_gettimeofday; 31 tv->tv_sec = mktime(2000, 1, 1, 0, 0, 0);
33int (*rtc_set_time)(const time_t) = sh_rtc_settimeofday; 32 tv->tv_nsec = 0;
34#else 33}
35void (*rtc_get_time)(struct timespec *); 34
36int (*rtc_set_time)(const time_t); 35static int null_rtc_set_time(const time_t secs)
37#endif 36{
37 return 0;
38}
39
40void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time;
41int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time;
38 42
39/* 43/*
40 * Scheduler clock - returns current time in nanosec units. 44 * Scheduler clock - returns current time in nanosec units.
@@ -70,7 +74,6 @@ void do_gettimeofday(struct timeval *tv)
70 tv->tv_sec = sec; 74 tv->tv_sec = sec;
71 tv->tv_usec = usec; 75 tv->tv_usec = usec;
72} 76}
73
74EXPORT_SYMBOL(do_gettimeofday); 77EXPORT_SYMBOL(do_gettimeofday);
75 78
76int do_settimeofday(struct timespec *tv) 79int do_settimeofday(struct timespec *tv)
@@ -103,7 +106,6 @@ int do_settimeofday(struct timespec *tv)
103 106
104 return 0; 107 return 0;
105} 108}
106
107EXPORT_SYMBOL(do_settimeofday); 109EXPORT_SYMBOL(do_settimeofday);
108 110
109/* last time the RTC clock got updated */ 111/* last time the RTC clock got updated */
@@ -135,7 +137,7 @@ void handle_timer_tick(struct pt_regs *regs)
135 xtime.tv_sec > last_rtc_update + 660 && 137 xtime.tv_sec > last_rtc_update + 660 &&
136 (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && 138 (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
137 (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { 139 (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
138 if (rtc_set_time(xtime.tv_sec) == 0) 140 if (rtc_sh_set_time(xtime.tv_sec) == 0)
139 last_rtc_update = xtime.tv_sec; 141 last_rtc_update = xtime.tv_sec;
140 else 142 else
141 /* do it again in 60s */ 143 /* do it again in 60s */
@@ -143,8 +145,33 @@ void handle_timer_tick(struct pt_regs *regs)
143 } 145 }
144} 146}
145 147
148#ifdef CONFIG_PM
149int timer_suspend(struct sys_device *dev, pm_message_t state)
150{
151 struct sys_timer *sys_timer = container_of(dev, struct sys_timer, dev);
152
153 sys_timer->ops->stop();
154
155 return 0;
156}
157
158int timer_resume(struct sys_device *dev)
159{
160 struct sys_timer *sys_timer = container_of(dev, struct sys_timer, dev);
161
162 sys_timer->ops->start();
163
164 return 0;
165}
166#else
167#define timer_suspend NULL
168#define timer_resume NULL
169#endif
170
146static struct sysdev_class timer_sysclass = { 171static struct sysdev_class timer_sysclass = {
147 set_kset_name("timer"), 172 set_kset_name("timer"),
173 .suspend = timer_suspend,
174 .resume = timer_resume,
148}; 175};
149 176
150static int __init timer_init_sysfs(void) 177static int __init timer_init_sysfs(void)
@@ -156,7 +183,6 @@ static int __init timer_init_sysfs(void)
156 sys_timer->dev.cls = &timer_sysclass; 183 sys_timer->dev.cls = &timer_sysclass;
157 return sysdev_register(&sys_timer->dev); 184 return sysdev_register(&sys_timer->dev);
158} 185}
159
160device_initcall(timer_init_sysfs); 186device_initcall(timer_init_sysfs);
161 187
162void (*board_time_init)(void); 188void (*board_time_init)(void);
@@ -168,15 +194,9 @@ void __init time_init(void)
168 194
169 clk_init(); 195 clk_init();
170 196
171 if (rtc_get_time) { 197 rtc_sh_get_time(&xtime);
172 rtc_get_time(&xtime); 198 set_normalized_timespec(&wall_to_monotonic,
173 } else { 199 -xtime.tv_sec, -xtime.tv_nsec);
174 xtime.tv_sec = mktime(2000, 1, 1, 0, 0, 0);
175 xtime.tv_nsec = 0;
176 }
177
178 set_normalized_timespec(&wall_to_monotonic,
179 -xtime.tv_sec, -xtime.tv_nsec);
180 200
181 /* 201 /*
182 * Find the timer to use as the system timer, it will be 202 * Find the timer to use as the system timer, it will be
diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c
index d4212add53b2..205816fcf0da 100644
--- a/arch/sh/kernel/timers/timer-tmu.c
+++ b/arch/sh/kernel/timers/timer-tmu.c
@@ -132,17 +132,17 @@ static unsigned long tmu_timer_get_frequency(void)
132 ctrl_outl(0xffffffff, TMU0_TCOR); 132 ctrl_outl(0xffffffff, TMU0_TCOR);
133 ctrl_outl(0xffffffff, TMU0_TCNT); 133 ctrl_outl(0xffffffff, TMU0_TCNT);
134 134
135 rtc_get_time(&ts2); 135 rtc_sh_get_time(&ts2);
136 136
137 do { 137 do {
138 rtc_get_time(&ts1); 138 rtc_sh_get_time(&ts1);
139 } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); 139 } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec);
140 140
141 /* actually start the timer */ 141 /* actually start the timer */
142 ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); 142 ctrl_outb(TMU_TSTR_INIT, TMU_TSTR);
143 143
144 do { 144 do {
145 rtc_get_time(&ts2); 145 rtc_sh_get_time(&ts2);
146 } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); 146 } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec);
147 147
148 freq = 0xffffffff - ctrl_inl(TMU0_TCNT); 148 freq = 0xffffffff - ctrl_inl(TMU0_TCNT);
@@ -188,6 +188,18 @@ static struct clk tmu0_clk = {
188 .ops = &tmu_clk_ops, 188 .ops = &tmu_clk_ops,
189}; 189};
190 190
191static int tmu_timer_start(void)
192{
193 ctrl_outb(TMU_TSTR_INIT, TMU_TSTR);
194 return 0;
195}
196
197static int tmu_timer_stop(void)
198{
199 ctrl_outb(0, TMU_TSTR);
200 return 0;
201}
202
191static int tmu_timer_init(void) 203static int tmu_timer_init(void)
192{ 204{
193 unsigned long interval; 205 unsigned long interval;
@@ -197,7 +209,7 @@ static int tmu_timer_init(void)
197 tmu0_clk.parent = clk_get("module_clk"); 209 tmu0_clk.parent = clk_get("module_clk");
198 210
199 /* Start TMU0 */ 211 /* Start TMU0 */
200 ctrl_outb(0, TMU_TSTR); 212 tmu_timer_stop();
201#if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760) 213#if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760)
202 ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); 214 ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
203#endif 215#endif
@@ -211,13 +223,15 @@ static int tmu_timer_init(void)
211 ctrl_outl(interval, TMU0_TCOR); 223 ctrl_outl(interval, TMU0_TCOR);
212 ctrl_outl(interval, TMU0_TCNT); 224 ctrl_outl(interval, TMU0_TCNT);
213 225
214 ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); 226 tmu_timer_start();
215 227
216 return 0; 228 return 0;
217} 229}
218 230
219struct sys_timer_ops tmu_timer_ops = { 231struct sys_timer_ops tmu_timer_ops = {
220 .init = tmu_timer_init, 232 .init = tmu_timer_init,
233 .start = tmu_timer_start,
234 .stop = tmu_timer_stop,
221 .get_frequency = tmu_timer_get_frequency, 235 .get_frequency = tmu_timer_get_frequency,
222 .get_offset = tmu_timer_get_offset, 236 .get_offset = tmu_timer_get_offset,
223}; 237};
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index d9db1180f770..c2c597e09482 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -36,40 +36,15 @@
36 36
37#ifdef CONFIG_SH_KGDB 37#ifdef CONFIG_SH_KGDB
38#include <asm/kgdb.h> 38#include <asm/kgdb.h>
39#define CHK_REMOTE_DEBUG(regs) \ 39#define CHK_REMOTE_DEBUG(regs) \
40{ \ 40{ \
41 if ((kgdb_debug_hook != (kgdb_debug_hook_t *) NULL) && (!user_mode(regs))) \ 41 if (kgdb_debug_hook && !user_mode(regs))\
42 { \ 42 (*kgdb_debug_hook)(regs); \
43 (*kgdb_debug_hook)(regs); \
44 } \
45} 43}
46#else 44#else
47#define CHK_REMOTE_DEBUG(regs) 45#define CHK_REMOTE_DEBUG(regs)
48#endif 46#endif
49 47
50#define DO_ERROR(trapnr, signr, str, name, tsk) \
51asmlinkage void do_##name(unsigned long r4, unsigned long r5, \
52 unsigned long r6, unsigned long r7, \
53 struct pt_regs regs) \
54{ \
55 unsigned long error_code; \
56 \
57 /* Check if it's a DSP instruction */ \
58 if (is_dsp_inst(&regs)) { \
59 /* Enable DSP mode, and restart instruction. */ \
60 regs.sr |= SR_DSP; \
61 return; \
62 } \
63 \
64 asm volatile("stc r2_bank, %0": "=r" (error_code)); \
65 local_irq_enable(); \
66 tsk->thread.error_code = error_code; \
67 tsk->thread.trap_no = trapnr; \
68 CHK_REMOTE_DEBUG(&regs); \
69 force_sig(signr, tsk); \
70 die_if_no_fixup(str,&regs,error_code); \
71}
72
73#ifdef CONFIG_CPU_SH2 48#ifdef CONFIG_CPU_SH2
74#define TRAP_RESERVED_INST 4 49#define TRAP_RESERVED_INST 4
75#define TRAP_ILLEGAL_SLOT_INST 6 50#define TRAP_ILLEGAL_SLOT_INST 6
@@ -86,7 +61,7 @@ asmlinkage void do_##name(unsigned long r4, unsigned long r5, \
86#define VMALLOC_OFFSET (8*1024*1024) 61#define VMALLOC_OFFSET (8*1024*1024)
87#define MODULE_RANGE (8*1024*1024) 62#define MODULE_RANGE (8*1024*1024)
88 63
89spinlock_t die_lock; 64DEFINE_SPINLOCK(die_lock);
90 65
91void die(const char * str, struct pt_regs * regs, long err) 66void die(const char * str, struct pt_regs * regs, long err)
92{ 67{
@@ -575,8 +550,117 @@ int is_dsp_inst(struct pt_regs *regs)
575#define is_dsp_inst(regs) (0) 550#define is_dsp_inst(regs) (0)
576#endif /* CONFIG_SH_DSP */ 551#endif /* CONFIG_SH_DSP */
577 552
578DO_ERROR(TRAP_RESERVED_INST, SIGILL, "reserved instruction", reserved_inst, current) 553extern int do_fpu_inst(unsigned short, struct pt_regs*);
579DO_ERROR(TRAP_ILLEGAL_SLOT_INST, SIGILL, "illegal slot instruction", illegal_slot_inst, current) 554
555asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
556 unsigned long r6, unsigned long r7,
557 struct pt_regs regs)
558{
559 unsigned long error_code;
560 struct task_struct *tsk = current;
561
562#ifdef CONFIG_SH_FPU_EMU
563 unsigned short inst;
564 int err;
565
566 get_user(inst, (unsigned short*)regs.pc);
567
568 err = do_fpu_inst(inst, &regs);
569 if (!err) {
570 regs.pc += 2;
571 return;
572 }
573 /* not a FPU inst. */
574#endif
575
576#ifdef CONFIG_SH_DSP
577 /* Check if it's a DSP instruction */
578 if (is_dsp_inst(&regs)) {
579 /* Enable DSP mode, and restart instruction. */
580 regs.sr |= SR_DSP;
581 return;
582 }
583#endif
584
585 asm volatile("stc r2_bank, %0": "=r" (error_code));
586 local_irq_enable();
587 tsk->thread.error_code = error_code;
588 tsk->thread.trap_no = TRAP_RESERVED_INST;
589 CHK_REMOTE_DEBUG(&regs);
590 force_sig(SIGILL, tsk);
591 die_if_no_fixup("reserved instruction", &regs, error_code);
592}
593
594#ifdef CONFIG_SH_FPU_EMU
595static int emulate_branch(unsigned short inst, struct pt_regs* regs)
596{
597 /*
598 * bfs: 8fxx: PC+=d*2+4;
599 * bts: 8dxx: PC+=d*2+4;
600 * bra: axxx: PC+=D*2+4;
601 * bsr: bxxx: PC+=D*2+4 after PR=PC+4;
602 * braf:0x23: PC+=Rn*2+4;
603 * bsrf:0x03: PC+=Rn*2+4 after PR=PC+4;
604 * jmp: 4x2b: PC=Rn;
605 * jsr: 4x0b: PC=Rn after PR=PC+4;
606 * rts: 000b: PC=PR;
607 */
608 if ((inst & 0xfd00) == 0x8d00) {
609 regs->pc += SH_PC_8BIT_OFFSET(inst);
610 return 0;
611 }
612
613 if ((inst & 0xe000) == 0xa000) {
614 regs->pc += SH_PC_12BIT_OFFSET(inst);
615 return 0;
616 }
617
618 if ((inst & 0xf0df) == 0x0003) {
619 regs->pc += regs->regs[(inst & 0x0f00) >> 8] + 4;
620 return 0;
621 }
622
623 if ((inst & 0xf0df) == 0x400b) {
624 regs->pc = regs->regs[(inst & 0x0f00) >> 8];
625 return 0;
626 }
627
628 if ((inst & 0xffff) == 0x000b) {
629 regs->pc = regs->pr;
630 return 0;
631 }
632
633 return 1;
634}
635#endif
636
637asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
638 unsigned long r6, unsigned long r7,
639 struct pt_regs regs)
640{
641 unsigned long error_code;
642 struct task_struct *tsk = current;
643#ifdef CONFIG_SH_FPU_EMU
644 unsigned short inst;
645
646 get_user(inst, (unsigned short *)regs.pc + 1);
647 if (!do_fpu_inst(inst, &regs)) {
648 get_user(inst, (unsigned short *)regs.pc);
649 if (!emulate_branch(inst, &regs))
650 return;
651 /* fault in branch.*/
652 }
653 /* not a FPU inst. */
654#endif
655
656 asm volatile("stc r2_bank, %0": "=r" (error_code));
657 local_irq_enable();
658 tsk->thread.error_code = error_code;
659 tsk->thread.trap_no = TRAP_RESERVED_INST;
660 CHK_REMOTE_DEBUG(&regs);
661 force_sig(SIGILL, tsk);
662 die_if_no_fixup("illegal slot instruction", &regs, error_code);
663}
580 664
581asmlinkage void do_exception_error(unsigned long r4, unsigned long r5, 665asmlinkage void do_exception_error(unsigned long r4, unsigned long r5,
582 unsigned long r6, unsigned long r7, 666 unsigned long r6, unsigned long r7,
@@ -634,14 +718,16 @@ void __init trap_init(void)
634 exception_handling_table[TRAP_ILLEGAL_SLOT_INST] 718 exception_handling_table[TRAP_ILLEGAL_SLOT_INST]
635 = (void *)do_illegal_slot_inst; 719 = (void *)do_illegal_slot_inst;
636 720
637#ifdef CONFIG_CPU_SH4 721#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_FPU) || \
638 if (!(cpu_data->flags & CPU_HAS_FPU)) { 722 defined(CONFIG_SH_FPU_EMU)
639 /* For SH-4 lacking an FPU, treat floating point instructions 723 /*
640 as reserved. */ 724 * For SH-4 lacking an FPU, treat floating point instructions as
641 /* entry 64 corresponds to EXPEVT=0x800 */ 725 * reserved. They'll be handled in the math-emu case, or faulted on
642 exception_handling_table[64] = (void *)do_reserved_inst; 726 * otherwise.
643 exception_handling_table[65] = (void *)do_illegal_slot_inst; 727 */
644 } 728 /* entry 64 corresponds to EXPEVT=0x800 */
729 exception_handling_table[64] = (void *)do_reserved_inst;
730 exception_handling_table[65] = (void *)do_illegal_slot_inst;
645#endif 731#endif
646 732
647 /* Setup VBR for boot cpu */ 733 /* Setup VBR for boot cpu */
@@ -655,20 +741,12 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
655 unsigned long module_end = VMALLOC_END; 741 unsigned long module_end = VMALLOC_END;
656 int i = 1; 742 int i = 1;
657 743
658 if (tsk && !sp) { 744 if (!tsk)
745 tsk = current;
746 if (tsk == current)
747 sp = (unsigned long *)current_stack_pointer;
748 else
659 sp = (unsigned long *)tsk->thread.sp; 749 sp = (unsigned long *)tsk->thread.sp;
660 }
661
662 if (!sp) {
663 __asm__ __volatile__ (
664 "mov r15, %0\n\t"
665 "stc r7_bank, %1\n\t"
666 : "=r" (module_start),
667 "=r" (module_end)
668 );
669
670 sp = (unsigned long *)module_start;
671 }
672 750
673 stack = sp; 751 stack = sp;
674 752
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index 95fdd9135fcf..5eb930918186 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -2,6 +2,7 @@
2 * ld script to make SuperH Linux kernel 2 * ld script to make SuperH Linux kernel
3 * Written by Niibe Yutaka 3 * Written by Niibe Yutaka
4 */ 4 */
5#include <asm/thread_info.h>
5#include <asm-generic/vmlinux.lds.h> 6#include <asm-generic/vmlinux.lds.h>
6 7
7#ifdef CONFIG_CPU_LITTLE_ENDIAN 8#ifdef CONFIG_CPU_LITTLE_ENDIAN
@@ -13,7 +14,7 @@ OUTPUT_ARCH(sh)
13ENTRY(_start) 14ENTRY(_start)
14SECTIONS 15SECTIONS
15{ 16{
16 . = 0x80000000 + CONFIG_MEMORY_START + CONFIG_ZERO_PAGE_OFFSET; 17 . = CONFIG_PAGE_OFFSET + CONFIG_MEMORY_START + CONFIG_ZERO_PAGE_OFFSET;
17 _text = .; /* Text and read-only data */ 18 _text = .; /* Text and read-only data */
18 text = .; /* Text and read-only data */ 19 text = .; /* Text and read-only data */
19 .empty_zero_page : { 20 .empty_zero_page : {
@@ -40,16 +41,16 @@ SECTIONS
40 *(.data) 41 *(.data)
41 42
42 /* Align the initial ramdisk image (INITRD) on page boundaries. */ 43 /* Align the initial ramdisk image (INITRD) on page boundaries. */
43 . = ALIGN(4096); 44 . = ALIGN(PAGE_SIZE);
44 __rd_start = .; 45 __rd_start = .;
45 *(.initrd) 46 *(.initrd)
46 . = ALIGN(4096); 47 . = ALIGN(PAGE_SIZE);
47 __rd_end = .; 48 __rd_end = .;
48 49
49 CONSTRUCTORS 50 CONSTRUCTORS
50 } 51 }
51 52
52 . = ALIGN(4096); 53 . = ALIGN(PAGE_SIZE);
53 .data.page_aligned : { *(.data.idt) } 54 .data.page_aligned : { *(.data.idt) }
54 55
55 . = ALIGN(32); 56 . = ALIGN(32);
@@ -60,12 +61,10 @@ SECTIONS
60 61
61 _edata = .; /* End of data section */ 62 _edata = .; /* End of data section */
62 63
63 . = ALIGN(8192); /* init_task */ 64 . = ALIGN(THREAD_SIZE); /* init_task */
64 .data.init_task : { *(.data.init_task) } 65 .data.init_task : { *(.data.init_task) }
65 /* stack */
66 .stack : { stack = .; _stack = .; }
67 66
68 . = ALIGN(4096); /* Init code and data */ 67 . = ALIGN(PAGE_SIZE); /* Init code and data */
69 __init_begin = .; 68 __init_begin = .;
70 _sinittext = .; 69 _sinittext = .;
71 .init.text : { *(.init.text) } 70 .init.text : { *(.init.text) }
@@ -96,7 +95,7 @@ SECTIONS
96 __machvec_start = .; 95 __machvec_start = .;
97 .init.machvec : { *(.init.machvec) } 96 .init.machvec : { *(.init.machvec) }
98 __machvec_end = .; 97 __machvec_end = .;
99 . = ALIGN(4096); 98 . = ALIGN(PAGE_SIZE);
100 __init_end = .; 99 __init_end = .;
101 100
102 . = ALIGN(4); 101 . = ALIGN(4);
diff --git a/arch/sh/kernel/vsyscall/Makefile b/arch/sh/kernel/vsyscall/Makefile
new file mode 100644
index 000000000000..4bbce1cfa359
--- /dev/null
+++ b/arch/sh/kernel/vsyscall/Makefile
@@ -0,0 +1,36 @@
1obj-y += vsyscall.o vsyscall-syscall.o
2
3$(obj)/vsyscall-syscall.o: \
4 $(foreach F,trapa,$(obj)/vsyscall-$F.so)
5
6# Teach kbuild about targets
7targets += $(foreach F,trapa,vsyscall-$F.o vsyscall-$F.so)
8targets += vsyscall-note.o vsyscall.lds
9
10# The DSO images are built using a special linker script
11quiet_cmd_syscall = SYSCALL $@
12 cmd_syscall = $(CC) -nostdlib $(SYSCFLAGS_$(@F)) \
13 -Wl,-T,$(filter-out FORCE,$^) -o $@
14
15export CPPFLAGS_vsyscall.lds += -P -C -Ush
16
17vsyscall-flags = -shared -s -Wl,-soname=linux-gate.so.1 \
18 $(call ld-option, -Wl$(comma)--hash-style=sysv)
19
20SYSCFLAGS_vsyscall-trapa.so = $(vsyscall-flags)
21
22$(obj)/vsyscall-trapa.so: \
23$(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
24 $(call if_changed,syscall)
25
26# We also create a special relocatable object that should mirror the symbol
27# table and layout of the linked DSO. With ld -R we can then refer to
28# these symbols in the kernel code rather than hand-coded addresses.
29extra-y += vsyscall-syms.o
30$(obj)/built-in.o: $(obj)/vsyscall-syms.o
31$(obj)/built-in.o: ld_flags += -R $(obj)/vsyscall-syms.o
32
33SYSCFLAGS_vsyscall-syms.o = -r
34$(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \
35 $(obj)/vsyscall-trapa.o $(obj)/vsyscall-note.o FORCE
36 $(call if_changed,syscall)
diff --git a/arch/sh/kernel/vsyscall/vsyscall-note.S b/arch/sh/kernel/vsyscall/vsyscall-note.S
new file mode 100644
index 000000000000..d4b5be4f3d5f
--- /dev/null
+++ b/arch/sh/kernel/vsyscall/vsyscall-note.S
@@ -0,0 +1,25 @@
1/*
2 * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text.
3 * Here we can supply some information useful to userland.
4 */
5
6#include <linux/uts.h>
7#include <linux/version.h>
8
9#define ASM_ELF_NOTE_BEGIN(name, flags, vendor, type) \
10 .section name, flags; \
11 .balign 4; \
12 .long 1f - 0f; /* name length */ \
13 .long 3f - 2f; /* data length */ \
14 .long type; /* note type */ \
150: .asciz vendor; /* vendor name */ \
161: .balign 4; \
172:
18
19#define ASM_ELF_NOTE_END \
203: .balign 4; /* pad out section */ \
21 .previous
22
23 ASM_ELF_NOTE_BEGIN(".note.kernel-version", "a", UTS_SYSNAME, 0)
24 .long LINUX_VERSION_CODE
25 ASM_ELF_NOTE_END
diff --git a/arch/sh/kernel/vsyscall/vsyscall-sigreturn.S b/arch/sh/kernel/vsyscall/vsyscall-sigreturn.S
new file mode 100644
index 000000000000..555a64f124ca
--- /dev/null
+++ b/arch/sh/kernel/vsyscall/vsyscall-sigreturn.S
@@ -0,0 +1,39 @@
1#include <asm/unistd.h>
2
3 .text
4 .balign 32
5 .globl __kernel_sigreturn
6 .type __kernel_sigreturn,@function
7__kernel_sigreturn:
8.LSTART_sigreturn:
9 mov.w 1f, r3
10 trapa #0x10
11 or r0, r0
12 or r0, r0
13 or r0, r0
14 or r0, r0
15 or r0, r0
16
171: .short __NR_sigreturn
18.LEND_sigreturn:
19 .size __kernel_sigreturn,.-.LSTART_sigreturn
20
21 .balign 32
22 .globl __kernel_rt_sigreturn
23 .type __kernel_rt_sigreturn,@function
24__kernel_rt_sigreturn:
25.LSTART_rt_sigreturn:
26 mov.w 1f, r3
27 trapa #0x10
28 or r0, r0
29 or r0, r0
30 or r0, r0
31 or r0, r0
32 or r0, r0
33
341: .short __NR_rt_sigreturn
35.LEND_rt_sigreturn:
36 .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn
37
38 .section .eh_frame,"a",@progbits
39 .previous
diff --git a/arch/sh/kernel/vsyscall/vsyscall-syscall.S b/arch/sh/kernel/vsyscall/vsyscall-syscall.S
new file mode 100644
index 000000000000..c2ac7f0282b3
--- /dev/null
+++ b/arch/sh/kernel/vsyscall/vsyscall-syscall.S
@@ -0,0 +1,10 @@
1#include <linux/init.h>
2
3__INITDATA
4
5 .globl vsyscall_trapa_start, vsyscall_trapa_end
6vsyscall_trapa_start:
7 .incbin "arch/sh/kernel/vsyscall/vsyscall-trapa.so"
8vsyscall_trapa_end:
9
10__FINIT
diff --git a/arch/sh/kernel/vsyscall/vsyscall-trapa.S b/arch/sh/kernel/vsyscall/vsyscall-trapa.S
new file mode 100644
index 000000000000..3b6eb34c43fa
--- /dev/null
+++ b/arch/sh/kernel/vsyscall/vsyscall-trapa.S
@@ -0,0 +1,42 @@
1 .text
2 .globl __kernel_vsyscall
3 .type __kernel_vsyscall,@function
4__kernel_vsyscall:
5.LSTART_vsyscall:
6 /* XXX: We'll have to do something here once we opt to use the vDSO
7 * page for something other than the signal trampoline.. as well as
8 * fill out .eh_frame -- PFM. */
9.LEND_vsyscall:
10 .size __kernel_vsyscall,.-.LSTART_vsyscall
11 .previous
12
13 .section .eh_frame,"a",@progbits
14.LCIE:
15 .ualong .LCIE_end - .LCIE_start
16.LCIE_start:
17 .ualong 0 /* CIE ID */
18 .byte 0x1 /* Version number */
19 .string "zRS" /* NUL-terminated augmentation string */
20 .uleb128 0x1 /* Code alignment factor */
21 .sleb128 -4 /* Data alignment factor */
22 .byte 0x11 /* Return address register column */
23 /* Augmentation length and data (none) */
24 .byte 0xc /* DW_CFA_def_cfa */
25 .uleb128 0xf /* r15 */
26 .uleb128 0x0 /* offset 0 */
27
28 .align 2
29.LCIE_end:
30
31 .ualong .LFDE_end-.LFDE_start /* Length FDE */
32.LFDE_start:
33 .ualong .LCIE /* CIE pointer */
34 .ualong .LSTART_vsyscall-. /* start address */
35 .ualong .LEND_vsyscall-.LSTART_vsyscall
36 .uleb128 0
37 .align 2
38.LFDE_end:
39 .previous
40
41/* Get the common code for the sigreturn entry points */
42#include "vsyscall-sigreturn.S"
diff --git a/arch/sh/kernel/vsyscall/vsyscall.c b/arch/sh/kernel/vsyscall/vsyscall.c
new file mode 100644
index 000000000000..075d6cc1a2d7
--- /dev/null
+++ b/arch/sh/kernel/vsyscall/vsyscall.c
@@ -0,0 +1,150 @@
1/*
2 * arch/sh/kernel/vsyscall.c
3 *
4 * Copyright (C) 2006 Paul Mundt
5 *
6 * vDSO randomization
7 * Copyright(C) 2005-2006, Red Hat, Inc., Ingo Molnar
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13#include <linux/mm.h>
14#include <linux/slab.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/gfp.h>
18#include <linux/module.h>
19#include <linux/elf.h>
20
21/*
22 * Should the kernel map a VDSO page into processes and pass its
23 * address down to glibc upon exec()?
24 */
25unsigned int __read_mostly vdso_enabled = 1;
26EXPORT_SYMBOL_GPL(vdso_enabled);
27
28static int __init vdso_setup(char *s)
29{
30 vdso_enabled = simple_strtoul(s, NULL, 0);
31 return 1;
32}
33__setup("vdso=", vdso_setup);
34
35/*
36 * These symbols are defined by vsyscall.o to mark the bounds
37 * of the ELF DSO images included therein.
38 */
39extern const char vsyscall_trapa_start, vsyscall_trapa_end;
40static void *syscall_page;
41
42int __init vsyscall_init(void)
43{
44 syscall_page = (void *)get_zeroed_page(GFP_ATOMIC);
45
46 /*
47 * XXX: Map this page to a fixmap entry if we get around
48 * to adding the page to ELF core dumps
49 */
50
51 memcpy(syscall_page,
52 &vsyscall_trapa_start,
53 &vsyscall_trapa_end - &vsyscall_trapa_start);
54
55 return 0;
56}
57
58static struct page *syscall_vma_nopage(struct vm_area_struct *vma,
59 unsigned long address, int *type)
60{
61 unsigned long offset = address - vma->vm_start;
62 struct page *page;
63
64 if (address < vma->vm_start || address > vma->vm_end)
65 return NOPAGE_SIGBUS;
66
67 page = virt_to_page(syscall_page + offset);
68
69 get_page(page);
70
71 return page;
72}
73
74/* Prevent VMA merging */
75static void syscall_vma_close(struct vm_area_struct *vma)
76{
77}
78
79static struct vm_operations_struct syscall_vm_ops = {
80 .nopage = syscall_vma_nopage,
81 .close = syscall_vma_close,
82};
83
84/* Setup a VMA at program startup for the vsyscall page */
85int arch_setup_additional_pages(struct linux_binprm *bprm,
86 int executable_stack)
87{
88 struct vm_area_struct *vma;
89 struct mm_struct *mm = current->mm;
90 unsigned long addr;
91 int ret;
92
93 down_write(&mm->mmap_sem);
94 addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
95 if (IS_ERR_VALUE(addr)) {
96 ret = addr;
97 goto up_fail;
98 }
99
100 vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL);
101 if (!vma) {
102 ret = -ENOMEM;
103 goto up_fail;
104 }
105
106 vma->vm_start = addr;
107 vma->vm_end = addr + PAGE_SIZE;
108 /* MAYWRITE to allow gdb to COW and set breakpoints */
109 vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE;
110 vma->vm_flags |= mm->def_flags;
111 vma->vm_page_prot = protection_map[vma->vm_flags & 7];
112 vma->vm_ops = &syscall_vm_ops;
113 vma->vm_mm = mm;
114
115 ret = insert_vm_struct(mm, vma);
116 if (unlikely(ret)) {
117 kmem_cache_free(vm_area_cachep, vma);
118 goto up_fail;
119 }
120
121 current->mm->context.vdso = (void *)addr;
122
123 mm->total_vm++;
124up_fail:
125 up_write(&mm->mmap_sem);
126 return ret;
127}
128
129const char *arch_vma_name(struct vm_area_struct *vma)
130{
131 if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
132 return "[vdso]";
133
134 return NULL;
135}
136
137struct vm_area_struct *get_gate_vma(struct task_struct *task)
138{
139 return NULL;
140}
141
142int in_gate_area(struct task_struct *task, unsigned long address)
143{
144 return 0;
145}
146
147int in_gate_area_no_task(unsigned long address)
148{
149 return 0;
150}
diff --git a/arch/sh/kernel/vsyscall/vsyscall.lds.S b/arch/sh/kernel/vsyscall/vsyscall.lds.S
new file mode 100644
index 000000000000..b13c3d439fee
--- /dev/null
+++ b/arch/sh/kernel/vsyscall/vsyscall.lds.S
@@ -0,0 +1,74 @@
1/*
2 * Linker script for vsyscall DSO. The vsyscall page is an ELF shared
3 * object prelinked to its virtual address, and with only one read-only
4 * segment (that fits in one page). This script controls its layout.
5 */
6#include <asm/asm-offsets.h>
7
8#ifdef CONFIG_CPU_LITTLE_ENDIAN
9OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux")
10#else
11OUTPUT_FORMAT("elf32-shbig-linux", "elf32-shbig-linux", "elf32-shbig-linux")
12#endif
13OUTPUT_ARCH(sh)
14
15/* The ELF entry point can be used to set the AT_SYSINFO value. */
16ENTRY(__kernel_vsyscall);
17
18SECTIONS
19{
20 . = SIZEOF_HEADERS;
21
22 .hash : { *(.hash) } :text
23 .gnu.hash : { *(.gnu.hash) }
24 .dynsym : { *(.dynsym) }
25 .dynstr : { *(.dynstr) }
26 .gnu.version : { *(.gnu.version) }
27 .gnu.version_d : { *(.gnu.version_d) }
28 .gnu.version_r : { *(.gnu.version_r) }
29
30 /* This linker script is used both with -r and with -shared.
31 For the layouts to match, we need to skip more than enough
32 space for the dynamic symbol table et al. If this amount
33 is insufficient, ld -shared will barf. Just increase it here. */
34 . = 0x400;
35
36 .text : { *(.text) } :text =0x90909090
37 .note : { *(.note.*) } :text :note
38 .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
39 .eh_frame : { KEEP (*(.eh_frame)) } :text
40 .dynamic : { *(.dynamic) } :text :dynamic
41 .useless : {
42 *(.got.plt) *(.got)
43 *(.data .data.* .gnu.linkonce.d.*)
44 *(.dynbss)
45 *(.bss .bss.* .gnu.linkonce.b.*)
46 } :text
47}
48
49/*
50 * We must supply the ELF program headers explicitly to get just one
51 * PT_LOAD segment, and set the flags explicitly to make segments read-only.
52 */
53PHDRS
54{
55 text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
56 dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
57 note PT_NOTE FLAGS(4); /* PF_R */
58 eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */
59}
60
61/*
62 * This controls what symbols we export from the DSO.
63 */
64VERSION
65{
66 LINUX_2.6 {
67 global:
68 __kernel_vsyscall;
69 __kernel_sigreturn;
70 __kernel_rt_sigreturn;
71
72 local: *;
73 };
74}
diff --git a/arch/sh/lib/checksum.S b/arch/sh/lib/checksum.S
index 7c50dfe68c07..cbdd0d40e545 100644
--- a/arch/sh/lib/checksum.S
+++ b/arch/sh/lib/checksum.S
@@ -202,8 +202,9 @@ ENTRY(csum_partial_copy_generic)
202 cmp/pz r6 ! Jump if we had at least two bytes. 202 cmp/pz r6 ! Jump if we had at least two bytes.
203 bt/s 1f 203 bt/s 1f
204 clrt 204 clrt
205 add #2,r6 ! r6 was < 2. Deal with it.
205 bra 4f 206 bra 4f
206 add #2,r6 ! r6 was < 2. Deal with it. 207 mov r6,r2
207 208
2083: ! Handle different src and dest alignments. 2093: ! Handle different src and dest alignments.
209 ! This is not common, so simple byte by byte copy will do. 210 ! This is not common, so simple byte by byte copy will do.
diff --git a/arch/sh/lib/memcpy-sh4.S b/arch/sh/lib/memcpy-sh4.S
index db6b736537ad..560bc17eebdd 100644
--- a/arch/sh/lib/memcpy-sh4.S
+++ b/arch/sh/lib/memcpy-sh4.S
@@ -727,8 +727,8 @@ ENTRY(memcpy)
727 mov.l @(0x04,r5), r11 ! 18 LS (latency=2) 727 mov.l @(0x04,r5), r11 ! 18 LS (latency=2)
728 xtrct r9, r8 ! 48 EX 728 xtrct r9, r8 ! 48 EX
729 729
730 mov.w @(0x02,r5), r12 ! 18 LS (latency=2) 730 mov.l @(0x00,r5), r12 ! 18 LS (latency=2)
731 xtrct r10, r9 ! 48 EX 731 xtrct r10, r9 ! 48 EX
732 732
733 movca.l r0,@r1 ! 40 LS (latency=3-7) 733 movca.l r0,@r1 ! 40 LS (latency=3-7)
734 add #-0x1c, r1 ! 50 EX 734 add #-0x1c, r1 ! 50 EX
diff --git a/arch/sh/lib/memset.S b/arch/sh/lib/memset.S
index 95670090680e..af91fe2b72a6 100644
--- a/arch/sh/lib/memset.S
+++ b/arch/sh/lib/memset.S
@@ -29,6 +29,7 @@ ENTRY(memset)
29 bf/s 1b 29 bf/s 1b
30 mov.b r5,@-r4 30 mov.b r5,@-r4
312: ! make VVVV 312: ! make VVVV
32 extu.b r5,r5
32 swap.b r5,r0 ! V0 33 swap.b r5,r0 ! V0
33 or r0,r5 ! VV 34 or r0,r5 ! VV
34 swap.w r5,r0 ! VV00 35 swap.w r5,r0 ! VV00
diff --git a/arch/sh/math-emu/Makefile b/arch/sh/math-emu/Makefile
new file mode 100644
index 000000000000..638b342c781a
--- /dev/null
+++ b/arch/sh/math-emu/Makefile
@@ -0,0 +1 @@
obj-y := math.o
diff --git a/arch/sh/math-emu/math.c b/arch/sh/math-emu/math.c
new file mode 100644
index 000000000000..26b6046814fd
--- /dev/null
+++ b/arch/sh/math-emu/math.c
@@ -0,0 +1,624 @@
1/*
2 * arch/sh/math-emu/math.c
3 *
4 * Copyright (C) 2006 Takashi YOSHII <takasi-y@ops.dti.ne.jp>
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/config.h>
11#include <linux/kernel.h>
12#include <linux/errno.h>
13#include <linux/types.h>
14#include <linux/sched.h>
15#include <linux/signal.h>
16
17#include <asm/system.h>
18#include <asm/uaccess.h>
19#include <asm/processor.h>
20#include <asm/io.h>
21
22#include "sfp-util.h"
23#include <math-emu/soft-fp.h>
24#include <math-emu/single.h>
25#include <math-emu/double.h>
26
27#define FPUL (fregs->fpul)
28#define FPSCR (fregs->fpscr)
29#define FPSCR_RM (FPSCR&3)
30#define FPSCR_DN ((FPSCR>>18)&1)
31#define FPSCR_PR ((FPSCR>>19)&1)
32#define FPSCR_SZ ((FPSCR>>20)&1)
33#define FPSCR_FR ((FPSCR>>21)&1)
34#define FPSCR_MASK 0x003fffffUL
35
36#define BANK(n) (n^(FPSCR_FR?16:0))
37#define FR ((unsigned long*)(fregs->fp_regs))
38#define FR0 (FR[BANK(0)])
39#define FRn (FR[BANK(n)])
40#define FRm (FR[BANK(m)])
41#define DR ((unsigned long long*)(fregs->fp_regs))
42#define DRn (DR[BANK(n)/2])
43#define DRm (DR[BANK(m)/2])
44
45#define XREG(n) (n^16)
46#define XFn (FR[BANK(XREG(n))])
47#define XFm (FR[BANK(XREG(m))])
48#define XDn (DR[BANK(XREG(n))/2])
49#define XDm (DR[BANK(XREG(m))/2])
50
51#define R0 (regs->regs[0])
52#define Rn (regs->regs[n])
53#define Rm (regs->regs[m])
54
55#define WRITE(d,a) ({if(put_user(d, (typeof (d)*)a)) return -EFAULT;})
56#define READ(d,a) ({if(get_user(d, (typeof (d)*)a)) return -EFAULT;})
57
58#define PACK_S(r,f) FP_PACK_SP(&r,f)
59#define UNPACK_S(f,r) FP_UNPACK_SP(f,&r)
60#define PACK_D(r,f) \
61 {u32 t[2]; FP_PACK_DP(t,f); ((u32*)&r)[0]=t[1]; ((u32*)&r)[1]=t[0];}
62#define UNPACK_D(f,r) \
63 {u32 t[2]; t[0]=((u32*)&r)[1]; t[1]=((u32*)&r)[0]; FP_UNPACK_DP(f,t);}
64
65// 2 args instructions.
66#define BOTH_PRmn(op,x) \
67 FP_DECL_EX; if(FPSCR_PR) op(D,x,DRm,DRn); else op(S,x,FRm,FRn);
68
69#define CMP_X(SZ,R,M,N) do{ \
70 FP_DECL_##SZ(Fm); FP_DECL_##SZ(Fn); \
71 UNPACK_##SZ(Fm, M); UNPACK_##SZ(Fn, N); \
72 FP_CMP_##SZ(R, Fn, Fm, 2); }while(0)
73#define EQ_X(SZ,R,M,N) do{ \
74 FP_DECL_##SZ(Fm); FP_DECL_##SZ(Fn); \
75 UNPACK_##SZ(Fm, M); UNPACK_##SZ(Fn, N); \
76 FP_CMP_EQ_##SZ(R, Fn, Fm); }while(0)
77#define CMP(OP) ({ int r; BOTH_PRmn(OP##_X,r); r; })
78
79static int
80fcmp_gt(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
81{
82 if (CMP(CMP) > 0)
83 regs->sr |= 1;
84 else
85 regs->sr &= ~1;
86
87 return 0;
88}
89
90static int
91fcmp_eq(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
92{
93 if (CMP(CMP /*EQ*/) == 0)
94 regs->sr |= 1;
95 else
96 regs->sr &= ~1;
97 return 0;
98}
99
100#define ARITH_X(SZ,OP,M,N) do{ \
101 FP_DECL_##SZ(Fm); FP_DECL_##SZ(Fn); FP_DECL_##SZ(Fr); \
102 UNPACK_##SZ(Fm, M); UNPACK_##SZ(Fn, N); \
103 FP_##OP##_##SZ(Fr, Fn, Fm); \
104 PACK_##SZ(N, Fr); }while(0)
105
106static int
107fadd(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
108{
109 BOTH_PRmn(ARITH_X, ADD);
110 return 0;
111}
112
113static int
114fsub(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
115{
116 BOTH_PRmn(ARITH_X, SUB);
117 return 0;
118}
119
120static int
121fmul(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
122{
123 BOTH_PRmn(ARITH_X, MUL);
124 return 0;
125}
126
127static int
128fdiv(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
129{
130 BOTH_PRmn(ARITH_X, DIV);
131 return 0;
132}
133
134static int
135fmac(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
136{
137 FP_DECL_EX;
138 FP_DECL_S(Fr);
139 FP_DECL_S(Ft);
140 FP_DECL_S(F0);
141 FP_DECL_S(Fm);
142 FP_DECL_S(Fn);
143 UNPACK_S(F0, FR0);
144 UNPACK_S(Fm, FRm);
145 UNPACK_S(Fn, FRn);
146 FP_MUL_S(Ft, Fm, F0);
147 FP_ADD_S(Fr, Fn, Ft);
148 PACK_S(FRn, Fr);
149 return 0;
150}
151
152// to process fmov's extention (odd n for DR access XD).
153#define FMOV_EXT(x) if(x&1) x+=16-1
154
155static int
156fmov_idx_reg(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
157 int n)
158{
159 if (FPSCR_SZ) {
160 FMOV_EXT(n);
161 READ(FRn, Rm + R0 + 4);
162 n++;
163 READ(FRn, Rm + R0);
164 } else {
165 READ(FRn, Rm + R0);
166 }
167
168 return 0;
169}
170
171static int
172fmov_mem_reg(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
173 int n)
174{
175 if (FPSCR_SZ) {
176 FMOV_EXT(n);
177 READ(FRn, Rm + 4);
178 n++;
179 READ(FRn, Rm);
180 } else {
181 READ(FRn, Rm);
182 }
183
184 return 0;
185}
186
187static int
188fmov_inc_reg(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
189 int n)
190{
191 if (FPSCR_SZ) {
192 FMOV_EXT(n);
193 READ(FRn, Rm + 4);
194 n++;
195 READ(FRn, Rm);
196 Rm += 8;
197 } else {
198 READ(FRn, Rm);
199 Rm += 4;
200 }
201
202 return 0;
203}
204
205static int
206fmov_reg_idx(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
207 int n)
208{
209 if (FPSCR_SZ) {
210 FMOV_EXT(m);
211 WRITE(FRm, Rn + R0 + 4);
212 m++;
213 WRITE(FRm, Rn + R0);
214 } else {
215 WRITE(FRm, Rn + R0);
216 }
217
218 return 0;
219}
220
221static int
222fmov_reg_mem(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
223 int n)
224{
225 if (FPSCR_SZ) {
226 FMOV_EXT(m);
227 WRITE(FRm, Rn + 4);
228 m++;
229 WRITE(FRm, Rn);
230 } else {
231 WRITE(FRm, Rn);
232 }
233
234 return 0;
235}
236
237static int
238fmov_reg_dec(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
239 int n)
240{
241 if (FPSCR_SZ) {
242 FMOV_EXT(m);
243 Rn -= 8;
244 WRITE(FRm, Rn + 4);
245 m++;
246 WRITE(FRm, Rn);
247 } else {
248 Rn -= 4;
249 WRITE(FRm, Rn);
250 }
251
252 return 0;
253}
254
255static int
256fmov_reg_reg(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m,
257 int n)
258{
259 if (FPSCR_SZ) {
260 FMOV_EXT(m);
261 FMOV_EXT(n);
262 DRn = DRm;
263 } else {
264 FRn = FRm;
265 }
266
267 return 0;
268}
269
270static int
271fnop_mn(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n)
272{
273 return -EINVAL;
274}
275
276// 1 arg instructions.
277#define NOTYETn(i) static int i(struct sh_fpu_soft_struct *fregs, int n) \
278 { printk( #i " not yet done.\n"); return 0; }
279
280NOTYETn(ftrv)
281NOTYETn(fsqrt)
282NOTYETn(fipr)
283NOTYETn(fsca)
284NOTYETn(fsrra)
285
286#define EMU_FLOAT_X(SZ,N) do { \
287 FP_DECL_##SZ(Fn); \
288 FP_FROM_INT_##SZ(Fn, FPUL, 32, int); \
289 PACK_##SZ(N, Fn); }while(0)
290static int ffloat(struct sh_fpu_soft_struct *fregs, int n)
291{
292 FP_DECL_EX;
293
294 if (FPSCR_PR)
295 EMU_FLOAT_X(D, DRn);
296 else
297 EMU_FLOAT_X(S, FRn);
298
299 return 0;
300}
301
302#define EMU_FTRC_X(SZ,N) do { \
303 FP_DECL_##SZ(Fn); \
304 UNPACK_##SZ(Fn, N); \
305 FP_TO_INT_##SZ(FPUL, Fn, 32, 1); }while(0)
306static int ftrc(struct sh_fpu_soft_struct *fregs, int n)
307{
308 FP_DECL_EX;
309
310 if (FPSCR_PR)
311 EMU_FTRC_X(D, DRn);
312 else
313 EMU_FTRC_X(S, FRn);
314
315 return 0;
316}
317
318static int fcnvsd(struct sh_fpu_soft_struct *fregs, int n)
319{
320 FP_DECL_EX;
321 FP_DECL_S(Fn);
322 FP_DECL_D(Fr);
323 UNPACK_S(Fn, FPUL);
324 FP_CONV(D, S, 2, 1, Fr, Fn);
325 PACK_D(DRn, Fr);
326 return 0;
327}
328
329static int fcnvds(struct sh_fpu_soft_struct *fregs, int n)
330{
331 FP_DECL_EX;
332 FP_DECL_D(Fn);
333 FP_DECL_S(Fr);
334 UNPACK_D(Fn, DRn);
335 FP_CONV(S, D, 1, 2, Fr, Fn);
336 PACK_S(FPUL, Fr);
337 return 0;
338}
339
340static int fxchg(struct sh_fpu_soft_struct *fregs, int flag)
341{
342 FPSCR ^= flag;
343 return 0;
344}
345
346static int fsts(struct sh_fpu_soft_struct *fregs, int n)
347{
348 FRn = FPUL;
349 return 0;
350}
351
352static int flds(struct sh_fpu_soft_struct *fregs, int n)
353{
354 FPUL = FRn;
355 return 0;
356}
357
358static int fneg(struct sh_fpu_soft_struct *fregs, int n)
359{
360 FRn ^= (1 << (_FP_W_TYPE_SIZE - 1));
361 return 0;
362}
363
364static int fabs(struct sh_fpu_soft_struct *fregs, int n)
365{
366 FRn &= ~(1 << (_FP_W_TYPE_SIZE - 1));
367 return 0;
368}
369
370static int fld0(struct sh_fpu_soft_struct *fregs, int n)
371{
372 FRn = 0;
373 return 0;
374}
375
376static int fld1(struct sh_fpu_soft_struct *fregs, int n)
377{
378 FRn = (_FP_EXPBIAS_S << (_FP_FRACBITS_S - 1));
379 return 0;
380}
381
382static int fnop_n(struct sh_fpu_soft_struct *fregs, int n)
383{
384 return -EINVAL;
385}
386
387/// Instruction decoders.
388
389static int id_fxfd(struct sh_fpu_soft_struct *, int);
390static int id_fnxd(struct sh_fpu_soft_struct *, struct pt_regs *, int, int);
391
392static int (*fnxd[])(struct sh_fpu_soft_struct *, int) = {
393 fsts, flds, ffloat, ftrc, fneg, fabs, fsqrt, fsrra,
394 fld0, fld1, fcnvsd, fcnvds, fnop_n, fnop_n, fipr, id_fxfd
395};
396
397static int (*fnmx[])(struct sh_fpu_soft_struct *, struct pt_regs *, int, int) = {
398 fadd, fsub, fmul, fdiv, fcmp_eq, fcmp_gt, fmov_idx_reg, fmov_reg_idx,
399 fmov_mem_reg, fmov_inc_reg, fmov_reg_mem, fmov_reg_dec,
400 fmov_reg_reg, id_fnxd, fmac, fnop_mn};
401
402static int id_fxfd(struct sh_fpu_soft_struct *fregs, int x)
403{
404 const int flag[] = { FPSCR_SZ, FPSCR_PR, FPSCR_FR, 0 };
405 switch (x & 3) {
406 case 3:
407 fxchg(fregs, flag[x >> 2]);
408 break;
409 case 1:
410 ftrv(fregs, x - 1);
411 break;
412 default:
413 fsca(fregs, x);
414 }
415 return 0;
416}
417
418static int
419id_fnxd(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int x, int n)
420{
421 return (fnxd[x])(fregs, n);
422}
423
424static int
425id_fnmx(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, u16 code)
426{
427 int n = (code >> 8) & 0xf, m = (code >> 4) & 0xf, x = code & 0xf;
428 return (fnmx[x])(fregs, regs, m, n);
429}
430
431static int
432id_sys(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, u16 code)
433{
434 int n = ((code >> 8) & 0xf);
435 unsigned long *reg = (code & 0x0010) ? &FPUL : &FPSCR;
436
437 switch (code & 0xf0ff) {
438 case 0x005a:
439 case 0x006a:
440 Rn = *reg;
441 break;
442 case 0x405a:
443 case 0x406a:
444 *reg = Rn;
445 break;
446 case 0x4052:
447 case 0x4062:
448 Rn -= 4;
449 WRITE(*reg, Rn);
450 break;
451 case 0x4056:
452 case 0x4066:
453 READ(*reg, Rn);
454 Rn += 4;
455 break;
456 default:
457 return -EINVAL;
458 }
459
460 return 0;
461}
462
463static int fpu_emulate(u16 code, struct sh_fpu_soft_struct *fregs, struct pt_regs *regs)
464{
465 if ((code & 0xf000) == 0xf000)
466 return id_fnmx(fregs, regs, code);
467 else
468 return id_sys(fregs, regs, code);
469}
470
471/**
472 * denormal_to_double - Given denormalized float number,
473 * store double float
474 *
475 * @fpu: Pointer to sh_fpu_hard structure
476 * @n: Index to FP register
477 */
478static void denormal_to_double(struct sh_fpu_hard_struct *fpu, int n)
479{
480 unsigned long du, dl;
481 unsigned long x = fpu->fpul;
482 int exp = 1023 - 126;
483
484 if (x != 0 && (x & 0x7f800000) == 0) {
485 du = (x & 0x80000000);
486 while ((x & 0x00800000) == 0) {
487 x <<= 1;
488 exp--;
489 }
490 x &= 0x007fffff;
491 du |= (exp << 20) | (x >> 3);
492 dl = x << 29;
493
494 fpu->fp_regs[n] = du;
495 fpu->fp_regs[n+1] = dl;
496 }
497}
498
499/**
500 * ieee_fpe_handler - Handle denormalized number exception
501 *
502 * @regs: Pointer to register structure
503 *
504 * Returns 1 when it's handled (should not cause exception).
505 */
506static int ieee_fpe_handler(struct pt_regs *regs)
507{
508 unsigned short insn = *(unsigned short *)regs->pc;
509 unsigned short finsn;
510 unsigned long nextpc;
511 int nib[4] = {
512 (insn >> 12) & 0xf,
513 (insn >> 8) & 0xf,
514 (insn >> 4) & 0xf,
515 insn & 0xf};
516
517 if (nib[0] == 0xb ||
518 (nib[0] == 0x4 && nib[2] == 0x0 && nib[3] == 0xb)) /* bsr & jsr */
519 regs->pr = regs->pc + 4;
520
521 if (nib[0] == 0xa || nib[0] == 0xb) { /* bra & bsr */
522 nextpc = regs->pc + 4 + ((short) ((insn & 0xfff) << 4) >> 3);
523 finsn = *(unsigned short *) (regs->pc + 2);
524 } else if (nib[0] == 0x8 && nib[1] == 0xd) { /* bt/s */
525 if (regs->sr & 1)
526 nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1);
527 else
528 nextpc = regs->pc + 4;
529 finsn = *(unsigned short *) (regs->pc + 2);
530 } else if (nib[0] == 0x8 && nib[1] == 0xf) { /* bf/s */
531 if (regs->sr & 1)
532 nextpc = regs->pc + 4;
533 else
534 nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1);
535 finsn = *(unsigned short *) (regs->pc + 2);
536 } else if (nib[0] == 0x4 && nib[3] == 0xb &&
537 (nib[2] == 0x0 || nib[2] == 0x2)) { /* jmp & jsr */
538 nextpc = regs->regs[nib[1]];
539 finsn = *(unsigned short *) (regs->pc + 2);
540 } else if (nib[0] == 0x0 && nib[3] == 0x3 &&
541 (nib[2] == 0x0 || nib[2] == 0x2)) { /* braf & bsrf */
542 nextpc = regs->pc + 4 + regs->regs[nib[1]];
543 finsn = *(unsigned short *) (regs->pc + 2);
544 } else if (insn == 0x000b) { /* rts */
545 nextpc = regs->pr;
546 finsn = *(unsigned short *) (regs->pc + 2);
547 } else {
548 nextpc = regs->pc + 2;
549 finsn = insn;
550 }
551
552 if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */
553 struct task_struct *tsk = current;
554
555 if ((tsk->thread.fpu.hard.fpscr & (1 << 17))) {
556 /* FPU error */
557 denormal_to_double (&tsk->thread.fpu.hard,
558 (finsn >> 8) & 0xf);
559 tsk->thread.fpu.hard.fpscr &=
560 ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK);
561 set_tsk_thread_flag(tsk, TIF_USEDFPU);
562 } else {
563 tsk->thread.trap_no = 11;
564 tsk->thread.error_code = 0;
565 force_sig(SIGFPE, tsk);
566 }
567
568 regs->pc = nextpc;
569 return 1;
570 }
571
572 return 0;
573}
574
575asmlinkage void do_fpu_error(unsigned long r4, unsigned long r5,
576 unsigned long r6, unsigned long r7,
577 struct pt_regs regs)
578{
579 struct task_struct *tsk = current;
580
581 if (ieee_fpe_handler (&regs))
582 return;
583
584 regs.pc += 2;
585 tsk->thread.trap_no = 11;
586 tsk->thread.error_code = 0;
587 force_sig(SIGFPE, tsk);
588}
589
590/**
591 * fpu_init - Initialize FPU registers
592 * @fpu: Pointer to software emulated FPU registers.
593 */
594static void fpu_init(struct sh_fpu_soft_struct *fpu)
595{
596 int i;
597
598 fpu->fpscr = FPSCR_INIT;
599 fpu->fpul = 0;
600
601 for (i = 0; i < 16; i++) {
602 fpu->fp_regs[i] = 0;
603 fpu->xfp_regs[i]= 0;
604 }
605}
606
607/**
608 * do_fpu_inst - Handle reserved instructions for FPU emulation
609 * @inst: instruction code.
610 * @regs: registers on stack.
611 */
612int do_fpu_inst(unsigned short inst, struct pt_regs *regs)
613{
614 struct task_struct *tsk = current;
615 struct sh_fpu_soft_struct *fpu = &(tsk->thread.fpu.soft);
616
617 if (!test_tsk_thread_flag(tsk, TIF_USEDFPU)) {
618 /* initialize once. */
619 fpu_init(fpu);
620 set_tsk_thread_flag(tsk, TIF_USEDFPU);
621 }
622
623 return fpu_emulate(inst, fpu, regs);
624}
diff --git a/arch/sh/math-emu/sfp-util.h b/arch/sh/math-emu/sfp-util.h
new file mode 100644
index 000000000000..8ae1bd310ad0
--- /dev/null
+++ b/arch/sh/math-emu/sfp-util.h
@@ -0,0 +1,72 @@
1/*
2 * These are copied from glibc/stdlib/longlong.h
3 */
4
5#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
6 do { \
7 UWtype __x; \
8 __x = (al) + (bl); \
9 (sh) = (ah) + (bh) + (__x < (al)); \
10 (sl) = __x; \
11 } while (0)
12
13#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
14 do { \
15 UWtype __x; \
16 __x = (al) - (bl); \
17 (sh) = (ah) - (bh) - (__x > (al)); \
18 (sl) = __x; \
19 } while (0)
20
21#define umul_ppmm(w1, w0, u, v) \
22 __asm__ ("dmulu.l %2,%3\n\tsts macl,%1\n\tsts mach,%0" \
23 : "=r" ((u32)(w1)), "=r" ((u32)(w0)) \
24 : "r" ((u32)(u)), "r" ((u32)(v)) \
25 : "macl", "mach")
26
27#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
28#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
29#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
30
31#define udiv_qrnnd(q, r, n1, n0, d) \
32 do { \
33 UWtype __d1, __d0, __q1, __q0; \
34 UWtype __r1, __r0, __m; \
35 __d1 = __ll_highpart (d); \
36 __d0 = __ll_lowpart (d); \
37 \
38 __r1 = (n1) % __d1; \
39 __q1 = (n1) / __d1; \
40 __m = (UWtype) __q1 * __d0; \
41 __r1 = __r1 * __ll_B | __ll_highpart (n0); \
42 if (__r1 < __m) \
43 { \
44 __q1--, __r1 += (d); \
45 if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
46 if (__r1 < __m) \
47 __q1--, __r1 += (d); \
48 } \
49 __r1 -= __m; \
50 \
51 __r0 = __r1 % __d1; \
52 __q0 = __r1 / __d1; \
53 __m = (UWtype) __q0 * __d0; \
54 __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
55 if (__r0 < __m) \
56 { \
57 __q0--, __r0 += (d); \
58 if (__r0 >= (d)) \
59 if (__r0 < __m) \
60 __q0--, __r0 += (d); \
61 } \
62 __r0 -= __m; \
63 \
64 (q) = (UWtype) __q1 * __ll_B | __q0; \
65 (r) = __r0; \
66 } while (0)
67
68#define abort() return 0
69
70#define __BYTE_ORDER __LITTLE_ENDIAN
71
72
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index fb586b1cf8bb..9dd606464d23 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -20,7 +20,10 @@ config CPU_SH4
20config CPU_SH4A 20config CPU_SH4A
21 bool 21 bool
22 select CPU_SH4 22 select CPU_SH4
23 select CPU_HAS_INTC2_IRQ 23
24config CPU_SH4AL_DSP
25 bool
26 select CPU_SH4A
24 27
25config CPU_SUBTYPE_ST40 28config CPU_SUBTYPE_ST40
26 bool 29 bool
@@ -48,6 +51,12 @@ config CPU_SUBTYPE_SH7705
48 select CPU_SH3 51 select CPU_SH3
49 select CPU_HAS_PINT_IRQ 52 select CPU_HAS_PINT_IRQ
50 53
54config CPU_SUBTYPE_SH7706
55 bool "Support SH7706 processor"
56 select CPU_SH3
57 help
58 Select SH7706 if you have a 133 Mhz SH-3 HD6417706 CPU.
59
51config CPU_SUBTYPE_SH7707 60config CPU_SUBTYPE_SH7707
52 bool "Support SH7707 processor" 61 bool "Support SH7707 processor"
53 select CPU_SH3 62 select CPU_SH3
@@ -69,6 +78,12 @@ config CPU_SUBTYPE_SH7709
69 help 78 help
70 Select SH7709 if you have a 80 Mhz SH-3 HD6417709 CPU. 79 Select SH7709 if you have a 80 Mhz SH-3 HD6417709 CPU.
71 80
81config CPU_SUBTYPE_SH7710
82 bool "Support SH7710 processor"
83 select CPU_SH3
84 help
85 Select SH7710 if you have a SH3-DSP SH7710 CPU.
86
72comment "SH-4 Processor Support" 87comment "SH-4 Processor Support"
73 88
74config CPU_SUBTYPE_SH7750 89config CPU_SUBTYPE_SH7750
@@ -133,10 +148,6 @@ config CPU_SUBTYPE_ST40GX1
133 148
134comment "SH-4A Processor Support" 149comment "SH-4A Processor Support"
135 150
136config CPU_SUBTYPE_SH73180
137 bool "Support SH73180 processor"
138 select CPU_SH4A
139
140config CPU_SUBTYPE_SH7770 151config CPU_SUBTYPE_SH7770
141 bool "Support SH7770 processor" 152 bool "Support SH7770 processor"
142 select CPU_SH4A 153 select CPU_SH4A
@@ -144,6 +155,17 @@ config CPU_SUBTYPE_SH7770
144config CPU_SUBTYPE_SH7780 155config CPU_SUBTYPE_SH7780
145 bool "Support SH7780 processor" 156 bool "Support SH7780 processor"
146 select CPU_SH4A 157 select CPU_SH4A
158 select CPU_HAS_INTC2_IRQ
159
160comment "SH4AL-DSP Processor Support"
161
162config CPU_SUBTYPE_SH73180
163 bool "Support SH73180 processor"
164 select CPU_SH4AL_DSP
165
166config CPU_SUBTYPE_SH7343
167 bool "Support SH7343 processor"
168 select CPU_SH4AL_DSP
147 169
148endmenu 170endmenu
149 171
@@ -161,15 +183,59 @@ config MMU
161 turning this off will boot the kernel on these machines with the 183 turning this off will boot the kernel on these machines with the
162 MMU implicitly switched off. 184 MMU implicitly switched off.
163 185
186config PAGE_OFFSET
187 hex
188 default "0x80000000" if MMU
189 default "0x00000000"
190
191config MEMORY_START
192 hex "Physical memory start address"
193 default "0x08000000"
194 ---help---
195 Computers built with Hitachi SuperH processors always
196 map the ROM starting at address zero. But the processor
197 does not specify the range that RAM takes.
198
199 The physical memory (RAM) start address will be automatically
200 set to 08000000. Other platforms, such as the Solution Engine
201 boards typically map RAM at 0C000000.
202
203 Tweak this only when porting to a new machine which does not
204 already have a defconfig. Changing it from the known correct
205 value on any of the known systems will only lead to disaster.
206
207config MEMORY_SIZE
208 hex "Physical memory size"
209 default "0x00400000"
210 help
211 This sets the default memory size assumed by your SH kernel. It can
212 be overridden as normal by the 'mem=' argument on the kernel command
213 line. If unsure, consult your board specifications or just leave it
214 as 0x00400000 which was the default value before this became
215 configurable.
216
164config 32BIT 217config 32BIT
165 bool "Support 32-bit physical addressing through PMB" 218 bool "Support 32-bit physical addressing through PMB"
166 depends on CPU_SH4A 219 depends on CPU_SH4A && MMU
167 default y 220 default y
168 help 221 help
169 If you say Y here, physical addressing will be extended to 222 If you say Y here, physical addressing will be extended to
170 32-bits through the SH-4A PMB. If this is not set, legacy 223 32-bits through the SH-4A PMB. If this is not set, legacy
171 29-bit physical addressing will be used. 224 29-bit physical addressing will be used.
172 225
226config VSYSCALL
227 bool "Support vsyscall page"
228 depends on MMU
229 default y
230 help
231 This will enable support for the kernel mapping a vDSO page
232 in process space, and subsequently handing down the entry point
233 to the libc through the ELF auxiliary vector.
234
235 From the kernel side this is used for the signal trampoline.
236 For systems with an MMU that can afford to give up a page,
237 (the default value) say Y.
238
173choice 239choice
174 prompt "HugeTLB page size" 240 prompt "HugeTLB page size"
175 depends on HUGETLB_PAGE && CPU_SH4 && MMU 241 depends on HUGETLB_PAGE && CPU_SH4 && MMU
diff --git a/arch/sh/mm/Makefile b/arch/sh/mm/Makefile
index 9489a1424644..3ffd7f68c0a2 100644
--- a/arch/sh/mm/Makefile
+++ b/arch/sh/mm/Makefile
@@ -6,20 +6,26 @@ obj-y := init.o extable.o consistent.o
6 6
7obj-$(CONFIG_CPU_SH2) += cache-sh2.o 7obj-$(CONFIG_CPU_SH2) += cache-sh2.o
8obj-$(CONFIG_CPU_SH3) += cache-sh3.o 8obj-$(CONFIG_CPU_SH3) += cache-sh3.o
9obj-$(CONFIG_CPU_SH4) += cache-sh4.o pg-sh4.o 9obj-$(CONFIG_CPU_SH4) += cache-sh4.o
10 10
11obj-$(CONFIG_DMA_PAGE_OPS) += pg-dma.o 11obj-$(CONFIG_DMA_PAGE_OPS) += pg-dma.o
12obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 12obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
13 13
14mmu-y := fault-nommu.o tlb-nommu.o pg-nommu.o 14mmu-y := fault-nommu.o tlb-nommu.o pg-nommu.o
15mmu-$(CONFIG_MMU) := fault.o clear_page.o copy_page.o 15mmu-$(CONFIG_MMU) := fault.o clear_page.o copy_page.o tlb-flush.o \
16 ioremap.o
16 17
17obj-y += $(mmu-y) 18obj-y += $(mmu-y)
18 19
20ifdef CONFIG_DEBUG_FS
21obj-$(CONFIG_CPU_SH4) += cache-debugfs.o
22endif
23
19ifdef CONFIG_MMU 24ifdef CONFIG_MMU
20obj-$(CONFIG_CPU_SH3) += tlb-sh3.o 25obj-$(CONFIG_CPU_SH3) += tlb-sh3.o
21obj-$(CONFIG_CPU_SH4) += tlb-sh4.o ioremap.o 26obj-$(CONFIG_CPU_SH4) += tlb-sh4.o pg-sh4.o
22obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh7705.o 27obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh7705.o
23endif 28endif
24 29
25obj-$(CONFIG_SH7705_CACHE_32KB) += cache-sh7705.o 30obj-$(CONFIG_SH7705_CACHE_32KB) += cache-sh7705.o
31obj-$(CONFIG_32BIT) += pmb.o
diff --git a/arch/sh/mm/cache-debugfs.c b/arch/sh/mm/cache-debugfs.c
new file mode 100644
index 000000000000..a22d914e4d15
--- /dev/null
+++ b/arch/sh/mm/cache-debugfs.c
@@ -0,0 +1,147 @@
1/*
2 * debugfs ops for the L1 cache
3 *
4 * Copyright (C) 2006 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10#include <linux/init.h>
11#include <linux/module.h>
12#include <linux/debugfs.h>
13#include <linux/seq_file.h>
14#include <asm/processor.h>
15#include <asm/uaccess.h>
16#include <asm/cache.h>
17#include <asm/io.h>
18
19enum cache_type {
20 CACHE_TYPE_ICACHE,
21 CACHE_TYPE_DCACHE,
22 CACHE_TYPE_UNIFIED,
23};
24
25static int cache_seq_show(struct seq_file *file, void *iter)
26{
27 unsigned int cache_type = (unsigned int)file->private;
28 struct cache_info *cache;
29 unsigned int waysize, way, cache_size;
30 unsigned long ccr, base;
31 static unsigned long addrstart = 0;
32
33 /*
34 * Go uncached immediately so we don't skew the results any
35 * more than we already are..
36 */
37 jump_to_P2();
38
39 ccr = ctrl_inl(CCR);
40 if ((ccr & CCR_CACHE_ENABLE) == 0) {
41 back_to_P1();
42
43 seq_printf(file, "disabled\n");
44 return 0;
45 }
46
47 if (cache_type == CACHE_TYPE_DCACHE) {
48 base = CACHE_OC_ADDRESS_ARRAY;
49 cache = &cpu_data->dcache;
50 } else {
51 base = CACHE_IC_ADDRESS_ARRAY;
52 cache = &cpu_data->icache;
53 }
54
55 /*
56 * Due to the amount of data written out (depending on the cache size),
57 * we may be iterated over multiple times. In this case, keep track of
58 * the entry position in addrstart, and rewind it when we've hit the
59 * end of the cache.
60 *
61 * Likewise, the same code is used for multiple caches, so care must
62 * be taken for bouncing addrstart back and forth so the appropriate
63 * cache is hit.
64 */
65 cache_size = cache->ways * cache->sets * cache->linesz;
66 if (((addrstart & 0xff000000) != base) ||
67 (addrstart & 0x00ffffff) > cache_size)
68 addrstart = base;
69
70 waysize = cache->sets;
71
72 /*
73 * If the OC is already in RAM mode, we only have
74 * half of the entries to consider..
75 */
76 if ((ccr & CCR_CACHE_ORA) && cache_type == CACHE_TYPE_DCACHE)
77 waysize >>= 1;
78
79 waysize <<= cache->entry_shift;
80
81 for (way = 0; way < cache->ways; way++) {
82 unsigned long addr;
83 unsigned int line;
84
85 seq_printf(file, "-----------------------------------------\n");
86 seq_printf(file, "Way %d\n", way);
87 seq_printf(file, "-----------------------------------------\n");
88
89 for (addr = addrstart, line = 0;
90 addr < addrstart + waysize;
91 addr += cache->linesz, line++) {
92 unsigned long data = ctrl_inl(addr);
93
94 /* Check the V bit, ignore invalid cachelines */
95 if ((data & 1) == 0)
96 continue;
97
98 /* U: Dirty, cache tag is 10 bits up */
99 seq_printf(file, "%3d: %c 0x%lx\n",
100 line, data & 2 ? 'U' : ' ',
101 data & 0x1ffffc00);
102 }
103
104 addrstart += cache->way_incr;
105 }
106
107 back_to_P1();
108
109 return 0;
110}
111
112static int cache_debugfs_open(struct inode *inode, struct file *file)
113{
114 return single_open(file, cache_seq_show, inode->u.generic_ip);
115}
116
117static struct file_operations cache_debugfs_fops = {
118 .owner = THIS_MODULE,
119 .open = cache_debugfs_open,
120 .read = seq_read,
121 .llseek = seq_lseek,
122 .release = seq_release,
123};
124
125static int __init cache_debugfs_init(void)
126{
127 struct dentry *dcache_dentry, *icache_dentry;
128
129 dcache_dentry = debugfs_create_file("dcache", S_IRUSR, NULL,
130 (unsigned int *)CACHE_TYPE_DCACHE,
131 &cache_debugfs_fops);
132 if (IS_ERR(dcache_dentry))
133 return PTR_ERR(dcache_dentry);
134
135 icache_dentry = debugfs_create_file("icache", S_IRUSR, NULL,
136 (unsigned int *)CACHE_TYPE_ICACHE,
137 &cache_debugfs_fops);
138 if (IS_ERR(icache_dentry)) {
139 debugfs_remove(dcache_dentry);
140 return PTR_ERR(icache_dentry);
141 }
142
143 return 0;
144}
145module_init(cache_debugfs_init);
146
147MODULE_LICENSE("GPL v2");
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index 524cea5b47f9..e48cc22724d9 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -2,49 +2,120 @@
2 * arch/sh/mm/cache-sh4.c 2 * arch/sh/mm/cache-sh4.c
3 * 3 *
4 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka 4 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka
5 * Copyright (C) 2001, 2002, 2003, 2004 Paul Mundt 5 * Copyright (C) 2001 - 2006 Paul Mundt
6 * Copyright (C) 2003 Richard Curnow 6 * Copyright (C) 2003 Richard Curnow
7 * 7 *
8 * This file is subject to the terms and conditions of the GNU General Public 8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive 9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details. 10 * for more details.
11 */ 11 */
12
13#include <linux/init.h> 12#include <linux/init.h>
14#include <linux/mman.h>
15#include <linux/mm.h> 13#include <linux/mm.h>
16#include <linux/threads.h>
17#include <asm/addrspace.h> 14#include <asm/addrspace.h>
18#include <asm/page.h>
19#include <asm/pgtable.h> 15#include <asm/pgtable.h>
20#include <asm/processor.h> 16#include <asm/processor.h>
21#include <asm/cache.h> 17#include <asm/cache.h>
22#include <asm/io.h> 18#include <asm/io.h>
23#include <asm/uaccess.h>
24#include <asm/pgalloc.h> 19#include <asm/pgalloc.h>
25#include <asm/mmu_context.h> 20#include <asm/mmu_context.h>
26#include <asm/cacheflush.h> 21#include <asm/cacheflush.h>
27 22
28extern void __flush_cache_4096_all(unsigned long start); 23/*
29static void __flush_cache_4096_all_ex(unsigned long start); 24 * The maximum number of pages we support up to when doing ranged dcache
30extern void __flush_dcache_all(void); 25 * flushing. Anything exceeding this will simply flush the dcache in its
31static void __flush_dcache_all_ex(void); 26 * entirety.
27 */
28#define MAX_DCACHE_PAGES 64 /* XXX: Tune for ways */
29
30static void __flush_dcache_segment_1way(unsigned long start,
31 unsigned long extent);
32static void __flush_dcache_segment_2way(unsigned long start,
33 unsigned long extent);
34static void __flush_dcache_segment_4way(unsigned long start,
35 unsigned long extent);
36
37static void __flush_cache_4096(unsigned long addr, unsigned long phys,
38 unsigned long exec_offset);
39
40/*
41 * This is initialised here to ensure that it is not placed in the BSS. If
42 * that were to happen, note that cache_init gets called before the BSS is
43 * cleared, so this would get nulled out which would be hopeless.
44 */
45static void (*__flush_dcache_segment_fn)(unsigned long, unsigned long) =
46 (void (*)(unsigned long, unsigned long))0xdeadbeef;
47
48static void compute_alias(struct cache_info *c)
49{
50 c->alias_mask = ((c->sets - 1) << c->entry_shift) & ~(PAGE_SIZE - 1);
51 c->n_aliases = (c->alias_mask >> PAGE_SHIFT) + 1;
52}
53
54static void __init emit_cache_params(void)
55{
56 printk("PVR=%08x CVR=%08x PRR=%08x\n",
57 ctrl_inl(CCN_PVR),
58 ctrl_inl(CCN_CVR),
59 ctrl_inl(CCN_PRR));
60 printk("I-cache : n_ways=%d n_sets=%d way_incr=%d\n",
61 cpu_data->icache.ways,
62 cpu_data->icache.sets,
63 cpu_data->icache.way_incr);
64 printk("I-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
65 cpu_data->icache.entry_mask,
66 cpu_data->icache.alias_mask,
67 cpu_data->icache.n_aliases);
68 printk("D-cache : n_ways=%d n_sets=%d way_incr=%d\n",
69 cpu_data->dcache.ways,
70 cpu_data->dcache.sets,
71 cpu_data->dcache.way_incr);
72 printk("D-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
73 cpu_data->dcache.entry_mask,
74 cpu_data->dcache.alias_mask,
75 cpu_data->dcache.n_aliases);
76
77 if (!__flush_dcache_segment_fn)
78 panic("unknown number of cache ways\n");
79}
32 80
33/* 81/*
34 * SH-4 has virtually indexed and physically tagged cache. 82 * SH-4 has virtually indexed and physically tagged cache.
35 */ 83 */
36 84
37struct semaphore p3map_sem[4]; 85/* Worst case assumed to be 64k cache, direct-mapped i.e. 4 synonym bits. */
86#define MAX_P3_SEMAPHORES 16
87
88struct semaphore p3map_sem[MAX_P3_SEMAPHORES];
38 89
39void __init p3_cache_init(void) 90void __init p3_cache_init(void)
40{ 91{
41 if (remap_area_pages(P3SEG, 0, PAGE_SIZE*4, _PAGE_CACHABLE)) 92 int i;
93
94 compute_alias(&cpu_data->icache);
95 compute_alias(&cpu_data->dcache);
96
97 switch (cpu_data->dcache.ways) {
98 case 1:
99 __flush_dcache_segment_fn = __flush_dcache_segment_1way;
100 break;
101 case 2:
102 __flush_dcache_segment_fn = __flush_dcache_segment_2way;
103 break;
104 case 4:
105 __flush_dcache_segment_fn = __flush_dcache_segment_4way;
106 break;
107 default:
108 __flush_dcache_segment_fn = NULL;
109 break;
110 }
111
112 emit_cache_params();
113
114 if (remap_area_pages(P3SEG, 0, PAGE_SIZE * 4, _PAGE_CACHABLE))
42 panic("%s failed.", __FUNCTION__); 115 panic("%s failed.", __FUNCTION__);
43 116
44 sema_init (&p3map_sem[0], 1); 117 for (i = 0; i < cpu_data->dcache.n_aliases; i++)
45 sema_init (&p3map_sem[1], 1); 118 sema_init(&p3map_sem[i], 1);
46 sema_init (&p3map_sem[2], 1);
47 sema_init (&p3map_sem[3], 1);
48} 119}
49 120
50/* 121/*
@@ -89,7 +160,6 @@ void __flush_purge_region(void *start, int size)
89 } 160 }
90} 161}
91 162
92
93/* 163/*
94 * No write back please 164 * No write back please
95 */ 165 */
@@ -108,40 +178,6 @@ void __flush_invalidate_region(void *start, int size)
108 } 178 }
109} 179}
110 180
111static void __flush_dcache_all_ex(void)
112{
113 unsigned long addr, end_addr, entry_offset;
114
115 end_addr = CACHE_OC_ADDRESS_ARRAY + (cpu_data->dcache.sets << cpu_data->dcache.entry_shift) * cpu_data->dcache.ways;
116 entry_offset = 1 << cpu_data->dcache.entry_shift;
117 for (addr = CACHE_OC_ADDRESS_ARRAY; addr < end_addr; addr += entry_offset) {
118 ctrl_outl(0, addr);
119 }
120}
121
122static void __flush_cache_4096_all_ex(unsigned long start)
123{
124 unsigned long addr, entry_offset;
125 int i;
126
127 entry_offset = 1 << cpu_data->dcache.entry_shift;
128 for (i = 0; i < cpu_data->dcache.ways; i++, start += cpu_data->dcache.way_incr) {
129 for (addr = CACHE_OC_ADDRESS_ARRAY + start;
130 addr < CACHE_OC_ADDRESS_ARRAY + 4096 + start;
131 addr += entry_offset) {
132 ctrl_outl(0, addr);
133 }
134 }
135}
136
137void flush_cache_4096_all(unsigned long start)
138{
139 if (cpu_data->dcache.ways == 1)
140 __flush_cache_4096_all(start);
141 else
142 __flush_cache_4096_all_ex(start);
143}
144
145/* 181/*
146 * Write back the range of D-cache, and purge the I-cache. 182 * Write back the range of D-cache, and purge the I-cache.
147 * 183 *
@@ -153,14 +189,14 @@ void flush_icache_range(unsigned long start, unsigned long end)
153} 189}
154 190
155/* 191/*
156 * Write back the D-cache and purge the I-cache for signal trampoline. 192 * Write back the D-cache and purge the I-cache for signal trampoline.
157 * .. which happens to be the same behavior as flush_icache_range(). 193 * .. which happens to be the same behavior as flush_icache_range().
158 * So, we simply flush out a line. 194 * So, we simply flush out a line.
159 */ 195 */
160void flush_cache_sigtramp(unsigned long addr) 196void flush_cache_sigtramp(unsigned long addr)
161{ 197{
162 unsigned long v, index; 198 unsigned long v, index;
163 unsigned long flags; 199 unsigned long flags;
164 int i; 200 int i;
165 201
166 v = addr & ~(L1_CACHE_BYTES-1); 202 v = addr & ~(L1_CACHE_BYTES-1);
@@ -172,30 +208,33 @@ void flush_cache_sigtramp(unsigned long addr)
172 208
173 local_irq_save(flags); 209 local_irq_save(flags);
174 jump_to_P2(); 210 jump_to_P2();
175 for(i = 0; i < cpu_data->icache.ways; i++, index += cpu_data->icache.way_incr) 211
212 for (i = 0; i < cpu_data->icache.ways;
213 i++, index += cpu_data->icache.way_incr)
176 ctrl_outl(0, index); /* Clear out Valid-bit */ 214 ctrl_outl(0, index); /* Clear out Valid-bit */
215
177 back_to_P1(); 216 back_to_P1();
217 wmb();
178 local_irq_restore(flags); 218 local_irq_restore(flags);
179} 219}
180 220
181static inline void flush_cache_4096(unsigned long start, 221static inline void flush_cache_4096(unsigned long start,
182 unsigned long phys) 222 unsigned long phys)
183{ 223{
184 unsigned long flags; 224 unsigned long flags, exec_offset = 0;
185 extern void __flush_cache_4096(unsigned long addr, unsigned long phys, unsigned long exec_offset);
186 225
187 /* 226 /*
188 * SH7751, SH7751R, and ST40 have no restriction to handle cache. 227 * All types of SH-4 require PC to be in P2 to operate on the I-cache.
189 * (While SH7750 must do that at P2 area.) 228 * Some types of SH-4 require PC to be in P2 to operate on the D-cache.
190 */ 229 */
191 if ((cpu_data->flags & CPU_HAS_P2_FLUSH_BUG) 230 if ((cpu_data->flags & CPU_HAS_P2_FLUSH_BUG) ||
192 || start < CACHE_OC_ADDRESS_ARRAY) { 231 (start < CACHE_OC_ADDRESS_ARRAY))
193 local_irq_save(flags); 232 exec_offset = 0x20000000;
194 __flush_cache_4096(start | SH_CACHE_ASSOC, P1SEGADDR(phys), 0x20000000); 233
195 local_irq_restore(flags); 234 local_irq_save(flags);
196 } else { 235 __flush_cache_4096(start | SH_CACHE_ASSOC,
197 __flush_cache_4096(start | SH_CACHE_ASSOC, P1SEGADDR(phys), 0); 236 P1SEGADDR(phys), exec_offset);
198 } 237 local_irq_restore(flags);
199} 238}
200 239
201/* 240/*
@@ -206,15 +245,19 @@ void flush_dcache_page(struct page *page)
206{ 245{
207 if (test_bit(PG_mapped, &page->flags)) { 246 if (test_bit(PG_mapped, &page->flags)) {
208 unsigned long phys = PHYSADDR(page_address(page)); 247 unsigned long phys = PHYSADDR(page_address(page));
248 unsigned long addr = CACHE_OC_ADDRESS_ARRAY;
249 int i, n;
209 250
210 /* Loop all the D-cache */ 251 /* Loop all the D-cache */
211 flush_cache_4096(CACHE_OC_ADDRESS_ARRAY, phys); 252 n = cpu_data->dcache.n_aliases;
212 flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x1000, phys); 253 for (i = 0; i < n; i++, addr += PAGE_SIZE)
213 flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x2000, phys); 254 flush_cache_4096(addr, phys);
214 flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x3000, phys);
215 } 255 }
256
257 wmb();
216} 258}
217 259
260/* TODO: Selective icache invalidation through IC address array.. */
218static inline void flush_icache_all(void) 261static inline void flush_icache_all(void)
219{ 262{
220 unsigned long flags, ccr; 263 unsigned long flags, ccr;
@@ -227,34 +270,142 @@ static inline void flush_icache_all(void)
227 ccr |= CCR_CACHE_ICI; 270 ccr |= CCR_CACHE_ICI;
228 ctrl_outl(ccr, CCR); 271 ctrl_outl(ccr, CCR);
229 272
273 /*
274 * back_to_P1() will take care of the barrier for us, don't add
275 * another one!
276 */
277
230 back_to_P1(); 278 back_to_P1();
231 local_irq_restore(flags); 279 local_irq_restore(flags);
232} 280}
233 281
282void flush_dcache_all(void)
283{
284 (*__flush_dcache_segment_fn)(0UL, cpu_data->dcache.way_size);
285 wmb();
286}
287
234void flush_cache_all(void) 288void flush_cache_all(void)
235{ 289{
236 if (cpu_data->dcache.ways == 1) 290 flush_dcache_all();
237 __flush_dcache_all();
238 else
239 __flush_dcache_all_ex();
240 flush_icache_all(); 291 flush_icache_all();
241} 292}
242 293
294static void __flush_cache_mm(struct mm_struct *mm, unsigned long start,
295 unsigned long end)
296{
297 unsigned long d = 0, p = start & PAGE_MASK;
298 unsigned long alias_mask = cpu_data->dcache.alias_mask;
299 unsigned long n_aliases = cpu_data->dcache.n_aliases;
300 unsigned long select_bit;
301 unsigned long all_aliases_mask;
302 unsigned long addr_offset;
303 pgd_t *dir;
304 pmd_t *pmd;
305 pud_t *pud;
306 pte_t *pte;
307 int i;
308
309 dir = pgd_offset(mm, p);
310 pud = pud_offset(dir, p);
311 pmd = pmd_offset(pud, p);
312 end = PAGE_ALIGN(end);
313
314 all_aliases_mask = (1 << n_aliases) - 1;
315
316 do {
317 if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) {
318 p &= PMD_MASK;
319 p += PMD_SIZE;
320 pmd++;
321
322 continue;
323 }
324
325 pte = pte_offset_kernel(pmd, p);
326
327 do {
328 unsigned long phys;
329 pte_t entry = *pte;
330
331 if (!(pte_val(entry) & _PAGE_PRESENT)) {
332 pte++;
333 p += PAGE_SIZE;
334 continue;
335 }
336
337 phys = pte_val(entry) & PTE_PHYS_MASK;
338
339 if ((p ^ phys) & alias_mask) {
340 d |= 1 << ((p & alias_mask) >> PAGE_SHIFT);
341 d |= 1 << ((phys & alias_mask) >> PAGE_SHIFT);
342
343 if (d == all_aliases_mask)
344 goto loop_exit;
345 }
346
347 pte++;
348 p += PAGE_SIZE;
349 } while (p < end && ((unsigned long)pte & ~PAGE_MASK));
350 pmd++;
351 } while (p < end);
352
353loop_exit:
354 addr_offset = 0;
355 select_bit = 1;
356
357 for (i = 0; i < n_aliases; i++) {
358 if (d & select_bit) {
359 (*__flush_dcache_segment_fn)(addr_offset, PAGE_SIZE);
360 wmb();
361 }
362
363 select_bit <<= 1;
364 addr_offset += PAGE_SIZE;
365 }
366}
367
368/*
369 * Note : (RPC) since the caches are physically tagged, the only point
370 * of flush_cache_mm for SH-4 is to get rid of aliases from the
371 * D-cache. The assumption elsewhere, e.g. flush_cache_range, is that
372 * lines can stay resident so long as the virtual address they were
373 * accessed with (hence cache set) is in accord with the physical
374 * address (i.e. tag). It's no different here. So I reckon we don't
375 * need to flush the I-cache, since aliases don't matter for that. We
376 * should try that.
377 *
378 * Caller takes mm->mmap_sem.
379 */
243void flush_cache_mm(struct mm_struct *mm) 380void flush_cache_mm(struct mm_struct *mm)
244{ 381{
245 /* Is there any good way? */ 382 /*
246 /* XXX: possibly call flush_cache_range for each vm area */ 383 * If cache is only 4k-per-way, there are never any 'aliases'. Since
247 /* 384 * the cache is physically tagged, the data can just be left in there.
248 * FIXME: Really, the optimal solution here would be able to flush out
249 * individual lines created by the specified context, but this isn't
250 * feasible for a number of architectures (such as MIPS, and some
251 * SPARC) .. is this possible for SuperH?
252 *
253 * In the meantime, we'll just flush all of the caches.. this
254 * seems to be the simplest way to avoid at least a few wasted
255 * cache flushes. -Lethal
256 */ 385 */
257 flush_cache_all(); 386 if (cpu_data->dcache.n_aliases == 0)
387 return;
388
389 /*
390 * Don't bother groveling around the dcache for the VMA ranges
391 * if there are too many PTEs to make it worthwhile.
392 */
393 if (mm->nr_ptes >= MAX_DCACHE_PAGES)
394 flush_dcache_all();
395 else {
396 struct vm_area_struct *vma;
397
398 /*
399 * In this case there are reasonably sized ranges to flush,
400 * iterate through the VMA list and take care of any aliases.
401 */
402 for (vma = mm->mmap; vma; vma = vma->vm_next)
403 __flush_cache_mm(mm, vma->vm_start, vma->vm_end);
404 }
405
406 /* Only touch the icache if one of the VMAs has VM_EXEC set. */
407 if (mm->exec_vm)
408 flush_icache_all();
258} 409}
259 410
260/* 411/*
@@ -263,27 +414,40 @@ void flush_cache_mm(struct mm_struct *mm)
263 * ADDR: Virtual Address (U0 address) 414 * ADDR: Virtual Address (U0 address)
264 * PFN: Physical page number 415 * PFN: Physical page number
265 */ 416 */
266void flush_cache_page(struct vm_area_struct *vma, unsigned long address, unsigned long pfn) 417void flush_cache_page(struct vm_area_struct *vma, unsigned long address,
418 unsigned long pfn)
267{ 419{
268 unsigned long phys = pfn << PAGE_SHIFT; 420 unsigned long phys = pfn << PAGE_SHIFT;
421 unsigned int alias_mask;
422
423 alias_mask = cpu_data->dcache.alias_mask;
269 424
270 /* We only need to flush D-cache when we have alias */ 425 /* We only need to flush D-cache when we have alias */
271 if ((address^phys) & CACHE_ALIAS) { 426 if ((address^phys) & alias_mask) {
272 /* Loop 4K of the D-cache */ 427 /* Loop 4K of the D-cache */
273 flush_cache_4096( 428 flush_cache_4096(
274 CACHE_OC_ADDRESS_ARRAY | (address & CACHE_ALIAS), 429 CACHE_OC_ADDRESS_ARRAY | (address & alias_mask),
275 phys); 430 phys);
276 /* Loop another 4K of the D-cache */ 431 /* Loop another 4K of the D-cache */
277 flush_cache_4096( 432 flush_cache_4096(
278 CACHE_OC_ADDRESS_ARRAY | (phys & CACHE_ALIAS), 433 CACHE_OC_ADDRESS_ARRAY | (phys & alias_mask),
279 phys); 434 phys);
280 } 435 }
281 436
282 if (vma->vm_flags & VM_EXEC) 437 alias_mask = cpu_data->icache.alias_mask;
283 /* Loop 4K (half) of the I-cache */ 438 if (vma->vm_flags & VM_EXEC) {
439 /*
440 * Evict entries from the portion of the cache from which code
441 * may have been executed at this address (virtual). There's
442 * no need to evict from the portion corresponding to the
443 * physical address as for the D-cache, because we know the
444 * kernel has never executed the code through its identity
445 * translation.
446 */
284 flush_cache_4096( 447 flush_cache_4096(
285 CACHE_IC_ADDRESS_ARRAY | (address & 0x1000), 448 CACHE_IC_ADDRESS_ARRAY | (address & alias_mask),
286 phys); 449 phys);
450 }
287} 451}
288 452
289/* 453/*
@@ -298,52 +462,31 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long address, unsigne
298void flush_cache_range(struct vm_area_struct *vma, unsigned long start, 462void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
299 unsigned long end) 463 unsigned long end)
300{ 464{
301 unsigned long p = start & PAGE_MASK; 465 /*
302 pgd_t *dir; 466 * If cache is only 4k-per-way, there are never any 'aliases'. Since
303 pmd_t *pmd; 467 * the cache is physically tagged, the data can just be left in there.
304 pte_t *pte; 468 */
305 pte_t entry; 469 if (cpu_data->dcache.n_aliases == 0)
306 unsigned long phys; 470 return;
307 unsigned long d = 0;
308
309 dir = pgd_offset(vma->vm_mm, p);
310 pmd = pmd_offset(dir, p);
311 471
312 do { 472 /*
313 if (pmd_none(*pmd) || pmd_bad(*pmd)) { 473 * Don't bother with the lookup and alias check if we have a
314 p &= ~((1 << PMD_SHIFT) -1); 474 * wide range to cover, just blow away the dcache in its
315 p += (1 << PMD_SHIFT); 475 * entirety instead. -- PFM.
316 pmd++; 476 */
317 continue; 477 if (((end - start) >> PAGE_SHIFT) >= MAX_DCACHE_PAGES)
318 } 478 flush_dcache_all();
319 pte = pte_offset_kernel(pmd, p); 479 else
320 do { 480 __flush_cache_mm(vma->vm_mm, start, end);
321 entry = *pte; 481
322 if ((pte_val(entry) & _PAGE_PRESENT)) { 482 if (vma->vm_flags & VM_EXEC) {
323 phys = pte_val(entry)&PTE_PHYS_MASK; 483 /*
324 if ((p^phys) & CACHE_ALIAS) { 484 * TODO: Is this required??? Need to look at how I-cache
325 d |= 1 << ((p & CACHE_ALIAS)>>12); 485 * coherency is assured when new programs are loaded to see if
326 d |= 1 << ((phys & CACHE_ALIAS)>>12); 486 * this matters.
327 if (d == 0x0f) 487 */
328 goto loop_exit;
329 }
330 }
331 pte++;
332 p += PAGE_SIZE;
333 } while (p < end && ((unsigned long)pte & ~PAGE_MASK));
334 pmd++;
335 } while (p < end);
336 loop_exit:
337 if (d & 1)
338 flush_cache_4096_all(0);
339 if (d & 2)
340 flush_cache_4096_all(0x1000);
341 if (d & 4)
342 flush_cache_4096_all(0x2000);
343 if (d & 8)
344 flush_cache_4096_all(0x3000);
345 if (vma->vm_flags & VM_EXEC)
346 flush_icache_all(); 488 flush_icache_all();
489 }
347} 490}
348 491
349/* 492/*
@@ -357,5 +500,273 @@ void flush_icache_user_range(struct vm_area_struct *vma,
357 struct page *page, unsigned long addr, int len) 500 struct page *page, unsigned long addr, int len)
358{ 501{
359 flush_cache_page(vma, addr, page_to_pfn(page)); 502 flush_cache_page(vma, addr, page_to_pfn(page));
503 mb();
504}
505
506/**
507 * __flush_cache_4096
508 *
509 * @addr: address in memory mapped cache array
510 * @phys: P1 address to flush (has to match tags if addr has 'A' bit
511 * set i.e. associative write)
512 * @exec_offset: set to 0x20000000 if flush has to be executed from P2
513 * region else 0x0
514 *
515 * The offset into the cache array implied by 'addr' selects the
516 * 'colour' of the virtual address range that will be flushed. The
517 * operation (purge/write-back) is selected by the lower 2 bits of
518 * 'phys'.
519 */
520static void __flush_cache_4096(unsigned long addr, unsigned long phys,
521 unsigned long exec_offset)
522{
523 int way_count;
524 unsigned long base_addr = addr;
525 struct cache_info *dcache;
526 unsigned long way_incr;
527 unsigned long a, ea, p;
528 unsigned long temp_pc;
529
530 dcache = &cpu_data->dcache;
531 /* Write this way for better assembly. */
532 way_count = dcache->ways;
533 way_incr = dcache->way_incr;
534
535 /*
536 * Apply exec_offset (i.e. branch to P2 if required.).
537 *
538 * FIXME:
539 *
540 * If I write "=r" for the (temp_pc), it puts this in r6 hence
541 * trashing exec_offset before it's been added on - why? Hence
542 * "=&r" as a 'workaround'
543 */
544 asm volatile("mov.l 1f, %0\n\t"
545 "add %1, %0\n\t"
546 "jmp @%0\n\t"
547 "nop\n\t"
548 ".balign 4\n\t"
549 "1: .long 2f\n\t"
550 "2:\n" : "=&r" (temp_pc) : "r" (exec_offset));
551
552 /*
553 * We know there will be >=1 iteration, so write as do-while to avoid
554 * pointless nead-of-loop check for 0 iterations.
555 */
556 do {
557 ea = base_addr + PAGE_SIZE;
558 a = base_addr;
559 p = phys;
560
561 do {
562 *(volatile unsigned long *)a = p;
563 /*
564 * Next line: intentionally not p+32, saves an add, p
565 * will do since only the cache tag bits need to
566 * match.
567 */
568 *(volatile unsigned long *)(a+32) = p;
569 a += 64;
570 p += 64;
571 } while (a < ea);
572
573 base_addr += way_incr;
574 } while (--way_count != 0);
360} 575}
361 576
577/*
578 * Break the 1, 2 and 4 way variants of this out into separate functions to
579 * avoid nearly all the overhead of having the conditional stuff in the function
580 * bodies (+ the 1 and 2 way cases avoid saving any registers too).
581 */
582static void __flush_dcache_segment_1way(unsigned long start,
583 unsigned long extent_per_way)
584{
585 unsigned long orig_sr, sr_with_bl;
586 unsigned long base_addr;
587 unsigned long way_incr, linesz, way_size;
588 struct cache_info *dcache;
589 register unsigned long a0, a0e;
590
591 asm volatile("stc sr, %0" : "=r" (orig_sr));
592 sr_with_bl = orig_sr | (1<<28);
593 base_addr = ((unsigned long)&empty_zero_page[0]);
594
595 /*
596 * The previous code aligned base_addr to 16k, i.e. the way_size of all
597 * existing SH-4 D-caches. Whilst I don't see a need to have this
598 * aligned to any better than the cache line size (which it will be
599 * anyway by construction), let's align it to at least the way_size of
600 * any existing or conceivable SH-4 D-cache. -- RPC
601 */
602 base_addr = ((base_addr >> 16) << 16);
603 base_addr |= start;
604
605 dcache = &cpu_data->dcache;
606 linesz = dcache->linesz;
607 way_incr = dcache->way_incr;
608 way_size = dcache->way_size;
609
610 a0 = base_addr;
611 a0e = base_addr + extent_per_way;
612 do {
613 asm volatile("ldc %0, sr" : : "r" (sr_with_bl));
614 asm volatile("movca.l r0, @%0\n\t"
615 "ocbi @%0" : : "r" (a0));
616 a0 += linesz;
617 asm volatile("movca.l r0, @%0\n\t"
618 "ocbi @%0" : : "r" (a0));
619 a0 += linesz;
620 asm volatile("movca.l r0, @%0\n\t"
621 "ocbi @%0" : : "r" (a0));
622 a0 += linesz;
623 asm volatile("movca.l r0, @%0\n\t"
624 "ocbi @%0" : : "r" (a0));
625 asm volatile("ldc %0, sr" : : "r" (orig_sr));
626 a0 += linesz;
627 } while (a0 < a0e);
628}
629
630static void __flush_dcache_segment_2way(unsigned long start,
631 unsigned long extent_per_way)
632{
633 unsigned long orig_sr, sr_with_bl;
634 unsigned long base_addr;
635 unsigned long way_incr, linesz, way_size;
636 struct cache_info *dcache;
637 register unsigned long a0, a1, a0e;
638
639 asm volatile("stc sr, %0" : "=r" (orig_sr));
640 sr_with_bl = orig_sr | (1<<28);
641 base_addr = ((unsigned long)&empty_zero_page[0]);
642
643 /* See comment under 1-way above */
644 base_addr = ((base_addr >> 16) << 16);
645 base_addr |= start;
646
647 dcache = &cpu_data->dcache;
648 linesz = dcache->linesz;
649 way_incr = dcache->way_incr;
650 way_size = dcache->way_size;
651
652 a0 = base_addr;
653 a1 = a0 + way_incr;
654 a0e = base_addr + extent_per_way;
655 do {
656 asm volatile("ldc %0, sr" : : "r" (sr_with_bl));
657 asm volatile("movca.l r0, @%0\n\t"
658 "movca.l r0, @%1\n\t"
659 "ocbi @%0\n\t"
660 "ocbi @%1" : :
661 "r" (a0), "r" (a1));
662 a0 += linesz;
663 a1 += linesz;
664 asm volatile("movca.l r0, @%0\n\t"
665 "movca.l r0, @%1\n\t"
666 "ocbi @%0\n\t"
667 "ocbi @%1" : :
668 "r" (a0), "r" (a1));
669 a0 += linesz;
670 a1 += linesz;
671 asm volatile("movca.l r0, @%0\n\t"
672 "movca.l r0, @%1\n\t"
673 "ocbi @%0\n\t"
674 "ocbi @%1" : :
675 "r" (a0), "r" (a1));
676 a0 += linesz;
677 a1 += linesz;
678 asm volatile("movca.l r0, @%0\n\t"
679 "movca.l r0, @%1\n\t"
680 "ocbi @%0\n\t"
681 "ocbi @%1" : :
682 "r" (a0), "r" (a1));
683 asm volatile("ldc %0, sr" : : "r" (orig_sr));
684 a0 += linesz;
685 a1 += linesz;
686 } while (a0 < a0e);
687}
688
689static void __flush_dcache_segment_4way(unsigned long start,
690 unsigned long extent_per_way)
691{
692 unsigned long orig_sr, sr_with_bl;
693 unsigned long base_addr;
694 unsigned long way_incr, linesz, way_size;
695 struct cache_info *dcache;
696 register unsigned long a0, a1, a2, a3, a0e;
697
698 asm volatile("stc sr, %0" : "=r" (orig_sr));
699 sr_with_bl = orig_sr | (1<<28);
700 base_addr = ((unsigned long)&empty_zero_page[0]);
701
702 /* See comment under 1-way above */
703 base_addr = ((base_addr >> 16) << 16);
704 base_addr |= start;
705
706 dcache = &cpu_data->dcache;
707 linesz = dcache->linesz;
708 way_incr = dcache->way_incr;
709 way_size = dcache->way_size;
710
711 a0 = base_addr;
712 a1 = a0 + way_incr;
713 a2 = a1 + way_incr;
714 a3 = a2 + way_incr;
715 a0e = base_addr + extent_per_way;
716 do {
717 asm volatile("ldc %0, sr" : : "r" (sr_with_bl));
718 asm volatile("movca.l r0, @%0\n\t"
719 "movca.l r0, @%1\n\t"
720 "movca.l r0, @%2\n\t"
721 "movca.l r0, @%3\n\t"
722 "ocbi @%0\n\t"
723 "ocbi @%1\n\t"
724 "ocbi @%2\n\t"
725 "ocbi @%3\n\t" : :
726 "r" (a0), "r" (a1), "r" (a2), "r" (a3));
727 a0 += linesz;
728 a1 += linesz;
729 a2 += linesz;
730 a3 += linesz;
731 asm volatile("movca.l r0, @%0\n\t"
732 "movca.l r0, @%1\n\t"
733 "movca.l r0, @%2\n\t"
734 "movca.l r0, @%3\n\t"
735 "ocbi @%0\n\t"
736 "ocbi @%1\n\t"
737 "ocbi @%2\n\t"
738 "ocbi @%3\n\t" : :
739 "r" (a0), "r" (a1), "r" (a2), "r" (a3));
740 a0 += linesz;
741 a1 += linesz;
742 a2 += linesz;
743 a3 += linesz;
744 asm volatile("movca.l r0, @%0\n\t"
745 "movca.l r0, @%1\n\t"
746 "movca.l r0, @%2\n\t"
747 "movca.l r0, @%3\n\t"
748 "ocbi @%0\n\t"
749 "ocbi @%1\n\t"
750 "ocbi @%2\n\t"
751 "ocbi @%3\n\t" : :
752 "r" (a0), "r" (a1), "r" (a2), "r" (a3));
753 a0 += linesz;
754 a1 += linesz;
755 a2 += linesz;
756 a3 += linesz;
757 asm volatile("movca.l r0, @%0\n\t"
758 "movca.l r0, @%1\n\t"
759 "movca.l r0, @%2\n\t"
760 "movca.l r0, @%3\n\t"
761 "ocbi @%0\n\t"
762 "ocbi @%1\n\t"
763 "ocbi @%2\n\t"
764 "ocbi @%3\n\t" : :
765 "r" (a0), "r" (a1), "r" (a2), "r" (a3));
766 asm volatile("ldc %0, sr" : : "r" (orig_sr));
767 a0 += linesz;
768 a1 += linesz;
769 a2 += linesz;
770 a3 += linesz;
771 } while (a0 < a0e);
772}
diff --git a/arch/sh/mm/cache-sh7705.c b/arch/sh/mm/cache-sh7705.c
index ad8ed7d41e16..045abdf078f5 100644
--- a/arch/sh/mm/cache-sh7705.c
+++ b/arch/sh/mm/cache-sh7705.c
@@ -9,7 +9,6 @@
9 * for more details. 9 * for more details.
10 * 10 *
11 */ 11 */
12
13#include <linux/init.h> 12#include <linux/init.h>
14#include <linux/mman.h> 13#include <linux/mman.h>
15#include <linux/mm.h> 14#include <linux/mm.h>
@@ -25,14 +24,10 @@
25#include <asm/mmu_context.h> 24#include <asm/mmu_context.h>
26#include <asm/cacheflush.h> 25#include <asm/cacheflush.h>
27 26
28/* The 32KB cache on the SH7705 suffers from the same synonym problem 27/*
29 * as SH4 CPUs */ 28 * The 32KB cache on the SH7705 suffers from the same synonym problem
30 29 * as SH4 CPUs
31#define __pte_offset(address) \ 30 */
32 ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
33#define pte_offset(dir, address) ((pte_t *) pmd_page_kernel(*(dir)) + \
34 __pte_offset(address))
35
36static inline void cache_wback_all(void) 31static inline void cache_wback_all(void)
37{ 32{
38 unsigned long ways, waysize, addrstart; 33 unsigned long ways, waysize, addrstart;
@@ -73,7 +68,6 @@ void flush_icache_range(unsigned long start, unsigned long end)
73 __flush_wback_region((void *)start, end - start); 68 __flush_wback_region((void *)start, end - start);
74} 69}
75 70
76
77/* 71/*
78 * Writeback&Invalidate the D-cache of the page 72 * Writeback&Invalidate the D-cache of the page
79 */ 73 */
@@ -128,7 +122,6 @@ static void __flush_dcache_page(unsigned long phys)
128 local_irq_restore(flags); 122 local_irq_restore(flags);
129} 123}
130 124
131
132/* 125/*
133 * Write back & invalidate the D-cache of the page. 126 * Write back & invalidate the D-cache of the page.
134 * (To avoid "alias" issues) 127 * (To avoid "alias" issues)
@@ -186,7 +179,8 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
186 * 179 *
187 * ADDRESS: Virtual Address (U0 address) 180 * ADDRESS: Virtual Address (U0 address)
188 */ 181 */
189void flush_cache_page(struct vm_area_struct *vma, unsigned long address, unsigned long pfn) 182void flush_cache_page(struct vm_area_struct *vma, unsigned long address,
183 unsigned long pfn)
190{ 184{
191 __flush_dcache_page(pfn << PAGE_SHIFT); 185 __flush_dcache_page(pfn << PAGE_SHIFT);
192} 186}
@@ -203,4 +197,3 @@ void flush_icache_page(struct vm_area_struct *vma, struct page *page)
203{ 197{
204 __flush_purge_region(page_address(page), PAGE_SIZE); 198 __flush_purge_region(page_address(page), PAGE_SIZE);
205} 199}
206
diff --git a/arch/sh/mm/clear_page.S b/arch/sh/mm/clear_page.S
index 08acead7b2a1..7b96425ae270 100644
--- a/arch/sh/mm/clear_page.S
+++ b/arch/sh/mm/clear_page.S
@@ -193,102 +193,5 @@ ENTRY(__clear_user_page)
193 nop 193 nop
194.L4096: .word 4096 194.L4096: .word 4096
195 195
196ENTRY(__flush_cache_4096)
197 mov.l 1f,r3
198 add r6,r3
199 mov r4,r0
200 mov #64,r2
201 shll r2
202 mov #64,r6
203 jmp @r3
204 mov #96,r7
205 .align 2
2061: .long 2f
2072:
208 .rept 32
209 mov.l r5,@r0
210 mov.l r5,@(32,r0)
211 mov.l r5,@(r0,r6)
212 mov.l r5,@(r0,r7)
213 add r2,r5
214 add r2,r0
215 .endr
216 nop
217 nop
218 nop
219 nop
220 nop
221 nop
222 nop
223 rts
224 nop
225
226ENTRY(__flush_dcache_all)
227 mov.l 2f,r0
228 mov.l 3f,r4
229 and r0,r4 ! r4 = (unsigned long)&empty_zero_page[0] & ~0xffffc000
230 stc sr,r1 ! save SR
231 mov.l 4f,r2
232 or r1,r2
233 mov #32,r3
234 shll2 r3
2351:
236 ldc r2,sr ! set BL bit
237 movca.l r0,@r4
238 ocbi @r4
239 add #32,r4
240 movca.l r0,@r4
241 ocbi @r4
242 add #32,r4
243 movca.l r0,@r4
244 ocbi @r4
245 add #32,r4
246 movca.l r0,@r4
247 ocbi @r4
248 ldc r1,sr ! restore SR
249 dt r3
250 bf/s 1b
251 add #32,r4
252
253 rts
254 nop
255 .align 2
2562: .long 0xffffc000
2573: .long empty_zero_page
2584: .long 0x10000000 ! BL bit
259
260/* __flush_cache_4096_all(unsigned long addr) */
261ENTRY(__flush_cache_4096_all)
262 mov.l 2f,r0
263 mov.l 3f,r2
264 and r0,r2
265 or r2,r4 ! r4 = addr | (unsigned long)&empty_zero_page[0] & ~0x3fff
266 stc sr,r1 ! save SR
267 mov.l 4f,r2
268 or r1,r2
269 mov #32,r3
2701:
271 ldc r2,sr ! set BL bit
272 movca.l r0,@r4
273 ocbi @r4
274 add #32,r4
275 movca.l r0,@r4
276 ocbi @r4
277 add #32,r4
278 movca.l r0,@r4
279 ocbi @r4
280 add #32,r4
281 movca.l r0,@r4
282 ocbi @r4
283 ldc r1,sr ! restore SR
284 dt r3
285 bf/s 1b
286 add #32,r4
287
288 rts
289 nop
290 .align 2
2912: .long 0xffffc000
2923: .long empty_zero_page
2934: .long 0x10000000 ! BL bit
294#endif 196#endif
197
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index ee73e30263af..c81e6b67ad30 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -9,6 +9,8 @@
9 */ 9 */
10#include <linux/mm.h> 10#include <linux/mm.h>
11#include <linux/dma-mapping.h> 11#include <linux/dma-mapping.h>
12#include <asm/cacheflush.h>
13#include <asm/addrspace.h>
12#include <asm/io.h> 14#include <asm/io.h>
13 15
14void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle) 16void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle)
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index 775f86cd3fe8..c69fd603226a 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -1,33 +1,22 @@
1/* $Id: fault.c,v 1.14 2004/01/13 05:52:11 kkojima Exp $ 1/*
2 * Page fault handler for SH with an MMU.
2 * 3 *
3 * linux/arch/sh/mm/fault.c
4 * Copyright (C) 1999 Niibe Yutaka 4 * Copyright (C) 1999 Niibe Yutaka
5 * Copyright (C) 2003 Paul Mundt 5 * Copyright (C) 2003 Paul Mundt
6 * 6 *
7 * Based on linux/arch/i386/mm/fault.c: 7 * Based on linux/arch/i386/mm/fault.c:
8 * Copyright (C) 1995 Linus Torvalds 8 * Copyright (C) 1995 Linus Torvalds
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive
12 * for more details.
9 */ 13 */
10
11#include <linux/signal.h>
12#include <linux/sched.h>
13#include <linux/kernel.h> 14#include <linux/kernel.h>
14#include <linux/errno.h>
15#include <linux/string.h>
16#include <linux/types.h>
17#include <linux/ptrace.h>
18#include <linux/mman.h>
19#include <linux/mm.h> 15#include <linux/mm.h>
20#include <linux/smp.h> 16#include <linux/hardirq.h>
21#include <linux/smp_lock.h> 17#include <linux/kprobes.h>
22#include <linux/interrupt.h>
23#include <linux/module.h>
24
25#include <asm/system.h> 18#include <asm/system.h>
26#include <asm/io.h>
27#include <asm/uaccess.h>
28#include <asm/pgalloc.h>
29#include <asm/mmu_context.h> 19#include <asm/mmu_context.h>
30#include <asm/cacheflush.h>
31#include <asm/kgdb.h> 20#include <asm/kgdb.h>
32 21
33extern void die(const char *,struct pt_regs *,long); 22extern void die(const char *,struct pt_regs *,long);
@@ -187,18 +176,30 @@ do_sigbus:
187 goto no_context; 176 goto no_context;
188} 177}
189 178
179#ifdef CONFIG_SH_STORE_QUEUES
190/* 180/*
191 * Called with interrupt disabled. 181 * This is a special case for the SH-4 store queues, as pages for this
182 * space still need to be faulted in before it's possible to flush the
183 * store queue cache for writeout to the remapped region.
192 */ 184 */
193asmlinkage int __do_page_fault(struct pt_regs *regs, unsigned long writeaccess, 185#define P3_ADDR_MAX (P4SEG_STORE_QUE + 0x04000000)
194 unsigned long address) 186#else
187#define P3_ADDR_MAX P4SEG
188#endif
189
190/*
191 * Called with interrupts disabled.
192 */
193asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs,
194 unsigned long writeaccess,
195 unsigned long address)
195{ 196{
196 unsigned long addrmax = P4SEG;
197 pgd_t *pgd; 197 pgd_t *pgd;
198 pud_t *pud;
198 pmd_t *pmd; 199 pmd_t *pmd;
199 pte_t *pte; 200 pte_t *pte;
200 pte_t entry; 201 pte_t entry;
201 struct mm_struct *mm; 202 struct mm_struct *mm = current->mm;
202 spinlock_t *ptl; 203 spinlock_t *ptl;
203 int ret = 1; 204 int ret = 1;
204 205
@@ -207,31 +208,37 @@ asmlinkage int __do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
207 kgdb_bus_err_hook(); 208 kgdb_bus_err_hook();
208#endif 209#endif
209 210
210#ifdef CONFIG_SH_STORE_QUEUES 211 /*
211 addrmax = P4SEG_STORE_QUE + 0x04000000; 212 * We don't take page faults for P1, P2, and parts of P4, these
212#endif 213 * are always mapped, whether it be due to legacy behaviour in
213 214 * 29-bit mode, or due to PMB configuration in 32-bit mode.
214 if (address >= P3SEG && address < addrmax) { 215 */
216 if (address >= P3SEG && address < P3_ADDR_MAX) {
215 pgd = pgd_offset_k(address); 217 pgd = pgd_offset_k(address);
216 mm = NULL; 218 mm = NULL;
217 } else if (address >= TASK_SIZE) 219 } else {
218 return 1; 220 if (unlikely(address >= TASK_SIZE || !mm))
219 else if (!(mm = current->mm)) 221 return 1;
220 return 1; 222
221 else
222 pgd = pgd_offset(mm, address); 223 pgd = pgd_offset(mm, address);
224 }
223 225
224 pmd = pmd_offset(pgd, address); 226 pud = pud_offset(pgd, address);
227 if (pud_none_or_clear_bad(pud))
228 return 1;
229 pmd = pmd_offset(pud, address);
225 if (pmd_none_or_clear_bad(pmd)) 230 if (pmd_none_or_clear_bad(pmd))
226 return 1; 231 return 1;
232
227 if (mm) 233 if (mm)
228 pte = pte_offset_map_lock(mm, pmd, address, &ptl); 234 pte = pte_offset_map_lock(mm, pmd, address, &ptl);
229 else 235 else
230 pte = pte_offset_kernel(pmd, address); 236 pte = pte_offset_kernel(pmd, address);
231 237
232 entry = *pte; 238 entry = *pte;
233 if (pte_none(entry) || pte_not_present(entry) 239 if (unlikely(pte_none(entry) || pte_not_present(entry)))
234 || (writeaccess && !pte_write(entry))) 240 goto unlock;
241 if (unlikely(writeaccess && !pte_write(entry)))
235 goto unlock; 242 goto unlock;
236 243
237 if (writeaccess) 244 if (writeaccess)
@@ -243,13 +250,7 @@ asmlinkage int __do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
243 * ITLB is not affected by "ldtlb" instruction. 250 * ITLB is not affected by "ldtlb" instruction.
244 * So, we need to flush the entry by ourselves. 251 * So, we need to flush the entry by ourselves.
245 */ 252 */
246 253 __flush_tlb_page(get_asid(), address & PAGE_MASK);
247 {
248 unsigned long flags;
249 local_irq_save(flags);
250 __flush_tlb_page(get_asid(), address&PAGE_MASK);
251 local_irq_restore(flags);
252 }
253#endif 254#endif
254 255
255 set_pte(pte, entry); 256 set_pte(pte, entry);
@@ -260,121 +261,3 @@ unlock:
260 pte_unmap_unlock(pte, ptl); 261 pte_unmap_unlock(pte, ptl);
261 return ret; 262 return ret;
262} 263}
263
264void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
265{
266 if (vma->vm_mm && vma->vm_mm->context != NO_CONTEXT) {
267 unsigned long flags;
268 unsigned long asid;
269 unsigned long saved_asid = MMU_NO_ASID;
270
271 asid = vma->vm_mm->context & MMU_CONTEXT_ASID_MASK;
272 page &= PAGE_MASK;
273
274 local_irq_save(flags);
275 if (vma->vm_mm != current->mm) {
276 saved_asid = get_asid();
277 set_asid(asid);
278 }
279 __flush_tlb_page(asid, page);
280 if (saved_asid != MMU_NO_ASID)
281 set_asid(saved_asid);
282 local_irq_restore(flags);
283 }
284}
285
286void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
287 unsigned long end)
288{
289 struct mm_struct *mm = vma->vm_mm;
290
291 if (mm->context != NO_CONTEXT) {
292 unsigned long flags;
293 int size;
294
295 local_irq_save(flags);
296 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
297 if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */
298 mm->context = NO_CONTEXT;
299 if (mm == current->mm)
300 activate_context(mm);
301 } else {
302 unsigned long asid = mm->context&MMU_CONTEXT_ASID_MASK;
303 unsigned long saved_asid = MMU_NO_ASID;
304
305 start &= PAGE_MASK;
306 end += (PAGE_SIZE - 1);
307 end &= PAGE_MASK;
308 if (mm != current->mm) {
309 saved_asid = get_asid();
310 set_asid(asid);
311 }
312 while (start < end) {
313 __flush_tlb_page(asid, start);
314 start += PAGE_SIZE;
315 }
316 if (saved_asid != MMU_NO_ASID)
317 set_asid(saved_asid);
318 }
319 local_irq_restore(flags);
320 }
321}
322
323void flush_tlb_kernel_range(unsigned long start, unsigned long end)
324{
325 unsigned long flags;
326 int size;
327
328 local_irq_save(flags);
329 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
330 if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */
331 flush_tlb_all();
332 } else {
333 unsigned long asid = init_mm.context&MMU_CONTEXT_ASID_MASK;
334 unsigned long saved_asid = get_asid();
335
336 start &= PAGE_MASK;
337 end += (PAGE_SIZE - 1);
338 end &= PAGE_MASK;
339 set_asid(asid);
340 while (start < end) {
341 __flush_tlb_page(asid, start);
342 start += PAGE_SIZE;
343 }
344 set_asid(saved_asid);
345 }
346 local_irq_restore(flags);
347}
348
349void flush_tlb_mm(struct mm_struct *mm)
350{
351 /* Invalidate all TLB of this process. */
352 /* Instead of invalidating each TLB, we get new MMU context. */
353 if (mm->context != NO_CONTEXT) {
354 unsigned long flags;
355
356 local_irq_save(flags);
357 mm->context = NO_CONTEXT;
358 if (mm == current->mm)
359 activate_context(mm);
360 local_irq_restore(flags);
361 }
362}
363
364void flush_tlb_all(void)
365{
366 unsigned long flags, status;
367
368 /*
369 * Flush all the TLB.
370 *
371 * Write to the MMU control register's bit:
372 * TF-bit for SH-3, TI-bit for SH-4.
373 * It's same position, bit #2.
374 */
375 local_irq_save(flags);
376 status = ctrl_inl(MMUCR);
377 status |= 0x04;
378 ctrl_outl(status, MMUCR);
379 local_irq_restore(flags);
380}
diff --git a/arch/sh/mm/hugetlbpage.c b/arch/sh/mm/hugetlbpage.c
index 2a85bc15a412..329059d6b54a 100644
--- a/arch/sh/mm/hugetlbpage.c
+++ b/arch/sh/mm/hugetlbpage.c
@@ -26,61 +26,41 @@
26pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) 26pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
27{ 27{
28 pgd_t *pgd; 28 pgd_t *pgd;
29 pud_t *pud;
29 pmd_t *pmd; 30 pmd_t *pmd;
30 pte_t *pte = NULL; 31 pte_t *pte = NULL;
31 32
32 pgd = pgd_offset(mm, addr); 33 pgd = pgd_offset(mm, addr);
33 if (pgd) { 34 if (pgd) {
34 pmd = pmd_alloc(mm, pgd, addr); 35 pud = pud_alloc(mm, pgd, addr);
35 if (pmd) 36 if (pud) {
36 pte = pte_alloc_map(mm, pmd, addr); 37 pmd = pmd_alloc(mm, pud, addr);
38 if (pmd)
39 pte = pte_alloc_map(mm, pmd, addr);
40 }
37 } 41 }
42
38 return pte; 43 return pte;
39} 44}
40 45
41pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) 46pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
42{ 47{
43 pgd_t *pgd; 48 pgd_t *pgd;
49 pud_t *pud;
44 pmd_t *pmd; 50 pmd_t *pmd;
45 pte_t *pte = NULL; 51 pte_t *pte = NULL;
46 52
47 pgd = pgd_offset(mm, addr); 53 pgd = pgd_offset(mm, addr);
48 if (pgd) { 54 if (pgd) {
49 pmd = pmd_offset(pgd, addr); 55 pud = pud_offset(pgd, addr);
50 if (pmd) 56 if (pud) {
51 pte = pte_offset_map(pmd, addr); 57 pmd = pmd_offset(pud, addr);
52 } 58 if (pmd)
53 return pte; 59 pte = pte_offset_map(pmd, addr);
54} 60 }
55
56void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
57 pte_t *ptep, pte_t entry)
58{
59 int i;
60
61 for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
62 set_pte_at(mm, addr, ptep, entry);
63 ptep++;
64 addr += PAGE_SIZE;
65 pte_val(entry) += PAGE_SIZE;
66 } 61 }
67}
68
69pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
70 pte_t *ptep)
71{
72 pte_t entry;
73 int i;
74
75 entry = *ptep;
76 62
77 for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { 63 return pte;
78 pte_clear(mm, addr, ptep);
79 addr += PAGE_SIZE;
80 ptep++;
81 }
82
83 return entry;
84} 64}
85 65
86struct page *follow_huge_addr(struct mm_struct *mm, 66struct page *follow_huge_addr(struct mm_struct *mm,
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 8ea27ca4b700..7154d1ce9785 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -24,7 +24,7 @@
24#include <linux/highmem.h> 24#include <linux/highmem.h>
25#include <linux/bootmem.h> 25#include <linux/bootmem.h>
26#include <linux/pagemap.h> 26#include <linux/pagemap.h>
27 27#include <linux/proc_fs.h>
28#include <asm/processor.h> 28#include <asm/processor.h>
29#include <asm/system.h> 29#include <asm/system.h>
30#include <asm/uaccess.h> 30#include <asm/uaccess.h>
@@ -80,6 +80,7 @@ void show_mem(void)
80static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) 80static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
81{ 81{
82 pgd_t *pgd; 82 pgd_t *pgd;
83 pud_t *pud;
83 pmd_t *pmd; 84 pmd_t *pmd;
84 pte_t *pte; 85 pte_t *pte;
85 86
@@ -89,7 +90,17 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
89 return; 90 return;
90 } 91 }
91 92
92 pmd = pmd_offset(pgd, addr); 93 pud = pud_offset(pgd, addr);
94 if (pud_none(*pud)) {
95 pmd = (pmd_t *)get_zeroed_page(GFP_ATOMIC);
96 set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
97 if (pmd != pmd_offset(pud, 0)) {
98 pud_ERROR(*pud);
99 return;
100 }
101 }
102
103 pmd = pmd_offset(pud, addr);
93 if (pmd_none(*pmd)) { 104 if (pmd_none(*pmd)) {
94 pte = (pte_t *)get_zeroed_page(GFP_ATOMIC); 105 pte = (pte_t *)get_zeroed_page(GFP_ATOMIC);
95 set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER)); 106 set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
@@ -212,6 +223,8 @@ void __init paging_init(void)
212 free_area_init_node(0, NODE_DATA(0), zones_size, __MEMORY_START >> PAGE_SHIFT, 0); 223 free_area_init_node(0, NODE_DATA(0), zones_size, __MEMORY_START >> PAGE_SHIFT, 0);
213} 224}
214 225
226static struct kcore_list kcore_mem, kcore_vmalloc;
227
215void __init mem_init(void) 228void __init mem_init(void)
216{ 229{
217 extern unsigned long empty_zero_page[1024]; 230 extern unsigned long empty_zero_page[1024];
@@ -237,8 +250,13 @@ void __init mem_init(void)
237 * Setup wrappers for copy/clear_page(), these will get overridden 250 * Setup wrappers for copy/clear_page(), these will get overridden
238 * later in the boot process if a better method is available. 251 * later in the boot process if a better method is available.
239 */ 252 */
253#ifdef CONFIG_MMU
240 copy_page = copy_page_slow; 254 copy_page = copy_page_slow;
241 clear_page = clear_page_slow; 255 clear_page = clear_page_slow;
256#else
257 copy_page = copy_page_nommu;
258 clear_page = clear_page_nommu;
259#endif
242 260
243 /* this will put all low memory onto the freelists */ 261 /* this will put all low memory onto the freelists */
244 totalram_pages += free_all_bootmem_node(NODE_DATA(0)); 262 totalram_pages += free_all_bootmem_node(NODE_DATA(0));
@@ -254,7 +272,12 @@ void __init mem_init(void)
254 datasize = (unsigned long) &_edata - (unsigned long) &_etext; 272 datasize = (unsigned long) &_edata - (unsigned long) &_etext;
255 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; 273 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
256 274
257 printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n", 275 kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
276 kclist_add(&kcore_vmalloc, (void *)VMALLOC_START,
277 VMALLOC_END - VMALLOC_START);
278
279 printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, "
280 "%dk reserved, %dk data, %dk init)\n",
258 (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), 281 (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
259 max_mapnr << (PAGE_SHIFT-10), 282 max_mapnr << (PAGE_SHIFT-10),
260 codesize >> 10, 283 codesize >> 10,
@@ -263,6 +286,9 @@ void __init mem_init(void)
263 initsize >> 10); 286 initsize >> 10);
264 287
265 p3_cache_init(); 288 p3_cache_init();
289
290 /* Initialize the vDSO */
291 vsyscall_init();
266} 292}
267 293
268void free_initmem(void) 294void free_initmem(void)
diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c
index 96fa4a999e2a..a9fe80cfc233 100644
--- a/arch/sh/mm/ioremap.c
+++ b/arch/sh/mm/ioremap.c
@@ -15,6 +15,7 @@
15#include <linux/vmalloc.h> 15#include <linux/vmalloc.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/mm.h> 17#include <linux/mm.h>
18#include <linux/pci.h>
18#include <asm/io.h> 19#include <asm/io.h>
19#include <asm/page.h> 20#include <asm/page.h>
20#include <asm/pgalloc.h> 21#include <asm/pgalloc.h>
@@ -135,6 +136,20 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
135 return (void __iomem *)phys_to_virt(phys_addr); 136 return (void __iomem *)phys_to_virt(phys_addr);
136 137
137 /* 138 /*
139 * If we're on an SH7751 or SH7780 PCI controller, PCI memory is
140 * mapped at the end of the address space (typically 0xfd000000)
141 * in a non-translatable area, so mapping through page tables for
142 * this area is not only pointless, but also fundamentally
143 * broken. Just return the physical address instead.
144 *
145 * For boards that map a small PCI memory aperture somewhere in
146 * P1/P2 space, ioremap() will already do the right thing,
147 * and we'll never get this far.
148 */
149 if (is_pci_memaddr(phys_addr) && is_pci_memaddr(last_addr))
150 return (void __iomem *)phys_addr;
151
152 /*
138 * Don't allow anybody to remap normal RAM that we're using.. 153 * Don't allow anybody to remap normal RAM that we're using..
139 */ 154 */
140 if (phys_addr < virt_to_phys(high_memory)) 155 if (phys_addr < virt_to_phys(high_memory))
@@ -192,7 +207,7 @@ void __iounmap(void __iomem *addr)
192 unsigned long vaddr = (unsigned long __force)addr; 207 unsigned long vaddr = (unsigned long __force)addr;
193 struct vm_struct *p; 208 struct vm_struct *p;
194 209
195 if (PXSEG(vaddr) < P3SEG) 210 if (PXSEG(vaddr) < P3SEG || is_pci_memaddr(vaddr))
196 return; 211 return;
197 212
198#ifdef CONFIG_32BIT 213#ifdef CONFIG_32BIT
diff --git a/arch/sh/mm/pg-nommu.c b/arch/sh/mm/pg-nommu.c
index 8f9165a4e333..d15221beaa16 100644
--- a/arch/sh/mm/pg-nommu.c
+++ b/arch/sh/mm/pg-nommu.c
@@ -14,23 +14,24 @@
14#include <linux/string.h> 14#include <linux/string.h>
15#include <asm/page.h> 15#include <asm/page.h>
16 16
17static void copy_page_nommu(void *to, void *from) 17void copy_page_nommu(void *to, void *from)
18{ 18{
19 memcpy(to, from, PAGE_SIZE); 19 memcpy(to, from, PAGE_SIZE);
20} 20}
21 21
22static void clear_page_nommu(void *to) 22void clear_page_nommu(void *to)
23{ 23{
24 memset(to, 0, PAGE_SIZE); 24 memset(to, 0, PAGE_SIZE);
25} 25}
26 26
27static int __init pg_nommu_init(void) 27__kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n)
28{ 28{
29 copy_page = copy_page_nommu; 29 memcpy(to, from, n);
30 clear_page = clear_page_nommu;
31
32 return 0; 30 return 0;
33} 31}
34 32
35subsys_initcall(pg_nommu_init); 33__kernel_size_t __clear_user(void *to, __kernel_size_t n)
36 34{
35 memset(to, 0, n);
36 return 0;
37}
diff --git a/arch/sh/mm/pg-sh4.c b/arch/sh/mm/pg-sh4.c
index c776b60fc250..07371ed7a313 100644
--- a/arch/sh/mm/pg-sh4.c
+++ b/arch/sh/mm/pg-sh4.c
@@ -2,7 +2,7 @@
2 * arch/sh/mm/pg-sh4.c 2 * arch/sh/mm/pg-sh4.c
3 * 3 *
4 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka 4 * Copyright (C) 1999, 2000, 2002 Niibe Yutaka
5 * Copyright (C) 2002 Paul Mundt 5 * Copyright (C) 2002 - 2005 Paul Mundt
6 * 6 *
7 * Released under the terms of the GNU GPL v2.0. 7 * Released under the terms of the GNU GPL v2.0.
8 */ 8 */
@@ -23,6 +23,8 @@
23 23
24extern struct semaphore p3map_sem[]; 24extern struct semaphore p3map_sem[];
25 25
26#define CACHE_ALIAS (cpu_data->dcache.alias_mask)
27
26/* 28/*
27 * clear_user_page 29 * clear_user_page
28 * @to: P1 address 30 * @to: P1 address
@@ -35,14 +37,15 @@ void clear_user_page(void *to, unsigned long address, struct page *page)
35 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) 37 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
36 clear_page(to); 38 clear_page(to);
37 else { 39 else {
38 pgprot_t pgprot = __pgprot(_PAGE_PRESENT | 40 pgprot_t pgprot = __pgprot(_PAGE_PRESENT |
39 _PAGE_RW | _PAGE_CACHABLE | 41 _PAGE_RW | _PAGE_CACHABLE |
40 _PAGE_DIRTY | _PAGE_ACCESSED | 42 _PAGE_DIRTY | _PAGE_ACCESSED |
41 _PAGE_HW_SHARED | _PAGE_FLAGS_HARD); 43 _PAGE_HW_SHARED | _PAGE_FLAGS_HARD);
42 unsigned long phys_addr = PHYSADDR(to); 44 unsigned long phys_addr = PHYSADDR(to);
43 unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS); 45 unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS);
44 pgd_t *dir = pgd_offset_k(p3_addr); 46 pgd_t *pgd = pgd_offset_k(p3_addr);
45 pmd_t *pmd = pmd_offset(dir, p3_addr); 47 pud_t *pud = pud_offset(pgd, p3_addr);
48 pmd_t *pmd = pmd_offset(pud, p3_addr);
46 pte_t *pte = pte_offset_kernel(pmd, p3_addr); 49 pte_t *pte = pte_offset_kernel(pmd, p3_addr);
47 pte_t entry; 50 pte_t entry;
48 unsigned long flags; 51 unsigned long flags;
@@ -67,21 +70,22 @@ void clear_user_page(void *to, unsigned long address, struct page *page)
67 * @address: U0 address to be mapped 70 * @address: U0 address to be mapped
68 * @page: page (virt_to_page(to)) 71 * @page: page (virt_to_page(to))
69 */ 72 */
70void copy_user_page(void *to, void *from, unsigned long address, 73void copy_user_page(void *to, void *from, unsigned long address,
71 struct page *page) 74 struct page *page)
72{ 75{
73 __set_bit(PG_mapped, &page->flags); 76 __set_bit(PG_mapped, &page->flags);
74 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) 77 if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0)
75 copy_page(to, from); 78 copy_page(to, from);
76 else { 79 else {
77 pgprot_t pgprot = __pgprot(_PAGE_PRESENT | 80 pgprot_t pgprot = __pgprot(_PAGE_PRESENT |
78 _PAGE_RW | _PAGE_CACHABLE | 81 _PAGE_RW | _PAGE_CACHABLE |
79 _PAGE_DIRTY | _PAGE_ACCESSED | 82 _PAGE_DIRTY | _PAGE_ACCESSED |
80 _PAGE_HW_SHARED | _PAGE_FLAGS_HARD); 83 _PAGE_HW_SHARED | _PAGE_FLAGS_HARD);
81 unsigned long phys_addr = PHYSADDR(to); 84 unsigned long phys_addr = PHYSADDR(to);
82 unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS); 85 unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS);
83 pgd_t *dir = pgd_offset_k(p3_addr); 86 pgd_t *pgd = pgd_offset_k(p3_addr);
84 pmd_t *pmd = pmd_offset(dir, p3_addr); 87 pud_t *pud = pud_offset(pgd, p3_addr);
88 pmd_t *pmd = pmd_offset(pud, p3_addr);
85 pte_t *pte = pte_offset_kernel(pmd, p3_addr); 89 pte_t *pte = pte_offset_kernel(pmd, p3_addr);
86 pte_t entry; 90 pte_t entry;
87 unsigned long flags; 91 unsigned long flags;
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c
new file mode 100644
index 000000000000..92e745341e4d
--- /dev/null
+++ b/arch/sh/mm/pmb.c
@@ -0,0 +1,400 @@
1/*
2 * arch/sh/mm/pmb.c
3 *
4 * Privileged Space Mapping Buffer (PMB) Support.
5 *
6 * Copyright (C) 2005, 2006 Paul Mundt
7 *
8 * P1/P2 Section mapping definitions from map32.h, which was:
9 *
10 * Copyright 2003 (c) Lineo Solutions,Inc.
11 *
12 * This file is subject to the terms and conditions of the GNU General Public
13 * License. See the file "COPYING" in the main directory of this archive
14 * for more details.
15 */
16#include <linux/init.h>
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/slab.h>
20#include <linux/bitops.h>
21#include <linux/debugfs.h>
22#include <linux/fs.h>
23#include <linux/seq_file.h>
24#include <linux/err.h>
25#include <asm/system.h>
26#include <asm/uaccess.h>
27#include <asm/pgtable.h>
28#include <asm/mmu.h>
29#include <asm/io.h>
30
31#define NR_PMB_ENTRIES 16
32
33static kmem_cache_t *pmb_cache;
34static unsigned long pmb_map;
35
36static struct pmb_entry pmb_init_map[] = {
37 /* vpn ppn flags (ub/sz/c/wt) */
38
39 /* P1 Section Mappings */
40 { 0x80000000, 0x00000000, PMB_SZ_64M | PMB_C, },
41 { 0x84000000, 0x04000000, PMB_SZ_64M | PMB_C, },
42 { 0x88000000, 0x08000000, PMB_SZ_128M | PMB_C, },
43 { 0x90000000, 0x10000000, PMB_SZ_64M | PMB_C, },
44 { 0x94000000, 0x14000000, PMB_SZ_64M | PMB_C, },
45 { 0x98000000, 0x18000000, PMB_SZ_64M | PMB_C, },
46
47 /* P2 Section Mappings */
48 { 0xa0000000, 0x00000000, PMB_UB | PMB_SZ_64M | PMB_WT, },
49 { 0xa4000000, 0x04000000, PMB_UB | PMB_SZ_64M | PMB_WT, },
50 { 0xa8000000, 0x08000000, PMB_UB | PMB_SZ_128M | PMB_WT, },
51 { 0xb0000000, 0x10000000, PMB_UB | PMB_SZ_64M | PMB_WT, },
52 { 0xb4000000, 0x14000000, PMB_UB | PMB_SZ_64M | PMB_WT, },
53 { 0xb8000000, 0x18000000, PMB_UB | PMB_SZ_64M | PMB_WT, },
54};
55
56static inline unsigned long mk_pmb_entry(unsigned int entry)
57{
58 return (entry & PMB_E_MASK) << PMB_E_SHIFT;
59}
60
61static inline unsigned long mk_pmb_addr(unsigned int entry)
62{
63 return mk_pmb_entry(entry) | PMB_ADDR;
64}
65
66static inline unsigned long mk_pmb_data(unsigned int entry)
67{
68 return mk_pmb_entry(entry) | PMB_DATA;
69}
70
71struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn,
72 unsigned long flags)
73{
74 struct pmb_entry *pmbe;
75
76 pmbe = kmem_cache_alloc(pmb_cache, GFP_KERNEL);
77 if (!pmbe)
78 return ERR_PTR(-ENOMEM);
79
80 pmbe->vpn = vpn;
81 pmbe->ppn = ppn;
82 pmbe->flags = flags;
83
84 return pmbe;
85}
86
87void pmb_free(struct pmb_entry *pmbe)
88{
89 kmem_cache_free(pmb_cache, pmbe);
90}
91
92/*
93 * Must be in P2 for __set_pmb_entry()
94 */
95int __set_pmb_entry(unsigned long vpn, unsigned long ppn,
96 unsigned long flags, int *entry)
97{
98 unsigned int pos = *entry;
99
100 if (unlikely(pos == PMB_NO_ENTRY))
101 pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES);
102
103repeat:
104 if (unlikely(pos > NR_PMB_ENTRIES))
105 return -ENOSPC;
106
107 if (test_and_set_bit(pos, &pmb_map)) {
108 pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES);
109 goto repeat;
110 }
111
112 ctrl_outl(vpn | PMB_V, mk_pmb_addr(pos));
113
114#ifdef CONFIG_SH_WRITETHROUGH
115 /*
116 * When we are in 32-bit address extended mode, CCR.CB becomes
117 * invalid, so care must be taken to manually adjust cacheable
118 * translations.
119 */
120 if (likely(flags & PMB_C))
121 flags |= PMB_WT;
122#endif
123
124 ctrl_outl(ppn | flags | PMB_V, mk_pmb_data(pos));
125
126 *entry = pos;
127
128 return 0;
129}
130
131int set_pmb_entry(struct pmb_entry *pmbe)
132{
133 int ret;
134
135 jump_to_P2();
136 ret = __set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, &pmbe->entry);
137 back_to_P1();
138
139 return ret;
140}
141
142void clear_pmb_entry(struct pmb_entry *pmbe)
143{
144 unsigned int entry = pmbe->entry;
145 unsigned long addr;
146
147 /*
148 * Don't allow clearing of wired init entries, P1 or P2 access
149 * without a corresponding mapping in the PMB will lead to reset
150 * by the TLB.
151 */
152 if (unlikely(entry < ARRAY_SIZE(pmb_init_map) ||
153 entry >= NR_PMB_ENTRIES))
154 return;
155
156 jump_to_P2();
157
158 /* Clear V-bit */
159 addr = mk_pmb_addr(entry);
160 ctrl_outl(ctrl_inl(addr) & ~PMB_V, addr);
161
162 addr = mk_pmb_data(entry);
163 ctrl_outl(ctrl_inl(addr) & ~PMB_V, addr);
164
165 back_to_P1();
166
167 clear_bit(entry, &pmb_map);
168}
169
170static DEFINE_SPINLOCK(pmb_list_lock);
171static struct pmb_entry *pmb_list;
172
173static inline void pmb_list_add(struct pmb_entry *pmbe)
174{
175 struct pmb_entry **p, *tmp;
176
177 p = &pmb_list;
178 while ((tmp = *p) != NULL)
179 p = &tmp->next;
180
181 pmbe->next = tmp;
182 *p = pmbe;
183}
184
185static inline void pmb_list_del(struct pmb_entry *pmbe)
186{
187 struct pmb_entry **p, *tmp;
188
189 for (p = &pmb_list; (tmp = *p); p = &tmp->next)
190 if (tmp == pmbe) {
191 *p = tmp->next;
192 return;
193 }
194}
195
196static struct {
197 unsigned long size;
198 int flag;
199} pmb_sizes[] = {
200 { .size = 0x20000000, .flag = PMB_SZ_512M, },
201 { .size = 0x08000000, .flag = PMB_SZ_128M, },
202 { .size = 0x04000000, .flag = PMB_SZ_64M, },
203 { .size = 0x01000000, .flag = PMB_SZ_16M, },
204};
205
206long pmb_remap(unsigned long vaddr, unsigned long phys,
207 unsigned long size, unsigned long flags)
208{
209 struct pmb_entry *pmbp;
210 unsigned long wanted;
211 int pmb_flags, i;
212
213 /* Convert typical pgprot value to the PMB equivalent */
214 if (flags & _PAGE_CACHABLE) {
215 if (flags & _PAGE_WT)
216 pmb_flags = PMB_WT;
217 else
218 pmb_flags = PMB_C;
219 } else
220 pmb_flags = PMB_WT | PMB_UB;
221
222 pmbp = NULL;
223 wanted = size;
224
225again:
226 for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) {
227 struct pmb_entry *pmbe;
228 int ret;
229
230 if (size < pmb_sizes[i].size)
231 continue;
232
233 pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag);
234 if (IS_ERR(pmbe))
235 return PTR_ERR(pmbe);
236
237 ret = set_pmb_entry(pmbe);
238 if (ret != 0) {
239 pmb_free(pmbe);
240 return -EBUSY;
241 }
242
243 phys += pmb_sizes[i].size;
244 vaddr += pmb_sizes[i].size;
245 size -= pmb_sizes[i].size;
246
247 /*
248 * Link adjacent entries that span multiple PMB entries
249 * for easier tear-down.
250 */
251 if (likely(pmbp))
252 pmbp->link = pmbe;
253
254 pmbp = pmbe;
255 }
256
257 if (size >= 0x1000000)
258 goto again;
259
260 return wanted - size;
261}
262
263void pmb_unmap(unsigned long addr)
264{
265 struct pmb_entry **p, *pmbe;
266
267 for (p = &pmb_list; (pmbe = *p); p = &pmbe->next)
268 if (pmbe->vpn == addr)
269 break;
270
271 if (unlikely(!pmbe))
272 return;
273
274 WARN_ON(!test_bit(pmbe->entry, &pmb_map));
275
276 do {
277 struct pmb_entry *pmblink = pmbe;
278
279 clear_pmb_entry(pmbe);
280 pmbe = pmblink->link;
281
282 pmb_free(pmblink);
283 } while (pmbe);
284}
285
286static void pmb_cache_ctor(void *pmb, kmem_cache_t *cachep, unsigned long flags)
287{
288 struct pmb_entry *pmbe = pmb;
289
290 memset(pmb, 0, sizeof(struct pmb_entry));
291
292 spin_lock_irq(&pmb_list_lock);
293
294 pmbe->entry = PMB_NO_ENTRY;
295 pmb_list_add(pmbe);
296
297 spin_unlock_irq(&pmb_list_lock);
298}
299
300static void pmb_cache_dtor(void *pmb, kmem_cache_t *cachep, unsigned long flags)
301{
302 spin_lock_irq(&pmb_list_lock);
303 pmb_list_del(pmb);
304 spin_unlock_irq(&pmb_list_lock);
305}
306
307static int __init pmb_init(void)
308{
309 unsigned int nr_entries = ARRAY_SIZE(pmb_init_map);
310 unsigned int entry;
311
312 BUG_ON(unlikely(nr_entries >= NR_PMB_ENTRIES));
313
314 pmb_cache = kmem_cache_create("pmb", sizeof(struct pmb_entry),
315 0, 0, pmb_cache_ctor, pmb_cache_dtor);
316 BUG_ON(!pmb_cache);
317
318 jump_to_P2();
319
320 /*
321 * Ordering is important, P2 must be mapped in the PMB before we
322 * can set PMB.SE, and P1 must be mapped before we jump back to
323 * P1 space.
324 */
325 for (entry = 0; entry < nr_entries; entry++) {
326 struct pmb_entry *pmbe = pmb_init_map + entry;
327
328 __set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, &entry);
329 }
330
331 ctrl_outl(0, PMB_IRMCR);
332
333 /* PMB.SE and UB[7] */
334 ctrl_outl((1 << 31) | (1 << 7), PMB_PASCR);
335
336 back_to_P1();
337
338 return 0;
339}
340arch_initcall(pmb_init);
341
342static int pmb_seq_show(struct seq_file *file, void *iter)
343{
344 int i;
345
346 seq_printf(file, "V: Valid, C: Cacheable, WT: Write-Through\n"
347 "CB: Copy-Back, B: Buffered, UB: Unbuffered\n");
348 seq_printf(file, "ety vpn ppn size flags\n");
349
350 for (i = 0; i < NR_PMB_ENTRIES; i++) {
351 unsigned long addr, data;
352 unsigned int size;
353 char *sz_str = NULL;
354
355 addr = ctrl_inl(mk_pmb_addr(i));
356 data = ctrl_inl(mk_pmb_data(i));
357
358 size = data & PMB_SZ_MASK;
359 sz_str = (size == PMB_SZ_16M) ? " 16MB":
360 (size == PMB_SZ_64M) ? " 64MB":
361 (size == PMB_SZ_128M) ? "128MB":
362 "512MB";
363
364 /* 02: V 0x88 0x08 128MB C CB B */
365 seq_printf(file, "%02d: %c 0x%02lx 0x%02lx %s %c %s %s\n",
366 i, ((addr & PMB_V) && (data & PMB_V)) ? 'V' : ' ',
367 (addr >> 24) & 0xff, (data >> 24) & 0xff,
368 sz_str, (data & PMB_C) ? 'C' : ' ',
369 (data & PMB_WT) ? "WT" : "CB",
370 (data & PMB_UB) ? "UB" : " B");
371 }
372
373 return 0;
374}
375
376static int pmb_debugfs_open(struct inode *inode, struct file *file)
377{
378 return single_open(file, pmb_seq_show, NULL);
379}
380
381static struct file_operations pmb_debugfs_fops = {
382 .owner = THIS_MODULE,
383 .open = pmb_debugfs_open,
384 .read = seq_read,
385 .llseek = seq_lseek,
386 .release = seq_release,
387};
388
389static int __init pmb_debugfs_init(void)
390{
391 struct dentry *dentry;
392
393 dentry = debugfs_create_file("pmb", S_IFREG | S_IRUGO,
394 NULL, NULL, &pmb_debugfs_fops);
395 if (IS_ERR(dentry))
396 return PTR_ERR(dentry);
397
398 return 0;
399}
400postcore_initcall(pmb_debugfs_init);
diff --git a/arch/sh/mm/tlb-flush.c b/arch/sh/mm/tlb-flush.c
new file mode 100644
index 000000000000..73ec7f6084fa
--- /dev/null
+++ b/arch/sh/mm/tlb-flush.c
@@ -0,0 +1,134 @@
1/*
2 * TLB flushing operations for SH with an MMU.
3 *
4 * Copyright (C) 1999 Niibe Yutaka
5 * Copyright (C) 2003 Paul Mundt
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11#include <linux/mm.h>
12#include <asm/mmu_context.h>
13#include <asm/tlbflush.h>
14
15void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
16{
17 if (vma->vm_mm && vma->vm_mm->context.id != NO_CONTEXT) {
18 unsigned long flags;
19 unsigned long asid;
20 unsigned long saved_asid = MMU_NO_ASID;
21
22 asid = vma->vm_mm->context.id & MMU_CONTEXT_ASID_MASK;
23 page &= PAGE_MASK;
24
25 local_irq_save(flags);
26 if (vma->vm_mm != current->mm) {
27 saved_asid = get_asid();
28 set_asid(asid);
29 }
30 __flush_tlb_page(asid, page);
31 if (saved_asid != MMU_NO_ASID)
32 set_asid(saved_asid);
33 local_irq_restore(flags);
34 }
35}
36
37void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
38 unsigned long end)
39{
40 struct mm_struct *mm = vma->vm_mm;
41
42 if (mm->context.id != NO_CONTEXT) {
43 unsigned long flags;
44 int size;
45
46 local_irq_save(flags);
47 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
48 if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */
49 mm->context.id = NO_CONTEXT;
50 if (mm == current->mm)
51 activate_context(mm);
52 } else {
53 unsigned long asid;
54 unsigned long saved_asid = MMU_NO_ASID;
55
56 asid = mm->context.id & MMU_CONTEXT_ASID_MASK;
57 start &= PAGE_MASK;
58 end += (PAGE_SIZE - 1);
59 end &= PAGE_MASK;
60 if (mm != current->mm) {
61 saved_asid = get_asid();
62 set_asid(asid);
63 }
64 while (start < end) {
65 __flush_tlb_page(asid, start);
66 start += PAGE_SIZE;
67 }
68 if (saved_asid != MMU_NO_ASID)
69 set_asid(saved_asid);
70 }
71 local_irq_restore(flags);
72 }
73}
74
75void flush_tlb_kernel_range(unsigned long start, unsigned long end)
76{
77 unsigned long flags;
78 int size;
79
80 local_irq_save(flags);
81 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
82 if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */
83 flush_tlb_all();
84 } else {
85 unsigned long asid;
86 unsigned long saved_asid = get_asid();
87
88 asid = init_mm.context.id & MMU_CONTEXT_ASID_MASK;
89 start &= PAGE_MASK;
90 end += (PAGE_SIZE - 1);
91 end &= PAGE_MASK;
92 set_asid(asid);
93 while (start < end) {
94 __flush_tlb_page(asid, start);
95 start += PAGE_SIZE;
96 }
97 set_asid(saved_asid);
98 }
99 local_irq_restore(flags);
100}
101
102void flush_tlb_mm(struct mm_struct *mm)
103{
104 /* Invalidate all TLB of this process. */
105 /* Instead of invalidating each TLB, we get new MMU context. */
106 if (mm->context.id != NO_CONTEXT) {
107 unsigned long flags;
108
109 local_irq_save(flags);
110 mm->context.id = NO_CONTEXT;
111 if (mm == current->mm)
112 activate_context(mm);
113 local_irq_restore(flags);
114 }
115}
116
117void flush_tlb_all(void)
118{
119 unsigned long flags, status;
120
121 /*
122 * Flush all the TLB.
123 *
124 * Write to the MMU control register's bit:
125 * TF-bit for SH-3, TI-bit for SH-4.
126 * It's same position, bit #2.
127 */
128 local_irq_save(flags);
129 status = ctrl_inl(MMUCR);
130 status |= 0x04;
131 ctrl_outl(status, MMUCR);
132 ctrl_barrier();
133 local_irq_restore(flags);
134}
diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c
index 115b1b6be40b..812b2d567de2 100644
--- a/arch/sh/mm/tlb-sh4.c
+++ b/arch/sh/mm/tlb-sh4.c
@@ -36,7 +36,6 @@ void update_mmu_cache(struct vm_area_struct * vma,
36 unsigned long vpn; 36 unsigned long vpn;
37 struct page *page; 37 struct page *page;
38 unsigned long pfn; 38 unsigned long pfn;
39 unsigned long ptea;
40 39
41 /* Ptrace may call this routine. */ 40 /* Ptrace may call this routine. */
42 if (vma && current->active_mm != vma->vm_mm) 41 if (vma && current->active_mm != vma->vm_mm)
@@ -59,10 +58,11 @@ void update_mmu_cache(struct vm_area_struct * vma,
59 ctrl_outl(vpn, MMU_PTEH); 58 ctrl_outl(vpn, MMU_PTEH);
60 59
61 pteval = pte_val(pte); 60 pteval = pte_val(pte);
61
62 /* Set PTEA register */ 62 /* Set PTEA register */
63 /* TODO: make this look less hacky */ 63 if (cpu_data->flags & CPU_HAS_PTEA)
64 ptea = ((pteval >> 28) & 0xe) | (pteval & 0x1); 64 /* TODO: make this look less hacky */
65 ctrl_outl(ptea, MMU_PTEA); 65 ctrl_outl(((pteval >> 28) & 0xe) | (pteval & 0x1), MMU_PTEA);
66 66
67 /* Set PTEL register */ 67 /* Set PTEL register */
68 pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */ 68 pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
diff --git a/arch/sh/oprofile/Makefile b/arch/sh/oprofile/Makefile
index 686738d4aa3c..1f25d9bb7538 100644
--- a/arch/sh/oprofile/Makefile
+++ b/arch/sh/oprofile/Makefile
@@ -7,7 +7,11 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
7 timer_int.o ) 7 timer_int.o )
8 8
9profdrvr-y := op_model_null.o 9profdrvr-y := op_model_null.o
10
11# SH7750-style performance counters exist across 7750/7750S and 7091.
12profdrvr-$(CONFIG_CPU_SUBTYPE_SH7750S) := op_model_sh7750.o
10profdrvr-$(CONFIG_CPU_SUBTYPE_SH7750) := op_model_sh7750.o 13profdrvr-$(CONFIG_CPU_SUBTYPE_SH7750) := op_model_sh7750.o
14profdrvr-$(CONFIG_CPU_SUBTYPE_SH7091) := op_model_sh7750.o
11 15
12oprofile-y := $(DRIVER_OBJS) $(profdrvr-y) 16oprofile-y := $(DRIVER_OBJS) $(profdrvr-y)
13 17
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types
index 182fe9092577..ac57638977ee 100644
--- a/arch/sh/tools/mach-types
+++ b/arch/sh/tools/mach-types
@@ -8,16 +8,15 @@
8SE SH_SOLUTION_ENGINE 8SE SH_SOLUTION_ENGINE
97751SE SH_7751_SOLUTION_ENGINE 97751SE SH_7751_SOLUTION_ENGINE
107300SE SH_7300_SOLUTION_ENGINE 107300SE SH_7300_SOLUTION_ENGINE
117343SE SH_7343_SOLUTION_ENGINE
1173180SE SH_73180_SOLUTION_ENGINE 1273180SE SH_73180_SOLUTION_ENGINE
127751SYSTEMH SH_7751_SYSTEMH 137751SYSTEMH SH_7751_SYSTEMH
13HP6XX SH_HP6XX 14HP6XX SH_HP6XX
14HD64461 HD64461 15HD64461 HD64461
15HD64465 HD64465 16HD64465 HD64465
16SH2000 SH_SH2000
17SATURN SH_SATURN 17SATURN SH_SATURN
18DREAMCAST SH_DREAMCAST 18DREAMCAST SH_DREAMCAST
19BIGSUR SH_BIGSUR 19BIGSUR SH_BIGSUR
20ADX SH_ADX
21MPC1211 SH_MPC1211 20MPC1211 SH_MPC1211
22SNAPGEAR SH_SECUREEDGE5410 21SNAPGEAR SH_SECUREEDGE5410
23HS7751RVOIP SH_HS7751RVOIP 22HS7751RVOIP SH_HS7751RVOIP
@@ -25,4 +24,9 @@ RTS7751R2D SH_RTS7751R2D
25EDOSK7705 SH_EDOSK7705 24EDOSK7705 SH_EDOSK7705
26SH4202_MICRODEV SH_SH4202_MICRODEV 25SH4202_MICRODEV SH_SH4202_MICRODEV
27SH03 SH_SH03 26SH03 SH_SH03
28 27LANDISK SH_LANDISK
28R7780RP SH_R7780RP
29R7780MP SH_R7780MP
30TITAN SH_TITAN
31SHMIN SH_SHMIN
327710VOIPGW SH_7710VOIPGW
diff --git a/arch/sh64/mm/init.c b/arch/sh64/mm/init.c
index 1169757fb38b..83295bd21aa7 100644
--- a/arch/sh64/mm/init.c
+++ b/arch/sh64/mm/init.c
@@ -110,7 +110,7 @@ void show_mem(void)
110 */ 110 */
111void __init paging_init(void) 111void __init paging_init(void)
112{ 112{
113 unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; 113 unsigned long zones_size[MAX_NR_ZONES] = {0, };
114 114
115 pgd_init((unsigned long)swapper_pg_dir); 115 pgd_init((unsigned long)swapper_pg_dir);
116 pgd_init((unsigned long)swapper_pg_dir + 116 pgd_init((unsigned long)swapper_pg_dir +
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 16e13f663ab0..b27a506309ee 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -2175,7 +2175,7 @@ void __init ld_mmu_srmmu(void)
2175 2175
2176 BTFIXUPSET_CALL(pte_pfn, srmmu_pte_pfn, BTFIXUPCALL_NORM); 2176 BTFIXUPSET_CALL(pte_pfn, srmmu_pte_pfn, BTFIXUPCALL_NORM);
2177 BTFIXUPSET_CALL(pmd_page, srmmu_pmd_page, BTFIXUPCALL_NORM); 2177 BTFIXUPSET_CALL(pmd_page, srmmu_pmd_page, BTFIXUPCALL_NORM);
2178 BTFIXUPSET_CALL(pgd_page, srmmu_pgd_page, BTFIXUPCALL_NORM); 2178 BTFIXUPSET_CALL(pgd_page_vaddr, srmmu_pgd_page, BTFIXUPCALL_NORM);
2179 2179
2180 BTFIXUPSET_SETHI(none_mask, 0xF0000000); 2180 BTFIXUPSET_SETHI(none_mask, 0xF0000000);
2181 2181
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index 7fdddf3c7e16..436021ceb2e7 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -2280,5 +2280,5 @@ void __init ld_mmu_sun4c(void)
2280 2280
2281 /* These should _never_ get called with two level tables. */ 2281 /* These should _never_ get called with two level tables. */
2282 BTFIXUPSET_CALL(pgd_set, sun4c_pgd_set, BTFIXUPCALL_NOP); 2282 BTFIXUPSET_CALL(pgd_set, sun4c_pgd_set, BTFIXUPCALL_NOP);
2283 BTFIXUPSET_CALL(pgd_page, sun4c_pgd_page, BTFIXUPCALL_RETO0); 2283 BTFIXUPSET_CALL(pgd_page_vaddr, sun4c_pgd_page, BTFIXUPCALL_RETO0);
2284} 2284}
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 51cf6027b701..0fbdaa5daa8c 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.18 3# Linux kernel version: 2.6.18
4# Sat Sep 23 18:32:19 2006 4# Tue Sep 26 23:09:35 2006
5# 5#
6CONFIG_SPARC=y 6CONFIG_SPARC=y
7CONFIG_SPARC64=y 7CONFIG_SPARC64=y
@@ -141,6 +141,7 @@ CONFIG_SUN_AUXIO=y
141CONFIG_SUN_IO=y 141CONFIG_SUN_IO=y
142CONFIG_PCI=y 142CONFIG_PCI=y
143CONFIG_PCI_DOMAINS=y 143CONFIG_PCI_DOMAINS=y
144# CONFIG_PCI_MULTITHREAD_PROBE is not set
144# CONFIG_PCI_DEBUG is not set 145# CONFIG_PCI_DEBUG is not set
145CONFIG_SUN_OPENPROMFS=m 146CONFIG_SUN_OPENPROMFS=m
146CONFIG_SPARC32_COMPAT=y 147CONFIG_SPARC32_COMPAT=y
@@ -194,21 +195,9 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=y
194CONFIG_INET_XFRM_MODE_TUNNEL=y 195CONFIG_INET_XFRM_MODE_TUNNEL=y
195CONFIG_INET_DIAG=y 196CONFIG_INET_DIAG=y
196CONFIG_INET_TCP_DIAG=y 197CONFIG_INET_TCP_DIAG=y
197CONFIG_TCP_CONG_ADVANCED=y 198# CONFIG_TCP_CONG_ADVANCED is not set
198 199CONFIG_TCP_CONG_CUBIC=y
199# 200CONFIG_DEFAULT_TCP_CONG="cubic"
200# TCP congestion control
201#
202CONFIG_TCP_CONG_BIC=y
203CONFIG_TCP_CONG_CUBIC=m
204CONFIG_TCP_CONG_WESTWOOD=m
205CONFIG_TCP_CONG_HTCP=m
206CONFIG_TCP_CONG_HSTCP=m
207CONFIG_TCP_CONG_HYBLA=m
208CONFIG_TCP_CONG_VEGAS=m
209CONFIG_TCP_CONG_SCALABLE=m
210CONFIG_TCP_CONG_LP=m
211CONFIG_TCP_CONG_VENO=m
212CONFIG_IPV6=m 201CONFIG_IPV6=m
213CONFIG_IPV6_PRIVACY=y 202CONFIG_IPV6_PRIVACY=y
214CONFIG_IPV6_ROUTER_PREF=y 203CONFIG_IPV6_ROUTER_PREF=y
@@ -247,6 +236,7 @@ CONFIG_IP_DCCP_TFRC_LIB=m
247# DCCP Kernel Hacking 236# DCCP Kernel Hacking
248# 237#
249# CONFIG_IP_DCCP_DEBUG is not set 238# CONFIG_IP_DCCP_DEBUG is not set
239# CONFIG_NET_DCCPPROBE is not set
250 240
251# 241#
252# SCTP Configuration (EXPERIMENTAL) 242# SCTP Configuration (EXPERIMENTAL)
@@ -401,6 +391,7 @@ CONFIG_IDEDMA_AUTO=y
401# 391#
402CONFIG_RAID_ATTRS=m 392CONFIG_RAID_ATTRS=m
403CONFIG_SCSI=y 393CONFIG_SCSI=y
394CONFIG_SCSI_NETLINK=y
404CONFIG_SCSI_PROC_FS=y 395CONFIG_SCSI_PROC_FS=y
405 396
406# 397#
@@ -422,12 +413,13 @@ CONFIG_SCSI_CONSTANTS=y
422# CONFIG_SCSI_LOGGING is not set 413# CONFIG_SCSI_LOGGING is not set
423 414
424# 415#
425# SCSI Transport Attributes 416# SCSI Transports
426# 417#
427CONFIG_SCSI_SPI_ATTRS=y 418CONFIG_SCSI_SPI_ATTRS=y
428CONFIG_SCSI_FC_ATTRS=y 419CONFIG_SCSI_FC_ATTRS=y
429CONFIG_SCSI_ISCSI_ATTRS=m 420CONFIG_SCSI_ISCSI_ATTRS=m
430# CONFIG_SCSI_SAS_ATTRS is not set 421# CONFIG_SCSI_SAS_ATTRS is not set
422# CONFIG_SCSI_SAS_LIBSAS is not set
431 423
432# 424#
433# SCSI low-level drivers 425# SCSI low-level drivers
@@ -440,16 +432,18 @@ CONFIG_ISCSI_TCP=m
440# CONFIG_SCSI_AIC7XXX is not set 432# CONFIG_SCSI_AIC7XXX is not set
441# CONFIG_SCSI_AIC7XXX_OLD is not set 433# CONFIG_SCSI_AIC7XXX_OLD is not set
442# CONFIG_SCSI_AIC79XX is not set 434# CONFIG_SCSI_AIC79XX is not set
435# CONFIG_SCSI_AIC94XX is not set
436# CONFIG_SCSI_ARCMSR is not set
443# CONFIG_MEGARAID_NEWGEN is not set 437# CONFIG_MEGARAID_NEWGEN is not set
444# CONFIG_MEGARAID_LEGACY is not set 438# CONFIG_MEGARAID_LEGACY is not set
445# CONFIG_MEGARAID_SAS is not set 439# CONFIG_MEGARAID_SAS is not set
446# CONFIG_SCSI_SATA is not set
447# CONFIG_SCSI_HPTIOP is not set 440# CONFIG_SCSI_HPTIOP is not set
448# CONFIG_SCSI_DMX3191D is not set 441# CONFIG_SCSI_DMX3191D is not set
449# CONFIG_SCSI_FUTURE_DOMAIN is not set 442# CONFIG_SCSI_FUTURE_DOMAIN is not set
450# CONFIG_SCSI_IPS is not set 443# CONFIG_SCSI_IPS is not set
451# CONFIG_SCSI_INITIO is not set 444# CONFIG_SCSI_INITIO is not set
452# CONFIG_SCSI_INIA100 is not set 445# CONFIG_SCSI_INIA100 is not set
446# CONFIG_SCSI_STEX is not set
453# CONFIG_SCSI_SYM53C8XX_2 is not set 447# CONFIG_SCSI_SYM53C8XX_2 is not set
454# CONFIG_SCSI_IPR is not set 448# CONFIG_SCSI_IPR is not set
455# CONFIG_SCSI_QLOGIC_1280 is not set 449# CONFIG_SCSI_QLOGIC_1280 is not set
@@ -462,6 +456,11 @@ CONFIG_ISCSI_TCP=m
462# CONFIG_SCSI_SUNESP is not set 456# CONFIG_SCSI_SUNESP is not set
463 457
464# 458#
459# Serial ATA (prod) and Parallel ATA (experimental) drivers
460#
461# CONFIG_ATA is not set
462
463#
465# Multi-device support (RAID and LVM) 464# Multi-device support (RAID and LVM)
466# 465#
467CONFIG_MD=y 466CONFIG_MD=y
@@ -575,6 +574,7 @@ CONFIG_E1000_NAPI=y
575# CONFIG_VIA_VELOCITY is not set 574# CONFIG_VIA_VELOCITY is not set
576CONFIG_TIGON3=m 575CONFIG_TIGON3=m
577CONFIG_BNX2=m 576CONFIG_BNX2=m
577# CONFIG_QLA3XXX is not set
578 578
579# 579#
580# Ethernet (10000 Mbit) 580# Ethernet (10000 Mbit)
@@ -1006,6 +1006,7 @@ CONFIG_SND_ALI5451=m
1006# CONFIG_SND_VIA82XX_MODEM is not set 1006# CONFIG_SND_VIA82XX_MODEM is not set
1007# CONFIG_SND_VX222 is not set 1007# CONFIG_SND_VX222 is not set
1008# CONFIG_SND_YMFPCI is not set 1008# CONFIG_SND_YMFPCI is not set
1009# CONFIG_SND_AC97_POWER_SAVE is not set
1009 1010
1010# 1011#
1011# USB devices 1012# USB devices
@@ -1353,6 +1354,7 @@ CONFIG_KPROBES=y
1353# Kernel hacking 1354# Kernel hacking
1354# 1355#
1355CONFIG_PRINTK_TIME=y 1356CONFIG_PRINTK_TIME=y
1357CONFIG_ENABLE_MUST_CHECK=y
1356CONFIG_MAGIC_SYSRQ=y 1358CONFIG_MAGIC_SYSRQ=y
1357# CONFIG_UNUSED_SYMBOLS is not set 1359# CONFIG_UNUSED_SYMBOLS is not set
1358CONFIG_DEBUG_KERNEL=y 1360CONFIG_DEBUG_KERNEL=y
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index c88ae23ce812..69444f266e2d 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -1016,7 +1016,7 @@ struct __sysctl_args32 {
1016 1016
1017asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) 1017asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
1018{ 1018{
1019#ifndef CONFIG_SYSCTL 1019#ifndef CONFIG_SYSCTL_SYSCALL
1020 return -ENOSYS; 1020 return -ENOSYS;
1021#else 1021#else
1022 struct __sysctl_args32 tmp; 1022 struct __sysctl_args32 tmp;
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index dcba4e6ab570..09cb7fccc03a 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -920,8 +920,7 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail,
920 if (sparc_ramdisk_image || sparc_ramdisk_image64) { 920 if (sparc_ramdisk_image || sparc_ramdisk_image64) {
921 unsigned long ramdisk_image = sparc_ramdisk_image ? 921 unsigned long ramdisk_image = sparc_ramdisk_image ?
922 sparc_ramdisk_image : sparc_ramdisk_image64; 922 sparc_ramdisk_image : sparc_ramdisk_image64;
923 if (ramdisk_image >= (unsigned long)_end - 2 * PAGE_SIZE) 923 ramdisk_image -= KERNBASE;
924 ramdisk_image -= KERNBASE;
925 initrd_start = ramdisk_image + phys_base; 924 initrd_start = ramdisk_image + phys_base;
926 initrd_end = initrd_start + sparc_ramdisk_size; 925 initrd_end = initrd_start + sparc_ramdisk_size;
927 if (initrd_end > end_of_phys_memory) { 926 if (initrd_end > end_of_phys_memory) {
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
index 8135ec322c9c..642541769a17 100644
--- a/arch/sparc64/solaris/misc.c
+++ b/arch/sparc64/solaris/misc.c
@@ -736,20 +736,15 @@ struct exec_domain solaris_exec_domain = {
736 736
737extern int init_socksys(void); 737extern int init_socksys(void);
738 738
739#ifdef MODULE
740
741MODULE_AUTHOR("Jakub Jelinek (jj@ultra.linux.cz), Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)"); 739MODULE_AUTHOR("Jakub Jelinek (jj@ultra.linux.cz), Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)");
742MODULE_DESCRIPTION("Solaris binary emulation module"); 740MODULE_DESCRIPTION("Solaris binary emulation module");
743MODULE_LICENSE("GPL"); 741MODULE_LICENSE("GPL");
744 742
745#ifdef __sparc_v9__
746extern u32 tl0_solaris[8]; 743extern u32 tl0_solaris[8];
747#define update_ttable(x) \ 744#define update_ttable(x) \
748 tl0_solaris[3] = (((long)(x) - (long)tl0_solaris - 3) >> 2) | 0x40000000; \ 745 tl0_solaris[3] = (((long)(x) - (long)tl0_solaris - 3) >> 2) | 0x40000000; \
749 wmb(); \ 746 wmb(); \
750 __asm__ __volatile__ ("flush %0" : : "r" (&tl0_solaris[3])) 747 __asm__ __volatile__ ("flush %0" : : "r" (&tl0_solaris[3]))
751#else
752#endif
753 748
754extern u32 solaris_sparc_syscall[]; 749extern u32 solaris_sparc_syscall[];
755extern u32 solaris_syscall[]; 750extern u32 solaris_syscall[];
@@ -757,7 +752,7 @@ extern void cleanup_socksys(void);
757 752
758extern u32 entry64_personality_patch; 753extern u32 entry64_personality_patch;
759 754
760int init_module(void) 755static int __init solaris_init(void)
761{ 756{
762 int ret; 757 int ret;
763 758
@@ -777,19 +772,12 @@ int init_module(void)
777 return 0; 772 return 0;
778} 773}
779 774
780void cleanup_module(void) 775static void __exit solaris_exit(void)
781{ 776{
782 update_ttable(solaris_syscall); 777 update_ttable(solaris_syscall);
783 cleanup_socksys(); 778 cleanup_socksys();
784 unregister_exec_domain(&solaris_exec_domain); 779 unregister_exec_domain(&solaris_exec_domain);
785} 780}
786 781
787#else 782module_init(solaris_init);
788int init_solaris_emul(void) 783module_exit(solaris_exit);
789{
790 register_exec_domain(&solaris_exec_domain);
791 init_socksys();
792 return 0;
793}
794#endif
795
diff --git a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c
index bc3df95bc057..7c90e41fd3be 100644
--- a/arch/sparc64/solaris/socksys.c
+++ b/arch/sparc64/solaris/socksys.c
@@ -168,8 +168,7 @@ static struct file_operations socksys_fops = {
168 .release = socksys_release, 168 .release = socksys_release,
169}; 169};
170 170
171int __init 171int __init init_socksys(void)
172init_socksys(void)
173{ 172{
174 int ret; 173 int ret;
175 struct file * file; 174 struct file * file;
@@ -199,8 +198,7 @@ init_socksys(void)
199 return 0; 198 return 0;
200} 199}
201 200
202void 201void __exit cleanup_socksys(void)
203cleanup_socksys(void)
204{ 202{
205 if (unregister_chrdev(30, "socksys")) 203 if (unregister_chrdev(30, "socksys"))
206 printk ("Couldn't unregister socksys character device\n"); 204 printk ("Couldn't unregister socksys character device\n");
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index 9558a7cf34d5..11154b6773ec 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -4,10 +4,13 @@
4core-y += arch/um/sys-x86_64/ 4core-y += arch/um/sys-x86_64/
5START := 0x60000000 5START := 0x60000000
6 6
7_extra_flags_ = -fno-builtin -m64 -mcmodel=kernel
8
7#We #undef __x86_64__ for kernelspace, not for userspace where 9#We #undef __x86_64__ for kernelspace, not for userspace where
8#it's needed for headers to work! 10#it's needed for headers to work!
9CFLAGS += -U__$(SUBARCH)__ -fno-builtin -m64 11CFLAGS += -U__$(SUBARCH)__ $(_extra_flags_)
10USER_CFLAGS += -fno-builtin -m64 12USER_CFLAGS += $(_extra_flags_)
13
11CHECKFLAGS += -m64 14CHECKFLAGS += -m64
12AFLAGS += -m64 15AFLAGS += -m64
13LDFLAGS += -m elf_x86_64 16LDFLAGS += -m elf_x86_64
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 7218c754505b..3576b3cc505e 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -110,7 +110,7 @@ static void not_configged_free(void *data)
110 "UML\n"); 110 "UML\n");
111} 111}
112 112
113static struct chan_ops not_configged_ops = { 113static const struct chan_ops not_configged_ops = {
114 .init = not_configged_init, 114 .init = not_configged_init,
115 .open = not_configged_open, 115 .open = not_configged_open,
116 .close = not_configged_close, 116 .close = not_configged_close,
@@ -373,7 +373,7 @@ int console_write_chan(struct list_head *chans, const char *buf, int len)
373} 373}
374 374
375int console_open_chan(struct line *line, struct console *co, 375int console_open_chan(struct line *line, struct console *co,
376 struct chan_opts *opts) 376 const struct chan_opts *opts)
377{ 377{
378 int err; 378 int err;
379 379
@@ -494,10 +494,10 @@ int chan_config_string(struct list_head *chans, char *str, int size,
494 494
495struct chan_type { 495struct chan_type {
496 char *key; 496 char *key;
497 struct chan_ops *ops; 497 const struct chan_ops *ops;
498}; 498};
499 499
500static struct chan_type chan_table[] = { 500static const struct chan_type chan_table[] = {
501 { "fd", &fd_ops }, 501 { "fd", &fd_ops },
502 502
503#ifdef CONFIG_NULL_CHAN 503#ifdef CONFIG_NULL_CHAN
@@ -534,17 +534,17 @@ static struct chan_type chan_table[] = {
534}; 534};
535 535
536static struct chan *parse_chan(struct line *line, char *str, int device, 536static struct chan *parse_chan(struct line *line, char *str, int device,
537 struct chan_opts *opts) 537 const struct chan_opts *opts)
538{ 538{
539 struct chan_type *entry; 539 const struct chan_type *entry;
540 struct chan_ops *ops; 540 const struct chan_ops *ops;
541 struct chan *chan; 541 struct chan *chan;
542 void *data; 542 void *data;
543 int i; 543 int i;
544 544
545 ops = NULL; 545 ops = NULL;
546 data = NULL; 546 data = NULL;
547 for(i = 0; i < sizeof(chan_table)/sizeof(chan_table[0]); i++){ 547 for(i = 0; i < ARRAY_SIZE(chan_table); i++){
548 entry = &chan_table[i]; 548 entry = &chan_table[i];
549 if(!strncmp(str, entry->key, strlen(entry->key))){ 549 if(!strncmp(str, entry->key, strlen(entry->key))){
550 ops = entry->ops; 550 ops = entry->ops;
@@ -582,7 +582,7 @@ static struct chan *parse_chan(struct line *line, char *str, int device,
582} 582}
583 583
584int parse_chan_pair(char *str, struct line *line, int device, 584int parse_chan_pair(char *str, struct line *line, int device,
585 struct chan_opts *opts) 585 const struct chan_opts *opts)
586{ 586{
587 struct list_head *chans = &line->chan_list; 587 struct list_head *chans = &line->chan_list;
588 struct chan *new, *chan; 588 struct chan *new, *chan;
diff --git a/arch/um/drivers/daemon.h b/arch/um/drivers/daemon.h
index 7326c42f7ef9..3bc3cf6b94aa 100644
--- a/arch/um/drivers/daemon.h
+++ b/arch/um/drivers/daemon.h
@@ -18,7 +18,7 @@ struct daemon_data {
18 void *dev; 18 void *dev;
19}; 19};
20 20
21extern struct net_user_info daemon_user_info; 21extern const struct net_user_info daemon_user_info;
22 22
23extern int daemon_user_write(int fd, void *buf, int len, 23extern int daemon_user_write(int fd, void *buf, int len,
24 struct daemon_data *pri); 24 struct daemon_data *pri);
diff --git a/arch/um/drivers/daemon_kern.c b/arch/um/drivers/daemon_kern.c
index 53d09ed78b42..824386974f88 100644
--- a/arch/um/drivers/daemon_kern.c
+++ b/arch/um/drivers/daemon_kern.c
@@ -57,7 +57,7 @@ static int daemon_write(int fd, struct sk_buff **skb,
57 (struct daemon_data *) &lp->user)); 57 (struct daemon_data *) &lp->user));
58} 58}
59 59
60static struct net_kern_info daemon_kern_info = { 60static const struct net_kern_info daemon_kern_info = {
61 .init = daemon_init, 61 .init = daemon_init,
62 .protocol = eth_protocol, 62 .protocol = eth_protocol,
63 .read = daemon_read, 63 .read = daemon_read,
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index c944265955e2..77954ea77043 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -182,7 +182,7 @@ static int daemon_set_mtu(int mtu, void *data)
182 return(mtu); 182 return(mtu);
183} 183}
184 184
185struct net_user_info daemon_user_info = { 185const struct net_user_info daemon_user_info = {
186 .init = daemon_user_init, 186 .init = daemon_user_init,
187 .open = daemon_open, 187 .open = daemon_open,
188 .close = NULL, 188 .close = NULL,
diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
index c41f75e4acb5..108b7dafbd0e 100644
--- a/arch/um/drivers/fd.c
+++ b/arch/um/drivers/fd.c
@@ -20,7 +20,7 @@ struct fd_chan {
20 char str[sizeof("1234567890\0")]; 20 char str[sizeof("1234567890\0")];
21}; 21};
22 22
23static void *fd_init(char *str, int device, struct chan_opts *opts) 23static void *fd_init(char *str, int device, const struct chan_opts *opts)
24{ 24{
25 struct fd_chan *data; 25 struct fd_chan *data;
26 char *end; 26 char *end;
@@ -77,7 +77,7 @@ static void fd_close(int fd, void *d)
77 } 77 }
78} 78}
79 79
80struct chan_ops fd_ops = { 80const struct chan_ops fd_ops = {
81 .type = "fd", 81 .type = "fd",
82 .init = fd_init, 82 .init = fd_init,
83 .open = fd_open, 83 .open = fd_open,
diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
index 37232f908cd7..d247ef45c374 100644
--- a/arch/um/drivers/hostaudio_kern.c
+++ b/arch/um/drivers/hostaudio_kern.c
@@ -280,7 +280,7 @@ static int hostmixer_release(struct inode *inode, struct file *file)
280 280
281/* kernel module operations */ 281/* kernel module operations */
282 282
283static struct file_operations hostaudio_fops = { 283static const struct file_operations hostaudio_fops = {
284 .owner = THIS_MODULE, 284 .owner = THIS_MODULE,
285 .llseek = no_llseek, 285 .llseek = no_llseek,
286 .read = hostaudio_read, 286 .read = hostaudio_read,
@@ -292,7 +292,7 @@ static struct file_operations hostaudio_fops = {
292 .release = hostaudio_release, 292 .release = hostaudio_release,
293}; 293};
294 294
295static struct file_operations hostmixer_fops = { 295static const struct file_operations hostmixer_fops = {
296 .owner = THIS_MODULE, 296 .owner = THIS_MODULE,
297 .llseek = no_llseek, 297 .llseek = no_llseek,
298 .ioctl = hostmixer_ioctl_mixdev, 298 .ioctl = hostmixer_ioctl_mixdev,
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index ebebaabb78ad..563ce7690a1e 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -251,7 +251,7 @@ void line_set_termios(struct tty_struct *tty, struct termios * old)
251 /* nothing */ 251 /* nothing */
252} 252}
253 253
254static struct { 254static const struct {
255 int cmd; 255 int cmd;
256 char *level; 256 char *level;
257 char *name; 257 char *name;
@@ -405,7 +405,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data,
405 405
406int line_setup_irq(int fd, int input, int output, struct line *line, void *data) 406int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
407{ 407{
408 struct line_driver *driver = line->driver; 408 const struct line_driver *driver = line->driver;
409 int err = 0, flags = IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM; 409 int err = 0, flags = IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM;
410 410
411 if (input) 411 if (input)
@@ -558,7 +558,7 @@ int line_setup(struct line *lines, unsigned int num, char *init)
558} 558}
559 559
560int line_config(struct line *lines, unsigned int num, char *str, 560int line_config(struct line *lines, unsigned int num, char *str,
561 struct chan_opts *opts) 561 const struct chan_opts *opts)
562{ 562{
563 struct line *line; 563 struct line *line;
564 char *new; 564 char *new;
diff --git a/arch/um/drivers/mcast.h b/arch/um/drivers/mcast.h
index a2c6db243458..bc56af9d3e53 100644
--- a/arch/um/drivers/mcast.h
+++ b/arch/um/drivers/mcast.h
@@ -13,7 +13,7 @@ struct mcast_data {
13 void *dev; 13 void *dev;
14}; 14};
15 15
16extern struct net_user_info mcast_user_info; 16extern const struct net_user_info mcast_user_info;
17 17
18extern int mcast_user_write(int fd, void *buf, int len, 18extern int mcast_user_write(int fd, void *buf, int len,
19 struct mcast_data *pri); 19 struct mcast_data *pri);
diff --git a/arch/um/drivers/mcast_kern.c b/arch/um/drivers/mcast_kern.c
index 3a7af18cf944..c090fbd464e7 100644
--- a/arch/um/drivers/mcast_kern.c
+++ b/arch/um/drivers/mcast_kern.c
@@ -61,7 +61,7 @@ static int mcast_write(int fd, struct sk_buff **skb,
61 (struct mcast_data *) &lp->user); 61 (struct mcast_data *) &lp->user);
62} 62}
63 63
64static struct net_kern_info mcast_kern_info = { 64static const struct net_kern_info mcast_kern_info = {
65 .init = mcast_init, 65 .init = mcast_init,
66 .protocol = eth_protocol, 66 .protocol = eth_protocol,
67 .read = mcast_read, 67 .read = mcast_read,
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
index afe85bfa66e0..4d2bd39a85bc 100644
--- a/arch/um/drivers/mcast_user.c
+++ b/arch/um/drivers/mcast_user.c
@@ -152,7 +152,7 @@ static int mcast_set_mtu(int mtu, void *data)
152 return(mtu); 152 return(mtu);
153} 153}
154 154
155struct net_user_info mcast_user_info = { 155const struct net_user_info mcast_user_info = {
156 .init = mcast_user_init, 156 .init = mcast_user_init,
157 .open = mcast_open, 157 .open = mcast_open,
158 .close = mcast_close, 158 .close = mcast_close,
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index b414522f7686..79610b5ce67e 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -497,7 +497,7 @@ static void mconsole_get_config(int (*get_config)(char *, char *, int,
497 } 497 }
498 498
499 error = NULL; 499 error = NULL;
500 size = sizeof(default_buf)/sizeof(default_buf[0]); 500 size = ARRAY_SIZE(default_buf);
501 buf = default_buf; 501 buf = default_buf;
502 502
503 while(1){ 503 while(1){
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
index 9bfd405c3bd8..5b2f5fe9e426 100644
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -16,6 +16,7 @@
16#include "user.h" 16#include "user.h"
17#include "mconsole.h" 17#include "mconsole.h"
18#include "umid.h" 18#include "umid.h"
19#include "user_util.h"
19 20
20static struct mconsole_command commands[] = { 21static struct mconsole_command commands[] = {
21 /* With uts namespaces, uts information becomes process-specific, so 22 /* With uts namespaces, uts information becomes process-specific, so
@@ -65,14 +66,14 @@ static struct mconsole_command *mconsole_parse(struct mc_request *req)
65 struct mconsole_command *cmd; 66 struct mconsole_command *cmd;
66 int i; 67 int i;
67 68
68 for(i=0;i<sizeof(commands)/sizeof(commands[0]);i++){ 69 for(i = 0; i < ARRAY_SIZE(commands); i++){
69 cmd = &commands[i]; 70 cmd = &commands[i];
70 if(!strncmp(req->request.data, cmd->command, 71 if(!strncmp(req->request.data, cmd->command,
71 strlen(cmd->command))){ 72 strlen(cmd->command))){
72 return(cmd); 73 return cmd;
73 } 74 }
74 } 75 }
75 return(NULL); 76 return NULL;
76} 77}
77 78
78#define MIN(a,b) ((a)<(b) ? (a):(b)) 79#define MIN(a,b) ((a)<(b) ? (a):(b))
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index 022f67bb6873..9a3b5daf6250 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -85,7 +85,7 @@ mmapper_release(struct inode *inode, struct file *file)
85 return 0; 85 return 0;
86} 86}
87 87
88static struct file_operations mmapper_fops = { 88static const struct file_operations mmapper_fops = {
89 .owner = THIS_MODULE, 89 .owner = THIS_MODULE,
90 .read = mmapper_read, 90 .read = mmapper_read,
91 .write = mmapper_write, 91 .write = mmapper_write,
@@ -95,7 +95,7 @@ static struct file_operations mmapper_fops = {
95 .release = mmapper_release, 95 .release = mmapper_release,
96}; 96};
97 97
98static struct miscdevice mmapper_dev = { 98static const struct miscdevice mmapper_dev = {
99 .minor = MISC_DYNAMIC_MINOR, 99 .minor = MISC_DYNAMIC_MINOR,
100 .name = "mmapper", 100 .name = "mmapper",
101 .fops = &mmapper_fops 101 .fops = &mmapper_fops
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 501f95675d89..664c2e2fb820 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -31,6 +31,11 @@
31#include "irq_user.h" 31#include "irq_user.h"
32#include "irq_kern.h" 32#include "irq_kern.h"
33 33
34static inline void set_ether_mac(struct net_device *dev, unsigned char *addr)
35{
36 memcpy(dev->dev_addr, addr, ETH_ALEN);
37}
38
34#define DRIVER_NAME "uml-netdev" 39#define DRIVER_NAME "uml-netdev"
35 40
36static DEFINE_SPINLOCK(opened_lock); 41static DEFINE_SPINLOCK(opened_lock);
@@ -109,8 +114,6 @@ static int uml_net_open(struct net_device *dev)
109 struct uml_net_private *lp = dev->priv; 114 struct uml_net_private *lp = dev->priv;
110 int err; 115 int err;
111 116
112 spin_lock(&lp->lock);
113
114 if(lp->fd >= 0){ 117 if(lp->fd >= 0){
115 err = -ENXIO; 118 err = -ENXIO;
116 goto out; 119 goto out;
@@ -144,8 +147,6 @@ static int uml_net_open(struct net_device *dev)
144 */ 147 */
145 while((err = uml_net_rx(dev)) > 0) ; 148 while((err = uml_net_rx(dev)) > 0) ;
146 149
147 spin_unlock(&lp->lock);
148
149 spin_lock(&opened_lock); 150 spin_lock(&opened_lock);
150 list_add(&lp->list, &opened); 151 list_add(&lp->list, &opened);
151 spin_unlock(&opened_lock); 152 spin_unlock(&opened_lock);
@@ -155,7 +156,6 @@ out_close:
155 if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user); 156 if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
156 lp->fd = -1; 157 lp->fd = -1;
157out: 158out:
158 spin_unlock(&lp->lock);
159 return err; 159 return err;
160} 160}
161 161
@@ -164,15 +164,12 @@ static int uml_net_close(struct net_device *dev)
164 struct uml_net_private *lp = dev->priv; 164 struct uml_net_private *lp = dev->priv;
165 165
166 netif_stop_queue(dev); 166 netif_stop_queue(dev);
167 spin_lock(&lp->lock);
168 167
169 free_irq(dev->irq, dev); 168 free_irq(dev->irq, dev);
170 if(lp->close != NULL) 169 if(lp->close != NULL)
171 (*lp->close)(lp->fd, &lp->user); 170 (*lp->close)(lp->fd, &lp->user);
172 lp->fd = -1; 171 lp->fd = -1;
173 172
174 spin_unlock(&lp->lock);
175
176 spin_lock(&opened_lock); 173 spin_lock(&opened_lock);
177 list_del(&lp->list); 174 list_del(&lp->list);
178 spin_unlock(&opened_lock); 175 spin_unlock(&opened_lock);
@@ -241,9 +238,9 @@ static int uml_net_set_mac(struct net_device *dev, void *addr)
241 struct uml_net_private *lp = dev->priv; 238 struct uml_net_private *lp = dev->priv;
242 struct sockaddr *hwaddr = addr; 239 struct sockaddr *hwaddr = addr;
243 240
244 spin_lock(&lp->lock); 241 spin_lock_irq(&lp->lock);
245 memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN); 242 set_ether_mac(dev, hwaddr->sa_data);
246 spin_unlock(&lp->lock); 243 spin_unlock_irq(&lp->lock);
247 244
248 return(0); 245 return(0);
249} 246}
@@ -253,7 +250,7 @@ static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
253 struct uml_net_private *lp = dev->priv; 250 struct uml_net_private *lp = dev->priv;
254 int err = 0; 251 int err = 0;
255 252
256 spin_lock(&lp->lock); 253 spin_lock_irq(&lp->lock);
257 254
258 new_mtu = (*lp->set_mtu)(new_mtu, &lp->user); 255 new_mtu = (*lp->set_mtu)(new_mtu, &lp->user);
259 if(new_mtu < 0){ 256 if(new_mtu < 0){
@@ -264,7 +261,7 @@ static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
264 dev->mtu = new_mtu; 261 dev->mtu = new_mtu;
265 262
266 out: 263 out:
267 spin_unlock(&lp->lock); 264 spin_unlock_irq(&lp->lock);
268 return err; 265 return err;
269} 266}
270 267
@@ -564,12 +561,13 @@ static int eth_setup(char *str)
564 int n, err; 561 int n, err;
565 562
566 err = eth_parse(str, &n, &str); 563 err = eth_parse(str, &n, &str);
567 if(err) return(1); 564 if(err)
565 return 1;
568 566
569 new = alloc_bootmem(sizeof(new)); 567 new = alloc_bootmem(sizeof(*new));
570 if (new == NULL){ 568 if (new == NULL){
571 printk("eth_init : alloc_bootmem failed\n"); 569 printk("eth_init : alloc_bootmem failed\n");
572 return(1); 570 return 1;
573 } 571 }
574 572
575 INIT_LIST_HEAD(&new->list); 573 INIT_LIST_HEAD(&new->list);
@@ -577,7 +575,7 @@ static int eth_setup(char *str)
577 new->init = str; 575 new->init = str;
578 576
579 list_add_tail(&new->list, &eth_cmd_line); 577 list_add_tail(&new->list, &eth_cmd_line);
580 return(1); 578 return 1;
581} 579}
582 580
583__setup("eth", eth_setup); 581__setup("eth", eth_setup);
@@ -790,13 +788,6 @@ void dev_ip_addr(void *d, unsigned char *bin_buf)
790 memcpy(bin_buf, &in->ifa_address, sizeof(in->ifa_address)); 788 memcpy(bin_buf, &in->ifa_address, sizeof(in->ifa_address));
791} 789}
792 790
793void set_ether_mac(void *d, unsigned char *addr)
794{
795 struct net_device *dev = d;
796
797 memcpy(dev->dev_addr, addr, ETH_ALEN);
798}
799
800struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra) 791struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
801{ 792{
802 if((skb != NULL) && (skb_tailroom(skb) < extra)){ 793 if((skb != NULL) && (skb_tailroom(skb) < extra)){
diff --git a/arch/um/drivers/null.c b/arch/um/drivers/null.c
index 14cc5f78398a..3683ed44315d 100644
--- a/arch/um/drivers/null.c
+++ b/arch/um/drivers/null.c
@@ -10,7 +10,7 @@
10 10
11static int null_chan; 11static int null_chan;
12 12
13static void *null_init(char *str, int device, struct chan_opts *opts) 13static void *null_init(char *str, int device, const struct chan_opts *opts)
14{ 14{
15 return(&null_chan); 15 return(&null_chan);
16} 16}
@@ -31,7 +31,7 @@ static void null_free(void *data)
31{ 31{
32} 32}
33 33
34struct chan_ops null_ops = { 34const struct chan_ops null_ops = {
35 .type = "null", 35 .type = "null",
36 .init = null_init, 36 .init = null_init,
37 .open = null_open, 37 .open = null_open,
diff --git a/arch/um/drivers/pcap_kern.c b/arch/um/drivers/pcap_kern.c
index 466ff2c2f918..6e1ef8558283 100644
--- a/arch/um/drivers/pcap_kern.c
+++ b/arch/um/drivers/pcap_kern.c
@@ -46,7 +46,7 @@ static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
46 return(-EPERM); 46 return(-EPERM);
47} 47}
48 48
49static struct net_kern_info pcap_kern_info = { 49static const struct net_kern_info pcap_kern_info = {
50 .init = pcap_init, 50 .init = pcap_init,
51 .protocol = eth_protocol, 51 .protocol = eth_protocol,
52 .read = pcap_read, 52 .read = pcap_read,
@@ -76,7 +76,7 @@ int pcap_setup(char *str, char **mac_out, void *data)
76 if(host_if != NULL) 76 if(host_if != NULL)
77 init->host_if = host_if; 77 init->host_if = host_if;
78 78
79 for(i = 0; i < sizeof(options)/sizeof(options[0]); i++){ 79 for(i = 0; i < ARRAY_SIZE(options); i++){
80 if(options[i] == NULL) 80 if(options[i] == NULL)
81 continue; 81 continue;
82 if(!strcmp(options[i], "promisc")) 82 if(!strcmp(options[i], "promisc"))
diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c
index edfcb29273e1..2ef641ded960 100644
--- a/arch/um/drivers/pcap_user.c
+++ b/arch/um/drivers/pcap_user.c
@@ -120,7 +120,7 @@ int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
120 return(hdata.len); 120 return(hdata.len);
121} 121}
122 122
123struct net_user_info pcap_user_info = { 123const struct net_user_info pcap_user_info = {
124 .init = pcap_user_init, 124 .init = pcap_user_init,
125 .open = pcap_open, 125 .open = pcap_open,
126 .close = NULL, 126 .close = NULL,
diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
index c43e8bb32502..f2e8fc42ecc2 100644
--- a/arch/um/drivers/port_user.c
+++ b/arch/um/drivers/port_user.c
@@ -27,7 +27,7 @@ struct port_chan {
27 char dev[sizeof("32768\0")]; 27 char dev[sizeof("32768\0")];
28}; 28};
29 29
30static void *port_init(char *str, int device, struct chan_opts *opts) 30static void *port_init(char *str, int device, const struct chan_opts *opts)
31{ 31{
32 struct port_chan *data; 32 struct port_chan *data;
33 void *kern_data; 33 void *kern_data;
@@ -100,7 +100,7 @@ static void port_close(int fd, void *d)
100 os_close_file(fd); 100 os_close_file(fd);
101} 101}
102 102
103struct chan_ops port_ops = { 103const struct chan_ops port_ops = {
104 .type = "port", 104 .type = "port",
105 .init = port_init, 105 .init = port_init,
106 .open = port_open, 106 .open = port_open,
diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
index 1c555c38de4d..abec620e8380 100644
--- a/arch/um/drivers/pty.c
+++ b/arch/um/drivers/pty.c
@@ -22,7 +22,7 @@ struct pty_chan {
22 char dev_name[sizeof("/dev/pts/0123456\0")]; 22 char dev_name[sizeof("/dev/pts/0123456\0")];
23}; 23};
24 24
25static void *pty_chan_init(char *str, int device, struct chan_opts *opts) 25static void *pty_chan_init(char *str, int device, const struct chan_opts *opts)
26{ 26{
27 struct pty_chan *data; 27 struct pty_chan *data;
28 28
@@ -118,7 +118,7 @@ static int pty_open(int input, int output, int primary, void *d,
118 return(fd); 118 return(fd);
119} 119}
120 120
121struct chan_ops pty_ops = { 121const struct chan_ops pty_ops = {
122 .type = "pty", 122 .type = "pty",
123 .init = pty_chan_init, 123 .init = pty_chan_init,
124 .open = pty_open, 124 .open = pty_open,
@@ -131,7 +131,7 @@ struct chan_ops pty_ops = {
131 .winch = 0, 131 .winch = 0,
132}; 132};
133 133
134struct chan_ops pts_ops = { 134const struct chan_ops pts_ops = {
135 .type = "pts", 135 .type = "pts",
136 .init = pty_chan_init, 136 .init = pty_chan_init,
137 .open = pts_open, 137 .open = pts_open,
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index ba471f5864a6..ae9909415b9c 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -68,7 +68,7 @@ static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size,
68 return ret; 68 return ret;
69} 69}
70 70
71static struct file_operations rng_chrdev_ops = { 71static const struct file_operations rng_chrdev_ops = {
72 .owner = THIS_MODULE, 72 .owner = THIS_MODULE,
73 .open = rng_dev_open, 73 .open = rng_dev_open,
74 .read = rng_dev_read, 74 .read = rng_dev_read,
diff --git a/arch/um/drivers/slip.h b/arch/um/drivers/slip.h
index bb0dab41c2e4..c64f8c61d274 100644
--- a/arch/um/drivers/slip.h
+++ b/arch/um/drivers/slip.h
@@ -12,7 +12,7 @@ struct slip_data {
12 struct slip_proto slip; 12 struct slip_proto slip;
13}; 13};
14 14
15extern struct net_user_info slip_user_info; 15extern const struct net_user_info slip_user_info;
16 16
17extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri); 17extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri);
18extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri); 18extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri);
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c
index 163ee0d5f75e..ccea2d7885e5 100644
--- a/arch/um/drivers/slip_kern.c
+++ b/arch/um/drivers/slip_kern.c
@@ -61,7 +61,7 @@ static int slip_write(int fd, struct sk_buff **skb,
61 (struct slip_data *) &lp->user)); 61 (struct slip_data *) &lp->user));
62} 62}
63 63
64struct net_kern_info slip_kern_info = { 64const struct net_kern_info slip_kern_info = {
65 .init = slip_init, 65 .init = slip_init,
66 .protocol = slip_protocol, 66 .protocol = slip_protocol,
67 .read = slip_read, 67 .read = slip_read,
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index 89fbec185cc1..8460285c69a5 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -241,7 +241,7 @@ static void slip_del_addr(unsigned char *addr, unsigned char *netmask,
241 close_addr(addr, netmask, pri->name); 241 close_addr(addr, netmask, pri->name);
242} 242}
243 243
244struct net_user_info slip_user_info = { 244const struct net_user_info slip_user_info = {
245 .init = slip_user_init, 245 .init = slip_user_init,
246 .open = slip_open, 246 .open = slip_open,
247 .close = slip_close, 247 .close = slip_close,
diff --git a/arch/um/drivers/slirp.h b/arch/um/drivers/slirp.h
index 6cf88ab580c9..89ccf83b7577 100644
--- a/arch/um/drivers/slirp.h
+++ b/arch/um/drivers/slirp.h
@@ -24,7 +24,7 @@ struct slirp_data {
24 struct slip_proto slip; 24 struct slip_proto slip;
25}; 25};
26 26
27extern struct net_user_info slirp_user_info; 27extern const struct net_user_info slirp_user_info;
28 28
29extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri); 29extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri);
30extern int slirp_user_write(int fd, void *buf, int len, 30extern int slirp_user_write(int fd, void *buf, int len,
diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c
index 95e50c943e14..ae322e1c8a87 100644
--- a/arch/um/drivers/slirp_kern.c
+++ b/arch/um/drivers/slirp_kern.c
@@ -64,7 +64,7 @@ static int slirp_write(int fd, struct sk_buff **skb,
64 (struct slirp_data *) &lp->user)); 64 (struct slirp_data *) &lp->user));
65} 65}
66 66
67struct net_kern_info slirp_kern_info = { 67const struct net_kern_info slirp_kern_info = {
68 .init = slirp_init, 68 .init = slirp_init,
69 .protocol = slirp_protocol, 69 .protocol = slirp_protocol,
70 .read = slirp_read, 70 .read = slirp_read,
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index 33c5f6e625e8..ce5e85d1de3d 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -126,7 +126,7 @@ static int slirp_set_mtu(int mtu, void *data)
126 return(mtu); 126 return(mtu);
127} 127}
128 128
129struct net_user_info slirp_user_info = { 129const struct net_user_info slirp_user_info = {
130 .init = slirp_user_init, 130 .init = slirp_user_init,
131 .open = slirp_open, 131 .open = slirp_open,
132 .close = slirp_close, 132 .close = slirp_close,
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index 6dafd6fbfdae..6f13e7c71a82 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -23,7 +23,7 @@
23#include "irq_user.h" 23#include "irq_user.h"
24#include "mconsole_kern.h" 24#include "mconsole_kern.h"
25 25
26static int ssl_version = 1; 26static const int ssl_version = 1;
27 27
28/* Referenced only by tty_driver below - presumably it's locked correctly 28/* Referenced only by tty_driver below - presumably it's locked correctly
29 * by the tty driver. 29 * by the tty driver.
@@ -123,7 +123,7 @@ void ssl_hangup(struct tty_struct *tty)
123} 123}
124#endif 124#endif
125 125
126static struct tty_operations ssl_ops = { 126static const struct tty_operations ssl_ops = {
127 .open = ssl_open, 127 .open = ssl_open,
128 .close = line_close, 128 .close = line_close,
129 .write = line_write, 129 .write = line_write,
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 856f568c2687..5e44adb07051 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -110,7 +110,7 @@ static int con_open(struct tty_struct *tty, struct file *filp)
110 110
111static int con_init_done = 0; 111static int con_init_done = 0;
112 112
113static struct tty_operations console_ops = { 113static const struct tty_operations console_ops = {
114 .open = con_open, 114 .open = con_open,
115 .close = line_close, 115 .close = line_close,
116 .write = line_write, 116 .write = line_write,
diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
index 9f70edf5d8ef..11de3ac1eb5c 100644
--- a/arch/um/drivers/tty.c
+++ b/arch/um/drivers/tty.c
@@ -18,7 +18,7 @@ struct tty_chan {
18 struct termios tt; 18 struct termios tt;
19}; 19};
20 20
21static void *tty_chan_init(char *str, int device, struct chan_opts *opts) 21static void *tty_chan_init(char *str, int device, const struct chan_opts *opts)
22{ 22{
23 struct tty_chan *data; 23 struct tty_chan *data;
24 24
@@ -62,7 +62,7 @@ static int tty_open(int input, int output, int primary, void *d,
62 return fd; 62 return fd;
63} 63}
64 64
65struct chan_ops tty_ops = { 65const struct chan_ops tty_ops = {
66 .type = "tty", 66 .type = "tty",
67 .init = tty_chan_init, 67 .init = tty_chan_init,
68 .open = tty_open, 68 .open = tty_open,
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index aaa636661043..386f8b952982 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -31,7 +31,7 @@ struct xterm_chan {
31}; 31};
32 32
33/* Not static because it's called directly by the tt mode gdb code */ 33/* Not static because it's called directly by the tt mode gdb code */
34void *xterm_init(char *str, int device, struct chan_opts *opts) 34void *xterm_init(char *str, int device, const struct chan_opts *opts)
35{ 35{
36 struct xterm_chan *data; 36 struct xterm_chan *data;
37 37
@@ -194,7 +194,7 @@ static void xterm_free(void *d)
194 free(d); 194 free(d);
195} 195}
196 196
197struct chan_ops xterm_ops = { 197const struct chan_ops xterm_ops = {
198 .type = "xterm", 198 .type = "xterm",
199 .init = xterm_init, 199 .init = xterm_init,
200 .open = xterm_open, 200 .open = xterm_open,
diff --git a/arch/um/include/chan_kern.h b/arch/um/include/chan_kern.h
index 1bb5e9d94270..572d286ed2c6 100644
--- a/arch/um/include/chan_kern.h
+++ b/arch/um/include/chan_kern.h
@@ -23,21 +23,21 @@ struct chan {
23 unsigned int opened:1; 23 unsigned int opened:1;
24 unsigned int enabled:1; 24 unsigned int enabled:1;
25 int fd; 25 int fd;
26 struct chan_ops *ops; 26 const struct chan_ops *ops;
27 void *data; 27 void *data;
28}; 28};
29 29
30extern void chan_interrupt(struct list_head *chans, struct work_struct *task, 30extern void chan_interrupt(struct list_head *chans, struct work_struct *task,
31 struct tty_struct *tty, int irq); 31 struct tty_struct *tty, int irq);
32extern int parse_chan_pair(char *str, struct line *line, int device, 32extern int parse_chan_pair(char *str, struct line *line, int device,
33 struct chan_opts *opts); 33 const struct chan_opts *opts);
34extern int open_chan(struct list_head *chans); 34extern int open_chan(struct list_head *chans);
35extern int write_chan(struct list_head *chans, const char *buf, int len, 35extern int write_chan(struct list_head *chans, const char *buf, int len,
36 int write_irq); 36 int write_irq);
37extern int console_write_chan(struct list_head *chans, const char *buf, 37extern int console_write_chan(struct list_head *chans, const char *buf,
38 int len); 38 int len);
39extern int console_open_chan(struct line *line, struct console *co, 39extern int console_open_chan(struct line *line, struct console *co,
40 struct chan_opts *opts); 40 const struct chan_opts *opts);
41extern void deactivate_chan(struct list_head *chans, int irq); 41extern void deactivate_chan(struct list_head *chans, int irq);
42extern void reactivate_chan(struct list_head *chans, int irq); 42extern void reactivate_chan(struct list_head *chans, int irq);
43extern void chan_enable_winch(struct list_head *chans, struct tty_struct *tty); 43extern void chan_enable_winch(struct list_head *chans, struct tty_struct *tty);
diff --git a/arch/um/include/chan_user.h b/arch/um/include/chan_user.h
index 659bb3cac32f..a795547a1dbd 100644
--- a/arch/um/include/chan_user.h
+++ b/arch/um/include/chan_user.h
@@ -20,7 +20,7 @@ enum chan_init_pri { INIT_STATIC, INIT_ALL, INIT_ONE };
20 20
21struct chan_ops { 21struct chan_ops {
22 char *type; 22 char *type;
23 void *(*init)(char *, int, struct chan_opts *); 23 void *(*init)(char *, int, const struct chan_opts *);
24 int (*open)(int, int, int, void *, char **); 24 int (*open)(int, int, int, void *, char **);
25 void (*close)(int, void *); 25 void (*close)(int, void *);
26 int (*read)(int, char *, void *); 26 int (*read)(int, char *, void *);
@@ -31,8 +31,8 @@ struct chan_ops {
31 int winch; 31 int winch;
32}; 32};
33 33
34extern struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops, tty_ops, 34extern const struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops,
35 xterm_ops; 35 tty_ops, xterm_ops;
36 36
37extern void generic_close(int fd, void *unused); 37extern void generic_close(int fd, void *unused);
38extern int generic_read(int fd, char *c_out, void *unused); 38extern int generic_read(int fd, char *c_out, void *unused);
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index b98bdd8e052a..59cfa9e0cad0 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -21,13 +21,12 @@ struct kern_handlers {
21 kern_hndl timer_handler; 21 kern_hndl timer_handler;
22}; 22};
23 23
24extern struct kern_handlers handlinfo_kern; 24extern const struct kern_handlers handlinfo_kern;
25 25
26extern int ncpus; 26extern int ncpus;
27extern char *linux_prog; 27extern char *linux_prog;
28extern char *gdb_init; 28extern char *gdb_init;
29extern int kmalloc_ok; 29extern int kmalloc_ok;
30extern int timer_irq_inited;
31extern int jail; 30extern int jail;
32extern int nsyscalls; 31extern int nsyscalls;
33 32
diff --git a/arch/um/include/line.h b/arch/um/include/line.h
index 27bf2f6fbc05..642c9a0320f9 100644
--- a/arch/um/include/line.h
+++ b/arch/um/include/line.h
@@ -52,7 +52,7 @@ struct line {
52 52
53 int sigio; 53 int sigio;
54 struct work_struct task; 54 struct work_struct task;
55 struct line_driver *driver; 55 const struct line_driver *driver;
56 int have_irq; 56 int have_irq;
57}; 57};
58 58
@@ -99,7 +99,7 @@ extern void lines_init(struct line *lines, int nlines, struct chan_opts *opts);
99extern void close_lines(struct line *lines, int nlines); 99extern void close_lines(struct line *lines, int nlines);
100 100
101extern int line_config(struct line *lines, unsigned int sizeof_lines, 101extern int line_config(struct line *lines, unsigned int sizeof_lines,
102 char *str, struct chan_opts *opts); 102 char *str, const struct chan_opts *opts);
103extern int line_id(char **str, int *start_out, int *end_out); 103extern int line_id(char **str, int *start_out, int *end_out);
104extern int line_remove(struct line *lines, unsigned int sizeof_lines, int n); 104extern int line_remove(struct line *lines, unsigned int sizeof_lines, int n);
105extern int line_get_config(char *dev, struct line *lines, 105extern int line_get_config(char *dev, struct line *lines,
diff --git a/arch/um/include/longjmp.h b/arch/um/include/longjmp.h
index 1b5c0131a12e..e93c6d3e893b 100644
--- a/arch/um/include/longjmp.h
+++ b/arch/um/include/longjmp.h
@@ -1,9 +1,12 @@
1#ifndef __UML_LONGJMP_H 1#ifndef __UML_LONGJMP_H
2#define __UML_LONGJMP_H 2#define __UML_LONGJMP_H
3 3
4#include <setjmp.h> 4#include "sysdep/archsetjmp.h"
5#include "os.h" 5#include "os.h"
6 6
7extern int setjmp(jmp_buf);
8extern void longjmp(jmp_buf, int);
9
7#define UML_LONGJMP(buf, val) do { \ 10#define UML_LONGJMP(buf, val) do { \
8 longjmp(*buf, val); \ 11 longjmp(*buf, val); \
9} while(0) 12} while(0)
diff --git a/arch/um/include/net_kern.h b/arch/um/include/net_kern.h
index f7de6df60dd7..769fba43ee03 100644
--- a/arch/um/include/net_kern.h
+++ b/arch/um/include/net_kern.h
@@ -54,8 +54,8 @@ struct transport {
54 struct list_head list; 54 struct list_head list;
55 char *name; 55 char *name;
56 int (*setup)(char *, char **, void *); 56 int (*setup)(char *, char **, void *);
57 struct net_user_info *user; 57 const struct net_user_info *user;
58 struct net_kern_info *kern; 58 const struct net_kern_info *kern;
59 int private_size; 59 int private_size;
60 int setup_size; 60 int setup_size;
61}; 61};
diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h
index 800c403920bc..47ef7cb49a8e 100644
--- a/arch/um/include/net_user.h
+++ b/arch/um/include/net_user.h
@@ -26,7 +26,6 @@ struct net_user_info {
26 26
27extern void ether_user_init(void *data, void *dev); 27extern void ether_user_init(void *data, void *dev);
28extern void dev_ip_addr(void *d, unsigned char *bin_buf); 28extern void dev_ip_addr(void *d, unsigned char *bin_buf);
29extern void set_ether_mac(void *d, unsigned char *addr);
30extern void iter_addresses(void *d, void (*cb)(unsigned char *, 29extern void iter_addresses(void *d, void (*cb)(unsigned char *,
31 unsigned char *, void *), 30 unsigned char *, void *),
32 void *arg); 31 void *arg);
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 5316e8a4a4fd..120ca21a513a 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -14,6 +14,7 @@
14#include "skas/mm_id.h" 14#include "skas/mm_id.h"
15#include "irq_user.h" 15#include "irq_user.h"
16#include "sysdep/tls.h" 16#include "sysdep/tls.h"
17#include "sysdep/archsetjmp.h"
17 18
18#define OS_TYPE_FILE 1 19#define OS_TYPE_FILE 1
19#define OS_TYPE_DIR 2 20#define OS_TYPE_DIR 2
@@ -198,7 +199,9 @@ extern long os_ptrace_ldt(long pid, long addr, long data);
198extern int os_getpid(void); 199extern int os_getpid(void);
199extern int os_getpgrp(void); 200extern int os_getpgrp(void);
200 201
202#ifdef UML_CONFIG_MODE_TT
201extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)); 203extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
204#endif
202extern void init_new_thread_signals(void); 205extern void init_new_thread_signals(void);
203extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr); 206extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
204 207
@@ -216,7 +219,6 @@ extern void os_flush_stdout(void);
216 */ 219 */
217extern void forward_ipi(int fd, int pid); 220extern void forward_ipi(int fd, int pid);
218extern void kill_child_dead(int pid); 221extern void kill_child_dead(int pid);
219extern void stop(void);
220extern int wait_for_stop(int pid, int sig, int cont_type, void *relay); 222extern int wait_for_stop(int pid, int sig, int cont_type, void *relay);
221extern int protect_memory(unsigned long addr, unsigned long len, 223extern int protect_memory(unsigned long addr, unsigned long len,
222 int r, int w, int x, int must_succeed); 224 int r, int w, int x, int must_succeed);
@@ -276,9 +278,11 @@ extern int setjmp_wrapper(void (*proc)(void *, void *), ...);
276 278
277extern void switch_timers(int to_real); 279extern void switch_timers(int to_real);
278extern void idle_sleep(int secs); 280extern void idle_sleep(int secs);
281extern int set_interval(int is_virtual);
282#ifdef CONFIG_MODE_TT
279extern void enable_timer(void); 283extern void enable_timer(void);
284#endif
280extern void disable_timer(void); 285extern void disable_timer(void);
281extern void user_time_init(void);
282extern void uml_idle_timer(void); 286extern void uml_idle_timer(void);
283extern unsigned long long os_nsecs(void); 287extern unsigned long long os_nsecs(void);
284 288
@@ -305,12 +309,9 @@ extern int copy_context_skas0(unsigned long stack, int pid);
305extern void userspace(union uml_pt_regs *regs); 309extern void userspace(union uml_pt_regs *regs);
306extern void map_stub_pages(int fd, unsigned long code, 310extern void map_stub_pages(int fd, unsigned long code,
307 unsigned long data, unsigned long stack); 311 unsigned long data, unsigned long stack);
308extern void new_thread(void *stack, void **switch_buf_ptr, 312extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void));
309 void **fork_buf_ptr, void (*handler)(int)); 313extern void switch_threads(jmp_buf *me, jmp_buf *you);
310extern void thread_wait(void *sw, void *fb); 314extern int start_idle_thread(void *stack, jmp_buf *switch_buf);
311extern void switch_threads(void *me, void *next);
312extern int start_idle_thread(void *stack, void *switch_buf_ptr,
313 void **fork_buf_ptr);
314extern void initial_thread_cb_skas(void (*proc)(void *), 315extern void initial_thread_cb_skas(void (*proc)(void *),
315 void *arg); 316 void *arg);
316extern void halt_skas(void); 317extern void halt_skas(void);
@@ -329,6 +330,7 @@ extern void os_set_ioignore(void);
329extern void init_irq_signals(int on_sigstack); 330extern void init_irq_signals(int on_sigstack);
330 331
331/* sigio.c */ 332/* sigio.c */
333extern int add_sigio_fd(int fd);
332extern int ignore_sigio_fd(int fd); 334extern int ignore_sigio_fd(int fd);
333extern void maybe_sigio_broken(int fd, int read); 335extern void maybe_sigio_broken(int fd, int read);
334 336
diff --git a/arch/um/include/registers.h b/arch/um/include/registers.h
index 83b688ca198f..f845b3629a6d 100644
--- a/arch/um/include/registers.h
+++ b/arch/um/include/registers.h
@@ -7,6 +7,7 @@
7#define __REGISTERS_H 7#define __REGISTERS_H
8 8
9#include "sysdep/ptrace.h" 9#include "sysdep/ptrace.h"
10#include "sysdep/archsetjmp.h"
10 11
11extern void init_thread_registers(union uml_pt_regs *to); 12extern void init_thread_registers(union uml_pt_regs *to);
12extern int save_fp_registers(int pid, unsigned long *fp_regs); 13extern int save_fp_registers(int pid, unsigned long *fp_regs);
@@ -15,6 +16,6 @@ extern void save_registers(int pid, union uml_pt_regs *regs);
15extern void restore_registers(int pid, union uml_pt_regs *regs); 16extern void restore_registers(int pid, union uml_pt_regs *regs);
16extern void init_registers(int pid); 17extern void init_registers(int pid);
17extern void get_safe_registers(unsigned long * regs, unsigned long * fp_regs); 18extern void get_safe_registers(unsigned long * regs, unsigned long * fp_regs);
18extern void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer); 19extern unsigned long get_thread_reg(int reg, jmp_buf *buf);
19 20
20#endif 21#endif
diff --git a/arch/um/include/skas/skas.h b/arch/um/include/skas/skas.h
index 853b26f148c5..e88926b16072 100644
--- a/arch/um/include/skas/skas.h
+++ b/arch/um/include/skas/skas.h
@@ -14,8 +14,7 @@ extern int proc_mm, ptrace_faultinfo, ptrace_ldt;
14extern int skas_needs_stub; 14extern int skas_needs_stub;
15 15
16extern int user_thread(unsigned long stack, int flags); 16extern int user_thread(unsigned long stack, int flags);
17extern void new_thread_proc(void *stack, void (*handler)(int sig)); 17extern void new_thread_handler(void);
18extern void new_thread_handler(int sig);
19extern void handle_syscall(union uml_pt_regs *regs); 18extern void handle_syscall(union uml_pt_regs *regs);
20extern int new_mm(unsigned long stack); 19extern int new_mm(unsigned long stack);
21extern void get_skas_faultinfo(int pid, struct faultinfo * fi); 20extern void get_skas_faultinfo(int pid, struct faultinfo * fi);
diff --git a/arch/um/include/sysdep-i386/archsetjmp.h b/arch/um/include/sysdep-i386/archsetjmp.h
new file mode 100644
index 000000000000..11bafab669e9
--- /dev/null
+++ b/arch/um/include/sysdep-i386/archsetjmp.h
@@ -0,0 +1,22 @@
1/*
2 * arch/i386/include/klibc/archsetjmp.h
3 */
4
5#ifndef _KLIBC_ARCHSETJMP_H
6#define _KLIBC_ARCHSETJMP_H
7
8struct __jmp_buf {
9 unsigned int __ebx;
10 unsigned int __esp;
11 unsigned int __ebp;
12 unsigned int __esi;
13 unsigned int __edi;
14 unsigned int __eip;
15};
16
17typedef struct __jmp_buf jmp_buf[1];
18
19#define JB_IP __eip
20#define JB_SP __esp
21
22#endif /* _SETJMP_H */
diff --git a/arch/um/include/sysdep-i386/signal.h b/arch/um/include/sysdep-i386/signal.h
deleted file mode 100644
index 07518b162136..000000000000
--- a/arch/um/include/sysdep-i386/signal.h
+++ /dev/null
@@ -1,27 +0,0 @@
1/*
2 * Copyright (C) 2004 PathScale, Inc
3 * Licensed under the GPL
4 */
5
6#ifndef __I386_SIGNAL_H_
7#define __I386_SIGNAL_H_
8
9#include <signal.h>
10
11#define ARCH_SIGHDLR_PARAM int sig
12
13#define ARCH_GET_SIGCONTEXT(sc, sig) \
14 do sc = (struct sigcontext *) (&sig + 1); while(0)
15
16#endif
17
18/*
19 * Overrides for Emacs so that we follow Linus's tabbing style.
20 * Emacs will notice this stuff at the end of the file and automatically
21 * adjust the settings for this buffer only. This must remain at the end
22 * of the file.
23 * ---------------------------------------------------------------------------
24 * Local variables:
25 * c-file-style: "linux"
26 * End:
27 */
diff --git a/arch/um/include/sysdep-x86_64/archsetjmp.h b/arch/um/include/sysdep-x86_64/archsetjmp.h
new file mode 100644
index 000000000000..9a5e1a6ec800
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/archsetjmp.h
@@ -0,0 +1,24 @@
1/*
2 * arch/x86_64/include/klibc/archsetjmp.h
3 */
4
5#ifndef _KLIBC_ARCHSETJMP_H
6#define _KLIBC_ARCHSETJMP_H
7
8struct __jmp_buf {
9 unsigned long __rbx;
10 unsigned long __rsp;
11 unsigned long __rbp;
12 unsigned long __r12;
13 unsigned long __r13;
14 unsigned long __r14;
15 unsigned long __r15;
16 unsigned long __rip;
17};
18
19typedef struct __jmp_buf jmp_buf[1];
20
21#define JB_IP __rip
22#define JB_SP __rsp
23
24#endif /* _SETJMP_H */
diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h
index 8d353f0feec1..617bb9efc934 100644
--- a/arch/um/include/sysdep-x86_64/ptrace.h
+++ b/arch/um/include/sysdep-x86_64/ptrace.h
@@ -50,6 +50,21 @@
50#define HOST_FS 25 50#define HOST_FS 25
51#define HOST_GS 26 51#define HOST_GS 26
52 52
53/* Also defined in asm/ptrace-x86_64.h, but not in libc headers. So, these
54 * are already defined for kernel code, but not for userspace code.
55 */
56#ifndef FS_BASE
57/* These aren't defined in ptrace.h, but exist in struct user_regs_struct,
58 * which is what x86_64 ptrace actually uses.
59 */
60#define FS_BASE (HOST_FS_BASE * sizeof(long))
61#define GS_BASE (HOST_GS_BASE * sizeof(long))
62#define DS (HOST_DS * sizeof(long))
63#define ES (HOST_ES * sizeof(long))
64#define FS (HOST_FS * sizeof(long))
65#define GS (HOST_GS * sizeof(long))
66#endif
67
53#define REGS_FS_BASE(r) ((r)[HOST_FS_BASE]) 68#define REGS_FS_BASE(r) ((r)[HOST_FS_BASE])
54#define REGS_GS_BASE(r) ((r)[HOST_GS_BASE]) 69#define REGS_GS_BASE(r) ((r)[HOST_GS_BASE])
55#define REGS_DS(r) ((r)[HOST_DS]) 70#define REGS_DS(r) ((r)[HOST_DS])
@@ -89,9 +104,12 @@ union uml_pt_regs {
89#endif 104#endif
90#ifdef UML_CONFIG_MODE_SKAS 105#ifdef UML_CONFIG_MODE_SKAS
91 struct skas_regs { 106 struct skas_regs {
92 /* XXX */ 107 /* x86_64 ptrace uses sizeof(user_regs_struct) as its register
93 unsigned long regs[27]; 108 * file size, while i386 uses FRAME_SIZE. Therefore, we need
94 unsigned long fp[65]; 109 * to use UM_FRAME_SIZE here instead of HOST_FRAME_SIZE.
110 */
111 unsigned long regs[UM_FRAME_SIZE];
112 unsigned long fp[HOST_FP_SIZE];
95 struct faultinfo faultinfo; 113 struct faultinfo faultinfo;
96 long syscall; 114 long syscall;
97 int is_user; 115 int is_user;
@@ -120,11 +138,16 @@ extern int mode_tt;
120#define UPT_R14(r) __CHOOSE_MODE(SC_R14(UPT_SC(r)), REGS_R14((r)->skas.regs)) 138#define UPT_R14(r) __CHOOSE_MODE(SC_R14(UPT_SC(r)), REGS_R14((r)->skas.regs))
121#define UPT_R15(r) __CHOOSE_MODE(SC_R15(UPT_SC(r)), REGS_R15((r)->skas.regs)) 139#define UPT_R15(r) __CHOOSE_MODE(SC_R15(UPT_SC(r)), REGS_R15((r)->skas.regs))
122#define UPT_CS(r) __CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs)) 140#define UPT_CS(r) __CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs))
141#define UPT_FS_BASE(r) \
142 __CHOOSE_MODE(SC_FS_BASE(UPT_SC(r)), REGS_FS_BASE((r)->skas.regs))
123#define UPT_FS(r) __CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs)) 143#define UPT_FS(r) __CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs))
144#define UPT_GS_BASE(r) \
145 __CHOOSE_MODE(SC_GS_BASE(UPT_SC(r)), REGS_GS_BASE((r)->skas.regs))
124#define UPT_GS(r) __CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs)) 146#define UPT_GS(r) __CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs))
125#define UPT_DS(r) __CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs)) 147#define UPT_DS(r) __CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs))
126#define UPT_ES(r) __CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs)) 148#define UPT_ES(r) __CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs))
127#define UPT_CS(r) __CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs)) 149#define UPT_CS(r) __CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs))
150#define UPT_SS(r) __CHOOSE_MODE(SC_SS(UPT_SC(r)), REGS_SS((r)->skas.regs))
128#define UPT_ORIG_RAX(r) \ 151#define UPT_ORIG_RAX(r) \
129 __CHOOSE_MODE((r)->tt.orig_rax, REGS_ORIG_RAX((r)->skas.regs)) 152 __CHOOSE_MODE((r)->tt.orig_rax, REGS_ORIG_RAX((r)->skas.regs))
130 153
@@ -183,6 +206,13 @@ struct syscall_args {
183 case RBP: val = UPT_RBP(regs); break; \ 206 case RBP: val = UPT_RBP(regs); break; \
184 case ORIG_RAX: val = UPT_ORIG_RAX(regs); break; \ 207 case ORIG_RAX: val = UPT_ORIG_RAX(regs); break; \
185 case CS: val = UPT_CS(regs); break; \ 208 case CS: val = UPT_CS(regs); break; \
209 case SS: val = UPT_SS(regs); break; \
210 case FS_BASE: val = UPT_FS_BASE(regs); break; \
211 case GS_BASE: val = UPT_GS_BASE(regs); break; \
212 case DS: val = UPT_DS(regs); break; \
213 case ES: val = UPT_ES(regs); break; \
214 case FS : val = UPT_FS (regs); break; \
215 case GS: val = UPT_GS(regs); break; \
186 case EFLAGS: val = UPT_EFLAGS(regs); break; \ 216 case EFLAGS: val = UPT_EFLAGS(regs); break; \
187 default : \ 217 default : \
188 panic("Bad register in UPT_REG : %d\n", reg); \ 218 panic("Bad register in UPT_REG : %d\n", reg); \
@@ -214,6 +244,13 @@ struct syscall_args {
214 case RBP: UPT_RBP(regs) = __upt_val; break; \ 244 case RBP: UPT_RBP(regs) = __upt_val; break; \
215 case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \ 245 case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \
216 case CS: UPT_CS(regs) = __upt_val; break; \ 246 case CS: UPT_CS(regs) = __upt_val; break; \
247 case SS: UPT_SS(regs) = __upt_val; break; \
248 case FS_BASE: UPT_FS_BASE(regs) = __upt_val; break; \
249 case GS_BASE: UPT_GS_BASE(regs) = __upt_val; break; \
250 case DS: UPT_DS(regs) = __upt_val; break; \
251 case ES: UPT_ES(regs) = __upt_val; break; \
252 case FS: UPT_FS(regs) = __upt_val; break; \
253 case GS: UPT_GS(regs) = __upt_val; break; \
217 case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \ 254 case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \
218 default : \ 255 default : \
219 panic("Bad register in UPT_SET : %d\n", reg); \ 256 panic("Bad register in UPT_SET : %d\n", reg); \
diff --git a/arch/um/include/sysdep-x86_64/sc.h b/arch/um/include/sysdep-x86_64/sc.h
index a160d9fcc596..8aee45b07434 100644
--- a/arch/um/include/sysdep-x86_64/sc.h
+++ b/arch/um/include/sysdep-x86_64/sc.h
@@ -35,11 +35,11 @@
35#define SC_GS(sc) SC_OFFSET(sc, SC_GS) 35#define SC_GS(sc) SC_OFFSET(sc, SC_GS)
36#define SC_EFLAGS(sc) SC_OFFSET(sc, SC_EFLAGS) 36#define SC_EFLAGS(sc) SC_OFFSET(sc, SC_EFLAGS)
37#define SC_SIGMASK(sc) SC_OFFSET(sc, SC_SIGMASK) 37#define SC_SIGMASK(sc) SC_OFFSET(sc, SC_SIGMASK)
38#define SC_SS(sc) SC_OFFSET(sc, SC_SS)
38#if 0 39#if 0
39#define SC_ORIG_RAX(sc) SC_OFFSET(sc, SC_ORIG_RAX) 40#define SC_ORIG_RAX(sc) SC_OFFSET(sc, SC_ORIG_RAX)
40#define SC_DS(sc) SC_OFFSET(sc, SC_DS) 41#define SC_DS(sc) SC_OFFSET(sc, SC_DS)
41#define SC_ES(sc) SC_OFFSET(sc, SC_ES) 42#define SC_ES(sc) SC_OFFSET(sc, SC_ES)
42#define SC_SS(sc) SC_OFFSET(sc, SC_SS)
43#endif 43#endif
44 44
45#endif 45#endif
diff --git a/arch/um/include/sysdep-x86_64/signal.h b/arch/um/include/sysdep-x86_64/signal.h
deleted file mode 100644
index 6142897af3d1..000000000000
--- a/arch/um/include/sysdep-x86_64/signal.h
+++ /dev/null
@@ -1,29 +0,0 @@
1/*
2 * Copyright (C) 2004 PathScale, Inc
3 * Licensed under the GPL
4 */
5
6#ifndef __X86_64_SIGNAL_H_
7#define __X86_64_SIGNAL_H_
8
9#define ARCH_SIGHDLR_PARAM int sig
10
11#define ARCH_GET_SIGCONTEXT(sc, sig_addr) \
12 do { \
13 struct ucontext *__uc; \
14 asm("movq %%rdx, %0" : "=r" (__uc)); \
15 sc = (struct sigcontext *) &__uc->uc_mcontext; \
16 } while(0)
17
18#endif
19
20/*
21 * Overrides for Emacs so that we follow Linus's tabbing style.
22 * Emacs will notice this stuff at the end of the file and automatically
23 * adjust the settings for this buffer only. This must remain at the end
24 * of the file.
25 * ---------------------------------------------------------------------------
26 * Local variables:
27 * c-file-style: "linux"
28 * End:
29 */
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index a2d93065b2d0..6fa63a2a89e3 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -7,7 +7,7 @@ extra-y := vmlinux.lds
7clean-files := 7clean-files :=
8 8
9obj-y = config.o exec.o exitcode.o init_task.o irq.o ksyms.o mem.o \ 9obj-y = config.o exec.o exitcode.o init_task.o irq.o ksyms.o mem.o \
10 physmem.o process_kern.o ptrace.o reboot.o resource.o sigio.o \ 10 physmem.o process.o ptrace.o reboot.o resource.o sigio.o \
11 signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o uaccess.o \ 11 signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o uaccess.o \
12 um_arch.o umid.o 12 um_arch.o umid.o
13 13
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c
index fc38a6d5906d..0561c43b4685 100644
--- a/arch/um/kernel/exec.c
+++ b/arch/um/kernel/exec.c
@@ -41,9 +41,11 @@ static long execve1(char *file, char __user * __user *argv,
41 long error; 41 long error;
42 42
43#ifdef CONFIG_TTY_LOG 43#ifdef CONFIG_TTY_LOG
44 task_lock(current); 44 mutex_lock(&tty_mutex);
45 task_lock(current); /* FIXME: is this needed ? */
45 log_exec(argv, current->signal->tty); 46 log_exec(argv, current->signal->tty);
46 task_unlock(current); 47 task_unlock(current);
48 mutex_unlock(&tty_mutex);
47#endif 49#endif
48 error = do_execve(file, argv, env, &current->thread.regs); 50 error = do_execve(file, argv, env, &current->thread.regs);
49 if (error == 0){ 51 if (error == 0){
diff --git a/arch/um/kernel/gmon_syms.c b/arch/um/kernel/gmon_syms.c
index 2c86e7fdb014..13aa115cd1b4 100644
--- a/arch/um/kernel/gmon_syms.c
+++ b/arch/um/kernel/gmon_syms.c
@@ -5,7 +5,7 @@
5 5
6#include "linux/module.h" 6#include "linux/module.h"
7 7
8extern void __bb_init_func(void *); 8extern void __bb_init_func(void *) __attribute__((weak));
9EXPORT_SYMBOL(__bb_init_func); 9EXPORT_SYMBOL(__bb_init_func);
10 10
11/* This is defined (and referred to in profiling stub code) only by some GCC 11/* This is defined (and referred to in profiling stub code) only by some GCC
@@ -21,14 +21,3 @@ EXPORT_SYMBOL(__gcov_init);
21 21
22extern void __gcov_merge_add(void *) __attribute__((weak)); 22extern void __gcov_merge_add(void *) __attribute__((weak));
23EXPORT_SYMBOL(__gcov_merge_add); 23EXPORT_SYMBOL(__gcov_merge_add);
24
25/*
26 * Overrides for Emacs so that we follow Linus's tabbing style.
27 * Emacs will notice this stuff at the end of the file and automatically
28 * adjust the settings for this buffer only. This must remain at the end
29 * of the file.
30 * ---------------------------------------------------------------------------
31 * Local variables:
32 * c-file-style: "linux"
33 * End:
34 */
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 589c69a75043..ce7f233fc490 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -142,19 +142,6 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
142 .events = events, 142 .events = events,
143 .current_events = 0 } ); 143 .current_events = 0 } );
144 144
145 /* Critical section - locked by a spinlock because this stuff can
146 * be changed from interrupt handlers. The stuff above is done
147 * outside the lock because it allocates memory.
148 */
149
150 /* Actually, it only looks like it can be called from interrupt
151 * context. The culprit is reactivate_fd, which calls
152 * maybe_sigio_broken, which calls write_sigio_workaround,
153 * which calls activate_fd. However, write_sigio_workaround should
154 * only be called once, at boot time. That would make it clear that
155 * this is called only from process context, and can be locked with
156 * a semaphore.
157 */
158 spin_lock_irqsave(&irq_lock, flags); 145 spin_lock_irqsave(&irq_lock, flags);
159 for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { 146 for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) {
160 if ((irq_fd->fd == fd) && (irq_fd->type == type)) { 147 if ((irq_fd->fd == fd) && (irq_fd->type == type)) {
@@ -165,7 +152,6 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
165 } 152 }
166 } 153 }
167 154
168 /*-------------*/
169 if (type == IRQ_WRITE) 155 if (type == IRQ_WRITE)
170 fd = -1; 156 fd = -1;
171 157
@@ -198,7 +184,6 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
198 184
199 spin_lock_irqsave(&irq_lock, flags); 185 spin_lock_irqsave(&irq_lock, flags);
200 } 186 }
201 /*-------------*/
202 187
203 *last_irq_ptr = new_fd; 188 *last_irq_ptr = new_fd;
204 last_irq_ptr = &new_fd->next; 189 last_irq_ptr = &new_fd->next;
@@ -210,14 +195,14 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
210 */ 195 */
211 maybe_sigio_broken(fd, (type == IRQ_READ)); 196 maybe_sigio_broken(fd, (type == IRQ_READ));
212 197
213 return(0); 198 return 0;
214 199
215 out_unlock: 200 out_unlock:
216 spin_unlock_irqrestore(&irq_lock, flags); 201 spin_unlock_irqrestore(&irq_lock, flags);
217 out_kfree: 202 out_kfree:
218 kfree(new_fd); 203 kfree(new_fd);
219 out: 204 out:
220 return(err); 205 return err;
221} 206}
222 207
223static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg) 208static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
@@ -302,10 +287,7 @@ void reactivate_fd(int fd, int irqnum)
302 os_set_pollfd(i, irq->fd); 287 os_set_pollfd(i, irq->fd);
303 spin_unlock_irqrestore(&irq_lock, flags); 288 spin_unlock_irqrestore(&irq_lock, flags);
304 289
305 /* This calls activate_fd, so it has to be outside the critical 290 add_sigio_fd(fd);
306 * section.
307 */
308 maybe_sigio_broken(fd, (irq->type == IRQ_READ));
309} 291}
310 292
311void deactivate_fd(int fd, int irqnum) 293void deactivate_fd(int fd, int irqnum)
@@ -316,11 +298,15 @@ void deactivate_fd(int fd, int irqnum)
316 298
317 spin_lock_irqsave(&irq_lock, flags); 299 spin_lock_irqsave(&irq_lock, flags);
318 irq = find_irq_by_fd(fd, irqnum, &i); 300 irq = find_irq_by_fd(fd, irqnum, &i);
319 if (irq == NULL) 301 if(irq == NULL){
320 goto out; 302 spin_unlock_irqrestore(&irq_lock, flags);
303 return;
304 }
305
321 os_set_pollfd(i, -1); 306 os_set_pollfd(i, -1);
322 out:
323 spin_unlock_irqrestore(&irq_lock, flags); 307 spin_unlock_irqrestore(&irq_lock, flags);
308
309 ignore_sigio_fd(fd);
324} 310}
325 311
326int deactivate_all_fds(void) 312int deactivate_all_fds(void)
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index c97045d6d89f..f030e44262ba 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -21,7 +21,6 @@
21#include "mem_user.h" 21#include "mem_user.h"
22#include "os.h" 22#include "os.h"
23 23
24EXPORT_SYMBOL(stop);
25EXPORT_SYMBOL(uml_physmem); 24EXPORT_SYMBOL(uml_physmem);
26EXPORT_SYMBOL(set_signals); 25EXPORT_SYMBOL(set_signals);
27EXPORT_SYMBOL(get_signals); 26EXPORT_SYMBOL(get_signals);
@@ -41,12 +40,14 @@ EXPORT_SYMBOL(handle_page_fault);
41EXPORT_SYMBOL(find_iomem); 40EXPORT_SYMBOL(find_iomem);
42 41
43#ifdef CONFIG_MODE_TT 42#ifdef CONFIG_MODE_TT
43EXPORT_SYMBOL(stop);
44EXPORT_SYMBOL(strncpy_from_user_tt); 44EXPORT_SYMBOL(strncpy_from_user_tt);
45EXPORT_SYMBOL(copy_from_user_tt); 45EXPORT_SYMBOL(copy_from_user_tt);
46EXPORT_SYMBOL(copy_to_user_tt); 46EXPORT_SYMBOL(copy_to_user_tt);
47#endif 47#endif
48 48
49#ifdef CONFIG_MODE_SKAS 49#ifdef CONFIG_MODE_SKAS
50EXPORT_SYMBOL(strnlen_user_skas);
50EXPORT_SYMBOL(strncpy_from_user_skas); 51EXPORT_SYMBOL(strncpy_from_user_skas);
51EXPORT_SYMBOL(copy_to_user_skas); 52EXPORT_SYMBOL(copy_to_user_skas);
52EXPORT_SYMBOL(copy_from_user_skas); 53EXPORT_SYMBOL(copy_from_user_skas);
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 61280167c560..c95855ba6ab5 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -79,8 +79,10 @@ void mem_init(void)
79 79
80 /* this will put all low memory onto the freelists */ 80 /* this will put all low memory onto the freelists */
81 totalram_pages = free_all_bootmem(); 81 totalram_pages = free_all_bootmem();
82#ifdef CONFIG_HIGHMEM
82 totalhigh_pages = highmem >> PAGE_SHIFT; 83 totalhigh_pages = highmem >> PAGE_SHIFT;
83 totalram_pages += totalhigh_pages; 84 totalram_pages += totalhigh_pages;
85#endif
84 num_physpages = totalram_pages; 86 num_physpages = totalram_pages;
85 max_pfn = totalram_pages; 87 max_pfn = totalram_pages;
86 printk(KERN_INFO "Memory: %luk available\n", 88 printk(KERN_INFO "Memory: %luk available\n",
@@ -221,10 +223,14 @@ void paging_init(void)
221 223
222 empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE); 224 empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
223 empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE); 225 empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
224 for(i=0;i<sizeof(zones_size)/sizeof(zones_size[0]);i++) 226 for(i = 0; i < ARRAY_SIZE(zones_size); i++)
225 zones_size[i] = 0; 227 zones_size[i] = 0;
226 zones_size[ZONE_DMA] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT); 228
229 zones_size[ZONE_NORMAL] = (end_iomem >> PAGE_SHIFT) -
230 (uml_physmem >> PAGE_SHIFT);
231#ifdef CONFIG_HIGHMEM
227 zones_size[ZONE_HIGHMEM] = highmem >> PAGE_SHIFT; 232 zones_size[ZONE_HIGHMEM] = highmem >> PAGE_SHIFT;
233#endif
228 free_area_init(zones_size); 234 free_area_init(zones_size);
229 235
230 /* 236 /*
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process.c
index f6a5a502120b..fe6c64abda5b 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process.c
@@ -1,10 +1,9 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Copyright 2003 PathScale, Inc. 3 * Copyright 2003 PathScale, Inc.
4 * Licensed under the GPL 4 * Licensed under the GPL
5 */ 5 */
6 6
7#include "linux/config.h"
8#include "linux/kernel.h" 7#include "linux/kernel.h"
9#include "linux/sched.h" 8#include "linux/sched.h"
10#include "linux/interrupt.h" 9#include "linux/interrupt.h"
@@ -23,6 +22,7 @@
23#include "linux/proc_fs.h" 22#include "linux/proc_fs.h"
24#include "linux/ptrace.h" 23#include "linux/ptrace.h"
25#include "linux/random.h" 24#include "linux/random.h"
25#include "linux/personality.h"
26#include "asm/unistd.h" 26#include "asm/unistd.h"
27#include "asm/mman.h" 27#include "asm/mman.h"
28#include "asm/segment.h" 28#include "asm/segment.h"
@@ -112,11 +112,11 @@ void set_current(void *t)
112 112
113void *_switch_to(void *prev, void *next, void *last) 113void *_switch_to(void *prev, void *next, void *last)
114{ 114{
115 struct task_struct *from = prev; 115 struct task_struct *from = prev;
116 struct task_struct *to= next; 116 struct task_struct *to= next;
117 117
118 to->thread.prev_sched = from; 118 to->thread.prev_sched = from;
119 set_current(to); 119 set_current(to);
120 120
121 do { 121 do {
122 current->thread.saved_task = NULL ; 122 current->thread.saved_task = NULL ;
@@ -127,7 +127,7 @@ void *_switch_to(void *prev, void *next, void *last)
127 prev= current; 127 prev= current;
128 } while(current->thread.saved_task); 128 } while(current->thread.saved_task);
129 129
130 return(current->thread.prev_sched); 130 return(current->thread.prev_sched);
131 131
132} 132}
133 133
@@ -141,19 +141,19 @@ void release_thread(struct task_struct *task)
141{ 141{
142 CHOOSE_MODE(release_thread_tt(task), release_thread_skas(task)); 142 CHOOSE_MODE(release_thread_tt(task), release_thread_skas(task));
143} 143}
144 144
145void exit_thread(void) 145void exit_thread(void)
146{ 146{
147 unprotect_stack((unsigned long) current_thread); 147 unprotect_stack((unsigned long) current_thread);
148} 148}
149 149
150void *get_current(void) 150void *get_current(void)
151{ 151{
152 return(current); 152 return(current);
153} 153}
154 154
155int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, 155int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
156 unsigned long stack_top, struct task_struct * p, 156 unsigned long stack_top, struct task_struct * p,
157 struct pt_regs *regs) 157 struct pt_regs *regs)
158{ 158{
159 int ret; 159 int ret;
@@ -182,11 +182,11 @@ void initial_thread_cb(void (*proc)(void *), void *arg)
182 int save_kmalloc_ok = kmalloc_ok; 182 int save_kmalloc_ok = kmalloc_ok;
183 183
184 kmalloc_ok = 0; 184 kmalloc_ok = 0;
185 CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc, 185 CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc,
186 arg); 186 arg);
187 kmalloc_ok = save_kmalloc_ok; 187 kmalloc_ok = save_kmalloc_ok;
188} 188}
189 189
190unsigned long stack_sp(unsigned long page) 190unsigned long stack_sp(unsigned long page)
191{ 191{
192 return(page + PAGE_SIZE - sizeof(void *)); 192 return(page + PAGE_SIZE - sizeof(void *));
@@ -210,7 +210,7 @@ void default_idle(void)
210 */ 210 */
211 if(need_resched()) 211 if(need_resched())
212 schedule(); 212 schedule();
213 213
214 idle_sleep(10); 214 idle_sleep(10);
215 } 215 }
216} 216}
@@ -225,7 +225,7 @@ int page_size(void)
225 return(PAGE_SIZE); 225 return(PAGE_SIZE);
226} 226}
227 227
228void *um_virt_to_phys(struct task_struct *task, unsigned long addr, 228void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
229 pte_t *pte_out) 229 pte_t *pte_out)
230{ 230{
231 pgd_t *pgd; 231 pgd_t *pgd;
@@ -234,7 +234,7 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
234 pte_t *pte; 234 pte_t *pte;
235 pte_t ptent; 235 pte_t ptent;
236 236
237 if(task->mm == NULL) 237 if(task->mm == NULL)
238 return(ERR_PTR(-EINVAL)); 238 return(ERR_PTR(-EINVAL));
239 pgd = pgd_offset(task->mm, addr); 239 pgd = pgd_offset(task->mm, addr);
240 if(!pgd_present(*pgd)) 240 if(!pgd_present(*pgd))
@@ -245,7 +245,7 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
245 return(ERR_PTR(-EINVAL)); 245 return(ERR_PTR(-EINVAL));
246 246
247 pmd = pmd_offset(pud, addr); 247 pmd = pmd_offset(pud, addr);
248 if(!pmd_present(*pmd)) 248 if(!pmd_present(*pmd))
249 return(ERR_PTR(-EINVAL)); 249 return(ERR_PTR(-EINVAL));
250 250
251 pte = pte_offset_kernel(pmd, addr); 251 pte = pte_offset_kernel(pmd, addr);
@@ -270,7 +270,7 @@ char *current_cmd(void)
270 270
271void force_sigbus(void) 271void force_sigbus(void)
272{ 272{
273 printk(KERN_ERR "Killing pid %d because of a lack of memory\n", 273 printk(KERN_ERR "Killing pid %d because of a lack of memory\n",
274 current->pid); 274 current->pid);
275 lock_kernel(); 275 lock_kernel();
276 sigaddset(&current->pending.signal, SIGBUS); 276 sigaddset(&current->pending.signal, SIGBUS);
@@ -476,7 +476,7 @@ int singlestepping(void * t)
476#ifndef arch_align_stack 476#ifndef arch_align_stack
477unsigned long arch_align_stack(unsigned long sp) 477unsigned long arch_align_stack(unsigned long sp)
478{ 478{
479 if (randomize_va_space) 479 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
480 sp -= get_random_int() % 8192; 480 sp -= get_random_int() % 8192;
481 return sp & ~0xf; 481 return sp & ~0xf;
482} 482}
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index 3ef73bf2e781..f602623644aa 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -22,7 +22,7 @@ static void kill_idlers(int me)
22 struct task_struct *p; 22 struct task_struct *p;
23 int i; 23 int i;
24 24
25 for(i = 0; i < sizeof(idle_threads)/sizeof(idle_threads[0]); i++){ 25 for(i = 0; i < ARRAY_SIZE(idle_threads); i++){
26 p = idle_threads[i]; 26 p = idle_threads[i];
27 if((p != NULL) && (p->thread.mode.tt.extern_pid != me)) 27 if((p != NULL) && (p->thread.mode.tt.extern_pid != me))
28 os_kill_process(p->thread.mode.tt.extern_pid, 0); 28 os_kill_process(p->thread.mode.tt.extern_pid, 0);
@@ -62,14 +62,3 @@ void machine_halt(void)
62{ 62{
63 machine_power_off(); 63 machine_power_off();
64} 64}
65
66/*
67 * Overrides for Emacs so that we follow Linus's tabbing style.
68 * Emacs will notice this stuff at the end of the file and automatically
69 * adjust the settings for this buffer only. This must remain at the end
70 * of the file.
71 * ---------------------------------------------------------------------------
72 * Local variables:
73 * c-file-style: "linux"
74 * End:
75 */
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
index ea3a8e409a6e..3e3fa7e7e3cf 100644
--- a/arch/um/kernel/skas/Makefile
+++ b/arch/um/kernel/skas/Makefile
@@ -3,8 +3,7 @@
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6obj-y := clone.o exec_kern.o mem.o mmu.o process_kern.o \ 6obj-y := clone.o exec.o mem.o mmu.o process.o syscall.o tlb.o uaccess.o
7 syscall.o tlb.o uaccess.o
8 7
9# clone.o is in the stub, so it can't be built with profiling 8# clone.o is in the stub, so it can't be built with profiling
10# GCC hardened also auto-enables -fpic, but we need %ebx so it can't work -> 9# GCC hardened also auto-enables -fpic, but we need %ebx so it can't work ->
diff --git a/arch/um/kernel/skas/exec.c b/arch/um/kernel/skas/exec.c
new file mode 100644
index 000000000000..54b795951372
--- /dev/null
+++ b/arch/um/kernel/skas/exec.c
@@ -0,0 +1,30 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/kernel.h"
7#include "asm/current.h"
8#include "asm/page.h"
9#include "asm/signal.h"
10#include "asm/ptrace.h"
11#include "asm/uaccess.h"
12#include "asm/mmu_context.h"
13#include "tlb.h"
14#include "skas.h"
15#include "um_mmu.h"
16#include "os.h"
17
18void flush_thread_skas(void)
19{
20 force_flush_all();
21 switch_mm_skas(&current->mm->context.skas.id);
22}
23
24void start_thread_skas(struct pt_regs *regs, unsigned long eip,
25 unsigned long esp)
26{
27 set_fs(USER_DS);
28 PT_REGS_IP(regs) = eip;
29 PT_REGS_SP(regs) = esp;
30}
diff --git a/arch/um/kernel/skas/exec_kern.c b/arch/um/kernel/skas/exec_kern.c
deleted file mode 100644
index 77ed7bbab219..000000000000
--- a/arch/um/kernel/skas/exec_kern.c
+++ /dev/null
@@ -1,41 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/kernel.h"
7#include "asm/current.h"
8#include "asm/page.h"
9#include "asm/signal.h"
10#include "asm/ptrace.h"
11#include "asm/uaccess.h"
12#include "asm/mmu_context.h"
13#include "tlb.h"
14#include "skas.h"
15#include "um_mmu.h"
16#include "os.h"
17
18void flush_thread_skas(void)
19{
20 force_flush_all();
21 switch_mm_skas(&current->mm->context.skas.id);
22}
23
24void start_thread_skas(struct pt_regs *regs, unsigned long eip,
25 unsigned long esp)
26{
27 set_fs(USER_DS);
28 PT_REGS_IP(regs) = eip;
29 PT_REGS_SP(regs) = esp;
30}
31
32/*
33 * Overrides for Emacs so that we follow Linus's tabbing style.
34 * Emacs will notice this stuff at the end of the file and automatically
35 * adjust the settings for this buffer only. This must remain at the end
36 * of the file.
37 * ---------------------------------------------------------------------------
38 * Local variables:
39 * c-file-style: "linux"
40 * End:
41 */
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 624ca238d1fd..79c22707a637 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -55,7 +55,7 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
55 * destroy_context_skas. 55 * destroy_context_skas.
56 */ 56 */
57 57
58 mm->context.skas.last_page_table = pmd_page_kernel(*pmd); 58 mm->context.skas.last_page_table = pmd_page_vaddr(*pmd);
59#ifdef CONFIG_3_LEVEL_PGTABLES 59#ifdef CONFIG_3_LEVEL_PGTABLES
60 mm->context.skas.last_pmd = (unsigned long) __va(pud_val(*pud)); 60 mm->context.skas.last_pmd = (unsigned long) __va(pud_val(*pud));
61#endif 61#endif
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
new file mode 100644
index 000000000000..ae4fa71d3b8b
--- /dev/null
+++ b/arch/um/kernel/skas/process.c
@@ -0,0 +1,217 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/sched.h"
7#include "linux/slab.h"
8#include "linux/ptrace.h"
9#include "linux/proc_fs.h"
10#include "linux/file.h"
11#include "linux/errno.h"
12#include "linux/init.h"
13#include "asm/uaccess.h"
14#include "asm/atomic.h"
15#include "kern_util.h"
16#include "skas.h"
17#include "os.h"
18#include "user_util.h"
19#include "tlb.h"
20#include "kern.h"
21#include "mode.h"
22#include "registers.h"
23
24void switch_to_skas(void *prev, void *next)
25{
26 struct task_struct *from, *to;
27
28 from = prev;
29 to = next;
30
31 /* XXX need to check runqueues[cpu].idle */
32 if(current->pid == 0)
33 switch_timers(0);
34
35 switch_threads(&from->thread.mode.skas.switch_buf,
36 &to->thread.mode.skas.switch_buf);
37
38 arch_switch_to_skas(current->thread.prev_sched, current);
39
40 if(current->pid == 0)
41 switch_timers(1);
42}
43
44extern void schedule_tail(struct task_struct *prev);
45
46/* This is called magically, by its address being stuffed in a jmp_buf
47 * and being longjmp-d to.
48 */
49void new_thread_handler(void)
50{
51 int (*fn)(void *), n;
52 void *arg;
53
54 if(current->thread.prev_sched != NULL)
55 schedule_tail(current->thread.prev_sched);
56 current->thread.prev_sched = NULL;
57
58 fn = current->thread.request.u.thread.proc;
59 arg = current->thread.request.u.thread.arg;
60
61 /* The return value is 1 if the kernel thread execs a process,
62 * 0 if it just exits
63 */
64 n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
65 if(n == 1){
66 /* Handle any immediate reschedules or signals */
67 interrupt_end();
68 userspace(&current->thread.regs.regs);
69 }
70 else do_exit(0);
71}
72
73void release_thread_skas(struct task_struct *task)
74{
75}
76
77/* Called magically, see new_thread_handler above */
78void fork_handler(void)
79{
80 force_flush_all();
81 if(current->thread.prev_sched == NULL)
82 panic("blech");
83
84 schedule_tail(current->thread.prev_sched);
85
86 /* XXX: if interrupt_end() calls schedule, this call to
87 * arch_switch_to_skas isn't needed. We could want to apply this to
88 * improve performance. -bb */
89 arch_switch_to_skas(current->thread.prev_sched, current);
90
91 current->thread.prev_sched = NULL;
92
93/* Handle any immediate reschedules or signals */
94 interrupt_end();
95
96 userspace(&current->thread.regs.regs);
97}
98
99int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
100 unsigned long stack_top, struct task_struct * p,
101 struct pt_regs *regs)
102{
103 void (*handler)(void);
104
105 if(current->thread.forking){
106 memcpy(&p->thread.regs.regs.skas, &regs->regs.skas,
107 sizeof(p->thread.regs.regs.skas));
108 REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0);
109 if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp;
110
111 handler = fork_handler;
112
113 arch_copy_thread(&current->thread.arch, &p->thread.arch);
114 }
115 else {
116 init_thread_registers(&p->thread.regs.regs);
117 p->thread.request.u.thread = current->thread.request.u.thread;
118 handler = new_thread_handler;
119 }
120
121 new_thread(task_stack_page(p), &p->thread.mode.skas.switch_buf,
122 handler);
123 return(0);
124}
125
126int new_mm(unsigned long stack)
127{
128 int fd;
129
130 fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0);
131 if(fd < 0)
132 return(fd);
133
134 if(skas_needs_stub)
135 map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack);
136
137 return(fd);
138}
139
140void init_idle_skas(void)
141{
142 cpu_tasks[current_thread->cpu].pid = os_getpid();
143 default_idle();
144}
145
146extern void start_kernel(void);
147
148static int start_kernel_proc(void *unused)
149{
150 int pid;
151
152 block_signals();
153 pid = os_getpid();
154
155 cpu_tasks[0].pid = pid;
156 cpu_tasks[0].task = current;
157#ifdef CONFIG_SMP
158 cpu_online_map = cpumask_of_cpu(0);
159#endif
160 start_kernel();
161 return(0);
162}
163
164extern int userspace_pid[];
165
166int start_uml_skas(void)
167{
168 if(proc_mm)
169 userspace_pid[0] = start_userspace(0);
170
171 init_new_thread_signals();
172
173 init_task.thread.request.u.thread.proc = start_kernel_proc;
174 init_task.thread.request.u.thread.arg = NULL;
175 return(start_idle_thread(task_stack_page(&init_task),
176 &init_task.thread.mode.skas.switch_buf));
177}
178
179int external_pid_skas(struct task_struct *task)
180{
181#warning Need to look up userspace_pid by cpu
182 return(userspace_pid[0]);
183}
184
185int thread_pid_skas(struct task_struct *task)
186{
187#warning Need to look up userspace_pid by cpu
188 return(userspace_pid[0]);
189}
190
191void kill_off_processes_skas(void)
192{
193 if(proc_mm)
194#warning need to loop over userspace_pids in kill_off_processes_skas
195 os_kill_ptraced_process(userspace_pid[0], 1);
196 else {
197 struct task_struct *p;
198 int pid, me;
199
200 me = os_getpid();
201 for_each_process(p){
202 if(p->mm == NULL)
203 continue;
204
205 pid = p->mm->context.skas.id.u.pid;
206 os_kill_ptraced_process(pid, 1);
207 }
208 }
209}
210
211unsigned long current_stub_stack(void)
212{
213 if(current->mm == NULL)
214 return(0);
215
216 return(current->mm->context.skas.id.stack);
217}
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index 55caeec8b257..0f3d5d084dc7 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -1,227 +1,484 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Copyright 2003 PathScale, Inc.
3 * Licensed under the GPL 4 * Licensed under the GPL
4 */ 5 */
5 6
7#include "linux/config.h"
8#include "linux/kernel.h"
6#include "linux/sched.h" 9#include "linux/sched.h"
10#include "linux/interrupt.h"
11#include "linux/string.h"
12#include "linux/mm.h"
7#include "linux/slab.h" 13#include "linux/slab.h"
8#include "linux/ptrace.h" 14#include "linux/utsname.h"
9#include "linux/proc_fs.h" 15#include "linux/fs.h"
10#include "linux/file.h" 16#include "linux/utime.h"
11#include "linux/errno.h" 17#include "linux/smp_lock.h"
18#include "linux/module.h"
12#include "linux/init.h" 19#include "linux/init.h"
20#include "linux/capability.h"
21#include "linux/vmalloc.h"
22#include "linux/spinlock.h"
23#include "linux/proc_fs.h"
24#include "linux/ptrace.h"
25#include "linux/random.h"
26#include "linux/personality.h"
27#include "asm/unistd.h"
28#include "asm/mman.h"
29#include "asm/segment.h"
30#include "asm/stat.h"
31#include "asm/pgtable.h"
32#include "asm/processor.h"
33#include "asm/tlbflush.h"
13#include "asm/uaccess.h" 34#include "asm/uaccess.h"
14#include "asm/atomic.h" 35#include "asm/user.h"
15#include "kern_util.h"
16#include "skas.h"
17#include "os.h"
18#include "user_util.h" 36#include "user_util.h"
19#include "tlb.h" 37#include "kern_util.h"
20#include "kern.h" 38#include "kern.h"
39#include "signal_kern.h"
40#include "init.h"
41#include "irq_user.h"
42#include "mem_user.h"
43#include "tlb.h"
44#include "frame_kern.h"
45#include "sigcontext.h"
46#include "os.h"
21#include "mode.h" 47#include "mode.h"
22#include "registers.h" 48#include "mode_kern.h"
49#include "choose-mode.h"
50
51/* This is a per-cpu array. A processor only modifies its entry and it only
52 * cares about its entry, so it's OK if another processor is modifying its
53 * entry.
54 */
55struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
56
57int external_pid(void *t)
58{
59 struct task_struct *task = t ? t : current;
60
61 return(CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task));
62}
63
64int pid_to_processor_id(int pid)
65{
66 int i;
67
68 for(i = 0; i < ncpus; i++){
69 if(cpu_tasks[i].pid == pid) return(i);
70 }
71 return(-1);
72}
73
74void free_stack(unsigned long stack, int order)
75{
76 free_pages(stack, order);
77}
78
79unsigned long alloc_stack(int order, int atomic)
80{
81 unsigned long page;
82 gfp_t flags = GFP_KERNEL;
83
84 if (atomic)
85 flags = GFP_ATOMIC;
86 page = __get_free_pages(flags, order);
87 if(page == 0)
88 return(0);
89 stack_protections(page);
90 return(page);
91}
92
93int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
94{
95 int pid;
96
97 current->thread.request.u.thread.proc = fn;
98 current->thread.request.u.thread.arg = arg;
99 pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0,
100 &current->thread.regs, 0, NULL, NULL);
101 if(pid < 0)
102 panic("do_fork failed in kernel_thread, errno = %d", pid);
103 return(pid);
104}
23 105
24void switch_to_skas(void *prev, void *next) 106void set_current(void *t)
25{ 107{
26 struct task_struct *from, *to; 108 struct task_struct *task = t;
27 109
28 from = prev; 110 cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task)
29 to = next; 111 { external_pid(task), task });
112}
30 113
31 /* XXX need to check runqueues[cpu].idle */ 114void *_switch_to(void *prev, void *next, void *last)
32 if(current->pid == 0) 115{
33 switch_timers(0); 116 struct task_struct *from = prev;
117 struct task_struct *to= next;
34 118
35 switch_threads(&from->thread.mode.skas.switch_buf, 119 to->thread.prev_sched = from;
36 to->thread.mode.skas.switch_buf); 120 set_current(to);
37 121
38 arch_switch_to_skas(current->thread.prev_sched, current); 122 do {
123 current->thread.saved_task = NULL ;
124 CHOOSE_MODE_PROC(switch_to_tt, switch_to_skas, prev, next);
125 if(current->thread.saved_task)
126 show_regs(&(current->thread.regs));
127 next= current->thread.saved_task;
128 prev= current;
129 } while(current->thread.saved_task);
130
131 return(current->thread.prev_sched);
39 132
40 if(current->pid == 0)
41 switch_timers(1);
42} 133}
43 134
44extern void schedule_tail(struct task_struct *prev); 135void interrupt_end(void)
136{
137 if(need_resched()) schedule();
138 if(test_tsk_thread_flag(current, TIF_SIGPENDING)) do_signal();
139}
45 140
46void new_thread_handler(int sig) 141void release_thread(struct task_struct *task)
47{ 142{
48 int (*fn)(void *), n; 143 CHOOSE_MODE(release_thread_tt(task), release_thread_skas(task));
49 void *arg; 144}
50 145
51 fn = current->thread.request.u.thread.proc; 146void exit_thread(void)
52 arg = current->thread.request.u.thread.arg; 147{
53 os_usr1_signal(1); 148 unprotect_stack((unsigned long) current_thread);
54 thread_wait(&current->thread.mode.skas.switch_buf, 149}
55 current->thread.mode.skas.fork_buf);
56 150
57 if(current->thread.prev_sched != NULL) 151void *get_current(void)
58 schedule_tail(current->thread.prev_sched); 152{
59 current->thread.prev_sched = NULL; 153 return(current);
154}
155
156int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
157 unsigned long stack_top, struct task_struct * p,
158 struct pt_regs *regs)
159{
160 int ret;
60 161
61 /* The return value is 1 if the kernel thread execs a process, 162 p->thread = (struct thread_struct) INIT_THREAD;
62 * 0 if it just exits 163 ret = CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr,
164 clone_flags, sp, stack_top, p, regs);
165
166 if (ret || !current->thread.forking)
167 goto out;
168
169 clear_flushed_tls(p);
170
171 /*
172 * Set a new TLS for the child thread?
63 */ 173 */
64 n = run_kernel_thread(fn, arg, &current->thread.exec_buf); 174 if (clone_flags & CLONE_SETTLS)
65 if(n == 1){ 175 ret = arch_copy_tls(p);
66 /* Handle any immediate reschedules or signals */ 176
67 interrupt_end(); 177out:
68 userspace(&current->thread.regs.regs); 178 return ret;
179}
180
181void initial_thread_cb(void (*proc)(void *), void *arg)
182{
183 int save_kmalloc_ok = kmalloc_ok;
184
185 kmalloc_ok = 0;
186 CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc,
187 arg);
188 kmalloc_ok = save_kmalloc_ok;
189}
190
191unsigned long stack_sp(unsigned long page)
192{
193 return(page + PAGE_SIZE - sizeof(void *));
194}
195
196int current_pid(void)
197{
198 return(current->pid);
199}
200
201void default_idle(void)
202{
203 CHOOSE_MODE(uml_idle_timer(), (void) 0);
204
205 while(1){
206 /* endless idle loop with no priority at all */
207
208 /*
209 * although we are an idle CPU, we do not want to
210 * get into the scheduler unnecessarily.
211 */
212 if(need_resched())
213 schedule();
214
215 idle_sleep(10);
69 } 216 }
70 else do_exit(0);
71} 217}
72 218
73void new_thread_proc(void *stack, void (*handler)(int sig)) 219void cpu_idle(void)
74{ 220{
75 init_new_thread_stack(stack, handler); 221 CHOOSE_MODE(init_idle_tt(), init_idle_skas());
76 os_usr1_process(os_getpid());
77} 222}
78 223
79void release_thread_skas(struct task_struct *task) 224int page_size(void)
80{ 225{
226 return(PAGE_SIZE);
81} 227}
82 228
83void fork_handler(int sig) 229void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
230 pte_t *pte_out)
84{ 231{
85 os_usr1_signal(1); 232 pgd_t *pgd;
86 thread_wait(&current->thread.mode.skas.switch_buf, 233 pud_t *pud;
87 current->thread.mode.skas.fork_buf); 234 pmd_t *pmd;
88 235 pte_t *pte;
89 force_flush_all(); 236 pte_t ptent;
90 if(current->thread.prev_sched == NULL) 237
91 panic("blech"); 238 if(task->mm == NULL)
239 return(ERR_PTR(-EINVAL));
240 pgd = pgd_offset(task->mm, addr);
241 if(!pgd_present(*pgd))
242 return(ERR_PTR(-EINVAL));
243
244 pud = pud_offset(pgd, addr);
245 if(!pud_present(*pud))
246 return(ERR_PTR(-EINVAL));
247
248 pmd = pmd_offset(pud, addr);
249 if(!pmd_present(*pmd))
250 return(ERR_PTR(-EINVAL));
251
252 pte = pte_offset_kernel(pmd, addr);
253 ptent = *pte;
254 if(!pte_present(ptent))
255 return(ERR_PTR(-EINVAL));
256
257 if(pte_out != NULL)
258 *pte_out = ptent;
259 return((void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK));
260}
92 261
93 schedule_tail(current->thread.prev_sched); 262char *current_cmd(void)
263{
264#if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM)
265 return("(Unknown)");
266#else
267 void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL);
268 return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr);
269#endif
270}
94 271
95 /* XXX: if interrupt_end() calls schedule, this call to 272void force_sigbus(void)
96 * arch_switch_to_skas isn't needed. We could want to apply this to 273{
97 * improve performance. -bb */ 274 printk(KERN_ERR "Killing pid %d because of a lack of memory\n",
98 arch_switch_to_skas(current->thread.prev_sched, current); 275 current->pid);
276 lock_kernel();
277 sigaddset(&current->pending.signal, SIGBUS);
278 recalc_sigpending();
279 current->flags |= PF_SIGNALED;
280 do_exit(SIGBUS | 0x80);
281}
99 282
100 current->thread.prev_sched = NULL; 283void dump_thread(struct pt_regs *regs, struct user *u)
284{
285}
101 286
102/* Handle any immediate reschedules or signals */ 287void enable_hlt(void)
103 interrupt_end(); 288{
289 panic("enable_hlt");
290}
291
292EXPORT_SYMBOL(enable_hlt);
104 293
105 userspace(&current->thread.regs.regs); 294void disable_hlt(void)
295{
296 panic("disable_hlt");
106} 297}
107 298
108int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp, 299EXPORT_SYMBOL(disable_hlt);
109 unsigned long stack_top, struct task_struct * p, 300
110 struct pt_regs *regs) 301void *um_kmalloc(int size)
111{ 302{
112 void (*handler)(int); 303 return kmalloc(size, GFP_KERNEL);
304}
113 305
114 if(current->thread.forking){ 306void *um_kmalloc_atomic(int size)
115 memcpy(&p->thread.regs.regs.skas, &regs->regs.skas, 307{
116 sizeof(p->thread.regs.regs.skas)); 308 return kmalloc(size, GFP_ATOMIC);
117 REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0); 309}
118 if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp;
119 310
120 handler = fork_handler; 311void *um_vmalloc(int size)
312{
313 return vmalloc(size);
314}
121 315
122 arch_copy_thread(&current->thread.arch, &p->thread.arch); 316void *um_vmalloc_atomic(int size)
123 } 317{
124 else { 318 return __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM, PAGE_KERNEL);
125 init_thread_registers(&p->thread.regs.regs); 319}
126 p->thread.request.u.thread = current->thread.request.u.thread;
127 handler = new_thread_handler;
128 }
129 320
130 new_thread(task_stack_page(p), &p->thread.mode.skas.switch_buf, 321int __cant_sleep(void) {
131 &p->thread.mode.skas.fork_buf, handler); 322 return in_atomic() || irqs_disabled() || in_interrupt();
132 return(0); 323 /* Is in_interrupt() really needed? */
324}
325
326unsigned long get_fault_addr(void)
327{
328 return((unsigned long) current->thread.fault_addr);
133} 329}
134 330
135int new_mm(unsigned long stack) 331EXPORT_SYMBOL(get_fault_addr);
332
333void not_implemented(void)
136{ 334{
137 int fd; 335 printk(KERN_DEBUG "Something isn't implemented in here\n");
336}
138 337
139 fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0); 338EXPORT_SYMBOL(not_implemented);
140 if(fd < 0)
141 return(fd);
142 339
143 if(skas_needs_stub) 340int user_context(unsigned long sp)
144 map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack); 341{
342 unsigned long stack;
145 343
146 return(fd); 344 stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER);
345 return(stack != (unsigned long) current_thread);
147} 346}
148 347
149void init_idle_skas(void) 348extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end;
349
350void do_uml_exitcalls(void)
150{ 351{
151 cpu_tasks[current_thread->cpu].pid = os_getpid(); 352 exitcall_t *call;
152 default_idle(); 353
354 call = &__uml_exitcall_end;
355 while (--call >= &__uml_exitcall_begin)
356 (*call)();
153} 357}
154 358
155extern void start_kernel(void); 359char *uml_strdup(char *string)
360{
361 return kstrdup(string, GFP_KERNEL);
362}
156 363
157static int start_kernel_proc(void *unused) 364int copy_to_user_proc(void __user *to, void *from, int size)
158{ 365{
159 int pid; 366 return(copy_to_user(to, from, size));
367}
368
369int copy_from_user_proc(void *to, void __user *from, int size)
370{
371 return(copy_from_user(to, from, size));
372}
373
374int clear_user_proc(void __user *buf, int size)
375{
376 return(clear_user(buf, size));
377}
160 378
161 block_signals(); 379int strlen_user_proc(char __user *str)
162 pid = os_getpid(); 380{
381 return(strlen_user(str));
382}
163 383
164 cpu_tasks[0].pid = pid; 384int smp_sigio_handler(void)
165 cpu_tasks[0].task = current; 385{
166#ifdef CONFIG_SMP 386#ifdef CONFIG_SMP
167 cpu_online_map = cpumask_of_cpu(0); 387 int cpu = current_thread->cpu;
388 IPI_handler(cpu);
389 if(cpu != 0)
390 return(1);
168#endif 391#endif
169 start_kernel();
170 return(0); 392 return(0);
171} 393}
172 394
173extern int userspace_pid[]; 395int cpu(void)
174
175int start_uml_skas(void)
176{ 396{
177 if(proc_mm) 397 return(current_thread->cpu);
178 userspace_pid[0] = start_userspace(0); 398}
399
400static atomic_t using_sysemu = ATOMIC_INIT(0);
401int sysemu_supported;
179 402
180 init_new_thread_signals(); 403void set_using_sysemu(int value)
404{
405 if (value > sysemu_supported)
406 return;
407 atomic_set(&using_sysemu, value);
408}
181 409
182 init_task.thread.request.u.thread.proc = start_kernel_proc; 410int get_using_sysemu(void)
183 init_task.thread.request.u.thread.arg = NULL; 411{
184 return(start_idle_thread(task_stack_page(&init_task), 412 return atomic_read(&using_sysemu);
185 &init_task.thread.mode.skas.switch_buf,
186 &init_task.thread.mode.skas.fork_buf));
187} 413}
188 414
189int external_pid_skas(struct task_struct *task) 415static int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data)
190{ 416{
191#warning Need to look up userspace_pid by cpu 417 if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size) /*No overflow*/
192 return(userspace_pid[0]); 418 *eof = 1;
419
420 return strlen(buf);
193} 421}
194 422
195int thread_pid_skas(struct task_struct *task) 423static int proc_write_sysemu(struct file *file,const char __user *buf, unsigned long count,void *data)
196{ 424{
197#warning Need to look up userspace_pid by cpu 425 char tmp[2];
198 return(userspace_pid[0]); 426
427 if (copy_from_user(tmp, buf, 1))
428 return -EFAULT;
429
430 if (tmp[0] >= '0' && tmp[0] <= '2')
431 set_using_sysemu(tmp[0] - '0');
432 return count; /*We use the first char, but pretend to write everything*/
199} 433}
200 434
201void kill_off_processes_skas(void) 435int __init make_proc_sysemu(void)
202{ 436{
203 if(proc_mm) 437 struct proc_dir_entry *ent;
204#warning need to loop over userspace_pids in kill_off_processes_skas 438 if (!sysemu_supported)
205 os_kill_ptraced_process(userspace_pid[0], 1); 439 return 0;
206 else {
207 struct task_struct *p;
208 int pid, me;
209 440
210 me = os_getpid(); 441 ent = create_proc_entry("sysemu", 0600, &proc_root);
211 for_each_process(p){
212 if(p->mm == NULL)
213 continue;
214 442
215 pid = p->mm->context.skas.id.u.pid; 443 if (ent == NULL)
216 os_kill_ptraced_process(pid, 1); 444 {
217 } 445 printk(KERN_WARNING "Failed to register /proc/sysemu\n");
446 return(0);
218 } 447 }
448
449 ent->read_proc = proc_read_sysemu;
450 ent->write_proc = proc_write_sysemu;
451
452 return 0;
219} 453}
220 454
221unsigned long current_stub_stack(void) 455late_initcall(make_proc_sysemu);
456
457int singlestepping(void * t)
222{ 458{
223 if(current->mm == NULL) 459 struct task_struct *task = t ? t : current;
460
461 if ( ! (task->ptrace & PT_DTRACE) )
224 return(0); 462 return(0);
225 463
226 return(current->mm->context.skas.id.stack); 464 if (task->thread.singlestep_syscall)
465 return(1);
466
467 return 2;
468}
469
470/*
471 * Only x86 and x86_64 have an arch_align_stack().
472 * All other arches have "#define arch_align_stack(x) (x)"
473 * in their asm/system.h
474 * As this is included in UML from asm-um/system-generic.h,
475 * we can use it to behave as the subarch does.
476 */
477#ifndef arch_align_stack
478unsigned long arch_align_stack(unsigned long sp)
479{
480 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
481 sp -= get_random_int() % 8192;
482 return sp & ~0xf;
227} 483}
484#endif
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index 552ca1cb9847..820affbf3e16 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -35,9 +35,6 @@ unsigned long long sched_clock(void)
35 return (unsigned long long)jiffies_64 * (1000000000 / HZ); 35 return (unsigned long long)jiffies_64 * (1000000000 / HZ);
36} 36}
37 37
38/* Changed at early boot */
39int timer_irq_inited = 0;
40
41static unsigned long long prev_nsecs; 38static unsigned long long prev_nsecs;
42#ifdef CONFIG_UML_REAL_TIME_CLOCK 39#ifdef CONFIG_UML_REAL_TIME_CLOCK
43static long long delta; /* Deviation per interval */ 40static long long delta; /* Deviation per interval */
@@ -98,7 +95,7 @@ irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
98 95
99 do_timer(regs); 96 do_timer(regs);
100 97
101 nsecs = get_time() + local_offset; 98 nsecs = get_time();
102 xtime.tv_sec = nsecs / NSEC_PER_SEC; 99 xtime.tv_sec = nsecs / NSEC_PER_SEC;
103 xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC; 100 xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC;
104 101
@@ -113,12 +110,13 @@ static void register_timer(void)
113 110
114 err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL); 111 err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL);
115 if(err != 0) 112 if(err != 0)
116 printk(KERN_ERR "timer_init : request_irq failed - " 113 printk(KERN_ERR "register_timer : request_irq failed - "
117 "errno = %d\n", -err); 114 "errno = %d\n", -err);
118 115
119 timer_irq_inited = 1; 116 err = set_interval(1);
120 117 if(err != 0)
121 user_time_init(); 118 printk(KERN_ERR "register_timer : set_interval failed - "
119 "errno = %d\n", -err);
122} 120}
123 121
124extern void (*late_time_init)(void); 122extern void (*late_time_init)(void);
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index f5b0636f9ad7..54a5ff25645a 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -16,12 +16,12 @@
16#include "os.h" 16#include "os.h"
17 17
18static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, 18static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
19 int r, int w, int x, struct host_vm_op *ops, int *index, 19 int r, int w, int x, struct host_vm_op *ops, int *index,
20 int last_filled, union mm_context *mmu, void **flush, 20 int last_filled, union mm_context *mmu, void **flush,
21 int (*do_ops)(union mm_context *, struct host_vm_op *, 21 int (*do_ops)(union mm_context *, struct host_vm_op *,
22 int, int, void **)) 22 int, int, void **))
23{ 23{
24 __u64 offset; 24 __u64 offset;
25 struct host_vm_op *last; 25 struct host_vm_op *last;
26 int fd, ret = 0; 26 int fd, ret = 0;
27 27
@@ -89,7 +89,7 @@ static int add_munmap(unsigned long addr, unsigned long len,
89static int add_mprotect(unsigned long addr, unsigned long len, int r, int w, 89static int add_mprotect(unsigned long addr, unsigned long len, int r, int w,
90 int x, struct host_vm_op *ops, int *index, 90 int x, struct host_vm_op *ops, int *index,
91 int last_filled, union mm_context *mmu, void **flush, 91 int last_filled, union mm_context *mmu, void **flush,
92 int (*do_ops)(union mm_context *, struct host_vm_op *, 92 int (*do_ops)(union mm_context *, struct host_vm_op *,
93 int, int, void **)) 93 int, int, void **))
94{ 94{
95 struct host_vm_op *last; 95 struct host_vm_op *last;
@@ -124,105 +124,105 @@ static int add_mprotect(unsigned long addr, unsigned long len, int r, int w,
124#define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1)) 124#define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1))
125 125
126void fix_range_common(struct mm_struct *mm, unsigned long start_addr, 126void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
127 unsigned long end_addr, int force, 127 unsigned long end_addr, int force,
128 int (*do_ops)(union mm_context *, struct host_vm_op *, 128 int (*do_ops)(union mm_context *, struct host_vm_op *,
129 int, int, void **)) 129 int, int, void **))
130{ 130{
131 pgd_t *npgd; 131 pgd_t *npgd;
132 pud_t *npud; 132 pud_t *npud;
133 pmd_t *npmd; 133 pmd_t *npmd;
134 pte_t *npte; 134 pte_t *npte;
135 union mm_context *mmu = &mm->context; 135 union mm_context *mmu = &mm->context;
136 unsigned long addr, end; 136 unsigned long addr, end;
137 int r, w, x; 137 int r, w, x;
138 struct host_vm_op ops[1]; 138 struct host_vm_op ops[1];
139 void *flush = NULL; 139 void *flush = NULL;
140 int op_index = -1, last_op = sizeof(ops) / sizeof(ops[0]) - 1; 140 int op_index = -1, last_op = ARRAY_SIZE(ops) - 1;
141 int ret = 0; 141 int ret = 0;
142 142
143 if(mm == NULL) return; 143 if(mm == NULL)
144 144 return;
145 ops[0].type = NONE; 145
146 for(addr = start_addr; addr < end_addr && !ret;){ 146 ops[0].type = NONE;
147 npgd = pgd_offset(mm, addr); 147 for(addr = start_addr; addr < end_addr && !ret;){
148 if(!pgd_present(*npgd)){ 148 npgd = pgd_offset(mm, addr);
149 end = ADD_ROUND(addr, PGDIR_SIZE); 149 if(!pgd_present(*npgd)){
150 if(end > end_addr) 150 end = ADD_ROUND(addr, PGDIR_SIZE);
151 end = end_addr; 151 if(end > end_addr)
152 if(force || pgd_newpage(*npgd)){ 152 end = end_addr;
153 ret = add_munmap(addr, end - addr, ops, 153 if(force || pgd_newpage(*npgd)){
154 &op_index, last_op, mmu, 154 ret = add_munmap(addr, end - addr, ops,
155 &flush, do_ops); 155 &op_index, last_op, mmu,
156 pgd_mkuptodate(*npgd); 156 &flush, do_ops);
157 } 157 pgd_mkuptodate(*npgd);
158 addr = end; 158 }
159 continue; 159 addr = end;
160 } 160 continue;
161 161 }
162 npud = pud_offset(npgd, addr); 162
163 if(!pud_present(*npud)){ 163 npud = pud_offset(npgd, addr);
164 end = ADD_ROUND(addr, PUD_SIZE); 164 if(!pud_present(*npud)){
165 if(end > end_addr) 165 end = ADD_ROUND(addr, PUD_SIZE);
166 end = end_addr; 166 if(end > end_addr)
167 if(force || pud_newpage(*npud)){ 167 end = end_addr;
168 ret = add_munmap(addr, end - addr, ops, 168 if(force || pud_newpage(*npud)){
169 &op_index, last_op, mmu, 169 ret = add_munmap(addr, end - addr, ops,
170 &flush, do_ops); 170 &op_index, last_op, mmu,
171 pud_mkuptodate(*npud); 171 &flush, do_ops);
172 } 172 pud_mkuptodate(*npud);
173 addr = end; 173 }
174 continue; 174 addr = end;
175 } 175 continue;
176 176 }
177 npmd = pmd_offset(npud, addr); 177
178 if(!pmd_present(*npmd)){ 178 npmd = pmd_offset(npud, addr);
179 end = ADD_ROUND(addr, PMD_SIZE); 179 if(!pmd_present(*npmd)){
180 if(end > end_addr) 180 end = ADD_ROUND(addr, PMD_SIZE);
181 end = end_addr; 181 if(end > end_addr)
182 if(force || pmd_newpage(*npmd)){ 182 end = end_addr;
183 ret = add_munmap(addr, end - addr, ops, 183 if(force || pmd_newpage(*npmd)){
184 &op_index, last_op, mmu, 184 ret = add_munmap(addr, end - addr, ops,
185 &flush, do_ops); 185 &op_index, last_op, mmu,
186 pmd_mkuptodate(*npmd); 186 &flush, do_ops);
187 } 187 pmd_mkuptodate(*npmd);
188 addr = end; 188 }
189 continue; 189 addr = end;
190 } 190 continue;
191 191 }
192 npte = pte_offset_kernel(npmd, addr); 192
193 r = pte_read(*npte); 193 npte = pte_offset_kernel(npmd, addr);
194 w = pte_write(*npte); 194 r = pte_read(*npte);
195 x = pte_exec(*npte); 195 w = pte_write(*npte);
196 x = pte_exec(*npte);
196 if (!pte_young(*npte)) { 197 if (!pte_young(*npte)) {
197 r = 0; 198 r = 0;
198 w = 0; 199 w = 0;
199 } else if (!pte_dirty(*npte)) { 200 } else if (!pte_dirty(*npte)) {
200 w = 0; 201 w = 0;
201 } 202 }
202 if(force || pte_newpage(*npte)){ 203 if(force || pte_newpage(*npte)){
203 if(pte_present(*npte)) 204 if(pte_present(*npte))
204 ret = add_mmap(addr, 205 ret = add_mmap(addr,
205 pte_val(*npte) & PAGE_MASK, 206 pte_val(*npte) & PAGE_MASK,
206 PAGE_SIZE, r, w, x, ops, 207 PAGE_SIZE, r, w, x, ops,
207 &op_index, last_op, mmu, 208 &op_index, last_op, mmu,
208 &flush, do_ops); 209 &flush, do_ops);
209 else ret = add_munmap(addr, PAGE_SIZE, ops, 210 else ret = add_munmap(addr, PAGE_SIZE, ops,
210 &op_index, last_op, mmu, 211 &op_index, last_op, mmu,
211 &flush, do_ops); 212 &flush, do_ops);
212 } 213 }
213 else if(pte_newprot(*npte)) 214 else if(pte_newprot(*npte))
214 ret = add_mprotect(addr, PAGE_SIZE, r, w, x, ops, 215 ret = add_mprotect(addr, PAGE_SIZE, r, w, x, ops,
215 &op_index, last_op, mmu, 216 &op_index, last_op, mmu,
216 &flush, do_ops); 217 &flush, do_ops);
217 218
218 *npte = pte_mkuptodate(*npte); 219 *npte = pte_mkuptodate(*npte);
219 addr += PAGE_SIZE; 220 addr += PAGE_SIZE;
220 } 221 }
221
222 if(!ret) 222 if(!ret)
223 ret = (*do_ops)(mmu, ops, op_index, 1, &flush); 223 ret = (*do_ops)(mmu, ops, op_index, 1, &flush);
224 224
225 /* This is not an else because ret is modified above */ 225/* This is not an else because ret is modified above */
226 if(ret) { 226 if(ret) {
227 printk("fix_range_common: failed, killing current process\n"); 227 printk("fix_range_common: failed, killing current process\n");
228 force_sig(SIGKILL, current); 228 force_sig(SIGKILL, current);
@@ -231,160 +231,160 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
231 231
232int flush_tlb_kernel_range_common(unsigned long start, unsigned long end) 232int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
233{ 233{
234 struct mm_struct *mm; 234 struct mm_struct *mm;
235 pgd_t *pgd; 235 pgd_t *pgd;
236 pud_t *pud; 236 pud_t *pud;
237 pmd_t *pmd; 237 pmd_t *pmd;
238 pte_t *pte; 238 pte_t *pte;
239 unsigned long addr, last; 239 unsigned long addr, last;
240 int updated = 0, err; 240 int updated = 0, err;
241 241
242 mm = &init_mm; 242 mm = &init_mm;
243 for(addr = start; addr < end;){ 243 for(addr = start; addr < end;){
244 pgd = pgd_offset(mm, addr); 244 pgd = pgd_offset(mm, addr);
245 if(!pgd_present(*pgd)){ 245 if(!pgd_present(*pgd)){
246 last = ADD_ROUND(addr, PGDIR_SIZE); 246 last = ADD_ROUND(addr, PGDIR_SIZE);
247 if(last > end) 247 if(last > end)
248 last = end; 248 last = end;
249 if(pgd_newpage(*pgd)){ 249 if(pgd_newpage(*pgd)){
250 updated = 1; 250 updated = 1;
251 err = os_unmap_memory((void *) addr, 251 err = os_unmap_memory((void *) addr,
252 last - addr); 252 last - addr);
253 if(err < 0) 253 if(err < 0)
254 panic("munmap failed, errno = %d\n", 254 panic("munmap failed, errno = %d\n",
255 -err); 255 -err);
256 } 256 }
257 addr = last; 257 addr = last;
258 continue; 258 continue;
259 } 259 }
260 260
261 pud = pud_offset(pgd, addr); 261 pud = pud_offset(pgd, addr);
262 if(!pud_present(*pud)){ 262 if(!pud_present(*pud)){
263 last = ADD_ROUND(addr, PUD_SIZE); 263 last = ADD_ROUND(addr, PUD_SIZE);
264 if(last > end) 264 if(last > end)
265 last = end; 265 last = end;
266 if(pud_newpage(*pud)){ 266 if(pud_newpage(*pud)){
267 updated = 1; 267 updated = 1;
268 err = os_unmap_memory((void *) addr, 268 err = os_unmap_memory((void *) addr,
269 last - addr); 269 last - addr);
270 if(err < 0) 270 if(err < 0)
271 panic("munmap failed, errno = %d\n", 271 panic("munmap failed, errno = %d\n",
272 -err); 272 -err);
273 } 273 }
274 addr = last; 274 addr = last;
275 continue; 275 continue;
276 } 276 }
277 277
278 pmd = pmd_offset(pud, addr); 278 pmd = pmd_offset(pud, addr);
279 if(!pmd_present(*pmd)){ 279 if(!pmd_present(*pmd)){
280 last = ADD_ROUND(addr, PMD_SIZE); 280 last = ADD_ROUND(addr, PMD_SIZE);
281 if(last > end) 281 if(last > end)
282 last = end; 282 last = end;
283 if(pmd_newpage(*pmd)){ 283 if(pmd_newpage(*pmd)){
284 updated = 1; 284 updated = 1;
285 err = os_unmap_memory((void *) addr, 285 err = os_unmap_memory((void *) addr,
286 last - addr); 286 last - addr);
287 if(err < 0) 287 if(err < 0)
288 panic("munmap failed, errno = %d\n", 288 panic("munmap failed, errno = %d\n",
289 -err); 289 -err);
290 } 290 }
291 addr = last; 291 addr = last;
292 continue; 292 continue;
293 } 293 }
294 294
295 pte = pte_offset_kernel(pmd, addr); 295 pte = pte_offset_kernel(pmd, addr);
296 if(!pte_present(*pte) || pte_newpage(*pte)){ 296 if(!pte_present(*pte) || pte_newpage(*pte)){
297 updated = 1; 297 updated = 1;
298 err = os_unmap_memory((void *) addr, 298 err = os_unmap_memory((void *) addr,
299 PAGE_SIZE); 299 PAGE_SIZE);
300 if(err < 0) 300 if(err < 0)
301 panic("munmap failed, errno = %d\n", 301 panic("munmap failed, errno = %d\n",
302 -err); 302 -err);
303 if(pte_present(*pte)) 303 if(pte_present(*pte))
304 map_memory(addr, 304 map_memory(addr,
305 pte_val(*pte) & PAGE_MASK, 305 pte_val(*pte) & PAGE_MASK,
306 PAGE_SIZE, 1, 1, 1); 306 PAGE_SIZE, 1, 1, 1);
307 } 307 }
308 else if(pte_newprot(*pte)){ 308 else if(pte_newprot(*pte)){
309 updated = 1; 309 updated = 1;
310 os_protect_memory((void *) addr, PAGE_SIZE, 1, 1, 1); 310 os_protect_memory((void *) addr, PAGE_SIZE, 1, 1, 1);
311 } 311 }
312 addr += PAGE_SIZE; 312 addr += PAGE_SIZE;
313 } 313 }
314 return(updated); 314 return(updated);
315} 315}
316 316
317pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address) 317pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
318{ 318{
319 return(pgd_offset(mm, address)); 319 return(pgd_offset(mm, address));
320} 320}
321 321
322pud_t *pud_offset_proc(pgd_t *pgd, unsigned long address) 322pud_t *pud_offset_proc(pgd_t *pgd, unsigned long address)
323{ 323{
324 return(pud_offset(pgd, address)); 324 return(pud_offset(pgd, address));
325} 325}
326 326
327pmd_t *pmd_offset_proc(pud_t *pud, unsigned long address) 327pmd_t *pmd_offset_proc(pud_t *pud, unsigned long address)
328{ 328{
329 return(pmd_offset(pud, address)); 329 return(pmd_offset(pud, address));
330} 330}
331 331
332pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address) 332pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address)
333{ 333{
334 return(pte_offset_kernel(pmd, address)); 334 return(pte_offset_kernel(pmd, address));
335} 335}
336 336
337pte_t *addr_pte(struct task_struct *task, unsigned long addr) 337pte_t *addr_pte(struct task_struct *task, unsigned long addr)
338{ 338{
339 pgd_t *pgd = pgd_offset(task->mm, addr); 339 pgd_t *pgd = pgd_offset(task->mm, addr);
340 pud_t *pud = pud_offset(pgd, addr); 340 pud_t *pud = pud_offset(pgd, addr);
341 pmd_t *pmd = pmd_offset(pud, addr); 341 pmd_t *pmd = pmd_offset(pud, addr);
342 342
343 return(pte_offset_map(pmd, addr)); 343 return(pte_offset_map(pmd, addr));
344} 344}
345 345
346void flush_tlb_page(struct vm_area_struct *vma, unsigned long address) 346void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
347{ 347{
348 address &= PAGE_MASK; 348 address &= PAGE_MASK;
349 flush_tlb_range(vma, address, address + PAGE_SIZE); 349 flush_tlb_range(vma, address, address + PAGE_SIZE);
350} 350}
351 351
352void flush_tlb_all(void) 352void flush_tlb_all(void)
353{ 353{
354 flush_tlb_mm(current->mm); 354 flush_tlb_mm(current->mm);
355} 355}
356 356
357void flush_tlb_kernel_range(unsigned long start, unsigned long end) 357void flush_tlb_kernel_range(unsigned long start, unsigned long end)
358{ 358{
359 CHOOSE_MODE_PROC(flush_tlb_kernel_range_tt, 359 CHOOSE_MODE_PROC(flush_tlb_kernel_range_tt,
360 flush_tlb_kernel_range_common, start, end); 360 flush_tlb_kernel_range_common, start, end);
361} 361}
362 362
363void flush_tlb_kernel_vm(void) 363void flush_tlb_kernel_vm(void)
364{ 364{
365 CHOOSE_MODE(flush_tlb_kernel_vm_tt(), 365 CHOOSE_MODE(flush_tlb_kernel_vm_tt(),
366 flush_tlb_kernel_range_common(start_vm, end_vm)); 366 flush_tlb_kernel_range_common(start_vm, end_vm));
367} 367}
368 368
369void __flush_tlb_one(unsigned long addr) 369void __flush_tlb_one(unsigned long addr)
370{ 370{
371 CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr); 371 CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr);
372} 372}
373 373
374void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, 374void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
375 unsigned long end) 375 unsigned long end)
376{ 376{
377 CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, vma, start, 377 CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, vma, start,
378 end); 378 end);
379} 379}
380 380
381void flush_tlb_mm(struct mm_struct *mm) 381void flush_tlb_mm(struct mm_struct *mm)
382{ 382{
383 CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm); 383 CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm);
384} 384}
385 385
386void force_flush_all(void) 386void force_flush_all(void)
387{ 387{
388 CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas()); 388 CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas());
389} 389}
390 390
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index ac70fa5a2e2a..61a23fff4395 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -140,14 +140,6 @@ void segv_handler(int sig, union uml_pt_regs *regs)
140 segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs); 140 segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs);
141} 141}
142 142
143struct kern_handlers handlinfo_kern = {
144 .relay_signal = relay_signal,
145 .winch = winch,
146 .bus_handler = relay_signal,
147 .page_fault = segv_handler,
148 .sigio_handler = sigio_handler,
149 .timer_handler = timer_handler
150};
151/* 143/*
152 * We give a *copy* of the faultinfo in the regs to segv. 144 * We give a *copy* of the faultinfo in the regs to segv.
153 * This must be done, since nesting SEGVs could overwrite 145 * This must be done, since nesting SEGVs could overwrite
@@ -227,9 +219,16 @@ void bad_segv(struct faultinfo fi, unsigned long ip)
227 219
228void relay_signal(int sig, union uml_pt_regs *regs) 220void relay_signal(int sig, union uml_pt_regs *regs)
229{ 221{
230 if(arch_handle_signal(sig, regs)) return; 222 if(arch_handle_signal(sig, regs))
231 if(!UPT_IS_USER(regs)) 223 return;
224
225 if(!UPT_IS_USER(regs)){
226 if(sig == SIGBUS)
227 printk("Bus error - the /dev/shm or /tmp mount likely "
228 "just ran out of space\n");
232 panic("Kernel mode signal %d", sig); 229 panic("Kernel mode signal %d", sig);
230 }
231
233 current->thread.arch.faultinfo = *UPT_FAULTINFO(regs); 232 current->thread.arch.faultinfo = *UPT_FAULTINFO(regs);
234 force_sig(sig, current); 233 force_sig(sig, current);
235} 234}
@@ -246,6 +245,15 @@ void winch(int sig, union uml_pt_regs *regs)
246 do_IRQ(WINCH_IRQ, regs); 245 do_IRQ(WINCH_IRQ, regs);
247} 246}
248 247
248const struct kern_handlers handlinfo_kern = {
249 .relay_signal = relay_signal,
250 .winch = winch,
251 .bus_handler = bus_handler,
252 .page_fault = segv_handler,
253 .sigio_handler = sigio_handler,
254 .timer_handler = timer_handler
255};
256
249void trap_init(void) 257void trap_init(void)
250{ 258{
251} 259}
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 7896cf98232d..55005710dcbb 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -106,7 +106,7 @@ static void c_stop(struct seq_file *m, void *v)
106{ 106{
107} 107}
108 108
109struct seq_operations cpuinfo_op = { 109const struct seq_operations cpuinfo_op = {
110 .start = c_start, 110 .start = c_start,
111 .next = c_next, 111 .next = c_next,
112 .stop = c_stop, 112 .stop = c_stop,
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index f4bfc4c7ccac..b4183929b32c 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -4,15 +4,19 @@
4# 4#
5 5
6obj-y = aio.o elf_aux.o file.o helper.o irq.o main.o mem.o process.o sigio.o \ 6obj-y = aio.o elf_aux.o file.o helper.o irq.o main.o mem.o process.o sigio.o \
7 signal.o start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o tls.o \ 7 signal.o start_up.o time.o trap.o tty.o uaccess.o umid.o tls.o \
8 user_syms.o util.o drivers/ sys-$(SUBARCH)/ 8 user_syms.o util.o drivers/ sys-$(SUBARCH)/
9 9
10obj-$(CONFIG_MODE_SKAS) += skas/ 10obj-$(CONFIG_MODE_SKAS) += skas/
11
12obj-$(CONFIG_MODE_TT) += tt.o
13user-objs-$(CONFIG_MODE_TT) += tt.o
14
11obj-$(CONFIG_TTY_LOG) += tty_log.o 15obj-$(CONFIG_TTY_LOG) += tty_log.o
12user-objs-$(CONFIG_TTY_LOG) += tty_log.o 16user-objs-$(CONFIG_TTY_LOG) += tty_log.o
13 17
14USER_OBJS := $(user-objs-y) aio.o elf_aux.o file.o helper.o irq.o main.o mem.o \ 18USER_OBJS := $(user-objs-y) aio.o elf_aux.o file.o helper.o irq.o main.o mem.o \
15 process.o sigio.o signal.o start_up.o time.o trap.o tt.o tty.o tls.o \ 19 process.o sigio.o signal.o start_up.o time.o trap.o tty.o tls.o \
16 uaccess.o umid.o util.o 20 uaccess.o umid.o util.o
17 21
18CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH) 22CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH)
diff --git a/arch/um/os-Linux/drivers/etap.h b/arch/um/os-Linux/drivers/etap.h
index b84f6c4740f7..57ecdaf2f67e 100644
--- a/arch/um/os-Linux/drivers/etap.h
+++ b/arch/um/os-Linux/drivers/etap.h
@@ -13,7 +13,7 @@ struct ethertap_data {
13 void *dev; 13 void *dev;
14}; 14};
15 15
16extern struct net_user_info ethertap_user_info; 16extern const struct net_user_info ethertap_user_info;
17 17
18/* 18/*
19 * Overrides for Emacs so that we follow Linus's tabbing style. 19 * Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/arch/um/os-Linux/drivers/ethertap_kern.c b/arch/um/os-Linux/drivers/ethertap_kern.c
index 768606bec233..16385e2ada85 100644
--- a/arch/um/os-Linux/drivers/ethertap_kern.c
+++ b/arch/um/os-Linux/drivers/ethertap_kern.c
@@ -65,7 +65,7 @@ static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp)
65 return(net_send(fd, (*skb)->data, (*skb)->len)); 65 return(net_send(fd, (*skb)->data, (*skb)->len));
66} 66}
67 67
68struct net_kern_info ethertap_kern_info = { 68const struct net_kern_info ethertap_kern_info = {
69 .init = etap_init, 69 .init = etap_init,
70 .protocol = eth_protocol, 70 .protocol = eth_protocol,
71 .read = etap_read, 71 .read = etap_read,
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index 8f49507e64ef..f559bdf746e6 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -216,7 +216,7 @@ static void etap_del_addr(unsigned char *addr, unsigned char *netmask,
216 etap_close_addr(addr, netmask, &pri->control_fd); 216 etap_close_addr(addr, netmask, &pri->control_fd);
217} 217}
218 218
219struct net_user_info ethertap_user_info = { 219const struct net_user_info ethertap_user_info = {
220 .init = etap_user_init, 220 .init = etap_user_init,
221 .open = etap_open, 221 .open = etap_open,
222 .close = etap_close, 222 .close = etap_close,
diff --git a/arch/um/os-Linux/drivers/tuntap.h b/arch/um/os-Linux/drivers/tuntap.h
index 25d4a2868814..d3e8d3af6245 100644
--- a/arch/um/os-Linux/drivers/tuntap.h
+++ b/arch/um/os-Linux/drivers/tuntap.h
@@ -16,7 +16,7 @@ struct tuntap_data {
16 void *dev; 16 void *dev;
17}; 17};
18 18
19extern struct net_user_info tuntap_user_info; 19extern const struct net_user_info tuntap_user_info;
20 20
21#endif 21#endif
22 22
diff --git a/arch/um/os-Linux/drivers/tuntap_kern.c b/arch/um/os-Linux/drivers/tuntap_kern.c
index 190009a6f89c..0edbac63c527 100644
--- a/arch/um/os-Linux/drivers/tuntap_kern.c
+++ b/arch/um/os-Linux/drivers/tuntap_kern.c
@@ -53,7 +53,7 @@ static int tuntap_write(int fd, struct sk_buff **skb,
53 return(net_write(fd, (*skb)->data, (*skb)->len)); 53 return(net_write(fd, (*skb)->data, (*skb)->len));
54} 54}
55 55
56struct net_kern_info tuntap_kern_info = { 56const struct net_kern_info tuntap_kern_info = {
57 .init = tuntap_init, 57 .init = tuntap_init,
58 .protocol = eth_protocol, 58 .protocol = eth_protocol,
59 .read = tuntap_read, 59 .read = tuntap_read,
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
index 87c3aa0252db..e846b23f7558 100644
--- a/arch/um/os-Linux/drivers/tuntap_user.c
+++ b/arch/um/os-Linux/drivers/tuntap_user.c
@@ -205,7 +205,7 @@ static int tuntap_set_mtu(int mtu, void *data)
205 return(mtu); 205 return(mtu);
206} 206}
207 207
208struct net_user_info tuntap_user_info = { 208const struct net_user_info tuntap_user_info = {
209 .init = tuntap_user_init, 209 .init = tuntap_user_init,
210 .open = tuntap_open, 210 .open = tuntap_open,
211 .close = tuntap_close, 211 .close = tuntap_close,
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index 6987d1d247a2..cd15b9df5b5c 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -42,7 +42,7 @@ static int helper_child(void *arg)
42 if(data->pre_exec != NULL) 42 if(data->pre_exec != NULL)
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("helper_child - execve 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);
@@ -62,7 +62,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
62 stack = *stack_out; 62 stack = *stack_out;
63 else stack = alloc_stack(0, __cant_sleep()); 63 else stack = alloc_stack(0, __cant_sleep());
64 if(stack == 0) 64 if(stack == 0)
65 return(-ENOMEM); 65 return -ENOMEM;
66 66
67 ret = os_pipe(fds, 1, 0); 67 ret = os_pipe(fds, 1, 0);
68 if(ret < 0){ 68 if(ret < 0){
@@ -95,16 +95,16 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
95 /* Read the errno value from the child, if the exec failed, or get 0 if 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 * the exec succeeded because the pipe fd was set as close-on-exec. */
97 n = os_read_file(fds[0], &ret, sizeof(ret)); 97 n = os_read_file(fds[0], &ret, sizeof(ret));
98 if (n < 0) { 98 if(n == 0)
99 printk("run_helper : read on pipe failed, ret = %d\n", -n);
100 ret = n;
101 kill(pid, SIGKILL);
102 CATCH_EINTR(waitpid(pid, NULL, 0));
103 } else if(n != 0){
104 CATCH_EINTR(n = waitpid(pid, NULL, 0));
105 ret = -errno;
106 } else {
107 ret = pid; 99 ret = pid;
100 else {
101 if(n < 0){
102 printk("run_helper : read on pipe failed, ret = %d\n",
103 -n);
104 ret = n;
105 kill(pid, SIGKILL);
106 }
107 CATCH_EINTR(waitpid(pid, NULL, 0));
108 } 108 }
109 109
110out_close: 110out_close:
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c
index 7555bf9c33d9..a97206df5b52 100644
--- a/arch/um/os-Linux/irq.c
+++ b/arch/um/os-Linux/irq.c
@@ -132,7 +132,7 @@ void os_set_pollfd(int i, int fd)
132 132
133void os_set_ioignore(void) 133void os_set_ioignore(void)
134{ 134{
135 set_handler(SIGIO, SIG_IGN, 0, -1); 135 signal(SIGIO, SIG_IGN);
136} 136}
137 137
138void init_irq_signals(int on_sigstack) 138void init_irq_signals(int on_sigstack)
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index 90912aaca7aa..d1c5670787dc 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -67,13 +67,32 @@ static __init void do_uml_initcalls(void)
67 67
68static void last_ditch_exit(int sig) 68static void last_ditch_exit(int sig)
69{ 69{
70 signal(SIGINT, SIG_DFL);
71 signal(SIGTERM, SIG_DFL);
72 signal(SIGHUP, SIG_DFL);
73 uml_cleanup(); 70 uml_cleanup();
74 exit(1); 71 exit(1);
75} 72}
76 73
74static void install_fatal_handler(int sig)
75{
76 struct sigaction action;
77
78 /* All signals are enabled in this handler ... */
79 sigemptyset(&action.sa_mask);
80
81 /* ... including the signal being handled, plus we want the
82 * handler reset to the default behavior, so that if an exit
83 * handler is hanging for some reason, the UML will just die
84 * after this signal is sent a second time.
85 */
86 action.sa_flags = SA_RESETHAND | SA_NODEFER;
87 action.sa_restorer = NULL;
88 action.sa_handler = last_ditch_exit;
89 if(sigaction(sig, &action, NULL) < 0){
90 printf("failed to install handler for signal %d - errno = %d\n",
91 errno);
92 exit(1);
93 }
94}
95
77#define UML_LIB_PATH ":/usr/lib/uml" 96#define UML_LIB_PATH ":/usr/lib/uml"
78 97
79static void setup_env_path(void) 98static void setup_env_path(void)
@@ -158,9 +177,12 @@ int main(int argc, char **argv, char **envp)
158 } 177 }
159 new_argv[argc] = NULL; 178 new_argv[argc] = NULL;
160 179
161 set_handler(SIGINT, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); 180 /* Allow these signals to bring down a UML if all other
162 set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); 181 * methods of control fail.
163 set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); 182 */
183 install_fatal_handler(SIGINT);
184 install_fatal_handler(SIGTERM);
185 install_fatal_handler(SIGHUP);
164 186
165 scan_elf_aux( envp); 187 scan_elf_aux( envp);
166 188
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index 560c8063c77c..b170b4704dc4 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -114,14 +114,14 @@ static void which_tmpdir(void)
114 } 114 }
115 115
116 while(1){ 116 while(1){
117 found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), ' '); 117 found = next(fd, buf, ARRAY_SIZE(buf), ' ');
118 if(found != 1) 118 if(found != 1)
119 break; 119 break;
120 120
121 if(!strncmp(buf, "/dev/shm", strlen("/dev/shm"))) 121 if(!strncmp(buf, "/dev/shm", strlen("/dev/shm")))
122 goto found; 122 goto found;
123 123
124 found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), '\n'); 124 found = next(fd, buf, ARRAY_SIZE(buf), '\n');
125 if(found != 1) 125 if(found != 1)
126 break; 126 break;
127 } 127 }
@@ -135,7 +135,7 @@ err:
135 return; 135 return;
136 136
137found: 137found:
138 found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), ' '); 138 found = next(fd, buf, ARRAY_SIZE(buf), ' ');
139 if(found != 1) 139 if(found != 1)
140 goto err; 140 goto err;
141 141
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index b98d3ca2cd1b..ff203625a4bd 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -7,7 +7,6 @@
7#include <stdio.h> 7#include <stdio.h>
8#include <errno.h> 8#include <errno.h>
9#include <signal.h> 9#include <signal.h>
10#include <setjmp.h>
11#include <linux/unistd.h> 10#include <linux/unistd.h>
12#include <sys/mman.h> 11#include <sys/mman.h>
13#include <sys/wait.h> 12#include <sys/wait.h>
@@ -247,7 +246,17 @@ void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
247 set_sigstack(sig_stack, pages * page_size()); 246 set_sigstack(sig_stack, pages * page_size());
248 flags = SA_ONSTACK; 247 flags = SA_ONSTACK;
249 } 248 }
250 if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1); 249 if(usr1_handler){
250 struct sigaction sa;
251
252 sa.sa_handler = usr1_handler;
253 sigemptyset(&sa.sa_mask);
254 sa.sa_flags = flags;
255 sa.sa_restorer = NULL;
256 if(sigaction(SIGUSR1, &sa, NULL) < 0)
257 panic("init_new_thread_stack - sigaction failed - "
258 "errno = %d\n", errno);
259 }
251} 260}
252 261
253void init_new_thread_signals(void) 262void init_new_thread_signals(void)
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
index 0ecac563c7b3..f6457765b17d 100644
--- a/arch/um/os-Linux/sigio.c
+++ b/arch/um/os-Linux/sigio.c
@@ -43,17 +43,9 @@ struct pollfds {
43/* Protected by sigio_lock(). Used by the sigio thread, but the UML thread 43/* Protected by sigio_lock(). Used by the sigio thread, but the UML thread
44 * synchronizes with it. 44 * synchronizes with it.
45 */ 45 */
46static struct pollfds current_poll = { 46static struct pollfds current_poll;
47 .poll = NULL, 47static struct pollfds next_poll;
48 .size = 0, 48static struct pollfds all_sigio_fds;
49 .used = 0
50};
51
52static struct pollfds next_poll = {
53 .poll = NULL,
54 .size = 0,
55 .used = 0
56};
57 49
58static int write_sigio_thread(void *unused) 50static int write_sigio_thread(void *unused)
59{ 51{
@@ -78,7 +70,8 @@ static int write_sigio_thread(void *unused)
78 n = os_read_file(sigio_private[1], &c, sizeof(c)); 70 n = os_read_file(sigio_private[1], &c, sizeof(c));
79 if(n != sizeof(c)) 71 if(n != sizeof(c))
80 printk("write_sigio_thread : " 72 printk("write_sigio_thread : "
81 "read failed, err = %d\n", -n); 73 "read on socket failed, "
74 "err = %d\n", -n);
82 tmp = current_poll; 75 tmp = current_poll;
83 current_poll = next_poll; 76 current_poll = next_poll;
84 next_poll = tmp; 77 next_poll = tmp;
@@ -93,35 +86,36 @@ static int write_sigio_thread(void *unused)
93 86
94 n = os_write_file(respond_fd, &c, sizeof(c)); 87 n = os_write_file(respond_fd, &c, sizeof(c));
95 if(n != sizeof(c)) 88 if(n != sizeof(c))
96 printk("write_sigio_thread : write failed, " 89 printk("write_sigio_thread : write on socket "
97 "err = %d\n", -n); 90 "failed, err = %d\n", -n);
98 } 91 }
99 } 92 }
100 93
101 return 0; 94 return 0;
102} 95}
103 96
104static int need_poll(int n) 97static int need_poll(struct pollfds *polls, int n)
105{ 98{
106 if(n <= next_poll.size){ 99 if(n <= polls->size){
107 next_poll.used = n; 100 polls->used = n;
108 return(0); 101 return 0;
109 } 102 }
110 kfree(next_poll.poll); 103 kfree(polls->poll);
111 next_poll.poll = um_kmalloc_atomic(n * sizeof(struct pollfd)); 104 polls->poll = um_kmalloc_atomic(n * sizeof(struct pollfd));
112 if(next_poll.poll == NULL){ 105 if(polls->poll == NULL){
113 printk("need_poll : failed to allocate new pollfds\n"); 106 printk("need_poll : failed to allocate new pollfds\n");
114 next_poll.size = 0; 107 polls->size = 0;
115 next_poll.used = 0; 108 polls->used = 0;
116 return(-1); 109 return -ENOMEM;
117 } 110 }
118 next_poll.size = n; 111 polls->size = n;
119 next_poll.used = n; 112 polls->used = n;
120 return(0); 113 return 0;
121} 114}
122 115
123/* Must be called with sigio_lock held, because it's needed by the marked 116/* Must be called with sigio_lock held, because it's needed by the marked
124 * critical section. */ 117 * critical section.
118 */
125static void update_thread(void) 119static void update_thread(void)
126{ 120{
127 unsigned long flags; 121 unsigned long flags;
@@ -156,34 +150,39 @@ static void update_thread(void)
156 set_signals(flags); 150 set_signals(flags);
157} 151}
158 152
159static int add_sigio_fd(int fd, int read) 153int add_sigio_fd(int fd)
160{ 154{
161 int err = 0, i, n, events; 155 struct pollfd *p;
156 int err = 0, i, n;
162 157
163 sigio_lock(); 158 sigio_lock();
159 for(i = 0; i < all_sigio_fds.used; i++){
160 if(all_sigio_fds.poll[i].fd == fd)
161 break;
162 }
163 if(i == all_sigio_fds.used)
164 goto out;
165
166 p = &all_sigio_fds.poll[i];
167
164 for(i = 0; i < current_poll.used; i++){ 168 for(i = 0; i < current_poll.used; i++){
165 if(current_poll.poll[i].fd == fd) 169 if(current_poll.poll[i].fd == fd)
166 goto out; 170 goto out;
167 } 171 }
168 172
169 n = current_poll.used + 1; 173 n = current_poll.used + 1;
170 err = need_poll(n); 174 err = need_poll(&next_poll, n);
171 if(err) 175 if(err)
172 goto out; 176 goto out;
173 177
174 for(i = 0; i < current_poll.used; i++) 178 for(i = 0; i < current_poll.used; i++)
175 next_poll.poll[i] = current_poll.poll[i]; 179 next_poll.poll[i] = current_poll.poll[i];
176 180
177 if(read) events = POLLIN; 181 next_poll.poll[n - 1] = *p;
178 else events = POLLOUT;
179
180 next_poll.poll[n - 1] = ((struct pollfd) { .fd = fd,
181 .events = events,
182 .revents = 0 });
183 update_thread(); 182 update_thread();
184 out: 183 out:
185 sigio_unlock(); 184 sigio_unlock();
186 return(err); 185 return err;
187} 186}
188 187
189int ignore_sigio_fd(int fd) 188int ignore_sigio_fd(int fd)
@@ -205,18 +204,14 @@ int ignore_sigio_fd(int fd)
205 if(i == current_poll.used) 204 if(i == current_poll.used)
206 goto out; 205 goto out;
207 206
208 err = need_poll(current_poll.used - 1); 207 err = need_poll(&next_poll, current_poll.used - 1);
209 if(err) 208 if(err)
210 goto out; 209 goto out;
211 210
212 for(i = 0; i < current_poll.used; i++){ 211 for(i = 0; i < current_poll.used; i++){
213 p = &current_poll.poll[i]; 212 p = &current_poll.poll[i];
214 if(p->fd != fd) next_poll.poll[n++] = current_poll.poll[i]; 213 if(p->fd != fd)
215 } 214 next_poll.poll[n++] = *p;
216 if(n == i){
217 printk("ignore_sigio_fd : fd %d not found\n", fd);
218 err = -1;
219 goto out;
220 } 215 }
221 216
222 update_thread(); 217 update_thread();
@@ -234,7 +229,7 @@ static struct pollfd *setup_initial_poll(int fd)
234 printk("setup_initial_poll : failed to allocate poll\n"); 229 printk("setup_initial_poll : failed to allocate poll\n");
235 return NULL; 230 return NULL;
236 } 231 }
237 *p = ((struct pollfd) { .fd = fd, 232 *p = ((struct pollfd) { .fd = fd,
238 .events = POLLIN, 233 .events = POLLIN,
239 .revents = 0 }); 234 .revents = 0 });
240 return p; 235 return p;
@@ -323,6 +318,8 @@ out_close1:
323 318
324void maybe_sigio_broken(int fd, int read) 319void maybe_sigio_broken(int fd, int read)
325{ 320{
321 int err;
322
326 if(!isatty(fd)) 323 if(!isatty(fd))
327 return; 324 return;
328 325
@@ -330,7 +327,19 @@ void maybe_sigio_broken(int fd, int read)
330 return; 327 return;
331 328
332 write_sigio_workaround(); 329 write_sigio_workaround();
333 add_sigio_fd(fd, read); 330
331 sigio_lock();
332 err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1);
333 if(err){
334 printk("maybe_sigio_broken - failed to add pollfd\n");
335 goto out;
336 }
337 all_sigio_fds.poll[all_sigio_fds.used++] =
338 ((struct pollfd) { .fd = fd,
339 .events = read ? POLLIN : POLLOUT,
340 .revents = 0 });
341out:
342 sigio_unlock();
334} 343}
335 344
336static void sigio_cleanup(void) 345static void sigio_cleanup(void)
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 60e4faedf254..6b81739279d1 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -15,7 +15,6 @@
15#include "user.h" 15#include "user.h"
16#include "signal_kern.h" 16#include "signal_kern.h"
17#include "sysdep/sigcontext.h" 17#include "sysdep/sigcontext.h"
18#include "sysdep/signal.h"
19#include "sigcontext.h" 18#include "sigcontext.h"
20#include "mode.h" 19#include "mode.h"
21#include "os.h" 20#include "os.h"
@@ -38,18 +37,10 @@
38static int signals_enabled = 1; 37static int signals_enabled = 1;
39static int pending = 0; 38static int pending = 0;
40 39
41void sig_handler(ARCH_SIGHDLR_PARAM) 40void sig_handler(int sig, struct sigcontext *sc)
42{ 41{
43 struct sigcontext *sc;
44 int enabled; 42 int enabled;
45 43
46 /* Must be the first thing that this handler does - x86_64 stores
47 * the sigcontext in %rdx, and we need to save it before it has a
48 * chance to get trashed.
49 */
50
51 ARCH_GET_SIGCONTEXT(sc, sig);
52
53 enabled = signals_enabled; 44 enabled = signals_enabled;
54 if(!enabled && (sig == SIGIO)){ 45 if(!enabled && (sig == SIGIO)){
55 pending |= SIGIO_MASK; 46 pending |= SIGIO_MASK;
@@ -64,15 +55,8 @@ void sig_handler(ARCH_SIGHDLR_PARAM)
64 set_signals(enabled); 55 set_signals(enabled);
65} 56}
66 57
67extern int timer_irq_inited;
68
69static void real_alarm_handler(int sig, struct sigcontext *sc) 58static void real_alarm_handler(int sig, struct sigcontext *sc)
70{ 59{
71 if(!timer_irq_inited){
72 signals_enabled = 1;
73 return;
74 }
75
76 if(sig == SIGALRM) 60 if(sig == SIGALRM)
77 switch_timers(0); 61 switch_timers(0);
78 62
@@ -84,13 +68,10 @@ static void real_alarm_handler(int sig, struct sigcontext *sc)
84 68
85} 69}
86 70
87void alarm_handler(ARCH_SIGHDLR_PARAM) 71void alarm_handler(int sig, struct sigcontext *sc)
88{ 72{
89 struct sigcontext *sc;
90 int enabled; 73 int enabled;
91 74
92 ARCH_GET_SIGCONTEXT(sc, sig);
93
94 enabled = signals_enabled; 75 enabled = signals_enabled;
95 if(!signals_enabled){ 76 if(!signals_enabled){
96 if(sig == SIGVTALRM) 77 if(sig == SIGVTALRM)
@@ -126,6 +107,10 @@ void remove_sigstack(void)
126 panic("disabling signal stack failed, errno = %d\n", errno); 107 panic("disabling signal stack failed, errno = %d\n", errno);
127} 108}
128 109
110void (*handlers[_NSIG])(int sig, struct sigcontext *sc);
111
112extern void hard_handler(int sig);
113
129void set_handler(int sig, void (*handler)(int), int flags, ...) 114void set_handler(int sig, void (*handler)(int), int flags, ...)
130{ 115{
131 struct sigaction action; 116 struct sigaction action;
@@ -133,13 +118,16 @@ void set_handler(int sig, void (*handler)(int), int flags, ...)
133 sigset_t sig_mask; 118 sigset_t sig_mask;
134 int mask; 119 int mask;
135 120
136 va_start(ap, flags); 121 handlers[sig] = (void (*)(int, struct sigcontext *)) handler;
137 action.sa_handler = handler; 122 action.sa_handler = hard_handler;
123
138 sigemptyset(&action.sa_mask); 124 sigemptyset(&action.sa_mask);
139 while((mask = va_arg(ap, int)) != -1){ 125
126 va_start(ap, flags);
127 while((mask = va_arg(ap, int)) != -1)
140 sigaddset(&action.sa_mask, mask); 128 sigaddset(&action.sa_mask, mask);
141 }
142 va_end(ap); 129 va_end(ap);
130
143 action.sa_flags = flags; 131 action.sa_flags = flags;
144 action.sa_restorer = NULL; 132 action.sa_restorer = NULL;
145 if(sigaction(sig, &action, NULL) < 0) 133 if(sigaction(sig, &action, NULL) < 0)
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index 7baf90fda58b..cb9ab54146cc 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -8,7 +8,6 @@
8#include <unistd.h> 8#include <unistd.h>
9#include <errno.h> 9#include <errno.h>
10#include <signal.h> 10#include <signal.h>
11#include <setjmp.h>
12#include <sched.h> 11#include <sched.h>
13#include "ptrace_user.h" 12#include "ptrace_user.h"
14#include <sys/wait.h> 13#include <sys/wait.h>
@@ -156,11 +155,15 @@ extern int __syscall_stub_start;
156static int userspace_tramp(void *stack) 155static int userspace_tramp(void *stack)
157{ 156{
158 void *addr; 157 void *addr;
158 int err;
159 159
160 ptrace(PTRACE_TRACEME, 0, 0, 0); 160 ptrace(PTRACE_TRACEME, 0, 0, 0);
161 161
162 init_new_thread_signals(); 162 init_new_thread_signals();
163 enable_timer(); 163 err = set_interval(1);
164 if(err)
165 panic("userspace_tramp - setting timer failed, errno = %d\n",
166 err);
164 167
165 if(!proc_mm){ 168 if(!proc_mm){
166 /* This has a pte, but it can't be mapped in with the usual 169 /* This has a pte, but it can't be mapped in with the usual
@@ -190,14 +193,25 @@ static int userspace_tramp(void *stack)
190 } 193 }
191 } 194 }
192 if(!ptrace_faultinfo && (stack != NULL)){ 195 if(!ptrace_faultinfo && (stack != NULL)){
196 struct sigaction sa;
197
193 unsigned long v = UML_CONFIG_STUB_CODE + 198 unsigned long v = UML_CONFIG_STUB_CODE +
194 (unsigned long) stub_segv_handler - 199 (unsigned long) stub_segv_handler -
195 (unsigned long) &__syscall_stub_start; 200 (unsigned long) &__syscall_stub_start;
196 201
197 set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size()); 202 set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size());
198 set_handler(SIGSEGV, (void *) v, SA_ONSTACK, 203 sigemptyset(&sa.sa_mask);
199 SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, 204 sigaddset(&sa.sa_mask, SIGIO);
200 SIGUSR1, -1); 205 sigaddset(&sa.sa_mask, SIGWINCH);
206 sigaddset(&sa.sa_mask, SIGALRM);
207 sigaddset(&sa.sa_mask, SIGVTALRM);
208 sigaddset(&sa.sa_mask, SIGUSR1);
209 sa.sa_flags = SA_ONSTACK;
210 sa.sa_handler = (void *) v;
211 sa.sa_restorer = NULL;
212 if(sigaction(SIGSEGV, &sa, NULL) < 0)
213 panic("userspace_tramp - setting SIGSEGV handler "
214 "failed - errno = %d\n", errno);
201 } 215 }
202 216
203 os_stop_process(os_getpid()); 217 os_stop_process(os_getpid());
@@ -430,56 +444,22 @@ void map_stub_pages(int fd, unsigned long code,
430 } 444 }
431} 445}
432 446
433void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, 447void new_thread(void *stack, jmp_buf *buf, void (*handler)(void))
434 void (*handler)(int))
435{ 448{
436 unsigned long flags; 449 (*buf)[0].JB_IP = (unsigned long) handler;
437 jmp_buf switch_buf, fork_buf; 450 (*buf)[0].JB_SP = (unsigned long) stack +
438 451 (PAGE_SIZE << UML_CONFIG_KERNEL_STACK_ORDER) - sizeof(void *);
439 *switch_buf_ptr = &switch_buf;
440 *fork_buf_ptr = &fork_buf;
441
442 /* Somewhat subtle - siglongjmp restores the signal mask before doing
443 * the longjmp. This means that when jumping from one stack to another
444 * when the target stack has interrupts enabled, an interrupt may occur
445 * on the source stack. This is bad when starting up a process because
446 * it's not supposed to get timer ticks until it has been scheduled.
447 * So, we disable interrupts around the sigsetjmp to ensure that
448 * they can't happen until we get back here where they are safe.
449 */
450 flags = get_signals();
451 block_signals();
452 if(UML_SETJMP(&fork_buf) == 0)
453 new_thread_proc(stack, handler);
454
455 remove_sigstack();
456
457 set_signals(flags);
458} 452}
459 453
460#define INIT_JMP_NEW_THREAD 0 454#define INIT_JMP_NEW_THREAD 0
461#define INIT_JMP_REMOVE_SIGSTACK 1 455#define INIT_JMP_CALLBACK 1
462#define INIT_JMP_CALLBACK 2 456#define INIT_JMP_HALT 2
463#define INIT_JMP_HALT 3 457#define INIT_JMP_REBOOT 3
464#define INIT_JMP_REBOOT 4
465 458
466void thread_wait(void *sw, void *fb) 459void switch_threads(jmp_buf *me, jmp_buf *you)
467{ 460{
468 jmp_buf buf, **switch_buf = sw, *fork_buf; 461 if(UML_SETJMP(me) == 0)
469 462 UML_LONGJMP(you, 1);
470 *switch_buf = &buf;
471 fork_buf = fb;
472 if(UML_SETJMP(&buf) == 0)
473 siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK);
474}
475
476void switch_threads(void *me, void *next)
477{
478 jmp_buf my_buf, **me_ptr = me, *next_buf = next;
479
480 *me_ptr = &my_buf;
481 if(UML_SETJMP(&my_buf) == 0)
482 UML_LONGJMP(next_buf, 1);
483} 463}
484 464
485static jmp_buf initial_jmpbuf; 465static jmp_buf initial_jmpbuf;
@@ -489,23 +469,21 @@ static void (*cb_proc)(void *arg);
489static void *cb_arg; 469static void *cb_arg;
490static jmp_buf *cb_back; 470static jmp_buf *cb_back;
491 471
492int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) 472int start_idle_thread(void *stack, jmp_buf *switch_buf)
493{ 473{
494 jmp_buf **switch_buf = switch_buf_ptr;
495 int n; 474 int n;
496 475
497 set_handler(SIGWINCH, (__sighandler_t) sig_handler, 476 set_handler(SIGWINCH, (__sighandler_t) sig_handler,
498 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM, 477 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
499 SIGVTALRM, -1); 478 SIGVTALRM, -1);
500 479
501 *fork_buf_ptr = &initial_jmpbuf;
502 n = UML_SETJMP(&initial_jmpbuf); 480 n = UML_SETJMP(&initial_jmpbuf);
503 switch(n){ 481 switch(n){
504 case INIT_JMP_NEW_THREAD: 482 case INIT_JMP_NEW_THREAD:
505 new_thread_proc((void *) stack, new_thread_handler); 483 (*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler;
506 break; 484 (*switch_buf)[0].JB_SP = (unsigned long) stack +
507 case INIT_JMP_REMOVE_SIGSTACK: 485 (PAGE_SIZE << UML_CONFIG_KERNEL_STACK_ORDER) -
508 remove_sigstack(); 486 sizeof(void *);
509 break; 487 break;
510 case INIT_JMP_CALLBACK: 488 case INIT_JMP_CALLBACK:
511 (*cb_proc)(cb_arg); 489 (*cb_proc)(cb_arg);
@@ -520,7 +498,7 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
520 default: 498 default:
521 panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); 499 panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
522 } 500 }
523 UML_LONGJMP(*switch_buf, 1); 501 UML_LONGJMP(switch_buf, 1);
524} 502}
525 503
526void initial_thread_cb_skas(void (*proc)(void *), void *arg) 504void initial_thread_cb_skas(void (*proc)(void *), void *arg)
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 503148504009..7fe92680c7dd 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -14,7 +14,6 @@
14#include <sched.h> 14#include <sched.h>
15#include <fcntl.h> 15#include <fcntl.h>
16#include <errno.h> 16#include <errno.h>
17#include <setjmp.h>
18#include <sys/time.h> 17#include <sys/time.h>
19#include <sys/wait.h> 18#include <sys/wait.h>
20#include <sys/mman.h> 19#include <sys/mman.h>
diff --git a/arch/um/os-Linux/sys-i386/Makefile b/arch/um/os-Linux/sys-i386/Makefile
index b3213613c41c..37806621b25d 100644
--- a/arch/um/os-Linux/sys-i386/Makefile
+++ b/arch/um/os-Linux/sys-i386/Makefile
@@ -3,7 +3,7 @@
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6obj-$(CONFIG_MODE_SKAS) = registers.o tls.o 6obj-$(CONFIG_MODE_SKAS) = registers.o signal.o tls.o
7 7
8USER_OBJS := $(obj-y) 8USER_OBJS := $(obj-y)
9 9
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
index 516f66dd87e3..7cd0369e02b3 100644
--- a/arch/um/os-Linux/sys-i386/registers.c
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -5,12 +5,12 @@
5 5
6#include <errno.h> 6#include <errno.h>
7#include <string.h> 7#include <string.h>
8#include <setjmp.h>
9#include "sysdep/ptrace_user.h" 8#include "sysdep/ptrace_user.h"
10#include "sysdep/ptrace.h" 9#include "sysdep/ptrace.h"
11#include "uml-config.h" 10#include "uml-config.h"
12#include "skas_ptregs.h" 11#include "skas_ptregs.h"
13#include "registers.h" 12#include "registers.h"
13#include "longjmp.h"
14#include "user.h" 14#include "user.h"
15 15
16/* These are set once at boot time and not changed thereafter */ 16/* These are set once at boot time and not changed thereafter */
@@ -130,11 +130,14 @@ void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
130 HOST_FP_SIZE * sizeof(unsigned long)); 130 HOST_FP_SIZE * sizeof(unsigned long));
131} 131}
132 132
133void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer) 133unsigned long get_thread_reg(int reg, jmp_buf *buf)
134{ 134{
135 struct __jmp_buf_tag *jmpbuf = buffer; 135 switch(reg){
136 136 case EIP: return buf[0]->__eip;
137 UPT_SET(uml_regs, EIP, jmpbuf->__jmpbuf[JB_PC]); 137 case UESP: return buf[0]->__esp;
138 UPT_SET(uml_regs, UESP, jmpbuf->__jmpbuf[JB_SP]); 138 case EBP: return buf[0]->__ebp;
139 UPT_SET(uml_regs, EBP, jmpbuf->__jmpbuf[JB_BP]); 139 default:
140 printk("get_thread_regs - unknown register %d\n", reg);
141 return 0;
142 }
140} 143}
diff --git a/arch/um/os-Linux/sys-i386/signal.c b/arch/um/os-Linux/sys-i386/signal.c
new file mode 100644
index 000000000000..0d3eae518352
--- /dev/null
+++ b/arch/um/os-Linux/sys-i386/signal.c
@@ -0,0 +1,15 @@
1/*
2 * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL
4 */
5
6#include <signal.h>
7
8extern void (*handlers[])(int sig, struct sigcontext *sc);
9
10void hard_handler(int sig)
11{
12 struct sigcontext *sc = (struct sigcontext *) (&sig + 1);
13
14 (*handlers[sig])(sig, sc);
15}
diff --git a/arch/um/os-Linux/sys-x86_64/Makefile b/arch/um/os-Linux/sys-x86_64/Makefile
index 340ef26f5944..f67842a7735b 100644
--- a/arch/um/os-Linux/sys-x86_64/Makefile
+++ b/arch/um/os-Linux/sys-x86_64/Makefile
@@ -3,7 +3,7 @@
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6obj-$(CONFIG_MODE_SKAS) = registers.o 6obj-$(CONFIG_MODE_SKAS) = registers.o signal.o
7 7
8USER_OBJS := $(obj-y) 8USER_OBJS := $(obj-y)
9 9
diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c
index becd898d9398..cb8e8a263280 100644
--- a/arch/um/os-Linux/sys-x86_64/registers.c
+++ b/arch/um/os-Linux/sys-x86_64/registers.c
@@ -5,11 +5,11 @@
5 5
6#include <errno.h> 6#include <errno.h>
7#include <string.h> 7#include <string.h>
8#include <setjmp.h>
9#include "ptrace_user.h" 8#include "ptrace_user.h"
10#include "uml-config.h" 9#include "uml-config.h"
11#include "skas_ptregs.h" 10#include "skas_ptregs.h"
12#include "registers.h" 11#include "registers.h"
12#include "longjmp.h"
13#include "user.h" 13#include "user.h"
14 14
15/* These are set once at boot time and not changed thereafter */ 15/* These are set once at boot time and not changed thereafter */
@@ -78,11 +78,14 @@ void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
78 HOST_FP_SIZE * sizeof(unsigned long)); 78 HOST_FP_SIZE * sizeof(unsigned long));
79} 79}
80 80
81void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer) 81unsigned long get_thread_reg(int reg, jmp_buf *buf)
82{ 82{
83 struct __jmp_buf_tag *jmpbuf = buffer; 83 switch(reg){
84 84 case RIP: return buf[0]->__rip;
85 UPT_SET(uml_regs, RIP, jmpbuf->__jmpbuf[JB_PC]); 85 case RSP: return buf[0]->__rsp;
86 UPT_SET(uml_regs, RSP, jmpbuf->__jmpbuf[JB_RSP]); 86 case RBP: return buf[0]->__rbp;
87 UPT_SET(uml_regs, RBP, jmpbuf->__jmpbuf[JB_RBP]); 87 default:
88 printk("get_thread_regs - unknown register %d\n", reg);
89 return 0;
90 }
88} 91}
diff --git a/arch/um/os-Linux/sys-x86_64/signal.c b/arch/um/os-Linux/sys-x86_64/signal.c
new file mode 100644
index 000000000000..3f369e5f976b
--- /dev/null
+++ b/arch/um/os-Linux/sys-x86_64/signal.c
@@ -0,0 +1,16 @@
1/*
2 * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL
4 */
5
6#include <signal.h>
7
8extern void (*handlers[])(int sig, struct sigcontext *sc);
9
10void hard_handler(int sig)
11{
12 struct ucontext *uc;
13 asm("movq %%rdx, %0" : "=r" (uc));
14
15 (*handlers[sig])(sig, (struct sigcontext *) &uc->uc_mcontext);
16}
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index 4ae73c0e5485..38be096e750f 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -17,20 +17,25 @@
17#include "kern_constants.h" 17#include "kern_constants.h"
18#include "os.h" 18#include "os.h"
19 19
20static void set_interval(int timer_type) 20int set_interval(int is_virtual)
21{ 21{
22 int usec = 1000000/hz(); 22 int usec = 1000000/hz();
23 int timer_type = is_virtual ? ITIMER_VIRTUAL : ITIMER_REAL;
23 struct itimerval interval = ((struct itimerval) { { 0, usec }, 24 struct itimerval interval = ((struct itimerval) { { 0, usec },
24 { 0, usec } }); 25 { 0, usec } });
25 26
26 if(setitimer(timer_type, &interval, NULL) == -1) 27 if(setitimer(timer_type, &interval, NULL) == -1)
27 panic("setitimer failed - errno = %d\n", errno); 28 return -errno;
29
30 return 0;
28} 31}
29 32
33#ifdef CONFIG_MODE_TT
30void enable_timer(void) 34void enable_timer(void)
31{ 35{
32 set_interval(ITIMER_VIRTUAL); 36 set_interval(1);
33} 37}
38#endif
34 39
35void disable_timer(void) 40void disable_timer(void)
36{ 41{
@@ -40,8 +45,8 @@ void disable_timer(void)
40 printk("disnable_timer - setitimer failed, errno = %d\n", 45 printk("disnable_timer - setitimer failed, errno = %d\n",
41 errno); 46 errno);
42 /* If there are signals already queued, after unblocking ignore them */ 47 /* If there are signals already queued, after unblocking ignore them */
43 set_handler(SIGALRM, SIG_IGN, 0, -1); 48 signal(SIGALRM, SIG_IGN);
44 set_handler(SIGVTALRM, SIG_IGN, 0, -1); 49 signal(SIGVTALRM, SIG_IGN);
45} 50}
46 51
47void switch_timers(int to_real) 52void switch_timers(int to_real)
@@ -74,7 +79,7 @@ void uml_idle_timer(void)
74 79
75 set_handler(SIGALRM, (__sighandler_t) alarm_handler, 80 set_handler(SIGALRM, (__sighandler_t) alarm_handler,
76 SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); 81 SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
77 set_interval(ITIMER_REAL); 82 set_interval(0);
78} 83}
79#endif 84#endif
80 85
@@ -94,8 +99,3 @@ void idle_sleep(int secs)
94 ts.tv_nsec = 0; 99 ts.tv_nsec = 0;
95 nanosleep(&ts, NULL); 100 nanosleep(&ts, NULL);
96} 101}
97
98void user_time_init(void)
99{
100 set_interval(ITIMER_VIRTUAL);
101}
diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c
index 90b29ae9af46..1df231a26244 100644
--- a/arch/um/os-Linux/trap.c
+++ b/arch/um/os-Linux/trap.c
@@ -5,7 +5,6 @@
5 5
6#include <stdlib.h> 6#include <stdlib.h>
7#include <signal.h> 7#include <signal.h>
8#include <setjmp.h>
9#include "kern_util.h" 8#include "kern_util.h"
10#include "user_util.h" 9#include "user_util.h"
11#include "os.h" 10#include "os.h"
diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c
index 865f6a6a2590..bbb73a650370 100644
--- a/arch/um/os-Linux/uaccess.c
+++ b/arch/um/os-Linux/uaccess.c
@@ -4,8 +4,7 @@
4 * Licensed under the GPL 4 * Licensed under the GPL
5 */ 5 */
6 6
7#include <setjmp.h> 7#include <stddef.h>
8#include <string.h>
9#include "longjmp.h" 8#include "longjmp.h"
10 9
11unsigned long __do_user_copy(void *to, const void *from, int n, 10unsigned long __do_user_copy(void *to, const void *from, int n,
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c
index c47a2a7ce70e..3f5b1514e8a7 100644
--- a/arch/um/os-Linux/util.c
+++ b/arch/um/os-Linux/util.c
@@ -7,7 +7,6 @@
7#include <stdlib.h> 7#include <stdlib.h>
8#include <unistd.h> 8#include <unistd.h>
9#include <limits.h> 9#include <limits.h>
10#include <setjmp.h>
11#include <sys/mman.h> 10#include <sys/mman.h>
12#include <sys/stat.h> 11#include <sys/stat.h>
13#include <sys/utsname.h> 12#include <sys/utsname.h>
@@ -107,11 +106,11 @@ int setjmp_wrapper(void (*proc)(void *, void *), ...)
107 jmp_buf buf; 106 jmp_buf buf;
108 int n; 107 int n;
109 108
110 n = sigsetjmp(buf, 1); 109 n = UML_SETJMP(&buf);
111 if(n == 0){ 110 if(n == 0){
112 va_start(args, proc); 111 va_start(args, proc);
113 (*proc)(&buf, &args); 112 (*proc)(&buf, &args);
114 } 113 }
115 va_end(args); 114 va_end(args);
116 return(n); 115 return n;
117} 116}
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 374d61a19439..0e32adf03be1 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -1,10 +1,10 @@
1obj-y = bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ 1obj-y = bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
2 ptrace_user.o signal.o sigcontext.o syscalls.o sysrq.o \ 2 ptrace_user.o setjmp.o signal.o sigcontext.o syscalls.o sysrq.o \
3 sys_call_table.o tls.o 3 sys_call_table.o tls.o
4 4
5obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o 5obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o
6 6
7subarch-obj-y = lib/bitops.o kernel/semaphore.o 7subarch-obj-y = lib/bitops.o lib/semaphore.o
8subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem.o 8subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem.o
9subarch-obj-$(CONFIG_MODULES) += kernel/module.o 9subarch-obj-$(CONFIG_MODULES) += kernel/module.o
10 10
diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c
index 41b0ab2fe830..f1bcd399ac90 100644
--- a/arch/um/sys-i386/bugs.c
+++ b/arch/um/sys-i386/bugs.c
@@ -13,6 +13,7 @@
13#include "sysdep/ptrace.h" 13#include "sysdep/ptrace.h"
14#include "task.h" 14#include "task.h"
15#include "os.h" 15#include "os.h"
16#include "user_util.h"
16 17
17#define MAXTOKEN 64 18#define MAXTOKEN 64
18 19
@@ -104,17 +105,17 @@ int cpu_feature(char *what, char *buf, int len)
104static int check_cpu_flag(char *feature, int *have_it) 105static int check_cpu_flag(char *feature, int *have_it)
105{ 106{
106 char buf[MAXTOKEN], c; 107 char buf[MAXTOKEN], c;
107 int fd, len = sizeof(buf)/sizeof(buf[0]); 108 int fd, len = ARRAY_SIZE(buf);
108 109
109 printk("Checking for host processor %s support...", feature); 110 printk("Checking for host processor %s support...", feature);
110 fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0); 111 fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
111 if(fd < 0){ 112 if(fd < 0){
112 printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd); 113 printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
113 return(0); 114 return 0;
114 } 115 }
115 116
116 *have_it = 0; 117 *have_it = 0;
117 if(!find_cpuinfo_line(fd, "flags", buf, sizeof(buf) / sizeof(buf[0]))) 118 if(!find_cpuinfo_line(fd, "flags", buf, ARRAY_SIZE(buf)))
118 goto out; 119 goto out;
119 120
120 c = token(fd, buf, len - 1, ' '); 121 c = token(fd, buf, len - 1, ' ');
@@ -138,7 +139,7 @@ static int check_cpu_flag(char *feature, int *have_it)
138 if(*have_it == 0) printk("No\n"); 139 if(*have_it == 0) printk("No\n");
139 else if(*have_it == 1) printk("Yes\n"); 140 else if(*have_it == 1) printk("Yes\n");
140 os_close_file(fd); 141 os_close_file(fd);
141 return(1); 142 return 1;
142} 143}
143 144
144#if 0 /* This doesn't work in tt mode, plus it's causing compilation problems 145#if 0 /* This doesn't work in tt mode, plus it's causing compilation problems
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index fe0877b3509c..69971b78beaf 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -424,9 +424,8 @@ void ldt_get_host_info(void)
424 size++; 424 size++;
425 } 425 }
426 426
427 if(size < sizeof(dummy_list)/sizeof(dummy_list[0])) { 427 if(size < ARRAY_SIZE(dummy_list))
428 host_ldt_entries = dummy_list; 428 host_ldt_entries = dummy_list;
429 }
430 else { 429 else {
431 size = (size + 1) * sizeof(dummy_list[0]); 430 size = (size + 1) * sizeof(dummy_list[0]);
432 host_ldt_entries = (short *)kmalloc(size, GFP_KERNEL); 431 host_ldt_entries = (short *)kmalloc(size, GFP_KERNEL);
diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c
index 40aa88531446..5f3cc6685820 100644
--- a/arch/um/sys-i386/ptrace_user.c
+++ b/arch/um/sys-i386/ptrace_user.c
@@ -15,6 +15,7 @@
15#include "user.h" 15#include "user.h"
16#include "os.h" 16#include "os.h"
17#include "uml-config.h" 17#include "uml-config.h"
18#include "user_util.h"
18 19
19int ptrace_getregs(long pid, unsigned long *regs_out) 20int ptrace_getregs(long pid, unsigned long *regs_out)
20{ 21{
@@ -51,7 +52,7 @@ static void write_debugregs(int pid, unsigned long *regs)
51 int nregs, i; 52 int nregs, i;
52 53
53 dummy = NULL; 54 dummy = NULL;
54 nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]); 55 nregs = ARRAY_SIZE(dummy->u_debugreg);
55 for(i = 0; i < nregs; i++){ 56 for(i = 0; i < nregs; i++){
56 if((i == 4) || (i == 5)) continue; 57 if((i == 4) || (i == 5)) continue;
57 if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i], 58 if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i],
@@ -68,7 +69,7 @@ static void read_debugregs(int pid, unsigned long *regs)
68 int nregs, i; 69 int nregs, i;
69 70
70 dummy = NULL; 71 dummy = NULL;
71 nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]); 72 nregs = ARRAY_SIZE(dummy->u_debugreg);
72 for(i = 0; i < nregs; i++){ 73 for(i = 0; i < nregs; i++){
73 regs[i] = ptrace(PTRACE_PEEKUSR, pid, 74 regs[i] = ptrace(PTRACE_PEEKUSR, pid,
74 &dummy->u_debugreg[i], 0); 75 &dummy->u_debugreg[i], 0);
diff --git a/arch/um/sys-i386/setjmp.S b/arch/um/sys-i386/setjmp.S
new file mode 100644
index 000000000000..b766792c9933
--- /dev/null
+++ b/arch/um/sys-i386/setjmp.S
@@ -0,0 +1,58 @@
1#
2# arch/i386/setjmp.S
3#
4# setjmp/longjmp for the i386 architecture
5#
6
7#
8# The jmp_buf is assumed to contain the following, in order:
9# %ebx
10# %esp
11# %ebp
12# %esi
13# %edi
14# <return address>
15#
16
17 .text
18 .align 4
19 .globl setjmp
20 .type setjmp, @function
21setjmp:
22#ifdef _REGPARM
23 movl %eax,%edx
24#else
25 movl 4(%esp),%edx
26#endif
27 popl %ecx # Return address, and adjust the stack
28 xorl %eax,%eax # Return value
29 movl %ebx,(%edx)
30 movl %esp,4(%edx) # Post-return %esp!
31 pushl %ecx # Make the call/return stack happy
32 movl %ebp,8(%edx)
33 movl %esi,12(%edx)
34 movl %edi,16(%edx)
35 movl %ecx,20(%edx) # Return address
36 ret
37
38 .size setjmp,.-setjmp
39
40 .text
41 .align 4
42 .globl longjmp
43 .type longjmp, @function
44longjmp:
45#ifdef _REGPARM
46 xchgl %eax,%edx
47#else
48 movl 4(%esp),%edx # jmp_ptr address
49 movl 8(%esp),%eax # Return value
50#endif
51 movl (%edx),%ebx
52 movl 4(%edx),%esp
53 movl 8(%edx),%ebp
54 movl 12(%edx),%esi
55 movl 16(%edx),%edi
56 jmp *20(%edx)
57
58 .size longjmp,.-longjmp
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index c19794d435d6..f41768b8e25e 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -5,8 +5,8 @@
5# 5#
6 6
7obj-y = bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \ 7obj-y = bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \
8 sigcontext.o signal.o syscalls.o syscall_table.o sysrq.o ksyms.o \ 8 setjmp.o sigcontext.o signal.o syscalls.o syscall_table.o sysrq.o \
9 tls.o 9 ksyms.o tls.o
10 10
11obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o 11obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o
12obj-$(CONFIG_MODULES) += um_module.o 12obj-$(CONFIG_MODULES) += um_module.o
diff --git a/arch/um/sys-x86_64/setjmp.S b/arch/um/sys-x86_64/setjmp.S
new file mode 100644
index 000000000000..45f547b4043e
--- /dev/null
+++ b/arch/um/sys-x86_64/setjmp.S
@@ -0,0 +1,54 @@
1#
2# arch/x86_64/setjmp.S
3#
4# setjmp/longjmp for the x86-64 architecture
5#
6
7#
8# The jmp_buf is assumed to contain the following, in order:
9# %rbx
10# %rsp (post-return)
11# %rbp
12# %r12
13# %r13
14# %r14
15# %r15
16# <return address>
17#
18
19 .text
20 .align 4
21 .globl setjmp
22 .type setjmp, @function
23setjmp:
24 pop %rsi # Return address, and adjust the stack
25 xorl %eax,%eax # Return value
26 movq %rbx,(%rdi)
27 movq %rsp,8(%rdi) # Post-return %rsp!
28 push %rsi # Make the call/return stack happy
29 movq %rbp,16(%rdi)
30 movq %r12,24(%rdi)
31 movq %r13,32(%rdi)
32 movq %r14,40(%rdi)
33 movq %r15,48(%rdi)
34 movq %rsi,56(%rdi) # Return address
35 ret
36
37 .size setjmp,.-setjmp
38
39 .text
40 .align 4
41 .globl longjmp
42 .type longjmp, @function
43longjmp:
44 movl %esi,%eax # Return value (int)
45 movq (%rdi),%rbx
46 movq 8(%rdi),%rsp
47 movq 16(%rdi),%rbp
48 movq 24(%rdi),%r12
49 movq 32(%rdi),%r13
50 movq 40(%rdi),%r14
51 movq 48(%rdi),%r15
52 jmp *56(%rdi)
53
54 .size longjmp,.-longjmp
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 6cd4878625f1..32ae1378f35c 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -24,6 +24,10 @@ config X86
24 bool 24 bool
25 default y 25 default y
26 26
27config ZONE_DMA32
28 bool
29 default y
30
27config LOCKDEP_SUPPORT 31config LOCKDEP_SUPPORT
28 bool 32 bool
29 default y 33 default y
@@ -81,6 +85,9 @@ config ARCH_MAY_HAVE_PC_FDC
81 bool 85 bool
82 default y 86 default y
83 87
88config ARCH_POPULATES_NODE_MAP
89 def_bool y
90
84config DMI 91config DMI
85 bool 92 bool
86 default y 93 default y
@@ -105,6 +112,7 @@ config X86_PC
105 112
106config X86_VSMP 113config X86_VSMP
107 bool "Support for ScaleMP vSMP" 114 bool "Support for ScaleMP vSMP"
115 depends on PCI
108 help 116 help
109 Support for ScaleMP vSMP systems. Say 'Y' here if this kernel is 117 Support for ScaleMP vSMP systems. Say 'Y' here if this kernel is
110 supposed to run on these EM64T-based machines. Only choose this option 118 supposed to run on these EM64T-based machines. Only choose this option
@@ -163,6 +171,7 @@ config X86_GOOD_APIC
163 171
164config MICROCODE 172config MICROCODE
165 tristate "/dev/cpu/microcode - Intel CPU microcode support" 173 tristate "/dev/cpu/microcode - Intel CPU microcode support"
174 select FW_LOADER
166 ---help--- 175 ---help---
167 If you say Y here the 'File systems' section, you will be 176 If you say Y here the 'File systems' section, you will be
168 able to update the microcode on Intel processors. You will 177 able to update the microcode on Intel processors. You will
@@ -178,6 +187,11 @@ config MICROCODE
178 If you use modprobe or kmod you may also want to add the line 187 If you use modprobe or kmod you may also want to add the line
179 'alias char-major-10-184 microcode' to your /etc/modules.conf file. 188 'alias char-major-10-184 microcode' to your /etc/modules.conf file.
180 189
190config MICROCODE_OLD_INTERFACE
191 bool
192 depends on MICROCODE
193 default y
194
181config X86_MSR 195config X86_MSR
182 tristate "/dev/cpu/*/msr - Model-specific register support" 196 tristate "/dev/cpu/*/msr - Model-specific register support"
183 help 197 help
@@ -291,7 +305,7 @@ config NUMA
291 305
292config K8_NUMA 306config K8_NUMA
293 bool "Old style AMD Opteron NUMA detection" 307 bool "Old style AMD Opteron NUMA detection"
294 depends on NUMA 308 depends on NUMA && PCI
295 default y 309 default y
296 help 310 help
297 Enable K8 NUMA node topology detection. You should say Y here if 311 Enable K8 NUMA node topology detection. You should say Y here if
@@ -421,7 +435,6 @@ config IOMMU
421 435
422config CALGARY_IOMMU 436config CALGARY_IOMMU
423 bool "IBM Calgary IOMMU support" 437 bool "IBM Calgary IOMMU support"
424 default y
425 select SWIOTLB 438 select SWIOTLB
426 depends on PCI && EXPERIMENTAL 439 depends on PCI && EXPERIMENTAL
427 help 440 help
@@ -468,8 +481,7 @@ config X86_MCE_AMD
468 the DRAM Error Threshold. 481 the DRAM Error Threshold.
469 482
470config KEXEC 483config KEXEC
471 bool "kexec system call (EXPERIMENTAL)" 484 bool "kexec system call"
472 depends on EXPERIMENTAL
473 help 485 help
474 kexec is a system call that implements the ability to shutdown your 486 kexec is a system call that implements the ability to shutdown your
475 current kernel, and to start another kernel. It is like a reboot 487 current kernel, and to start another kernel. It is like a reboot
@@ -488,7 +500,14 @@ config CRASH_DUMP
488 bool "kernel crash dumps (EXPERIMENTAL)" 500 bool "kernel crash dumps (EXPERIMENTAL)"
489 depends on EXPERIMENTAL 501 depends on EXPERIMENTAL
490 help 502 help
491 Generate crash dump after being started by kexec. 503 Generate crash dump after being started by kexec.
504 This should be normally only set in special crash dump kernels
505 which are loaded in the main kernel with kexec-tools into
506 a specially reserved region and then later executed after
507 a crash by kdump/kexec. The crash dump kernel must be compiled
508 to a memory address not used by the main kernel or BIOS using
509 PHYSICAL_START.
510 For more details see Documentation/kdump/kdump.txt
492 511
493config PHYSICAL_START 512config PHYSICAL_START
494 hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) 513 hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
@@ -526,6 +545,30 @@ config SECCOMP
526 545
527 If unsure, say Y. Only embedded should say N here. 546 If unsure, say Y. Only embedded should say N here.
528 547
548config CC_STACKPROTECTOR
549 bool "Enable -fstack-protector buffer overflow detection (EXPRIMENTAL)"
550 depends on EXPERIMENTAL
551 help
552 This option turns on the -fstack-protector GCC feature. This
553 feature puts, at the beginning of critical functions, a canary
554 value on the stack just before the return address, and validates
555 the value just before actually returning. Stack based buffer
556 overflows (that need to overwrite this return address) now also
557 overwrite the canary, which gets detected and the attack is then
558 neutralized via a kernel panic.
559
560 This feature requires gcc version 4.2 or above, or a distribution
561 gcc with the feature backported. Older versions are automatically
562 detected and for those versions, this configuration option is ignored.
563
564config CC_STACKPROTECTOR_ALL
565 bool "Use stack-protector for all functions"
566 depends on CC_STACKPROTECTOR
567 help
568 Normally, GCC only inserts the canary value protection for
569 functions that use large-ish on-stack buffers. By enabling
570 this option, GCC will be asked to do this for ALL functions.
571
529source kernel/Kconfig.hz 572source kernel/Kconfig.hz
530 573
531config REORDER 574config REORDER
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile
index 431bb4bc36cd..1c0f18d4f887 100644
--- a/arch/x86_64/Makefile
+++ b/arch/x86_64/Makefile
@@ -54,6 +54,16 @@ endif
54cflags-y += $(call cc-option,-funit-at-a-time) 54cflags-y += $(call cc-option,-funit-at-a-time)
55# prevent gcc from generating any FP code by mistake 55# prevent gcc from generating any FP code by mistake
56cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) 56cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
57# do binutils support CFI?
58cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
59AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
60
61# is .cfi_signal_frame supported too?
62cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
63AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
64
65cflags-$(CONFIG_CC_STACKPROTECTOR) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC) -fstack-protector )
66cflags-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC) -fstack-protector-all )
57 67
58CFLAGS += $(cflags-y) 68CFLAGS += $(cflags-y)
59CFLAGS_KERNEL += $(cflags-kernel-y) 69CFLAGS_KERNEL += $(cflags-kernel-y)
diff --git a/arch/x86_64/boot/compressed/Makefile b/arch/x86_64/boot/compressed/Makefile
index f89d96f11a9f..e70fa6e1da08 100644
--- a/arch/x86_64/boot/compressed/Makefile
+++ b/arch/x86_64/boot/compressed/Makefile
@@ -7,7 +7,8 @@
7# 7#
8 8
9targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o 9targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o
10EXTRA_AFLAGS := -traditional -m32 10EXTRA_AFLAGS := -traditional
11AFLAGS := $(subst -m64,-m32,$(AFLAGS))
11 12
12# cannot use EXTRA_CFLAGS because base CFLAGS contains -mkernel which conflicts with 13# cannot use EXTRA_CFLAGS because base CFLAGS contains -mkernel which conflicts with
13# -m32 14# -m32
diff --git a/arch/x86_64/boot/setup.S b/arch/x86_64/boot/setup.S
index a50b631f4d2b..c3bfd223ab49 100644
--- a/arch/x86_64/boot/setup.S
+++ b/arch/x86_64/boot/setup.S
@@ -526,12 +526,12 @@ is_disk1:
526 movw %cs, %ax # aka SETUPSEG 526 movw %cs, %ax # aka SETUPSEG
527 subw $DELTA_INITSEG, %ax # aka INITSEG 527 subw $DELTA_INITSEG, %ax # aka INITSEG
528 movw %ax, %ds 528 movw %ax, %ds
529 movw $0, (0x1ff) # default is no pointing device 529 movb $0, (0x1ff) # default is no pointing device
530 int $0x11 # int 0x11: equipment list 530 int $0x11 # int 0x11: equipment list
531 testb $0x04, %al # check if mouse installed 531 testb $0x04, %al # check if mouse installed
532 jz no_psmouse 532 jz no_psmouse
533 533
534 movw $0xAA, (0x1ff) # device present 534 movb $0xAA, (0x1ff) # device present
535no_psmouse: 535no_psmouse:
536 536
537#include "../../i386/boot/edd.S" 537#include "../../i386/boot/edd.S"
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
index 5fb970715941..647610ecb580 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.18-rc4 3# Linux kernel version: 2.6.18-git5
4# Thu Aug 24 21:05:55 2006 4# Tue Sep 26 09:30:47 2006
5# 5#
6CONFIG_X86_64=y 6CONFIG_X86_64=y
7CONFIG_64BIT=y 7CONFIG_64BIT=y
@@ -19,6 +19,7 @@ CONFIG_GENERIC_ISA_DMA=y
19CONFIG_GENERIC_IOMAP=y 19CONFIG_GENERIC_IOMAP=y
20CONFIG_ARCH_MAY_HAVE_PC_FDC=y 20CONFIG_ARCH_MAY_HAVE_PC_FDC=y
21CONFIG_DMI=y 21CONFIG_DMI=y
22CONFIG_AUDIT_ARCH=y
22CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" 23CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
23 24
24# 25#
@@ -38,16 +39,16 @@ CONFIG_SYSVIPC=y
38CONFIG_POSIX_MQUEUE=y 39CONFIG_POSIX_MQUEUE=y
39# CONFIG_BSD_PROCESS_ACCT is not set 40# CONFIG_BSD_PROCESS_ACCT is not set
40# CONFIG_TASKSTATS is not set 41# CONFIG_TASKSTATS is not set
41CONFIG_SYSCTL=y
42# CONFIG_AUDIT is not set 42# CONFIG_AUDIT is not set
43CONFIG_IKCONFIG=y 43CONFIG_IKCONFIG=y
44CONFIG_IKCONFIG_PROC=y 44CONFIG_IKCONFIG_PROC=y
45# CONFIG_CPUSETS is not set 45# CONFIG_CPUSETS is not set
46# CONFIG_RELAY is not set 46# CONFIG_RELAY is not set
47CONFIG_INITRAMFS_SOURCE="" 47CONFIG_INITRAMFS_SOURCE=""
48CONFIG_UID16=y
49CONFIG_CC_OPTIMIZE_FOR_SIZE=y 48CONFIG_CC_OPTIMIZE_FOR_SIZE=y
50# CONFIG_EMBEDDED is not set 49# CONFIG_EMBEDDED is not set
50CONFIG_UID16=y
51CONFIG_SYSCTL=y
51CONFIG_KALLSYMS=y 52CONFIG_KALLSYMS=y
52CONFIG_KALLSYMS_ALL=y 53CONFIG_KALLSYMS_ALL=y
53# CONFIG_KALLSYMS_EXTRA_PASS is not set 54# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -56,12 +57,12 @@ CONFIG_PRINTK=y
56CONFIG_BUG=y 57CONFIG_BUG=y
57CONFIG_ELF_CORE=y 58CONFIG_ELF_CORE=y
58CONFIG_BASE_FULL=y 59CONFIG_BASE_FULL=y
59CONFIG_RT_MUTEXES=y
60CONFIG_FUTEX=y 60CONFIG_FUTEX=y
61CONFIG_EPOLL=y 61CONFIG_EPOLL=y
62CONFIG_SHMEM=y 62CONFIG_SHMEM=y
63CONFIG_SLAB=y 63CONFIG_SLAB=y
64CONFIG_VM_EVENT_COUNTERS=y 64CONFIG_VM_EVENT_COUNTERS=y
65CONFIG_RT_MUTEXES=y
65# CONFIG_TINY_SHMEM is not set 66# CONFIG_TINY_SHMEM is not set
66CONFIG_BASE_SMALL=0 67CONFIG_BASE_SMALL=0
67# CONFIG_SLOB is not set 68# CONFIG_SLOB is not set
@@ -160,6 +161,7 @@ CONFIG_X86_MCE_AMD=y
160# CONFIG_CRASH_DUMP is not set 161# CONFIG_CRASH_DUMP is not set
161CONFIG_PHYSICAL_START=0x200000 162CONFIG_PHYSICAL_START=0x200000
162CONFIG_SECCOMP=y 163CONFIG_SECCOMP=y
164# CONFIG_CC_STACKPROTECTOR is not set
163# CONFIG_HZ_100 is not set 165# CONFIG_HZ_100 is not set
164CONFIG_HZ_250=y 166CONFIG_HZ_250=y
165# CONFIG_HZ_1000 is not set 167# CONFIG_HZ_1000 is not set
@@ -307,18 +309,23 @@ CONFIG_IP_PNP_DHCP=y
307CONFIG_INET_DIAG=y 309CONFIG_INET_DIAG=y
308CONFIG_INET_TCP_DIAG=y 310CONFIG_INET_TCP_DIAG=y
309# CONFIG_TCP_CONG_ADVANCED is not set 311# CONFIG_TCP_CONG_ADVANCED is not set
310CONFIG_TCP_CONG_BIC=y 312CONFIG_TCP_CONG_CUBIC=y
313CONFIG_DEFAULT_TCP_CONG="cubic"
311CONFIG_IPV6=y 314CONFIG_IPV6=y
312# CONFIG_IPV6_PRIVACY is not set 315# CONFIG_IPV6_PRIVACY is not set
313# CONFIG_IPV6_ROUTER_PREF is not set 316# CONFIG_IPV6_ROUTER_PREF is not set
314# CONFIG_INET6_AH is not set 317# CONFIG_INET6_AH is not set
315# CONFIG_INET6_ESP is not set 318# CONFIG_INET6_ESP is not set
316# CONFIG_INET6_IPCOMP is not set 319# CONFIG_INET6_IPCOMP is not set
320# CONFIG_IPV6_MIP6 is not set
317# CONFIG_INET6_XFRM_TUNNEL is not set 321# CONFIG_INET6_XFRM_TUNNEL is not set
318# CONFIG_INET6_TUNNEL is not set 322# CONFIG_INET6_TUNNEL is not set
319# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set 323# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
320# CONFIG_INET6_XFRM_MODE_TUNNEL is not set 324# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
325# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
321# CONFIG_IPV6_TUNNEL is not set 326# CONFIG_IPV6_TUNNEL is not set
327# CONFIG_IPV6_SUBTREES is not set
328# CONFIG_IPV6_MULTIPLE_TABLES is not set
322# CONFIG_NETWORK_SECMARK is not set 329# CONFIG_NETWORK_SECMARK is not set
323# CONFIG_NETFILTER is not set 330# CONFIG_NETFILTER is not set
324 331
@@ -345,7 +352,6 @@ CONFIG_IPV6=y
345# CONFIG_ATALK is not set 352# CONFIG_ATALK is not set
346# CONFIG_X25 is not set 353# CONFIG_X25 is not set
347# CONFIG_LAPB is not set 354# CONFIG_LAPB is not set
348# CONFIG_NET_DIVERT is not set
349# CONFIG_ECONET is not set 355# CONFIG_ECONET is not set
350# CONFIG_WAN_ROUTER is not set 356# CONFIG_WAN_ROUTER is not set
351 357
@@ -487,6 +493,7 @@ CONFIG_IDEDMA_AUTO=y
487# 493#
488# CONFIG_RAID_ATTRS is not set 494# CONFIG_RAID_ATTRS is not set
489CONFIG_SCSI=y 495CONFIG_SCSI=y
496CONFIG_SCSI_NETLINK=y
490# CONFIG_SCSI_PROC_FS is not set 497# CONFIG_SCSI_PROC_FS is not set
491 498
492# 499#
@@ -508,12 +515,13 @@ CONFIG_SCSI_CONSTANTS=y
508# CONFIG_SCSI_LOGGING is not set 515# CONFIG_SCSI_LOGGING is not set
509 516
510# 517#
511# SCSI Transport Attributes 518# SCSI Transports
512# 519#
513CONFIG_SCSI_SPI_ATTRS=y 520CONFIG_SCSI_SPI_ATTRS=y
514CONFIG_SCSI_FC_ATTRS=y 521CONFIG_SCSI_FC_ATTRS=y
515# CONFIG_SCSI_ISCSI_ATTRS is not set 522# CONFIG_SCSI_ISCSI_ATTRS is not set
516CONFIG_SCSI_SAS_ATTRS=y 523CONFIG_SCSI_SAS_ATTRS=y
524# CONFIG_SCSI_SAS_LIBSAS is not set
517 525
518# 526#
519# SCSI low-level drivers 527# SCSI low-level drivers
@@ -532,29 +540,14 @@ CONFIG_AIC79XX_RESET_DELAY_MS=4000
532# CONFIG_AIC79XX_DEBUG_ENABLE is not set 540# CONFIG_AIC79XX_DEBUG_ENABLE is not set
533CONFIG_AIC79XX_DEBUG_MASK=0 541CONFIG_AIC79XX_DEBUG_MASK=0
534# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set 542# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
543# CONFIG_SCSI_AIC94XX is not set
544# CONFIG_SCSI_ARCMSR is not set
535CONFIG_MEGARAID_NEWGEN=y 545CONFIG_MEGARAID_NEWGEN=y
536CONFIG_MEGARAID_MM=y 546CONFIG_MEGARAID_MM=y
537CONFIG_MEGARAID_MAILBOX=y 547CONFIG_MEGARAID_MAILBOX=y
538# CONFIG_MEGARAID_LEGACY is not set 548# CONFIG_MEGARAID_LEGACY is not set
539CONFIG_MEGARAID_SAS=y 549CONFIG_MEGARAID_SAS=y
540CONFIG_SCSI_SATA=y
541CONFIG_SCSI_SATA_AHCI=y
542CONFIG_SCSI_SATA_SVW=y
543CONFIG_SCSI_ATA_PIIX=y
544# CONFIG_SCSI_SATA_MV is not set
545CONFIG_SCSI_SATA_NV=y
546# CONFIG_SCSI_PDC_ADMA is not set
547# CONFIG_SCSI_HPTIOP is not set 550# CONFIG_SCSI_HPTIOP is not set
548# CONFIG_SCSI_SATA_QSTOR is not set
549# CONFIG_SCSI_SATA_PROMISE is not set
550# CONFIG_SCSI_SATA_SX4 is not set
551CONFIG_SCSI_SATA_SIL=y
552# CONFIG_SCSI_SATA_SIL24 is not set
553# CONFIG_SCSI_SATA_SIS is not set
554# CONFIG_SCSI_SATA_ULI is not set
555CONFIG_SCSI_SATA_VIA=y
556# CONFIG_SCSI_SATA_VITESSE is not set
557CONFIG_SCSI_SATA_INTEL_COMBINED=y
558# CONFIG_SCSI_BUSLOGIC is not set 551# CONFIG_SCSI_BUSLOGIC is not set
559# CONFIG_SCSI_DMX3191D is not set 552# CONFIG_SCSI_DMX3191D is not set
560# CONFIG_SCSI_EATA is not set 553# CONFIG_SCSI_EATA is not set
@@ -563,6 +556,7 @@ CONFIG_SCSI_SATA_INTEL_COMBINED=y
563# CONFIG_SCSI_IPS is not set 556# CONFIG_SCSI_IPS is not set
564# CONFIG_SCSI_INITIO is not set 557# CONFIG_SCSI_INITIO is not set
565# CONFIG_SCSI_INIA100 is not set 558# CONFIG_SCSI_INIA100 is not set
559# CONFIG_SCSI_STEX is not set
566# CONFIG_SCSI_SYM53C8XX_2 is not set 560# CONFIG_SCSI_SYM53C8XX_2 is not set
567# CONFIG_SCSI_IPR is not set 561# CONFIG_SCSI_IPR is not set
568# CONFIG_SCSI_QLOGIC_1280 is not set 562# CONFIG_SCSI_QLOGIC_1280 is not set
@@ -573,6 +567,62 @@ CONFIG_SCSI_SATA_INTEL_COMBINED=y
573# CONFIG_SCSI_DEBUG is not set 567# CONFIG_SCSI_DEBUG is not set
574 568
575# 569#
570# Serial ATA (prod) and Parallel ATA (experimental) drivers
571#
572CONFIG_ATA=y
573CONFIG_SATA_AHCI=y
574CONFIG_SATA_SVW=y
575CONFIG_ATA_PIIX=y
576# CONFIG_SATA_MV is not set
577CONFIG_SATA_NV=y
578# CONFIG_PDC_ADMA is not set
579# CONFIG_SATA_QSTOR is not set
580# CONFIG_SATA_PROMISE is not set
581# CONFIG_SATA_SX4 is not set
582CONFIG_SATA_SIL=y
583# CONFIG_SATA_SIL24 is not set
584# CONFIG_SATA_SIS is not set
585# CONFIG_SATA_ULI is not set
586CONFIG_SATA_VIA=y
587# CONFIG_SATA_VITESSE is not set
588CONFIG_SATA_INTEL_COMBINED=y
589# CONFIG_PATA_ALI is not set
590# CONFIG_PATA_AMD is not set
591# CONFIG_PATA_ARTOP is not set
592# CONFIG_PATA_ATIIXP is not set
593# CONFIG_PATA_CMD64X is not set
594# CONFIG_PATA_CS5520 is not set
595# CONFIG_PATA_CS5530 is not set
596# CONFIG_PATA_CYPRESS is not set
597# CONFIG_PATA_EFAR is not set
598# CONFIG_ATA_GENERIC is not set
599# CONFIG_PATA_HPT366 is not set
600# CONFIG_PATA_HPT37X is not set
601# CONFIG_PATA_HPT3X2N is not set
602# CONFIG_PATA_HPT3X3 is not set
603# CONFIG_PATA_IT821X is not set
604# CONFIG_PATA_JMICRON is not set
605# CONFIG_PATA_LEGACY is not set
606# CONFIG_PATA_TRIFLEX is not set
607# CONFIG_PATA_MPIIX is not set
608# CONFIG_PATA_OLDPIIX is not set
609# CONFIG_PATA_NETCELL is not set
610# CONFIG_PATA_NS87410 is not set
611# CONFIG_PATA_OPTI is not set
612# CONFIG_PATA_OPTIDMA is not set
613# CONFIG_PATA_PDC_OLD is not set
614# CONFIG_PATA_QDI is not set
615# CONFIG_PATA_RADISYS is not set
616# CONFIG_PATA_RZ1000 is not set
617# CONFIG_PATA_SC1200 is not set
618# CONFIG_PATA_SERVERWORKS is not set
619# CONFIG_PATA_PDC2027X is not set
620# CONFIG_PATA_SIL680 is not set
621# CONFIG_PATA_SIS is not set
622# CONFIG_PATA_VIA is not set
623# CONFIG_PATA_WINBOND is not set
624
625#
576# Multi-device support (RAID and LVM) 626# Multi-device support (RAID and LVM)
577# 627#
578CONFIG_MD=y 628CONFIG_MD=y
@@ -678,6 +728,7 @@ CONFIG_NET_PCI=y
678# CONFIG_ADAPTEC_STARFIRE is not set 728# CONFIG_ADAPTEC_STARFIRE is not set
679CONFIG_B44=y 729CONFIG_B44=y
680CONFIG_FORCEDETH=y 730CONFIG_FORCEDETH=y
731# CONFIG_FORCEDETH_NAPI is not set
681# CONFIG_DGRS is not set 732# CONFIG_DGRS is not set
682# CONFIG_EEPRO100 is not set 733# CONFIG_EEPRO100 is not set
683CONFIG_E100=y 734CONFIG_E100=y
@@ -714,6 +765,7 @@ CONFIG_E1000=y
714# CONFIG_VIA_VELOCITY is not set 765# CONFIG_VIA_VELOCITY is not set
715CONFIG_TIGON3=y 766CONFIG_TIGON3=y
716CONFIG_BNX2=y 767CONFIG_BNX2=y
768# CONFIG_QLA3XXX is not set
717 769
718# 770#
719# Ethernet (10000 Mbit) 771# Ethernet (10000 Mbit)
@@ -1036,6 +1088,7 @@ CONFIG_SOUND=y
1036# Open Sound System 1088# Open Sound System
1037# 1089#
1038CONFIG_SOUND_PRIME=y 1090CONFIG_SOUND_PRIME=y
1091CONFIG_OSS_OBSOLETE_DRIVER=y
1039# CONFIG_SOUND_BT878 is not set 1092# CONFIG_SOUND_BT878 is not set
1040# CONFIG_SOUND_EMU10K1 is not set 1093# CONFIG_SOUND_EMU10K1 is not set
1041# CONFIG_SOUND_FUSION is not set 1094# CONFIG_SOUND_FUSION is not set
@@ -1046,7 +1099,6 @@ CONFIG_SOUND_ICH=y
1046# CONFIG_SOUND_MSNDPIN is not set 1099# CONFIG_SOUND_MSNDPIN is not set
1047# CONFIG_SOUND_VIA82CXXX is not set 1100# CONFIG_SOUND_VIA82CXXX is not set
1048# CONFIG_SOUND_OSS is not set 1101# CONFIG_SOUND_OSS is not set
1049# CONFIG_SOUND_TVMIXER is not set
1050 1102
1051# 1103#
1052# USB support 1104# USB support
@@ -1203,7 +1255,6 @@ CONFIG_USB_MON=y
1203# InfiniBand support 1255# InfiniBand support
1204# 1256#
1205# CONFIG_INFINIBAND is not set 1257# CONFIG_INFINIBAND is not set
1206# CONFIG_IPATH_CORE is not set
1207 1258
1208# 1259#
1209# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) 1260# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
@@ -1449,10 +1500,6 @@ CONFIG_DEBUG_STACKOVERFLOW=y
1449# CONFIG_CRYPTO is not set 1500# CONFIG_CRYPTO is not set
1450 1501
1451# 1502#
1452# Hardware crypto devices
1453#
1454
1455#
1456# Library routines 1503# Library routines
1457# 1504#
1458# CONFIG_CRC_CCITT is not set 1505# CONFIG_CRC_CCITT is not set
diff --git a/arch/x86_64/ia32/ia32_aout.c b/arch/x86_64/ia32/ia32_aout.c
index 3bf58af98936..396d3c100011 100644
--- a/arch/x86_64/ia32/ia32_aout.c
+++ b/arch/x86_64/ia32/ia32_aout.c
@@ -333,7 +333,8 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
333 return error; 333 return error;
334 } 334 }
335 335
336 error = bprm->file->f_op->read(bprm->file, (char *)text_addr, 336 error = bprm->file->f_op->read(bprm->file,
337 (char __user *)text_addr,
337 ex.a_text+ex.a_data, &pos); 338 ex.a_text+ex.a_data, &pos);
338 if ((signed long)error < 0) { 339 if ((signed long)error < 0) {
339 send_sig(SIGKILL, current, 0); 340 send_sig(SIGKILL, current, 0);
@@ -366,7 +367,8 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
366 down_write(&current->mm->mmap_sem); 367 down_write(&current->mm->mmap_sem);
367 do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); 368 do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
368 up_write(&current->mm->mmap_sem); 369 up_write(&current->mm->mmap_sem);
369 bprm->file->f_op->read(bprm->file,(char *)N_TXTADDR(ex), 370 bprm->file->f_op->read(bprm->file,
371 (char __user *)N_TXTADDR(ex),
370 ex.a_text+ex.a_data, &pos); 372 ex.a_text+ex.a_data, &pos);
371 flush_icache_range((unsigned long) N_TXTADDR(ex), 373 flush_icache_range((unsigned long) N_TXTADDR(ex),
372 (unsigned long) N_TXTADDR(ex) + 374 (unsigned long) N_TXTADDR(ex) +
@@ -477,7 +479,7 @@ static int load_aout_library(struct file *file)
477 do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); 479 do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
478 up_write(&current->mm->mmap_sem); 480 up_write(&current->mm->mmap_sem);
479 481
480 file->f_op->read(file, (char *)start_addr, 482 file->f_op->read(file, (char __user *)start_addr,
481 ex.a_text + ex.a_data, &pos); 483 ex.a_text + ex.a_data, &pos);
482 flush_icache_range((unsigned long) start_addr, 484 flush_icache_range((unsigned long) start_addr,
483 (unsigned long) start_addr + ex.a_text + ex.a_data); 485 (unsigned long) start_addr + ex.a_text + ex.a_data);
diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c
index 25e5ca22204c..a6ba9951e86c 100644
--- a/arch/x86_64/ia32/ia32_signal.c
+++ b/arch/x86_64/ia32/ia32_signal.c
@@ -113,25 +113,19 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
113} 113}
114 114
115asmlinkage long 115asmlinkage long
116sys32_sigsuspend(int history0, int history1, old_sigset_t mask, 116sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
117 struct pt_regs *regs)
118{ 117{
119 sigset_t saveset;
120
121 mask &= _BLOCKABLE; 118 mask &= _BLOCKABLE;
122 spin_lock_irq(&current->sighand->siglock); 119 spin_lock_irq(&current->sighand->siglock);
123 saveset = current->blocked; 120 current->saved_sigmask = current->blocked;
124 siginitset(&current->blocked, mask); 121 siginitset(&current->blocked, mask);
125 recalc_sigpending(); 122 recalc_sigpending();
126 spin_unlock_irq(&current->sighand->siglock); 123 spin_unlock_irq(&current->sighand->siglock);
127 124
128 regs->rax = -EINTR; 125 current->state = TASK_INTERRUPTIBLE;
129 while (1) { 126 schedule();
130 current->state = TASK_INTERRUPTIBLE; 127 set_thread_flag(TIF_RESTORE_SIGMASK);
131 schedule(); 128 return -ERESTARTNOHAND;
132 if (do_signal(regs, &saveset))
133 return -EINTR;
134 }
135} 129}
136 130
137asmlinkage long 131asmlinkage long
@@ -437,15 +431,7 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
437 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 431 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
438 goto give_sigsegv; 432 goto give_sigsegv;
439 433
440 { 434 err |= __put_user(sig, &frame->sig);
441 struct exec_domain *ed = current_thread_info()->exec_domain;
442 err |= __put_user((ed
443 && ed->signal_invmap
444 && sig < 32
445 ? ed->signal_invmap[sig]
446 : sig),
447 &frame->sig);
448 }
449 if (err) 435 if (err)
450 goto give_sigsegv; 436 goto give_sigsegv;
451 437
@@ -492,6 +478,11 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
492 regs->rsp = (unsigned long) frame; 478 regs->rsp = (unsigned long) frame;
493 regs->rip = (unsigned long) ka->sa.sa_handler; 479 regs->rip = (unsigned long) ka->sa.sa_handler;
494 480
481 /* Make -mregparm=3 work */
482 regs->rax = sig;
483 regs->rdx = 0;
484 regs->rcx = 0;
485
495 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS)); 486 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
496 asm volatile("movl %0,%%es" :: "r" (__USER32_DS)); 487 asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
497 488
@@ -499,20 +490,20 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
499 regs->ss = __USER32_DS; 490 regs->ss = __USER32_DS;
500 491
501 set_fs(USER_DS); 492 set_fs(USER_DS);
502 regs->eflags &= ~TF_MASK; 493 regs->eflags &= ~TF_MASK;
503 if (test_thread_flag(TIF_SINGLESTEP)) 494 if (test_thread_flag(TIF_SINGLESTEP))
504 ptrace_notify(SIGTRAP); 495 ptrace_notify(SIGTRAP);
505 496
506#if DEBUG_SIG 497#if DEBUG_SIG
507 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", 498 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
508 current->comm, current->pid, frame, regs->rip, frame->pretcode); 499 current->comm, current->pid, frame, regs->rip, frame->pretcode);
509#endif 500#endif
510 501
511 return 1; 502 return 0;
512 503
513give_sigsegv: 504give_sigsegv:
514 force_sigsegv(sig, current); 505 force_sigsegv(sig, current);
515 return 0; 506 return -EFAULT;
516} 507}
517 508
518int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 509int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
@@ -595,18 +586,18 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
595 regs->ss = __USER32_DS; 586 regs->ss = __USER32_DS;
596 587
597 set_fs(USER_DS); 588 set_fs(USER_DS);
598 regs->eflags &= ~TF_MASK; 589 regs->eflags &= ~TF_MASK;
599 if (test_thread_flag(TIF_SINGLESTEP)) 590 if (test_thread_flag(TIF_SINGLESTEP))
600 ptrace_notify(SIGTRAP); 591 ptrace_notify(SIGTRAP);
601 592
602#if DEBUG_SIG 593#if DEBUG_SIG
603 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", 594 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
604 current->comm, current->pid, frame, regs->rip, frame->pretcode); 595 current->comm, current->pid, frame, regs->rip, frame->pretcode);
605#endif 596#endif
606 597
607 return 1; 598 return 0;
608 599
609give_sigsegv: 600give_sigsegv:
610 force_sigsegv(sig, current); 601 force_sigsegv(sig, current);
611 return 0; 602 return -EFAULT;
612} 603}
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index 5d4a7d125ed0..b4aa875e175b 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -71,6 +71,7 @@
71 */ 71 */
72ENTRY(ia32_sysenter_target) 72ENTRY(ia32_sysenter_target)
73 CFI_STARTPROC32 simple 73 CFI_STARTPROC32 simple
74 CFI_SIGNAL_FRAME
74 CFI_DEF_CFA rsp,0 75 CFI_DEF_CFA rsp,0
75 CFI_REGISTER rsp,rbp 76 CFI_REGISTER rsp,rbp
76 swapgs 77 swapgs
@@ -186,6 +187,7 @@ ENDPROC(ia32_sysenter_target)
186 */ 187 */
187ENTRY(ia32_cstar_target) 188ENTRY(ia32_cstar_target)
188 CFI_STARTPROC32 simple 189 CFI_STARTPROC32 simple
190 CFI_SIGNAL_FRAME
189 CFI_DEF_CFA rsp,PDA_STACKOFFSET 191 CFI_DEF_CFA rsp,PDA_STACKOFFSET
190 CFI_REGISTER rip,rcx 192 CFI_REGISTER rip,rcx
191 /*CFI_REGISTER rflags,r11*/ 193 /*CFI_REGISTER rflags,r11*/
@@ -293,6 +295,7 @@ ia32_badarg:
293 295
294ENTRY(ia32_syscall) 296ENTRY(ia32_syscall)
295 CFI_STARTPROC simple 297 CFI_STARTPROC simple
298 CFI_SIGNAL_FRAME
296 CFI_DEF_CFA rsp,SS+8-RIP 299 CFI_DEF_CFA rsp,SS+8-RIP
297 /*CFI_REL_OFFSET ss,SS-RIP*/ 300 /*CFI_REL_OFFSET ss,SS-RIP*/
298 CFI_REL_OFFSET rsp,RSP-RIP 301 CFI_REL_OFFSET rsp,RSP-RIP
@@ -370,6 +373,7 @@ ENTRY(ia32_ptregs_common)
370 popq %r11 373 popq %r11
371 CFI_ENDPROC 374 CFI_ENDPROC
372 CFI_STARTPROC32 simple 375 CFI_STARTPROC32 simple
376 CFI_SIGNAL_FRAME
373 CFI_DEF_CFA rsp,SS+8-ARGOFFSET 377 CFI_DEF_CFA rsp,SS+8-ARGOFFSET
374 CFI_REL_OFFSET rax,RAX-ARGOFFSET 378 CFI_REL_OFFSET rax,RAX-ARGOFFSET
375 CFI_REL_OFFSET rcx,RCX-ARGOFFSET 379 CFI_REL_OFFSET rcx,RCX-ARGOFFSET
@@ -703,8 +707,8 @@ ia32_sys_call_table:
703 .quad sys_readlinkat /* 305 */ 707 .quad sys_readlinkat /* 305 */
704 .quad sys_fchmodat 708 .quad sys_fchmodat
705 .quad sys_faccessat 709 .quad sys_faccessat
706 .quad quiet_ni_syscall /* pselect6 for now */ 710 .quad compat_sys_pselect6
707 .quad quiet_ni_syscall /* ppoll for now */ 711 .quad compat_sys_ppoll
708 .quad sys_unshare /* 310 */ 712 .quad sys_unshare /* 310 */
709 .quad compat_sys_set_robust_list 713 .quad compat_sys_set_robust_list
710 .quad compat_sys_get_robust_list 714 .quad compat_sys_get_robust_list
@@ -713,4 +717,5 @@ ia32_sys_call_table:
713 .quad sys_tee 717 .quad sys_tee
714 .quad compat_sys_vmsplice 718 .quad compat_sys_vmsplice
715 .quad compat_sys_move_pages 719 .quad compat_sys_move_pages
720 .quad sys_getcpu
716ia32_syscall_end: 721ia32_syscall_end:
diff --git a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c
index 659c0722f6b8..d18198ed636b 100644
--- a/arch/x86_64/ia32/ptrace32.c
+++ b/arch/x86_64/ia32/ptrace32.c
@@ -117,6 +117,10 @@ static int putreg32(struct task_struct *child, unsigned regno, u32 val)
117 if ((0x5454 >> ((val >> (16 + 4*i)) & 0xf)) & 1) 117 if ((0x5454 >> ((val >> (16 + 4*i)) & 0xf)) & 1)
118 return -EIO; 118 return -EIO;
119 child->thread.debugreg7 = val; 119 child->thread.debugreg7 = val;
120 if (val)
121 set_tsk_thread_flag(child, TIF_DEBUG);
122 else
123 clear_tsk_thread_flag(child, TIF_DEBUG);
120 break; 124 break;
121 125
122 default: 126 default:
@@ -371,8 +375,10 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
371 ret = -EIO; 375 ret = -EIO;
372 if (!access_ok(VERIFY_READ, u, sizeof(*u))) 376 if (!access_ok(VERIFY_READ, u, sizeof(*u)))
373 break; 377 break;
374 /* no checking to be bug-to-bug compatible with i386 */ 378 /* no checking to be bug-to-bug compatible with i386. */
375 __copy_from_user(&child->thread.i387.fxsave, u, sizeof(*u)); 379 /* but silence warning */
380 if (__copy_from_user(&child->thread.i387.fxsave, u, sizeof(*u)))
381 ;
376 set_stopped_child_used_math(child); 382 set_stopped_child_used_math(child);
377 child->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask; 383 child->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
378 ret = 0; 384 ret = 0;
diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c
index 9c130993380d..f280d3665f4b 100644
--- a/arch/x86_64/ia32/sys_ia32.c
+++ b/arch/x86_64/ia32/sys_ia32.c
@@ -60,6 +60,7 @@
60#include <linux/highuid.h> 60#include <linux/highuid.h>
61#include <linux/vmalloc.h> 61#include <linux/vmalloc.h>
62#include <linux/fsnotify.h> 62#include <linux/fsnotify.h>
63#include <linux/sysctl.h>
63#include <asm/mman.h> 64#include <asm/mman.h>
64#include <asm/types.h> 65#include <asm/types.h>
65#include <asm/uaccess.h> 66#include <asm/uaccess.h>
@@ -389,7 +390,9 @@ sys32_rt_sigprocmask(int how, compat_sigset_t __user *set,
389 } 390 }
390 } 391 }
391 set_fs (KERNEL_DS); 392 set_fs (KERNEL_DS);
392 ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, 393 ret = sys_rt_sigprocmask(how,
394 set ? (sigset_t __user *)&s : NULL,
395 oset ? (sigset_t __user *)&s : NULL,
393 sigsetsize); 396 sigsetsize);
394 set_fs (old_fs); 397 set_fs (old_fs);
395 if (ret) return ret; 398 if (ret) return ret;
@@ -541,7 +544,7 @@ sys32_sysinfo(struct sysinfo32 __user *info)
541 int bitcount = 0; 544 int bitcount = 0;
542 545
543 set_fs (KERNEL_DS); 546 set_fs (KERNEL_DS);
544 ret = sys_sysinfo(&s); 547 ret = sys_sysinfo((struct sysinfo __user *)&s);
545 set_fs (old_fs); 548 set_fs (old_fs);
546 549
547 /* Check to see if any memory value is too large for 32-bit and scale 550 /* Check to see if any memory value is too large for 32-bit and scale
@@ -589,7 +592,7 @@ sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *int
589 mm_segment_t old_fs = get_fs (); 592 mm_segment_t old_fs = get_fs ();
590 593
591 set_fs (KERNEL_DS); 594 set_fs (KERNEL_DS);
592 ret = sys_sched_rr_get_interval(pid, &t); 595 ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t);
593 set_fs (old_fs); 596 set_fs (old_fs);
594 if (put_compat_timespec(&t, interval)) 597 if (put_compat_timespec(&t, interval))
595 return -EFAULT; 598 return -EFAULT;
@@ -605,7 +608,7 @@ sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize)
605 mm_segment_t old_fs = get_fs(); 608 mm_segment_t old_fs = get_fs();
606 609
607 set_fs (KERNEL_DS); 610 set_fs (KERNEL_DS);
608 ret = sys_rt_sigpending(&s, sigsetsize); 611 ret = sys_rt_sigpending((sigset_t __user *)&s, sigsetsize);
609 set_fs (old_fs); 612 set_fs (old_fs);
610 if (!ret) { 613 if (!ret) {
611 switch (_NSIG_WORDS) { 614 switch (_NSIG_WORDS) {
@@ -630,7 +633,7 @@ sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo)
630 if (copy_siginfo_from_user32(&info, uinfo)) 633 if (copy_siginfo_from_user32(&info, uinfo))
631 return -EFAULT; 634 return -EFAULT;
632 set_fs (KERNEL_DS); 635 set_fs (KERNEL_DS);
633 ret = sys_rt_sigqueueinfo(pid, sig, &info); 636 ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
634 set_fs (old_fs); 637 set_fs (old_fs);
635 return ret; 638 return ret;
636} 639}
@@ -645,7 +648,7 @@ sys32_pause(void)
645} 648}
646 649
647 650
648#ifdef CONFIG_SYSCTL 651#ifdef CONFIG_SYSCTL_SYSCALL
649struct sysctl_ia32 { 652struct sysctl_ia32 {
650 unsigned int name; 653 unsigned int name;
651 int nlen; 654 int nlen;
@@ -666,9 +669,6 @@ sys32_sysctl(struct sysctl_ia32 __user *args32)
666 size_t oldlen; 669 size_t oldlen;
667 int __user *namep; 670 int __user *namep;
668 long ret; 671 long ret;
669 extern int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp,
670 void *newval, size_t newlen);
671
672 672
673 if (copy_from_user(&a32, args32, sizeof (a32))) 673 if (copy_from_user(&a32, args32, sizeof (a32)))
674 return -EFAULT; 674 return -EFAULT;
@@ -692,7 +692,8 @@ sys32_sysctl(struct sysctl_ia32 __user *args32)
692 692
693 set_fs(KERNEL_DS); 693 set_fs(KERNEL_DS);
694 lock_kernel(); 694 lock_kernel();
695 ret = do_sysctl(namep, a32.nlen, oldvalp, &oldlen, newvalp, (size_t) a32.newlen); 695 ret = do_sysctl(namep, a32.nlen, oldvalp, (size_t __user *)&oldlen,
696 newvalp, (size_t) a32.newlen);
696 unlock_kernel(); 697 unlock_kernel();
697 set_fs(old_fs); 698 set_fs(old_fs);
698 699
@@ -743,7 +744,8 @@ sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, s32 count)
743 return -EFAULT; 744 return -EFAULT;
744 745
745 set_fs(KERNEL_DS); 746 set_fs(KERNEL_DS);
746 ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count); 747 ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL,
748 count);
747 set_fs(old_fs); 749 set_fs(old_fs);
748 750
749 if (offset && put_user(of, offset)) 751 if (offset && put_user(of, offset))
@@ -778,7 +780,7 @@ asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
778 780
779asmlinkage long sys32_olduname(struct oldold_utsname __user * name) 781asmlinkage long sys32_olduname(struct oldold_utsname __user * name)
780{ 782{
781 int error; 783 int err;
782 784
783 if (!name) 785 if (!name)
784 return -EFAULT; 786 return -EFAULT;
@@ -787,27 +789,31 @@ asmlinkage long sys32_olduname(struct oldold_utsname __user * name)
787 789
788 down_read(&uts_sem); 790 down_read(&uts_sem);
789 791
790 error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); 792 err = __copy_to_user(&name->sysname,&system_utsname.sysname,
791 __put_user(0,name->sysname+__OLD_UTS_LEN); 793 __OLD_UTS_LEN);
792 __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); 794 err |= __put_user(0,name->sysname+__OLD_UTS_LEN);
793 __put_user(0,name->nodename+__OLD_UTS_LEN); 795 err |= __copy_to_user(&name->nodename,&system_utsname.nodename,
794 __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); 796 __OLD_UTS_LEN);
795 __put_user(0,name->release+__OLD_UTS_LEN); 797 err |= __put_user(0,name->nodename+__OLD_UTS_LEN);
796 __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); 798 err |= __copy_to_user(&name->release,&system_utsname.release,
797 __put_user(0,name->version+__OLD_UTS_LEN); 799 __OLD_UTS_LEN);
800 err |= __put_user(0,name->release+__OLD_UTS_LEN);
801 err |= __copy_to_user(&name->version,&system_utsname.version,
802 __OLD_UTS_LEN);
803 err |= __put_user(0,name->version+__OLD_UTS_LEN);
798 { 804 {
799 char *arch = "x86_64"; 805 char *arch = "x86_64";
800 if (personality(current->personality) == PER_LINUX32) 806 if (personality(current->personality) == PER_LINUX32)
801 arch = "i686"; 807 arch = "i686";
802 808
803 __copy_to_user(&name->machine,arch,strlen(arch)+1); 809 err |= __copy_to_user(&name->machine,arch,strlen(arch)+1);
804 } 810 }
805 811
806 up_read(&uts_sem); 812 up_read(&uts_sem);
807 813
808 error = error ? -EFAULT : 0; 814 err = err ? -EFAULT : 0;
809 815
810 return error; 816 return err;
811} 817}
812 818
813long sys32_uname(struct old_utsname __user * name) 819long sys32_uname(struct old_utsname __user * name)
@@ -831,7 +837,7 @@ long sys32_ustat(unsigned dev, struct ustat32 __user *u32p)
831 837
832 seg = get_fs(); 838 seg = get_fs();
833 set_fs(KERNEL_DS); 839 set_fs(KERNEL_DS);
834 ret = sys_ustat(dev,&u); 840 ret = sys_ustat(dev, (struct ustat __user *)&u);
835 set_fs(seg); 841 set_fs(seg);
836 if (ret >= 0) { 842 if (ret >= 0) {
837 if (!access_ok(VERIFY_WRITE,u32p,sizeof(struct ustat32)) || 843 if (!access_ok(VERIFY_WRITE,u32p,sizeof(struct ustat32)) ||
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile
index b5aaeafc1cd3..3c7cbff04d3d 100644
--- a/arch/x86_64/kernel/Makefile
+++ b/arch/x86_64/kernel/Makefile
@@ -11,7 +11,7 @@ obj-y := process.o signal.o entry.o traps.o irq.o \
11 pci-dma.o pci-nommu.o alternative.o 11 pci-dma.o pci-nommu.o alternative.o
12 12
13obj-$(CONFIG_STACKTRACE) += stacktrace.o 13obj-$(CONFIG_STACKTRACE) += stacktrace.o
14obj-$(CONFIG_X86_MCE) += mce.o 14obj-$(CONFIG_X86_MCE) += mce.o therm_throt.o
15obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o 15obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o
16obj-$(CONFIG_X86_MCE_AMD) += mce_amd.o 16obj-$(CONFIG_X86_MCE_AMD) += mce_amd.o
17obj-$(CONFIG_MTRR) += ../../i386/kernel/cpu/mtrr/ 17obj-$(CONFIG_MTRR) += ../../i386/kernel/cpu/mtrr/
@@ -20,8 +20,8 @@ obj-$(CONFIG_X86_MSR) += msr.o
20obj-$(CONFIG_MICROCODE) += microcode.o 20obj-$(CONFIG_MICROCODE) += microcode.o
21obj-$(CONFIG_X86_CPUID) += cpuid.o 21obj-$(CONFIG_X86_CPUID) += cpuid.o
22obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o 22obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o
23obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o 23obj-y += apic.o nmi.o
24obj-$(CONFIG_X86_IO_APIC) += io_apic.o mpparse.o \ 24obj-y += io_apic.o mpparse.o \
25 genapic.o genapic_cluster.o genapic_flat.o 25 genapic.o genapic_cluster.o genapic_flat.o
26obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o 26obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o
27obj-$(CONFIG_CRASH_DUMP) += crash_dump.o 27obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
@@ -39,12 +39,14 @@ obj-$(CONFIG_K8_NB) += k8.o
39obj-$(CONFIG_AUDIT) += audit.o 39obj-$(CONFIG_AUDIT) += audit.o
40 40
41obj-$(CONFIG_MODULES) += module.o 41obj-$(CONFIG_MODULES) += module.o
42obj-$(CONFIG_PCI) += early-quirks.o
42 43
43obj-y += topology.o 44obj-y += topology.o
44obj-y += intel_cacheinfo.o 45obj-y += intel_cacheinfo.o
45 46
46CFLAGS_vsyscall.o := $(PROFILING) -g0 47CFLAGS_vsyscall.o := $(PROFILING) -g0
47 48
49therm_throt-y += ../../i386/kernel/cpu/mcheck/therm_throt.o
48bootflag-y += ../../i386/kernel/bootflag.o 50bootflag-y += ../../i386/kernel/bootflag.o
49cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o 51cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o
50topology-y += ../../i386/kernel/topology.o 52topology-y += ../../i386/kernel/topology.o
@@ -54,4 +56,3 @@ quirks-y += ../../i386/kernel/quirks.o
54i8237-y += ../../i386/kernel/i8237.o 56i8237-y += ../../i386/kernel/i8237.o
55msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o 57msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o
56alternative-y += ../../i386/kernel/alternative.o 58alternative-y += ../../i386/kernel/alternative.o
57
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c
index 58af8e73738b..b487396c4c5b 100644
--- a/arch/x86_64/kernel/aperture.c
+++ b/arch/x86_64/kernel/aperture.c
@@ -17,6 +17,7 @@
17#include <linux/pci_ids.h> 17#include <linux/pci_ids.h>
18#include <linux/pci.h> 18#include <linux/pci.h>
19#include <linux/bitops.h> 19#include <linux/bitops.h>
20#include <linux/ioport.h>
20#include <asm/e820.h> 21#include <asm/e820.h>
21#include <asm/io.h> 22#include <asm/io.h>
22#include <asm/proto.h> 23#include <asm/proto.h>
@@ -33,6 +34,18 @@ int fallback_aper_force __initdata = 0;
33 34
34int fix_aperture __initdata = 1; 35int fix_aperture __initdata = 1;
35 36
37static struct resource gart_resource = {
38 .name = "GART",
39 .flags = IORESOURCE_MEM,
40};
41
42static void __init insert_aperture_resource(u32 aper_base, u32 aper_size)
43{
44 gart_resource.start = aper_base;
45 gart_resource.end = aper_base + aper_size - 1;
46 insert_resource(&iomem_resource, &gart_resource);
47}
48
36/* This code runs before the PCI subsystem is initialized, so just 49/* This code runs before the PCI subsystem is initialized, so just
37 access the northbridge directly. */ 50 access the northbridge directly. */
38 51
@@ -48,7 +61,7 @@ static u32 __init allocate_aperture(void)
48 61
49 /* 62 /*
50 * Aperture has to be naturally aligned. This means an 2GB aperture won't 63 * Aperture has to be naturally aligned. This means an 2GB aperture won't
51 * have much chances to find a place in the lower 4GB of memory. 64 * have much chance of finding a place in the lower 4GB of memory.
52 * Unfortunately we cannot move it up because that would make the 65 * Unfortunately we cannot move it up because that would make the
53 * IOMMU useless. 66 * IOMMU useless.
54 */ 67 */
@@ -62,6 +75,7 @@ static u32 __init allocate_aperture(void)
62 } 75 }
63 printk("Mapping aperture over %d KB of RAM @ %lx\n", 76 printk("Mapping aperture over %d KB of RAM @ %lx\n",
64 aper_size >> 10, __pa(p)); 77 aper_size >> 10, __pa(p));
78 insert_aperture_resource((u32)__pa(p), aper_size);
65 return (u32)__pa(p); 79 return (u32)__pa(p);
66} 80}
67 81
@@ -198,7 +212,7 @@ void __init iommu_hole_init(void)
198 u64 aper_base, last_aper_base = 0; 212 u64 aper_base, last_aper_base = 0;
199 int valid_agp = 0; 213 int valid_agp = 0;
200 214
201 if (iommu_aperture_disabled || !fix_aperture) 215 if (iommu_aperture_disabled || !fix_aperture || !early_pci_allowed())
202 return; 216 return;
203 217
204 printk("Checking aperture...\n"); 218 printk("Checking aperture...\n");
@@ -233,8 +247,13 @@ void __init iommu_hole_init(void)
233 last_aper_base = aper_base; 247 last_aper_base = aper_base;
234 } 248 }
235 249
236 if (!fix && !fallback_aper_force) 250 if (!fix && !fallback_aper_force) {
251 if (last_aper_base) {
252 unsigned long n = (32 * 1024 * 1024) << last_aper_order;
253 insert_aperture_resource((u32)last_aper_base, n);
254 }
237 return; 255 return;
256 }
238 257
239 if (!fallback_aper_force) 258 if (!fallback_aper_force)
240 aper_alloc = search_agp_bridge(&aper_order, &valid_agp); 259 aper_alloc = search_agp_bridge(&aper_order, &valid_agp);
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index 2b8cef037a65..135ff25e6b44 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -25,6 +25,7 @@
25#include <linux/kernel_stat.h> 25#include <linux/kernel_stat.h>
26#include <linux/sysdev.h> 26#include <linux/sysdev.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/ioport.h>
28 29
29#include <asm/atomic.h> 30#include <asm/atomic.h>
30#include <asm/smp.h> 31#include <asm/smp.h>
@@ -36,13 +37,20 @@
36#include <asm/idle.h> 37#include <asm/idle.h>
37#include <asm/proto.h> 38#include <asm/proto.h>
38#include <asm/timex.h> 39#include <asm/timex.h>
40#include <asm/apic.h>
39 41
42int apic_mapped;
40int apic_verbosity; 43int apic_verbosity;
41int apic_runs_main_timer; 44int apic_runs_main_timer;
42int apic_calibrate_pmtmr __initdata; 45int apic_calibrate_pmtmr __initdata;
43 46
44int disable_apic_timer __initdata; 47int disable_apic_timer __initdata;
45 48
49static struct resource lapic_resource = {
50 .name = "Local APIC",
51 .flags = IORESOURCE_MEM | IORESOURCE_BUSY,
52};
53
46/* 54/*
47 * cpu_mask that denotes the CPUs that needs timer interrupt coming in as 55 * cpu_mask that denotes the CPUs that needs timer interrupt coming in as
48 * IPIs in place of local APIC timers 56 * IPIs in place of local APIC timers
@@ -136,72 +144,40 @@ void clear_local_APIC(void)
136 apic_read(APIC_ESR); 144 apic_read(APIC_ESR);
137} 145}
138 146
139void __init connect_bsp_APIC(void)
140{
141 if (pic_mode) {
142 /*
143 * Do not trust the local APIC being empty at bootup.
144 */
145 clear_local_APIC();
146 /*
147 * PIC mode, enable APIC mode in the IMCR, i.e.
148 * connect BSP's local APIC to INT and NMI lines.
149 */
150 apic_printk(APIC_VERBOSE, "leaving PIC mode, enabling APIC mode.\n");
151 outb(0x70, 0x22);
152 outb(0x01, 0x23);
153 }
154}
155
156void disconnect_bsp_APIC(int virt_wire_setup) 147void disconnect_bsp_APIC(int virt_wire_setup)
157{ 148{
158 if (pic_mode) { 149 /* Go back to Virtual Wire compatibility mode */
159 /* 150 unsigned long value;
160 * Put the board back into PIC mode (has an effect 151
161 * only on certain older boards). Note that APIC 152 /* For the spurious interrupt use vector F, and enable it */
162 * interrupts, including IPIs, won't work beyond 153 value = apic_read(APIC_SPIV);
163 * this point! The only exception are INIT IPIs. 154 value &= ~APIC_VECTOR_MASK;
164 */ 155 value |= APIC_SPIV_APIC_ENABLED;
165 apic_printk(APIC_QUIET, "disabling APIC mode, entering PIC mode.\n"); 156 value |= 0xf;
166 outb(0x70, 0x22); 157 apic_write(APIC_SPIV, value);
167 outb(0x00, 0x23);
168 }
169 else {
170 /* Go back to Virtual Wire compatibility mode */
171 unsigned long value;
172
173 /* For the spurious interrupt use vector F, and enable it */
174 value = apic_read(APIC_SPIV);
175 value &= ~APIC_VECTOR_MASK;
176 value |= APIC_SPIV_APIC_ENABLED;
177 value |= 0xf;
178 apic_write(APIC_SPIV, value);
179
180 if (!virt_wire_setup) {
181 /* For LVT0 make it edge triggered, active high, external and enabled */
182 value = apic_read(APIC_LVT0);
183 value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
184 APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
185 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED );
186 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
187 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
188 apic_write(APIC_LVT0, value);
189 }
190 else {
191 /* Disable LVT0 */
192 apic_write(APIC_LVT0, APIC_LVT_MASKED);
193 }
194 158
195 /* For LVT1 make it edge triggered, active high, nmi and enabled */ 159 if (!virt_wire_setup) {
196 value = apic_read(APIC_LVT1); 160 /* For LVT0 make it edge triggered, active high, external and enabled */
197 value &= ~( 161 value = apic_read(APIC_LVT0);
198 APIC_MODE_MASK | APIC_SEND_PENDING | 162 value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
199 APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | 163 APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
200 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); 164 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED );
201 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; 165 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
202 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI); 166 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
203 apic_write(APIC_LVT1, value); 167 apic_write(APIC_LVT0, value);
168 } else {
169 /* Disable LVT0 */
170 apic_write(APIC_LVT0, APIC_LVT_MASKED);
204 } 171 }
172
173 /* For LVT1 make it edge triggered, active high, nmi and enabled */
174 value = apic_read(APIC_LVT1);
175 value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
176 APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
177 APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
178 value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
179 value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
180 apic_write(APIC_LVT1, value);
205} 181}
206 182
207void disable_local_APIC(void) 183void disable_local_APIC(void)
@@ -297,8 +273,6 @@ void __init sync_Arb_IDs(void)
297 | APIC_DM_INIT); 273 | APIC_DM_INIT);
298} 274}
299 275
300extern void __error_in_apic_c (void);
301
302/* 276/*
303 * An initial setup of the virtual wire mode. 277 * An initial setup of the virtual wire mode.
304 */ 278 */
@@ -345,8 +319,7 @@ void __cpuinit setup_local_APIC (void)
345 319
346 value = apic_read(APIC_LVR); 320 value = apic_read(APIC_LVR);
347 321
348 if ((SPURIOUS_APIC_VECTOR & 0x0f) != 0x0f) 322 BUILD_BUG_ON((SPURIOUS_APIC_VECTOR & 0x0f) != 0x0f);
349 __error_in_apic_c();
350 323
351 /* 324 /*
352 * Double-check whether this APIC is really registered. 325 * Double-check whether this APIC is really registered.
@@ -399,32 +372,8 @@ void __cpuinit setup_local_APIC (void)
399 */ 372 */
400 value |= APIC_SPIV_APIC_ENABLED; 373 value |= APIC_SPIV_APIC_ENABLED;
401 374
402 /* 375 /* We always use processor focus */
403 * Some unknown Intel IO/APIC (or APIC) errata is biting us with 376
404 * certain networking cards. If high frequency interrupts are
405 * happening on a particular IOAPIC pin, plus the IOAPIC routing
406 * entry is masked/unmasked at a high rate as well then sooner or
407 * later IOAPIC line gets 'stuck', no more interrupts are received
408 * from the device. If focus CPU is disabled then the hang goes
409 * away, oh well :-(
410 *
411 * [ This bug can be reproduced easily with a level-triggered
412 * PCI Ne2000 networking cards and PII/PIII processors, dual
413 * BX chipset. ]
414 */
415 /*
416 * Actually disabling the focus CPU check just makes the hang less
417 * frequent as it makes the interrupt distributon model be more
418 * like LRU than MRU (the short-term load is more even across CPUs).
419 * See also the comment in end_level_ioapic_irq(). --macro
420 */
421#if 1
422 /* Enable focus processor (bit==0) */
423 value &= ~APIC_SPIV_FOCUS_DISABLED;
424#else
425 /* Disable focus processor (bit==1) */
426 value |= APIC_SPIV_FOCUS_DISABLED;
427#endif
428 /* 377 /*
429 * Set spurious IRQ vector 378 * Set spurious IRQ vector
430 */ 379 */
@@ -442,7 +391,7 @@ void __cpuinit setup_local_APIC (void)
442 * TODO: set up through-local-APIC from through-I/O-APIC? --macro 391 * TODO: set up through-local-APIC from through-I/O-APIC? --macro
443 */ 392 */
444 value = apic_read(APIC_LVT0) & APIC_LVT_MASKED; 393 value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
445 if (!smp_processor_id() && (pic_mode || !value)) { 394 if (!smp_processor_id() && !value) {
446 value = APIC_DM_EXTINT; 395 value = APIC_DM_EXTINT;
447 apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n", smp_processor_id()); 396 apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n", smp_processor_id());
448 } else { 397 } else {
@@ -479,8 +428,7 @@ void __cpuinit setup_local_APIC (void)
479 } 428 }
480 429
481 nmi_watchdog_default(); 430 nmi_watchdog_default();
482 if (nmi_watchdog == NMI_LOCAL_APIC) 431 setup_apic_nmi_watchdog(NULL);
483 setup_apic_nmi_watchdog();
484 apic_pm_activate(); 432 apic_pm_activate();
485} 433}
486 434
@@ -527,8 +475,7 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state)
527 apic_pm_state.apic_tmict = apic_read(APIC_TMICT); 475 apic_pm_state.apic_tmict = apic_read(APIC_TMICT);
528 apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); 476 apic_pm_state.apic_tdcr = apic_read(APIC_TDCR);
529 apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); 477 apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR);
530 local_save_flags(flags); 478 local_irq_save(flags);
531 local_irq_disable();
532 disable_local_APIC(); 479 disable_local_APIC();
533 local_irq_restore(flags); 480 local_irq_restore(flags);
534 return 0; 481 return 0;
@@ -606,18 +553,24 @@ static void apic_pm_activate(void) { }
606 553
607static int __init apic_set_verbosity(char *str) 554static int __init apic_set_verbosity(char *str)
608{ 555{
556 if (str == NULL) {
557 skip_ioapic_setup = 0;
558 ioapic_force = 1;
559 return 0;
560 }
609 if (strcmp("debug", str) == 0) 561 if (strcmp("debug", str) == 0)
610 apic_verbosity = APIC_DEBUG; 562 apic_verbosity = APIC_DEBUG;
611 else if (strcmp("verbose", str) == 0) 563 else if (strcmp("verbose", str) == 0)
612 apic_verbosity = APIC_VERBOSE; 564 apic_verbosity = APIC_VERBOSE;
613 else 565 else {
614 printk(KERN_WARNING "APIC Verbosity level %s not recognised" 566 printk(KERN_WARNING "APIC Verbosity level %s not recognised"
615 " use apic=verbose or apic=debug", str); 567 " use apic=verbose or apic=debug\n", str);
568 return -EINVAL;
569 }
616 570
617 return 1; 571 return 0;
618} 572}
619 573early_param("apic", apic_set_verbosity);
620__setup("apic=", apic_set_verbosity);
621 574
622/* 575/*
623 * Detect and enable local APICs on non-SMP boards. 576 * Detect and enable local APICs on non-SMP boards.
@@ -638,6 +591,40 @@ static int __init detect_init_APIC (void)
638 return 0; 591 return 0;
639} 592}
640 593
594#ifdef CONFIG_X86_IO_APIC
595static struct resource * __init ioapic_setup_resources(void)
596{
597#define IOAPIC_RESOURCE_NAME_SIZE 11
598 unsigned long n;
599 struct resource *res;
600 char *mem;
601 int i;
602
603 if (nr_ioapics <= 0)
604 return NULL;
605
606 n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource);
607 n *= nr_ioapics;
608
609 res = alloc_bootmem(n);
610
611 if (!res)
612 return NULL;
613
614 memset(res, 0, n);
615 mem = (void *)&res[nr_ioapics];
616
617 for (i = 0; i < nr_ioapics; i++) {
618 res[i].name = mem;
619 res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
620 snprintf(mem, IOAPIC_RESOURCE_NAME_SIZE, "IOAPIC %u", i);
621 mem += IOAPIC_RESOURCE_NAME_SIZE;
622 }
623
624 return res;
625}
626#endif
627
641void __init init_apic_mappings(void) 628void __init init_apic_mappings(void)
642{ 629{
643 unsigned long apic_phys; 630 unsigned long apic_phys;
@@ -654,19 +641,26 @@ void __init init_apic_mappings(void)
654 apic_phys = mp_lapic_addr; 641 apic_phys = mp_lapic_addr;
655 642
656 set_fixmap_nocache(FIX_APIC_BASE, apic_phys); 643 set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
644 apic_mapped = 1;
657 apic_printk(APIC_VERBOSE,"mapped APIC to %16lx (%16lx)\n", APIC_BASE, apic_phys); 645 apic_printk(APIC_VERBOSE,"mapped APIC to %16lx (%16lx)\n", APIC_BASE, apic_phys);
658 646
647 /* Put local APIC into the resource map. */
648 lapic_resource.start = apic_phys;
649 lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1;
650 insert_resource(&iomem_resource, &lapic_resource);
651
659 /* 652 /*
660 * Fetch the APIC ID of the BSP in case we have a 653 * Fetch the APIC ID of the BSP in case we have a
661 * default configuration (or the MP table is broken). 654 * default configuration (or the MP table is broken).
662 */ 655 */
663 boot_cpu_id = GET_APIC_ID(apic_read(APIC_ID)); 656 boot_cpu_id = GET_APIC_ID(apic_read(APIC_ID));
664 657
665#ifdef CONFIG_X86_IO_APIC
666 { 658 {
667 unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; 659 unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
668 int i; 660 int i;
661 struct resource *ioapic_res;
669 662
663 ioapic_res = ioapic_setup_resources();
670 for (i = 0; i < nr_ioapics; i++) { 664 for (i = 0; i < nr_ioapics; i++) {
671 if (smp_found_config) { 665 if (smp_found_config) {
672 ioapic_phys = mp_ioapics[i].mpc_apicaddr; 666 ioapic_phys = mp_ioapics[i].mpc_apicaddr;
@@ -678,9 +672,15 @@ void __init init_apic_mappings(void)
678 apic_printk(APIC_VERBOSE,"mapped IOAPIC to %016lx (%016lx)\n", 672 apic_printk(APIC_VERBOSE,"mapped IOAPIC to %016lx (%016lx)\n",
679 __fix_to_virt(idx), ioapic_phys); 673 __fix_to_virt(idx), ioapic_phys);
680 idx++; 674 idx++;
675
676 if (ioapic_res) {
677 ioapic_res->start = ioapic_phys;
678 ioapic_res->end = ioapic_phys + (4 * 1024) - 1;
679 insert_resource(&iomem_resource, ioapic_res);
680 ioapic_res++;
681 }
681 } 682 }
682 } 683 }
683#endif
684} 684}
685 685
686/* 686/*
@@ -951,7 +951,7 @@ void smp_local_timer_interrupt(struct pt_regs *regs)
951 * We take the 'long' return path, and there every subsystem 951 * We take the 'long' return path, and there every subsystem
952 * grabs the appropriate locks (kernel lock/ irq lock). 952 * grabs the appropriate locks (kernel lock/ irq lock).
953 * 953 *
954 * we might want to decouple profiling from the 'long path', 954 * We might want to decouple profiling from the 'long path',
955 * and do the profiling totally in assembly. 955 * and do the profiling totally in assembly.
956 * 956 *
957 * Currently this isn't too much of an issue (performance wise), 957 * Currently this isn't too much of an issue (performance wise),
@@ -1123,19 +1123,15 @@ int __init APIC_init_uniprocessor (void)
1123 1123
1124 verify_local_APIC(); 1124 verify_local_APIC();
1125 1125
1126 connect_bsp_APIC();
1127
1128 phys_cpu_present_map = physid_mask_of_physid(boot_cpu_id); 1126 phys_cpu_present_map = physid_mask_of_physid(boot_cpu_id);
1129 apic_write(APIC_ID, SET_APIC_ID(boot_cpu_id)); 1127 apic_write(APIC_ID, SET_APIC_ID(boot_cpu_id));
1130 1128
1131 setup_local_APIC(); 1129 setup_local_APIC();
1132 1130
1133#ifdef CONFIG_X86_IO_APIC
1134 if (smp_found_config && !skip_ioapic_setup && nr_ioapics) 1131 if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
1135 setup_IO_APIC(); 1132 setup_IO_APIC();
1136 else 1133 else
1137 nr_ioapics = 0; 1134 nr_ioapics = 0;
1138#endif
1139 setup_boot_APIC_clock(); 1135 setup_boot_APIC_clock();
1140 check_nmi_watchdog(); 1136 check_nmi_watchdog();
1141 return 0; 1137 return 0;
@@ -1144,14 +1140,17 @@ int __init APIC_init_uniprocessor (void)
1144static __init int setup_disableapic(char *str) 1140static __init int setup_disableapic(char *str)
1145{ 1141{
1146 disable_apic = 1; 1142 disable_apic = 1;
1147 return 1; 1143 clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
1148} 1144 return 0;
1145}
1146early_param("disableapic", setup_disableapic);
1149 1147
1148/* same as disableapic, for compatibility */
1150static __init int setup_nolapic(char *str) 1149static __init int setup_nolapic(char *str)
1151{ 1150{
1152 disable_apic = 1; 1151 return setup_disableapic(str);
1153 return 1;
1154} 1152}
1153early_param("nolapic", setup_nolapic);
1155 1154
1156static __init int setup_noapictimer(char *str) 1155static __init int setup_noapictimer(char *str)
1157{ 1156{
@@ -1184,11 +1183,5 @@ static __init int setup_apicpmtimer(char *s)
1184} 1183}
1185__setup("apicpmtimer", setup_apicpmtimer); 1184__setup("apicpmtimer", setup_apicpmtimer);
1186 1185
1187/* dummy parsing: see setup.c */
1188
1189__setup("disableapic", setup_disableapic);
1190__setup("nolapic", setup_nolapic); /* same as disableapic, for compatibility */
1191
1192__setup("noapictimer", setup_noapictimer); 1186__setup("noapictimer", setup_noapictimer);
1193 1187
1194/* no "lapic" flag - we only use the lapic when the BIOS tells us so. */
diff --git a/arch/x86_64/kernel/crash.c b/arch/x86_64/kernel/crash.c
index d8d5750d6106..3525f884af82 100644
--- a/arch/x86_64/kernel/crash.c
+++ b/arch/x86_64/kernel/crash.c
@@ -23,6 +23,7 @@
23#include <asm/nmi.h> 23#include <asm/nmi.h>
24#include <asm/hw_irq.h> 24#include <asm/hw_irq.h>
25#include <asm/mach_apic.h> 25#include <asm/mach_apic.h>
26#include <asm/kdebug.h>
26 27
27/* This keeps a track of which one is crashing cpu. */ 28/* This keeps a track of which one is crashing cpu. */
28static int crashing_cpu; 29static int crashing_cpu;
@@ -68,7 +69,7 @@ static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
68 * for the data I pass, and I need tags 69 * for the data I pass, and I need tags
69 * on the data to indicate what information I have 70 * on the data to indicate what information I have
70 * squirrelled away. ELF notes happen to provide 71 * squirrelled away. ELF notes happen to provide
71 * all of that that no need to invent something new. 72 * all of that, no need to invent something new.
72 */ 73 */
73 74
74 buf = (u32*)per_cpu_ptr(crash_notes, cpu); 75 buf = (u32*)per_cpu_ptr(crash_notes, cpu);
@@ -95,15 +96,25 @@ static void crash_save_self(struct pt_regs *regs)
95#ifdef CONFIG_SMP 96#ifdef CONFIG_SMP
96static atomic_t waiting_for_crash_ipi; 97static atomic_t waiting_for_crash_ipi;
97 98
98static int crash_nmi_callback(struct pt_regs *regs, int cpu) 99static int crash_nmi_callback(struct notifier_block *self,
100 unsigned long val, void *data)
99{ 101{
102 struct pt_regs *regs;
103 int cpu;
104
105 if (val != DIE_NMI_IPI)
106 return NOTIFY_OK;
107
108 regs = ((struct die_args *)data)->regs;
109 cpu = raw_smp_processor_id();
110
100 /* 111 /*
101 * Don't do anything if this handler is invoked on crashing cpu. 112 * Don't do anything if this handler is invoked on crashing cpu.
102 * Otherwise, system will completely hang. Crashing cpu can get 113 * Otherwise, system will completely hang. Crashing cpu can get
103 * an NMI if system was initially booted with nmi_watchdog parameter. 114 * an NMI if system was initially booted with nmi_watchdog parameter.
104 */ 115 */
105 if (cpu == crashing_cpu) 116 if (cpu == crashing_cpu)
106 return 1; 117 return NOTIFY_STOP;
107 local_irq_disable(); 118 local_irq_disable();
108 119
109 crash_save_this_cpu(regs, cpu); 120 crash_save_this_cpu(regs, cpu);
@@ -127,12 +138,17 @@ static void smp_send_nmi_allbutself(void)
127 * cpu hotplug shouldn't matter. 138 * cpu hotplug shouldn't matter.
128 */ 139 */
129 140
141static struct notifier_block crash_nmi_nb = {
142 .notifier_call = crash_nmi_callback,
143};
144
130static void nmi_shootdown_cpus(void) 145static void nmi_shootdown_cpus(void)
131{ 146{
132 unsigned long msecs; 147 unsigned long msecs;
133 148
134 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); 149 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
135 set_nmi_callback(crash_nmi_callback); 150 if (register_die_notifier(&crash_nmi_nb))
151 return; /* return what? */
136 152
137 /* 153 /*
138 * Ensure the new callback function is set before sending 154 * Ensure the new callback function is set before sending
@@ -178,9 +194,7 @@ void machine_crash_shutdown(struct pt_regs *regs)
178 if(cpu_has_apic) 194 if(cpu_has_apic)
179 disable_local_APIC(); 195 disable_local_APIC();
180 196
181#if defined(CONFIG_X86_IO_APIC)
182 disable_IO_APIC(); 197 disable_IO_APIC();
183#endif
184 198
185 crash_save_self(regs); 199 crash_save_self(regs);
186} 200}
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c
index d6d7f731f6f0..b3f0908668ec 100644
--- a/arch/x86_64/kernel/e820.c
+++ b/arch/x86_64/kernel/e820.c
@@ -16,6 +16,7 @@
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/kexec.h> 17#include <linux/kexec.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/mm.h>
19 20
20#include <asm/pgtable.h> 21#include <asm/pgtable.h>
21#include <asm/page.h> 22#include <asm/page.h>
@@ -24,6 +25,8 @@
24#include <asm/bootsetup.h> 25#include <asm/bootsetup.h>
25#include <asm/sections.h> 26#include <asm/sections.h>
26 27
28struct e820map e820 __initdata;
29
27/* 30/*
28 * PFN of last memory page. 31 * PFN of last memory page.
29 */ 32 */
@@ -40,7 +43,7 @@ unsigned long end_pfn_map;
40/* 43/*
41 * Last pfn which the user wants to use. 44 * Last pfn which the user wants to use.
42 */ 45 */
43unsigned long end_user_pfn = MAXMEM>>PAGE_SHIFT; 46static unsigned long __initdata end_user_pfn = MAXMEM>>PAGE_SHIFT;
44 47
45extern struct resource code_resource, data_resource; 48extern struct resource code_resource, data_resource;
46 49
@@ -69,12 +72,7 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size)
69 return 1; 72 return 1;
70 } 73 }
71#endif 74#endif
72 /* kernel code + 640k memory hole (later should not be needed, but 75 /* kernel code */
73 be paranoid for now) */
74 if (last >= 640*1024 && addr < 1024*1024) {
75 *addrp = 1024*1024;
76 return 1;
77 }
78 if (last >= __pa_symbol(&_text) && last < __pa_symbol(&_end)) { 76 if (last >= __pa_symbol(&_text) && last < __pa_symbol(&_end)) {
79 *addrp = __pa_symbol(&_end); 77 *addrp = __pa_symbol(&_end);
80 return 1; 78 return 1;
@@ -164,59 +162,14 @@ unsigned long __init find_e820_area(unsigned long start, unsigned long end, unsi
164 return -1UL; 162 return -1UL;
165} 163}
166 164
167/*
168 * Free bootmem based on the e820 table for a node.
169 */
170void __init e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end)
171{
172 int i;
173 for (i = 0; i < e820.nr_map; i++) {
174 struct e820entry *ei = &e820.map[i];
175 unsigned long last, addr;
176
177 if (ei->type != E820_RAM ||
178 ei->addr+ei->size <= start ||
179 ei->addr >= end)
180 continue;
181
182 addr = round_up(ei->addr, PAGE_SIZE);
183 if (addr < start)
184 addr = start;
185
186 last = round_down(ei->addr + ei->size, PAGE_SIZE);
187 if (last >= end)
188 last = end;
189
190 if (last > addr && last-addr >= PAGE_SIZE)
191 free_bootmem_node(pgdat, addr, last-addr);
192 }
193}
194
195/* 165/*
196 * Find the highest page frame number we have available 166 * Find the highest page frame number we have available
197 */ 167 */
198unsigned long __init e820_end_of_ram(void) 168unsigned long __init e820_end_of_ram(void)
199{ 169{
200 int i;
201 unsigned long end_pfn = 0; 170 unsigned long end_pfn = 0;
171 end_pfn = find_max_pfn_with_active_regions();
202 172
203 for (i = 0; i < e820.nr_map; i++) {
204 struct e820entry *ei = &e820.map[i];
205 unsigned long start, end;
206
207 start = round_up(ei->addr, PAGE_SIZE);
208 end = round_down(ei->addr + ei->size, PAGE_SIZE);
209 if (start >= end)
210 continue;
211 if (ei->type == E820_RAM) {
212 if (end > end_pfn<<PAGE_SHIFT)
213 end_pfn = end>>PAGE_SHIFT;
214 } else {
215 if (end > end_pfn_map<<PAGE_SHIFT)
216 end_pfn_map = end>>PAGE_SHIFT;
217 }
218 }
219
220 if (end_pfn > end_pfn_map) 173 if (end_pfn > end_pfn_map)
221 end_pfn_map = end_pfn; 174 end_pfn_map = end_pfn;
222 if (end_pfn_map > MAXMEM>>PAGE_SHIFT) 175 if (end_pfn_map > MAXMEM>>PAGE_SHIFT)
@@ -226,43 +179,10 @@ unsigned long __init e820_end_of_ram(void)
226 if (end_pfn > end_pfn_map) 179 if (end_pfn > end_pfn_map)
227 end_pfn = end_pfn_map; 180 end_pfn = end_pfn_map;
228 181
182 printk("end_pfn_map = %lu\n", end_pfn_map);
229 return end_pfn; 183 return end_pfn;
230} 184}
231 185
232/*
233 * Compute how much memory is missing in a range.
234 * Unlike the other functions in this file the arguments are in page numbers.
235 */
236unsigned long __init
237e820_hole_size(unsigned long start_pfn, unsigned long end_pfn)
238{
239 unsigned long ram = 0;
240 unsigned long start = start_pfn << PAGE_SHIFT;
241 unsigned long end = end_pfn << PAGE_SHIFT;
242 int i;
243 for (i = 0; i < e820.nr_map; i++) {
244 struct e820entry *ei = &e820.map[i];
245 unsigned long last, addr;
246
247 if (ei->type != E820_RAM ||
248 ei->addr+ei->size <= start ||
249 ei->addr >= end)
250 continue;
251
252 addr = round_up(ei->addr, PAGE_SIZE);
253 if (addr < start)
254 addr = start;
255
256 last = round_down(ei->addr + ei->size, PAGE_SIZE);
257 if (last >= end)
258 last = end;
259
260 if (last > addr)
261 ram += last - addr;
262 }
263 return ((end - start) - ram) >> PAGE_SHIFT;
264}
265
266/* 186/*
267 * Mark e820 reserved areas as busy for the resource manager. 187 * Mark e820 reserved areas as busy for the resource manager.
268 */ 188 */
@@ -297,6 +217,96 @@ void __init e820_reserve_resources(void)
297 } 217 }
298} 218}
299 219
220/* Mark pages corresponding to given address range as nosave */
221static void __init
222e820_mark_nosave_range(unsigned long start, unsigned long end)
223{
224 unsigned long pfn, max_pfn;
225
226 if (start >= end)
227 return;
228
229 printk("Nosave address range: %016lx - %016lx\n", start, end);
230 max_pfn = end >> PAGE_SHIFT;
231 for (pfn = start >> PAGE_SHIFT; pfn < max_pfn; pfn++)
232 if (pfn_valid(pfn))
233 SetPageNosave(pfn_to_page(pfn));
234}
235
236/*
237 * Find the ranges of physical addresses that do not correspond to
238 * e820 RAM areas and mark the corresponding pages as nosave for software
239 * suspend and suspend to RAM.
240 *
241 * This function requires the e820 map to be sorted and without any
242 * overlapping entries and assumes the first e820 area to be RAM.
243 */
244void __init e820_mark_nosave_regions(void)
245{
246 int i;
247 unsigned long paddr;
248
249 paddr = round_down(e820.map[0].addr + e820.map[0].size, PAGE_SIZE);
250 for (i = 1; i < e820.nr_map; i++) {
251 struct e820entry *ei = &e820.map[i];
252
253 if (paddr < ei->addr)
254 e820_mark_nosave_range(paddr,
255 round_up(ei->addr, PAGE_SIZE));
256
257 paddr = round_down(ei->addr + ei->size, PAGE_SIZE);
258 if (ei->type != E820_RAM)
259 e820_mark_nosave_range(round_up(ei->addr, PAGE_SIZE),
260 paddr);
261
262 if (paddr >= (end_pfn << PAGE_SHIFT))
263 break;
264 }
265}
266
267/* Walk the e820 map and register active regions within a node */
268void __init
269e820_register_active_regions(int nid, unsigned long start_pfn,
270 unsigned long end_pfn)
271{
272 int i;
273 unsigned long ei_startpfn, ei_endpfn;
274 for (i = 0; i < e820.nr_map; i++) {
275 struct e820entry *ei = &e820.map[i];
276 ei_startpfn = round_up(ei->addr, PAGE_SIZE) >> PAGE_SHIFT;
277 ei_endpfn = round_down(ei->addr + ei->size, PAGE_SIZE)
278 >> PAGE_SHIFT;
279
280 /* Skip map entries smaller than a page */
281 if (ei_startpfn > ei_endpfn)
282 continue;
283
284 /* Check if end_pfn_map should be updated */
285 if (ei->type != E820_RAM && ei_endpfn > end_pfn_map)
286 end_pfn_map = ei_endpfn;
287
288 /* Skip if map is outside the node */
289 if (ei->type != E820_RAM ||
290 ei_endpfn <= start_pfn ||
291 ei_startpfn >= end_pfn)
292 continue;
293
294 /* Check for overlaps */
295 if (ei_startpfn < start_pfn)
296 ei_startpfn = start_pfn;
297 if (ei_endpfn > end_pfn)
298 ei_endpfn = end_pfn;
299
300 /* Obey end_user_pfn to save on memmap */
301 if (ei_startpfn >= end_user_pfn)
302 continue;
303 if (ei_endpfn > end_user_pfn)
304 ei_endpfn = end_user_pfn;
305
306 add_active_range(nid, ei_startpfn, ei_endpfn);
307 }
308}
309
300/* 310/*
301 * Add a memory region to the kernel e820 map. 311 * Add a memory region to the kernel e820 map.
302 */ 312 */
@@ -517,13 +527,6 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
517 * If we're lucky and live on a modern system, the setup code 527 * If we're lucky and live on a modern system, the setup code
518 * will have given us a memory map that we can use to properly 528 * will have given us a memory map that we can use to properly
519 * set up memory. If we aren't, we'll fake a memory map. 529 * set up memory. If we aren't, we'll fake a memory map.
520 *
521 * We check to see that the memory map contains at least 2 elements
522 * before we'll use it, because the detection code in setup.S may
523 * not be perfect and most every PC known to man has two memory
524 * regions: one from 0 to 640k, and one from 1mb up. (The IBM
525 * thinkpad 560x, for example, does not cooperate with the memory
526 * detection code.)
527 */ 530 */
528static int __init copy_e820_map(struct e820entry * biosmap, int nr_map) 531static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
529{ 532{
@@ -541,34 +544,19 @@ static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
541 if (start > end) 544 if (start > end)
542 return -1; 545 return -1;
543 546
544 /*
545 * Some BIOSes claim RAM in the 640k - 1M region.
546 * Not right. Fix it up.
547 *
548 * This should be removed on Hammer which is supposed to not
549 * have non e820 covered ISA mappings there, but I had some strange
550 * problems so it stays for now. -AK
551 */
552 if (type == E820_RAM) {
553 if (start < 0x100000ULL && end > 0xA0000ULL) {
554 if (start < 0xA0000ULL)
555 add_memory_region(start, 0xA0000ULL-start, type);
556 if (end <= 0x100000ULL)
557 continue;
558 start = 0x100000ULL;
559 size = end - start;
560 }
561 }
562
563 add_memory_region(start, size, type); 547 add_memory_region(start, size, type);
564 } while (biosmap++,--nr_map); 548 } while (biosmap++,--nr_map);
565 return 0; 549 return 0;
566} 550}
567 551
568void __init setup_memory_region(void) 552void early_panic(char *msg)
569{ 553{
570 char *who = "BIOS-e820"; 554 early_printk(msg);
555 panic(msg);
556}
571 557
558void __init setup_memory_region(void)
559{
572 /* 560 /*
573 * Try to copy the BIOS-supplied E820-map. 561 * Try to copy the BIOS-supplied E820-map.
574 * 562 *
@@ -576,51 +564,70 @@ void __init setup_memory_region(void)
576 * the next section from 1mb->appropriate_mem_k 564 * the next section from 1mb->appropriate_mem_k
577 */ 565 */
578 sanitize_e820_map(E820_MAP, &E820_MAP_NR); 566 sanitize_e820_map(E820_MAP, &E820_MAP_NR);
579 if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) { 567 if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0)
580 unsigned long mem_size; 568 early_panic("Cannot find a valid memory map");
581
582 /* compare results from other methods and take the greater */
583 if (ALT_MEM_K < EXT_MEM_K) {
584 mem_size = EXT_MEM_K;
585 who = "BIOS-88";
586 } else {
587 mem_size = ALT_MEM_K;
588 who = "BIOS-e801";
589 }
590
591 e820.nr_map = 0;
592 add_memory_region(0, LOWMEMSIZE(), E820_RAM);
593 add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM);
594 }
595 printk(KERN_INFO "BIOS-provided physical RAM map:\n"); 569 printk(KERN_INFO "BIOS-provided physical RAM map:\n");
596 e820_print_map(who); 570 e820_print_map("BIOS-e820");
597} 571}
598 572
599void __init parse_memopt(char *p, char **from) 573static int __init parse_memopt(char *p)
600{ 574{
601 end_user_pfn = memparse(p, from); 575 if (!p)
576 return -EINVAL;
577 end_user_pfn = memparse(p, &p);
602 end_user_pfn >>= PAGE_SHIFT; 578 end_user_pfn >>= PAGE_SHIFT;
579 return 0;
603} 580}
581early_param("mem", parse_memopt);
582
583static int userdef __initdata;
604 584
605void __init parse_memmapopt(char *p, char **from) 585static int __init parse_memmap_opt(char *p)
606{ 586{
587 char *oldp;
607 unsigned long long start_at, mem_size; 588 unsigned long long start_at, mem_size;
608 589
609 mem_size = memparse(p, from); 590 if (!strcmp(p, "exactmap")) {
610 p = *from; 591#ifdef CONFIG_CRASH_DUMP
592 /* If we are doing a crash dump, we
593 * still need to know the real mem
594 * size before original memory map is
595 * reset.
596 */
597 saved_max_pfn = e820_end_of_ram();
598#endif
599 end_pfn_map = 0;
600 e820.nr_map = 0;
601 userdef = 1;
602 return 0;
603 }
604
605 oldp = p;
606 mem_size = memparse(p, &p);
607 if (p == oldp)
608 return -EINVAL;
611 if (*p == '@') { 609 if (*p == '@') {
612 start_at = memparse(p+1, from); 610 start_at = memparse(p+1, &p);
613 add_memory_region(start_at, mem_size, E820_RAM); 611 add_memory_region(start_at, mem_size, E820_RAM);
614 } else if (*p == '#') { 612 } else if (*p == '#') {
615 start_at = memparse(p+1, from); 613 start_at = memparse(p+1, &p);
616 add_memory_region(start_at, mem_size, E820_ACPI); 614 add_memory_region(start_at, mem_size, E820_ACPI);
617 } else if (*p == '$') { 615 } else if (*p == '$') {
618 start_at = memparse(p+1, from); 616 start_at = memparse(p+1, &p);
619 add_memory_region(start_at, mem_size, E820_RESERVED); 617 add_memory_region(start_at, mem_size, E820_RESERVED);
620 } else { 618 } else {
621 end_user_pfn = (mem_size >> PAGE_SHIFT); 619 end_user_pfn = (mem_size >> PAGE_SHIFT);
622 } 620 }
623 p = *from; 621 return *p == '\0' ? 0 : -EINVAL;
622}
623early_param("memmap", parse_memmap_opt);
624
625void finish_e820_parsing(void)
626{
627 if (userdef) {
628 printk(KERN_INFO "user-defined physical RAM map:\n");
629 e820_print_map("user");
630 }
624} 631}
625 632
626unsigned long pci_mem_start = 0xaeedbabe; 633unsigned long pci_mem_start = 0xaeedbabe;
diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c
new file mode 100644
index 000000000000..208e38a372c1
--- /dev/null
+++ b/arch/x86_64/kernel/early-quirks.c
@@ -0,0 +1,122 @@
1/* Various workarounds for chipset bugs.
2 This code runs very early and can't use the regular PCI subsystem
3 The entries are keyed to PCI bridges which usually identify chipsets
4 uniquely.
5 This is only for whole classes of chipsets with specific problems which
6 need early invasive action (e.g. before the timers are initialized).
7 Most PCI device specific workarounds can be done later and should be
8 in standard PCI quirks
9 Mainboard specific bugs should be handled by DMI entries.
10 CPU specific bugs in setup.c */
11
12#include <linux/pci.h>
13#include <linux/acpi.h>
14#include <linux/pci_ids.h>
15#include <asm/pci-direct.h>
16#include <asm/proto.h>
17#include <asm/dma.h>
18
19static void via_bugs(void)
20{
21#ifdef CONFIG_IOMMU
22 if ((end_pfn > MAX_DMA32_PFN || force_iommu) &&
23 !iommu_aperture_allowed) {
24 printk(KERN_INFO
25 "Looks like a VIA chipset. Disabling IOMMU. Override with iommu=allowed\n");
26 iommu_aperture_disabled = 1;
27 }
28#endif
29}
30
31#ifdef CONFIG_ACPI
32
33static int nvidia_hpet_detected __initdata;
34
35static int __init nvidia_hpet_check(unsigned long phys, unsigned long size)
36{
37 nvidia_hpet_detected = 1;
38 return 0;
39}
40#endif
41
42static void nvidia_bugs(void)
43{
44#ifdef CONFIG_ACPI
45 /*
46 * All timer overrides on Nvidia are
47 * wrong unless HPET is enabled.
48 */
49 nvidia_hpet_detected = 0;
50 acpi_table_parse(ACPI_HPET, nvidia_hpet_check);
51 if (nvidia_hpet_detected == 0) {
52 acpi_skip_timer_override = 1;
53 printk(KERN_INFO "Nvidia board "
54 "detected. Ignoring ACPI "
55 "timer override.\n");
56 }
57#endif
58 /* RED-PEN skip them on mptables too? */
59
60}
61
62static void ati_bugs(void)
63{
64#if 1 /* for testing */
65 printk("ATI board detected\n");
66#endif
67 /* No bugs right now */
68}
69
70struct chipset {
71 u16 vendor;
72 void (*f)(void);
73};
74
75static struct chipset early_qrk[] = {
76 { PCI_VENDOR_ID_NVIDIA, nvidia_bugs },
77 { PCI_VENDOR_ID_VIA, via_bugs },
78 { PCI_VENDOR_ID_ATI, ati_bugs },
79 {}
80};
81
82void __init early_quirks(void)
83{
84 int num, slot, func;
85
86 if (!early_pci_allowed())
87 return;
88
89 /* Poor man's PCI discovery */
90 for (num = 0; num < 32; num++) {
91 for (slot = 0; slot < 32; slot++) {
92 for (func = 0; func < 8; func++) {
93 u32 class;
94 u32 vendor;
95 u8 type;
96 int i;
97 class = read_pci_config(num,slot,func,
98 PCI_CLASS_REVISION);
99 if (class == 0xffffffff)
100 break;
101
102 if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
103 continue;
104
105 vendor = read_pci_config(num, slot, func,
106 PCI_VENDOR_ID);
107 vendor &= 0xffff;
108
109 for (i = 0; early_qrk[i].f; i++)
110 if (early_qrk[i].vendor == vendor) {
111 early_qrk[i].f();
112 return;
113 }
114
115 type = read_pci_config_byte(num, slot, func,
116 PCI_HEADER_TYPE);
117 if (!(type & 0x80))
118 break;
119 }
120 }
121 }
122}
diff --git a/arch/x86_64/kernel/early_printk.c b/arch/x86_64/kernel/early_printk.c
index 140051e07fa6..e22ecd54870d 100644
--- a/arch/x86_64/kernel/early_printk.c
+++ b/arch/x86_64/kernel/early_printk.c
@@ -215,20 +215,16 @@ void early_printk(const char *fmt, ...)
215 215
216static int __initdata keep_early; 216static int __initdata keep_early;
217 217
218int __init setup_early_printk(char *opt) 218static int __init setup_early_printk(char *buf)
219{ 219{
220 char *space; 220 if (!buf)
221 char buf[256]; 221 return 0;
222 222
223 if (early_console_initialized) 223 if (early_console_initialized)
224 return 1; 224 return 0;
225 225 early_console_initialized = 1;
226 strlcpy(buf,opt,sizeof(buf));
227 space = strchr(buf, ' ');
228 if (space)
229 *space = 0;
230 226
231 if (strstr(buf,"keep")) 227 if (!strcmp(buf,"keep"))
232 keep_early = 1; 228 keep_early = 1;
233 229
234 if (!strncmp(buf, "serial", 6)) { 230 if (!strncmp(buf, "serial", 6)) {
@@ -248,11 +244,12 @@ int __init setup_early_printk(char *opt)
248 early_console = &simnow_console; 244 early_console = &simnow_console;
249 keep_early = 1; 245 keep_early = 1;
250 } 246 }
251 early_console_initialized = 1;
252 register_console(early_console); 247 register_console(early_console);
253 return 0; 248 return 0;
254} 249}
255 250
251early_param("earlyprintk", setup_early_printk);
252
256void __init disable_early_printk(void) 253void __init disable_early_printk(void)
257{ 254{
258 if (!early_console_initialized || !early_console) 255 if (!early_console_initialized || !early_console)
@@ -266,4 +263,3 @@ void __init disable_early_printk(void)
266 } 263 }
267} 264}
268 265
269__setup("earlyprintk=", setup_early_printk);
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
index aa8d8939abc1..2802524104f3 100644
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -4,8 +4,6 @@
4 * Copyright (C) 1991, 1992 Linus Torvalds 4 * Copyright (C) 1991, 1992 Linus Torvalds
5 * Copyright (C) 2000, 2001, 2002 Andi Kleen SuSE Labs 5 * Copyright (C) 2000, 2001, 2002 Andi Kleen SuSE Labs
6 * Copyright (C) 2000 Pavel Machek <pavel@suse.cz> 6 * Copyright (C) 2000 Pavel Machek <pavel@suse.cz>
7 *
8 * $Id$
9 */ 7 */
10 8
11/* 9/*
@@ -22,15 +20,25 @@
22 * at the top of the kernel process stack. 20 * at the top of the kernel process stack.
23 * - partial stack frame: partially saved registers upto R11. 21 * - partial stack frame: partially saved registers upto R11.
24 * - full stack frame: Like partial stack frame, but all register saved. 22 * - full stack frame: Like partial stack frame, but all register saved.
25 * 23 *
26 * TODO: 24 * Some macro usage:
27 * - schedule it carefully for the final hardware. 25 * - CFI macros are used to generate dwarf2 unwind information for better
26 * backtraces. They don't change any code.
27 * - SAVE_ALL/RESTORE_ALL - Save/restore all registers
28 * - SAVE_ARGS/RESTORE_ARGS - Save/restore registers that C functions modify.
29 * There are unfortunately lots of special cases where some registers
30 * not touched. The macro is a big mess that should be cleaned up.
31 * - SAVE_REST/RESTORE_REST - Handle the registers not saved by SAVE_ARGS.
32 * Gives a full stack frame.
33 * - ENTRY/END Define functions in the symbol table.
34 * - FIXUP_TOP_OF_STACK/RESTORE_TOP_OF_STACK - Fix up the hardware stack
35 * frame that is otherwise undefined after a SYSCALL
36 * - TRACE_IRQ_* - Trace hard interrupt state for lock debugging.
37 * - errorentry/paranoidentry/zeroentry - Define exception entry points.
28 */ 38 */
29 39
30#define ASSEMBLY 1
31#include <linux/linkage.h> 40#include <linux/linkage.h>
32#include <asm/segment.h> 41#include <asm/segment.h>
33#include <asm/smp.h>
34#include <asm/cache.h> 42#include <asm/cache.h>
35#include <asm/errno.h> 43#include <asm/errno.h>
36#include <asm/dwarf2.h> 44#include <asm/dwarf2.h>
@@ -115,6 +123,7 @@
115 .macro CFI_DEFAULT_STACK start=1 123 .macro CFI_DEFAULT_STACK start=1
116 .if \start 124 .if \start
117 CFI_STARTPROC simple 125 CFI_STARTPROC simple
126 CFI_SIGNAL_FRAME
118 CFI_DEF_CFA rsp,SS+8 127 CFI_DEF_CFA rsp,SS+8
119 .else 128 .else
120 CFI_DEF_CFA_OFFSET SS+8 129 CFI_DEF_CFA_OFFSET SS+8
@@ -146,6 +155,10 @@
146/* rdi: prev */ 155/* rdi: prev */
147ENTRY(ret_from_fork) 156ENTRY(ret_from_fork)
148 CFI_DEFAULT_STACK 157 CFI_DEFAULT_STACK
158 push kernel_eflags(%rip)
159 CFI_ADJUST_CFA_OFFSET 4
160 popf # reset kernel eflags
161 CFI_ADJUST_CFA_OFFSET -4
149 call schedule_tail 162 call schedule_tail
150 GET_THREAD_INFO(%rcx) 163 GET_THREAD_INFO(%rcx)
151 testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),threadinfo_flags(%rcx) 164 testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),threadinfo_flags(%rcx)
@@ -199,6 +212,7 @@ END(ret_from_fork)
199 212
200ENTRY(system_call) 213ENTRY(system_call)
201 CFI_STARTPROC simple 214 CFI_STARTPROC simple
215 CFI_SIGNAL_FRAME
202 CFI_DEF_CFA rsp,PDA_STACKOFFSET 216 CFI_DEF_CFA rsp,PDA_STACKOFFSET
203 CFI_REGISTER rip,rcx 217 CFI_REGISTER rip,rcx
204 /*CFI_REGISTER rflags,r11*/ 218 /*CFI_REGISTER rflags,r11*/
@@ -316,6 +330,7 @@ END(system_call)
316 */ 330 */
317ENTRY(int_ret_from_sys_call) 331ENTRY(int_ret_from_sys_call)
318 CFI_STARTPROC simple 332 CFI_STARTPROC simple
333 CFI_SIGNAL_FRAME
319 CFI_DEF_CFA rsp,SS+8-ARGOFFSET 334 CFI_DEF_CFA rsp,SS+8-ARGOFFSET
320 /*CFI_REL_OFFSET ss,SS-ARGOFFSET*/ 335 /*CFI_REL_OFFSET ss,SS-ARGOFFSET*/
321 CFI_REL_OFFSET rsp,RSP-ARGOFFSET 336 CFI_REL_OFFSET rsp,RSP-ARGOFFSET
@@ -476,6 +491,7 @@ END(stub_rt_sigreturn)
476 */ 491 */
477 .macro _frame ref 492 .macro _frame ref
478 CFI_STARTPROC simple 493 CFI_STARTPROC simple
494 CFI_SIGNAL_FRAME
479 CFI_DEF_CFA rsp,SS+8-\ref 495 CFI_DEF_CFA rsp,SS+8-\ref
480 /*CFI_REL_OFFSET ss,SS-\ref*/ 496 /*CFI_REL_OFFSET ss,SS-\ref*/
481 CFI_REL_OFFSET rsp,RSP-\ref 497 CFI_REL_OFFSET rsp,RSP-\ref
@@ -511,7 +527,12 @@ END(stub_rt_sigreturn)
511 testl $3,CS(%rdi) 527 testl $3,CS(%rdi)
512 je 1f 528 je 1f
513 swapgs 529 swapgs
5141: incl %gs:pda_irqcount # RED-PEN should check preempt count 530 /* irqcount is used to check if a CPU is already on an interrupt
531 stack or not. While this is essentially redundant with preempt_count
532 it is a little cheaper to use a separate counter in the PDA
533 (short of moving irq_enter into assembly, which would be too
534 much work) */
5351: incl %gs:pda_irqcount
515 cmoveq %gs:pda_irqstackptr,%rsp 536 cmoveq %gs:pda_irqstackptr,%rsp
516 push %rbp # backlink for old unwinder 537 push %rbp # backlink for old unwinder
517 /* 538 /*
@@ -619,8 +640,7 @@ retint_signal:
619#ifdef CONFIG_PREEMPT 640#ifdef CONFIG_PREEMPT
620 /* Returning to kernel space. Check if we need preemption */ 641 /* Returning to kernel space. Check if we need preemption */
621 /* rcx: threadinfo. interrupts off. */ 642 /* rcx: threadinfo. interrupts off. */
622 .p2align 643ENTRY(retint_kernel)
623retint_kernel:
624 cmpl $0,threadinfo_preempt_count(%rcx) 644 cmpl $0,threadinfo_preempt_count(%rcx)
625 jnz retint_restore_args 645 jnz retint_restore_args
626 bt $TIF_NEED_RESCHED,threadinfo_flags(%rcx) 646 bt $TIF_NEED_RESCHED,threadinfo_flags(%rcx)
@@ -679,7 +699,6 @@ ENTRY(call_function_interrupt)
679END(call_function_interrupt) 699END(call_function_interrupt)
680#endif 700#endif
681 701
682#ifdef CONFIG_X86_LOCAL_APIC
683ENTRY(apic_timer_interrupt) 702ENTRY(apic_timer_interrupt)
684 apicinterrupt LOCAL_TIMER_VECTOR,smp_apic_timer_interrupt 703 apicinterrupt LOCAL_TIMER_VECTOR,smp_apic_timer_interrupt
685END(apic_timer_interrupt) 704END(apic_timer_interrupt)
@@ -691,7 +710,6 @@ END(error_interrupt)
691ENTRY(spurious_interrupt) 710ENTRY(spurious_interrupt)
692 apicinterrupt SPURIOUS_APIC_VECTOR,smp_spurious_interrupt 711 apicinterrupt SPURIOUS_APIC_VECTOR,smp_spurious_interrupt
693END(spurious_interrupt) 712END(spurious_interrupt)
694#endif
695 713
696/* 714/*
697 * Exception entry points. 715 * Exception entry points.
@@ -768,7 +786,9 @@ paranoid_exit\trace:
768 testl $3,CS(%rsp) 786 testl $3,CS(%rsp)
769 jnz paranoid_userspace\trace 787 jnz paranoid_userspace\trace
770paranoid_swapgs\trace: 788paranoid_swapgs\trace:
789 .if \trace
771 TRACE_IRQS_IRETQ 0 790 TRACE_IRQS_IRETQ 0
791 .endif
772 swapgs 792 swapgs
773paranoid_restore\trace: 793paranoid_restore\trace:
774 RESTORE_ALL 8 794 RESTORE_ALL 8
@@ -814,7 +834,7 @@ paranoid_schedule\trace:
814 * Exception entry point. This expects an error code/orig_rax on the stack 834 * Exception entry point. This expects an error code/orig_rax on the stack
815 * and the exception handler in %rax. 835 * and the exception handler in %rax.
816 */ 836 */
817ENTRY(error_entry) 837KPROBE_ENTRY(error_entry)
818 _frame RDI 838 _frame RDI
819 /* rdi slot contains rax, oldrax contains error code */ 839 /* rdi slot contains rax, oldrax contains error code */
820 cld 840 cld
@@ -898,7 +918,7 @@ error_kernelspace:
898 cmpq $gs_change,RIP(%rsp) 918 cmpq $gs_change,RIP(%rsp)
899 je error_swapgs 919 je error_swapgs
900 jmp error_sti 920 jmp error_sti
901END(error_entry) 921KPROBE_END(error_entry)
902 922
903 /* Reload gs selector with exception handling */ 923 /* Reload gs selector with exception handling */
904 /* edi: new selector */ 924 /* edi: new selector */
@@ -1020,8 +1040,7 @@ ENDPROC(execve)
1020 1040
1021KPROBE_ENTRY(page_fault) 1041KPROBE_ENTRY(page_fault)
1022 errorentry do_page_fault 1042 errorentry do_page_fault
1023END(page_fault) 1043KPROBE_END(page_fault)
1024 .previous .text
1025 1044
1026ENTRY(coprocessor_error) 1045ENTRY(coprocessor_error)
1027 zeroentry do_coprocessor_error 1046 zeroentry do_coprocessor_error
@@ -1042,8 +1061,7 @@ KPROBE_ENTRY(debug)
1042 CFI_ADJUST_CFA_OFFSET 8 1061 CFI_ADJUST_CFA_OFFSET 8
1043 paranoidentry do_debug, DEBUG_STACK 1062 paranoidentry do_debug, DEBUG_STACK
1044 paranoidexit 1063 paranoidexit
1045END(debug) 1064KPROBE_END(debug)
1046 .previous .text
1047 1065
1048 /* runs on exception stack */ 1066 /* runs on exception stack */
1049KPROBE_ENTRY(nmi) 1067KPROBE_ENTRY(nmi)
@@ -1057,8 +1075,7 @@ KPROBE_ENTRY(nmi)
1057 jmp paranoid_exit1 1075 jmp paranoid_exit1
1058 CFI_ENDPROC 1076 CFI_ENDPROC
1059#endif 1077#endif
1060END(nmi) 1078KPROBE_END(nmi)
1061 .previous .text
1062 1079
1063KPROBE_ENTRY(int3) 1080KPROBE_ENTRY(int3)
1064 INTR_FRAME 1081 INTR_FRAME
@@ -1067,8 +1084,7 @@ KPROBE_ENTRY(int3)
1067 paranoidentry do_int3, DEBUG_STACK 1084 paranoidentry do_int3, DEBUG_STACK
1068 jmp paranoid_exit1 1085 jmp paranoid_exit1
1069 CFI_ENDPROC 1086 CFI_ENDPROC
1070END(int3) 1087KPROBE_END(int3)
1071 .previous .text
1072 1088
1073ENTRY(overflow) 1089ENTRY(overflow)
1074 zeroentry do_overflow 1090 zeroentry do_overflow
@@ -1116,8 +1132,7 @@ END(stack_segment)
1116 1132
1117KPROBE_ENTRY(general_protection) 1133KPROBE_ENTRY(general_protection)
1118 errorentry do_general_protection 1134 errorentry do_general_protection
1119END(general_protection) 1135KPROBE_END(general_protection)
1120 .previous .text
1121 1136
1122ENTRY(alignment_check) 1137ENTRY(alignment_check)
1123 errorentry do_alignment_check 1138 errorentry do_alignment_check
diff --git a/arch/x86_64/kernel/genapic_cluster.c b/arch/x86_64/kernel/genapic_cluster.c
index 3020917546de..cdb90e671b88 100644
--- a/arch/x86_64/kernel/genapic_cluster.c
+++ b/arch/x86_64/kernel/genapic_cluster.c
@@ -118,7 +118,6 @@ struct genapic apic_cluster = {
118 .name = "clustered", 118 .name = "clustered",
119 .int_delivery_mode = dest_Fixed, 119 .int_delivery_mode = dest_Fixed,
120 .int_dest_mode = (APIC_DEST_PHYSICAL != 0), 120 .int_dest_mode = (APIC_DEST_PHYSICAL != 0),
121 .int_delivery_dest = APIC_DEST_PHYSICAL | APIC_DM_FIXED,
122 .target_cpus = cluster_target_cpus, 121 .target_cpus = cluster_target_cpus,
123 .apic_id_registered = cluster_apic_id_registered, 122 .apic_id_registered = cluster_apic_id_registered,
124 .init_apic_ldr = cluster_init_apic_ldr, 123 .init_apic_ldr = cluster_init_apic_ldr,
diff --git a/arch/x86_64/kernel/genapic_flat.c b/arch/x86_64/kernel/genapic_flat.c
index eb86d374813a..50ad153eaac4 100644
--- a/arch/x86_64/kernel/genapic_flat.c
+++ b/arch/x86_64/kernel/genapic_flat.c
@@ -49,8 +49,7 @@ static void flat_send_IPI_mask(cpumask_t cpumask, int vector)
49 unsigned long cfg; 49 unsigned long cfg;
50 unsigned long flags; 50 unsigned long flags;
51 51
52 local_save_flags(flags); 52 local_irq_save(flags);
53 local_irq_disable();
54 53
55 /* 54 /*
56 * Wait for idle. 55 * Wait for idle.
@@ -121,7 +120,6 @@ struct genapic apic_flat = {
121 .name = "flat", 120 .name = "flat",
122 .int_delivery_mode = dest_LowestPrio, 121 .int_delivery_mode = dest_LowestPrio,
123 .int_dest_mode = (APIC_DEST_LOGICAL != 0), 122 .int_dest_mode = (APIC_DEST_LOGICAL != 0),
124 .int_delivery_dest = APIC_DEST_LOGICAL | APIC_DM_LOWEST,
125 .target_cpus = flat_target_cpus, 123 .target_cpus = flat_target_cpus,
126 .apic_id_registered = flat_apic_id_registered, 124 .apic_id_registered = flat_apic_id_registered,
127 .init_apic_ldr = flat_init_apic_ldr, 125 .init_apic_ldr = flat_init_apic_ldr,
@@ -180,7 +178,6 @@ struct genapic apic_physflat = {
180 .name = "physical flat", 178 .name = "physical flat",
181 .int_delivery_mode = dest_Fixed, 179 .int_delivery_mode = dest_Fixed,
182 .int_dest_mode = (APIC_DEST_PHYSICAL != 0), 180 .int_dest_mode = (APIC_DEST_PHYSICAL != 0),
183 .int_delivery_dest = APIC_DEST_PHYSICAL | APIC_DM_FIXED,
184 .target_cpus = physflat_target_cpus, 181 .target_cpus = physflat_target_cpus,
185 .apic_id_registered = flat_apic_id_registered, 182 .apic_id_registered = flat_apic_id_registered,
186 .init_apic_ldr = flat_init_apic_ldr,/*not needed, but shouldn't hurt*/ 183 .init_apic_ldr = flat_init_apic_ldr,/*not needed, but shouldn't hurt*/
diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S
index c9739ca81d06..1e6f80870679 100644
--- a/arch/x86_64/kernel/head.S
+++ b/arch/x86_64/kernel/head.S
@@ -5,8 +5,6 @@
5 * Copyright (C) 2000 Pavel Machek <pavel@suse.cz> 5 * Copyright (C) 2000 Pavel Machek <pavel@suse.cz>
6 * Copyright (C) 2000 Karsten Keil <kkeil@suse.de> 6 * Copyright (C) 2000 Karsten Keil <kkeil@suse.de>
7 * Copyright (C) 2001,2002 Andi Kleen <ak@suse.de> 7 * Copyright (C) 2001,2002 Andi Kleen <ak@suse.de>
8 *
9 * $Id: head.S,v 1.49 2002/03/19 17:39:25 ak Exp $
10 */ 8 */
11 9
12 10
@@ -187,12 +185,15 @@ startup_64:
187 185
188 /* Finally jump to run C code and to be on real kernel address 186 /* Finally jump to run C code and to be on real kernel address
189 * Since we are running on identity-mapped space we have to jump 187 * Since we are running on identity-mapped space we have to jump
190 * to the full 64bit address , this is only possible as indirect 188 * to the full 64bit address, this is only possible as indirect
191 * jump 189 * jump. In addition we need to ensure %cs is set so we make this
190 * a far return.
192 */ 191 */
193 movq initial_code(%rip),%rax 192 movq initial_code(%rip),%rax
194 pushq $0 # fake return address 193 pushq $0 # fake return address to stop unwinder
195 jmp *%rax 194 pushq $__KERNEL_CS # set correct cs
195 pushq %rax # target address in negative space
196 lretq
196 197
197 /* SMP bootup changes these two */ 198 /* SMP bootup changes these two */
198 .align 8 199 .align 8
@@ -371,7 +372,7 @@ ENTRY(cpu_gdt_table)
371 .quad 0,0 /* TSS */ 372 .quad 0,0 /* TSS */
372 .quad 0,0 /* LDT */ 373 .quad 0,0 /* LDT */
373 .quad 0,0,0 /* three TLS descriptors */ 374 .quad 0,0,0 /* three TLS descriptors */
374 .quad 0 /* unused */ 375 .quad 0x0000f40000000000 /* node/CPU stored in limit */
375gdt_end: 376gdt_end:
376 /* asm/segment.h:GDT_ENTRIES must match this */ 377 /* asm/segment.h:GDT_ENTRIES must match this */
377 /* This should be a multiple of the cache line size */ 378 /* This should be a multiple of the cache line size */
diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c
index 36647ce6aecb..9561eb3c5b5c 100644
--- a/arch/x86_64/kernel/head64.c
+++ b/arch/x86_64/kernel/head64.c
@@ -45,38 +45,16 @@ static void __init copy_bootdata(char *real_mode_data)
45 new_data = *(int *) (x86_boot_params + NEW_CL_POINTER); 45 new_data = *(int *) (x86_boot_params + NEW_CL_POINTER);
46 if (!new_data) { 46 if (!new_data) {
47 if (OLD_CL_MAGIC != * (u16 *) OLD_CL_MAGIC_ADDR) { 47 if (OLD_CL_MAGIC != * (u16 *) OLD_CL_MAGIC_ADDR) {
48 printk("so old bootloader that it does not support commandline?!\n");
49 return; 48 return;
50 } 49 }
51 new_data = OLD_CL_BASE_ADDR + * (u16 *) OLD_CL_OFFSET; 50 new_data = OLD_CL_BASE_ADDR + * (u16 *) OLD_CL_OFFSET;
52 printk("old bootloader convention, maybe loadlin?\n");
53 } 51 }
54 command_line = (char *) ((u64)(new_data)); 52 command_line = (char *) ((u64)(new_data));
55 memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); 53 memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
56 printk("Bootdata ok (command line is %s)\n", saved_command_line);
57}
58
59static void __init setup_boot_cpu_data(void)
60{
61 unsigned int dummy, eax;
62
63 /* get vendor info */
64 cpuid(0, (unsigned int *)&boot_cpu_data.cpuid_level,
65 (unsigned int *)&boot_cpu_data.x86_vendor_id[0],
66 (unsigned int *)&boot_cpu_data.x86_vendor_id[8],
67 (unsigned int *)&boot_cpu_data.x86_vendor_id[4]);
68
69 /* get cpu type */
70 cpuid(1, &eax, &dummy, &dummy,
71 (unsigned int *) &boot_cpu_data.x86_capability);
72 boot_cpu_data.x86 = (eax >> 8) & 0xf;
73 boot_cpu_data.x86_model = (eax >> 4) & 0xf;
74 boot_cpu_data.x86_mask = eax & 0xf;
75} 54}
76 55
77void __init x86_64_start_kernel(char * real_mode_data) 56void __init x86_64_start_kernel(char * real_mode_data)
78{ 57{
79 char *s;
80 int i; 58 int i;
81 59
82 for (i = 0; i < 256; i++) 60 for (i = 0; i < 256; i++)
@@ -84,10 +62,7 @@ void __init x86_64_start_kernel(char * real_mode_data)
84 asm volatile("lidt %0" :: "m" (idt_descr)); 62 asm volatile("lidt %0" :: "m" (idt_descr));
85 clear_bss(); 63 clear_bss();
86 64
87 /* 65 early_printk("Kernel alive\n");
88 * This must be called really, really early:
89 */
90 lockdep_init();
91 66
92 /* 67 /*
93 * switch to init_level4_pgt from boot_level4_pgt 68 * switch to init_level4_pgt from boot_level4_pgt
@@ -103,22 +78,5 @@ void __init x86_64_start_kernel(char * real_mode_data)
103#ifdef CONFIG_SMP 78#ifdef CONFIG_SMP
104 cpu_set(0, cpu_online_map); 79 cpu_set(0, cpu_online_map);
105#endif 80#endif
106 s = strstr(saved_command_line, "earlyprintk=");
107 if (s != NULL)
108 setup_early_printk(strchr(s, '=') + 1);
109#ifdef CONFIG_NUMA
110 s = strstr(saved_command_line, "numa=");
111 if (s != NULL)
112 numa_setup(s+5);
113#endif
114#ifdef CONFIG_X86_IO_APIC
115 if (strstr(saved_command_line, "disableapic"))
116 disable_apic = 1;
117#endif
118 /* You need early console to see that */
119 if (__pa_symbol(&_end) >= KERNEL_TEXT_SIZE)
120 panic("Kernel too big for kernel mapping\n");
121
122 setup_boot_cpu_data();
123 start_kernel(); 81 start_kernel();
124} 82}
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c
index 0434b1f8e3dd..2dd51f364ea2 100644
--- a/arch/x86_64/kernel/i8259.c
+++ b/arch/x86_64/kernel/i8259.c
@@ -55,7 +55,6 @@
55 */ 55 */
56BUILD_16_IRQS(0x0) 56BUILD_16_IRQS(0x0)
57 57
58#ifdef CONFIG_X86_LOCAL_APIC
59/* 58/*
60 * The IO-APIC gives us many more interrupt sources. Most of these 59 * The IO-APIC gives us many more interrupt sources. Most of these
61 * are unused but an SMP system is supposed to have enough memory ... 60 * are unused but an SMP system is supposed to have enough memory ...
@@ -75,8 +74,6 @@ BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd)
75 BUILD_15_IRQS(0xe) 74 BUILD_15_IRQS(0xe)
76#endif 75#endif
77 76
78#endif
79
80#undef BUILD_16_IRQS 77#undef BUILD_16_IRQS
81#undef BUILD_15_IRQS 78#undef BUILD_15_IRQS
82#undef BI 79#undef BI
@@ -100,7 +97,6 @@ BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd)
100void (*interrupt[NR_IRQS])(void) = { 97void (*interrupt[NR_IRQS])(void) = {
101 IRQLIST_16(0x0), 98 IRQLIST_16(0x0),
102 99
103#ifdef CONFIG_X86_IO_APIC
104 IRQLIST_16(0x1), IRQLIST_16(0x2), IRQLIST_16(0x3), 100 IRQLIST_16(0x1), IRQLIST_16(0x2), IRQLIST_16(0x3),
105 IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7), 101 IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7),
106 IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb), 102 IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb),
@@ -110,7 +106,6 @@ void (*interrupt[NR_IRQS])(void) = {
110 , IRQLIST_15(0xe) 106 , IRQLIST_15(0xe)
111#endif 107#endif
112 108
113#endif
114}; 109};
115 110
116#undef IRQ 111#undef IRQ
@@ -128,6 +123,8 @@ void (*interrupt[NR_IRQS])(void) = {
128 123
129DEFINE_SPINLOCK(i8259A_lock); 124DEFINE_SPINLOCK(i8259A_lock);
130 125
126static int i8259A_auto_eoi;
127
131static void end_8259A_irq (unsigned int irq) 128static void end_8259A_irq (unsigned int irq)
132{ 129{
133 if (irq > 256) { 130 if (irq > 256) {
@@ -341,6 +338,8 @@ void init_8259A(int auto_eoi)
341{ 338{
342 unsigned long flags; 339 unsigned long flags;
343 340
341 i8259A_auto_eoi = auto_eoi;
342
344 spin_lock_irqsave(&i8259A_lock, flags); 343 spin_lock_irqsave(&i8259A_lock, flags);
345 344
346 outb(0xff, 0x21); /* mask all of 8259A-1 */ 345 outb(0xff, 0x21); /* mask all of 8259A-1 */
@@ -399,7 +398,7 @@ static void save_ELCR(char *trigger)
399 398
400static int i8259A_resume(struct sys_device *dev) 399static int i8259A_resume(struct sys_device *dev)
401{ 400{
402 init_8259A(0); 401 init_8259A(i8259A_auto_eoi);
403 restore_ELCR(irq_trigger); 402 restore_ELCR(irq_trigger);
404 return 0; 403 return 0;
405} 404}
@@ -453,9 +452,7 @@ void __init init_ISA_irqs (void)
453{ 452{
454 int i; 453 int i;
455 454
456#ifdef CONFIG_X86_LOCAL_APIC
457 init_bsp_APIC(); 455 init_bsp_APIC();
458#endif
459 init_8259A(0); 456 init_8259A(0);
460 457
461 for (i = 0; i < NR_IRQS; i++) { 458 for (i = 0; i < NR_IRQS; i++) {
@@ -581,14 +578,12 @@ void __init init_IRQ(void)
581 set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); 578 set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt);
582 set_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt); 579 set_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);
583 580
584#ifdef CONFIG_X86_LOCAL_APIC
585 /* self generated IPI for local APIC timer */ 581 /* self generated IPI for local APIC timer */
586 set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); 582 set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
587 583
588 /* IPI vectors for APIC spurious and error interrupts */ 584 /* IPI vectors for APIC spurious and error interrupts */
589 set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); 585 set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
590 set_intr_gate(ERROR_APIC_VECTOR, error_interrupt); 586 set_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
591#endif
592 587
593 /* 588 /*
594 * Set the clock to HZ Hz, we already have a valid 589 * Set the clock to HZ Hz, we already have a valid
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index 924a4a332954..0491019d4c8d 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -48,7 +48,7 @@ int sis_apic_bug; /* not actually supported, dummy for compile */
48 48
49static int no_timer_check; 49static int no_timer_check;
50 50
51int disable_timer_pin_1 __initdata; 51static int disable_timer_pin_1 __initdata;
52 52
53int timer_over_8254 __initdata = 0; 53int timer_over_8254 __initdata = 0;
54 54
@@ -111,6 +111,33 @@ int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1};
111 FINAL; \ 111 FINAL; \
112} 112}
113 113
114union entry_union {
115 struct { u32 w1, w2; };
116 struct IO_APIC_route_entry entry;
117};
118
119static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin)
120{
121 union entry_union eu;
122 unsigned long flags;
123 spin_lock_irqsave(&ioapic_lock, flags);
124 eu.w1 = io_apic_read(apic, 0x10 + 2 * pin);
125 eu.w2 = io_apic_read(apic, 0x11 + 2 * pin);
126 spin_unlock_irqrestore(&ioapic_lock, flags);
127 return eu.entry;
128}
129
130static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
131{
132 unsigned long flags;
133 union entry_union eu;
134 eu.entry = e;
135 spin_lock_irqsave(&ioapic_lock, flags);
136 io_apic_write(apic, 0x10 + 2*pin, eu.w1);
137 io_apic_write(apic, 0x11 + 2*pin, eu.w2);
138 spin_unlock_irqrestore(&ioapic_lock, flags);
139}
140
114#ifdef CONFIG_SMP 141#ifdef CONFIG_SMP
115static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) 142static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
116{ 143{
@@ -196,13 +223,9 @@ static void unmask_IO_APIC_irq (unsigned int irq)
196static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) 223static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
197{ 224{
198 struct IO_APIC_route_entry entry; 225 struct IO_APIC_route_entry entry;
199 unsigned long flags;
200 226
201 /* Check delivery_mode to be sure we're not clearing an SMI pin */ 227 /* Check delivery_mode to be sure we're not clearing an SMI pin */
202 spin_lock_irqsave(&ioapic_lock, flags); 228 entry = ioapic_read_entry(apic, pin);
203 *(((int*)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
204 *(((int*)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
205 spin_unlock_irqrestore(&ioapic_lock, flags);
206 if (entry.delivery_mode == dest_SMI) 229 if (entry.delivery_mode == dest_SMI)
207 return; 230 return;
208 /* 231 /*
@@ -210,10 +233,7 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
210 */ 233 */
211 memset(&entry, 0, sizeof(entry)); 234 memset(&entry, 0, sizeof(entry));
212 entry.mask = 1; 235 entry.mask = 1;
213 spin_lock_irqsave(&ioapic_lock, flags); 236 ioapic_write_entry(apic, pin, entry);
214 io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry) + 0));
215 io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry) + 1));
216 spin_unlock_irqrestore(&ioapic_lock, flags);
217} 237}
218 238
219static void clear_IO_APIC (void) 239static void clear_IO_APIC (void)
@@ -225,14 +245,6 @@ static void clear_IO_APIC (void)
225 clear_IO_APIC_pin(apic, pin); 245 clear_IO_APIC_pin(apic, pin);
226} 246}
227 247
228/*
229 * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to
230 * specific CPU-side IRQs.
231 */
232
233#define MAX_PIRQS 8
234static int pirq_entries [MAX_PIRQS];
235static int pirqs_enabled;
236int skip_ioapic_setup; 248int skip_ioapic_setup;
237int ioapic_force; 249int ioapic_force;
238 250
@@ -241,18 +253,17 @@ int ioapic_force;
241static int __init disable_ioapic_setup(char *str) 253static int __init disable_ioapic_setup(char *str)
242{ 254{
243 skip_ioapic_setup = 1; 255 skip_ioapic_setup = 1;
244 return 1; 256 return 0;
245} 257}
258early_param("noapic", disable_ioapic_setup);
246 259
247static int __init enable_ioapic_setup(char *str) 260/* Actually the next is obsolete, but keep it for paranoid reasons -AK */
261static int __init disable_timer_pin_setup(char *arg)
248{ 262{
249 ioapic_force = 1; 263 disable_timer_pin_1 = 1;
250 skip_ioapic_setup = 0;
251 return 1; 264 return 1;
252} 265}
253 266__setup("disable_timer_pin_1", disable_timer_pin_setup);
254__setup("noapic", disable_ioapic_setup);
255__setup("apic", enable_ioapic_setup);
256 267
257static int __init setup_disable_8254_timer(char *s) 268static int __init setup_disable_8254_timer(char *s)
258{ 269{
@@ -268,135 +279,6 @@ static int __init setup_enable_8254_timer(char *s)
268__setup("disable_8254_timer", setup_disable_8254_timer); 279__setup("disable_8254_timer", setup_disable_8254_timer);
269__setup("enable_8254_timer", setup_enable_8254_timer); 280__setup("enable_8254_timer", setup_enable_8254_timer);
270 281
271#include <asm/pci-direct.h>
272#include <linux/pci_ids.h>
273#include <linux/pci.h>
274
275
276#ifdef CONFIG_ACPI
277
278static int nvidia_hpet_detected __initdata;
279
280static int __init nvidia_hpet_check(unsigned long phys, unsigned long size)
281{
282 nvidia_hpet_detected = 1;
283 return 0;
284}
285#endif
286
287/* Temporary Hack. Nvidia and VIA boards currently only work with IO-APIC
288 off. Check for an Nvidia or VIA PCI bridge and turn it off.
289 Use pci direct infrastructure because this runs before the PCI subsystem.
290
291 Can be overwritten with "apic"
292
293 And another hack to disable the IOMMU on VIA chipsets.
294
295 ... and others. Really should move this somewhere else.
296
297 Kludge-O-Rama. */
298void __init check_ioapic(void)
299{
300 int num,slot,func;
301 /* Poor man's PCI discovery */
302 for (num = 0; num < 32; num++) {
303 for (slot = 0; slot < 32; slot++) {
304 for (func = 0; func < 8; func++) {
305 u32 class;
306 u32 vendor;
307 u8 type;
308 class = read_pci_config(num,slot,func,
309 PCI_CLASS_REVISION);
310 if (class == 0xffffffff)
311 break;
312
313 if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
314 continue;
315
316 vendor = read_pci_config(num, slot, func,
317 PCI_VENDOR_ID);
318 vendor &= 0xffff;
319 switch (vendor) {
320 case PCI_VENDOR_ID_VIA:
321#ifdef CONFIG_IOMMU
322 if ((end_pfn > MAX_DMA32_PFN ||
323 force_iommu) &&
324 !iommu_aperture_allowed) {
325 printk(KERN_INFO
326 "Looks like a VIA chipset. Disabling IOMMU. Override with \"iommu=allowed\"\n");
327 iommu_aperture_disabled = 1;
328 }
329#endif
330 return;
331 case PCI_VENDOR_ID_NVIDIA:
332#ifdef CONFIG_ACPI
333 /*
334 * All timer overrides on Nvidia are
335 * wrong unless HPET is enabled.
336 */
337 nvidia_hpet_detected = 0;
338 acpi_table_parse(ACPI_HPET,
339 nvidia_hpet_check);
340 if (nvidia_hpet_detected == 0) {
341 acpi_skip_timer_override = 1;
342 printk(KERN_INFO "Nvidia board "
343 "detected. Ignoring ACPI "
344 "timer override.\n");
345 }
346#endif
347 /* RED-PEN skip them on mptables too? */
348 return;
349
350 /* This should be actually default, but
351 for 2.6.16 let's do it for ATI only where
352 it's really needed. */
353 case PCI_VENDOR_ID_ATI:
354 if (timer_over_8254 == 1) {
355 timer_over_8254 = 0;
356 printk(KERN_INFO
357 "ATI board detected. Disabling timer routing over 8254.\n");
358 }
359 return;
360 }
361
362
363 /* No multi-function device? */
364 type = read_pci_config_byte(num,slot,func,
365 PCI_HEADER_TYPE);
366 if (!(type & 0x80))
367 break;
368 }
369 }
370 }
371}
372
373static int __init ioapic_pirq_setup(char *str)
374{
375 int i, max;
376 int ints[MAX_PIRQS+1];
377
378 get_options(str, ARRAY_SIZE(ints), ints);
379
380 for (i = 0; i < MAX_PIRQS; i++)
381 pirq_entries[i] = -1;
382
383 pirqs_enabled = 1;
384 apic_printk(APIC_VERBOSE, "PIRQ redirection, working around broken MP-BIOS.\n");
385 max = MAX_PIRQS;
386 if (ints[0] < MAX_PIRQS)
387 max = ints[0];
388
389 for (i = 0; i < max; i++) {
390 apic_printk(APIC_VERBOSE, "... PIRQ%d -> IRQ %d\n", i, ints[i+1]);
391 /*
392 * PIRQs are mapped upside down, usually.
393 */
394 pirq_entries[MAX_PIRQS-i-1] = ints[i+1];
395 }
396 return 1;
397}
398
399__setup("pirq=", ioapic_pirq_setup);
400 282
401/* 283/*
402 * Find the IRQ entry number of a certain pin. 284 * Find the IRQ entry number of a certain pin.
@@ -425,9 +307,7 @@ static int __init find_isa_irq_pin(int irq, int type)
425 for (i = 0; i < mp_irq_entries; i++) { 307 for (i = 0; i < mp_irq_entries; i++) {
426 int lbus = mp_irqs[i].mpc_srcbus; 308 int lbus = mp_irqs[i].mpc_srcbus;
427 309
428 if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || 310 if (test_bit(lbus, mp_bus_not_pci) &&
429 mp_bus_id_to_type[lbus] == MP_BUS_EISA ||
430 mp_bus_id_to_type[lbus] == MP_BUS_MCA) &&
431 (mp_irqs[i].mpc_irqtype == type) && 311 (mp_irqs[i].mpc_irqtype == type) &&
432 (mp_irqs[i].mpc_srcbusirq == irq)) 312 (mp_irqs[i].mpc_srcbusirq == irq))
433 313
@@ -443,9 +323,7 @@ static int __init find_isa_irq_apic(int irq, int type)
443 for (i = 0; i < mp_irq_entries; i++) { 323 for (i = 0; i < mp_irq_entries; i++) {
444 int lbus = mp_irqs[i].mpc_srcbus; 324 int lbus = mp_irqs[i].mpc_srcbus;
445 325
446 if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || 326 if (test_bit(lbus, mp_bus_not_pci) &&
447 mp_bus_id_to_type[lbus] == MP_BUS_EISA ||
448 mp_bus_id_to_type[lbus] == MP_BUS_MCA) &&
449 (mp_irqs[i].mpc_irqtype == type) && 327 (mp_irqs[i].mpc_irqtype == type) &&
450 (mp_irqs[i].mpc_srcbusirq == irq)) 328 (mp_irqs[i].mpc_srcbusirq == irq))
451 break; 329 break;
@@ -485,7 +363,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
485 mp_irqs[i].mpc_dstapic == MP_APIC_ALL) 363 mp_irqs[i].mpc_dstapic == MP_APIC_ALL)
486 break; 364 break;
487 365
488 if ((mp_bus_id_to_type[lbus] == MP_BUS_PCI) && 366 if (!test_bit(lbus, mp_bus_not_pci) &&
489 !mp_irqs[i].mpc_irqtype && 367 !mp_irqs[i].mpc_irqtype &&
490 (bus == lbus) && 368 (bus == lbus) &&
491 (slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f))) { 369 (slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f))) {
@@ -508,27 +386,6 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
508 return best_guess; 386 return best_guess;
509} 387}
510 388
511/*
512 * EISA Edge/Level control register, ELCR
513 */
514static int EISA_ELCR(unsigned int irq)
515{
516 if (irq < 16) {
517 unsigned int port = 0x4d0 + (irq >> 3);
518 return (inb(port) >> (irq & 7)) & 1;
519 }
520 apic_printk(APIC_VERBOSE, "Broken MPtable reports ISA irq %d\n", irq);
521 return 0;
522}
523
524/* EISA interrupts are always polarity zero and can be edge or level
525 * trigger depending on the ELCR value. If an interrupt is listed as
526 * EISA conforming in the MP table, that means its trigger type must
527 * be read in from the ELCR */
528
529#define default_EISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].mpc_srcbusirq))
530#define default_EISA_polarity(idx) (0)
531
532/* ISA interrupts are always polarity zero edge triggered, 389/* ISA interrupts are always polarity zero edge triggered,
533 * when listed as conforming in the MP table. */ 390 * when listed as conforming in the MP table. */
534 391
@@ -541,12 +398,6 @@ static int EISA_ELCR(unsigned int irq)
541#define default_PCI_trigger(idx) (1) 398#define default_PCI_trigger(idx) (1)
542#define default_PCI_polarity(idx) (1) 399#define default_PCI_polarity(idx) (1)
543 400
544/* MCA interrupts are always polarity zero level triggered,
545 * when listed as conforming in the MP table. */
546
547#define default_MCA_trigger(idx) (1)
548#define default_MCA_polarity(idx) (0)
549
550static int __init MPBIOS_polarity(int idx) 401static int __init MPBIOS_polarity(int idx)
551{ 402{
552 int bus = mp_irqs[idx].mpc_srcbus; 403 int bus = mp_irqs[idx].mpc_srcbus;
@@ -558,38 +409,11 @@ static int __init MPBIOS_polarity(int idx)
558 switch (mp_irqs[idx].mpc_irqflag & 3) 409 switch (mp_irqs[idx].mpc_irqflag & 3)
559 { 410 {
560 case 0: /* conforms, ie. bus-type dependent polarity */ 411 case 0: /* conforms, ie. bus-type dependent polarity */
561 { 412 if (test_bit(bus, mp_bus_not_pci))
562 switch (mp_bus_id_to_type[bus]) 413 polarity = default_ISA_polarity(idx);
563 { 414 else
564 case MP_BUS_ISA: /* ISA pin */ 415 polarity = default_PCI_polarity(idx);
565 {
566 polarity = default_ISA_polarity(idx);
567 break;
568 }
569 case MP_BUS_EISA: /* EISA pin */
570 {
571 polarity = default_EISA_polarity(idx);
572 break;
573 }
574 case MP_BUS_PCI: /* PCI pin */
575 {
576 polarity = default_PCI_polarity(idx);
577 break;
578 }
579 case MP_BUS_MCA: /* MCA pin */
580 {
581 polarity = default_MCA_polarity(idx);
582 break;
583 }
584 default:
585 {
586 printk(KERN_WARNING "broken BIOS!!\n");
587 polarity = 1;
588 break;
589 }
590 }
591 break; 416 break;
592 }
593 case 1: /* high active */ 417 case 1: /* high active */
594 { 418 {
595 polarity = 0; 419 polarity = 0;
@@ -627,38 +451,11 @@ static int MPBIOS_trigger(int idx)
627 switch ((mp_irqs[idx].mpc_irqflag>>2) & 3) 451 switch ((mp_irqs[idx].mpc_irqflag>>2) & 3)
628 { 452 {
629 case 0: /* conforms, ie. bus-type dependent */ 453 case 0: /* conforms, ie. bus-type dependent */
630 { 454 if (test_bit(bus, mp_bus_not_pci))
631 switch (mp_bus_id_to_type[bus]) 455 trigger = default_ISA_trigger(idx);
632 { 456 else
633 case MP_BUS_ISA: /* ISA pin */ 457 trigger = default_PCI_trigger(idx);
634 {
635 trigger = default_ISA_trigger(idx);
636 break;
637 }
638 case MP_BUS_EISA: /* EISA pin */
639 {
640 trigger = default_EISA_trigger(idx);
641 break;
642 }
643 case MP_BUS_PCI: /* PCI pin */
644 {
645 trigger = default_PCI_trigger(idx);
646 break;
647 }
648 case MP_BUS_MCA: /* MCA pin */
649 {
650 trigger = default_MCA_trigger(idx);
651 break;
652 }
653 default:
654 {
655 printk(KERN_WARNING "broken BIOS!!\n");
656 trigger = 1;
657 break;
658 }
659 }
660 break; 458 break;
661 }
662 case 1: /* edge */ 459 case 1: /* edge */
663 { 460 {
664 trigger = 0; 461 trigger = 0;
@@ -764,49 +561,17 @@ static int pin_2_irq(int idx, int apic, int pin)
764 if (mp_irqs[idx].mpc_dstirq != pin) 561 if (mp_irqs[idx].mpc_dstirq != pin)
765 printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n"); 562 printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n");
766 563
767 switch (mp_bus_id_to_type[bus]) 564 if (test_bit(bus, mp_bus_not_pci)) {
768 { 565 irq = mp_irqs[idx].mpc_srcbusirq;
769 case MP_BUS_ISA: /* ISA pin */ 566 } else {
770 case MP_BUS_EISA: 567 /*
771 case MP_BUS_MCA: 568 * PCI IRQs are mapped in order
772 { 569 */
773 irq = mp_irqs[idx].mpc_srcbusirq; 570 i = irq = 0;
774 break; 571 while (i < apic)
775 } 572 irq += nr_ioapic_registers[i++];
776 case MP_BUS_PCI: /* PCI pin */ 573 irq += pin;
777 { 574 irq = gsi_irq_sharing(irq);
778 /*
779 * PCI IRQs are mapped in order
780 */
781 i = irq = 0;
782 while (i < apic)
783 irq += nr_ioapic_registers[i++];
784 irq += pin;
785 irq = gsi_irq_sharing(irq);
786 break;
787 }
788 default:
789 {
790 printk(KERN_ERR "unknown bus type %d.\n",bus);
791 irq = 0;
792 break;
793 }
794 }
795 BUG_ON(irq >= NR_IRQS);
796
797 /*
798 * PCI IRQ command line redirection. Yes, limits are hardcoded.
799 */
800 if ((pin >= 16) && (pin <= 23)) {
801 if (pirq_entries[pin-16] != -1) {
802 if (!pirq_entries[pin-16]) {
803 apic_printk(APIC_VERBOSE, "disabling PIRQ%d\n", pin-16);
804 } else {
805 irq = pirq_entries[pin-16];
806 apic_printk(APIC_VERBOSE, "using PIRQ%d -> IRQ %d\n",
807 pin-16, irq);
808 }
809 }
810 } 575 }
811 BUG_ON(irq >= NR_IRQS); 576 BUG_ON(irq >= NR_IRQS);
812 return irq; 577 return irq;
@@ -943,9 +708,9 @@ static void __init setup_IO_APIC_irqs(void)
943 if (!apic && (irq < 16)) 708 if (!apic && (irq < 16))
944 disable_8259A_irq(irq); 709 disable_8259A_irq(irq);
945 } 710 }
711 ioapic_write_entry(apic, pin, entry);
712
946 spin_lock_irqsave(&ioapic_lock, flags); 713 spin_lock_irqsave(&ioapic_lock, flags);
947 io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
948 io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
949 set_native_irq_info(irq, TARGET_CPUS); 714 set_native_irq_info(irq, TARGET_CPUS);
950 spin_unlock_irqrestore(&ioapic_lock, flags); 715 spin_unlock_irqrestore(&ioapic_lock, flags);
951 } 716 }
@@ -1083,10 +848,7 @@ void __apicdebuginit print_IO_APIC(void)
1083 for (i = 0; i <= reg_01.bits.entries; i++) { 848 for (i = 0; i <= reg_01.bits.entries; i++) {
1084 struct IO_APIC_route_entry entry; 849 struct IO_APIC_route_entry entry;
1085 850
1086 spin_lock_irqsave(&ioapic_lock, flags); 851 entry = ioapic_read_entry(apic, i);
1087 *(((int *)&entry)+0) = io_apic_read(apic, 0x10+i*2);
1088 *(((int *)&entry)+1) = io_apic_read(apic, 0x11+i*2);
1089 spin_unlock_irqrestore(&ioapic_lock, flags);
1090 852
1091 printk(KERN_DEBUG " %02x %03X %02X ", 853 printk(KERN_DEBUG " %02x %03X %02X ",
1092 i, 854 i,
@@ -1281,9 +1043,6 @@ static void __init enable_IO_APIC(void)
1281 irq_2_pin[i].pin = -1; 1043 irq_2_pin[i].pin = -1;
1282 irq_2_pin[i].next = 0; 1044 irq_2_pin[i].next = 0;
1283 } 1045 }
1284 if (!pirqs_enabled)
1285 for (i = 0; i < MAX_PIRQS; i++)
1286 pirq_entries[i] = -1;
1287 1046
1288 /* 1047 /*
1289 * The number of IO-APIC IRQ registers (== #pins): 1048 * The number of IO-APIC IRQ registers (== #pins):
@@ -1299,11 +1058,7 @@ static void __init enable_IO_APIC(void)
1299 /* See if any of the pins is in ExtINT mode */ 1058 /* See if any of the pins is in ExtINT mode */
1300 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { 1059 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
1301 struct IO_APIC_route_entry entry; 1060 struct IO_APIC_route_entry entry;
1302 spin_lock_irqsave(&ioapic_lock, flags); 1061 entry = ioapic_read_entry(apic, pin);
1303 *(((int *)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
1304 *(((int *)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
1305 spin_unlock_irqrestore(&ioapic_lock, flags);
1306
1307 1062
1308 /* If the interrupt line is enabled and in ExtInt mode 1063 /* If the interrupt line is enabled and in ExtInt mode
1309 * I have found the pin where the i8259 is connected. 1064 * I have found the pin where the i8259 is connected.
@@ -1355,7 +1110,6 @@ void disable_IO_APIC(void)
1355 */ 1110 */
1356 if (ioapic_i8259.pin != -1) { 1111 if (ioapic_i8259.pin != -1) {
1357 struct IO_APIC_route_entry entry; 1112 struct IO_APIC_route_entry entry;
1358 unsigned long flags;
1359 1113
1360 memset(&entry, 0, sizeof(entry)); 1114 memset(&entry, 0, sizeof(entry));
1361 entry.mask = 0; /* Enabled */ 1115 entry.mask = 0; /* Enabled */
@@ -1372,84 +1126,13 @@ void disable_IO_APIC(void)
1372 /* 1126 /*
1373 * Add it to the IO-APIC irq-routing table: 1127 * Add it to the IO-APIC irq-routing table:
1374 */ 1128 */
1375 spin_lock_irqsave(&ioapic_lock, flags); 1129 ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry);
1376 io_apic_write(ioapic_i8259.apic, 0x11+2*ioapic_i8259.pin,
1377 *(((int *)&entry)+1));
1378 io_apic_write(ioapic_i8259.apic, 0x10+2*ioapic_i8259.pin,
1379 *(((int *)&entry)+0));
1380 spin_unlock_irqrestore(&ioapic_lock, flags);
1381 } 1130 }
1382 1131
1383 disconnect_bsp_APIC(ioapic_i8259.pin != -1); 1132 disconnect_bsp_APIC(ioapic_i8259.pin != -1);
1384} 1133}
1385 1134
1386/* 1135/*
1387 * function to set the IO-APIC physical IDs based on the
1388 * values stored in the MPC table.
1389 *
1390 * by Matt Domsch <Matt_Domsch@dell.com> Tue Dec 21 12:25:05 CST 1999
1391 */
1392
1393static void __init setup_ioapic_ids_from_mpc (void)
1394{
1395 union IO_APIC_reg_00 reg_00;
1396 int apic;
1397 int i;
1398 unsigned char old_id;
1399 unsigned long flags;
1400
1401 /*
1402 * Set the IOAPIC ID to the value stored in the MPC table.
1403 */
1404 for (apic = 0; apic < nr_ioapics; apic++) {
1405
1406 /* Read the register 0 value */
1407 spin_lock_irqsave(&ioapic_lock, flags);
1408 reg_00.raw = io_apic_read(apic, 0);
1409 spin_unlock_irqrestore(&ioapic_lock, flags);
1410
1411 old_id = mp_ioapics[apic].mpc_apicid;
1412
1413
1414 printk(KERN_INFO "Using IO-APIC %d\n", mp_ioapics[apic].mpc_apicid);
1415
1416
1417 /*
1418 * We need to adjust the IRQ routing table
1419 * if the ID changed.
1420 */
1421 if (old_id != mp_ioapics[apic].mpc_apicid)
1422 for (i = 0; i < mp_irq_entries; i++)
1423 if (mp_irqs[i].mpc_dstapic == old_id)
1424 mp_irqs[i].mpc_dstapic
1425 = mp_ioapics[apic].mpc_apicid;
1426
1427 /*
1428 * Read the right value from the MPC table and
1429 * write it into the ID register.
1430 */
1431 apic_printk(APIC_VERBOSE,KERN_INFO "...changing IO-APIC physical APIC ID to %d ...",
1432 mp_ioapics[apic].mpc_apicid);
1433
1434 reg_00.bits.ID = mp_ioapics[apic].mpc_apicid;
1435 spin_lock_irqsave(&ioapic_lock, flags);
1436 io_apic_write(apic, 0, reg_00.raw);
1437 spin_unlock_irqrestore(&ioapic_lock, flags);
1438
1439 /*
1440 * Sanity check
1441 */
1442 spin_lock_irqsave(&ioapic_lock, flags);
1443 reg_00.raw = io_apic_read(apic, 0);
1444 spin_unlock_irqrestore(&ioapic_lock, flags);
1445 if (reg_00.bits.ID != mp_ioapics[apic].mpc_apicid)
1446 printk("could not set ID!\n");
1447 else
1448 apic_printk(APIC_VERBOSE," ok.\n");
1449 }
1450}
1451
1452/*
1453 * There is a nasty bug in some older SMP boards, their mptable lies 1136 * There is a nasty bug in some older SMP boards, their mptable lies
1454 * about the timer IRQ. We do the following to work around the situation: 1137 * about the timer IRQ. We do the following to work around the situation:
1455 * 1138 *
@@ -1964,11 +1647,6 @@ void __init setup_IO_APIC(void)
1964 1647
1965 apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n"); 1648 apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n");
1966 1649
1967 /*
1968 * Set up the IO-APIC IRQ routing table.
1969 */
1970 if (!acpi_ioapic)
1971 setup_ioapic_ids_from_mpc();
1972 sync_Arb_IDs(); 1650 sync_Arb_IDs();
1973 setup_IO_APIC_irqs(); 1651 setup_IO_APIC_irqs();
1974 init_IO_APIC_traps(); 1652 init_IO_APIC_traps();
@@ -1987,17 +1665,12 @@ static int ioapic_suspend(struct sys_device *dev, pm_message_t state)
1987{ 1665{
1988 struct IO_APIC_route_entry *entry; 1666 struct IO_APIC_route_entry *entry;
1989 struct sysfs_ioapic_data *data; 1667 struct sysfs_ioapic_data *data;
1990 unsigned long flags;
1991 int i; 1668 int i;
1992 1669
1993 data = container_of(dev, struct sysfs_ioapic_data, dev); 1670 data = container_of(dev, struct sysfs_ioapic_data, dev);
1994 entry = data->entry; 1671 entry = data->entry;
1995 spin_lock_irqsave(&ioapic_lock, flags); 1672 for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ )
1996 for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) { 1673 *entry = ioapic_read_entry(dev->id, i);
1997 *(((int *)entry) + 1) = io_apic_read(dev->id, 0x11 + 2 * i);
1998 *(((int *)entry) + 0) = io_apic_read(dev->id, 0x10 + 2 * i);
1999 }
2000 spin_unlock_irqrestore(&ioapic_lock, flags);
2001 1674
2002 return 0; 1675 return 0;
2003} 1676}
@@ -2019,11 +1692,9 @@ static int ioapic_resume(struct sys_device *dev)
2019 reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid; 1692 reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid;
2020 io_apic_write(dev->id, 0, reg_00.raw); 1693 io_apic_write(dev->id, 0, reg_00.raw);
2021 } 1694 }
2022 for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) {
2023 io_apic_write(dev->id, 0x11+2*i, *(((int *)entry)+1));
2024 io_apic_write(dev->id, 0x10+2*i, *(((int *)entry)+0));
2025 }
2026 spin_unlock_irqrestore(&ioapic_lock, flags); 1695 spin_unlock_irqrestore(&ioapic_lock, flags);
1696 for (i = 0; i < nr_ioapic_registers[dev->id]; i++)
1697 ioapic_write_entry(dev->id, i, entry[i]);
2027 1698
2028 return 0; 1699 return 0;
2029} 1700}
@@ -2077,19 +1748,6 @@ device_initcall(ioapic_init_sysfs);
2077 1748
2078#define IO_APIC_MAX_ID 0xFE 1749#define IO_APIC_MAX_ID 0xFE
2079 1750
2080int __init io_apic_get_version (int ioapic)
2081{
2082 union IO_APIC_reg_01 reg_01;
2083 unsigned long flags;
2084
2085 spin_lock_irqsave(&ioapic_lock, flags);
2086 reg_01.raw = io_apic_read(ioapic, 1);
2087 spin_unlock_irqrestore(&ioapic_lock, flags);
2088
2089 return reg_01.bits.version;
2090}
2091
2092
2093int __init io_apic_get_redir_entries (int ioapic) 1751int __init io_apic_get_redir_entries (int ioapic)
2094{ 1752{
2095 union IO_APIC_reg_01 reg_01; 1753 union IO_APIC_reg_01 reg_01;
@@ -2148,10 +1806,10 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int p
2148 if (!ioapic && (irq < 16)) 1806 if (!ioapic && (irq < 16))
2149 disable_8259A_irq(irq); 1807 disable_8259A_irq(irq);
2150 1808
1809 ioapic_write_entry(ioapic, pin, entry);
1810
2151 spin_lock_irqsave(&ioapic_lock, flags); 1811 spin_lock_irqsave(&ioapic_lock, flags);
2152 io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1)); 1812 set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS);
2153 io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0));
2154 set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS);
2155 spin_unlock_irqrestore(&ioapic_lock, flags); 1813 spin_unlock_irqrestore(&ioapic_lock, flags);
2156 1814
2157 return 0; 1815 return 0;
diff --git a/arch/x86_64/kernel/ioport.c b/arch/x86_64/kernel/ioport.c
index b81614970ecc..fe063d3cfe42 100644
--- a/arch/x86_64/kernel/ioport.c
+++ b/arch/x86_64/kernel/ioport.c
@@ -56,6 +56,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
56 56
57 memset(bitmap, 0xff, IO_BITMAP_BYTES); 57 memset(bitmap, 0xff, IO_BITMAP_BYTES);
58 t->io_bitmap_ptr = bitmap; 58 t->io_bitmap_ptr = bitmap;
59 set_thread_flag(TIF_IO_BITMAP);
59 } 60 }
60 61
61 /* 62 /*
diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c
index 5221a53e90c1..b3677e6ccc6e 100644
--- a/arch/x86_64/kernel/irq.c
+++ b/arch/x86_64/kernel/irq.c
@@ -20,11 +20,6 @@
20#include <asm/idle.h> 20#include <asm/idle.h>
21 21
22atomic_t irq_err_count; 22atomic_t irq_err_count;
23#ifdef CONFIG_X86_IO_APIC
24#ifdef APIC_MISMATCH_DEBUG
25atomic_t irq_mis_count;
26#endif
27#endif
28 23
29#ifdef CONFIG_DEBUG_STACKOVERFLOW 24#ifdef CONFIG_DEBUG_STACKOVERFLOW
30/* 25/*
@@ -92,18 +87,11 @@ skip:
92 for_each_online_cpu(j) 87 for_each_online_cpu(j)
93 seq_printf(p, "%10u ", cpu_pda(j)->__nmi_count); 88 seq_printf(p, "%10u ", cpu_pda(j)->__nmi_count);
94 seq_putc(p, '\n'); 89 seq_putc(p, '\n');
95#ifdef CONFIG_X86_LOCAL_APIC
96 seq_printf(p, "LOC: "); 90 seq_printf(p, "LOC: ");
97 for_each_online_cpu(j) 91 for_each_online_cpu(j)
98 seq_printf(p, "%10u ", cpu_pda(j)->apic_timer_irqs); 92 seq_printf(p, "%10u ", cpu_pda(j)->apic_timer_irqs);
99 seq_putc(p, '\n'); 93 seq_putc(p, '\n');
100#endif
101 seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); 94 seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
102#ifdef CONFIG_X86_IO_APIC
103#ifdef APIC_MISMATCH_DEBUG
104 seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
105#endif
106#endif
107 } 95 }
108 return 0; 96 return 0;
109} 97}
diff --git a/arch/x86_64/kernel/machine_kexec.c b/arch/x86_64/kernel/machine_kexec.c
index 106076b370fc..0497e3bd5bff 100644
--- a/arch/x86_64/kernel/machine_kexec.c
+++ b/arch/x86_64/kernel/machine_kexec.c
@@ -15,6 +15,15 @@
15#include <asm/mmu_context.h> 15#include <asm/mmu_context.h>
16#include <asm/io.h> 16#include <asm/io.h>
17 17
18#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
19static u64 kexec_pgd[512] PAGE_ALIGNED;
20static u64 kexec_pud0[512] PAGE_ALIGNED;
21static u64 kexec_pmd0[512] PAGE_ALIGNED;
22static u64 kexec_pte0[512] PAGE_ALIGNED;
23static u64 kexec_pud1[512] PAGE_ALIGNED;
24static u64 kexec_pmd1[512] PAGE_ALIGNED;
25static u64 kexec_pte1[512] PAGE_ALIGNED;
26
18static void init_level2_page(pmd_t *level2p, unsigned long addr) 27static void init_level2_page(pmd_t *level2p, unsigned long addr)
19{ 28{
20 unsigned long end_addr; 29 unsigned long end_addr;
@@ -144,32 +153,19 @@ static void load_segments(void)
144 ); 153 );
145} 154}
146 155
147typedef NORET_TYPE void (*relocate_new_kernel_t)(unsigned long indirection_page,
148 unsigned long control_code_buffer,
149 unsigned long start_address,
150 unsigned long pgtable) ATTRIB_NORET;
151
152extern const unsigned char relocate_new_kernel[];
153extern const unsigned long relocate_new_kernel_size;
154
155int machine_kexec_prepare(struct kimage *image) 156int machine_kexec_prepare(struct kimage *image)
156{ 157{
157 unsigned long start_pgtable, control_code_buffer; 158 unsigned long start_pgtable;
158 int result; 159 int result;
159 160
160 /* Calculate the offsets */ 161 /* Calculate the offsets */
161 start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT; 162 start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT;
162 control_code_buffer = start_pgtable + PAGE_SIZE;
163 163
164 /* Setup the identity mapped 64bit page table */ 164 /* Setup the identity mapped 64bit page table */
165 result = init_pgtable(image, start_pgtable); 165 result = init_pgtable(image, start_pgtable);
166 if (result) 166 if (result)
167 return result; 167 return result;
168 168
169 /* Place the code in the reboot code buffer */
170 memcpy(__va(control_code_buffer), relocate_new_kernel,
171 relocate_new_kernel_size);
172
173 return 0; 169 return 0;
174} 170}
175 171
@@ -184,28 +180,34 @@ void machine_kexec_cleanup(struct kimage *image)
184 */ 180 */
185NORET_TYPE void machine_kexec(struct kimage *image) 181NORET_TYPE void machine_kexec(struct kimage *image)
186{ 182{
187 unsigned long page_list; 183 unsigned long page_list[PAGES_NR];
188 unsigned long control_code_buffer; 184 void *control_page;
189 unsigned long start_pgtable;
190 relocate_new_kernel_t rnk;
191 185
192 /* Interrupts aren't acceptable while we reboot */ 186 /* Interrupts aren't acceptable while we reboot */
193 local_irq_disable(); 187 local_irq_disable();
194 188
195 /* Calculate the offsets */ 189 control_page = page_address(image->control_code_page) + PAGE_SIZE;
196 page_list = image->head; 190 memcpy(control_page, relocate_kernel, PAGE_SIZE);
197 start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT; 191
198 control_code_buffer = start_pgtable + PAGE_SIZE; 192 page_list[PA_CONTROL_PAGE] = __pa(control_page);
199 193 page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
200 /* Set the low half of the page table to my identity mapped 194 page_list[PA_PGD] = __pa(kexec_pgd);
201 * page table for kexec. Leave the high half pointing at the 195 page_list[VA_PGD] = (unsigned long)kexec_pgd;
202 * kernel pages. Don't bother to flush the global pages 196 page_list[PA_PUD_0] = __pa(kexec_pud0);
203 * as that will happen when I fully switch to my identity mapped 197 page_list[VA_PUD_0] = (unsigned long)kexec_pud0;
204 * page table anyway. 198 page_list[PA_PMD_0] = __pa(kexec_pmd0);
205 */ 199 page_list[VA_PMD_0] = (unsigned long)kexec_pmd0;
206 memcpy(__va(read_cr3()), __va(start_pgtable), PAGE_SIZE/2); 200 page_list[PA_PTE_0] = __pa(kexec_pte0);
207 __flush_tlb(); 201 page_list[VA_PTE_0] = (unsigned long)kexec_pte0;
208 202 page_list[PA_PUD_1] = __pa(kexec_pud1);
203 page_list[VA_PUD_1] = (unsigned long)kexec_pud1;
204 page_list[PA_PMD_1] = __pa(kexec_pmd1);
205 page_list[VA_PMD_1] = (unsigned long)kexec_pmd1;
206 page_list[PA_PTE_1] = __pa(kexec_pte1);
207 page_list[VA_PTE_1] = (unsigned long)kexec_pte1;
208
209 page_list[PA_TABLE_PAGE] =
210 (unsigned long)__pa(page_address(image->control_code_page));
209 211
210 /* The segment registers are funny things, they have both a 212 /* The segment registers are funny things, they have both a
211 * visible and an invisible part. Whenever the visible part is 213 * visible and an invisible part. Whenever the visible part is
@@ -222,7 +224,36 @@ NORET_TYPE void machine_kexec(struct kimage *image)
222 */ 224 */
223 set_gdt(phys_to_virt(0),0); 225 set_gdt(phys_to_virt(0),0);
224 set_idt(phys_to_virt(0),0); 226 set_idt(phys_to_virt(0),0);
227
225 /* now call it */ 228 /* now call it */
226 rnk = (relocate_new_kernel_t) control_code_buffer; 229 relocate_kernel((unsigned long)image->head, (unsigned long)page_list,
227 (*rnk)(page_list, control_code_buffer, image->start, start_pgtable); 230 image->start);
228} 231}
232
233/* crashkernel=size@addr specifies the location to reserve for
234 * a crash kernel. By reserving this memory we guarantee
235 * that linux never set's it up as a DMA target.
236 * Useful for holding code to do something appropriate
237 * after a kernel panic.
238 */
239static int __init setup_crashkernel(char *arg)
240{
241 unsigned long size, base;
242 char *p;
243 if (!arg)
244 return -EINVAL;
245 size = memparse(arg, &p);
246 if (arg == p)
247 return -EINVAL;
248 if (*p == '@') {
249 base = memparse(p+1, &p);
250 /* FIXME: Do I want a sanity check to validate the
251 * memory range? Yes you do, but it's too early for
252 * e820 -AK */
253 crashk_res.start = base;
254 crashk_res.end = base + size - 1;
255 }
256 return 0;
257}
258early_param("crashkernel", setup_crashkernel);
259
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c
index 4e017fb30fb3..bbea88801d88 100644
--- a/arch/x86_64/kernel/mce.c
+++ b/arch/x86_64/kernel/mce.c
@@ -182,7 +182,7 @@ void do_machine_check(struct pt_regs * regs, long error_code)
182 goto out2; 182 goto out2;
183 183
184 memset(&m, 0, sizeof(struct mce)); 184 memset(&m, 0, sizeof(struct mce));
185 m.cpu = safe_smp_processor_id(); 185 m.cpu = smp_processor_id();
186 rdmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus); 186 rdmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus);
187 if (!(m.mcgstatus & MCG_STATUS_RIPV)) 187 if (!(m.mcgstatus & MCG_STATUS_RIPV))
188 kill_it = 1; 188 kill_it = 1;
@@ -274,6 +274,33 @@ void do_machine_check(struct pt_regs * regs, long error_code)
274 atomic_dec(&mce_entry); 274 atomic_dec(&mce_entry);
275} 275}
276 276
277#ifdef CONFIG_X86_MCE_INTEL
278/***
279 * mce_log_therm_throt_event - Logs the thermal throttling event to mcelog
280 * @cpu: The CPU on which the event occured.
281 * @status: Event status information
282 *
283 * This function should be called by the thermal interrupt after the
284 * event has been processed and the decision was made to log the event
285 * further.
286 *
287 * The status parameter will be saved to the 'status' field of 'struct mce'
288 * and historically has been the register value of the
289 * MSR_IA32_THERMAL_STATUS (Intel) msr.
290 */
291void mce_log_therm_throt_event(unsigned int cpu, __u64 status)
292{
293 struct mce m;
294
295 memset(&m, 0, sizeof(m));
296 m.cpu = cpu;
297 m.bank = MCE_THERMAL_BANK;
298 m.status = status;
299 rdtscll(m.tsc);
300 mce_log(&m);
301}
302#endif /* CONFIG_X86_MCE_INTEL */
303
277/* 304/*
278 * Periodic polling timer for "silent" machine check errors. 305 * Periodic polling timer for "silent" machine check errors.
279 */ 306 */
diff --git a/arch/x86_64/kernel/mce_intel.c b/arch/x86_64/kernel/mce_intel.c
index 8f533d2c40cb..6551505d8a2c 100644
--- a/arch/x86_64/kernel/mce_intel.c
+++ b/arch/x86_64/kernel/mce_intel.c
@@ -11,36 +11,21 @@
11#include <asm/mce.h> 11#include <asm/mce.h>
12#include <asm/hw_irq.h> 12#include <asm/hw_irq.h>
13#include <asm/idle.h> 13#include <asm/idle.h>
14 14#include <asm/therm_throt.h>
15static DEFINE_PER_CPU(unsigned long, next_check);
16 15
17asmlinkage void smp_thermal_interrupt(void) 16asmlinkage void smp_thermal_interrupt(void)
18{ 17{
19 struct mce m; 18 __u64 msr_val;
20 19
21 ack_APIC_irq(); 20 ack_APIC_irq();
22 21
23 exit_idle(); 22 exit_idle();
24 irq_enter(); 23 irq_enter();
25 if (time_before(jiffies, __get_cpu_var(next_check)))
26 goto done;
27
28 __get_cpu_var(next_check) = jiffies + HZ*300;
29 memset(&m, 0, sizeof(m));
30 m.cpu = smp_processor_id();
31 m.bank = MCE_THERMAL_BANK;
32 rdtscll(m.tsc);
33 rdmsrl(MSR_IA32_THERM_STATUS, m.status);
34 if (m.status & 0x1) {
35 printk(KERN_EMERG
36 "CPU%d: Temperature above threshold, cpu clock throttled\n", m.cpu);
37 add_taint(TAINT_MACHINE_CHECK);
38 } else {
39 printk(KERN_EMERG "CPU%d: Temperature/speed normal\n", m.cpu);
40 }
41 24
42 mce_log(&m); 25 rdmsrl(MSR_IA32_THERM_STATUS, msr_val);
43done: 26 if (therm_throt_process(msr_val & 1))
27 mce_log_therm_throt_event(smp_processor_id(), msr_val);
28
44 irq_exit(); 29 irq_exit();
45} 30}
46 31
@@ -92,6 +77,9 @@ static void __cpuinit intel_init_thermal(struct cpuinfo_x86 *c)
92 apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED); 77 apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
93 printk(KERN_INFO "CPU%d: Thermal monitoring enabled (%s)\n", 78 printk(KERN_INFO "CPU%d: Thermal monitoring enabled (%s)\n",
94 cpu, tm2 ? "TM2" : "TM1"); 79 cpu, tm2 ? "TM2" : "TM1");
80
81 /* enable thermal throttle processing */
82 atomic_set(&therm_throt_en, 1);
95 return; 83 return;
96} 84}
97 85
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index a1ab4197f8a1..20e88f4b564b 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -41,8 +41,7 @@ int acpi_found_madt;
41 * Various Linux-internal data structures created from the 41 * Various Linux-internal data structures created from the
42 * MP-table. 42 * MP-table.
43 */ 43 */
44unsigned char apic_version [MAX_APICS]; 44DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
45unsigned char mp_bus_id_to_type [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
46int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; 45int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
47 46
48static int mp_current_pci_id = 0; 47static int mp_current_pci_id = 0;
@@ -56,7 +55,6 @@ struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
56int mp_irq_entries; 55int mp_irq_entries;
57 56
58int nr_ioapics; 57int nr_ioapics;
59int pic_mode;
60unsigned long mp_lapic_addr = 0; 58unsigned long mp_lapic_addr = 0;
61 59
62 60
@@ -71,19 +69,6 @@ unsigned disabled_cpus __initdata;
71/* Bitmask of physically existing CPUs */ 69/* Bitmask of physically existing CPUs */
72physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE; 70physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE;
73 71
74/* ACPI MADT entry parsing functions */
75#ifdef CONFIG_ACPI
76extern struct acpi_boot_flags acpi_boot;
77#ifdef CONFIG_X86_LOCAL_APIC
78extern int acpi_parse_lapic (acpi_table_entry_header *header);
79extern int acpi_parse_lapic_addr_ovr (acpi_table_entry_header *header);
80extern int acpi_parse_lapic_nmi (acpi_table_entry_header *header);
81#endif /*CONFIG_X86_LOCAL_APIC*/
82#ifdef CONFIG_X86_IO_APIC
83extern int acpi_parse_ioapic (acpi_table_entry_header *header);
84#endif /*CONFIG_X86_IO_APIC*/
85#endif /*CONFIG_ACPI*/
86
87u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; 72u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID };
88 73
89 74
@@ -108,24 +93,20 @@ static int __init mpf_checksum(unsigned char *mp, int len)
108static void __cpuinit MP_processor_info (struct mpc_config_processor *m) 93static void __cpuinit MP_processor_info (struct mpc_config_processor *m)
109{ 94{
110 int cpu; 95 int cpu;
111 unsigned char ver;
112 cpumask_t tmp_map; 96 cpumask_t tmp_map;
97 char *bootup_cpu = "";
113 98
114 if (!(m->mpc_cpuflag & CPU_ENABLED)) { 99 if (!(m->mpc_cpuflag & CPU_ENABLED)) {
115 disabled_cpus++; 100 disabled_cpus++;
116 return; 101 return;
117 } 102 }
118
119 printk(KERN_INFO "Processor #%d %d:%d APIC version %d\n",
120 m->mpc_apicid,
121 (m->mpc_cpufeature & CPU_FAMILY_MASK)>>8,
122 (m->mpc_cpufeature & CPU_MODEL_MASK)>>4,
123 m->mpc_apicver);
124
125 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { 103 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
126 Dprintk(" Bootup CPU\n"); 104 bootup_cpu = " (Bootup-CPU)";
127 boot_cpu_id = m->mpc_apicid; 105 boot_cpu_id = m->mpc_apicid;
128 } 106 }
107
108 printk(KERN_INFO "Processor #%d%s\n", m->mpc_apicid, bootup_cpu);
109
129 if (num_processors >= NR_CPUS) { 110 if (num_processors >= NR_CPUS) {
130 printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached." 111 printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached."
131 " Processor ignored.\n", NR_CPUS); 112 " Processor ignored.\n", NR_CPUS);
@@ -136,24 +117,7 @@ static void __cpuinit MP_processor_info (struct mpc_config_processor *m)
136 cpus_complement(tmp_map, cpu_present_map); 117 cpus_complement(tmp_map, cpu_present_map);
137 cpu = first_cpu(tmp_map); 118 cpu = first_cpu(tmp_map);
138 119
139#if MAX_APICS < 255
140 if ((int)m->mpc_apicid > MAX_APICS) {
141 printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n",
142 m->mpc_apicid, MAX_APICS);
143 return;
144 }
145#endif
146 ver = m->mpc_apicver;
147
148 physid_set(m->mpc_apicid, phys_cpu_present_map); 120 physid_set(m->mpc_apicid, phys_cpu_present_map);
149 /*
150 * Validate version
151 */
152 if (ver == 0x0) {
153 printk(KERN_ERR "BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->mpc_apicid);
154 ver = 0x10;
155 }
156 apic_version[m->mpc_apicid] = ver;
157 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { 121 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
158 /* 122 /*
159 * bios_cpu_apicid is required to have processors listed 123 * bios_cpu_apicid is required to have processors listed
@@ -178,15 +142,11 @@ static void __init MP_bus_info (struct mpc_config_bus *m)
178 Dprintk("Bus #%d is %s\n", m->mpc_busid, str); 142 Dprintk("Bus #%d is %s\n", m->mpc_busid, str);
179 143
180 if (strncmp(str, "ISA", 3) == 0) { 144 if (strncmp(str, "ISA", 3) == 0) {
181 mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; 145 set_bit(m->mpc_busid, mp_bus_not_pci);
182 } else if (strncmp(str, "EISA", 4) == 0) {
183 mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA;
184 } else if (strncmp(str, "PCI", 3) == 0) { 146 } else if (strncmp(str, "PCI", 3) == 0) {
185 mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI; 147 clear_bit(m->mpc_busid, mp_bus_not_pci);
186 mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id; 148 mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id;
187 mp_current_pci_id++; 149 mp_current_pci_id++;
188 } else if (strncmp(str, "MCA", 3) == 0) {
189 mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA;
190 } else { 150 } else {
191 printk(KERN_ERR "Unknown bustype %s\n", str); 151 printk(KERN_ERR "Unknown bustype %s\n", str);
192 } 152 }
@@ -197,8 +157,8 @@ static void __init MP_ioapic_info (struct mpc_config_ioapic *m)
197 if (!(m->mpc_flags & MPC_APIC_USABLE)) 157 if (!(m->mpc_flags & MPC_APIC_USABLE))
198 return; 158 return;
199 159
200 printk("I/O APIC #%d Version %d at 0x%X.\n", 160 printk("I/O APIC #%d at 0x%X.\n",
201 m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr); 161 m->mpc_apicid, m->mpc_apicaddr);
202 if (nr_ioapics >= MAX_IO_APICS) { 162 if (nr_ioapics >= MAX_IO_APICS) {
203 printk(KERN_ERR "Max # of I/O APICs (%d) exceeded (found %d).\n", 163 printk(KERN_ERR "Max # of I/O APICs (%d) exceeded (found %d).\n",
204 MAX_IO_APICS, nr_ioapics); 164 MAX_IO_APICS, nr_ioapics);
@@ -232,19 +192,6 @@ static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m)
232 m->mpc_irqtype, m->mpc_irqflag & 3, 192 m->mpc_irqtype, m->mpc_irqflag & 3,
233 (m->mpc_irqflag >> 2) &3, m->mpc_srcbusid, 193 (m->mpc_irqflag >> 2) &3, m->mpc_srcbusid,
234 m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint); 194 m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint);
235 /*
236 * Well it seems all SMP boards in existence
237 * use ExtINT/LVT1 == LINT0 and
238 * NMI/LVT2 == LINT1 - the following check
239 * will show us if this assumptions is false.
240 * Until then we do not have to add baggage.
241 */
242 if ((m->mpc_irqtype == mp_ExtINT) &&
243 (m->mpc_destapiclint != 0))
244 BUG();
245 if ((m->mpc_irqtype == mp_NMI) &&
246 (m->mpc_destapiclint != 1))
247 BUG();
248} 195}
249 196
250/* 197/*
@@ -258,7 +205,7 @@ static int __init smp_read_mpc(struct mp_config_table *mpc)
258 unsigned char *mpt=((unsigned char *)mpc)+count; 205 unsigned char *mpt=((unsigned char *)mpc)+count;
259 206
260 if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) { 207 if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) {
261 printk("SMP mptable: bad signature [%c%c%c%c]!\n", 208 printk("MPTABLE: bad signature [%c%c%c%c]!\n",
262 mpc->mpc_signature[0], 209 mpc->mpc_signature[0],
263 mpc->mpc_signature[1], 210 mpc->mpc_signature[1],
264 mpc->mpc_signature[2], 211 mpc->mpc_signature[2],
@@ -266,31 +213,31 @@ static int __init smp_read_mpc(struct mp_config_table *mpc)
266 return 0; 213 return 0;
267 } 214 }
268 if (mpf_checksum((unsigned char *)mpc,mpc->mpc_length)) { 215 if (mpf_checksum((unsigned char *)mpc,mpc->mpc_length)) {
269 printk("SMP mptable: checksum error!\n"); 216 printk("MPTABLE: checksum error!\n");
270 return 0; 217 return 0;
271 } 218 }
272 if (mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04) { 219 if (mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04) {
273 printk(KERN_ERR "SMP mptable: bad table version (%d)!!\n", 220 printk(KERN_ERR "MPTABLE: bad table version (%d)!!\n",
274 mpc->mpc_spec); 221 mpc->mpc_spec);
275 return 0; 222 return 0;
276 } 223 }
277 if (!mpc->mpc_lapic) { 224 if (!mpc->mpc_lapic) {
278 printk(KERN_ERR "SMP mptable: null local APIC address!\n"); 225 printk(KERN_ERR "MPTABLE: null local APIC address!\n");
279 return 0; 226 return 0;
280 } 227 }
281 memcpy(str,mpc->mpc_oem,8); 228 memcpy(str,mpc->mpc_oem,8);
282 str[8]=0; 229 str[8] = 0;
283 printk(KERN_INFO "OEM ID: %s ",str); 230 printk(KERN_INFO "MPTABLE: OEM ID: %s ",str);
284 231
285 memcpy(str,mpc->mpc_productid,12); 232 memcpy(str,mpc->mpc_productid,12);
286 str[12]=0; 233 str[12] = 0;
287 printk("Product ID: %s ",str); 234 printk("MPTABLE: Product ID: %s ",str);
288 235
289 printk("APIC at: 0x%X\n",mpc->mpc_lapic); 236 printk("MPTABLE: APIC at: 0x%X\n",mpc->mpc_lapic);
290 237
291 /* save the local APIC address, it might be non-default */ 238 /* save the local APIC address, it might be non-default */
292 if (!acpi_lapic) 239 if (!acpi_lapic)
293 mp_lapic_addr = mpc->mpc_lapic; 240 mp_lapic_addr = mpc->mpc_lapic;
294 241
295 /* 242 /*
296 * Now process the configuration blocks. 243 * Now process the configuration blocks.
@@ -302,7 +249,7 @@ static int __init smp_read_mpc(struct mp_config_table *mpc)
302 struct mpc_config_processor *m= 249 struct mpc_config_processor *m=
303 (struct mpc_config_processor *)mpt; 250 (struct mpc_config_processor *)mpt;
304 if (!acpi_lapic) 251 if (!acpi_lapic)
305 MP_processor_info(m); 252 MP_processor_info(m);
306 mpt += sizeof(*m); 253 mpt += sizeof(*m);
307 count += sizeof(*m); 254 count += sizeof(*m);
308 break; 255 break;
@@ -321,8 +268,8 @@ static int __init smp_read_mpc(struct mp_config_table *mpc)
321 struct mpc_config_ioapic *m= 268 struct mpc_config_ioapic *m=
322 (struct mpc_config_ioapic *)mpt; 269 (struct mpc_config_ioapic *)mpt;
323 MP_ioapic_info(m); 270 MP_ioapic_info(m);
324 mpt+=sizeof(*m); 271 mpt += sizeof(*m);
325 count+=sizeof(*m); 272 count += sizeof(*m);
326 break; 273 break;
327 } 274 }
328 case MP_INTSRC: 275 case MP_INTSRC:
@@ -331,8 +278,8 @@ static int __init smp_read_mpc(struct mp_config_table *mpc)
331 (struct mpc_config_intsrc *)mpt; 278 (struct mpc_config_intsrc *)mpt;
332 279
333 MP_intsrc_info(m); 280 MP_intsrc_info(m);
334 mpt+=sizeof(*m); 281 mpt += sizeof(*m);
335 count+=sizeof(*m); 282 count += sizeof(*m);
336 break; 283 break;
337 } 284 }
338 case MP_LINTSRC: 285 case MP_LINTSRC:
@@ -340,15 +287,15 @@ static int __init smp_read_mpc(struct mp_config_table *mpc)
340 struct mpc_config_lintsrc *m= 287 struct mpc_config_lintsrc *m=
341 (struct mpc_config_lintsrc *)mpt; 288 (struct mpc_config_lintsrc *)mpt;
342 MP_lintsrc_info(m); 289 MP_lintsrc_info(m);
343 mpt+=sizeof(*m); 290 mpt += sizeof(*m);
344 count+=sizeof(*m); 291 count += sizeof(*m);
345 break; 292 break;
346 } 293 }
347 } 294 }
348 } 295 }
349 clustered_apic_check(); 296 clustered_apic_check();
350 if (!num_processors) 297 if (!num_processors)
351 printk(KERN_ERR "SMP mptable: no processors registered!\n"); 298 printk(KERN_ERR "MPTABLE: no processors registered!\n");
352 return num_processors; 299 return num_processors;
353} 300}
354 301
@@ -444,13 +391,10 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
444 * 2 CPUs, numbered 0 & 1. 391 * 2 CPUs, numbered 0 & 1.
445 */ 392 */
446 processor.mpc_type = MP_PROCESSOR; 393 processor.mpc_type = MP_PROCESSOR;
447 /* Either an integrated APIC or a discrete 82489DX. */ 394 processor.mpc_apicver = 0;
448 processor.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01;
449 processor.mpc_cpuflag = CPU_ENABLED; 395 processor.mpc_cpuflag = CPU_ENABLED;
450 processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | 396 processor.mpc_cpufeature = 0;
451 (boot_cpu_data.x86_model << 4) | 397 processor.mpc_featureflag = 0;
452 boot_cpu_data.x86_mask;
453 processor.mpc_featureflag = boot_cpu_data.x86_capability[0];
454 processor.mpc_reserved[0] = 0; 398 processor.mpc_reserved[0] = 0;
455 processor.mpc_reserved[1] = 0; 399 processor.mpc_reserved[1] = 0;
456 for (i = 0; i < 2; i++) { 400 for (i = 0; i < 2; i++) {
@@ -469,14 +413,6 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
469 case 5: 413 case 5:
470 memcpy(bus.mpc_bustype, "ISA ", 6); 414 memcpy(bus.mpc_bustype, "ISA ", 6);
471 break; 415 break;
472 case 2:
473 case 6:
474 case 3:
475 memcpy(bus.mpc_bustype, "EISA ", 6);
476 break;
477 case 4:
478 case 7:
479 memcpy(bus.mpc_bustype, "MCA ", 6);
480 } 416 }
481 MP_bus_info(&bus); 417 MP_bus_info(&bus);
482 if (mpc_default_type > 4) { 418 if (mpc_default_type > 4) {
@@ -487,7 +423,7 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
487 423
488 ioapic.mpc_type = MP_IOAPIC; 424 ioapic.mpc_type = MP_IOAPIC;
489 ioapic.mpc_apicid = 2; 425 ioapic.mpc_apicid = 2;
490 ioapic.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01; 426 ioapic.mpc_apicver = 0;
491 ioapic.mpc_flags = MPC_APIC_USABLE; 427 ioapic.mpc_flags = MPC_APIC_USABLE;
492 ioapic.mpc_apicaddr = 0xFEC00000; 428 ioapic.mpc_apicaddr = 0xFEC00000;
493 MP_ioapic_info(&ioapic); 429 MP_ioapic_info(&ioapic);
@@ -530,13 +466,6 @@ void __init get_smp_config (void)
530 printk(KERN_INFO "Using ACPI for processor (LAPIC) configuration information\n"); 466 printk(KERN_INFO "Using ACPI for processor (LAPIC) configuration information\n");
531 467
532 printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification); 468 printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
533 if (mpf->mpf_feature2 & (1<<7)) {
534 printk(KERN_INFO " IMCR and PIC compatibility mode.\n");
535 pic_mode = 1;
536 } else {
537 printk(KERN_INFO " Virtual Wire compatibility mode.\n");
538 pic_mode = 0;
539 }
540 469
541 /* 470 /*
542 * Now see if we need to read further. 471 * Now see if we need to read further.
@@ -616,7 +545,7 @@ static int __init smp_scan_config (unsigned long base, unsigned long length)
616 return 0; 545 return 0;
617} 546}
618 547
619void __init find_intel_smp (void) 548void __init find_smp_config(void)
620{ 549{
621 unsigned int address; 550 unsigned int address;
622 551
@@ -633,9 +562,7 @@ void __init find_intel_smp (void)
633 smp_scan_config(0xF0000,0x10000)) 562 smp_scan_config(0xF0000,0x10000))
634 return; 563 return;
635 /* 564 /*
636 * If it is an SMP machine we should know now, unless the 565 * If it is an SMP machine we should know now.
637 * configuration is in an EISA/MCA bus machine with an
638 * extended bios data area.
639 * 566 *
640 * there is a real-mode segmented pointer pointing to the 567 * there is a real-mode segmented pointer pointing to the
641 * 4K EBDA area at 0x40E, calculate and scan it here. 568 * 4K EBDA area at 0x40E, calculate and scan it here.
@@ -656,69 +583,41 @@ void __init find_intel_smp (void)
656 printk(KERN_INFO "No mptable found.\n"); 583 printk(KERN_INFO "No mptable found.\n");
657} 584}
658 585
659/*
660 * - Intel MP Configuration Table
661 */
662void __init find_smp_config (void)
663{
664#ifdef CONFIG_X86_LOCAL_APIC
665 find_intel_smp();
666#endif
667}
668
669
670/* -------------------------------------------------------------------------- 586/* --------------------------------------------------------------------------
671 ACPI-based MP Configuration 587 ACPI-based MP Configuration
672 -------------------------------------------------------------------------- */ 588 -------------------------------------------------------------------------- */
673 589
674#ifdef CONFIG_ACPI 590#ifdef CONFIG_ACPI
675 591
676void __init mp_register_lapic_address ( 592void __init mp_register_lapic_address(u64 address)
677 u64 address)
678{ 593{
679 mp_lapic_addr = (unsigned long) address; 594 mp_lapic_addr = (unsigned long) address;
680
681 set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr); 595 set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
682
683 if (boot_cpu_id == -1U) 596 if (boot_cpu_id == -1U)
684 boot_cpu_id = GET_APIC_ID(apic_read(APIC_ID)); 597 boot_cpu_id = GET_APIC_ID(apic_read(APIC_ID));
685
686 Dprintk("Boot CPU = %d\n", boot_cpu_physical_apicid);
687} 598}
688 599
689 600void __cpuinit mp_register_lapic (u8 id, u8 enabled)
690void __cpuinit mp_register_lapic (
691 u8 id,
692 u8 enabled)
693{ 601{
694 struct mpc_config_processor processor; 602 struct mpc_config_processor processor;
695 int boot_cpu = 0; 603 int boot_cpu = 0;
696 604
697 if (id >= MAX_APICS) { 605 if (id == boot_cpu_id)
698 printk(KERN_WARNING "Processor #%d invalid (max %d)\n",
699 id, MAX_APICS);
700 return;
701 }
702
703 if (id == boot_cpu_physical_apicid)
704 boot_cpu = 1; 606 boot_cpu = 1;
705 607
706 processor.mpc_type = MP_PROCESSOR; 608 processor.mpc_type = MP_PROCESSOR;
707 processor.mpc_apicid = id; 609 processor.mpc_apicid = id;
708 processor.mpc_apicver = GET_APIC_VERSION(apic_read(APIC_LVR)); 610 processor.mpc_apicver = 0;
709 processor.mpc_cpuflag = (enabled ? CPU_ENABLED : 0); 611 processor.mpc_cpuflag = (enabled ? CPU_ENABLED : 0);
710 processor.mpc_cpuflag |= (boot_cpu ? CPU_BOOTPROCESSOR : 0); 612 processor.mpc_cpuflag |= (boot_cpu ? CPU_BOOTPROCESSOR : 0);
711 processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | 613 processor.mpc_cpufeature = 0;
712 (boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_mask; 614 processor.mpc_featureflag = 0;
713 processor.mpc_featureflag = boot_cpu_data.x86_capability[0];
714 processor.mpc_reserved[0] = 0; 615 processor.mpc_reserved[0] = 0;
715 processor.mpc_reserved[1] = 0; 616 processor.mpc_reserved[1] = 0;
716 617
717 MP_processor_info(&processor); 618 MP_processor_info(&processor);
718} 619}
719 620
720#ifdef CONFIG_X86_IO_APIC
721
722#define MP_ISA_BUS 0 621#define MP_ISA_BUS 0
723#define MP_MAX_IOAPIC_PIN 127 622#define MP_MAX_IOAPIC_PIN 127
724 623
@@ -729,11 +628,9 @@ static struct mp_ioapic_routing {
729 u32 pin_programmed[4]; 628 u32 pin_programmed[4];
730} mp_ioapic_routing[MAX_IO_APICS]; 629} mp_ioapic_routing[MAX_IO_APICS];
731 630
732 631static int mp_find_ioapic(int gsi)
733static int mp_find_ioapic (
734 int gsi)
735{ 632{
736 int i = 0; 633 int i = 0;
737 634
738 /* Find the IOAPIC that manages this GSI. */ 635 /* Find the IOAPIC that manages this GSI. */
739 for (i = 0; i < nr_ioapics; i++) { 636 for (i = 0; i < nr_ioapics; i++) {
@@ -743,17 +640,12 @@ static int mp_find_ioapic (
743 } 640 }
744 641
745 printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi); 642 printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi);
746
747 return -1; 643 return -1;
748} 644}
749
750 645
751void __init mp_register_ioapic ( 646void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base)
752 u8 id,
753 u32 address,
754 u32 gsi_base)
755{ 647{
756 int idx = 0; 648 int idx = 0;
757 649
758 if (nr_ioapics >= MAX_IO_APICS) { 650 if (nr_ioapics >= MAX_IO_APICS) {
759 printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " 651 printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded "
@@ -774,7 +666,7 @@ void __init mp_register_ioapic (
774 666
775 set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); 667 set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
776 mp_ioapics[idx].mpc_apicid = id; 668 mp_ioapics[idx].mpc_apicid = id;
777 mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx); 669 mp_ioapics[idx].mpc_apicver = 0;
778 670
779 /* 671 /*
780 * Build basic IRQ lookup table to facilitate gsi->io_apic lookups 672 * Build basic IRQ lookup table to facilitate gsi->io_apic lookups
@@ -785,21 +677,15 @@ void __init mp_register_ioapic (
785 mp_ioapic_routing[idx].gsi_end = gsi_base + 677 mp_ioapic_routing[idx].gsi_end = gsi_base +
786 io_apic_get_redir_entries(idx); 678 io_apic_get_redir_entries(idx);
787 679
788 printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, " 680 printk(KERN_INFO "IOAPIC[%d]: apic_id %d, address 0x%x, "
789 "GSI %d-%d\n", idx, mp_ioapics[idx].mpc_apicid, 681 "GSI %d-%d\n", idx, mp_ioapics[idx].mpc_apicid,
790 mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr, 682 mp_ioapics[idx].mpc_apicaddr,
791 mp_ioapic_routing[idx].gsi_start, 683 mp_ioapic_routing[idx].gsi_start,
792 mp_ioapic_routing[idx].gsi_end); 684 mp_ioapic_routing[idx].gsi_end);
793
794 return;
795} 685}
796 686
797 687void __init
798void __init mp_override_legacy_irq ( 688mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
799 u8 bus_irq,
800 u8 polarity,
801 u8 trigger,
802 u32 gsi)
803{ 689{
804 struct mpc_config_intsrc intsrc; 690 struct mpc_config_intsrc intsrc;
805 int ioapic = -1; 691 int ioapic = -1;
@@ -837,22 +723,18 @@ void __init mp_override_legacy_irq (
837 mp_irqs[mp_irq_entries] = intsrc; 723 mp_irqs[mp_irq_entries] = intsrc;
838 if (++mp_irq_entries == MAX_IRQ_SOURCES) 724 if (++mp_irq_entries == MAX_IRQ_SOURCES)
839 panic("Max # of irq sources exceeded!\n"); 725 panic("Max # of irq sources exceeded!\n");
840
841 return;
842} 726}
843 727
844 728void __init mp_config_acpi_legacy_irqs(void)
845void __init mp_config_acpi_legacy_irqs (void)
846{ 729{
847 struct mpc_config_intsrc intsrc; 730 struct mpc_config_intsrc intsrc;
848 int i = 0; 731 int i = 0;
849 int ioapic = -1; 732 int ioapic = -1;
850 733
851 /* 734 /*
852 * Fabricate the legacy ISA bus (bus #31). 735 * Fabricate the legacy ISA bus (bus #31).
853 */ 736 */
854 mp_bus_id_to_type[MP_ISA_BUS] = MP_BUS_ISA; 737 set_bit(MP_ISA_BUS, mp_bus_not_pci);
855 Dprintk("Bus #%d is ISA\n", MP_ISA_BUS);
856 738
857 /* 739 /*
858 * Locate the IOAPIC that manages the ISA IRQs (0-15). 740 * Locate the IOAPIC that manages the ISA IRQs (0-15).
@@ -905,24 +787,22 @@ void __init mp_config_acpi_legacy_irqs (void)
905 if (++mp_irq_entries == MAX_IRQ_SOURCES) 787 if (++mp_irq_entries == MAX_IRQ_SOURCES)
906 panic("Max # of irq sources exceeded!\n"); 788 panic("Max # of irq sources exceeded!\n");
907 } 789 }
908
909 return;
910} 790}
911 791
912#define MAX_GSI_NUM 4096 792#define MAX_GSI_NUM 4096
913 793
914int mp_register_gsi(u32 gsi, int triggering, int polarity) 794int mp_register_gsi(u32 gsi, int triggering, int polarity)
915{ 795{
916 int ioapic = -1; 796 int ioapic = -1;
917 int ioapic_pin = 0; 797 int ioapic_pin = 0;
918 int idx, bit = 0; 798 int idx, bit = 0;
919 static int pci_irq = 16; 799 static int pci_irq = 16;
920 /* 800 /*
921 * Mapping between Global System Interrupts, which 801 * Mapping between Global System Interrupts, which
922 * represent all possible interrupts, to the IRQs 802 * represent all possible interrupts, to the IRQs
923 * assigned to actual devices. 803 * assigned to actual devices.
924 */ 804 */
925 static int gsi_to_irq[MAX_GSI_NUM]; 805 static int gsi_to_irq[MAX_GSI_NUM];
926 806
927 if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) 807 if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
928 return gsi; 808 return gsi;
@@ -996,6 +876,4 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity)
996 polarity == ACPI_ACTIVE_HIGH ? 0 : 1); 876 polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
997 return gsi; 877 return gsi;
998} 878}
999
1000#endif /*CONFIG_X86_IO_APIC*/
1001#endif /*CONFIG_ACPI*/ 879#endif /*CONFIG_ACPI*/
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
index 5baa0c726e97..4d6fb047952e 100644
--- a/arch/x86_64/kernel/nmi.c
+++ b/arch/x86_64/kernel/nmi.c
@@ -28,71 +28,138 @@
28#include <asm/mce.h> 28#include <asm/mce.h>
29#include <asm/intel_arch_perfmon.h> 29#include <asm/intel_arch_perfmon.h>
30 30
31/* 31/* perfctr_nmi_owner tracks the ownership of the perfctr registers:
32 * lapic_nmi_owner tracks the ownership of the lapic NMI hardware: 32 * evtsel_nmi_owner tracks the ownership of the event selection
33 * - it may be reserved by some other driver, or not 33 * - different performance counters/ event selection may be reserved for
34 * - when not reserved by some other driver, it may be used for 34 * different subsystems this reservation system just tries to coordinate
35 * the NMI watchdog, or not 35 * things a little
36 *
37 * This is maintained separately from nmi_active because the NMI
38 * watchdog may also be driven from the I/O APIC timer.
39 */ 36 */
40static DEFINE_SPINLOCK(lapic_nmi_owner_lock); 37static DEFINE_PER_CPU(unsigned, perfctr_nmi_owner);
41static unsigned int lapic_nmi_owner; 38static DEFINE_PER_CPU(unsigned, evntsel_nmi_owner[2]);
42#define LAPIC_NMI_WATCHDOG (1<<0) 39
43#define LAPIC_NMI_RESERVED (1<<1) 40/* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's
41 * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now)
42 */
43#define NMI_MAX_COUNTER_BITS 66
44 44
45/* nmi_active: 45/* nmi_active:
46 * +1: the lapic NMI watchdog is active, but can be disabled 46 * >0: the lapic NMI watchdog is active, but can be disabled
47 * 0: the lapic NMI watchdog has not been set up, and cannot 47 * <0: the lapic NMI watchdog has not been set up, and cannot
48 * be enabled 48 * be enabled
49 * -1: the lapic NMI watchdog is disabled, but can be enabled 49 * 0: the lapic NMI watchdog is disabled, but can be enabled
50 */ 50 */
51int nmi_active; /* oprofile uses this */ 51atomic_t nmi_active = ATOMIC_INIT(0); /* oprofile uses this */
52int panic_on_timeout; 52int panic_on_timeout;
53 53
54unsigned int nmi_watchdog = NMI_DEFAULT; 54unsigned int nmi_watchdog = NMI_DEFAULT;
55static unsigned int nmi_hz = HZ; 55static unsigned int nmi_hz = HZ;
56static unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */
57static unsigned int nmi_p4_cccr_val;
58 56
59/* Note that these events don't tick when the CPU idles. This means 57struct nmi_watchdog_ctlblk {
60 the frequency varies with CPU load. */ 58 int enabled;
59 u64 check_bit;
60 unsigned int cccr_msr;
61 unsigned int perfctr_msr; /* the MSR to reset in NMI handler */
62 unsigned int evntsel_msr; /* the MSR to select the events to handle */
63};
64static DEFINE_PER_CPU(struct nmi_watchdog_ctlblk, nmi_watchdog_ctlblk);
61 65
62#define K7_EVNTSEL_ENABLE (1 << 22) 66/* local prototypes */
63#define K7_EVNTSEL_INT (1 << 20) 67static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu);
64#define K7_EVNTSEL_OS (1 << 17)
65#define K7_EVNTSEL_USR (1 << 16)
66#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76
67#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING
68 68
69#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL 69/* converts an msr to an appropriate reservation bit */
70#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK 70static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr)
71{
72 /* returns the bit offset of the performance counter register */
73 switch (boot_cpu_data.x86_vendor) {
74 case X86_VENDOR_AMD:
75 return (msr - MSR_K7_PERFCTR0);
76 case X86_VENDOR_INTEL:
77 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON))
78 return (msr - MSR_ARCH_PERFMON_PERFCTR0);
79 else
80 return (msr - MSR_P4_BPU_PERFCTR0);
81 }
82 return 0;
83}
71 84
72#define MSR_P4_MISC_ENABLE 0x1A0 85/* converts an msr to an appropriate reservation bit */
73#define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7) 86static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr)
74#define MSR_P4_MISC_ENABLE_PEBS_UNAVAIL (1<<12) 87{
75#define MSR_P4_PERFCTR0 0x300 88 /* returns the bit offset of the event selection register */
76#define MSR_P4_CCCR0 0x360 89 switch (boot_cpu_data.x86_vendor) {
77#define P4_ESCR_EVENT_SELECT(N) ((N)<<25) 90 case X86_VENDOR_AMD:
78#define P4_ESCR_OS (1<<3) 91 return (msr - MSR_K7_EVNTSEL0);
79#define P4_ESCR_USR (1<<2) 92 case X86_VENDOR_INTEL:
80#define P4_CCCR_OVF_PMI0 (1<<26) 93 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON))
81#define P4_CCCR_OVF_PMI1 (1<<27) 94 return (msr - MSR_ARCH_PERFMON_EVENTSEL0);
82#define P4_CCCR_THRESHOLD(N) ((N)<<20) 95 else
83#define P4_CCCR_COMPLEMENT (1<<19) 96 return (msr - MSR_P4_BSU_ESCR0);
84#define P4_CCCR_COMPARE (1<<18) 97 }
85#define P4_CCCR_REQUIRED (3<<16) 98 return 0;
86#define P4_CCCR_ESCR_SELECT(N) ((N)<<13) 99}
87#define P4_CCCR_ENABLE (1<<12) 100
88/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter 101/* checks for a bit availability (hack for oprofile) */
89 CRU_ESCR0 (with any non-null event selector) through a complemented 102int avail_to_resrv_perfctr_nmi_bit(unsigned int counter)
90 max threshold. [IA32-Vol3, Section 14.9.9] */ 103{
91#define MSR_P4_IQ_COUNTER0 0x30C 104 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
92#define P4_NMI_CRU_ESCR0 (P4_ESCR_EVENT_SELECT(0x3F)|P4_ESCR_OS|P4_ESCR_USR) 105
93#define P4_NMI_IQ_CCCR0 \ 106 return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner)));
94 (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \ 107}
95 P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE) 108
109/* checks the an msr for availability */
110int avail_to_resrv_perfctr_nmi(unsigned int msr)
111{
112 unsigned int counter;
113
114 counter = nmi_perfctr_msr_to_bit(msr);
115 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
116
117 return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner)));
118}
119
120int reserve_perfctr_nmi(unsigned int msr)
121{
122 unsigned int counter;
123
124 counter = nmi_perfctr_msr_to_bit(msr);
125 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
126
127 if (!test_and_set_bit(counter, &__get_cpu_var(perfctr_nmi_owner)))
128 return 1;
129 return 0;
130}
131
132void release_perfctr_nmi(unsigned int msr)
133{
134 unsigned int counter;
135
136 counter = nmi_perfctr_msr_to_bit(msr);
137 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
138
139 clear_bit(counter, &__get_cpu_var(perfctr_nmi_owner));
140}
141
142int reserve_evntsel_nmi(unsigned int msr)
143{
144 unsigned int counter;
145
146 counter = nmi_evntsel_msr_to_bit(msr);
147 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
148
149 if (!test_and_set_bit(counter, &__get_cpu_var(evntsel_nmi_owner)))
150 return 1;
151 return 0;
152}
153
154void release_evntsel_nmi(unsigned int msr)
155{
156 unsigned int counter;
157
158 counter = nmi_evntsel_msr_to_bit(msr);
159 BUG_ON(counter > NMI_MAX_COUNTER_BITS);
160
161 clear_bit(counter, &__get_cpu_var(evntsel_nmi_owner));
162}
96 163
97static __cpuinit inline int nmi_known_cpu(void) 164static __cpuinit inline int nmi_known_cpu(void)
98{ 165{
@@ -109,7 +176,7 @@ static __cpuinit inline int nmi_known_cpu(void)
109} 176}
110 177
111/* Run after command line and cpu_init init, but before all other checks */ 178/* Run after command line and cpu_init init, but before all other checks */
112void __cpuinit nmi_watchdog_default(void) 179void nmi_watchdog_default(void)
113{ 180{
114 if (nmi_watchdog != NMI_DEFAULT) 181 if (nmi_watchdog != NMI_DEFAULT)
115 return; 182 return;
@@ -145,6 +212,12 @@ int __init check_nmi_watchdog (void)
145 int *counts; 212 int *counts;
146 int cpu; 213 int cpu;
147 214
215 if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT))
216 return 0;
217
218 if (!atomic_read(&nmi_active))
219 return 0;
220
148 counts = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL); 221 counts = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL);
149 if (!counts) 222 if (!counts)
150 return -1; 223 return -1;
@@ -162,26 +235,43 @@ int __init check_nmi_watchdog (void)
162 mdelay((10*1000)/nmi_hz); // wait 10 ticks 235 mdelay((10*1000)/nmi_hz); // wait 10 ticks
163 236
164 for_each_online_cpu(cpu) { 237 for_each_online_cpu(cpu) {
238 if (!per_cpu(nmi_watchdog_ctlblk, cpu).enabled)
239 continue;
165 if (cpu_pda(cpu)->__nmi_count - counts[cpu] <= 5) { 240 if (cpu_pda(cpu)->__nmi_count - counts[cpu] <= 5) {
166 endflag = 1;
167 printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n", 241 printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n",
168 cpu, 242 cpu,
169 counts[cpu], 243 counts[cpu],
170 cpu_pda(cpu)->__nmi_count); 244 cpu_pda(cpu)->__nmi_count);
171 nmi_active = 0; 245 per_cpu(nmi_watchdog_ctlblk, cpu).enabled = 0;
172 lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG; 246 atomic_dec(&nmi_active);
173 nmi_perfctr_msr = 0;
174 kfree(counts);
175 return -1;
176 } 247 }
177 } 248 }
249 if (!atomic_read(&nmi_active)) {
250 kfree(counts);
251 atomic_set(&nmi_active, -1);
252 return -1;
253 }
178 endflag = 1; 254 endflag = 1;
179 printk("OK.\n"); 255 printk("OK.\n");
180 256
181 /* now that we know it works we can reduce NMI frequency to 257 /* now that we know it works we can reduce NMI frequency to
182 something more reasonable; makes a difference in some configs */ 258 something more reasonable; makes a difference in some configs */
183 if (nmi_watchdog == NMI_LOCAL_APIC) 259 if (nmi_watchdog == NMI_LOCAL_APIC) {
260 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
261
184 nmi_hz = 1; 262 nmi_hz = 1;
263 /*
264 * On Intel CPUs with ARCH_PERFMON only 32 bits in the counter
265 * are writable, with higher bits sign extending from bit 31.
266 * So, we can only program the counter with 31 bit values and
267 * 32nd bit should be 1, for 33.. to be 1.
268 * Find the appropriate nmi_hz
269 */
270 if (wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0 &&
271 ((u64)cpu_khz * 1000) > 0x7fffffffULL) {
272 nmi_hz = ((u64)cpu_khz * 1000) / 0x7fffffffUL + 1;
273 }
274 }
185 275
186 kfree(counts); 276 kfree(counts);
187 return 0; 277 return 0;
@@ -201,91 +291,65 @@ int __init setup_nmi_watchdog(char *str)
201 291
202 get_option(&str, &nmi); 292 get_option(&str, &nmi);
203 293
204 if (nmi >= NMI_INVALID) 294 if ((nmi >= NMI_INVALID) || (nmi < NMI_NONE))
205 return 0; 295 return 0;
296
297 if ((nmi == NMI_LOCAL_APIC) && (nmi_known_cpu() == 0))
298 return 0; /* no lapic support */
206 nmi_watchdog = nmi; 299 nmi_watchdog = nmi;
207 return 1; 300 return 1;
208} 301}
209 302
210__setup("nmi_watchdog=", setup_nmi_watchdog); 303__setup("nmi_watchdog=", setup_nmi_watchdog);
211 304
212static void disable_intel_arch_watchdog(void);
213
214static void disable_lapic_nmi_watchdog(void) 305static void disable_lapic_nmi_watchdog(void)
215{ 306{
216 if (nmi_active <= 0) 307 BUG_ON(nmi_watchdog != NMI_LOCAL_APIC);
308
309 if (atomic_read(&nmi_active) <= 0)
217 return; 310 return;
218 switch (boot_cpu_data.x86_vendor) {
219 case X86_VENDOR_AMD:
220 wrmsr(MSR_K7_EVNTSEL0, 0, 0);
221 break;
222 case X86_VENDOR_INTEL:
223 if (boot_cpu_data.x86 == 15) {
224 wrmsr(MSR_P4_IQ_CCCR0, 0, 0);
225 wrmsr(MSR_P4_CRU_ESCR0, 0, 0);
226 } else if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
227 disable_intel_arch_watchdog();
228 }
229 break;
230 }
231 nmi_active = -1;
232 /* tell do_nmi() and others that we're not active any more */
233 nmi_watchdog = 0;
234}
235 311
236static void enable_lapic_nmi_watchdog(void) 312 on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1);
237{ 313
238 if (nmi_active < 0) { 314 BUG_ON(atomic_read(&nmi_active) != 0);
239 nmi_watchdog = NMI_LOCAL_APIC;
240 touch_nmi_watchdog();
241 setup_apic_nmi_watchdog();
242 }
243} 315}
244 316
245int reserve_lapic_nmi(void) 317static void enable_lapic_nmi_watchdog(void)
246{ 318{
247 unsigned int old_owner; 319 BUG_ON(nmi_watchdog != NMI_LOCAL_APIC);
248 320
249 spin_lock(&lapic_nmi_owner_lock); 321 /* are we already enabled */
250 old_owner = lapic_nmi_owner; 322 if (atomic_read(&nmi_active) != 0)
251 lapic_nmi_owner |= LAPIC_NMI_RESERVED; 323 return;
252 spin_unlock(&lapic_nmi_owner_lock);
253 if (old_owner & LAPIC_NMI_RESERVED)
254 return -EBUSY;
255 if (old_owner & LAPIC_NMI_WATCHDOG)
256 disable_lapic_nmi_watchdog();
257 return 0;
258}
259 324
260void release_lapic_nmi(void) 325 /* are we lapic aware */
261{ 326 if (nmi_known_cpu() <= 0)
262 unsigned int new_owner; 327 return;
263 328
264 spin_lock(&lapic_nmi_owner_lock); 329 on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1);
265 new_owner = lapic_nmi_owner & ~LAPIC_NMI_RESERVED; 330 touch_nmi_watchdog();
266 lapic_nmi_owner = new_owner;
267 spin_unlock(&lapic_nmi_owner_lock);
268 if (new_owner & LAPIC_NMI_WATCHDOG)
269 enable_lapic_nmi_watchdog();
270} 331}
271 332
272void disable_timer_nmi_watchdog(void) 333void disable_timer_nmi_watchdog(void)
273{ 334{
274 if ((nmi_watchdog != NMI_IO_APIC) || (nmi_active <= 0)) 335 BUG_ON(nmi_watchdog != NMI_IO_APIC);
336
337 if (atomic_read(&nmi_active) <= 0)
275 return; 338 return;
276 339
277 disable_irq(0); 340 disable_irq(0);
278 unset_nmi_callback(); 341 on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1);
279 nmi_active = -1; 342
280 nmi_watchdog = NMI_NONE; 343 BUG_ON(atomic_read(&nmi_active) != 0);
281} 344}
282 345
283void enable_timer_nmi_watchdog(void) 346void enable_timer_nmi_watchdog(void)
284{ 347{
285 if (nmi_active < 0) { 348 BUG_ON(nmi_watchdog != NMI_IO_APIC);
286 nmi_watchdog = NMI_IO_APIC; 349
350 if (atomic_read(&nmi_active) == 0) {
287 touch_nmi_watchdog(); 351 touch_nmi_watchdog();
288 nmi_active = 1; 352 on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1);
289 enable_irq(0); 353 enable_irq(0);
290 } 354 }
291} 355}
@@ -296,15 +360,20 @@ static int nmi_pm_active; /* nmi_active before suspend */
296 360
297static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state) 361static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state)
298{ 362{
299 nmi_pm_active = nmi_active; 363 /* only CPU0 goes here, other CPUs should be offline */
300 disable_lapic_nmi_watchdog(); 364 nmi_pm_active = atomic_read(&nmi_active);
365 stop_apic_nmi_watchdog(NULL);
366 BUG_ON(atomic_read(&nmi_active) != 0);
301 return 0; 367 return 0;
302} 368}
303 369
304static int lapic_nmi_resume(struct sys_device *dev) 370static int lapic_nmi_resume(struct sys_device *dev)
305{ 371{
306 if (nmi_pm_active > 0) 372 /* only CPU0 goes here, other CPUs should be offline */
307 enable_lapic_nmi_watchdog(); 373 if (nmi_pm_active > 0) {
374 setup_apic_nmi_watchdog(NULL);
375 touch_nmi_watchdog();
376 }
308 return 0; 377 return 0;
309} 378}
310 379
@@ -323,7 +392,13 @@ static int __init init_lapic_nmi_sysfs(void)
323{ 392{
324 int error; 393 int error;
325 394
326 if (nmi_active == 0 || nmi_watchdog != NMI_LOCAL_APIC) 395 /* should really be a BUG_ON but b/c this is an
396 * init call, it just doesn't work. -dcz
397 */
398 if (nmi_watchdog != NMI_LOCAL_APIC)
399 return 0;
400
401 if ( atomic_read(&nmi_active) < 0 )
327 return 0; 402 return 0;
328 403
329 error = sysdev_class_register(&nmi_sysclass); 404 error = sysdev_class_register(&nmi_sysclass);
@@ -341,74 +416,209 @@ late_initcall(init_lapic_nmi_sysfs);
341 * Original code written by Keith Owens. 416 * Original code written by Keith Owens.
342 */ 417 */
343 418
344static void clear_msr_range(unsigned int base, unsigned int n) 419/* Note that these events don't tick when the CPU idles. This means
345{ 420 the frequency varies with CPU load. */
346 unsigned int i;
347 421
348 for(i = 0; i < n; ++i) 422#define K7_EVNTSEL_ENABLE (1 << 22)
349 wrmsr(base+i, 0, 0); 423#define K7_EVNTSEL_INT (1 << 20)
350} 424#define K7_EVNTSEL_OS (1 << 17)
425#define K7_EVNTSEL_USR (1 << 16)
426#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76
427#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING
351 428
352static void setup_k7_watchdog(void) 429static int setup_k7_watchdog(void)
353{ 430{
354 int i; 431 unsigned int perfctr_msr, evntsel_msr;
355 unsigned int evntsel; 432 unsigned int evntsel;
433 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
356 434
357 nmi_perfctr_msr = MSR_K7_PERFCTR0; 435 perfctr_msr = MSR_K7_PERFCTR0;
436 evntsel_msr = MSR_K7_EVNTSEL0;
437 if (!reserve_perfctr_nmi(perfctr_msr))
438 goto fail;
358 439
359 for(i = 0; i < 4; ++i) { 440 if (!reserve_evntsel_nmi(evntsel_msr))
360 /* Simulator may not support it */ 441 goto fail1;
361 if (checking_wrmsrl(MSR_K7_EVNTSEL0+i, 0UL)) { 442
362 nmi_perfctr_msr = 0; 443 /* Simulator may not support it */
363 return; 444 if (checking_wrmsrl(evntsel_msr, 0UL))
364 } 445 goto fail2;
365 wrmsrl(MSR_K7_PERFCTR0+i, 0UL); 446 wrmsrl(perfctr_msr, 0UL);
366 }
367 447
368 evntsel = K7_EVNTSEL_INT 448 evntsel = K7_EVNTSEL_INT
369 | K7_EVNTSEL_OS 449 | K7_EVNTSEL_OS
370 | K7_EVNTSEL_USR 450 | K7_EVNTSEL_USR
371 | K7_NMI_EVENT; 451 | K7_NMI_EVENT;
372 452
373 wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); 453 /* setup the timer */
374 wrmsrl(MSR_K7_PERFCTR0, -((u64)cpu_khz * 1000 / nmi_hz)); 454 wrmsr(evntsel_msr, evntsel, 0);
455 wrmsrl(perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz));
375 apic_write(APIC_LVTPC, APIC_DM_NMI); 456 apic_write(APIC_LVTPC, APIC_DM_NMI);
376 evntsel |= K7_EVNTSEL_ENABLE; 457 evntsel |= K7_EVNTSEL_ENABLE;
377 wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); 458 wrmsr(evntsel_msr, evntsel, 0);
459
460 wd->perfctr_msr = perfctr_msr;
461 wd->evntsel_msr = evntsel_msr;
462 wd->cccr_msr = 0; //unused
463 wd->check_bit = 1ULL<<63;
464 return 1;
465fail2:
466 release_evntsel_nmi(evntsel_msr);
467fail1:
468 release_perfctr_nmi(perfctr_msr);
469fail:
470 return 0;
378} 471}
379 472
380static void disable_intel_arch_watchdog(void) 473static void stop_k7_watchdog(void)
381{ 474{
382 unsigned ebx; 475 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
383 476
384 /* 477 wrmsr(wd->evntsel_msr, 0, 0);
385 * Check whether the Architectural PerfMon supports 478
386 * Unhalted Core Cycles Event or not. 479 release_evntsel_nmi(wd->evntsel_msr);
387 * NOTE: Corresponding bit = 0 in ebp indicates event present. 480 release_perfctr_nmi(wd->perfctr_msr);
481}
482
483/* Note that these events don't tick when the CPU idles. This means
484 the frequency varies with CPU load. */
485
486#define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7)
487#define P4_ESCR_EVENT_SELECT(N) ((N)<<25)
488#define P4_ESCR_OS (1<<3)
489#define P4_ESCR_USR (1<<2)
490#define P4_CCCR_OVF_PMI0 (1<<26)
491#define P4_CCCR_OVF_PMI1 (1<<27)
492#define P4_CCCR_THRESHOLD(N) ((N)<<20)
493#define P4_CCCR_COMPLEMENT (1<<19)
494#define P4_CCCR_COMPARE (1<<18)
495#define P4_CCCR_REQUIRED (3<<16)
496#define P4_CCCR_ESCR_SELECT(N) ((N)<<13)
497#define P4_CCCR_ENABLE (1<<12)
498#define P4_CCCR_OVF (1<<31)
499/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter
500 CRU_ESCR0 (with any non-null event selector) through a complemented
501 max threshold. [IA32-Vol3, Section 14.9.9] */
502
503static int setup_p4_watchdog(void)
504{
505 unsigned int perfctr_msr, evntsel_msr, cccr_msr;
506 unsigned int evntsel, cccr_val;
507 unsigned int misc_enable, dummy;
508 unsigned int ht_num;
509 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
510
511 rdmsr(MSR_IA32_MISC_ENABLE, misc_enable, dummy);
512 if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL))
513 return 0;
514
515#ifdef CONFIG_SMP
516 /* detect which hyperthread we are on */
517 if (smp_num_siblings == 2) {
518 unsigned int ebx, apicid;
519
520 ebx = cpuid_ebx(1);
521 apicid = (ebx >> 24) & 0xff;
522 ht_num = apicid & 1;
523 } else
524#endif
525 ht_num = 0;
526
527 /* performance counters are shared resources
528 * assign each hyperthread its own set
529 * (re-use the ESCR0 register, seems safe
530 * and keeps the cccr_val the same)
388 */ 531 */
389 ebx = cpuid_ebx(10); 532 if (!ht_num) {
390 if (!(ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) 533 /* logical cpu 0 */
391 wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, 0, 0); 534 perfctr_msr = MSR_P4_IQ_PERFCTR0;
535 evntsel_msr = MSR_P4_CRU_ESCR0;
536 cccr_msr = MSR_P4_IQ_CCCR0;
537 cccr_val = P4_CCCR_OVF_PMI0 | P4_CCCR_ESCR_SELECT(4);
538 } else {
539 /* logical cpu 1 */
540 perfctr_msr = MSR_P4_IQ_PERFCTR1;
541 evntsel_msr = MSR_P4_CRU_ESCR0;
542 cccr_msr = MSR_P4_IQ_CCCR1;
543 cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4);
544 }
545
546 if (!reserve_perfctr_nmi(perfctr_msr))
547 goto fail;
548
549 if (!reserve_evntsel_nmi(evntsel_msr))
550 goto fail1;
551
552 evntsel = P4_ESCR_EVENT_SELECT(0x3F)
553 | P4_ESCR_OS
554 | P4_ESCR_USR;
555
556 cccr_val |= P4_CCCR_THRESHOLD(15)
557 | P4_CCCR_COMPLEMENT
558 | P4_CCCR_COMPARE
559 | P4_CCCR_REQUIRED;
560
561 wrmsr(evntsel_msr, evntsel, 0);
562 wrmsr(cccr_msr, cccr_val, 0);
563 wrmsrl(perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz));
564 apic_write(APIC_LVTPC, APIC_DM_NMI);
565 cccr_val |= P4_CCCR_ENABLE;
566 wrmsr(cccr_msr, cccr_val, 0);
567
568 wd->perfctr_msr = perfctr_msr;
569 wd->evntsel_msr = evntsel_msr;
570 wd->cccr_msr = cccr_msr;
571 wd->check_bit = 1ULL<<39;
572 return 1;
573fail1:
574 release_perfctr_nmi(perfctr_msr);
575fail:
576 return 0;
577}
578
579static void stop_p4_watchdog(void)
580{
581 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
582
583 wrmsr(wd->cccr_msr, 0, 0);
584 wrmsr(wd->evntsel_msr, 0, 0);
585
586 release_evntsel_nmi(wd->evntsel_msr);
587 release_perfctr_nmi(wd->perfctr_msr);
392} 588}
393 589
590#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL
591#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK
592
394static int setup_intel_arch_watchdog(void) 593static int setup_intel_arch_watchdog(void)
395{ 594{
595 unsigned int ebx;
596 union cpuid10_eax eax;
597 unsigned int unused;
598 unsigned int perfctr_msr, evntsel_msr;
396 unsigned int evntsel; 599 unsigned int evntsel;
397 unsigned ebx; 600 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
398 601
399 /* 602 /*
400 * Check whether the Architectural PerfMon supports 603 * Check whether the Architectural PerfMon supports
401 * Unhalted Core Cycles Event or not. 604 * Unhalted Core Cycles Event or not.
402 * NOTE: Corresponding bit = 0 in ebp indicates event present. 605 * NOTE: Corresponding bit = 0 in ebx indicates event present.
403 */ 606 */
404 ebx = cpuid_ebx(10); 607 cpuid(10, &(eax.full), &ebx, &unused, &unused);
405 if ((ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) 608 if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) ||
406 return 0; 609 (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT))
610 goto fail;
611
612 perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0;
613 evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL0;
407 614
408 nmi_perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; 615 if (!reserve_perfctr_nmi(perfctr_msr))
616 goto fail;
409 617
410 clear_msr_range(MSR_ARCH_PERFMON_EVENTSEL0, 2); 618 if (!reserve_evntsel_nmi(evntsel_msr))
411 clear_msr_range(MSR_ARCH_PERFMON_PERFCTR0, 2); 619 goto fail1;
620
621 wrmsrl(perfctr_msr, 0UL);
412 622
413 evntsel = ARCH_PERFMON_EVENTSEL_INT 623 evntsel = ARCH_PERFMON_EVENTSEL_INT
414 | ARCH_PERFMON_EVENTSEL_OS 624 | ARCH_PERFMON_EVENTSEL_OS
@@ -416,84 +626,122 @@ static int setup_intel_arch_watchdog(void)
416 | ARCH_PERFMON_NMI_EVENT_SEL 626 | ARCH_PERFMON_NMI_EVENT_SEL
417 | ARCH_PERFMON_NMI_EVENT_UMASK; 627 | ARCH_PERFMON_NMI_EVENT_UMASK;
418 628
419 wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0); 629 /* setup the timer */
420 wrmsrl(MSR_ARCH_PERFMON_PERFCTR0, -((u64)cpu_khz * 1000 / nmi_hz)); 630 wrmsr(evntsel_msr, evntsel, 0);
631 wrmsrl(perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz));
632
421 apic_write(APIC_LVTPC, APIC_DM_NMI); 633 apic_write(APIC_LVTPC, APIC_DM_NMI);
422 evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE; 634 evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE;
423 wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0); 635 wrmsr(evntsel_msr, evntsel, 0);
636
637 wd->perfctr_msr = perfctr_msr;
638 wd->evntsel_msr = evntsel_msr;
639 wd->cccr_msr = 0; //unused
640 wd->check_bit = 1ULL << (eax.split.bit_width - 1);
424 return 1; 641 return 1;
642fail1:
643 release_perfctr_nmi(perfctr_msr);
644fail:
645 return 0;
425} 646}
426 647
427 648static void stop_intel_arch_watchdog(void)
428static int setup_p4_watchdog(void)
429{ 649{
430 unsigned int misc_enable, dummy; 650 unsigned int ebx;
651 union cpuid10_eax eax;
652 unsigned int unused;
653 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
431 654
432 rdmsr(MSR_P4_MISC_ENABLE, misc_enable, dummy); 655 /*
433 if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL)) 656 * Check whether the Architectural PerfMon supports
434 return 0; 657 * Unhalted Core Cycles Event or not.
658 * NOTE: Corresponding bit = 0 in ebx indicates event present.
659 */
660 cpuid(10, &(eax.full), &ebx, &unused, &unused);
661 if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) ||
662 (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT))
663 return;
435 664
436 nmi_perfctr_msr = MSR_P4_IQ_COUNTER0; 665 wrmsr(wd->evntsel_msr, 0, 0);
437 nmi_p4_cccr_val = P4_NMI_IQ_CCCR0;
438#ifdef CONFIG_SMP
439 if (smp_num_siblings == 2)
440 nmi_p4_cccr_val |= P4_CCCR_OVF_PMI1;
441#endif
442 666
443 if (!(misc_enable & MSR_P4_MISC_ENABLE_PEBS_UNAVAIL)) 667 release_evntsel_nmi(wd->evntsel_msr);
444 clear_msr_range(0x3F1, 2); 668 release_perfctr_nmi(wd->perfctr_msr);
445 /* MSR 0x3F0 seems to have a default value of 0xFC00, but current
446 docs doesn't fully define it, so leave it alone for now. */
447 if (boot_cpu_data.x86_model >= 0x3) {
448 /* MSR_P4_IQ_ESCR0/1 (0x3ba/0x3bb) removed */
449 clear_msr_range(0x3A0, 26);
450 clear_msr_range(0x3BC, 3);
451 } else {
452 clear_msr_range(0x3A0, 31);
453 }
454 clear_msr_range(0x3C0, 6);
455 clear_msr_range(0x3C8, 6);
456 clear_msr_range(0x3E0, 2);
457 clear_msr_range(MSR_P4_CCCR0, 18);
458 clear_msr_range(MSR_P4_PERFCTR0, 18);
459
460 wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0);
461 wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 0);
462 Dprintk("setting P4_IQ_COUNTER0 to 0x%08lx\n", -(cpu_khz * 1000UL / nmi_hz));
463 wrmsrl(MSR_P4_IQ_COUNTER0, -((u64)cpu_khz * 1000 / nmi_hz));
464 apic_write(APIC_LVTPC, APIC_DM_NMI);
465 wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0);
466 return 1;
467} 669}
468 670
469void setup_apic_nmi_watchdog(void) 671void setup_apic_nmi_watchdog(void *unused)
470{ 672{
471 switch (boot_cpu_data.x86_vendor) { 673 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
472 case X86_VENDOR_AMD: 674
473 if (boot_cpu_data.x86 != 15) 675 /* only support LOCAL and IO APICs for now */
474 return; 676 if ((nmi_watchdog != NMI_LOCAL_APIC) &&
475 if (strstr(boot_cpu_data.x86_model_id, "Screwdriver")) 677 (nmi_watchdog != NMI_IO_APIC))
476 return; 678 return;
477 setup_k7_watchdog(); 679
478 break; 680 if (wd->enabled == 1)
479 case X86_VENDOR_INTEL: 681 return;
480 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { 682
481 if (!setup_intel_arch_watchdog()) 683 /* cheap hack to support suspend/resume */
684 /* if cpu0 is not active neither should the other cpus */
685 if ((smp_processor_id() != 0) && (atomic_read(&nmi_active) <= 0))
686 return;
687
688 if (nmi_watchdog == NMI_LOCAL_APIC) {
689 switch (boot_cpu_data.x86_vendor) {
690 case X86_VENDOR_AMD:
691 if (strstr(boot_cpu_data.x86_model_id, "Screwdriver"))
482 return; 692 return;
483 } else if (boot_cpu_data.x86 == 15) { 693 if (!setup_k7_watchdog())
694 return;
695 break;
696 case X86_VENDOR_INTEL:
697 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
698 if (!setup_intel_arch_watchdog())
699 return;
700 break;
701 }
484 if (!setup_p4_watchdog()) 702 if (!setup_p4_watchdog())
485 return; 703 return;
486 } else { 704 break;
705 default:
487 return; 706 return;
488 } 707 }
708 }
709 wd->enabled = 1;
710 atomic_inc(&nmi_active);
711}
712
713void stop_apic_nmi_watchdog(void *unused)
714{
715 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
489 716
490 break; 717 /* only support LOCAL and IO APICs for now */
718 if ((nmi_watchdog != NMI_LOCAL_APIC) &&
719 (nmi_watchdog != NMI_IO_APIC))
720 return;
491 721
492 default: 722 if (wd->enabled == 0)
493 return; 723 return;
724
725 if (nmi_watchdog == NMI_LOCAL_APIC) {
726 switch (boot_cpu_data.x86_vendor) {
727 case X86_VENDOR_AMD:
728 if (strstr(boot_cpu_data.x86_model_id, "Screwdriver"))
729 return;
730 stop_k7_watchdog();
731 break;
732 case X86_VENDOR_INTEL:
733 if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
734 stop_intel_arch_watchdog();
735 break;
736 }
737 stop_p4_watchdog();
738 break;
739 default:
740 return;
741 }
494 } 742 }
495 lapic_nmi_owner = LAPIC_NMI_WATCHDOG; 743 wd->enabled = 0;
496 nmi_active = 1; 744 atomic_dec(&nmi_active);
497} 745}
498 746
499/* 747/*
@@ -526,93 +774,109 @@ void touch_nmi_watchdog (void)
526 touch_softlockup_watchdog(); 774 touch_softlockup_watchdog();
527} 775}
528 776
529void __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) 777int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
530{ 778{
531 int sum; 779 int sum;
532 int touched = 0; 780 int touched = 0;
781 struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
782 u64 dummy;
783 int rc=0;
784
785 /* check for other users first */
786 if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT)
787 == NOTIFY_STOP) {
788 rc = 1;
789 touched = 1;
790 }
533 791
534 sum = read_pda(apic_timer_irqs); 792 sum = read_pda(apic_timer_irqs);
535 if (__get_cpu_var(nmi_touch)) { 793 if (__get_cpu_var(nmi_touch)) {
536 __get_cpu_var(nmi_touch) = 0; 794 __get_cpu_var(nmi_touch) = 0;
537 touched = 1; 795 touched = 1;
538 } 796 }
797
539#ifdef CONFIG_X86_MCE 798#ifdef CONFIG_X86_MCE
540 /* Could check oops_in_progress here too, but it's safer 799 /* Could check oops_in_progress here too, but it's safer
541 not too */ 800 not too */
542 if (atomic_read(&mce_entry) > 0) 801 if (atomic_read(&mce_entry) > 0)
543 touched = 1; 802 touched = 1;
544#endif 803#endif
804 /* if the apic timer isn't firing, this cpu isn't doing much */
545 if (!touched && __get_cpu_var(last_irq_sum) == sum) { 805 if (!touched && __get_cpu_var(last_irq_sum) == sum) {
546 /* 806 /*
547 * Ayiee, looks like this CPU is stuck ... 807 * Ayiee, looks like this CPU is stuck ...
548 * wait a few IRQs (5 seconds) before doing the oops ... 808 * wait a few IRQs (5 seconds) before doing the oops ...
549 */ 809 */
550 local_inc(&__get_cpu_var(alert_counter)); 810 local_inc(&__get_cpu_var(alert_counter));
551 if (local_read(&__get_cpu_var(alert_counter)) == 5*nmi_hz) { 811 if (local_read(&__get_cpu_var(alert_counter)) == 5*nmi_hz)
552 if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) 812 die_nmi("NMI Watchdog detected LOCKUP on CPU %d\n", regs,
553 == NOTIFY_STOP) { 813 panic_on_timeout);
554 local_set(&__get_cpu_var(alert_counter), 0);
555 return;
556 }
557 die_nmi("NMI Watchdog detected LOCKUP on CPU %d\n", regs);
558 }
559 } else { 814 } else {
560 __get_cpu_var(last_irq_sum) = sum; 815 __get_cpu_var(last_irq_sum) = sum;
561 local_set(&__get_cpu_var(alert_counter), 0); 816 local_set(&__get_cpu_var(alert_counter), 0);
562 } 817 }
563 if (nmi_perfctr_msr) { 818
564 if (nmi_perfctr_msr == MSR_P4_IQ_COUNTER0) { 819 /* see if the nmi watchdog went off */
565 /* 820 if (wd->enabled) {
566 * P4 quirks: 821 if (nmi_watchdog == NMI_LOCAL_APIC) {
567 * - An overflown perfctr will assert its interrupt 822 rdmsrl(wd->perfctr_msr, dummy);
568 * until the OVF flag in its CCCR is cleared. 823 if (dummy & wd->check_bit){
569 * - LVTPC is masked on interrupt and must be 824 /* this wasn't a watchdog timer interrupt */
570 * unmasked by the LVTPC handler. 825 goto done;
571 */ 826 }
572 wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); 827
573 apic_write(APIC_LVTPC, APIC_DM_NMI); 828 /* only Intel uses the cccr msr */
574 } else if (nmi_perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) { 829 if (wd->cccr_msr != 0) {
575 /* 830 /*
576 * For Intel based architectural perfmon 831 * P4 quirks:
577 * - LVTPC is masked on interrupt and must be 832 * - An overflown perfctr will assert its interrupt
578 * unmasked by the LVTPC handler. 833 * until the OVF flag in its CCCR is cleared.
834 * - LVTPC is masked on interrupt and must be
835 * unmasked by the LVTPC handler.
836 */
837 rdmsrl(wd->cccr_msr, dummy);
838 dummy &= ~P4_CCCR_OVF;
839 wrmsrl(wd->cccr_msr, dummy);
840 apic_write(APIC_LVTPC, APIC_DM_NMI);
841 } else if (wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) {
842 /*
843 * ArchPerfom/Core Duo needs to re-unmask
844 * the apic vector
845 */
846 apic_write(APIC_LVTPC, APIC_DM_NMI);
847 }
848 /* start the cycle over again */
849 wrmsrl(wd->perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz));
850 rc = 1;
851 } else if (nmi_watchdog == NMI_IO_APIC) {
852 /* don't know how to accurately check for this.
853 * just assume it was a watchdog timer interrupt
854 * This matches the old behaviour.
579 */ 855 */
580 apic_write(APIC_LVTPC, APIC_DM_NMI); 856 rc = 1;
581 } 857 } else
582 wrmsrl(nmi_perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz)); 858 printk(KERN_WARNING "Unknown enabled NMI hardware?!\n");
583 } 859 }
860done:
861 return rc;
584} 862}
585 863
586static __kprobes int dummy_nmi_callback(struct pt_regs * regs, int cpu)
587{
588 return 0;
589}
590
591static nmi_callback_t nmi_callback = dummy_nmi_callback;
592
593asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code) 864asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code)
594{ 865{
595 int cpu = safe_smp_processor_id();
596
597 nmi_enter(); 866 nmi_enter();
598 add_pda(__nmi_count,1); 867 add_pda(__nmi_count,1);
599 if (!rcu_dereference(nmi_callback)(regs, cpu)) 868 default_do_nmi(regs);
600 default_do_nmi(regs);
601 nmi_exit(); 869 nmi_exit();
602} 870}
603 871
604void set_nmi_callback(nmi_callback_t callback) 872int do_nmi_callback(struct pt_regs * regs, int cpu)
605{ 873{
606 vmalloc_sync_all(); 874#ifdef CONFIG_SYSCTL
607 rcu_assign_pointer(nmi_callback, callback); 875 if (unknown_nmi_panic)
608} 876 return unknown_nmi_panic_callback(regs, cpu);
609EXPORT_SYMBOL_GPL(set_nmi_callback); 877#endif
610 878 return 0;
611void unset_nmi_callback(void)
612{
613 nmi_callback = dummy_nmi_callback;
614} 879}
615EXPORT_SYMBOL_GPL(unset_nmi_callback);
616 880
617#ifdef CONFIG_SYSCTL 881#ifdef CONFIG_SYSCTL
618 882
@@ -621,36 +885,42 @@ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu)
621 unsigned char reason = get_nmi_reason(); 885 unsigned char reason = get_nmi_reason();
622 char buf[64]; 886 char buf[64];
623 887
624 if (!(reason & 0xc0)) { 888 sprintf(buf, "NMI received for unknown reason %02x\n", reason);
625 sprintf(buf, "NMI received for unknown reason %02x\n", reason); 889 die_nmi(buf, regs, 1); /* Always panic here */
626 die_nmi(buf,regs);
627 }
628 return 0; 890 return 0;
629} 891}
630 892
631/* 893/*
632 * proc handler for /proc/sys/kernel/unknown_nmi_panic 894 * proc handler for /proc/sys/kernel/nmi
633 */ 895 */
634int proc_unknown_nmi_panic(struct ctl_table *table, int write, struct file *file, 896int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file,
635 void __user *buffer, size_t *length, loff_t *ppos) 897 void __user *buffer, size_t *length, loff_t *ppos)
636{ 898{
637 int old_state; 899 int old_state;
638 900
639 old_state = unknown_nmi_panic; 901 nmi_watchdog_enabled = (atomic_read(&nmi_active) > 0) ? 1 : 0;
902 old_state = nmi_watchdog_enabled;
640 proc_dointvec(table, write, file, buffer, length, ppos); 903 proc_dointvec(table, write, file, buffer, length, ppos);
641 if (!!old_state == !!unknown_nmi_panic) 904 if (!!old_state == !!nmi_watchdog_enabled)
642 return 0; 905 return 0;
643 906
644 if (unknown_nmi_panic) { 907 if (atomic_read(&nmi_active) < 0) {
645 if (reserve_lapic_nmi() < 0) { 908 printk( KERN_WARNING "NMI watchdog is permanently disabled\n");
646 unknown_nmi_panic = 0; 909 return -EIO;
647 return -EBUSY; 910 }
648 } else { 911
649 set_nmi_callback(unknown_nmi_panic_callback); 912 /* if nmi_watchdog is not set yet, then set it */
650 } 913 nmi_watchdog_default();
914
915 if (nmi_watchdog == NMI_LOCAL_APIC) {
916 if (nmi_watchdog_enabled)
917 enable_lapic_nmi_watchdog();
918 else
919 disable_lapic_nmi_watchdog();
651 } else { 920 } else {
652 release_lapic_nmi(); 921 printk( KERN_WARNING
653 unset_nmi_callback(); 922 "NMI watchdog doesn't know what hardware to touch\n");
923 return -EIO;
654 } 924 }
655 return 0; 925 return 0;
656} 926}
@@ -659,8 +929,12 @@ int proc_unknown_nmi_panic(struct ctl_table *table, int write, struct file *file
659 929
660EXPORT_SYMBOL(nmi_active); 930EXPORT_SYMBOL(nmi_active);
661EXPORT_SYMBOL(nmi_watchdog); 931EXPORT_SYMBOL(nmi_watchdog);
662EXPORT_SYMBOL(reserve_lapic_nmi); 932EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi);
663EXPORT_SYMBOL(release_lapic_nmi); 933EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit);
934EXPORT_SYMBOL(reserve_perfctr_nmi);
935EXPORT_SYMBOL(release_perfctr_nmi);
936EXPORT_SYMBOL(reserve_evntsel_nmi);
937EXPORT_SYMBOL(release_evntsel_nmi);
664EXPORT_SYMBOL(disable_timer_nmi_watchdog); 938EXPORT_SYMBOL(disable_timer_nmi_watchdog);
665EXPORT_SYMBOL(enable_timer_nmi_watchdog); 939EXPORT_SYMBOL(enable_timer_nmi_watchdog);
666EXPORT_SYMBOL(touch_nmi_watchdog); 940EXPORT_SYMBOL(touch_nmi_watchdog);
diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c
index 146924ba5df5..cfb09b07ae99 100644
--- a/arch/x86_64/kernel/pci-calgary.c
+++ b/arch/x86_64/kernel/pci-calgary.c
@@ -86,7 +86,8 @@
86 86
87#define MAX_NUM_OF_PHBS 8 /* how many PHBs in total? */ 87#define MAX_NUM_OF_PHBS 8 /* how many PHBs in total? */
88#define MAX_NUM_CHASSIS 8 /* max number of chassis */ 88#define MAX_NUM_CHASSIS 8 /* max number of chassis */
89#define MAX_PHB_BUS_NUM (MAX_NUM_OF_PHBS * MAX_NUM_CHASSIS * 2) /* max dev->bus->number */ 89/* MAX_PHB_BUS_NUM is the maximal possible dev->bus->number */
90#define MAX_PHB_BUS_NUM (MAX_NUM_OF_PHBS * MAX_NUM_CHASSIS * 2)
90#define PHBS_PER_CALGARY 4 91#define PHBS_PER_CALGARY 4
91 92
92/* register offsets in Calgary's internal register space */ 93/* register offsets in Calgary's internal register space */
@@ -111,31 +112,49 @@ static const unsigned long phb_offsets[] = {
111 0xB000 /* PHB3 */ 112 0xB000 /* PHB3 */
112}; 113};
113 114
114static char bus_to_phb[MAX_PHB_BUS_NUM];
115void* tce_table_kva[MAX_PHB_BUS_NUM];
116unsigned int specified_table_size = TCE_TABLE_SIZE_UNSPECIFIED; 115unsigned int specified_table_size = TCE_TABLE_SIZE_UNSPECIFIED;
117static int translate_empty_slots __read_mostly = 0; 116static int translate_empty_slots __read_mostly = 0;
118static int calgary_detected __read_mostly = 0; 117static int calgary_detected __read_mostly = 0;
119 118
120/* 119struct calgary_bus_info {
121 * the bitmap of PHBs the user requested that we disable 120 void *tce_space;
122 * translation on. 121 unsigned char translation_disabled;
123 */ 122 signed char phbid;
124static DECLARE_BITMAP(translation_disabled, MAX_PHB_BUS_NUM); 123};
124
125static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, };
125 126
126static void tce_cache_blast(struct iommu_table *tbl); 127static void tce_cache_blast(struct iommu_table *tbl);
127 128
128/* enable this to stress test the chip's TCE cache */ 129/* enable this to stress test the chip's TCE cache */
129#ifdef CONFIG_IOMMU_DEBUG 130#ifdef CONFIG_IOMMU_DEBUG
130static inline void tce_cache_blast_stress(struct iommu_table *tbl) 131int debugging __read_mostly = 1;
132
133static inline unsigned long verify_bit_range(unsigned long* bitmap,
134 int expected, unsigned long start, unsigned long end)
131{ 135{
132 tce_cache_blast(tbl); 136 unsigned long idx = start;
137
138 BUG_ON(start >= end);
139
140 while (idx < end) {
141 if (!!test_bit(idx, bitmap) != expected)
142 return idx;
143 ++idx;
144 }
145
146 /* all bits have the expected value */
147 return ~0UL;
133} 148}
134#else 149#else /* debugging is disabled */
135static inline void tce_cache_blast_stress(struct iommu_table *tbl) 150int debugging __read_mostly = 0;
151
152static inline unsigned long verify_bit_range(unsigned long* bitmap,
153 int expected, unsigned long start, unsigned long end)
136{ 154{
155 return ~0UL;
137} 156}
138#endif /* BLAST_TCE_CACHE_ON_UNMAP */ 157#endif /* CONFIG_IOMMU_DEBUG */
139 158
140static inline unsigned int num_dma_pages(unsigned long dma, unsigned int dmalen) 159static inline unsigned int num_dma_pages(unsigned long dma, unsigned int dmalen)
141{ 160{
@@ -149,7 +168,7 @@ static inline unsigned int num_dma_pages(unsigned long dma, unsigned int dmalen)
149 168
150static inline int translate_phb(struct pci_dev* dev) 169static inline int translate_phb(struct pci_dev* dev)
151{ 170{
152 int disabled = test_bit(dev->bus->number, translation_disabled); 171 int disabled = bus_info[dev->bus->number].translation_disabled;
153 return !disabled; 172 return !disabled;
154} 173}
155 174
@@ -158,6 +177,7 @@ static void iommu_range_reserve(struct iommu_table *tbl,
158{ 177{
159 unsigned long index; 178 unsigned long index;
160 unsigned long end; 179 unsigned long end;
180 unsigned long badbit;
161 181
162 index = start_addr >> PAGE_SHIFT; 182 index = start_addr >> PAGE_SHIFT;
163 183
@@ -169,14 +189,15 @@ static void iommu_range_reserve(struct iommu_table *tbl,
169 if (end > tbl->it_size) /* don't go off the table */ 189 if (end > tbl->it_size) /* don't go off the table */
170 end = tbl->it_size; 190 end = tbl->it_size;
171 191
172 while (index < end) { 192 badbit = verify_bit_range(tbl->it_map, 0, index, end);
173 if (test_bit(index, tbl->it_map)) 193 if (badbit != ~0UL) {
194 if (printk_ratelimit())
174 printk(KERN_ERR "Calgary: entry already allocated at " 195 printk(KERN_ERR "Calgary: entry already allocated at "
175 "0x%lx tbl %p dma 0x%lx npages %u\n", 196 "0x%lx tbl %p dma 0x%lx npages %u\n",
176 index, tbl, start_addr, npages); 197 badbit, tbl, start_addr, npages);
177 ++index;
178 } 198 }
179 set_bit_string(tbl->it_map, start_addr >> PAGE_SHIFT, npages); 199
200 set_bit_string(tbl->it_map, index, npages);
180} 201}
181 202
182static unsigned long iommu_range_alloc(struct iommu_table *tbl, 203static unsigned long iommu_range_alloc(struct iommu_table *tbl,
@@ -243,7 +264,7 @@ static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
243 unsigned int npages) 264 unsigned int npages)
244{ 265{
245 unsigned long entry; 266 unsigned long entry;
246 unsigned long i; 267 unsigned long badbit;
247 268
248 entry = dma_addr >> PAGE_SHIFT; 269 entry = dma_addr >> PAGE_SHIFT;
249 270
@@ -251,16 +272,15 @@ static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
251 272
252 tce_free(tbl, entry, npages); 273 tce_free(tbl, entry, npages);
253 274
254 for (i = 0; i < npages; ++i) { 275 badbit = verify_bit_range(tbl->it_map, 1, entry, entry + npages);
255 if (!test_bit(entry + i, tbl->it_map)) 276 if (badbit != ~0UL) {
277 if (printk_ratelimit())
256 printk(KERN_ERR "Calgary: bit is off at 0x%lx " 278 printk(KERN_ERR "Calgary: bit is off at 0x%lx "
257 "tbl %p dma 0x%Lx entry 0x%lx npages %u\n", 279 "tbl %p dma 0x%Lx entry 0x%lx npages %u\n",
258 entry + i, tbl, dma_addr, entry, npages); 280 badbit, tbl, dma_addr, entry, npages);
259 } 281 }
260 282
261 __clear_bit_string(tbl->it_map, entry, npages); 283 __clear_bit_string(tbl->it_map, entry, npages);
262
263 tce_cache_blast_stress(tbl);
264} 284}
265 285
266static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, 286static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
@@ -454,7 +474,7 @@ static struct dma_mapping_ops calgary_dma_ops = {
454 474
455static inline int busno_to_phbid(unsigned char num) 475static inline int busno_to_phbid(unsigned char num)
456{ 476{
457 return bus_to_phb[num]; 477 return bus_info[num].phbid;
458} 478}
459 479
460static inline unsigned long split_queue_offset(unsigned char num) 480static inline unsigned long split_queue_offset(unsigned char num)
@@ -631,6 +651,10 @@ static int __init calgary_setup_tar(struct pci_dev *dev, void __iomem *bbar)
631 if (ret) 651 if (ret)
632 return ret; 652 return ret;
633 653
654 tbl = dev->sysdata;
655 tbl->it_base = (unsigned long)bus_info[dev->bus->number].tce_space;
656 tce_free(tbl, 0, tbl->it_size);
657
634 calgary_reserve_regions(dev); 658 calgary_reserve_regions(dev);
635 659
636 /* set TARs for each PHB */ 660 /* set TARs for each PHB */
@@ -654,11 +678,12 @@ static int __init calgary_setup_tar(struct pci_dev *dev, void __iomem *bbar)
654 return 0; 678 return 0;
655} 679}
656 680
657static void __init calgary_free_tar(struct pci_dev *dev) 681static void __init calgary_free_bus(struct pci_dev *dev)
658{ 682{
659 u64 val64; 683 u64 val64;
660 struct iommu_table *tbl = dev->sysdata; 684 struct iommu_table *tbl = dev->sysdata;
661 void __iomem *target; 685 void __iomem *target;
686 unsigned int bitmapsz;
662 687
663 target = calgary_reg(tbl->bbar, tar_offset(dev->bus->number)); 688 target = calgary_reg(tbl->bbar, tar_offset(dev->bus->number));
664 val64 = be64_to_cpu(readq(target)); 689 val64 = be64_to_cpu(readq(target));
@@ -666,8 +691,15 @@ static void __init calgary_free_tar(struct pci_dev *dev)
666 writeq(cpu_to_be64(val64), target); 691 writeq(cpu_to_be64(val64), target);
667 readq(target); /* flush */ 692 readq(target); /* flush */
668 693
694 bitmapsz = tbl->it_size / BITS_PER_BYTE;
695 free_pages((unsigned long)tbl->it_map, get_order(bitmapsz));
696 tbl->it_map = NULL;
697
669 kfree(tbl); 698 kfree(tbl);
670 dev->sysdata = NULL; 699 dev->sysdata = NULL;
700
701 /* Can't free bootmem allocated memory after system is up :-( */
702 bus_info[dev->bus->number].tce_space = NULL;
671} 703}
672 704
673static void calgary_watchdog(unsigned long data) 705static void calgary_watchdog(unsigned long data)
@@ -772,12 +804,11 @@ static inline unsigned int __init locate_register_space(struct pci_dev *dev)
772 return address; 804 return address;
773} 805}
774 806
775static int __init calgary_init_one_nontraslated(struct pci_dev *dev) 807static void __init calgary_init_one_nontraslated(struct pci_dev *dev)
776{ 808{
809 pci_dev_get(dev);
777 dev->sysdata = NULL; 810 dev->sysdata = NULL;
778 dev->bus->self = dev; 811 dev->bus->self = dev;
779
780 return 0;
781} 812}
782 813
783static int __init calgary_init_one(struct pci_dev *dev) 814static int __init calgary_init_one(struct pci_dev *dev)
@@ -798,6 +829,7 @@ static int __init calgary_init_one(struct pci_dev *dev)
798 if (ret) 829 if (ret)
799 goto iounmap; 830 goto iounmap;
800 831
832 pci_dev_get(dev);
801 dev->bus->self = dev; 833 dev->bus->self = dev;
802 calgary_enable_translation(dev); 834 calgary_enable_translation(dev);
803 835
@@ -824,10 +856,9 @@ static int __init calgary_init(void)
824 calgary_init_one_nontraslated(dev); 856 calgary_init_one_nontraslated(dev);
825 continue; 857 continue;
826 } 858 }
827 if (!tce_table_kva[dev->bus->number] && !translate_empty_slots) { 859 if (!bus_info[dev->bus->number].tce_space && !translate_empty_slots)
828 pci_dev_put(dev);
829 continue; 860 continue;
830 } 861
831 ret = calgary_init_one(dev); 862 ret = calgary_init_one(dev);
832 if (ret) 863 if (ret)
833 goto error; 864 goto error;
@@ -840,15 +871,18 @@ error:
840 dev = pci_find_device_reverse(PCI_VENDOR_ID_IBM, 871 dev = pci_find_device_reverse(PCI_VENDOR_ID_IBM,
841 PCI_DEVICE_ID_IBM_CALGARY, 872 PCI_DEVICE_ID_IBM_CALGARY,
842 dev); 873 dev);
874 if (!dev)
875 break;
843 if (!translate_phb(dev)) { 876 if (!translate_phb(dev)) {
844 pci_dev_put(dev); 877 pci_dev_put(dev);
845 continue; 878 continue;
846 } 879 }
847 if (!tce_table_kva[dev->bus->number] && !translate_empty_slots) 880 if (!bus_info[dev->bus->number].tce_space && !translate_empty_slots)
848 continue; 881 continue;
882
849 calgary_disable_translation(dev); 883 calgary_disable_translation(dev);
850 calgary_free_tar(dev); 884 calgary_free_bus(dev);
851 pci_dev_put(dev); 885 pci_dev_put(dev); /* Undo calgary_init_one()'s pci_dev_get() */
852 } 886 }
853 887
854 return ret; 888 return ret;
@@ -890,13 +924,15 @@ void __init detect_calgary(void)
890 if (swiotlb || no_iommu || iommu_detected) 924 if (swiotlb || no_iommu || iommu_detected)
891 return; 925 return;
892 926
927 if (!early_pci_allowed())
928 return;
929
893 specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE); 930 specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE);
894 931
895 for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) { 932 for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) {
896 int dev; 933 int dev;
897 934 struct calgary_bus_info *info = &bus_info[bus];
898 tce_table_kva[bus] = NULL; 935 info->phbid = -1;
899 bus_to_phb[bus] = -1;
900 936
901 if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY) 937 if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY)
902 continue; 938 continue;
@@ -907,12 +943,9 @@ void __init detect_calgary(void)
907 */ 943 */
908 phb = (phb + 1) % PHBS_PER_CALGARY; 944 phb = (phb + 1) % PHBS_PER_CALGARY;
909 945
910 if (test_bit(bus, translation_disabled)) { 946 if (info->translation_disabled)
911 printk(KERN_INFO "Calgary: translation is disabled for "
912 "PHB 0x%x\n", bus);
913 /* skip this phb, don't allocate a tbl for it */
914 continue; 947 continue;
915 } 948
916 /* 949 /*
917 * Scan the slots of the PCI bus to see if there is a device present. 950 * Scan the slots of the PCI bus to see if there is a device present.
918 * The parent bus will be the zero-ith device, so start at 1. 951 * The parent bus will be the zero-ith device, so start at 1.
@@ -923,8 +956,8 @@ void __init detect_calgary(void)
923 tbl = alloc_tce_table(); 956 tbl = alloc_tce_table();
924 if (!tbl) 957 if (!tbl)
925 goto cleanup; 958 goto cleanup;
926 tce_table_kva[bus] = tbl; 959 info->tce_space = tbl;
927 bus_to_phb[bus] = phb; 960 info->phbid = phb;
928 calgary_found = 1; 961 calgary_found = 1;
929 break; 962 break;
930 } 963 }
@@ -934,15 +967,20 @@ void __init detect_calgary(void)
934 if (calgary_found) { 967 if (calgary_found) {
935 iommu_detected = 1; 968 iommu_detected = 1;
936 calgary_detected = 1; 969 calgary_detected = 1;
937 printk(KERN_INFO "PCI-DMA: Calgary IOMMU detected. " 970 printk(KERN_INFO "PCI-DMA: Calgary IOMMU detected.\n");
938 "TCE table spec is %d.\n", specified_table_size); 971 printk(KERN_INFO "PCI-DMA: Calgary TCE table spec is %d, "
972 "CONFIG_IOMMU_DEBUG is %s.\n", specified_table_size,
973 debugging ? "enabled" : "disabled");
939 } 974 }
940 return; 975 return;
941 976
942cleanup: 977cleanup:
943 for (--bus; bus >= 0; --bus) 978 for (--bus; bus >= 0; --bus) {
944 if (tce_table_kva[bus]) 979 struct calgary_bus_info *info = &bus_info[bus];
945 free_tce_table(tce_table_kva[bus]); 980
981 if (info->tce_space)
982 free_tce_table(info->tce_space);
983 }
946} 984}
947 985
948int __init calgary_iommu_init(void) 986int __init calgary_iommu_init(void)
@@ -1016,7 +1054,7 @@ static int __init calgary_parse_options(char *p)
1016 if (bridge < MAX_PHB_BUS_NUM) { 1054 if (bridge < MAX_PHB_BUS_NUM) {
1017 printk(KERN_INFO "Calgary: disabling " 1055 printk(KERN_INFO "Calgary: disabling "
1018 "translation for PHB 0x%x\n", bridge); 1056 "translation for PHB 0x%x\n", bridge);
1019 set_bit(bridge, translation_disabled); 1057 bus_info[bridge].translation_disabled = 1;
1020 } 1058 }
1021 } 1059 }
1022 1060
diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c
index 9c44f4f2433d..4dcb671bd19f 100644
--- a/arch/x86_64/kernel/pci-dma.c
+++ b/arch/x86_64/kernel/pci-dma.c
@@ -236,6 +236,9 @@ __init int iommu_setup(char *p)
236{ 236{
237 iommu_merge = 1; 237 iommu_merge = 1;
238 238
239 if (!p)
240 return -EINVAL;
241
239 while (*p) { 242 while (*p) {
240 if (!strncmp(p,"off",3)) 243 if (!strncmp(p,"off",3))
241 no_iommu = 1; 244 no_iommu = 1;
@@ -278,9 +281,9 @@ __init int iommu_setup(char *p)
278 if (*p == ',') 281 if (*p == ',')
279 ++p; 282 ++p;
280 } 283 }
281 return 1; 284 return 0;
282} 285}
283__setup("iommu=", iommu_setup); 286early_param("iommu", iommu_setup);
284 287
285void __init pci_iommu_alloc(void) 288void __init pci_iommu_alloc(void)
286{ 289{
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c
index 6d3e61baf7a0..16261a8a3303 100644
--- a/arch/x86_64/kernel/pci-gart.c
+++ b/arch/x86_64/kernel/pci-gart.c
@@ -239,8 +239,6 @@ dma_addr_t gart_map_single(struct device *dev, void *addr, size_t size, int dir)
239{ 239{
240 unsigned long phys_mem, bus; 240 unsigned long phys_mem, bus;
241 241
242 BUG_ON(dir == DMA_NONE);
243
244 if (!dev) 242 if (!dev)
245 dev = &fallback_dev; 243 dev = &fallback_dev;
246 244
@@ -383,7 +381,6 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
383 unsigned long pages = 0; 381 unsigned long pages = 0;
384 int need = 0, nextneed; 382 int need = 0, nextneed;
385 383
386 BUG_ON(dir == DMA_NONE);
387 if (nents == 0) 384 if (nents == 0)
388 return 0; 385 return 0;
389 386
diff --git a/arch/x86_64/kernel/pci-nommu.c b/arch/x86_64/kernel/pci-nommu.c
index aad7609d8e92..df09ab05a1bd 100644
--- a/arch/x86_64/kernel/pci-nommu.c
+++ b/arch/x86_64/kernel/pci-nommu.c
@@ -59,7 +59,6 @@ int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
59{ 59{
60 int i; 60 int i;
61 61
62 BUG_ON(direction == DMA_NONE);
63 for (i = 0; i < nents; i++ ) { 62 for (i = 0; i < nents; i++ ) {
64 struct scatterlist *s = &sg[i]; 63 struct scatterlist *s = &sg[i];
65 BUG_ON(!s->page); 64 BUG_ON(!s->page);
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index bb6745d13b8f..458006ae19f3 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -80,25 +80,25 @@ void idle_notifier_unregister(struct notifier_block *n)
80} 80}
81EXPORT_SYMBOL(idle_notifier_unregister); 81EXPORT_SYMBOL(idle_notifier_unregister);
82 82
83enum idle_state { CPU_IDLE, CPU_NOT_IDLE };
84static DEFINE_PER_CPU(enum idle_state, idle_state) = CPU_NOT_IDLE;
85
86void enter_idle(void) 83void enter_idle(void)
87{ 84{
88 __get_cpu_var(idle_state) = CPU_IDLE; 85 write_pda(isidle, 1);
89 atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL); 86 atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL);
90} 87}
91 88
92static void __exit_idle(void) 89static void __exit_idle(void)
93{ 90{
94 __get_cpu_var(idle_state) = CPU_NOT_IDLE; 91 if (read_pda(isidle) == 0)
92 return;
93 write_pda(isidle, 0);
95 atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL); 94 atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL);
96} 95}
97 96
98/* Called from interrupts to signify idle end */ 97/* Called from interrupts to signify idle end */
99void exit_idle(void) 98void exit_idle(void)
100{ 99{
101 if (current->pid | read_pda(irqcount)) 100 /* idle loop has pid 0 */
101 if (current->pid)
102 return; 102 return;
103 __exit_idle(); 103 __exit_idle();
104} 104}
@@ -220,6 +220,9 @@ void cpu_idle (void)
220 play_dead(); 220 play_dead();
221 enter_idle(); 221 enter_idle();
222 idle(); 222 idle();
223 /* In many cases the interrupt that ended idle
224 has already called exit_idle. But some idle
225 loops can be woken up without interrupt. */
223 __exit_idle(); 226 __exit_idle();
224 } 227 }
225 228
@@ -350,6 +353,7 @@ void exit_thread(void)
350 353
351 kfree(t->io_bitmap_ptr); 354 kfree(t->io_bitmap_ptr);
352 t->io_bitmap_ptr = NULL; 355 t->io_bitmap_ptr = NULL;
356 clear_thread_flag(TIF_IO_BITMAP);
353 /* 357 /*
354 * Careful, clear this in the TSS too: 358 * Careful, clear this in the TSS too:
355 */ 359 */
@@ -369,6 +373,7 @@ void flush_thread(void)
369 if (t->flags & _TIF_IA32) 373 if (t->flags & _TIF_IA32)
370 current_thread_info()->status |= TS_COMPAT; 374 current_thread_info()->status |= TS_COMPAT;
371 } 375 }
376 t->flags &= ~_TIF_DEBUG;
372 377
373 tsk->thread.debugreg0 = 0; 378 tsk->thread.debugreg0 = 0;
374 tsk->thread.debugreg1 = 0; 379 tsk->thread.debugreg1 = 0;
@@ -461,7 +466,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp,
461 asm("mov %%es,%0" : "=m" (p->thread.es)); 466 asm("mov %%es,%0" : "=m" (p->thread.es));
462 asm("mov %%ds,%0" : "=m" (p->thread.ds)); 467 asm("mov %%ds,%0" : "=m" (p->thread.ds));
463 468
464 if (unlikely(me->thread.io_bitmap_ptr != NULL)) { 469 if (unlikely(test_tsk_thread_flag(me, TIF_IO_BITMAP))) {
465 p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); 470 p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
466 if (!p->thread.io_bitmap_ptr) { 471 if (!p->thread.io_bitmap_ptr) {
467 p->thread.io_bitmap_max = 0; 472 p->thread.io_bitmap_max = 0;
@@ -469,6 +474,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp,
469 } 474 }
470 memcpy(p->thread.io_bitmap_ptr, me->thread.io_bitmap_ptr, 475 memcpy(p->thread.io_bitmap_ptr, me->thread.io_bitmap_ptr,
471 IO_BITMAP_BYTES); 476 IO_BITMAP_BYTES);
477 set_tsk_thread_flag(p, TIF_IO_BITMAP);
472 } 478 }
473 479
474 /* 480 /*
@@ -498,6 +504,40 @@ out:
498 */ 504 */
499#define loaddebug(thread,r) set_debugreg(thread->debugreg ## r, r) 505#define loaddebug(thread,r) set_debugreg(thread->debugreg ## r, r)
500 506
507static inline void __switch_to_xtra(struct task_struct *prev_p,
508 struct task_struct *next_p,
509 struct tss_struct *tss)
510{
511 struct thread_struct *prev, *next;
512
513 prev = &prev_p->thread,
514 next = &next_p->thread;
515
516 if (test_tsk_thread_flag(next_p, TIF_DEBUG)) {
517 loaddebug(next, 0);
518 loaddebug(next, 1);
519 loaddebug(next, 2);
520 loaddebug(next, 3);
521 /* no 4 and 5 */
522 loaddebug(next, 6);
523 loaddebug(next, 7);
524 }
525
526 if (test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) {
527 /*
528 * Copy the relevant range of the IO bitmap.
529 * Normally this is 128 bytes or less:
530 */
531 memcpy(tss->io_bitmap, next->io_bitmap_ptr,
532 max(prev->io_bitmap_max, next->io_bitmap_max));
533 } else if (test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) {
534 /*
535 * Clear any possible leftover bits:
536 */
537 memset(tss->io_bitmap, 0xff, prev->io_bitmap_max);
538 }
539}
540
501/* 541/*
502 * switch_to(x,y) should switch tasks from x to y. 542 * switch_to(x,y) should switch tasks from x to y.
503 * 543 *
@@ -515,6 +555,10 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
515 int cpu = smp_processor_id(); 555 int cpu = smp_processor_id();
516 struct tss_struct *tss = &per_cpu(init_tss, cpu); 556 struct tss_struct *tss = &per_cpu(init_tss, cpu);
517 557
558 /* we're going to use this soon, after a few expensive things */
559 if (next_p->fpu_counter>5)
560 prefetch(&next->i387.fxsave);
561
518 /* 562 /*
519 * Reload esp0, LDT and the page table pointer: 563 * Reload esp0, LDT and the page table pointer:
520 */ 564 */
@@ -583,41 +627,29 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
583 And the AMD workaround requires it to be after DS reload. */ 627 And the AMD workaround requires it to be after DS reload. */
584 unlazy_fpu(prev_p); 628 unlazy_fpu(prev_p);
585 write_pda(kernelstack, 629 write_pda(kernelstack,
586 task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET); 630 (unsigned long)task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
587 631#ifdef CONFIG_CC_STACKPROTECTOR
632 write_pda(stack_canary, next_p->stack_canary);
588 /* 633 /*
589 * Now maybe reload the debug registers 634 * Build time only check to make sure the stack_canary is at
635 * offset 40 in the pda; this is a gcc ABI requirement
590 */ 636 */
591 if (unlikely(next->debugreg7)) { 637 BUILD_BUG_ON(offsetof(struct x8664_pda, stack_canary) != 40);
592 loaddebug(next, 0); 638#endif
593 loaddebug(next, 1);
594 loaddebug(next, 2);
595 loaddebug(next, 3);
596 /* no 4 and 5 */
597 loaddebug(next, 6);
598 loaddebug(next, 7);
599 }
600
601 639
602 /* 640 /*
603 * Handle the IO bitmap 641 * Now maybe reload the debug registers and handle I/O bitmaps
604 */ 642 */
605 if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) { 643 if (unlikely((task_thread_info(next_p)->flags & _TIF_WORK_CTXSW))
606 if (next->io_bitmap_ptr) 644 || test_tsk_thread_flag(prev_p, TIF_IO_BITMAP))
607 /* 645 __switch_to_xtra(prev_p, next_p, tss);
608 * Copy the relevant range of the IO bitmap.
609 * Normally this is 128 bytes or less:
610 */
611 memcpy(tss->io_bitmap, next->io_bitmap_ptr,
612 max(prev->io_bitmap_max, next->io_bitmap_max));
613 else {
614 /*
615 * Clear any possible leftover bits:
616 */
617 memset(tss->io_bitmap, 0xff, prev->io_bitmap_max);
618 }
619 }
620 646
647 /* If the task has used fpu the last 5 timeslices, just do a full
648 * restore of the math state immediately to avoid the trap; the
649 * chances of needing FPU soon are obviously high now
650 */
651 if (next_p->fpu_counter>5)
652 math_state_restore();
621 return prev_p; 653 return prev_p;
622} 654}
623 655
@@ -834,7 +866,7 @@ int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
834 866
835unsigned long arch_align_stack(unsigned long sp) 867unsigned long arch_align_stack(unsigned long sp)
836{ 868{
837 if (randomize_va_space) 869 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
838 sp -= get_random_int() % 8192; 870 sp -= get_random_int() % 8192;
839 return sp & ~0xf; 871 return sp & ~0xf;
840} 872}
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c
index 2d50024c9f30..addc14af0c56 100644
--- a/arch/x86_64/kernel/ptrace.c
+++ b/arch/x86_64/kernel/ptrace.c
@@ -116,17 +116,17 @@ unsigned long convert_rip_to_linear(struct task_struct *child, struct pt_regs *r
116 return addr; 116 return addr;
117} 117}
118 118
119static int is_at_popf(struct task_struct *child, struct pt_regs *regs) 119static int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs)
120{ 120{
121 int i, copied; 121 int i, copied;
122 unsigned char opcode[16]; 122 unsigned char opcode[15];
123 unsigned long addr = convert_rip_to_linear(child, regs); 123 unsigned long addr = convert_rip_to_linear(child, regs);
124 124
125 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0); 125 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
126 for (i = 0; i < copied; i++) { 126 for (i = 0; i < copied; i++) {
127 switch (opcode[i]) { 127 switch (opcode[i]) {
128 /* popf */ 128 /* popf and iret */
129 case 0x9d: 129 case 0x9d: case 0xcf:
130 return 1; 130 return 1;
131 131
132 /* CHECKME: 64 65 */ 132 /* CHECKME: 64 65 */
@@ -138,14 +138,17 @@ static int is_at_popf(struct task_struct *child, struct pt_regs *regs)
138 case 0x26: case 0x2e: 138 case 0x26: case 0x2e:
139 case 0x36: case 0x3e: 139 case 0x36: case 0x3e:
140 case 0x64: case 0x65: 140 case 0x64: case 0x65:
141 case 0xf0: case 0xf2: case 0xf3: 141 case 0xf2: case 0xf3:
142 continue; 142 continue;
143 143
144 /* REX prefixes */
145 case 0x40 ... 0x4f: 144 case 0x40 ... 0x4f:
145 if (regs->cs != __USER_CS)
146 /* 32-bit mode: register increment */
147 return 0;
148 /* 64-bit mode: REX prefix */
146 continue; 149 continue;
147 150
148 /* CHECKME: f0, f2, f3 */ 151 /* CHECKME: f2, f3 */
149 152
150 /* 153 /*
151 * pushf: NOTE! We should probably not let 154 * pushf: NOTE! We should probably not let
@@ -186,10 +189,8 @@ static void set_singlestep(struct task_struct *child)
186 * ..but if TF is changed by the instruction we will trace, 189 * ..but if TF is changed by the instruction we will trace,
187 * don't mark it as being "us" that set it, so that we 190 * don't mark it as being "us" that set it, so that we
188 * won't clear it by hand later. 191 * won't clear it by hand later.
189 *
190 * AK: this is not enough, LAHF and IRET can change TF in user space too.
191 */ 192 */
192 if (is_at_popf(child, regs)) 193 if (is_setting_trap_flag(child, regs))
193 return; 194 return;
194 195
195 child->ptrace |= PT_DTRACE; 196 child->ptrace |= PT_DTRACE;
@@ -420,9 +421,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
420 if ((0x5554 >> ((data >> (16 + 4*i)) & 0xf)) & 1) 421 if ((0x5554 >> ((data >> (16 + 4*i)) & 0xf)) & 1)
421 break; 422 break;
422 if (i == 4) { 423 if (i == 4) {
423 child->thread.debugreg7 = data; 424 child->thread.debugreg7 = data;
425 if (data)
426 set_tsk_thread_flag(child, TIF_DEBUG);
427 else
428 clear_tsk_thread_flag(child, TIF_DEBUG);
424 ret = 0; 429 ret = 0;
425 } 430 }
426 break; 431 break;
427 } 432 }
428 break; 433 break;
diff --git a/arch/x86_64/kernel/relocate_kernel.S b/arch/x86_64/kernel/relocate_kernel.S
index d24fa9b72a2b..14e95872c6a3 100644
--- a/arch/x86_64/kernel/relocate_kernel.S
+++ b/arch/x86_64/kernel/relocate_kernel.S
@@ -7,31 +7,169 @@
7 */ 7 */
8 8
9#include <linux/linkage.h> 9#include <linux/linkage.h>
10#include <asm/page.h>
11#include <asm/kexec.h>
10 12
11 /* 13/*
12 * Must be relocatable PIC code callable as a C function, that once 14 * Must be relocatable PIC code callable as a C function
13 * it starts can not use the previous processes stack. 15 */
14 */ 16
15 .globl relocate_new_kernel 17#define PTR(x) (x << 3)
18#define PAGE_ALIGNED (1 << PAGE_SHIFT)
19#define PAGE_ATTR 0x63 /* _PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY */
20
21 .text
22 .align PAGE_ALIGNED
16 .code64 23 .code64
24 .globl relocate_kernel
25relocate_kernel:
26 /* %rdi indirection_page
27 * %rsi page_list
28 * %rdx start address
29 */
30
31 /* map the control page at its virtual address */
32
33 movq $0x0000ff8000000000, %r10 /* mask */
34 mov $(39 - 3), %cl /* bits to shift */
35 movq PTR(VA_CONTROL_PAGE)(%rsi), %r11 /* address to map */
36
37 movq %r11, %r9
38 andq %r10, %r9
39 shrq %cl, %r9
40
41 movq PTR(VA_PGD)(%rsi), %r8
42 addq %r8, %r9
43 movq PTR(PA_PUD_0)(%rsi), %r8
44 orq $PAGE_ATTR, %r8
45 movq %r8, (%r9)
46
47 shrq $9, %r10
48 sub $9, %cl
49
50 movq %r11, %r9
51 andq %r10, %r9
52 shrq %cl, %r9
53
54 movq PTR(VA_PUD_0)(%rsi), %r8
55 addq %r8, %r9
56 movq PTR(PA_PMD_0)(%rsi), %r8
57 orq $PAGE_ATTR, %r8
58 movq %r8, (%r9)
59
60 shrq $9, %r10
61 sub $9, %cl
62
63 movq %r11, %r9
64 andq %r10, %r9
65 shrq %cl, %r9
66
67 movq PTR(VA_PMD_0)(%rsi), %r8
68 addq %r8, %r9
69 movq PTR(PA_PTE_0)(%rsi), %r8
70 orq $PAGE_ATTR, %r8
71 movq %r8, (%r9)
72
73 shrq $9, %r10
74 sub $9, %cl
75
76 movq %r11, %r9
77 andq %r10, %r9
78 shrq %cl, %r9
79
80 movq PTR(VA_PTE_0)(%rsi), %r8
81 addq %r8, %r9
82 movq PTR(PA_CONTROL_PAGE)(%rsi), %r8
83 orq $PAGE_ATTR, %r8
84 movq %r8, (%r9)
85
86 /* identity map the control page at its physical address */
87
88 movq $0x0000ff8000000000, %r10 /* mask */
89 mov $(39 - 3), %cl /* bits to shift */
90 movq PTR(PA_CONTROL_PAGE)(%rsi), %r11 /* address to map */
91
92 movq %r11, %r9
93 andq %r10, %r9
94 shrq %cl, %r9
95
96 movq PTR(VA_PGD)(%rsi), %r8
97 addq %r8, %r9
98 movq PTR(PA_PUD_1)(%rsi), %r8
99 orq $PAGE_ATTR, %r8
100 movq %r8, (%r9)
101
102 shrq $9, %r10
103 sub $9, %cl
104
105 movq %r11, %r9
106 andq %r10, %r9
107 shrq %cl, %r9
108
109 movq PTR(VA_PUD_1)(%rsi), %r8
110 addq %r8, %r9
111 movq PTR(PA_PMD_1)(%rsi), %r8
112 orq $PAGE_ATTR, %r8
113 movq %r8, (%r9)
114
115 shrq $9, %r10
116 sub $9, %cl
117
118 movq %r11, %r9
119 andq %r10, %r9
120 shrq %cl, %r9
121
122 movq PTR(VA_PMD_1)(%rsi), %r8
123 addq %r8, %r9
124 movq PTR(PA_PTE_1)(%rsi), %r8
125 orq $PAGE_ATTR, %r8
126 movq %r8, (%r9)
127
128 shrq $9, %r10
129 sub $9, %cl
130
131 movq %r11, %r9
132 andq %r10, %r9
133 shrq %cl, %r9
134
135 movq PTR(VA_PTE_1)(%rsi), %r8
136 addq %r8, %r9
137 movq PTR(PA_CONTROL_PAGE)(%rsi), %r8
138 orq $PAGE_ATTR, %r8
139 movq %r8, (%r9)
140
17relocate_new_kernel: 141relocate_new_kernel:
18 /* %rdi page_list 142 /* %rdi indirection_page
19 * %rsi reboot_code_buffer 143 * %rsi page_list
20 * %rdx start address 144 * %rdx start address
21 * %rcx page_table
22 * %r8 arg5
23 * %r9 arg6
24 */ 145 */
25 146
26 /* zero out flags, and disable interrupts */ 147 /* zero out flags, and disable interrupts */
27 pushq $0 148 pushq $0
28 popfq 149 popfq
29 150
30 /* set a new stack at the bottom of our page... */ 151 /* get physical address of control page now */
31 lea 4096(%rsi), %rsp 152 /* this is impossible after page table switch */
153 movq PTR(PA_CONTROL_PAGE)(%rsi), %r8
154
155 /* get physical address of page table now too */
156 movq PTR(PA_TABLE_PAGE)(%rsi), %rcx
32 157
33 /* store the parameters back on the stack */ 158 /* switch to new set of page tables */
34 pushq %rdx /* store the start address */ 159 movq PTR(PA_PGD)(%rsi), %r9
160 movq %r9, %cr3
161
162 /* setup a new stack at the end of the physical control page */
163 lea 4096(%r8), %rsp
164
165 /* jump to identity mapped page */
166 addq $(identity_mapped - relocate_kernel), %r8
167 pushq %r8
168 ret
169
170identity_mapped:
171 /* store the start address on the stack */
172 pushq %rdx
35 173
36 /* Set cr0 to a known state: 174 /* Set cr0 to a known state:
37 * 31 1 == Paging enabled 175 * 31 1 == Paging enabled
@@ -136,8 +274,3 @@ relocate_new_kernel:
136 xorq %r15, %r15 274 xorq %r15, %r15
137 275
138 ret 276 ret
139relocate_new_kernel_end:
140
141 .globl relocate_new_kernel_size
142relocate_new_kernel_size:
143 .quad relocate_new_kernel_end - relocate_new_kernel
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 34afad704824..0b00bb2ea576 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -74,16 +74,6 @@ EXPORT_SYMBOL(boot_cpu_data);
74 74
75unsigned long mmu_cr4_features; 75unsigned long mmu_cr4_features;
76 76
77int acpi_disabled;
78EXPORT_SYMBOL(acpi_disabled);
79#ifdef CONFIG_ACPI
80extern int __initdata acpi_ht;
81extern acpi_interrupt_flags acpi_sci_flags;
82int __initdata acpi_force = 0;
83#endif
84
85int acpi_numa __initdata;
86
87/* Boot loader ID as an integer, for the benefit of proc_dointvec */ 77/* Boot loader ID as an integer, for the benefit of proc_dointvec */
88int bootloader_type; 78int bootloader_type;
89 79
@@ -107,7 +97,6 @@ struct sys_desc_table_struct {
107 97
108struct edid_info edid_info; 98struct edid_info edid_info;
109EXPORT_SYMBOL_GPL(edid_info); 99EXPORT_SYMBOL_GPL(edid_info);
110struct e820map e820;
111 100
112extern int root_mountflags; 101extern int root_mountflags;
113 102
@@ -276,185 +265,22 @@ static void __init probe_roms(void)
276 } 265 }
277} 266}
278 267
279/* Check for full argument with no trailing characters */ 268#ifdef CONFIG_PROC_VMCORE
280static int fullarg(char *p, char *arg) 269/* elfcorehdr= specifies the location of elf core header
270 * stored by the crashed kernel. This option will be passed
271 * by kexec loader to the capture kernel.
272 */
273static int __init setup_elfcorehdr(char *arg)
281{ 274{
282 int l = strlen(arg); 275 char *end;
283 return !memcmp(p, arg, l) && (p[l] == 0 || isspace(p[l])); 276 if (!arg)
277 return -EINVAL;
278 elfcorehdr_addr = memparse(arg, &end);
279 return end > arg ? 0 : -EINVAL;
284} 280}
285 281early_param("elfcorehdr", setup_elfcorehdr);
286static __init void parse_cmdline_early (char ** cmdline_p)
287{
288 char c = ' ', *to = command_line, *from = COMMAND_LINE;
289 int len = 0;
290 int userdef = 0;
291
292 for (;;) {
293 if (c != ' ')
294 goto next_char;
295
296#ifdef CONFIG_SMP
297 /*
298 * If the BIOS enumerates physical processors before logical,
299 * maxcpus=N at enumeration-time can be used to disable HT.
300 */
301 else if (!memcmp(from, "maxcpus=", 8)) {
302 extern unsigned int maxcpus;
303
304 maxcpus = simple_strtoul(from + 8, NULL, 0);
305 }
306#endif
307#ifdef CONFIG_ACPI
308 /* "acpi=off" disables both ACPI table parsing and interpreter init */
309 if (fullarg(from,"acpi=off"))
310 disable_acpi();
311
312 if (fullarg(from, "acpi=force")) {
313 /* add later when we do DMI horrors: */
314 acpi_force = 1;
315 acpi_disabled = 0;
316 }
317
318 /* acpi=ht just means: do ACPI MADT parsing
319 at bootup, but don't enable the full ACPI interpreter */
320 if (fullarg(from, "acpi=ht")) {
321 if (!acpi_force)
322 disable_acpi();
323 acpi_ht = 1;
324 }
325 else if (fullarg(from, "pci=noacpi"))
326 acpi_disable_pci();
327 else if (fullarg(from, "acpi=noirq"))
328 acpi_noirq_set();
329
330 else if (fullarg(from, "acpi_sci=edge"))
331 acpi_sci_flags.trigger = 1;
332 else if (fullarg(from, "acpi_sci=level"))
333 acpi_sci_flags.trigger = 3;
334 else if (fullarg(from, "acpi_sci=high"))
335 acpi_sci_flags.polarity = 1;
336 else if (fullarg(from, "acpi_sci=low"))
337 acpi_sci_flags.polarity = 3;
338
339 /* acpi=strict disables out-of-spec workarounds */
340 else if (fullarg(from, "acpi=strict")) {
341 acpi_strict = 1;
342 }
343#ifdef CONFIG_X86_IO_APIC
344 else if (fullarg(from, "acpi_skip_timer_override"))
345 acpi_skip_timer_override = 1;
346#endif
347#endif
348
349 if (fullarg(from, "disable_timer_pin_1"))
350 disable_timer_pin_1 = 1;
351 if (fullarg(from, "enable_timer_pin_1"))
352 disable_timer_pin_1 = -1;
353
354 if (fullarg(from, "nolapic") || fullarg(from, "disableapic")) {
355 clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
356 disable_apic = 1;
357 }
358
359 if (fullarg(from, "noapic"))
360 skip_ioapic_setup = 1;
361
362 if (fullarg(from,"apic")) {
363 skip_ioapic_setup = 0;
364 ioapic_force = 1;
365 }
366
367 if (!memcmp(from, "mem=", 4))
368 parse_memopt(from+4, &from);
369
370 if (!memcmp(from, "memmap=", 7)) {
371 /* exactmap option is for used defined memory */
372 if (!memcmp(from+7, "exactmap", 8)) {
373#ifdef CONFIG_CRASH_DUMP
374 /* If we are doing a crash dump, we
375 * still need to know the real mem
376 * size before original memory map is
377 * reset.
378 */
379 saved_max_pfn = e820_end_of_ram();
380#endif
381 from += 8+7;
382 end_pfn_map = 0;
383 e820.nr_map = 0;
384 userdef = 1;
385 }
386 else {
387 parse_memmapopt(from+7, &from);
388 userdef = 1;
389 }
390 }
391
392#ifdef CONFIG_NUMA
393 if (!memcmp(from, "numa=", 5))
394 numa_setup(from+5);
395#endif 282#endif
396 283
397 if (!memcmp(from,"iommu=",6)) {
398 iommu_setup(from+6);
399 }
400
401 if (fullarg(from,"oops=panic"))
402 panic_on_oops = 1;
403
404 if (!memcmp(from, "noexec=", 7))
405 nonx_setup(from + 7);
406
407#ifdef CONFIG_KEXEC
408 /* crashkernel=size@addr specifies the location to reserve for
409 * a crash kernel. By reserving this memory we guarantee
410 * that linux never set's it up as a DMA target.
411 * Useful for holding code to do something appropriate
412 * after a kernel panic.
413 */
414 else if (!memcmp(from, "crashkernel=", 12)) {
415 unsigned long size, base;
416 size = memparse(from+12, &from);
417 if (*from == '@') {
418 base = memparse(from+1, &from);
419 /* FIXME: Do I want a sanity check
420 * to validate the memory range?
421 */
422 crashk_res.start = base;
423 crashk_res.end = base + size - 1;
424 }
425 }
426#endif
427
428#ifdef CONFIG_PROC_VMCORE
429 /* elfcorehdr= specifies the location of elf core header
430 * stored by the crashed kernel. This option will be passed
431 * by kexec loader to the capture kernel.
432 */
433 else if(!memcmp(from, "elfcorehdr=", 11))
434 elfcorehdr_addr = memparse(from+11, &from);
435#endif
436
437#ifdef CONFIG_HOTPLUG_CPU
438 else if (!memcmp(from, "additional_cpus=", 16))
439 setup_additional_cpus(from+16);
440#endif
441
442 next_char:
443 c = *(from++);
444 if (!c)
445 break;
446 if (COMMAND_LINE_SIZE <= ++len)
447 break;
448 *(to++) = c;
449 }
450 if (userdef) {
451 printk(KERN_INFO "user-defined physical RAM map:\n");
452 e820_print_map("user");
453 }
454 *to = '\0';
455 *cmdline_p = command_line;
456}
457
458#ifndef CONFIG_NUMA 284#ifndef CONFIG_NUMA
459static void __init 285static void __init
460contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn) 286contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
@@ -466,7 +292,8 @@ contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
466 if (bootmap == -1L) 292 if (bootmap == -1L)
467 panic("Cannot find bootmem map of size %ld\n",bootmap_size); 293 panic("Cannot find bootmem map of size %ld\n",bootmap_size);
468 bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn); 294 bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
469 e820_bootmem_free(NODE_DATA(0), 0, end_pfn << PAGE_SHIFT); 295 e820_register_active_regions(0, start_pfn, end_pfn);
296 free_bootmem_with_active_regions(0, end_pfn);
470 reserve_bootmem(bootmap, bootmap_size); 297 reserve_bootmem(bootmap, bootmap_size);
471} 298}
472#endif 299#endif
@@ -521,6 +348,8 @@ static void discover_ebda(void)
521 348
522void __init setup_arch(char **cmdline_p) 349void __init setup_arch(char **cmdline_p)
523{ 350{
351 printk(KERN_INFO "Command line: %s\n", saved_command_line);
352
524 ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); 353 ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
525 screen_info = SCREEN_INFO; 354 screen_info = SCREEN_INFO;
526 edid_info = EDID_INFO; 355 edid_info = EDID_INFO;
@@ -547,16 +376,22 @@ void __init setup_arch(char **cmdline_p)
547 data_resource.start = virt_to_phys(&_etext); 376 data_resource.start = virt_to_phys(&_etext);
548 data_resource.end = virt_to_phys(&_edata)-1; 377 data_resource.end = virt_to_phys(&_edata)-1;
549 378
550 parse_cmdline_early(cmdline_p);
551
552 early_identify_cpu(&boot_cpu_data); 379 early_identify_cpu(&boot_cpu_data);
553 380
381 strlcpy(command_line, saved_command_line, COMMAND_LINE_SIZE);
382 *cmdline_p = command_line;
383
384 parse_early_param();
385
386 finish_e820_parsing();
387
388 e820_register_active_regions(0, 0, -1UL);
554 /* 389 /*
555 * partially used pages are not usable - thus 390 * partially used pages are not usable - thus
556 * we are rounding upwards: 391 * we are rounding upwards:
557 */ 392 */
558 end_pfn = e820_end_of_ram(); 393 end_pfn = e820_end_of_ram();
559 num_physpages = end_pfn; /* for pfn_valid */ 394 num_physpages = end_pfn;
560 395
561 check_efer(); 396 check_efer();
562 397
@@ -576,6 +411,14 @@ void __init setup_arch(char **cmdline_p)
576 acpi_boot_table_init(); 411 acpi_boot_table_init();
577#endif 412#endif
578 413
414 /* How many end-of-memory variables you have, grandma! */
415 max_low_pfn = end_pfn;
416 max_pfn = end_pfn;
417 high_memory = (void *)__va(end_pfn * PAGE_SIZE - 1) + 1;
418
419 /* Remove active ranges so rediscovery with NUMA-awareness happens */
420 remove_all_active_ranges();
421
579#ifdef CONFIG_ACPI_NUMA 422#ifdef CONFIG_ACPI_NUMA
580 /* 423 /*
581 * Parse SRAT to discover nodes. 424 * Parse SRAT to discover nodes.
@@ -625,12 +468,10 @@ void __init setup_arch(char **cmdline_p)
625 */ 468 */
626 acpi_reserve_bootmem(); 469 acpi_reserve_bootmem();
627#endif 470#endif
628#ifdef CONFIG_X86_LOCAL_APIC
629 /* 471 /*
630 * Find and reserve possible boot-time SMP configuration: 472 * Find and reserve possible boot-time SMP configuration:
631 */ 473 */
632 find_smp_config(); 474 find_smp_config();
633#endif
634#ifdef CONFIG_BLK_DEV_INITRD 475#ifdef CONFIG_BLK_DEV_INITRD
635 if (LOADER_TYPE && INITRD_START) { 476 if (LOADER_TYPE && INITRD_START) {
636 if (INITRD_START + INITRD_SIZE <= (end_pfn << PAGE_SHIFT)) { 477 if (INITRD_START + INITRD_SIZE <= (end_pfn << PAGE_SHIFT)) {
@@ -657,7 +498,9 @@ void __init setup_arch(char **cmdline_p)
657 498
658 paging_init(); 499 paging_init();
659 500
660 check_ioapic(); 501#ifdef CONFIG_PCI
502 early_quirks();
503#endif
661 504
662 /* 505 /*
663 * set this early, so we dont allocate cpu0 506 * set this early, so we dont allocate cpu0
@@ -674,14 +517,12 @@ void __init setup_arch(char **cmdline_p)
674 517
675 init_cpu_to_node(); 518 init_cpu_to_node();
676 519
677#ifdef CONFIG_X86_LOCAL_APIC
678 /* 520 /*
679 * get boot-time SMP configuration: 521 * get boot-time SMP configuration:
680 */ 522 */
681 if (smp_found_config) 523 if (smp_found_config)
682 get_smp_config(); 524 get_smp_config();
683 init_apic_mappings(); 525 init_apic_mappings();
684#endif
685 526
686 /* 527 /*
687 * Request address space for all standard RAM and ROM resources 528 * Request address space for all standard RAM and ROM resources
@@ -689,6 +530,7 @@ void __init setup_arch(char **cmdline_p)
689 */ 530 */
690 probe_roms(); 531 probe_roms();
691 e820_reserve_resources(); 532 e820_reserve_resources();
533 e820_mark_nosave_regions();
692 534
693 request_resource(&iomem_resource, &video_ram_resource); 535 request_resource(&iomem_resource, &video_ram_resource);
694 536
@@ -838,7 +680,7 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
838#endif 680#endif
839} 681}
840 682
841static void __init init_amd(struct cpuinfo_x86 *c) 683static void __cpuinit init_amd(struct cpuinfo_x86 *c)
842{ 684{
843 unsigned level; 685 unsigned level;
844 686
@@ -894,6 +736,12 @@ static void __init init_amd(struct cpuinfo_x86 *c)
894 736
895 /* Fix cpuid4 emulation for more */ 737 /* Fix cpuid4 emulation for more */
896 num_cache_leaves = 3; 738 num_cache_leaves = 3;
739
740 /* When there is only one core no need to synchronize RDTSC */
741 if (num_possible_cpus() == 1)
742 set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
743 else
744 clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
897} 745}
898 746
899static void __cpuinit detect_ht(struct cpuinfo_x86 *c) 747static void __cpuinit detect_ht(struct cpuinfo_x86 *c)
@@ -975,8 +823,7 @@ static void srat_detect_node(void)
975 node = first_node(node_online_map); 823 node = first_node(node_online_map);
976 numa_set_node(cpu, node); 824 numa_set_node(cpu, node);
977 825
978 if (acpi_numa > 0) 826 printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node);
979 printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node);
980#endif 827#endif
981} 828}
982 829
@@ -1010,6 +857,8 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
1010 if ((c->x86 == 0xf && c->x86_model >= 0x03) || 857 if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
1011 (c->x86 == 0x6 && c->x86_model >= 0x0e)) 858 (c->x86 == 0x6 && c->x86_model >= 0x0e))
1012 set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability); 859 set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
860 if (c->x86 == 6)
861 set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
1013 set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); 862 set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
1014 c->x86_max_cores = intel_num_cpu_cores(c); 863 c->x86_max_cores = intel_num_cpu_cores(c);
1015 864
@@ -1228,8 +1077,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
1228 1077
1229 /* Intel-defined (#2) */ 1078 /* Intel-defined (#2) */
1230 "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est", 1079 "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est",
1231 "tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL, 1080 "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
1232 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1081 NULL, NULL, "dca", NULL, NULL, NULL, NULL, NULL,
1233 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1082 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1234 1083
1235 /* VIA/Cyrix/Centaur-defined */ 1084 /* VIA/Cyrix/Centaur-defined */
diff --git a/arch/x86_64/kernel/setup64.c b/arch/x86_64/kernel/setup64.c
index 417de564456e..8c4b80fe71a1 100644
--- a/arch/x86_64/kernel/setup64.c
+++ b/arch/x86_64/kernel/setup64.c
@@ -24,7 +24,7 @@
24#include <asm/proto.h> 24#include <asm/proto.h>
25#include <asm/sections.h> 25#include <asm/sections.h>
26 26
27char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,}; 27char x86_boot_params[BOOT_PARAM_SIZE] __initdata;
28 28
29cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE; 29cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
30 30
@@ -46,8 +46,10 @@ Control non executable mappings for 64bit processes.
46on Enable(default) 46on Enable(default)
47off Disable 47off Disable
48*/ 48*/
49int __init nonx_setup(char *str) 49static int __init nonx_setup(char *str)
50{ 50{
51 if (!str)
52 return -EINVAL;
51 if (!strncmp(str, "on", 2)) { 53 if (!strncmp(str, "on", 2)) {
52 __supported_pte_mask |= _PAGE_NX; 54 __supported_pte_mask |= _PAGE_NX;
53 do_not_nx = 0; 55 do_not_nx = 0;
@@ -55,9 +57,9 @@ int __init nonx_setup(char *str)
55 do_not_nx = 1; 57 do_not_nx = 1;
56 __supported_pte_mask &= ~_PAGE_NX; 58 __supported_pte_mask &= ~_PAGE_NX;
57 } 59 }
58 return 1; 60 return 0;
59} 61}
60__setup("noexec=", nonx_setup); /* parsed early actually */ 62early_param("noexec", nonx_setup);
61 63
62int force_personality32 = 0; 64int force_personality32 = 0;
63 65
@@ -93,12 +95,9 @@ void __init setup_per_cpu_areas(void)
93#endif 95#endif
94 96
95 /* Copy section for each CPU (we discard the original) */ 97 /* Copy section for each CPU (we discard the original) */
96 size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES); 98 size = PERCPU_ENOUGH_ROOM;
97#ifdef CONFIG_MODULES
98 if (size < PERCPU_ENOUGH_ROOM)
99 size = PERCPU_ENOUGH_ROOM;
100#endif
101 99
100 printk(KERN_INFO "PERCPU: Allocating %lu bytes of per cpu data\n", size);
102 for_each_cpu_mask (i, cpu_possible_map) { 101 for_each_cpu_mask (i, cpu_possible_map) {
103 char *ptr; 102 char *ptr;
104 103
@@ -122,7 +121,10 @@ void pda_init(int cpu)
122 121
123 /* Setup up data that may be needed in __get_free_pages early */ 122 /* Setup up data that may be needed in __get_free_pages early */
124 asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0)); 123 asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0));
124 /* Memory clobbers used to order PDA accessed */
125 mb();
125 wrmsrl(MSR_GS_BASE, pda); 126 wrmsrl(MSR_GS_BASE, pda);
127 mb();
126 128
127 pda->cpunumber = cpu; 129 pda->cpunumber = cpu;
128 pda->irqcount = -1; 130 pda->irqcount = -1;
@@ -178,6 +180,8 @@ void __cpuinit check_efer(void)
178 } 180 }
179} 181}
180 182
183unsigned long kernel_eflags;
184
181/* 185/*
182 * cpu_init() initializes state that is per-CPU. Some data is already 186 * cpu_init() initializes state that is per-CPU. Some data is already
183 * initialized (naturally) in the bootstrap process, such as the GDT 187 * initialized (naturally) in the bootstrap process, such as the GDT
@@ -235,28 +239,17 @@ void __cpuinit cpu_init (void)
235 * set up and load the per-CPU TSS 239 * set up and load the per-CPU TSS
236 */ 240 */
237 for (v = 0; v < N_EXCEPTION_STACKS; v++) { 241 for (v = 0; v < N_EXCEPTION_STACKS; v++) {
242 static const unsigned int order[N_EXCEPTION_STACKS] = {
243 [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER,
244 [DEBUG_STACK - 1] = DEBUG_STACK_ORDER
245 };
238 if (cpu) { 246 if (cpu) {
239 static const unsigned int order[N_EXCEPTION_STACKS] = {
240 [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER,
241 [DEBUG_STACK - 1] = DEBUG_STACK_ORDER
242 };
243
244 estacks = (char *)__get_free_pages(GFP_ATOMIC, order[v]); 247 estacks = (char *)__get_free_pages(GFP_ATOMIC, order[v]);
245 if (!estacks) 248 if (!estacks)
246 panic("Cannot allocate exception stack %ld %d\n", 249 panic("Cannot allocate exception stack %ld %d\n",
247 v, cpu); 250 v, cpu);
248 } 251 }
249 switch (v + 1) { 252 estacks += PAGE_SIZE << order[v];
250#if DEBUG_STKSZ > EXCEPTION_STKSZ
251 case DEBUG_STACK:
252 cpu_pda(cpu)->debugstack = (unsigned long)estacks;
253 estacks += DEBUG_STKSZ;
254 break;
255#endif
256 default:
257 estacks += EXCEPTION_STKSZ;
258 break;
259 }
260 orig_ist->ist[v] = t->ist[v] = (unsigned long)estacks; 253 orig_ist->ist[v] = t->ist[v] = (unsigned long)estacks;
261 } 254 }
262 255
@@ -290,4 +283,6 @@ void __cpuinit cpu_init (void)
290 set_debugreg(0UL, 7); 283 set_debugreg(0UL, 7);
291 284
292 fpu_init(); 285 fpu_init();
286
287 raw_local_save_flags(kernel_eflags);
293} 288}
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
index 28161170fb0a..49ec324cd141 100644
--- a/arch/x86_64/kernel/signal.c
+++ b/arch/x86_64/kernel/signal.c
@@ -38,37 +38,6 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
38 sigset_t *set, struct pt_regs * regs); 38 sigset_t *set, struct pt_regs * regs);
39 39
40asmlinkage long 40asmlinkage long
41sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs)
42{
43 sigset_t saveset, newset;
44
45 /* XXX: Don't preclude handling different sized sigset_t's. */
46 if (sigsetsize != sizeof(sigset_t))
47 return -EINVAL;
48
49 if (copy_from_user(&newset, unewset, sizeof(newset)))
50 return -EFAULT;
51 sigdelsetmask(&newset, ~_BLOCKABLE);
52
53 spin_lock_irq(&current->sighand->siglock);
54 saveset = current->blocked;
55 current->blocked = newset;
56 recalc_sigpending();
57 spin_unlock_irq(&current->sighand->siglock);
58#ifdef DEBUG_SIG
59 printk("rt_sigsuspend savset(%lx) newset(%lx) regs(%p) rip(%lx)\n",
60 saveset, newset, regs, regs->rip);
61#endif
62 regs->rax = -EINTR;
63 while (1) {
64 current->state = TASK_INTERRUPTIBLE;
65 schedule();
66 if (do_signal(regs, &saveset))
67 return -EINTR;
68 }
69}
70
71asmlinkage long
72sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, 41sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
73 struct pt_regs *regs) 42 struct pt_regs *regs)
74{ 43{
@@ -308,11 +277,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
308#endif 277#endif
309 278
310 /* Set up registers for signal handler */ 279 /* Set up registers for signal handler */
311 {
312 struct exec_domain *ed = current_thread_info()->exec_domain;
313 if (unlikely(ed && ed->signal_invmap && sig < 32))
314 sig = ed->signal_invmap[sig];
315 }
316 regs->rdi = sig; 280 regs->rdi = sig;
317 /* In case the signal handler was declared without prototypes */ 281 /* In case the signal handler was declared without prototypes */
318 regs->rax = 0; 282 regs->rax = 0;
@@ -341,11 +305,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
341 current->comm, current->pid, frame, regs->rip, frame->pretcode); 305 current->comm, current->pid, frame, regs->rip, frame->pretcode);
342#endif 306#endif
343 307
344 return 1; 308 return 0;
345 309
346give_sigsegv: 310give_sigsegv:
347 force_sigsegv(sig, current); 311 force_sigsegv(sig, current);
348 return 0; 312 return -EFAULT;
349} 313}
350 314
351/* 315/*
@@ -408,7 +372,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
408#endif 372#endif
409 ret = setup_rt_frame(sig, ka, info, oldset, regs); 373 ret = setup_rt_frame(sig, ka, info, oldset, regs);
410 374
411 if (ret) { 375 if (ret == 0) {
412 spin_lock_irq(&current->sighand->siglock); 376 spin_lock_irq(&current->sighand->siglock);
413 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 377 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
414 if (!(ka->sa.sa_flags & SA_NODEFER)) 378 if (!(ka->sa.sa_flags & SA_NODEFER))
@@ -425,11 +389,12 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
425 * want to handle. Thus you cannot kill init even with a SIGKILL even by 389 * want to handle. Thus you cannot kill init even with a SIGKILL even by
426 * mistake. 390 * mistake.
427 */ 391 */
428int do_signal(struct pt_regs *regs, sigset_t *oldset) 392static void do_signal(struct pt_regs *regs)
429{ 393{
430 struct k_sigaction ka; 394 struct k_sigaction ka;
431 siginfo_t info; 395 siginfo_t info;
432 int signr; 396 int signr;
397 sigset_t *oldset;
433 398
434 /* 399 /*
435 * We want the common case to go fast, which 400 * We want the common case to go fast, which
@@ -438,9 +403,11 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
438 * if so. 403 * if so.
439 */ 404 */
440 if (!user_mode(regs)) 405 if (!user_mode(regs))
441 return 1; 406 return;
442 407
443 if (!oldset) 408 if (test_thread_flag(TIF_RESTORE_SIGMASK))
409 oldset = &current->saved_sigmask;
410 else
444 oldset = &current->blocked; 411 oldset = &current->blocked;
445 412
446 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 413 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
@@ -454,30 +421,46 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
454 set_debugreg(current->thread.debugreg7, 7); 421 set_debugreg(current->thread.debugreg7, 7);
455 422
456 /* Whee! Actually deliver the signal. */ 423 /* Whee! Actually deliver the signal. */
457 return handle_signal(signr, &info, &ka, oldset, regs); 424 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
425 /* a signal was successfully delivered; the saved
426 * sigmask will have been stored in the signal frame,
427 * and will be restored by sigreturn, so we can simply
428 * clear the TIF_RESTORE_SIGMASK flag */
429 clear_thread_flag(TIF_RESTORE_SIGMASK);
430 }
431 return;
458 } 432 }
459 433
460 /* Did we come from a system call? */ 434 /* Did we come from a system call? */
461 if ((long)regs->orig_rax >= 0) { 435 if ((long)regs->orig_rax >= 0) {
462 /* Restart the system call - no handlers present */ 436 /* Restart the system call - no handlers present */
463 long res = regs->rax; 437 long res = regs->rax;
464 if (res == -ERESTARTNOHAND || 438 switch (res) {
465 res == -ERESTARTSYS || 439 case -ERESTARTNOHAND:
466 res == -ERESTARTNOINTR) { 440 case -ERESTARTSYS:
441 case -ERESTARTNOINTR:
467 regs->rax = regs->orig_rax; 442 regs->rax = regs->orig_rax;
468 regs->rip -= 2; 443 regs->rip -= 2;
469 } 444 break;
470 if (regs->rax == (unsigned long)-ERESTART_RESTARTBLOCK) { 445 case -ERESTART_RESTARTBLOCK:
471 regs->rax = test_thread_flag(TIF_IA32) ? 446 regs->rax = test_thread_flag(TIF_IA32) ?
472 __NR_ia32_restart_syscall : 447 __NR_ia32_restart_syscall :
473 __NR_restart_syscall; 448 __NR_restart_syscall;
474 regs->rip -= 2; 449 regs->rip -= 2;
450 break;
475 } 451 }
476 } 452 }
477 return 0; 453
454 /* if there's no signal to deliver, we just put the saved sigmask
455 back. */
456 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
457 clear_thread_flag(TIF_RESTORE_SIGMASK);
458 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
459 }
478} 460}
479 461
480void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, __u32 thread_info_flags) 462void
463do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
481{ 464{
482#ifdef DEBUG_SIG 465#ifdef DEBUG_SIG
483 printk("do_notify_resume flags:%x rip:%lx rsp:%lx caller:%lx pending:%lx\n", 466 printk("do_notify_resume flags:%x rip:%lx rsp:%lx caller:%lx pending:%lx\n",
@@ -491,8 +474,8 @@ void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, __u32 thread_info_
491 } 474 }
492 475
493 /* deal with pending signal delivery */ 476 /* deal with pending signal delivery */
494 if (thread_info_flags & _TIF_SIGPENDING) 477 if (thread_info_flags & (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK))
495 do_signal(regs,oldset); 478 do_signal(regs);
496} 479}
497 480
498void signal_fault(struct pt_regs *regs, void __user *frame, char *where) 481void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c
index 06af6ca60129..4f67697f5036 100644
--- a/arch/x86_64/kernel/smp.c
+++ b/arch/x86_64/kernel/smp.c
@@ -522,26 +522,3 @@ asmlinkage void smp_call_function_interrupt(void)
522 } 522 }
523} 523}
524 524
525int safe_smp_processor_id(void)
526{
527 unsigned apicid, i;
528
529 if (disable_apic)
530 return 0;
531
532 apicid = hard_smp_processor_id();
533 if (apicid < NR_CPUS && x86_cpu_to_apicid[apicid] == apicid)
534 return apicid;
535
536 for (i = 0; i < NR_CPUS; ++i) {
537 if (x86_cpu_to_apicid[i] == apicid)
538 return i;
539 }
540
541 /* No entries in x86_cpu_to_apicid? Either no MPS|ACPI,
542 * or called too early. Either way, we must be CPU 0. */
543 if (x86_cpu_to_apicid[0] == BAD_APICID)
544 return 0;
545
546 return 0; /* Should not happen */
547}
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 975380207b46..7b7a6870288a 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -46,9 +46,10 @@
46#include <linux/bootmem.h> 46#include <linux/bootmem.h>
47#include <linux/thread_info.h> 47#include <linux/thread_info.h>
48#include <linux/module.h> 48#include <linux/module.h>
49
50#include <linux/delay.h> 49#include <linux/delay.h>
51#include <linux/mc146818rtc.h> 50#include <linux/mc146818rtc.h>
51#include <linux/smp.h>
52
52#include <asm/mtrr.h> 53#include <asm/mtrr.h>
53#include <asm/pgalloc.h> 54#include <asm/pgalloc.h>
54#include <asm/desc.h> 55#include <asm/desc.h>
@@ -1090,7 +1091,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
1090 /* 1091 /*
1091 * Switch from PIC to APIC mode. 1092 * Switch from PIC to APIC mode.
1092 */ 1093 */
1093 connect_bsp_APIC();
1094 setup_local_APIC(); 1094 setup_local_APIC();
1095 1095
1096 if (GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_id) { 1096 if (GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_id) {
@@ -1175,12 +1175,9 @@ int __cpuinit __cpu_up(unsigned int cpu)
1175void __init smp_cpus_done(unsigned int max_cpus) 1175void __init smp_cpus_done(unsigned int max_cpus)
1176{ 1176{
1177 smp_cleanup_boot(); 1177 smp_cleanup_boot();
1178
1179#ifdef CONFIG_X86_IO_APIC
1180 setup_ioapic_dest(); 1178 setup_ioapic_dest();
1181#endif
1182
1183 check_nmi_watchdog(); 1179 check_nmi_watchdog();
1180 time_init_gtod();
1184} 1181}
1185 1182
1186#ifdef CONFIG_HOTPLUG_CPU 1183#ifdef CONFIG_HOTPLUG_CPU
@@ -1233,6 +1230,8 @@ int __cpu_disable(void)
1233 if (cpu == 0) 1230 if (cpu == 0)
1234 return -EBUSY; 1231 return -EBUSY;
1235 1232
1233 if (nmi_watchdog == NMI_LOCAL_APIC)
1234 stop_apic_nmi_watchdog(NULL);
1236 clear_local_APIC(); 1235 clear_local_APIC();
1237 1236
1238 /* 1237 /*
@@ -1272,11 +1271,11 @@ void __cpu_die(unsigned int cpu)
1272 printk(KERN_ERR "CPU %u didn't die...\n", cpu); 1271 printk(KERN_ERR "CPU %u didn't die...\n", cpu);
1273} 1272}
1274 1273
1275__init int setup_additional_cpus(char *s) 1274static __init int setup_additional_cpus(char *s)
1276{ 1275{
1277 return get_option(&s, &additional_cpus); 1276 return s && get_option(&s, &additional_cpus) ? 0 : -EINVAL;
1278} 1277}
1279__setup("additional_cpus=", setup_additional_cpus); 1278early_param("additional_cpus", setup_additional_cpus);
1280 1279
1281#else /* ... !CONFIG_HOTPLUG_CPU */ 1280#else /* ... !CONFIG_HOTPLUG_CPU */
1282 1281
diff --git a/arch/x86_64/kernel/stacktrace.c b/arch/x86_64/kernel/stacktrace.c
index 32cf55eb9af8..6026b31d037e 100644
--- a/arch/x86_64/kernel/stacktrace.c
+++ b/arch/x86_64/kernel/stacktrace.c
@@ -7,215 +7,49 @@
7 */ 7 */
8#include <linux/sched.h> 8#include <linux/sched.h>
9#include <linux/stacktrace.h> 9#include <linux/stacktrace.h>
10#include <linux/module.h>
11#include <asm/stacktrace.h>
10 12
11#include <asm/smp.h> 13static void save_stack_warning(void *data, char *msg)
12
13static inline int
14in_range(unsigned long start, unsigned long addr, unsigned long end)
15{ 14{
16 return addr >= start && addr <= end;
17} 15}
18 16
19static unsigned long 17static void
20get_stack_end(struct task_struct *task, unsigned long stack) 18save_stack_warning_symbol(void *data, char *msg, unsigned long symbol)
21{ 19{
22 unsigned long stack_start, stack_end, flags;
23 int i, cpu;
24
25 /*
26 * The most common case is that we are in the task stack:
27 */
28 stack_start = (unsigned long)task->thread_info;
29 stack_end = stack_start + THREAD_SIZE;
30
31 if (in_range(stack_start, stack, stack_end))
32 return stack_end;
33
34 /*
35 * We are in an interrupt if irqstackptr is set:
36 */
37 raw_local_irq_save(flags);
38 cpu = safe_smp_processor_id();
39 stack_end = (unsigned long)cpu_pda(cpu)->irqstackptr;
40
41 if (stack_end) {
42 stack_start = stack_end & ~(IRQSTACKSIZE-1);
43 if (in_range(stack_start, stack, stack_end))
44 goto out_restore;
45 /*
46 * We get here if we are in an IRQ context but we
47 * are also in an exception stack.
48 */
49 }
50
51 /*
52 * Iterate over all exception stacks, and figure out whether
53 * 'stack' is in one of them:
54 */
55 for (i = 0; i < N_EXCEPTION_STACKS; i++) {
56 /*
57 * set 'end' to the end of the exception stack.
58 */
59 stack_end = per_cpu(init_tss, cpu).ist[i];
60 stack_start = stack_end - EXCEPTION_STKSZ;
61
62 /*
63 * Is 'stack' above this exception frame's end?
64 * If yes then skip to the next frame.
65 */
66 if (stack >= stack_end)
67 continue;
68 /*
69 * Is 'stack' above this exception frame's start address?
70 * If yes then we found the right frame.
71 */
72 if (stack >= stack_start)
73 goto out_restore;
74
75 /*
76 * If this is a debug stack, and if it has a larger size than
77 * the usual exception stacks, then 'stack' might still
78 * be within the lower portion of the debug stack:
79 */
80#if DEBUG_STKSZ > EXCEPTION_STKSZ
81 if (i == DEBUG_STACK - 1 && stack >= stack_end - DEBUG_STKSZ) {
82 /*
83 * Black magic. A large debug stack is composed of
84 * multiple exception stack entries, which we
85 * iterate through now. Dont look:
86 */
87 do {
88 stack_end -= EXCEPTION_STKSZ;
89 stack_start -= EXCEPTION_STKSZ;
90 } while (stack < stack_start);
91
92 goto out_restore;
93 }
94#endif
95 }
96 /*
97 * Ok, 'stack' is not pointing to any of the system stacks.
98 */
99 stack_end = 0;
100
101out_restore:
102 raw_local_irq_restore(flags);
103
104 return stack_end;
105} 20}
106 21
107 22static int save_stack_stack(void *data, char *name)
108/*
109 * Save stack-backtrace addresses into a stack_trace buffer:
110 */
111static inline unsigned long
112save_context_stack(struct stack_trace *trace, unsigned int skip,
113 unsigned long stack, unsigned long stack_end)
114{ 23{
115 unsigned long addr; 24 struct stack_trace *trace = (struct stack_trace *)data;
116 25 return trace->all_contexts ? 0 : -1;
117#ifdef CONFIG_FRAME_POINTER 26}
118 unsigned long prev_stack = 0;
119 27
120 while (in_range(prev_stack, stack, stack_end)) { 28static void save_stack_address(void *data, unsigned long addr)
121 pr_debug("stack: %p\n", (void *)stack); 29{
122 addr = (unsigned long)(((unsigned long *)stack)[1]); 30 struct stack_trace *trace = (struct stack_trace *)data;
123 pr_debug("addr: %p\n", (void *)addr); 31 if (trace->skip > 0) {
124 if (!skip) 32 trace->skip--;
125 trace->entries[trace->nr_entries++] = addr-1; 33 return;
126 else
127 skip--;
128 if (trace->nr_entries >= trace->max_entries)
129 break;
130 if (!addr)
131 return 0;
132 /*
133 * Stack frames must go forwards (otherwise a loop could
134 * happen if the stackframe is corrupted), so we move
135 * prev_stack forwards:
136 */
137 prev_stack = stack;
138 stack = (unsigned long)(((unsigned long *)stack)[0]);
139 }
140 pr_debug("invalid: %p\n", (void *)stack);
141#else
142 while (stack < stack_end) {
143 addr = ((unsigned long *)stack)[0];
144 stack += sizeof(long);
145 if (__kernel_text_address(addr)) {
146 if (!skip)
147 trace->entries[trace->nr_entries++] = addr-1;
148 else
149 skip--;
150 if (trace->nr_entries >= trace->max_entries)
151 break;
152 }
153 } 34 }
154#endif 35 if (trace->nr_entries < trace->max_entries - 1)
155 return stack; 36 trace->entries[trace->nr_entries++] = addr;
156} 37}
157 38
158#define MAX_STACKS 10 39static struct stacktrace_ops save_stack_ops = {
40 .warning = save_stack_warning,
41 .warning_symbol = save_stack_warning_symbol,
42 .stack = save_stack_stack,
43 .address = save_stack_address,
44};
159 45
160/* 46/*
161 * Save stack-backtrace addresses into a stack_trace buffer. 47 * Save stack-backtrace addresses into a stack_trace buffer.
162 * If all_contexts is set, all contexts (hardirq, softirq and process)
163 * are saved. If not set then only the current context is saved.
164 */ 48 */
165void save_stack_trace(struct stack_trace *trace, 49void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
166 struct task_struct *task, int all_contexts,
167 unsigned int skip)
168{ 50{
169 unsigned long stack = (unsigned long)&stack; 51 dump_trace(task, NULL, NULL, &save_stack_ops, trace);
170 int i, nr_stacks = 0, stacks_done[MAX_STACKS]; 52 trace->entries[trace->nr_entries++] = ULONG_MAX;
171
172 WARN_ON(trace->nr_entries || !trace->max_entries);
173
174 if (!task)
175 task = current;
176
177 pr_debug("task: %p, ti: %p\n", task, task->thread_info);
178
179 if (!task || task == current) {
180 /* Grab rbp right from our regs: */
181 asm ("mov %%rbp, %0" : "=r" (stack));
182 pr_debug("rbp: %p\n", (void *)stack);
183 } else {
184 /* rbp is the last reg pushed by switch_to(): */
185 stack = task->thread.rsp;
186 pr_debug("other task rsp: %p\n", (void *)stack);
187 stack = (unsigned long)(((unsigned long *)stack)[0]);
188 pr_debug("other task rbp: %p\n", (void *)stack);
189 }
190
191 while (1) {
192 unsigned long stack_end = get_stack_end(task, stack);
193
194 pr_debug("stack: %p\n", (void *)stack);
195 pr_debug("stack end: %p\n", (void *)stack_end);
196
197 /*
198 * Invalid stack addres?
199 */
200 if (!stack_end)
201 return;
202 /*
203 * Were we in this stack already? (recursion)
204 */
205 for (i = 0; i < nr_stacks; i++)
206 if (stacks_done[i] == stack_end)
207 return;
208 stacks_done[nr_stacks] = stack_end;
209
210 stack = save_context_stack(trace, skip, stack, stack_end);
211 if (!all_contexts || !stack ||
212 trace->nr_entries >= trace->max_entries)
213 return;
214 trace->entries[trace->nr_entries++] = ULONG_MAX;
215 if (trace->nr_entries >= trace->max_entries)
216 return;
217 if (++nr_stacks >= MAX_STACKS)
218 return;
219 }
220} 53}
54EXPORT_SYMBOL(save_stack_trace);
221 55
diff --git a/arch/x86_64/kernel/suspend_asm.S b/arch/x86_64/kernel/suspend_asm.S
index 320b6fb00cca..bfbe00763c68 100644
--- a/arch/x86_64/kernel/suspend_asm.S
+++ b/arch/x86_64/kernel/suspend_asm.S
@@ -54,7 +54,7 @@ ENTRY(restore_image)
54 movq %rcx, %cr3; 54 movq %rcx, %cr3;
55 movq %rax, %cr4; # turn PGE back on 55 movq %rax, %cr4; # turn PGE back on
56 56
57 movq pagedir_nosave(%rip), %rdx 57 movq restore_pblist(%rip), %rdx
58loop: 58loop:
59 testq %rdx, %rdx 59 testq %rdx, %rdx
60 jz done 60 jz done
diff --git a/arch/x86_64/kernel/tce.c b/arch/x86_64/kernel/tce.c
index 5530dda3f27a..cbabfdf78e06 100644
--- a/arch/x86_64/kernel/tce.c
+++ b/arch/x86_64/kernel/tce.c
@@ -1,4 +1,6 @@
1/* 1/*
2 * This file manages the translation entries for the IBM Calgary IOMMU.
3 *
2 * Derived from arch/powerpc/platforms/pseries/iommu.c 4 * Derived from arch/powerpc/platforms/pseries/iommu.c
3 * 5 *
4 * Copyright (C) IBM Corporation, 2006 6 * Copyright (C) IBM Corporation, 2006
@@ -104,14 +106,6 @@ static int tce_table_setparms(struct pci_dev *dev, struct iommu_table *tbl)
104 /* set the tce table size - measured in entries */ 106 /* set the tce table size - measured in entries */
105 tbl->it_size = table_size_to_number_of_entries(specified_table_size); 107 tbl->it_size = table_size_to_number_of_entries(specified_table_size);
106 108
107 tbl->it_base = (unsigned long)tce_table_kva[dev->bus->number];
108 if (!tbl->it_base) {
109 printk(KERN_ERR "Calgary: iommu_table_setparms: "
110 "no table allocated?!\n");
111 ret = -ENOMEM;
112 goto done;
113 }
114
115 /* 109 /*
116 * number of bytes needed for the bitmap size in number of 110 * number of bytes needed for the bitmap size in number of
117 * entries; we need one bit per entry 111 * entries; we need one bit per entry
@@ -160,8 +154,6 @@ int build_tce_table(struct pci_dev *dev, void __iomem *bbar)
160 if (ret) 154 if (ret)
161 goto free_tbl; 155 goto free_tbl;
162 156
163 tce_free(tbl, 0, tbl->it_size);
164
165 tbl->bbar = bbar; 157 tbl->bbar = bbar;
166 158
167 /* 159 /*
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 7a9b18224182..1c255ee76e7c 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -24,6 +24,8 @@
24#include <linux/device.h> 24#include <linux/device.h>
25#include <linux/sysdev.h> 25#include <linux/sysdev.h>
26#include <linux/bcd.h> 26#include <linux/bcd.h>
27#include <linux/notifier.h>
28#include <linux/cpu.h>
27#include <linux/kallsyms.h> 29#include <linux/kallsyms.h>
28#include <linux/acpi.h> 30#include <linux/acpi.h>
29#ifdef CONFIG_ACPI 31#ifdef CONFIG_ACPI
@@ -39,9 +41,7 @@
39#include <asm/sections.h> 41#include <asm/sections.h>
40#include <linux/cpufreq.h> 42#include <linux/cpufreq.h>
41#include <linux/hpet.h> 43#include <linux/hpet.h>
42#ifdef CONFIG_X86_LOCAL_APIC
43#include <asm/apic.h> 44#include <asm/apic.h>
44#endif
45 45
46#ifdef CONFIG_CPU_FREQ 46#ifdef CONFIG_CPU_FREQ
47static void cpufreq_delayed_get(void); 47static void cpufreq_delayed_get(void);
@@ -49,7 +49,7 @@ static void cpufreq_delayed_get(void);
49extern void i8254_timer_resume(void); 49extern void i8254_timer_resume(void);
50extern int using_apic_timer; 50extern int using_apic_timer;
51 51
52static char *time_init_gtod(void); 52static char *timename = NULL;
53 53
54DEFINE_SPINLOCK(rtc_lock); 54DEFINE_SPINLOCK(rtc_lock);
55EXPORT_SYMBOL(rtc_lock); 55EXPORT_SYMBOL(rtc_lock);
@@ -187,20 +187,15 @@ unsigned long profile_pc(struct pt_regs *regs)
187{ 187{
188 unsigned long pc = instruction_pointer(regs); 188 unsigned long pc = instruction_pointer(regs);
189 189
190 /* Assume the lock function has either no stack frame or only a single 190 /* Assume the lock function has either no stack frame or a copy
191 word. This checks if the address on the stack looks like a kernel 191 of eflags from PUSHF
192 text address. 192 Eflags always has bits 22 and up cleared unlike kernel addresses. */
193 There is a small window for false hits, but in that case the tick
194 is just accounted to the spinlock function.
195 Better would be to write these functions in assembler again
196 and check exactly. */
197 if (!user_mode(regs) && in_lock_functions(pc)) { 193 if (!user_mode(regs) && in_lock_functions(pc)) {
198 char *v = *(char **)regs->rsp; 194 unsigned long *sp = (unsigned long *)regs->rsp;
199 if ((v >= _stext && v <= _etext) || 195 if (sp[0] >> 22)
200 (v >= _sinittext && v <= _einittext) || 196 return sp[0];
201 (v >= (char *)MODULES_VADDR && v <= (char *)MODULES_END)) 197 if (sp[1] >> 22)
202 return (unsigned long)v; 198 return sp[1];
203 return ((unsigned long *)regs->rsp)[1];
204 } 199 }
205 return pc; 200 return pc;
206} 201}
@@ -281,6 +276,7 @@ static void set_rtc_mmss(unsigned long nowtime)
281 * Note: This function is required to return accurate 276 * Note: This function is required to return accurate
282 * time even in the absence of multiple timer ticks. 277 * time even in the absence of multiple timer ticks.
283 */ 278 */
279static inline unsigned long long cycles_2_ns(unsigned long long cyc);
284unsigned long long monotonic_clock(void) 280unsigned long long monotonic_clock(void)
285{ 281{
286 unsigned long seq; 282 unsigned long seq;
@@ -305,8 +301,7 @@ unsigned long long monotonic_clock(void)
305 base = monotonic_base; 301 base = monotonic_base;
306 } while (read_seqretry(&xtime_lock, seq)); 302 } while (read_seqretry(&xtime_lock, seq));
307 this_offset = get_cycles_sync(); 303 this_offset = get_cycles_sync();
308 /* FIXME: 1000 or 1000000? */ 304 offset = cycles_2_ns(this_offset - last_offset);
309 offset = (this_offset - last_offset)*1000 / cpu_khz;
310 } 305 }
311 return base + offset; 306 return base + offset;
312} 307}
@@ -410,8 +405,7 @@ void main_timer_handler(struct pt_regs *regs)
410 offset %= USEC_PER_TICK; 405 offset %= USEC_PER_TICK;
411 } 406 }
412 407
413 /* FIXME: 1000 or 1000000? */ 408 monotonic_base += cycles_2_ns(tsc - vxtime.last_tsc);
414 monotonic_base += (tsc - vxtime.last_tsc) * 1000000 / cpu_khz;
415 409
416 vxtime.last_tsc = tsc - vxtime.quot * delay / vxtime.tsc_quot; 410 vxtime.last_tsc = tsc - vxtime.quot * delay / vxtime.tsc_quot;
417 411
@@ -441,12 +435,8 @@ void main_timer_handler(struct pt_regs *regs)
441 * have to call the local interrupt handler. 435 * have to call the local interrupt handler.
442 */ 436 */
443 437
444#ifndef CONFIG_X86_LOCAL_APIC
445 profile_tick(CPU_PROFILING, regs);
446#else
447 if (!using_apic_timer) 438 if (!using_apic_timer)
448 smp_local_timer_interrupt(regs); 439 smp_local_timer_interrupt(regs);
449#endif
450 440
451/* 441/*
452 * If we have an externally synchronized Linux clock, then update CMOS clock 442 * If we have an externally synchronized Linux clock, then update CMOS clock
@@ -470,10 +460,8 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
470 if (apic_runs_main_timer > 1) 460 if (apic_runs_main_timer > 1)
471 return IRQ_HANDLED; 461 return IRQ_HANDLED;
472 main_timer_handler(regs); 462 main_timer_handler(regs);
473#ifdef CONFIG_X86_LOCAL_APIC
474 if (using_apic_timer) 463 if (using_apic_timer)
475 smp_send_timer_broadcast_ipi(); 464 smp_send_timer_broadcast_ipi();
476#endif
477 return IRQ_HANDLED; 465 return IRQ_HANDLED;
478} 466}
479 467
@@ -893,11 +881,17 @@ static struct irqaction irq0 = {
893 timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL 881 timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL
894}; 882};
895 883
896void __init time_init(void) 884static int __cpuinit
885time_cpu_notifier(struct notifier_block *nb, unsigned long action, void *hcpu)
897{ 886{
898 char *timename; 887 unsigned cpu = (unsigned long) hcpu;
899 char *gtod; 888 if (action == CPU_ONLINE)
889 vsyscall_set_cpu(cpu);
890 return NOTIFY_DONE;
891}
900 892
893void __init time_init(void)
894{
901 if (nohpet) 895 if (nohpet)
902 vxtime.hpet_address = 0; 896 vxtime.hpet_address = 0;
903 897
@@ -931,18 +925,17 @@ void __init time_init(void)
931 } 925 }
932 926
933 vxtime.mode = VXTIME_TSC; 927 vxtime.mode = VXTIME_TSC;
934 gtod = time_init_gtod();
935
936 printk(KERN_INFO "time.c: Using %ld.%06ld MHz WALL %s GTOD %s timer.\n",
937 vxtime_hz / 1000000, vxtime_hz % 1000000, timename, gtod);
938 printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n",
939 cpu_khz / 1000, cpu_khz % 1000);
940 vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz; 928 vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz;
941 vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz; 929 vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz;
942 vxtime.last_tsc = get_cycles_sync(); 930 vxtime.last_tsc = get_cycles_sync();
931 set_cyc2ns_scale(cpu_khz);
943 setup_irq(0, &irq0); 932 setup_irq(0, &irq0);
933 hotcpu_notifier(time_cpu_notifier, 0);
934 time_cpu_notifier(NULL, CPU_ONLINE, (void *)(long)smp_processor_id());
944 935
945 set_cyc2ns_scale(cpu_khz); 936#ifndef CONFIG_SMP
937 time_init_gtod();
938#endif
946} 939}
947 940
948/* 941/*
@@ -973,12 +966,18 @@ __cpuinit int unsynchronized_tsc(void)
973/* 966/*
974 * Decide what mode gettimeofday should use. 967 * Decide what mode gettimeofday should use.
975 */ 968 */
976__init static char *time_init_gtod(void) 969void time_init_gtod(void)
977{ 970{
978 char *timetype; 971 char *timetype;
979 972
980 if (unsynchronized_tsc()) 973 if (unsynchronized_tsc())
981 notsc = 1; 974 notsc = 1;
975
976 if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP))
977 vgetcpu_mode = VGETCPU_RDTSCP;
978 else
979 vgetcpu_mode = VGETCPU_LSL;
980
982 if (vxtime.hpet_address && notsc) { 981 if (vxtime.hpet_address && notsc) {
983 timetype = hpet_use_timer ? "HPET" : "PIT/HPET"; 982 timetype = hpet_use_timer ? "HPET" : "PIT/HPET";
984 if (hpet_use_timer) 983 if (hpet_use_timer)
@@ -1001,7 +1000,16 @@ __init static char *time_init_gtod(void)
1001 timetype = hpet_use_timer ? "HPET/TSC" : "PIT/TSC"; 1000 timetype = hpet_use_timer ? "HPET/TSC" : "PIT/TSC";
1002 vxtime.mode = VXTIME_TSC; 1001 vxtime.mode = VXTIME_TSC;
1003 } 1002 }
1004 return timetype; 1003
1004 printk(KERN_INFO "time.c: Using %ld.%06ld MHz WALL %s GTOD %s timer.\n",
1005 vxtime_hz / 1000000, vxtime_hz % 1000000, timename, timetype);
1006 printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n",
1007 cpu_khz / 1000, cpu_khz % 1000);
1008 vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz;
1009 vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz;
1010 vxtime.last_tsc = get_cycles_sync();
1011
1012 set_cyc2ns_scale(cpu_khz);
1005} 1013}
1006 1014
1007__setup("report_lost_ticks", time_setup); 1015__setup("report_lost_ticks", time_setup);
@@ -1031,8 +1039,16 @@ static int timer_resume(struct sys_device *dev)
1031 unsigned long flags; 1039 unsigned long flags;
1032 unsigned long sec; 1040 unsigned long sec;
1033 unsigned long ctime = get_cmos_time(); 1041 unsigned long ctime = get_cmos_time();
1034 unsigned long sleep_length = (ctime - sleep_start) * HZ; 1042 long sleep_length = (ctime - sleep_start) * HZ;
1035 1043
1044 if (sleep_length < 0) {
1045 printk(KERN_WARNING "Time skew detected in timer resume!\n");
1046 /* The time after the resume must not be earlier than the time
1047 * before the suspend or some nasty things will happen
1048 */
1049 sleep_length = 0;
1050 ctime = sleep_start;
1051 }
1036 if (vxtime.hpet_address) 1052 if (vxtime.hpet_address)
1037 hpet_reenable(); 1053 hpet_reenable();
1038 else 1054 else
@@ -1148,23 +1164,25 @@ int hpet_rtc_timer_init(void)
1148 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ; 1164 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
1149 1165
1150 local_irq_save(flags); 1166 local_irq_save(flags);
1167
1151 cnt = hpet_readl(HPET_COUNTER); 1168 cnt = hpet_readl(HPET_COUNTER);
1152 cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq); 1169 cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
1153 hpet_writel(cnt, HPET_T1_CMP); 1170 hpet_writel(cnt, HPET_T1_CMP);
1154 hpet_t1_cmp = cnt; 1171 hpet_t1_cmp = cnt;
1155 local_irq_restore(flags);
1156 1172
1157 cfg = hpet_readl(HPET_T1_CFG); 1173 cfg = hpet_readl(HPET_T1_CFG);
1158 cfg &= ~HPET_TN_PERIODIC; 1174 cfg &= ~HPET_TN_PERIODIC;
1159 cfg |= HPET_TN_ENABLE | HPET_TN_32BIT; 1175 cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
1160 hpet_writel(cfg, HPET_T1_CFG); 1176 hpet_writel(cfg, HPET_T1_CFG);
1161 1177
1178 local_irq_restore(flags);
1179
1162 return 1; 1180 return 1;
1163} 1181}
1164 1182
1165static void hpet_rtc_timer_reinit(void) 1183static void hpet_rtc_timer_reinit(void)
1166{ 1184{
1167 unsigned int cfg, cnt; 1185 unsigned int cfg, cnt, ticks_per_int, lost_ints;
1168 1186
1169 if (unlikely(!(PIE_on | AIE_on | UIE_on))) { 1187 if (unlikely(!(PIE_on | AIE_on | UIE_on))) {
1170 cfg = hpet_readl(HPET_T1_CFG); 1188 cfg = hpet_readl(HPET_T1_CFG);
@@ -1179,10 +1197,33 @@ static void hpet_rtc_timer_reinit(void)
1179 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ; 1197 hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
1180 1198
1181 /* It is more accurate to use the comparator value than current count.*/ 1199 /* It is more accurate to use the comparator value than current count.*/
1182 cnt = hpet_t1_cmp; 1200 ticks_per_int = hpet_tick * HZ / hpet_rtc_int_freq;
1183 cnt += hpet_tick*HZ/hpet_rtc_int_freq; 1201 hpet_t1_cmp += ticks_per_int;
1184 hpet_writel(cnt, HPET_T1_CMP); 1202 hpet_writel(hpet_t1_cmp, HPET_T1_CMP);
1185 hpet_t1_cmp = cnt; 1203
1204 /*
1205 * If the interrupt handler was delayed too long, the write above tries
1206 * to schedule the next interrupt in the past and the hardware would
1207 * not interrupt until the counter had wrapped around.
1208 * So we have to check that the comparator wasn't set to a past time.
1209 */
1210 cnt = hpet_readl(HPET_COUNTER);
1211 if (unlikely((int)(cnt - hpet_t1_cmp) > 0)) {
1212 lost_ints = (cnt - hpet_t1_cmp) / ticks_per_int + 1;
1213 /* Make sure that, even with the time needed to execute
1214 * this code, the next scheduled interrupt has been moved
1215 * back to the future: */
1216 lost_ints++;
1217
1218 hpet_t1_cmp += lost_ints * ticks_per_int;
1219 hpet_writel(hpet_t1_cmp, HPET_T1_CMP);
1220
1221 if (PIE_on)
1222 PIE_count += lost_ints;
1223
1224 printk(KERN_WARNING "rtc: lost some interrupts at %ldHz.\n",
1225 hpet_rtc_int_freq);
1226 }
1186} 1227}
1187 1228
1188/* 1229/*
diff --git a/arch/x86_64/kernel/trampoline.S b/arch/x86_64/kernel/trampoline.S
index 23a03eb91fc7..c79b99a9e2f6 100644
--- a/arch/x86_64/kernel/trampoline.S
+++ b/arch/x86_64/kernel/trampoline.S
@@ -64,7 +64,7 @@ idt_48:
64 .word 0, 0 # idt base = 0L 64 .word 0, 0 # idt base = 0L
65 65
66gdt_48: 66gdt_48:
67 .short __KERNEL32_CS + 7 # gdt limit 67 .short GDT_ENTRIES*8 - 1 # gdt limit
68 .long cpu_gdt_table-__START_KERNEL_map 68 .long cpu_gdt_table-__START_KERNEL_map
69 69
70.globl trampoline_end 70.globl trampoline_end
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index b1249774d1e8..01f2a8d254c2 100644
--- a/arch/x86_64/kernel/traps.c
+++ b/arch/x86_64/kernel/traps.c
@@ -45,6 +45,7 @@
45#include <asm/pda.h> 45#include <asm/pda.h>
46#include <asm/proto.h> 46#include <asm/proto.h>
47#include <asm/nmi.h> 47#include <asm/nmi.h>
48#include <asm/stacktrace.h>
48 49
49asmlinkage void divide_error(void); 50asmlinkage void divide_error(void);
50asmlinkage void debug(void); 51asmlinkage void debug(void);
@@ -142,7 +143,7 @@ void printk_address(unsigned long address)
142#endif 143#endif
143 144
144static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, 145static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
145 unsigned *usedp, const char **idp) 146 unsigned *usedp, char **idp)
146{ 147{
147 static char ids[][8] = { 148 static char ids[][8] = {
148 [DEBUG_STACK - 1] = "#DB", 149 [DEBUG_STACK - 1] = "#DB",
@@ -161,26 +162,7 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
161 * 'stack' is in one of them: 162 * 'stack' is in one of them:
162 */ 163 */
163 for (k = 0; k < N_EXCEPTION_STACKS; k++) { 164 for (k = 0; k < N_EXCEPTION_STACKS; k++) {
164 unsigned long end; 165 unsigned long end = per_cpu(orig_ist, cpu).ist[k];
165
166 /*
167 * set 'end' to the end of the exception stack.
168 */
169 switch (k + 1) {
170 /*
171 * TODO: this block is not needed i think, because
172 * setup64.c:cpu_init() sets up t->ist[DEBUG_STACK]
173 * properly too.
174 */
175#if DEBUG_STKSZ > EXCEPTION_STKSZ
176 case DEBUG_STACK:
177 end = cpu_pda(cpu)->debugstack + DEBUG_STKSZ;
178 break;
179#endif
180 default:
181 end = per_cpu(orig_ist, cpu).ist[k];
182 break;
183 }
184 /* 166 /*
185 * Is 'stack' above this exception frame's end? 167 * Is 'stack' above this exception frame's end?
186 * If yes then skip to the next frame. 168 * If yes then skip to the next frame.
@@ -234,13 +216,19 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
234 return NULL; 216 return NULL;
235} 217}
236 218
237static int show_trace_unwind(struct unwind_frame_info *info, void *context) 219struct ops_and_data {
220 struct stacktrace_ops *ops;
221 void *data;
222};
223
224static int dump_trace_unwind(struct unwind_frame_info *info, void *context)
238{ 225{
226 struct ops_and_data *oad = (struct ops_and_data *)context;
239 int n = 0; 227 int n = 0;
240 228
241 while (unwind(info) == 0 && UNW_PC(info)) { 229 while (unwind(info) == 0 && UNW_PC(info)) {
242 n++; 230 n++;
243 printk_address(UNW_PC(info)); 231 oad->ops->address(oad->data, UNW_PC(info));
244 if (arch_unw_user_mode(info)) 232 if (arch_unw_user_mode(info))
245 break; 233 break;
246 } 234 }
@@ -254,45 +242,53 @@ static int show_trace_unwind(struct unwind_frame_info *info, void *context)
254 * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack 242 * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
255 */ 243 */
256 244
257void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * stack) 245void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * stack,
246 struct stacktrace_ops *ops, void *data)
258{ 247{
259 const unsigned cpu = safe_smp_processor_id(); 248 const unsigned cpu = smp_processor_id();
260 unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr; 249 unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr;
261 unsigned used = 0; 250 unsigned used = 0;
262 251
263 printk("\nCall Trace:\n");
264
265 if (!tsk) 252 if (!tsk)
266 tsk = current; 253 tsk = current;
267 254
268 if (call_trace >= 0) { 255 if (call_trace >= 0) {
269 int unw_ret = 0; 256 int unw_ret = 0;
270 struct unwind_frame_info info; 257 struct unwind_frame_info info;
258 struct ops_and_data oad = { .ops = ops, .data = data };
271 259
272 if (regs) { 260 if (regs) {
273 if (unwind_init_frame_info(&info, tsk, regs) == 0) 261 if (unwind_init_frame_info(&info, tsk, regs) == 0)
274 unw_ret = show_trace_unwind(&info, NULL); 262 unw_ret = dump_trace_unwind(&info, &oad);
275 } else if (tsk == current) 263 } else if (tsk == current)
276 unw_ret = unwind_init_running(&info, show_trace_unwind, NULL); 264 unw_ret = unwind_init_running(&info, dump_trace_unwind, &oad);
277 else { 265 else {
278 if (unwind_init_blocked(&info, tsk) == 0) 266 if (unwind_init_blocked(&info, tsk) == 0)
279 unw_ret = show_trace_unwind(&info, NULL); 267 unw_ret = dump_trace_unwind(&info, &oad);
280 } 268 }
281 if (unw_ret > 0) { 269 if (unw_ret > 0) {
282 if (call_trace == 1 && !arch_unw_user_mode(&info)) { 270 if (call_trace == 1 && !arch_unw_user_mode(&info)) {
283 print_symbol("DWARF2 unwinder stuck at %s\n", 271 ops->warning_symbol(data, "DWARF2 unwinder stuck at %s\n",
284 UNW_PC(&info)); 272 UNW_PC(&info));
285 if ((long)UNW_SP(&info) < 0) { 273 if ((long)UNW_SP(&info) < 0) {
286 printk("Leftover inexact backtrace:\n"); 274 ops->warning(data, "Leftover inexact backtrace:\n");
287 stack = (unsigned long *)UNW_SP(&info); 275 stack = (unsigned long *)UNW_SP(&info);
276 if (!stack)
277 return;
288 } else 278 } else
289 printk("Full inexact backtrace again:\n"); 279 ops->warning(data, "Full inexact backtrace again:\n");
290 } else if (call_trace >= 1) 280 } else if (call_trace >= 1)
291 return; 281 return;
292 else 282 else
293 printk("Full inexact backtrace again:\n"); 283 ops->warning(data, "Full inexact backtrace again:\n");
294 } else 284 } else
295 printk("Inexact backtrace:\n"); 285 ops->warning(data, "Inexact backtrace:\n");
286 }
287 if (!stack) {
288 unsigned long dummy;
289 stack = &dummy;
290 if (tsk && tsk != current)
291 stack = (unsigned long *)tsk->thread.rsp;
296 } 292 }
297 293
298 /* 294 /*
@@ -303,7 +299,9 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s
303#define HANDLE_STACK(cond) \ 299#define HANDLE_STACK(cond) \
304 do while (cond) { \ 300 do while (cond) { \
305 unsigned long addr = *stack++; \ 301 unsigned long addr = *stack++; \
306 if (kernel_text_address(addr)) { \ 302 if (oops_in_progress ? \
303 __kernel_text_address(addr) : \
304 kernel_text_address(addr)) { \
307 /* \ 305 /* \
308 * If the address is either in the text segment of the \ 306 * If the address is either in the text segment of the \
309 * kernel, or in the region which contains vmalloc'ed \ 307 * kernel, or in the region which contains vmalloc'ed \
@@ -312,7 +310,7 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s
312 * down the cause of the crash will be able to figure \ 310 * down the cause of the crash will be able to figure \
313 * out the call path that was taken. \ 311 * out the call path that was taken. \
314 */ \ 312 */ \
315 printk_address(addr); \ 313 ops->address(data, addr); \
316 } \ 314 } \
317 } while (0) 315 } while (0)
318 316
@@ -321,16 +319,17 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s
321 * current stack address. If the stacks consist of nested 319 * current stack address. If the stacks consist of nested
322 * exceptions 320 * exceptions
323 */ 321 */
324 for ( ; ; ) { 322 for (;;) {
325 const char *id; 323 char *id;
326 unsigned long *estack_end; 324 unsigned long *estack_end;
327 estack_end = in_exception_stack(cpu, (unsigned long)stack, 325 estack_end = in_exception_stack(cpu, (unsigned long)stack,
328 &used, &id); 326 &used, &id);
329 327
330 if (estack_end) { 328 if (estack_end) {
331 printk(" <%s>", id); 329 if (ops->stack(data, id) < 0)
330 break;
332 HANDLE_STACK (stack < estack_end); 331 HANDLE_STACK (stack < estack_end);
333 printk(" <EOE>"); 332 ops->stack(data, "<EOE>");
334 /* 333 /*
335 * We link to the next stack via the 334 * We link to the next stack via the
336 * second-to-last pointer (index -2 to end) in the 335 * second-to-last pointer (index -2 to end) in the
@@ -345,7 +344,8 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s
345 (IRQSTACKSIZE - 64) / sizeof(*irqstack); 344 (IRQSTACKSIZE - 64) / sizeof(*irqstack);
346 345
347 if (stack >= irqstack && stack < irqstack_end) { 346 if (stack >= irqstack && stack < irqstack_end) {
348 printk(" <IRQ>"); 347 if (ops->stack(data, "IRQ") < 0)
348 break;
349 HANDLE_STACK (stack < irqstack_end); 349 HANDLE_STACK (stack < irqstack_end);
350 /* 350 /*
351 * We link to the next stack (which would be 351 * We link to the next stack (which would be
@@ -354,7 +354,7 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s
354 */ 354 */
355 stack = (unsigned long *) (irqstack_end[-1]); 355 stack = (unsigned long *) (irqstack_end[-1]);
356 irqstack_end = NULL; 356 irqstack_end = NULL;
357 printk(" <EOI>"); 357 ops->stack(data, "EOI");
358 continue; 358 continue;
359 } 359 }
360 } 360 }
@@ -362,19 +362,57 @@ void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s
362 } 362 }
363 363
364 /* 364 /*
365 * This prints the process stack: 365 * This handles the process stack:
366 */ 366 */
367 HANDLE_STACK (((long) stack & (THREAD_SIZE-1)) != 0); 367 HANDLE_STACK (((long) stack & (THREAD_SIZE-1)) != 0);
368#undef HANDLE_STACK 368#undef HANDLE_STACK
369}
370EXPORT_SYMBOL(dump_trace);
371
372static void
373print_trace_warning_symbol(void *data, char *msg, unsigned long symbol)
374{
375 print_symbol(msg, symbol);
376 printk("\n");
377}
378
379static void print_trace_warning(void *data, char *msg)
380{
381 printk("%s\n", msg);
382}
383
384static int print_trace_stack(void *data, char *name)
385{
386 printk(" <%s> ", name);
387 return 0;
388}
389
390static void print_trace_address(void *data, unsigned long addr)
391{
392 printk_address(addr);
393}
394
395static struct stacktrace_ops print_trace_ops = {
396 .warning = print_trace_warning,
397 .warning_symbol = print_trace_warning_symbol,
398 .stack = print_trace_stack,
399 .address = print_trace_address,
400};
369 401
402void
403show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack)
404{
405 printk("\nCall Trace:\n");
406 dump_trace(tsk, regs, stack, &print_trace_ops, NULL);
370 printk("\n"); 407 printk("\n");
371} 408}
372 409
373static void _show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long * rsp) 410static void
411_show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *rsp)
374{ 412{
375 unsigned long *stack; 413 unsigned long *stack;
376 int i; 414 int i;
377 const int cpu = safe_smp_processor_id(); 415 const int cpu = smp_processor_id();
378 unsigned long *irqstack_end = (unsigned long *) (cpu_pda(cpu)->irqstackptr); 416 unsigned long *irqstack_end = (unsigned long *) (cpu_pda(cpu)->irqstackptr);
379 unsigned long *irqstack = (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE); 417 unsigned long *irqstack = (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE);
380 418
@@ -428,7 +466,7 @@ void show_registers(struct pt_regs *regs)
428 int i; 466 int i;
429 int in_kernel = !user_mode(regs); 467 int in_kernel = !user_mode(regs);
430 unsigned long rsp; 468 unsigned long rsp;
431 const int cpu = safe_smp_processor_id(); 469 const int cpu = smp_processor_id();
432 struct task_struct *cur = cpu_pda(cpu)->pcurrent; 470 struct task_struct *cur = cpu_pda(cpu)->pcurrent;
433 471
434 rsp = regs->rsp; 472 rsp = regs->rsp;
@@ -503,9 +541,11 @@ static unsigned int die_nest_count;
503 541
504unsigned __kprobes long oops_begin(void) 542unsigned __kprobes long oops_begin(void)
505{ 543{
506 int cpu = safe_smp_processor_id(); 544 int cpu = smp_processor_id();
507 unsigned long flags; 545 unsigned long flags;
508 546
547 oops_enter();
548
509 /* racy, but better than risking deadlock. */ 549 /* racy, but better than risking deadlock. */
510 local_irq_save(flags); 550 local_irq_save(flags);
511 if (!spin_trylock(&die_lock)) { 551 if (!spin_trylock(&die_lock)) {
@@ -534,6 +574,7 @@ void __kprobes oops_end(unsigned long flags)
534 spin_unlock_irqrestore(&die_lock, flags); 574 spin_unlock_irqrestore(&die_lock, flags);
535 if (panic_on_oops) 575 if (panic_on_oops)
536 panic("Fatal exception"); 576 panic("Fatal exception");
577 oops_exit();
537} 578}
538 579
539void __kprobes __die(const char * str, struct pt_regs * regs, long err) 580void __kprobes __die(const char * str, struct pt_regs * regs, long err)
@@ -570,7 +611,7 @@ void die(const char * str, struct pt_regs * regs, long err)
570 do_exit(SIGSEGV); 611 do_exit(SIGSEGV);
571} 612}
572 613
573void __kprobes die_nmi(char *str, struct pt_regs *regs) 614void __kprobes die_nmi(char *str, struct pt_regs *regs, int do_panic)
574{ 615{
575 unsigned long flags = oops_begin(); 616 unsigned long flags = oops_begin();
576 617
@@ -578,13 +619,12 @@ void __kprobes die_nmi(char *str, struct pt_regs *regs)
578 * We are in trouble anyway, lets at least try 619 * We are in trouble anyway, lets at least try
579 * to get a message out. 620 * to get a message out.
580 */ 621 */
581 printk(str, safe_smp_processor_id()); 622 printk(str, smp_processor_id());
582 show_registers(regs); 623 show_registers(regs);
583 if (kexec_should_crash(current)) 624 if (kexec_should_crash(current))
584 crash_kexec(regs); 625 crash_kexec(regs);
585 if (panic_on_timeout || panic_on_oops) 626 if (do_panic || panic_on_oops)
586 panic("nmi watchdog"); 627 panic("Non maskable interrupt");
587 printk("console shuts up ...\n");
588 oops_end(flags); 628 oops_end(flags);
589 nmi_exit(); 629 nmi_exit();
590 local_irq_enable(); 630 local_irq_enable();
@@ -730,8 +770,15 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs,
730static __kprobes void 770static __kprobes void
731mem_parity_error(unsigned char reason, struct pt_regs * regs) 771mem_parity_error(unsigned char reason, struct pt_regs * regs)
732{ 772{
733 printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n"); 773 printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n",
734 printk("You probably have a hardware problem with your RAM chips\n"); 774 reason);
775 printk(KERN_EMERG "You probably have a hardware problem with your "
776 "RAM chips\n");
777
778 if (panic_on_unrecovered_nmi)
779 panic("NMI: Not continuing");
780
781 printk(KERN_EMERG "Dazed and confused, but trying to continue\n");
735 782
736 /* Clear and disable the memory parity error line. */ 783 /* Clear and disable the memory parity error line. */
737 reason = (reason & 0xf) | 4; 784 reason = (reason & 0xf) | 4;
@@ -754,9 +801,15 @@ io_check_error(unsigned char reason, struct pt_regs * regs)
754 801
755static __kprobes void 802static __kprobes void
756unknown_nmi_error(unsigned char reason, struct pt_regs * regs) 803unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
757{ printk("Uhhuh. NMI received for unknown reason %02x.\n", reason); 804{
758 printk("Dazed and confused, but trying to continue\n"); 805 printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n",
759 printk("Do you have a strange power saving mode enabled?\n"); 806 reason);
807 printk(KERN_EMERG "Do you have a strange power saving mode enabled?\n");
808
809 if (panic_on_unrecovered_nmi)
810 panic("NMI: Not continuing");
811
812 printk(KERN_EMERG "Dazed and confused, but trying to continue\n");
760} 813}
761 814
762/* Runs on IST stack. This code must keep interrupts off all the time. 815/* Runs on IST stack. This code must keep interrupts off all the time.
@@ -776,17 +829,15 @@ asmlinkage __kprobes void default_do_nmi(struct pt_regs *regs)
776 if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT) 829 if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT)
777 == NOTIFY_STOP) 830 == NOTIFY_STOP)
778 return; 831 return;
779#ifdef CONFIG_X86_LOCAL_APIC
780 /* 832 /*
781 * Ok, so this is none of the documented NMI sources, 833 * Ok, so this is none of the documented NMI sources,
782 * so it must be the NMI watchdog. 834 * so it must be the NMI watchdog.
783 */ 835 */
784 if (nmi_watchdog > 0) { 836 if (nmi_watchdog_tick(regs,reason))
785 nmi_watchdog_tick(regs,reason);
786 return; 837 return;
787 } 838 if (!do_nmi_callback(regs,cpu))
788#endif 839 unknown_nmi_error(reason, regs);
789 unknown_nmi_error(reason, regs); 840
790 return; 841 return;
791 } 842 }
792 if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) 843 if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP)
@@ -1071,6 +1122,7 @@ asmlinkage void math_state_restore(void)
1071 init_fpu(me); 1122 init_fpu(me);
1072 restore_fpu_checking(&me->thread.i387.fxsave); 1123 restore_fpu_checking(&me->thread.i387.fxsave);
1073 task_thread_info(me)->status |= TS_USEDFPU; 1124 task_thread_info(me)->status |= TS_USEDFPU;
1125 me->fpu_counter++;
1074} 1126}
1075 1127
1076void __init trap_init(void) 1128void __init trap_init(void)
@@ -1109,24 +1161,30 @@ void __init trap_init(void)
1109} 1161}
1110 1162
1111 1163
1112/* Actual parsing is done early in setup.c. */ 1164static int __init oops_setup(char *s)
1113static int __init oops_dummy(char *s)
1114{ 1165{
1115 panic_on_oops = 1; 1166 if (!s)
1116 return 1; 1167 return -EINVAL;
1168 if (!strcmp(s, "panic"))
1169 panic_on_oops = 1;
1170 return 0;
1117} 1171}
1118__setup("oops=", oops_dummy); 1172early_param("oops", oops_setup);
1119 1173
1120static int __init kstack_setup(char *s) 1174static int __init kstack_setup(char *s)
1121{ 1175{
1176 if (!s)
1177 return -EINVAL;
1122 kstack_depth_to_print = simple_strtoul(s,NULL,0); 1178 kstack_depth_to_print = simple_strtoul(s,NULL,0);
1123 return 1; 1179 return 0;
1124} 1180}
1125__setup("kstack=", kstack_setup); 1181early_param("kstack", kstack_setup);
1126 1182
1127#ifdef CONFIG_STACK_UNWIND 1183#ifdef CONFIG_STACK_UNWIND
1128static int __init call_trace_setup(char *s) 1184static int __init call_trace_setup(char *s)
1129{ 1185{
1186 if (!s)
1187 return -EINVAL;
1130 if (strcmp(s, "old") == 0) 1188 if (strcmp(s, "old") == 0)
1131 call_trace = -1; 1189 call_trace = -1;
1132 else if (strcmp(s, "both") == 0) 1190 else if (strcmp(s, "both") == 0)
@@ -1135,7 +1193,7 @@ static int __init call_trace_setup(char *s)
1135 call_trace = 1; 1193 call_trace = 1;
1136 else if (strcmp(s, "new") == 0) 1194 else if (strcmp(s, "new") == 0)
1137 call_trace = 2; 1195 call_trace = 2;
1138 return 1; 1196 return 0;
1139} 1197}
1140__setup("call_trace=", call_trace_setup); 1198early_param("call_trace", call_trace_setup);
1141#endif 1199#endif
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S
index 7c4de31471d4..d0564f1bcb0b 100644
--- a/arch/x86_64/kernel/vmlinux.lds.S
+++ b/arch/x86_64/kernel/vmlinux.lds.S
@@ -13,6 +13,12 @@ OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
13OUTPUT_ARCH(i386:x86-64) 13OUTPUT_ARCH(i386:x86-64)
14ENTRY(phys_startup_64) 14ENTRY(phys_startup_64)
15jiffies_64 = jiffies; 15jiffies_64 = jiffies;
16PHDRS {
17 text PT_LOAD FLAGS(5); /* R_E */
18 data PT_LOAD FLAGS(7); /* RWE */
19 user PT_LOAD FLAGS(7); /* RWE */
20 note PT_NOTE FLAGS(4); /* R__ */
21}
16SECTIONS 22SECTIONS
17{ 23{
18 . = __START_KERNEL; 24 . = __START_KERNEL;
@@ -31,7 +37,7 @@ SECTIONS
31 KPROBES_TEXT 37 KPROBES_TEXT
32 *(.fixup) 38 *(.fixup)
33 *(.gnu.warning) 39 *(.gnu.warning)
34 } = 0x9090 40 } :text = 0x9090
35 /* out-of-line lock text */ 41 /* out-of-line lock text */
36 .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) { *(.text.lock) } 42 .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) { *(.text.lock) }
37 43
@@ -57,7 +63,7 @@ SECTIONS
57 .data : AT(ADDR(.data) - LOAD_OFFSET) { 63 .data : AT(ADDR(.data) - LOAD_OFFSET) {
58 *(.data) 64 *(.data)
59 CONSTRUCTORS 65 CONSTRUCTORS
60 } 66 } :data
61 67
62 _edata = .; /* End of data section */ 68 _edata = .; /* End of data section */
63 69
@@ -89,7 +95,7 @@ SECTIONS
89#define VVIRT(x) (ADDR(x) - VVIRT_OFFSET) 95#define VVIRT(x) (ADDR(x) - VVIRT_OFFSET)
90 96
91 . = VSYSCALL_ADDR; 97 . = VSYSCALL_ADDR;
92 .vsyscall_0 : AT(VSYSCALL_PHYS_ADDR) { *(.vsyscall_0) } 98 .vsyscall_0 : AT(VSYSCALL_PHYS_ADDR) { *(.vsyscall_0) } :user
93 __vsyscall_0 = VSYSCALL_VIRT_ADDR; 99 __vsyscall_0 = VSYSCALL_VIRT_ADDR;
94 100
95 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); 101 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
@@ -99,6 +105,9 @@ SECTIONS
99 .vxtime : AT(VLOAD(.vxtime)) { *(.vxtime) } 105 .vxtime : AT(VLOAD(.vxtime)) { *(.vxtime) }
100 vxtime = VVIRT(.vxtime); 106 vxtime = VVIRT(.vxtime);
101 107
108 .vgetcpu_mode : AT(VLOAD(.vgetcpu_mode)) { *(.vgetcpu_mode) }
109 vgetcpu_mode = VVIRT(.vgetcpu_mode);
110
102 .wall_jiffies : AT(VLOAD(.wall_jiffies)) { *(.wall_jiffies) } 111 .wall_jiffies : AT(VLOAD(.wall_jiffies)) { *(.wall_jiffies) }
103 wall_jiffies = VVIRT(.wall_jiffies); 112 wall_jiffies = VVIRT(.wall_jiffies);
104 113
@@ -132,7 +141,7 @@ SECTIONS
132 . = ALIGN(8192); /* init_task */ 141 . = ALIGN(8192); /* init_task */
133 .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { 142 .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
134 *(.data.init_task) 143 *(.data.init_task)
135 } 144 } :data
136 145
137 . = ALIGN(4096); 146 . = ALIGN(4096);
138 .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { 147 .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
@@ -207,14 +216,12 @@ SECTIONS
207 __initramfs_start = .; 216 __initramfs_start = .;
208 .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) } 217 .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) }
209 __initramfs_end = .; 218 __initramfs_end = .;
210 /* temporary here to work around NR_CPUS. If you see this comment in 2.6.17+ 219 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
211 complain */
212 . = ALIGN(4096);
213 __init_end = .;
214 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
215 __per_cpu_start = .; 220 __per_cpu_start = .;
216 .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) } 221 .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) }
217 __per_cpu_end = .; 222 __per_cpu_end = .;
223 . = ALIGN(4096);
224 __init_end = .;
218 225
219 . = ALIGN(4096); 226 . = ALIGN(4096);
220 __nosave_begin = .; 227 __nosave_begin = .;
diff --git a/arch/x86_64/kernel/vsmp.c b/arch/x86_64/kernel/vsmp.c
index 92f70c74965f..044e852bd25e 100644
--- a/arch/x86_64/kernel/vsmp.c
+++ b/arch/x86_64/kernel/vsmp.c
@@ -20,6 +20,9 @@ static int __init vsmp_init(void)
20 void *address; 20 void *address;
21 unsigned int cap, ctl; 21 unsigned int cap, ctl;
22 22
23 if (!early_pci_allowed())
24 return 0;
25
23 /* Check if we are running on a ScaleMP vSMP box */ 26 /* Check if we are running on a ScaleMP vSMP box */
24 if ((read_pci_config_16(0, 0x1f, 0, PCI_VENDOR_ID) != PCI_VENDOR_ID_SCALEMP) || 27 if ((read_pci_config_16(0, 0x1f, 0, PCI_VENDOR_ID) != PCI_VENDOR_ID_SCALEMP) ||
25 (read_pci_config_16(0, 0x1f, 0, PCI_DEVICE_ID) != PCI_DEVICE_ID_SCALEMP_VSMP_CTL)) 28 (read_pci_config_16(0, 0x1f, 0, PCI_DEVICE_ID) != PCI_DEVICE_ID_SCALEMP_VSMP_CTL))
diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c
index f603037df162..ac48c3857ddb 100644
--- a/arch/x86_64/kernel/vsyscall.c
+++ b/arch/x86_64/kernel/vsyscall.c
@@ -26,6 +26,7 @@
26#include <linux/seqlock.h> 26#include <linux/seqlock.h>
27#include <linux/jiffies.h> 27#include <linux/jiffies.h>
28#include <linux/sysctl.h> 28#include <linux/sysctl.h>
29#include <linux/getcpu.h>
29 30
30#include <asm/vsyscall.h> 31#include <asm/vsyscall.h>
31#include <asm/pgtable.h> 32#include <asm/pgtable.h>
@@ -33,11 +34,15 @@
33#include <asm/fixmap.h> 34#include <asm/fixmap.h>
34#include <asm/errno.h> 35#include <asm/errno.h>
35#include <asm/io.h> 36#include <asm/io.h>
37#include <asm/segment.h>
38#include <asm/desc.h>
39#include <asm/topology.h>
36 40
37#define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr))) 41#define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr)))
38 42
39int __sysctl_vsyscall __section_sysctl_vsyscall = 1; 43int __sysctl_vsyscall __section_sysctl_vsyscall = 1;
40seqlock_t __xtime_lock __section_xtime_lock = SEQLOCK_UNLOCKED; 44seqlock_t __xtime_lock __section_xtime_lock = SEQLOCK_UNLOCKED;
45int __vgetcpu_mode __section_vgetcpu_mode;
41 46
42#include <asm/unistd.h> 47#include <asm/unistd.h>
43 48
@@ -72,7 +77,8 @@ static __always_inline void do_vgettimeofday(struct timeval * tv)
72 __vxtime.tsc_quot) >> 32; 77 __vxtime.tsc_quot) >> 32;
73 /* See comment in x86_64 do_gettimeofday. */ 78 /* See comment in x86_64 do_gettimeofday. */
74 } else { 79 } else {
75 usec += ((readl((void *)fix_to_virt(VSYSCALL_HPET) + 0xf0) - 80 usec += ((readl((void __iomem *)
81 fix_to_virt(VSYSCALL_HPET) + 0xf0) -
76 __vxtime.last) * __vxtime.quot) >> 32; 82 __vxtime.last) * __vxtime.quot) >> 32;
77 } 83 }
78 } while (read_seqretry(&__xtime_lock, sequence)); 84 } while (read_seqretry(&__xtime_lock, sequence));
@@ -127,9 +133,46 @@ time_t __vsyscall(1) vtime(time_t *t)
127 return __xtime.tv_sec; 133 return __xtime.tv_sec;
128} 134}
129 135
130long __vsyscall(2) venosys_0(void) 136/* Fast way to get current CPU and node.
137 This helps to do per node and per CPU caches in user space.
138 The result is not guaranteed without CPU affinity, but usually
139 works out because the scheduler tries to keep a thread on the same
140 CPU.
141
142 tcache must point to a two element sized long array.
143 All arguments can be NULL. */
144long __vsyscall(2)
145vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache)
131{ 146{
132 return -ENOSYS; 147 unsigned int dummy, p;
148 unsigned long j = 0;
149
150 /* Fast cache - only recompute value once per jiffies and avoid
151 relatively costly rdtscp/cpuid otherwise.
152 This works because the scheduler usually keeps the process
153 on the same CPU and this syscall doesn't guarantee its
154 results anyways.
155 We do this here because otherwise user space would do it on
156 its own in a likely inferior way (no access to jiffies).
157 If you don't like it pass NULL. */
158 if (tcache && tcache->t0 == (j = __jiffies)) {
159 p = tcache->t1;
160 } else if (__vgetcpu_mode == VGETCPU_RDTSCP) {
161 /* Load per CPU data from RDTSCP */
162 rdtscp(dummy, dummy, p);
163 } else {
164 /* Load per CPU data from GDT */
165 asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG));
166 }
167 if (tcache) {
168 tcache->t0 = j;
169 tcache->t1 = p;
170 }
171 if (cpu)
172 *cpu = p & 0xfff;
173 if (node)
174 *node = p >> 12;
175 return 0;
133} 176}
134 177
135long __vsyscall(3) venosys_1(void) 178long __vsyscall(3) venosys_1(void)
@@ -149,7 +192,8 @@ static int vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp,
149 void __user *buffer, size_t *lenp, loff_t *ppos) 192 void __user *buffer, size_t *lenp, loff_t *ppos)
150{ 193{
151 extern u16 vsysc1, vsysc2; 194 extern u16 vsysc1, vsysc2;
152 u16 *map1, *map2; 195 u16 __iomem *map1;
196 u16 __iomem *map2;
153 int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); 197 int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
154 if (!write) 198 if (!write)
155 return ret; 199 return ret;
@@ -164,11 +208,11 @@ static int vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp,
164 goto out; 208 goto out;
165 } 209 }
166 if (!sysctl_vsyscall) { 210 if (!sysctl_vsyscall) {
167 *map1 = SYSCALL; 211 writew(SYSCALL, map1);
168 *map2 = SYSCALL; 212 writew(SYSCALL, map2);
169 } else { 213 } else {
170 *map1 = NOP2; 214 writew(NOP2, map1);
171 *map2 = NOP2; 215 writew(NOP2, map2);
172 } 216 }
173 iounmap(map2); 217 iounmap(map2);
174out: 218out:
@@ -200,6 +244,43 @@ static ctl_table kernel_root_table2[] = {
200 244
201#endif 245#endif
202 246
247static void __cpuinit write_rdtscp_cb(void *info)
248{
249 write_rdtscp_aux((unsigned long)info);
250}
251
252void __cpuinit vsyscall_set_cpu(int cpu)
253{
254 unsigned long *d;
255 unsigned long node = 0;
256#ifdef CONFIG_NUMA
257 node = cpu_to_node[cpu];
258#endif
259 if (cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP)) {
260 void *info = (void *)((node << 12) | cpu);
261 /* Can happen on preemptive kernel */
262 if (get_cpu() == cpu)
263 write_rdtscp_cb(info);
264#ifdef CONFIG_SMP
265 else {
266 /* the notifier is unfortunately not executed on the
267 target CPU */
268 smp_call_function_single(cpu,write_rdtscp_cb,info,0,1);
269 }
270#endif
271 put_cpu();
272 }
273
274 /* Store cpu number in limit so that it can be loaded quickly
275 in user space in vgetcpu.
276 12 bits for the CPU and 8 bits for the node. */
277 d = (unsigned long *)(cpu_gdt(cpu) + GDT_ENTRY_PER_CPU);
278 *d = 0x0f40000000000ULL;
279 *d |= cpu;
280 *d |= (node & 0xf) << 12;
281 *d |= (node >> 4) << 48;
282}
283
203static void __init map_vsyscall(void) 284static void __init map_vsyscall(void)
204{ 285{
205 extern char __vsyscall_0; 286 extern char __vsyscall_0;
@@ -214,6 +295,7 @@ static int __init vsyscall_init(void)
214 VSYSCALL_ADDR(__NR_vgettimeofday))); 295 VSYSCALL_ADDR(__NR_vgettimeofday)));
215 BUG_ON((unsigned long) &vtime != VSYSCALL_ADDR(__NR_vtime)); 296 BUG_ON((unsigned long) &vtime != VSYSCALL_ADDR(__NR_vtime));
216 BUG_ON((VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE))); 297 BUG_ON((VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE)));
298 BUG_ON((unsigned long) &vgetcpu != VSYSCALL_ADDR(__NR_vgetcpu));
217 map_vsyscall(); 299 map_vsyscall();
218#ifdef CONFIG_SYSCTL 300#ifdef CONFIG_SYSCTL
219 register_sysctl_table(kernel_root_table2, 0); 301 register_sysctl_table(kernel_root_table2, 0);
diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c
index 370952c4ff22..c3454af5e3a2 100644
--- a/arch/x86_64/kernel/x8664_ksyms.c
+++ b/arch/x86_64/kernel/x8664_ksyms.c
@@ -29,6 +29,7 @@ EXPORT_SYMBOL(__put_user_8);
29EXPORT_SYMBOL(copy_user_generic); 29EXPORT_SYMBOL(copy_user_generic);
30EXPORT_SYMBOL(copy_from_user); 30EXPORT_SYMBOL(copy_from_user);
31EXPORT_SYMBOL(copy_to_user); 31EXPORT_SYMBOL(copy_to_user);
32EXPORT_SYMBOL(__copy_from_user_inatomic);
32 33
33EXPORT_SYMBOL(copy_page); 34EXPORT_SYMBOL(copy_page);
34EXPORT_SYMBOL(clear_page); 35EXPORT_SYMBOL(clear_page);
diff --git a/arch/x86_64/lib/Makefile b/arch/x86_64/lib/Makefile
index ccef6ae747a3..b78d4170fce2 100644
--- a/arch/x86_64/lib/Makefile
+++ b/arch/x86_64/lib/Makefile
@@ -9,4 +9,4 @@ obj-y := io.o iomap_copy.o
9lib-y := csum-partial.o csum-copy.o csum-wrappers.o delay.o \ 9lib-y := csum-partial.o csum-copy.o csum-wrappers.o delay.o \
10 usercopy.o getuser.o putuser.o \ 10 usercopy.o getuser.o putuser.o \
11 thunk.o clear_page.o copy_page.o bitstr.o bitops.o 11 thunk.o clear_page.o copy_page.o bitstr.o bitops.o
12lib-y += memcpy.o memmove.o memset.o copy_user.o 12lib-y += memcpy.o memmove.o memset.o copy_user.o rwlock.o
diff --git a/arch/x86_64/lib/clear_page.S b/arch/x86_64/lib/clear_page.S
index 1f81b79b796c..9a10a78bb4a4 100644
--- a/arch/x86_64/lib/clear_page.S
+++ b/arch/x86_64/lib/clear_page.S
@@ -1,10 +1,22 @@
1#include <linux/linkage.h>
2#include <asm/dwarf2.h>
3
1/* 4/*
2 * Zero a page. 5 * Zero a page.
3 * rdi page 6 * rdi page
4 */ 7 */
5 .globl clear_page 8 ALIGN
6 .p2align 4 9clear_page_c:
7clear_page: 10 CFI_STARTPROC
11 movl $4096/8,%ecx
12 xorl %eax,%eax
13 rep stosq
14 ret
15 CFI_ENDPROC
16ENDPROC(clear_page)
17
18ENTRY(clear_page)
19 CFI_STARTPROC
8 xorl %eax,%eax 20 xorl %eax,%eax
9 movl $4096/64,%ecx 21 movl $4096/64,%ecx
10 .p2align 4 22 .p2align 4
@@ -23,28 +35,25 @@ clear_page:
23 jnz .Lloop 35 jnz .Lloop
24 nop 36 nop
25 ret 37 ret
26clear_page_end: 38 CFI_ENDPROC
39.Lclear_page_end:
40ENDPROC(clear_page)
27 41
28 /* Some CPUs run faster using the string instructions. 42 /* Some CPUs run faster using the string instructions.
29 It is also a lot simpler. Use this when possible */ 43 It is also a lot simpler. Use this when possible */
30 44
31#include <asm/cpufeature.h> 45#include <asm/cpufeature.h>
32 46
47 .section .altinstr_replacement,"ax"
481: .byte 0xeb /* jmp <disp8> */
49 .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */
502:
51 .previous
33 .section .altinstructions,"a" 52 .section .altinstructions,"a"
34 .align 8 53 .align 8
35 .quad clear_page 54 .quad clear_page
36 .quad clear_page_c 55 .quad 1b
37 .byte X86_FEATURE_REP_GOOD 56 .byte X86_FEATURE_REP_GOOD
38 .byte clear_page_end-clear_page 57 .byte .Lclear_page_end - clear_page
39 .byte clear_page_c_end-clear_page_c 58 .byte 2b - 1b
40 .previous
41
42 .section .altinstr_replacement,"ax"
43clear_page_c:
44 movl $4096/8,%ecx
45 xorl %eax,%eax
46 rep
47 stosq
48 ret
49clear_page_c_end:
50 .previous 59 .previous
diff --git a/arch/x86_64/lib/copy_page.S b/arch/x86_64/lib/copy_page.S
index 8fa19d96a7ee..0ebb03b60e79 100644
--- a/arch/x86_64/lib/copy_page.S
+++ b/arch/x86_64/lib/copy_page.S
@@ -1,17 +1,33 @@
1/* Written 2003 by Andi Kleen, based on a kernel by Evandro Menezes */ 1/* Written 2003 by Andi Kleen, based on a kernel by Evandro Menezes */
2 2
3#include <linux/config.h>
4#include <linux/linkage.h>
5#include <asm/dwarf2.h>
6
7 ALIGN
8copy_page_c:
9 CFI_STARTPROC
10 movl $4096/8,%ecx
11 rep movsq
12 ret
13 CFI_ENDPROC
14ENDPROC(copy_page_c)
15
3/* Don't use streaming store because it's better when the target 16/* Don't use streaming store because it's better when the target
4 ends up in cache. */ 17 ends up in cache. */
5 18
6/* Could vary the prefetch distance based on SMP/UP */ 19/* Could vary the prefetch distance based on SMP/UP */
7 20
8 .globl copy_page 21ENTRY(copy_page)
9 .p2align 4 22 CFI_STARTPROC
10copy_page:
11 subq $3*8,%rsp 23 subq $3*8,%rsp
24 CFI_ADJUST_CFA_OFFSET 3*8
12 movq %rbx,(%rsp) 25 movq %rbx,(%rsp)
26 CFI_REL_OFFSET rbx, 0
13 movq %r12,1*8(%rsp) 27 movq %r12,1*8(%rsp)
28 CFI_REL_OFFSET r12, 1*8
14 movq %r13,2*8(%rsp) 29 movq %r13,2*8(%rsp)
30 CFI_REL_OFFSET r13, 2*8
15 31
16 movl $(4096/64)-5,%ecx 32 movl $(4096/64)-5,%ecx
17 .p2align 4 33 .p2align 4
@@ -72,30 +88,33 @@ copy_page:
72 jnz .Loop2 88 jnz .Loop2
73 89
74 movq (%rsp),%rbx 90 movq (%rsp),%rbx
91 CFI_RESTORE rbx
75 movq 1*8(%rsp),%r12 92 movq 1*8(%rsp),%r12
93 CFI_RESTORE r12
76 movq 2*8(%rsp),%r13 94 movq 2*8(%rsp),%r13
95 CFI_RESTORE r13
77 addq $3*8,%rsp 96 addq $3*8,%rsp
97 CFI_ADJUST_CFA_OFFSET -3*8
78 ret 98 ret
99.Lcopy_page_end:
100 CFI_ENDPROC
101ENDPROC(copy_page)
79 102
80 /* Some CPUs run faster using the string copy instructions. 103 /* Some CPUs run faster using the string copy instructions.
81 It is also a lot simpler. Use this when possible */ 104 It is also a lot simpler. Use this when possible */
82 105
83#include <asm/cpufeature.h> 106#include <asm/cpufeature.h>
84 107
108 .section .altinstr_replacement,"ax"
1091: .byte 0xeb /* jmp <disp8> */
110 .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */
1112:
112 .previous
85 .section .altinstructions,"a" 113 .section .altinstructions,"a"
86 .align 8 114 .align 8
87 .quad copy_page 115 .quad copy_page
88 .quad copy_page_c 116 .quad 1b
89 .byte X86_FEATURE_REP_GOOD 117 .byte X86_FEATURE_REP_GOOD
90 .byte copy_page_c_end-copy_page_c 118 .byte .Lcopy_page_end - copy_page
91 .byte copy_page_c_end-copy_page_c 119 .byte 2b - 1b
92 .previous
93
94 .section .altinstr_replacement,"ax"
95copy_page_c:
96 movl $4096/8,%ecx
97 rep
98 movsq
99 ret
100copy_page_c_end:
101 .previous 120 .previous
diff --git a/arch/x86_64/lib/copy_user.S b/arch/x86_64/lib/copy_user.S
index f64569b83b54..70bebd310408 100644
--- a/arch/x86_64/lib/copy_user.S
+++ b/arch/x86_64/lib/copy_user.S
@@ -4,56 +4,78 @@
4 * Functions to copy from and to user space. 4 * Functions to copy from and to user space.
5 */ 5 */
6 6
7#include <linux/linkage.h>
8#include <asm/dwarf2.h>
9
7#define FIX_ALIGNMENT 1 10#define FIX_ALIGNMENT 1
8 11
9 #include <asm/current.h> 12#include <asm/current.h>
10 #include <asm/asm-offsets.h> 13#include <asm/asm-offsets.h>
11 #include <asm/thread_info.h> 14#include <asm/thread_info.h>
12 #include <asm/cpufeature.h> 15#include <asm/cpufeature.h>
13 16
14/* Standard copy_to_user with segment limit checking */ 17 .macro ALTERNATIVE_JUMP feature,orig,alt
15 .globl copy_to_user 180:
16 .p2align 4
17copy_to_user:
18 GET_THREAD_INFO(%rax)
19 movq %rdi,%rcx
20 addq %rdx,%rcx
21 jc bad_to_user
22 cmpq threadinfo_addr_limit(%rax),%rcx
23 jae bad_to_user
242:
25 .byte 0xe9 /* 32bit jump */ 19 .byte 0xe9 /* 32bit jump */
26 .long .Lcug-1f 20 .long \orig-1f /* by default jump to orig */
271: 211:
28
29 .section .altinstr_replacement,"ax" 22 .section .altinstr_replacement,"ax"
303: .byte 0xe9 /* replacement jmp with 8 bit immediate */ 232: .byte 0xe9 /* near jump with 32bit immediate */
31 .long copy_user_generic_c-1b /* offset */ 24 .long \alt-1b /* offset */ /* or alternatively to alt */
32 .previous 25 .previous
33 .section .altinstructions,"a" 26 .section .altinstructions,"a"
34 .align 8 27 .align 8
28 .quad 0b
35 .quad 2b 29 .quad 2b
36 .quad 3b 30 .byte \feature /* when feature is set */
37 .byte X86_FEATURE_REP_GOOD
38 .byte 5 31 .byte 5
39 .byte 5 32 .byte 5
40 .previous 33 .previous
34 .endm
35
36/* Standard copy_to_user with segment limit checking */
37ENTRY(copy_to_user)
38 CFI_STARTPROC
39 GET_THREAD_INFO(%rax)
40 movq %rdi,%rcx
41 addq %rdx,%rcx
42 jc bad_to_user
43 cmpq threadinfo_addr_limit(%rax),%rcx
44 jae bad_to_user
45 xorl %eax,%eax /* clear zero flag */
46 ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
47 CFI_ENDPROC
48
49ENTRY(copy_user_generic)
50 CFI_STARTPROC
51 movl $1,%ecx /* set zero flag */
52 ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
53 CFI_ENDPROC
54
55ENTRY(__copy_from_user_inatomic)
56 CFI_STARTPROC
57 xorl %ecx,%ecx /* clear zero flag */
58 ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
59 CFI_ENDPROC
41 60
42/* Standard copy_from_user with segment limit checking */ 61/* Standard copy_from_user with segment limit checking */
43 .globl copy_from_user 62ENTRY(copy_from_user)
44 .p2align 4 63 CFI_STARTPROC
45copy_from_user:
46 GET_THREAD_INFO(%rax) 64 GET_THREAD_INFO(%rax)
47 movq %rsi,%rcx 65 movq %rsi,%rcx
48 addq %rdx,%rcx 66 addq %rdx,%rcx
49 jc bad_from_user 67 jc bad_from_user
50 cmpq threadinfo_addr_limit(%rax),%rcx 68 cmpq threadinfo_addr_limit(%rax),%rcx
51 jae bad_from_user 69 jae bad_from_user
52 /* FALL THROUGH to copy_user_generic */ 70 movl $1,%ecx /* set zero flag */
71 ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
72 CFI_ENDPROC
73ENDPROC(copy_from_user)
53 74
54 .section .fixup,"ax" 75 .section .fixup,"ax"
55 /* must zero dest */ 76 /* must zero dest */
56bad_from_user: 77bad_from_user:
78 CFI_STARTPROC
57 movl %edx,%ecx 79 movl %edx,%ecx
58 xorl %eax,%eax 80 xorl %eax,%eax
59 rep 81 rep
@@ -61,40 +83,32 @@ bad_from_user:
61bad_to_user: 83bad_to_user:
62 movl %edx,%eax 84 movl %edx,%eax
63 ret 85 ret
86 CFI_ENDPROC
87END(bad_from_user)
64 .previous 88 .previous
65 89
66 90
67/* 91/*
68 * copy_user_generic - memory copy with exception handling. 92 * copy_user_generic_unrolled - memory copy with exception handling.
93 * This version is for CPUs like P4 that don't have efficient micro code for rep movsq
69 * 94 *
70 * Input: 95 * Input:
71 * rdi destination 96 * rdi destination
72 * rsi source 97 * rsi source
73 * rdx count 98 * rdx count
99 * ecx zero flag -- if true zero destination on error
74 * 100 *
75 * Output: 101 * Output:
76 * eax uncopied bytes or 0 if successful. 102 * eax uncopied bytes or 0 if successful.
77 */ 103 */
78 .globl copy_user_generic 104ENTRY(copy_user_generic_unrolled)
79 .p2align 4 105 CFI_STARTPROC
80copy_user_generic:
81 .byte 0x66,0x66,0x90 /* 5 byte nop for replacement jump */
82 .byte 0x66,0x90
831:
84 .section .altinstr_replacement,"ax"
852: .byte 0xe9 /* near jump with 32bit immediate */
86 .long copy_user_generic_c-1b /* offset */
87 .previous
88 .section .altinstructions,"a"
89 .align 8
90 .quad copy_user_generic
91 .quad 2b
92 .byte X86_FEATURE_REP_GOOD
93 .byte 5
94 .byte 5
95 .previous
96.Lcug:
97 pushq %rbx 106 pushq %rbx
107 CFI_ADJUST_CFA_OFFSET 8
108 CFI_REL_OFFSET rbx, 0
109 pushq %rcx
110 CFI_ADJUST_CFA_OFFSET 8
111 CFI_REL_OFFSET rcx, 0
98 xorl %eax,%eax /*zero for the exception handler */ 112 xorl %eax,%eax /*zero for the exception handler */
99 113
100#ifdef FIX_ALIGNMENT 114#ifdef FIX_ALIGNMENT
@@ -168,9 +182,16 @@ copy_user_generic:
168 decl %ecx 182 decl %ecx
169 jnz .Lloop_1 183 jnz .Lloop_1
170 184
185 CFI_REMEMBER_STATE
171.Lende: 186.Lende:
187 popq %rcx
188 CFI_ADJUST_CFA_OFFSET -8
189 CFI_RESTORE rcx
172 popq %rbx 190 popq %rbx
191 CFI_ADJUST_CFA_OFFSET -8
192 CFI_RESTORE rbx
173 ret 193 ret
194 CFI_RESTORE_STATE
174 195
175#ifdef FIX_ALIGNMENT 196#ifdef FIX_ALIGNMENT
176 /* align destination */ 197 /* align destination */
@@ -252,6 +273,8 @@ copy_user_generic:
252 addl %ecx,%edx 273 addl %ecx,%edx
253 /* edx: bytes to zero, rdi: dest, eax:zero */ 274 /* edx: bytes to zero, rdi: dest, eax:zero */
254.Lzero_rest: 275.Lzero_rest:
276 cmpl $0,(%rsp)
277 jz .Le_zero
255 movq %rdx,%rcx 278 movq %rdx,%rcx
256.Le_byte: 279.Le_byte:
257 xorl %eax,%eax 280 xorl %eax,%eax
@@ -261,6 +284,9 @@ copy_user_generic:
261.Le_zero: 284.Le_zero:
262 movq %rdx,%rax 285 movq %rdx,%rax
263 jmp .Lende 286 jmp .Lende
287 CFI_ENDPROC
288ENDPROC(copy_user_generic)
289
264 290
265 /* Some CPUs run faster using the string copy instructions. 291 /* Some CPUs run faster using the string copy instructions.
266 This is also a lot simpler. Use them when possible. 292 This is also a lot simpler. Use them when possible.
@@ -270,6 +296,7 @@ copy_user_generic:
270 /* rdi destination 296 /* rdi destination
271 * rsi source 297 * rsi source
272 * rdx count 298 * rdx count
299 * ecx zero flag
273 * 300 *
274 * Output: 301 * Output:
275 * eax uncopied bytes or 0 if successfull. 302 * eax uncopied bytes or 0 if successfull.
@@ -280,22 +307,48 @@ copy_user_generic:
280 * And more would be dangerous because both Intel and AMD have 307 * And more would be dangerous because both Intel and AMD have
281 * errata with rep movsq > 4GB. If someone feels the need to fix 308 * errata with rep movsq > 4GB. If someone feels the need to fix
282 * this please consider this. 309 * this please consider this.
283 */ 310 */
284copy_user_generic_c: 311ENTRY(copy_user_generic_string)
312 CFI_STARTPROC
313 movl %ecx,%r8d /* save zero flag */
285 movl %edx,%ecx 314 movl %edx,%ecx
286 shrl $3,%ecx 315 shrl $3,%ecx
287 andl $7,%edx 316 andl $7,%edx
317 jz 10f
2881: rep 3181: rep
289 movsq 319 movsq
290 movl %edx,%ecx 320 movl %edx,%ecx
2912: rep 3212: rep
292 movsb 322 movsb
2934: movl %ecx,%eax 3239: movl %ecx,%eax
294 ret 324 ret
2953: lea (%rdx,%rcx,8),%rax 325
326 /* multiple of 8 byte */
32710: rep
328 movsq
329 xor %eax,%eax
296 ret 330 ret
297 331
332 /* exception handling */
3333: lea (%rdx,%rcx,8),%rax /* exception on quad loop */
334 jmp 6f
3355: movl %ecx,%eax /* exception on byte loop */
336 /* eax: left over bytes */
3376: testl %r8d,%r8d /* zero flag set? */
338 jz 7f
339 movl %eax,%ecx /* initialize x86 loop counter */
340 push %rax
341 xorl %eax,%eax
3428: rep
343 stosb /* zero the rest */
34411: pop %rax
3457: ret
346 CFI_ENDPROC
347END(copy_user_generic_c)
348
298 .section __ex_table,"a" 349 .section __ex_table,"a"
299 .quad 1b,3b 350 .quad 1b,3b
300 .quad 2b,4b 351 .quad 2b,5b
352 .quad 8b,11b
353 .quad 10b,3b
301 .previous 354 .previous
diff --git a/arch/x86_64/lib/csum-copy.S b/arch/x86_64/lib/csum-copy.S
index 72fd55ee896e..f0dba36578ea 100644
--- a/arch/x86_64/lib/csum-copy.S
+++ b/arch/x86_64/lib/csum-copy.S
@@ -5,8 +5,9 @@
5 * License. See the file COPYING in the main directory of this archive 5 * License. See the file COPYING in the main directory of this archive
6 * for more details. No warranty for anything given at all. 6 * for more details. No warranty for anything given at all.
7 */ 7 */
8 #include <linux/linkage.h> 8#include <linux/linkage.h>
9 #include <asm/errno.h> 9#include <asm/dwarf2.h>
10#include <asm/errno.h>
10 11
11/* 12/*
12 * Checksum copy with exception handling. 13 * Checksum copy with exception handling.
@@ -53,19 +54,24 @@
53 .endm 54 .endm
54 55
55 56
56 .globl csum_partial_copy_generic 57ENTRY(csum_partial_copy_generic)
57 .p2align 4 58 CFI_STARTPROC
58csum_partial_copy_generic:
59 cmpl $3*64,%edx 59 cmpl $3*64,%edx
60 jle .Lignore 60 jle .Lignore
61 61
62.Lignore: 62.Lignore:
63 subq $7*8,%rsp 63 subq $7*8,%rsp
64 CFI_ADJUST_CFA_OFFSET 7*8
64 movq %rbx,2*8(%rsp) 65 movq %rbx,2*8(%rsp)
66 CFI_REL_OFFSET rbx, 2*8
65 movq %r12,3*8(%rsp) 67 movq %r12,3*8(%rsp)
68 CFI_REL_OFFSET r12, 3*8
66 movq %r14,4*8(%rsp) 69 movq %r14,4*8(%rsp)
70 CFI_REL_OFFSET r14, 4*8
67 movq %r13,5*8(%rsp) 71 movq %r13,5*8(%rsp)
72 CFI_REL_OFFSET r13, 5*8
68 movq %rbp,6*8(%rsp) 73 movq %rbp,6*8(%rsp)
74 CFI_REL_OFFSET rbp, 6*8
69 75
70 movq %r8,(%rsp) 76 movq %r8,(%rsp)
71 movq %r9,1*8(%rsp) 77 movq %r9,1*8(%rsp)
@@ -208,14 +214,22 @@ csum_partial_copy_generic:
208 addl %ebx,%eax 214 addl %ebx,%eax
209 adcl %r9d,%eax /* carry */ 215 adcl %r9d,%eax /* carry */
210 216
217 CFI_REMEMBER_STATE
211.Lende: 218.Lende:
212 movq 2*8(%rsp),%rbx 219 movq 2*8(%rsp),%rbx
220 CFI_RESTORE rbx
213 movq 3*8(%rsp),%r12 221 movq 3*8(%rsp),%r12
222 CFI_RESTORE r12
214 movq 4*8(%rsp),%r14 223 movq 4*8(%rsp),%r14
224 CFI_RESTORE r14
215 movq 5*8(%rsp),%r13 225 movq 5*8(%rsp),%r13
226 CFI_RESTORE r13
216 movq 6*8(%rsp),%rbp 227 movq 6*8(%rsp),%rbp
228 CFI_RESTORE rbp
217 addq $7*8,%rsp 229 addq $7*8,%rsp
230 CFI_ADJUST_CFA_OFFSET -7*8
218 ret 231 ret
232 CFI_RESTORE_STATE
219 233
220 /* Exception handlers. Very simple, zeroing is done in the wrappers */ 234 /* Exception handlers. Very simple, zeroing is done in the wrappers */
221.Lbad_source: 235.Lbad_source:
@@ -231,3 +245,5 @@ csum_partial_copy_generic:
231 jz .Lende 245 jz .Lende
232 movl $-EFAULT,(%rax) 246 movl $-EFAULT,(%rax)
233 jmp .Lende 247 jmp .Lende
248 CFI_ENDPROC
249ENDPROC(csum_partial_copy_generic)
diff --git a/arch/x86_64/lib/getuser.S b/arch/x86_64/lib/getuser.S
index 3844d5e885a4..5448876261f8 100644
--- a/arch/x86_64/lib/getuser.S
+++ b/arch/x86_64/lib/getuser.S
@@ -27,25 +27,26 @@
27 */ 27 */
28 28
29#include <linux/linkage.h> 29#include <linux/linkage.h>
30#include <asm/dwarf2.h>
30#include <asm/page.h> 31#include <asm/page.h>
31#include <asm/errno.h> 32#include <asm/errno.h>
32#include <asm/asm-offsets.h> 33#include <asm/asm-offsets.h>
33#include <asm/thread_info.h> 34#include <asm/thread_info.h>
34 35
35 .text 36 .text
36 .p2align 4 37ENTRY(__get_user_1)
37.globl __get_user_1 38 CFI_STARTPROC
38__get_user_1:
39 GET_THREAD_INFO(%r8) 39 GET_THREAD_INFO(%r8)
40 cmpq threadinfo_addr_limit(%r8),%rcx 40 cmpq threadinfo_addr_limit(%r8),%rcx
41 jae bad_get_user 41 jae bad_get_user
421: movzb (%rcx),%edx 421: movzb (%rcx),%edx
43 xorl %eax,%eax 43 xorl %eax,%eax
44 ret 44 ret
45 CFI_ENDPROC
46ENDPROC(__get_user_1)
45 47
46 .p2align 4 48ENTRY(__get_user_2)
47.globl __get_user_2 49 CFI_STARTPROC
48__get_user_2:
49 GET_THREAD_INFO(%r8) 50 GET_THREAD_INFO(%r8)
50 addq $1,%rcx 51 addq $1,%rcx
51 jc 20f 52 jc 20f
@@ -57,10 +58,11 @@ __get_user_2:
57 ret 58 ret
5820: decq %rcx 5920: decq %rcx
59 jmp bad_get_user 60 jmp bad_get_user
61 CFI_ENDPROC
62ENDPROC(__get_user_2)
60 63
61 .p2align 4 64ENTRY(__get_user_4)
62.globl __get_user_4 65 CFI_STARTPROC
63__get_user_4:
64 GET_THREAD_INFO(%r8) 66 GET_THREAD_INFO(%r8)
65 addq $3,%rcx 67 addq $3,%rcx
66 jc 30f 68 jc 30f
@@ -72,10 +74,11 @@ __get_user_4:
72 ret 74 ret
7330: subq $3,%rcx 7530: subq $3,%rcx
74 jmp bad_get_user 76 jmp bad_get_user
77 CFI_ENDPROC
78ENDPROC(__get_user_4)
75 79
76 .p2align 4 80ENTRY(__get_user_8)
77.globl __get_user_8 81 CFI_STARTPROC
78__get_user_8:
79 GET_THREAD_INFO(%r8) 82 GET_THREAD_INFO(%r8)
80 addq $7,%rcx 83 addq $7,%rcx
81 jc 40f 84 jc 40f
@@ -87,11 +90,16 @@ __get_user_8:
87 ret 90 ret
8840: subq $7,%rcx 9140: subq $7,%rcx
89 jmp bad_get_user 92 jmp bad_get_user
93 CFI_ENDPROC
94ENDPROC(__get_user_8)
90 95
91bad_get_user: 96bad_get_user:
97 CFI_STARTPROC
92 xorl %edx,%edx 98 xorl %edx,%edx
93 movq $(-EFAULT),%rax 99 movq $(-EFAULT),%rax
94 ret 100 ret
101 CFI_ENDPROC
102END(bad_get_user)
95 103
96.section __ex_table,"a" 104.section __ex_table,"a"
97 .quad 1b,bad_get_user 105 .quad 1b,bad_get_user
diff --git a/arch/x86_64/lib/iomap_copy.S b/arch/x86_64/lib/iomap_copy.S
index 8bbade5fea05..05a95e713da8 100644
--- a/arch/x86_64/lib/iomap_copy.S
+++ b/arch/x86_64/lib/iomap_copy.S
@@ -15,12 +15,16 @@
15 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 15 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
16 */ 16 */
17 17
18#include <linux/linkage.h>
19#include <asm/dwarf2.h>
20
18/* 21/*
19 * override generic version in lib/iomap_copy.c 22 * override generic version in lib/iomap_copy.c
20 */ 23 */
21 .globl __iowrite32_copy 24ENTRY(__iowrite32_copy)
22 .p2align 4 25 CFI_STARTPROC
23__iowrite32_copy:
24 movl %edx,%ecx 26 movl %edx,%ecx
25 rep movsd 27 rep movsd
26 ret 28 ret
29 CFI_ENDPROC
30ENDPROC(__iowrite32_copy)
diff --git a/arch/x86_64/lib/memcpy.S b/arch/x86_64/lib/memcpy.S
index 5554948b5554..967b22fa7d07 100644
--- a/arch/x86_64/lib/memcpy.S
+++ b/arch/x86_64/lib/memcpy.S
@@ -1,6 +1,10 @@
1/* Copyright 2002 Andi Kleen */ 1/* Copyright 2002 Andi Kleen */
2 2
3 #include <asm/cpufeature.h> 3#include <linux/config.h>
4#include <linux/linkage.h>
5#include <asm/dwarf2.h>
6#include <asm/cpufeature.h>
7
4/* 8/*
5 * memcpy - Copy a memory block. 9 * memcpy - Copy a memory block.
6 * 10 *
@@ -13,12 +17,26 @@
13 * rax original destination 17 * rax original destination
14 */ 18 */
15 19
16 .globl __memcpy 20 ALIGN
17 .globl memcpy 21memcpy_c:
18 .p2align 4 22 CFI_STARTPROC
19__memcpy: 23 movq %rdi,%rax
20memcpy: 24 movl %edx,%ecx
25 shrl $3,%ecx
26 andl $7,%edx
27 rep movsq
28 movl %edx,%ecx
29 rep movsb
30 ret
31 CFI_ENDPROC
32ENDPROC(memcpy_c)
33
34ENTRY(__memcpy)
35ENTRY(memcpy)
36 CFI_STARTPROC
21 pushq %rbx 37 pushq %rbx
38 CFI_ADJUST_CFA_OFFSET 8
39 CFI_REL_OFFSET rbx, 0
22 movq %rdi,%rax 40 movq %rdi,%rax
23 41
24 movl %edx,%ecx 42 movl %edx,%ecx
@@ -86,36 +104,27 @@ memcpy:
86 104
87.Lende: 105.Lende:
88 popq %rbx 106 popq %rbx
107 CFI_ADJUST_CFA_OFFSET -8
108 CFI_RESTORE rbx
89 ret 109 ret
90.Lfinal: 110.Lfinal:
111 CFI_ENDPROC
112ENDPROC(memcpy)
113ENDPROC(__memcpy)
91 114
92 /* Some CPUs run faster using the string copy instructions. 115 /* Some CPUs run faster using the string copy instructions.
93 It is also a lot simpler. Use this when possible */ 116 It is also a lot simpler. Use this when possible */
94 117
118 .section .altinstr_replacement,"ax"
1191: .byte 0xeb /* jmp <disp8> */
120 .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */
1212:
122 .previous
95 .section .altinstructions,"a" 123 .section .altinstructions,"a"
96 .align 8 124 .align 8
97 .quad memcpy 125 .quad memcpy
98 .quad memcpy_c 126 .quad 1b
99 .byte X86_FEATURE_REP_GOOD 127 .byte X86_FEATURE_REP_GOOD
100 .byte .Lfinal-memcpy 128 .byte .Lfinal - memcpy
101 .byte memcpy_c_end-memcpy_c 129 .byte 2b - 1b
102 .previous
103
104 .section .altinstr_replacement,"ax"
105 /* rdi destination
106 * rsi source
107 * rdx count
108 */
109memcpy_c:
110 movq %rdi,%rax
111 movl %edx,%ecx
112 shrl $3,%ecx
113 andl $7,%edx
114 rep
115 movsq
116 movl %edx,%ecx
117 rep
118 movsb
119 ret
120memcpy_c_end:
121 .previous 130 .previous
diff --git a/arch/x86_64/lib/memset.S b/arch/x86_64/lib/memset.S
index ad397f2c7de8..09ed1f6b0eaa 100644
--- a/arch/x86_64/lib/memset.S
+++ b/arch/x86_64/lib/memset.S
@@ -1,4 +1,9 @@
1/* Copyright 2002 Andi Kleen, SuSE Labs */ 1/* Copyright 2002 Andi Kleen, SuSE Labs */
2
3#include <linux/config.h>
4#include <linux/linkage.h>
5#include <asm/dwarf2.h>
6
2/* 7/*
3 * ISO C memset - set a memory block to a byte value. 8 * ISO C memset - set a memory block to a byte value.
4 * 9 *
@@ -8,11 +13,29 @@
8 * 13 *
9 * rax original destination 14 * rax original destination
10 */ 15 */
11 .globl __memset 16 ALIGN
12 .globl memset 17memset_c:
13 .p2align 4 18 CFI_STARTPROC
14memset: 19 movq %rdi,%r9
15__memset: 20 movl %edx,%r8d
21 andl $7,%r8d
22 movl %edx,%ecx
23 shrl $3,%ecx
24 /* expand byte value */
25 movzbl %sil,%esi
26 movabs $0x0101010101010101,%rax
27 mulq %rsi /* with rax, clobbers rdx */
28 rep stosq
29 movl %r8d,%ecx
30 rep stosb
31 movq %r9,%rax
32 ret
33 CFI_ENDPROC
34ENDPROC(memset_c)
35
36ENTRY(memset)
37ENTRY(__memset)
38 CFI_STARTPROC
16 movq %rdi,%r10 39 movq %rdi,%r10
17 movq %rdx,%r11 40 movq %rdx,%r11
18 41
@@ -25,6 +48,7 @@ __memset:
25 movl %edi,%r9d 48 movl %edi,%r9d
26 andl $7,%r9d 49 andl $7,%r9d
27 jnz .Lbad_alignment 50 jnz .Lbad_alignment
51 CFI_REMEMBER_STATE
28.Lafter_bad_alignment: 52.Lafter_bad_alignment:
29 53
30 movl %r11d,%ecx 54 movl %r11d,%ecx
@@ -75,6 +99,7 @@ __memset:
75 movq %r10,%rax 99 movq %r10,%rax
76 ret 100 ret
77 101
102 CFI_RESTORE_STATE
78.Lbad_alignment: 103.Lbad_alignment:
79 cmpq $7,%r11 104 cmpq $7,%r11
80 jbe .Lhandle_7 105 jbe .Lhandle_7
@@ -84,42 +109,26 @@ __memset:
84 addq %r8,%rdi 109 addq %r8,%rdi
85 subq %r8,%r11 110 subq %r8,%r11
86 jmp .Lafter_bad_alignment 111 jmp .Lafter_bad_alignment
112.Lfinal:
113 CFI_ENDPROC
114ENDPROC(memset)
115ENDPROC(__memset)
87 116
88 /* Some CPUs run faster using the string instructions. 117 /* Some CPUs run faster using the string instructions.
89 It is also a lot simpler. Use this when possible */ 118 It is also a lot simpler. Use this when possible */
90 119
91#include <asm/cpufeature.h> 120#include <asm/cpufeature.h>
92 121
122 .section .altinstr_replacement,"ax"
1231: .byte 0xeb /* jmp <disp8> */
124 .byte (memset_c - memset) - (2f - 1b) /* offset */
1252:
126 .previous
93 .section .altinstructions,"a" 127 .section .altinstructions,"a"
94 .align 8 128 .align 8
95 .quad memset 129 .quad memset
96 .quad memset_c 130 .quad 1b
97 .byte X86_FEATURE_REP_GOOD 131 .byte X86_FEATURE_REP_GOOD
98 .byte memset_c_end-memset_c 132 .byte .Lfinal - memset
99 .byte memset_c_end-memset_c 133 .byte 2b - 1b
100 .previous
101
102 .section .altinstr_replacement,"ax"
103 /* rdi destination
104 * rsi value
105 * rdx count
106 */
107memset_c:
108 movq %rdi,%r9
109 movl %edx,%r8d
110 andl $7,%r8d
111 movl %edx,%ecx
112 shrl $3,%ecx
113 /* expand byte value */
114 movzbl %sil,%esi
115 movabs $0x0101010101010101,%rax
116 mulq %rsi /* with rax, clobbers rdx */
117 rep
118 stosq
119 movl %r8d,%ecx
120 rep
121 stosb
122 movq %r9,%rax
123 ret
124memset_c_end:
125 .previous 134 .previous
diff --git a/arch/x86_64/lib/putuser.S b/arch/x86_64/lib/putuser.S
index 7f5593974e2d..4989f5a8fa9b 100644
--- a/arch/x86_64/lib/putuser.S
+++ b/arch/x86_64/lib/putuser.S
@@ -25,25 +25,26 @@
25 */ 25 */
26 26
27#include <linux/linkage.h> 27#include <linux/linkage.h>
28#include <asm/dwarf2.h>
28#include <asm/page.h> 29#include <asm/page.h>
29#include <asm/errno.h> 30#include <asm/errno.h>
30#include <asm/asm-offsets.h> 31#include <asm/asm-offsets.h>
31#include <asm/thread_info.h> 32#include <asm/thread_info.h>
32 33
33 .text 34 .text
34 .p2align 4 35ENTRY(__put_user_1)
35.globl __put_user_1 36 CFI_STARTPROC
36__put_user_1:
37 GET_THREAD_INFO(%r8) 37 GET_THREAD_INFO(%r8)
38 cmpq threadinfo_addr_limit(%r8),%rcx 38 cmpq threadinfo_addr_limit(%r8),%rcx
39 jae bad_put_user 39 jae bad_put_user
401: movb %dl,(%rcx) 401: movb %dl,(%rcx)
41 xorl %eax,%eax 41 xorl %eax,%eax
42 ret 42 ret
43 CFI_ENDPROC
44ENDPROC(__put_user_1)
43 45
44 .p2align 4 46ENTRY(__put_user_2)
45.globl __put_user_2 47 CFI_STARTPROC
46__put_user_2:
47 GET_THREAD_INFO(%r8) 48 GET_THREAD_INFO(%r8)
48 addq $1,%rcx 49 addq $1,%rcx
49 jc 20f 50 jc 20f
@@ -55,10 +56,11 @@ __put_user_2:
55 ret 56 ret
5620: decq %rcx 5720: decq %rcx
57 jmp bad_put_user 58 jmp bad_put_user
59 CFI_ENDPROC
60ENDPROC(__put_user_2)
58 61
59 .p2align 4 62ENTRY(__put_user_4)
60.globl __put_user_4 63 CFI_STARTPROC
61__put_user_4:
62 GET_THREAD_INFO(%r8) 64 GET_THREAD_INFO(%r8)
63 addq $3,%rcx 65 addq $3,%rcx
64 jc 30f 66 jc 30f
@@ -70,10 +72,11 @@ __put_user_4:
70 ret 72 ret
7130: subq $3,%rcx 7330: subq $3,%rcx
72 jmp bad_put_user 74 jmp bad_put_user
75 CFI_ENDPROC
76ENDPROC(__put_user_4)
73 77
74 .p2align 4 78ENTRY(__put_user_8)
75.globl __put_user_8 79 CFI_STARTPROC
76__put_user_8:
77 GET_THREAD_INFO(%r8) 80 GET_THREAD_INFO(%r8)
78 addq $7,%rcx 81 addq $7,%rcx
79 jc 40f 82 jc 40f
@@ -85,10 +88,15 @@ __put_user_8:
85 ret 88 ret
8640: subq $7,%rcx 8940: subq $7,%rcx
87 jmp bad_put_user 90 jmp bad_put_user
91 CFI_ENDPROC
92ENDPROC(__put_user_8)
88 93
89bad_put_user: 94bad_put_user:
95 CFI_STARTPROC
90 movq $(-EFAULT),%rax 96 movq $(-EFAULT),%rax
91 ret 97 ret
98 CFI_ENDPROC
99END(bad_put_user)
92 100
93.section __ex_table,"a" 101.section __ex_table,"a"
94 .quad 1b,bad_put_user 102 .quad 1b,bad_put_user
diff --git a/arch/x86_64/lib/rwlock.S b/arch/x86_64/lib/rwlock.S
new file mode 100644
index 000000000000..0cde1f807314
--- /dev/null
+++ b/arch/x86_64/lib/rwlock.S
@@ -0,0 +1,38 @@
1/* Slow paths of read/write spinlocks. */
2
3#include <linux/linkage.h>
4#include <asm/rwlock.h>
5#include <asm/alternative-asm.i>
6#include <asm/dwarf2.h>
7
8/* rdi: pointer to rwlock_t */
9ENTRY(__write_lock_failed)
10 CFI_STARTPROC
11 LOCK_PREFIX
12 addl $RW_LOCK_BIAS,(%rdi)
131: rep
14 nop
15 cmpl $RW_LOCK_BIAS,(%rdi)
16 jne 1b
17 LOCK_PREFIX
18 subl $RW_LOCK_BIAS,(%rdi)
19 jnz __write_lock_failed
20 ret
21 CFI_ENDPROC
22END(__write_lock_failed)
23
24/* rdi: pointer to rwlock_t */
25ENTRY(__read_lock_failed)
26 CFI_STARTPROC
27 LOCK_PREFIX
28 incl (%rdi)
291: rep
30 nop
31 cmpl $1,(%rdi)
32 js 1b
33 LOCK_PREFIX
34 decl (%rdi)
35 js __read_lock_failed
36 ret
37 CFI_ENDPROC
38END(__read_lock_failed)
diff --git a/arch/x86_64/lib/thunk.S b/arch/x86_64/lib/thunk.S
index 332ea5dff916..0025535cac8d 100644
--- a/arch/x86_64/lib/thunk.S
+++ b/arch/x86_64/lib/thunk.S
@@ -1,10 +1,9 @@
1 /* 1/*
2 * Save registers before calling assembly functions. This avoids 2 * Save registers before calling assembly functions. This avoids
3 * disturbance of register allocation in some inline assembly constructs. 3 * disturbance of register allocation in some inline assembly constructs.
4 * Copyright 2001,2002 by Andi Kleen, SuSE Labs. 4 * Copyright 2001,2002 by Andi Kleen, SuSE Labs.
5 * Subject to the GNU public license, v.2. No warranty of any kind. 5 * Subject to the GNU public license, v.2. No warranty of any kind.
6 * $Id: thunk.S,v 1.2 2002/03/13 20:06:58 ak Exp $ 6 */
7 */
8 7
9 #include <linux/config.h> 8 #include <linux/config.h>
10 #include <linux/linkage.h> 9 #include <linux/linkage.h>
@@ -67,33 +66,3 @@ restore_norax:
67 RESTORE_ARGS 1 66 RESTORE_ARGS 1
68 ret 67 ret
69 CFI_ENDPROC 68 CFI_ENDPROC
70
71#ifdef CONFIG_SMP
72/* Support for read/write spinlocks. */
73 .text
74/* rax: pointer to rwlock_t */
75ENTRY(__write_lock_failed)
76 lock
77 addl $RW_LOCK_BIAS,(%rax)
781: rep
79 nop
80 cmpl $RW_LOCK_BIAS,(%rax)
81 jne 1b
82 lock
83 subl $RW_LOCK_BIAS,(%rax)
84 jnz __write_lock_failed
85 ret
86
87/* rax: pointer to rwlock_t */
88ENTRY(__read_lock_failed)
89 lock
90 incl (%rax)
911: rep
92 nop
93 cmpl $1,(%rax)
94 js 1b
95 lock
96 decl (%rax)
97 js __read_lock_failed
98 ret
99#endif
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c
index ac8ea66ccb94..1a17b0733ab5 100644
--- a/arch/x86_64/mm/fault.c
+++ b/arch/x86_64/mm/fault.c
@@ -40,8 +40,7 @@
40#define PF_RSVD (1<<3) 40#define PF_RSVD (1<<3)
41#define PF_INSTR (1<<4) 41#define PF_INSTR (1<<4)
42 42
43#ifdef CONFIG_KPROBES 43static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
44ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
45 44
46/* Hook to register for page fault notifications */ 45/* Hook to register for page fault notifications */
47int register_page_fault_notifier(struct notifier_block *nb) 46int register_page_fault_notifier(struct notifier_block *nb)
@@ -49,11 +48,13 @@ int register_page_fault_notifier(struct notifier_block *nb)
49 vmalloc_sync_all(); 48 vmalloc_sync_all();
50 return atomic_notifier_chain_register(&notify_page_fault_chain, nb); 49 return atomic_notifier_chain_register(&notify_page_fault_chain, nb);
51} 50}
51EXPORT_SYMBOL_GPL(register_page_fault_notifier);
52 52
53int unregister_page_fault_notifier(struct notifier_block *nb) 53int unregister_page_fault_notifier(struct notifier_block *nb)
54{ 54{
55 return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb); 55 return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
56} 56}
57EXPORT_SYMBOL_GPL(unregister_page_fault_notifier);
57 58
58static inline int notify_page_fault(enum die_val val, const char *str, 59static inline int notify_page_fault(enum die_val val, const char *str,
59 struct pt_regs *regs, long err, int trap, int sig) 60 struct pt_regs *regs, long err, int trap, int sig)
@@ -67,13 +68,6 @@ static inline int notify_page_fault(enum die_val val, const char *str,
67 }; 68 };
68 return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args); 69 return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
69} 70}
70#else
71static inline int notify_page_fault(enum die_val val, const char *str,
72 struct pt_regs *regs, long err, int trap, int sig)
73{
74 return NOTIFY_DONE;
75}
76#endif
77 71
78void bust_spinlocks(int yes) 72void bust_spinlocks(int yes)
79{ 73{
@@ -102,7 +96,7 @@ void bust_spinlocks(int yes)
102static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, 96static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr,
103 unsigned long error_code) 97 unsigned long error_code)
104{ 98{
105 unsigned char *instr; 99 unsigned char __user *instr;
106 int scan_more = 1; 100 int scan_more = 1;
107 int prefetch = 0; 101 int prefetch = 0;
108 unsigned char *max_instr; 102 unsigned char *max_instr;
@@ -111,7 +105,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr,
111 if (error_code & PF_INSTR) 105 if (error_code & PF_INSTR)
112 return 0; 106 return 0;
113 107
114 instr = (unsigned char *)convert_rip_to_linear(current, regs); 108 instr = (unsigned char __user *)convert_rip_to_linear(current, regs);
115 max_instr = instr + 15; 109 max_instr = instr + 15;
116 110
117 if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE) 111 if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE)
@@ -122,7 +116,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr,
122 unsigned char instr_hi; 116 unsigned char instr_hi;
123 unsigned char instr_lo; 117 unsigned char instr_lo;
124 118
125 if (__get_user(opcode, instr)) 119 if (__get_user(opcode, (char __user *)instr))
126 break; 120 break;
127 121
128 instr_hi = opcode & 0xf0; 122 instr_hi = opcode & 0xf0;
@@ -160,7 +154,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr,
160 case 0x00: 154 case 0x00:
161 /* Prefetch instruction is 0x0F0D or 0x0F18 */ 155 /* Prefetch instruction is 0x0F0D or 0x0F18 */
162 scan_more = 0; 156 scan_more = 0;
163 if (__get_user(opcode, instr)) 157 if (__get_user(opcode, (char __user *)instr))
164 break; 158 break;
165 prefetch = (instr_lo == 0xF) && 159 prefetch = (instr_lo == 0xF) &&
166 (opcode == 0x0D || opcode == 0x18); 160 (opcode == 0x0D || opcode == 0x18);
@@ -176,7 +170,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr,
176static int bad_address(void *p) 170static int bad_address(void *p)
177{ 171{
178 unsigned long dummy; 172 unsigned long dummy;
179 return __get_user(dummy, (unsigned long *)p); 173 return __get_user(dummy, (unsigned long __user *)p);
180} 174}
181 175
182void dump_pagetable(unsigned long address) 176void dump_pagetable(unsigned long address)
@@ -299,7 +293,7 @@ static int vmalloc_fault(unsigned long address)
299 if (pgd_none(*pgd)) 293 if (pgd_none(*pgd))
300 set_pgd(pgd, *pgd_ref); 294 set_pgd(pgd, *pgd_ref);
301 else 295 else
302 BUG_ON(pgd_page(*pgd) != pgd_page(*pgd_ref)); 296 BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
303 297
304 /* Below here mismatches are bugs because these lower tables 298 /* Below here mismatches are bugs because these lower tables
305 are shared */ 299 are shared */
@@ -308,7 +302,7 @@ static int vmalloc_fault(unsigned long address)
308 pud_ref = pud_offset(pgd_ref, address); 302 pud_ref = pud_offset(pgd_ref, address);
309 if (pud_none(*pud_ref)) 303 if (pud_none(*pud_ref))
310 return -1; 304 return -1;
311 if (pud_none(*pud) || pud_page(*pud) != pud_page(*pud_ref)) 305 if (pud_none(*pud) || pud_page_vaddr(*pud) != pud_page_vaddr(*pud_ref))
312 BUG(); 306 BUG();
313 pmd = pmd_offset(pud, address); 307 pmd = pmd_offset(pud, address);
314 pmd_ref = pmd_offset(pud_ref, address); 308 pmd_ref = pmd_offset(pud_ref, address);
@@ -641,7 +635,7 @@ void vmalloc_sync_all(void)
641 if (pgd_none(*pgd)) 635 if (pgd_none(*pgd))
642 set_pgd(pgd, *pgd_ref); 636 set_pgd(pgd, *pgd_ref);
643 else 637 else
644 BUG_ON(pgd_page(*pgd) != pgd_page(*pgd_ref)); 638 BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref));
645 } 639 }
646 spin_unlock(&pgd_lock); 640 spin_unlock(&pgd_lock);
647 set_bit(pgd_index(address), insync); 641 set_bit(pgd_index(address), insync);
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index d14fb2dfbfc4..3e16fe08150e 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -229,7 +229,6 @@ __init void *early_ioremap(unsigned long addr, unsigned long size)
229 229
230 /* actually usually some more */ 230 /* actually usually some more */
231 if (size >= LARGE_PAGE_SIZE) { 231 if (size >= LARGE_PAGE_SIZE) {
232 printk("SMBIOS area too long %lu\n", size);
233 return NULL; 232 return NULL;
234 } 233 }
235 set_pmd(temp_mappings[0].pmd, __pmd(map | _KERNPG_TABLE | _PAGE_PSE)); 234 set_pmd(temp_mappings[0].pmd, __pmd(map | _KERNPG_TABLE | _PAGE_PSE));
@@ -250,12 +249,13 @@ __init void early_iounmap(void *addr, unsigned long size)
250} 249}
251 250
252static void __meminit 251static void __meminit
253phys_pmd_init(pmd_t *pmd, unsigned long address, unsigned long end) 252phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end)
254{ 253{
255 int i; 254 int i = pmd_index(address);
256 255
257 for (i = 0; i < PTRS_PER_PMD; pmd++, i++, address += PMD_SIZE) { 256 for (; i < PTRS_PER_PMD; i++, address += PMD_SIZE) {
258 unsigned long entry; 257 unsigned long entry;
258 pmd_t *pmd = pmd_page + pmd_index(address);
259 259
260 if (address >= end) { 260 if (address >= end) {
261 if (!after_bootmem) 261 if (!after_bootmem)
@@ -263,6 +263,10 @@ phys_pmd_init(pmd_t *pmd, unsigned long address, unsigned long end)
263 set_pmd(pmd, __pmd(0)); 263 set_pmd(pmd, __pmd(0));
264 break; 264 break;
265 } 265 }
266
267 if (pmd_val(*pmd))
268 continue;
269
266 entry = _PAGE_NX|_PAGE_PSE|_KERNPG_TABLE|_PAGE_GLOBAL|address; 270 entry = _PAGE_NX|_PAGE_PSE|_KERNPG_TABLE|_PAGE_GLOBAL|address;
267 entry &= __supported_pte_mask; 271 entry &= __supported_pte_mask;
268 set_pmd(pmd, __pmd(entry)); 272 set_pmd(pmd, __pmd(entry));
@@ -272,45 +276,41 @@ phys_pmd_init(pmd_t *pmd, unsigned long address, unsigned long end)
272static void __meminit 276static void __meminit
273phys_pmd_update(pud_t *pud, unsigned long address, unsigned long end) 277phys_pmd_update(pud_t *pud, unsigned long address, unsigned long end)
274{ 278{
275 pmd_t *pmd = pmd_offset(pud, (unsigned long)__va(address)); 279 pmd_t *pmd = pmd_offset(pud,0);
276 280 spin_lock(&init_mm.page_table_lock);
277 if (pmd_none(*pmd)) { 281 phys_pmd_init(pmd, address, end);
278 spin_lock(&init_mm.page_table_lock); 282 spin_unlock(&init_mm.page_table_lock);
279 phys_pmd_init(pmd, address, end); 283 __flush_tlb_all();
280 spin_unlock(&init_mm.page_table_lock);
281 __flush_tlb_all();
282 }
283} 284}
284 285
285static void __meminit phys_pud_init(pud_t *pud, unsigned long address, unsigned long end) 286static void __meminit phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end)
286{ 287{
287 long i = pud_index(address); 288 int i = pud_index(addr);
288 289
289 pud = pud + i;
290 290
291 if (after_bootmem && pud_val(*pud)) { 291 for (; i < PTRS_PER_PUD; i++, addr = (addr & PUD_MASK) + PUD_SIZE ) {
292 phys_pmd_update(pud, address, end);
293 return;
294 }
295
296 for (; i < PTRS_PER_PUD; pud++, i++) {
297 int map; 292 int map;
298 unsigned long paddr, pmd_phys; 293 unsigned long pmd_phys;
294 pud_t *pud = pud_page + pud_index(addr);
299 pmd_t *pmd; 295 pmd_t *pmd;
300 296
301 paddr = (address & PGDIR_MASK) + i*PUD_SIZE; 297 if (addr >= end)
302 if (paddr >= end)
303 break; 298 break;
304 299
305 if (!after_bootmem && !e820_any_mapped(paddr, paddr+PUD_SIZE, 0)) { 300 if (!after_bootmem && !e820_any_mapped(addr,addr+PUD_SIZE,0)) {
306 set_pud(pud, __pud(0)); 301 set_pud(pud, __pud(0));
307 continue; 302 continue;
308 } 303 }
309 304
305 if (pud_val(*pud)) {
306 phys_pmd_update(pud, addr, end);
307 continue;
308 }
309
310 pmd = alloc_low_page(&map, &pmd_phys); 310 pmd = alloc_low_page(&map, &pmd_phys);
311 spin_lock(&init_mm.page_table_lock); 311 spin_lock(&init_mm.page_table_lock);
312 set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE)); 312 set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE));
313 phys_pmd_init(pmd, paddr, end); 313 phys_pmd_init(pmd, addr, end);
314 spin_unlock(&init_mm.page_table_lock); 314 spin_unlock(&init_mm.page_table_lock);
315 unmap_low_page(map); 315 unmap_low_page(map);
316 } 316 }
@@ -403,69 +403,15 @@ void __cpuinit zap_low_mappings(int cpu)
403 __flush_tlb_all(); 403 __flush_tlb_all();
404} 404}
405 405
406/* Compute zone sizes for the DMA and DMA32 zones in a node. */
407__init void
408size_zones(unsigned long *z, unsigned long *h,
409 unsigned long start_pfn, unsigned long end_pfn)
410{
411 int i;
412 unsigned long w;
413
414 for (i = 0; i < MAX_NR_ZONES; i++)
415 z[i] = 0;
416
417 if (start_pfn < MAX_DMA_PFN)
418 z[ZONE_DMA] = MAX_DMA_PFN - start_pfn;
419 if (start_pfn < MAX_DMA32_PFN) {
420 unsigned long dma32_pfn = MAX_DMA32_PFN;
421 if (dma32_pfn > end_pfn)
422 dma32_pfn = end_pfn;
423 z[ZONE_DMA32] = dma32_pfn - start_pfn;
424 }
425 z[ZONE_NORMAL] = end_pfn - start_pfn;
426
427 /* Remove lower zones from higher ones. */
428 w = 0;
429 for (i = 0; i < MAX_NR_ZONES; i++) {
430 if (z[i])
431 z[i] -= w;
432 w += z[i];
433 }
434
435 /* Compute holes */
436 w = start_pfn;
437 for (i = 0; i < MAX_NR_ZONES; i++) {
438 unsigned long s = w;
439 w += z[i];
440 h[i] = e820_hole_size(s, w);
441 }
442
443 /* Add the space pace needed for mem_map to the holes too. */
444 for (i = 0; i < MAX_NR_ZONES; i++)
445 h[i] += (z[i] * sizeof(struct page)) / PAGE_SIZE;
446
447 /* The 16MB DMA zone has the kernel and other misc mappings.
448 Account them too */
449 if (h[ZONE_DMA]) {
450 h[ZONE_DMA] += dma_reserve;
451 if (h[ZONE_DMA] >= z[ZONE_DMA]) {
452 printk(KERN_WARNING
453 "Kernel too large and filling up ZONE_DMA?\n");
454 h[ZONE_DMA] = z[ZONE_DMA];
455 }
456 }
457}
458
459#ifndef CONFIG_NUMA 406#ifndef CONFIG_NUMA
460void __init paging_init(void) 407void __init paging_init(void)
461{ 408{
462 unsigned long zones[MAX_NR_ZONES], holes[MAX_NR_ZONES]; 409 unsigned long max_zone_pfns[MAX_NR_ZONES] = {MAX_DMA_PFN,
463 410 MAX_DMA32_PFN,
411 end_pfn};
464 memory_present(0, 0, end_pfn); 412 memory_present(0, 0, end_pfn);
465 sparse_init(); 413 sparse_init();
466 size_zones(zones, holes, 0, end_pfn); 414 free_area_init_nodes(max_zone_pfns);
467 free_area_init_node(0, NODE_DATA(0), zones,
468 __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes);
469} 415}
470#endif 416#endif
471 417
@@ -536,7 +482,7 @@ int memory_add_physaddr_to_nid(u64 start)
536int arch_add_memory(int nid, u64 start, u64 size) 482int arch_add_memory(int nid, u64 start, u64 size)
537{ 483{
538 struct pglist_data *pgdat = NODE_DATA(nid); 484 struct pglist_data *pgdat = NODE_DATA(nid);
539 struct zone *zone = pgdat->node_zones + MAX_NR_ZONES-2; 485 struct zone *zone = pgdat->node_zones + ZONE_NORMAL;
540 unsigned long start_pfn = start >> PAGE_SHIFT; 486 unsigned long start_pfn = start >> PAGE_SHIFT;
541 unsigned long nr_pages = size >> PAGE_SHIFT; 487 unsigned long nr_pages = size >> PAGE_SHIFT;
542 int ret; 488 int ret;
@@ -597,12 +543,6 @@ void __init mem_init(void)
597 543
598 pci_iommu_alloc(); 544 pci_iommu_alloc();
599 545
600 /* How many end-of-memory variables you have, grandma! */
601 max_low_pfn = end_pfn;
602 max_pfn = end_pfn;
603 num_physpages = end_pfn;
604 high_memory = (void *) __va(end_pfn * PAGE_SIZE);
605
606 /* clear the zero-page */ 546 /* clear the zero-page */
607 memset(empty_zero_page, 0, PAGE_SIZE); 547 memset(empty_zero_page, 0, PAGE_SIZE);
608 548
@@ -614,7 +554,8 @@ void __init mem_init(void)
614#else 554#else
615 totalram_pages = free_all_bootmem(); 555 totalram_pages = free_all_bootmem();
616#endif 556#endif
617 reservedpages = end_pfn - totalram_pages - e820_hole_size(0, end_pfn); 557 reservedpages = end_pfn - totalram_pages -
558 absent_pages_in_range(0, end_pfn);
618 559
619 after_bootmem = 1; 560 after_bootmem = 1;
620 561
@@ -714,8 +655,10 @@ void __init reserve_bootmem_generic(unsigned long phys, unsigned len)
714#else 655#else
715 reserve_bootmem(phys, len); 656 reserve_bootmem(phys, len);
716#endif 657#endif
717 if (phys+len <= MAX_DMA_PFN*PAGE_SIZE) 658 if (phys+len <= MAX_DMA_PFN*PAGE_SIZE) {
718 dma_reserve += len / PAGE_SIZE; 659 dma_reserve += len / PAGE_SIZE;
660 set_dma_reserve(dma_reserve);
661 }
719} 662}
720 663
721int kern_addr_valid(unsigned long addr) 664int kern_addr_valid(unsigned long addr)
diff --git a/arch/x86_64/mm/k8topology.c b/arch/x86_64/mm/k8topology.c
index 7c45c2d2b8b2..b5b8dba28b4e 100644
--- a/arch/x86_64/mm/k8topology.c
+++ b/arch/x86_64/mm/k8topology.c
@@ -54,6 +54,9 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
54 54
55 nodes_clear(nodes_parsed); 55 nodes_clear(nodes_parsed);
56 56
57 if (!early_pci_allowed())
58 return -1;
59
57 nb = find_northbridge(); 60 nb = find_northbridge();
58 if (nb < 0) 61 if (nb < 0)
59 return nb; 62 return nb;
@@ -146,6 +149,9 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
146 149
147 nodes[nodeid].start = base; 150 nodes[nodeid].start = base;
148 nodes[nodeid].end = limit; 151 nodes[nodeid].end = limit;
152 e820_register_active_regions(nodeid,
153 nodes[nodeid].start >> PAGE_SHIFT,
154 nodes[nodeid].end >> PAGE_SHIFT);
149 155
150 prevbase = base; 156 prevbase = base;
151 157
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
index b2fac14baac0..829a008bd39b 100644
--- a/arch/x86_64/mm/numa.c
+++ b/arch/x86_64/mm/numa.c
@@ -161,7 +161,7 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en
161 bootmap_start >> PAGE_SHIFT, 161 bootmap_start >> PAGE_SHIFT,
162 start_pfn, end_pfn); 162 start_pfn, end_pfn);
163 163
164 e820_bootmem_free(NODE_DATA(nodeid), start, end); 164 free_bootmem_with_active_regions(nodeid, end);
165 165
166 reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size); 166 reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size);
167 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);
@@ -175,13 +175,11 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en
175void __init setup_node_zones(int nodeid) 175void __init setup_node_zones(int nodeid)
176{ 176{
177 unsigned long start_pfn, end_pfn, memmapsize, limit; 177 unsigned long start_pfn, end_pfn, memmapsize, limit;
178 unsigned long zones[MAX_NR_ZONES];
179 unsigned long holes[MAX_NR_ZONES];
180 178
181 start_pfn = node_start_pfn(nodeid); 179 start_pfn = node_start_pfn(nodeid);
182 end_pfn = node_end_pfn(nodeid); 180 end_pfn = node_end_pfn(nodeid);
183 181
184 Dprintk(KERN_INFO "Setting up node %d %lx-%lx\n", 182 Dprintk(KERN_INFO "Setting up memmap for node %d %lx-%lx\n",
185 nodeid, start_pfn, end_pfn); 183 nodeid, start_pfn, end_pfn);
186 184
187 /* Try to allocate mem_map at end to not fill up precious <4GB 185 /* Try to allocate mem_map at end to not fill up precious <4GB
@@ -195,10 +193,6 @@ void __init setup_node_zones(int nodeid)
195 round_down(limit - memmapsize, PAGE_SIZE), 193 round_down(limit - memmapsize, PAGE_SIZE),
196 limit); 194 limit);
197#endif 195#endif
198
199 size_zones(zones, holes, start_pfn, end_pfn);
200 free_area_init_node(nodeid, NODE_DATA(nodeid), zones,
201 start_pfn, holes);
202} 196}
203 197
204void __init numa_init_array(void) 198void __init numa_init_array(void)
@@ -225,7 +219,7 @@ void __init numa_init_array(void)
225int numa_fake __initdata = 0; 219int numa_fake __initdata = 0;
226 220
227/* Numa emulation */ 221/* Numa emulation */
228static int numa_emulation(unsigned long start_pfn, unsigned long end_pfn) 222static int __init numa_emulation(unsigned long start_pfn, unsigned long end_pfn)
229{ 223{
230 int i; 224 int i;
231 struct bootnode nodes[MAX_NUMNODES]; 225 struct bootnode nodes[MAX_NUMNODES];
@@ -259,8 +253,11 @@ static int numa_emulation(unsigned long start_pfn, unsigned long end_pfn)
259 printk(KERN_ERR "No NUMA hash function found. Emulation disabled.\n"); 253 printk(KERN_ERR "No NUMA hash function found. Emulation disabled.\n");
260 return -1; 254 return -1;
261 } 255 }
262 for_each_online_node(i) 256 for_each_online_node(i) {
257 e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT,
258 nodes[i].end >> PAGE_SHIFT);
263 setup_node_bootmem(i, nodes[i].start, nodes[i].end); 259 setup_node_bootmem(i, nodes[i].start, nodes[i].end);
260 }
264 numa_init_array(); 261 numa_init_array();
265 return 0; 262 return 0;
266} 263}
@@ -299,6 +296,7 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn)
299 for (i = 0; i < NR_CPUS; i++) 296 for (i = 0; i < NR_CPUS; i++)
300 numa_set_node(i, 0); 297 numa_set_node(i, 0);
301 node_to_cpumask[0] = cpumask_of_cpu(0); 298 node_to_cpumask[0] = cpumask_of_cpu(0);
299 e820_register_active_regions(0, start_pfn, end_pfn);
302 setup_node_bootmem(0, start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT); 300 setup_node_bootmem(0, start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT);
303} 301}
304 302
@@ -340,17 +338,23 @@ static void __init arch_sparse_init(void)
340void __init paging_init(void) 338void __init paging_init(void)
341{ 339{
342 int i; 340 int i;
341 unsigned long max_zone_pfns[MAX_NR_ZONES] = { MAX_DMA_PFN,
342 MAX_DMA32_PFN,
343 end_pfn};
343 344
344 arch_sparse_init(); 345 arch_sparse_init();
345 346
346 for_each_online_node(i) { 347 for_each_online_node(i) {
347 setup_node_zones(i); 348 setup_node_zones(i);
348 } 349 }
350
351 free_area_init_nodes(max_zone_pfns);
349} 352}
350 353
351/* [numa=off] */ 354static __init int numa_setup(char *opt)
352__init int numa_setup(char *opt)
353{ 355{
356 if (!opt)
357 return -EINVAL;
354 if (!strncmp(opt,"off",3)) 358 if (!strncmp(opt,"off",3))
355 numa_off = 1; 359 numa_off = 1;
356#ifdef CONFIG_NUMA_EMU 360#ifdef CONFIG_NUMA_EMU
@@ -366,9 +370,11 @@ __init int numa_setup(char *opt)
366 if (!strncmp(opt,"hotadd=", 7)) 370 if (!strncmp(opt,"hotadd=", 7))
367 hotadd_percent = simple_strtoul(opt+7, NULL, 10); 371 hotadd_percent = simple_strtoul(opt+7, NULL, 10);
368#endif 372#endif
369 return 1; 373 return 0;
370} 374}
371 375
376early_param("numa", numa_setup);
377
372/* 378/*
373 * Setup early cpu_to_node. 379 * Setup early cpu_to_node.
374 * 380 *
diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c
index 2685b1f3671c..3e231d762aaa 100644
--- a/arch/x86_64/mm/pageattr.c
+++ b/arch/x86_64/mm/pageattr.c
@@ -108,8 +108,8 @@ static void revert_page(unsigned long address, pgprot_t ref_prot)
108 BUG_ON(pud_none(*pud)); 108 BUG_ON(pud_none(*pud));
109 pmd = pmd_offset(pud, address); 109 pmd = pmd_offset(pud, address);
110 BUG_ON(pmd_val(*pmd) & _PAGE_PSE); 110 BUG_ON(pmd_val(*pmd) & _PAGE_PSE);
111 pgprot_val(ref_prot) |= _PAGE_PSE;
112 large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, ref_prot); 111 large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, ref_prot);
112 large_pte = pte_mkhuge(large_pte);
113 set_pte((pte_t *)pmd, large_pte); 113 set_pte((pte_t *)pmd, large_pte);
114} 114}
115 115
@@ -119,32 +119,28 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
119{ 119{
120 pte_t *kpte; 120 pte_t *kpte;
121 struct page *kpte_page; 121 struct page *kpte_page;
122 unsigned kpte_flags;
123 pgprot_t ref_prot2; 122 pgprot_t ref_prot2;
124 kpte = lookup_address(address); 123 kpte = lookup_address(address);
125 if (!kpte) return 0; 124 if (!kpte) return 0;
126 kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK); 125 kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK);
127 kpte_flags = pte_val(*kpte);
128 if (pgprot_val(prot) != pgprot_val(ref_prot)) { 126 if (pgprot_val(prot) != pgprot_val(ref_prot)) {
129 if ((kpte_flags & _PAGE_PSE) == 0) { 127 if (!pte_huge(*kpte)) {
130 set_pte(kpte, pfn_pte(pfn, prot)); 128 set_pte(kpte, pfn_pte(pfn, prot));
131 } else { 129 } else {
132 /* 130 /*
133 * split_large_page will take the reference for this 131 * split_large_page will take the reference for this
134 * change_page_attr on the split page. 132 * change_page_attr on the split page.
135 */ 133 */
136
137 struct page *split; 134 struct page *split;
138 ref_prot2 = __pgprot(pgprot_val(pte_pgprot(*lookup_address(address))) & ~(1<<_PAGE_BIT_PSE)); 135 ref_prot2 = pte_pgprot(pte_clrhuge(*kpte));
139
140 split = split_large_page(address, prot, ref_prot2); 136 split = split_large_page(address, prot, ref_prot2);
141 if (!split) 137 if (!split)
142 return -ENOMEM; 138 return -ENOMEM;
143 set_pte(kpte,mk_pte(split, ref_prot2)); 139 set_pte(kpte, mk_pte(split, ref_prot2));
144 kpte_page = split; 140 kpte_page = split;
145 } 141 }
146 page_private(kpte_page)++; 142 page_private(kpte_page)++;
147 } else if ((kpte_flags & _PAGE_PSE) == 0) { 143 } else if (!pte_huge(*kpte)) {
148 set_pte(kpte, pfn_pte(pfn, ref_prot)); 144 set_pte(kpte, pfn_pte(pfn, ref_prot));
149 BUG_ON(page_private(kpte_page) == 0); 145 BUG_ON(page_private(kpte_page) == 0);
150 page_private(kpte_page)--; 146 page_private(kpte_page)--;
@@ -190,10 +186,12 @@ int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot)
190 * lowmem */ 186 * lowmem */
191 if (__pa(address) < KERNEL_TEXT_SIZE) { 187 if (__pa(address) < KERNEL_TEXT_SIZE) {
192 unsigned long addr2; 188 unsigned long addr2;
193 pgprot_t prot2 = prot; 189 pgprot_t prot2;
194 addr2 = __START_KERNEL_map + __pa(address); 190 addr2 = __START_KERNEL_map + __pa(address);
195 pgprot_val(prot2) &= ~_PAGE_NX; 191 /* Make sure the kernel mappings stay executable */
196 err = __change_page_attr(addr2, pfn, prot2, PAGE_KERNEL_EXEC); 192 prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot)));
193 err = __change_page_attr(addr2, pfn, prot2,
194 PAGE_KERNEL_EXEC);
197 } 195 }
198 } 196 }
199 up_write(&init_mm.mmap_sem); 197 up_write(&init_mm.mmap_sem);
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c
index 502fce65e96a..f8c04d6935c9 100644
--- a/arch/x86_64/mm/srat.c
+++ b/arch/x86_64/mm/srat.c
@@ -21,6 +21,8 @@
21#include <asm/numa.h> 21#include <asm/numa.h>
22#include <asm/e820.h> 22#include <asm/e820.h>
23 23
24int acpi_numa __initdata;
25
24#if (defined(CONFIG_ACPI_HOTPLUG_MEMORY) || \ 26#if (defined(CONFIG_ACPI_HOTPLUG_MEMORY) || \
25 defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)) \ 27 defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)) \
26 && !defined(CONFIG_MEMORY_HOTPLUG) 28 && !defined(CONFIG_MEMORY_HOTPLUG)
@@ -91,6 +93,7 @@ static __init void bad_srat(void)
91 apicid_to_node[i] = NUMA_NO_NODE; 93 apicid_to_node[i] = NUMA_NO_NODE;
92 for (i = 0; i < MAX_NUMNODES; i++) 94 for (i = 0; i < MAX_NUMNODES; i++)
93 nodes_add[i].start = nodes[i].end = 0; 95 nodes_add[i].start = nodes[i].end = 0;
96 remove_all_active_ranges();
94} 97}
95 98
96static __init inline int srat_disabled(void) 99static __init inline int srat_disabled(void)
@@ -173,7 +176,7 @@ static int hotadd_enough_memory(struct bootnode *nd)
173 176
174 if (mem < 0) 177 if (mem < 0)
175 return 0; 178 return 0;
176 allowed = (end_pfn - e820_hole_size(0, end_pfn)) * PAGE_SIZE; 179 allowed = (end_pfn - absent_pages_in_range(0, end_pfn)) * PAGE_SIZE;
177 allowed = (allowed / 100) * hotadd_percent; 180 allowed = (allowed / 100) * hotadd_percent;
178 if (allocated + mem > allowed) { 181 if (allocated + mem > allowed) {
179 unsigned long range; 182 unsigned long range;
@@ -223,8 +226,10 @@ static int reserve_hotadd(int node, unsigned long start, unsigned long end)
223 } 226 }
224 227
225 /* This check might be a bit too strict, but I'm keeping it for now. */ 228 /* This check might be a bit too strict, but I'm keeping it for now. */
226 if (e820_hole_size(s_pfn, e_pfn) != e_pfn - s_pfn) { 229 if (absent_pages_in_range(s_pfn, e_pfn) != e_pfn - s_pfn) {
227 printk(KERN_ERR "SRAT: Hotplug area has existing memory\n"); 230 printk(KERN_ERR
231 "SRAT: Hotplug area %lu -> %lu has existing memory\n",
232 s_pfn, e_pfn);
228 return -1; 233 return -1;
229 } 234 }
230 235
@@ -317,6 +322,10 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
317 322
318 printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm, 323 printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm,
319 nd->start, nd->end); 324 nd->start, nd->end);
325 e820_register_active_regions(node, nd->start >> PAGE_SHIFT,
326 nd->end >> PAGE_SHIFT);
327 push_node_boundaries(node, nd->start >> PAGE_SHIFT,
328 nd->end >> PAGE_SHIFT);
320 329
321#ifdef RESERVE_HOTADD 330#ifdef RESERVE_HOTADD
322 if (ma->flags.hot_pluggable && reserve_hotadd(node, start, end) < 0) { 331 if (ma->flags.hot_pluggable && reserve_hotadd(node, start, end) < 0) {
@@ -341,13 +350,13 @@ static int nodes_cover_memory(void)
341 unsigned long s = nodes[i].start >> PAGE_SHIFT; 350 unsigned long s = nodes[i].start >> PAGE_SHIFT;
342 unsigned long e = nodes[i].end >> PAGE_SHIFT; 351 unsigned long e = nodes[i].end >> PAGE_SHIFT;
343 pxmram += e - s; 352 pxmram += e - s;
344 pxmram -= e820_hole_size(s, e); 353 pxmram -= absent_pages_in_range(s, e);
345 pxmram -= nodes_add[i].end - nodes_add[i].start; 354 pxmram -= nodes_add[i].end - nodes_add[i].start;
346 if ((long)pxmram < 0) 355 if ((long)pxmram < 0)
347 pxmram = 0; 356 pxmram = 0;
348 } 357 }
349 358
350 e820ram = end_pfn - e820_hole_size(0, end_pfn); 359 e820ram = end_pfn - absent_pages_in_range(0, end_pfn);
351 /* We seem to lose 3 pages somewhere. Allow a bit of slack. */ 360 /* We seem to lose 3 pages somewhere. Allow a bit of slack. */
352 if ((long)(e820ram - pxmram) >= 1*1024*1024) { 361 if ((long)(e820ram - pxmram) >= 1*1024*1024) {
353 printk(KERN_ERR 362 printk(KERN_ERR
diff --git a/arch/x86_64/pci/Makefile b/arch/x86_64/pci/Makefile
index a3f6ad570179..1eb18f421edf 100644
--- a/arch/x86_64/pci/Makefile
+++ b/arch/x86_64/pci/Makefile
@@ -9,7 +9,7 @@ obj-y := i386.o
9obj-$(CONFIG_PCI_DIRECT)+= direct.o 9obj-$(CONFIG_PCI_DIRECT)+= direct.o
10obj-y += fixup.o init.o 10obj-y += fixup.o init.o
11obj-$(CONFIG_ACPI) += acpi.o 11obj-$(CONFIG_ACPI) += acpi.o
12obj-y += legacy.o irq.o common.o 12obj-y += legacy.o irq.o common.o early.o
13# mmconfig has a 64bit special 13# mmconfig has a 64bit special
14obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o 14obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o
15 15
@@ -23,3 +23,4 @@ common-y += ../../i386/pci/common.o
23fixup-y += ../../i386/pci/fixup.o 23fixup-y += ../../i386/pci/fixup.o
24i386-y += ../../i386/pci/i386.o 24i386-y += ../../i386/pci/i386.o
25init-y += ../../i386/pci/init.o 25init-y += ../../i386/pci/init.o
26early-y += ../../i386/pci/early.o
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c
index 3c55c76c6fd5..7732f4254d21 100644
--- a/arch/x86_64/pci/mmconfig.c
+++ b/arch/x86_64/pci/mmconfig.c
@@ -156,15 +156,45 @@ static __init void unreachable_devices(void)
156 addr = pci_dev_base(0, k, PCI_DEVFN(i, 0)); 156 addr = pci_dev_base(0, k, PCI_DEVFN(i, 0));
157 if (addr == NULL|| readl(addr) != val1) { 157 if (addr == NULL|| readl(addr) != val1) {
158 set_bit(i + 32*k, fallback_slots); 158 set_bit(i + 32*k, fallback_slots);
159 printk(KERN_NOTICE 159 printk(KERN_NOTICE "PCI: No mmconfig possible"
160 "PCI: No mmconfig possible on device %x:%x\n", 160 " on device %02x:%02x\n", k, i);
161 k, i);
162 } 161 }
163 } 162 }
164 } 163 }
165} 164}
166 165
167void __init pci_mmcfg_init(void) 166static __init void pci_mmcfg_insert_resources(void)
167{
168#define PCI_MMCFG_RESOURCE_NAME_LEN 19
169 int i;
170 struct resource *res;
171 char *names;
172 unsigned num_buses;
173
174 res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res),
175 pci_mmcfg_config_num, GFP_KERNEL);
176
177 if (!res) {
178 printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n");
179 return;
180 }
181
182 names = (void *)&res[pci_mmcfg_config_num];
183 for (i = 0; i < pci_mmcfg_config_num; i++, res++) {
184 num_buses = pci_mmcfg_config[i].end_bus_number -
185 pci_mmcfg_config[i].start_bus_number + 1;
186 res->name = names;
187 snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u",
188 pci_mmcfg_config[i].pci_segment_group_number);
189 res->start = pci_mmcfg_config[i].base_address;
190 res->end = res->start + (num_buses << 20) - 1;
191 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
192 insert_resource(&iomem_resource, res);
193 names += PCI_MMCFG_RESOURCE_NAME_LEN;
194 }
195}
196
197void __init pci_mmcfg_init(int type)
168{ 198{
169 int i; 199 int i;
170 200
@@ -177,7 +207,9 @@ void __init pci_mmcfg_init(void)
177 (pci_mmcfg_config[0].base_address == 0)) 207 (pci_mmcfg_config[0].base_address == 0))
178 return; 208 return;
179 209
180 if (!e820_all_mapped(pci_mmcfg_config[0].base_address, 210 /* Only do this check when type 1 works. If it doesn't work
211 assume we run on a Mac and always use MCFG */
212 if (type == 1 && !e820_all_mapped(pci_mmcfg_config[0].base_address,
181 pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, 213 pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN,
182 E820_RESERVED)) { 214 E820_RESERVED)) {
183 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", 215 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n",
@@ -186,7 +218,6 @@ void __init pci_mmcfg_init(void)
186 return; 218 return;
187 } 219 }
188 220
189 /* RED-PEN i386 doesn't do _nocache right now */
190 pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); 221 pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL);
191 if (pci_mmcfg_virt == NULL) { 222 if (pci_mmcfg_virt == NULL) {
192 printk("PCI: Can not allocate memory for mmconfig structures\n"); 223 printk("PCI: Can not allocate memory for mmconfig structures\n");
@@ -205,6 +236,7 @@ void __init pci_mmcfg_init(void)
205 } 236 }
206 237
207 unreachable_devices(); 238 unreachable_devices();
239 pci_mmcfg_insert_resources();
208 240
209 raw_pci_ops = &pci_mmcfg; 241 raw_pci_ops = &pci_mmcfg;
210 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; 242 pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;